Merge tag android-5.1.0_r1 into AOSP_5.1_MERGE

Change-Id: I66b86b72f38554e94db646538f2e04f1fab1d0b7
diff --git a/.gitignore b/.gitignore
index ad0f8ff..ceacb7b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,11 @@
 .android_config
 .gclient*
 .gm-actuals
+.cproject
+.project
+.settings/
 TAGS
+common
 gyp/build
 out
 platform_tools/chromeos/third_party/externals
@@ -12,3 +16,4 @@
 third_party/externals
 tools/bug_chomper/oauth_client_secret.json
 xcodebuild
+bower_components
diff --git a/AUTHORS b/AUTHORS
index 96f53ce..c8827a5 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,5 @@
 # This is the official list of Skia authors for copyright purposes.
-# 
+#
 # Names should be added to this file with one of the following patterns:
 #
 # For individual contributors:
@@ -13,6 +13,7 @@
 
 ACCESS CO., LTD. <*@access-company.com>
 ARM <*@arm.com>
+Ehsan Akhgari <ehsan.akhgari@gmail.com>
 George Wright <george@mozilla.com>
 Google Inc. <*@google.com>
 Igalia <*@igalia.com>
@@ -22,6 +23,8 @@
 NVIDIA <*@nvidia.com>
 Opera Software ASA <*@opera.com>
 Samsung <*@samsung.com>
+Samsung Open Source Group <*@osg.samsung.com>
+Skia <*@skia.org>
 Skia Buildbots <skia.buildbots@gmail.com>
 Steve Singer <steve@ssinger.info>
 The Chromium Authors <*@chromium.org>
diff --git a/CQ_COMMITTERS b/CQ_COMMITTERS
index e80c81c..4bd1685 100644
--- a/CQ_COMMITTERS
+++ b/CQ_COMMITTERS
@@ -8,6 +8,7 @@
 djsollen@google.com
 egdaniel@google.com
 egdaniel@chromium.org
+epoger@chromium.org
 epoger@google.com
 fmalita@chromium.org
 fmalita@google.com
@@ -15,6 +16,8 @@
 hcm@google.com
 humper@google.com
 jcgregorio@google.com
+joshualitt@chromium.org
+joshualitt@google.com
 junov@chromium.org
 junov@google.com
 jvanverth@google.com
@@ -32,6 +35,7 @@
 scroggo@google.com
 senorblanco@chromium.org
 skia.buildbots@gmail.com
+stephana@google.com
 sugoi@chromium.org
 sugoi@google.com
 tfarina@chromium.org
diff --git a/DEPS b/DEPS
index 9893ed1..9fb9078 100644
--- a/DEPS
+++ b/DEPS
@@ -3,27 +3,28 @@
 # Dependencies on outside packages.
 #
 deps = {
-  # DEPS using https://chromium.googlesource.com are pulled from chromium @ r205199
-  # (see https://chromium.googlesource.com/chromium/chromium/+/c59bfa8ef877f45bfa859669053859857af1d279)
-  "third_party/externals/angle2" : "https://chromium.googlesource.com/angle/angle.git",
+  "common": "https://skia.googlesource.com/common.git@5dd2918f96b277ebe04eb66469ec3d5c7ba6952a",
+
+  "third_party/externals/angle2" : "https://chromium.googlesource.com/angle/angle.git@23a8a433529d9db23882c702a29d5e594841563d",
   "third_party/externals/freetype" : "https://skia.googlesource.com/third_party/freetype2.git@VER-2-5-0-1",
   "third_party/externals/gyp" : "https://chromium.googlesource.com/external/gyp.git@3917682a16d5c19ff3576a8be0ffdb3a332954b1",
   "third_party/externals/libjpeg" : "https://chromium.googlesource.com/chromium/deps/libjpeg_turbo.git@82ce8a6d4ebe12a177c0c3597192f2b4f09e81c3",
-  "third_party/externals/jsoncpp" : "https://chromium.googlesource.com/external/jsoncpp/jsoncpp.git@ab1e40f3bce061ea6f9bdc60351d6cde2a4f872b",
-  # Move to a webp version newer than 0.3.0 to pickup NEON fix for iOS
-  "third_party/externals/jsoncpp-chromium" : "https://chromium.googlesource.com/chromium/src/third_party/jsoncpp.git@41239939c0c60481f34887d52c038facf05f5533",
+  "third_party/externals/jsoncpp" : "https://chromium.googlesource.com/external/jsoncpp/jsoncpp.git@1afff032c83e26ddf7f2776e8b43de5ad666c1fa",
   "third_party/externals/libwebp" : "https://chromium.googlesource.com/webm/libwebp.git@3fe91635df8734b23f3c1b9d1f0c4fa8cfaf4e39",
-  # "third_party/externals/v8" : "git://github.com/v8/v8.git@d15b0f0f2099dbd72867f3df70e9aaf5b8afbd2c",
   "third_party/externals/nanomsg": "git://github.com/nanomsg/nanomsg.git@0.4-beta",
 }
 
+recursedeps = [
+  "common",
+]
+
 deps_os = {
   "android": {
     "platform_tools/android/third_party/externals/expat" : "https://android.googlesource.com/platform/external/expat.git@android-4.2.2_r1.2",
     "platform_tools/android/third_party/externals/gif" : "https://android.googlesource.com/platform/external/giflib.git@android-4.2.2_r1.2",
     "platform_tools/android/third_party/externals/png" : "https://android.googlesource.com/platform/external/libpng.git@android-4.2.2_r1.2",
     "platform_tools/android/third_party/externals/jpeg" :
-      "https://android.googlesource.com/platform/external/jpeg.git@746f1f0853ddbd14ab5da6af35cc1fa560453d1e",
+      "https://android.googlesource.com/platform/external/jpeg.git@ef1b83013e7814622a9d11579878d342e84580b7",
   },
   "chromeos": {
     "platform_tools/chromeos/third_party/externals/gif" : "https://android.googlesource.com/platform/external/giflib.git@android-4.2.2_r1.2",
diff --git a/Makefile b/Makefile
index 1b15a74..29831bb 100644
--- a/Makefile
+++ b/Makefile
@@ -7,12 +7,12 @@
 #   make clean
 #
 #   # Build and run tests (in Debug mode)
-#   make tests
-#   out/Debug/tests
+#   make dm
+#   out/Debug/dm
 #
 #   # Build and run tests (in Release mode)
-#   make tests BUILDTYPE=Release
-#   out/Release/tests
+#   make dm BUILDTYPE=Release
+#   out/Release/dm
 #
 #   # Build bench and SampleApp (both in Release mode), and then run them
 #   make SampleApp bench BUILDTYPE=Release
@@ -40,7 +40,7 @@
 # TODO(epoger): I'm not sure if the above comment is still valid in a ninja
 # world.
 VALID_TARGETS := \
-                 bench \
+                 nanobench \
                  debugger \
                  dm \
                  everything \
@@ -53,7 +53,6 @@
                  skhello \
                  skia_lib \
                  skpskgr_test \
-                 tests \
                  tools \
                  skpdiff
 
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index dc8cb77..61fa2d6 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -20,11 +20,14 @@
 
 SKIA_TREE_STATUS_URL = 'http://skia-tree-status.appspot.com'
 
+# Please add the complete email address here (and not just 'xyz@' or 'xyz').
 PUBLIC_API_OWNERS = (
     'reed@chromium.org',
     'reed@google.com',
     'bsalomon@chromium.org',
     'bsalomon@google.com',
+    'djsollen@chromium.org',
+    'djsollen@google.com',
 )
 
 AUTHORS_FILE_NAME = 'AUTHORS'
@@ -46,6 +49,31 @@
   return []
 
 
+def _PythonChecks(input_api, output_api):
+  """Run checks on any modified Python files."""
+  pylint_disabled_warnings = (
+      'F0401',  # Unable to import.
+      'E0611',  # No name in module.
+      'W0232',  # Class has no __init__ method.
+      'E1002',  # Use of super on an old style class.
+      'W0403',  # Relative import used.
+      'R0201',  # Method could be a function.
+      'E1003',  # Using class name in super.
+      'W0613',  # Unused argument.
+  )
+  # Run Pylint on only the modified python files. Unfortunately it still runs
+  # Pylint on the whole file instead of just the modified lines.
+  affected_python_files = []
+  for affected_file in input_api.AffectedSourceFiles(None):
+    affected_file_path = affected_file.LocalPath()
+    if affected_file_path.endswith('.py'):
+      affected_python_files.append(affected_file_path)
+  return input_api.canned_checks.RunPylint(
+      input_api, output_api,
+      disabled_warnings=pylint_disabled_warnings,
+      white_list=affected_python_files)
+
+
 def _CommonChecks(input_api, output_api):
   """Presubmit checks common to upload and commit."""
   results = []
@@ -58,6 +86,7 @@
   results.extend(
       _CheckChangeHasEol(
           input_api, output_api, source_file_filter=sources))
+  results.extend(_PythonChecks(input_api, output_api))
   return results
 
 
@@ -114,7 +143,7 @@
   results = []
   issue = input_api.change.issue
   if issue and input_api.rietveld:
-    issue_properties = input_api.rietveld.get_issue_properties( 
+    issue_properties = input_api.rietveld.get_issue_properties(
         issue=int(issue), messages=False)
     owner_email = issue_properties['owner_email']
 
@@ -143,7 +172,7 @@
             '(individual) or '
             'https://developers.google.com/open-source/cla/corporate '
             '(corporate).'
-            % owner_email)) 
+            % owner_email))
     except IOError:
       # Do not fail if authors file cannot be found.
       traceback.print_exc()
@@ -160,11 +189,12 @@
   """
   results = []
   requires_owner_check = False
-  for affected_svn_file in input_api.AffectedFiles():
-    affected_file_path = affected_svn_file.AbsoluteLocalPath()
+  for affected_file in input_api.AffectedFiles():
+    affected_file_path = affected_file.LocalPath()
     file_path, file_ext = os.path.splitext(affected_file_path)
-    # We only care about files that end in .h and are under the include dir.
-    if file_ext == '.h' and 'include' in file_path.split(os.path.sep):
+    # We only care about files that end in .h and are under the top-level
+    # include dir.
+    if file_ext == '.h' and 'include' == file_path.split(os.path.sep)[0]:
       requires_owner_check = True
 
   if not requires_owner_check:
@@ -178,6 +208,16 @@
     if re.match(REVERT_CL_SUBJECT_PREFIX, issue_properties['subject'], re.I):
       # It is a revert CL, ignore the public api owners check.
       return results
+
+    match = re.search(r'^TBR=(.*)$', issue_properties['description'], re.M)
+    if match:
+      tbr_entries = match.group(1).strip().split(',')
+      for owner in PUBLIC_API_OWNERS:
+        if owner in tbr_entries or owner.split('@')[0] in tbr_entries:
+          # If an owner is specified in the TBR= line then ignore the public
+          # api owners check.
+          return results
+
     if issue_properties['owner_email'] in PUBLIC_API_OWNERS:
       # An owner created the CL that is an automatic LGTM.
       lgtm_from_owner = True
@@ -189,7 +229,7 @@
             'lgtm' in message['text'].lower()):
           # Found an lgtm in a message from an owner.
           lgtm_from_owner = True
-          break;
+          break
 
   if not lgtm_from_owner:
     results.append(
diff --git a/SKP_VERSION b/SKP_VERSION
index 978b4e8..97e3504 100644
--- a/SKP_VERSION
+++ b/SKP_VERSION
@@ -1 +1 @@
-26
\ No newline at end of file
+110
\ No newline at end of file
diff --git a/bench/AlternatingColorPatternBench.cpp b/bench/AlternatingColorPatternBench.cpp
new file mode 100644
index 0000000..b497979
--- /dev/null
+++ b/bench/AlternatingColorPatternBench.cpp
@@ -0,0 +1,200 @@
+/*
+ * 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 "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkPaint.h"
+#include "SkString.h"
+
+enum ColorPattern {
+    kWhite_ColorPattern,
+    kBlue_ColorPattern,
+    kOpaqueBitmap_ColorPattern,
+    kAlphaBitmap_ColorPattern,
+};
+
+static const struct ColorPatternData{
+    SkColor         fColor;
+    bool            fIsBitmap;
+    const char*     fName;
+} gColorPatterns[] = {
+    // Keep this in same order as ColorPattern enum
+    { SK_ColorWHITE, false,  "white"        }, // kWhite_ColorPattern
+    { SK_ColorBLUE,  false,  "blue"         }, // kBlue_ColorPattern
+    { SK_ColorWHITE, true,   "obaqueBitMap" }, // kOpaqueBitmap_ColorPattern
+    { 0x10000000,    true,   "alphaBitmap"  }, // kAlphaBitmap_ColorPattern
+};
+
+enum DrawType {
+    kRect_DrawType,
+    kPath_DrawType,
+};
+
+static void makebm(SkBitmap* bm, int w, int h) {
+    bm->allocN32Pixels(w, h);
+    bm->eraseColor(SK_ColorTRANSPARENT);
+
+    SkCanvas    canvas(*bm);
+    SkScalar    s = SkIntToScalar(SkMin32(w, h));
+    static const SkPoint     kPts0[] = { { 0, 0 }, { s, s } };
+    static const SkPoint     kPts1[] = { { s/2, 0 }, { s/2, s } };
+    static const SkScalar    kPos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
+    static const SkColor kColors0[] = {0x80F00080, 0xF0F08000, 0x800080F0 };
+    static const SkColor kColors1[] = {0xF08000F0, 0x8080F000, 0xF000F080 };
+
+
+    SkPaint     paint;
+
+    paint.setShader(SkGradientShader::CreateLinear(kPts0, kColors0, kPos,
+                    SK_ARRAY_COUNT(kColors0), SkShader::kClamp_TileMode))->unref();
+    canvas.drawPaint(paint);
+    paint.setShader(SkGradientShader::CreateLinear(kPts1, kColors1, kPos,
+                    SK_ARRAY_COUNT(kColors1), SkShader::kClamp_TileMode))->unref();
+    canvas.drawPaint(paint);
+}
+
+/**
+ * This bench draws a grid of either rects or filled paths, with two alternating color patterns.
+ * This color patterns are passed in as enums to the class. The options are:
+ *   1) solid white color
+ *   2) solid blue color
+ *   3) opaque bitmap
+ *   4) partial alpha bitmap
+ * The same color pattern can be set for both arguments to create a uniform pattern on all draws.
+ *
+ * The bench is used to test a few things. First it can test any optimizations made for a specific
+ * color pattern (for example drawing an opaque bitmap versus one with partial alpha). Also it can
+ * be used to test the cost of program switching and/or batching when alternating between different
+ * patterns when on the gpu.
+ */
+class AlternatingColorPatternBench : public Benchmark {
+public:
+    enum {
+        NX = 5,
+        NY = 5,
+        NUM_DRAWS = NX * NY,
+    };
+    SkShader* fBmShader;
+
+    SkPath  fPaths[NUM_DRAWS];
+    SkRect  fRects[NUM_DRAWS];
+    SkColor fColors[NUM_DRAWS];
+    SkShader* fShaders[NUM_DRAWS];
+
+    SkString        fName;
+    ColorPatternData    fPattern1;
+    ColorPatternData    fPattern2;
+    DrawType fDrawType;
+    SkBitmap fBmp;
+
+
+    AlternatingColorPatternBench(ColorPattern pattern1, ColorPattern pattern2, DrawType drawType)
+        : fBmShader(NULL) {
+        fPattern1 = gColorPatterns[pattern1];
+        fPattern2 = gColorPatterns[pattern2];
+        fName.printf("colorPattern_%s_%s_%s",
+                     fPattern1.fName, fPattern2.fName,
+                     kRect_DrawType == drawType ? "rect" : "path");
+        fDrawType = drawType;
+    }
+
+    virtual ~AlternatingColorPatternBench() {
+        SkSafeUnref(fBmShader);
+    }
+
+protected:
+    virtual const char* onGetName() SK_OVERRIDE {
+        return fName.c_str();
+    }
+
+    virtual void onPreDraw() {
+        int w = 40;
+        int h = 40;
+        makebm(&fBmp, w, h);
+        fBmShader = SkShader::CreateBitmapShader(fBmp,
+                                                 SkShader::kRepeat_TileMode,
+                                                 SkShader::kRepeat_TileMode);
+        int offset = 2;
+        int count = 0;
+        for (int j = 0; j < NY; ++j) {
+            for (int i = 0; i < NX; ++i) {
+                int x = (w + offset) * i;
+                int y = (h * offset) * j;
+                if (kRect_DrawType == fDrawType) {
+                    fRects[count].set(SkIntToScalar(x), SkIntToScalar(y),
+                                      SkIntToScalar(x + w), SkIntToScalar(y + h));
+                } else {
+                    fPaths[count].moveTo(SkIntToScalar(x), SkIntToScalar(y));
+                    fPaths[count].rLineTo(SkIntToScalar(w), 0);
+                    fPaths[count].rLineTo(0, SkIntToScalar(h));
+                    fPaths[count].rLineTo(SkIntToScalar(-w + 1), 0);
+                }
+                if (0 == count % 2) {
+                    fColors[count]  = fPattern1.fColor;
+                    fShaders[count] = fPattern1.fIsBitmap ? fBmShader : NULL;
+                } else {
+                    fColors[count]  = fPattern2.fColor;
+                    fShaders[count] = fPattern2.fIsBitmap ? fBmShader : NULL;
+                }
+                ++count;
+            }
+        }
+    }
+
+    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
+        SkPaint paint;
+        paint.setAntiAlias(false);
+        paint.setFilterLevel(SkPaint::kLow_FilterLevel);
+
+        for (int i = 0; i < loops; ++i) {
+            for (int j = 0; j < NUM_DRAWS; ++j) {
+                paint.setColor(fColors[j]);
+                paint.setShader(fShaders[j]);
+                if (kRect_DrawType == fDrawType) {
+                    canvas->drawRect(fRects[j], paint);
+                } else {
+                    canvas->drawPath(fPaths[j], paint);
+                }
+            }
+        }
+    }
+
+private:
+    typedef Benchmark INHERITED;
+};
+
+DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
+                             (kWhite_ColorPattern, kWhite_ColorPattern,
+                              kPath_DrawType)); )
+DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
+                             (kBlue_ColorPattern, kBlue_ColorPattern,
+                              kPath_DrawType)); )
+DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
+                             (kWhite_ColorPattern, kBlue_ColorPattern,
+                              kPath_DrawType)); )
+
+DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
+                             (kOpaqueBitmap_ColorPattern, kOpaqueBitmap_ColorPattern,
+                              kPath_DrawType)); )
+DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
+                             (kAlphaBitmap_ColorPattern, kAlphaBitmap_ColorPattern,
+                              kPath_DrawType)); )
+DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
+                             (kOpaqueBitmap_ColorPattern, kAlphaBitmap_ColorPattern,
+                              kPath_DrawType)); )
+
+DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
+                             (kOpaqueBitmap_ColorPattern, kOpaqueBitmap_ColorPattern,
+                              kRect_DrawType)); )
+DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
+                             (kAlphaBitmap_ColorPattern, kAlphaBitmap_ColorPattern,
+                              kRect_DrawType)); )
+DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
+                             (kOpaqueBitmap_ColorPattern, kAlphaBitmap_ColorPattern,
+                              kRect_DrawType)); )
+
diff --git a/bench/BenchGpuTimer_gl.cpp b/bench/BenchGpuTimer_gl.cpp
deleted file mode 100644
index 349fc15..0000000
--- a/bench/BenchGpuTimer_gl.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "BenchGpuTimer_gl.h"
-#include "gl/SkGLContextHelper.h"
-#include "gl/GrGLUtil.h"
-
-BenchGpuTimer::BenchGpuTimer(const SkGLContextHelper* glctx) {
-    fContext = glctx;
-    glctx->ref();
-    glctx->makeCurrent();
-    fStarted = false;
-    fSupported = GrGLGetVersion(glctx->gl()) > GR_GL_VER(3,3) ||
-                 glctx->hasExtension("GL_ARB_timer_query") ||
-                 glctx->hasExtension("GL_EXT_timer_query");
-
-    if (fSupported) {
-        SK_GL(*glctx, GenQueries(1, &fQuery));
-    }
-}
-
-BenchGpuTimer::~BenchGpuTimer() {
-    if (fSupported) {
-        fContext->makeCurrent();
-        SK_GL(*fContext, DeleteQueries(1, &fQuery));
-    }
-    fContext->unref();
-}
-
-void BenchGpuTimer::startGpu() {
-    if (fSupported) {
-        fContext->makeCurrent();
-        fStarted = true;
-        SK_GL(*fContext, BeginQuery(GR_GL_TIME_ELAPSED, fQuery));
-    }
-}
-
-/**
- * It is important to stop the cpu clocks first,
- * as this will cpu wait for the gpu to finish.
- */
-double BenchGpuTimer::endGpu() {
-    if (fSupported) {
-        fStarted = false;
-        fContext->makeCurrent();
-        SK_GL(*fContext, EndQuery(GR_GL_TIME_ELAPSED));
-
-        GrGLint available = 0;
-        while (!available) {
-            SK_GL_NOERRCHECK(*fContext, GetQueryObjectiv(fQuery,
-                                             GR_GL_QUERY_RESULT_AVAILABLE,
-                                             &available));
-            // If GetQueryObjectiv is erroring out we need some alternative
-            // means of breaking out of this loop
-            GrGLenum error;
-            SK_GL_RET_NOERRCHECK(*fContext, error, GetError());
-            if (GR_GL_NO_ERROR != error) {
-                break;
-            }
-        }
-        GrGLuint64 totalGPUTimeElapsed = 0;
-        SK_GL(*fContext, GetQueryObjectui64v(fQuery,
-                                             GR_GL_QUERY_RESULT,
-                                             &totalGPUTimeElapsed));
-
-        return totalGPUTimeElapsed / 1000000.0;
-    } else {
-        return 0;
-    }
-}
diff --git a/bench/BenchGpuTimer_gl.h b/bench/BenchGpuTimer_gl.h
deleted file mode 100644
index e472a4c..0000000
--- a/bench/BenchGpuTimer_gl.h
+++ /dev/null
@@ -1,26 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkBenchGpuTimer_DEFINED
-#define SkBenchGpuTimer_DEFINED
-
-class SkGLContextHelper;
-
-class BenchGpuTimer {
-public:
-    BenchGpuTimer(const SkGLContextHelper* glctx);
-    ~BenchGpuTimer();
-    void startGpu();
-    double endGpu();
-private:
-    unsigned fQuery;
-    int fStarted;
-    const SkGLContextHelper* fContext;
-    bool fSupported;
-};
-
-#endif
diff --git a/bench/BenchSysTimer_c.cpp b/bench/BenchSysTimer_c.cpp
deleted file mode 100644
index f4cbd39..0000000
--- a/bench/BenchSysTimer_c.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "BenchSysTimer_c.h"
-
-//Time
-#include <time.h>
-
-void BenchSysTimer::startWall() {
-    this->fStartWall = time();
-}
-void BenchSysTimer::startCpu() {
-    this->fStartCpu = clock();
-}
-
-double BenchSysTimer::endCpu() {
-    clock_t end_cpu = clock();
-    this->fCpu = (end_cpu - this->fStartCpu) * CLOCKS_PER_SEC / 1000.0;
-}
-double BenchSysTimer::endWall() {
-    time_t end_wall = time();
-    this->fWall = difftime(end_wall, this->fstartWall) / 1000.0;
-}
diff --git a/bench/BenchSysTimer_c.h b/bench/BenchSysTimer_c.h
deleted file mode 100644
index 586f0b4..0000000
--- a/bench/BenchSysTimer_c.h
+++ /dev/null
@@ -1,26 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkBenchSysTimer_DEFINED
-#define SkBenchSysTimer_DEFINED
-
-//Time
-#include <time.h>
-
-// Beware: this timer uses standard (as opposed to high precision) clocks
-class BenchSysTimer {
-public:
-    void startWall();
-    void startCpu();
-    double endCpu();
-    double endWall();
-private:
-    clock_t start_cpu;
-    time_t fStartWall;
-};
-
-#endif
diff --git a/bench/BenchSysTimer_mach.cpp b/bench/BenchSysTimer_mach.cpp
deleted file mode 100644
index 1f0a6b9..0000000
--- a/bench/BenchSysTimer_mach.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "BenchSysTimer_mach.h"
-
-//Time
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-
-static time_value_t macCpuTime() {
-    mach_port_t task = mach_task_self();
-    if (task == MACH_PORT_NULL) {
-        time_value_t none = {0, 0};
-        return none;
-    }
-
-    task_thread_times_info thread_info_data;
-    mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT;
-    if (KERN_SUCCESS != task_info(task,
-                 TASK_THREAD_TIMES_INFO,
-                 reinterpret_cast<task_info_t>(&thread_info_data),
-                 &thread_info_count))
-    {
-        time_value_t none = {0, 0};
-        return none;
-    }
-
-    time_value_add(&thread_info_data.user_time, &thread_info_data.system_time)
-    return thread_info_data.user_time;
-}
-
-static double intervalInMSec(const time_value_t start_clock
-                           , const time_value_t end_clock)
-{
-    double duration_clock;
-    if ((end_clock.microseconds - start_clock.microseconds) < 0) {
-        duration_clock = (end_clock.seconds - start_clock.seconds-1)*1000;
-        duration_clock += (1000000
-                           + end_clock.microseconds
-                           - start_clock.microseconds) / 1000.0;
-    } else {
-        duration_clock = (end_clock.seconds - start_clock.seconds)*1000;
-        duration_clock += (end_clock.microseconds - start_clock.microseconds)
-                           / 1000.0;
-    }
-    return duration_clock;
-}
-
-void BenchSysTimer::startWall() {
-    this->fStartWall = mach_absolute_time();
-}
-void BenchSysTimer::startCpu() {
-    this->fStartCpu = macCpuTime();
-}
-
-double BenchSysTimer::endCpu() {
-    time_value_t end_cpu = macCpuTime();
-    return intervalInMSec(this->fStartCpu, end_cpu);
-}
-double BenchSysTimer::endWall() {
-    uint64_t end_wall = mach_absolute_time();
-
-    uint64_t elapsed = end_wall - this->fStartWall;
-    mach_timebase_info_data_t sTimebaseInfo;
-    if (KERN_SUCCESS != mach_timebase_info(&sTimebaseInfo)) {
-        return 0;
-    } else {
-        uint64_t elapsedNano = elapsed * sTimebaseInfo.numer
-                               / sTimebaseInfo.denom;
-        return elapsedNano / 1000000.0;
-    }
-}
diff --git a/bench/BenchSysTimer_posix.cpp b/bench/BenchSysTimer_posix.cpp
deleted file mode 100644
index e6767e5..0000000
--- a/bench/BenchSysTimer_posix.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "BenchSysTimer_posix.h"
-
-//Time
-#include <time.h>
-
-static double intervalInMSec(const timespec start_clock
-                           , const timespec end_clock)
-{
-    double duration_clock;
-    if ((end_clock.tv_nsec - start_clock.tv_nsec) < 0) {
-        duration_clock = (end_clock.tv_sec - start_clock.tv_sec-1)*1000;
-        duration_clock += (1000000000 + end_clock.tv_nsec - start_clock.tv_nsec)
-                           / 1000000.0;
-    } else {
-        duration_clock = (end_clock.tv_sec - start_clock.tv_sec)*1000;
-        duration_clock += (end_clock.tv_nsec - start_clock.tv_nsec) / 1000000.0;
-    }
-    return duration_clock;
-}
-
-void BenchSysTimer::startWall() {
-    if (-1 == clock_gettime(CLOCK_MONOTONIC, &this->fWall)) {
-        timespec none = {0, 0};
-        this->fWall = none;
-    }
-}
-void BenchSysTimer::startCpu() {
-    if (-1 == clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &this->fCpu)) {
-        timespec none = {0, 0};
-        this->fCpu = none;
-    }
-}
-
-double BenchSysTimer::endCpu() {
-    timespec end_cpu;
-    if (-1 == clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_cpu)) {
-        timespec none = {0, 0};
-        end_cpu = none;
-    }
-    return intervalInMSec(this->fCpu, end_cpu);
-}
-
-double BenchSysTimer::endWall() {
-    timespec end_wall;
-    if (-1 == clock_gettime(CLOCK_MONOTONIC, &end_wall)) {
-        timespec none = {0, 0};
-        end_wall = none;
-    }
-    return intervalInMSec(this->fWall, end_wall);
-}
diff --git a/bench/BenchSysTimer_windows.cpp b/bench/BenchSysTimer_windows.cpp
deleted file mode 100644
index fab657a..0000000
--- a/bench/BenchSysTimer_windows.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "BenchSysTimer_windows.h"
-
-//Time
-#define WIN32_LEAN_AND_MEAN 1
-#include <windows.h>
-
-static ULONGLONG winCpuTime() {
-    FILETIME createTime;
-    FILETIME exitTime;
-    FILETIME usrTime;
-    FILETIME sysTime;
-    if (0 == GetProcessTimes(GetCurrentProcess()
-                           , &createTime, &exitTime
-                           , &sysTime, &usrTime))
-    {
-        return 0;
-    }
-    ULARGE_INTEGER start_cpu_sys;
-    ULARGE_INTEGER start_cpu_usr;
-    start_cpu_sys.LowPart  = sysTime.dwLowDateTime;
-    start_cpu_sys.HighPart = sysTime.dwHighDateTime;
-    start_cpu_usr.LowPart  = usrTime.dwLowDateTime;
-    start_cpu_usr.HighPart = usrTime.dwHighDateTime;
-    return start_cpu_sys.QuadPart + start_cpu_usr.QuadPart;
-}
-
-void BenchSysTimer::startWall() {
-    if (0 == ::QueryPerformanceCounter(&this->fStartWall)) {
-        this->fStartWall.QuadPart = 0;
-    }
-}
-void BenchSysTimer::startCpu() {
-    this->fStartCpu = winCpuTime();
-}
-
-double BenchSysTimer::endCpu() {
-    ULONGLONG end_cpu = winCpuTime();
-    return static_cast<double>((end_cpu - this->fStartCpu)) / 10000.0L;
-}
-double BenchSysTimer::endWall() {
-    LARGE_INTEGER end_wall;
-    if (0 == ::QueryPerformanceCounter(&end_wall)) {
-        end_wall.QuadPart = 0;
-    }
-
-    LARGE_INTEGER ticks_elapsed;
-    ticks_elapsed.QuadPart = end_wall.QuadPart - this->fStartWall.QuadPart;
-
-    LARGE_INTEGER frequency;
-    if (0 == ::QueryPerformanceFrequency(&frequency)) {
-        return 0.0L;
-    } else {
-        return static_cast<double>(ticks_elapsed.QuadPart)
-             / static_cast<double>(frequency.QuadPart)
-             * 1000.0L;
-    }
-}
diff --git a/bench/BenchTimer.cpp b/bench/BenchTimer.cpp
deleted file mode 100644
index f3e8e3b..0000000
--- a/bench/BenchTimer.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "BenchTimer.h"
-#if defined(SK_BUILD_FOR_WIN32)
-    #include "BenchSysTimer_windows.h"
-#elif defined(SK_BUILD_FOR_MAC)
-    #include "BenchSysTimer_mach.h"
-#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
-    #include "BenchSysTimer_posix.h"
-#else
-    #include "BenchSysTimer_c.h"
-#endif
-
-#if SK_SUPPORT_GPU
-#include "BenchGpuTimer_gl.h"
-#endif
-
-BenchTimer::BenchTimer(SkGLContextHelper* gl)
-        : fCpu(-1.0)
-        , fWall(-1.0)
-        , fTruncatedCpu(-1.0)
-        , fTruncatedWall(-1.0)
-        , fGpu(-1.0)
-{
-    fSysTimer = new BenchSysTimer();
-    fTruncatedSysTimer = new BenchSysTimer();
-#if SK_SUPPORT_GPU
-    if (gl) {
-        fGpuTimer = new BenchGpuTimer(gl);
-    } else {
-        fGpuTimer = NULL;
-    }
-#endif
-}
-
-BenchTimer::~BenchTimer() {
-    delete fSysTimer;
-    delete fTruncatedSysTimer;
-#if SK_SUPPORT_GPU
-    delete fGpuTimer;
-#endif
-}
-
-void BenchTimer::start(double durationScale) {
-    fDurationScale = durationScale;
-
-    fSysTimer->startWall();
-    fTruncatedSysTimer->startWall();
-#if SK_SUPPORT_GPU
-    if (fGpuTimer) {
-        fGpuTimer->startGpu();
-    }
-#endif
-    fSysTimer->startCpu();
-    fTruncatedSysTimer->startCpu();
-}
-
-void BenchTimer::end() {
-    fCpu = fSysTimer->endCpu() * fDurationScale;
-#if SK_SUPPORT_GPU
-    //It is important to stop the cpu clocks first,
-    //as the following will cpu wait for the gpu to finish.
-    if (fGpuTimer) {
-        fGpu = fGpuTimer->endGpu() * fDurationScale;
-    }
-#endif
-    fWall = fSysTimer->endWall() * fDurationScale;
-}
-
-void BenchTimer::truncatedEnd() {
-    fTruncatedCpu = fTruncatedSysTimer->endCpu() * fDurationScale;
-    fTruncatedWall = fTruncatedSysTimer->endWall() * fDurationScale;
-}
-
-WallTimer::WallTimer() : fWall(-1.0), fSysTimer(new BenchSysTimer) {}
-
-WallTimer::~WallTimer() {
-    delete fSysTimer;
-}
-
-void WallTimer::start(double durationScale) {
-    fDurationScale = durationScale;
-    fSysTimer->startWall();
-}
-
-void WallTimer::end() {
-    fWall = fSysTimer->endWall() * fDurationScale;
-}
-
diff --git a/bench/BenchTimer.h b/bench/BenchTimer.h
deleted file mode 100644
index 2abf10b..0000000
--- a/bench/BenchTimer.h
+++ /dev/null
@@ -1,67 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkBenchTimer_DEFINED
-#define SkBenchTimer_DEFINED
-
-#include <SkTypes.h>
-
-
-class BenchSysTimer;
-class BenchGpuTimer;
-
-class SkGLContextHelper;
-
-/**
- * SysTimers and GpuTimers are implemented orthogonally.
- * This class combines 2 SysTimers and a GpuTimer into one single,
- * platform specific Timer with a simple interface. The truncated
- * timer doesn't include the time required for the GPU to finish
- * its rendering. It should always be <= the un-truncated system
- * times and (for GPU configurations) can be used to roughly (very
- * roughly) gauge the GPU load/backlog.
- */
-class BenchTimer {
-public:
-    BenchTimer(SkGLContextHelper* gl = NULL);
-    ~BenchTimer();
-    void start(double durationScale = 1);
-    void end();
-    void truncatedEnd();
-    double fCpu;
-    double fWall;
-    double fTruncatedCpu;
-    double fTruncatedWall;
-    double fGpu;
-
-private:
-    BenchSysTimer* fSysTimer;
-    BenchSysTimer* fTruncatedSysTimer;
-#if SK_SUPPORT_GPU
-    BenchGpuTimer* fGpuTimer;
-#endif
-    double fDurationScale;  // for this start/end session
-};
-
-// Same as BenchTimer above, supporting only fWall but with much lower overhead.
-// (Typically, ~30ns instead of BenchTimer's ~1us.)
-class WallTimer {
-public:
-    WallTimer();
-    ~WallTimer();
-
-    void start(double durationScale = 1);
-    void end();
-
-    double fWall;
-
-private:
-    BenchSysTimer* fSysTimer;
-    double fDurationScale;
-};
-
-#endif
diff --git a/bench/BenchTool/BenchTool.xcodeproj/project.pbxproj b/bench/BenchTool/BenchTool.xcodeproj/project.pbxproj
deleted file mode 100644
index 4bb4b9c..0000000
--- a/bench/BenchTool/BenchTool.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,324 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 45;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		272FB43A0F11A19C00CA935D /* RectBench.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 272FB4390F11A19C00CA935D /* RectBench.cpp */; };
-		272FB4F30F11B40300CA935D /* Benchmark.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 272FB4F20F11B40300CA935D /* Benchmark.cpp */; };
-		2752A08A0F14CE1300BBDC03 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2752A0890F14CE1300BBDC03 /* main.cpp */; };
-		27739F4D0F11439200F233EA /* libmaccore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27739F240F11404A00F233EA /* libmaccore.a */; };
-		27739F4E0F11439300F233EA /* libcore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27739F1A0F11403B00F233EA /* libcore.a */; };
-		27739F520F1143C000F233EA /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27739F510F1143C000F233EA /* Carbon.framework */; };
-		8DD76F6A0486A84900D96B5E /* BenchTool.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859E8B029090EE04C91782 /* BenchTool.1 */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXContainerItemProxy section */
-		27739F190F11403B00F233EA /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 27739F120F11403B00F233EA /* core.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = core;
-		};
-		27739F230F11404A00F233EA /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 27739F1C0F11404A00F233EA /* maccore.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = maccore;
-		};
-		27739F3C0F11424800F233EA /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 27739F1C0F11404A00F233EA /* maccore.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = maccore;
-		};
-		27739F3E0F11424C00F233EA /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 27739F120F11403B00F233EA /* core.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = core;
-		};
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXCopyFilesBuildPhase section */
-		8DD76F690486A84900D96B5E /* CopyFiles */ = {
-			isa = PBXCopyFilesBuildPhase;
-			buildActionMask = 8;
-			dstPath = /usr/share/man/man1/;
-			dstSubfolderSpec = 0;
-			files = (
-				8DD76F6A0486A84900D96B5E /* BenchTool.1 in CopyFiles */,
-			);
-			runOnlyForDeploymentPostprocessing = 1;
-		};
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
-		272FB4390F11A19C00CA935D /* RectBench.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RectBench.cpp; path = ../RectBench.cpp; sourceTree = SOURCE_ROOT; };
-		272FB4F20F11B40300CA935D /* Benchmark.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Benchmark.cpp; path = ../Benchmark.cpp; sourceTree = SOURCE_ROOT; };
-		2752A0890F14CE1300BBDC03 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../main.cpp; sourceTree = SOURCE_ROOT; };
-		27739F120F11403B00F233EA /* core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = core.xcodeproj; path = ../../xcode/core/core.xcodeproj; sourceTree = SOURCE_ROOT; };
-		27739F1C0F11404A00F233EA /* maccore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = maccore.xcodeproj; path = ../../xcode/maccore/maccore.xcodeproj; sourceTree = SOURCE_ROOT; };
-		27739F510F1143C000F233EA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
-		8DD76F6C0486A84900D96B5E /* BenchTool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = BenchTool; sourceTree = BUILT_PRODUCTS_DIR; };
-		C6859E8B029090EE04C91782 /* BenchTool.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = BenchTool.1; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		8DD76F660486A84900D96B5E /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				27739F4D0F11439200F233EA /* libmaccore.a in Frameworks */,
-				27739F4E0F11439300F233EA /* libcore.a in Frameworks */,
-				27739F520F1143C000F233EA /* Carbon.framework in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		08FB7794FE84155DC02AAC07 /* BenchTool */ = {
-			isa = PBXGroup;
-			children = (
-				27739F510F1143C000F233EA /* Carbon.framework */,
-				27739F1C0F11404A00F233EA /* maccore.xcodeproj */,
-				27739F120F11403B00F233EA /* core.xcodeproj */,
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6859E8C029090F304C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = BenchTool;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				2752A0890F14CE1300BBDC03 /* main.cpp */,
-				272FB4F20F11B40300CA935D /* Benchmark.cpp */,
-				272FB4390F11A19C00CA935D /* RectBench.cpp */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				8DD76F6C0486A84900D96B5E /* BenchTool */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		27739F130F11403B00F233EA /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				27739F1A0F11403B00F233EA /* libcore.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		27739F1D0F11404A00F233EA /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				27739F240F11404A00F233EA /* libmaccore.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6859E8C029090F304C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-				C6859E8B029090EE04C91782 /* BenchTool.1 */,
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
-		8DD76F620486A84900D96B5E /* BenchTool */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "BenchTool" */;
-			buildPhases = (
-				8DD76F640486A84900D96B5E /* Sources */,
-				8DD76F660486A84900D96B5E /* Frameworks */,
-				8DD76F690486A84900D96B5E /* CopyFiles */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				27739F3D0F11424800F233EA /* PBXTargetDependency */,
-				27739F3F0F11424C00F233EA /* PBXTargetDependency */,
-			);
-			name = BenchTool;
-			productInstallPath = "$(HOME)/bin";
-			productName = BenchTool;
-			productReference = 8DD76F6C0486A84900D96B5E /* BenchTool */;
-			productType = "com.apple.product-type.tool";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "BenchTool" */;
-			compatibilityVersion = "Xcode 3.1";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* BenchTool */;
-			projectDirPath = "";
-			projectReferences = (
-				{
-					ProductGroup = 27739F130F11403B00F233EA /* Products */;
-					ProjectRef = 27739F120F11403B00F233EA /* core.xcodeproj */;
-				},
-				{
-					ProductGroup = 27739F1D0F11404A00F233EA /* Products */;
-					ProjectRef = 27739F1C0F11404A00F233EA /* maccore.xcodeproj */;
-				},
-			);
-			projectRoot = "";
-			targets = (
-				8DD76F620486A84900D96B5E /* BenchTool */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXReferenceProxy section */
-		27739F1A0F11403B00F233EA /* libcore.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libcore.a;
-			remoteRef = 27739F190F11403B00F233EA /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		27739F240F11404A00F233EA /* libmaccore.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libmaccore.a;
-			remoteRef = 27739F230F11404A00F233EA /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-/* End PBXReferenceProxy section */
-
-/* Begin PBXSourcesBuildPhase section */
-		8DD76F640486A84900D96B5E /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				272FB43A0F11A19C00CA935D /* RectBench.cpp in Sources */,
-				272FB4F30F11B40300CA935D /* Benchmark.cpp in Sources */,
-				2752A08A0F14CE1300BBDC03 /* main.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
-		27739F3D0F11424800F233EA /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = maccore;
-			targetProxy = 27739F3C0F11424800F233EA /* PBXContainerItemProxy */;
-		};
-		27739F3F0F11424C00F233EA /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = core;
-			targetProxy = 27739F3E0F11424C00F233EA /* PBXContainerItemProxy */;
-		};
-/* End PBXTargetDependency section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB923208733DC60010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"_GLIBCXX_DEBUG=1",
-					"_GLIBCXX_DEBUG_PEDANTIC=1",
-				);
-				INSTALL_PATH = /usr/local/bin;
-				PRODUCT_NAME = BenchTool;
-			};
-			name = Debug;
-		};
-		1DEB923308733DC60010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/bin;
-				PRODUCT_NAME = BenchTool;
-			};
-			name = Release;
-		};
-		1DEB923608733DC60010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-				GCC_C_LANGUAGE_STANDARD = c99;
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				ONLY_ACTIVE_ARCH = YES;
-				PREBINDING = NO;
-				SDKROOT = macosx10.5;
-				USER_HEADER_SEARCH_PATHS = ".. ../../include/**";
-			};
-			name = Debug;
-		};
-		1DEB923708733DC60010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-				GCC_C_LANGUAGE_STANDARD = c99;
-				GCC_ENABLE_CPP_EXCEPTIONS = NO;
-				GCC_ENABLE_CPP_RTTI = NO;
-				GCC_THREADSAFE_STATICS = NO;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				PREBINDING = NO;
-				SDKROOT = macosx10.5;
-				USER_HEADER_SEARCH_PATHS = ".. ../../include/**";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "BenchTool" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB923208733DC60010E9CD /* Debug */,
-				1DEB923308733DC60010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "BenchTool" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB923608733DC60010E9CD /* Debug */,
-				1DEB923708733DC60010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/bench/Benchmark.cpp b/bench/Benchmark.cpp
index ae614f0..9205ba9 100644
--- a/bench/Benchmark.cpp
+++ b/bench/Benchmark.cpp
@@ -16,8 +16,6 @@
 
 Benchmark::Benchmark() {
     fForceAlpha = 0xFF;
-    fForceAA = true;
-    fForceFilter = false;
     fDither = SkTriState::kDefault;
     fOrMask = fClearMask = 0;
 }
@@ -26,6 +24,10 @@
     return this->onGetName();
 }
 
+const char* Benchmark::getUniqueName() {
+    return this->onGetUniqueName();
+}
+
 SkIPoint Benchmark::getSize() {
     return this->onGetSize();
 }
@@ -40,9 +42,8 @@
 
 void Benchmark::setupPaint(SkPaint* paint) {
     paint->setAlpha(fForceAlpha);
-    paint->setAntiAlias(fForceAA);
-    paint->setFilterLevel(fForceFilter ? SkPaint::kLow_FilterLevel
-                                       : SkPaint::kNone_FilterLevel);
+    paint->setAntiAlias(true);
+    paint->setFilterLevel(SkPaint::kNone_FilterLevel);
 
     paint->setFlags((paint->getFlags() & ~fClearMask) | fOrMask);
 
diff --git a/bench/Benchmark.h b/bench/Benchmark.h
index db70bbe..508d1da 100644
--- a/bench/Benchmark.h
+++ b/bench/Benchmark.h
@@ -49,6 +49,7 @@
     Benchmark();
 
     const char* getName();
+    const char* getUniqueName();
     SkIPoint getSize();
 
     enum Backend {
@@ -76,14 +77,6 @@
         fForceAlpha = alpha;
     }
 
-    void setForceAA(bool aa) {
-        fForceAA = aa;
-    }
-
-    void setForceFilter(bool filter) {
-        fForceFilter = filter;
-    }
-
     void setDither(SkTriState::State state) {
         fDither = state;
     }
@@ -106,6 +99,7 @@
     virtual void setupPaint(SkPaint* paint);
 
     virtual const char* onGetName() = 0;
+    virtual const char* onGetUniqueName() { return this->onGetName(); }
     virtual void onPreDraw() {}
     // Each bench should do its main work in a loop like this:
     //   for (int i = 0; i < loops; i++) { <work here> }
@@ -115,8 +109,6 @@
 
 private:
     int     fForceAlpha;
-    bool    fForceAA;
-    bool    fForceFilter;
     SkTriState::State  fDither;
     uint32_t    fOrMask, fClearMask;
 
diff --git a/bench/BicubicBench.cpp b/bench/BicubicBench.cpp
deleted file mode 100644
index 9d03dd1..0000000
--- a/bench/BicubicBench.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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 "Benchmark.h"
-#include "SkBicubicImageFilter.h"
-#include "SkCanvas.h"
-#include "SkShader.h"
-#include "SkString.h"
-
-// This bench exercises SkBicubicImageFilter, upsampling a 40x40 input to
-// 100x100, 400x100, 100x400, and 400x400.
-
-class BicubicBench : public Benchmark {
-    SkSize         fScale;
-    SkString       fName;
-
-public:
-    BicubicBench(float x, float y)
-        : fScale(SkSize::Make(x, y)) {
-        fName.printf("bicubic_%gx%g",
-                     SkScalarToFloat(fScale.fWidth), SkScalarToFloat(fScale.fHeight));
-    }
-
-protected:
-    virtual const char* onGetName() {
-        return fName.c_str();
-    }
-
-    virtual void onDraw(const int loops, SkCanvas* canvas) {
-        SkPaint paint;
-        this->setupPaint(&paint);
-
-        paint.setAntiAlias(true);
-
-        SkRect r = SkRect::MakeWH(40, 40);
-        SkAutoTUnref<SkImageFilter> bicubic(SkBicubicImageFilter::CreateMitchell(fScale));
-        paint.setImageFilter(bicubic);
-
-        for (int i = 0; i < loops; i++) {
-            canvas->save();
-            canvas->clipRect(r);
-            canvas->drawOval(r, paint);
-            canvas->restore();
-        }
-    }
-
-private:
-    typedef Benchmark INHERITED;
-};
-
-DEF_BENCH( return new BicubicBench(10.0f, 10.0f); )
-DEF_BENCH( return new BicubicBench(2.5f, 10.0f); )
-DEF_BENCH( return new BicubicBench(10.0f, 2.5f); )
-DEF_BENCH( return new BicubicBench(2.5f, 2.5f); )
diff --git a/bench/BitmapBench.cpp b/bench/BitmapBench.cpp
index a269e90..e9ba1dc 100644
--- a/bench/BitmapBench.cpp
+++ b/bench/BitmapBench.cpp
@@ -107,12 +107,10 @@
         SkBitmap bm;
 
         if (kIndex_8_SkColorType == fColorType) {
-            bm.setInfo(SkImageInfo::MakeN32(W, H, fAlphaType));
+            bm.allocPixels(SkImageInfo::MakeN32(W, H, fAlphaType));
         } else {
-            bm.setInfo(SkImageInfo::Make(W, H, fColorType, fAlphaType));
+            bm.allocPixels(SkImageInfo::Make(W, H, fColorType, fAlphaType));
         }
-
-        bm.allocPixels();
         bm.eraseColor(kOpaque_SkAlphaType == fAlphaType ? SK_ColorBLACK : 0);
 
         onDrawIntoBitmap(bm);
diff --git a/bench/BlurBench.cpp b/bench/BlurBench.cpp
index cafc6f3..4133adc 100644
--- a/bench/BlurBench.cpp
+++ b/bench/BlurBench.cpp
@@ -14,6 +14,7 @@
 #include "SkShader.h"
 #include "SkString.h"
 
+#define MINI   0.01f
 #define SMALL   SkIntToScalar(2)
 #define REAL    1.5f
 #define BIG     SkIntToScalar(10)
@@ -78,6 +79,11 @@
     typedef Benchmark INHERITED;
 };
 
+DEF_BENCH(return new BlurBench(MINI, kNormal_SkBlurStyle);)
+DEF_BENCH(return new BlurBench(MINI, kSolid_SkBlurStyle);)
+DEF_BENCH(return new BlurBench(MINI, kOuter_SkBlurStyle);)
+DEF_BENCH(return new BlurBench(MINI, kInner_SkBlurStyle);)
+
 DEF_BENCH(return new BlurBench(SMALL, kNormal_SkBlurStyle);)
 DEF_BENCH(return new BlurBench(SMALL, kSolid_SkBlurStyle);)
 DEF_BENCH(return new BlurBench(SMALL, kOuter_SkBlurStyle);)
@@ -98,6 +104,8 @@
 DEF_BENCH(return new BlurBench(REAL, kOuter_SkBlurStyle);)
 DEF_BENCH(return new BlurBench(REAL, kInner_SkBlurStyle);)
 
+DEF_BENCH(return new BlurBench(MINI, kNormal_SkBlurStyle, SkBlurMaskFilter::kHighQuality_BlurFlag);)
+
 DEF_BENCH(return new BlurBench(SMALL, kNormal_SkBlurStyle, SkBlurMaskFilter::kHighQuality_BlurFlag);)
 
 DEF_BENCH(return new BlurBench(BIG, kNormal_SkBlurStyle, SkBlurMaskFilter::kHighQuality_BlurFlag);)
diff --git a/bench/BlurImageFilterBench.cpp b/bench/BlurImageFilterBench.cpp
index 786611b..9021d1b 100644
--- a/bench/BlurImageFilterBench.cpp
+++ b/bench/BlurImageFilterBench.cpp
@@ -6,7 +6,6 @@
  */
 
 #include "Benchmark.h"
-#include "SkBitmapDevice.h"
 #include "SkBlurImageFilter.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
@@ -18,6 +17,7 @@
 #define FILTER_HEIGHT_SMALL 32
 #define FILTER_WIDTH_LARGE  256
 #define FILTER_HEIGHT_LARGE 256
+#define BLUR_SIGMA_MINI     0.5f
 #define BLUR_SIGMA_SMALL    1.0f
 #define BLUR_SIGMA_LARGE    10.0f
 #define BLUR_SIGMA_HUGE     80.0f
@@ -87,6 +87,8 @@
 DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, 0, false);)
 DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_LARGE, false);)
 DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_SMALL, false);)
+DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_MINI, BLUR_SIGMA_MINI, true);)
+DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_MINI, BLUR_SIGMA_MINI, false);)
 DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, true);)
 DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, false);)
 DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, BLUR_SIGMA_LARGE, true);)
diff --git a/bench/ChartBench.cpp b/bench/ChartBench.cpp
index f33d2da..8d05ef1 100644
--- a/bench/ChartBench.cpp
+++ b/bench/ChartBench.cpp
@@ -64,7 +64,7 @@
         x += xDelta;
     }
 
-    if (NULL != bottomData) {
+    if (bottomData) {
         SkASSERT(bottomData->count() == topData.count());
         // iterate backwards over the previous graph's data to generate the bottom of the filled
         // area (and account for leftShift).
diff --git a/bench/DecodeBench.cpp b/bench/DecodeBench.cpp
index a4717f8..b03f898 100644
--- a/bench/DecodeBench.cpp
+++ b/bench/DecodeBench.cpp
@@ -20,7 +20,7 @@
     SkString          fName;
 public:
     DecodeBench(SkColorType ct) : fPrefColorType(ct) {
-        SkString fname = SkOSPath::SkBasename(FLAGS_decodeBenchFilename[0]);
+        SkString fname = SkOSPath::Basename(FLAGS_decodeBenchFilename[0]);
         fName.printf("decode_%s_%s", sk_tool_utils::colortype_name(ct), fname.c_str());
     }
 
diff --git a/bench/DeferredCanvasBench.cpp b/bench/DeferredCanvasBench.cpp
deleted file mode 100644
index 667895c..0000000
--- a/bench/DeferredCanvasBench.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2012 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 "SkDeferredCanvas.h"
-#include "SkDevice.h"
-#include "SkString.h"
-
-class DeferredCanvasBench : public Benchmark {
-public:
-    DeferredCanvasBench(const char name[])  {
-        fName.printf("deferred_canvas_%s", name);
-    }
-
-    enum {
-        CANVAS_WIDTH = 200,
-        CANVAS_HEIGHT = 200,
-    };
-protected:
-    virtual const char* onGetName() {
-        return fName.c_str();
-    }
-
-    virtual void onDraw(const int loops, SkCanvas* canvas) {
-#if 0   // what specifically are we interested in timing here?
-        SkBaseDevice *device = canvas->getDevice()->createCompatibleDevice(
-            SkBitmap::kARGB_8888_Config, CANVAS_WIDTH, CANVAS_HEIGHT, false);
-
-        SkAutoTUnref<SkDeferredCanvas> deferredCanvas(SkDeferredCanvas::Create(device));
-        device->unref();
-
-        initDeferredCanvas(deferredCanvas);
-        drawInDeferredCanvas(loops, deferredCanvas);
-        finalizeDeferredCanvas(deferredCanvas);
-        deferredCanvas->flush();
-#endif
-    }
-
-    virtual void initDeferredCanvas(SkDeferredCanvas* canvas) = 0;
-    virtual void drawInDeferredCanvas(const int loops, SkDeferredCanvas* canvas) = 0;
-    virtual void finalizeDeferredCanvas(SkDeferredCanvas* canvas) = 0;
-
-    SkString fName;
-
-private:
-    typedef Benchmark INHERITED;
-};
-
-class SimpleNotificationClient : public SkDeferredCanvas::NotificationClient {
-public:
-    SimpleNotificationClient() : fDummy(false) {}
-
-    //bogus virtual implementations that just do something small
-    virtual void prepareForDraw() SK_OVERRIDE {fDummy = true;}
-    virtual void storageAllocatedForRecordingChanged(size_t) SK_OVERRIDE {fDummy = false;}
-    virtual void flushedDrawCommands() SK_OVERRIDE {fDummy = !fDummy;}
-private:
-    bool fDummy;
-
-    typedef SkDeferredCanvas::NotificationClient INHERITED;
-};
-
-// Test that records very simple draw operations.
-// This benchmark aims to capture performance fluctuations in the recording
-// overhead of SkDeferredCanvas
-class DeferredRecordBench : public DeferredCanvasBench {
-public:
-    DeferredRecordBench()
-        : INHERITED("record") {
-    }
-
-protected:
-
-    virtual void initDeferredCanvas(SkDeferredCanvas* canvas) SK_OVERRIDE {
-        canvas->setNotificationClient(&fNotificationClient);
-    }
-
-    virtual void drawInDeferredCanvas(const int loops, SkDeferredCanvas* canvas) SK_OVERRIDE {
-        SkRect rect;
-        rect.setXYWH(0, 0, 10, 10);
-        SkPaint paint;
-        for (int i = 0; i < loops; i++) {
-            canvas->save();
-            canvas->translate(SkIntToScalar(i * 27 % CANVAS_WIDTH), SkIntToScalar(i * 13 % CANVAS_HEIGHT));
-            canvas->drawRect(rect, paint);
-            canvas->restore();
-        }
-    }
-
-    virtual void finalizeDeferredCanvas(SkDeferredCanvas* canvas) SK_OVERRIDE {
-        canvas->clear(0x0);
-        canvas->setNotificationClient(NULL);
-    }
-
-private:
-    typedef DeferredCanvasBench INHERITED;
-    SimpleNotificationClient fNotificationClient;
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-DEF_BENCH( return new DeferredRecordBench(); )
diff --git a/bench/DeferredSurfaceCopyBench.cpp b/bench/DeferredSurfaceCopyBench.cpp
index f4002b8..cbf98ec 100644
--- a/bench/DeferredSurfaceCopyBench.cpp
+++ b/bench/DeferredSurfaceCopyBench.cpp
@@ -34,26 +34,11 @@
     virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
         // The canvas is not actually used for this test except to provide
         // configuration information: gpu, multisampling, size, etc?
-        SkImageInfo info;
-        info.fWidth = kSurfaceWidth;
-        info.fHeight = kSurfaceHeight;
-        info.fColorType = kN32_SkColorType;
-        info.fAlphaType = kPremul_SkAlphaType;
+        SkImageInfo info = SkImageInfo::MakeN32Premul(kSurfaceWidth, kSurfaceHeight);
         const SkRect fullCanvasRect = SkRect::MakeWH(
             SkIntToScalar(kSurfaceWidth), SkIntToScalar(kSurfaceHeight));
-        SkSurface* surface;
-#if SK_SUPPORT_GPU
-        GrRenderTarget* rt = reinterpret_cast<GrRenderTarget*>(
-            canvas->getDevice()->accessRenderTarget());
-        if (NULL != rt) {
-            surface = SkSurface::NewRenderTarget(rt->getContext(), info, rt->numSamples());
-        } else
-#endif
-        {
-            surface = SkSurface::NewRaster(info);
-        }
+        SkAutoTUnref<SkSurface> surface(canvas->newSurface(info));
         SkAutoTUnref<SkDeferredCanvas> drawingCanvas(SkDeferredCanvas::Create(surface));
-        surface->unref();
 
         for (int iteration = 0; iteration < loops; iteration++) {
             drawingCanvas->clear(0);
diff --git a/bench/DisplacementBench.cpp b/bench/DisplacementBench.cpp
index 881ba33..2a0f7c0 100644
--- a/bench/DisplacementBench.cpp
+++ b/bench/DisplacementBench.cpp
@@ -4,8 +4,8 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "Benchmark.h"
-#include "SkBitmapDevice.h"
 #include "SkBitmapSource.h"
 #include "SkCanvas.h"
 #include "SkDisplacementMapEffect.h"
diff --git a/bench/ETCBitmapBench.cpp b/bench/ETCBitmapBench.cpp
index aaa2ce7..36573c8 100644
--- a/bench/ETCBitmapBench.cpp
+++ b/bench/ETCBitmapBench.cpp
@@ -21,7 +21,7 @@
 // This takes the etc1 data pointed to by orig, and copies it `factor` times in each
 // dimension. The return value is the new data or NULL on error.
 static etc1_byte* create_expanded_etc1_bitmap(const uint8_t* orig, int factor) {
-    SkASSERT(NULL != orig);
+    SkASSERT(orig);
     SkASSERT(factor > 1);
 
     const etc1_byte* origData = reinterpret_cast<const etc1_byte*>(orig);
@@ -89,13 +89,10 @@
     SkAutoDataUnref fPKMData;
 
 private:
-    SkData *loadPKM() {
-        SkString resourcePath = GetResourcePath();
-        SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(),
-                                                 "mandrill_128.pkm");
-
+    SkData* loadPKM() {
+        SkString pkmFilename = GetResourcePath("mandrill_128.pkm");
         // Expand the data
-        SkAutoDataUnref fileData(SkData::NewFromFileName(filename.c_str()));
+        SkAutoDataUnref fileData(SkData::NewFromFileName(pkmFilename.c_str()));
         if (NULL == fileData) {
             SkDebugf("Could not open the file. Did you forget to set the resourcePath?\n");
             return NULL;
@@ -210,8 +207,11 @@
     }
 
     virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
+        SkPixelRef* pr = fBitmap.pixelRef();
         for (int i = 0; i < loops; ++i) {
-            this->fBitmap.pixelRef()->notifyPixelsChanged();
+            if (pr) {
+                pr->notifyPixelsChanged();
+            }
             canvas->drawBitmap(this->fBitmap, 0, 0, NULL);
         }
     }
diff --git a/bench/FontCacheBench.cpp b/bench/FontCacheBench.cpp
index 0e75c9c..697bde6 100644
--- a/bench/FontCacheBench.cpp
+++ b/bench/FontCacheBench.cpp
@@ -7,6 +7,7 @@
 
 #include "Benchmark.h"
 #include "SkCanvas.h"
+#include "SkChecksum.h"
 #include "SkFontHost.h"
 #include "SkPaint.h"
 #include "SkString.h"
@@ -64,23 +65,12 @@
     return value ^ (value >> 8);
 }
 
-static uint32_t hasher2(uint32_t h) {
-    h ^= h >> 16;
-    h *= 0x85ebca6b;
-    h ^= h >> 13;
-    h *= 0xc2b2ae35;
-    h ^= h >> 16;
-
-    h ^= (h >> 8);
-    return h;
-}
-
 static const struct {
     const char* fName;
     HasherProc  fHasher;
 } gRec[] = {
     { "hasher0",  hasher0 },
-    { "hasher2",  hasher2 },
+    { "hasher2",  SkChecksum::Mix },
 };
 
 #define kMaxHashBits   12
diff --git a/bench/GMBench.cpp b/bench/GMBench.cpp
index 41a8e8c..bdf3290 100644
--- a/bench/GMBench.cpp
+++ b/bench/GMBench.cpp
@@ -8,7 +8,7 @@
 #include "GMBench.h"
 
 GMBench::GMBench(skiagm::GM* gm) : fGM(gm) {
-    fName.printf("GM:%s", gm->getName());
+    fName.printf("GM_%s", gm->getName());
 }
 
 GMBench::~GMBench() { delete fGM; }
@@ -49,3 +49,4 @@
     SkISize size = fGM->getISize();
     return SkIPoint::Make(size.fWidth, size.fHeight);
 }
+
diff --git a/bench/GMBench.h b/bench/GMBench.h
index 75cee6c..e224052 100644
--- a/bench/GMBench.h
+++ b/bench/GMBench.h
@@ -4,6 +4,8 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+#ifndef GMBench_DEFINED
+#define GMBench_DEFINED
 
 #include "Benchmark.h"
 #include "SkCanvas.h"
@@ -29,3 +31,5 @@
     SkString    fName;
     typedef Benchmark INHERITED;
 };
+
+#endif
diff --git a/bench/GrResourceCacheBench.cpp b/bench/GrResourceCacheBench.cpp
index 93ae356..d86ccf4 100644
--- a/bench/GrResourceCacheBench.cpp
+++ b/bench/GrResourceCacheBench.cpp
@@ -9,7 +9,7 @@
 #if SK_SUPPORT_GPU
 
 #include "Benchmark.h"
-#include "GrCacheable.h"
+#include "GrGpuResource.h"
 #include "GrContext.h"
 #include "GrResourceCache.h"
 #include "GrStencilBuffer.h"
@@ -21,21 +21,21 @@
     CACHE_SIZE_BYTES = 2 * 1024 * 1024,
 };
 
-class StencilResource : public GrCacheable {
+class StencilResource : public GrGpuResource {
 public:
     SK_DECLARE_INST_COUNT(StencilResource);
-    StencilResource(int id)
-        : fID(id) {
+    StencilResource(GrGpu* gpu, int id)
+        : INHERITED(gpu, false)
+        , fID(id) {
+        this->registerWithCache();
     }
 
+    virtual ~StencilResource() { this->release(); }
+
     virtual size_t gpuMemorySize() const SK_OVERRIDE {
         return 100 + ((fID % 1 == 0) ? -5 : 6);
     }
 
-    virtual bool isValidOnGpu() const SK_OVERRIDE {
-        return true;
-    }
-
     static GrResourceKey ComputeKey(int width, int height, int sampleCnt) {
         return GrStencilBuffer::ComputeKey(width, height, sampleCnt);
     }
@@ -43,24 +43,24 @@
     int fID;
 
 private:
-    typedef GrCacheable INHERITED;
+    typedef GrGpuResource INHERITED;
 };
 
-class TextureResource : public GrCacheable {
+class TextureResource : public GrGpuResource {
 public:
     SK_DECLARE_INST_COUNT(TextureResource);
-    TextureResource(int id)
-        : fID(id) {
+    TextureResource(GrGpu* gpu, int id)
+        : INHERITED(gpu, false)
+        , fID(id) {
+        this->registerWithCache();
     }
 
+    virtual ~TextureResource() { this->release(); }
+
     virtual size_t gpuMemorySize() const SK_OVERRIDE {
         return 100 + ((fID % 1 == 0) ? -40 : 33);
     }
 
-    virtual bool isValidOnGpu() const SK_OVERRIDE {
-        return true;
-    }
-
     static GrResourceKey ComputeKey(const GrTextureDesc& desc) {
         return GrTextureImpl::ComputeScratchKey(desc);
     }
@@ -68,7 +68,7 @@
     int fID;
 
 private:
-    typedef GrCacheable INHERITED;
+    typedef GrGpuResource INHERITED;
 };
 
 static void get_stencil(int i, int* w, int* h, int* s) {
@@ -91,7 +91,7 @@
         int w, h, s;
         get_stencil(i, &w, &h, &s);
         GrResourceKey key = GrStencilBuffer::ComputeKey(w, h, s);
-        GrCacheable* resource = SkNEW_ARGS(StencilResource, (i));
+        GrGpuResource* resource = SkNEW_ARGS(StencilResource, (gpu, i));
         cache->purgeAsNeeded(1, resource->gpuMemorySize());
         cache->addResource(key, resource);
         resource->unref();
@@ -101,7 +101,7 @@
         GrTextureDesc desc;
         get_texture_desc(i, &desc);
         GrResourceKey key =  TextureResource::ComputeKey(desc);
-        GrCacheable* resource = SkNEW_ARGS(TextureResource, (i));
+        GrGpuResource* resource = SkNEW_ARGS(TextureResource, (gpu, i));
         cache->purgeAsNeeded(1, resource->gpuMemorySize());
         cache->addResource(key, resource);
         resource->unref();
@@ -114,7 +114,7 @@
         GrTextureDesc desc;
         get_texture_desc(k, &desc);
         GrResourceKey key = TextureResource::ComputeKey(desc);
-        GrCacheable* item = cache->find(key);
+        GrGpuResource* item = cache->find(key);
         if (NULL == item) {
             SkFAIL("cache add does not work as expected");
             return;
@@ -128,7 +128,7 @@
         int w, h, s;
         get_stencil(k, &w, &h, &s);
         GrResourceKey key = StencilResource::ComputeKey(w, h, s);
-        GrCacheable* item = cache->find(key);
+        GrGpuResource* item = cache->find(key);
         if (NULL == item) {
             SkFAIL("cache add does not work as expected");
             return;
@@ -145,8 +145,8 @@
         get_texture_desc(k, &desc);
         desc.fHeight |= 1;
         GrResourceKey key = TextureResource::ComputeKey(desc);
-        GrCacheable* item = cache->find(key);
-        if (NULL != item) {
+        GrGpuResource* item = cache->find(key);
+        if (item) {
             SkFAIL("cache add does not work as expected");
             return;
         }
@@ -156,8 +156,8 @@
         get_stencil(k, &w, &h, &s);
         h |= 1;
         GrResourceKey key = StencilResource::ComputeKey(w, h, s);
-        GrCacheable* item = cache->find(key);
-        if (NULL != item) {
+        GrGpuResource* item = cache->find(key);
+        if (item) {
             SkFAIL("cache add does not work as expected");
             return;
         }
diff --git a/bench/GradientBench.cpp b/bench/GradientBench.cpp
index f3e783e..e5e5fc3 100644
--- a/bench/GradientBench.cpp
+++ b/bench/GradientBench.cpp
@@ -207,7 +207,6 @@
     enum {
         W   = 400,
         H   = 400,
-        kRepeat = 15,
     };
 public:
     SkShader* makeShader(GradType gradType, GradData data, SkShader::TileMode tm, float scale) {
@@ -275,7 +274,7 @@
         }
 
         SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
-        for (int i = 0; i < loops * kRepeat; i++) {
+        for (int i = 0; i < loops; i++) {
             switch (fGeomType) {
                case kRect_GeomType:
                    canvas->drawRect(r, paint);
diff --git a/bench/HairlinePathBench.cpp b/bench/HairlinePathBench.cpp
index e7e2b42..7b413c4 100644
--- a/bench/HairlinePathBench.cpp
+++ b/bench/HairlinePathBench.cpp
@@ -181,7 +181,7 @@
 #if SK_SUPPORT_GPU
         GrContext* context = canvas->getGrContext();
         // This is a workaround for skbug.com/2078. See also skbug.com/2033.
-        if (NULL != context) {
+        if (context) {
             GrTestTarget tt;
             context->getTestTarget(&tt);
             if (tt.target()->caps()->pathRenderingSupport()) {
diff --git a/bench/ImageCacheBench.cpp b/bench/ImageCacheBench.cpp
index e65d1fc..0f8fdf2 100644
--- a/bench/ImageCacheBench.cpp
+++ b/bench/ImageCacheBench.cpp
@@ -6,28 +6,46 @@
  */
 
 #include "Benchmark.h"
-#include "SkScaledImageCache.h"
+#include "SkResourceCache.h"
+
+namespace {
+static void* gGlobalAddress;
+class TestKey : public SkResourceCache::Key {
+public:
+    void*    fPtr;
+    intptr_t fValue;
+
+    TestKey(intptr_t value) : fPtr(&gGlobalAddress), fValue(value) {
+        this->init(sizeof(fPtr) + sizeof(fValue));
+    }
+};
+struct TestRec : public SkResourceCache::Rec {
+    TestKey     fKey;
+    intptr_t    fValue;
+
+    TestRec(const TestKey& key, intptr_t value) : fKey(key), fValue(value) {}
+
+    virtual const Key& getKey() const SK_OVERRIDE { return fKey; }
+    virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + sizeof(fValue); }
+
+    static bool Visitor(const SkResourceCache::Rec&, void*) {
+        return true;
+    }
+};
+}
 
 class ImageCacheBench : public Benchmark {
-    SkScaledImageCache  fCache;
-    SkBitmap            fBM;
+    SkResourceCache fCache;
 
     enum {
-        DIM = 1,
         CACHE_COUNT = 500
     };
 public:
-    ImageCacheBench()  : fCache(CACHE_COUNT * 100) {
-        fBM.allocN32Pixels(DIM, DIM);
-    }
+    ImageCacheBench()  : fCache(CACHE_COUNT * 100) {}
 
     void populateCache() {
-        SkScalar scale = 1;
         for (int i = 0; i < CACHE_COUNT; ++i) {
-            SkBitmap tmp;
-            tmp.allocN32Pixels(1, 1);
-            fCache.unlock(fCache.addAndLock(fBM, scale, scale, tmp));
-            scale += 1;
+            fCache.add(SkNEW_ARGS(TestRec, (TestKey(i), i)));
         }
     }
 
@@ -41,10 +59,11 @@
             this->populateCache();
         }
 
-        SkBitmap tmp;
-        // search for a miss (-1 scale)
+        TestKey key(-1);
+        // search for a miss (-1)
         for (int i = 0; i < loops; ++i) {
-            (void)fCache.findAndLock(fBM, -1, -1, &tmp);
+            SkDEBUGCODE(bool found =) fCache.find(key, TestRec::Visitor, NULL);
+            SkASSERT(!found);
         }
     }
 
diff --git a/bench/ImageDecodeBench.cpp b/bench/ImageDecodeBench.cpp
index 47993cf..3ce2fb0 100644
--- a/bench/ImageDecodeBench.cpp
+++ b/bench/ImageDecodeBench.cpp
@@ -25,7 +25,7 @@
     , fFilename(filename)
     , fStream()
     , fValid(false) {
-        fName.append(SkOSPath::SkBasename(filename));
+        fName.append(SkOSPath::Basename(filename));
     }
 
     virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
diff --git a/bench/ImageFilterDAGBench.cpp b/bench/ImageFilterDAGBench.cpp
index 29d1da1..680628e 100644
--- a/bench/ImageFilterDAGBench.cpp
+++ b/bench/ImageFilterDAGBench.cpp
@@ -18,8 +18,7 @@
 
 class ImageFilterDAGBench : public Benchmark {
 public:
-    ImageFilterDAGBench() {
-    }
+    ImageFilterDAGBench() {}
 
 protected:
     virtual const char* onGetName() SK_OVERRIDE {
@@ -27,16 +26,18 @@
     }
 
     virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
-        SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(20.0f, 20.0f));
-        SkImageFilter* inputs[kNumInputs];
-        for (int i = 0; i < kNumInputs; ++i) {
-            inputs[i] = blur.get();
+        for (int j = 0; j < loops; j++) {
+            SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(20.0f, 20.0f));
+            SkImageFilter* inputs[kNumInputs];
+            for (int i = 0; i < kNumInputs; ++i) {
+                inputs[i] = blur.get();
+            }
+            SkAutoTUnref<SkImageFilter> merge(SkMergeImageFilter::Create(inputs, kNumInputs));
+            SkPaint paint;
+            paint.setImageFilter(merge);
+            SkRect rect = SkRect::Make(SkIRect::MakeWH(400, 400));
+            canvas->drawRect(rect, paint);
         }
-        SkAutoTUnref<SkImageFilter> merge(SkMergeImageFilter::Create(inputs, kNumInputs));
-        SkPaint paint;
-        paint.setImageFilter(merge);
-        SkRect rect = SkRect::Make(SkIRect::MakeWH(400, 400));
-        canvas->drawRect(rect, paint);
     }
 
 private:
diff --git a/bench/MagnifierBench.cpp b/bench/MagnifierBench.cpp
index 875ec4f..c47dcdc 100644
--- a/bench/MagnifierBench.cpp
+++ b/bench/MagnifierBench.cpp
@@ -4,8 +4,8 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "Benchmark.h"
-#include "SkBitmapDevice.h"
 #include "SkCanvas.h"
 #include "SkMagnifierImageFilter.h"
 #include "SkRandom.h"
diff --git a/bench/MemcpyBench.cpp b/bench/MemcpyBench.cpp
index f550192..567320b 100644
--- a/bench/MemcpyBench.cpp
+++ b/bench/MemcpyBench.cpp
@@ -67,87 +67,6 @@
 BENCH(memcpy32_memcpy, 10000)
 BENCH(memcpy32_memcpy, 100000)
 
-// Let the compiler's autovectorizer do what it thinks is best.
-static void memcpy32_autovectorize(uint32_t* dst, const uint32_t* src, int count) {
-    while (count --> 0) {
-        *dst++ = *src++;
-    }
-}
-BENCH(memcpy32_autovectorize, 10)
-BENCH(memcpy32_autovectorize, 100)
-BENCH(memcpy32_autovectorize, 1000)
-BENCH(memcpy32_autovectorize, 10000)
-BENCH(memcpy32_autovectorize, 100000)
-
-#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
-
-// Align dst to 16 bytes, then use aligned stores.  src isn't algined, so use unaligned loads.
-static void memcpy32_sse2_align(uint32_t* dst, const uint32_t* src, int count) {
-    if (count >= 16) {
-        while (uintptr_t(dst) & 0xF) {
-            *dst++ = *src++;
-            count--;
-        }
-
-        __m128i* dst128 = reinterpret_cast<__m128i*>(dst);
-        const __m128i* src128 = reinterpret_cast<const __m128i*>(src);
-        dst += 16 * (count / 16);
-        src += 16 * (count / 16);
-        while (count >= 16) {
-            __m128i a = _mm_loadu_si128(src128++);
-            __m128i b = _mm_loadu_si128(src128++);
-            __m128i c = _mm_loadu_si128(src128++);
-            __m128i d = _mm_loadu_si128(src128++);
-
-            _mm_store_si128(dst128++, a);
-            _mm_store_si128(dst128++, b);
-            _mm_store_si128(dst128++, c);
-            _mm_store_si128(dst128++, d);
-
-            count -= 16;
-        }
-    }
-
-    while (count --> 0) {
-        *dst++ = *src++;
-    }
-}
-BENCH(memcpy32_sse2_align, 10)
-BENCH(memcpy32_sse2_align, 100)
-BENCH(memcpy32_sse2_align, 1000)
-BENCH(memcpy32_sse2_align, 10000)
-BENCH(memcpy32_sse2_align, 100000)
-
-// Leave both dst and src unaliged, and so use unaligned stores for dst and unaligned loads for src.
-static void memcpy32_sse2_unalign(uint32_t* dst, const uint32_t* src, int count) {
-    __m128i* dst128 = reinterpret_cast<__m128i*>(dst);
-    const __m128i* src128 = reinterpret_cast<const __m128i*>(src);
-    dst += 16 * (count / 16);
-    src += 16 * (count / 16);
-    while (count >= 16) {
-        __m128i a = _mm_loadu_si128(src128++);
-        __m128i b = _mm_loadu_si128(src128++);
-        __m128i c = _mm_loadu_si128(src128++);
-        __m128i d = _mm_loadu_si128(src128++);
-
-        _mm_storeu_si128(dst128++, a);
-        _mm_storeu_si128(dst128++, b);
-        _mm_storeu_si128(dst128++, c);
-        _mm_storeu_si128(dst128++, d);
-
-        count -= 16;
-    }
-
-    while (count --> 0) {
-        *dst++ = *src++;
-    }
-}
-BENCH(memcpy32_sse2_unalign, 10)
-BENCH(memcpy32_sse2_unalign, 100)
-BENCH(memcpy32_sse2_unalign, 1000)
-BENCH(memcpy32_sse2_unalign, 10000)
-BENCH(memcpy32_sse2_unalign, 100000)
-
 // Test our chosen best, from SkUtils.h
 BENCH(sk_memcpy32, 10)
 BENCH(sk_memcpy32, 100)
@@ -155,6 +74,4 @@
 BENCH(sk_memcpy32, 10000)
 BENCH(sk_memcpy32, 100000)
 
-#endif // SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
-
 #undef BENCH
diff --git a/bench/MemoryBench.cpp b/bench/MemoryBench.cpp
index 3fc46dc..05ec83b 100644
--- a/bench/MemoryBench.cpp
+++ b/bench/MemoryBench.cpp
@@ -56,110 +56,3 @@
 DEF_BENCH( return new ChunkAllocBench(64); )
 DEF_BENCH( return new ChunkAllocBench(8*1024); )
 
-static int* calloc(size_t num) {
-    return (int*)sk_calloc_throw(num*sizeof(int));
-}
-
-static int* malloc_bzero(size_t num) {
-    const size_t bytes = num*sizeof(int);
-    int* ints = (int*)sk_malloc_throw(bytes);
-    sk_bzero(ints, bytes);
-    return ints;
-}
-
-class ZerosBench : public Benchmark {
-    size_t   fNum;
-    bool     fRead;
-    bool     fWrite;
-    bool     fUseCalloc;
-    SkString fName;
-public:
-    ZerosBench(size_t num, bool read, bool write, bool useCalloc)
-        : fNum(num)
-        , fRead(read)
-        , fWrite(write)
-        , fUseCalloc(useCalloc) {
-        fName.printf("memory_%s", useCalloc ? "calloc" : "malloc_bzero");
-        if (read && write) {
-            fName.appendf("_rw");
-        } else if (read) {
-            fName.appendf("_r");
-        } else if (write) {
-            fName.appendf("_w");
-        }
-        fName.appendf("_"SK_SIZE_T_SPECIFIER, num);
-    }
-
-    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
-        return backend == kNonRendering_Backend;
-    }
-
-protected:
-    virtual const char* onGetName() SK_OVERRIDE {
-        return fName.c_str();
-    }
-
-    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
-        for (int i = 0; i < loops; i++) {
-            int* zeros = fUseCalloc ? calloc(fNum) : malloc_bzero(fNum);
-            if (fRead) {
-                volatile int x = 15;
-                for (size_t j = 0; j < fNum; j++) {
-                    x ^= zeros[j];
-                }
-            }
-            if (fWrite) {
-                for (size_t j = 0; j < fNum; j++) {
-                    zeros[j] = 15;
-                }
-            }
-            sk_free(zeros);
-        }
-    }
-};
-
-//                             zero count  r  w  useCalloc?
-DEF_BENCH(return new ZerosBench(1024*1024, 0, 0, 0))
-DEF_BENCH(return new ZerosBench(1024*1024, 0, 0, 1))
-DEF_BENCH(return new ZerosBench(1024*1024, 0, 1, 0))
-DEF_BENCH(return new ZerosBench(1024*1024, 0, 1, 1))
-DEF_BENCH(return new ZerosBench(1024*1024, 1, 0, 0))
-DEF_BENCH(return new ZerosBench(1024*1024, 1, 0, 1))
-DEF_BENCH(return new ZerosBench(1024*1024, 1, 1, 0))
-DEF_BENCH(return new ZerosBench(1024*1024, 1, 1, 1))
-
-DEF_BENCH(return new ZerosBench(256*1024, 0, 0, 0))
-DEF_BENCH(return new ZerosBench(256*1024, 0, 0, 1))
-DEF_BENCH(return new ZerosBench(256*1024, 0, 1, 0))
-DEF_BENCH(return new ZerosBench(256*1024, 0, 1, 1))
-DEF_BENCH(return new ZerosBench(256*1024, 1, 0, 0))
-DEF_BENCH(return new ZerosBench(256*1024, 1, 0, 1))
-DEF_BENCH(return new ZerosBench(256*1024, 1, 1, 0))
-DEF_BENCH(return new ZerosBench(256*1024, 1, 1, 1))
-
-DEF_BENCH(return new ZerosBench(4*1024, 0, 0, 0))
-DEF_BENCH(return new ZerosBench(4*1024, 0, 0, 1))
-DEF_BENCH(return new ZerosBench(4*1024, 0, 1, 0))
-DEF_BENCH(return new ZerosBench(4*1024, 0, 1, 1))
-DEF_BENCH(return new ZerosBench(4*1024, 1, 0, 0))
-DEF_BENCH(return new ZerosBench(4*1024, 1, 0, 1))
-DEF_BENCH(return new ZerosBench(4*1024, 1, 1, 0))
-DEF_BENCH(return new ZerosBench(4*1024, 1, 1, 1))
-
-DEF_BENCH(return new ZerosBench(300, 0, 0, 0))
-DEF_BENCH(return new ZerosBench(300, 0, 0, 1))
-DEF_BENCH(return new ZerosBench(300, 0, 1, 0))
-DEF_BENCH(return new ZerosBench(300, 0, 1, 1))
-DEF_BENCH(return new ZerosBench(300, 1, 0, 0))
-DEF_BENCH(return new ZerosBench(300, 1, 0, 1))
-DEF_BENCH(return new ZerosBench(300, 1, 1, 0))
-DEF_BENCH(return new ZerosBench(300, 1, 1, 1))
-
-DEF_BENCH(return new ZerosBench(4, 0, 0, 0))
-DEF_BENCH(return new ZerosBench(4, 0, 0, 1))
-DEF_BENCH(return new ZerosBench(4, 0, 1, 0))
-DEF_BENCH(return new ZerosBench(4, 0, 1, 1))
-DEF_BENCH(return new ZerosBench(4, 1, 0, 0))
-DEF_BENCH(return new ZerosBench(4, 1, 0, 1))
-DEF_BENCH(return new ZerosBench(4, 1, 1, 0))
-DEF_BENCH(return new ZerosBench(4, 1, 1, 1))
diff --git a/bench/MergeBench.cpp b/bench/MergeBench.cpp
index a6bb3ac..2e1ca32 100644
--- a/bench/MergeBench.cpp
+++ b/bench/MergeBench.cpp
@@ -4,8 +4,8 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "Benchmark.h"
-#include "SkBitmapDevice.h"
 #include "SkBitmapSource.h"
 #include "SkCanvas.h"
 #include "SkMergeImageFilter.h"
diff --git a/bench/MutexBench.cpp b/bench/MutexBench.cpp
index 67648b5..59f054c 100644
--- a/bench/MutexBench.cpp
+++ b/bench/MutexBench.cpp
@@ -19,7 +19,7 @@
     }
 
     virtual void onDraw(const int loops, SkCanvas*) {
-        SK_DECLARE_STATIC_MUTEX(mu);
+        SkMutex mu;
         for (int i = 0; i < loops; i++) {
             mu.acquire();
             mu.release();
diff --git a/bench/PatchBench.cpp b/bench/PatchBench.cpp
new file mode 100644
index 0000000..744141a
--- /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 "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkPaint.h"
+#include "SkPatchUtils.h"
+#include "SkString.h"
+
+/**
+ * This bench measures the rendering time of the call SkCanvas::drawPatch with different types of 
+ * input patches (regular case, with loops, a square, with a big difference between "parallel" 
+ * sides). This bench also tests the different combination of optional parameters for the function 
+ * (passing texture coordinates and colors, only textures coordinates, only colors or none).
+ * Finally, it applies a scale to test if the size affects the rendering time. 
+ */
+
+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* createShader() {
+        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 onPreDraw() SK_OVERRIDE {
+        this->setCubics();
+        this->setColors();
+        this->setTexCoords();
+        this->setupPaint(&fPaint);
+        switch (fVertexMode) {
+            case kTexCoords_VertexMode:
+            case kBoth_VertexMode:
+                fPaint.setShader(this->createShader())->unref();
+                break;
+            default:
+                fPaint.setShader(NULL);
+                break;
+        }
+    }
+
+    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
+        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() SK_OVERRIDE {
+        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() SK_OVERRIDE {
+        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() SK_OVERRIDE {
+        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); )
diff --git a/bench/PatchGridBench.cpp b/bench/PatchGridBench.cpp
new file mode 100644
index 0000000..c250781
--- /dev/null
+++ b/bench/PatchGridBench.cpp
@@ -0,0 +1,259 @@
+/*
+ * 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 "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkPaint.h"
+#include "SkPatchGrid.h"
+#include "SkString.h"
+
+ /**
+ * This bench measures the rendering time of a gridof patches. 
+ * This bench also tests the different combination of optional parameters for the function 
+ * (passing texture coordinates and colors, only textures coordinates, only colors or none).
+ * Finally, it also has 3 possible sizes small, medium and big to test if the size of the patches
+ * in the grid affects time. 
+ */
+
+class PatchGridBench : public Benchmark {
+    
+public:
+    
+    enum Size {
+        kSmall_Size,
+        kMedium_Size,
+        kBig_Size
+    };
+    
+    enum VertexMode {
+        kNone_VertexMode,
+        kColors_VertexMode,
+        kTexCoords_VertexMode,
+        kBoth_VertexMode
+    };
+    
+    PatchGridBench(Size size, VertexMode vertexMode)
+    : fVertexMode(vertexMode)
+    , fSize(size) { }
+    
+    void setScale(SkCanvas* canvas){
+        switch (fSize) {
+            case kSmall_Size:
+                canvas->scale(0.1f, 0.1f);
+                break;
+            case kMedium_Size:
+                canvas->scale(1.0f, 1.0f);
+                break;
+            case kBig_Size:
+                canvas->scale(3.0f, 3.0f);
+                break;
+        }
+    }
+    
+    void setGrid() {
+        SkPoint vertices[4][5] = {
+            {{50,50}, {150,50}, {250,50},{350,50},{450,50}},
+            {{50,150}, {120,120}, {250,150},{350,150},{450,150}},
+            {{50,250}, {150,250}, {250,250},{350,250},{450,250}},
+            {{100,300}, {150,350}, {250,350},{350,350},{450,350}}
+        };
+        
+        SkColor cornerColors[4][5] = {
+            {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE},
+            {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED},
+            {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE},
+            {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED},
+        };
+        
+        SkPoint texCoords[4][5] = {
+            {{0.0f,0.0f}, {1.0f,0.0f}, {2.0f,0.0f}, {3.0f,0.0f}, {4.0f,0.0f}},
+            {{0.0f,1.0f}, {1.0f,1.0f}, {2.0f,1.0f}, {3.0f,1.0f}, {4.0f,1.0f}},
+            {{0.0f,2.0f}, {1.0f,2.0f}, {2.0f,2.0f}, {3.0f,2.0f}, {4.0f,2.0f}},
+            {{0.0f,3.0f}, {1.0f,3.0f}, {2.0f,3.0f}, {3.0f,3.0f}, {4.0f,3.0f}},
+        };
+        
+        SkPoint hrzCtrl[4][8] = {
+            {{75,30},{125,45},{175,70},{225,20},{275,50},{325,50},{375,5},{425,90}},
+            {{75,150},{125,150},{175,150},{225,150},{275,150},{325,150},{375,150},{425,150}},
+            {{75,250},{125,250},{175,250},{225,250},{275,200},{325,150},{375,250},{425,250}},
+            {{75,350},{125,350},{175,350},{225,350},{275,350},{325,350},{375,350},{425,350}}
+        };
+        
+        SkPoint vrtCtrl[6][5] = {
+            {{50,75},{150,75},{250,75},{350,75},{450,75}},
+            {{50,125},{150,125},{250,125},{350,125},{450,125}},
+            {{50,175},{150,175},{220,225},{350,175},{470,225}},
+            {{50,225},{150,225},{220,175},{350,225},{470,155}},
+            {{50,275},{150,275},{250,275},{350,275},{400,305}},
+            {{50,325},{150,325},{250,325},{350,325},{450,325}}
+        };
+        
+        static const int kRows = 3;
+        static const int kCols = 4;
+        
+        fGrid.reset(kRows, kCols, SkPatchGrid::kColors_VertexType, NULL);
+        for (int i = 0; i < kRows; i++) {
+            for (int j = 0; j < kCols; j++) {
+                SkPoint points[12];
+                
+                //set corners
+                points[SkPatchUtils::kTopP0_CubicCtrlPts] = vertices[i][j];
+                points[SkPatchUtils::kTopP3_CubicCtrlPts] = vertices[i][j + 1];
+                points[SkPatchUtils::kBottomP0_CubicCtrlPts] = vertices[i + 1][j];
+                points[SkPatchUtils::kBottomP3_CubicCtrlPts] = vertices[i + 1][j + 1];
+                
+                points[SkPatchUtils::kTopP1_CubicCtrlPts] = hrzCtrl[i][j * 2];
+                points[SkPatchUtils::kTopP2_CubicCtrlPts] = hrzCtrl[i][j * 2 + 1];
+                points[SkPatchUtils::kBottomP1_CubicCtrlPts] = hrzCtrl[i + 1][j * 2];
+                points[SkPatchUtils::kBottomP2_CubicCtrlPts] = hrzCtrl[i + 1][j * 2 + 1];
+                
+                points[SkPatchUtils::kLeftP1_CubicCtrlPts] = vrtCtrl[i * 2][j];
+                points[SkPatchUtils::kLeftP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j];
+                points[SkPatchUtils::kRightP1_CubicCtrlPts] = vrtCtrl[i * 2][j + 1];
+                points[SkPatchUtils::kRightP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j + 1];
+                
+                SkColor colors[4];
+                colors[0] = cornerColors[i][j];
+                colors[1] = cornerColors[i][j + 1];
+                colors[3] = cornerColors[i + 1][j];
+                colors[2] = cornerColors[i + 1][j + 1];
+                
+                SkPoint texs[4];
+                texs[0] = texCoords[i][j];
+                texs[1] = texCoords[i][j + 1];
+                texs[3] = texCoords[i + 1][j];
+                texs[2] = texCoords[i + 1][j + 1];
+                
+                switch (fVertexMode) {
+                    case kNone_VertexMode:
+                        fGrid.setPatch(j, i, points, NULL, NULL);
+                        break;
+                    case kColors_VertexMode:
+                        fGrid.setPatch(j, i, points, colors, NULL);
+                        break;
+                    case kTexCoords_VertexMode:
+                        fGrid.setPatch(j, i, points, NULL, texs);
+                        break;
+                    case kBoth_VertexMode:
+                        fGrid.setPatch(j, i, points, colors, texs);
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+    
+    // override this method to change the shader
+    SkShader* createShader() {
+        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 size;
+        switch (fSize) {
+            case kSmall_Size:
+                size.set("small");
+                break;
+            case kMedium_Size:
+                size.set("medium");
+                break;
+            case kBig_Size:
+                size.set("big");
+                break;
+            default:
+                break;
+        }
+        fName.printf("patch_grid_%s_%s", vertexMode.c_str(), size.c_str());
+        return fName.c_str();
+    }
+    
+    virtual void onPreDraw() SK_OVERRIDE {
+        this->setGrid();
+        switch (fVertexMode) {
+            case kTexCoords_VertexMode:
+            case kBoth_VertexMode:
+                fPaint.setShader(createShader())->unref();
+                break;
+            default:
+                fPaint.setShader(NULL);
+                break;
+        }
+        this->setupPaint(&fPaint);
+    }
+
+    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
+        this->setScale(canvas);
+        for (int i = 0; i < loops; i++) {
+            fGrid.draw(canvas, fPaint);
+        }
+    }
+
+    SkPaint     fPaint;
+    SkString    fName;
+    SkPatchGrid fGrid;
+    VertexMode  fVertexMode;
+    Size        fSize;
+    
+    typedef Benchmark INHERITED;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size,
+                                     PatchGridBench::kNone_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size,
+                                     PatchGridBench::kColors_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size,
+                                     PatchGridBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size,
+                                     PatchGridBench::kBoth_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size,
+                                     PatchGridBench::kNone_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size,
+                                     PatchGridBench::kColors_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size,
+                                     PatchGridBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size,
+                                     PatchGridBench::kBoth_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size,
+                                     PatchGridBench::kNone_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size,
+                                     PatchGridBench::kColors_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size,
+                                     PatchGridBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size,
+                                     PatchGridBench::kBoth_VertexMode); )
diff --git a/bench/PathBench.cpp b/bench/PathBench.cpp
index 59b3bfa..297d36d 100644
--- a/bench/PathBench.cpp
+++ b/bench/PathBench.cpp
@@ -1012,8 +1012,11 @@
 DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRoundRect_Type); )
 DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kOval_Type); )
 
+// These seem to be optimized away, which is troublesome for timing.
+/*
 DEF_BENCH( return new ConicBench_Chop5() )
 DEF_BENCH( return new ConicBench_ChopHalf() )
 DEF_BENCH( return new ConicBench_ComputeError() )
 DEF_BENCH( return new ConicBench_asQuadTol() )
 DEF_BENCH( return new ConicBench_quadPow2() )
+*/
diff --git a/bench/PictureNestingBench.cpp b/bench/PictureNestingBench.cpp
new file mode 100644
index 0000000..c284883
--- /dev/null
+++ b/bench/PictureNestingBench.cpp
@@ -0,0 +1,167 @@
+/*
+ * 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 "SkCanvas.h"
+#include "SkColor.h"
+#include "SkNullCanvas.h"
+#include "SkPaint.h"
+#include "SkPicture.h"
+#include "SkPictureRecorder.h"
+#include "SkString.h"
+
+class PictureNesting : public Benchmark {
+public:
+    PictureNesting(const char* name, int maxLevel, int maxPictureLevel)
+        : fMaxLevel(maxLevel)
+        , fMaxPictureLevel(maxPictureLevel) {
+
+        fPaint.setColor(SK_ColorRED);
+        fPaint.setAntiAlias(true);
+        fPaint.setStyle(SkPaint::kStroke_Style);
+        SkAutoTUnref<SkCanvas> nullCanvas(SkCreateNullCanvas());
+        fName.printf("picture_nesting_%s_%d", name, this->sierpinsky(nullCanvas, 0, fPaint));
+    }
+
+protected:
+    virtual const char* onGetName() SK_OVERRIDE {
+        return fName.c_str();
+    }
+
+    void doDraw(SkCanvas* canvas) {
+        SkIPoint canvasSize = onGetSize();
+        canvas->save();
+        canvas->scale(SkIntToScalar(canvasSize.x()), SkIntToScalar(canvasSize.y()));
+
+        this->sierpinsky(canvas, 0, fPaint);
+
+        canvas->restore();
+    }
+
+    int sierpinsky(SkCanvas* canvas, int lvl, const SkPaint& paint) {
+        if (++lvl > fMaxLevel) {
+            return 0;
+        }
+
+        int pics = 0;
+        bool recordPicture = lvl <= fMaxPictureLevel;
+        SkPictureRecorder recorder;
+        SkCanvas* c = canvas;
+
+        if (recordPicture) {
+            c = recorder.beginRecording(1, 1);
+            pics++;
+        }
+
+        c->drawLine(0.5, 0, 0, 1, paint);
+        c->drawLine(0.5, 0, 1, 1, paint);
+        c->drawLine(0,   1, 1, 1, paint);
+
+        c->save();
+            c->scale(0.5, 0.5);
+
+            c->translate(0, 1);
+            pics += this->sierpinsky(c, lvl, paint);
+
+            c->translate(1, 0);
+            pics += this->sierpinsky(c, lvl, paint);
+
+            c->translate(-0.5, -1);
+            pics += this->sierpinsky(c, lvl, paint);
+        c->restore();
+
+        if (recordPicture) {
+            SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+            canvas->drawPicture(picture);
+        }
+
+        return pics;
+    }
+
+    int fMaxLevel;
+    int fMaxPictureLevel;
+
+private:
+    SkString fName;
+    SkPaint  fPaint;
+
+    typedef Benchmark INHERITED;
+};
+
+class PictureNestingRecording : public PictureNesting {
+public:
+    PictureNestingRecording(int maxLevel, int maxPictureLevel)
+        : INHERITED("recording", maxLevel, maxPictureLevel) {
+    }
+
+protected:
+    virtual bool isSuitableFor(Backend backend) {
+        return backend == kNonRendering_Backend;
+    }
+
+    virtual void onDraw(const int loops, SkCanvas*) {
+        SkIPoint canvasSize = onGetSize();
+        SkPictureRecorder recorder;
+
+        for (int i = 0; i < loops; i++) {
+            SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
+                                                  SkIntToScalar(canvasSize.y()));
+            this->doDraw(c);
+            SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+        }
+    }
+
+private:
+    typedef PictureNesting INHERITED;
+};
+
+class PictureNestingPlayback : public PictureNesting {
+public:
+    PictureNestingPlayback(int maxLevel, int maxPictureLevel)
+        : INHERITED("playback", maxLevel, maxPictureLevel) {
+
+        SkIPoint canvasSize = onGetSize();
+        SkPictureRecorder recorder;
+        SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
+                                              SkIntToScalar(canvasSize.y()));
+
+        this->doDraw(c);
+        fPicture.reset(recorder.endRecording());
+    }
+
+protected:
+    virtual void onDraw(const int loops, SkCanvas* canvas) {
+        for (int i = 0; i < loops; i++) {
+            canvas->drawPicture(fPicture);
+        }
+    }
+
+private:
+    SkAutoTUnref<SkPicture> fPicture;
+
+    typedef PictureNesting INHERITED;
+};
+
+DEF_BENCH( return new PictureNestingRecording(8, 0); )
+DEF_BENCH( return new PictureNestingRecording(8, 1); )
+DEF_BENCH( return new PictureNestingRecording(8, 2); )
+DEF_BENCH( return new PictureNestingRecording(8, 3); )
+DEF_BENCH( return new PictureNestingRecording(8, 4); )
+DEF_BENCH( return new PictureNestingRecording(8, 5); )
+DEF_BENCH( return new PictureNestingRecording(8, 6); )
+DEF_BENCH( return new PictureNestingRecording(8, 7); )
+DEF_BENCH( return new PictureNestingRecording(8, 8); )
+
+DEF_BENCH( return new PictureNestingPlayback(8, 0); )
+DEF_BENCH( return new PictureNestingPlayback(8, 1); )
+DEF_BENCH( return new PictureNestingPlayback(8, 2); )
+DEF_BENCH( return new PictureNestingPlayback(8, 3); )
+DEF_BENCH( return new PictureNestingPlayback(8, 4); )
+DEF_BENCH( return new PictureNestingPlayback(8, 5); )
+DEF_BENCH( return new PictureNestingPlayback(8, 6); )
+DEF_BENCH( return new PictureNestingPlayback(8, 7); )
+DEF_BENCH( return new PictureNestingPlayback(8, 8); )
diff --git a/bench/PicturePlaybackBench.cpp b/bench/PicturePlaybackBench.cpp
index 0109c72..947a784 100644
--- a/bench/PicturePlaybackBench.cpp
+++ b/bench/PicturePlaybackBench.cpp
@@ -46,7 +46,7 @@
         const SkPoint translateDelta = getTranslateDelta(loops);
 
         for (int i = 0; i < loops; i++) {
-            picture->draw(canvas);
+            picture->playback(canvas);
             canvas->translate(translateDelta.fX, translateDelta.fY);
         }
     }
diff --git a/bench/PremulAndUnpremulAlphaOpsBench.cpp b/bench/PremulAndUnpremulAlphaOpsBench.cpp
index 311bdf2..6ab585e 100644
--- a/bench/PremulAndUnpremulAlphaOpsBench.cpp
+++ b/bench/PremulAndUnpremulAlphaOpsBench.cpp
@@ -30,7 +30,7 @@
     }
 
     virtual void onPreDraw() {
-        SkImageInfo info = SkImageInfo::Make(W, H, fColorType, kPremul_SkAlphaType);
+        SkImageInfo info = SkImageInfo::Make(W, H, fColorType, kUnpremul_SkAlphaType);
         fBmp1.allocPixels(info);   // used in writePixels
 
         for (int h = 0; h < H; ++h) {
diff --git a/bench/QuadTreeBench.cpp b/bench/QuadTreeBench.cpp
deleted file mode 100644
index 79078a8..0000000
--- a/bench/QuadTreeBench.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * 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 "SkCanvas.h"
-#include "SkQuadTree.h"
-#include "SkRandom.h"
-#include "SkString.h"
-
-// confine rectangles to a smallish area, so queries generally hit something, and overlap occurs:
-static const int GENERATE_EXTENTS = 1000;
-static const int NUM_BUILD_RECTS = 500;
-static const int NUM_QUERY_RECTS = 5000;
-static const int GRID_WIDTH = 100;
-static const SkIRect QUAD_TREE_BOUNDS = SkIRect::MakeLTRB(
-    -GENERATE_EXTENTS, -GENERATE_EXTENTS, 2 * GENERATE_EXTENTS, 2 * GENERATE_EXTENTS);
-
-typedef SkIRect (*MakeRectProc)(SkRandom&, int, int);
-
-// Time how long it takes to build an QuadTree
-class QuadTreeBuildBench : public Benchmark {
-public:
-    QuadTreeBuildBench(const char* name, MakeRectProc proc, SkBBoxHierarchy* tree)
-        : fTree(tree)
-        , fProc(proc) {
-        fName.append("quadtree_");
-        fName.append(name);
-        fName.append("_build");
-    }
-
-    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
-        return backend == kNonRendering_Backend;
-    }
-
-    virtual ~QuadTreeBuildBench() {
-        fTree->unref();
-    }
-protected:
-    virtual const char* onGetName() SK_OVERRIDE {
-        return fName.c_str();
-    }
-    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
-        SkRandom rand;
-        for (int i = 0; i < loops; ++i) {
-            for (int j = 0; j < NUM_BUILD_RECTS; ++j) {
-                fTree->insert(reinterpret_cast<void*>(j), fProc(rand, j, NUM_BUILD_RECTS),
-                              false);
-            }
-            fTree->clear();
-        }
-    }
-private:
-    SkBBoxHierarchy* fTree;
-    MakeRectProc fProc;
-    SkString fName;
-    typedef Benchmark INHERITED;
-};
-
-// Time how long it takes to perform queries on an QuadTree
-class QuadTreeQueryBench : public Benchmark {
-public:
-    enum QueryType {
-        kSmall_QueryType, // small queries
-        kLarge_QueryType, // large queries
-        kRandom_QueryType,// randomly sized queries
-        kFull_QueryType   // queries that cover everything
-    };
-
-    QuadTreeQueryBench(const char* name, MakeRectProc proc,
-                    QueryType q, SkBBoxHierarchy* tree)
-        : fTree(tree)
-        , fProc(proc)
-        , fQuery(q) {
-        fName.append("quadtree_");
-        fName.append(name);
-        fName.append("_query");
-    }
-
-    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
-        return backend == kNonRendering_Backend;
-    }
-
-    virtual ~QuadTreeQueryBench() {
-        fTree->unref();
-    }
-protected:
-    virtual const char* onGetName() SK_OVERRIDE {
-        return fName.c_str();
-    }
-    virtual void onPreDraw() SK_OVERRIDE {
-        SkRandom rand;
-        for (int j = 0; j < NUM_QUERY_RECTS; ++j) {
-            fTree->insert(reinterpret_cast<void*>(j),
-                          fProc(rand, j, NUM_QUERY_RECTS),
-                          false);
-        }
-        fTree->flushDeferredInserts();
-    }
-
-    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
-        SkRandom rand;
-        for (int i = 0; i < loops; ++i) {
-            SkTDArray<void*> hits;
-            SkIRect query;
-            switch(fQuery) {
-                case kSmall_QueryType:
-                    query.fLeft = rand.nextU() % GENERATE_EXTENTS;
-                    query.fTop = rand.nextU() % GENERATE_EXTENTS;
-                    query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
-                    query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
-                    break;
-                case kLarge_QueryType:
-                    query.fLeft = rand.nextU() % GENERATE_EXTENTS;
-                    query.fTop = rand.nextU() % GENERATE_EXTENTS;
-                    query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
-                    query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
-                    break;
-                case kFull_QueryType:
-                    query.fLeft = -GENERATE_EXTENTS;
-                    query.fTop = -GENERATE_EXTENTS;
-                    query.fRight = 2 * GENERATE_EXTENTS;
-                    query.fBottom = 2 * GENERATE_EXTENTS;
-                    break;
-                default: // fallthrough
-                case kRandom_QueryType:
-                    query.fLeft = rand.nextU() % GENERATE_EXTENTS;
-                    query.fTop = rand.nextU() % GENERATE_EXTENTS;
-                    query.fRight = query.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
-                    query.fBottom = query.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
-                    break;
-            };
-            fTree->search(query, &hits);
-        }
-    }
-private:
-    SkBBoxHierarchy* fTree;
-    MakeRectProc fProc;
-    SkString fName;
-    QueryType fQuery;
-    typedef Benchmark INHERITED;
-};
-
-static inline SkIRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
-    SkIRect out = {0, 0, index + 1, index + 1};
-    return out;
-}
-
-static inline SkIRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
-    SkIRect out;
-    out.fLeft = index % GRID_WIDTH;
-    out.fTop = index / GRID_WIDTH;
-    out.fRight  = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
-    out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
-    return out;
-}
-
-static inline SkIRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
-    SkIRect out;
-    out.fLeft = index / GRID_WIDTH;
-    out.fTop = index % GRID_WIDTH;
-    out.fRight  = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
-    out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
-    return out;
-}
-
-static inline SkIRect make_random_rects(SkRandom& rand, int index, int numRects) {
-    SkIRect out;
-    out.fLeft   = rand.nextS() % GENERATE_EXTENTS;
-    out.fTop    = rand.nextS() % GENERATE_EXTENTS;
-    out.fRight  = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
-    out.fBottom = out.fTop  + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
-    return out;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-DEF_BENCH(
-    return SkNEW_ARGS(QuadTreeBuildBench, ("XYordered", &make_XYordered_rects,
-                      SkNEW_ARGS(SkQuadTree, (QUAD_TREE_BOUNDS))));
-)
-DEF_BENCH(
-    return SkNEW_ARGS(QuadTreeQueryBench, ("XYordered", &make_XYordered_rects,
-                      QuadTreeQueryBench::kRandom_QueryType,
-                      SkNEW_ARGS(SkQuadTree, (QUAD_TREE_BOUNDS))));
-)
-DEF_BENCH(
-    return SkNEW_ARGS(QuadTreeBuildBench, ("YXordered", &make_YXordered_rects,
-                      SkNEW_ARGS(SkQuadTree, (QUAD_TREE_BOUNDS))));
-)
-DEF_BENCH(
-    return SkNEW_ARGS(QuadTreeQueryBench, ("YXordered", &make_YXordered_rects,
-                      QuadTreeQueryBench::kRandom_QueryType,
-                      SkNEW_ARGS(SkQuadTree, (QUAD_TREE_BOUNDS))));
-)
-DEF_BENCH(
-    return SkNEW_ARGS(QuadTreeBuildBench, ("random", &make_random_rects,
-                      SkNEW_ARGS(SkQuadTree, (QUAD_TREE_BOUNDS))));
-)
-DEF_BENCH(
-    return SkNEW_ARGS(QuadTreeQueryBench, ("random", &make_random_rects,
-                      QuadTreeQueryBench::kRandom_QueryType,
-                      SkNEW_ARGS(SkQuadTree, (QUAD_TREE_BOUNDS))));
-)
-DEF_BENCH(
-    return SkNEW_ARGS(QuadTreeBuildBench, ("concentric", &make_concentric_rects_increasing,
-                      SkNEW_ARGS(SkQuadTree, (QUAD_TREE_BOUNDS))));
-)
-DEF_BENCH(
-    return SkNEW_ARGS(QuadTreeQueryBench, ("concentric", &make_concentric_rects_increasing,
-                      QuadTreeQueryBench::kRandom_QueryType,
-                      SkNEW_ARGS(SkQuadTree, (QUAD_TREE_BOUNDS))));
-)
diff --git a/bench/RTreeBench.cpp b/bench/RTreeBench.cpp
index 95f55c9..5442f7e 100644
--- a/bench/RTreeBench.cpp
+++ b/bench/RTreeBench.cpp
@@ -13,12 +13,12 @@
 #include "SkString.h"
 
 // confine rectangles to a smallish area, so queries generally hit something, and overlap occurs:
-static const int GENERATE_EXTENTS = 1000;
+static const SkScalar GENERATE_EXTENTS = 1000.0f;
 static const int NUM_BUILD_RECTS = 500;
 static const int NUM_QUERY_RECTS = 5000;
 static const int GRID_WIDTH = 100;
 
-typedef SkIRect (*MakeRectProc)(SkRandom&, int, int);
+typedef SkRect (*MakeRectProc)(SkRandom&, int, int);
 
 // Time how long it takes to build an R-Tree either bulk-loaded or not
 class RTreeBuildBench : public Benchmark {
@@ -115,32 +115,32 @@
         SkRandom rand;
         for (int i = 0; i < loops; ++i) {
             SkTDArray<void*> hits;
-            SkIRect query;
+            SkRect query;
             switch(fQuery) {
                 case kSmall_QueryType:
-                    query.fLeft = rand.nextU() % GENERATE_EXTENTS;
-                    query.fTop = rand.nextU() % GENERATE_EXTENTS;
-                    query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
-                    query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
+                    query.fLeft   = rand.nextRangeF(0, GENERATE_EXTENTS);
+                    query.fTop    = rand.nextRangeF(0, GENERATE_EXTENTS);
+                    query.fRight  = query.fLeft + (GENERATE_EXTENTS / 20);
+                    query.fBottom = query.fTop  + (GENERATE_EXTENTS / 20);
                     break;
                 case kLarge_QueryType:
-                    query.fLeft = rand.nextU() % GENERATE_EXTENTS;
-                    query.fTop = rand.nextU() % GENERATE_EXTENTS;
-                    query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
-                    query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
+                    query.fLeft   = rand.nextRangeF(0, GENERATE_EXTENTS);
+                    query.fTop    = rand.nextRangeF(0, GENERATE_EXTENTS);
+                    query.fRight  = query.fLeft + (GENERATE_EXTENTS / 2);
+                    query.fBottom = query.fTop  + (GENERATE_EXTENTS / 2);
                     break;
                 case kFull_QueryType:
-                    query.fLeft = -GENERATE_EXTENTS;
-                    query.fTop = -GENERATE_EXTENTS;
-                    query.fRight = 2 * GENERATE_EXTENTS;
+                    query.fLeft   = -GENERATE_EXTENTS;
+                    query.fTop    = -GENERATE_EXTENTS;
+                    query.fRight  = 2 * GENERATE_EXTENTS;
                     query.fBottom = 2 * GENERATE_EXTENTS;
                     break;
                 default: // fallthrough
                 case kRandom_QueryType:
-                    query.fLeft = rand.nextU() % GENERATE_EXTENTS;
-                    query.fTop = rand.nextU() % GENERATE_EXTENTS;
-                    query.fRight = query.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
-                    query.fBottom = query.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
+                    query.fLeft   = rand.nextRangeF(0, GENERATE_EXTENTS);
+                    query.fTop    = rand.nextRangeF(0, GENERATE_EXTENTS);
+                    query.fRight  = query.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/2);
+                    query.fBottom = query.fTop  + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/2);
                     break;
             };
             fTree->search(query, &hits);
@@ -155,34 +155,34 @@
     typedef Benchmark INHERITED;
 };
 
-static inline SkIRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
-    SkIRect out = {0, 0, index + 1, index + 1};
+static inline SkRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
+    SkRect out = SkRect::MakeWH(SkIntToScalar(index+1), SkIntToScalar(index+1));
     return out;
 }
 
-static inline SkIRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
-    SkIRect out;
-    out.fLeft = index % GRID_WIDTH;
-    out.fTop = index / GRID_WIDTH;
-    out.fRight  = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
-    out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
+static inline SkRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
+    SkRect out;
+    out.fLeft   = SkIntToScalar(index % GRID_WIDTH);
+    out.fTop    = SkIntToScalar(index / GRID_WIDTH);
+    out.fRight  = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
+    out.fBottom = out.fTop  + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
     return out;
 }
-static inline SkIRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
-    SkIRect out;
-    out.fLeft = index / GRID_WIDTH;
-    out.fTop = index % GRID_WIDTH;
-    out.fRight  = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
-    out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
+static inline SkRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
+    SkRect out;
+    out.fLeft   = SkIntToScalar(index / GRID_WIDTH);
+    out.fTop    = SkIntToScalar(index % GRID_WIDTH);
+    out.fRight  = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
+    out.fBottom = out.fTop  + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
     return out;
 }
 
-static inline SkIRect make_random_rects(SkRandom& rand, int index, int numRects) {
-    SkIRect out;
-    out.fLeft   = rand.nextS() % GENERATE_EXTENTS;
-    out.fTop    = rand.nextS() % GENERATE_EXTENTS;
-    out.fRight  = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
-    out.fBottom = out.fTop  + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
+static inline SkRect make_random_rects(SkRandom& rand, int index, int numRects) {
+    SkRect out;
+    out.fLeft   = rand.nextRangeF(0, GENERATE_EXTENTS);
+    out.fTop    = rand.nextRangeF(0, GENERATE_EXTENTS);
+    out.fRight  = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/5);
+    out.fBottom = out.fTop  + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/5);
     return out;
 }
 
diff --git a/bench/RecordingBench.cpp b/bench/RecordingBench.cpp
new file mode 100644
index 0000000..ee626bc
--- /dev/null
+++ b/bench/RecordingBench.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "RecordingBench.h"
+
+#include "SkBBHFactory.h"
+#include "SkPictureRecorder.h"
+
+static const int kTileSize = 256;
+
+RecordingBench::RecordingBench(const char* name, const SkPicture* pic, bool useBBH)
+    : fSrc(SkRef(pic))
+    , fName(name)
+    , fUseBBH(useBBH) {}
+
+const char* RecordingBench::onGetName() {
+    return fName.c_str();
+}
+
+bool RecordingBench::isSuitableFor(Backend backend) {
+    return backend == kNonRendering_Backend;
+}
+
+SkIPoint RecordingBench::onGetSize() {
+    return SkIPoint::Make(SkScalarCeilToInt(fSrc->cullRect().width()),
+                          SkScalarCeilToInt(fSrc->cullRect().height()));
+}
+
+void RecordingBench::onDraw(const int loops, SkCanvas*) {
+    SkTileGridFactory::TileGridInfo info;
+    info.fTileInterval.set(kTileSize, kTileSize);
+    info.fMargin.setEmpty();
+    info.fOffset.setZero();
+    SkTileGridFactory factory(info);
+
+    const SkScalar w = fSrc->cullRect().width(),
+                   h = fSrc->cullRect().height();
+
+    for (int i = 0; i < loops; i++) {
+        SkPictureRecorder recorder;
+        fSrc->playback(recorder.beginRecording(w, h, fUseBBH ? &factory : NULL));
+        SkDELETE(recorder.endRecording());
+    }
+}
diff --git a/bench/RecordingBench.h b/bench/RecordingBench.h
new file mode 100644
index 0000000..4c03401
--- /dev/null
+++ b/bench/RecordingBench.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef RecordingBench_DEFINED
+#define RecordingBench_DEFINED
+
+#include "Benchmark.h"
+#include "SkPicture.h"
+
+class RecordingBench : public Benchmark {
+public:
+    RecordingBench(const char* name, const SkPicture*, bool useBBH);
+
+protected:
+    virtual const char* onGetName() SK_OVERRIDE;
+    virtual bool isSuitableFor(Backend) SK_OVERRIDE;
+    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE;
+    virtual SkIPoint onGetSize() SK_OVERRIDE;
+
+private:
+    SkAutoTUnref<const SkPicture> fSrc;
+    SkString fName;
+    bool fUseBBH;
+
+    typedef Benchmark INHERITED;
+};
+
+#endif//RecordingBench_DEFINED
diff --git a/bench/RectBench.cpp b/bench/RectBench.cpp
index f50324a..c0201dc 100644
--- a/bench/RectBench.cpp
+++ b/bench/RectBench.cpp
@@ -170,60 +170,6 @@
     virtual const char* onGetName() { return fName; }
 };
 
-class AARectBench : public Benchmark {
-public:
-    enum {
-        W = 640,
-        H = 480,
-    };
-
-    AARectBench(bool rotate) : fRotate(rotate) {}
-
-protected:
-
-    virtual const char* onGetName() {
-        if (fRotate) {
-            return "aarects_rotated";
-        }
-        return "aarects";
-    }
-
-    virtual void onDraw(const int loops, SkCanvas* canvas) {
-        static const SkScalar kHalfRectSize = 0.75f;
-
-        SkPaint paint;
-        this->setupPaint(&paint);
-        paint.setAntiAlias(true);
-        paint.setColor(SK_ColorBLACK);
-        SkRect r = { -kHalfRectSize, -kHalfRectSize, kHalfRectSize, kHalfRectSize };
-        int rot = 0;
-
-        for (int i = 0; i < loops; i++) {
-            // Draw small aa rects in a grid across the screen
-            for (SkScalar y = kHalfRectSize+SK_Scalar1; y < H; y += 2*kHalfRectSize+2) {
-                for (SkScalar x = kHalfRectSize+SK_Scalar1; x < W; x += 2*kHalfRectSize+2) {
-                    canvas->save();
-                    canvas->translate(x, y);
-
-                    if (fRotate) {
-                        SkMatrix rotate;
-                        rotate.setRotate(SkIntToScalar(rot));
-                        canvas->concat(rotate);
-                        rot += 10;
-                    }
-
-                    canvas->drawRect(r, paint);
-                    canvas->restore();
-                }
-            }
-        }
-
-    }
-private:
-    bool fRotate;
-    typedef Benchmark INHERITED;
-};
-
 /*******************************************************************************
  * to bench BlitMask [Opaque, Black, color, shader]
  *******************************************************************************/
@@ -322,9 +268,6 @@
 
 DEF_BENCH( return SkNEW_ARGS(SrcModeRectBench, ()); )
 
-DEF_BENCH( return SkNEW_ARGS(AARectBench, (false)); )
-DEF_BENCH( return SkNEW_ARGS(AARectBench, (true)); )
-
 /* init the blitmask bench
  */
 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
diff --git a/bench/RefCntBench.cpp b/bench/RefCntBench.cpp
index 351513b..f846b1a 100644
--- a/bench/RefCntBench.cpp
+++ b/bench/RefCntBench.cpp
@@ -14,6 +14,54 @@
     M = 2
 };
 
+class AtomicInc32 : public Benchmark {
+public:
+    AtomicInc32() : fX(0) {}
+
+    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
+        return backend == kNonRendering_Backend;
+    }
+
+protected:
+    virtual const char* onGetName() {
+        return "atomic_inc_32";
+    }
+
+    virtual void onDraw(const int loops, SkCanvas*) {
+        for (int i = 0; i < loops; ++i) {
+            sk_atomic_inc(&fX);
+        }
+    }
+
+private:
+    int32_t fX;
+    typedef Benchmark INHERITED;
+};
+
+class AtomicInc64 : public Benchmark {
+public:
+    AtomicInc64() : fX(0) {}
+
+    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
+        return backend == kNonRendering_Backend;
+    }
+
+protected:
+    virtual const char* onGetName() {
+        return "atomic_inc_64";
+    }
+
+    virtual void onDraw(const int loops, SkCanvas*) {
+        for (int i = 0; i < loops; ++i) {
+            sk_atomic_inc(&fX);
+        }
+    }
+
+private:
+    int64_t fX;
+    typedef Benchmark INHERITED;
+};
+
 class RefCntBench_Stack : public Benchmark {
 public:
     virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
@@ -191,6 +239,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+DEF_BENCH( return new AtomicInc32(); )
+DEF_BENCH( return new AtomicInc64(); )
+
 DEF_BENCH( return new RefCntBench_Stack(); )
 DEF_BENCH( return new RefCntBench_Heap(); )
 DEF_BENCH( return new RefCntBench_New(); )
diff --git a/bench/ResultsWriter.cpp b/bench/ResultsWriter.cpp
deleted file mode 100644
index 08f11c1..0000000
--- a/bench/ResultsWriter.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Helper functions for result writing operations.
- */
-
-#include "ResultsWriter.h"
-
-Json::Value* SkFindNamedNode(Json::Value* root, const char name[]) {
-    Json::Value* search_results = NULL;
-    for(Json::Value::iterator iter = root->begin();
-            iter!= root->end(); ++iter) {
-        if(SkString(name).equals((*iter)["name"].asCString())) {
-            search_results = &(*iter);
-            break;
-        }
-    }
-
-    if(search_results != NULL) {
-        return search_results;
-    } else {
-        Json::Value* new_val = &(root->append(Json::Value()));
-        (*new_val)["name"] = name;
-        return new_val;
-    }
-}
-
diff --git a/bench/ResultsWriter.h b/bench/ResultsWriter.h
index ed10afa..f17bce3 100644
--- a/bench/ResultsWriter.h
+++ b/bench/ResultsWriter.h
@@ -20,124 +20,100 @@
 /**
  * Base class for writing out the bench results.
  *
- * TODO(jcgregorio) Add info if tests fail to converge?
+ * Default implementation does nothing.
  */
 class ResultsWriter : SkNoncopyable {
 public:
-    virtual ~ResultsWriter() {};
+    virtual ~ResultsWriter() {}
 
-    // Records one option set for this run. All options must be set before
-    // calling bench().
-    virtual void option(const char name[], const char value[]) = 0;
+    // Record one key value pair that makes up a unique key for this type of run, e.g.
+    // builder name, machine type, Debug/Release, etc.
+    virtual void key(const char name[], const char value[]) {}
 
-    // Denotes the start of a specific benchmark. Once bench is called,
+    // Record one key value pair that describes the run instance, e.g. git hash, build number.
+    virtual void property(const char name[], const char value[]) {}
+
+    // Denote the start of a specific benchmark. Once bench is called,
     // then config and timer can be called multiple times to record runs.
-    virtual void bench(const char name[], int32_t x, int32_t y) = 0;
+    virtual void bench(const char name[], int32_t x, int32_t y) {}
 
-    // Records the specific configuration a bench is run under, such as "8888".
-    virtual void config(const char name[]) = 0;
+    // Record the specific configuration a bench is run under, such as "8888".
+    virtual void config(const char name[]) {}
 
-    // Records a single test metric.
-    virtual void timer(const char name[], double ms) = 0;
+    // Record the options for a configuration, such as "GL_RENDERER".
+    virtual void configOption(const char name[], const char* value) {}
 
-    // Call when all results are finished.
-    virtual void end() = 0;
+    // Record a single test metric.
+    virtual void timer(const char name[], double ms) {}
 };
 
 /**
- * This ResultsWriter handles writing out the human readable format of the
- * bench results.
- */
-class LoggerResultsWriter : public ResultsWriter {
-public:
-    explicit LoggerResultsWriter(BenchLogger& logger, const char* timeFormat)
-        : fLogger(logger)
-        , fTimeFormat(timeFormat) {
-        fLogger.logProgress("skia bench:");
-    }
-    virtual void option(const char name[], const char value[]) {
-        fLogger.logProgress(SkStringPrintf(" %s=%s", name, value));
-    }
-    virtual void bench(const char name[], int32_t x, int32_t y) {
-        fLogger.logProgress(SkStringPrintf(
-            "\nrunning bench [%3d %3d] %40s", x, y, name));
-    }
-    virtual void config(const char name[]) {
-        fLogger.logProgress(SkStringPrintf("   %s:", name));
-    }
-    virtual void timer(const char name[], double ms) {
-        fLogger.logProgress(SkStringPrintf("  %s = ", name));
-        fLogger.logProgress(SkStringPrintf(fTimeFormat, ms));
-    }
-    virtual void end() {
-        fLogger.logProgress("\n");
-    }
-private:
-    BenchLogger& fLogger;
-    const char* fTimeFormat;
-};
+ NanoJSONResultsWriter writes the test results out in the following
+ format:
 
-/**
- * This ResultsWriter handles writing out the results in JSON.
- *
- * The output looks like (except compressed to a single line):
- *
- *  {
- *   "options" : {
- *      "alpha" : "0xFF",
- *      "scale" : "0",
- *      ...
- *      "system" : "UNIX"
- *   },
- *   "results" : [
- *      {
- *      "name" : "Xfermode_Luminosity_640_480",
- *      "results" : [
- *         {
- *            "name": "565",
- *            "cmsecs" : 143.188128906250,
- *            "msecs" : 143.835957031250
- *         },
- *         ...
- */
-
-Json::Value* SkFindNamedNode(Json::Value* root, const char name[]);
-class JSONResultsWriter : public ResultsWriter {
+ {
+    "key": {
+      "arch": "Arm7",
+      "gpu": "SGX540",
+      "os": "Android",
+      "model": "GalaxyNexus",
+    }
+    "gitHash": "d1830323662ae8ae06908b97f15180fd25808894",
+    "build_number": "1234",
+    "results" : {
+        "Xfermode_Luminosity_640_480" : {
+           "8888" : {
+                 "median_ms" : 143.188128906250,
+                 "min_ms" : 143.835957031250,
+                 ...
+              },
+          ...
+*/
+class NanoJSONResultsWriter : public ResultsWriter {
 public:
-    explicit JSONResultsWriter(const char filename[])
+    explicit NanoJSONResultsWriter(const char filename[])
         : fFilename(filename)
         , fRoot()
         , fResults(fRoot["results"])
         , fBench(NULL)
-        , fConfig(NULL) {
-    }
-    virtual void option(const char name[], const char value[]) {
-        fRoot["options"][name] = value;
-    }
-    virtual void bench(const char name[], int32_t x, int32_t y) {
-        SkString sk_name(name);
-        sk_name.append("_");
-        sk_name.appendS32(x);
-        sk_name.append("_");
-        sk_name.appendS32(y);
-        Json::Value* bench_node = SkFindNamedNode(&fResults, sk_name.c_str());
-        fBench = &(*bench_node)["results"];
-    }
-    virtual void config(const char name[]) {
-        SkASSERT(NULL != fBench);
-        fConfig = SkFindNamedNode(fBench, name);
-    }
-    virtual void timer(const char name[], double ms) {
-        SkASSERT(NULL != fConfig);
-        (*fConfig)[name] = ms;
-    }
-    virtual void end() {
+        , fConfig(NULL) {}
+
+    ~NanoJSONResultsWriter() {
         SkFILEWStream stream(fFilename.c_str());
-        stream.writeText(Json::FastWriter().write(fRoot).c_str());
+        stream.writeText(Json::StyledWriter().write(fRoot).c_str());
         stream.flush();
     }
-private:
 
+    // Added under "key".
+    virtual void key(const char name[], const char value[]) {
+        fRoot["key"][name] = value;
+    }
+    // Inserted directly into the root.
+    virtual void property(const char name[], const char value[]) {
+        fRoot[name] = value;
+    }
+    virtual void bench(const char name[], int32_t x, int32_t y) {
+        SkString id = SkStringPrintf( "%s_%d_%d", name, x, y);
+        fResults[id.c_str()] = Json::Value(Json::objectValue);
+        fBench = &fResults[id.c_str()];
+    }
+    virtual void config(const char name[]) {
+        SkASSERT(fBench);
+        fConfig = &(*fBench)[name];
+    }
+    virtual void configOption(const char name[], const char* value) {
+        (*fConfig)["options"][name] = value;
+    }
+    virtual void timer(const char name[], double ms) {
+        // Don't record if nan, or -nan.
+        if (sk_double_isnan(ms)) {
+            return;
+        }
+        SkASSERT(fConfig);
+        (*fConfig)[name] = ms;
+    }
+
+private:
     SkString fFilename;
     Json::Value fRoot;
     Json::Value& fResults;
@@ -145,54 +121,5 @@
     Json::Value* fConfig;
 };
 
-/**
- * This ResultsWriter writes out to multiple ResultsWriters.
- */
-class MultiResultsWriter : public ResultsWriter {
-public:
-    MultiResultsWriter() : writers() {
-    };
-    void add(ResultsWriter* writer) {
-      writers.push_back(writer);
-    }
-    virtual void option(const char name[], const char value[]) {
-        for (int i = 0; i < writers.count(); ++i) {
-            writers[i]->option(name, value);
-        }
-    }
-    virtual void bench(const char name[], int32_t x, int32_t y) {
-        for (int i = 0; i < writers.count(); ++i) {
-            writers[i]->bench(name, x, y);
-        }
-    }
-    virtual void config(const char name[]) {
-        for (int i = 0; i < writers.count(); ++i) {
-            writers[i]->config(name);
-        }
-    }
-    virtual void timer(const char name[], double ms) {
-        for (int i = 0; i < writers.count(); ++i) {
-            writers[i]->timer(name, ms);
-        }
-    }
-    virtual void end() {
-        for (int i = 0; i < writers.count(); ++i) {
-            writers[i]->end();
-        }
-    }
-private:
-    SkTArray<ResultsWriter *> writers;
-};
-
-/**
- * Calls the end() method of T on destruction.
- */
-template <typename T> class CallEnd : SkNoncopyable {
-public:
-    CallEnd(T& obj) : fObj(obj) {}
-    ~CallEnd() { fObj.end(); }
-private:
-    T&  fObj;
-};
 
 #endif
diff --git a/bench/RotatedRectBench.cpp b/bench/RotatedRectBench.cpp
new file mode 100644
index 0000000..ea8654a
--- /dev/null
+++ b/bench/RotatedRectBench.cpp
@@ -0,0 +1,194 @@
+/*
+ * 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 "SkCanvas.h"
+#include "SkPaint.h"
+
+#include <ctype.h>
+
+/** This benchmark tests rendering rotated rectangles. It can optionally apply AA and/or change the
+    paint color between each rect in different ways using the ColorType enum. The xfermode used can
+    be specified as well. 
+  */
+
+enum ColorType {
+    kConstantOpaque_ColorType,
+    kConstantTransparent_ColorType,
+    kChangingOpaque_ColorType,
+    kChangingTransparent_ColorType,
+    kAlternatingOpaqueAndTransparent_ColorType,
+};
+
+static inline SkColor start_color(ColorType ct) {
+    switch (ct) {
+        case kConstantOpaque_ColorType:
+        case kChangingOpaque_ColorType:
+        case kAlternatingOpaqueAndTransparent_ColorType:
+            return 0xFFA07040;
+        case kConstantTransparent_ColorType:
+        case kChangingTransparent_ColorType:
+            return 0x80A07040;
+    }
+    SkFAIL("Shouldn't reach here.");
+    return 0;
+}
+
+static inline SkColor advance_color(SkColor old, ColorType ct, int step) {
+    if (kAlternatingOpaqueAndTransparent_ColorType == ct) {
+        ct = (step & 0x1) ? kChangingOpaque_ColorType : kChangingTransparent_ColorType ;
+    }
+    switch (ct) {
+        case kConstantOpaque_ColorType:
+        case kConstantTransparent_ColorType:
+            return old;
+        case kChangingOpaque_ColorType:
+            return 0xFF000000 | (old + 0x00010307);
+        case kChangingTransparent_ColorType:
+            return (0x00FFFFFF & (old + 0x00010307)) | 0x80000000;
+        case kAlternatingOpaqueAndTransparent_ColorType:
+            SkFAIL("Can't get here");
+    }
+    SkFAIL("Shouldn't reach here.");
+    return 0;
+}
+
+static SkString to_lower(const char* str) {
+    SkString lower(str);
+    for (size_t i = 0; i < lower.size(); i++) {
+        lower[i] = tolower(lower[i]);
+    }
+    return lower;
+}
+
+class RotRectBench: public Benchmark {
+public:
+    RotRectBench(bool aa, ColorType ct, SkXfermode::Mode mode)
+        : fAA(aa)
+        , fColorType(ct)
+        , fMode(mode) {
+        this->makeName();
+    }
+
+protected:
+    virtual const char* onGetName() SK_OVERRIDE { return fName.c_str(); }
+
+    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
+        SkPaint paint;
+        paint.setAntiAlias(fAA);
+        paint.setXfermodeMode(fMode);
+        SkColor color = start_color(fColorType);
+
+        int w = canvas->getBaseLayerSize().width();
+        int h = canvas->getBaseLayerSize().height();
+
+        static const SkScalar kRectW = 25.1f;
+        static const SkScalar kRectH = 25.9f;
+
+        SkMatrix rotate;
+        // This value was chosen so that we frequently hit the axis-aligned case.
+        rotate.setRotate(30.f, kRectW / 2, kRectH / 2);
+        SkMatrix m = rotate;
+
+        SkScalar tx = 0, ty = 0;
+
+        for (int i = 0; i < loops; ++i) {
+            canvas->save();
+            canvas->translate(tx, ty);
+            canvas->concat(m);
+            paint.setColor(color);
+            color = advance_color(color, fColorType, i);
+
+            canvas->drawRect(SkRect::MakeWH(kRectW, kRectH), paint);
+            canvas->restore();
+
+            tx += kRectW + 2;
+            if (tx > w) {
+                tx = 0;
+                ty += kRectH + 2;
+                if (ty > h) {
+                    ty = 0;
+                }
+            }
+
+            m.postConcat(rotate);
+        }
+    }
+
+private:
+    void makeName() {
+        fName = "rotated_rects";
+        if (fAA) {
+            fName.append("_aa");
+        } else {
+            fName.append("_bw");
+        }
+        switch (fColorType) {
+            case kConstantOpaque_ColorType:
+                fName.append("_same_opaque");
+                break;
+            case kConstantTransparent_ColorType:
+                fName.append("_same_transparent");
+                break;
+            case kChangingOpaque_ColorType:
+                fName.append("_changing_opaque");
+                break;
+            case kChangingTransparent_ColorType:
+                fName.append("_changing_transparent");
+                break;
+            case kAlternatingOpaqueAndTransparent_ColorType:
+                fName.append("_alternating_transparent_and_opaque");
+                break;
+        }
+        fName.appendf("_%s", to_lower(SkXfermode::ModeName(fMode)).c_str());
+    }
+
+    bool             fAA;
+    ColorType        fColorType;
+    SkXfermode::Mode fMode;
+    SkString         fName;
+
+    typedef Benchmark INHERITED;
+};
+
+// Choose kSrcOver because it always allows coverage and alpha to be conflated. kSrc only allows
+// conflation when opaque, and kDarken because it isn't possilbe with standard GL blending.
+DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
+
+DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
+
+DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);)
+
+DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);)
+
+DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);)
+
+DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);)
diff --git a/bench/SKPBench.cpp b/bench/SKPBench.cpp
new file mode 100644
index 0000000..9d822d9
--- /dev/null
+++ b/bench/SKPBench.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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 "SKPBench.h"
+
+SKPBench::SKPBench(const char* name, const SkPicture* pic, const SkIRect& clip, SkScalar scale)
+    : fPic(SkRef(pic))
+    , fClip(clip)
+    , fScale(scale)
+    , fName(name) {
+    fUniqueName.printf("%s_%.2g", name, scale);  // Scale makes this unqiue for skiaperf.com traces.
+}
+
+const char* SKPBench::onGetName() {
+    return fName.c_str();
+}
+
+const char* SKPBench::onGetUniqueName() {
+    return fUniqueName.c_str();
+}
+
+bool SKPBench::isSuitableFor(Backend backend) {
+    return backend != kNonRendering_Backend;
+}
+
+SkIPoint SKPBench::onGetSize() {
+    return SkIPoint::Make(fClip.width(), fClip.height());
+}
+
+void SKPBench::onDraw(const int loops, SkCanvas* canvas) {
+    canvas->save();
+        canvas->scale(fScale, fScale);
+        for (int i = 0; i < loops; i++) {
+            fPic->playback(canvas);
+            canvas->flush();
+        }
+    canvas->restore();
+}
diff --git a/bench/SKPBench.h b/bench/SKPBench.h
new file mode 100644
index 0000000..0b0e008
--- /dev/null
+++ b/bench/SKPBench.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SKPBench_DEFINED
+#define SKPBench_DEFINED
+
+#include "Benchmark.h"
+#include "SkCanvas.h"
+#include "SkPicture.h"
+
+/**
+ * Runs an SkPicture as a benchmark by repeatedly drawing it scaled inside a device clip.
+ */
+class SKPBench : public Benchmark {
+public:
+    SKPBench(const char* name, const SkPicture*, const SkIRect& devClip, SkScalar scale);
+
+protected:
+    virtual const char* onGetName() SK_OVERRIDE;
+    virtual const char* onGetUniqueName() SK_OVERRIDE;
+    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE;
+    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE;
+    virtual SkIPoint onGetSize() SK_OVERRIDE;
+
+private:
+    SkAutoTUnref<const SkPicture> fPic;
+    const SkIRect fClip;
+    const SkScalar fScale;
+    SkString fName;
+    SkString fUniqueName;
+
+    typedef Benchmark INHERITED;
+};
+
+#endif
diff --git a/bench/SkipZeroesBench.cpp b/bench/SkipZeroesBench.cpp
index 30d9377..fc25f8b 100644
--- a/bench/SkipZeroesBench.cpp
+++ b/bench/SkipZeroesBench.cpp
@@ -52,8 +52,7 @@
             return;
         }
 
-        SkString fullPath = SkOSPath::SkPathJoin(resourcePath.c_str(),
-                                                 fFilename.c_str());
+        SkString fullPath = SkOSPath::Join(resourcePath.c_str(), fFilename.c_str());
         SkFILEStream fileStream(fullPath.c_str());
         fValid = fileStream.isValid() && fileStream.getLength() > 0;
         if (fValid) {
diff --git a/bench/StackBench.cpp b/bench/StackBench.cpp
deleted file mode 100644
index 3b41cb6..0000000
--- a/bench/StackBench.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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 "SkRandom.h"
-
-#include "SkChunkAlloc.h"
-#include "SkDeque.h"
-#include "SkTArray.h"
-#include "SkTDArray.h"
-
-// This file has several benchmarks using various data structures to do stack-like things:
-//   - push
-//   - push, immediately pop
-//   - push many, pop all of them
-//   - serial access
-//   - random access
-// When a data structure doesn't suppport an operation efficiently, we leave that combination out.
-// Where possible we hint to the data structure to allocate in 4K pages.
-//
-// These benchmarks may help you decide which data structure to use for a dynamically allocated
-// ordered list of allocations that grows on one end.
-//
-// Current overall winner (01/2014): SkTDArray.
-// It wins every benchmark on every machine I tried (Desktop, Nexus S, Laptop).
-
-template <typename Impl>
-struct StackBench : public Benchmark {
-    virtual bool isSuitableFor(Backend b) SK_OVERRIDE { return b == kNonRendering_Backend; }
-    virtual const char* onGetName() SK_OVERRIDE { return Impl::kName; }
-    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { Impl::bench(loops); }
-};
-
-#define BENCH(name)                                                          \
-    struct name { static const char* const kName; static void bench(int); }; \
-    const char* const name::kName = #name;                                   \
-    DEF_BENCH(return new StackBench<name>();)                                \
-    void name::bench(int loops)
-
-static const int K = 2049;
-
-// Add K items, then iterate through them serially many times.
-
-BENCH(Deque_Serial) {
-    SkDeque s(sizeof(int), 1024);
-    for (int i = 0; i < K; i++) *(int*)s.push_back() = i;
-
-    volatile int junk = 0;
-    for (int j = 0; j < loops; j++) {
-        SkDeque::Iter it(s, SkDeque::Iter::kFront_IterStart);
-        while(void* p = it.next()) {
-            junk += *(int*)p;
-        }
-    }
-}
-
-BENCH(TArray_Serial) {
-    SkTArray<int, true> s;
-    for (int i = 0; i < K; i++) s.push_back(i);
-
-    volatile int junk = 0;
-    for (int j = 0; j < loops; j++) {
-        for (int i = 0; i < s.count(); i++) junk += s[i];
-    }
-}
-
-BENCH(TDArray_Serial) {
-    SkTDArray<int> s;
-    for (int i = 0; i < K; i++) s.push(i);
-
-    volatile int junk = 0;
-    for (int j = 0; j < loops; j++) {
-        for (int i = 0; i < s.count(); i++) junk += s[i];
-    }
-}
-
-// Add K items, then randomly access them many times.
-
-BENCH(TArray_RandomAccess) {
-    SkTArray<int, true> s;
-    for (int i = 0; i < K; i++) s.push_back(i);
-
-    SkRandom rand;
-    volatile int junk = 0;
-    for (int i = 0; i < K*loops; i++) {
-        junk += s[rand.nextULessThan(K)];
-    }
-}
-
-BENCH(TDArray_RandomAccess) {
-    SkTDArray<int> s;
-    for (int i = 0; i < K; i++) s.push(i);
-
-    SkRandom rand;
-    volatile int junk = 0;
-    for (int i = 0; i < K*loops; i++) {
-        junk += s[rand.nextULessThan(K)];
-    }
-}
-
-// Push many times.
-
-BENCH(ChunkAlloc_Push) {
-    SkChunkAlloc s(4096);
-    for (int i = 0; i < K*loops; i++) s.allocThrow(sizeof(int));
-}
-
-BENCH(Deque_Push) {
-    SkDeque s(sizeof(int), 1024);
-    for (int i = 0; i < K*loops; i++) *(int*)s.push_back() = i;
-}
-
-BENCH(TArray_Push) {
-    SkTArray<int, true> s;
-    for (int i = 0; i < K*loops; i++) s.push_back(i);
-}
-
-BENCH(TDArray_Push) {
-    SkTDArray<int> s;
-    for (int i = 0; i < K*loops; i++) s.push(i);
-}
-
-// Push then immediately pop many times.
-
-BENCH(ChunkAlloc_PushPop) {
-    SkChunkAlloc s(4096);
-    for (int i = 0; i < K*loops; i++) {
-        void* p = s.allocThrow(sizeof(int));
-        s.unalloc(p);
-    }
-}
-
-BENCH(Deque_PushPop) {
-    SkDeque s(sizeof(int), 1024);
-    for (int i = 0; i < K*loops; i++) {
-        *(int*)s.push_back() = i;
-        s.pop_back();
-    }
-}
-
-BENCH(TArray_PushPop) {
-    SkTArray<int, true> s;
-    for (int i = 0; i < K*loops; i++) {
-        s.push_back(i);
-        s.pop_back();
-    }
-}
-
-BENCH(TDArray_PushPop) {
-    SkTDArray<int> s;
-    for (int i = 0; i < K*loops; i++) {
-        s.push(i);
-        s.pop();
-    }
-}
-
-// Push many items, then pop them all.
-
-BENCH(Deque_PushAllPopAll) {
-    SkDeque s(sizeof(int), 1024);
-    for (int i = 0; i < K*loops; i++) *(int*)s.push_back() = i;
-    for (int i = 0; i < K*loops; i++) s.pop_back();
-}
-
-BENCH(TArray_PushAllPopAll) {
-    SkTArray<int, true> s;
-    for (int i = 0; i < K*loops; i++) s.push_back(i);
-    for (int i = 0; i < K*loops; i++) s.pop_back();
-}
-
-BENCH(TDArray_PushAllPopAll) {
-    SkTDArray<int> s;
-    for (int i = 0; i < K*loops; i++) s.push(i);
-    for (int i = 0; i < K*loops; i++) s.pop();
-}
diff --git a/bench/TileBench.cpp b/bench/TileBench.cpp
index 7487b1b..9acef8c 100644
--- a/bench/TileBench.cpp
+++ b/bench/TileBench.cpp
@@ -114,18 +114,21 @@
     typedef Benchmark INHERITED;
 };
 
-DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, false, false, true))
+// Scaled benches are trending towards free.  Seems like caching.
+// TODO(mtklein, reed): fix and reenable
+
+//DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, false, false, true))
 DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, false, false, false))
-DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, false, false, true))
+//DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, false, false, true))
 
 DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, true, false, false))
-DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, true, false, true))
+//DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, true, false, true))
 DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, true, false, false))
 
-DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, false, true, true))
+//DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, false, true, true))
 DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, false, true, false))
-DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, false, true, true))
+//DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, false, true, true))
 
 DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, true, true, false))
-DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, true, true, true))
+//DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, true, true, true))
 DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, true, true, false))
diff --git a/bench/WritePixelsBench.cpp b/bench/WritePixelsBench.cpp
index 5138375..88b2e62 100644
--- a/bench/WritePixelsBench.cpp
+++ b/bench/WritePixelsBench.cpp
@@ -54,9 +54,7 @@
         bmp.allocN32Pixels(size.width(), size.height());
         canvas->readPixels(&bmp, 0, 0);
 
-        SkImageInfo info = bmp.info();
-        info.fColorType = fColorType;
-        info.fAlphaType = fAlphaType;
+        SkImageInfo info = SkImageInfo::Make(bmp.width(), bmp.height(), fColorType, fAlphaType);
 
         for (int loop = 0; loop < loops; ++loop) {
             canvas->writePixels(info, bmp.getPixels(), bmp.rowBytes(), 0, 0);
diff --git a/bench/XfermodeBench.cpp b/bench/XfermodeBench.cpp
index f73943b..54272da 100644
--- a/bench/XfermodeBench.cpp
+++ b/bench/XfermodeBench.cpp
@@ -18,12 +18,12 @@
 public:
     XfermodeBench(SkXfermode::Mode mode) {
         fXfermode.reset(SkXfermode::Create(mode));
-        SkASSERT(NULL != fXfermode.get() || SkXfermode::kSrcOver_Mode == mode);
+        SkASSERT(fXfermode.get() || SkXfermode::kSrcOver_Mode == mode);
         fName.printf("Xfermode_%s", SkXfermode::ModeName(mode));
     }
 
     XfermodeBench(SkXfermode* xferMode, const char* name) {
-        SkASSERT(NULL != xferMode);
+        SkASSERT(xferMode);
         fXfermode.reset(xferMode);
         fName.printf("Xfermode_%s", name);
     }
diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp
deleted file mode 100644
index 6b3f587..0000000
--- a/bench/benchmain.cpp
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "BenchLogger.h"
-#include "BenchTimer.h"
-#include "Benchmark.h"
-#include "CrashHandler.h"
-#include "GMBench.h"
-#include "ResultsWriter.h"
-#include "SkBitmapDevice.h"
-#include "SkCanvas.h"
-#include "SkColorPriv.h"
-#include "SkCommandLineFlags.h"
-#include "SkData.h"
-#include "SkDeferredCanvas.h"
-#include "SkGraphics.h"
-#include "SkImageEncoder.h"
-#include "SkOSFile.h"
-#include "SkPicture.h"
-#include "SkPictureRecorder.h"
-#include "SkString.h"
-#include "SkSurface.h"
-
-#if SK_SUPPORT_GPU
-#include "GrContext.h"
-#include "GrContextFactory.h"
-#include "GrRenderTarget.h"
-#include "SkGpuDevice.h"
-#include "gl/GrGLDefines.h"
-#else
-class GrContext;
-#endif // SK_SUPPORT_GPU
-
-#include <limits>
-
-enum BenchMode {
-    kNormal_BenchMode,
-    kDeferred_BenchMode,
-    kDeferredSilent_BenchMode,
-    kRecord_BenchMode,
-    kPictureRecord_BenchMode
-};
-const char* BenchMode_Name[] = {
-    "normal", "deferred", "deferredSilent", "record", "picturerecord"
-};
-
-static const char kDefaultsConfigStr[] = "defaults";
-
-///////////////////////////////////////////////////////////////////////////////
-
-class Iter {
-public:
-    Iter() : fBenches(BenchRegistry::Head()), fGMs(skiagm::GMRegistry::Head()) {}
-
-    Benchmark* next() {
-        if (fBenches) {
-            BenchRegistry::Factory f = fBenches->factory();
-            fBenches = fBenches->next();
-            return (*f)(NULL);
-        }
-
-        while (fGMs) {
-            SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL));
-            fGMs = fGMs->next();
-            if (gm->getFlags() & skiagm::GM::kAsBench_Flag) {
-                return SkNEW_ARGS(GMBench, (gm.detach()));
-            }
-        }
-
-        return NULL;
-    }
-
-private:
-    const BenchRegistry* fBenches;
-    const skiagm::GMRegistry* fGMs;
-};
-
-static void make_filename(const char name[], SkString* path) {
-    path->set(name);
-    for (int i = 0; name[i]; i++) {
-        switch (name[i]) {
-            case '/':
-            case '\\':
-            case ' ':
-            case ':':
-                path->writable_str()[i] = '-';
-                break;
-            default:
-                break;
-        }
-    }
-}
-
-static void saveFile(const char name[], const char config[], const char dir[],
-                     const SkImage* image) {
-    SkAutoTUnref<SkData> data(image->encode(SkImageEncoder::kPNG_Type, 100));
-    if (NULL == data.get()) {
-        return;
-    }
-
-    SkString filename;
-    make_filename(name, &filename);
-    filename.appendf("_%s.png", config);
-    SkString path = SkOSPath::SkPathJoin(dir, filename.c_str());
-    ::remove(path.c_str());
-
-    SkFILEWStream   stream(path.c_str());
-    stream.write(data->data(), data->size());
-}
-
-static void perform_clip(SkCanvas* canvas, int w, int h) {
-    SkRect r;
-
-    r.set(SkIntToScalar(10), SkIntToScalar(10),
-          SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
-    canvas->clipRect(r, SkRegion::kIntersect_Op);
-
-    r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
-          SkIntToScalar(w-10), SkIntToScalar(h-10));
-    canvas->clipRect(r, SkRegion::kXOR_Op);
-}
-
-static void perform_rotate(SkCanvas* canvas, int w, int h) {
-    const SkScalar x = SkIntToScalar(w) / 2;
-    const SkScalar y = SkIntToScalar(h) / 2;
-
-    canvas->translate(x, y);
-    canvas->rotate(SkIntToScalar(35));
-    canvas->translate(-x, -y);
-}
-
-static void perform_scale(SkCanvas* canvas, int w, int h) {
-    const SkScalar x = SkIntToScalar(w) / 2;
-    const SkScalar y = SkIntToScalar(h) / 2;
-
-    canvas->translate(x, y);
-    // just enough so we can't take the sprite case
-    canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
-    canvas->translate(-x, -y);
-}
-
-static SkSurface* make_surface(SkColorType colorType, const SkIPoint& size,
-                               Benchmark::Backend backend, int sampleCount,
-                               GrContext* context) {
-    SkSurface* surface = NULL;
-    SkImageInfo info = SkImageInfo::Make(size.fX, size.fY, colorType,
-                                         kPremul_SkAlphaType);
-
-    switch (backend) {
-        case Benchmark::kRaster_Backend:
-            surface = SkSurface::NewRaster(info);
-            surface->getCanvas()->clear(SK_ColorWHITE);
-            break;
-#if SK_SUPPORT_GPU
-        case Benchmark::kGPU_Backend: {
-            surface = SkSurface::NewRenderTarget(context, info, sampleCount);
-            break;
-        }
-#endif
-        case Benchmark::kPDF_Backend:
-        default:
-            SkDEBUGFAIL("unsupported");
-    }
-    return surface;
-}
-
-#if SK_SUPPORT_GPU
-GrContextFactory gContextFactory;
-typedef GrContextFactory::GLContextType GLContextType;
-static const GLContextType kNative = GrContextFactory::kNative_GLContextType;
-static const GLContextType kNVPR   = GrContextFactory::kNVPR_GLContextType;
-#if SK_ANGLE
-static const GLContextType kANGLE  = GrContextFactory::kANGLE_GLContextType;
-#endif
-static const GLContextType kDebug  = GrContextFactory::kDebug_GLContextType;
-static const GLContextType kNull   = GrContextFactory::kNull_GLContextType;
-#else
-typedef int GLContextType;
-static const GLContextType kNative = 0, kANGLE = 0, kDebug = 0, kNull = 0;
-#endif
-
-#ifdef SK_DEBUG
-static const bool kIsDebug = true;
-#else
-static const bool kIsDebug = false;
-#endif
-
-static const struct Config {
-    SkColorType         fColorType;
-    const char*         name;
-    int                 sampleCount;
-    Benchmark::Backend  backend;
-    GLContextType       contextType;
-    bool                runByDefault;
-} gConfigs[] = {
-    { kN32_SkColorType,     "NONRENDERING", 0, Benchmark::kNonRendering_Backend, kNative, true},
-    { kN32_SkColorType,     "8888",         0, Benchmark::kRaster_Backend,       kNative, true},
-    { kRGB_565_SkColorType, "565",          0, Benchmark::kRaster_Backend,       kNative, true},
-#if SK_SUPPORT_GPU
-    { kN32_SkColorType,     "GPU",          0, Benchmark::kGPU_Backend,          kNative, true},
-    { kN32_SkColorType,     "MSAA4",        4, Benchmark::kGPU_Backend,          kNative, false},
-    { kN32_SkColorType,     "MSAA16",      16, Benchmark::kGPU_Backend,          kNative, false},
-    { kN32_SkColorType,     "NVPRMSAA4",    4, Benchmark::kGPU_Backend,          kNVPR,   true},
-    { kN32_SkColorType,     "NVPRMSAA16",  16, Benchmark::kGPU_Backend,          kNVPR,   false},
-#if SK_ANGLE
-    { kN32_SkColorType,     "ANGLE",        0, Benchmark::kGPU_Backend,          kANGLE,  true},
-#endif // SK_ANGLE
-    { kN32_SkColorType,     "Debug",        0, Benchmark::kGPU_Backend,          kDebug,  kIsDebug},
-    { kN32_SkColorType,     "NULLGPU",      0, Benchmark::kGPU_Backend,          kNull,   true},
-#endif // SK_SUPPORT_GPU
-};
-
-DEFINE_string(outDir, "", "If given, image of each bench will be put in outDir.");
-DEFINE_string(timers, "cg", "Timers to display. "
-              "Options: w(all) W(all, truncated) c(pu) C(pu, truncated) g(pu)");
-
-DEFINE_bool(rotate, false,  "Rotate canvas before bench run?");
-DEFINE_bool(scale,  false,  "Scale canvas before bench run?");
-DEFINE_bool(clip,   false,  "Clip canvas before bench run?");
-
-DEFINE_bool(forceAA,        true,     "Force anti-aliasing?");
-DEFINE_bool(forceFilter,    false,    "Force bitmap filtering?");
-DEFINE_string(forceDither, "default", "Force dithering: true, false, or default?");
-DEFINE_bool(forceBlend,     false,    "Force alpha blending?");
-
-DEFINE_int32(gpuCacheBytes, -1, "GPU cache size limit in bytes.  0 to disable cache.");
-DEFINE_int32(gpuCacheCount, -1, "GPU cache size limit in object count.  0 to disable cache.");
-
-DEFINE_bool2(leaks, l, false, "show leaked ref cnt'd objects.");
-DEFINE_string(match, "",  "[~][^]substring[$] [...] of test name to run.\n"
-                          "Multiple matches may be separated by spaces.\n"
-                          "~ causes a matching test to always be skipped\n"
-                          "^ requires the start of the test to match\n"
-                          "$ requires the end of the test to match\n"
-                          "^ and $ requires an exact match\n"
-                          "If a test does not match any list entry,\n"
-                          "it is skipped unless some list entry starts with ~\n");
-DEFINE_string(mode, "normal",
-             "normal:         draw to a normal canvas;\n"
-             "deferred:       draw to a deferred canvas;\n"
-             "deferredSilent: deferred with silent playback;\n"
-             "record:         draw to an SkPicture;\n"
-             "picturerecord:  draw from an SkPicture to an SkPicture.\n");
-DEFINE_string(config, kDefaultsConfigStr,
-              "Run configs given.  By default, runs the configs marked \"runByDefault\" in gConfigs.");
-DEFINE_string(logFile, "", "Also write stdout here.");
-DEFINE_int32(minMs, 20,  "Shortest time we'll allow a benchmark to run.");
-DEFINE_int32(maxMs, 4000, "Longest time we'll allow a benchmark to run.");
-DEFINE_bool(runOnce, kIsDebug, "Run each bench exactly once and don't report timings.");
-DEFINE_double(error, 0.01,
-              "Ratio of subsequent bench measurements must drop within 1±error to converge.");
-DEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per 1000 loops.");
-DEFINE_bool2(verbose, v, false, "Print more.");
-DEFINE_string(outResultsFile, "", "If given, the results will be written to the file in JSON format.");
-DEFINE_bool(dryRun, false, "Don't actually run the tests, just print what would have been done.");
-
-// Has this bench converged?  First arguments are milliseconds / loop iteration,
-// last is overall runtime in milliseconds.
-static bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw) {
-    if (currRaw < FLAGS_minMs) {
-        return false;
-    }
-    const double low = 1 - FLAGS_error, high = 1 + FLAGS_error;
-    const double ratio = currPerLoop / prevPerLoop;
-    return low < ratio && ratio < high;
-}
-
-int tool_main(int argc, char** argv);
-int tool_main(int argc, char** argv) {
-    SetupCrashHandler();
-    SkCommandLineFlags::Parse(argc, argv);
-#if SK_ENABLE_INST_COUNT
-    if (FLAGS_leaks) {
-        gPrintInstCount = true;
-    }
-#endif
-    SkAutoGraphics ag;
-
-    // First, parse some flags.
-    BenchLogger logger;
-    if (FLAGS_logFile.count()) {
-        logger.SetLogFile(FLAGS_logFile[0]);
-    }
-
-    LoggerResultsWriter logWriter(logger, FLAGS_timeFormat[0]);
-    MultiResultsWriter writer;
-    writer.add(&logWriter);
-
-    SkAutoTDelete<JSONResultsWriter> jsonWriter;
-    if (FLAGS_outResultsFile.count()) {
-        jsonWriter.reset(SkNEW(JSONResultsWriter(FLAGS_outResultsFile[0])));
-        writer.add(jsonWriter.get());
-    }
-
-    // Instantiate after all the writers have been added to writer so that we
-    // call close() before their destructors are called on the way out.
-    CallEnd<MultiResultsWriter> ender(writer);
-
-    const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF;
-    SkTriState::State dither = SkTriState::kDefault;
-    for (size_t i = 0; i < 3; i++) {
-        if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) {
-            dither = static_cast<SkTriState::State>(i);
-        }
-    }
-
-    BenchMode benchMode = kNormal_BenchMode;
-    for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) {
-        if (strcmp(FLAGS_mode[0], BenchMode_Name[i]) == 0) {
-            benchMode = static_cast<BenchMode>(i);
-        }
-    }
-
-    SkTDArray<int> configs;
-    bool runDefaultConfigs = false;
-    // Try user-given configs first.
-    for (int i = 0; i < FLAGS_config.count(); i++) {
-        for (int j = 0; j < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++j) {
-            if (0 == strcmp(FLAGS_config[i], gConfigs[j].name)) {
-                *configs.append() = j;
-            } else if (0 == strcmp(FLAGS_config[i], kDefaultsConfigStr)) {
-                runDefaultConfigs = true;
-            }
-        }
-    }
-    // If there weren't any, fill in with defaults.
-    if (runDefaultConfigs) {
-        for (int i = 0; i < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++i) {
-            if (gConfigs[i].runByDefault) {
-                *configs.append() = i;
-            }
-        }
-    }
-    // Filter out things we can't run.
-    if (kNormal_BenchMode != benchMode) {
-        // Non-rendering configs only run in normal mode
-        for (int i = 0; i < configs.count(); ++i) {
-            const Config& config = gConfigs[configs[i]];
-            if (Benchmark::kNonRendering_Backend == config.backend) {
-                configs.remove(i, 1);
-                --i;
-            }
-        }
-    }
-
-#if SK_SUPPORT_GPU
-    for (int i = 0; i < configs.count(); ++i) {
-        const Config& config = gConfigs[configs[i]];
-
-        if (Benchmark::kGPU_Backend == config.backend) {
-            GrContext* context = gContextFactory.get(config.contextType);
-            if (NULL == context) {
-                SkDebugf("GrContext could not be created for config %s. Config will be skipped.\n",
-                    config.name);
-                configs.remove(i);
-                --i;
-                continue;
-            }
-            if (config.sampleCount > context->getMaxSampleCount()){
-                SkDebugf(
-                    "Sample count (%d) for config %s is not supported. Config will be skipped.\n",
-                    config.sampleCount, config.name);
-                configs.remove(i);
-                --i;
-                continue;
-            }
-        }
-    }
-#endif
-
-    // All flags should be parsed now.  Report our settings.
-    if (FLAGS_runOnce) {
-        logger.logError("bench was run with --runOnce, so we're going to hide the times."
-                        " It's for your own good!\n");
-    }
-    writer.option("mode", FLAGS_mode[0]);
-    writer.option("alpha", SkStringPrintf("0x%02X", alpha).c_str());
-    writer.option("antialias", SkStringPrintf("%d", FLAGS_forceAA).c_str());
-    writer.option("filter", SkStringPrintf("%d", FLAGS_forceFilter).c_str());
-    writer.option("dither",  SkTriState::Name[dither]);
-
-    writer.option("rotate", SkStringPrintf("%d", FLAGS_rotate).c_str());
-    writer.option("scale", SkStringPrintf("%d", FLAGS_scale).c_str());
-    writer.option("clip", SkStringPrintf("%d", FLAGS_clip).c_str());
-
-#if defined(SK_BUILD_FOR_WIN32)
-    writer.option("system", "WIN32");
-#elif defined(SK_BUILD_FOR_MAC)
-    writer.option("system", "MAC");
-#elif defined(SK_BUILD_FOR_ANDROID)
-    writer.option("system", "ANDROID");
-#elif defined(SK_BUILD_FOR_UNIX)
-    writer.option("system", "UNIX");
-#else
-    writer.option("system", "other");
-#endif
-
-#if defined(SK_DEBUG)
-    writer.option("build", "DEBUG");
-#else
-    writer.option("build", "RELEASE");
-#endif
-
-    // Set texture cache limits if non-default.
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
-#if SK_SUPPORT_GPU
-        const Config& config = gConfigs[i];
-        if (Benchmark::kGPU_Backend != config.backend) {
-            continue;
-        }
-        GrContext* context = gContextFactory.get(config.contextType);
-        if (NULL == context) {
-            continue;
-        }
-
-        size_t bytes;
-        int count;
-        context->getResourceCacheLimits(&count, &bytes);
-        if (-1 != FLAGS_gpuCacheBytes) {
-            bytes = static_cast<size_t>(FLAGS_gpuCacheBytes);
-        }
-        if (-1 != FLAGS_gpuCacheCount) {
-            count = FLAGS_gpuCacheCount;
-        }
-        context->setResourceCacheLimits(count, bytes);
-#endif
-    }
-
-    // Run each bench in each configuration it supports and we asked for.
-    Iter iter;
-    Benchmark* bench;
-    while ((bench = iter.next()) != NULL) {
-        SkAutoTUnref<Benchmark> benchUnref(bench);
-        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
-            continue;
-        }
-
-        bench->setForceAlpha(alpha);
-        bench->setForceAA(FLAGS_forceAA);
-        bench->setForceFilter(FLAGS_forceFilter);
-        bench->setDither(dither);
-        bench->preDraw();
-
-        bool loggedBenchName = false;
-        for (int i = 0; i < configs.count(); ++i) {
-            const int configIndex = configs[i];
-            const Config& config = gConfigs[configIndex];
-
-            if (!bench->isSuitableFor(config.backend)) {
-                continue;
-            }
-
-            GrContext* context = NULL;
-#if SK_SUPPORT_GPU
-            SkGLContextHelper* glContext = NULL;
-            if (Benchmark::kGPU_Backend == config.backend) {
-                context = gContextFactory.get(config.contextType);
-                if (NULL == context) {
-                    continue;
-                }
-                glContext = gContextFactory.getGLContext(config.contextType);
-            }
-#endif
-
-            SkAutoTUnref<SkCanvas> canvas;
-            SkAutoTUnref<SkPicture> recordFrom;
-            SkPictureRecorder recorderTo;
-            const SkIPoint dim = bench->getSize();
-
-            SkAutoTUnref<SkSurface> surface;
-            if (Benchmark::kNonRendering_Backend != config.backend) {
-                surface.reset(make_surface(config.fColorType,
-                                           dim,
-                                           config.backend,
-                                           config.sampleCount,
-                                           context));
-                if (!surface.get()) {
-                    logger.logError(SkStringPrintf(
-                        "Device creation failure for config %s. Will skip.\n", config.name));
-                    continue;
-                }
-
-                switch(benchMode) {
-                    case kDeferredSilent_BenchMode:
-                    case kDeferred_BenchMode:
-                        canvas.reset(SkDeferredCanvas::Create(surface.get()));
-                        break;
-                    case kRecord_BenchMode:
-                        canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
-                        break;
-                    case kPictureRecord_BenchMode: {
-                        SkPictureRecorder recorderFrom;
-                        bench->draw(1, recorderFrom.beginRecording(dim.fX, dim.fY));
-                        recordFrom.reset(recorderFrom.endRecording());
-                        canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
-                        break;
-                    }
-                    case kNormal_BenchMode:
-                        canvas.reset(SkRef(surface->getCanvas()));
-                        break;
-                    default:
-                        SkASSERT(false);
-                }
-            }
-
-            if (NULL != canvas) {
-                canvas->clear(SK_ColorWHITE);
-                if (FLAGS_clip)   {
-                    perform_clip(canvas, dim.fX, dim.fY);
-                }
-                if (FLAGS_scale)  {
-                    perform_scale(canvas, dim.fX, dim.fY);
-                }
-                if (FLAGS_rotate) {
-                    perform_rotate(canvas, dim.fX, dim.fY);
-                }
-            }
-
-            if (!loggedBenchName) {
-                loggedBenchName = true;
-                writer.bench(bench->getName(), dim.fX, dim.fY);
-            }
-
-#if SK_SUPPORT_GPU
-            SkGLContextHelper* contextHelper = NULL;
-            if (Benchmark::kGPU_Backend == config.backend) {
-                contextHelper = gContextFactory.getGLContext(config.contextType);
-            }
-            BenchTimer timer(contextHelper);
-#else
-            BenchTimer timer;
-#endif
-
-            double previous = std::numeric_limits<double>::infinity();
-            bool converged = false;
-
-            // variables used to compute loopsPerFrame
-            double frameIntervalTime = 0.0f;
-            int frameIntervalTotalLoops = 0;
-
-            bool frameIntervalComputed = false;
-            int loopsPerFrame = 0;
-            int loopsPerIter = 0;
-            if (FLAGS_verbose) { SkDebugf("%s %s: ", bench->getName(), config.name); }
-            if (!FLAGS_dryRun) {
-                do {
-                    // Ramp up 1 -> 2 -> 4 -> 8 -> 16 -> ... -> ~1 billion.
-                    loopsPerIter = (loopsPerIter == 0) ? 1 : loopsPerIter * 2;
-                    if (loopsPerIter >= (1<<30) || timer.fWall > FLAGS_maxMs) {
-                        // If you find it takes more than a billion loops to get up to 20ms of runtime,
-                        // you've got a computer clocked at several THz or have a broken benchmark.  ;)
-                        //     "1B ought to be enough for anybody."
-                        logger.logError(SkStringPrintf(
-                            "\nCan't get %s %s to converge in %dms (%d loops)",
-                             bench->getName(), config.name, FLAGS_maxMs, loopsPerIter));
-                        break;
-                    }
-
-                    if ((benchMode == kRecord_BenchMode || benchMode == kPictureRecord_BenchMode)) {
-                        // Clear the recorded commands so that they do not accumulate.
-                        canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
-                    }
-
-                    timer.start();
-                    // Inner loop that allows us to break the run into smaller
-                    // chunks (e.g. frames). This is especially useful for the GPU
-                    // as we can flush and/or swap buffers to keep the GPU from
-                    // queuing up too much work.
-                    for (int loopCount = loopsPerIter; loopCount > 0; ) {
-                        // Save and restore around each call to draw() to guarantee a pristine canvas.
-                        SkAutoCanvasRestore saveRestore(canvas, true/*also save*/);
-
-                        int loops;
-                        if (frameIntervalComputed && loopCount > loopsPerFrame) {
-                            loops = loopsPerFrame;
-                            loopCount -= loopsPerFrame;
-                        } else {
-                            loops = loopCount;
-                            loopCount = 0;
-                        }
-
-                        if (benchMode == kPictureRecord_BenchMode) {
-                            recordFrom->draw(canvas);
-                        } else {
-                            bench->draw(loops, canvas);
-                        }
-
-                        if (kDeferredSilent_BenchMode == benchMode) {
-                            static_cast<SkDeferredCanvas*>(canvas.get())->silentFlush();
-                        } else if (NULL != canvas) {
-                            canvas->flush();
-                        }
-
-    #if SK_SUPPORT_GPU
-                        // swap drawing buffers on each frame to prevent the GPU
-                        // from queuing up too much work
-                        if (NULL != glContext) {
-                            glContext->swapBuffers();
-                        }
-    #endif
-                    }
-
-
-
-                    // Stop truncated timers before GL calls complete, and stop the full timers after.
-                    timer.truncatedEnd();
-    #if SK_SUPPORT_GPU
-                    if (NULL != glContext) {
-                        context->flush();
-                        SK_GL(*glContext, Finish());
-                    }
-    #endif
-                    timer.end();
-
-                    // setup the frame interval for subsequent iterations
-                    if (!frameIntervalComputed) {
-                        frameIntervalTime += timer.fWall;
-                        frameIntervalTotalLoops += loopsPerIter;
-                        if (frameIntervalTime >= FLAGS_minMs) {
-                            frameIntervalComputed = true;
-                            loopsPerFrame =
-                              (int)(((double)frameIntervalTotalLoops / frameIntervalTime) * FLAGS_minMs);
-                            if (loopsPerFrame < 1) {
-                                loopsPerFrame = 1;
-                            }
-    //                        SkDebugf("  %s has %d loops in %f ms (normalized to %d)\n",
-    //                                 bench->getName(), frameIntervalTotalLoops,
-    //                                 timer.fWall, loopsPerFrame);
-                        }
-                    }
-
-                    const double current = timer.fWall / loopsPerIter;
-                    if (FLAGS_verbose && current > previous) { SkDebugf("↑"); }
-                    if (FLAGS_verbose) { SkDebugf("%.3g ", current); }
-                    converged = HasConverged(previous, current, timer.fWall);
-                    previous = current;
-                } while (!FLAGS_runOnce && !converged);
-            }
-            if (FLAGS_verbose) { SkDebugf("\n"); }
-
-            if (!FLAGS_dryRun && FLAGS_outDir.count() && Benchmark::kNonRendering_Backend != config.backend) {
-                SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
-                if (image.get()) {
-                    saveFile(bench->getName(), config.name, FLAGS_outDir[0],
-                             image);
-                }
-            }
-
-            if (FLAGS_runOnce) {
-                // Let's not mislead ourselves by looking at Debug build or single iteration bench times!
-                continue;
-            }
-
-            // Normalize to ms per 1000 iterations.
-            const double normalize = 1000.0 / loopsPerIter;
-            const struct { char shortName; const char* longName; double ms; } times[] = {
-                {'w', "msecs",  normalize * timer.fWall},
-                {'W', "Wmsecs", normalize * timer.fTruncatedWall},
-                {'c', "cmsecs", normalize * timer.fCpu},
-                {'C', "Cmsecs", normalize * timer.fTruncatedCpu},
-                {'g', "gmsecs", normalize * timer.fGpu},
-            };
-
-            writer.config(config.name);
-            for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) {
-                if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms > 0) {
-                    writer.timer(times[i].longName, times[i].ms);
-                }
-            }
-        }
-    }
-#if SK_SUPPORT_GPU
-    gContextFactory.destroyContexts();
-#endif
-    return 0;
-}
-
-#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
-int main(int argc, char * const argv[]) {
-    return tool_main(argc, (char**) argv);
-}
-#endif
diff --git a/bench/microbench.json b/bench/microbench.json
new file mode 100644
index 0000000..940a1cc
--- /dev/null
+++ b/bench/microbench.json
@@ -0,0 +1,122 @@
+{
+    "fields": [
+        {
+            "name": "buildNumber",
+            "type": "INTEGER"
+        },
+        {
+            "name": "gitNumber",
+            "type": "INTEGER"
+        },
+        {
+            "name": "gitHash",
+            "type": "STRING"
+        },
+        {
+            "name": "timestamp",
+            "type": "INTEGER"
+        },
+        {
+            "name": "value",
+            "type": "FLOAT"
+        },
+        {
+            "name": "key",
+            "type": "STRING"
+        },
+        {
+            "name": "is_trybot",
+            "type": "BOOLEAN"
+        },
+        {
+            "name": "params",
+            "type": "RECORD",
+            "fields": [
+                {
+                    "name": "builderName",
+                    "type": "STRING"
+                },
+                {
+                    "name": "configuration",
+                    "type": "STRING"
+                },
+                {
+                    "name": "rotate",
+                    "type": "STRING"
+                },
+                {
+                    "name": "system",
+                    "type": "STRING"
+                },
+                {
+                    "name": "clip",
+                    "type": "STRING"
+                },
+                {
+                    "name": "gpuConfig",
+                    "type": "STRING"
+                },
+                {
+                    "name": "os",
+                    "type": "STRING"
+                },
+                {
+                    "name": "role",
+                    "type": "STRING"
+                },
+                {
+                    "name": "testName",
+                    "type": "STRING"
+                },
+                {
+                    "name": "antialias",
+                    "type": "STRING"
+                },
+                {
+                    "name": "filter",
+                    "type": "STRING"
+                },
+                {
+                    "name": "scale",
+                    "type": "STRING"
+                },
+                {
+                    "name": "build",
+                    "type": "STRING"
+                },
+                {
+                    "name": "gpu",
+                    "type": "STRING"
+                },
+                {
+                    "name": "alpha",
+                    "type": "STRING"
+                },
+                {
+                    "name": "model",
+                    "type": "STRING"
+                },
+                {
+                    "name": "measurementType",
+                    "type": "STRING"
+                },
+                {
+                    "name": "arch",
+                    "type": "STRING"
+                },
+                {
+                    "name": "dither",
+                    "type": "STRING"
+                },
+                {
+                    "name": "mode",
+                    "type": "STRING"
+                },
+                {
+                    "name": "badParams",
+                    "type": "STRING"
+                }
+            ]
+        }
+    ]
+}
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
new file mode 100644
index 0000000..21aeef4
--- /dev/null
+++ b/bench/nanobench.cpp
@@ -0,0 +1,726 @@
+/*
+ * 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 <ctype.h>
+
+#include "Benchmark.h"
+#include "CrashHandler.h"
+#include "GMBench.h"
+#include "ProcStats.h"
+#include "ResultsWriter.h"
+#include "RecordingBench.h"
+#include "SKPBench.h"
+#include "Stats.h"
+#include "Timer.h"
+
+#include "SkBBHFactory.h"
+#include "SkCanvas.h"
+#include "SkCommonFlags.h"
+#include "SkForceLinking.h"
+#include "SkGraphics.h"
+#include "SkOSFile.h"
+#include "SkPictureRecorder.h"
+#include "SkString.h"
+#include "SkSurface.h"
+
+#if SK_SUPPORT_GPU
+    #include "gl/GrGLDefines.h"
+    #include "GrContextFactory.h"
+    SkAutoTDelete<GrContextFactory> gGrFactory;
+#endif
+
+__SK_FORCE_IMAGE_DECODER_LINKING;
+
+static const int kAutoTuneLoops = -1;
+
+static const int kDefaultLoops =
+#ifdef SK_DEBUG
+    1;
+#else
+    kAutoTuneLoops;
+#endif
+
+static SkString loops_help_txt() {
+    SkString help;
+    help.printf("Number of times to run each bench. Set this to %d to auto-"
+                "tune for each bench. Timings are only reported when auto-tuning.",
+                kAutoTuneLoops);
+    return help;
+}
+
+DEFINE_int32(loops, kDefaultLoops, loops_help_txt().c_str());
+
+DEFINE_int32(samples, 10, "Number of samples to measure for each bench.");
+DEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead.");
+DEFINE_double(overheadGoal, 0.0001,
+              "Loop until timer overhead is at most this fraction of our measurments.");
+DEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU.");
+DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allows to lag.");
+DEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to "
+                                          "software path rendering.");
+
+DEFINE_string(outResultsFile, "", "If given, write results here as JSON.");
+DEFINE_int32(maxCalibrationAttempts, 3,
+             "Try up to this many times to guess loops for a bench, or skip the bench.");
+DEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this.");
+DEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs.");
+DEFINE_string(scales, "1.0", "Space-separated scales for SKPs.");
+DEFINE_bool(bbh, true, "Build a BBH for SKPs?");
+
+static SkString humanize(double ms) {
+    if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6));
+    if (ms > 1e+3)     return SkStringPrintf("%.3gs",  ms/1e3);
+    if (ms < 1e-3)     return SkStringPrintf("%.3gns", ms*1e6);
+#ifdef SK_BUILD_FOR_WIN
+    if (ms < 1)        return SkStringPrintf("%.3gus", ms*1e3);
+#else
+    if (ms < 1)        return SkStringPrintf("%.3gµs", ms*1e3);
+#endif
+    return SkStringPrintf("%.3gms", ms);
+}
+#define HUMANIZE(ms) humanize(ms).c_str()
+
+static double time(int loops, Benchmark* bench, SkCanvas* canvas, SkGLContextHelper* gl) {
+    if (canvas) {
+        canvas->clear(SK_ColorWHITE);
+    }
+    WallTimer timer;
+    timer.start();
+    if (bench) {
+        bench->draw(loops, canvas);
+    }
+    if (canvas) {
+        canvas->flush();
+    }
+#if SK_SUPPORT_GPU
+    if (gl) {
+        SK_GL(*gl, Flush());
+        gl->swapBuffers();
+    }
+#endif
+    timer.end();
+    return timer.fWall;
+}
+
+static double estimate_timer_overhead() {
+    double overhead = 0;
+    for (int i = 0; i < FLAGS_overheadLoops; i++) {
+        overhead += time(1, NULL, NULL, NULL);
+    }
+    return overhead / FLAGS_overheadLoops;
+}
+
+static int clamp_loops(int loops) {
+    if (loops < 1) {
+        SkDebugf("ERROR: clamping loops from %d to 1.\n", loops);
+        return 1;
+    }
+    if (loops > FLAGS_maxLoops) {
+        SkDebugf("WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loops, FLAGS_maxLoops);
+        return FLAGS_maxLoops;
+    }
+    return loops;
+}
+
+static bool write_canvas_png(SkCanvas* canvas, const SkString& filename) {
+    if (filename.isEmpty()) {
+        return false;
+    }
+    if (kUnknown_SkColorType == canvas->imageInfo().colorType()) {
+        return false;
+    }
+    SkBitmap bmp;
+    bmp.setInfo(canvas->imageInfo());
+    if (!canvas->readPixels(&bmp, 0, 0)) {
+        SkDebugf("Can't read canvas pixels.\n");
+        return false;
+    }
+    SkString dir = SkOSPath::Dirname(filename.c_str());
+    if (!sk_mkdir(dir.c_str())) {
+        SkDebugf("Can't make dir %s.\n", dir.c_str());
+        return false;
+    }
+    SkFILEWStream stream(filename.c_str());
+    if (!stream.isValid()) {
+        SkDebugf("Can't write %s.\n", filename.c_str());
+        return false;
+    }
+    if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 100)) {
+        SkDebugf("Can't encode a PNG.\n");
+        return false;
+    }
+    return true;
+}
+
+static int kFailedLoops = -2;
+static int cpu_bench(const double overhead, Benchmark* bench, SkCanvas* canvas, double* samples) {
+    // First figure out approximately how many loops of bench it takes to make overhead negligible.
+    double bench_plus_overhead = 0.0;
+    int round = 0;
+    if (kAutoTuneLoops == FLAGS_loops) {
+        while (bench_plus_overhead < overhead) {
+            if (round++ == FLAGS_maxCalibrationAttempts) {
+                SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skipping.\n",
+                         bench->getUniqueName(), HUMANIZE(bench_plus_overhead), HUMANIZE(overhead));
+                return kFailedLoops;
+            }
+            bench_plus_overhead = time(1, bench, canvas, NULL);
+        }
+    }
+
+    // Later we'll just start and stop the timer once but loop N times.
+    // We'll pick N to make timer overhead negligible:
+    //
+    //          overhead
+    //  -------------------------  < FLAGS_overheadGoal
+    //  overhead + N * Bench Time
+    //
+    // where bench_plus_overhead ≈ overhead + Bench Time.
+    //
+    // Doing some math, we get:
+    //
+    //  (overhead / FLAGS_overheadGoal) - overhead
+    //  ------------------------------------------  < N
+    //       bench_plus_overhead - overhead)
+    //
+    // Luckily, this also works well in practice. :)
+    int loops = FLAGS_loops;
+    if (kAutoTuneLoops == loops) {
+        const double numer = overhead / FLAGS_overheadGoal - overhead;
+        const double denom = bench_plus_overhead - overhead;
+        loops = (int)ceil(numer / denom);
+    }
+    loops = clamp_loops(loops);
+
+    for (int i = 0; i < FLAGS_samples; i++) {
+        samples[i] = time(loops, bench, canvas, NULL) / loops;
+    }
+    return loops;
+}
+
+#if SK_SUPPORT_GPU
+static int gpu_bench(SkGLContextHelper* gl,
+                     Benchmark* bench,
+                     SkCanvas* canvas,
+                     double* samples) {
+    gl->makeCurrent();
+    // Make sure we're done with whatever came before.
+    SK_GL(*gl, Finish());
+
+    // First, figure out how many loops it'll take to get a frame up to FLAGS_gpuMs.
+    int loops = FLAGS_loops;
+    if (kAutoTuneLoops == loops) {
+        loops = 1;
+        double elapsed = 0;
+        do {
+            loops *= 2;
+            // If the GPU lets frames lag at all, we need to make sure we're timing
+            // _this_ round, not still timing last round.  We force this by looping
+            // more times than any reasonable GPU will allow frames to lag.
+            for (int i = 0; i < FLAGS_gpuFrameLag; i++) {
+                elapsed = time(loops, bench, canvas, gl);
+            }
+        } while (elapsed < FLAGS_gpuMs);
+
+        // We've overshot at least a little.  Scale back linearly.
+        loops = (int)ceil(loops * FLAGS_gpuMs / elapsed);
+
+        // Might as well make sure we're not still timing our calibration.
+        SK_GL(*gl, Finish());
+    }
+    loops = clamp_loops(loops);
+
+    // Pretty much the same deal as the calibration: do some warmup to make
+    // sure we're timing steady-state pipelined frames.
+    for (int i = 0; i < FLAGS_gpuFrameLag; i++) {
+        time(loops, bench, canvas, gl);
+    }
+
+    // Now, actually do the timing!
+    for (int i = 0; i < FLAGS_samples; i++) {
+        samples[i] = time(loops, bench, canvas, gl) / loops;
+    }
+    return loops;
+}
+#endif
+
+static SkString to_lower(const char* str) {
+    SkString lower(str);
+    for (size_t i = 0; i < lower.size(); i++) {
+        lower[i] = tolower(lower[i]);
+    }
+    return lower;
+}
+
+struct Config {
+    const char* name;
+    Benchmark::Backend backend;
+    SkColorType color;
+    SkAlphaType alpha;
+    int samples;
+#if SK_SUPPORT_GPU
+    GrContextFactory::GLContextType ctxType;
+#else
+    int bogusInt;
+#endif
+};
+
+struct Target {
+    explicit Target(const Config& c) : config(c) {}
+    const Config config;
+    SkAutoTDelete<SkSurface> surface;
+#if SK_SUPPORT_GPU
+    SkGLContextHelper* gl;
+#endif
+};
+
+static bool is_cpu_config_allowed(const char* name) {
+    for (int i = 0; i < FLAGS_config.count(); i++) {
+        if (to_lower(FLAGS_config[i]).equals(name)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+#if SK_SUPPORT_GPU
+static bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextType ctxType,
+                                  int sampleCnt) {
+    if (!is_cpu_config_allowed(name)) {
+        return false;
+    }
+    if (const GrContext* ctx = gGrFactory->get(ctxType)) {
+        return sampleCnt <= ctx->getMaxSampleCount();
+    }
+    return false;
+}
+#endif
+
+#if SK_SUPPORT_GPU
+#define kBogusGLContextType GrContextFactory::kNative_GLContextType
+#else
+#define kBogusGLContextType 0
+#endif
+
+// Append all configs that are enabled and supported.
+static void create_configs(SkTDArray<Config>* configs) {
+    #define CPU_CONFIG(name, backend, color, alpha)                                               \
+        if (is_cpu_config_allowed(#name)) {                                                       \
+            Config config = { #name, Benchmark::backend, color, alpha, 0, kBogusGLContextType };  \
+            configs->push(config);                                                                \
+        }
+
+    if (FLAGS_cpu) {
+        CPU_CONFIG(nonrendering, kNonRendering_Backend, kUnknown_SkColorType, kUnpremul_SkAlphaType)
+        CPU_CONFIG(8888, kRaster_Backend, kN32_SkColorType, kPremul_SkAlphaType)
+        CPU_CONFIG(565, kRaster_Backend, kRGB_565_SkColorType, kOpaque_SkAlphaType)
+    }
+
+#if SK_SUPPORT_GPU
+    #define GPU_CONFIG(name, ctxType, samples)                                   \
+        if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) {  \
+            Config config = {                                                    \
+                #name,                                                           \
+                Benchmark::kGPU_Backend,                                         \
+                kN32_SkColorType,                                                \
+                kPremul_SkAlphaType,                                             \
+                samples,                                                         \
+                GrContextFactory::ctxType };                                     \
+            configs->push(config);                                               \
+        }
+
+    if (FLAGS_gpu) {
+        GPU_CONFIG(gpu, kNative_GLContextType, 0)
+        GPU_CONFIG(msaa4, kNative_GLContextType, 4)
+        GPU_CONFIG(msaa16, kNative_GLContextType, 16)
+        GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4)
+        GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16)
+        GPU_CONFIG(debug, kDebug_GLContextType, 0)
+        GPU_CONFIG(nullgpu, kNull_GLContextType, 0)
+#ifdef SK_ANGLE
+        GPU_CONFIG(angle, kANGLE_GLContextType, 0)
+#endif
+    }
+#endif
+}
+
+// If bench is enabled for config, returns a Target* for it, otherwise NULL.
+static Target* is_enabled(Benchmark* bench, const Config& config) {
+    if (!bench->isSuitableFor(config.backend)) {
+        return NULL;
+    }
+
+    SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().fY,
+                                         config.color, config.alpha);
+
+    Target* target = new Target(config);
+
+    if (Benchmark::kRaster_Backend == config.backend) {
+        target->surface.reset(SkSurface::NewRaster(info));
+    }
+#if SK_SUPPORT_GPU
+    else if (Benchmark::kGPU_Backend == config.backend) {
+        target->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(config.ctxType), info,
+                                                         config.samples));
+        target->gl = gGrFactory->getGLContext(config.ctxType);
+    }
+#endif
+
+    if (Benchmark::kNonRendering_Backend != config.backend && !target->surface.get()) {
+        delete target;
+        return NULL;
+    }
+    return target;
+}
+
+// Creates targets for a benchmark and a set of configs.
+static void create_targets(SkTDArray<Target*>* targets, Benchmark* b,
+                           const SkTDArray<Config>& configs) {
+    for (int i = 0; i < configs.count(); ++i) {
+        if (Target* t = is_enabled(b, configs[i])) {
+            targets->push(t);
+        }
+
+    }
+}
+
+#if SK_SUPPORT_GPU
+static void fill_gpu_options(ResultsWriter* log, SkGLContextHelper* ctx) {
+    const GrGLubyte* version;
+    SK_GL_RET(*ctx, version, GetString(GR_GL_VERSION));
+    log->configOption("GL_VERSION", (const char*)(version));
+
+    SK_GL_RET(*ctx, version, GetString(GR_GL_RENDERER));
+    log->configOption("GL_RENDERER", (const char*) version);
+
+    SK_GL_RET(*ctx, version, GetString(GR_GL_VENDOR));
+    log->configOption("GL_VENDOR", (const char*) version);
+
+    SK_GL_RET(*ctx, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
+    log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version);
+}
+#endif
+
+class BenchmarkStream {
+public:
+    BenchmarkStream() : fBenches(BenchRegistry::Head())
+                      , fGMs(skiagm::GMRegistry::Head())
+                      , fCurrentRecording(0)
+                      , fCurrentScale(0)
+                      , fCurrentSKP(0) {
+        for (int i = 0; i < FLAGS_skps.count(); i++) {
+            if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
+                fSKPs.push_back() = FLAGS_skps[i];
+            } else {
+                SkOSFile::Iter it(FLAGS_skps[i], ".skp");
+                SkString path;
+                while (it.next(&path)) {
+                    fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str());
+                }
+            }
+        }
+
+        if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d",
+                        &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom)) {
+            SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]);
+            exit(1);
+        }
+
+        for (int i = 0; i < FLAGS_scales.count(); i++) {
+            if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) {
+                SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS_scales[i]);
+                exit(1);
+            }
+        }
+    }
+
+    static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) {
+        // Not strictly necessary, as it will be checked again later,
+        // but helps to avoid a lot of pointless work if we're going to skip it.
+        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) {
+            return false;
+        }
+
+        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
+        if (stream.get() == NULL) {
+            SkDebugf("Could not read %s.\n", path);
+            return false;
+        }
+
+        pic->reset(SkPicture::CreateFromStream(stream.get()));
+        if (pic->get() == NULL) {
+            SkDebugf("Could not read %s as an SkPicture.\n", path);
+            return false;
+        }
+        return true;
+    }
+
+    Benchmark* next() {
+        if (fBenches) {
+            Benchmark* bench = fBenches->factory()(NULL);
+            fBenches = fBenches->next();
+            fSourceType = "bench";
+            fBenchType  = "micro";
+            return bench;
+        }
+
+        while (fGMs) {
+            SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL));
+            fGMs = fGMs->next();
+            if (gm->getFlags() & skiagm::GM::kAsBench_Flag) {
+                fSourceType = "gm";
+                fBenchType  = "micro";
+                return SkNEW_ARGS(GMBench, (gm.detach()));
+            }
+        }
+
+        // First add all .skps as RecordingBenches.
+        while (fCurrentRecording < fSKPs.count()) {
+            const SkString& path = fSKPs[fCurrentRecording++];
+            SkAutoTUnref<SkPicture> pic;
+            if (!ReadPicture(path.c_str(), &pic)) {
+                continue;
+            }
+            SkString name = SkOSPath::Basename(path.c_str());
+            fSourceType = "skp";
+            fBenchType  = "recording";
+            return SkNEW_ARGS(RecordingBench, (name.c_str(), pic.get(), FLAGS_bbh));
+        }
+
+        // Then once each for each scale as SKPBenches (playback).
+        while (fCurrentScale < fScales.count()) {
+            while (fCurrentSKP < fSKPs.count()) {
+                const SkString& path = fSKPs[fCurrentSKP++];
+                SkAutoTUnref<SkPicture> pic;
+                if (!ReadPicture(path.c_str(), &pic)) {
+                    continue;
+                }
+                if (FLAGS_bbh) {
+                    // The SKP we read off disk doesn't have a BBH.  Re-record so it grows one.
+                    // Here we use an SkTileGrid with parameters optimized for FLAGS_clip.
+                    const SkTileGridFactory::TileGridInfo info = {
+                        SkISize::Make(fClip.width(), fClip.height()),  // tile interval
+                        SkISize::Make(0,0),                            // margin
+                        SkIPoint::Make(fClip.left(), fClip.top()),     // offset
+                    };
+                    SkTileGridFactory factory(info);
+                    SkPictureRecorder recorder;
+                    pic->playback(recorder.beginRecording(pic->cullRect().width(),
+                                                          pic->cullRect().height(),
+                                                          &factory));
+                    pic.reset(recorder.endRecording());
+                }
+                SkString name = SkOSPath::Basename(path.c_str());
+                fSourceType = "skp";
+                fBenchType  = "playback";
+                return SkNEW_ARGS(SKPBench,
+                        (name.c_str(), pic.get(), fClip, fScales[fCurrentScale]));
+            }
+            fCurrentSKP = 0;
+            fCurrentScale++;
+        }
+
+        return NULL;
+    }
+
+    void fillCurrentOptions(ResultsWriter* log) const {
+        log->configOption("source_type", fSourceType);
+        log->configOption("bench_type",  fBenchType);
+        if (0 == strcmp(fSourceType, "skp")) {
+            log->configOption("clip",
+                    SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop,
+                                                  fClip.fRight, fClip.fBottom).c_str());
+            log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentScale]).c_str());
+        }
+    }
+
+private:
+    const BenchRegistry* fBenches;
+    const skiagm::GMRegistry* fGMs;
+    SkIRect            fClip;
+    SkTArray<SkScalar> fScales;
+    SkTArray<SkString> fSKPs;
+
+    const char* fSourceType;  // What we're benching: bench, GM, SKP, ...
+    const char* fBenchType;   // How we bench it: micro, recording, playback, ...
+    int fCurrentRecording;
+    int fCurrentScale;
+    int fCurrentSKP;
+};
+
+int nanobench_main();
+int nanobench_main() {
+    SetupCrashHandler();
+    SkAutoGraphics ag;
+
+#if SK_SUPPORT_GPU
+    GrContext::Options grContextOpts;
+    grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks;
+    gGrFactory.reset(SkNEW_ARGS(GrContextFactory, (grContextOpts)));
+#endif
+
+    if (kAutoTuneLoops != FLAGS_loops) {
+        FLAGS_samples     = 1;
+        FLAGS_gpuFrameLag = 0;
+    }
+
+    if (!FLAGS_writePath.isEmpty()) {
+        SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]);
+        if (!sk_mkdir(FLAGS_writePath[0])) {
+            SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_writePath[0]);
+            FLAGS_writePath.set(0, NULL);
+        }
+    }
+
+    SkAutoTDelete<ResultsWriter> log(SkNEW(ResultsWriter));
+    if (!FLAGS_outResultsFile.isEmpty()) {
+        log.reset(SkNEW(NanoJSONResultsWriter(FLAGS_outResultsFile[0])));
+    }
+
+    if (1 == FLAGS_properties.count() % 2) {
+        SkDebugf("ERROR: --properties must be passed with an even number of arguments.\n");
+        return 1;
+    }
+    for (int i = 1; i < FLAGS_properties.count(); i += 2) {
+        log->property(FLAGS_properties[i-1], FLAGS_properties[i]);
+    }
+
+    if (1 == FLAGS_key.count() % 2) {
+        SkDebugf("ERROR: --key must be passed with an even number of arguments.\n");
+        return 1;
+    }
+    for (int i = 1; i < FLAGS_key.count(); i += 2) {
+        log->key(FLAGS_key[i-1], FLAGS_key[i]);
+    }
+
+    const double overhead = estimate_timer_overhead();
+    SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead));
+
+    SkAutoTMalloc<double> samples(FLAGS_samples);
+
+    if (kAutoTuneLoops != FLAGS_loops) {
+        SkDebugf("Fixed number of loops; times would only be misleading so we won't print them.\n");
+    } else if (FLAGS_verbose) {
+        // No header.
+    } else if (FLAGS_quiet) {
+        SkDebugf("median\tbench\tconfig\n");
+    } else {
+        SkDebugf("maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tbench\n",
+                 FLAGS_samples, "samples");
+    }
+
+    SkTDArray<Config> configs;
+    create_configs(&configs);
+
+    BenchmarkStream benchStream;
+    while (Benchmark* b = benchStream.next()) {
+        SkAutoTDelete<Benchmark> bench(b);
+        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName())) {
+            continue;
+        }
+
+        SkTDArray<Target*> targets;
+        create_targets(&targets, bench.get(), configs);
+
+        if (!targets.isEmpty()) {
+            log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSize().fY);
+            bench->preDraw();
+        }
+        for (int j = 0; j < targets.count(); j++) {
+            SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->getCanvas() : NULL;
+            const char* config = targets[j]->config.name;
+
+            const int loops =
+#if SK_SUPPORT_GPU
+                Benchmark::kGPU_Backend == targets[j]->config.backend
+                ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get())
+                :
+#endif
+                 cpu_bench(       overhead, bench.get(), canvas, samples.get());
+
+            if (canvas && !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) {
+                SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config);
+                pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniqueName());
+                pngFilename.append(".png");
+                write_canvas_png(canvas, pngFilename);
+            }
+
+            if (kFailedLoops == loops) {
+                // Can't be timed.  A warning note has already been printed.
+                continue;
+            }
+
+            Stats stats(samples.get(), FLAGS_samples);
+            log->config(config);
+            log->configOption("name", bench->getName());
+            benchStream.fillCurrentOptions(log.get());
+#if SK_SUPPORT_GPU
+            if (Benchmark::kGPU_Backend == targets[j]->config.backend) {
+                fill_gpu_options(log.get(), targets[j]->gl);
+            }
+#endif
+            log->timer("min_ms",    stats.min);
+            log->timer("median_ms", stats.median);
+            log->timer("mean_ms",   stats.mean);
+            log->timer("max_ms",    stats.max);
+            log->timer("stddev_ms", sqrt(stats.var));
+
+            if (kAutoTuneLoops != FLAGS_loops) {
+                if (targets.count() == 1) {
+                    config = ""; // Only print the config if we run the same bench on more than one.
+                }
+                SkDebugf("%4dM\t%s\t%s\n"
+                         , sk_tools::getMaxResidentSetSizeMB()
+                         , bench->getUniqueName()
+                         , config);
+            } else if (FLAGS_verbose) {
+                for (int i = 0; i < FLAGS_samples; i++) {
+                    SkDebugf("%s  ", HUMANIZE(samples[i]));
+                }
+                SkDebugf("%s\n", bench->getUniqueName());
+            } else if (FLAGS_quiet) {
+                if (targets.count() == 1) {
+                    config = ""; // Only print the config if we run the same bench on more than one.
+                }
+                SkDebugf("%s\t%s\t%s\n", HUMANIZE(stats.median), bench->getUniqueName(), config);
+            } else {
+                const double stddev_percent = 100 * sqrt(stats.var) / stats.mean;
+                SkDebugf("%4dM\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n"
+                        , sk_tools::getMaxResidentSetSizeMB()
+                        , loops
+                        , HUMANIZE(stats.min)
+                        , HUMANIZE(stats.median)
+                        , HUMANIZE(stats.mean)
+                        , HUMANIZE(stats.max)
+                        , stddev_percent
+                        , stats.plot.c_str()
+                        , config
+                        , bench->getUniqueName()
+                        );
+            }
+        }
+        targets.deleteAll();
+
+    #if SK_SUPPORT_GPU
+        if (FLAGS_abandonGpuContext) {
+            gGrFactory->abandonContexts();
+        }
+        if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) {
+            gGrFactory->destroyContexts();
+        }
+    #endif
+    }
+
+    return 0;
+}
+
+#if !defined SK_BUILD_FOR_IOS
+int main(int argc, char** argv) {
+    SkCommandLineFlags::Parse(argc, argv);
+    return nanobench_main();
+}
+#endif
diff --git a/bench/skpbench.json b/bench/skpbench.json
new file mode 100644
index 0000000..1e0e23f
--- /dev/null
+++ b/bench/skpbench.json
@@ -0,0 +1,102 @@
+{
+    "fields": [
+        {
+            "name": "buildNumber",
+            "type": "INTEGER"
+        },
+        {
+            "name": "gitNumber",
+            "type": "INTEGER"
+        },
+        {
+            "name": "gitHash",
+            "type": "STRING"
+        },
+        {
+            "name": "timestamp",
+            "type": "INTEGER"
+        },
+        {
+            "name": "value",
+            "type": "FLOAT"
+        },
+        {
+            "name": "key",
+            "type": "STRING"
+        },
+        {
+            "name": "isTrybot",
+            "type": "BOOLEAN"
+        },
+        {
+            "name": "params",
+            "type": "RECORD",
+            "fields": [
+                {
+                    "name": "builderName",
+                    "type": "STRING"
+                },
+                {
+                    "name": "config",
+                    "type": "STRING"
+                },
+                {
+                    "name": "arch",
+                    "type": "STRING"
+                },
+                {
+                    "name": "configuration",
+                    "type": "STRING"
+                },
+                {
+                    "name": "role",
+                    "type": "STRING"
+                },
+                {
+                    "name": "skpSize",
+                    "type": "STRING"
+                },
+                {
+                    "name": "mode",
+                    "type": "STRING"
+                },
+                {
+                    "name": "benchName",
+                    "type": "STRING"
+                },
+                {
+                    "name": "gpu",
+                    "type": "STRING"
+                },
+                {
+                    "name": "model",
+                    "type": "STRING"
+                },
+                {
+                    "name": "measurementType",
+                    "type": "STRING"
+                },
+                {
+                    "name": "os",
+                    "type": "STRING"
+                },
+                {
+                    "name": "viewport",
+                    "type": "STRING"
+                },
+                {
+                    "name": "scale",
+                    "type": "FLOAT"
+                },
+                {
+                    "name": "bbh",
+                    "type": "STRING"
+                },
+                {
+                    "name": "badParams",
+                    "type": "STRING"
+                }
+            ]
+        }
+    ]
+}
diff --git a/codereview.settings b/codereview.settings
index 1aeec8a..0dba340 100644
--- a/codereview.settings
+++ b/codereview.settings
@@ -4,3 +4,4 @@
 CC_LIST: reviews@skia.org
 BUG_PREFIX: skia:
 TRYSERVER_SVN_URL: https://skia-try.googlecode.com/svn
+PROJECT: skia
diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp
index 1873afc..b03b8f3 100644
--- a/debugger/QT/SkDebuggerGUI.cpp
+++ b/debugger/QT/SkDebuggerGUI.cpp
@@ -11,19 +11,20 @@
 #include "SkImageDecoder.h"
 #include <QListWidgetItem>
 #include "PictureRenderer.h"
-#include "SkPictureRecord.h"
 #include "SkPicturePlayback.h"
+#include "SkPictureRecord.h"
+#include "SkPictureData.h"
 
 __SK_FORCE_IMAGE_DECODER_LINKING;
 
 #if defined(SK_BUILD_FOR_WIN32)
-    #include "BenchSysTimer_windows.h"
+    #include "SysTimer_windows.h"
 #elif defined(SK_BUILD_FOR_MAC)
-    #include "BenchSysTimer_mach.h"
+    #include "SysTimer_mach.h"
 #elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
-    #include "BenchSysTimer_posix.h"
+    #include "SysTimer_posix.h"
 #else
-    #include "BenchSysTimer_c.h"
+    #include "SysTimer_c.h"
 #endif
 
 
@@ -155,26 +156,14 @@
     }
 }
 
-// The timed picture playback uses the SkPicturePlayback's profiling stubs
-// to time individual commands. The offsets are needed to map SkPicture
-// offsets to individual commands.
+// The timed picture playback just steps through every operation timing
+// each one individually. Note that each picture should be replayed multiple 
+// times (via calls to 'draw') before each command's time is accessed via 'time'.
 class SkTimedPicturePlayback : public SkPicturePlayback {
 public:
-    static SkTimedPicturePlayback* CreateFromStream(SkStream* stream, const SkPictInfo& info,
-                                                    SkPicture::InstallPixelRefProc proc,
-                                                    const SkTDArray<bool>& deletedCommands) {
-        // Mimics SkPicturePlayback::CreateFromStream
-        SkAutoTDelete<SkTimedPicturePlayback> playback(SkNEW_ARGS(SkTimedPicturePlayback,
-                                                               (deletedCommands, info)));
-        if (!playback->parseStream(stream, proc)) {
-            return NULL; // we're invalid
-        }
-        return playback.detach();
-    }
 
-    SkTimedPicturePlayback(const SkTDArray<bool>& deletedCommands,
-                           const SkPictInfo& info)
-        : INHERITED(info)
+    SkTimedPicturePlayback(const SkPicture* picture, const SkTDArray<bool>& deletedCommands)
+        : INHERITED(picture)
         , fSkipCommands(deletedCommands)
         , fTot(0.0)
         , fCurCommand(0) {
@@ -183,6 +172,47 @@
         this->resetTimes();
     }
 
+    virtual void draw(SkCanvas* canvas, SkDrawPictureCallback* callback) SK_OVERRIDE {
+        AutoResetOpID aroi(this);
+        SkASSERT(0 == fCurOffset);
+
+        SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData()->size());
+
+        // Record this, so we can concat w/ it if we encounter a setMatrix()
+        SkMatrix initialMatrix = canvas->getTotalMatrix();
+
+        SkAutoCanvasRestore acr(canvas, false);
+
+        int opIndex = -1;
+
+        while (!reader.eof()) {
+            if (callback && callback->abortDrawing()) {
+                return;
+            }
+
+            fCurOffset = reader.offset();
+            uint32_t size;
+            DrawType op = ReadOpAndSize(&reader, &size);
+            if (NOOP == op) {
+                // NOOPs are to be ignored - do not propagate them any further
+                reader.setOffset(fCurOffset + size);
+                continue;
+            }
+
+            opIndex++;
+
+            if (this->preDraw(opIndex, op)) {
+                // This operation is disabled in the debugger's GUI
+                reader.setOffset(fCurOffset + size);
+                continue;
+            }
+
+            this->handleOp(&reader, op, size, canvas, initialMatrix);
+
+            this->postDraw(opIndex);
+        }
+    }
+
     void resetTimes() {
         for (int i = 0; i < fTimes.count(); ++i) {
             fTimes[i] = 0.0;
@@ -195,6 +225,7 @@
 
     int count() const { return fTimes.count(); }
 
+    // Return the fraction of the total time consumed by the index-th operation
     double time(int index) const { return fTimes[index] / fTot; }
 
     const SkTDArray<double>* typeTimes() const { return &fTypeTimes; }
@@ -202,16 +233,16 @@
     double totTime() const { return fTot; }
 
 protected:
-    BenchSysTimer fTimer;
+    SysTimer fTimer;
     SkTDArray<bool> fSkipCommands; // has the command been deleted in the GUI?
     SkTDArray<double> fTimes;   // sum of time consumed for each command
     SkTDArray<double> fTypeTimes; // sum of time consumed for each type of command (e.g., drawPath)
     double fTot;                // total of all times in 'fTimes'
+
     int fCurType;
     int fCurCommand;            // the current command being executed/timed
 
-#ifdef SK_DEVELOPER
-    virtual bool preDraw(int opIndex, int type) SK_OVERRIDE {
+    bool preDraw(int opIndex, int type) {
         fCurCommand = opIndex;
 
         if (fSkipCommands[fCurCommand]) {
@@ -238,7 +269,7 @@
         return false;
     }
 
-    virtual void postDraw(int opIndex) SK_OVERRIDE {
+    void postDraw(int opIndex) {
 #if defined(SK_BUILD_FOR_WIN32)
         // CPU timer doesn't work well on Windows
         double time = fTimer.endWall();
@@ -253,12 +284,12 @@
         fTypeTimes[fCurType] += time;
         fTot += time;
     }
-#endif
 
 private:
     typedef SkPicturePlayback INHERITED;
 };
 
+#if 0
 // Wrap SkPicture to allow installation of an SkTimedPicturePlayback object
 class SkTimedPicture : public SkPicture {
 public:
@@ -286,19 +317,19 @@
         return NULL;
     }
 
-    void resetTimes() { ((SkTimedPicturePlayback*) fPlayback)->resetTimes(); }
+    void resetTimes() { ((SkTimedPicturePlayback*) fData.get())->resetTimes(); }
 
-    int count() const { return ((SkTimedPicturePlayback*) fPlayback)->count(); }
+    int count() const { return ((SkTimedPicturePlayback*) fData.get())->count(); }
 
     // return the fraction of the total time this command consumed
-    double time(int index) const { return ((SkTimedPicturePlayback*) fPlayback)->time(index); }
+    double time(int index) const { return ((SkTimedPicturePlayback*) fData.get())->time(index); }
 
-    const SkTDArray<double>* typeTimes() const { return ((SkTimedPicturePlayback*) fPlayback)->typeTimes(); }
+    const SkTDArray<double>* typeTimes() const { return ((SkTimedPicturePlayback*) fData.get())->typeTimes(); }
 
-    double totTime() const { return ((SkTimedPicturePlayback*) fPlayback)->totTime(); }
+    double totTime() const { return ((SkTimedPicturePlayback*) fData.get())->totTime(); }
 
 private:
-    // disallow default ctor b.c. we don't have a good way to setup the fPlayback ptr
+    // disallow default ctor b.c. we don't have a good way to setup the fData ptr
     SkTimedPicture();
     // Private ctor only used by CreateTimedPicture, which has created the playback.
     SkTimedPicture(SkTimedPicturePlayback* playback, int width, int height)
@@ -308,10 +339,11 @@
 
     typedef SkPicture INHERITED;
 };
+#endif
 
 // This is a simplification of PictureBenchmark's run with the addition of
 // clearing of the times after the first pass (in resetTimes)
-void SkDebuggerGUI::run(SkTimedPicture* pict,
+void SkDebuggerGUI::run(const SkPicture* pict,
                         sk_tools::PictureRenderer* renderer,
                         int repeats) {
     SkASSERT(pict);
@@ -330,8 +362,10 @@
     renderer->render();
     renderer->resetState(true);    // flush, swapBuffers and Finish
 
+#if 0
     // We throw this away the first batch of times to remove first time effects (such as paging in this program)
     pict->resetTimes();
+#endif
 
     for (int i = 0; i < repeats; ++i) {
         renderer->setup();
@@ -360,12 +394,15 @@
         return;
     }
 
-    SkAutoTUnref<SkTimedPicture> picture(SkTimedPicture::CreateTimedPicture(&inputStream,
-                                         &SkImageDecoder::DecodeMemory, fSkipCommands));
+    SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream,
+                                        &SkImageDecoder::DecodeMemory)); // , fSkipCommands));
     if (NULL == picture.get()) {
         return;
     }
 
+
+#if 0
+
     // For now this #if allows switching between tiled and simple rendering
     // modes. Eventually this will be accomplished via the GUI
 #if 0
@@ -414,6 +451,8 @@
 
     setupOverviewText(picture->typeTimes(), picture->totTime(), kNumRepeats);
     setupClipStackText();
+
+#endif
 }
 
 void SkDebuggerGUI::actionCancel() {
diff --git a/debugger/QT/SkDebuggerGUI.h b/debugger/QT/SkDebuggerGUI.h
index a137ee7..3f44550 100644
--- a/debugger/QT/SkDebuggerGUI.h
+++ b/debugger/QT/SkDebuggerGUI.h
@@ -357,7 +357,7 @@
         Render the supplied picture several times tracking the time consumed
         by each command.
      */
-    void run(SkTimedPicture* pict,
+    void run(const SkPicture* pict,
              sk_tools::PictureRenderer* renderer,
              int repeats);
 };
diff --git a/debugger/QT/SkGLWidget.cpp b/debugger/QT/SkGLWidget.cpp
index 019654f..bd24d4e 100644
--- a/debugger/QT/SkGLWidget.cpp
+++ b/debugger/QT/SkGLWidget.cpp
@@ -47,7 +47,8 @@
     GrBackendRenderTargetDesc desc = this->getDesc(this->width(), this->height());
     desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     GrRenderTarget* curRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
-    fGpuDevice = new SkGpuDevice(fCurContext, curRenderTarget);
+    fGpuDevice = SkGpuDevice::Create(curRenderTarget,
+                                     SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType));
     fCanvas = new SkCanvas(fGpuDevice);
     curRenderTarget->unref();
 }
@@ -65,10 +66,11 @@
         GrRenderTarget* curRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
         SkSafeUnref(fGpuDevice);
         SkSafeUnref(fCanvas);
-        fGpuDevice = new SkGpuDevice(fCurContext, curRenderTarget);
+        fGpuDevice = SkGpuDevice::Create(curRenderTarget,
+                                         SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType));
         fCanvas = new SkCanvas(fGpuDevice);
     }
-    fDebugger->resize(w, h);
+    fDebugger->setWindowSize(w, h);
     draw();
 }
 
diff --git a/debugger/QT/SkImageWidget.cpp b/debugger/QT/SkImageWidget.cpp
index 03c7e7e..aad9794 100644
--- a/debugger/QT/SkImageWidget.cpp
+++ b/debugger/QT/SkImageWidget.cpp
@@ -13,15 +13,11 @@
 
 SkImageWidget::SkImageWidget(SkDebugger *debugger)
     : QWidget()
-    , fDebugger(debugger) {
+    , fDebugger(debugger)
+{
     this->setStyleSheet("QWidget {background-color: white; border: 1px solid #cccccc;}");
 
-    SkImageInfo info;
-    info.fWidth = kImageWidgetWidth;
-    info.fHeight = kImageWidgetHeight;
-    info.fColorType = kN32_SkColorType;
-    info.fAlphaType = kPremul_SkAlphaType;
-
+    SkImageInfo info = SkImageInfo::MakeN32Premul(kImageWidgetWidth, kImageWidgetHeight);
     fSurface = SkSurface::NewRasterDirect(info, fPixels, 4 * kImageWidgetWidth);
 }
 
diff --git a/debugger/QT/SkRasterWidget.cpp b/debugger/QT/SkRasterWidget.cpp
index 705fdf0..ad05d39 100644
--- a/debugger/QT/SkRasterWidget.cpp
+++ b/debugger/QT/SkRasterWidget.cpp
@@ -29,7 +29,7 @@
     SkSafeUnref(fDevice);
     fDevice = new SkBitmapDevice(fBitmap);
     fCanvas = new SkCanvas(fDevice);
-    fDebugger->resize(event->size().width(), event->size().height());
+    fDebugger->setWindowSize(event->size().width(), event->size().height());
     this->update();
 }
 
diff --git a/debugger/SkDebugger.cpp b/debugger/SkDebugger.cpp
index af6900c..b220043 100644
--- a/debugger/SkDebugger.cpp
+++ b/debugger/SkDebugger.cpp
@@ -13,10 +13,8 @@
 
 SkDebugger::SkDebugger() {
     // Create this some other dynamic way?
-    fDebugCanvas = new SkDebugCanvas(100, 100);
+    fDebugCanvas = new SkDebugCanvas(0, 0);
     fPicture = NULL;
-    fPictureWidth = 0;
-    fPictureHeight = 0;
     fIndex = 0;
 }
 
@@ -27,23 +25,23 @@
 }
 
 void SkDebugger::loadPicture(SkPicture* picture) {
-    fPictureWidth = picture->width();
-    fPictureHeight = picture->height();
+    SkRefCnt_SafeAssign(fPicture, picture);
+
     delete fDebugCanvas;
-    fDebugCanvas = new SkDebugCanvas(fPictureWidth, fPictureHeight);
-    fDebugCanvas->setBounds(fPictureWidth, fPictureHeight);
+    fDebugCanvas = new SkDebugCanvas(SkScalarCeilToInt(this->pictureCull().width()), 
+                                     SkScalarCeilToInt(this->pictureCull().height()));
     fDebugCanvas->setPicture(picture);
-    picture->draw(fDebugCanvas);
+    picture->playback(fDebugCanvas);
     fDebugCanvas->setPicture(NULL);
     fIndex = fDebugCanvas->getSize() - 1;
-    SkRefCnt_SafeAssign(fPicture, picture);
 }
 
 SkPicture* SkDebugger::copyPicture() {
     // We can't just call clone here since we want to removed the "deleted"
     // commands. Playing back will strip those out.
     SkPictureRecorder recorder;
-    SkCanvas* canvas = recorder.beginRecording(fPictureWidth, fPictureHeight, NULL, 0);
+    SkCanvas* canvas = recorder.beginRecording(this->pictureCull().width(), 
+                                               this->pictureCull().height());
 
     bool vizMode = fDebugCanvas->getMegaVizMode();
     fDebugCanvas->setMegaVizMode(false);
@@ -100,7 +98,7 @@
         overview->append(SkDrawCommand::GetCommandString((DrawType) i));
         overview->append(": ");
         overview->appendS32(counts[i]);
-        if (NULL != typeTimes && totTime >= 0.0) {
+        if (typeTimes && totTime >= 0.0) {
             overview->append(" - ");
             overview->appendf("%.2f", (*typeTimes)[i]/(float)numRuns);
             overview->append("ms");
@@ -117,7 +115,7 @@
         total += counts[i];
     }
 #ifdef SK_DEBUG
-    if (NULL != typeTimes) {
+    if (typeTimes) {
         SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(totPercent),
                                      SkDoubleToScalar(100.0)));
         SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(tempSum),
@@ -143,13 +141,15 @@
     totalStr.append("<br/>");
     overview->insert(0, totalStr);
 
+    overview->append("<br/>SkPicture L: ");
+    overview->appendScalar(this->pictureCull().fLeft);
+    overview->append(" T: ");
+    overview->appendScalar(this->pictureCull().fTop);
+    overview->append(" R: ");
+    overview->appendScalar(this->pictureCull().fRight);
+    overview->append(" B: ");
+    overview->appendScalar(this->pictureCull().fBottom);
     overview->append("<br/>");
-    overview->append("SkPicture Width: ");
-    overview->appendS32(pictureWidth());
-    overview->append("px<br/>");
-    overview->append("SkPicture Height: ");
-    overview->appendS32(pictureHeight());
-    overview->append("px");
 }
 
 void SkDebugger::getClipStackText(SkString* clipStack) {
diff --git a/debugger/SkDebugger.h b/debugger/SkDebugger.h
index ffb2953..53b480a 100644
--- a/debugger/SkDebugger.h
+++ b/debugger/SkDebugger.h
@@ -60,9 +60,7 @@
         fDebugCanvas->toggleFilter(on);
     }
 
-    void resize(int width, int height) {
-        fDebugCanvas->setBounds(width, height);
-    }
+    void setWindowSize(int width, int height) { fDebugCanvas->setWindowSize(width, height); }
 
     void loadPicture(SkPicture* picture);
 
@@ -93,12 +91,8 @@
         return fDebugCanvas->getCurrentClip();
     }
 
-    int pictureHeight() {
-        return fPictureHeight;
-    }
-
-    int pictureWidth() {
-        return fPictureWidth;
+    SkRect pictureCull() const   { 
+        return NULL == fPicture ? SkRect::MakeEmpty() : fPicture->cullRect();
     }
 
     int index() {
@@ -106,25 +100,25 @@
     }
 
     void setOverdrawViz(bool overDrawViz) {
-        if (NULL != fDebugCanvas) {
+        if (fDebugCanvas) {
             fDebugCanvas->setOverdrawViz(overDrawViz);
         }
     }
 
     void setPathOps(bool pathOps) {
-        if (NULL != fDebugCanvas) {
+        if (fDebugCanvas) {
             fDebugCanvas->setAllowSimplifyClip(pathOps);
         }
     }
 
     void setMegaViz(bool megaViz) {
-        if (NULL != fDebugCanvas) {
+        if (fDebugCanvas) {
             fDebugCanvas->setMegaVizMode(megaViz);
         }
     }
 
     void setTexFilterOverride(bool texFilterOverride, SkPaint::FilterLevel level) {
-        if (NULL != fDebugCanvas) {
+        if (fDebugCanvas) {
             fDebugCanvas->overrideTexFiltering(texFilterOverride, level);
         }
     }
@@ -138,8 +132,6 @@
     SkDebugCanvas* fDebugCanvas;
     SkPicture* fPicture;
 
-    int fPictureWidth;
-    int fPictureHeight;
     int fIndex;
 };
 
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 2981013..aba6523 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -1,17 +1,20 @@
 // Main binary for DM.
 // For a high-level overview, please see dm/README.
 
-#include "Benchmark.h"
 #include "CrashHandler.h"
-#include "SkCommandLineFlags.h"
+#include "LazyDecodeBitmap.h"
+#include "SkCommonFlags.h"
 #include "SkForceLinking.h"
 #include "SkGraphics.h"
+#include "SkOSFile.h"
 #include "SkPicture.h"
 #include "SkString.h"
+#include "SkTaskGroup.h"
 #include "Test.h"
 #include "gm.h"
+#include "sk_tool_utils.h"
+#include "sk_tool_utils_flags.h"
 
-#include "DMBenchTask.h"
 #include "DMCpuGMTask.h"
 #include "DMGpuGMTask.h"
 #include "DMGpuSupport.h"
@@ -37,34 +40,13 @@
 using skiatest::Test;
 using skiatest::TestRegistry;
 
-DEFINE_int32(threads, -1, "Threads for CPU work. Default NUM_CPUS.");
-DEFINE_int32(gpuThreads, 1, "Threads for GPU work.");
-DEFINE_string2(expectations, r, "",
-               "If a directory, compare generated images against images under this path. "
-               "If a file, compare generated images against JSON expectations at this path."
-);
-DEFINE_string2(resources, i, "resources", "Path to resources directory.");
-DEFINE_string(match, "",  "[~][^]substring[$] [...] of GM name to run.\n"
-                          "Multiple matches may be separated by spaces.\n"
-                          "~ causes a matching GM to always be skipped\n"
-                          "^ requires the start of the GM to match\n"
-                          "$ requires the end of the GM to match\n"
-                          "^ and $ requires an exact match\n"
-                          "If a GM does not match any list entry,\n"
-                          "it is skipped unless some list entry starts with ~");
-DEFINE_string(config, "565 8888 pdf gpu nonrendering",
-              "Options: 565 8888 pdf gpu nonrendering msaa4 msaa16 nvprmsaa4 nvprmsaa16 "
-              "gpunull gpudebug angle mesa");
-DEFINE_bool(dryRun, false,
-            "Just print the tests that would be run, without actually running them.");
-DEFINE_bool(leaks, false, "Print leaked instance-counted objects at exit?");
-DEFINE_string(skps, "", "Directory to read skps from.");
+static const char kGpuAPINameGL[] = "gl";
+static const char kGpuAPINameGLES[] = "gles";
 
 DEFINE_bool(gms, true, "Run GMs?");
-DEFINE_bool(benches, true, "Run benches?  Does not run GMs-as-benches.");
 DEFINE_bool(tests, true, "Run tests?");
-
-DECLARE_bool(verbose);
+DEFINE_bool(reportUsedChars, false, "Output test font construction data to be pasted into"
+                                    " create_test_font.cpp.");
 
 __SK_FORCE_IMAGE_DECODER_LINKING;
 
@@ -77,25 +59,19 @@
 }
 
 static const GrContextFactory::GLContextType native = GrContextFactory::kNative_GLContextType;
-static const GrContextFactory::GLContextType nvpr = GrContextFactory::kNVPR_GLContextType;
+static const GrContextFactory::GLContextType nvpr   = GrContextFactory::kNVPR_GLContextType;
 static const GrContextFactory::GLContextType null   = GrContextFactory::kNull_GLContextType;
 static const GrContextFactory::GLContextType debug  = GrContextFactory::kDebug_GLContextType;
-static const GrContextFactory::GLContextType angle  =
 #if SK_ANGLE
-GrContextFactory::kANGLE_GLContextType;
-#else
-native;
+static const GrContextFactory::GLContextType angle  = GrContextFactory::kANGLE_GLContextType;
 #endif
-static const GrContextFactory::GLContextType mesa   =
 #if SK_MESA
-GrContextFactory::kMESA_GLContextType;
-#else
-native;
+static const GrContextFactory::GLContextType mesa   = GrContextFactory::kMESA_GLContextType;
 #endif
 
 static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
                          const SkTArray<SkString>& configs,
-                         const DM::Expectations& expectations,
+                         GrGLStandard gpuAPI,
                          DM::Reporter* reporter,
                          DM::TaskRunner* tasks) {
 #define START(name, type, ...)                                                              \
@@ -104,45 +80,23 @@
     }
     for (int i = 0; i < gms.count(); i++) {
         for (int j = 0; j < configs.count(); j++) {
-            START("565",        CpuGMTask, expectations, kRGB_565_SkColorType);
-            START("8888",       CpuGMTask, expectations, kN32_SkColorType);
-            START("gpu",        GpuGMTask, expectations, native, 0);
-            START("msaa4",      GpuGMTask, expectations, native, 4);
-            START("msaa16",     GpuGMTask, expectations, native, 16);
-            START("nvprmsaa4",  GpuGMTask, expectations, nvpr,   4);
-            START("nvprmsaa16", GpuGMTask, expectations, nvpr,   16);
-            START("gpunull",    GpuGMTask, expectations, null,   0);
-            START("gpudebug",   GpuGMTask, expectations, debug,  0);
-            START("angle",      GpuGMTask, expectations, angle,  0);
-            START("mesa",       GpuGMTask, expectations, mesa,   0);
-            START("pdf",        PDFTask,   RASTERIZE_PDF_PROC);
-        }
-    }
-#undef START
-}
 
-static void kick_off_benches(const SkTDArray<BenchRegistry::Factory>& benches,
-                             const SkTArray<SkString>& configs,
-                             DM::Reporter* reporter,
-                             DM::TaskRunner* tasks) {
-#define START(name, type, ...)                                                                 \
-    if (lowercase(configs[j]).equals(name)) {                                                  \
-        tasks->add(SkNEW_ARGS(DM::type, (name, reporter, tasks, benches[i], ## __VA_ARGS__))); \
-    }
-    for (int i = 0; i < benches.count(); i++) {
-        for (int j = 0; j < configs.count(); j++) {
-            START("nonrendering", NonRenderingBenchTask);
-            START("565",          CpuBenchTask, kRGB_565_SkColorType);
-            START("8888",         CpuBenchTask, kN32_SkColorType);
-            START("gpu",          GpuBenchTask, native, 0);
-            START("msaa4",        GpuBenchTask, native, 4);
-            START("msaa16",       GpuBenchTask, native, 16);
-            START("nvprmsaa4",    GpuBenchTask, nvpr,   4);
-            START("nvprmsaa16",   GpuBenchTask, nvpr,   16);
-            START("gpunull",      GpuBenchTask, null,   0);
-            START("gpudebug",     GpuBenchTask, debug,  0);
-            START("angle",        GpuBenchTask, angle,  0);
-            START("mesa",         GpuBenchTask, mesa,   0);
+            START("565",        CpuGMTask, kRGB_565_SkColorType);
+            START("8888",       CpuGMTask, kN32_SkColorType);
+            START("gpu",        GpuGMTask, native, gpuAPI, 0);
+            START("msaa4",      GpuGMTask, native, gpuAPI, 4);
+            START("msaa16",     GpuGMTask, native, gpuAPI, 16);
+            START("nvprmsaa4",  GpuGMTask, nvpr,   gpuAPI, 4);
+            START("nvprmsaa16", GpuGMTask, nvpr,   gpuAPI, 16);
+            START("gpunull",    GpuGMTask, null,   gpuAPI, 0);
+            START("gpudebug",   GpuGMTask, debug,  gpuAPI, 0);
+#if SK_ANGLE
+            START("angle",      GpuGMTask, angle,  gpuAPI, 0);
+#endif
+#if SK_MESA
+            START("mesa",       GpuGMTask, mesa,   gpuAPI, 0);
+#endif
+            START("pdf",        PDFTask,   RASTERIZE_PDF_PROC);
         }
     }
 #undef START
@@ -161,7 +115,7 @@
     }
 }
 
-static void kick_off_skps(DM::Reporter* reporter, DM::TaskRunner* tasks) {
+static void find_skps(SkTArray<SkString>* skps) {
     if (FLAGS_skps.isEmpty()) {
         return;
     }
@@ -169,26 +123,31 @@
     SkOSFile::Iter it(FLAGS_skps[0], ".skp");
     SkString filename;
     while (it.next(&filename)) {
-        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) {
-            continue;
+        if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) {
+            skps->push_back(SkOSPath::Join(FLAGS_skps[0], filename.c_str()));
         }
+    }
+}
 
-        const SkString path = SkOSPath::SkPathJoin(FLAGS_skps[0], filename.c_str());
-
-        SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path.c_str()));
+static void kick_off_skps(const SkTArray<SkString>& skps,
+                          DM::Reporter* reporter,
+                          DM::TaskRunner* tasks) {
+    for (int i = 0; i < skps.count(); ++i) {
+        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(skps[i].c_str()));
         if (stream.get() == NULL) {
-            SkDebugf("Could not read %s.\n", path.c_str());
+            SkDebugf("Could not read %s.\n", skps[i].c_str());
             exit(1);
         }
-        SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream.get()));
+        SkAutoTUnref<SkPicture> pic(
+                SkPicture::CreateFromStream(stream.get(), &sk_tools::LazyDecodeBitmap));
         if (pic.get() == NULL) {
-            SkDebugf("Could not read %s as an SkPicture.\n", path.c_str());
+            SkDebugf("Could not read %s as an SkPicture.\n", skps[i].c_str());
             exit(1);
         }
 
-        tasks->add(SkNEW_ARGS(DM::SKPTask, (reporter, tasks, pic->clone(), filename)));
-        tasks->add(SkNEW_ARGS(DM::PDFTask, (reporter, tasks, pic->clone(), filename,
-                                            RASTERIZE_PDF_PROC)));
+        SkString filename = SkOSPath::Basename(skps[i].c_str());
+        tasks->add(SkNEW_ARGS(DM::SKPTask, (reporter, tasks, pic, filename)));
+        tasks->add(SkNEW_ARGS(DM::PDFTask, (reporter, tasks, pic, filename, RASTERIZE_PDF_PROC)));
     }
 }
 
@@ -204,6 +163,16 @@
     SkDebugf("%d failures.\n", failures.count());
 }
 
+static GrGLStandard get_gl_standard() {
+  if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
+      return kGL_GrGLStandard;
+  }
+  if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
+      return kGLES_GrGLStandard;
+  }
+  return kNone_GrGLStandard;
+}
+
 template <typename T, typename Registry>
 static void append_matching_factories(Registry* head, SkTDArray<typename Registry::Factory>* out) {
     for (const Registry* reg = head; reg != NULL; reg = reg->next()) {
@@ -214,11 +183,11 @@
     }
 }
 
-int tool_main(int argc, char** argv);
-int tool_main(int argc, char** argv) {
+int dm_main();
+int dm_main() {
     SetupCrashHandler();
     SkAutoGraphics ag;
-    SkCommandLineFlags::Parse(argc, argv);
+    SkTaskGroup::Enabler enabled(FLAGS_threads);
 
     if (FLAGS_dryRun) {
         FLAGS_verbose = true;
@@ -232,24 +201,11 @@
         SkStrSplit(FLAGS_config[i], ", ", &configs);
     }
 
+    GrGLStandard gpuAPI = get_gl_standard();
+
     SkTDArray<GMRegistry::Factory> gms;
-    SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::NoExpectations));
     if (FLAGS_gms) {
         append_matching_factories<GM>(GMRegistry::Head(), &gms);
-
-        if (FLAGS_expectations.count() > 0) {
-            const char* path = FLAGS_expectations[0];
-            if (sk_isdir(path)) {
-                expectations.reset(SkNEW_ARGS(DM::WriteTask::Expectations, (path)));
-            } else {
-                expectations.reset(SkNEW_ARGS(DM::JsonExpectations, (path)));
-            }
-        }
-    }
-
-    SkTDArray<BenchRegistry::Factory> benches;
-    if (FLAGS_benches) {
-        append_matching_factories<Benchmark>(BenchRegistry::Head(), &benches);
     }
 
     SkTDArray<TestRegistry::Factory> tests;
@@ -257,17 +213,27 @@
         append_matching_factories<Test>(TestRegistry::Head(), &tests);
     }
 
-    SkDebugf("(%d GMs, %d benches) x %d configs, %d tests\n",
-             gms.count(), benches.count(), configs.count(), tests.count());
+    SkTArray<SkString> skps;
+    find_skps(&skps);
+
+    SkDebugf("%d GMs x %d configs, %d tests, %d pictures\n",
+             gms.count(), configs.count(), tests.count(), skps.count());
     DM::Reporter reporter;
-    DM::TaskRunner tasks(FLAGS_threads, FLAGS_gpuThreads);
-    kick_off_gms(gms, configs, *expectations, &reporter, &tasks);
-    kick_off_benches(benches, configs, &reporter, &tasks);
+
+    DM::TaskRunner tasks;
     kick_off_tests(tests, &reporter, &tasks);
-    kick_off_skps(&reporter, &tasks);
+    kick_off_gms(gms, configs, gpuAPI, &reporter, &tasks);
+    kick_off_skps(skps, &reporter, &tasks);
     tasks.wait();
 
+    DM::WriteTask::DumpJson();
+
     SkDebugf("\n");
+#ifdef SK_DEBUG
+    if (FLAGS_portableFonts && FLAGS_reportUsedChars) {
+        sk_tool_utils::report_used_chars();
+    }
+#endif
 
     SkTArray<SkString> failures;
     reporter.getFailures(&failures);
@@ -277,6 +243,7 @@
 
 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
 int main(int argc, char** argv) {
-    return tool_main(argc, argv);
+    SkCommandLineFlags::Parse(argc, argv);
+    return dm_main();
 }
 #endif
diff --git a/dm/DMBenchTask.cpp b/dm/DMBenchTask.cpp
deleted file mode 100644
index 7cd2fdc..0000000
--- a/dm/DMBenchTask.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "DMBenchTask.h"
-#include "DMUtil.h"
-#include "SkSurface.h"
-
-namespace DM {
-
-static SkString bench_name(const char* name, const char* config) {
-    SkString result("bench ");
-    result.appendf("%s_%s", name, config);
-    return result;
-}
-
-NonRenderingBenchTask::NonRenderingBenchTask(const char* config,
-                                             Reporter* reporter,
-                                             TaskRunner* tasks,
-                                             BenchRegistry::Factory factory)
-    : CpuTask(reporter, tasks)
-    , fBench(factory(NULL))
-    , fName(bench_name(fBench->getName(), config)) {}
-
-CpuBenchTask::CpuBenchTask(const char* config,
-                           Reporter* reporter,
-                           TaskRunner* tasks,
-                           BenchRegistry::Factory factory,
-                           SkColorType colorType)
-    : CpuTask(reporter, tasks)
-    , fBench(factory(NULL))
-    , fName(bench_name(fBench->getName(), config))
-    , fColorType(colorType) {}
-
-GpuBenchTask::GpuBenchTask(const char* config,
-                           Reporter* reporter,
-                           TaskRunner* tasks,
-                           BenchRegistry::Factory factory,
-                           GrContextFactory::GLContextType contextType,
-                           int sampleCount)
-    : GpuTask(reporter, tasks)
-    , fBench(factory(NULL))
-    , fName(bench_name(fBench->getName(), config))
-    , fContextType(contextType)
-    , fSampleCount(sampleCount) {}
-
-bool NonRenderingBenchTask::shouldSkip() const {
-    return !fBench->isSuitableFor(Benchmark::kNonRendering_Backend);
-}
-
-bool CpuBenchTask::shouldSkip() const {
-    return !fBench->isSuitableFor(Benchmark::kRaster_Backend);
-}
-
-bool GpuBenchTask::shouldSkip() const {
-    return kGPUDisabled || !fBench->isSuitableFor(Benchmark::kGPU_Backend);
-}
-
-static void draw_raster(Benchmark* bench, SkColorType colorType) {
-    SkBitmap bitmap;
-    AllocatePixels(colorType, bench->getSize().x(), bench->getSize().y(), &bitmap);
-    SkCanvas canvas(bitmap);
-
-    bench->preDraw();
-    bench->draw(1, &canvas);
-}
-
-void NonRenderingBenchTask::draw() {
-    draw_raster(fBench.get(), kN32_SkColorType);
-}
-
-void CpuBenchTask::draw() {
-    draw_raster(fBench.get(), fColorType);
-}
-
-void GpuBenchTask::draw(GrContextFactory* grFactory) {
-    SkImageInfo info = SkImageInfo::Make(fBench->getSize().x(),
-                                         fBench->getSize().y(),
-                                         kN32_SkColorType,
-                                         kPremul_SkAlphaType);
-    SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, info, fSampleCount));
-
-    fBench->preDraw();
-    fBench->draw(1, surface->getCanvas());
-}
-
-}  // namespace DM
diff --git a/dm/DMBenchTask.h b/dm/DMBenchTask.h
deleted file mode 100644
index 3c71cd7..0000000
--- a/dm/DMBenchTask.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef DMBenchTask_DEFINED
-#define DMBenchTask_DEFINED
-
-#include "Benchmark.h"
-#include "DMReporter.h"
-#include "DMTask.h"
-#include "DMTaskRunner.h"
-#include "SkString.h"
-#include "SkTemplates.h"
-
-// Tasks that run an Benchmark once as a check that it doesn't crash.
-
-namespace DM {
-
-class NonRenderingBenchTask : public CpuTask {
-public:
-    NonRenderingBenchTask(const char* config, Reporter*, TaskRunner*, BenchRegistry::Factory);
-
-    virtual void draw() SK_OVERRIDE;
-    virtual bool shouldSkip() const SK_OVERRIDE;
-    virtual SkString name() const SK_OVERRIDE { return fName; }
-
-private:
-    SkAutoTDelete<Benchmark> fBench;
-    const SkString fName;
-};
-
-class CpuBenchTask : public CpuTask {
-public:
-    CpuBenchTask(const char* config, Reporter*, TaskRunner*, BenchRegistry::Factory, SkColorType);
-
-    virtual void draw() SK_OVERRIDE;
-    virtual bool shouldSkip() const SK_OVERRIDE;
-    virtual SkString name() const SK_OVERRIDE { return fName; }
-
-private:
-    SkAutoTDelete<Benchmark> fBench;
-    const SkString fName;
-    const SkColorType fColorType;
-};
-
-class GpuBenchTask : public GpuTask {
-public:
-    GpuBenchTask(const char* config,
-                 Reporter*,
-                 TaskRunner*,
-                 BenchRegistry::Factory,
-                 GrContextFactory::GLContextType,
-                 int sampleCount);
-
-    virtual void draw(GrContextFactory*) SK_OVERRIDE;
-    virtual bool shouldSkip() const SK_OVERRIDE;
-    virtual SkString name() const SK_OVERRIDE { return fName; }
-
-private:
-    SkAutoTDelete<Benchmark> fBench;
-    const SkString fName;
-    const GrContextFactory::GLContextType fContextType;
-    int fSampleCount;
-};
-
-}  // namespace DM
-
-#endif // DMBenchTask_DEFINED
diff --git a/dm/DMCpuGMTask.cpp b/dm/DMCpuGMTask.cpp
index 8bec522..c3c4ae1 100644
--- a/dm/DMCpuGMTask.cpp
+++ b/dm/DMCpuGMTask.cpp
@@ -1,9 +1,6 @@
 #include "DMCpuGMTask.h"
-#include "DMExpectationsTask.h"
 #include "DMPipeTask.h"
 #include "DMQuiltTask.h"
-#include "DMRecordTask.h"
-#include "DMReplayTask.h"
 #include "DMSerializeTask.h"
 #include "DMUtil.h"
 #include "DMWriteTask.h"
@@ -14,39 +11,40 @@
                      Reporter* reporter,
                      TaskRunner* taskRunner,
                      skiagm::GMRegistry::Factory gmFactory,
-                     const Expectations& expectations,
                      SkColorType colorType)
     : CpuTask(reporter, taskRunner)
     , fGMFactory(gmFactory)
     , fGM(fGMFactory(NULL))
     , fName(UnderJoin(fGM->getName(), config))
-    , fExpectations(expectations)
     , fColorType(colorType)
     {}
 
 void CpuGMTask::draw() {
-    SkBitmap bitmap;
-    AllocatePixels(fColorType, fGM->getISize().width(), fGM->getISize().height(), &bitmap);
+    SkBitmap bm;
+    AllocatePixels(fColorType, fGM->getISize().width(), fGM->getISize().height(), &bm);
 
-    SkCanvas canvas(bitmap);
+    SkCanvas canvas(bm);
+    CanvasPreflight(&canvas);
     canvas.concat(fGM->getInitialTransform());
     fGM->draw(&canvas);
     canvas.flush();
 
 #define SPAWN(ChildTask, ...) this->spawnChild(SkNEW_ARGS(ChildTask, (*this, __VA_ARGS__)))
-    SPAWN(ExpectationsTask, fExpectations, bitmap);
+    SPAWN(PipeTask, fGMFactory(NULL), bm, PipeTask::kInProcess_Mode);
+    SPAWN(PipeTask, fGMFactory(NULL), bm, PipeTask::kCrossProcess_Mode);
+    SPAWN(PipeTask, fGMFactory(NULL), bm, PipeTask::kSharedAddress_Mode);
 
-    SPAWN(PipeTask, fGMFactory(NULL), bitmap, PipeTask::kInProcess_Mode);
-    SPAWN(PipeTask, fGMFactory(NULL), bitmap, PipeTask::kCrossProcess_Mode);
-    SPAWN(PipeTask, fGMFactory(NULL), bitmap, PipeTask::kSharedAddress_Mode);
-    SPAWN(QuiltTask, fGMFactory(NULL), bitmap);
-    SPAWN(RecordTask, fGMFactory(NULL), bitmap, RecordTask::kOptimize_Mode);
-    SPAWN(RecordTask, fGMFactory(NULL), bitmap, RecordTask::kNoOptimize_Mode);
-    SPAWN(ReplayTask, fGMFactory(NULL), bitmap, ReplayTask::kNormal_Mode);
-    SPAWN(ReplayTask, fGMFactory(NULL), bitmap, ReplayTask::kRTree_Mode);
-    SPAWN(SerializeTask, fGMFactory(NULL), bitmap);
+    SPAWN(QuiltTask, fGMFactory(NULL), bm, QuiltTask::kNone_BBH,     QuiltTask::kDefault_Backend);
+    SPAWN(QuiltTask, fGMFactory(NULL), bm, QuiltTask::kRTree_BBH,    QuiltTask::kDefault_Backend);
+    SPAWN(QuiltTask, fGMFactory(NULL), bm, QuiltTask::kTileGrid_BBH, QuiltTask::kDefault_Backend);
+    SPAWN(QuiltTask, fGMFactory(NULL), bm, QuiltTask::kNone_BBH,     QuiltTask::kSkRecord_Backend);
+    SPAWN(QuiltTask, fGMFactory(NULL), bm, QuiltTask::kRTree_BBH,    QuiltTask::kSkRecord_Backend);
+    SPAWN(QuiltTask, fGMFactory(NULL), bm, QuiltTask::kTileGrid_BBH, QuiltTask::kSkRecord_Backend);
 
-    SPAWN(WriteTask, bitmap);
+    SPAWN(SerializeTask, fGMFactory(NULL), bm, SerializeTask::kNormal_Mode);
+    SPAWN(SerializeTask, fGMFactory(NULL), bm, SerializeTask::kSkRecord_Mode);
+
+    SPAWN(WriteTask, "GM", bm);
 #undef SPAWN
 }
 
diff --git a/dm/DMCpuGMTask.h b/dm/DMCpuGMTask.h
index 968dd27..301cfd3 100644
--- a/dm/DMCpuGMTask.h
+++ b/dm/DMCpuGMTask.h
@@ -1,7 +1,6 @@
 #ifndef DMCpuGMTask_DEFINED
 #define DMCpuGMTask_DEFINED
 
-#include "DMExpectations.h"
 #include "DMReporter.h"
 #include "DMTask.h"
 #include "DMTaskRunner.h"
@@ -21,7 +20,6 @@
               Reporter*,
               TaskRunner*,
               skiagm::GMRegistry::Factory,
-              const Expectations&,
               SkColorType);
 
     virtual void draw() SK_OVERRIDE;
@@ -32,7 +30,6 @@
     skiagm::GMRegistry::Factory fGMFactory;
     SkAutoTDelete<skiagm::GM> fGM;
     const SkString fName;
-    const Expectations& fExpectations;
     const SkColorType fColorType;
 };
 
diff --git a/dm/DMExpectations.h b/dm/DMExpectations.h
deleted file mode 100644
index 238d1c5..0000000
--- a/dm/DMExpectations.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef DMExpectations_DEFINED
-#define DMExpectations_DEFINED
-
-#include "DMTask.h"
-#include "gm_expectations.h"
-
-namespace DM {
-
-struct Expectations {
-    virtual ~Expectations() {}
-
-    // Return true if bitmap is the correct output for task, else false.
-    virtual bool check(const Task& task, SkBitmap bitmap) const = 0;
-};
-
-class NoExpectations : public Expectations {
-public:
-    NoExpectations() {}
-    bool check(const Task&, SkBitmap) const SK_OVERRIDE { return true; }
-};
-
-class JsonExpectations : public Expectations {
-public:
-    explicit JsonExpectations(const char* path) : fGMExpectations(path) {}
-
-    bool check(const Task& task, SkBitmap bitmap) const SK_OVERRIDE {
-        SkString filename = task.name();
-        filename.append(".png");
-        const skiagm::Expectations expectations = fGMExpectations.get(filename.c_str());
-
-        if (expectations.ignoreFailure() || expectations.empty()) {
-            return true;
-        }
-
-        // Delay this calculation as long as possible.  It's expensive.
-        const skiagm::GmResultDigest digest(bitmap);
-        return expectations.match(digest);
-    }
-
-private:
-    skiagm::JsonExpectationsSource fGMExpectations;
-};
-
-}  // namespace DM
-
-#endif // DMExpectations_DEFINED
diff --git a/dm/DMExpectationsTask.cpp b/dm/DMExpectationsTask.cpp
deleted file mode 100644
index e29257a..0000000
--- a/dm/DMExpectationsTask.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "DMExpectationsTask.h"
-#include "DMUtil.h"
-
-namespace DM {
-
-ExpectationsTask::ExpectationsTask(const Task& parent,
-                                   const Expectations& expectations,
-                                   SkBitmap bitmap)
-    : CpuTask(parent)
-    , fName(parent.name())  // Masquerade as parent so failures are attributed to it.
-    , fExpectations(expectations)
-    , fBitmap(bitmap)
-    {}
-
-void ExpectationsTask::draw() {
-    if (!fExpectations.check(*this, fBitmap)) {
-        this->fail();
-    }
-}
-
-}  // namespace DM
diff --git a/dm/DMExpectationsTask.h b/dm/DMExpectationsTask.h
deleted file mode 100644
index 7000de4..0000000
--- a/dm/DMExpectationsTask.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef DMExpectationsTask_DEFINED
-#define DMExpectationsTask_DEFINED
-
-#include "DMExpectations.h"
-#include "DMTask.h"
-#include "SkBitmap.h"
-#include "SkString.h"
-
-namespace DM {
-
-// ExpectationsTask compares an SkBitmap against some Expectations.
-// Moving this off the GPU threadpool is a nice (~30%) runtime win.
-class ExpectationsTask : public CpuTask {
-public:
-    ExpectationsTask(const Task& parent, const Expectations&, SkBitmap);
-
-    virtual void draw() SK_OVERRIDE;
-    virtual bool shouldSkip() const SK_OVERRIDE { return false; }
-    virtual SkString name() const SK_OVERRIDE { return fName; }
-
-private:
-    const SkString fName;
-    const Expectations& fExpectations;
-    const SkBitmap fBitmap;
-};
-
-}  // namespace DM
-
-#endif  // DMExpectationsTask_DEFINED
diff --git a/dm/DMGpuGMTask.cpp b/dm/DMGpuGMTask.cpp
index b384485..65d65d9 100644
--- a/dm/DMGpuGMTask.cpp
+++ b/dm/DMGpuGMTask.cpp
@@ -1,6 +1,4 @@
 #include "DMGpuGMTask.h"
-
-#include "DMExpectationsTask.h"
 #include "DMUtil.h"
 #include "DMWriteTask.h"
 #include "SkCommandLineFlags.h"
@@ -13,14 +11,14 @@
                      Reporter* reporter,
                      TaskRunner* taskRunner,
                      skiagm::GMRegistry::Factory gmFactory,
-                     const Expectations& expectations,
                      GrContextFactory::GLContextType contextType,
+                     GrGLStandard gpuAPI,
                      int sampleCount)
     : GpuTask(reporter, taskRunner)
     , fGM(gmFactory(NULL))
     , fName(UnderJoin(fGM->getName(), config))
-    , fExpectations(expectations)
     , fContextType(contextType)
+    , fGpuAPI(gpuAPI)
     , fSampleCount(sampleCount)
     {}
 
@@ -29,8 +27,14 @@
                                          SkScalarCeilToInt(fGM->height()),
                                          kN32_SkColorType,
                                          kPremul_SkAlphaType);
-    SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, info, fSampleCount));
+    SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, fGpuAPI, info,
+                                                  fSampleCount));
+    if (!surface) {
+        this->fail("Could not create context for the config and the api.");
+        return;
+    }
     SkCanvas* canvas = surface->getCanvas();
+    CanvasPreflight(canvas);
 
     canvas->concat(fGM->getInitialTransform());
     fGM->draw(canvas);
@@ -40,8 +44,7 @@
     bitmap.setInfo(info);
     canvas->readPixels(&bitmap, 0, 0);
 
-    this->spawnChild(SkNEW_ARGS(ExpectationsTask, (*this, fExpectations, bitmap)));
-    this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
+    this->spawnChild(SkNEW_ARGS(WriteTask, (*this, "GM", bitmap)));
 }
 
 bool GpuGMTask::shouldSkip() const {
diff --git a/dm/DMGpuGMTask.h b/dm/DMGpuGMTask.h
index 6621a49..23f3a45 100644
--- a/dm/DMGpuGMTask.h
+++ b/dm/DMGpuGMTask.h
@@ -1,7 +1,6 @@
 #ifndef DMGpuGMTask_DEFINED
 #define DMGpuGMTask_DEFINED
 
-#include "DMExpectations.h"
 #include "DMGpuSupport.h"
 #include "DMReporter.h"
 #include "DMTask.h"
@@ -21,8 +20,8 @@
               Reporter*,
               TaskRunner*,
               skiagm::GMRegistry::Factory,
-              const Expectations&,
               GrContextFactory::GLContextType,
+              GrGLStandard gpuAPI,
               int sampleCount);
 
     virtual void draw(GrContextFactory*) SK_OVERRIDE;
@@ -32,8 +31,8 @@
 private:
     SkAutoTDelete<skiagm::GM> fGM;
     const SkString fName;
-    const Expectations& fExpectations;
     const GrContextFactory::GLContextType fContextType;
+    GrGLStandard fGpuAPI;
     const int fSampleCount;
 };
 
diff --git a/dm/DMGpuSupport.h b/dm/DMGpuSupport.h
index 46896b4..af6270d 100644
--- a/dm/DMGpuSupport.h
+++ b/dm/DMGpuSupport.h
@@ -19,9 +19,10 @@
 
 static inline SkSurface* NewGpuSurface(GrContextFactory* grFactory,
                                        GrContextFactory::GLContextType type,
+                                       GrGLStandard gpuAPI,
                                        SkImageInfo info,
                                        int samples) {
-    return SkSurface::NewRenderTarget(grFactory->get(type), info, samples);
+    return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI), info, samples, NULL);
 }
 
 }  // namespace DM
@@ -30,6 +31,12 @@
 
 // Ganesh is not available.  Fake it.
 
+enum GrGLStandard {
+    kNone_GrGLStandard,
+    kGL_GrGLStandard,
+    kGLES_GrGLStandard
+};
+
 class GrContextFactory {
 public:
     typedef int GLContextType;
@@ -40,6 +47,9 @@
                                kNVPR_GLContextType   = 0,
                                kNative_GLContextType = 0,
                                kNull_GLContextType   = 0;
+    void destroyContexts() {}
+
+    void abandonContexts() {}
 };
 
 namespace DM {
@@ -48,6 +58,7 @@
 
 static inline SkSurface* NewGpuSurface(GrContextFactory*,
                                        GrContextFactory::GLContextType,
+                                       GrGLStandard,
                                        SkImageInfo,
                                        int) {
     return NULL;
diff --git a/dm/DMPDFRasterizeTask.cpp b/dm/DMPDFRasterizeTask.cpp
index 43be6e5..d32178b 100644
--- a/dm/DMPDFRasterizeTask.cpp
+++ b/dm/DMPDFRasterizeTask.cpp
@@ -6,7 +6,6 @@
  */
 
 #include "DMPDFRasterizeTask.h"
-#include "DMExpectationsTask.h"
 #include "DMUtil.h"
 #include "DMWriteTask.h"
 #include "SkBitmap.h"
@@ -16,19 +15,21 @@
 namespace DM {
 
 PDFRasterizeTask::PDFRasterizeTask(const Task& parent,
-                                   SkData* pdf,
+                                   SkStreamAsset* pdf,
                                    RasterizePdfProc proc)
     : CpuTask(parent)
     , fName(UnderJoin(parent.name().c_str(), "rasterize"))
-    , fPdf(SkRef(pdf))
-    , fRasterize(proc) {}
+    , fPdf(pdf)
+    , fRasterize(proc) {
+    SkASSERT(fPdf.get());
+    SkASSERT(fPdf->unique());
+}
 
 void PDFRasterizeTask::draw() {
-    SkMemoryStream pdfStream(fPdf.get());
     SkBitmap bitmap;
 
-    if (fRasterize(&pdfStream, &bitmap)) {
-        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
+    if (fRasterize(fPdf.get(), &bitmap)) {
+        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, "PDF", bitmap)));
     } else {
         this->fail();
     }
diff --git a/dm/DMPDFRasterizeTask.h b/dm/DMPDFRasterizeTask.h
index 2cc1ef7..7231950 100644
--- a/dm/DMPDFRasterizeTask.h
+++ b/dm/DMPDFRasterizeTask.h
@@ -21,8 +21,9 @@
 
 class PDFRasterizeTask : public CpuTask {
 public:
+    // takes ownership of SkStreamAsset.
     PDFRasterizeTask(const Task& parent,
-                     SkData* pdf,
+                     SkStreamAsset* pdf,
                      RasterizePdfProc);
 
     virtual void draw() SK_OVERRIDE;
@@ -31,7 +32,7 @@
 
 private:
     const SkString fName;
-    SkAutoTUnref<SkData> fPdf;
+    SkAutoTDelete<SkStreamAsset> fPdf;
     RasterizePdfProc fRasterize;
 };
 
diff --git a/dm/DMPDFTask.cpp b/dm/DMPDFTask.cpp
index ecca130..3102478 100644
--- a/dm/DMPDFTask.cpp
+++ b/dm/DMPDFTask.cpp
@@ -32,7 +32,7 @@
 
 PDFTask::PDFTask(Reporter* reporter,
                  TaskRunner* taskRunner,
-                 SkPicture* picture,
+                 const SkPicture* picture,
                  SkString filename,
                  RasterizePdfProc rasterizePdfProc)
     : CpuTask(reporter, taskRunner)
@@ -50,11 +50,11 @@
 
     SkCanvas* canvas() { return fCanvas; }
 
-    SkData* end() {
+    SkStreamAsset* end() {
         fCanvas->flush();
         fDocument->endPage();
         fDocument->close();
-        return fWriteStream.copyToData();
+        return fWriteStream.detachAsStream();
     }
 
 private:
@@ -66,26 +66,31 @@
 }  // namespace
 
 void PDFTask::draw() {
-    SkAutoTUnref<SkData> pdfData;
+    SkAutoTDelete<SkStreamAsset> pdfData;
     bool rasterize = true;
     if (fGM.get()) {
         rasterize = 0 == (fGM->getFlags() & skiagm::GM::kSkipPDFRasterization_Flag);
         SinglePagePDF pdf(fGM->width(), fGM->height());
+        CanvasPreflight(pdf.canvas());
         //TODO(mtklein): GM doesn't do this.  Why not?
         //pdf.canvas()->concat(fGM->getInitialTransform());
         fGM->draw(pdf.canvas());
         pdfData.reset(pdf.end());
     } else {
-        SinglePagePDF pdf(SkIntToScalar(fPicture->width()), SkIntToScalar(fPicture->height()));
-        fPicture->draw(pdf.canvas());
+        SinglePagePDF pdf(fPicture->cullRect().width(), fPicture->cullRect().height());
+        CanvasPreflight(pdf.canvas());
+        fPicture->playback(pdf.canvas());
         pdfData.reset(pdf.end());
     }
 
     SkASSERT(pdfData.get());
     if (rasterize) {
-        this->spawnChild(SkNEW_ARGS(PDFRasterizeTask, (*this, pdfData.get(), fRasterize)));
+        this->spawnChild(SkNEW_ARGS(PDFRasterizeTask,
+                                    (*this, pdfData->duplicate(), fRasterize)));
     }
-    this->spawnChild(SkNEW_ARGS(WriteTask, (*this, pdfData.get(), ".pdf")));
+    const char* sourceType = fGM.get() ? "GM" : "SKP";
+    this->spawnChild(SkNEW_ARGS(WriteTask,
+                                (*this, sourceType, pdfData->duplicate(), ".pdf")));
 }
 
 bool PDFTask::shouldSkip() const {
diff --git a/dm/DMPDFTask.h b/dm/DMPDFTask.h
index d107611..72c0232 100644
--- a/dm/DMPDFTask.h
+++ b/dm/DMPDFTask.h
@@ -1,7 +1,6 @@
 #ifndef DMPDFTask_DEFINED
 #define DMPDFTask_DEFINED
 
-#include "DMExpectations.h"
 #include "DMPDFRasterizeTask.h"
 #include "DMTask.h"
 #include "SkBitmap.h"
@@ -24,7 +23,7 @@
 
     PDFTask(Reporter*,
             TaskRunner*,
-            SkPicture*,
+            const SkPicture*,
             SkString name,
             RasterizePdfProc);
 
@@ -37,7 +36,7 @@
 private:
     // One of these two will be set.
     SkAutoTDelete<skiagm::GM> fGM;
-    SkAutoTUnref<SkPicture> fPicture;
+    SkAutoTUnref<const SkPicture> fPicture;
 
     const SkString fName;
     RasterizePdfProc fRasterize;
diff --git a/dm/DMPipeTask.cpp b/dm/DMPipeTask.cpp
index 22404ec..383b51a 100644
--- a/dm/DMPipeTask.cpp
+++ b/dm/DMPipeTask.cpp
@@ -24,9 +24,9 @@
 static const char* get_name(const uint32_t flags) {
     if (flags & SkGPipeWriter::kCrossProcess_Flag &&
         flags & SkGPipeWriter::kSharedAddressSpace_Flag) {
-        return "shared_address_space_pipe";
+        return "shared-address-space-pipe";
     } else if (flags & SkGPipeWriter::kCrossProcess_Flag) {
-        return "cross_process_pipe";
+        return "cross-process-pipe";
     } else {
         return "pipe";
     }
@@ -55,13 +55,14 @@
                                                  fFlags,
                                                  bitmap.width(),
                                                  bitmap.height());
+    CanvasPreflight(pipeCanvas);
     pipeCanvas->concat(fGM->getInitialTransform());
     fGM->draw(pipeCanvas);
     writer.endRecording();
 
     if (!BitmapsEqual(bitmap, fReference)) {
         this->fail();
-        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
+        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, "GM", bitmap)));
     }
 }
 
diff --git a/dm/DMQuiltTask.cpp b/dm/DMQuiltTask.cpp
index f184980..9898dda 100644
--- a/dm/DMQuiltTask.cpp
+++ b/dm/DMQuiltTask.cpp
@@ -2,17 +2,28 @@
 #include "DMUtil.h"
 #include "DMWriteTask.h"
 
+#include "SkBBHFactory.h"
 #include "SkCommandLineFlags.h"
 #include "SkPicture.h"
+#include "SkTaskGroup.h"
 
-DEFINE_bool(quilt, true, "If true, draw into a quilt of small tiles and compare.");
-DEFINE_int32(quiltTile, 16, "Dimension of (square) quilt tile.");
+DEFINE_bool(quilt, true, "If true, draw GM via a picture into a quilt of small tiles and compare.");
+DEFINE_int32(quiltTile, 256, "Dimension of (square) quilt tile.");
 
 namespace DM {
 
-QuiltTask::QuiltTask(const Task& parent, skiagm::GM* gm, SkBitmap reference)
+static SkString suffix(QuiltTask::Backend backend, QuiltTask::BBH bbh) {
+    static const char* kBackends[] = { "default", "skrecord" };
+    static const char* kBBHs[]     = { "nobbh", "rtree", "tilegrid" };
+    return SkStringPrintf("%s-%s", kBackends[backend], kBBHs[bbh]);
+}
+
+QuiltTask::QuiltTask(const Task& parent, skiagm::GM* gm, SkBitmap reference,
+                     QuiltTask::BBH bbh, QuiltTask::Backend backend)
     : CpuTask(parent)
-    , fName(UnderJoin(parent.name().c_str(), "quilt"))
+    , fBBH(bbh)
+    , fBackend(backend)
+    , fName(UnderJoin(parent.name().c_str(), suffix(backend, bbh).c_str()))
     , fGM(gm)
     , fReference(reference)
     {}
@@ -21,37 +32,82 @@
     return (fullDimension + tileDimension - 1) / tileDimension;
 }
 
+class Tile : public SkRunnable {
+public:
+    Tile(int x, int y, const SkPicture& picture, SkBitmap* quilt)
+        : fX(x * FLAGS_quiltTile)
+        , fY(y * FLAGS_quiltTile)
+        , fPicture(picture)
+        , fQuilt(quilt) {}
+
+    virtual void run() SK_OVERRIDE {
+        SkBitmap tile;
+        fQuilt->extractSubset(&tile, SkIRect::MakeXYWH(fX, fY, FLAGS_quiltTile, FLAGS_quiltTile));
+        SkCanvas tileCanvas(tile);
+
+        tileCanvas.translate(SkIntToScalar(-fX), SkIntToScalar(-fY));
+        fPicture.playback(&tileCanvas);
+        tileCanvas.flush();
+
+        delete this;
+    }
+
+private:
+    const int fX, fY;
+    const SkPicture& fPicture;
+    SkBitmap* fQuilt;
+};
+
 void QuiltTask::draw() {
-    SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get()));
+    SkAutoTDelete<SkBBHFactory> factory;
+    switch (fBBH) {
+        case kNone_BBH: break;
+        case kRTree_BBH:
+            factory.reset(SkNEW(SkRTreeFactory));
+            break;
+        case kTileGrid_BBH: {
+            const SkTileGridFactory::TileGridInfo tiles = {
+                { FLAGS_quiltTile, FLAGS_quiltTile },
+                /*overlap: */{0, 0},
+                /*offset:  */{0, 0},
+            };
+            factory.reset(SkNEW_ARGS(SkTileGridFactory, (tiles)));
+            break;
+        }
+    }
+
+    // A couple GMs draw wrong when using a bounding box hierarchy.
+    // This almost certainly means we have a bug to fix, but for now
+    // just draw without a bounding box hierarchy.
+    if (fGM->getFlags() & skiagm::GM::kNoBBH_Flag) {
+        factory.reset(NULL);
+    }
+
+    SkAutoTUnref<const SkPicture> recorded(
+            RecordPicture(fGM.get(), factory.get(), kSkRecord_Backend == fBackend));
 
     SkBitmap full;
     AllocatePixels(fReference, &full);
-    SkCanvas fullCanvas(full);
 
-    SkBitmap tile;
-    tile.allocPixels(SkImageInfo::Make(FLAGS_quiltTile, FLAGS_quiltTile,
-                                       fReference.colorType(), kPremul_SkAlphaType));
-    SkCanvas tileCanvas(tile);
-
-    for (int y = 0; y < tiles_needed(full.height(), tile.height()); y++) {
-        for (int x = 0; x < tiles_needed(full.width(), tile.width()); x++) {
-            SkAutoCanvasRestore ar(&tileCanvas, true/*also save now*/);
-
-            const SkScalar xOffset = SkIntToScalar(x * tile.width()),
-                           yOffset = SkIntToScalar(y * tile.height());
-            SkMatrix matrix = tileCanvas.getTotalMatrix();
-            matrix.postTranslate(-xOffset, -yOffset);
-            tileCanvas.setMatrix(matrix);
-
-            recorded->draw(&tileCanvas);
-            tileCanvas.flush();
-            fullCanvas.drawBitmap(tile, xOffset, yOffset, NULL);
+    if (fGM->getFlags() & skiagm::GM::kSkipTiled_Flag) {
+        // Some GMs don't draw exactly the same when tiled.  Draw them in one go.
+        SkCanvas canvas(full);
+        recorded->playback(&canvas);
+        canvas.flush();
+    } else {
+        // Draw tiles in parallel into the same bitmap, simulating aggressive impl-side painting.
+        SkTaskGroup tg;
+        for (int y = 0; y < tiles_needed(full.height(), FLAGS_quiltTile); y++) {
+            for (int x = 0; x < tiles_needed(full.width(), FLAGS_quiltTile); x++) {
+                // Deletes itself when done.
+                tg.add(new Tile(x, y, *recorded, &full));
+            }
         }
     }
 
     if (!BitmapsEqual(full, fReference)) {
         this->fail();
-        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, full)));
+        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, "GM", full)));
     }
 }
 
@@ -59,9 +115,6 @@
     if (fGM->getFlags() & skiagm::GM::kSkipPicture_Flag) {
         return true;
     }
-    if (fGM->getFlags() & skiagm::GM::kSkipTiled_Flag) {
-        return true;
-    }
     return !FLAGS_quilt;
 }
 
diff --git a/dm/DMQuiltTask.h b/dm/DMQuiltTask.h
index 56f322f..0b49d12 100644
--- a/dm/DMQuiltTask.h
+++ b/dm/DMQuiltTask.h
@@ -12,17 +12,29 @@
 namespace DM {
 
 class QuiltTask : public CpuTask {
-
 public:
-    QuiltTask(const Task& parent,   // QuiltTask must be a child task.  Pass its parent here.
-                skiagm::GM*,          // GM to run through a picture.  Takes ownership.
-                SkBitmap reference);  // Bitmap to compare picture replay results to.
+    enum BBH {
+        kNone_BBH,
+        kRTree_BBH,
+        kTileGrid_BBH,
+    };
+    enum Backend {
+        kDefault_Backend,
+        kSkRecord_Backend,
+    };
+
+    QuiltTask(const Task& parent,  // QuiltTask must be a child task.  Pass its parent here.
+              skiagm::GM*,         // GM to run through a picture.  Takes ownership.
+              SkBitmap reference,  // Bitmap to compare picture replay results to.
+              BBH, Backend);
 
     virtual void draw() SK_OVERRIDE;
     virtual bool shouldSkip() const SK_OVERRIDE;
     virtual SkString name() const SK_OVERRIDE { return fName; }
 
 private:
+    const BBH fBBH;
+    const Backend fBackend;
     const SkString fName;
     SkAutoTDelete<skiagm::GM> fGM;
     const SkBitmap fReference;
diff --git a/dm/DMRecordTask.cpp b/dm/DMRecordTask.cpp
deleted file mode 100644
index 28633f2..0000000
--- a/dm/DMRecordTask.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#include "DMRecordTask.h"
-#include "DMUtil.h"
-#include "DMWriteTask.h"
-#include "SkCommandLineFlags.h"
-#include "SkRecord.h"
-#include "SkRecordDraw.h"
-#include "SkRecordOpts.h"
-#include "SkRecorder.h"
-
-DEFINE_bool(skr, true, "If true, run SKR tests.");
-
-namespace DM {
-
-RecordTask::RecordTask(const Task& parent, skiagm::GM* gm, SkBitmap reference, Mode mode)
-    : CpuTask(parent)
-    , fOptimize(mode == kOptimize_Mode)
-    , fName(UnderJoin(parent.name().c_str(), fOptimize ? "skr" : "skr-noopt"))
-    , fGM(gm)
-    , fReference(reference)
-    {}
-
-RecordTask::RecordTask(const Task& parent, SkPicture* pic, SkBitmap reference, Mode mode)
-    : CpuTask(parent)
-    , fOptimize(mode == kOptimize_Mode)
-    , fName(UnderJoin(parent.name().c_str(), fOptimize ? "skr" : "skr-noopt"))
-    , fPicture(SkRef(pic))
-    , fReference(reference)
-    {}
-
-void RecordTask::draw() {
-    // Record into an SkRecord.
-    SkRecord record;
-    SkRecorder recorder(&record, fReference.width(), fReference.height());
-
-    if (fGM.get()) {
-        recorder.concat(fGM->getInitialTransform());
-        fGM->draw(&recorder);
-    } else {
-        fPicture->draw(&recorder);
-    }
-
-
-    if (fOptimize) {
-        SkRecordOptimize(&record);
-    }
-
-    // Draw the SkRecord back into a bitmap.
-    SkBitmap bitmap;
-    AllocatePixels(fReference, &bitmap);
-    SkCanvas target(bitmap);
-    SkRecordDraw(record, &target);
-
-    if (!BitmapsEqual(bitmap, fReference)) {
-        this->fail();
-        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
-    }
-}
-
-bool RecordTask::shouldSkip() const {
-    return !FLAGS_skr;
-}
-
-}  // namespace DM
diff --git a/dm/DMRecordTask.h b/dm/DMRecordTask.h
deleted file mode 100644
index 1420724..0000000
--- a/dm/DMRecordTask.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef DMRecordTask_DEFINED
-#define DMRecordTask_DEFINED
-
-#include "DMTask.h"
-#include "SkBitmap.h"
-#include "SkPicture.h"
-#include "SkString.h"
-#include "SkTemplates.h"
-#include "gm.h"
-
-// Records a GM or SKP through an SkRecord, draws it, and compares against the reference bitmap.
-
-namespace DM {
-
-class RecordTask : public CpuTask {
-
-public:
-    enum Mode {
-        kNoOptimize_Mode,
-        kOptimize_Mode,
-    };
-    RecordTask(const Task& parent, skiagm::GM*, SkBitmap reference, Mode);
-    RecordTask(const Task& parent, SkPicture*,  SkBitmap reference, Mode);
-
-    virtual void draw() SK_OVERRIDE;
-    virtual bool shouldSkip() const SK_OVERRIDE;
-    virtual SkString name() const SK_OVERRIDE { return fName; }
-
-private:
-    bool fOptimize;
-    const SkString fName;
-    SkAutoTUnref<SkPicture> fPicture;
-    SkAutoTDelete<skiagm::GM> fGM;
-    const SkBitmap fReference;
-};
-
-}  // namespace DM
-
-#endif  // DMRecordTask_DEFINED
diff --git a/dm/DMReplayTask.cpp b/dm/DMReplayTask.cpp
deleted file mode 100644
index 8683879..0000000
--- a/dm/DMReplayTask.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "DMReplayTask.h"
-#include "DMWriteTask.h"
-#include "DMUtil.h"
-
-#include "SkBBHFactory.h"
-#include "SkCommandLineFlags.h"
-#include "SkPicture.h"
-
-DEFINE_bool(replay, true, "If true, run picture replay tests.");
-DEFINE_bool(rtree,  true, "If true, run picture replay tests with an rtree.");
-
-namespace DM {
-
-ReplayTask::ReplayTask(const Task& parent,
-                       skiagm::GM* gm,
-                       SkBitmap reference,
-                       Mode mode)
-    : CpuTask(parent)
-    , fUseRTree(mode == kRTree_Mode)
-    , fName(UnderJoin(parent.name().c_str(), fUseRTree ? "rtree" : "replay"))
-    , fGM(gm)
-    , fReference(reference)
-    {}
-
-void ReplayTask::draw() {
-    SkAutoTDelete<SkBBHFactory> factory;
-    if (fUseRTree) {
-        factory.reset(SkNEW(SkRTreeFactory));
-    }
-    SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get(), 0, factory.get()));
-
-    SkBitmap bitmap;
-    AllocatePixels(fReference, &bitmap);
-    DrawPicture(recorded, &bitmap);
-    if (!BitmapsEqual(bitmap, fReference)) {
-        this->fail();
-        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
-    }
-}
-
-bool ReplayTask::shouldSkip() const {
-    if (fGM->getFlags() & skiagm::GM::kSkipPicture_Flag) {
-        return true;
-    }
-
-    if (FLAGS_rtree && fUseRTree) {
-        return false;
-    }
-    if (FLAGS_replay && !fUseRTree) {
-        return false;
-    }
-    return true;
-}
-
-}  // namespace DM
diff --git a/dm/DMReplayTask.h b/dm/DMReplayTask.h
deleted file mode 100644
index de28172..0000000
--- a/dm/DMReplayTask.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef DMReplayTask_DEFINED
-#define DMReplayTask_DEFINED
-
-#include "DMTask.h"
-#include "SkBitmap.h"
-#include "SkString.h"
-#include "SkTemplates.h"
-#include "gm.h"
-
-// Records a GM through an SkPicture, draws it, and compares against the reference bitmap.
-
-namespace DM {
-
-class ReplayTask : public CpuTask {
-
-public:
-    enum Mode {
-        kNormal_Mode,
-        kRTree_Mode,
-    };
-    ReplayTask(const Task& parent,  // ReplayTask must be a child task.  Pass its parent here.
-               skiagm::GM*,         // GM to run through a picture.  Takes ownership.
-               SkBitmap reference,  // Bitmap to compare picture replay results to.
-               Mode);
-
-    virtual void draw() SK_OVERRIDE;
-    virtual bool shouldSkip() const SK_OVERRIDE;
-    virtual SkString name() const SK_OVERRIDE { return fName; }
-
-private:
-    const bool fUseRTree;
-    const SkString fName;
-    SkAutoTDelete<skiagm::GM> fGM;
-    const SkBitmap fReference;
-};
-
-}  // namespace DM
-
-#endif  // DMReplayTask_DEFINED
diff --git a/dm/DMReporter.cpp b/dm/DMReporter.cpp
index 0bc77bd..7b2cea8 100644
--- a/dm/DMReporter.cpp
+++ b/dm/DMReporter.cpp
@@ -1,11 +1,9 @@
 #include "DMReporter.h"
 
 #include "SkDynamicAnnotations.h"
-#include "SkCommandLineFlags.h"
+#include "SkCommonFlags.h"
 #include "OverwriteLine.h"
-
-DEFINE_bool2(quiet, q, false, "If true, don't print status updates.");
-DEFINE_bool2(verbose, v, false, "If true, print status updates one-per-line.");
+#include "ProcStats.h"
 
 namespace DM {
 
@@ -24,7 +22,11 @@
         status.appendf(", %d failed", failed);
     }
     if (FLAGS_verbose) {
-        status.appendf("\t%5dms %s", timeMs, name.c_str());
+        int max_rss_mb = sk_tools::getMaxResidentSetSizeMB();
+        if (max_rss_mb >= 0) {
+            status.appendf("\t%4dM peak", max_rss_mb);
+        }
+        status.appendf("\t%5dms\t%s", timeMs, name.c_str());
     }
     SkDebugf("%s", status.c_str());
 }
diff --git a/dm/DMSKPTask.cpp b/dm/DMSKPTask.cpp
index 760138f..d633594 100644
--- a/dm/DMSKPTask.cpp
+++ b/dm/DMSKPTask.cpp
@@ -1,23 +1,31 @@
-#include "DMRecordTask.h"
 #include "DMSKPTask.h"
 #include "DMUtil.h"
 #include "DMWriteTask.h"
 
+#include "SkCommandLineFlags.h"
+#include "SkPictureRecorder.h"
+
+DEFINE_int32(skpMaxWidth,  1000, "Max SKPTask viewport width.");
+DEFINE_int32(skpMaxHeight, 1000, "Max SKPTask viewport height.");
+
 namespace DM {
 
-SKPTask::SKPTask(Reporter* r, TaskRunner* tr, SkPicture* pic, SkString filename)
-    : CpuTask(r, tr), fPicture(SkRef(pic)), fName(FileToTaskName(filename)) {}
+SKPTask::SKPTask(Reporter* r,
+                 TaskRunner* tr,
+                 const SkPicture* pic,
+                 SkString filename)
+    : CpuTask(r, tr)
+    , fPicture(SkRef(pic))
+    , fName(FileToTaskName(filename)) {}
 
 void SKPTask::draw() {
+    const int width  = SkTMin(SkScalarCeilToInt(fPicture->cullRect().width()),  FLAGS_skpMaxWidth),
+              height = SkTMin(SkScalarCeilToInt(fPicture->cullRect().height()), FLAGS_skpMaxHeight);
     SkBitmap bitmap;
-    AllocatePixels(kN32_SkColorType, fPicture->width(), fPicture->height(), &bitmap);
-    DrawPicture(fPicture, &bitmap);
+    AllocatePixels(kN32_SkColorType, width, height, &bitmap);
+    DrawPicture(*fPicture, &bitmap);
 
-    this->spawnChild(SkNEW_ARGS(RecordTask,
-                                (*this, fPicture, bitmap, RecordTask::kNoOptimize_Mode)));
-    this->spawnChild(SkNEW_ARGS(RecordTask,
-                                (*this, fPicture, bitmap, RecordTask::kOptimize_Mode)));
-    this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
+    this->spawnChild(SkNEW_ARGS(WriteTask, (*this, "SKP", bitmap)));
 }
 
 }  // namespace DM
diff --git a/dm/DMSKPTask.h b/dm/DMSKPTask.h
index ef465af..b8a288e 100644
--- a/dm/DMSKPTask.h
+++ b/dm/DMSKPTask.h
@@ -14,14 +14,14 @@
 
 class SKPTask : public CpuTask {
 public:
-    SKPTask(Reporter*, TaskRunner*, SkPicture*, SkString name);
+    SKPTask(Reporter*, TaskRunner*, const SkPicture*, SkString name);
 
     virtual void draw() SK_OVERRIDE;
     virtual bool shouldSkip() const SK_OVERRIDE { return false; }
     virtual SkString name() const SK_OVERRIDE { return fName; }
 
 private:
-    SkAutoTUnref<SkPicture> fPicture;
+    SkAutoTUnref<const SkPicture> fPicture;
     const SkString fName;
 };
 
diff --git a/dm/DMSerializeTask.cpp b/dm/DMSerializeTask.cpp
index 62c45b3..161836b 100644
--- a/dm/DMSerializeTask.cpp
+++ b/dm/DMSerializeTask.cpp
@@ -6,21 +6,28 @@
 #include "SkPicture.h"
 #include "SkPixelRef.h"
 
-DEFINE_bool(serialize, true, "If true, run picture serialization tests.");
+DEFINE_bool(serialize,     true, "If true, run picture serialization tests via SkPictureData.");
+DEFINE_bool(serialize_skr, true, "If true, run picture serialization tests via SkRecord.");
+
+static const char* kSuffixes[] = { "serialize", "serialize-skr" };
+static const bool* kEnabled[]  = { &FLAGS_serialize, &FLAGS_serialize_skr };
 
 namespace DM {
 
 SerializeTask::SerializeTask(const Task& parent,
                              skiagm::GM* gm,
-                             SkBitmap reference)
+                             SkBitmap reference,
+                             SerializeTask::Mode mode)
     : CpuTask(parent)
-    , fName(UnderJoin(parent.name().c_str(), "serialize"))
+    , fMode(mode)
+    , fName(UnderJoin(parent.name().c_str(), kSuffixes[mode]))
     , fGM(gm)
     , fReference(reference)
     {}
 
 void SerializeTask::draw() {
-    SkAutoTUnref<SkPicture> recorded(RecordPicture(fGM.get()));
+    SkAutoTUnref<SkPicture> recorded(
+        RecordPicture(fGM.get(), NULL/*no BBH*/, kSkRecord_Mode == fMode));
 
     SkDynamicMemoryWStream wStream;
     recorded->serialize(&wStream, NULL);
@@ -29,15 +36,18 @@
 
     SkBitmap bitmap;
     AllocatePixels(fReference, &bitmap);
-    DrawPicture(reconstructed, &bitmap);
+    DrawPicture(*reconstructed, &bitmap);
     if (!BitmapsEqual(bitmap, fReference)) {
         this->fail();
-        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
+        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, "GM", bitmap)));
     }
 }
 
 bool SerializeTask::shouldSkip() const {
-    return !FLAGS_serialize || fGM->getFlags() & skiagm::GM::kSkipPicture_Flag;
+    if (fGM->getFlags() & skiagm::GM::kSkipPicture_Flag) {
+        return true;
+    }
+    return !*kEnabled[fMode];
 }
 
 }  // namespace DM
diff --git a/dm/DMSerializeTask.h b/dm/DMSerializeTask.h
index 1f8b836..d06ebeb 100644
--- a/dm/DMSerializeTask.h
+++ b/dm/DMSerializeTask.h
@@ -14,15 +14,21 @@
 class SerializeTask : public CpuTask {
 
 public:
+    enum Mode {
+        kNormal_Mode,
+        kSkRecord_Mode,
+    };
     SerializeTask(const Task& parent,
                   skiagm::GM*,
-                  SkBitmap reference);
+                  SkBitmap reference,
+                  Mode mode);
 
     virtual void draw() SK_OVERRIDE;
     virtual bool shouldSkip() const SK_OVERRIDE;
     virtual SkString name() const SK_OVERRIDE { return fName; }
 
 private:
+    const Mode fMode;
     const SkString fName;
     SkAutoTDelete<skiagm::GM> fGM;
     const SkBitmap fReference;
diff --git a/dm/DMTask.cpp b/dm/DMTask.cpp
index 54e7df3..3fa5c39 100644
--- a/dm/DMTask.cpp
+++ b/dm/DMTask.cpp
@@ -1,11 +1,6 @@
 #include "DMTask.h"
 #include "DMTaskRunner.h"
-#include "SkCommandLineFlags.h"
-
-DEFINE_bool(cpu, true, "Master switch for running CPU-bound work.");
-DEFINE_bool(gpu, true, "Master switch for running GPU-bound work.");
-
-DECLARE_bool(dryRun);
+#include "SkCommonFlags.h"
 
 namespace DM {
 
@@ -43,15 +38,17 @@
     fReporter->printStatus(this->name(), SkTime::GetMSecs() - fStart);
 }
 
-void Task::spawnChildNext(CpuTask* task) {
-    fTaskRunner->addNext(task);
+void Task::reallySpawnChild(CpuTask* task) {
+    fTaskRunner->add(task);
 }
 
 CpuTask::CpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {}
 CpuTask::CpuTask(const Task& parent) : Task(parent) {}
 
 void CpuTask::run() {
-    if (FLAGS_cpu && !this->shouldSkip()) {
+    // If the task says skip, or if we're starting a top-level CPU task and we don't want to, skip.
+    const bool skip = this->shouldSkip() || (this->depth() == 0 && !FLAGS_cpu);
+    if (!skip) {
         this->start();
         if (!FLAGS_dryRun) this->draw();
         this->finish();
@@ -61,26 +58,34 @@
 
 void CpuTask::spawnChild(CpuTask* task) {
     // Run children serially on this (CPU) thread.  This tends to save RAM and is usually no slower.
-    // Calling spawnChildNext() is nearly equivalent, but it'd pointlessly contend on the
-    // threadpool; spawnChildNext() is most useful when you want to change threadpools.
+    // Calling reallySpawnChild() is nearly equivalent, but it'd pointlessly contend on the
+    // threadpool; reallySpawnChild() is most useful when you want to change threadpools.
     task->run();
 }
 
 GpuTask::GpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {}
 
-void GpuTask::run(GrContextFactory& factory) {
-    if (FLAGS_gpu && !this->shouldSkip()) {
+void GpuTask::run(GrContextFactory* factory) {
+    // If the task says skip, or if we're starting a top-level GPU task and we don't want to, skip.
+    const bool skip = this->shouldSkip() || (this->depth() == 0 && !FLAGS_gpu);
+    if (!skip) {
         this->start();
-        if (!FLAGS_dryRun) this->draw(&factory);
+        if (!FLAGS_dryRun) this->draw(factory);
         this->finish();
+        if (FLAGS_abandonGpuContext) {
+            factory->abandonContexts();
+        }
+        if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) {
+            factory->destroyContexts();
+        }
     }
     SkDELETE(this);
 }
 
 void GpuTask::spawnChild(CpuTask* task) {
-    // Really spawn a new task so it runs on the CPU threadpool instead of the GPU one we're on now.
+    // Spawn a new task so it runs on the CPU threadpool instead of the GPU one we're on now.
     // It goes on the front of the queue to minimize the time we must hold reference bitmaps in RAM.
-    this->spawnChildNext(task);
+    this->reallySpawnChild(task);
 }
 
 }  // namespace DM
diff --git a/dm/DMTask.h b/dm/DMTask.h
index 32bb948..3f41b49 100644
--- a/dm/DMTask.h
+++ b/dm/DMTask.h
@@ -1,9 +1,10 @@
 #ifndef DMTask_DEFINED
 #define DMTask_DEFINED
 
-#include "DMReporter.h"
 #include "DMGpuSupport.h"
+#include "DMReporter.h"
 #include "SkRunnable.h"
+#include "SkTaskGroup.h"
 #include "SkTime.h"
 
 // DM will run() these tasks on one of two threadpools.
@@ -36,7 +37,7 @@
     void fail(const char* msg = NULL);
     void finish();
 
-    void spawnChildNext(CpuTask* task);  // For now we don't allow GPU child tasks.
+    void reallySpawnChild(CpuTask* task);  // For now we don't allow GPU child tasks.
 
 private:
     Reporter* fReporter;      // Unowned.
@@ -57,12 +58,12 @@
     void spawnChild(CpuTask* task);
 };
 
-class GpuTask : public Task, public SkTRunnable<GrContextFactory> {
+class GpuTask : public Task {
  public:
     GpuTask(Reporter* reporter, TaskRunner* taskRunner);
     virtual ~GpuTask() {}
 
-    void run(GrContextFactory&) SK_OVERRIDE;
+    void run(GrContextFactory*);
     virtual void draw(GrContextFactory*) = 0;
 
     void spawnChild(CpuTask* task);
diff --git a/dm/DMTaskRunner.cpp b/dm/DMTaskRunner.cpp
index 8a0bc83..92381a7 100644
--- a/dm/DMTaskRunner.cpp
+++ b/dm/DMTaskRunner.cpp
@@ -3,19 +3,15 @@
 
 namespace DM {
 
-TaskRunner::TaskRunner(int cpuThreads, int gpuThreads) : fCpu(cpuThreads), fGpu(gpuThreads) {}
-
-void TaskRunner::add(CpuTask* task) { fCpu.add(task); }
-void TaskRunner::addNext(CpuTask* task) { fCpu.addNext(task); }
-void TaskRunner::add(GpuTask* task) { fGpu.add(task); }
+void TaskRunner::add(CpuTask* task) { fCpuWork.add(task);  }
+void TaskRunner::add(GpuTask* task) { fGpuWork.push(task); }
 
 void TaskRunner::wait() {
-    // These wait calls block until each threadpool is done.  We don't allow
-    // spawning new child GPU tasks, so we can wait for that first knowing
-    // we'll never try to add to it later.  Same can't be said of the CPU pool:
-    // both CPU and GPU tasks can spawn off new CPU work, so we wait for that last.
-    fGpu.wait();
-    fCpu.wait();
+    GrContextFactory factory;
+    for (int i = 0; i < fGpuWork.count(); i++) {
+        fGpuWork[i]->run(&factory);
+    }
+    fCpuWork.wait();
 }
 
 }  // namespace DM
diff --git a/dm/DMTaskRunner.h b/dm/DMTaskRunner.h
index dd1440e..3d4e491 100644
--- a/dm/DMTaskRunner.h
+++ b/dm/DMTaskRunner.h
@@ -2,12 +2,10 @@
 #define DMTaskRunner_DEFINED
 
 #include "DMGpuSupport.h"
-#include "SkThreadPool.h"
+#include "SkTDArray.h"
+#include "SkTaskGroup.h"
 #include "SkTypes.h"
 
-// TaskRunner runs Tasks on one of two threadpools depending on the need for a GrContextFactory.
-// It's typically a good idea to run fewer GPU threads than CPU threads (go nuts with those).
-
 namespace DM {
 
 class CpuTask;
@@ -15,16 +13,15 @@
 
 class TaskRunner : SkNoncopyable {
 public:
-    explicit TaskRunner(int cpuThreads, int gpuThreads);
+    TaskRunner() {}
 
     void add(CpuTask* task);
-    void addNext(CpuTask* task);
     void add(GpuTask* task);
     void wait();
 
 private:
-    SkTThreadPool<void> fCpu;
-    SkTThreadPool<GrContextFactory> fGpu;
+    SkTaskGroup fCpuWork;
+    SkTDArray<GpuTask*> fGpuWork;
 };
 
 }  // namespace DM
diff --git a/dm/DMTestTask.cpp b/dm/DMTestTask.cpp
index f99abd0..ad0c3fb 100644
--- a/dm/DMTestTask.cpp
+++ b/dm/DMTestTask.cpp
@@ -1,20 +1,14 @@
 #include "DMTestTask.h"
 #include "DMUtil.h"
 #include "SkCommandLineFlags.h"
+#include "SkCommonFlags.h"
 
-// When PathOps threaded tests get going, they're briefly a big consumer of lots of RAM.
-// We disable the internal threading there by default on 32-bit builds.
-static const bool is32Bit = sizeof(void*) == 4;
-
-DEFINE_bool2(pathOpsExtended,     x, false, "Run extended pathOps tests.");
-DEFINE_bool2(pathOpsSingleThread, z, is32Bit, "Disallow pathOps tests from using threads.");
-DEFINE_bool2(pathOpsVerbose,      V, false, "Tell pathOps tests to be verbose.");
+DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests.");
 
 namespace DM {
 
 bool TestReporter::allowExtendedTest() const { return FLAGS_pathOpsExtended; }
-bool TestReporter::allowThreaded()     const { return !FLAGS_pathOpsSingleThread; }
-bool TestReporter::verbose()           const { return FLAGS_pathOpsVerbose; }
+bool TestReporter::verbose()           const { return FLAGS_veryVerbose; }
 
 static SkString test_name(const char* name) {
     SkString result("test ");
diff --git a/dm/DMTestTask.h b/dm/DMTestTask.h
index a65f096..ceb0e12 100644
--- a/dm/DMTestTask.h
+++ b/dm/DMTestTask.h
@@ -19,7 +19,6 @@
 
 private:
   virtual bool allowExtendedTest() const SK_OVERRIDE;
-  virtual bool allowThreaded()     const SK_OVERRIDE;
   virtual bool verbose()           const SK_OVERRIDE;
 
   virtual void onReportFailed(const SkString& desc) SK_OVERRIDE {
diff --git a/dm/DMUtil.cpp b/dm/DMUtil.cpp
index 94fdd6e..a702bbe 100644
--- a/dm/DMUtil.cpp
+++ b/dm/DMUtil.cpp
@@ -1,11 +1,25 @@
 #include "DMUtil.h"
 
 #include "SkColorPriv.h"
+#include "SkCommandLineFlags.h"
 #include "SkPicture.h"
 #include "SkPictureRecorder.h"
 
+DEFINE_string(matrix, "1 0 0 0 1 0 0 0 1",
+              "Matrix to apply to the canvas before drawing.");
+
 namespace DM {
 
+void CanvasPreflight(SkCanvas* canvas) {
+    if (FLAGS_matrix.count() == 9) {
+        SkMatrix m;
+        for (int i = 0; i < 9; i++) {
+            m[i] = (SkScalar)atof(FLAGS_matrix[i]);
+        }
+        canvas->concat(m);
+    }
+}
+
 SkString UnderJoin(const char* a, const char* b) {
     SkString s;
     s.appendf("%s_%s", a, b);
@@ -20,10 +34,14 @@
     return filename;
 }
 
-SkPicture* RecordPicture(skiagm::GM* gm, uint32_t recordFlags, SkBBHFactory* factory) {
-    const SkISize size = gm->getISize();
+SkPicture* RecordPicture(skiagm::GM* gm, SkBBHFactory* factory, bool skr) {
+    const SkScalar w = SkIntToScalar(gm->getISize().width()),
+                   h = SkIntToScalar(gm->getISize().height());
     SkPictureRecorder recorder;
-    SkCanvas* canvas = recorder.beginRecording(size.width(), size.height(), factory, recordFlags);
+
+    SkCanvas* canvas = skr ? recorder.EXPERIMENTAL_beginRecording(w, h, factory)
+                           : recorder.  DEPRECATED_beginRecording(w, h, factory);
+    CanvasPreflight(canvas);
     canvas->concat(gm->getInitialTransform());
     gm->draw(canvas);
     canvas->flush();
@@ -39,11 +57,10 @@
     AllocatePixels(reference.colorType(), reference.width(), reference.height(), bitmap);
 }
 
-void DrawPicture(SkPicture* picture, SkBitmap* bitmap) {
-    SkASSERT(picture != NULL);
+void DrawPicture(const SkPicture& picture, SkBitmap* bitmap) {
     SkASSERT(bitmap != NULL);
     SkCanvas canvas(*bitmap);
-    canvas.drawPicture(picture);
+    canvas.drawPicture(&picture);
     canvas.flush();
 }
 
diff --git a/dm/DMUtil.h b/dm/DMUtil.h
index b99fe0c..49da857 100644
--- a/dm/DMUtil.h
+++ b/dm/DMUtil.h
@@ -1,10 +1,10 @@
 #ifndef DMUtil_DEFINED
 #define DMUtil_DEFINED
 
-#include "Benchmark.h"
 #include "SkBitmap.h"
+#include "SkCanvas.h"
 #include "SkString.h"
-#include "gm_expectations.h"
+#include "gm.h"
 
 class SkBBHFactory;
 
@@ -18,10 +18,10 @@
 // "foo_bar.skp" -> "foo-bar_skp"
 SkString FileToTaskName(SkString);
 
-// Draw gm to picture.  Passes recordFlags to SkPictureRecorder::beginRecording().
+// Draw gm to picture.  If skr is true, uses EXPERIMENTAL_beginRecording().
 SkPicture* RecordPicture(skiagm::GM* gm,
-                         uint32_t recordFlags = 0,
-                         SkBBHFactory* factory = NULL);
+                         SkBBHFactory* factory = NULL,
+                         bool skr = false);
 
 // Allocate an empty bitmap with this size and depth.
 void AllocatePixels(SkColorType, int w, int h, SkBitmap* bitmap);
@@ -29,7 +29,7 @@
 void AllocatePixels(const SkBitmap& reference, SkBitmap* bitmap);
 
 // Draw picture to bitmap.
-void DrawPicture(SkPicture* picture, SkBitmap* bitmap);
+void DrawPicture(const SkPicture& picture, SkBitmap* bitmap);
 
 // What is the maximum component difference in these bitmaps?
 unsigned MaxComponentDifference(const SkBitmap& a, const SkBitmap& b);
@@ -37,6 +37,9 @@
 // Are these identical bitmaps?
 bool BitmapsEqual(const SkBitmap& a, const SkBitmap& b);
 
+// Hook to modify canvas using global flag values (e.g. --matrix).
+void CanvasPreflight(SkCanvas*);
+
 }  // namespace DM
 
 #endif  // DMUtil_DEFINED
diff --git a/dm/DMWriteTask.cpp b/dm/DMWriteTask.cpp
index 13f25d0..08feb98 100644
--- a/dm/DMWriteTask.cpp
+++ b/dm/DMWriteTask.cpp
@@ -2,15 +2,16 @@
 
 #include "DMUtil.h"
 #include "SkColorPriv.h"
-#include "SkCommandLineFlags.h"
+#include "SkCommonFlags.h"
+#include "SkData.h"
 #include "SkImageEncoder.h"
+#include "SkMD5.h"
 #include "SkMallocPixelRef.h"
+#include "SkOSFile.h"
 #include "SkStream.h"
 #include "SkString.h"
 
-DEFINE_string2(writePath, w, "", "If set, write GMs here as .pngs.");
-DEFINE_bool(writePngOnly, false, "If true, don't encode raw bitmap after .png data.  "
-                                 "This means -r won't work, but skdiff will still work fine.");
+DEFINE_bool(nameByHash, false, "If true, write .../hash.png instead of .../mode/config/name.png");
 
 namespace DM {
 
@@ -28,25 +29,34 @@
     return consumed;
 }
 
-inline static SkString find_gm_name(const Task& parent, SkTArray<SkString>* suffixList) {
+inline static SkString find_base_name(const Task& parent, SkTArray<SkString>* suffixList) {
     const int suffixes = parent.depth() + 1;
     const SkString& name = parent.name();
     const int totalSuffixLength = split_suffixes(suffixes, name.c_str(), suffixList);
     return SkString(name.c_str(), name.size() - totalSuffixLength);
 }
 
-WriteTask::WriteTask(const Task& parent, SkBitmap bitmap)
+WriteTask::WriteTask(const Task& parent, const char* sourceType, SkBitmap bitmap)
     : CpuTask(parent)
-    , fGmName(find_gm_name(parent, &fSuffixes))
+    , fBaseName(find_base_name(parent, &fSuffixes))
+    , fSourceType(sourceType)
     , fBitmap(bitmap)
     , fData(NULL)
-    , fExtension(".png") {}
+    , fExtension(".png") {
+}
 
-WriteTask::WriteTask(const Task& parent, SkData *data, const char* ext)
+WriteTask::WriteTask(const Task& parent,
+                     const char* sourceType,
+                     SkStreamAsset *data,
+                     const char* ext)
     : CpuTask(parent)
-    , fGmName(find_gm_name(parent, &fSuffixes))
-    , fData(SkRef(data))
-    , fExtension(ext) {}
+    , fBaseName(find_base_name(parent, &fSuffixes))
+    , fSourceType(sourceType)
+    , fData(data)
+    , fExtension(ext) {
+    SkASSERT(fData.get());
+    SkASSERT(fData->unique());
+}
 
 void WriteTask::makeDirOrFail(SkString dir) {
     if (!sk_mkdir(dir.c_str())) {
@@ -54,94 +64,90 @@
     }
 }
 
-namespace {
+static SkString get_md5(const void* ptr, size_t len) {
+    SkMD5 hasher;
+    hasher.write(ptr, len);
+    SkMD5::Digest digest;
+    hasher.finish(digest);
 
-// One file that first contains a .png of an SkBitmap, then its raw pixels.
-// We use this custom format to avoid premultiplied/unpremultiplied pixel conversions.
-struct PngAndRaw {
-    static bool Encode(SkBitmap bitmap, const char* path) {
-        SkFILEWStream stream(path);
-        if (!stream.isValid()) {
-            SkDebugf("Can't write %s.\n", path);
-            return false;
-        }
-
-        // Write a PNG first for humans and other tools to look at.
-        if (!SkImageEncoder::EncodeStream(&stream, bitmap, SkImageEncoder::kPNG_Type, 100)) {
-            SkDebugf("Can't encode a PNG.\n");
-            return false;
-        }
-        if (FLAGS_writePngOnly) {
-            return true;
-        }
-
-        // Pad out so the raw pixels start 4-byte aligned.
-        const uint32_t maxPadding = 0;
-        const size_t pos = stream.bytesWritten();
-        stream.write(&maxPadding, SkAlign4(pos) - pos);
-
-        // Then write our secret raw pixels that only DM reads.
-        SkAutoLockPixels lock(bitmap);
-        return stream.write(bitmap.getPixels(), bitmap.getSize());
+    SkString md5;
+    for (int i = 0; i < 16; i++) {
+        md5.appendf("%02x", digest.data[i]);
     }
-
-    // This assumes bitmap already has allocated pixels of the correct size.
-    static bool Decode(const char* path, SkImageInfo info, SkBitmap* bitmap) {
-        SkAutoTUnref<SkData> data(SkData::NewFromFileName(path));
-        if (!data) {
-            SkDebugf("Can't read %s.\n", path);
-            return false;
-        }
-
-        // The raw pixels are at the end of the file.  We'll skip the encoded PNG at the front.
-        const size_t rowBytes = info.minRowBytes();  // Assume densely packed.
-        const size_t bitmapBytes = info.getSafeSize(rowBytes);
-        if (data->size() < bitmapBytes) {
-            SkDebugf("%s is too small to contain the bitmap we're looking for.\n", path);
-            return false;
-        }
-
-        const size_t offset = data->size() - bitmapBytes;
-        SkAutoTUnref<SkData> subset(
-                SkData::NewSubset(data, offset, bitmapBytes));
-        SkAutoTUnref<SkPixelRef> pixels(
-            SkMallocPixelRef::NewWithData(
-                    info, rowBytes, NULL/*ctable*/, subset));
-        SkASSERT(pixels);
-
-        bitmap->setInfo(info, rowBytes);
-        bitmap->setPixelRef(pixels);
-        return true;
-    }
-};
-
-// Does not take ownership of data.
-bool save_data_to_file(const SkData* data, const char* path) {
-    SkFILEWStream stream(path);
-    if (!stream.isValid() || !stream.write(data->data(), data->size())) {
-        SkDebugf("Can't write %s.\n", path);
-        return false;
-    }
-    return true;
+    return md5;
 }
 
-}  // namespace
+struct JsonData {
+    SkString name;            // E.g. "ninepatch-stretch", "desk-gws_skp"
+    SkString config;          //      "gpu", "8888"
+    SkString mode;            //      "direct", "default-tilegrid", "pipe"
+    SkString sourceType;      //      "GM", "SKP"
+    SkString md5;             // In ASCII, so 32 bytes long.
+};
+SkTArray<JsonData> gJsonData;
+SK_DECLARE_STATIC_MUTEX(gJsonDataLock);
 
 void WriteTask::draw() {
-    SkString dir(FLAGS_writePath[0]);
-    this->makeDirOrFail(dir);
-    for (int i = 0; i < fSuffixes.count(); i++) {
-        dir = SkOSPath::SkPathJoin(dir.c_str(), fSuffixes[i].c_str());
-        this->makeDirOrFail(dir);
+    SkString md5;
+    {
+        SkAutoLockPixels lock(fBitmap);
+        md5 = fData ? get_md5(fData->getMemoryBase(), fData->getLength())
+                    : get_md5(fBitmap.getPixels(), fBitmap.getSize());
     }
 
-    SkString path = SkOSPath::SkPathJoin(dir.c_str(), fGmName.c_str());
-    path.append(fExtension);
+    SkASSERT(fSuffixes.count() > 0);
+    SkString config = fSuffixes.back();
+    SkString mode("direct");
+    if (fSuffixes.count() > 1) {
+        mode = fSuffixes.fromBack(1);
+    }
 
-    const bool ok = fData.get() ? save_data_to_file(fData,   path.c_str())
-                                : PngAndRaw::Encode(fBitmap, path.c_str());
+    JsonData entry = { fBaseName, config, mode, fSourceType, md5 };
+    {
+        SkAutoMutexAcquire lock(&gJsonDataLock);
+        gJsonData.push_back(entry);
+    }
+
+    SkString dir(FLAGS_writePath[0]);
+#if SK_BUILD_FOR_IOS
+    if (dir.equals("@")) {
+        dir.set(FLAGS_resourcePath[0]);
+    }
+#endif
+    this->makeDirOrFail(dir);
+
+    SkString path;
+    if (FLAGS_nameByHash) {
+        // Flat directory of hash-named files.
+        path = SkOSPath::Join(dir.c_str(), md5.c_str());
+        path.append(fExtension);
+        // We're content-addressed, so it's possible two threads race to write
+        // this file.  We let the first one win.  This also means we won't
+        // overwrite identical files from previous runs.
+        if (sk_exists(path.c_str())) {
+            return;
+        }
+    } else {
+        // Nested by mode, config, etc.
+        for (int i = 0; i < fSuffixes.count(); i++) {
+            dir = SkOSPath::Join(dir.c_str(), fSuffixes[i].c_str());
+            this->makeDirOrFail(dir);
+        }
+        path = SkOSPath::Join(dir.c_str(), fBaseName.c_str());
+        path.append(fExtension);
+        // The path is unique, so two threads can't both write to the same file.
+        // If already present we overwrite here, since the content may have changed.
+    }
+
+    SkFILEWStream file(path.c_str());
+    if (!file.isValid()) {
+        return this->fail("Can't open file.");
+    }
+
+    bool ok = fData ? file.writeStream(fData, fData->getLength())
+                    : SkImageEncoder::EncodeStream(&file, fBitmap, SkImageEncoder::kPNG_Type, 100);
     if (!ok) {
-        this->fail();
+        return this->fail("Can't write to file.");
     }
 }
 
@@ -150,7 +156,7 @@
     for (int i = 0; i < fSuffixes.count(); i++) {
         name.appendf("%s/", fSuffixes[i].c_str());
     }
-    name.append(fGmName.c_str());
+    name.append(fBaseName.c_str());
     return name;
 }
 
@@ -158,38 +164,38 @@
     return FLAGS_writePath.isEmpty();
 }
 
-static SkString path_to_expected_image(const char* root, const Task& task) {
-    SkString filename = task.name();
-
-    // We know that all names passed in here belong to top-level Tasks, which have a single suffix
-    // (8888, 565, gpu, etc.) indicating what subdirectory to look in.
-    SkTArray<SkString> suffixes;
-    const int suffixLength = split_suffixes(1, filename.c_str(), &suffixes);
-    SkASSERT(1 == suffixes.count());
-
-    // We'll look in root/suffix for images.
-    const SkString dir = SkOSPath::SkPathJoin(root, suffixes[0].c_str());
-
-    // Remove the suffix and tack on a .png.
-    filename.remove(filename.size() - suffixLength, suffixLength);
-    filename.append(".png");
-
-    return SkOSPath::SkPathJoin(dir.c_str(), filename.c_str());
-}
-
-bool WriteTask::Expectations::check(const Task& task, SkBitmap bitmap) const {
-    if (!FLAGS_writePath.isEmpty() && 0 == strcmp(FLAGS_writePath[0], fRoot)) {
-        SkDebugf("We seem to be reading and writing %s concurrently.  This won't work.\n", fRoot);
-        return false;
+void WriteTask::DumpJson() {
+    if (FLAGS_writePath.isEmpty()) {
+        return;
     }
 
-    const SkString path = path_to_expected_image(fRoot, task);
-    SkBitmap expected;
-    if (!PngAndRaw::Decode(path.c_str(), bitmap.info(), &expected)) {
-        return false;
+    Json::Value root;
+
+    for (int i = 1; i < FLAGS_properties.count(); i += 2) {
+        root[FLAGS_properties[i-1]] = FLAGS_properties[i];
+    }
+    for (int i = 1; i < FLAGS_key.count(); i += 2) {
+        root["key"][FLAGS_key[i-1]] = FLAGS_key[i];
     }
 
-    return BitmapsEqual(expected, bitmap);
+    {
+        SkAutoMutexAcquire lock(&gJsonDataLock);
+        for (int i = 0; i < gJsonData.count(); i++) {
+            Json::Value result;
+            result["key"]["name"]            = gJsonData[i].name.c_str();
+            result["key"]["config"]          = gJsonData[i].config.c_str();
+            result["key"]["mode"]            = gJsonData[i].mode.c_str();
+            result["options"]["source_type"] = gJsonData[i].sourceType.c_str();
+            result["md5"]                    = gJsonData[i].md5.c_str();
+
+            root["results"].append(result);
+        }
+    }
+
+    SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json");
+    SkFILEWStream stream(path.c_str());
+    stream.writeText(Json::StyledWriter().write(root).c_str());
+    stream.flush();
 }
 
 }  // namespace DM
diff --git a/dm/DMWriteTask.h b/dm/DMWriteTask.h
index c2c1d9f..d2403ad 100644
--- a/dm/DMWriteTask.h
+++ b/dm/DMWriteTask.h
@@ -1,9 +1,10 @@
 #ifndef DMWriteTask_DEFINED
 #define DMWriteTask_DEFINED
 
-#include "DMExpectations.h"
 #include "DMTask.h"
 #include "SkBitmap.h"
+#include "SkJSONCPP.h"
+#include "SkStream.h"
 #include "SkString.h"
 #include "SkTArray.h"
 
@@ -15,32 +16,28 @@
 class WriteTask : public CpuTask {
 
 public:
-    WriteTask(const Task& parent,  // WriteTask must be a child task.
-              SkBitmap bitmap);    // Bitmap to encode to PNG and write to disk.
+    WriteTask(const Task& parent,      // WriteTask must be a child task.
+              const char* sourceType,  // E.g. "GM", "SKP".  For humans.
+              SkBitmap bitmap);        // Bitmap to encode to PNG and write to disk.
 
-    WriteTask(const Task& parent,   // WriteTask must be a child task.
-              SkData *data,         // Pre-encoded data to write to disk.
-              const char* ext);     // File extension.
+    // Takes ownership of SkStreamAsset
+    WriteTask(const Task& parent,      // WriteTask must be a child task.
+              const char* sourceType,  // E.g. "GM", "SKP".  For humans.
+              SkStreamAsset* data,     // Pre-encoded data to write to disk.
+              const char* ext);        // File extension.
 
     virtual void draw() SK_OVERRIDE;
     virtual bool shouldSkip() const SK_OVERRIDE;
     virtual SkString name() const SK_OVERRIDE;
 
-    // Reads image files WriteTask wrote under root and compares them with bitmap.
-    class Expectations : public DM::Expectations {
-    public:
-        explicit Expectations(const char* root) : fRoot(root) {}
-
-        bool check(const Task& task, SkBitmap bitmap) const SK_OVERRIDE;
-    private:
-        const char* fRoot;
-    };
+    static void DumpJson();
 
 private:
     SkTArray<SkString> fSuffixes;
-    const SkString fGmName;
+    const SkString fBaseName;
+    const SkString fSourceType;
     const SkBitmap fBitmap;
-    SkAutoTUnref<SkData> fData;
+    SkAutoTDelete<SkStreamAsset> fData;
     const char* fExtension;
 
     void makeDirOrFail(SkString dir);
diff --git a/expectations/bench/bench_expectations_Perf-Android-GalaxyNexus-SGX540-Arm7-Release.txt b/expectations/bench/bench_expectations_Perf-Android-GalaxyNexus-SGX540-Arm7-Release.txt
index 9e35e6c..6d3824f 100644
--- a/expectations/bench/bench_expectations_Perf-Android-GalaxyNexus-SGX540-Arm7-Release.txt
+++ b/expectations/bench/bench_expectations_Perf-Android-GalaxyNexus-SGX540-Arm7-Release.txt
@@ -1,252 +1,252 @@
-desk_amazon.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,17.44,14.48384,19.91116
-desk_baidu.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,15.65,12.82744,17.96756
-desk_blogger.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,18.9,15.78784,21.49216
-desk_booking.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,31.64,27.46792,35.30208
-desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,562.23,515.13584,608.95416
-desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,313.06,285.90272,339.62228
-desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,20.1,16.8512,22.8388
-desk_ebay.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,34.2,29.82304,38.06696
-desk_espn.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,131.09,118.76072,142.86928
-desk_facebook.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,79.4,71.3068,86.9632
-desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,4.19,2.28424,5.59076
-desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,29.23,25.27112,32.67388
-desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,86.36,77.68112,94.44888
-desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,7.31,5.17488,8.93512
-desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,180.91,162.06488,198.57512
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,59.89,53.34784,65.88216
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,124.27,112.06496,136.12004
-desk_gws.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,37.92,33.32544,42.02956
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,89.36,80.47064,97.71936
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,7.85,5.65176,9.54324
-desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,21.05,17.8052,23.8098
-desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,376.96,344.9408,408.4792
-desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,29.01,24.95824,32.50676
-desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2.19,0.47432,3.41568
-desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,16.96,14.01264,19.40736
-desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,38.54,33.766,42.794
-desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1.47,-0.31808,2.77808
-desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,77.74,69.81976,85.12024
-desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,25.61,21.95984,28.78516
-desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,110.77,100.2772,120.7728
-desk_twitter.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,69.57,62.18232,76.44768
-desk_weather.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,129.78,117.55632,141.45368
-desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,173.08,157.3516,188.2684
-desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,29.15,25.216,32.609
-desk_youtube.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,25.89,22.20824,29.07676
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,113.43,102.69472,123.66028
-mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.72,19.29112,25.65388
-tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,43.2,38.10272,47.78728
-tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,41.93,36.93424,46.41576
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,307.07,280.66984,333.03016
-tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,182.37,166.018,198.242
-tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,91.37,82.44952,99.79548
-tabl_digg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,25.96,22.34264,29.08736
-tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,24.82,21.23392,27.88608
-tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,591.06,541.80192,639.77808
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,41.84,36.81208,46.36792
-tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,4.64,2.62776,6.18724
-tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,14.73,12.01104,16.95896
-tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,36.61,31.76904,40.98596
-tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,14.75,12.0196,16.9704
-tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,38.8,33.9748,43.1352
-tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,24.77,21.21792,27.81708
-tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,27.18,23.4556,30.3944
-tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.21,18.82216,25.10284
-tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,227.95,207.89152,247.49848
-tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,23.62,20.12984,26.59016
-tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,23.55,20.11584,26.47416
-tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,496.45,454.60192,537.66308
-tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,40.02,35.16672,44.38828
-tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,12.23,9.65112,14.28888
-tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,198.35,180.66992,215.54008
-tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.27,18.82784,25.20716
-tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,41.66,36.7568,46.0582
-desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1474.99,1282.34536,1683.45964
-desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50168,1.04668
-desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,79.61,69.17432,90.02568
-desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,3.93,-17.72728,29.90728
-desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,97.13,69.9008,120.7742
-desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,20.96,-16.55448,57.77448
-desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,125.18,111.83048,138.03452
-desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,44.67,38.61952,50.30548
-desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,27.8,-14.69704,71.45204
-tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,163.05,115.58192,194.23808
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,19.83,10.98688,25.36312
-tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,3.0,-108.848,140.738
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,151.7,111.7136,192.8614
-tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1.75,-29.49776,39.75776
-tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,70.24,54.86064,81.11436
-tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,31.52,24.3568,38.6282
-tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,185.33,138.52896,238.76604
-tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,27.76,10.40192,46.67808
-tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,25.22,20.8776,29.2674
-tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,11.01,0.30984,22.06516
-tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,23.52,19.94664,26.61836
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,17.79,14.74608,20.31892
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,19.13,15.93832,21.81668
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,38.4,33.64664,42.65336
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,655.26,600.87432,709.17068
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,308.3,281.624,334.491
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,37.83,33.1628,41.9872
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,35.74,31.24,39.73
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,266.35,242.28696,290.06804
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,190.67,172.55936,208.50564
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,4.78,2.8476,6.2024
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,39.79,34.99544,44.08956
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,93.03,83.86624,101.65876
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,8.12,5.92032,9.80968
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,219.46,199.95168,238.37832
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,73.33,65.82264,80.32736
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,169.21,152.99696,185.19304
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,39.17,34.36504,43.49496
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,123.68,112.0328,134.8672
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,8.7,6.43376,10.46124
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.91,19.44592,25.88408
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,304.73,278.62736,330.38764
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,29.54,25.53552,33.03448
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2.4,0.68768,3.61732
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,90.31,81.5144,98.6006
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,41.93,36.96416,46.40084
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1.7,-0.19776,3.16276
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,82.08,73.69048,90.00452
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,36.63,32.07872,40.66628
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,111.13,100.40832,121.32168
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,292.19,266.93176,316.95324
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,211.04,191.49048,230.33452
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,243.6,222.11824,264.59176
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,30.03,26.00656,33.53844
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,160.9,146.1136,175.2664
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,135.39,122.77344,147.57656
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,24.66,21.01528,27.82472
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,204.57,186.13112,222.40388
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,191.1,171.78544,209.39456
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1136.07,1042.14088,1229.67912
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,339.82,310.75264,368.34736
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,174.26,155.53352,193.16648
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,68.39,61.23808,75.04192
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,132.42,120.05368,144.28632
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,649.04,595.17248,702.42752
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,62.56,55.82376,68.78624
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,5.1,2.98064,6.74936
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,13.62,10.96008,15.77492
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,41.79,36.79552,46.29948
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,17.99,15.00048,20.46952
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,111.11,100.51976,121.20524
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,27.31,23.5248,30.5752
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,30.05,26.0552,33.5448
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,206.42,188.03232,224.37768
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,248.61,226.92848,269.79652
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,25.04,21.42576,28.15924
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,24.35,20.81136,27.38864
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,704.56,645.23408,763.59092
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,142.9,129.76648,155.53852
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,12.05,9.53576,14.05424
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,316.46,288.406,344.209
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,39.99,35.22008,44.25492
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,56.33,50.15256,61.98244
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1619.53,1405.89928,1850.74072
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50168,1.04668
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,92.06,82.53784,101.13216
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,25.53,-76.17704,104.03204
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,98.75,36.76672,159.76328
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,59.87,1.032,124.768
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,542.27,492.93824,592.02676
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,53.49,45.4368,60.8232
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50168,1.04668
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,26.93,-10.71288,68.62288
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,349.6,277.82544,400.17956
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,163.74,103.80168,201.32832
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2.69,-951.93408,1191.23908
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,183.61,143.73424,224.51576
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2.15,-15.19648,22.86148
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,64.85,45.83576,77.51924
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,318.48,257.23536,364.53464
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,277.17,213.85536,321.29464
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,34.66,10.17656,55.90344
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,58.01,32.01656,73.76344
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,13.82,-0.22008,29.77008
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.4816,1.0216
\ No newline at end of file
+desk_amazon.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,16.13,13.25,18.51
+desk_baidu.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,13.05,10.42,15.18
+desk_blogger.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,15.26,12.36,17.71
+desk_booking.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,28.52,24.50,32.10
+desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,614.57,535.68,699.68
+desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,314.29,287.30,340.77
+desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,17.52,14.49,20.02
+desk_ebay.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,32.39,28.07,36.20
+desk_espn.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,47.32,41.88,52.27
+desk_facebook.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,81.72,73.46,89.49
+desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,3.79,1.94,5.13
+desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2.01,0.25,3.25
+desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,84.83,76.35,92.79
+desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,6.98,4.83,8.63
+desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,157.64,143.35,171.43
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,59.80,53.23,65.89
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,126.24,113.99,138.09
+desk_gws.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,33.45,29.21,37.20
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,13.32,10.68,15.45
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,7.45,5.28,9.11
+desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,19.11,15.95,21.78
+desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,370.58,338.86,401.83
+desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,26.45,22.73,29.65
+desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2.21,0.49,3.44
+desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,16.69,13.55,19.36
+desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,35.54,31.11,39.47
+desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1.32,-0.49,2.68
+desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,76.95,69.05,84.36
+desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,24.40,20.84,27.47
+desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,112.22,100.43,123.79
+desk_twitter.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,66.82,59.74,73.34
+desk_weather.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.79,19.38,25.70
+desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,39.53,34.62,43.98
+desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,24.83,21.13,28.01
+desk_youtube.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,24.35,20.78,27.45
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,110.02,99.25,120.21
+mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,19.39,16.25,22.03
+tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,40.88,35.87,45.36
+tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,40.35,35.48,44.71
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,99.60,87.25,110.55
+tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,44.18,38.72,49.15
+tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,29.53,25.59,32.99
+tabl_digg.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,24.51,20.92,27.61
+tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.64,19.19,25.58
+tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,456.23,417.17,494.52
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,35.80,31.30,39.79
+tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,4.38,2.26,6.05
+tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,13.00,10.39,15.11
+tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,35.12,30.72,39.02
+tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,14.79,11.68,17.46
+tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,35.77,29.30,42.18
+tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,21.97,18.54,24.87
+tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,26.08,22.42,29.23
+tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,21.60,18.26,24.44
+tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,201.65,183.67,219.12
+tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,19.55,16.45,22.16
+tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,20.00,16.79,22.72
+tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,36.08,31.54,40.09
+tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,38.25,32.45,43.79
+tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,10.10,7.74,11.95
+tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,30.38,26.34,33.93
+tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,19.89,16.70,22.56
+tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,46.51,41.07,51.46
+desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1820.32,1591.62,2066.71
+desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,77.11,68.51,85.11
+desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,3.75,-18.17,29.99
+desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,92.41,68.37,112.84
+desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,16.09,-1.11,33.29
+desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,119.53,103.66,135.45
+desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,39.46,32.78,46.12
+desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,31.92,16.69,45.87
+tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,160.70,118.00,189.10
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,18.80,10.28,24.31
+tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,3.02,-71.74,94.43
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,145.50,102.97,189.24
+tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1.65,-15.35,21.87
+tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,70.14,56.11,80.66
+tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,23.51,18.04,28.96
+tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,185.49,139.73,237.51
+tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.56,7.07,40.36
+tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.04,17.89,25.91
+tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,9.66,-1.60,20.44
+tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.00,18.62,24.87
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,15.56,12.68,17.95
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,16.95,14.01,19.41
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,36.15,31.66,40.12
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,722.44,635.62,814.64
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,307.12,280.29,333.55
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,34.78,30.43,38.63
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,34.66,30.17,38.66
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,245.56,224.10,266.48
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,182.49,165.95,198.46
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,4.23,2.34,5.61
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,18.27,15.22,20.82
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,91.95,82.89,100.56
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,7.85,5.64,9.58
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,201.46,183.55,218.88
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,73.60,66.03,80.67
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,168.88,146.43,192.48
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,35.87,31.38,39.85
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,109.38,98.80,119.48
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,8.54,6.26,10.30
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,21.59,18.27,24.41
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,300.57,274.42,326.23
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,27.33,23.57,30.58
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2.40,0.64,3.66
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,88.23,78.35,97.90
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,40.53,35.64,44.94
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1.57,-0.26,2.95
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,81.01,72.73,88.69
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,34.09,29.69,37.96
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,113.98,103.04,124.41
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,265.70,241.34,289.60
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,171.51,156.09,186.44
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,218.19,199.06,236.84
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,26.84,22.94,30.23
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,151.25,137.34,164.58
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,127.95,115.90,139.51
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,21.83,18.40,24.76
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,189.98,173.02,206.46
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,175.28,159.50,190.60
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,1018.42,934.38,1101.87
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,317.17,289.82,344.12
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,167.71,147.37,188.43
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,65.38,58.45,71.82
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,122.63,111.10,133.67
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,553.62,507.35,599.29
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,57.46,51.25,63.17
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,5.04,3.05,6.53
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,12.51,9.90,14.63
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,40.81,35.80,45.29
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,18.24,15.18,20.78
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,103.82,93.74,113.44
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,31.69,27.48,35.37
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,29.43,25.31,33.02
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,183.58,167.20,199.48
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,229.79,209.63,249.45
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,22.09,17.63,26.33
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,21.82,18.50,24.63
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,622.17,570.45,673.36
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,137.35,124.47,149.67
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,10.59,8.18,12.51
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,290.62,265.61,315.11
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,38.06,33.43,42.21
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,61.17,54.60,67.26
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2073.44,1813.64,2353.89
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,99.93,87.24,112.82
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,33.22,-59.59,82.50
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,93.76,55.77,136.62
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,57.61,-0.12,123.23
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,552.47,503.11,602.10
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,46.01,31.03,62.76
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,33.24,1.05,71.50
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,353.70,277.71,409.34
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,164.07,104.31,201.28
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2.74,-955.90,1196.33
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,190.18,130.82,243.87
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,2.16,-15.31,23.03
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,67.73,47.87,80.95
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,320.07,258.97,366.17
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,280.78,216.07,325.76
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,29.45,-4.57,62.69
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,59.00,32.04,75.53
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,13.41,-0.12,28.62
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.48,1.02
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-GalaxyNexus-SGX540-Arm7-Release-25th,0.02,-1.50,1.05
\ No newline at end of file
diff --git a/expectations/bench/bench_expectations_Perf-Android-Nexus10-MaliT604-Arm7-Release.txt b/expectations/bench/bench_expectations_Perf-Android-Nexus10-MaliT604-Arm7-Release.txt
index fcb9fa9..1bea8e7 100644
--- a/expectations/bench/bench_expectations_Perf-Android-Nexus10-MaliT604-Arm7-Release.txt
+++ b/expectations/bench/bench_expectations_Perf-Android-Nexus10-MaliT604-Arm7-Release.txt
@@ -1,252 +1,237 @@
-desk_amazon.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.27,6.96776,11.08724
-desk_baidu.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.58,6.26272,10.40728
-desk_blogger.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.04,8.58664,12.98836
-desk_booking.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,18.47,15.4216,21.0134
-desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,275.19,251.3224,298.5326
-desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,184.05,167.20864,200.38636
-desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.55,9.00584,13.57916
-desk_ebay.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,18.55,15.47512,21.12488
-desk_espn.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,72.52,65.03712,79.50288
-desk_facebook.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,40.99,36.10016,45.38484
-desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.66,-0.14336,2.98336
-desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,16.2,13.31336,18.58664
-desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,47.37,41.95008,52.25492
-desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.05,2.12552,5.49948
-desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,92.53,82.37056,101.64944
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,30.36,25.99936,34.12564
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,66.73,59.6096,73.3754
-desk_gws.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,24.84,21.27168,27.92832
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,48.21,42.74144,53.18356
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.36,2.46128,5.74872
-desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.79,10.2168,14.8532
-desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,227.07,206.90992,246.78508
-desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.29,14.30656,19.75344
-desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.01,-0.65128,2.19128
-desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.18,6.27288,11.73212
-desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,22.94,19.44336,25.93164
-desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.71,-0.90728,1.84228
-desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,45.21,39.62856,50.36144
-desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.4,11.65768,16.64232
-desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,62.93,56.2732,69.1168
-desk_twitter.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,32.69,28.484,36.396
-desk_weather.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,73.5,65.9996,80.4854
-desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,98.75,88.42472,108.71528
-desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,15.61,12.75088,17.97412
-desk_youtube.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.73,11.06128,15.89372
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,60.21,53.55088,66.36412
-mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.75,10.09888,14.91112
-tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,23.42,19.91592,26.38908
-tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,21.89,18.54816,24.73184
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,153.96,129.4076,180.6174
-tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,99.71,90.05064,108.91436
-tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,50.89,45.16848,56.08152
-tabl_digg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,15.28,12.40664,17.66836
-tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.37,10.64896,15.60604
-tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,286.81,261.99128,311.19872
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,23.63,20.16888,26.58612
-tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,2.52,0.75816,3.79684
-tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.48,6.26096,10.20904
-tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,22.98,19.56048,25.91952
-tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.44,5.244,9.161
-tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.8,14.33296,27.56704
-tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.45,10.80352,15.59148
-tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.51,9.03904,13.47096
-tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.55,9.96496,14.65504
-tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,120.16,108.18352,131.76148
-tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.6,10.97104,15.73896
-tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.71,10.30008,16.79992
-tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,293.26,267.13168,319.08832
-tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.81,21.93384,29.15116
-tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,6.71,4.54272,8.38728
-tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,118.33,107.19184,128.98816
-tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.34,9.78256,14.39244
-tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.48,21.75976,28.70024
-desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.24,4.62432,9.46568
-desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.52,8.00352,14.78648
-desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,10.03,-12.77184,37.43184
-desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.43,15.7984,24.9116
-desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,721.35,621.76824,821.93676
-desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,791.19,689.37488,881.06512
-desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,6.44,3.8712,8.6238
-desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.07,8.41408,30.45092
-desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.58,12.81152,28.62848
-desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,24.94,18.98648,30.91352
-desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.61,-1.39048,2.20048
-desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,49.14,40.39408,58.09092
-desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,36.23,29.46944,43.03056
-desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,3.75,1.38688,5.75312
-desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.66,19.80616,31.56384
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,178.7,151.2496,205.4504
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,228.66,165.75528,284.80472
-desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,15.64,6.8524,25.4076
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.1,2.12568,7.70432
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,3.93,-1.0152,9.1052
-desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,15.97,9.08632,23.37368
-desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,152.07,136.79376,167.20124
-desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,30.26,20.08992,40.86508
-desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.45,-1.20728,1.63728
-desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,2.89,0.9676,4.3374
-desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,27.8,23.20176,32.04824
-desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.41,-0.45584,2.81584
-desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,236.95,214.38184,258.95816
-desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.26,6.56208,11.54792
-desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,153.71,130.30288,172.85212
-desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,57.01,45.74184,68.88316
-desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.59,16.93232,23.62768
-desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,16.77,12.89464,20.35536
-desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,21.49,16.22088,26.47412
-desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,28.51,19.31072,37.69928
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.44,1.85792,6.70208
-mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.76,5.15416,9.94084
-tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,16.78,12.99432,20.23068
-tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,66.51,54.64488,78.49512
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,30.4,24.0184,36.8166
-tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.28,6.31632,11.56368
-tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.02,7.82544,18.10456
-tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,6.45,3.822,8.573
-tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.42,6.44856,12.04644
-tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.93,-0.19664,3.65164
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.29,21.18192,28.99808
-tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.65,-0.28336,3.15836
-tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.99,4.01656,13.94344
-tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,19.03,12.92304,24.88196
-tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.83,-0.38304,10.27804
-tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.25,4.484,13.626
-tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,21.41,12.31952,30.92048
-tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,194.43,149.87488,237.97512
-tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,6.44,3.76624,8.75376
-tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,28.25,21.838,34.727
-tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.15,10.22472,15.64528
-tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,15.86,10.51824,21.24676
-tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,65.84,56.50352,75.15648
-tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,65.37,56.16016,74.64984
-tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.17,2.97256,6.93744
-tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,22.72,15.47368,30.37632
-tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.61,9.49632,15.37368
-tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.23,18.45184,32.08316
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.36,9.8104,14.4246
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.52,7.12744,11.42256
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.3,8.83536,13.27964
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,22.03,18.65712,24.90788
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,322.58,294.32728,350.56772
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,175.73,158.23296,192.78204
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.95,17.7036,23.6914
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,19.8,16.36264,22.75736
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,134.97,122.18152,147.13348
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,95.09,84.84704,105.09296
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.96,0.1528,3.2822
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,22.0,18.66976,24.82524
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,51.13,45.42832,56.33668
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.57,2.62368,6.03632
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,112.44,101.70336,122.64664
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,37.84,33.1924,41.9726
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,95.57,84.71656,106.25344
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.9,22.23712,29.06288
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,60.05,53.61544,65.99456
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.0,3.0596,6.4504
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.91,11.166,16.164
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,184.17,167.504,200.286
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.1,14.13152,19.54848
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.11,-0.57928,2.32428
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,47.98,42.59152,52.85848
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,24.63,21.06912,27.69088
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.83,-0.79664,1.97164
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,47.6,42.2016,52.4984
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.18,17.0156,22.8344
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,63.77,57.0376,70.0124
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,140.53,127.64648,152.90352
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,108.36,97.54784,118.78716
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,127.66,115.62552,139.18448
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,15.83,12.9836,18.1514
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,86.08,77.57312,94.07188
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,70.29,62.94376,77.14624
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.9,10.62472,16.84028
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,108.28,97.26176,118.98824
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,96.52,86.14656,106.36344
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,574.19,526.01056,621.96444
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,176.68,160.9048,191.9452
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,89.89,80.06944,99.49056
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,38.72,33.96072,42.97428
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,66.84,59.90192,73.27808
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,309.48,282.39704,336.13296
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,35.71,31.28248,39.63252
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,2.75,0.94944,4.07056
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.65,5.46784,9.32716
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,26.27,12.04544,42.63956
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.24,6.96048,11.02952
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,58.32,51.01952,65.38048
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.29,11.60616,16.48384
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.92,10.3364,14.9936
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,110.53,99.904,120.681
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,132.78,119.77928,144.87072
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.43,11.70544,16.64956
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.12,11.42,16.315
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,368.88,337.33776,399.94224
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,80.95,72.87392,88.50608
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,6.67,4.5356,8.3294
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,169.39,154.1568,184.1232
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,22.08,18.75288,24.92212
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,32.83,28.36368,36.65632
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.83,5.8084,11.4616
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,10.96,6.92504,14.88496
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,10.09,7.12424,12.69576
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.58,16.98008,23.76992
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,784.45,695.67368,874.97132
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,731.67,650.39512,812.81488
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.12,4.19688,11.95812
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,103.36,82.40232,126.49268
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,74.17,64.36648,84.03852
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,50.66,42.59952,58.70548
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.63,-1.3632,2.2332
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,68.36,51.81288,86.69712
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,30.13,25.39616,34.52384
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.01,2.08992,7.66008
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,28.37,24.23736,32.04764
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,182.35,124.60056,231.58444
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,230.28,141.8732,293.2268
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,18.3,8.35336,28.54164
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,28.12,23.75968,31.84032
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,6.67,-1.61344,15.95344
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.39,10.6608,24.5492
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,117.11,103.32072,130.73928
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,28.16,11.64064,40.45436
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.48,-1.13944,1.61944
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.64,2.17464,6.73036
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,26.05,21.2584,30.6416
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.5,-0.37224,2.91224
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,240.73,208.85408,274.49092
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.95,6.59592,13.01908
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,158.39,128.87864,182.14636
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,113.6,98.82032,127.72968
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,64.03,54.88728,73.16272
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,40.25,33.14104,47.40396
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.2,12.38272,21.83728
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,27.34,21.3648,33.3352
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.74,1.88368,7.31632
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.41,4.21944,10.30556
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,48.96,41.10536,56.80464
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,120.88,101.15008,138.84492
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,203.59,176.66832,232.09168
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.56,9.40688,19.62812
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.98,1.14288,30.95212
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,10.34,5.192,15.103
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.02,11.77152,22.31348
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.27,2.22608,8.06892
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,26.84,22.2976,31.0374
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.92,-0.12504,3.54004
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.27,2.76152,7.42348
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,19.48,10.02408,29.34592
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.93,-3.18808,36.33808
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,57.63,49.11792,66.11708
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,33.49,23.4576,42.4724
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,256.11,181.49872,329.42128
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.55,5.61456,13.21544
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,48.94,40.9512,56.8638
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.47,8.76048,13.72952
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.84,10.35248,16.97752
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,127.33,112.99456,141.61544
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,95.78,84.07688,107.56812
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.9,2.6856,6.6944
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,51.21,40.4848,62.5502
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.12,10.92608,16.95392
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,27.54,20.87208,33.96292
\ No newline at end of file
+desk_amazon.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.82,6.54424,10.59076
+desk_baidu.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.72,5.39168,9.57832
+desk_blogger.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,10.0,7.60968,11.89032
+desk_booking.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.31,14.3344,19.7856
+desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,314.38,268.0912,362.1738
+desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,179.86,162.63352,196.71648
+desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,10.42,7.64408,12.80592
+desk_ebay.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,19.25,16.1396,21.8554
+desk_espn.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,23.76,20.24864,26.77636
+desk_facebook.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,41.09,34.52576,47.52924
+desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.84,0.1124,3.0876
+desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.92,-0.74384,2.08384
+desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,49.25,43.58936,54.42064
+desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,3.93,1.99464,5.39536
+desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,83.79,75.4752,91.6098
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,30.27,26.01656,34.08344
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,69.18,61.78248,76.12252
+desk_gws.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,24.58,21.01304,27.67196
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,6.49,4.43032,8.05968
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.69,2.72464,6.15536
+desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.2,9.66328,14.25172
+desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,216.99,187.66776,248.37224
+desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,16.07,12.9928,18.6522
+desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.27,-0.38152,2.41152
+desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.11,6.57952,11.21548
+desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,22.1,18.65064,25.09436
+desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.67,-0.94384,1.79884
+desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,44.56,39.20208,49.46792
+desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.61,10.89016,15.83984
+desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,63.62,56.62792,70.16708
+desk_twitter.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,31.57,27.0212,35.7488
+desk_weather.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.57,9.104,13.546
+desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,21.16,17.89696,23.91804
+desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.05,11.3552,16.2398
+desk_youtube.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.44,10.79448,15.58052
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,59.24,52.73848,65.26152
+mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.38,8.82824,13.46676
+tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,23.36,19.9004,26.3196
+tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,21.36,18.08104,24.13396
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,41.82,36.89336,46.26664
+tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,23.03,19.45504,26.13996
+tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.43,11.6544,16.7356
+tabl_digg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.84,12.06208,17.11792
+tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.06,10.45408,15.18092
+tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,225.93,205.67096,245.81404
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,21.28,17.79616,24.28884
+tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,2.52,0.758,3.797
+tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.89,5.71832,9.57168
+tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,23.45,18.76912,27.91088
+tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.8,5.61512,9.49988
+tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.21,16.94176,22.99324
+tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.24,9.69032,14.28468
+tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.66,9.126,13.719
+tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.69,10.1544,14.7306
+tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,112.56,101.78216,122.88284
+tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.12,9.49976,14.25524
+tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.58,9.99248,14.68752
+tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,18.32,15.11288,21.08712
+tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.75,22.1192,28.8758
+tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.91,3.8564,7.4836
+tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.87,14.83904,20.42596
+tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.44,8.93456,13.44544
+tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,28.27,24.07584,32.00416
+desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,6.22,3.21608,8.92892
+desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.05,6.30184,11.38316
+desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.06,5.27624,10.47876
+desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.34,13.55816,20.82184
+desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,734.38,557.80064,906.59936
+desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,757.0,672.34608,838.88892
+desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.92,2.23992,7.29508
+desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.01,10.62896,23.60604
+desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.55,10.476,24.414
+desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,24.81,18.75416,30.93584
+desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.57,-1.41768,2.16768
+desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.1,-0.68984,2.39484
+desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,36.2,28.04016,43.87484
+desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,3.37,1.03704,5.25296
+desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.08,19.132,31.113
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,175.11,136.43112,208.40888
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,227.08,189.46656,264.46844
+desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.63,3.32344,22.49656
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.02,1.94728,7.74772
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,3.68,-2.35928,10.21928
+desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.19,8.93272,19.57728
+desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,148.0,132.00976,163.78524
+desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.12,15.87224,33.64776
+desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.45,-1.22768,1.66268
+desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,2.74,0.80952,4.20048
+desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,24.37,9.57592,41.41908
+desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.35,-0.59168,2.85168
+desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,230.5,199.3388,263.8612
+desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.6,5.05616,9.72884
+desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,151.03,134.732,167.278
+desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,56.81,46.33744,67.47756
+desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.11,15.39056,24.72944
+desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.11,3.29264,25.87236
+desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,16.64,12.26248,20.87752
+desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,31.21,22.83608,39.69892
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,3.6,1.40928,5.39072
+mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.49,3.1376,7.4224
+tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,16.19,12.08744,20.04756
+tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,66.27,55.82152,75.82348
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,30.47,23.94192,36.93808
+tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.51,4.73936,9.90064
+tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,10.63,7.34928,13.59572
+tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.51,2.99616,7.55384
+tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.22,5.25608,10.79392
+tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.85,-0.9832,4.4782
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,21.12,17.1548,24.7552
+tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.53,-0.22296,2.79296
+tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.97,3.79536,11.87964
+tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,16.12,10.86656,20.94344
+tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.24,-9.79176,29.69176
+tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.33,4.83344,11.61156
+tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,19.91,11.02272,29.14728
+tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,192.99,152.42176,233.97324
+tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.81,3.24832,7.99668
+tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,28.52,22.15344,34.80156
+tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.72,6.54872,12.41128
+tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.02,8.00408,17.65592
+tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,65.7,55.61104,75.88896
+tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,65.21,55.9808,74.5392
+tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.08,2.00056,5.69944
+tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,19.69,12.23632,26.96868
+tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.66,6.70984,12.16516
+tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,25.62,18.65824,32.76176
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.95,9.4036,13.9964
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.45,7.08344,11.32156
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,10.95,8.47328,12.95172
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,21.68,18.38472,24.49028
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,371.79,324.92904,418.75096
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,171.3,154.39488,188.01512
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,19.83,16.63288,22.53212
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.47,17.22112,23.22388
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,129.27,116.33296,141.95704
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,94.43,85.14352,103.20648
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.99,0.22992,3.27508
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.25,6.98976,11.01524
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,52.53,46.73664,57.82336
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.5,2.5796,5.9354
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,107.49,97.26896,117.24104
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,36.69,32.12368,40.76632
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,96.76,85.33112,108.05388
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,26.43,22.75456,29.62044
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,56.17,49.9964,61.7986
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.9,2.9376,6.3574
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.66,10.96688,15.83312
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,176.23,160.03528,192.04972
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,16.46,13.57264,18.84236
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.24,-2.428,4.923
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,45.08,39.88256,49.77744
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,24.5,20.9196,27.5654
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,0.79,-0.85352,1.95352
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,46.83,41.3412,51.8338
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,20.49,16.89904,23.67096
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,64.07,57.29376,70.31624
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,134.72,121.45584,147.65916
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,92.46,83.48136,100.95864
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,119.64,107.63168,131.26832
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.91,12.08736,17.19764
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,81.85,73.50928,89.74072
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,73.16,65.69552,80.12948
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.14,10.39784,15.40716
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,105.87,95.7796,115.4454
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,92.61,81.18032,104.02968
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,541.86,486.57928,599.08072
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,168.94,152.30376,185.36624
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,85.77,74.558,96.562
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,36.97,32.44208,40.99292
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,64.03,56.8944,70.7706
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,295.01,269.36584,320.15416
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,33.71,29.42256,37.49744
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,2.67,0.85568,4.00932
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.53,5.35744,9.19756
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,26.38,22.64872,29.64128
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.99,7.6504,11.8396
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,57.77,51.4772,63.5828
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,18.52,15.44792,21.09208
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.18,10.55536,15.29964
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,105.11,91.7148,118.8502
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,128.39,116.48744,139.80256
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.51,10.83888,15.68112
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.66,10.93648,15.89352
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,346.74,306.81592,388.66408
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,77.63,69.82904,84.93096
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,6.37,4.20968,8.04532
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,164.4,149.19304,179.22196
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,21.3,17.98536,24.11964
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,35.63,31.16864,39.59636
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.99,4.55216,11.15784
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.2,6.35024,11.58976
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,18.24,14.53696,21.58304
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,787.52,618.06264,964.31736
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,736.12,661.0968,806.1532
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,7.5,2.79584,11.20416
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,73.86,63.97216,83.77284
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,50.54,42.596,58.559
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.26,-1.19,3.195
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.19,2.07536,8.07964
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,28.22,22.082,34.383
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,179.46,133.0284,217.7266
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,16.31,8.94936,24.28064
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,24.45,15.26104,31.97896
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.43,2.30408,6.10092
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,23.93,20.13344,27.27656
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.36,-0.47,2.745
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,237.49,215.72176,258.89324
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,8.71,5.54752,11.58748
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,111.94,97.10392,126.79608
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.12,10.4136,17.5714
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.92,9.37096,20.09404
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,3.82,1.56216,5.66784
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.69,2.66632,8.43368
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,48.67,40.7768,56.5482
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,117.47,98.58904,137.55596
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,203.19,173.81488,233.97512
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,13.7,8.34312,18.92188
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,14.33,9.31576,19.36424
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.17,5.7864,12.3136
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,5.24,2.28872,7.90128
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,23.76,19.38528,27.71972
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,1.78,-0.224,3.374
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.79,2.2308,6.9942
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,17.26,7.29248,27.76752
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,19.4,-2.74968,45.77468
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,57.64,49.1368,66.1382
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,37.51,28.5992,46.5158
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,249.48,190.35472,316.30028
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.22,5.61096,12.61904
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,48.56,40.55152,56.53848
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,9.13,6.2988,11.5862
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,11.96,8.32976,15.29024
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,127.36,110.31056,143.71444
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,95.74,84.0532,107.3518
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,4.21,1.57808,6.42692
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,49.1,37.20944,61.20056
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus10-MaliT604-Arm7-Release-25th,12.21,8.23448,15.49552
\ No newline at end of file
diff --git a/expectations/bench/bench_expectations_Perf-Android-Nexus4-Adreno320-Arm7-Release.txt b/expectations/bench/bench_expectations_Perf-Android-Nexus4-Adreno320-Arm7-Release.txt
index 57e6755..d1438c9 100644
--- a/expectations/bench/bench_expectations_Perf-Android-Nexus4-Adreno320-Arm7-Release.txt
+++ b/expectations/bench/bench_expectations_Perf-Android-Nexus4-Adreno320-Arm7-Release.txt
@@ -1,252 +1,252 @@
-desk_amazon.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,7.79,5.63688,9.42812
-desk_baidu.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,8.34,5.98096,10.22404
-desk_blogger.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.13,6.76,10.945
-desk_booking.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.14,14.03648,19.77852
-desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,259.6,233.67616,285.79384
-desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,145.5,131.5628,159.1122
-desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.26,6.9988,11.0262
-desk_ebay.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.52,11.71832,16.76668
-desk_espn.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,62.3,55.23272,68.96728
-desk_facebook.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,40.25,34.76424,45.38076
-desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.85,0.12072,3.09928
-desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.05,12.2548,17.3452
-desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,44.29,38.99592,49.12408
-desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,3.72,1.75208,5.16292
-desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,75.64,67.9776,82.8074
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,26.43,22.694,29.696
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,70.03,61.77272,77.93728
-desk_gws.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.88,15.9852,23.4298
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,40.28,35.42608,44.64392
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,4.0,2.07016,5.38984
-desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.62,8.2296,12.5204
-desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,189.31,169.82768,208.88232
-desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.4,10.04512,20.88488
-desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.91,-0.77336,2.09836
-desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.65,4.38624,8.44876
-desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,23.09,19.09856,26.69644
-desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.81,-0.83536,1.97536
-desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,41.2,34.21744,48.08756
-desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.88,9.20776,14.10724
-desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,46.38,40.41432,52.01068
-desk_twitter.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,32.62,28.31824,36.44676
-desk_weather.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,62.73,55.99,68.98
-desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,84.61,76.23024,92.49476
-desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.12,10.45856,15.28644
-desk_youtube.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.92,9.35504,13.98996
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,49.53,43.44568,55.13432
-mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.54,7.47072,13.28928
-tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.87,18.48904,24.76096
-tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.81,16.63448,22.48552
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,139.09,123.66016,154.57984
-tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,82.75,74.4888,90.5012
-tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,43.49,38.31096,48.12904
-tabl_digg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.63,9.09808,13.68692
-tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.45,8.24008,14.28992
-tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,230.77,207.86568,253.81432
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.89,18.52792,24.75708
-tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.93,-1.67592,5.52092
-tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.89,4.81824,8.46676
-tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.73,16.2488,22.7662
-tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.39,4.32872,7.94128
-tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,16.42,11.50752,21.33248
-tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.7,9.214,13.676
-tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.68,10.00464,14.85036
-tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.41,8.00664,12.30836
-tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,102.78,92.25416,112.87084
-tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.77,9.22656,13.83844
-tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.11,9.49912,14.25588
-tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,240.78,219.84616,261.23384
-tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.65,15.52792,21.23708
-tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,5.96,3.88232,7.56268
-tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,95.98,86.73104,104.72396
-tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.05,8.2436,13.4614
-tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.88,19.18576,26.11924
-desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.01,10.25832,15.24668
-desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.34,17.022,23.183
-desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.88,14.81816,20.45184
-desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,35.15,30.02272,39.95728
-desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,704.37,644.09344,764.05156
-desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,484.98,427.77064,545.06436
-desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.21,6.85152,11.09848
-desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.08,16.7524,22.9176
-desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,26.02,21.91568,29.70932
-desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,30.56,26.33248,34.31252
-desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.27,-0.442,2.487
-desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,66.46,59.392,72.978
-desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,51.32,45.4428,56.6522
-desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.06,3.86464,7.74036
-desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.11,18.64,25.085
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,133.78,120.4996,146.6254
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,645.96,589.19392,702.39608
-desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.78,18.88384,26.29616
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,4.34,1.69592,6.65908
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,3.45,0.12248,6.66252
-desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.81,17.42336,23.75164
-desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,125.17,110.57088,139.80912
-desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,27.96,23.7004,31.8046
-desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.75,-0.81,1.81
-desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,5.73,3.56032,7.38468
-desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,44.2,35.26576,53.55924
-desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.81,0.0636,3.0814
-desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,145.74,129.91064,161.66436
-desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.15,13.93616,19.90384
-desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,105.37,91.05568,120.18432
-desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,56.18,49.8652,61.8948
-desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,33.85,29.40056,37.76944
-desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.95,16.42176,23.06324
-desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.59,18.22208,24.44792
-desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,72.6,65.05096,79.66404
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.41,8.90672,13.41328
-mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.04,7.39872,18.92628
-tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.14,15.958,21.837
-tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,36.37,30.1212,42.5538
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,27.67,23.91576,30.93424
-tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.04,14.76848,23.07652
-tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.55,10.88448,15.73552
-tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.49,9.80848,14.71652
-tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,16.05,12.74224,18.98776
-tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.17,3.87504,7.99496
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,48.85,35.6888,63.3962
-tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.66,-0.03384,2.86884
-tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.61,7.76688,15.25812
-tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.62,17.52608,27.63392
-tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.08,3.82216,7.88284
-tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.33,7.2996,12.9904
-tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,57.46,50.85176,63.40324
-tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,30.67,26.64624,34.18876
-tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.19,6.91392,10.97608
-tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.03,14.65512,20.98988
-tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.81,15.54168,28.30832
-tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.17,16.6036,23.3264
-tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,34.1,29.76112,37.94388
-tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,51.53,45.66576,56.90924
-tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,8.18,5.9552,9.8998
-tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,32.56,28.05144,36.57856
-tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.91,17.86336,25.63164
-tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,31.43,25.65416,36.29084
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.11,7.74048,11.99452
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.49,7.1004,11.3446
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.33,6.91424,11.17576
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.86,16.52024,22.69476
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,315.3,284.76672,345.82828
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,139.46,124.07752,154.92748
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.98,13.09104,18.37396
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.94,12.22464,17.16036
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,116.12,104.4652,127.4448
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,89.93,80.51,98.985
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,2.17,0.39488,3.47012
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.3,15.16568,20.90932
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,48.14,42.18592,53.69908
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,4.14,2.16904,5.55596
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,93.72,83.82544,103.31456
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,34.03,29.67712,37.84788
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,103.88,90.63512,117.40988
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.71,16.99992,24.03508
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,51.31,45.0916,57.1584
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,4.51,2.50944,5.95556
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.19,9.61288,14.29212
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,154.3,139.66128,168.56872
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.26,12.41768,17.63232
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.0,-0.66072,2.18072
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,36.66,31.71392,41.21108
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,25.26,21.61792,28.43208
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.91,-0.7436,2.0836
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,43.48,37.95976,48.54524
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.7,12.19,18.875
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,47.69,41.95008,52.98992
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,125.88,113.33568,138.00932
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,92.1,82.38496,101.48004
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,109.82,96.87248,122.83752
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.28,10.63584,15.44416
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,76.61,68.1672,84.7328
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,57.85,51.0492,64.2508
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.56,6.83288,16.33712
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,97.84,87.47248,107.89752
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,85.69,72.74256,99.21244
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,475.43,435.00304,515.39696
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,146.68,132.60032,160.37968
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,76.9,66.7356,86.9644
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,28.26,23.96504,32.16496
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,57.92,50.98224,64.46776
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,252.54,227.74784,277.55216
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,32.23,27.97968,36.00032
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,2.11,0.36,3.38
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.14,4.04768,7.75732
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.27,18.53488,25.59512
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,7.5,5.29808,9.22692
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,43.16,37.46152,48.54348
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.52,9.60448,15.01552
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.25,10.46912,15.49588
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,94.68,82.17088,107.51912
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,113.0,101.6132,124.0518
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.26,9.64752,14.38248
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.02,9.47728,14.08272
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,310.27,282.51704,337.83296
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,57.32,50.61144,63.63856
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,5.84,3.73136,7.48364
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,140.3,126.92272,153.27228
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.51,14.45728,20.07772
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,29.56,25.48432,33.12068
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.07,14.93256,20.73244
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.7,16.0504,22.9696
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.17,14.74304,21.19196
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,36.21,31.3608,40.6492
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,846.07,774.79312,916.84688
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,451.48,392.6004,515.0146
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.37,-13.728,45.608
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,42.76,37.46568,47.57932
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,35.85,31.31072,39.90928
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,47.55,41.692,52.978
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.4,-0.27272,2.58772
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,72.07,64.55312,79.03688
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,47.68,42.04336,52.85164
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,8.08,2.63392,13.84608
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.08,12.21144,17.48856
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,148.67,133.62568,163.26432
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,358.23,324.12872,392.47128
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.72,18.5576,26.5474
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.03,7.52952,23.22048
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,5.03,-0.82584,11.34584
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.56,18.98304,25.68196
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,100.78,90.37192,110.76308
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,27.64,23.2952,31.6198
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.85,-0.718,1.918
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.25,15.1392,20.8308
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,41.62,32.84336,50.72164
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.82,-0.01704,3.18204
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,148.99,134.38024,163.21476
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.13,16.57712,23.24788
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,106.75,91.13816,122.97684
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,74.33,66.69272,81.44728
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,34.6,30.16048,38.55952
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.92,19.44472,25.93028
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.19,14.94216,20.98784
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,33.98,29.66024,37.82476
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.22,9.5916,14.3634
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.92,7.60608,18.37892
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,29.15,25.14696,32.62804
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,43.36,38.09976,48.08024
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,76.99,69.18016,84.26984
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,35.5,30.26488,40.43512
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,23.33,19.79184,26.38816
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.57,17.23272,23.43228
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,28.08,23.51664,32.27836
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.99,12.01976,17.50524
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,53.69,39.93904,68.87596
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,2.09,0.29176,3.39824
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.04,7.6264,11.9586
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,30.02,23.14856,35.06644
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.01,5.42392,12.39108
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.23,17.958,26.182
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,56.72,49.97832,62.86668
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,36.75,32.1896,40.7954
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.23,15.05,20.875
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.26,18.84848,25.18152
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.64,14.93168,24.23332
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,16.7,13.65272,19.27728
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,53.99,48.06952,59.43548
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,65.29,58.28584,71.72916
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,7.78,5.58736,9.46764
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,40.57,35.4724,45.1426
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,27.55,23.72416,30.90584
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,41.05,30.34104,52.62896
\ No newline at end of file
+desk_amazon.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,7.39,5.22,9.08
+desk_baidu.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,7.54,5.23,9.40
+desk_blogger.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,8.00,5.72,9.79
+desk_booking.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,16.14,12.90,18.90
+desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,299.30,249.78,352.87
+desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,146.74,131.14,160.93
+desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,8.69,6.39,10.49
+desk_ebay.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.79,11.04,16.06
+desk_espn.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.31,16.93,23.23
+desk_facebook.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,40.30,32.32,48.44
+desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.88,0.14,3.13
+desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.50,-1.12,1.64
+desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,43.79,38.70,48.39
+desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,3.42,1.50,4.88
+desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,66.80,59.31,73.76
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,26.50,20.41,32.67
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,69.69,61.32,77.58
+desk_gws.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.55,15.35,21.25
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.40,4.28,8.04
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,3.76,1.92,5.10
+desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.09,7.67,12.01
+desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,192.71,174.86,210.04
+desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.30,11.49,16.61
+desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.91,-0.69,2.02
+desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.60,4.47,8.23
+desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.19,15.18,27.29
+desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.76,-0.88,1.92
+desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,41.50,36.54,45.99
+desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.13,8.66,13.12
+desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,47.64,41.93,52.89
+desk_twitter.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,30.91,26.34,35.10
+desk_weather.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.79,7.43,11.67
+desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.82,14.67,20.48
+desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.66,9.13,13.71
+desk_youtube.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.16,8.54,13.32
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,47.59,41.70,52.99
+mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.74,6.03,13.26
+tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.55,18.02,24.58
+tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.29,15.97,22.09
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,51.73,45.25,57.71
+tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.11,14.97,20.74
+tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.69,11.03,15.86
+tabl_digg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.34,8.74,13.46
+tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.07,8.53,13.14
+tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,163.53,148.38,178.18
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.55,15.76,22.95
+tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.84,0.12,3.05
+tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.57,4.45,8.21
+tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.95,15.77,21.64
+tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,7.00,4.77,8.71
+tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.79,12.90,18.19
+tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.51,7.93,12.60
+tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.43,9.71,14.64
+tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.76,8.33,12.69
+tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,94.34,84.87,103.32
+tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.60,8.12,12.58
+tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.13,8.63,13.13
+tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.96,12.98,18.46
+tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.37,12.37,22.31
+tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,5.35,3.34,6.84
+tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.69,11.93,16.96
+tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.03,7.62,11.96
+tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,26.41,22.22,30.09
+desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.62,7.77,15.29
+desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.88,15.57,21.71
+desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.19,10.50,19.82
+desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,31.61,26.98,35.87
+desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,711.81,649.47,774.10
+desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,492.25,427.26,561.35
+desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,7.85,-0.90,17.24
+desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.52,11.69,23.49
+desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.73,15.85,27.71
+desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,30.93,26.69,34.68
+desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.24,-0.40,2.39
+desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.89,-0.97,2.31
+desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,51.92,45.92,57.31
+desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,5.54,1.67,9.37
+desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.61,19.18,25.53
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,127.73,115.19,139.90
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,574.89,523.00,626.39
+desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.36,15.57,22.79
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,4.29,1.69,6.56
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,3.16,-0.18,6.36
+desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.89,15.52,21.76
+desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,123.48,106.38,141.22
+desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,32.61,27.88,36.66
+desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.75,-0.83,1.84
+desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,5.43,3.28,7.10
+desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,37.83,29.52,46.41
+desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.71,-0.11,3.04
+desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,137.46,123.10,151.37
+desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.43,10.27,18.39
+desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,106.13,82.12,132.90
+desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,57.42,50.91,63.46
+desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,33.41,28.64,37.51
+desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.93,12.76,18.63
+desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.64,15.36,21.39
+desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,73.62,65.19,81.33
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.00,9.45,14.06
+mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.38,6.10,14.61
+tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.69,16.49,22.38
+tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,36.77,31.61,41.55
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,27.91,24.09,31.24
+tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,16.71,12.25,20.97
+tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.57,10.76,15.92
+tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.48,8.90,13.61
+tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.94,9.96,17.76
+tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.25,4.02,8.03
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,44.26,31.55,58.32
+tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.49,-0.22,2.70
+tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.38,6.64,13.95
+tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,19.45,14.11,24.73
+tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.12,8.54,13.25
+tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.19,6.23,11.77
+tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,54.07,47.96,59.63
+tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,30.98,26.90,34.55
+tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,8.13,5.83,9.94
+tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.20,15.07,20.83
+tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.62,11.17,24.33
+tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.29,14.19,19.90
+tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,34.70,30.30,38.59
+tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,52.24,45.96,57.80
+tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.95,3.27,10.46
+tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,29.36,24.56,33.65
+tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.99,15.72,21.80
+tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,31.83,25.96,37.62
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,9.35,6.96,11.24
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,8.64,6.36,10.42
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,8.99,6.63,10.84
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.02,16.71,22.87
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,356.94,304.20,411.56
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,141.04,127.99,153.57
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.79,12.00,17.09
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.47,11.68,16.74
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,108.22,96.57,119.42
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,85.65,74.74,96.55
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,2.15,0.45,3.36
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,7.33,5.10,9.07
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,47.56,41.68,52.96
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,3.78,1.91,5.15
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,86.60,77.92,94.75
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,33.20,28.72,37.11
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,99.95,88.36,110.84
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.05,16.65,22.96
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,46.25,40.74,51.24
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,4.38,2.42,5.82
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.84,9.25,13.90
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,155.53,139.47,171.17
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.80,11.92,17.18
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.03,-0.55,2.11
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,36.34,28.72,43.43
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,23.73,19.62,27.35
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.87,-0.77,2.02
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,43.76,38.29,48.61
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.15,12.23,17.59
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,48.77,43.07,53.99
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,115.84,102.76,128.30
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,77.27,69.34,84.68
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,101.96,92.09,111.32
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,12.62,9.85,14.89
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,68.50,60.66,75.85
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,56.17,48.02,64.30
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.04,6.84,15.15
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,92.01,81.88,101.75
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,82.88,73.17,92.27
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,432.51,392.35,472.13
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,135.66,122.91,147.92
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,73.58,61.46,85.34
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,26.45,22.72,29.67
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,54.73,47.88,61.08
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,223.47,197.82,246.99
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,29.40,25.36,32.94
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,2.01,0.29,3.23
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.05,4.00,7.61
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.64,18.04,24.72
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,8.44,6.17,10.21
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,40.14,35.11,44.65
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.93,11.24,16.13
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.16,9.66,16.23
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,86.57,77.81,94.86
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,106.02,94.92,116.75
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.38,8.79,13.47
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.37,8.78,13.45
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,280.96,255.51,305.82
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,52.86,47.04,58.21
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,5.61,3.55,7.17
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,129.63,115.75,143.00
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,16.27,13.40,18.66
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,32.28,27.42,36.63
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.16,12.88,23.09
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,20.17,15.58,24.29
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.05,13.56,22.09
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,36.03,28.44,43.17
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,858.05,724.84,1005.62
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,483.02,404.07,564.06
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,13.39,10.34,15.96
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,44.70,35.22,53.67
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,39.01,30.71,46.85
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,47.11,38.37,55.40
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.48,-0.91,3.51
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.94,-2.08,3.77
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,49.25,41.02,56.83
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.09,-0.61,22.11
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,16.64,12.28,20.52
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,153.42,127.53,179.22
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,364.45,303.72,424.81
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.07,16.12,25.55
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,16.25,-3.53,39.35
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,5.06,-5.06,16.61
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.37,14.00,31.11
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,103.35,83.58,123.26
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,32.83,28.16,36.93
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,0.91,-0.72,2.04
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.98,14.81,20.64
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,38.23,29.19,47.75
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.71,-0.90,4.00
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,150.11,123.88,176.35
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.99,14.51,21.06
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,114.01,78.72,152.51
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,75.41,66.84,83.08
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,34.97,27.77,41.66
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,33.75,26.49,40.51
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,16.40,13.21,19.07
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,35.90,29.47,41.77
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.25,9.14,19.10
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,11.39,7.22,15.44
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,31.55,25.01,37.64
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,43.96,38.23,49.28
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,84.17,68.51,99.39
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,37.90,29.48,45.82
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,23.38,19.12,27.19
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,21.46,16.16,26.29
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,27.65,21.94,32.88
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.11,12.15,17.56
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,51.14,37.07,66.71
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,1.94,-0.20,3.71
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,10.12,6.85,12.94
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,26.54,22.10,30.53
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,14.69,11.14,17.74
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.34,18.98,25.20
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,60.50,51.83,68.65
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,39.62,31.68,47.03
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,18.85,13.37,24.08
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,22.45,19.04,25.38
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,17.13,12.32,21.91
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,15.13,12.27,17.53
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,58.91,47.81,69.46
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,69.52,57.97,80.52
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,6.88,4.63,8.64
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,40.98,32.25,49.22
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,27.16,21.16,32.63
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus4-Adreno320-Arm7-Release-25th,46.50,34.68,58.56
\ No newline at end of file
diff --git a/expectations/bench/bench_expectations_Perf-Android-Nexus7-Tegra3-Arm7-Release.txt b/expectations/bench/bench_expectations_Perf-Android-Nexus7-Tegra3-Arm7-Release.txt
index 0004fff..129ca30 100644
--- a/expectations/bench/bench_expectations_Perf-Android-Nexus7-Tegra3-Arm7-Release.txt
+++ b/expectations/bench/bench_expectations_Perf-Android-Nexus7-Tegra3-Arm7-Release.txt
@@ -1,252 +1,252 @@
-desk_amazon.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.68,10.06456,14.82044
-desk_baidu.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.17,5.83496,10.05004
-desk_blogger.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.04,8.55608,13.04892
-desk_booking.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,18.42,14.97648,21.18852
-desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,327.42,299.27208,355.06792
-desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,172.62,157.18992,187.53508
-desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.53,9.00728,13.53272
-desk_ebay.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.32,16.97296,23.17704
-desk_espn.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,79.2,71.17328,86.70672
-desk_facebook.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,49.7,44.11312,54.79188
-desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.23,0.37056,3.63444
-desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,19.03,15.95728,21.59272
-desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,50.58,44.85272,55.80728
-desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,3.89,1.84792,5.46708
-desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,104.01,93.91896,113.51104
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,35.98,31.43024,40.04976
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,71.67,64.23456,78.61044
-desk_gws.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.94,18.55384,24.83616
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,51.51,45.81896,56.69604
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,4.63,2.53848,6.23152
-desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.51,8.918,13.622
-desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,205.87,187.61832,223.64668
-desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.75,13.83976,19.15524
-desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.33,-0.3972,2.5872
-desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.61,9.07048,13.65452
-desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,22.1,18.7412,24.9588
-desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,0.87,-0.78008,2.04008
-desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,42.11,37.13032,46.59468
-desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.84,12.94184,18.24816
-desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,55.74,49.60016,61.37984
-desk_twitter.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,47.57,42.19376,52.44124
-desk_weather.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,77.9,69.98728,85.31272
-desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,103.4,93.29504,113.06496
-desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.77,13.79752,19.25248
-desk_youtube.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,18.26,15.23872,20.79628
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,67.02,60.03808,73.48692
-mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.05,10.23464,15.41036
-tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,29.21,25.27296,32.62704
-tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,28.39,24.56848,31.70152
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,183.69,167.31384,199.56616
-tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,105.57,95.53328,115.10672
-tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,56.76,50.60928,62.37072
-tabl_digg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.8,14.80544,20.28956
-tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.61,14.61,20.11
-tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,318.7,291.55248,345.36252
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,25.07,21.4832,28.1768
-tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.68,0.92504,3.94496
-tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,9.42,7.09624,11.23876
-tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.63,17.046,23.799
-tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.53,6.07608,10.52892
-tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,22.87,17.22408,28.59092
-tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.73,12.93104,18.03896
-tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,18.29,15.266,20.829
-tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.85,13.93136,19.26364
-tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,134.76,122.39744,146.64256
-tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.02,11.328,16.207
-tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.31,11.62472,16.50528
-tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,288.57,263.88408,312.73592
-tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,24.57,20.84248,27.86252
-tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,6.32,4.08312,8.09188
-tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,113.57,102.88408,123.73592
-tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.03,11.32776,16.20724
-tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,24.1,20.52136,27.19364
-desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.92,6.212,11.228
-desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.37,10.52872,15.75628
-desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.47,10.40048,15.95952
-desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,27.84,23.91064,31.31936
-desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,339.75,306.9952,370.5698
-desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,664.3,599.55832,725.72668
-desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.99,5.62912,11.73088
-desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,28.21,24.14992,31.80008
-desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,26.64,16.16872,37.64128
-desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,27.54,23.03416,31.43084
-desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.84,0.1524,3.0376
-desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,22.67,15.25016,30.43984
-desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,27.05,23.11456,30.48544
-desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,3.82,1.81248,5.37752
-desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,82.39,74.16808,90.12192
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,108.58,96.23216,120.87284
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,291.7,250.85472,333.00028
-desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.67,12.72424,20.01076
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,6.7,4.62352,8.28648
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,3.0,0.79632,4.81868
-desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.64,14.62792,20.17708
-desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,141.38,127.18776,155.39224
-desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,18.71,14.37968,22.69032
+desk_amazon.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.56,8.99472,13.61528
+desk_baidu.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,6.67,4.41472,8.48028
+desk_blogger.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,9.15,6.59552,11.28448
+desk_booking.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.58,13.55288,19.11212
+desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,356.65,317.67232,396.85768
+desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,172.32,154.88824,189.66676
+desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,10.1,7.72184,11.97316
+desk_ebay.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,19.44,16.17312,22.19188
+desk_espn.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,33.79,29.47544,37.60956
+desk_facebook.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,48.69,43.17432,53.69068
+desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.01,0.17824,3.36176
+desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.7,-0.11712,3.06212
+desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,48.43,42.80368,53.59632
+desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,3.72,1.72072,5.26928
+desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,89.18,80.2936,97.5614
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,36.78,32.18584,40.88916
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,72.93,65.21328,80.19672
+desk_gws.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,19.58,16.05168,22.67832
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.92,9.39624,13.93876
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,4.38,2.29832,5.99668
+desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,10.4,7.83608,12.49892
+desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,201.04,182.68288,218.97712
+desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.41,12.58672,17.73328
+desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.34,-0.4176,2.6126
+desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.53,9.08704,13.47796
+desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.36,17.06992,23.19008
+desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,0.79,-0.83352,1.92852
+desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,40.88,35.80784,45.48216
+desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.12,12.27936,17.47064
+desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,56.65,50.39672,62.41328
+desk_twitter.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,45.85,40.53984,50.69516
+desk_weather.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,19.06,15.9548,21.6402
+desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,30.24,25.78752,34.30248
+desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.63,11.83936,16.90564
+desk_youtube.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.46,14.50248,19.93252
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,70.2,62.55408,77.14092
+mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.29,5.48064,17.44436
+tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,28.31,24.42464,31.68036
+tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,27.34,23.61184,30.57816
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,72.84,64.95976,80.29024
+tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,30.01,25.94792,33.61208
+tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,22.55,19.1556,25.4444
+tabl_digg.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.12,14.21008,19.53992
+tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.28,13.34664,18.72336
+tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,241.42,220.41536,261.90464
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.9,18.57792,24.71708
+tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.6,0.822,3.873
+tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.49,6.2404,10.2346
+tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,18.93,15.34992,22.15008
+tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.52,6.03648,10.53352
+tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.88,17.418,23.892
+tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.25,11.52904,16.49096
+tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.66,14.666,20.174
+tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.53,13.63696,18.91804
+tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,119.84,108.46016,130.76984
+tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.02,9.488,14.047
+tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.17,9.62624,14.20876
+tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,25.99,22.19904,29.31096
+tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,23.13,19.66856,26.09644
+tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,5.19,3.03272,6.90728
+tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,19.56,16.4048,22.2152
+tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.77,10.16752,14.89248
+tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,26.84,23.09144,30.11356
+desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,7.76,5.13392,9.96608
+desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.06,8.3632,13.2668
+desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.53,8.68112,13.93888
+desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.9,18.34568,24.98432
+desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,340.93,306.3444,375.6956
+desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,650.53,593.53168,706.82832
+desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,7.59,3.21296,11.88704
+desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,24.96,21.10064,28.31936
+desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.54,16.49112,25.86888
+desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,24.72,20.8088,28.0812
+desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.83,0.14344,3.02656
+desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,0.93,-1.1964,2.6714
+desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,25.01,21.23616,28.32884
+desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,3.42,1.16584,5.06916
+desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,81.67,73.34672,89.40828
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,105.62,89.5772,121.4728
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,297.81,268.87608,326.95392
+desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.89,9.48568,15.80932
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,6.77,4.68808,8.36192
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.61,-0.28392,5.29892
+desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.22,13.25152,18.70848
+desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,143.11,127.28304,158.47696
+desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.75,13.48448,19.57552
 desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.13,-0.4604,2.2204
-desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,9.54,7.02512,11.59488
-desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,31.59,22.0432,41.3618
-desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.25,-0.48056,2.49056
-desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,164.31,147.53664,180.68336
-desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.56,8.688,16.247
-desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,137.19,123.0884,150.3866
-desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,51.27,44.5932,57.6468
-desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.77,11.44104,19.71896
-desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,31.52,27.27656,35.27344
-desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.87,13.44288,19.87212
-desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,19.66,16.02816,22.86184
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,171.5,156.12952,186.34048
-mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,27.55,18.40896,33.61604
-tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,25.29,21.57528,28.48472
-tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,101.11,90.7768,110.8582
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,90.7,81.57008,99.35492
-tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,62.38,55.2828,69.0372
-tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.76,17.2772,23.7328
-tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,9.09,6.25968,11.52532
-tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.12,8.33776,13.34224
-tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.74,10.06024,16.55976
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,26.71,21.77536,31.17464
-tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.28,-0.34248,2.40748
-tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.35,5.91992,10.34508
-tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.08,13.0004,18.7096
-tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,5.97,3.81176,7.58324
-tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.22,10.0196,16.0354
-tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.0,12.12744,17.39256
-tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,88.7,79.98336,96.90164
-tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,9.24,6.52744,11.41256
-tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,157.54,142.41856,172.21144
-tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.57,9.30312,16.72188
-tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.75,7.37736,28.07264
-tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,107.34,96.00312,118.26188
-tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,111.86,99.93392,123.54108
-tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,5.82,1.63848,9.98152
-tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.74,17.8176,25.1524
-tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.48,11.36752,17.18248
-tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,45.77,40.5068,50.5582
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.68,12.83504,18.02496
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,9.13,6.68864,11.10136
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.17,8.66568,13.17932
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.77,18.40712,24.66288
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,379.86,347.51,411.645
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,167.78,152.4944,182.6556
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,22.51,19.0488,25.4662
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.57,18.15264,24.51236
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,150.97,137.19088,164.25412
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,110.06,99.41176,120.24824
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.52,0.61704,3.97296
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,23.76,20.2688,26.7512
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,53.13,47.26864,58.49636
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,4.33,2.26224,5.95276
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,123.55,112.02464,134.56536
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,44.0,38.67632,48.80868
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,97.18,87.50352,106.32148
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,22.71,19.26264,25.66736
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,70.06,62.86416,76.75584
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,5.31,3.234,6.901
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.58,9.88256,14.80244
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,166.51,151.42672,181.15828
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.97,14.022,19.418
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.44,-0.29624,2.70624
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,54.28,48.22704,59.77296
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,23.88,20.34856,26.94144
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.0,-0.6404,2.1554
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,44.12,38.85896,48.91604
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.32,18.01328,24.15172
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,56.71,50.38168,62.54332
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,164.64,149.87784,178.90216
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,123.67,111.97472,134.89528
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,141.25,128.12752,153.90748
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.16,14.10648,19.71352
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,96.23,86.93136,105.00864
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,79.34,71.3016,86.8584
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.42,11.22344,17.20656
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,119.45,108.20264,130.17736
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,109.93,98.6792,120.8058
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,642.41,589.40624,694.91876
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,191.4,174.45656,207.85344
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,102.04,91.53184,112.21316
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,42.41,37.37656,46.93344
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,74.32,66.71368,81.42132
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,344.3,312.71432,375.99568
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,36.69,32.11384,40.80116
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.96,1.1532,4.2618
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,9.02,6.72824,10.80676
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,23.48,19.91032,26.57468
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,10.53,7.946,12.674
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,61.22,54.55056,67.43444
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.81,13.8248,19.2852
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,19.81,16.66424,22.47076
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,122.63,111.03864,133.70136
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,147.67,134.106,160.729
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.2,12.35344,17.55656
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.51,11.7788,16.7362
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,397.73,364.1892,430.8258
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,84.79,76.3052,92.7798
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,6.4,4.15704,8.17796
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,180.53,164.41712,196.11788
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,24.06,20.5648,27.0502
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,32.18,28.04464,35.83036
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,105.88,95.24608,115.95392
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.9,11.0468,16.2682
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,30.98,26.82,34.64
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,59.59,52.97032,65.68468
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,372.35,332.18376,413.05124
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,639.04,557.25112,709.96888
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,105.71,95.29832,115.66668
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,486.53,441.97936,530.36564
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,421.98,384.27288,459.14212
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,120.68,107.80056,133.16944
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.1,0.39184,3.31816
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,113.53,102.65496,123.91004
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,33.69,28.93208,38.04292
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,4.47,2.32976,6.18024
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,121.15,109.0128,132.6622
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,120.03,107.24424,132.53076
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,269.68,236.84264,298.20236
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.46,17.042,23.358
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,201.76,182.14,220.92
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,32.39,27.44504,36.66496
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,22.08,18.36024,25.34476
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,111.31,97.61664,124.24336
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.85,18.29088,24.87412
+desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,9.21,6.85216,11.09784
+desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,27.44,20.42248,32.33752
+desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.16,-0.61448,2.47948
+desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,163.12,143.42728,181.81772
+desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,9.56,6.9012,11.7938
+desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,139.11,125.49488,152.31012
+desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,48.9,41.32024,56.28976
+desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.33,8.99008,15.26992
+desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,30.13,25.94744,33.81256
+desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.77,10.63616,16.46884
+desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.74,14.61904,20.36596
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,238.26,215.03808,261.03192
+mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.03,11.32632,19.90368
+tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,28.7,24.67224,32.26276
+tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,99.78,89.17072,109.98928
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,89.57,72.11744,108.59756
+tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,62.32,55.13504,69.01996
+tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,18.73,15.35832,21.62668
+tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.43,5.1672,11.4178
+tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,10.09,6.7388,12.8862
+tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.75,10.02832,14.97668
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,23.97,20.36096,27.10404
+tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.08,-0.58712,2.26712
+tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,6.93,4.40424,8.91576
+tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.45,11.2404,17.2296
+tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,5.34,2.2236,8.2064
+tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.04,7.1708,14.7342
+tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,10.36,7.60608,12.62892
+tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,87.28,78.7068,95.3532
+tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.46,2.9248,14.2152
+tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,160.14,131.11808,192.21192
+tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,10.77,7.08184,13.99316
+tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,16.67,10.51864,22.40136
+tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,109.47,98.23392,120.35608
+tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,112.85,101.68672,123.55828
+tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,5.62,0.1244,9.6306
+tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,19.2,15.93272,22.00228
+tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.75,8.65648,14.34852
+tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,48.38,41.48592,54.76908
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,14.96,12.1528,17.2722
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.11,5.73944,10.03556
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,10.24,7.83928,12.16072
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.67,17.40552,23.43948
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,422.15,375.57832,470.11168
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,167.55,152.37424,182.27076
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.94,17.7244,23.6656
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.91,17.53608,23.78892
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,138.74,125.91912,151.07088
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,102.22,92.43136,111.51364
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.21,0.32216,3.62784
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,10.47,8.06216,12.37284
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,53.41,47.48648,58.80352
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,4.14,2.02648,5.82352
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,115.22,104.3616,125.5684
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,44.38,39.21848,49.04652
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,99.02,84.75056,110.40444
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.1,17.81088,23.91412
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,63.09,56.30032,69.43968
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,5.21,3.14264,6.79236
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,11.96,9.3416,14.1184
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,162.92,148.01432,177.35068
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.93,13.08512,18.26988
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.46,-0.31776,2.77776
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,48.98,43.44096,54.00404
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,22.92,19.52568,25.82932
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,0.92,-0.73416,2.09416
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,43.06,37.89256,47.78244
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.43,17.2144,23.1656
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,57.56,51.30416,63.33084
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,151.77,137.82728,165.19772
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,101.56,91.68384,110.97616
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,128.03,116.14696,139.40304
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,15.57,12.6632,17.9718
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,87.39,78.64648,95.67352
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,76.69,68.92368,83.96632
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,12.71,9.9916,14.9784
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,111.76,101.188,121.842
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,101.81,91.52856,111.68144
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,581.84,532.95832,630.31668
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,181.08,164.78168,196.93332
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,95.95,86.18976,105.17524
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,40.63,35.76848,44.99652
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,67.79,60.61504,74.50496
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,311.61,284.66776,338.11224
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,34.25,29.9292,38.0908
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.87,1.08,4.175
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,8.38,6.10856,10.17644
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,22.93,19.36376,26.03124
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,10.8,8.22488,12.90512
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,57.89,51.236,64.129
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.13,16.92888,22.83112
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,19.48,16.33072,22.12928
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,110.87,100.25896,120.95104
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,135.28,122.79728,147.21272
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.57,10.89352,15.74648
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.23,10.57072,15.41428
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,361.92,331.09368,392.22632
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,81.78,73.36584,89.71916
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,5.63,3.48896,7.29604
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,163.56,148.5636,178.0464
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,23.14,19.71848,26.05652
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,34.54,30.14584,38.44416
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,105.88,95.17416,116.06584
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,13.89,10.99584,16.35416
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,30.9,26.58672,34.66328
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,58.26,51.3512,64.6738
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,373.56,330.81472,417.68528
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,628.36,541.68504,702.09496
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,105.62,94.85016,115.93484
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,490.05,448.63112,530.94388
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,422.34,386.21192,458.01808
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,120.84,108.50896,132.75604
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,2.1,0.41192,3.29308
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.11,-0.50864,2.21364
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,34.31,29.84336,38.28664
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,4.95,2.87208,6.57292
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,123.12,111.5184,134.2166
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,120.7,108.038,133.122
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,276.94,237.97712,309.84788
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,20.47,17.10096,23.37404
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,195.83,177.85976,213.32024
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,31.73,27.58048,35.38452
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.74,18.21904,24.74096
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,112.78,98.65352,125.86148
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,21.68,18.29368,24.58132
 desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.22,-0.3776,2.3176
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,259.02,236.48648,281.06352
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,33.92,27.96032,39.49968
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.3,-0.38464,2.50464
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,167.59,150.2932,184.2618
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,84.1,74.5544,93.0456
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,142.1,120.94192,159.40808
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,425.0,386.7996,462.0454
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,329.54,300.53248,358.12752
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,286.83,260.31648,312.79352
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,18.02,14.81656,20.74344
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,159.19,141.89744,175.52756
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,186.4,169.20904,202.74596
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,28.12,20.04592,36.74408
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,204.04,184.0256,222.8194
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,250.86,227.80648,273.44352
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1114.25,1020.50672,1206.75828
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,532.45,485.90768,578.53732
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,217.47,197.67288,236.74212
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,201.38,183.02184,219.24316
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,81.27,72.34616,89.51884
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,193.62,176.41792,210.30708
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,105.86,94.41512,116.51988
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.53,-0.2136,2.8036
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,53.41,47.27192,59.09308
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,26.2,22.1016,29.8334
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,58.09,51.49792,64.15708
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,279.63,255.22208,303.60292
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,66.56,59.4436,73.1364
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,194.78,174.27704,214.70796
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,179.24,162.80536,195.16464
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,247.2,222.45112,271.27388
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,45.73,40.0236,50.9814
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,45.92,40.0576,51.3174
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,217.05,197.01616,236.46884
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,480.05,439.21816,520.29684
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,7.29,4.934,9.191
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,165.66,149.73056,180.95444
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,115.02,103.11296,126.41204
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,79.7,71.11808,87.77692
\ No newline at end of file
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,260.5,237.97888,282.52112
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,39.89,32.51176,45.57324
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.22,-0.5888,2.5588
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,168.27,145.37952,188.43048
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,83.1,73.89928,91.74572
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,144.39,119.2692,163.8858
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,414.45,373.97904,453.90596
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,304.72,277.8824,331.0926
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,279.11,253.4712,304.0688
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,17.41,14.25552,20.08448
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,156.22,141.84936,170.07064
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,249.97,228.192,271.183
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,28.04,22.06912,34.04088
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,206.5,187.904,224.581
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,249.67,227.47288,271.32212
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1102.66,1011.59472,1193.33528
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,526.18,481.5456,570.4144
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,214.61,195.2048,233.5852
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,201.93,183.60696,219.49304
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,81.03,72.26288,89.17712
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,193.41,174.93744,211.14756
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,106.69,94.55696,118.43804
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,1.52,-0.1824,2.7424
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,53.26,47.12648,58.87352
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,25.42,21.55,28.85
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,58.24,51.6744,64.3606
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,278.68,222.21848,342.48152
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,92.19,82.90368,100.87632
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,197.12,176.59464,217.74536
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,179.13,162.70584,194.99916
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,245.06,220.69752,269.38748
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,45.83,40.3112,50.9138
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,45.84,39.93728,51.17772
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,223.27,203.47368,242.60632
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,476.41,433.52336,518.28164
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,6.72,3.60736,9.21764
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,169.05,152.63536,184.94964
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,115.49,104.0968,126.3432
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Android-Nexus7-Tegra3-Arm7-Release-25th,85.02,76.16416,93.44584
\ No newline at end of file
diff --git a/expectations/bench/bench_expectations_Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release.txt b/expectations/bench/bench_expectations_Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release.txt
deleted file mode 100644
index a95d6e4..0000000
--- a/expectations/bench/bench_expectations_Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release.txt
+++ /dev/null
@@ -1,252 +0,0 @@
-desk_amazon.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.94,1.96344,5.45656
-desk_baidu.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.11,1.19032,4.54968
-desk_blogger.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.84,1.952,5.248
-desk_booking.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.98,3.94104,7.53396
-desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,116.21,105.11976,126.85024
-desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,53.53,39.99352,68.13648
-desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.84,1.99224,5.19776
-desk_ebay.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.31,6.86424,11.26076
-desk_espn.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,21.18,17.79336,24.09164
-desk_facebook.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,13.97,11.20088,16.25412
-desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.52,-0.142,2.692
-desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.89,3.86832,7.40168
-desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,16.03,12.99656,18.55844
-desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.98,0.23128,3.22872
-desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,30.92,26.73488,34.63512
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.95,7.52336,11.88664
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,20.66,17.41648,23.40352
-desk_gws.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.49,4.44096,8.02404
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,14.54,11.78648,16.79352
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,2.08,0.37288,3.29712
-desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.53,2.62728,5.94272
-desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,71.39,63.96616,78.34384
-desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.83,3.71296,7.46204
-desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.4,-0.30216,2.60216
-desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.75,3.63904,7.37596
-desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.52,4.24816,10.58184
-desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.22,-1.2976,1.2376
-desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,14.9,11.74904,17.35096
-desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.73,3.59008,7.41492
-desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,18.48,15.39056,21.07444
-desk_twitter.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,12.51,9.9388,14.5762
-desk_weather.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,21.55,18.21512,24.38988
-desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,59.77,53.13544,65.92456
-desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.95,3.8536,7.5314
-desk_youtube.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.14,4.07832,7.69668
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,24.96,21.332,28.098
-mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.91,4.65536,8.71464
-tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,10.1,7.66128,12.04872
-tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.51,6.25888,10.25612
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,49.15,43.52648,54.25352
-tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,29.8,24.92168,34.40332
-tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,16.93,13.88552,19.40948
-tabl_digg.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.23,3.2512,6.7238
-tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.03,3.07752,6.47248
-tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,91.98,76.20056,108.82444
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.86,5.59064,9.61936
-tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.32,-1.2056,1.3456
-tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.64,1.79888,4.97112
-tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.13,4.84832,8.94168
-tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.75,1.79952,5.21548
-tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.74,4.57984,8.43016
-tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.82,2.87384,6.28116
-tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.97,3.01136,6.44364
-tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.59,3.58216,7.11284
-tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,34.36,29.9808,38.2492
-tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.29,2.39672,5.67328
-tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.38,2.46904,5.80596
-tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,90.43,78.26352,102.09648
-tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.97,7.55168,11.87332
-tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,2.94,1.18456,4.20044
-tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,34.14,29.6464,38.1986
-tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.07,2.15424,5.48576
-tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.2,6.76176,11.18824
-desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,2.94,0.20616,5.39884
-desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.09,1.38304,6.02196
-desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.42,1.1528,5.2872
-desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.84,4.5012,8.6388
-desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,136.08,111.58104,162.66396
-desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,184.12,163.188,205.182
-desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,2.51,0.74848,3.78652
-desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,18.3,-44.1332,94.7032
-desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,10.2,4.54456,16.16044
-desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,13.16,4.09192,23.30808
-desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.6,-1.486,2.296
-desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.77,0.6564,15.5736
-desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,13.6,-8.89672,40.47672
-desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.4,-0.3028,2.6028
-desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,23.82,12.27176,36.81324
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,34.24,25.96888,42.60612
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,102.3,91.88392,112.01608
-desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.81,2.01168,7.26832
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.6,0.08176,11.48324
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.31,-0.63128,2.81128
-desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.12,-3.47904,14.88404
-desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,68.48,12.44432,135.91068
-desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,11.99,5.18816,18.91684
-desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.08,-1.4264,1.0864
-desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.3,2.0944,6.0956
-desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.2,5.76232,10.16268
-desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.28,-0.39288,2.44788
-desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,42.44,9.89,81.155
-desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,11.73,-32.0336,65.2336
-desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,39.35,26.84368,52.43132
-desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,23.92,5.89656,44.85344
-desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.81,-5.84568,23.79568
-desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,16.31,-13.86632,52.56132
-desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.57,0.9724,16.9626
-desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.25,-26.76088,53.10588
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,30.11,13.4372,49.4278
-mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.08,6.61016,11.10984
-tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,15.29,5.54312,25.88688
-tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,27.54,16.1824,36.3476
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,27.1,-18.8292,82.0642
-tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,14.74,9.95448,19.52552
-tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.84,3.74776,14.12224
-tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.44,-8.8292,22.2042
-tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.48,-5.22072,15.60572
-tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.68,-0.7724,17.1824
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.83,4.97296,14.77704
-tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.77,-1.1944,2.3344
-tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,2.79,0.91608,4.13392
-tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.87,2.05544,11.84956
-tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.71,-29.556,44.041
-tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.35,-1.32216,19.31216
-tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.28,-0.04504,13.11004
-tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,41.13,-10.19896,102.81396
-tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.25,1.39976,4.60024
-tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,27.78,15.53184,40.81316
-tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.24,0.51584,7.34916
-tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.66,3.27424,7.63076
-tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,40.97,12.9636,74.2114
-tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,36.92,28.2948,45.3102
-tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.83,-0.39136,3.53636
-tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.19,3.1552,8.9598
-tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.17,-8.322,18.792
-tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,12.1,-19.5028,50.3978
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,23.95,18.30232,29.58268
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.08,1.31344,4.35156
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.86,1.97056,5.26944
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.93,4.83512,8.53488
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,140.42,127.3536,153.0464
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,57.43,50.41632,64.01368
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.01,2.12864,5.40636
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.0,6.65808,10.87192
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,40.06,35.12416,44.53084
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,29.84,24.414,35.101
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.76,0.05856,2.97644
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.84,4.74248,8.42752
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,17.55,14.5352,20.0698
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,2.24,0.5404,3.4446
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,37.29,32.69576,41.38924
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,12.58,9.92256,14.75244
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,28.26,24.40808,31.61192
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.54,5.41664,9.16836
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,19.24,16.14024,21.85476
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,2.4,0.65784,3.63216
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.71,2.8128,6.1122
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,57.83,51.50136,63.66364
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.71,3.672,7.268
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.63,-0.0408,2.8108
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,17.76,14.72792,20.29708
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.11,5.79032,9.94968
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.23,-1.2884,1.2484
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,15.86,13.00056,18.21944
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,21.68,17.32984,25.78516
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,18.93,15.85464,21.52036
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,48.29,36.40784,61.24716
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,32.68,28.40392,36.45108
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,80.74,71.37888,89.92612
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.09,4.0124,7.6676
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,26.88,23.07896,30.15104
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,29.41,25.38528,32.95472
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.4,5.09728,9.23272
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,37.34,31.98768,42.40732
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,30.67,26.3848,34.5152
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,176.58,159.57616,193.35884
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,46.93,41.43352,51.94148
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,29.81,25.19224,34.08776
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.28,1.8156,8.6044
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,20.87,17.41888,23.75612
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,98.27,88.30832,107.85668
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.4,6.16712,10.14788
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.34,-1.20768,1.39268
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.54,1.68656,4.88844
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.37,6.15016,10.07984
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.3,2.38584,5.70916
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,22.63,19.24928,25.50572
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.8,2.87552,6.23448
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.24,3.21936,6.78564
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,35.01,30.47808,39.07692
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,38.79,32.68248,44.74252
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,4.11,2.26096,5.46404
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.78,1.92728,5.12272
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,117.8,106.26192,128.87808
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,10.32,7.91336,12.24664
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,2.87,1.0596,4.2004
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,49.92,43.7712,55.6638
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.18,3.20456,6.67044
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.96,7.57272,11.84728
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,18.06,14.07456,21.73544
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,3.83,-0.98064,8.86064
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.55,4.34496,8.21004
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,14.96,11.73072,17.57428
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,155.4,131.03032,181.11968
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,185.67,167.83472,202.90028
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,16.79,-46.75984,94.92484
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,93.13,79.9996,106.7754
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,74.0,64.75312,82.01188
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,28.43,19.5484,38.0366
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.54,-1.03304,1.59804
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,23.65,18.81888,28.31612
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,14.71,8.22408,21.48592
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.44,-0.21568,2.60568
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,29.17,-24.85384,95.16384
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,37.57,29.0624,46.3476
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,70.08,25.52024,118.65976
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.1,3.68352,10.35148
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,30.61,12.93456,51.15044
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,5.52,0.8972,10.3078
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,6.8,0.84512,13.20488
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,55.67,10.57272,106.26228
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,7.62,4.86944,9.96056
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.08,-1.46656,1.13656
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,45.94,-9.954,113.929
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.96,6.39184,11.09316
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.75,-0.90088,1.90088
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,42.73,11.46856,79.94644
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,16.15,-33.70064,77.14064
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,40.89,33.25064,48.46936
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,80.09,32.48264,136.98736
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,55.13,29.53144,85.08356
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,81.9,71.12504,92.82996
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.66,5.20824,14.08676
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,28.72,-2.87928,64.51428
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,32.59,21.53504,44.61996
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.49,6.91768,11.61732
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,48.81,29.578,66.267
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,50.61,35.39848,67.50152
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,198.99,168.15016,232.50484
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,78.93,66.72736,91.61264
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,37.62,30.68856,44.53644
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,35.89,29.15648,42.64352
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,16.33,12.8884,19.4066
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,36.38,-20.05968,105.24468
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,23.12,19.29344,26.54156
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,0.89,-0.74168,2.03668
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,10.3,7.6936,12.4764
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,8.07,5.47008,10.25992
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,11.79,-43.16304,79.13804
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,55.64,36.24208,68.70292
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,15.63,2.82112,30.36388
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,63.51,39.46616,90.02884
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,28.78,24.492,32.688
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,41.99,36.25536,47.37464
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.57,5.4596,12.4954
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,9.31,6.63104,11.57396
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,95.83,85.62976,105.40524
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,90.24,70.70456,111.86044
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,1.63,-0.4028,3.2628
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,30.67,9.51496,55.41504
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,22.12,10.58392,35.16108
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Mac10.8-MacMini4.1-GeForce320M-x86-Release-25th,20.89,16.41952,24.93548
\ No newline at end of file
diff --git a/expectations/bench/bench_expectations_Perf-Ubuntu12-ShuttleA-GTX660-x86-Release.txt b/expectations/bench/bench_expectations_Perf-Ubuntu12-ShuttleA-GTX660-x86-Release.txt
index c968e04..8f4dfe8 100644
--- a/expectations/bench/bench_expectations_Perf-Ubuntu12-ShuttleA-GTX660-x86-Release.txt
+++ b/expectations/bench/bench_expectations_Perf-Ubuntu12-ShuttleA-GTX660-x86-Release.txt
@@ -1,252 +1,252 @@
-desk_amazon.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.99,-0.62976,2.11976
-desk_baidu.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.9,-0.69208,1.99708
-desk_blogger.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.02,-0.58216,2.12716
-desk_booking.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.01,0.2992,3.2108
-desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,48.5,41.00856,56.01644
-desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,26.53,22.36528,30.28472
-desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.38,-0.25056,2.51556
-desk_ebay.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.47,0.75216,3.69284
-desk_espn.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,10.03,7.67728,11.87272
-desk_facebook.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.85,2.91184,6.27816
-desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.21,-1.32688,1.25188
-desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.14,0.42832,3.36168
-desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,5.24,3.30056,6.68444
-desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.65,-0.92216,1.72716
-desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,13.4,10.6772,15.6378
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.23,1.45104,4.51396
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,8.83,6.55328,10.60172
-desk_gws.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.33,0.62344,3.54156
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,7.11,4.9912,8.7188
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.44,-1.0952,1.4752
-desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.41,-0.22328,2.54828
-desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,30.68,26.5948,34.2752
-desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.79,0.10648,2.98352
-desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.15,-1.38224,1.18724
-desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.39,-0.26184,2.55184
-desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.46,0.74296,3.68204
-desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.09,-1.43752,1.12252
-desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,6.8,4.7356,8.3694
-desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.68,0.00504,2.86496
-desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.39,7.078,11.217
-desk_twitter.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.03,2.11728,5.44272
-desk_weather.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,10.38,7.97936,12.27564
-desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,28.76,24.86872,32.15128
-desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.76,0.09896,2.92604
-desk_youtube.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.53,-0.15272,2.72772
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.16,6.84616,10.99384
-mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.35,-0.30824,2.49824
-tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.74,0.91032,4.07468
-tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.5,0.7396,3.7754
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,21.21,17.82224,24.12276
-tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.7,11.91344,16.99156
-tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,6.91,4.78688,8.52812
-tabl_digg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.91,0.0352,3.3398
-tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.44,-0.21536,2.60536
-tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,43.0,37.0644,48.6606
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.88,1.10912,4.16088
-tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.61,-0.9388,1.6588
-tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.81,-0.77504,1.90004
-tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.72,0.98224,3.96276
-tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.96,-0.63688,2.06188
-tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.17,1.36648,4.46352
-tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.37,-0.26,2.505
-tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.32,-0.32592,2.47592
-tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.54,-0.12352,2.71352
-tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,16.83,13.92296,19.25204
-tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.32,-0.30592,2.45092
-tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.26,-0.36088,2.38588
-tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,42.57,37.49336,47.16664
-tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.69,1.79416,5.11084
-tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.7,-0.87608,1.78108
-tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,16.22,13.33192,18.60808
-tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.35,-0.27808,2.48308
-tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.47,1.6424,4.7876
-desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.82,-0.76584,1.91084
-desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.48,-0.15888,2.62388
-desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.24,-0.3996,2.3896
-desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.37,0.58992,3.65008
-desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,36.54,29.93744,43.11756
-desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,57.68,50.962,63.958
-desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.69,-0.93544,1.81044
-desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.02,-0.60208,2.15208
-desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.16,0.44664,3.38336
-desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.12,0.43,3.315
-desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.05,-1.47408,1.07908
-desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.6,0.87184,3.83316
-desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.79,0.97632,4.10368
-desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.41,-1.15272,1.45772
-desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.58,-0.11712,2.77212
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,12.88,10.14792,15.11708
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,26.75,22.90912,30.05088
-desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.47,-0.41856,2.90356
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.14,-1.41144,1.20144
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.21,-1.38816,1.32816
-desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.52,-0.1516,2.6816
-desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.72,11.8212,17.1288
-desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.34,0.25064,4.02936
+desk_amazon.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.92,-0.69384,2.04384
+desk_baidu.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.76,-0.84128,1.87128
+desk_blogger.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.93,-0.68464,2.05464
+desk_booking.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.92,0.2164,3.1136
+desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,47.71,40.03824,55.10676
+desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,26.65,22.9372,29.8828
+desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.25,-0.37032,2.37532
+desk_ebay.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.37,0.63984,3.61016
+desk_espn.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.11,1.3004,4.4346
+desk_facebook.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.85,2.70904,6.53096
+desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.21,-1.3068,1.2268
+desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.07,-1.4356,1.0756
+desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,5.24,3.28032,6.70968
+desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.64,-0.95136,1.74136
+desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,12.8,10.2356,14.8744
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.29,1.50648,4.57852
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,8.95,6.7136,10.6914
+desk_gws.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.18,0.46528,3.40472
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.73,-0.84856,1.81356
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.42,-1.15408,1.50408
+desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.37,-0.25984,2.50484
+desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,31.34,26.78928,35.52572
+desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.73,0.0712,2.8938
+desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.15,-1.38208,1.18708
+desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.38,-0.25096,2.51596
+desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.37,0.64,3.61
+desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.09,-1.43736,1.12236
+desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,6.89,4.77816,8.51684
+desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.53,-0.11248,2.67748
+desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.49,7.1808,11.2892
+desk_twitter.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.94,2.0548,5.3202
+desk_weather.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.23,-0.4088,2.3788
+desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.06,1.25448,4.38052
+desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.63,-0.02048,2.78548
+desk_youtube.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.47,-0.2284,2.6884
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.18,6.86472,11.01528
+mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.25,-0.39992,2.38992
+tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.71,0.92312,3.99188
+tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.43,0.65464,3.72536
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.91,2.97664,6.35336
+tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.04,1.22656,4.34844
+tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.58,-0.10688,2.78188
+tabl_digg.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.91,0.23704,3.08796
+tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.36,-0.28936,2.51936
+tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,35.84,31.41232,39.78268
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.66,0.85696,3.96304
+tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.6,-0.96808,1.67308
+tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.74,-0.8596,1.8496
+tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.69,0.93432,3.95568
+tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.01,-0.59096,2.11596
+tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.66,0.92688,3.89812
+tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.27,-0.35176,2.39676
+tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.28,-0.36256,2.43256
+tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.5,-0.19024,2.68524
+tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,16.7,13.79376,19.10124
+tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.19,-0.4052,2.2852
+tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.15,-0.492,2.282
+tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.5,0.67848,3.85152
+tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.57,1.73432,4.89568
+tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.62,-0.95,1.695
+tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.9,0.22752,3.07748
+tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.16,-0.47312,2.30312
+tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.45,1.60392,4.79108
+desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.75,-0.83024,1.83524
+desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.23,-0.38896,2.35396
+desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.12,-0.62,2.33
+desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.17,0.45608,3.39392
+desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,36.71,30.53464,42.79536
+desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,57.75,51.40864,63.55636
+desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.56,-1.00488,1.62988
+desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.93,-0.66472,2.02972
+desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.94,0.26448,3.12052
+desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.01,-0.41432,4.12432
+desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.05,-1.454,1.054
+desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.03,-1.4724,1.0324
+desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.68,0.89504,3.95996
+desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.39,-1.16128,1.44628
+desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.55,-0.0944,2.6994
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,13.42,10.27416,16.14084
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,25.31,21.63368,28.50132
+desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.24,-0.66056,2.71556
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.14,-1.41136,1.20136
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.2,-1.37696,1.29196
+desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.41,-0.25272,2.56272
+desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.62,11.78904,16.99096
+desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.25,0.51976,3.47024
 desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.01,-1.4908,1.0108
-desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.38,-1.24096,1.50096
-desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.03,1.26744,4.29756
-desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.12,-1.40968,1.15468
-desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,18.58,15.172,21.548
-desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.04,-0.96512,2.65012
-desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.61,11.67792,17.06208
-desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.07,1.76184,5.99816
-desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.48,-0.5604,3.1254
-desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.75,-0.36312,3.45812
-desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.85,0.12112,3.09888
-desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.27,0.39688,3.66812
+desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.35,-1.25896,1.47896
+desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.89,1.12888,4.13612
+desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.12,-1.67072,1.48072
+desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,18.62,15.42896,21.31604
+desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.93,-1.06656,2.53156
+desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.55,11.6028,17.0222
+desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.86,1.62864,5.69636
+desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.21,-0.46736,2.40736
+desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.54,-0.55464,3.18464
+desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.67,-1.12856,4.25856
+desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.16,0.4372,3.3728
 desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.38,-1.1504,1.4104
-mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.9,-1.79048,3.34548
-tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.64,-0.01128,2.79628
-tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.59,0.822,3.873
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.74,-0.9,1.9
-tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.96,-0.6668,2.0768
-tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.06,-0.6156,2.2356
-tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.76,-0.84144,1.87144
-tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.14,-0.5012,2.2712
-tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.26,-1.30104,1.33104
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.88,1.03936,4.22564
-tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.13,-1.44072,1.21572
-tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.71,-0.9876,1.9426
-tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.94,0.04376,3.39624
-tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.47,-1.08768,1.53268
-tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.91,-1.16592,2.61092
-tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.68,-0.4768,3.4668
-tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.93,-0.71528,2.07028
-tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.69,-1.08632,2.02132
-tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.9,-0.7324,2.0474
-tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.46,-0.288,2.718
-tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.82,0.04216,3.10784
-tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.55,-0.51648,3.22648
-tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.77,0.08768,2.96232
-tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.67,-0.90368,1.74868
-tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.74,-0.01992,2.98492
-tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.34,-0.28744,2.47244
-tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.22,1.36104,4.60396
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.1,0.39144,3.31856
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.22,-0.39784,2.34284
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.11,-0.49904,2.22404
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.61,0.84048,3.89452
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,56.4,49.77552,62.60948
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,25.28,21.65648,28.42852
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.48,2.6012,5.8638
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.48,0.74104,3.72896
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,19.55,16.3956,22.2044
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,12.91,10.2668,15.0582
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.23,-1.30856,1.27356
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.51,1.6792,4.8308
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,5.72,3.722,7.228
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.75,-0.83016,1.83516
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,16.19,13.32416,18.55084
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.07,2.20408,5.44592
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,11.85,9.33168,13.86332
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.45,0.73368,3.67132
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,8.65,6.38752,10.40748
+mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.69,-1.96456,3.09456
+tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.5,-0.16032,2.67032
+tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.55,0.63528,3.99472
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.71,-0.92736,1.86736
+tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.87,-0.74,1.99
+tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.99,-0.6592,2.1342
+tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.72,-0.85776,1.80276
+tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.03,-0.64248,2.20248
+tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.26,-1.6628,1.7828
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.72,0.912,4.028
+tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.13,-1.40048,1.16548
+tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.62,-1.13072,1.92072
+tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.85,0.1212,3.0988
+tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.57,-0.996,1.641
+tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.85,-1.6916,3.0666
+tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.15,-0.79312,2.65812
+tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.9,-0.69216,1.99716
+tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.61,-0.95888,1.68388
+tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.87,-0.90072,2.19072
+tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.21,-0.41672,2.32172
+tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.65,-0.03216,2.82216
+tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.45,-1.09976,3.70976
+tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.62,-0.0904,2.8504
+tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.57,-0.99576,1.64076
+tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.58,-0.12736,2.80736
+tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.18,-0.48488,2.33988
+tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.96,1.11256,4.31244
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.03,0.32736,3.24264
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.13,-0.52088,2.29588
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.09,-0.51752,2.20252
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.58,0.83328,3.83672
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,55.85,47.25776,64.36724
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,25.52,21.546,29.079
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.44,2.56472,5.82028
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.39,0.67856,3.60644
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,19.31,16.22464,21.90536
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,13.41,10.79656,15.53344
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.23,-1.2884,1.2484
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.86,-0.7088,1.9288
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,5.71,3.68312,7.23188
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.74,-0.83936,1.82436
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,16.45,13.54336,18.85664
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.09,2.24248,5.44252
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,12.04,9.46624,14.11876
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.38,0.66936,3.59564
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,8.9,6.61776,10.67724
 desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.49,-1.06928,1.55428
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.63,-0.02048,2.78548
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,24.72,21.1816,27.7734
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.75,0.08984,2.91516
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.64,-0.0116,2.7966
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,25.22,21.6416,28.3134
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.74,0.06032,2.92968
 desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.17,-1.3436,1.1836
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,6.79,4.6456,8.4594
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.77,1.00792,4.04208
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,6.69,4.59392,8.30108
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.75,0.94904,4.07096
 desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.11,-1.3988,1.1188
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,7.25,5.14952,8.85548
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.76,1.91856,5.11144
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.52,7.21768,11.33232
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,20.75,17.50872,23.51128
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,16.17,12.98448,18.93052
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,36.02,31.43728,40.10772
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.77,0.10792,2.93708
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,12.51,9.94832,14.58668
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,11.05,8.62544,12.98456
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.49,-0.1792,2.6492
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,16.03,13.19736,18.35264
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,13.81,11.00344,16.12156
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,81.63,73.16824,89.63176
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,32.65,28.38648,36.42852
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,13.47,10.79144,15.67356
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.6,7.29152,11.41848
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.47,7.11136,11.35364
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,44.98,38.686,51.049
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,6.59,4.5128,8.1572
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.67,-0.90408,1.74908
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.75,-0.88,1.875
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.87,1.12032,4.12468
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.28,-0.3428,2.4078
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,16.29,13.446,18.644
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.89,0.21872,3.06628
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.44,-0.19528,2.58028
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,15.85,13.01176,18.18324
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,19.05,15.65376,22.01624
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.84,0.17264,3.01236
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.12,0.42992,3.31508
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,53.1,47.26144,58.43856
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,22.35,17.83712,26.64288
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.7,-0.87624,1.78124
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,24.99,21.38016,28.10484
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.45,2.57384,5.83116
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,5.92,3.90568,7.44432
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.81,-0.77488,1.89988
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.39,-0.24176,2.52676
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.16,-0.61376,2.47876
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.32,0.59416,3.55584
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,38.02,31.69096,44.20404
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,59.41,52.88424,65.48076
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.64,-0.96136,1.73136
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.14,-0.53136,2.28636
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.14,0.4188,3.3512
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.44,0.6948,3.6752
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.06,-1.4448,1.0648
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.64,0.85856,3.91644
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.94,0.58232,4.95268
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.48,-1.07848,1.54348
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.3,-0.32416,2.42916
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.26,11.53808,16.50192
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,22.15,18.44456,25.44044
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.34,-0.30768,2.49768
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.37,-1.5412,1.8762
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.23,-1.30848,1.27348
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.56,-0.09472,2.69972
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,11.49,8.9,13.6
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.15,0.45776,3.34724
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,7.3,5.17528,8.93472
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.64,1.80824,4.98176
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.68,7.33536,11.51964
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,20.7,17.47328,23.42172
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.72,11.98192,16.97308
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,36.3,31.82568,40.26932
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.74,0.05088,2.91912
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,12.31,9.19352,15.08148
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,11.11,8.67104,13.03896
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.44,-0.21592,2.60592
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,16.29,13.09464,19.06036
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,13.76,11.03728,16.01272
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,80.49,72.4004,88.0496
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,32.48,28.3208,36.1542
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,13.43,10.5932,15.7868
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.64,6.64152,12.31848
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,9.61,7.2604,11.4796
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,45.51,40.2788,50.2412
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,6.39,4.2572,8.0528
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.67,-0.9336,1.7636
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.75,-0.88008,1.87508
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.82,1.07384,4.07116
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.37,-0.34136,2.60636
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,15.88,13.06888,18.20112
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.33,1.52296,4.64704
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.42,-0.21376,2.55876
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,15.86,12.98096,18.24404
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,18.82,15.70392,21.44108
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.77,0.108,2.937
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.06,0.35464,3.27536
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,53.92,46.91392,60.72108
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,22.44,19.07456,25.30044
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.69,-0.91512,1.78512
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,24.84,20.97,28.26
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,4.3,2.4156,5.6944
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,5.93,3.89528,7.47972
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.74,-0.83936,1.82436
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.21,-0.41664,2.32164
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.1,-0.78936,2.56436
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.16,0.366,3.484
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,38.01,31.81128,44.05372
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,52.74,45.46352,59.83648
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.57,-0.99584,1.64084
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.05,-0.59456,2.20956
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.99,-0.01072,3.57572
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.37,0.06792,4.30208
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.05,-1.47408,1.07908
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.03,-1.4724,1.0324
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.86,1.10128,4.10372
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.51,-1.15128,1.70128
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.28,-0.3428,2.4078
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.09,11.342,16.323
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,23.0,19.55904,25.96596
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.21,-0.40696,2.33196
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.37,-1.17968,1.42468
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.22,-1.31776,1.26276
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.5,-0.14024,2.64524
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,11.52,8.92728,13.63272
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.13,0.43936,3.32564
 desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.01,-1.4908,1.0108
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.5,-1.06008,1.56508
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.87,1.04944,4.19056
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.11,-1.41904,1.14404
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,19.12,15.94888,21.82612
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.01,-0.66096,2.18096
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.78,12.0368,17.0382
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.83,1.12968,6.23032
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.16,-0.5132,2.3532
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.51,-0.1912,2.7312
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.64,-0.12176,2.91176
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.66,-0.24384,3.10884
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.4,-1.15216,1.45716
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.82,-1.84328,3.18828
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.58,-0.0964,2.7464
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.55,0.78456,3.83044
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.09,-0.15616,3.62116
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.52,-1.0216,1.5616
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.75,0.91888,4.08612
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.11,-1.41896,1.14396
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,19.2,15.83152,22.08348
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.95,-0.66616,2.07616
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,14.61,11.87104,16.84396
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.69,1.35152,5.61848
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.93,-0.70536,2.08036
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.38,-0.66208,3.00708
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.54,-0.12352,2.71352
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.59,-0.4188,3.1938
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.41,-1.1228,1.4428
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.69,-1.93408,3.03408
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.52,-0.12216,2.66716
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.56,0.63392,3.99608
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.05,0.06632,3.43368
 tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.96,-0.6168,2.0368
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.08,-0.57688,2.23188
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.75,-0.81,1.81
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.53,-0.1928,2.7778
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.03,-0.64296,2.20296
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.69,-0.88528,1.77028
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.45,-0.18632,2.59132
 tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.5,-1.14048,1.66548
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.96,1.20296,4.22204
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.17,-1.80552,1.76052
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.53,-1.03256,1.59756
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.13,0.29864,3.50136
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.43,-1.12448,1.48948
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.91,-1.44648,2.96148
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.25,-0.3704,2.3754
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.96,-0.63688,2.06188
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.66,-0.93336,1.76336
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.98,-1.29088,2.90088
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.19,-0.42528,2.31028
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.52,-0.42296,3.04296
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.59,-0.53952,3.34452
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.69,-0.07512,2.92012
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.62,-0.97032,1.72032
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.73,-0.35984,3.36484
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.3,-0.32424,2.42924
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.65,1.81728,4.99272
\ No newline at end of file
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.85,1.08144,4.12856
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.19,-1.3456,1.2306
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.49,-1.06944,1.55444
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,2.04,0.20568,3.39432
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.55,-1.01416,1.61916
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.87,-1.60344,3.06844
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.15,-1.36592,3.39592
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.91,-0.68336,2.00836
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.62,-0.94984,1.69484
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.95,-0.64648,2.05148
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.06,-0.686,2.346
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.43,-0.69624,3.16124
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.52,-0.83456,3.53456
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.64,-0.30088,3.00088
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,0.57,-0.99616,1.64116
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.6,-0.55136,3.38136
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,1.19,-0.42536,2.31036
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Ubuntu12-ShuttleA-GTX660-x86-Release-25th,3.39,1.22672,5.12828
\ No newline at end of file
diff --git a/expectations/bench/bench_expectations_Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE.txt b/expectations/bench/bench_expectations_Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE.txt
index b01565e..87b7d83 100644
--- a/expectations/bench/bench_expectations_Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE.txt
+++ b/expectations/bench/bench_expectations_Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE.txt
@@ -1,63 +1,63 @@
-desk_amazon.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.67,-0.31656,3.22156
-desk_baidu.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.88,-0.25456,3.54456
-desk_blogger.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.66,-0.65664,3.60164
-desk_booking.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.18,0.42344,5.41656
-desk_carsvg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,52.88,37.90824,68.14176
-desk_chalkboard.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,183.31,153.53112,214.87388
-desk_css3gradients.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.6,-0.11896,2.81896
-desk_ebay.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,4.1,-2.18984,10.80984
-desk_espn.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.99,1.0596,4.4454
-desk_facebook.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.77,1.60424,5.48076
+desk_amazon.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.71,-0.34912,3.32912
+desk_baidu.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.72,-0.70416,3.79416
+desk_blogger.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.6,-0.75336,3.63336
+desk_booking.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.09,0.88928,4.88072
+desk_carsvg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,54.38,42.92448,66.29052
+desk_chalkboard.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,191.85,164.75664,220.26836
+desk_css3gradients.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.54,-0.2244,2.8394
+desk_ebay.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,4.2,-2.15624,10.85624
+desk_espn.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.03,1.11592,4.46408
+desk_facebook.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.85,1.67952,5.52048
 desk_fontwipe.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.32,-1.22576,1.37076
-desk_forecastio.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.48,1.47024,5.02476
-desk_gmailthread.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.92,1.784,5.591
-desk_googlehome.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.68,-0.99576,1.88576
-desk_googleplus.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,5.22,1.51544,8.79956
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,32.95,27.88792,37.56208
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,39.62,33.26048,45.60452
-desk_gws.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.92,0.10392,3.27608
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.67,-0.54304,3.45804
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.78,-0.8832,1.9682
-desk_linkedin.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.06,0.24368,3.39132
-desk_mapsvg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,31.77,25.79088,37.21412
-desk_mobilenews.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.69,0.75376,4.13624
+desk_forecastio.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.23,-1.30872,1.27372
+desk_gmailthread.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.56,1.40208,5.19792
+desk_googlehome.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.64,-1.01344,1.81844
+desk_googleplus.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,5.35,3.18184,6.98816
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,34.12,28.85344,38.76156
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,38.48,32.26696,44.28304
+desk_gws.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.83,-0.00832,3.19332
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.93,-0.3436,3.4536
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.78,-0.89344,1.95844
+desk_linkedin.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.02,0.2076,3.3474
+desk_mapsvg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,33.37,23.6072,43.7528
+desk_mobilenews.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.67,0.8048,4.0502
 desk_oldinboxapp.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.01,-1.4908,1.0108
-desk_pinterest.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.47,0.69136,3.76864
-desk_pokemonwiki.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.61,1.56952,5.14548
-desk_rectangletransition.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.31,-1.25536,1.38536
-desk_samoasvg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,48.95,38.30184,60.04816
-desk_sfgate.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.66,0.57432,4.18068
-desk_tigersvg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,33.54,24.29064,43.40936
-desk_twitter.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,5.84,-0.75696,13.03696
-desk_weather.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.57,0.73304,3.91696
-desk_wowwiki.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,4.38,2.1956,6.1244
-desk_yahooanswers.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.17,0.2236,3.6164
-desk_youtube.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.49,0.09656,4.48844
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,7.28,4.56328,9.58672
-mobi_wikipedia.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.23,0.42936,3.56064
-tabl_androidpolice.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.53,1.48496,5.14004
-tabl_cnet.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,7.24,4.61688,9.45312
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,8.03,5.43416,10.17084
-tabl_cuteoverload.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,4.19,1.8096,6.1604
-tabl_deviantart.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.45,0.62208,3.78792
-tabl_digg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.76,-0.10248,3.13248
-tabl_engadget.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.74,-0.02992,3.01992
-tabl_frantzen.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.19,1.19288,4.65712
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.94,-0.41192,8.19692
-tabl_gmail.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.39,-1.44712,1.80212
-tabl_googleblog.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.27,-0.42192,2.46192
-tabl_googlecalendar.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.48,0.67056,3.79444
-tabl_gspro.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.31,-0.35544,2.49044
-tabl_hsfi.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.59,-0.38688,5.26688
-tabl_mercurynews.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.79,-0.01504,3.13504
-tabl_mlb.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,11.49,7.0792,15.7608
-tabl_mozilla.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.87,0.08872,3.16128
-tabl_nofolo.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,6.19,3.1668,8.9232
-tabl_nytimes.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.92,0.1756,3.1644
-tabl_pravda.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.53,0.51472,4.10028
-tabl_sahadan.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,12.2,7.76352,16.60148
-tabl_slashdot.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,10.16,7.51392,12.36608
-tabl_techmeme.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.87,-0.76032,2.01532
-tabl_ukwsj.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.44,0.14136,4.29864
-tabl_vnexpress.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.96,0.1108,3.3342
-tabl_worldjournal.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.59,1.45872,5.26128
\ No newline at end of file
+desk_pinterest.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.52,0.66704,3.88796
+desk_pokemonwiki.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.68,1.65424,5.19576
+desk_rectangletransition.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.35,-1.22808,1.41808
+desk_samoasvg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,51.35,43.49352,58.54648
+desk_sfgate.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.31,0.0048,4.1552
+desk_tigersvg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,35.18,28.7716,40.7334
+desk_twitter.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,5.72,-1.80104,13.91604
+desk_weather.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.17,0.30336,3.56164
+desk_wowwiki.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,4.34,2.07936,6.18064
+desk_yahooanswers.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.11,0.20728,3.54772
+desk_youtube.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.5,0.32688,4.22312
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,8.05,5.23224,10.51276
+mobi_wikipedia.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.14,0.3676,3.4374
+tabl_androidpolice.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.62,1.57808,5.20192
+tabl_cnet.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,7.37,4.74592,9.60408
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,8.14,5.21176,10.73824
+tabl_cuteoverload.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,4.24,2.1892,5.7758
+tabl_deviantart.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.47,0.67072,3.79428
+tabl_digg.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.69,-0.03592,2.91592
+tabl_engadget.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.6,-0.10856,2.82856
+tabl_frantzen.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.19,1.1748,4.6352
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.93,1.75376,5.56124
+tabl_gmail.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.37,-1.20024,1.45024
+tabl_googleblog.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.23,-0.45912,2.41912
+tabl_googlecalendar.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.52,0.60592,3.96408
+tabl_gspro.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.25,-0.4004,2.3904
+tabl_hsfi.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.52,-0.2276,4.9576
+tabl_mercurynews.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.67,-0.01392,2.84392
+tabl_mlb.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,11.9,8.37368,15.08132
+tabl_mozilla.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.88,0.11888,3.14612
+tabl_nofolo.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,6.28,3.33168,8.96332
+tabl_nytimes.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.75,-0.00088,3.00588
+tabl_pravda.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.65,0.58344,4.28156
+tabl_sahadan.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,12.64,9.1092,15.9008
+tabl_slashdot.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,10.27,7.5964,12.4636
+tabl_techmeme.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,0.85,-0.78808,1.98308
+tabl_ukwsj.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,2.48,0.22616,4.25884
+tabl_vnexpress.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,1.97,0.12104,3.29896
+tabl_worldjournal.skp_simple_viewport_1000x1000_angle_,Perf-Win7-ShuttleA-HD2000-x86-Release-ANGLE-25th,3.94,1.8036,5.5214
\ No newline at end of file
diff --git a/expectations/bench/bench_expectations_Perf-Win7-ShuttleA-HD2000-x86-Release.txt b/expectations/bench/bench_expectations_Perf-Win7-ShuttleA-HD2000-x86-Release.txt
index 5014fbb..5c914be 100644
--- a/expectations/bench/bench_expectations_Perf-Win7-ShuttleA-HD2000-x86-Release.txt
+++ b/expectations/bench/bench_expectations_Perf-Win7-ShuttleA-HD2000-x86-Release.txt
@@ -1,252 +1,252 @@
-desk_amazon.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.01,-0.70176,2.23176
-desk_baidu.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.93,-0.7548,2.1198
-desk_blogger.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.21,-0.49736,2.42236
-desk_booking.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.1,0.2708,3.4692
-desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,56.06,46.56136,65.88364
-desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,26.36,22.034,30.251
-desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.38,-0.35152,2.64152
-desk_ebay.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.73,0.86024,4.11476
-desk_espn.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.33,6.79744,13.57256
-desk_facebook.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.57,2.53344,6.12656
-desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.24,-1.3196,1.3096
-desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.01,0.2076,3.3474
-desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.31,1.99616,8.46884
-desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.37,-1.22008,1.47508
-desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.53,10.394,16.191
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.34,1.40176,4.75324
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.56,5.22408,9.38592
-desk_gws.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.74,0.85968,4.11532
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.76,4.54656,8.49344
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.47,-1.12832,1.58332
-desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.46,-0.2476,2.6676
-desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,31.54,26.91224,35.68276
-desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.84,0.06176,3.12824
-desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.15,-1.38248,1.18748
-desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.59,-0.15744,2.82244
-desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.56,0.7036,3.9314
-desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.11,-1.41904,1.14404
-desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.46,4.31152,8.11848
-desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.45,-0.24728,2.66728
-desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.42,6.94416,11.40584
-desk_twitter.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.63,2.5688,6.1712
-desk_weather.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.98,7.14768,12.42232
-desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,27.67,22.37864,32.74136
-desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.91,0.13608,3.21392
-desk_youtube.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.55,-0.18504,2.79004
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.35,4.93192,13.62808
-mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.51,-0.20176,2.72176
-tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.06,1.15456,4.46044
-tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.92,0.98488,4.36012
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,21.66,17.10032,25.95968
-tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,14.22,10.43824,17.60676
-tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.95,4.5916,8.7934
-tabl_digg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.55,-0.16464,2.76464
-tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.72,-0.03872,3.00872
-tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,43.8,36.94304,50.52696
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.49,0.64992,3.82008
-tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.17,-1.36376,1.20876
-tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.94,-0.716,2.116
-tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.65,0.78656,4.02844
-tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.2,-0.52664,2.43664
-tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.55,-0.17504,2.80004
-tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.48,-0.26,2.75
-tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.53,-0.20344,2.76844
-tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.74,-0.00072,3.00572
-tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,18.09,14.95,20.755
-tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.43,-0.34664,2.74664
-tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.31,-0.45544,2.57044
-tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,48.69,36.56136,59.10864
-tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.57,0.52832,4.17168
-tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.83,-0.8968,2.0518
-tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,16.38,11.9844,20.2406
-tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.16,-0.4936,2.3286
-tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.98,0.77776,4.66224
-desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.08,0.18144,3.51356
-desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.08,0.86064,4.80436
-desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.76,0.72648,4.34852
-desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.0,2.69736,6.85764
-desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,122.34,108.30808,135.96692
-desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,260.55,229.67176,291.01824
-desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.24,-0.68888,2.54888
-desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.9,-0.69488,8.61488
-desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.14,2.94528,6.90472
-desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.83,3.50096,7.70404
-desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.31,-1.23488,1.35988
-desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.31,3.74176,8.47324
-desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.21,5.35784,10.48716
-desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.88,-0.84096,2.11596
-desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.71,5.60784,11.13216
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,53.25,45.76512,60.41488
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,80.18,68.85456,91.74044
-desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.01,0.95648,4.61852
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.65,-0.43168,3.34168
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.57,-1.06648,1.70648
-desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.87,0.8668,4.3732
-desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,48.51,35.04944,61.09056
-desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.84,2.8004,6.3946
-desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.3,-1.24408,1.34908
-desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.98,-0.74104,4.17104
-desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.48,3.19904,7.30096
-desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.31,-1.25496,1.38496
-desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,79.66,67.23296,92.21704
-desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.48,0.52,3.96
-desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,44.75,35.39424,53.31576
-desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,12.78,8.81816,16.26184
-desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.17,2.57584,7.40916
-desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.34,-3.07336,12.46836
-desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.23,1.93032,5.91968
-desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.39,3.07632,7.20868
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.95,3.80616,9.86384
-mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.83,0.09296,3.06704
-tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.29,2.72272,7.24728
-tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.28,5.68168,13.97832
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.94,3.45232,12.46768
-tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.11,1.66944,6.00056
-tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.93,2.0044,5.3606
-tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.95,0.14296,3.27204
-tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.27,0.3052,3.7598
-tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.84,0.3732,4.8768
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.05,4.6532,8.9618
-tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.39,-1.18152,1.47152
-tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.61,-0.30032,3.04532
-tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.18,2.0516,5.8584
-tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.17,-0.56464,2.43964
-tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.5,-0.28536,5.03036
-tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.37,2.218,6.052
-tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,11.51,8.4456,14.1894
-tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.22,-0.568,2.488
-tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.78,3.19376,7.93124
-tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.8,0.86376,4.26624
-tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.71,2.51264,6.39736
-tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,11.89,6.314,17.721
-tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,12.27,9.03552,14.85448
-tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.19,-0.53632,2.42632
-tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.4,2.36536,5.97964
-tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.29,1.37552,4.71948
-tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.08,2.89264,6.70236
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,12.24,8.56296,15.69204
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.94,-0.74576,2.13076
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.22,-0.53864,2.47364
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.77,0.87736,4.18264
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,66.45,56.59584,76.37916
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,24.97,21.09872,28.41128
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.48,-0.21864,2.65364
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.69,0.85328,4.05672
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,21.06,16.0424,25.8976
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.22,9.98896,16.09604
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.28,-1.26264,1.32764
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.55,0.78512,3.82988
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.76,3.04512,8.13988
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.41,-1.21312,1.53312
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,16.92,13.09984,20.43516
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.01,1.94728,5.58772
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.02,6.26784,13.51716
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.92,0.8832,4.4418
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.16,6.06032,11.90468
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.54,-1.06352,1.65852
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.63,-0.24128,2.92628
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,25.51,19.34128,31.39872
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.8,0.03392,3.09608
+desk_amazon.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.03,-0.67256,2.21756
+desk_baidu.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.92,-0.74456,2.08456
+desk_blogger.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.13,-0.50112,2.27112
+desk_booking.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.08,0.31168,3.37332
+desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,54.33,47.8812,60.2488
+desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,27.47,23.15088,31.26412
+desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.35,-0.3284,2.5234
+desk_ebay.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.82,0.96304,4.18696
+desk_espn.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.69,1.68448,5.13552
+desk_facebook.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.68,2.7152,6.1448
+desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.25,-1.29024,1.29524
+desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.13,-1.41024,1.15524
+desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.38,3.22768,7.04232
+desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.38,-1.2004,1.4504
+desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.1,10.06872,15.66128
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.47,1.4416,4.9934
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.87,5.40736,9.84764
+desk_gws.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.71,0.82288,4.07212
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.75,-0.89088,1.91088
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.46,-1.11696,1.54696
+desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.42,-0.2748,2.6348
+desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,32.42,27.73248,36.59752
+desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.81,0.03424,3.09576
+desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.16,-1.37288,1.19788
+desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.59,-0.09832,2.79332
+desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.59,0.83264,3.83736
+desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.11,-1.41936,1.14436
+desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.67,4.27464,8.61036
+desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.39,-0.29176,2.56676
+desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.86,7.28912,11.95588
+desk_twitter.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.67,2.51464,6.35036
+desk_weather.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.28,-0.48432,2.58432
+desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.22,1.35136,4.59364
+desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.83,0.042,3.153
+desk_youtube.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.52,-0.22296,2.79296
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.72,6.90792,12.09708
+mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.43,-0.26528,2.64528
+tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.95,0.94176,4.50324
+tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.7,0.82176,4.11824
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.91,3.72528,7.62472
+tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.45,0.62304,3.78696
+tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.68,-0.11584,2.97084
+tabl_digg.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.37,-0.34064,2.60564
+tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.49,-0.19008,2.68508
+tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,36.92,31.43768,41.93232
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.26,0.27584,3.81916
+tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.17,-1.36384,1.20884
+tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.89,-0.72152,2.01152
+tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.74,0.94096,4.01404
+tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.14,-0.51208,2.30708
+tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.5,-0.26224,2.79724
+tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.21,-0.58824,2.55824
+tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.56,-0.15544,2.77544
+tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.81,0.09488,3.02012
+tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,18.4,15.05528,21.22472
+tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.35,-0.36936,2.57436
+tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.21,-0.4976,2.4226
+tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.56,0.62344,4.03156
+tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.16,0.28544,3.53956
+tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.74,-0.90944,1.88944
+tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.96,0.15184,3.28316
+tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.08,-0.5772,2.2322
+tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.33,1.43176,4.73824
+desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.12,0.0156,3.8094
+desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.01,1.01624,4.54376
+desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.7,0.74192,4.17308
+desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.09,2.87048,6.81952
+desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,129.52,113.34584,145.53916
+desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,266.94,232.39504,299.47996
+desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.33,-0.36672,2.52672
+desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.02,-2.40704,10.83704
+desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.28,3.03576,7.05924
+desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.84,3.63088,7.56412
+desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.35,-1.21856,1.42856
+desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.28,-1.26248,1.32748
+desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.11,5.63736,10.11764
+desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.9,-0.79328,2.12328
+desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.95,4.87512,10.55488
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,55.61,47.79664,63.31836
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,79.15,66.48952,92.06048
+desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.96,1.072,4.363
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.72,-0.46832,3.54332
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.64,-1.00136,1.78136
+desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.84,0.94096,4.25904
+desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,50.01,41.88992,58.05508
+desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.19,2.77312,7.00688
+desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.34,-1.20728,1.39228
+desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.06,-0.30984,4.07984
+desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.56,3.34272,7.27728
+desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.35,-1.22816,1.41816
+desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,82.32,69.41552,95.80448
+desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.44,0.49352,3.88148
+desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,46.4,37.99392,54.28608
+desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.26,9.6424,16.3026
+desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.11,2.11216,7.13784
+desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.28,-1.9284,10.9084
+desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.98,1.91056,5.54444
+desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.5,2.62696,7.90304
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.6,3.8012,11.3188
+mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.91,0.1556,3.1894
+tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.32,3.05984,7.09516
+tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.51,4.90096,15.41904
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.96,3.03176,13.05824
+tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.04,2.0948,5.5152
+tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.9,1.86552,5.44448
+tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.0,0.01752,3.56248
+tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.26,0.31784,3.72216
+tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.92,0.6684,4.7766
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.29,4.16528,10.05972
+tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.4,-1.18208,1.47208
+tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.55,-0.286,2.916
+tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.36,2.06904,6.17096
+tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.52,-0.31392,2.88392
+tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.0,1.88952,5.52548
+tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.88,0.88776,4.39224
+tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,11.71,3.13088,21.29412
+tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.41,-0.31328,2.63828
+tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.89,2.93104,8.59396
+tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.7,0.82256,4.11744
+tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.77,2.57584,6.47416
+tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,12.3,6.902,17.878
+tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,12.51,9.48712,14.93788
+tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.14,-0.682,2.497
+tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.51,2.39648,6.16352
+tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.29,1.28552,4.80948
+tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.52,3.30504,7.27996
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,12.53,9.62344,14.90156
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.99,-0.67984,2.15984
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.22,-0.48864,2.43364
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.85,1.02152,4.15848
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,63.77,55.74784,71.30716
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,26.25,22.2176,29.7324
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.45,-0.24704,2.66704
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.01,0.96696,4.62804
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,21.65,17.63128,25.13872
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.57,10.62216,15.97284
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.28,-1.26256,1.32756
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.93,-0.76528,2.11028
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.87,3.63816,7.62184
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.41,-1.16328,1.49328
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,17.4,13.94416,20.40584
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.22,2.19072,5.77428
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.62,7.97744,12.81256
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.85,0.89864,4.35636
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.39,6.5956,11.7294
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.51,-1.07112,1.60112
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.6,-0.10952,2.82952
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,26.11,21.94856,29.66644
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.86,0.14088,3.07412
 desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.17,-1.36376,1.20876
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.71,5.80992,11.15008
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.91,1.02584,4.30916
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.24,5.74864,10.24636
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.04,1.20552,4.37448
 desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.13,-1.40056,1.16556
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.72,4.11808,8.82692
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.22,7.36872,12.63628
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.57,7.0728,11.5572
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,23.01,17.34192,28.73308
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,17.64,14.18248,20.68752
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,37.77,28.97176,46.40824
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.97,0.16072,3.29428
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.09,9.98928,15.80572
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,11.1,7.656,14.239
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.63,-0.1312,2.9012
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,18.52,13.07832,23.91668
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,14.91,10.78336,18.80164
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,91.03,73.382,107.678
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,22.1,18.11536,25.73964
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.83,10.27864,16.93636
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.53,-0.30408,2.89408
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.38,7.60744,12.62756
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,46.09,40.58984,51.10016
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.67,0.78512,4.07488
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.19,-1.34528,1.23028
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.83,-0.87768,2.07268
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.01,1.16784,4.37716
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.63,-0.09104,2.85104
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.43,7.41176,13.07324
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.38,-0.3916,2.6916
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.63,-0.13136,2.90136
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,16.38,13.06672,19.22828
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,19.65,15.6696,23.2654
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.38,-0.34128,2.60628
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.08,-0.56744,2.24244
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,54.32,19.73216,95.17784
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.46,0.63224,3.79776
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.77,-0.88216,1.92216
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,24.79,21.08448,28.00552
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.97,0.22152,3.21848
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.42,1.51504,4.83496
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.49,-2.4328,12.0028
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.05,1.07416,4.56084
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.67,0.76456,4.10044
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.92,2.48152,6.85848
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,141.61,112.3544,165.5806
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,260.94,224.1432,297.7468
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.14,-2.52536,11.34036
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,19.27,16.14712,21.91288
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,15.63,12.08696,18.71304
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.44,5.37032,10.84968
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.31,-1.26488,1.37488
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.76,6.73328,12.29172
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.14,6.25232,11.62268
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.15,-0.5928,2.4078
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.57,5.03432,14.69068
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,57.56,49.34376,64.99124
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,53.29,46.84928,59.33072
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.93,1.01448,4.34552
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.81,-3.10528,18.15028
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.26,-0.39088,2.40088
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.98,0.9596,4.5254
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,38.49,29.15656,46.68344
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.65,1.96104,6.88396
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.32,-1.22584,1.37084
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.98,-1.62224,23.37224
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.2,3.10272,6.79728
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.29,-1.29384,1.38884
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,82.52,72.96472,91.86528
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.96,-2.1492,10.0692
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,45.87,37.13256,54.69744
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,33.71,9.46696,55.55304
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,11.65,-1.80648,27.29648
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,16.76,13.0056,20.2194
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.37,2.11712,6.17788
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.68,4.60408,10.29092
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.51,4.22,10.595
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.19,0.4244,3.4556
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,12.58,6.39528,17.15472
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.37,8.96728,17.63772
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,39.71,23.68696,57.92304
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,17.91,14.44488,20.98512
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.59,4.86192,14.11308
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.08,5.33952,10.44548
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.87,1.8788,5.3612
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.43,5.71208,10.78292
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.35,4.93112,9.19388
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.54,-1.07336,1.64836
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.44,0.39008,4.05492
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.28,3.16712,6.87288
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.83,0.85,4.35
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,11.1,8.30984,13.35516
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.64,1.39688,5.42812
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,16.73,13.72056,19.21444
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.83,3.74704,9.64796
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.03,6.488,10.972
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.41,0.57616,3.73384
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.09,2.09128,5.60872
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,23.56,17.90568,29.23432
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,24.12,20.41936,27.32064
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.17,-0.65536,2.53036
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.07,4.27184,9.43816
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.0,2.62568,6.96932
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.7,4.39224,8.50776
\ No newline at end of file
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.96,4.6692,8.7858
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.4,7.46384,12.89616
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.02,7.47536,12.07964
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,23.71,19.33752,27.71248
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,16.26,12.8352,19.2948
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,38.56,33.14168,43.34832
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.95,-0.13856,3.62356
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.22,10.22072,15.69428
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,11.72,8.4372,14.6678
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.66,-0.08392,2.90892
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,18.76,14.39208,22.87792
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,15.29,10.87616,19.44384
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,93.36,79.33296,107.41704
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,22.88,17.8612,27.5038
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.91,9.65464,17.96036
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.44,-0.2552,2.6102
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.42,6.86688,13.57312
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,48.19,42.472,53.408
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.5,0.5984,3.9066
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.19,-1.34536,1.23036
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.82,-0.82608,1.98608
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.07,1.17288,4.48212
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.66,-0.05368,2.89368
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.74,7.9784,13.0566
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.21,-0.56824,2.53324
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.68,-0.04472,2.90472
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,16.37,12.36248,20.10752
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,20.3,16.50144,23.69856
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.36,-0.38016,2.61016
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.08,-0.61696,2.28196
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,57.36,22.14648,99.04352
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.18,0.3948,3.4702
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.76,-0.84152,1.87152
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,25.39,21.19536,29.06964
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.08,0.3028,3.3622
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.9,1.92688,5.36812
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.56,-2.58224,12.32724
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.88,0.97752,4.30248
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.64,0.62712,4.18288
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.84,2.64944,6.60556
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,138.87,106.5632,163.9418
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,250.57,209.8308,287.7942
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.22,-2.77152,11.89152
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,19.74,16.56048,22.39952
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,15.92,12.48424,18.88576
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.71,5.7044,11.2356
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.36,-1.1688,1.3888
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.32,-1.23544,1.36044
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.89,6.33544,10.93956
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.31,-0.4964,2.6664
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.23,5.40328,12.56672
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,56.93,48.90744,64.73756
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,54.47,43.80968,65.05532
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.83,0.90152,4.26348
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,6.99,-3.08552,18.55052
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.34,-0.328,2.523
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.98,0.94984,4.56016
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,37.68,31.30032,43.61468
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.81,2.59408,6.45092
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.36,-1.26944,1.51444
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,10.29,-3.8508,26.8658
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.16,2.99368,6.86632
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.33,-1.2464,1.3964
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,81.62,69.53896,93.64104
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.91,-2.24776,10.36776
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,45.6,32.524,58.946
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,32.02,23.75232,40.27268
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,11.07,-3.6756,28.3406
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,17.11,14.0296,19.7204
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.11,2.15048,5.57952
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.97,4.97656,10.47344
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.24,5.43768,10.70232
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.3,0.55496,3.56004
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,12.53,6.94976,16.20024
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,13.76,9.06936,17.99564
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,40.54,18.5856,66.1894
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,18.34,14.70976,21.63524
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.78,6.00088,13.06912
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.22,5.44736,10.62264
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.98,1.85976,5.63024
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,8.71,5.72952,11.20548
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.27,4.32936,9.81064
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,0.53,-1.08248,1.63748
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.56,0.55368,4.00632
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.2,2.80984,7.14016
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.97,0.7888,4.6712
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,12.75,5.80264,17.31236
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,4.47,1.62296,7.03704
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,17.13,14.12944,19.59556
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.29,4.01672,10.35828
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,9.15,6.5056,11.2844
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,2.37,0.40784,3.87716
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,3.98,1.88944,5.61556
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,24.27,18.86008,29.62492
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,24.52,20.35808,27.95192
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,1.11,-0.62,2.375
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.19,4.3984,9.5916
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,5.08,2.84072,6.87928
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win7-ShuttleA-HD2000-x86-Release-25th,7.33,4.97096,9.23404
\ No newline at end of file
diff --git a/expectations/bench/bench_expectations_Perf-Win8-ShuttleA-GTX660-x86-Release.txt b/expectations/bench/bench_expectations_Perf-Win8-ShuttleA-GTX660-x86-Release.txt
index 4143a35..5dcf119 100644
--- a/expectations/bench/bench_expectations_Perf-Win8-ShuttleA-GTX660-x86-Release.txt
+++ b/expectations/bench/bench_expectations_Perf-Win8-ShuttleA-GTX660-x86-Release.txt
@@ -1,252 +1,252 @@
-desk_amazon.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.99,-0.67008,2.17008
-desk_baidu.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.9,-0.73272,2.04772
-desk_blogger.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.17,-0.46392,2.31392
-desk_booking.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.07,0.2432,3.4368
-desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,55.51,48.9104,61.7496
-desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,25.6,21.44752,29.35748
-desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.35,-0.31856,2.53356
-desk_ebay.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.67,0.89576,3.95924
-desk_espn.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,10.25,5.8264,14.6736
-desk_facebook.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,4.41,2.43584,5.91416
-desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.23,-1.30864,1.27364
-desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.99,0.2904,3.1996
-desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,5.07,2.97296,6.69204
-desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.36,-1.20904,1.43904
-desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,13.35,10.62072,15.57428
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.27,1.36696,4.70804
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,7.44,5.21392,9.17608
-desk_gws.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.66,0.81672,4.01328
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,6.68,4.52408,8.36592
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.46,-1.09696,1.52196
-desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.4,-0.32232,2.62732
-desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,30.53,25.33144,35.51856
-desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.8,0.0956,3.0194
-desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.15,-1.38208,1.18708
-desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.53,-0.14232,2.69232
-desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.5,0.7392,3.7758
-desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.11,-1.42872,1.13372
-desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,6.22,4.11176,7.83324
-desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.41,-0.26312,2.59812
-desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,9.15,6.71576,11.13424
-desk_twitter.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,4.49,2.46952,6.00548
-desk_weather.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,9.48,6.9692,11.5308
-desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,25.99,20.86464,30.86536
-desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.85,0.13192,3.06308
-desk_youtube.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.5,-0.2008,2.7208
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,8.86,6.45928,10.78572
-mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.46,-0.19712,2.62712
-tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.94,1.03336,4.36664
-tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.82,0.93368,4.24632
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,20.89,17.1352,24.2448
-tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,13.74,10.73728,16.29772
-tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,6.7,4.47216,8.45284
-tabl_digg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.5,-0.16024,2.67024
-tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.65,-0.052,2.847
-tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,41.95,36.78024,46.67476
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.44,0.64368,3.76132
-tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.16,-1.37304,1.19804
-tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.92,-0.694,2.044
-tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.59,0.80192,3.89808
-tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.2,-0.43656,2.34656
-tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.51,-0.23184,2.78184
-tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.45,-0.24656,2.66656
-tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.49,-0.18976,2.68476
-tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.71,0.0128,2.9222
-tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,17.39,14.03648,20.31352
-tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.4,-0.27264,2.58764
-tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.27,-0.39216,2.44716
-tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,38.63,33.3052,43.4348
-tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.49,0.73016,3.76484
-tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.76,-0.84136,1.87136
-tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,15.73,12.73,18.245
-tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.07,-0.646,2.296
-tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.78,0.9564,4.1286
-desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.55,-1.17536,1.77536
-desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.96,-0.71744,2.16244
-desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.87,-0.802,2.067
-desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.69,-0.07536,2.92036
-desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,43.25,27.26096,54.32404
-desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,62.45,54.1248,70.5002
-desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.77,-0.91368,1.98368
-desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.17,-0.55424,2.40424
-desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.35,0.49152,3.72848
-desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.37,0.53896,3.73604
-desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.16,-1.4332,1.2732
-desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.07,1.24312,4.41688
-desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.08,1.24312,4.41688
-desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.55,-1.064,1.659
-desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.81,0.11512,2.99488
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,13.27,10.0224,16.0076
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,27.18,22.39864,31.55636
-desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.54,-0.16368,2.76368
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.43,-1.14488,1.51488
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.34,-1.26848,1.46848
-desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.68,-0.1252,3.0052
-desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,14.86,11.36232,17.96768
-desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.61,0.8404,3.8946
-desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.12,-1.44984,1.20484
-desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.53,-1.03256,1.59756
-desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.22,1.3716,4.5684
-desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.23,-1.40936,1.39936
-desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,18.54,14.6176,21.9024
-desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.21,-0.468,2.408
-desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,14.56,10.96304,17.46196
-desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,4.47,2.54176,5.89324
-desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.74,0.03016,2.94484
-desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.92,0.06456,3.28044
-desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.07,0.30296,3.36204
-desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.69,0.88416,3.99584
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.71,-0.88712,1.81712
-mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.93,-0.75464,2.11964
-tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.85,0.11176,3.08824
-tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.91,0.95504,4.37496
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.31,-0.42568,2.55568
-tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.11,-0.60936,2.33936
-tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.31,-0.38488,2.50488
-tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.93,-0.71472,2.06972
-tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.28,-0.39264,2.44764
-tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.71,-0.91712,1.83212
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.99,1.16056,4.31944
-tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.26,-1.3712,1.3962
-tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.87,-0.76016,2.01516
-tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.03,0.2364,3.3336
-tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.65,-0.94256,1.75256
-tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.1,-0.52824,2.23824
-tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.98,0.24088,3.23912
-tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.17,-0.46424,2.31424
-tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.85,-0.79784,1.97284
-tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.17,-0.4844,2.3394
-tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.54,-0.144,2.739
-tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.01,0.20784,3.34716
-tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.82,-0.00688,3.19188
-tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.13,0.3184,3.4316
-tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.8,-0.87424,1.97924
-tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.89,0.11712,3.19288
-tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.51,-0.1512,2.6812
-tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.13,1.29896,4.48104
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,11.95,8.95912,14.50588
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.92,-0.67368,2.01868
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.17,-0.53432,2.37932
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.67,0.8352,4.0348
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,65.82,58.368,72.852
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,24.3,20.1792,28.0658
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.42,-0.24368,2.57368
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.33,0.58296,3.59204
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,20.65,16.7164,23.9636
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,12.72,9.8604,15.0746
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.27,-1.27176,1.31676
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.52,0.60688,3.96312
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,5.5,3.33688,7.21812
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.4,-1.19256,1.50756
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,16.48,12.3732,20.0918
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.97,2.05064,5.41436
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,10.78,8.20568,12.88432
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.76,0.918,4.132
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,8.61,6.22016,10.50484
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.5,-1.06008,1.56508
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.51,-0.21152,2.75652
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,24.58,20.8908,27.7792
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.76,0.07872,2.95128
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.16,-1.39328,1.22328
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,7.71,5.4216,9.5184
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.83,1.04264,4.13236
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.12,-1.40976,1.15476
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,6.55,4.31488,8.31512
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,9.81,7.30488,11.78012
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,9.3,6.95488,11.17012
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,21.97,17.4684,26.0316
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,16.73,13.08664,19.98336
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,35.88,29.90488,41.48512
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.9,0.20768,3.10232
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,12.29,9.48328,14.63172
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,11.01,8.23608,13.35892
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.58,-0.12696,2.80696
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,17.78,13.7976,21.3674
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,14.7,11.51776,17.46224
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,81.17,72.10528,89.86472
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,21.58,17.93088,24.74412
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,13.2,10.07816,15.91684
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.5,-0.19048,2.68548
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,10.12,7.3968,12.3332
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,44.71,38.26888,50.74112
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.59,0.75192,3.93808
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.18,-1.35456,1.21956
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.82,-0.80608,1.96108
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.94,1.14424,4.25076
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.59,-0.0976,2.7926
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,10.11,5.90512,14.28488
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.54,-0.28392,2.86892
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.71,-0.108,3.073
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,16.6,13.40936,19.38064
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,20.21,13.95608,24.63392
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.34,-0.35744,2.53744
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.04,-0.60392,2.19892
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,54.64,35.2824,74.8776
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.38,0.44776,3.87224
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.75,-0.83016,1.83516
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,24.25,18.22832,30.38668
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.91,0.21688,3.11312
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.26,1.43872,4.59628
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.55,-1.2268,1.8618
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.91,-0.74368,2.08368
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.85,-0.82952,2.03452
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.67,-0.14368,2.93868
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,44.86,28.3832,55.8868
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,57.93,49.2268,66.6982
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.76,-0.8008,1.8208
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.66,-0.03344,2.86844
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.28,0.45608,3.63892
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.75,0.85896,4.16104
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.16,-1.45336,1.29836
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.11,1.24072,4.46428
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.21,1.33192,4.61808
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.62,-1.01,1.77
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.47,-0.20864,2.66364
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,14.75,11.07592,17.92408
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,22.67,18.0428,26.4722
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.45,-0.22632,2.64132
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.91,-0.70328,2.03328
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.36,-1.24968,1.48968
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.68,0.00504,2.86496
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,11.77,8.75256,14.31744
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.42,0.61584,3.72916
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.12,-1.40968,1.15468
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.83,-0.75648,1.92148
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.09,1.2316,4.4534
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.23,-1.38904,1.37404
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,18.79,15.17232,21.94768
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.17,-0.52456,2.38956
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,14.8,11.67224,17.40276
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,4.23,2.20032,5.73968
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.37,-0.28,2.53
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.68,-0.10536,2.98036
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.79,0.046,3.059
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.85,0.05056,3.16444
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.49,-1.06936,1.55436
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.88,-0.77096,2.05096
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.76,0.07856,2.95144
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.86,1.01056,4.19444
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.06,-0.01112,3.64112
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.93,-0.66448,2.02948
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.29,-0.37376,2.46876
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.87,-0.76048,2.01548
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.7,-0.02608,2.92608
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.56,-1.06544,1.70544
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.05,1.22512,4.39488
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.3,-1.3248,1.4498
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.67,-0.97392,1.81392
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.26,0.53856,3.49144
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.6,-0.9684,1.6734
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.09,-0.5472,2.2172
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.55,-0.16464,2.76464
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.11,-0.5804,2.3254
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.83,-0.78632,1.93632
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.21,-0.44752,2.38252
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.29,-0.39392,2.49392
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.68,-0.14544,3.03044
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.78,0.00704,3.06296
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.91,0.13568,3.21432
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.75,-0.89048,1.91048
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.88,0.14824,3.13176
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.49,-0.16968,2.65968
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.46,1.45112,5.00388
\ No newline at end of file
+desk_amazon.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.01,-0.68216,2.20716
+desk_baidu.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.9,-0.80296,2.11296
+desk_blogger.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.12,-0.69032,2.44032
+desk_booking.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.05,0.25496,3.35504
+desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,52.81,39.64424,67.10076
+desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,27.58,20.94088,34.28912
+desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.33,-0.31656,2.48656
+desk_ebay.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.74,0.79864,4.23636
+desk_espn.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.62,1.69944,5.05056
+desk_facebook.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,4.54,2.4648,6.1452
+desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.24,-1.31944,1.30944
+desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.12,-1.40968,1.15468
+desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,5.15,3.10736,6.70264
+desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.36,-1.24976,1.48976
+desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,12.61,9.7572,15.0028
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.44,1.26248,5.21752
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,8.49,6.04912,10.49588
+desk_gws.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.61,0.8004,3.9446
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.74,-0.92976,1.91476
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.45,-1.086,1.486
+desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.43,-0.20448,2.56948
+desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,31.43,27.01288,35.40212
+desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.77,0.06776,2.98724
+desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.15,-1.38216,1.18716
+desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.56,-0.15496,2.77496
+desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.52,0.7576,3.7974
+desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.11,-1.3988,1.1188
+desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,6.47,4.34184,8.10316
+desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.35,-0.29816,2.50816
+desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,9.6,7.1804,11.5346
+desk_twitter.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,4.59,2.53104,6.17396
+desk_weather.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.29,-0.42432,2.50932
+desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.19,1.374,4.521
+desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.8,0.08584,3.00916
+desk_youtube.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.5,-0.2212,2.7462
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,9.07,6.6128,11.0622
+mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.4,-0.23216,2.53716
+tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.89,1.02832,4.26168
+tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.64,0.82768,3.97732
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,5.8,3.50408,7.65592
+tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.42,0.59552,3.75448
+tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.63,-0.152,2.927
+tabl_digg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.32,-0.33552,2.46552
+tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.43,-0.27464,2.63464
+tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,35.68,31.07384,39.78116
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.21,0.39104,3.56396
+tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.17,-1.36384,1.20884
+tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.86,-0.7696,2.0046
+tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.68,0.94536,3.91964
+tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.11,-0.5396,2.2746
+tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.49,-0.19952,2.67452
+tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.2,-0.47712,2.39712
+tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.53,-0.13288,2.70288
+tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.76,0.00848,3.01652
+tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,17.53,14.46624,20.08876
+tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.32,-0.38608,2.55108
+tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.19,-0.44536,2.33536
+tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.52,0.72784,3.81216
+tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.11,0.33072,3.39428
+tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.71,-0.8672,1.7922
+tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.9,0.18768,3.12732
+tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.04,-0.56328,2.14828
+tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.16,1.34616,4.48884
+desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.5,-1.28312,1.84312
+desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.79,-0.8544,1.9544
+desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.75,-0.83016,1.83516
+desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.52,-0.21208,2.75708
+desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,45.39,32.06184,54.40316
+desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,65.33,57.10736,73.19764
+desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.65,-0.952,1.742
+desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.08,-0.6376,2.3076
+desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.04,0.2056,3.3944
+desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.27,0.5076,3.5524
+desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.11,-1.41888,1.14388
+desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.13,-1.40064,1.16564
+desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.96,1.15288,4.26212
+desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.45,-1.12688,1.53688
+desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.75,-0.02136,3.03136
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,14.38,11.45656,16.84844
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,26.43,22.3216,30.0034
+desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.3,-0.3244,2.4294
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.44,-1.31856,1.70856
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.34,-1.48168,1.66668
+desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.6,-0.21056,2.95556
+desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,15.32,12.4628,17.6872
+desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.54,0.76664,3.80836
+desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.06,-1.46496,1.08996
+desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.7,-0.87624,1.78124
+desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.01,1.16768,4.37732
+desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.19,-1.40544,1.26044
+desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,19.36,15.24304,23.15196
+desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.06,-0.6048,2.1998
+desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,15.01,12.06776,17.46724
+desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,4.26,2.21768,5.80732
+desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.43,-0.3248,2.6748
+desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.67,-0.29544,3.19544
+desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.86,0.19064,3.03436
+desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.58,0.8132,3.8618
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.76,-1.10056,2.01556
+mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.85,-1.12256,2.37756
+tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.69,-0.00576,2.90076
+tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.81,0.93456,4.20044
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.31,-0.35568,2.49068
+tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.0,-0.7016,2.2316
+tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.17,-0.5352,2.3802
+tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.84,-0.76784,1.95784
+tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.16,-0.5644,2.3944
+tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.77,-1.11432,2.09932
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.75,0.93952,4.06048
+tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.21,-1.36792,1.30292
+tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.75,-0.93128,1.96128
+tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.92,0.15568,3.18932
+tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.71,-0.91704,1.83204
+tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.98,-0.72,2.21
+tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.43,-0.28536,2.67036
+tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.19,-0.49576,2.37576
+tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.85,-1.08448,2.32948
+tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.1,-0.65032,2.39032
+tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.26,-0.44224,2.48724
+tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.77,0.06752,2.98748
+tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.68,-0.166,3.056
+tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.93,0.21472,3.16028
+tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.69,-0.91528,1.78528
+tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.66,-0.18504,3.03504
+tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.27,-0.42224,2.46224
+tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.07,1.13328,4.53172
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,12.16,9.3136,14.5764
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.96,-0.69824,2.13824
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.18,-0.48472,2.33972
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.71,0.93224,4.00276
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,61.8,53.05872,70.38628
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,25.64,21.2644,29.6756
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.45,-0.20624,2.61624
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.48,0.69088,3.76912
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,21.68,17.09456,25.83044
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,13.14,10.34552,15.49448
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.27,-1.2516,1.2916
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.88,-0.7108,1.9758
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,5.66,3.47544,7.37956
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.41,-1.14288,1.46788
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,18.2,12.41624,23.95876
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,4.16,2.22584,5.61916
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,10.64,8.04616,12.74884
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.79,0.91544,4.17956
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,9.0,6.60864,10.91136
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.5,-1.06016,1.56516
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.61,-0.11952,2.86452
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,25.26,21.41576,28.63924
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.84,0.13248,3.06252
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.17,-1.36368,1.20868
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,7.9,5.50576,9.81424
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.0,1.17904,4.34096
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.12,-1.41,1.155
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,6.85,4.55976,8.70024
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,10.16,7.53568,12.24932
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,9.73,7.20968,11.81032
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,22.8,19.0536,26.0164
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,15.46,12.31088,18.09912
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,37.0,32.10488,41.43512
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.91,0.21648,3.11352
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,13.52,9.2724,17.3876
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,11.28,8.6152,13.4648
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.62,-0.0596,2.7896
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,19.24,13.144,25.011
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,15.58,12.05792,18.68208
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,90.02,72.61064,107.35936
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,22.03,18.11296,25.45204
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,13.9,10.37432,16.95068
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.33,-0.31656,2.48656
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,10.08,7.45872,12.25628
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,45.1,39.40744,50.34756
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.45,0.6528,3.7722
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.18,-1.37488,1.24488
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.8,-0.8448,1.9648
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.01,1.17872,4.34128
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.64,-0.01152,2.79652
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,10.49,7.06216,13.37284
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.18,-0.45504,2.32504
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.64,-0.01136,2.79636
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,17.08,11.24096,21.42904
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,19.39,15.89368,22.45132
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.33,-0.3368,2.5118
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.05,-0.55424,2.15924
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,54.12,47.86768,59.84232
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.13,0.41888,3.35112
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.75,-0.85016,1.86016
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,24.67,20.692,28.228
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.02,0.1876,3.3724
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.72,1.84128,5.11872
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.58,-1.08712,1.77712
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.81,-0.96632,2.07132
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.8,-0.82504,1.94004
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.59,-0.11832,2.81832
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,46.91,31.58016,59.72984
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,60.61,52.1688,68.4412
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.82,-1.19024,2.35024
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.67,-0.14616,2.98616
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.08,0.29136,3.39864
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.62,0.73824,4.02176
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.12,-1.3896,1.1296
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.14,-1.39128,1.17628
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.09,1.12,4.615
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.59,-1.11992,1.83992
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.55,-0.25512,2.85512
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,15.34,11.89736,18.39264
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,23.63,18.02264,27.94236
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.28,-0.43352,2.49852
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.05,-0.75408,2.27408
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.45,-1.46776,1.78276
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.61,-0.23192,2.98192
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,12.09,9.38024,14.35976
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.45,0.6932,3.7218
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.06,-1.46496,1.08996
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.13,-0.82968,2.43468
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.03,1.24696,4.32304
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.19,-1.39568,1.27068
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,19.86,15.59152,23.85348
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.1,-0.69928,2.38428
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,14.98,12.06104,17.36396
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,4.16,2.06576,5.77424
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.16,-0.5236,2.3436
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.75,-0.55776,3.25276
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.71,0.03288,2.89712
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.81,0.07456,3.04544
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.6,-1.14144,1.86644
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.8,-1.046,2.171
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.67,-0.08528,2.95528
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.82,0.95272,4.22228
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.48,-0.3544,4.2894
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.17,-0.58576,2.46576
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.2,-0.52688,2.43688
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.86,-0.75888,1.96888
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.6,-0.09832,2.79332
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.65,-1.12544,1.93544
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.9,1.04672,4.28328
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.25,-1.29008,1.29508
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.64,-1.1628,1.9378
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,2.11,0.28,3.48
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.68,-0.9352,1.8102
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.04,-0.87456,2.46956
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.42,-0.2544,2.6094
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.07,-0.62624,2.27124
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.12,-1.10848,2.55848
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.18,-0.5464,2.4164
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.15,-0.61272,2.38772
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.55,-0.11456,2.72456
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.66,-0.0948,2.9448
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.82,0.0436,3.1064
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,0.66,-0.97416,1.81416
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.69,-0.08688,3.00188
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,1.3,-0.35416,2.44416
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-GTX660-x86-Release-25th,3.61,1.71056,5.01444
\ No newline at end of file
diff --git a/expectations/bench/bench_expectations_Perf-Win8-ShuttleA-HD7770-x86-Release.txt b/expectations/bench/bench_expectations_Perf-Win8-ShuttleA-HD7770-x86-Release.txt
index 865933e..d4c4d53 100644
--- a/expectations/bench/bench_expectations_Perf-Win8-ShuttleA-HD7770-x86-Release.txt
+++ b/expectations/bench/bench_expectations_Perf-Win8-ShuttleA-HD7770-x86-Release.txt
@@ -1,252 +1,252 @@
-desk_amazon.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.99,-0.69944,2.18444
-desk_baidu.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.9,-0.71256,2.02256
-desk_blogger.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.17,-0.46392,2.31392
-desk_booking.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.07,0.29408,3.35092
-desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,56.09,49.15736,62.66764
-desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,25.54,21.74312,28.87688
-desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.35,-0.29816,2.50816
-desk_ebay.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.67,0.866,3.974
-desk_espn.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,10.16,7.19232,12.58768
-desk_facebook.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.44,2.47432,5.91068
-desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.23,-1.30856,1.27356
-desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.97,0.27176,3.17824
-desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,5.05,3.01544,6.59456
-desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.36,-1.20896,1.43896
-desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,13.03,10.24576,15.32924
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.26,1.39848,4.64652
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,7.41,5.18656,9.14344
-desk_gws.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.65,0.89744,3.91256
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,6.65,4.47648,8.35852
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.46,-1.1172,1.5472
-desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.41,-0.29312,2.61312
-desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,30.59,26.35064,34.33436
-desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.8,0.09576,3.01924
-desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.15,-1.38224,1.18724
-desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.52,-0.162,2.717
-desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.48,0.74104,3.72896
+desk_amazon.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.99,-0.79112,2.32112
+desk_baidu.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.9,-0.80304,2.11304
+desk_blogger.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.12,-0.70168,2.47668
+desk_booking.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.06,0.30448,3.31552
+desk_carsvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,52.42,46.07088,58.31912
+desk_chalkboard.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,27.69,23.4908,31.3742
+desk_css3gradients.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.3,-0.38432,2.50432
+desk_ebay.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.64,0.90848,3.87652
+desk_espn.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.7,1.55392,5.23108
+desk_facebook.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.52,2.49656,6.08344
+desk_fontwipe.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.24,-1.2792,1.2592
+desk_forecastio.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.12,-1.40968,1.15468
+desk_gmailthread.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,5.18,3.1748,6.6852
+desk_googlehome.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.37,-1.1596,1.3996
+desk_googleplus.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,12.58,9.8208,14.8792
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.42,1.52488,4.84512
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,7.72,5.39056,9.57944
+desk_gws.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.61,0.84048,3.89452
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.74,-0.83928,1.82428
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.46,-1.12688,1.53688
+desk_linkedin.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.43,-0.21424,2.55924
+desk_mapsvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,31.44,27.11264,35.27736
+desk_mobilenews.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.78,0.1376,2.9224
+desk_oldinboxapp.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.15,-1.38208,1.18708
+desk_pinterest.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.56,-0.12544,2.76044
+desk_pokemonwiki.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.53,0.75736,3.79764
 desk_rectangletransition.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.11,-1.3988,1.1188
-desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,6.21,4.19288,7.73212
-desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.42,-0.33464,2.70964
-desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,9.16,6.84616,10.99384
-desk_twitter.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.53,2.54648,6.04352
-desk_weather.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,9.63,7.04744,11.76756
-desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,26.55,22.07144,30.71856
-desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.85,0.12144,3.09856
-desk_youtube.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.5,-0.20088,2.72088
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,9.19,6.31928,11.69572
-mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.46,-0.1972,2.6272
-tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.93,1.08496,4.28004
-tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.79,0.92576,4.18924
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,20.83,16.57504,24.80996
-tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,13.9,10.57416,16.88084
-tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,6.74,4.58976,8.39524
-tabl_digg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.5,-0.14016,2.64516
-tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.66,-0.03368,2.86868
-tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,41.69,34.9788,48.2512
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.43,0.67496,3.70004
-tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.16,-1.37312,1.19812
-tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.92,-0.7344,2.0944
-tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.59,0.84232,3.84768
-tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.17,-0.44376,2.28876
-tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.52,-0.192,2.732
-tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.45,-0.24688,2.66688
-tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.5,-0.16048,2.67048
-tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.71,-0.02808,2.97308
-tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,17.11,14.0296,19.7204
-tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.41,-0.33312,2.66312
-tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.27,-0.42168,2.46168
-tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,39.2,30.95664,47.41336
-tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.49,0.75056,3.73944
-tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.77,-0.81168,1.85668
-tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,15.95,12.76208,18.71792
-tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.07,-0.58568,2.22068
-tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.77,0.96768,4.09232
-desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.76,-0.29264,3.39264
-desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.79,-0.03448,3.15948
-desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.87,0.09928,3.17072
-desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.99,1.02968,4.46032
-desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,67.82,59.642,75.628
-desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,124.41,104.50432,143.58068
-desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.92,-0.91584,2.27584
-desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.37,-0.59216,2.85216
-desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.8,0.82504,4.31496
-desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.98,0.86976,4.61524
-desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.16,-1.4332,1.2732
-desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.19,2.04128,5.84872
-desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.91,1.74344,5.64156
-desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.62,-1.05056,1.82056
-desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.19,0.27344,3.66656
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,26.33,22.21112,29.96388
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,52.18,45.09904,58.61596
-desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.79,0.01584,3.07416
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.42,-1.21464,1.57964
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.43,-1.3144,1.6144
-desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.91,0.0568,3.2232
-desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,26.22,22.09656,29.97344
-desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.07,1.254,4.381
-desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.06,-1.52536,1.16536
-desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.69,-1.05608,1.96108
-desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.58,1.50152,5.20848
-desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.26,-1.35112,1.37112
-desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,40.18,35.16184,44.77316
-desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.47,-0.34776,2.74776
-desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,22.22,18.74056,25.20444
-desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,5.96,3.55024,7.90976
-desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.27,0.35688,3.71812
-desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.22,0.35096,3.61404
-desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.52,0.63776,3.85724
-desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.48,1.42024,5.06476
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.74,-0.89984,1.89984
-mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.21,-0.47704,2.39704
-tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.19,0.2724,3.6676
-tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.05,1.91344,5.74156
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.08,0.20304,3.48696
-tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.47,-0.32864,2.81364
-tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.53,-0.31424,2.88424
-tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.18,-0.52464,2.38964
-tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.55,-0.23504,2.87504
-tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.77,-1.09344,2.20844
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.73,1.67976,5.32024
-tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.29,-1.32336,1.40336
-tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.1,-0.84936,2.45936
-tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.44,0.58376,3.83624
-tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.86,-0.80968,2.05468
-tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.31,-0.7464,2.7764
-tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.67,0.7756,4.0644
-tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.55,-0.36712,2.97212
-tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.96,-0.7476,2.1776
-tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.72,-0.09904,3.08404
-tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.76,-0.03168,3.06668
-tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.56,-2.92184,8.43684
-tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.15,-23.66792,33.45292
-tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.7,0.7928,4.1322
-tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.95,-0.73672,2.14172
-tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.39,0.40752,3.92248
-tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.77,0.02752,3.03748
-tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.55,1.58456,5.01544
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,11.85,8.89872,14.24628
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.91,-0.70344,2.03344
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.17,-0.514,2.354
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.67,0.83512,4.03488
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,65.38,58.34688,71.94312
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,24.34,20.61064,27.59436
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.42,-0.23408,2.58408
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.35,0.59192,3.60308
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,20.48,16.9984,23.5016
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,12.8,10.14568,14.91932
+desk_samoasvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,6.5,4.35872,8.17128
+desk_sfgate.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.36,-0.31896,2.53396
+desk_tigersvg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,9.6,7.10944,11.64556
+desk_twitter.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.59,2.60232,6.06268
+desk_weather.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.28,-0.40312,2.48312
+desk_wowwiki.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.17,1.2952,4.5748
+desk_yahooanswers.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.8,0.0656,3.0344
+desk_youtube.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.5,-0.18048,2.69548
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,9.12,6.68872,11.05628
+mobi_wikipedia.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.4,-0.212,2.512
+tabl_androidpolice.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.89,0.99696,4.32304
+tabl_cnet.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.63,0.70712,4.08288
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,5.79,3.6756,7.4194
+tabl_cuteoverload.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.42,0.57576,3.77924
+tabl_deviantart.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.63,-0.06104,2.83604
+tabl_digg.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.32,-0.36648,2.52648
+tabl_engadget.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.44,-0.21552,2.60552
+tabl_frantzen.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,36.57,31.39936,41.38064
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.18,0.43552,3.41948
+tabl_gmail.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.17,-1.37344,1.19844
+tabl_googleblog.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.88,-0.74032,1.99032
+tabl_googlecalendar.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.64,0.828,3.977
+tabl_gspro.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.16,-0.51368,2.35368
+tabl_hsfi.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.49,-0.18968,2.68468
+tabl_mercurynews.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.2,-0.43672,2.34672
+tabl_mlb.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.52,-0.14232,2.69232
+tabl_mozilla.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.75,0.0492,2.9658
+tabl_nofolo.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,17.81,14.56216,20.59284
+tabl_nytimes.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.32,-0.30576,2.45076
+tabl_pravda.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.19,-0.466,2.361
+tabl_sahadan.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.49,0.68968,3.81532
+tabl_slashdot.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.1,0.39144,3.31856
+tabl_techmeme.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.71,-0.88728,1.81728
+tabl_ukwsj.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.9,0.20744,3.10256
+tabl_vnexpress.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.04,-0.66368,2.27368
+tabl_worldjournal.skp_simple_viewport_1000x1000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.17,1.2656,4.5894
+desk_amazon.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.19,-0.5064,2.4114
+desk_baidu.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.7,-0.03728,2.96228
+desk_blogger.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.6,-0.1792,2.8942
+desk_booking.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.0,1.00856,4.53144
+desk_carsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,58.46,50.78544,65.80456
+desk_chalkboard.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,130.61,116.21912,144.63088
+desk_css3gradients.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.69,-0.96576,1.87076
+desk_ebay.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.36,-0.43904,2.63904
+desk_espn.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.78,0.77592,4.30908
+desk_facebook.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.87,1.01968,4.25032
+desk_fontwipe.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.11,-1.50896,1.23396
+desk_forecastio.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.06,-1.50528,1.14028
+desk_gmailthread.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.65,1.6972,5.0978
+desk_googlehome.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.56,-1.08536,1.73036
+desk_googleplus.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.01,0.23872,3.28628
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,27.61,23.50832,31.28668
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,42.87,35.93136,49.64864
+desk_gws.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.7,-0.06688,2.97688
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.26,-1.36136,1.40636
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.31,-1.27512,1.41012
+desk_linkedin.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.87,0.06944,3.18556
+desk_mapsvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,27.71,23.53072,31.41428
+desk_mobilenews.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.94,1.16432,4.22568
+desk_oldinboxapp.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.03,-1.71336,1.33336
+desk_pinterest.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.52,-1.17208,1.72708
+desk_pokemonwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.63,1.73848,5.04652
+desk_rectangletransition.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.21,-1.41696,1.34196
+desk_samoasvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,42.25,37.04568,46.98932
+desk_sfgate.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.32,-0.45624,2.61624
+desk_tigersvg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,23.21,19.02696,27.05304
+desk_twitter.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,5.54,3.2844,7.3056
+desk_weather.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.83,-0.0884,3.2934
+desk_wowwiki.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.06,0.02352,3.66648
+desk_yahooanswers.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.31,0.51488,3.61012
+desk_youtube.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.04,1.19576,4.40924
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.55,-1.0544,1.6694
+mobi_wikipedia.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.81,-0.79504,1.92504
+tabl_androidpolice.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.03,0.186,3.419
+tabl_cnet.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.81,1.7228,5.4222
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.24,-0.5204,2.5404
+tabl_cuteoverload.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.24,-0.56088,2.59088
+tabl_deviantart.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.43,-0.26576,2.64576
+tabl_digg.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.07,-0.62592,2.27092
+tabl_engadget.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.38,-0.36072,2.63072
+tabl_frantzen.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.51,-1.29208,1.87708
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.77,1.78664,5.29836
+tabl_gmail.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.23,-1.34864,1.32364
+tabl_googleblog.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.92,-0.71448,2.06948
+tabl_googlecalendar.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.46,0.61168,3.82332
+tabl_gspro.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.85,-0.77832,1.99332
+tabl_hsfi.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.19,-0.58552,2.46552
+tabl_mercurynews.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.64,-0.09224,2.89724
+tabl_mlb.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.38,-0.29176,2.56676
+tabl_mozilla.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.76,-0.89112,1.91112
+tabl_nofolo.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.19,-0.54592,2.46092
+tabl_nytimes.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.57,-0.16648,2.81148
+tabl_pravda.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.44,0.68392,3.71108
+tabl_sahadan.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.16,0.12592,3.73908
+tabl_slashdot.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.35,0.4104,3.8296
+tabl_techmeme.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.76,-0.8708,1.8858
+tabl_ukwsj.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.35,0.26984,4.00516
+tabl_vnexpress.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.74,-0.05,3.045
+tabl_worldjournal.skp_simple_viewport_1000x1000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.69,1.72392,5.17608
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,12.14,9.0844,14.7056
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.97,-0.65752,2.08752
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.17,-0.5244,2.3894
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.71,0.84192,4.09308
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,63.8,44.83656,83.13844
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,25.53,21.68464,28.95036
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.42,-0.284,2.624
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.47,0.71192,3.74308
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,21.0,17.43608,24.06892
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,13.12,10.15736,15.66264
 desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.27,-1.2516,1.2916
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.51,0.72864,3.81136
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,5.51,3.45856,7.06644
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.4,-1.17224,1.48224
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,16.56,12.50576,20.05924
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.22,2.28184,5.68316
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,9.99,7.58968,11.91532
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.77,0.99832,4.03168
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,8.57,5.8604,10.8646
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.49,-1.11,1.605
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.52,-0.14176,2.69176
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,24.64,21.04664,27.76336
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.77,0.0584,2.9766
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.16,-1.37304,1.19804
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,7.74,5.48968,9.50032
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.84,1.052,4.143
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.12,-1.40992,1.15492
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,6.54,4.39584,8.21416
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,9.76,7.01704,12.07296
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,9.47,7.06168,11.39332
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,22.16,17.86328,25.80672
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,16.66,12.89112,20.00388
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,36.5,30.0904,42.3196
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.9,0.20728,3.10272
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,12.31,9.584,14.506
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,11.02,7.09832,14.80168
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.59,-0.26944,2.98444
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,17.87,13.94376,21.47624
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,14.77,11.08976,18.17524
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,81.06,69.2248,93.0552
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,21.36,18.0104,24.1996
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,13.23,10.23552,15.80948
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.49,-0.18984,2.68484
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,10.05,7.3724,12.2526
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,44.38,39.1272,49.1378
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.59,0.82224,3.87276
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.18,-1.35456,1.21956
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.82,-0.80632,1.96132
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.96,1.1128,4.3122
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.59,-0.05744,2.74244
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,10.02,7.56736,11.98764
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.38,-0.33112,2.61612
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.59,-0.07736,2.76736
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,15.32,12.40232,17.76268
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,20.12,16.0092,23.4408
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.35,-0.328,2.523
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.05,-0.5944,2.2094
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,55.66,25.43328,87.54172
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.39,0.6384,3.6566
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.75,-0.83008,1.83508
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,23.91,20.22384,27.14116
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.92,0.22616,3.12384
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.27,1.44752,4.60748
-desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.16,0.04488,3.79512
-desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.71,-0.04776,2.99776
-desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.98,0.04064,3.39936
-desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.0,1.0892,4.3858
-desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,70.02,60.21416,78.80584
-desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,112.35,97.28232,127.55768
-desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.08,-0.63712,2.30712
-desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.93,-0.18992,3.57492
-desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.73,0.81016,4.19984
-desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.75,1.6884,5.2866
-desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.16,-1.41312,1.24812
-desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.17,1.98392,5.92108
-desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.7,2.43056,6.54444
-desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.77,-0.89296,1.95796
-desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.13,0.2288,3.5662
-desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,27.79,22.14184,32.98816
-desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,29.68,24.50552,34.56448
-desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.69,-0.17656,3.04656
-desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.65,-1.27624,2.10124
-desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.47,-1.18896,1.65896
-desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.91,0.04616,3.30384
-desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,20.0,14.22984,25.82016
-desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.9,1.0672,4.2578
-desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.06,-1.50536,1.14036
-desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.29,-0.49376,2.57376
-desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.47,1.56152,4.88848
-desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.23,-1.48944,1.45444
-desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,40.77,35.72624,45.29376
-desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.37,-0.87784,3.16284
-desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,22.63,18.40624,26.46876
-desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,5.66,3.4248,7.4202
-desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.71,-0.11808,3.06308
-desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.47,0.64184,3.80816
-desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.18,0.31336,3.57164
-desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.34,0.4816,3.7184
-desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.79,-0.92312,1.97312
-mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.09,-0.59832,2.30332
-tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.18,0.2244,3.6156
-tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.95,1.85048,5.61952
-tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.19,1.1632,4.7168
-tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.16,0.32592,3.53408
-tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.57,-0.29752,2.95252
-tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.5,-0.39008,2.84508
-tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.2,0.34336,3.51164
-tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.04,-0.83408,2.46408
-tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.82,1.80328,5.36672
-tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.36,-1.22904,1.46404
-tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.93,-0.7548,2.1198
-tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.11,1.2608,4.4392
-tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.9,-0.86304,2.18804
-tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.6,-1.12992,3.56492
-tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.03,0.23616,3.33384
-tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.83,-0.25616,3.30116
-tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.23,-0.50904,2.50404
-tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.94,0.08408,3.30092
-tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.57,-0.49656,3.02156
-tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.11,0.33976,3.40524
-tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.31,0.19264,3.96736
-tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.49,0.70968,3.79032
-tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.89,-0.7924,2.0774
-tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.35,0.31888,3.96612
-tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.72,-0.0688,3.0238
-tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.58,2.40288,6.22212
\ No newline at end of file
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.92,-0.73432,2.09432
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,5.64,3.31584,7.53416
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.42,-1.15392,1.50392
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,16.66,12.87072,20.13928
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.17,2.07576,5.78424
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,10.61,8.06896,12.67604
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.79,0.99664,4.07836
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,8.95,6.47112,10.94888
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.5,-1.08032,1.59032
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.61,-0.0592,2.7892
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,25.28,21.41432,28.68568
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.83,0.14336,3.02664
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.17,-1.3436,1.1836
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,7.89,5.36552,9.98948
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.0,1.15896,4.36604
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.12,-1.41,1.155
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,6.84,4.67128,8.53872
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,10.2,7.50032,12.44968
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,9.72,7.27112,11.68888
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,22.52,18.554,25.971
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,15.64,12.71672,18.08328
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,35.75,31.06616,39.96884
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.91,0.19696,3.13804
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,12.7,9.97144,14.95856
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,10.8,8.16328,12.98172
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.61,-0.1404,2.8904
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,18.19,14.65264,21.10236
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,14.95,11.81,17.61
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,83.39,74.85544,91.42456
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,21.93,18.31312,25.04688
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,13.59,10.7504,15.9696
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.33,-0.31664,2.48664
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,10.18,7.63416,12.21584
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,44.99,39.52904,49.90596
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.45,0.66344,3.73656
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.18,-1.3548,1.2198
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.81,-0.79496,1.92496
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.0,1.1592,4.3658
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.66,-0.04304,2.85804
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,10.33,7.85208,12.32292
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.19,-0.44568,2.33568
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.62,-0.02992,2.77492
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,15.8,11.67944,19.64556
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,19.35,15.80736,22.44764
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.33,-0.31672,2.48672
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.05,-0.6548,2.2848
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,54.99,48.74768,60.72732
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.12,0.36984,3.39016
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.75,-0.85016,1.86016
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,24.48,20.11512,28.25488
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.01,0.3088,3.2212
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.73,1.87104,5.10396
+desk_amazon.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.36,-2.38776,5.11776
+desk_baidu.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.67,-0.14552,3.03052
+desk_blogger.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.6,-0.15928,2.86928
+desk_booking.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.03,1.086,4.524
+desk_carsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,61.35,53.69528,68.45472
+desk_chalkboard.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,118.19,104.52112,131.17888
+desk_css3gradients.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.72,-0.918,1.878
+desk_ebay.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.62,-0.11008,2.87508
+desk_espn.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.81,0.83392,4.32608
+desk_facebook.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.55,1.4424,5.1926
+desk_fontwipe.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.11,-1.44872,1.15872
+desk_forecastio.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.08,-1.46656,1.13656
+desk_gmailthread.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.26,2.03624,6.03376
+desk_googlehome.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.83,-0.82648,1.98648
+desk_googleplus.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.64,-0.09176,2.89676
+desk_googlespreadsheet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,28.91,24.66464,32.69536
+desk_googlespreadsheetdashed.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,30.64,26.04464,34.85036
+desk_gws.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.64,-0.08184,2.86184
+desk_jsfiddlebigcar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.57,-1.33752,2.06752
+desk_jsfiddlehumperclip.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.33,-1.30696,1.47196
+desk_linkedin.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.99,0.20992,3.30008
+desk_mapsvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,21.01,17.678,23.857
+desk_mobilenews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.85,0.95024,4.26976
+desk_oldinboxapp.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.03,-1.55288,1.13288
+desk_pinterest.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.81,-0.81504,1.95004
+desk_pokemonwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.59,1.69216,4.99284
+desk_rectangletransition.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.19,-1.38592,1.28092
+desk_samoasvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,42.35,37.1196,47.0754
+desk_sfgate.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.33,-0.39768,2.58768
+desk_tigersvg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,22.87,19.2872,25.9928
+desk_twitter.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,5.31,3.09168,7.03332
+desk_weather.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.4,-0.41256,2.67256
+desk_wowwiki.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.82,0.05344,3.11656
+desk_yahooanswers.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.01,0.12656,3.44844
+desk_youtube.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.24,0.45032,3.53468
+desk_youtubetvvideo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.59,-0.99752,1.68752
+mobi_wikipedia.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.83,-0.79696,1.97196
+tabl_androidpolice.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.08,0.23288,3.42712
+tabl_cnet.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.8,1.75352,5.36148
+tabl_culturalsolutions.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.11,1.21968,4.53532
+tabl_cuteoverload.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.43,-0.26504,2.64504
+tabl_deviantart.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.49,-0.30992,2.78992
+tabl_digg.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.0,-0.6608,2.1808
+tabl_engadget.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.08,0.1812,3.5138
+tabl_frantzen.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.78,-1.07328,2.18328
+tabl_gamedeksiam.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,3.99,2.05984,5.42516
+tabl_gmail.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.28,-1.28256,1.35256
+tabl_googleblog.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.71,-0.96824,1.91824
+tabl_googlecalendar.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.96,1.1124,4.3126
+tabl_gspro.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.81,-0.8452,1.9652
+tabl_hsfi.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.25,-0.53168,2.53168
+tabl_mercurynews.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.62,-0.19064,2.93064
+tabl_mlb.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.58,-0.10704,2.78204
+tabl_mozilla.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.79,-0.86328,1.94328
+tabl_nofolo.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.26,-0.50192,2.56192
+tabl_nytimes.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.38,-0.34088,2.60588
+tabl_pravda.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.14,0.27712,3.52788
+tabl_sahadan.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.25,0.4484,3.5816
+tabl_slashdot.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.42,0.60576,3.76424
+tabl_techmeme.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,0.77,-0.85184,1.90684
+tabl_ukwsj.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,2.4,0.41656,3.93344
+tabl_vnexpress.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,1.74,-0.05024,3.04524
+tabl_worldjournal.skp_simple_viewport_1000x1000_scalar_1.100000_gpu_,Perf-Win8-ShuttleA-HD7770-x86-Release-25th,4.79,2.63432,6.49068
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-GalaxyNexus-SGX540-Arm7-Debug/expected-results.json b/expectations/gm/Test-Android-GalaxyNexus-SGX540-Arm7-Debug/expected-results.json
index ac6bcdd..67723c6 100644
--- a/expectations/gm/Test-Android-GalaxyNexus-SGX540-Arm7-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-GalaxyNexus-SGX540-Arm7-Debug/expected-results.json
@@ -195,29 +195,23 @@
       ], 
       "ignore-failure": false
     }, 
-    "bicubicfilter_565.png": {
+    "astcbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864700347231029854
+          7296080463405164282
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "bicubicfilter_8888.png": {
+    "astcbitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10469536215464879914
+          7104155647358997780
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_565.png": {
       "allowed-digests": [
@@ -316,7 +310,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5556270988884295076
+          12687331394697954528
         ]
       ], 
       "reviewed-by-human": true
@@ -325,7 +319,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410204863204197194
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -1498,6 +1492,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -1729,6 +1741,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2354,7 +2384,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15764519043297885758
+          4104797309315770800
         ]
       ], 
       "reviewed-by-human": true
@@ -2363,7 +2393,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7935307680550293784
+          6544536706877310514
         ]
       ], 
       "reviewed-by-human": true
@@ -2381,7 +2411,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1557613698479648092
+          8097997023778848191
         ]
       ], 
       "reviewed-by-human": true
@@ -2390,7 +2420,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          686626615788563308
+          5836493341538608113
         ]
       ], 
       "reviewed-by-human": true
@@ -2408,7 +2438,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5930938593239004653
+          4165425675033352640
         ]
       ], 
       "reviewed-by-human": true
@@ -2417,7 +2447,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3190552677201665775
+          10152516748782571739
         ]
       ], 
       "reviewed-by-human": true
@@ -2435,7 +2465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4870317370734649728
+          8180502121217066191
         ]
       ], 
       "reviewed-by-human": true
@@ -2444,7 +2474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5783287451488289297
+          16993829969091028380
         ]
       ], 
       "reviewed-by-human": true
@@ -2498,19 +2528,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17707691143950027168
+          4792118895672570848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788619303593885819
+          11285887424651164487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -2567,7 +2597,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17138342910351740780
+          15418783980877386199
         ]
       ], 
       "reviewed-by-human": true
@@ -2576,7 +2606,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13937678633951136440
+          7882161322447216882
         ]
       ], 
       "reviewed-by-human": true
@@ -2594,7 +2624,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2256130412784819033
+          3184062263576953667
         ]
       ], 
       "reviewed-by-human": true
@@ -2603,7 +2633,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10471902765578272701
+          713799816796517938
         ]
       ], 
       "reviewed-by-human": true
@@ -2744,7 +2774,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9374541812861034293
+          11475660560101599954
         ]
       ], 
       "reviewed-by-human": true
@@ -2753,7 +2783,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2576698895183287698
+          7311723676588845146
         ]
       ], 
       "reviewed-by-human": true
@@ -2789,7 +2819,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3767760557629765982
+          4057230872151110302
         ]
       ], 
       "ignore-failure": false, 
@@ -2799,7 +2829,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12070678672447530766
+          9482070623821433904
         ]
       ], 
       "ignore-failure": false, 
@@ -2818,31 +2848,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -2851,7 +2875,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -2860,55 +2884,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6989712392624471913
+          17775297231868448514
         ]
       ], 
       "reviewed-by-human": true
@@ -2917,7 +2929,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10855232109519818829
+          12804472649182277577
         ]
       ], 
       "reviewed-by-human": true
@@ -2926,7 +2938,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -2935,7 +2947,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -2944,55 +2956,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2497837460215148124
+          6055955940623478607
         ]
       ], 
       "reviewed-by-human": true
@@ -3001,7 +3001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13192464168020553898
+          11797865288006977816
         ]
       ], 
       "reviewed-by-human": true
@@ -3010,7 +3010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -3019,7 +3019,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
         ]
       ], 
       "reviewed-by-human": true
@@ -3028,7 +3028,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          4886211991926050486
         ]
       ], 
       "reviewed-by-human": true
@@ -3037,7 +3037,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          8737545656412765906
         ]
       ], 
       "reviewed-by-human": true
@@ -3046,7 +3046,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -3055,7 +3055,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
         ]
       ], 
       "reviewed-by-human": true
@@ -3064,7 +3064,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          4707049264800437834
         ]
       ], 
       "reviewed-by-human": true
@@ -3073,7 +3073,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          3175389971476411688
         ]
       ], 
       "reviewed-by-human": true
@@ -3082,7 +3082,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
       "reviewed-by-human": true
@@ -3109,7 +3109,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5455618422902283397
+          15797039913993285826
         ]
       ], 
       "reviewed-by-human": true
@@ -3118,7 +3118,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14095817193753318732
+          17497164562330387900
         ]
       ], 
       "reviewed-by-human": true
@@ -3136,7 +3136,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          716171842978913864
+          273445276579232833
         ]
       ], 
       "reviewed-by-human": true
@@ -3145,7 +3145,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17171710908581496295
+          13357226331142394630
         ]
       ], 
       "reviewed-by-human": true
@@ -3172,7 +3172,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16452419234213932266
+          1802138798652377585
         ]
       ], 
       "reviewed-by-human": true
@@ -3181,7 +3181,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13347568447034524087
+          588269449619860245
         ]
       ], 
       "reviewed-by-human": true
@@ -3267,6 +3267,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3391,7 +3409,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -3400,7 +3418,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -3409,7 +3427,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -3418,7 +3436,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -3427,7 +3445,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -3436,7 +3454,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -3445,7 +3463,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -3454,7 +3472,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -3463,7 +3481,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -3472,7 +3490,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -3481,7 +3499,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -3490,7 +3508,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -3499,7 +3517,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -3508,7 +3526,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -3517,7 +3535,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -3526,7 +3544,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -3535,7 +3553,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -3544,7 +3562,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -3571,7 +3589,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -3580,7 +3598,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -3607,7 +3625,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -3616,7 +3634,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -3625,7 +3643,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -3634,57 +3652,63 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          4855908374887822167
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          11690691754075111299
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          4335659971728708662
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
@@ -3707,11 +3731,29 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2500355683115767624
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7818310295492545479
+          11716334334721910796
         ]
       ], 
       "ignore-failure": false, 
@@ -3721,7 +3763,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4994151175360770217
+          5693920054563327483
         ]
       ], 
       "ignore-failure": false, 
@@ -4060,6 +4102,150 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18181809164582745765
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14988814117683836650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863085462100832326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271247215169625597
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -4287,7 +4473,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -4314,7 +4500,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13538992606665750486
+          8988444324654919932
         ]
       ], 
       "reviewed-by-human": true
@@ -4448,11 +4634,29 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          741134624395776214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          357284903731074601
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3794665630847901594
+          13620335786972140736
         ]
       ], 
       "reviewed-by-human": true
@@ -4461,7 +4665,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7748801528548244433
+          17030111096598942390
         ]
       ], 
       "reviewed-by-human": true
@@ -4479,7 +4683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259128835424197006
+          1922338586017046100
         ]
       ], 
       "reviewed-by-human": true
@@ -4488,7 +4692,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13149265802466457140
+          3693078186234250164
         ]
       ], 
       "reviewed-by-human": true
@@ -4524,7 +4728,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6719033984262147569
+          9334915207072042375
         ]
       ], 
       "reviewed-by-human": true
@@ -4533,7 +4737,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9527595429529547733
+          4262113639047937913
         ]
       ], 
       "reviewed-by-human": true
@@ -4551,23 +4755,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8498778868685964382
+          9643897842146508458
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          880034339526468883
+          14154076457851775362
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219558445660995645
+          16816155573392653040
         ]
       ], 
       "reviewed-by-human": true
@@ -4576,7 +4782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          861754899676926834
+          15621659488709502951
         ]
       ], 
       "reviewed-by-human": true
@@ -4601,7 +4807,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15200137971968303012
+          14400660572715212845
         ]
       ], 
       "reviewed-by-human": true
@@ -4610,7 +4816,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199776944359958607
+          12820728063175372793
         ]
       ], 
       "reviewed-by-human": true
@@ -4628,23 +4834,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5274487773236388163
+          4458594706234736506
         ]
       ], 
       "reviewed-by-human": true
@@ -4653,7 +4861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10772725192724193725
+          7881653068493848399
         ]
       ], 
       "reviewed-by-human": true
@@ -4812,7 +5020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15118920252874319058
+          9075523320529578103
         ]
       ], 
       "reviewed-by-human": true
@@ -4821,7 +5029,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13213375518846743511
+          4131799565799962704
         ]
       ], 
       "reviewed-by-human": true
@@ -4839,7 +5047,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7394602124225746876
+          4095489997625677813
         ]
       ], 
       "reviewed-by-human": true
@@ -4848,7 +5056,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768949088352973106
+          17687576741285937089
         ]
       ], 
       "reviewed-by-human": true
@@ -4898,7 +5106,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14753870890166488787
+          13546074453897362674
         ]
       ], 
       "reviewed-by-human": true
@@ -4907,7 +5115,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12332409505555151686
+          2645433785253737964
         ]
       ], 
       "reviewed-by-human": true
@@ -5098,6 +5306,186 @@
       ], 
       "ignore-failure": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -5222,7 +5610,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15293668784585893125
+          4656886197492028969
         ]
       ], 
       "reviewed-by-human": true
@@ -5231,7 +5619,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17470748697630737319
+          10009949554846362902
         ]
       ], 
       "reviewed-by-human": true
@@ -5287,6 +5675,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -5486,7 +5910,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -5495,7 +5919,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -5509,6 +5933,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -5527,6 +5969,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -5545,6 +6005,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5576,7 +6054,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18000254716935645999
+          13710370929503896242
         ]
       ], 
       "reviewed-by-human": true
@@ -5585,7 +6063,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16383033135480419663
+          14868659503042841956
         ]
       ], 
       "reviewed-by-human": true
@@ -5621,7 +6099,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16422530932852428674
+          2214368729624239628
         ]
       ], 
       "reviewed-by-human": true
@@ -5630,7 +6108,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13797585911734062488
+          13695847048236137972
         ]
       ], 
       "reviewed-by-human": true
@@ -5648,7 +6126,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13221078215540522692
+          6757078992106948579
         ]
       ], 
       "reviewed-by-human": true
@@ -5657,7 +6135,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7149831205496297560
+          24796932854446382
         ]
       ], 
       "reviewed-by-human": true
@@ -6091,7 +6569,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8055681999420608630
+          1275265661982217699
         ]
       ], 
       "reviewed-by-human": true
@@ -6131,7 +6609,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14522519434293790013
+          7420045945089200912
         ]
       ], 
       "reviewed-by-human": true
@@ -6456,7 +6934,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14585555250092963383
+          13909757336310240518
         ]
       ], 
       "reviewed-by-human": true
@@ -6465,7 +6943,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6423558589708144215
+          17885518595384354919
         ]
       ], 
       "reviewed-by-human": true
@@ -6474,7 +6952,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11744373400809739356
+          11699531654048406518
         ]
       ], 
       "reviewed-by-human": true
@@ -6483,7 +6961,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8270526029969251327
+          4523091657809672686
         ]
       ], 
       "reviewed-by-human": true
@@ -6678,7 +7156,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10230426069067413407
+          18286981917824090179
         ]
       ], 
       "reviewed-by-human": true
@@ -6687,7 +7165,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15098401526248766364
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -6723,7 +7201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15528863190484305841
+          1369006746513120542
         ]
       ], 
       "reviewed-by-human": true
@@ -6732,7 +7210,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15197842121034928067
+          10584886924228958226
         ]
       ], 
       "reviewed-by-human": true
@@ -6741,13 +7219,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4806854696235085637
+          14688683472045987229
         ]
       ], 
       "bugs": [
-        2603
+        2905
       ], 
-      "ignore-failure": true
+      "reviewed-by-human": true
     }, 
     "texdata_565.png": {
       "allowed-digests": [
@@ -6786,6 +7264,33 @@
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          163112871246100159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -6818,10 +7323,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          804279550415026015
+          1763610880767920386
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -6848,7 +7353,8 @@
           7813081860549969723
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa4.png": {
       "allowed-digests": [
@@ -6884,7 +7390,8 @@
           10263284767330603632
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa4.png": {
       "allowed-digests": [
@@ -6899,7 +7406,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17022932193658353157
+          15732727687033594466
         ]
       ], 
       "reviewed-by-human": true
@@ -6908,7 +7415,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -6917,7 +7424,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -6998,7 +7505,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          72965177575169510
+          10762595506322490263
         ]
       ], 
       "reviewed-by-human": true
@@ -7025,7 +7532,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13395432061591976419
+          17049896290947009259
         ]
       ], 
       "reviewed-by-human": true
@@ -7174,6 +7681,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7170409368469409463
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7170409368469409463
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14344016941486954089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14344016941486954089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -7286,7 +7901,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3394570787947912684
+          3112652115716203250
         ]
       ], 
       "reviewed-by-human": true
@@ -7295,7 +7910,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4231863532718175149
+          12938112915997113104
         ]
       ], 
       "reviewed-by-human": true
@@ -7304,7 +7919,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15068259611285548534
+          6881445176597662698
         ]
       ], 
       "reviewed-by-human": true
@@ -7339,7 +7954,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5776168118091758288
+          17945782884039236964
         ]
       ], 
       "reviewed-by-human": true
@@ -7366,7 +7981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14864763259786294626
+          15533171637285737420
         ]
       ], 
       "reviewed-by-human": true
@@ -7393,10 +8008,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14286000270409792100
+          7278542263334512857
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16324383818446088765
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-GalaxyNexus-SGX540-Arm7-Release/expected-results.json b/expectations/gm/Test-Android-GalaxyNexus-SGX540-Arm7-Release/expected-results.json
index a8fbc2d..cf2ecd9 100644
--- a/expectations/gm/Test-Android-GalaxyNexus-SGX540-Arm7-Release/expected-results.json
+++ b/expectations/gm/Test-Android-GalaxyNexus-SGX540-Arm7-Release/expected-results.json
@@ -195,29 +195,23 @@
       ], 
       "ignore-failure": false
     }, 
-    "bicubicfilter_565.png": {
+    "astcbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864700347231029854
+          7296080463405164282
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "bicubicfilter_8888.png": {
+    "astcbitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10469536215464879914
+          7104155647358997780
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_565.png": {
       "allowed-digests": [
@@ -316,7 +310,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5556270988884295076
+          12687331394697954528
         ]
       ], 
       "reviewed-by-human": true
@@ -325,7 +319,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410204863204197194
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -1498,6 +1492,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -1729,6 +1741,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2354,7 +2384,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15764519043297885758
+          4104797309315770800
         ]
       ], 
       "reviewed-by-human": true
@@ -2363,7 +2393,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7935307680550293784
+          6544536706877310514
         ]
       ], 
       "reviewed-by-human": true
@@ -2381,7 +2411,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1557613698479648092
+          8097997023778848191
         ]
       ], 
       "reviewed-by-human": true
@@ -2390,7 +2420,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          686626615788563308
+          5836493341538608113
         ]
       ], 
       "reviewed-by-human": true
@@ -2408,7 +2438,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5930938593239004653
+          4165425675033352640
         ]
       ], 
       "reviewed-by-human": true
@@ -2417,7 +2447,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3190552677201665775
+          10152516748782571739
         ]
       ], 
       "reviewed-by-human": true
@@ -2435,7 +2465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4870317370734649728
+          8180502121217066191
         ]
       ], 
       "reviewed-by-human": true
@@ -2444,7 +2474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5783287451488289297
+          16993829969091028380
         ]
       ], 
       "reviewed-by-human": true
@@ -2498,19 +2528,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17707691143950027168
+          4792118895672570848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788619303593885819
+          11285887424651164487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -2567,7 +2597,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17138342910351740780
+          15418783980877386199
         ]
       ], 
       "reviewed-by-human": true
@@ -2576,7 +2606,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13937678633951136440
+          7882161322447216882
         ]
       ], 
       "reviewed-by-human": true
@@ -2594,7 +2624,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2256130412784819033
+          3184062263576953667
         ]
       ], 
       "reviewed-by-human": true
@@ -2603,7 +2633,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10471902765578272701
+          713799816796517938
         ]
       ], 
       "reviewed-by-human": true
@@ -2744,7 +2774,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9374541812861034293
+          11475660560101599954
         ]
       ], 
       "reviewed-by-human": true
@@ -2753,7 +2783,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2576698895183287698
+          7311723676588845146
         ]
       ], 
       "reviewed-by-human": true
@@ -2789,7 +2819,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3767760557629765982
+          4057230872151110302
         ]
       ], 
       "ignore-failure": false, 
@@ -2799,7 +2829,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12070678672447530766
+          9482070623821433904
         ]
       ], 
       "ignore-failure": false, 
@@ -2818,31 +2848,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -2851,7 +2875,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -2860,55 +2884,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6989712392624471913
+          17775297231868448514
         ]
       ], 
       "reviewed-by-human": true
@@ -2917,7 +2929,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10855232109519818829
+          12804472649182277577
         ]
       ], 
       "reviewed-by-human": true
@@ -2926,7 +2938,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -2935,7 +2947,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -2944,55 +2956,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2497837460215148124
+          6055955940623478607
         ]
       ], 
       "reviewed-by-human": true
@@ -3001,7 +3001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13192464168020553898
+          11797865288006977816
         ]
       ], 
       "reviewed-by-human": true
@@ -3010,7 +3010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -3019,7 +3019,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
         ]
       ], 
       "reviewed-by-human": true
@@ -3028,7 +3028,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          4886211991926050486
         ]
       ], 
       "reviewed-by-human": true
@@ -3037,7 +3037,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          8737545656412765906
         ]
       ], 
       "reviewed-by-human": true
@@ -3046,7 +3046,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -3055,7 +3055,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
         ]
       ], 
       "reviewed-by-human": true
@@ -3064,7 +3064,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          4707049264800437834
         ]
       ], 
       "reviewed-by-human": true
@@ -3073,7 +3073,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          3175389971476411688
         ]
       ], 
       "reviewed-by-human": true
@@ -3082,7 +3082,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
       "reviewed-by-human": true
@@ -3109,7 +3109,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5455618422902283397
+          15797039913993285826
         ]
       ], 
       "reviewed-by-human": true
@@ -3118,7 +3118,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14095817193753318732
+          17497164562330387900
         ]
       ], 
       "reviewed-by-human": true
@@ -3136,7 +3136,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          716171842978913864
+          273445276579232833
         ]
       ], 
       "reviewed-by-human": true
@@ -3145,7 +3145,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17171710908581496295
+          13357226331142394630
         ]
       ], 
       "reviewed-by-human": true
@@ -3172,7 +3172,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16452419234213932266
+          1802138798652377585
         ]
       ], 
       "reviewed-by-human": true
@@ -3181,7 +3181,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13347568447034524087
+          588269449619860245
         ]
       ], 
       "reviewed-by-human": true
@@ -3267,6 +3267,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3391,7 +3409,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -3400,7 +3418,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -3409,7 +3427,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -3418,7 +3436,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -3427,7 +3445,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -3436,7 +3454,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -3445,7 +3463,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -3454,7 +3472,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -3463,7 +3481,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -3472,7 +3490,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -3481,7 +3499,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -3490,7 +3508,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -3499,7 +3517,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -3508,7 +3526,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -3517,7 +3535,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -3526,7 +3544,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -3535,7 +3553,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -3544,7 +3562,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -3571,7 +3589,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -3580,7 +3598,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -3607,7 +3625,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -3616,7 +3634,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -3625,7 +3643,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -3634,57 +3652,63 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          4855908374887822167
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          11690691754075111299
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          4335659971728708662
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
@@ -3707,11 +3731,29 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2500355683115767624
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7818310295492545479
+          11716334334721910796
         ]
       ], 
       "ignore-failure": false, 
@@ -3721,7 +3763,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4994151175360770217
+          5693920054563327483
         ]
       ], 
       "ignore-failure": false, 
@@ -4060,6 +4102,150 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18181809164582745765
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14988814117683836650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863085462100832326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271247215169625597
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -4287,7 +4473,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -4314,7 +4500,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13538992606665750486
+          8988444324654919932
         ]
       ], 
       "reviewed-by-human": true
@@ -4440,11 +4626,29 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          741134624395776214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          357284903731074601
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3794665630847901594
+          13620335786972140736
         ]
       ], 
       "reviewed-by-human": true
@@ -4453,7 +4657,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7748801528548244433
+          17030111096598942390
         ]
       ], 
       "reviewed-by-human": true
@@ -4471,7 +4675,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259128835424197006
+          1922338586017046100
         ]
       ], 
       "reviewed-by-human": true
@@ -4480,7 +4684,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13149265802466457140
+          3693078186234250164
         ]
       ], 
       "reviewed-by-human": true
@@ -4516,7 +4720,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6719033984262147569
+          9334915207072042375
         ]
       ], 
       "reviewed-by-human": true
@@ -4525,7 +4729,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9527595429529547733
+          4262113639047937913
         ]
       ], 
       "reviewed-by-human": true
@@ -4543,23 +4747,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8498778868685964382
+          9643897842146508458
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          880034339526468883
+          14154076457851775362
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219558445660995645
+          16816155573392653040
         ]
       ], 
       "reviewed-by-human": true
@@ -4568,7 +4774,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          861754899676926834
+          15621659488709502951
         ]
       ], 
       "reviewed-by-human": true
@@ -4593,7 +4799,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15200137971968303012
+          14400660572715212845
         ]
       ], 
       "reviewed-by-human": true
@@ -4602,7 +4808,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199776944359958607
+          12820728063175372793
         ]
       ], 
       "reviewed-by-human": true
@@ -4620,23 +4826,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5274487773236388163
+          4458594706234736506
         ]
       ], 
       "reviewed-by-human": true
@@ -4645,7 +4853,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10772725192724193725
+          7881653068493848399
         ]
       ], 
       "reviewed-by-human": true
@@ -4804,7 +5012,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15118920252874319058
+          9075523320529578103
         ]
       ], 
       "reviewed-by-human": true
@@ -4813,7 +5021,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13213375518846743511
+          4131799565799962704
         ]
       ], 
       "reviewed-by-human": true
@@ -4831,7 +5039,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7394602124225746876
+          4095489997625677813
         ]
       ], 
       "reviewed-by-human": true
@@ -4840,7 +5048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768949088352973106
+          17687576741285937089
         ]
       ], 
       "reviewed-by-human": true
@@ -4890,7 +5098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14753870890166488787
+          13546074453897362674
         ]
       ], 
       "reviewed-by-human": true
@@ -4899,7 +5107,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12332409505555151686
+          2645433785253737964
         ]
       ], 
       "reviewed-by-human": true
@@ -5090,6 +5298,186 @@
       ], 
       "ignore-failure": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -5214,7 +5602,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15293668784585893125
+          4656886197492028969
         ]
       ], 
       "reviewed-by-human": true
@@ -5223,7 +5611,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17470748697630737319
+          10009949554846362902
         ]
       ], 
       "reviewed-by-human": true
@@ -5279,6 +5667,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -5478,7 +5902,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -5487,7 +5911,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -5501,6 +5925,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -5519,6 +5961,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -5537,6 +5997,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5568,7 +6046,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18000254716935645999
+          13710370929503896242
         ]
       ], 
       "reviewed-by-human": true
@@ -5577,7 +6055,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16383033135480419663
+          14868659503042841956
         ]
       ], 
       "reviewed-by-human": true
@@ -5613,7 +6091,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16422530932852428674
+          2214368729624239628
         ]
       ], 
       "reviewed-by-human": true
@@ -5622,7 +6100,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13797585911734062488
+          13695847048236137972
         ]
       ], 
       "reviewed-by-human": true
@@ -5640,7 +6118,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13221078215540522692
+          6757078992106948579
         ]
       ], 
       "reviewed-by-human": true
@@ -5649,7 +6127,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7149831205496297560
+          24796932854446382
         ]
       ], 
       "reviewed-by-human": true
@@ -6083,7 +6561,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8055681999420608630
+          1275265661982217699
         ]
       ], 
       "reviewed-by-human": true
@@ -6123,7 +6601,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14522519434293790013
+          7420045945089200912
         ]
       ], 
       "reviewed-by-human": true
@@ -6448,7 +6926,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14585555250092963383
+          13909757336310240518
         ]
       ], 
       "reviewed-by-human": true
@@ -6457,7 +6935,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6423558589708144215
+          17885518595384354919
         ]
       ], 
       "reviewed-by-human": true
@@ -6466,7 +6944,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11744373400809739356
+          11699531654048406518
         ]
       ], 
       "reviewed-by-human": true
@@ -6475,7 +6953,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8270526029969251327
+          4523091657809672686
         ]
       ], 
       "reviewed-by-human": true
@@ -6670,7 +7148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10230426069067413407
+          18286981917824090179
         ]
       ], 
       "reviewed-by-human": true
@@ -6679,7 +7157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15098401526248766364
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -6715,7 +7193,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15528863190484305841
+          1369006746513120542
         ]
       ], 
       "reviewed-by-human": true
@@ -6724,7 +7202,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15197842121034928067
+          10584886924228958226
         ]
       ], 
       "reviewed-by-human": true
@@ -6733,13 +7211,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4806854696235085637
+          14688683472045987229
         ]
       ], 
       "bugs": [
-        2603
+        2905
       ], 
-      "ignore-failure": true
+      "reviewed-by-human": true
     }, 
     "texdata_565.png": {
       "allowed-digests": [
@@ -6778,6 +7256,33 @@
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          163112871246100159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -6810,10 +7315,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          804279550415026015
+          1763610880767920386
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -6840,7 +7345,8 @@
           7813081860549969723
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa4.png": {
       "allowed-digests": [
@@ -6876,7 +7382,8 @@
           10263284767330603632
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa4.png": {
       "allowed-digests": [
@@ -6891,7 +7398,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17022932193658353157
+          15732727687033594466
         ]
       ], 
       "reviewed-by-human": true
@@ -6900,7 +7407,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -6909,7 +7416,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -6990,7 +7497,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          72965177575169510
+          10762595506322490263
         ]
       ], 
       "reviewed-by-human": true
@@ -7017,7 +7524,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13395432061591976419
+          17049896290947009259
         ]
       ], 
       "reviewed-by-human": true
@@ -7166,6 +7673,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7170409368469409463
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7170409368469409463
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14344016941486954089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14344016941486954089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -7278,7 +7893,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3394570787947912684
+          3112652115716203250
         ]
       ], 
       "reviewed-by-human": true
@@ -7287,7 +7902,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4231863532718175149
+          12938112915997113104
         ]
       ], 
       "reviewed-by-human": true
@@ -7296,7 +7911,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15068259611285548534
+          6881445176597662698
         ]
       ], 
       "reviewed-by-human": true
@@ -7331,7 +7946,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5776168118091758288
+          17945782884039236964
         ]
       ], 
       "reviewed-by-human": true
@@ -7358,7 +7973,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14864763259786294626
+          15533171637285737420
         ]
       ], 
       "reviewed-by-human": true
@@ -7385,10 +8000,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14286000270409792100
+          7278542263334512857
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16324383818446088765
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-IntelRhb-SGX544-x86-Release/expected-results.json b/expectations/gm/Test-Android-IntelRhb-SGX544-x86-Release/expected-results.json
deleted file mode 100644
index b2626ec..0000000
--- a/expectations/gm/Test-Android-IntelRhb-SGX544-x86-Release/expected-results.json
+++ /dev/null
@@ -1,9194 +0,0 @@
-{
-  "actual-results": {
-    "failed": null, 
-    "failure-ignored": null, 
-    "no-comparison": null, 
-    "succeeded": null
-  }, 
-  "expected-results": {
-    "3x3bitmaprect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16998423976396106083
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "3x3bitmaprect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2054956815327187963
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "3x3bitmaprect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2054956815327187963
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "aaclip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5680982666881858509
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "aaclip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3732865537665519508
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "aaclip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10348117792540005656
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "aarectmodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3404105191202303432
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "aarectmodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11273986525140282221
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "aarectmodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5564579097835689226
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "alphagradients_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1062660886109823876
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "alphagradients_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8685680158225267849
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "alphagradients_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16679719501773877249
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "android_paint_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14311572539143932530
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "android_paint_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8184968261467646356
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "android_paint_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16578618981524164940
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "arcofzorro_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14297291255102949024
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "arcofzorro_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12650638297902351267
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "arcofzorro_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5103413628089441416
-        ]
-      ]
-    }, 
-    "arithmode_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6535059923367762503
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "arithmode_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1951236732185589783
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "arithmode_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15667116140869597659
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bat_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15429625158026413569
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bezier_conic_effects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11753547281694642402
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bezier_cubic_effects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12989453616557980490
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bezier_quad_effects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16976789512297453380
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17080656068138564372
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigblurs_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14704206703218007573
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigblurs_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17309852422285247848
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigblurs_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17467678310125758092
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigmatrix_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6169251833522681202
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigmatrix_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10455976041474647335
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigmatrix_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18154086740989312733
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigtext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9208106745937650664
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigtext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6224084673272175658
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigtext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11616592246687288786
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmap_premul_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3459248890389921752
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmap_premul_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1875487390803094182
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmap_premul_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1875487390803094182
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapfilters_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          299280079964293648
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapfilters_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1785801269079633261
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapfilters_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8975361232797313708
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmaprect_i_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18028564147828277613
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_i_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14065905418589114539
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_i_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8511579297892894623
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_s_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18028564147828277613
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_s_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14065905418589114539
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_s_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8511579297892894623
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprecttest_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1454528164630516875
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprecttest_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1454528164630516875
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprecttest_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1454528164630516875
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapscroll_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6745916709387193253
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapscroll_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4717735016506370050
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapscroll_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          930590022062657844
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapshaders_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          787402053855503258
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapshaders_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13897226711214500859
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapshaders_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4527303960541121992
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapsource_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15581542612528711266
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapsource_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13071585613760610277
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapsource_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5847234706736959503
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bleed_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1844781142419806112
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bleed_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          749193672577578009
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bleed_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9718993354602675709
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurcircles_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8149334815780864538
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurcircles_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11187657384039514790
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurquickreject_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14575894174086753692
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurquickreject_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1951057418144050940
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurquickreject_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8292097632245464218
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          820069996201877993
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3184582570657056326
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3184582570657056326
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12718077445807995842
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5778991912674004218
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5778991912674004218
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8935160718296765370
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16776390169922007578
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16776390169922007578
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2256669791146023451
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10179579145235258409
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10179579145235258409
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14392183012539686738
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16043278436798717097
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16043278436798717097
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14390657820413340948
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          795828165830353598
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          795828165830353598
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13601707396267686719
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8459602697994167638
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8459602697994167638
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10010715170666325693
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14526183591501064820
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14526183591501064820
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16822449160546304858
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2027939861397155283
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2027939861397155283
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7324830233289320569
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16228083818774745601
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16228083818774745601
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3539263275279493989
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11235472972448689767
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11235472972448689767
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18397664291113348978
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3014025170376903742
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3014025170376903742
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8147548538595899093
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8450430456683814098
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8450430456683814098
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3392741620327676409
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6934363565052222509
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6934363565052222509
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5777905000809157737
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6260375605261477035
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6260375605261477035
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          106403897902062488
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          685229733900948221
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          685229733900948221
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15285897477966750444
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8078454220178362362
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8078454220178362362
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17750039418684378027
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          805644383472349129
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          805644383472349129
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14103173815576510618
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8586295779506545029
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8586295779506545029
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17524943648572389133
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10060482719496990794
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10060482719496990794
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8152120831203711857
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10705231956829285301
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10705231956829285301
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12328862147889454268
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15258994592739155032
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15258994592739155032
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2981653799231691010
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14266854668713428040
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14266854668713428040
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13987214398939984878
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7552003167091473918
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7552003167091473918
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17480567211870826097
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17796133053007318503
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17796133053007318503
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17480567211870826097
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4056266015657707537
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4056266015657707537
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11526247382010115107
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17802184554241704666
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17802184554241704666
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14693279281973817316
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5373137501337162900
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5373137501337162900
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13364339805031281090
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8793723769315696288
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8793723769315696288
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          778688345972082046
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3351391123811424042
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3351391123811424042
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9837373898678543005
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8753902296095062956
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8753902296095062956
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8768734282047712040
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5736147449766359017
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5736147449766359017
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13703672010266950657
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3606241125593407269
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3606241125593407269
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3915594753875998111
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15504874507306860669
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15504874507306860669
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3431843565557123885
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5438277324777890642
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5438277324777890642
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12762400988164231611
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15858720212484315695
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15858720212484315695
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_inner_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          621096468045033319
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_inner_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5693351230273671931
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_inner_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7704622158080950782
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_normal_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17577119326547731450
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_normal_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17173516333093181363
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_normal_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4623570465766786751
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_outer_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8428983424693155205
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_outer_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10227974232335477600
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_outer_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13463578097308563300
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_solid_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17328977028061879775
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_solid_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16067654207889334831
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_solid_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18282763485464690287
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3696341484825569467
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11980986810369723513
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          260989999972072184
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurroundrect-WH[100x100]-unevenCorners_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10612639499777084126
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurroundrect-WH[100x100]-unevenCorners_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6035759061702062244
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurroundrect-WH[100x100]-unevenCorners_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8500043106468453797
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurs_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17805090981812894527
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurs_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17800001274907447804
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurs_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18332742573339604858
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "canvas-layer-state_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12670698167582780333
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "canvas-layer-state_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12670698167582780333
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "canvas-state_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11592955199341201053
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "canvas-state_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11592955199341201053
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "canvas-state_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5541967782360980927
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext1_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6708894799496057436
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext1_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6708894799496057436
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext1_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6708894799496057436
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13774733025575034199
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13774733025575034199
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3313052130644407339
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circles_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6008092610982260089
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circles_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14991965560443449693
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circles_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17106055778626858542
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circular-clips_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7045926575348655010
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circular-clips_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7045926575348655010
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circular-clips_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1988347527319338472
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clamped_gradients_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6740406662310759992
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clamped_gradients_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12600235552582834170
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clamped_gradients_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15658888448911378390
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp-hq_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5543970311616574408
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp-hq_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9243927175489158803
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp-hq_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5000282312660607550
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "clipped-bitmap-shaders-clamp_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6731999058828201370
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6731999058828201370
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6731999058828201370
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror-hq_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14000830941634575767
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror-hq_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14412729226029504152
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror-hq_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18066226042033064966
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "clipped-bitmap-shaders-mirror_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10131313151475985201
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10131313151475985201
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10131313151475985201
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile-hq_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5937007347321497195
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile-hq_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6655127558305687514
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile-hq_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17436695901683300479
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "clipped-bitmap-shaders-tile_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          25307406092894825
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          25307406092894825
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          25307406092894825
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clippedcubic_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2047816653827409443
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clippedcubic_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2047816653827409443
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clippedcubic_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10318279557324425152
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "cmykjpeg_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13052709698662664204
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "cmykjpeg_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9927483517871541702
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "cmykjpeg_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9927483517871541702
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colorfilterimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17051103650973594106
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colorfilterimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1025940906896326990
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colorfilterimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          192532786620859689
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colormatrix_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3235581033534814469
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colormatrix_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5008998920935758481
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colormatrix_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1575688773869978322
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colortype_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7789211976036245847
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "colortype_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12063547141229638542
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "colortype_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15432189428597356877
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1971136545200141017
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7558229948134696044
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7558229948134696044
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_path_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16086429144316222800
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_path_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12832097210600987517
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_path_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          626377265510811395
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_path_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13497374237280200272
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_path_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13907447324398926215
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_path_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6767202152973974411
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rect_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4388703640234091457
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rect_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6840582159469938207
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rect_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16628817470554933537
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_rrect_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11609605102436644365
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_rrect_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6484021739759757221
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_rrect_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12795866211978733736
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_rrect_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13632122222988723717
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rrect_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14609392979961079625
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rrect_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7607167258483373168
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2183310436696200447
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          744025704131278337
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12123725839294251145
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_layer_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3659943080425900329
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_layer_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1205455874446983865
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_layer_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6305857535625023602
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12748157450884875422
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12349332232493061534
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15377182906618145948
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_layer_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2492514386480839663
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_layer_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2975399947010553387
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_layer_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12578511015260635257
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "composeshader_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4616535333272790055
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "composeshader_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7653047818906774476
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "composeshader_alpha_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2785143308349902483
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "composeshader_alpha_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3069347792056802140
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "composeshader_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13476719363156020502
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "convex_poly_clip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17917330964671139160
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "convex_poly_clip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5601850589005836986
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "convex_poly_clip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3931972752458035902
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "convex_poly_effect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13562837227301896730
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "convexpaths_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12930829906409283378
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "convexpaths_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5590017600958012619
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "convexpaths_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10865343678259724198
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "copyTo4444_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13047964648578320887
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "copyTo4444_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13512184095617016052
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "copyTo4444_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13512184095617016052
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "cubicclosepath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13521200955406107775
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicclosepath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17912401236231679127
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicclosepath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8341536688885218293
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicpath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6583472814997240235
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicpath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9058335517377211817
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicpath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11731651872638524201
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dashcubics_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1243485597747942942
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashcubics_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          561323664416995153
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashcubics_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10530014763886697529
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dashing2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7522047842497784488
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16976334130763507258
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          751221660731865592
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing3_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5458443768353447519
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing3_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2000525185460569669
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing3_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1456612750003227022
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing4_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3905274096451946067
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dashing4_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1394068287232006716
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dashing_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2587070015488181148
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11645276935331048518
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18015592834088027197
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "degeneratesegments_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4578086267105259029
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "degeneratesegments_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1521449590373842396
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "degeneratesegments_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16978708541322119393
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "deviceproperties_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5004276491084267368
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "deviceproperties_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7746803903450904418
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "discard_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1696674976993092902
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "displacement_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10557537838778749160
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "displacement_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7089896533323038526
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "displacement_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12394438758744026163
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "distantclip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2455115578822786504
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "distantclip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2455115578822786504
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "distantclip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2455115578822786504
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_high_512_256_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15154730871764821124
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_checkerboard_high_512_256_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          194619977446273533
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_checkerboard_high_512_256_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9008293750211777201
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_checkerboard_low_512_256_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10232582998248890344
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_low_512_256_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1233814311003427744
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16704802669726334024
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_medium_512_256_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1203257848312793050
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3984265676088058160
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          992494534717898142
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_checkerboard_none_512_256_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3646964297203490771
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_none_512_256_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17145060002425698132
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3849621410806513723
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_high_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17264975515988900071
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_image_high_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3911174280407842684
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_image_high_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4191803426779135801
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_image_low_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6765275404189723366
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6485054271692420021
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3676645757082565261
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13571956230133077991
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8840752418158714253
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16700399834273149128
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_image_none_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14270272450959568098
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13220718652543317787
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          142674759365826172
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_text_high_72.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16519436267890610369
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_high_72.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11825439513932272119
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_high_72.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12649869831822432987
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_low_72.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14912104351264232935
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_low_72.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15487921510411770637
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_low_72.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4685776213094226352
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_medium_72.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10684547795556100510
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_medium_72.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7577014624371342379
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_medium_72.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13141085848085289030
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_none_72.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15469192468104182267
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_none_72.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9482106153945169929
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_none_72.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          326696583887893469
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drawbitmapmatrix_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5230239791132469231
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "drawbitmapmatrix_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15096840641759877301
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "drawbitmapmatrix_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16772618235934374845
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "drawlooper_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5134999156369384783
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drawlooper_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12521309603120134056
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drawlooper_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8141288215353462246
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dropshadowimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17176620593335973597
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dropshadowimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13663064994494293289
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dropshadowimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6983309335249454236
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drrect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7282537335075785928
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drrect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8863849031372460120
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drrect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3779095071531514150
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "emptypath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18094470146972105480
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "emptypath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16729138449439522348
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "emptypath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8158239880603207616
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15855537393781495131
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10396043285211938891
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_ktx_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10660132459335344948
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_ktx_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17338451294848191155
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_npot_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4755621039067033683
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_npot_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9352463391366748675
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_pkm_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10660132459335344948
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_pkm_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17338451294848191155
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "extractbitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11559795738519917215
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "extractbitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11559795738519917215
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "extractbitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11559795738519917215
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "factory_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4768741511907258218
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "factory_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11150486540244810089
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "factory_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11150486540244810089
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fatpathfill_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7781767658511133788
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fatpathfill_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15926472232550846517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fatpathfill_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2028184591354531695
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6394623980536394421
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4586322702989781686
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17693182030144018869
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypespersp_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13448151295100783239
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypespersp_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1122618131815112502
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypespersp_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8397994591127819291
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_192_192_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7419227591265311221
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_192_192_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9941389284961210315
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_192_192_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13872974075155174385
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4712618105826416872
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6814786601958107546
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13175000843516560645
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_32_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11309219541124250528
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_32_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8042312968331390097
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_32_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12621944278316839160
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_8_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17324002053051694427
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_8_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10616193688896439855
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_8_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16892871506538567763
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_4_4_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10302533496874247276
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_4_4_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12569931102745160299
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_4_4_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3197389257186652855
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_128.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          842153490277803410
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_128.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7577999994704956939
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_128.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9016131185709747295
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_16.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17152997950184504727
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_16.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11428391327691184765
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_16.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3293710486546961723
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_256.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4139187976413040197
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_256.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14073034095251842923
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_256.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3264292480595545579
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_32.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17106863847823042087
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_32.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12215969181637652211
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_32.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16029411561224473754
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8457226704515835046
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13673721686942765185
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3518436430982597449
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_64.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3068653512092670589
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_64.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15170271034615721666
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_64.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15252086719294314503
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_10.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11543071368100420439
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_10.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13979895877101196974
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_10.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12174104284041385825
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_3.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10562352406325167130
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_3.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4740040018036044870
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_3.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14844459319468499053
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_7.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2358351893182060187
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_7.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17870285622555231718
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_7.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          434039534086427901
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "fontcache_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          994935463198632465
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "fontmgr_iter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_iter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_iter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_match_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_match_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_match_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontscaler_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13697197938526917158
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "fontscaler_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9665018536861377984
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "fontscaler_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10979683921873521339
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gammatext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11098600005518612422
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gammatext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12924368150056635888
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gammatext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9988534402643805553
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "getpostextpath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2033602119516310281
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "getpostextpath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8346234615044725182
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "getpostextpath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1245896931972085138
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "giantbitmap_clamp_bilerp_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8844253733895577971
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          373739036198791129
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8112152499985052384
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3486485929104356236
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10633738215712183989
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8430366169989348557
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17592263249674059658
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17592263249674059658
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17664227249162604428
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9837143541713078189
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9837143541713078189
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9837143541713078189
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4418651112090392588
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12707263608068309424
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18436669324822800859
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3198037782278889365
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6252132392610996150
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9662671494674386025
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7897959591317755434
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7897959591317755434
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13311283151063713989
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18105452151182268887
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18105452151182268887
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13431550740599981254
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14124862738846038338
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18058439211441456286
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16302744549495549154
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8227734820754620843
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11021884726574795651
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4906927396615969438
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9093746103412643649
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9093746103412643649
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13294138182223094091
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14547059667322106211
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14547059667322106211
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1623953817113568190
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_dirty_laundry_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16978210180572955621
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_dirty_laundry_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          637854104407104115
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_dirty_laundry_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4735033599846615424
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_matrix_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9800597089191342482
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_matrix_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11303638772874009054
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_matrix_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10145849591466155435
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_edge_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14049649032069259181
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_edge_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8533660654825840563
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_edge_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8565726929159118677
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_inside_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2230084888912360694
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_inside_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7465934387832943420
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_inside_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5119195493073943472
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_outside_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16953788240617605317
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_outside_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17033624275484244376
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_outside_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8194516921738963656
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12097193819749785352
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15403609442106846169
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_degenerate_2pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2419426995212058042
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_degenerate_2pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6029254312400609793
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_degenerate_2pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13313927878342351507
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13999764467348834395
-        ]
-      ], 
-      "ignore-failure": true
-    }, 
-    "gradients_local_perspective_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3955747071082596728
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_local_perspective_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10472560090813482435
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_local_perspective_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10047289731704020189
-        ]
-      ], 
-      "ignore-failure": true
-    }, 
-    "gradients_many_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7893853359175854146
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_many_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5219979658561439244
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_many_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9465514724720153003
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_no_texture_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          225020687293424504
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_no_texture_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11527542446888766490
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_no_texture_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16087518691782755600
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_view_perspective_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12408080239125179236
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_view_perspective_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1082062268335165982
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_view_perspective_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18184323868453549029
-        ]
-      ], 
-      "ignore-failure": true
-    }, 
-    "gradtext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9297095911910169239
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradtext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5771478138095675386
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradtext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16088397879491903202
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "hairlines_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9293293797458777202
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hairlines_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13269473576016756464
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hairlines_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13785031436850319619
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "hairmodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13753109946556116551
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hairmodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9057348143868599843
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hairmodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17279526082933136574
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hittestpath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9550811290357199511
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hittestpath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15448966239818316608
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hittestpath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16781705300910493680
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "image-surface_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17630890424038541282
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "image-surface_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10851904927850256296
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "image-surface_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9401026423085178591
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagealphathreshold_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9262312764539834132
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imagealphathreshold_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7434810293688860099
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imagealphathreshold_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16743719107131210314
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imageblur_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3869730655096851160
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          788899247822925790
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5976634674759312143
-        ]
-      ], 
-      "bugs": [
-        2085
-      ], 
-      "ignore-failure": true, 
-      "reviewed-by-human": false
-    }, 
-    "imageblur_large_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5781271367332766897
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_large_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13746237675706248024
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_large_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12702998954585031011
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblurtiled_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16654054210158593753
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblurtiled_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2843556688273725953
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblurtiled_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10272013979024454230
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersbase_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4532729496698970871
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersbase_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7641510194452485262
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersbase_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14513261314839005722
-        ]
-      ], 
-      "bugs": [
-        2005
-      ], 
-      "ignore-failure": true, 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersclipped_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14771974755728278127
-        ]
-      ]
-    }, 
-    "imagefiltersclipped_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14537515405997069608
-        ]
-      ]
-    }, 
-    "imagefiltersclipped_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8665802903094730049
-        ]
-      ]
-    }, 
-    "imagefilterscropped_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16480020330796061578
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefilterscropped_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4131813877373753759
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefilterscropped_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6114011311493833332
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersgraph_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12620063976225784909
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersgraph_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          204467962017973076
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersgraph_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1103995645853022148
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersscaled_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15769177648683788265
-        ]
-      ]
-    }, 
-    "imagefiltersscaled_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18437708945397499005
-        ]
-      ]
-    }, 
-    "imagefiltersscaled_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17667280750482645242
-        ]
-      ]
-    }, 
-    "imagemagnifier_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6327054889332906721
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagemagnifier_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11878406934177300231
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagemagnifier_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10399323179213606951
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageresizetiled_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11537830680807011411
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imageresizetiled_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2840733308476616973
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imageresizetiled_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2840733308476616973
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "internal_links_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11477547669639384796
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "internal_links_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11751433989801294344
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "internal_links_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13900375946366690268
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "inverse_paths_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12462644636324896185
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "inverse_paths_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6825022448693098908
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "inverse_paths_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6283227002281509479
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lcdtext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6122935913437439554
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lcdtext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1511393143767092759
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lcdtext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1511393143767092759
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lerpmode_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10818286910555371914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lerpmode_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4328896907702672721
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lerpmode_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14139714820651029117
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lighting_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6728484050681732905
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lighting_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3122543961009401649
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lighting_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5598689909109043043
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lightingcolorfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7968186755331229682
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lightingcolorfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1516320293275754779
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lightingcolorfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6114476395450060705
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lineclosepath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2564246142489134519
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lineclosepath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1370520776657521517
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lineclosepath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7446182077244886426
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "linepath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1981696952434326875
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "linepath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15238792371190456534
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "linepath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10096967694534333921
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lumafilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5049467161770100346
-        ]
-      ]
-    }, 
-    "lumafilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8374476823825156605
-        ]
-      ]
-    }, 
-    "lumafilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3056389996783374736
-        ]
-      ]
-    }, 
-    "lumamode_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8495874039699811736
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lumamode_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15450664592066744642
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "matrixconvolution_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3101476576521947165
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "matrixconvolution_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10055081768235896808
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "matrixconvolution_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13589934301785253810
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "matriximagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10858609396135450061
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "matriximagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8182459068173254170
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "matriximagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8662058601690590393
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_0x0_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          899343682044846669
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_0x0_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4811817245879819217
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_0x0_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          389258352199308507
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "megalooper_1x4_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          899343682044846669
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_1x4_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4811817245879819217
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_1x4_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          389258352199308507
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "megalooper_4x1_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          899343682044846669
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_4x1_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4811817245879819217
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_4x1_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          389258352199308507
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "mixed_xfermodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9621832453494372057
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "mixed_xfermodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1944307888764212912
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "mixed_xfermodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1159197049660363044
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "modecolorfilters_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2595933616904054518
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "modecolorfilters_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5532792141023246970
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "modecolorfilters_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14409347541136653391
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "morphology_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13276990043616594793
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "morphology_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12053534281222176521
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "morphology_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15160418634894798633
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "nested_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2682194241459481981
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "nested_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1792040421885608938
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "nested_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2956570062403950585
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "nested_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1642884649618332584
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nested_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2247784507927793592
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nested_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6638289994984814421
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ninepatch-stretch_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18411873313823762166
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "ninepatch-stretch_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14862133879758372505
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "ninepatch-stretch_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18240364857152463172
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "nonclosedpaths_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8797161389659029383
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nonclosedpaths_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9282658625266410335
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nonclosedpaths_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2717683152392989202
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "offsetimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15240835456320409473
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "offsetimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          249289862803617115
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "offsetimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17818108684129139098
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "optimizations_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13811812839638384010
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "optimizations_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13857521313271479795
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "optimizations_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13857521313271479795
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ovals_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4201817511424287157
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ovals_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1184189085315519615
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ovals_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10347668577930193751
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "path-reverse_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5447571501272498127
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "path-reverse_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8312881875844297775
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "path-reverse_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          772433085551372706
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "patheffect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16045594695628613487
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "patheffect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13136038454993854220
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "patheffect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15962075333689603774
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathfill_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9913956212375399295
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathfill_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12306117555345084962
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathfill_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13972162918751012955
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathinterior_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3396766038203432666
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathinterior_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12110360517026697498
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathinterior_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16405106071112654012
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathinvfill_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8654831421971241050
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathinvfill_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11144284047498640984
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathinvfill_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3520993708181297768
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathopsinverse_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17617505767021323437
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathopsinverse_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11577432472710705185
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathopsinverse_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          404088650467664322
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathopsskpclip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6154660184356174115
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathopsskpclip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4313744187563601995
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathopsskpclip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          123433350506930487
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "peekpixels_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2758866006531517960
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "peekpixels_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5344748376042459393
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "peekpixels_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10481810241231481688
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "perlinnoise_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16968168405481699903
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "perlinnoise_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1098763191610264229
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "perlinnoise_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5617237608049886158
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pictureimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15710121230086435602
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1763586683528188858
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1763586683528188858
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureshader_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9198676987657517428
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureshader_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17117388175840647151
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureshader_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7549768996631810693
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "points_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8567194488499472739
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "points_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8567194488499472739
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "points_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3323041250453388207
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "poly2poly_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1729179301788020778
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "poly2poly_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15018091812205538488
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "poly2poly_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17764211397622357735
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "polygons_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7471239721499308199
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "polygons_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          961606689700631635
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "polygons_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1583603789414455339
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "quadclosepath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17243480259296502336
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadclosepath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6891379388563692035
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadclosepath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6297650466511707379
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadpath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6963865127519492895
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadpath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7223243377781866680
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadpath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5595773772993530952
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "radial_gradient2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2509551852078940571
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4012506323387989153
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11959852029544468073
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10067107685325019703
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15369886492036014971
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8690270988024634484
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7959433338453691623
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10522172914016896806
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14982217045743030920
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "resizeimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11574452324482789141
-        ]
-      ]
-    }, 
-    "resizeimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15004076002839832883
-        ]
-      ]
-    }, 
-    "resizeimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5076745909900181906
-        ]
-      ]
-    }, 
-    "roundrects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17752420136993868343
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "roundrects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1161927000752559561
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "roundrects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          835479464135575251
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18340118795193628429
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14795654963615468231
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13783532124190227221
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13792455863265377338
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8162996231165662471
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1500157245784304324
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6810446943823350860
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3764224183150533222
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14635716521372290944
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8853776977311383548
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17915472794674819668
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5677622882171244043
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16102744790083806869
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2639533157784794570
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_draw_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14635716521372290944
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8853776977311383548
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10134143739778253386
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5677622882171244043
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16102744790083806869
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2639533157784794570
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_effect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9741594763308804282
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11654998290125202938
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "samplerstress_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6887529583056247381
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "samplerstress_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15016075013768190397
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "samplerstress_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          979344291475393331
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_bitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7135789859959079868
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_bitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2185595877830848468
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_bitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11540820957422662028
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_gradient_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14913297062861988444
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_gradient_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7517125506221018662
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_gradient_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14758428393785721359
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14647286245000917282
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16574168428196349390
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14378884143882412610
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_npot_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7491706677759704423
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_npot_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13922841069600322051
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_npot_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18413532602239109176
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "selftest1_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12927999507540085554
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest1_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1209453360120438698
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest1_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1149339852105949057
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8863920166200910451
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13451349865803053525
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7903070799454133570
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shaderbounds_linear_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4739835670329472924
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shaderbounds_linear_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17407206349726255504
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shaderbounds_linear_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9231268892600322210
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shadows_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11496795807715360050
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shadows_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11973828271981934898
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shadows_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6393145760590998803
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_conical_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17982294224537325140
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_conical_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10213220249745462631
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_conical_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17110523027129122270
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "shallow_gradient_linear_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2414118852281882343
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_linear_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2600596201303470577
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_linear_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13330672348717914117
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_radial_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7637358666429963225
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_radial_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12757191687259698018
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_radial_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3576469387623502205
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_sweep_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6974552498637279685
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_sweep_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          766715199662180977
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_sweep_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9322393820489779517
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "simpleaaclip_aaclip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7216936724349703423
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_aaclip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8297028920093819054
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_aaclip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16021439723556558918
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_path_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7216936724349703423
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_path_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8505743106500736554
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_path_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1978759492972376322
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_rect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5181638003047557471
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_rect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2247183642119438840
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_rect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16948766582215433974
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleblurroundrect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          335739214192474542
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleblurroundrect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5652577089689509120
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleblurroundrect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15913476983071756158
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "skbug1719_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2332391077132553330
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "skbug1719_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13212045663266308489
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "skbug1719_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17095707402781773995
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "spritebitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13563811160364567248
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "spritebitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          227198932212139294
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "spritebitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5342593300778917277
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "srcmode_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14499438099795304341
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "srcmode_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14771578516798309775
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "srcmode_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12943740194645175665
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stringart_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          517466260915157438
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "stringart_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12919217765216356865
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "stringart_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8864794410650886097
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "stroke-fill_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3203505322339327449
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stroke-fill_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16626870905607243018
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stroke-fill_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15798393829747738691
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "strokerect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15458182862530229195
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "strokerect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2467605443292336055
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "strokerect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16007880695407826360
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "strokerects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10731083935300051992
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokerects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3590050428307921218
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokerects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5747656467049588206
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes3_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1686573849514282054
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes3_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9947658613138732028
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes3_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7751974933403726499
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_poly_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13975044413592406455
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_poly_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9847781398855716283
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_poly_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5265350706794735927
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_round_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8830084223721413158
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "strokes_round_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14762739513429490065
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "strokes_round_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          849657193303901676
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stroketext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7449648884353637669
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stroketext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4914721999172725849
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stroketext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18332417829561221001
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tablecolorfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6155339908971373908
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tablecolorfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5497460981955702016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tablecolorfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8226915152097966889
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "testimagefilters_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10876942606580879984
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "testimagefilters_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6913857649673524662
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "testimagefilters_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12654679736886426328
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "texdata_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8202463522803346863
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "texdata_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8202463522803346863
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "texdata_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2736593828543197285
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "texteffects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13357146488219809893
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "texteffects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7386759365357423329
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "texteffects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7386759365357423329
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "texture_domain_effect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11734977558073048483
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinrects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17949451347125150629
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinrects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12074631820414627784
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinrects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5935862934447854810
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinstrokedrects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17882028260402842392
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinstrokedrects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2596255945580270876
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinstrokedrects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18134316930773092342
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tileimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15884441815359625883
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tileimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6913371489075702069
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tileimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6913371489075702069
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_bitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7135789859959079868
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_bitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2185595877830848468
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_bitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11540820957422662028
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_gradient_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14913297062861988444
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_gradient_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7517125506221018662
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_gradient_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14758428393785721359
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10553952199599604816
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14968443247329529117
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5254473306719673022
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_npot_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5008151281798703171
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_npot_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13298836052288001622
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_npot_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8451918751746608219
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tinybitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12538857845722393084
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tinybitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11468465429225805
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tinybitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5633315905476176630
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "twopointconical_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14356658846198325540
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "twopointconical_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6036270199387229964
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "twopointconical_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7663579407369070653
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typeface_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3225712846346731230
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typeface_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3057908372893981204
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typeface_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3057908372893981204
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5356705204909842699
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13370428013149648258
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13370428013149648258
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_kerning_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          201259875367580358
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "typefacestyles_kerning_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2080761164861757576
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "typefacestyles_kerning_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8882773799933891216
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "vertices_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12016571983635712769
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "vertices_80_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11220339642934269879
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "vertices_80_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5116617595194840746
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "vertices_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          753078211441143405
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "vertices_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1343433454959599907
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "verttext2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2163610981651965452
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14527641142409674625
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3597293503861619263
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4473316427232601425
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10869528886180759869
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7700008644697398877
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodeimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10958353996143090911
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodeimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17000878545702467803
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodeimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12340026112988841012
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6775705236924739798
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2952493606222488372
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14811732441451933971
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes3_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1103771815346361861
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes3_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14561360239620524377
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes3_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12574873031515180645
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6398363063795275200
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          382247129895543895
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11611679597896853327
-        ]
-      ], 
-      "reviewed-by-human": true
-    }
-  }
-}
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-Logan-Nvidia-Arm7-Debug/expected-results.json b/expectations/gm/Test-Android-Logan-Nvidia-Arm7-Debug/expected-results.json
index 32dc829..2d25092 100644
--- a/expectations/gm/Test-Android-Logan-Nvidia-Arm7-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-Logan-Nvidia-Arm7-Debug/expected-results.json
@@ -112,28 +112,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -220,10 +220,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13374984169934185688
+          925745442849939541
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arcofzorro_565.png": {
       "allowed-digests": [
@@ -292,28 +292,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16256908561026135869
+          646557001524252318
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16256908561026135869
+          10516625019498630005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16256908561026135869
+          9323956199897655272
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bezier_conic_effects_gpu.png": {
       "allowed-digests": [
@@ -396,51 +441,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
@@ -463,28 +463,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -625,7 +625,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8832072556959385525
+          6980407574393099333
         ]
       ], 
       "reviewed-by-human": true
@@ -634,7 +634,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410204863204197194
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -643,7 +643,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4226199328543812562
+          4387664888229533345
         ]
       ], 
       "reviewed-by-human": true
@@ -652,7 +652,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8519025059264881753
+          9888209494992457033
         ]
       ], 
       "reviewed-by-human": true
@@ -661,7 +661,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4226199328543812562
+          13682524339971744241
         ]
       ], 
       "reviewed-by-human": true
@@ -967,28 +967,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
@@ -1066,10 +1075,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurquickreject_nvprmsaa4.png": {
       "allowed-digests": [
@@ -2700,6 +2709,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrects_565.png": {
       "allowed-digests": [
         [
@@ -2722,25 +2776,70 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
         ]
       ], 
       "reviewed-by-human": false
@@ -2830,10 +2929,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7396185915576941225
+          17576251751918836741
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "canvas-layer-state_565.png": {
       "allowed-digests": [
@@ -2983,10 +3082,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13359516246713785301
+          2705167135790734954
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "circles_565.png": {
       "allowed-digests": [
@@ -3892,181 +3991,181 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16060629266653836541
+          1787647314443274475
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7935307680550293784
+          6544536706877310514
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5376434742197928758
+          2429920120052843062
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9535817198338710631
+          14933444110384788676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          686626615788563308
+          5836493341538608113
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4185170493872982769
+          13233801567212171947
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12069726724129734770
+          15485331406466346020
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3598125911353643753
+          12237070751559223219
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14550900247676568928
+          14135331895619870123
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5263937991765085157
+          17975172422298551459
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12521617399540287245
+          6492358805688952506
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3190552677201665775
+          10152516748782571739
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9989505875172612569
+          8599486095534837754
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4870317370734649728
+          8180502121217066191
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5783287451488289297
+          16993829969091028380
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11610619298771405034
+          4464186135826350269
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14439091353698050152
+          14141267173026023305
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11257571588060326962
+          13498010893710025632
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16746284846042281359
+          2415668012055957094
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13318887921907322647
+          9539755934700963810
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "composeshader_565.png": {
       "allowed-digests": [
@@ -4162,46 +4261,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17707691143950027168
+          4792118895672570848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788619303593885819
+          11285887424651164487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4926472493732110498
+          10334501517119110652
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18305864860571767110
+          6304025159727097447
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13057601874484076666
+          8117309247099167489
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -4324,91 +4423,91 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16297020246115085704
+          15805712012337691465
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13937678633951136440
+          7882161322447216882
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3726266269852802824
+          18122740434942105247
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1798887035736952574
+          6829248170885657128
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2342768345948172537
+          2453925789213425067
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2151942491107284230
+          2526905513820650564
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10471902765578272701
+          713799816796517938
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2609926456888543295
+          8431167782322283532
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1237278902324987650
+          15679797404545787927
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17974846249120039155
+          10173413397873712322
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dashcubics_565.png": {
       "allowed-digests": [
@@ -4567,7 +4666,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4903737309685329914
+          1395267708058780826
         ]
       ], 
       "reviewed-by-human": true
@@ -4639,46 +4738,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13409592322484279194
+          14932083482843942713
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2576698895183287698
+          7311723676588845146
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6308928332848582976
+          2361687506949128762
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5799732183293696351
+          1884546014600286233
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17586380316024760889
+          7740476675036496581
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_565.png": {
       "allowed-digests": [
@@ -4729,97 +4828,97 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3767760557629765982
+          4057230872151110302
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12070678672447530766
+          9482070623821433904
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10805526250301825223
+          1170916231930532316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10805526250301825223
+          1170916231930532316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10805526250301825223
+          1170916231930532316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          16760516999045902880
         ]
       ], 
       "reviewed-by-human": true
@@ -4828,7 +4927,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          7954380755899068917
         ]
       ], 
       "reviewed-by-human": true
@@ -4999,7 +5098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          8512647456105910709
         ]
       ], 
       "reviewed-by-human": true
@@ -5008,7 +5107,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          16406522223209644047
         ]
       ], 
       "reviewed-by-human": true
@@ -5179,7 +5278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          15355618085509456693
         ]
       ], 
       "reviewed-by-human": true
@@ -5188,7 +5287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          11069475268607558634
         ]
       ], 
       "reviewed-by-human": true
@@ -5359,10 +5458,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5377,118 +5476,118 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13627205234939690742
+          14145109580428845757
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17686572383265746470
+          17938573218167752738
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11190272575141191020
+          14959282528007631804
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5455618422902283397
+          15797039913993285826
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14095817193753318732
+          17497164562330387900
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11810718459521441197
+          9990087363523944057
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5139087224554682195
+          7554456787542902160
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6687232050765608960
+          5137243343635867552
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          716171842978913864
+          273445276579232833
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17171710908581496295
+          13357226331142394630
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12121624202840786854
+          8871417605619188715
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6315439063975527169
+          4576941471884713054
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8942647279416935944
+          4012628516826662450
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drrect_565.png": {
       "allowed-digests": [
@@ -5539,46 +5638,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13764232316250089830
+          2991124572032378675
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13347568447034524087
+          588269449619860245
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679404933823525244
+          6632000588223833713
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4726184163004720120
+          10645864801661650192
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16422436842030419749
+          11631650877749129252
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "etc1bitmap_565.png": {
       "allowed-digests": [
@@ -5760,6 +5859,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -5989,7 +6133,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -5998,7 +6142,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -6034,7 +6178,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -6043,7 +6187,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -6079,7 +6223,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -6088,7 +6232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -6124,7 +6268,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -6133,7 +6277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -6169,7 +6313,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -6178,7 +6322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -6214,7 +6358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -6223,7 +6367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -6259,7 +6403,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -6268,7 +6412,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -6304,7 +6448,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -6313,7 +6457,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -6349,7 +6493,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -6358,7 +6502,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -6439,7 +6583,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -6448,7 +6592,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -6529,7 +6673,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -6538,7 +6682,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -6574,7 +6718,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -6583,7 +6727,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
@@ -6615,6 +6759,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14901126990301924005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -6637,61 +6826,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15147463239787661010
+          12917051629701364633
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          16422406671162802527
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          11690691754075111299
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1321940012742590695
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1321940012742590695
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          9583722823847795919
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          15819102890789133004
         ]
       ], 
       "reviewed-by-human": false
@@ -6700,7 +6889,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
       "reviewed-by-human": false
@@ -6709,7 +6898,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
       "reviewed-by-human": false
@@ -6718,7 +6907,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
       "reviewed-by-human": false
@@ -6727,7 +6916,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          10694755477090262742
         ]
       ], 
       "reviewed-by-human": false
@@ -6772,7 +6961,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12766008228994452070
+          9827686428448367785
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11964679111422592867
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5162571039647650276
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10375921896063669652
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15719875773249376092
         ]
       ], 
       "reviewed-by-human": false
@@ -6781,46 +7015,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2141961881550032904
+          17581551777079826402
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4994151175360770217
+          5693920054563327483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1037675752615738994
+          7410404176182207331
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          171374670034459728
+          12079550107147764281
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1037675752615738994
+          5256632636384986167
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_565.png": {
       "allowed-digests": [
@@ -6862,10 +7096,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13104141215218891719
+          2266469853588125333
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "giantbitmap_clamp_bilerp_rotate_565.png": {
       "allowed-digests": [
@@ -7407,6 +7641,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12043275845924027375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9553556786248148858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5869882930804807574
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9680535192998402106
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2181777231001889228
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8437696829904997437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9680535192998402106
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2181777231001889228
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8437696829904997437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13690252386192317596
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15062317314457631068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16712947435795137252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3402744090301168937
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1172449135522100758
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6654099907038825072
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8682526722128026537
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5328812593105334287
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9680535192998402106
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2181777231001889228
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8437696829904997437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6177783559433684532
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13718259144500110006
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          850684155668853192
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5642177073237761871
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9676704235267262129
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13665525553817379099
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8529852847226464317
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15774413156690645534
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7432,7 +8026,7 @@
           2515733614721864626
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -7522,7 +8116,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa16.png": {
       "allowed-digests": [
@@ -7567,7 +8161,7 @@
           16605120526645549774
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa16.png": {
       "allowed-digests": [
@@ -7612,7 +8206,7 @@
           169027135498041421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa16.png": {
       "allowed-digests": [
@@ -7702,7 +8296,7 @@
           12227348360284420259
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_local_perspective_565.png": {
       "allowed-digests": [
@@ -7729,7 +8323,7 @@
           13235754433685839215
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_local_perspective_msaa16.png": {
       "allowed-digests": [
@@ -7828,7 +8422,7 @@
           8515310025484729496
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_no_texture_msaa16.png": {
       "allowed-digests": [
@@ -7861,10 +8455,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_view_perspective_8888.png": {
       "allowed-digests": [
@@ -7888,10 +8482,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_view_perspective_nvprmsaa4.png": {
       "allowed-digests": [
@@ -7906,10 +8500,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13538992606665750486
+          8988444324654919932
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
@@ -7918,7 +8512,7 @@
           8157217091633419434
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -7927,7 +8521,7 @@
           16721733946941939566
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
@@ -7936,16 +8530,16 @@
           8366007750043973832
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16721733946941939566
+          16847891220631188052
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -8014,28 +8608,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -8122,10 +8716,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          228299435050770401
+          9714515488019089032
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagealphathreshold_565.png": {
       "allowed-digests": [
@@ -8172,95 +8766,140 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16489109101972185585
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6650426797361351839
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9776762281301239489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9776762281301239489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6593485300815939687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3794665630847901594
+          16107386499979435430
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7748801528548244433
+          9389518362994061039
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6440623956172024364
+          10981059208022654171
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259128835424197006
+          1922338586017046100
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13149265802466457140
+          3693078186234250164
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7035854796006504278
+          14743789370195470948
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15891714078517096849
+          18400192829798117824
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15274594502388916855
+          13097220800213758803
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17255294541834537394
+          1652938096297334479
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9515358740070484422
+          1199132258760929254
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_565.png": {
       "allowed-digests": [
@@ -8302,55 +8941,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13414680421788843979
+          8488316645392964651
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6719033984262147569
+          6619992761400261824
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9527595429529547733
+          13496371326149688854
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          934074116857685250
+          9946670624537414154
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13606097315164647251
+          12105436533254137439
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10725217729953227399
+          14231134936887828848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_565.png": {
       "allowed-digests": [
@@ -8401,46 +9040,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219558445660995645
+          5790851814695952086
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          861754899676926834
+          9505242634744136184
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17263014151402343206
+          13672016410066459606
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15599021112138015625
+          1385093157503074217
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9315410500595669184
+          721446359122972453
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_565.png": {
       "allowed-digests": [
@@ -8491,91 +9130,91 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          9975630938390290961
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          5942637760001128743
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8101800382797015796
+          11423939606971574450
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408291191960139489
+          12326964440209572344
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3518014965514239134
+          15624400477400066280
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5274487773236388163
+          4458594706234736506
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10772725192724193725
+          7881653068493848399
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          188351412526107333
+          16810514191517798581
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3620285955459918379
+          14570586585222357891
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8845965706215357892
+          9564936616808561566
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_565.png": {
       "allowed-digests": [
@@ -8617,10 +9256,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5803572190214013609
+          6842651198871289715
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_565.png": {
       "allowed-digests": [
@@ -8662,10 +9301,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17245097583413490008
+          16081379139259811194
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "inverse_paths_565.png": {
       "allowed-digests": [
@@ -8752,10 +9391,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9235059342087793513
+          11959464110029038483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_565.png": {
       "allowed-digests": [
@@ -8779,28 +9418,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
@@ -8896,91 +9535,91 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15294128480303197948
+          15171677204658263732
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13213375518846743511
+          4131799565799962704
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3310003219173606036
+          1045969928879715118
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15961543103452040916
+          12120630131388185697
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8359751217551455987
+          4867273038158340835
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5561914357564245394
+          14593570443940328754
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768949088352973106
+          17687576741285937089
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5046743995888862942
+          13002510595192638282
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11309338358157991178
+          8376525710210280732
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9314300104674967071
+          2165166272129857429
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_565.png": {
       "allowed-digests": [
@@ -9004,73 +9643,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14723609246296107549
+          1534686038045373611
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7344147531832172146
+          6716626629650396947
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16699441214433531992
+          10207170719548229442
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14753870890166488787
+          13546074453897362674
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12332409505555151686
+          2645433785253737964
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17207392593029037762
+          15861769207857876297
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17207392593029037762
+          15861769207857876297
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17207392593029037762
+          15861769207857876297
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -9139,28 +9778,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_565.png": {
       "allowed-digests": [
@@ -9184,28 +9823,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_565.png": {
       "allowed-digests": [
@@ -9229,28 +9868,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "mixed_xfermodes_565.png": {
       "allowed-digests": [
@@ -9319,28 +9958,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
@@ -9387,6 +10026,456 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9571,46 +10660,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15293668784585893125
+          4656886197492028969
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17470748697630737319
+          10009949554846362902
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6258969688980197856
+          13683962615885282836
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4719209936458065266
+          12790249440258822462
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6258969688980197856
+          13683962615885282836
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_8888.png": {
       "allowed-digests": [
@@ -9625,28 +10714,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -9693,6 +10782,96 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -10057,7 +11236,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -10066,7 +11245,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -10075,16 +11254,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8078582473004825903
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
@@ -10093,7 +11317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
@@ -10138,7 +11362,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7375436820633666472
+          9376005759542604670
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
         ]
       ], 
       "reviewed-by-human": false
@@ -10188,6 +11457,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -10237,46 +11551,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18000254716935645999
+          13710370929503896242
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16383033135480419663
+          14868659503042841956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14306801897016050411
+          8724279776371741209
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9442389447799496085
+          16386079146972189141
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1758139275968336775
+          10501642383939903115
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "polygons_565.png": {
       "allowed-digests": [
@@ -10327,91 +11641,91 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8722535421343092722
+          11616620239881546194
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13797585911734062488
+          13695847048236137972
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10290311668975325061
+          16921633698439533289
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3383949128342572810
+          14551164182151379984
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9688837733706048395
+          6278496007380788720
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1429162301232528158
+          10424880346112239562
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7149831205496297560
+          24796932854446382
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          811832897169446842
+          14387256875722535895
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11956221874461591582
+          3084001820350865112
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13657366124212829861
+          10580819542753628704
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient2_565.png": {
       "allowed-digests": [
@@ -10480,28 +11794,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -10528,7 +11842,7 @@
           11339980900210544915
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -11020,10 +12334,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5106652718712307834
+          13054117570333345927
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -11065,7 +12379,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5791355409085474167
+          6603262244480838578
         ]
       ], 
       "reviewed-by-human": true
@@ -11110,10 +12424,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5013168967456038846
+          16767964269884530933
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemodes_565.png": {
       "allowed-digests": [
@@ -11137,7 +12451,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16047831436063908462
+          3329654708179781467
         ]
       ], 
       "reviewed-by-human": true
@@ -11146,7 +12460,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12633846902641763898
+          3634916922351141598
         ]
       ], 
       "reviewed-by-human": true
@@ -11173,7 +12487,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10278697750582382331
+          4685625529159208416
         ]
       ], 
       "reviewed-by-human": true
@@ -11182,7 +12496,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16266387511399788956
+          3910412077329177087
         ]
       ], 
       "reviewed-by-human": true
@@ -11191,7 +12505,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10278697750582382331
+          7185557222786853214
         ]
       ], 
       "reviewed-by-human": true
@@ -11200,7 +12514,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16047831436063908462
+          15598108598963880382
         ]
       ], 
       "reviewed-by-human": true
@@ -11605,10 +12919,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14249365533430423372
+          5109245597691922700
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_565.png": {
       "allowed-digests": [
@@ -11650,10 +12964,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9767546197274641539
+          3555205160009401239
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_565.png": {
       "allowed-digests": [
@@ -11695,7 +13009,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11708184300213244484
+          1975120293097303892
         ]
       ], 
       "reviewed-by-human": true
@@ -11839,46 +13153,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11744373400809739356
+          11699531654048406518
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8270526029969251327
+          4523091657809672686
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12686420221117081803
+          10825240656177983622
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12686420221117081803
+          5322506552282967802
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12681809384054758075
+          11489252242825644312
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -11965,10 +13279,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5229914946265067393
+          1584098566405040124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "strokerect_565.png": {
       "allowed-digests": [
@@ -12199,7 +13513,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9529107797168461968
+          5033516764144244033
         ]
       ], 
       "reviewed-by-human": true
@@ -12208,7 +13522,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15098401526248766364
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -12217,7 +13531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          152965079748686847
+          6404558339120488836
         ]
       ], 
       "reviewed-by-human": true
@@ -12226,7 +13540,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1055459124709498581
+          2277109490511489216
         ]
       ], 
       "reviewed-by-human": true
@@ -12235,7 +13549,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12576068860582224002
+          14164859472780460449
         ]
       ], 
       "reviewed-by-human": true
@@ -12357,6 +13671,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5996036510207866577
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6571507317861452784
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9796000551046772836
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9796000551046772836
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4979181777203379619
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -12406,28 +13765,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9407358693309761110
+          5829921135942844635
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -12454,7 +13813,7 @@
           17501446579955337831
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -12499,7 +13858,7 @@
           14626919895309756138
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -12523,46 +13882,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17022932193658353157
+          15732727687033594466
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -12604,7 +13963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5791355409085474167
+          6603262244480838578
         ]
       ], 
       "reviewed-by-human": true
@@ -12649,10 +14008,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5013168967456038846
+          16767964269884530933
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemodes_565.png": {
       "allowed-digests": [
@@ -12676,7 +14035,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11584832146089969107
+          2483911436983576286
         ]
       ], 
       "reviewed-by-human": true
@@ -12685,7 +14044,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14295636111001791530
+          8320002136174109365
         ]
       ], 
       "reviewed-by-human": true
@@ -12712,7 +14071,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14216970501880738242
+          16496795039069152068
         ]
       ], 
       "reviewed-by-human": true
@@ -12721,7 +14080,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14109805982087708293
+          101411760227870599
         ]
       ], 
       "reviewed-by-human": true
@@ -12730,7 +14089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14216970501880738242
+          16384482106126909208
         ]
       ], 
       "reviewed-by-human": true
@@ -12739,7 +14098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11584832146089969107
+          12708776489646732763
         ]
       ], 
       "reviewed-by-human": true
@@ -12814,7 +14173,7 @@
           74109172769746346
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "twopointconical_msaa16.png": {
       "allowed-digests": [
@@ -12829,10 +14188,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10060886431688452398
+          1943698464051928811
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_565.png": {
       "allowed-digests": [
@@ -12874,10 +14233,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14725542749908228
+          16400297164492096982
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_565.png": {
       "allowed-digests": [
@@ -12946,10 +14305,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          539829354440306365
+          18056543758253973423
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_msaa16.png": {
       "allowed-digests": [
@@ -12964,10 +14323,190 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6475798309604476317
+          17294510074434159565
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1952127887831515847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9769614951001146061
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12041989397910562336
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6832825185173658903
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1952127887831515847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9769614951001146061
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12041989397910562336
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6832825185173658903
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1752599991641140864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5112257246836121794
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9488969065851737597
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          449267873124950862
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1752599991641140864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5112257246836121794
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9488969065851737597
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          449267873124950862
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "vertices_565.png": {
       "allowed-digests": [
@@ -13099,10 +14638,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12238883472526934397
+          1831358800461900123
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_565.png": {
       "allowed-digests": [
@@ -13144,55 +14683,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9603191152115149072
+          114252305762558512
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3394570787947912684
+          3112652115716203250
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4231863532718175149
+          12938112915997113104
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6573194240143689227
+          1141902512976477957
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6573194240143689227
+          1141902512976477957
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6573194240143689227
+          1141902512976477957
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
@@ -13216,28 +14755,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18070508412495593985
+          15147018840180384131
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16415047223853670750
+          721300356033145236
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18070508412495593985
+          3813033603856492134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_565.png": {
       "allowed-digests": [
@@ -13279,10 +14818,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1154363106472965006
+          12011229033319908796
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_565.png": {
       "allowed-digests": [
@@ -13306,25 +14845,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3680789048917201641
+          13951513751310057438
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6725067416297177922
+          16184415525257363318
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3680789048917201641
+          14510921787218221764
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
         ]
       ], 
       "reviewed-by-human": false
diff --git a/expectations/gm/Test-Android-Logan-Nvidia-Arm7-Release/expected-results.json b/expectations/gm/Test-Android-Logan-Nvidia-Arm7-Release/expected-results.json
index 32dc829..2d25092 100644
--- a/expectations/gm/Test-Android-Logan-Nvidia-Arm7-Release/expected-results.json
+++ b/expectations/gm/Test-Android-Logan-Nvidia-Arm7-Release/expected-results.json
@@ -112,28 +112,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -220,10 +220,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13374984169934185688
+          925745442849939541
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arcofzorro_565.png": {
       "allowed-digests": [
@@ -292,28 +292,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16256908561026135869
+          646557001524252318
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16256908561026135869
+          10516625019498630005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16256908561026135869
+          9323956199897655272
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bezier_conic_effects_gpu.png": {
       "allowed-digests": [
@@ -396,51 +441,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
@@ -463,28 +463,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -625,7 +625,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8832072556959385525
+          6980407574393099333
         ]
       ], 
       "reviewed-by-human": true
@@ -634,7 +634,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410204863204197194
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -643,7 +643,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4226199328543812562
+          4387664888229533345
         ]
       ], 
       "reviewed-by-human": true
@@ -652,7 +652,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8519025059264881753
+          9888209494992457033
         ]
       ], 
       "reviewed-by-human": true
@@ -661,7 +661,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4226199328543812562
+          13682524339971744241
         ]
       ], 
       "reviewed-by-human": true
@@ -967,28 +967,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
@@ -1066,10 +1075,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurquickreject_nvprmsaa4.png": {
       "allowed-digests": [
@@ -2700,6 +2709,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrects_565.png": {
       "allowed-digests": [
         [
@@ -2722,25 +2776,70 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
         ]
       ], 
       "reviewed-by-human": false
@@ -2830,10 +2929,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7396185915576941225
+          17576251751918836741
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "canvas-layer-state_565.png": {
       "allowed-digests": [
@@ -2983,10 +3082,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13359516246713785301
+          2705167135790734954
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "circles_565.png": {
       "allowed-digests": [
@@ -3892,181 +3991,181 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16060629266653836541
+          1787647314443274475
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7935307680550293784
+          6544536706877310514
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5376434742197928758
+          2429920120052843062
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9535817198338710631
+          14933444110384788676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          686626615788563308
+          5836493341538608113
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4185170493872982769
+          13233801567212171947
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12069726724129734770
+          15485331406466346020
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3598125911353643753
+          12237070751559223219
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14550900247676568928
+          14135331895619870123
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5263937991765085157
+          17975172422298551459
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12521617399540287245
+          6492358805688952506
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3190552677201665775
+          10152516748782571739
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9989505875172612569
+          8599486095534837754
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4870317370734649728
+          8180502121217066191
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5783287451488289297
+          16993829969091028380
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11610619298771405034
+          4464186135826350269
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14439091353698050152
+          14141267173026023305
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11257571588060326962
+          13498010893710025632
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16746284846042281359
+          2415668012055957094
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13318887921907322647
+          9539755934700963810
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "composeshader_565.png": {
       "allowed-digests": [
@@ -4162,46 +4261,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17707691143950027168
+          4792118895672570848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788619303593885819
+          11285887424651164487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4926472493732110498
+          10334501517119110652
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18305864860571767110
+          6304025159727097447
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13057601874484076666
+          8117309247099167489
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -4324,91 +4423,91 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16297020246115085704
+          15805712012337691465
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13937678633951136440
+          7882161322447216882
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3726266269852802824
+          18122740434942105247
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1798887035736952574
+          6829248170885657128
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2342768345948172537
+          2453925789213425067
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2151942491107284230
+          2526905513820650564
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10471902765578272701
+          713799816796517938
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2609926456888543295
+          8431167782322283532
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1237278902324987650
+          15679797404545787927
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17974846249120039155
+          10173413397873712322
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dashcubics_565.png": {
       "allowed-digests": [
@@ -4567,7 +4666,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4903737309685329914
+          1395267708058780826
         ]
       ], 
       "reviewed-by-human": true
@@ -4639,46 +4738,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13409592322484279194
+          14932083482843942713
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2576698895183287698
+          7311723676588845146
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6308928332848582976
+          2361687506949128762
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5799732183293696351
+          1884546014600286233
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17586380316024760889
+          7740476675036496581
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_565.png": {
       "allowed-digests": [
@@ -4729,97 +4828,97 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3767760557629765982
+          4057230872151110302
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12070678672447530766
+          9482070623821433904
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10805526250301825223
+          1170916231930532316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10805526250301825223
+          1170916231930532316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10805526250301825223
+          1170916231930532316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          16760516999045902880
         ]
       ], 
       "reviewed-by-human": true
@@ -4828,7 +4927,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          7954380755899068917
         ]
       ], 
       "reviewed-by-human": true
@@ -4999,7 +5098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          8512647456105910709
         ]
       ], 
       "reviewed-by-human": true
@@ -5008,7 +5107,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          16406522223209644047
         ]
       ], 
       "reviewed-by-human": true
@@ -5179,7 +5278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          15355618085509456693
         ]
       ], 
       "reviewed-by-human": true
@@ -5188,7 +5287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          11069475268607558634
         ]
       ], 
       "reviewed-by-human": true
@@ -5359,10 +5458,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5377,118 +5476,118 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13627205234939690742
+          14145109580428845757
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17686572383265746470
+          17938573218167752738
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11190272575141191020
+          14959282528007631804
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5455618422902283397
+          15797039913993285826
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14095817193753318732
+          17497164562330387900
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11810718459521441197
+          9990087363523944057
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5139087224554682195
+          7554456787542902160
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6687232050765608960
+          5137243343635867552
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          716171842978913864
+          273445276579232833
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17171710908581496295
+          13357226331142394630
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12121624202840786854
+          8871417605619188715
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6315439063975527169
+          4576941471884713054
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8942647279416935944
+          4012628516826662450
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drrect_565.png": {
       "allowed-digests": [
@@ -5539,46 +5638,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13764232316250089830
+          2991124572032378675
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13347568447034524087
+          588269449619860245
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679404933823525244
+          6632000588223833713
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4726184163004720120
+          10645864801661650192
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16422436842030419749
+          11631650877749129252
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "etc1bitmap_565.png": {
       "allowed-digests": [
@@ -5760,6 +5859,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -5989,7 +6133,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -5998,7 +6142,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -6034,7 +6178,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -6043,7 +6187,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -6079,7 +6223,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -6088,7 +6232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -6124,7 +6268,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -6133,7 +6277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -6169,7 +6313,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -6178,7 +6322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -6214,7 +6358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -6223,7 +6367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -6259,7 +6403,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -6268,7 +6412,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -6304,7 +6448,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -6313,7 +6457,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -6349,7 +6493,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -6358,7 +6502,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -6439,7 +6583,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -6448,7 +6592,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -6529,7 +6673,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -6538,7 +6682,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -6574,7 +6718,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -6583,7 +6727,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
@@ -6615,6 +6759,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14901126990301924005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -6637,61 +6826,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15147463239787661010
+          12917051629701364633
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          16422406671162802527
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          11690691754075111299
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1321940012742590695
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1321940012742590695
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          9583722823847795919
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          15819102890789133004
         ]
       ], 
       "reviewed-by-human": false
@@ -6700,7 +6889,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
       "reviewed-by-human": false
@@ -6709,7 +6898,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
       "reviewed-by-human": false
@@ -6718,7 +6907,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
       "reviewed-by-human": false
@@ -6727,7 +6916,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          10694755477090262742
         ]
       ], 
       "reviewed-by-human": false
@@ -6772,7 +6961,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12766008228994452070
+          9827686428448367785
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11964679111422592867
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5162571039647650276
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10375921896063669652
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15719875773249376092
         ]
       ], 
       "reviewed-by-human": false
@@ -6781,46 +7015,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2141961881550032904
+          17581551777079826402
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4994151175360770217
+          5693920054563327483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1037675752615738994
+          7410404176182207331
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          171374670034459728
+          12079550107147764281
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1037675752615738994
+          5256632636384986167
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_565.png": {
       "allowed-digests": [
@@ -6862,10 +7096,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13104141215218891719
+          2266469853588125333
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "giantbitmap_clamp_bilerp_rotate_565.png": {
       "allowed-digests": [
@@ -7407,6 +7641,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12043275845924027375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9553556786248148858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5869882930804807574
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9680535192998402106
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2181777231001889228
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8437696829904997437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9680535192998402106
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2181777231001889228
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8437696829904997437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13690252386192317596
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15062317314457631068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16712947435795137252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3402744090301168937
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1172449135522100758
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6654099907038825072
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8682526722128026537
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5328812593105334287
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9680535192998402106
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2181777231001889228
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8437696829904997437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6177783559433684532
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13718259144500110006
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          850684155668853192
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5642177073237761871
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9676704235267262129
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13665525553817379099
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8529852847226464317
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15774413156690645534
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7432,7 +8026,7 @@
           2515733614721864626
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -7522,7 +8116,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa16.png": {
       "allowed-digests": [
@@ -7567,7 +8161,7 @@
           16605120526645549774
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa16.png": {
       "allowed-digests": [
@@ -7612,7 +8206,7 @@
           169027135498041421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa16.png": {
       "allowed-digests": [
@@ -7702,7 +8296,7 @@
           12227348360284420259
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_local_perspective_565.png": {
       "allowed-digests": [
@@ -7729,7 +8323,7 @@
           13235754433685839215
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_local_perspective_msaa16.png": {
       "allowed-digests": [
@@ -7828,7 +8422,7 @@
           8515310025484729496
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_no_texture_msaa16.png": {
       "allowed-digests": [
@@ -7861,10 +8455,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_view_perspective_8888.png": {
       "allowed-digests": [
@@ -7888,10 +8482,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_view_perspective_nvprmsaa4.png": {
       "allowed-digests": [
@@ -7906,10 +8500,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13538992606665750486
+          8988444324654919932
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
@@ -7918,7 +8512,7 @@
           8157217091633419434
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -7927,7 +8521,7 @@
           16721733946941939566
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
@@ -7936,16 +8530,16 @@
           8366007750043973832
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16721733946941939566
+          16847891220631188052
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -8014,28 +8608,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -8122,10 +8716,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          228299435050770401
+          9714515488019089032
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagealphathreshold_565.png": {
       "allowed-digests": [
@@ -8172,95 +8766,140 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16489109101972185585
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6650426797361351839
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9776762281301239489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9776762281301239489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6593485300815939687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3794665630847901594
+          16107386499979435430
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7748801528548244433
+          9389518362994061039
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6440623956172024364
+          10981059208022654171
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259128835424197006
+          1922338586017046100
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13149265802466457140
+          3693078186234250164
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7035854796006504278
+          14743789370195470948
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15891714078517096849
+          18400192829798117824
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15274594502388916855
+          13097220800213758803
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17255294541834537394
+          1652938096297334479
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9515358740070484422
+          1199132258760929254
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_565.png": {
       "allowed-digests": [
@@ -8302,55 +8941,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13414680421788843979
+          8488316645392964651
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6719033984262147569
+          6619992761400261824
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9527595429529547733
+          13496371326149688854
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          934074116857685250
+          9946670624537414154
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13606097315164647251
+          12105436533254137439
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10725217729953227399
+          14231134936887828848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_565.png": {
       "allowed-digests": [
@@ -8401,46 +9040,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219558445660995645
+          5790851814695952086
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          861754899676926834
+          9505242634744136184
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17263014151402343206
+          13672016410066459606
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15599021112138015625
+          1385093157503074217
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9315410500595669184
+          721446359122972453
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_565.png": {
       "allowed-digests": [
@@ -8491,91 +9130,91 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          9975630938390290961
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          5942637760001128743
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8101800382797015796
+          11423939606971574450
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408291191960139489
+          12326964440209572344
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3518014965514239134
+          15624400477400066280
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5274487773236388163
+          4458594706234736506
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10772725192724193725
+          7881653068493848399
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          188351412526107333
+          16810514191517798581
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3620285955459918379
+          14570586585222357891
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8845965706215357892
+          9564936616808561566
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_565.png": {
       "allowed-digests": [
@@ -8617,10 +9256,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5803572190214013609
+          6842651198871289715
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_565.png": {
       "allowed-digests": [
@@ -8662,10 +9301,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17245097583413490008
+          16081379139259811194
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "inverse_paths_565.png": {
       "allowed-digests": [
@@ -8752,10 +9391,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9235059342087793513
+          11959464110029038483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_565.png": {
       "allowed-digests": [
@@ -8779,28 +9418,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
@@ -8896,91 +9535,91 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15294128480303197948
+          15171677204658263732
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13213375518846743511
+          4131799565799962704
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3310003219173606036
+          1045969928879715118
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15961543103452040916
+          12120630131388185697
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8359751217551455987
+          4867273038158340835
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5561914357564245394
+          14593570443940328754
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768949088352973106
+          17687576741285937089
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5046743995888862942
+          13002510595192638282
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11309338358157991178
+          8376525710210280732
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9314300104674967071
+          2165166272129857429
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_565.png": {
       "allowed-digests": [
@@ -9004,73 +9643,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14723609246296107549
+          1534686038045373611
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7344147531832172146
+          6716626629650396947
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16699441214433531992
+          10207170719548229442
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14753870890166488787
+          13546074453897362674
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12332409505555151686
+          2645433785253737964
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17207392593029037762
+          15861769207857876297
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17207392593029037762
+          15861769207857876297
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17207392593029037762
+          15861769207857876297
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -9139,28 +9778,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_565.png": {
       "allowed-digests": [
@@ -9184,28 +9823,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_565.png": {
       "allowed-digests": [
@@ -9229,28 +9868,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "mixed_xfermodes_565.png": {
       "allowed-digests": [
@@ -9319,28 +9958,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
@@ -9387,6 +10026,456 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9571,46 +10660,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15293668784585893125
+          4656886197492028969
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17470748697630737319
+          10009949554846362902
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6258969688980197856
+          13683962615885282836
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4719209936458065266
+          12790249440258822462
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6258969688980197856
+          13683962615885282836
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_8888.png": {
       "allowed-digests": [
@@ -9625,28 +10714,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -9693,6 +10782,96 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -10057,7 +11236,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -10066,7 +11245,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -10075,16 +11254,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8078582473004825903
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
@@ -10093,7 +11317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
@@ -10138,7 +11362,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7375436820633666472
+          9376005759542604670
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
         ]
       ], 
       "reviewed-by-human": false
@@ -10188,6 +11457,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -10237,46 +11551,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18000254716935645999
+          13710370929503896242
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16383033135480419663
+          14868659503042841956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14306801897016050411
+          8724279776371741209
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9442389447799496085
+          16386079146972189141
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1758139275968336775
+          10501642383939903115
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "polygons_565.png": {
       "allowed-digests": [
@@ -10327,91 +11641,91 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8722535421343092722
+          11616620239881546194
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13797585911734062488
+          13695847048236137972
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10290311668975325061
+          16921633698439533289
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3383949128342572810
+          14551164182151379984
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9688837733706048395
+          6278496007380788720
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1429162301232528158
+          10424880346112239562
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7149831205496297560
+          24796932854446382
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          811832897169446842
+          14387256875722535895
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11956221874461591582
+          3084001820350865112
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13657366124212829861
+          10580819542753628704
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient2_565.png": {
       "allowed-digests": [
@@ -10480,28 +11794,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -10528,7 +11842,7 @@
           11339980900210544915
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -11020,10 +12334,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5106652718712307834
+          13054117570333345927
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -11065,7 +12379,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5791355409085474167
+          6603262244480838578
         ]
       ], 
       "reviewed-by-human": true
@@ -11110,10 +12424,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5013168967456038846
+          16767964269884530933
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemodes_565.png": {
       "allowed-digests": [
@@ -11137,7 +12451,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16047831436063908462
+          3329654708179781467
         ]
       ], 
       "reviewed-by-human": true
@@ -11146,7 +12460,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12633846902641763898
+          3634916922351141598
         ]
       ], 
       "reviewed-by-human": true
@@ -11173,7 +12487,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10278697750582382331
+          4685625529159208416
         ]
       ], 
       "reviewed-by-human": true
@@ -11182,7 +12496,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16266387511399788956
+          3910412077329177087
         ]
       ], 
       "reviewed-by-human": true
@@ -11191,7 +12505,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10278697750582382331
+          7185557222786853214
         ]
       ], 
       "reviewed-by-human": true
@@ -11200,7 +12514,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16047831436063908462
+          15598108598963880382
         ]
       ], 
       "reviewed-by-human": true
@@ -11605,10 +12919,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14249365533430423372
+          5109245597691922700
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_565.png": {
       "allowed-digests": [
@@ -11650,10 +12964,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9767546197274641539
+          3555205160009401239
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_565.png": {
       "allowed-digests": [
@@ -11695,7 +13009,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11708184300213244484
+          1975120293097303892
         ]
       ], 
       "reviewed-by-human": true
@@ -11839,46 +13153,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11744373400809739356
+          11699531654048406518
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8270526029969251327
+          4523091657809672686
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12686420221117081803
+          10825240656177983622
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12686420221117081803
+          5322506552282967802
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12681809384054758075
+          11489252242825644312
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -11965,10 +13279,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5229914946265067393
+          1584098566405040124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "strokerect_565.png": {
       "allowed-digests": [
@@ -12199,7 +13513,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9529107797168461968
+          5033516764144244033
         ]
       ], 
       "reviewed-by-human": true
@@ -12208,7 +13522,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15098401526248766364
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -12217,7 +13531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          152965079748686847
+          6404558339120488836
         ]
       ], 
       "reviewed-by-human": true
@@ -12226,7 +13540,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1055459124709498581
+          2277109490511489216
         ]
       ], 
       "reviewed-by-human": true
@@ -12235,7 +13549,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12576068860582224002
+          14164859472780460449
         ]
       ], 
       "reviewed-by-human": true
@@ -12357,6 +13671,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5996036510207866577
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6571507317861452784
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9796000551046772836
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9796000551046772836
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4979181777203379619
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -12406,28 +13765,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9407358693309761110
+          5829921135942844635
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -12454,7 +13813,7 @@
           17501446579955337831
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -12499,7 +13858,7 @@
           14626919895309756138
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -12523,46 +13882,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17022932193658353157
+          15732727687033594466
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -12604,7 +13963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5791355409085474167
+          6603262244480838578
         ]
       ], 
       "reviewed-by-human": true
@@ -12649,10 +14008,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5013168967456038846
+          16767964269884530933
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemodes_565.png": {
       "allowed-digests": [
@@ -12676,7 +14035,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11584832146089969107
+          2483911436983576286
         ]
       ], 
       "reviewed-by-human": true
@@ -12685,7 +14044,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14295636111001791530
+          8320002136174109365
         ]
       ], 
       "reviewed-by-human": true
@@ -12712,7 +14071,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14216970501880738242
+          16496795039069152068
         ]
       ], 
       "reviewed-by-human": true
@@ -12721,7 +14080,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14109805982087708293
+          101411760227870599
         ]
       ], 
       "reviewed-by-human": true
@@ -12730,7 +14089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14216970501880738242
+          16384482106126909208
         ]
       ], 
       "reviewed-by-human": true
@@ -12739,7 +14098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11584832146089969107
+          12708776489646732763
         ]
       ], 
       "reviewed-by-human": true
@@ -12814,7 +14173,7 @@
           74109172769746346
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "twopointconical_msaa16.png": {
       "allowed-digests": [
@@ -12829,10 +14188,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10060886431688452398
+          1943698464051928811
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_565.png": {
       "allowed-digests": [
@@ -12874,10 +14233,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14725542749908228
+          16400297164492096982
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_565.png": {
       "allowed-digests": [
@@ -12946,10 +14305,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          539829354440306365
+          18056543758253973423
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_msaa16.png": {
       "allowed-digests": [
@@ -12964,10 +14323,190 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6475798309604476317
+          17294510074434159565
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1952127887831515847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9769614951001146061
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12041989397910562336
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6832825185173658903
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1952127887831515847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9769614951001146061
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12041989397910562336
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6832825185173658903
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1752599991641140864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5112257246836121794
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9488969065851737597
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          449267873124950862
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1752599991641140864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5112257246836121794
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9488969065851737597
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          449267873124950862
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "vertices_565.png": {
       "allowed-digests": [
@@ -13099,10 +14638,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12238883472526934397
+          1831358800461900123
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_565.png": {
       "allowed-digests": [
@@ -13144,55 +14683,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9603191152115149072
+          114252305762558512
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3394570787947912684
+          3112652115716203250
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4231863532718175149
+          12938112915997113104
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6573194240143689227
+          1141902512976477957
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6573194240143689227
+          1141902512976477957
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6573194240143689227
+          1141902512976477957
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
@@ -13216,28 +14755,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18070508412495593985
+          15147018840180384131
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16415047223853670750
+          721300356033145236
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18070508412495593985
+          3813033603856492134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_565.png": {
       "allowed-digests": [
@@ -13279,10 +14818,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1154363106472965006
+          12011229033319908796
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_565.png": {
       "allowed-digests": [
@@ -13306,25 +14845,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3680789048917201641
+          13951513751310057438
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6725067416297177922
+          16184415525257363318
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3680789048917201641
+          14510921787218221764
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
         ]
       ], 
       "reviewed-by-human": false
diff --git a/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Debug/expected-results.json b/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Debug/expected-results.json
index 667b527..c4603f2 100644
--- a/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Debug/expected-results.json
@@ -113,19 +113,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5026092757857652816
+          1146375027159957531
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11350550014829151063
+          6379613855638636955
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -268,7 +270,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2893684135042278491
+          1761278230894790045
         ]
       ], 
       "reviewed-by-human": true
@@ -277,7 +279,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2893684135042278491
+          1761278230894790045
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -298,7 +336,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16937826245063043393
+          4981823264217273689
         ]
       ], 
       "reviewed-by-human": true
@@ -307,7 +345,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1625650000574334368
+          5246634874959150570
         ]
       ], 
       "reviewed-by-human": true
@@ -316,7 +354,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5950834616123524220
+          13773072584611565658
         ]
       ], 
       "reviewed-by-human": true
@@ -325,7 +363,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4439200707771429092
+          15150074299283974308
         ]
       ], 
       "reviewed-by-human": true
@@ -334,7 +372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11836824726968626971
+          14603413282175161618
         ]
       ], 
       "reviewed-by-human": true
@@ -343,49 +381,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7185775830111795273
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7986799885106602241
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_msaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7986799885106602241
+          7826012751896877231
         ]
       ], 
       "reviewed-by-human": true
@@ -412,19 +408,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6556557775884332983
+          11049254347913309109
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12843708684659573815
+          16508684429113109899
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -496,10 +492,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12359262904549189844
+          11021706081645443796
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bigtext_msaa4.png": {
       "allowed-digests": [
@@ -559,7 +556,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5556270988884295076
+          12687331394697954528
         ]
       ], 
       "reviewed-by-human": true
@@ -568,7 +565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410204863204197194
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -577,7 +574,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3378108973415664789
+          271311882745633725
         ]
       ], 
       "reviewed-by-human": true
@@ -586,7 +583,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3378108973415664789
+          271311882745633725
         ]
       ], 
       "reviewed-by-human": true
@@ -841,19 +838,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1911284151223294607
+          12298010451676936832
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5496062952963902498
+          9867627344966414537
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "blend_gpu.png": {
       "allowed-digests": [
@@ -938,7 +941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8585274474692888711
+          12682910021301734282
         ]
       ], 
       "reviewed-by-human": true
@@ -2410,6 +2413,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -2600,16 +2639,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15802800677340237213
+          158195814517883351
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15802800677340237213
+          158195814517883351
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          271466639589239328
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10426400083921889194
         ]
       ], 
       "reviewed-by-human": false
@@ -2855,10 +2930,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5271492299818290635
+          2111070892848864737
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "circles_msaa4.png": {
       "allowed-digests": [
@@ -2943,7 +3019,8 @@
           4165161027652562674
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "clamped_gradients_msaa4.png": {
       "allowed-digests": [
@@ -3499,7 +3576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9173305563013405797
+          6538569194874273793
         ]
       ], 
       "reviewed-by-human": true
@@ -3619,7 +3696,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5551215450807356131
+          12606971060652066622
         ]
       ], 
       "reviewed-by-human": true
@@ -3673,7 +3750,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15764519043297885758
+          4104797309315770800
         ]
       ], 
       "reviewed-by-human": true
@@ -3682,7 +3759,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7935307680550293784
+          6544536706877310514
         ]
       ], 
       "reviewed-by-human": true
@@ -3691,7 +3768,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17629601631421032649
+          14513438909331829416
         ]
       ], 
       "reviewed-by-human": true
@@ -3700,7 +3777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1557613698479648092
+          8097997023778848191
         ]
       ], 
       "reviewed-by-human": true
@@ -3709,7 +3786,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          686626615788563308
+          5836493341538608113
         ]
       ], 
       "reviewed-by-human": true
@@ -3718,7 +3795,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11008419185465923560
+          9084880565837755264
         ]
       ], 
       "reviewed-by-human": true
@@ -3727,7 +3804,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9486392645453497087
+          17768595575576867230
         ]
       ], 
       "reviewed-by-human": true
@@ -3736,7 +3813,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16112459223155284268
+          18260984331770722196
         ]
       ], 
       "reviewed-by-human": true
@@ -3745,7 +3822,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5930938593239004653
+          4165425675033352640
         ]
       ], 
       "reviewed-by-human": true
@@ -3754,7 +3831,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3190552677201665775
+          10152516748782571739
         ]
       ], 
       "reviewed-by-human": true
@@ -3763,7 +3840,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9513391566593573165
+          14914601045858845148
         ]
       ], 
       "reviewed-by-human": true
@@ -3772,7 +3849,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4870317370734649728
+          8180502121217066191
         ]
       ], 
       "reviewed-by-human": true
@@ -3781,7 +3858,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5783287451488289297
+          16993829969091028380
         ]
       ], 
       "reviewed-by-human": true
@@ -3790,7 +3867,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11074069104236429752
+          1059511820934474761
         ]
       ], 
       "reviewed-by-human": true
@@ -3799,7 +3876,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5806668200495180873
+          15952923770779117335
         ]
       ], 
       "reviewed-by-human": true
@@ -3808,7 +3885,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14316497875403562633
+          14110404372599098336
         ]
       ], 
       "reviewed-by-human": true
@@ -3891,43 +3968,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17707691143950027168
+          4792118895672570848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788619303593885819
+          11285887424651164487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17279500842640178602
+          9807676647004956667
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7100780245620768737
+          3010580829471563399
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3986029323432953206
+          13463378520577789165
         ]
       ], 
       "reviewed-by-human": true
@@ -3963,7 +4040,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          878134881943676117
+          8826348418330119107
         ]
       ], 
       "reviewed-by-human": true
@@ -4030,7 +4107,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17138342910351740780
+          15418783980877386199
         ]
       ], 
       "reviewed-by-human": true
@@ -4039,7 +4116,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13937678633951136440
+          7882161322447216882
         ]
       ], 
       "reviewed-by-human": true
@@ -4048,7 +4125,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12437925742673758459
+          4204097215809673028
         ]
       ], 
       "reviewed-by-human": true
@@ -4057,7 +4134,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14755023570715423032
+          7751217857540747
         ]
       ], 
       "reviewed-by-human": true
@@ -4066,7 +4143,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2256130412784819033
+          3184062263576953667
         ]
       ], 
       "reviewed-by-human": true
@@ -4075,7 +4152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10471902765578272701
+          713799816796517938
         ]
       ], 
       "reviewed-by-human": true
@@ -4084,7 +4161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6406309812490590578
+          13367306876695640597
         ]
       ], 
       "reviewed-by-human": true
@@ -4093,7 +4170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9564056393704879247
+          18324282461018392405
         ]
       ], 
       "reviewed-by-human": true
@@ -4126,7 +4203,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7604196399059623193
+          13633210306002531372
         ]
       ], 
       "reviewed-by-human": true
@@ -4250,7 +4327,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          791242651888418698
+          842505089271483404
         ]
       ], 
       "reviewed-by-human": true
@@ -4311,7 +4388,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9374541812861034293
+          11475660560101599954
         ]
       ], 
       "reviewed-by-human": true
@@ -4320,7 +4397,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2576698895183287698
+          7311723676588845146
         ]
       ], 
       "reviewed-by-human": true
@@ -4329,7 +4406,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11639051266587012430
+          12602988813237402949
         ]
       ], 
       "reviewed-by-human": true
@@ -4338,7 +4415,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10884278746786757102
+          8320360396414647822
         ]
       ], 
       "reviewed-by-human": true
@@ -4383,7 +4460,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3767760557629765982
+          4057230872151110302
         ]
       ], 
       "reviewed-by-human": true
@@ -4392,7 +4469,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12070678672447530766
+          9482070623821433904
         ]
       ], 
       "reviewed-by-human": true
@@ -4401,7 +4478,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6894694195096323180
+          1170916231930532316
         ]
       ], 
       "ignore-failure": false, 
@@ -4411,7 +4488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6894694195096323180
+          1170916231930532316
         ]
       ], 
       "ignore-failure": false, 
@@ -4421,49 +4498,45 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -4472,7 +4545,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -4481,7 +4554,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16402901581873179688
+          2053143241305253519
         ]
       ], 
       "reviewed-by-human": true
@@ -4490,7 +4563,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13362740310524141608
+          13558497883564503203
         ]
       ], 
       "reviewed-by-human": true
@@ -4499,103 +4572,79 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14023107341215656134
+          1365476015121733881
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14164969753916932440
+          4085557449317823255
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16402901581873179688
+          2053143241305253519
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13362740310524141608
+          13558497883564503203
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6989712392624471913
+          17775297231868448514
         ]
       ], 
       "reviewed-by-human": true
@@ -4604,7 +4653,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10855232109519818829
+          12804472649182277577
         ]
       ], 
       "reviewed-by-human": true
@@ -4613,31 +4662,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4191781949737697782
+          12650731363086188245
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11095225883539199074
+          7320890964320867858
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -4646,7 +4689,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -4655,7 +4698,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11015226385634627319
+          13504880513739592005
         ]
       ], 
       "reviewed-by-human": true
@@ -4664,7 +4707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12072318510619816364
+          16903774499113610668
         ]
       ], 
       "reviewed-by-human": true
@@ -4673,103 +4716,79 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17095214210643863806
+          6399690160433481902
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1468452751651415530
+          8921034639234342908
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11015226385634627319
+          13504880513739592005
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12072318510619816364
+          16903774499113610668
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2497837460215148124
+          6055955940623478607
         ]
       ], 
       "reviewed-by-human": true
@@ -4778,7 +4797,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13192464168020553898
+          11797865288006977816
         ]
       ], 
       "reviewed-by-human": true
@@ -4787,31 +4806,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3501964266759034972
+          11185694799637075711
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14493483688798209788
+          18352104832144523134
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -4820,7 +4833,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
         ]
       ], 
       "reviewed-by-human": true
@@ -4829,7 +4842,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16613355738876267064
+          14579864208673224889
         ]
       ], 
       "reviewed-by-human": true
@@ -4838,7 +4851,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11814031037659245194
+          15078056460862308465
         ]
       ], 
       "reviewed-by-human": true
@@ -4847,7 +4860,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          4886211991926050486
         ]
       ], 
       "reviewed-by-human": true
@@ -4856,7 +4869,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          8737545656412765906
         ]
       ], 
       "reviewed-by-human": true
@@ -4865,7 +4878,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16220755812352055363
+          14057740961401979106
         ]
       ], 
       "reviewed-by-human": true
@@ -4874,7 +4887,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3630497057597410398
+          6129142780121532863
         ]
       ], 
       "reviewed-by-human": true
@@ -4883,7 +4896,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -4892,7 +4905,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
         ]
       ], 
       "reviewed-by-human": true
@@ -4901,7 +4914,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13026483582621867219
+          10604640727019939807
         ]
       ], 
       "reviewed-by-human": true
@@ -4910,7 +4923,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11870810962143606254
+          8392931363281798442
         ]
       ], 
       "reviewed-by-human": true
@@ -4919,7 +4932,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          4707049264800437834
         ]
       ], 
       "reviewed-by-human": true
@@ -4928,7 +4941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          3175389971476411688
         ]
       ], 
       "reviewed-by-human": true
@@ -4937,7 +4950,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6240516027066032938
+          365721829706691205
         ]
       ], 
       "reviewed-by-human": true
@@ -4946,7 +4959,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6158634465433606581
+          2473941895467574423
         ]
       ], 
       "reviewed-by-human": true
@@ -4955,7 +4968,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
       "reviewed-by-human": true
@@ -4973,25 +4986,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7321152256688530904
+          15394406070971249703
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18007652415364355329
+          14484858848664747251
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5455618422902283397
+          15797039913993285826
         ]
       ], 
       "reviewed-by-human": true
@@ -5000,7 +5015,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14095817193753318732
+          17497164562330387900
         ]
       ], 
       "reviewed-by-human": true
@@ -5009,7 +5024,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3872986862548041645
+          12686426978094913156
         ]
       ], 
       "reviewed-by-human": true
@@ -5018,7 +5033,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3825409027096066799
+          6490420606640500316
         ]
       ], 
       "reviewed-by-human": true
@@ -5027,7 +5042,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          716171842978913864
+          273445276579232833
         ]
       ], 
       "reviewed-by-human": true
@@ -5036,7 +5051,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17171710908581496295
+          13357226331142394630
         ]
       ], 
       "reviewed-by-human": true
@@ -5045,7 +5060,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16393840778105859134
+          3819664262710657017
         ]
       ], 
       "reviewed-by-human": true
@@ -5054,7 +5069,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12578433082733978467
+          367215542131912432
         ]
       ], 
       "reviewed-by-human": true
@@ -5081,7 +5096,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18222344878169758652
+          12767183233496534484
         ]
       ], 
       "reviewed-by-human": true
@@ -5099,7 +5114,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16452419234213932266
+          1802138798652377585
         ]
       ], 
       "reviewed-by-human": true
@@ -5108,7 +5123,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13347568447034524087
+          588269449619860245
         ]
       ], 
       "reviewed-by-human": true
@@ -5117,7 +5132,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8048041692818960741
+          13516932575826030439
         ]
       ], 
       "reviewed-by-human": true
@@ -5126,7 +5141,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14770838630769789516
+          649418728571953564
         ]
       ], 
       "reviewed-by-human": true
@@ -5275,6 +5290,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -5480,7 +5531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -5489,7 +5540,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -5516,7 +5567,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -5525,7 +5576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -5552,7 +5603,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -5561,7 +5612,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -5588,7 +5639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -5597,7 +5648,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -5624,7 +5675,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -5633,7 +5684,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -5660,7 +5711,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -5669,7 +5720,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -5696,7 +5747,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -5705,7 +5756,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -5732,7 +5783,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -5741,7 +5792,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -5768,7 +5819,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -5777,7 +5828,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -5840,7 +5891,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -5849,7 +5900,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -5912,7 +5963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -5921,7 +5972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -5948,7 +5999,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -5957,7 +6008,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
@@ -5980,6 +6031,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2286802257293267683
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4050292462410603306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -6002,85 +6089,83 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          17276962213970077366
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          8694218356938189525
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1857288326388942863
         ]
       ], 
-      "ignore-failure": false
+      "bugs": [
+        2887
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1857288326388942863
         ]
       ], 
-      "ignore-failure": false
+      "bugs": [
+        2887
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          4335659971728708662
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": false
     }, 
     "fontmgr_match_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -6118,11 +6203,47 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2500355683115767624
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954882728248735643
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954882728248735643
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7818310295492545479
+          11716334334721910796
         ]
       ], 
       "reviewed-by-human": true
@@ -6131,7 +6252,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4994151175360770217
+          5693920054563327483
         ]
       ], 
       "reviewed-by-human": true
@@ -6140,7 +6261,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16992328529818347083
+          4779790303751499909
         ]
       ], 
       "ignore-failure": false, 
@@ -6150,7 +6271,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10536938466654728031
+          11415732188148058124
         ]
       ], 
       "ignore-failure": false, 
@@ -6178,7 +6299,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11958130802613243691
+          18352804101744384563
         ]
       ], 
       "reviewed-by-human": true
@@ -6684,6 +6805,294 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17133241123252992386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17133241123252992386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2740474667902760224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13062572212227089670
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2740474667902760224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13062572212227089670
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18181809164582745765
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10646101256712397679
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5216581726550480243
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14988814117683836650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16062483234765207871
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3020788879261074646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2740474667902760224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13062572212227089670
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863085462100832326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14621205964232291210
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          738609491282019773
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271247215169625597
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2739908385541953120
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16879059920514854608
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -6715,10 +7124,7 @@
           6515341671020089010
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa4.png": {
       "allowed-digests": [
@@ -6799,7 +7205,7 @@
           8697473946772464652
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa4.png": {
       "allowed-digests": [
@@ -6835,7 +7241,7 @@
           6477843407979522548
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa4.png": {
       "allowed-digests": [
@@ -6871,7 +7277,7 @@
           14407511764193782824
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa4.png": {
       "allowed-digests": [
@@ -7080,7 +7486,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -7118,7 +7524,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13538992606665750486
+          8988444324654919932
         ]
       ], 
       "reviewed-by-human": true
@@ -7170,7 +7576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12254036309807088467
+          15771786769254973604
         ]
       ], 
       "reviewed-by-human": true
@@ -7212,25 +7618,24 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15608068978304990937
+          974999507980407411
         ]
       ], 
-      "bugs": [
-        1655
-      ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6086347690359883301
+          14247877693672647204
         ]
       ], 
       "bugs": [
         1655
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -7348,11 +7753,47 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          741134624395776214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          357284903731074601
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10462784937398826625
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10462784937398826625
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3794665630847901594
+          13620335786972140736
         ]
       ], 
       "reviewed-by-human": true
@@ -7361,7 +7802,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7748801528548244433
+          17030111096598942390
         ]
       ], 
       "reviewed-by-human": true
@@ -7370,7 +7811,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10600008287836361870
+          1105584058315288349
         ]
       ], 
       "ignore-failure": false, 
@@ -7380,7 +7821,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259128835424197006
+          1922338586017046100
         ]
       ], 
       "reviewed-by-human": true
@@ -7389,7 +7830,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13149265802466457140
+          3693078186234250164
         ]
       ], 
       "reviewed-by-human": true
@@ -7398,7 +7839,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6055181530730610249
+          11518661682572191380
         ]
       ], 
       "reviewed-by-human": true
@@ -7407,7 +7848,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          467903512579381270
+          13388867466611225896
         ]
       ], 
       "reviewed-by-human": true
@@ -7416,7 +7857,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15006392815688908432
+          10285237549190759962
         ]
       ], 
       "ignore-failure": false, 
@@ -7462,7 +7903,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6719033984262147569
+          9334915207072042375
         ]
       ], 
       "reviewed-by-human": true
@@ -7471,7 +7912,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9527595429529547733
+          4262113639047937913
         ]
       ], 
       "reviewed-by-human": true
@@ -7480,7 +7921,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3901701882206486087
+          13519884549264043430
         ]
       ], 
       "ignore-failure": false, 
@@ -7490,7 +7931,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13854151776049831058
+          4393655961616093182
         ]
       ], 
       "ignore-failure": false, 
@@ -7500,25 +7941,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8498778868685964382
+          9643897842146508458
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          880034339526468883
+          14154076457851775362
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7378130804090280505
+          6187141994062797732
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_msaa4.png": {
       "allowed-digests": [
@@ -7532,7 +7976,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219558445660995645
+          16816155573392653040
         ]
       ], 
       "reviewed-by-human": true
@@ -7541,7 +7985,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          861754899676926834
+          15621659488709502951
         ]
       ], 
       "reviewed-by-human": true
@@ -7550,7 +7994,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2189776203782237302
+          13481672823921868407
         ]
       ], 
       "reviewed-by-human": true
@@ -7559,7 +8003,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16812648126579727424
+          5523411567262382106
         ]
       ], 
       "reviewed-by-human": true
@@ -7568,7 +8012,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15200137971968303012
+          14400660572715212845
         ]
       ], 
       "reviewed-by-human": true
@@ -7577,7 +8021,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199776944359958607
+          12820728063175372793
         ]
       ], 
       "reviewed-by-human": true
@@ -7595,12 +8039,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14205191585536753006
+          2586660090509305197
         ]
       ], 
-      "bugs": [
-        1985
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -7608,39 +8049,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7984057522805858516
+          88044436581289267
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          28560584844019362
+          12997200926589207952
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5274487773236388163
+          4458594706234736506
         ]
       ], 
       "reviewed-by-human": true
@@ -7649,7 +8094,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10772725192724193725
+          7881653068493848399
         ]
       ], 
       "reviewed-by-human": true
@@ -7658,7 +8103,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4439390010850114092
+          12683787554719393302
         ]
       ], 
       "reviewed-by-human": true
@@ -7667,7 +8112,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7359778396292882174
+          18111354910595959932
         ]
       ], 
       "reviewed-by-human": true
@@ -7844,25 +8289,22 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6457829872533044881
+          1889599541186254424
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3484111703141212082
+          7255273740487203408
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
@@ -7940,7 +8382,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15118920252874319058
+          9075523320529578103
         ]
       ], 
       "reviewed-by-human": true
@@ -7949,7 +8391,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13213375518846743511
+          4131799565799962704
         ]
       ], 
       "reviewed-by-human": true
@@ -7958,7 +8400,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8215825475342594196
+          13362151343000560853
         ]
       ], 
       "reviewed-by-human": true
@@ -7967,7 +8409,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10703646791439328135
+          179903152301013150
         ]
       ], 
       "reviewed-by-human": true
@@ -7976,7 +8418,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7394602124225746876
+          4095489997625677813
         ]
       ], 
       "reviewed-by-human": true
@@ -7985,7 +8427,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768949088352973106
+          17687576741285937089
         ]
       ], 
       "reviewed-by-human": true
@@ -7994,7 +8436,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12299776392542434240
+          16350254171643964347
         ]
       ], 
       "reviewed-by-human": true
@@ -8003,7 +8445,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13360137564165442940
+          15500554310857216494
         ]
       ], 
       "reviewed-by-human": true
@@ -8028,17 +8470,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10006188054349176574
+          14694204158057728253
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11696269093170011678
+          9645881182143954138
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumamode_565.png": {
       "allowed-digests": [
@@ -8076,7 +8520,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14753870890166488787
+          13546074453897362674
         ]
       ], 
       "reviewed-by-human": true
@@ -8085,7 +8529,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12332409505555151686
+          2645433785253737964
         ]
       ], 
       "reviewed-by-human": true
@@ -8094,7 +8538,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12919974392613482745
+          4116381614494335362
         ]
       ], 
       "reviewed-by-human": true
@@ -8103,7 +8547,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12919974392613482745
+          4116381614494335362
         ]
       ], 
       "reviewed-by-human": true
@@ -8172,7 +8616,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12842668762277630465
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8181,7 +8625,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1883413208707995739
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8214,7 +8658,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12842668762277630465
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8223,7 +8667,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1883413208707995739
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8256,7 +8700,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12842668762277630465
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8265,7 +8709,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1883413208707995739
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8292,7 +8736,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16535785180897049372
+          17906316606932287523
         ]
       ], 
       "reviewed-by-human": true
@@ -8335,19 +8779,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15954233068969828611
+          10690075085961116152
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15954233068969828611
+          10690075085961116152
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
@@ -8385,6 +8831,366 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1799022373381634937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16072650776783849785
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16949296854614739341
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16870762334260965145
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10168290996640020029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17974959293136356721
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7647115313085356918
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18294645664025061405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6876146362791096301
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          672013974639373790
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          407121617914140822
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17107111279642959699
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13019697501260947975
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14977913019013260327
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5641947831670404346
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          937225195420941057
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16646836410262782197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18100820390850075519
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2574095166522288827
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8955432419196193693
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -8575,7 +9381,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15293668784585893125
+          4656886197492028969
         ]
       ], 
       "reviewed-by-human": true
@@ -8584,7 +9390,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17470748697630737319
+          10009949554846362902
         ]
       ], 
       "reviewed-by-human": true
@@ -8593,7 +9399,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8013314903160673417
+          16425393435205920402
         ]
       ], 
       "reviewed-by-human": true
@@ -8602,7 +9408,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14816111461423147722
+          16688770112471467177
         ]
       ], 
       "reviewed-by-human": true
@@ -8635,19 +9441,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          6176209756741778646
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          6176209756741778646
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -8671,10 +9479,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1219491329735674349
+          3849340549236541887
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "ovals_msaa4.png": {
       "allowed-digests": [
@@ -8686,6 +9495,78 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12854990838652667931
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16478730915407089386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11115688412167805107
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4893664413873629107
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -8714,7 +9595,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13767201167892001999
+          14746240212910087597
         ]
       ], 
       "reviewed-by-human": true
@@ -8756,7 +9637,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14555493949249922058
+          10102068867409260207
         ]
       ], 
       "reviewed-by-human": true
@@ -8964,7 +9845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          477994727837130729
+          8959682453711286650
         ]
       ], 
       "reviewed-by-human": true
@@ -9018,7 +9899,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -9027,7 +9908,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -9036,17 +9917,53 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4777066890322501677
+          16202756285536072592
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8190195795812546474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8190195795812546474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7592079403906379683
+          16202756285536072592
         ]
       ], 
       "ignore-failure": false, 
@@ -9088,6 +10005,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11523502336595345447
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -9124,6 +10077,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -9172,7 +10161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18000254716935645999
+          13710370929503896242
         ]
       ], 
       "reviewed-by-human": true
@@ -9181,7 +10170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16383033135480419663
+          14868659503042841956
         ]
       ], 
       "reviewed-by-human": true
@@ -9190,7 +10179,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7284761092876246188
+          10839024960221357604
         ]
       ], 
       "reviewed-by-human": true
@@ -9199,7 +10188,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11519978157451678721
+          4353301731847242860
         ]
       ], 
       "reviewed-by-human": true
@@ -9226,25 +10215,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16113518265745121824
+          11943929872177488726
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "polygons_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13042174351117973323
+          18412169674810091291
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16422530932852428674
+          2214368729624239628
         ]
       ], 
       "reviewed-by-human": true
@@ -9253,7 +10242,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13797585911734062488
+          13695847048236137972
         ]
       ], 
       "reviewed-by-human": true
@@ -9262,7 +10251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14655234950067739505
+          12911950575835675253
         ]
       ], 
       "reviewed-by-human": true
@@ -9271,7 +10260,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16247577806145016641
+          12770899583726255744
         ]
       ], 
       "reviewed-by-human": true
@@ -9280,7 +10269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13221078215540522692
+          6757078992106948579
         ]
       ], 
       "reviewed-by-human": true
@@ -9289,7 +10278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7149831205496297560
+          24796932854446382
         ]
       ], 
       "reviewed-by-human": true
@@ -9298,7 +10287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17577789094752396345
+          15761539880746862400
         ]
       ], 
       "reviewed-by-human": true
@@ -9307,7 +10296,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10381960982730511552
+          10004632522250129097
         ]
       ], 
       "reviewed-by-human": true
@@ -9332,17 +10321,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1214323161004682693
+          2345997695698587496
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "radial_gradient2_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          517817170355194916
+          13265214489338924633
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_565.png": {
       "allowed-digests": [
@@ -9372,19 +10363,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8572585790542700888
+          9371573623541139881
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8572585790542700888
+          9371573623541139881
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -9408,7 +10401,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4961203383083962998
+          1197889143489694088
         ]
       ], 
       "reviewed-by-human": true
@@ -9476,7 +10469,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4404268085170872926
+          1238816738306779698
         ]
       ], 
       "reviewed-by-human": true
@@ -9602,7 +10595,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5421265310411119471
+          4652843928975001956
         ]
       ], 
       "reviewed-by-human": true
@@ -9674,10 +10667,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          737317753319305404
+          1288562748996894577
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rrect_draw_aa_msaa4.png": {
       "allowed-digests": [
@@ -9746,7 +10739,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10207186591028010237
+          2155978747761042485
         ]
       ], 
       "reviewed-by-human": true
@@ -9890,7 +10883,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8301470970114807246
+          11838132127013699928
         ]
       ], 
       "reviewed-by-human": true
@@ -9899,7 +10892,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1089343327835502505
+          15717961650619683621
         ]
       ], 
       "reviewed-by-human": true
@@ -9926,7 +10919,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8987936749168597901
+          15930720713777284476
         ]
       ], 
       "reviewed-by-human": true
@@ -9935,7 +10928,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8987936749168597901
+          15930720713777284476
         ]
       ], 
       "reviewed-by-human": true
@@ -10097,7 +11090,8 @@
           13223903649982789417
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "shadows_msaa4.png": {
       "allowed-digests": [
@@ -10334,7 +11328,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8130019868850205893
+          17911005775522481791
         ]
       ], 
       "reviewed-by-human": true
@@ -10440,9 +11434,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14248208315278090286
+          16076861668720652969
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "skbug1719_msaa4.png": {
       "allowed-digests": [
@@ -10457,7 +11452,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14585555250092963383
+          13909757336310240518
         ]
       ], 
       "reviewed-by-human": true
@@ -10466,7 +11461,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6423558589708144215
+          17885518595384354919
         ]
       ], 
       "reviewed-by-human": true
@@ -10493,7 +11488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11744373400809739356
+          11699531654048406518
         ]
       ], 
       "reviewed-by-human": true
@@ -10502,7 +11497,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8270526029969251327
+          4523091657809672686
         ]
       ], 
       "reviewed-by-human": true
@@ -10511,7 +11506,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1380374968369111790
+          11932325483223150611
         ]
       ], 
       "reviewed-by-human": true
@@ -10520,7 +11515,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1380374968369111790
+          4758860195708070393
         ]
       ], 
       "reviewed-by-human": true
@@ -10628,7 +11623,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11725101012616316052
+          6137491411888461050
         ]
       ], 
       "reviewed-by-human": true
@@ -10796,7 +11791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12416137150818188702
+          6800887868791302499
         ]
       ], 
       "reviewed-by-human": true
@@ -10814,7 +11809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10230426069067413407
+          18286981917824090179
         ]
       ], 
       "reviewed-by-human": true
@@ -10823,7 +11818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15098401526248766364
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -10832,7 +11827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16598261928768030936
+          11625837403190001764
         ]
       ], 
       "reviewed-by-human": true
@@ -10841,7 +11836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14551311725473456993
+          3753618903036190582
         ]
       ], 
       "reviewed-by-human": true
@@ -10892,7 +11887,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15528863190484305841
+          1369006746513120542
         ]
       ], 
       "reviewed-by-human": true
@@ -10901,7 +11896,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15197842121034928067
+          10584886924228958226
         ]
       ], 
       "reviewed-by-human": true
@@ -10910,10 +11905,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7549641138224830904
+          4597062943976028698
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "testimagefilters_msaa4.png": {
       "allowed-digests": [
@@ -10966,6 +11962,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          163112871246100159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -11006,19 +12038,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3355189550605099479
+          1542449700616506808
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3355189550605099479
+          1542449700616506808
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -11045,7 +12077,8 @@
           10999541404612369092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa4.png": {
       "allowed-digests": [
@@ -11081,7 +12114,8 @@
           1946366533119786586
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa4.png": {
       "allowed-digests": [
@@ -11096,7 +12130,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17022932193658353157
+          15732727687033594466
         ]
       ], 
       "reviewed-by-human": true
@@ -11105,7 +12139,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -11114,7 +12148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -11123,7 +12157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -11222,7 +12256,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5051951153050201080
+          15432201581929914329
         ]
       ], 
       "reviewed-by-human": true
@@ -11231,7 +12265,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          525633548833083339
+          15270349007635227054
         ]
       ], 
       "reviewed-by-human": true
@@ -11258,7 +12292,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7249864038792229190
+          8293716677305839949
         ]
       ], 
       "reviewed-by-human": true
@@ -11267,7 +12301,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7249864038792229190
+          8293716677305839949
         ]
       ], 
       "reviewed-by-human": true
@@ -11460,6 +12494,150 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683867137211693534
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11064306957043870693
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683867137211693534
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11064306957043870693
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16282339837156485923
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2548812463070281529
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16282339837156485923
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2548812463070281529
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -11608,7 +12786,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3394570787947912684
+          3112652115716203250
         ]
       ], 
       "reviewed-by-human": true
@@ -11617,7 +12795,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4231863532718175149
+          12938112915997113104
         ]
       ], 
       "reviewed-by-human": true
@@ -11626,7 +12804,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8487916907396584951
+          1512989932016141784
         ]
       ], 
       "reviewed-by-human": true
@@ -11635,7 +12813,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8487916907396584951
+          1512989932016141784
         ]
       ], 
       "reviewed-by-human": true
@@ -11662,7 +12840,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10006734138077464282
+          3259542057496795230
         ]
       ], 
       "reviewed-by-human": true
@@ -11671,7 +12849,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9458503948962017865
+          17330165520408407412
         ]
       ], 
       "reviewed-by-human": true
@@ -11734,7 +12912,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2651990224646434968
+          12373255510807920217
         ]
       ], 
       "reviewed-by-human": true
@@ -11743,10 +12921,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6135004858351118478
+          14037617966684837344
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14593717200149920625
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14593717200149920625
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json b/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Release-Recipes/expected-results.json
similarity index 60%
copy from expectations/gm/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json
copy to expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Release-Recipes/expected-results.json
index bdd5217..5462c43 100644
--- a/expectations/gm/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Release-Recipes/expected-results.json
@@ -37,10 +37,16 @@
           2054956815327187963
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "3x3bitmaprect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2054956815327187963
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "aaclip_565.png": {
       "allowed-digests": [
@@ -64,16 +70,26 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10348117792540005656
+          671622424901235344
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "aaclip_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17071572681547805645
+        ]
+      ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
     "aarectmodes_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3404105191202303432
+          14760033689012826769
         ]
       ], 
       "bugs": [
@@ -85,7 +101,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11273986525140282221
+          13739372576644267630
         ]
       ], 
       "bugs": [
@@ -97,13 +113,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5564579097835689226
+          1146375027159957531
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6379613855638636955
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -133,19 +157,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16679719501773877249
+          4424928001525270278
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "alphagradients_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13824040243765634976
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "android_paint_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14311572539143932530
+          2341648886856445164
         ]
       ], 
       "bugs": [
@@ -157,7 +187,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8184968261467646356
+          5769176894888533648
         ]
       ], 
       "bugs": [
@@ -169,7 +199,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16578618981524164940
+          6832276110046226725
         ]
       ], 
       "bugs": [
@@ -177,35 +207,44 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "android_paint_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          456109718969461821
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "arcofzorro_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14297291255102949024
+          13786535001616823825
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "arcofzorro_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12650638297902351267
+          8666021583927870678
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "arcofzorro_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5103413628089441416
+          10746379129215911669
+        ]
+      ]
+    }, 
+    "arcofzorro_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17002240467480611027
         ]
       ]
     }, 
@@ -213,7 +252,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6535059923367762503
+          8274897023630205151
         ]
       ], 
       "reviewed-by-human": true
@@ -222,7 +261,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1951236732185589783
+          13062082258702353494
         ]
       ], 
       "reviewed-by-human": true
@@ -231,7 +270,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15667116140869597659
+          1761278230894790045
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arithmode_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1761278230894790045
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -240,7 +324,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15429625158026413569
+          17005587388995313084
         ]
       ], 
       "bugs": [
@@ -252,7 +336,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11753547281694642402
+          4981823264217273689
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_conic_effects_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5246634874959150570
         ]
       ], 
       "reviewed-by-human": true
@@ -261,7 +354,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12989453616557980490
+          13773072584611565658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_cubic_effects_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15150074299283974308
         ]
       ], 
       "reviewed-by-human": true
@@ -270,52 +372,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16976789512297453380
+          14603413282175161618
         ]
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
+    "bezier_quad_effects_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864700347231029854
+          7826012751896877231
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17080656068138564372
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14704206703218007573
+          2422083043229439955
         ]
       ], 
       "reviewed-by-human": false
@@ -333,16 +408,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17467678310125758092
+          11049254347913309109
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "bigblurs_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16508684429113109899
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6169251833522681202
+          10240571881937710202
         ]
       ], 
       "bugs": [
@@ -354,7 +438,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10455976041474647335
+          14225434535210388132
         ]
       ], 
       "bugs": [
@@ -366,19 +450,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18154086740989312733
+          3852188643697536108
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "bigmatrix_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8057534357246918104
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "bigtext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9208106745937650664
+          13522834714006056195
         ]
       ], 
       "bugs": [
@@ -390,7 +480,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224084673272175658
+          15371795889574689123
         ]
       ], 
       "bugs": [
@@ -402,13 +492,20 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11616592246687288786
+          11021706081645443796
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "bigtext_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6853721018259764749
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "bitmap_premul_565.png": {
       "allowed-digests": [
@@ -417,6 +514,9 @@
           3459248890389921752
         ]
       ], 
+      "bugs": [
+        1759
+      ], 
       "reviewed-by-human": false
     }, 
     "bitmap_premul_8888.png": {
@@ -426,6 +526,9 @@
           1875487390803094182
         ]
       ], 
+      "bugs": [
+        1759
+      ], 
       "reviewed-by-human": false
     }, 
     "bitmap_premul_gpu.png": {
@@ -435,13 +538,25 @@
           1875487390803094182
         ]
       ], 
+      "bugs": [
+        1759
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmap_premul_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1875487390803094182
+        ]
+      ], 
       "reviewed-by-human": false
     }, 
     "bitmapfilters_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          299280079964293648
+          12687331394697954528
         ]
       ], 
       "reviewed-by-human": true
@@ -450,7 +565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1785801269079633261
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -459,7 +574,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8975361232797313708
+          271311882745633725
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapfilters_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          271311882745633725
         ]
       ], 
       "reviewed-by-human": true
@@ -468,115 +592,115 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18028564147828277613
+          15954400542104295064
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmaprect_i_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14065905418589114539
+          1263164671174760260
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmaprect_i_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8511579297892894623
+          15889635428898938024
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "bitmaprect_i_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18385248633144273285
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "bitmaprect_s_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18028564147828277613
+          15954400542104295064
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmaprect_s_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14065905418589114539
+          1263164671174760260
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmaprect_s_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8511579297892894623
+          15889635428898938024
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "bitmaprect_s_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18385248633144273285
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "bitmaprecttest_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1454528164630516875
+          5432165152598403513
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmaprecttest_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1454528164630516875
+          5432165152598403513
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmaprecttest_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1454528164630516875
+          5432165152598403513
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "bitmaprecttest_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16511728478537962232
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "bitmapscroll_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6745916709387193253
+          2196346147885638539
         ]
       ], 
       "bugs": [
@@ -588,7 +712,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4717735016506370050
+          4883607151963013153
         ]
       ], 
       "bugs": [
@@ -600,19 +724,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          930590022062657844
+          13160232247494763565
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "bitmapscroll_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          941789738099764326
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "bitmapshaders_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          787402053855503258
+          12003105459052744890
         ]
       ], 
       "reviewed-by-human": true
@@ -621,7 +751,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13897226711214500859
+          23481610040948036
         ]
       ], 
       "reviewed-by-human": true
@@ -630,16 +760,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4527303960541121992
+          11942752365219497015
         ]
       ], 
-      "reviewed-by-human": false
+      "bugs": [
+        2293
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapshaders_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8391486305693314097
+        ]
+      ], 
+      "bugs": [
+        2293
+      ], 
+      "reviewed-by-human": true
     }, 
     "bitmapsource_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15581542612528711266
+          10503127572291510299
         ]
       ], 
       "reviewed-by-human": true
@@ -648,7 +793,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071585613760610277
+          10522304426373074824
         ]
       ], 
       "reviewed-by-human": true
@@ -657,7 +802,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5847234706736959503
+          7685474019394322155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapsource_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7685474019394322155
         ]
       ], 
       "reviewed-by-human": true
@@ -666,7 +820,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1844781142419806112
+          5804278196362313921
         ]
       ], 
       "reviewed-by-human": true
@@ -675,7 +829,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          749193672577578009
+          10874368221386742934
         ]
       ], 
       "reviewed-by-human": true
@@ -684,16 +838,49 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9718993354602675709
+          12298010451676936832
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bleed_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9867627344966414537
+        ]
+      ], 
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blend_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15908269249044190948
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
+    "blend_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15908269249044190948
+        ]
+      ], 
+      "ignore-failure": false
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8149334815780864538
+          17148910878401545731
         ]
       ], 
       "reviewed-by-human": false
@@ -702,7 +889,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11187657384039514790
+          6067714883605508534
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurcircles_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7279256031086971938
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurcircles_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7279256031086971938
         ]
       ], 
       "reviewed-by-human": false
@@ -713,11 +918,7 @@
           "bitmap-64bitMD5", 
           14575894174086753692
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "blurquickreject_8888.png": {
       "allowed-digests": [
@@ -725,17 +926,22 @@
           "bitmap-64bitMD5", 
           1951057418144050940
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "blurquickreject_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8292097632245464218
+          1467070598154572645
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurquickreject_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12682910021301734282
         ]
       ], 
       "reviewed-by-human": true
@@ -744,7 +950,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          820069996201877993
+          7937640658770483101
         ]
       ], 
       "reviewed-by-human": true
@@ -767,11 +973,20 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_25_100_20_inner_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3184582570657056326
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_25_100_20_inner_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12718077445807995842
+          2980156820919596497
         ]
       ], 
       "bugs": [
@@ -798,16 +1013,22 @@
           5778991912674004218
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_25_100_20_inner_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5778991912674004218
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_25_100_20_normal_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8935160718296765370
+          2538610438575582155
         ]
       ], 
       "reviewed-by-human": true
@@ -830,11 +1051,20 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_25_100_20_normal_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16776390169922007578
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_25_100_20_normal_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2256669791146023451
+          13515504142273854629
         ]
       ], 
       "bugs": [
@@ -861,16 +1091,22 @@
           10179579145235258409
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_25_100_20_normal_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10179579145235258409
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_25_100_20_outer_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14392183012539686738
+          979535589726215668
         ]
       ], 
       "reviewed-by-human": true
@@ -893,11 +1129,20 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_25_100_20_outer_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16043278436798717097
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_25_100_20_outer_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14390657820413340948
+          469891400263202822
         ]
       ], 
       "bugs": [
@@ -924,16 +1169,22 @@
           795828165830353598
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_25_100_20_outer_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          795828165830353598
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_25_100_2_inner_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13601707396267686719
+          11641473617599999419
         ]
       ], 
       "bugs": [
@@ -960,16 +1211,22 @@
           8459602697994167638
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_25_100_2_inner_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8459602697994167638
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_25_100_2_inner_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010715170666325693
+          2497946753949588222
         ]
       ], 
       "bugs": [
@@ -996,16 +1253,22 @@
           14526183591501064820
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_25_100_2_inner_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14526183591501064820
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_25_100_2_normal_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16822449160546304858
+          11877010048399988714
         ]
       ], 
       "bugs": [
@@ -1032,16 +1295,22 @@
           2027939861397155283
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_25_100_2_normal_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2027939861397155283
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_25_100_2_normal_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7324830233289320569
+          10672373549329653561
         ]
       ], 
       "bugs": [
@@ -1068,16 +1337,22 @@
           16228083818774745601
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_25_100_2_normal_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16228083818774745601
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_25_100_2_outer_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3539263275279493989
+          11787269131518922484
         ]
       ], 
       "bugs": [
@@ -1104,16 +1379,22 @@
           11235472972448689767
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_25_100_2_outer_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11235472972448689767
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_25_100_2_outer_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18397664291113348978
+          17766756600887659495
         ]
       ], 
       "bugs": [
@@ -1140,16 +1421,22 @@
           3014025170376903742
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_25_100_2_outer_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014025170376903742
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_100_20_inner_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8147548538595899093
+          15006337376019039104
         ]
       ], 
       "reviewed-by-human": true
@@ -1172,11 +1459,20 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_5_100_20_inner_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450430456683814098
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_5_100_20_inner_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3392741620327676409
+          13488428611470317575
         ]
       ], 
       "bugs": [
@@ -1203,16 +1499,22 @@
           6934363565052222509
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_100_20_inner_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6934363565052222509
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_100_20_normal_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5777905000809157737
+          2662024595823670226
         ]
       ], 
       "reviewed-by-human": true
@@ -1235,11 +1537,20 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_5_100_20_normal_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6260375605261477035
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_5_100_20_normal_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          106403897902062488
+          6430918336013269123
         ]
       ], 
       "bugs": [
@@ -1266,16 +1577,22 @@
           685229733900948221
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_100_20_normal_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          685229733900948221
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_100_20_outer_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15285897477966750444
+          2703515622849643953
         ]
       ], 
       "reviewed-by-human": true
@@ -1298,11 +1615,20 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_5_100_20_outer_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8078454220178362362
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_5_100_20_outer_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17750039418684378027
+          16620284574674851854
         ]
       ], 
       "bugs": [
@@ -1329,16 +1655,22 @@
           805644383472349129
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_100_20_outer_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          805644383472349129
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_100_2_inner_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14103173815576510618
+          1854592748881346557
         ]
       ], 
       "bugs": [
@@ -1365,16 +1697,22 @@
           8586295779506545029
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_100_2_inner_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8586295779506545029
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_100_2_inner_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17524943648572389133
+          6494357978488384985
         ]
       ], 
       "bugs": [
@@ -1401,16 +1739,22 @@
           10060482719496990794
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_100_2_inner_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10060482719496990794
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_100_2_normal_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8152120831203711857
+          2768527762178886297
         ]
       ], 
       "bugs": [
@@ -1437,16 +1781,22 @@
           10705231956829285301
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_100_2_normal_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10705231956829285301
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_100_2_normal_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12328862147889454268
+          9556862863752256436
         ]
       ], 
       "bugs": [
@@ -1473,16 +1823,22 @@
           15258994592739155032
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_100_2_normal_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15258994592739155032
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_100_2_outer_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2981653799231691010
+          12910036470964562372
         ]
       ], 
       "bugs": [
@@ -1509,16 +1865,22 @@
           14266854668713428040
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_100_2_outer_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14266854668713428040
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_100_2_outer_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13987214398939984878
+          10635770833288139564
         ]
       ], 
       "bugs": [
@@ -1545,16 +1907,22 @@
           7552003167091473918
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_100_2_outer_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7552003167091473918
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_5_20_inner_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17480567211870826097
+          8689938548045974643
         ]
       ], 
       "bugs": [
@@ -1580,11 +1948,20 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_5_5_20_inner_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17796133053007318503
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_5_5_20_inner_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17480567211870826097
+          8689938548045974643
         ]
       ], 
       "bugs": [
@@ -1611,19 +1988,28 @@
           4056266015657707537
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_5_20_inner_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4056266015657707537
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_5_20_normal_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11526247382010115107
+          8689938548045974643
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "blurrect_5_5_20_normal_fast_8888.png": {
       "allowed-digests": [
@@ -1643,11 +2029,20 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_5_5_20_normal_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17802184554241704666
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_5_5_20_normal_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14693279281973817316
+          8689938548045974643
         ]
       ], 
       "bugs": [
@@ -1674,19 +2069,28 @@
           5373137501337162900
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_5_20_normal_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5373137501337162900
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_5_20_outer_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13364339805031281090
+          8689938548045974643
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "blurrect_5_5_20_outer_fast_8888.png": {
       "allowed-digests": [
@@ -1706,11 +2110,20 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_5_5_20_outer_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8793723769315696288
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_5_5_20_outer_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          778688345972082046
+          8689938548045974643
         ]
       ], 
       "bugs": [
@@ -1737,16 +2150,22 @@
           3351391123811424042
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_5_20_outer_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3351391123811424042
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_5_2_inner_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9837373898678543005
+          8302766638569272530
         ]
       ], 
       "bugs": [
@@ -1773,16 +2192,22 @@
           8753902296095062956
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_5_2_inner_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8753902296095062956
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_5_2_inner_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8768734282047712040
+          11936654946112556152
         ]
       ], 
       "bugs": [
@@ -1809,16 +2234,22 @@
           5736147449766359017
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_5_2_inner_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5736147449766359017
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_5_2_normal_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13703672010266950657
+          2373554527744690058
         ]
       ], 
       "bugs": [
@@ -1845,16 +2276,22 @@
           3606241125593407269
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_5_2_normal_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3606241125593407269
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_5_2_normal_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3915594753875998111
+          4682955924562239319
         ]
       ], 
       "bugs": [
@@ -1881,16 +2318,22 @@
           15504874507306860669
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_5_2_normal_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15504874507306860669
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_5_2_outer_fast_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3431843565557123885
+          11460116042811593798
         ]
       ], 
       "bugs": [
@@ -1917,16 +2360,22 @@
           5438277324777890642
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_5_2_outer_fast_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5438277324777890642
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_5_5_2_outer_slow_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12762400988164231611
+          12181747588025565695
         ]
       ], 
       "bugs": [
@@ -1953,16 +2402,58 @@
           15858720212484315695
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_5_5_2_outer_slow_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15858720212484315695
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
+    }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          621096468045033319
+          2707547671401008766
         ]
       ], 
       "bugs": [
@@ -1986,19 +2477,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7704622158080950782
+          16140144931673608909
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_inner_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16140144931673608909
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_normal_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17577119326547731450
+          12992313620871801308
         ]
       ], 
       "bugs": [
@@ -2022,19 +2519,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4623570465766786751
+          6671489295833268361
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_normal_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6671489295833268361
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_outer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8428983424693155205
+          13733572974310280657
         ]
       ], 
       "bugs": [
@@ -2058,19 +2561,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13463578097308563300
+          7017089093030580678
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_outer_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7017089093030580678
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrect_solid_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17328977028061879775
+          11400749014246816197
         ]
       ], 
       "bugs": [
@@ -2094,19 +2603,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18282763485464690287
+          1644599672379380535
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "blurrect_solid_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1644599672379380535
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "blurrects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3696341484825569467
+          13080629583390552103
         ]
       ], 
       "reviewed-by-human": false
@@ -2124,7 +2639,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          260989999972072184
+          158195814517883351
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          158195814517883351
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          271466639589239328
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10426400083921889194
         ]
       ], 
       "reviewed-by-human": false
@@ -2133,7 +2693,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10612639499777084126
+          5849651065413553680
         ]
       ], 
       "reviewed-by-human": false
@@ -2142,7 +2702,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6035759061702062244
+          4619759825939595617
         ]
       ], 
       "reviewed-by-human": false
@@ -2151,7 +2711,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8500043106468453797
+          14032862889795240664
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH[100x100]-unevenCorners_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15286938614901311801
         ]
       ], 
       "reviewed-by-human": false
@@ -2160,7 +2729,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17805090981812894527
+          12432048901204294234
         ]
       ], 
       "reviewed-by-human": true
@@ -2169,7 +2738,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17800001274907447804
+          1470201827989444658
         ]
       ], 
       "reviewed-by-human": true
@@ -2178,7 +2747,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18332742573339604858
+          1366655946391804971
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurs_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9323354551120439554
         ]
       ], 
       "reviewed-by-human": true
@@ -2229,19 +2807,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5541967782360980927
+          5083910756480608901
         ]
       ], 
       "bugs": [
-        1759
+        1578
       ], 
       "reviewed-by-human": false
     }, 
+    "canvas-state_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15865471464929251478
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "chrome_gradtext1_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          7950166054919619394
         ]
       ], 
       "bugs": [
@@ -2253,7 +2840,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          7950166054919619394
         ]
       ], 
       "bugs": [
@@ -2265,19 +2852,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          7950166054919619394
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "chrome_gradtext1_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1073030908540204562
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "chrome_gradtext2_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13774733025575034199
+          930789055331505026
         ]
       ], 
       "bugs": [
@@ -2289,7 +2882,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13774733025575034199
+          930789055331505026
         ]
       ], 
       "bugs": [
@@ -2301,55 +2894,63 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3313052130644407339
+          15512263596264641903
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "chrome_gradtext2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6034723123247957533
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "circles_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6008092610982260089
+          3041043330243503378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "circles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14991965560443449693
+          9296850955490059248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "circles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17106055778626858542
+          2111070892848864737
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "circles_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          27321413692615312
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "circular-clips_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7045926575348655010
+          5152108745492225309
         ]
       ], 
       "bugs": [
@@ -2361,7 +2962,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7045926575348655010
+          5152108745492225309
         ]
       ], 
       "bugs": [
@@ -2377,7 +2978,19 @@
         ]
       ], 
       "bugs": [
-        1759
+        1578
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "circular-clips_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8273977756448800482
+        ]
+      ], 
+      "bugs": [
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -2388,10 +3001,7 @@
           6740406662310759992
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "clamped_gradients_8888.png": {
       "allowed-digests": [
@@ -2400,22 +3010,26 @@
           12600235552582834170
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "clamped_gradients_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15658888448911378390
+          4165161027652562674
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "clamped_gradients_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4165161027652562674
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "clipped-bitmap-shaders-clamp-hq_565.png": {
       "allowed-digests": [
@@ -2424,6 +3038,9 @@
           5543970311616574408
         ]
       ], 
+      "bugs": [
+        1759
+      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-clamp-hq_8888.png": {
@@ -2433,13 +3050,25 @@
           9243927175489158803
         ]
       ], 
+      "bugs": [
+        1759
+      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-clamp-hq_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5000282312660607550
+          204218343358397709
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          204218343358397709
         ]
       ], 
       "reviewed-by-human": true
@@ -2476,7 +3105,19 @@
         ]
       ], 
       "bugs": [
-        1759
+        1578
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "clipped-bitmap-shaders-clamp_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "bugs": [
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -2487,6 +3128,9 @@
           14000830941634575767
         ]
       ], 
+      "bugs": [
+        1759
+      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-mirror-hq_8888.png": {
@@ -2496,13 +3140,25 @@
           14412729226029504152
         ]
       ], 
+      "bugs": [
+        1759
+      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-mirror-hq_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18066226042033064966
+          8267457060238409676
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8267457060238409676
         ]
       ], 
       "reviewed-by-human": true
@@ -2539,7 +3195,19 @@
         ]
       ], 
       "bugs": [
-        1759
+        1578
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "clipped-bitmap-shaders-mirror_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "bugs": [
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -2550,6 +3218,9 @@
           5937007347321497195
         ]
       ], 
+      "bugs": [
+        1759
+      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-tile-hq_8888.png": {
@@ -2559,13 +3230,25 @@
           6655127558305687514
         ]
       ], 
+      "bugs": [
+        1759
+      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-tile-hq_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17436695901683300479
+          2334895375062438086
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2334895375062438086
         ]
       ], 
       "reviewed-by-human": true
@@ -2602,7 +3285,19 @@
         ]
       ], 
       "bugs": [
-        1759
+        1578
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "clipped-bitmap-shaders-tile_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "bugs": [
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -2634,13 +3329,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10318279557324425152
+          2433752872333325525
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "clippedcubic_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8568852401967913278
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "cmykjpeg_565.png": {
       "allowed-digests": [
@@ -2673,10 +3374,16 @@
           9927483517871541702
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "cmykjpeg_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9927483517871541702
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "colorfilterimagefilter_565.png": {
       "allowed-digests": [
@@ -2706,13 +3413,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          192532786620859689
+          2714283339000823472
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "colorfilterimagefilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2714283339000823472
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "colormatrix_565.png": {
       "allowed-digests": [
@@ -2742,19 +3455,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1575688773869978322
+          632768445634214292
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "colormatrix_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          632768445634214292
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "colortype_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7789211976036245847
+          16101291896048576683
         ]
       ], 
       "reviewed-by-human": false
@@ -2763,7 +3482,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12063547141229638542
+          6958362917585628191
         ]
       ], 
       "reviewed-by-human": false
@@ -2772,7 +3491,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15432189428597356877
+          13430579085704011533
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13430579085704011533
         ]
       ], 
       "reviewed-by-human": true
@@ -2808,10 +3536,17 @@
           7558229948134696044
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "complexclip2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15835598503521329982
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip2_path_aa_565.png": {
       "allowed-digests": [
@@ -2820,7 +3555,10 @@
           16086429144316222800
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "complexclip2_path_aa_8888.png": {
       "allowed-digests": [
@@ -2829,17 +3567,29 @@
           12832097210600987517
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "complexclip2_path_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          626377265510811395
+          6538569194874273793
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "complexclip2_path_aa_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15417208658917013634
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "complexclip2_path_bw_565.png": {
       "allowed-digests": [
         [
@@ -2847,7 +3597,10 @@
           13497374237280200272
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "complexclip2_path_bw_8888.png": {
       "allowed-digests": [
@@ -2856,19 +3609,28 @@
           13907447324398926215
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "complexclip2_path_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6767202152973974411
+          7064746384958261694
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "complexclip2_path_bw_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14499546166220364975
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "complexclip2_rect_aa_565.png": {
       "allowed-digests": [
@@ -2898,11 +3660,20 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16628817470554933537
+          1400000972609731233
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "complexclip2_rect_aa_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6866538074859371289
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "complexclip2_rrect_aa_565.png": {
       "allowed-digests": [
         [
@@ -2925,7 +3696,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12795866211978733736
+          12606971060652066622
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1249017088009421345
         ]
       ], 
       "reviewed-by-human": true
@@ -2957,11 +3737,20 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "complexclip2_rrect_bw_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7550047750900987875
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "complexclip_aa_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2183310436696200447
+          4104797309315770800
         ]
       ], 
       "reviewed-by-human": true
@@ -2970,7 +3759,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          744025704131278337
+          6544536706877310514
         ]
       ], 
       "reviewed-by-human": true
@@ -2979,7 +3768,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12123725839294251145
+          14513438909331829416
         ]
       ], 
       "reviewed-by-human": true
@@ -2988,7 +3777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3659943080425900329
+          8097997023778848191
         ]
       ], 
       "reviewed-by-human": true
@@ -2997,7 +3786,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1205455874446983865
+          5836493341538608113
         ]
       ], 
       "reviewed-by-human": true
@@ -3006,7 +3795,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6305857535625023602
+          9084880565837755264
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip_aa_layer_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17768595575576867230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip_aa_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18260984331770722196
         ]
       ], 
       "reviewed-by-human": true
@@ -3015,7 +3822,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12748157450884875422
+          4165425675033352640
         ]
       ], 
       "reviewed-by-human": true
@@ -3024,7 +3831,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12349332232493061534
+          10152516748782571739
         ]
       ], 
       "reviewed-by-human": true
@@ -3033,7 +3840,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15377182906618145948
+          14914601045858845148
         ]
       ], 
       "reviewed-by-human": true
@@ -3042,7 +3849,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2492514386480839663
+          8180502121217066191
         ]
       ], 
       "reviewed-by-human": true
@@ -3051,7 +3858,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2975399947010553387
+          16993829969091028380
         ]
       ], 
       "reviewed-by-human": true
@@ -3060,7 +3867,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12578511015260635257
+          1059511820934474761
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip_bw_layer_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15952923770779117335
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip_bw_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14110404372599098336
         ]
       ], 
       "reviewed-by-human": true
@@ -3101,6 +3926,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "composeshader_alpha_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13415066704472475041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "composeshader_alpha_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13415066704472475041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "composeshader_gpu.png": {
       "allowed-digests": [
         [
@@ -3108,40 +3951,69 @@
           13476719363156020502
         ]
       ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13476719363156020502
+        ]
+      ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "convex_poly_clip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17917330964671139160
+          4792118895672570848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5601850589005836986
+          11285887424651164487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3931972752458035902
+          9807676647004956667
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "convex_poly_clip_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3010580829471563399
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13562837227301896730
+          13463378520577789165
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convex_poly_effect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9497742047085032268
         ]
       ], 
       "reviewed-by-human": true
@@ -3150,35 +4022,39 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12930829906409283378
+          18327995834040812041
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "convexpaths_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5590017600958012619
+          457069184203133078
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "convexpaths_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10865343678259724198
+          8826348418330119107
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "convexpaths_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9367514703795196166
+        ]
+      ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
     "copyTo4444_565.png": {
       "allowed-digests": [
         [
@@ -3211,7 +4087,19 @@
         ]
       ], 
       "bugs": [
-        1759
+        1578
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "copyTo4444_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13512184095617016052
+        ]
+      ], 
+      "bugs": [
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -3219,7 +4107,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13521200955406107775
+          15418783980877386199
         ]
       ], 
       "reviewed-by-human": true
@@ -3228,7 +4116,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17912401236231679127
+          7882161322447216882
         ]
       ], 
       "reviewed-by-human": true
@@ -3237,7 +4125,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8341536688885218293
+          4204097215809673028
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cubicclosepath_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7751217857540747
         ]
       ], 
       "reviewed-by-human": true
@@ -3246,7 +4143,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6583472814997240235
+          3184062263576953667
         ]
       ], 
       "reviewed-by-human": true
@@ -3255,7 +4152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058335517377211817
+          713799816796517938
         ]
       ], 
       "reviewed-by-human": true
@@ -3264,7 +4161,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11731651872638524201
+          13367306876695640597
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cubicpath_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18324282461018392405
         ]
       ], 
       "reviewed-by-human": true
@@ -3273,7 +4179,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1243485597747942942
+          14579960821593575197
         ]
       ], 
       "bugs": [
@@ -3285,7 +4191,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          561323664416995153
+          17019125613404625792
         ]
       ], 
       "bugs": [
@@ -3297,16 +4203,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10530014763886697529
+          13633210306002531372
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "dashcubics_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10420851514862858878
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "dashing2_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7522047842497784488
+          2494610485041198535
         ]
       ], 
       "bugs": [
@@ -3318,7 +4233,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16976334130763507258
+          5568370216546802477
         ]
       ], 
       "bugs": [
@@ -3330,11 +4245,20 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          751221660731865592
+          491154211623518706
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
+    "dashing2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12021553253042702121
         ]
       ], 
       "bugs": [
-        1759
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -3342,7 +4266,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5458443768353447519
+          12022711034501498873
         ]
       ], 
       "bugs": [
@@ -3354,7 +4278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2000525185460569669
+          9992031980990536415
         ]
       ], 
       "bugs": [
@@ -3366,19 +4290,26 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1456612750003227022
+          11276789762492958264
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "dashing3_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9484069846755377869
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "dashing4_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3905274096451946067
+          14433773091096403168
         ]
       ], 
       "reviewed-by-human": true
@@ -3387,7 +4318,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1394068287232006716
+          10873004693785991483
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          842505089271483404
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8318805250773634136
         ]
       ], 
       "reviewed-by-human": true
@@ -3396,7 +4345,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2587070015488181148
+          14912539765453208522
         ]
       ], 
       "bugs": [
@@ -3420,19 +4369,26 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18015592834088027197
+          4092537744584410156
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "dashing_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5485153920280341540
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "degeneratesegments_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4578086267105259029
+          11475660560101599954
         ]
       ], 
       "reviewed-by-human": true
@@ -3441,7 +4397,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1521449590373842396
+          7311723676588845146
         ]
       ], 
       "reviewed-by-human": true
@@ -3450,7 +4406,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16978708541322119393
+          12602988813237402949
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "degeneratesegments_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8320360396414647822
         ]
       ], 
       "reviewed-by-human": true
@@ -3459,7 +4424,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5004276491084267368
+          16442079060610240238
         ]
       ], 
       "reviewed-by-human": true
@@ -3468,7 +4433,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7746803903450904418
+          8850017817310905002
         ]
       ], 
       "reviewed-by-human": true
@@ -3477,16 +4442,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1696674976993092902
+          11635187478196931850
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "discard_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11635187478196931850
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "displacement_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10557537838778749160
+          4057230872151110302
         ]
       ], 
       "reviewed-by-human": true
@@ -3495,7 +4469,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7089896533323038526
+          9482070623821433904
         ]
       ], 
       "reviewed-by-human": true
@@ -3504,52 +4478,65 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12394438758744026163
+          1170916231930532316
         ]
       ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "displacement_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1170916231930532316
+        ]
+      ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "distantclip_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -3558,7 +4545,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -3567,7 +4554,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9008293750211777201
+          2053143241305253519
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13558497883564503203
         ]
       ], 
       "reviewed-by-human": true
@@ -3576,67 +4572,70 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16704802669726334024
+          1365476015121733881
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4085557449317823255
+        ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          992494534717898142
+          2053143241305253519
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13558497883564503203
         ]
       ], 
       "reviewed-by-human": true
@@ -3645,43 +4644,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17775297231868448514
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12804472649182277577
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3849621410806513723
+          12650731363086188245
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7320890964320867858
+        ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -3690,7 +4689,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -3699,7 +4698,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4191803426779135801
+          13504880513739592005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16903774499113610668
         ]
       ], 
       "reviewed-by-human": true
@@ -3708,67 +4716,70 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3676645757082565261
+          6399690160433481902
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8921034639234342908
+        ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16700399834273149128
+          13504880513739592005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16903774499113610668
         ]
       ], 
       "reviewed-by-human": true
@@ -3777,43 +4788,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          6055955940623478607
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          11797865288006977816
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          142674759365826172
+          11185694799637075711
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18352104832144523134
+        ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -3822,7 +4833,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
         ]
       ], 
       "reviewed-by-human": true
@@ -3831,7 +4842,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12649869831822432987
+          14579864208673224889
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15078056460862308465
         ]
       ], 
       "reviewed-by-human": true
@@ -3840,7 +4860,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          4886211991926050486
         ]
       ], 
       "reviewed-by-human": true
@@ -3849,7 +4869,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          8737545656412765906
         ]
       ], 
       "reviewed-by-human": true
@@ -3858,7 +4878,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4685776213094226352
+          14057740961401979106
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6129142780121532863
         ]
       ], 
       "reviewed-by-human": true
@@ -3867,7 +4896,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -3876,7 +4905,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
         ]
       ], 
       "reviewed-by-human": true
@@ -3885,7 +4914,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13141085848085289030
+          10604640727019939807
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8392931363281798442
         ]
       ], 
       "reviewed-by-human": true
@@ -3894,7 +4932,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15469192468104182267
+          4707049264800437834
         ]
       ], 
       "reviewed-by-human": true
@@ -3903,7 +4941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9482106153945169929
+          3175389971476411688
         ]
       ], 
       "reviewed-by-human": true
@@ -3912,7 +4950,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          326696583887893469
+          365721829706691205
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2473941895467574423
         ]
       ], 
       "reviewed-by-human": true
@@ -3921,43 +4968,45 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          11292884853289362433
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15096840641759877301
+          16912290287677763264
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16772618235934374845
+          15394406070971249703
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14484858848664747251
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5134999156369384783
+          15797039913993285826
         ]
       ], 
       "reviewed-by-human": true
@@ -3966,7 +5015,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12521309603120134056
+          17497164562330387900
         ]
       ], 
       "reviewed-by-human": true
@@ -3975,7 +5024,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8141288215353462246
+          12686426978094913156
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawlooper_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6490420606640500316
         ]
       ], 
       "reviewed-by-human": true
@@ -3984,7 +5042,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17176620593335973597
+          273445276579232833
         ]
       ], 
       "reviewed-by-human": true
@@ -3993,7 +5051,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13663064994494293289
+          13357226331142394630
         ]
       ], 
       "reviewed-by-human": true
@@ -4002,7 +5060,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6983309335249454236
+          3819664262710657017
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dropshadowimagefilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          367215542131912432
         ]
       ], 
       "reviewed-by-human": true
@@ -4011,7 +5078,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7282537335075785928
+          3740162382031499255
         ]
       ], 
       "reviewed-by-human": true
@@ -4020,7 +5087,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8863849031372460120
+          7505650564332324157
         ]
       ], 
       "reviewed-by-human": true
@@ -4029,7 +5096,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3779095071531514150
+          12767183233496534484
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drrect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10190284423574240066
         ]
       ], 
       "reviewed-by-human": true
@@ -4038,7 +5114,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18094470146972105480
+          1802138798652377585
         ]
       ], 
       "reviewed-by-human": true
@@ -4047,7 +5123,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16729138449439522348
+          588269449619860245
         ]
       ], 
       "reviewed-by-human": true
@@ -4056,7 +5132,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8158239880603207616
+          13516932575826030439
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "emptypath_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          649418728571953564
         ]
       ], 
       "reviewed-by-human": true
@@ -4079,6 +5164,15 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10396043285211938891
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "etc1bitmap_ktx_565.png": {
       "allowed-digests": [
         [
@@ -4097,6 +5191,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_ktx_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10396043285211938891
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "etc1bitmap_npot_565.png": {
       "allowed-digests": [
         [
@@ -4115,6 +5236,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_npot_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "etc1bitmap_pkm_565.png": {
       "allowed-digests": [
         [
@@ -4133,11 +5272,65 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_pkm_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11559795738519917215
+          10931473040653078858
         ]
       ], 
       "reviewed-by-human": true
@@ -4146,7 +5339,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11559795738519917215
+          10931473040653078858
         ]
       ], 
       "reviewed-by-human": true
@@ -4155,7 +5348,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11559795738519917215
+          10931473040653078858
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10931473040653078858
         ]
       ], 
       "reviewed-by-human": true
@@ -4191,10 +5393,16 @@
           11150486540244810089
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "factory_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11150486540244810089
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "fatpathfill_565.png": {
       "allowed-digests": [
@@ -4224,19 +5432,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2028184591354531695
+          4289371422806910081
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "fatpathfill_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          824079147458833816
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "filltypes_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6394623980536394421
+          1160039999451806268
         ]
       ], 
       "bugs": [
@@ -4248,7 +5462,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4586322702989781686
+          9755437692677243946
         ]
       ], 
       "bugs": [
@@ -4260,19 +5474,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17693182030144018869
+          18124989730286911389
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "filltypes_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11329292713172925792
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "filltypespersp_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13448151295100783239
+          14894017545918091807
         ]
       ], 
       "bugs": [
@@ -4284,19 +5504,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1122618131815112502
+          7410424049029296878
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filltypespersp_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8397994591127819291
+          735386539415263401
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypespersp_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6951768338748558570
         ]
       ], 
       "reviewed-by-human": true
@@ -4305,7 +5531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7419227591265311221
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -4314,7 +5540,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9941389284961210315
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -4323,7 +5549,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13872974075155174385
+          6416906456074531975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_192_192_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15346563228391012421
         ]
       ], 
       "reviewed-by-human": true
@@ -4332,7 +5567,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4712618105826416872
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -4341,7 +5576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6814786601958107546
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -4350,7 +5585,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13175000843516560645
+          14718953584331679586
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          709138701467955192
         ]
       ], 
       "reviewed-by-human": true
@@ -4359,7 +5603,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11309219541124250528
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -4368,7 +5612,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8042312968331390097
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -4377,7 +5621,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12621944278316839160
+          11715858707992144255
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_32_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15553154700984748202
         ]
       ], 
       "reviewed-by-human": true
@@ -4386,7 +5639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17324002053051694427
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -4395,7 +5648,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10616193688896439855
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -4404,7 +5657,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16892871506538567763
+          10207019146922177135
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_8_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15733323208124391995
         ]
       ], 
       "reviewed-by-human": true
@@ -4413,7 +5675,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10302533496874247276
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -4422,7 +5684,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12569931102745160299
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -4431,7 +5693,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3197389257186652855
+          14459233869935150094
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_4_4_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9868215782064868064
         ]
       ], 
       "reviewed-by-human": true
@@ -4440,7 +5711,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          842153490277803410
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -4449,7 +5720,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577999994704956939
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -4458,7 +5729,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9016131185709747295
+          10929478370694983072
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_128.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11834676469477761758
         ]
       ], 
       "reviewed-by-human": true
@@ -4467,7 +5747,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17152997950184504727
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -4476,7 +5756,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11428391327691184765
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -4485,7 +5765,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3293710486546961723
+          13015175397476464878
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_16.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7356613433947850556
         ]
       ], 
       "reviewed-by-human": true
@@ -4494,7 +5783,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4139187976413040197
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -4503,7 +5792,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14073034095251842923
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -4512,7 +5801,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3264292480595545579
+          10203369636767887124
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_256.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7545556399199546808
         ]
       ], 
       "reviewed-by-human": true
@@ -4521,7 +5819,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17106863847823042087
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -4530,7 +5828,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12215969181637652211
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -4539,7 +5837,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16029411561224473754
+          3832837277343463422
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_32.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17486944558466625092
         ]
       ], 
       "reviewed-by-human": true
@@ -4548,7 +5855,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8457226704515835046
+          6683720920985855313
         ]
       ], 
       "reviewed-by-human": true
@@ -4557,7 +5864,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13673721686942765185
+          1125681780471010403
         ]
       ], 
       "reviewed-by-human": true
@@ -4566,7 +5873,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3518436430982597449
+          2281254577128678728
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18309462666339717466
         ]
       ], 
       "reviewed-by-human": true
@@ -4575,7 +5891,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3068653512092670589
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -4584,7 +5900,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15170271034615721666
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -4593,7 +5909,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15252086719294314503
+          17851942342592137697
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_64.png_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14542855006567772669
         ]
       ], 
       "reviewed-by-human": true
@@ -4602,7 +5927,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11543071368100420439
+          33986293470780328
         ]
       ], 
       "reviewed-by-human": true
@@ -4611,7 +5936,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13979895877101196974
+          18157626535966948982
         ]
       ], 
       "reviewed-by-human": true
@@ -4620,7 +5945,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12174104284041385825
+          2496644378646011138
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7997901555644379668
         ]
       ], 
       "reviewed-by-human": true
@@ -4629,7 +5963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10562352406325167130
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -4638,7 +5972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4740040018036044870
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -4647,7 +5981,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14844459319468499053
+          14945838412908111196
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_3.00pt_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13606662514638710665
         ]
       ], 
       "reviewed-by-human": true
@@ -4656,7 +5999,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2358351893182060187
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -4665,7 +6008,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17870285622555231718
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
@@ -4674,97 +6017,155 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          434039534086427901
+          1564669317661983291
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "filterbitmap_text_7.00pt_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11645610712534679057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2286802257293267683
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4050292462410603306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          994935463198632465
+          15147463239787661010
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "fontcache_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15147463239787661010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          17276962213970077366
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          8694218356938189525
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1857288326388942863
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "fontmgr_iter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1857288326388942863
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          4335659971728708662
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5297915207580543309
+        ]
       ], 
+      "ignore-failure": false, 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13697197938526917158
+          17710251147672086087
         ]
       ], 
       "reviewed-by-human": true
@@ -4773,7 +6174,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9665018536861377984
+          8220509209288028295
         ]
       ], 
       "reviewed-by-human": true
@@ -4782,16 +6183,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10979683921873521339
+          13061307990914479876
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "fontscaler_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5782373087524107299
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2500355683115767624
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954882728248735643
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954882728248735643
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11098600005518612422
+          11716334334721910796
         ]
       ], 
       "reviewed-by-human": true
@@ -4800,7 +6246,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12924368150056635888
+          5693920054563327483
         ]
       ], 
       "reviewed-by-human": true
@@ -4809,16 +6255,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9988534402643805553
+          4779790303751499909
         ]
       ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "gammatext_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11415732188148058124
+        ]
+      ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "getpostextpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2033602119516310281
+          4104502497653829415
         ]
       ], 
       "reviewed-by-human": true
@@ -4827,7 +6284,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8346234615044725182
+          9568693510532495016
         ]
       ], 
       "reviewed-by-human": true
@@ -4836,7 +6293,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1245896931972085138
+          18352804101744384563
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "getpostextpath_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6491595006082478981
         ]
       ], 
       "reviewed-by-human": true
@@ -4869,13 +6335,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8112152499985052384
+          1104566393623360633
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1104566393623360633
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_clamp_bilerp_scale_565.png": {
       "allowed-digests": [
@@ -4905,13 +6377,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8430366169989348557
+          8129199009785017829
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_clamp_bilerp_scale_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8129199009785017829
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_clamp_point_rotate_565.png": {
       "allowed-digests": [
@@ -4941,13 +6419,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17664227249162604428
+          11732357288176540699
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_clamp_point_rotate_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11732357288176540699
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_clamp_point_scale_565.png": {
       "allowed-digests": [
@@ -4980,10 +6464,16 @@
           9837143541713078189
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_clamp_point_scale_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9837143541713078189
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_mirror_bilerp_rotate_565.png": {
       "allowed-digests": [
@@ -5013,13 +6503,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18436669324822800859
+          8310471451250889117
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8310471451250889117
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_mirror_bilerp_scale_565.png": {
       "allowed-digests": [
@@ -5049,13 +6545,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9662671494674386025
+          15651344781609644368
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_mirror_bilerp_scale_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15651344781609644368
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_mirror_point_rotate_565.png": {
       "allowed-digests": [
@@ -5085,13 +6587,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13311283151063713989
+          2425376415405090974
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_mirror_point_rotate_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2425376415405090974
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_mirror_point_scale_565.png": {
       "allowed-digests": [
@@ -5121,13 +6629,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13431550740599981254
+          18105452151182268887
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_mirror_point_scale_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105452151182268887
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_repeat_bilerp_rotate_565.png": {
       "allowed-digests": [
@@ -5157,49 +6671,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16302744549495549154
+          1142119770139642274
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1142119770139642274
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_repeat_bilerp_scale_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8227734820754620843
+          3467547098277083272
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "giantbitmap_repeat_bilerp_scale_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11021884726574795651
+          17571397130661778041
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "giantbitmap_repeat_bilerp_scale_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4906927396615969438
+          5396069192065881677
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_repeat_bilerp_scale_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5396069192065881677
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_repeat_point_rotate_565.png": {
       "allowed-digests": [
@@ -5208,10 +6728,7 @@
           9093746103412643649
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "giantbitmap_repeat_point_rotate_8888.png": {
       "allowed-digests": [
@@ -5220,22 +6737,25 @@
           9093746103412643649
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "giantbitmap_repeat_point_rotate_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13294138182223094091
+          14207927019435362510
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_repeat_point_rotate_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14207927019435362510
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "giantbitmap_repeat_point_scale_565.png": {
       "allowed-digests": [
@@ -5265,11 +6785,305 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1623953817113568190
+          14547059667322106211
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "giantbitmap_repeat_point_scale_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14547059667322106211
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17133241123252992386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17133241123252992386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2740474667902760224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13062572212227089670
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2740474667902760224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13062572212227089670
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18181809164582745765
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10646101256712397679
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5216581726550480243
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14988814117683836650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16062483234765207871
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3020788879261074646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2740474667902760224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13062572212227089670
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863085462100832326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14621205964232291210
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          738609491282019773
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271247215169625597
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2739908385541953120
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16879059920514854608
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -5301,11 +7115,20 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4735033599846615424
+          6515341671020089010
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_dirty_laundry_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6515341671020089010
         ]
       ], 
       "bugs": [
-        1759
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -5337,19 +7160,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10145849591466155435
+          10295001037965641703
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "gradient_matrix_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9412382014453992174
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "gradients_2pt_conical_edge_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14049649032069259181
+          11073979394505631674
         ]
       ], 
       "reviewed-by-human": false
@@ -5358,7 +7187,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8533660654825840563
+          2886762409915472022
         ]
       ], 
       "reviewed-by-human": false
@@ -5367,7 +7196,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8565726929159118677
+          8697473946772464652
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8697473946772464652
         ]
       ], 
       "reviewed-by-human": false
@@ -5394,7 +7232,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5119195493073943472
+          6477843407979522548
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6477843407979522548
         ]
       ], 
       "reviewed-by-human": false
@@ -5421,7 +7268,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8194516921738963656
+          14407511764193782824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14407511764193782824
         ]
       ], 
       "reviewed-by-human": false
@@ -5433,6 +7289,7 @@
           12097193819749785352
         ]
       ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "gradients_8888.png": {
@@ -5442,6 +7299,7 @@
           15403609442106846169
         ]
       ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "gradients_degenerate_2pt_565.png": {
@@ -5472,21 +7330,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13313927878342351507
+          2596123370770096567
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "gradients_degenerate_2pt_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2596123370770096567
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "gradients_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6892258587104376755
+          6344306350503519124
         ]
       ], 
+      "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
     "gradients_local_perspective_565.png": {
@@ -5496,6 +7361,7 @@
           3955747071082596728
         ]
       ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "gradients_local_perspective_8888.png": {
@@ -5505,13 +7371,24 @@
           10472560090813482435
         ]
       ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "gradients_local_perspective_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16262330141361316575
+          6153702525281427462
+        ]
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6153702525281427462
         ]
       ], 
       "ignore-failure": true, 
@@ -5539,11 +7416,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9465514724720153003
+          5929649840971741982
         ]
       ], 
       "reviewed-by-human": false
     }, 
+    "gradients_many_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5714964798679963713
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradients_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6344306350503519124
+        ]
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
+    }, 
     "gradients_no_texture_565.png": {
       "allowed-digests": [
         [
@@ -5566,16 +7462,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16087518691782755600
+          13124619514736243025
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "gradients_no_texture_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13124619514736243025
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradients_view_perspective_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -5584,7 +7489,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1082062268335165982
+          4762618020579508996
         ]
       ], 
       "reviewed-by-human": true
@@ -5593,7 +7498,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16663486379543086186
+          10491688216569008375
+        ]
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16559640938310025794
         ]
       ], 
       "ignore-failure": true, 
@@ -5603,7 +7518,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297095911910169239
+          8988444324654919932
         ]
       ], 
       "reviewed-by-human": true
@@ -5612,7 +7527,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5771478138095675386
+          8157217091633419434
         ]
       ], 
       "reviewed-by-human": true
@@ -5621,7 +7536,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16088397879491903202
+          150610904007713741
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradtext_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          150610904007713741
         ]
       ], 
       "reviewed-by-human": true
@@ -5630,13 +7554,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9293293797458777202
+          3746404902639900755
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "hairlines_8888.png": {
       "allowed-digests": [
@@ -5644,26 +7564,31 @@
           "bitmap-64bitMD5", 
           13269473576016756464
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "hairlines_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13785031436850319619
+          15771786769254973604
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "hairlines_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10833370454122692930
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "hairmodes_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13753109946556116551
+          1085590255436271494
         ]
       ], 
       "bugs": [
@@ -5675,7 +7600,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9057348143868599843
+          1802514640949456155
         ]
       ], 
       "bugs": [
@@ -5687,19 +7612,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17279526082933136574
+          974999507980407411
+        ]
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14247877693672647204
         ]
       ], 
       "bugs": [
-        1759
+        1655
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9550811290357199511
+          11711016279383188197
         ]
       ], 
       "bugs": [
@@ -5711,7 +7647,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15448966239818316608
+          14807718233642576408
         ]
       ], 
       "bugs": [
@@ -5723,19 +7659,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16781705300910493680
+          3542250264918452791
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "hittestpath_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3586545995007079598
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "image-surface_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17630890424038541282
+          16771938741318176654
         ]
       ], 
       "reviewed-by-human": true
@@ -5744,7 +7686,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10851904927850256296
+          15729042135723497470
         ]
       ], 
       "reviewed-by-human": true
@@ -5753,9 +7695,20 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9401026423085178591
+          18048497206906346281
         ]
       ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "image-surface_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5621345534884087809
+        ]
+      ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "imagealphathreshold_565.png": {
@@ -5785,11 +7738,56 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imagealphathreshold_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16743719107131210314
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          741134624395776214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          357284903731074601
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10462784937398826625
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10462784937398826625
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3869730655096851160
+          13620335786972140736
         ]
       ], 
       "reviewed-by-human": true
@@ -5798,7 +7796,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          788899247822925790
+          17030111096598942390
         ]
       ], 
       "reviewed-by-human": true
@@ -5807,20 +7805,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5976634674759312143
+          1105584058315288349
         ]
       ], 
-      "bugs": [
-        2085
-      ], 
-      "ignore-failure": true, 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5781271367332766897
+          1922338586017046100
         ]
       ], 
       "reviewed-by-human": true
@@ -5829,7 +7824,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13746237675706248024
+          3693078186234250164
         ]
       ], 
       "reviewed-by-human": true
@@ -5838,16 +7833,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702998954585031011
+          11518661682572191380
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "imageblur_large_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13388867466611225896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10285237549190759962
+        ]
+      ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
     "imageblurtiled_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16654054210158593753
+          14143901564679014792
         ]
       ], 
       "reviewed-by-human": true
@@ -5856,7 +7870,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2843556688273725953
+          17186499223783647141
         ]
       ], 
       "reviewed-by-human": true
@@ -5865,7 +7879,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10272013979024454230
+          9359799980072967472
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblurtiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9359799980072967472
         ]
       ], 
       "reviewed-by-human": true
@@ -5874,7 +7897,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532729496698970871
+          9334915207072042375
         ]
       ], 
       "reviewed-by-human": true
@@ -5883,7 +7906,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7641510194452485262
+          4262113639047937913
         ]
       ], 
       "reviewed-by-human": true
@@ -5892,36 +7915,54 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15637318917107725155
+          13519884549264043430
         ]
       ], 
-      "bugs": [
-        2005
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersbase_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4393655961616093182
+        ]
       ], 
-      "ignore-failure": true, 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "imagefiltersclipped_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14771974755728278127
+          9643897842146508458
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14537515405997069608
+          14154076457851775362
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8665802903094730049
+          6187141994062797732
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersclipped_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1265386704127173584
         ]
       ]
     }, 
@@ -5929,7 +7970,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16480020330796061578
+          16816155573392653040
         ]
       ], 
       "reviewed-by-human": true
@@ -5938,7 +7979,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4131813877373753759
+          15621659488709502951
         ]
       ], 
       "reviewed-by-human": true
@@ -5947,7 +7988,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6114011311493833332
+          13481672823921868407
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefilterscropped_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5523411567262382106
         ]
       ], 
       "reviewed-by-human": true
@@ -5956,7 +8006,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12620063976225784909
+          14400660572715212845
         ]
       ], 
       "reviewed-by-human": true
@@ -5965,7 +8015,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          204467962017973076
+          12820728063175372793
         ]
       ], 
       "reviewed-by-human": true
@@ -5974,40 +8024,62 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1103995645853022148
+          2586660090509305197
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "imagefiltersgraph_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2586660090509305197
+        ]
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
+    }, 
     "imagefiltersscaled_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17667280750482645242
+          88044436581289267
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersscaled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12997200926589207952
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6327054889332906721
+          4458594706234736506
         ]
       ], 
       "reviewed-by-human": true
@@ -6016,7 +8088,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11878406934177300231
+          7881653068493848399
         ]
       ], 
       "reviewed-by-human": true
@@ -6025,7 +8097,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10399323179213606951
+          12683787554719393302
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagemagnifier_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18111354910595959932
         ]
       ], 
       "reviewed-by-human": true
@@ -6034,7 +8115,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11537830680807011411
+          16955463079319608247
         ]
       ], 
       "reviewed-by-human": false
@@ -6043,7 +8124,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2840733308476616973
+          5803572190214013609
         ]
       ], 
       "reviewed-by-human": false
@@ -6052,7 +8133,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2840733308476616973
+          5803572190214013609
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageresizetiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5803572190214013609
         ]
       ], 
       "reviewed-by-human": false
@@ -6061,7 +8151,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11477547669639384796
+          15651773991982238342
         ]
       ], 
       "reviewed-by-human": true
@@ -6070,7 +8160,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11751433989801294344
+          1266355932999225698
         ]
       ], 
       "reviewed-by-human": true
@@ -6079,7 +8169,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900375946366690268
+          1166998594929450624
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "internal_links_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1166998594929450624
         ]
       ], 
       "reviewed-by-human": true
@@ -6088,7 +8187,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12462644636324896185
+          18373794772311086000
         ]
       ], 
       "reviewed-by-human": true
@@ -6097,7 +8196,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6825022448693098908
+          6619571412969335764
         ]
       ], 
       "reviewed-by-human": true
@@ -6106,7 +8205,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6283227002281509479
+          11579271860209080071
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "inverse_paths_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5746914795204272829
         ]
       ], 
       "reviewed-by-human": true
@@ -6115,7 +8223,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6122935913437439554
+          18027956661574207189
         ]
       ], 
       "reviewed-by-human": true
@@ -6124,7 +8232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511393143767092759
+          9235059342087793513
         ]
       ], 
       "reviewed-by-human": true
@@ -6133,7 +8241,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511393143767092759
+          9235059342087793513
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lcdtext_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9235059342087793513
         ]
       ], 
       "reviewed-by-human": true
@@ -6142,7 +8259,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10818286910555371914
+          12271636760963423766
         ]
       ], 
       "bugs": [
@@ -6154,7 +8271,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4328896907702672721
+          11952378473714520027
         ]
       ], 
       "bugs": [
@@ -6166,19 +8283,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14139714820651029117
+          1889599541186254424
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lerpmode_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7255273740487203408
         ]
       ], 
       "bugs": [
-        1759
+        1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6728484050681732905
+          5778987087064312358
         ]
       ], 
       "reviewed-by-human": true
@@ -6187,7 +8313,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3122543961009401649
+          10848355732603050567
         ]
       ], 
       "reviewed-by-human": true
@@ -6196,7 +8322,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598689909109043043
+          15863263903362759847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lighting_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15863263903362759847
         ]
       ], 
       "reviewed-by-human": true
@@ -6223,7 +8358,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6114476395450060705
+          6703252236476240963
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lightingcolorfilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6703252236476240963
         ]
       ], 
       "reviewed-by-human": false
@@ -6232,7 +8376,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564246142489134519
+          9075523320529578103
         ]
       ], 
       "reviewed-by-human": true
@@ -6241,7 +8385,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1370520776657521517
+          4131799565799962704
         ]
       ], 
       "reviewed-by-human": true
@@ -6250,7 +8394,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7446182077244886426
+          13362151343000560853
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lineclosepath_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          179903152301013150
         ]
       ], 
       "reviewed-by-human": true
@@ -6259,7 +8412,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981696952434326875
+          4095489997625677813
         ]
       ], 
       "reviewed-by-human": true
@@ -6268,7 +8421,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15238792371190456534
+          17687576741285937089
         ]
       ], 
       "reviewed-by-human": true
@@ -6277,7 +8430,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10096967694534333921
+          16350254171643964347
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "linepath_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15500554310857216494
         ]
       ], 
       "reviewed-by-human": true
@@ -6286,7 +8448,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5049467161770100346
+          15721345070217154235
         ]
       ]
     }, 
@@ -6294,7 +8456,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374476823825156605
+          3651441664185012389
         ]
       ]
     }, 
@@ -6302,39 +8464,57 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3056389996783374736
+          14694204158057728253
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lumafilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9645881182143954138
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumamode_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8495874039699811736
+          4885021002503040739
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "lumamode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15450664592066744642
+          15352335719021523600
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
+    }, 
+    "lumamode_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15725917579141915080
+        ]
+      ]
+    }, 
+    "lumamode_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4704875357867721480
+        ]
+      ]
     }, 
     "matrixconvolution_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3101476576521947165
+          13546074453897362674
         ]
       ], 
       "reviewed-by-human": true
@@ -6343,7 +8523,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10055081768235896808
+          2645433785253737964
         ]
       ], 
       "reviewed-by-human": true
@@ -6352,7 +8532,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589934301785253810
+          4116381614494335362
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "matrixconvolution_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4116381614494335362
         ]
       ], 
       "reviewed-by-human": true
@@ -6361,7 +8550,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10858609396135450061
+          14072014607244294525
         ]
       ], 
       "reviewed-by-human": false
@@ -6370,7 +8559,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8182459068173254170
+          18093313968129673224
         ]
       ], 
       "reviewed-by-human": false
@@ -6379,7 +8568,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8662058601690590393
+          921639679220198416
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matriximagefilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17179228966596117510
         ]
       ], 
       "reviewed-by-human": false
@@ -6412,7 +8610,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          389258352199308507
+          940913407237519059
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -6445,7 +8652,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          389258352199308507
+          940913407237519059
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -6478,7 +8694,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          389258352199308507
+          940913407237519059
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -6487,7 +8712,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9621832453494372057
+          1539651103309648647
         ]
       ], 
       "reviewed-by-human": true
@@ -6496,7 +8721,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1944307888764212912
+          14918941537433499795
         ]
       ], 
       "reviewed-by-human": true
@@ -6505,11 +8730,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1159197049660363044
+          17906316606932287523
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "mixed_xfermodes_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6374438980958395205
+        ]
+      ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
     "modecolorfilters_565.png": {
       "allowed-digests": [
         [
@@ -6538,19 +8773,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14409347541136653391
+          10690075085961116152
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "modecolorfilters_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10690075085961116152
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13276990043616594793
+          17044527983161977372
         ]
       ], 
       "reviewed-by-human": true
@@ -6559,7 +8802,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12053534281222176521
+          16679250406161029701
         ]
       ], 
       "reviewed-by-human": true
@@ -6568,37 +8811,427 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15160418634894798633
+          3140032282102690470
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "morphology_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3140032282102690470
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1799022373381634937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16072650776783849785
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16949296854614739341
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16870762334260965145
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10168290996640020029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17974959293136356721
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7647115313085356918
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18294645664025061405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6876146362791096301
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          672013974639373790
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          407121617914140822
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17107111279642959699
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13019697501260947975
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14977913019013260327
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5641947831670404346
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          937225195420941057
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16646836410262782197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18100820390850075519
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2574095166522288827
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8955432419196193693
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2682194241459481981
+          16123340172201812866
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "nested_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1792040421885608938
+          15356581678046831315
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "nested_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2956570062403950585
+          4768701989801326173
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "nested_aa_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8130234880941083628
+        ]
+      ], 
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "nested_bw_565.png": {
       "allowed-digests": [
@@ -6632,7 +9265,19 @@
         ]
       ], 
       "bugs": [
-        1759
+        1578
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "nested_bw_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8130234880941083628
+        ]
+      ], 
+      "bugs": [
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -6640,7 +9285,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18411873313823762166
+          2353651351546903350
         ]
       ], 
       "reviewed-by-human": true
@@ -6649,7 +9294,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14862133879758372505
+          12454353570070316868
         ]
       ], 
       "reviewed-by-human": true
@@ -6658,16 +9303,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18240364857152463172
+          16540029273389069204
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "ninepatch-stretch_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10044490000462319933
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nocolorbleed_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8421297753169056377
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
+    "nocolorbleed_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8421297753169056377
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "nonclosedpaths_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8797161389659029383
+          11279780315114260398
         ]
       ], 
       "reviewed-by-human": false
@@ -6676,7 +9348,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9282658625266410335
+          1265866929190406854
         ]
       ], 
       "reviewed-by-human": false
@@ -6685,7 +9357,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2717683152392989202
+          8197587017585371230
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "nonclosedpaths_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4023065398873229773
         ]
       ], 
       "reviewed-by-human": false
@@ -6694,7 +9375,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15240835456320409473
+          4656886197492028969
         ]
       ], 
       "reviewed-by-human": true
@@ -6703,7 +9384,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          249289862803617115
+          10009949554846362902
         ]
       ], 
       "reviewed-by-human": true
@@ -6712,7 +9393,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17818108684129139098
+          16425393435205920402
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "offsetimagefilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16688770112471467177
         ]
       ], 
       "reviewed-by-human": true
@@ -6745,47 +9435,129 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          6176209756741778646
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "optimizations_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6176209756741778646
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201817511424287157
+          4956630750436269799
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "ovals_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1184189085315519615
+          14188637820577652361
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "ovals_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10347668577930193751
+          3849340549236541887
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "ovals_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4077016649880928732
+        ]
+      ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12854990838652667931
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16478730915407089386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11115688412167805107
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4893664413873629107
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -6793,7 +9565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5447571501272498127
+          17899022691963121600
         ]
       ], 
       "bugs": [
@@ -6805,7 +9577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8312881875844297775
+          8212877465944976095
         ]
       ], 
       "bugs": [
@@ -6817,16 +9589,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          772433085551372706
+          14746240212910087597
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "path-reverse_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8556906240414798264
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "patheffect_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16045594695628613487
+          4427938030923047423
         ]
       ], 
       "bugs": [
@@ -6838,7 +9619,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13136038454993854220
+          4547654274603880457
         ]
       ], 
       "bugs": [
@@ -6850,70 +9631,109 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15962075333689603774
+          10102068867409260207
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "patheffect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11422815971462368947
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "pathfill_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9913956212375399295
+          10238641571996885423
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "pathfill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12306117555345084962
+          1120308788076075072
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "pathfill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13972162918751012955
+          6559039257537457437
         ]
       ], 
-      "reviewed-by-human": true
+      "ignore-failure": false
+    }, 
+    "pathfill_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5414209785014865741
+        ]
+      ], 
+      "ignore-failure": false
     }, 
     "pathinterior_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3396766038203432666
+          15564974755024712566
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "pathinterior_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12110360517026697498
+          6224212202381569470
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        1578
+      ], 
+      "reviewed-by-human": false
     }, 
     "pathinterior_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16405106071112654012
+          3097566210934595717
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "pathinterior_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          309616696507038075
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "pathinvfill_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8654831421971241050
+          8118219865348031190
         ]
       ], 
       "bugs": [
@@ -6925,7 +9745,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11144284047498640984
+          7771083304049147305
         ]
       ], 
       "bugs": [
@@ -6937,13 +9757,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3520993708181297768
+          5029407105525423667
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "pathinvfill_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5372292285746485836
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "pathopsinverse_565.png": {
       "allowed-digests": [
@@ -6970,20 +9796,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          404088650467664322
+          17032101979965966989
         ]
       ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "pathopsinverse_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3499633526125840539
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "pathopsskpclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6154660184356174115
+          2904824217886262883
         ]
       ], 
       "bugs": [
-        1759
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -6991,11 +9827,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4313744187563601995
+          6847070945713556374
         ]
       ], 
       "bugs": [
-        1759
+        1578
       ], 
       "reviewed-by-human": false
     }, 
@@ -7003,16 +9839,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          123433350506930487
+          8959682453711286650
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "pathopsskpclip_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8747062802182670817
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
     "peekpixels_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2758866006531517960
+          14531156101283739799
         ]
       ], 
       "reviewed-by-human": false
@@ -7021,7 +9866,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5344748376042459393
+          7937779188195651413
         ]
       ], 
       "reviewed-by-human": false
@@ -7030,7 +9875,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10481810241231481688
+          15458148370028677363
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "peekpixels_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10631445720626011577
         ]
       ], 
       "reviewed-by-human": false
@@ -7039,7 +9893,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -7048,7 +9902,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -7057,19 +9911,63 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5617237608049886158
+          16202756285536072592
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
       ], 
       "reviewed-by-human": false
     }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8190195795812546474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8190195795812546474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16202756285536072592
+        ]
+      ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15710121230086435602
+          14656164594743658373
         ]
       ], 
       "reviewed-by-human": true
@@ -7078,7 +9976,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1763586683528188858
+          7375436820633666472
         ]
       ], 
       "reviewed-by-human": true
@@ -7087,16 +9985,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1763586683528188858
+          7375436820633666472
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureimagefilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7375436820633666472
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11523502336595345447
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9198676987657517428
+          12994511397188975534
         ]
       ], 
       "reviewed-by-human": true
@@ -7105,7 +10048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17117388175840647151
+          18060131563380789045
         ]
       ], 
       "reviewed-by-human": true
@@ -7114,16 +10057,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7549768996631810693
+          9763269945803838112
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshader_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9763269945803838112
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8567194488499472739
+          9418063666161005464
         ]
       ], 
       "bugs": [
@@ -7135,7 +10123,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8567194488499472739
+          9418063666161005464
         ]
       ], 
       "bugs": [
@@ -7147,19 +10135,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3323041250453388207
+          3551260343426267181
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "points_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4104082303451079299
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1729179301788020778
+          13710370929503896242
         ]
       ], 
       "reviewed-by-human": true
@@ -7168,7 +10164,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15018091812205538488
+          14868659503042841956
         ]
       ], 
       "reviewed-by-human": true
@@ -7177,7 +10173,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17764211397622357735
+          10839024960221357604
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "poly2poly_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4353301731847242860
         ]
       ], 
       "reviewed-by-human": true
@@ -7186,7 +10191,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7471239721499308199
+          11517709488632152524
         ]
       ], 
       "reviewed-by-human": false
@@ -7195,7 +10200,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          961606689700631635
+          4804961199935719320
         ]
       ], 
       "reviewed-by-human": false
@@ -7204,16 +10209,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1583603789414455339
+          11943929872177488726
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "polygons_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18412169674810091291
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17243480259296502336
+          2214368729624239628
         ]
       ], 
       "reviewed-by-human": true
@@ -7222,7 +10236,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6891379388563692035
+          13695847048236137972
         ]
       ], 
       "reviewed-by-human": true
@@ -7231,7 +10245,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6297650466511707379
+          12911950575835675253
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "quadclosepath_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12770899583726255744
         ]
       ], 
       "reviewed-by-human": true
@@ -7240,7 +10263,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6963865127519492895
+          6757078992106948579
         ]
       ], 
       "reviewed-by-human": true
@@ -7249,7 +10272,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7223243377781866680
+          24796932854446382
         ]
       ], 
       "reviewed-by-human": true
@@ -7258,7 +10281,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5595773772993530952
+          15761539880746862400
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "quadpath_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10004632522250129097
         ]
       ], 
       "reviewed-by-human": true
@@ -7267,37 +10299,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2509551852078940571
+          11394637011745804615
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "radial_gradient2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4012506323387989153
+          11455010006792010801
         ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "radial_gradient2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11959852029544468073
+          2345997695698587496
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13265214489338924633
+        ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_565.png": {
       "allowed-digests": [
@@ -7327,19 +10357,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8690270988024634484
+          9371573623541139881
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9371573623541139881
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7959433338453691623
+          16802558787635856000
         ]
       ], 
       "reviewed-by-human": true
@@ -7348,7 +10386,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10522172914016896806
+          5173940140316611618
         ]
       ], 
       "reviewed-by-human": true
@@ -7357,7 +10395,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14982217045743030920
+          1197889143489694088
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          900608325866460990
         ]
       ], 
       "reviewed-by-human": true
@@ -7382,7 +10429,15 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5076745909900181906
+          7349956630718143123
+        ]
+      ]
+    }, 
+    "resizeimagefilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10856236620367132161
         ]
       ]
     }, 
@@ -7390,7 +10445,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17752420136993868343
+          10192478482016992029
         ]
       ], 
       "reviewed-by-human": true
@@ -7399,7 +10454,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1161927000752559561
+          16060307579559364278
         ]
       ], 
       "reviewed-by-human": true
@@ -7408,7 +10463,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          835479464135575251
+          1238816738306779698
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "roundrects_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          601943582393634455
         ]
       ], 
       "reviewed-by-human": true
@@ -7417,7 +10481,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18340118795193628429
+          9108911139001347487
         ]
       ], 
       "reviewed-by-human": true
@@ -7435,7 +10499,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13783532124190227221
+          14570932930676169469
         ]
       ], 
       "reviewed-by-human": true
@@ -7444,7 +10508,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13792455863265377338
+          6506138814340064770
         ]
       ], 
       "reviewed-by-human": true
@@ -7453,7 +10517,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8162996231165662471
+          5982212810056487769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_aa_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4186919709450229197
         ]
       ], 
       "reviewed-by-human": true
@@ -7480,7 +10553,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3764224183150533222
+          11653828811393066804
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_bw_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4186919709450229197
         ]
       ], 
       "reviewed-by-human": true
@@ -7489,7 +10571,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14635716521372290944
+          2598431657762879570
         ]
       ], 
       "reviewed-by-human": true
@@ -7498,7 +10580,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8853776977311383548
+          16466610707606959589
         ]
       ], 
       "reviewed-by-human": true
@@ -7507,7 +10589,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17915472794674819668
+          4652843928975001956
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3275281469903472416
         ]
       ], 
       "reviewed-by-human": true
@@ -7534,7 +10625,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2639533157784794570
+          8388919664468878536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_bw_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3275281469903472416
         ]
       ], 
       "reviewed-by-human": true
@@ -7543,7 +10643,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14635716521372290944
+          2598431657762879570
         ]
       ], 
       "reviewed-by-human": false
@@ -7552,7 +10652,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8853776977311383548
+          16466610707606959589
         ]
       ], 
       "reviewed-by-human": false
@@ -7561,7 +10661,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134143739778253386
+          1288562748996894577
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_aa_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3275281469903472416
         ]
       ], 
       "reviewed-by-human": false
@@ -7588,7 +10697,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2639533157784794570
+          8388919664468878536
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_draw_bw_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3275281469903472416
         ]
       ], 
       "reviewed-by-human": false
@@ -7597,7 +10715,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9741594763308804282
+          12786193733444395814
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_effect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12786193733444395814
         ]
       ], 
       "reviewed-by-human": false
@@ -7606,7 +10733,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11654998290125202938
+          2155978747761042485
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13792080558498309031
         ]
       ], 
       "reviewed-by-human": true
@@ -7615,7 +10751,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6887529583056247381
+          10747343857890775646
         ]
       ], 
       "reviewed-by-human": true
@@ -7624,7 +10760,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15016075013768190397
+          18242828079204705888
         ]
       ], 
       "reviewed-by-human": true
@@ -7633,7 +10769,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          979344291475393331
+          14479813863153725191
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "samplerstress_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3182129732232557875
         ]
       ], 
       "reviewed-by-human": true
@@ -7642,7 +10787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7135789859959079868
+          16328564683097406664
         ]
       ], 
       "reviewed-by-human": true
@@ -7651,7 +10796,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2185595877830848468
+          1864383706473625196
         ]
       ], 
       "reviewed-by-human": true
@@ -7660,7 +10805,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11540820957422662028
+          15863116205353424790
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "scaled_tilemode_bitmap_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15863116205353424790
         ]
       ], 
       "reviewed-by-human": true
@@ -7669,7 +10823,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14913297062861988444
+          16863946674017062032
         ]
       ], 
       "reviewed-by-human": true
@@ -7678,7 +10832,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7517125506221018662
+          14791436059610164321
         ]
       ], 
       "reviewed-by-human": true
@@ -7687,7 +10841,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14758428393785721359
+          4115409753570776342
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "scaled_tilemode_gradient_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4115409753570776342
         ]
       ], 
       "reviewed-by-human": true
@@ -7696,7 +10859,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14647286245000917282
+          2037993151486963791
         ]
       ], 
       "reviewed-by-human": true
@@ -7705,7 +10868,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16574168428196349390
+          7186960244825707915
         ]
       ], 
       "reviewed-by-human": true
@@ -7714,7 +10877,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14378884143882412610
+          11838132127013699928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "scaled_tilemodes_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15717961650619683621
         ]
       ], 
       "reviewed-by-human": true
@@ -7723,7 +10895,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7491706677759704423
+          787457888857029946
         ]
       ], 
       "reviewed-by-human": true
@@ -7732,7 +10904,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13922841069600322051
+          15540325168021281899
         ]
       ], 
       "reviewed-by-human": true
@@ -7741,7 +10913,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18413532602239109176
+          15930720713777284476
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "scaled_tilemodes_npot_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15930720713777284476
         ]
       ], 
       "reviewed-by-human": true
@@ -7777,10 +10958,16 @@
           1149339852105949057
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "selftest1_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1149339852105949057
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "selftest2_565.png": {
       "allowed-digests": [
@@ -7813,10 +11000,16 @@
           7903070799454133570
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "selftest2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7903070799454133570
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "shaderbounds_linear_565.png": {
       "allowed-digests": [
@@ -7846,19 +11039,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9231268892600322210
+          5642345952324434695
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "shaderbounds_linear_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13627924528135949304
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "shadows_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11496795807715360050
+          3556699044314006968
         ]
       ], 
       "bugs": [
@@ -7870,7 +11069,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11973828271981934898
+          12023275411897178283
         ]
       ], 
       "bugs": [
@@ -7882,13 +11081,20 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6393145760590998803
+          13223903649982789417
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "shadows_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16566182015823976290
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "shallow_gradient_conical_565.png": {
       "allowed-digests": [
@@ -7918,7 +11124,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17110523027129122270
+          6196392378926331366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_conical_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6196392378926331366
         ]
       ], 
       "reviewed-by-human": true
@@ -7951,13 +11166,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13330672348717914117
+          928711528976194484
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "shallow_gradient_linear_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          928711528976194484
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "shallow_gradient_radial_565.png": {
       "allowed-digests": [
@@ -7987,13 +11208,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3576469387623502205
+          10603003832140933469
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "shallow_gradient_radial_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10603003832140933469
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "shallow_gradient_sweep_565.png": {
       "allowed-digests": [
@@ -8023,19 +11250,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9322393820489779517
+          2511838126366942986
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "shallow_gradient_sweep_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2511838126366942986
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "simpleaaclip_aaclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7216936724349703423
+          5772369802529947832
         ]
       ], 
       "reviewed-by-human": true
@@ -8044,7 +11277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8297028920093819054
+          18010746007073820817
         ]
       ], 
       "reviewed-by-human": true
@@ -8053,7 +11286,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16021439723556558918
+          13752864005883944298
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleaaclip_aaclip_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3153768880396211339
         ]
       ], 
       "reviewed-by-human": true
@@ -8062,7 +11304,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7216936724349703423
+          5772369802529947832
         ]
       ], 
       "reviewed-by-human": true
@@ -8071,7 +11313,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8505743106500736554
+          17160448045672967434
         ]
       ], 
       "reviewed-by-human": true
@@ -8080,7 +11322,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1978759492972376322
+          17911005775522481791
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleaaclip_path_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14819693481844219446
         ]
       ], 
       "reviewed-by-human": true
@@ -8089,7 +11340,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5181638003047557471
+          13182565406150039161
         ]
       ], 
       "reviewed-by-human": true
@@ -8098,7 +11349,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2247183642119438840
+          1769885343134219810
         ]
       ], 
       "reviewed-by-human": true
@@ -8107,7 +11358,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16948766582215433974
+          3192212603736226562
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleaaclip_rect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9042094218046158759
         ]
       ], 
       "reviewed-by-human": true
@@ -8116,7 +11376,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          335739214192474542
+          13988021646843375450
         ]
       ], 
       "reviewed-by-human": true
@@ -8125,7 +11385,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5652577089689509120
+          7482672038493178391
         ]
       ], 
       "reviewed-by-human": true
@@ -8134,7 +11394,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15913476983071756158
+          8411590397840305868
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleblurroundrect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8411590397840305868
         ]
       ], 
       "reviewed-by-human": true
@@ -8145,11 +11414,7 @@
           "bitmap-64bitMD5", 
           2332391077132553330
         ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "skbug1719_8888.png": {
       "allowed-digests": [
@@ -8157,21 +11422,23 @@
           "bitmap-64bitMD5", 
           13212045663266308489
         ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      ]
     }, 
     "skbug1719_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17095707402781773995
+          16076861668720652969
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": true
+    }, 
+    "skbug1719_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14741463111103498316
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -8179,43 +11446,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13563811160364567248
+          13909757336310240518
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "spritebitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          227198932212139294
+          17885518595384354919
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "spritebitmap_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5342593300778917277
+          14591259311540122321
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "spritebitmap_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14591259311540122321
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "srcmode_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14499438099795304341
+          11699531654048406518
         ]
       ], 
       "reviewed-by-human": true
@@ -8224,7 +11491,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14771578516798309775
+          4523091657809672686
         ]
       ], 
       "reviewed-by-human": true
@@ -8233,7 +11500,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12943740194645175665
+          11932325483223150611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "srcmode_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4758860195708070393
         ]
       ], 
       "reviewed-by-human": true
@@ -8266,7 +11542,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8864794410650886097
+          10366014201433878424
         ]
       ], 
       "bugs": [
@@ -8274,11 +11550,20 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "stringart_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2619457830856634051
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "stroke-fill_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3203505322339327449
+          814718949876335150
         ]
       ], 
       "reviewed-by-human": true
@@ -8287,7 +11572,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16626870905607243018
+          14156844530688032350
         ]
       ], 
       "reviewed-by-human": true
@@ -8296,7 +11581,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15798393829747738691
+          12534197914063090605
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stroke-fill_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16520246176382101026
         ]
       ], 
       "reviewed-by-human": true
@@ -8323,16 +11617,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16007880695407826360
+          6137491411888461050
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "strokerect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15029252674312959982
+        ]
+      ], 
+      "bugs": [
+        1841
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
+    }, 
     "strokerects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10731083935300051992
+          1252564837192523211
         ]
       ], 
       "bugs": [
@@ -8356,19 +11663,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5747656467049588206
+          15090725858042311967
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "strokerects_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16931955409114499864
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "strokes3_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1686573849514282054
+          8397039244880318300
         ]
       ], 
       "bugs": [
@@ -8380,7 +11693,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9947658613138732028
+          16717945387368894511
+        ]
+      ], 
+      "ignore-failure": false
+    }, 
+    "strokes3_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17152026830293837540
         ]
       ], 
       "bugs": [
@@ -8388,23 +11710,21 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "strokes3_gpu.png": {
+    "strokes3_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7751974933403726499
+          7963128043860422901
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "strokes_poly_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13975044413592406455
+          4939197335393210893
         ]
       ], 
       "bugs": [
@@ -8416,7 +11736,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9847781398855716283
+          8189110711369465006
         ]
       ], 
       "bugs": [
@@ -8428,19 +11748,26 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5265350706794735927
+          9937631940225759866
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "strokes_poly_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17602650810832693174
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "strokes_round_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8830084223721413158
+          1967359529448596413
         ]
       ], 
       "reviewed-by-human": true
@@ -8449,7 +11776,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14762739513429490065
+          11874628554314465422
         ]
       ], 
       "reviewed-by-human": true
@@ -8458,7 +11785,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          849657193303901676
+          6800887868791302499
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_round_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8264575581090854634
         ]
       ], 
       "reviewed-by-human": true
@@ -8467,7 +11803,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7449648884353637669
+          18286981917824090179
         ]
       ], 
       "reviewed-by-human": true
@@ -8476,7 +11812,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4914721999172725849
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -8485,16 +11821,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18332417829561221001
+          11625837403190001764
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "stroketext_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3753618903036190582
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tablecolorfilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6155339908971373908
+          13695771735763792806
         ]
       ], 
       "bugs": [
@@ -8506,7 +11851,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5497460981955702016
+          4361716833575286014
         ]
       ], 
       "bugs": [
@@ -8518,49 +11863,56 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8226915152097966889
+          14390703273660617396
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "tablecolorfilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14390703273660617396
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "testimagefilters_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10876942606580879984
+          1369006746513120542
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "testimagefilters_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913857649673524662
+          10584886924228958226
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "testimagefilters_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12654679736886426328
+          4597062943976028698
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7686535302725161510
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "texdata_565.png": {
       "allowed-digests": [
@@ -8593,16 +11945,58 @@
           2736593828543197285
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "texdata_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2736593828543197285
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
+    }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          163112871246100159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13357146488219809893
+          3352233736449563022
         ]
       ], 
       "reviewed-by-human": true
@@ -8611,7 +12005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7386759365357423329
+          377328076341373940
         ]
       ], 
       "reviewed-by-human": true
@@ -8620,7 +12014,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7386759365357423329
+          6885322238950860527
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texteffects_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6885322238950860527
         ]
       ], 
       "reviewed-by-human": true
@@ -8629,10 +12032,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11734977558073048483
+          1542449700616506808
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "texture_domain_effect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1542449700616506808
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -8641,10 +12053,7 @@
           17949451347125150629
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "thinrects_8888.png": {
       "allowed-digests": [
@@ -8653,22 +12062,26 @@
           12074631820414627784
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "thinrects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5935862934447854810
+          10999541404612369092
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12238579170258253339
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "thinstrokedrects_565.png": {
       "allowed-digests": [
@@ -8677,10 +12090,7 @@
           17882028260402842392
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "thinstrokedrects_8888.png": {
       "allowed-digests": [
@@ -8689,28 +12099,32 @@
           2596255945580270876
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "thinstrokedrects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18134316930773092342
+          1946366533119786586
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12987283967322439160
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15884441815359625883
+          15732727687033594466
         ]
       ], 
       "reviewed-by-human": true
@@ -8719,7 +12133,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8728,7 +12142,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          8847318198118613005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tileimagefilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8737,7 +12160,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7135789859959079868
+          16328564683097406664
         ]
       ], 
       "reviewed-by-human": true
@@ -8746,7 +12169,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2185595877830848468
+          1864383706473625196
         ]
       ], 
       "reviewed-by-human": true
@@ -8755,7 +12178,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11540820957422662028
+          15863116205353424790
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tilemode_bitmap_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15863116205353424790
         ]
       ], 
       "reviewed-by-human": true
@@ -8764,7 +12196,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14913297062861988444
+          16863946674017062032
         ]
       ], 
       "reviewed-by-human": true
@@ -8773,7 +12205,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7517125506221018662
+          14791436059610164321
         ]
       ], 
       "reviewed-by-human": true
@@ -8782,7 +12214,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14758428393785721359
+          4115409753570776342
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tilemode_gradient_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4115409753570776342
         ]
       ], 
       "reviewed-by-human": true
@@ -8791,7 +12232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10553952199599604816
+          14518357519823587689
         ]
       ], 
       "reviewed-by-human": true
@@ -8800,7 +12241,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14968443247329529117
+          14480947444732898359
         ]
       ], 
       "reviewed-by-human": true
@@ -8809,7 +12250,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5254473306719673022
+          15432201581929914329
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tilemodes_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270349007635227054
         ]
       ], 
       "reviewed-by-human": true
@@ -8818,7 +12268,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5008151281798703171
+          7541465528042330556
         ]
       ], 
       "reviewed-by-human": true
@@ -8827,7 +12277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13298836052288001622
+          14216970501880738242
         ]
       ], 
       "reviewed-by-human": true
@@ -8836,7 +12286,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8451918751746608219
+          8293716677305839949
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tilemodes_npot_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8293716677305839949
         ]
       ], 
       "reviewed-by-human": true
@@ -8872,16 +12331,22 @@
           5633315905476176630
         ]
       ], 
-      "bugs": [
-        1759
+      "ignore-failure": false
+    }, 
+    "tinybitmap_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5633315905476176630
+        ]
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": false
     }, 
     "twopointconical_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14356658846198325540
+          312360552053871343
         ]
       ], 
       "reviewed-by-human": true
@@ -8890,7 +12355,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6036270199387229964
+          5412705785906131810
         ]
       ], 
       "reviewed-by-human": true
@@ -8899,7 +12364,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7663579407369070653
+          7602193588573987007
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "twopointconical_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8745787247861012911
         ]
       ], 
       "reviewed-by-human": true
@@ -8908,7 +12382,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3225712846346731230
+          15619398124800687676
         ]
       ], 
       "reviewed-by-human": true
@@ -8917,7 +12391,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3057908372893981204
+          14725542749908228
         ]
       ], 
       "reviewed-by-human": true
@@ -8926,7 +12400,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3057908372893981204
+          14725542749908228
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "typeface_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14725542749908228
         ]
       ], 
       "reviewed-by-human": true
@@ -8935,7 +12418,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5356705204909842699
+          4613753462059358003
         ]
       ], 
       "reviewed-by-human": true
@@ -8944,7 +12427,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370428013149648258
+          6475798309604476317
         ]
       ], 
       "reviewed-by-human": true
@@ -8953,16 +12436,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370428013149648258
+          6475798309604476317
         ]
       ], 
+      "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          201259875367580358
+          2637218109707056544
         ]
       ], 
       "reviewed-by-human": false
@@ -8971,7 +12455,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2080761164861757576
+          17546866530171427130
         ]
       ], 
       "reviewed-by-human": false
@@ -8980,11 +12464,174 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8882773799933891216
+          539829354440306365
         ]
       ], 
       "reviewed-by-human": false
     }, 
+    "typefacestyles_kerning_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          539829354440306365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6475798309604476317
+        ]
+      ], 
+      "ignore-failure": false, 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683867137211693534
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11064306957043870693
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683867137211693534
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11064306957043870693
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16282339837156485923
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2548812463070281529
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16282339837156485923
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2548812463070281529
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -9012,6 +12659,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "vertices_80_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4978884384916614166
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13624063381339047598
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_8888.png": {
       "allowed-digests": [
         [
@@ -9025,7 +12690,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1343433454959599907
+          3919362424169097654
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "vertices_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2725929479483228685
         ]
       ], 
       "reviewed-by-human": false
@@ -9034,7 +12708,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2163610981651965452
+          11841449243819703285
         ]
       ], 
       "reviewed-by-human": true
@@ -9043,7 +12717,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14527641142409674625
+          6274320838479527537
         ]
       ], 
       "reviewed-by-human": true
@@ -9052,7 +12726,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3597293503861619263
+          9542465742508355750
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "verttext2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          61757559844828924
         ]
       ], 
       "reviewed-by-human": true
@@ -9061,7 +12744,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4473316427232601425
+          13128495885096967138
         ]
       ], 
       "reviewed-by-human": true
@@ -9070,7 +12753,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10869528886180759869
+          12569529133241702893
         ]
       ], 
       "reviewed-by-human": true
@@ -9079,7 +12762,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7700008644697398877
+          9176862830826009650
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "verttext_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13106407264936009474
         ]
       ], 
       "reviewed-by-human": true
@@ -9088,7 +12780,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10958353996143090911
+          3112652115716203250
         ]
       ], 
       "reviewed-by-human": true
@@ -9097,7 +12789,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17000878545702467803
+          12938112915997113104
         ]
       ], 
       "reviewed-by-human": true
@@ -9106,7 +12798,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12340026112988841012
+          1512989932016141784
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "xfermodeimagefilter_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1512989932016141784
         ]
       ], 
       "reviewed-by-human": true
@@ -9115,7 +12816,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6775705236924739798
+          9091807513339597757
         ]
       ], 
       "reviewed-by-human": true
@@ -9124,7 +12825,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2952493606222488372
+          6431759696672110544
         ]
       ], 
       "reviewed-by-human": true
@@ -9133,7 +12834,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14811732441451933971
+          3259542057496795230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "xfermodes2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17330165520408407412
         ]
       ], 
       "reviewed-by-human": true
@@ -9142,7 +12852,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1103771815346361861
+          6138089295555010874
         ]
       ], 
       "reviewed-by-human": true
@@ -9151,7 +12861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14561360239620524377
+          15172719087640402575
         ]
       ], 
       "reviewed-by-human": true
@@ -9160,7 +12870,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12574873031515180645
+          12709457172558903514
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "xfermodes3_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12709457172558903514
         ]
       ], 
       "reviewed-by-human": true
@@ -9169,7 +12888,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6398363063795275200
+          7109422783042838679
         ]
       ], 
       "reviewed-by-human": true
@@ -9178,7 +12897,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          382247129895543895
+          1637047472327850125
         ]
       ], 
       "reviewed-by-human": true
@@ -9187,10 +12906,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11611679597896853327
+          12373255510807920217
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "xfermodes_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14037617966684837344
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14593717200149920625
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14593717200149920625
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Release/expected-results.json b/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Release/expected-results.json
index c34cccf..c4603f2 100644
--- a/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Release/expected-results.json
+++ b/expectations/gm/Test-Android-Nexus10-MaliT604-Arm7-Release/expected-results.json
@@ -113,19 +113,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5026092757857652816
+          1146375027159957531
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11350550014829151063
+          6379613855638636955
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -268,7 +270,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2893684135042278491
+          1761278230894790045
         ]
       ], 
       "reviewed-by-human": true
@@ -277,7 +279,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2893684135042278491
+          1761278230894790045
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -298,7 +336,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16937826245063043393
+          4981823264217273689
         ]
       ], 
       "reviewed-by-human": true
@@ -307,7 +345,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1625650000574334368
+          5246634874959150570
         ]
       ], 
       "reviewed-by-human": true
@@ -316,7 +354,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5950834616123524220
+          13773072584611565658
         ]
       ], 
       "reviewed-by-human": true
@@ -325,7 +363,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4439200707771429092
+          15150074299283974308
         ]
       ], 
       "reviewed-by-human": true
@@ -334,7 +372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11836824726968626971
+          14603413282175161618
         ]
       ], 
       "reviewed-by-human": true
@@ -343,49 +381,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7185775830111795273
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7986799885106602241
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_msaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7986799885106602241
+          7826012751896877231
         ]
       ], 
       "reviewed-by-human": true
@@ -412,19 +408,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6556557775884332983
+          11049254347913309109
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12843708684659573815
+          16508684429113109899
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -496,10 +492,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12359262904549189844
+          11021706081645443796
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bigtext_msaa4.png": {
       "allowed-digests": [
@@ -559,7 +556,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5556270988884295076
+          12687331394697954528
         ]
       ], 
       "reviewed-by-human": true
@@ -568,7 +565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410204863204197194
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -577,7 +574,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3378108973415664789
+          271311882745633725
         ]
       ], 
       "reviewed-by-human": true
@@ -586,7 +583,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3378108973415664789
+          271311882745633725
         ]
       ], 
       "reviewed-by-human": true
@@ -841,19 +838,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1911284151223294607
+          12298010451676936832
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5496062952963902498
+          9867627344966414537
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "blend_gpu.png": {
       "allowed-digests": [
@@ -938,7 +941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8585274474692888711
+          12682910021301734282
         ]
       ], 
       "reviewed-by-human": true
@@ -2410,6 +2413,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -2600,16 +2639,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15802800677340237213
+          158195814517883351
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15802800677340237213
+          158195814517883351
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          271466639589239328
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10426400083921889194
         ]
       ], 
       "reviewed-by-human": false
@@ -2855,10 +2930,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5271492299818290635
+          2111070892848864737
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "circles_msaa4.png": {
       "allowed-digests": [
@@ -2943,7 +3019,8 @@
           4165161027652562674
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "clamped_gradients_msaa4.png": {
       "allowed-digests": [
@@ -3499,7 +3576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9173305563013405797
+          6538569194874273793
         ]
       ], 
       "reviewed-by-human": true
@@ -3619,7 +3696,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5551215450807356131
+          12606971060652066622
         ]
       ], 
       "reviewed-by-human": true
@@ -3673,7 +3750,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15764519043297885758
+          4104797309315770800
         ]
       ], 
       "reviewed-by-human": true
@@ -3682,7 +3759,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7935307680550293784
+          6544536706877310514
         ]
       ], 
       "reviewed-by-human": true
@@ -3691,7 +3768,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17629601631421032649
+          14513438909331829416
         ]
       ], 
       "reviewed-by-human": true
@@ -3700,7 +3777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1557613698479648092
+          8097997023778848191
         ]
       ], 
       "reviewed-by-human": true
@@ -3709,7 +3786,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          686626615788563308
+          5836493341538608113
         ]
       ], 
       "reviewed-by-human": true
@@ -3718,7 +3795,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11008419185465923560
+          9084880565837755264
         ]
       ], 
       "reviewed-by-human": true
@@ -3727,7 +3804,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9486392645453497087
+          17768595575576867230
         ]
       ], 
       "reviewed-by-human": true
@@ -3736,7 +3813,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16112459223155284268
+          18260984331770722196
         ]
       ], 
       "reviewed-by-human": true
@@ -3745,7 +3822,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5930938593239004653
+          4165425675033352640
         ]
       ], 
       "reviewed-by-human": true
@@ -3754,7 +3831,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3190552677201665775
+          10152516748782571739
         ]
       ], 
       "reviewed-by-human": true
@@ -3763,7 +3840,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9513391566593573165
+          14914601045858845148
         ]
       ], 
       "reviewed-by-human": true
@@ -3772,7 +3849,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4870317370734649728
+          8180502121217066191
         ]
       ], 
       "reviewed-by-human": true
@@ -3781,7 +3858,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5783287451488289297
+          16993829969091028380
         ]
       ], 
       "reviewed-by-human": true
@@ -3790,7 +3867,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11074069104236429752
+          1059511820934474761
         ]
       ], 
       "reviewed-by-human": true
@@ -3799,7 +3876,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5806668200495180873
+          15952923770779117335
         ]
       ], 
       "reviewed-by-human": true
@@ -3808,7 +3885,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14316497875403562633
+          14110404372599098336
         ]
       ], 
       "reviewed-by-human": true
@@ -3891,43 +3968,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17707691143950027168
+          4792118895672570848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788619303593885819
+          11285887424651164487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17279500842640178602
+          9807676647004956667
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7100780245620768737
+          3010580829471563399
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3986029323432953206
+          13463378520577789165
         ]
       ], 
       "reviewed-by-human": true
@@ -3963,7 +4040,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          878134881943676117
+          8826348418330119107
         ]
       ], 
       "reviewed-by-human": true
@@ -4030,7 +4107,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17138342910351740780
+          15418783980877386199
         ]
       ], 
       "reviewed-by-human": true
@@ -4039,7 +4116,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13937678633951136440
+          7882161322447216882
         ]
       ], 
       "reviewed-by-human": true
@@ -4048,7 +4125,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12437925742673758459
+          4204097215809673028
         ]
       ], 
       "reviewed-by-human": true
@@ -4057,7 +4134,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14755023570715423032
+          7751217857540747
         ]
       ], 
       "reviewed-by-human": true
@@ -4066,7 +4143,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2256130412784819033
+          3184062263576953667
         ]
       ], 
       "reviewed-by-human": true
@@ -4075,7 +4152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10471902765578272701
+          713799816796517938
         ]
       ], 
       "reviewed-by-human": true
@@ -4084,7 +4161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6406309812490590578
+          13367306876695640597
         ]
       ], 
       "reviewed-by-human": true
@@ -4093,7 +4170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9564056393704879247
+          18324282461018392405
         ]
       ], 
       "reviewed-by-human": true
@@ -4126,7 +4203,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7604196399059623193
+          13633210306002531372
         ]
       ], 
       "reviewed-by-human": true
@@ -4250,7 +4327,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          791242651888418698
+          842505089271483404
         ]
       ], 
       "reviewed-by-human": true
@@ -4311,7 +4388,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9374541812861034293
+          11475660560101599954
         ]
       ], 
       "reviewed-by-human": true
@@ -4320,7 +4397,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2576698895183287698
+          7311723676588845146
         ]
       ], 
       "reviewed-by-human": true
@@ -4329,7 +4406,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11639051266587012430
+          12602988813237402949
         ]
       ], 
       "reviewed-by-human": true
@@ -4338,7 +4415,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10884278746786757102
+          8320360396414647822
         ]
       ], 
       "reviewed-by-human": true
@@ -4383,7 +4460,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3767760557629765982
+          4057230872151110302
         ]
       ], 
       "reviewed-by-human": true
@@ -4392,7 +4469,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12070678672447530766
+          9482070623821433904
         ]
       ], 
       "reviewed-by-human": true
@@ -4401,7 +4478,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6894694195096323180
+          1170916231930532316
         ]
       ], 
       "ignore-failure": false, 
@@ -4411,7 +4488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6894694195096323180
+          1170916231930532316
         ]
       ], 
       "ignore-failure": false, 
@@ -4421,49 +4498,45 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -4472,7 +4545,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -4481,7 +4554,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16402901581873179688
+          2053143241305253519
         ]
       ], 
       "reviewed-by-human": true
@@ -4490,7 +4563,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13362740310524141608
+          13558497883564503203
         ]
       ], 
       "reviewed-by-human": true
@@ -4499,103 +4572,79 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14023107341215656134
+          1365476015121733881
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14164969753916932440
+          4085557449317823255
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16402901581873179688
+          2053143241305253519
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13362740310524141608
+          13558497883564503203
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6989712392624471913
+          17775297231868448514
         ]
       ], 
       "reviewed-by-human": true
@@ -4604,7 +4653,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10855232109519818829
+          12804472649182277577
         ]
       ], 
       "reviewed-by-human": true
@@ -4613,31 +4662,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4191781949737697782
+          12650731363086188245
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11095225883539199074
+          7320890964320867858
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -4646,7 +4689,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -4655,7 +4698,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11015226385634627319
+          13504880513739592005
         ]
       ], 
       "reviewed-by-human": true
@@ -4664,7 +4707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12072318510619816364
+          16903774499113610668
         ]
       ], 
       "reviewed-by-human": true
@@ -4673,103 +4716,79 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17095214210643863806
+          6399690160433481902
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1468452751651415530
+          8921034639234342908
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11015226385634627319
+          13504880513739592005
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12072318510619816364
+          16903774499113610668
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2497837460215148124
+          6055955940623478607
         ]
       ], 
       "reviewed-by-human": true
@@ -4778,7 +4797,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13192464168020553898
+          11797865288006977816
         ]
       ], 
       "reviewed-by-human": true
@@ -4787,31 +4806,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3501964266759034972
+          11185694799637075711
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14493483688798209788
+          18352104832144523134
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -4820,7 +4833,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
         ]
       ], 
       "reviewed-by-human": true
@@ -4829,7 +4842,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16613355738876267064
+          14579864208673224889
         ]
       ], 
       "reviewed-by-human": true
@@ -4838,7 +4851,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11814031037659245194
+          15078056460862308465
         ]
       ], 
       "reviewed-by-human": true
@@ -4847,7 +4860,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          4886211991926050486
         ]
       ], 
       "reviewed-by-human": true
@@ -4856,7 +4869,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          8737545656412765906
         ]
       ], 
       "reviewed-by-human": true
@@ -4865,7 +4878,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16220755812352055363
+          14057740961401979106
         ]
       ], 
       "reviewed-by-human": true
@@ -4874,7 +4887,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3630497057597410398
+          6129142780121532863
         ]
       ], 
       "reviewed-by-human": true
@@ -4883,7 +4896,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -4892,7 +4905,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
         ]
       ], 
       "reviewed-by-human": true
@@ -4901,7 +4914,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13026483582621867219
+          10604640727019939807
         ]
       ], 
       "reviewed-by-human": true
@@ -4910,7 +4923,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11870810962143606254
+          8392931363281798442
         ]
       ], 
       "reviewed-by-human": true
@@ -4919,7 +4932,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          4707049264800437834
         ]
       ], 
       "reviewed-by-human": true
@@ -4928,7 +4941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          3175389971476411688
         ]
       ], 
       "reviewed-by-human": true
@@ -4937,7 +4950,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6240516027066032938
+          365721829706691205
         ]
       ], 
       "reviewed-by-human": true
@@ -4946,7 +4959,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6158634465433606581
+          2473941895467574423
         ]
       ], 
       "reviewed-by-human": true
@@ -4955,7 +4968,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
       "reviewed-by-human": true
@@ -4973,25 +4986,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7321152256688530904
+          15394406070971249703
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18007652415364355329
+          14484858848664747251
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5455618422902283397
+          15797039913993285826
         ]
       ], 
       "reviewed-by-human": true
@@ -5000,7 +5015,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14095817193753318732
+          17497164562330387900
         ]
       ], 
       "reviewed-by-human": true
@@ -5009,7 +5024,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3872986862548041645
+          12686426978094913156
         ]
       ], 
       "reviewed-by-human": true
@@ -5018,7 +5033,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3825409027096066799
+          6490420606640500316
         ]
       ], 
       "reviewed-by-human": true
@@ -5027,7 +5042,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          716171842978913864
+          273445276579232833
         ]
       ], 
       "reviewed-by-human": true
@@ -5036,7 +5051,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17171710908581496295
+          13357226331142394630
         ]
       ], 
       "reviewed-by-human": true
@@ -5045,7 +5060,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16393840778105859134
+          3819664262710657017
         ]
       ], 
       "reviewed-by-human": true
@@ -5054,7 +5069,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12578433082733978467
+          367215542131912432
         ]
       ], 
       "reviewed-by-human": true
@@ -5081,7 +5096,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18222344878169758652
+          12767183233496534484
         ]
       ], 
       "reviewed-by-human": true
@@ -5099,7 +5114,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16452419234213932266
+          1802138798652377585
         ]
       ], 
       "reviewed-by-human": true
@@ -5108,7 +5123,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13347568447034524087
+          588269449619860245
         ]
       ], 
       "reviewed-by-human": true
@@ -5117,7 +5132,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8048041692818960741
+          13516932575826030439
         ]
       ], 
       "reviewed-by-human": true
@@ -5126,7 +5141,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14770838630769789516
+          649418728571953564
         ]
       ], 
       "reviewed-by-human": true
@@ -5275,6 +5290,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -5480,7 +5531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -5489,7 +5540,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -5516,7 +5567,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -5525,7 +5576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -5552,7 +5603,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -5561,7 +5612,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -5588,7 +5639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -5597,7 +5648,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -5624,7 +5675,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -5633,7 +5684,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -5660,7 +5711,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -5669,7 +5720,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -5696,7 +5747,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -5705,7 +5756,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -5732,7 +5783,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -5741,7 +5792,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -5768,7 +5819,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -5777,7 +5828,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -5840,7 +5891,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -5849,7 +5900,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -5912,7 +5963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -5921,7 +5972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -5948,7 +5999,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -5957,7 +6008,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
@@ -5980,6 +6031,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2286802257293267683
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4050292462410603306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -6002,85 +6089,83 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          17276962213970077366
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          8694218356938189525
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1857288326388942863
         ]
       ], 
-      "ignore-failure": false
+      "bugs": [
+        2887
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1857288326388942863
         ]
       ], 
-      "ignore-failure": false
+      "bugs": [
+        2887
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          4335659971728708662
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": false
     }, 
     "fontmgr_match_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -6118,11 +6203,47 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2500355683115767624
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954882728248735643
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954882728248735643
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7818310295492545479
+          11716334334721910796
         ]
       ], 
       "reviewed-by-human": true
@@ -6131,7 +6252,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4994151175360770217
+          5693920054563327483
         ]
       ], 
       "reviewed-by-human": true
@@ -6140,7 +6261,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16992328529818347083
+          4779790303751499909
         ]
       ], 
       "ignore-failure": false, 
@@ -6150,7 +6271,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10536938466654728031
+          11415732188148058124
         ]
       ], 
       "ignore-failure": false, 
@@ -6178,7 +6299,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11958130802613243691
+          18352804101744384563
         ]
       ], 
       "reviewed-by-human": true
@@ -6684,6 +6805,294 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17133241123252992386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17133241123252992386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2740474667902760224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13062572212227089670
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2740474667902760224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13062572212227089670
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18181809164582745765
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10646101256712397679
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5216581726550480243
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14988814117683836650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16062483234765207871
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3020788879261074646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2740474667902760224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13062572212227089670
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863085462100832326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14621205964232291210
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          738609491282019773
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271247215169625597
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2739908385541953120
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16879059920514854608
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -6715,10 +7124,7 @@
           6515341671020089010
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa4.png": {
       "allowed-digests": [
@@ -6799,7 +7205,7 @@
           8697473946772464652
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa4.png": {
       "allowed-digests": [
@@ -6835,7 +7241,7 @@
           6477843407979522548
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa4.png": {
       "allowed-digests": [
@@ -6871,7 +7277,7 @@
           14407511764193782824
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa4.png": {
       "allowed-digests": [
@@ -7080,7 +7486,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -7118,7 +7524,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13538992606665750486
+          8988444324654919932
         ]
       ], 
       "reviewed-by-human": true
@@ -7170,7 +7576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12254036309807088467
+          15771786769254973604
         ]
       ], 
       "reviewed-by-human": true
@@ -7212,25 +7618,24 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15608068978304990937
+          974999507980407411
         ]
       ], 
-      "bugs": [
-        1655
-      ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6086347690359883301
+          14247877693672647204
         ]
       ], 
       "bugs": [
         1655
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -7348,11 +7753,47 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          741134624395776214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          357284903731074601
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10462784937398826625
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10462784937398826625
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3794665630847901594
+          13620335786972140736
         ]
       ], 
       "reviewed-by-human": true
@@ -7361,7 +7802,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7748801528548244433
+          17030111096598942390
         ]
       ], 
       "reviewed-by-human": true
@@ -7370,7 +7811,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10600008287836361870
+          1105584058315288349
         ]
       ], 
       "ignore-failure": false, 
@@ -7380,7 +7821,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259128835424197006
+          1922338586017046100
         ]
       ], 
       "reviewed-by-human": true
@@ -7389,7 +7830,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13149265802466457140
+          3693078186234250164
         ]
       ], 
       "reviewed-by-human": true
@@ -7398,7 +7839,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6055181530730610249
+          11518661682572191380
         ]
       ], 
       "reviewed-by-human": true
@@ -7407,7 +7848,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          467903512579381270
+          13388867466611225896
         ]
       ], 
       "reviewed-by-human": true
@@ -7416,7 +7857,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15006392815688908432
+          10285237549190759962
         ]
       ], 
       "ignore-failure": false, 
@@ -7462,7 +7903,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6719033984262147569
+          9334915207072042375
         ]
       ], 
       "reviewed-by-human": true
@@ -7471,7 +7912,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9527595429529547733
+          4262113639047937913
         ]
       ], 
       "reviewed-by-human": true
@@ -7480,7 +7921,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3901701882206486087
+          13519884549264043430
         ]
       ], 
       "ignore-failure": false, 
@@ -7490,7 +7931,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13854151776049831058
+          4393655961616093182
         ]
       ], 
       "ignore-failure": false, 
@@ -7500,25 +7941,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8498778868685964382
+          9643897842146508458
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          880034339526468883
+          14154076457851775362
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7378130804090280505
+          6187141994062797732
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_msaa4.png": {
       "allowed-digests": [
@@ -7532,7 +7976,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219558445660995645
+          16816155573392653040
         ]
       ], 
       "reviewed-by-human": true
@@ -7541,7 +7985,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          861754899676926834
+          15621659488709502951
         ]
       ], 
       "reviewed-by-human": true
@@ -7550,7 +7994,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2189776203782237302
+          13481672823921868407
         ]
       ], 
       "reviewed-by-human": true
@@ -7559,7 +8003,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16812648126579727424
+          5523411567262382106
         ]
       ], 
       "reviewed-by-human": true
@@ -7568,7 +8012,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15200137971968303012
+          14400660572715212845
         ]
       ], 
       "reviewed-by-human": true
@@ -7577,7 +8021,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199776944359958607
+          12820728063175372793
         ]
       ], 
       "reviewed-by-human": true
@@ -7595,52 +8039,53 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14205191585536753006
+          2586660090509305197
         ]
       ], 
-      "bugs": [
-        2005
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7984057522805858516
+          88044436581289267
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          28560584844019362
+          12997200926589207952
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5274487773236388163
+          4458594706234736506
         ]
       ], 
       "reviewed-by-human": true
@@ -7649,7 +8094,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10772725192724193725
+          7881653068493848399
         ]
       ], 
       "reviewed-by-human": true
@@ -7658,7 +8103,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4439390010850114092
+          12683787554719393302
         ]
       ], 
       "reviewed-by-human": true
@@ -7667,7 +8112,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7359778396292882174
+          18111354910595959932
         ]
       ], 
       "reviewed-by-human": true
@@ -7844,25 +8289,22 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6457829872533044881
+          1889599541186254424
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3484111703141212082
+          7255273740487203408
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
@@ -7940,7 +8382,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15118920252874319058
+          9075523320529578103
         ]
       ], 
       "reviewed-by-human": true
@@ -7949,7 +8391,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13213375518846743511
+          4131799565799962704
         ]
       ], 
       "reviewed-by-human": true
@@ -7958,7 +8400,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8215825475342594196
+          13362151343000560853
         ]
       ], 
       "reviewed-by-human": true
@@ -7967,7 +8409,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10703646791439328135
+          179903152301013150
         ]
       ], 
       "reviewed-by-human": true
@@ -7976,7 +8418,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7394602124225746876
+          4095489997625677813
         ]
       ], 
       "reviewed-by-human": true
@@ -7985,7 +8427,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768949088352973106
+          17687576741285937089
         ]
       ], 
       "reviewed-by-human": true
@@ -7994,7 +8436,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12299776392542434240
+          16350254171643964347
         ]
       ], 
       "reviewed-by-human": true
@@ -8003,7 +8445,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13360137564165442940
+          15500554310857216494
         ]
       ], 
       "reviewed-by-human": true
@@ -8028,17 +8470,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10006188054349176574
+          14694204158057728253
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11696269093170011678
+          9645881182143954138
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumamode_565.png": {
       "allowed-digests": [
@@ -8076,7 +8520,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14753870890166488787
+          13546074453897362674
         ]
       ], 
       "reviewed-by-human": true
@@ -8085,7 +8529,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12332409505555151686
+          2645433785253737964
         ]
       ], 
       "reviewed-by-human": true
@@ -8094,7 +8538,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12919974392613482745
+          4116381614494335362
         ]
       ], 
       "reviewed-by-human": true
@@ -8103,7 +8547,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12919974392613482745
+          4116381614494335362
         ]
       ], 
       "reviewed-by-human": true
@@ -8172,7 +8616,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12842668762277630465
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8181,7 +8625,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1883413208707995739
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8214,7 +8658,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12842668762277630465
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8223,7 +8667,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1883413208707995739
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8256,7 +8700,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12842668762277630465
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8265,7 +8709,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1883413208707995739
+          940913407237519059
         ]
       ], 
       "reviewed-by-human": true
@@ -8292,7 +8736,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16535785180897049372
+          17906316606932287523
         ]
       ], 
       "reviewed-by-human": true
@@ -8335,19 +8779,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15954233068969828611
+          10690075085961116152
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15954233068969828611
+          10690075085961116152
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
@@ -8385,6 +8831,366 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1799022373381634937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16072650776783849785
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16949296854614739341
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16870762334260965145
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10168290996640020029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17974959293136356721
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7647115313085356918
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18294645664025061405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6876146362791096301
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          672013974639373790
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          407121617914140822
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17107111279642959699
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13019697501260947975
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14977913019013260327
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5641947831670404346
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          937225195420941057
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16646836410262782197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18100820390850075519
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2574095166522288827
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8955432419196193693
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -8575,7 +9381,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15293668784585893125
+          4656886197492028969
         ]
       ], 
       "reviewed-by-human": true
@@ -8584,7 +9390,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17470748697630737319
+          10009949554846362902
         ]
       ], 
       "reviewed-by-human": true
@@ -8593,7 +9399,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8013314903160673417
+          16425393435205920402
         ]
       ], 
       "reviewed-by-human": true
@@ -8602,7 +9408,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14816111461423147722
+          16688770112471467177
         ]
       ], 
       "reviewed-by-human": true
@@ -8635,19 +9441,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          6176209756741778646
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          6176209756741778646
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -8671,10 +9479,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1219491329735674349
+          3849340549236541887
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "ovals_msaa4.png": {
       "allowed-digests": [
@@ -8686,6 +9495,78 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12854990838652667931
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16478730915407089386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11115688412167805107
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4893664413873629107
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -8714,7 +9595,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13767201167892001999
+          14746240212910087597
         ]
       ], 
       "reviewed-by-human": true
@@ -8756,7 +9637,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14555493949249922058
+          10102068867409260207
         ]
       ], 
       "reviewed-by-human": true
@@ -8964,7 +9845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          477994727837130729
+          8959682453711286650
         ]
       ], 
       "reviewed-by-human": true
@@ -9018,7 +9899,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -9027,7 +9908,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -9036,17 +9917,53 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4777066890322501677
+          16202756285536072592
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8190195795812546474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8190195795812546474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7592079403906379683
+          16202756285536072592
         ]
       ], 
       "ignore-failure": false, 
@@ -9088,6 +10005,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11523502336595345447
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -9124,6 +10077,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -9172,7 +10161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18000254716935645999
+          13710370929503896242
         ]
       ], 
       "reviewed-by-human": true
@@ -9181,7 +10170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16383033135480419663
+          14868659503042841956
         ]
       ], 
       "reviewed-by-human": true
@@ -9190,7 +10179,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7284761092876246188
+          10839024960221357604
         ]
       ], 
       "reviewed-by-human": true
@@ -9199,7 +10188,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11519978157451678721
+          4353301731847242860
         ]
       ], 
       "reviewed-by-human": true
@@ -9226,25 +10215,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16113518265745121824
+          11943929872177488726
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "polygons_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13042174351117973323
+          18412169674810091291
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16422530932852428674
+          2214368729624239628
         ]
       ], 
       "reviewed-by-human": true
@@ -9253,7 +10242,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13797585911734062488
+          13695847048236137972
         ]
       ], 
       "reviewed-by-human": true
@@ -9262,7 +10251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14655234950067739505
+          12911950575835675253
         ]
       ], 
       "reviewed-by-human": true
@@ -9271,7 +10260,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16247577806145016641
+          12770899583726255744
         ]
       ], 
       "reviewed-by-human": true
@@ -9280,7 +10269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13221078215540522692
+          6757078992106948579
         ]
       ], 
       "reviewed-by-human": true
@@ -9289,7 +10278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7149831205496297560
+          24796932854446382
         ]
       ], 
       "reviewed-by-human": true
@@ -9298,7 +10287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17577789094752396345
+          15761539880746862400
         ]
       ], 
       "reviewed-by-human": true
@@ -9307,7 +10296,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10381960982730511552
+          10004632522250129097
         ]
       ], 
       "reviewed-by-human": true
@@ -9332,17 +10321,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1214323161004682693
+          2345997695698587496
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "radial_gradient2_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          517817170355194916
+          13265214489338924633
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_565.png": {
       "allowed-digests": [
@@ -9372,19 +10363,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8572585790542700888
+          9371573623541139881
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8572585790542700888
+          9371573623541139881
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -9408,7 +10401,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4961203383083962998
+          1197889143489694088
         ]
       ], 
       "reviewed-by-human": true
@@ -9476,7 +10469,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4404268085170872926
+          1238816738306779698
         ]
       ], 
       "reviewed-by-human": true
@@ -9602,7 +10595,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5421265310411119471
+          4652843928975001956
         ]
       ], 
       "reviewed-by-human": true
@@ -9674,10 +10667,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          737317753319305404
+          1288562748996894577
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rrect_draw_aa_msaa4.png": {
       "allowed-digests": [
@@ -9746,7 +10739,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10207186591028010237
+          2155978747761042485
         ]
       ], 
       "reviewed-by-human": true
@@ -9890,7 +10883,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8301470970114807246
+          11838132127013699928
         ]
       ], 
       "reviewed-by-human": true
@@ -9899,7 +10892,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1089343327835502505
+          15717961650619683621
         ]
       ], 
       "reviewed-by-human": true
@@ -9926,7 +10919,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8987936749168597901
+          15930720713777284476
         ]
       ], 
       "reviewed-by-human": true
@@ -9935,7 +10928,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8987936749168597901
+          15930720713777284476
         ]
       ], 
       "reviewed-by-human": true
@@ -10097,7 +11090,8 @@
           13223903649982789417
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "shadows_msaa4.png": {
       "allowed-digests": [
@@ -10334,7 +11328,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8130019868850205893
+          17911005775522481791
         ]
       ], 
       "reviewed-by-human": true
@@ -10440,9 +11434,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14248208315278090286
+          16076861668720652969
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "skbug1719_msaa4.png": {
       "allowed-digests": [
@@ -10457,7 +11452,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14585555250092963383
+          13909757336310240518
         ]
       ], 
       "reviewed-by-human": true
@@ -10466,7 +11461,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6423558589708144215
+          17885518595384354919
         ]
       ], 
       "reviewed-by-human": true
@@ -10493,7 +11488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11744373400809739356
+          11699531654048406518
         ]
       ], 
       "reviewed-by-human": true
@@ -10502,7 +11497,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8270526029969251327
+          4523091657809672686
         ]
       ], 
       "reviewed-by-human": true
@@ -10511,7 +11506,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1380374968369111790
+          11932325483223150611
         ]
       ], 
       "reviewed-by-human": true
@@ -10520,7 +11515,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1380374968369111790
+          4758860195708070393
         ]
       ], 
       "reviewed-by-human": true
@@ -10628,7 +11623,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11725101012616316052
+          6137491411888461050
         ]
       ], 
       "reviewed-by-human": true
@@ -10796,7 +11791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12416137150818188702
+          6800887868791302499
         ]
       ], 
       "reviewed-by-human": true
@@ -10814,7 +11809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10230426069067413407
+          18286981917824090179
         ]
       ], 
       "reviewed-by-human": true
@@ -10823,7 +11818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15098401526248766364
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -10832,7 +11827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16598261928768030936
+          11625837403190001764
         ]
       ], 
       "reviewed-by-human": true
@@ -10841,7 +11836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14551311725473456993
+          3753618903036190582
         ]
       ], 
       "reviewed-by-human": true
@@ -10892,7 +11887,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15528863190484305841
+          1369006746513120542
         ]
       ], 
       "reviewed-by-human": true
@@ -10901,7 +11896,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15197842121034928067
+          10584886924228958226
         ]
       ], 
       "reviewed-by-human": true
@@ -10910,10 +11905,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7549641138224830904
+          4597062943976028698
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "testimagefilters_msaa4.png": {
       "allowed-digests": [
@@ -10966,6 +11962,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          163112871246100159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -11006,19 +12038,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3355189550605099479
+          1542449700616506808
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3355189550605099479
+          1542449700616506808
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -11045,7 +12077,8 @@
           10999541404612369092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa4.png": {
       "allowed-digests": [
@@ -11081,7 +12114,8 @@
           1946366533119786586
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa4.png": {
       "allowed-digests": [
@@ -11096,7 +12130,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17022932193658353157
+          15732727687033594466
         ]
       ], 
       "reviewed-by-human": true
@@ -11105,7 +12139,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -11114,7 +12148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -11123,7 +12157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -11222,7 +12256,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5051951153050201080
+          15432201581929914329
         ]
       ], 
       "reviewed-by-human": true
@@ -11231,7 +12265,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          525633548833083339
+          15270349007635227054
         ]
       ], 
       "reviewed-by-human": true
@@ -11258,7 +12292,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7249864038792229190
+          8293716677305839949
         ]
       ], 
       "reviewed-by-human": true
@@ -11267,7 +12301,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7249864038792229190
+          8293716677305839949
         ]
       ], 
       "reviewed-by-human": true
@@ -11460,6 +12494,150 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683867137211693534
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11064306957043870693
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683867137211693534
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11064306957043870693
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16282339837156485923
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2548812463070281529
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16282339837156485923
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2548812463070281529
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -11608,7 +12786,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3394570787947912684
+          3112652115716203250
         ]
       ], 
       "reviewed-by-human": true
@@ -11617,7 +12795,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4231863532718175149
+          12938112915997113104
         ]
       ], 
       "reviewed-by-human": true
@@ -11626,7 +12804,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8487916907396584951
+          1512989932016141784
         ]
       ], 
       "reviewed-by-human": true
@@ -11635,7 +12813,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8487916907396584951
+          1512989932016141784
         ]
       ], 
       "reviewed-by-human": true
@@ -11662,7 +12840,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10006734138077464282
+          3259542057496795230
         ]
       ], 
       "reviewed-by-human": true
@@ -11671,7 +12849,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9458503948962017865
+          17330165520408407412
         ]
       ], 
       "reviewed-by-human": true
@@ -11734,7 +12912,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2651990224646434968
+          12373255510807920217
         ]
       ], 
       "reviewed-by-human": true
@@ -11743,10 +12921,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6135004858351118478
+          14037617966684837344
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14593717200149920625
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14593717200149920625
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-Nexus4-Adreno320-Arm7-Release/expected-results.json b/expectations/gm/Test-Android-Nexus4-Adreno320-Arm7-Release/expected-results.json
deleted file mode 100644
index f664d73..0000000
--- a/expectations/gm/Test-Android-Nexus4-Adreno320-Arm7-Release/expected-results.json
+++ /dev/null
@@ -1,9463 +0,0 @@
-{
-  "expected-results": {
-    "3x3bitmaprect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16998423976396106083
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "3x3bitmaprect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2054956815327187963
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "3x3bitmaprect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2054956815327187963
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "aaclip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5680982666881858509
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "aaclip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3732865537665519508
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "aaclip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4834500295502840348
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "aarectmodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14760033689012826769
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "aarectmodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13739372576644267630
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "aarectmodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7778842390739990811
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "alphagradients_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1062660886109823876
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "alphagradients_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8685680158225267849
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "alphagradients_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          249568195177528755
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "android_paint_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17812352573841872614
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "android_paint_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11374118262664303352
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "android_paint_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16578618981524164940
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "arcofzorro_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13786535001616823825
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "arcofzorro_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8666021583927870678
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "arcofzorro_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5103413628089441416
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "arithmode_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8827950106908644173
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "arithmode_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1951236732185589783
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "arithmode_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16119411048162915342
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bezier_conic_effects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14690535209962836585
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bezier_cubic_effects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          258516539966628223
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bezier_quad_effects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6408009309113804039
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12488185918270960759
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigblurs_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2422083043229439955
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigblurs_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17309852422285247848
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigblurs_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15262453002939091927
-        ]
-      ], 
-      "bugs": [
-        2528
-      ], 
-      "ignore-failure": true, 
-      "reviewed-by-human": false
-    }, 
-    "bigmatrix_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10240571881937710202
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigmatrix_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14225434535210388132
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigmatrix_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11312341834140573842
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigtext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9363175749442909647
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigtext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8357897490332471314
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bigtext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14992614689880273626
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmap_premul_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3459248890389921752
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmap_premul_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1875487390803094182
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmap_premul_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1875487390803094182
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapfilters_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15577847810878117619
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapfilters_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16537885423072386302
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapfilters_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7099981478239046398
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmaprect_i_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15954400542104295064
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_i_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1263164671174760260
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_i_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15749658617332094331
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_s_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15954400542104295064
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_s_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1263164671174760260
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprect_s_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15749658617332094331
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprecttest_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5432165152598403513
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprecttest_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5432165152598403513
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmaprecttest_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1454528164630516875
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapscroll_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2235975214838086978
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapscroll_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2020710583966674615
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapscroll_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          930590022062657844
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bitmapshaders_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12003105459052744890
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapshaders_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          23481610040948036
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapshaders_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12179263968956328984
-        ]
-      ], 
-      "bugs": [
-        2293
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapsource_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15581542612528711266
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapsource_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13071585613760610277
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bitmapsource_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          400977977058761258
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bleed_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5804278196362313921
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bleed_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10874368221386742934
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bleed_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8780149372826681087
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurcircles_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17148910878401545731
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurcircles_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6067714883605508534
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurcircles_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11635423331580981373
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurquickreject_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14575894174086753692
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurquickreject_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1951057418144050940
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurquickreject_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8292097632245464218
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7937640658770483101
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3184582570657056326
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3184582570657056326
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2980156820919596497
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5778991912674004218
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5778991912674004218
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2538610438575582155
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16776390169922007578
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16776390169922007578
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13515504142273854629
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10179579145235258409
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10179579145235258409
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          979535589726215668
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16043278436798717097
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16043278436798717097
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          469891400263202822
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          795828165830353598
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          795828165830353598
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11641473617599999419
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8459602697994167638
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8459602697994167638
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2497946753949588222
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14526183591501064820
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14526183591501064820
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11877010048399988714
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2027939861397155283
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2027939861397155283
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10672373549329653561
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16228083818774745601
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16228083818774745601
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11787269131518922484
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11235472972448689767
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11235472972448689767
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17766756600887659495
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3014025170376903742
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3014025170376903742
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15006337376019039104
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8450430456683814098
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8450430456683814098
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13488428611470317575
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6934363565052222509
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6934363565052222509
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2662024595823670226
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6260375605261477035
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6260375605261477035
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6430918336013269123
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          685229733900948221
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          685229733900948221
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2703515622849643953
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8078454220178362362
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8078454220178362362
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16620284574674851854
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          805644383472349129
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          805644383472349129
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1854592748881346557
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8586295779506545029
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8586295779506545029
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6494357978488384985
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10060482719496990794
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10060482719496990794
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2768527762178886297
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10705231956829285301
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10705231956829285301
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9556862863752256436
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15258994592739155032
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15258994592739155032
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12910036470964562372
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14266854668713428040
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14266854668713428040
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10635770833288139564
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7552003167091473918
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7552003167091473918
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8689938548045974643
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17796133053007318503
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17796133053007318503
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8689938548045974643
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4056266015657707537
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4056266015657707537
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8689938548045974643
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17802184554241704666
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17802184554241704666
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8689938548045974643
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5373137501337162900
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5373137501337162900
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8689938548045974643
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8793723769315696288
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8793723769315696288
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8689938548045974643
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3351391123811424042
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3351391123811424042
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8302766638569272530
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8753902296095062956
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8753902296095062956
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11936654946112556152
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5736147449766359017
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5736147449766359017
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2373554527744690058
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3606241125593407269
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3606241125593407269
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4682955924562239319
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15504874507306860669
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15504874507306860669
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11460116042811593798
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5438277324777890642
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5438277324777890642
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12181747588025565695
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15858720212484315695
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15858720212484315695
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13080629583390552103
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11980986810369723513
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18253719462566450522
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurroundrect-WH[100x100]-unevenCorners_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5849651065413553680
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurroundrect-WH[100x100]-unevenCorners_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4619759825939595617
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurroundrect-WH[100x100]-unevenCorners_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6642232162121933341
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurs_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6827358016184068480
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurs_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18214876018436421527
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurs_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16764988930995149135
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "canvas-layer-state_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12670698167582780333
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "canvas-layer-state_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12670698167582780333
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "canvas-state_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11592955199341201053
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "canvas-state_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11592955199341201053
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "canvas-state_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5541967782360980927
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext1_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6708894799496057436
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext1_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6708894799496057436
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext1_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6708894799496057436
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13774733025575034199
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13774733025575034199
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "chrome_gradtext2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7116408385747031060
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circles_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3041043330243503378
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circles_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9296850955490059248
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circles_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12963960118217928020
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circular-clips_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5152108745492225309
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circular-clips_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5152108745492225309
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "circular-clips_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1988347527319338472
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clamped_gradients_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6740406662310759992
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clamped_gradients_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12600235552582834170
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clamped_gradients_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3828862583467184095
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp-hq_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5543970311616574408
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp-hq_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9243927175489158803
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp-hq_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4002879225250347684
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6731999058828201370
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6731999058828201370
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-clamp_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6731999058828201370
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror-hq_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14000830941634575767
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror-hq_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14412729226029504152
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror-hq_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5631913109279460988
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10131313151475985201
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10131313151475985201
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-mirror_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10131313151475985201
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile-hq_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5937007347321497195
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile-hq_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6655127558305687514
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile-hq_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10940051680257625059
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          25307406092894825
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          25307406092894825
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clipped-bitmap-shaders-tile_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          25307406092894825
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clippedcubic_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2047816653827409443
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clippedcubic_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2047816653827409443
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "clippedcubic_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6010362627338084613
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cmykjpeg_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13052709698662664204
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "cmykjpeg_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9927483517871541702
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "cmykjpeg_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9927483517871541702
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colorfilterimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17051103650973594106
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colorfilterimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1025940906896326990
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colorfilterimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2061614246926476221
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colormatrix_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3235581033534814469
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colormatrix_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5008998920935758481
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colormatrix_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7201496349565256049
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colortype_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7322753158848112633
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colortype_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13587257461703619696
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "colortype_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2386152686556935098
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1971136545200141017
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7558229948134696044
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7558229948134696044
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_path_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16086429144316222800
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_path_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12832097210600987517
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_path_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11490765877564985529
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_path_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13497374237280200272
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_path_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13907447324398926215
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_path_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6767202152973974411
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rect_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4388703640234091457
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rect_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6840582159469938207
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rect_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11709014768122709362
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_rrect_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11609605102436644365
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_rrect_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6484021739759757221
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_rrect_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10546564699546205411
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip2_rrect_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13632122222988723717
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rrect_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14609392979961079625
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_rrect_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7607167258483373168
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2035525753977535256
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12559465164864479162
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7358555905763201928
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_layer_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3306730904107685940
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_layer_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13591877655871515458
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_layer_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13408156583590041760
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6310901099269765196
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2511666966287866166
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9870707006952451670
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_layer_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17159080850865344792
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_layer_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2302717591157402628
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_layer_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5176667371385901463
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "composeshader_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4616535333272790055
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "composeshader_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7653047818906774476
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "composeshader_alpha_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2785143308349902483
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "composeshader_alpha_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3069347792056802140
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "composeshader_alpha_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13415066704472475041
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "composeshader_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13476719363156020502
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "convex_poly_clip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3742871756784050961
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "convex_poly_clip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14394590208816375119
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "convex_poly_clip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5297539228443187427
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "convex_poly_effect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9295659414181314501
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "convexpaths_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18327995834040812041
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "convexpaths_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          457069184203133078
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "convexpaths_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16987735369546175545
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "copyTo4444_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13047964648578320887
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "copyTo4444_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13512184095617016052
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "copyTo4444_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13512184095617016052
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "cubicclosepath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12345522437202727374
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicclosepath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17912401236231679127
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicclosepath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4407767759255340842
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicpath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11191728978684557482
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicpath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9058335517377211817
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "cubicpath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15880316531252693614
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dashcubics_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14579960821593575197
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashcubics_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17019125613404625792
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashcubics_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7060845763217753003
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2494610485041198535
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5568370216546802477
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          491154211623518706
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing3_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12022711034501498873
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing3_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9992031980990536415
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing3_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6427104955877219419
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dashing4_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14433773091096403168
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dashing4_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10873004693785991483
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dashing4_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6278497568528421897
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dashing_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14912539765453208522
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11645276935331048518
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "dashing_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2637106900149052753
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "degeneratesegments_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1940009043017990568
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "degeneratesegments_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11122804881221782538
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "degeneratesegments_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3875243706575375716
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "deviceproperties_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17799487143319424536
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "deviceproperties_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1020763452380907607
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "discard_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11635187478196931850
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "displacement_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10557537838778749160
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "displacement_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7089896533323038526
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "displacement_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6994945621426128555
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "distantclip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2455115578822786504
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "distantclip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2455115578822786504
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "distantclip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2455115578822786504
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_high_512_256_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15154730871764821124
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_checkerboard_high_512_256_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          194619977446273533
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_checkerboard_high_512_256_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9753614989636915824
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_checkerboard_low_512_256_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10232582998248890344
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_low_512_256_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1233814311003427744
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8044171070473798324
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_medium_512_256_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1203257848312793050
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3984265676088058160
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9753614989636915824
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_none_512_256_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6989712392624471913
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_none_512_256_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10855232109519818829
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6096625630775082776
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_high_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17264975515988900071
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_image_high_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3911174280407842684
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_image_high_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8358902968682749303
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_image_low_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6765275404189723366
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6485054271692420021
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14204452381545620746
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13571956230133077991
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8840752418158714253
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8358902968682749303
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_none_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2497837460215148124
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13192464168020553898
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14063480206491490964
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "downsamplebitmap_text_high_72.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16519436267890610369
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_high_72.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11825439513932272119
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_high_72.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10904087299234981169
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_low_72.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14912104351264232935
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_low_72.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15487921510411770637
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_low_72.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9117643962511052605
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_medium_72.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10684547795556100510
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_medium_72.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7577014624371342379
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_medium_72.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15385694394456194958
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_none_72.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10237388909415541908
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_none_72.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2858581709660741041
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "downsamplebitmap_text_none_72.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16252566948450263228
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drawbitmapmatrix_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13106701293308057590
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "drawbitmapmatrix_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16912290287677763264
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "drawbitmapmatrix_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15371575219017467192
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "drawlooper_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16880886031490071742
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drawlooper_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          428119157032316167
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drawlooper_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          203762582004180365
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dropshadowimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7416446637660374210
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dropshadowimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13313875175804070508
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "dropshadowimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2181808913183233869
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "drrect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3740162382031499255
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "drrect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7505650564332324157
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "drrect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8305223338397272588
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "emptypath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5887470903797208725
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "emptypath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16729138449439522348
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "emptypath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8740619907670856259
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15855537393781495131
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10396043285211938891
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10396043285211938891
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_ktx_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10660132459335344948
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_ktx_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17338451294848191155
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_ktx_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17338451294848191155
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_npot_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4755621039067033683
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_npot_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9352463391366748675
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_npot_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9352463391366748675
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_pkm_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10660132459335344948
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_pkm_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17338451294848191155
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_pkm_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17338451294848191155
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "extractbitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10931473040653078858
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "extractbitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10931473040653078858
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "extractbitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10931473040653078858
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "factory_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4768741511907258218
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "factory_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11150486540244810089
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "factory_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11150486540244810089
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fatpathfill_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7781767658511133788
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fatpathfill_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15926472232550846517
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fatpathfill_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5196197600261907918
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1160039999451806268
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9755437692677243946
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2587801139190028480
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypespersp_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14894017545918091807
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypespersp_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7410424049029296878
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filltypespersp_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7037108715901603128
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_192_192_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11849479847158189672
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_192_192_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5598960819970570537
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_192_192_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5345582652871648495
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2960178481215162337
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4450718444101780683
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6672198569426452298
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_checkerboard_32_32_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13403191811040300266
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_32_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13640210300978315176
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_32_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3334041031604606874
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_checkerboard_32_8_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2841712854914200171
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_8_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18006484729950247920
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_32_8_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2122017758048304487
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_checkerboard_4_4_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9253425473221951017
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_4_4_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7196879659919462842
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_checkerboard_4_4_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9727599448817163517
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_image_mandrill_128.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3818470414665025673
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_128.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6458389215599169812
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_128.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1345397821316727542
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_image_mandrill_16.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8734759244377509313
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_16.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16189637050029803867
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_16.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1416345281623416523
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_image_mandrill_256.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2558252763680580376
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_256.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          314376617607170618
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_256.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10082929265978245599
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_image_mandrill_32.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3241890450402571997
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_32.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18261351407702936062
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_32.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2502904745789888859
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_image_mandrill_512.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6683720920985855313
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_image_mandrill_512.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1125681780471010403
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_image_mandrill_512.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14422714158002139047
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_image_mandrill_64.png_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14201938350237123162
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_64.png_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13817564933175934896
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_image_mandrill_64.png_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6200800593359404308
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "filterbitmap_text_10.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          33986293470780328
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_10.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18157626535966948982
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_10.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10784446786087633900
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_3.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7289467627965448716
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_3.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3926971490478181787
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_3.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3991561479472368628
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_7.00pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14643066968979788941
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_7.00pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3363453308488752313
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "filterbitmap_text_7.00pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8552148705074963587
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "fontcache_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          994935463198632465
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "fontmgr_iter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_iter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_iter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_match_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_match_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_match_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontscaler_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8822685363675334860
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "fontscaler_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6043856383647232157
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "fontscaler_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8813823881613026115
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gammatext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9981410297050803682
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gammatext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12924368150056635888
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gammatext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13572098499379143438
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "getpostextpath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6055708031509552175
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "getpostextpath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8346234615044725182
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "getpostextpath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17005825839359521305
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "giantbitmap_clamp_bilerp_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8844253733895577971
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          373739036198791129
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8112152499985052384
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3486485929104356236
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10633738215712183989
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_bilerp_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8430366169989348557
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17592263249674059658
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17592263249674059658
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17664227249162604428
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9837143541713078189
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9837143541713078189
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_clamp_point_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9837143541713078189
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4418651112090392588
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12707263608068309424
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3373048891778268599
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3198037782278889365
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6252132392610996150
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_bilerp_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4487809511991243437
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7897959591317755434
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7897959591317755434
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12270897651601903070
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18105452151182268887
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18105452151182268887
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_mirror_point_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18105452151182268887
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14124862738846038338
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18058439211441456286
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10221881734083134060
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3467547098277083272
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17571397130661778041
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_bilerp_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6434436505279098745
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_rotate_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9093746103412643649
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_rotate_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9093746103412643649
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_rotate_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7372779768318507780
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_scale_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14547059667322106211
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_scale_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14547059667322106211
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "giantbitmap_repeat_point_scale_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14547059667322106211
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_dirty_laundry_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16978210180572955621
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_dirty_laundry_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          637854104407104115
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_dirty_laundry_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10507251147319950569
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_matrix_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9800597089191342482
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_matrix_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11303638772874009054
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradient_matrix_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14477148031683291493
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_edge_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11073979394505631674
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_edge_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2886762409915472022
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_edge_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14123074605417440290
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_inside_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2230084888912360694
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_inside_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7465934387832943420
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_inside_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11510630091444160659
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_outside_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16953788240617605317
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_outside_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17033624275484244376
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_2pt_conical_outside_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13911362926596692
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12097193819749785352
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15403609442106846169
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_degenerate_2pt_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2419426995212058042
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_degenerate_2pt_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6029254312400609793
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_degenerate_2pt_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11233985797286739496
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7955310992779650969
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_local_perspective_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3955747071082596728
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_local_perspective_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10472560090813482435
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_local_perspective_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12252979001720125360
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_many_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7893853359175854146
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_many_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5219979658561439244
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_many_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17107968724208723172
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "gradients_no_texture_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          225020687293424504
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_no_texture_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11527542446888766490
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_no_texture_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13177731101421450081
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_view_perspective_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3351550727216338875
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_view_perspective_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4762618020579508996
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradients_view_perspective_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13386502562674133801
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradtext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9297095911910169239
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradtext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5771478138095675386
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "gradtext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15574593963961481812
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "hairlines_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3746404902639900755
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hairlines_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13269473576016756464
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hairlines_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2962020151157269156
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "hairmodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1085590255436271494
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hairmodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1802514640949456155
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hairmodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8677080270533683993
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hittestpath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11711016279383188197
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hittestpath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14807718233642576408
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hittestpath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11931398909998950167
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "image-surface_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13996060058040131634
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "image-surface_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7410839535321428153
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "image-surface_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11461830496962761905
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagealphathreshold_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9262312764539834132
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imagealphathreshold_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7434810293688860099
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imagealphathreshold_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7434810293688860099
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imageblur_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3576279505219183019
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8692857562686154753
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17797568728257858573
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_large_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10777355457185638337
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_large_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13071282510990956080
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_large_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14715461394634766316
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblurtiled_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16654054210158593753
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblurtiled_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2843556688273725953
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblurtiled_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17761515447235669868
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersbase_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4403916508561740668
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersbase_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2169481878270022443
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersbase_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9782073632467081036
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersclipped_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8498778868685964382
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imagefiltersclipped_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          880034339526468883
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "imagefiltersclipped_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11335639414083835017
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefilterscropped_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17735192342007451132
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefilterscropped_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4966754436744417482
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefilterscropped_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8797890792514086240
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersgraph_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4935800023393625832
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersgraph_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1510287820165086493
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersgraph_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3249705975497923432
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagefiltersscaled_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3846565992437209770
-        ]
-      ]
-    }, 
-    "imagefiltersscaled_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16797253953584829082
-        ]
-      ]
-    }, 
-    "imagefiltersscaled_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13272858034079482084
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagemagnifier_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14625944923053341670
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagemagnifier_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1901521361109987395
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imagemagnifier_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10861701182667580883
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageresizetiled_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11537830680807011411
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageresizetiled_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2840733308476616973
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "imageresizetiled_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2840733308476616973
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "internal_links_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17273967085043866153
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "internal_links_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11751433989801294344
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "internal_links_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13900375946366690268
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "inverse_paths_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18373794772311086000
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "inverse_paths_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6619571412969335764
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "inverse_paths_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16833589819863475738
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lcdtext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14643161545794817643
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lcdtext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1511393143767092759
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lcdtext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1511393143767092759
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lerpmode_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12271636760963423766
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lerpmode_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11952378473714520027
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lerpmode_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3391919152857140005
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lighting_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6728484050681732905
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lighting_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3122543961009401649
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lighting_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9697510406290295114
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lightingcolorfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7968186755331229682
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lightingcolorfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1516320293275754779
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lightingcolorfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7556478305846361566
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lineclosepath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2569157419236777949
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lineclosepath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1370520776657521517
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lineclosepath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14351036907860663618
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "linepath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16518858492509120064
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "linepath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15238792371190456534
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "linepath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9343804110836898394
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "lumafilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7104435648687592254
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lumafilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18100962139592302037
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "lumafilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13861401015232083062
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "matrixconvolution_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3101476576521947165
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "matrixconvolution_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10055081768235896808
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "matrixconvolution_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1350439713947208131
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "matriximagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14072014607244294525
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "matriximagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18093313968129673224
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "matriximagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3030196161215824937
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_0x0_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          899343682044846669
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_0x0_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4811817245879819217
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_0x0_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17553587858062838425
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "megalooper_1x4_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          899343682044846669
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_1x4_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4811817245879819217
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_1x4_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17553587858062838425
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "megalooper_4x1_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          899343682044846669
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_4x1_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4811817245879819217
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "megalooper_4x1_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17553587858062838425
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "mixed_xfermodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1539651103309648647
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "mixed_xfermodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14918941537433499795
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "mixed_xfermodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10531722056214126451
-        ]
-      ], 
-      "bugs": [
-        1596
-      ], 
-      "ignore-failure": true, 
-      "reviewed-by-human": true
-    }, 
-    "modecolorfilters_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2595933616904054518
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "modecolorfilters_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5532792141023246970
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "modecolorfilters_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11934469864526604734
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "morphology_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13276990043616594793
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "morphology_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12053534281222176521
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "morphology_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15869818052487928163
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "nested_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16123340172201812866
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nested_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15356581678046831315
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nested_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2638906430515983326
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nested_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1642884649618332584
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nested_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2247784507927793592
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nested_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6638289994984814421
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ninepatch-stretch_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2353651351546903350
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ninepatch-stretch_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12454353570070316868
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ninepatch-stretch_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18050122059109328370
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "nonclosedpaths_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11279780315114260398
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nonclosedpaths_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1265866929190406854
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "nonclosedpaths_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15507167805925596819
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "offsetimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15240835456320409473
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "offsetimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          249289862803617115
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "offsetimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15497506993121739956
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "optimizations_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13857521313271479795
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "optimizations_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13857521313271479795
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ovals_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4956630750436269799
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ovals_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14188637820577652361
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "ovals_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15539157422757135778
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "path-reverse_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18264085885951369494
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "path-reverse_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6845561371571987961
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "path-reverse_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3236205967252504838
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "patheffect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4427938030923047423
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "patheffect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4547654274603880457
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "patheffect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1092686924736574858
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathfill_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10238641571996885423
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathfill_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1120308788076075072
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathfill_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10348248682413334541
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathinterior_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15564974755024712566
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathinterior_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6224212202381569470
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathinterior_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7587513741148937952
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathinvfill_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8118219865348031190
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathinvfill_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7771083304049147305
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathinvfill_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5029407105525423667
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathopsinverse_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17617505767021323437
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathopsinverse_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11577432472710705185
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathopsinverse_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10465138288252168039
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pathopsskpclip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2904824217886262883
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathopsskpclip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6847070945713556374
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "pathopsskpclip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11084457427150731223
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "peekpixels_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14531156101283739799
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "peekpixels_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7937779188195651413
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "peekpixels_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2668596768018443187
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "perlinnoise_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16968168405481699903
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "perlinnoise_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1098763191610264229
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "perlinnoise_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5910660068342021532
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15710121230086435602
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1763586683528188858
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1763586683528188858
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureshader_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12994511397188975534
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureshader_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18060131563380789045
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "pictureshader_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6480312308420165751
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "points_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9418063666161005464
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "points_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9418063666161005464
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "points_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16211895599394737932
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "poly2poly_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6571118611946058617
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "poly2poly_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2985268228390879272
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "poly2poly_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4090908000301047480
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "polygons_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11517709488632152524
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "polygons_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4804961199935719320
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "polygons_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17918044004945956042
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "quadclosepath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9971396627985154706
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadclosepath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6891379388563692035
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadclosepath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7133096296319789026
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadpath_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1288004664951630498
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadpath_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7223243377781866680
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "quadpath_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12191681455930613784
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "radial_gradient2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11394637011745804615
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11455010006792010801
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17294523260520684759
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10067107685325019703
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15369886492036014971
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "radial_gradient_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14470264741921611599
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16802558787635856000
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5173940140316611618
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16787331154477637635
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "resizeimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11574452324482789141
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "resizeimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15004076002839832883
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "resizeimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14431908552565411545
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "roundrects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10192478482016992029
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "roundrects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16060307579559364278
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "roundrects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4328782957090497633
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9108911139001347487
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14795654963615468231
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14570932930676169469
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6506138814340064770
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5457090617640236110
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1500157245784304324
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6810446943823350860
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3764224183150533222
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2598431657762879570
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16466610707606959589
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11436925749408943089
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5677622882171244043
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16102744790083806869
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_clip_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2639533157784794570
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_draw_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2598431657762879570
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16466610707606959589
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3711852771533671325
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5677622882171244043
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16102744790083806869
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_draw_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2639533157784794570
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_effect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2310215659204296151
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "rrect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16239303488141694764
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "samplerstress_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11062223404183756877
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "samplerstress_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12850560549198663520
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "samplerstress_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5470149947701693909
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_bitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1410103792220800931
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_bitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2293107890848557380
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_bitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12802535321257469607
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_gradient_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5067627966950621939
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_gradient_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7517125506221018662
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemode_gradient_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7606734424710060898
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9319993179135558393
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16574168428196349390
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3968605136301912973
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_npot_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17418047642108977670
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_npot_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1556868127331379479
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_npot_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14148935305656142180
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "selftest1_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12927999507540085554
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest1_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1209453360120438698
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest1_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1149339852105949057
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8863920166200910451
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13451349865803053525
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "selftest2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7903070799454133570
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shaderbounds_linear_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4739835670329472924
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shaderbounds_linear_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17407206349726255504
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shaderbounds_linear_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9365123651944233851
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shadows_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3556699044314006968
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shadows_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12023275411897178283
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shadows_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5407486909752567765
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_conical_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17982294224537325140
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_conical_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10213220249745462631
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_conical_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16147329029888950793
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "shallow_gradient_linear_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2414118852281882343
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_linear_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2600596201303470577
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_linear_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3271123187213282006
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_radial_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7637358666429963225
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_radial_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12757191687259698018
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_radial_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6129084542466137453
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_sweep_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6974552498637279685
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_sweep_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          766715199662180977
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "shallow_gradient_sweep_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16883506100501459281
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "simpleaaclip_aaclip_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2422870003307313999
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_aaclip_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8297028920093819054
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_aaclip_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16021439723556558918
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_path_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2422870003307313999
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_path_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8505743106500736554
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_path_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6566419177529590403
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_rect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2276755423088781585
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_rect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2247183642119438840
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleaaclip_rect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8484924843781194174
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleblurroundrect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13988021646843375450
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleblurroundrect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7482672038493178391
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "simpleblurroundrect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13014561373059764150
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "skbug1719_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2332391077132553330
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "skbug1719_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13212045663266308489
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "skbug1719_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6564000819756404686
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "spritebitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14585555250092963383
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "spritebitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6423558589708144215
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "spritebitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6074758673205850548
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "srcmode_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17619211944443238901
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "srcmode_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12476337759406055776
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "srcmode_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1838432270932859890
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stringart_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          517466260915157438
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "stringart_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12919217765216356865
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "stringart_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16477903969068168632
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "stroke-fill_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2450726810754127074
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stroke-fill_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12690621371284385511
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stroke-fill_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16688606203531911724
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "strokerect_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15458182862530229195
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokerect_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2467605443292336055
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokerect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17613759578043625526
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokerects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1252564837192523211
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokerects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3590050428307921218
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokerects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10205964363897246069
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes3_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8397039244880318300
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes3_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16717945387368894511
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes3_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18221436202436168043
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_poly_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4939197335393210893
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_poly_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8189110711369465006
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_poly_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6641542521483188265
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_round_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1967359529448596413
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_round_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11874628554314465422
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "strokes_round_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13080561315920218716
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "stroketext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10084807092550654294
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stroketext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15846255821264969272
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "stroketext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1841381969935611676
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tablecolorfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13695771735763792806
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tablecolorfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4361716833575286014
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tablecolorfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17892855770534705304
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "testimagefilters_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15528863190484305841
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "testimagefilters_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15197842121034928067
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "testimagefilters_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5204419253707868565
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "texdata_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1221372586972395156
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "texteffects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11311445240364221126
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "texteffects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9681917212200619788
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "texteffects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9681917212200619788
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "texture_domain_effect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11365388622786306146
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinrects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17949451347125150629
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinrects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12074631820414627784
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinrects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18123780144204716606
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinstrokedrects_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17882028260402842392
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinstrokedrects_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2596255945580270876
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "thinstrokedrects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14598560863929901019
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tileimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15884441815359625883
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tileimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6913371489075702069
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tileimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6913371489075702069
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_bitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1410103792220800931
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_bitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2293107890848557380
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_bitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12802535321257469607
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_gradient_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5067627966950621939
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_gradient_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7517125506221018662
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemode_gradient_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7606734424710060898
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1916052269453883881
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14968443247329529117
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2592756938145874158
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_npot_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8143654303249859581
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_npot_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13298836052288001622
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_npot_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1838655959411055883
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "tinybitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12538857845722393084
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tinybitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11468465429225805
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "tinybitmap_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5633315905476176630
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "twopointconical_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18223584313005621176
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "twopointconical_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6036270199387229964
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "twopointconical_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1045519680717029999
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typeface_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11426788897705172941
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typeface_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3057908372893981204
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typeface_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3057908372893981204
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          714676201649578466
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13370428013149648258
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13370428013149648258
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_kerning_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5443026492957156846
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_kerning_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2080761164861757576
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_kerning_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8882773799933891216
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "vertices_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12016571983635712769
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "vertices_80_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11220339642934269879
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "vertices_80_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5116617595194840746
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "vertices_80_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          567116109091156501
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "vertices_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          753078211441143405
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "vertices_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10272241803718302085
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "verttext2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9457742961471532948
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14527641142409674625
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3597293503861619263
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3820411693075952029
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3587671227602487124
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "verttext_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3897538395660363842
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodeimagefilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10958353996143090911
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodeimagefilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17000878545702467803
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodeimagefilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          167015306588432469
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes2_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4613530689633279630
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes2_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2952493606222488372
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2992781255766374719
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes3_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12480404425423207055
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes3_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14561360239620524377
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes3_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16987219934025015385
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4935026131066456043
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10963470347499254787
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "xfermodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4224918093600621161
-        ]
-      ], 
-      "reviewed-by-human": true
-    }
-  }
-}
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-Nexus4-Adreno320-Arm7-Debug/expected-results.json b/expectations/gm/Test-Android-Nexus5-Adreno330-Arm7-Debug/expected-results.json
similarity index 83%
rename from expectations/gm/Test-Android-Nexus4-Adreno320-Arm7-Debug/expected-results.json
rename to expectations/gm/Test-Android-Nexus5-Adreno330-Arm7-Debug/expected-results.json
index 8e54b14..3ee8efb 100644
--- a/expectations/gm/Test-Android-Nexus4-Adreno320-Arm7-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-Nexus5-Adreno330-Arm7-Debug/expected-results.json
@@ -58,7 +58,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4834500295502840348
+          4051703290108094975
         ]
       ], 
       "reviewed-by-human": true
@@ -91,13 +91,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7778842390739990811
+          11491762121233092989
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -211,7 +208,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8827950106908644173
+          17926029181770873121
         ]
       ], 
       "reviewed-by-human": true
@@ -220,7 +217,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1951236732185589783
+          13062082258702353494
         ]
       ], 
       "reviewed-by-human": true
@@ -229,7 +226,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16119411048162915342
+          16160417814295732631
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -238,7 +262,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14690535209962836585
+          1893525008058911358
         ]
       ], 
       "reviewed-by-human": true
@@ -247,7 +271,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          258516539966628223
+          2193603642080030108
         ]
       ], 
       "reviewed-by-human": true
@@ -261,53 +285,14 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12488185918270960759
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2422083043229439955
+          14704206703218007573
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_8888.png": {
       "allowed-digests": [
@@ -325,14 +310,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15262453002939091927
+          12186349305207417968
         ]
       ], 
-      "bugs": [
-        2528
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -374,37 +356,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9363175749442909647
+          13522834714006056195
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8357897490332471314
+          15371795889574689123
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14992614689880273626
+          15993755133919765308
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmap_premul_565.png": {
       "allowed-digests": [
@@ -446,7 +419,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15577847810878117619
+          6980407574393099333
         ]
       ], 
       "reviewed-by-human": true
@@ -455,7 +428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16537885423072386302
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -464,7 +437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7099981478239046398
+          6408368646738826293
         ]
       ], 
       "reviewed-by-human": true
@@ -581,37 +554,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2235975214838086978
+          2196346147885638539
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2020710583966674615
+          4883607151963013153
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          930590022062657844
+          10338830390467391331
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapshaders_565.png": {
       "allowed-digests": [
@@ -647,7 +611,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15581542612528711266
+          10503127572291510299
         ]
       ], 
       "reviewed-by-human": true
@@ -656,7 +620,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071585613760610277
+          10522304426373074824
         ]
       ], 
       "reviewed-by-human": true
@@ -665,7 +629,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          400977977058761258
+          14364119850332005144
         ]
       ], 
       "reviewed-by-human": true
@@ -698,22 +662,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8780149372826681087
+          6482505834609090342
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17148910878401545731
+          446330175668077197
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurcircles_8888.png": {
       "allowed-digests": [
@@ -761,13 +722,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8292097632245464218
+          14587775113781716416
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrect_25_100_20_inner_fast_565.png": {
       "allowed-digests": [
@@ -2065,17 +2023,41 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13080629583390552103
+          3696341484825569467
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_8888.png": {
       "allowed-digests": [
@@ -2093,13 +2075,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18253719462566450522
+          9641246636600586865
         ]
       ], 
-      "bugs": [
-        2146
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6642232162121933341
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
@@ -2141,7 +2147,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6827358016184068480
+          2150244883739371334
         ]
       ], 
       "reviewed-by-human": true
@@ -2150,7 +2156,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18214876018436421527
+          1470201827989444658
         ]
       ], 
       "reviewed-by-human": true
@@ -2159,7 +2165,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16764988930995149135
+          10660358181509326600
         ]
       ], 
       "reviewed-by-human": true
@@ -2222,73 +2228,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          7950166054919619394
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          7950166054919619394
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          7950166054919619394
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13774733025575034199
+          930789055331505026
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13774733025575034199
+          930789055331505026
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7116408385747031060
+          6698655366271403718
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "circles_565.png": {
       "allowed-digests": [
@@ -2354,13 +2342,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1988347527319338472
+          13930158063852006486
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "clamped_gradients_565.png": {
       "allowed-digests": [
@@ -2393,10 +2378,7 @@
           3828862583467184095
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "clipped-bitmap-shaders-clamp-hq_565.png": {
       "allowed-digests": [
@@ -2711,13 +2693,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2061614246926476221
+          2646827529077989952
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colormatrix_565.png": {
       "allowed-digests": [
@@ -2759,37 +2738,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322753158848112633
+          16101291896048576683
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13587257461703619696
+          6958362917585628191
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2386152686556935098
+          13430579085704011533
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -2852,13 +2822,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11490765877564985529
+          3797306140110758200
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_path_bw_565.png": {
       "allowed-digests": [
@@ -2924,7 +2891,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11709014768122709362
+          3615138553335577401
         ]
       ], 
       "reviewed-by-human": true
@@ -2951,7 +2918,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10546564699546205411
+          9394585766845655876
         ]
       ], 
       "reviewed-by-human": true
@@ -2996,7 +2963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2035525753977535256
+          1787647314443274475
         ]
       ], 
       "reviewed-by-human": true
@@ -3005,7 +2972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12559465164864479162
+          6544536706877310514
         ]
       ], 
       "reviewed-by-human": true
@@ -3014,7 +2981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7358555905763201928
+          14203888972719556254
         ]
       ], 
       "reviewed-by-human": true
@@ -3023,7 +2990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3306730904107685940
+          14933444110384788676
         ]
       ], 
       "reviewed-by-human": true
@@ -3032,7 +2999,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13591877655871515458
+          5836493341538608113
         ]
       ], 
       "reviewed-by-human": true
@@ -3041,7 +3008,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13408156583590041760
+          2268166315101404727
         ]
       ], 
       "reviewed-by-human": true
@@ -3050,7 +3017,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6310901099269765196
+          6492358805688952506
         ]
       ], 
       "reviewed-by-human": true
@@ -3059,7 +3026,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2511666966287866166
+          10152516748782571739
         ]
       ], 
       "reviewed-by-human": true
@@ -3068,7 +3035,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9870707006952451670
+          3437577920781380091
         ]
       ], 
       "reviewed-by-human": true
@@ -3077,7 +3044,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17159080850865344792
+          8180502121217066191
         ]
       ], 
       "reviewed-by-human": true
@@ -3086,7 +3053,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2302717591157402628
+          16993829969091028380
         ]
       ], 
       "reviewed-by-human": true
@@ -3095,7 +3062,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5176667371385901463
+          6154910293993208197
         ]
       ], 
       "reviewed-by-human": true
@@ -3158,7 +3125,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3742871756784050961
+          4792118895672570848
         ]
       ], 
       "reviewed-by-human": true
@@ -3167,7 +3134,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14394590208816375119
+          11285887424651164487
         ]
       ], 
       "reviewed-by-human": true
@@ -3176,7 +3143,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5297539228443187427
+          11238366782850465904
         ]
       ], 
       "reviewed-by-human": true
@@ -3185,7 +3152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9295659414181314501
+          1761288288611240316
         ]
       ], 
       "reviewed-by-human": true
@@ -3266,7 +3233,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12345522437202727374
+          15805712012337691465
         ]
       ], 
       "reviewed-by-human": true
@@ -3275,7 +3242,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17912401236231679127
+          7882161322447216882
         ]
       ], 
       "reviewed-by-human": true
@@ -3284,7 +3251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4407767759255340842
+          10625642201334602406
         ]
       ], 
       "reviewed-by-human": true
@@ -3293,7 +3260,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11191728978684557482
+          2526905513820650564
         ]
       ], 
       "reviewed-by-human": true
@@ -3302,7 +3269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058335517377211817
+          713799816796517938
         ]
       ], 
       "reviewed-by-human": true
@@ -3311,7 +3278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15880316531252693614
+          14332218640581301593
         ]
       ], 
       "reviewed-by-human": true
@@ -3425,7 +3392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14433773091096403168
+          8454109889032154845
         ]
       ], 
       "reviewed-by-human": true
@@ -3443,7 +3410,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6278497568528421897
+          1262614943450883570
         ]
       ], 
       "reviewed-by-human": true
@@ -3452,13 +3419,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912539765453208522
+          2587070015488181148
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dashing_8888.png": {
       "allowed-digests": [
@@ -3476,7 +3440,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2637106900149052753
+          9237020395486912339
         ]
       ], 
       "reviewed-by-human": true
@@ -3485,7 +3449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1940009043017990568
+          14932083482843942713
         ]
       ], 
       "reviewed-by-human": true
@@ -3494,7 +3458,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11122804881221782538
+          7311723676588845146
         ]
       ], 
       "reviewed-by-human": true
@@ -3503,7 +3467,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875243706575375716
+          16335342645475325976
         ]
       ], 
       "reviewed-by-human": true
@@ -3512,7 +3476,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799487143319424536
+          16442079060610240238
         ]
       ], 
       "reviewed-by-human": true
@@ -3521,7 +3485,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1020763452380907607
+          8850017817310905002
         ]
       ], 
       "reviewed-by-human": true
@@ -3539,7 +3503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10557537838778749160
+          4057230872151110302
         ]
       ], 
       "reviewed-by-human": true
@@ -3548,7 +3512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7089896533323038526
+          9482070623821433904
         ]
       ], 
       "reviewed-by-human": true
@@ -3557,7 +3521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6994945621426128555
+          11651015540131061089
         ]
       ], 
       "reviewed-by-human": true
@@ -3566,43 +3530,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -3611,7 +3566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -3620,7 +3575,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9753614989636915824
+          16791319229896708086
         ]
       ], 
       "reviewed-by-human": true
@@ -3629,115 +3584,88 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8044171070473798324
+          3688678278715679643
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9753614989636915824
+          16791319229896708086
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6989712392624471913
+          17775297231868448514
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10855232109519818829
+          12804472649182277577
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6096625630775082776
+          18291808159456495873
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -3746,7 +3674,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -3755,7 +3683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8358902968682749303
+          17252554729222171743
         ]
       ], 
       "reviewed-by-human": true
@@ -3764,115 +3692,88 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14204452381545620746
+          3638140728733337240
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8358902968682749303
+          17252554729222171743
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2497837460215148124
+          6055955940623478607
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13192464168020553898
+          11797865288006977816
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14063480206491490964
+          14270146303385771045
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -3881,7 +3782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
         ]
       ], 
       "reviewed-by-human": true
@@ -3890,7 +3791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10904087299234981169
+          9143885823705622089
         ]
       ], 
       "reviewed-by-human": true
@@ -3899,7 +3800,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          4886211991926050486
         ]
       ], 
       "reviewed-by-human": true
@@ -3908,7 +3809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          8737545656412765906
         ]
       ], 
       "reviewed-by-human": true
@@ -3917,7 +3818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9117643962511052605
+          5280794742313748754
         ]
       ], 
       "reviewed-by-human": true
@@ -3926,7 +3827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -3935,7 +3836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
         ]
       ], 
       "reviewed-by-human": true
@@ -3944,7 +3845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15385694394456194958
+          11941429900712810519
         ]
       ], 
       "reviewed-by-human": true
@@ -3953,7 +3854,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          4707049264800437834
         ]
       ], 
       "reviewed-by-human": true
@@ -3962,7 +3863,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          3175389971476411688
         ]
       ], 
       "reviewed-by-human": true
@@ -3971,7 +3872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16252566948450263228
+          18069542661784516392
         ]
       ], 
       "reviewed-by-human": true
@@ -3980,13 +3881,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -4004,19 +3902,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15371575219017467192
+          9730655672235986353
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16880886031490071742
+          15797039913993285826
         ]
       ], 
       "reviewed-by-human": true
@@ -4025,7 +3920,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          428119157032316167
+          17497164562330387900
         ]
       ], 
       "reviewed-by-human": true
@@ -4034,7 +3929,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          203762582004180365
+          14002403257262217178
         ]
       ], 
       "reviewed-by-human": true
@@ -4043,7 +3938,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7416446637660374210
+          273445276579232833
         ]
       ], 
       "reviewed-by-human": true
@@ -4052,7 +3947,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13313875175804070508
+          13357226331142394630
         ]
       ], 
       "reviewed-by-human": true
@@ -4061,7 +3956,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2181808913183233869
+          16092444387055031196
         ]
       ], 
       "reviewed-by-human": true
@@ -4094,7 +3989,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8305223338397272588
+          13121122186680676320
         ]
       ], 
       "reviewed-by-human": true
@@ -4103,7 +3998,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5887470903797208725
+          2991124572032378675
         ]
       ], 
       "reviewed-by-human": true
@@ -4112,7 +4007,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16729138449439522348
+          588269449619860245
         ]
       ], 
       "reviewed-by-human": true
@@ -4121,7 +4016,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8740619907670856259
+          8292779718174496966
         ]
       ], 
       "reviewed-by-human": true
@@ -4234,6 +4129,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -4415,7 +4337,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -4424,7 +4346,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -4442,7 +4364,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -4451,7 +4373,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -4472,7 +4394,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -4481,7 +4403,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -4502,7 +4424,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -4511,7 +4433,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -4532,7 +4454,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -4541,7 +4463,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -4562,7 +4484,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -4571,7 +4493,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -4580,19 +4502,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1345397821316727542
+          17628458224178314911
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_16.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -4601,7 +4520,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -4610,19 +4529,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1416345281623416523
+          16580381507386940199
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_256.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -4631,7 +4547,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -4640,19 +4556,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10082929265978245599
+          2398344546936861841
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_32.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -4661,7 +4574,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -4670,13 +4583,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2502904745789888859
+          9999922221837501057
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_512.png_565.png": {
       "allowed-digests": [
@@ -4706,19 +4616,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14422714158002139047
+          17282911349395151329
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_64.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -4727,7 +4634,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -4736,13 +4643,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6200800593359404308
+          13091200127226820869
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_565.png": {
       "allowed-digests": [
@@ -4766,7 +4670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10784446786087633900
+          15270587208090710238
         ]
       ], 
       "reviewed-by-human": true
@@ -4775,7 +4679,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -4784,7 +4688,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -4793,7 +4697,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3991561479472368628
+          1537929885055741265
         ]
       ], 
       "reviewed-by-human": true
@@ -4802,7 +4706,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -4811,7 +4715,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
@@ -4820,7 +4724,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552148705074963587
+          16949219801246071464
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1993355360238974511
         ]
       ], 
       "reviewed-by-human": true
@@ -4829,7 +4760,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          994935463198632465
+          15147463239787661010
         ]
       ], 
       "reviewed-by-human": true
@@ -4838,79 +4769,65 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5363798543478698363
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          8694218356938189525
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1857288326388942863
         ]
       ], 
       "bugs": [
-        2146
+        2887
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          15819102890789133004
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8822685363675334860
+          15707397417757563547
         ]
       ], 
       "reviewed-by-human": true
@@ -4919,7 +4836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6043856383647232157
+          8220509209288028295
         ]
       ], 
       "reviewed-by-human": true
@@ -4928,7 +4845,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8813823881613026115
+          14579472578064423896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11964679111422592867
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13550083050240938758
         ]
       ], 
       "reviewed-by-human": true
@@ -4937,7 +4881,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9981410297050803682
+          17581551777079826402
         ]
       ], 
       "reviewed-by-human": true
@@ -4946,7 +4890,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12924368150056635888
+          5693920054563327483
         ]
       ], 
       "reviewed-by-human": true
@@ -4955,7 +4899,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13572098499379143438
+          1238274545749308638
         ]
       ], 
       "reviewed-by-human": true
@@ -4964,7 +4908,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6055708031509552175
+          13639866476835179815
         ]
       ], 
       "reviewed-by-human": true
@@ -4973,7 +4917,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8346234615044725182
+          9568693510532495016
         ]
       ], 
       "reviewed-by-human": true
@@ -4982,7 +4926,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17005825839359521305
+          12621265934565896095
         ]
       ], 
       "reviewed-by-human": true
@@ -5419,6 +5363,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          184879578592190320
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4641497961465395824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4641497961465395824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13690252386192317596
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6939604931911556567
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1172449135522100758
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9537878225507055943
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4641497961465395824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6177783559433684532
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5447017815880783298
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9676704235267262129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11838346310084813250
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -5447,13 +5607,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10507251147319950569
+          8538815695349052437
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_matrix_565.png": {
       "allowed-digests": [
@@ -5516,7 +5673,7 @@
           14123074605417440290
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_565.png": {
       "allowed-digests": [
@@ -5543,7 +5700,7 @@
           11510630091444160659
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_565.png": {
       "allowed-digests": [
@@ -5630,7 +5787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7955310992779650969
+          16755037058295448772
         ]
       ], 
       "reviewed-by-human": true
@@ -5657,7 +5814,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12252979001720125360
+          378606969488456375
         ]
       ], 
       "reviewed-by-human": true
@@ -5711,7 +5868,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13177731101421450081
+          14371031619054237690
         ]
       ], 
       "reviewed-by-human": true
@@ -5720,7 +5877,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -5738,7 +5895,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13386502562674133801
+          3428427799072987608
         ]
       ], 
       "reviewed-by-human": true
@@ -5747,7 +5904,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297095911910169239
+          8988444324654919932
         ]
       ], 
       "reviewed-by-human": true
@@ -5756,7 +5913,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5771478138095675386
+          8157217091633419434
         ]
       ], 
       "reviewed-by-human": true
@@ -5765,7 +5922,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15574593963961481812
+          8946537113042143544
         ]
       ], 
       "reviewed-by-human": true
@@ -5774,13 +5931,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3746404902639900755
+          9293293797458777202
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_8888.png": {
       "allowed-digests": [
@@ -5831,13 +5985,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8677080270533683993
+          6591688167872296078
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -5879,7 +6030,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13996060058040131634
+          12107833635271491463
         ]
       ], 
       "reviewed-by-human": true
@@ -5888,7 +6039,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7410839535321428153
+          15729042135723497470
         ]
       ], 
       "reviewed-by-human": true
@@ -5897,7 +6048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11461830496962761905
+          7100567264985323761
         ]
       ], 
       "reviewed-by-human": true
@@ -5938,11 +6089,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          741134624395776214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          357284903731074601
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14156935262802098519
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3576279505219183019
+          13620335786972140736
         ]
       ], 
       "reviewed-by-human": true
@@ -5951,7 +6129,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8692857562686154753
+          17030111096598942390
         ]
       ], 
       "reviewed-by-human": true
@@ -5960,7 +6138,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17797568728257858573
+          3330039396091736631
         ]
       ], 
       "reviewed-by-human": true
@@ -5969,7 +6147,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10777355457185638337
+          1922338586017046100
         ]
       ], 
       "reviewed-by-human": true
@@ -5978,7 +6156,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071282510990956080
+          3693078186234250164
         ]
       ], 
       "reviewed-by-human": true
@@ -5987,7 +6165,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14715461394634766316
+          10207079958347315313
         ]
       ], 
       "reviewed-by-human": true
@@ -5996,7 +6174,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16654054210158593753
+          14143901564679014792
         ]
       ], 
       "reviewed-by-human": true
@@ -6005,7 +6183,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2843556688273725953
+          17186499223783647141
         ]
       ], 
       "reviewed-by-human": true
@@ -6014,7 +6192,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17761515447235669868
+          6928710463223662169
         ]
       ], 
       "reviewed-by-human": true
@@ -6023,7 +6201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4403916508561740668
+          9334915207072042375
         ]
       ], 
       "reviewed-by-human": true
@@ -6032,7 +6210,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2169481878270022443
+          4262113639047937913
         ]
       ], 
       "reviewed-by-human": true
@@ -6041,7 +6219,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9782073632467081036
+          9267484176238756819
         ]
       ], 
       "reviewed-by-human": true
@@ -6050,31 +6228,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8498778868685964382
+          9643897842146508458
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          880034339526468883
+          14154076457851775362
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11335639414083835017
+          9274818930704597206
         ]
       ], 
       "reviewed-by-human": true
@@ -6083,7 +6255,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17735192342007451132
+          16816155573392653040
         ]
       ], 
       "reviewed-by-human": true
@@ -6092,7 +6264,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4966754436744417482
+          15621659488709502951
         ]
       ], 
       "reviewed-by-human": true
@@ -6101,7 +6273,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8797890792514086240
+          13054541218806395094
         ]
       ], 
       "reviewed-by-human": true
@@ -6110,7 +6282,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4935800023393625832
+          14400660572715212845
         ]
       ], 
       "reviewed-by-human": true
@@ -6119,7 +6291,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1510287820165086493
+          12820728063175372793
         ]
       ], 
       "reviewed-by-human": true
@@ -6128,7 +6300,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3249705975497923432
+          6514050084756992117
         ]
       ], 
       "reviewed-by-human": true
@@ -6137,23 +6309,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13272858034079482084
+          8609426350230866683
         ]
       ], 
       "reviewed-by-human": true
@@ -6162,7 +6336,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14625944923053341670
+          4458594706234736506
         ]
       ], 
       "reviewed-by-human": true
@@ -6171,7 +6345,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1901521361109987395
+          7881653068493848399
         ]
       ], 
       "reviewed-by-human": true
@@ -6180,7 +6354,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10861701182667580883
+          4870912098826075624
         ]
       ], 
       "reviewed-by-human": true
@@ -6189,7 +6363,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11537830680807011411
+          16955463079319608247
         ]
       ], 
       "reviewed-by-human": true
@@ -6198,7 +6372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2840733308476616973
+          5803572190214013609
         ]
       ], 
       "reviewed-by-human": true
@@ -6207,7 +6381,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2840733308476616973
+          5803572190214013609
         ]
       ], 
       "reviewed-by-human": true
@@ -6216,7 +6390,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273967085043866153
+          14723834413890477065
         ]
       ], 
       "reviewed-by-human": true
@@ -6225,7 +6399,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11751433989801294344
+          1266355932999225698
         ]
       ], 
       "reviewed-by-human": true
@@ -6234,7 +6408,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900375946366690268
+          17245097583413490008
         ]
       ], 
       "reviewed-by-human": true
@@ -6279,7 +6453,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643161545794817643
+          9028961643555474074
         ]
       ], 
       "reviewed-by-human": true
@@ -6288,7 +6462,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511393143767092759
+          9235059342087793513
         ]
       ], 
       "reviewed-by-human": true
@@ -6297,7 +6471,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511393143767092759
+          9235059342087793513
         ]
       ], 
       "reviewed-by-human": true
@@ -6330,19 +6504,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3391919152857140005
+          6405163685079178064
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6728484050681732905
+          5778987087064312358
         ]
       ], 
       "reviewed-by-human": true
@@ -6351,7 +6522,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3122543961009401649
+          10848355732603050567
         ]
       ], 
       "reviewed-by-human": true
@@ -6360,7 +6531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9697510406290295114
+          17754841998252196891
         ]
       ], 
       "reviewed-by-human": true
@@ -6405,7 +6576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2569157419236777949
+          15171677204658263732
         ]
       ], 
       "reviewed-by-human": true
@@ -6414,7 +6585,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1370520776657521517
+          4131799565799962704
         ]
       ], 
       "reviewed-by-human": true
@@ -6423,7 +6594,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14351036907860663618
+          17298767776572466394
         ]
       ], 
       "reviewed-by-human": true
@@ -6432,7 +6603,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16518858492509120064
+          14593570443940328754
         ]
       ], 
       "reviewed-by-human": true
@@ -6441,7 +6612,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15238792371190456534
+          17687576741285937089
         ]
       ], 
       "reviewed-by-human": true
@@ -6450,7 +6621,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9343804110836898394
+          17725216555771216881
         ]
       ], 
       "reviewed-by-human": true
@@ -6459,43 +6630,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7104435648687592254
+          15721345070217154235
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18100962139592302037
+          3651441664185012389
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13861401015232083062
+          14549425769583729518
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3101476576521947165
+          13546074453897362674
         ]
       ], 
       "reviewed-by-human": true
@@ -6504,7 +6666,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10055081768235896808
+          2645433785253737964
         ]
       ], 
       "reviewed-by-human": true
@@ -6513,7 +6675,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350439713947208131
+          15583304423700623450
         ]
       ], 
       "reviewed-by-human": true
@@ -6573,7 +6735,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17553587858062838425
+          8756248250594748551
         ]
       ], 
       "reviewed-by-human": true
@@ -6606,7 +6768,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17553587858062838425
+          8756248250594748551
         ]
       ], 
       "reviewed-by-human": true
@@ -6639,7 +6801,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17553587858062838425
+          8756248250594748551
         ]
       ], 
       "reviewed-by-human": true
@@ -6672,12 +6834,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7758597652352633244
+          11898977239618964760
         ]
       ], 
-      "bugs": [
-        1596
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -6709,19 +6868,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11934469864526604734
+          6287674327505113148
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13276990043616594793
+          17044527983161977372
         ]
       ], 
       "reviewed-by-human": true
@@ -6730,7 +6886,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12053534281222176521
+          16679250406161029701
         ]
       ], 
       "reviewed-by-human": true
@@ -6739,7 +6895,277 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15869818052487928163
+          3140032282102690470
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16064342292519177703
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16328681329150531419
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3387451507864625255
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          530696139292907434
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5010538637752141343
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17349807853851939382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13456162487414097587
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7108849406246770065
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12945819083706719382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2689185877755429682
         ]
       ], 
       "reviewed-by-human": true
@@ -6889,7 +7315,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15240835456320409473
+          4656886197492028969
         ]
       ], 
       "reviewed-by-human": true
@@ -6898,7 +7324,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          249289862803617115
+          10009949554846362902
         ]
       ], 
       "reviewed-by-human": true
@@ -6907,7 +7333,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15497506993121739956
+          13683962615885282836
         ]
       ], 
       "reviewed-by-human": true
@@ -6928,13 +7354,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          4625205966782873365
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -6972,53 +7395,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2143850486822799899
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15350252464204167970
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18264085885951369494
+          17899022691963121600
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6845561371571987961
+          8212877465944976095
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3236205967252504838
+          10591577672223116924
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "patheffect_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4427938030923047423
+          14182680775472184218
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "patheffect_8888.png": {
       "allowed-digests": [
@@ -7249,7 +7714,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -7258,7 +7723,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -7267,7 +7732,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5910660068342021532
+          12602702778262712881
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3817855389012712870
         ]
       ], 
       "reviewed-by-human": true
@@ -7276,7 +7768,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15710121230086435602
+          14656164594743658373
         ]
       ], 
       "reviewed-by-human": true
@@ -7285,7 +7777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1763586683528188858
+          7375436820633666472
         ]
       ], 
       "reviewed-by-human": true
@@ -7294,7 +7786,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1763586683528188858
+          7375436820633666472
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
         ]
       ], 
       "reviewed-by-human": true
@@ -7326,6 +7845,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -7363,7 +7909,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6571118611946058617
+          13710370929503896242
         ]
       ], 
       "reviewed-by-human": true
@@ -7372,7 +7918,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2985268228390879272
+          14868659503042841956
         ]
       ], 
       "reviewed-by-human": true
@@ -7381,7 +7927,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4090908000301047480
+          16248212291629065148
         ]
       ], 
       "reviewed-by-human": true
@@ -7426,7 +7972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9971396627985154706
+          11616620239881546194
         ]
       ], 
       "reviewed-by-human": true
@@ -7435,7 +7981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6891379388563692035
+          13695847048236137972
         ]
       ], 
       "reviewed-by-human": true
@@ -7444,7 +7990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7133096296319789026
+          8928805579832560331
         ]
       ], 
       "reviewed-by-human": true
@@ -7453,7 +7999,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1288004664951630498
+          10424880346112239562
         ]
       ], 
       "reviewed-by-human": true
@@ -7462,7 +8008,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7223243377781866680
+          24796932854446382
         ]
       ], 
       "reviewed-by-human": true
@@ -7471,7 +8017,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12191681455930613784
+          3232711541650961499
         ]
       ], 
       "reviewed-by-human": true
@@ -7504,13 +8050,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17294523260520684759
+          16089700058417943666
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_565.png": {
       "allowed-digests": [
@@ -7540,13 +8083,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14470264741921611599
+          15031929842713675110
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -7579,10 +8119,7 @@
           16787331154477637635
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "resizeimagefilter_565.png": {
       "allowed-digests": [
@@ -7660,13 +8197,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9108911139001347487
+          18340118795193628429
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rrect_8888.png": {
       "allowed-digests": [
@@ -7756,7 +8290,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11436925749408943089
+          18385677641429471665
         ]
       ], 
       "reviewed-by-human": true
@@ -7846,10 +8380,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2310215659204296151
+          13432058568869482858
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rrect_gpu.png": {
       "allowed-digests": [
@@ -7894,7 +8428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1410103792220800931
+          8082315010167812063
         ]
       ], 
       "reviewed-by-human": true
@@ -7903,7 +8437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2293107890848557380
+          1864383706473625196
         ]
       ], 
       "reviewed-by-human": true
@@ -7912,7 +8446,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12802535321257469607
+          8364375847748518642
         ]
       ], 
       "reviewed-by-human": true
@@ -7921,7 +8455,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5067627966950621939
+          14137833661681785135
         ]
       ], 
       "reviewed-by-human": true
@@ -7930,7 +8464,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7517125506221018662
+          14791436059610164321
         ]
       ], 
       "reviewed-by-human": true
@@ -7939,7 +8473,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7606734424710060898
+          5563001502326738261
         ]
       ], 
       "reviewed-by-human": true
@@ -7948,7 +8482,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9319993179135558393
+          13924533833588869139
         ]
       ], 
       "reviewed-by-human": true
@@ -7957,7 +8491,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16574168428196349390
+          7186960244825707915
         ]
       ], 
       "reviewed-by-human": true
@@ -7966,7 +8500,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3968605136301912973
+          1376209882197320131
         ]
       ], 
       "reviewed-by-human": true
@@ -7975,7 +8509,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17418047642108977670
+          164630131521766648
         ]
       ], 
       "reviewed-by-human": true
@@ -7984,7 +8518,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1556868127331379479
+          15540325168021281899
         ]
       ], 
       "reviewed-by-human": true
@@ -7993,7 +8527,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14148935305656142180
+          13328221062685842667
         ]
       ], 
       "reviewed-by-human": true
@@ -8110,13 +8644,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3556699044314006968
+          163919757956159506
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "shadows_8888.png": {
       "allowed-digests": [
@@ -8278,19 +8809,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16883506100501459281
+          7976181664392439726
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2422870003307313999
+          6856823905290886591
         ]
       ], 
       "reviewed-by-human": true
@@ -8299,7 +8827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8297028920093819054
+          18010746007073820817
         ]
       ], 
       "reviewed-by-human": true
@@ -8308,7 +8836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16021439723556558918
+          14249365533430423372
         ]
       ], 
       "reviewed-by-human": true
@@ -8317,7 +8845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2422870003307313999
+          6856823905290886591
         ]
       ], 
       "reviewed-by-human": true
@@ -8326,7 +8854,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8505743106500736554
+          17160448045672967434
         ]
       ], 
       "reviewed-by-human": true
@@ -8335,7 +8863,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6566419177529590403
+          18363282621086286494
         ]
       ], 
       "reviewed-by-human": true
@@ -8344,7 +8872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2276755423088781585
+          13802666172572918659
         ]
       ], 
       "reviewed-by-human": true
@@ -8353,7 +8881,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2247183642119438840
+          1769885343134219810
         ]
       ], 
       "reviewed-by-human": true
@@ -8362,7 +8890,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8484924843781194174
+          11976294617324151262
         ]
       ], 
       "reviewed-by-human": true
@@ -8371,7 +8899,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13988021646843375450
+          16249993606621732315
         ]
       ], 
       "reviewed-by-human": true
@@ -8389,7 +8917,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13014561373059764150
+          7523538521688389229
         ]
       ], 
       "reviewed-by-human": true
@@ -8434,25 +8962,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14585555250092963383
+          13909757336310240518
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "spritebitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6423558589708144215
+          17885518595384354919
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "spritebitmap_gpu.png": {
       "allowed-digests": [
@@ -8470,7 +8992,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17619211944443238901
+          11699531654048406518
         ]
       ], 
       "reviewed-by-human": true
@@ -8479,7 +9001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476337759406055776
+          4523091657809672686
         ]
       ], 
       "reviewed-by-human": true
@@ -8488,7 +9010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1838432270932859890
+          6909139710433844754
         ]
       ], 
       "reviewed-by-human": true
@@ -8533,7 +9055,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2450726810754127074
+          8404092897044868761
         ]
       ], 
       "reviewed-by-human": true
@@ -8542,7 +9064,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12690621371284385511
+          14156844530688032350
         ]
       ], 
       "reviewed-by-human": true
@@ -8551,7 +9073,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16688606203531911724
+          14632249572216229788
         ]
       ], 
       "reviewed-by-human": true
@@ -8596,13 +9118,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1252564837192523211
+          10731083935300051992
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "strokerects_8888.png": {
       "allowed-digests": [
@@ -8632,13 +9151,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8397039244880318300
+          9117693921833992353
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "strokes3_8888.png": {
       "allowed-digests": [
@@ -8740,7 +9256,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10084807092550654294
+          5033516764144244033
         ]
       ], 
       "reviewed-by-human": true
@@ -8749,7 +9265,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15846255821264969272
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -8758,7 +9274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1841381969935611676
+          17666174042372237996
         ]
       ], 
       "reviewed-by-human": true
@@ -8791,67 +9307,79 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17892855770534705304
+          11181230850811915000
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "testimagefilters_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15528863190484305841
+          1369006746513120542
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "testimagefilters_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15197842121034928067
+          10584886924228958226
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "testimagefilters_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5204419253707868565
+          16334968078566298182
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texdata_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1221372586972395156
+          2736593828543197285
         ]
       ], 
-      "bugs": [
-        2146
+      "reviewed-by-human": true
+    }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17484439610611592723
+        ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11311445240364221126
+          3352233736449563022
         ]
       ], 
       "reviewed-by-human": true
@@ -8860,7 +9388,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9681917212200619788
+          377328076341373940
         ]
       ], 
       "reviewed-by-human": true
@@ -8869,7 +9397,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9681917212200619788
+          6885322238950860527
         ]
       ], 
       "reviewed-by-human": true
@@ -8878,10 +9406,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11365388622786306146
+          8813824922010639566
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -8914,10 +9442,7 @@
           18123780144204716606
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_565.png": {
       "allowed-digests": [
@@ -8950,16 +9475,13 @@
           14598560863929901019
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15884441815359625883
+          15732727687033594466
         ]
       ], 
       "reviewed-by-human": true
@@ -8968,7 +9490,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8977,7 +9499,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8986,7 +9508,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1410103792220800931
+          8082315010167812063
         ]
       ], 
       "reviewed-by-human": true
@@ -8995,7 +9517,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2293107890848557380
+          1864383706473625196
         ]
       ], 
       "reviewed-by-human": true
@@ -9004,7 +9526,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12802535321257469607
+          8364375847748518642
         ]
       ], 
       "reviewed-by-human": true
@@ -9013,7 +9535,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5067627966950621939
+          14137833661681785135
         ]
       ], 
       "reviewed-by-human": true
@@ -9022,7 +9544,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7517125506221018662
+          14791436059610164321
         ]
       ], 
       "reviewed-by-human": true
@@ -9031,7 +9553,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7606734424710060898
+          5563001502326738261
         ]
       ], 
       "reviewed-by-human": true
@@ -9040,7 +9562,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1916052269453883881
+          1211393994967316525
         ]
       ], 
       "reviewed-by-human": true
@@ -9049,7 +9571,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14968443247329529117
+          14480947444732898359
         ]
       ], 
       "reviewed-by-human": true
@@ -9058,7 +9580,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2592756938145874158
+          3017506100985054305
         ]
       ], 
       "reviewed-by-human": true
@@ -9067,7 +9589,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8143654303249859581
+          11691375869271942933
         ]
       ], 
       "reviewed-by-human": true
@@ -9076,7 +9598,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13298836052288001622
+          14216970501880738242
         ]
       ], 
       "reviewed-by-human": true
@@ -9085,7 +9607,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1838655959411055883
+          14701343820986514047
         ]
       ], 
       "reviewed-by-human": true
@@ -9130,7 +9652,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18223584313005621176
+          18323972177455356231
         ]
       ], 
       "reviewed-by-human": true
@@ -9139,7 +9661,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6036270199387229964
+          5412705785906131810
         ]
       ], 
       "reviewed-by-human": true
@@ -9148,7 +9670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1045519680717029999
+          6056335833066049972
         ]
       ], 
       "reviewed-by-human": true
@@ -9157,7 +9679,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11426788897705172941
+          12765023135113455799
         ]
       ], 
       "reviewed-by-human": true
@@ -9166,7 +9688,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3057908372893981204
+          14725542749908228
         ]
       ], 
       "reviewed-by-human": true
@@ -9175,7 +9697,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3057908372893981204
+          14725542749908228
         ]
       ], 
       "reviewed-by-human": true
@@ -9184,7 +9706,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          714676201649578466
+          11838752118610481979
         ]
       ], 
       "reviewed-by-human": true
@@ -9193,7 +9715,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370428013149648258
+          6475798309604476317
         ]
       ], 
       "reviewed-by-human": true
@@ -9202,7 +9724,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370428013149648258
+          6475798309604476317
         ]
       ], 
       "reviewed-by-human": true
@@ -9211,7 +9733,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5443026492957156846
+          508446862935931396
         ]
       ], 
       "reviewed-by-human": true
@@ -9220,7 +9742,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2080761164861757576
+          17546866530171427130
         ]
       ], 
       "reviewed-by-human": true
@@ -9229,7 +9751,115 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8882773799933891216
+          539829354440306365
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1952127887831515847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          26534852890899274
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1952127887831515847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          26534852890899274
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1752599991641140864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12914772605547417778
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1752599991641140864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12914772605547417778
         ]
       ], 
       "reviewed-by-human": true
@@ -9301,7 +9931,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9457742961471532948
+          14144865147136195678
         ]
       ], 
       "reviewed-by-human": true
@@ -9310,7 +9940,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14527641142409674625
+          6274320838479527537
         ]
       ], 
       "reviewed-by-human": true
@@ -9319,7 +9949,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3597293503861619263
+          11188008329308255443
         ]
       ], 
       "reviewed-by-human": true
@@ -9328,7 +9958,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3820411693075952029
+          6737255892443592724
         ]
       ], 
       "reviewed-by-human": true
@@ -9337,7 +9967,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3587671227602487124
+          12569529133241702893
         ]
       ], 
       "reviewed-by-human": true
@@ -9346,7 +9976,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3897538395660363842
+          15091714070778715037
         ]
       ], 
       "reviewed-by-human": true
@@ -9355,7 +9985,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10958353996143090911
+          3112652115716203250
         ]
       ], 
       "reviewed-by-human": true
@@ -9364,7 +9994,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17000878545702467803
+          12938112915997113104
         ]
       ], 
       "reviewed-by-human": true
@@ -9373,7 +10003,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          167015306588432469
+          2398735729200624910
         ]
       ], 
       "reviewed-by-human": true
@@ -9382,7 +10012,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4613530689633279630
+          4006560807085464955
         ]
       ], 
       "reviewed-by-human": true
@@ -9391,7 +10021,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2952493606222488372
+          6431759696672110544
         ]
       ], 
       "reviewed-by-human": true
@@ -9400,7 +10030,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2992781255766374719
+          4474185865412834223
         ]
       ], 
       "reviewed-by-human": true
@@ -9409,7 +10039,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12480404425423207055
+          15662585344043467067
         ]
       ], 
       "reviewed-by-human": true
@@ -9418,7 +10048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14561360239620524377
+          15172719087640402575
         ]
       ], 
       "reviewed-by-human": true
@@ -9427,7 +10057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16987219934025015385
+          17724920587118100620
         ]
       ], 
       "reviewed-by-human": true
@@ -9436,7 +10066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4935026131066456043
+          10103658154547338580
         ]
       ], 
       "reviewed-by-human": true
@@ -9445,7 +10075,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10963470347499254787
+          1637047472327850125
         ]
       ], 
       "reviewed-by-human": true
@@ -9454,7 +10084,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4224918093600621161
+          11638705468219848676
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7017362768546994774
         ]
       ], 
       "reviewed-by-human": true
diff --git a/expectations/gm/Test-Android-Nexus4-Adreno320-Arm7-Debug/expected-results.json b/expectations/gm/Test-Android-Nexus5-Adreno330-Arm7-Release/expected-results.json
similarity index 83%
copy from expectations/gm/Test-Android-Nexus4-Adreno320-Arm7-Debug/expected-results.json
copy to expectations/gm/Test-Android-Nexus5-Adreno330-Arm7-Release/expected-results.json
index 8e54b14..3ee8efb 100644
--- a/expectations/gm/Test-Android-Nexus4-Adreno320-Arm7-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-Nexus5-Adreno330-Arm7-Release/expected-results.json
@@ -58,7 +58,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4834500295502840348
+          4051703290108094975
         ]
       ], 
       "reviewed-by-human": true
@@ -91,13 +91,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7778842390739990811
+          11491762121233092989
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -211,7 +208,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8827950106908644173
+          17926029181770873121
         ]
       ], 
       "reviewed-by-human": true
@@ -220,7 +217,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1951236732185589783
+          13062082258702353494
         ]
       ], 
       "reviewed-by-human": true
@@ -229,7 +226,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16119411048162915342
+          16160417814295732631
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -238,7 +262,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14690535209962836585
+          1893525008058911358
         ]
       ], 
       "reviewed-by-human": true
@@ -247,7 +271,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          258516539966628223
+          2193603642080030108
         ]
       ], 
       "reviewed-by-human": true
@@ -261,53 +285,14 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12488185918270960759
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2422083043229439955
+          14704206703218007573
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_8888.png": {
       "allowed-digests": [
@@ -325,14 +310,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15262453002939091927
+          12186349305207417968
         ]
       ], 
-      "bugs": [
-        2528
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -374,37 +356,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9363175749442909647
+          13522834714006056195
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8357897490332471314
+          15371795889574689123
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14992614689880273626
+          15993755133919765308
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmap_premul_565.png": {
       "allowed-digests": [
@@ -446,7 +419,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15577847810878117619
+          6980407574393099333
         ]
       ], 
       "reviewed-by-human": true
@@ -455,7 +428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16537885423072386302
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -464,7 +437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7099981478239046398
+          6408368646738826293
         ]
       ], 
       "reviewed-by-human": true
@@ -581,37 +554,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2235975214838086978
+          2196346147885638539
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2020710583966674615
+          4883607151963013153
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          930590022062657844
+          10338830390467391331
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapshaders_565.png": {
       "allowed-digests": [
@@ -647,7 +611,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15581542612528711266
+          10503127572291510299
         ]
       ], 
       "reviewed-by-human": true
@@ -656,7 +620,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071585613760610277
+          10522304426373074824
         ]
       ], 
       "reviewed-by-human": true
@@ -665,7 +629,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          400977977058761258
+          14364119850332005144
         ]
       ], 
       "reviewed-by-human": true
@@ -698,22 +662,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8780149372826681087
+          6482505834609090342
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17148910878401545731
+          446330175668077197
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurcircles_8888.png": {
       "allowed-digests": [
@@ -761,13 +722,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8292097632245464218
+          14587775113781716416
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrect_25_100_20_inner_fast_565.png": {
       "allowed-digests": [
@@ -2065,17 +2023,41 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13080629583390552103
+          3696341484825569467
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_8888.png": {
       "allowed-digests": [
@@ -2093,13 +2075,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18253719462566450522
+          9641246636600586865
         ]
       ], 
-      "bugs": [
-        2146
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6642232162121933341
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
@@ -2141,7 +2147,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6827358016184068480
+          2150244883739371334
         ]
       ], 
       "reviewed-by-human": true
@@ -2150,7 +2156,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18214876018436421527
+          1470201827989444658
         ]
       ], 
       "reviewed-by-human": true
@@ -2159,7 +2165,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16764988930995149135
+          10660358181509326600
         ]
       ], 
       "reviewed-by-human": true
@@ -2222,73 +2228,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          7950166054919619394
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          7950166054919619394
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          7950166054919619394
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13774733025575034199
+          930789055331505026
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13774733025575034199
+          930789055331505026
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7116408385747031060
+          6698655366271403718
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "circles_565.png": {
       "allowed-digests": [
@@ -2354,13 +2342,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1988347527319338472
+          13930158063852006486
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "clamped_gradients_565.png": {
       "allowed-digests": [
@@ -2393,10 +2378,7 @@
           3828862583467184095
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "clipped-bitmap-shaders-clamp-hq_565.png": {
       "allowed-digests": [
@@ -2711,13 +2693,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2061614246926476221
+          2646827529077989952
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colormatrix_565.png": {
       "allowed-digests": [
@@ -2759,37 +2738,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322753158848112633
+          16101291896048576683
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13587257461703619696
+          6958362917585628191
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2386152686556935098
+          13430579085704011533
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -2852,13 +2822,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11490765877564985529
+          3797306140110758200
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_path_bw_565.png": {
       "allowed-digests": [
@@ -2924,7 +2891,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11709014768122709362
+          3615138553335577401
         ]
       ], 
       "reviewed-by-human": true
@@ -2951,7 +2918,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10546564699546205411
+          9394585766845655876
         ]
       ], 
       "reviewed-by-human": true
@@ -2996,7 +2963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2035525753977535256
+          1787647314443274475
         ]
       ], 
       "reviewed-by-human": true
@@ -3005,7 +2972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12559465164864479162
+          6544536706877310514
         ]
       ], 
       "reviewed-by-human": true
@@ -3014,7 +2981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7358555905763201928
+          14203888972719556254
         ]
       ], 
       "reviewed-by-human": true
@@ -3023,7 +2990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3306730904107685940
+          14933444110384788676
         ]
       ], 
       "reviewed-by-human": true
@@ -3032,7 +2999,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13591877655871515458
+          5836493341538608113
         ]
       ], 
       "reviewed-by-human": true
@@ -3041,7 +3008,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13408156583590041760
+          2268166315101404727
         ]
       ], 
       "reviewed-by-human": true
@@ -3050,7 +3017,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6310901099269765196
+          6492358805688952506
         ]
       ], 
       "reviewed-by-human": true
@@ -3059,7 +3026,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2511666966287866166
+          10152516748782571739
         ]
       ], 
       "reviewed-by-human": true
@@ -3068,7 +3035,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9870707006952451670
+          3437577920781380091
         ]
       ], 
       "reviewed-by-human": true
@@ -3077,7 +3044,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17159080850865344792
+          8180502121217066191
         ]
       ], 
       "reviewed-by-human": true
@@ -3086,7 +3053,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2302717591157402628
+          16993829969091028380
         ]
       ], 
       "reviewed-by-human": true
@@ -3095,7 +3062,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5176667371385901463
+          6154910293993208197
         ]
       ], 
       "reviewed-by-human": true
@@ -3158,7 +3125,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3742871756784050961
+          4792118895672570848
         ]
       ], 
       "reviewed-by-human": true
@@ -3167,7 +3134,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14394590208816375119
+          11285887424651164487
         ]
       ], 
       "reviewed-by-human": true
@@ -3176,7 +3143,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5297539228443187427
+          11238366782850465904
         ]
       ], 
       "reviewed-by-human": true
@@ -3185,7 +3152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9295659414181314501
+          1761288288611240316
         ]
       ], 
       "reviewed-by-human": true
@@ -3266,7 +3233,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12345522437202727374
+          15805712012337691465
         ]
       ], 
       "reviewed-by-human": true
@@ -3275,7 +3242,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17912401236231679127
+          7882161322447216882
         ]
       ], 
       "reviewed-by-human": true
@@ -3284,7 +3251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4407767759255340842
+          10625642201334602406
         ]
       ], 
       "reviewed-by-human": true
@@ -3293,7 +3260,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11191728978684557482
+          2526905513820650564
         ]
       ], 
       "reviewed-by-human": true
@@ -3302,7 +3269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058335517377211817
+          713799816796517938
         ]
       ], 
       "reviewed-by-human": true
@@ -3311,7 +3278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15880316531252693614
+          14332218640581301593
         ]
       ], 
       "reviewed-by-human": true
@@ -3425,7 +3392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14433773091096403168
+          8454109889032154845
         ]
       ], 
       "reviewed-by-human": true
@@ -3443,7 +3410,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6278497568528421897
+          1262614943450883570
         ]
       ], 
       "reviewed-by-human": true
@@ -3452,13 +3419,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912539765453208522
+          2587070015488181148
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dashing_8888.png": {
       "allowed-digests": [
@@ -3476,7 +3440,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2637106900149052753
+          9237020395486912339
         ]
       ], 
       "reviewed-by-human": true
@@ -3485,7 +3449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1940009043017990568
+          14932083482843942713
         ]
       ], 
       "reviewed-by-human": true
@@ -3494,7 +3458,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11122804881221782538
+          7311723676588845146
         ]
       ], 
       "reviewed-by-human": true
@@ -3503,7 +3467,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875243706575375716
+          16335342645475325976
         ]
       ], 
       "reviewed-by-human": true
@@ -3512,7 +3476,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799487143319424536
+          16442079060610240238
         ]
       ], 
       "reviewed-by-human": true
@@ -3521,7 +3485,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1020763452380907607
+          8850017817310905002
         ]
       ], 
       "reviewed-by-human": true
@@ -3539,7 +3503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10557537838778749160
+          4057230872151110302
         ]
       ], 
       "reviewed-by-human": true
@@ -3548,7 +3512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7089896533323038526
+          9482070623821433904
         ]
       ], 
       "reviewed-by-human": true
@@ -3557,7 +3521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6994945621426128555
+          11651015540131061089
         ]
       ], 
       "reviewed-by-human": true
@@ -3566,43 +3530,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -3611,7 +3566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -3620,7 +3575,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9753614989636915824
+          16791319229896708086
         ]
       ], 
       "reviewed-by-human": true
@@ -3629,115 +3584,88 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8044171070473798324
+          3688678278715679643
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9753614989636915824
+          16791319229896708086
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6989712392624471913
+          17775297231868448514
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10855232109519818829
+          12804472649182277577
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6096625630775082776
+          18291808159456495873
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -3746,7 +3674,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -3755,7 +3683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8358902968682749303
+          17252554729222171743
         ]
       ], 
       "reviewed-by-human": true
@@ -3764,115 +3692,88 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14204452381545620746
+          3638140728733337240
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8358902968682749303
+          17252554729222171743
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2497837460215148124
+          6055955940623478607
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13192464168020553898
+          11797865288006977816
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14063480206491490964
+          14270146303385771045
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -3881,7 +3782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
         ]
       ], 
       "reviewed-by-human": true
@@ -3890,7 +3791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10904087299234981169
+          9143885823705622089
         ]
       ], 
       "reviewed-by-human": true
@@ -3899,7 +3800,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          4886211991926050486
         ]
       ], 
       "reviewed-by-human": true
@@ -3908,7 +3809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          8737545656412765906
         ]
       ], 
       "reviewed-by-human": true
@@ -3917,7 +3818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9117643962511052605
+          5280794742313748754
         ]
       ], 
       "reviewed-by-human": true
@@ -3926,7 +3827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -3935,7 +3836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
         ]
       ], 
       "reviewed-by-human": true
@@ -3944,7 +3845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15385694394456194958
+          11941429900712810519
         ]
       ], 
       "reviewed-by-human": true
@@ -3953,7 +3854,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          4707049264800437834
         ]
       ], 
       "reviewed-by-human": true
@@ -3962,7 +3863,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          3175389971476411688
         ]
       ], 
       "reviewed-by-human": true
@@ -3971,7 +3872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16252566948450263228
+          18069542661784516392
         ]
       ], 
       "reviewed-by-human": true
@@ -3980,13 +3881,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -4004,19 +3902,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15371575219017467192
+          9730655672235986353
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16880886031490071742
+          15797039913993285826
         ]
       ], 
       "reviewed-by-human": true
@@ -4025,7 +3920,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          428119157032316167
+          17497164562330387900
         ]
       ], 
       "reviewed-by-human": true
@@ -4034,7 +3929,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          203762582004180365
+          14002403257262217178
         ]
       ], 
       "reviewed-by-human": true
@@ -4043,7 +3938,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7416446637660374210
+          273445276579232833
         ]
       ], 
       "reviewed-by-human": true
@@ -4052,7 +3947,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13313875175804070508
+          13357226331142394630
         ]
       ], 
       "reviewed-by-human": true
@@ -4061,7 +3956,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2181808913183233869
+          16092444387055031196
         ]
       ], 
       "reviewed-by-human": true
@@ -4094,7 +3989,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8305223338397272588
+          13121122186680676320
         ]
       ], 
       "reviewed-by-human": true
@@ -4103,7 +3998,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5887470903797208725
+          2991124572032378675
         ]
       ], 
       "reviewed-by-human": true
@@ -4112,7 +4007,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16729138449439522348
+          588269449619860245
         ]
       ], 
       "reviewed-by-human": true
@@ -4121,7 +4016,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8740619907670856259
+          8292779718174496966
         ]
       ], 
       "reviewed-by-human": true
@@ -4234,6 +4129,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -4415,7 +4337,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -4424,7 +4346,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -4442,7 +4364,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -4451,7 +4373,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -4472,7 +4394,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -4481,7 +4403,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -4502,7 +4424,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -4511,7 +4433,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -4532,7 +4454,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -4541,7 +4463,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -4562,7 +4484,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -4571,7 +4493,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -4580,19 +4502,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1345397821316727542
+          17628458224178314911
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_16.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -4601,7 +4520,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -4610,19 +4529,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1416345281623416523
+          16580381507386940199
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_256.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -4631,7 +4547,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -4640,19 +4556,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10082929265978245599
+          2398344546936861841
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_32.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -4661,7 +4574,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -4670,13 +4583,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2502904745789888859
+          9999922221837501057
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_512.png_565.png": {
       "allowed-digests": [
@@ -4706,19 +4616,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14422714158002139047
+          17282911349395151329
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_image_mandrill_64.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -4727,7 +4634,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -4736,13 +4643,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6200800593359404308
+          13091200127226820869
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_565.png": {
       "allowed-digests": [
@@ -4766,7 +4670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10784446786087633900
+          15270587208090710238
         ]
       ], 
       "reviewed-by-human": true
@@ -4775,7 +4679,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -4784,7 +4688,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -4793,7 +4697,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3991561479472368628
+          1537929885055741265
         ]
       ], 
       "reviewed-by-human": true
@@ -4802,7 +4706,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -4811,7 +4715,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
@@ -4820,7 +4724,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552148705074963587
+          16949219801246071464
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1993355360238974511
         ]
       ], 
       "reviewed-by-human": true
@@ -4829,7 +4760,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          994935463198632465
+          15147463239787661010
         ]
       ], 
       "reviewed-by-human": true
@@ -4838,79 +4769,65 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5363798543478698363
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          8694218356938189525
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1857288326388942863
         ]
       ], 
       "bugs": [
-        2146
+        2887
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          15819102890789133004
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8822685363675334860
+          15707397417757563547
         ]
       ], 
       "reviewed-by-human": true
@@ -4919,7 +4836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6043856383647232157
+          8220509209288028295
         ]
       ], 
       "reviewed-by-human": true
@@ -4928,7 +4845,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8813823881613026115
+          14579472578064423896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11964679111422592867
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13550083050240938758
         ]
       ], 
       "reviewed-by-human": true
@@ -4937,7 +4881,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9981410297050803682
+          17581551777079826402
         ]
       ], 
       "reviewed-by-human": true
@@ -4946,7 +4890,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12924368150056635888
+          5693920054563327483
         ]
       ], 
       "reviewed-by-human": true
@@ -4955,7 +4899,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13572098499379143438
+          1238274545749308638
         ]
       ], 
       "reviewed-by-human": true
@@ -4964,7 +4908,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6055708031509552175
+          13639866476835179815
         ]
       ], 
       "reviewed-by-human": true
@@ -4973,7 +4917,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8346234615044725182
+          9568693510532495016
         ]
       ], 
       "reviewed-by-human": true
@@ -4982,7 +4926,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17005825839359521305
+          12621265934565896095
         ]
       ], 
       "reviewed-by-human": true
@@ -5419,6 +5363,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          184879578592190320
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4641497961465395824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4641497961465395824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13690252386192317596
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6939604931911556567
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1172449135522100758
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9537878225507055943
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6028219565996228394
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4641497961465395824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6177783559433684532
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5447017815880783298
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9676704235267262129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11838346310084813250
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -5447,13 +5607,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10507251147319950569
+          8538815695349052437
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_matrix_565.png": {
       "allowed-digests": [
@@ -5516,7 +5673,7 @@
           14123074605417440290
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_565.png": {
       "allowed-digests": [
@@ -5543,7 +5700,7 @@
           11510630091444160659
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_565.png": {
       "allowed-digests": [
@@ -5630,7 +5787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7955310992779650969
+          16755037058295448772
         ]
       ], 
       "reviewed-by-human": true
@@ -5657,7 +5814,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12252979001720125360
+          378606969488456375
         ]
       ], 
       "reviewed-by-human": true
@@ -5711,7 +5868,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13177731101421450081
+          14371031619054237690
         ]
       ], 
       "reviewed-by-human": true
@@ -5720,7 +5877,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -5738,7 +5895,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13386502562674133801
+          3428427799072987608
         ]
       ], 
       "reviewed-by-human": true
@@ -5747,7 +5904,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297095911910169239
+          8988444324654919932
         ]
       ], 
       "reviewed-by-human": true
@@ -5756,7 +5913,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5771478138095675386
+          8157217091633419434
         ]
       ], 
       "reviewed-by-human": true
@@ -5765,7 +5922,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15574593963961481812
+          8946537113042143544
         ]
       ], 
       "reviewed-by-human": true
@@ -5774,13 +5931,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3746404902639900755
+          9293293797458777202
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_8888.png": {
       "allowed-digests": [
@@ -5831,13 +5985,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8677080270533683993
+          6591688167872296078
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -5879,7 +6030,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13996060058040131634
+          12107833635271491463
         ]
       ], 
       "reviewed-by-human": true
@@ -5888,7 +6039,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7410839535321428153
+          15729042135723497470
         ]
       ], 
       "reviewed-by-human": true
@@ -5897,7 +6048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11461830496962761905
+          7100567264985323761
         ]
       ], 
       "reviewed-by-human": true
@@ -5938,11 +6089,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          741134624395776214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          357284903731074601
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14156935262802098519
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3576279505219183019
+          13620335786972140736
         ]
       ], 
       "reviewed-by-human": true
@@ -5951,7 +6129,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8692857562686154753
+          17030111096598942390
         ]
       ], 
       "reviewed-by-human": true
@@ -5960,7 +6138,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17797568728257858573
+          3330039396091736631
         ]
       ], 
       "reviewed-by-human": true
@@ -5969,7 +6147,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10777355457185638337
+          1922338586017046100
         ]
       ], 
       "reviewed-by-human": true
@@ -5978,7 +6156,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071282510990956080
+          3693078186234250164
         ]
       ], 
       "reviewed-by-human": true
@@ -5987,7 +6165,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14715461394634766316
+          10207079958347315313
         ]
       ], 
       "reviewed-by-human": true
@@ -5996,7 +6174,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16654054210158593753
+          14143901564679014792
         ]
       ], 
       "reviewed-by-human": true
@@ -6005,7 +6183,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2843556688273725953
+          17186499223783647141
         ]
       ], 
       "reviewed-by-human": true
@@ -6014,7 +6192,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17761515447235669868
+          6928710463223662169
         ]
       ], 
       "reviewed-by-human": true
@@ -6023,7 +6201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4403916508561740668
+          9334915207072042375
         ]
       ], 
       "reviewed-by-human": true
@@ -6032,7 +6210,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2169481878270022443
+          4262113639047937913
         ]
       ], 
       "reviewed-by-human": true
@@ -6041,7 +6219,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9782073632467081036
+          9267484176238756819
         ]
       ], 
       "reviewed-by-human": true
@@ -6050,31 +6228,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8498778868685964382
+          9643897842146508458
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          880034339526468883
+          14154076457851775362
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11335639414083835017
+          9274818930704597206
         ]
       ], 
       "reviewed-by-human": true
@@ -6083,7 +6255,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17735192342007451132
+          16816155573392653040
         ]
       ], 
       "reviewed-by-human": true
@@ -6092,7 +6264,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4966754436744417482
+          15621659488709502951
         ]
       ], 
       "reviewed-by-human": true
@@ -6101,7 +6273,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8797890792514086240
+          13054541218806395094
         ]
       ], 
       "reviewed-by-human": true
@@ -6110,7 +6282,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4935800023393625832
+          14400660572715212845
         ]
       ], 
       "reviewed-by-human": true
@@ -6119,7 +6291,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1510287820165086493
+          12820728063175372793
         ]
       ], 
       "reviewed-by-human": true
@@ -6128,7 +6300,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3249705975497923432
+          6514050084756992117
         ]
       ], 
       "reviewed-by-human": true
@@ -6137,23 +6309,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13272858034079482084
+          8609426350230866683
         ]
       ], 
       "reviewed-by-human": true
@@ -6162,7 +6336,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14625944923053341670
+          4458594706234736506
         ]
       ], 
       "reviewed-by-human": true
@@ -6171,7 +6345,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1901521361109987395
+          7881653068493848399
         ]
       ], 
       "reviewed-by-human": true
@@ -6180,7 +6354,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10861701182667580883
+          4870912098826075624
         ]
       ], 
       "reviewed-by-human": true
@@ -6189,7 +6363,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11537830680807011411
+          16955463079319608247
         ]
       ], 
       "reviewed-by-human": true
@@ -6198,7 +6372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2840733308476616973
+          5803572190214013609
         ]
       ], 
       "reviewed-by-human": true
@@ -6207,7 +6381,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2840733308476616973
+          5803572190214013609
         ]
       ], 
       "reviewed-by-human": true
@@ -6216,7 +6390,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273967085043866153
+          14723834413890477065
         ]
       ], 
       "reviewed-by-human": true
@@ -6225,7 +6399,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11751433989801294344
+          1266355932999225698
         ]
       ], 
       "reviewed-by-human": true
@@ -6234,7 +6408,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900375946366690268
+          17245097583413490008
         ]
       ], 
       "reviewed-by-human": true
@@ -6279,7 +6453,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643161545794817643
+          9028961643555474074
         ]
       ], 
       "reviewed-by-human": true
@@ -6288,7 +6462,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511393143767092759
+          9235059342087793513
         ]
       ], 
       "reviewed-by-human": true
@@ -6297,7 +6471,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511393143767092759
+          9235059342087793513
         ]
       ], 
       "reviewed-by-human": true
@@ -6330,19 +6504,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3391919152857140005
+          6405163685079178064
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6728484050681732905
+          5778987087064312358
         ]
       ], 
       "reviewed-by-human": true
@@ -6351,7 +6522,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3122543961009401649
+          10848355732603050567
         ]
       ], 
       "reviewed-by-human": true
@@ -6360,7 +6531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9697510406290295114
+          17754841998252196891
         ]
       ], 
       "reviewed-by-human": true
@@ -6405,7 +6576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2569157419236777949
+          15171677204658263732
         ]
       ], 
       "reviewed-by-human": true
@@ -6414,7 +6585,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1370520776657521517
+          4131799565799962704
         ]
       ], 
       "reviewed-by-human": true
@@ -6423,7 +6594,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14351036907860663618
+          17298767776572466394
         ]
       ], 
       "reviewed-by-human": true
@@ -6432,7 +6603,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16518858492509120064
+          14593570443940328754
         ]
       ], 
       "reviewed-by-human": true
@@ -6441,7 +6612,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15238792371190456534
+          17687576741285937089
         ]
       ], 
       "reviewed-by-human": true
@@ -6450,7 +6621,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9343804110836898394
+          17725216555771216881
         ]
       ], 
       "reviewed-by-human": true
@@ -6459,43 +6630,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7104435648687592254
+          15721345070217154235
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18100962139592302037
+          3651441664185012389
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13861401015232083062
+          14549425769583729518
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3101476576521947165
+          13546074453897362674
         ]
       ], 
       "reviewed-by-human": true
@@ -6504,7 +6666,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10055081768235896808
+          2645433785253737964
         ]
       ], 
       "reviewed-by-human": true
@@ -6513,7 +6675,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350439713947208131
+          15583304423700623450
         ]
       ], 
       "reviewed-by-human": true
@@ -6573,7 +6735,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17553587858062838425
+          8756248250594748551
         ]
       ], 
       "reviewed-by-human": true
@@ -6606,7 +6768,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17553587858062838425
+          8756248250594748551
         ]
       ], 
       "reviewed-by-human": true
@@ -6639,7 +6801,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17553587858062838425
+          8756248250594748551
         ]
       ], 
       "reviewed-by-human": true
@@ -6672,12 +6834,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7758597652352633244
+          11898977239618964760
         ]
       ], 
-      "bugs": [
-        1596
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -6709,19 +6868,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11934469864526604734
+          6287674327505113148
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13276990043616594793
+          17044527983161977372
         ]
       ], 
       "reviewed-by-human": true
@@ -6730,7 +6886,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12053534281222176521
+          16679250406161029701
         ]
       ], 
       "reviewed-by-human": true
@@ -6739,7 +6895,277 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15869818052487928163
+          3140032282102690470
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16064342292519177703
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16328681329150531419
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3387451507864625255
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          530696139292907434
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5010538637752141343
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17349807853851939382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13456162487414097587
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7108849406246770065
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12945819083706719382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2689185877755429682
         ]
       ], 
       "reviewed-by-human": true
@@ -6889,7 +7315,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15240835456320409473
+          4656886197492028969
         ]
       ], 
       "reviewed-by-human": true
@@ -6898,7 +7324,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          249289862803617115
+          10009949554846362902
         ]
       ], 
       "reviewed-by-human": true
@@ -6907,7 +7333,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15497506993121739956
+          13683962615885282836
         ]
       ], 
       "reviewed-by-human": true
@@ -6928,13 +7354,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          4625205966782873365
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -6972,53 +7395,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2143850486822799899
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15350252464204167970
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18264085885951369494
+          17899022691963121600
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6845561371571987961
+          8212877465944976095
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3236205967252504838
+          10591577672223116924
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "patheffect_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4427938030923047423
+          14182680775472184218
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "patheffect_8888.png": {
       "allowed-digests": [
@@ -7249,7 +7714,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -7258,7 +7723,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -7267,7 +7732,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5910660068342021532
+          12602702778262712881
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3817855389012712870
         ]
       ], 
       "reviewed-by-human": true
@@ -7276,7 +7768,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15710121230086435602
+          14656164594743658373
         ]
       ], 
       "reviewed-by-human": true
@@ -7285,7 +7777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1763586683528188858
+          7375436820633666472
         ]
       ], 
       "reviewed-by-human": true
@@ -7294,7 +7786,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1763586683528188858
+          7375436820633666472
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
         ]
       ], 
       "reviewed-by-human": true
@@ -7326,6 +7845,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -7363,7 +7909,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6571118611946058617
+          13710370929503896242
         ]
       ], 
       "reviewed-by-human": true
@@ -7372,7 +7918,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2985268228390879272
+          14868659503042841956
         ]
       ], 
       "reviewed-by-human": true
@@ -7381,7 +7927,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4090908000301047480
+          16248212291629065148
         ]
       ], 
       "reviewed-by-human": true
@@ -7426,7 +7972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9971396627985154706
+          11616620239881546194
         ]
       ], 
       "reviewed-by-human": true
@@ -7435,7 +7981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6891379388563692035
+          13695847048236137972
         ]
       ], 
       "reviewed-by-human": true
@@ -7444,7 +7990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7133096296319789026
+          8928805579832560331
         ]
       ], 
       "reviewed-by-human": true
@@ -7453,7 +7999,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1288004664951630498
+          10424880346112239562
         ]
       ], 
       "reviewed-by-human": true
@@ -7462,7 +8008,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7223243377781866680
+          24796932854446382
         ]
       ], 
       "reviewed-by-human": true
@@ -7471,7 +8017,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12191681455930613784
+          3232711541650961499
         ]
       ], 
       "reviewed-by-human": true
@@ -7504,13 +8050,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17294523260520684759
+          16089700058417943666
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_565.png": {
       "allowed-digests": [
@@ -7540,13 +8083,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14470264741921611599
+          15031929842713675110
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -7579,10 +8119,7 @@
           16787331154477637635
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "resizeimagefilter_565.png": {
       "allowed-digests": [
@@ -7660,13 +8197,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9108911139001347487
+          18340118795193628429
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rrect_8888.png": {
       "allowed-digests": [
@@ -7756,7 +8290,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11436925749408943089
+          18385677641429471665
         ]
       ], 
       "reviewed-by-human": true
@@ -7846,10 +8380,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2310215659204296151
+          13432058568869482858
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rrect_gpu.png": {
       "allowed-digests": [
@@ -7894,7 +8428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1410103792220800931
+          8082315010167812063
         ]
       ], 
       "reviewed-by-human": true
@@ -7903,7 +8437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2293107890848557380
+          1864383706473625196
         ]
       ], 
       "reviewed-by-human": true
@@ -7912,7 +8446,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12802535321257469607
+          8364375847748518642
         ]
       ], 
       "reviewed-by-human": true
@@ -7921,7 +8455,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5067627966950621939
+          14137833661681785135
         ]
       ], 
       "reviewed-by-human": true
@@ -7930,7 +8464,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7517125506221018662
+          14791436059610164321
         ]
       ], 
       "reviewed-by-human": true
@@ -7939,7 +8473,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7606734424710060898
+          5563001502326738261
         ]
       ], 
       "reviewed-by-human": true
@@ -7948,7 +8482,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9319993179135558393
+          13924533833588869139
         ]
       ], 
       "reviewed-by-human": true
@@ -7957,7 +8491,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16574168428196349390
+          7186960244825707915
         ]
       ], 
       "reviewed-by-human": true
@@ -7966,7 +8500,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3968605136301912973
+          1376209882197320131
         ]
       ], 
       "reviewed-by-human": true
@@ -7975,7 +8509,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17418047642108977670
+          164630131521766648
         ]
       ], 
       "reviewed-by-human": true
@@ -7984,7 +8518,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1556868127331379479
+          15540325168021281899
         ]
       ], 
       "reviewed-by-human": true
@@ -7993,7 +8527,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14148935305656142180
+          13328221062685842667
         ]
       ], 
       "reviewed-by-human": true
@@ -8110,13 +8644,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3556699044314006968
+          163919757956159506
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "shadows_8888.png": {
       "allowed-digests": [
@@ -8278,19 +8809,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16883506100501459281
+          7976181664392439726
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2422870003307313999
+          6856823905290886591
         ]
       ], 
       "reviewed-by-human": true
@@ -8299,7 +8827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8297028920093819054
+          18010746007073820817
         ]
       ], 
       "reviewed-by-human": true
@@ -8308,7 +8836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16021439723556558918
+          14249365533430423372
         ]
       ], 
       "reviewed-by-human": true
@@ -8317,7 +8845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2422870003307313999
+          6856823905290886591
         ]
       ], 
       "reviewed-by-human": true
@@ -8326,7 +8854,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8505743106500736554
+          17160448045672967434
         ]
       ], 
       "reviewed-by-human": true
@@ -8335,7 +8863,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6566419177529590403
+          18363282621086286494
         ]
       ], 
       "reviewed-by-human": true
@@ -8344,7 +8872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2276755423088781585
+          13802666172572918659
         ]
       ], 
       "reviewed-by-human": true
@@ -8353,7 +8881,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2247183642119438840
+          1769885343134219810
         ]
       ], 
       "reviewed-by-human": true
@@ -8362,7 +8890,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8484924843781194174
+          11976294617324151262
         ]
       ], 
       "reviewed-by-human": true
@@ -8371,7 +8899,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13988021646843375450
+          16249993606621732315
         ]
       ], 
       "reviewed-by-human": true
@@ -8389,7 +8917,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13014561373059764150
+          7523538521688389229
         ]
       ], 
       "reviewed-by-human": true
@@ -8434,25 +8962,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14585555250092963383
+          13909757336310240518
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "spritebitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6423558589708144215
+          17885518595384354919
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "spritebitmap_gpu.png": {
       "allowed-digests": [
@@ -8470,7 +8992,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17619211944443238901
+          11699531654048406518
         ]
       ], 
       "reviewed-by-human": true
@@ -8479,7 +9001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476337759406055776
+          4523091657809672686
         ]
       ], 
       "reviewed-by-human": true
@@ -8488,7 +9010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1838432270932859890
+          6909139710433844754
         ]
       ], 
       "reviewed-by-human": true
@@ -8533,7 +9055,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2450726810754127074
+          8404092897044868761
         ]
       ], 
       "reviewed-by-human": true
@@ -8542,7 +9064,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12690621371284385511
+          14156844530688032350
         ]
       ], 
       "reviewed-by-human": true
@@ -8551,7 +9073,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16688606203531911724
+          14632249572216229788
         ]
       ], 
       "reviewed-by-human": true
@@ -8596,13 +9118,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1252564837192523211
+          10731083935300051992
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "strokerects_8888.png": {
       "allowed-digests": [
@@ -8632,13 +9151,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8397039244880318300
+          9117693921833992353
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "strokes3_8888.png": {
       "allowed-digests": [
@@ -8740,7 +9256,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10084807092550654294
+          5033516764144244033
         ]
       ], 
       "reviewed-by-human": true
@@ -8749,7 +9265,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15846255821264969272
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -8758,7 +9274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1841381969935611676
+          17666174042372237996
         ]
       ], 
       "reviewed-by-human": true
@@ -8791,67 +9307,79 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17892855770534705304
+          11181230850811915000
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "testimagefilters_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15528863190484305841
+          1369006746513120542
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "testimagefilters_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15197842121034928067
+          10584886924228958226
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "testimagefilters_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5204419253707868565
+          16334968078566298182
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texdata_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1221372586972395156
+          2736593828543197285
         ]
       ], 
-      "bugs": [
-        2146
+      "reviewed-by-human": true
+    }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17484439610611592723
+        ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11311445240364221126
+          3352233736449563022
         ]
       ], 
       "reviewed-by-human": true
@@ -8860,7 +9388,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9681917212200619788
+          377328076341373940
         ]
       ], 
       "reviewed-by-human": true
@@ -8869,7 +9397,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9681917212200619788
+          6885322238950860527
         ]
       ], 
       "reviewed-by-human": true
@@ -8878,10 +9406,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11365388622786306146
+          8813824922010639566
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -8914,10 +9442,7 @@
           18123780144204716606
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_565.png": {
       "allowed-digests": [
@@ -8950,16 +9475,13 @@
           14598560863929901019
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15884441815359625883
+          15732727687033594466
         ]
       ], 
       "reviewed-by-human": true
@@ -8968,7 +9490,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8977,7 +9499,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8986,7 +9508,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1410103792220800931
+          8082315010167812063
         ]
       ], 
       "reviewed-by-human": true
@@ -8995,7 +9517,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2293107890848557380
+          1864383706473625196
         ]
       ], 
       "reviewed-by-human": true
@@ -9004,7 +9526,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12802535321257469607
+          8364375847748518642
         ]
       ], 
       "reviewed-by-human": true
@@ -9013,7 +9535,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5067627966950621939
+          14137833661681785135
         ]
       ], 
       "reviewed-by-human": true
@@ -9022,7 +9544,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7517125506221018662
+          14791436059610164321
         ]
       ], 
       "reviewed-by-human": true
@@ -9031,7 +9553,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7606734424710060898
+          5563001502326738261
         ]
       ], 
       "reviewed-by-human": true
@@ -9040,7 +9562,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1916052269453883881
+          1211393994967316525
         ]
       ], 
       "reviewed-by-human": true
@@ -9049,7 +9571,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14968443247329529117
+          14480947444732898359
         ]
       ], 
       "reviewed-by-human": true
@@ -9058,7 +9580,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2592756938145874158
+          3017506100985054305
         ]
       ], 
       "reviewed-by-human": true
@@ -9067,7 +9589,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8143654303249859581
+          11691375869271942933
         ]
       ], 
       "reviewed-by-human": true
@@ -9076,7 +9598,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13298836052288001622
+          14216970501880738242
         ]
       ], 
       "reviewed-by-human": true
@@ -9085,7 +9607,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1838655959411055883
+          14701343820986514047
         ]
       ], 
       "reviewed-by-human": true
@@ -9130,7 +9652,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18223584313005621176
+          18323972177455356231
         ]
       ], 
       "reviewed-by-human": true
@@ -9139,7 +9661,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6036270199387229964
+          5412705785906131810
         ]
       ], 
       "reviewed-by-human": true
@@ -9148,7 +9670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1045519680717029999
+          6056335833066049972
         ]
       ], 
       "reviewed-by-human": true
@@ -9157,7 +9679,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11426788897705172941
+          12765023135113455799
         ]
       ], 
       "reviewed-by-human": true
@@ -9166,7 +9688,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3057908372893981204
+          14725542749908228
         ]
       ], 
       "reviewed-by-human": true
@@ -9175,7 +9697,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3057908372893981204
+          14725542749908228
         ]
       ], 
       "reviewed-by-human": true
@@ -9184,7 +9706,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          714676201649578466
+          11838752118610481979
         ]
       ], 
       "reviewed-by-human": true
@@ -9193,7 +9715,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370428013149648258
+          6475798309604476317
         ]
       ], 
       "reviewed-by-human": true
@@ -9202,7 +9724,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370428013149648258
+          6475798309604476317
         ]
       ], 
       "reviewed-by-human": true
@@ -9211,7 +9733,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5443026492957156846
+          508446862935931396
         ]
       ], 
       "reviewed-by-human": true
@@ -9220,7 +9742,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2080761164861757576
+          17546866530171427130
         ]
       ], 
       "reviewed-by-human": true
@@ -9229,7 +9751,115 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8882773799933891216
+          539829354440306365
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1952127887831515847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          26534852890899274
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1952127887831515847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          26534852890899274
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1752599991641140864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12914772605547417778
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1752599991641140864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12914772605547417778
         ]
       ], 
       "reviewed-by-human": true
@@ -9301,7 +9931,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9457742961471532948
+          14144865147136195678
         ]
       ], 
       "reviewed-by-human": true
@@ -9310,7 +9940,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14527641142409674625
+          6274320838479527537
         ]
       ], 
       "reviewed-by-human": true
@@ -9319,7 +9949,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3597293503861619263
+          11188008329308255443
         ]
       ], 
       "reviewed-by-human": true
@@ -9328,7 +9958,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3820411693075952029
+          6737255892443592724
         ]
       ], 
       "reviewed-by-human": true
@@ -9337,7 +9967,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3587671227602487124
+          12569529133241702893
         ]
       ], 
       "reviewed-by-human": true
@@ -9346,7 +9976,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3897538395660363842
+          15091714070778715037
         ]
       ], 
       "reviewed-by-human": true
@@ -9355,7 +9985,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10958353996143090911
+          3112652115716203250
         ]
       ], 
       "reviewed-by-human": true
@@ -9364,7 +9994,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17000878545702467803
+          12938112915997113104
         ]
       ], 
       "reviewed-by-human": true
@@ -9373,7 +10003,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          167015306588432469
+          2398735729200624910
         ]
       ], 
       "reviewed-by-human": true
@@ -9382,7 +10012,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4613530689633279630
+          4006560807085464955
         ]
       ], 
       "reviewed-by-human": true
@@ -9391,7 +10021,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2952493606222488372
+          6431759696672110544
         ]
       ], 
       "reviewed-by-human": true
@@ -9400,7 +10030,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2992781255766374719
+          4474185865412834223
         ]
       ], 
       "reviewed-by-human": true
@@ -9409,7 +10039,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12480404425423207055
+          15662585344043467067
         ]
       ], 
       "reviewed-by-human": true
@@ -9418,7 +10048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14561360239620524377
+          15172719087640402575
         ]
       ], 
       "reviewed-by-human": true
@@ -9427,7 +10057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16987219934025015385
+          17724920587118100620
         ]
       ], 
       "reviewed-by-human": true
@@ -9436,7 +10066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4935026131066456043
+          10103658154547338580
         ]
       ], 
       "reviewed-by-human": true
@@ -9445,7 +10075,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10963470347499254787
+          1637047472327850125
         ]
       ], 
       "reviewed-by-human": true
@@ -9454,7 +10084,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4224918093600621161
+          11638705468219848676
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7017362768546994774
         ]
       ], 
       "reviewed-by-human": true
diff --git a/expectations/gm/Test-Android-Nexus7-Tegra3-Arm7-Debug/expected-results.json b/expectations/gm/Test-Android-Nexus7-Tegra3-Arm7-Debug/expected-results.json
index be5e478..791ab8e 100644
--- a/expectations/gm/Test-Android-Nexus7-Tegra3-Arm7-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-Nexus7-Tegra3-Arm7-Debug/expected-results.json
@@ -93,10 +93,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15460761261952737126
+          14297927035801776466
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -216,7 +217,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12148282628610020026
+          10845196607849461596
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -260,39 +288,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9345454686226166633
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
@@ -315,10 +310,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14245466793676403290
+          11976769394076607440
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -345,7 +340,8 @@
           15331153357897203778
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bigtext_565.png": {
       "allowed-digests": [
@@ -423,7 +419,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5556270988884295076
+          12687331394697954528
         ]
       ], 
       "reviewed-by-human": true
@@ -432,7 +428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410204863204197194
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -441,7 +437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12232189640901617615
+          15436081105654232696
         ]
       ], 
       "reviewed-by-human": true
@@ -643,10 +639,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5267344739982858700
+          5114692605203855359
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
@@ -695,7 +694,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16186598678776995408
+          1176222842118078025
         ]
       ], 
       "reviewed-by-human": true
@@ -1690,6 +1689,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14473518652319975040
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -1964,7 +1990,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12486595519840703485
+          15477254742759075309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13364049019106243487
         ]
       ], 
       "reviewed-by-human": false
@@ -2225,7 +2278,8 @@
           8609345557630302846
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "clipped-bitmap-shaders-clamp-hq_565.png": {
       "allowed-digests": [
@@ -2769,7 +2823,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15764519043297885758
+          4104797309315770800
         ]
       ], 
       "reviewed-by-human": true
@@ -2778,7 +2832,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7935307680550293784
+          6544536706877310514
         ]
       ], 
       "reviewed-by-human": true
@@ -2787,7 +2841,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5471012436762551398
+          7066435915747351913
         ]
       ], 
       "reviewed-by-human": true
@@ -2796,7 +2850,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1557613698479648092
+          8097997023778848191
         ]
       ], 
       "reviewed-by-human": true
@@ -2805,7 +2859,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          686626615788563308
+          5836493341538608113
         ]
       ], 
       "reviewed-by-human": true
@@ -2814,7 +2868,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9960042924980287727
+          5953472570329245150
         ]
       ], 
       "reviewed-by-human": true
@@ -2823,7 +2877,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5930938593239004653
+          4165425675033352640
         ]
       ], 
       "reviewed-by-human": true
@@ -2832,7 +2886,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3190552677201665775
+          10152516748782571739
         ]
       ], 
       "reviewed-by-human": true
@@ -2841,7 +2895,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          684132920930319303
+          13262888511953363261
         ]
       ], 
       "reviewed-by-human": true
@@ -2850,7 +2904,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4870317370734649728
+          8180502121217066191
         ]
       ], 
       "reviewed-by-human": true
@@ -2859,7 +2913,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5783287451488289297
+          16993829969091028380
         ]
       ], 
       "reviewed-by-human": true
@@ -2868,7 +2922,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11810056493244595774
+          10501115473108298882
         ]
       ], 
       "reviewed-by-human": true
@@ -2931,28 +2985,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17707691143950027168
+          4792118895672570848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788619303593885819
+          11285887424651164487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12477159368808426654
+          8056631522680651323
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -3030,7 +3084,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17138342910351740780
+          15418783980877386199
         ]
       ], 
       "reviewed-by-human": true
@@ -3039,7 +3093,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13937678633951136440
+          7882161322447216882
         ]
       ], 
       "reviewed-by-human": true
@@ -3048,7 +3102,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13341606961501773179
+          9084726022784412994
         ]
       ], 
       "reviewed-by-human": true
@@ -3057,7 +3111,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2256130412784819033
+          3184062263576953667
         ]
       ], 
       "reviewed-by-human": true
@@ -3066,7 +3120,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10471902765578272701
+          713799816796517938
         ]
       ], 
       "reviewed-by-human": true
@@ -3075,7 +3129,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3167565818671493256
+          1524421127104888844
         ]
       ], 
       "reviewed-by-human": true
@@ -3184,7 +3238,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          791731370982641459
+          12983436663287935053
         ]
       ], 
       "reviewed-by-human": true
@@ -3226,7 +3280,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9374541812861034293
+          11475660560101599954
         ]
       ], 
       "reviewed-by-human": true
@@ -3235,7 +3289,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2576698895183287698
+          7311723676588845146
         ]
       ], 
       "reviewed-by-human": true
@@ -3244,7 +3298,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11379833094085660515
+          8359929465185009217
         ]
       ], 
       "reviewed-by-human": true
@@ -3282,7 +3336,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3767760557629765982
+          4057230872151110302
         ]
       ], 
       "ignore-failure": false, 
@@ -3292,7 +3346,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12070678672447530766
+          9482070623821433904
         ]
       ], 
       "ignore-failure": false, 
@@ -3302,7 +3356,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14570840123822355129
+          6390479542851385994
         ]
       ], 
       "ignore-failure": false, 
@@ -3312,43 +3366,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -3357,7 +3402,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -3366,7 +3411,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
       "reviewed-by-human": true
@@ -3375,67 +3420,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
       "reviewed-by-human": true
@@ -3444,7 +3474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6989712392624471913
+          17775297231868448514
         ]
       ], 
       "reviewed-by-human": true
@@ -3453,7 +3483,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10855232109519818829
+          12804472649182277577
         ]
       ], 
       "reviewed-by-human": true
@@ -3462,19 +3492,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2410384022323180262
+          8136862497622595689
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -3483,7 +3510,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -3492,7 +3519,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
       "reviewed-by-human": true
@@ -3501,67 +3528,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
       "reviewed-by-human": true
@@ -3570,7 +3582,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2497837460215148124
+          6055955940623478607
         ]
       ], 
       "reviewed-by-human": true
@@ -3579,7 +3591,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13192464168020553898
+          11797865288006977816
         ]
       ], 
       "reviewed-by-human": true
@@ -3588,19 +3600,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11818903631048803455
+          9781042422538097277
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -3609,7 +3618,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181838889584580159
         ]
       ], 
       "reviewed-by-human": true
@@ -3618,7 +3636,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          4886211991926050486
         ]
       ], 
       "reviewed-by-human": true
@@ -3627,7 +3645,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          8737545656412765906
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8820398513653894612
         ]
       ], 
       "reviewed-by-human": true
@@ -3636,7 +3663,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -3645,7 +3672,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8820398513653894612
         ]
       ], 
       "reviewed-by-human": true
@@ -3654,7 +3690,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          4707049264800437834
         ]
       ], 
       "reviewed-by-human": true
@@ -3663,7 +3699,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          3175389971476411688
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4277401128811031135
         ]
       ], 
       "reviewed-by-human": true
@@ -3672,7 +3717,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
       "reviewed-by-human": true
@@ -3690,16 +3735,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2931946104892198077
+          4473589478120711048
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5455618422902283397
+          15797039913993285826
         ]
       ], 
       "reviewed-by-human": true
@@ -3708,7 +3754,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14095817193753318732
+          17497164562330387900
         ]
       ], 
       "reviewed-by-human": true
@@ -3717,7 +3763,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2692505469297757718
+          11947571491152707744
         ]
       ], 
       "reviewed-by-human": true
@@ -3726,7 +3772,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          716171842978913864
+          273445276579232833
         ]
       ], 
       "reviewed-by-human": true
@@ -3735,7 +3781,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17171710908581496295
+          13357226331142394630
         ]
       ], 
       "reviewed-by-human": true
@@ -3744,7 +3790,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1289208517076135500
+          13157598198362907279
         ]
       ], 
       "reviewed-by-human": true
@@ -3780,7 +3826,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16452419234213932266
+          1802138798652377585
         ]
       ], 
       "reviewed-by-human": true
@@ -3789,7 +3835,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13347568447034524087
+          588269449619860245
         ]
       ], 
       "reviewed-by-human": true
@@ -3798,7 +3844,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          768255655200339155
+          12200967819639880627
         ]
       ], 
       "reviewed-by-human": true
@@ -3911,6 +3957,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -4068,7 +4141,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -4077,7 +4150,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -4095,7 +4168,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -4104,7 +4177,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -4122,7 +4195,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -4131,7 +4204,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -4149,7 +4222,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -4158,7 +4231,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -4176,7 +4249,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -4185,7 +4258,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -4203,7 +4276,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -4212,7 +4285,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -4230,7 +4303,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -4239,7 +4312,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -4257,7 +4330,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -4266,7 +4339,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -4284,7 +4357,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -4293,7 +4366,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -4338,7 +4411,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -4347,7 +4420,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -4392,7 +4465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -4401,7 +4474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -4419,7 +4492,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -4428,7 +4501,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
@@ -4442,6 +4515,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18400047645694418480
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -4455,72 +4555,58 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          17276962213970077366
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          8694218356938189525
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1857288326388942863
         ]
       ], 
       "bugs": [
-        1578
+        2887
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          4335659971728708662
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
@@ -4553,11 +4639,38 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2500355683115767624
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6163838330434021775
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7818310295492545479
+          11716334334721910796
         ]
       ], 
       "ignore-failure": false, 
@@ -4567,7 +4680,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4994151175360770217
+          5693920054563327483
         ]
       ], 
       "ignore-failure": false, 
@@ -4577,7 +4690,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10768745779609912779
+          11558678086719578288
         ]
       ], 
       "ignore-failure": false, 
@@ -4934,6 +5047,222 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1124904529638696182
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7401870099194519468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7401870099194519468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18181809164582745765
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18177453939513851246
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14988814117683836650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4372045147535855874
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7401870099194519468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863085462100832326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8673137414478041582
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271247215169625597
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7396548710257716434
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -4965,10 +5294,7 @@
           14015662146260093838
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_matrix_565.png": {
       "allowed-digests": [
@@ -5031,7 +5357,7 @@
           3493263944278727556
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_565.png": {
       "allowed-digests": [
@@ -5058,7 +5384,7 @@
           15451235578409962625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_565.png": {
       "allowed-digests": [
@@ -5085,7 +5411,7 @@
           10135349930059020946
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_565.png": {
       "allowed-digests": [
@@ -5232,7 +5558,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -5250,7 +5576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14930897081171395685
+          13837779357393426492
         ]
       ], 
       "ignore-failure": false, 
@@ -5260,7 +5586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13538992606665750486
+          8988444324654919932
         ]
       ], 
       "reviewed-by-human": true
@@ -5330,10 +5656,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17297019758764752680
+          5005820819642466038
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -5425,11 +5752,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          741134624395776214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          357284903731074601
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5034635930426005712
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3794665630847901594
+          13620335786972140736
         ]
       ], 
       "reviewed-by-human": true
@@ -5438,7 +5792,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7748801528548244433
+          17030111096598942390
         ]
       ], 
       "reviewed-by-human": true
@@ -5447,7 +5801,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6332063967132987532
+          18278123345850322998
         ]
       ], 
       "ignore-failure": false, 
@@ -5457,7 +5811,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259128835424197006
+          1922338586017046100
         ]
       ], 
       "reviewed-by-human": true
@@ -5466,7 +5820,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13149265802466457140
+          3693078186234250164
         ]
       ], 
       "reviewed-by-human": true
@@ -5475,7 +5829,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4974844375073481282
+          6350563482483431609
         ]
       ], 
       "reviewed-by-human": true
@@ -5511,7 +5865,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6719033984262147569
+          9334915207072042375
         ]
       ], 
       "reviewed-by-human": true
@@ -5520,7 +5874,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9527595429529547733
+          4262113639047937913
         ]
       ], 
       "reviewed-by-human": true
@@ -5529,7 +5883,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6008461518333374558
+          16944197972322374985
         ]
       ], 
       "ignore-failure": false, 
@@ -5539,17 +5893,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8498778868685964382
+          9643897842146508458
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          880034339526468883
+          14154076457851775362
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_gpu.png": {
       "allowed-digests": [
@@ -5564,7 +5920,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219558445660995645
+          16816155573392653040
         ]
       ], 
       "reviewed-by-human": true
@@ -5573,7 +5929,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          861754899676926834
+          15621659488709502951
         ]
       ], 
       "reviewed-by-human": true
@@ -5582,7 +5938,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5664795631214643440
+          9176520558186220317
         ]
       ], 
       "reviewed-by-human": true
@@ -5591,7 +5947,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15200137971968303012
+          14400660572715212845
         ]
       ], 
       "reviewed-by-human": true
@@ -5600,7 +5956,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199776944359958607
+          12820728063175372793
         ]
       ], 
       "reviewed-by-human": true
@@ -5619,23 +5975,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15332790159062618713
+          8663959489913767436
         ]
       ], 
       "reviewed-by-human": true
@@ -5644,7 +6002,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5274487773236388163
+          4458594706234736506
         ]
       ], 
       "reviewed-by-human": true
@@ -5653,7 +6011,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10772725192724193725
+          7881653068493848399
         ]
       ], 
       "reviewed-by-human": true
@@ -5662,7 +6020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6138663057683877780
+          5896248217426666691
         ]
       ], 
       "reviewed-by-human": true
@@ -5803,13 +6161,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1128030240545260947
+          9202866929862689391
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
@@ -5869,7 +6227,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15118920252874319058
+          9075523320529578103
         ]
       ], 
       "reviewed-by-human": true
@@ -5878,7 +6236,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13213375518846743511
+          4131799565799962704
         ]
       ], 
       "reviewed-by-human": true
@@ -5887,7 +6245,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5216420263713929251
+          5217925660404039517
         ]
       ], 
       "reviewed-by-human": true
@@ -5896,7 +6254,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7394602124225746876
+          4095489997625677813
         ]
       ], 
       "reviewed-by-human": true
@@ -5905,7 +6263,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768949088352973106
+          17687576741285937089
         ]
       ], 
       "reviewed-by-human": true
@@ -5914,7 +6272,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8388956649707556649
+          12660892446188981889
         ]
       ], 
       "reviewed-by-human": true
@@ -5939,9 +6297,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11768049299524715926
+          12551593558877396461
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumamode_565.png": {
       "allowed-digests": [
@@ -5971,7 +6330,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14753870890166488787
+          13546074453897362674
         ]
       ], 
       "reviewed-by-human": true
@@ -5980,7 +6339,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12332409505555151686
+          2645433785253737964
         ]
       ], 
       "reviewed-by-human": true
@@ -5989,7 +6348,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413857436675528921
+          9399689272866614344
         ]
       ], 
       "reviewed-by-human": true
@@ -6049,7 +6408,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6082,7 +6441,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6115,7 +6474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6175,13 +6534,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6322714542176233479
+          2764095265218154928
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
@@ -6210,6 +6569,276 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12026275426271527150
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6958579088836506224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2297483525893474810
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18100843957901826201
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4478490979400536378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16204222930251940046
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16721089005631938371
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9760231745798245964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5749308152293375604
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662786566822056022
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -6367,7 +6996,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15293668784585893125
+          4656886197492028969
         ]
       ], 
       "reviewed-by-human": true
@@ -6376,7 +7005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17470748697630737319
+          10009949554846362902
         ]
       ], 
       "reviewed-by-human": true
@@ -6385,7 +7014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6258969688980197856
+          13683962615885282836
         ]
       ], 
       "reviewed-by-human": true
@@ -6418,13 +7047,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          2379796454057556376
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -6453,6 +7082,60 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7258406699897973752
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17286230013131859770
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -6694,7 +7377,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -6703,7 +7386,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -6712,12 +7395,39 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11853841295252803459
+          9624355400568283482
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9747549608031779530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -6745,6 +7455,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14249024706582191865
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -6772,6 +7509,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -6804,7 +7568,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18000254716935645999
+          13710370929503896242
         ]
       ], 
       "reviewed-by-human": true
@@ -6813,7 +7577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16383033135480419663
+          14868659503042841956
         ]
       ], 
       "reviewed-by-human": true
@@ -6822,7 +7586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11294115177099606513
+          11236564600268325973
         ]
       ], 
       "reviewed-by-human": true
@@ -6858,7 +7622,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16422530932852428674
+          2214368729624239628
         ]
       ], 
       "reviewed-by-human": true
@@ -6867,7 +7631,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13797585911734062488
+          13695847048236137972
         ]
       ], 
       "reviewed-by-human": true
@@ -6876,7 +7640,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16912233602921927369
+          14658443335125933532
         ]
       ], 
       "reviewed-by-human": true
@@ -6885,7 +7649,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13221078215540522692
+          6757078992106948579
         ]
       ], 
       "reviewed-by-human": true
@@ -6894,7 +7658,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7149831205496297560
+          24796932854446382
         ]
       ], 
       "reviewed-by-human": true
@@ -6903,7 +7667,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16814255993965116910
+          3924532181987290555
         ]
       ], 
       "reviewed-by-human": true
@@ -6954,10 +7718,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199326463862210265
+          2683400429924886711
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -7338,7 +8103,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6385849539525834967
+          13572029116278729382
         ]
       ], 
       "reviewed-by-human": true
@@ -7365,7 +8130,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7460303501608458490
+          8475139782488098737
         ]
       ], 
       "reviewed-by-human": true
@@ -7773,7 +8538,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14585555250092963383
+          13909757336310240518
         ]
       ], 
       "reviewed-by-human": true
@@ -7782,7 +8547,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6423558589708144215
+          17885518595384354919
         ]
       ], 
       "reviewed-by-human": true
@@ -7803,7 +8568,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11744373400809739356
+          11699531654048406518
         ]
       ], 
       "reviewed-by-human": true
@@ -7812,7 +8577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8270526029969251327
+          4523091657809672686
         ]
       ], 
       "reviewed-by-human": true
@@ -7821,7 +8586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17477851404941805193
+          17847682713276246556
         ]
       ], 
       "reviewed-by-human": true
@@ -8028,7 +8793,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10230426069067413407
+          18286981917824090179
         ]
       ], 
       "reviewed-by-human": true
@@ -8037,7 +8802,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15098401526248766364
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -8046,7 +8811,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933051189242765749
+          4566289877673568210
         ]
       ], 
       "reviewed-by-human": true
@@ -8082,7 +8847,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15528863190484305841
+          1369006746513120542
         ]
       ], 
       "reviewed-by-human": true
@@ -8091,7 +8856,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15197842121034928067
+          10584886924228958226
         ]
       ], 
       "reviewed-by-human": true
@@ -8132,6 +8897,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          163112871246100159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          374437982401021225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -8163,10 +8955,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16780536364041129122
+          758934049590219880
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -8193,7 +8985,8 @@
           15858307657519327001
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_565.png": {
       "allowed-digests": [
@@ -8220,13 +9013,14 @@
           12367524911555205763
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17022932193658353157
+          15732727687033594466
         ]
       ], 
       "reviewed-by-human": true
@@ -8235,7 +9029,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8244,7 +9038,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8325,7 +9119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          539915969408525938
+          11627825601504219410
         ]
       ], 
       "reviewed-by-human": true
@@ -8352,7 +9146,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10071678485394503756
+          10094506929640064268
         ]
       ], 
       "reviewed-by-human": true
@@ -8492,6 +9286,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14824515475287110550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14824515475287110550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6750354401496927826
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6750354401496927826
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -8604,7 +9506,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3394570787947912684
+          3112652115716203250
         ]
       ], 
       "reviewed-by-human": true
@@ -8613,7 +9515,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4231863532718175149
+          12938112915997113104
         ]
       ], 
       "reviewed-by-human": true
@@ -8622,7 +9524,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682926307093534631
+          7099868207716879131
         ]
       ], 
       "reviewed-by-human": true
@@ -8649,7 +9551,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          238819112342131317
+          11587903491111347656
         ]
       ], 
       "reviewed-by-human": true
@@ -8676,7 +9578,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10255763987814493261
+          1169777226871264424
         ]
       ], 
       "reviewed-by-human": true
@@ -8703,10 +9605,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7871079263072256188
+          4896933091710642125
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6719196348100419960
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-Nexus7-Tegra3-Arm7-Release/expected-results.json b/expectations/gm/Test-Android-Nexus7-Tegra3-Arm7-Release/expected-results.json
index be5e478..791ab8e 100644
--- a/expectations/gm/Test-Android-Nexus7-Tegra3-Arm7-Release/expected-results.json
+++ b/expectations/gm/Test-Android-Nexus7-Tegra3-Arm7-Release/expected-results.json
@@ -93,10 +93,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15460761261952737126
+          14297927035801776466
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -216,7 +217,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12148282628610020026
+          10845196607849461596
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -260,39 +288,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9345454686226166633
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
@@ -315,10 +310,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14245466793676403290
+          11976769394076607440
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -345,7 +340,8 @@
           15331153357897203778
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bigtext_565.png": {
       "allowed-digests": [
@@ -423,7 +419,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5556270988884295076
+          12687331394697954528
         ]
       ], 
       "reviewed-by-human": true
@@ -432,7 +428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410204863204197194
+          14046350300528444244
         ]
       ], 
       "reviewed-by-human": true
@@ -441,7 +437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12232189640901617615
+          15436081105654232696
         ]
       ], 
       "reviewed-by-human": true
@@ -643,10 +639,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5267344739982858700
+          5114692605203855359
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
@@ -695,7 +694,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16186598678776995408
+          1176222842118078025
         ]
       ], 
       "reviewed-by-human": true
@@ -1690,6 +1689,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14473518652319975040
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -1964,7 +1990,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12486595519840703485
+          15477254742759075309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13364049019106243487
         ]
       ], 
       "reviewed-by-human": false
@@ -2225,7 +2278,8 @@
           8609345557630302846
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "clipped-bitmap-shaders-clamp-hq_565.png": {
       "allowed-digests": [
@@ -2769,7 +2823,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15764519043297885758
+          4104797309315770800
         ]
       ], 
       "reviewed-by-human": true
@@ -2778,7 +2832,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7935307680550293784
+          6544536706877310514
         ]
       ], 
       "reviewed-by-human": true
@@ -2787,7 +2841,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5471012436762551398
+          7066435915747351913
         ]
       ], 
       "reviewed-by-human": true
@@ -2796,7 +2850,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1557613698479648092
+          8097997023778848191
         ]
       ], 
       "reviewed-by-human": true
@@ -2805,7 +2859,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          686626615788563308
+          5836493341538608113
         ]
       ], 
       "reviewed-by-human": true
@@ -2814,7 +2868,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9960042924980287727
+          5953472570329245150
         ]
       ], 
       "reviewed-by-human": true
@@ -2823,7 +2877,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5930938593239004653
+          4165425675033352640
         ]
       ], 
       "reviewed-by-human": true
@@ -2832,7 +2886,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3190552677201665775
+          10152516748782571739
         ]
       ], 
       "reviewed-by-human": true
@@ -2841,7 +2895,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          684132920930319303
+          13262888511953363261
         ]
       ], 
       "reviewed-by-human": true
@@ -2850,7 +2904,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4870317370734649728
+          8180502121217066191
         ]
       ], 
       "reviewed-by-human": true
@@ -2859,7 +2913,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5783287451488289297
+          16993829969091028380
         ]
       ], 
       "reviewed-by-human": true
@@ -2868,7 +2922,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11810056493244595774
+          10501115473108298882
         ]
       ], 
       "reviewed-by-human": true
@@ -2931,28 +2985,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17707691143950027168
+          4792118895672570848
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788619303593885819
+          11285887424651164487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12477159368808426654
+          8056631522680651323
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -3030,7 +3084,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17138342910351740780
+          15418783980877386199
         ]
       ], 
       "reviewed-by-human": true
@@ -3039,7 +3093,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13937678633951136440
+          7882161322447216882
         ]
       ], 
       "reviewed-by-human": true
@@ -3048,7 +3102,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13341606961501773179
+          9084726022784412994
         ]
       ], 
       "reviewed-by-human": true
@@ -3057,7 +3111,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2256130412784819033
+          3184062263576953667
         ]
       ], 
       "reviewed-by-human": true
@@ -3066,7 +3120,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10471902765578272701
+          713799816796517938
         ]
       ], 
       "reviewed-by-human": true
@@ -3075,7 +3129,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3167565818671493256
+          1524421127104888844
         ]
       ], 
       "reviewed-by-human": true
@@ -3184,7 +3238,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          791731370982641459
+          12983436663287935053
         ]
       ], 
       "reviewed-by-human": true
@@ -3226,7 +3280,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9374541812861034293
+          11475660560101599954
         ]
       ], 
       "reviewed-by-human": true
@@ -3235,7 +3289,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2576698895183287698
+          7311723676588845146
         ]
       ], 
       "reviewed-by-human": true
@@ -3244,7 +3298,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11379833094085660515
+          8359929465185009217
         ]
       ], 
       "reviewed-by-human": true
@@ -3282,7 +3336,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3767760557629765982
+          4057230872151110302
         ]
       ], 
       "ignore-failure": false, 
@@ -3292,7 +3346,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12070678672447530766
+          9482070623821433904
         ]
       ], 
       "ignore-failure": false, 
@@ -3302,7 +3356,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14570840123822355129
+          6390479542851385994
         ]
       ], 
       "ignore-failure": false, 
@@ -3312,43 +3366,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -3357,7 +3402,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -3366,7 +3411,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
       "reviewed-by-human": true
@@ -3375,67 +3420,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
       "reviewed-by-human": true
@@ -3444,7 +3474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6989712392624471913
+          17775297231868448514
         ]
       ], 
       "reviewed-by-human": true
@@ -3453,7 +3483,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10855232109519818829
+          12804472649182277577
         ]
       ], 
       "reviewed-by-human": true
@@ -3462,19 +3492,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2410384022323180262
+          8136862497622595689
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -3483,7 +3510,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -3492,7 +3519,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
       "reviewed-by-human": true
@@ -3501,67 +3528,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
       "reviewed-by-human": true
@@ -3570,7 +3582,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2497837460215148124
+          6055955940623478607
         ]
       ], 
       "reviewed-by-human": true
@@ -3579,7 +3591,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13192464168020553898
+          11797865288006977816
         ]
       ], 
       "reviewed-by-human": true
@@ -3588,19 +3600,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11818903631048803455
+          9781042422538097277
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -3609,7 +3618,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181838889584580159
         ]
       ], 
       "reviewed-by-human": true
@@ -3618,7 +3636,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          4886211991926050486
         ]
       ], 
       "reviewed-by-human": true
@@ -3627,7 +3645,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          8737545656412765906
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8820398513653894612
         ]
       ], 
       "reviewed-by-human": true
@@ -3636,7 +3663,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -3645,7 +3672,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8820398513653894612
         ]
       ], 
       "reviewed-by-human": true
@@ -3654,7 +3690,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          4707049264800437834
         ]
       ], 
       "reviewed-by-human": true
@@ -3663,7 +3699,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          3175389971476411688
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4277401128811031135
         ]
       ], 
       "reviewed-by-human": true
@@ -3672,7 +3717,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13106701293308057590
+          11292884853289362433
         ]
       ], 
       "reviewed-by-human": true
@@ -3690,16 +3735,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2931946104892198077
+          4473589478120711048
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5455618422902283397
+          15797039913993285826
         ]
       ], 
       "reviewed-by-human": true
@@ -3708,7 +3754,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14095817193753318732
+          17497164562330387900
         ]
       ], 
       "reviewed-by-human": true
@@ -3717,7 +3763,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2692505469297757718
+          11947571491152707744
         ]
       ], 
       "reviewed-by-human": true
@@ -3726,7 +3772,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          716171842978913864
+          273445276579232833
         ]
       ], 
       "reviewed-by-human": true
@@ -3735,7 +3781,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17171710908581496295
+          13357226331142394630
         ]
       ], 
       "reviewed-by-human": true
@@ -3744,7 +3790,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1289208517076135500
+          13157598198362907279
         ]
       ], 
       "reviewed-by-human": true
@@ -3780,7 +3826,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16452419234213932266
+          1802138798652377585
         ]
       ], 
       "reviewed-by-human": true
@@ -3789,7 +3835,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13347568447034524087
+          588269449619860245
         ]
       ], 
       "reviewed-by-human": true
@@ -3798,7 +3844,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          768255655200339155
+          12200967819639880627
         ]
       ], 
       "reviewed-by-human": true
@@ -3911,6 +3957,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -4068,7 +4141,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -4077,7 +4150,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -4095,7 +4168,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -4104,7 +4177,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -4122,7 +4195,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13403191811040300266
+          14722635495513489032
         ]
       ], 
       "reviewed-by-human": true
@@ -4131,7 +4204,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13640210300978315176
+          12282574495328673422
         ]
       ], 
       "reviewed-by-human": true
@@ -4149,7 +4222,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2841712854914200171
+          13693191183042277532
         ]
       ], 
       "reviewed-by-human": true
@@ -4158,7 +4231,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006484729950247920
+          16660777759874050826
         ]
       ], 
       "reviewed-by-human": true
@@ -4176,7 +4249,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9253425473221951017
+          8040843233240943903
         ]
       ], 
       "reviewed-by-human": true
@@ -4185,7 +4258,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7196879659919462842
+          9083165358184844265
         ]
       ], 
       "reviewed-by-human": true
@@ -4203,7 +4276,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3818470414665025673
+          17018639447672062793
         ]
       ], 
       "reviewed-by-human": true
@@ -4212,7 +4285,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458389215599169812
+          12272424701333998130
         ]
       ], 
       "reviewed-by-human": true
@@ -4230,7 +4303,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8734759244377509313
+          13417197952712807946
         ]
       ], 
       "reviewed-by-human": true
@@ -4239,7 +4312,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16189637050029803867
+          3026049626060566850
         ]
       ], 
       "reviewed-by-human": true
@@ -4257,7 +4330,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2558252763680580376
+          3776620851026277431
         ]
       ], 
       "reviewed-by-human": true
@@ -4266,7 +4339,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          314376617607170618
+          15048764744488112807
         ]
       ], 
       "reviewed-by-human": true
@@ -4284,7 +4357,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3241890450402571997
+          14696910306727510138
         ]
       ], 
       "reviewed-by-human": true
@@ -4293,7 +4366,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18261351407702936062
+          10815979445723137947
         ]
       ], 
       "reviewed-by-human": true
@@ -4338,7 +4411,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14201938350237123162
+          4315422957234654068
         ]
       ], 
       "reviewed-by-human": true
@@ -4347,7 +4420,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817564933175934896
+          1005120818505701076
         ]
       ], 
       "reviewed-by-human": true
@@ -4392,7 +4465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7289467627965448716
+          5444966390426892775
         ]
       ], 
       "reviewed-by-human": true
@@ -4401,7 +4474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3926971490478181787
+          9485187966930935416
         ]
       ], 
       "reviewed-by-human": true
@@ -4419,7 +4492,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14643066968979788941
+          16140209716006433983
         ]
       ], 
       "reviewed-by-human": true
@@ -4428,7 +4501,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3363453308488752313
+          10081099437124071090
         ]
       ], 
       "reviewed-by-human": true
@@ -4442,6 +4515,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18400047645694418480
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -4455,72 +4555,58 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          17276962213970077366
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          8694218356938189525
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1857288326388942863
         ]
       ], 
       "bugs": [
-        1578
+        2887
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          4335659971728708662
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          5297915207580543309
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
@@ -4553,11 +4639,38 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2500355683115767624
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          904096376103231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6163838330434021775
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7818310295492545479
+          11716334334721910796
         ]
       ], 
       "ignore-failure": false, 
@@ -4567,7 +4680,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4994151175360770217
+          5693920054563327483
         ]
       ], 
       "ignore-failure": false, 
@@ -4577,7 +4690,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10768745779609912779
+          11558678086719578288
         ]
       ], 
       "ignore-failure": false, 
@@ -4934,6 +5047,222 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196989680608516010
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2267616380693640877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1124904529638696182
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7401870099194519468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7401870099194519468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18181809164582745765
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394844511878157900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18177453939513851246
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14988814117683836650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4782017764054717040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4372045147535855874
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11065728939551509595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9113410047973329469
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7401870099194519468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863085462100832326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15185569085386261743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8673137414478041582
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271247215169625597
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14767707884887387147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7396548710257716434
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -4965,10 +5294,7 @@
           14015662146260093838
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_matrix_565.png": {
       "allowed-digests": [
@@ -5031,7 +5357,7 @@
           3493263944278727556
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_565.png": {
       "allowed-digests": [
@@ -5058,7 +5384,7 @@
           15451235578409962625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_565.png": {
       "allowed-digests": [
@@ -5085,7 +5411,7 @@
           10135349930059020946
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_565.png": {
       "allowed-digests": [
@@ -5232,7 +5558,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -5250,7 +5576,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14930897081171395685
+          13837779357393426492
         ]
       ], 
       "ignore-failure": false, 
@@ -5260,7 +5586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13538992606665750486
+          8988444324654919932
         ]
       ], 
       "reviewed-by-human": true
@@ -5330,10 +5656,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17297019758764752680
+          5005820819642466038
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -5425,11 +5752,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          741134624395776214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          357284903731074601
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5034635930426005712
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3794665630847901594
+          13620335786972140736
         ]
       ], 
       "reviewed-by-human": true
@@ -5438,7 +5792,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7748801528548244433
+          17030111096598942390
         ]
       ], 
       "reviewed-by-human": true
@@ -5447,7 +5801,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6332063967132987532
+          18278123345850322998
         ]
       ], 
       "ignore-failure": false, 
@@ -5457,7 +5811,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259128835424197006
+          1922338586017046100
         ]
       ], 
       "reviewed-by-human": true
@@ -5466,7 +5820,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13149265802466457140
+          3693078186234250164
         ]
       ], 
       "reviewed-by-human": true
@@ -5475,7 +5829,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4974844375073481282
+          6350563482483431609
         ]
       ], 
       "reviewed-by-human": true
@@ -5511,7 +5865,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6719033984262147569
+          9334915207072042375
         ]
       ], 
       "reviewed-by-human": true
@@ -5520,7 +5874,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9527595429529547733
+          4262113639047937913
         ]
       ], 
       "reviewed-by-human": true
@@ -5529,7 +5883,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6008461518333374558
+          16944197972322374985
         ]
       ], 
       "ignore-failure": false, 
@@ -5539,17 +5893,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8498778868685964382
+          9643897842146508458
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          880034339526468883
+          14154076457851775362
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_gpu.png": {
       "allowed-digests": [
@@ -5564,7 +5920,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219558445660995645
+          16816155573392653040
         ]
       ], 
       "reviewed-by-human": true
@@ -5573,7 +5929,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          861754899676926834
+          15621659488709502951
         ]
       ], 
       "reviewed-by-human": true
@@ -5582,7 +5938,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5664795631214643440
+          9176520558186220317
         ]
       ], 
       "reviewed-by-human": true
@@ -5591,7 +5947,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15200137971968303012
+          14400660572715212845
         ]
       ], 
       "reviewed-by-human": true
@@ -5600,7 +5956,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199776944359958607
+          12820728063175372793
         ]
       ], 
       "reviewed-by-human": true
@@ -5619,23 +5975,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15332790159062618713
+          8663959489913767436
         ]
       ], 
       "reviewed-by-human": true
@@ -5644,7 +6002,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5274487773236388163
+          4458594706234736506
         ]
       ], 
       "reviewed-by-human": true
@@ -5653,7 +6011,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10772725192724193725
+          7881653068493848399
         ]
       ], 
       "reviewed-by-human": true
@@ -5662,7 +6020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6138663057683877780
+          5896248217426666691
         ]
       ], 
       "reviewed-by-human": true
@@ -5803,13 +6161,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1128030240545260947
+          9202866929862689391
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
@@ -5869,7 +6227,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15118920252874319058
+          9075523320529578103
         ]
       ], 
       "reviewed-by-human": true
@@ -5878,7 +6236,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13213375518846743511
+          4131799565799962704
         ]
       ], 
       "reviewed-by-human": true
@@ -5887,7 +6245,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5216420263713929251
+          5217925660404039517
         ]
       ], 
       "reviewed-by-human": true
@@ -5896,7 +6254,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7394602124225746876
+          4095489997625677813
         ]
       ], 
       "reviewed-by-human": true
@@ -5905,7 +6263,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768949088352973106
+          17687576741285937089
         ]
       ], 
       "reviewed-by-human": true
@@ -5914,7 +6272,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8388956649707556649
+          12660892446188981889
         ]
       ], 
       "reviewed-by-human": true
@@ -5939,9 +6297,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11768049299524715926
+          12551593558877396461
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumamode_565.png": {
       "allowed-digests": [
@@ -5971,7 +6330,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14753870890166488787
+          13546074453897362674
         ]
       ], 
       "reviewed-by-human": true
@@ -5980,7 +6339,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12332409505555151686
+          2645433785253737964
         ]
       ], 
       "reviewed-by-human": true
@@ -5989,7 +6348,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413857436675528921
+          9399689272866614344
         ]
       ], 
       "reviewed-by-human": true
@@ -6049,7 +6408,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6082,7 +6441,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6115,7 +6474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6175,13 +6534,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6322714542176233479
+          2764095265218154928
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
@@ -6210,6 +6569,276 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12026275426271527150
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6958579088836506224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2297483525893474810
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18100843957901826201
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4478490979400536378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16204222930251940046
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16721089005631938371
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9760231745798245964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5749308152293375604
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662786566822056022
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -6367,7 +6996,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15293668784585893125
+          4656886197492028969
         ]
       ], 
       "reviewed-by-human": true
@@ -6376,7 +7005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17470748697630737319
+          10009949554846362902
         ]
       ], 
       "reviewed-by-human": true
@@ -6385,7 +7014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6258969688980197856
+          13683962615885282836
         ]
       ], 
       "reviewed-by-human": true
@@ -6418,13 +7047,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          2379796454057556376
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -6453,6 +7082,60 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7258406699897973752
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17286230013131859770
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -6694,7 +7377,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -6703,7 +7386,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -6712,12 +7395,39 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11853841295252803459
+          9624355400568283482
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9747549608031779530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -6745,6 +7455,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14249024706582191865
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -6772,6 +7509,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -6804,7 +7568,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18000254716935645999
+          13710370929503896242
         ]
       ], 
       "reviewed-by-human": true
@@ -6813,7 +7577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16383033135480419663
+          14868659503042841956
         ]
       ], 
       "reviewed-by-human": true
@@ -6822,7 +7586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11294115177099606513
+          11236564600268325973
         ]
       ], 
       "reviewed-by-human": true
@@ -6858,7 +7622,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16422530932852428674
+          2214368729624239628
         ]
       ], 
       "reviewed-by-human": true
@@ -6867,7 +7631,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13797585911734062488
+          13695847048236137972
         ]
       ], 
       "reviewed-by-human": true
@@ -6876,7 +7640,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16912233602921927369
+          14658443335125933532
         ]
       ], 
       "reviewed-by-human": true
@@ -6885,7 +7649,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13221078215540522692
+          6757078992106948579
         ]
       ], 
       "reviewed-by-human": true
@@ -6894,7 +7658,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7149831205496297560
+          24796932854446382
         ]
       ], 
       "reviewed-by-human": true
@@ -6903,7 +7667,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16814255993965116910
+          3924532181987290555
         ]
       ], 
       "reviewed-by-human": true
@@ -6954,10 +7718,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199326463862210265
+          2683400429924886711
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -7338,7 +8103,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6385849539525834967
+          13572029116278729382
         ]
       ], 
       "reviewed-by-human": true
@@ -7365,7 +8130,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7460303501608458490
+          8475139782488098737
         ]
       ], 
       "reviewed-by-human": true
@@ -7773,7 +8538,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14585555250092963383
+          13909757336310240518
         ]
       ], 
       "reviewed-by-human": true
@@ -7782,7 +8547,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6423558589708144215
+          17885518595384354919
         ]
       ], 
       "reviewed-by-human": true
@@ -7803,7 +8568,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11744373400809739356
+          11699531654048406518
         ]
       ], 
       "reviewed-by-human": true
@@ -7812,7 +8577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8270526029969251327
+          4523091657809672686
         ]
       ], 
       "reviewed-by-human": true
@@ -7821,7 +8586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17477851404941805193
+          17847682713276246556
         ]
       ], 
       "reviewed-by-human": true
@@ -8028,7 +8793,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10230426069067413407
+          18286981917824090179
         ]
       ], 
       "reviewed-by-human": true
@@ -8037,7 +8802,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15098401526248766364
+          10092481067847317760
         ]
       ], 
       "reviewed-by-human": true
@@ -8046,7 +8811,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933051189242765749
+          4566289877673568210
         ]
       ], 
       "reviewed-by-human": true
@@ -8082,7 +8847,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15528863190484305841
+          1369006746513120542
         ]
       ], 
       "reviewed-by-human": true
@@ -8091,7 +8856,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15197842121034928067
+          10584886924228958226
         ]
       ], 
       "reviewed-by-human": true
@@ -8132,6 +8897,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          163112871246100159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          374437982401021225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -8163,10 +8955,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16780536364041129122
+          758934049590219880
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -8193,7 +8985,8 @@
           15858307657519327001
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_565.png": {
       "allowed-digests": [
@@ -8220,13 +9013,14 @@
           12367524911555205763
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17022932193658353157
+          15732727687033594466
         ]
       ], 
       "reviewed-by-human": true
@@ -8235,7 +9029,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8244,7 +9038,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16516401516776860515
+          8847318198118613005
         ]
       ], 
       "reviewed-by-human": true
@@ -8325,7 +9119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          539915969408525938
+          11627825601504219410
         ]
       ], 
       "reviewed-by-human": true
@@ -8352,7 +9146,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10071678485394503756
+          10094506929640064268
         ]
       ], 
       "reviewed-by-human": true
@@ -8492,6 +9286,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14824515475287110550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7140046544242806721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12142032913522110489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14824515475287110550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6750354401496927826
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          908106839765115426
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11554131256517465520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6750354401496927826
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -8604,7 +9506,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3394570787947912684
+          3112652115716203250
         ]
       ], 
       "reviewed-by-human": true
@@ -8613,7 +9515,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4231863532718175149
+          12938112915997113104
         ]
       ], 
       "reviewed-by-human": true
@@ -8622,7 +9524,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682926307093534631
+          7099868207716879131
         ]
       ], 
       "reviewed-by-human": true
@@ -8649,7 +9551,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          238819112342131317
+          11587903491111347656
         ]
       ], 
       "reviewed-by-human": true
@@ -8676,7 +9578,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10255763987814493261
+          1169777226871264424
         ]
       ], 
       "reviewed-by-human": true
@@ -8703,10 +9605,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7871079263072256188
+          4896933091710642125
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6719196348100419960
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-NexusS-SGX540-Arm7-Debug/expected-results.json b/expectations/gm/Test-Android-NexusS-SGX540-Arm7-Debug/expected-results.json
index c42d95c..45709ae 100644
--- a/expectations/gm/Test-Android-NexusS-SGX540-Arm7-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-NexusS-SGX540-Arm7-Debug/expected-results.json
@@ -194,6 +194,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bezier_conic_effects_gpu.png": {
       "allowed-digests": [
         [
@@ -218,30 +236,6 @@
         ]
       ]
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
@@ -339,7 +333,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15577847810878117619
+          17340263283992921059
         ]
       ], 
       "reviewed-by-human": true
@@ -348,7 +342,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16537885423072386302
+          16466362226127156448
         ]
       ], 
       "reviewed-by-human": true
@@ -1537,6 +1531,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -1759,6 +1771,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2384,7 +2414,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2035525753977535256
+          17227422062891506713
         ]
       ], 
       "reviewed-by-human": true
@@ -2393,7 +2423,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12559465164864479162
+          17092054436660282529
         ]
       ], 
       "reviewed-by-human": true
@@ -2411,7 +2441,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3306730904107685940
+          6553725485240272462
         ]
       ], 
       "reviewed-by-human": true
@@ -2420,7 +2450,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13591877655871515458
+          6166183189201099571
         ]
       ], 
       "reviewed-by-human": true
@@ -2438,7 +2468,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6310901099269765196
+          11280758551326894049
         ]
       ], 
       "reviewed-by-human": true
@@ -2447,7 +2477,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2511666966287866166
+          2733201198429145442
         ]
       ], 
       "reviewed-by-human": true
@@ -2465,7 +2495,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17159080850865344792
+          954351366070381450
         ]
       ], 
       "reviewed-by-human": true
@@ -2474,7 +2504,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2302717591157402628
+          9210178579115499419
         ]
       ], 
       "reviewed-by-human": true
@@ -2528,19 +2558,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3742871756784050961
+          15926573056550878185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14394590208816375119
+          4158201481429178795
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -2597,7 +2627,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12345522437202727374
+          18285742889357948755
         ]
       ], 
       "reviewed-by-human": true
@@ -2606,7 +2636,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17912401236231679127
+          15743894196129681683
         ]
       ], 
       "reviewed-by-human": true
@@ -2624,7 +2654,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11191728978684557482
+          12885714138729982908
         ]
       ], 
       "reviewed-by-human": true
@@ -2633,7 +2663,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058335517377211817
+          5570027336852511465
         ]
       ], 
       "reviewed-by-human": true
@@ -2774,7 +2804,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1940009043017990568
+          3145556866881820143
         ]
       ], 
       "reviewed-by-human": true
@@ -2783,7 +2813,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11122804881221782538
+          5022030446032169064
         ]
       ], 
       "reviewed-by-human": true
@@ -2821,7 +2851,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10557537838778749160
+          12185342896868259586
         ]
       ], 
       "ignore-failure": false, 
@@ -2831,7 +2861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7089896533323038526
+          14869624664666518810
         ]
       ], 
       "ignore-failure": false, 
@@ -2850,25 +2880,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
@@ -3159,7 +3183,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16880886031490071742
+          4714004310352992111
         ]
       ], 
       "reviewed-by-human": true
@@ -3168,7 +3192,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          428119157032316167
+          17158122750214958555
         ]
       ], 
       "reviewed-by-human": true
@@ -3186,7 +3210,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7416446637660374210
+          1749131430740318779
         ]
       ], 
       "reviewed-by-human": true
@@ -3195,7 +3219,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13313875175804070508
+          12553201495837952118
         ]
       ], 
       "reviewed-by-human": true
@@ -3222,7 +3246,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5887470903797208725
+          16963462312155122453
         ]
       ], 
       "reviewed-by-human": true
@@ -3231,7 +3255,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16729138449439522348
+          2100485553427956358
         ]
       ], 
       "reviewed-by-human": true
@@ -3317,6 +3341,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3689,52 +3731,58 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1475455449101363363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          18038814198885194090
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          2092147631998739275
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13271159159658735588
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
@@ -3761,7 +3809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9981410297050803682
+          10022685771442805167
         ]
       ], 
       "ignore-failure": false, 
@@ -3771,7 +3819,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12924368150056635888
+          3638984878878580889
         ]
       ], 
       "ignore-failure": false, 
@@ -4110,6 +4158,150 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2542842552177748878
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14451045898461494763
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7022748339536758719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7022748339536758719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4612002176583322834
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1619379911426141072
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5594089710385261655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14690527047657142551
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7022748339536758719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17614249141264363600
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13816591426241372835
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          541128224231284869
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3660765690515931744
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -4364,7 +4556,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297095911910169239
+          9403600246824010712
         ]
       ], 
       "reviewed-by-human": true
@@ -4373,7 +4565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5771478138095675386
+          12332797412638201498
         ]
       ], 
       "reviewed-by-human": true
@@ -4498,11 +4690,29 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          113756186147872748
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1951520719731465030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3576279505219183019
+          7646015017506458801
         ]
       ], 
       "reviewed-by-human": true
@@ -4511,7 +4721,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8692857562686154753
+          7255674387847076030
         ]
       ], 
       "reviewed-by-human": true
@@ -4529,7 +4739,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10777355457185638337
+          12586841244820131235
         ]
       ], 
       "reviewed-by-human": true
@@ -4538,7 +4748,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071282510990956080
+          17873119728038419105
         ]
       ], 
       "reviewed-by-human": true
@@ -4565,7 +4775,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4403916508561740668
+          335209188838570314
         ]
       ], 
       "reviewed-by-human": true
@@ -4574,7 +4784,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2169481878270022443
+          13743577552461463126
         ]
       ], 
       "reviewed-by-human": true
@@ -4608,7 +4818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17735192342007451132
+          1114087428478246190
         ]
       ], 
       "reviewed-by-human": true
@@ -4617,7 +4827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4966754436744417482
+          16950706967996242477
         ]
       ], 
       "reviewed-by-human": true
@@ -4661,23 +4871,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          9975630938390290961
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          5942637760001128743
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14625944923053341670
+          14117400437006921516
         ]
       ], 
       "reviewed-by-human": true
@@ -4686,7 +4898,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1901521361109987395
+          14816015368674233714
         ]
       ], 
       "reviewed-by-human": true
@@ -4845,7 +5057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2569157419236777949
+          1505564491534805459
         ]
       ], 
       "reviewed-by-human": true
@@ -4854,7 +5066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1370520776657521517
+          17212900163667680667
         ]
       ], 
       "reviewed-by-human": true
@@ -4872,7 +5084,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16518858492509120064
+          3151309748251776881
         ]
       ], 
       "reviewed-by-human": true
@@ -4881,7 +5093,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15238792371190456534
+          5122071235510816862
         ]
       ], 
       "reviewed-by-human": true
@@ -4939,7 +5151,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3101476576521947165
+          15820508232675609834
         ]
       ], 
       "reviewed-by-human": true
@@ -4948,7 +5160,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10055081768235896808
+          17131106171251635717
         ]
       ], 
       "reviewed-by-human": true
@@ -5254,7 +5466,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15240835456320409473
+          2417541102915221087
         ]
       ], 
       "reviewed-by-human": true
@@ -5263,7 +5475,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          249289862803617115
+          4496194756153902794
         ]
       ], 
       "reviewed-by-human": true
@@ -5319,6 +5531,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -5518,7 +5766,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -5527,7 +5775,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -5541,6 +5789,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -5559,6 +5825,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7097560965947999022
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -5577,6 +5861,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5608,7 +5910,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6571118611946058617
+          17983017435379030888
         ]
       ], 
       "reviewed-by-human": true
@@ -5617,7 +5919,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2985268228390879272
+          14038652322622145328
         ]
       ], 
       "reviewed-by-human": true
@@ -5653,7 +5955,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9971396627985154706
+          1083821199230412070
         ]
       ], 
       "reviewed-by-human": true
@@ -5662,7 +5964,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6891379388563692035
+          16113419322232484853
         ]
       ], 
       "reviewed-by-human": true
@@ -5680,7 +5982,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1288004664951630498
+          9362196728682918223
         ]
       ], 
       "reviewed-by-human": true
@@ -5689,7 +5991,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7223243377781866680
+          12925825870714067916
         ]
       ], 
       "reviewed-by-human": true
@@ -6098,7 +6400,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6553800916134540056
+          2682101865426225451
         ]
       ], 
       "reviewed-by-human": true
@@ -6125,7 +6427,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15899868466464942813
+          1670480655312426736
         ]
       ], 
       "reviewed-by-human": true
@@ -6474,7 +6776,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17619211944443238901
+          10211393238987918705
         ]
       ], 
       "reviewed-by-human": true
@@ -6483,7 +6785,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476337759406055776
+          5070879619906521041
         ]
       ], 
       "reviewed-by-human": true
@@ -6678,7 +6980,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10084807092550654294
+          1034290175750690735
         ]
       ], 
       "reviewed-by-human": true
@@ -6687,7 +6989,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15846255821264969272
+          16800018700019366772
         ]
       ], 
       "reviewed-by-human": true
@@ -6741,13 +7043,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4806854696235085637
+          14688683472045987229
         ]
       ], 
-      "bugs": [
-        2603
-      ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "texdata_565.png": {
       "allowed-digests": [
@@ -6818,10 +7118,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          804279550415026015
+          1763610880767920386
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -6845,10 +7145,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7813081860549969723
+          8766541196376509727
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_565.png": {
       "allowed-digests": [
@@ -6872,16 +7173,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10263284767330603632
+          14836554418600570065
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15884441815359625883
+          15191409507212695130
         ]
       ], 
       "reviewed-by-human": true
@@ -6890,7 +7192,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          11411832946137461218
         ]
       ], 
       "reviewed-by-human": true
@@ -6899,7 +7201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          11411832946137461218
         ]
       ], 
       "reviewed-by-human": true
@@ -6980,7 +7282,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2340858254721670310
+          1918039825256352277
         ]
       ], 
       "reviewed-by-human": true
@@ -7007,7 +7309,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11966425166064673492
+          536647543438981800
         ]
       ], 
       "reviewed-by-human": true
@@ -7070,7 +7372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17818312623556077
+          1077973399138178688
         ]
       ], 
       "reviewed-by-human": true
@@ -7156,6 +7458,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10041481593696731324
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1779290589524924521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487584321918589723
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10041481593696731324
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1779290589524924521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487584321918589723
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18023890918338450644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7850745143997123083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7008675941510073754
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18023890918338450644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7850745143997123083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7008675941510073754
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -7268,7 +7678,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10958353996143090911
+          17760244815865706025
         ]
       ], 
       "reviewed-by-human": true
@@ -7277,7 +7687,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17000878545702467803
+          2770675093666585013
         ]
       ], 
       "reviewed-by-human": true
@@ -7286,7 +7696,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5746234603117716194
+          4814776997302561652
         ]
       ], 
       "reviewed-by-human": true
@@ -7313,7 +7723,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18244176185171938696
+          1576296540827012199
         ]
       ], 
       "reviewed-by-human": true
@@ -7340,7 +7750,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          274415068130026266
+          10244615098040095474
         ]
       ], 
       "reviewed-by-human": true
@@ -7367,10 +7777,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12078165737327679843
+          12535168602791254556
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16324383818446088765
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-NexusS-SGX540-Arm7-Release/expected-results.json b/expectations/gm/Test-Android-NexusS-SGX540-Arm7-Release/expected-results.json
index c42d95c..45709ae 100644
--- a/expectations/gm/Test-Android-NexusS-SGX540-Arm7-Release/expected-results.json
+++ b/expectations/gm/Test-Android-NexusS-SGX540-Arm7-Release/expected-results.json
@@ -194,6 +194,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bezier_conic_effects_gpu.png": {
       "allowed-digests": [
         [
@@ -218,30 +236,6 @@
         ]
       ]
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
@@ -339,7 +333,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15577847810878117619
+          17340263283992921059
         ]
       ], 
       "reviewed-by-human": true
@@ -348,7 +342,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16537885423072386302
+          16466362226127156448
         ]
       ], 
       "reviewed-by-human": true
@@ -1537,6 +1531,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -1759,6 +1771,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2384,7 +2414,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2035525753977535256
+          17227422062891506713
         ]
       ], 
       "reviewed-by-human": true
@@ -2393,7 +2423,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12559465164864479162
+          17092054436660282529
         ]
       ], 
       "reviewed-by-human": true
@@ -2411,7 +2441,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3306730904107685940
+          6553725485240272462
         ]
       ], 
       "reviewed-by-human": true
@@ -2420,7 +2450,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13591877655871515458
+          6166183189201099571
         ]
       ], 
       "reviewed-by-human": true
@@ -2438,7 +2468,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6310901099269765196
+          11280758551326894049
         ]
       ], 
       "reviewed-by-human": true
@@ -2447,7 +2477,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2511666966287866166
+          2733201198429145442
         ]
       ], 
       "reviewed-by-human": true
@@ -2465,7 +2495,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17159080850865344792
+          954351366070381450
         ]
       ], 
       "reviewed-by-human": true
@@ -2474,7 +2504,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2302717591157402628
+          9210178579115499419
         ]
       ], 
       "reviewed-by-human": true
@@ -2528,19 +2558,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3742871756784050961
+          15926573056550878185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14394590208816375119
+          4158201481429178795
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -2597,7 +2627,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12345522437202727374
+          18285742889357948755
         ]
       ], 
       "reviewed-by-human": true
@@ -2606,7 +2636,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17912401236231679127
+          15743894196129681683
         ]
       ], 
       "reviewed-by-human": true
@@ -2624,7 +2654,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11191728978684557482
+          12885714138729982908
         ]
       ], 
       "reviewed-by-human": true
@@ -2633,7 +2663,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058335517377211817
+          5570027336852511465
         ]
       ], 
       "reviewed-by-human": true
@@ -2774,7 +2804,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1940009043017990568
+          3145556866881820143
         ]
       ], 
       "reviewed-by-human": true
@@ -2783,7 +2813,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11122804881221782538
+          5022030446032169064
         ]
       ], 
       "reviewed-by-human": true
@@ -2821,7 +2851,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10557537838778749160
+          12185342896868259586
         ]
       ], 
       "ignore-failure": false, 
@@ -2831,7 +2861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7089896533323038526
+          14869624664666518810
         ]
       ], 
       "ignore-failure": false, 
@@ -2850,25 +2880,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
@@ -3159,7 +3183,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16880886031490071742
+          4714004310352992111
         ]
       ], 
       "reviewed-by-human": true
@@ -3168,7 +3192,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          428119157032316167
+          17158122750214958555
         ]
       ], 
       "reviewed-by-human": true
@@ -3186,7 +3210,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7416446637660374210
+          1749131430740318779
         ]
       ], 
       "reviewed-by-human": true
@@ -3195,7 +3219,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13313875175804070508
+          12553201495837952118
         ]
       ], 
       "reviewed-by-human": true
@@ -3222,7 +3246,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5887470903797208725
+          16963462312155122453
         ]
       ], 
       "reviewed-by-human": true
@@ -3231,7 +3255,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16729138449439522348
+          2100485553427956358
         ]
       ], 
       "reviewed-by-human": true
@@ -3317,6 +3341,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3689,52 +3731,58 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1475455449101363363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          18038814198885194090
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          2092147631998739275
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13271159159658735588
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
@@ -3761,7 +3809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9981410297050803682
+          10022685771442805167
         ]
       ], 
       "ignore-failure": false, 
@@ -3771,7 +3819,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12924368150056635888
+          3638984878878580889
         ]
       ], 
       "ignore-failure": false, 
@@ -4110,6 +4158,150 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2542842552177748878
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14451045898461494763
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7022748339536758719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7022748339536758719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4612002176583322834
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1619379911426141072
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5594089710385261655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14690527047657142551
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7022748339536758719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17614249141264363600
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13816591426241372835
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          541128224231284869
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3660765690515931744
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -4364,7 +4556,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297095911910169239
+          9403600246824010712
         ]
       ], 
       "reviewed-by-human": true
@@ -4373,7 +4565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5771478138095675386
+          12332797412638201498
         ]
       ], 
       "reviewed-by-human": true
@@ -4498,11 +4690,29 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          113756186147872748
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1951520719731465030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3576279505219183019
+          7646015017506458801
         ]
       ], 
       "reviewed-by-human": true
@@ -4511,7 +4721,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8692857562686154753
+          7255674387847076030
         ]
       ], 
       "reviewed-by-human": true
@@ -4529,7 +4739,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10777355457185638337
+          12586841244820131235
         ]
       ], 
       "reviewed-by-human": true
@@ -4538,7 +4748,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071282510990956080
+          17873119728038419105
         ]
       ], 
       "reviewed-by-human": true
@@ -4565,7 +4775,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4403916508561740668
+          335209188838570314
         ]
       ], 
       "reviewed-by-human": true
@@ -4574,7 +4784,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2169481878270022443
+          13743577552461463126
         ]
       ], 
       "reviewed-by-human": true
@@ -4608,7 +4818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17735192342007451132
+          1114087428478246190
         ]
       ], 
       "reviewed-by-human": true
@@ -4617,7 +4827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4966754436744417482
+          16950706967996242477
         ]
       ], 
       "reviewed-by-human": true
@@ -4661,23 +4871,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3846565992437209770
+          9975630938390290961
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16797253953584829082
+          5942637760001128743
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14625944923053341670
+          14117400437006921516
         ]
       ], 
       "reviewed-by-human": true
@@ -4686,7 +4898,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1901521361109987395
+          14816015368674233714
         ]
       ], 
       "reviewed-by-human": true
@@ -4845,7 +5057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2569157419236777949
+          1505564491534805459
         ]
       ], 
       "reviewed-by-human": true
@@ -4854,7 +5066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1370520776657521517
+          17212900163667680667
         ]
       ], 
       "reviewed-by-human": true
@@ -4872,7 +5084,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16518858492509120064
+          3151309748251776881
         ]
       ], 
       "reviewed-by-human": true
@@ -4881,7 +5093,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15238792371190456534
+          5122071235510816862
         ]
       ], 
       "reviewed-by-human": true
@@ -4939,7 +5151,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3101476576521947165
+          15820508232675609834
         ]
       ], 
       "reviewed-by-human": true
@@ -4948,7 +5160,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10055081768235896808
+          17131106171251635717
         ]
       ], 
       "reviewed-by-human": true
@@ -5254,7 +5466,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15240835456320409473
+          2417541102915221087
         ]
       ], 
       "reviewed-by-human": true
@@ -5263,7 +5475,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          249289862803617115
+          4496194756153902794
         ]
       ], 
       "reviewed-by-human": true
@@ -5319,6 +5531,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -5518,7 +5766,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -5527,7 +5775,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -5541,6 +5789,24 @@
       ], 
       "ignore-failure": false
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -5559,6 +5825,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7097560965947999022
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -5577,6 +5861,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5608,7 +5910,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6571118611946058617
+          17983017435379030888
         ]
       ], 
       "reviewed-by-human": true
@@ -5617,7 +5919,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2985268228390879272
+          14038652322622145328
         ]
       ], 
       "reviewed-by-human": true
@@ -5653,7 +5955,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9971396627985154706
+          1083821199230412070
         ]
       ], 
       "reviewed-by-human": true
@@ -5662,7 +5964,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6891379388563692035
+          16113419322232484853
         ]
       ], 
       "reviewed-by-human": true
@@ -5680,7 +5982,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1288004664951630498
+          9362196728682918223
         ]
       ], 
       "reviewed-by-human": true
@@ -5689,7 +5991,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7223243377781866680
+          12925825870714067916
         ]
       ], 
       "reviewed-by-human": true
@@ -6098,7 +6400,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6553800916134540056
+          2682101865426225451
         ]
       ], 
       "reviewed-by-human": true
@@ -6125,7 +6427,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15899868466464942813
+          1670480655312426736
         ]
       ], 
       "reviewed-by-human": true
@@ -6474,7 +6776,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17619211944443238901
+          10211393238987918705
         ]
       ], 
       "reviewed-by-human": true
@@ -6483,7 +6785,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476337759406055776
+          5070879619906521041
         ]
       ], 
       "reviewed-by-human": true
@@ -6678,7 +6980,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10084807092550654294
+          1034290175750690735
         ]
       ], 
       "reviewed-by-human": true
@@ -6687,7 +6989,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15846255821264969272
+          16800018700019366772
         ]
       ], 
       "reviewed-by-human": true
@@ -6741,13 +7043,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4806854696235085637
+          14688683472045987229
         ]
       ], 
-      "bugs": [
-        2603
-      ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "texdata_565.png": {
       "allowed-digests": [
@@ -6818,10 +7118,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          804279550415026015
+          1763610880767920386
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -6845,10 +7145,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7813081860549969723
+          8766541196376509727
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_565.png": {
       "allowed-digests": [
@@ -6872,16 +7173,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10263284767330603632
+          14836554418600570065
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15884441815359625883
+          15191409507212695130
         ]
       ], 
       "reviewed-by-human": true
@@ -6890,7 +7192,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          11411832946137461218
         ]
       ], 
       "reviewed-by-human": true
@@ -6899,7 +7201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          11411832946137461218
         ]
       ], 
       "reviewed-by-human": true
@@ -6980,7 +7282,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2340858254721670310
+          1918039825256352277
         ]
       ], 
       "reviewed-by-human": true
@@ -7007,7 +7309,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11966425166064673492
+          536647543438981800
         ]
       ], 
       "reviewed-by-human": true
@@ -7070,7 +7372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17818312623556077
+          1077973399138178688
         ]
       ], 
       "reviewed-by-human": true
@@ -7156,6 +7458,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10041481593696731324
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1779290589524924521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487584321918589723
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10041481593696731324
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1779290589524924521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487584321918589723
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18023890918338450644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7850745143997123083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7008675941510073754
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18023890918338450644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7850745143997123083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7008675941510073754
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -7268,7 +7678,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10958353996143090911
+          17760244815865706025
         ]
       ], 
       "reviewed-by-human": true
@@ -7277,7 +7687,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17000878545702467803
+          2770675093666585013
         ]
       ], 
       "reviewed-by-human": true
@@ -7286,7 +7696,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5746234603117716194
+          4814776997302561652
         ]
       ], 
       "reviewed-by-human": true
@@ -7313,7 +7723,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18244176185171938696
+          1576296540827012199
         ]
       ], 
       "reviewed-by-human": true
@@ -7340,7 +7750,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          274415068130026266
+          10244615098040095474
         ]
       ], 
       "reviewed-by-human": true
@@ -7367,10 +7777,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12078165737327679843
+          12535168602791254556
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16324383818446088765
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-RazrI-SGX540-x86-Debug/expected-results.json b/expectations/gm/Test-Android-RazrI-SGX540-x86-Debug/expected-results.json
index 4a09746..03f2a30 100644
--- a/expectations/gm/Test-Android-RazrI-SGX540-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-RazrI-SGX540-x86-Debug/expected-results.json
@@ -294,54 +294,6 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13582928607956785164
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4845416958200328807
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
         [
diff --git a/expectations/gm/Test-Android-RazrI-SGX540-x86-Release/expected-results.json b/expectations/gm/Test-Android-RazrI-SGX540-x86-Release/expected-results.json
index 2ff1c00..8d85627 100644
--- a/expectations/gm/Test-Android-RazrI-SGX540-x86-Release/expected-results.json
+++ b/expectations/gm/Test-Android-RazrI-SGX540-x86-Release/expected-results.json
@@ -294,54 +294,6 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13582928607956785164
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4845416958200328807
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
         [
diff --git a/expectations/gm/Test-Android-Reference-Unknown-Arm64-Debug/expected-results.json b/expectations/gm/Test-Android-Reference-Unknown-Arm64-Debug/expected-results.json
new file mode 100644
index 0000000..e76ee4c
--- /dev/null
+++ b/expectations/gm/Test-Android-Reference-Unknown-Arm64-Debug/expected-results.json
@@ -0,0 +1,12974 @@
+{
+  "expected-results": {
+    "3x3bitmaprect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16998423976396106083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "3x3bitmaprect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2054956815327187963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "3x3bitmaprect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2054956815327187963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "3x3bitmaprect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2054956815327187963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "3x3bitmaprect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2054956815327187963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5680982666881858509
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3732865537665519508
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16138168970750938639
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8134232418720361841
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10533368505163408108
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3404105191202303432
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11273986525140282221
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17425253971181998702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3770567129781642033
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10856546368486015793
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "alphagradients_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1062660886109823876
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "alphagradients_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8685680158225267849
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "alphagradients_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16099433447675743067
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "alphagradients_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1425061253173299211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "alphagradients_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8739326512478669061
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14297291255102949024
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12650638297902351267
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10746379129215911669
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4415166035281199789
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10387217536102058403
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15265492591840367073
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9219144465915962055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15566840808391504142
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4107685585296508350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6200394711225120969
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_conic_effects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          947503126928099687
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_conic_effects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9912144481918126776
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_conic_effects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16516697672029631553
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bezier_cubic_effects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13327676768378365463
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_cubic_effects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11442935220507014428
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_cubic_effects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7377825348303385118
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_quad_effects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7453545016317079091
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_quad_effects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9401932308530341379
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_quad_effects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14408490808488662254
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bigblurs_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2422083043229439955
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigblurs_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17309852422285247848
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigblurs_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8741984205182434161
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigblurs_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6463895742034431573
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigblurs_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17909315077536907276
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6169251833522681202
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10455976041474647335
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2936142022778827490
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8704820462791580200
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6873835910636963460
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bigtext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16290380272927731074
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigtext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10628348283204942671
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigtext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12280679610593832898
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigtext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12107669081044262947
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigtext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9905378213660022882
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3459248890389921752
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1875487390803094182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1875487390803094182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1875487390803094182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1875487390803094182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapfilters_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          345159363880628503
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapfilters_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662285177911778105
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapfilters_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6135240601272046401
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapfilters_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11082017410849796451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapfilters_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2512611752667952735
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmaprect_i_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18028564147828277613
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_i_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14065905418589114539
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_i_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8511579297892894623
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_i_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7851232271117128980
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_i_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1399188605698989457
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18028564147828277613
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14065905418589114539
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8511579297892894623
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7851232271117128980
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1399188605698989457
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5432165152598403513
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5432165152598403513
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1454528164630516875
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6877842861292710470
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2386657650052469554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapscroll_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18243297381828962051
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapscroll_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6170260754610315050
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapscroll_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3054365581811078847
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapscroll_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7776828220102838697
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapscroll_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13105039024633899653
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapshaders_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12003105459052744890
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapshaders_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          23481610040948036
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapshaders_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4292341330653523437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapshaders_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4205379988615278373
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapshaders_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16768122979300405928
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11249040102864413890
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8913537231360636680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14062072472966722601
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13895505754463462984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14062072472966722601
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bleed_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1844781142419806112
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bleed_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4157891812921567984
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bleed_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17870693939301194374
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bleed_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7798430527876011187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bleed_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          527932406326671983
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11627389852748930348
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11187657384039514790
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6125325568353237512
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15077952026473594665
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7277028211493676521
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurquickreject_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14575894174086753692
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurquickreject_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1951057418144050940
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurquickreject_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8760711575806144560
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurquickreject_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          64400470544822501
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurquickreject_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          64400470544822501
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080629583390552103
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11980986810369723513
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12624863915440686736
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16569869274475548824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5272469947522392970
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16280549642825337575
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12952750947910530683
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17423569280673366651
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17360690807365040182
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13137504778664331730
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext1_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662423679102384425
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext1_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662423679102384425
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext1_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662423679102384425
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext1_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16392176982191881918
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext1_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7682434275864547744
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17256358122895634639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17256358122895634639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2564291978259597241
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12148996194027470930
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17382282587146791370
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "circles_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6008092610982260089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circles_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14991965560443449693
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circles_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10167332900422109271
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circles_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15421079171046661928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circles_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2678163400591480162
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "circular-clips_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7045926575348655010
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circular-clips_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7045926575348655010
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circular-clips_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1988347527319338472
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circular-clips_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14908415861822233627
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circular-clips_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10895255954294537598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "clamped_gradients_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6740406662310759992
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clamped_gradients_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12600235552582834170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clamped_gradients_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2843220994853257782
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clamped_gradients_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13709860748431912538
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clamped_gradients_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2843220994853257782
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5543970311616574408
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9243927175489158803
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5000282312660607550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13139990863075622673
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5000282312660607550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14000830941634575767
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14412729226029504152
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12553623139335427893
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16692610170563400568
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12553623139335427893
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5937007347321497195
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6655127558305687514
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271388652122232326
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12963654110512376981
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271388652122232326
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2047816653827409443
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2047816653827409443
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2433752872333325525
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4143351860764425727
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8872399908845615950
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cmykjpeg_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13052709698662664204
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cmykjpeg_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9927483517871541702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cmykjpeg_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9927483517871541702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cmykjpeg_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9927483517871541702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cmykjpeg_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9927483517871541702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17051103650973594106
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1025940906896326990
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7133069077424093701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7133069077424093701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7133069077424093701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3235581033534814469
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5008998920935758481
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10772261323503226822
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10772261323503226822
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10772261323503226822
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11621506803825288957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14190393959731746891
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16465183276659682081
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16465183276659682081
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16465183276659682081
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1971136545200141017
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7558229948134696044
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7558229948134696044
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6100333162046229937
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17476385235562312316
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16086429144316222800
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12832097210600987517
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12073577656052761501
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13127122903587486352
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2618721010833979939
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip2_path_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13497374237280200272
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13907447324398926215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7064746384958261694
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9471735316991657266
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5765718557844909990
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip2_rect_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4388703640234091457
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rect_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6840582159469938207
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rect_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17329940322086025654
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rect_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8050767971717414561
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rect_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3160075146533642167
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11609605102436644365
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6484021739759757221
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15256308173777619343
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7847760144633844068
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3072745735157512087
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip2_rrect_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13632122222988723717
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14609392979961079625
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7607167258483373168
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15131202646914045884
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5371709705048813809
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2325131462719689144
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15708997754764845116
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15189155443552210923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6919536005785204777
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          981140130956307876
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9401534843786095695
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5110280309113538858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17777699321728709295
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10795457976747629138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9255525311477145573
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          107757481322174214
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5158682864201505817
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9522614830088431557
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9285320341410288250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13992567653263715999
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11757389550631022989
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13076020007854111750
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2615429072046131347
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14987478535910616085
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5223702466494518255
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "composeshader_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4616535333272790055
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7653047818906774476
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2785143308349902483
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3069347792056802140
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13415066704472475041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13415066704472475041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13415066704472475041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13476719363156020502
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13476719363156020502
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13476719363156020502
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convex_poly_clip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12585273536591245486
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_clip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10513029412761741862
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_clip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5867828507021919277
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_clip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16412671624919600564
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_clip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1883714548275530342
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15882849726405746866
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convex_poly_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9153870358782460504
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convex_poly_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9044825281919197740
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12930829906409283378
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5590017600958012619
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10333539536432134335
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1577336393354602706
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11761962128954199420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "copyTo4444_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13047964648578320887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "copyTo4444_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13512184095617016052
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "copyTo4444_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13512184095617016052
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "copyTo4444_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13512184095617016052
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "copyTo4444_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13512184095617016052
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cubicclosepath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2345715375030022927
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicclosepath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12849881092393067256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicclosepath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15191345378522401619
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicclosepath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1186842997313654987
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicclosepath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3376308403876425995
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16905942204084829637
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2700158731075789675
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10506940913420847037
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          549590040284264230
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5247935948854828221
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashcubics_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1243485597747942942
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashcubics_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          561323664416995153
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashcubics_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11455201270631447135
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashcubics_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          778363553632558994
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashcubics_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15469553023761418546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashing2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7522047842497784488
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16976334130763507258
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          751221660731865592
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17074122650246637487
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11009857797348161863
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashing3_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5458443768353447519
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing3_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2000525185460569669
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing3_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16283576159589291289
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing3_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7874984797872337707
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing3_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18144570818565346260
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashing4_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1285926743114346270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1394068287232006716
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4119744344752250956
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4196388052103005149
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12716951463835119116
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashing_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14912539765453208522
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11645276935331048518
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          484770861362799750
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14510209917265279305
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14510209917265279305
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "degeneratesegments_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10466664180330873334
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "degeneratesegments_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3996746667148125710
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "degeneratesegments_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4907300117469925225
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "degeneratesegments_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8371223905519476756
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "degeneratesegments_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11777374227797392699
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "deviceproperties_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9581820593659890703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "deviceproperties_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14195512172918453244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "discard_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11635187478196931850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "discard_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11635187478196931850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "discard_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11635187478196931850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "displacement_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9964043232524494023
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "displacement_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8812360810248646843
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "displacement_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8565417244362419697
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "displacement_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8565417244362419697
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "displacement_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8565417244362419697
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "distantclip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "distantclip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "distantclip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "distantclip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "distantclip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10903381122071794033
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10821670216999952848
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3280894626320084909
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1679496167850171703
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1168815789267919276
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11574858737582987248
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3690964357297286254
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4417265118328754927
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2865115198277360103
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8318264989773826055
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1005393243870299378
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15122674148017830807
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3280894626320084909
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5972223539601497054
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1168815789267919276
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17775297231868448514
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12804472649182277577
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4669810823447720319
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6294302794168975688
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4964331974602408988
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2684271591231220590
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4072072153531825530
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18232159459512256382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7242452800597086444
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          232650040899166460
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14990791594568777598
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16736962537597702928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9714755284879996124
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11085841619585784123
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5630345150013547410
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8214952685982906644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1457014783786728197
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18232159459512256382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9415478158149096409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          232650040899166460
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6055955940623478607
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11797865288006977816
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9499136896577531799
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4122284216066015433
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9548901024930911300
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4946691776839943214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10974664895754668656
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14402041105652881195
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15773305950634890477
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12015146308140154097
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4886211991926050486
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8737545656412765906
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10785325214215702800
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14682256763331130073
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9206254719726879906
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15586391272068523346
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          688606398961769278
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14402041105652881195
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16096222533538746319
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12015146308140154097
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4707049264800437834
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3175389971476411688
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18322907672040918672
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16629367922595384594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17711326968880099014
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16223060172667792670
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2528533571105501164
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7316445525652115151
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5041644101832918027
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12878478093979926276
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawlooper_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1977841434427374344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawlooper_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10410746316347940725
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawlooper_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18138990658460563504
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawlooper_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7040875820758603592
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawlooper_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6309775068063051029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5763769801346273390
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10105924271191235629
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4799188806446627840
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12535488919130000675
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8570678133707623518
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drrect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7282537335075785928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drrect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8863849031372460120
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drrect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12032414562671442267
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drrect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12812244415353974975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drrect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7753131063978727382
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16960104312592762778
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14179105798042777292
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          995796898386366606
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10656411028302201279
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3665018619870944721
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "etc1bitmap_ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10660132459335344948
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4755621039067033683
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10660132459335344948
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4768741511907258218
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11150486540244810089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11150486540244810089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11150486540244810089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11150486540244810089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7781767658511133788
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15926472232550846517
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16838534225394965684
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9002062426255277430
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14038996595497366789
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394623980536394421
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4586322702989781686
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11027690090981579357
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1405934342638609234
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10587067134950383884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filltypespersp_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13448151295100783239
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypespersp_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1122618131815112502
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypespersp_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5767265637499000580
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypespersp_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8716703435560519381
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypespersp_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7857489148100181041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_192_192_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1629520545943808082
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_192_192_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14892881851398732945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_192_192_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8442978142037036312
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_192_192_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1983942016959154459
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_192_192_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8402140909094062636
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          370415619944804844
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_32_2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271636985969391381
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_32_2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10456709796483052890
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5280902776134426739
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10749845338814785119
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_32_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16589880178812098449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_32_32_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          693268816632117565
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_32_32_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14030341984444358122
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_32_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11693321457901891931
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_32_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6575523098421564071
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_8_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          321260363995600949
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_32_8_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3569375701849257368
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_32_8_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7153103239611262568
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_8_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7002854654353738207
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_8_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8788270204561233782
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_4_4_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5784708047120841629
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_4_4_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10638485927127565077
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_4_4_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2219260729330785345
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_4_4_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4460441267403725517
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_4_4_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9169343746984194045
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_128.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9931571021055748413
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_128.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5693379441886746467
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_128.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7190783558262028798
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_128.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17302685400977738726
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_128.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12485566063545782556
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_16.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14610085259694031163
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_16.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6669000405246553088
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_16.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1194931309760096840
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_16.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15518917334950092166
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_16.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10171324835261343670
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_256.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9642958205239012359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_256.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4235081023893045230
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_256.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8299138092654008
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_256.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17435701251674019391
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_256.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11473232264179437462
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_32.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14229539764825450958
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_32.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16968175873930742751
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_32.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16922077612324074886
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_32.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6336606019785014415
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_32.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17145922605765993976
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3846489095845909164
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13785247303497252549
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17708614393374152687
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6311074125671995560
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17084415400287303864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_64.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9456835780241686074
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_64.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4117326879550640407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_image_mandrill_64.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10371560779910511424
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_64.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          152513634616866145
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_64.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15262410401104836311
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17010185584983096882
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6137221892341792135
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15959938188761089149
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2618691591940464743
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11457026221671552788
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_3.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1982129914607054330
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_text_3.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14846528981684475457
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_text_3.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2703784268130353392
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_3.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4595934339506207747
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_3.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10819059090915870146
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_7.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17314197526789357444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_text_7.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6414752434043041892
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_text_7.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10696518928883964326
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_7.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16964839535901188924
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_7.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          964322779266615494
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5594467318955027257
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9270340285022118879
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fontcache_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7122371849485640073
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontcache_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7122371849485640073
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontcache_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7193206875886806378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12201658576022942621
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5212774837146287438
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10274342291140328927
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10274342291140328927
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5513384533889704848
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14439323017086424327
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6546267859629380412
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6546267859629380412
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6546267859629380412
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10425971092471098788
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9156029157770316510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17853826291384107654
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          148832310344910223
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7875202569123646599
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7650931275064111292
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6112218413602965540
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3629288051003909841
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15684001358909497263
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6331184130756262249
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5279353358620915852
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammatext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10522992496710310056
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammatext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          810016065483539842
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammatext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11904962674552578785
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammatext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3829446403711318055
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammatext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1707855369960724268
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7664223524042185177
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14987153633306294415
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9735543669628314102
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5095141316207268684
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1047049262326645642
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8844253733895577971
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          373739036198791129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          373739036198791129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          373739036198791129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          373739036198791129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3486485929104356236
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10633738215712183989
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5234100658342674745
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4744970992857502154
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5234100658342674745
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17592263249674059658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17592263249674059658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17664227249162604428
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8239860526252863351
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17664227249162604428
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9837143541713078189
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9837143541713078189
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9837143541713078189
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5287801775965535756
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9837143541713078189
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4418651112090392588
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12707263608068309424
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14546624369730796798
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14546624369730796798
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14546624369730796798
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3198037782278889365
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6252132392610996150
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5114812640377291001
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7702421410730994532
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5114812640377291001
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7897959591317755434
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7897959591317755434
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6027650989617108262
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11579385657707635347
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6027650989617108262
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105452151182268887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105452151182268887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105452151182268887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15319891449962236366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105452151182268887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14124862738846038338
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18058439211441456286
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12824016190610382225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12824016190610382225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12824016190610382225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3467547098277083272
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17571397130661778041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3799780300050269068
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7824201676975876874
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3799780300050269068
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093746103412643649
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093746103412643649
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093746103412643649
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12045406399812737068
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093746103412643649
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14547059667322106211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14547059667322106211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14547059667322106211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17749716806782985123
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14547059667322106211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4276320022939160834
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17643085335704509310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14965563725111780865
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13168785166761282770
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1481345310915902657
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14758277684964620733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16046622591743518090
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8847532592184319816
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15118074813677282304
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          958875886558434679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14758277684964620733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16046622591743518090
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8847532592184319816
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15118074813677282304
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          958875886558434679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2602748132502891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3751845982462242923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1865153144215084464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17858070142754470383
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          855693738218616842
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1607607228725634961
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13271451856963328595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4831046796258034406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5739753494793955168
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16244856208509803609
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14758277684964620733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16046622591743518090
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8847532592184319816
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15118074813677282304
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          958875886558434679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16630748084230317586
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2247052490807352208
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12679712547111191711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9192723520575465553
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13040887588651568038
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11739106939528290811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8624562905162231900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14871433604768330356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9397998918260636008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4741703366890969189
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradient_dirty_laundry_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16978210180572955621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_dirty_laundry_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          637854104407104115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_dirty_laundry_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2515733614721864626
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_dirty_laundry_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11465802641541660752
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_dirty_laundry_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2515733614721864626
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9800597089191342482
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11303638772874009054
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5440703124026425939
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2546420512273550381
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5440703124026425939
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14703125591712713753
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17510398591996397109
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5985102520168480975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2986891744271581923
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5985102520168480975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2230084888912360694
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7465934387832943420
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16605120526645549774
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9388661571018248940
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10628586845016617452
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16953788240617605317
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17033624275484244376
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          169027135498041421
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11612303178833324850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          169027135498041421
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12097193819749785352
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15403609442106846169
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2419426995212058042
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6029254312400609793
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12090528873106669963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9864202235334056076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12090528873106669963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12227348360284420259
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3955747071082596728
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10472560090813482435
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13235754433685839215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17557970359039826564
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13235754433685839215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7893853359175854146
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5219979658561439244
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3211745479711329543
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17035563971167092066
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5165571929278471309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6147499591152784117
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          225020687293424504
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11527542446888766490
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8515310025484729496
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12478700377844813122
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8515310025484729496
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12227348360284420259
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10887305247691796896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1082062268335165982
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          683358655251706777
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16307177227728636543
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2583075582908960098
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradtext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9146082458658249961
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradtext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2268171585127424663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradtext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8632902654060963030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradtext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1375864790732725387
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradtext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4858623585328518977
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "hairlines_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3746404902639900755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairlines_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13269473576016756464
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairlines_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4510143230044868465
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairlines_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7832496952922641344
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairlines_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18117004874449161145
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13753109946556116551
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9057348143868599843
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18273777771364992874
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15416135243961642681
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17201093324020423129
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "hittestpath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8523631311893232363
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hittestpath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11207060820710342539
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hittestpath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3542250264918452791
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hittestpath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4368572629756795538
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hittestpath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1774670947569183167
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15353016436502839307
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10137730247008255507
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2185009192733708381
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4455484211239477170
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2994277352970065179
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagealphathreshold_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9262312764539834132
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagealphathreshold_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7434810293688860099
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagealphathreshold_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7434810293688860099
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagealphathreshold_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7434810293688860099
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagealphathreshold_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7434810293688860099
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4050927371409298902
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11543952802185029256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17711173961568530641
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17711173961568530641
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4301364147710982888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7972099385022043163
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13524624881629427986
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9123527159995734506
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6509805491311925747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3348160208451213136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12120345012269820932
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6674427432111772822
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11069776588985027208
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6079122060213400647
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5045143698351348143
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblurtiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17054250179583622870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblurtiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1156342941006792822
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblurtiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11336551237729672640
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblurtiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11336551237729672640
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblurtiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14780961132879929600
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14569224010202736848
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13401294041247408330
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2421552135721980456
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16104300300051532861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16334233174028260946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersclipped_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14771974755728278127
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersclipped_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14537515405997069608
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersclipped_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14402254378860870900
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersclipped_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6251521850339800063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersclipped_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915579201755413377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10247589757189186626
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15587395118695958545
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          501400666034284343
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8222498952068485559
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5518003520302698509
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11183433079869112751
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          983928521095254996
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16488788837787377286
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16488788837787377286
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16488788837787377286
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersscaled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6454090845110612368
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersscaled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4353899728334541990
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersscaled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11423939606971574450
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersscaled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15983510321246205590
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersscaled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15624400477400066280
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8006485449338039559
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          240159961841543167
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14582154252831191796
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1520366797391603185
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16465366847175223174
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageresizetiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5141682991552891869
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageresizetiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10937092928162206016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageresizetiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10937092928162206016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageresizetiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10937092928162206016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageresizetiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8644525877870358267
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5059700774653818583
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2338732552908364652
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13182984977214873037
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13182984977214873037
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13955465857932776642
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "inverse_paths_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12462644636324896185
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "inverse_paths_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6825022448693098908
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "inverse_paths_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311895978368842562
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "inverse_paths_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10426477699808452586
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "inverse_paths_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2370936279830175070
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14661893292754926992
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14283445429737354407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14283445429737354407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14283445429737354407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          34198758193522334
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lerpmode_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10818286910555371914
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lerpmode_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4328896907702672721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lerpmode_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4337305683950474221
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lerpmode_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9267399652224228185
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lerpmode_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1428546987899351483
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18156908345610667988
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1769392566669846297
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18271831098350645344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18271831098350645344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18271831098350645344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lightingcolorfilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7968186755331229682
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lightingcolorfilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1516320293275754779
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lightingcolorfilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          556860185459449659
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lightingcolorfilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3872806463861356082
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lightingcolorfilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          556860185459449659
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lineclosepath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3640305923296260413
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lineclosepath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          276407871848572356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lineclosepath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16287622823135714887
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lineclosepath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17234606436915991127
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lineclosepath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17471787301847758321
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16431419263757631790
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3671039803897286861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1771844914197216619
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8487612764787744444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5466634636951993842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14599078747412582488
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15818539722582657764
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          676111419579198838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8978480198192478930
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5413870340007295648
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13081606013576553320
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1788065363817621252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13705231434945847811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13705231434945847811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13705231434945847811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matriximagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14072014607244294525
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "matriximagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18093313968129673224
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "matriximagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18080388188695782013
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "matriximagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6827451056190936667
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "matriximagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2177633859503791126
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          899343682044846669
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4811817245879819217
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15858100026349596240
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          899343682044846669
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4811817245879819217
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15858100026349596240
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          899343682044846669
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4811817245879819217
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15858100026349596240
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "mixed_xfermodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9621832453494372057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "mixed_xfermodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1944307888764212912
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "mixed_xfermodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2856294934376734458
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "mixed_xfermodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11526222328150036340
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "mixed_xfermodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7591469946375994741
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "modecolorfilters_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2595933616904054518
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "modecolorfilters_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5532792141023246970
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "modecolorfilters_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13540332316670655625
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "modecolorfilters_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12218867104690768584
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "modecolorfilters_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13540332316670655625
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "morphology_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16521635780782687979
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "morphology_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          646563942213926444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "morphology_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16797936202031245776
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "morphology_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16797936202031245776
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "morphology_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16797936202031245776
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9070004057067143109
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          979358962257430997
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1931333095841013517
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2299872890887738341
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1720078348651898798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3479815062121124662
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6077337614356925620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1686562823295652230
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10644565422189658447
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          334050809309354339
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10563086407668217292
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10894823014236844623
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17913826207662276248
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18274907554323845349
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6908080221790706626
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16347389714960675049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15799707465465693052
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          91575498355555016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5852466887392959578
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18123568953700729991
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "nested_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2682194241459481981
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1792040421885608938
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2956570062403950585
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15571494050515187668
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10434121413968052702
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "nested_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1642884649618332584
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2247784507927793592
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6638289994984814421
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15571494050515187668
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10434121413968052702
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "ninepatch-stretch_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18411873313823762166
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ninepatch-stretch_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14862133879758372505
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ninepatch-stretch_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16157379715594734952
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ninepatch-stretch_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2485159481287372607
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ninepatch-stretch_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6226802852587597390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8797161389659029383
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9282658625266410335
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15611815259151344511
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9859297600562619539
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8612369225308422078
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9332445919508686672
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6836578362263548470
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16160570029354727735
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3679976481498468690
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3679976481498468690
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "optimizations_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13857521313271479795
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "optimizations_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9183725853792620789
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "optimizations_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8127642505197276510
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "optimizations_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9183725853792620789
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4201817511424287157
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1184189085315519615
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1279912102270906485
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13661329316121048556
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7097895563118983089
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2071285435632750836
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          454419097931516549
+        ]
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11892545700196234679
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11023418833969415383
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          636464920332490932
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9785959084810043220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11218436066091856382
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17707872611568165011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4594497434690420731
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patheffect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12000354906642530911
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patheffect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13136038454993854220
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patheffect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14067025671364900578
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patheffect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352969135236811083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patheffect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5415179396675387208
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pathfill_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9913956212375399295
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathfill_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12306117555345084962
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathfill_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17931803287102431107
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathfill_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4498024042829372500
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathfill_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9028424578854512276
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pathinterior_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3396766038203432666
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinterior_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12110360517026697498
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinterior_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17479758826656648496
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinterior_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1151605755804748972
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinterior_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17388654056447984491
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8654831421971241050
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11144284047498640984
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3520993708181297768
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7090035026515398892
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13350177784367266818
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pathopsinverse_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17617505767021323437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsinverse_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11577432472710705185
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsinverse_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3181704756887945687
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsinverse_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5591146566217797280
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsinverse_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11025506788242552694
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6154660184356174115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4313744187563601995
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5677908987773616373
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11460675912619342328
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11157237442918763566
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "peekpixels_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2758866006531517960
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "peekpixels_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5344748376042459393
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "peekpixels_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2117041505467664585
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "peekpixels_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9264992068618239238
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "peekpixels_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17077044380877012193
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1539561209878927288
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14413015027460366330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6945090583139588959
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6945090583139588959
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6945090583139588959
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14801725520513922963
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12098491632750651220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12098491632750651220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12098491632750651220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15493927584984335902
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7074442374200469751
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13807718612946490238
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1925902024016434685
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3298829096497099492
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13288790000507495232
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8567194488499472739
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8567194488499472739
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7449362905694021309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1704644220614711688
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14262258178388208669
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15752228483716340184
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9600712706940307510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18273026657594929057
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18345234563841023550
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6795673127289875978
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "polygons_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7471239721499308199
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "polygons_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          961606689700631635
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "polygons_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3344969070850904263
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "polygons_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5468058878210139138
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "polygons_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9887825123733570563
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313537653075020359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15540539959703820843
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1528621230156781313
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6418169567469353560
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15207535740869213581
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17750273719514230908
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12968426991611677795
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16287167623514876790
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14883147621745392045
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13719367263412668706
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "radial_gradient2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2509551852078940571
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4012506323387989153
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105030510199748233
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          616895105520984452
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11600744039926164744
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "radial_gradient_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10067107685325019703
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15369886492036014971
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14941464582660867910
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          227457349309358061
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14941464582660867910
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7959433338453691623
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10522172914016896806
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11339980900210544915
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6239879080037398278
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4010833721373542094
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "resizeimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11574452324482789141
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "resizeimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004076002839832883
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "resizeimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16941137351142187530
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "resizeimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5168536017395085399
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "resizeimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18403762395924531087
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "roundrects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17752420136993868343
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "roundrects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1161927000752559561
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "roundrects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12086616517730738594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "roundrects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10172086750392023029
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "roundrects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4051216113582839289
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9108911139001347487
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14795654963615468231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14635716521372290944
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8853776977311383548
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18168424126789500571
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3055968029040102617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4013957681165008981
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_clip_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5677622882171244043
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16102744790083806869
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8388919664468878536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3055968029040102617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4013957681165008981
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_draw_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14635716521372290944
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8853776977311383548
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14953639362807460202
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3055968029040102617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4013957681165008981
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_draw_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5677622882171244043
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16102744790083806869
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8388919664468878536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3055968029040102617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4013957681165008981
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4300907509754823851
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10791384680520892994
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4300907509754823851
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15880737340733736621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9700284503645872210
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10204288420390896965
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "samplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11413662173938170642
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "samplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16512668348979676302
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "samplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15376222571969084017
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "samplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7773313959599550205
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "samplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17550423132771028045
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "scaled_tilemode_bitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16202156323496453186
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_bitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18320695188397156612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_bitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          291294819063810031
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_bitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9284152842222597272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_bitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7031568369867707114
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5301354159895374100
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7212824178569834046
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2333961629735595646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9628133036798734492
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12967756622957744836
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17916990489332610247
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4361073581663031498
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7099532709538059803
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13634813695671871778
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5494217425218220819
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10721334890659730406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2988734578790256008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10979969633399782871
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15444592364779646619
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8102298704200698886
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "selftest1_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12927999507540085554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest1_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1209453360120438698
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest1_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1149339852105949057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest1_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1149339852105949057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest1_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1149339852105949057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8863920166200910451
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13451349865803053525
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7903070799454133570
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7903070799454133570
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7903070799454133570
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4739835670329472924
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17407206349726255504
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2509331043182251203
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8879550809322519694
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11320774917639038133
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10804395662064163067
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11973828271981934898
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16065988395535735595
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10158714776567287562
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15113208936007369755
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "shallow_gradient_conical_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17982294224537325140
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_conical_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10213220249745462631
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_conical_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          103053982990746762
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_conical_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1305496964728839535
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_conical_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          103053982990746762
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2414118852281882343
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2600596201303470577
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16719793849261907536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16719793849261907536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16719793849261907536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7637358666429963225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12757191687259698018
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10939736148238347507
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15635279764260732794
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10939736148238347507
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6974552498637279685
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          766715199662180977
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          505316756506251280
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15070177880693766645
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          505316756506251280
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleaaclip_aaclip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2716635983736130572
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_aaclip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6323185425935976578
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_aaclip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14792628545823171531
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_aaclip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6437416978571967965
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_aaclip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          158361826253799606
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2716635983736130572
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1684803956798529676
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7776449119510647616
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          132852148809063331
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16759061850730950379
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7856938689333642802
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3392443767163314236
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6118609150423265769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10359254455982955934
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2100931586089555889
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleblurroundrect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12397550977213308037
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleblurroundrect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5652577089689509120
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleblurroundrect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3196650548285977166
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleblurroundrect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11504299822100144685
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleblurroundrect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4323854140016112056
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "skbug1719_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2332391077132553330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "skbug1719_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13212045663266308489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "skbug1719_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6846687859627369127
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "skbug1719_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4851170883353423359
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "skbug1719_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1075111322101840115
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "spritebitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13563811160364567248
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "spritebitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          227198932212139294
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "spritebitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1647638141282055974
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "spritebitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1647638141282055974
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "spritebitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1647638141282055974
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "srcmode_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7716668905830605416
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "srcmode_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6635637522868788156
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "srcmode_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15751900135813748883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "srcmode_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2022832707658358979
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "srcmode_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3143492941196749873
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stringart_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          517466260915157438
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stringart_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12919217765216356865
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stringart_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3407765471622235987
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stringart_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10146871010021812623
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stringart_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5208896917206754825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stroke-fill_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9267212173575576732
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroke-fill_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12391135340682188523
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroke-fill_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6113074317698019955
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroke-fill_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17210831440928667457
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroke-fill_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1252486262030484135
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15458182862530229195
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2467605443292336055
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1648852024813032692
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9666123301505523830
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4717987710581110780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1252564837192523211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3590050428307921218
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6336266129240777095
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4337570176483288507
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9133559894067712940
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12878931714876978005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9947658613138732028
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17262994750584158226
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2353456527456632046
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10287743286276150382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13975044413592406455
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9847781398855716283
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16530030588081833286
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9989688846254434850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2243202409153973536
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "strokes_round_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8830084223721413158
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_round_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14762739513429490065
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_round_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18208182831453388386
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_round_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10553904208497015722
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_round_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11128748943191707337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13786058399173961813
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17780930205994965542
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9120431816414641182
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10848626204179922135
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13981050594918231661
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6155339908971373908
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5497460981955702016
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17720341081172525928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17720341081172525928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17720341081172525928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10876942606580879984
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6913857649673524662
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5115665870392462534
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5714371734871865975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15671347724433934993
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texdata_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2736593828543197285
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texdata_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2736593828543197285
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texdata_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2736593828543197285
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          163112871246100159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16312476967739707580
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texteffects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17000480734115531314
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texteffects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15806412237117346050
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texteffects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17515591586084571256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texteffects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17515591586084571256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texteffects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17515591586084571256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texture_domain_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17099586086831668928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texture_domain_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5351853408178981372
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texture_domain_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7646850408534888075
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17949451347125150629
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12074631820414627784
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17501446579955337831
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3967170325391392383
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3979007074061355265
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17882028260402842392
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2596255945580270876
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14626919895309756138
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5543949501668688147
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5158860798933444596
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tileimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2893625561624793005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tileimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4046978300889376789
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tileimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4046978300889376789
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tileimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4046978300889376789
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tileimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4046978300889376789
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16202156323496453186
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18320695188397156612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          291294819063810031
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9284152842222597272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7031568369867707114
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5301354159895374100
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7212824178569834046
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2333961629735595646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9628133036798734492
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12967756622957744836
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13107047343822691410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17656517732103593482
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1460100162088232495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13345565835934825527
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1016379573268994349
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13721934356222709475
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2703226654627094494
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5786648404634357546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17966057434048971014
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8039290250803630632
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tinybitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12538857845722393084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tinybitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11468465429225805
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tinybitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5633315905476176630
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tinybitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5633315905476176630
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tinybitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5633315905476176630
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "twopointconical_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8813543224253503623
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "twopointconical_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10487196951809200447
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "twopointconical_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2024124685080721188
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "twopointconical_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          156310787923265214
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "twopointconical_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12294271572612285815
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7630443482944449324
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          541791446919644762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          541791446919644762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          541791446919644762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8102001591139534628
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5782656429071871585
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093615056685804062
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093615056685804062
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7242130339475265377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9946363327226628317
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18074462901923174459
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18074462901923174459
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14302855136061508597
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093615056685804062
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10003362713791489293
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7205684210809830268
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13789324379573341403
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7963837640830480163
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3663362132010737168
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7457535226975143406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7205684210809830268
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13789324379573341403
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7963837640830480163
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3663362132010737168
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7457535226975143406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17631782564810163297
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2817472816787253027
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15856387179055100718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7062959562720776972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13842064697956814589
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17631782564810163297
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2817472816787253027
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15856387179055100718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7062959562720776972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13842064697956814589
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "vertices_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12016571983635712769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11220339642934269879
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5116617595194840746
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1238935355949663480
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10433092584712962295
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1124242406804705805
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          753078211441143405
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16119691045778726906
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8469012837534615666
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10724574345208314013
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "verttext2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11345248105896220068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9273698158417602516
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12923080987897144985
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3215791117169189388
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2405294955146628811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5372075096677220148
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6104627350528703861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          104419481998564261
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4674076918445194225
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12704247657614646796
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9169362964428595499
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8036801967395272185
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17451382664837991053
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17451382664837991053
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17451382664837991053
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3669258016173734776
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11711243112888067446
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12389511830554214503
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14411744652289973264
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1143772492254209525
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17424339298588817189
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4115706103934190223
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9701350788577476400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13266604257445564827
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12305758378054318125
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16726470973503710769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          931382594145774191
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17289770589494488729
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8998690330665917593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17997093412787453516
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": true
+    }
+  }
+}
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-Reference-Unknown-Arm64-Release/expected-results.json b/expectations/gm/Test-Android-Reference-Unknown-Arm64-Release/expected-results.json
new file mode 100644
index 0000000..fb41fa2
--- /dev/null
+++ b/expectations/gm/Test-Android-Reference-Unknown-Arm64-Release/expected-results.json
@@ -0,0 +1,12931 @@
+{
+  "expected-results": {
+    "3x3bitmaprect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16998423976396106083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "3x3bitmaprect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2054956815327187963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "3x3bitmaprect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2054956815327187963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "3x3bitmaprect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2054956815327187963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "3x3bitmaprect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2054956815327187963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5680982666881858509
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3732865537665519508
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16138168970750938639
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8134232418720361841
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aaclip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10533368505163408108
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3404105191202303432
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11273986525140282221
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17425253971181998702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3770567129781642033
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "aarectmodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10856546368486015793
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "alphagradients_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1062660886109823876
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "alphagradients_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8685680158225267849
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "alphagradients_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16099433447675743067
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "alphagradients_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1425061253173299211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "alphagradients_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8739326512478669061
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          495458940800121980
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7871844485538418123
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2850728294444748824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3418687822256532441
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "arcofzorro_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16068426685709495414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15265492591840367073
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9219144465915962055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15566840808391504142
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4107685585296508350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "arithmode_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6200394711225120969
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_conic_effects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9615451479430787512
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_conic_effects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8229328116050661849
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_conic_effects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6065575029328298155
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bezier_cubic_effects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10280047986202946903
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_cubic_effects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18028439748843352797
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_cubic_effects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1806914509748908078
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_quad_effects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1624329355466510234
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_quad_effects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15977694152698269230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bezier_quad_effects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16341310555553934694
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bigblurs_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2422083043229439955
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigblurs_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17309852422285247848
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigblurs_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8741984205182434161
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigblurs_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6463895742034431573
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigblurs_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17909315077536907276
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6169251833522681202
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10455976041474647335
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8953572525650094726
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bigmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6565617683803240866
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9918578779790399213
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bigtext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16290380272927731074
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigtext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10628348283204942671
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigtext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12280679610593832898
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigtext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12107669081044262947
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigtext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9905378213660022882
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3459248890389921752
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1875487390803094182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1875487390803094182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1875487390803094182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmap_premul_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1875487390803094182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapfilters_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          345159363880628503
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapfilters_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662285177911778105
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapfilters_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6135240601272046401
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapfilters_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11082017410849796451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapfilters_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2512611752667952735
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmaprect_i_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18096603530409620115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_i_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10732507724426853062
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_i_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8511579297892894623
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_i_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7851232271117128980
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_i_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1399188605698989457
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18096603530409620115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10732507724426853062
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8511579297892894623
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7851232271117128980
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprect_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1399188605698989457
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5432165152598403513
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5432165152598403513
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1454528164630516875
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6877842861292710470
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmaprecttest_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2386657650052469554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapscroll_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18243297381828962051
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapscroll_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6170260754610315050
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapscroll_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3054365581811078847
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapscroll_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7776828220102838697
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapscroll_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13105039024633899653
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapshaders_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7997010809127251282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapshaders_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11547423821464646560
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapshaders_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4292341330653523437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapshaders_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4205379988615278373
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bitmapshaders_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16768122979300405928
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11249040102864413890
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8913537231360636680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14062072472966722601
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13895505754463462984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapsource_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14062072472966722601
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bleed_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15265790973475056741
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bleed_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5689050822385083392
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bleed_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17870693939301194374
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bleed_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7798430527876011187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bleed_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          527932406326671983
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11627389852748930348
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11187657384039514790
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6125325568353237512
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15077952026473594665
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurcircles_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7277028211493676521
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurquickreject_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14575894174086753692
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurquickreject_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1951057418144050940
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurquickreject_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8760711575806144560
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurquickreject_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          64400470544822501
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurquickreject_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          64400470544822501
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17888368671702445896
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080629583390552103
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11980986810369723513
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12624863915440686736
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16569869274475548824
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5272469947522392970
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16280549642825337575
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12952750947910530683
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17423569280673366651
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17360690807365040182
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurs_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13137504778664331730
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext1_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662423679102384425
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext1_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662423679102384425
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext1_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662423679102384425
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext1_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16392176982191881918
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext1_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7682434275864547744
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "chrome_gradtext2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17256358122895634639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17256358122895634639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2564291978259597241
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12148996194027470930
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "chrome_gradtext2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17382282587146791370
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "circles_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6008092610982260089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circles_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14991965560443449693
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circles_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10167332900422109271
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circles_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15421079171046661928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circles_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2678163400591480162
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "circular-clips_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7045926575348655010
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circular-clips_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7045926575348655010
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circular-clips_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1988347527319338472
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circular-clips_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14908415861822233627
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "circular-clips_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10895255954294537598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "clamped_gradients_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6740406662310759992
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clamped_gradients_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12600235552582834170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clamped_gradients_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2843220994853257782
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clamped_gradients_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13709860748431912538
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clamped_gradients_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2843220994853257782
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5543970311616574408
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9243927175489158803
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5000282312660607550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13139990863075622673
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp-hq_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5000282312660607550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-clamp_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6731999058828201370
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14000830941634575767
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14412729226029504152
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12553623139335427893
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16692610170563400568
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror-hq_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12553623139335427893
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-mirror_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10131313151475985201
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5937007347321497195
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6655127558305687514
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271388652122232326
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12963654110512376981
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile-hq_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8271388652122232326
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clipped-bitmap-shaders-tile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          25307406092894825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2047816653827409443
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2047816653827409443
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2433752872333325525
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4143351860764425727
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "clippedcubic_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8872399908845615950
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cmykjpeg_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13052709698662664204
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cmykjpeg_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9927483517871541702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cmykjpeg_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9927483517871541702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cmykjpeg_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9927483517871541702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cmykjpeg_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9927483517871541702
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17051103650973594106
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1025940906896326990
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7133069077424093701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7133069077424093701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colorfilterimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7133069077424093701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3235581033534814469
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5008998920935758481
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10772261323503226822
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10772261323503226822
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colormatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10772261323503226822
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11621506803825288957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14190393959731746891
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16465183276659682081
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16465183276659682081
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "colortype_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16465183276659682081
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1971136545200141017
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7558229948134696044
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7558229948134696044
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6100333162046229937
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17476385235562312316
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16086429144316222800
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12832097210600987517
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12073577656052761501
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13127122903587486352
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2618721010833979939
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip2_path_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13497374237280200272
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13907447324398926215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7064746384958261694
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9471735316991657266
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_path_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5765718557844909990
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip2_rect_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4388703640234091457
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rect_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6840582159469938207
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rect_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17329940322086025654
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rect_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8050767971717414561
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rect_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3160075146533642167
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11609605102436644365
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6484021739759757221
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15256308173777619343
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7847760144633844068
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3072745735157512087
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip2_rrect_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13632122222988723717
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14609392979961079625
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7607167258483373168
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15131202646914045884
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "complexclip2_rrect_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5371709705048813809
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2325131462719689144
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15708997754764845116
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15189155443552210923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6919536005785204777
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          981140130956307876
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9401534843786095695
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5110280309113538858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_layer_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17777699321728709295
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10795457976747629138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9255525311477145573
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          107757481322174214
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5158682864201505817
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9522614830088431557
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9285320341410288250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13992567653263715999
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11757389550631022989
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13076020007854111750
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_layer_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2615429072046131347
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14987478535910616085
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5223702466494518255
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "composeshader_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4616535333272790055
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7653047818906774476
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2785143308349902483
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3069347792056802140
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13415066704472475041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13415066704472475041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_alpha_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13415066704472475041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13476719363156020502
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13476719363156020502
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "composeshader_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13476719363156020502
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convex_poly_clip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3948251542575458636
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_clip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11034884277227293367
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_clip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7867705685854011032
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_clip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16412671624919600564
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_clip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1883714548275530342
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "convex_poly_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9997743782700417564
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convex_poly_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14098578924213652985
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convex_poly_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10130387245603970231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12930829906409283378
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5590017600958012619
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16141054984179977082
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1577336393354602706
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "convexpaths_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11761962128954199420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "copyTo4444_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13047964648578320887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "copyTo4444_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13512184095617016052
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "copyTo4444_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13512184095617016052
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "copyTo4444_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13512184095617016052
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "copyTo4444_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13512184095617016052
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "cubicclosepath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2345715375030022927
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicclosepath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12849881092393067256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicclosepath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15191345378522401619
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicclosepath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1186842997313654987
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicclosepath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3376308403876425995
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16905942204084829637
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2700158731075789675
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10506940913420847037
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          549590040284264230
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "cubicpath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5247935948854828221
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashcubics_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13530080652412977490
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashcubics_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2169040330228236229
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashcubics_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14010323779373410567
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashcubics_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17751931895117204488
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashcubics_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15469553023761418546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashing2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13156696673314639856
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15806004005385515608
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6815734951724900700
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15811554800916365506
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11679144472381784362
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashing3_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12219938204781922
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing3_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          277815915162459879
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing3_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8566656494085823417
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing3_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7874984797872337707
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing3_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18144570818565346260
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashing4_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1285926743114346270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1394068287232006716
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4119744344752250956
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4196388052103005149
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing4_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12716951463835119116
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dashing_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14912539765453208522
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11645276935331048518
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          484770861362799750
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14510209917265279305
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "dashing_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14510209917265279305
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "degeneratesegments_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10466664180330873334
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "degeneratesegments_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3996746667148125710
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "degeneratesegments_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4907300117469925225
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "degeneratesegments_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8371223905519476756
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "degeneratesegments_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11777374227797392699
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "deviceproperties_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9581820593659890703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "deviceproperties_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14195512172918453244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "discard_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11635187478196931850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "discard_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11635187478196931850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "discard_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11635187478196931850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "displacement_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9964043232524494023
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "displacement_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8812360810248646843
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "displacement_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8565417244362419697
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "displacement_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8565417244362419697
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "displacement_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8565417244362419697
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "distantclip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "distantclip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "distantclip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "distantclip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "distantclip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12081034570142193461
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10903381122071794033
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14431765885366021905
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3280894626320084909
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1679496167850171703
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_high_512_256_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1168815789267919276
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6140325482496116397
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16629314387624924083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4417265118328754927
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2865115198277360103
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8318264989773826055
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          146618164289407850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13682412046418160056
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3280894626320084909
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5972223539601497054
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1168815789267919276
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15049441533248059743
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4357112622205445213
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4669810823447720319
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6294302794168975688
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4964331974602408988
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7427438670963424834
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13867304480215187457
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18232159459512256382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7242452800597086444
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_high_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          232650040899166460
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7793475532993441069
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2525443652532187813
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9714755284879996124
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11085841619585784123
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5630345150013547410
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16202891097923593943
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16057075759434115164
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18232159459512256382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9415478158149096409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          232650040899166460
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1703073926628991198
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16322347441140460920
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9499136896577531799
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4122284216066015433
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9548901024930911300
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4946691776839943214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4036791490242594432
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14402041105652881195
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15773305950634890477
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12015146308140154097
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17049650673567275451
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16230085031274022751
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10785325214215702800
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14682256763331130073
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9206254719726879906
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1837411953574676536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6259702434008608341
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14402041105652881195
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16096222533538746319
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12015146308140154097
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149865604022932026
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5032185698840173535
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18322907672040918672
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16629367922595384594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17711326968880099014
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14885443772641556897
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9217510046825383362
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7316445525652115151
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5041644101832918027
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawbitmapmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12878478093979926276
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drawlooper_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1977841434427374344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawlooper_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10410746316347940725
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawlooper_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18138990658460563504
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawlooper_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7040875820758603592
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawlooper_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6309775068063051029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5763769801346273390
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10105924271191235629
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4799188806446627840
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12535488919130000675
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "dropshadowimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8570678133707623518
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drrect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7282537335075785928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drrect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8863849031372460120
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drrect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12032414562671442267
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drrect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12812244415353974975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "drrect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7753131063978727382
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16960104312592762778
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14179105798042777292
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          995796898386366606
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10656411028302201279
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "emptypath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3665018619870944721
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "etc1bitmap_ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10660132459335344948
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4755621039067033683
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_npot_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352463391366748675
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10660132459335344948
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_pkm_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17338451294848191155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3263188022291407521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "extractbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11559795738519917215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4768741511907258218
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11150486540244810089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11150486540244810089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11150486540244810089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "factory_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11150486540244810089
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7781767658511133788
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15926472232550846517
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16838534225394965684
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9002062426255277430
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fatpathfill_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14038996595497366789
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6394623980536394421
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4586322702989781686
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11027690090981579357
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1405934342638609234
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10587067134950383884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filltypespersp_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9878940293263687062
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypespersp_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18074214067524610773
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypespersp_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15741786351214647198
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypespersp_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10141655382174130521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filltypespersp_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2420838640516336860
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterbitmap_checkerboard_192_192_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1302571164019139584
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_192_192_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1628983305024081591
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_192_192_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8442978142037036312
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_192_192_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1983942016959154459
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_192_192_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8402140909094062636
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7646022030248958633
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9026060023130302159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10456709796483052890
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5280902776134426739
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10749845338814785119
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_32_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7492090674869210215
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_32_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17557255555542043996
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_32_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14030341984444358122
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_32_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11693321457901891931
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_32_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6575523098421564071
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_8_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11985832678862054845
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_8_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6740071145134585279
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_8_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7153103239611262568
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_8_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7002854654353738207
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_32_8_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8788270204561233782
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_4_4_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          644944384575064193
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_4_4_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          230093671414916384
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_4_4_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2219260729330785345
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_4_4_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4460441267403725517
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_checkerboard_4_4_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9169343746984194045
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_128.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12821179432869579516
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_128.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5320960699319223840
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_128.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7190783558262028798
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_128.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17302685400977738726
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_128.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12485566063545782556
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_16.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1545185468827262042
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_16.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2028999451540933459
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_16.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1194931309760096840
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_16.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15518917334950092166
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_16.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10171324835261343670
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_256.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15598738669811122132
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_256.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6153989879750293303
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_256.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8299138092654008
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_256.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17435701251674019391
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_256.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11473232264179437462
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_32.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          573090442343199224
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_32.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17572528082893274078
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_32.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16922077612324074886
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_32.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6336606019785014415
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_32.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17145922605765993976
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5900404501445419588
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2972012266462825423
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17708614393374152687
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6311074125671995560
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_512.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17084415400287303864
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_64.png_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6888811561911833737
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_64.png_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18314323529138104796
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_64.png_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10371560779910511424
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_64.png_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          152513634616866145
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_image_mandrill_64.png_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15262410401104836311
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4658409309637948923
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2680492854341107541
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15959938188761089149
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2618691591940464743
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_10.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11457026221671552788
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_3.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1045985194128200391
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_3.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11066785285645824658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_3.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2703784268130353392
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_3.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4595934339506207747
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_3.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10819059090915870146
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_7.00pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8707751834300887471
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_7.00pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9588038223776538212
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_7.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10696518928883964326
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_7.00pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16964839535901188924
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterbitmap_text_7.00pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          964322779266615494
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5594467318955027257
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9270340285022118879
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "fontcache_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7122371849485640073
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontcache_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7122371849485640073
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontcache_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7193206875886806378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12201658576022942621
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5212774837146287438
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10274342291140328927
+        ]
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10274342291140328927
+        ]
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_iter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5513384533889704848
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14439323017086424327
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6546267859629380412
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6546267859629380412
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6546267859629380412
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontmgr_match_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10425971092471098788
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9156029157770316510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17853826291384107654
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1171079048376804989
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7875202569123646599
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "fontscaler_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14638286221799373252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6112218413602965540
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3629288051003909841
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15684001358909497263
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6331184130756262249
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5279353358620915852
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammatext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10522992496710310056
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammatext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          810016065483539842
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammatext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11904962674552578785
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammatext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3829446403711318055
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gammatext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1707855369960724268
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7664223524042185177
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14987153633306294415
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14045875957630310388
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5095141316207268684
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "getpostextpath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1047049262326645642
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8844253733895577971
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          373739036198791129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          373739036198791129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          373739036198791129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          373739036198791129
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3486485929104356236
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10633738215712183989
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5234100658342674745
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4744970992857502154
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_bilerp_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5234100658342674745
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17592263249674059658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17592263249674059658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17664227249162604428
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8239860526252863351
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17664227249162604428
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9837143541713078189
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9837143541713078189
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9837143541713078189
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5287801775965535756
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_clamp_point_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9837143541713078189
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          155204057300894620
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6169200792919803055
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14546624369730796798
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14546624369730796798
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14546624369730796798
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3198037782278889365
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6252132392610996150
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5114812640377291001
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7702421410730994532
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_bilerp_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5114812640377291001
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7897959591317755434
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7897959591317755434
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6027650989617108262
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11579385657707635347
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6027650989617108262
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105452151182268887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105452151182268887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105452151182268887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15319891449962236366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_mirror_point_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105452151182268887
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18057040418255616674
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7178545581016626904
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12824016190610382225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12824016190610382225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12824016190610382225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3467547098277083272
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17571397130661778041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3799780300050269068
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7824201676975876874
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_bilerp_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3799780300050269068
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093746103412643649
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093746103412643649
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093746103412643649
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12045406399812737068
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_rotate_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093746103412643649
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14547059667322106211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14547059667322106211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14547059667322106211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17749716806782985123
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "giantbitmap_repeat_point_scale_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14547059667322106211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4276320022939160834
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17643085335704509310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14965563725111780865
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13168785166761282770
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1481345310915902657
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10911580515745285899
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9687671988663432495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11006947578465183049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15118074813677282304
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          958875886558434679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10911580515745285899
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9687671988663432495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11006947578465183049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15118074813677282304
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          958875886558434679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4218664642765807794
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7628027693439564086
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15717774735860581988
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17858070142754470383
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12815920291456220598
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          864469610350305973
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1061667613472303987
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9137178698028013612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7152218358550301468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16244856208509803609
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10911580515745285899
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9687671988663432495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11006947578465183049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15118074813677282304
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          958875886558434679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          733236286672786025
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8354872977609962198
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6756008755114362980
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2033039618168211094
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13040887588651568038
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11739106939528290811
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8624562905162231900
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14871433604768330356
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9397998918260636008
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4741703366890969189
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradient_dirty_laundry_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16978210180572955621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_dirty_laundry_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          637854104407104115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_dirty_laundry_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2515733614721864626
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_dirty_laundry_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11465802641541660752
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_dirty_laundry_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2515733614721864626
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3257854206723121418
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17085140911695839234
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5440703124026425939
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2546420512273550381
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradient_matrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5440703124026425939
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          42238346884798931
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6538785661636291463
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13252579527834948627
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3457121314031615214
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_edge_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13252579527834948627
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2230084888912360694
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7465934387832943420
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9397113433319404913
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14932255395742614741
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_inside_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9397113433319404913
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16953788240617605317
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17033624275484244376
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          169027135498041421
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11612303178833324850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_2pt_conical_outside_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          169027135498041421
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17986561235486925113
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2765642849960132766
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2419426995212058042
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6029254312400609793
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12090528873106669963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9864202235334056076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_degenerate_2pt_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12090528873106669963
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6343974098574595047
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12941134113016055553
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14872108584912017257
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7326682059241730325
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8828315217808412428
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_local_perspective_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7326682059241730325
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7893853359175854146
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5219979658561439244
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3211745479711329543
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17035563971167092066
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_many_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5165571929278471309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5894862011463619604
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2581942217672907914
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2842147962568160190
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8515310025484729496
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12478700377844813122
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_no_texture_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8515310025484729496
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6343974098574595047
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13974282889693274316
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1258305220074921642
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1079024506125173241
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16307177227728636543
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradients_view_perspective_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2583075582908960098
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gradtext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9146082458658249961
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradtext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2268171585127424663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradtext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8632902654060963030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradtext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1375864790732725387
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gradtext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4858623585328518977
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "hairlines_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3746404902639900755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairlines_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13269473576016756464
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairlines_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15010770576403415780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairlines_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18220941149044814585
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairlines_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18117004874449161145
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13753109946556116551
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9057348143868599843
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18273777771364992874
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15416135243961642681
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hairmodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17201093324020423129
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "hittestpath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8523631311893232363
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hittestpath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11207060820710342539
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hittestpath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3542250264918452791
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hittestpath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4368572629756795538
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "hittestpath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1774670947569183167
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14456293106670687118
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3693329049564187895
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2185009192733708381
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4455484211239477170
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "image-surface_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2994277352970065179
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagealphathreshold_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9262312764539834132
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagealphathreshold_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7434810293688860099
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagealphathreshold_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7434810293688860099
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagealphathreshold_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7434810293688860099
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagealphathreshold_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7434810293688860099
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4050927371409298902
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11543952802185029256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17711173961568530641
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17711173961568530641
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4301364147710982888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7972099385022043163
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13524624881629427986
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9123527159995734506
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6509805491311925747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3348160208451213136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12120345012269820932
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6674427432111772822
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_large_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11069776588985027208
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblur_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6079122060213400647
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5045143698351348143
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageblurtiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17054250179583622870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblurtiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1156342941006792822
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblurtiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11336551237729672640
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblurtiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11336551237729672640
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblurtiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14780961132879929600
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14569224010202736848
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13401294041247408330
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2421552135721980456
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16104300300051532861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersbase_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16334233174028260946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersclipped_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14771974755728278127
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersclipped_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14537515405997069608
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersclipped_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14402254378860870900
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersclipped_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6251521850339800063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersclipped_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915579201755413377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10247589757189186626
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15587395118695958545
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          501400666034284343
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8222498952068485559
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropped_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5518003520302698509
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11183433079869112751
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          983928521095254996
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16488788837787377286
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16488788837787377286
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersgraph_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16488788837787377286
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefiltersscaled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14742637760017989425
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersscaled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7714583592091446597
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersscaled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11423939606971574450
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersscaled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15983510321246205590
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imagefiltersscaled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15624400477400066280
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6916196793444678687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17314580917060153554
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14582154252831191796
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1520366797391603185
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagemagnifier_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16465366847175223174
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "imageresizetiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5141682991552891869
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageresizetiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10937092928162206016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageresizetiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10937092928162206016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageresizetiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10937092928162206016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageresizetiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8644525877870358267
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5059700774653818583
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2338732552908364652
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13182984977214873037
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13182984977214873037
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "internal_links_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13955465857932776642
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "inverse_paths_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12462644636324896185
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "inverse_paths_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6825022448693098908
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "inverse_paths_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311895978368842562
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "inverse_paths_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10426477699808452586
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "inverse_paths_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2370936279830175070
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14661893292754926992
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14283445429737354407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14283445429737354407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14283445429737354407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lcdtext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          34198758193522334
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lerpmode_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10818286910555371914
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lerpmode_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4328896907702672721
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lerpmode_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4337305683950474221
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lerpmode_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9267399652224228185
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lerpmode_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1428546987899351483
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18156908345610667988
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1769392566669846297
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18271831098350645344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18271831098350645344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lighting_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18271831098350645344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lightingcolorfilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7968186755331229682
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lightingcolorfilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1516320293275754779
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lightingcolorfilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          556860185459449659
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lightingcolorfilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3872806463861356082
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lightingcolorfilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          556860185459449659
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "lineclosepath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3640305923296260413
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lineclosepath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          276407871848572356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lineclosepath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16287622823135714887
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lineclosepath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17234606436915991127
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lineclosepath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17471787301847758321
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16431419263757631790
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3671039803897286861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1771844914197216619
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8487612764787744444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "linepath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5466634636951993842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14599078747412582488
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15818539722582657764
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          676111419579198838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8978480198192478930
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "lumafilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5413870340007295648
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11146919251978436021
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1606841984552213888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13705231434945847811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13705231434945847811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matrixconvolution_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13705231434945847811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "matriximagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14072014607244294525
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "matriximagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18093313968129673224
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "matriximagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18080388188695782013
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "matriximagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6827451056190936667
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "matriximagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2177633859503791126
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          899343682044846669
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4811817245879819217
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15858100026349596240
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_0x0_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          899343682044846669
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4811817245879819217
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15858100026349596240
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_1x4_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          899343682044846669
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4811817245879819217
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15858100026349596240
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "megalooper_4x1_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9244974085600588614
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "mixed_xfermodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9621832453494372057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "mixed_xfermodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1944307888764212912
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "mixed_xfermodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13047847845209349036
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "mixed_xfermodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11526222328150036340
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "mixed_xfermodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7591469946375994741
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "modecolorfilters_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2595933616904054518
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "modecolorfilters_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5532792141023246970
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "modecolorfilters_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13540332316670655625
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "modecolorfilters_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12218867104690768584
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "modecolorfilters_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13540332316670655625
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "morphology_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16521635780782687979
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "morphology_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          646563942213926444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "morphology_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16797936202031245776
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "morphology_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16797936202031245776
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "morphology_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16797936202031245776
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9070004057067143109
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          979358962257430997
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1931333095841013517
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2299872890887738341
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1720078348651898798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3479815062121124662
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6077337614356925620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1686562823295652230
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10644565422189658447
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          334050809309354339
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10563086407668217292
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10894823014236844623
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17913826207662276248
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18274907554323845349
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6908080221790706626
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16347389714960675049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15799707465465693052
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          91575498355555016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5852466887392959578
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18123568953700729991
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "nested_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2682194241459481981
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1792040421885608938
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2956570062403950585
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15571494050515187668
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10434121413968052702
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "nested_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1642884649618332584
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2247784507927793592
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6638289994984814421
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15571494050515187668
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nested_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10434121413968052702
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "ninepatch-stretch_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11372836632181742505
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ninepatch-stretch_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2287329273811057555
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ninepatch-stretch_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16157379715594734952
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ninepatch-stretch_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2485159481287372607
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ninepatch-stretch_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6226802852587597390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8797161389659029383
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9282658625266410335
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15611815259151344511
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9859297600562619539
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "nonclosedpaths_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8612369225308422078
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9332445919508686672
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6836578362263548470
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16160570029354727735
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3679976481498468690
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "offsetimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3679976481498468690
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "optimizations_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13857521313271479795
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "optimizations_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9183725853792620789
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "optimizations_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8127642505197276510
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "optimizations_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9183725853792620789
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4201817511424287157
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1184189085315519615
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1279912102270906485
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13661329316121048556
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "ovals_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7097895563118983089
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13032620715514196131
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16350623234684389125
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5078992531918210632
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7079579220602916012
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7833653665942395917
+        ]
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6649774899785349351
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18288995708673007668
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          793317929753086187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3840744329424491772
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7556145214358663305
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          636464920332490932
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9785959084810043220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17039171757821442029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17707872611568165011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "path-reverse_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4594497434690420731
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patheffect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12000354906642530911
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patheffect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13136038454993854220
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patheffect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8347851619159734706
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patheffect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9352969135236811083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "patheffect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5415179396675387208
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pathfill_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9913956212375399295
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathfill_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12306117555345084962
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathfill_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17931803287102431107
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathfill_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4498024042829372500
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathfill_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9028424578854512276
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pathinterior_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3396766038203432666
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinterior_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12110360517026697498
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinterior_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17479758826656648496
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinterior_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1151605755804748972
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinterior_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17388654056447984491
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8654831421971241050
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11144284047498640984
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3520993708181297768
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7090035026515398892
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathinvfill_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13350177784367266818
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pathopsinverse_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17617505767021323437
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsinverse_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11577432472710705185
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsinverse_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3181704756887945687
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsinverse_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5591146566217797280
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsinverse_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11025506788242552694
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6154660184356174115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4313744187563601995
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5677908987773616373
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11460675912619342328
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pathopsskpclip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11157237442918763566
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "peekpixels_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2758866006531517960
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "peekpixels_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5344748376042459393
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "peekpixels_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2117041505467664585
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "peekpixels_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9264992068618239238
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "peekpixels_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17077044380877012193
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1539561209878927288
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14413015027460366330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6945090583139588959
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6945090583139588959
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "perlinnoise_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6945090583139588959
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14801725520513922963
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12098491632750651220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12098491632750651220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12098491632750651220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15493927584984335902
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5787037840005040154
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15428032280989033057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1925902024016434685
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3298829096497099492
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshader_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13288790000507495232
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8567194488499472739
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8567194488499472739
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7449362905694021309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1704644220614711688
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "points_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14262258178388208669
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15752228483716340184
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9600712706940307510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18273026657594929057
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18345234563841023550
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "poly2poly_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6795673127289875978
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "polygons_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7471239721499308199
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "polygons_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          961606689700631635
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "polygons_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3344969070850904263
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "polygons_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5468058878210139138
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "polygons_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9887825123733570563
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313537653075020359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15540539959703820843
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1528621230156781313
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6418169567469353560
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadclosepath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15207535740869213581
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17750273719514230908
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12968426991611677795
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16287167623514876790
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14883147621745392045
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "quadpath_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13719367263412668706
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "radial_gradient2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2509551852078940571
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4012506323387989153
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18105030510199748233
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          616895105520984452
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11600744039926164744
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "radial_gradient_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10067107685325019703
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15369886492036014971
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14941464582660867910
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          227457349309358061
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "radial_gradient_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14941464582660867910
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8867175365182256822
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11221280940369658912
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11339980900210544915
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6239879080037398278
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4010833721373542094
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "resizeimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11574452324482789141
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "resizeimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004076002839832883
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "resizeimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16941137351142187530
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "resizeimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5168536017395085399
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "resizeimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18403762395924531087
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "roundrects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17752420136993868343
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "roundrects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1161927000752559561
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "roundrects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1105214242516896399
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "roundrects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10172086750392023029
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "roundrects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4051216113582839289
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9108911139001347487
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14795654963615468231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14635716521372290944
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8853776977311383548
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18168424126789500571
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3055968029040102617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4013957681165008981
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_clip_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5677622882171244043
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16102744790083806869
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8388919664468878536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3055968029040102617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_clip_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4013957681165008981
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_draw_aa_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14635716521372290944
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_aa_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8853776977311383548
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_aa_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14953639362807460202
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_aa_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3055968029040102617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_aa_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4013957681165008981
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_draw_bw_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5677622882171244043
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_bw_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16102744790083806869
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_bw_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8388919664468878536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_bw_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3055968029040102617
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_draw_bw_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4013957681165008981
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "rrect_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4300907509754823851
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10791384680520892994
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4300907509754823851
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4689261115608866447
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9700284503645872210
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "rrect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10204288420390896965
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "scaled_tilemode_bitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16202156323496453186
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_bitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18320695188397156612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_bitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          291294819063810031
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_bitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9284152842222597272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_bitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7031568369867707114
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5540007979619091451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3908941454591681450
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2333961629735595646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9628133036798734492
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemode_gradient_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12967756622957744836
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13114664408316434199
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17620727745163451077
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7099532709538059803
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13634813695671871778
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8932592043722071881
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2717765448488008751
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2988734578790256008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10979969633399782871
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_npot_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15444592364779646619
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8102298704200698886
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "selftest1_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12927999507540085554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest1_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1209453360120438698
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest1_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1149339852105949057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest1_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1149339852105949057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest1_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1149339852105949057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8863920166200910451
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13451349865803053525
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7903070799454133570
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7903070799454133570
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "selftest2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7903070799454133570
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4739835670329472924
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17407206349726255504
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2509331043182251203
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8879550809322519694
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shaderbounds_linear_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11320774917639038133
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10804395662064163067
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11973828271981934898
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16065988395535735595
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10158714776567287562
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shadows_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15113208936007369755
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "shallow_gradient_conical_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17982294224537325140
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_conical_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10213220249745462631
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_conical_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          103053982990746762
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_conical_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1305496964728839535
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_conical_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          103053982990746762
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2414118852281882343
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2600596201303470577
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16719793849261907536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16719793849261907536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_linear_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16719793849261907536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3573223055541654414
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1965999637836338391
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10939736148238347507
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15635279764260732794
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_radial_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10939736148238347507
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6974552498637279685
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          766715199662180977
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          505316756506251280
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15070177880693766645
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "shallow_gradient_sweep_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          505316756506251280
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleaaclip_aaclip_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2716635983736130572
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_aaclip_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6323185425935976578
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_aaclip_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14792628545823171531
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_aaclip_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6437416978571967965
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_aaclip_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          158361826253799606
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2716635983736130572
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1684803956798529676
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7776449119510647616
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          132852148809063331
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_path_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16759061850730950379
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7856938689333642802
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3392443767163314236
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6118609150423265769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10359254455982955934
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleaaclip_rect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2100931586089555889
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "simpleblurroundrect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12397550977213308037
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleblurroundrect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5652577089689509120
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleblurroundrect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3196650548285977166
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleblurroundrect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11504299822100144685
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "simpleblurroundrect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4323854140016112056
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "skbug1719_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2332391077132553330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "skbug1719_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13212045663266308489
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "skbug1719_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6846687859627369127
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "skbug1719_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4851170883353423359
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "skbug1719_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1075111322101840115
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "spritebitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13563811160364567248
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "spritebitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          227198932212139294
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "spritebitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1647638141282055974
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "spritebitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1647638141282055974
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "spritebitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1647638141282055974
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "srcmode_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7716668905830605416
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "srcmode_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6635637522868788156
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "srcmode_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15751900135813748883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "srcmode_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2022832707658358979
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "srcmode_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3143492941196749873
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stringart_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          517466260915157438
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stringart_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12919217765216356865
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stringart_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3407765471622235987
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stringart_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10146871010021812623
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stringart_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5208896917206754825
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "stroke-fill_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9267212173575576732
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroke-fill_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12391135340682188523
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroke-fill_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6113074317698019955
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroke-fill_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17210831440928667457
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroke-fill_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1252486262030484135
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15458182862530229195
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2467605443292336055
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1648852024813032692
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9666123301505523830
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4717987710581110780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1252564837192523211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3590050428307921218
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6336266129240777095
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4337570176483288507
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokerects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9133559894067712940
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12878931714876978005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9947658613138732028
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7534646549465423253
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2353456527456632046
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes3_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10287743286276150382
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16910787505800458486
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7757836920339953940
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8825634154909138815
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9989688846254434850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_poly_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2243202409153973536
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "strokes_round_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8830084223721413158
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_round_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14762739513429490065
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_round_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18208182831453388386
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_round_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10553904208497015722
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "strokes_round_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11128748943191707337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18338291332088684335
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11544127214212088947
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6057347291556151985
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10848626204179922135
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "stroketext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13981050594918231661
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6155339908971373908
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5497460981955702016
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17720341081172525928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17720341081172525928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tablecolorfilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17720341081172525928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10876942606580879984
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6913857649673524662
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5115665870392462534
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5714371734871865975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "testimagefilters_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15671347724433934993
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texdata_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2736593828543197285
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texdata_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2736593828543197285
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texdata_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2736593828543197285
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          163112871246100159
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8796565274520104554
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16312476967739707580
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texteffects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17000480734115531314
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texteffects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15806412237117346050
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texteffects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17515591586084571256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texteffects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17515591586084571256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texteffects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17515591586084571256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "texture_domain_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17099586086831668928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texture_domain_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5351853408178981372
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "texture_domain_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7646850408534888075
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17949451347125150629
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12074631820414627784
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17501446579955337831
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3967170325391392383
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinrects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3979007074061355265
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17882028260402842392
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2596255945580270876
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14626919895309756138
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5543949501668688147
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "thinstrokedrects_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5158860798933444596
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tileimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2893625561624793005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tileimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4046978300889376789
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tileimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4046978300889376789
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tileimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4046978300889376789
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tileimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4046978300889376789
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16202156323496453186
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18320695188397156612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          291294819063810031
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9284152842222597272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_bitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7031568369867707114
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5540007979619091451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3908941454591681450
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2333961629735595646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9628133036798734492
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemode_gradient_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12967756622957744836
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13107047343822691410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17656517732103593482
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1460100162088232495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13345565835934825527
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1016379573268994349
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13721934356222709475
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2703226654627094494
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5786648404634357546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_npot_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17966057434048971014
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8039290250803630632
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "tinybitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12538857845722393084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tinybitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11468465429225805
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tinybitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5633315905476176630
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tinybitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5633315905476176630
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "tinybitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5633315905476176630
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "twopointconical_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8813543224253503623
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "twopointconical_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10487196951809200447
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "twopointconical_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2024124685080721188
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "twopointconical_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          156310787923265214
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "twopointconical_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12294271572612285815
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7630443482944449324
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          541791446919644762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          541791446919644762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          541791446919644762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typeface_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8102001591139534628
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5782656429071871585
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093615056685804062
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093615056685804062
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7242130339475265377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9946363327226628317
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18074462901923174459
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18074462901923174459
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_kerning_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14302855136061508597
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9093615056685804062
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10003362713791489293
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7205684210809830268
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13789324379573341403
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7963837640830480163
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3663362132010737168
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7457535226975143406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7205684210809830268
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13789324379573341403
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7963837640830480163
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3663362132010737168
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7457535226975143406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17631782564810163297
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2817472816787253027
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15856387179055100718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7062959562720776972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13842064697956814589
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17631782564810163297
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2817472816787253027
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15856387179055100718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7062959562720776972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13842064697956814589
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "vertices_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6092447564586372262
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15543035394331574799
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7054083838010162546
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1238935355949663480
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10433092584712962295
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_80_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1124242406804705805
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14737572076836658261
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16119691045778726906
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8469012837534615666
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "vertices_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10724574345208314013
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "verttext2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11345248105896220068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9273698158417602516
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12923080987897144985
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3215791117169189388
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2405294955146628811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5372075096677220148
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6104627350528703861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          104419481998564261
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4674076918445194225
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12704247657614646796
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9169362964428595499
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8036801967395272185
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17451382664837991053
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17451382664837991053
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodeimagefilter_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17451382664837991053
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3669258016173734776
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11711243112888067446
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12389511830554214503
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14411744652289973264
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1143772492254209525
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17424339298588817189
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4115706103934190223
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9701350788577476400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13266604257445564827
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes3_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12305758378054318125
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16726470973503710769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          931382594145774191
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17289770589494488729
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8998690330665917593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "xfermodes_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17997093412787453516
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": true
+    }
+  }
+}
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-Xoom-Tegra2-Arm7-Debug/expected-results.json b/expectations/gm/Test-Android-Xoom-Tegra2-Arm7-Debug/expected-results.json
index 1c2deac..c6fc637 100644
--- a/expectations/gm/Test-Android-Xoom-Tegra2-Arm7-Debug/expected-results.json
+++ b/expectations/gm/Test-Android-Xoom-Tegra2-Arm7-Debug/expected-results.json
@@ -93,10 +93,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15592284536634451280
+          2903367112932605463
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -228,7 +229,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          652103505066540991
+          2710382194894587269
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -272,39 +300,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2270603732178876438
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
@@ -327,10 +322,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12098157465203303789
+          10972939966027239488
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -435,7 +430,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1363231849466414445
+          5402695108674598933
         ]
       ], 
       "reviewed-by-human": true
@@ -444,7 +439,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16537885423072386302
+          16466362226127156448
         ]
       ], 
       "reviewed-by-human": true
@@ -453,7 +448,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12259914099693836701
+          5947835383588192459
         ]
       ], 
       "reviewed-by-human": true
@@ -673,10 +668,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12738906014496179860
+          5370958088737789129
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
@@ -733,7 +731,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16186598678776995408
+          1176222842118078025
         ]
       ], 
       "reviewed-by-human": true
@@ -1728,6 +1726,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14473518652319975040
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -2002,7 +2027,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12486595519840703485
+          15477254742759075309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18251991733853007362
         ]
       ], 
       "reviewed-by-human": false
@@ -2263,7 +2315,8 @@
           8609345557630302846
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "clipped-bitmap-shaders-clamp-hq_565.png": {
       "allowed-digests": [
@@ -2807,7 +2860,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18124781305265667336
+          563207381090352008
         ]
       ], 
       "reviewed-by-human": true
@@ -2816,7 +2869,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12559465164864479162
+          17092054436660282529
         ]
       ], 
       "reviewed-by-human": true
@@ -2825,7 +2878,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16064663276594096777
+          12913703232089787440
         ]
       ], 
       "reviewed-by-human": true
@@ -2834,7 +2887,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1064237583460814939
+          9240871388945807325
         ]
       ], 
       "reviewed-by-human": true
@@ -2843,7 +2896,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13591877655871515458
+          6166183189201099571
         ]
       ], 
       "reviewed-by-human": true
@@ -2852,7 +2905,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12495592009351799445
+          113947972487099583
         ]
       ], 
       "reviewed-by-human": true
@@ -2861,7 +2914,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5330578238506301560
+          4355652678835588931
         ]
       ], 
       "reviewed-by-human": true
@@ -2870,7 +2923,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2511666966287866166
+          2733201198429145442
         ]
       ], 
       "reviewed-by-human": true
@@ -2879,7 +2932,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5994511022330203150
+          5243670499244708257
         ]
       ], 
       "reviewed-by-human": true
@@ -2888,7 +2941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17159080850865344792
+          954351366070381450
         ]
       ], 
       "reviewed-by-human": true
@@ -2897,7 +2950,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2302717591157402628
+          9210178579115499419
         ]
       ], 
       "reviewed-by-human": true
@@ -2906,7 +2959,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5757739631109868852
+          13749889605633074996
         ]
       ], 
       "reviewed-by-human": true
@@ -2969,28 +3022,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3742871756784050961
+          15926573056550878185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14394590208816375119
+          4158201481429178795
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8622209163480504063
+          12656296645578933840
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -3068,7 +3121,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13521200955406107775
+          18170924992776935225
         ]
       ], 
       "reviewed-by-human": true
@@ -3077,7 +3130,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17912401236231679127
+          15743894196129681683
         ]
       ], 
       "reviewed-by-human": true
@@ -3086,7 +3139,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7820182512312513013
+          7113400801147544530
         ]
       ], 
       "reviewed-by-human": true
@@ -3095,7 +3148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6583472814997240235
+          9707939494112550600
         ]
       ], 
       "reviewed-by-human": true
@@ -3104,7 +3157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058335517377211817
+          5570027336852511465
         ]
       ], 
       "reviewed-by-human": true
@@ -3113,7 +3166,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18070415739788425864
+          3049744144841095386
         ]
       ], 
       "reviewed-by-human": true
@@ -3221,7 +3274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          562361837559055355
+          2623304109209673201
         ]
       ], 
       "reviewed-by-human": true
@@ -3263,7 +3316,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15818466451697206030
+          1558433439357463328
         ]
       ], 
       "reviewed-by-human": true
@@ -3272,7 +3325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11122804881221782538
+          5022030446032169064
         ]
       ], 
       "reviewed-by-human": true
@@ -3281,7 +3334,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          87698442851034644
+          5233170840864135621
         ]
       ], 
       "reviewed-by-human": true
@@ -3319,7 +3372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10557537838778749160
+          12185342896868259586
         ]
       ], 
       "ignore-failure": false, 
@@ -3329,7 +3382,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7089896533323038526
+          14869624664666518810
         ]
       ], 
       "ignore-failure": false, 
@@ -3339,7 +3392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2196029228819590195
+          13311037442753260633
         ]
       ], 
       "ignore-failure": false, 
@@ -3349,43 +3402,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -3394,7 +3438,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -3403,7 +3447,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
       "reviewed-by-human": true
@@ -3412,67 +3456,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
       "reviewed-by-human": true
@@ -3481,43 +3510,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7291613642918106073
+          1557116782665821961
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8174026154893573789
+          10644646464255634876
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2410384022323180262
+          8136862497622595689
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -3526,7 +3546,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -3535,7 +3555,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
       "reviewed-by-human": true
@@ -3544,67 +3564,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
       "reviewed-by-human": true
@@ -3613,43 +3618,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15018591777914911277
+          2490903614933092965
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4969033013118250897
+          3966309174829559531
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11818903631048803455
+          9781042422538097277
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -3658,7 +3654,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181838889584580159
         ]
       ], 
       "reviewed-by-human": true
@@ -3667,7 +3672,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          9700449137961279890
         ]
       ], 
       "reviewed-by-human": true
@@ -3676,7 +3681,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          11779869739935637171
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8820398513653894612
         ]
       ], 
       "reviewed-by-human": true
@@ -3685,7 +3699,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -3694,7 +3708,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8820398513653894612
         ]
       ], 
       "reviewed-by-human": true
@@ -3703,7 +3726,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          2507541198623560707
         ]
       ], 
       "reviewed-by-human": true
@@ -3712,7 +3735,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          807228199936042550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4277401128811031135
         ]
       ], 
       "reviewed-by-human": true
@@ -3721,10 +3753,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11845984825122755781
+          13062574079309331603
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -3739,16 +3772,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2931946104892198077
+          4473589478120711048
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16880886031490071742
+          4714004310352992111
         ]
       ], 
       "reviewed-by-human": true
@@ -3757,7 +3791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          428119157032316167
+          17158122750214958555
         ]
       ], 
       "reviewed-by-human": true
@@ -3766,7 +3800,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6272755490524033601
+          4525040456215730772
         ]
       ], 
       "reviewed-by-human": true
@@ -3775,7 +3809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7416446637660374210
+          1749131430740318779
         ]
       ], 
       "reviewed-by-human": true
@@ -3784,7 +3818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13313875175804070508
+          12553201495837952118
         ]
       ], 
       "reviewed-by-human": true
@@ -3793,7 +3827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4286126979002176463
+          9747536968620326358
         ]
       ], 
       "reviewed-by-human": true
@@ -3829,7 +3863,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18094470146972105480
+          12661336325625617644
         ]
       ], 
       "reviewed-by-human": true
@@ -3838,7 +3872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16729138449439522348
+          2100485553427956358
         ]
       ], 
       "reviewed-by-human": true
@@ -3847,7 +3881,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          773867758980201814
+          9435645443799817571
         ]
       ], 
       "reviewed-by-human": true
@@ -3960,6 +3994,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -4118,7 +4179,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -4127,7 +4188,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -4145,7 +4206,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8577320746364246324
+          17901413475889955182
         ]
       ], 
       "reviewed-by-human": true
@@ -4154,7 +4215,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6301307169172356565
+          15655962568887109300
         ]
       ], 
       "reviewed-by-human": true
@@ -4172,7 +4233,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15194393119626941638
+          2025817326132268044
         ]
       ], 
       "reviewed-by-human": true
@@ -4181,7 +4242,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18024624917912577304
+          4498759410061841062
         ]
       ], 
       "reviewed-by-human": true
@@ -4199,7 +4260,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16878465395422523550
+          12791906531913394489
         ]
       ], 
       "reviewed-by-human": true
@@ -4208,7 +4269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13162576846071114657
+          7053460792550818176
         ]
       ], 
       "reviewed-by-human": true
@@ -4226,7 +4287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16230885768543124448
+          15924108274958577762
         ]
       ], 
       "reviewed-by-human": true
@@ -4235,7 +4296,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6797057477759131840
+          17768838851047792154
         ]
       ], 
       "reviewed-by-human": true
@@ -4253,7 +4314,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8846430944908901166
+          2471052076010128346
         ]
       ], 
       "reviewed-by-human": true
@@ -4262,7 +4323,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11911675832026192391
+          6090155424035379572
         ]
       ], 
       "reviewed-by-human": true
@@ -4280,7 +4341,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237759626563291567
+          4336016262533487701
         ]
       ], 
       "reviewed-by-human": true
@@ -4289,7 +4350,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8732622580114980787
+          9142174592881097490
         ]
       ], 
       "reviewed-by-human": true
@@ -4307,7 +4368,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17156163502530286228
+          15960009663661689458
         ]
       ], 
       "reviewed-by-human": true
@@ -4316,7 +4377,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13898311729224982406
+          9758610231644803186
         ]
       ], 
       "reviewed-by-human": true
@@ -4334,7 +4395,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8088349932016019412
+          3976985443811942783
         ]
       ], 
       "reviewed-by-human": true
@@ -4343,7 +4404,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16152681108877952354
+          6917722507436446345
         ]
       ], 
       "reviewed-by-human": true
@@ -4388,7 +4449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6659537104690458991
+          8438084710543507198
         ]
       ], 
       "reviewed-by-human": true
@@ -4397,7 +4458,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14777277832097178014
+          17977715539560943749
         ]
       ], 
       "reviewed-by-human": true
@@ -4442,7 +4503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15534699152944221402
+          17230662924303836725
         ]
       ], 
       "reviewed-by-human": true
@@ -4451,7 +4512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9842142403939335300
+          9212565008999202179
         ]
       ], 
       "reviewed-by-human": true
@@ -4469,7 +4530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11953445213035982682
+          15675965195423663386
         ]
       ], 
       "reviewed-by-human": true
@@ -4478,7 +4539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18356463429915079552
+          4460192903137624324
         ]
       ], 
       "reviewed-by-human": true
@@ -4492,6 +4553,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18400047645694418480
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -4505,72 +4593,54 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1821325695757397620
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13605807214433697
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13605807214433697
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          6708763127627046893
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13271159159658735588
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13271159159658735588
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
@@ -4603,11 +4673,38 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10215574519029554698
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12061292170759771468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          964478338131907768
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11098600005518612422
+          8160621906382172772
         ]
       ], 
       "ignore-failure": false, 
@@ -4617,7 +4714,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12924368150056635888
+          3638984878878580889
         ]
       ], 
       "ignore-failure": false, 
@@ -4627,7 +4724,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1248385260413008534
+          6985401488806315560
         ]
       ], 
       "ignore-failure": false, 
@@ -4984,6 +5081,222 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2542842552177748878
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14451045898461494763
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10878364517039000997
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14024409341192570213
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11926541870165436762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14024409341192570213
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11926541870165436762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8640054562370462165
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1619379911426141072
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079712827936605791
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8322189768762361893
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14690527047657142551
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13982751467199249854
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14024409341192570213
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11926541870165436762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16269982327662298279
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13816591426241372835
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10210969919713266978
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6701875488092960282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3660765690515931744
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          483347305491602167
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -5015,10 +5328,7 @@
           14015662146260093838
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_matrix_565.png": {
       "allowed-digests": [
@@ -5081,7 +5391,7 @@
           3493263944278727556
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_565.png": {
       "allowed-digests": [
@@ -5108,7 +5418,7 @@
           15451235578409962625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_565.png": {
       "allowed-digests": [
@@ -5135,7 +5445,7 @@
           10135349930059020946
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_565.png": {
       "allowed-digests": [
@@ -5282,7 +5592,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "ignore-failure": false, 
@@ -5312,7 +5622,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297095911910169239
+          9805842470726753368
         ]
       ], 
       "reviewed-by-human": true
@@ -5390,10 +5700,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8439292883038599650
+          17075103240901787870
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -5485,11 +5796,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12464380758342201484
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1246800919397645188
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6243034097773735184
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14035574113753451382
+          11106328037616688411
         ]
       ], 
       "ignore-failure": false, 
@@ -5499,7 +5837,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15210866016398022120
+          15644130602377025892
         ]
       ], 
       "ignore-failure": false, 
@@ -5509,7 +5847,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          603695485072907856
+          7619477096231926311
         ]
       ], 
       "ignore-failure": false, 
@@ -5519,7 +5857,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10777355457185638337
+          12586841244820131235
         ]
       ], 
       "reviewed-by-human": true
@@ -5528,7 +5866,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071282510990956080
+          17873119728038419105
         ]
       ], 
       "reviewed-by-human": true
@@ -5537,7 +5875,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8795346686869088146
+          344246998918338983
         ]
       ], 
       "reviewed-by-human": true
@@ -5573,7 +5911,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10444748308763470034
+          12784893736395190326
         ]
       ], 
       "ignore-failure": false, 
@@ -5583,7 +5921,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966045235333891041
+          10029023872252369111
         ]
       ], 
       "ignore-failure": false, 
@@ -5593,7 +5931,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16871273291364293800
+          12569676270494334123
         ]
       ], 
       "ignore-failure": false, 
@@ -5619,7 +5957,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7083256779583570909
+          9179365879237426214
         ]
       ], 
       "reviewed-by-human": true
@@ -5628,7 +5966,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6884363144513814401
+          13878008363115233918
         ]
       ], 
       "reviewed-by-human": true
@@ -5637,7 +5975,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14804607715615711480
+          638319242050328704
         ]
       ], 
       "reviewed-by-human": true
@@ -5646,7 +5984,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14847356829373202930
+          18237646684385467588
         ]
       ], 
       "reviewed-by-human": true
@@ -5685,23 +6023,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8686840007074574670
+          6884063645048513632
         ]
       ], 
       "reviewed-by-human": true
@@ -5710,7 +6050,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14625944923053341670
+          14117400437006921516
         ]
       ], 
       "reviewed-by-human": true
@@ -5719,7 +6059,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1901521361109987395
+          14816015368674233714
         ]
       ], 
       "reviewed-by-human": true
@@ -5728,7 +6068,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7982720251199582723
+          8798527610830880143
         ]
       ], 
       "reviewed-by-human": true
@@ -5869,13 +6209,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8033413492174781528
+          14104477372457343571
         ]
       ], 
       "bugs": [
         1759
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
@@ -5935,7 +6275,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564246142489134519
+          12034621044014828739
         ]
       ], 
       "reviewed-by-human": true
@@ -5944,7 +6284,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1370520776657521517
+          17212900163667680667
         ]
       ], 
       "reviewed-by-human": true
@@ -5953,7 +6293,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15956062266281295116
+          1995926033333720658
         ]
       ], 
       "reviewed-by-human": true
@@ -5962,7 +6302,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981696952434326875
+          10205549632922849523
         ]
       ], 
       "reviewed-by-human": true
@@ -5971,7 +6311,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15238792371190456534
+          5122071235510816862
         ]
       ], 
       "reviewed-by-human": true
@@ -5980,7 +6320,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18193617695367577901
+          17196821659743114733
         ]
       ], 
       "reviewed-by-human": true
@@ -6005,15 +6345,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10386492654531940245
+          9170387744192116888
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3101476576521947165
+          6352977614463860995
         ]
       ], 
       "reviewed-by-human": true
@@ -6022,7 +6363,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10055081768235896808
+          16055003435471712082
         ]
       ], 
       "reviewed-by-human": true
@@ -6031,7 +6372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2603077871826545278
+          12577732892225437166
         ]
       ], 
       "reviewed-by-human": true
@@ -6091,7 +6432,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6124,7 +6465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6157,7 +6498,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6217,13 +6558,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1392431913011031709
+          9537223841629940172
         ]
       ], 
       "bugs": [
         1759
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
@@ -6252,6 +6593,276 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12026275426271527150
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6958579088836506224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2297483525893474810
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18100843957901826201
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4478490979400536378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16204222930251940046
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16721089005631938371
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9760231745798245964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5749308152293375604
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662786566822056022
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -6409,7 +7020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15240835456320409473
+          2417541102915221087
         ]
       ], 
       "reviewed-by-human": true
@@ -6418,7 +7029,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          249289862803617115
+          4496194756153902794
         ]
       ], 
       "reviewed-by-human": true
@@ -6427,7 +7038,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17818108684129139098
+          4154305136980930847
         ]
       ], 
       "reviewed-by-human": true
@@ -6460,13 +7071,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          2379796454057556376
         ]
       ], 
       "bugs": [
         1759
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -6495,6 +7106,60 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14923802744175220714
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17286230013131859770
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -6604,7 +7269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10076388000940146533
+          1682572932242995816
         ]
       ], 
       "bugs": [
@@ -6740,7 +7405,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -6749,7 +7414,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -6758,11 +7423,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6943431591101726407
+          8237755924122347050
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9531551378023358784
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -6790,6 +7482,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4509758055939626468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -6817,6 +7536,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -6849,7 +7595,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6571118611946058617
+          17983017435379030888
         ]
       ], 
       "reviewed-by-human": true
@@ -6858,7 +7604,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2985268228390879272
+          14038652322622145328
         ]
       ], 
       "reviewed-by-human": true
@@ -6867,7 +7613,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16168905822423961360
+          7780142035003324778
         ]
       ], 
       "reviewed-by-human": true
@@ -6903,7 +7649,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17243480259296502336
+          8491037037204301331
         ]
       ], 
       "reviewed-by-human": true
@@ -6912,7 +7658,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6891379388563692035
+          16113419322232484853
         ]
       ], 
       "reviewed-by-human": true
@@ -6921,7 +7667,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3493526150687710271
+          18200832368629027021
         ]
       ], 
       "reviewed-by-human": true
@@ -6930,7 +7676,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6963865127519492895
+          13158779623131982179
         ]
       ], 
       "reviewed-by-human": true
@@ -6939,7 +7685,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7223243377781866680
+          12925825870714067916
         ]
       ], 
       "reviewed-by-human": true
@@ -6948,7 +7694,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11938277717739874979
+          11423134871343942431
         ]
       ], 
       "reviewed-by-human": true
@@ -7011,10 +7757,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199326463862210265
+          16390092508393346144
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -7318,12 +8065,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2127407127834363551
+          7623093636828792551
         ]
       ], 
-      "bugs": [
-        1838
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -7403,7 +8147,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10172121282900547958
+          12022539994697419041
         ]
       ], 
       "reviewed-by-human": true
@@ -7430,7 +8174,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3998266583888463598
+          8293817049980287910
         ]
       ], 
       "reviewed-by-human": true
@@ -7874,7 +8618,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17619211944443238901
+          10211393238987918705
         ]
       ], 
       "reviewed-by-human": true
@@ -7883,7 +8627,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476337759406055776
+          5070879619906521041
         ]
       ], 
       "reviewed-by-human": true
@@ -7892,7 +8636,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6669667580550234931
+          13798375824850427074
         ]
       ], 
       "reviewed-by-human": true
@@ -8099,7 +8843,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7085130049375511832
+          11055155137550620869
         ]
       ], 
       "reviewed-by-human": true
@@ -8108,7 +8852,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15846255821264969272
+          16800018700019366772
         ]
       ], 
       "reviewed-by-human": true
@@ -8117,7 +8861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10510375443381640752
+          18205738113783069124
         ]
       ], 
       "reviewed-by-human": true
@@ -8203,6 +8947,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17484439610611592723
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          374437982401021225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -8234,10 +9005,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16780536364041129122
+          758934049590219880
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -8264,7 +9035,8 @@
           15858307657519327001
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_565.png": {
       "allowed-digests": [
@@ -8297,16 +9069,13 @@
           12367524911555205763
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15884441815359625883
+          15191409507212695130
         ]
       ], 
       "reviewed-by-human": true
@@ -8315,7 +9084,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          11411832946137461218
         ]
       ], 
       "reviewed-by-human": true
@@ -8324,7 +9093,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          11411832946137461218
         ]
       ], 
       "reviewed-by-human": true
@@ -8405,7 +9174,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15663350675863222117
+          7526371396718664611
         ]
       ], 
       "reviewed-by-human": true
@@ -8432,7 +9201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18099831386641683703
+          9912155885325751678
         ]
       ], 
       "reviewed-by-human": true
@@ -8572,6 +9341,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17056303258237391595
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1779290589524924521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3856303282484892427
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17056303258237391595
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1779290589524924521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3856303282484892427
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17426798752912810170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7850745143997123083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13581485591687976567
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17426798752912810170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7850745143997123083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13581485591687976567
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -8684,7 +9561,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10958353996143090911
+          17760244815865706025
         ]
       ], 
       "reviewed-by-human": true
@@ -8693,7 +9570,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17000878545702467803
+          2770675093666585013
         ]
       ], 
       "reviewed-by-human": true
@@ -8702,7 +9579,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1557616897383013085
+          15972717687977180040
         ]
       ], 
       "reviewed-by-human": true
@@ -8729,7 +9606,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16806594850934938489
+          11056040080954093657
         ]
       ], 
       "reviewed-by-human": true
@@ -8756,7 +9633,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17085212712405221649
+          5483074157359624611
         ]
       ], 
       "reviewed-by-human": true
@@ -8783,10 +9660,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12025936981544886506
+          10082620380128469910
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6719196348100419960
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-Xoom-Tegra2-Arm7-Release/expected-results.json b/expectations/gm/Test-Android-Xoom-Tegra2-Arm7-Release/expected-results.json
index e47cea0..115e031 100644
--- a/expectations/gm/Test-Android-Xoom-Tegra2-Arm7-Release/expected-results.json
+++ b/expectations/gm/Test-Android-Xoom-Tegra2-Arm7-Release/expected-results.json
@@ -93,10 +93,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15592284536634451280
+          2903367112932605463
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "alphagradients_565.png": {
       "allowed-digests": [
@@ -228,7 +229,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          652103505066540991
+          2710382194894587269
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -272,39 +300,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2270603732178876438
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "bigblurs_565.png": {
       "allowed-digests": [
         [
@@ -327,10 +322,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12098157465203303789
+          10972939966027239488
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -435,7 +430,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1363231849466414445
+          5402695108674598933
         ]
       ], 
       "reviewed-by-human": true
@@ -444,7 +439,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16537885423072386302
+          16466362226127156448
         ]
       ], 
       "reviewed-by-human": true
@@ -453,7 +448,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12259914099693836701
+          5947835383588192459
         ]
       ], 
       "reviewed-by-human": true
@@ -673,10 +668,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12738906014496179860
+          5370958088737789129
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
@@ -733,7 +731,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16186598678776995408
+          1176222842118078025
         ]
       ], 
       "reviewed-by-human": true
@@ -1728,6 +1726,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14473518652319975040
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -2002,7 +2027,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12486595519840703485
+          15477254742759075309
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18251991733853007362
         ]
       ], 
       "reviewed-by-human": false
@@ -2263,7 +2315,8 @@
           8609345557630302846
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "clipped-bitmap-shaders-clamp-hq_565.png": {
       "allowed-digests": [
@@ -2807,7 +2860,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18124781305265667336
+          563207381090352008
         ]
       ], 
       "reviewed-by-human": true
@@ -2816,7 +2869,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12559465164864479162
+          17092054436660282529
         ]
       ], 
       "reviewed-by-human": true
@@ -2825,7 +2878,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16064663276594096777
+          12913703232089787440
         ]
       ], 
       "reviewed-by-human": true
@@ -2834,7 +2887,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1064237583460814939
+          9240871388945807325
         ]
       ], 
       "reviewed-by-human": true
@@ -2843,7 +2896,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13591877655871515458
+          6166183189201099571
         ]
       ], 
       "reviewed-by-human": true
@@ -2852,7 +2905,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12495592009351799445
+          113947972487099583
         ]
       ], 
       "reviewed-by-human": true
@@ -2861,7 +2914,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5330578238506301560
+          4355652678835588931
         ]
       ], 
       "reviewed-by-human": true
@@ -2870,7 +2923,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2511666966287866166
+          2733201198429145442
         ]
       ], 
       "reviewed-by-human": true
@@ -2879,7 +2932,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5994511022330203150
+          5243670499244708257
         ]
       ], 
       "reviewed-by-human": true
@@ -2888,7 +2941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17159080850865344792
+          954351366070381450
         ]
       ], 
       "reviewed-by-human": true
@@ -2897,7 +2950,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2302717591157402628
+          9210178579115499419
         ]
       ], 
       "reviewed-by-human": true
@@ -2906,7 +2959,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5757739631109868852
+          13749889605633074996
         ]
       ], 
       "reviewed-by-human": true
@@ -2969,28 +3022,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3742871756784050961
+          15926573056550878185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14394590208816375119
+          4158201481429178795
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8622209163480504063
+          12656296645578933840
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -3068,7 +3121,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13521200955406107775
+          18170924992776935225
         ]
       ], 
       "reviewed-by-human": true
@@ -3077,7 +3130,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17912401236231679127
+          15743894196129681683
         ]
       ], 
       "reviewed-by-human": true
@@ -3086,7 +3139,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7820182512312513013
+          7113400801147544530
         ]
       ], 
       "reviewed-by-human": true
@@ -3095,7 +3148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6583472814997240235
+          9707939494112550600
         ]
       ], 
       "reviewed-by-human": true
@@ -3104,7 +3157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058335517377211817
+          5570027336852511465
         ]
       ], 
       "reviewed-by-human": true
@@ -3113,7 +3166,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18070415739788425864
+          3049744144841095386
         ]
       ], 
       "reviewed-by-human": true
@@ -3221,7 +3274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          562361837559055355
+          2623304109209673201
         ]
       ], 
       "reviewed-by-human": true
@@ -3263,7 +3316,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15818466451697206030
+          1558433439357463328
         ]
       ], 
       "reviewed-by-human": true
@@ -3272,7 +3325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11122804881221782538
+          5022030446032169064
         ]
       ], 
       "reviewed-by-human": true
@@ -3281,7 +3334,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          87698442851034644
+          5233170840864135621
         ]
       ], 
       "reviewed-by-human": true
@@ -3319,7 +3372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10557537838778749160
+          12185342896868259586
         ]
       ], 
       "ignore-failure": false, 
@@ -3329,7 +3382,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7089896533323038526
+          14869624664666518810
         ]
       ], 
       "ignore-failure": false, 
@@ -3339,7 +3392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2196029228819590195
+          13311037442753260633
         ]
       ], 
       "ignore-failure": false, 
@@ -3349,43 +3402,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -3394,7 +3438,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -3403,7 +3447,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
       "reviewed-by-human": true
@@ -3412,67 +3456,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10440183167364399689
+          10185443326596583225
         ]
       ], 
       "reviewed-by-human": true
@@ -3481,43 +3510,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7291613642918106073
+          1557116782665821961
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8174026154893573789
+          10644646464255634876
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2410384022323180262
+          8136862497622595689
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -3526,7 +3546,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -3535,7 +3555,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
       "reviewed-by-human": true
@@ -3544,67 +3564,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12594265632012724270
+          12165025014092448821
         ]
       ], 
       "reviewed-by-human": true
@@ -3613,43 +3618,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15018591777914911277
+          2490903614933092965
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4969033013118250897
+          3966309174829559531
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11818903631048803455
+          9781042422538097277
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          4946691776839943214
         ]
       ], 
       "reviewed-by-human": true
@@ -3658,7 +3654,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          10974664895754668656
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_high_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181838889584580159
         ]
       ], 
       "reviewed-by-human": true
@@ -3667,7 +3672,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          9700449137961279890
         ]
       ], 
       "reviewed-by-human": true
@@ -3676,7 +3681,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          11779869739935637171
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_low_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8820398513653894612
         ]
       ], 
       "reviewed-by-human": true
@@ -3685,7 +3699,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          15586391272068523346
         ]
       ], 
       "reviewed-by-human": true
@@ -3694,7 +3708,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          688606398961769278
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_medium_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8820398513653894612
         ]
       ], 
       "reviewed-by-human": true
@@ -3703,7 +3726,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10237388909415541908
+          2507541198623560707
         ]
       ], 
       "reviewed-by-human": true
@@ -3712,7 +3735,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2858581709660741041
+          807228199936042550
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "downsamplebitmap_text_none_72.00pt_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4277401128811031135
         ]
       ], 
       "reviewed-by-human": true
@@ -3721,10 +3753,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11845984825122755781
+          13062574079309331603
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -3739,16 +3772,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2931946104892198077
+          4473589478120711048
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16880886031490071742
+          4714004310352992111
         ]
       ], 
       "reviewed-by-human": true
@@ -3757,7 +3791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          428119157032316167
+          17158122750214958555
         ]
       ], 
       "reviewed-by-human": true
@@ -3766,7 +3800,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6272755490524033601
+          4525040456215730772
         ]
       ], 
       "reviewed-by-human": true
@@ -3775,7 +3809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7416446637660374210
+          1749131430740318779
         ]
       ], 
       "reviewed-by-human": true
@@ -3784,7 +3818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13313875175804070508
+          12553201495837952118
         ]
       ], 
       "reviewed-by-human": true
@@ -3793,7 +3827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4286126979002176463
+          9747536968620326358
         ]
       ], 
       "reviewed-by-human": true
@@ -3829,7 +3863,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18094470146972105480
+          12661336325625617644
         ]
       ], 
       "reviewed-by-human": true
@@ -3838,7 +3872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16729138449439522348
+          2100485553427956358
         ]
       ], 
       "reviewed-by-human": true
@@ -3847,7 +3881,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          773867758980201814
+          9435645443799817571
         ]
       ], 
       "reviewed-by-human": true
@@ -3960,6 +3994,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -4118,7 +4179,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          15840136010363750101
         ]
       ], 
       "reviewed-by-human": true
@@ -4127,7 +4188,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          553151099982623163
         ]
       ], 
       "reviewed-by-human": true
@@ -4145,7 +4206,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8577320746364246324
+          17901413475889955182
         ]
       ], 
       "reviewed-by-human": true
@@ -4154,7 +4215,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6301307169172356565
+          15655962568887109300
         ]
       ], 
       "reviewed-by-human": true
@@ -4172,7 +4233,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15194393119626941638
+          2025817326132268044
         ]
       ], 
       "reviewed-by-human": true
@@ -4181,7 +4242,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18024624917912577304
+          4498759410061841062
         ]
       ], 
       "reviewed-by-human": true
@@ -4199,7 +4260,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16878465395422523550
+          12791906531913394489
         ]
       ], 
       "reviewed-by-human": true
@@ -4208,7 +4269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13162576846071114657
+          7053460792550818176
         ]
       ], 
       "reviewed-by-human": true
@@ -4226,7 +4287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16230885768543124448
+          15924108274958577762
         ]
       ], 
       "reviewed-by-human": true
@@ -4235,7 +4296,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6797057477759131840
+          17768838851047792154
         ]
       ], 
       "reviewed-by-human": true
@@ -4253,7 +4314,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8846430944908901166
+          2471052076010128346
         ]
       ], 
       "reviewed-by-human": true
@@ -4262,7 +4323,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11911675832026192391
+          6090155424035379572
         ]
       ], 
       "reviewed-by-human": true
@@ -4280,7 +4341,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237759626563291567
+          4336016262533487701
         ]
       ], 
       "reviewed-by-human": true
@@ -4289,7 +4350,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8732622580114980787
+          9142174592881097490
         ]
       ], 
       "reviewed-by-human": true
@@ -4307,7 +4368,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17156163502530286228
+          15960009663661689458
         ]
       ], 
       "reviewed-by-human": true
@@ -4316,7 +4377,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13898311729224982406
+          9758610231644803186
         ]
       ], 
       "reviewed-by-human": true
@@ -4334,7 +4395,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8088349932016019412
+          3976985443811942783
         ]
       ], 
       "reviewed-by-human": true
@@ -4343,7 +4404,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16152681108877952354
+          6917722507436446345
         ]
       ], 
       "reviewed-by-human": true
@@ -4388,7 +4449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6659537104690458991
+          8438084710543507198
         ]
       ], 
       "reviewed-by-human": true
@@ -4397,7 +4458,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14777277832097178014
+          17977715539560943749
         ]
       ], 
       "reviewed-by-human": true
@@ -4442,7 +4503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15534699152944221402
+          17230662924303836725
         ]
       ], 
       "reviewed-by-human": true
@@ -4451,7 +4512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9842142403939335300
+          9212565008999202179
         ]
       ], 
       "reviewed-by-human": true
@@ -4469,7 +4530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11953445213035982682
+          15675965195423663386
         ]
       ], 
       "reviewed-by-human": true
@@ -4478,7 +4539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18356463429915079552
+          4460192903137624324
         ]
       ], 
       "reviewed-by-human": true
@@ -4492,6 +4553,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18400047645694418480
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -4505,72 +4593,54 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          1821325695757397620
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13605807214433697
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13605807214433697
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          6708763127627046893
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13271159159658735588
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          13271159159658735588
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
@@ -4603,11 +4673,38 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10215574519029554698
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12061292170759771468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          964478338131907768
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11098600005518612422
+          8160621906382172772
         ]
       ], 
       "ignore-failure": false, 
@@ -4617,7 +4714,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12924368150056635888
+          3638984878878580889
         ]
       ], 
       "ignore-failure": false, 
@@ -4627,7 +4724,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1248385260413008534
+          6985401488806315560
         ]
       ], 
       "ignore-failure": false, 
@@ -4984,6 +5081,222 @@
       ], 
       "ignore-failure": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2542842552177748878
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14451045898461494763
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10878364517039000997
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14024409341192570213
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11926541870165436762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14024409341192570213
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11926541870165436762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8640054562370462165
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1619379911426141072
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079712827936605791
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8322189768762361893
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14690527047657142551
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13982751467199249854
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14024409341192570213
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3014570544789576830
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11926541870165436762
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16269982327662298279
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13816591426241372835
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10210969919713266978
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6701875488092960282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3660765690515931744
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          483347305491602167
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -5015,10 +5328,7 @@
           14015662146260093838
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_matrix_565.png": {
       "allowed-digests": [
@@ -5081,7 +5391,7 @@
           3493263944278727556
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_565.png": {
       "allowed-digests": [
@@ -5108,7 +5418,7 @@
           15451235578409962625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_565.png": {
       "allowed-digests": [
@@ -5135,7 +5445,7 @@
           10135349930059020946
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_565.png": {
       "allowed-digests": [
@@ -5282,7 +5592,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "ignore-failure": false, 
@@ -5312,7 +5622,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297095911910169239
+          9805842470726753368
         ]
       ], 
       "reviewed-by-human": true
@@ -5390,10 +5700,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8439292883038599650
+          17075103240901787870
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -5485,11 +5796,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12464380758342201484
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1246800919397645188
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6243034097773735184
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14035574113753451382
+          11106328037616688411
         ]
       ], 
       "ignore-failure": false, 
@@ -5499,7 +5837,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15210866016398022120
+          15644130602377025892
         ]
       ], 
       "ignore-failure": false, 
@@ -5509,7 +5847,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          603695485072907856
+          7619477096231926311
         ]
       ], 
       "ignore-failure": false, 
@@ -5519,7 +5857,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10777355457185638337
+          12586841244820131235
         ]
       ], 
       "reviewed-by-human": true
@@ -5528,7 +5866,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071282510990956080
+          17873119728038419105
         ]
       ], 
       "reviewed-by-human": true
@@ -5537,7 +5875,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8795346686869088146
+          344246998918338983
         ]
       ], 
       "reviewed-by-human": true
@@ -5573,7 +5911,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10444748308763470034
+          12784893736395190326
         ]
       ], 
       "ignore-failure": false, 
@@ -5583,7 +5921,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966045235333891041
+          10029023872252369111
         ]
       ], 
       "ignore-failure": false, 
@@ -5593,7 +5931,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16871273291364293800
+          12569676270494334123
         ]
       ], 
       "ignore-failure": false, 
@@ -5619,7 +5957,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7083256779583570909
+          9179365879237426214
         ]
       ], 
       "reviewed-by-human": true
@@ -5628,7 +5966,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6884363144513814401
+          13878008363115233918
         ]
       ], 
       "reviewed-by-human": true
@@ -5637,7 +5975,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14804607715615711480
+          638319242050328704
         ]
       ], 
       "reviewed-by-human": true
@@ -5646,7 +5984,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14847356829373202930
+          18237646684385467588
         ]
       ], 
       "reviewed-by-human": true
@@ -5685,23 +6023,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8686840007074574670
+          6884063645048513632
         ]
       ], 
       "reviewed-by-human": true
@@ -5710,7 +6050,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14625944923053341670
+          14117400437006921516
         ]
       ], 
       "reviewed-by-human": true
@@ -5719,7 +6059,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1901521361109987395
+          14816015368674233714
         ]
       ], 
       "reviewed-by-human": true
@@ -5728,7 +6068,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7982720251199582723
+          8798527610830880143
         ]
       ], 
       "reviewed-by-human": true
@@ -5869,13 +6209,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8033413492174781528
+          14104477372457343571
         ]
       ], 
       "bugs": [
         1759
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_565.png": {
       "allowed-digests": [
@@ -5935,7 +6275,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564246142489134519
+          12034621044014828739
         ]
       ], 
       "reviewed-by-human": true
@@ -5944,7 +6284,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1370520776657521517
+          17212900163667680667
         ]
       ], 
       "reviewed-by-human": true
@@ -5953,7 +6293,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15956062266281295116
+          1995926033333720658
         ]
       ], 
       "reviewed-by-human": true
@@ -5962,7 +6302,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981696952434326875
+          10205549632922849523
         ]
       ], 
       "reviewed-by-human": true
@@ -5971,7 +6311,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15238792371190456534
+          5122071235510816862
         ]
       ], 
       "reviewed-by-human": true
@@ -5980,7 +6320,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18193617695367577901
+          17196821659743114733
         ]
       ], 
       "reviewed-by-human": true
@@ -6005,15 +6345,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10386492654531940245
+          9170387744192116888
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3101476576521947165
+          6352977614463860995
         ]
       ], 
       "reviewed-by-human": true
@@ -6022,7 +6363,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10055081768235896808
+          16055003435471712082
         ]
       ], 
       "reviewed-by-human": true
@@ -6031,7 +6372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2603077871826545278
+          12577732892225437166
         ]
       ], 
       "reviewed-by-human": true
@@ -6091,7 +6432,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6124,7 +6465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6157,7 +6498,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12384378992736585751
+          14719038845723165619
         ]
       ], 
       "reviewed-by-human": true
@@ -6217,13 +6558,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1392431913011031709
+          9537223841629940172
         ]
       ], 
       "bugs": [
         1759
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_565.png": {
       "allowed-digests": [
@@ -6252,6 +6593,276 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12026275426271527150
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6958579088836506224
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2297483525893474810
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18100843957901826201
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4478490979400536378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16204222930251940046
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16721089005631938371
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9760231745798245964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5749308152293375604
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16662786566822056022
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -6409,7 +7020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15240835456320409473
+          2417541102915221087
         ]
       ], 
       "reviewed-by-human": true
@@ -6418,7 +7029,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          249289862803617115
+          4496194756153902794
         ]
       ], 
       "reviewed-by-human": true
@@ -6427,7 +7038,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17818108684129139098
+          4154305136980930847
         ]
       ], 
       "reviewed-by-human": true
@@ -6460,13 +7071,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          2379796454057556376
         ]
       ], 
       "bugs": [
         1759
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "ovals_565.png": {
       "allowed-digests": [
@@ -6495,6 +7106,60 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14923802744175220714
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17286230013131859770
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -6604,7 +7269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10076388000940146533
+          1682572932242995816
         ]
       ], 
       "bugs": [
@@ -6740,7 +7405,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -6749,7 +7414,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -6758,11 +7423,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6943431591101726407
+          8237755924122347050
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9531551378023358784
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -6790,6 +7482,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4509758055939626468
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -6817,6 +7536,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -6849,7 +7595,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6571118611946058617
+          17983017435379030888
         ]
       ], 
       "reviewed-by-human": true
@@ -6858,7 +7604,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2985268228390879272
+          14038652322622145328
         ]
       ], 
       "reviewed-by-human": true
@@ -6867,7 +7613,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16168905822423961360
+          7780142035003324778
         ]
       ], 
       "reviewed-by-human": true
@@ -6903,7 +7649,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17243480259296502336
+          8491037037204301331
         ]
       ], 
       "reviewed-by-human": true
@@ -6912,7 +7658,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6891379388563692035
+          16113419322232484853
         ]
       ], 
       "reviewed-by-human": true
@@ -6921,7 +7667,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3493526150687710271
+          18200832368629027021
         ]
       ], 
       "reviewed-by-human": true
@@ -6930,7 +7676,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6963865127519492895
+          13158779623131982179
         ]
       ], 
       "reviewed-by-human": true
@@ -6939,7 +7685,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7223243377781866680
+          12925825870714067916
         ]
       ], 
       "reviewed-by-human": true
@@ -6948,7 +7694,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11938277717739874979
+          11423134871343942431
         ]
       ], 
       "reviewed-by-human": true
@@ -7011,10 +7757,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18199326463862210265
+          16390092508393346144
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "rects_565.png": {
       "allowed-digests": [
@@ -7318,12 +8065,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2127407127834363551
+          7623093636828792551
         ]
       ], 
-      "bugs": [
-        1838
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -7403,7 +8147,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10172121282900547958
+          12022539994697419041
         ]
       ], 
       "reviewed-by-human": true
@@ -7430,7 +8174,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3998266583888463598
+          8293817049980287910
         ]
       ], 
       "reviewed-by-human": true
@@ -7874,7 +8618,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17619211944443238901
+          10211393238987918705
         ]
       ], 
       "reviewed-by-human": true
@@ -7883,7 +8627,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476337759406055776
+          5070879619906521041
         ]
       ], 
       "reviewed-by-human": true
@@ -7892,7 +8636,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6669667580550234931
+          13798375824850427074
         ]
       ], 
       "reviewed-by-human": true
@@ -8099,7 +8843,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7085130049375511832
+          11055155137550620869
         ]
       ], 
       "reviewed-by-human": true
@@ -8108,7 +8852,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15846255821264969272
+          16800018700019366772
         ]
       ], 
       "reviewed-by-human": true
@@ -8117,7 +8861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10510375443381640752
+          18205738113783069124
         ]
       ], 
       "reviewed-by-human": true
@@ -8203,6 +8947,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17484439610611592723
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8109963484323310187
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          374437982401021225
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -8234,10 +9005,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16780536364041129122
+          758934049590219880
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -8264,7 +9035,8 @@
           15858307657519327001
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_565.png": {
       "allowed-digests": [
@@ -8297,16 +9069,13 @@
           12367524911555205763
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15884441815359625883
+          15191409507212695130
         ]
       ], 
       "reviewed-by-human": true
@@ -8315,7 +9084,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          11411832946137461218
         ]
       ], 
       "reviewed-by-human": true
@@ -8324,7 +9093,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          11411832946137461218
         ]
       ], 
       "reviewed-by-human": true
@@ -8405,7 +9174,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15663350675863222117
+          7526371396718664611
         ]
       ], 
       "reviewed-by-human": true
@@ -8432,7 +9201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18099831386641683703
+          9912155885325751678
         ]
       ], 
       "reviewed-by-human": true
@@ -8572,6 +9341,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17056303258237391595
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1779290589524924521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3856303282484892427
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17056303258237391595
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1779290589524924521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3856303282484892427
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17426798752912810170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7850745143997123083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13581485591687976567
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17426798752912810170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7850745143997123083
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13581485591687976567
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -8684,7 +9561,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10958353996143090911
+          17760244815865706025
         ]
       ], 
       "reviewed-by-human": true
@@ -8693,7 +9570,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17000878545702467803
+          2770675093666585013
         ]
       ], 
       "reviewed-by-human": true
@@ -8702,7 +9579,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1557616897383013085
+          15972717687977180040
         ]
       ], 
       "reviewed-by-human": true
@@ -8729,7 +9606,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16806594850934938489
+          11056040080954093657
         ]
       ], 
       "reviewed-by-human": true
@@ -8756,7 +9633,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17085212712405221649
+          5483074157359624611
         ]
       ], 
       "reviewed-by-human": true
@@ -8783,10 +9660,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12025936981544886506
+          10082620380128469910
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6719196348100419960
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-ChromeOS-Alex-GMA3150-x86-Debug/expected-results.json b/expectations/gm/Test-ChromeOS-Alex-GMA3150-x86-Debug/expected-results.json
index f0837a4..01a48cb 100644
--- a/expectations/gm/Test-ChromeOS-Alex-GMA3150-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-ChromeOS-Alex-GMA3150-x86-Debug/expected-results.json
@@ -132,20 +132,20 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
+    "astcbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864700347231029854
+          7296080463405164282
         ]
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_8888.png": {
+    "astcbitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10469536215464879914
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -316,7 +316,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12733412592393621295
+          14933947455022207810
         ]
       ], 
       "reviewed-by-human": true
@@ -325,7 +325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5946418223481278362
+          9429397631137042338
         ]
       ], 
       "reviewed-by-human": true
@@ -1317,6 +1317,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -1431,6 +1449,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -1903,7 +1939,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4055619075226987340
+          4365324358071647520
         ]
       ], 
       "reviewed-by-human": true
@@ -1912,7 +1948,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4557992853592297566
+          5614484684548433583
         ]
       ], 
       "reviewed-by-human": true
@@ -2053,97 +2089,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10068837538312183953
+          4122573986499083629
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10016521496433115213
+          17811514544878557690
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7464499056519654703
+          10785291306759230388
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15332578859151090320
+          12746992454674933423
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8965480679282112778
+          579801054003976645
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2304893413235782801
+          10391939239471720359
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6227016395519002875
+          14514750372511820
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1986132516951273797
+          6593314678375567465
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "composeshader_565.png": {
       "allowed-digests": [
@@ -2185,7 +2197,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16287621504408228135
+          1925435588931099227
         ]
       ], 
       "reviewed-by-human": true
@@ -2194,7 +2206,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13751296096684188541
+          8932658893921139420
         ]
       ], 
       "reviewed-by-human": true
@@ -2251,13 +2263,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6518663564051896723
+          4473716651631484322
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -2275,13 +2284,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10821558801204565074
+          1408988420258361261
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -2395,13 +2401,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3270902242322559127
+          17607805564534773069
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -2437,55 +2440,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14315484682760036965
+          15939998926969705592
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10723174703710553903
+          8936909783553541695
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -2494,7 +2485,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -2503,7 +2494,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
       "reviewed-by-human": true
@@ -2512,7 +2503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
       "reviewed-by-human": true
@@ -2521,7 +2512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
       "reviewed-by-human": true
@@ -2530,7 +2521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
       "reviewed-by-human": true
@@ -2539,7 +2530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
       "reviewed-by-human": true
@@ -2548,7 +2539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
       "reviewed-by-human": true
@@ -2557,7 +2548,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -2566,7 +2557,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -2575,7 +2566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
       "reviewed-by-human": true
@@ -2584,7 +2575,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
       "reviewed-by-human": true
@@ -2593,7 +2584,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
       "reviewed-by-human": true
@@ -2602,7 +2593,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
       "reviewed-by-human": true
@@ -2611,7 +2602,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
       "reviewed-by-human": true
@@ -2620,7 +2611,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
       "reviewed-by-human": true
@@ -2629,7 +2620,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1530707512178085561
+          10271058086783546999
         ]
       ], 
       "reviewed-by-human": true
@@ -2638,7 +2629,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          980323142529009371
+          3142498189590007725
         ]
       ], 
       "reviewed-by-human": true
@@ -2647,7 +2638,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17548929630775824590
+          6313179153663796686
         ]
       ], 
       "reviewed-by-human": true
@@ -2656,7 +2647,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11976677741164833714
+          2585068771325704109
         ]
       ], 
       "reviewed-by-human": true
@@ -2665,7 +2656,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5571304773194307139
+          1246435018882871242
         ]
       ], 
       "reviewed-by-human": true
@@ -2674,7 +2665,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7809896048824512616
+          12649783538704748585
         ]
       ], 
       "reviewed-by-human": true
@@ -2683,7 +2674,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11148261353425501841
+          9062603587929076887
         ]
       ], 
       "reviewed-by-human": true
@@ -2692,7 +2683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17036053137930953952
+          8795270385167261268
         ]
       ], 
       "reviewed-by-human": true
@@ -2701,7 +2692,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          5064010763405785676
         ]
       ], 
       "reviewed-by-human": true
@@ -2719,13 +2710,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12296443715875078696
+          572931968259377616
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -2743,25 +2731,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4566318301688711976
+          16929342067451720663
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13845187347141053231
+          10521895959783131624
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_565.png": {
       "allowed-digests": [
@@ -2801,13 +2783,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17410878668100321713
+          13415547801707026682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -2893,6 +2872,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3005,7 +3002,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7419227591265311221
+          2180768823026833562
         ]
       ], 
       "reviewed-by-human": true
@@ -3014,7 +3011,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9941389284961210315
+          12199897808056356124
         ]
       ], 
       "reviewed-by-human": true
@@ -3023,7 +3020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4712618105826416872
+          370415619944804844
         ]
       ], 
       "reviewed-by-human": true
@@ -3032,7 +3029,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6814786601958107546
+          8271636985969391381
         ]
       ], 
       "reviewed-by-human": true
@@ -3041,7 +3038,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11309219541124250528
+          4847810197899900218
         ]
       ], 
       "reviewed-by-human": true
@@ -3050,7 +3047,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8042312968331390097
+          3506803607239781083
         ]
       ], 
       "reviewed-by-human": true
@@ -3059,7 +3056,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17324002053051694427
+          2090785975892516151
         ]
       ], 
       "reviewed-by-human": true
@@ -3068,7 +3065,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10616193688896439855
+          2924211775552310056
         ]
       ], 
       "reviewed-by-human": true
@@ -3077,7 +3074,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10302533496874247276
+          16889052153239653128
         ]
       ], 
       "reviewed-by-human": true
@@ -3086,7 +3083,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12569931102745160299
+          6790235028873950669
         ]
       ], 
       "reviewed-by-human": true
@@ -3095,7 +3092,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          842153490277803410
+          10744005928079115852
         ]
       ], 
       "reviewed-by-human": true
@@ -3104,7 +3101,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577999994704956939
+          6776804094106320859
         ]
       ], 
       "reviewed-by-human": true
@@ -3113,7 +3110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17152997950184504727
+          12357182101174773078
         ]
       ], 
       "reviewed-by-human": true
@@ -3122,7 +3119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11428391327691184765
+          3126361758776039631
         ]
       ], 
       "reviewed-by-human": true
@@ -3131,7 +3128,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4139187976413040197
+          8367950844952921343
         ]
       ], 
       "reviewed-by-human": true
@@ -3140,7 +3137,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14073034095251842923
+          15525258025464017393
         ]
       ], 
       "reviewed-by-human": true
@@ -3149,7 +3146,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17106863847823042087
+          7934322701486748120
         ]
       ], 
       "reviewed-by-human": true
@@ -3158,7 +3155,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12215969181637652211
+          4704939924625922499
         ]
       ], 
       "reviewed-by-human": true
@@ -3185,7 +3182,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3068653512092670589
+          18291684100428307360
         ]
       ], 
       "reviewed-by-human": true
@@ -3194,7 +3191,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15170271034615721666
+          1747669205907815761
         ]
       ], 
       "reviewed-by-human": true
@@ -3203,7 +3200,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2173204936520384840
+          10025423967750907106
         ]
       ], 
       "reviewed-by-human": true
@@ -3212,7 +3209,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7629194220620174331
+          12682513741653730072
         ]
       ], 
       "reviewed-by-human": true
@@ -3221,7 +3218,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14880073344865389405
+          18437536326942136095
         ]
       ], 
       "reviewed-by-human": true
@@ -3230,7 +3227,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14779749701421579036
+          992750546082849424
         ]
       ], 
       "reviewed-by-human": true
@@ -3239,7 +3236,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15879723616088175665
+          13253889832974067817
         ]
       ], 
       "reviewed-by-human": true
@@ -3248,58 +3245,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13288279458404367808
+          9808251841916487642
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11155802316895019081
+          3107305384935863757
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4456781603336379072
+          12311346928809779354
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          6338121414979628929
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          2548288105368098781
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -3319,17 +3322,32 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1492550562662371249
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1451871976526159345
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13816344334579959610
+          1885470002978941560
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -3643,6 +3661,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14725946082527122548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1970752919594322242
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14000000175854108187
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16484158412400378838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5738923741860091972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4139252971218166703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6780742014081653195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17328318429823679802
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14464249100640346115
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8126556954709394782
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5738923741860091972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4139252971218166703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13815629778380581120
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17078460818277377725
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15002961101914920583
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1699653212169289473
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -3839,7 +4001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          10887305247691796896
         ]
       ], 
       "reviewed-by-human": true
@@ -3857,25 +4019,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14815619054047376737
+          5025305727406958156
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1691062541253205748
+          15612462860180208512
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -3985,35 +4141,47 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6174753214922676017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14386872466540604812
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2501247263900090221
+          9151992564279761362
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17338444569500642489
+          1484908596766764778
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7047160218840827662
+          11578047827687176535
         ]
       ], 
       "reviewed-by-human": true
@@ -4022,7 +4190,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3219790507750540513
+          9753979676410027445
         ]
       ], 
       "reviewed-by-human": true
@@ -4154,7 +4322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
       ], 
       "reviewed-by-human": true
@@ -4163,7 +4331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
       ], 
       "reviewed-by-human": true
@@ -4172,7 +4340,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18066506753999183497
+          7955099457759770546
         ]
       ], 
       "reviewed-by-human": true
@@ -4181,7 +4349,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11982781292527727120
+          6913141539607550299
         ]
       ], 
       "reviewed-by-human": true
@@ -4340,13 +4508,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4316780454237822885
+          9378058285900148337
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -4364,13 +4529,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11315452322479838543
+          7959551695024800866
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -4428,19 +4590,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17681274672761086257
+          14870126594662014966
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10222071295493882388
+          4143151400782668729
         ]
       ], 
       "reviewed-by-human": true
@@ -4601,6 +4760,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -4689,17 +5028,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3512281410281869464
+          16387093217215132664
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1569508413774938590
+          11363954745247829087
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -4749,6 +5090,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -4930,7 +5307,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -4939,11 +5316,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -4960,6 +5355,24 @@
         ]
       ]
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -4978,6 +5391,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5006,7 +5437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61607569459068318
+          6869421870530403934
         ]
       ], 
       "reviewed-by-human": true
@@ -5015,7 +5446,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3695817156238720886
+          922181716107376654
         ]
       ], 
       "reviewed-by-human": true
@@ -5042,13 +5473,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8548116805903985121
+          2853960147093856126
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -5066,13 +5494,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13326304985990194555
+          15351687325140125092
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -5484,7 +5909,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11165871866367438949
+          12291440777244417138
         ]
       ], 
       "reviewed-by-human": true
@@ -5493,7 +5918,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13641016986377676105
+          16183462849525299755
         ]
       ], 
       "reviewed-by-human": true
@@ -5511,7 +5936,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12300021040423412330
+          4978564899265777194
         ]
       ], 
       "reviewed-by-human": true
@@ -5520,7 +5945,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4063155744015088621
+          13017143225617973072
         ]
       ], 
       "reviewed-by-human": true
@@ -5773,25 +6198,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10578477976307184622
+          253131715823163995
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8347094436302455537
+          7617296157433611704
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -5947,7 +6366,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864788083336423375
+          330942250169968308
         ]
       ], 
       "reviewed-by-human": true
@@ -5956,7 +6375,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7463337896229207134
+          7668062252694178795
         ]
       ], 
       "reviewed-by-human": true
@@ -6009,6 +6428,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11990750039619298194
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3499763660998801760
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -6085,17 +6522,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15337196922136784147
+          1211749665346933897
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          595779208369948227
+          4086269437985502628
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -6277,6 +6716,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13819134465309978660
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11544526722524785606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          366412474691268411
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2883817717015897758
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1259588124280752477
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10575467507503597964
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15178893511229446182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6372880763970640048
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -6371,25 +6882,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3097518840997296951
+          1044052949699122451
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7316468186520532597
+          13975490780846913072
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
diff --git a/expectations/gm/Test-ChromeOS-Alex-GMA3150-x86-Release/expected-results.json b/expectations/gm/Test-ChromeOS-Alex-GMA3150-x86-Release/expected-results.json
index 6d28eb8..269a695 100644
--- a/expectations/gm/Test-ChromeOS-Alex-GMA3150-x86-Release/expected-results.json
+++ b/expectations/gm/Test-ChromeOS-Alex-GMA3150-x86-Release/expected-results.json
@@ -132,20 +132,20 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
+    "astcbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864700347231029854
+          7296080463405164282
         ]
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_8888.png": {
+    "astcbitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10469536215464879914
+          7104155647358997780
         ]
       ], 
       "reviewed-by-human": true
@@ -316,7 +316,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12733412592393621295
+          14933947455022207810
         ]
       ], 
       "reviewed-by-human": true
@@ -325,7 +325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5946418223481278362
+          9429397631137042338
         ]
       ], 
       "reviewed-by-human": true
@@ -1317,6 +1317,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -1431,6 +1449,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -1903,19 +1939,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4055619075226987340
+          4365324358071647520
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4557992853592297566
+          5614484684548433583
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -2053,97 +2089,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10068837538312183953
+          4122573986499083629
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10016521496433115213
+          17811514544878557690
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7464499056519654703
+          10785291306759230388
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15332578859151090320
+          12746992454674933423
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8965480679282112778
+          579801054003976645
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2304893413235782801
+          10391939239471720359
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6227016395519002875
+          14514750372511820
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1986132516951273797
+          6593314678375567465
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "composeshader_565.png": {
       "allowed-digests": [
@@ -2185,7 +2197,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16287621504408228135
+          1925435588931099227
         ]
       ], 
       "reviewed-by-human": true
@@ -2194,7 +2206,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13751296096684188541
+          8932658893921139420
         ]
       ], 
       "reviewed-by-human": true
@@ -2251,13 +2263,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6518663564051896723
+          4473716651631484322
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -2275,13 +2284,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10821558801204565074
+          1408988420258361261
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -2395,13 +2401,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3270902242322559127
+          17607805564534773069
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -2437,55 +2440,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14315484682760036965
+          15939998926969705592
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10723174703710553903
+          8936909783553541695
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -2494,7 +2485,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -2503,7 +2494,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
       "reviewed-by-human": true
@@ -2512,7 +2503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
       "reviewed-by-human": true
@@ -2521,7 +2512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
       "reviewed-by-human": true
@@ -2530,7 +2521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
       "reviewed-by-human": true
@@ -2539,7 +2530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
       "reviewed-by-human": true
@@ -2548,7 +2539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
       "reviewed-by-human": true
@@ -2557,7 +2548,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -2566,7 +2557,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -2575,7 +2566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
       "reviewed-by-human": true
@@ -2584,7 +2575,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
       "reviewed-by-human": true
@@ -2593,7 +2584,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
       "reviewed-by-human": true
@@ -2602,7 +2593,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
       "reviewed-by-human": true
@@ -2611,7 +2602,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
       "reviewed-by-human": true
@@ -2620,7 +2611,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
       "reviewed-by-human": true
@@ -2629,7 +2620,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1530707512178085561
+          10271058086783546999
         ]
       ], 
       "reviewed-by-human": true
@@ -2638,7 +2629,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          980323142529009371
+          3142498189590007725
         ]
       ], 
       "reviewed-by-human": true
@@ -2647,7 +2638,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17548929630775824590
+          6313179153663796686
         ]
       ], 
       "reviewed-by-human": true
@@ -2656,7 +2647,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11976677741164833714
+          2585068771325704109
         ]
       ], 
       "reviewed-by-human": true
@@ -2665,7 +2656,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5571304773194307139
+          1246435018882871242
         ]
       ], 
       "reviewed-by-human": true
@@ -2674,7 +2665,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7809896048824512616
+          12649783538704748585
         ]
       ], 
       "reviewed-by-human": true
@@ -2683,7 +2674,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11148261353425501841
+          9062603587929076887
         ]
       ], 
       "reviewed-by-human": true
@@ -2692,7 +2683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17036053137930953952
+          8795270385167261268
         ]
       ], 
       "reviewed-by-human": true
@@ -2701,7 +2692,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          5064010763405785676
         ]
       ], 
       "reviewed-by-human": true
@@ -2719,13 +2710,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12296443715875078696
+          572931968259377616
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -2743,25 +2731,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4566318301688711976
+          16929342067451720663
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13845187347141053231
+          10521895959783131624
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_565.png": {
       "allowed-digests": [
@@ -2801,13 +2783,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17410878668100321713
+          13415547801707026682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -2893,6 +2872,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3005,7 +3002,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7419227591265311221
+          2180768823026833562
         ]
       ], 
       "reviewed-by-human": true
@@ -3014,7 +3011,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9941389284961210315
+          12199897808056356124
         ]
       ], 
       "reviewed-by-human": true
@@ -3023,7 +3020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4712618105826416872
+          370415619944804844
         ]
       ], 
       "reviewed-by-human": true
@@ -3032,7 +3029,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6814786601958107546
+          8271636985969391381
         ]
       ], 
       "reviewed-by-human": true
@@ -3041,7 +3038,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11309219541124250528
+          4847810197899900218
         ]
       ], 
       "reviewed-by-human": true
@@ -3050,7 +3047,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8042312968331390097
+          3506803607239781083
         ]
       ], 
       "reviewed-by-human": true
@@ -3059,7 +3056,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17324002053051694427
+          2090785975892516151
         ]
       ], 
       "reviewed-by-human": true
@@ -3068,7 +3065,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10616193688896439855
+          2924211775552310056
         ]
       ], 
       "reviewed-by-human": true
@@ -3077,7 +3074,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10302533496874247276
+          16889052153239653128
         ]
       ], 
       "reviewed-by-human": true
@@ -3086,7 +3083,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12569931102745160299
+          6790235028873950669
         ]
       ], 
       "reviewed-by-human": true
@@ -3095,7 +3092,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          842153490277803410
+          10744005928079115852
         ]
       ], 
       "reviewed-by-human": true
@@ -3104,7 +3101,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577999994704956939
+          6776804094106320859
         ]
       ], 
       "reviewed-by-human": true
@@ -3113,7 +3110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17152997950184504727
+          12357182101174773078
         ]
       ], 
       "reviewed-by-human": true
@@ -3122,7 +3119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11428391327691184765
+          3126361758776039631
         ]
       ], 
       "reviewed-by-human": true
@@ -3131,7 +3128,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4139187976413040197
+          8367950844952921343
         ]
       ], 
       "reviewed-by-human": true
@@ -3140,7 +3137,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14073034095251842923
+          15525258025464017393
         ]
       ], 
       "reviewed-by-human": true
@@ -3149,7 +3146,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17106863847823042087
+          7934322701486748120
         ]
       ], 
       "reviewed-by-human": true
@@ -3158,7 +3155,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12215969181637652211
+          4704939924625922499
         ]
       ], 
       "reviewed-by-human": true
@@ -3185,7 +3182,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3068653512092670589
+          18291684100428307360
         ]
       ], 
       "reviewed-by-human": true
@@ -3194,7 +3191,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15170271034615721666
+          1747669205907815761
         ]
       ], 
       "reviewed-by-human": true
@@ -3203,7 +3200,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2173204936520384840
+          10025423967750907106
         ]
       ], 
       "reviewed-by-human": true
@@ -3212,7 +3209,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7629194220620174331
+          12682513741653730072
         ]
       ], 
       "reviewed-by-human": true
@@ -3221,7 +3218,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14880073344865389405
+          18437536326942136095
         ]
       ], 
       "reviewed-by-human": true
@@ -3230,7 +3227,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14779749701421579036
+          992750546082849424
         ]
       ], 
       "reviewed-by-human": true
@@ -3239,7 +3236,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15879723616088175665
+          13253889832974067817
         ]
       ], 
       "reviewed-by-human": true
@@ -3248,58 +3245,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13288279458404367808
+          9808251841916487642
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11155802316895019081
+          3107305384935863757
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4456781603336379072
+          12311346928809779354
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          6338121414979628929
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          2548288105368098781
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -3319,17 +3322,32 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1492550562662371249
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1451871976526159345
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13816344334579959610
+          1885470002978941560
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -3643,6 +3661,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14725946082527122548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1970752919594322242
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14000000175854108187
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16484158412400378838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5738923741860091972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4139252971218166703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6780742014081653195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17328318429823679802
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14464249100640346115
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8126556954709394782
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5738923741860091972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4139252971218166703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13815629778380581120
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17078460818277377725
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15002961101914920583
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1699653212169289473
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -3839,7 +4001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          10887305247691796896
         ]
       ], 
       "reviewed-by-human": true
@@ -3857,25 +4019,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14815619054047376737
+          5025305727406958156
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1691062541253205748
+          15612462860180208512
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -3985,35 +4141,47 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6174753214922676017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14386872466540604812
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2501247263900090221
+          9151992564279761362
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17338444569500642489
+          1484908596766764778
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7047160218840827662
+          11578047827687176535
         ]
       ], 
       "reviewed-by-human": true
@@ -4022,7 +4190,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3219790507750540513
+          9753979676410027445
         ]
       ], 
       "reviewed-by-human": true
@@ -4155,7 +4323,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
       ], 
       "reviewed-by-human": true
@@ -4164,7 +4332,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
       ], 
       "reviewed-by-human": true
@@ -4173,7 +4341,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18066506753999183497
+          7955099457759770546
         ]
       ], 
       "reviewed-by-human": true
@@ -4182,7 +4350,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11982781292527727120
+          6913141539607550299
         ]
       ], 
       "reviewed-by-human": true
@@ -4338,13 +4506,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4316780454237822885
+          9378058285900148337
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -4362,13 +4527,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11315452322479838543
+          7959551695024800866
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -4426,7 +4588,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17681274672761086257
+          14870126594662014966
         ]
       ], 
       "reviewed-by-human": true
@@ -4435,7 +4597,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10222071295493882388
+          4143151400782668729
         ]
       ], 
       "reviewed-by-human": true
@@ -4596,6 +4758,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -4684,17 +5026,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3512281410281869464
+          16387093217215132664
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1569508413774938590
+          11363954745247829087
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -4744,6 +5088,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -4925,7 +5305,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -4934,11 +5314,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -4955,6 +5353,24 @@
         ]
       ]
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -4973,6 +5389,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5001,7 +5435,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61607569459068318
+          6869421870530403934
         ]
       ], 
       "reviewed-by-human": true
@@ -5010,7 +5444,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3695817156238720886
+          922181716107376654
         ]
       ], 
       "reviewed-by-human": true
@@ -5037,13 +5471,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8548116805903985121
+          2853960147093856126
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -5061,13 +5492,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13326304985990194555
+          15351687325140125092
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -5479,7 +5907,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11165871866367438949
+          12291440777244417138
         ]
       ], 
       "reviewed-by-human": true
@@ -5488,7 +5916,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13641016986377676105
+          16183462849525299755
         ]
       ], 
       "reviewed-by-human": true
@@ -5506,7 +5934,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12300021040423412330
+          4978564899265777194
         ]
       ], 
       "reviewed-by-human": true
@@ -5515,7 +5943,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4063155744015088621
+          13017143225617973072
         ]
       ], 
       "reviewed-by-human": true
@@ -5765,25 +6193,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10578477976307184622
+          253131715823163995
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8347094436302455537
+          7617296157433611704
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -5939,7 +6361,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864788083336423375
+          330942250169968308
         ]
       ], 
       "reviewed-by-human": true
@@ -5948,7 +6370,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7463337896229207134
+          7668062252694178795
         ]
       ], 
       "reviewed-by-human": true
@@ -6001,6 +6423,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11990750039619298194
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3499763660998801760
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -6077,17 +6517,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15337196922136784147
+          1211749665346933897
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          595779208369948227
+          4086269437985502628
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -6269,6 +6711,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13819134465309978660
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11544526722524785606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          366412474691268411
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2883817717015897758
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1259588124280752477
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10575467507503597964
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15178893511229446182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6372880763970640048
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -6363,25 +6877,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3097518840997296951
+          1044052949699122451
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7316468186520532597
+          13975490780846913072
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
diff --git a/expectations/gm/Test-ChromeOS-Daisy-MaliT604-Arm7-Debug/expected-results.json b/expectations/gm/Test-ChromeOS-Daisy-MaliT604-Arm7-Debug/expected-results.json
index 3601e6b..3f026ba 100644
--- a/expectations/gm/Test-ChromeOS-Daisy-MaliT604-Arm7-Debug/expected-results.json
+++ b/expectations/gm/Test-ChromeOS-Daisy-MaliT604-Arm7-Debug/expected-results.json
@@ -138,29 +138,23 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
+    "astcbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864700347231029854
+          7296080463405164282
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "bicubicfilter_8888.png": {
+    "astcbitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10469536215464879914
+          7104155647358997780
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
@@ -328,7 +322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12733412592393621295
+          14933947455022207810
         ]
       ], 
       "reviewed-by-human": true
@@ -337,7 +331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5946418223481278362
+          9429397631137042338
         ]
       ], 
       "reviewed-by-human": true
@@ -1345,6 +1339,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -1459,6 +1471,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -1931,7 +1961,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4723751871359287410
+          6710611135031885899
         ]
       ], 
       "reviewed-by-human": true
@@ -1940,7 +1970,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16275740961157987318
+          11668713810113487563
         ]
       ], 
       "reviewed-by-human": true
@@ -2081,97 +2111,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2753080621801780987
+          1159422801946897894
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14078432724068635914
+          3468034359065801772
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5193269735383560885
+          5105819921398055097
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10083983166703517856
+          225145983047092460
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5332628131931501513
+          11573273501549610521
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328601028583299619
+          17258811667836725493
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2681563620265783022
+          13873318124810469935
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11176948121396322227
+          10160786175174165126
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "composeshader_565.png": {
       "allowed-digests": [
@@ -2213,19 +2219,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14184505217300327710
+          13526588063853374053
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12412589444870044769
+          8257077378942623401
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -2279,13 +2285,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6518663564051896723
+          4473716651631484322
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -2303,13 +2306,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10821558801204565074
+          1408988420258361261
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -2441,13 +2441,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6631188351176705985
+          5340548698269931580
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -2483,55 +2480,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14315484682760036965
+          15939998926969705592
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10723174703710553903
+          8936909783553541695
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -2540,7 +2525,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -2549,79 +2534,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7291613642918106073
+          1557116782665821961
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8174026154893573789
+          10644646464255634876
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -2630,7 +2597,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -2639,79 +2606,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15018591777914911277
+          2490903614933092965
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4969033013118250897
+          3966309174829559531
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1530707512178085561
+          10271058086783546999
         ]
       ], 
       "reviewed-by-human": true
@@ -2720,7 +2669,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          980323142529009371
+          3142498189590007725
         ]
       ], 
       "reviewed-by-human": true
@@ -2729,85 +2678,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17548929630775824590
+          6313179153663796686
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11976677741164833714
+          2585068771325704109
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5571304773194307139
+          1246435018882871242
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7809896048824512616
+          12649783538704748585
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18068108488302721549
+          5908851689540874823
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3005287687233744446
+          3145302666298610960
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11845984825122755781
+          13062574079309331603
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -2825,13 +2753,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12296443715875078696
+          572931968259377616
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -2849,25 +2774,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16344471555621995988
+          15332513913473526735
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11777169860874606699
+          206764306434136411
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_565.png": {
       "allowed-digests": [
@@ -2907,13 +2826,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17410878668100321713
+          13415547801707026682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -2999,6 +2915,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3117,7 +3051,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14926392126645297823
+          17429225697325886661
         ]
       ], 
       "reviewed-by-human": true
@@ -3126,7 +3060,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6394097611931650055
+          11074463627678272502
         ]
       ], 
       "reviewed-by-human": true
@@ -3135,7 +3069,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4019994460979269818
+          16180045166539302946
         ]
       ], 
       "reviewed-by-human": true
@@ -3144,7 +3078,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788804044111767687
+          3056389369996890451
         ]
       ], 
       "reviewed-by-human": true
@@ -3153,7 +3087,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9985740165162656554
+          2996594788685476639
         ]
       ], 
       "reviewed-by-human": true
@@ -3162,7 +3096,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7512978605317496312
+          4115452913784389212
         ]
       ], 
       "reviewed-by-human": true
@@ -3171,7 +3105,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3162420554572589386
+          2485354725416261219
         ]
       ], 
       "reviewed-by-human": true
@@ -3180,7 +3114,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8851045147730143959
+          17159408690493829565
         ]
       ], 
       "reviewed-by-human": true
@@ -3189,7 +3123,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18073378795532927407
+          5837261641785333589
         ]
       ], 
       "reviewed-by-human": true
@@ -3198,7 +3132,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1657453700800580106
+          7824625726453706276
         ]
       ], 
       "reviewed-by-human": true
@@ -3207,7 +3141,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1191357084001840719
+          1066737382160658641
         ]
       ], 
       "reviewed-by-human": true
@@ -3216,7 +3150,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6116810557990792912
+          11256101141871549147
         ]
       ], 
       "reviewed-by-human": true
@@ -3225,7 +3159,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17043844130066330142
+          16525116510288929664
         ]
       ], 
       "reviewed-by-human": true
@@ -3234,7 +3168,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11431747498099827035
+          15951380223649721193
         ]
       ], 
       "reviewed-by-human": true
@@ -3243,7 +3177,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4313052184918471061
+          11793904931168112742
         ]
       ], 
       "reviewed-by-human": true
@@ -3252,7 +3186,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16923808709076031828
+          15007687659163860586
         ]
       ], 
       "reviewed-by-human": true
@@ -3261,7 +3195,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15577477372772821161
+          5128929257626294654
         ]
       ], 
       "reviewed-by-human": true
@@ -3270,7 +3204,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14935726466439974471
+          16105476415843262061
         ]
       ], 
       "reviewed-by-human": true
@@ -3297,7 +3231,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17892848845648300636
+          6764052376846683351
         ]
       ], 
       "reviewed-by-human": true
@@ -3306,7 +3240,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6138216583594586961
+          15814574300028751814
         ]
       ], 
       "reviewed-by-human": true
@@ -3315,7 +3249,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6630240023867865329
+          4464144818359800909
         ]
       ], 
       "reviewed-by-human": true
@@ -3324,7 +3258,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5771187642751392832
+          15488247027049521295
         ]
       ], 
       "reviewed-by-human": true
@@ -3333,7 +3267,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5907461037530955185
+          11154597841147756355
         ]
       ], 
       "reviewed-by-human": true
@@ -3342,7 +3276,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4805292785877010776
+          4136648182665591320
         ]
       ], 
       "reviewed-by-human": true
@@ -3351,7 +3285,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3065437048390603657
+          17782506306943014101
         ]
       ], 
       "reviewed-by-human": true
@@ -3360,58 +3294,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12585618167292168586
+          13532109319571265208
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11155802316895019081
+          3107305384935863757
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4456781603336379072
+          12311346928809779354
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          6338121414979628929
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          2548288105368098781
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -3431,17 +3371,32 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1492550562662371249
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1451871976526159345
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13816344334579959610
+          1885470002978941560
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -3767,6 +3722,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6501176273278212266
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4553858123273357571
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12806221703278414902
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12582336056605206740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10942046361504976833
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14496328789934396870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6780742014081653195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17328318429823679802
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13372973621858281741
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15789658965464704843
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10942046361504976833
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14496328789934396870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15281676065484131510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          290500730973734951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7582679071047841466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2211360627760914126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -3969,7 +4068,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -3987,25 +4086,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14815619054047376737
+          5025305727406958156
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1691062541253205748
+          15612462860180208512
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -4115,35 +4208,47 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6174753214922676017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14386872466540604812
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16420472036142742167
+          5725351811430597350
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006967280791834436
+          3863179479326746375
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16888892931621717497
+          7869971224508451945
         ]
       ], 
       "reviewed-by-human": true
@@ -4152,7 +4257,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3445674795428490303
+          5692770311525557271
         ]
       ], 
       "reviewed-by-human": true
@@ -4283,41 +4388,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18129300067786247916
+          10126308050944144217
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8698863922407868351
+          5924938292289537271
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_565.png": {
       "allowed-digests": [
@@ -4473,13 +4574,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4316780454237822885
+          9378058285900148337
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -4497,13 +4595,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11315452322479838543
+          7959551695024800866
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -4561,25 +4656,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17681274672761086257
+          14870126594662014966
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10222071295493882388
+          4143151400782668729
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -4737,6 +4826,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -4825,17 +5094,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3512281410281869464
+          16387093217215132664
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1569508413774938590
+          11363954745247829087
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -4885,6 +5156,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -5072,7 +5379,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -5081,11 +5388,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -5102,6 +5427,24 @@
         ]
       ]
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -5120,6 +5463,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5148,7 +5509,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2473856620674970180
+          4901757472857812117
         ]
       ], 
       "reviewed-by-human": true
@@ -5157,7 +5518,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12650836521336992308
+          2131283125610642115
         ]
       ], 
       "reviewed-by-human": true
@@ -5184,13 +5545,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8548116805903985121
+          2853960147093856126
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -5208,13 +5566,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13326304985990194555
+          15351687325140125092
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -5632,7 +5987,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17679372824216335614
+          3879248516601619513
         ]
       ], 
       "reviewed-by-human": true
@@ -5641,7 +5996,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8151893417943928471
+          7841456666967854035
         ]
       ], 
       "reviewed-by-human": true
@@ -5659,7 +6014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16854659843522686561
+          102168595845174371
         ]
       ], 
       "reviewed-by-human": true
@@ -5668,7 +6023,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10095764636848439150
+          2465594291353775714
         ]
       ], 
       "reviewed-by-human": true
@@ -5927,25 +6282,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4311017870212844309
+          14563062782860784218
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2413959871985421251
+          6868262718202869238
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -6107,7 +6456,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9580868274365908576
+          708484880195116844
         ]
       ], 
       "reviewed-by-human": true
@@ -6116,7 +6465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1571215749821631639
+          1283121768714112057
         ]
       ], 
       "reviewed-by-human": true
@@ -6169,6 +6518,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11990750039619298194
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3499763660998801760
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -6245,17 +6612,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15337196922136784147
+          1211749665346933897
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          595779208369948227
+          4086269437985502628
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -6443,6 +6812,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13819134465309978660
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11544526722524785606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          366412474691268411
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2883817717015897758
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1259588124280752477
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10575467507503597964
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15178893511229446182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6372880763970640048
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -6537,25 +6978,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3097518840997296951
+          1044052949699122451
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7316468186520532597
+          13975490780846913072
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
diff --git a/expectations/gm/Test-ChromeOS-Daisy-MaliT604-Arm7-Release/expected-results.json b/expectations/gm/Test-ChromeOS-Daisy-MaliT604-Arm7-Release/expected-results.json
index 5d54db1..3f026ba 100644
--- a/expectations/gm/Test-ChromeOS-Daisy-MaliT604-Arm7-Release/expected-results.json
+++ b/expectations/gm/Test-ChromeOS-Daisy-MaliT604-Arm7-Release/expected-results.json
@@ -138,29 +138,23 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
+    "astcbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864700347231029854
+          7296080463405164282
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "bicubicfilter_8888.png": {
+    "astcbitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10469536215464879914
+          7104155647358997780
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
@@ -328,7 +322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12733412592393621295
+          14933947455022207810
         ]
       ], 
       "reviewed-by-human": true
@@ -337,7 +331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5946418223481278362
+          9429397631137042338
         ]
       ], 
       "reviewed-by-human": true
@@ -1345,6 +1339,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -1459,6 +1471,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -1931,19 +1961,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4723751871359287410
+          6710611135031885899
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16275740961157987318
+          11668713810113487563
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -2081,97 +2111,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2753080621801780987
+          1159422801946897894
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14078432724068635914
+          3468034359065801772
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5193269735383560885
+          5105819921398055097
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10083983166703517856
+          225145983047092460
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5332628131931501513
+          11573273501549610521
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328601028583299619
+          17258811667836725493
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2681563620265783022
+          13873318124810469935
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11176948121396322227
+          10160786175174165126
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "composeshader_565.png": {
       "allowed-digests": [
@@ -2213,19 +2219,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14184505217300327710
+          13526588063853374053
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12412589444870044769
+          8257077378942623401
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -2279,13 +2285,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6518663564051896723
+          4473716651631484322
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -2303,13 +2306,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10821558801204565074
+          1408988420258361261
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -2441,13 +2441,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6631188351176705985
+          5340548698269931580
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -2483,55 +2480,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14315484682760036965
+          15939998926969705592
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10723174703710553903
+          8936909783553541695
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -2540,7 +2525,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -2549,79 +2534,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7291613642918106073
+          1557116782665821961
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8174026154893573789
+          10644646464255634876
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -2630,7 +2597,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -2639,79 +2606,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          8214952685982906644
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          1457014783786728197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15018591777914911277
+          2490903614933092965
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4969033013118250897
+          3966309174829559531
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1530707512178085561
+          10271058086783546999
         ]
       ], 
       "reviewed-by-human": true
@@ -2720,7 +2669,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          980323142529009371
+          3142498189590007725
         ]
       ], 
       "reviewed-by-human": true
@@ -2729,85 +2678,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17548929630775824590
+          6313179153663796686
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11976677741164833714
+          2585068771325704109
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5571304773194307139
+          1246435018882871242
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7809896048824512616
+          12649783538704748585
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18068108488302721549
+          5908851689540874823
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3005287687233744446
+          3145302666298610960
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11845984825122755781
+          13062574079309331603
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -2825,13 +2753,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12296443715875078696
+          572931968259377616
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -2849,25 +2774,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16344471555621995988
+          15332513913473526735
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11777169860874606699
+          206764306434136411
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_565.png": {
       "allowed-digests": [
@@ -2907,13 +2826,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17410878668100321713
+          13415547801707026682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -2999,6 +2915,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3117,7 +3051,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14926392126645297823
+          17429225697325886661
         ]
       ], 
       "reviewed-by-human": true
@@ -3126,7 +3060,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6394097611931650055
+          11074463627678272502
         ]
       ], 
       "reviewed-by-human": true
@@ -3135,7 +3069,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4019994460979269818
+          16180045166539302946
         ]
       ], 
       "reviewed-by-human": true
@@ -3144,7 +3078,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16788804044111767687
+          3056389369996890451
         ]
       ], 
       "reviewed-by-human": true
@@ -3153,7 +3087,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9985740165162656554
+          2996594788685476639
         ]
       ], 
       "reviewed-by-human": true
@@ -3162,7 +3096,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7512978605317496312
+          4115452913784389212
         ]
       ], 
       "reviewed-by-human": true
@@ -3171,7 +3105,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3162420554572589386
+          2485354725416261219
         ]
       ], 
       "reviewed-by-human": true
@@ -3180,7 +3114,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8851045147730143959
+          17159408690493829565
         ]
       ], 
       "reviewed-by-human": true
@@ -3189,7 +3123,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18073378795532927407
+          5837261641785333589
         ]
       ], 
       "reviewed-by-human": true
@@ -3198,7 +3132,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1657453700800580106
+          7824625726453706276
         ]
       ], 
       "reviewed-by-human": true
@@ -3207,7 +3141,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1191357084001840719
+          1066737382160658641
         ]
       ], 
       "reviewed-by-human": true
@@ -3216,7 +3150,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6116810557990792912
+          11256101141871549147
         ]
       ], 
       "reviewed-by-human": true
@@ -3225,7 +3159,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17043844130066330142
+          16525116510288929664
         ]
       ], 
       "reviewed-by-human": true
@@ -3234,7 +3168,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11431747498099827035
+          15951380223649721193
         ]
       ], 
       "reviewed-by-human": true
@@ -3243,7 +3177,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4313052184918471061
+          11793904931168112742
         ]
       ], 
       "reviewed-by-human": true
@@ -3252,7 +3186,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16923808709076031828
+          15007687659163860586
         ]
       ], 
       "reviewed-by-human": true
@@ -3261,7 +3195,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15577477372772821161
+          5128929257626294654
         ]
       ], 
       "reviewed-by-human": true
@@ -3270,7 +3204,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14935726466439974471
+          16105476415843262061
         ]
       ], 
       "reviewed-by-human": true
@@ -3297,7 +3231,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17892848845648300636
+          6764052376846683351
         ]
       ], 
       "reviewed-by-human": true
@@ -3306,7 +3240,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6138216583594586961
+          15814574300028751814
         ]
       ], 
       "reviewed-by-human": true
@@ -3315,7 +3249,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6630240023867865329
+          4464144818359800909
         ]
       ], 
       "reviewed-by-human": true
@@ -3324,7 +3258,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5771187642751392832
+          15488247027049521295
         ]
       ], 
       "reviewed-by-human": true
@@ -3333,7 +3267,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5907461037530955185
+          11154597841147756355
         ]
       ], 
       "reviewed-by-human": true
@@ -3342,7 +3276,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4805292785877010776
+          4136648182665591320
         ]
       ], 
       "reviewed-by-human": true
@@ -3351,7 +3285,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3065437048390603657
+          17782506306943014101
         ]
       ], 
       "reviewed-by-human": true
@@ -3360,58 +3294,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12585618167292168586
+          13532109319571265208
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11155802316895019081
+          3107305384935863757
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4456781603336379072
+          12311346928809779354
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          6338121414979628929
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          2548288105368098781
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -3431,17 +3371,32 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1492550562662371249
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1451871976526159345
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13816344334579959610
+          1885470002978941560
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -3767,6 +3722,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6501176273278212266
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4553858123273357571
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12806221703278414902
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12582336056605206740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10942046361504976833
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14496328789934396870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6780742014081653195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17328318429823679802
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13372973621858281741
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15789658965464704843
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10942046361504976833
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14496328789934396870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15281676065484131510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          290500730973734951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7582679071047841466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2211360627760914126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -3969,7 +4068,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -3987,25 +4086,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14815619054047376737
+          5025305727406958156
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1691062541253205748
+          15612462860180208512
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -4115,35 +4208,47 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6174753214922676017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14386872466540604812
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16420472036142742167
+          5725351811430597350
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006967280791834436
+          3863179479326746375
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16888892931621717497
+          7869971224508451945
         ]
       ], 
       "reviewed-by-human": true
@@ -4152,7 +4257,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3445674795428490303
+          5692770311525557271
         ]
       ], 
       "reviewed-by-human": true
@@ -4283,41 +4388,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18129300067786247916
+          10126308050944144217
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8698863922407868351
+          5924938292289537271
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_565.png": {
       "allowed-digests": [
@@ -4473,13 +4574,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4316780454237822885
+          9378058285900148337
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -4497,13 +4595,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11315452322479838543
+          7959551695024800866
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -4561,25 +4656,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17681274672761086257
+          14870126594662014966
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10222071295493882388
+          4143151400782668729
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -4737,6 +4826,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -4825,17 +5094,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3512281410281869464
+          16387093217215132664
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1569508413774938590
+          11363954745247829087
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -4885,6 +5156,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -5072,7 +5379,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -5081,11 +5388,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -5102,6 +5427,24 @@
         ]
       ]
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -5120,6 +5463,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5148,7 +5509,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2473856620674970180
+          4901757472857812117
         ]
       ], 
       "reviewed-by-human": true
@@ -5157,7 +5518,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12650836521336992308
+          2131283125610642115
         ]
       ], 
       "reviewed-by-human": true
@@ -5184,13 +5545,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8548116805903985121
+          2853960147093856126
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -5208,13 +5566,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13326304985990194555
+          15351687325140125092
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -5632,7 +5987,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17679372824216335614
+          3879248516601619513
         ]
       ], 
       "reviewed-by-human": true
@@ -5641,7 +5996,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8151893417943928471
+          7841456666967854035
         ]
       ], 
       "reviewed-by-human": true
@@ -5659,7 +6014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16854659843522686561
+          102168595845174371
         ]
       ], 
       "reviewed-by-human": true
@@ -5668,7 +6023,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10095764636848439150
+          2465594291353775714
         ]
       ], 
       "reviewed-by-human": true
@@ -5927,25 +6282,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4311017870212844309
+          14563062782860784218
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2413959871985421251
+          6868262718202869238
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -6107,7 +6456,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9580868274365908576
+          708484880195116844
         ]
       ], 
       "reviewed-by-human": true
@@ -6116,7 +6465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1571215749821631639
+          1283121768714112057
         ]
       ], 
       "reviewed-by-human": true
@@ -6169,6 +6518,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11990750039619298194
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3499763660998801760
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -6245,17 +6612,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15337196922136784147
+          1211749665346933897
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          595779208369948227
+          4086269437985502628
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -6443,6 +6812,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13819134465309978660
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11544526722524785606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          366412474691268411
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2883817717015897758
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1259588124280752477
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10575467507503597964
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15178893511229446182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6372880763970640048
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -6537,25 +6978,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3097518840997296951
+          1044052949699122451
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7316468186520532597
+          13975490780846913072
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
diff --git a/expectations/gm/Test-ChromeOS-Link-HD4000-x86_64-Debug/expected-results.json b/expectations/gm/Test-ChromeOS-Link-HD4000-x86_64-Debug/expected-results.json
index e448f22..c99f0af 100644
--- a/expectations/gm/Test-ChromeOS-Link-HD4000-x86_64-Debug/expected-results.json
+++ b/expectations/gm/Test-ChromeOS-Link-HD4000-x86_64-Debug/expected-results.json
@@ -138,29 +138,23 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
+    "astcbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864700347231029854
+          7296080463405164282
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "bicubicfilter_8888.png": {
+    "astcbitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10469536215464879914
+          7104155647358997780
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
@@ -328,7 +322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12733412592393621295
+          14933947455022207810
         ]
       ], 
       "reviewed-by-human": true
@@ -337,7 +331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5946418223481278362
+          9429397631137042338
         ]
       ], 
       "reviewed-by-human": true
@@ -1345,6 +1339,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -1459,6 +1471,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -1931,19 +1961,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4055619075226987340
+          4365324358071647520
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4557992853592297566
+          5614484684548433583
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -2081,97 +2111,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10068837538312183953
+          4122573986499083629
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10016521496433115213
+          17811514544878557690
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7464499056519654703
+          10785291306759230388
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15332578859151090320
+          12746992454674933423
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8965480679282112778
+          579801054003976645
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2304893413235782801
+          10391939239471720359
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6227016395519002875
+          14514750372511820
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1986132516951273797
+          6593314678375567465
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "composeshader_565.png": {
       "allowed-digests": [
@@ -2213,19 +2219,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16287621504408228135
+          1925435588931099227
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13751296096684188541
+          8932658893921139420
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -2279,13 +2285,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6518663564051896723
+          4473716651631484322
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -2303,13 +2306,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10821558801204565074
+          1408988420258361261
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -2441,13 +2441,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3270902242322559127
+          17607805564534773069
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -2483,55 +2480,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14315484682760036965
+          15939998926969705592
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10723174703710553903
+          8936909783553541695
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -2540,7 +2525,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -2549,79 +2534,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -2630,7 +2597,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -2639,79 +2606,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1530707512178085561
+          10271058086783546999
         ]
       ], 
       "reviewed-by-human": true
@@ -2720,7 +2669,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          980323142529009371
+          3142498189590007725
         ]
       ], 
       "reviewed-by-human": true
@@ -2729,85 +2678,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17548929630775824590
+          6313179153663796686
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11976677741164833714
+          2585068771325704109
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5571304773194307139
+          1246435018882871242
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7809896048824512616
+          12649783538704748585
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11148261353425501841
+          9062603587929076887
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17036053137930953952
+          8795270385167261268
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          5064010763405785676
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -2825,13 +2753,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12296443715875078696
+          572931968259377616
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -2849,25 +2774,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4566318301688711976
+          16929342067451720663
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13845187347141053231
+          10521895959783131624
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_565.png": {
       "allowed-digests": [
@@ -2907,13 +2826,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17410878668100321713
+          13415547801707026682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -2999,6 +2915,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3117,7 +3051,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176401027747712373
+          5309891953138315298
         ]
       ], 
       "reviewed-by-human": true
@@ -3126,7 +3060,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11272179801264636450
+          14526840074449574066
         ]
       ], 
       "reviewed-by-human": true
@@ -3135,7 +3069,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15198871804360226443
+          9215723161792449926
         ]
       ], 
       "reviewed-by-human": true
@@ -3144,7 +3078,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7856045684728929971
+          2392355743669508205
         ]
       ], 
       "reviewed-by-human": true
@@ -3153,7 +3087,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16978450773511607710
+          1922439110496083683
         ]
       ], 
       "reviewed-by-human": true
@@ -3162,7 +3096,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6278595518621591608
+          13421806279953941280
         ]
       ], 
       "reviewed-by-human": true
@@ -3171,7 +3105,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6269581803563312235
+          8653581790829574678
         ]
       ], 
       "reviewed-by-human": true
@@ -3180,7 +3114,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7534215132153111580
+          14304360467166489415
         ]
       ], 
       "reviewed-by-human": true
@@ -3189,7 +3123,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12343046498140718348
+          11315694301382876090
         ]
       ], 
       "reviewed-by-human": true
@@ -3198,7 +3132,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6345971390397937472
+          17952171829995911009
         ]
       ], 
       "reviewed-by-human": true
@@ -3207,7 +3141,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4168067701806693625
+          3827095505720286728
         ]
       ], 
       "reviewed-by-human": true
@@ -3216,7 +3150,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17172040454616353959
+          3962214001616470324
         ]
       ], 
       "reviewed-by-human": true
@@ -3225,7 +3159,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12020342225442211019
+          4499532536817155763
         ]
       ], 
       "reviewed-by-human": true
@@ -3234,7 +3168,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15486455585945174582
+          2532277191814352883
         ]
       ], 
       "reviewed-by-human": true
@@ -3243,7 +3177,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1349764396121687334
+          9675188186932125398
         ]
       ], 
       "reviewed-by-human": true
@@ -3252,7 +3186,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13512793178880974830
+          252003960684820363
         ]
       ], 
       "reviewed-by-human": true
@@ -3261,7 +3195,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7087467719445182209
+          1555493983183157774
         ]
       ], 
       "reviewed-by-human": true
@@ -3270,7 +3204,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13702064810817834637
+          9578858996653266547
         ]
       ], 
       "reviewed-by-human": true
@@ -3297,7 +3231,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15599673700324610016
+          7328053965687721632
         ]
       ], 
       "reviewed-by-human": true
@@ -3306,7 +3240,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5268278487198498347
+          7059435553345332705
         ]
       ], 
       "reviewed-by-human": true
@@ -3315,7 +3249,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11806976191031241103
+          3804640520733771646
         ]
       ], 
       "reviewed-by-human": true
@@ -3324,7 +3258,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          918886233658089924
+          13707324402683023381
         ]
       ], 
       "reviewed-by-human": true
@@ -3333,7 +3267,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7434001392388078060
+          12324512178840694333
         ]
       ], 
       "reviewed-by-human": true
@@ -3342,7 +3276,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17118176660803708231
+          14730292237998012820
         ]
       ], 
       "reviewed-by-human": true
@@ -3351,7 +3285,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15525976297289272494
+          11765573650955780488
         ]
       ], 
       "reviewed-by-human": true
@@ -3360,58 +3294,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14749187943288137284
+          3373929960089483036
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11155802316895019081
+          3107305384935863757
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4456781603336379072
+          12311346928809779354
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          6338121414979628929
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          2548288105368098781
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -3431,17 +3371,32 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1492550562662371249
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1451871976526159345
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13816344334579959610
+          1885470002978941560
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -3767,6 +3722,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14725946082527122548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1970752919594322242
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14000000175854108187
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16484158412400378838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5738923741860091972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4139252971218166703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6780742014081653195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17328318429823679802
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14464249100640346115
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8126556954709394782
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5738923741860091972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4139252971218166703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13815629778380581120
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17078460818277377725
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15002961101914920583
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1699653212169289473
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -3969,7 +4068,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          10887305247691796896
         ]
       ], 
       "reviewed-by-human": true
@@ -3987,25 +4086,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14815619054047376737
+          5025305727406958156
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1691062541253205748
+          15612462860180208512
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -4115,35 +4208,47 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6174753214922676017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14386872466540604812
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2501247263900090221
+          9151992564279761362
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17338444569500642489
+          1484908596766764778
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7047160218840827662
+          11578047827687176535
         ]
       ], 
       "reviewed-by-human": true
@@ -4152,7 +4257,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3219790507750540513
+          9753979676410027445
         ]
       ], 
       "reviewed-by-human": true
@@ -4283,41 +4388,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18066506753999183497
+          7955099457759770546
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11982781292527727120
+          6913141539607550299
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_565.png": {
       "allowed-digests": [
@@ -4473,13 +4574,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4316780454237822885
+          9378058285900148337
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -4497,13 +4595,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11315452322479838543
+          7959551695024800866
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -4561,25 +4656,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17681274672761086257
+          14870126594662014966
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10222071295493882388
+          4143151400782668729
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -4737,6 +4826,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -4825,17 +5094,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3512281410281869464
+          16387093217215132664
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1569508413774938590
+          11363954745247829087
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -4885,6 +5156,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -5066,7 +5373,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -5075,11 +5382,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -5096,6 +5421,24 @@
         ]
       ]
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -5114,6 +5457,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5142,7 +5503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61607569459068318
+          6869421870530403934
         ]
       ], 
       "reviewed-by-human": true
@@ -5151,7 +5512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3695817156238720886
+          922181716107376654
         ]
       ], 
       "reviewed-by-human": true
@@ -5178,13 +5539,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8548116805903985121
+          2853960147093856126
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -5202,13 +5560,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13326304985990194555
+          15351687325140125092
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -5626,7 +5981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8189097946205624269
+          12616649673148243944
         ]
       ], 
       "reviewed-by-human": true
@@ -5635,7 +5990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13641016986377676105
+          16183462849525299755
         ]
       ], 
       "reviewed-by-human": true
@@ -5653,7 +6008,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12300021040423412330
+          4978564899265777194
         ]
       ], 
       "reviewed-by-human": true
@@ -5662,7 +6017,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4063155744015088621
+          13017143225617973072
         ]
       ], 
       "reviewed-by-human": true
@@ -5921,25 +6276,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10578477976307184622
+          253131715823163995
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8347094436302455537
+          7617296157433611704
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -6101,7 +6450,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864788083336423375
+          330942250169968308
         ]
       ], 
       "reviewed-by-human": true
@@ -6110,7 +6459,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7463337896229207134
+          7668062252694178795
         ]
       ], 
       "reviewed-by-human": true
@@ -6163,6 +6512,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11990750039619298194
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3499763660998801760
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -6239,17 +6606,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15337196922136784147
+          1211749665346933897
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          595779208369948227
+          4086269437985502628
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -6437,6 +6806,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13819134465309978660
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11544526722524785606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          366412474691268411
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2883817717015897758
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1259588124280752477
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10575467507503597964
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15178893511229446182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6372880763970640048
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -6531,25 +6972,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3097518840997296951
+          1044052949699122451
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7316468186520532597
+          13975490780846913072
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
diff --git a/expectations/gm/Test-ChromeOS-Link-HD4000-x86_64-Release/expected-results.json b/expectations/gm/Test-ChromeOS-Link-HD4000-x86_64-Release/expected-results.json
index e448f22..c99f0af 100644
--- a/expectations/gm/Test-ChromeOS-Link-HD4000-x86_64-Release/expected-results.json
+++ b/expectations/gm/Test-ChromeOS-Link-HD4000-x86_64-Release/expected-results.json
@@ -138,29 +138,23 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
+    "astcbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864700347231029854
+          7296080463405164282
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "bicubicfilter_8888.png": {
+    "astcbitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10469536215464879914
+          7104155647358997780
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
@@ -328,7 +322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12733412592393621295
+          14933947455022207810
         ]
       ], 
       "reviewed-by-human": true
@@ -337,7 +331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5946418223481278362
+          9429397631137042338
         ]
       ], 
       "reviewed-by-human": true
@@ -1345,6 +1339,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -1459,6 +1471,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -1931,19 +1961,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4055619075226987340
+          4365324358071647520
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4557992853592297566
+          5614484684548433583
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -2081,97 +2111,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10068837538312183953
+          4122573986499083629
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10016521496433115213
+          17811514544878557690
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7464499056519654703
+          10785291306759230388
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15332578859151090320
+          12746992454674933423
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8965480679282112778
+          579801054003976645
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2304893413235782801
+          10391939239471720359
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6227016395519002875
+          14514750372511820
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1986132516951273797
+          6593314678375567465
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "composeshader_565.png": {
       "allowed-digests": [
@@ -2213,19 +2219,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16287621504408228135
+          1925435588931099227
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13751296096684188541
+          8932658893921139420
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -2279,13 +2285,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6518663564051896723
+          4473716651631484322
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -2303,13 +2306,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10821558801204565074
+          1408988420258361261
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -2441,13 +2441,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3270902242322559127
+          17607805564534773069
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -2483,55 +2480,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14315484682760036965
+          15939998926969705592
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10723174703710553903
+          8936909783553541695
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -2540,7 +2525,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -2549,79 +2534,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -2630,7 +2597,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -2639,79 +2606,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1530707512178085561
+          10271058086783546999
         ]
       ], 
       "reviewed-by-human": true
@@ -2720,7 +2669,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          980323142529009371
+          3142498189590007725
         ]
       ], 
       "reviewed-by-human": true
@@ -2729,85 +2678,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17548929630775824590
+          6313179153663796686
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11976677741164833714
+          2585068771325704109
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5571304773194307139
+          1246435018882871242
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7809896048824512616
+          12649783538704748585
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11148261353425501841
+          9062603587929076887
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17036053137930953952
+          8795270385167261268
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          5064010763405785676
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -2825,13 +2753,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12296443715875078696
+          572931968259377616
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -2849,25 +2774,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4566318301688711976
+          16929342067451720663
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13845187347141053231
+          10521895959783131624
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_565.png": {
       "allowed-digests": [
@@ -2907,13 +2826,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17410878668100321713
+          13415547801707026682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -2999,6 +2915,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -3117,7 +3051,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176401027747712373
+          5309891953138315298
         ]
       ], 
       "reviewed-by-human": true
@@ -3126,7 +3060,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11272179801264636450
+          14526840074449574066
         ]
       ], 
       "reviewed-by-human": true
@@ -3135,7 +3069,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15198871804360226443
+          9215723161792449926
         ]
       ], 
       "reviewed-by-human": true
@@ -3144,7 +3078,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7856045684728929971
+          2392355743669508205
         ]
       ], 
       "reviewed-by-human": true
@@ -3153,7 +3087,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16978450773511607710
+          1922439110496083683
         ]
       ], 
       "reviewed-by-human": true
@@ -3162,7 +3096,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6278595518621591608
+          13421806279953941280
         ]
       ], 
       "reviewed-by-human": true
@@ -3171,7 +3105,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6269581803563312235
+          8653581790829574678
         ]
       ], 
       "reviewed-by-human": true
@@ -3180,7 +3114,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7534215132153111580
+          14304360467166489415
         ]
       ], 
       "reviewed-by-human": true
@@ -3189,7 +3123,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12343046498140718348
+          11315694301382876090
         ]
       ], 
       "reviewed-by-human": true
@@ -3198,7 +3132,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6345971390397937472
+          17952171829995911009
         ]
       ], 
       "reviewed-by-human": true
@@ -3207,7 +3141,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4168067701806693625
+          3827095505720286728
         ]
       ], 
       "reviewed-by-human": true
@@ -3216,7 +3150,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17172040454616353959
+          3962214001616470324
         ]
       ], 
       "reviewed-by-human": true
@@ -3225,7 +3159,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12020342225442211019
+          4499532536817155763
         ]
       ], 
       "reviewed-by-human": true
@@ -3234,7 +3168,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15486455585945174582
+          2532277191814352883
         ]
       ], 
       "reviewed-by-human": true
@@ -3243,7 +3177,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1349764396121687334
+          9675188186932125398
         ]
       ], 
       "reviewed-by-human": true
@@ -3252,7 +3186,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13512793178880974830
+          252003960684820363
         ]
       ], 
       "reviewed-by-human": true
@@ -3261,7 +3195,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7087467719445182209
+          1555493983183157774
         ]
       ], 
       "reviewed-by-human": true
@@ -3270,7 +3204,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13702064810817834637
+          9578858996653266547
         ]
       ], 
       "reviewed-by-human": true
@@ -3297,7 +3231,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15599673700324610016
+          7328053965687721632
         ]
       ], 
       "reviewed-by-human": true
@@ -3306,7 +3240,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5268278487198498347
+          7059435553345332705
         ]
       ], 
       "reviewed-by-human": true
@@ -3315,7 +3249,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11806976191031241103
+          3804640520733771646
         ]
       ], 
       "reviewed-by-human": true
@@ -3324,7 +3258,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          918886233658089924
+          13707324402683023381
         ]
       ], 
       "reviewed-by-human": true
@@ -3333,7 +3267,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7434001392388078060
+          12324512178840694333
         ]
       ], 
       "reviewed-by-human": true
@@ -3342,7 +3276,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17118176660803708231
+          14730292237998012820
         ]
       ], 
       "reviewed-by-human": true
@@ -3351,7 +3285,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15525976297289272494
+          11765573650955780488
         ]
       ], 
       "reviewed-by-human": true
@@ -3360,58 +3294,64 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14749187943288137284
+          3373929960089483036
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11155802316895019081
+          3107305384935863757
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4456781603336379072
+          12311346928809779354
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          6338121414979628929
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          2548288105368098781
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -3431,17 +3371,32 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1492550562662371249
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1451871976526159345
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13816344334579959610
+          1885470002978941560
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -3767,6 +3722,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14725946082527122548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1970752919594322242
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14000000175854108187
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16484158412400378838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5738923741860091972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4139252971218166703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6780742014081653195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17328318429823679802
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14464249100640346115
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8126556954709394782
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5738923741860091972
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4139252971218166703
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13815629778380581120
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17078460818277377725
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15002961101914920583
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1699653212169289473
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -3969,7 +4068,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          10887305247691796896
         ]
       ], 
       "reviewed-by-human": true
@@ -3987,25 +4086,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14815619054047376737
+          5025305727406958156
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1691062541253205748
+          15612462860180208512
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -4115,35 +4208,47 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6174753214922676017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14386872466540604812
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2501247263900090221
+          9151992564279761362
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17338444569500642489
+          1484908596766764778
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7047160218840827662
+          11578047827687176535
         ]
       ], 
       "reviewed-by-human": true
@@ -4152,7 +4257,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3219790507750540513
+          9753979676410027445
         ]
       ], 
       "reviewed-by-human": true
@@ -4283,41 +4388,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18066506753999183497
+          7955099457759770546
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11982781292527727120
+          6913141539607550299
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_565.png": {
       "allowed-digests": [
@@ -4473,13 +4574,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4316780454237822885
+          9378058285900148337
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -4497,13 +4595,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11315452322479838543
+          7959551695024800866
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -4561,25 +4656,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17681274672761086257
+          14870126594662014966
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10222071295493882388
+          4143151400782668729
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -4737,6 +4826,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -4825,17 +5094,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3512281410281869464
+          16387093217215132664
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1569508413774938590
+          11363954745247829087
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -4885,6 +5156,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -5066,7 +5373,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -5075,11 +5382,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureimagefilter_565.png": {
       "allowed-digests": [
         [
@@ -5096,6 +5421,24 @@
         ]
       ]
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -5114,6 +5457,24 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -5142,7 +5503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61607569459068318
+          6869421870530403934
         ]
       ], 
       "reviewed-by-human": true
@@ -5151,7 +5512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3695817156238720886
+          922181716107376654
         ]
       ], 
       "reviewed-by-human": true
@@ -5178,13 +5539,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8548116805903985121
+          2853960147093856126
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -5202,13 +5560,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13326304985990194555
+          15351687325140125092
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -5626,7 +5981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8189097946205624269
+          12616649673148243944
         ]
       ], 
       "reviewed-by-human": true
@@ -5635,7 +5990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13641016986377676105
+          16183462849525299755
         ]
       ], 
       "reviewed-by-human": true
@@ -5653,7 +6008,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12300021040423412330
+          4978564899265777194
         ]
       ], 
       "reviewed-by-human": true
@@ -5662,7 +6017,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4063155744015088621
+          13017143225617973072
         ]
       ], 
       "reviewed-by-human": true
@@ -5921,25 +6276,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10578477976307184622
+          253131715823163995
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8347094436302455537
+          7617296157433611704
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -6101,7 +6450,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13864788083336423375
+          330942250169968308
         ]
       ], 
       "reviewed-by-human": true
@@ -6110,7 +6459,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7463337896229207134
+          7668062252694178795
         ]
       ], 
       "reviewed-by-human": true
@@ -6163,6 +6512,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11990750039619298194
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3499763660998801760
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -6239,17 +6606,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15337196922136784147
+          1211749665346933897
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          595779208369948227
+          4086269437985502628
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -6437,6 +6806,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13819134465309978660
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11544526722524785606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          366412474691268411
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2883817717015897758
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1259588124280752477
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10575467507503597964
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15178893511229446182
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6372880763970640048
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -6531,25 +6972,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3097518840997296951
+          1044052949699122451
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7316468186520532597
+          13975490780846913072
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
diff --git a/expectations/gm/Test-Linux-Bare-NoGPU-Arm8_64-Debug/expected-results.json b/expectations/gm/Test-Linux-Bare-NoGPU-Arm8_64-Debug/expected-results.json
index 70b5f5d..f9936d9 100644
--- a/expectations/gm/Test-Linux-Bare-NoGPU-Arm8_64-Debug/expected-results.json
+++ b/expectations/gm/Test-Linux-Bare-NoGPU-Arm8_64-Debug/expected-results.json
@@ -131,30 +131,6 @@
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
diff --git a/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug/expected-results.json b/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug/expected-results.json
index b44d7ad..f488ed0 100644
--- a/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug/expected-results.json
@@ -145,10 +145,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_mesa.png": {
       "allowed-digests": [
@@ -327,10 +328,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7417457142513546046
+          3445907652572728040
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_mesa.png": {
       "allowed-digests": [
@@ -410,66 +412,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -606,10 +548,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -861,7 +803,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5777018562057023640
+          5652631356520050261
         ]
       ], 
       "ignore-failure": false, 
@@ -871,7 +813,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6701475556859720248
+          18144262876994636113
         ]
       ], 
       "ignore-failure": false, 
@@ -881,7 +823,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14997372310722697089
+          17613871877893290698
         ]
       ], 
       "ignore-failure": false, 
@@ -900,7 +842,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "ignore-failure": false, 
@@ -1243,10 +1185,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4934543716979966986
+          1545238008550730369
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -3116,6 +3061,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8785380353362636115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -3567,10 +3548,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3581,6 +3562,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -5163,25 +5180,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          665168405971931025
+          9633429568143695291
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15131814227723664821
+          5242666562845939902
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9389818151389137504
+          2149195073956237149
         ]
       ], 
       "reviewed-by-human": true
@@ -5190,25 +5209,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14366060070439960096
+          7863404296805464794
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5685223049982850150
+          17368301361018793417
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1010743362306860905
+          4779757895247586098
         ]
       ], 
       "reviewed-by-human": true
@@ -5277,25 +5298,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17422205021368829610
+          9935254523116169025
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9821720789011763423
+          12331260327999412870
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1937334521609062043
+          1620979866025844094
         ]
       ], 
       "reviewed-by-human": true
@@ -5304,25 +5327,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9348026094121958314
+          9934357075027963805
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4596071658633617104
+          4890879553357259071
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11690717966306415472
+          4892109393691046331
         ]
       ], 
       "reviewed-by-human": true
@@ -5484,25 +5509,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3024253696016115783
+          14357007263288803555
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17795901728843928428
+          8402631776022957603
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722404461927006733
+          1338168398487173014
         ]
       ], 
       "reviewed-by-human": true
@@ -5511,10 +5536,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6565307449718980632
+          14616623864166698570
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -5652,10 +5677,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817811151094970149
+          5263049493635651247
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -5709,10 +5735,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17343465017084601070
+          1094986599959608344
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -5947,7 +5974,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -6032,10 +6059,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14708709892741000887
+          2043935716870585758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -6158,37 +6186,41 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8262676092064269134
+          14769785241545366124
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7134813727306880422
+          4735649758874443595
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3018678439694993490
+          9379319802824458516
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12727483994808055747
+          12298747061616734092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -6206,49 +6238,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -6971,10 +6991,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_mesa.png": {
       "allowed-digests": [
@@ -7076,28 +7097,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350004806369207576
+          3064287075142692675
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15191846232339756433
+          10762376520878409589
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932184608426865277
+          1856281286238149528
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_mesa.png": {
       "allowed-digests": [
@@ -7209,10 +7233,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8223725667898988327
+          6552828745377153692
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -8358,6 +8383,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2280319422541178486
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -8519,10 +8580,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17399714883265675846
+          5222639516687013651
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -9457,6 +9519,258 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5754720502560945124
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7011334045879187335
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8628460967635371466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17451888925266329354
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9031220353414122420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12052356451580286635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11042941222396113326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          48543321865687406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5318641665973281074
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17886210747206101484
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2634361064545893352
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9031220353414122420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12052356451580286635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11042941222396113326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8895392042474228917
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1565600920099335476
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -10043,28 +10357,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          577763867002558156
+          11205985628221530558
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3187127509363486589
+          10285466311387505594
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4683300170457454676
+          13832149431434647982
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_mesa.png": {
       "allowed-digests": [
@@ -10176,10 +10493,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -10326,34 +10644,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14629176447812511478
+          5413335793265780255
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8245731952136246044
+          10848890344958988336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11441833945311352205
+          1501592947168890373
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6881212425150993004
+          3616866535538175131
         ]
       ], 
       "reviewed-by-human": true
@@ -10362,7 +10683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8737805866501421815
+          10571786398500313895
         ]
       ], 
       "reviewed-by-human": true
@@ -10371,7 +10692,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5437813950680945839
+          5173631195162600059
         ]
       ], 
       "reviewed-by-human": true
@@ -10678,25 +10999,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -10710,37 +11034,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18398749201184065674
+          9048645334347347219
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4170254974711908124
+          11735516438606322202
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6712205253018787021
+          6630436809914720778
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -10995,13 +11310,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -11133,10 +11448,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7446798776121845780
+          17728485306935400783
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -11199,10 +11515,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6415119852357736555
+          7364313105510370410
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -11263,9 +11580,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -11329,28 +11647,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203473492631421787
+          17818187927143108856
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476847311382274456
+          11190807301117980817
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13965549836065899622
+          2386090875437968887
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_mesa.png": {
       "allowed-digests": [
@@ -11374,10 +11695,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1297122028776862965
+          4929141275269305050
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -11455,7 +11777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11512,7 +11834,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11569,7 +11891,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11653,13 +11975,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -12001,34 +12323,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4798715448524644865
+          3519930826502579748
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2800701274256052620
+          5286849848700479024
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10502438783252033586
+          7891530307203346402
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8605111114604394652
+          14215622928526214164
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12070,13 +12396,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -12151,6 +12477,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14962954696492920650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -12605,7 +12940,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -12614,7 +12949,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -12623,12 +12958,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -12793,28 +13164,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12192533791124548766
+          7598705955573369265
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1076509006514835448
+          5088246291585946445
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1558579503072776168
+          605948953793264619
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_mesa.png": {
       "allowed-digests": [
@@ -12886,10 +13260,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16317721053082477698
+          7748961206865598068
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -12943,10 +13318,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          450396981900864967
+          17355038258869709320
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -13072,10 +13448,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_mesa.png": {
       "allowed-digests": [
@@ -13798,7 +14175,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2933168279465787248
+          6329347603253038636
         ]
       ], 
       "reviewed-by-human": true
@@ -13825,7 +14202,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6619811780594584075
+          5240298026024448139
         ]
       ], 
       "reviewed-by-human": true
@@ -14062,7 +14439,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755244266552015381
+          18036393210557490316
         ]
       ], 
       "ignore-failure": false, 
@@ -14072,7 +14449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4039701180316548008
+          8029953815957055913
         ]
       ], 
       "reviewed-by-human": true
@@ -14172,7 +14549,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10091423976881850596
+          6248877619455181145
         ]
       ], 
       "ignore-failure": false, 
@@ -14182,7 +14559,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2767576208219662715
+          16711909409935915202
         ]
       ], 
       "ignore-failure": false, 
@@ -14192,7 +14569,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7715194674260336757
+          3706805872892876100
         ]
       ], 
       "ignore-failure": false, 
@@ -14872,46 +15249,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13829746709169881192
+          942384268111291460
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4911917813061003086
+          6614286442225667967
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10067541241159264052
+          6742938846486152831
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7183783733564413719
+          9791523307259089537
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -15339,7 +15708,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -15348,7 +15717,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -15357,7 +15726,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -15612,10 +15981,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -15717,34 +16086,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981207417492931405
+          12217816694960917505
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981207417492931405
+          12217816694960917505
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14783277981175726957
+          12023820251736326597
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15846,14 +16219,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6682913794993626676
+          12114185262432977992
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -15891,7 +16261,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12388512780760636683
+          15854879828764391650
         ]
       ], 
       "ignore-failure": false, 
@@ -15937,7 +16307,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12429166359100573225
+          8812521911353944523
         ]
       ], 
       "reviewed-by-human": true
@@ -16258,6 +16628,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          348413092207079170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10722724283338195300
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          30267766473840413
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          716838804598794694
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          348413092207079170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11352770692839533894
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5962540449220470246
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          716838804598794694
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3636935167937031390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7285761756469430704
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14721156579837454246
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18166683683399098682
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3636935167937031390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14364877558859916252
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13121746060825330133
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18166683683399098682
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -16485,40 +16999,40 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1665207036697331602
+          525901368556559203
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12804134340931910653
+          11438921612517607616
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8693932099695153913
+          8690743309968362323
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6646529780639572517
+          13037355755302747778
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -16554,10 +17068,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8123203123250626293
+          2579239595975804443
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-mac.png": {
       "allowed-digests": [
@@ -16647,10 +17162,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1708616588915295899
+          10041658900606708398
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_mesa.png": {
       "allowed-digests": [
@@ -16690,6 +17206,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Release/expected-results.json b/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Release/expected-results.json
index b69187f..e0271c6 100644
--- a/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Release/expected-results.json
+++ b/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Release/expected-results.json
@@ -121,10 +121,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_mesa.png": {
       "allowed-digests": [
@@ -279,10 +280,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7417457142513546046
+          3445907652572728040
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_mesa.png": {
       "allowed-digests": [
@@ -362,54 +364,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -534,10 +488,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -789,7 +743,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5777018562057023640
+          5652631356520050261
         ]
       ], 
       "ignore-failure": false, 
@@ -799,7 +753,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6701475556859720248
+          18144262876994636113
         ]
       ], 
       "ignore-failure": false, 
@@ -809,7 +763,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14997372310722697089
+          17613871877893290698
         ]
       ], 
       "ignore-failure": false, 
@@ -828,7 +782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "ignore-failure": false, 
@@ -1147,10 +1101,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4934543716979966986
+          1545238008550730369
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -2768,6 +2725,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8785380353362636115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -3171,10 +3164,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3185,6 +3178,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4587,25 +4616,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          665168405971931025
+          9633429568143695291
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15131814227723664821
+          5242666562845939902
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9389818151389137504
+          2149195073956237149
         ]
       ], 
       "reviewed-by-human": true
@@ -4614,25 +4645,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14366060070439960096
+          7863404296805464794
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5685223049982850150
+          17368301361018793417
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1010743362306860905
+          4779757895247586098
         ]
       ], 
       "reviewed-by-human": true
@@ -4701,25 +4734,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17422205021368829610
+          9935254523116169025
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9821720789011763423
+          12331260327999412870
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1937334521609062043
+          1620979866025844094
         ]
       ], 
       "reviewed-by-human": true
@@ -4728,25 +4763,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9348026094121958314
+          9934357075027963805
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4596071658633617104
+          4890879553357259071
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11690717966306415472
+          4892109393691046331
         ]
       ], 
       "reviewed-by-human": true
@@ -4896,25 +4933,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3024253696016115783
+          14357007263288803555
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17795901728843928428
+          8402631776022957603
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722404461927006733
+          1338168398487173014
         ]
       ], 
       "reviewed-by-human": true
@@ -4923,10 +4960,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6565307449718980632
+          14616623864166698570
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -5055,10 +5092,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817811151094970149
+          5263049493635651247
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -5112,10 +5150,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17343465017084601070
+          1094986599959608344
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -5338,7 +5377,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -5411,10 +5450,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14708709892741000887
+          2043935716870585758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -5537,85 +5577,77 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8262676092064269134
+          14769785241545366124
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7134813727306880422
+          4735649758874443595
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3018678439694993490
+          9379319802824458516
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12727483994808055747
+          12298747061616734092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
@@ -6254,10 +6286,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_mesa.png": {
       "allowed-digests": [
@@ -6359,28 +6392,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350004806369207576
+          3064287075142692675
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15191846232339756433
+          10762376520878409589
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932184608426865277
+          1856281286238149528
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_mesa.png": {
       "allowed-digests": [
@@ -6492,10 +6528,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8223725667898988327
+          6552828745377153692
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -7579,6 +7616,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2280319422541178486
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -7740,10 +7813,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17399714883265675846
+          5222639516687013651
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -8546,6 +8620,258 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5754720502560945124
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7011334045879187335
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8628460967635371466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17451888925266329354
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9031220353414122420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12052356451580286635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11042941222396113326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          48543321865687406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5318641665973281074
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17886210747206101484
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2634361064545893352
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9031220353414122420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12052356451580286635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11042941222396113326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8895392042474228917
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1565600920099335476
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -9096,28 +9422,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          577763867002558156
+          11205985628221530558
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3187127509363486589
+          10285466311387505594
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4683300170457454676
+          13832149431434647982
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_mesa.png": {
       "allowed-digests": [
@@ -9141,14 +9470,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9803122300416240866
+          7961471823724588641
         ]
       ], 
-      "bugs": [
-        476
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -9205,10 +9531,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -9343,34 +9670,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14629176447812511478
+          5413335793265780255
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8245731952136246044
+          10848890344958988336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11441833945311352205
+          1501592947168890373
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6881212425150993004
+          3616866535538175131
         ]
       ], 
       "reviewed-by-human": true
@@ -9379,7 +9709,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8737805866501421815
+          10571786398500313895
         ]
       ], 
       "reviewed-by-human": true
@@ -9388,7 +9718,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5437813950680945839
+          5173631195162600059
         ]
       ], 
       "reviewed-by-human": true
@@ -9671,25 +10001,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -9703,37 +10036,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18398749201184065674
+          9048645334347347219
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4170254974711908124
+          11735516438606322202
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6712205253018787021
+          6630436809914720778
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -9976,13 +10300,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -10114,10 +10438,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7446798776121845780
+          17728485306935400783
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -10180,10 +10505,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6415119852357736555
+          7364313105510370410
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -10244,9 +10570,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -10313,28 +10640,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203473492631421787
+          17818187927143108856
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476847311382274456
+          11190807301117980817
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13965549836065899622
+          2386090875437968887
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_mesa.png": {
       "allowed-digests": [
@@ -10358,10 +10688,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1297122028776862965
+          4929141275269305050
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -10439,7 +10770,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10496,7 +10827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10541,7 +10872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10625,13 +10956,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -10976,34 +11307,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4798715448524644865
+          3519930826502579748
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2800701274256052620
+          5286849848700479024
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10502438783252033586
+          7891530307203346402
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8605111114604394652
+          14215622928526214164
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -11033,13 +11368,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -11090,6 +11425,15 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14962954696492920650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -11490,7 +11834,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -11499,7 +11843,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -11508,12 +11852,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -11654,28 +12034,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12192533791124548766
+          7598705955573369265
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1076509006514835448
+          5088246291585946445
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1558579503072776168
+          605948953793264619
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_mesa.png": {
       "allowed-digests": [
@@ -11747,10 +12130,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16317721053082477698
+          7748961206865598068
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -11804,10 +12188,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          450396981900864967
+          17355038258869709320
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -11921,10 +12306,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_mesa.png": {
       "allowed-digests": [
@@ -12588,7 +12974,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2933168279465787248
+          6329347603253038636
         ]
       ], 
       "reviewed-by-human": true
@@ -12615,7 +13001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6619811780594584075
+          5240298026024448139
         ]
       ], 
       "reviewed-by-human": true
@@ -12816,7 +13202,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755244266552015381
+          18036393210557490316
         ]
       ], 
       "ignore-failure": false, 
@@ -12826,7 +13212,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4039701180316548008
+          8029953815957055913
         ]
       ], 
       "reviewed-by-human": true
@@ -12926,7 +13312,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10091423976881850596
+          6248877619455181145
         ]
       ], 
       "ignore-failure": false, 
@@ -12936,7 +13322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2767576208219662715
+          16711909409935915202
         ]
       ], 
       "ignore-failure": false, 
@@ -12946,7 +13332,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7715194674260336757
+          3706805872892876100
         ]
       ], 
       "ignore-failure": false, 
@@ -13554,46 +13940,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13829746709169881192
+          942384268111291460
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4911917813061003086
+          6614286442225667967
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10067541241159264052
+          6742938846486152831
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7183783733564413719
+          9791523307259089537
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -13973,7 +14351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -13982,7 +14360,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -13991,7 +14369,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -14234,10 +14612,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -14339,34 +14717,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981207417492931405
+          12217816694960917505
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981207417492931405
+          12217816694960917505
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14783277981175726957
+          12023820251736326597
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -14512,7 +14894,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12388512780760636683
+          15854879828764391650
         ]
       ], 
       "ignore-failure": false, 
@@ -14558,7 +14940,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12429166359100573225
+          8812521911353944523
         ]
       ], 
       "reviewed-by-human": true
@@ -14843,6 +15225,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          348413092207079170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10722724283338195300
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          30267766473840413
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          716838804598794694
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          348413092207079170
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11352770692839533894
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5962540449220470246
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          716838804598794694
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3636935167937031390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7285761756469430704
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14721156579837454246
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18166683683399098682
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3636935167937031390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14364877558859916252
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13121746060825330133
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18166683683399098682
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -15061,40 +15587,40 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1665207036697331602
+          525901368556559203
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12804134340931910653
+          11438921612517607616
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8693932099695153913
+          8690743309968362323
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6646529780639572517
+          13037355755302747778
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15130,10 +15656,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8123203123250626293
+          2579239595975804443
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-mac.png": {
       "allowed-digests": [
@@ -15223,10 +15750,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1708616588915295899
+          10041658900606708398
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_mesa.png": {
       "allowed-digests": [
@@ -15266,6 +15794,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json b/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json
index 40edb90..8f4001c 100644
--- a/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json
+++ b/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json
@@ -145,10 +145,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_mesa.png": {
       "allowed-digests": [
@@ -327,10 +328,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7417457142513546046
+          3445907652572728040
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_mesa.png": {
       "allowed-digests": [
@@ -371,6 +373,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -410,66 +448,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -606,10 +584,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -861,7 +839,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5777018562057023640
+          5652631356520050261
         ]
       ], 
       "ignore-failure": false, 
@@ -871,7 +849,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6701475556859720248
+          18144262876994636113
         ]
       ], 
       "ignore-failure": false, 
@@ -881,7 +859,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14997372310722697089
+          17613871877893290698
         ]
       ], 
       "ignore-failure": false, 
@@ -900,7 +878,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "ignore-failure": false, 
@@ -1243,10 +1221,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4934543716979966986
+          1545238008550730369
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -3116,6 +3097,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8785380353362636115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -3567,10 +3584,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3581,6 +3598,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -5163,25 +5216,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          665168405971931025
+          9633429568143695291
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15131814227723664821
+          5242666562845939902
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9389818151389137504
+          2149195073956237149
         ]
       ], 
       "reviewed-by-human": true
@@ -5190,25 +5245,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14366060070439960096
+          7863404296805464794
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5685223049982850150
+          17368301361018793417
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1010743362306860905
+          4779757895247586098
         ]
       ], 
       "reviewed-by-human": true
@@ -5277,25 +5334,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17422205021368829610
+          9935254523116169025
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9821720789011763423
+          12331260327999412870
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1937334521609062043
+          1620979866025844094
         ]
       ], 
       "reviewed-by-human": true
@@ -5304,25 +5363,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9348026094121958314
+          9934357075027963805
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4596071658633617104
+          4890879553357259071
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11690717966306415472
+          4892109393691046331
         ]
       ], 
       "reviewed-by-human": true
@@ -5484,25 +5545,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17255800637930023618
+          4129093513008291925
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6129480582617306932
+          3489663057389836029
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721985909153986241
+          6239050768846819411
         ]
       ], 
       "reviewed-by-human": true
@@ -5511,10 +5572,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8677782814211184228
+          1213518350448964928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -5652,10 +5713,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817811151094970149
+          5263049493635651247
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -5709,10 +5771,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17343465017084601070
+          1094986599959608344
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -5947,7 +6010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -6032,10 +6095,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14708709892741000887
+          2043935716870585758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -6158,37 +6222,41 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8262676092064269134
+          14769785241545366124
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7134813727306880422
+          4735649758874443595
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3018678439694993490
+          9379319802824458516
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12727483994808055747
+          12298747061616734092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -6206,49 +6274,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -6266,7 +6322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -6275,7 +6331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -6284,7 +6340,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
       "reviewed-by-human": true
@@ -6293,13 +6349,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6317,49 +6370,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2519050949583701818
+          5976613545322007809
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6377,49 +6418,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6437,49 +6466,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12455652221971736296
+          8380951080763030595
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6497,7 +6514,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -6506,7 +6523,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -6515,7 +6532,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
       "reviewed-by-human": true
@@ -6524,13 +6541,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6548,49 +6562,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4878087893157172610
+          17064895090763866225
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6608,49 +6610,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6668,49 +6658,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6155554109563033370
+          2065497081829583993
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6728,7 +6706,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5919915105268875757
+          12458415807323245880
         ]
       ], 
       "reviewed-by-human": true
@@ -6737,7 +6715,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13928185901657589056
+          16590667623672359983
         ]
       ], 
       "reviewed-by-human": true
@@ -6746,7 +6724,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17488622437035947581
+          4664354702478074573
         ]
       ], 
       "reviewed-by-human": true
@@ -6755,13 +6733,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10111800974903191139
+          7403302388657572158
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6779,31 +6754,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4352290332792222875
+          13916429574877477104
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12272133695305984693
+          17648707419813124347
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185164918568866102
+          17107553478662989560
         ]
       ], 
       "reviewed-by-human": true
@@ -6812,13 +6781,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10111800974903191139
+          7403302388657572158
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6836,31 +6802,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1122113892427574737
+          13397135280020812368
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13130982919481452930
+          16722260883232812682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17488622437035947581
+          4664354702478074573
         ]
       ], 
       "reviewed-by-human": true
@@ -6869,13 +6829,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10111800974903191139
+          7403302388657572158
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6893,49 +6850,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7326062217379727899
+          9742232829834221657
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16629084369127295061
+          6138409041841752826
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9183707564290546529
+          2860000284724465188
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10111800974903191139
+          7403302388657572158
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6953,10 +6898,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -6971,10 +6917,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_mesa.png": {
       "allowed-digests": [
@@ -7010,10 +6957,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4129679964321889985
+          6591173699928884438
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -7076,28 +7024,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350004806369207576
+          3064287075142692675
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15191846232339756433
+          10762376520878409589
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932184608426865277
+          1856281286238149528
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_mesa.png": {
       "allowed-digests": [
@@ -7201,10 +7152,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8223725667898988327
+          6552828745377153692
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -7398,6 +7350,45 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12376274542774427561
+        ]
+      ], 
+      "bugs": [
+        2832
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -7696,7 +7687,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -7705,7 +7696,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -7743,7 +7734,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -7752,7 +7743,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -7790,7 +7781,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -7799,7 +7790,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -7837,7 +7828,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -7846,7 +7837,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -7884,7 +7875,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -7893,7 +7884,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -7931,7 +7922,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15123141881758046683
+          4863848110543323757
         ]
       ], 
       "reviewed-by-human": true
@@ -7940,7 +7931,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120268963253281049
+          15875870232997232472
         ]
       ], 
       "reviewed-by-human": true
@@ -7978,7 +7969,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15307161886299199412
+          2346105604879341495
         ]
       ], 
       "reviewed-by-human": true
@@ -7987,7 +7978,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14376175129664776793
+          12823183142873462143
         ]
       ], 
       "reviewed-by-human": true
@@ -8025,7 +8016,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14168263863081771415
+          4142499014663782701
         ]
       ], 
       "reviewed-by-human": true
@@ -8034,7 +8025,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12278150292542285269
+          3606589379053873513
         ]
       ], 
       "reviewed-by-human": true
@@ -8072,7 +8063,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13045887677262062075
+          16405981284469235830
         ]
       ], 
       "reviewed-by-human": true
@@ -8081,7 +8072,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4995388855933583287
+          12497281568611526356
         ]
       ], 
       "reviewed-by-human": true
@@ -8166,7 +8157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12648193441807138871
+          11989990309095001939
         ]
       ], 
       "reviewed-by-human": true
@@ -8175,7 +8166,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3330948725703968729
+          7077203408218534481
         ]
       ], 
       "reviewed-by-human": true
@@ -8260,7 +8251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7152746370488611708
+          15598193008092032806
         ]
       ], 
       "reviewed-by-human": true
@@ -8269,7 +8260,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13910449030103127310
+          1172945633876564106
         ]
       ], 
       "reviewed-by-human": true
@@ -8307,7 +8298,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8932070407012852288
+          14463101894225022814
         ]
       ], 
       "reviewed-by-human": true
@@ -8316,7 +8307,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1464369534918103055
+          9489745336011434546
         ]
       ], 
       "reviewed-by-human": true
@@ -8350,6 +8341,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17052873949347861482
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -8366,37 +8393,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15257991883133124567
+          14104970488407444996
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3318990240647055550
+          3344183342766821772
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11229329600143623486
+          18096382468661734181
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
@@ -8507,14 +8525,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10071169096365666576
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8168125816284503355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11224636278170507808
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14095919809525179386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17399714883265675846
+          5222639516687013651
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -9449,6 +9504,294 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2902090852508957882
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7011334045879187335
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8628460967635371466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10605891769253668365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9031220353414122420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12052356451580286635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11042941222396113326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          48543321865687406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6265215811237278554
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17886210747206101484
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18402865251623653419
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9031220353414122420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12052356451580286635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11042941222396113326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8895392042474228917
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17537945578842671855
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2756771085785913839
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12370407365013342828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7298563598521283160
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7203144125028809771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -9480,10 +9823,7 @@
           7829581953999677788
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-mac.png": {
       "allowed-digests": [
@@ -9591,7 +9931,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-mac.png": {
       "allowed-digests": [
@@ -9627,7 +9967,7 @@
           1906077521761566198
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-mac.png": {
       "allowed-digests": [
@@ -9663,7 +10003,7 @@
           14730655713673397636
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-mac.png": {
       "allowed-digests": [
@@ -9966,7 +10306,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "ignore-failure": false, 
@@ -10035,19 +10375,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          577763867002558156
+          10270350534543045024
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3187127509363486589
+          2613292064298616534
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -10056,7 +10398,8 @@
           4683300170457454676
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_mesa.png": {
       "allowed-digests": [
@@ -10168,55 +10511,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4828006313825982924
+          11711016279383188197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6750687666132142674
+          14807718233642576408
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10123948872601300376
+          3542250264918452791
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          407851636120283393
+          5100778197484655594
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10314,38 +10650,77 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9608958026324610750
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1072398151931745130
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11678564671792396439
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8212424581111328793
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2876569939983437533
+          10195286292611262483
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15008759050710746276
+          12868682869175428478
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7259230266720940868
+          2073846486723560683
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15367863860544360168
+          4489720002158860293
         ]
       ], 
       "reviewed-by-human": true
@@ -10354,7 +10729,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7896644149102272693
+          4139022765641862285
         ]
       ], 
       "reviewed-by-human": true
@@ -10363,7 +10738,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8938101494310557817
+          14016676347560822434
         ]
       ], 
       "reviewed-by-human": true
@@ -10670,25 +11045,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -10702,37 +11080,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1232053320656860839
+          3420294909331584076
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17532019165080555635
+          17015627783817350285
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5846645600592968591
+          18441723233217074975
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -10987,13 +11356,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -11125,10 +11494,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7446798776121845780
+          17728485306935400783
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -11191,10 +11561,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6415119852357736555
+          7364313105510370410
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -11255,9 +11626,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -11321,28 +11693,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203473492631421787
+          6004390302197575342
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476847311382274456
+          14086868980283597197
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13965549836065899622
+          4862350907741833412
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_mesa.png": {
       "allowed-digests": [
@@ -11366,10 +11741,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1297122028776862965
+          9542015800753453668
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -11447,7 +11823,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11504,7 +11880,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11561,7 +11937,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11645,13 +12021,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -11734,6 +12110,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712923251277710326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4443863184936217029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10033547804616068548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4381959501339171759
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3873095513352910051
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8759449444261779571
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7450316469051364550
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18104149097289142823
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6609016078678717837
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16356648792486681056
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -11993,34 +12729,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4798715448524644865
+          3519930826502579748
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2800701274256052620
+          5286849848700479024
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10502438783252033586
+          7891530307203346402
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8605111114604394652
+          14215622928526214164
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12062,13 +12802,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -12143,6 +12883,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          526671347486000095
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          315162850214656667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          834353666864975522
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          736103432728252861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -12597,7 +13409,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -12606,7 +13418,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -12615,12 +13427,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -12678,6 +13526,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6108713926578393015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -12714,6 +13598,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -12785,28 +13705,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12192533791124548766
+          7598705955573369265
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1076509006514835448
+          5088246291585946445
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1558579503072776168
+          605948953793264619
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_mesa.png": {
       "allowed-digests": [
@@ -12878,10 +13801,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16317721053082477698
+          7748961206865598068
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -12935,10 +13859,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          450396981900864967
+          17355038258869709320
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -13064,10 +13989,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_mesa.png": {
       "allowed-digests": [
@@ -13790,7 +14716,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2933168279465787248
+          6329347603253038636
         ]
       ], 
       "reviewed-by-human": true
@@ -13817,7 +14743,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6619811780594584075
+          5240298026024448139
         ]
       ], 
       "reviewed-by-human": true
@@ -14054,7 +14980,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13040178079167757885
+          2118593831950610510
         ]
       ], 
       "ignore-failure": false, 
@@ -14064,7 +14990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8388233011720328513
+          7243535253056860916
         ]
       ], 
       "reviewed-by-human": true
@@ -14104,7 +15030,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9925437062346155958
+          3888857556865804716
         ]
       ], 
       "ignore-failure": false, 
@@ -14164,7 +15090,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10091423976881850596
+          6248877619455181145
         ]
       ], 
       "ignore-failure": false, 
@@ -14174,7 +15100,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2767576208219662715
+          16711909409935915202
         ]
       ], 
       "ignore-failure": false, 
@@ -14184,7 +15110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7715194674260336757
+          3706805872892876100
         ]
       ], 
       "ignore-failure": false, 
@@ -14864,46 +15790,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13829746709169881192
+          942384268111291460
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4911917813061003086
+          6614286442225667967
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10067541241159264052
+          6742938846486152831
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7183783733564413719
+          9791523307259089537
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -15331,7 +16249,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -15340,7 +16258,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -15349,7 +16267,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -15543,6 +16461,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          603367086804693806
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14530465982360073720
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16412446230659551733
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13906484169395459506
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -15604,10 +16558,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -15634,7 +16588,8 @@
           17501446579955337831
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-mac.png": {
       "allowed-digests": [
@@ -15682,7 +16637,8 @@
           14626919895309756138
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-mac.png": {
       "allowed-digests": [
@@ -15709,34 +16665,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981207417492931405
+          12217816694960917505
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981207417492931405
+          12217816694960917505
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14783277981175726957
+          12023820251736326597
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15882,7 +16842,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12388512780760636683
+          15854879828764391650
         ]
       ], 
       "ignore-failure": false, 
@@ -15928,7 +16888,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12429166359100573225
+          8812521911353944523
         ]
       ], 
       "reviewed-by-human": true
@@ -16249,6 +17209,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          176643172050242146
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2948157242638756753
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1308589864172522587
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5334307329064438746
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          176643172050242146
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16691134947101004308
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4130029465199010076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5334307329064438746
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11722569971661041791
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2459536250875419508
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2634998542277034848
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1067219044543347512
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11722569971661041791
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12778609035830803381
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11630855191271740654
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1067219044543347512
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -16476,40 +17580,40 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1665207036697331602
+          525901368556559203
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12804134340931910653
+          11438921612517607616
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8693932099695153913
+          8690743309968362323
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6646529780639572517
+          13037355755302747778
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -16545,10 +17649,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8123203123250626293
+          2579239595975804443
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-mac.png": {
       "allowed-digests": [
@@ -16638,10 +17743,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1708616588915295899
+          10041658900606708398
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_mesa.png": {
       "allowed-digests": [
@@ -16681,6 +17787,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json b/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json
index 1c93158..d527455 100644
--- a/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json
+++ b/expectations/gm/Test-Mac10.6-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json
@@ -121,10 +121,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_mesa.png": {
       "allowed-digests": [
@@ -267,10 +268,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7417457142513546046
+          3445907652572728040
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_mesa.png": {
       "allowed-digests": [
@@ -311,6 +313,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -350,54 +388,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -510,10 +500,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -729,7 +719,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5777018562057023640
+          5652631356520050261
         ]
       ], 
       "ignore-failure": false, 
@@ -739,7 +729,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6701475556859720248
+          18144262876994636113
         ]
       ], 
       "ignore-failure": false, 
@@ -749,7 +739,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14997372310722697089
+          17613871877893290698
         ]
       ], 
       "ignore-failure": false, 
@@ -768,7 +758,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "ignore-failure": false, 
@@ -1063,10 +1053,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4934543716979966986
+          1545238008550730369
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -2480,6 +2473,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8785380353362636115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -2883,10 +2912,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -2897,6 +2926,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4239,25 +4304,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          665168405971931025
+          9633429568143695291
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15131814227723664821
+          5242666562845939902
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9389818151389137504
+          2149195073956237149
         ]
       ], 
       "reviewed-by-human": true
@@ -4266,25 +4333,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14366060070439960096
+          7863404296805464794
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5685223049982850150
+          17368301361018793417
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1010743362306860905
+          4779757895247586098
         ]
       ], 
       "reviewed-by-human": true
@@ -4353,25 +4422,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17422205021368829610
+          9935254523116169025
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9821720789011763423
+          12331260327999412870
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1937334521609062043
+          1620979866025844094
         ]
       ], 
       "reviewed-by-human": true
@@ -4380,25 +4451,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9348026094121958314
+          9934357075027963805
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4596071658633617104
+          4890879553357259071
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11690717966306415472
+          4892109393691046331
         ]
       ], 
       "reviewed-by-human": true
@@ -4548,25 +4621,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17255800637930023618
+          4129093513008291925
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6129480582617306932
+          3489663057389836029
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721985909153986241
+          6239050768846819411
         ]
       ], 
       "reviewed-by-human": true
@@ -4575,10 +4648,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8677782814211184228
+          1213518350448964928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -4707,10 +4780,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13817811151094970149
+          5263049493635651247
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -4764,10 +4838,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17343465017084601070
+          1094986599959608344
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -4966,7 +5041,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -5039,10 +5114,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14708709892741000887
+          2043935716870585758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -5161,91 +5237,83 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8262676092064269134
+          14769785241545366124
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7134813727306880422
+          4735649758874443595
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3018678439694993490
+          9379319802824458516
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12727483994808055747
+          12298747061616734092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -5254,7 +5322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -5263,7 +5331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
       "reviewed-by-human": true
@@ -5272,163 +5340,124 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2519050949583701818
+          5976613545322007809
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12455652221971736296
+          8380951080763030595
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -5437,7 +5466,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -5446,7 +5475,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
       "reviewed-by-human": true
@@ -5455,13 +5484,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5479,49 +5505,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4878087893157172610
+          17064895090763866225
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5539,49 +5553,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5599,49 +5601,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6155554109563033370
+          2065497081829583993
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5659,7 +5649,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5919915105268875757
+          12458415807323245880
         ]
       ], 
       "reviewed-by-human": true
@@ -5668,7 +5658,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13928185901657589056
+          16590667623672359983
         ]
       ], 
       "reviewed-by-human": true
@@ -5677,7 +5667,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17488622437035947581
+          4664354702478074573
         ]
       ], 
       "reviewed-by-human": true
@@ -5686,13 +5676,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10111800974903191139
+          7403302388657572158
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5710,31 +5697,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4352290332792222875
+          13916429574877477104
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12272133695305984693
+          17648707419813124347
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185164918568866102
+          17107553478662989560
         ]
       ], 
       "reviewed-by-human": true
@@ -5743,13 +5724,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10111800974903191139
+          7403302388657572158
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5767,31 +5745,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1122113892427574737
+          13397135280020812368
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13130982919481452930
+          16722260883232812682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17488622437035947581
+          4664354702478074573
         ]
       ], 
       "reviewed-by-human": true
@@ -5800,13 +5772,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10111800974903191139
+          7403302388657572158
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5824,49 +5793,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7326062217379727899
+          9742232829834221657
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16629084369127295061
+          6138409041841752826
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9183707564290546529
+          2860000284724465188
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10111800974903191139
+          7403302388657572158
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5884,10 +5841,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5902,10 +5860,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_mesa.png": {
       "allowed-digests": [
@@ -5929,10 +5888,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4129679964321889985
+          6591173699928884438
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -5983,28 +5943,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350004806369207576
+          3064287075142692675
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15191846232339756433
+          10762376520878409589
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932184608426865277
+          1856281286238149528
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_mesa.png": {
       "allowed-digests": [
@@ -6116,10 +6079,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8223725667898988327
+          6552828745377153692
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -6313,6 +6277,45 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12376274542774427561
+        ]
+      ], 
+      "bugs": [
+        2832
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -6551,7 +6554,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -6560,7 +6563,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -6588,7 +6591,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -6597,7 +6600,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -6625,7 +6628,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -6634,7 +6637,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -6662,7 +6665,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -6671,7 +6674,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -6699,7 +6702,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -6708,7 +6711,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -6736,7 +6739,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15123141881758046683
+          4863848110543323757
         ]
       ], 
       "reviewed-by-human": true
@@ -6745,7 +6748,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120268963253281049
+          15875870232997232472
         ]
       ], 
       "reviewed-by-human": true
@@ -6783,7 +6786,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15307161886299199412
+          2346105604879341495
         ]
       ], 
       "reviewed-by-human": true
@@ -6792,7 +6795,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14376175129664776793
+          12823183142873462143
         ]
       ], 
       "reviewed-by-human": true
@@ -6820,7 +6823,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14168263863081771415
+          4142499014663782701
         ]
       ], 
       "reviewed-by-human": true
@@ -6829,7 +6832,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12278150292542285269
+          3606589379053873513
         ]
       ], 
       "reviewed-by-human": true
@@ -6867,7 +6870,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13045887677262062075
+          16405981284469235830
         ]
       ], 
       "reviewed-by-human": true
@@ -6876,7 +6879,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4995388855933583287
+          12497281568611526356
         ]
       ], 
       "reviewed-by-human": true
@@ -6951,7 +6954,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12648193441807138871
+          11989990309095001939
         ]
       ], 
       "reviewed-by-human": true
@@ -6960,7 +6963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3330948725703968729
+          7077203408218534481
         ]
       ], 
       "reviewed-by-human": true
@@ -7025,7 +7028,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7152746370488611708
+          15598193008092032806
         ]
       ], 
       "reviewed-by-human": true
@@ -7034,7 +7037,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13910449030103127310
+          1172945633876564106
         ]
       ], 
       "reviewed-by-human": true
@@ -7062,7 +7065,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8932070407012852288
+          14463101894225022814
         ]
       ], 
       "reviewed-by-human": true
@@ -7071,7 +7074,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1464369534918103055
+          9489745336011434546
         ]
       ], 
       "reviewed-by-human": true
@@ -7095,6 +7098,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17052873949347861482
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -7111,37 +7150,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15257991883133124567
+          14104970488407444996
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3318990240647055550
+          3344183342766821772
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11229329600143623486
+          18096382468661734181
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
@@ -7252,14 +7282,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10071169096365666576
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8168125816284503355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11224636278170507808
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14095919809525179386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17399714883265675846
+          5222639516687013651
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -8050,6 +8117,294 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2902090852508957882
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7011334045879187335
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8628460967635371466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10605891769253668365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9031220353414122420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12052356451580286635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11042941222396113326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          48543321865687406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6265215811237278554
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17886210747206101484
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18402865251623653419
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9031220353414122420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12052356451580286635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15100357834447730718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11042941222396113326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8895392042474228917
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17537945578842671855
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2756771085785913839
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12370407365013342828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7298563598521283160
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7203144125028809771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -8081,10 +8436,7 @@
           7829581953999677788
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-mac.png": {
       "allowed-digests": [
@@ -8168,7 +8520,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-mac.png": {
       "allowed-digests": [
@@ -8204,7 +8556,7 @@
           1906077521761566198
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-mac.png": {
       "allowed-digests": [
@@ -8240,7 +8592,7 @@
           14730655713673397636
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-mac.png": {
       "allowed-digests": [
@@ -8495,7 +8847,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "ignore-failure": false, 
@@ -8552,19 +8904,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          577763867002558156
+          10270350534543045024
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3187127509363486589
+          2613292064298616534
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -8573,7 +8927,8 @@
           4683300170457454676
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_mesa.png": {
       "allowed-digests": [
@@ -8673,55 +9028,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4828006313825982924
+          11711016279383188197
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6750687666132142674
+          14807718233642576408
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10123948872601300376
+          3542250264918452791
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          407851636120283393
+          5100778197484655594
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "image-surface_565.png": {
       "allowed-digests": [
@@ -8807,38 +9155,77 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9608958026324610750
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1072398151931745130
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11678564671792396439
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8212424581111328793
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2876569939983437533
+          10195286292611262483
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15008759050710746276
+          12868682869175428478
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7259230266720940868
+          2073846486723560683
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15367863860544360168
+          4489720002158860293
         ]
       ], 
       "reviewed-by-human": true
@@ -8847,7 +9234,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7896644149102272693
+          4139022765641862285
         ]
       ], 
       "reviewed-by-human": true
@@ -8856,7 +9243,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8938101494310557817
+          14016676347560822434
         ]
       ], 
       "reviewed-by-human": true
@@ -9152,25 +9539,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -9184,37 +9574,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1232053320656860839
+          3420294909331584076
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17532019165080555635
+          17015627783817350285
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5846645600592968591
+          18441723233217074975
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -9458,13 +9839,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -9572,10 +9953,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7446798776121845780
+          17728485306935400783
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -9638,10 +10020,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6415119852357736555
+          7364313105510370410
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -9702,9 +10085,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -9771,28 +10155,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203473492631421787
+          6004390302197575342
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476847311382274456
+          14086868980283597197
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13965549836065899622
+          4862350907741833412
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_mesa.png": {
       "allowed-digests": [
@@ -9816,10 +10203,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1297122028776862965
+          9542015800753453668
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -9885,7 +10273,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -9930,7 +10318,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -9975,7 +10363,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10047,13 +10435,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -10124,6 +10512,366 @@
       ], 
       "ignore-failure": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712923251277710326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4443863184936217029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10033547804616068548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4381959501339171759
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3873095513352910051
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8759449444261779571
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7450316469051364550
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18104149097289142823
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6609016078678717837
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16356648792486681056
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -10350,34 +11098,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4798715448524644865
+          3519930826502579748
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2800701274256052620
+          5286849848700479024
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10502438783252033586
+          7891530307203346402
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8605111114604394652
+          14215622928526214164
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -10407,13 +11159,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -10464,6 +11216,78 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          526671347486000095
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          315162850214656667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          834353666864975522
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          736103432728252861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -10840,7 +11664,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -10849,7 +11673,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -10858,12 +11682,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -10909,6 +11769,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6108713926578393015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -10945,6 +11841,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -11004,28 +11936,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12192533791124548766
+          7598705955573369265
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1076509006514835448
+          5088246291585946445
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1558579503072776168
+          605948953793264619
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_mesa.png": {
       "allowed-digests": [
@@ -11097,10 +12032,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16317721053082477698
+          7748961206865598068
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -11154,10 +12090,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          450396981900864967
+          17355038258869709320
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -11271,10 +12208,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_mesa.png": {
       "allowed-digests": [
@@ -11901,7 +12839,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2933168279465787248
+          6329347603253038636
         ]
       ], 
       "reviewed-by-human": true
@@ -11928,7 +12866,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6619811780594584075
+          5240298026024448139
         ]
       ], 
       "reviewed-by-human": true
@@ -12117,7 +13055,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13040178079167757885
+          2118593831950610510
         ]
       ], 
       "ignore-failure": false, 
@@ -12127,7 +13065,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8388233011720328513
+          7243535253056860916
         ]
       ], 
       "reviewed-by-human": true
@@ -12167,7 +13105,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9925437062346155958
+          3888857556865804716
         ]
       ], 
       "ignore-failure": false, 
@@ -12227,7 +13165,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10091423976881850596
+          6248877619455181145
         ]
       ], 
       "ignore-failure": false, 
@@ -12237,7 +13175,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2767576208219662715
+          16711909409935915202
         ]
       ], 
       "ignore-failure": false, 
@@ -12247,7 +13185,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7715194674260336757
+          3706805872892876100
         ]
       ], 
       "ignore-failure": false, 
@@ -12843,46 +13781,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13829746709169881192
+          942384268111291460
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4911917813061003086
+          6614286442225667967
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10067541241159264052
+          6742938846486152831
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7183783733564413719
+          9791523307259089537
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -13226,7 +14156,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -13235,7 +14165,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -13244,7 +14174,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -13402,6 +14332,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          603367086804693806
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14530465982360073720
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16412446230659551733
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13906484169395459506
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -13463,10 +14429,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -13493,7 +14459,8 @@
           17501446579955337831
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-mac.png": {
       "allowed-digests": [
@@ -13529,7 +14496,8 @@
           14626919895309756138
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-mac.png": {
       "allowed-digests": [
@@ -13544,34 +14512,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981207417492931405
+          12217816694960917505
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981207417492931405
+          12217816694960917505
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14783277981175726957
+          12023820251736326597
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -13705,7 +14677,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12388512780760636683
+          15854879828764391650
         ]
       ], 
       "ignore-failure": false, 
@@ -13751,7 +14723,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12429166359100573225
+          8812521911353944523
         ]
       ], 
       "reviewed-by-human": true
@@ -14048,6 +15020,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          176643172050242146
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2948157242638756753
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2987686067405810665
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5334307329064438746
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          176643172050242146
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16691134947101004308
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10915999732098659587
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5334307329064438746
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11722569971661041791
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2459536250875419508
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2634998542277034848
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1067219044543347512
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11722569971661041791
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12778609035830803381
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11630855191271740654
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1067219044543347512
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -14278,40 +15394,40 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1665207036697331602
+          525901368556559203
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12804134340931910653
+          11438921612517607616
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8693932099695153913
+          8690743309968362323
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6646529780639572517
+          13037355755302747778
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
@@ -14335,10 +15451,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8123203123250626293
+          2579239595975804443
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-mac.png": {
       "allowed-digests": [
@@ -14428,10 +15545,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1708616588915295899
+          10041658900606708398
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_mesa.png": {
       "allowed-digests": [
@@ -14471,6 +15589,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86-Debug/expected-results.json b/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86-Debug/expected-results.json
index 41ad33d..a29838e 100644
--- a/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86-Debug/expected-results.json
@@ -145,10 +145,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_mesa.png": {
       "allowed-digests": [
@@ -327,10 +328,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10331913054160058507
+          17844811874684279167
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_mesa.png": {
       "allowed-digests": [
@@ -410,66 +412,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -606,10 +548,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -876,7 +818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11263121177956081962
+          2409150024638863289
         ]
       ], 
       "ignore-failure": false, 
@@ -886,7 +828,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17649097035579168327
+          15626124810409855367
         ]
       ], 
       "ignore-failure": false, 
@@ -896,7 +838,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841068380794853380
+          13733035719094699014
         ]
       ], 
       "ignore-failure": false, 
@@ -924,7 +866,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "ignore-failure": false, 
@@ -1276,10 +1218,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15670396195383392960
+          8673269696598503535
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -3473,6 +3418,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8785380353362636115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -3906,10 +3887,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3920,6 +3901,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -5502,25 +5519,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6123419902160692651
+          5212173412708113520
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3809590124209857421
+          3720203697975861088
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18347201664626360496
+          204759598828008356
         ]
       ], 
       "reviewed-by-human": true
@@ -5529,25 +5548,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7583681819040202951
+          7865627489095055720
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1230999868990378393
+          13514563981348744281
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12293526536671799797
+          10193496408581030570
         ]
       ], 
       "reviewed-by-human": true
@@ -5625,25 +5646,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16196032589168704488
+          12808730150828409264
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          921258377474277367
+          12249427830197392212
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13210506930521232327
+          18357213417143374634
         ]
       ], 
       "reviewed-by-human": true
@@ -5652,25 +5675,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8795255553544082122
+          7495010017544348218
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5324925625080682630
+          9144501203695666890
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006407078399395366
+          5114600323751013874
         ]
       ], 
       "reviewed-by-human": true
@@ -5832,25 +5857,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16455693795188954474
+          1653256216885126877
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14792959090383552183
+          12266278739140147398
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8048532164970210915
+          7878996255719276722
         ]
       ], 
       "reviewed-by-human": true
@@ -5859,10 +5884,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4289378502332903087
+          16632403572132256560
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -6000,10 +6025,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10096979422202429896
+          9905253261961784981
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -6066,10 +6092,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6517466887489531391
+          1928905579557393358
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -6313,7 +6340,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -6389,10 +6416,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11674823230783784193
+          8089926634715704386
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -6506,28 +6534,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15457244731984093291
+          12318536301042690256
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14905088650881536479
+          13148999798334714164
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8945075775178012729
+          14566284578615647081
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_mesa.png": {
       "allowed-digests": [
@@ -6542,10 +6573,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10541170658901789960
+          973288136502268399
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -6563,49 +6595,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -7328,10 +7348,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_mesa.png": {
       "allowed-digests": [
@@ -7424,28 +7445,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18142393732412374548
+          14388859012652081591
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867899822381270963
+          585879583128494541
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9490797780143450653
+          4938308976478710250
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_mesa.png": {
       "allowed-digests": [
@@ -7549,10 +7573,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13074434264978053068
+          8259832074254599344
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -8707,6 +8732,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2280319422541178486
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -8877,10 +8938,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7081957696172861137
+          14222934087994137555
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -9815,6 +9877,258 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5754720502560945124
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10582361084119358598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9889873028847414635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11526137674739582723
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14930953744440100687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13561772982395679060
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14111175556930133371
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8259981840478701749
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14893561051388592815
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557507953214120656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4589733990828742235
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14930953744440100687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13561772982395679060
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14111175556930133371
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2149023362899746020
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11628745550697969125
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -10401,28 +10715,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16711030473393003330
+          3027988817282544411
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5601680366772353113
+          17465630610251176417
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6462892377598795803
+          9493505356907239504
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_mesa.png": {
       "allowed-digests": [
@@ -10533,10 +10850,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hairmodes_mesa.png": {
       "allowed-digests": [
@@ -10692,34 +11010,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10754200258215518410
+          10158009152571271862
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17872469439081589334
+          7444289590513012923
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13812356551352377596
+          13268306957945075160
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13842047838793676074
+          18068232354401983438
         ]
       ], 
       "reviewed-by-human": true
@@ -10728,7 +11049,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          900663437344374874
+          5375735702525181390
         ]
       ], 
       "reviewed-by-human": true
@@ -10737,7 +11058,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5437813950680945839
+          5173631195162600059
         ]
       ], 
       "reviewed-by-human": true
@@ -11061,25 +11382,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -11093,37 +11417,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1260355118517778027
+          14648621886201700244
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6305758343370725293
+          11781198242125730877
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17681110047748143008
+          16332944174405791207
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -11387,13 +11702,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -11525,10 +11840,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2457693200778852941
+          11512081962368050917
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -11591,10 +11907,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3073276399184194186
+          2224709660660895645
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -11664,9 +11981,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -11730,28 +12048,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          965984557003869974
+          3286735716127700599
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7486642102096339594
+          16780787446185472833
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          53814325837509071
+          3903869198734994636
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_mesa.png": {
       "allowed-digests": [
@@ -11766,10 +12087,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10248077147151390843
+          16406204735946722431
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -11847,7 +12169,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11904,7 +12226,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11961,7 +12283,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -12054,13 +12376,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -12411,34 +12733,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10797457500428939740
+          13038088541840590857
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13394566409373341681
+          5396945219892187649
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12719966244684890134
+          16512638965718818146
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11471680836110227297
+          14367589711849160690
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12480,13 +12806,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -12570,6 +12896,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14962954696492920650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -13024,7 +13359,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -13033,7 +13368,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -13042,12 +13377,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -13212,28 +13583,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9116835329505890799
+          17808408933762198842
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13947662123670711572
+          3769417856176534943
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16242961868107899448
+          12301930618375208055
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_mesa.png": {
       "allowed-digests": [
@@ -13305,10 +13679,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443938700022111394
+          13115491961826310339
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -13371,10 +13746,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12406769633090064132
+          1008281814180975280
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -13500,10 +13876,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_mesa.png": {
       "allowed-digests": [
@@ -14244,7 +14621,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6920229711803578784
+          5790094153385861425
         ]
       ], 
       "reviewed-by-human": true
@@ -14271,7 +14648,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6950742424526011369
+          12659612428340608980
         ]
       ], 
       "reviewed-by-human": true
@@ -14508,7 +14885,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9314052174761257286
+          17902364094371218708
         ]
       ], 
       "ignore-failure": false, 
@@ -14518,7 +14895,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9408309760166687700
+          6609651740892289444
         ]
       ], 
       "reviewed-by-human": true
@@ -14618,7 +14995,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8536367671564957259
+          7094093838339942950
         ]
       ], 
       "ignore-failure": false, 
@@ -14628,7 +15005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4704442475147199754
+          6854671567471754060
         ]
       ], 
       "ignore-failure": false, 
@@ -14638,7 +15015,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          372148908897802531
+          16657899707572687773
         ]
       ], 
       "ignore-failure": false, 
@@ -15327,46 +15704,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9359422494023233869
+          393125001874403968
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4129518398493460981
+          7796844495772667439
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14169295674273306180
+          15374275609203997765
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18253694509356273626
+          17697059014067550094
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -15803,7 +16172,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -15812,7 +16181,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -15821,7 +16190,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -16079,10 +16448,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -16202,34 +16571,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7420220992884329616
+          9702900262400336960
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -16375,7 +16748,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5061253744723512316
+          6755155921388577052
         ]
       ], 
       "ignore-failure": false, 
@@ -16421,7 +16794,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2574512286616033861
+          8947348046211497261
         ]
       ], 
       "reviewed-by-human": true
@@ -16754,6 +17127,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16213817522699895557
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16695670147246382731
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10521118097037993460
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14437774039288974077
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16213817522699895557
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11634740968981127310
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15011246466716453230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14437774039288974077
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15844281722319881998
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16952714748856780634
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2193667352795405348
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8323840933077931023
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15844281722319881998
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15620550636479883022
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18342718327160098232
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8323840933077931023
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -16990,28 +17507,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11287209491577059906
+          1575412881132542515
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          610849827880040391
+          7801401619129355812
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17189203782066223379
+          18349090605113364446
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_mesa.png": {
       "allowed-digests": [
@@ -17026,10 +17546,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8925491547830039513
+          2282620731115150177
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -17065,10 +17586,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10675084246400923267
+          16444559737432424692
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_mesa.png": {
       "allowed-digests": [
@@ -17167,10 +17689,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2144643099806449553
+          7073885620578418690
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_mesa.png": {
       "allowed-digests": [
@@ -17210,6 +17733,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86-Release/expected-results.json b/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86-Release/expected-results.json
index 9bf68d2..1ea6a59 100644
--- a/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86-Release/expected-results.json
+++ b/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86-Release/expected-results.json
@@ -121,10 +121,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_mesa.png": {
       "allowed-digests": [
@@ -291,10 +292,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10331913054160058507
+          17844811874684279167
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_mesa.png": {
       "allowed-digests": [
@@ -374,54 +376,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -558,10 +512,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -816,7 +770,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11263121177956081962
+          2409150024638863289
         ]
       ], 
       "ignore-failure": false, 
@@ -826,7 +780,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17649097035579168327
+          15626124810409855367
         ]
       ], 
       "ignore-failure": false, 
@@ -836,7 +790,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841068380794853380
+          13733035719094699014
         ]
       ], 
       "ignore-failure": false, 
@@ -864,7 +818,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "ignore-failure": false, 
@@ -1216,10 +1170,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15670396195383392960
+          8673269696598503535
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -3209,6 +3166,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8785380353362636115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -3594,10 +3587,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3608,6 +3601,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -5034,25 +5063,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6123419902160692651
+          5212173412708113520
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3809590124209857421
+          3720203697975861088
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18347201664626360496
+          204759598828008356
         ]
       ], 
       "reviewed-by-human": true
@@ -5061,25 +5092,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7583681819040202951
+          7865627489095055720
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1230999868990378393
+          13514563981348744281
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12293526536671799797
+          10193496408581030570
         ]
       ], 
       "reviewed-by-human": true
@@ -5145,25 +5178,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16196032589168704488
+          12808730150828409264
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          921258377474277367
+          12249427830197392212
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13210506930521232327
+          18357213417143374634
         ]
       ], 
       "reviewed-by-human": true
@@ -5172,25 +5207,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8795255553544082122
+          7495010017544348218
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5324925625080682630
+          9144501203695666890
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006407078399395366
+          5114600323751013874
         ]
       ], 
       "reviewed-by-human": true
@@ -5340,25 +5377,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16455693795188954474
+          1653256216885126877
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14792959090383552183
+          12266278739140147398
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8048532164970210915
+          7878996255719276722
         ]
       ], 
       "reviewed-by-human": true
@@ -5367,10 +5404,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4289378502332903087
+          16632403572132256560
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -5511,10 +5548,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10096979422202429896
+          9905253261961784981
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -5577,10 +5615,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6517466887489531391
+          1928905579557393358
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -5812,7 +5851,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -5876,10 +5915,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11674823230783784193
+          8089926634715704386
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -5993,28 +6033,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15457244731984093291
+          12318536301042690256
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14905088650881536479
+          13148999798334714164
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8945075775178012729
+          14566284578615647081
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_mesa.png": {
       "allowed-digests": [
@@ -6029,10 +6072,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10541170658901789960
+          973288136502268399
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -6050,49 +6094,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
@@ -6743,10 +6775,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_mesa.png": {
       "allowed-digests": [
@@ -6839,28 +6872,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18142393732412374548
+          14388859012652081591
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867899822381270963
+          585879583128494541
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9490797780143450653
+          4938308976478710250
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_mesa.png": {
       "allowed-digests": [
@@ -6972,10 +7008,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13074434264978053068
+          8259832074254599344
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -8004,6 +8041,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2280319422541178486
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -8174,10 +8247,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7081957696172861137
+          14222934087994137555
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -8992,6 +9066,258 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5754720502560945124
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10582361084119358598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9889873028847414635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11526137674739582723
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14930953744440100687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13561772982395679060
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14111175556930133371
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8259981840478701749
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14893561051388592815
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557507953214120656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4589733990828742235
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14930953744440100687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13561772982395679060
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14111175556930133371
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2149023362899746020
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11628745550697969125
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -9506,28 +9832,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16711030473393003330
+          3027988817282544411
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5601680366772353113
+          17465630610251176417
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6462892377598795803
+          9493505356907239504
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_mesa.png": {
       "allowed-digests": [
@@ -9626,10 +9955,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hairmodes_mesa.png": {
       "allowed-digests": [
@@ -9785,34 +10115,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10754200258215518410
+          10158009152571271862
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17872469439081589334
+          7444289590513012923
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13812356551352377596
+          13268306957945075160
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13842047838793676074
+          18068232354401983438
         ]
       ], 
       "reviewed-by-human": true
@@ -9821,7 +10154,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          900663437344374874
+          5375735702525181390
         ]
       ], 
       "reviewed-by-human": true
@@ -9830,7 +10163,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5437813950680945839
+          5173631195162600059
         ]
       ], 
       "reviewed-by-human": true
@@ -10142,25 +10475,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -10174,37 +10510,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1260355118517778027
+          14648621886201700244
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6305758343370725293
+          11781198242125730877
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17681110047748143008
+          16332944174405791207
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -10456,13 +10783,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -10594,10 +10921,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2457693200778852941
+          11512081962368050917
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -10660,10 +10988,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3073276399184194186
+          2224709660660895645
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -10733,9 +11062,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -10794,28 +11124,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          965984557003869974
+          3286735716127700599
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7486642102096339594
+          16780787446185472833
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          53814325837509071
+          3903869198734994636
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_mesa.png": {
       "allowed-digests": [
@@ -10830,10 +11163,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10248077147151390843
+          16406204735946722431
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -10911,7 +11245,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10956,7 +11290,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11001,7 +11335,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11082,13 +11416,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -11406,34 +11740,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10797457500428939740
+          13038088541840590857
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13394566409373341681
+          5396945219892187649
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12719966244684890134
+          16512638965718818146
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11471680836110227297
+          14367589711849160690
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -11463,13 +11801,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -11529,6 +11867,15 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14962954696492920650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -11941,7 +12288,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -11950,7 +12297,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -11959,12 +12306,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -12117,28 +12500,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9116835329505890799
+          17808408933762198842
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13947662123670711572
+          3769417856176534943
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16242961868107899448
+          12301930618375208055
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_mesa.png": {
       "allowed-digests": [
@@ -12210,10 +12596,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443938700022111394
+          13115491961826310339
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -12276,10 +12663,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12406769633090064132
+          1008281814180975280
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -12405,10 +12793,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_mesa.png": {
       "allowed-digests": [
@@ -13101,7 +13490,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6920229711803578784
+          5790094153385861425
         ]
       ], 
       "reviewed-by-human": true
@@ -13128,7 +13517,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6950742424526011369
+          12659612428340608980
         ]
       ], 
       "reviewed-by-human": true
@@ -13329,7 +13718,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9314052174761257286
+          17902364094371218708
         ]
       ], 
       "ignore-failure": false, 
@@ -13339,7 +13728,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9408309760166687700
+          6609651740892289444
         ]
       ], 
       "reviewed-by-human": true
@@ -13439,7 +13828,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8536367671564957259
+          7094093838339942950
         ]
       ], 
       "ignore-failure": false, 
@@ -13449,7 +13838,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4704442475147199754
+          6854671567471754060
         ]
       ], 
       "ignore-failure": false, 
@@ -13459,7 +13848,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          372148908897802531
+          16657899707572687773
         ]
       ], 
       "ignore-failure": false, 
@@ -14100,46 +14489,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9359422494023233869
+          393125001874403968
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4129518398493460981
+          7796844495772667439
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14169295674273306180
+          15374275609203997765
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18253694509356273626
+          17697059014067550094
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -14540,7 +14921,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -14549,7 +14930,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -14558,7 +14939,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -14804,10 +15185,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -14915,34 +15296,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7420220992884329616
+          9702900262400336960
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15088,7 +15473,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5061253744723512316
+          6755155921388577052
         ]
       ], 
       "ignore-failure": false, 
@@ -15134,7 +15519,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2574512286616033861
+          8947348046211497261
         ]
       ], 
       "reviewed-by-human": true
@@ -15443,6 +15828,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16213817522699895557
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16695670147246382731
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10521118097037993460
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14437774039288974077
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16213817522699895557
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11634740968981127310
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15011246466716453230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14437774039288974077
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15844281722319881998
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16952714748856780634
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2193667352795405348
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8323840933077931023
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15844281722319881998
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15620550636479883022
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18342718327160098232
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8323840933077931023
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -15658,28 +16187,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11287209491577059906
+          1575412881132542515
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          610849827880040391
+          7801401619129355812
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17189203782066223379
+          18349090605113364446
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_mesa.png": {
       "allowed-digests": [
@@ -15694,10 +16226,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8925491547830039513
+          2282620731115150177
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15733,10 +16266,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10675084246400923267
+          16444559737432424692
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_mesa.png": {
       "allowed-digests": [
@@ -15835,10 +16369,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2144643099806449553
+          7073885620578418690
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_mesa.png": {
       "allowed-digests": [
@@ -15878,6 +16413,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json b/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json
index 32195b4..02be61e 100644
--- a/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json
+++ b/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json
@@ -145,10 +145,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_mesa.png": {
       "allowed-digests": [
@@ -327,10 +328,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10331913054160058507
+          17844811874684279167
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_mesa.png": {
       "allowed-digests": [
@@ -371,6 +373,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -410,66 +448,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -606,10 +584,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -876,7 +854,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11263121177956081962
+          2409150024638863289
         ]
       ], 
       "ignore-failure": false, 
@@ -886,7 +864,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17649097035579168327
+          15626124810409855367
         ]
       ], 
       "ignore-failure": false, 
@@ -896,7 +874,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841068380794853380
+          13733035719094699014
         ]
       ], 
       "ignore-failure": false, 
@@ -924,7 +902,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "ignore-failure": false, 
@@ -1276,10 +1254,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15670396195383392960
+          8673269696598503535
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -3473,6 +3454,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8785380353362636115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -3906,10 +3923,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3920,6 +3937,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -5502,25 +5555,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6123419902160692651
+          5212173412708113520
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3809590124209857421
+          3720203697975861088
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18347201664626360496
+          204759598828008356
         ]
       ], 
       "reviewed-by-human": true
@@ -5529,25 +5584,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7583681819040202951
+          7865627489095055720
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1230999868990378393
+          13514563981348744281
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12293526536671799797
+          10193496408581030570
         ]
       ], 
       "reviewed-by-human": true
@@ -5625,25 +5682,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16196032589168704488
+          12808730150828409264
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          921258377474277367
+          12249427830197392212
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13210506930521232327
+          18357213417143374634
         ]
       ], 
       "reviewed-by-human": true
@@ -5652,25 +5711,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8795255553544082122
+          7495010017544348218
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5324925625080682630
+          9144501203695666890
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006407078399395366
+          5114600323751013874
         ]
       ], 
       "reviewed-by-human": true
@@ -5832,25 +5893,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10866806415112349879
+          1782597699774950013
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7337650884745590744
+          15149178935785271539
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2819348015554651988
+          3937178519974921093
         ]
       ], 
       "reviewed-by-human": true
@@ -5859,10 +5920,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5253189687450864363
+          11021349865548503388
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -6000,10 +6061,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10096979422202429896
+          9905253261961784981
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -6066,10 +6128,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6517466887489531391
+          1928905579557393358
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -6313,7 +6376,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -6389,10 +6452,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11674823230783784193
+          8089926634715704386
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -6506,28 +6570,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15457244731984093291
+          12318536301042690256
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14905088650881536479
+          13148999798334714164
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8945075775178012729
+          14566284578615647081
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_mesa.png": {
       "allowed-digests": [
@@ -6542,10 +6609,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10541170658901789960
+          973288136502268399
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -6563,49 +6631,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -6623,7 +6679,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -6632,7 +6688,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -6641,7 +6697,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
       "reviewed-by-human": true
@@ -6650,13 +6706,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6674,49 +6727,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2519050949583701818
+          5976613545322007809
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6734,49 +6775,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6794,49 +6823,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12455652221971736296
+          8380951080763030595
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6854,7 +6871,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -6863,7 +6880,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -6872,7 +6889,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
       "reviewed-by-human": true
@@ -6881,13 +6898,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6905,49 +6919,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4878087893157172610
+          17064895090763866225
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6965,49 +6967,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7025,49 +7015,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6155554109563033370
+          2065497081829583993
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7085,7 +7063,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5398725819069767178
+          17228749247169786721
         ]
       ], 
       "reviewed-by-human": true
@@ -7094,7 +7072,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14662610224354573548
+          117158244705957425
         ]
       ], 
       "reviewed-by-human": true
@@ -7103,7 +7081,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1526364923262215210
+          17747978481924214839
         ]
       ], 
       "reviewed-by-human": true
@@ -7112,13 +7090,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12828839751858758430
+          8111924835192809725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -7136,31 +7111,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          720081480487410498
+          7552478037018588623
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9975536350217643283
+          5772699870249850487
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1345391049248355734
+          14537080711634552948
         ]
       ], 
       "reviewed-by-human": true
@@ -7169,13 +7138,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12828839751858758430
+          8111924835192809725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -7193,31 +7159,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10894588250693245309
+          2996003952131594372
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1075843783136977484
+          9058003032472302656
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1526364923262215210
+          17747978481924214839
         ]
       ], 
       "reviewed-by-human": true
@@ -7226,13 +7186,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12828839751858758430
+          8111924835192809725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -7250,49 +7207,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9556278974878993969
+          10612098539528623699
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701644982849102757
+          2169969531073727118
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4935686972044741946
+          4436978442739651226
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12828839751858758430
+          8111924835192809725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -7310,10 +7255,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -7328,10 +7274,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_mesa.png": {
       "allowed-digests": [
@@ -7367,10 +7314,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17978468903925654073
+          18074555472627507022
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -7424,28 +7372,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18142393732412374548
+          14388859012652081591
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867899822381270963
+          585879583128494541
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9490797780143450653
+          4938308976478710250
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_mesa.png": {
       "allowed-digests": [
@@ -7557,10 +7508,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13074434264978053068
+          8259832074254599344
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -7763,6 +7715,45 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12376274542774427561
+        ]
+      ], 
+      "bugs": [
+        2832
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -8061,7 +8052,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -8070,7 +8061,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -8108,7 +8099,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -8117,7 +8108,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -8155,7 +8146,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -8164,7 +8155,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -8202,7 +8193,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -8211,7 +8202,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -8249,7 +8240,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -8258,7 +8249,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -8296,7 +8287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15123141881758046683
+          4863848110543323757
         ]
       ], 
       "reviewed-by-human": true
@@ -8305,7 +8296,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120268963253281049
+          15875870232997232472
         ]
       ], 
       "reviewed-by-human": true
@@ -8343,7 +8334,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15307161886299199412
+          2346105604879341495
         ]
       ], 
       "reviewed-by-human": true
@@ -8352,7 +8343,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14376175129664776793
+          12823183142873462143
         ]
       ], 
       "reviewed-by-human": true
@@ -8390,7 +8381,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14168263863081771415
+          4142499014663782701
         ]
       ], 
       "reviewed-by-human": true
@@ -8399,7 +8390,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12278150292542285269
+          3606589379053873513
         ]
       ], 
       "reviewed-by-human": true
@@ -8437,7 +8428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13045887677262062075
+          16405981284469235830
         ]
       ], 
       "reviewed-by-human": true
@@ -8446,7 +8437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4995388855933583287
+          12497281568611526356
         ]
       ], 
       "reviewed-by-human": true
@@ -8531,7 +8522,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12648193441807138871
+          11989990309095001939
         ]
       ], 
       "reviewed-by-human": true
@@ -8540,7 +8531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3330948725703968729
+          7077203408218534481
         ]
       ], 
       "reviewed-by-human": true
@@ -8625,7 +8616,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3769679814348319486
+          10554264491405807922
         ]
       ], 
       "reviewed-by-human": true
@@ -8634,7 +8625,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8129720186306078513
+          12979926523130906254
         ]
       ], 
       "reviewed-by-human": true
@@ -8672,7 +8663,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9381896105202598961
+          10045826677719372831
         ]
       ], 
       "reviewed-by-human": true
@@ -8681,7 +8672,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17603982840034461548
+          4940698443684340147
         ]
       ], 
       "reviewed-by-human": true
@@ -8715,6 +8706,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17052873949347861482
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -8731,37 +8758,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1398996083819146930
+          5455445884785343135
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281107942755631080
+          6584242003506916653
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14381387321853004947
+          12433181322174206946
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
@@ -8881,14 +8899,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15853323570786993974
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9111020190125500557
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8444189901793941601
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14095919809525179386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7081957696172861137
+          14222934087994137555
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -9823,6 +9878,294 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2902090852508957882
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10582361084119358598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9889873028847414635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4864532344327180657
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14930953744440100687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13561772982395679060
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17470970587320296316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8259981840478701749
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1966492872216272409
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557507953214120656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13525351757321669064
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14930953744440100687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13561772982395679060
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17470970587320296316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2149023362899746020
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2990802639527148033
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2756771085785913839
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12370407365013342828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7298563598521283160
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7203144125028809771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -9854,10 +10197,7 @@
           7829581953999677788
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-mac.png": {
       "allowed-digests": [
@@ -9965,7 +10305,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-mac.png": {
       "allowed-digests": [
@@ -10001,7 +10341,7 @@
           9677442873231842372
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-mac.png": {
       "allowed-digests": [
@@ -10037,7 +10377,7 @@
           3090817784180349654
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-mac.png": {
       "allowed-digests": [
@@ -10340,7 +10680,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "ignore-failure": false, 
@@ -10409,19 +10749,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16711030473393003330
+          15758701092535531601
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5601680366772353113
+          13279639801687685261
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -10430,7 +10772,8 @@
           6462892377598795803
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_mesa.png": {
       "allowed-digests": [
@@ -10541,10 +10884,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hairmodes_mesa.png": {
       "allowed-digests": [
@@ -10696,38 +11040,77 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9608958026324610750
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1072398151931745130
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11678564671792396439
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8212424581111328793
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11599728965142360042
+          8857113470735439387
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4581218540407504486
+          1167242400311266132
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14311763117104890088
+          12601233496431438705
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7505049403357523092
+          13641975689947970811
         ]
       ], 
       "reviewed-by-human": true
@@ -10736,7 +11119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2567403841460285865
+          14925950926978222214
         ]
       ], 
       "reviewed-by-human": true
@@ -10745,7 +11128,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8938101494310557817
+          14016676347560822434
         ]
       ], 
       "reviewed-by-human": true
@@ -11069,25 +11452,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -11101,37 +11487,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3129180565868942849
+          2623036152066516254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5144690836398868430
+          16341862097066727299
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5527027071149411727
+          306001991548170999
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -11395,13 +11772,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -11533,10 +11910,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2457693200778852941
+          11512081962368050917
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -11599,10 +11977,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3073276399184194186
+          2224709660660895645
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -11672,9 +12051,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -11738,28 +12118,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          965984557003869974
+          434632923319141574
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7486642102096339594
+          6610148046456183203
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          53814325837509071
+          8476248732632152119
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_mesa.png": {
       "allowed-digests": [
@@ -11774,10 +12157,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10248077147151390843
+          5940994834242943779
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -11855,7 +12239,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11912,7 +12296,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11969,7 +12353,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -12062,13 +12446,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -12160,6 +12544,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712923251277710326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4443863184936217029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10033547804616068548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4381959501339171759
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3873095513352910051
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8759449444261779571
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7450316469051364550
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18104149097289142823
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6609016078678717837
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16356648792486681056
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -12419,34 +13163,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10797457500428939740
+          13038088541840590857
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13394566409373341681
+          5396945219892187649
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12719966244684890134
+          16512638965718818146
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11471680836110227297
+          14367589711849160690
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12488,13 +13236,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -12578,6 +13326,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          526671347486000095
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          315162850214656667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          834353666864975522
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          736103432728252861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -13032,7 +13852,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -13041,7 +13861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -13050,12 +13870,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -13113,6 +13969,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          99805091459040859
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -13149,6 +14041,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -13220,28 +14148,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9116835329505890799
+          17808408933762198842
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13947662123670711572
+          3769417856176534943
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16242961868107899448
+          12301930618375208055
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_mesa.png": {
       "allowed-digests": [
@@ -13313,10 +14244,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443938700022111394
+          13115491961826310339
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -13379,10 +14311,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12406769633090064132
+          1008281814180975280
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -13508,10 +14441,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_mesa.png": {
       "allowed-digests": [
@@ -14252,7 +15186,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6920229711803578784
+          5790094153385861425
         ]
       ], 
       "reviewed-by-human": true
@@ -14279,7 +15213,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6950742424526011369
+          12659612428340608980
         ]
       ], 
       "reviewed-by-human": true
@@ -14516,7 +15450,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15918656700665568231
+          9662049661835088514
         ]
       ], 
       "ignore-failure": false, 
@@ -14526,7 +15460,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6343855064436115941
+          3715602790506617396
         ]
       ], 
       "reviewed-by-human": true
@@ -14566,7 +15500,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9925437062346155958
+          3888857556865804716
         ]
       ], 
       "ignore-failure": false, 
@@ -14626,7 +15560,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8536367671564957259
+          7094093838339942950
         ]
       ], 
       "ignore-failure": false, 
@@ -14636,7 +15570,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4704442475147199754
+          6854671567471754060
         ]
       ], 
       "ignore-failure": false, 
@@ -14646,7 +15580,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          372148908897802531
+          16657899707572687773
         ]
       ], 
       "ignore-failure": false, 
@@ -15335,46 +16269,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9359422494023233869
+          393125001874403968
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4129518398493460981
+          7796844495772667439
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14169295674273306180
+          15374275609203997765
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18253694509356273626
+          17697059014067550094
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -15811,7 +16737,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -15820,7 +16746,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -15829,7 +16755,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -16026,6 +16952,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18095396609750804641
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11882296874863336219
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7058119782533650074
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13906484169395459506
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -16087,10 +17049,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -16117,7 +17079,8 @@
           17501446579955337831
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_mesa.png": {
       "allowed-digests": [
@@ -16174,7 +17137,8 @@
           14626919895309756138
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_mesa.png": {
       "allowed-digests": [
@@ -16210,34 +17174,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7420220992884329616
+          9702900262400336960
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -16383,7 +17351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5061253744723512316
+          6755155921388577052
         ]
       ], 
       "ignore-failure": false, 
@@ -16429,7 +17397,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2574512286616033861
+          8947348046211497261
         ]
       ], 
       "reviewed-by-human": true
@@ -16762,6 +17730,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17628572146517326838
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12650670073247231483
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7255010914474242267
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13067845786044557791
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17628572146517326838
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13004246353792273493
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9206089993029643936
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13067845786044557791
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17106217204268766211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11952609355369971735
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8763629445626037881
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5407549800302455679
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17106217204268766211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16055975013079612168
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1570033657773431514
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5407549800302455679
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -16998,28 +18110,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11287209491577059906
+          1575412881132542515
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          610849827880040391
+          7801401619129355812
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17189203782066223379
+          18349090605113364446
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_mesa.png": {
       "allowed-digests": [
@@ -17034,10 +18149,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8925491547830039513
+          2282620731115150177
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -17073,10 +18189,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10675084246400923267
+          16444559737432424692
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_mesa.png": {
       "allowed-digests": [
@@ -17175,10 +18292,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2144643099806449553
+          7073885620578418690
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_mesa.png": {
       "allowed-digests": [
@@ -17218,6 +18336,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json b/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json
index eae83da..208c5f0 100644
--- a/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json
+++ b/expectations/gm/Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json
@@ -121,10 +121,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_mesa.png": {
       "allowed-digests": [
@@ -267,10 +268,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10331913054160058507
+          17844811874684279167
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_mesa.png": {
       "allowed-digests": [
@@ -311,6 +313,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -350,54 +388,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -510,10 +500,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -756,7 +746,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11263121177956081962
+          2409150024638863289
         ]
       ], 
       "ignore-failure": false, 
@@ -766,7 +756,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17649097035579168327
+          15626124810409855367
         ]
       ], 
       "ignore-failure": false, 
@@ -776,7 +766,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841068380794853380
+          13733035719094699014
         ]
       ], 
       "ignore-failure": false, 
@@ -804,7 +794,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "ignore-failure": false, 
@@ -1108,10 +1098,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15670396195383392960
+          8673269696598503535
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -2849,6 +2842,42 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8785380353362636115
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -3234,10 +3263,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3248,6 +3277,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4602,25 +4667,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6123419902160692651
+          5212173412708113520
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3809590124209857421
+          3720203697975861088
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18347201664626360496
+          204759598828008356
         ]
       ], 
       "reviewed-by-human": true
@@ -4629,25 +4696,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7583681819040202951
+          7865627489095055720
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1230999868990378393
+          13514563981348744281
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12293526536671799797
+          10193496408581030570
         ]
       ], 
       "reviewed-by-human": true
@@ -4725,25 +4794,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16196032589168704488
+          12808730150828409264
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          921258377474277367
+          12249427830197392212
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13210506930521232327
+          18357213417143374634
         ]
       ], 
       "reviewed-by-human": true
@@ -4752,25 +4823,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8795255553544082122
+          7495010017544348218
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5324925625080682630
+          9144501203695666890
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18006407078399395366
+          5114600323751013874
         ]
       ], 
       "reviewed-by-human": true
@@ -4920,25 +4993,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10866806415112349879
+          1782597699774950013
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7337650884745590744
+          15149178935785271539
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2819348015554651988
+          3937178519974921093
         ]
       ], 
       "reviewed-by-human": true
@@ -4947,10 +5020,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5253189687450864363
+          11021349865548503388
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -5079,10 +5152,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10096979422202429896
+          9905253261961784981
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -5145,10 +5219,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6517466887489531391
+          1928905579557393358
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -5356,7 +5431,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -5420,10 +5495,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11674823230783784193
+          8089926634715704386
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -5537,28 +5613,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15457244731984093291
+          12318536301042690256
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14905088650881536479
+          13148999798334714164
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8945075775178012729
+          14566284578615647081
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_mesa.png": {
       "allowed-digests": [
@@ -5573,64 +5652,53 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10541170658901789960
+          973288136502268399
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -5639,7 +5707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -5648,7 +5716,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
       "reviewed-by-human": true
@@ -5657,163 +5725,124 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2519050949583701818
+          5976613545322007809
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12455652221971736296
+          8380951080763030595
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -5822,7 +5851,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -5831,7 +5860,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
       "reviewed-by-human": true
@@ -5840,13 +5869,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5864,49 +5890,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4878087893157172610
+          17064895090763866225
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5924,49 +5938,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5984,49 +5986,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6155554109563033370
+          2065497081829583993
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6044,7 +6034,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5398725819069767178
+          17228749247169786721
         ]
       ], 
       "reviewed-by-human": true
@@ -6053,7 +6043,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14662610224354573548
+          117158244705957425
         ]
       ], 
       "reviewed-by-human": true
@@ -6062,7 +6052,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1526364923262215210
+          17747978481924214839
         ]
       ], 
       "reviewed-by-human": true
@@ -6071,13 +6061,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12828839751858758430
+          8111924835192809725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6095,31 +6082,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          720081480487410498
+          7552478037018588623
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9975536350217643283
+          5772699870249850487
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1345391049248355734
+          14537080711634552948
         ]
       ], 
       "reviewed-by-human": true
@@ -6128,13 +6109,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12828839751858758430
+          8111924835192809725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6152,31 +6130,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10894588250693245309
+          2996003952131594372
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1075843783136977484
+          9058003032472302656
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1526364923262215210
+          17747978481924214839
         ]
       ], 
       "reviewed-by-human": true
@@ -6185,13 +6157,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12828839751858758430
+          8111924835192809725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6209,49 +6178,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9556278974878993969
+          10612098539528623699
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701644982849102757
+          2169969531073727118
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4935686972044741946
+          4436978442739651226
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12828839751858758430
+          8111924835192809725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6269,10 +6226,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -6287,10 +6245,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_mesa.png": {
       "allowed-digests": [
@@ -6314,10 +6273,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17978468903925654073
+          18074555472627507022
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -6359,28 +6319,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18142393732412374548
+          14388859012652081591
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867899822381270963
+          585879583128494541
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9490797780143450653
+          4938308976478710250
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_mesa.png": {
       "allowed-digests": [
@@ -6492,10 +6455,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13074434264978053068
+          8259832074254599344
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -6698,6 +6662,45 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12376274542774427561
+        ]
+      ], 
+      "bugs": [
+        2832
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -6936,7 +6939,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -6945,7 +6948,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -6973,7 +6976,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -6982,7 +6985,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -7010,7 +7013,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -7019,7 +7022,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -7047,7 +7050,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -7056,7 +7059,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -7084,7 +7087,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -7093,7 +7096,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -7121,7 +7124,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15123141881758046683
+          4863848110543323757
         ]
       ], 
       "reviewed-by-human": true
@@ -7130,7 +7133,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120268963253281049
+          15875870232997232472
         ]
       ], 
       "reviewed-by-human": true
@@ -7168,7 +7171,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15307161886299199412
+          2346105604879341495
         ]
       ], 
       "reviewed-by-human": true
@@ -7177,7 +7180,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14376175129664776793
+          12823183142873462143
         ]
       ], 
       "reviewed-by-human": true
@@ -7205,7 +7208,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14168263863081771415
+          4142499014663782701
         ]
       ], 
       "reviewed-by-human": true
@@ -7214,7 +7217,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12278150292542285269
+          3606589379053873513
         ]
       ], 
       "reviewed-by-human": true
@@ -7252,7 +7255,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13045887677262062075
+          16405981284469235830
         ]
       ], 
       "reviewed-by-human": true
@@ -7261,7 +7264,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4995388855933583287
+          12497281568611526356
         ]
       ], 
       "reviewed-by-human": true
@@ -7336,7 +7339,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12648193441807138871
+          11989990309095001939
         ]
       ], 
       "reviewed-by-human": true
@@ -7345,7 +7348,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3330948725703968729
+          7077203408218534481
         ]
       ], 
       "reviewed-by-human": true
@@ -7410,7 +7413,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3769679814348319486
+          10554264491405807922
         ]
       ], 
       "reviewed-by-human": true
@@ -7419,7 +7422,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8129720186306078513
+          12979926523130906254
         ]
       ], 
       "reviewed-by-human": true
@@ -7447,7 +7450,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9381896105202598961
+          10045826677719372831
         ]
       ], 
       "reviewed-by-human": true
@@ -7456,7 +7459,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17603982840034461548
+          4940698443684340147
         ]
       ], 
       "reviewed-by-human": true
@@ -7480,6 +7483,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17052873949347861482
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -7496,37 +7535,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1398996083819146930
+          5455445884785343135
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281107942755631080
+          6584242003506916653
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14381387321853004947
+          12433181322174206946
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
@@ -7646,14 +7676,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15853323570786993974
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9111020190125500557
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8444189901793941601
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14095919809525179386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7081957696172861137
+          14222934087994137555
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -8444,6 +8511,294 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2902090852508957882
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10582361084119358598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9889873028847414635
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4864532344327180657
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14930953744440100687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13561772982395679060
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17470970587320296316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8259981840478701749
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1966492872216272409
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557507953214120656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13525351757321669064
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14930953744440100687
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13561772982395679060
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7014199087131282761
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17470970587320296316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2149023362899746020
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2990802639527148033
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2756771085785913839
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12370407365013342828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7298563598521283160
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7203144125028809771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -8475,10 +8830,7 @@
           7829581953999677788
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-mac.png": {
       "allowed-digests": [
@@ -8562,7 +8914,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-mac.png": {
       "allowed-digests": [
@@ -8598,7 +8950,7 @@
           9677442873231842372
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-mac.png": {
       "allowed-digests": [
@@ -8634,7 +8986,7 @@
           3090817784180349654
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-mac.png": {
       "allowed-digests": [
@@ -8889,7 +9241,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "ignore-failure": false, 
@@ -8946,19 +9298,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16711030473393003330
+          15758701092535531601
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5601680366772353113
+          13279639801687685261
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -8967,7 +9321,8 @@
           6462892377598795803
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_mesa.png": {
       "allowed-digests": [
@@ -9066,10 +9421,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hairmodes_mesa.png": {
       "allowed-digests": [
@@ -9209,38 +9565,77 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9608958026324610750
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1072398151931745130
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11678564671792396439
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8212424581111328793
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11599728965142360042
+          8857113470735439387
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4581218540407504486
+          1167242400311266132
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14311763117104890088
+          12601233496431438705
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7505049403357523092
+          13641975689947970811
         ]
       ], 
       "reviewed-by-human": true
@@ -9249,7 +9644,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2567403841460285865
+          14925950926978222214
         ]
       ], 
       "reviewed-by-human": true
@@ -9258,7 +9653,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8938101494310557817
+          14016676347560822434
         ]
       ], 
       "reviewed-by-human": true
@@ -9570,25 +9965,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -9602,37 +10000,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3129180565868942849
+          2623036152066516254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5144690836398868430
+          16341862097066727299
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5527027071149411727
+          306001991548170999
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -9884,13 +10273,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -9998,10 +10387,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2457693200778852941
+          11512081962368050917
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -10064,10 +10454,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3073276399184194186
+          2224709660660895645
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -10137,9 +10528,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -10194,28 +10586,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          965984557003869974
+          434632923319141574
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7486642102096339594
+          6610148046456183203
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          53814325837509071
+          8476248732632152119
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_mesa.png": {
       "allowed-digests": [
@@ -10230,10 +10625,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10248077147151390843
+          5940994834242943779
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -10299,7 +10695,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10344,7 +10740,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10389,7 +10785,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10470,13 +10866,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -10556,6 +10952,366 @@
       ], 
       "ignore-failure": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712923251277710326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4443863184936217029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10033547804616068548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4381959501339171759
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3873095513352910051
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8759449444261779571
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7450316469051364550
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18104149097289142823
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6609016078678717837
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16356648792486681056
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -10782,34 +11538,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10797457500428939740
+          13038088541840590857
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13394566409373341681
+          5396945219892187649
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12719966244684890134
+          16512638965718818146
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11471680836110227297
+          14367589711849160690
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -10839,13 +11599,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -10905,6 +11665,78 @@
       ], 
       "ignore-failure": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          526671347486000095
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          315162850214656667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          834353666864975522
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          736103432728252861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -11281,7 +12113,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -11290,7 +12122,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -11299,12 +12131,48 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -11350,6 +12218,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          99805091459040859
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -11386,6 +12290,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -11445,28 +12385,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9116835329505890799
+          17808408933762198842
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13947662123670711572
+          3769417856176534943
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16242961868107899448
+          12301930618375208055
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_mesa.png": {
       "allowed-digests": [
@@ -11538,10 +12481,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443938700022111394
+          13115491961826310339
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -11604,10 +12548,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12406769633090064132
+          1008281814180975280
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -11721,10 +12666,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_mesa.png": {
       "allowed-digests": [
@@ -12369,7 +13315,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6920229711803578784
+          5790094153385861425
         ]
       ], 
       "reviewed-by-human": true
@@ -12396,7 +13342,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6950742424526011369
+          12659612428340608980
         ]
       ], 
       "reviewed-by-human": true
@@ -12597,7 +13543,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15918656700665568231
+          9662049661835088514
         ]
       ], 
       "ignore-failure": false, 
@@ -12607,7 +13553,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6343855064436115941
+          3715602790506617396
         ]
       ], 
       "reviewed-by-human": true
@@ -12647,7 +13593,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9925437062346155958
+          3888857556865804716
         ]
       ], 
       "ignore-failure": false, 
@@ -12707,7 +13653,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8536367671564957259
+          7094093838339942950
         ]
       ], 
       "ignore-failure": false, 
@@ -12717,7 +13663,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4704442475147199754
+          6854671567471754060
         ]
       ], 
       "ignore-failure": false, 
@@ -12727,7 +13673,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          372148908897802531
+          16657899707572687773
         ]
       ], 
       "ignore-failure": false, 
@@ -13332,46 +14278,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9359422494023233869
+          393125001874403968
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4129518398493460981
+          7796844495772667439
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14169295674273306180
+          15374275609203997765
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18253694509356273626
+          17697059014067550094
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -13724,7 +14662,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -13733,7 +14671,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -13742,7 +14680,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -13903,6 +14841,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18095396609750804641
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11882296874863336219
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7058119782533650074
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13906484169395459506
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -13964,10 +14938,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -13994,7 +14968,8 @@
           17501446579955337831
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_mesa.png": {
       "allowed-digests": [
@@ -14039,7 +15014,8 @@
           14626919895309756138
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_mesa.png": {
       "allowed-digests": [
@@ -14063,34 +15039,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7420220992884329616
+          9702900262400336960
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -14224,7 +15204,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5061253744723512316
+          6755155921388577052
         ]
       ], 
       "ignore-failure": false, 
@@ -14270,7 +15250,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2574512286616033861
+          8947348046211497261
         ]
       ], 
       "reviewed-by-human": true
@@ -14591,6 +15571,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17628572146517326838
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12650670073247231483
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2141039844592264311
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13067845786044557791
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17628572146517326838
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13004246353792273493
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14894401503896290449
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13067845786044557791
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17106217204268766211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11952609355369971735
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8763629445626037881
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5407549800302455679
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17106217204268766211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16055975013079612168
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1570033657773431514
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5407549800302455679
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -14830,28 +15954,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11287209491577059906
+          1575412881132542515
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          610849827880040391
+          7801401619129355812
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17189203782066223379
+          18349090605113364446
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_mesa.png": {
       "allowed-digests": [
@@ -14866,10 +15993,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8925491547830039513
+          2282620731115150177
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
@@ -14893,10 +16021,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10675084246400923267
+          16444559737432424692
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_mesa.png": {
       "allowed-digests": [
@@ -14995,10 +16124,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2144643099806449553
+          7073885620578418690
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_mesa.png": {
       "allowed-digests": [
@@ -15038,6 +16168,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Debug/expected-results.json b/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Debug/expected-results.json
index 1f0deff..a04ddeb 100644
--- a/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Debug/expected-results.json
@@ -142,13 +142,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-mac.png": {
       "allowed-digests": [
@@ -322,13 +322,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7585301453670699990
+          6098879441101922023
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-mac.png": {
       "allowed-digests": [
@@ -390,66 +390,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -586,10 +526,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -844,7 +784,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3516482789560301063
+          6986195247346044549
         ]
       ], 
       "reviewed-by-human": true
@@ -853,7 +793,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17939280135922697007
+          4282857988841255911
         ]
       ], 
       "reviewed-by-human": true
@@ -862,7 +802,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14406301301719837846
+          2879040974346827882
         ]
       ], 
       "reviewed-by-human": true
@@ -871,7 +811,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "reviewed-by-human": true
@@ -1213,10 +1153,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15670396195383392960
+          8673269696598503535
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -3387,6 +3330,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          346936278222712390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -3649,10 +3628,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3663,6 +3642,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -5176,31 +5191,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          438085985987860061
+          17108713816735835476
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9910004580606227246
+          14727412700340797007
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18089788802398509102
+          14977898083131641027
         ]
       ], 
       "reviewed-by-human": true
@@ -5209,31 +5218,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7906848873016763409
+          9185779902964787017
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8896323177766721496
+          16714543486061053899
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6595448497332937684
+          11320116179918134067
         ]
       ], 
       "reviewed-by-human": true
@@ -5290,31 +5293,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9530723101470813244
+          8388715572244629246
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11596878876897804224
+          1849260133786078619
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7689028667507304545
+          737709909401895757
         ]
       ], 
       "reviewed-by-human": true
@@ -5323,31 +5320,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11855218282468385074
+          2609640897702002341
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14954651981222586872
+          15936143258253863805
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8850618154374618263
+          10149436699593679171
         ]
       ], 
       "reviewed-by-human": true
@@ -5488,25 +5479,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11138456041364087997
+          8145542268708075263
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10660986017540247634
+          5128528030104918430
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4812491394626997703
+          9961444926720549533
         ]
       ], 
       "reviewed-by-human": true
@@ -5515,10 +5506,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12733104537520805965
+          1944433420282621615
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -5644,13 +5635,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5047956449610305990
+          7811307969250227070
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -5704,13 +5692,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18067789556529248416
+          9740210242819537814
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -5956,7 +5941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -6031,13 +6016,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6660636569183417958
+          1115103080046986579
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -6160,46 +6142,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7360996518918447134
+          5687278183010828692
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18188970459252048907
+          11531647857360613251
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12913991563088928773
+          12676955383869092918
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1810600077063814094
+          7414314395478860308
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -6217,49 +6191,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -6988,13 +6950,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-mac.png": {
       "allowed-digests": [
@@ -7081,37 +7043,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7298095422068480098
+          4559593148815511319
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15440720271305019367
+          17891168488186837636
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          421058666110978042
+          5433560442976955880
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-mac.png": {
       "allowed-digests": [
@@ -7209,13 +7162,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10545166542672389199
+          16086883057437485444
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -8355,6 +8305,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2280319422541178486
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -8524,13 +8510,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6933105541311972103
+          5385450980380221512
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -9357,6 +9340,258 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5754720502560945124
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6344252670904552877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11917402922015673526
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2502323078757290431
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5512187507311855443
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11469014437225752510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8823691185254277217
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2502323078757290431
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3594441802072435930
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8259981840478701749
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14893561051388592815
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557507953214120656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8174768065647839766
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11469014437225752510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8823691185254277217
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2502323078757290431
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3594441802072435930
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2149023362899746020
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15880490449814859479
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -9883,37 +10118,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9158718560267424958
+          11915340602673461027
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15728250112877579536
+          9017654430577069882
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9084320026879402193
+          15465449795335955014
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-mac.png": {
       "allowed-digests": [
@@ -10025,13 +10251,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -10181,43 +10407,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14869473461389147241
+          4450358446191608677
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16997042557102488683
+          12186616484400081652
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15099658502819950174
+          18055003409349691942
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2386314572138675027
+          8702034469291126130
         ]
       ], 
       "reviewed-by-human": true
@@ -10226,7 +10443,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15215316876375538188
+          9427069139642765472
         ]
       ], 
       "reviewed-by-human": true
@@ -10235,7 +10452,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16562979750095560446
+          5173631195162600059
         ]
       ], 
       "reviewed-by-human": true
@@ -10551,25 +10768,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -10583,37 +10803,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6459261538002025610
+          8402160723692950436
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2993436125160758059
+          7674654351353365427
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2900163680187871524
+          14979508226511938894
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -10871,13 +11082,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -11000,13 +11211,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10473859523003774030
+          4073826775453589770
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -11060,13 +11268,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7256545614857310490
+          9542378752260571354
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -11136,9 +11341,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -11220,46 +11426,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15547657131007192270
+          7278684196825676290
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14636889163812671258
+          2325294178376073230
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16798641906139237180
+          16872954599722417479
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5222842117621347857
+          8334352395170340199
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -11337,7 +11535,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11394,7 +11592,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11451,7 +11649,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11535,13 +11733,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -11829,34 +12027,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9096146171773163039
+          8862105716410247518
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14322257610947906640
+          7000268788070565802
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15583567372102453165
+          14617426113757437880
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10028657535360125944
+          11424214639135557558
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -11898,13 +12100,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -11987,6 +12189,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14962954696492920650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -12417,7 +12628,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -12426,7 +12637,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -12435,11 +12646,47 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -12594,37 +12841,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1194208603696997224
+          17229983227775256161
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8977197750746447486
+          17226215298079214212
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16685057262171472460
+          7630063388209942560
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-mac.png": {
       "allowed-digests": [
@@ -12690,13 +12928,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          983401311621557258
+          781059895238671264
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -12750,13 +12985,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2760213843229179292
+          1271849376191424689
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -12888,13 +13120,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-mac.png": {
       "allowed-digests": [
@@ -13560,7 +13792,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8523166743571704640
+          1519450481293848865
         ]
       ], 
       "reviewed-by-human": true
@@ -13587,7 +13819,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14574323693724145117
+          17452890341258841872
         ]
       ], 
       "reviewed-by-human": true
@@ -13818,7 +14050,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14256199029854029755
+          12613547384338731067
         ]
       ], 
       "reviewed-by-human": true
@@ -13827,7 +14059,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8978465217429079738
+          11379708263115810021
         ]
       ], 
       "reviewed-by-human": true
@@ -13907,7 +14139,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15975715934420382547
+          7659102386277248999
         ]
       ], 
       "reviewed-by-human": true
@@ -13916,7 +14148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9696640987342691348
+          4796617908971826562
         ]
       ], 
       "reviewed-by-human": true
@@ -13925,7 +14157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15488626259907890206
+          15810021754345762015
         ]
       ], 
       "reviewed-by-human": true
@@ -14570,46 +14802,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11073670040937865654
+          5211605619123017367
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17934983963714898594
+          6911800964813594601
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5344523825436759150
+          17153370684983975140
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9450667808507318797
+          11950059817129497188
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -15014,7 +15238,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -15023,7 +15247,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -15032,7 +15256,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -15287,10 +15511,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -15416,34 +15640,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7420220992884329616
+          9702900262400336960
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15587,7 +15815,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15874577312761973499
+          7528537384927383865
         ]
       ], 
       "reviewed-by-human": true
@@ -15614,7 +15842,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6355714605828203586
+          5914389437599076514
         ]
       ], 
       "reviewed-by-human": true
@@ -15928,6 +16156,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8679752340573720155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10593818329794009615
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16708853363377692279
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12333184336167701040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8679752340573720155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6861711383471350930
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8842238748376066025
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12333184336167701040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16787930231984103257
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12675658875403195140
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16737837537237511911
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12553865258275922205
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16787930231984103257
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13006503416783858580
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14424407606830733868
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12553865258275922205
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -16166,46 +16538,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13444808970173033007
+          5394838673504083550
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13437526506460114619
+          17091929662869962251
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15737364487559488164
+          8487322294173618087
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8366221292044135943
+          12367744648740553948
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -16247,13 +16611,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          345898905519780717
+          10255557835044221556
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-mac.png": {
       "allowed-digests": [
@@ -16361,13 +16725,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1106360726796718103
+          17423281849856450242
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-mac.png": {
       "allowed-digests": [
@@ -16389,6 +16753,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Release/expected-results.json b/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Release/expected-results.json
index ae4ff85..892ebc9 100644
--- a/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Release/expected-results.json
+++ b/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Release/expected-results.json
@@ -118,13 +118,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-mac.png": {
       "allowed-digests": [
@@ -298,13 +298,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7585301453670699990
+          6098879441101922023
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-mac.png": {
       "allowed-digests": [
@@ -366,54 +366,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -538,10 +490,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -796,7 +748,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3516482789560301063
+          6986195247346044549
         ]
       ], 
       "reviewed-by-human": true
@@ -805,7 +757,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17939280135922697007
+          4282857988841255911
         ]
       ], 
       "reviewed-by-human": true
@@ -814,7 +766,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14406301301719837846
+          2879040974346827882
         ]
       ], 
       "reviewed-by-human": true
@@ -823,7 +775,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "reviewed-by-human": true
@@ -1141,10 +1093,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15670396195383392960
+          8673269696598503535
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -3243,6 +3198,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          346936278222712390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -3457,10 +3448,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3471,6 +3462,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4888,31 +4915,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          438085985987860061
+          17108713816735835476
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9910004580606227246
+          14727412700340797007
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18089788802398509102
+          14977898083131641027
         ]
       ], 
       "reviewed-by-human": true
@@ -4921,31 +4942,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7906848873016763409
+          9185779902964787017
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8896323177766721496
+          16714543486061053899
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6595448497332937684
+          11320116179918134067
         ]
       ], 
       "reviewed-by-human": true
@@ -5002,31 +5017,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9530723101470813244
+          8388715572244629246
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11596878876897804224
+          1849260133786078619
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7689028667507304545
+          737709909401895757
         ]
       ], 
       "reviewed-by-human": true
@@ -5035,31 +5044,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11855218282468385074
+          2609640897702002341
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14954651981222586872
+          15936143258253863805
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8850618154374618263
+          10149436699593679171
         ]
       ], 
       "reviewed-by-human": true
@@ -5188,25 +5191,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11138456041364087997
+          8145542268708075263
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10660986017540247634
+          5128528030104918430
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4812491394626997703
+          9961444926720549533
         ]
       ], 
       "reviewed-by-human": true
@@ -5215,10 +5218,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12733104537520805965
+          1944433420282621615
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -5335,13 +5338,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5047956449610305990
+          7811307969250227070
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -5395,13 +5395,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18067789556529248416
+          9740210242819537814
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -5623,7 +5620,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -5686,13 +5683,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6660636569183417958
+          1115103080046986579
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -5815,46 +5809,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7360996518918447134
+          5687278183010828692
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18188970459252048907
+          11531647857360613251
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12913991563088928773
+          12676955383869092918
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1810600077063814094
+          7414314395478860308
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -5872,49 +5858,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
@@ -6547,13 +6521,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-mac.png": {
       "allowed-digests": [
@@ -6628,37 +6602,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7298095422068480098
+          4559593148815511319
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15440720271305019367
+          17891168488186837636
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          421058666110978042
+          5433560442976955880
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-mac.png": {
       "allowed-digests": [
@@ -6764,13 +6729,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10545166542672389199
+          16086883057437485444
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -7786,6 +7748,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2280319422541178486
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -7955,13 +7953,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6933105541311972103
+          5385450980380221512
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -8728,6 +8723,258 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5754720502560945124
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6344252670904552877
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11917402922015673526
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2502323078757290431
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5512187507311855443
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11469014437225752510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8823691185254277217
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2502323078757290431
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3594441802072435930
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8259981840478701749
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14893561051388592815
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557507953214120656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8174768065647839766
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11469014437225752510
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8823691185254277217
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2502323078757290431
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3594441802072435930
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2149023362899746020
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15880490449814859479
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -9206,37 +9453,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9158718560267424958
+          11915340602673461027
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15728250112877579536
+          9017654430577069882
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9084320026879402193
+          15465449795335955014
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-mac.png": {
       "allowed-digests": [
@@ -9348,13 +9586,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -9492,43 +9730,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14869473461389147241
+          4450358446191608677
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16997042557102488683
+          12186616484400081652
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15099658502819950174
+          18055003409349691942
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2386314572138675027
+          8702034469291126130
         ]
       ], 
       "reviewed-by-human": true
@@ -9537,7 +9766,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15215316876375538188
+          9427069139642765472
         ]
       ], 
       "reviewed-by-human": true
@@ -9546,7 +9775,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16562979750095560446
+          5173631195162600059
         ]
       ], 
       "reviewed-by-human": true
@@ -9862,25 +10091,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -9894,37 +10126,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6459261538002025610
+          8402160723692950436
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2993436125160758059
+          7674654351353365427
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2900163680187871524
+          14979508226511938894
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -10182,13 +10405,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -10311,13 +10534,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10473859523003774030
+          4073826775453589770
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -10371,13 +10591,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7256545614857310490
+          9542378752260571354
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -10447,9 +10664,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -10519,46 +10737,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15547657131007192270
+          7278684196825676290
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14636889163812671258
+          2325294178376073230
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16798641906139237180
+          16872954599722417479
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5222842117621347857
+          8334352395170340199
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -10636,7 +10846,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10693,7 +10903,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10750,7 +10960,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -10834,13 +11044,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -11119,34 +11329,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9096146171773163039
+          8862105716410247518
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14322257610947906640
+          7000268788070565802
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15583567372102453165
+          14617426113757437880
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10028657535360125944
+          11424214639135557558
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -11176,13 +11390,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -11241,6 +11455,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14962954696492920650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -11617,7 +11840,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -11626,7 +11849,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -11635,11 +11858,47 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -11770,37 +12029,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1194208603696997224
+          17229983227775256161
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8977197750746447486
+          17226215298079214212
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16685057262171472460
+          7630063388209942560
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-mac.png": {
       "allowed-digests": [
@@ -11866,13 +12116,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          983401311621557258
+          781059895238671264
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -11926,13 +12173,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2760213843229179292
+          1271849376191424689
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -12064,13 +12308,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-mac.png": {
       "allowed-digests": [
@@ -12700,7 +12944,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8523166743571704640
+          1519450481293848865
         ]
       ], 
       "reviewed-by-human": true
@@ -12727,7 +12971,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14574323693724145117
+          17452890341258841872
         ]
       ], 
       "reviewed-by-human": true
@@ -12922,7 +13166,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14256199029854029755
+          12613547384338731067
         ]
       ], 
       "reviewed-by-human": true
@@ -12931,7 +13175,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8978465217429079738
+          11379708263115810021
         ]
       ], 
       "reviewed-by-human": true
@@ -13011,7 +13255,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15975715934420382547
+          7659102386277248999
         ]
       ], 
       "reviewed-by-human": true
@@ -13020,7 +13264,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9696640987342691348
+          4796617908971826562
         ]
       ], 
       "reviewed-by-human": true
@@ -13029,7 +13273,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15488626259907890206
+          15810021754345762015
         ]
       ], 
       "reviewed-by-human": true
@@ -13614,46 +13858,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11073670040937865654
+          5211605619123017367
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17934983963714898594
+          6911800964813594601
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5344523825436759150
+          17153370684983975140
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9450667808507318797
+          11950059817129497188
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -14034,7 +14270,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -14043,7 +14279,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -14052,7 +14288,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -14283,10 +14519,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -14412,34 +14648,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10975102556474299334
+          4434382260803121315
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          755577654057505722
+          3824408873020225049
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7420220992884329616
+          9702900262400336960
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -14583,7 +14823,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15874577312761973499
+          7528537384927383865
         ]
       ], 
       "reviewed-by-human": true
@@ -14610,7 +14850,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6355714605828203586
+          5914389437599076514
         ]
       ], 
       "reviewed-by-human": true
@@ -14912,6 +15152,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8679752340573720155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10593818329794009615
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16708853363377692279
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12333184336167701040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8679752340573720155
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6861711383471350930
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8842238748376066025
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12333184336167701040
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16787930231984103257
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12675658875403195140
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16737837537237511911
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12553865258275922205
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16787930231984103257
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13006503416783858580
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14424407606830733868
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12553865258275922205
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -15129,46 +15513,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13444808970173033007
+          5394838673504083550
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13437526506460114619
+          17091929662869962251
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15737364487559488164
+          8487322294173618087
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8366221292044135943
+          12367744648740553948
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
@@ -15198,13 +15574,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          345898905519780717
+          10255557835044221556
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-mac.png": {
       "allowed-digests": [
@@ -15312,13 +15688,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1106360726796718103
+          17423281849856450242
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-mac.png": {
       "allowed-digests": [
@@ -15340,6 +15716,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json b/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json
index f8e669d..268f58e 100644
--- a/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json
+++ b/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/expected-results.json
@@ -142,13 +142,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-mac.png": {
       "allowed-digests": [
@@ -322,13 +322,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7585301453670699990
+          6098879441101922023
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-mac.png": {
       "allowed-digests": [
@@ -351,6 +351,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -390,66 +426,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -586,10 +562,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -844,7 +820,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3516482789560301063
+          6986195247346044549
         ]
       ], 
       "reviewed-by-human": true
@@ -853,7 +829,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17939280135922697007
+          4282857988841255911
         ]
       ], 
       "reviewed-by-human": true
@@ -862,7 +838,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14406301301719837846
+          2879040974346827882
         ]
       ], 
       "reviewed-by-human": true
@@ -871,7 +847,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "reviewed-by-human": true
@@ -1213,10 +1189,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15670396195383392960
+          8673269696598503535
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -3387,6 +3366,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          346936278222712390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -3649,10 +3664,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3663,6 +3678,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -5176,31 +5227,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          438085985987860061
+          17108713816735835476
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9910004580606227246
+          14727412700340797007
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18089788802398509102
+          14977898083131641027
         ]
       ], 
       "reviewed-by-human": true
@@ -5209,31 +5254,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7906848873016763409
+          9185779902964787017
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8896323177766721496
+          16714543486061053899
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6595448497332937684
+          11320116179918134067
         ]
       ], 
       "reviewed-by-human": true
@@ -5290,31 +5329,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9530723101470813244
+          8388715572244629246
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11596878876897804224
+          1849260133786078619
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7689028667507304545
+          737709909401895757
         ]
       ], 
       "reviewed-by-human": true
@@ -5323,31 +5356,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11855218282468385074
+          2609640897702002341
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14954651981222586872
+          15936143258253863805
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8850618154374618263
+          10149436699593679171
         ]
       ], 
       "reviewed-by-human": true
@@ -5488,25 +5515,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          27487878135383284
+          299290525989578950
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7526635288709203721
+          4959262438000071841
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15274793892560279411
+          14507472376308929914
         ]
       ], 
       "reviewed-by-human": true
@@ -5515,10 +5542,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471104266458022056
+          13698101689082826616
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -5644,13 +5671,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15565871273444368809
+          6545487005513542725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -5704,13 +5728,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14957940179851888220
+          8187308303645608543
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -5956,7 +5977,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -6031,13 +6052,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2646568142600296004
+          7435653263268033885
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -6160,46 +6178,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7360996518918447134
+          5687278183010828692
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18188970459252048907
+          11531647857360613251
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12913991563088928773
+          12676955383869092918
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1810600077063814094
+          7414314395478860308
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -6217,49 +6227,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -6277,7 +6275,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -6286,7 +6284,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -6295,7 +6293,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
       "reviewed-by-human": true
@@ -6304,13 +6302,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6328,49 +6323,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2519050949583701818
+          5976613545322007809
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6388,49 +6371,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6448,49 +6419,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12455652221971736296
+          8380951080763030595
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -6508,7 +6467,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -6517,7 +6476,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -6526,7 +6485,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
       "reviewed-by-human": true
@@ -6535,13 +6494,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6559,49 +6515,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4878087893157172610
+          17064895090763866225
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6619,49 +6563,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6679,49 +6611,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6155554109563033370
+          2065497081829583993
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -6739,7 +6659,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1194712295639060571
+          2808779372617310289
         ]
       ], 
       "reviewed-by-human": true
@@ -6748,7 +6668,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16174614172336845225
+          16545446640991730163
         ]
       ], 
       "reviewed-by-human": true
@@ -6757,7 +6677,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14789607656538828465
+          6921993107840503722
         ]
       ], 
       "reviewed-by-human": true
@@ -6766,13 +6686,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12176664247208500993
+          2140129066020504148
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6790,31 +6707,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17344224489353197134
+          17596993571244704527
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4078521593207609256
+          14778109919964092466
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13321318023015871272
+          13196729628535970551
         ]
       ], 
       "reviewed-by-human": true
@@ -6823,13 +6734,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12176664247208500993
+          2140129066020504148
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6847,31 +6755,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9022651218968780517
+          8734216036921787059
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          918373436065877396
+          6526784784687902513
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14789607656538828465
+          6921993107840503722
         ]
       ], 
       "reviewed-by-human": true
@@ -6880,13 +6782,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12176664247208500993
+          2140129066020504148
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6904,49 +6803,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11490831310369554229
+          10953357379677359291
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18140940615090040158
+          14028537401806247066
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15149046239979444131
+          1482028884227623567
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12176664247208500993
+          2140129066020504148
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6964,13 +6851,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -6988,13 +6872,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-mac.png": {
       "allowed-digests": [
@@ -7021,13 +6905,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16464180119281004551
+          17355934809820918146
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -7081,37 +6962,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7298095422068480098
+          4559593148815511319
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15440720271305019367
+          17891168488186837636
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          421058666110978042
+          5433560442976955880
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-mac.png": {
       "allowed-digests": [
@@ -7209,13 +7081,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10545166542672389199
+          16086883057437485444
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -7409,6 +7278,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -7701,7 +7606,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -7710,7 +7615,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -7748,7 +7653,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -7757,7 +7662,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -7795,7 +7700,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -7804,7 +7709,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -7842,7 +7747,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -7851,7 +7756,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -7889,7 +7794,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -7898,7 +7803,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -7936,7 +7841,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -7945,7 +7850,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -7983,7 +7888,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -7992,7 +7897,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -8030,7 +7935,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -8039,7 +7944,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -8077,7 +7982,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -8086,7 +7991,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -8171,7 +8076,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -8180,7 +8085,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -8265,7 +8170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8726635984120251137
+          3924003715864408328
         ]
       ], 
       "reviewed-by-human": true
@@ -8274,7 +8179,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10722832041625329874
+          17817341224996846104
         ]
       ], 
       "reviewed-by-human": true
@@ -8312,7 +8217,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4466082290073531062
+          6191209484355168001
         ]
       ], 
       "reviewed-by-human": true
@@ -8321,7 +8226,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11157177322312317181
+          10677165858451950339
         ]
       ], 
       "reviewed-by-human": true
@@ -8355,6 +8260,42 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17052873949347861482
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -8371,37 +8312,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2923727738525710795
+          2425644440618781106
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6095335716309928708
+          17798897784508333200
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4006703836460015240
+          5914317227580657676
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
@@ -8520,17 +8452,50 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3610620274427825456
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11608780551395276942
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17645289349125251696
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14095919809525179386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12872428137492657225
+          3687488920536317769
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -9357,6 +9322,294 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2902090852508957882
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8003986504359203333
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4926111011675128636
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15937320568943303273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11745644499552256973
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2627991343461002616
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1582657629558125819
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15937320568943303273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11676737936175321539
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8259981840478701749
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1966492872216272409
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557507953214120656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9495717480904350154
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2627991343461002616
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1582657629558125819
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15937320568943303273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11676737936175321539
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2149023362899746020
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17116113789327076952
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2756771085785913839
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12370407365013342828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7298563598521283160
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7203144125028809771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -9388,10 +9641,7 @@
           7829581953999677788
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-mac.png": {
       "allowed-digests": [
@@ -9499,7 +9749,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-mac.png": {
       "allowed-digests": [
@@ -9535,7 +9785,7 @@
           9677442873231842372
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-mac.png": {
       "allowed-digests": [
@@ -9571,7 +9821,7 @@
           3090817784180349654
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-mac.png": {
       "allowed-digests": [
@@ -9832,7 +10082,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -9883,25 +10133,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9161474548197839772
+          1196992559341551804
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4437791810524083176
+          11341488244958220268
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -9910,10 +10154,7 @@
           6426034390838459732
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-mac.png": {
       "allowed-digests": [
@@ -10025,13 +10266,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -10177,47 +10418,74 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9608958026324610750
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1072398151931745130
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11678564671792396439
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8212424581111328793
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9797118317215464695
+          12006230766204467056
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12650372322449345601
+          13332567911887670120
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12728597496442589556
+          2785713521997066899
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13560757344541576520
+          16824094486659314550
         ]
       ], 
       "reviewed-by-human": true
@@ -10226,7 +10494,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15367116077543893369
+          2952162885890239150
         ]
       ], 
       "reviewed-by-human": true
@@ -10235,7 +10503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9053945589234582421
+          14016676347560822434
         ]
       ], 
       "reviewed-by-human": true
@@ -10551,25 +10819,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -10583,37 +10854,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13517124986811807474
+          8881145964157255702
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630035333111010942
+          231049563686566065
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9486162745552233172
+          7398251839257822665
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -10871,13 +11133,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -11000,13 +11262,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2546262337440795131
+          1937773844931758475
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -11060,13 +11319,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8862067760135184901
+          4982904661847773385
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -11136,9 +11392,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -11220,46 +11477,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15547657131007192270
+          4069626359737943030
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14636889163812671258
+          6093865524984698180
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16798641906139237180
+          9301285623493541837
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5222842117621347857
+          2649401612919659015
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -11337,7 +11586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11394,7 +11643,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11451,7 +11700,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11535,13 +11784,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -11624,6 +11873,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712923251277710326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4443863184936217029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10033547804616068548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4381959501339171759
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3873095513352910051
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8759449444261779571
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7450316469051364550
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18104149097289142823
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6609016078678717837
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16356648792486681056
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -11829,34 +12438,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9096146171773163039
+          8862105716410247518
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14322257610947906640
+          7000268788070565802
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15583567372102453165
+          14617426113757437880
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10028657535360125944
+          11424214639135557558
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -11898,13 +12511,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -11987,6 +12600,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          526671347486000095
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          315162850214656667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          834353666864975522
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          736103432728252861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -12417,7 +13102,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -12426,7 +13111,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -12435,11 +13120,47 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -12497,6 +13218,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          99805091459040859
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -12533,6 +13290,42 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -12594,37 +13387,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          629821941870256645
+          12884571093974353905
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          350854785021884881
+          13543648152054227175
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11130345882866091654
+          13289089982625103849
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-mac.png": {
       "allowed-digests": [
@@ -12690,13 +13474,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13775520417654625690
+          507602684001895289
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -12750,13 +13531,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1496036221287123764
+          16345939908493056603
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -12888,13 +13666,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-mac.png": {
       "allowed-digests": [
@@ -13560,7 +14338,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8523166743571704640
+          1519450481293848865
         ]
       ], 
       "reviewed-by-human": true
@@ -13587,7 +14365,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14574323693724145117
+          17452890341258841872
         ]
       ], 
       "reviewed-by-human": true
@@ -13818,7 +14596,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10547773479883336688
+          6651118343277262089
         ]
       ], 
       "reviewed-by-human": true
@@ -13827,7 +14605,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11943435293466893439
+          1703243925595618753
         ]
       ], 
       "reviewed-by-human": true
@@ -13858,7 +14636,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9925437062346155958
+          3888857556865804716
         ]
       ], 
       "reviewed-by-human": true
@@ -13907,7 +14685,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15975715934420382547
+          7659102386277248999
         ]
       ], 
       "reviewed-by-human": true
@@ -13916,7 +14694,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9696640987342691348
+          4796617908971826562
         ]
       ], 
       "reviewed-by-human": true
@@ -13925,7 +14703,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15488626259907890206
+          15810021754345762015
         ]
       ], 
       "reviewed-by-human": true
@@ -14570,46 +15348,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11073670040937865654
+          5211605619123017367
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17934983963714898594
+          6911800964813594601
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5344523825436759150
+          17153370684983975140
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9450667808507318797
+          11950059817129497188
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -15014,7 +15784,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -15023,7 +15793,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -15032,7 +15802,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -15223,6 +15993,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17257438050358379773
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4004695096216748211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          490695971561407254
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13906484169395459506
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -15287,10 +16093,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -15323,10 +16129,7 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-mac.png": {
       "allowed-digests": [
@@ -15383,10 +16186,7 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-mac.png": {
       "allowed-digests": [
@@ -15416,34 +16216,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9221871076009801406
+          18417437552773176864
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13752889104305409841
+          14795861386913800488
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13752889104305409841
+          14795861386913800488
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9215724429865335100
+          5398732324300827370
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15587,7 +16391,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15874577312761973499
+          7528537384927383865
         ]
       ], 
       "reviewed-by-human": true
@@ -15614,7 +16418,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6355714605828203586
+          5914389437599076514
         ]
       ], 
       "reviewed-by-human": true
@@ -15928,6 +16732,150 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11036341991050210951
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16335490382738661925
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2504206901225584494
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17934077009272289263
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11036341991050210951
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14896593775241841936
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11038426272403209801
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17934077009272289263
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2485988702935970844
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4587757309724885298
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18223236230911025154
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7092552829173842465
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2485988702935970844
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15149319253017354950
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10459303419023414243
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7092552829173842465
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -16166,46 +17114,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13444808970173033007
+          5394838673504083550
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13437526506460114619
+          17091929662869962251
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15737364487559488164
+          8487322294173618087
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8366221292044135943
+          12367744648740553948
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -16247,13 +17187,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          345898905519780717
+          10255557835044221556
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-mac.png": {
       "allowed-digests": [
@@ -16361,13 +17301,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1106360726796718103
+          17423281849856450242
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-mac.png": {
       "allowed-digests": [
@@ -16389,6 +17329,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json b/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json
index 4703ece..d46fc0b 100644
--- a/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json
+++ b/expectations/gm/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Release/expected-results.json
@@ -136,13 +136,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3315121183069039719
+          732637529794329269
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-mac.png": {
       "allowed-digests": [
@@ -307,13 +307,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7585301453670699990
+          6098879441101922023
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-mac.png": {
       "allowed-digests": [
@@ -345,6 +345,54 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1864820902552691714
+        ]
+      ], 
+      "bugs": [
+        2832
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -384,63 +432,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-mac.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12055561269186852835
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-native.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10563148403190576093
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -571,10 +562,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-mac.png": {
       "allowed-digests": [
@@ -850,7 +841,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3516482789560301063
+          6986195247346044549
         ]
       ], 
       "reviewed-by-human": true
@@ -859,7 +850,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17939280135922697007
+          4282857988841255911
         ]
       ], 
       "reviewed-by-human": true
@@ -868,7 +859,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14406301301719837846
+          2879040974346827882
         ]
       ], 
       "reviewed-by-human": true
@@ -877,7 +868,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2911931176733381504
+          5753381857408042105
         ]
       ], 
       "reviewed-by-human": true
@@ -886,7 +877,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6969751783855069272
+          1475402476441666555
         ]
       ], 
       "reviewed-by-human": true
@@ -1234,10 +1225,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15670396195383392960
+          8673269696598503535
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-mac.png": {
       "allowed-digests": [
@@ -3303,6 +3297,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          346936278222712390
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13639887636199639849
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -3517,10 +3556,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-mac.png": {
       "allowed-digests": [
@@ -3540,6 +3579,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1571488556534675441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18324784283320246863
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -5068,31 +5152,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          438085985987860061
+          17108713816735835476
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9910004580606227246
+          14727412700340797007
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18089788802398509102
+          14977898083131641027
         ]
       ], 
       "reviewed-by-human": true
@@ -5101,31 +5179,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7906848873016763409
+          9185779902964787017
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8896323177766721496
+          16714543486061053899
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6595448497332937684
+          11320116179918134067
         ]
       ], 
       "reviewed-by-human": true
@@ -5146,10 +5218,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933251792933799140
+          9528325689827931037
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -5179,7 +5251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4573011093667496706
+          13429706392276452751
         ]
       ], 
       "reviewed-by-human": true
@@ -5200,31 +5272,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9530723101470813244
+          8388715572244629246
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11596878876897804224
+          1849260133786078619
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7689028667507304545
+          737709909401895757
         ]
       ], 
       "reviewed-by-human": true
@@ -5233,31 +5299,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11855218282468385074
+          2609640897702002341
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14954651981222586872
+          15936143258253863805
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8850618154374618263
+          10149436699593679171
         ]
       ], 
       "reviewed-by-human": true
@@ -5278,7 +5338,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2838872793515188592
+          3319636079639200276
         ]
       ], 
       "reviewed-by-human": true
@@ -5311,7 +5371,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1103035032195768549
+          5855822768926779617
         ]
       ], 
       "reviewed-by-human": true
@@ -5422,25 +5482,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          27487878135383284
+          299290525989578950
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7526635288709203721
+          4959262438000071841
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15274793892560279411
+          14507472376308929914
         ]
       ], 
       "reviewed-by-human": true
@@ -5449,19 +5509,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471104266458022056
+          13698101689082826616
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15039431616480054261
+          255576588291493518
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_gpu.png": {
       "allowed-digests": [
@@ -5596,13 +5656,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15565871273444368809
+          6545487005513542725
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -5644,7 +5701,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8557952399971613170
+          15732283515166172928
         ]
       ], 
       "reviewed-by-human": true
@@ -5665,13 +5722,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14957940179851888220
+          8187308303645608543
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -5713,7 +5767,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          138516984898060998
+          10545770677509510387
         ]
       ], 
       "reviewed-by-human": true
@@ -5917,7 +5971,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10916419994292168605
+          17509002517889485628
         ]
       ], 
       "reviewed-by-human": true
@@ -5998,13 +6052,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2646568142600296004
+          7435653263268033885
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -6046,7 +6097,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11873922145341656317
+          9021261987800552505
         ]
       ], 
       "reviewed-by-human": true
@@ -6145,118 +6196,98 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7360996518918447134
+          5687278183010828692
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18188970459252048907
+          11531647857360613251
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12913991563088928773
+          12676955383869092918
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1810600077063814094
+          7414314395478860308
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14959252445091379373
+          15609000996688532221
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -6265,7 +6296,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -6274,7 +6305,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
       "reviewed-by-human": true
@@ -6283,19 +6314,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11417614158990841541
+          17682238166057708384
         ]
       ], 
       "reviewed-by-human": true
@@ -6304,55 +6332,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2519050949583701818
+          5976613545322007809
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11417614158990841541
+          17682238166057708384
         ]
       ], 
       "reviewed-by-human": true
@@ -6361,55 +6377,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6481939352948074473
+          17653475865218299100
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11417614158990841541
+          17682238166057708384
         ]
       ], 
       "reviewed-by-human": true
@@ -6418,55 +6422,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12455652221971736296
+          8380951080763030595
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16093357615070406962
+          7538152569095094254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11417614158990841541
+          17682238166057708384
         ]
       ], 
       "reviewed-by-human": true
@@ -6475,7 +6467,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -6484,7 +6476,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -6493,7 +6485,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
       "reviewed-by-human": true
@@ -6502,19 +6494,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2929669555809205000
+          1857028492049082890
         ]
       ], 
       "reviewed-by-human": true
@@ -6535,55 +6524,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4878087893157172610
+          17064895090763866225
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2929669555809205000
+          1857028492049082890
         ]
       ], 
       "reviewed-by-human": true
@@ -6604,55 +6581,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13242845885221560615
+          10401816495806428775
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2929669555809205000
+          1857028492049082890
         ]
       ], 
       "reviewed-by-human": true
@@ -6673,55 +6638,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6155554109563033370
+          2065497081829583993
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4728543805842578754
+          11462742134243594933
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2929669555809205000
+          1857028492049082890
         ]
       ], 
       "reviewed-by-human": true
@@ -6742,7 +6695,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1194712295639060571
+          2808779372617310289
         ]
       ], 
       "reviewed-by-human": true
@@ -6751,7 +6704,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16174614172336845225
+          16545446640991730163
         ]
       ], 
       "reviewed-by-human": true
@@ -6760,7 +6713,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14789607656538828465
+          6921993107840503722
         ]
       ], 
       "reviewed-by-human": true
@@ -6769,19 +6722,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12176664247208500993
+          2140129066020504148
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7169151292796170653
+          2767543098518448000
         ]
       ], 
       "reviewed-by-human": true
@@ -6802,31 +6752,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17344224489353197134
+          17596993571244704527
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4078521593207609256
+          14778109919964092466
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13321318023015871272
+          13196729628535970551
         ]
       ], 
       "reviewed-by-human": true
@@ -6835,19 +6779,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12176664247208500993
+          2140129066020504148
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7169151292796170653
+          2767543098518448000
         ]
       ], 
       "reviewed-by-human": true
@@ -6868,31 +6809,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9022651218968780517
+          8734216036921787059
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          918373436065877396
+          6526784784687902513
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14789607656538828465
+          6921993107840503722
         ]
       ], 
       "reviewed-by-human": true
@@ -6901,19 +6836,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12176664247208500993
+          2140129066020504148
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7169151292796170653
+          2767543098518448000
         ]
       ], 
       "reviewed-by-human": true
@@ -6934,55 +6866,43 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11490831310369554229
+          10953357379677359291
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18140940615090040158
+          14028537401806247066
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15149046239979444131
+          1482028884227623567
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12176664247208500993
+          2140129066020504148
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7169151292796170653
+          2767543098518448000
         ]
       ], 
       "reviewed-by-human": true
@@ -7003,13 +6923,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -7027,13 +6944,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5138827235681832044
+          1111702777882128269
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-mac.png": {
       "allowed-digests": [
@@ -7057,13 +6974,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16464180119281004551
+          17355934809820918146
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -7114,37 +7028,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7298095422068480098
+          4559593148815511319
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15440720271305019367
+          17891168488186837636
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          421058666110978042
+          5433560442976955880
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-mac.png": {
       "allowed-digests": [
@@ -7162,7 +7067,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7715394634144893966
+          18078265559939067235
         ]
       ], 
       "reviewed-by-human": true
@@ -7276,13 +7181,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10545166542672389199
+          16086883057437485444
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -7324,10 +7226,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8495652173329351569
+          12468837360216416021
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -7521,6 +7423,54 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14095514329977820919
+        ]
+      ], 
+      "bugs": [
+        2832
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -7810,7 +7760,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -7819,7 +7769,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -7857,7 +7807,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -7866,7 +7816,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -7904,7 +7854,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -7913,7 +7863,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -7961,7 +7911,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -7970,7 +7920,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -8008,7 +7958,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -8017,7 +7967,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -8054,7 +8004,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -8063,7 +8013,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -8111,7 +8061,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -8120,7 +8070,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -8158,7 +8108,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -8167,7 +8117,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -8214,7 +8164,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -8223,7 +8173,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -8317,7 +8267,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -8326,7 +8276,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -8411,7 +8361,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8726635984120251137
+          3924003715864408328
         ]
       ], 
       "reviewed-by-human": true
@@ -8420,7 +8370,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10722832041625329874
+          17817341224996846104
         ]
       ], 
       "reviewed-by-human": true
@@ -8458,7 +8408,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4466082290073531062
+          6191209484355168001
         ]
       ], 
       "reviewed-by-human": true
@@ -8467,7 +8417,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11157177322312317181
+          10677165858451950339
         ]
       ], 
       "reviewed-by-human": true
@@ -8501,6 +8451,51 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2410801700961591983
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17052873949347861482
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          451012912567537881
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -8517,37 +8512,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2923727738525710795
+          2425644440618781106
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6095335716309928708
+          17798897784508333200
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4006703836460015240
+          5914317227580657676
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
@@ -8684,17 +8670,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3610620274427825456
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11608780551395276942
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17645289349125251696
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14095919809525179386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2599237996435538668
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12872428137492657225
+          3687488920536317769
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -9516,6 +9544,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13403366906199904982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17126897731288245806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10757728341821326298
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2902090852508957882
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6875032678428722187
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8003986504359203333
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4926111011675128636
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15937320568943303273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11745644499552256973
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18004220278950936283
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2627991343461002616
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1582657629558125819
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15937320568943303273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11676737936175321539
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18004220278950936283
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3273377749308495008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5478530947153704718
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8259981840478701749
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1966492872216272409
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          623251485184688601
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2557590184015265914
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3863034158844721400
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557507953214120656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9495717480904350154
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15351333361032644205
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2627991343461002616
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1582657629558125819
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15937320568943303273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11676737936175321539
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18004220278950936283
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6411157279702973888
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13509575348949939743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2149023362899746020
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17116113789327076952
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15351333361032644205
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2756771085785913839
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12370407365013342828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7298563598521283160
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7203144125028809771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7193239408499701443
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -9547,10 +9935,7 @@
           7829581953999677788
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-mac.png": {
       "allowed-digests": [
@@ -9652,7 +10037,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-mac.png": {
       "allowed-digests": [
@@ -9697,7 +10082,7 @@
           9677442873231842372
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-mac.png": {
       "allowed-digests": [
@@ -9742,7 +10127,7 @@
           3090817784180349654
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-mac.png": {
       "allowed-digests": [
@@ -10021,7 +10406,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -10069,25 +10454,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9161474548197839772
+          1196992559341551804
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4437791810524083176
+          11341488244958220268
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -10096,10 +10475,7 @@
           6426034390838459732
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-mac.png": {
       "allowed-digests": [
@@ -10217,13 +10593,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3294926585174064910
+          18258056184409556905
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -10372,47 +10748,83 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9608958026324610750
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1072398151931745130
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11678564671792396439
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8212424581111328793
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3962137073116654394
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9797118317215464695
+          12006230766204467056
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12650372322449345601
+          13332567911887670120
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12728597496442589556
+          2785713521997066899
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13560757344541576520
+          16824094486659314550
         ]
       ], 
       "reviewed-by-human": true
@@ -10421,7 +10833,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15367116077543893369
+          2952162885890239150
         ]
       ], 
       "reviewed-by-human": true
@@ -10430,7 +10842,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9053945589234582421
+          14016676347560822434
         ]
       ], 
       "reviewed-by-human": true
@@ -10448,10 +10860,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3685369701056692339
+          6378226693183597340
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_pdf-mac.png": {
       "allowed-digests": [
@@ -10469,10 +10881,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3685369701056692339
+          6378226693183597340
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_pdf-poppler.png": {
       "allowed-digests": [
@@ -10805,25 +11217,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8126282611016392185
+          9414100593029520033
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-mac.png": {
       "allowed-digests": [
@@ -10846,37 +11261,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13517124986811807474
+          8881145964157255702
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630035333111010942
+          231049563686566065
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9486162745552233172
+          7398251839257822665
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-mac.png": {
       "allowed-digests": [
@@ -10894,10 +11300,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3685369701056692339
+          6378226693183597340
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_565.png": {
       "allowed-digests": [
@@ -11155,13 +11561,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4021252917133180712
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-mac.png": {
       "allowed-digests": [
@@ -11287,13 +11693,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2546262337440795131
+          1937773844931758475
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -11335,7 +11738,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13607393328072223058
+          3957823738717639714
         ]
       ], 
       "reviewed-by-human": true
@@ -11356,13 +11759,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8862067760135184901
+          4982904661847773385
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -11404,7 +11804,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14681530284938562109
+          7818150155951602556
         ]
       ], 
       "reviewed-by-human": true
@@ -11441,9 +11841,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371716533453042652
+          5252555163271260722
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-mac.png": {
       "allowed-digests": [
@@ -11526,52 +11927,44 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15547657131007192270
+          4069626359737943030
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14636889163812671258
+          6093865524984698180
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16798641906139237180
+          9301285623493541837
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5222842117621347857
+          2649401612919659015
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7521888051668081535
+          2203428644684228800
         ]
       ], 
       "reviewed-by-human": true
@@ -11649,7 +12042,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11703,7 +12096,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11757,7 +12150,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -11838,13 +12231,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          6168032688602434941
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-mac.png": {
       "allowed-digests": [
@@ -11933,6 +12326,456 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712923251277710326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4443863184936217029
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10033547804616068548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4381959501339171759
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3873095513352910051
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8759449444261779571
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7450316469051364550
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18104149097289142823
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6609016078678717837
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16356648792486681056
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -12141,40 +12984,44 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9096146171773163039
+          8862105716410247518
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14322257610947906640
+          7000268788070565802
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15583567372102453165
+          14617426113757437880
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10028657535360125944
+          11424214639135557558
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5995928192042218612
+          16216123146985044324
         ]
       ], 
       "reviewed-by-human": true
@@ -12207,13 +13054,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          14415361990696875204
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-mac.png": {
       "allowed-digests": [
@@ -12290,6 +13137,96 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          526671347486000095
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          315162850214656667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2369041079816362152
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          834353666864975522
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          736103432728252861
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6626420070719803954
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -12714,7 +13651,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -12723,7 +13660,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -12732,11 +13669,56 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16881627692812078573
+          6945090583139588959
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13631218334089896337
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-mac.png": {
       "allowed-digests": [
         [
@@ -12800,6 +13782,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          99805091459040859
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9784267484294405486
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -12845,6 +13872,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -12903,37 +13975,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          629821941870256645
+          12884571093974353905
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          350854785021884881
+          13543648152054227175
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11130345882866091654
+          13289089982625103849
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-mac.png": {
       "allowed-digests": [
@@ -12951,7 +14014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6755079989498392657
+          17973888395623304656
         ]
       ], 
       "reviewed-by-human": true
@@ -13017,13 +14080,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13775520417654625690
+          507602684001895289
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -13065,10 +14125,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16872771988986585171
+          2773662249556805029
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13086,13 +14146,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1496036221287123764
+          16345939908493056603
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -13134,7 +14191,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11228911889295878011
+          4007030279944286561
         ]
       ], 
       "reviewed-by-human": true
@@ -13230,13 +14287,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          16832628682857079624
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-mac.png": {
       "allowed-digests": [
@@ -13957,7 +15014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8523166743571704640
+          1519450481293848865
         ]
       ], 
       "reviewed-by-human": true
@@ -13984,7 +15041,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14574323693724145117
+          17452890341258841872
         ]
       ], 
       "reviewed-by-human": true
@@ -14232,7 +15289,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10547773479883336688
+          6651118343277262089
         ]
       ], 
       "reviewed-by-human": true
@@ -14241,7 +15298,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11943435293466893439
+          1703243925595618753
         ]
       ], 
       "reviewed-by-human": true
@@ -14281,7 +15338,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9925437062346155958
+          3888857556865804716
         ]
       ], 
       "reviewed-by-human": true
@@ -14339,7 +15396,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15975715934420382547
+          7659102386277248999
         ]
       ], 
       "reviewed-by-human": true
@@ -14348,7 +15405,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9696640987342691348
+          4796617908971826562
         ]
       ], 
       "reviewed-by-human": true
@@ -14357,7 +15414,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15488626259907890206
+          15810021754345762015
         ]
       ], 
       "reviewed-by-human": true
@@ -15027,55 +16084,47 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11073670040937865654
+          5211605619123017367
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17934983963714898594
+          6911800964813594601
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5344523825436759150
+          17153370684983975140
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9450667808507318797
+          11950059817129497188
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18066056440315462315
+          6252023998108177460
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -15459,7 +16508,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14061060998594981108
+          4540758465788138693
         ]
       ], 
       "reviewed-by-human": true
@@ -15468,7 +16517,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13205076994244157607
+          6947833843628630223
         ]
       ], 
       "reviewed-by-human": true
@@ -15477,7 +16526,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2614658944612492840
+          644645243155308208
         ]
       ], 
       "reviewed-by-human": true
@@ -15495,7 +16544,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13344800184383511415
+          5790659396096634931
         ]
       ], 
       "reviewed-by-human": true
@@ -15659,6 +16708,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17257438050358379773
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4004695096216748211
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          490695971561407254
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13906484169395459506
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7693679797078782821
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -15732,10 +16826,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -15768,10 +16862,7 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-mac.png": {
       "allowed-digests": [
@@ -15825,10 +16916,7 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-mac.png": {
       "allowed-digests": [
@@ -15855,40 +16943,44 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9221871076009801406
+          18417437552773176864
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13752889104305409841
+          14795861386913800488
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13752889104305409841
+          14795861386913800488
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9215724429865335100
+          5398732324300827370
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9215724429865335100
+          5398732324300827370
         ]
       ], 
       "reviewed-by-human": true
@@ -16041,7 +17133,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15874577312761973499
+          7528537384927383865
         ]
       ], 
       "reviewed-by-human": true
@@ -16068,7 +17160,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6355714605828203586
+          5914389437599076514
         ]
       ], 
       "reviewed-by-human": true
@@ -16433,6 +17525,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11036341991050210951
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16335490382738661925
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4688593307220918483
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17934077009272289263
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10952334352497413189
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11036341991050210951
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14896593775241841936
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4170663069537039843
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17934077009272289263
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10952334352497413189
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2485988702935970844
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4587757309724885298
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18223236230911025154
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7092552829173842465
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17169372055298113271
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2485988702935970844
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15149319253017354950
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10459303419023414243
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-mac.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7092552829173842465
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-native.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17169372055298113271
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -16719,52 +17991,44 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13444808970173033007
+          5394838673504083550
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13437526506460114619
+          17091929662869962251
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15737364487559488164
+          8487322294173618087
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-mac.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8366221292044135943
+          12367744648740553948
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-native.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1336366624407579096
+          10233699036798629910
         ]
       ], 
       "reviewed-by-human": true
@@ -16797,13 +18061,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          345898905519780717
+          10255557835044221556
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-mac.png": {
       "allowed-digests": [
@@ -16929,13 +18193,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1106360726796718103
+          17423281849856450242
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-mac.png": {
       "allowed-digests": [
@@ -16966,6 +18230,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86-Debug/expected-results.json b/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86-Debug/expected-results.json
index 487707e..9754147 100644
--- a/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86-Debug/expected-results.json
@@ -153,38 +153,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -348,38 +348,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          8509476067209440798
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          6953582728625873818
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          4850895322567541620
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -390,6 +387,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3358888352773124551
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -483,69 +534,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12332389189099053788
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -712,37 +700,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -993,13 +972,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15308835346079711937
+          13663949626340090597
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -1014,7 +990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9707111840054705070
+          5753977543166902872
         ]
       ], 
       "ignore-failure": false, 
@@ -1024,7 +1000,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966472219258108320
+          3622726894191108275
         ]
       ], 
       "ignore-failure": false, 
@@ -1034,7 +1010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5388227895717978780
+          5008177951711187426
         ]
       ], 
       "ignore-failure": false, 
@@ -1044,7 +1020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7908101291719253601
+          2625617788607302304
         ]
       ], 
       "reviewed-by-human": true
@@ -1053,7 +1029,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5388227895717978780
+          15847638636930861743
         ]
       ], 
       "reviewed-by-human": true
@@ -1062,7 +1038,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4425981769758897451
+          8652857569622477512
         ]
       ], 
       "reviewed-by-human": true
@@ -1474,28 +1450,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -1600,13 +1585,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurquickreject_nvprmsaa4.png": {
       "allowed-digests": [
@@ -3818,6 +3800,60 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9127987412867969701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -4146,37 +4182,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -4187,6 +4214,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2767554231532657737
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4306,13 +4387,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17103835371669353467
+          10122332848450541880
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -4544,13 +4622,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8342401373468633748
+          10088452398931315952
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -5359,13 +5434,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2874808003280900420
+          10568305498027471247
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -5513,25 +5585,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14602262721761630857
+          7017815369204328634
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          14149123815610089425
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
       "reviewed-by-human": true
@@ -5540,37 +5612,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1995539702399150009
+          10363407019316773455
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -5954,85 +6017,77 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9308347137055900457
+          11137376764949716657
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          70554801271357149
+          9237294305986351770
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2893820023009333324
+          5842617443052169408
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11986351729917860717
+          6664819925988745829
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17407721376245627230
+          7782456344628243848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13259111868844875039
+          17699771136066957749
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6886995277392420867
+          12446109424042490351
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17234618925843989936
+          857815900353647485
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6047,25 +6102,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17289619728742065294
+          12167696310276417671
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          298289002043954726
+          15112343104874953659
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_pdf-poppler.png": {
       "allowed-digests": [
@@ -6080,85 +6129,77 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17046138572928461942
+          1060100128535571349
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16848821614766946815
+          2130878875932816169
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11656665183177874362
+          2530953864070751441
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14046532233792735234
+          10215436687867452743
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6040117814573953462
+          60525349492118674
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3691285029135011922
+          7507188018788541198
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          636883424267411162
+          8045133037980648445
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11150731716715141897
+          13732634818710636058
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6173,25 +6214,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3382891004691951866
+          14508705528594025331
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11236143476052676434
+          7004399922767132272
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -6314,7 +6349,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4110722122594872859
+          3692847587555755996
         ]
       ], 
       "reviewed-by-human": true
@@ -6323,7 +6358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15192724137559208204
+          12867323471223068426
         ]
       ], 
       "reviewed-by-human": true
@@ -6332,7 +6367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12390000919902989614
+          8566631317914568343
         ]
       ], 
       "reviewed-by-human": true
@@ -6341,31 +6376,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12210515662385677484
+          6633944641607131513
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17274497380173363267
+          16204544386885042034
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13214515577780181252
+          2035440368234831638
         ]
       ], 
       "reviewed-by-human": true
@@ -6530,10 +6559,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14629387967092406744
+          489208137730623687
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -6573,13 +6603,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7786557523508893251
+          12079760358174422971
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6597,10 +6624,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8947422315903317870
+          3220333313183474890
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -6640,13 +6668,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17290567770120363032
+          12110591489796654880
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6853,7 +6878,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11983291604958613824
+          4119744344752250956
         ]
       ], 
       "reviewed-by-human": true
@@ -6953,10 +6978,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18018965749997300368
+          9095643239105155650
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -6996,12 +7022,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13517902628428185359
+          4757316088197438923
         ]
       ], 
       "bugs": [
-        2325
+        2826
       ], 
+      "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
     "degeneratesegments_pdf-poppler.png": {
@@ -7104,62 +7131,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16850764937772706343
+          3377544910324212919
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14105405523972827206
+          7432066987408472244
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5600826535722550519
+          64614149029383431
         ]
       ], 
       "reviewed-by-human": true
@@ -7168,79 +7188,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -7249,7 +7251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -7258,7 +7260,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7267,7 +7269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16451780885896960300
+          14204243393620033211
         ]
       ], 
       "reviewed-by-human": true
@@ -7276,7 +7278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7285,7 +7287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7294,7 +7296,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
       "reviewed-by-human": true
@@ -7303,7 +7305,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
       "reviewed-by-human": true
@@ -7312,43 +7314,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443130797061158720
+          3590945223549597113
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7357,7 +7350,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
       "reviewed-by-human": true
@@ -7366,7 +7359,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
       "reviewed-by-human": true
@@ -7375,43 +7368,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8034132364379362582
+          17212795401772012692
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7420,7 +7404,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
       "reviewed-by-human": true
@@ -7429,7 +7413,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
       "reviewed-by-human": true
@@ -7438,43 +7422,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15854240744220847964
+          12495564829829617636
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7483,7 +7458,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -7492,7 +7467,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -7501,7 +7476,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7510,7 +7485,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61543217406202998
+          11968003402313032299
         ]
       ], 
       "reviewed-by-human": true
@@ -7519,7 +7494,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7528,7 +7503,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532637637939557491
+          13364626080781238305
         ]
       ], 
       "reviewed-by-human": true
@@ -7537,7 +7512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
       "reviewed-by-human": true
@@ -7546,7 +7521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
       "reviewed-by-human": true
@@ -7555,43 +7530,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2171610356153094701
+          8951768093676734731
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532637637939557491
+          13364626080781238305
         ]
       ], 
       "reviewed-by-human": true
@@ -7600,7 +7566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
       "reviewed-by-human": true
@@ -7609,7 +7575,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
       "reviewed-by-human": true
@@ -7618,43 +7584,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6692547324448596108
+          16032430115842971269
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532637637939557491
+          13364626080781238305
         ]
       ], 
       "reviewed-by-human": true
@@ -7663,7 +7620,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
       "reviewed-by-human": true
@@ -7672,7 +7629,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
       "reviewed-by-human": true
@@ -7681,43 +7638,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12362918265113141584
+          352963511646887173
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532637637939557491
+          13364626080781238305
         ]
       ], 
       "reviewed-by-human": true
@@ -7726,7 +7674,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          316392167046886906
+          11438413222729306097
         ]
       ], 
       "reviewed-by-human": true
@@ -7735,7 +7683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3203476165028839490
+          140707004996434734
         ]
       ], 
       "reviewed-by-human": true
@@ -7744,7 +7692,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
       "reviewed-by-human": true
@@ -7753,7 +7701,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10114430088335751528
+          10526892636346125391
         ]
       ], 
       "reviewed-by-human": true
@@ -7762,7 +7710,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
       "reviewed-by-human": true
@@ -7771,7 +7719,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14066121939439543543
+          8513291652694658229
         ]
       ], 
       "reviewed-by-human": true
@@ -7780,7 +7728,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4948510891620894130
+          1660605744162077853
         ]
       ], 
       "reviewed-by-human": true
@@ -7789,7 +7737,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4476112184102812424
+          12859230602339856753
         ]
       ], 
       "reviewed-by-human": true
@@ -7798,43 +7746,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8526522685583771158
+          4676690602747042598
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          870325780867202543
+          8602355022075378915
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8526522685583771158
+          4676690602747042598
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14066121939439543543
+          8513291652694658229
         ]
       ], 
       "reviewed-by-human": true
@@ -7843,7 +7782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4360699237363138563
+          16566569798343072386
         ]
       ], 
       "reviewed-by-human": true
@@ -7852,7 +7791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14168968675551513983
+          17382926884387968116
         ]
       ], 
       "reviewed-by-human": true
@@ -7861,43 +7800,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15017086665895517748
+          6242233697981173654
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14066121939439543543
+          8513291652694658229
         ]
       ], 
       "reviewed-by-human": true
@@ -7906,7 +7836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7098608858408966733
+          15979713947291339443
         ]
       ], 
       "reviewed-by-human": true
@@ -7915,7 +7845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14725179627975328921
+          17669316236050085372
         ]
       ], 
       "reviewed-by-human": true
@@ -7924,43 +7854,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2503842551053061740
+          13407493730926639865
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3070667813149638343
+          6139002882789673698
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2503842551053061740
+          13407493730926639865
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14066121939439543543
+          8513291652694658229
         ]
       ], 
       "reviewed-by-human": true
@@ -7969,7 +7890,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          5064010763405785676
         ]
       ], 
       "ignore-failure": false, 
@@ -7989,38 +7910,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16820737304423131667
+          7316445525652115151
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12708502432145746966
+          5041644101832918027
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3476566219080103593
+          12878478093979926276
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -8035,10 +7956,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16139251987605503044
+          7480091562491824315
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -8078,13 +8000,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259993451537882346
+          11045935574568457313
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -8099,56 +8018,49 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11046937029873515189
+          17705942446971461800
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5239442822275439160
+          7356321131319852548
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14897792001610563483
+          13689022292455941920
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14252168183976211244
+          2198482392389683711
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          380749030198936352
+          7474822897845279878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -8203,13 +8115,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15775370780535441106
+          12964191813177138234
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8284,10 +8193,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16565881092123145800
+          8357703037535831273
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -8327,13 +8237,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5172771228988998519
+          10046979169747724368
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8563,6 +8470,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5098763081949571745
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -8889,7 +8850,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7419227591265311221
+          2180768823026833562
         ]
       ], 
       "reviewed-by-human": true
@@ -8898,7 +8859,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9941389284961210315
+          12199897808056356124
         ]
       ], 
       "reviewed-by-human": true
@@ -8944,7 +8905,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4712618105826416872
+          370415619944804844
         ]
       ], 
       "reviewed-by-human": true
@@ -8953,7 +8914,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6814786601958107546
+          8271636985969391381
         ]
       ], 
       "reviewed-by-human": true
@@ -9008,7 +8969,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11309219541124250528
+          4847810197899900218
         ]
       ], 
       "reviewed-by-human": true
@@ -9017,7 +8978,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8042312968331390097
+          3506803607239781083
         ]
       ], 
       "reviewed-by-human": true
@@ -9072,7 +9033,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17324002053051694427
+          2090785975892516151
         ]
       ], 
       "reviewed-by-human": true
@@ -9081,7 +9042,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10616193688896439855
+          2924211775552310056
         ]
       ], 
       "reviewed-by-human": true
@@ -9136,7 +9097,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10302533496874247276
+          16889052153239653128
         ]
       ], 
       "reviewed-by-human": true
@@ -9145,7 +9106,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12569931102745160299
+          6790235028873950669
         ]
       ], 
       "reviewed-by-human": true
@@ -9200,7 +9161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          842153490277803410
+          10744005928079115852
         ]
       ], 
       "reviewed-by-human": true
@@ -9209,7 +9170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577999994704956939
+          6776804094106320859
         ]
       ], 
       "reviewed-by-human": true
@@ -9264,7 +9225,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17152997950184504727
+          12357182101174773078
         ]
       ], 
       "reviewed-by-human": true
@@ -9273,7 +9234,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11428391327691184765
+          3126361758776039631
         ]
       ], 
       "reviewed-by-human": true
@@ -9328,7 +9289,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4139187976413040197
+          8367950844952921343
         ]
       ], 
       "reviewed-by-human": true
@@ -9337,7 +9298,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14073034095251842923
+          15525258025464017393
         ]
       ], 
       "reviewed-by-human": true
@@ -9392,7 +9353,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17106863847823042087
+          7934322701486748120
         ]
       ], 
       "reviewed-by-human": true
@@ -9401,7 +9362,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12215969181637652211
+          4704939924625922499
         ]
       ], 
       "reviewed-by-human": true
@@ -9520,7 +9481,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3068653512092670589
+          18291684100428307360
         ]
       ], 
       "reviewed-by-human": true
@@ -9529,7 +9490,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15170271034615721666
+          1747669205907815761
         ]
       ], 
       "reviewed-by-human": true
@@ -9584,7 +9545,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12953124581979057663
+          2939909229015482136
         ]
       ], 
       "reviewed-by-human": true
@@ -9593,7 +9554,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6060145829986674671
+          16784170841543500838
         ]
       ], 
       "reviewed-by-human": true
@@ -9602,43 +9563,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15878740706156254185
+          12115609809541331955
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3235842036818065829
+          7741874124483388245
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15878740706156254185
+          12115609809541331955
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16873604997776801559
+          6264318715281092048
         ]
       ], 
       "ignore-failure": true, 
@@ -9648,7 +9600,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9385831891271254731
+          2530225677707713973
         ]
       ], 
       "reviewed-by-human": true
@@ -9657,7 +9609,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15495639177924148762
+          11737771933273684317
         ]
       ], 
       "reviewed-by-human": true
@@ -9666,43 +9618,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9560342061098090172
+          7646299335763235021
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9291463380778281308
+          6192530157172807562
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9560342061098090172
+          7646299335763235021
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2095931816548076565
+          12975575323222896175
         ]
       ], 
       "ignore-failure": true, 
@@ -9712,7 +9655,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9965963170738840176
+          2153098313336566581
         ]
       ], 
       "reviewed-by-human": true
@@ -9721,7 +9664,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14289759274523525273
+          9483593199149625360
         ]
       ], 
       "reviewed-by-human": true
@@ -9730,48 +9673,93 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9924687013532237178
+          17595942081154547308
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12386000803794075244
+          13543482950582224848
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9924687013532237178
+          17595942081154547308
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13745943106421332910
+          13727482678081612567
         ]
       ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14901126990301924005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1042098274477732047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -9800,145 +9788,109 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15918710972937868190
+          13192441167517447297
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3837345849472965080
+          8941245033428719604
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10929108306360722303
+          14135920799259443071
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7771644967924691504
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7771644967924691504
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          6255857682785307937
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          282728204444207247
+          2642821964627964924
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13196130985402258979
+          8742629042949635540
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          9377051299359577559
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          9377051299359577559
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          6013434920470292904
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          751768362423893408
+          1305833112985343548
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -9983,7 +9935,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9376519829232163481
+          12737689080510541699
         ]
       ], 
       "reviewed-by-human": true
@@ -9997,66 +9949,113 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16389315216289626974
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          661283946918891348
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11191748144946304564
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16745962585467963862
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10670628188057478241
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2331397672223269101
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5346798618605808309
+          5983654477358278958
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18349477956646401922
+          18319238038903413042
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3521193882387509458
+          6867991060051121346
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9451184519094825250
+          4846529169177988106
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3521193882387509458
+          644210377077145666
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11514219422733957634
+          14185380098316064946
         ]
       ], 
       "reviewed-by-human": true
@@ -10107,13 +10106,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5923123814296227252
+          13267969425935880104
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10928,6 +10924,438 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6172128683301553757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4827031153572338195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12594100502165346083
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14294242618865072998
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4586436592064500005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5433207270266805876
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1252866419102335842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10974866288863391771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6064119078588419632
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4210787692809798256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          777666299623824232
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4305684336407110182
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17153088450454553964
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8298209255771457934
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12499850813365812951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3023222294858564203
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12330676944414335565
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9799960307893174466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17570093836970109349
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10991112512849041738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10974866288863391771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13234881846499298757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6987984883296298526
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12196229923735361002
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14509163529223272481
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12820931542168562870
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7596124566362246306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907720242023997068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13491726316742145147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17754273294250967740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1777618438222741913
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6540527200127538614
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          676714076804984027
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -10959,10 +11387,7 @@
           2515733614721864626
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -11515,7 +11940,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          10887305247691796896
         ]
       ], 
       "ignore-failure": false, 
@@ -11545,7 +11970,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
       "reviewed-by-human": true
@@ -11575,19 +12000,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3160793858475866402
+          15859984430307806446
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9161659132855227715
+          5659028446842583448
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -11596,11 +12023,8 @@
           92511276571386922
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
@@ -11609,22 +12033,16 @@
           3124201814718695673
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          92511276571386922
+          6404505258636913207
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -11712,38 +12130,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -11855,7 +12273,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15581784646583613988
+          17484477122955938183
         ]
       ], 
       "reviewed-by-human": true
@@ -11938,42 +12356,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4960440391450740763
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14416712990565014740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13176912798569666712
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2940066578573590628
+          6679146172037188198
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13749909274890084570
+          3705961818794504133
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16785789595319639672
+          12759686595185656420
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7734161192636331207
+          10603373527933089029
         ]
       ], 
       "reviewed-by-human": true
@@ -11982,7 +12453,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18175958529226931597
+          3953751248814186934
         ]
       ], 
       "reviewed-by-human": true
@@ -11991,37 +12462,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12058414599914735969
+          4016697118621605241
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13676918670476155168
+          2296889387509264077
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8866329483052081099
+          7404189070007343463
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
@@ -12036,25 +12498,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17135666482003439061
+          10265552030778016870
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12131741421773209441
+          3814516952917649585
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_pdf-poppler.png": {
       "allowed-digests": [
@@ -12109,13 +12565,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9451113239611252518
+          11358423048091168224
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12172,13 +12625,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15524566862764359637
+          3436830071126863243
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -12363,13 +12813,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13904453152957483485
+          10202019670274831016
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -12448,7 +12895,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
       ], 
       "reviewed-by-human": true
@@ -12457,7 +12904,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
       ], 
       "reviewed-by-human": true
@@ -12466,7 +12913,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3262803126131585722
+          13391508749678438749
         ]
       ], 
       "reviewed-by-human": true
@@ -12475,7 +12922,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          661616009017115779
+          3054597254770601118
         ]
       ], 
       "reviewed-by-human": true
@@ -12484,7 +12931,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9659350677391822056
+          1102950561799296746
         ]
       ], 
       "reviewed-by-human": true
@@ -12501,7 +12948,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15966221253644391598
+          681401366445135140
         ]
       ], 
       "reviewed-by-human": true
@@ -12510,7 +12957,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6803625819311760695
+          4219988338924914895
         ]
       ], 
       "reviewed-by-human": true
@@ -12519,37 +12966,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6946593127096270008
+          14069830140047435524
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9004397529590800817
+          11403629407822261921
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15904079654772183797
+          2185400216731303545
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -12612,13 +13050,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6664533234575204169
+          13939654497258336594
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12681,13 +13116,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9054013070996242459
+          16773017670820649508
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -12814,13 +13246,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12731556315894686366
+          8030725662518062791
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12862,37 +13291,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -13040,10 +13469,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10291224769557172430
+          17704265017767572066
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -13083,13 +13513,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16282234596408134348
+          5709812329699199972
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13107,10 +13534,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11214635697117158219
+          15315508224860148267
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -13150,13 +13578,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12969761536311811498
+          13102837636444825585
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13187,37 +13612,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6584772443733517325
+          8036070052794735085
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          253712541328863653
+          2990680921703942550
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1534386106053156477
+          3328324156548225782
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13265,7 +13687,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14337201570310240929
+          8638631336814102897
         ]
       ], 
       "ignore-failure": false, 
@@ -13275,7 +13697,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11202438527860078687
+          17927372218178797511
         ]
       ], 
       "ignore-failure": false, 
@@ -13285,44 +13707,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1818655397466532351
+          15887214589697950727
         ]
       ], 
       "reviewed-by-human": true
@@ -13409,39 +13822,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_pdf-poppler.png": {
       "allowed-digests": [
@@ -13480,39 +13884,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_pdf-poppler.png": {
       "allowed-digests": [
@@ -13554,39 +13949,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_pdf-poppler.png": {
       "allowed-digests": [
@@ -13631,14 +14017,14 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18053729995632638218
+          5194202950428804182
         ]
       ], 
       "bugs": [
         2354
       ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "mixed_xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
@@ -13680,37 +14066,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -13781,6 +14167,546 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8719876420876618449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5980286511424355844
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7730731144263164598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7813398969375683276
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17643575047596097946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15845733488367618269
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13338081280989731045
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2672526945072259380
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683870789515781899
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2429486074917537971
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -14076,59 +15002,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12155325540830354759
+          5996648237050377037
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3339405153867447160
+          3965248782497463807
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9089568072831657991
+          13332864465231151117
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9968769882425487491
+          1175479943072326396
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9089568072831657991
+          13332864465231151117
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10658811892185308847
+          4274397413122380873
         ]
       ], 
       "reviewed-by-human": true
@@ -14161,37 +15080,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -14260,6 +15179,114 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1970032844879616905
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1842269258804065125
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -14775,7 +15802,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -14784,7 +15811,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -14793,17 +15820,71 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7769408336713819900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2934804817352937872
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -14812,7 +15893,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -14866,13 +15947,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12090999085559058466
+          5557910745049633908
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -14883,6 +15961,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1843194965390816202
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -14937,6 +16069,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -14996,7 +16182,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17761441655459925802
+          6200040322909789654
         ]
       ], 
       "ignore-failure": false, 
@@ -15006,7 +16192,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          584852425794817692
+          2652863181334626267
         ]
       ], 
       "ignore-failure": false, 
@@ -15016,7 +16202,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16334305116962929134
+          11900472786319635625
         ]
       ], 
       "ignore-failure": false, 
@@ -15026,20 +16212,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12915657818379420968
+          859519043843310852
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4725339200098775862
+          1554255494938845354
         ]
       ], 
       "reviewed-by-human": true
@@ -15123,10 +16306,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16424717553440518736
+          6254546707005318320
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -15166,13 +16350,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17195403769079449765
+          18127761162138529103
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15190,10 +16371,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3155083044843636999
+          12732664272876775262
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -15233,13 +16415,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14790270578728495649
+          1201544144882965410
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15338,38 +16517,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -15405,10 +16584,7 @@
           11339980900210544915
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -15993,13 +17169,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9712986429528697461
+          17402623096381811933
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -16053,7 +17226,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11484656948681556804
+          603889413078018210
         ]
       ], 
       "reviewed-by-human": true
@@ -16113,13 +17286,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3637152984721254457
+          16395924466838212878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -16152,7 +17322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9952165733700277657
+          5688757353305988584
         ]
       ], 
       "reviewed-by-human": true
@@ -16161,7 +17331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13785642655596247386
+          15611152105682208694
         ]
       ], 
       "reviewed-by-human": true
@@ -16188,7 +17358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14845859051414195721
+          7427081417172568205
         ]
       ], 
       "reviewed-by-human": true
@@ -16197,7 +17367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4487879976516068927
+          1703789635957684086
         ]
       ], 
       "reviewed-by-human": true
@@ -16206,7 +17376,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14845859051414195721
+          7488972794602546651
         ]
       ], 
       "reviewed-by-human": true
@@ -16224,7 +17394,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9952165733700277657
+          10724820182460485707
         ]
       ], 
       "reviewed-by-human": true
@@ -16450,7 +17620,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          414768291566756351
+          11598216018668638377
         ]
       ], 
       "reviewed-by-human": true
@@ -16459,7 +17629,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17773646925429384088
+          5014938153257796246
         ]
       ], 
       "reviewed-by-human": true
@@ -16468,25 +17638,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12366755253801250205
+          13990644605545735043
         ]
       ], 
-      "bugs": [
-        2619
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "shadertext2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13374125976246952627
+          14883414452656690954
         ]
       ], 
-      "bugs": [
-        2619
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -16494,7 +17658,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          223777537998895726
+          10235286573595132383
         ]
       ], 
       "reviewed-by-human": true
@@ -16503,7 +17667,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          363651743109664983
+          17433207623652171757
         ]
       ], 
       "ignore-failure": false, 
@@ -16541,7 +17705,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3569770788112621273
+          2353063788706484506
         ]
       ], 
       "reviewed-by-human": true
@@ -16559,7 +17723,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1800000102265782105
+          16716882881077358409
         ]
       ], 
       "ignore-failure": false, 
@@ -16569,7 +17733,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12281091565078967987
+          14711512755683802427
         ]
       ], 
       "ignore-failure": false, 
@@ -16579,7 +17743,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10042306223458878314
+          6407445498372558270
         ]
       ], 
       "ignore-failure": false, 
@@ -16589,7 +17753,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11119856323552654038
+          4052931258289345567
         ]
       ], 
       "reviewed-by-human": true
@@ -16598,7 +17762,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          46744022306204318
+          14715792432845667200
         ]
       ], 
       "reviewed-by-human": true
@@ -17001,13 +18165,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4429473827193042884
+          14068765431433693142
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -17064,13 +18225,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5605338931353764550
+          316799210449981670
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -17127,13 +18285,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7217507911128786327
+          17371031338824646424
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_pdf-poppler.png": {
       "allowed-digests": [
@@ -17332,67 +18487,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1430031890715528002
+          7659929100708975654
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          254318060234203033
+          13619399217835536541
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          113135342230966660
+          12119099569932150047
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          113135342230966660
+          3794750305076354153
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11960639219773597759
+          4531129654172985200
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16134046954799129070
+          7657054601899880488
         ]
       ], 
       "reviewed-by-human": true
@@ -17507,13 +18647,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1781244994412984169
+          4126252108879846874
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -17830,7 +18967,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7615951997407285496
+          18299855773787932617
         ]
       ], 
       "reviewed-by-human": true
@@ -17839,7 +18976,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17665436176340313326
+          3820153663375892124
         ]
       ], 
       "reviewed-by-human": true
@@ -17848,7 +18985,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2400348954160929648
+          16140885015853298544
         ]
       ], 
       "reviewed-by-human": true
@@ -17857,7 +18994,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4763201130776673922
+          13455217919464509867
         ]
       ], 
       "reviewed-by-human": true
@@ -17866,7 +19003,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5216165706151276286
+          10744565359108073823
         ]
       ], 
       "reviewed-by-human": true
@@ -18071,6 +19208,60 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17235038783782663409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16486637480158260521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17762278278392565594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17762278278392565594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1358760508249242163
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16903255024657466835
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -18142,28 +19333,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9407358693309761110
+          5829921135942844635
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -18190,11 +19381,8 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -18254,11 +19442,8 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -18300,55 +19485,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          126344850819174936
+          9375228469990118595
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15464669010903857039
+          14711755288216381805
         ]
       ], 
       "reviewed-by-human": true
@@ -18393,7 +19575,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11484656948681556804
+          603889413078018210
         ]
       ], 
       "reviewed-by-human": true
@@ -18453,13 +19635,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3637152984721254457
+          16395924466838212878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -18494,7 +19673,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14621436615237149247
+          3862599236828490251
         ]
       ], 
       "ignore-failure": false, 
@@ -18504,7 +19683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1853325399924584174
+          5442275593233872177
         ]
       ], 
       "reviewed-by-human": true
@@ -18531,7 +19710,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2051444200921081988
+          6329602332652473958
         ]
       ], 
       "reviewed-by-human": true
@@ -18540,7 +19719,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5664984420286171612
+          6138347655700728056
         ]
       ], 
       "reviewed-by-human": true
@@ -18549,7 +19728,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2051444200921081988
+          6901612585770457729
         ]
       ], 
       "reviewed-by-human": true
@@ -18567,7 +19746,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14621436615237149247
+          150588090347378989
         ]
       ], 
       "reviewed-by-human": true
@@ -18687,7 +19866,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10951464805453100925
+          7976185962753704838
         ]
       ], 
       "reviewed-by-human": true
@@ -18705,73 +19884,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4576021857620851191
+          2799147878061647403
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          4393488982813169804
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17391291832856229078
+          17296028215314109032
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_565.png": {
       "allowed-digests": [
@@ -18861,13 +20022,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11562249440399459338
+          12927740593822621795
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -18897,13 +20055,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4077398801659852267
+          12294528495888004394
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -18917,6 +20072,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10116032837978635800
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18154361016912445141
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3971059681811542268
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5442459823623424975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8952249585661143762
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11693715989410224137
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16280904268338645670
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10760709080022845641
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15543477125466102631
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7549142694352295409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8418057357389671210
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557729198294542220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7299943176517707258
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10092984979233544677
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14215331500430849765
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15022281553729610746
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12511123456870701231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5248478921458325627
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10277740082513188305
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9554470894306324526
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6371478998258738983
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16144209558281772024
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7231497730013821579
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8711004908212839257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -19041,7 +20412,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          197051971219635936
+          18327648018858793968
         ]
       ], 
       "ignore-failure": false, 
@@ -19051,7 +20422,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8329676900146900637
+          13883101138826307738
         ]
       ], 
       "ignore-failure": false, 
@@ -19061,7 +20432,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7557567270051125372
+          14377082299960675760
         ]
       ], 
       "ignore-failure": false, 
@@ -19071,7 +20442,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          138444525739207993
+          6530140610436991685
         ]
       ], 
       "reviewed-by-human": true
@@ -19080,7 +20451,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6271772538233648846
+          11287472543272099935
         ]
       ], 
       "reviewed-by-human": true
@@ -19089,7 +20460,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4922114328247158994
+          9163624118736443612
         ]
       ], 
       "reviewed-by-human": true
@@ -19141,7 +20512,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8981196494502834755
+          9432867194928348522
         ]
       ], 
       "reviewed-by-human": true
@@ -19213,62 +20584,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120931637037293931
+          9731357412382235356
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6709336082279713745
+          8697273950167613341
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11089296821936872594
+          2963356239888582885
         ]
       ], 
       "reviewed-by-human": true
@@ -19295,38 +20659,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18290343612708221939
+          99304012495268944
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9543759850676654383
+          17976537055001151954
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18290343612708221939
+          7093901190222689258
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19381,13 +20742,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16770666263463766901
+          14175629323496966287
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -19420,38 +20778,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5334235195393676951
+          16935319345008694478
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2467361690438720912
+          11975782723899906465
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5334235195393676951
+          6129301005097965173
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -19461,6 +20816,33 @@
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/expected-results.json b/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/expected-results.json
index aecd446..9a995a0 100644
--- a/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/expected-results.json
+++ b/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/expected-results.json
@@ -153,38 +153,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -348,38 +348,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          8509476067209440798
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          6953582728625873818
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          4850895322567541620
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -390,6 +387,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3358888352773124551
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -483,69 +534,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12332389189099053788
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -712,37 +700,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -993,13 +972,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15308835346079711937
+          13663949626340090597
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -1014,7 +990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9707111840054705070
+          5753977543166902872
         ]
       ], 
       "ignore-failure": false, 
@@ -1024,7 +1000,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966472219258108320
+          3622726894191108275
         ]
       ], 
       "ignore-failure": false, 
@@ -1034,7 +1010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5388227895717978780
+          5008177951711187426
         ]
       ], 
       "ignore-failure": false, 
@@ -1044,7 +1020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7908101291719253601
+          2625617788607302304
         ]
       ], 
       "reviewed-by-human": true
@@ -1053,7 +1029,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5388227895717978780
+          15847638636930861743
         ]
       ], 
       "reviewed-by-human": true
@@ -1062,7 +1038,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4425981769758897451
+          8652857569622477512
         ]
       ], 
       "reviewed-by-human": true
@@ -1479,28 +1455,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -1605,13 +1590,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurquickreject_nvprmsaa4.png": {
       "allowed-digests": [
@@ -3823,6 +3805,60 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9127987412867969701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -4151,37 +4187,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -4192,6 +4219,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2767554231532657737
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4311,13 +4392,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17103835371669353467
+          10122332848450541880
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -4549,13 +4627,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8342401373468633748
+          10088452398931315952
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -5361,13 +5436,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2874808003280900420
+          10568305498027471247
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -5515,25 +5587,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14602262721761630857
+          7017815369204328634
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          14149123815610089425
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
       "reviewed-by-human": true
@@ -5542,37 +5614,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1995539702399150009
+          10363407019316773455
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -5956,85 +6019,77 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9308347137055900457
+          11137376764949716657
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          70554801271357149
+          9237294305986351770
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2893820023009333324
+          5842617443052169408
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11986351729917860717
+          6664819925988745829
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17407721376245627230
+          7782456344628243848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13259111868844875039
+          17699771136066957749
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6886995277392420867
+          12446109424042490351
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17234618925843989936
+          857815900353647485
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6049,25 +6104,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17289619728742065294
+          12167696310276417671
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          298289002043954726
+          15112343104874953659
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_pdf-poppler.png": {
       "allowed-digests": [
@@ -6082,85 +6131,77 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17046138572928461942
+          1060100128535571349
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16848821614766946815
+          2130878875932816169
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11656665183177874362
+          2530953864070751441
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14046532233792735234
+          10215436687867452743
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6040117814573953462
+          60525349492118674
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3691285029135011922
+          7507188018788541198
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          636883424267411162
+          8045133037980648445
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11150731716715141897
+          13732634818710636058
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6175,25 +6216,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3382891004691951866
+          14508705528594025331
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11236143476052676434
+          7004399922767132272
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -6316,7 +6351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4110722122594872859
+          3692847587555755996
         ]
       ], 
       "reviewed-by-human": true
@@ -6325,7 +6360,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15192724137559208204
+          12867323471223068426
         ]
       ], 
       "reviewed-by-human": true
@@ -6334,7 +6369,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12390000919902989614
+          8566631317914568343
         ]
       ], 
       "reviewed-by-human": true
@@ -6343,31 +6378,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12210515662385677484
+          6633944641607131513
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17274497380173363267
+          16204544386885042034
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13214515577780181252
+          2035440368234831638
         ]
       ], 
       "reviewed-by-human": true
@@ -6532,10 +6561,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14629387967092406744
+          489208137730623687
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -6575,13 +6605,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7786557523508893251
+          12079760358174422971
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6599,10 +6626,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8947422315903317870
+          3220333313183474890
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -6642,13 +6670,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17290567770120363032
+          12110591489796654880
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6859,7 +6884,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11983291604958613824
+          4119744344752250956
         ]
       ], 
       "reviewed-by-human": true
@@ -6959,10 +6984,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18018965749997300368
+          9095643239105155650
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -7002,13 +7028,14 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13517902628428185359
+          215278920234240161
         ]
       ], 
       "bugs": [
-        2325
+        2826
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -7110,62 +7137,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16850764937772706343
+          3377544910324212919
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14105405523972827206
+          7432066987408472244
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5600826535722550519
+          64614149029383431
         ]
       ], 
       "reviewed-by-human": true
@@ -7174,73 +7194,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565-pipe cross-process.png": {
       "allowed-digests": [
@@ -7264,7 +7266,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          296179642722990434
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -7291,7 +7293,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6998570850154406591
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -7300,7 +7302,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7309,7 +7311,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16451780885896960300
+          14204243393620033211
         ]
       ], 
       "reviewed-by-human": true
@@ -7318,7 +7320,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7327,7 +7329,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7336,7 +7338,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
       "reviewed-by-human": true
@@ -7345,7 +7347,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
       "reviewed-by-human": true
@@ -7354,43 +7356,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443130797061158720
+          3590945223549597113
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7399,7 +7392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
       "reviewed-by-human": true
@@ -7408,7 +7401,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
       "reviewed-by-human": true
@@ -7417,43 +7410,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8034132364379362582
+          17212795401772012692
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7462,7 +7446,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
       "reviewed-by-human": true
@@ -7471,7 +7455,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
       "reviewed-by-human": true
@@ -7480,43 +7464,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15854240744220847964
+          12495564829829617636
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7543,7 +7518,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10174175970901629058
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -7588,7 +7563,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6090416266698448089
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -7597,7 +7572,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7606,7 +7581,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61543217406202998
+          11968003402313032299
         ]
       ], 
       "reviewed-by-human": true
@@ -7615,7 +7590,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7624,7 +7599,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532637637939557491
+          13364626080781238305
         ]
       ], 
       "reviewed-by-human": true
@@ -7633,7 +7608,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
       "reviewed-by-human": true
@@ -7642,7 +7617,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
       "reviewed-by-human": true
@@ -7651,43 +7626,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2171610356153094701
+          8951768093676734731
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532637637939557491
+          13364626080781238305
         ]
       ], 
       "reviewed-by-human": true
@@ -7696,7 +7662,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
       "reviewed-by-human": true
@@ -7705,7 +7671,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
       "reviewed-by-human": true
@@ -7714,43 +7680,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6692547324448596108
+          16032430115842971269
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532637637939557491
+          13364626080781238305
         ]
       ], 
       "reviewed-by-human": true
@@ -7759,7 +7716,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
       "reviewed-by-human": true
@@ -7768,7 +7725,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
       "reviewed-by-human": true
@@ -7777,43 +7734,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12362918265113141584
+          352963511646887173
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532637637939557491
+          13364626080781238305
         ]
       ], 
       "reviewed-by-human": true
@@ -7822,7 +7770,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          316392167046886906
+          11438413222729306097
         ]
       ], 
       "reviewed-by-human": true
@@ -7831,7 +7779,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5454778002458116517
+          140707004996434734
         ]
       ], 
       "reviewed-by-human": true
@@ -7840,7 +7788,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
       "reviewed-by-human": true
@@ -7849,7 +7797,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10114430088335751528
+          10526892636346125391
         ]
       ], 
       "reviewed-by-human": true
@@ -7858,7 +7806,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
       "reviewed-by-human": true
@@ -7867,7 +7815,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14066121939439543543
+          8513291652694658229
         ]
       ], 
       "reviewed-by-human": true
@@ -7876,7 +7824,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4948510891620894130
+          1660605744162077853
         ]
       ], 
       "reviewed-by-human": true
@@ -7885,7 +7833,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4476112184102812424
+          12859230602339856753
         ]
       ], 
       "reviewed-by-human": true
@@ -7894,43 +7842,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8526522685583771158
+          4676690602747042598
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          870325780867202543
+          8602355022075378915
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8526522685583771158
+          4676690602747042598
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14066121939439543543
+          8513291652694658229
         ]
       ], 
       "reviewed-by-human": true
@@ -7939,7 +7878,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4360699237363138563
+          16566569798343072386
         ]
       ], 
       "reviewed-by-human": true
@@ -7948,7 +7887,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14168968675551513983
+          17382926884387968116
         ]
       ], 
       "reviewed-by-human": true
@@ -7957,43 +7896,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15017086665895517748
+          6242233697981173654
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14066121939439543543
+          8513291652694658229
         ]
       ], 
       "reviewed-by-human": true
@@ -8002,7 +7932,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7098608858408966733
+          15979713947291339443
         ]
       ], 
       "reviewed-by-human": true
@@ -8011,7 +7941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14725179627975328921
+          17669316236050085372
         ]
       ], 
       "reviewed-by-human": true
@@ -8020,43 +7950,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2503842551053061740
+          13407493730926639865
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3070667813149638343
+          6139002882789673698
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2503842551053061740
+          13407493730926639865
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14066121939439543543
+          8513291652694658229
         ]
       ], 
       "reviewed-by-human": true
@@ -8065,7 +7986,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          5064010763405785676
         ]
       ], 
       "ignore-failure": false, 
@@ -8085,38 +8006,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16820737304423131667
+          7316445525652115151
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12708502432145746966
+          5041644101832918027
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3476566219080103593
+          12878478093979926276
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -8131,10 +8052,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16139251987605503044
+          7480091562491824315
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -8174,13 +8096,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259993451537882346
+          11045935574568457313
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -8195,25 +8114,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11046937029873515189
+          17705942446971461800
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5239442822275439160
+          7356321131319852548
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14897792001610563483
+          13689022292455941920
         ]
       ], 
       "ignore-failure": false, 
@@ -8223,25 +8144,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14252168183976211244
+          2198482392389683711
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          380749030198936352
+          7474822897845279878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -8296,13 +8211,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15775370780535441106
+          12964191813177138234
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8377,10 +8289,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16565881092123145800
+          8357703037535831273
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -8420,13 +8333,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5172771228988998519
+          10046979169747724368
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8656,6 +8566,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5098763081949571745
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -8982,7 +8946,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7419227591265311221
+          2180768823026833562
         ]
       ], 
       "reviewed-by-human": true
@@ -8991,7 +8955,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9941389284961210315
+          12199897808056356124
         ]
       ], 
       "reviewed-by-human": true
@@ -9037,7 +9001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4712618105826416872
+          370415619944804844
         ]
       ], 
       "reviewed-by-human": true
@@ -9046,7 +9010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6814786601958107546
+          8271636985969391381
         ]
       ], 
       "reviewed-by-human": true
@@ -9101,7 +9065,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11309219541124250528
+          4847810197899900218
         ]
       ], 
       "reviewed-by-human": true
@@ -9110,7 +9074,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8042312968331390097
+          3506803607239781083
         ]
       ], 
       "reviewed-by-human": true
@@ -9165,7 +9129,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17324002053051694427
+          2090785975892516151
         ]
       ], 
       "reviewed-by-human": true
@@ -9174,7 +9138,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10616193688896439855
+          2924211775552310056
         ]
       ], 
       "reviewed-by-human": true
@@ -9229,7 +9193,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10302533496874247276
+          16889052153239653128
         ]
       ], 
       "reviewed-by-human": true
@@ -9238,7 +9202,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12569931102745160299
+          6790235028873950669
         ]
       ], 
       "reviewed-by-human": true
@@ -9293,7 +9257,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          842153490277803410
+          10744005928079115852
         ]
       ], 
       "reviewed-by-human": true
@@ -9302,7 +9266,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577999994704956939
+          6776804094106320859
         ]
       ], 
       "reviewed-by-human": true
@@ -9357,7 +9321,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17152997950184504727
+          12357182101174773078
         ]
       ], 
       "reviewed-by-human": true
@@ -9366,7 +9330,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11428391327691184765
+          3126361758776039631
         ]
       ], 
       "reviewed-by-human": true
@@ -9421,7 +9385,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4139187976413040197
+          8367950844952921343
         ]
       ], 
       "reviewed-by-human": true
@@ -9430,7 +9394,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14073034095251842923
+          15525258025464017393
         ]
       ], 
       "reviewed-by-human": true
@@ -9485,7 +9449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17106863847823042087
+          7934322701486748120
         ]
       ], 
       "reviewed-by-human": true
@@ -9494,7 +9458,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12215969181637652211
+          4704939924625922499
         ]
       ], 
       "reviewed-by-human": true
@@ -9567,7 +9531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12617614780925646679
+          8457226704515835046
         ]
       ], 
       "reviewed-by-human": true
@@ -9594,7 +9558,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9743406049766573166
+          13673721686942765185
         ]
       ], 
       "reviewed-by-human": true
@@ -9649,7 +9613,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3068653512092670589
+          18291684100428307360
         ]
       ], 
       "reviewed-by-human": true
@@ -9658,7 +9622,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15170271034615721666
+          1747669205907815761
         ]
       ], 
       "reviewed-by-human": true
@@ -9713,7 +9677,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12953124581979057663
+          2939909229015482136
         ]
       ], 
       "reviewed-by-human": true
@@ -9722,7 +9686,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6060145829986674671
+          16784170841543500838
         ]
       ], 
       "reviewed-by-human": true
@@ -9731,43 +9695,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15878740706156254185
+          12115609809541331955
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3235842036818065829
+          7741874124483388245
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15878740706156254185
+          12115609809541331955
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16873604997776801559
+          6264318715281092048
         ]
       ], 
       "ignore-failure": true, 
@@ -9777,7 +9732,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9385831891271254731
+          2530225677707713973
         ]
       ], 
       "reviewed-by-human": true
@@ -9786,7 +9741,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15495639177924148762
+          11737771933273684317
         ]
       ], 
       "reviewed-by-human": true
@@ -9795,43 +9750,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9560342061098090172
+          7646299335763235021
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9291463380778281308
+          6192530157172807562
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9560342061098090172
+          7646299335763235021
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2095931816548076565
+          12975575323222896175
         ]
       ], 
       "ignore-failure": true, 
@@ -9841,7 +9787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9965963170738840176
+          2153098313336566581
         ]
       ], 
       "reviewed-by-human": true
@@ -9850,7 +9796,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14289759274523525273
+          9483593199149625360
         ]
       ], 
       "reviewed-by-human": true
@@ -9859,48 +9805,93 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9924687013532237178
+          17595942081154547308
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12386000803794075244
+          13543482950582224848
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9924687013532237178
+          17595942081154547308
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13745943106421332910
+          13727482678081612567
         ]
       ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14901126990301924005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1042098274477732047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -9929,145 +9920,109 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15918710972937868190
+          13192441167517447297
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3837345849472965080
+          8941245033428719604
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10929108306360722303
+          14135920799259443071
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7771644967924691504
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7771644967924691504
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          6255857682785307937
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          282728204444207247
+          2642821964627964924
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13196130985402258979
+          8742629042949635540
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          9377051299359577559
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          9377051299359577559
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          6013434920470292904
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          751768362423893408
+          1305833112985343548
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -10112,7 +10067,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9376519829232163481
+          12737689080510541699
         ]
       ], 
       "reviewed-by-human": true
@@ -10126,66 +10081,113 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16389315216289626974
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          661283946918891348
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11191748144946304564
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16745962585467963862
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10670628188057478241
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2331397672223269101
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5346798618605808309
+          5983654477358278958
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18349477956646401922
+          18319238038903413042
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3521193882387509458
+          6867991060051121346
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9451184519094825250
+          4846529169177988106
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3521193882387509458
+          644210377077145666
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11514219422733957634
+          14185380098316064946
         ]
       ], 
       "reviewed-by-human": true
@@ -10236,13 +10238,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5923123814296227252
+          13267969425935880104
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -11057,6 +11056,438 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6172128683301553757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4827031153572338195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12594100502165346083
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14294242618865072998
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4586436592064500005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5433207270266805876
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1252866419102335842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10974866288863391771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6064119078588419632
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4210787692809798256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          777666299623824232
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4305684336407110182
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17153088450454553964
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8298209255771457934
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12499850813365812951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3023222294858564203
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12330676944414335565
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9799960307893174466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17570093836970109349
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10991112512849041738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10974866288863391771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13234881846499298757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6987984883296298526
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12196229923735361002
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14509163529223272481
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12820931542168562870
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7596124566362246306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907720242023997068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13491726316742145147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17754273294250967740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1777618438222741913
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6540527200127538614
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          676714076804984027
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -11088,10 +11519,7 @@
           2515733614721864626
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -11635,7 +12063,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          10887305247691796896
         ]
       ], 
       "ignore-failure": false, 
@@ -11665,7 +12093,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
       "reviewed-by-human": true
@@ -11695,19 +12123,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3160793858475866402
+          15859984430307806446
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9161659132855227715
+          5659028446842583448
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -11716,11 +12146,8 @@
           92511276571386922
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
@@ -11729,22 +12156,16 @@
           3124201814718695673
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          92511276571386922
+          6404505258636913207
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -11832,38 +12253,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -11975,7 +12396,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15581784646583613988
+          17484477122955938183
         ]
       ], 
       "reviewed-by-human": true
@@ -12061,29 +12482,85 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4960440391450740763
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14416712990565014740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13176912798569666712
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2940066578573590628
+          6679146172037188198
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13749909274890084570
+          3705961818794504133
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16785789595319639672
+          12759686595185656420
         ]
       ], 
       "ignore-failure": false, 
@@ -12093,7 +12570,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7734161192636331207
+          10603373527933089029
         ]
       ], 
       "reviewed-by-human": true
@@ -12102,7 +12579,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18175958529226931597
+          3953751248814186934
         ]
       ], 
       "reviewed-by-human": true
@@ -12111,37 +12588,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12058414599914735969
+          4016697118621605241
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13676918670476155168
+          2296889387509264077
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8866329483052081099
+          7404189070007343463
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
@@ -12156,19 +12624,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17135666482003439061
+          10265552030778016870
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12131741421773209441
+          3814516952917649585
         ]
       ], 
       "reviewed-by-human": true
@@ -12226,13 +12691,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9451113239611252518
+          11358423048091168224
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12289,13 +12751,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15524566862764359637
+          3436830071126863243
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -12480,13 +12939,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13904453152957483485
+          10202019670274831016
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -12583,7 +13039,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
       ], 
       "reviewed-by-human": true
@@ -12610,7 +13066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
       ], 
       "reviewed-by-human": true
@@ -12619,7 +13075,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3262803126131585722
+          13391508749678438749
         ]
       ], 
       "reviewed-by-human": true
@@ -12628,7 +13084,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          661616009017115779
+          3054597254770601118
         ]
       ], 
       "reviewed-by-human": true
@@ -12637,7 +13093,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9659350677391822056
+          1102950561799296746
         ]
       ], 
       "reviewed-by-human": true
@@ -12654,7 +13110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15966221253644391598
+          681401366445135140
         ]
       ], 
       "reviewed-by-human": true
@@ -12663,7 +13119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6803625819311760695
+          4219988338924914895
         ]
       ], 
       "reviewed-by-human": true
@@ -12672,37 +13128,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6946593127096270008
+          14069830140047435524
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9004397529590800817
+          11403629407822261921
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15904079654772183797
+          2185400216731303545
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -12765,13 +13212,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6664533234575204169
+          13939654497258336594
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12834,13 +13278,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9054013070996242459
+          16773017670820649508
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -12967,13 +13408,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12731556315894686366
+          8030725662518062791
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13015,37 +13453,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -13193,10 +13631,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10291224769557172430
+          17704265017767572066
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -13236,13 +13675,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16282234596408134348
+          5709812329699199972
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13260,10 +13696,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11214635697117158219
+          15315508224860148267
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -13303,13 +13740,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12969761536311811498
+          13102837636444825585
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13340,37 +13774,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6584772443733517325
+          8036070052794735085
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          253712541328863653
+          2990680921703942550
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1534386106053156477
+          3328324156548225782
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13418,7 +13849,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14337201570310240929
+          8638631336814102897
         ]
       ], 
       "ignore-failure": false, 
@@ -13428,7 +13859,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11202438527860078687
+          17927372218178797511
         ]
       ], 
       "ignore-failure": false, 
@@ -13438,44 +13869,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1818655397466532351
+          15887214589697950727
         ]
       ], 
       "reviewed-by-human": true
@@ -13562,39 +13984,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_pdf-poppler.png": {
       "allowed-digests": [
@@ -13633,39 +14046,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_pdf-poppler.png": {
       "allowed-digests": [
@@ -13707,39 +14111,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_pdf-poppler.png": {
       "allowed-digests": [
@@ -13784,14 +14179,14 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7068817626419515805
+          5194202950428804182
         ]
       ], 
       "bugs": [
         2354
       ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "mixed_xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
@@ -13833,37 +14228,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -13934,6 +14329,546 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8719876420876618449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5980286511424355844
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7730731144263164598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7813398969375683276
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17643575047596097946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15845733488367618269
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13338081280989731045
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2672526945072259380
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683870789515781899
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2429486074917537971
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -14229,59 +15164,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12155325540830354759
+          5996648237050377037
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3339405153867447160
+          3965248782497463807
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9089568072831657991
+          13332864465231151117
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9968769882425487491
+          1175479943072326396
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9089568072831657991
+          13332864465231151117
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10658811892185308847
+          4274397413122380873
         ]
       ], 
       "reviewed-by-human": true
@@ -14314,37 +15242,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
-        1578
+        2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -14413,6 +15341,114 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1970032844879616905
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1842269258804065125
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -14925,7 +15961,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -14934,7 +15970,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -14943,17 +15979,71 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7769408336713819900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2934804817352937872
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -14962,7 +16052,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15016,13 +16106,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12090999085559058466
+          5557910745049633908
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15033,6 +16120,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1843194965390816202
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -15087,6 +16228,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -15146,7 +16341,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17761441655459925802
+          6200040322909789654
         ]
       ], 
       "ignore-failure": false, 
@@ -15156,7 +16351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          584852425794817692
+          2652863181334626267
         ]
       ], 
       "ignore-failure": false, 
@@ -15166,7 +16361,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16334305116962929134
+          11900472786319635625
         ]
       ], 
       "ignore-failure": false, 
@@ -15176,20 +16371,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12915657818379420968
+          859519043843310852
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4725339200098775862
+          1554255494938845354
         ]
       ], 
       "reviewed-by-human": true
@@ -15270,10 +16462,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16424717553440518736
+          6254546707005318320
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -15313,13 +16506,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17195403769079449765
+          18127761162138529103
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15337,10 +16527,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3155083044843636999
+          12732664272876775262
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -15380,13 +16571,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14790270578728495649
+          1201544144882965410
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15482,38 +16670,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -15549,10 +16737,7 @@
           11339980900210544915
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -16226,13 +17411,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9712986429528697461
+          17402623096381811933
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -16286,7 +17468,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11484656948681556804
+          603889413078018210
         ]
       ], 
       "reviewed-by-human": true
@@ -16346,13 +17528,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3637152984721254457
+          16395924466838212878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -16385,7 +17564,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9952165733700277657
+          5688757353305988584
         ]
       ], 
       "reviewed-by-human": true
@@ -16394,7 +17573,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13785642655596247386
+          15611152105682208694
         ]
       ], 
       "reviewed-by-human": true
@@ -16421,7 +17600,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14845859051414195721
+          7427081417172568205
         ]
       ], 
       "reviewed-by-human": true
@@ -16430,7 +17609,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4487879976516068927
+          1703789635957684086
         ]
       ], 
       "reviewed-by-human": true
@@ -16439,7 +17618,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14845859051414195721
+          7488972794602546651
         ]
       ], 
       "reviewed-by-human": true
@@ -16457,7 +17636,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9952165733700277657
+          10724820182460485707
         ]
       ], 
       "reviewed-by-human": true
@@ -16683,7 +17862,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          414768291566756351
+          11598216018668638377
         ]
       ], 
       "ignore-failure": false, 
@@ -16693,7 +17872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17773646925429384088
+          5014938153257796246
         ]
       ], 
       "reviewed-by-human": true
@@ -16702,12 +17881,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12366755253801250205
+          15706038792148077135
         ]
       ], 
-      "bugs": [
-        2619
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -16715,20 +17891,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17518799550679467287
+          14883414452656690954
         ]
       ], 
-      "bugs": [
-        2619
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "shadertext2_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          223777537998895726
+          10235286573595132383
         ]
       ], 
       "reviewed-by-human": true
@@ -16737,7 +17910,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          363651743109664983
+          17433207623652171757
         ]
       ], 
       "ignore-failure": false, 
@@ -16775,7 +17948,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3569770788112621273
+          2353063788706484506
         ]
       ], 
       "reviewed-by-human": true
@@ -16793,7 +17966,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1800000102265782105
+          16716882881077358409
         ]
       ], 
       "ignore-failure": false, 
@@ -16803,7 +17976,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12281091565078967987
+          14711512755683802427
         ]
       ], 
       "ignore-failure": false, 
@@ -16813,7 +17986,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10042306223458878314
+          6407445498372558270
         ]
       ], 
       "ignore-failure": false, 
@@ -16823,7 +17996,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11119856323552654038
+          4052931258289345567
         ]
       ], 
       "reviewed-by-human": true
@@ -16832,7 +18005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          46744022306204318
+          14715792432845667200
         ]
       ], 
       "reviewed-by-human": true
@@ -17226,13 +18399,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4429473827193042884
+          14068765431433693142
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -17289,13 +18459,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5605338931353764550
+          316799210449981670
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -17352,13 +18519,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7217507911128786327
+          17371031338824646424
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_pdf-poppler.png": {
       "allowed-digests": [
@@ -17557,67 +18721,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1430031890715528002
+          7659929100708975654
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          254318060234203033
+          13619399217835536541
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          113135342230966660
+          12119099569932150047
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          113135342230966660
+          3794750305076354153
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11960639219773597759
+          4531129654172985200
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16134046954799129070
+          7657054601899880488
         ]
       ], 
       "reviewed-by-human": true
@@ -17735,13 +18884,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1781244994412984169
+          4126252108879846874
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -18055,7 +19201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7615951997407285496
+          18299855773787932617
         ]
       ], 
       "reviewed-by-human": true
@@ -18064,7 +19210,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17665436176340313326
+          3820153663375892124
         ]
       ], 
       "reviewed-by-human": true
@@ -18073,7 +19219,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2400348954160929648
+          16140885015853298544
         ]
       ], 
       "reviewed-by-human": true
@@ -18082,7 +19228,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4763201130776673922
+          13455217919464509867
         ]
       ], 
       "reviewed-by-human": true
@@ -18091,7 +19237,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5216165706151276286
+          10744565359108073823
         ]
       ], 
       "reviewed-by-human": true
@@ -18296,6 +19442,60 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17235038783782663409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16486637480158260521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17762278278392565594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17762278278392565594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1358760508249242163
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16903255024657466835
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -18367,28 +19567,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9407358693309761110
+          5829921135942844635
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -18415,11 +19615,8 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -18479,11 +19676,8 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -18525,55 +19719,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          126344850819174936
+          9375228469990118595
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15464669010903857039
+          14711755288216381805
         ]
       ], 
       "reviewed-by-human": true
@@ -18618,7 +19809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11484656948681556804
+          603889413078018210
         ]
       ], 
       "reviewed-by-human": true
@@ -18678,13 +19869,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3637152984721254457
+          16395924466838212878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -18719,7 +19907,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14621436615237149247
+          3862599236828490251
         ]
       ], 
       "ignore-failure": false, 
@@ -18729,7 +19917,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1853325399924584174
+          5442275593233872177
         ]
       ], 
       "reviewed-by-human": true
@@ -18756,7 +19944,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2051444200921081988
+          6329602332652473958
         ]
       ], 
       "reviewed-by-human": true
@@ -18765,7 +19953,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5664984420286171612
+          6138347655700728056
         ]
       ], 
       "reviewed-by-human": true
@@ -18774,7 +19962,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2051444200921081988
+          6901612585770457729
         ]
       ], 
       "reviewed-by-human": true
@@ -18792,7 +19980,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14621436615237149247
+          150588090347378989
         ]
       ], 
       "reviewed-by-human": true
@@ -18912,7 +20100,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10951464805453100925
+          7976185962753704838
         ]
       ], 
       "reviewed-by-human": true
@@ -18930,73 +20118,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4576021857620851191
+          2799147878061647403
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          4393488982813169804
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17391291832856229078
+          17296028215314109032
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_565.png": {
       "allowed-digests": [
@@ -19086,13 +20256,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11562249440399459338
+          12927740593822621795
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -19122,13 +20289,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4077398801659852267
+          12294528495888004394
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -19142,6 +20306,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10116032837978635800
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18154361016912445141
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3971059681811542268
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5442459823623424975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8952249585661143762
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11693715989410224137
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16280904268338645670
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10760709080022845641
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15543477125466102631
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7549142694352295409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8418057357389671210
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557729198294542220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7299943176517707258
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10092984979233544677
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14215331500430849765
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15022281553729610746
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12511123456870701231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5248478921458325627
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10277740082513188305
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9554470894306324526
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6371478998258738983
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16144209558281772024
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7231497730013821579
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8711004908212839257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -19266,7 +20646,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          197051971219635936
+          18327648018858793968
         ]
       ], 
       "ignore-failure": false, 
@@ -19276,7 +20656,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8329676900146900637
+          13883101138826307738
         ]
       ], 
       "ignore-failure": false, 
@@ -19286,7 +20666,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7557567270051125372
+          14377082299960675760
         ]
       ], 
       "ignore-failure": false, 
@@ -19296,7 +20676,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          138444525739207993
+          6530140610436991685
         ]
       ], 
       "reviewed-by-human": true
@@ -19305,7 +20685,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6271772538233648846
+          11287472543272099935
         ]
       ], 
       "reviewed-by-human": true
@@ -19314,7 +20694,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4922114328247158994
+          9163624118736443612
         ]
       ], 
       "reviewed-by-human": true
@@ -19366,7 +20746,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8981196494502834755
+          9432867194928348522
         ]
       ], 
       "reviewed-by-human": true
@@ -19438,62 +20818,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120931637037293931
+          9731357412382235356
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6709336082279713745
+          8697273950167613341
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11089296821936872594
+          2963356239888582885
         ]
       ], 
       "reviewed-by-human": true
@@ -19520,38 +20893,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18290343612708221939
+          99304012495268944
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9543759850676654383
+          17976537055001151954
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18290343612708221939
+          7093901190222689258
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19606,13 +20976,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16770666263463766901
+          14175629323496966287
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -19645,38 +21012,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5334235195393676951
+          16935319345008694478
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2467361690438720912
+          11975782723899906465
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5334235195393676951
+          6129301005097965173
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -19686,6 +21050,33 @@
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86_64-Debug/expected-results.json b/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86_64-Debug/expected-results.json
index fd283d2..32fdd14 100644
--- a/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86_64-Debug/expected-results.json
+++ b/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86_64-Debug/expected-results.json
@@ -153,38 +153,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -355,38 +355,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          8509476067209440798
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          6953582728625873818
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          4850895322567541620
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -397,6 +394,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3358888352773124551
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -517,75 +568,6 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12332389189099053788
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -752,37 +734,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -1045,13 +1018,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15308835346079711937
+          13663949626340090597
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -1066,7 +1036,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9707111840054705070
+          5753977543166902872
         ]
       ], 
       "ignore-failure": false, 
@@ -1076,7 +1046,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966472219258108320
+          3622726894191108275
         ]
       ], 
       "ignore-failure": false, 
@@ -1086,7 +1056,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5388227895717978780
+          5008177951711187426
         ]
       ], 
       "ignore-failure": false, 
@@ -1096,7 +1066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7908101291719253601
+          2625617788607302304
         ]
       ], 
       "reviewed-by-human": true
@@ -1105,7 +1075,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5388227895717978780
+          15847638636930861743
         ]
       ], 
       "reviewed-by-human": true
@@ -1114,7 +1084,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4425981769758897451
+          8652857569622477512
         ]
       ], 
       "reviewed-by-human": true
@@ -1542,20 +1512,23 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
       "bugs": [
-        2325
+        2762
       ], 
       "reviewed-by-human": false
     }, 
@@ -1563,10 +1536,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -1671,13 +1647,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurquickreject_nvprmsaa4.png": {
       "allowed-digests": [
@@ -3889,6 +3862,60 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9127987412867969701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -4217,37 +4244,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -4258,6 +4276,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2767554231532657737
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4377,13 +4449,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17103835371669353467
+          10122332848450541880
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -4615,13 +4684,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8342401373468633748
+          10088452398931315952
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -5430,13 +5496,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2874808003280900420
+          10568305498027471247
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -5584,7 +5647,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14602262721761630857
+          7017815369204328634
         ]
       ], 
       "reviewed-by-human": true
@@ -5593,7 +5656,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          14149123815610089425
         ]
       ], 
       "reviewed-by-human": true
@@ -5602,7 +5665,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
       "reviewed-by-human": true
@@ -5611,37 +5674,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1995539702399150009
+          10363407019316773455
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -6025,85 +6079,77 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9308347137055900457
+          11137376764949716657
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          70554801271357149
+          9237294305986351770
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2893820023009333324
+          5842617443052169408
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11986351729917860717
+          6664819925988745829
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17407721376245627230
+          7782456344628243848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13259111868844875039
+          17699771136066957749
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6886995277392420867
+          12446109424042490351
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17234618925843989936
+          857815900353647485
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6118,25 +6164,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17289619728742065294
+          12167696310276417671
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          298289002043954726
+          15112343104874953659
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_pdf-poppler.png": {
       "allowed-digests": [
@@ -6151,85 +6191,77 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17046138572928461942
+          1060100128535571349
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16848821614766946815
+          2130878875932816169
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11656665183177874362
+          2530953864070751441
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14046532233792735234
+          10215436687867452743
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6040117814573953462
+          60525349492118674
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3691285029135011922
+          7507188018788541198
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          636883424267411162
+          8045133037980648445
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11150731716715141897
+          13732634818710636058
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6244,25 +6276,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3382891004691951866
+          14508705528594025331
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11236143476052676434
+          7004399922767132272
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -6385,67 +6411,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4110722122594872859
+          3692847587555755996
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15192724137559208204
+          12867323471223068426
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12390000919902989614
+          8566631317914568343
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12210515662385677484
+          6633944641607131513
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17274497380173363267
+          16204544386885042034
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5676963015806633645
+          1731971574151750911
         ]
       ], 
       "reviewed-by-human": true
@@ -6457,10 +6468,7 @@
           15882849726405746866
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_msaa16.png": {
       "allowed-digests": [
@@ -6622,10 +6630,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14629387967092406744
+          489208137730623687
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -6665,13 +6674,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7786557523508893251
+          12079760358174422971
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6689,10 +6695,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8947422315903317870
+          3220333313183474890
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -6732,13 +6739,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17290567770120363032
+          12110591489796654880
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6961,7 +6965,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11983291604958613824
+          4119744344752250956
         ]
       ], 
       "reviewed-by-human": true
@@ -7064,10 +7068,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18018965749997300368
+          9095643239105155650
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -7107,13 +7112,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2539621048677205985
+          215278920234240161
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -7215,62 +7217,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16850764937772706343
+          3377544910324212919
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14105405523972827206
+          7432066987408472244
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5600826535722550519
+          64614149029383431
         ]
       ], 
       "reviewed-by-human": true
@@ -7279,79 +7274,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -7360,7 +7337,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -7369,7 +7346,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7378,7 +7355,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16451780885896960300
+          14204243393620033211
         ]
       ], 
       "reviewed-by-human": true
@@ -7387,7 +7364,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7396,7 +7373,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7405,67 +7382,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443130797061158720
+          3590945223549597113
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7474,67 +7436,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8034132364379362582
+          17212795401772012692
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7543,67 +7490,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15854240744220847964
+          12495564829829617636
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7612,7 +7544,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -7621,7 +7553,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -7630,7 +7562,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7639,7 +7571,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61543217406202998
+          11968003402313032299
         ]
       ], 
       "reviewed-by-human": true
@@ -7648,7 +7580,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7657,7 +7589,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7830336908520811081
+          7886311591518744367
         ]
       ], 
       "reviewed-by-human": true
@@ -7666,67 +7598,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2171610356153094701
+          8951768093676734731
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7830336908520811081
+          7886311591518744367
         ]
       ], 
       "reviewed-by-human": true
@@ -7735,67 +7652,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6692547324448596108
+          16032430115842971269
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7830336908520811081
+          7886311591518744367
         ]
       ], 
       "reviewed-by-human": true
@@ -7804,67 +7706,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12362918265113141584
+          352963511646887173
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7830336908520811081
+          7886311591518744367
         ]
       ], 
       "reviewed-by-human": true
@@ -7873,7 +7760,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          316392167046886906
+          11438413222729306097
         ]
       ], 
       "reviewed-by-human": true
@@ -7882,7 +7769,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3203476165028839490
+          140707004996434734
         ]
       ], 
       "reviewed-by-human": true
@@ -7891,7 +7778,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
       "reviewed-by-human": true
@@ -7900,7 +7787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10114430088335751528
+          10526892636346125391
         ]
       ], 
       "reviewed-by-human": true
@@ -7909,7 +7796,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
       "reviewed-by-human": true
@@ -7918,7 +7805,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14517950724001851018
+          3161206607262163039
         ]
       ], 
       "reviewed-by-human": true
@@ -7927,67 +7814,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4948510891620894130
+          1660605744162077853
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4476112184102812424
+          12859230602339856753
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8526522685583771158
+          4676690602747042598
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          870325780867202543
+          8602355022075378915
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8526522685583771158
+          4676690602747042598
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14517950724001851018
+          3161206607262163039
         ]
       ], 
       "reviewed-by-human": true
@@ -7996,67 +7868,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4360699237363138563
+          16566569798343072386
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14168968675551513983
+          17382926884387968116
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15017086665895517748
+          6242233697981173654
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14517950724001851018
+          3161206607262163039
         ]
       ], 
       "reviewed-by-human": true
@@ -8065,67 +7922,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7098608858408966733
+          15979713947291339443
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14725179627975328921
+          17669316236050085372
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2503842551053061740
+          13407493730926639865
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3070667813149638343
+          6139002882789673698
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2503842551053061740
+          13407493730926639865
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14517950724001851018
+          3161206607262163039
         ]
       ], 
       "reviewed-by-human": true
@@ -8134,10 +7976,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          5064010763405785676
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -8152,38 +7995,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4044067462010750201
+          6342427866691203627
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18416785834500530233
+          2337948389991614457
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6609647321648041579
+          16443289277689710577
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -8198,10 +8041,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16139251987605503044
+          7480091562491824315
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -8241,13 +8085,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259993451537882346
+          11045935574568457313
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -8262,56 +8103,49 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11046937029873515189
+          17705942446971461800
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5239442822275439160
+          7356321131319852548
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14897792001610563483
+          13689022292455941920
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14252168183976211244
+          2198482392389683711
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          380749030198936352
+          7474822897845279878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -8366,13 +8200,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15775370780535441106
+          12964191813177138234
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8447,10 +8278,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16565881092123145800
+          8357703037535831273
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -8490,13 +8322,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5172771228988998519
+          10046979169747724368
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8726,6 +8555,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5098763081949571745
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -9050,7 +8933,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176401027747712373
+          5309891953138315298
         ]
       ], 
       "reviewed-by-human": true
@@ -9059,7 +8942,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11272179801264636450
+          14526840074449574066
         ]
       ], 
       "reviewed-by-human": true
@@ -9105,7 +8988,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15198871804360226443
+          9215723161792449926
         ]
       ], 
       "reviewed-by-human": true
@@ -9114,7 +8997,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7856045684728929971
+          2392355743669508205
         ]
       ], 
       "reviewed-by-human": true
@@ -9169,7 +9052,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16978450773511607710
+          1922439110496083683
         ]
       ], 
       "reviewed-by-human": true
@@ -9178,7 +9061,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6278595518621591608
+          13421806279953941280
         ]
       ], 
       "reviewed-by-human": true
@@ -9233,7 +9116,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6269581803563312235
+          8653581790829574678
         ]
       ], 
       "reviewed-by-human": true
@@ -9242,7 +9125,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7534215132153111580
+          14304360467166489415
         ]
       ], 
       "reviewed-by-human": true
@@ -9297,7 +9180,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12343046498140718348
+          11315694301382876090
         ]
       ], 
       "reviewed-by-human": true
@@ -9306,7 +9189,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6345971390397937472
+          17952171829995911009
         ]
       ], 
       "reviewed-by-human": true
@@ -9361,7 +9244,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4168067701806693625
+          3827095505720286728
         ]
       ], 
       "reviewed-by-human": true
@@ -9370,7 +9253,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17172040454616353959
+          3962214001616470324
         ]
       ], 
       "reviewed-by-human": true
@@ -9425,7 +9308,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12020342225442211019
+          4499532536817155763
         ]
       ], 
       "reviewed-by-human": true
@@ -9434,7 +9317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15486455585945174582
+          2532277191814352883
         ]
       ], 
       "reviewed-by-human": true
@@ -9489,7 +9372,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1349764396121687334
+          9675188186932125398
         ]
       ], 
       "reviewed-by-human": true
@@ -9498,7 +9381,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13512793178880974830
+          252003960684820363
         ]
       ], 
       "reviewed-by-human": true
@@ -9553,7 +9436,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7087467719445182209
+          1555493983183157774
         ]
       ], 
       "reviewed-by-human": true
@@ -9562,7 +9445,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13702064810817834637
+          9578858996653266547
         ]
       ], 
       "reviewed-by-human": true
@@ -9681,7 +9564,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15599673700324610016
+          7328053965687721632
         ]
       ], 
       "reviewed-by-human": true
@@ -9690,7 +9573,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5268278487198498347
+          7059435553345332705
         ]
       ], 
       "reviewed-by-human": true
@@ -9745,7 +9628,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2798807683929613348
+          14172867549655561814
         ]
       ], 
       "reviewed-by-human": true
@@ -9754,7 +9637,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14825737167317700678
+          6198605176358084298
         ]
       ], 
       "reviewed-by-human": true
@@ -9763,43 +9646,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15878740706156254185
+          12115609809541331955
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3235842036818065829
+          7741874124483388245
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15878740706156254185
+          12115609809541331955
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14921341614033680796
+          8734915309544527654
         ]
       ], 
       "ignore-failure": true, 
@@ -9809,7 +9683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13532382804553257370
+          1479964679245541605
         ]
       ], 
       "reviewed-by-human": true
@@ -9818,7 +9692,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3049241456762138365
+          11399081827859230847
         ]
       ], 
       "reviewed-by-human": true
@@ -9827,43 +9701,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9560342061098090172
+          7646299335763235021
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9291463380778281308
+          6192530157172807562
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9560342061098090172
+          7646299335763235021
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4700853947534465845
+          15094457383317574422
         ]
       ], 
       "ignore-failure": true, 
@@ -9873,7 +9738,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18193737071240070809
+          411558866575208409
         ]
       ], 
       "reviewed-by-human": true
@@ -9882,7 +9747,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2637407914961122231
+          761919473704229560
         ]
       ], 
       "reviewed-by-human": true
@@ -9891,48 +9756,93 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9924687013532237178
+          17595942081154547308
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12386000803794075244
+          13543482950582224848
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9924687013532237178
+          17595942081154547308
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14075196769671590809
+          3768630344114099033
         ]
       ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14901126990301924005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1042098274477732047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -9961,145 +9871,109 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15918710972937868190
+          8722739816575573844
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3837345849472965080
+          8941245033428719604
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10929108306360722303
+          14135920799259443071
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7771644967924691504
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7771644967924691504
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7674289571277755921
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          282728204444207247
+          2642821964627964924
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13196130985402258979
+          8742629042949635540
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          9377051299359577559
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          9377051299359577559
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          6013434920470292904
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          751768362423893408
+          1305833112985343548
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -10144,7 +10018,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9376519829232163481
+          12584690214250652961
         ]
       ], 
       "reviewed-by-human": true
@@ -10158,66 +10032,113 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16389315216289626974
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          661283946918891348
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11191748144946304564
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16745962585467963862
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10670628188057478241
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2331397672223269101
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5346798618605808309
+          5983654477358278958
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18349477956646401922
+          18319238038903413042
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3521193882387509458
+          6867991060051121346
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9451184519094825250
+          4846529169177988106
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3521193882387509458
+          644210377077145666
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11514219422733957634
+          14185380098316064946
         ]
       ], 
       "reviewed-by-human": true
@@ -10271,13 +10192,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5923123814296227252
+          13267969425935880104
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -11104,6 +11022,438 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6172128683301553757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4827031153572338195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12594100502165346083
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14294242618865072998
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4586436592064500005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12269852657063590148
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1252866419102335842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10974866288863391771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6064119078588419632
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4210787692809798256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          777666299623824232
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4305684336407110182
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16206316588171820057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8298209255771457934
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12499850813365812951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3023222294858564203
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12330676944414335565
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9799960307893174466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17570093836970109349
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10991112512849041738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10974866288863391771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13234881846499298757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6987984883296298526
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12196229923735361002
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14509163529223272481
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12820931542168562870
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7596124566362246306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907720242023997068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13491726316742145147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17754273294250967740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1777618438222741913
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6540527200127538614
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          676714076804984027
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -11135,10 +11485,7 @@
           2515733614721864626
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -11267,7 +11614,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa16.png": {
       "allowed-digests": [
@@ -11321,7 +11668,7 @@
           16605120526645549774
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa16.png": {
       "allowed-digests": [
@@ -11375,7 +11722,7 @@
           169027135498041421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa16.png": {
       "allowed-digests": [
@@ -11697,7 +12044,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          10887305247691796896
         ]
       ], 
       "ignore-failure": false, 
@@ -11727,7 +12074,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
       "reviewed-by-human": true
@@ -11757,19 +12104,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3160793858475866402
+          15859984430307806446
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9161659132855227715
+          5659028446842583448
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -11778,11 +12127,8 @@
           92511276571386922
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
@@ -11791,22 +12137,16 @@
           3124201814718695673
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          92511276571386922
+          6404505258636913207
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -11897,38 +12237,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -12040,7 +12380,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15581784646583613988
+          17484477122955938183
         ]
       ], 
       "reviewed-by-human": true
@@ -12126,42 +12466,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4960440391450740763
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14416712990565014740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13176912798569666712
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2940066578573590628
+          6679146172037188198
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13749909274890084570
+          3705961818794504133
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16785789595319639672
+          12759686595185656420
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7734161192636331207
+          10603373527933089029
         ]
       ], 
       "reviewed-by-human": true
@@ -12170,7 +12563,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18175958529226931597
+          3953751248814186934
         ]
       ], 
       "reviewed-by-human": true
@@ -12179,37 +12572,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12058414599914735969
+          4016697118621605241
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13676918670476155168
+          2296889387509264077
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8866329483052081099
+          7404189070007343463
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
@@ -12224,25 +12608,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17135666482003439061
+          10265552030778016870
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12131741421773209441
+          3814516952917649585
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_pdf-poppler.png": {
       "allowed-digests": [
@@ -12297,13 +12675,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9451113239611252518
+          11358423048091168224
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12360,13 +12735,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15524566862764359637
+          3436830071126863243
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -12550,13 +12922,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13904453152957483485
+          10202019670274831016
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -12635,53 +13004,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3262803126131585722
+          13391508749678438749
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          661616009017115779
+          3054597254770601118
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9659350677391822056
+          1102950561799296746
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12695,61 +13057,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15966221253644391598
+          681401366445135140
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6803625819311760695
+          4219988338924914895
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6946593127096270008
+          14069830140047435524
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9004397529590800817
+          11403629407822261921
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15904079654772183797
+          2185400216731303545
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -12812,13 +13159,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6664533234575204169
+          13939654497258336594
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12881,13 +13225,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9054013070996242459
+          16773017670820649508
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -13014,13 +13355,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12731556315894686366
+          8030725662518062791
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13062,37 +13400,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -13240,10 +13578,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10291224769557172430
+          17704265017767572066
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -13283,13 +13622,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16282234596408134348
+          5709812329699199972
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13307,10 +13643,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11214635697117158219
+          15315508224860148267
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -13350,13 +13687,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12969761536311811498
+          13102837636444825585
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13387,37 +13721,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6584772443733517325
+          8036070052794735085
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          253712541328863653
+          2990680921703942550
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1534386106053156477
+          3328324156548225782
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13465,62 +13796,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14337201570310240929
+          8638631336814102897
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11202438527860078687
+          17927372218178797511
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1818655397466532351
+          15887214589697950727
         ]
       ], 
       "reviewed-by-human": true
@@ -13607,39 +13931,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_pdf-poppler.png": {
       "allowed-digests": [
@@ -13678,39 +13993,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_pdf-poppler.png": {
       "allowed-digests": [
@@ -13752,39 +14058,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_pdf-poppler.png": {
       "allowed-digests": [
@@ -13832,14 +14129,14 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7068817626419515805
+          5194202950428804182
         ]
       ], 
       "bugs": [
         2354
       ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "mixed_xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
@@ -13881,37 +14178,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -13982,6 +14279,546 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8719876420876618449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5980286511424355844
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7730731144263164598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7813398969375683276
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17643575047596097946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15845733488367618269
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13338081280989731045
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2672526945072259380
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683870789515781899
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2429486074917537971
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -14283,59 +15120,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12155325540830354759
+          5996648237050377037
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3339405153867447160
+          3965248782497463807
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9089568072831657991
+          13332864465231151117
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9968769882425487491
+          1175479943072326396
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9089568072831657991
+          13332864465231151117
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10658811892185308847
+          4274397413122380873
         ]
       ], 
       "reviewed-by-human": true
@@ -14368,37 +15198,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -14467,6 +15297,114 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1970032844879616905
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1842269258804065125
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -14987,7 +15925,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -14996,7 +15934,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -15005,17 +15943,71 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7769408336713819900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2934804817352937872
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15024,7 +16016,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15078,13 +16070,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12090999085559058466
+          5557910745049633908
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15095,6 +16084,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1843194965390816202
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -15149,6 +16192,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -15208,7 +16305,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17761441655459925802
+          6200040322909789654
         ]
       ], 
       "ignore-failure": false, 
@@ -15218,7 +16315,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          584852425794817692
+          2652863181334626267
         ]
       ], 
       "ignore-failure": false, 
@@ -15228,7 +16325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16334305116962929134
+          11900472786319635625
         ]
       ], 
       "ignore-failure": false, 
@@ -15238,20 +16335,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12915657818379420968
+          859519043843310852
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4725339200098775862
+          1554255494938845354
         ]
       ], 
       "reviewed-by-human": true
@@ -15335,10 +16429,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16424717553440518736
+          6254546707005318320
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -15378,13 +16473,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17195403769079449765
+          18127761162138529103
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15402,10 +16494,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3155083044843636999
+          12732664272876775262
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -15445,13 +16538,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14790270578728495649
+          1201544144882965410
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15553,38 +16643,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -15620,10 +16710,7 @@
           11339980900210544915
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -16214,13 +17301,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9712986429528697461
+          17402623096381811933
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -16274,7 +17358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11484656948681556804
+          603889413078018210
         ]
       ], 
       "reviewed-by-human": true
@@ -16340,13 +17424,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3637152984721254457
+          16395924466838212878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -16379,7 +17460,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9952165733700277657
+          5688757353305988584
         ]
       ], 
       "reviewed-by-human": true
@@ -16388,7 +17469,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13785642655596247386
+          15611152105682208694
         ]
       ], 
       "reviewed-by-human": true
@@ -16415,7 +17496,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14845859051414195721
+          7427081417172568205
         ]
       ], 
       "reviewed-by-human": true
@@ -16424,7 +17505,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4487879976516068927
+          1703789635957684086
         ]
       ], 
       "reviewed-by-human": true
@@ -16433,7 +17514,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14845859051414195721
+          7488972794602546651
         ]
       ], 
       "reviewed-by-human": true
@@ -16451,7 +17532,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9952165733700277657
+          10724820182460485707
         ]
       ], 
       "reviewed-by-human": true
@@ -16677,7 +17758,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          214651258640525297
+          17067517941224065243
         ]
       ], 
       "ignore-failure": false, 
@@ -16687,7 +17768,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790110109815580358
+          786458466612254044
         ]
       ], 
       "reviewed-by-human": true
@@ -16696,12 +17777,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9290689085471276179
+          8805637738762869076
         ]
       ], 
-      "bugs": [
-        2619
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -16709,20 +17787,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4702027525692342270
+          8805974184185185146
         ]
       ], 
-      "bugs": [
-        2619
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "shadertext2_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          387202918560141756
+          8051735558131986459
         ]
       ], 
       "reviewed-by-human": true
@@ -16731,7 +17806,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          363651743109664983
+          17433207623652171757
         ]
       ], 
       "ignore-failure": false, 
@@ -16769,7 +17844,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3569770788112621273
+          2353063788706484506
         ]
       ], 
       "reviewed-by-human": true
@@ -16787,7 +17862,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16118814308223737737
+          1855944793144275915
         ]
       ], 
       "ignore-failure": false, 
@@ -16797,7 +17872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6564017357373772997
+          9541843996635442831
         ]
       ], 
       "ignore-failure": false, 
@@ -16807,7 +17882,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9492568723070634170
+          3706559258798264682
         ]
       ], 
       "ignore-failure": false, 
@@ -16817,7 +17892,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11619459974005556843
+          2620134778866063734
         ]
       ], 
       "reviewed-by-human": true
@@ -16826,7 +17901,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          46744022306204318
+          14715792432845667200
         ]
       ], 
       "reviewed-by-human": true
@@ -17235,13 +18310,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4429473827193042884
+          14068765431433693142
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -17298,13 +18370,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5605338931353764550
+          316799210449981670
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -17361,13 +18430,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7217507911128786327
+          17371031338824646424
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_pdf-poppler.png": {
       "allowed-digests": [
@@ -17569,67 +18635,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1430031890715528002
+          7659929100708975654
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          254318060234203033
+          13619399217835536541
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          113135342230966660
+          12119099569932150047
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          113135342230966660
+          3794750305076354153
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11960639219773597759
+          4531129654172985200
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16134046954799129070
+          7657054601899880488
         ]
       ], 
       "reviewed-by-human": true
@@ -17750,13 +18801,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1781244994412984169
+          4126252108879846874
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -18077,7 +19125,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7615951997407285496
+          18299855773787932617
         ]
       ], 
       "reviewed-by-human": true
@@ -18086,7 +19134,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17665436176340313326
+          3820153663375892124
         ]
       ], 
       "reviewed-by-human": true
@@ -18095,7 +19143,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2400348954160929648
+          16140885015853298544
         ]
       ], 
       "reviewed-by-human": true
@@ -18104,7 +19152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4763201130776673922
+          13455217919464509867
         ]
       ], 
       "reviewed-by-human": true
@@ -18113,7 +19161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5216165706151276286
+          10744565359108073823
         ]
       ], 
       "reviewed-by-human": true
@@ -18321,6 +19369,60 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17235038783782663409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16486637480158260521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17762278278392565594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17762278278392565594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1358760508249242163
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16903255024657466835
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -18392,28 +19494,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          461340767000445644
+          2252852476882257738
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7106538505228762194
+          9074211968785557862
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          461340767000445644
+          2252852476882257738
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -18440,11 +19542,8 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -18504,11 +19603,8 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -18550,55 +19646,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          126344850819174936
+          9375228469990118595
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15464669010903857039
+          14711755288216381805
         ]
       ], 
       "reviewed-by-human": true
@@ -18643,7 +19736,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11484656948681556804
+          603889413078018210
         ]
       ], 
       "reviewed-by-human": true
@@ -18709,13 +19802,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3637152984721254457
+          16395924466838212878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -18750,7 +19840,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14621436615237149247
+          3862599236828490251
         ]
       ], 
       "ignore-failure": false, 
@@ -18760,7 +19850,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1853325399924584174
+          5442275593233872177
         ]
       ], 
       "reviewed-by-human": true
@@ -18787,7 +19877,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2051444200921081988
+          6329602332652473958
         ]
       ], 
       "reviewed-by-human": true
@@ -18796,7 +19886,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5664984420286171612
+          6138347655700728056
         ]
       ], 
       "reviewed-by-human": true
@@ -18805,7 +19895,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2051444200921081988
+          6901612585770457729
         ]
       ], 
       "reviewed-by-human": true
@@ -18823,7 +19913,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14621436615237149247
+          150588090347378989
         ]
       ], 
       "reviewed-by-human": true
@@ -18943,7 +20033,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10951464805453100925
+          7976185962753704838
         ]
       ], 
       "reviewed-by-human": true
@@ -18961,73 +20051,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4576021857620851191
+          2799147878061647403
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          4393488982813169804
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17391291832856229078
+          17296028215314109032
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_565.png": {
       "allowed-digests": [
@@ -19117,13 +20189,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11562249440399459338
+          11562824691469652309
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -19153,13 +20222,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4077398801659852267
+          12294528495888004394
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -19173,6 +20239,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10116032837978635800
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18154361016912445141
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3971059681811542268
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5442459823623424975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8952249585661143762
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11693715989410224137
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16280904268338645670
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10760709080022845641
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15543477125466102631
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7549142694352295409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8418057357389671210
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557729198294542220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7299943176517707258
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10092984979233544677
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14215331500430849765
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15022281553729610746
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12511123456870701231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5248478921458325627
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10277740082513188305
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9554470894306324526
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6371478998258738983
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16144209558281772024
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7231497730013821579
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8711004908212839257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -19303,7 +20585,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          197051971219635936
+          18327648018858793968
         ]
       ], 
       "ignore-failure": false, 
@@ -19313,7 +20595,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8329676900146900637
+          13883101138826307738
         ]
       ], 
       "ignore-failure": false, 
@@ -19323,7 +20605,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7557567270051125372
+          14377082299960675760
         ]
       ], 
       "ignore-failure": false, 
@@ -19333,7 +20615,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          138444525739207993
+          6530140610436991685
         ]
       ], 
       "reviewed-by-human": true
@@ -19342,7 +20624,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6271772538233648846
+          11287472543272099935
         ]
       ], 
       "reviewed-by-human": true
@@ -19351,7 +20633,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4922114328247158994
+          9163624118736443612
         ]
       ], 
       "reviewed-by-human": true
@@ -19403,7 +20685,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8981196494502834755
+          9432867194928348522
         ]
       ], 
       "reviewed-by-human": true
@@ -19484,62 +20766,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120931637037293931
+          9731357412382235356
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6709336082279713745
+          8697273950167613341
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11089296821936872594
+          2963356239888582885
         ]
       ], 
       "reviewed-by-human": true
@@ -19566,38 +20841,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18290343612708221939
+          99304012495268944
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9543759850676654383
+          17976537055001151954
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18290343612708221939
+          7093901190222689258
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19652,13 +20924,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16770666263463766901
+          14175629323496966287
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -19691,38 +20960,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5334235195393676951
+          16935319345008694478
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2467361690438720912
+          11975782723899906465
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5334235195393676951
+          6129301005097965173
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -19732,6 +20998,33 @@
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86_64-Release/expected-results.json b/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86_64-Release/expected-results.json
index 88ce70e..92deff5 100644
--- a/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86_64-Release/expected-results.json
+++ b/expectations/gm/Test-Ubuntu12-ShuttleA-GTX660-x86_64-Release/expected-results.json
@@ -153,38 +153,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -355,38 +355,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          8509476067209440798
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          6953582728625873818
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10928282226528754856
+          4850895322567541620
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -397,6 +394,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3358888352773124551
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -517,75 +568,6 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12332389189099053788
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -752,37 +734,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -1045,13 +1018,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15308835346079711937
+          13663949626340090597
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -1066,7 +1036,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9707111840054705070
+          5753977543166902872
         ]
       ], 
       "ignore-failure": false, 
@@ -1076,7 +1046,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966472219258108320
+          3622726894191108275
         ]
       ], 
       "ignore-failure": false, 
@@ -1086,7 +1056,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5388227895717978780
+          5008177951711187426
         ]
       ], 
       "ignore-failure": false, 
@@ -1096,7 +1066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7908101291719253601
+          2625617788607302304
         ]
       ], 
       "reviewed-by-human": true
@@ -1105,7 +1075,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5388227895717978780
+          15847638636930861743
         ]
       ], 
       "reviewed-by-human": true
@@ -1114,7 +1084,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4425981769758897451
+          8652857569622477512
         ]
       ], 
       "reviewed-by-human": true
@@ -1542,20 +1512,23 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
       "bugs": [
-        2325
+        2762
       ], 
       "reviewed-by-human": false
     }, 
@@ -1563,10 +1536,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -1671,13 +1647,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurquickreject_nvprmsaa4.png": {
       "allowed-digests": [
@@ -3889,6 +3862,60 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9127987412867969701
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -4217,37 +4244,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -4258,6 +4276,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2767554231532657737
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4377,13 +4449,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17103835371669353467
+          10122332848450541880
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -4615,13 +4684,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8342401373468633748
+          10088452398931315952
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -5430,13 +5496,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2874808003280900420
+          10568305498027471247
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -5584,25 +5647,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14602262721761630857
+          7017815369204328634
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          14149123815610089425
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
       "reviewed-by-human": true
@@ -5611,37 +5674,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481217777013051559
+          358570991076446134
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1995539702399150009
+          10363407019316773455
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -6025,85 +6079,77 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9308347137055900457
+          11137376764949716657
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          70554801271357149
+          9237294305986351770
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2893820023009333324
+          5842617443052169408
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11986351729917860717
+          6664819925988745829
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17407721376245627230
+          7782456344628243848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13259111868844875039
+          17699771136066957749
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6886995277392420867
+          12446109424042490351
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17234618925843989936
+          857815900353647485
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6118,25 +6164,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17289619728742065294
+          12167696310276417671
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          298289002043954726
+          15112343104874953659
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_pdf-poppler.png": {
       "allowed-digests": [
@@ -6151,85 +6191,77 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17046138572928461942
+          1060100128535571349
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16848821614766946815
+          2130878875932816169
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11656665183177874362
+          2530953864070751441
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14046532233792735234
+          10215436687867452743
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6040117814573953462
+          60525349492118674
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3691285029135011922
+          7507188018788541198
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          636883424267411162
+          8045133037980648445
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11150731716715141897
+          13732634818710636058
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6244,25 +6276,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3382891004691951866
+          14508705528594025331
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11236143476052676434
+          7004399922767132272
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -6385,67 +6411,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4110722122594872859
+          3692847587555755996
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15192724137559208204
+          12867323471223068426
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12390000919902989614
+          8566631317914568343
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12210515662385677484
+          6633944641607131513
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17274497380173363267
+          16204544386885042034
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5676963015806633645
+          1731971574151750911
         ]
       ], 
       "reviewed-by-human": true
@@ -6457,10 +6468,7 @@
           15882849726405746866
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_effect_msaa16.png": {
       "allowed-digests": [
@@ -6622,10 +6630,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14629387967092406744
+          489208137730623687
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -6665,13 +6674,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7786557523508893251
+          12079760358174422971
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6689,10 +6695,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8947422315903317870
+          3220333313183474890
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -6732,13 +6739,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17290567770120363032
+          12110591489796654880
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6961,7 +6965,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11983291604958613824
+          4119744344752250956
         ]
       ], 
       "reviewed-by-human": true
@@ -7064,10 +7068,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18018965749997300368
+          9095643239105155650
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -7107,13 +7112,14 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2539621048677205985
+          13762763215526500776
         ]
       ], 
       "bugs": [
-        2325
+        2689
       ], 
-      "reviewed-by-human": false
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -7215,62 +7221,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16850764937772706343
+          3377544910324212919
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14105405523972827206
+          7432066987408472244
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6911083384990764467
+          14784402351750683622
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5600826535722550519
+          64614149029383431
         ]
       ], 
       "reviewed-by-human": true
@@ -7279,79 +7278,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          296179642722990434
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -7360,7 +7341,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6998570850154406591
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -7369,7 +7350,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7378,7 +7359,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16451780885896960300
+          14204243393620033211
         ]
       ], 
       "reviewed-by-human": true
@@ -7387,7 +7368,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7396,7 +7377,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7405,67 +7386,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443130797061158720
+          3590945223549597113
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7474,67 +7440,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8034132364379362582
+          17212795401772012692
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7543,67 +7494,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15854240744220847964
+          12495564829829617636
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11549616021626620319
+          4362761663405360055
         ]
       ], 
       "reviewed-by-human": true
@@ -7612,7 +7548,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9260853671338342442
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -7621,7 +7557,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4276981932731074819
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -7630,7 +7566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7639,7 +7575,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61543217406202998
+          11968003402313032299
         ]
       ], 
       "reviewed-by-human": true
@@ -7648,7 +7584,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7657,7 +7593,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7830336908520811081
+          7886311591518744367
         ]
       ], 
       "reviewed-by-human": true
@@ -7666,67 +7602,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2171610356153094701
+          8951768093676734731
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7830336908520811081
+          7886311591518744367
         ]
       ], 
       "reviewed-by-human": true
@@ -7735,67 +7656,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6692547324448596108
+          16032430115842971269
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7830336908520811081
+          7886311591518744367
         ]
       ], 
       "reviewed-by-human": true
@@ -7804,67 +7710,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12362918265113141584
+          352963511646887173
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7830336908520811081
+          7886311591518744367
         ]
       ], 
       "reviewed-by-human": true
@@ -7873,7 +7764,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          316392167046886906
+          11438413222729306097
         ]
       ], 
       "reviewed-by-human": true
@@ -7882,7 +7773,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5454778002458116517
+          140707004996434734
         ]
       ], 
       "reviewed-by-human": true
@@ -7891,7 +7782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
       "reviewed-by-human": true
@@ -7900,7 +7791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10114430088335751528
+          10526892636346125391
         ]
       ], 
       "reviewed-by-human": true
@@ -7909,7 +7800,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
       "reviewed-by-human": true
@@ -7918,7 +7809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14517950724001851018
+          3161206607262163039
         ]
       ], 
       "reviewed-by-human": true
@@ -7927,67 +7818,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4948510891620894130
+          1660605744162077853
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4476112184102812424
+          12859230602339856753
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8526522685583771158
+          4676690602747042598
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          870325780867202543
+          8602355022075378915
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8526522685583771158
+          4676690602747042598
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14517950724001851018
+          3161206607262163039
         ]
       ], 
       "reviewed-by-human": true
@@ -7996,67 +7872,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4360699237363138563
+          16566569798343072386
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14168968675551513983
+          17382926884387968116
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15017086665895517748
+          6242233697981173654
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13143715838422192555
+          18235431355943074314
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14517950724001851018
+          3161206607262163039
         ]
       ], 
       "reviewed-by-human": true
@@ -8065,67 +7926,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7098608858408966733
+          15979713947291339443
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14725179627975328921
+          17669316236050085372
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2503842551053061740
+          13407493730926639865
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3070667813149638343
+          6139002882789673698
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2503842551053061740
+          13407493730926639865
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14517950724001851018
+          3161206607262163039
         ]
       ], 
       "reviewed-by-human": true
@@ -8134,10 +7980,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          5064010763405785676
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -8152,38 +7999,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4044067462010750201
+          6342427866691203627
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18416785834500530233
+          2337948389991614457
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6609647321648041579
+          16443289277689710577
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -8198,10 +8045,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16139251987605503044
+          7480091562491824315
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
@@ -8241,13 +8089,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10259993451537882346
+          11045935574568457313
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -8262,56 +8107,49 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11046937029873515189
+          17705942446971461800
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5239442822275439160
+          7356321131319852548
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14897792001610563483
+          13689022292455941920
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14252168183976211244
+          2198482392389683711
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          380749030198936352
+          7474822897845279878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -8366,13 +8204,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15775370780535441106
+          12964191813177138234
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8447,10 +8282,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16565881092123145800
+          8357703037535831273
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -8490,13 +8326,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5172771228988998519
+          10046979169747724368
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8726,6 +8559,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5098763081949571745
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -9050,7 +8937,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176401027747712373
+          5309891953138315298
         ]
       ], 
       "reviewed-by-human": true
@@ -9059,7 +8946,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11272179801264636450
+          14526840074449574066
         ]
       ], 
       "reviewed-by-human": true
@@ -9105,7 +8992,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15198871804360226443
+          9215723161792449926
         ]
       ], 
       "reviewed-by-human": true
@@ -9114,7 +9001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7856045684728929971
+          2392355743669508205
         ]
       ], 
       "reviewed-by-human": true
@@ -9169,7 +9056,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16978450773511607710
+          1922439110496083683
         ]
       ], 
       "reviewed-by-human": true
@@ -9178,7 +9065,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6278595518621591608
+          13421806279953941280
         ]
       ], 
       "reviewed-by-human": true
@@ -9233,7 +9120,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6269581803563312235
+          8653581790829574678
         ]
       ], 
       "reviewed-by-human": true
@@ -9242,7 +9129,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7534215132153111580
+          14304360467166489415
         ]
       ], 
       "reviewed-by-human": true
@@ -9297,7 +9184,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12343046498140718348
+          11315694301382876090
         ]
       ], 
       "reviewed-by-human": true
@@ -9306,7 +9193,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6345971390397937472
+          17952171829995911009
         ]
       ], 
       "reviewed-by-human": true
@@ -9361,7 +9248,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4168067701806693625
+          3827095505720286728
         ]
       ], 
       "reviewed-by-human": true
@@ -9370,7 +9257,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17172040454616353959
+          3962214001616470324
         ]
       ], 
       "reviewed-by-human": true
@@ -9425,7 +9312,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12020342225442211019
+          4499532536817155763
         ]
       ], 
       "reviewed-by-human": true
@@ -9434,7 +9321,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15486455585945174582
+          2532277191814352883
         ]
       ], 
       "reviewed-by-human": true
@@ -9489,7 +9376,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1349764396121687334
+          9675188186932125398
         ]
       ], 
       "reviewed-by-human": true
@@ -9498,7 +9385,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13512793178880974830
+          252003960684820363
         ]
       ], 
       "reviewed-by-human": true
@@ -9553,7 +9440,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7087467719445182209
+          1555493983183157774
         ]
       ], 
       "reviewed-by-human": true
@@ -9562,7 +9449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13702064810817834637
+          9578858996653266547
         ]
       ], 
       "reviewed-by-human": true
@@ -9617,7 +9504,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8704557309892348458
+          10557249652522576828
         ]
       ], 
       "reviewed-by-human": true
@@ -9626,7 +9513,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4970802896499185146
+          13250886976686460858
         ]
       ], 
       "reviewed-by-human": true
@@ -9681,7 +9568,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15599673700324610016
+          7328053965687721632
         ]
       ], 
       "reviewed-by-human": true
@@ -9690,7 +9577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5268278487198498347
+          7059435553345332705
         ]
       ], 
       "reviewed-by-human": true
@@ -9745,7 +9632,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2798807683929613348
+          14172867549655561814
         ]
       ], 
       "reviewed-by-human": true
@@ -9754,7 +9641,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14825737167317700678
+          6198605176358084298
         ]
       ], 
       "reviewed-by-human": true
@@ -9763,43 +9650,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15878740706156254185
+          12115609809541331955
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3235842036818065829
+          7741874124483388245
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15878740706156254185
+          12115609809541331955
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14921341614033680796
+          8734915309544527654
         ]
       ], 
       "ignore-failure": true, 
@@ -9809,7 +9687,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13532382804553257370
+          1479964679245541605
         ]
       ], 
       "reviewed-by-human": true
@@ -9818,7 +9696,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3049241456762138365
+          11399081827859230847
         ]
       ], 
       "reviewed-by-human": true
@@ -9827,43 +9705,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9560342061098090172
+          7646299335763235021
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9291463380778281308
+          6192530157172807562
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9560342061098090172
+          7646299335763235021
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4700853947534465845
+          15094457383317574422
         ]
       ], 
       "ignore-failure": true, 
@@ -9873,7 +9742,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18193737071240070809
+          411558866575208409
         ]
       ], 
       "reviewed-by-human": true
@@ -9882,7 +9751,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2637407914961122231
+          761919473704229560
         ]
       ], 
       "reviewed-by-human": true
@@ -9891,48 +9760,93 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9924687013532237178
+          17595942081154547308
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12386000803794075244
+          13543482950582224848
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9924687013532237178
+          17595942081154547308
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14075196769671590809
+          3768630344114099033
         ]
       ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14901126990301924005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15801869881177332883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1042098274477732047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -9961,145 +9875,109 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15918710972937868190
+          8722739816575573844
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3837345849472965080
+          8941245033428719604
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10929108306360722303
+          14135920799259443071
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7771644967924691504
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7771644967924691504
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9689801458305733135
+          7674289571277755921
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          282728204444207247
+          2642821964627964924
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13196130985402258979
+          8742629042949635540
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          9377051299359577559
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          9377051299359577559
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13989853011208136427
+          6013434920470292904
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          751768362423893408
+          1305833112985343548
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
@@ -10144,7 +10022,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9376519829232163481
+          12584690214250652961
         ]
       ], 
       "reviewed-by-human": true
@@ -10158,66 +10036,113 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16389315216289626974
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          661283946918891348
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11191748144946304564
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16745962585467963862
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10670628188057478241
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2331397672223269101
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5346798618605808309
+          5983654477358278958
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18349477956646401922
+          18319238038903413042
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3521193882387509458
+          6867991060051121346
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9451184519094825250
+          4846529169177988106
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3521193882387509458
+          644210377077145666
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11514219422733957634
+          14185380098316064946
         ]
       ], 
       "reviewed-by-human": true
@@ -10271,13 +10196,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5923123814296227252
+          13267969425935880104
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -11104,6 +11026,438 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6172128683301553757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4827031153572338195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12594100502165346083
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14294242618865072998
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4586436592064500005
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_align_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12269852657063590148
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1252866419102335842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10974866288863391771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6064119078588419632
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4210787692809798256
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          777666299623824232
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4305684336407110182
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16206316588171820057
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8298209255771457934
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12499850813365812951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3023222294858564203
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12330676944414335565
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9799960307893174466
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17570093836970109349
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10991112512849041738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2417755546465359842
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11277304835575730956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          239948722457080288
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14487137818841721316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5505881283794409647
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10974866288863391771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13234881846499298757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6987984883296298526
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12196229923735361002
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14509163529223272481
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12820931542168562870
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7596124566362246306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907720242023997068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13491726316742145147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17754273294250967740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1777618438222741913
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6540527200127538614
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          676714076804984027
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -11135,10 +11489,7 @@
           2515733614721864626
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -11267,7 +11618,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa16.png": {
       "allowed-digests": [
@@ -11321,7 +11672,7 @@
           16605120526645549774
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa16.png": {
       "allowed-digests": [
@@ -11375,7 +11726,7 @@
           169027135498041421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa16.png": {
       "allowed-digests": [
@@ -11697,7 +12048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          10887305247691796896
         ]
       ], 
       "ignore-failure": false, 
@@ -11727,7 +12078,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
       "reviewed-by-human": true
@@ -11757,19 +12108,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3160793858475866402
+          15859984430307806446
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9161659132855227715
+          5659028446842583448
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -11778,11 +12131,8 @@
           92511276571386922
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
@@ -11791,22 +12141,16 @@
           3124201814718695673
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          92511276571386922
+          6404505258636913207
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -11897,38 +12241,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -12040,7 +12384,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15581784646583613988
+          17484477122955938183
         ]
       ], 
       "reviewed-by-human": true
@@ -12126,42 +12470,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4960440391450740763
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14416712990565014740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4727683076023577474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13176912798569666712
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2940066578573590628
+          6679146172037188198
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13749909274890084570
+          3705961818794504133
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16785789595319639672
+          12759686595185656420
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7734161192636331207
+          10603373527933089029
         ]
       ], 
       "reviewed-by-human": true
@@ -12170,7 +12567,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18175958529226931597
+          3953751248814186934
         ]
       ], 
       "reviewed-by-human": true
@@ -12179,37 +12576,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12058414599914735969
+          4016697118621605241
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13676918670476155168
+          2296889387509264077
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8866329483052081099
+          7404189070007343463
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
@@ -12224,25 +12612,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17135666482003439061
+          10265552030778016870
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12131741421773209441
+          3814516952917649585
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_pdf-poppler.png": {
       "allowed-digests": [
@@ -12297,13 +12679,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9451113239611252518
+          11358423048091168224
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12360,13 +12739,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15524566862764359637
+          3436830071126863243
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -12550,13 +12926,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13904453152957483485
+          10202019670274831016
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -12635,53 +13008,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3262803126131585722
+          13391508749678438749
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          661616009017115779
+          3054597254770601118
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9659350677391822056
+          1102950561799296746
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12695,61 +13061,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15966221253644391598
+          681401366445135140
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6803625819311760695
+          4219988338924914895
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6946593127096270008
+          14069830140047435524
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9004397529590800817
+          11403629407822261921
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15904079654772183797
+          2185400216731303545
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -12812,13 +13163,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6664533234575204169
+          13939654497258336594
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12881,13 +13229,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9054013070996242459
+          16773017670820649508
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -13014,13 +13359,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12731556315894686366
+          8030725662518062791
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13062,37 +13404,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -13240,10 +13582,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10291224769557172430
+          17704265017767572066
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -13283,13 +13626,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16282234596408134348
+          5709812329699199972
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13307,10 +13647,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11214635697117158219
+          15315508224860148267
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -13350,13 +13691,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12969761536311811498
+          13102837636444825585
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13387,37 +13725,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6584772443733517325
+          8036070052794735085
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          253712541328863653
+          2990680921703942550
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1534386106053156477
+          3328324156548225782
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13465,62 +13800,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14337201570310240929
+          8638631336814102897
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11202438527860078687
+          17927372218178797511
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14116185741175471915
+          11313936147221484357
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1818655397466532351
+          15887214589697950727
         ]
       ], 
       "reviewed-by-human": true
@@ -13607,39 +13935,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10807026657174943320
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_0x0_pdf-poppler.png": {
       "allowed-digests": [
@@ -13678,39 +13997,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10807026657174943320
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_1x4_pdf-poppler.png": {
       "allowed-digests": [
@@ -13752,39 +14062,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10807026657174943320
+          15858100026349596240
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "megalooper_4x1_pdf-poppler.png": {
       "allowed-digests": [
@@ -13832,14 +14133,14 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18053729995632638218
+          5194202950428804182
         ]
       ], 
       "bugs": [
         2354
       ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "mixed_xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
@@ -13882,37 +14183,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -13983,6 +14284,546 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8719876420876618449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5980286511424355844
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7730731144263164598
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7813398969375683276
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17643575047596097946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15845733488367618269
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13338081280989731045
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2672526945072259380
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5683870789515781899
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2429486074917537971
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -14284,59 +15125,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12155325540830354759
+          5996648237050377037
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3339405153867447160
+          3965248782497463807
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9089568072831657991
+          13332864465231151117
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9968769882425487491
+          1175479943072326396
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9089568072831657991
+          13332864465231151117
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10658811892185308847
+          4274397413122380873
         ]
       ], 
       "reviewed-by-human": true
@@ -14369,37 +15203,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
-        1578
+        2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -14468,6 +15302,114 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1970032844879616905
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1842269258804065125
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -14988,7 +15930,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -14997,7 +15939,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -15006,17 +15948,71 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7769408336713819900
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2934804817352937872
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15025,7 +16021,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15079,13 +16075,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12090999085559058466
+          5557910745049633908
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15096,6 +16089,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1843194965390816202
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -15150,6 +16197,60 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -15209,7 +16310,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17761441655459925802
+          6200040322909789654
         ]
       ], 
       "ignore-failure": false, 
@@ -15219,7 +16320,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          584852425794817692
+          2652863181334626267
         ]
       ], 
       "ignore-failure": false, 
@@ -15229,7 +16330,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16334305116962929134
+          11900472786319635625
         ]
       ], 
       "ignore-failure": false, 
@@ -15239,20 +16340,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12915657818379420968
+          859519043843310852
         ]
       ], 
-      "bugs": [
-        2354
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4725339200098775862
+          1554255494938845354
         ]
       ], 
       "reviewed-by-human": true
@@ -15336,10 +16434,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16424717553440518736
+          6254546707005318320
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -15379,13 +16478,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17195403769079449765
+          18127761162138529103
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15403,10 +16499,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3155083044843636999
+          12732664272876775262
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -15446,13 +16543,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14790270578728495649
+          1201544144882965410
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15554,38 +16648,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -15621,10 +16715,7 @@
           11339980900210544915
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -16308,13 +17399,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9712986429528697461
+          17402623096381811933
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -16368,7 +17456,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11484656948681556804
+          603889413078018210
         ]
       ], 
       "reviewed-by-human": true
@@ -16434,13 +17522,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3637152984721254457
+          16395924466838212878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -16473,7 +17558,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9952165733700277657
+          5688757353305988584
         ]
       ], 
       "reviewed-by-human": true
@@ -16482,7 +17567,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13785642655596247386
+          15611152105682208694
         ]
       ], 
       "reviewed-by-human": true
@@ -16509,7 +17594,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14845859051414195721
+          7427081417172568205
         ]
       ], 
       "reviewed-by-human": true
@@ -16518,7 +17603,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4487879976516068927
+          1703789635957684086
         ]
       ], 
       "reviewed-by-human": true
@@ -16527,7 +17612,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14845859051414195721
+          7488972794602546651
         ]
       ], 
       "reviewed-by-human": true
@@ -16545,7 +17630,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9952165733700277657
+          10724820182460485707
         ]
       ], 
       "reviewed-by-human": true
@@ -16771,7 +17856,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          214651258640525297
+          17067517941224065243
         ]
       ], 
       "ignore-failure": false, 
@@ -16781,7 +17866,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790110109815580358
+          786458466612254044
         ]
       ], 
       "reviewed-by-human": true
@@ -16790,25 +17875,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9290689085471276179
+          8805637738762869076
         ]
       ], 
-      "bugs": [
-        2619
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "shadertext2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4702027525692342270
+          8805974184185185146
         ]
       ], 
-      "bugs": [
-        2619
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -16816,7 +17895,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          387202918560141756
+          8051735558131986459
         ]
       ], 
       "reviewed-by-human": true
@@ -16825,7 +17904,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          363651743109664983
+          17433207623652171757
         ]
       ], 
       "ignore-failure": false, 
@@ -16863,7 +17942,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3569770788112621273
+          2353063788706484506
         ]
       ], 
       "reviewed-by-human": true
@@ -16881,7 +17960,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16118814308223737737
+          1855944793144275915
         ]
       ], 
       "ignore-failure": false, 
@@ -16891,7 +17970,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6564017357373772997
+          9541843996635442831
         ]
       ], 
       "ignore-failure": false, 
@@ -16901,7 +17980,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9492568723070634170
+          3706559258798264682
         ]
       ], 
       "ignore-failure": false, 
@@ -16911,7 +17990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11619459974005556843
+          2620134778866063734
         ]
       ], 
       "reviewed-by-human": true
@@ -16920,7 +17999,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          46744022306204318
+          14715792432845667200
         ]
       ], 
       "reviewed-by-human": true
@@ -17329,13 +18408,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4429473827193042884
+          14068765431433693142
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -17392,13 +18468,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5605338931353764550
+          316799210449981670
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -17455,13 +18528,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7217507911128786327
+          17371031338824646424
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_pdf-poppler.png": {
       "allowed-digests": [
@@ -17663,67 +18733,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1430031890715528002
+          7659929100708975654
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          254318060234203033
+          13619399217835536541
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          113135342230966660
+          12119099569932150047
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          113135342230966660
+          3794750305076354153
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11960639219773597759
+          4531129654172985200
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16134046954799129070
+          7657054601899880488
         ]
       ], 
       "reviewed-by-human": true
@@ -17844,13 +18899,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1781244994412984169
+          4126252108879846874
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -18171,7 +19223,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7615951997407285496
+          18299855773787932617
         ]
       ], 
       "reviewed-by-human": true
@@ -18180,7 +19232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17665436176340313326
+          3820153663375892124
         ]
       ], 
       "reviewed-by-human": true
@@ -18189,7 +19241,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2400348954160929648
+          16140885015853298544
         ]
       ], 
       "reviewed-by-human": true
@@ -18198,7 +19250,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4763201130776673922
+          13455217919464509867
         ]
       ], 
       "reviewed-by-human": true
@@ -18207,7 +19259,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5216165706151276286
+          10744565359108073823
         ]
       ], 
       "reviewed-by-human": true
@@ -18415,6 +19467,60 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17235038783782663409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16486637480158260521
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17762278278392565594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17762278278392565594
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1358760508249242163
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16903255024657466835
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -18486,28 +19592,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          461340767000445644
+          2252852476882257738
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7106538505228762194
+          9074211968785557862
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          461340767000445644
+          2252852476882257738
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -18534,11 +19640,8 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -18598,11 +19701,8 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -18644,55 +19744,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          126344850819174936
+          9375228469990118595
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15464669010903857039
+          14711755288216381805
         ]
       ], 
       "reviewed-by-human": true
@@ -18737,7 +19834,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11484656948681556804
+          603889413078018210
         ]
       ], 
       "reviewed-by-human": true
@@ -18803,13 +19900,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3637152984721254457
+          16395924466838212878
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -18844,7 +19938,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14621436615237149247
+          3862599236828490251
         ]
       ], 
       "ignore-failure": false, 
@@ -18854,7 +19948,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1853325399924584174
+          5442275593233872177
         ]
       ], 
       "reviewed-by-human": true
@@ -18881,7 +19975,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2051444200921081988
+          6329602332652473958
         ]
       ], 
       "reviewed-by-human": true
@@ -18890,7 +19984,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5664984420286171612
+          6138347655700728056
         ]
       ], 
       "reviewed-by-human": true
@@ -18899,7 +19993,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2051444200921081988
+          6901612585770457729
         ]
       ], 
       "reviewed-by-human": true
@@ -18917,7 +20011,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14621436615237149247
+          150588090347378989
         ]
       ], 
       "reviewed-by-human": true
@@ -19037,7 +20131,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10951464805453100925
+          7976185962753704838
         ]
       ], 
       "reviewed-by-human": true
@@ -19055,73 +20149,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4576021857620851191
+          2799147878061647403
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          745221849714643599
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5208636738166344971
+          4393488982813169804
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17391291832856229078
+          17296028215314109032
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_565.png": {
       "allowed-digests": [
@@ -19211,13 +20287,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11562249440399459338
+          11562824691469652309
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -19247,13 +20320,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4077398801659852267
+          12294528495888004394
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -19267,6 +20337,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10116032837978635800
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18154361016912445141
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3971059681811542268
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5442459823623424975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8952249585661143762
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11693715989410224137
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16280904268338645670
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10760709080022845641
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15543477125466102631
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7549142694352295409
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8418057357389671210
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12557729198294542220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7299943176517707258
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10092984979233544677
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14215331500430849765
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15022281553729610746
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12511123456870701231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5248478921458325627
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10277740082513188305
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9554470894306324526
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6371478998258738983
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16144209558281772024
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7231497730013821579
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8711004908212839257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -19397,7 +20683,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          197051971219635936
+          18327648018858793968
         ]
       ], 
       "ignore-failure": false, 
@@ -19407,7 +20693,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8329676900146900637
+          13883101138826307738
         ]
       ], 
       "ignore-failure": false, 
@@ -19417,7 +20703,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7557567270051125372
+          14377082299960675760
         ]
       ], 
       "ignore-failure": false, 
@@ -19427,7 +20713,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          138444525739207993
+          6530140610436991685
         ]
       ], 
       "reviewed-by-human": true
@@ -19436,7 +20722,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6271772538233648846
+          11287472543272099935
         ]
       ], 
       "reviewed-by-human": true
@@ -19445,7 +20731,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4922114328247158994
+          9163624118736443612
         ]
       ], 
       "reviewed-by-human": true
@@ -19497,7 +20783,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8981196494502834755
+          9432867194928348522
         ]
       ], 
       "reviewed-by-human": true
@@ -19578,62 +20864,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120931637037293931
+          9731357412382235356
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6709336082279713745
+          8697273950167613341
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          307767874711053345
+          8384210594534919664
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11089296821936872594
+          2963356239888582885
         ]
       ], 
       "reviewed-by-human": true
@@ -19660,38 +20939,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18290343612708221939
+          99304012495268944
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9543759850676654383
+          17976537055001151954
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18290343612708221939
+          7093901190222689258
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19746,13 +21022,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16770666263463766901
+          14175629323496966287
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -19785,38 +21058,35 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5334235195393676951
+          16935319345008694478
         ]
       ], 
       "bugs": [
         2325
       ], 
       "ignore-failure": false, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2467361690438720912
+          11975782723899906465
         ]
       ], 
       "bugs": [
         2325
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5334235195393676951
+          6129301005097965173
         ]
       ], 
-      "bugs": [
-        2325
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -19826,6 +21096,33 @@
         ]
       ], 
       "reviewed-by-human": true
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json b/expectations/gm/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug-Recipes/expected-results.json
similarity index 66%
rename from expectations/gm/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json
rename to expectations/gm/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug-Recipes/expected-results.json
index bdd5217..b210bc4 100644
--- a/expectations/gm/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug-Recipes/expected-results.json
@@ -1,45 +1,30 @@
 {
-  "actual-results": {
-    "failed": null, 
-    "failure-ignored": null, 
-    "no-comparison": null, 
-    "succeeded": null
-  }, 
   "expected-results": {
     "3x3bitmaprect_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16998423976396106083
+          12831071530564277917
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "3x3bitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2054956815327187963
+          17528757113465644181
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "3x3bitmaprect_gpu.png": {
+    "3x3bitmaprect_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2054956815327187963
+          943547538218683577
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "aaclip_565.png": {
@@ -49,7 +34,7 @@
           5680982666881858509
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "aaclip_8888.png": {
       "allowed-digests": [
@@ -58,16 +43,16 @@
           3732865537665519508
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "aaclip_gpu.png": {
+    "aaclip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10348117792540005656
+          16795945789209492348
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "aarectmodes_565.png": {
       "allowed-digests": [
@@ -76,9 +61,6 @@
           3404105191202303432
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "aarectmodes_8888.png": {
@@ -88,21 +70,15 @@
           11273986525140282221
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "aarectmodes_gpu.png": {
+    "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5564579097835689226
+          8649057832934655185
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "alphagradients_565.png": {
@@ -112,9 +88,6 @@
           1062660886109823876
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "alphagradients_8888.png": {
@@ -124,57 +97,15 @@
           8685680158225267849
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "alphagradients_gpu.png": {
+    "alphagradients_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16679719501773877249
+          9527652324911159875
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "android_paint_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14311572539143932530
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "android_paint_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8184968261467646356
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "android_paint_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16578618981524164940
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "arcofzorro_565.png": {
@@ -184,9 +115,6 @@
           14297291255102949024
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "arcofzorro_8888.png": {
@@ -196,118 +124,122 @@
           12650638297902351267
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "arcofzorro_gpu.png": {
+    "arcofzorro_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5103413628089441416
+          16200512925954076786
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "arithmode_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6535059923367762503
+          640004172515634810
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1951236732185589783
+          17302960578858142968
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "arithmode_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15667116140869597659
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bat_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15429625158026413569
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
-    "bezier_conic_effects_gpu.png": {
+    "arithmode_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11753547281694642402
+          7769026432982905461
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "bezier_cubic_effects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12989453616557980490
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bezier_quad_effects_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16976789512297453380
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_8888.png": {
+    "astcbitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10469536215464879914
+          7296080463405164282
         ]
       ], 
-      "bugs": [
-        1578
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7713084592037647903
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "bigbitmaprect_i_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13015342363421751909
+        ]
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_gpu.png": {
+    "bigbitmaprect_i_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17080656068138564372
+          966524621168003506
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": false
+    }, 
+    "bigbitmaprect_i_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10970557155523436171
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bigbitmaprect_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13015342363421751909
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bigbitmaprect_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          966524621168003506
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bigbitmaprect_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10970557155523436171
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -329,11 +261,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bigblurs_gpu.png": {
+    "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17467678310125758092
+          6539050160610613353
         ]
       ], 
       "reviewed-by-human": false
@@ -345,9 +277,6 @@
           6169251833522681202
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "bigmatrix_8888.png": {
@@ -357,57 +286,42 @@
           10455976041474647335
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "bigmatrix_gpu.png": {
+    "bigmatrix_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18154086740989312733
+          7908383583010729614
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "bigtext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9208106745937650664
+          4757895177073080988
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224084673272175658
+          9782529516066649880
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "bigtext_gpu.png": {
+    "bigtext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11616592246687288786
+          8689938548045974643
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "bitmap_premul_565.png": {
@@ -428,7 +342,7 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bitmap_premul_gpu.png": {
+    "bitmap_premul_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
@@ -437,32 +351,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "bitmapcopy_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15752676101273938692
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapcopy_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9026107375821215970
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "bitmapcopy_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9009932451531494327
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "bitmapfilters_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          299280079964293648
+          5753977543166902872
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "bitmapfilters_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1785801269079633261
+          3622726894191108275
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "bitmapfilters_gpu.png": {
+    "bitmapfilters_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8975361232797313708
+          1805467840158031920
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "bitmaprect_i_565.png": {
       "allowed-digests": [
@@ -471,9 +412,6 @@
           18028564147828277613
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "bitmaprect_i_8888.png": {
@@ -483,21 +421,15 @@
           14065905418589114539
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "bitmaprect_i_gpu.png": {
+    "bitmaprect_i_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8511579297892894623
+          6282651149745940821
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "bitmaprect_s_565.png": {
@@ -507,9 +439,6 @@
           18028564147828277613
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "bitmaprect_s_8888.png": {
@@ -519,21 +448,15 @@
           14065905418589114539
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "bitmaprect_s_gpu.png": {
+    "bitmaprect_s_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8511579297892894623
+          6282651149745940821
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "bitmaprecttest_565.png": {
@@ -543,9 +466,6 @@
           1454528164630516875
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "bitmaprecttest_8888.png": {
@@ -555,57 +475,42 @@
           1454528164630516875
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "bitmaprecttest_gpu.png": {
+    "bitmaprecttest_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1454528164630516875
+          15490976168363655365
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "bitmapscroll_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6745916709387193253
+          8206897152319623453
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4717735016506370050
+          12784106463433054207
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "bitmapscroll_gpu.png": {
+    "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          930590022062657844
+          18022002426854053968
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "bitmapshaders_565.png": {
@@ -615,7 +520,7 @@
           787402053855503258
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "bitmapshaders_8888.png": {
       "allowed-digests": [
@@ -624,13 +529,13 @@
           13897226711214500859
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "bitmapshaders_gpu.png": {
+    "bitmapshaders_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4527303960541121992
+          6777450024992468361
         ]
       ], 
       "reviewed-by-human": false
@@ -639,28 +544,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15581542612528711266
+          2360580519277032267
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13071585613760610277
+          13078362449576502397
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "bitmapsource_gpu.png": {
+    "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5847234706736959503
+          16291061935116366487
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "bleed_565.png": {
       "allowed-digests": [
@@ -669,7 +574,7 @@
           1844781142419806112
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "bleed_8888.png": {
       "allowed-digests": [
@@ -678,16 +583,16 @@
           749193672577578009
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "bleed_gpu.png": {
+    "bleed_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9718993354602675709
+          4572298529323124815
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "blurcircles_565.png": {
       "allowed-digests": [
@@ -707,6 +612,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurcircles_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12411969916048928910
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurquickreject_565.png": {
       "allowed-digests": [
         [
@@ -714,9 +628,6 @@
           14575894174086753692
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "blurquickreject_8888.png": {
@@ -726,1380 +637,42 @@
           1951057418144050940
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "blurquickreject_gpu.png": {
+    "blurquickreject_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8292097632245464218
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          820069996201877993
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3184582570657056326
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3184582570657056326
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12718077445807995842
+          10154742945558178134
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "blurrect_25_100_20_inner_slow_8888.png": {
+    "blurrect_gallery_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5778991912674004218
+          8181688189057988621
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "blurrect_25_100_20_inner_slow_gpu.png": {
+    "blurrect_gallery_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5778991912674004218
+          926365638072273755
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
-    "blurrect_25_100_20_normal_fast_565.png": {
+    "blurrect_gallery_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8935160718296765370
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16776390169922007578
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16776390169922007578
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2256669791146023451
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10179579145235258409
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10179579145235258409
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14392183012539686738
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16043278436798717097
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16043278436798717097
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_25_100_20_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14390657820413340948
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          795828165830353598
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_20_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          795828165830353598
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13601707396267686719
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8459602697994167638
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8459602697994167638
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10010715170666325693
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14526183591501064820
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14526183591501064820
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16822449160546304858
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2027939861397155283
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2027939861397155283
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7324830233289320569
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16228083818774745601
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16228083818774745601
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3539263275279493989
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11235472972448689767
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11235472972448689767
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18397664291113348978
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3014025170376903742
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_25_100_2_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3014025170376903742
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8147548538595899093
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8450430456683814098
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8450430456683814098
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3392741620327676409
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6934363565052222509
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6934363565052222509
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5777905000809157737
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6260375605261477035
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6260375605261477035
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          106403897902062488
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          685229733900948221
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          685229733900948221
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15285897477966750444
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8078454220178362362
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8078454220178362362
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_100_20_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17750039418684378027
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          805644383472349129
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_20_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          805644383472349129
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14103173815576510618
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8586295779506545029
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8586295779506545029
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17524943648572389133
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10060482719496990794
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10060482719496990794
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8152120831203711857
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10705231956829285301
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10705231956829285301
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12328862147889454268
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15258994592739155032
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15258994592739155032
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2981653799231691010
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14266854668713428040
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14266854668713428040
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13987214398939984878
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7552003167091473918
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_100_2_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7552003167091473918
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17480567211870826097
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17796133053007318503
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17796133053007318503
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17480567211870826097
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4056266015657707537
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4056266015657707537
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11526247382010115107
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17802184554241704666
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17802184554241704666
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14693279281973817316
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5373137501337162900
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5373137501337162900
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13364339805031281090
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8793723769315696288
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8793723769315696288
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "blurrect_5_5_20_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          778688345972082046
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3351391123811424042
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_20_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3351391123811424042
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          9837373898678543005
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8753902296095062956
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8753902296095062956
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8768734282047712040
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5736147449766359017
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_inner_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5736147449766359017
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13703672010266950657
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3606241125593407269
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3606241125593407269
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3915594753875998111
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15504874507306860669
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_normal_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15504874507306860669
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_fast_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3431843565557123885
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_fast_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5438277324777890642
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_fast_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5438277324777890642
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_slow_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12762400988164231611
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_slow_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15858720212484315695
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_5_5_2_outer_slow_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15858720212484315695
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_inner_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          621096468045033319
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_inner_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5693351230273671931
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_inner_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7704622158080950782
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_normal_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17577119326547731450
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_normal_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17173516333093181363
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_normal_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          4623570465766786751
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_outer_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8428983424693155205
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_outer_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10227974232335477600
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_outer_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13463578097308563300
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_solid_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17328977028061879775
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_solid_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16067654207889334831
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "blurrect_solid_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18282763485464690287
+          1361336023550239966
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "blurrects_565.png": {
@@ -2120,16 +693,16 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "blurrects_gpu.png": {
+    "blurrects_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          260989999972072184
+          17941713633255291753
         ]
       ], 
       "reviewed-by-human": false
     }, 
-    "blurroundrect-WH[100x100]-unevenCorners_565.png": {
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
@@ -2138,7 +711,7 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "blurroundrect-WH[100x100]-unevenCorners_8888.png": {
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
@@ -2147,11 +720,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "blurroundrect-WH[100x100]-unevenCorners_gpu.png": {
+    "blurroundrect-WH-100x100-unevenCorners_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8500043106468453797
+          2767554231532657737
         ]
       ], 
       "reviewed-by-human": false
@@ -2160,153 +733,81 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17805090981812894527
+          127907488061629881
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17800001274907447804
+          13925535616325299985
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "blurs_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          18332742573339604858
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "canvas-layer-state_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12670698167582780333
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "canvas-layer-state_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12670698167582780333
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "canvas-state_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11592955199341201053
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "canvas-state_8888.png": {
+    "blurs_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11592955199341201053
+          18058911750622887527
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "canvas-state_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5541967782360980927
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "chrome_gradtext1_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          773914938049404057
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          773914938049404057
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "chrome_gradtext1_gpu.png": {
+    "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6708894799496057436
+          14992838638363180728
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "chrome_gradtext2_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13774733025575034199
+          14434076065250953795
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13774733025575034199
+          14434076065250953795
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "chrome_gradtext2_gpu.png": {
+    "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3313052130644407339
+          15398054936392236728
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "circles_565.png": {
@@ -2316,9 +817,6 @@
           6008092610982260089
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "circles_8888.png": {
@@ -2328,21 +826,15 @@
           14991965560443449693
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "circles_gpu.png": {
+    "circles_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17106055778626858542
+          425924134218556955
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "circular-clips_565.png": {
@@ -2352,9 +844,6 @@
           7045926575348655010
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "circular-clips_8888.png": {
@@ -2364,21 +853,15 @@
           7045926575348655010
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "circular-clips_gpu.png": {
+    "circular-clips_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1988347527319338472
+          1812887249290830056
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "clamped_gradients_565.png": {
@@ -2388,9 +871,6 @@
           6740406662310759992
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "clamped_gradients_8888.png": {
@@ -2400,21 +880,15 @@
           12600235552582834170
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "clamped_gradients_gpu.png": {
+    "clamped_gradients_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15658888448911378390
+          8264377152451149106
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-clamp-hq_565.png": {
@@ -2435,14 +909,14 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "clipped-bitmap-shaders-clamp-hq_gpu.png": {
+    "clipped-bitmap-shaders-clamp-hq_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5000282312660607550
+          6731999058828201370
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-clamp_565.png": {
       "allowed-digests": [
@@ -2451,9 +925,6 @@
           6731999058828201370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-clamp_8888.png": {
@@ -2463,21 +934,15 @@
           6731999058828201370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "clipped-bitmap-shaders-clamp_gpu.png": {
+    "clipped-bitmap-shaders-clamp_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
           6731999058828201370
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-mirror-hq_565.png": {
@@ -2498,14 +963,14 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "clipped-bitmap-shaders-mirror-hq_gpu.png": {
+    "clipped-bitmap-shaders-mirror-hq_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18066226042033064966
+          16108448605784434508
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-mirror_565.png": {
       "allowed-digests": [
@@ -2514,9 +979,6 @@
           10131313151475985201
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-mirror_8888.png": {
@@ -2526,21 +988,15 @@
           10131313151475985201
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "clipped-bitmap-shaders-mirror_gpu.png": {
+    "clipped-bitmap-shaders-mirror_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10131313151475985201
+          16108448605784434508
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-tile-hq_565.png": {
@@ -2561,14 +1017,14 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "clipped-bitmap-shaders-tile-hq_gpu.png": {
+    "clipped-bitmap-shaders-tile-hq_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17436695901683300479
+          25307406092894825
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-tile_565.png": {
       "allowed-digests": [
@@ -2577,9 +1033,6 @@
           25307406092894825
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "clipped-bitmap-shaders-tile_8888.png": {
@@ -2589,21 +1042,15 @@
           25307406092894825
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "clipped-bitmap-shaders-tile_gpu.png": {
+    "clipped-bitmap-shaders-tile_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
           25307406092894825
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "clippedcubic_565.png": {
@@ -2613,9 +1060,6 @@
           2047816653827409443
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "clippedcubic_8888.png": {
@@ -2625,21 +1069,15 @@
           2047816653827409443
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "clippedcubic_gpu.png": {
+    "clippedcubic_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10318279557324425152
+          3311560533639750597
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "cmykjpeg_565.png": {
@@ -2649,9 +1087,6 @@
           13052709698662664204
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "cmykjpeg_8888.png": {
@@ -2661,20 +1096,41 @@
           9927483517871541702
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "cmykjpeg_gpu.png": {
+    "cmykjpeg_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9927483517871541702
+          4659204300078138667
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": false
+    }, 
+    "coloremoji_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6713179479512539555
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "coloremoji_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3701519862414100192
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "coloremoji_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6477632694560941064
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -2685,9 +1141,6 @@
           17051103650973594106
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "colorfilterimagefilter_8888.png": {
@@ -2697,21 +1150,15 @@
           1025940906896326990
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "colorfilterimagefilter_gpu.png": {
+    "colorfilterimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          192532786620859689
+          15427569532983092888
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "colormatrix_565.png": {
@@ -2721,9 +1168,6 @@
           3235581033534814469
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "colormatrix_8888.png": {
@@ -2733,28 +1177,22 @@
           5008998920935758481
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "colormatrix_gpu.png": {
+    "colormatrix_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1575688773869978322
+          15925679540242213002
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "colortype_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7789211976036245847
+          13536892577262913070
         ]
       ], 
       "reviewed-by-human": false
@@ -2763,19 +1201,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12063547141229638542
+          12336742096447867996
         ]
       ], 
       "reviewed-by-human": false
     }, 
-    "colortype_gpu.png": {
+    "colortype_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15432189428597356877
+          15192745610378391585
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip2_565.png": {
       "allowed-digests": [
@@ -2784,9 +1222,6 @@
           1971136545200141017
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "complexclip2_8888.png": {
@@ -2796,21 +1231,6 @@
           7558229948134696044
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "complexclip2_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          7558229948134696044
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "complexclip2_path_aa_565.png": {
@@ -2820,7 +1240,7 @@
           16086429144316222800
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip2_path_aa_8888.png": {
       "allowed-digests": [
@@ -2829,16 +1249,16 @@
           12832097210600987517
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "complexclip2_path_aa_gpu.png": {
+    "complexclip2_path_aa_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          626377265510811395
+          16333624854177111429
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip2_path_bw_565.png": {
       "allowed-digests": [
@@ -2847,7 +1267,7 @@
           13497374237280200272
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip2_path_bw_8888.png": {
       "allowed-digests": [
@@ -2856,17 +1276,23 @@
           13907447324398926215
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "complexclip2_path_bw_gpu.png": {
+    "complexclip2_path_bw_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6767202152973974411
+          14658110981814329983
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": false
+    }, 
+    "complexclip2_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12923310282749133071
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -2877,9 +1303,6 @@
           4388703640234091457
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "complexclip2_rect_aa_8888.png": {
@@ -2889,19 +1312,16 @@
           6840582159469938207
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "complexclip2_rect_aa_gpu.png": {
+    "complexclip2_rect_aa_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16628817470554933537
+          18110557533014404672
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip2_rrect_aa_565.png": {
       "allowed-digests": [
@@ -2910,7 +1330,7 @@
           11609605102436644365
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip2_rrect_aa_8888.png": {
       "allowed-digests": [
@@ -2919,16 +1339,16 @@
           6484021739759757221
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "complexclip2_rrect_aa_gpu.png": {
+    "complexclip2_rrect_aa_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12795866211978733736
+          13829636196206222589
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip2_rrect_bw_565.png": {
       "allowed-digests": [
@@ -2948,11 +1368,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "complexclip2_rrect_bw_gpu.png": {
+    "complexclip2_rrect_bw_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7607167258483373168
+          1099472031394618642
         ]
       ], 
       "reviewed-by-human": false
@@ -2961,109 +1381,109 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2183310436696200447
+          11137376764949716657
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          744025704131278337
+          9237294305986351770
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12123725839294251145
-        ]
-      ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3659943080425900329
+          6664819925988745829
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1205455874446983865
+          7782456344628243848
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "complexclip_aa_layer_gpu.png": {
+    "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6305857535625023602
+          16988686611786383576
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "complexclip_aa_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1263544685695288204
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "complexclip_bw_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12748157450884875422
+          1060100128535571349
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12349332232493061534
+          2130878875932816169
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "complexclip_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15377182906618145948
-        ]
-      ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2492514386480839663
+          10215436687867452743
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2975399947010553387
+          60525349492118674
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "complexclip_bw_layer_gpu.png": {
+    "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12578511015260635257
+          12717628662592109772
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "complexclip_bw_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9446421828323806547
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "composeshader_565.png": {
       "allowed-digests": [
@@ -3072,7 +1492,7 @@
           4616535333272790055
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "composeshader_8888.png": {
       "allowed-digests": [
@@ -3081,13 +1501,13 @@
           7653047818906774476
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "composeshader_alpha_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2785143308349902483
+          17593634704240688672
         ]
       ], 
       "reviewed-by-human": false
@@ -3096,25 +1516,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3069347792056802140
+          9779259465230566097
         ]
       ], 
       "reviewed-by-human": false
     }, 
-    "composeshader_gpu.png": {
+    "composeshader_alpha_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13415066704472475041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "composeshader_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
           13476719363156020502
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "convex_poly_clip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17917330964671139160
+          8663434824303916598
         ]
       ], 
       "reviewed-by-human": false
@@ -3123,29 +1552,20 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5601850589005836986
+          14359381315000567764
         ]
       ], 
       "reviewed-by-human": false
     }, 
-    "convex_poly_clip_gpu.png": {
+    "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3931972752458035902
+          3512710532978960058
         ]
       ], 
       "reviewed-by-human": false
     }, 
-    "convex_poly_effect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13562837227301896730
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "convexpaths_565.png": {
       "allowed-digests": [
         [
@@ -3153,9 +1573,6 @@
           12930829906409283378
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "convexpaths_8888.png": {
@@ -3165,19 +1582,16 @@
           5590017600958012619
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
-    "convexpaths_gpu.png": {
+    "convexpaths_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10865343678259724198
+          6644321117698340469
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "copyTo4444_565.png": {
       "allowed-digests": [
@@ -3186,9 +1600,6 @@
           13047964648578320887
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "copyTo4444_8888.png": {
@@ -3198,76 +1609,70 @@
           13512184095617016052
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "copyTo4444_gpu.png": {
+    "copyTo4444_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13512184095617016052
+          7180412349101917022
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "cubicclosepath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13521200955406107775
+          489208137730623687
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17912401236231679127
+          12844266625376066645
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "cubicclosepath_gpu.png": {
+    "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8341536688885218293
+          10634001722688422165
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "cubicpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6583472814997240235
+          3220333313183474890
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058335517377211817
+          4837814199747970292
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "cubicpath_gpu.png": {
+    "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11731651872638524201
+          1674572805676007669
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "dashcubics_565.png": {
       "allowed-digests": [
@@ -3276,9 +1681,6 @@
           1243485597747942942
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "dashcubics_8888.png": {
@@ -3288,19 +1690,16 @@
           561323664416995153
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "dashcubics_gpu.png": {
+    "dashcubics_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10530014763886697529
+          6372281393962002709
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "dashing2_565.png": {
       "allowed-digests": [
@@ -3309,9 +1708,6 @@
           7522047842497784488
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "dashing2_8888.png": {
@@ -3321,21 +1717,15 @@
           16976334130763507258
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "dashing2_gpu.png": {
+    "dashing2_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          751221660731865592
+          4486503885534337283
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "dashing3_565.png": {
@@ -3345,9 +1735,6 @@
           5458443768353447519
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "dashing3_8888.png": {
@@ -3357,21 +1744,15 @@
           2000525185460569669
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "dashing3_gpu.png": {
+    "dashing3_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1456612750003227022
+          10475351773979495594
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "dashing4_565.png": {
@@ -3381,7 +1762,7 @@
           3905274096451946067
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "dashing4_8888.png": {
       "allowed-digests": [
@@ -3390,7 +1771,16 @@
           1394068287232006716
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "dashing4_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          231561481260893579
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "dashing_565.png": {
       "allowed-digests": [
@@ -3399,9 +1789,6 @@
           2587070015488181148
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "dashing_8888.png": {
@@ -3411,73 +1798,67 @@
           11645276935331048518
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "dashing_gpu.png": {
+    "dashing_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18015592834088027197
+          18292104043667314195
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "degeneratesegments_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4578086267105259029
+          9095643239105155650
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1521449590373842396
+          7827702298324160095
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "degeneratesegments_gpu.png": {
+    "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16978708541322119393
+          6630828231561098435
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "deviceproperties_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5004276491084267368
+          17492958016254535864
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7746803903450904418
+          4607866981467817456
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "discard_gpu.png": {
+    "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1696674976993092902
+          15450980721964373933
         ]
       ], 
       "reviewed-by-human": false
@@ -3486,70 +1867,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10557537838778749160
+          3377544910324212919
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7089896533323038526
+          7432066987408472244
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "displacement_gpu.png": {
+    "displacement_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12394438758744026163
+          13993598563841655273
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "distantclip_gpu.png": {
+    "distantclip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -3558,16 +1930,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
     }, 
-    "downsamplebitmap_checkerboard_high_512_256_gpu.png": {
+    "downsamplebitmap_checkerboard_high_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9008293750211777201
+          7302661753448391976
         ]
       ], 
       "reviewed-by-human": true
@@ -3576,67 +1948,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
+    "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16704802669726334024
+          7302661753448391976
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
+    "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          992494534717898142
+          7302661753448391976
         ]
       ], 
       "reviewed-by-human": true
@@ -3645,43 +2002,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
+    "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3849621410806513723
+          7302661753448391976
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -3690,16 +2038,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
     }, 
-    "downsamplebitmap_image_high_mandrill_512.png_gpu.png": {
+    "downsamplebitmap_image_high_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4191803426779135801
+          8658998421535480067
         ]
       ], 
       "reviewed-by-human": true
@@ -3708,67 +2056,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
+    "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3676645757082565261
+          8658998421535480067
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
+    "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16700399834273149128
+          8658998421535480067
         ]
       ], 
       "reviewed-by-human": true
@@ -3777,43 +2110,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
+    "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          142674759365826172
+          8658998421535480067
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16519436267890610369
+          2638236405210610207
         ]
       ], 
       "reviewed-by-human": true
@@ -3822,16 +2146,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11825439513932272119
+          17152891550328552781
         ]
       ], 
       "reviewed-by-human": true
     }, 
-    "downsamplebitmap_text_high_72.00pt_gpu.png": {
+    "downsamplebitmap_text_high_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12649869831822432987
+          3964823451564767041
         ]
       ], 
       "reviewed-by-human": true
@@ -3840,7 +2164,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14912104351264232935
+          12888254052815311717
         ]
       ], 
       "reviewed-by-human": true
@@ -3849,16 +2173,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15487921510411770637
+          13146265116635825340
         ]
       ], 
       "reviewed-by-human": true
     }, 
-    "downsamplebitmap_text_low_72.00pt_gpu.png": {
+    "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4685776213094226352
+          3964823451564767041
         ]
       ], 
       "reviewed-by-human": true
@@ -3867,7 +2191,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10684547795556100510
+          17213204946752252417
         ]
       ], 
       "reviewed-by-human": true
@@ -3876,16 +2200,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577014624371342379
+          1395616124298337649
         ]
       ], 
       "reviewed-by-human": true
     }, 
-    "downsamplebitmap_text_medium_72.00pt_gpu.png": {
+    "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13141085848085289030
+          3964823451564767041
         ]
       ], 
       "reviewed-by-human": true
@@ -3894,7 +2218,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15469192468104182267
+          10492812055341362702
         ]
       ], 
       "reviewed-by-human": true
@@ -3903,16 +2227,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9482106153945169929
+          13729172239672956154
         ]
       ], 
       "reviewed-by-human": true
     }, 
-    "downsamplebitmap_text_none_72.00pt_gpu.png": {
+    "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          326696583887893469
+          3964823451564767041
         ]
       ], 
       "reviewed-by-human": true
@@ -3921,12 +2245,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5230239791132469231
+          5064010763405785676
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "drawbitmapmatrix_8888.png": {
@@ -3936,20 +2257,41 @@
           15096840641759877301
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "drawbitmapmatrix_gpu.png": {
+    "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16772618235934374845
+          2664813586291208208
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": false
+    }, 
+    "drawbitmaprect_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9262517121961573927
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawbitmaprect_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13473405500447885112
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "drawbitmaprect_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7924478814771357248
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -3957,55 +2299,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5134999156369384783
+          17705942446971461800
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12521309603120134056
+          7356321131319852548
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "drawlooper_gpu.png": {
+    "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8141288215353462246
+          244531940576930000
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "dropshadowimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17176620593335973597
+          104003251407946453
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13663064994494293289
+          17142865660189844867
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "dropshadowimagefilter_gpu.png": {
+    "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6983309335249454236
+          4817232172041585236
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "drrect_565.png": {
       "allowed-digests": [
@@ -4014,7 +2356,7 @@
           7282537335075785928
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "drrect_8888.png": {
       "allowed-digests": [
@@ -4023,61 +2365,43 @@
           8863849031372460120
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "drrect_gpu.png": {
+    "drrect_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3779095071531514150
+          14245969990125846971
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "emptypath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18094470146972105480
+          8357703037535831273
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16729138449439522348
+          15970947268409158917
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "emptypath_gpu.png": {
+    "emptypath_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8158239880603207616
+          12311402579038862924
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15855537393781495131
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "etc1bitmap_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10396043285211938891
-        ]
-      ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "etc1bitmap_ktx_565.png": {
       "allowed-digests": [
@@ -4086,7 +2410,7 @@
           10660132459335344948
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "etc1bitmap_ktx_8888.png": {
       "allowed-digests": [
@@ -4095,7 +2419,16 @@
           17338451294848191155
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "etc1bitmap_ktx_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8547826992249995128
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "etc1bitmap_npot_565.png": {
       "allowed-digests": [
@@ -4104,7 +2437,7 @@
           4755621039067033683
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "etc1bitmap_npot_8888.png": {
       "allowed-digests": [
@@ -4113,7 +2446,16 @@
           9352463391366748675
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "etc1bitmap_npot_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196298534905260259
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "etc1bitmap_pkm_565.png": {
       "allowed-digests": [
@@ -4122,7 +2464,7 @@
           10660132459335344948
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "etc1bitmap_pkm_8888.png": {
       "allowed-digests": [
@@ -4131,6 +2473,42 @@
           17338451294848191155
         ]
       ], 
+      "reviewed-by-human": false
+    }, 
+    "etc1bitmap_pkm_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8547826992249995128
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4552201006453026620
+        ]
+      ], 
       "reviewed-by-human": true
     }, 
     "extractbitmap_565.png": {
@@ -4140,7 +2518,7 @@
           11559795738519917215
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "extractbitmap_8888.png": {
       "allowed-digests": [
@@ -4149,16 +2527,16 @@
           11559795738519917215
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "extractbitmap_gpu.png": {
+    "extractbitmap_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11559795738519917215
+          13285669446805456944
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "factory_565.png": {
       "allowed-digests": [
@@ -4167,9 +2545,6 @@
           4768741511907258218
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "factory_8888.png": {
@@ -4179,21 +2554,15 @@
           11150486540244810089
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "factory_gpu.png": {
+    "factory_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11150486540244810089
+          3321350666216749569
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "fatpathfill_565.png": {
@@ -4203,9 +2572,6 @@
           7781767658511133788
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fatpathfill_8888.png": {
@@ -4215,21 +2581,15 @@
           15926472232550846517
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "fatpathfill_gpu.png": {
+    "fatpathfill_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2028184591354531695
+          17149952456267262208
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "filltypes_565.png": {
@@ -4239,9 +2599,6 @@
           6394623980536394421
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "filltypes_8888.png": {
@@ -4251,21 +2608,15 @@
           4586322702989781686
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "filltypes_gpu.png": {
+    "filltypes_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17693182030144018869
+          16710702184284734752
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "filltypespersp_565.png": {
@@ -4275,9 +2626,6 @@
           13448151295100783239
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "filltypespersp_8888.png": {
@@ -4287,262 +2635,259 @@
           1122618131815112502
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "filltypespersp_gpu.png": {
+    "filltypespersp_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8397994591127819291
+          549674585114504358
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_192_192_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7419227591265311221
+          2180768823026833562
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_192_192_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9941389284961210315
+          12199897808056356124
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_checkerboard_192_192_gpu.png": {
+    "filterbitmap_checkerboard_192_192_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13872974075155174385
+          5203388461958240579
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_32_2_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4712618105826416872
+          370415619944804844
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_32_2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6814786601958107546
+          8271636985969391381
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_checkerboard_32_2_gpu.png": {
+    "filterbitmap_checkerboard_32_2_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13175000843516560645
+          18444539834437971943
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_32_32_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11309219541124250528
+          4847810197899900218
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_32_32_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8042312968331390097
+          3506803607239781083
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_checkerboard_32_32_gpu.png": {
+    "filterbitmap_checkerboard_32_32_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12621944278316839160
+          10947750880182249988
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_32_8_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17324002053051694427
+          2090785975892516151
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_32_8_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10616193688896439855
+          2924211775552310056
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_checkerboard_32_8_gpu.png": {
+    "filterbitmap_checkerboard_32_8_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16892871506538567763
+          3205779391809712145
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_4_4_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10302533496874247276
+          16889052153239653128
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_checkerboard_4_4_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12569931102745160299
+          6790235028873950669
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_checkerboard_4_4_gpu.png": {
+    "filterbitmap_checkerboard_4_4_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3197389257186652855
+          10295529840226518047
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_128.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          842153490277803410
+          10744005928079115852
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_128.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7577999994704956939
+          6776804094106320859
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_image_mandrill_128.png_gpu.png": {
+    "filterbitmap_image_mandrill_128.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9016131185709747295
+          18151285181604935806
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_16.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17152997950184504727
+          12357182101174773078
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_16.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11428391327691184765
+          3126361758776039631
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_image_mandrill_16.png_gpu.png": {
+    "filterbitmap_image_mandrill_16.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3293710486546961723
+          7096762157070022778
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_256.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4139187976413040197
+          8367950844952921343
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_256.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14073034095251842923
+          15525258025464017393
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_image_mandrill_256.png_gpu.png": {
+    "filterbitmap_image_mandrill_256.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3264292480595545579
+          15118912166828841078
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_32.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17106863847823042087
+          7934322701486748120
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_32.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12215969181637652211
+          4704939924625922499
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_image_mandrill_32.png_gpu.png": {
+    "filterbitmap_image_mandrill_32.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16029411561224473754
+          11324987060954080537
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_512.png_565.png": {
       "allowed-digests": [
@@ -4551,7 +2896,7 @@
           8457226704515835046
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_512.png_8888.png": {
       "allowed-digests": [
@@ -4560,286 +2905,304 @@
           13673721686942765185
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_image_mandrill_512.png_gpu.png": {
+    "filterbitmap_image_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3518436430982597449
+          13858594519782999967
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_64.png_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3068653512092670589
+          18291684100428307360
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_image_mandrill_64.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15170271034615721666
+          1747669205907815761
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_image_mandrill_64.png_gpu.png": {
+    "filterbitmap_image_mandrill_64.png_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15252086719294314503
+          4012798572929329761
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_text_10.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11543071368100420439
+          5156627662604022054
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_text_10.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13979895877101196974
+          8632398522887565241
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_text_10.00pt_gpu.png": {
+    "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12174104284041385825
+          15532643418563789874
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_text_3.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10562352406325167130
+          14825303979752234211
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_text_3.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4740040018036044870
+          11659903379500873158
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_text_3.00pt_gpu.png": {
+    "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14844459319468499053
+          9073116125256346759
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_text_7.00pt_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2358351893182060187
+          4691168632586971202
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "filterbitmap_text_7.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17870285622555231718
+          7568389529702954124
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "filterbitmap_text_7.00pt_gpu.png": {
+    "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          434039534086427901
+          14781799138105324558
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "fontcache_gpu.png": {
+    "filterindiabox_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          994935463198632465
+          4735602592836874005
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1331259832456717901
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          3439736162679063809
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          15589891711481242151
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "fontmgr_iter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2211593642825930916
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          2642821964627964924
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          8742629042949635540
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "fontmgr_match_gpu.png": {
+    "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2211593642825930916
+          8688775630354981154
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "fontscaler_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13697197938526917158
+          6877271144203680721
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9665018536861377984
+          12744597724958166182
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "fontscaler_gpu.png": {
+    "fontscaler_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10979683921873521339
+          2357922959185985553
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16389315216289626974
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          661283946918891348
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2331397672223269101
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11098600005518612422
+          8262225973105376727
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12924368150056635888
+          18349477956646401922
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "gammatext_gpu.png": {
+    "gammatext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9988534402643805553
+          9058876046532708041
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "getpostextpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2033602119516310281
+          12680286771530511332
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8346234615044725182
+          1553084498081498101
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "getpostextpath_gpu.png": {
+    "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1245896931972085138
+          5011645329794375282
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "giantbitmap_clamp_bilerp_rotate_565.png": {
       "allowed-digests": [
@@ -4848,9 +3211,6 @@
           8844253733895577971
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_clamp_bilerp_rotate_8888.png": {
@@ -4860,21 +3220,15 @@
           373739036198791129
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_clamp_bilerp_rotate_gpu.png": {
+    "giantbitmap_clamp_bilerp_rotate_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8112152499985052384
+          8029692933389055752
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_clamp_bilerp_scale_565.png": {
@@ -4884,9 +3238,6 @@
           3486485929104356236
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_clamp_bilerp_scale_8888.png": {
@@ -4896,21 +3247,15 @@
           10633738215712183989
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_clamp_bilerp_scale_gpu.png": {
+    "giantbitmap_clamp_bilerp_scale_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8430366169989348557
+          10161295094898335059
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_clamp_point_rotate_565.png": {
@@ -4920,9 +3265,6 @@
           17592263249674059658
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_clamp_point_rotate_8888.png": {
@@ -4932,21 +3274,15 @@
           17592263249674059658
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_clamp_point_rotate_gpu.png": {
+    "giantbitmap_clamp_point_rotate_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17664227249162604428
+          8029692933389055752
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_clamp_point_scale_565.png": {
@@ -4956,9 +3292,6 @@
           9837143541713078189
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_clamp_point_scale_8888.png": {
@@ -4968,21 +3301,15 @@
           9837143541713078189
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_clamp_point_scale_gpu.png": {
+    "giantbitmap_clamp_point_scale_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9837143541713078189
+          10161295094898335059
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_mirror_bilerp_rotate_565.png": {
@@ -4992,9 +3319,6 @@
           4418651112090392588
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_mirror_bilerp_rotate_8888.png": {
@@ -5004,21 +3328,15 @@
           12707263608068309424
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_mirror_bilerp_rotate_gpu.png": {
+    "giantbitmap_mirror_bilerp_rotate_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18436669324822800859
+          2751342889503638150
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_mirror_bilerp_scale_565.png": {
@@ -5028,9 +3346,6 @@
           3198037782278889365
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_mirror_bilerp_scale_8888.png": {
@@ -5040,21 +3355,15 @@
           6252132392610996150
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_mirror_bilerp_scale_gpu.png": {
+    "giantbitmap_mirror_bilerp_scale_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9662671494674386025
+          561416556812940597
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_mirror_point_rotate_565.png": {
@@ -5064,9 +3373,6 @@
           7897959591317755434
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_mirror_point_rotate_8888.png": {
@@ -5076,21 +3382,15 @@
           7897959591317755434
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_mirror_point_rotate_gpu.png": {
+    "giantbitmap_mirror_point_rotate_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13311283151063713989
+          2751342889503638150
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_mirror_point_scale_565.png": {
@@ -5100,9 +3400,6 @@
           18105452151182268887
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_mirror_point_scale_8888.png": {
@@ -5112,21 +3409,15 @@
           18105452151182268887
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_mirror_point_scale_gpu.png": {
+    "giantbitmap_mirror_point_scale_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13431550740599981254
+          561416556812940597
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_repeat_bilerp_rotate_565.png": {
@@ -5136,9 +3427,6 @@
           14124862738846038338
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_repeat_bilerp_rotate_8888.png": {
@@ -5148,21 +3436,15 @@
           18058439211441456286
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_repeat_bilerp_rotate_gpu.png": {
+    "giantbitmap_repeat_bilerp_rotate_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16302744549495549154
+          3085496363958813180
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_repeat_bilerp_scale_565.png": {
@@ -5172,9 +3454,6 @@
           8227734820754620843
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_repeat_bilerp_scale_8888.png": {
@@ -5184,21 +3463,15 @@
           11021884726574795651
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_repeat_bilerp_scale_gpu.png": {
+    "giantbitmap_repeat_bilerp_scale_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4906927396615969438
+          2753677831554080556
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_repeat_point_rotate_565.png": {
@@ -5208,9 +3481,6 @@
           9093746103412643649
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_repeat_point_rotate_8888.png": {
@@ -5220,21 +3490,15 @@
           9093746103412643649
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_repeat_point_rotate_gpu.png": {
+    "giantbitmap_repeat_point_rotate_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13294138182223094091
+          3085496363958813180
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_repeat_point_scale_565.png": {
@@ -5244,9 +3508,6 @@
           14547059667322106211
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "giantbitmap_repeat_point_scale_8888.png": {
@@ -5256,20 +3517,230 @@
           14547059667322106211
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "giantbitmap_repeat_point_scale_gpu.png": {
+    "giantbitmap_repeat_point_scale_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1623953817113568190
+          2753677831554080556
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6172128683301553757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4827031153572338195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7333325208889016448
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4819930517064115638
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1543177897210203203
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11243193839916746068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16178092860099522122
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16783556862890570841
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8797749315680963967
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          752586750378005278
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6924162342084005951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16993536392893735257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7069684555966165547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15363890707028412369
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1036301532806773049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16178092860099522122
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16783556862890570841
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8797749315680963967
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10789911541747501993
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5336978858190419178
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3150104030080269441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907720242023997068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13491726316742145147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          676714076804984027
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -5280,9 +3751,6 @@
           16978210180572955621
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "gradient_dirty_laundry_8888.png": {
@@ -5292,21 +3760,15 @@
           637854104407104115
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "gradient_dirty_laundry_gpu.png": {
+    "gradient_dirty_laundry_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4735033599846615424
+          14879545126349478144
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "gradient_matrix_565.png": {
@@ -5316,9 +3778,6 @@
           9800597089191342482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "gradient_matrix_8888.png": {
@@ -5328,21 +3787,15 @@
           11303638772874009054
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "gradient_matrix_gpu.png": {
+    "gradient_matrix_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10145849591466155435
+          6435424937654608099
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "gradients_2pt_conical_edge_565.png": {
@@ -5363,11 +3816,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "gradients_2pt_conical_edge_gpu.png": {
+    "gradients_2pt_conical_edge_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8565726929159118677
+          4482872279875216090
         ]
       ], 
       "reviewed-by-human": false
@@ -5390,11 +3843,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "gradients_2pt_conical_inside_gpu.png": {
+    "gradients_2pt_conical_inside_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5119195493073943472
+          16070990744561825511
         ]
       ], 
       "reviewed-by-human": false
@@ -5417,11 +3870,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "gradients_2pt_conical_outside_gpu.png": {
+    "gradients_2pt_conical_outside_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8194516921738963656
+          17759078874248877834
         ]
       ], 
       "reviewed-by-human": false
@@ -5433,7 +3886,7 @@
           12097193819749785352
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "gradients_8888.png": {
       "allowed-digests": [
@@ -5442,7 +3895,7 @@
           15403609442106846169
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "gradients_degenerate_2pt_565.png": {
       "allowed-digests": [
@@ -5451,9 +3904,6 @@
           2419426995212058042
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "gradients_degenerate_2pt_8888.png": {
@@ -5463,32 +3913,17 @@
           6029254312400609793
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "gradients_degenerate_2pt_gpu.png": {
+    "gradients_degenerate_2pt_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13313927878342351507
+          10552995703607727960
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
-    "gradients_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6892258587104376755
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "gradients_local_perspective_565.png": {
       "allowed-digests": [
         [
@@ -5496,7 +3931,7 @@
           3955747071082596728
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "gradients_local_perspective_8888.png": {
       "allowed-digests": [
@@ -5505,17 +3940,16 @@
           10472560090813482435
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "gradients_local_perspective_gpu.png": {
+    "gradients_local_perspective_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16262330141361316575
+          6001294768641918463
         ]
       ], 
-      "ignore-failure": true, 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "gradients_many_565.png": {
       "allowed-digests": [
@@ -5535,11 +3969,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "gradients_many_gpu.png": {
+    "gradients_many_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9465514724720153003
+          8410813352026558145
         ]
       ], 
       "reviewed-by-human": false
@@ -5551,7 +3985,7 @@
           225020687293424504
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "gradients_no_texture_8888.png": {
       "allowed-digests": [
@@ -5560,25 +3994,34 @@
           11527542446888766490
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "gradients_no_texture_gpu.png": {
+    "gradients_no_texture_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16087518691782755600
+          8150003318299445045
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "gradients_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4629631123442965005
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "gradients_view_perspective_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12408080239125179236
+          10887305247691796896
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "gradients_view_perspective_8888.png": {
       "allowed-digests": [
@@ -5587,44 +4030,43 @@
           1082062268335165982
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "gradients_view_perspective_gpu.png": {
+    "gradients_view_perspective_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16663486379543086186
+          1337351715293494917
         ]
       ], 
-      "ignore-failure": true, 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "gradtext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297095911910169239
+          18362317620146061776
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5771478138095675386
+          10122989494294825043
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "gradtext_gpu.png": {
+    "gradtext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16088397879491903202
+          10553011693854087599
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "hairlines_565.png": {
       "allowed-digests": [
@@ -5633,9 +4075,6 @@
           9293293797458777202
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "hairlines_8888.png": {
@@ -5645,19 +4084,16 @@
           13269473576016756464
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "hairlines_gpu.png": {
+    "hairlines_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13785031436850319619
+          977372539310569340
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "hairmodes_565.png": {
       "allowed-digests": [
@@ -5666,9 +4102,6 @@
           13753109946556116551
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "hairmodes_8888.png": {
@@ -5678,21 +4111,6 @@
           9057348143868599843
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "hairmodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17279526082933136574
-        ]
-      ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "hittestpath_565.png": {
@@ -5702,9 +4120,6 @@
           9550811290357199511
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "hittestpath_8888.png": {
@@ -5714,49 +4129,43 @@
           15448966239818316608
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "hittestpath_gpu.png": {
+    "hittestpath_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16781705300910493680
+          4411948001429166519
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "image-surface_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17630890424038541282
+          14663702759700043076
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "image-surface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10851904927850256296
+          16562368907538301224
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "image-surface_gpu.png": {
+    "image-surface_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9401026423085178591
+          15433636742076345381
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imagealphathreshold_565.png": {
       "allowed-digests": [
@@ -5776,11 +4185,38 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "imagealphathreshold_gpu.png": {
+    "imagealphathreshold_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16743719107131210314
+          5381614661669977835
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4960440391450740763
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14416712990565014740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13176912798569666712
         ]
       ], 
       "reviewed-by-human": false
@@ -5789,117 +4225,109 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3869730655096851160
+          6679146172037188198
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          788899247822925790
+          3705961818794504133
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "imageblur_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5976634674759312143
-        ]
-      ], 
-      "bugs": [
-        2085
-      ], 
-      "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5781271367332766897
+          10603373527933089029
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imageblur_large_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13746237675706248024
+          3953751248814186934
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "imageblur_large_gpu.png": {
+    "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702998954585031011
+          18005277294461023140
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "imageblur_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18005277294461023140
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "imageblurtiled_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16654054210158593753
+          1672239788423162481
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2843556688273725953
+          6974201924079969276
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "imageblurtiled_gpu.png": {
+    "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10272013979024454230
+          7162962487674293114
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imagefiltersbase_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4532729496698970871
+          2326691465405459364
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7641510194452485262
+          16884114388917958169
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "imagefiltersbase_gpu.png": {
+    "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15637318917107725155
+          9065573693993931295
         ]
       ], 
-      "bugs": [
-        2005
-      ], 
-      "ignore-failure": true, 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imagefiltersclipped_565.png": {
       "allowed-digests": [
@@ -5907,7 +4335,8 @@
           "bitmap-64bitMD5", 
           14771974755728278127
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
@@ -5915,126 +4344,158 @@
           "bitmap-64bitMD5", 
           14537515405997069608
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
-    "imagefiltersclipped_gpu.png": {
+    "imagefiltersclipped_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8665802903094730049
+          3854266854123865664
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropexpand_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4519336739440884428
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropexpand_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10208891112154705698
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imagefilterscropexpand_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10153152457433802106
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "imagefilterscropped_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16480020330796061578
+          11640669486244643201
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4131813877373753759
+          12644236474180508699
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "imagefilterscropped_gpu.png": {
+    "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6114011311493833332
+          9547725908958363934
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imagefiltersgraph_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12620063976225784909
+          10388433292552933932
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          204467962017973076
+          4440912998596233461
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "imagefiltersgraph_gpu.png": {
+    "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1103995645853022148
+          8176890448257738684
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imagefiltersscaled_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
-    "imagefiltersscaled_gpu.png": {
+    "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17667280750482645242
+          7403124810876127284
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "imagemagnifier_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6327054889332906721
+          681401366445135140
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11878406934177300231
+          4219988338924914895
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "imagemagnifier_gpu.png": {
+    "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10399323179213606951
+          18005277294461023140
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "imageresizetiled_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11537830680807011411
+          7887138951532219849
         ]
       ], 
       "reviewed-by-human": false
@@ -6043,16 +4504,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2840733308476616973
+          16396699102124993997
         ]
       ], 
       "reviewed-by-human": false
     }, 
-    "imageresizetiled_gpu.png": {
+    "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2840733308476616973
+          9257807016249425727
         ]
       ], 
       "reviewed-by-human": false
@@ -6061,28 +4522,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11477547669639384796
+          13167829804362867725
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11751433989801294344
+          2361825756447877952
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "internal_links_gpu.png": {
+    "internal_links_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900375946366690268
+          9043139654089692170
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "inverse_paths_565.png": {
       "allowed-digests": [
@@ -6091,7 +4552,7 @@
           12462644636324896185
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "inverse_paths_8888.png": {
       "allowed-digests": [
@@ -6100,43 +4561,43 @@
           6825022448693098908
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "inverse_paths_gpu.png": {
+    "inverse_paths_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6283227002281509479
+          1421216790044501178
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "lcdtext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6122935913437439554
+          1988132027237865386
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511393143767092759
+          16014201600379326957
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "lcdtext_gpu.png": {
+    "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511393143767092759
+          8113796305250364456
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "lerpmode_565.png": {
       "allowed-digests": [
@@ -6145,9 +4606,6 @@
           10818286910555371914
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "lerpmode_8888.png": {
@@ -6157,49 +4615,43 @@
           4328896907702672721
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "lerpmode_gpu.png": {
+    "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14139714820651029117
+          125470945696302801
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "lighting_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6728484050681732905
+          6090553349191246080
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3122543961009401649
+          9341133377277028081
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "lighting_gpu.png": {
+    "lighting_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598689909109043043
+          7616938643195027057
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "lightingcolorfilter_565.png": {
       "allowed-digests": [
@@ -6219,11 +4671,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "lightingcolorfilter_gpu.png": {
+    "lightingcolorfilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6114476395450060705
+          1566440121364267926
         ]
       ], 
       "reviewed-by-human": false
@@ -6232,130 +4684,109 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564246142489134519
+          17704265017767572066
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1370520776657521517
+          14667404558591895503
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "lineclosepath_gpu.png": {
+    "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7446182077244886426
+          8510442037486798969
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "linepath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1981696952434326875
+          15315508224860148267
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15238792371190456534
+          6055819101912884425
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "linepath_gpu.png": {
+    "linepath_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10096967694534333921
+          1930191322006662925
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "lumafilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5049467161770100346
+          16269251141162771406
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374476823825156605
+          15427106535247705603
         ]
-      ]
-    }, 
-    "lumafilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3056389996783374736
-        ]
-      ]
-    }, 
-    "lumamode_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8495874039699811736
-        ]
-      ], 
-      "bugs": [
-        1578
       ], 
       "reviewed-by-human": false
     }, 
-    "lumamode_8888.png": {
+    "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15450664592066744642
+          5796675491511749899
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "matrixconvolution_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3101476576521947165
+          8638631336814102897
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10055081768235896808
+          17927372218178797511
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "matrixconvolution_gpu.png": {
+    "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589934301785253810
+          7071396690124545218
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -6375,11 +4806,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "matriximagefilter_gpu.png": {
+    "matriximagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8662058601690590393
+          2643837627687025900
         ]
       ], 
       "reviewed-by-human": false
@@ -6391,9 +4822,6 @@
           899343682044846669
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "megalooper_0x0_8888.png": {
@@ -6403,19 +4831,16 @@
           4811817245879819217
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "megalooper_0x0_gpu.png": {
+    "megalooper_0x0_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          389258352199308507
+          2758551896219999523
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "megalooper_1x4_565.png": {
       "allowed-digests": [
@@ -6424,9 +4849,6 @@
           899343682044846669
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "megalooper_1x4_8888.png": {
@@ -6436,19 +4858,16 @@
           4811817245879819217
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "megalooper_1x4_gpu.png": {
+    "megalooper_1x4_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          389258352199308507
+          14096836655867535987
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "megalooper_4x1_565.png": {
       "allowed-digests": [
@@ -6457,9 +4876,6 @@
           899343682044846669
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "megalooper_4x1_8888.png": {
@@ -6469,19 +4885,16 @@
           4811817245879819217
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "megalooper_4x1_gpu.png": {
+    "megalooper_4x1_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          389258352199308507
+          14096836655867535987
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "mixed_xfermodes_565.png": {
       "allowed-digests": [
@@ -6490,7 +4903,7 @@
           9621832453494372057
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "mixed_xfermodes_8888.png": {
       "allowed-digests": [
@@ -6499,16 +4912,7 @@
           1944307888764212912
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "mixed_xfermodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1159197049660363044
-        ]
-      ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "modecolorfilters_565.png": {
       "allowed-digests": [
@@ -6517,9 +4921,6 @@
           2595933616904054518
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "modecolorfilters_8888.png": {
@@ -6529,49 +4930,313 @@
           5532792141023246970
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "modecolorfilters_gpu.png": {
+    "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14409347541136653391
+          13609667650179480195
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "morphology_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13276990043616594793
+          12884451066028586476
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12053534281222176521
+          12036643626023843857
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "morphology_gpu.png": {
+    "morphology_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15160418634894798633
+          17520842664020170726
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3079799453812238375
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14931987213977619655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9459890334119679719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14490602083813002798
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13080903845231278138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3958036946589644576
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1881380590513849017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9953455340443885808
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16703202936429821262
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8366184577391542130
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          53192431698628771
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10112835462328054451
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2961865306057597398
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3241401692854862740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1420078327614095344
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17026130197066393055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9839416814727932547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17063737427249129273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9005793904365356420
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1008223773855662464
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14743834986366432049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9384774650876549956
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14961147148503095310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18380207362961681747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4755942226550790435
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2170985013237979948
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10964351607455754013
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13549282096200230349
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "nested_aa_565.png": {
       "allowed-digests": [
@@ -6580,7 +5245,7 @@
           2682194241459481981
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "nested_aa_8888.png": {
       "allowed-digests": [
@@ -6589,16 +5254,16 @@
           1792040421885608938
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "nested_aa_gpu.png": {
+    "nested_aa_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2956570062403950585
+          13966876451853453414
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "nested_bw_565.png": {
       "allowed-digests": [
@@ -6607,9 +5272,6 @@
           1642884649618332584
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "nested_bw_8888.png": {
@@ -6619,21 +5281,15 @@
           2247784507927793592
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "nested_bw_gpu.png": {
+    "nested_bw_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6638289994984814421
+          13966876451853453414
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "ninepatch-stretch_565.png": {
@@ -6643,7 +5299,7 @@
           18411873313823762166
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "ninepatch-stretch_8888.png": {
       "allowed-digests": [
@@ -6652,16 +5308,16 @@
           14862133879758372505
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "ninepatch-stretch_gpu.png": {
+    "ninepatch-stretch_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18240364857152463172
+          11186689125853156921
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "nonclosedpaths_565.png": {
       "allowed-digests": [
@@ -6681,11 +5337,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "nonclosedpaths_gpu.png": {
+    "nonclosedpaths_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2717683152392989202
+          9812948111090752522
         ]
       ], 
       "reviewed-by-human": false
@@ -6694,39 +5350,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15240835456320409473
+          5996648237050377037
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          249289862803617115
+          3965248782497463807
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "offsetimagefilter_gpu.png": {
+    "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17818108684129139098
+          6277456920245605123
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "optimizations_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13811812839638384010
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "optimizations_8888.png": {
@@ -6736,21 +5380,15 @@
           13857521313271479795
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "optimizations_gpu.png": {
+    "optimizations_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9820008929704962008
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "ovals_565.png": {
@@ -6760,9 +5398,6 @@
           4201817511424287157
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "ovals_8888.png": {
@@ -6772,20 +5407,68 @@
           1184189085315519615
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "ovals_gpu.png": {
+    "ovals_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10347668577930193751
+          17099657634061871413
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          933135777308706707
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1254335909041814733
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10830939811784361362
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3954700475348576410
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5491544966345994143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4738636976825604965
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -6793,34 +5476,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5447571501272498127
+          304940773186681613
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8312881875844297775
+          9673425434002710908
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "path-reverse_gpu.png": {
+    "path-reverse_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          772433085551372706
+          6849307079160737644
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "patheffect_565.png": {
       "allowed-digests": [
@@ -6829,9 +5506,6 @@
           16045594695628613487
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "patheffect_8888.png": {
@@ -6841,19 +5515,16 @@
           13136038454993854220
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "patheffect_gpu.png": {
+    "patheffect_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15962075333689603774
+          11374167470113636710
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "pathfill_565.png": {
       "allowed-digests": [
@@ -6862,7 +5533,7 @@
           9913956212375399295
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "pathfill_8888.png": {
       "allowed-digests": [
@@ -6871,16 +5542,16 @@
           12306117555345084962
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "pathfill_gpu.png": {
+    "pathfill_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13972162918751012955
+          1313008434183403262
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "pathinterior_565.png": {
       "allowed-digests": [
@@ -6889,7 +5560,7 @@
           3396766038203432666
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "pathinterior_8888.png": {
       "allowed-digests": [
@@ -6898,16 +5569,16 @@
           12110360517026697498
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "pathinterior_gpu.png": {
+    "pathinterior_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16405106071112654012
+          818376873979411246
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "pathinvfill_565.png": {
       "allowed-digests": [
@@ -6916,9 +5587,6 @@
           8654831421971241050
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "pathinvfill_8888.png": {
@@ -6928,52 +5596,43 @@
           11144284047498640984
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "pathinvfill_gpu.png": {
+    "pathinvfill_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3520993708181297768
+          10993442877907212694
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "pathopsinverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17617505767021323437
+          9203084105917442586
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "pathopsinverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11577432472710705185
+          4723631856577570487
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "pathopsinverse_gpu.png": {
+    "pathopsinverse_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          404088650467664322
+          1473281111378748058
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "pathopsskpclip_565.png": {
       "allowed-digests": [
@@ -6982,9 +5641,6 @@
           6154660184356174115
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "pathopsskpclip_8888.png": {
@@ -6994,19 +5650,16 @@
           4313744187563601995
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
-    "pathopsskpclip_gpu.png": {
+    "pathopsskpclip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          123433350506930487
+          8052622755390845664
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "peekpixels_565.png": {
       "allowed-digests": [
@@ -7026,11 +5679,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "peekpixels_gpu.png": {
+    "peekpixels_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10481810241231481688
+          4613879885074000279
         ]
       ], 
       "reviewed-by-human": false
@@ -7039,29 +5692,53 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "perlinnoise_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "perlinnoise_gpu.png": {
+    "perlinnoise_localmatrix_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5617237608049886158
+          1146938693925995110
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9642424294640112060
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -7069,28 +5746,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15710121230086435602
+          12579670983511239948
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1763586683528188858
+          12090999085559058466
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "pictureimagefilter_gpu.png": {
+    "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1763586683528188858
+          5831432114786455253
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8020729765378671984
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "pictureshader_565.png": {
       "allowed-digests": [
@@ -7099,7 +5803,7 @@
           9198676987657517428
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "pictureshader_8888.png": {
       "allowed-digests": [
@@ -7108,16 +5812,43 @@
           17117388175840647151
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "pictureshader_gpu.png": {
+    "pictureshader_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7549768996631810693
+          17893064590271461596
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17150111212732148326
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15340954572962785384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11685055315519282691
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "points_565.png": {
       "allowed-digests": [
@@ -7126,9 +5857,6 @@
           8567194488499472739
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "points_8888.png": {
@@ -7138,49 +5866,43 @@
           8567194488499472739
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "points_gpu.png": {
+    "points_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3323041250453388207
+          14208320379733166227
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "poly2poly_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1729179301788020778
+          6200040322909789654
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15018091812205538488
+          2652863181334626267
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "poly2poly_gpu.png": {
+    "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17764211397622357735
+          482433404568462611
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "polygons_565.png": {
       "allowed-digests": [
@@ -7200,11 +5922,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "polygons_gpu.png": {
+    "polygons_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1583603789414455339
+          11545521910555847306
         ]
       ], 
       "reviewed-by-human": false
@@ -7213,55 +5935,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17243480259296502336
+          6254546707005318320
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6891379388563692035
+          1252422633566762346
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "quadclosepath_gpu.png": {
+    "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6297650466511707379
+          8281746729489500204
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "quadpath_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6963865127519492895
+          12732664272876775262
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7223243377781866680
+          862660997116502875
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "quadpath_gpu.png": {
+    "quadpath_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5595773772993530952
+          17898736826805441849
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "radial_gradient2_565.png": {
       "allowed-digests": [
@@ -7270,9 +5992,6 @@
           2509551852078940571
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "radial_gradient2_8888.png": {
@@ -7282,21 +6001,15 @@
           4012506323387989153
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "radial_gradient2_gpu.png": {
+    "radial_gradient2_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11959852029544468073
+          1785332503518290427
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "radial_gradient_565.png": {
@@ -7306,9 +6019,6 @@
           10067107685325019703
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "radial_gradient_8888.png": {
@@ -7318,21 +6028,15 @@
           15369886492036014971
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "radial_gradient_gpu.png": {
+    "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8690270988024634484
+          9840979663035601085
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "rects_565.png": {
@@ -7342,7 +6046,7 @@
           7959433338453691623
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "rects_8888.png": {
       "allowed-digests": [
@@ -7351,16 +6055,16 @@
           10522172914016896806
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "rects_gpu.png": {
+    "rects_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14982217045743030920
+          565498776261988620
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "resizeimagefilter_565.png": {
       "allowed-digests": [
@@ -7368,7 +6072,8 @@
           "bitmap-64bitMD5", 
           11574452324482789141
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "resizeimagefilter_8888.png": {
       "allowed-digests": [
@@ -7376,15 +6081,17 @@
           "bitmap-64bitMD5", 
           15004076002839832883
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
-    "resizeimagefilter_gpu.png": {
+    "resizeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5076745909900181906
+          7720572764086610133
         ]
-      ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "roundrects_565.png": {
       "allowed-digests": [
@@ -7393,7 +6100,7 @@
           17752420136993868343
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "roundrects_8888.png": {
       "allowed-digests": [
@@ -7402,16 +6109,16 @@
           1161927000752559561
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "roundrects_gpu.png": {
+    "roundrects_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          835479464135575251
+          7907450306472145150
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "rrect_565.png": {
       "allowed-digests": [
@@ -7420,7 +6127,7 @@
           18340118795193628429
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "rrect_8888.png": {
       "allowed-digests": [
@@ -7429,61 +6136,7 @@
           14795654963615468231
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_aa_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13783532124190227221
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_aa_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13792455863265377338
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_aa_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8162996231165662471
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_bw_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          1500157245784304324
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_bw_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6810446943823350860
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "rrect_bw_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          3764224183150533222
-        ]
-      ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "rrect_clip_aa_565.png": {
       "allowed-digests": [
@@ -7492,7 +6145,7 @@
           14635716521372290944
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "rrect_clip_aa_8888.png": {
       "allowed-digests": [
@@ -7501,16 +6154,16 @@
           8853776977311383548
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "rrect_clip_aa_gpu.png": {
+    "rrect_clip_aa_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17915472794674819668
+          17335618681854141616
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "rrect_clip_bw_565.png": {
       "allowed-digests": [
@@ -7519,7 +6172,7 @@
           5677622882171244043
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "rrect_clip_bw_8888.png": {
       "allowed-digests": [
@@ -7528,16 +6181,16 @@
           16102744790083806869
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "rrect_clip_bw_gpu.png": {
+    "rrect_clip_bw_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2639533157784794570
+          12794106701249812755
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "rrect_draw_aa_565.png": {
       "allowed-digests": [
@@ -7557,11 +6210,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "rrect_draw_aa_gpu.png": {
+    "rrect_draw_aa_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134143739778253386
+          2874923958520656718
         ]
       ], 
       "reviewed-by-human": false
@@ -7584,167 +6237,131 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "rrect_draw_bw_gpu.png": {
+    "rrect_draw_bw_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2639533157784794570
+          2874923958520656718
         ]
       ], 
       "reviewed-by-human": false
     }, 
-    "rrect_effect_gpu.png": {
+    "rrect_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9741594763308804282
+          5393787589671924237
         ]
       ], 
       "reviewed-by-human": false
     }, 
-    "rrect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11654998290125202938
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "samplerstress_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          6887529583056247381
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "samplerstress_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15016075013768190397
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "samplerstress_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          979344291475393331
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
     "scaled_tilemode_bitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7135789859959079868
+          15085181508691477257
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "scaled_tilemode_bitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2185595877830848468
+          14900199030409304606
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "scaled_tilemode_bitmap_gpu.png": {
+    "scaled_tilemode_bitmap_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11540820957422662028
+          9399676858343702510
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "scaled_tilemode_gradient_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14913297062861988444
+          429600091114712424
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7517125506221018662
+          5780739589561614035
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "scaled_tilemode_gradient_gpu.png": {
+    "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14758428393785721359
+          11422427169520375363
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "scaled_tilemodes_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14647286245000917282
+          7381732169504243535
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "scaled_tilemodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16574168428196349390
+          12299183791498066390
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "scaled_tilemodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14378884143882412610
-        ]
-      ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "scaled_tilemodes_npot_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7491706677759704423
+          13834303788239784306
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "scaled_tilemodes_npot_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13922841069600322051
+          8924365548094931117
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "scaled_tilemodes_npot_gpu.png": {
+    "scaled_tilemodes_npot_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18413532602239109176
+          4839899270350514863
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "scaled_tilemodes_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6299321203234155995
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "selftest1_565.png": {
       "allowed-digests": [
@@ -7753,9 +6370,6 @@
           12927999507540085554
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "selftest1_8888.png": {
@@ -7765,21 +6379,15 @@
           1209453360120438698
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "selftest1_gpu.png": {
+    "selftest1_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
           1149339852105949057
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "selftest2_565.png": {
@@ -7789,9 +6397,6 @@
           8863920166200910451
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "selftest2_8888.png": {
@@ -7801,21 +6406,15 @@
           13451349865803053525
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "selftest2_gpu.png": {
+    "selftest2_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
           7903070799454133570
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "shaderbounds_linear_565.png": {
@@ -7825,9 +6424,6 @@
           4739835670329472924
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "shaderbounds_linear_8888.png": {
@@ -7837,20 +6433,86 @@
           17407206349726255504
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "shaderbounds_linear_gpu.png": {
+    "shaderbounds_linear_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9231268892600322210
+          3861587073991955167
         ]
       ], 
-      "bugs": [
-        1759
+      "reviewed-by-human": false
+    }, 
+    "shadertext2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16014371841028076561
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "shadertext2_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8357956844212052272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "shadertext3_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17433207623652171757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "shadertext3_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13395173877594535908
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "shadertext3_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3417608703392941692
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "shadertext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16716882881077358409
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "shadertext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14711512755683802427
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "shadertext_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5033402855732189708
+        ]
       ], 
       "reviewed-by-human": false
     }, 
@@ -7861,9 +6523,6 @@
           11496795807715360050
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "shadows_8888.png": {
@@ -7873,21 +6532,15 @@
           11973828271981934898
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "shadows_gpu.png": {
+    "shadows_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6393145760590998803
+          3202298987386568393
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "shallow_gradient_conical_565.png": {
@@ -7897,9 +6550,6 @@
           17982294224537325140
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "shallow_gradient_conical_8888.png": {
@@ -7909,19 +6559,16 @@
           10213220249745462631
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "shallow_gradient_conical_gpu.png": {
+    "shallow_gradient_conical_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17110523027129122270
+          11200986978138084393
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "shallow_gradient_linear_565.png": {
       "allowed-digests": [
@@ -7930,9 +6577,6 @@
           2414118852281882343
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "shallow_gradient_linear_8888.png": {
@@ -7942,21 +6586,15 @@
           2600596201303470577
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "shallow_gradient_linear_gpu.png": {
+    "shallow_gradient_linear_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13330672348717914117
+          6159317287087368010
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "shallow_gradient_radial_565.png": {
@@ -7966,9 +6604,6 @@
           7637358666429963225
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "shallow_gradient_radial_8888.png": {
@@ -7978,21 +6613,15 @@
           12757191687259698018
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "shallow_gradient_radial_gpu.png": {
+    "shallow_gradient_radial_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3576469387623502205
+          1782214594164146403
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "shallow_gradient_sweep_565.png": {
@@ -8002,9 +6631,6 @@
           6974552498637279685
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "shallow_gradient_sweep_8888.png": {
@@ -8014,103 +6640,97 @@
           766715199662180977
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "shallow_gradient_sweep_gpu.png": {
+    "shallow_gradient_sweep_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9322393820489779517
+          5288641012874610000
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "simpleaaclip_aaclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7216936724349703423
+          13098400038866920549
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8297028920093819054
+          13710429790167871057
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "simpleaaclip_aaclip_gpu.png": {
+    "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16021439723556558918
+          2544617820859390551
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "simpleaaclip_path_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7216936724349703423
+          13098400038866920549
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8505743106500736554
+          16506504346504275732
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "simpleaaclip_path_gpu.png": {
+    "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1978759492972376322
+          12919763059361649742
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "simpleaaclip_rect_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5181638003047557471
+          10032934596494084466
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2247183642119438840
+          12843146502433510065
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "simpleaaclip_rect_gpu.png": {
+    "simpleaaclip_rect_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16948766582215433974
+          12919763059361649742
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "simpleblurroundrect_565.png": {
       "allowed-digests": [
@@ -8119,7 +6739,7 @@
           335739214192474542
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "simpleblurroundrect_8888.png": {
       "allowed-digests": [
@@ -8128,16 +6748,16 @@
           5652577089689509120
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "simpleblurroundrect_gpu.png": {
+    "simpleblurroundrect_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15913476983071756158
+          2359097874306140716
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "skbug1719_565.png": {
       "allowed-digests": [
@@ -8146,9 +6766,6 @@
           2332391077132553330
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "skbug1719_8888.png": {
@@ -8158,21 +6775,15 @@
           13212045663266308489
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
-    "skbug1719_gpu.png": {
+    "skbug1719_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17095707402781773995
+          6153193177095332966
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "spritebitmap_565.png": {
@@ -8182,9 +6793,6 @@
           13563811160364567248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "spritebitmap_8888.png": {
@@ -8194,49 +6802,43 @@
           227198932212139294
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "spritebitmap_gpu.png": {
+    "spritebitmap_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5342593300778917277
+          12189389221010209921
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "srcmode_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14499438099795304341
+          7659929100708975654
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14771578516798309775
+          13619399217835536541
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "srcmode_gpu.png": {
+    "srcmode_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12943740194645175665
+          10113425430523985117
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -8245,9 +6847,6 @@
           517466260915157438
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "stringart_8888.png": {
@@ -8257,49 +6856,43 @@
           12919217765216356865
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
-    "stringart_gpu.png": {
+    "stringart_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8864794410650886097
+          12856026003403692851
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "stroke-fill_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3203505322339327449
+          6084133340719361077
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16626870905607243018
+          3095860065990533568
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "stroke-fill_gpu.png": {
+    "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15798393829747738691
+          11452796365743999728
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "strokerect_565.png": {
       "allowed-digests": [
@@ -8308,7 +6901,7 @@
           15458182862530229195
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "strokerect_8888.png": {
       "allowed-digests": [
@@ -8317,16 +6910,16 @@
           2467605443292336055
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "strokerect_gpu.png": {
+    "strokerect_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16007880695407826360
+          9431727042483531891
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "strokerects_565.png": {
       "allowed-digests": [
@@ -8335,9 +6928,6 @@
           10731083935300051992
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "strokerects_8888.png": {
@@ -8347,21 +6937,15 @@
           3590050428307921218
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "strokerects_gpu.png": {
+    "strokerects_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5747656467049588206
+          12459269287019925922
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "strokes3_565.png": {
@@ -8371,9 +6955,6 @@
           1686573849514282054
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "strokes3_8888.png": {
@@ -8383,21 +6964,15 @@
           9947658613138732028
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "strokes3_gpu.png": {
+    "strokes3_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7751974933403726499
+          690642312004948359
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "strokes_poly_565.png": {
@@ -8407,9 +6982,6 @@
           13975044413592406455
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "strokes_poly_8888.png": {
@@ -8419,21 +6991,15 @@
           9847781398855716283
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "strokes_poly_gpu.png": {
+    "strokes_poly_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5265350706794735927
+          6874636085752264778
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "strokes_round_565.png": {
@@ -8443,7 +7009,7 @@
           8830084223721413158
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "strokes_round_8888.png": {
       "allowed-digests": [
@@ -8452,40 +7018,40 @@
           14762739513429490065
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "strokes_round_gpu.png": {
+    "strokes_round_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          849657193303901676
+          6316118216701943272
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "stroketext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7449648884353637669
+          18299855773787932617
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "stroketext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4914721999172725849
+          3820153663375892124
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "stroketext_gpu.png": {
+    "stroketext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18332417829561221001
+          17413186770331227978
         ]
       ], 
       "reviewed-by-human": false
@@ -8497,9 +7063,6 @@
           6155339908971373908
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "tablecolorfilter_8888.png": {
@@ -8509,21 +7072,15 @@
           5497460981955702016
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "tablecolorfilter_gpu.png": {
+    "tablecolorfilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8226915152097966889
+          1107542531052783554
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "testimagefilters_565.png": {
@@ -8533,9 +7090,6 @@
           10876942606580879984
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "testimagefilters_8888.png": {
@@ -8545,91 +7099,67 @@
           6913857649673524662
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "testimagefilters_gpu.png": {
+    "testimagefilters_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12654679736886426328
+          2776142962929484390
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
-    "texdata_565.png": {
+    "textblob_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8202463522803346863
+          6283582074892934398
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "texdata_8888.png": {
+    "textblob_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8202463522803346863
+          11990496565593787222
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
-    "texdata_gpu.png": {
+    "textblob_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2736593828543197285
+          2298347222358284753
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13357146488219809893
+          1866332902720093759
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7386759365357423329
+          11251707344866523352
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "texteffects_gpu.png": {
+    "texteffects_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7386759365357423329
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "texture_domain_effect_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          11734977558073048483
+          17758489229198579022
         ]
       ], 
       "reviewed-by-human": false
@@ -8641,9 +7171,6 @@
           17949451347125150629
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "thinrects_8888.png": {
@@ -8653,21 +7180,15 @@
           12074631820414627784
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "thinrects_gpu.png": {
+    "thinrects_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5935862934447854810
+          666320551091630944
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "thinstrokedrects_565.png": {
@@ -8677,9 +7198,6 @@
           17882028260402842392
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "thinstrokedrects_8888.png": {
@@ -8689,157 +7207,151 @@
           2596255945580270876
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "thinstrokedrects_gpu.png": {
+    "thinstrokedrects_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18134316930773092342
+          14526100002179430622
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "tileimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15884441815359625883
+          9375228469990118595
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          13913574038782635042
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "tileimagefilter_gpu.png": {
+    "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6913371489075702069
+          9898471888378191754
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7135789859959079868
+          15085181508691477257
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "tilemode_bitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2185595877830848468
+          14900199030409304606
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "tilemode_bitmap_gpu.png": {
+    "tilemode_bitmap_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11540820957422662028
+          9399676858343702510
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "tilemode_gradient_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14913297062861988444
+          429600091114712424
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7517125506221018662
+          5780739589561614035
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "tilemode_gradient_gpu.png": {
+    "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14758428393785721359
+          11422427169520375363
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "tilemodes_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10553952199599604816
+          15096262708272513094
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "tilemodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14968443247329529117
+          3155101103011661780
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "tilemodes_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5254473306719673022
-        ]
-      ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "tilemodes_npot_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5008151281798703171
+          17384605692665114656
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "tilemodes_npot_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13298836052288001622
+          2051444200921081988
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "tilemodes_npot_gpu.png": {
+    "tilemodes_npot_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8451918751746608219
+          12699139152706924616
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "tilemodes_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1866790395919411069
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "tinybitmap_565.png": {
       "allowed-digests": [
@@ -8848,9 +7360,6 @@
           12538857845722393084
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
     "tinybitmap_8888.png": {
@@ -8860,109 +7369,94 @@
           11468465429225805
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
       "reviewed-by-human": false
     }, 
-    "tinybitmap_gpu.png": {
+    "tinybitmap_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5633315905476176630
+          8809171659405559850
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
       "reviewed-by-human": false
     }, 
     "twopointconical_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14356658846198325540
+          17419371928338190811
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "twopointconical_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6036270199387229964
+          12603748610281134586
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "twopointconical_gpu.png": {
+    "twopointconical_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7663579407369070653
+          11807976509148388142
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "typeface_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3225712846346731230
+          4576021857620851191
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3057908372893981204
+          5208636738166344971
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "typeface_gpu.png": {
+    "typeface_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3057908372893981204
+          17391291832856229078
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "typefacestyles_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5356705204909842699
+          2975121461919673787
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370428013149648258
+          4077398801659852267
         ]
       ], 
-      "reviewed-by-human": true
-    }, 
-    "typefacestyles_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13370428013149648258
-        ]
-      ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          201259875367580358
+          12736036630629987083
         ]
       ], 
       "reviewed-by-human": false
@@ -8971,16 +7465,133 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2080761164861757576
+          4088499375538585583
         ]
       ], 
       "reviewed-by-human": false
     }, 
-    "typefacestyles_kerning_gpu.png": {
+    "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8882773799933891216
+          15758506118142027562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "typefacestyles_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13469112554631044406
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6315732216230779153
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8115033200303266537
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4188115768451335358
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6767819970310290910
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2989466990197971651
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12304601970560557026
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9486126293825922645
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7920341665021649768
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8072725096013458348
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13383429714233549520
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1691634741439222638
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2146089154803149372
         ]
       ], 
       "reviewed-by-human": false
@@ -8998,7 +7609,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11220339642934269879
+          925585149480269261
         ]
       ], 
       "reviewed-by-human": false
@@ -9007,7 +7618,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5116617595194840746
+          5226204384509634475
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "vertices_80_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5541447607866535516
         ]
       ], 
       "reviewed-by-human": false
@@ -9021,11 +7641,11 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "vertices_gpu.png": {
+    "vertices_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1343433454959599907
+          5541447607866535516
         ]
       ], 
       "reviewed-by-human": false
@@ -9034,163 +7654,190 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2163610981651965452
+          197051971219635936
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14527641142409674625
+          8329676900146900637
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "verttext2_gpu.png": {
+    "verttext2_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3597293503861619263
+          5300807916778605796
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "verttext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4473316427232601425
+          15190076431667849841
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10869528886180759869
+          10923393792793064152
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "verttext_gpu.png": {
+    "verttext_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7700008644697398877
+          12436207478291469141
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
+    }, 
+    "verylargebitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6194629758544639580
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verylargebitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11880098846453637456
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "verylargebitmap_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11771739633730971374
+        ]
+      ], 
+      "reviewed-by-human": false
     }, 
     "xfermodeimagefilter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10958353996143090911
+          9731357412382235356
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17000878545702467803
+          8697273950167613341
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "xfermodeimagefilter_gpu.png": {
+    "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12340026112988841012
+          466567012962449593
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6775705236924739798
+          10791826234515004650
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2952493606222488372
+          6095374791930218953
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "xfermodes2_gpu.png": {
+    "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14811732441451933971
+          13509820775467975310
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "xfermodes3_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1103771815346361861
+          16108567015735396113
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14561360239620524377
+          8906891206365137079
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "xfermodes3_gpu.png": {
+    "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12574873031515180645
+          2784335417435063860
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "xfermodes_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6398363063795275200
+          18218431041656045348
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          382247129895543895
+          6381213170385594025
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }, 
-    "xfermodes_gpu.png": {
+    "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11611679597896853327
+          12332625502817210303
         ]
       ], 
-      "reviewed-by-human": true
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json b/expectations/gm/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json
index 09d6c58..44c31b3 100644
--- a/expectations/gm/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json
+++ b/expectations/gm/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json
@@ -226,42 +226,6 @@
       ], 
       "reviewed-by-human": false
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -512,7 +476,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9707111840054705070
+          5753977543166902872
         ]
       ], 
       "ignore-failure": false, 
@@ -522,7 +486,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966472219258108320
+          3622726894191108275
         ]
       ], 
       "ignore-failure": false, 
@@ -541,7 +505,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4512051244528732145
+          1805467840158031920
         ]
       ], 
       "reviewed-by-human": true
@@ -2241,6 +2205,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1361336023550239966
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -2520,6 +2511,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10612639499777084126
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6035759061702062244
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2767554231532657737
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -3490,19 +3508,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9308347137055900457
+          11137376764949716657
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          70554801271357149
+          9237294305986351770
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
@@ -3517,19 +3537,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11986351729917860717
+          6664819925988745829
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17407721376245627230
+          7782456344628243848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
@@ -3568,19 +3590,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17046138572928461942
+          1060100128535571349
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16848821614766946815
+          2130878875932816169
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
@@ -3595,19 +3619,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14046532233792735234
+          10215436687867452743
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6040117814573953462
+          60525349492118674
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
@@ -3700,28 +3726,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13480930557238326806
+          8663434824303916598
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9576951200427528769
+          14359381315000567764
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2842932421972883720
+          3512710532978960058
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -3799,10 +3825,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14629387967092406744
+          489208137730623687
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
@@ -3838,10 +3865,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8947422315903317870
+          3220333313183474890
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
@@ -4066,10 +4094,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18018965749997300368
+          9095643239105155650
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
@@ -4140,19 +4169,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16850764937772706343
+          3377544910324212919
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14105405523972827206
+          7432066987408472244
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
@@ -4167,49 +4198,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6600229641658723202
+          13993598563841655273
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_565.png": {
       "allowed-digests": [
@@ -4706,19 +4725,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11046937029873515189
+          17705942446971461800
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5239442822275439160
+          7356321131319852548
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
@@ -4797,10 +4818,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16565881092123145800
+          8357703037535831273
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
@@ -5512,6 +5534,33 @@
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4735602592836874005
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          46200135541452310
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1331259832456717901
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
@@ -5608,10 +5657,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5346798618605808309
+          8262225973105376727
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
@@ -6195,6 +6245,195 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6172128683301553757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4827031153572338195
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7333325208889016448
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4819930517064115638
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1543177897210203203
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11243193839916746068
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16178092860099522122
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16783556862890570841
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8797749315680963967
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          752586750378005278
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6924162342084005951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16993536392893735257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7069684555966165547
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15363890707028412369
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1036301532806773049
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16178092860099522122
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16783556862890570841
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8797749315680963967
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10789911541747501993
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5336978858190419178
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3150104030080269441
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -6571,7 +6810,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5045864062852669782
+          6188640951948066118
         ]
       ], 
       "ignore-failure": false, 
@@ -6581,7 +6820,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5108047977576892377
+          15983307837291793479
         ]
       ], 
       "ignore-failure": false, 
@@ -6763,19 +7002,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2940066578573590628
+          6679146172037188198
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13749909274890084570
+          3705961818794504133
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
@@ -6790,7 +7031,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7734161192636331207
+          10603373527933089029
         ]
       ], 
       "reviewed-by-human": true
@@ -6799,7 +7040,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18175958529226931597
+          3953751248814186934
         ]
       ], 
       "reviewed-by-human": true
@@ -7010,17 +7251,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15769177648683788265
+          6454090845110612368
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18437708945397499005
+          4353899728334541990
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -7034,25 +7277,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15966221253644391598
+          681401366445135140
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6803625819311760695
+          4219988338924914895
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -7286,10 +7523,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10291224769557172430
+          17704265017767572066
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
@@ -7325,10 +7563,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11214635697117158219
+          15315508224860148267
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
@@ -7414,19 +7653,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14337201570310240929
+          10810778304178838774
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11202438527860078687
+          3845484561850070276
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
@@ -7441,13 +7682,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1931826975545572792
+          7103351725800760269
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matriximagefilter_565.png": {
       "allowed-digests": [
@@ -7849,29 +8087,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12155325540830354759
+          5996648237050377037
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3339405153867447160
+          3965248782497463807
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1436176685703907921
+          6277456920245605123
         ]
       ], 
-      "bugs": [
-        1884
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_565.png": {
       "allowed-digests": [
@@ -8234,7 +8471,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -8243,7 +8480,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -8257,6 +8494,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13712645074845199757
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -8364,7 +8628,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17761441655459925802
+          6200040322909789654
         ]
       ], 
       "ignore-failure": false, 
@@ -8374,7 +8638,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          584852425794817692
+          2652863181334626267
         ]
       ], 
       "ignore-failure": false, 
@@ -8432,10 +8696,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16424717553440518736
+          6254546707005318320
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
@@ -8471,10 +8736,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3155083044843636999
+          12732664272876775262
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
@@ -9188,7 +9454,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9342750822777050473
+          16014371841028076561
         ]
       ], 
       "ignore-failure": false, 
@@ -9207,7 +9473,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5483462587049856153
+          8357956844212052272
         ]
       ], 
       "reviewed-by-human": true
@@ -9254,7 +9520,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1800000102265782105
+          16716882881077358409
         ]
       ], 
       "ignore-failure": false, 
@@ -9264,7 +9530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12281091565078967987
+          14711512755683802427
         ]
       ], 
       "ignore-failure": false, 
@@ -9669,37 +9935,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1430031890715528002
+          7659929100708975654
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          254318060234203033
+          13619399217835536541
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4072778636575166791
+          10113425430523985117
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stringart_565.png": {
       "allowed-digests": [
@@ -9975,7 +10232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7615951997407285496
+          18299855773787932617
         ]
       ], 
       "reviewed-by-human": true
@@ -9984,7 +10241,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17665436176340313326
+          3820153663375892124
         ]
       ], 
       "reviewed-by-human": true
@@ -10224,29 +10481,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          126344850819174936
+          9375228469990118595
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10116568998534667241
+          13913574038782635042
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5814251851586099649
+          9898471888378191754
         ]
       ], 
-      "bugs": [
-        1884
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_bitmap_565.png": {
       "allowed-digests": [
@@ -10552,6 +10808,114 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6315732216230779153
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8115033200303266537
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4188115768451335358
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6767819970310290910
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2989466990197971651
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12304601970560557026
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9486126293825922645
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7920341665021649768
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8072725096013458348
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13383429714233549520
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1691634741439222638
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_pdf-poppler.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2146089154803149372
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -10713,19 +11077,21 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120931637037293931
+          9731357412382235356
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6709336082279713745
+          8697273950167613341
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
@@ -10740,13 +11106,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3958323457448654683
+          466567012962449593
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_565.png": {
       "allowed-digests": [
diff --git a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug-ANGLE/expected-results.json b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug-ANGLE/expected-results.json
index ca9fb40..818006d 100644
--- a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug-ANGLE/expected-results.json
+++ b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug-ANGLE/expected-results.json
@@ -148,10 +148,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1526268471177155551
+          17598662146761915222
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_gpu.png": {
       "allowed-digests": [
@@ -318,10 +319,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6329400057600097234
+          13043841266956948959
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
@@ -347,6 +349,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_angle.png": {
       "allowed-digests": [
         [
@@ -424,66 +435,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5515466835202955433
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17527609633242467013
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_angle.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10573214378214332517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10573214378214332517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -608,10 +559,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6890339176809960518
+          7784555326813513893
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -699,13 +650,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9285075549510159913
+          12344393715903085582
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
@@ -819,10 +767,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          6658400916517904289
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
@@ -876,10 +825,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15067856232268696933
+          7702289957265438175
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapfilters_gpu.png": {
       "allowed-digests": [
@@ -1113,7 +1063,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6636953761704810781
+          3749700138471010191
         ]
       ], 
       "ignore-failure": false, 
@@ -1193,7 +1143,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          49884881388550458
+          2657634365985855345
         ]
       ], 
       "reviewed-by-human": true
@@ -1228,10 +1178,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7294639324157923250
+          5564289181496146035
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_gpu.png": {
       "allowed-digests": [
@@ -3281,6 +3234,15 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12424138734353506606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -3552,7 +3514,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10988013427224104734
+          12469056507152539419
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3790505575251759681
         ]
       ], 
       "reviewed-by-human": false
@@ -3594,10 +3565,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13287019284984521481
+          10837998485880758642
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
@@ -3747,10 +3719,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
@@ -3804,10 +3777,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5398721390547657273
+          775573788840541761
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
@@ -4509,13 +4483,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          660002910751114028
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
@@ -4686,7 +4657,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17128498486631460526
+          7760022190728266716
         ]
       ], 
       "reviewed-by-human": true
@@ -5010,7 +4981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058483060047613631
+          16296263294649982832
         ]
       ], 
       "reviewed-by-human": true
@@ -5052,7 +5023,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14533261291613333659
+          6930594261089573842
         ]
       ], 
       "reviewed-by-human": true
@@ -5118,7 +5089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17231147392296689177
+          13646830220341132229
         ]
       ], 
       "reviewed-by-human": true
@@ -5160,7 +5131,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5263345208833070549
+          1683602642474003356
         ]
       ], 
       "reviewed-by-human": true
@@ -5268,7 +5239,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4153150429672455644
+          11323802454873808645
         ]
       ], 
       "reviewed-by-human": true
@@ -5413,7 +5384,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13125632869332727872
+          980265202579587852
         ]
       ], 
       "ignore-failure": false, 
@@ -5471,7 +5442,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17028001984269604559
+          16571742391219299955
         ]
       ], 
       "ignore-failure": false, 
@@ -5675,7 +5646,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1948223754134562857
+          10828679394151128246
         ]
       ], 
       "reviewed-by-human": true
@@ -5767,10 +5738,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15903710117831491594
+          12640422166305242801
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
@@ -5824,10 +5796,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1357781408314308336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
@@ -5890,10 +5863,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
@@ -5947,13 +5921,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
@@ -6007,7 +5978,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8197937578774172307
+          5074057389327471760
         ]
       ], 
       "reviewed-by-human": true
@@ -6061,13 +6032,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18151825792332629539
+          12554309158897513995
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
@@ -6121,7 +6089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8197937578774172307
+          5074057389327471760
         ]
       ], 
       "reviewed-by-human": true
@@ -6178,13 +6146,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17863627234966078184
+          2377348236008994698
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
@@ -6238,7 +6203,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2622242306943640776
+          9281115052846806992
         ]
       ], 
       "reviewed-by-human": true
@@ -6292,13 +6257,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15543119602279131183
+          4221707714960246704
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
@@ -6352,7 +6314,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2622242306943640776
+          9281115052846806992
         ]
       ], 
       "reviewed-by-human": true
@@ -6409,13 +6371,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17606136414045263365
+          17385794784074028214
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
@@ -6469,7 +6428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15827887096973936314
+          5031508746353160829
         ]
       ], 
       "reviewed-by-human": true
@@ -6523,13 +6482,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7939602626345563815
+          7706893206933305485
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
@@ -6583,7 +6539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15827887096973936314
+          5031508746353160829
         ]
       ], 
       "reviewed-by-human": true
@@ -6640,13 +6596,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1271443847717805806
+          9867001988272277110
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
@@ -6700,10 +6653,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10262587862336842078
+          13868366127434680362
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_gpu.png": {
       "allowed-digests": [
@@ -6757,10 +6711,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10072750740945871465
+          16553053007513863215
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
@@ -6814,10 +6769,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13717384973349640095
+          14666226782194455577
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
@@ -6863,9 +6819,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1209493015352084772
+          6269586002134908784
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
@@ -6920,10 +6877,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6448857246475111318
+          12215957626196597172
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
@@ -6985,6 +6943,15 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -7786,7 +7753,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8252495047556495076
+          18109428777592547662
         ]
       ], 
       "reviewed-by-human": true
@@ -7832,7 +7799,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17928075006619754842
+          13062378031799365156
         ]
       ], 
       "reviewed-by-human": true
@@ -7878,7 +7845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4214729581428645124
+          4650431575315769874
         ]
       ], 
       "reviewed-by-human": true
@@ -7902,17 +7869,23 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13141254399024073210
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_angle.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
@@ -7954,7 +7927,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3080700020968668861
+          7775298570096891696
         ]
       ], 
       "ignore-failure": true, 
@@ -7988,13 +7961,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16100319568123135454
+          7775298570096891696
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
@@ -8049,13 +8019,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          12563966124941755321
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
@@ -8109,10 +8076,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5775802194278023812
+          2383876210829591671
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
@@ -8138,6 +8106,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16334966420230267651
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
@@ -8166,10 +8143,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5632244007594345836
+          7380380359170776688
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
@@ -8223,7 +8201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16749118127216539313
+          10038204505088525800
         ]
       ], 
       "reviewed-by-human": true
@@ -8933,6 +8911,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9050243732888826330
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7863480688033981489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7863480688033981489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17081537394391627241
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14705873799684872747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7863480688033981489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1599569324088157595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5858961485035967834
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -8964,10 +9014,7 @@
           12213884113784735929
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_gpu.png": {
       "allowed-digests": [
@@ -9385,10 +9432,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2328482482999487459
+          9833133577951959237
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -9488,10 +9536,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3558248687285610866
+          8148623670954566533
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hairmodes_gpu.png": {
       "allowed-digests": [
@@ -9590,7 +9639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15896254500886456697
+          18338026403264996017
         ]
       ], 
       "reviewed-by-human": true
@@ -9628,6 +9677,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11847517854086327634
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
@@ -9656,10 +9714,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9856700641955552351
+          11888686022754756017
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
@@ -9695,7 +9754,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12958440671393733211
+          7044686035558524733
         ]
       ], 
       "reviewed-by-human": true
@@ -9741,9 +9800,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7515396075491109228
+          4641014269499037622
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
@@ -9789,10 +9849,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9246209776414716804
+          7613331097292776777
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
@@ -9887,9 +9948,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17887140213824821509
+          3192280854189963519
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
@@ -9939,10 +10001,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18200079507569830870
+          214593100636960333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
@@ -9988,9 +10051,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8048174065831948696
+          17129964158848571576
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
@@ -10036,13 +10100,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12316458082598669525
+          10548005182299770458
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
@@ -10072,10 +10133,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_565.png": {
       "allowed-digests": [
@@ -10105,13 +10166,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
@@ -10222,10 +10280,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
@@ -10279,13 +10338,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16271637167989743463
+          9812993713815487791
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_gpu.png": {
       "allowed-digests": [
@@ -10339,10 +10398,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7390396075740049141
+          17747269762102294402
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
@@ -10405,10 +10465,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8200021215559120818
+          4436921789491969731
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
@@ -10462,10 +10523,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17364323165819274082
+          1230289844649030381
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
@@ -10511,9 +10573,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7139505319228028644
+          5229191514367865056
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
@@ -10600,10 +10663,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          76021802114671408
+          8299715471717602450
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
@@ -10666,7 +10730,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16926225104435755293
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -10720,7 +10784,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16926225104435755293
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -10774,7 +10838,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16926225104435755293
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -10822,7 +10886,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12761674399065406539
+          3719160171581050213
         ]
       ], 
       "reviewed-by-human": true
@@ -10864,13 +10928,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11302360056092717723
+          2992375879142624268
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_gpu.png": {
       "allowed-digests": [
@@ -10924,10 +10988,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
@@ -10953,6 +11018,96 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17287639956046803338
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8850164348354363393
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9121382299391264577
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11695898540945930296
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2845576788353783281
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11211712352447365565
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6388754610233777743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8396932509075294070
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5815720514657918820
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13123455672052131213
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -11156,9 +11311,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
@@ -11208,13 +11364,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          17352743232213033167
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_gpu.png": {
       "allowed-digests": [
@@ -11297,6 +11453,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13184440885036233012
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12714294017370964694
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -11325,7 +11499,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7576885622105024513
+          5487905569373974848
         ]
       ], 
       "reviewed-by-human": true
@@ -11722,7 +11896,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13918912246429055687
+          17735883773617287292
         ]
       ], 
       "reviewed-by-human": true
@@ -11736,6 +11910,15 @@
       ], 
       "ignore-failure": false
     }, 
+    "perlinnoise_localmatrix_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16250745281745965444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -11768,10 +11951,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
@@ -11781,6 +11964,15 @@
         ]
       ]
     }, 
+    "pictures_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_angle.png": {
       "allowed-digests": [
         [
@@ -11790,6 +11982,15 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -11875,10 +12076,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          762243915147523410
+          15759320443030700079
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
@@ -11941,10 +12143,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17174790409763084733
+          13266574652712721391
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
@@ -11998,10 +12201,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11798651298936594976
+          4607089709845142814
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
@@ -12107,10 +12311,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5440525180981761895
+          15164085309365805708
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_gpu.png": {
       "allowed-digests": [
@@ -12547,10 +12752,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1273169501689516162
+          11023997900504944144
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
@@ -12604,7 +12810,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -12661,13 +12867,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13319064646371789115
+          2175335291804019445
         ]
       ], 
-      "bugs": [
-        1603
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
@@ -12721,7 +12924,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7118242390016568495
+          5882099978049709122
         ]
       ], 
       "reviewed-by-human": true
@@ -12766,7 +12969,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12615277578507098981
+          10535089760215978010
         ]
       ], 
       "reviewed-by-human": true
@@ -12997,7 +13200,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12504534449156720496
+          4461440472871449053
         ]
       ], 
       "reviewed-by-human": true
@@ -13048,7 +13251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          235287745026699518
+          12216133416504143715
         ]
       ], 
       "reviewed-by-human": true
@@ -13099,7 +13302,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15734966135864889540
+          5767367904615292779
         ]
       ], 
       "ignore-failure": false, 
@@ -13454,13 +13657,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219446946103144942
+          2597227467519029948
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
@@ -13514,7 +13714,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12528160347888068703
+          12130054421194224314
         ]
       ], 
       "reviewed-by-human": true
@@ -13571,7 +13771,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8616167896215121185
+          13372821229356207590
         ]
       ], 
       "reviewed-by-human": true
@@ -13765,13 +13965,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11699606127967884853
+          18066188128226642718
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
@@ -13885,10 +14082,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14092660394167221372
+          793571917548606224
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
@@ -14185,7 +14383,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1179874960318751469
+          7861383235576349971
         ]
       ], 
       "reviewed-by-human": true
@@ -14361,6 +14559,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -14389,10 +14596,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
@@ -14422,10 +14630,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16570721013563827642
+          16893666949631983554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -14458,7 +14666,8 @@
           10999541404612369092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_gpu.png": {
       "allowed-digests": [
@@ -14515,7 +14724,8 @@
           6717965895519090324
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_gpu.png": {
       "allowed-digests": [
@@ -14561,9 +14771,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
@@ -14613,7 +14824,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -14670,13 +14881,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13319064646371789115
+          2175335291804019445
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
@@ -14730,7 +14938,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2490573331458469013
+          11439266403004262361
         ]
       ], 
       "ignore-failure": false, 
@@ -14776,7 +14984,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5908852437805895316
         ]
       ], 
       "reviewed-by-human": true
@@ -14902,7 +15110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2777928313170626539
+          2446410806867201529
         ]
       ], 
       "ignore-failure": false, 
@@ -14960,13 +15168,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
@@ -15020,13 +15225,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
@@ -15044,10 +15246,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -15061,6 +15263,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3150156316299090359
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9681310633081179342
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1349309672055368776
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7788637017468019330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_80_angle.png": {
       "allowed-digests": [
         [
@@ -15107,10 +15345,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17080929691634768887
+          12055084226919357366
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
@@ -15164,10 +15403,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7826954068731758433
+          17030759078570309626
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
@@ -15274,13 +15514,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8785170447147063713
+          4135753765908252121
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
@@ -15334,10 +15571,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6046964193895052919
+          17681872747273719749
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
@@ -15383,9 +15621,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3265828289773778069
+          6604468477653477623
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
@@ -15435,10 +15674,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5093669879719766239
+          12726014549462824316
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
@@ -15463,6 +15703,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10591909693224673086
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug-DirectWrite/expected-results.json b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug-DirectWrite/expected-results.json
index a2907b2..1ad9e68 100644
--- a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug-DirectWrite/expected-results.json
+++ b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug-DirectWrite/expected-results.json
@@ -112,10 +112,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10879622672299268205
+          12831307062174214826
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -226,28 +227,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9370787683929398146
+          8386050591090575061
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15339685398252053165
+          17119504700677749589
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1137110444666174739
+          16786896836766143161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -300,48 +304,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10573214378214332517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -460,10 +422,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2944061319698975510
+          14822676243771102497
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -614,28 +576,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12405270661687912953
+          13314899585272765728
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11173906150143499164
+          3534768579781843121
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          386061514299605512
+          6658400916517904289
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -653,7 +618,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8868465328584970059
+          12030291790142951562
         ]
       ], 
       "ignore-failure": false, 
@@ -663,7 +628,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2050148903307452592
+          2328990479460076921
         ]
       ], 
       "ignore-failure": false, 
@@ -673,7 +638,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12646107109970106955
+          7666464896359988018
         ]
       ], 
       "ignore-failure": false, 
@@ -963,10 +928,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9337838425513581101
+          12195310936180436782
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -2464,6 +2432,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12424138734353506606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -2795,10 +2790,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4626344487553497677
+          7048546964514197209
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -2809,6 +2804,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          636195428699273093
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2849,28 +2871,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5759032192978176963
+          8885827664842700271
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11865018114051956745
+          12764966007571970378
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16253612354061260592
+          16038422283720293399
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -3584,10 +3609,7 @@
           660002910751114028
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3692,31 +3714,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10674445246146571014
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10475544940395894106
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6690373756982300464
+          7760022190728266716
         ]
       ], 
       "reviewed-by-human": true
@@ -3965,7 +3981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3111584286530470921
+          2931817475980821997
         ]
       ], 
       "ignore-failure": false, 
@@ -3975,7 +3991,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2389886074356873914
+          5185842740431793908
         ]
       ], 
       "ignore-failure": false, 
@@ -3985,7 +4001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4806894783935148622
+          10990887139037962924
         ]
       ], 
       "reviewed-by-human": true
@@ -3994,7 +4010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          466694581017578405
+          14177391063005797992
         ]
       ], 
       "ignore-failure": false, 
@@ -4004,7 +4020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7262732955128363425
+          6823565356147184210
         ]
       ], 
       "ignore-failure": false, 
@@ -4014,7 +4030,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8645462464069482295
+          11767564415406014631
         ]
       ], 
       "reviewed-by-human": true
@@ -4047,7 +4063,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8160467023327505878
+          18180274608236460762
         ]
       ], 
       "ignore-failure": false, 
@@ -4057,7 +4073,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15560833469838583085
+          7774541298746974882
         ]
       ], 
       "ignore-failure": false, 
@@ -4067,7 +4083,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16933664667764098877
+          343773841046282683
         ]
       ], 
       "reviewed-by-human": true
@@ -4076,7 +4092,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17997826664435491287
+          13640252250101891066
         ]
       ], 
       "ignore-failure": false, 
@@ -4086,7 +4102,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1338557485273368876
+          3113239910847922849
         ]
       ], 
       "ignore-failure": false, 
@@ -4096,7 +4112,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7069319741280458117
+          4491023457741351309
         ]
       ], 
       "reviewed-by-human": true
@@ -4201,7 +4217,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          892670307169065083
+          4604486586531253956
         ]
       ], 
       "reviewed-by-human": true
@@ -4210,7 +4226,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2045428650102255005
+          2051802506720253599
         ]
       ], 
       "reviewed-by-human": true
@@ -4219,7 +4235,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5469030517403717728
+          964167756699231217
         ]
       ], 
       "reviewed-by-human": true
@@ -4330,28 +4346,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10229835032130991608
+          6863972292267418469
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8557264136300127266
+          10364599796573376762
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          561775685874046243
+          7898840088714420125
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4369,28 +4388,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1947033099431075157
+          4658655007649634701
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4337268315472364028
+          18036292203388148817
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8953408673606432250
+          9317020945793047069
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4606,28 +4628,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5037191661353682037
+          15590002593583735483
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1459244195044373587
+          16969415686637953721
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4997994672252257554
+          15175995861819667151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -4645,7 +4670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4574532664855445266
+          11007951012846856042
         ]
       ], 
       "ignore-failure": false, 
@@ -4655,7 +4680,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16627899931991709843
+          1357781408314308336
         ]
       ], 
       "ignore-failure": false, 
@@ -4665,7 +4690,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16627899931991709843
+          1357781408314308336
         ]
       ], 
       "ignore-failure": false, 
@@ -4693,28 +4718,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12360310496788002201
+          5311592490631599434
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9009790187657699292
+          5546602314850585745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11818783730454982289
+          2937206974579924892
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -4732,37 +4760,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -5295,10 +5314,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10303810140172040904
+          11482296602351535562
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5316,28 +5336,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12742254379011527697
+          4623834158998477445
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9726486919602113469
+          8360698665239233312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9540502248948568122
+          16553053007513863215
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5355,28 +5378,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          539087815038847069
+          10014106509042438342
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12704004861477258789
+          1912712104834108856
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4694564845177125499
+          14666226782194455577
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5462,28 +5488,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8388090760290606396
+          2183732814993705842
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16872985054846188577
+          14083194632819813968
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15570922757582072529
+          6619271459357894670
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6336,6 +6365,33 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13417891009993581964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13417891009993581964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13417891009993581964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -6352,67 +6408,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2438765299806098068
+          17177797826902908900
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16133775448912321248
+          12727560363135530973
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2438765299806098068
+          17177797826902908900
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16133775448912321248
+          12727560363135530973
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14620265942826601396
+          10433897477521617665
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14620265942826601396
+          10433897477521617665
         ]
       ], 
       "ignore-failure": true, 
@@ -6470,7 +6511,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11660485744537268700
+          2124588341689625752
         ]
       ], 
       "ignore-failure": false, 
@@ -6480,7 +6521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8075785474404249341
+          8295720945662111046
         ]
       ], 
       "ignore-failure": false, 
@@ -6490,7 +6531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8231607849705352156
+          3761726957027384064
         ]
       ], 
       "ignore-failure": false, 
@@ -6512,28 +6553,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7013888080494554933
+          13800984280135952333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9212520228583611491
+          2529985197633194300
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16521960960612022739
+          1481537360072784758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -6551,31 +6595,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9531067793904115326
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9873701237853697459
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8163306893465264655
+          487156685711148680
         ]
       ], 
       "reviewed-by-human": true
@@ -7114,6 +7152,168 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16867245765576148898
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3996052619796469473
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18359962369733108667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7551,28 +7751,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14524832302197029972
+          4840050909527376172
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10915126794559085124
+          18046380690276657173
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4298566763218358590
+          14241394273706423946
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7645,10 +7848,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13274748155400875756
+          17393768864600460161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -7699,7 +7903,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11632287358738717426
+          5100503083862816328
         ]
       ], 
       "reviewed-by-human": true
@@ -7708,7 +7912,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15464036326509927420
+          5315670865766411029
         ]
       ], 
       "reviewed-by-human": true
@@ -7717,7 +7921,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11039164946908631608
+          18338026403264996017
         ]
       ], 
       "reviewed-by-human": true
@@ -7771,34 +7975,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10959537816936562124
+          5567358773991782197
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6165054369453890576
+          12471740373961346125
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5410478754485738631
+          11888686022754756017
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          639993729203874391
+          14697442244205319783
         ]
       ], 
       "reviewed-by-human": true
@@ -7807,7 +8014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11102915899703956350
+          18044565907096276184
         ]
       ], 
       "reviewed-by-human": true
@@ -7816,7 +8023,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13075313129660290164
+          7044686035558524733
         ]
       ], 
       "reviewed-by-human": true
@@ -7846,25 +8053,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17431620301049520066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5259420383792564443
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15427414520831625993
+          4641014269499037622
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8064,7 +8274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
       ], 
       "reviewed-by-human": true
@@ -8073,7 +8283,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
       ], 
       "reviewed-by-human": true
@@ -8082,9 +8292,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16236721268324357263
+          4596576699457741273
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8098,37 +8309,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16600741938009686069
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          821346083091436619
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8236228376266854287
+          10548005182299770458
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8146,28 +8348,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4819271082682650894
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8311442417738165725
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8311442417738165725
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8182,37 +8384,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12431322744385996416
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10744242484906745791
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11635192793803727488
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8266,28 +8459,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11957481143088684855
+          5413590040608356550
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10623463231700267019
+          6505993221153840547
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10383062109891418930
+          16818718173210917334
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8329,13 +8525,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16271637167989743463
+          7150313580130655353
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -8428,28 +8624,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10545947940358671124
+          10616859326334085691
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12143876096554673110
+          13005892560864159760
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15184660098717765710
+          5843577122150718596
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8467,28 +8666,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973245457801045626
+          14481939058217271046
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5772926797119771265
+          12396256756772939715
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          301604990440380181
+          7493595502744203397
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8524,7 +8726,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17584525476237622529
+          18226744787129433112
         ]
       ], 
       "reviewed-by-human": true
@@ -8575,7 +8777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          126743758999994050
+          11414164107255410557
         ]
       ], 
       "ignore-failure": false, 
@@ -8585,7 +8787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6750115639747842206
+          6702528719621525693
         ]
       ], 
       "ignore-failure": false, 
@@ -8595,10 +8797,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7463425779585516638
+          13361237981546011864
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -8676,7 +8879,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8721,7 +8924,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8766,7 +8969,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8838,13 +9041,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11302360056092717723
+          4273377358399608835
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -9096,25 +9299,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15412489287884551475
+          11593332453638950760
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3177659409539294891
+          565785417218411423
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4162325017686884511
+          16347156219649766987
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9156,13 +9362,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          12848328078440704869
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9542,7 +9748,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -9551,7 +9757,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -9560,12 +9766,39 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13918912246429055687
+          17735883773617287292
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16250745281745965444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -9691,28 +9924,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14613866000180590045
+          6009493504302066276
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9112154987602543605
+          13358913611238803501
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9672017626817765423
+          104273781585409685
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -9766,28 +10002,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10737745884963325809
+          15576488907248411849
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273056267123692872
+          11776299738014423526
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18208821564072678596
+          11767847879379411189
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9805,28 +10044,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12373062268850855118
+          6344407473960729259
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13785070712159670775
+          9813576216999362038
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6853951779022240800
+          16760938805266099790
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9904,10 +10146,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5440525180981761895
+          9571104979652806930
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10338,7 +10581,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8402469330842901625
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -10347,7 +10590,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2818284624000076897
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -10356,7 +10599,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9761855064744478265
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -10377,7 +10620,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          355895795495140690
+          18237938427133021346
         ]
       ], 
       "reviewed-by-human": true
@@ -10386,7 +10629,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13608069052934182065
+          2134703127931704587
         ]
       ], 
       "reviewed-by-human": true
@@ -10395,7 +10638,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8563261825144500497
+          7659748670555812121
         ]
       ], 
       "reviewed-by-human": true
@@ -10416,7 +10659,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2872689351489933799
+          9228469833437167668
         ]
       ], 
       "reviewed-by-human": true
@@ -10425,7 +10668,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10434494122342737744
+          17250454159117352933
         ]
       ], 
       "reviewed-by-human": true
@@ -10434,7 +10677,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4295161658641647793
+          7261720940549232078
         ]
       ], 
       "reviewed-by-human": true
@@ -10443,7 +10686,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12722166574620502982
+          16342024067941080851
         ]
       ], 
       "reviewed-by-human": true
@@ -10452,7 +10695,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18355814165005862692
+          17317072924787566080
         ]
       ], 
       "reviewed-by-human": true
@@ -10461,7 +10704,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5535804529377953328
+          12101886556041102559
         ]
       ], 
       "reviewed-by-human": true
@@ -10629,7 +10872,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16416838050714920080
+          16393968203105861983
         ]
       ], 
       "reviewed-by-human": true
@@ -10638,7 +10881,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2659266311643653911
+          12692320183870247864
         ]
       ], 
       "reviewed-by-human": true
@@ -10697,7 +10940,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6498061702190355571
+          15166740142850249140
         ]
       ], 
       "ignore-failure": false, 
@@ -10707,7 +10950,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15713939700559521401
+          7911974576054616569
         ]
       ], 
       "ignore-failure": false, 
@@ -10717,7 +10960,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14127006905311928300
+          15759781880810789448
         ]
       ], 
       "ignore-failure": false, 
@@ -10964,37 +11207,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1566797545260704260
+          8249967000998873336
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6443390981079994389
+          11336103823568541577
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15435478586476187031
+          1438660038977905881
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -11012,28 +11246,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1566797545260704260
+          8249967000998873336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15610290292855764472
+          615326829446859241
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8141860840939642201
+          13391020767722885480
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11051,25 +11288,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1575584161984222124
+          6781554900301524151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2758384836604842295
+          7568063466353017848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7239531933601841272
+          12376246715763899370
         ]
       ], 
       "reviewed-by-human": true
@@ -11210,37 +11449,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13002893509660100613
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6668961177350965185
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9930324128115193643
+          15825828722190913352
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -11303,28 +11533,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17161103720460860537
+          159004473548620887
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12936256772116954852
+          8104410590312662232
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15857981712599323172
+          793571917548606224
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -11540,7 +11773,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10043902679277564783
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -11549,7 +11782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          560241391671542747
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -11558,7 +11791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4473467245062379118
+          5656265252683071823
         ]
       ], 
       "reviewed-by-human": true
@@ -11693,28 +11926,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9405789693101019700
+          9805106273662486358
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8300678802456582769
+          3321267585316102772
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1518591953302236567
+          2207063873455367749
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11819,25 +12055,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6174664833383347560
+          13643462334056680198
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13669553763054499433
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13669553763054499433
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -11855,7 +12094,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8402469330842901625
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -11864,7 +12103,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2818284624000076897
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -11873,7 +12112,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9761855064744478265
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -11894,7 +12133,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          355895795495140690
+          18237938427133021346
         ]
       ], 
       "reviewed-by-human": true
@@ -11903,7 +12142,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13608069052934182065
+          2134703127931704587
         ]
       ], 
       "reviewed-by-human": true
@@ -11912,7 +12151,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8563261825144500497
+          7659748670555812121
         ]
       ], 
       "reviewed-by-human": true
@@ -11933,7 +12172,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7852792503787209328
+          10903574554557130940
         ]
       ], 
       "ignore-failure": false, 
@@ -11943,7 +12182,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8207854083030820942
+          4985017360636277471
         ]
       ], 
       "ignore-failure": false, 
@@ -11953,7 +12192,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1613716011867819554
+          4954472096981762200
         ]
       ], 
       "ignore-failure": false, 
@@ -11963,7 +12202,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12148910523537559005
+          9085173547997942241
         ]
       ], 
       "reviewed-by-human": true
@@ -11972,7 +12211,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15640303705530956159
+          7321105861580014856
         ]
       ], 
       "reviewed-by-human": true
@@ -11981,7 +12220,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5902651983250387614
+          6703295218647016900
         ]
       ], 
       "reviewed-by-human": true
@@ -12053,7 +12292,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14536950363793768591
+          13495792426164432844
         ]
       ], 
       "ignore-failure": false, 
@@ -12063,7 +12302,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7448455245906035564
+          15504021362006183015
         ]
       ], 
       "ignore-failure": false, 
@@ -12073,7 +12312,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          810087598205526141
+          2446410806867201529
         ]
       ], 
       "ignore-failure": false, 
@@ -12095,37 +12334,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11318988853832426203
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3835087014061651858
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9202287982145158388
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -12143,37 +12373,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1585532987875160032
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7930133030757872508
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7930133030757872508
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
@@ -12223,6 +12444,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5701895924183087555
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12300111888349865181
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10382127665747013988
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7870452552399035571
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16846592895652028679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7025230607614396892
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10567700594698864677
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4934037525238326145
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -12299,7 +12628,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7327591005347046543
+          3266324430040340637
         ]
       ], 
       "ignore-failure": false, 
@@ -12309,7 +12638,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13691427943773136574
+          5036001268883781826
         ]
       ], 
       "ignore-failure": false, 
@@ -12319,7 +12648,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12075094618501930853
+          1439418242802718141
         ]
       ], 
       "reviewed-by-human": true
@@ -12340,28 +12669,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10286397624740111412
+          8274208197386934822
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6924954974933988088
+          11832156116308490489
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5831176308157757540
+          1551174895956573184
         ]
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12379,12 +12711,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10950481694600695676
+          6183456328083498663
         ]
       ], 
-      "bugs": [
-        1822
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -12423,28 +12752,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16924304794833816968
+          17298851971445257464
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14709336717565174668
+          14681108931572136865
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15042349468177411621
+          7571665914830278260
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12462,28 +12794,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15503778794712337663
+          16464916071202373983
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15952895491456712438
+          7722978681047038091
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3987827829779115018
+          1745606781345726404
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -12501,25 +12836,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11837740987106354087
+          13335469986208246779
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4361733175295861002
+          5785239134980311524
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13771004439622141780
+          4576794236692228884
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -12537,28 +12875,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12764586552176228609
+          9430581040858116312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15851445661672644545
+          18201622713807911998
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14131904844964275075
+          8538297429821405390
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -12571,6 +12912,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10591909693224673086
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug/expected-results.json b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug/expected-results.json
index 07fa03f..b3ab2d2 100644
--- a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Debug/expected-results.json
@@ -112,10 +112,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10879622672299268205
+          12831307062174214826
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -226,28 +227,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          8386050591090575061
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          17119504700677749589
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6329400057600097234
+          16786896836766143161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -261,6 +265,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -300,48 +331,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10573214378214332517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -460,10 +449,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2944061319698975510
+          14822676243771102497
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -518,37 +507,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          707578552626433941
+          4135526557546616687
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -614,28 +594,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          13314899585272765728
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          3534768579781843121
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          6658400916517904289
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -653,7 +636,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          12030291790142951562
         ]
       ], 
       "ignore-failure": false, 
@@ -663,7 +646,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          2328990479460076921
         ]
       ], 
       "ignore-failure": false, 
@@ -673,7 +656,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669107578763825775
+          7666464896359988018
         ]
       ], 
       "ignore-failure": false, 
@@ -827,28 +810,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -911,15 +897,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
       ], 
       "reviewed-by-human": true
@@ -928,9 +915,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2801325236637973751
+          5281412422904919583
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -963,10 +951,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9337838425513581101
+          12195310936180436782
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -2464,6 +2455,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12424138734353506606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -2777,10 +2795,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4626344487553497677
+          7048546964514197209
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -2791,6 +2809,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          636195428699273093
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2831,28 +2876,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3617424777768145898
+          16038422283720293399
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -2945,34 +2993,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -2990,28 +3033,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8826561316445684686
+          16297948529498506413
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -3536,37 +3582,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          660002910751114028
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3671,31 +3708,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17128498486631460526
+          7760022190728266716
         ]
       ], 
       "reviewed-by-human": true
@@ -3800,10 +3831,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4841496337918692008
+          10208615534534427054
         ]
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "complexclip2_path_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -3926,10 +3958,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7461094591079150540
+          14745371879903012446
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_rrect_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -3944,25 +3976,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          2931817475980821997
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          5185842740431793908
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6493039209837692850
+          10990887139037962924
         ]
       ], 
       "reviewed-by-human": true
@@ -3971,25 +4005,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          14177391063005797992
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          6823565356147184210
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13265855489806029964
+          11767564415406014631
         ]
       ], 
       "reviewed-by-human": true
@@ -4022,25 +4058,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          18180274608236460762
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          7774541298746974882
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15436226578831879472
+          343773841046282683
         ]
       ], 
       "reviewed-by-human": true
@@ -4049,25 +4087,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          13640252250101891066
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          3113239910847922849
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1190962956186333047
+          4491023457741351309
         ]
       ], 
       "reviewed-by-human": true
@@ -4172,7 +4212,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
       "reviewed-by-human": true
@@ -4181,7 +4221,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
       "reviewed-by-human": true
@@ -4190,7 +4230,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          681518688112967286
+          964167756699231217
         ]
       ], 
       "reviewed-by-human": true
@@ -4301,28 +4341,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          6863972292267418469
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          10364599796573376762
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11310385329664314856
+          7898840088714420125
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4340,28 +4383,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4658655007649634701
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          18036292203388148817
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8160232458378510085
+          9317020945793047069
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4586,28 +4632,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          15590002593583735483
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          16969415686637953721
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5375673450726446602
+          15175995861819667151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -4625,28 +4674,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          11007951012846856042
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1357781408314308336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1357781408314308336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -4673,28 +4725,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -4712,37 +4767,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4760,7 +4806,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -4769,7 +4815,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -4778,7 +4824,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12241316569839901585
+          8040800720155301683
         ]
       ], 
       "reviewed-by-human": true
@@ -4799,7 +4845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
       "reviewed-by-human": true
@@ -4808,7 +4854,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
       "reviewed-by-human": true
@@ -4817,13 +4863,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13397371426171817534
+          1281057607739566387
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4841,7 +4884,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
       "reviewed-by-human": true
@@ -4850,7 +4893,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
       "reviewed-by-human": true
@@ -4859,13 +4902,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12241316569839901585
+          8040800720155301683
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4883,7 +4923,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
       "reviewed-by-human": true
@@ -4892,7 +4932,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
       "reviewed-by-human": true
@@ -4901,13 +4941,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7922854781530363105
+          10091200121371913151
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4925,7 +4962,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -4934,7 +4971,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -4943,7 +4980,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1503976714167724830
+          12559198495177059060
         ]
       ], 
       "reviewed-by-human": true
@@ -4964,7 +5001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
       "reviewed-by-human": true
@@ -4973,7 +5010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
       "reviewed-by-human": true
@@ -4982,13 +5019,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12388921334436224745
+          3850207957964943776
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5006,7 +5040,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
       "reviewed-by-human": true
@@ -5015,7 +5049,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
       "reviewed-by-human": true
@@ -5024,13 +5058,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1503976714167724830
+          12559198495177059060
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5048,7 +5079,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
       "reviewed-by-human": true
@@ -5057,7 +5088,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
       "reviewed-by-human": true
@@ -5066,13 +5097,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12965470470056135172
+          10440591076012582303
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5090,7 +5118,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -5099,7 +5127,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -5108,7 +5136,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2141019891928343978
+          10951953396077624358
         ]
       ], 
       "reviewed-by-human": true
@@ -5129,7 +5157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
       "reviewed-by-human": true
@@ -5138,7 +5166,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
       "reviewed-by-human": true
@@ -5147,13 +5175,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17351323733553391924
+          17521327519243435949
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5171,7 +5196,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
       "reviewed-by-human": true
@@ -5180,7 +5205,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
       "reviewed-by-human": true
@@ -5189,13 +5214,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2141019891928343978
+          10951953396077624358
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5213,7 +5235,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
       "reviewed-by-human": true
@@ -5222,7 +5244,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
       "reviewed-by-human": true
@@ -5231,13 +5253,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8546063919377166259
+          9082824586346219222
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5255,7 +5274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
       "ignore-failure": false, 
@@ -5275,10 +5294,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10303810140172040904
+          11482296602351535562
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5296,28 +5316,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          14000810406608195551
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          8360698665239233312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10072750740945871465
+          16553053007513863215
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5335,28 +5358,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13717384973349640095
+          14666226782194455577
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5374,25 +5400,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          652105149337720065
+          13023439110169898341
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -5442,28 +5471,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          2183732814993705842
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          14083194632819813968
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13248443147554810424
+          6619271459357894670
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -5585,6 +5617,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -5802,7 +5861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -5811,7 +5870,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -5839,7 +5898,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -5848,7 +5907,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -5876,7 +5935,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -5885,7 +5944,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -5913,7 +5972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -5922,7 +5981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -5950,7 +6009,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -5959,7 +6018,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -5987,7 +6046,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -5996,7 +6055,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -6024,7 +6083,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -6033,7 +6092,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -6061,7 +6120,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -6070,7 +6129,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -6098,7 +6157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -6107,7 +6166,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -6172,7 +6231,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -6181,7 +6240,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -6209,7 +6268,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
       "reviewed-by-human": true
@@ -6218,7 +6277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
       "reviewed-by-human": true
@@ -6227,7 +6286,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16132206054577275426
+          9014502494028699619
         ]
       ], 
       "reviewed-by-human": true
@@ -6246,7 +6305,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -6255,7 +6314,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -6264,7 +6323,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6571014605016942961
+          10286803221364697801
         ]
       ], 
       "reviewed-by-human": true
@@ -6283,7 +6342,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6865564636648157250
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -6292,7 +6351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9256179289443217715
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -6301,7 +6360,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3112939118667482752
+          5125823501637387350
         ]
       ], 
       "reviewed-by-human": true
@@ -6316,83 +6375,92 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11987204656394981007
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11172256210463001362
+          15720178186502724169
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8235727908523200854
+          14818252557016116600
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12300505832476339318
+          16507136324562418008
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9634328461383126524
+          14818252557016116600
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6727685461018676373
+          16507136324562418008
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15532577507744171028
+          6940737243764937510
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2963378280773795200
+          6940737243764937510
         ]
       ], 
       "ignore-failure": true, 
@@ -6402,37 +6470,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          6912355345607947791
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          9115989932432402646
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16666842658661744318
+          6777672133164700613
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -6450,28 +6509,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          2124588341689625752
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          8295720945662111046
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16738047539038188349
+          3761726957027384064
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_pdf-poppler.png": {
       "allowed-digests": [
@@ -6485,32 +6547,62 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6109517714117419633
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3095060401995611617
+          1481537360072784758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -6528,31 +6620,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14350650523048604465
+          487156685711148680
         ]
       ], 
       "reviewed-by-human": true
@@ -7091,6 +7177,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9050243732888826330
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16867245765576148898
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3996052619796469473
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18359962369733108667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12852304057572000016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7122,10 +7424,7 @@
           9898697105564368249
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-poppler.png": {
       "allowed-digests": [
@@ -7489,7 +7788,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -7528,28 +7827,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2328482482999487459
+          9833133577951959237
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7622,10 +7924,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13274748155400875756
+          17393768864600460161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -7676,7 +7979,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          5100503083862816328
         ]
       ], 
       "reviewed-by-human": true
@@ -7685,7 +7988,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          5315670865766411029
         ]
       ], 
       "reviewed-by-human": true
@@ -7694,7 +7997,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15896254500886456697
+          18338026403264996017
         ]
       ], 
       "reviewed-by-human": true
@@ -7744,11 +8047,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11847517854086327634
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          5567358773991782197
         ]
       ], 
       "ignore-failure": false, 
@@ -7758,7 +8088,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          12471740373961346125
         ]
       ], 
       "ignore-failure": false, 
@@ -7768,16 +8098,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9856700641955552351
+          11888686022754756017
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          14697442244205319783
         ]
       ], 
       "reviewed-by-human": true
@@ -7786,7 +8117,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          18044565907096276184
         ]
       ], 
       "reviewed-by-human": true
@@ -7795,7 +8126,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12958440671393733211
+          7044686035558524733
         ]
       ], 
       "reviewed-by-human": true
@@ -7825,25 +8156,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7515396075491109228
+          4641014269499037622
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -7857,28 +8191,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13129455763424501371
+          14770902400313891624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -7965,25 +8302,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1810444454668426072
+          15217122207501330203
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -8001,28 +8341,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18200079507569830870
+          214593100636960333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -8040,7 +8383,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
       ], 
       "reviewed-by-human": true
@@ -8049,7 +8392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
       ], 
       "reviewed-by-human": true
@@ -8058,9 +8401,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16236721268324357263
+          4596576699457741273
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8074,7 +8418,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
       "reviewed-by-human": true
@@ -8083,7 +8427,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
       "reviewed-by-human": true
@@ -8092,13 +8436,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12316458082598669525
+          10548005182299770458
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8116,28 +8457,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8152,37 +8493,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8236,28 +8568,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4182857538588713843
+          16818718173210917334
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8299,13 +8634,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16271637167989743463
+          7150313580130655353
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -8323,28 +8658,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7390396075740049141
+          17747269762102294402
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -8398,28 +8736,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          10616859326334085691
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          13005892560864159760
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8660327948439151591
+          5843577122150718596
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8437,28 +8778,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          14481939058217271046
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          12396256756772939715
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1253279159644460411
+          7493595502744203397
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8476,25 +8820,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          1606938827300604281
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          16065808063166858733
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7139505319228028644
+          18226744787129433112
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8541,16 +8888,17 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
       "ignore-failure": false, 
@@ -8560,10 +8908,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2994579633452577661
+          16144546122411234896
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -8641,7 +8990,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8686,7 +9035,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8731,7 +9080,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8803,13 +9152,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11302360056092717723
+          4273377358399608835
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -8827,28 +9176,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -8862,6 +9214,276 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14168003095232129524
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16174472480972198806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16387431988923787343
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1027612514960788650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9560692921579649405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3585100793314895154
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15407893317880102456
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1841509450334894439
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7478955310715869440
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12825465872317767907
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9061,25 +9683,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9121,13 +9746,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          12848328078440704869
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9180,29 +9805,85 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16458370652639524599
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5260695078479088411
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3618256589512039908
+          4059585779960614622
         ]
       ], 
       "reviewed-by-human": true
@@ -9507,7 +10188,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -9516,7 +10197,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -9525,12 +10206,39 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13918912246429055687
+          17735883773617287292
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16250745281745965444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -9547,25 +10255,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9576,6 +10287,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -9612,6 +10350,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -9656,28 +10421,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          6009493504302066276
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          13358913611238803501
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17849746177518873287
+          104273781585409685
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -9731,28 +10499,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          15576488907248411849
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          11776299738014423526
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13992807470689754488
+          11767847879379411189
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9770,28 +10541,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          6344407473960729259
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          9813576216999362038
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8672103517888678305
+          16760938805266099790
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9869,10 +10643,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5440525180981761895
+          9571104979652806930
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10282,28 +11057,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497038318515454624
+          17752415278946897
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -10321,7 +11099,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -10330,7 +11108,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -10339,7 +11117,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -10360,7 +11138,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
       "reviewed-by-human": true
@@ -10369,7 +11147,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
       "reviewed-by-human": true
@@ -10378,13 +11156,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932682095705715863
+          7659748670555812121
         ]
       ], 
-      "bugs": [
-        1603
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10402,7 +11177,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          9228469833437167668
         ]
       ], 
       "reviewed-by-human": true
@@ -10411,7 +11186,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          17250454159117352933
         ]
       ], 
       "reviewed-by-human": true
@@ -10420,7 +11195,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9379659218927886410
+          7261720940549232078
         ]
       ], 
       "reviewed-by-human": true
@@ -10429,7 +11204,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16342024067941080851
         ]
       ], 
       "reviewed-by-human": true
@@ -10438,7 +11213,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          17317072924787566080
         ]
       ], 
       "reviewed-by-human": true
@@ -10447,7 +11222,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12615277578507098981
+          12101886556041102559
         ]
       ], 
       "reviewed-by-human": true
@@ -10615,7 +11390,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          16393968203105861983
         ]
       ], 
       "reviewed-by-human": true
@@ -10624,7 +11399,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8053365202385311069
+          12692320183870247864
         ]
       ], 
       "reviewed-by-human": true
@@ -10642,7 +11417,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "ignore-failure": false, 
@@ -10652,7 +11427,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "ignore-failure": false, 
@@ -10662,7 +11437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13394212856950326493
+          15279657961859822991
         ]
       ], 
       "reviewed-by-human": true
@@ -10680,7 +11455,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "ignore-failure": false, 
@@ -10690,7 +11465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "ignore-failure": false, 
@@ -10700,7 +11475,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          32030531006027067
+          15759781880810789448
         ]
       ], 
       "ignore-failure": false, 
@@ -10947,37 +11722,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          8249967000998873336
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          11336103823568541577
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6185310100469816433
+          1438660038977905881
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -10995,28 +11761,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          8249967000998873336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          615326829446859241
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12133799822073532931
+          13391020767722885480
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11034,25 +11803,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          6781554900301524151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          7568063466353017848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10868077502519846091
+          12376246715763899370
         ]
       ], 
       "reviewed-by-human": true
@@ -11193,37 +11964,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          248128091148658883
+          15825828722190913352
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -11286,28 +12048,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14861880405767971501
+          159004473548620887
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2172995158306505021
+          8104410590312662232
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14092660394167221372
+          793571917548606224
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -11523,7 +12288,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -11532,7 +12297,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -11541,7 +12306,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12206828883575652405
+          5656265252683071823
         ]
       ], 
       "reviewed-by-human": true
@@ -11672,32 +12437,62 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11715,10 +12510,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16570721013563827642
+          16893666949631983554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -11745,7 +12540,8 @@
           10999541404612369092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11784,7 +12580,8 @@
           6717965895519090324
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11802,25 +12599,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -11838,7 +12638,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -11847,7 +12647,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -11856,7 +12656,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -11877,7 +12677,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
       "reviewed-by-human": true
@@ -11886,7 +12686,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
       "reviewed-by-human": true
@@ -11895,13 +12695,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932682095705715863
+          7659748670555812121
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -11919,7 +12716,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          10903574554557130940
         ]
       ], 
       "ignore-failure": false, 
@@ -11929,7 +12726,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          4985017360636277471
         ]
       ], 
       "ignore-failure": false, 
@@ -11939,7 +12736,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127867708506544979
+          4954472096981762200
         ]
       ], 
       "ignore-failure": false, 
@@ -11949,7 +12746,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          9085173547997942241
         ]
       ], 
       "reviewed-by-human": true
@@ -11958,7 +12755,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          7321105861580014856
         ]
       ], 
       "reviewed-by-human": true
@@ -11967,7 +12764,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18228384523492481373
+          6703295218647016900
         ]
       ], 
       "reviewed-by-human": true
@@ -12039,7 +12836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          13495792426164432844
         ]
       ], 
       "ignore-failure": false, 
@@ -12049,7 +12846,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          15504021362006183015
         ]
       ], 
       "ignore-failure": false, 
@@ -12059,7 +12856,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2777928313170626539
+          2446410806867201529
         ]
       ], 
       "ignore-failure": false, 
@@ -12081,37 +12878,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -12129,64 +12917,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -12209,6 +12988,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5701895924183087555
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12300111888349865181
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10382127665747013988
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7870452552399035571
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16846592895652028679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7025230607614396892
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10567700594698864677
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4934037525238326145
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -12285,31 +13172,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12923408472393428718
+          1439418242802718141
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -12327,28 +13213,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17972597467707082942
+          18290759104797452817
         ]
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12366,12 +13255,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14598676117102408562
+          6183456328083498663
         ]
       ], 
-      "bugs": [
-        1822
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -12410,28 +13296,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12421287546540698026
+          7571665914830278260
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12449,28 +13338,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          16464916071202373983
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          7722978681047038091
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7351962579811010389
+          1745606781345726404
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -12488,25 +13380,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          13335469986208246779
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          5785239134980311524
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3511629606700176049
+          4576794236692228884
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -12524,28 +13419,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          9430581040858116312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          18201622713807911998
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5321738870293124408
+          8538297429821405390
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -12558,6 +13456,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10591909693224673086
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release-ANGLE/expected-results.json b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release-ANGLE/expected-results.json
index c5acaa8..e2db044 100644
--- a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release-ANGLE/expected-results.json
+++ b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release-ANGLE/expected-results.json
@@ -148,10 +148,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1526268471177155551
+          17598662146761915222
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_gpu.png": {
       "allowed-digests": [
@@ -318,10 +319,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6329400057600097234
+          13043841266956948959
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
@@ -347,6 +349,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_angle.png": {
       "allowed-digests": [
         [
@@ -424,66 +435,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          5515466835202955433
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          17527609633242467013
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_angle.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10573214378214332517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10573214378214332517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -608,10 +559,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6890339176809960518
+          7784555326813513893
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigmatrix_565.png": {
       "allowed-digests": [
@@ -699,13 +650,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9285075549510159913
+          12344393715903085582
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
@@ -819,10 +767,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          6658400916517904289
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
@@ -876,10 +825,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15067856232268696933
+          7702289957265438175
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapfilters_gpu.png": {
       "allowed-digests": [
@@ -1113,7 +1063,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6636953761704810781
+          3749700138471010191
         ]
       ], 
       "ignore-failure": false, 
@@ -1193,7 +1143,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          49884881388550458
+          2657634365985855345
         ]
       ], 
       "reviewed-by-human": true
@@ -1228,10 +1178,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7294639324157923250
+          5564289181496146035
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_gpu.png": {
       "allowed-digests": [
@@ -3281,6 +3234,15 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12424138734353506606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -3552,7 +3514,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10988013427224104734
+          12469056507152539419
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3790505575251759681
         ]
       ], 
       "reviewed-by-human": false
@@ -3594,10 +3565,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13287019284984521481
+          10837998485880758642
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
@@ -3747,10 +3719,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
@@ -3804,10 +3777,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5398721390547657273
+          775573788840541761
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
@@ -4509,13 +4483,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          660002910751114028
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
@@ -4686,7 +4657,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17128498486631460526
+          7760022190728266716
         ]
       ], 
       "reviewed-by-human": true
@@ -5010,7 +4981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9058483060047613631
+          16296263294649982832
         ]
       ], 
       "reviewed-by-human": true
@@ -5052,7 +5023,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14533261291613333659
+          6930594261089573842
         ]
       ], 
       "reviewed-by-human": true
@@ -5118,7 +5089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17231147392296689177
+          13646830220341132229
         ]
       ], 
       "reviewed-by-human": true
@@ -5160,7 +5131,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5263345208833070549
+          1683602642474003356
         ]
       ], 
       "reviewed-by-human": true
@@ -5268,7 +5239,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4153150429672455644
+          11323802454873808645
         ]
       ], 
       "reviewed-by-human": true
@@ -5413,7 +5384,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13125632869332727872
+          980265202579587852
         ]
       ], 
       "ignore-failure": false, 
@@ -5471,7 +5442,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17028001984269604559
+          16571742391219299955
         ]
       ], 
       "ignore-failure": false, 
@@ -5675,7 +5646,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1948223754134562857
+          10828679394151128246
         ]
       ], 
       "reviewed-by-human": true
@@ -5767,10 +5738,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15903710117831491594
+          12640422166305242801
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
@@ -5824,10 +5796,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1357781408314308336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
@@ -5890,10 +5863,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
@@ -5947,13 +5921,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
@@ -6007,7 +5978,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8197937578774172307
+          5074057389327471760
         ]
       ], 
       "reviewed-by-human": true
@@ -6061,13 +6032,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18151825792332629539
+          12554309158897513995
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
@@ -6121,7 +6089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8197937578774172307
+          5074057389327471760
         ]
       ], 
       "reviewed-by-human": true
@@ -6178,13 +6146,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17863627234966078184
+          2377348236008994698
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
@@ -6238,7 +6203,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2622242306943640776
+          9281115052846806992
         ]
       ], 
       "reviewed-by-human": true
@@ -6292,13 +6257,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15543119602279131183
+          4221707714960246704
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
@@ -6352,7 +6314,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2622242306943640776
+          9281115052846806992
         ]
       ], 
       "reviewed-by-human": true
@@ -6409,13 +6371,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17606136414045263365
+          17385794784074028214
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
@@ -6469,7 +6428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15827887096973936314
+          5031508746353160829
         ]
       ], 
       "reviewed-by-human": true
@@ -6523,13 +6482,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7939602626345563815
+          7706893206933305485
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
@@ -6583,7 +6539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15827887096973936314
+          5031508746353160829
         ]
       ], 
       "reviewed-by-human": true
@@ -6640,13 +6596,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1271443847717805806
+          9867001988272277110
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
@@ -6700,10 +6653,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10262587862336842078
+          13868366127434680362
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_gpu.png": {
       "allowed-digests": [
@@ -6757,10 +6711,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10072750740945871465
+          16553053007513863215
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
@@ -6814,10 +6769,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13717384973349640095
+          14666226782194455577
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
@@ -6863,9 +6819,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1209493015352084772
+          6269586002134908784
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
@@ -6920,10 +6877,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6448857246475111318
+          12215957626196597172
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
@@ -6985,6 +6943,15 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -7786,7 +7753,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8252495047556495076
+          18109428777592547662
         ]
       ], 
       "reviewed-by-human": true
@@ -7832,7 +7799,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17928075006619754842
+          13062378031799365156
         ]
       ], 
       "reviewed-by-human": true
@@ -7878,7 +7845,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4214729581428645124
+          4650431575315769874
         ]
       ], 
       "reviewed-by-human": true
@@ -7902,17 +7869,23 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13141254399024073210
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_angle.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
@@ -7954,7 +7927,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3080700020968668861
+          7775298570096891696
         ]
       ], 
       "ignore-failure": true, 
@@ -7988,13 +7961,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16100319568123135454
+          7775298570096891696
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
@@ -8049,13 +8019,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          12563966124941755321
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
@@ -8109,10 +8076,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5775802194278023812
+          2383876210829591671
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
@@ -8138,6 +8106,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16334966420230267651
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
@@ -8166,10 +8143,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5632244007594345836
+          7380380359170776688
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
@@ -8223,7 +8201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16749118127216539313
+          10038204505088525800
         ]
       ], 
       "reviewed-by-human": true
@@ -8933,6 +8911,78 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9050243732888826330
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7863480688033981489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7863480688033981489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17081537394391627241
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14705873799684872747
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7863480688033981489
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1599569324088157595
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5858961485035967834
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -8964,10 +9014,7 @@
           12213884113784735929
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_gpu.png": {
       "allowed-digests": [
@@ -9385,10 +9432,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2328482482999487459
+          9833133577951959237
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
@@ -9488,10 +9536,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3558248687285610866
+          8148623670954566533
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hairmodes_gpu.png": {
       "allowed-digests": [
@@ -9590,7 +9639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15896254500886456697
+          18338026403264996017
         ]
       ], 
       "reviewed-by-human": true
@@ -9628,6 +9677,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11847517854086327634
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
@@ -9656,10 +9714,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9856700641955552351
+          11888686022754756017
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
@@ -9695,7 +9754,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12958440671393733211
+          7044686035558524733
         ]
       ], 
       "reviewed-by-human": true
@@ -9741,9 +9800,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7515396075491109228
+          4641014269499037622
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
@@ -9789,10 +9849,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9246209776414716804
+          7613331097292776777
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
@@ -9887,9 +9948,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17887140213824821509
+          3192280854189963519
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
@@ -9939,10 +10001,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18200079507569830870
+          214593100636960333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
@@ -9988,9 +10051,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8048174065831948696
+          17129964158848571576
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
@@ -10036,13 +10100,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12316458082598669525
+          10548005182299770458
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
@@ -10072,10 +10133,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_565.png": {
       "allowed-digests": [
@@ -10105,13 +10166,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
@@ -10222,10 +10280,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
@@ -10279,13 +10338,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16271637167989743463
+          9812993713815487791
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_gpu.png": {
       "allowed-digests": [
@@ -10339,10 +10398,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7390396075740049141
+          17747269762102294402
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
@@ -10405,10 +10465,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8200021215559120818
+          4436921789491969731
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
@@ -10462,10 +10523,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17364323165819274082
+          1230289844649030381
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
@@ -10511,9 +10573,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7139505319228028644
+          5229191514367865056
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
@@ -10600,10 +10663,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          76021802114671408
+          8299715471717602450
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
@@ -10666,7 +10730,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16926225104435755293
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -10720,7 +10784,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16926225104435755293
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -10774,7 +10838,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16926225104435755293
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -10822,7 +10886,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12761674399065406539
+          3719160171581050213
         ]
       ], 
       "reviewed-by-human": true
@@ -10864,13 +10928,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11302360056092717723
+          2992375879142624268
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_gpu.png": {
       "allowed-digests": [
@@ -10924,10 +10988,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
@@ -10953,6 +11018,96 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17287639956046803338
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8850164348354363393
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9121382299391264577
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11695898540945930296
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2845576788353783281
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11211712352447365565
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6388754610233777743
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8396932509075294070
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5815720514657918820
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13123455672052131213
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -11156,9 +11311,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
@@ -11208,13 +11364,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          17352743232213033167
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_gpu.png": {
       "allowed-digests": [
@@ -11297,6 +11453,24 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13184440885036233012
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12714294017370964694
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
@@ -11325,7 +11499,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7576885622105024513
+          5487905569373974848
         ]
       ], 
       "reviewed-by-human": true
@@ -11722,7 +11896,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13918912246429055687
+          17735883773617287292
         ]
       ], 
       "reviewed-by-human": true
@@ -11736,6 +11910,15 @@
       ], 
       "ignore-failure": false
     }, 
+    "perlinnoise_localmatrix_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16250745281745965444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -11768,10 +11951,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
@@ -11781,6 +11964,15 @@
         ]
       ]
     }, 
+    "pictures_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_angle.png": {
       "allowed-digests": [
         [
@@ -11790,6 +11982,15 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -11875,10 +12076,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          762243915147523410
+          15759320443030700079
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
@@ -11941,10 +12143,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17174790409763084733
+          13266574652712721391
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
@@ -11998,10 +12201,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11798651298936594976
+          4607089709845142814
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
@@ -12107,10 +12311,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5440525180981761895
+          15164085309365805708
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_gpu.png": {
       "allowed-digests": [
@@ -12547,10 +12752,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1273169501689516162
+          11023997900504944144
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
@@ -12604,7 +12810,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -12661,13 +12867,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13319064646371789115
+          2175335291804019445
         ]
       ], 
-      "bugs": [
-        1603
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
@@ -12721,7 +12924,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7118242390016568495
+          5882099978049709122
         ]
       ], 
       "reviewed-by-human": true
@@ -12766,7 +12969,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12615277578507098981
+          10535089760215978010
         ]
       ], 
       "reviewed-by-human": true
@@ -12997,7 +13200,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12504534449156720496
+          4461440472871449053
         ]
       ], 
       "reviewed-by-human": true
@@ -13048,7 +13251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          235287745026699518
+          12216133416504143715
         ]
       ], 
       "reviewed-by-human": true
@@ -13099,7 +13302,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15734966135864889540
+          5767367904615292779
         ]
       ], 
       "ignore-failure": false, 
@@ -13454,13 +13657,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219446946103144942
+          2597227467519029948
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
@@ -13514,7 +13714,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12528160347888068703
+          12130054421194224314
         ]
       ], 
       "reviewed-by-human": true
@@ -13571,7 +13771,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8616167896215121185
+          13372821229356207590
         ]
       ], 
       "reviewed-by-human": true
@@ -13765,13 +13965,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11699606127967884853
+          18066188128226642718
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
@@ -13885,10 +14082,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14092660394167221372
+          793571917548606224
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
@@ -14185,7 +14383,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1179874960318751469
+          7861383235576349971
         ]
       ], 
       "reviewed-by-human": true
@@ -14361,6 +14559,15 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
@@ -14389,10 +14596,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
@@ -14422,10 +14630,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16570721013563827642
+          16893666949631983554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -14458,7 +14666,8 @@
           10999541404612369092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_gpu.png": {
       "allowed-digests": [
@@ -14515,7 +14724,8 @@
           6717965895519090324
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_gpu.png": {
       "allowed-digests": [
@@ -14561,9 +14771,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
@@ -14613,7 +14824,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -14670,13 +14881,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13319064646371789115
+          2175335291804019445
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
@@ -14730,7 +14938,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2490573331458469013
+          11439266403004262361
         ]
       ], 
       "ignore-failure": false, 
@@ -14776,7 +14984,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5908852437805895316
         ]
       ], 
       "reviewed-by-human": true
@@ -14902,7 +15110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2777928313170626539
+          2446410806867201529
         ]
       ], 
       "ignore-failure": false, 
@@ -14960,13 +15168,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
@@ -15020,13 +15225,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
@@ -15044,10 +15246,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -15061,6 +15263,42 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3150156316299090359
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9681310633081179342
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1349309672055368776
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7788637017468019330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_80_angle.png": {
       "allowed-digests": [
         [
@@ -15107,10 +15345,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17080929691634768887
+          12055084226919357366
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
@@ -15164,10 +15403,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7826954068731758433
+          17030759078570309626
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
@@ -15266,13 +15506,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8785170447147063713
+          4135753765908252121
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
@@ -15326,10 +15563,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6046964193895052919
+          17681872747273719749
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
@@ -15375,9 +15613,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3265828289773778069
+          6604468477653477623
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
@@ -15427,10 +15666,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5093669879719766239
+          12726014549462824316
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
@@ -15455,6 +15695,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_angle.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10591909693224673086
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite/expected-results.json b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite/expected-results.json
index e62d258..a8e4745 100644
--- a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite/expected-results.json
+++ b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite/expected-results.json
@@ -112,10 +112,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10879622672299268205
+          12831307062174214826
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -226,28 +227,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9370787683929398146
+          8386050591090575061
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15339685398252053165
+          17119504700677749589
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1137110444666174739
+          16786896836766143161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -300,48 +304,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10573214378214332517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -460,10 +422,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2944061319698975510
+          14822676243771102497
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -614,28 +576,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12405270661687912953
+          13314899585272765728
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11173906150143499164
+          3534768579781843121
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          386061514299605512
+          6658400916517904289
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -653,7 +618,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8868465328584970059
+          12030291790142951562
         ]
       ], 
       "ignore-failure": false, 
@@ -663,7 +628,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2050148903307452592
+          2328990479460076921
         ]
       ], 
       "ignore-failure": false, 
@@ -673,7 +638,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12646107109970106955
+          7666464896359988018
         ]
       ], 
       "ignore-failure": false, 
@@ -963,10 +928,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9337838425513581101
+          12195310936180436782
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -2464,6 +2432,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12424138734353506606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -2795,10 +2790,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4626344487553497677
+          7048546964514197209
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -2809,6 +2804,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          636195428699273093
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2849,28 +2871,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5759032192978176963
+          8885827664842700271
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11865018114051956745
+          12764966007571970378
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16253612354061260592
+          16038422283720293399
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -3584,10 +3609,7 @@
           660002910751114028
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3692,7 +3714,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10674445246146571014
+          16754938408236949132
         ]
       ], 
       "reviewed-by-human": true
@@ -3701,7 +3723,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10475544940395894106
+          7760022190728266716
         ]
       ], 
       "reviewed-by-human": true
@@ -3710,7 +3732,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6690373756982300464
+          7760022190728266716
         ]
       ], 
       "reviewed-by-human": true
@@ -3959,7 +3981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3111584286530470921
+          2931817475980821997
         ]
       ], 
       "ignore-failure": false, 
@@ -3969,7 +3991,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2389886074356873914
+          5185842740431793908
         ]
       ], 
       "ignore-failure": false, 
@@ -3979,7 +4001,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4806894783935148622
+          10990887139037962924
         ]
       ], 
       "reviewed-by-human": true
@@ -3988,7 +4010,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          466694581017578405
+          14177391063005797992
         ]
       ], 
       "ignore-failure": false, 
@@ -3998,7 +4020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7262732955128363425
+          6823565356147184210
         ]
       ], 
       "ignore-failure": false, 
@@ -4008,7 +4030,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8645462464069482295
+          11767564415406014631
         ]
       ], 
       "reviewed-by-human": true
@@ -4041,7 +4063,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8160467023327505878
+          18180274608236460762
         ]
       ], 
       "ignore-failure": false, 
@@ -4051,7 +4073,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15560833469838583085
+          7774541298746974882
         ]
       ], 
       "ignore-failure": false, 
@@ -4061,7 +4083,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16933664667764098877
+          343773841046282683
         ]
       ], 
       "reviewed-by-human": true
@@ -4070,7 +4092,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17997826664435491287
+          13640252250101891066
         ]
       ], 
       "ignore-failure": false, 
@@ -4080,7 +4102,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1338557485273368876
+          3113239910847922849
         ]
       ], 
       "ignore-failure": false, 
@@ -4090,7 +4112,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7069319741280458117
+          4491023457741351309
         ]
       ], 
       "reviewed-by-human": true
@@ -4195,7 +4217,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          892670307169065083
+          4604486586531253956
         ]
       ], 
       "reviewed-by-human": true
@@ -4204,7 +4226,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2045428650102255005
+          2051802506720253599
         ]
       ], 
       "reviewed-by-human": true
@@ -4213,7 +4235,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5469030517403717728
+          964167756699231217
         ]
       ], 
       "reviewed-by-human": true
@@ -4324,28 +4346,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10229835032130991608
+          6863972292267418469
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8557264136300127266
+          10364599796573376762
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          561775685874046243
+          7898840088714420125
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4363,28 +4388,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1947033099431075157
+          4658655007649634701
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4337268315472364028
+          18036292203388148817
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8953408673606432250
+          9317020945793047069
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4600,28 +4628,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5037191661353682037
+          15590002593583735483
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1459244195044373587
+          16969415686637953721
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4997994672252257554
+          15175995861819667151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -4639,7 +4670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4574532664855445266
+          11007951012846856042
         ]
       ], 
       "ignore-failure": false, 
@@ -4649,7 +4680,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16627899931991709843
+          1357781408314308336
         ]
       ], 
       "ignore-failure": false, 
@@ -4659,7 +4690,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16627899931991709843
+          1357781408314308336
         ]
       ], 
       "ignore-failure": false, 
@@ -4687,28 +4718,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12360310496788002201
+          5311592490631599434
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9009790187657699292
+          5546602314850585745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11818783730454982289
+          2937206974579924892
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -4726,37 +4760,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -5289,10 +5314,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10303810140172040904
+          11482296602351535562
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5310,28 +5336,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12742254379011527697
+          4623834158998477445
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9726486919602113469
+          8360698665239233312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9540502248948568122
+          16553053007513863215
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5349,28 +5378,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          539087815038847069
+          10014106509042438342
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12704004861477258789
+          1912712104834108856
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4694564845177125499
+          14666226782194455577
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5456,28 +5488,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8388090760290606396
+          2183732814993705842
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16872985054846188577
+          14083194632819813968
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15570922757582072529
+          6619271459357894670
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6330,6 +6365,33 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13417891009993581964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13417891009993581964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13417891009993581964
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
@@ -6346,67 +6408,52 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2438765299806098068
+          17177797826902908900
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16133775448912321248
+          12727560363135530973
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2438765299806098068
+          17177797826902908900
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16133775448912321248
+          12727560363135530973
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14620265942826601396
+          10433897477521617665
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14620265942826601396
+          10433897477521617665
         ]
       ], 
       "ignore-failure": true, 
@@ -6464,7 +6511,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11660485744537268700
+          2124588341689625752
         ]
       ], 
       "ignore-failure": false, 
@@ -6474,7 +6521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8075785474404249341
+          8295720945662111046
         ]
       ], 
       "ignore-failure": false, 
@@ -6484,7 +6531,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8231607849705352156
+          3761726957027384064
         ]
       ], 
       "ignore-failure": false, 
@@ -6506,28 +6553,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7013888080494554933
+          13800984280135952333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9212520228583611491
+          2529985197633194300
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16521960960612022739
+          1481537360072784758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -6545,31 +6595,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9531067793904115326
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9873701237853697459
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8163306893465264655
+          487156685711148680
         ]
       ], 
       "reviewed-by-human": true
@@ -7108,6 +7152,168 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16867245765576148898
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3996052619796469473
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18359962369733108667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7545,28 +7751,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14524832302197029972
+          4840050909527376172
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10915126794559085124
+          18046380690276657173
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4298566763218358590
+          14241394273706423946
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7639,10 +7848,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13274748155400875756
+          17393768864600460161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -7693,7 +7903,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11632287358738717426
+          5100503083862816328
         ]
       ], 
       "reviewed-by-human": true
@@ -7702,7 +7912,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15464036326509927420
+          5315670865766411029
         ]
       ], 
       "reviewed-by-human": true
@@ -7711,7 +7921,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11039164946908631608
+          18338026403264996017
         ]
       ], 
       "reviewed-by-human": true
@@ -7765,34 +7975,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10959537816936562124
+          5567358773991782197
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6165054369453890576
+          12471740373961346125
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5410478754485738631
+          11888686022754756017
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          639993729203874391
+          14697442244205319783
         ]
       ], 
       "reviewed-by-human": true
@@ -7801,7 +8014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11102915899703956350
+          18044565907096276184
         ]
       ], 
       "reviewed-by-human": true
@@ -7810,7 +8023,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13075313129660290164
+          7044686035558524733
         ]
       ], 
       "reviewed-by-human": true
@@ -7840,25 +8053,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17431620301049520066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5259420383792564443
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15427414520831625993
+          4641014269499037622
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8058,7 +8274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
       ], 
       "reviewed-by-human": true
@@ -8067,7 +8283,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
       ], 
       "reviewed-by-human": true
@@ -8076,9 +8292,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16236721268324357263
+          4596576699457741273
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8092,37 +8309,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16600741938009686069
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          821346083091436619
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8236228376266854287
+          10548005182299770458
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8140,28 +8348,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4819271082682650894
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8311442417738165725
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8311442417738165725
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8176,37 +8384,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12431322744385996416
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10744242484906745791
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11635192793803727488
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8260,28 +8459,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11957481143088684855
+          5413590040608356550
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10623463231700267019
+          6505993221153840547
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10383062109891418930
+          16818718173210917334
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8323,13 +8525,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16271637167989743463
+          7150313580130655353
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -8422,28 +8624,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10545947940358671124
+          10616859326334085691
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12143876096554673110
+          13005892560864159760
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15184660098717765710
+          5843577122150718596
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8461,28 +8666,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973245457801045626
+          14481939058217271046
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5772926797119771265
+          12396256756772939715
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          301604990440380181
+          7493595502744203397
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8518,7 +8726,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17584525476237622529
+          18226744787129433112
         ]
       ], 
       "reviewed-by-human": true
@@ -8569,7 +8777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          126743758999994050
+          11414164107255410557
         ]
       ], 
       "ignore-failure": false, 
@@ -8579,7 +8787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6750115639747842206
+          6702528719621525693
         ]
       ], 
       "ignore-failure": false, 
@@ -8589,10 +8797,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7463425779585516638
+          13361237981546011864
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -8670,7 +8879,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8715,7 +8924,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8760,7 +8969,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8832,13 +9041,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11302360056092717723
+          4273377358399608835
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -9090,25 +9299,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15412489287884551475
+          11593332453638950760
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3177659409539294891
+          565785417218411423
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4162325017686884511
+          16347156219649766987
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9150,13 +9362,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          12848328078440704869
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9536,7 +9748,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -9545,7 +9757,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -9554,12 +9766,39 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13918912246429055687
+          17735883773617287292
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16250745281745965444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -9685,28 +9924,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14613866000180590045
+          6009493504302066276
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9112154987602543605
+          13358913611238803501
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9672017626817765423
+          104273781585409685
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -9760,28 +10002,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10737745884963325809
+          15576488907248411849
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273056267123692872
+          11776299738014423526
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18208821564072678596
+          11767847879379411189
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9799,28 +10044,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12373062268850855118
+          6344407473960729259
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13785070712159670775
+          9813576216999362038
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6853951779022240800
+          16760938805266099790
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9898,10 +10146,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5440525180981761895
+          9571104979652806930
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10333,7 +10582,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8402469330842901625
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -10342,7 +10591,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2818284624000076897
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -10351,7 +10600,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9761855064744478265
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -10372,7 +10621,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          355895795495140690
+          18237938427133021346
         ]
       ], 
       "reviewed-by-human": true
@@ -10381,7 +10630,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13608069052934182065
+          2134703127931704587
         ]
       ], 
       "reviewed-by-human": true
@@ -10390,7 +10639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8563261825144500497
+          7659748670555812121
         ]
       ], 
       "reviewed-by-human": true
@@ -10411,7 +10660,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2872689351489933799
+          9228469833437167668
         ]
       ], 
       "reviewed-by-human": true
@@ -10420,7 +10669,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10434494122342737744
+          17250454159117352933
         ]
       ], 
       "reviewed-by-human": true
@@ -10429,7 +10678,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4295161658641647793
+          7261720940549232078
         ]
       ], 
       "reviewed-by-human": true
@@ -10438,7 +10687,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12722166574620502982
+          16342024067941080851
         ]
       ], 
       "reviewed-by-human": true
@@ -10447,7 +10696,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18355814165005862692
+          17317072924787566080
         ]
       ], 
       "reviewed-by-human": true
@@ -10456,7 +10705,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5535804529377953328
+          12101886556041102559
         ]
       ], 
       "reviewed-by-human": true
@@ -10624,7 +10873,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16416838050714920080
+          16393968203105861983
         ]
       ], 
       "reviewed-by-human": true
@@ -10633,7 +10882,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2659266311643653911
+          12692320183870247864
         ]
       ], 
       "reviewed-by-human": true
@@ -10692,7 +10941,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6498061702190355571
+          15166740142850249140
         ]
       ], 
       "ignore-failure": false, 
@@ -10702,7 +10951,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15713939700559521401
+          7911974576054616569
         ]
       ], 
       "ignore-failure": false, 
@@ -10712,7 +10961,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14127006905311928300
+          15759781880810789448
         ]
       ], 
       "ignore-failure": false, 
@@ -10959,37 +11208,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1566797545260704260
+          8249967000998873336
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6443390981079994389
+          11336103823568541577
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15435478586476187031
+          1438660038977905881
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -11007,28 +11247,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1566797545260704260
+          8249967000998873336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15610290292855764472
+          615326829446859241
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8141860840939642201
+          13391020767722885480
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11046,25 +11289,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1575584161984222124
+          6781554900301524151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2758384836604842295
+          7568063466353017848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7239531933601841272
+          12376246715763899370
         ]
       ], 
       "reviewed-by-human": true
@@ -11205,37 +11450,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13002893509660100613
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6668961177350965185
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9930324128115193643
+          15825828722190913352
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -11298,28 +11534,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17161103720460860537
+          159004473548620887
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12936256772116954852
+          8104410590312662232
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15857981712599323172
+          793571917548606224
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -11535,7 +11774,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10043902679277564783
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -11544,7 +11783,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          560241391671542747
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -11553,7 +11792,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4473467245062379118
+          5656265252683071823
         ]
       ], 
       "reviewed-by-human": true
@@ -11688,28 +11927,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9405789693101019700
+          9805106273662486358
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8300678802456582769
+          3321267585316102772
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1518591953302236567
+          2207063873455367749
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11814,25 +12056,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6174664833383347560
+          13643462334056680198
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13669553763054499433
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13669553763054499433
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -11850,7 +12095,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8402469330842901625
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -11859,7 +12104,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2818284624000076897
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -11868,7 +12113,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9761855064744478265
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -11889,7 +12134,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          355895795495140690
+          18237938427133021346
         ]
       ], 
       "reviewed-by-human": true
@@ -11898,7 +12143,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13608069052934182065
+          2134703127931704587
         ]
       ], 
       "reviewed-by-human": true
@@ -11907,7 +12152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8563261825144500497
+          7659748670555812121
         ]
       ], 
       "reviewed-by-human": true
@@ -11928,7 +12173,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7852792503787209328
+          10903574554557130940
         ]
       ], 
       "ignore-failure": false, 
@@ -11938,7 +12183,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8207854083030820942
+          4985017360636277471
         ]
       ], 
       "ignore-failure": false, 
@@ -11948,7 +12193,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1613716011867819554
+          4954472096981762200
         ]
       ], 
       "ignore-failure": false, 
@@ -11958,7 +12203,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12148910523537559005
+          9085173547997942241
         ]
       ], 
       "reviewed-by-human": true
@@ -11967,7 +12212,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15640303705530956159
+          7321105861580014856
         ]
       ], 
       "reviewed-by-human": true
@@ -11976,7 +12221,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5902651983250387614
+          6703295218647016900
         ]
       ], 
       "reviewed-by-human": true
@@ -12048,7 +12293,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14536950363793768591
+          13495792426164432844
         ]
       ], 
       "ignore-failure": false, 
@@ -12058,7 +12303,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7448455245906035564
+          15504021362006183015
         ]
       ], 
       "ignore-failure": false, 
@@ -12068,7 +12313,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          810087598205526141
+          2446410806867201529
         ]
       ], 
       "ignore-failure": false, 
@@ -12090,37 +12335,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11318988853832426203
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3835087014061651858
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9202287982145158388
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -12138,37 +12374,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1585532987875160032
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7930133030757872508
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7930133030757872508
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
@@ -12218,6 +12445,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5701895924183087555
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12300111888349865181
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10382127665747013988
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7870452552399035571
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16846592895652028679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7025230607614396892
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10567700594698864677
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4934037525238326145
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -12294,7 +12629,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7327591005347046543
+          3266324430040340637
         ]
       ], 
       "ignore-failure": false, 
@@ -12304,7 +12639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13691427943773136574
+          5036001268883781826
         ]
       ], 
       "ignore-failure": false, 
@@ -12314,7 +12649,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12075094618501930853
+          1439418242802718141
         ]
       ], 
       "reviewed-by-human": true
@@ -12335,28 +12670,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10286397624740111412
+          8274208197386934822
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6924954974933988088
+          11832156116308490489
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5831176308157757540
+          1551174895956573184
         ]
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12410,28 +12748,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16924304794833816968
+          17298851971445257464
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14709336717565174668
+          14681108931572136865
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15042349468177411621
+          7571665914830278260
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12449,28 +12790,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15503778794712337663
+          16464916071202373983
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15952895491456712438
+          7722978681047038091
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3987827829779115018
+          1745606781345726404
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -12488,25 +12832,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11837740987106354087
+          13335469986208246779
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4361733175295861002
+          5785239134980311524
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13771004439622141780
+          4576794236692228884
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -12524,28 +12871,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12764586552176228609
+          9430581040858116312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15851445661672644545
+          18201622713807911998
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14131904844964275075
+          8538297429821405390
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -12558,6 +12908,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10591909693224673086
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release/expected-results.json b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release/expected-results.json
index 647757d..5edb926 100644
--- a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release/expected-results.json
+++ b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86-Release/expected-results.json
@@ -106,13 +106,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6558327361272317062
+          4226546152156322054
         ]
       ], 
       "bugs": [
         2146
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -223,7 +223,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8041875314565355903
+          7237272955232499144
         ]
       ], 
       "reviewed-by-human": true
@@ -232,7 +232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13958936906784224568
+          11744617725360039813
         ]
       ], 
       "reviewed-by-human": true
@@ -241,13 +241,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12135992436573664639
+          10587244924467085761
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -261,6 +258,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8170684153031214379
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16366458477471008961
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15881486888956990999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bezier_conic_effects_gpu.png": {
       "allowed-digests": [
         [
@@ -288,48 +312,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10856972031325180110
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          2608489731912387182
-        ]
-      ], 
-      "reviewed-by-human": true
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          8154155218608892427
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13916889568279826355
-        ]
-      ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -514,37 +496,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15144521196064460691
+          5292692606681550577
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          663573232933334381
+          9183532109486734926
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2974709284851643136
+          4400838084077139484
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -610,37 +583,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1090181377780599340
+          13679034522244671328
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9823503639766793576
+          3529106680749454872
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6464039284376821461
+          7839301942759176321
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -658,7 +622,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5181447535751629073
+          16553076980342911342
         ]
       ], 
       "reviewed-by-human": true
@@ -667,7 +631,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4677737304935080193
+          3379491469082806553
         ]
       ], 
       "reviewed-by-human": true
@@ -676,7 +640,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1292392522126344788
+          2602855212189850254
         ]
       ], 
       "reviewed-by-human": true
@@ -829,37 +793,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8309990036210717190
+          7957918354476660039
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1068226879225099686
+          8492456404410173304
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10573095089400585665
+          6469460710477576953
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -916,37 +871,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1731623748405687355
+          14086504487556643501
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18181434794274263009
+          3918580087012657831
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17102914554317403380
+          18358737556949260027
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -2811,6 +2757,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15282610128383086639
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4656965967992186032
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          799562396222102051
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrects_565.png": {
       "allowed-digests": [
         [
@@ -2859,6 +2832,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5907590445712582557
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7640930630514662191
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4742398555810919817
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2911,25 +2911,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11471397093005162371
+          2021240214645806077
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3089736967613501224
+          8083038324566713991
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
@@ -3035,37 +3029,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16467266927122961249
+          5372400953229647581
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16467266927122961249
+          5372400953229647581
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18327771393953674047
+          12390772160528429641
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -3083,37 +3068,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12365040041837338873
+          14248153941601461721
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12365040041837338873
+          14248153941601461721
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2584548940021957998
+          9676471299517522369
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -3368,37 +3344,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10725140447377401753
+          12902758707626816494
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15828201952672770552
+          1673799734172531495
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8520772769676306853
+          4295657416679509254
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3506,7 +3473,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17181297103478458715
+          7232235523527296475
         ]
       ], 
       "reviewed-by-human": true
@@ -3515,7 +3482,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7546727185956980642
+          11064268551446773027
         ]
       ], 
       "reviewed-by-human": true
@@ -3524,7 +3491,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4846573469356373121
+          13483529038568622167
         ]
       ], 
       "reviewed-by-human": true
@@ -3569,13 +3536,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5322076506213727769
+          2234950304049838739
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_path_aa_565.png": {
       "allowed-digests": [
@@ -3650,13 +3614,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9063602190207242061
+          7024591397239428237
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_path_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -3710,7 +3671,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3908297226363946093
+          6438524046114913660
         ]
       ], 
       "bugs": [
@@ -3753,7 +3714,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11042904879899740810
+          16545620039728547520
         ]
       ], 
       "bugs": [
@@ -3802,13 +3763,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7214726488801362480
+          14741022433395837133
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_rrect_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -3826,31 +3784,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1989250226929903114
+          3738234449842126639
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1580321566867304774
+          14286656670148579782
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          128968217831476027
+          7981521648440869379
         ]
       ], 
       "reviewed-by-human": true
@@ -3859,7 +3811,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7436562358458389681
+          4184300989550383160
         ]
       ], 
       "reviewed-by-human": true
@@ -3868,7 +3820,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9285735432678612679
+          13987636093401025295
         ]
       ], 
       "reviewed-by-human": true
@@ -3877,7 +3829,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14695277940854729415
+          8298940877484532115
         ]
       ], 
       "reviewed-by-human": true
@@ -3910,31 +3862,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17594009915663732156
+          1842591632998097069
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11848238473330771214
+          4029727429633374785
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          773940296976001270
+          364192544516833127
         ]
       ], 
       "reviewed-by-human": true
@@ -3943,7 +3889,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11429641238535505234
+          5486183604335303624
         ]
       ], 
       "reviewed-by-human": true
@@ -3952,7 +3898,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4662494297803474070
+          11982295059281291936
         ]
       ], 
       "reviewed-by-human": true
@@ -3961,7 +3907,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8883051521009287885
+          9270542666205568303
         ]
       ], 
       "reviewed-by-human": true
@@ -4066,7 +4012,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13243479656013709126
+          16808363345820852336
         ]
       ], 
       "reviewed-by-human": true
@@ -4075,7 +4021,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6943880756231591243
+          13318984140424053051
         ]
       ], 
       "reviewed-by-human": true
@@ -4084,7 +4030,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14060906485569418880
+          5825367181318112144
         ]
       ], 
       "reviewed-by-human": true
@@ -4156,31 +4102,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5059561327566700951
+          18113556730628307344
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17900448554026277397
+          2788641812614794786
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11899605546047577978
+          11271993072930104485
         ]
       ], 
       "reviewed-by-human": true
@@ -4201,31 +4141,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10960889421198687681
+          431497949273467151
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16633884832255437041
+          10694010244552893353
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12703755685146274553
+          12388119678372730331
         ]
       ], 
       "reviewed-by-human": true
@@ -4428,14 +4362,14 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13624796742030499023
+          5315960437537659710
         ]
       ], 
       "bugs": [
         2331
       ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dashing_pdf-poppler.png": {
       "allowed-digests": [
@@ -4453,7 +4387,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2131008422498531851
+          3856788155670738512
         ]
       ], 
       "reviewed-by-human": true
@@ -4462,7 +4396,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14893283725523134436
+          13277387136813269779
         ]
       ], 
       "reviewed-by-human": true
@@ -4471,7 +4405,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5316686583666650646
+          10819449855272179546
         ]
       ], 
       "reviewed-by-human": true
@@ -4492,7 +4426,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1941780879882993867
+          2620294976559240261
         ]
       ], 
       "reviewed-by-human": true
@@ -4501,7 +4435,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7243161883317753792
+          5779606507775530505
         ]
       ], 
       "reviewed-by-human": true
@@ -4510,13 +4444,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13161358996161327958
+          738438644390168590
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -4543,37 +4474,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15505095057515534539
+          10864592672955962114
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7011776512440361054
+          9588785820896836314
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11119313405188274609
+          253217769819183906
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -4591,37 +4513,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4639,7 +4552,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17739480939119815846
+          11420531008760604954
         ]
       ], 
       "reviewed-by-human": true
@@ -4648,7 +4561,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7465593901867134959
+          8844124908077162564
         ]
       ], 
       "reviewed-by-human": true
@@ -4657,13 +4570,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17698544599922713099
+          10916653587834076749
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_high_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4681,7 +4591,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13451301075256272182
+          1756863595526498318
         ]
       ], 
       "reviewed-by-human": true
@@ -4690,7 +4600,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17858548085504587761
+          4466976346693318554
         ]
       ], 
       "reviewed-by-human": true
@@ -4699,13 +4609,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3442475422000359435
+          9835339280241402985
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4723,7 +4630,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1353882974103153244
+          7405362650064835229
         ]
       ], 
       "reviewed-by-human": true
@@ -4732,7 +4639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10632051688165747819
+          1253885756427199463
         ]
       ], 
       "reviewed-by-human": true
@@ -4741,13 +4648,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17698544599922713099
+          10916653587834076749
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4765,7 +4669,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10513411969606389681
+          6413680629826446471
         ]
       ], 
       "reviewed-by-human": true
@@ -4774,7 +4678,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3321611781518064959
+          2868010501523287951
         ]
       ], 
       "reviewed-by-human": true
@@ -4783,13 +4687,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16254938199163185786
+          5551091250810641741
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4807,7 +4708,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8745145637687143076
+          15020031517474839519
         ]
       ], 
       "reviewed-by-human": true
@@ -4816,7 +4717,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6993918466191937105
+          1893744112014142570
         ]
       ], 
       "reviewed-by-human": true
@@ -4825,13 +4726,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14253810054287287902
+          2366700429543469810
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_high_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -4849,7 +4747,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1914848545928021783
+          17064867224023969737
         ]
       ], 
       "reviewed-by-human": true
@@ -4858,7 +4756,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300750857936102408
+          9435841043516514431
         ]
       ], 
       "reviewed-by-human": true
@@ -4867,13 +4765,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6709102397184686125
+          14541301795607794125
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -4891,7 +4786,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11170386878427065669
+          2213457324951931032
         ]
       ], 
       "reviewed-by-human": true
@@ -4900,7 +4795,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6315838627339454335
+          17967849568983078655
         ]
       ], 
       "reviewed-by-human": true
@@ -4909,13 +4804,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14253810054287287902
+          2366700429543469810
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -4933,7 +4825,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18389776575364855959
+          15046300732641618192
         ]
       ], 
       "reviewed-by-human": true
@@ -4942,7 +4834,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          458539216017402871
+          8935720978078542385
         ]
       ], 
       "reviewed-by-human": true
@@ -4951,13 +4843,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14330203722438404887
+          14113891340736192682
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -4975,7 +4864,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10581476713476745560
+          8901644924895362666
         ]
       ], 
       "reviewed-by-human": true
@@ -4984,7 +4873,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          815895667235287651
+          7429633825632191835
         ]
       ], 
       "reviewed-by-human": true
@@ -4993,13 +4882,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14499175744913418683
+          10496334376605165379
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_high_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5017,7 +4903,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11720661313906605161
+          14803131983301727280
         ]
       ], 
       "reviewed-by-human": true
@@ -5026,7 +4912,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17205632165591007520
+          4420766130136494857
         ]
       ], 
       "reviewed-by-human": true
@@ -5035,13 +4921,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6490399802570347207
+          11146928371095997514
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5059,7 +4942,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17179188525703164235
+          15593501387637210268
         ]
       ], 
       "reviewed-by-human": true
@@ -5068,7 +4951,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11465300977060392578
+          10313286136829543814
         ]
       ], 
       "reviewed-by-human": true
@@ -5077,13 +4960,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14499175744913418683
+          10496334376605165379
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5101,37 +4981,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3622973154032536739
+          8031113373398814993
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1963085877693319546
+          11316776397413354208
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8897234501727444846
+          4640772026513137800
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5149,13 +5020,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          166418574949411105
+          6516220728816158373
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5173,13 +5041,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5131537907885847552
+          618412905295349879
         ]
       ], 
       "bugs": [
         2146
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5210,7 +5078,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13264061492083372916
+          9821299115625388169
         ]
       ], 
       "reviewed-by-human": true
@@ -5232,7 +5100,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5238922412575017132
+          4951660135179851476
         ]
       ], 
       "reviewed-by-human": true
@@ -5241,13 +5109,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2622525443148643029
+          81790018775886512
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5265,37 +5130,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7699067875379372785
+          6683330475999050288
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15484051544224952759
+          6070527399334316626
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6948585840692315512
+          1713740298895854893
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5313,37 +5169,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10958265994833730965
+          12156758254935928614
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11057676932194832086
+          3409427114865193370
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12748979719050203832
+          15424309905151923376
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -5409,31 +5256,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12456703185629425181
+          14849943833165709742
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2050167591072458486
+          2945814439882073677
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3924276303538878085
+          16084166050283192099
         ]
       ], 
       "reviewed-by-human": true
@@ -5561,6 +5402,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13811992109694599488
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7766355001976966235
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13936903658903494972
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -6255,7 +6123,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14033624067322655249
+          13379039103269012557
         ]
       ], 
       "reviewed-by-human": true
@@ -6264,7 +6132,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9497297541995146142
+          14981181897697686396
         ]
       ], 
       "reviewed-by-human": true
@@ -6273,13 +6141,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11498976540758131488
+          17175176344884448693
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6297,7 +6162,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14300735994806958835
+          7231212027317944166
         ]
       ], 
       "reviewed-by-human": true
@@ -6306,7 +6171,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479816607774125111
+          14508653360601919315
         ]
       ], 
       "reviewed-by-human": true
@@ -6315,13 +6180,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12475548526423977295
+          10161192712077498697
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6339,7 +6201,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16620171632220397441
+          10233358161631275388
         ]
       ], 
       "reviewed-by-human": true
@@ -6348,7 +6210,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5684420855743817323
+          4637166976073368318
         ]
       ], 
       "reviewed-by-human": true
@@ -6357,13 +6219,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4761554227373782511
+          13552122419554078129
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6377,23 +6236,47 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2874027724274654954
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15831407821439428991
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5551073885786808573
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3803081951053124139
+          12517246003811618736
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12424910962919445852
+          2800914978112631696
         ]
       ], 
       "reviewed-by-human": true
@@ -6402,7 +6285,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2885108538518881078
+          7683507315585398617
         ]
       ], 
       "reviewed-by-human": true
@@ -6411,7 +6294,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13847035951659720503
+          2800914978112631696
         ]
       ], 
       "reviewed-by-human": true
@@ -6420,7 +6303,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7424479814495399925
+          7683507315585398617
         ]
       ], 
       "reviewed-by-human": true
@@ -6429,7 +6312,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17692907377778721397
+          9363209264984934623
         ]
       ], 
       "reviewed-by-human": true
@@ -6438,43 +6321,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12695617344179013706
+          9363209264984934623
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12588209360960834548
+          4195483612630816496
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18099554134712670127
+          17835196085495965372
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3801390650489419615
+          2003884290311298242
         ]
       ], 
       "reviewed-by-human": true
@@ -6495,7 +6369,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4046935123341543832
+          15244494169241116278
         ]
       ], 
       "reviewed-by-human": true
@@ -6504,7 +6378,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10512006153047295836
+          2414958849468802418
         ]
       ], 
       "reviewed-by-human": true
@@ -6513,7 +6387,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11144265321290126829
+          16495513460694848125
         ]
       ], 
       "reviewed-by-human": true
@@ -6530,11 +6404,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9580179729635925535
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8136774173446564624
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4396837515461665844
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14844455821176607649
+          14521306298491773817
         ]
       ], 
       "reviewed-by-human": true
@@ -6543,7 +6444,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          590295232070368346
+          5390003937757686793
         ]
       ], 
       "reviewed-by-human": true
@@ -6552,7 +6453,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12029230719139333420
+          2302337850265191499
         ]
       ], 
       "reviewed-by-human": true
@@ -6573,31 +6474,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          616799781477038240
+          10872508526418953577
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18332619517088670401
+          10077498490329166410
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10277104407906957887
+          16243013749405519932
         ]
       ], 
       "reviewed-by-human": true
@@ -7157,6 +7052,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13368105708885696768
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16019094586953427942
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11978179071161966570
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8485565368296391663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14475576954260188538
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16907487337938434137
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9636812555333520
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17303456829167600849
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16907487337938434137
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1660008348904381128
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12779330917504210850
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16413276399617183705
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17276525113519411071
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8287426313979811143
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10928449686939574862
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9636812555333520
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17303456829167600849
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16907487337938434137
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7877219412448600517
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8082457506565830220
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2629876541757913106
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17345282381149750301
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15350003933843306879
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15356977387349394600
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7245,7 +7356,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5996967608016708327
+          5082501280123251095
         ]
       ], 
       "reviewed-by-human": true
@@ -7281,7 +7392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5415962064592580525
+          17674638327341573792
         ]
       ], 
       "reviewed-by-human": true
@@ -7317,10 +7428,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10390445521428060386
+          7104710030573429391
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_8888.png": {
       "allowed-digests": [
@@ -7353,7 +7464,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6053720856321646432
+          16586301115230386945
         ]
       ], 
       "reviewed-by-human": true
@@ -7428,7 +7539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7697628586609558485
+          1992179961519751519
         ]
       ], 
       "reviewed-by-human": true
@@ -7503,7 +7614,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          106597733756617188
+          6410023955832745012
         ]
       ], 
       "reviewed-by-human": true
@@ -7554,7 +7665,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8125193860474394657
+          12210303372090663848
         ]
       ], 
       "reviewed-by-human": true
@@ -7593,37 +7704,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3399599745676726224
+          3106724795794061078
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5992126538748202945
+          16973027945240730085
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8002195113902858033
+          17885198737775662917
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7698,7 +7800,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1553160354463395660
+          474901370948379106
         ]
       ], 
       "reviewed-by-human": true
@@ -7749,7 +7851,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2799673041133776516
+          8211738968266339279
         ]
       ], 
       "reviewed-by-human": true
@@ -7758,7 +7860,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9347665569853907289
+          3642351884009361030
         ]
       ], 
       "reviewed-by-human": true
@@ -7767,7 +7869,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16371709412338984557
+          7730176415647470092
         ]
       ], 
       "reviewed-by-human": true
@@ -7826,11 +7928,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1293768704642366273
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7009006462865874165
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1304880608034461754
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          614232838932399841
+          14250307661884197452
         ]
       ], 
       "reviewed-by-human": true
@@ -7839,7 +7968,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6458356707477115216
+          14624717372884486025
         ]
       ], 
       "reviewed-by-human": true
@@ -7848,19 +7977,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8048811343477674178
+          3949604761058720339
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5863213468146730056
+          10429495340026770866
         ]
       ], 
       "reviewed-by-human": true
@@ -7869,7 +7995,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9767349198791655141
+          3636094057523498960
         ]
       ], 
       "reviewed-by-human": true
@@ -7878,13 +8004,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13009338007042307796
+          17507706916724661270
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
@@ -7914,7 +8037,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4445918934299022010
+          14524068702057000950
         ]
       ], 
       "reviewed-by-human": true
@@ -7923,7 +8046,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10789252569287313908
+          14082942030520244168
         ]
       ], 
       "reviewed-by-human": true
@@ -7932,9 +8055,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7641904976704446110
+          2648113187004525884
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -7948,31 +8072,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3789574455780051798
+          1606766433292587129
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7353264041679850013
+          2790369550145406869
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10236234247906467314
+          16913545736601487804
         ]
       ], 
       "reviewed-by-human": true
@@ -7993,15 +8111,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16692102102419719437
+          635979580517379393
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4326203569588991738
+          113002630783446701
         ]
       ], 
       "reviewed-by-human": true
@@ -8010,9 +8129,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4333149094244176860
+          10460422425138382099
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersclipped_pdf-poppler.png": {
       "allowed-digests": [
@@ -8026,19 +8146,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          693130714639849016
+          244555999793481918
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropexpand_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14017620473467015886
+          10497138161379203849
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropexpand_gpu.png": {
       "allowed-digests": [
@@ -8062,7 +8182,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15852310828037040271
+          3749750118650267200
         ]
       ], 
       "reviewed-by-human": true
@@ -8071,7 +8191,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16234788992103634942
+          178973988411389205
         ]
       ], 
       "reviewed-by-human": true
@@ -8080,13 +8200,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8362778457869312061
+          18388166482043280699
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -8104,37 +8221,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6754845991820168214
+          10508610902827253621
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15931492453496604918
+          330729206936883409
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11069665466365777584
+          1298507027794538961
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -8152,7 +8260,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3925356151021679334
+          8414965866494505019
         ]
       ], 
       "reviewed-by-human": true
@@ -8161,7 +8269,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15610725060999386667
+          3408618958648861303
         ]
       ], 
       "reviewed-by-human": true
@@ -8170,7 +8278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1598628677798151441
+          16172727660017045821
         ]
       ], 
       "reviewed-by-human": true
@@ -8187,37 +8295,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5994337649189059376
+          5563667344996973164
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12178866294961771234
+          1845870277236459979
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5919828337528045502
+          14011644356630400111
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8235,7 +8334,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5188454463397160739
+          9532848671817304297
         ]
       ], 
       "reviewed-by-human": true
@@ -8244,7 +8343,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17292807414665803228
+          10951173200287814000
         ]
       ], 
       "reviewed-by-human": true
@@ -8253,13 +8352,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3855832969847973763
+          9451235839094395835
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8277,37 +8373,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16138790657005249955
+          5474721460556102968
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14823022260166512433
+          4500232731537808925
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7499146792320316430
+          8272506706906557119
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8349,7 +8436,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6089012304980605252
+          13045675692080251872
         ]
       ], 
       "reviewed-by-human": true
@@ -8370,37 +8457,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6521104367013565461
+          13147886198633619686
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2399398974291326623
+          1352612543570925448
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12507516108088554005
+          8712567441915556121
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8442,13 +8520,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14382648217710410614
+          4051325077334920598
         ]
       ], 
       "bugs": [
         2146
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -8466,7 +8544,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18259564607875160153
+          16235660250992127025
         ]
       ], 
       "reviewed-by-human": true
@@ -8475,7 +8553,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18036947753238711064
+          7000778575484257136
         ]
       ], 
       "reviewed-by-human": true
@@ -8484,7 +8562,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          359989267416217819
+          2407814723026072713
         ]
       ], 
       "reviewed-by-human": true
@@ -8547,31 +8625,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4636818053341835392
+          9030372963013694072
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4893449160296689477
+          10215782140465432026
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1840565444722518649
+          10959000994535266625
         ]
       ], 
       "reviewed-by-human": true
@@ -8592,31 +8664,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2585278642785283660
+          11854258645508095178
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3383328472061127123
+          16019382768661802332
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12799683944434281829
+          17281493462673776602
         ]
       ], 
       "reviewed-by-human": true
@@ -8637,19 +8703,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10298588630195812345
+          2175275733521269420
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15336342514442025663
+          15355607958109679818
         ]
       ], 
       "reviewed-by-human": true
@@ -8658,7 +8721,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3672259092195863541
+          10572369558235196368
         ]
       ], 
       "reviewed-by-human": true
@@ -8679,7 +8742,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10081243083302436005
+          12294691412074341492
         ]
       ], 
       "reviewed-by-human": true
@@ -8688,7 +8751,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14359173184873173473
+          4859525186662421423
         ]
       ], 
       "reviewed-by-human": true
@@ -8697,7 +8760,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7914499044910747479
+          16957582996835162367
         ]
       ], 
       "reviewed-by-human": true
@@ -8772,12 +8835,9 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18350438646195657329
+          14917261868564924876
         ]
       ], 
-      "bugs": [
-        2359
-      ], 
       "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
@@ -8893,7 +8953,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16048358665979618885
+          5436516912516784614
         ]
       ], 
       "bugs": [
@@ -8924,7 +8984,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11284881185315663337
+          16812502858992843033
         ]
       ], 
       "reviewed-by-human": true
@@ -8945,7 +9005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17889950941935985221
+          4835673321336272632
         ]
       ], 
       "reviewed-by-human": true
@@ -8954,7 +9014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10284117331564645915
+          3698632733842365971
         ]
       ], 
       "reviewed-by-human": true
@@ -8963,13 +9023,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3153047718922766640
+          17258652013351781820
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -8983,6 +9040,276 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15689018233715720907
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4651028785771811911
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12831401510693446774
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11042791709255145961
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1113466441257518623
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12775245600979345958
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3723594597627267588
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3723594597627267588
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11352896660463588372
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10678449739876239835
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10678449739876239835
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14224930356961745548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7686979122220810950
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2439437447858581103
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1967701120591706552
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9121905884121104313
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13505028355991476945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17656255951061248061
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4912614113349642277
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13682248461620974345
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7802953822340933415
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8837771976832019127
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11505812231792381610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8937153707402713768
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4065262632871634405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16750822438192359785
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16063187191518044042
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13334982739298815452
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17840716896300933271
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          575758429787114565
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9176,37 +9503,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13902034132498275794
+          13069475429396433384
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2405769766532653403
+          8079586476986119645
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16874670417176350457
+          14958238030050326789
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9233,13 +9551,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1554322964315256815
+          3686981308882837527
         ]
       ], 
       "bugs": [
         2146
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9292,35 +9610,83 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10117079588519949973
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2857821247781250661
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1581689793735031713
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8958583990006157478
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          86962460989791721
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14065216125948059435
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5033964588183000072
+          4244449970633756739
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11398191060136310090
+          3722177087752173495
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2787035485519891455
+          17631343867087046124
         ]
       ], 
       "reviewed-by-human": true
@@ -9641,7 +10007,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          595364992935238245
+          12880950832309205060
         ]
       ], 
       "reviewed-by-human": true
@@ -9650,7 +10016,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7207055203865857440
+          7400423969593511818
         ]
       ], 
       "reviewed-by-human": true
@@ -9659,11 +10025,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17086878885703116839
+          16269662143957398126
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10572447502045383504
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          480579565243248615
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2850551680970426382
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -9680,37 +10073,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3847976510612018780
+          12717633193854429355
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4774238784771160892
+          412191482567204695
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4774238784771160892
+          412191482567204695
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9724,6 +10108,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12283203511045515689
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          361052193200246518
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          257841325956901629
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -9760,6 +10171,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9257485282316370415
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6963846929111313789
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12398589242603873708
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -9812,31 +10250,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5872999533302894245
+          4617426271087666310
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7138005156595458935
+          17840164419101588331
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10300122544800095763
+          13553646085177152057
         ]
       ], 
       "reviewed-by-human": true
@@ -9896,31 +10328,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17755923123800373467
+          18364281448012856428
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9440689629058151001
+          13896708756344743166
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12776710935195667813
+          18351530641712988579
         ]
       ], 
       "reviewed-by-human": true
@@ -9941,31 +10367,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4785953566037225202
+          11886331910396701114
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3531464746703680976
+          9869312601929862300
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9386861241463205631
+          15105260308295550529
         ]
       ], 
       "reviewed-by-human": true
@@ -10046,7 +10466,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5629453813311250627
+          5031387450270332432
         ]
       ], 
       "reviewed-by-human": true
@@ -10106,25 +10526,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4839773467732437404
+          9784021767788543233
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "resizeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10054666765127394221
+          4058236109834328907
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "resizeimagefilter_gpu.png": {
       "allowed-digests": [
@@ -10463,37 +10877,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11019693300483899275
+          2347041900036355177
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15178713372796081945
+          6600079679864586996
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12476786469577304225
+          6885308062913571352
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -10511,7 +10916,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13684555790539183181
+          4079842783642162678
         ]
       ], 
       "reviewed-by-human": true
@@ -10520,7 +10925,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14587339349100616068
+          6924402771068196086
         ]
       ], 
       "reviewed-by-human": true
@@ -10529,7 +10934,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4845657008892614902
+          4490657881493756635
         ]
       ], 
       "reviewed-by-human": true
@@ -10550,19 +10955,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5690148983251652763
+          9054724363030889537
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6950824879875834417
+          13784032993637985188
         ]
       ], 
       "reviewed-by-human": true
@@ -10571,7 +10973,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12033348890106673917
+          15714576116580958779
         ]
       ], 
       "reviewed-by-human": true
@@ -10736,7 +11138,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16902688729666742253
+          5384772099975601339
         ]
       ], 
       "reviewed-by-human": true
@@ -10745,7 +11147,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9020409907521243523
+          258245350892797530
         ]
       ], 
       "reviewed-by-human": true
@@ -10779,7 +11181,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1406471306745984767
+          14706337511398381332
         ]
       ], 
       "reviewed-by-human": true
@@ -10801,7 +11203,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8011732242532217579
+          5285766050647285113
         ]
       ], 
       "reviewed-by-human": true
@@ -10810,7 +11212,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3157146873642213683
+          6926549500589202128
         ]
       ], 
       "reviewed-by-human": true
@@ -10831,7 +11233,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4094674655400353487
+          6647419173510501574
         ]
       ], 
       "reviewed-by-human": true
@@ -10840,7 +11242,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15164281621008730277
+          4905205277372049553
         ]
       ], 
       "reviewed-by-human": true
@@ -10849,7 +11251,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11565946240507138341
+          5389167625912745339
         ]
       ], 
       "reviewed-by-human": true
@@ -11104,37 +11506,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4857876752094099394
+          3268185963185226931
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          618305338420681310
+          17741711273862641060
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          215936472566145370
+          15644344825352553452
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -11152,37 +11545,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18393656524959493883
+          2065380717407882390
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1197051673605397153
+          9755016252949575899
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9913564289411061437
+          1607410104402857907
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11200,31 +11584,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8858633751615564105
+          15420516170303985953
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11184996226718348764
+          2676010855533224643
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10522879694818406889
+          10412245435925535771
         ]
       ], 
       "reviewed-by-human": true
@@ -11365,37 +11743,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15904685562812477343
+          5114665811133889740
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11916890518456100173
+          13623167137100309594
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15820139673354632826
+          374109213617886566
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -11458,7 +11827,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8926888885120777208
+          7133761308125391722
         ]
       ], 
       "reviewed-by-human": true
@@ -11467,7 +11836,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6986551265466737246
+          89266111179744888
         ]
       ], 
       "reviewed-by-human": true
@@ -11476,13 +11845,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3395505242219313691
+          3273664144381777374
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -11708,7 +12074,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15199225922209494444
+          8476586823553329427
         ]
       ], 
       "reviewed-by-human": true
@@ -11717,7 +12083,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17421561072181138590
+          4248767333297366911
         ]
       ], 
       "reviewed-by-human": true
@@ -11726,7 +12092,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17821670764116704103
+          1369984582239601169
         ]
       ], 
       "reviewed-by-human": true
@@ -11842,11 +12208,38 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7217086530462994228
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15638093138342431956
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6004554306774589861
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2652756554855941986
+          8197028845488493324
         ]
       ], 
       "reviewed-by-human": true
@@ -11855,7 +12248,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15598741866315425710
+          273715184861249836
         ]
       ], 
       "reviewed-by-human": true
@@ -11864,13 +12257,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11356441647026139686
+          252126282987304781
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11888,10 +12278,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16570721013563827642
+          16893666949631983554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -11990,7 +12380,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16842337686959212479
+          7706193739865453226
         ]
       ], 
       "reviewed-by-human": true
@@ -11999,7 +12389,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11092812822290904917
+          10394862522863217811
         ]
       ], 
       "reviewed-by-human": true
@@ -12008,13 +12398,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17697630042508304399
+          1744745764169632336
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12032,7 +12419,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13684555790539183181
+          4079842783642162678
         ]
       ], 
       "reviewed-by-human": true
@@ -12041,7 +12428,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14587339349100616068
+          6924402771068196086
         ]
       ], 
       "reviewed-by-human": true
@@ -12050,7 +12437,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4845657008892614902
+          4490657881493756635
         ]
       ], 
       "reviewed-by-human": true
@@ -12071,19 +12458,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5690148983251652763
+          9054724363030889537
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6950824879875834417
+          13784032993637985188
         ]
       ], 
       "reviewed-by-human": true
@@ -12092,7 +12476,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12033348890106673917
+          15714576116580958779
         ]
       ], 
       "reviewed-by-human": true
@@ -12113,7 +12497,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17793168923743372787
+          9421155880930121883
         ]
       ], 
       "reviewed-by-human": true
@@ -12122,7 +12506,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7145256036683994452
+          18229665496986439439
         ]
       ], 
       "reviewed-by-human": true
@@ -12131,7 +12515,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3488925571342820329
+          105241220564519876
         ]
       ], 
       "reviewed-by-human": true
@@ -12140,7 +12524,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10142872210589910512
+          4563248346148482892
         ]
       ], 
       "reviewed-by-human": true
@@ -12149,7 +12533,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8065383055741598278
+          871386803148914938
         ]
       ], 
       "reviewed-by-human": true
@@ -12158,7 +12542,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18291547764603511730
+          4003578528625251315
         ]
       ], 
       "reviewed-by-human": true
@@ -12239,7 +12623,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5934309731866117042
+          9465975819853219225
         ]
       ], 
       "reviewed-by-human": true
@@ -12248,7 +12632,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3755243187117270240
+          6716520464112503707
         ]
       ], 
       "reviewed-by-human": true
@@ -12257,7 +12641,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7947770726308015845
+          11316730716624469973
         ]
       ], 
       "reviewed-by-human": true
@@ -12278,37 +12662,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1645616767380937001
+          9429708724863544827
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6573333690852305392
+          17943319865010822752
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6573333690852305392
+          17943319865010822752
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -12326,73 +12701,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15114553511769777308
+          17718120888140666675
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1868600027959115515
+          12769090836677776831
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16930961979993062474
+          2928609262520934005
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3303957336640673144
+          15466609454401378954
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6959472844938986495
+          7563430578643640083
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14968340081520270039
+          9915783629919682203
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -12418,6 +12775,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8016674471264445543
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          364990464712065046
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1717022897323454986
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8016674471264445543
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          364990464712065046
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1717022897323454986
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7152129134887335611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17723924170151385302
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13155766220564029308
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7152129134887335611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17723924170151385302
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13155766220564029308
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -12500,31 +12965,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16694308522803417239
+          2089892562626313651
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15066688788639351077
+          10826393201339392414
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13998596758363022455
+          4187211411003539883
         ]
       ], 
       "reviewed-by-human": true
@@ -12545,7 +13004,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11258108435881621254
+          6159788927647373190
         ]
       ], 
       "reviewed-by-human": true
@@ -12554,7 +13013,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4297052245541539817
+          9935284324655219048
         ]
       ], 
       "reviewed-by-human": true
@@ -12563,7 +13022,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12922216189963810918
+          6394207612322747160
         ]
       ], 
       "reviewed-by-human": true
@@ -12602,7 +13061,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2947983991092664961
+          2904019594945473810
         ]
       ], 
       "reviewed-by-human": true
@@ -12623,7 +13082,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13033437583454572808
+          17191223209799682875
         ]
       ], 
       "reviewed-by-human": true
@@ -12632,7 +13091,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15784559218199345382
+          684500268220078839
         ]
       ], 
       "reviewed-by-human": true
@@ -12641,13 +13100,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17987163926472091210
+          15384891931773131138
         ]
       ], 
-      "bugs": [
-        2146
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12665,7 +13121,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10129495190519485171
+          3481708780174816153
         ]
       ], 
       "reviewed-by-human": true
@@ -12674,7 +13130,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15155072419379282036
+          9094207230997611194
         ]
       ], 
       "reviewed-by-human": true
@@ -12683,7 +13139,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6797874516960842447
+          15177137532703774790
         ]
       ], 
       "reviewed-by-human": true
@@ -12704,7 +13160,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12487686416149787646
+          13242395172626269451
         ]
       ], 
       "reviewed-by-human": true
@@ -12713,7 +13169,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17893131623095512316
+          6808860434682210813
         ]
       ], 
       "reviewed-by-human": true
@@ -12722,7 +13178,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15509702616994760437
+          7685769890951039829
         ]
       ], 
       "reviewed-by-human": true
@@ -12738,6 +13194,15 @@
         2146
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10591909693224673086
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86_64-Debug/expected-results.json b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86_64-Debug/expected-results.json
index c30accc..e7535a5 100644
--- a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86_64-Debug/expected-results.json
+++ b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86_64-Debug/expected-results.json
@@ -112,10 +112,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10879622672299268205
+          12831307062174214826
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -225,28 +226,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          8386050591090575061
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          17119504700677749589
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6329400057600097234
+          16786896836766143161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -260,6 +264,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -299,54 +330,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10573214378214332517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -465,10 +448,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2944061319698975510
+          14822676243771102497
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -522,37 +505,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          707578552626433941
+          4135526557546616687
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -618,28 +592,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          13314899585272765728
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          3534768579781843121
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          6658400916517904289
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -657,7 +634,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          12030291790142951562
         ]
       ], 
       "ignore-failure": false, 
@@ -667,7 +644,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          2328990479460076921
         ]
       ], 
       "ignore-failure": false, 
@@ -677,7 +654,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669107578763825775
+          7666464896359988018
         ]
       ], 
       "ignore-failure": false, 
@@ -843,28 +820,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -921,25 +901,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2801325236637973751
+          5281412422904919583
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -972,10 +955,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9337838425513581101
+          12195310936180436782
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -2473,6 +2459,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12424138734353506606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -2786,10 +2799,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4626344487553497677
+          7048546964514197209
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -2800,6 +2813,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          636195428699273093
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2840,28 +2880,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3617424777768145898
+          16038422283720293399
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -2954,34 +2997,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -2999,28 +3037,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8826561316445684686
+          16297948529498506413
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -3545,37 +3586,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          660002910751114028
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3680,31 +3712,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17128498486631460526
+          7760022190728266716
         ]
       ], 
       "reviewed-by-human": true
@@ -3809,10 +3835,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4841496337918692008
+          10208615534534427054
         ]
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "complexclip2_path_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -3935,10 +3962,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7461094591079150540
+          14745371879903012446
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_rrect_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -3953,25 +3980,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          2931817475980821997
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          5185842740431793908
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6493039209837692850
+          10990887139037962924
         ]
       ], 
       "reviewed-by-human": true
@@ -3980,25 +4009,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          14177391063005797992
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          6823565356147184210
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13265855489806029964
+          11767564415406014631
         ]
       ], 
       "reviewed-by-human": true
@@ -4031,25 +4062,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          18180274608236460762
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          7774541298746974882
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15436226578831879472
+          343773841046282683
         ]
       ], 
       "reviewed-by-human": true
@@ -4058,25 +4091,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          13640252250101891066
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          3113239910847922849
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1190962956186333047
+          4491023457741351309
         ]
       ], 
       "reviewed-by-human": true
@@ -4181,28 +4216,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          681518688112967286
+          964167756699231217
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4310,28 +4345,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          6863972292267418469
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          10364599796573376762
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11310385329664314856
+          7898840088714420125
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4349,28 +4387,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4658655007649634701
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          18036292203388148817
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8160232458378510085
+          9317020945793047069
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4592,28 +4633,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          15590002593583735483
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          16969415686637953721
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5375673450726446602
+          15175995861819667151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -4631,28 +4675,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          11007951012846856042
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1357781408314308336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1357781408314308336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -4679,28 +4726,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -4718,37 +4768,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4766,7 +4807,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -4775,7 +4816,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -4784,7 +4825,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12241316569839901585
+          8040800720155301683
         ]
       ], 
       "reviewed-by-human": true
@@ -4805,37 +4846,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13397371426171817534
+          1281057607739566387
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4853,37 +4885,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12241316569839901585
+          8040800720155301683
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4901,37 +4924,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7922854781530363105
+          10091200121371913151
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4949,7 +4963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -4958,7 +4972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -4967,7 +4981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1503976714167724830
+          12559198495177059060
         ]
       ], 
       "reviewed-by-human": true
@@ -4988,37 +5002,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12388921334436224745
+          3850207957964943776
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5036,37 +5041,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1503976714167724830
+          12559198495177059060
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5084,37 +5080,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12965470470056135172
+          10440591076012582303
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5132,7 +5119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -5141,7 +5128,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -5150,7 +5137,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2141019891928343978
+          10951953396077624358
         ]
       ], 
       "reviewed-by-human": true
@@ -5171,37 +5158,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17351323733553391924
+          17521327519243435949
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5219,37 +5197,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2141019891928343978
+          10951953396077624358
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5267,37 +5236,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8546063919377166259
+          9082824586346219222
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5315,10 +5275,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5333,10 +5294,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10303810140172040904
+          11482296602351535562
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5354,28 +5316,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          14000810406608195551
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          8360698665239233312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10072750740945871465
+          16553053007513863215
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5393,28 +5358,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13717384973349640095
+          14666226782194455577
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5432,25 +5400,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          652105149337720065
+          13023439110169898341
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -5500,28 +5471,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          2183732814993705842
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          14083194632819813968
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13248443147554810424
+          6619271459357894670
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -5643,6 +5617,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -5860,7 +5861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -5869,7 +5870,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -5897,7 +5898,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -5906,7 +5907,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -5934,7 +5935,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -5943,7 +5944,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -5971,7 +5972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -5980,7 +5981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -6008,7 +6009,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -6017,7 +6018,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -6045,7 +6046,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -6054,7 +6055,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -6082,7 +6083,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -6091,7 +6092,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -6119,7 +6120,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -6128,7 +6129,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -6156,7 +6157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -6165,7 +6166,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -6230,7 +6231,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -6239,7 +6240,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -6267,7 +6268,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
       "reviewed-by-human": true
@@ -6276,7 +6277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
       "reviewed-by-human": true
@@ -6285,7 +6286,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16132206054577275426
+          9014502494028699619
         ]
       ], 
       "reviewed-by-human": true
@@ -6304,7 +6305,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -6313,7 +6314,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -6322,7 +6323,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6571014605016942961
+          10286803221364697801
         ]
       ], 
       "reviewed-by-human": true
@@ -6341,7 +6342,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6865564636648157250
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -6350,7 +6351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9256179289443217715
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -6359,7 +6360,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3112939118667482752
+          5125823501637387350
         ]
       ], 
       "reviewed-by-human": true
@@ -6374,83 +6375,92 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11987204656394981007
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11172256210463001362
+          15720178186502724169
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8235727908523200854
+          14818252557016116600
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12300505832476339318
+          16507136324562418008
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9634328461383126524
+          14818252557016116600
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6727685461018676373
+          16507136324562418008
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15532577507744171028
+          6940737243764937510
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2963378280773795200
+          6940737243764937510
         ]
       ], 
       "ignore-failure": true, 
@@ -6460,37 +6470,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          6912355345607947791
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          9115989932432402646
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16666842658661744318
+          6777672133164700613
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -6508,28 +6509,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          2124588341689625752
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          8295720945662111046
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16738047539038188349
+          3761726957027384064
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_pdf-poppler.png": {
       "allowed-digests": [
@@ -6543,32 +6547,62 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6109517714117419633
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3095060401995611617
+          1481537360072784758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -6586,31 +6620,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14350650523048604465
+          487156685711148680
         ]
       ], 
       "reviewed-by-human": true
@@ -7161,6 +7189,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9050243732888826330
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16867245765576148898
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3996052619796469473
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18359962369733108667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12852304057572000016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7192,10 +7436,7 @@
           9898697105564368249
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-poppler.png": {
       "allowed-digests": [
@@ -7282,7 +7523,7 @@
           871619327129850391
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-poppler.png": {
       "allowed-digests": [
@@ -7318,7 +7559,7 @@
           15361695066602809881
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-poppler.png": {
       "allowed-digests": [
@@ -7354,7 +7595,7 @@
           16855420853188990089
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-poppler.png": {
       "allowed-digests": [
@@ -7567,7 +7808,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "ignore-failure": false, 
@@ -7609,28 +7850,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2328482482999487459
+          9833133577951959237
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7703,10 +7947,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13274748155400875756
+          17393768864600460161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -7757,7 +8002,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          5100503083862816328
         ]
       ], 
       "reviewed-by-human": true
@@ -7766,7 +8011,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          5315670865766411029
         ]
       ], 
       "reviewed-by-human": true
@@ -7775,7 +8020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15896254500886456697
+          18338026403264996017
         ]
       ], 
       "reviewed-by-human": true
@@ -7825,38 +8070,68 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11847517854086327634
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          5567358773991782197
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          12471740373961346125
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9856700641955552351
+          11888686022754756017
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          14697442244205319783
         ]
       ], 
       "reviewed-by-human": true
@@ -7865,7 +8140,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          18044565907096276184
         ]
       ], 
       "reviewed-by-human": true
@@ -7874,7 +8149,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12958440671393733211
+          7044686035558524733
         ]
       ], 
       "reviewed-by-human": true
@@ -7904,25 +8179,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7515396075491109228
+          4641014269499037622
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -7936,28 +8214,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13129455763424501371
+          14770902400313891624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -8043,25 +8324,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1810444454668426072
+          15217122207501330203
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -8079,28 +8363,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18200079507569830870
+          214593100636960333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -8118,25 +8405,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16236721268324357263
+          4596576699457741273
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8150,37 +8440,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12316458082598669525
+          10548005182299770458
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8198,28 +8479,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8234,37 +8515,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8318,28 +8590,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4182857538588713843
+          16818718173210917334
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8381,13 +8656,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16271637167989743463
+          7150313580130655353
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -8405,28 +8680,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7390396075740049141
+          17747269762102294402
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -8480,28 +8758,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          10616859326334085691
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          13005892560864159760
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8660327948439151591
+          5843577122150718596
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8519,28 +8800,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          14481939058217271046
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          12396256756772939715
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1253279159644460411
+          7493595502744203397
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8558,25 +8842,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          1606938827300604281
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          16065808063166858733
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7139505319228028644
+          18226744787129433112
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8623,28 +8910,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2994579633452577661
+          16144546122411234896
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -8722,7 +9012,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8767,7 +9057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8812,7 +9102,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8884,13 +9174,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11302360056092717723
+          4273377358399608835
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -8908,28 +9198,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -8943,6 +9236,276 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14168003095232129524
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16174472480972198806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16387431988923787343
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1027612514960788650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9560692921579649405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3585100793314895154
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15407893317880102456
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1841509450334894439
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7478955310715869440
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12825465872317767907
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9142,25 +9705,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9202,13 +9768,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          12848328078440704869
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9261,29 +9827,85 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16458370652639524599
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5260695078479088411
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3618256589512039908
+          4059585779960614622
         ]
       ], 
       "reviewed-by-human": true
@@ -9586,7 +10208,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -9595,7 +10217,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -9604,12 +10226,39 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13918912246429055687
+          17735883773617287292
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16250745281745965444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -9626,25 +10275,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9655,6 +10307,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -9691,6 +10370,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -9735,28 +10441,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          6009493504302066276
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          13358913611238803501
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17849746177518873287
+          104273781585409685
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -9810,28 +10519,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          15576488907248411849
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          11776299738014423526
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13992807470689754488
+          11767847879379411189
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9849,28 +10561,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          6344407473960729259
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          9813576216999362038
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8672103517888678305
+          16760938805266099790
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9948,10 +10663,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5440525180981761895
+          9571104979652806930
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10361,28 +11077,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497038318515454624
+          17752415278946897
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -10400,7 +11119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -10409,7 +11128,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -10418,7 +11137,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -10439,37 +11158,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1603
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1603
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932682095705715863
+          7659748670555812121
         ]
       ], 
-      "bugs": [
-        1603
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10487,7 +11197,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          9228469833437167668
         ]
       ], 
       "reviewed-by-human": true
@@ -10496,7 +11206,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          17250454159117352933
         ]
       ], 
       "reviewed-by-human": true
@@ -10505,7 +11215,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9379659218927886410
+          7261720940549232078
         ]
       ], 
       "reviewed-by-human": true
@@ -10514,7 +11224,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16342024067941080851
         ]
       ], 
       "reviewed-by-human": true
@@ -10523,7 +11233,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          17317072924787566080
         ]
       ], 
       "reviewed-by-human": true
@@ -10532,7 +11242,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12615277578507098981
+          12101886556041102559
         ]
       ], 
       "reviewed-by-human": true
@@ -10700,7 +11410,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          16393968203105861983
         ]
       ], 
       "ignore-failure": false, 
@@ -10710,7 +11420,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8053365202385311069
+          12692320183870247864
         ]
       ], 
       "reviewed-by-human": true
@@ -10731,7 +11441,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "ignore-failure": false, 
@@ -10741,7 +11451,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "ignore-failure": false, 
@@ -10751,7 +11461,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13394212856950326493
+          15279657961859822991
         ]
       ], 
       "reviewed-by-human": true
@@ -10772,7 +11482,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "ignore-failure": false, 
@@ -10782,7 +11492,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "ignore-failure": false, 
@@ -10792,7 +11502,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          32030531006027067
+          15759781880810789448
         ]
       ], 
       "ignore-failure": false, 
@@ -11045,37 +11755,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          8249967000998873336
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          11336103823568541577
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6185310100469816433
+          1438660038977905881
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -11093,28 +11794,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          8249967000998873336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          615326829446859241
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12133799822073532931
+          13391020767722885480
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11132,25 +11836,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          6781554900301524151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          7568063466353017848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10868077502519846091
+          12376246715763899370
         ]
       ], 
       "reviewed-by-human": true
@@ -11291,37 +11997,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          248128091148658883
+          15825828722190913352
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -11387,28 +12084,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14861880405767971501
+          159004473548620887
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2172995158306505021
+          8104410590312662232
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14092660394167221372
+          793571917548606224
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -11621,7 +12321,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -11630,7 +12330,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -11639,7 +12339,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12206828883575652405
+          5656265252683071823
         ]
       ], 
       "reviewed-by-human": true
@@ -11770,32 +12470,62 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11813,10 +12543,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16570721013563827642
+          16893666949631983554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -11843,7 +12573,8 @@
           10999541404612369092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11882,7 +12613,8 @@
           6717965895519090324
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11900,25 +12632,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -11936,7 +12671,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -11945,7 +12680,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -11954,7 +12689,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -11975,37 +12710,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932682095705715863
+          7659748670555812121
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -12023,7 +12749,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          10903574554557130940
         ]
       ], 
       "ignore-failure": false, 
@@ -12033,7 +12759,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          4985017360636277471
         ]
       ], 
       "ignore-failure": false, 
@@ -12043,7 +12769,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127867708506544979
+          4954472096981762200
         ]
       ], 
       "ignore-failure": false, 
@@ -12053,7 +12779,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          9085173547997942241
         ]
       ], 
       "reviewed-by-human": true
@@ -12062,7 +12788,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          7321105861580014856
         ]
       ], 
       "reviewed-by-human": true
@@ -12071,7 +12797,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18228384523492481373
+          6703295218647016900
         ]
       ], 
       "reviewed-by-human": true
@@ -12143,7 +12869,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          13495792426164432844
         ]
       ], 
       "ignore-failure": false, 
@@ -12153,7 +12879,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          15504021362006183015
         ]
       ], 
       "ignore-failure": false, 
@@ -12163,7 +12889,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2777928313170626539
+          2446410806867201529
         ]
       ], 
       "ignore-failure": false, 
@@ -12185,37 +12911,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -12233,64 +12950,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -12313,6 +13021,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5701895924183087555
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12300111888349865181
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10382127665747013988
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7870452552399035571
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16846592895652028679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7025230607614396892
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10567700594698864677
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4934037525238326145
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -12389,31 +13205,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12923408472393428718
+          1439418242802718141
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -12431,28 +13246,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17972597467707082942
+          18290759104797452817
         ]
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12506,28 +13324,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12421287546540698026
+          7571665914830278260
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12545,28 +13366,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          16464916071202373983
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          7722978681047038091
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7351962579811010389
+          1745606781345726404
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -12584,25 +13408,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          13335469986208246779
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          5785239134980311524
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3511629606700176049
+          4576794236692228884
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -12620,28 +13447,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          9430581040858116312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          18201622713807911998
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5321738870293124408
+          8538297429821405390
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -12654,6 +13484,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10591909693224673086
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86_64-Release/expected-results.json b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86_64-Release/expected-results.json
index f8c0a91..e7535a5 100644
--- a/expectations/gm/Test-Win7-ShuttleA-HD2000-x86_64-Release/expected-results.json
+++ b/expectations/gm/Test-Win7-ShuttleA-HD2000-x86_64-Release/expected-results.json
@@ -112,10 +112,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10879622672299268205
+          12831307062174214826
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -225,28 +226,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          8386050591090575061
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          17119504700677749589
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6329400057600097234
+          16786896836766143161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -260,6 +264,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -299,54 +330,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10573214378214332517
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -465,10 +448,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2944061319698975510
+          14822676243771102497
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -522,37 +505,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          707578552626433941
+          4135526557546616687
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -618,28 +592,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          13314899585272765728
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          3534768579781843121
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          6658400916517904289
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -657,7 +634,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          12030291790142951562
         ]
       ], 
       "ignore-failure": false, 
@@ -667,7 +644,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          2328990479460076921
         ]
       ], 
       "ignore-failure": false, 
@@ -677,7 +654,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669107578763825775
+          7666464896359988018
         ]
       ], 
       "ignore-failure": false, 
@@ -843,28 +820,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -921,25 +901,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2801325236637973751
+          5281412422904919583
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -972,10 +955,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9337838425513581101
+          12195310936180436782
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -2473,6 +2459,33 @@
       ], 
       "ignore-failure": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12424138734353506606
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_gpu.png": {
       "allowed-digests": [
         [
@@ -2786,10 +2799,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4626344487553497677
+          7048546964514197209
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -2800,6 +2813,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          636195428699273093
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -2840,28 +2880,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3617424777768145898
+          16038422283720293399
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -2954,34 +2997,29 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          14184772749174668745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -2999,28 +3037,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8826561316445684686
+          16297948529498506413
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -3545,37 +3586,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          660002910751114028
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3680,31 +3712,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17128498486631460526
+          7760022190728266716
         ]
       ], 
       "reviewed-by-human": true
@@ -3809,10 +3835,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4841496337918692008
+          10208615534534427054
         ]
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "complexclip2_path_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -3935,10 +3962,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7461094591079150540
+          14745371879903012446
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip2_rrect_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -3953,25 +3980,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          2931817475980821997
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          5185842740431793908
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6493039209837692850
+          10990887139037962924
         ]
       ], 
       "reviewed-by-human": true
@@ -3980,25 +4009,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          14177391063005797992
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          6823565356147184210
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13265855489806029964
+          11767564415406014631
         ]
       ], 
       "reviewed-by-human": true
@@ -4031,25 +4062,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          18180274608236460762
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          7774541298746974882
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15436226578831879472
+          343773841046282683
         ]
       ], 
       "reviewed-by-human": true
@@ -4058,25 +4091,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          13640252250101891066
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          3113239910847922849
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1190962956186333047
+          4491023457741351309
         ]
       ], 
       "reviewed-by-human": true
@@ -4181,28 +4216,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          681518688112967286
+          964167756699231217
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4310,28 +4345,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          6863972292267418469
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          10364599796573376762
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11310385329664314856
+          7898840088714420125
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4349,28 +4387,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4658655007649634701
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          18036292203388148817
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8160232458378510085
+          9317020945793047069
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4533,7 +4574,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11379723987131334781
+          4199059907564224666
         ]
       ], 
       "bugs": [
@@ -4592,28 +4633,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          15590002593583735483
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          16969415686637953721
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5375673450726446602
+          15175995861819667151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -4631,28 +4675,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          11007951012846856042
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1357781408314308336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1357781408314308336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -4679,28 +4726,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -4718,37 +4768,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4766,7 +4807,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -4775,7 +4816,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -4784,7 +4825,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12241316569839901585
+          8040800720155301683
         ]
       ], 
       "reviewed-by-human": true
@@ -4805,37 +4846,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13397371426171817534
+          1281057607739566387
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4853,37 +4885,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12241316569839901585
+          8040800720155301683
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4901,37 +4924,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7922854781530363105
+          10091200121371913151
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -4949,7 +4963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -4958,7 +4972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -4967,7 +4981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1503976714167724830
+          12559198495177059060
         ]
       ], 
       "reviewed-by-human": true
@@ -4988,37 +5002,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12388921334436224745
+          3850207957964943776
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5036,37 +5041,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1503976714167724830
+          12559198495177059060
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5084,37 +5080,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12965470470056135172
+          10440591076012582303
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5132,7 +5119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -5141,7 +5128,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -5150,7 +5137,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2141019891928343978
+          10951953396077624358
         ]
       ], 
       "reviewed-by-human": true
@@ -5171,37 +5158,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17351323733553391924
+          17521327519243435949
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5219,37 +5197,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2141019891928343978
+          10951953396077624358
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5267,37 +5236,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8546063919377166259
+          9082824586346219222
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5315,10 +5275,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5333,10 +5294,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10303810140172040904
+          11482296602351535562
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5354,28 +5316,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          14000810406608195551
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          8360698665239233312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10072750740945871465
+          16553053007513863215
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5393,28 +5358,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13717384973349640095
+          14666226782194455577
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5432,25 +5400,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          652105149337720065
+          13023439110169898341
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -5500,28 +5471,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          2183732814993705842
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          14083194632819813968
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13248443147554810424
+          6619271459357894670
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -5643,6 +5617,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -5860,7 +5861,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -5869,7 +5870,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -5897,7 +5898,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -5906,7 +5907,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -5934,7 +5935,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -5943,7 +5944,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -5971,7 +5972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -5980,7 +5981,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -6008,7 +6009,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -6017,7 +6018,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -6045,7 +6046,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -6054,7 +6055,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -6082,7 +6083,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -6091,7 +6092,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -6119,7 +6120,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -6128,7 +6129,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -6156,7 +6157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -6165,7 +6166,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -6230,7 +6231,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -6239,7 +6240,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -6267,7 +6268,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
       "reviewed-by-human": true
@@ -6276,7 +6277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
       "reviewed-by-human": true
@@ -6285,7 +6286,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16132206054577275426
+          9014502494028699619
         ]
       ], 
       "reviewed-by-human": true
@@ -6304,7 +6305,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -6313,7 +6314,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -6322,7 +6323,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6571014605016942961
+          10286803221364697801
         ]
       ], 
       "reviewed-by-human": true
@@ -6341,7 +6342,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6865564636648157250
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -6350,7 +6351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9256179289443217715
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -6359,7 +6360,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3112939118667482752
+          5125823501637387350
         ]
       ], 
       "reviewed-by-human": true
@@ -6374,83 +6375,92 @@
       "ignore-failure": true, 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11987204656394981007
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11172256210463001362
+          15720178186502724169
         ]
       ], 
-      "bugs": [
-        1759
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8235727908523200854
+          14818252557016116600
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12300505832476339318
+          16507136324562418008
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9634328461383126524
+          14818252557016116600
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6727685461018676373
+          16507136324562418008
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15532577507744171028
+          6940737243764937510
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2963378280773795200
+          6940737243764937510
         ]
       ], 
       "ignore-failure": true, 
@@ -6460,37 +6470,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          6912355345607947791
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          9115989932432402646
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16666842658661744318
+          6777672133164700613
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -6508,28 +6509,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          2124588341689625752
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          8295720945662111046
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16738047539038188349
+          3761726957027384064
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "fontscaler_pdf-poppler.png": {
       "allowed-digests": [
@@ -6543,32 +6547,62 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6109517714117419633
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3095060401995611617
+          1481537360072784758
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -6586,31 +6620,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14350650523048604465
+          487156685711148680
         ]
       ], 
       "reviewed-by-human": true
@@ -7161,6 +7189,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9050243732888826330
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16867245765576148898
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3996052619796469473
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          258655677780145923
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18359962369733108667
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12852304057572000016
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7192,10 +7436,7 @@
           9898697105564368249
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-poppler.png": {
       "allowed-digests": [
@@ -7282,7 +7523,7 @@
           871619327129850391
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-poppler.png": {
       "allowed-digests": [
@@ -7318,7 +7559,7 @@
           15361695066602809881
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-poppler.png": {
       "allowed-digests": [
@@ -7354,7 +7595,7 @@
           16855420853188990089
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-poppler.png": {
       "allowed-digests": [
@@ -7567,7 +7808,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "ignore-failure": false, 
@@ -7609,28 +7850,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2328482482999487459
+          9833133577951959237
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7703,10 +7947,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13274748155400875756
+          17393768864600460161
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -7757,7 +8002,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          5100503083862816328
         ]
       ], 
       "reviewed-by-human": true
@@ -7766,7 +8011,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          5315670865766411029
         ]
       ], 
       "reviewed-by-human": true
@@ -7775,7 +8020,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15896254500886456697
+          18338026403264996017
         ]
       ], 
       "reviewed-by-human": true
@@ -7825,38 +8070,68 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11847517854086327634
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          5567358773991782197
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          12471740373961346125
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9856700641955552351
+          11888686022754756017
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          14697442244205319783
         ]
       ], 
       "reviewed-by-human": true
@@ -7865,7 +8140,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          18044565907096276184
         ]
       ], 
       "reviewed-by-human": true
@@ -7874,7 +8149,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12958440671393733211
+          7044686035558524733
         ]
       ], 
       "reviewed-by-human": true
@@ -7904,25 +8179,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7515396075491109228
+          4641014269499037622
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -7936,28 +8214,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13129455763424501371
+          14770902400313891624
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -8043,25 +8324,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1810444454668426072
+          15217122207501330203
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -8079,28 +8363,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18200079507569830870
+          214593100636960333
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -8118,25 +8405,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16236721268324357263
+          4596576699457741273
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8150,37 +8440,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12316458082598669525
+          10548005182299770458
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8198,28 +8479,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8234,37 +8515,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8318,28 +8590,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4182857538588713843
+          16818718173210917334
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8381,13 +8656,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16271637167989743463
+          7150313580130655353
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -8405,28 +8680,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7390396075740049141
+          17747269762102294402
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -8480,28 +8758,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          10616859326334085691
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          13005892560864159760
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8660327948439151591
+          5843577122150718596
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8519,28 +8800,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          14481939058217271046
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          12396256756772939715
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1253279159644460411
+          7493595502744203397
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8558,25 +8842,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          1606938827300604281
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          16065808063166858733
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7139505319228028644
+          18226744787129433112
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8623,28 +8910,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2994579633452577661
+          16144546122411234896
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -8722,7 +9012,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8767,7 +9057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8812,7 +9102,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13328031630073680450
+          10227090825150464532
         ]
       ], 
       "reviewed-by-human": true
@@ -8884,13 +9174,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11302360056092717723
+          4273377358399608835
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -8908,28 +9198,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -8943,6 +9236,276 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14168003095232129524
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16174472480972198806
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16387431988923787343
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1027612514960788650
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9560692921579649405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3585100793314895154
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15407893317880102456
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1841509450334894439
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7478955310715869440
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12825465872317767907
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9142,25 +9705,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9202,13 +9768,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          12848328078440704869
         ]
       ], 
       "bugs": [
         1578
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9261,29 +9827,85 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16458370652639524599
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5260695078479088411
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3618256589512039908
+          4059585779960614622
         ]
       ], 
       "reviewed-by-human": true
@@ -9586,7 +10208,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -9595,7 +10217,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -9604,12 +10226,39 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13918912246429055687
+          17735883773617287292
         ]
       ], 
       "ignore-failure": false, 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16250745281745965444
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -9626,25 +10275,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9655,6 +10307,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -9691,6 +10370,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -9735,28 +10441,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          6009493504302066276
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          13358913611238803501
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17849746177518873287
+          104273781585409685
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -9810,28 +10519,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          15576488907248411849
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          11776299738014423526
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13992807470689754488
+          11767847879379411189
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9849,28 +10561,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          6344407473960729259
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          9813576216999362038
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8672103517888678305
+          16760938805266099790
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9948,10 +10663,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5440525180981761895
+          9571104979652806930
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10361,28 +11077,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497038318515454624
+          17752415278946897
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -10400,7 +11119,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -10409,7 +11128,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -10418,7 +11137,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -10439,37 +11158,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1603
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1603
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932682095705715863
+          7659748670555812121
         ]
       ], 
-      "bugs": [
-        1603
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10487,7 +11197,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          9228469833437167668
         ]
       ], 
       "reviewed-by-human": true
@@ -10496,7 +11206,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          17250454159117352933
         ]
       ], 
       "reviewed-by-human": true
@@ -10505,7 +11215,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9379659218927886410
+          7261720940549232078
         ]
       ], 
       "reviewed-by-human": true
@@ -10514,7 +11224,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16342024067941080851
         ]
       ], 
       "reviewed-by-human": true
@@ -10523,7 +11233,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          17317072924787566080
         ]
       ], 
       "reviewed-by-human": true
@@ -10532,7 +11242,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12615277578507098981
+          12101886556041102559
         ]
       ], 
       "reviewed-by-human": true
@@ -10700,7 +11410,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          16393968203105861983
         ]
       ], 
       "ignore-failure": false, 
@@ -10710,7 +11420,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8053365202385311069
+          12692320183870247864
         ]
       ], 
       "reviewed-by-human": true
@@ -10731,7 +11441,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "ignore-failure": false, 
@@ -10741,7 +11451,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "ignore-failure": false, 
@@ -10751,7 +11461,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13394212856950326493
+          15279657961859822991
         ]
       ], 
       "reviewed-by-human": true
@@ -10772,7 +11482,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "ignore-failure": false, 
@@ -10782,7 +11492,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "ignore-failure": false, 
@@ -10792,7 +11502,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          32030531006027067
+          15759781880810789448
         ]
       ], 
       "ignore-failure": false, 
@@ -11045,37 +11755,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          8249967000998873336
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          11336103823568541577
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6185310100469816433
+          1438660038977905881
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -11093,28 +11794,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          8249967000998873336
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          615326829446859241
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12133799822073532931
+          13391020767722885480
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11132,25 +11836,27 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          6781554900301524151
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          7568063466353017848
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10868077502519846091
+          12376246715763899370
         ]
       ], 
       "reviewed-by-human": true
@@ -11291,37 +11997,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          248128091148658883
+          15825828722190913352
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -11387,28 +12084,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14861880405767971501
+          159004473548620887
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2172995158306505021
+          8104410590312662232
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14092660394167221372
+          793571917548606224
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -11621,7 +12321,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -11630,7 +12330,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -11639,7 +12339,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12206828883575652405
+          5656265252683071823
         ]
       ], 
       "reviewed-by-human": true
@@ -11770,32 +12470,62 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11813,10 +12543,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16570721013563827642
+          16893666949631983554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -11843,7 +12573,8 @@
           10999541404612369092
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11882,7 +12613,8 @@
           6717965895519090324
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11900,25 +12632,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -11936,7 +12671,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -11945,7 +12680,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -11954,7 +12689,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10403438720744094292
+          17937048783747748672
         ]
       ], 
       "reviewed-by-human": true
@@ -11975,37 +12710,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7932682095705715863
+          7659748670555812121
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -12023,7 +12749,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          10903574554557130940
         ]
       ], 
       "ignore-failure": false, 
@@ -12033,7 +12759,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          4985017360636277471
         ]
       ], 
       "ignore-failure": false, 
@@ -12043,7 +12769,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127867708506544979
+          4954472096981762200
         ]
       ], 
       "ignore-failure": false, 
@@ -12053,7 +12779,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          9085173547997942241
         ]
       ], 
       "reviewed-by-human": true
@@ -12062,7 +12788,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          7321105861580014856
         ]
       ], 
       "reviewed-by-human": true
@@ -12071,7 +12797,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18228384523492481373
+          6703295218647016900
         ]
       ], 
       "reviewed-by-human": true
@@ -12143,7 +12869,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          13495792426164432844
         ]
       ], 
       "ignore-failure": false, 
@@ -12153,7 +12879,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          15504021362006183015
         ]
       ], 
       "ignore-failure": false, 
@@ -12163,7 +12889,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2777928313170626539
+          2446410806867201529
         ]
       ], 
       "ignore-failure": false, 
@@ -12185,37 +12911,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -12233,64 +12950,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -12313,6 +13021,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5701895924183087555
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12300111888349865181
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5723754619989219775
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10382127665747013988
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7870452552399035571
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16846592895652028679
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7025230607614396892
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2403731110436935270
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10567700594698864677
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4934037525238326145
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -12389,31 +13205,30 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12923408472393428718
+          1439418242802718141
         ]
       ], 
-      "bugs": [
-        1578
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -12431,28 +13246,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17972597467707082942
+          18290759104797452817
         ]
       ], 
-      "ignore-failure": true
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12506,28 +13324,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12421287546540698026
+          7571665914830278260
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12545,28 +13366,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          16464916071202373983
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          7722978681047038091
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7351962579811010389
+          1745606781345726404
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -12584,25 +13408,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          13335469986208246779
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          5785239134980311524
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3511629606700176049
+          4576794236692228884
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -12620,28 +13447,31 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          9430581040858116312
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          18201622713807911998
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5321738870293124408
+          8538297429821405390
         ]
       ], 
-      "ignore-failure": false
+      "ignore-failure": false, 
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -12654,6 +13484,15 @@
         1578
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10591909693224673086
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win8-ShuttleA-GTX660-x86-Debug/expected-results.json b/expectations/gm/Test-Win8-ShuttleA-GTX660-x86-Debug/expected-results.json
index bce8c1c..33250b3 100644
--- a/expectations/gm/Test-Win8-ShuttleA-GTX660-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Win8-ShuttleA-GTX660-x86-Debug/expected-results.json
@@ -151,34 +151,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -331,58 +331,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          7593352410810558049
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          1175700925683069803
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          15415204559421796941
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          12035029927330392542
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          751809614678646951
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -396,6 +384,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -501,75 +534,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -736,34 +700,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -850,58 +808,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14652235513246564229
+          12449041092507757378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16245483467216489815
+          9087208410328931904
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4047354824627112796
+          908079640636796316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -988,58 +934,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          7812520044346961011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          12807763425550694757
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          10348011941932861480
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          10348011941932861480
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          5166570216456302933
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -1057,7 +991,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          3617797305044480555
         ]
       ], 
       "reviewed-by-human": true
@@ -1066,7 +1000,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          14987526374456897079
         ]
       ], 
       "reviewed-by-human": true
@@ -1075,7 +1009,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099769173772687975
+          1537092402026262432
         ]
       ], 
       "reviewed-by-human": true
@@ -1084,7 +1018,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1928858325393991739
+          10733498520612026154
         ]
       ], 
       "reviewed-by-human": true
@@ -1093,7 +1027,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099769173772687975
+          10651756436507454114
         ]
       ], 
       "reviewed-by-human": true
@@ -1321,58 +1255,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14029934813708721331
+          11476701287181118472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6379907739251348875
+          2800217968641110362
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -1453,58 +1375,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14934551414236827349
+          2874388734250092639
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16244994631386084477
+          15152103473812092421
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14934551414236827349
+          2874388734250092639
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -1540,28 +1450,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -1666,7 +1585,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
       "reviewed-by-human": true
@@ -4044,6 +3963,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -4306,25 +4270,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
       "reviewed-by-human": true
@@ -4338,6 +4302,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4411,58 +4420,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8976307978169070533
+          9715048358204914021
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15274361429663626659
+          10791718083342670060
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7361441850871240424
+          11226069113236569409
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -4576,58 +4573,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16508855522965628557
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -4645,58 +4630,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          7596334653042200982
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5806130805959000992
+          11076529384363630535
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          12683881210526887632
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -5473,58 +5446,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          660002910751114028
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15742069787955891275
+          5900403635120013876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          13340499774791895971
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -5680,58 +5641,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
@@ -6130,94 +6079,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          8059723840111543656
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          4022128344496177992
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13811349623686669396
+          12100412534735983468
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          7167682324595825921
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          1167106541986679122
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          484686002760255512
+          4977268569647138810
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9758791734243356840
+          7473120410450320644
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370661691515227788
+          11887374817081287579
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6235,22 +6163,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11906262362145726223
+          8406846183024424798
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10341156631225228790
+          1698813443589668875
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_pdf-poppler.png": {
       "allowed-digests": [
@@ -6268,94 +6193,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          3183371552229607548
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          3409717039232577306
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8717162927730913272
+          2057371307378029751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          14815312009812228022
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          9409727332382440449
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8704676340583221795
+          548631379086924810
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8562400821134319401
+          12844041116036912013
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13625518271740009316
+          9058223880734977500
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6373,22 +6277,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12058934008258379833
+          368988525699315975
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12805678179242111681
+          9726049292572177337
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -6514,46 +6415,50 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          479069169116054389
+          17121828245730015083
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8565104511668826829
+          8627394447232319577
         ]
       ], 
-      "reviewed-by-human": false
+      "bugs": [
+        2824
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16530634008647790653
+          7570814056450667246
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -6733,58 +6638,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          2396629361279121278
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          12144247543820336588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3386415177137025017
+          5390095926777602051
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18409257590792155660
+          15673049959189156070
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4965073552524677584
+          9808820959788087997
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6802,58 +6695,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4844524665660284305
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          5938003447863338066
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1918820825774442918
+          5087929812634018385
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5492952256259345052
+          8726256039731354406
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7050192252559156843
+          15223225239913271101
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -7093,7 +6974,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4903737309685329914
+          1395267708058780826
         ]
       ], 
       "reviewed-by-human": true
@@ -7186,58 +7067,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          8144433221544041893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          6901150638632819323
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7340746540294423206
+          9538730268883185427
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18428594076841281649
+          16675708267160231217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14161050065750911947
+          12734850694189703805
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -7255,58 +7124,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          15209085685049262946
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -7351,58 +7208,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -7420,58 +7265,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -7489,7 +7322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -7498,7 +7331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -7507,7 +7340,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7516,7 +7349,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16451780885896960300
+          14204243393620033211
         ]
       ], 
       "reviewed-by-human": true
@@ -7525,7 +7358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7546,58 +7379,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443130797061158720
+          3590945223549597113
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7615,58 +7436,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8034132364379362582
+          17212795401772012692
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7684,58 +7493,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15854240744220847964
+          12495564829829617636
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7753,7 +7550,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -7762,7 +7559,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -7771,7 +7568,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7780,7 +7577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61543217406202998
+          11968003402313032299
         ]
       ], 
       "reviewed-by-human": true
@@ -7789,7 +7586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7810,58 +7607,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2171610356153094701
+          8951768093676734731
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7879,58 +7664,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6692547324448596108
+          16032430115842971269
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7948,58 +7721,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12362918265113141584
+          352963511646887173
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -8017,7 +7778,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -8026,7 +7787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -8035,7 +7796,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
       "reviewed-by-human": true
@@ -8044,7 +7805,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6125556691115888800
+          16977393652065766378
         ]
       ], 
       "reviewed-by-human": true
@@ -8053,7 +7814,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
       "reviewed-by-human": true
@@ -8074,58 +7835,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14156869179031488870
+          7501369635627690776
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12495827092338238690
+          7692738176472808848
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14156869179031488870
+          7501369635627690776
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8143,58 +7892,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6871411400838133729
+          2835685519522776626
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8212,58 +7949,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16162216557075653007
+          2760623527115162554
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1243361506848516240
+          15670553619205431923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16162216557075653007
+          2760623527115162554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8281,13 +8006,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -8305,34 +8027,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13627205234939690742
+          14145109580428845757
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17686572383265746470
+          17938573218167752738
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11190272575141191020
+          14959282528007631804
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -8350,58 +8072,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          10560594815938292783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          12545797976096132621
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16944071921626269866
+          7296629561031831197
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17326759309207012859
+          6255577643368982288
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16944071921626269866
+          3875306556126405867
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -8419,58 +8129,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17641824294124384978
+          15926382706833037919
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13760859783463290994
+          289707744025360504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14118413545283346564
+          11324020305665756421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -8488,58 +8186,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10582819077805576685
+          51541207251928275
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10966410634478253303
+          15538638387135444952
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3032133295741624070
+          16953834221792082615
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8611,58 +8297,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          229562018395218460
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          12760426964160092214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7610947751291879266
+          5792779588987266181
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8907607835040622257
+          6530275130754592140
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5599646814156973739
+          451260416074786226
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8856,6 +8530,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -9187,7 +8906,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -9196,7 +8915,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -9244,7 +8963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -9253,7 +8972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -9307,7 +9026,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -9316,7 +9035,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -9370,7 +9089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -9379,7 +9098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -9433,7 +9152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -9442,7 +9161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -9496,7 +9215,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -9505,7 +9224,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -9559,7 +9278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -9568,7 +9287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -9622,7 +9341,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -9631,7 +9350,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -9685,7 +9404,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -9694,7 +9413,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -9811,7 +9530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -9820,7 +9539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -9874,58 +9593,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11574133982069711928
+          5532051404015186872
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2113348389489071842
+          13863379279912600675
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11574133982069711928
+          5532051404015186872
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -9943,7 +9650,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -9952,7 +9659,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -9961,34 +9668,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15302642444517196692
+          3271940701668668277
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5126343750573898991
+          8027294698161910767
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15302642444517196692
+          3271940701668668277
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -10006,7 +9707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15618220200870997449
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -10015,7 +9716,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10526671976174365374
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -10024,34 +9725,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1094828084143041922
+          6425288885008549863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1408513740171764116
+          11693284923582451238
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1094828084143041922
+          6425288885008549863
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -10065,209 +9760,212 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8305101852626451769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7779118070033093384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8305101852626451769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          14883457588515450185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5851939326059970416
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15546460357391099353
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14292646344952811693
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16542857918429840050
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          14287369518419556676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          14287369518419556676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          2085580649669581585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          922176307457717158
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          10200358509808425244
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          10200358509808425244
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          6738101046888470769
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -10285,31 +9983,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          13203594782216607040
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          15828501156207808430
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6038427216880721079
+          11929432714848218301
         ]
       ], 
       "reviewed-by-human": true
@@ -10318,19 +10010,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8356197894460139473
+          15767280341492508020
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11819142696872198617
+          10611437431422341640
         ]
       ], 
       "reviewed-by-human": true
@@ -10347,62 +10036,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3876782072761139785
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10667209145671721407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5352278316997662690
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1046694922283575432
+          7310201851346355510
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11179742213777376243
+          4376621845120437533
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1046694922283575432
+          14147609500698884768
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -10420,43 +10142,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17766273991942049288
+          17912233352232188365
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8020995970029089582
+          7335848171046712603
         ]
       ], 
       "reviewed-by-human": true
@@ -10465,10 +10178,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16518931243149906456
+          15543648061215744397
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -11310,6 +11023,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15889650838157198039
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14393949491637878306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7553968815810048260
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11769204272611093646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17839836921231752863
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7482589153229259850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9899853331722013852
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17326560431224736462
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6459206295890594330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8382915188572696476
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          363214432637750870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4514485822480600121
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16359544679338136257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2205365319218156147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10350633209557780455
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -11341,10 +11414,7 @@
           2515733614721864626
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -11473,7 +11543,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa16.png": {
       "allowed-digests": [
@@ -11527,7 +11597,7 @@
           16605120526645549774
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa16.png": {
       "allowed-digests": [
@@ -11581,7 +11651,7 @@
           169027135498041421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa16.png": {
       "allowed-digests": [
@@ -11908,7 +11978,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -11935,7 +12005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
       "reviewed-by-human": true
@@ -11965,58 +12035,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9262043821850989724
+          12751187030376887099
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17498929465580770598
+          15041389777883880577
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9262043821850989724
+          1194623239453375939
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12124,34 +12182,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -12223,7 +12281,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          2859104781692949426
         ]
       ], 
       "reviewed-by-human": true
@@ -12232,7 +12290,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          2670248603126936222
         ]
       ], 
       "reviewed-by-human": true
@@ -12241,7 +12299,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1502871433053621895
+          873535995353697759
         ]
       ], 
       "reviewed-by-human": true
@@ -12250,7 +12308,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4706028507622067827
+          17721745947522835626
         ]
       ], 
       "reviewed-by-human": true
@@ -12259,7 +12317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1502871433053621895
+          787908483793116578
         ]
       ], 
       "reviewed-by-human": true
@@ -12327,47 +12385,83 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8438243272047728234
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8438243272047728234
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7938559748189909140
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          14557198649976668882
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          13002044415183336403
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15061683733564186204
+          3429469574871335702
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          6559263086767964475
         ]
       ], 
       "reviewed-by-human": true
@@ -12376,7 +12470,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          14315647952979882955
         ]
       ], 
       "reviewed-by-human": true
@@ -12385,7 +12479,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5042747931564698790
+          10880379701383794584
         ]
       ], 
       "reviewed-by-human": true
@@ -12394,7 +12488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2688291096121197296
+          17408884944030048338
         ]
       ], 
       "reviewed-by-human": true
@@ -12403,10 +12497,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4771014495127026924
+          15911448479106757347
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
@@ -12421,22 +12515,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          122726789056295963
+          1537105960517213309
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15947771628835537481
+          7179091632218471759
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_pdf-poppler.png": {
       "allowed-digests": [
@@ -12454,41 +12545,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          10223214443700181285
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          10223214443700181285
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          18404005473374897414
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12502,58 +12598,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3300816044347370985
+          3518283227649716316
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6542871302874538158
+          14527201156012636147
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14627439817426003316
+          5516953276145914495
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -12673,58 +12757,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12913059478362291221
+          13596415401198873831
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6043577369810335263
+          17962675542424191142
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17401169737638319038
+          14044923836925531517
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -12742,58 +12814,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -12811,42 +12871,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3262803126131585722
+          13391508749678438749
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11426838740980958872
+          8382253584634947082
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9659350677391822056
+          1102950561799296746
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12860,58 +12924,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17073193087595049207
+          1321180911407859380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12394367286940416876
+          18069013584799504840
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13709606587202811817
+          5366191227041081961
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -12929,46 +12981,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          2462464065957440433
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12983,58 +13035,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          8797975763901838314
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -13106,58 +13146,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          1938473326245501278
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13199,34 +13227,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -13244,58 +13272,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -13367,58 +13383,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          4183511498011974903
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          10285833817111015220
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8200021215559120818
+          9202923584968077183
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16621163543038358032
+          9457661346008587898
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481364132226706053
+          3674694234040196508
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13436,58 +13440,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          9263713892251900876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          3699172046262487290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17364323165819274082
+          1243570489849511690
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8542930727646104844
+          17006239057979777374
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6362537695706148742
+          1527267847491917447
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13505,58 +13497,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          15807341393622522232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          6484758485740569522
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8099618297706003570
+          13672413721263802056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12717738459185687769
+          7264182713172897674
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12424363096228788735
+          16626294912432257339
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13574,58 +13554,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -13721,7 +13689,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13730,7 +13698,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13739,7 +13707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13784,7 +13752,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13793,7 +13761,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13802,7 +13770,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13847,7 +13815,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13856,7 +13824,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13865,7 +13833,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13964,34 +13932,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -14009,58 +13977,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -14074,6 +14030,456 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -14351,58 +14757,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1201553558635803052
+          5602760436216664605
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -14444,34 +14838,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -14551,62 +14945,140 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5738277652531841246
+          13432295925256731908
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7995388484637533091
+          9421281174921218201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11836133234466138290
+          12770815845542827504
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_pdf-poppler.png": {
       "allowed-digests": [
@@ -15089,7 +15561,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -15098,7 +15570,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -15107,16 +15579,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2934804817352937872
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15125,7 +15642,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15146,58 +15663,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          17506817297106108685
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15211,6 +15716,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -15265,6 +15815,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -15332,43 +15927,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          14919179564192850472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          6704764580322283111
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16504108627280647914
+          11044759503191387491
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15755700643078617599
+          17439478692444443893
         ]
       ], 
       "reviewed-by-human": true
@@ -15377,10 +15963,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14430759865428982597
+          8648676323088729372
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -15464,58 +16050,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          18104496854197341496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          6952495213922076627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17174790409763084733
+          16945286131909290674
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5132409693689837643
+          10086078156008471061
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18400817843938057493
+          7580933693393515476
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15533,58 +16107,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          11795498474298281319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          14297982111593447018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11798651298936594976
+          6963242957620421884
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2886396052067032686
+          4271409036060367806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768414447821598463
+          3142395726537453688
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15689,34 +16251,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -15755,10 +16317,7 @@
           11339980900210544915
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -16332,58 +16891,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14684491285852381433
+          13065162206529155581
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8023336521280369497
+          4059069468906277635
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4439825578385779753
+          13474389573104079912
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -16401,7 +16948,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -16410,7 +16957,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -16419,7 +16966,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          6048869515923073564
         ]
       ], 
       "reviewed-by-human": true
@@ -16428,7 +16975,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1559349726696617839
+          14734348706173171694
         ]
       ], 
       "reviewed-by-human": true
@@ -16437,7 +16984,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          13986036354074897447
         ]
       ], 
       "reviewed-by-human": true
@@ -16458,58 +17005,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          16367101498658508972
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14603002718790540977
+          16751914431820491012
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          1205048549325125274
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -16527,7 +17062,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          18140335162380255225
         ]
       ], 
       "reviewed-by-human": true
@@ -16536,7 +17071,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          7129698125485750601
         ]
       ], 
       "reviewed-by-human": true
@@ -16545,7 +17080,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4156481340570717959
+          13719342871832399838
         ]
       ], 
       "reviewed-by-human": true
@@ -16554,7 +17089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12705698943369055239
+          5248743086217192530
         ]
       ], 
       "reviewed-by-human": true
@@ -16563,7 +17098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16281098760671026549
         ]
       ], 
       "reviewed-by-human": true
@@ -16572,7 +17107,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          13530435022292494762
         ]
       ], 
       "reviewed-by-human": true
@@ -16581,7 +17116,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13131209168116653631
+          13814877700654806883
         ]
       ], 
       "reviewed-by-human": true
@@ -16590,7 +17125,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548364158761522774
+          16624590309946972209
         ]
       ], 
       "reviewed-by-human": true
@@ -16599,7 +17134,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13131209168116653631
+          12492815789504654915
         ]
       ], 
       "reviewed-by-human": true
@@ -16620,7 +17155,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4156481340570717959
+          14838890993150454189
         ]
       ], 
       "reviewed-by-human": true
@@ -16848,7 +17383,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          3831063373917728128
         ]
       ], 
       "reviewed-by-human": true
@@ -16857,7 +17392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11081789658344209328
+          10497222257759782905
         ]
       ], 
       "reviewed-by-human": true
@@ -16866,7 +17401,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6304960047606523701
+          6509695928299095478
         ]
       ], 
       "reviewed-by-human": true
@@ -16875,7 +17410,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17371546210615613853
+          11856586713916442122
         ]
       ], 
       "reviewed-by-human": true
@@ -16896,7 +17431,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "reviewed-by-human": true
@@ -16905,7 +17440,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "reviewed-by-human": true
@@ -16914,7 +17449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2113206247214385098
+          9291687675247984765
         ]
       ], 
       "reviewed-by-human": true
@@ -16923,7 +17458,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14071403280264096223
+          14493378758991003394
         ]
       ], 
       "reviewed-by-human": true
@@ -16932,7 +17467,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16741507987193604094
+          16947177559920250893
         ]
       ], 
       "reviewed-by-human": true
@@ -16953,7 +17488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "reviewed-by-human": true
@@ -16962,7 +17497,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "reviewed-by-human": true
@@ -16971,7 +17506,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14510027867806755962
+          13673140479532038640
         ]
       ], 
       "reviewed-by-human": true
@@ -16980,7 +17515,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12146654658304155786
+          15576286174149035789
         ]
       ], 
       "reviewed-by-human": true
@@ -16989,7 +17524,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17031144438812250524
+          16258109186950173986
         ]
       ], 
       "reviewed-by-human": true
@@ -17355,58 +17890,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          1581438121274106176
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9884173386347087482
+          1933490657284787592
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10525579109813075137
+          17459659862280803801
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9884173386347087482
+          6667479893675462157
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -17424,58 +17947,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          2283035916243745030
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1609512922117613959
+          367167356747061080
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3490322557642337363
+          117706835416353038
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380899108733265481
+          6453538714645879627
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -17493,31 +18004,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          852960377597007352
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          1031488952720446379
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12889890156182669108
+          495886922968836878
         ]
       ], 
       "reviewed-by-human": true
@@ -17526,22 +18031,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18377760636939840560
+          14966470912654351144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          309877259595619467
+          9253606783225793790
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_pdf-poppler.png": {
       "allowed-digests": [
@@ -17751,58 +18253,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564656089209715121
+          4796295628459008767
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564656089209715121
+          15300564346213801791
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3720605705123675736
+          14465730655738711503
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -17889,58 +18379,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9425059496441527728
+          159004473548620887
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5089083539219748309
+          8104410590312662232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6772529533806073828
+          13706743646479427266
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17931259227737559526
+          12682715880467573944
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2029910099093282736
+          10781607431815735586
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -18294,7 +18772,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -18303,7 +18781,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -18312,7 +18790,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9400706697033338692
+          13764339996600437836
         ]
       ], 
       "reviewed-by-human": true
@@ -18321,7 +18799,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          237633552255702584
+          15536171010526909654
         ]
       ], 
       "reviewed-by-human": true
@@ -18330,7 +18808,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15481694980398014047
+          17890488678190568949
         ]
       ], 
       "reviewed-by-human": true
@@ -18515,62 +18993,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1131824196339345229
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -18588,28 +19099,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9407358693309761110
+          5829921135942844635
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -18642,10 +19153,7 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -18711,10 +19219,7 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -18753,58 +19258,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -18822,7 +19315,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -18831,7 +19324,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -18840,7 +19333,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          6048869515923073564
         ]
       ], 
       "reviewed-by-human": true
@@ -18849,7 +19342,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1559349726696617839
+          14734348706173171694
         ]
       ], 
       "reviewed-by-human": true
@@ -18858,7 +19351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          13986036354074897447
         ]
       ], 
       "reviewed-by-human": true
@@ -18879,58 +19372,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          16367101498658508972
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14603002718790540977
+          16751914431820491012
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          1205048549325125274
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -18948,7 +19429,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          4864263811791905685
         ]
       ], 
       "reviewed-by-human": true
@@ -18957,7 +19438,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          16801244478240186276
         ]
       ], 
       "reviewed-by-human": true
@@ -18966,7 +19447,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15641677254803875749
+          8757435387673298229
         ]
       ], 
       "reviewed-by-human": true
@@ -18975,7 +19456,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12233502021372539335
+          7513095271860536492
         ]
       ], 
       "reviewed-by-human": true
@@ -18984,7 +19465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          14598823216365008278
         ]
       ], 
       "reviewed-by-human": true
@@ -18993,7 +19474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5949714246508281820
         ]
       ], 
       "reviewed-by-human": true
@@ -19002,7 +19483,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5402764657976459291
         ]
       ], 
       "reviewed-by-human": true
@@ -19011,7 +19492,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13789919752467315906
+          8878476896705676612
         ]
       ], 
       "reviewed-by-human": true
@@ -19020,7 +19501,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          6996671819617945771
         ]
       ], 
       "reviewed-by-human": true
@@ -19041,7 +19522,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15641677254803875749
+          13498177505417262335
         ]
       ], 
       "reviewed-by-human": true
@@ -19131,7 +19612,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          1258363359136286164
         ]
       ], 
       "reviewed-by-human": true
@@ -19140,7 +19621,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          5399430353808909931
         ]
       ], 
       "reviewed-by-human": true
@@ -19149,7 +19630,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5092500482844467763
+          10977620141810635112
         ]
       ], 
       "reviewed-by-human": true
@@ -19158,7 +19639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7272353906741772982
+          10217664941927163150
         ]
       ], 
       "reviewed-by-human": true
@@ -19167,7 +19648,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15810556183767148552
+          5696450717885951386
         ]
       ], 
       "reviewed-by-human": true
@@ -19188,58 +19669,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          7451829304858435646
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -19257,94 +19726,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          9822393380242794213
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -19362,22 +19810,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          1794524931659012049
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -19391,6 +19836,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14238495105637549536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13091587407128414591
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2811772865778668658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7185018533082072769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9068081473418106350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6787753377476893062
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9066227969618021937
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7185018533082072769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13706090452902799076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9261209386788794091
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13592132854078956729
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16239445678573089230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7389120679870614644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8144110888506762127
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1546493394542600629
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16239445678573089230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -19503,43 +20128,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5483308942142720488
+          12997787133028120518
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4696340272245690277
+          4367857761078620058
         ]
       ], 
       "reviewed-by-human": true
@@ -19548,10 +20164,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7664082110143619089
+          6780241912548653043
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19569,58 +20185,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7796209920479635095
+          16932359230392749690
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14523815480948971483
+          3695036642112880517
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5911601511426755275
+          13167397400025502386
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -19638,14 +20242,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18028468636148123109
+          6183456328083498663
         ]
       ], 
-      "bugs": [
-        1978
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verylargebitmap_8888.png": {
       "allowed-digests": [
@@ -19709,58 +20310,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -19778,58 +20367,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          438558267463767125
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          6853497244680825166
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          962717882117070565
+          9083297924306753575
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          768763528917693850
+          4901741930957102676
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          962717882117070565
+          18343278898776537277
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19847,58 +20424,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          18005779299301055149
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          543837030557564588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9806700643412380727
+          14265963860216842340
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11875667066985540599
+          9782797996062068312
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9806700643412380727
+          10234504630630772106
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -19916,58 +20481,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          16976170622579387959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          3296931836447172845
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9113706558474041625
+          5944658117124283263
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1323079300068890978
+          7166884040512070986
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9113706558474041625
+          2432684250684813924
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -19980,6 +20533,33 @@
         1935
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win8-ShuttleA-GTX660-x86-Release/expected-results.json b/expectations/gm/Test-Win8-ShuttleA-GTX660-x86-Release/expected-results.json
index f0777e5..a534114 100644
--- a/expectations/gm/Test-Win8-ShuttleA-GTX660-x86-Release/expected-results.json
+++ b/expectations/gm/Test-Win8-ShuttleA-GTX660-x86-Release/expected-results.json
@@ -151,34 +151,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -331,58 +331,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          7593352410810558049
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          1175700925683069803
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          15415204559421796941
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          12035029927330392542
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          751809614678646951
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -396,6 +384,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -501,75 +534,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -736,34 +700,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -850,58 +808,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14652235513246564229
+          12449041092507757378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16245483467216489815
+          9087208410328931904
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4047354824627112796
+          908079640636796316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -988,58 +934,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          7812520044346961011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          12807763425550694757
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          10348011941932861480
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          10348011941932861480
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          5166570216456302933
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -1057,7 +991,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          3617797305044480555
         ]
       ], 
       "reviewed-by-human": true
@@ -1066,7 +1000,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          14987526374456897079
         ]
       ], 
       "reviewed-by-human": true
@@ -1075,7 +1009,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099769173772687975
+          1537092402026262432
         ]
       ], 
       "reviewed-by-human": true
@@ -1084,7 +1018,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1928858325393991739
+          10733498520612026154
         ]
       ], 
       "reviewed-by-human": true
@@ -1093,7 +1027,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099769173772687975
+          10651756436507454114
         ]
       ], 
       "reviewed-by-human": true
@@ -1321,58 +1255,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14029934813708721331
+          11476701287181118472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6379907739251348875
+          2800217968641110362
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -1453,58 +1375,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14934551414236827349
+          2874388734250092639
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16244994631386084477
+          15152103473812092421
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14934551414236827349
+          2874388734250092639
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -1540,28 +1450,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -1666,7 +1585,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
       "reviewed-by-human": true
@@ -4044,6 +3963,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -4306,25 +4270,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
       "reviewed-by-human": true
@@ -4338,6 +4302,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4411,58 +4420,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8976307978169070533
+          9715048358204914021
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15274361429663626659
+          10791718083342670060
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7361441850871240424
+          11226069113236569409
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -4576,58 +4573,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16508855522965628557
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -4645,58 +4630,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          7596334653042200982
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5806130805959000992
+          11076529384363630535
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          12683881210526887632
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -5473,58 +5446,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          660002910751114028
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15742069787955891275
+          5900403635120013876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          13340499774791895971
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -5680,58 +5641,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
@@ -6130,94 +6079,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          8059723840111543656
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          4022128344496177992
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13811349623686669396
+          12100412534735983468
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          7167682324595825921
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          1167106541986679122
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          484686002760255512
+          4977268569647138810
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9758791734243356840
+          7473120410450320644
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370661691515227788
+          11887374817081287579
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6235,22 +6163,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11906262362145726223
+          8406846183024424798
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10341156631225228790
+          1698813443589668875
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_pdf-poppler.png": {
       "allowed-digests": [
@@ -6268,94 +6193,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          3183371552229607548
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          3409717039232577306
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8717162927730913272
+          2057371307378029751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          14815312009812228022
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          9409727332382440449
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8704676340583221795
+          548631379086924810
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8562400821134319401
+          12844041116036912013
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13625518271740009316
+          9058223880734977500
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6373,22 +6277,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12058934008258379833
+          368988525699315975
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12805678179242111681
+          9726049292572177337
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -6514,46 +6415,50 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          479069169116054389
+          17121828245730015083
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8565104511668826829
+          17868394612177611310
         ]
       ], 
-      "reviewed-by-human": false
+      "bugs": [
+        2824
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16530634008647790653
+          7570814056450667246
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -6733,58 +6638,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          2396629361279121278
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          12144247543820336588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3386415177137025017
+          5390095926777602051
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18409257590792155660
+          15673049959189156070
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4965073552524677584
+          9808820959788087997
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6802,58 +6695,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4844524665660284305
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          5938003447863338066
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1918820825774442918
+          5087929812634018385
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5492952256259345052
+          8726256039731354406
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7050192252559156843
+          15223225239913271101
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -7093,7 +6974,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4903737309685329914
+          1395267708058780826
         ]
       ], 
       "reviewed-by-human": true
@@ -7186,58 +7067,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          8144433221544041893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          6901150638632819323
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7340746540294423206
+          9538730268883185427
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18428594076841281649
+          16675708267160231217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14161050065750911947
+          12734850694189703805
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -7255,58 +7124,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          15209085685049262946
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -7351,58 +7208,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -7420,58 +7265,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -7489,7 +7322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -7498,7 +7331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -7507,7 +7340,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7516,7 +7349,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16451780885896960300
+          14204243393620033211
         ]
       ], 
       "reviewed-by-human": true
@@ -7525,7 +7358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7546,58 +7379,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443130797061158720
+          3590945223549597113
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7615,58 +7436,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8034132364379362582
+          17212795401772012692
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7684,58 +7493,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15854240744220847964
+          12495564829829617636
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7753,7 +7550,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -7762,7 +7559,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -7771,7 +7568,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7780,7 +7577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61543217406202998
+          11968003402313032299
         ]
       ], 
       "reviewed-by-human": true
@@ -7789,7 +7586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7810,58 +7607,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2171610356153094701
+          8951768093676734731
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7879,58 +7664,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6692547324448596108
+          16032430115842971269
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7948,58 +7721,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12362918265113141584
+          352963511646887173
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -8017,7 +7778,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -8026,7 +7787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -8035,7 +7796,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
       "reviewed-by-human": true
@@ -8044,7 +7805,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6125556691115888800
+          16977393652065766378
         ]
       ], 
       "reviewed-by-human": true
@@ -8053,7 +7814,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
       "reviewed-by-human": true
@@ -8074,58 +7835,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14156869179031488870
+          7501369635627690776
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12495827092338238690
+          7692738176472808848
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14156869179031488870
+          7501369635627690776
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8143,58 +7892,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6871411400838133729
+          2835685519522776626
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8212,58 +7949,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16162216557075653007
+          2760623527115162554
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1243361506848516240
+          15670553619205431923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16162216557075653007
+          2760623527115162554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8281,13 +8006,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -8305,34 +8027,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13627205234939690742
+          14145109580428845757
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17686572383265746470
+          17938573218167752738
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11190272575141191020
+          14959282528007631804
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -8350,58 +8072,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          10560594815938292783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          12545797976096132621
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16944071921626269866
+          7296629561031831197
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17326759309207012859
+          6255577643368982288
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16944071921626269866
+          3875306556126405867
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -8419,58 +8129,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17641824294124384978
+          15926382706833037919
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13760859783463290994
+          289707744025360504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14118413545283346564
+          11324020305665756421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -8488,58 +8186,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10582819077805576685
+          51541207251928275
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10966410634478253303
+          15538638387135444952
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3032133295741624070
+          16953834221792082615
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8611,58 +8297,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          229562018395218460
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          12760426964160092214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7610947751291879266
+          5792779588987266181
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8907607835040622257
+          6530275130754592140
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5599646814156973739
+          451260416074786226
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8856,6 +8530,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -9187,7 +8906,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -9196,7 +8915,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -9244,7 +8963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -9253,7 +8972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -9307,7 +9026,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -9316,7 +9035,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -9370,7 +9089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -9379,7 +9098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -9433,7 +9152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -9442,7 +9161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -9496,7 +9215,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -9505,7 +9224,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -9559,7 +9278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -9568,7 +9287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -9622,7 +9341,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -9631,7 +9350,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -9685,7 +9404,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -9694,7 +9413,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -9811,7 +9530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -9820,7 +9539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -9874,58 +9593,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11574133982069711928
+          5532051404015186872
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2113348389489071842
+          13863379279912600675
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11574133982069711928
+          5532051404015186872
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -9943,7 +9650,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -9952,7 +9659,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -9961,34 +9668,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15302642444517196692
+          3271940701668668277
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5126343750573898991
+          8027294698161910767
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15302642444517196692
+          3271940701668668277
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -10006,7 +9707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15618220200870997449
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -10015,7 +9716,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10526671976174365374
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -10024,34 +9725,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1094828084143041922
+          6425288885008549863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1408513740171764116
+          11693284923582451238
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1094828084143041922
+          6425288885008549863
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -10065,209 +9760,212 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8305101852626451769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7779118070033093384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8305101852626451769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          14883457588515450185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5851939326059970416
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15546460357391099353
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14292646344952811693
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16542857918429840050
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          14287369518419556676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          14287369518419556676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          2085580649669581585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          922176307457717158
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          10200358509808425244
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          10200358509808425244
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          6738101046888470769
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -10285,31 +9983,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          13203594782216607040
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          15828501156207808430
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6038427216880721079
+          11929432714848218301
         ]
       ], 
       "reviewed-by-human": true
@@ -10318,19 +10010,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8356197894460139473
+          15767280341492508020
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11819142696872198617
+          10611437431422341640
         ]
       ], 
       "reviewed-by-human": true
@@ -10347,62 +10036,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3876782072761139785
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10667209145671721407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5352278316997662690
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1046694922283575432
+          7310201851346355510
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11179742213777376243
+          4376621845120437533
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1046694922283575432
+          14147609500698884768
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -10420,43 +10142,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17766273991942049288
+          17912233352232188365
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8020995970029089582
+          7335848171046712603
         ]
       ], 
       "reviewed-by-human": true
@@ -10465,10 +10178,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16518931243149906456
+          15543648061215744397
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -11310,6 +11023,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15889650838157198039
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14393949491637878306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7553968815810048260
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11769204272611093646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17839836921231752863
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7482589153229259850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9899853331722013852
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17326560431224736462
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6459206295890594330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8382915188572696476
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          363214432637750870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4514485822480600121
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16359544679338136257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2205365319218156147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10350633209557780455
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -11341,10 +11414,7 @@
           2515733614721864626
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -11473,7 +11543,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa16.png": {
       "allowed-digests": [
@@ -11527,7 +11597,7 @@
           16605120526645549774
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa16.png": {
       "allowed-digests": [
@@ -11581,7 +11651,7 @@
           169027135498041421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa16.png": {
       "allowed-digests": [
@@ -11908,7 +11978,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -11935,7 +12005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
       "reviewed-by-human": true
@@ -11965,58 +12035,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9262043821850989724
+          12751187030376887099
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17498929465580770598
+          15041389777883880577
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9262043821850989724
+          1194623239453375939
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12124,34 +12182,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -12223,7 +12281,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          2859104781692949426
         ]
       ], 
       "reviewed-by-human": true
@@ -12232,7 +12290,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          2670248603126936222
         ]
       ], 
       "reviewed-by-human": true
@@ -12241,7 +12299,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1502871433053621895
+          873535995353697759
         ]
       ], 
       "reviewed-by-human": true
@@ -12250,7 +12308,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4706028507622067827
+          17721745947522835626
         ]
       ], 
       "reviewed-by-human": true
@@ -12259,7 +12317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1502871433053621895
+          787908483793116578
         ]
       ], 
       "reviewed-by-human": true
@@ -12327,47 +12385,83 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8438243272047728234
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8438243272047728234
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7938559748189909140
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          14557198649976668882
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          13002044415183336403
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15061683733564186204
+          3429469574871335702
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          6559263086767964475
         ]
       ], 
       "reviewed-by-human": true
@@ -12376,7 +12470,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          14315647952979882955
         ]
       ], 
       "reviewed-by-human": true
@@ -12385,7 +12479,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5042747931564698790
+          10880379701383794584
         ]
       ], 
       "reviewed-by-human": true
@@ -12394,7 +12488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2688291096121197296
+          17408884944030048338
         ]
       ], 
       "reviewed-by-human": true
@@ -12403,10 +12497,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4771014495127026924
+          15911448479106757347
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
@@ -12421,22 +12515,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          122726789056295963
+          1537105960517213309
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15947771628835537481
+          7179091632218471759
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_pdf-poppler.png": {
       "allowed-digests": [
@@ -12454,41 +12545,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          10223214443700181285
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          10223214443700181285
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          18404005473374897414
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12502,58 +12598,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3300816044347370985
+          3518283227649716316
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6542871302874538158
+          14527201156012636147
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14627439817426003316
+          5516953276145914495
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -12673,58 +12757,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12913059478362291221
+          13596415401198873831
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6043577369810335263
+          17962675542424191142
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17401169737638319038
+          14044923836925531517
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -12742,58 +12814,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -12811,42 +12871,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3262803126131585722
+          13391508749678438749
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11426838740980958872
+          8382253584634947082
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9659350677391822056
+          1102950561799296746
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12860,58 +12924,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17073193087595049207
+          1321180911407859380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12394367286940416876
+          18069013584799504840
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13709606587202811817
+          5366191227041081961
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -12929,46 +12981,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          2462464065957440433
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12983,58 +13035,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          8797975763901838314
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -13106,58 +13146,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          1938473326245501278
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13199,34 +13227,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -13244,58 +13272,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -13367,58 +13383,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          4183511498011974903
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          10285833817111015220
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8200021215559120818
+          9202923584968077183
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16621163543038358032
+          9457661346008587898
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481364132226706053
+          3674694234040196508
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13436,58 +13440,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          9263713892251900876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          3699172046262487290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17364323165819274082
+          1243570489849511690
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8542930727646104844
+          17006239057979777374
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6362537695706148742
+          1527267847491917447
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13505,58 +13497,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          15807341393622522232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          6484758485740569522
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8099618297706003570
+          13672413721263802056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12717738459185687769
+          7264182713172897674
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12424363096228788735
+          16626294912432257339
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13574,58 +13554,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -13721,7 +13689,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13730,7 +13698,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13739,7 +13707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13784,7 +13752,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13793,7 +13761,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13802,7 +13770,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13847,7 +13815,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13856,7 +13824,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13865,7 +13833,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13964,34 +13932,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -14009,58 +13977,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -14074,6 +14030,456 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -14351,58 +14757,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1201553558635803052
+          5602760436216664605
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -14444,34 +14838,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -14551,62 +14945,140 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5738277652531841246
+          13432295925256731908
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7995388484637533091
+          9421281174921218201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11836133234466138290
+          12770815845542827504
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_pdf-poppler.png": {
       "allowed-digests": [
@@ -15089,7 +15561,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -15098,7 +15570,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -15107,16 +15579,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2934804817352937872
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15125,7 +15642,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15146,58 +15663,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          17506817297106108685
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15211,6 +15716,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -15265,6 +15815,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -15332,43 +15927,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          14919179564192850472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          6704764580322283111
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16504108627280647914
+          11044759503191387491
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15755700643078617599
+          17439478692444443893
         ]
       ], 
       "reviewed-by-human": true
@@ -15377,10 +15963,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14430759865428982597
+          8648676323088729372
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -15464,58 +16050,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          18104496854197341496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          6952495213922076627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17174790409763084733
+          16945286131909290674
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5132409693689837643
+          10086078156008471061
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18400817843938057493
+          7580933693393515476
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15533,58 +16107,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          11795498474298281319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          14297982111593447018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11798651298936594976
+          6963242957620421884
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2886396052067032686
+          4271409036060367806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768414447821598463
+          3142395726537453688
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15689,34 +16251,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -15755,10 +16317,7 @@
           11339980900210544915
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -16332,58 +16891,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14684491285852381433
+          13065162206529155581
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8023336521280369497
+          4059069468906277635
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4439825578385779753
+          13474389573104079912
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -16401,7 +16948,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -16410,7 +16957,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -16419,7 +16966,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          6048869515923073564
         ]
       ], 
       "reviewed-by-human": true
@@ -16428,7 +16975,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1559349726696617839
+          14734348706173171694
         ]
       ], 
       "reviewed-by-human": true
@@ -16437,7 +16984,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          13986036354074897447
         ]
       ], 
       "reviewed-by-human": true
@@ -16458,58 +17005,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          16367101498658508972
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14603002718790540977
+          16751914431820491012
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          1205048549325125274
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -16527,7 +17062,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          18140335162380255225
         ]
       ], 
       "reviewed-by-human": true
@@ -16536,7 +17071,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          7129698125485750601
         ]
       ], 
       "reviewed-by-human": true
@@ -16545,7 +17080,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4156481340570717959
+          13719342871832399838
         ]
       ], 
       "reviewed-by-human": true
@@ -16554,7 +17089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12705698943369055239
+          5248743086217192530
         ]
       ], 
       "reviewed-by-human": true
@@ -16563,7 +17098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16281098760671026549
         ]
       ], 
       "reviewed-by-human": true
@@ -16572,7 +17107,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          13530435022292494762
         ]
       ], 
       "reviewed-by-human": true
@@ -16581,7 +17116,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13131209168116653631
+          13814877700654806883
         ]
       ], 
       "reviewed-by-human": true
@@ -16590,7 +17125,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548364158761522774
+          16624590309946972209
         ]
       ], 
       "reviewed-by-human": true
@@ -16599,7 +17134,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13131209168116653631
+          12492815789504654915
         ]
       ], 
       "reviewed-by-human": true
@@ -16620,7 +17155,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4156481340570717959
+          14838890993150454189
         ]
       ], 
       "reviewed-by-human": true
@@ -16848,7 +17383,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          3831063373917728128
         ]
       ], 
       "reviewed-by-human": true
@@ -16857,7 +17392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11081789658344209328
+          10497222257759782905
         ]
       ], 
       "reviewed-by-human": true
@@ -16866,7 +17401,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6304960047606523701
+          6509695928299095478
         ]
       ], 
       "reviewed-by-human": true
@@ -16875,7 +17410,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17371546210615613853
+          11856586713916442122
         ]
       ], 
       "reviewed-by-human": true
@@ -16896,7 +17431,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "reviewed-by-human": true
@@ -16905,7 +17440,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "reviewed-by-human": true
@@ -16914,7 +17449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2113206247214385098
+          9291687675247984765
         ]
       ], 
       "reviewed-by-human": true
@@ -16923,7 +17458,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14071403280264096223
+          14493378758991003394
         ]
       ], 
       "reviewed-by-human": true
@@ -16932,7 +17467,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16741507987193604094
+          16947177559920250893
         ]
       ], 
       "reviewed-by-human": true
@@ -16953,7 +17488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "reviewed-by-human": true
@@ -16962,7 +17497,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "reviewed-by-human": true
@@ -16971,7 +17506,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14510027867806755962
+          13673140479532038640
         ]
       ], 
       "reviewed-by-human": true
@@ -16980,7 +17515,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12146654658304155786
+          15576286174149035789
         ]
       ], 
       "reviewed-by-human": true
@@ -16989,7 +17524,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17031144438812250524
+          16258109186950173986
         ]
       ], 
       "reviewed-by-human": true
@@ -17355,58 +17890,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          1581438121274106176
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9884173386347087482
+          1933490657284787592
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10525579109813075137
+          17459659862280803801
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9884173386347087482
+          6667479893675462157
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -17424,58 +17947,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          2283035916243745030
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1609512922117613959
+          367167356747061080
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3490322557642337363
+          117706835416353038
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380899108733265481
+          6453538714645879627
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -17493,31 +18004,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          852960377597007352
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          1031488952720446379
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12889890156182669108
+          495886922968836878
         ]
       ], 
       "reviewed-by-human": true
@@ -17526,22 +18031,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18377760636939840560
+          14966470912654351144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          309877259595619467
+          9253606783225793790
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_pdf-poppler.png": {
       "allowed-digests": [
@@ -17751,58 +18253,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564656089209715121
+          4796295628459008767
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564656089209715121
+          15300564346213801791
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3720605705123675736
+          14465730655738711503
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -17889,58 +18379,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9425059496441527728
+          159004473548620887
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5089083539219748309
+          8104410590312662232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6772529533806073828
+          13706743646479427266
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17931259227737559526
+          12682715880467573944
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2029910099093282736
+          10781607431815735586
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -18294,7 +18772,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -18303,7 +18781,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -18312,7 +18790,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9400706697033338692
+          13764339996600437836
         ]
       ], 
       "reviewed-by-human": true
@@ -18321,7 +18799,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          237633552255702584
+          15536171010526909654
         ]
       ], 
       "reviewed-by-human": true
@@ -18330,7 +18808,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15481694980398014047
+          17890488678190568949
         ]
       ], 
       "reviewed-by-human": true
@@ -18515,62 +18993,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1131824196339345229
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -18588,28 +19099,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9407358693309761110
+          5829921135942844635
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -18642,10 +19153,7 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -18711,10 +19219,7 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -18753,58 +19258,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -18822,7 +19315,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -18831,7 +19324,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -18840,7 +19333,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          6048869515923073564
         ]
       ], 
       "reviewed-by-human": true
@@ -18849,7 +19342,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1559349726696617839
+          14734348706173171694
         ]
       ], 
       "reviewed-by-human": true
@@ -18858,7 +19351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          13986036354074897447
         ]
       ], 
       "reviewed-by-human": true
@@ -18879,58 +19372,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          16367101498658508972
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14603002718790540977
+          16751914431820491012
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          1205048549325125274
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -18948,7 +19429,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          4864263811791905685
         ]
       ], 
       "reviewed-by-human": true
@@ -18957,7 +19438,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          16801244478240186276
         ]
       ], 
       "reviewed-by-human": true
@@ -18966,7 +19447,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15641677254803875749
+          8757435387673298229
         ]
       ], 
       "reviewed-by-human": true
@@ -18975,7 +19456,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12233502021372539335
+          7513095271860536492
         ]
       ], 
       "reviewed-by-human": true
@@ -18984,7 +19465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          14598823216365008278
         ]
       ], 
       "reviewed-by-human": true
@@ -18993,7 +19474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5949714246508281820
         ]
       ], 
       "reviewed-by-human": true
@@ -19002,7 +19483,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5402764657976459291
         ]
       ], 
       "reviewed-by-human": true
@@ -19011,7 +19492,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13789919752467315906
+          8878476896705676612
         ]
       ], 
       "reviewed-by-human": true
@@ -19020,7 +19501,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          6996671819617945771
         ]
       ], 
       "reviewed-by-human": true
@@ -19041,7 +19522,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15641677254803875749
+          13498177505417262335
         ]
       ], 
       "reviewed-by-human": true
@@ -19131,7 +19612,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          1258363359136286164
         ]
       ], 
       "reviewed-by-human": true
@@ -19140,7 +19621,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          5399430353808909931
         ]
       ], 
       "reviewed-by-human": true
@@ -19149,7 +19630,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5092500482844467763
+          10977620141810635112
         ]
       ], 
       "reviewed-by-human": true
@@ -19158,7 +19639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7272353906741772982
+          10217664941927163150
         ]
       ], 
       "reviewed-by-human": true
@@ -19167,7 +19648,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15810556183767148552
+          5696450717885951386
         ]
       ], 
       "reviewed-by-human": true
@@ -19188,58 +19669,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          7451829304858435646
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -19257,94 +19726,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          9822393380242794213
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -19362,22 +19810,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          1794524931659012049
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -19391,6 +19836,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14238495105637549536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13091587407128414591
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2811772865778668658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7185018533082072769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9068081473418106350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6787753377476893062
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9066227969618021937
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7185018533082072769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13706090452902799076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9261209386788794091
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13592132854078956729
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16239445678573089230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7389120679870614644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8144110888506762127
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1546493394542600629
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16239445678573089230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -19503,43 +20128,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5483308942142720488
+          12997787133028120518
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4696340272245690277
+          4367857761078620058
         ]
       ], 
       "reviewed-by-human": true
@@ -19548,10 +20164,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7664082110143619089
+          6780241912548653043
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19569,58 +20185,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7796209920479635095
+          16932359230392749690
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14523815480948971483
+          3695036642112880517
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5911601511426755275
+          13167397400025502386
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -19638,18 +20242,26 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10262256877703773151
+          6183456328083498663
         ]
       ], 
+      "bugs": [
+        2775
+      ], 
+      "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
     "verylargebitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11880098846453637456
+          10492157671811011535
         ]
       ], 
+      "bugs": [
+        2775
+      ], 
+      "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
     "verylargebitmap_gpu.png": {
@@ -19701,58 +20313,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -19770,58 +20370,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          438558267463767125
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          6853497244680825166
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          962717882117070565
+          9083297924306753575
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          768763528917693850
+          4901741930957102676
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          962717882117070565
+          18343278898776537277
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19839,58 +20427,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          18005779299301055149
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          543837030557564588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9806700643412380727
+          14265963860216842340
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11875667066985540599
+          9782797996062068312
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9806700643412380727
+          10234504630630772106
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -19908,58 +20484,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          16976170622579387959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          3296931836447172845
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9113706558474041625
+          5944658117124283263
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1323079300068890978
+          7166884040512070986
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9113706558474041625
+          2432684250684813924
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -19972,6 +20536,33 @@
         1935
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win8-ShuttleA-GTX660-x86_64-Debug/expected-results.json b/expectations/gm/Test-Win8-ShuttleA-GTX660-x86_64-Debug/expected-results.json
index 59728b1..3c306cc 100644
--- a/expectations/gm/Test-Win8-ShuttleA-GTX660-x86_64-Debug/expected-results.json
+++ b/expectations/gm/Test-Win8-ShuttleA-GTX660-x86_64-Debug/expected-results.json
@@ -151,34 +151,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -331,58 +331,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          7593352410810558049
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          1175700925683069803
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          15415204559421796941
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          12035029927330392542
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          751809614678646951
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -396,6 +384,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -501,75 +534,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -736,34 +700,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -850,58 +808,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14652235513246564229
+          12449041092507757378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16245483467216489815
+          9087208410328931904
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4047354824627112796
+          908079640636796316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -988,58 +934,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          7812520044346961011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          12807763425550694757
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          10348011941932861480
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          10348011941932861480
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          5166570216456302933
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -1057,7 +991,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          3617797305044480555
         ]
       ], 
       "reviewed-by-human": true
@@ -1066,7 +1000,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          14987526374456897079
         ]
       ], 
       "reviewed-by-human": true
@@ -1075,7 +1009,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099769173772687975
+          1537092402026262432
         ]
       ], 
       "reviewed-by-human": true
@@ -1084,7 +1018,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1928858325393991739
+          10733498520612026154
         ]
       ], 
       "reviewed-by-human": true
@@ -1093,7 +1027,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099769173772687975
+          10651756436507454114
         ]
       ], 
       "reviewed-by-human": true
@@ -1321,58 +1255,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14029934813708721331
+          11476701287181118472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6379907739251348875
+          2800217968641110362
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -1453,58 +1375,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14934551414236827349
+          2874388734250092639
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16244994631386084477
+          15152103473812092421
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14934551414236827349
+          2874388734250092639
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -1540,28 +1450,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -1666,7 +1585,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
       "reviewed-by-human": true
@@ -4044,6 +3963,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -4306,25 +4270,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
       "reviewed-by-human": true
@@ -4338,6 +4302,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4411,58 +4420,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8976307978169070533
+          9715048358204914021
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15274361429663626659
+          10791718083342670060
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7361441850871240424
+          11226069113236569409
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -4576,58 +4573,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16508855522965628557
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -4645,58 +4630,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          7596334653042200982
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5806130805959000992
+          11076529384363630535
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          12683881210526887632
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -5473,58 +5446,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          660002910751114028
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15742069787955891275
+          5900403635120013876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          13340499774791895971
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -5680,58 +5641,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
@@ -6130,94 +6079,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          8059723840111543656
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          4022128344496177992
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13811349623686669396
+          12100412534735983468
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          7167682324595825921
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          1167106541986679122
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          484686002760255512
+          4977268569647138810
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9758791734243356840
+          7473120410450320644
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370661691515227788
+          11887374817081287579
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6235,22 +6163,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11906262362145726223
+          8406846183024424798
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10341156631225228790
+          1698813443589668875
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_pdf-poppler.png": {
       "allowed-digests": [
@@ -6268,94 +6193,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          3183371552229607548
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          3409717039232577306
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8717162927730913272
+          2057371307378029751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          14815312009812228022
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          9409727332382440449
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8704676340583221795
+          548631379086924810
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8562400821134319401
+          12844041116036912013
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13625518271740009316
+          9058223880734977500
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6373,22 +6277,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12058934008258379833
+          368988525699315975
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12805678179242111681
+          9726049292572177337
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -6514,46 +6415,50 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          479069169116054389
+          17121828245730015083
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8565104511668826829
+          17868394612177611310
         ]
       ], 
-      "reviewed-by-human": false
+      "bugs": [
+        2824
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16530634008647790653
+          7570814056450667246
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -6733,58 +6638,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          2396629361279121278
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          12144247543820336588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3386415177137025017
+          5390095926777602051
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18409257590792155660
+          15673049959189156070
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4965073552524677584
+          9808820959788087997
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6802,58 +6695,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4844524665660284305
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          5938003447863338066
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1918820825774442918
+          5087929812634018385
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5492952256259345052
+          8726256039731354406
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7050192252559156843
+          15223225239913271101
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -7093,7 +6974,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4903737309685329914
+          1395267708058780826
         ]
       ], 
       "reviewed-by-human": true
@@ -7186,58 +7067,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          8144433221544041893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          6901150638632819323
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7340746540294423206
+          9538730268883185427
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18428594076841281649
+          16675708267160231217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14161050065750911947
+          12734850694189703805
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -7255,58 +7124,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          15209085685049262946
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -7351,58 +7208,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -7420,58 +7265,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -7489,7 +7322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -7498,7 +7331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -7507,7 +7340,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7516,7 +7349,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16451780885896960300
+          14204243393620033211
         ]
       ], 
       "reviewed-by-human": true
@@ -7525,7 +7358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7546,58 +7379,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443130797061158720
+          3590945223549597113
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7615,58 +7436,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8034132364379362582
+          17212795401772012692
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7684,58 +7493,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15854240744220847964
+          12495564829829617636
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7753,7 +7550,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -7762,7 +7559,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -7771,7 +7568,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7780,7 +7577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61543217406202998
+          11968003402313032299
         ]
       ], 
       "reviewed-by-human": true
@@ -7789,7 +7586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7810,58 +7607,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2171610356153094701
+          8951768093676734731
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7879,58 +7664,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6692547324448596108
+          16032430115842971269
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7948,58 +7721,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12362918265113141584
+          352963511646887173
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -8017,7 +7778,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -8026,7 +7787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -8035,7 +7796,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
       "reviewed-by-human": true
@@ -8044,7 +7805,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6125556691115888800
+          16977393652065766378
         ]
       ], 
       "reviewed-by-human": true
@@ -8053,7 +7814,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
       "reviewed-by-human": true
@@ -8074,58 +7835,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14156869179031488870
+          7501369635627690776
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12495827092338238690
+          7692738176472808848
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14156869179031488870
+          7501369635627690776
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8143,58 +7892,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6871411400838133729
+          2835685519522776626
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8212,58 +7949,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16162216557075653007
+          2760623527115162554
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1243361506848516240
+          15670553619205431923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16162216557075653007
+          2760623527115162554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8281,13 +8006,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -8305,34 +8027,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13627205234939690742
+          14145109580428845757
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17686572383265746470
+          17938573218167752738
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11190272575141191020
+          14959282528007631804
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -8350,58 +8072,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          10560594815938292783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          12545797976096132621
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16944071921626269866
+          7296629561031831197
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17326759309207012859
+          6255577643368982288
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16944071921626269866
+          3875306556126405867
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -8419,58 +8129,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17641824294124384978
+          15926382706833037919
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13760859783463290994
+          289707744025360504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14118413545283346564
+          11324020305665756421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -8488,58 +8186,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10582819077805576685
+          51541207251928275
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10966410634478253303
+          15538638387135444952
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3032133295741624070
+          16953834221792082615
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8611,58 +8297,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          229562018395218460
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          12760426964160092214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7610947751291879266
+          5792779588987266181
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8907607835040622257
+          6530275130754592140
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5599646814156973739
+          451260416074786226
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8856,6 +8530,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -9187,7 +8906,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -9196,7 +8915,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -9244,7 +8963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -9253,7 +8972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -9307,7 +9026,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -9316,7 +9035,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -9370,7 +9089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -9379,7 +9098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -9433,7 +9152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -9442,7 +9161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -9496,7 +9215,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -9505,7 +9224,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -9559,7 +9278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -9568,7 +9287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -9622,7 +9341,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -9631,7 +9350,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -9685,7 +9404,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -9694,7 +9413,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -9811,7 +9530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -9820,7 +9539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -9874,58 +9593,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11574133982069711928
+          5532051404015186872
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2113348389489071842
+          13863379279912600675
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11574133982069711928
+          5532051404015186872
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -9943,7 +9650,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -9952,7 +9659,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -9961,34 +9668,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15302642444517196692
+          3271940701668668277
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5126343750573898991
+          8027294698161910767
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15302642444517196692
+          3271940701668668277
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -10006,7 +9707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15618220200870997449
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -10015,7 +9716,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10526671976174365374
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -10024,34 +9725,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1094828084143041922
+          6425288885008549863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1408513740171764116
+          11693284923582451238
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1094828084143041922
+          6425288885008549863
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -10065,209 +9760,212 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8305101852626451769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7779118070033093384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8305101852626451769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          14883457588515450185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5851939326059970416
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15546460357391099353
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14292646344952811693
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16542857918429840050
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          14287369518419556676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          14287369518419556676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          2085580649669581585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          922176307457717158
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          10200358509808425244
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          10200358509808425244
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          6738101046888470769
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -10285,31 +9983,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          13203594782216607040
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          15828501156207808430
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6038427216880721079
+          11929432714848218301
         ]
       ], 
       "reviewed-by-human": true
@@ -10318,19 +10010,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8356197894460139473
+          15767280341492508020
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11819142696872198617
+          10611437431422341640
         ]
       ], 
       "reviewed-by-human": true
@@ -10347,62 +10036,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3876782072761139785
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10667209145671721407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5352278316997662690
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1046694922283575432
+          7310201851346355510
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11179742213777376243
+          4376621845120437533
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1046694922283575432
+          14147609500698884768
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -10420,43 +10142,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17766273991942049288
+          17912233352232188365
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8020995970029089582
+          7335848171046712603
         ]
       ], 
       "reviewed-by-human": true
@@ -10465,10 +10178,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16518931243149906456
+          15543648061215744397
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -11310,6 +11023,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15889650838157198039
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14393949491637878306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7553968815810048260
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11769204272611093646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17839836921231752863
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7482589153229259850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9899853331722013852
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17326560431224736462
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6459206295890594330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8382915188572696476
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          363214432637750870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4514485822480600121
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16359544679338136257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2205365319218156147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10350633209557780455
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -11341,10 +11414,7 @@
           2515733614721864626
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -11473,7 +11543,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa16.png": {
       "allowed-digests": [
@@ -11527,7 +11597,7 @@
           16605120526645549774
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa16.png": {
       "allowed-digests": [
@@ -11581,7 +11651,7 @@
           169027135498041421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa16.png": {
       "allowed-digests": [
@@ -11908,7 +11978,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -11935,7 +12005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
       "reviewed-by-human": true
@@ -11965,58 +12035,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9262043821850989724
+          12751187030376887099
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17498929465580770598
+          15041389777883880577
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9262043821850989724
+          1194623239453375939
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12124,34 +12182,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -12223,7 +12281,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          2859104781692949426
         ]
       ], 
       "reviewed-by-human": true
@@ -12232,7 +12290,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          2670248603126936222
         ]
       ], 
       "reviewed-by-human": true
@@ -12241,7 +12299,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1502871433053621895
+          873535995353697759
         ]
       ], 
       "reviewed-by-human": true
@@ -12250,7 +12308,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4706028507622067827
+          17721745947522835626
         ]
       ], 
       "reviewed-by-human": true
@@ -12259,7 +12317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1502871433053621895
+          787908483793116578
         ]
       ], 
       "reviewed-by-human": true
@@ -12327,47 +12385,83 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8438243272047728234
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8438243272047728234
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7938559748189909140
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          14557198649976668882
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          13002044415183336403
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15061683733564186204
+          3429469574871335702
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          6559263086767964475
         ]
       ], 
       "reviewed-by-human": true
@@ -12376,7 +12470,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          14315647952979882955
         ]
       ], 
       "reviewed-by-human": true
@@ -12385,7 +12479,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5042747931564698790
+          10880379701383794584
         ]
       ], 
       "reviewed-by-human": true
@@ -12394,7 +12488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2688291096121197296
+          17408884944030048338
         ]
       ], 
       "reviewed-by-human": true
@@ -12403,10 +12497,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4771014495127026924
+          15911448479106757347
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
@@ -12421,22 +12515,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          122726789056295963
+          1537105960517213309
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15947771628835537481
+          7179091632218471759
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_pdf-poppler.png": {
       "allowed-digests": [
@@ -12454,41 +12545,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          10223214443700181285
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          10223214443700181285
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          18404005473374897414
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12502,58 +12598,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3300816044347370985
+          3518283227649716316
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6542871302874538158
+          14527201156012636147
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14627439817426003316
+          5516953276145914495
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -12673,58 +12757,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12913059478362291221
+          13596415401198873831
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6043577369810335263
+          17962675542424191142
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17401169737638319038
+          14044923836925531517
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -12742,58 +12814,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -12811,42 +12871,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3262803126131585722
+          13391508749678438749
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11426838740980958872
+          8382253584634947082
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9659350677391822056
+          1102950561799296746
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12860,58 +12924,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17073193087595049207
+          1321180911407859380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12394367286940416876
+          18069013584799504840
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13709606587202811817
+          5366191227041081961
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -12929,46 +12981,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          2462464065957440433
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12983,58 +13035,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          8797975763901838314
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -13106,58 +13146,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          1938473326245501278
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13199,34 +13227,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -13244,58 +13272,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -13367,58 +13383,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          4183511498011974903
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          10285833817111015220
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8200021215559120818
+          9202923584968077183
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16621163543038358032
+          9457661346008587898
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481364132226706053
+          3674694234040196508
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13436,58 +13440,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          9263713892251900876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          3699172046262487290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17364323165819274082
+          1243570489849511690
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8542930727646104844
+          17006239057979777374
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6362537695706148742
+          1527267847491917447
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13505,58 +13497,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          15807341393622522232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          6484758485740569522
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8099618297706003570
+          13672413721263802056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12717738459185687769
+          7264182713172897674
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12424363096228788735
+          16626294912432257339
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13574,58 +13554,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -13721,7 +13689,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13730,7 +13698,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13739,7 +13707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13784,7 +13752,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13793,7 +13761,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13802,7 +13770,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13847,7 +13815,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13856,7 +13824,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13865,7 +13833,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13964,34 +13932,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -14009,58 +13977,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -14074,6 +14030,456 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -14351,58 +14757,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1201553558635803052
+          5602760436216664605
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -14444,34 +14838,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -14551,62 +14945,140 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5738277652531841246
+          13432295925256731908
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7995388484637533091
+          9421281174921218201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11836133234466138290
+          12770815845542827504
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_pdf-poppler.png": {
       "allowed-digests": [
@@ -15089,7 +15561,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -15098,7 +15570,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -15107,16 +15579,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2934804817352937872
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15125,7 +15642,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15146,58 +15663,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          17506817297106108685
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15211,6 +15716,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -15265,6 +15815,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -15332,43 +15927,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          14919179564192850472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          6704764580322283111
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16504108627280647914
+          11044759503191387491
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15755700643078617599
+          17439478692444443893
         ]
       ], 
       "reviewed-by-human": true
@@ -15377,10 +15963,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14430759865428982597
+          8648676323088729372
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -15464,58 +16050,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          18104496854197341496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          6952495213922076627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17174790409763084733
+          16945286131909290674
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5132409693689837643
+          10086078156008471061
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18400817843938057493
+          7580933693393515476
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15533,58 +16107,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          11795498474298281319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          14297982111593447018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11798651298936594976
+          6963242957620421884
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2886396052067032686
+          4271409036060367806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768414447821598463
+          3142395726537453688
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15689,34 +16251,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -15755,10 +16317,7 @@
           11339980900210544915
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -16332,58 +16891,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14684491285852381433
+          13065162206529155581
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8023336521280369497
+          4059069468906277635
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4439825578385779753
+          13474389573104079912
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -16401,7 +16948,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -16410,7 +16957,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -16419,7 +16966,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          6048869515923073564
         ]
       ], 
       "reviewed-by-human": true
@@ -16428,7 +16975,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1559349726696617839
+          14734348706173171694
         ]
       ], 
       "reviewed-by-human": true
@@ -16437,7 +16984,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          13986036354074897447
         ]
       ], 
       "reviewed-by-human": true
@@ -16458,58 +17005,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          16367101498658508972
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14603002718790540977
+          16751914431820491012
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          1205048549325125274
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -16527,7 +17062,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          18140335162380255225
         ]
       ], 
       "reviewed-by-human": true
@@ -16536,7 +17071,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          7129698125485750601
         ]
       ], 
       "reviewed-by-human": true
@@ -16545,7 +17080,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4156481340570717959
+          13719342871832399838
         ]
       ], 
       "reviewed-by-human": true
@@ -16554,7 +17089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12705698943369055239
+          5248743086217192530
         ]
       ], 
       "reviewed-by-human": true
@@ -16563,7 +17098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16281098760671026549
         ]
       ], 
       "reviewed-by-human": true
@@ -16572,7 +17107,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          13530435022292494762
         ]
       ], 
       "reviewed-by-human": true
@@ -16581,7 +17116,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13131209168116653631
+          13814877700654806883
         ]
       ], 
       "reviewed-by-human": true
@@ -16590,7 +17125,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548364158761522774
+          16624590309946972209
         ]
       ], 
       "reviewed-by-human": true
@@ -16599,7 +17134,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13131209168116653631
+          12492815789504654915
         ]
       ], 
       "reviewed-by-human": true
@@ -16620,7 +17155,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4156481340570717959
+          14838890993150454189
         ]
       ], 
       "reviewed-by-human": true
@@ -16848,7 +17383,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          3831063373917728128
         ]
       ], 
       "reviewed-by-human": true
@@ -16857,7 +17392,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11081789658344209328
+          10497222257759782905
         ]
       ], 
       "reviewed-by-human": true
@@ -16866,7 +17401,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6304960047606523701
+          6509695928299095478
         ]
       ], 
       "reviewed-by-human": true
@@ -16875,7 +17410,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17371546210615613853
+          11856586713916442122
         ]
       ], 
       "reviewed-by-human": true
@@ -16896,7 +17431,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "reviewed-by-human": true
@@ -16905,7 +17440,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "reviewed-by-human": true
@@ -16914,7 +17449,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2113206247214385098
+          9291687675247984765
         ]
       ], 
       "reviewed-by-human": true
@@ -16923,7 +17458,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14071403280264096223
+          14493378758991003394
         ]
       ], 
       "reviewed-by-human": true
@@ -16932,7 +17467,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16741507987193604094
+          16947177559920250893
         ]
       ], 
       "reviewed-by-human": true
@@ -16953,7 +17488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "reviewed-by-human": true
@@ -16962,7 +17497,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "reviewed-by-human": true
@@ -16971,7 +17506,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14510027867806755962
+          13673140479532038640
         ]
       ], 
       "reviewed-by-human": true
@@ -16980,7 +17515,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12146654658304155786
+          15576286174149035789
         ]
       ], 
       "reviewed-by-human": true
@@ -16989,7 +17524,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17031144438812250524
+          16258109186950173986
         ]
       ], 
       "reviewed-by-human": true
@@ -17355,58 +17890,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          1581438121274106176
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9884173386347087482
+          1933490657284787592
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10525579109813075137
+          17459659862280803801
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9884173386347087482
+          6667479893675462157
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -17424,58 +17947,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          2283035916243745030
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1609512922117613959
+          367167356747061080
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3490322557642337363
+          117706835416353038
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380899108733265481
+          6453538714645879627
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -17493,31 +18004,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          852960377597007352
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          1031488952720446379
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12889890156182669108
+          495886922968836878
         ]
       ], 
       "reviewed-by-human": true
@@ -17526,22 +18031,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18377760636939840560
+          14966470912654351144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          309877259595619467
+          9253606783225793790
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_pdf-poppler.png": {
       "allowed-digests": [
@@ -17751,58 +18253,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564656089209715121
+          4796295628459008767
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564656089209715121
+          15300564346213801791
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3720605705123675736
+          14465730655738711503
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -17889,58 +18379,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9425059496441527728
+          159004473548620887
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5089083539219748309
+          8104410590312662232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6772529533806073828
+          13706743646479427266
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17931259227737559526
+          12682715880467573944
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2029910099093282736
+          10781607431815735586
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -18294,7 +18772,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -18303,7 +18781,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -18312,7 +18790,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9400706697033338692
+          13764339996600437836
         ]
       ], 
       "reviewed-by-human": true
@@ -18321,7 +18799,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          237633552255702584
+          15536171010526909654
         ]
       ], 
       "reviewed-by-human": true
@@ -18330,7 +18808,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15481694980398014047
+          17890488678190568949
         ]
       ], 
       "reviewed-by-human": true
@@ -18515,62 +18993,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1131824196339345229
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -18588,28 +19099,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9407358693309761110
+          5829921135942844635
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -18642,10 +19153,7 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -18711,10 +19219,7 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -18753,58 +19258,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -18822,7 +19315,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -18831,7 +19324,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -18840,7 +19333,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          6048869515923073564
         ]
       ], 
       "reviewed-by-human": true
@@ -18849,7 +19342,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1559349726696617839
+          14734348706173171694
         ]
       ], 
       "reviewed-by-human": true
@@ -18858,7 +19351,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          13986036354074897447
         ]
       ], 
       "reviewed-by-human": true
@@ -18879,58 +19372,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          16367101498658508972
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14603002718790540977
+          16751914431820491012
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          1205048549325125274
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -18948,7 +19429,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          4864263811791905685
         ]
       ], 
       "reviewed-by-human": true
@@ -18957,7 +19438,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          16801244478240186276
         ]
       ], 
       "reviewed-by-human": true
@@ -18966,7 +19447,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15641677254803875749
+          8757435387673298229
         ]
       ], 
       "reviewed-by-human": true
@@ -18975,7 +19456,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12233502021372539335
+          7513095271860536492
         ]
       ], 
       "reviewed-by-human": true
@@ -18984,7 +19465,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          14598823216365008278
         ]
       ], 
       "reviewed-by-human": true
@@ -18993,7 +19474,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5949714246508281820
         ]
       ], 
       "reviewed-by-human": true
@@ -19002,7 +19483,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5402764657976459291
         ]
       ], 
       "reviewed-by-human": true
@@ -19011,7 +19492,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13789919752467315906
+          8878476896705676612
         ]
       ], 
       "reviewed-by-human": true
@@ -19020,7 +19501,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          6996671819617945771
         ]
       ], 
       "reviewed-by-human": true
@@ -19041,7 +19522,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15641677254803875749
+          13498177505417262335
         ]
       ], 
       "reviewed-by-human": true
@@ -19131,7 +19612,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          1258363359136286164
         ]
       ], 
       "reviewed-by-human": true
@@ -19140,7 +19621,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          5399430353808909931
         ]
       ], 
       "reviewed-by-human": true
@@ -19149,7 +19630,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5092500482844467763
+          10977620141810635112
         ]
       ], 
       "reviewed-by-human": true
@@ -19158,7 +19639,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7272353906741772982
+          10217664941927163150
         ]
       ], 
       "reviewed-by-human": true
@@ -19167,7 +19648,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15810556183767148552
+          5696450717885951386
         ]
       ], 
       "reviewed-by-human": true
@@ -19188,58 +19669,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          7451829304858435646
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -19257,94 +19726,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          9822393380242794213
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -19362,22 +19810,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          1794524931659012049
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -19391,6 +19836,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14238495105637549536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13091587407128414591
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2811772865778668658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7185018533082072769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9068081473418106350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6787753377476893062
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9066227969618021937
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7185018533082072769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13706090452902799076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9261209386788794091
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13592132854078956729
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16239445678573089230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7389120679870614644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8144110888506762127
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1546493394542600629
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16239445678573089230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -19503,43 +20128,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5483308942142720488
+          12997787133028120518
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4696340272245690277
+          4367857761078620058
         ]
       ], 
       "reviewed-by-human": true
@@ -19548,10 +20164,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7664082110143619089
+          6780241912548653043
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19569,58 +20185,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7796209920479635095
+          16932359230392749690
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14523815480948971483
+          3695036642112880517
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5911601511426755275
+          13167397400025502386
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -19707,58 +20311,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -19776,58 +20368,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          438558267463767125
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          6853497244680825166
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          962717882117070565
+          9083297924306753575
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          768763528917693850
+          4901741930957102676
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          962717882117070565
+          18343278898776537277
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19845,58 +20425,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          18005779299301055149
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          543837030557564588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9806700643412380727
+          14265963860216842340
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11875667066985540599
+          9782797996062068312
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9806700643412380727
+          10234504630630772106
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -19914,58 +20482,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          16976170622579387959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          3296931836447172845
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9113706558474041625
+          5944658117124283263
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1323079300068890978
+          7166884040512070986
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9113706558474041625
+          2432684250684813924
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -19978,6 +20534,33 @@
         1935
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win8-ShuttleA-GTX660-x86_64-Release/expected-results.json b/expectations/gm/Test-Win8-ShuttleA-GTX660-x86_64-Release/expected-results.json
index ec83ba6..22baa8d 100644
--- a/expectations/gm/Test-Win8-ShuttleA-GTX660-x86_64-Release/expected-results.json
+++ b/expectations/gm/Test-Win8-ShuttleA-GTX660-x86_64-Release/expected-results.json
@@ -151,34 +151,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6264358317394269317
+          5361673090383820149
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7182621384544392279
+          3770567129781642033
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10787414641951246795
+          10856546368486015793
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -331,58 +331,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          7593352410810558049
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          1175700925683069803
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          15415204559421796941
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          12035029927330392542
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3261753940083266931
+          751809614678646951
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -396,6 +384,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -501,75 +534,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_msaa16.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          16647433105813638439
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_nvprmsaa4.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          14528482862946863016
-        ]
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -736,34 +700,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          8741984205182434161
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17620776907435730050
+          6463895742034431573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1822195599289208664
+          3635090355061860852
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -850,58 +808,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14652235513246564229
+          12449041092507757378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16245483467216489815
+          9087208410328931904
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4047354824627112796
+          908079640636796316
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -988,58 +934,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          7812520044346961011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          12807763425550694757
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          10348011941932861480
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          10348011941932861480
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          5166570216456302933
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -1057,7 +991,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          3617797305044480555
         ]
       ], 
       "reviewed-by-human": true
@@ -1066,7 +1000,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          14987526374456897079
         ]
       ], 
       "reviewed-by-human": true
@@ -1075,7 +1009,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099769173772687975
+          1537092402026262432
         ]
       ], 
       "reviewed-by-human": true
@@ -1084,7 +1018,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1928858325393991739
+          10733498520612026154
         ]
       ], 
       "reviewed-by-human": true
@@ -1093,7 +1027,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099769173772687975
+          10651756436507454114
         ]
       ], 
       "reviewed-by-human": true
@@ -1321,58 +1255,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14029934813708721331
+          11476701287181118472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6379907739251348875
+          2800217968641110362
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -1453,58 +1375,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14934551414236827349
+          2874388734250092639
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16244994631386084477
+          15152103473812092421
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14934551414236827349
+          2874388734250092639
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -1540,28 +1450,37 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15932099923878777235
+          13014075482864288220
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10134098955798538896
+          17870693939301194374
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -1666,7 +1585,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4423698801691949037
+          64400470544822501
         ]
       ], 
       "reviewed-by-human": true
@@ -4044,6 +3963,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14959184435044560366
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -4306,25 +4270,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17273108520052589230
+          3305918433026350742
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2179491647235836681
+          12624863915440686736
         ]
       ], 
       "reviewed-by-human": true
@@ -4338,6 +4302,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5150056817584634445
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1907907583112016008
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12210721514739080593
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -4411,58 +4420,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8976307978169070533
+          9715048358204914021
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15274361429663626659
+          10791718083342670060
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7361441850871240424
+          11226069113236569409
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -4576,58 +4573,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16508855522965628557
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -4645,58 +4630,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          7596334653042200982
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5806130805959000992
+          11076529384363630535
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          12683881210526887632
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -5473,58 +5446,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          660002910751114028
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15742069787955891275
+          5900403635120013876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7722630561533572129
+          13340499774791895971
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -5680,58 +5641,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7501060753807376568
+          7760022190728266716
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
@@ -6130,94 +6079,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          8059723840111543656
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          4022128344496177992
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13811349623686669396
+          12100412534735983468
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          7167682324595825921
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          1167106541986679122
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          484686002760255512
+          4977268569647138810
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9758791734243356840
+          7473120410450320644
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13370661691515227788
+          11887374817081287579
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6235,22 +6163,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11906262362145726223
+          8406846183024424798
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10341156631225228790
+          1698813443589668875
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_pdf-poppler.png": {
       "allowed-digests": [
@@ -6268,94 +6193,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          3183371552229607548
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          3409717039232577306
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8717162927730913272
+          2057371307378029751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          14815312009812228022
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          9409727332382440449
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8704676340583221795
+          548631379086924810
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8562400821134319401
+          12844041116036912013
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13625518271740009316
+          9058223880734977500
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -6373,22 +6277,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12058934008258379833
+          368988525699315975
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12805678179242111681
+          9726049292572177337
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_pdf-poppler.png": {
       "allowed-digests": [
@@ -6514,46 +6415,50 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          479069169116054389
+          17121828245730015083
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8565104511668826829
+          8627394447232319577
         ]
       ], 
-      "reviewed-by-human": false
+      "bugs": [
+        2824
+      ], 
+      "ignore-failure": true, 
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16530634008647790653
+          7570814056450667246
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -6733,58 +6638,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          2396629361279121278
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          12144247543820336588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3386415177137025017
+          5390095926777602051
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18409257590792155660
+          15673049959189156070
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4965073552524677584
+          9808820959788087997
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6802,58 +6695,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4844524665660284305
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          5938003447863338066
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1918820825774442918
+          5087929812634018385
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5492952256259345052
+          8726256039731354406
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7050192252559156843
+          15223225239913271101
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -7093,7 +6974,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4903737309685329914
+          1395267708058780826
         ]
       ], 
       "reviewed-by-human": true
@@ -7186,58 +7067,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          8144433221544041893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          6901150638632819323
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7340746540294423206
+          9538730268883185427
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18428594076841281649
+          16675708267160231217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14161050065750911947
+          12734850694189703805
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_pdf-poppler.png": {
       "allowed-digests": [
@@ -7255,58 +7124,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          15209085685049262946
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -7351,58 +7208,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -7420,58 +7265,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -7489,7 +7322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -7498,7 +7331,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -7507,7 +7340,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7516,7 +7349,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16451780885896960300
+          14204243393620033211
         ]
       ], 
       "reviewed-by-human": true
@@ -7525,7 +7358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
       "reviewed-by-human": true
@@ -7546,58 +7379,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16443130797061158720
+          3590945223549597113
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2972193426634768127
+          4417265118328754927
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7615,58 +7436,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8034132364379362582
+          17212795401772012692
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5277999924748275029
+          3280894626320084909
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7684,58 +7493,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15854240744220847964
+          12495564829829617636
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251100339010349543
+          4669810823447720319
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -7753,7 +7550,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -7762,7 +7559,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -7771,7 +7568,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7780,7 +7577,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          61543217406202998
+          11968003402313032299
         ]
       ], 
       "reviewed-by-human": true
@@ -7789,7 +7586,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
       "reviewed-by-human": true
@@ -7810,58 +7607,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2171610356153094701
+          8951768093676734731
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8552976708912667222
+          9714755284879996124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7879,58 +7664,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6692547324448596108
+          16032430115842971269
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5006319602237852337
+          18232159459512256382
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -7948,58 +7721,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12362918265113141584
+          352963511646887173
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14740888209109309852
+          9499136896577531799
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -8017,7 +7778,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -8026,7 +7787,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -8035,7 +7796,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
       "reviewed-by-human": true
@@ -8044,7 +7805,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6125556691115888800
+          16977393652065766378
         ]
       ], 
       "reviewed-by-human": true
@@ -8053,7 +7814,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
       "reviewed-by-human": true
@@ -8074,58 +7835,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14156869179031488870
+          7501369635627690776
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12495827092338238690
+          7692738176472808848
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14156869179031488870
+          7501369635627690776
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8143,58 +7892,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6871411400838133729
+          2835685519522776626
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7928106482960753428
+          15008794787823887487
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8212,58 +7949,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16162216557075653007
+          2760623527115162554
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1243361506848516240
+          15670553619205431923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16162216557075653007
+          2760623527115162554
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -8281,13 +8006,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -8305,34 +8027,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13627205234939690742
+          14145109580428845757
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17686572383265746470
+          17938573218167752738
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11190272575141191020
+          14959282528007631804
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -8350,58 +8072,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          10560594815938292783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          12545797976096132621
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16944071921626269866
+          7296629561031831197
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17326759309207012859
+          6255577643368982288
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16944071921626269866
+          3875306556126405867
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -8419,58 +8129,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17641824294124384978
+          15926382706833037919
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13760859783463290994
+          289707744025360504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14118413545283346564
+          11324020305665756421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -8488,58 +8186,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10582819077805576685
+          51541207251928275
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10966410634478253303
+          15538638387135444952
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3032133295741624070
+          16953834221792082615
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -8611,58 +8297,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          229562018395218460
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          12760426964160092214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7610947751291879266
+          5792779588987266181
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8907607835040622257
+          6530275130754592140
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5599646814156973739
+          451260416074786226
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -8856,6 +8530,51 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -9187,7 +8906,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -9196,7 +8915,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -9244,7 +8963,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -9253,7 +8972,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -9307,7 +9026,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -9316,7 +9035,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -9370,7 +9089,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -9379,7 +9098,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -9433,7 +9152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -9442,7 +9161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -9496,7 +9215,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -9505,7 +9224,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -9559,7 +9278,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -9568,7 +9287,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -9622,7 +9341,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -9631,7 +9350,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -9685,7 +9404,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -9694,7 +9413,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -9811,7 +9530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -9820,7 +9539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -9874,58 +9593,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11574133982069711928
+          5532051404015186872
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2113348389489071842
+          13863379279912600675
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11574133982069711928
+          5532051404015186872
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -9943,7 +9650,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -9952,7 +9659,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -9961,34 +9668,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15302642444517196692
+          3271940701668668277
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5126343750573898991
+          8027294698161910767
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15302642444517196692
+          3271940701668668277
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -10006,7 +9707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15618220200870997449
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -10015,7 +9716,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10526671976174365374
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -10024,34 +9725,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1094828084143041922
+          6425288885008549863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1408513740171764116
+          11693284923582451238
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1094828084143041922
+          6425288885008549863
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -10065,209 +9760,212 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8305101852626451769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7779118070033093384
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8305101852626451769
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          16278344162205895265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontcache_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4293340861720868561
+          14883457588515450185
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5851939326059970416
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15546460357391099353
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14292646344952811693
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16542857918429840050
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380248589656005503
+          14287369518419556676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          5588217583560643377
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16089754232477461561
+          14287369518419556676
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          2085580649669581585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          922176307457717158
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          10200358509808425244
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          10200358509808425244
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5543625173929768932
+          6738101046888470769
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -10285,31 +9983,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          13203594782216607040
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          15828501156207808430
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6038427216880721079
+          11929432714848218301
         ]
       ], 
       "reviewed-by-human": true
@@ -10318,19 +10010,16 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8356197894460139473
+          15767280341492508020
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11819142696872198617
+          10611437431422341640
         ]
       ], 
       "reviewed-by-human": true
@@ -10347,62 +10036,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3876782072761139785
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10667209145671721407
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5352278316997662690
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1046694922283575432
+          7310201851346355510
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11179742213777376243
+          4376621845120437533
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1046694922283575432
+          14147609500698884768
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -10420,43 +10142,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17766273991942049288
+          17912233352232188365
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8020995970029089582
+          7335848171046712603
         ]
       ], 
       "reviewed-by-human": true
@@ -10465,10 +10178,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16518931243149906456
+          15543648061215744397
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -11310,6 +11023,366 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15889650838157198039
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14393949491637878306
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7553968815810048260
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11769204272611093646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17839836921231752863
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7482589153229259850
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9899853331722013852
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17326560431224736462
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6459206295890594330
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1306189972263268656
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4649945233724185359
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17478635869814805063
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8382915188572696476
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          363214432637750870
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4514485822480600121
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16359544679338136257
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2205365319218156147
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10350633209557780455
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -11341,10 +11414,7 @@
           2515733614721864626
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_msaa16.png": {
       "allowed-digests": [
@@ -11473,7 +11543,7 @@
           5985102520168480975
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_msaa16.png": {
       "allowed-digests": [
@@ -11527,7 +11597,7 @@
           16605120526645549774
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_msaa16.png": {
       "allowed-digests": [
@@ -11581,7 +11651,7 @@
           169027135498041421
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_msaa16.png": {
       "allowed-digests": [
@@ -11908,7 +11978,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -11935,7 +12005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12251179949487160659
+          16307177227728636543
         ]
       ], 
       "reviewed-by-human": true
@@ -11965,58 +12035,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9262043821850989724
+          12751187030376887099
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17498929465580770598
+          15041389777883880577
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9262043821850989724
+          1194623239453375939
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -12124,34 +12182,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8404168600142393187
+          7836212725887477706
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12702798999143893321
+          15416135243961642681
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hairmodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12127494652108138591
+          17201093324020423129
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -12223,7 +12281,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          2859104781692949426
         ]
       ], 
       "reviewed-by-human": true
@@ -12232,7 +12290,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          2670248603126936222
         ]
       ], 
       "reviewed-by-human": true
@@ -12241,7 +12299,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1502871433053621895
+          873535995353697759
         ]
       ], 
       "reviewed-by-human": true
@@ -12250,7 +12308,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4706028507622067827
+          17721745947522835626
         ]
       ], 
       "reviewed-by-human": true
@@ -12259,7 +12317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1502871433053621895
+          787908483793116578
         ]
       ], 
       "reviewed-by-human": true
@@ -12327,47 +12385,83 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8438243272047728234
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8438243272047728234
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7938559748189909140
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          14557198649976668882
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          13002044415183336403
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15061683733564186204
+          3429469574871335702
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          6559263086767964475
         ]
       ], 
       "reviewed-by-human": true
@@ -12376,7 +12470,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          14315647952979882955
         ]
       ], 
       "reviewed-by-human": true
@@ -12385,7 +12479,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5042747931564698790
+          10880379701383794584
         ]
       ], 
       "reviewed-by-human": true
@@ -12394,7 +12488,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2688291096121197296
+          17408884944030048338
         ]
       ], 
       "reviewed-by-human": true
@@ -12403,10 +12497,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4771014495127026924
+          15911448479106757347
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_pdf-poppler.png": {
       "allowed-digests": [
@@ -12421,22 +12515,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          122726789056295963
+          1537105960517213309
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15947771628835537481
+          7179091632218471759
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_pdf-poppler.png": {
       "allowed-digests": [
@@ -12454,41 +12545,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          10223214443700181285
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          10223214443700181285
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11275946822720025788
+          18404005473374897414
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12502,58 +12598,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3300816044347370985
+          3518283227649716316
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6542871302874538158
+          14527201156012636147
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14627439817426003316
+          5516953276145914495
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_pdf-poppler.png": {
       "allowed-digests": [
@@ -12673,58 +12757,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12913059478362291221
+          13596415401198873831
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6043577369810335263
+          17962675542424191142
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17401169737638319038
+          14044923836925531517
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -12742,58 +12814,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11412718429517550075
+          12922640840671259677
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -12811,42 +12871,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3262803126131585722
+          13391508749678438749
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11426838740980958872
+          8382253584634947082
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9659350677391822056
+          1102950561799296746
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12860,58 +12924,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17073193087595049207
+          1321180911407859380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12394367286940416876
+          18069013584799504840
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13709606587202811817
+          5366191227041081961
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -12929,46 +12981,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          2462464065957440433
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -12983,58 +13035,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          4741875322934522959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          8797975763901838314
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -13106,58 +13146,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          8728476020428093247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17910577862166221122
+          1938473326245501278
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13199,34 +13227,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7644615105063909095
+          4337305683950474221
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7322423701581962313
+          9267399652224228185
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4430448241326881541
+          1428546987899351483
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -13244,58 +13272,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12224813748530188784
+          12510331047165839500
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -13367,58 +13383,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          4183511498011974903
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          10285833817111015220
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8200021215559120818
+          9202923584968077183
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16621163543038358032
+          9457661346008587898
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3481364132226706053
+          3674694234040196508
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13436,58 +13440,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          9263713892251900876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          3699172046262487290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17364323165819274082
+          1243570489849511690
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8542930727646104844
+          17006239057979777374
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6362537695706148742
+          1527267847491917447
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -13505,58 +13497,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          15807341393622522232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          6484758485740569522
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8099618297706003570
+          13672413721263802056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12717738459185687769
+          7264182713172897674
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12424363096228788735
+          16626294912432257339
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13574,58 +13554,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5933175092518834108
+          14816356732233544604
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -13721,7 +13689,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13730,7 +13698,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13739,7 +13707,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13784,7 +13752,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13793,7 +13761,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13802,7 +13770,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13847,7 +13815,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9052518098699698650
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13856,7 +13824,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          15858100026349596240
         ]
       ], 
       "reviewed-by-human": true
@@ -13865,7 +13833,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10769322296615755298
+          9244974085600588614
         ]
       ], 
       "reviewed-by-human": true
@@ -13964,34 +13932,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          12218867104690768584
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8415259505554733417
+          13540332316670655625
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -14009,58 +13977,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -14074,6 +14030,456 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17741005818411834677
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9265612574044352620
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9795158717889443937
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4626545367635596414
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12182100514519640149
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8026646935734061548
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8681193181351362655
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1521738858804611916
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2868425547375505945
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2855399770388364001
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18373414443815003066
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2708646018226064405
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17792848192245761365
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2217637002980097951
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4282144583097941660
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17915085302147104474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12721205378987728138
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6994515551393190984
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5735731041994535982
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4003653857191144688
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4539109860379960157
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10368005618861010562
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7502872607664881015
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11353001553943716738
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4901562284897753449
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11895928500676038290
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -14351,58 +14757,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1201553558635803052
+          5602760436216664605
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3509650711398249196
+          16347156219649766987
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -14444,34 +14838,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8127642505197276510
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          9183725853792620789
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -14551,62 +14945,140 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7156892847473324055
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11819100036740887047
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5026331788182910252
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10100563470575930000
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14630928668948889801
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5738277652531841246
+          13432295925256731908
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7995388484637533091
+          9421281174921218201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11836133234466138290
+          12770815845542827504
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_pdf-poppler.png": {
       "allowed-digests": [
@@ -15089,7 +15561,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -15098,7 +15570,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -15107,16 +15579,61 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13707735959203445530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2934804817352937872
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15125,7 +15642,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          734948878473953699
+          17028129281110104643
         ]
       ], 
       "reviewed-by-human": true
@@ -15146,58 +15663,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          17506817297106108685
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -15211,6 +15716,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12928401000246596270
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -15265,6 +15815,51 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -15332,43 +15927,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          14919179564192850472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          6704764580322283111
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16504108627280647914
+          11044759503191387491
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15755700643078617599
+          17439478692444443893
         ]
       ], 
       "reviewed-by-human": true
@@ -15377,10 +15963,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14430759865428982597
+          8648676323088729372
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -15464,58 +16050,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          18104496854197341496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          6952495213922076627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17174790409763084733
+          16945286131909290674
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5132409693689837643
+          10086078156008471061
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18400817843938057493
+          7580933693393515476
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15533,58 +16107,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          11795498474298281319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          14297982111593447018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11798651298936594976
+          6963242957620421884
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2886396052067032686
+          4271409036060367806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14768414447821598463
+          3142395726537453688
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -15689,34 +16251,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9166505397491645236
+          227457349309358061
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2647944145708871231
+          14941464582660867910
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -15755,10 +16317,7 @@
           11339980900210544915
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_msaa16.png": {
       "allowed-digests": [
@@ -16333,58 +16892,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14684491285852381433
+          13065162206529155581
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8023336521280369497
+          4059069468906277635
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4439825578385779753
+          13474389573104079912
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -16402,7 +16949,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -16411,7 +16958,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -16420,7 +16967,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          6048869515923073564
         ]
       ], 
       "reviewed-by-human": true
@@ -16429,7 +16976,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1559349726696617839
+          14734348706173171694
         ]
       ], 
       "reviewed-by-human": true
@@ -16438,7 +16985,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          13986036354074897447
         ]
       ], 
       "reviewed-by-human": true
@@ -16459,58 +17006,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          16367101498658508972
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14603002718790540977
+          16751914431820491012
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          1205048549325125274
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -16528,7 +17063,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          18140335162380255225
         ]
       ], 
       "reviewed-by-human": true
@@ -16537,7 +17072,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          7129698125485750601
         ]
       ], 
       "reviewed-by-human": true
@@ -16546,7 +17081,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4156481340570717959
+          13719342871832399838
         ]
       ], 
       "reviewed-by-human": true
@@ -16555,7 +17090,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12705698943369055239
+          5248743086217192530
         ]
       ], 
       "reviewed-by-human": true
@@ -16564,7 +17099,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16281098760671026549
         ]
       ], 
       "reviewed-by-human": true
@@ -16573,7 +17108,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          13530435022292494762
         ]
       ], 
       "reviewed-by-human": true
@@ -16582,7 +17117,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13131209168116653631
+          13814877700654806883
         ]
       ], 
       "reviewed-by-human": true
@@ -16591,7 +17126,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548364158761522774
+          16624590309946972209
         ]
       ], 
       "reviewed-by-human": true
@@ -16600,7 +17135,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13131209168116653631
+          12492815789504654915
         ]
       ], 
       "reviewed-by-human": true
@@ -16621,7 +17156,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4156481340570717959
+          14838890993150454189
         ]
       ], 
       "reviewed-by-human": true
@@ -16849,7 +17384,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          3831063373917728128
         ]
       ], 
       "reviewed-by-human": true
@@ -16858,7 +17393,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11081789658344209328
+          10497222257759782905
         ]
       ], 
       "reviewed-by-human": true
@@ -16867,7 +17402,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6304960047606523701
+          6509695928299095478
         ]
       ], 
       "reviewed-by-human": true
@@ -16876,7 +17411,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17371546210615613853
+          11856586713916442122
         ]
       ], 
       "reviewed-by-human": true
@@ -16897,7 +17432,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "reviewed-by-human": true
@@ -16906,7 +17441,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "reviewed-by-human": true
@@ -16915,7 +17450,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2113206247214385098
+          9291687675247984765
         ]
       ], 
       "reviewed-by-human": true
@@ -16924,7 +17459,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14071403280264096223
+          14493378758991003394
         ]
       ], 
       "reviewed-by-human": true
@@ -16933,7 +17468,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16741507987193604094
+          16947177559920250893
         ]
       ], 
       "reviewed-by-human": true
@@ -16954,7 +17489,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "reviewed-by-human": true
@@ -16963,7 +17498,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "reviewed-by-human": true
@@ -16972,7 +17507,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14510027867806755962
+          13673140479532038640
         ]
       ], 
       "reviewed-by-human": true
@@ -16981,7 +17516,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12146654658304155786
+          15576286174149035789
         ]
       ], 
       "reviewed-by-human": true
@@ -16990,7 +17525,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17031144438812250524
+          16258109186950173986
         ]
       ], 
       "reviewed-by-human": true
@@ -17356,58 +17891,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          1581438121274106176
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9884173386347087482
+          1933490657284787592
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10525579109813075137
+          17459659862280803801
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9884173386347087482
+          6667479893675462157
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -17425,58 +17948,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          2283035916243745030
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1609512922117613959
+          367167356747061080
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3490322557642337363
+          117706835416353038
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2380899108733265481
+          6453538714645879627
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -17494,31 +18005,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          852960377597007352
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          1031488952720446379
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12889890156182669108
+          495886922968836878
         ]
       ], 
       "reviewed-by-human": true
@@ -17527,22 +18032,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18377760636939840560
+          14966470912654351144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          309877259595619467
+          9253606783225793790
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_pdf-poppler.png": {
       "allowed-digests": [
@@ -17752,58 +18254,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564656089209715121
+          4796295628459008767
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2564656089209715121
+          15300564346213801791
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3720605705123675736
+          14465730655738711503
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -17890,58 +18380,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9425059496441527728
+          159004473548620887
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5089083539219748309
+          8104410590312662232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6772529533806073828
+          13706743646479427266
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17931259227737559526
+          12682715880467573944
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2029910099093282736
+          10781607431815735586
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -18295,7 +18773,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -18304,7 +18782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -18313,7 +18791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9400706697033338692
+          13764339996600437836
         ]
       ], 
       "reviewed-by-human": true
@@ -18322,7 +18800,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          237633552255702584
+          15536171010526909654
         ]
       ], 
       "reviewed-by-human": true
@@ -18331,7 +18809,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15481694980398014047
+          17890488678190568949
         ]
       ], 
       "reviewed-by-human": true
@@ -18516,62 +18994,95 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1131824196339345229
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12436917278295251764
+          2207063873455367749
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -18589,28 +19100,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9407358693309761110
+          5829921135942844635
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texture_domain_effect_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10952281952311499098
+          17099586086831668928
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -18643,10 +19154,7 @@
           17501446579955337831
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_msaa16.png": {
       "allowed-digests": [
@@ -18712,10 +19220,7 @@
           14626919895309756138
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_msaa16.png": {
       "allowed-digests": [
@@ -18754,58 +19259,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -18823,7 +19316,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -18832,7 +19325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -18841,7 +19334,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          6048869515923073564
         ]
       ], 
       "reviewed-by-human": true
@@ -18850,7 +19343,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1559349726696617839
+          14734348706173171694
         ]
       ], 
       "reviewed-by-human": true
@@ -18859,7 +19352,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10234586171976117018
+          13986036354074897447
         ]
       ], 
       "reviewed-by-human": true
@@ -18880,58 +19373,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          16367101498658508972
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14603002718790540977
+          16751914431820491012
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2203136195650082380
+          1205048549325125274
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -18949,7 +19430,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          4864263811791905685
         ]
       ], 
       "reviewed-by-human": true
@@ -18958,7 +19439,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          16801244478240186276
         ]
       ], 
       "reviewed-by-human": true
@@ -18967,7 +19448,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15641677254803875749
+          8757435387673298229
         ]
       ], 
       "reviewed-by-human": true
@@ -18976,7 +19457,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12233502021372539335
+          7513095271860536492
         ]
       ], 
       "reviewed-by-human": true
@@ -18985,7 +19466,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          14598823216365008278
         ]
       ], 
       "reviewed-by-human": true
@@ -18994,7 +19475,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5949714246508281820
         ]
       ], 
       "reviewed-by-human": true
@@ -19003,7 +19484,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5402764657976459291
         ]
       ], 
       "reviewed-by-human": true
@@ -19012,7 +19493,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13789919752467315906
+          8878476896705676612
         ]
       ], 
       "reviewed-by-human": true
@@ -19021,7 +19502,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          6996671819617945771
         ]
       ], 
       "reviewed-by-human": true
@@ -19042,7 +19523,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15641677254803875749
+          13498177505417262335
         ]
       ], 
       "reviewed-by-human": true
@@ -19132,7 +19613,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          1258363359136286164
         ]
       ], 
       "reviewed-by-human": true
@@ -19141,7 +19622,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          5399430353808909931
         ]
       ], 
       "reviewed-by-human": true
@@ -19150,7 +19631,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5092500482844467763
+          10977620141810635112
         ]
       ], 
       "reviewed-by-human": true
@@ -19159,7 +19640,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7272353906741772982
+          10217664941927163150
         ]
       ], 
       "reviewed-by-human": true
@@ -19168,7 +19649,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15810556183767148552
+          5696450717885951386
         ]
       ], 
       "reviewed-by-human": true
@@ -19189,58 +19670,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          7451829304858435646
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -19258,94 +19727,73 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          9822393380242794213
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -19363,22 +19811,19 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          1794524931659012049
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_pdf-poppler.png": {
       "allowed-digests": [
@@ -19392,6 +19837,186 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14238495105637549536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13091587407128414591
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2811772865778668658
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7185018533082072769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9068081473418106350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6787753377476893062
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9066227969618021937
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7185018533082072769
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13706090452902799076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9261209386788794091
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13592132854078956729
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16239445678573089230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7389120679870614644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8144110888506762127
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1546493394542600629
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16239445678573089230
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -19504,43 +20129,34 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5483308942142720488
+          12997787133028120518
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4696340272245690277
+          4367857761078620058
         ]
       ], 
       "reviewed-by-human": true
@@ -19549,10 +20165,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7664082110143619089
+          6780241912548653043
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19570,58 +20186,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7796209920479635095
+          16932359230392749690
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14523815480948971483
+          3695036642112880517
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5911601511426755275
+          13167397400025502386
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -19708,58 +20312,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3875898608761485258
+          1368059231204069698
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -19777,58 +20369,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          438558267463767125
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          6853497244680825166
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          962717882117070565
+          9083297924306753575
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          768763528917693850
+          4901741930957102676
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          962717882117070565
+          18343278898776537277
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -19846,58 +20426,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          18005779299301055149
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          543837030557564588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9806700643412380727
+          14265963860216842340
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11875667066985540599
+          9782797996062068312
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9806700643412380727
+          10234504630630772106
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -19915,58 +20483,46 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          16976170622579387959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          3296931836447172845
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9113706558474041625
+          5944658117124283263
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_msaa16.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1323079300068890978
+          7166884040512070986
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_nvprmsaa4.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9113706558474041625
+          2432684250684813924
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -19979,6 +20535,33 @@
         1935
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_msaa16.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_nvprmsaa4.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10030599291822810250
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win8-ShuttleA-HD7770-x86-Debug/expected-results.json b/expectations/gm/Test-Win8-ShuttleA-HD7770-x86-Debug/expected-results.json
index de629de..447d93c 100644
--- a/expectations/gm/Test-Win8-ShuttleA-HD7770-x86-Debug/expected-results.json
+++ b/expectations/gm/Test-Win8-ShuttleA-HD7770-x86-Debug/expected-results.json
@@ -112,13 +112,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9116581189758651423
+          15809448707538670203
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -232,37 +232,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          7593352410810558049
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          1175700925683069803
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5397366739123878075
+          13075729487004798723
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -276,6 +267,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -315,54 +333,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15950576281929256616
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -487,13 +457,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14956383359215747887
+          7097626952679229344
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -559,37 +526,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9922659528306658557
+          2303232560051909292
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -655,37 +613,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          7812520044346961011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          12807763425550694757
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          15793158843142784115
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -703,7 +652,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          3617797305044480555
         ]
       ], 
       "reviewed-by-human": true
@@ -712,7 +661,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          14987526374456897079
         ]
       ], 
       "reviewed-by-human": true
@@ -721,7 +670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1069560900195226454
+          8761033589775555439
         ]
       ], 
       "reviewed-by-human": true
@@ -880,37 +829,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -967,37 +907,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          723881656378404198
+          11261496560109552360
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -1033,10 +964,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6875302572300858944
+          7529423456826523215
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -2754,6 +2688,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11625436031249047137
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -2968,10 +2929,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7347494984795284241
+          12471200664293097992
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -2982,6 +2943,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1844934731312222820
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -3034,37 +3022,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9625285383140468503
+          14727185097661361928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -3157,37 +3136,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -3205,37 +3175,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          4866779553818268646
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -3373,10 +3334,7 @@
           9760605998205294594
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "clamped_gradients_pdf-poppler.png": {
       "allowed-digests": [
@@ -3778,37 +3736,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6417845319730596065
+          8838348413064640232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3922,37 +3871,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12387482010887223670
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
@@ -4231,73 +4171,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          8059723840111543656
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          4022128344496177992
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2135110186834179048
+          4057972683794837582
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          7167682324595825921
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          1167106541986679122
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11053664474482502784
+          11988028230067312464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -4327,73 +4249,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          3183371552229607548
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          3409717039232577306
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5875026620649308377
+          2544801691703111355
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          14815312009812228022
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          9409727332382440449
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10639490036404480043
+          10283183606999741153
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -4495,28 +4399,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5340125364304991377
+          15543580299298398882
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4534,7 +4438,7 @@
           11172569970945835791
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -4636,37 +4540,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          2396629361279121278
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          12144247543820336588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15358458950773129043
+          15717326522919224627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4684,37 +4579,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4844524665660284305
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          5938003447863338066
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1058787969831663033
+          11440763486733192079
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4891,7 +4777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506677856374279783
+          11049252658797568946
         ]
       ], 
       "reviewed-by-human": true
@@ -4945,31 +4831,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          8144433221544041893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          6901150638632819323
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410235621134781680
+          13537241190860014083
         ]
       ], 
       "reviewed-by-human": true
@@ -4990,37 +4870,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          15209085685049262946
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -5047,37 +4918,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -5095,37 +4957,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -5143,7 +4996,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -5152,7 +5005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -5161,7 +5014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10705771699045417639
+          7197605738989166101
         ]
       ], 
       "reviewed-by-human": true
@@ -5182,37 +5035,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7074080660153850768
+          3254023914347090375
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5230,37 +5074,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10705771699045417639
+          7197605738989166101
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5278,37 +5113,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          264101635027303883
+          16436981872023639313
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5326,7 +5152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -5335,7 +5161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -5344,7 +5170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4080615844295629366
+          4152319917332298870
         ]
       ], 
       "reviewed-by-human": true
@@ -5365,37 +5191,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16390733923759130290
+          4702183093414213222
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5413,37 +5230,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4080615844295629366
+          4152319917332298870
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5461,37 +5269,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10994608627209887379
+          8933879350550574707
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5509,7 +5308,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -5518,7 +5317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -5527,7 +5326,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7227409546001357465
+          7505416530295524168
         ]
       ], 
       "reviewed-by-human": true
@@ -5548,37 +5347,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3963933049901977131
+          16387879104346298478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5596,37 +5386,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7227409546001357465
+          7505416530295524168
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5644,37 +5425,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17901138592820159062
+          15197110389470158423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5692,13 +5464,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5716,13 +5485,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5180476370530034389
+          1174005698323125985
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5740,37 +5509,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          10560594815938292783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          12545797976096132621
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3684509459233185490
+          12693249940895422269
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5788,37 +5548,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15535370944862272667
+          2870448527115037503
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5836,37 +5587,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11356347296900089938
+          5091638787528363639
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -5920,37 +5662,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          229562018395218460
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          12760426964160092214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14772192336320512059
+          3371229958370954107
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6072,6 +5805,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -6307,7 +6067,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -6316,7 +6076,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -6346,7 +6106,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -6355,7 +6115,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -6388,7 +6148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -6397,7 +6157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -6430,7 +6190,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -6439,7 +6199,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -6472,7 +6232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -6481,7 +6241,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -6514,7 +6274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -6523,7 +6283,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -6556,7 +6316,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -6565,7 +6325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -6598,7 +6358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -6607,7 +6367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -6640,7 +6400,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -6649,7 +6409,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -6724,7 +6484,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -6733,7 +6493,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -6766,37 +6526,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966312344107014278
+          1165122519415389342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6814,7 +6565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -6823,7 +6574,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -6832,13 +6583,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15899709871876671133
+          470803814675761954
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6856,7 +6604,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15618220200870997449
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -6865,7 +6613,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10526671976174365374
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -6874,13 +6622,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251058858943277200
+          15170716972812490654
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6894,125 +6639,122 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4809842658371595960
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6628457321213338187
+          14935536508309642496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5851939326059970416
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15546460357391099353
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14292646344952811693
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16542857918429840050
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11929629716097313856
+          17393608634102982914
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          785891687725455133
+          17393608634102982914
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          2085580649669581585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          922176307457717158
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5079529663229630788
+          15521436249339506113
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -7030,31 +6772,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          13203594782216607040
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          15828501156207808430
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2642181544656365761
+          12291674391000425244
         ]
       ], 
       "reviewed-by-human": true
@@ -7071,41 +6807,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2420542765757901158
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7936336550806170595
+          6625686271197846546
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7123,37 +6877,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2111850772955491482
+          8195143885811873005
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -7743,6 +7488,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2810053128747067719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7359682993524147740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6336160084203417578
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1664147454648047962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17246726191352242657
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7774,10 +7735,7 @@
           9549780950462638931
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-poppler.png": {
       "allowed-digests": [
@@ -7864,7 +7822,7 @@
           13522756995350332622
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-poppler.png": {
       "allowed-digests": [
@@ -7900,7 +7858,7 @@
           7583081466968213482
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-poppler.png": {
       "allowed-digests": [
@@ -7936,7 +7894,7 @@
           8254576008248233124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-poppler.png": {
       "allowed-digests": [
@@ -8152,7 +8110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -8191,37 +8149,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10503393508125510015
+          9352626230764939481
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8311,13 +8260,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11738985815771891649
+          18272123830337130792
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -8371,7 +8320,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          2859104781692949426
         ]
       ], 
       "reviewed-by-human": true
@@ -8380,7 +8329,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          2670248603126936222
         ]
       ], 
       "reviewed-by-human": true
@@ -8389,7 +8338,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11760620697645253556
+          10863862076099772450
         ]
       ], 
       "reviewed-by-human": true
@@ -8439,47 +8388,65 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17249750308733517929
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          14557198649976668882
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          13002044415183336403
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5265597945723386162
+          14858836062897817413
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          6559263086767964475
         ]
       ], 
       "reviewed-by-human": true
@@ -8488,7 +8455,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          14315647952979882955
         ]
       ], 
       "reviewed-by-human": true
@@ -8497,7 +8464,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14523541400205998761
+          10240857570766314473
         ]
       ], 
       "reviewed-by-human": true
@@ -8527,25 +8494,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14083077936503758144
+          13950318353121381941
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8559,31 +8529,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13003169758303005933
+          1472972384237551711
         ]
       ], 
       "reviewed-by-human": true
@@ -8672,37 +8636,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7675439007472632415
+          12101872241792172919
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -8720,37 +8675,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15694343583458308781
+          18381994223402917282
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -8768,25 +8714,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1389498434675647804
+          7208281972040301992
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8800,37 +8749,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          287609287017214995
+          10859371975988916463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8848,28 +8788,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8884,37 +8824,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          3206410185119417900
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8968,37 +8899,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3654056322022973120
+          12692402074946866438
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -9040,13 +8962,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4182855140761016648
+          15784589612095101596
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -9064,37 +8986,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9091680425837314853
+          17659092449314049101
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -9148,37 +9061,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          4183511498011974903
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          10285833817111015220
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9908940664418223770
+          2496080518118586453
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9196,37 +9100,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          9263713892251900876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          3699172046262487290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12179054190378308686
+          13343919742186718018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9244,37 +9139,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          15807341393622522232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          6484758485740569522
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1774953335560534791
+          12759141749071174975
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9292,37 +9178,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3073663060834825429
+          12626539941577179734
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -9400,7 +9277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9445,7 +9322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9490,7 +9367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9571,13 +9448,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9669500704988468242
+          15011145842294672643
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -9595,37 +9472,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -9639,6 +9507,276 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16856624681990420774
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7232762719573200219
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10739955244469697231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6477532226734197477
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          409580787775275211
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2387249436036122883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6096992832765585389
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6337103226184907800
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12171826916608926152
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15102900421095191651
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9835,37 +9973,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13996532842460132317
+          344995640682343584
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9907,13 +10036,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8531414046974890102
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9972,41 +10101,86 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          714362839995821386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8722496997948775287
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9944670259825864249
+          14883265963077518402
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_pdf-poppler.png": {
       "allowed-digests": [
@@ -10345,7 +10519,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -10354,7 +10528,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -10363,11 +10537,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4290312399137233394
+          7817331447715494921
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5231425050527397097
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -10384,37 +10585,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -10428,6 +10620,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -10464,6 +10683,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -10516,37 +10762,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          14919179564192850472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          6704764580322283111
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18147422701216546539
+          10370303613366441635
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -10612,37 +10849,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          18104496854197341496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          6952495213922076627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          227829760963439120
+          8327257136761092849
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10660,37 +10888,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          11795498474298281319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          14297982111593447018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12591620996868959647
+          7943321657838237986
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10774,13 +10993,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6537650027777621088
+          5074139331563224033
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10819,10 +11038,7 @@
           17814588108040439543
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11188,37 +11404,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8705705241535249484
+          8889574289631904822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -11236,7 +11443,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -11245,7 +11452,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -11254,7 +11461,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7418452673388406132
+          17931180650811183988
         ]
       ], 
       "reviewed-by-human": true
@@ -11275,37 +11482,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15071445256051250690
+          11407138909322787259
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -11323,7 +11521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          18140335162380255225
         ]
       ], 
       "reviewed-by-human": true
@@ -11332,7 +11530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          7129698125485750601
         ]
       ], 
       "reviewed-by-human": true
@@ -11341,7 +11539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16122562040553040405
+          16864054374939191846
         ]
       ], 
       "reviewed-by-human": true
@@ -11350,7 +11548,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16281098760671026549
         ]
       ], 
       "reviewed-by-human": true
@@ -11359,7 +11557,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          13530435022292494762
         ]
       ], 
       "reviewed-by-human": true
@@ -11368,7 +11566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13743228729078400838
+          16628773046898476604
         ]
       ], 
       "reviewed-by-human": true
@@ -11545,7 +11743,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          3831063373917728128
         ]
       ], 
       "reviewed-by-human": true
@@ -11554,7 +11752,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12858821977237734612
+          11361790156959481856
         ]
       ], 
       "reviewed-by-human": true
@@ -11575,7 +11773,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "reviewed-by-human": true
@@ -11584,7 +11782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "reviewed-by-human": true
@@ -11593,7 +11791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14052288189283116408
+          13339599933665638930
         ]
       ], 
       "reviewed-by-human": true
@@ -11614,7 +11812,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "reviewed-by-human": true
@@ -11623,7 +11821,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "reviewed-by-human": true
@@ -11632,7 +11830,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3062321392537577611
+          7137647242198869163
         ]
       ], 
       "reviewed-by-human": true
@@ -11893,37 +12091,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          1581438121274106176
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15748755127436578058
+          11239927296406791044
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -11941,37 +12130,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          2283035916243745030
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3941358313351519231
+          1470336279047837260
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11989,31 +12169,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          852960377597007352
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          1031488952720446379
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350717240335379099
+          14702070993604648505
         ]
       ], 
       "reviewed-by-human": true
@@ -12166,31 +12340,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7854497950007138890
+          8515557571801312024
         ]
       ], 
       "reviewed-by-human": true
@@ -12259,37 +12427,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9425059496441527728
+          159004473548620887
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5089083539219748309
+          8104410590312662232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15515795060770515766
+          9752383613340516071
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -12541,7 +12700,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -12550,7 +12709,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -12559,7 +12718,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3608468917449842359
+          10239717967376591558
         ]
       ], 
       "reviewed-by-human": true
@@ -12681,41 +12840,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17839679750257082708
+          8113048109667414542
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12733,10 +12910,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4270416167210500804
+          17014688961708579526
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -12769,10 +12946,7 @@
           4283066490335654069
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12817,10 +12991,7 @@
           8250384630523253692
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12838,37 +13009,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12886,7 +13048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -12895,7 +13057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -12904,7 +13066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7418452673388406132
+          17931180650811183988
         ]
       ], 
       "reviewed-by-human": true
@@ -12925,37 +13087,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15071445256051250690
+          11407138909322787259
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -12973,7 +13126,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          4864263811791905685
         ]
       ], 
       "reviewed-by-human": true
@@ -12982,7 +13135,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          16801244478240186276
         ]
       ], 
       "reviewed-by-human": true
@@ -12991,7 +13144,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3468478849798030465
+          17428423077434820434
         ]
       ], 
       "reviewed-by-human": true
@@ -13000,7 +13153,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          14598823216365008278
         ]
       ], 
       "reviewed-by-human": true
@@ -13009,7 +13162,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5949714246508281820
         ]
       ], 
       "reviewed-by-human": true
@@ -13018,7 +13171,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13541863965066487806
+          11481397622454631047
         ]
       ], 
       "reviewed-by-human": true
@@ -13099,7 +13252,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          1258363359136286164
         ]
       ], 
       "reviewed-by-human": true
@@ -13108,7 +13261,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          5399430353808909931
         ]
       ], 
       "reviewed-by-human": true
@@ -13117,7 +13270,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17551190655047246050
+          2263031703865503689
         ]
       ], 
       "reviewed-by-human": true
@@ -13138,37 +13291,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -13186,73 +13330,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -13278,6 +13404,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14238495105637549536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14699863291227746930
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9068081473418106350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8382018261996002975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13706090452902799076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18003005108267271928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7389120679870614644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2705667727921803473
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -13354,37 +13588,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8235706630447597231
+          17998815825968568632
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -13402,37 +13627,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          257164027359431995
+          11232415922678752327
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13450,14 +13666,11 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6194629758544639580
+          6183456328083498663
         ]
       ], 
-      "bugs": [
-        1978
-      ], 
       "ignore-failure": true, 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verylargebitmap_8888.png": {
       "allowed-digests": [
@@ -13500,37 +13713,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2328769121930348993
+          5072674010218928088
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13548,37 +13752,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          438558267463767125
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          6853497244680825166
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4845915819383239688
+          749203639250691265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -13596,37 +13791,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          18005779299301055149
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          543837030557564588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10516542134158400366
+          13803303722111799889
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -13644,37 +13830,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          16976170622579387959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          3296931836447172845
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6884232680263443032
+          5995827422588214875
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -13687,6 +13864,15 @@
         1935
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10845440994435344847
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win8-ShuttleA-HD7770-x86-Release/expected-results.json b/expectations/gm/Test-Win8-ShuttleA-HD7770-x86-Release/expected-results.json
index 3a35203..1826322 100644
--- a/expectations/gm/Test-Win8-ShuttleA-HD7770-x86-Release/expected-results.json
+++ b/expectations/gm/Test-Win8-ShuttleA-HD7770-x86-Release/expected-results.json
@@ -112,13 +112,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9116581189758651423
+          15809448707538670203
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -232,37 +232,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          7593352410810558049
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          1175700925683069803
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5397366739123878075
+          13075729487004798723
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -276,6 +267,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -315,54 +333,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15950576281929256616
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -487,13 +457,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14956383359215747887
+          7097626952679229344
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -559,37 +526,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9922659528306658557
+          2303232560051909292
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -655,37 +613,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          7812520044346961011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          12807763425550694757
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          15793158843142784115
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -703,7 +652,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          3617797305044480555
         ]
       ], 
       "reviewed-by-human": true
@@ -712,7 +661,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          14987526374456897079
         ]
       ], 
       "reviewed-by-human": true
@@ -721,7 +670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1069560900195226454
+          8761033589775555439
         ]
       ], 
       "reviewed-by-human": true
@@ -880,37 +829,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -967,37 +907,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          723881656378404198
+          11261496560109552360
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -1033,10 +964,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6875302572300858944
+          7529423456826523215
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -2754,6 +2688,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11625436031249047137
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -2968,10 +2929,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7347494984795284241
+          12471200664293097992
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -2982,6 +2943,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1844934731312222820
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -3034,37 +3022,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9625285383140468503
+          14727185097661361928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -3157,37 +3136,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -3205,37 +3175,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          4866779553818268646
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -3373,10 +3334,7 @@
           9760605998205294594
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "clamped_gradients_pdf-poppler.png": {
       "allowed-digests": [
@@ -3778,37 +3736,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6417845319730596065
+          8838348413064640232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3922,37 +3871,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12387482010887223670
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
@@ -4231,73 +4171,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          8059723840111543656
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          4022128344496177992
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2135110186834179048
+          4057972683794837582
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          7167682324595825921
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          1167106541986679122
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11053664474482502784
+          11988028230067312464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -4327,73 +4249,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          3183371552229607548
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          3409717039232577306
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5875026620649308377
+          2544801691703111355
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          14815312009812228022
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          9409727332382440449
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10639490036404480043
+          10283183606999741153
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -4495,28 +4399,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5340125364304991377
+          15543580299298398882
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4534,7 +4438,7 @@
           11172569970945835791
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -4636,37 +4540,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          2396629361279121278
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          12144247543820336588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15358458950773129043
+          15717326522919224627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4684,37 +4579,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4844524665660284305
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          5938003447863338066
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1058787969831663033
+          11440763486733192079
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4891,7 +4777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506677856374279783
+          11049252658797568946
         ]
       ], 
       "reviewed-by-human": true
@@ -4945,31 +4831,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          8144433221544041893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          6901150638632819323
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410235621134781680
+          13537241190860014083
         ]
       ], 
       "reviewed-by-human": true
@@ -4990,37 +4870,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          15209085685049262946
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -5047,37 +4918,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -5095,37 +4957,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -5143,7 +4996,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -5152,7 +5005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -5161,7 +5014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10705771699045417639
+          7197605738989166101
         ]
       ], 
       "reviewed-by-human": true
@@ -5182,37 +5035,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7074080660153850768
+          3254023914347090375
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5230,37 +5074,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10705771699045417639
+          7197605738989166101
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5278,37 +5113,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          264101635027303883
+          16436981872023639313
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5326,7 +5152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -5335,7 +5161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -5344,7 +5170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4080615844295629366
+          4152319917332298870
         ]
       ], 
       "reviewed-by-human": true
@@ -5365,37 +5191,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16390733923759130290
+          4702183093414213222
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5413,37 +5230,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4080615844295629366
+          4152319917332298870
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5461,37 +5269,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10994608627209887379
+          8933879350550574707
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5509,7 +5308,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -5518,7 +5317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -5527,7 +5326,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7227409546001357465
+          7505416530295524168
         ]
       ], 
       "reviewed-by-human": true
@@ -5548,37 +5347,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3963933049901977131
+          16387879104346298478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5596,37 +5386,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7227409546001357465
+          7505416530295524168
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5644,37 +5425,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17901138592820159062
+          15197110389470158423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5692,13 +5464,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5716,13 +5485,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5180476370530034389
+          1174005698323125985
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5740,37 +5509,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          10560594815938292783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          12545797976096132621
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3684509459233185490
+          12693249940895422269
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5788,37 +5548,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15535370944862272667
+          2870448527115037503
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5836,37 +5587,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11356347296900089938
+          5091638787528363639
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -5920,37 +5662,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          229562018395218460
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          12760426964160092214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14772192336320512059
+          3371229958370954107
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6072,6 +5805,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -6307,7 +6067,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -6316,7 +6076,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -6346,7 +6106,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -6355,7 +6115,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -6388,7 +6148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -6397,7 +6157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -6430,7 +6190,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -6439,7 +6199,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -6472,7 +6232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -6481,7 +6241,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -6514,7 +6274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -6523,7 +6283,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -6556,7 +6316,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -6565,7 +6325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -6598,7 +6358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -6607,7 +6367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -6640,7 +6400,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -6649,7 +6409,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -6724,7 +6484,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -6733,7 +6493,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -6766,37 +6526,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966312344107014278
+          1165122519415389342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6814,7 +6565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -6823,7 +6574,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -6832,13 +6583,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15899709871876671133
+          470803814675761954
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6856,7 +6604,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15618220200870997449
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -6865,7 +6613,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10526671976174365374
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -6874,13 +6622,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251058858943277200
+          15170716972812490654
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6894,125 +6639,122 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4809842658371595960
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6628457321213338187
+          14935536508309642496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5851939326059970416
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15546460357391099353
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14292646344952811693
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16542857918429840050
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11929629716097313856
+          17393608634102982914
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          785891687725455133
+          17393608634102982914
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          2085580649669581585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          922176307457717158
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5079529663229630788
+          15521436249339506113
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -7030,31 +6772,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          13203594782216607040
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          15828501156207808430
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2642181544656365761
+          12291674391000425244
         ]
       ], 
       "reviewed-by-human": true
@@ -7071,41 +6807,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2420542765757901158
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7936336550806170595
+          6625686271197846546
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7123,37 +6877,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2111850772955491482
+          8195143885811873005
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -7743,6 +7488,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2810053128747067719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7359682993524147740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6336160084203417578
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1664147454648047962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17246726191352242657
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7774,10 +7735,7 @@
           9549780950462638931
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-poppler.png": {
       "allowed-digests": [
@@ -7864,7 +7822,7 @@
           13522756995350332622
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-poppler.png": {
       "allowed-digests": [
@@ -7900,7 +7858,7 @@
           7583081466968213482
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-poppler.png": {
       "allowed-digests": [
@@ -7936,7 +7894,7 @@
           8254576008248233124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-poppler.png": {
       "allowed-digests": [
@@ -8152,7 +8110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -8191,37 +8149,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10503393508125510015
+          9352626230764939481
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8311,13 +8260,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11738985815771891649
+          18272123830337130792
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -8371,7 +8320,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          2859104781692949426
         ]
       ], 
       "reviewed-by-human": true
@@ -8380,7 +8329,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          2670248603126936222
         ]
       ], 
       "reviewed-by-human": true
@@ -8389,7 +8338,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11760620697645253556
+          10863862076099772450
         ]
       ], 
       "reviewed-by-human": true
@@ -8439,47 +8388,65 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17249750308733517929
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          14557198649976668882
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          13002044415183336403
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5265597945723386162
+          14858836062897817413
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          6559263086767964475
         ]
       ], 
       "reviewed-by-human": true
@@ -8488,7 +8455,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          14315647952979882955
         ]
       ], 
       "reviewed-by-human": true
@@ -8497,7 +8464,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14523541400205998761
+          10240857570766314473
         ]
       ], 
       "reviewed-by-human": true
@@ -8527,25 +8494,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14083077936503758144
+          13950318353121381941
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8559,31 +8529,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13003169758303005933
+          1472972384237551711
         ]
       ], 
       "reviewed-by-human": true
@@ -8672,37 +8636,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7675439007472632415
+          12101872241792172919
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -8720,37 +8675,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15694343583458308781
+          18381994223402917282
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -8768,25 +8714,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1389498434675647804
+          7208281972040301992
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8800,37 +8749,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          287609287017214995
+          10859371975988916463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8848,28 +8788,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8884,37 +8824,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          3206410185119417900
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8968,37 +8899,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3654056322022973120
+          12692402074946866438
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -9040,13 +8962,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4182855140761016648
+          15784589612095101596
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -9064,37 +8986,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9091680425837314853
+          17659092449314049101
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -9148,37 +9061,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          4183511498011974903
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          10285833817111015220
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9908940664418223770
+          2496080518118586453
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9196,37 +9100,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          9263713892251900876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          3699172046262487290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12179054190378308686
+          13343919742186718018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9244,37 +9139,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          15807341393622522232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          6484758485740569522
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1774953335560534791
+          12759141749071174975
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9292,37 +9178,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3073663060834825429
+          12626539941577179734
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -9400,7 +9277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9445,7 +9322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9490,7 +9367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9571,13 +9448,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9669500704988468242
+          15011145842294672643
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -9595,37 +9472,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -9639,6 +9507,276 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16856624681990420774
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7232762719573200219
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10739955244469697231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6477532226734197477
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          409580787775275211
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2387249436036122883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6096992832765585389
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6337103226184907800
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12171826916608926152
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15102900421095191651
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9835,37 +9973,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13996532842460132317
+          344995640682343584
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9907,13 +10036,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8531414046974890102
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9972,41 +10101,86 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          714362839995821386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8722496997948775287
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9944670259825864249
+          14883265963077518402
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_pdf-poppler.png": {
       "allowed-digests": [
@@ -10345,7 +10519,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -10354,7 +10528,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -10363,11 +10537,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4290312399137233394
+          7817331447715494921
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5231425050527397097
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -10384,37 +10585,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -10428,6 +10620,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -10464,6 +10683,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -10516,37 +10762,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          14919179564192850472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          6704764580322283111
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18147422701216546539
+          10370303613366441635
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -10612,37 +10849,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          18104496854197341496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          6952495213922076627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          227829760963439120
+          8327257136761092849
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10660,37 +10888,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          11795498474298281319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          14297982111593447018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12591620996868959647
+          7943321657838237986
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10774,13 +10993,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6537650027777621088
+          5074139331563224033
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10819,10 +11038,7 @@
           17814588108040439543
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11188,37 +11404,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8705705241535249484
+          8889574289631904822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -11236,7 +11443,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -11245,7 +11452,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -11254,7 +11461,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7418452673388406132
+          17931180650811183988
         ]
       ], 
       "reviewed-by-human": true
@@ -11275,37 +11482,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15071445256051250690
+          11407138909322787259
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -11323,7 +11521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          18140335162380255225
         ]
       ], 
       "reviewed-by-human": true
@@ -11332,7 +11530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          7129698125485750601
         ]
       ], 
       "reviewed-by-human": true
@@ -11341,7 +11539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16122562040553040405
+          16864054374939191846
         ]
       ], 
       "reviewed-by-human": true
@@ -11350,7 +11548,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16281098760671026549
         ]
       ], 
       "reviewed-by-human": true
@@ -11359,7 +11557,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          13530435022292494762
         ]
       ], 
       "reviewed-by-human": true
@@ -11368,7 +11566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13743228729078400838
+          16628773046898476604
         ]
       ], 
       "reviewed-by-human": true
@@ -11545,7 +11743,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          3831063373917728128
         ]
       ], 
       "reviewed-by-human": true
@@ -11554,7 +11752,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12858821977237734612
+          11361790156959481856
         ]
       ], 
       "reviewed-by-human": true
@@ -11575,7 +11773,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "reviewed-by-human": true
@@ -11584,7 +11782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "reviewed-by-human": true
@@ -11593,7 +11791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14052288189283116408
+          13339599933665638930
         ]
       ], 
       "reviewed-by-human": true
@@ -11614,7 +11812,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "reviewed-by-human": true
@@ -11623,7 +11821,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "reviewed-by-human": true
@@ -11632,7 +11830,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3062321392537577611
+          7137647242198869163
         ]
       ], 
       "reviewed-by-human": true
@@ -11893,37 +12091,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          1581438121274106176
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15748755127436578058
+          11239927296406791044
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -11941,37 +12130,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          2283035916243745030
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3941358313351519231
+          1470336279047837260
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11989,31 +12169,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          852960377597007352
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          1031488952720446379
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350717240335379099
+          14702070993604648505
         ]
       ], 
       "reviewed-by-human": true
@@ -12166,31 +12340,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7854497950007138890
+          8515557571801312024
         ]
       ], 
       "reviewed-by-human": true
@@ -12259,37 +12427,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9425059496441527728
+          159004473548620887
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5089083539219748309
+          8104410590312662232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15515795060770515766
+          9752383613340516071
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -12541,7 +12700,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -12550,7 +12709,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -12559,7 +12718,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3608468917449842359
+          10239717967376591558
         ]
       ], 
       "reviewed-by-human": true
@@ -12681,41 +12840,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17839679750257082708
+          8113048109667414542
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12733,10 +12910,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4270416167210500804
+          17014688961708579526
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -12769,10 +12946,7 @@
           4283066490335654069
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12817,10 +12991,7 @@
           8250384630523253692
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12838,37 +13009,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12886,7 +13048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -12895,7 +13057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -12904,7 +13066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7418452673388406132
+          17931180650811183988
         ]
       ], 
       "reviewed-by-human": true
@@ -12925,37 +13087,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15071445256051250690
+          11407138909322787259
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -12973,7 +13126,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          4864263811791905685
         ]
       ], 
       "reviewed-by-human": true
@@ -12982,7 +13135,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          16801244478240186276
         ]
       ], 
       "reviewed-by-human": true
@@ -12991,7 +13144,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3468478849798030465
+          17428423077434820434
         ]
       ], 
       "reviewed-by-human": true
@@ -13000,7 +13153,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          14598823216365008278
         ]
       ], 
       "reviewed-by-human": true
@@ -13009,7 +13162,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5949714246508281820
         ]
       ], 
       "reviewed-by-human": true
@@ -13018,7 +13171,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13541863965066487806
+          11481397622454631047
         ]
       ], 
       "reviewed-by-human": true
@@ -13099,7 +13252,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          1258363359136286164
         ]
       ], 
       "reviewed-by-human": true
@@ -13108,7 +13261,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          5399430353808909931
         ]
       ], 
       "reviewed-by-human": true
@@ -13117,7 +13270,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17551190655047246050
+          2263031703865503689
         ]
       ], 
       "reviewed-by-human": true
@@ -13138,37 +13291,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -13186,73 +13330,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -13278,6 +13404,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14238495105637549536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14699863291227746930
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9068081473418106350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8382018261996002975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13706090452902799076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18003005108267271928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7389120679870614644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2705667727921803473
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -13354,37 +13588,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8235706630447597231
+          17998815825968568632
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -13402,37 +13627,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          257164027359431995
+          11232415922678752327
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13450,18 +13666,26 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10262256877703773151
+          6183456328083498663
         ]
       ], 
+      "bugs": [
+        2775
+      ], 
+      "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
     "verylargebitmap_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11880098846453637456
+          10492157671811011535
         ]
       ], 
+      "bugs": [
+        2775
+      ], 
+      "ignore-failure": true, 
       "reviewed-by-human": true
     }, 
     "verylargebitmap_gpu.png": {
@@ -13492,37 +13716,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2328769121930348993
+          5072674010218928088
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13540,37 +13755,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          438558267463767125
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          6853497244680825166
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4845915819383239688
+          749203639250691265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -13588,37 +13794,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          18005779299301055149
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          543837030557564588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10516542134158400366
+          13803303722111799889
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -13636,37 +13833,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          16976170622579387959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          3296931836447172845
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6884232680263443032
+          5995827422588214875
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -13679,6 +13867,15 @@
         1935
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10845440994435344847
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win8-ShuttleA-HD7770-x86_64-Debug/expected-results.json b/expectations/gm/Test-Win8-ShuttleA-HD7770-x86_64-Debug/expected-results.json
index 239398f..4a89b6ad 100644
--- a/expectations/gm/Test-Win8-ShuttleA-HD7770-x86_64-Debug/expected-results.json
+++ b/expectations/gm/Test-Win8-ShuttleA-HD7770-x86_64-Debug/expected-results.json
@@ -112,13 +112,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9116581189758651423
+          15809448707538670203
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -232,37 +232,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          7593352410810558049
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          1175700925683069803
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5397366739123878075
+          13075729487004798723
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -276,6 +267,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -315,54 +333,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15950576281929256616
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -487,13 +457,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14956383359215747887
+          7097626952679229344
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -559,37 +526,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9922659528306658557
+          2303232560051909292
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -655,37 +613,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          7812520044346961011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          12807763425550694757
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          15793158843142784115
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -703,7 +652,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          3617797305044480555
         ]
       ], 
       "reviewed-by-human": true
@@ -712,7 +661,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          14987526374456897079
         ]
       ], 
       "reviewed-by-human": true
@@ -721,7 +670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1069560900195226454
+          8761033589775555439
         ]
       ], 
       "reviewed-by-human": true
@@ -880,37 +829,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -967,37 +907,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          723881656378404198
+          11261496560109552360
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -1033,10 +964,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6875302572300858944
+          7529423456826523215
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -2754,6 +2688,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11625436031249047137
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -2968,10 +2929,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7347494984795284241
+          12471200664293097992
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -2982,6 +2943,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1844934731312222820
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -3034,37 +3022,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9625285383140468503
+          14727185097661361928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -3157,37 +3136,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -3205,37 +3175,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          4866779553818268646
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -3373,10 +3334,7 @@
           9760605998205294594
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "clamped_gradients_pdf-poppler.png": {
       "allowed-digests": [
@@ -3778,37 +3736,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6417845319730596065
+          8838348413064640232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3922,37 +3871,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12387482010887223670
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
@@ -4231,73 +4171,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          8059723840111543656
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          4022128344496177992
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2135110186834179048
+          4057972683794837582
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          7167682324595825921
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          1167106541986679122
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11053664474482502784
+          11988028230067312464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -4327,73 +4249,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          3183371552229607548
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          3409717039232577306
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5875026620649308377
+          2544801691703111355
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          14815312009812228022
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          9409727332382440449
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10639490036404480043
+          10283183606999741153
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -4495,28 +4399,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5340125364304991377
+          15543580299298398882
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4534,7 +4438,7 @@
           11172569970945835791
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -4636,37 +4540,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          2396629361279121278
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          12144247543820336588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15358458950773129043
+          15717326522919224627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4684,37 +4579,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4844524665660284305
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          5938003447863338066
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1058787969831663033
+          11440763486733192079
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4891,7 +4777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506677856374279783
+          11049252658797568946
         ]
       ], 
       "reviewed-by-human": true
@@ -4945,31 +4831,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          8144433221544041893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          6901150638632819323
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410235621134781680
+          13537241190860014083
         ]
       ], 
       "reviewed-by-human": true
@@ -4990,37 +4870,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          15209085685049262946
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -5047,37 +4918,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -5095,37 +4957,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -5143,7 +4996,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -5152,7 +5005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -5161,7 +5014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10705771699045417639
+          7197605738989166101
         ]
       ], 
       "reviewed-by-human": true
@@ -5182,37 +5035,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7074080660153850768
+          3254023914347090375
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5230,37 +5074,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10705771699045417639
+          7197605738989166101
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5278,37 +5113,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          264101635027303883
+          16436981872023639313
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5326,7 +5152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -5335,7 +5161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -5344,7 +5170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4080615844295629366
+          4152319917332298870
         ]
       ], 
       "reviewed-by-human": true
@@ -5365,37 +5191,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16390733923759130290
+          4702183093414213222
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5413,37 +5230,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4080615844295629366
+          4152319917332298870
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5461,37 +5269,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10994608627209887379
+          8933879350550574707
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5509,7 +5308,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -5518,7 +5317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -5527,7 +5326,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7227409546001357465
+          7505416530295524168
         ]
       ], 
       "reviewed-by-human": true
@@ -5548,37 +5347,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3963933049901977131
+          16387879104346298478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5596,37 +5386,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7227409546001357465
+          7505416530295524168
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5644,37 +5425,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17901138592820159062
+          15197110389470158423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5692,13 +5464,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5716,13 +5485,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5180476370530034389
+          1174005698323125985
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5740,37 +5509,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          10560594815938292783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          12545797976096132621
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3684509459233185490
+          12693249940895422269
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5788,37 +5548,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15535370944862272667
+          2870448527115037503
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5836,37 +5587,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11356347296900089938
+          5091638787528363639
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -5920,37 +5662,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          229562018395218460
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          12760426964160092214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14772192336320512059
+          3371229958370954107
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6072,6 +5805,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -6307,7 +6067,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -6316,7 +6076,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -6346,7 +6106,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -6355,7 +6115,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -6388,7 +6148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -6397,7 +6157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -6430,7 +6190,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -6439,7 +6199,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -6472,7 +6232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -6481,7 +6241,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -6514,7 +6274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -6523,7 +6283,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -6556,7 +6316,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -6565,7 +6325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -6598,7 +6358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -6607,7 +6367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -6640,7 +6400,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -6649,7 +6409,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -6724,7 +6484,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -6733,7 +6493,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -6766,37 +6526,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966312344107014278
+          1165122519415389342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6814,7 +6565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -6823,7 +6574,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -6832,13 +6583,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15899709871876671133
+          470803814675761954
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6856,7 +6604,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15618220200870997449
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -6865,7 +6613,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10526671976174365374
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -6874,13 +6622,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251058858943277200
+          15170716972812490654
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6894,125 +6639,122 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4809842658371595960
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6628457321213338187
+          14935536508309642496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5851939326059970416
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15546460357391099353
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14292646344952811693
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16542857918429840050
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11929629716097313856
+          17393608634102982914
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          785891687725455133
+          17393608634102982914
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          2085580649669581585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          922176307457717158
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5079529663229630788
+          15521436249339506113
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -7030,31 +6772,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          13203594782216607040
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          15828501156207808430
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2642181544656365761
+          12291674391000425244
         ]
       ], 
       "reviewed-by-human": true
@@ -7071,41 +6807,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2420542765757901158
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7936336550806170595
+          6625686271197846546
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7123,37 +6877,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2111850772955491482
+          8195143885811873005
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -7743,6 +7488,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2810053128747067719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7359682993524147740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6336160084203417578
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1664147454648047962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17246726191352242657
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7774,10 +7735,7 @@
           9549780950462638931
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-poppler.png": {
       "allowed-digests": [
@@ -7864,7 +7822,7 @@
           13522756995350332622
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-poppler.png": {
       "allowed-digests": [
@@ -7900,7 +7858,7 @@
           7583081466968213482
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-poppler.png": {
       "allowed-digests": [
@@ -7936,7 +7894,7 @@
           8254576008248233124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-poppler.png": {
       "allowed-digests": [
@@ -8152,7 +8110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -8191,37 +8149,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10503393508125510015
+          9352626230764939481
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8311,13 +8260,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11738985815771891649
+          18272123830337130792
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -8371,7 +8320,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          2859104781692949426
         ]
       ], 
       "reviewed-by-human": true
@@ -8380,7 +8329,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          2670248603126936222
         ]
       ], 
       "reviewed-by-human": true
@@ -8389,7 +8338,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11760620697645253556
+          10863862076099772450
         ]
       ], 
       "reviewed-by-human": true
@@ -8439,47 +8388,65 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17249750308733517929
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          14557198649976668882
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          13002044415183336403
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5265597945723386162
+          14858836062897817413
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          6559263086767964475
         ]
       ], 
       "reviewed-by-human": true
@@ -8488,7 +8455,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          14315647952979882955
         ]
       ], 
       "reviewed-by-human": true
@@ -8497,7 +8464,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14523541400205998761
+          10240857570766314473
         ]
       ], 
       "reviewed-by-human": true
@@ -8527,25 +8494,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14083077936503758144
+          13950318353121381941
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8559,31 +8529,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13003169758303005933
+          1472972384237551711
         ]
       ], 
       "reviewed-by-human": true
@@ -8672,37 +8636,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7675439007472632415
+          12101872241792172919
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -8720,37 +8675,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15694343583458308781
+          18381994223402917282
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -8768,25 +8714,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1389498434675647804
+          7208281972040301992
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8800,37 +8749,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          287609287017214995
+          10859371975988916463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8848,28 +8788,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8884,37 +8824,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          3206410185119417900
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8968,37 +8899,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3654056322022973120
+          12692402074946866438
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -9040,13 +8962,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4182855140761016648
+          15784589612095101596
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -9064,37 +8986,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9091680425837314853
+          17659092449314049101
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -9148,37 +9061,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          4183511498011974903
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          10285833817111015220
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9908940664418223770
+          2496080518118586453
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9196,37 +9100,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          9263713892251900876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          3699172046262487290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12179054190378308686
+          13343919742186718018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9244,37 +9139,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          15807341393622522232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          6484758485740569522
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1774953335560534791
+          12759141749071174975
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9292,37 +9178,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3073663060834825429
+          12626539941577179734
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -9400,7 +9277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9445,7 +9322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9490,7 +9367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9571,13 +9448,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9669500704988468242
+          15011145842294672643
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -9595,37 +9472,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -9639,6 +9507,276 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16856624681990420774
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7232762719573200219
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10739955244469697231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6477532226734197477
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          409580787775275211
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2387249436036122883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6096992832765585389
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6337103226184907800
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12171826916608926152
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15102900421095191651
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9835,37 +9973,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13996532842460132317
+          344995640682343584
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9907,13 +10036,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8531414046974890102
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9972,41 +10101,86 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          714362839995821386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8722496997948775287
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9944670259825864249
+          14883265963077518402
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_pdf-poppler.png": {
       "allowed-digests": [
@@ -10345,7 +10519,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -10354,7 +10528,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -10363,11 +10537,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4290312399137233394
+          7817331447715494921
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5231425050527397097
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -10384,37 +10585,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -10428,6 +10620,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -10464,6 +10683,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -10516,37 +10762,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          14919179564192850472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          6704764580322283111
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18147422701216546539
+          10370303613366441635
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -10612,37 +10849,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          18104496854197341496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          6952495213922076627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          227829760963439120
+          8327257136761092849
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10660,37 +10888,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          11795498474298281319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          14297982111593447018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12591620996868959647
+          7943321657838237986
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10774,13 +10993,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6537650027777621088
+          5074139331563224033
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10819,10 +11038,7 @@
           17814588108040439543
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11188,37 +11404,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8705705241535249484
+          8889574289631904822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -11236,7 +11443,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -11245,7 +11452,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -11254,7 +11461,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7418452673388406132
+          17931180650811183988
         ]
       ], 
       "reviewed-by-human": true
@@ -11275,37 +11482,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15071445256051250690
+          11407138909322787259
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -11323,7 +11521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          18140335162380255225
         ]
       ], 
       "reviewed-by-human": true
@@ -11332,7 +11530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          7129698125485750601
         ]
       ], 
       "reviewed-by-human": true
@@ -11341,7 +11539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16122562040553040405
+          16864054374939191846
         ]
       ], 
       "reviewed-by-human": true
@@ -11350,7 +11548,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16281098760671026549
         ]
       ], 
       "reviewed-by-human": true
@@ -11359,7 +11557,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          13530435022292494762
         ]
       ], 
       "reviewed-by-human": true
@@ -11368,7 +11566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13743228729078400838
+          16628773046898476604
         ]
       ], 
       "reviewed-by-human": true
@@ -11545,7 +11743,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          3831063373917728128
         ]
       ], 
       "reviewed-by-human": true
@@ -11554,7 +11752,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12858821977237734612
+          11361790156959481856
         ]
       ], 
       "reviewed-by-human": true
@@ -11575,7 +11773,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "reviewed-by-human": true
@@ -11584,7 +11782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "reviewed-by-human": true
@@ -11593,7 +11791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14052288189283116408
+          13339599933665638930
         ]
       ], 
       "reviewed-by-human": true
@@ -11614,7 +11812,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "reviewed-by-human": true
@@ -11623,7 +11821,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "reviewed-by-human": true
@@ -11632,7 +11830,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3062321392537577611
+          7137647242198869163
         ]
       ], 
       "reviewed-by-human": true
@@ -11893,37 +12091,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          1581438121274106176
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15748755127436578058
+          11239927296406791044
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -11941,37 +12130,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          2283035916243745030
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3941358313351519231
+          1470336279047837260
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11989,31 +12169,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          852960377597007352
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          1031488952720446379
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350717240335379099
+          14702070993604648505
         ]
       ], 
       "reviewed-by-human": true
@@ -12166,31 +12340,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7854497950007138890
+          8515557571801312024
         ]
       ], 
       "reviewed-by-human": true
@@ -12259,37 +12427,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9425059496441527728
+          159004473548620887
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5089083539219748309
+          8104410590312662232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15515795060770515766
+          9752383613340516071
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -12541,7 +12700,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -12550,7 +12709,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -12559,7 +12718,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3608468917449842359
+          10239717967376591558
         ]
       ], 
       "reviewed-by-human": true
@@ -12681,41 +12840,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17839679750257082708
+          8113048109667414542
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12733,10 +12910,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4270416167210500804
+          17014688961708579526
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -12769,10 +12946,7 @@
           4283066490335654069
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12817,10 +12991,7 @@
           8250384630523253692
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12838,37 +13009,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12886,7 +13048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -12895,7 +13057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -12904,7 +13066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7418452673388406132
+          17931180650811183988
         ]
       ], 
       "reviewed-by-human": true
@@ -12925,37 +13087,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15071445256051250690
+          11407138909322787259
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -12973,7 +13126,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          4864263811791905685
         ]
       ], 
       "reviewed-by-human": true
@@ -12982,7 +13135,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          16801244478240186276
         ]
       ], 
       "reviewed-by-human": true
@@ -12991,7 +13144,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3468478849798030465
+          17428423077434820434
         ]
       ], 
       "reviewed-by-human": true
@@ -13000,7 +13153,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          14598823216365008278
         ]
       ], 
       "reviewed-by-human": true
@@ -13009,7 +13162,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5949714246508281820
         ]
       ], 
       "reviewed-by-human": true
@@ -13018,7 +13171,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13541863965066487806
+          11481397622454631047
         ]
       ], 
       "reviewed-by-human": true
@@ -13099,7 +13252,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          1258363359136286164
         ]
       ], 
       "reviewed-by-human": true
@@ -13108,7 +13261,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          5399430353808909931
         ]
       ], 
       "reviewed-by-human": true
@@ -13117,7 +13270,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17551190655047246050
+          2263031703865503689
         ]
       ], 
       "reviewed-by-human": true
@@ -13138,37 +13291,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -13186,73 +13330,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -13278,6 +13404,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14238495105637549536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14699863291227746930
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9068081473418106350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8382018261996002975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13706090452902799076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18003005108267271928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7389120679870614644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2705667727921803473
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -13354,37 +13588,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8235706630447597231
+          17998815825968568632
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -13402,37 +13627,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          257164027359431995
+          11232415922678752327
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13498,37 +13714,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2328769121930348993
+          5072674010218928088
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13546,37 +13753,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          438558267463767125
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          6853497244680825166
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4845915819383239688
+          749203639250691265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -13594,37 +13792,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          18005779299301055149
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          543837030557564588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10516542134158400366
+          13803303722111799889
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -13642,37 +13831,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          16976170622579387959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          3296931836447172845
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6884232680263443032
+          5995827422588214875
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -13685,6 +13865,15 @@
         1935
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10845440994435344847
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/Test-Win8-ShuttleA-HD7770-x86_64-Release/expected-results.json b/expectations/gm/Test-Win8-ShuttleA-HD7770-x86_64-Release/expected-results.json
index 239398f..4a89b6ad 100644
--- a/expectations/gm/Test-Win8-ShuttleA-HD7770-x86_64-Release/expected-results.json
+++ b/expectations/gm/Test-Win8-ShuttleA-HD7770-x86_64-Release/expected-results.json
@@ -112,13 +112,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9116581189758651423
+          15809448707538670203
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "aarectmodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -232,37 +232,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5839962155445477769
+          7593352410810558049
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7156566021516385167
+          1175700925683069803
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5397366739123878075
+          13075729487004798723
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "arithmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -276,6 +267,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "astcbitmap_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7296080463405164282
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "astcbitmap_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7104155647358997780
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "bat_gpu.png": {
       "allowed-digests": [
         [
@@ -315,54 +333,6 @@
       ], 
       "reviewed-by-human": true
     }, 
-    "bicubicfilter_565.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          13864700347231029854
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_8888.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          10469536215464879914
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_gpu.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          15950576281929256616
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
-    "bicubicfilter_pdf-poppler.png": {
-      "allowed-digests": [
-        [
-          "bitmap-64bitMD5", 
-          12297352892272012287
-        ]
-      ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
-    }, 
     "bigbitmaprect_i_565.png": {
       "allowed-digests": [
         [
@@ -487,13 +457,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14956383359215747887
+          7097626952679229344
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigblurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -559,37 +526,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10690991833202333228
+          5276042071209726466
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18012280510168355332
+          16400787115543600042
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9922659528306658557
+          2303232560051909292
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bigtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -655,37 +613,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5979146979240941584
+          7812520044346961011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          12807763425550694757
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9769079178972712396
+          15793158843142784115
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapcopy_pdf-poppler.png": {
       "allowed-digests": [
@@ -703,7 +652,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14716678433615240987
+          3617797305044480555
         ]
       ], 
       "reviewed-by-human": true
@@ -712,7 +661,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14089867808957901889
+          14987526374456897079
         ]
       ], 
       "reviewed-by-human": true
@@ -721,7 +670,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1069560900195226454
+          8761033589775555439
         ]
       ], 
       "reviewed-by-human": true
@@ -880,37 +829,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8374498344295064826
+          699957806917460270
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7661658472507345576
+          17151342280057693608
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6988485463832158984
+          13316672857843153758
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapscroll_pdf-poppler.png": {
       "allowed-digests": [
@@ -967,37 +907,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          371178799665115891
+          7634008000794960573
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9122960779200833672
+          9587979520754881585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          723881656378404198
+          11261496560109552360
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "bitmapsource_pdf-poppler.png": {
       "allowed-digests": [
@@ -1033,10 +964,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6875302572300858944
+          7529423456826523215
         ]
       ], 
-      "reviewed-by-human": true
+      "bugs": [
+        2762
+      ], 
+      "reviewed-by-human": false
     }, 
     "bleed_pdf-poppler.png": {
       "allowed-digests": [
@@ -2754,6 +2688,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurrect_gallery_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8181688189057988621
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          926365638072273755
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "blurrect_gallery_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11625436031249047137
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "blurrect_inner_565.png": {
       "allowed-digests": [
         [
@@ -2968,10 +2929,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7347494984795284241
+          12471200664293097992
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -2982,6 +2943,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "blurroundrect-WH-100x100-unevenCorners_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5849651065413553680
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4619759825939595617
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "blurroundrect-WH-100x100-unevenCorners_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1844934731312222820
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "blurroundrect-WH[100x100]-unevenCorners_565.png": {
       "allowed-digests": [
         [
@@ -3034,37 +3022,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17918773138208904527
+          8885827664842700271
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5802417966042309585
+          12764966007571970378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9625285383140468503
+          14727185097661361928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "blurs_pdf-poppler.png": {
       "allowed-digests": [
@@ -3157,37 +3136,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5630935511407937833
+          7629469764602032763
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext1_pdf-poppler.png": {
       "allowed-digests": [
@@ -3205,37 +3175,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6610768468046039919
+          14963173374117197072
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4420768163403134622
+          4866779553818268646
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "chrome_gradtext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -3373,10 +3334,7 @@
           9760605998205294594
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "clamped_gradients_pdf-poppler.png": {
       "allowed-digests": [
@@ -3778,37 +3736,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10524437190323785933
+          12458050902936749668
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13135854746821589433
+          12720271908908851463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6417845319730596065
+          8838348413064640232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "coloremoji_pdf-poppler.png": {
       "allowed-digests": [
@@ -3922,37 +3871,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4435635874507528843
+          16754938408236949132
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11388847455044852750
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12387482010887223670
+          7760022190728266716
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "colortype_pdf-poppler.png": {
       "allowed-digests": [
@@ -4231,73 +4171,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15086840398446270080
+          8059723840111543656
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12256726096519443626
+          4022128344496177992
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2135110186834179048
+          4057972683794837582
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13900550048335620767
+          7167682324595825921
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13830967495616795782
+          1167106541986679122
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11053664474482502784
+          11988028230067312464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_aa_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -4327,73 +4249,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6219538047232204558
+          3183371552229607548
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17408343536636620438
+          3409717039232577306
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5875026620649308377
+          2544801691703111355
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4308432622037386040
+          14815312009812228022
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5187352004350055148
+          9409727332382440449
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10639490036404480043
+          10283183606999741153
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "complexclip_bw_layer_pdf-poppler.png": {
       "allowed-digests": [
@@ -4495,28 +4399,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16528868776552619632
+          4604486586531253956
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4471733774366429528
+          2051802506720253599
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5340125364304991377
+          15543580299298398882
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convex_poly_clip_pdf-poppler.png": {
       "allowed-digests": [
@@ -4534,7 +4438,7 @@
           11172569970945835791
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "convexpaths_565.png": {
       "allowed-digests": [
@@ -4636,37 +4540,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16642126176331915552
+          2396629361279121278
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8808568066129615559
+          12144247543820336588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15358458950773129043
+          15717326522919224627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4684,37 +4579,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9879227133619727217
+          4844524665660284305
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10531951636515062999
+          5938003447863338066
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1058787969831663033
+          11440763486733192079
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "cubicpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -4891,7 +4777,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506677856374279783
+          11049252658797568946
         ]
       ], 
       "reviewed-by-human": true
@@ -4945,31 +4831,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15054322479285185584
+          8144433221544041893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16839814821666096745
+          6901150638632819323
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "degeneratesegments_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12410235621134781680
+          13537241190860014083
         ]
       ], 
       "reviewed-by-human": true
@@ -4990,37 +4870,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6224697345794232255
+          15209085685049262946
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10010276479003822633
+          1695396467980502536
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "deviceproperties_pdf-poppler.png": {
       "allowed-digests": [
@@ -5047,37 +4918,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9127724751254250264
+          5311592490631599434
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          989738608887264410
+          5546602314850585745
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12006806320042950518
+          2937206974579924892
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "displacement_pdf-poppler.png": {
       "allowed-digests": [
@@ -5095,37 +4957,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2455115578822786504
+          12081034570142193461
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "distantclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -5143,7 +4996,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15154730871764821124
+          10903381122071794033
         ]
       ], 
       "reviewed-by-human": true
@@ -5152,7 +5005,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194619977446273533
+          10821670216999952848
         ]
       ], 
       "reviewed-by-human": true
@@ -5161,7 +5014,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10705771699045417639
+          7197605738989166101
         ]
       ], 
       "reviewed-by-human": true
@@ -5182,37 +5035,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10232582998248890344
+          11574858737582987248
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1233814311003427744
+          3690964357297286254
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7074080660153850768
+          3254023914347090375
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_low_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5230,37 +5074,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1203257848312793050
+          1005393243870299378
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3984265676088058160
+          15122674148017830807
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10705771699045417639
+          7197605738989166101
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_medium_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5278,37 +5113,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3646964297203490771
+          17376724739712413482
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17145060002425698132
+          12547882070304664454
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          264101635027303883
+          16436981872023639313
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_checkerboard_none_512_256_pdf-poppler.png": {
       "allowed-digests": [
@@ -5326,7 +5152,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17264975515988900071
+          2684271591231220590
         ]
       ], 
       "reviewed-by-human": true
@@ -5335,7 +5161,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3911174280407842684
+          4072072153531825530
         ]
       ], 
       "reviewed-by-human": true
@@ -5344,7 +5170,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4080615844295629366
+          4152319917332298870
         ]
       ], 
       "reviewed-by-human": true
@@ -5365,37 +5191,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6765275404189723366
+          14990791594568777598
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6485054271692420021
+          16736962537597702928
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16390733923759130290
+          4702183093414213222
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_low_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5413,37 +5230,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13571956230133077991
+          15795260477712563370
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8840752418158714253
+          4676614614370538868
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4080615844295629366
+          4152319917332298870
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_medium_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5461,37 +5269,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14270272450959568098
+          13125314496708254483
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13220718652543317787
+          15966784871311652363
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10994608627209887379
+          8933879350550574707
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_image_none_mandrill_512.png_pdf-poppler.png": {
       "allowed-digests": [
@@ -5509,7 +5308,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16300138276708471133
+          17342868766245391890
         ]
       ], 
       "reviewed-by-human": true
@@ -5518,7 +5317,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1794634032409076750
+          14855743345030278093
         ]
       ], 
       "reviewed-by-human": true
@@ -5527,7 +5326,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7227409546001357465
+          7505416530295524168
         ]
       ], 
       "reviewed-by-human": true
@@ -5548,37 +5347,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7530407115819228868
+          17843348435148286470
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8790219078085373164
+          16166456234155304682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3963933049901977131
+          16387879104346298478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_low_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5596,37 +5386,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7686945076313655877
+          16994390033189144484
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10584874825669399103
+          1323010937803190247
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7227409546001357465
+          7505416530295524168
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_medium_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5644,37 +5425,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1511306226410583719
+          17903061515238096226
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14820504682169578033
+          11449283803849346686
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17901138592820159062
+          15197110389470158423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "downsamplebitmap_text_none_72.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -5692,13 +5464,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10358565987363211292
+          15387448829875767682
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_8888.png": {
       "allowed-digests": [
@@ -5716,13 +5485,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5180476370530034389
+          1174005698323125985
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmapmatrix_pdf-poppler.png": {
       "allowed-digests": [
@@ -5740,37 +5509,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14417133020710349071
+          10560594815938292783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11099535915332015085
+          12545797976096132621
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3684509459233185490
+          12693249940895422269
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawbitmaprect_pdf-poppler.png": {
       "allowed-digests": [
@@ -5788,37 +5548,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4176243375830737807
+          10014106509042438342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4503954533486099708
+          1912712104834108856
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15535370944862272667
+          2870448527115037503
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "drawlooper_pdf-poppler.png": {
       "allowed-digests": [
@@ -5836,37 +5587,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1878952781508762983
+          2878413088829673422
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16375219338730536333
+          4660236967370621790
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11356347296900089938
+          5091638787528363639
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "dropshadowimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -5920,37 +5662,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3179421156273465928
+          229562018395218460
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6656584779175746910
+          12760426964160092214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14772192336320512059
+          3371229958370954107
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "emptypath_pdf-poppler.png": {
       "allowed-digests": [
@@ -6072,6 +5805,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "etc1bitmap_r11.ktx_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1495436641215277847
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "etc1bitmap_r11.ktx_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14073051900873346231
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "extractbitmap_565.png": {
       "allowed-digests": [
         [
@@ -6307,7 +6067,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11849479847158189672
+          5768044287840033357
         ]
       ], 
       "reviewed-by-human": true
@@ -6316,7 +6076,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5598960819970570537
+          6935773165017827364
         ]
       ], 
       "reviewed-by-human": true
@@ -6346,7 +6106,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2960178481215162337
+          8671570728952009368
         ]
       ], 
       "reviewed-by-human": true
@@ -6355,7 +6115,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4450718444101780683
+          939720769378298526
         ]
       ], 
       "reviewed-by-human": true
@@ -6388,7 +6148,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7014687204130401525
+          4764666190884059758
         ]
       ], 
       "reviewed-by-human": true
@@ -6397,7 +6157,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3806902690903137233
+          8099535723040488851
         ]
       ], 
       "reviewed-by-human": true
@@ -6430,7 +6190,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13881630103079494069
+          9417618387713208391
         ]
       ], 
       "reviewed-by-human": true
@@ -6439,7 +6199,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9932044079274644873
+          12875792784913551813
         ]
       ], 
       "reviewed-by-human": true
@@ -6472,7 +6232,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1579671231929888838
+          2021729417891596038
         ]
       ], 
       "reviewed-by-human": true
@@ -6481,7 +6241,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13302794141569322047
+          13987077395880214723
         ]
       ], 
       "reviewed-by-human": true
@@ -6514,7 +6274,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9297700286159875383
+          202166896140107874
         ]
       ], 
       "reviewed-by-human": true
@@ -6523,7 +6283,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2973278832290154575
+          399424409131177601
         ]
       ], 
       "reviewed-by-human": true
@@ -6556,7 +6316,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16463835176045189428
+          8956987427746173336
         ]
       ], 
       "reviewed-by-human": true
@@ -6565,7 +6325,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6005085772252447499
+          8942152313335044956
         ]
       ], 
       "reviewed-by-human": true
@@ -6598,7 +6358,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14701147707000835863
+          4733270989262395458
         ]
       ], 
       "reviewed-by-human": true
@@ -6607,7 +6367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13963787067456426543
+          14256052409798599342
         ]
       ], 
       "reviewed-by-human": true
@@ -6640,7 +6400,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16111742563610080290
+          832250766423211363
         ]
       ], 
       "reviewed-by-human": true
@@ -6649,7 +6409,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6995483270082414180
+          10495914511070527920
         ]
       ], 
       "reviewed-by-human": true
@@ -6724,7 +6484,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16378256781529096921
+          9858494347061234386
         ]
       ], 
       "reviewed-by-human": true
@@ -6733,7 +6493,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15046624545894643263
+          5346119798377374888
         ]
       ], 
       "reviewed-by-human": true
@@ -6766,37 +6526,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4282697869254025799
+          17189951714195521290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17906931989778693882
+          16417451919771975585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9966312344107014278
+          1165122519415389342
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_10.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6814,7 +6565,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16607800556363548229
+          14760320241772915514
         ]
       ], 
       "reviewed-by-human": true
@@ -6823,7 +6574,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13495993656211725261
+          857680318039301891
         ]
       ], 
       "reviewed-by-human": true
@@ -6832,13 +6583,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15899709871876671133
+          470803814675761954
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_3.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6856,7 +6604,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15618220200870997449
+          18213918577588705559
         ]
       ], 
       "reviewed-by-human": true
@@ -6865,7 +6613,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10526671976174365374
+          11982034096402023221
         ]
       ], 
       "reviewed-by-human": true
@@ -6874,13 +6622,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7251058858943277200
+          15170716972812490654
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "filterbitmap_text_7.00pt_pdf-poppler.png": {
       "allowed-digests": [
@@ -6894,125 +6639,122 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "filterindiabox_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5356292344634806612
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          35490507854748284
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "filterindiabox_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4809842658371595960
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "fontcache_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6628457321213338187
+          14935536508309642496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5851939326059970416
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15546460357391099353
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14292646344952811693
+          959878741858530751
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16542857918429840050
+          1003428895143800786
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_factory_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11929629716097313856
+          17393608634102982914
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_iter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          785891687725455133
+          17393608634102982914
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6832217877127725208
+          2085580649669581585
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10766119269193181024
+          922176307457717158
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5079529663229630788
+          15521436249339506113
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontmgr_match_pdf-poppler.png": {
       "allowed-digests": [
@@ -7030,31 +6772,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9499588106829924023
+          13203594782216607040
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9187505713856674683
+          15828501156207808430
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "fontscaler_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2642181544656365761
+          12291674391000425244
         ]
       ], 
       "reviewed-by-human": true
@@ -7071,41 +6807,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "gammagradienttext_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16349421352428533946
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1125392895089655418
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gammagradienttext_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2420542765757901158
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gammatext_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7679297002197502314
+          13800984280135952333
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5619788297414609386
+          2529985197633194300
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7936336550806170595
+          6625686271197846546
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gammatext_pdf-poppler.png": {
       "allowed-digests": [
@@ -7123,37 +6877,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8085796325209380826
+          7537551135357698806
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10909520016157880919
+          13699276548961697214
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2111850772955491482
+          8195143885811873005
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "getpostextpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -7743,6 +7488,222 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "glyph_pos_align_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          579101372049800146
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8169560928327264884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_align_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2810053128747067719
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          4149431595116827034
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10302456443573129378
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_h_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7359682993524147740
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9618214379387468474
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16568131432067513017
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_b_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6336160084203417578
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18128268310031962391
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1055466622031207646
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_f_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10336474360265964610
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3118199924302571493
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11333313033369680096
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "glyph_pos_n_s_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1664147454648047962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8415921158513008891
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11313680758681612011
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "gpusamplerstress_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17246726191352242657
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "gradient_dirty_laundry_565.png": {
       "allowed-digests": [
         [
@@ -7774,10 +7735,7 @@
           9549780950462638931
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradient_dirty_laundry_pdf-poppler.png": {
       "allowed-digests": [
@@ -7864,7 +7822,7 @@
           13522756995350332622
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_edge_pdf-poppler.png": {
       "allowed-digests": [
@@ -7900,7 +7858,7 @@
           7583081466968213482
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_inside_pdf-poppler.png": {
       "allowed-digests": [
@@ -7936,7 +7894,7 @@
           8254576008248233124
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradients_2pt_conical_outside_pdf-poppler.png": {
       "allowed-digests": [
@@ -8152,7 +8110,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3351550727216338875
+          11562681936963040479
         ]
       ], 
       "reviewed-by-human": true
@@ -8191,37 +8149,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13921952822661237062
+          5358977218148623651
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14237848994313215721
+          1883617362438967528
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10503393508125510015
+          9352626230764939481
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "gradtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -8311,13 +8260,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11738985815771891649
+          18272123830337130792
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "hittestpath_565.png": {
       "allowed-digests": [
@@ -8371,7 +8320,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14181374245311350591
+          2859104781692949426
         ]
       ], 
       "reviewed-by-human": true
@@ -8380,7 +8329,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10597799258015429155
+          2670248603126936222
         ]
       ], 
       "reviewed-by-human": true
@@ -8389,7 +8338,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11760620697645253556
+          10863862076099772450
         ]
       ], 
       "reviewed-by-human": true
@@ -8439,47 +8388,65 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "imageblur2_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14543238184872570136
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15004694860472755495
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "imageblur2_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          17249750308733517929
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "imageblur_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2025074220422169799
+          14557198649976668882
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17968155108570846305
+          13002044415183336403
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5265597945723386162
+          14858836062897817413
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageblur_large_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4201039589513270063
+          6559263086767964475
         ]
       ], 
       "reviewed-by-human": true
@@ -8488,7 +8455,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5409747208695663879
+          14315647952979882955
         ]
       ], 
       "reviewed-by-human": true
@@ -8497,7 +8464,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14523541400205998761
+          10240857570766314473
         ]
       ], 
       "reviewed-by-human": true
@@ -8527,25 +8494,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7841628441839775066
+          8036386996825154774
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3060597873850351230
+          3951023112288690493
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14083077936503758144
+          13950318353121381941
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imageblurtiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8559,31 +8529,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5163116162222181270
+          3902918736371911951
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2703822092089350506
+          978480490919637031
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersbase_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13003169758303005933
+          1472972384237551711
         ]
       ], 
       "reviewed-by-human": true
@@ -8672,37 +8636,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12701798715039974608
+          2546290479021589783
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4409581878233253133
+          16291100939440783217
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7675439007472632415
+          12101872241792172919
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefilterscropped_pdf-poppler.png": {
       "allowed-digests": [
@@ -8720,37 +8675,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16270104872231160675
+          12397973020047643144
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16989655229284721085
+          3028242240833581871
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15694343583458308781
+          18381994223402917282
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagefiltersgraph_pdf-poppler.png": {
       "allowed-digests": [
@@ -8768,25 +8714,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16374068527216052297
+          2337680673667749002
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4781711442727351551
+          11178354341533563746
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1389498434675647804
+          7208281972040301992
         ]
-      ]
+      ], 
+      "reviewed-by-human": true
     }, 
     "imagefiltersscaled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8800,37 +8749,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18120509887329722541
+          3118751021842548389
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17530746377391001262
+          16134641349444195314
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          287609287017214995
+          10859371975988916463
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imagemagnifier_pdf-poppler.png": {
       "allowed-digests": [
@@ -8848,28 +8788,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          366370455362981767
+          7778838624740354134
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14006603930599710444
+          13863293165254715143
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "imageresizetiled_pdf-poppler.png": {
       "allowed-digests": [
@@ -8884,37 +8824,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15109641821094815831
+          7519509356222400789
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7127122112754348737
+          1553759510016289215
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3877631189763401125
+          3206410185119417900
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "internal_links_pdf-poppler.png": {
       "allowed-digests": [
@@ -8968,37 +8899,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8506572757677233462
+          5413590040608356550
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12284846972770084322
+          6505993221153840547
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3654056322022973120
+          12692402074946866438
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lcdtext_pdf-poppler.png": {
       "allowed-digests": [
@@ -9040,13 +8962,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4182855140761016648
+          15784589612095101596
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lerpmode_pdf-poppler.png": {
       "allowed-digests": [
@@ -9064,37 +8986,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3410140065760570266
+          16176952994917133863
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11437957044728813342
+          14288311445588719923
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9091680425837314853
+          17659092449314049101
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lighting_pdf-poppler.png": {
       "allowed-digests": [
@@ -9148,37 +9061,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16996348385288109887
+          4183511498011974903
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7850730623714783539
+          10285833817111015220
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9908940664418223770
+          2496080518118586453
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lineclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9196,37 +9100,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16720628902071319523
+          9263713892251900876
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2313265316554504716
+          3699172046262487290
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12179054190378308686
+          13343919742186718018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "linepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -9244,37 +9139,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7910675456019623265
+          15807341393622522232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8405846389312946683
+          6484758485740569522
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1774953335560534791
+          12759141749071174975
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "lumafilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9292,37 +9178,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12068893372127883735
+          14389470863423565011
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8591172619739740146
+          17693992863465001487
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3073663060834825429
+          12626539941577179734
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "matrixconvolution_pdf-poppler.png": {
       "allowed-digests": [
@@ -9400,7 +9277,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9445,7 +9322,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9490,7 +9367,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11282658944184824071
+          11342720063665480940
         ]
       ], 
       "reviewed-by-human": true
@@ -9571,13 +9448,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9669500704988468242
+          15011145842294672643
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "modecolorfilters_pdf-poppler.png": {
       "allowed-digests": [
@@ -9595,37 +9472,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1517767291814791924
+          12549360642438897235
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7452392621884368054
+          17476718297850315478
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4159829520363805044
+          8133824192863832117
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "morphology_pdf-poppler.png": {
       "allowed-digests": [
@@ -9639,6 +9507,276 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "multipicturedraw_invpathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9703041468125968282
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15516661955773674709
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16856624681990420774
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6855833681739980828
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15148828238931084858
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_invpathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7232762719573200219
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3761287326770653884
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10739955244469697231
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14308772794029612377
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_noclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6477532226734197477
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2487898131670212350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15693369477747297944
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          409580787775275211
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6192956499824448530
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          500979748616333925
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_pathclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2387249436036122883
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15270138114757185962
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15332966925537010272
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6096992832765585389
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5583446812787070838
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10196169116829665030
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6337103226184907800
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6863796958441296663
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          11447101547405897355
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_simple_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12171826916608926152
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10202443996649390546
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1560204122899681316
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "multipicturedraw_rrectclip_tiled_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15102900421095191651
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "nested_aa_565.png": {
       "allowed-digests": [
         [
@@ -9835,37 +9973,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7267464234076196179
+          11593332453638950760
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5243133089763527248
+          565785417218411423
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13996532842460132317
+          344995640682343584
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "offsetimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -9907,13 +10036,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13857521313271479795
+          8531414046974890102
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "optimizations_pdf-poppler.png": {
       "allowed-digests": [
@@ -9972,41 +10101,86 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "patch_grid_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13791344411978581811
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15107039688877047424
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_grid_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          714362839995821386
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          12311672375935852309
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16900678846621265323
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "patch_primitive_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8722496997948775287
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "path-reverse_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8873353007899405413
+          6340411979636405380
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16497314288418959893
+          14723958203905295362
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9944670259825864249
+          14883265963077518402
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "path-reverse_pdf-poppler.png": {
       "allowed-digests": [
@@ -10345,7 +10519,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16968168405481699903
+          1539561209878927288
         ]
       ], 
       "reviewed-by-human": true
@@ -10354,7 +10528,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1098763191610264229
+          14413015027460366330
         ]
       ], 
       "reviewed-by-human": true
@@ -10363,11 +10537,38 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4290312399137233394
+          7817331447715494921
         ]
       ], 
       "reviewed-by-human": true
     }, 
+    "perlinnoise_localmatrix_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          1146938693925995110
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14683067705107117711
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "perlinnoise_localmatrix_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          5231425050527397097
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "perlinnoise_pdf-poppler.png": {
       "allowed-digests": [
         [
@@ -10384,37 +10585,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14506043780003705045
+          5210379642109091609
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5185419490189304266
+          1579775443659434177
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "pictureimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -10428,6 +10620,33 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "pictures_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9144012151750431041
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16757813114881765350
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictures_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          3911440082938535639
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "pictureshader_565.png": {
       "allowed-digests": [
         [
@@ -10464,6 +10683,33 @@
       ], 
       "reviewed-by-human": true
     }, 
+    "pictureshadertile_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          829769456197975356
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
+    "pictureshadertile_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          16229963383871377197
+        ]
+      ], 
+      "reviewed-by-human": false
+    }, 
     "points_565.png": {
       "allowed-digests": [
         [
@@ -10516,37 +10762,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          649190908137356462
+          14919179564192850472
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          854856574649606475
+          6704764580322283111
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          18147422701216546539
+          10370303613366441635
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "poly2poly_pdf-poppler.png": {
       "allowed-digests": [
@@ -10612,37 +10849,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9069289420625235773
+          18104496854197341496
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9630285749750559431
+          6952495213922076627
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          227829760963439120
+          8327257136761092849
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadclosepath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10660,37 +10888,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2188286230219565322
+          11795498474298281319
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4199314639973282739
+          14297982111593447018
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12591620996868959647
+          7943321657838237986
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "quadpath_pdf-poppler.png": {
       "allowed-digests": [
@@ -10774,13 +10993,13 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6537650027777621088
+          5074139331563224033
         ]
       ], 
       "bugs": [
         1935
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "radial_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -10819,10 +11038,7 @@
           17814588108040439543
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "rects_pdf-poppler.png": {
       "allowed-digests": [
@@ -11188,37 +11404,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16413612005347796853
+          9180818560842379201
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7873872448388026294
+          10094008325673029893
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8705705241535249484
+          8889574289631904822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "samplerstress_pdf-poppler.png": {
       "allowed-digests": [
@@ -11236,7 +11443,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -11245,7 +11452,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -11254,7 +11461,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7418452673388406132
+          17931180650811183988
         ]
       ], 
       "reviewed-by-human": true
@@ -11275,37 +11482,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15071445256051250690
+          11407138909322787259
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "scaled_tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -11323,7 +11521,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9860275637246616812
+          18140335162380255225
         ]
       ], 
       "reviewed-by-human": true
@@ -11332,7 +11530,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17381081701697674781
+          7129698125485750601
         ]
       ], 
       "reviewed-by-human": true
@@ -11341,7 +11539,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16122562040553040405
+          16864054374939191846
         ]
       ], 
       "reviewed-by-human": true
@@ -11350,7 +11548,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11488251422655199295
+          16281098760671026549
         ]
       ], 
       "reviewed-by-human": true
@@ -11359,7 +11557,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          77032301419838201
+          13530435022292494762
         ]
       ], 
       "reviewed-by-human": true
@@ -11368,7 +11566,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13743228729078400838
+          16628773046898476604
         ]
       ], 
       "reviewed-by-human": true
@@ -11545,7 +11743,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4721382661721666101
+          3831063373917728128
         ]
       ], 
       "reviewed-by-human": true
@@ -11554,7 +11752,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12858821977237734612
+          11361790156959481856
         ]
       ], 
       "reviewed-by-human": true
@@ -11575,7 +11773,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17353877458368015149
+          15111004528287052817
         ]
       ], 
       "reviewed-by-human": true
@@ -11584,7 +11782,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15348462621046294022
+          8125939581889210704
         ]
       ], 
       "reviewed-by-human": true
@@ -11593,7 +11791,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14052288189283116408
+          13339599933665638930
         ]
       ], 
       "reviewed-by-human": true
@@ -11614,7 +11812,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13609479783732570932
+          15166740142850249140
         ]
       ], 
       "reviewed-by-human": true
@@ -11623,7 +11821,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4451949037265385190
+          7911974576054616569
         ]
       ], 
       "reviewed-by-human": true
@@ -11632,7 +11830,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3062321392537577611
+          7137647242198869163
         ]
       ], 
       "reviewed-by-human": true
@@ -11893,37 +12091,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5125486367287369013
+          1581438121274106176
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15748755127436578058
+          11239927296406791044
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_aaclip_pdf-poppler.png": {
       "allowed-digests": [
@@ -11941,37 +12130,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9597237696040391197
+          6089396249218372118
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17359238857629145816
+          2283035916243745030
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3941358313351519231
+          1470336279047837260
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_path_pdf-poppler.png": {
       "allowed-digests": [
@@ -11989,31 +12169,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6591113124168837838
+          852960377597007352
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2121507113826541274
+          1031488952720446379
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "simpleaaclip_rect_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1350717240335379099
+          14702070993604648505
         ]
       ], 
       "reviewed-by-human": true
@@ -12166,31 +12340,25 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10548024191560453076
+          13143812168225183465
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4746025269070656018
+          5878554696785974637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "srcmode_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7854497950007138890
+          8515557571801312024
         ]
       ], 
       "reviewed-by-human": true
@@ -12259,37 +12427,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9425059496441527728
+          159004473548620887
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5089083539219748309
+          8104410590312662232
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15515795060770515766
+          9752383613340516071
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "stroke-fill_pdf-poppler.png": {
       "allowed-digests": [
@@ -12541,7 +12700,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9498485304931230418
+          11988199864332270594
         ]
       ], 
       "reviewed-by-human": true
@@ -12550,7 +12709,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          5377413442802208855
+          14434493615135380869
         ]
       ], 
       "reviewed-by-human": true
@@ -12559,7 +12718,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3608468917449842359
+          10239717967376591558
         ]
       ], 
       "reviewed-by-human": true
@@ -12681,41 +12840,59 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "textblob_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8578201284082955084
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          6848497618937600819
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "textblob_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8450106420219141611
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "texteffects_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          194668986131045106
+          9805106273662486358
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10466931808969001893
+          3321267585316102772
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17839679750257082708
+          8113048109667414542
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "texteffects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12733,10 +12910,10 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4270416167210500804
+          17014688961708579526
         ]
       ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_565.png": {
       "allowed-digests": [
@@ -12769,10 +12946,7 @@
           4283066490335654069
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12817,10 +12991,7 @@
           8250384630523253692
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "thinstrokedrects_pdf-poppler.png": {
       "allowed-digests": [
@@ -12838,37 +13009,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13589853158989280917
+          13643462334056680198
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6831635186525247935
+          4219207843435792504
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tileimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -12886,7 +13048,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15812603631794984096
+          13561720884733686842
         ]
       ], 
       "reviewed-by-human": true
@@ -12895,7 +13057,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3084679922126628983
+          9938901521610960492
         ]
       ], 
       "reviewed-by-human": true
@@ -12904,7 +13066,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          7418452673388406132
+          17931180650811183988
         ]
       ], 
       "reviewed-by-human": true
@@ -12925,37 +13087,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1592227748175088361
+          18237938427133021346
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17799380770871981065
+          2134703127931704587
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15071445256051250690
+          11407138909322787259
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "tilemode_gradient_pdf-poppler.png": {
       "allowed-digests": [
@@ -12973,7 +13126,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16962990988331249371
+          4864263811791905685
         ]
       ], 
       "reviewed-by-human": true
@@ -12982,7 +13135,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2869879561540713031
+          16801244478240186276
         ]
       ], 
       "reviewed-by-human": true
@@ -12991,7 +13144,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3468478849798030465
+          17428423077434820434
         ]
       ], 
       "reviewed-by-human": true
@@ -13000,7 +13153,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9857729080874698160
+          14598823216365008278
         ]
       ], 
       "reviewed-by-human": true
@@ -13009,7 +13162,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16682488125750110606
+          5949714246508281820
         ]
       ], 
       "reviewed-by-human": true
@@ -13018,7 +13171,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13541863965066487806
+          11481397622454631047
         ]
       ], 
       "reviewed-by-human": true
@@ -13099,7 +13252,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17453681852009184262
+          1258363359136286164
         ]
       ], 
       "reviewed-by-human": true
@@ -13108,7 +13261,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9692196727387651123
+          5399430353808909931
         ]
       ], 
       "reviewed-by-human": true
@@ -13117,7 +13270,7 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17551190655047246050
+          2263031703865503689
         ]
       ], 
       "reviewed-by-human": true
@@ -13138,37 +13291,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          15228836062906581784
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          6188372188127675056
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          9299054446323094621
+          4230219031790547441
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typeface_pdf-poppler.png": {
       "allowed-digests": [
@@ -13186,73 +13330,55 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          12659286956475364783
+          3107992133872006410
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15832913375493921878
+          8171069724296243205
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_565.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15281084345390801869
+          3891968816847912704
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          14669575486571291164
+          11421725802721844620
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "typefacestyles_kerning_pdf-poppler.png": {
       "allowed-digests": [
@@ -13278,6 +13404,114 @@
       ], 
       "reviewed-by-human": false
     }, 
+    "varied_text_clipped_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14238495105637549536
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14699863291227746930
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          15174997355459806999
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          9068081473418106350
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_clipped_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          8382018261996002975
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          13706090452902799076
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          18003005108267271928
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_565.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          14907105370239763957
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_8888.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          7389120679870614644
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
+    "varied_text_ignorable_clip_no_lcd_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          2705667727921803473
+        ]
+      ], 
+      "reviewed-by-human": true
+    }, 
     "vertices_565.png": {
       "allowed-digests": [
         [
@@ -13354,37 +13588,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          11328574041890597001
+          3266324430040340637
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          3564841414622439452
+          5036001268883781826
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          8235706630447597231
+          17998815825968568632
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext2_pdf-poppler.png": {
       "allowed-digests": [
@@ -13402,37 +13627,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          13647784529713168712
+          8274208197386934822
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          429496524471329904
+          11832156116308490489
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          257164027359431995
+          11232415922678752327
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "verttext_pdf-poppler.png": {
       "allowed-digests": [
@@ -13498,37 +13714,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          1479116357727804239
+          17298851971445257464
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          17744727655126998812
+          14681108931572136865
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2328769121930348993
+          5072674010218928088
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodeimagefilter_pdf-poppler.png": {
       "allowed-digests": [
@@ -13546,37 +13753,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10867762899153607563
+          438558267463767125
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          15256447318671495054
+          6853497244680825166
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4845915819383239688
+          749203639250691265
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes2_pdf-poppler.png": {
       "allowed-digests": [
@@ -13594,37 +13792,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          4792494784763135349
+          18005779299301055149
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          2346110414893443666
+          543837030557564588
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          10516542134158400366
+          13803303722111799889
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes3_pdf-poppler.png": {
       "allowed-digests": [
@@ -13642,37 +13831,28 @@
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          16489442407009284088
+          16976170622579387959
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_8888.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          841434441529559407
+          3296931836447172845
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_gpu.png": {
       "allowed-digests": [
         [
           "bitmap-64bitMD5", 
-          6884232680263443032
+          5995827422588214875
         ]
       ], 
-      "bugs": [
-        1935
-      ], 
-      "reviewed-by-human": false
+      "reviewed-by-human": true
     }, 
     "xfermodes_pdf-poppler.png": {
       "allowed-digests": [
@@ -13685,6 +13865,15 @@
         1935
       ], 
       "reviewed-by-human": false
+    }, 
+    "yuv_to_rgb_effect_gpu.png": {
+      "allowed-digests": [
+        [
+          "bitmap-64bitMD5", 
+          10845440994435344847
+        ]
+      ], 
+      "reviewed-by-human": false
     }
   }
 }
\ No newline at end of file
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index 2cc1b85..989e1f3 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -33,43 +33,14 @@
 ## epoger will rebaseline by 25 Dec 2013
 #gradtext
 
-# reed: bitmapfilters changed (labels) with hide_config CL, just need rebaselines
-bitmapfilters
+# jvanverth
+fontcache
 
-# humper:
-# Needs rebaselining after faster GPU blur patch lands
-megalooper_0x0
-megalooper_1x4
-megalooper_4x1
-bleed
-blurquickreject
-blurrects
-bigblurs
+# reed - conservative_rasterclip CL
+multipicturedraw_pathclip_tiled
 
-# Added by robertphillips for https://codereview.chromium.org/316143003/
-# This CL actually fixes this GM's image
-distantclip
+# rileya - https://codereview.chromium.org/516463005/ will rebaseline after bots cycle
+yuv_to_rgb_effect
 
-# krajcevski:
-# Added GPU-based dithering for all SkPaints that have that flag set
-# https://codereview.chromium.org/321253002/
-radial_gradient
-modecolorfilters
-scaled_tilemodes
-tilemodes
-scaled_tilemodes_npot
-lerpmode
-xfermodes2
-xfermodes
-drawbitmapmatrix
-complexclip_bw_layer
-complexclip_aa_layer
-hairmodes
-aarectmodes
-tilemodes_npot
-convex_poly_clip
-lumafilter
-shadertext
-bitmapfilters
-arithmode
-optimizations
+#edgdaniel https://codereview.chromium.org/703783002/
+dashing
diff --git a/expectations/skimage/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json b/expectations/skimage/Test-Android-Nexus10-MaliT604-Arm7-Release-Recipes/expected-results.json
similarity index 100%
copy from expectations/skimage/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json
copy to expectations/skimage/Test-Android-Nexus10-MaliT604-Arm7-Release-Recipes/expected-results.json
diff --git a/expectations/skimage/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json b/expectations/skimage/Test-Android-Nexus5-Adreno330-Arm7-Debug/expected-results.json
similarity index 100%
rename from expectations/skimage/Test-Android-IntelRhb-SGX544-x86-Debug/expected-results.json
rename to expectations/skimage/Test-Android-Nexus5-Adreno330-Arm7-Debug/expected-results.json
diff --git a/expectations/skimage/Test-Android-IntelRhb-SGX544-x86-Release/expected-results.json b/expectations/skimage/Test-Android-Nexus5-Adreno330-Arm7-Release/expected-results.json
similarity index 100%
rename from expectations/skimage/Test-Android-IntelRhb-SGX544-x86-Release/expected-results.json
rename to expectations/skimage/Test-Android-Nexus5-Adreno330-Arm7-Release/expected-results.json
diff --git a/expectations/skimage/Test-Android-Reference-Unknown-Arm64-Debug/expected-results.json b/expectations/skimage/Test-Android-Reference-Unknown-Arm64-Debug/expected-results.json
new file mode 100644
index 0000000..53aa7c6
--- /dev/null
+++ b/expectations/skimage/Test-Android-Reference-Unknown-Arm64-Debug/expected-results.json
@@ -0,0 +1,784 @@
+{
+   "actual-results" : {
+      "failed" : null,
+      "failure-ignored" : null,
+      "no-comparison" : null,
+      "succeeded" : null
+   },
+   "expected-results" : {
+      "01-original-jpg-1088_810_1263_1227_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8119287607925761104 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg-1963_196_1981_1292_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 12836145563586703872 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg-331_234_1659_1063_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2969243348583428517 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg-757_60_969_301_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3907094952662683920 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg-928_190_1516_1068_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3440648846909211984 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6357612266670593419 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-1088_810_1263_1227_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5957882619838196067 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-1963_196_1981_1292_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6649439191540254120 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-331_234_1659_1063_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3996894105347440112 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-757_60_969_301_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17543681660269580194 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-928_190_1516_1068_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6128170287099328517 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13796732312180268210 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-1088_810_1263_1227_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2214068824839690652 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-1963_196_1981_1292_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14378130713468537275 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-331_234_1659_1063_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11701616052554565549 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-757_60_969_301_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5544352372572752888 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-928_190_1516_1068_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14472897486417411465 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6388620656649963843 ]
+         ],
+         "ignore-failure" : false
+      },
+      "1-bmp_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3196238483932704104 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-123_39_267_118_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8305989916569023174 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-125_106_235_142_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9624100960294255012 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-175_57_192_180_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2516216405763465877 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-96_203_108_205_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17942269483021635879 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-9_135_53_181_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10900471035558488354 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11012800850215976675 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-126_96_396_366_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6407475641463981743 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-231_217_485_452_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6150605659869149120 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-353_178_421_347_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14418789266100017433 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-39_68_311_448_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 1976861472606097846 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-430_402_497_495_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10122290901164585750 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8044662098954176130 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-12_123_200_201_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 16169634263361337441 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-137_64_188_200_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3917763264896407490 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-40_44_160_112_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15625465493494102443 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-53_48_126_117_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13352450420328173656 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-88_100_179_203_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2686434636485574525 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3518857344143029942 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-35_140_123_141_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15508139346878296592 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-45_140_161_180_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9437228090911164248 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-53_39_220_106_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14992889119901961376 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-80_58_175_123_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13686870895926309729 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-96_126_225_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9421160173812736481 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4640356172221432257 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-3193_312_4546_411_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2079877871524582959 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-363_304_2443_316_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8399520676954467047 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-3992_342_5448_706_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13504407073793777919 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-4801_345_6759_368_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11813583117121539570 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-961_338_4705_755_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9255198281132237123 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15493791864227637231 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Softskin-Series-Folder-Folder-TV-DEXTER-2-ico_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6383196142855109799 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-12_110_200_151_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 16977809602617047929 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-137_79_188_110_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5785490454447943918 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-40_88_160_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15532037766377872958 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-53_68_126_186_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3426516996035821680 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-88_72_179_81_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 536653090002276103 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 7518208176958373090 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-35_72_123_81_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8073164978716864831 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-45_88_161_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17164364735586543426 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-53_79_220_110_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 12921132848639790725 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-80_110_175_151_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11208235722978619114 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-96_68_225_186_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14917741574154016658 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10122895588403815825 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-112_747_575_810_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8966360222528656115 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-285_172_1115_356_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14803273480969617940 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-576_270_828_1068_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13492018660083785874 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-587_743_763_874_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 12129645989653494633 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-729_1021_1013_1100_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 639543039016497327 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 1194865470158040918 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17957846113312275139 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-416_270_748_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13712112352188536747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-445_116_1195_652_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15335849374473276073 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-495_267_832_570_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8026281099336453400 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-969_61_1013_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14270323850217953714 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4163734972868667214 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17957846113312275139 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-416_270_748_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13712112352188536747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-445_116_1195_652_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15335849374473276073 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-495_267_832_570_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8026281099336453400 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-969_61_1013_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14270323850217953714 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4163734972868667214 ]
+         ],
+         "ignore-failure" : false
+      },
+      "bmp-test-bmp_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13377769522785041821 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-123_74_587_711_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 853072107369632915 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-416_846_748_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6228679914993247968 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-445_972_1195_1012_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 16179873303613580557 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-495_634_832_651_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13299584507281094418 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-969_412_1013_829_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13961777034271921424 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15513164475782874663 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-11_7_35_10_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9340296159768970784 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-24_12_55_16_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17085239329526136435 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-42_3_54_14_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13153627359928650747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-67_0_70_1_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4425052328498175637 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-7_8_46_10_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5783519806456857766 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 168800254427225818 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-123_74_331_199_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10837571551891601196 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-245_317_457_412_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11529961394083056222 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-416_334_492_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2647533022907512881 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-427_460_445_500_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10600826856852254117 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-64_122_239_139_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8480971169511667766 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 76400998740744557 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-108_270_416_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9719677579409137284 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 92297153399217503 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-192_90_495_267_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11846257104075747997 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-329_61_373_380_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6187955895365891761 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-445_116_555_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 7321365207201114721 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3962535646133419277 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17957846113312275139 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-416_270_748_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13712112352188536747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-445_116_1195_652_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15335849374473276073 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-495_267_832_570_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8026281099336453400 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-969_61_1013_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14270323850217953714 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4163734972868667214 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17957846113312275139 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-416_270_748_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13712112352188536747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-445_116_1195_652_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15335849374473276073 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-495_267_832_570_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8026281099336453400 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-969_61_1013_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14270323850217953714 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4163734972868667214 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-126_221_1322_382_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6015818614679807304 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-305_170_636_571_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3553491475938567812 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-400_128_1367_649_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13519630188063928249 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-598_102_953_600_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5895887052682926570 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-72_480_870_558_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 762618565494735020 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13794277939360474741 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-108_270_416_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11199126684650393979 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 16263897892077508819 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-192_90_495_267_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 18306831335099361730 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-329_61_373_380_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14953310006143786464 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-445_116_555_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 1478691171816983364 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 7996831545507232176 ]
+         ],
+         "ignore-failure" : false
+      }
+   }
+}
diff --git a/expectations/skimage/Test-Android-Reference-Unknown-Arm64-Release/expected-results.json b/expectations/skimage/Test-Android-Reference-Unknown-Arm64-Release/expected-results.json
new file mode 100644
index 0000000..53aa7c6
--- /dev/null
+++ b/expectations/skimage/Test-Android-Reference-Unknown-Arm64-Release/expected-results.json
@@ -0,0 +1,784 @@
+{
+   "actual-results" : {
+      "failed" : null,
+      "failure-ignored" : null,
+      "no-comparison" : null,
+      "succeeded" : null
+   },
+   "expected-results" : {
+      "01-original-jpg-1088_810_1263_1227_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8119287607925761104 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg-1963_196_1981_1292_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 12836145563586703872 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg-331_234_1659_1063_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2969243348583428517 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg-757_60_969_301_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3907094952662683920 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg-928_190_1516_1068_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3440648846909211984 ]
+         ],
+         "ignore-failure" : false
+      },
+      "01-original-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6357612266670593419 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-1088_810_1263_1227_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5957882619838196067 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-1963_196_1981_1292_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6649439191540254120 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-331_234_1659_1063_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3996894105347440112 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-757_60_969_301_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17543681660269580194 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG-928_190_1516_1068_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6128170287099328517 ]
+         ],
+         "ignore-failure" : false
+      },
+      "02-empty-filter-JPG_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13796732312180268210 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-1088_810_1263_1227_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2214068824839690652 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-1963_196_1981_1292_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14378130713468537275 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-331_234_1659_1063_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11701616052554565549 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-757_60_969_301_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5544352372572752888 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG-928_190_1516_1068_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14472897486417411465 ]
+         ],
+         "ignore-failure" : false
+      },
+      "03-none-filter-JPG_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6388620656649963843 ]
+         ],
+         "ignore-failure" : false
+      },
+      "1-bmp_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3196238483932704104 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-123_39_267_118_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8305989916569023174 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-125_106_235_142_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9624100960294255012 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-175_57_192_180_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2516216405763465877 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-96_203_108_205_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17942269483021635879 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp-9_135_53_181_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10900471035558488354 ]
+         ],
+         "ignore-failure" : false
+      },
+      "5-sm-webp_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11012800850215976675 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-126_96_396_366_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6407475641463981743 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-231_217_485_452_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6150605659869149120 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-353_178_421_347_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14418789266100017433 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-39_68_311_448_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 1976861472606097846 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg-430_402_497_495_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10122290901164585750 ]
+         ],
+         "ignore-failure" : false
+      },
+      "CMYK-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8044662098954176130 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-12_123_200_201_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 16169634263361337441 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-137_64_188_200_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3917763264896407490 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-40_44_160_112_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15625465493494102443 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-53_48_126_117_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13352450420328173656 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg-88_100_179_203_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2686434636485574525 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Left-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3518857344143029942 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-35_140_123_141_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15508139346878296592 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-45_140_161_180_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9437228090911164248 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-53_39_220_106_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14992889119901961376 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-80_58_175_123_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13686870895926309729 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg-96_126_225_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9421160173812736481 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Lower-Right-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4640356172221432257 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-3193_312_4546_411_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2079877871524582959 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-363_304_2443_316_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8399520676954467047 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-3992_342_5448_706_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13504407073793777919 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-4801_345_6759_368_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11813583117121539570 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg-961_338_4705_755_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9255198281132237123 ]
+         ],
+         "ignore-failure" : false
+      },
+      "PANO-20121023-214540-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15493791864227637231 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Softskin-Series-Folder-Folder-TV-DEXTER-2-ico_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6383196142855109799 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-12_110_200_151_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 16977809602617047929 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-137_79_188_110_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5785490454447943918 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-40_88_160_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15532037766377872958 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-53_68_126_186_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3426516996035821680 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg-88_72_179_81_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 536653090002276103 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Left-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 7518208176958373090 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-35_72_123_81_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8073164978716864831 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-45_88_161_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17164364735586543426 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-53_79_220_110_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 12921132848639790725 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-80_110_175_151_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11208235722978619114 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg-96_68_225_186_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14917741574154016658 ]
+         ],
+         "ignore-failure" : false
+      },
+      "Upper-Right-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10122895588403815825 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-112_747_575_810_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8966360222528656115 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-285_172_1115_356_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14803273480969617940 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-576_270_828_1068_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13492018660083785874 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-587_743_763_874_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 12129645989653494633 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg-729_1021_1013_1100_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 639543039016497327 ]
+         ],
+         "ignore-failure" : false
+      },
+      "art-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 1194865470158040918 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17957846113312275139 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-416_270_748_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13712112352188536747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-445_116_1195_652_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15335849374473276073 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-495_267_832_570_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8026281099336453400 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg-969_61_1013_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14270323850217953714 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-jpeg-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4163734972868667214 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17957846113312275139 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-416_270_748_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13712112352188536747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-445_116_1195_652_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15335849374473276073 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-495_267_832_570_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8026281099336453400 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg-969_61_1013_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14270323850217953714 ]
+         ],
+         "ignore-failure" : false
+      },
+      "baseline-restart-jpeg-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4163734972868667214 ]
+         ],
+         "ignore-failure" : false
+      },
+      "bmp-test-bmp_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13377769522785041821 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-123_74_587_711_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 853072107369632915 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-416_846_748_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6228679914993247968 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-445_972_1195_1012_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 16179873303613580557 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-495_634_832_651_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13299584507281094418 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg-969_412_1013_829_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13961777034271921424 ]
+         ],
+         "ignore-failure" : false
+      },
+      "desk-yahoonews-0-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15513164475782874663 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-11_7_35_10_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9340296159768970784 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-24_12_55_16_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17085239329526136435 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-42_3_54_14_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13153627359928650747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-67_0_70_1_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4425052328498175637 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png-7_8_46_10_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5783519806456857766 ]
+         ],
+         "ignore-failure" : false
+      },
+      "kokteylogo-png_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 168800254427225818 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-123_74_331_199_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10837571551891601196 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-245_317_457_412_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11529961394083056222 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-416_334_492_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 2647533022907512881 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-427_460_445_500_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 10600826856852254117 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png-64_122_239_139_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8480971169511667766 ]
+         ],
+         "ignore-failure" : false
+      },
+      "photo-jpg-png_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 76400998740744557 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-108_270_416_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 9719677579409137284 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 92297153399217503 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-192_90_495_267_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11846257104075747997 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-329_61_373_380_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6187955895365891761 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png-445_116_555_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 7321365207201114721 ]
+         ],
+         "ignore-failure" : false
+      },
+      "png-test-png_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3962535646133419277 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17957846113312275139 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-416_270_748_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13712112352188536747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-445_116_1195_652_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15335849374473276073 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-495_267_832_570_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8026281099336453400 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg-969_61_1013_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14270323850217953714 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-jpeg-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4163734972868667214 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 17957846113312275139 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-416_270_748_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13712112352188536747 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-445_116_1195_652_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 15335849374473276073 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-495_267_832_570_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 8026281099336453400 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg-969_61_1013_860_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14270323850217953714 ]
+         ],
+         "ignore-failure" : false
+      },
+      "progressive-restart-jpeg-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 4163734972868667214 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-126_221_1322_382_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 6015818614679807304 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-305_170_636_571_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 3553491475938567812 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-400_128_1367_649_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13519630188063928249 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-598_102_953_600_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 5895887052682926570 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg-72_480_870_558_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 762618565494735020 ]
+         ],
+         "ignore-failure" : false
+      },
+      "tabl-mozilla-0-jpg_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 13794277939360474741 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-108_270_416_348_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 11199126684650393979 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-123_263_587_394_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 16263897892077508819 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-192_90_495_267_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 18306831335099361730 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-329_61_373_380_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 14953310006143786464 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp-445_116_555_172_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 1478691171816983364 ]
+         ],
+         "ignore-failure" : false
+      },
+      "webp-test-webp_8888.png" : {
+         "allowed-digests" : [
+            [ "bitmap-64bitMD5", 7996831545507232176 ]
+         ],
+         "ignore-failure" : false
+      }
+   }
+}
diff --git a/expectations/skimage/Test-Android-Venue8-PowerVR-x86-Debug/expected-results.json b/expectations/skimage/Test-Android-Venue8-PowerVR-x86-Debug/expected-results.json
new file mode 100644
index 0000000..ba5bb79
--- /dev/null
+++ b/expectations/skimage/Test-Android-Venue8-PowerVR-x86-Debug/expected-results.json
@@ -0,0 +1,4 @@
+{
+  "expected-results": {}
+}
+
diff --git a/expectations/skimage/Test-Android-Venue8-PowerVR-x86-Release/expected-results.json b/expectations/skimage/Test-Android-Venue8-PowerVR-x86-Release/expected-results.json
new file mode 100644
index 0000000..ba5bb79
--- /dev/null
+++ b/expectations/skimage/Test-Android-Venue8-PowerVR-x86-Release/expected-results.json
@@ -0,0 +1,4 @@
+{
+  "expected-results": {}
+}
+
diff --git a/expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json b/expectations/skimage/Test-ChromeOS-Link-HD4000-x86_64-Debug-Recipes/expected-results.json
similarity index 100%
copy from expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json
copy to expectations/skimage/Test-ChromeOS-Link-HD4000-x86_64-Debug-Recipes/expected-results.json
diff --git a/expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json b/expectations/skimage/Test-Ubuntu13.10-GCE-NoGPU-x86_64-Debug/expected-results.json
similarity index 100%
copy from expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json
copy to expectations/skimage/Test-Ubuntu13.10-GCE-NoGPU-x86_64-Debug/expected-results.json
diff --git a/expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json b/expectations/skimage/Test-Ubuntu13.10-GCE-NoGPU-x86_64-Release-Shared/expected-results.json
similarity index 100%
copy from expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json
copy to expectations/skimage/Test-Ubuntu13.10-GCE-NoGPU-x86_64-Release-Shared/expected-results.json
diff --git a/expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json b/expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug-Recipes/expected-results.json
similarity index 100%
rename from expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug/expected-results.json
rename to expectations/skimage/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug-Recipes/expected-results.json
diff --git a/expectations/skimage/Test-Win7-ShuttleA-HD2000-x86-Debug-DirectWrite/expected-results.json b/expectations/skimage/Test-Win7-ShuttleA-HD2000-x86-Debug-GDI/expected-results.json
similarity index 100%
rename from expectations/skimage/Test-Win7-ShuttleA-HD2000-x86-Debug-DirectWrite/expected-results.json
rename to expectations/skimage/Test-Win7-ShuttleA-HD2000-x86-Debug-GDI/expected-results.json
diff --git a/expectations/skimage/Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite/expected-results.json b/expectations/skimage/Test-Win7-ShuttleA-HD2000-x86-Release-GDI/expected-results.json
similarity index 100%
rename from expectations/skimage/Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite/expected-results.json
rename to expectations/skimage/Test-Win7-ShuttleA-HD2000-x86-Release-GDI/expected-results.json
diff --git a/third_party/harfbuzz/ChangeLog b/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-defaults.json
similarity index 100%
rename from third_party/harfbuzz/ChangeLog
rename to expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-defaults.json
diff --git a/third_party/harfbuzz/ChangeLog b/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-grid.json
similarity index 100%
copy from third_party/harfbuzz/ChangeLog
copy to expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-grid.json
diff --git a/third_party/harfbuzz/ChangeLog b/expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-defaults.json
similarity index 100%
copy from third_party/harfbuzz/ChangeLog
copy to expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-defaults.json
diff --git a/third_party/harfbuzz/ChangeLog b/expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-grid.json
similarity index 100%
copy from third_party/harfbuzz/ChangeLog
copy to expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-grid.json
diff --git a/third_party/harfbuzz/ChangeLog b/expectations/skp/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug-Recipes/renderskp-defaults.json
similarity index 100%
copy from third_party/harfbuzz/ChangeLog
copy to expectations/skp/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug-Recipes/renderskp-defaults.json
diff --git a/third_party/harfbuzz/ChangeLog b/expectations/skp/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug-Recipes/renderskp-grid.json
similarity index 100%
copy from third_party/harfbuzz/ChangeLog
copy to expectations/skp/Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug-Recipes/renderskp-grid.json
diff --git a/experimental/Intersection/CubicIntersection_Test.cpp b/experimental/Intersection/CubicIntersection_Test.cpp
index ffaa933..b43001b 100644
--- a/experimental/Intersection/CubicIntersection_Test.cpp
+++ b/experimental/Intersection/CubicIntersection_Test.cpp
@@ -245,7 +245,7 @@
                 intersections2.fPt[pt1].y, xy2.x, xy2.y, tt2);
 #endif
         SkASSERT(xy1.approximatelyEqual(xy2));
-#if SK_DEBUG
+#ifdef SK_DEBUG
         found = false;
         for (pt3 = 0; pt3 < intersections3.used(); ++pt3) {
             if (roughly_equal(tt1, intersections3.fT[0][pt3])) {
diff --git a/experimental/Intersection/CubicUtilities.cpp b/experimental/Intersection/CubicUtilities.cpp
index c9881c1..474dc5e 100644
--- a/experimental/Intersection/CubicUtilities.cpp
+++ b/experimental/Intersection/CubicUtilities.cpp
@@ -20,7 +20,7 @@
     return (width > height ? width : height) / gPrecisionUnit;
 }
 
-#if SK_DEBUG
+#ifdef SK_DEBUG
 double calcPrecision(const Cubic& cubic, double t, double scale) {
     Cubic part;
     sub_divide(cubic, SkTMax(0., t - scale), SkTMin(1., t + scale), part);
@@ -166,7 +166,7 @@
 }
 
 int cubicRootsReal(double A, double B, double C, double D, double s[3]) {
-#if SK_DEBUG
+#ifdef SK_DEBUG
     // create a string mathematica understands
     // GDB set print repe 15 # if repeated digits is a bother
     //     set print elements 400 # if line doesn't fit
diff --git a/experimental/Intersection/CubicUtilities.h b/experimental/Intersection/CubicUtilities.h
index b055619..eaf16a4 100644
--- a/experimental/Intersection/CubicUtilities.h
+++ b/experimental/Intersection/CubicUtilities.h
@@ -11,7 +11,7 @@
 #include "SkTDArray.h"
 
 double calcPrecision(const Cubic& cubic);
-#if SK_DEBUG
+#ifdef SK_DEBUG
 double calcPrecision(const Cubic& cubic, double t, double scale);
 #endif
 void chop_at(const Cubic& src, CubicPair& dst, double t);
diff --git a/experimental/Intersection/DataTypes.cpp b/experimental/Intersection/DataTypes.cpp
index a4a3039..3425ea9 100644
--- a/experimental/Intersection/DataTypes.cpp
+++ b/experimental/Intersection/DataTypes.cpp
@@ -38,7 +38,7 @@
 #endif
     int32_t i;
     float f;
-#if SK_DEBUG
+#ifdef SK_DEBUG
     struct
     {   // Bitfields for exploration. Do not use in production code.
         uint32_t mantissa : 23;
@@ -76,7 +76,7 @@
 }
 #endif
 
-#if SK_DEBUG
+#ifdef SK_DEBUG
 void mathematica_ize(char* str, size_t bufferLen) {
     size_t len = strlen(str);
     bool num = false;
diff --git a/experimental/Intersection/DataTypes.h b/experimental/Intersection/DataTypes.h
index 20dbef8..870a6de 100644
--- a/experimental/Intersection/DataTypes.h
+++ b/experimental/Intersection/DataTypes.h
@@ -409,7 +409,7 @@
 #define sk_double_isnan(a) sk_float_isnan(a)
 
 // FIXME: move these to debugging file
-#if SK_DEBUG
+#ifdef SK_DEBUG
 void mathematica_ize(char* str, size_t bufferSize);
 bool valid_wind(int winding);
 void winding_printf(int winding);
diff --git a/experimental/Intersection/Intersections.h b/experimental/Intersection/Intersections.h
index fc4c26c..a4135af 100644
--- a/experimental/Intersection/Intersections.h
+++ b/experimental/Intersection/Intersections.h
@@ -11,12 +11,12 @@
 public:
     Intersections()
         : fFlip(0)
-#if SK_DEBUG
+#ifdef SK_DEBUG
         , fDepth(0)
 #endif
         , fSwap(0)
     {
-#if SK_DEBUG
+#ifdef SK_DEBUG
         bzero(fPt, sizeof(fPt));
         bzero(fT, sizeof(fT));
         bzero(fIsCoincident, sizeof(fIsCoincident));
@@ -35,7 +35,7 @@
             if (fIsCoincident[0] & (1 << index)) {
                 ++count;
             }
-    #if SK_DEBUG
+    #ifdef SK_DEBUG
             if (fIsCoincident[1] & (1 << index)) {
                 ++count2;
             }
@@ -119,7 +119,7 @@
         SkASSERT(++fDepth < 16);
     }
 
-#if SK_DEBUG
+#ifdef SK_DEBUG
     int depth() const {
         return fDepth;
     }
@@ -131,7 +131,7 @@
     unsigned char fUsed;
     bool fFlip;
     bool fUnsortable;
-#if SK_DEBUG
+#ifdef SK_DEBUG
     int fDepth;
 #endif
 protected:
diff --git a/experimental/Intersection/QuadraticImplicit.cpp b/experimental/Intersection/QuadraticImplicit.cpp
index e2024f7..f16ddd9 100644
--- a/experimental/Intersection/QuadraticImplicit.cpp
+++ b/experimental/Intersection/QuadraticImplicit.cpp
@@ -13,7 +13,7 @@
 #include "QuadraticUtilities.h"
 #include "TSearch.h"
 
-#if SK_DEBUG
+#ifdef SK_DEBUG
 #include "LineUtilities.h"
 #endif
 
@@ -166,7 +166,7 @@
         int roots = intersect(q2, *testLines[index], rootTs);
         for (int idx2 = 0; idx2 < roots; ++idx2) {
             double t = rootTs.fT[0][idx2];
-#if SK_DEBUG
+#ifdef SK_DEBUG
         _Point qPt, lPt;
         xy_at_t(q2, t, qPt.x, qPt.y);
         xy_at_t(*testLines[index], rootTs.fT[1][idx2], lPt.x, lPt.y);
@@ -261,7 +261,7 @@
 static void relaxedIsLinear(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
     double m1 = flatMeasure(q1);
     double m2 = flatMeasure(q2);
-#if SK_DEBUG
+#ifdef SK_DEBUG
     double min = SkTMin(m1, m2);
     if (min > 5) {
         SkDebugf("%s maybe not flat enough.. %1.9g\n", __FUNCTION__, min);
diff --git a/experimental/Intersection/QuarticRoot.cpp b/experimental/Intersection/QuarticRoot.cpp
index 039a2c7..46bb4f5 100644
--- a/experimental/Intersection/QuarticRoot.cpp
+++ b/experimental/Intersection/QuarticRoot.cpp
@@ -32,7 +32,7 @@
 
 int reducedQuarticRoots(const double t4, const double t3, const double t2, const double t1,
         const double t0, const bool oneHint, double roots[4]) {
-#if SK_DEBUG
+#ifdef SK_DEBUG
     // create a string mathematica understands
     // GDB set print repe 15 # if repeated digits is a bother
     //     set print elements 400 # if line doesn't fit
diff --git a/experimental/PdfViewer/SkNulCanvas.h b/experimental/PdfViewer/SkNulCanvas.h
index a976ea4..49d276d 100644
--- a/experimental/PdfViewer/SkNulCanvas.h
+++ b/experimental/PdfViewer/SkNulCanvas.h
@@ -59,14 +59,11 @@
     virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE {return NULL;}
 
     virtual bool isClipEmpty() const SK_OVERRIDE { return false; }
-#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE
-    virtual ClipType getClipType() const SK_OVERRIDE { return kRect_ClipType; }
-#endif
     virtual bool getClipBounds(SkRect* bounds) const SK_OVERRIDE {
         if (NULL != bounds) {
             bounds->setXYWH(0, 0,
-                            SkIntToScalar(this->imageInfo().fWidth),
-                            SkIntToScalar(this->imageInfo().fHeight));
+                            SkIntToScalar(this->imageInfo().width()),
+                            SkIntToScalar(this->imageInfo().height()));
         }
         return true;
     }
@@ -103,7 +100,7 @@
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE {}
     virtual void onClipRegion(const SkRegion&, SkRegion::Op)  SK_OVERRIDE {}
 
-    virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE {}
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE {}
     
 private:
     typedef SkCanvas INHERITED;
diff --git a/experimental/PdfViewer/SkTrackDevice.h b/experimental/PdfViewer/SkTrackDevice.h
index 25857f6..ca4c689 100644
--- a/experimental/PdfViewer/SkTrackDevice.h
+++ b/experimental/PdfViewer/SkTrackDevice.h
@@ -29,10 +29,6 @@
     SkTrackDevice(const SkBitmap& bitmap) : SkBitmapDevice(bitmap)
                                           , fTracker(NULL) {}
 
-    SkTrackDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties)
-        : SkBitmapDevice(bitmap, deviceProperties)
-        , fTracker(NULL) {}
-
     virtual ~SkTrackDevice() {}
 
     // Install a tracker - we can reuse the tracker between multiple devices, and the state of the
diff --git a/experimental/PdfViewer/chop_transparency_main.cpp b/experimental/PdfViewer/chop_transparency_main.cpp
index 3f4b1fd..c79515d 100644
--- a/experimental/PdfViewer/chop_transparency_main.cpp
+++ b/experimental/PdfViewer/chop_transparency_main.cpp
@@ -157,7 +157,7 @@
                 if (!is_image_file(filename.c_str())) {
                     continue;
                 }
-                SkString fullname = SkOSPath::SkPathJoin(dir, filename.c_str());
+                SkString fullname = SkOSPath::Join(dir, filename.c_str());
                 decodeFileAndWrite(fullname.c_str());
             }
         } else if (sk_exists(readPath) && is_image_file(readPath)) {
diff --git a/experimental/PdfViewer/pdf_viewer_main.cpp b/experimental/PdfViewer/pdf_viewer_main.cpp
index 2f1a055..f5bfdbb 100644
--- a/experimental/PdfViewer/pdf_viewer_main.cpp
+++ b/experimental/PdfViewer/pdf_viewer_main.cpp
@@ -21,12 +21,6 @@
 #include "SkTArray.h"
 #include "SkNulCanvas.h"
 
-#if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
-#include "GrContext.h"
-#include "SkGpuDevice.h"
-#endif
-
 DEFINE_string2(readPath, r, "", "pdf files or directories of pdf files to process.");
 DEFINE_string2(writePath, w, "", "Directory to write the rendered pages.");
 DEFINE_bool2(noExtensionForOnePagePdf, n, false, "No page extension if only one page.");
@@ -42,18 +36,10 @@
 DEFINE_int32(benchLoad, 0, "Load the pdf file minimally N times, without any rendering and \n"
              "\tminimal parsing to ensure correctness. Default 0 (disabled).");
 DEFINE_int32(benchRender, 0, "Render the pdf content N times. Default 0 (disabled)");
-#if SK_SUPPORT_GPU
-DEFINE_string2(config, c, "8888", "Canvas to render:\n"
-                                  "\t8888 - argb\n"
-                                  "\tgpu: use the gpu\n"
-                                  "\tnul - render in null canvas, any draw will just return.\n"
-               );
-#else
 DEFINE_string2(config, c, "8888", "Canvas to render:\n"
                                   "\t8888 - argb\n"
                                   "\tnul - render in null canvas, any draw will just return.\n"
                );
-#endif
 DEFINE_bool2(transparentBackground, t, false, "Make background transparent instead of white.");
 
 /**
@@ -103,7 +89,7 @@
 static bool make_output_filepath(SkString* path, const SkString& dir,
                                  const SkString& name,
                                  int page) {
-    *path = SkOSPath::SkPathJoin(dir.c_str(), name.c_str());
+    *path = SkOSPath::Join(dir.c_str(), name.c_str());
     return add_page_and_replace_filename_extension(path, page,
                                                    PDF_FILE_EXTENSION,
                                                    PNG_FILE_EXTENSION);
@@ -126,10 +112,6 @@
 extern "C" SkCanvas* gDumpCanvas;
 #endif
 
-#if SK_SUPPORT_GPU
-GrContextFactory gContextFactory;
-#endif
-
 static bool render_page(const SkString& outputDir,
                         const SkString& inputFilename,
                         const SkPdfRenderer& renderer,
@@ -164,30 +146,7 @@
         SkAutoTUnref<SkBaseDevice> device;
         if (strcmp(FLAGS_config[0], "8888") == 0) {
             device.reset(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
-        }
-#if SK_SUPPORT_GPU
-        else if (strcmp(FLAGS_config[0], "gpu") == 0) {
-            SkAutoTUnref<GrSurface> target;
-            GrContext* gr = gContextFactory.get(GrContextFactory::kNative_GLContextType);
-            if (gr) {
-                // create a render target to back the device
-                GrTextureDesc desc;
-                desc.fConfig = kSkia8888_GrPixelConfig;
-                desc.fFlags = kRenderTarget_GrTextureFlagBit;
-                desc.fWidth = SkScalarCeilToInt(width);
-                desc.fHeight = SkScalarCeilToInt(height);
-                desc.fSampleCnt = 0;
-                target.reset(gr->createUncachedTexture(desc, NULL, 0));
-            }
-            if (NULL == target.get()) {
-                SkASSERT(0);
-                return false;
-            }
-
-            device.reset(SkGpuDevice::Create(target));
-        }
-#endif
-        else {
+        } else {
             SkDebugf("unknown --config: %s\n", FLAGS_config[0]);
             return false;
         }
@@ -220,7 +179,7 @@
 static bool process_pdf(const SkString& inputPath, const SkString& outputDir) {
     SkDebugf("Loading PDF:  %s\n", inputPath.c_str());
 
-    SkString inputFilename = SkOSPath::SkBasename(inputPath.c_str());
+    SkString inputFilename = SkOSPath::Basename(inputPath.c_str());
 
     SkAutoTDelete<SkPdfRenderer> renderer(SkPdfRenderer::CreateFromFile(inputPath.c_str()));
     if (NULL == renderer.get()) {
@@ -298,7 +257,7 @@
         SkOSFile::Iter iter(input, PDF_FILE_EXTENSION);
         SkString inputFilename;
         while (iter.next(&inputFilename)) {
-            SkString inputPath = SkOSPath::SkPathJoin(input, inputFilename.c_str());
+            SkString inputPath = SkOSPath::Join(input, inputFilename.c_str());
             if (!process_pdf(inputPath, outputDir)) {
                 ++failures;
             }
diff --git a/experimental/SimpleiOSApp/SimpleApp.mm b/experimental/SimpleiOSApp/SimpleApp.mm
index dba8bcc..040472c 100644
--- a/experimental/SimpleiOSApp/SimpleApp.mm
+++ b/experimental/SimpleiOSApp/SimpleApp.mm
@@ -1,11 +1,12 @@
+#include "SkApplication.h"
 #import "SkCanvas.h"
 #import "SkPaint.h"
 #import "SkWindow.h"
 #include "SkGraphics.h"
 #include "SkCGUtils.h"
 
-extern void tool_main(int argc, char *argv[]);
-void save_args(int argc, char *argv[]);
+void dummy_main(int , char *[]) {
+}
 
 class SkSampleView : public SkView {
 public:
@@ -41,9 +42,10 @@
 int saved_argc;
 char** saved_argv;
 
-void save_args(int argc, char *argv[]) {
+IOS_launch_type set_cmd_line_args(int argc, char *argv[], const char* ) {
     saved_argc = argc;
     saved_argv = argv;
+    return kTool_iOSLaunchType;
 }
 
 class FillLayout : public SkView::Layout {
@@ -58,7 +60,7 @@
 @implementation SimpleApp
 
 - (id)initWithDefaults {
-    (void) tool_main(saved_argc, saved_argv);
+    dummy_main(saved_argc, saved_argv);
     if (self = [super initWithDefaults]) {
         fWind = new SkOSWindow(self);
         fWind->setLayout(new FillLayout, false);
diff --git a/experimental/SkV8Example/Global.cpp b/experimental/SkV8Example/Global.cpp
index e8ad318..4bbdb7b 100644
--- a/experimental/SkV8Example/Global.cpp
+++ b/experimental/SkV8Example/Global.cpp
@@ -41,7 +41,7 @@
         fprintf(stderr, "%s\n", exceptionString);
     } else {
         // Print (filename):(line number): (message).
-        String::Utf8Value filename(message->GetScriptResourceName());
+        String::Utf8Value filename(message->GetScriptOrigin().ResourceName());
         const char* filenameString = to_cstring(filename);
         int linenum = message->GetLineNumber();
         fprintf(stderr,
diff --git a/experimental/benchtools/rebase.py b/experimental/benchtools/rebase.py
index 85290d7..f542454 100755
--- a/experimental/benchtools/rebase.py
+++ b/experimental/benchtools/rebase.py
@@ -32,9 +32,6 @@
 # Google Storage bench file prefix.
 GS_PREFIX = 'gs://chromium-skia-gm/perfdata'
 
-# List of Perf platforms we want to process. Populate from expectations/bench.
-PLATFORMS = []
-
 # Regular expression for matching githash data.
 HA_RE = '<a href="/skia/\+/([0-9a-f]+)">'
 HA_RE_COMPILED = re.compile(HA_RE)
@@ -88,17 +85,61 @@
     return True
   return False
 
-def calc_expectations(p, h, gs_dir, exp_dir, repo_dir):
+def get_expectations_dict(f):
+  """Given an expectations file f, returns a dictionary of data."""
+  # maps row_key to (expected, lower_bound, upper_bound) float tuple.
+  dic = {}
+  for l in open(f).readlines():
+    line_parts = l.strip().split(',')
+    if line_parts[0].startswith('#') or len(line_parts) != 5:
+      continue
+    dic[','.join(line_parts[:2])] = (float(line_parts[2]), float(line_parts[3]),
+                                     float(line_parts[4]))
+
+  return dic
+
+def calc_expectations(p, h, gs_dir, exp_dir, repo_dir, extra_dir, extra_hash):
   exp_filename = 'bench_expectations_%s.txt' % p
+  exp_fullname = os.path.join(exp_dir, exp_filename)
   proc = subprocess.Popen(['python', 'skia/bench/gen_bench_expectations.py',
-      '-r', h, '-b', p, '-d', os.path.join(gs_dir, p), '-o',
-          os.path.join(exp_dir, exp_filename)],
+      '-r', h, '-b', p, '-d', os.path.join(gs_dir, p), '-o', exp_fullname],
               stdout=subprocess.PIPE)
   out, err = proc.communicate()
   if err:
     print 'ERR_CALCULATING_EXPECTATIONS: ' + err
     return False
   print 'CALCULATED_EXPECTATIONS: ' + out
+  if extra_dir:  # Adjust data with the ones in extra_dir
+    print 'USE_EXTRA_DATA_FOR_ADJUSTMENT.'
+    proc = subprocess.Popen(['python', 'skia/bench/gen_bench_expectations.py',
+        '-r', extra_hash, '-b', p, '-d', os.path.join(extra_dir, p), '-o',
+            os.path.join(extra_dir, exp_filename)],
+                stdout=subprocess.PIPE)
+    out, err = proc.communicate()
+    if err:
+      print 'ERR_CALCULATING_EXTRA_EXPECTATIONS: ' + err
+      return False
+    extra_dic = get_expectations_dict(os.path.join(extra_dir, exp_filename))
+    output_lines = []
+    for l in open(exp_fullname).readlines():
+      parts = l.strip().split(',')
+      if parts[0].startswith('#') or len(parts) != 5:
+        output_lines.append(l.strip())
+        continue
+      key = ','.join(parts[:2])
+      if key in extra_dic:
+        exp, lb, ub = (float(parts[2]), float(parts[3]), float(parts[4]))
+        alt, _, _ = extra_dic[key]
+        avg = (exp + alt) / 2
+        # Keeps the extra range in lower/upper bounds from two actual values.
+        new_lb = min(exp, alt) - (exp - lb)
+        new_ub = max(exp, alt) + (ub - exp)
+        output_lines.append('%s,%.2f,%.2f,%.2f' % (key, avg, new_lb, new_ub))
+      else:
+        output_lines.append(l.strip())
+    with open(exp_fullname, 'w') as f:
+      f.write('\n'.join(output_lines))
+
   repo_file = os.path.join(repo_dir, 'expectations', 'bench', exp_filename)
   if (os.path.isfile(repo_file) and
       filecmp.cmp(repo_file, os.path.join(exp_dir, exp_filename))):
@@ -125,13 +166,16 @@
   os.chdir(old_cwd)
   return status
 
-def git_commit_expectations(repo_dir, exp_dir, update_li, h, commit):
-  commit_msg = """manual bench rebase after %s
+def git_commit_expectations(repo_dir, exp_dir, update_li, h, commit,
+                            extra_hash):
+  if extra_hash:
+    extra_hash = ', adjusted with ' + extra_hash
+  commit_msg = """manual bench rebase after %s%s
 
 TBR=robertphillips@google.com
 
 Bypassing trybots:
-NOTRY=true""" % h
+NOTRY=true""" % (h, extra_hash)
   old_cwd = os.getcwd()
   os.chdir(repo_dir)
   upload = ['git', 'cl', 'upload', '-f', '--bypass-hooks',
@@ -175,7 +219,14 @@
     return
   parser = argparse.ArgumentParser()
   parser.add_argument('--githash',
-                      help='Githash prefix (7+ chars) to rebaseline to.')
+                      help=('Githash prefix (7+ chars) to rebaseline to. If '
+                            'a second one is supplied after comma, and it has '
+                            'corresponding bench data, will shift the range '
+                            'center to the average of two expected values.'))
+  parser.add_argument('--bots',
+                      help=('Comma-separated list of bots to work on. If no '
+                            'matching bots are found in the list, will default '
+                            'to processing all bots.'))
   parser.add_argument('--commit', action='store_true',
                       help='Whether to commit changes automatically.')
   args = parser.parse_args()
@@ -193,30 +244,54 @@
     print 'Updated this script from repo; please run again.'
     return
 
+  all_platforms = []  # Find existing list of platforms with expectations.
   for item in os.listdir(os.path.join(d, 'skia/expectations/bench')):
-    PLATFORMS.append(
+    all_platforms.append(
         item.replace('bench_expectations_', '').replace('.txt', ''))
 
+  platforms = []
+  # If at least one given bot is in all_platforms, use list of valid args.bots.
+  if args.bots:
+    bots = args.bots.strip().split(',')
+    for bot in bots:
+      if bot in all_platforms:  # Filters platforms with given bot list.
+        platforms.append(bot)
+  if not platforms:  # Include all existing platforms with expectations.
+    platforms = all_platforms
+
   if not args.githash or len(args.githash) < 7:
     raise Exception('Please provide --githash with a longer prefix (7+).')
+  githashes = args.githash.strip().split(',')
+  if len(githashes[0]) < 7:
+    raise Exception('Please provide --githash with longer prefixes (7+).')
   commit = False
   if args.commit:
     commit = True
-  rebase_hash = args.githash[:7]
+  rebase_hash = githashes[0][:7]
+  extra_hash = ''
+  if len(githashes) == 2:
+    extra_hash = githashes[1][:7]
   hashes = get_git_hashes()
   short_hashes = [h[:7] for h in hashes]
-  if rebase_hash not in short_hashes:
-    raise Exception('Provided --githash not found in recent history!')
+  if (rebase_hash not in short_hashes or
+      (extra_hash and extra_hash not in short_hashes) or
+      rebase_hash == extra_hash):
+    raise Exception('Provided --githashes not found, or identical!')
+  if extra_hash:
+    extra_hash = hashes[short_hashes.index(extra_hash)]
   hashes = hashes[:short_hashes.index(rebase_hash) + 1]
   update_li = []
 
   ts_str = '%s' % time.time()
   gs_dir = os.path.join(d, 'gs' + ts_str)
   exp_dir = os.path.join(d, 'exp' + ts_str)
+  extra_dir = os.path.join(d, 'extra' + ts_str)
   clean_dir(gs_dir)
   clean_dir(exp_dir)
-  for p in PLATFORMS:
+  clean_dir(extra_dir)
+  for p in platforms:
     clean_dir(os.path.join(gs_dir, p))
+    clean_dir(os.path.join(extra_dir, p))
     hash_to_use = ''
     for h in reversed(hashes):
       li = get_gs_filelist(p, h)
@@ -230,18 +305,23 @@
         print 'DOWNLOAD BENCH FAILED %s/%s' % (p, h)
         break
     if hash_to_use:
-      if calc_expectations(p, h, gs_dir, exp_dir, repo_dir):
+      if extra_hash and download_gs_files(p, extra_hash, extra_dir):
+        print 'Copied extra data %s/%s' % (p, extra_hash)
+        if calc_expectations(p, h, gs_dir, exp_dir, repo_dir, extra_dir,
+                             extra_hash):
+          update_li.append('bench_expectations_%s.txt' % p)
+      elif calc_expectations(p, h, gs_dir, exp_dir, repo_dir, '', ''):
         update_li.append('bench_expectations_%s.txt' % p)
   if not update_li:
     print 'No bench data to update after %s!' % args.githash
   elif not git_commit_expectations(
-      repo_dir, exp_dir, update_li, args.githash[:7], commit):
+      repo_dir, exp_dir, update_li, rebase_hash, commit, extra_hash):
     print 'ERROR uploading expectations using git.'
   elif not commit:
     print 'CL created. Please take a look at the link above.'
   else:
     print 'New bench baselines should be in CQ now.'
-  delete_dirs([gs_dir, exp_dir])
+  delete_dirs([gs_dir, exp_dir, extra_dir])
 
 
 if __name__ == "__main__":
diff --git a/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-defaults.json b/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-defaults.json
new file mode 100644
index 0000000..47114b6
--- /dev/null
+++ b/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-defaults.json
@@ -0,0 +1,1346 @@
+{
+  "expected-results": {
+    "desk_baidu.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5510949507806706943", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_5510949507806706943.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4622418091259302841", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_4622418091259302841.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7705930371507694208", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_7705930371507694208.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12317749648466137796", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12317749648466137796.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13092743760936029533", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13092743760936029533.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14783408633137721173", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_14783408633137721173.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18085831060737163534", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_18085831060737163534.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1664185099925875810", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_1664185099925875810.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13783872130691114045", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13783872130691114045.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4251409765260720119", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_4251409765260720119.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15909889068299287523", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15909889068299287523.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15215602532725166577", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15215602532725166577.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12815364849356885672", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12815364849356885672.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13164588161148906052", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13164588161148906052.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2539157984787587772", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2539157984787587772.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1027331229460980498", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_1027331229460980498.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10477184082008794723", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_10477184082008794723.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16643765212098808703", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16643765212098808703.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17027327171337018732", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17027327171337018732.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17428317017476560348", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17428317017476560348.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5909337452074227103", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_5909337452074227103.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13302609138176228816", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13302609138176228816.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16858395402357368969", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16858395402357368969.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }, 
+    "desk_blogger.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18193696074589909928", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18193696074589909928.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6497701297353523037", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6497701297353523037.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11785152122139506459", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11785152122139506459.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18430208307346174630", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18430208307346174630.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16877428576881411401", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16877428576881411401.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2019481412010345810", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2019481412010345810.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15854601218802446421", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15854601218802446421.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15469534865109249405", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15469534865109249405.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6662796013602259314", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6662796013602259314.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16173971805930781909", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16173971805930781909.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15391249933675296541", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15391249933675296541.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18399440961969146567", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18399440961969146567.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6069040010646638133", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6069040010646638133.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6745453463705933528", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6745453463705933528.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "873197292128898639", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_873197292128898639.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12501067190077474731", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12501067190077474731.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12182843447128977645", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12182843447128977645.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "26773737329821472", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_26773737329821472.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9227736571607873653", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9227736571607873653.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "796682111958180573", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_796682111958180573.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5025228445659542827", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5025228445659542827.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8102640754580394584", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8102640754580394584.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13983369311423653591", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13983369311423653591.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7866999636262318063", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7866999636262318063.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8493174528435558164", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8493174528435558164.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9326417106879447920", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9326417106879447920.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16093948354673765421", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16093948354673765421.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11361934388533362154", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11361934388533362154.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8771978309291039635", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8771978309291039635.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10230062863412328400", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10230062863412328400.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2341453029778767862", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2341453029778767862.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3031422606891944260", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3031422606891944260.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2684293480018873967", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2684293480018873967.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17939753176675551940", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17939753176675551940.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15369960552495866504", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15369960552495866504.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3168314579830116147", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3168314579830116147.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13057211837426464782", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13057211837426464782.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16138926132656497197", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16138926132656497197.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17863239536507361583", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17863239536507361583.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10248905545368276433", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10248905545368276433.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7383323457948286876", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7383323457948286876.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14197795513211745038", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14197795513211745038.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4734987298013439083", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4734987298013439083.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15465284720103991575", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15465284720103991575.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5516480160298870797", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5516480160298870797.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13021672792550622692", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13021672792550622692.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3099173933603006251", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3099173933603006251.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16172889928626067999", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16172889928626067999.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15236078591758877622", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15236078591758877622.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6680102432844645833", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6680102432844645833.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16128165167478823048", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16128165167478823048.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3605252414081920514", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3605252414081920514.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16589129184558107315", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16589129184558107315.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6638093165109080854", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6638093165109080854.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9956115900941476755", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9956115900941476755.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8686898041074983968", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8686898041074983968.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9964189931096402288", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9964189931096402288.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6957505210631754297", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6957505210631754297.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10195939513068588505", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10195939513068588505.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7906582923153584382", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7906582923153584382.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18064618796114971019", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18064618796114971019.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11369907070287413693", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11369907070287413693.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7527290808416231356", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7527290808416231356.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "383738317842516145", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_383738317842516145.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15252208369879473582", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15252208369879473582.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "841943910542607154", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_841943910542607154.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4101647095708255832", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4101647095708255832.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10224131532229351507", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10224131532229351507.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10417063134679809185", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10417063134679809185.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17149322956605856579", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17149322956605856579.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17852070562173402509", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17852070562173402509.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5100603959220766123", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5100603959220766123.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6889850068780519491", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6889850068780519491.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "392170183229836145", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_392170183229836145.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14548182214395934108", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14548182214395934108.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9396525855978633839", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9396525855978633839.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15027461975863665772", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15027461975863665772.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14512247607555859904", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14512247607555859904.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4640376493988766790", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4640376493988766790.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16906327606017927194", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16906327606017927194.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1567144668892774143", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1567144668892774143.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16846477871394845568", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16846477871394845568.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13337526335316080955", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13337526335316080955.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12486618539850454912", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12486618539850454912.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3250469153123222089", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3250469153123222089.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10039760334491748169", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10039760334491748169.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8920840005472164712", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8920840005472164712.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10312960052215366927", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10312960052215366927.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9579612800481114333", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9579612800481114333.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10590514961500285791", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10590514961500285791.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4595240846166872319", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4595240846166872319.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "736390975313861599", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_736390975313861599.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4118383298795315325", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4118383298795315325.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13670063135855155613", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13670063135855155613.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4153691405972215108", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4153691405972215108.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2644951716624303240", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2644951716624303240.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11755522400750885035", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11755522400750885035.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16368577349712977363", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16368577349712977363.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9084154871324098052", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9084154871324098052.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2311531479661712409", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2311531479661712409.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5384569044418205202", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5384569044418205202.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5506206312736182193", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5506206312736182193.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }
+  }, 
+  "header": {
+    "revision": 1, 
+    "type": "ChecksummedImages"
+  }
+}
\ No newline at end of file
diff --git a/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-deferImageDecoding.json b/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-deferImageDecoding.json
new file mode 100644
index 0000000..6a86d87
--- /dev/null
+++ b/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-deferImageDecoding.json
@@ -0,0 +1,1346 @@
+{
+  "expected-results": {
+    "desk_baidu.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15416105200059008351", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15416105200059008351.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4973086474270251778", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_4973086474270251778.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18021596506523099808", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_18021596506523099808.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12426445537303847919", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12426445537303847919.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9876786765754472302", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9876786765754472302.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15331065111291899650", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15331065111291899650.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17539528729374288441", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17539528729374288441.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9100680979201226800", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9100680979201226800.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12173323263528710419", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12173323263528710419.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3712178768989178390", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_3712178768989178390.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "211888896324696047", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_211888896324696047.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7083400329331785041", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_7083400329331785041.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9815460630499410395", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9815460630499410395.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2473890974675091487", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2473890974675091487.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2479754884816755898", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2479754884816755898.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14172691682527577539", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_14172691682527577539.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5621989358731174221", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_5621989358731174221.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2194449339140901772", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2194449339140901772.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15475485765526191487", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15475485765526191487.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9104131931332113553", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9104131931332113553.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16302809368008861575", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16302809368008861575.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11599249512246895329", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_11599249512246895329.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16858395402357368969", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16858395402357368969.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }, 
+    "desk_blogger.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7841221974904480141", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7841221974904480141.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12952058328558118361", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12952058328558118361.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13438474142770400621", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13438474142770400621.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17305138246482099834", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17305138246482099834.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2339237720340106572", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2339237720340106572.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9133518276788097938", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9133518276788097938.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16768763127532639628", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16768763127532639628.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16108613879169710267", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16108613879169710267.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6781918266006344063", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6781918266006344063.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9062645238268733571", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9062645238268733571.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "172493045746957600", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_172493045746957600.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4296133301180502367", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4296133301180502367.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15638577549339283490", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15638577549339283490.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12644379640631274656", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12644379640631274656.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3352045847025161390", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3352045847025161390.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15123237272049632329", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15123237272049632329.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17808053363983400384", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17808053363983400384.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1870959069040666868", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1870959069040666868.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5578637393273578954", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5578637393273578954.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17468170000466055398", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17468170000466055398.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2798133757667981950", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2798133757667981950.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12056186299810582132", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12056186299810582132.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14805126467323821815", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14805126467323821815.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1262761629208254711", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1262761629208254711.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10017221126624110965", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10017221126624110965.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9326417106879447920", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9326417106879447920.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10732956852784776392", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10732956852784776392.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16796717901686899745", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16796717901686899745.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5284376332506067560", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5284376332506067560.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8445679907174827840", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8445679907174827840.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4045733944080058452", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4045733944080058452.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16573813979083448236", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16573813979083448236.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8964683934034389040", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8964683934034389040.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17571463359924121607", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17571463359924121607.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15369960552495866504", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15369960552495866504.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3487218210168886496", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3487218210168886496.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16116481139464372435", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16116481139464372435.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10175869703021583627", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10175869703021583627.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2495618649560987836", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2495618649560987836.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16700931713289358511", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16700931713289358511.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10828047253212456343", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10828047253212456343.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1375951298049525932", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1375951298049525932.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "43126774536983876", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_43126774536983876.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10994815648702250558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10994815648702250558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10721132518498860573", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10721132518498860573.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15521913976926340790", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15521913976926340790.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15462843448168743659", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15462843448168743659.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16172889928626067999", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16172889928626067999.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15236078591758877622", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15236078591758877622.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6680102432844645833", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6680102432844645833.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15178861613701060319", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15178861613701060319.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9821698822945749270", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9821698822945749270.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6533741389672656623", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6533741389672656623.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6631881651846346069", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6631881651846346069.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10474305944716211711", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10474305944716211711.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1456787145413697865", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1456787145413697865.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13598941742737334496", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13598941742737334496.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10872701498030761173", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10872701498030761173.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11936566152876930889", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11936566152876930889.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16948841223902088798", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16948841223902088798.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2075646102019337688", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2075646102019337688.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10328467874235548196", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10328467874235548196.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7754424482287838161", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7754424482287838161.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10187865664468729110", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10187865664468729110.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9692329142475544501", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9692329142475544501.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11805082683909040672", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11805082683909040672.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12055072783392081613", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12055072783392081613.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16415644052404953300", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16415644052404953300.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10417063134679809185", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10417063134679809185.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17149322956605856579", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17149322956605856579.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17852070562173402509", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17852070562173402509.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6009473361945447992", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6009473361945447992.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2906954880153437864", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2906954880153437864.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16159666950478632099", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16159666950478632099.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "434955267933854712", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_434955267933854712.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6964150898141519015", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6964150898141519015.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6940588501707502747", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6940588501707502747.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6763326955485442779", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6763326955485442779.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11068022256279202338", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11068022256279202338.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2092729783561167800", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2092729783561167800.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8259470553186264019", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8259470553186264019.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11439861493994832272", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11439861493994832272.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13337526335316080955", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13337526335316080955.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16032242154117966364", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16032242154117966364.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10022606368105601930", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10022606368105601930.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2626105827972108937", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2626105827972108937.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3856258771777886656", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3856258771777886656.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8213635271367467056", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8213635271367467056.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10608071113433085369", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10608071113433085369.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3035135943591931231", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3035135943591931231.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6241565033127932581", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6241565033127932581.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1210958474959001922", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1210958474959001922.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4118383298795315325", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4118383298795315325.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13670063135855155613", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13670063135855155613.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4153691405972215108", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4153691405972215108.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17317665081186813642", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17317665081186813642.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11606967570971750256", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11606967570971750256.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4714743017604436495", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4714743017604436495.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9084154871324098052", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9084154871324098052.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7664523892962060584", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7664523892962060584.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3214042322297598605", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3214042322297598605.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4036117529343107446", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4036117529343107446.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }
+  }, 
+  "header": {
+    "revision": 1, 
+    "type": "ChecksummedImages"
+  }
+}
\ No newline at end of file
diff --git a/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-grid.json b/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-grid.json
new file mode 100644
index 0000000..47114b6
--- /dev/null
+++ b/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-grid.json
@@ -0,0 +1,1346 @@
+{
+  "expected-results": {
+    "desk_baidu.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5510949507806706943", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_5510949507806706943.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4622418091259302841", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_4622418091259302841.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7705930371507694208", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_7705930371507694208.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12317749648466137796", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12317749648466137796.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13092743760936029533", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13092743760936029533.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14783408633137721173", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_14783408633137721173.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18085831060737163534", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_18085831060737163534.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1664185099925875810", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_1664185099925875810.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13783872130691114045", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13783872130691114045.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4251409765260720119", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_4251409765260720119.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15909889068299287523", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15909889068299287523.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15215602532725166577", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15215602532725166577.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12815364849356885672", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12815364849356885672.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13164588161148906052", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13164588161148906052.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2539157984787587772", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2539157984787587772.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1027331229460980498", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_1027331229460980498.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10477184082008794723", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_10477184082008794723.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16643765212098808703", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16643765212098808703.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17027327171337018732", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17027327171337018732.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17428317017476560348", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17428317017476560348.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5909337452074227103", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_5909337452074227103.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13302609138176228816", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13302609138176228816.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16858395402357368969", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16858395402357368969.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }, 
+    "desk_blogger.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18193696074589909928", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18193696074589909928.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6497701297353523037", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6497701297353523037.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11785152122139506459", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11785152122139506459.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18430208307346174630", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18430208307346174630.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16877428576881411401", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16877428576881411401.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2019481412010345810", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2019481412010345810.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15854601218802446421", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15854601218802446421.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15469534865109249405", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15469534865109249405.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6662796013602259314", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6662796013602259314.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16173971805930781909", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16173971805930781909.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15391249933675296541", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15391249933675296541.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18399440961969146567", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18399440961969146567.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6069040010646638133", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6069040010646638133.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6745453463705933528", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6745453463705933528.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "873197292128898639", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_873197292128898639.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12501067190077474731", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12501067190077474731.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12182843447128977645", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12182843447128977645.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "26773737329821472", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_26773737329821472.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9227736571607873653", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9227736571607873653.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "796682111958180573", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_796682111958180573.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5025228445659542827", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5025228445659542827.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8102640754580394584", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8102640754580394584.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13983369311423653591", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13983369311423653591.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7866999636262318063", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7866999636262318063.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8493174528435558164", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8493174528435558164.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9326417106879447920", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9326417106879447920.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16093948354673765421", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16093948354673765421.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11361934388533362154", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11361934388533362154.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8771978309291039635", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8771978309291039635.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10230062863412328400", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10230062863412328400.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2341453029778767862", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2341453029778767862.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3031422606891944260", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3031422606891944260.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2684293480018873967", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2684293480018873967.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17939753176675551940", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17939753176675551940.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15369960552495866504", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15369960552495866504.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3168314579830116147", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3168314579830116147.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13057211837426464782", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13057211837426464782.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16138926132656497197", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16138926132656497197.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17863239536507361583", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17863239536507361583.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10248905545368276433", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10248905545368276433.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7383323457948286876", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7383323457948286876.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14197795513211745038", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14197795513211745038.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4734987298013439083", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4734987298013439083.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15465284720103991575", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15465284720103991575.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5516480160298870797", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5516480160298870797.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13021672792550622692", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13021672792550622692.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3099173933603006251", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3099173933603006251.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16172889928626067999", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16172889928626067999.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15236078591758877622", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15236078591758877622.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6680102432844645833", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6680102432844645833.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16128165167478823048", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16128165167478823048.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3605252414081920514", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3605252414081920514.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16589129184558107315", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16589129184558107315.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6638093165109080854", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6638093165109080854.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9956115900941476755", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9956115900941476755.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8686898041074983968", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8686898041074983968.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9964189931096402288", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9964189931096402288.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6957505210631754297", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6957505210631754297.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10195939513068588505", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10195939513068588505.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7906582923153584382", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7906582923153584382.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18064618796114971019", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18064618796114971019.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11369907070287413693", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11369907070287413693.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7527290808416231356", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7527290808416231356.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "383738317842516145", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_383738317842516145.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15252208369879473582", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15252208369879473582.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "841943910542607154", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_841943910542607154.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4101647095708255832", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4101647095708255832.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10224131532229351507", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10224131532229351507.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10417063134679809185", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10417063134679809185.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17149322956605856579", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17149322956605856579.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17852070562173402509", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17852070562173402509.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5100603959220766123", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5100603959220766123.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6889850068780519491", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6889850068780519491.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "392170183229836145", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_392170183229836145.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14548182214395934108", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14548182214395934108.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9396525855978633839", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9396525855978633839.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15027461975863665772", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15027461975863665772.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14512247607555859904", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14512247607555859904.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4640376493988766790", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4640376493988766790.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16906327606017927194", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16906327606017927194.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1567144668892774143", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1567144668892774143.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16846477871394845568", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16846477871394845568.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13337526335316080955", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13337526335316080955.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12486618539850454912", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12486618539850454912.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3250469153123222089", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3250469153123222089.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10039760334491748169", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10039760334491748169.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8920840005472164712", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8920840005472164712.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10312960052215366927", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10312960052215366927.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9579612800481114333", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9579612800481114333.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10590514961500285791", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10590514961500285791.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4595240846166872319", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4595240846166872319.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "736390975313861599", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_736390975313861599.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4118383298795315325", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4118383298795315325.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13670063135855155613", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13670063135855155613.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4153691405972215108", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4153691405972215108.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2644951716624303240", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2644951716624303240.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11755522400750885035", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11755522400750885035.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16368577349712977363", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16368577349712977363.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9084154871324098052", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9084154871324098052.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2311531479661712409", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2311531479661712409.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5384569044418205202", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5384569044418205202.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5506206312736182193", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5506206312736182193.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }
+  }, 
+  "header": {
+    "revision": 1, 
+    "type": "ChecksummedImages"
+  }
+}
\ No newline at end of file
diff --git a/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-rtree.json b/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-rtree.json
new file mode 100644
index 0000000..6a86d87
--- /dev/null
+++ b/experimental/expectations/skp/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/renderskp-rtree.json
@@ -0,0 +1,1346 @@
+{
+  "expected-results": {
+    "desk_baidu.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15416105200059008351", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15416105200059008351.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4973086474270251778", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_4973086474270251778.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18021596506523099808", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_18021596506523099808.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12426445537303847919", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12426445537303847919.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9876786765754472302", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9876786765754472302.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15331065111291899650", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15331065111291899650.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17539528729374288441", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17539528729374288441.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9100680979201226800", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9100680979201226800.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12173323263528710419", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12173323263528710419.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3712178768989178390", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_3712178768989178390.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "211888896324696047", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_211888896324696047.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7083400329331785041", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_7083400329331785041.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9815460630499410395", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9815460630499410395.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2473890974675091487", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2473890974675091487.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2479754884816755898", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2479754884816755898.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14172691682527577539", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_14172691682527577539.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5621989358731174221", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_5621989358731174221.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2194449339140901772", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2194449339140901772.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15475485765526191487", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15475485765526191487.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9104131931332113553", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9104131931332113553.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16302809368008861575", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16302809368008861575.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11599249512246895329", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_11599249512246895329.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16858395402357368969", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16858395402357368969.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }, 
+    "desk_blogger.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7841221974904480141", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7841221974904480141.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12952058328558118361", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12952058328558118361.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13438474142770400621", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13438474142770400621.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17305138246482099834", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17305138246482099834.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2339237720340106572", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2339237720340106572.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9133518276788097938", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9133518276788097938.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16768763127532639628", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16768763127532639628.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16108613879169710267", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16108613879169710267.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6781918266006344063", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6781918266006344063.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9062645238268733571", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9062645238268733571.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "172493045746957600", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_172493045746957600.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4296133301180502367", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4296133301180502367.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15638577549339283490", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15638577549339283490.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12644379640631274656", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12644379640631274656.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3352045847025161390", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3352045847025161390.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15123237272049632329", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15123237272049632329.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17808053363983400384", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17808053363983400384.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1870959069040666868", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1870959069040666868.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5578637393273578954", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5578637393273578954.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17468170000466055398", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17468170000466055398.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2798133757667981950", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2798133757667981950.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12056186299810582132", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12056186299810582132.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14805126467323821815", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14805126467323821815.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1262761629208254711", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1262761629208254711.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10017221126624110965", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10017221126624110965.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9326417106879447920", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9326417106879447920.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10732956852784776392", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10732956852784776392.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16796717901686899745", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16796717901686899745.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5284376332506067560", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5284376332506067560.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8445679907174827840", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8445679907174827840.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4045733944080058452", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4045733944080058452.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16573813979083448236", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16573813979083448236.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8964683934034389040", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8964683934034389040.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17571463359924121607", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17571463359924121607.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15369960552495866504", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15369960552495866504.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3487218210168886496", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3487218210168886496.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16116481139464372435", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16116481139464372435.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10175869703021583627", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10175869703021583627.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2495618649560987836", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2495618649560987836.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16700931713289358511", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16700931713289358511.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10828047253212456343", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10828047253212456343.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1375951298049525932", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1375951298049525932.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "43126774536983876", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_43126774536983876.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10994815648702250558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10994815648702250558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10721132518498860573", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10721132518498860573.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15521913976926340790", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15521913976926340790.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15462843448168743659", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15462843448168743659.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16172889928626067999", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16172889928626067999.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15236078591758877622", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15236078591758877622.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6680102432844645833", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6680102432844645833.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15178861613701060319", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15178861613701060319.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9821698822945749270", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9821698822945749270.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6533741389672656623", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6533741389672656623.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6631881651846346069", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6631881651846346069.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10474305944716211711", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10474305944716211711.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1456787145413697865", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1456787145413697865.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13598941742737334496", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13598941742737334496.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10872701498030761173", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10872701498030761173.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11936566152876930889", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11936566152876930889.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16948841223902088798", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16948841223902088798.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2075646102019337688", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2075646102019337688.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10328467874235548196", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10328467874235548196.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7754424482287838161", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7754424482287838161.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10187865664468729110", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10187865664468729110.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9692329142475544501", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9692329142475544501.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11805082683909040672", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11805082683909040672.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12055072783392081613", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12055072783392081613.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16415644052404953300", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16415644052404953300.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10417063134679809185", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10417063134679809185.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17149322956605856579", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17149322956605856579.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17852070562173402509", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17852070562173402509.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6009473361945447992", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6009473361945447992.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2906954880153437864", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2906954880153437864.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16159666950478632099", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16159666950478632099.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "434955267933854712", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_434955267933854712.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6964150898141519015", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6964150898141519015.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6940588501707502747", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6940588501707502747.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6763326955485442779", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6763326955485442779.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11068022256279202338", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11068022256279202338.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2092729783561167800", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2092729783561167800.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8259470553186264019", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8259470553186264019.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11439861493994832272", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11439861493994832272.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13337526335316080955", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13337526335316080955.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16032242154117966364", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16032242154117966364.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10022606368105601930", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10022606368105601930.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2626105827972108937", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2626105827972108937.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3856258771777886656", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3856258771777886656.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8213635271367467056", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8213635271367467056.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10608071113433085369", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10608071113433085369.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3035135943591931231", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3035135943591931231.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6241565033127932581", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6241565033127932581.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1210958474959001922", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1210958474959001922.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4118383298795315325", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4118383298795315325.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13670063135855155613", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13670063135855155613.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4153691405972215108", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4153691405972215108.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17317665081186813642", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17317665081186813642.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11606967570971750256", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11606967570971750256.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4714743017604436495", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4714743017604436495.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9084154871324098052", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9084154871324098052.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7664523892962060584", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7664523892962060584.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3214042322297598605", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3214042322297598605.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4036117529343107446", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4036117529343107446.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }
+  }, 
+  "header": {
+    "revision": 1, 
+    "type": "ChecksummedImages"
+  }
+}
\ No newline at end of file
diff --git a/experimental/expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-defaults.json b/experimental/expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-defaults.json
new file mode 100644
index 0000000..8abffb3
--- /dev/null
+++ b/experimental/expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-defaults.json
@@ -0,0 +1,1346 @@
+{
+  "expected-results": {
+    "desk_baidu.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3103957207455402189", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_3103957207455402189.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11925568760951136415", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_11925568760951136415.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8888133269384212643", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_8888133269384212643.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17435217654509333124", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17435217654509333124.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2691218562276236261", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2691218562276236261.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13672224023108986449", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13672224023108986449.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7738965648261737420", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_7738965648261737420.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16810744210966367354", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16810744210966367354.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6435532870061265927", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_6435532870061265927.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15977263461823528082", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15977263461823528082.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9732930971450196281", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9732930971450196281.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9211406172407949768", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9211406172407949768.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "134411606574472711", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_134411606574472711.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12599858964862963121", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12599858964862963121.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11495683735352899084", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_11495683735352899084.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14368526869268404973", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_14368526869268404973.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "934067786525143945", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_934067786525143945.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14536710494262003674", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_14536710494262003674.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3949389531893113396", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_3949389531893113396.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1299411908358108494", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_1299411908358108494.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17276800542466300447", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17276800542466300447.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1854619144645237659", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_1854619144645237659.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16858395402357368969", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16858395402357368969.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }, 
+    "desk_blogger.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4409098515104762699", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4409098515104762699.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18063726072059682166", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18063726072059682166.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "578410399481473734", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_578410399481473734.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2589405255835792110", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2589405255835792110.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16526700744570463500", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16526700744570463500.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15427155972791686227", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15427155972791686227.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17189576784142909362", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17189576784142909362.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8143782940301948488", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8143782940301948488.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15923740601950322525", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15923740601950322525.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10468064568897259544", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10468064568897259544.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4764547265983582174", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4764547265983582174.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "555681830662279942", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_555681830662279942.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14759553433179345431", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14759553433179345431.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1931480068715411289", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1931480068715411289.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13654386293398306653", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13654386293398306653.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14073455342569729771", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14073455342569729771.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1109580770517590475", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1109580770517590475.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3680496870786029807", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3680496870786029807.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1424885171315687230", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1424885171315687230.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14196166553629708478", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14196166553629708478.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15404791874924753598", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15404791874924753598.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4165986149161562619", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4165986149161562619.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9856235210909150304", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9856235210909150304.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8802756878634943156", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8802756878634943156.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17535503900932381245", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17535503900932381245.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9326417106879447920", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9326417106879447920.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5178085763805992526", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5178085763805992526.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11869569364477193720", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11869569364477193720.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "548435612187582040", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_548435612187582040.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14179104895304717525", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14179104895304717525.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1934572640745902043", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1934572640745902043.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13160104162506982940", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13160104162506982940.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6115945743987553050", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6115945743987553050.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1283803438437923386", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1283803438437923386.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15369960552495866504", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15369960552495866504.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17071536272004227731", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17071536272004227731.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7003549960656976385", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7003549960656976385.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1594283046124638522", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1594283046124638522.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "972302601138260902", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_972302601138260902.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6227683145577307757", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6227683145577307757.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9457693224425111124", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9457693224425111124.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10955236939817798898", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10955236939817798898.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4438057092999264657", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4438057092999264657.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18114440324917939881", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18114440324917939881.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18006831638063341288", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18006831638063341288.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17433936882953789865", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17433936882953789865.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12723744419745085842", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12723744419745085842.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11613699191910703362", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11613699191910703362.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9557099198443573641", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9557099198443573641.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6680102432844645833", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6680102432844645833.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11837263834511675779", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11837263834511675779.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3870126445747712572", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3870126445747712572.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5236483905029898201", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5236483905029898201.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1536403971510144397", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1536403971510144397.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11270251894704189538", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11270251894704189538.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11048385056788108684", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11048385056788108684.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14925159620935787998", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14925159620935787998.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9548444977865406697", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9548444977865406697.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13901275459799646042", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13901275459799646042.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9500625502858480775", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9500625502858480775.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12963300397607994376", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12963300397607994376.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1040212142345063485", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1040212142345063485.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12782844368195151910", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12782844368195151910.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3988060650317583226", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3988060650317583226.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11079601822198307230", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11079601822198307230.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12896944502868948208", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12896944502868948208.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11600770619664464362", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11600770619664464362.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13969960985640821181", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13969960985640821181.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8869070581921666053", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8869070581921666053.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13147017370295037042", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13147017370295037042.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9279665181398103652", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9279665181398103652.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7303087569656196667", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7303087569656196667.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "706042466293040698", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_706042466293040698.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9957631787957492476", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9957631787957492476.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11467254681435763083", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11467254681435763083.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5481743975971658299", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5481743975971658299.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14356174681243099953", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14356174681243099953.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4698942479665102739", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4698942479665102739.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7893107362714041473", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7893107362714041473.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7106679553205561366", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7106679553205561366.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13380142741069001789", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13380142741069001789.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2746829924057212395", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2746829924057212395.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1285424446886417072", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1285424446886417072.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1709378357931948221", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1709378357931948221.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11080694908395382227", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11080694908395382227.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3240010718406782309", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3240010718406782309.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5320916944068509977", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5320916944068509977.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3236246394968999037", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3236246394968999037.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11060533057820057454", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11060533057820057454.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5235366103879424344", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5235366103879424344.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5281449086122419263", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5281449086122419263.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4245834217885058121", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4245834217885058121.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4543965757853917820", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4543965757853917820.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3573296526852807165", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3573296526852807165.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4499268025613836002", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4499268025613836002.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5182972607551661321", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5182972607551661321.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12386147276617332256", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12386147276617332256.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14014574075260666393", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14014574075260666393.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13784047907206805889", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13784047907206805889.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17302052631373368991", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17302052631373368991.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9651952082807389183", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9651952082807389183.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1768330543673562709", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1768330543673562709.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }
+  }, 
+  "header": {
+    "revision": 1, 
+    "type": "ChecksummedImages"
+  }
+}
\ No newline at end of file
diff --git a/experimental/expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-grid.json b/experimental/expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-grid.json
new file mode 100644
index 0000000..8abffb3
--- /dev/null
+++ b/experimental/expectations/skp/Test-Ubuntu12-ShuttleA-GTX660-x86-Release/renderskp-grid.json
@@ -0,0 +1,1346 @@
+{
+  "expected-results": {
+    "desk_baidu.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3103957207455402189", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_3103957207455402189.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11925568760951136415", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_11925568760951136415.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8888133269384212643", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_8888133269384212643.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17435217654509333124", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17435217654509333124.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2691218562276236261", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_2691218562276236261.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13672224023108986449", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_13672224023108986449.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7738965648261737420", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_7738965648261737420.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16810744210966367354", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16810744210966367354.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6435532870061265927", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_6435532870061265927.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15977263461823528082", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_15977263461823528082.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9732930971450196281", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9732930971450196281.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9211406172407949768", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_9211406172407949768.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "134411606574472711", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_134411606574472711.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12599858964862963121", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_12599858964862963121.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11495683735352899084", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_11495683735352899084.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14368526869268404973", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_14368526869268404973.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "934067786525143945", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_934067786525143945.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14536710494262003674", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_14536710494262003674.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3949389531893113396", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_3949389531893113396.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1299411908358108494", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_1299411908358108494.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17276800542466300447", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_17276800542466300447.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1854619144645237659", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_1854619144645237659.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16858395402357368969", 
+          "filepath": "desk_baidu_skp/bitmap-64bitMD5_16858395402357368969.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }, 
+    "desk_blogger.skp": {
+      "tiled-images": [
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4409098515104762699", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4409098515104762699.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18063726072059682166", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18063726072059682166.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "578410399481473734", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_578410399481473734.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2589405255835792110", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2589405255835792110.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "16526700744570463500", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_16526700744570463500.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15427155972791686227", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15427155972791686227.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17189576784142909362", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17189576784142909362.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8143782940301948488", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8143782940301948488.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15923740601950322525", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15923740601950322525.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10468064568897259544", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10468064568897259544.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4764547265983582174", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4764547265983582174.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "555681830662279942", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_555681830662279942.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14759553433179345431", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14759553433179345431.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1931480068715411289", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1931480068715411289.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13654386293398306653", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13654386293398306653.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14073455342569729771", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14073455342569729771.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1109580770517590475", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1109580770517590475.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3680496870786029807", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3680496870786029807.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1424885171315687230", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1424885171315687230.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14196166553629708478", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14196166553629708478.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15404791874924753598", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15404791874924753598.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4165986149161562619", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4165986149161562619.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9856235210909150304", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9856235210909150304.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8802756878634943156", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8802756878634943156.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17535503900932381245", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17535503900932381245.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9326417106879447920", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9326417106879447920.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5178085763805992526", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5178085763805992526.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11869569364477193720", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11869569364477193720.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "548435612187582040", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_548435612187582040.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14179104895304717525", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14179104895304717525.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1934572640745902043", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1934572640745902043.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13160104162506982940", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13160104162506982940.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6115945743987553050", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6115945743987553050.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1283803438437923386", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1283803438437923386.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "15369960552495866504", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_15369960552495866504.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17071536272004227731", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17071536272004227731.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7003549960656976385", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7003549960656976385.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1594283046124638522", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1594283046124638522.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "972302601138260902", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_972302601138260902.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6227683145577307757", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6227683145577307757.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9457693224425111124", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9457693224425111124.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "10955236939817798898", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_10955236939817798898.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4438057092999264657", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4438057092999264657.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18114440324917939881", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18114440324917939881.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "18006831638063341288", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_18006831638063341288.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17433936882953789865", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17433936882953789865.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12723744419745085842", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12723744419745085842.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11613699191910703362", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11613699191910703362.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9557099198443573641", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9557099198443573641.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "6680102432844645833", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_6680102432844645833.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11837263834511675779", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11837263834511675779.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3870126445747712572", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3870126445747712572.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5236483905029898201", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5236483905029898201.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1536403971510144397", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1536403971510144397.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11270251894704189538", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11270251894704189538.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11048385056788108684", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11048385056788108684.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14925159620935787998", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14925159620935787998.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9548444977865406697", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9548444977865406697.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13901275459799646042", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13901275459799646042.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9500625502858480775", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9500625502858480775.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12963300397607994376", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12963300397607994376.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1040212142345063485", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1040212142345063485.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12782844368195151910", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12782844368195151910.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3988060650317583226", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3988060650317583226.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11079601822198307230", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11079601822198307230.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12896944502868948208", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12896944502868948208.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11600770619664464362", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11600770619664464362.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13969960985640821181", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13969960985640821181.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "8869070581921666053", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_8869070581921666053.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13147017370295037042", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13147017370295037042.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9279665181398103652", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9279665181398103652.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7303087569656196667", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7303087569656196667.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "706042466293040698", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_706042466293040698.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9957631787957492476", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9957631787957492476.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11467254681435763083", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11467254681435763083.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5481743975971658299", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5481743975971658299.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14356174681243099953", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14356174681243099953.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4698942479665102739", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4698942479665102739.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7893107362714041473", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7893107362714041473.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "7106679553205561366", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_7106679553205561366.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13380142741069001789", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13380142741069001789.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "2746829924057212395", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_2746829924057212395.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1285424446886417072", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1285424446886417072.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1709378357931948221", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1709378357931948221.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11080694908395382227", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11080694908395382227.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3240010718406782309", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3240010718406782309.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5320916944068509977", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5320916944068509977.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3236246394968999037", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3236246394968999037.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "11060533057820057454", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_11060533057820057454.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5235366103879424344", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5235366103879424344.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5281449086122419263", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5281449086122419263.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4245834217885058121", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4245834217885058121.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4543965757853917820", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4543965757853917820.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "3573296526852807165", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_3573296526852807165.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "4499268025613836002", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_4499268025613836002.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "5182972607551661321", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_5182972607551661321.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "12386147276617332256", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_12386147276617332256.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "14014574075260666393", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_14014574075260666393.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "13784047907206805889", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_13784047907206805889.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "17302052631373368991", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_17302052631373368991.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "9651952082807389183", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_9651952082807389183.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "1768330543673562709", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_1768330543673562709.png", 
+          "reviewed-by-human": false
+        }, 
+        {
+          "bugs": null, 
+          "checksumAlgorithm": "bitmap-64bitMD5", 
+          "checksumValue": "702315074913249558", 
+          "filepath": "desk_blogger_skp/bitmap-64bitMD5_702315074913249558.png", 
+          "reviewed-by-human": false
+        }
+      ]
+    }
+  }, 
+  "header": {
+    "revision": 1, 
+    "type": "ChecksummedImages"
+  }
+}
\ No newline at end of file
diff --git a/experimental/iOSSampleApp/Shared/skia_ios.mm b/experimental/iOSSampleApp/Shared/skia_ios.mm
index 65b3e8a..45675fa 100644
--- a/experimental/iOSSampleApp/Shared/skia_ios.mm
+++ b/experimental/iOSSampleApp/Shared/skia_ios.mm
@@ -1,14 +1,17 @@
 #import <UIKit/UIKit.h>
 #include "SkApplication.h"
 
-extern void save_args(int argc, char *argv[]);
-
 int main(int argc, char *argv[]) {
     signal(SIGPIPE, SIG_IGN);
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
     application_init();
-    save_args(argc, argv);
-    int retVal = UIApplicationMain(argc, argv, nil, nil);
+    // Identify the documents directory
+    NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+    NSString *docsDir = [dirPaths objectAtIndex:0];
+    const char *d = [docsDir UTF8String];
+    IOS_launch_type launchType = set_cmd_line_args(argc, argv, d);
+    int retVal = launchType == kApplication__iOSLaunchType
+            ? UIApplicationMain(argc, argv, nil, nil) : (int) launchType;
     application_term();
     [pool release];
     return retVal;
diff --git a/experimental/iOSShell/iOSShell-Info.plist b/experimental/iOSShell/iOSShell-Info.plist
new file mode 100644
index 0000000..69b62ef
--- /dev/null
+++ b/experimental/iOSShell/iOSShell-Info.plist
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.google.iOSShell</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSMainNibFile</key>
+	<string>MainWindow_iPhone</string>
+	<key>NSMainNibFile~ipad</key>
+	<string>MainWindow_iPad</string>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+</dict>
+</plist>
diff --git a/experimental/nanomsg/picture_demo.cpp b/experimental/nanomsg/picture_demo.cpp
index 5a3ebdc..5efa03c 100644
--- a/experimental/nanomsg/picture_demo.cpp
+++ b/experimental/nanomsg/picture_demo.cpp
@@ -82,9 +82,9 @@
     SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&stream));
 
     PictureHeader header;
-    SkRandom rand(picture->width() * picture->height());
-    SkScalar r = rand.nextRangeScalar(0, picture->width()),
-             b = rand.nextRangeScalar(0, picture->height()),
+    SkRandom rand(picture->cullRect().width() * picture->cullRect().height());
+    SkScalar r = rand.nextRangeScalar(0, picture->cullRect().width()),
+             b = rand.nextRangeScalar(0, picture->cullRect().height()),
              l = rand.nextRangeScalar(0, r),
              t = rand.nextRangeScalar(0, b);
     header.clip.setLTRB(l,t,r,b);
@@ -152,7 +152,7 @@
         canvas->saveLayer(NULL, &paint);
             canvas->concat(header.matrix);
             canvas->clipRect(header.clip);
-            picture->draw(canvas);
+            picture->playback(canvas);
         canvas->restore();
         SkDebugf(" drew");
 
diff --git a/experimental/webtry/DESIGN.md b/experimental/webtry/DESIGN.md
index a179c04..c2e3d19 100644
--- a/experimental/webtry/DESIGN.md
+++ b/experimental/webtry/DESIGN.md
@@ -89,7 +89,7 @@
 
     sudo /etc/init.d/webtry [start|stop|restart]
 
-By sysv init only handles starting and stopping a program once, so we use
+But sysv init only handles starting and stopping a program once, so we use
 Monit to monitor the application and restart it if it crashes. The config
 is in:
 
diff --git a/experimental/webtry/build b/experimental/webtry/build
new file mode 100755
index 0000000..44791a2
--- /dev/null
+++ b/experimental/webtry/build
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# This script builds the webtry server; before compilation we need to create the code template
+# so that it contains all publicly available header files in skia/include.
+#
+# By default, the script expects to be run out of the skia/experimental/webtry directory; 
+# if we move directories around this can be overridden by setting the SKIA_ROOT and WEBTRY_ROOT
+# environment variables to point to the skia source tree and the webtry source tree, 
+# respectively.
+
+[ -z "$SKIA_ROOT" ] && SKIA_ROOT="../.."
+[ -z "$WEBTRY_ROOT" ] && WEBTRY_ROOT=`pwd`
+
+cd ${SKIA_ROOT}/include
+echo "Creating compile template..."
+find core effects pathops  -maxdepth 1 -name "*.h" | sed "s#^[^\/]*\/##g" | sed "s/\(.*\)/#include \"\1\"/" | sort > ${WEBTRY_ROOT}/templates/template.cpp
+echo "SkBitmap source;" >> ${WEBTRY_ROOT}/templates/template.cpp
+echo "{{.Code}}" >> ${WEBTRY_ROOT}/templates/template.cpp
+cd ${WEBTRY_ROOT}
+echo "Building webtry..."
+go build webtry.go
+echo "Done!"
diff --git a/experimental/webtry/gyp_for_webtry b/experimental/webtry/gyp_for_webtry
new file mode 100755
index 0000000..374c02a
--- /dev/null
+++ b/experimental/webtry/gyp_for_webtry
@@ -0,0 +1,43 @@
+#!/usr/bin/python
+import os
+import sys
+
+script_dir = os.path.dirname(__file__)
+
+skia_src = os.path.abspath(os.environ.get('SKIA_SRC', os.path.join( script_dir, "..", "..")))
+gyp_source_dir = os.path.join(skia_src, 'third_party', 'externals', 'gyp')
+
+WEBTRY_CACHE_DEFAULT = os.path.join(script_dir, "..", "..", "..", "cache")
+WEBTRY_INOUT_DEFAULT = os.path.join(script_dir, "..", "..", "..", "inout")
+
+sys.path.insert(0, os.path.abspath(os.path.join(gyp_source_dir, 'pylib')))
+import gyp
+
+if __name__ == '__main__':
+  if len(sys.argv) < 2:
+    print "Usage: gyp_for_webtry [code hash value]"
+    sys.exit(-1) 
+
+  args = sys.argv[2:]
+
+  if not os.environ.get('GYP_GENERATORS'):
+    os.environ['GYP_GENERATORS'] = 'ninja'
+
+  args.append('--check')
+  args.append('-I%s/gyp/common.gypi' % skia_src)
+  args.extend(['--depth', '.'])
+  webtry_cache_dir = os.path.abspath(os.environ.get('WEBTRY_CACHE', WEBTRY_CACHE_DEFAULT))
+  webtry_inout_dir = os.path.abspath(os.environ.get('WEBTRY_INOUT', WEBTRY_INOUT_DEFAULT))
+
+  args.append('-Goutput_dir=%s' % webtry_inout_dir)
+
+  args.append(os.path.join(webtry_cache_dir, '%s.gyp' % sys.argv[1]))
+
+  # gyp is really picky about the current working directory having src/ under it
+  os.chdir(webtry_cache_dir)
+
+  os.environ['CC'] = '../../skia/experimental/webtry/safec'
+  os.environ['CXX'] = '../../skia/experimental/webtry/safec++'
+  os.environ['LD'] = '../../skia/experimental/webtry/safec++'
+
+  sys.exit(gyp.main(args))
diff --git a/experimental/webtry/main.cpp b/experimental/webtry/main.cpp
index 44f8aab..b2c06c0 100644
--- a/experimental/webtry/main.cpp
+++ b/experimental/webtry/main.cpp
@@ -23,6 +23,8 @@
 extern SkBitmap source;
 
 static bool install_syscall_filter() {
+
+#ifndef SK_UNSAFE_BUILD_DESKTOP_ONLY
     struct sock_filter filter[] = {
         /* Grab the system call number. */
         EXAMINE_SYSCALL,
@@ -64,6 +66,9 @@
         fprintf(stderr, "SECCOMP_FILTER is not available. :(\n");
     }
     return false;
+#else
+    return true;
+#endif /* SK_UNSAFE_BUILD_DESKTOP_ONLY */
 }
 
 static void setLimits() {
diff --git a/experimental/webtry/res/css/webtry.css b/experimental/webtry/res/css/webtry.css
index 09751df..246fb9b 100644
--- a/experimental/webtry/res/css/webtry.css
+++ b/experimental/webtry/res/css/webtry.css
@@ -125,4 +125,10 @@
 
 .CodeMirror {
   border: solid gray 1px;
+  height: auto;
+}
+
+.CodeMirror-scroll {
+  overflow-y: hidden;
+  overflow-x: auto;
 }
diff --git a/experimental/webtry/res/js/webtry.js b/experimental/webtry/res/js/webtry.js
index b24501e..b673e09 100644
--- a/experimental/webtry/res/js/webtry.js
+++ b/experimental/webtry/res/js/webtry.js
@@ -11,7 +11,7 @@
  * namespace. If workspaceName is the empty string then we know we aren't
  * running on a workspace page.
  *
- * If we are on a workspace page we also look for a 'history'
+ * If we are on a workspace page we also look for a 'history_'
  * variable in the global namespace which contains the list of tries
  * that are included in this workspace. That variable is used to
  * populate the history list.
@@ -286,9 +286,9 @@
       }
 
       // Add the images to the history if we are on a workspace page.
-      if (tryHistory && history) {
-        for (var i=0; i<history.length; i++) {
-          addToHistory(history[i].hash, '/i/'+history[i].hash+'.png');
+      if (tryHistory && history_) {
+        for (var i=0; i<history_.length; i++) {
+          addToHistory(history_[i].hash, '/i/'+history_[i].hash+'.png');
         }
       }
     }
@@ -297,7 +297,7 @@
     if (document.readyState != "loading") {
       onLoad();
     } else {
-      this.addEventListener('DOMContentLoaded', onLoad);
+      this.addEventListener('load', onLoad);
     }
 
 })();
diff --git a/experimental/webtry/safec b/experimental/webtry/safec
new file mode 100755
index 0000000..9cc5771
--- /dev/null
+++ b/experimental/webtry/safec
@@ -0,0 +1,7 @@
+#!/bin/bash
+# Limit the amount of time and the core size for the compiler.
+set -e
+
+ulimit -t 5 -c 0
+
+cc $@
diff --git a/experimental/webtry/seccomp_bpf.h b/experimental/webtry/seccomp_bpf.h
index 02bf3cf..bf72f9a 100644
--- a/experimental/webtry/seccomp_bpf.h
+++ b/experimental/webtry/seccomp_bpf.h
@@ -14,6 +14,8 @@
 #ifndef _SECCOMP_BPF_H_
 #define _SECCOMP_BPF_H_
 
+#ifndef SK_UNSAFE_BUILD_DESKTOP_ONLY
+
 #define _GNU_SOURCE 1
 #include <stdio.h>
 #include <stddef.h>
@@ -62,4 +64,6 @@
 #define KILL_PROCESS \
     BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
 
+#endif /* SK_UNSAFE_BUILD_DESKTOP_ONLY */
+
 #endif /* _SECCOMP_BPF_H_ */
diff --git a/experimental/webtry/setup/continue_install b/experimental/webtry/setup/continue_install
index 7891be4..1959ee7 100755
--- a/experimental/webtry/setup/continue_install
+++ b/experimental/webtry/setup/continue_install
@@ -30,6 +30,7 @@
 export PATH=$PATH:$GOROOT/bin
 
 mkdir /home/webtry/cache
+mkdir /home/webtry/cache/src
 mkdir /home/webtry/inout
 chmod 777 /home/webtry/inout
 
diff --git a/experimental/webtry/templates/template.cpp b/experimental/webtry/templates/template.cpp
deleted file mode 100644
index 6c5cfa8..0000000
--- a/experimental/webtry/templates/template.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-// To regenerate this list of includes run the following command from skia/include:
-//
-//     find core effects pathops  -maxdepth 1 -name "*.h" | sed "s#^[^\/]*\/##g" | sed "s/\(.*\)/#include \"\1\"/" | sort
-//
-#include "Sk1DPathEffect.h"
-#include "Sk2DPathEffect.h"
-#include "SkAdvancedTypefaceMetrics.h"
-#include "SkAlphaThresholdFilter.h"
-#include "SkAnnotation.h"
-#include "SkArithmeticMode.h"
-#include "SkAvoidXfermode.h"
-#include "SkBBHFactory.h"
-#include "SkBicubicImageFilter.h"
-#include "SkBitmapDevice.h"
-#include "SkBitmap.h"
-#include "SkBitmapSource.h"
-#include "SkBlitRow.h"
-#include "SkBlurDrawLooper.h"
-#include "SkBlurImageFilter.h"
-#include "SkBlurMaskFilter.h"
-#include "SkBlurTypes.h"
-#include "SkCanvas.h"
-#include "SkChecksum.h"
-#include "SkChunkAlloc.h"
-#include "SkClipStack.h"
-#include "SkColorFilter.h"
-#include "SkColorFilterImageFilter.h"
-#include "SkColor.h"
-#include "SkColorMatrixFilter.h"
-#include "SkColorMatrix.h"
-#include "SkColorPriv.h"
-#include "SkColorShader.h"
-#include "SkColorTable.h"
-#include "SkComposeImageFilter.h"
-#include "SkComposeShader.h"
-#include "SkCornerPathEffect.h"
-#include "SkDashPathEffect.h"
-#include "SkData.h"
-#include "SkDataTable.h"
-#include "SkDeque.h"
-#include "SkDevice.h"
-#include "SkDeviceProperties.h"
-#include "SkDiscretePathEffect.h"
-#include "SkDisplacementMapEffect.h"
-#include "SkDither.h"
-#include "SkDocument.h"
-#include "SkDrawExtraPathEffect.h"
-#include "SkDrawFilter.h"
-#include "SkDraw.h"
-#include "SkDrawLooper.h"
-#include "SkDropShadowImageFilter.h"
-#include "SkDynamicAnnotations.h"
-#include "SkEmbossMaskFilter.h"
-#include "SkEmptyShader.h"
-#include "SkEndian.h"
-#include "SkError.h"
-#include "SkFixed.h"
-#include "SkFlate.h"
-#include "SkFlattenableBuffers.h"
-#include "SkFlattenable.h"
-#include "SkFlattenableSerialization.h"
-#include "SkFloatBits.h"
-#include "SkFloatingPoint.h"
-#include "SkFont.h"
-#include "SkFontHost.h"
-#include "SkFontLCDConfig.h"
-#include "SkGeometry.h"
-#include "SkGradientShader.h"
-#include "SkGraphics.h"
-#include "SkImageDecoder.h"
-#include "SkImageEncoder.h"
-#include "SkImageFilter.h"
-#include "SkImageGenerator.h"
-#include "SkImage.h"
-#include "SkImageInfo.h"
-#include "SkInstCnt.h"
-#include "SkLayerDrawLooper.h"
-#include "SkLayerRasterizer.h"
-#include "SkLerpXfermode.h"
-#include "SkLightingImageFilter.h"
-#include "SkLineClipper.h"
-#include "SkLumaColorFilter.h"
-#include "SkMagnifierImageFilter.h"
-#include "SkMallocPixelRef.h"
-#include "SkMaskFilter.h"
-#include "SkMask.h"
-#include "SkMath.h"
-#include "SkMatrixConvolutionImageFilter.h"
-#include "SkMatrix.h"
-#include "SkMatrixImageFilter.h"
-#include "SkMergeImageFilter.h"
-#include "SkMetaData.h"
-#include "SkMorphologyImageFilter.h"
-#include "SkOffsetImageFilter.h"
-#include "SkOnce.h"
-#include "SkOSFile.h"
-#include "SkPackBits.h"
-#include "SkPaintFlagsDrawFilter.h"
-#include "SkPaint.h"
-#include "SkPaintOptionsAndroid.h"
-#include "SkPathEffect.h"
-#include "SkPath.h"
-#include "SkPathMeasure.h"
-#include "SkPathOps.h"
-#include "SkPathRef.h"
-#include "SkPerlinNoiseShader.h"
-#include "SkPicture.h"
-#include "SkPictureImageFilter.h"
-#include "SkPictureRecorder.h"
-#include "SkPixelRef.h"
-#include "SkPixelXorXfermode.h"
-#include "SkPoint.h"
-#include "SkPorterDuff.h"
-#include "SkPostConfig.h"
-#include "SkPreConfig.h"
-#include "SkRasterizer.h"
-#include "SkReadBuffer.h"
-#include "SkReader32.h"
-#include "SkRect.h"
-#include "SkRectShaderImageFilter.h"
-#include "SkRefCnt.h"
-#include "SkRegion.h"
-#include "SkRRect.h"
-#include "SkScalar.h"
-#include "SkShader.h"
-#include "SkSize.h"
-#include "SkStippleMaskFilter.h"
-#include "SkStream.h"
-#include "SkString.h"
-#include "SkStringUtils.h"
-#include "SkStrokeRec.h"
-#include "SkSurface.h"
-#include "SkTableColorFilter.h"
-#include "SkTableMaskFilter.h"
-#include "SkTArray.h"
-#include "SkTDArray.h"
-#include "SkTDict.h"
-#include "SkTDStack.h"
-#include "SkTemplates.h"
-#include "SkTestImageFilters.h"
-#include "SkThread.h"
-#include "SkTileImageFilter.h"
-#include "SkTime.h"
-#include "SkTInternalLList.h"
-#include "SkTLazy.h"
-#include "SkTransparentShader.h"
-#include "SkTRegistry.h"
-#include "SkTSearch.h"
-#include "SkTypeface.h"
-#include "SkTypes.h"
-#include "SkUnPreMultiply.h"
-#include "SkUtils.h"
-#include "SkVertState.h"
-#include "SkWeakRefCnt.h"
-#include "SkWriteBuffer.h"
-#include "SkWriter32.h"
-#include "SkXfermode.h"
-#include "SkXfermodeImageFilter.h"
-
-SkBitmap source;
-
-{{.Code}}
diff --git a/experimental/webtry/templates/template.gyp b/experimental/webtry/templates/template.gyp
new file mode 100644
index 0000000..d0486dc
--- /dev/null
+++ b/experimental/webtry/templates/template.gyp
@@ -0,0 +1,34 @@
+{
+  'targets': [
+    {
+      'configurations': {
+        'Debug': { },
+        'Release': { }
+      },
+      'cflags!': [
+        '-Werror'
+      ],
+      'target_name': '{{.Hash}}',
+      'type': 'executable',
+      'dependencies': [
+        '../skia/gyp/skia_lib.gyp:skia_lib',
+        '../skia/gyp/flags.gyp:flags'
+      ],
+      'include_dirs': [
+        '../skia/include/config',
+        '../skia/include/core',
+        '../skia/tools/flags',
+        '../skia/src/core',
+      ],
+      'conditions': [
+        ['skia_os == "mac"', {
+                'defines': ['SK_UNSAFE_BUILD_DESKTOP_ONLY=1']
+        }]
+      ],
+      'sources': [
+        'src/{{.Hash}}.cpp',
+        '../skia/experimental/webtry/main.cpp'
+      ],
+    }
+  ]
+}
diff --git a/experimental/webtry/templates/workspace.html b/experimental/webtry/templates/workspace.html
index 9694a35..cb7a827 100644
--- a/experimental/webtry/templates/workspace.html
+++ b/experimental/webtry/templates/workspace.html
@@ -19,7 +19,8 @@
   </section>
 
   <script type='text/javascript'>
-    var history = {{.Tries}};
+    var history_ = {{.Tries}};
+    console.log(history_);
   </script>
   <script type='text/javascript'>
       // Set the workspace name so run.js also updates the history.
diff --git a/experimental/webtry/webtry.go b/experimental/webtry/webtry.go
index 93e78c4..fd512de 100644
--- a/experimental/webtry/webtry.go
+++ b/experimental/webtry/webtry.go
@@ -36,8 +36,8 @@
 )
 
 const (
-	RESULT_COMPILE = `../../experimental/webtry/safec++ -DSK_GAMMA_SRGB -DSK_GAMMA_APPLY_TO_A8 -DSK_SCALAR_TO_FLOAT_EXCLUDED -DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1 -DSK_SUPPORT_GPU=0 -DSK_SUPPORT_OPENCL=0 -DSK_FORCE_DISTANCEFIELD_FONTS=0 -DSK_SCALAR_IS_FLOAT -DSK_CAN_USE_FLOAT -DSK_SAMPLES_FOR_X -DSK_BUILD_FOR_UNIX -DSK_USE_POSIX_THREADS -DSK_SYSTEM_ZLIB=1 -DSK_DEBUG -DSK_DEVELOPER=1 -I../../src/core -I../../src/images -I../../tools/flags -I../../include/config -I../../include/core -I../../include/pathops -I../../include/pipe -I../../include/effects -I../../include/ports -I../../src/sfnt -I../../include/utils -I../../src/utils -I../../include/images -g -fno-exceptions -fstrict-aliasing -Wall -Wextra -Winit-self -Wpointer-arith -Wno-unused-parameter -m64 -fno-rtti -Wnon-virtual-dtor -c ../../../cache/%s.cpp -o ../../../cache/%s.o`
-	LINK           = `../../experimental/webtry/safec++ -m64 -lstdc++ -lm -o ../../../inout/%s -Wl,--start-group ../../../cache/%s.o obj/experimental/webtry/webtry.main.o obj/gyp/libflags.a libskia_images.a libskia_core.a libskia_effects.a obj/gyp/libjpeg.a obj/gyp/libetc1.a obj/gyp/libSkKTX.a obj/gyp/libwebp_dec.a obj/gyp/libwebp_demux.a obj/gyp/libwebp_dsp.a obj/gyp/libwebp_enc.a obj/gyp/libwebp_utils.a libskia_utils.a libskia_opts.a libskia_opts_ssse3.a libskia_ports.a libskia_sfnt.a -Wl,--end-group -lpng -lz -lgif -lpthread -lfontconfig -ldl -lfreetype`
+	RUN_GYP   = `../../experimental/webtry/gyp_for_webtry %s -Dskia_gpu=0`
+	RUN_NINJA = `ninja -C ../../../inout/Release %s`
 
 	DEFAULT_SAMPLE = `void draw(SkCanvas* canvas) {
     SkPaint p;
@@ -56,6 +56,9 @@
 	// codeTemplate is the cpp code template the user's code is copied into.
 	codeTemplate *template.Template = nil
 
+	// gypTemplate is the GYP file to build the executable containing the user's code.
+	gypTemplate *template.Template = nil
+
 	// indexTemplate is the main index.html page we serve.
 	indexTemplate *htemplate.Template = nil
 
@@ -150,6 +153,10 @@
 	if err != nil {
 		panic(err)
 	}
+	gypTemplate, err = template.ParseFiles(filepath.Join(cwd, "templates/template.gyp"))
+	if err != nil {
+		panic(err)
+	}
 	indexTemplate, err = htemplate.ParseFiles(
 		filepath.Join(cwd, "templates/index.html"),
 		filepath.Join(cwd, "templates/titlebar.html"),
@@ -337,14 +344,20 @@
 	Titlebar Titlebar
 }
 
-// expandToFile expands the template and writes the result to the file.
-func expandToFile(filename string, code string, t *template.Template) error {
+// writeTemplate creates a given output file and writes the template
+// result there.
+func writeTemplate(filename string, t *template.Template, context interface{}) error {
 	f, err := os.Create(filename)
 	if err != nil {
 		return err
 	}
 	defer f.Close()
-	return t.Execute(f, userCode{Code: code, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}})
+	return t.Execute(f, context)
+}
+
+// expandToFile expands the template and writes the result to the file.
+func expandToFile(filename string, code string, t *template.Template) error {
+	return writeTemplate(filename, t, userCode{Code: code, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}})
 }
 
 // expandCode expands the template into a file and calculates the MD5 hash.
@@ -356,10 +369,15 @@
 	// At this point we are running in skia/experimental/webtry, making cache a
 	// peer directory to skia.
 	// TODO(jcgregorio) Make all relative directories into flags.
-	err := expandToFile(fmt.Sprintf("../../../cache/%s.cpp", hash), code, codeTemplate)
+	err := expandToFile(fmt.Sprintf("../../../cache/src/%s.cpp", hash), code, codeTemplate)
 	return hash, err
 }
 
+// expandGyp produces the GYP file needed to build the code
+func expandGyp(hash string) error {
+	return writeTemplate(fmt.Sprintf("../../../cache/%s.gyp", hash), gypTemplate, struct{ Hash string }{hash})
+}
+
 // response is serialized to JSON as a response to POSTs.
 type response struct {
 	Message string `json:"message"`
@@ -738,7 +756,7 @@
 }
 
 func cleanCompileOutput(s, hash string) string {
-	old := "../../../cache/" + hash + ".cpp:"
+	old := "../../../cache/src/" + hash + ".cpp:"
 	log.Printf("INFO: replacing %q\n", old)
 	return strings.Replace(s, old, "usercode.cpp:", -1)
 }
@@ -798,13 +816,18 @@
 			return
 		}
 		writeToDatabase(hash, request.Code, request.Name, request.Source)
-		message, err := doCmd(fmt.Sprintf(RESULT_COMPILE, hash, hash), true)
+		err = expandGyp(hash)
+		if err != nil {
+			reportTryError(w, r, err, "Failed to write the gyp file.", hash)
+			return
+		}
+		message, err := doCmd(fmt.Sprintf(RUN_GYP, hash), true)
 		if err != nil {
 			message = cleanCompileOutput(message, hash)
 			reportTryError(w, r, err, message, hash)
 			return
 		}
-		linkMessage, err := doCmd(fmt.Sprintf(LINK, hash, hash), true)
+		linkMessage, err := doCmd(fmt.Sprintf(RUN_NINJA, hash), true)
 		if err != nil {
 			linkMessage = cleanCompileOutput(linkMessage, hash)
 			reportTryError(w, r, err, linkMessage, hash)
@@ -816,9 +839,9 @@
 			cmd += fmt.Sprintf("  --source image-%d.png", request.Source)
 		}
 		if *useChroot {
-			cmd = "schroot -c webtry --directory=/inout -- /inout/" + cmd
+			cmd = "schroot -c webtry --directory=/inout -- /inout/Release/" + cmd
 		} else {
-			abs, err := filepath.Abs("../../../inout")
+			abs, err := filepath.Abs("../../../inout/Release")
 			if err != nil {
 				reportTryError(w, r, err, "Failed to find executable directory.", hash)
 				return
diff --git a/gm/androidfallback.cpp b/gm/androidfallback.cpp
deleted file mode 100644
index e0f36aa..0000000
--- a/gm/androidfallback.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 "gm.h"
-
-namespace skiagm {
-
-class AndroidFallbackGM : public GM {
-public:
-    AndroidFallbackGM() {
-        this->setBGColor(0xFFCCCCCC);
-    }
-
-protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        // TODO(scroggo): Undo this if we decide to fix skia:1763.
-        return GM::kSkipPipe_Flag;
-    }
-
-    virtual SkString onShortName() SK_OVERRIDE {
-        return SkString("android_paint");
-    }
-
-    virtual SkISize onISize() SK_OVERRIDE {
-        return SkISize::Make(500, 500);
-    }
-
-    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
-
-        SkPaint paint;
-        paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
-        paint.setTextSize(24);
-
-        SkPaintOptionsAndroid options = paint.getPaintOptionsAndroid();
-        options.setUseFontFallbacks(true);
-        paint.setPaintOptionsAndroid(options);
-
-        // "א foo 免舌 bar क"
-        const uint16_t unicodeStr[] = {0x05D0, 0x0020, 0x0066, 0x006F, 0x006F, 0x0020, 0x514D,
-                                       0x820c, 0x0020, 0x0062, 0x0061, 0x0072, 0x0020, 0x0915};
-        const int strLength = sizeof(unicodeStr) / sizeof(uint16_t);
-        const int strByteLength = sizeof(unicodeStr);
-
-        SkScalar posX[strLength];
-        SkPoint posXY[strLength];
-
-        for (int i = 0; i < strLength; ++i) {
-            posX[i] = SkIntToScalar(i * 24);
-            posXY[i].fX = posX[i];
-            posXY[i].fY = SkIntToScalar(24 + i);
-        }
-
-        canvas->translate(SkIntToScalar(10), SkIntToScalar(25));
-        // This currently causes the PDF backend to assert
-        // canvas->drawText(unicodeStr, strByteLength, 0, 0, paint);
-
-        canvas->translate(0, SkIntToScalar(75));
-        canvas->drawPosTextH(unicodeStr, strByteLength, posX, 0, paint);
-
-        options.setLanguage("ja");
-        paint.setPaintOptionsAndroid(options);
-
-        canvas->translate(0, SkIntToScalar(75));
-        canvas->drawPosText(unicodeStr, strByteLength, posXY, paint);
-
-        SkPath path;
-        path.moveTo(0, 0);
-        path.quadTo(50.0f, 100.0f, 250.0f, 150.0f);
-
-        canvas->translate(0, SkIntToScalar(75));
-        canvas->drawTextOnPath(unicodeStr, strByteLength, path, NULL, paint);
-    }
-
-private:
-    typedef GM INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_GM( return SkNEW(AndroidFallbackGM); )
-
-}
diff --git a/gm/arithmode.cpp b/gm/arithmode.cpp
index d85e43d..14f6aa0 100644
--- a/gm/arithmode.cpp
+++ b/gm/arithmode.cpp
@@ -57,6 +57,7 @@
     SkPaint paint;
     paint.setTextSize(SkIntToScalar(24));
     paint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&paint);
     for (int i = 0; i < 4; ++i) {
         SkString str;
         str.appendScalar(k[i]);
diff --git a/gm/astcbitmap.cpp b/gm/astcbitmap.cpp
new file mode 100644
index 0000000..3c9079c
--- /dev/null
+++ b/gm/astcbitmap.cpp
@@ -0,0 +1,104 @@
+/*
+ * 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 "gm.h"
+
+#include "Resources.h"
+#include "SkCanvas.h"
+#include "SkData.h"
+#include "SkDecodingImageGenerator.h"
+#include "SkImageDecoder.h"
+#include "SkOSFile.h"
+#include "SkTextureCompressor.h"
+
+static const char *kASTCFilenames[] = {
+    "mandrill_128x128_4x4.astc",    // kASTC_4x4_Format
+    "mandrill_130x128_5x4.astc",    // kASTC_5x4_Format
+    "mandrill_130x130_5x5.astc",    // kASTC_5x5_Format
+    "mandrill_132x130_6x5.astc",    // kASTC_6x5_Format
+    "mandrill_132x132_6x6.astc",    // kASTC_6x6_Format
+    "mandrill_128x130_8x5.astc",    // kASTC_8x5_Format
+    "mandrill_128x132_8x6.astc",    // kASTC_8x6_Format
+    "mandrill_128x128_8x8.astc",    // kASTC_8x8_Format
+    "mandrill_130x130_10x5.astc",   // kASTC_10x5_Format
+    "mandrill_130x132_10x6.astc",   // kASTC_10x6_Format
+    "mandrill_130x128_10x8.astc",   // kASTC_10x8_Format
+    "mandrill_130x130_10x10.astc",  // kASTC_10x10_Format
+    "mandrill_132x130_12x10.astc",  // kASTC_12x10_Format
+    "mandrill_132x132_12x12.astc",  // kASTC_12x12_Format
+};
+
+static const int kNumASTCFilenames = SK_ARRAY_COUNT(kASTCFilenames);
+
+static inline const char *get_astc_filename(int idx) {
+    if (idx < 0 || kNumASTCFilenames <= idx) {
+        return "";
+    }
+
+    return kASTCFilenames[idx];
+}
+
+namespace skiagm {
+
+/**
+ *  Test decoding an image from an ASTC file and then from compressed ASTC data.
+ */
+class ASTCBitmapGM : public GM {
+public:
+    ASTCBitmapGM() { }
+    virtual ~ASTCBitmapGM() { }
+
+protected:
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("astcbitmap");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(kGMDimension, kGMDimension);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        for (int j = 0; j < 4; ++j) {
+            for (int i = 0; i < 4; ++i) {
+                SkString filename = GetResourcePath(get_astc_filename(j*4+i));
+                if (filename == GetResourcePath("")) {
+                    continue;
+                }
+
+                SkAutoTUnref<SkData> fileData(SkData::NewFromFileName(filename.c_str()));
+                if (NULL == fileData) {
+                    SkDebugf("Could not open the file. Did you forget to set the resourcePath?\n");
+                    return;
+                }
+
+                SkBitmap bm;
+                if (!SkInstallDiscardablePixelRef(
+                        SkDecodingImageGenerator::Create(
+                            fileData, SkDecodingImageGenerator::Options()), &bm)) {
+                    SkDebugf("Could not install discardable pixel ref.\n");
+                    return;
+                }
+
+                const SkScalar bmX = static_cast<SkScalar>(i*kBitmapDimension);
+                const SkScalar bmY = static_cast<SkScalar>(j*kBitmapDimension);
+                canvas->drawBitmap(bm, bmX, bmY);
+            }
+        }
+    }
+
+private:
+    static const int kGMDimension = 600;
+    static const int kBitmapDimension = kGMDimension/4;
+
+    typedef GM INHERITED;
+};
+
+}  // namespace skiagm
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM( return SkNEW(skiagm::ASTCBitmapGM); )
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 9252a58..ec7e83e 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -26,7 +26,7 @@
 namespace {
 extern const GrVertexAttrib kAttribs[] = {
     {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
-    {kVec4f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}
+    {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
 };
 }
 
@@ -92,17 +92,17 @@
                 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
                 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
             };
-            for(int edgeType = 0; edgeType < kGrEffectEdgeTypeCnt; ++edgeType) {
-                SkAutoTUnref<GrEffectRef> effect;
+            for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
+                SkAutoTUnref<GrGeometryProcessor> gp;
                 {   // scope to contain GrTestTarget
                     GrTestTarget tt;
                     context->getTestTarget(&tt);
                     if (NULL == tt.target()) {
                         continue;
                     }
-                    GrEffectEdgeType et = (GrEffectEdgeType)edgeType;
-                    effect.reset(GrCubicEffect::Create(et, *tt.target()->caps()));
-                    if (!effect) {
+                    GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
+                    gp.reset(GrCubicEffect::Create(et, *tt.target()->caps()));
+                    if (!gp) {
                         continue;
                     }
                 }
@@ -166,11 +166,11 @@
 
                     GrTestTarget tt;
                     context->getTestTarget(&tt);
-                    SkASSERT(NULL != tt.target());
+                    SkASSERT(tt.target());
                     GrDrawState* drawState = tt.target()->drawState();
-                    drawState->setVertexAttribs<kAttribs>(2);
+                    drawState->setVertexAttribs<kAttribs>(2, sizeof(Vertex));
 
-                    drawState->addCoverageEffect(effect, 1);
+                    drawState->setGeometryProcessor(gp);
                     drawState->setRenderTarget(rt);
                     drawState->setColor(0xff000000);
 
@@ -250,17 +250,17 @@
                 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
             };
             SkScalar weight = rand.nextRangeF(0.f, 2.f);
-            for(int edgeType = 0; edgeType < kGrEffectEdgeTypeCnt; ++edgeType) {
-                SkAutoTUnref<GrEffectRef> effect;
+            for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
+                SkAutoTUnref<GrGeometryProcessor> gp;
                 {   // scope to contain GrTestTarget
                     GrTestTarget tt;
                     context->getTestTarget(&tt);
                     if (NULL == tt.target()) {
                         continue;
                     }
-                    GrEffectEdgeType et = (GrEffectEdgeType)edgeType;
-                    effect.reset(GrConicEffect::Create(et, *tt.target()->caps()));
-                    if (!effect) {
+                    GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
+                    gp.reset(GrConicEffect::Create(et, *tt.target()->caps()));
+                    if (!gp) {
                         continue;
                     }
                 }
@@ -321,11 +321,11 @@
 
                     GrTestTarget tt;
                     context->getTestTarget(&tt);
-                    SkASSERT(NULL != tt.target());
+                    SkASSERT(tt.target());
                     GrDrawState* drawState = tt.target()->drawState();
-                    drawState->setVertexAttribs<kAttribs>(2);
+                    drawState->setVertexAttribs<kAttribs>(2, sizeof(Vertex));
 
-                    drawState->addCoverageEffect(effect, 1);
+                    drawState->setGeometryProcessor(gp);
                     drawState->setRenderTarget(rt);
                     drawState->setColor(0xff000000);
 
@@ -439,17 +439,17 @@
                 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
                 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
             };
-            for(int edgeType = 0; edgeType < kGrEffectEdgeTypeCnt; ++edgeType) {
-                SkAutoTUnref<GrEffectRef> effect;
+            for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
+                SkAutoTUnref<GrGeometryProcessor> gp;
                 {   // scope to contain GrTestTarget
                     GrTestTarget tt;
                     context->getTestTarget(&tt);
                     if (NULL == tt.target()) {
                         continue;
                     }
-                    GrEffectEdgeType et = (GrEffectEdgeType)edgeType;
-                    effect.reset(GrQuadEffect::Create(et, *tt.target()->caps()));
-                    if (!effect) {
+                    GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
+                    gp.reset(GrQuadEffect::Create(et, *tt.target()->caps()));
+                    if (!gp) {
                         continue;
                     }
                 }
@@ -505,11 +505,11 @@
 
                     GrTestTarget tt;
                     context->getTestTarget(&tt);
-                    SkASSERT(NULL != tt.target());
+                    SkASSERT(tt.target());
                     GrDrawState* drawState = tt.target()->drawState();
-                    drawState->setVertexAttribs<kAttribs>(2);
+                    drawState->setVertexAttribs<kAttribs>(2, sizeof(Vertex));
 
-                    drawState->addCoverageEffect(effect, 1);
+                    drawState->setGeometryProcessor(gp);
                     drawState->setRenderTarget(rt);
                     drawState->setColor(0xff000000);
 
diff --git a/gm/bicubicfilter.cpp b/gm/bicubicfilter.cpp
deleted file mode 100644
index 0f33b6f..0000000
--- a/gm/bicubicfilter.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 "gm.h"
-#include "SkColor.h"
-#include "SkBicubicImageFilter.h"
-
-namespace skiagm {
-
-class BicubicGM : public GM {
-public:
-    BicubicGM() : fInitialized(false) {
-        this->setBGColor(0x00000000);
-    }
-
-protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
-    virtual SkString onShortName() {
-        return SkString("bicubicfilter");
-    }
-
-    void make_checkerboard(int width, int height) {
-        SkASSERT(width % 2 == 0);
-        SkASSERT(height % 2 == 0);
-        fCheckerboard.allocN32Pixels(width, height);
-        for (int y = 0; y < height; y += 2) {
-            SkPMColor* s = fCheckerboard.getAddr32(0, y);
-            for (int x = 0; x < width; x += 2) {
-                *s++ = 0xFFFFFFFF;
-                *s++ = 0xFF000000;
-            }
-            s = fCheckerboard.getAddr32(0, y + 1);
-            for (int x = 0; x < width; x += 2) {
-                *s++ = 0xFF000000;
-                *s++ = 0xFFFFFFFF;
-            }
-        }
-    }
-
-    virtual SkISize onISize() {
-        return SkISize::Make(400, 300);
-    }
-
-    virtual void onDraw(SkCanvas* canvas) {
-        if (!fInitialized) {
-            make_checkerboard(4, 4);
-            fInitialized = true;
-        }
-        SkScalar sk32 = SkIntToScalar(32);
-        canvas->clear(0x00000000);
-        SkPaint bilinearPaint, bicubicPaint;
-        SkSize scale = SkSize::Make(sk32, sk32);
-        canvas->save();
-        canvas->scale(sk32, sk32);
-        bilinearPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
-        canvas->drawBitmap(fCheckerboard, 0, 0, &bilinearPaint);
-        canvas->restore();
-        SkAutoTUnref<SkImageFilter> bicubic(SkBicubicImageFilter::CreateMitchell(scale));
-        bicubicPaint.setImageFilter(bicubic);
-        SkRect srcBounds;
-        fCheckerboard.getBounds(&srcBounds);
-        canvas->translate(SkIntToScalar(140), 0);
-        canvas->saveLayer(&srcBounds, &bicubicPaint);
-        canvas->drawBitmap(fCheckerboard, 0, 0);
-        canvas->restore();
-    }
-
-private:
-    typedef GM INHERITED;
-    SkBitmap fCheckerboard;
-    bool fInitialized;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-static GM* MyFactory(void*) { return new BicubicGM; }
-static GMRegistry reg(MyFactory);
-
-}
diff --git a/gm/bigmatrix.cpp b/gm/bigmatrix.cpp
index 3ad128e..df542fd 100644
--- a/gm/bigmatrix.cpp
+++ b/gm/bigmatrix.cpp
@@ -19,10 +19,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() {
         return SkString("bigmatrix");
     }
diff --git a/gm/bigtext.cpp b/gm/bigtext.cpp
index 9c2682c..eabad14 100644
--- a/gm/bigtext.cpp
+++ b/gm/bigtext.cpp
@@ -34,6 +34,7 @@
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setTextSize(1500);
 
         SkRect r;
diff --git a/gm/bitmapcopy.cpp b/gm/bitmapcopy.cpp
index eaad8d0..74505d9 100644
--- a/gm/bitmapcopy.cpp
+++ b/gm/bitmapcopy.cpp
@@ -77,6 +77,8 @@
 
         canvas->clear(0xFFDDDDDD);
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
+        
         SkScalar width = SkIntToScalar(40);
         SkScalar height = SkIntToScalar(40);
         if (paint.getFontSpacing() > height) {
diff --git a/gm/bitmapfilters.cpp b/gm/bitmapfilters.cpp
index eaaa11a..f1348b1 100644
--- a/gm/bitmapfilters.cpp
+++ b/gm/bitmapfilters.cpp
@@ -55,6 +55,7 @@
     const int scale = 32;
 
     paint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&paint);
     const char* name = sk_tool_utils::colortype_name(bm.colorType());
     canvas->drawText(name, strlen(name), x, SkIntToScalar(bm.height())*scale*5/8,
                      paint);
diff --git a/gm/bitmaprect.cpp b/gm/bitmaprect.cpp
index 8b29283..badffb9 100644
--- a/gm/bitmaprect.cpp
+++ b/gm/bitmaprect.cpp
@@ -45,6 +45,13 @@
         return SkISize::Make(640, 480);
     }
 
+#ifdef SK_CPU_ARM64
+    // Skip tiled drawing on 64-bit ARM until https://skbug.com/2908 is fixed.
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+#endif
+
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
         canvas->drawColor(0xFFCCCCCC);
 
diff --git a/gm/bitmaprecttest.cpp b/gm/bitmaprecttest.cpp
index 06495b9..6f0ab58 100644
--- a/gm/bitmaprecttest.cpp
+++ b/gm/bitmaprecttest.cpp
@@ -56,10 +56,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() {
         return SkString("bitmaprecttest");
     }
diff --git a/gm/bitmapscroll.cpp b/gm/bitmapscroll.cpp
index 7e23d8b..d38cbbe 100644
--- a/gm/bitmapscroll.cpp
+++ b/gm/bitmapscroll.cpp
@@ -59,14 +59,14 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() {
         return SkString("bitmapscroll");
     }
 
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+
     virtual SkISize onISize() {
       return SkISize::Make(800, 600);
     }
@@ -109,6 +109,7 @@
     void drawLabel(SkCanvas* canvas, const char *text, int startX, int startY,
                  int endX, int endY) {
         SkPaint paint;
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xFF000000);
         SkPath path;
         path.moveTo(SkIntToScalar(startX), SkIntToScalar(startY));
diff --git a/gm/bitmapshader.cpp b/gm/bitmapshader.cpp
index 5cf5e14..8085f5c 100644
--- a/gm/bitmapshader.cpp
+++ b/gm/bitmapshader.cpp
@@ -50,10 +50,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() {
         return SkString("bitmapshaders");
     }
diff --git a/gm/bitmapsource.cpp b/gm/bitmapsource.cpp
index 9cf5a75..f6badde 100644
--- a/gm/bitmapsource.cpp
+++ b/gm/bitmapsource.cpp
@@ -27,6 +27,7 @@
         canvas.clear(0x00000000);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xFFFFFFFF);
         paint.setTextSize(SkIntToScalar(96));
         const char* str = "e";
diff --git a/gm/bleed.cpp b/gm/bleed.cpp
index 99dba70..aa2b0df 100644
--- a/gm/bleed.cpp
+++ b/gm/bleed.cpp
@@ -212,7 +212,7 @@
 #if SK_SUPPORT_GPU
             GrContext* ctx = canvas->getGrContext();
             int oldMaxTextureSize = 0;
-            if (NULL != ctx) {
+            if (ctx) {
                 // shrink the max texture size so all our textures can be reasonably sized
                 oldMaxTextureSize = ctx->getMaxTextureSize();
                 ctx->setMaxTextureSizeOverride(kMaxTextureSize);
@@ -244,7 +244,7 @@
             this->drawCase4(canvas, kCol6X, kRow3Y, SkCanvas::kBleed_DrawBitmapRectFlag, SkPaint::kHigh_FilterLevel);
 
 #if SK_SUPPORT_GPU
-            if (NULL != ctx) {
+            if (ctx) {
                 ctx->setMaxTextureSizeOverride(oldMaxTextureSize);
             }
 #endif
diff --git a/gm/blurrect.cpp b/gm/blurrect.cpp
index 0ea6f87..768e798 100644
--- a/gm/blurrect.cpp
+++ b/gm/blurrect.cpp
@@ -115,7 +115,7 @@
         }
     }
 
-    virtual uint32_t onGetFlags() const { return kSkipPipe_Flag | kSkipTiled_Flag; }
+    virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; }
 
 private:
     void drawProcs(SkCanvas* canvas, const SkRect& r, const SkPaint& paint,
diff --git a/gm/blurroundrect.cpp b/gm/blurroundrect.cpp
index 3e6f1bd..d78335f 100644
--- a/gm/blurroundrect.cpp
+++ b/gm/blurroundrect.cpp
@@ -42,10 +42,6 @@
         fRRect.setRectRadii(r, radii);
     }
 
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() SK_OVERRIDE {
         return fName;
     }
@@ -104,10 +100,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() SK_OVERRIDE {
         return fName;
     }
diff --git a/gm/blurs.cpp b/gm/blurs.cpp
index 8a8949a..ad363e4 100644
--- a/gm/blurs.cpp
+++ b/gm/blurs.cpp
@@ -45,6 +45,7 @@
 
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setTextSize(SkIntToScalar(25));
         canvas->translate(SkIntToScalar(-40), SkIntToScalar(0));
 
diff --git a/gm/canvasstate.cpp b/gm/canvasstate.cpp
deleted file mode 100644
index b61ee72..0000000
--- a/gm/canvasstate.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * 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 "gm.h"
-#include "SkCanvas.h"
-#include "SkPaint.h"
-#include "SkPath.h"
-#include "SkRect.h"
-
-namespace skiagm {
-
-/*
- * This GM exercises the flags to SkCanvas::save(). The canvas' save() and
- * restore actions can be limited to only a portion of the canvas' state through
- * the use of flags when calling save.
- */
-class CanvasStateGM : public GM {
-    SkSize  fSize;
-    enum {
-        WIDTH = 150,
-        HEIGHT = 150,
-    };
-
-    SkPaint fFillPaint;
-    SkPaint fStrokePaint;
-
-    SkPath fPath;
-
-    SkRect fOutlineRect;
-    SkRect fFillRect;
-
-
-public:
-    CanvasStateGM() {
-        fSize.set(SkIntToScalar(WIDTH), SkIntToScalar(HEIGHT));
-
-        fFillPaint.setColor(SK_ColorRED);
-        fFillPaint.setStyle(SkPaint::kFill_Style);
-
-        fStrokePaint.setColor(SK_ColorBLUE);
-        fStrokePaint.setStyle(SkPaint::kStroke_Style);
-        fStrokePaint.setStrokeWidth(1);
-
-        fPath.moveTo(25, 25);
-        fPath.lineTo(125, 25);
-        fPath.lineTo(75, 125);
-        fPath.close();
-
-        fOutlineRect = SkRect::MakeXYWH(1, 1, WIDTH-2, HEIGHT-2);
-        fFillRect = SkRect::MakeXYWH(10, 10, WIDTH-20, HEIGHT-20);
-    }
-
-protected:
-    virtual SkString onShortName() SK_OVERRIDE {
-        return SkString("canvas-state");
-    }
-
-    virtual SkISize onISize() SK_OVERRIDE {
-        return SkISize::Make(WIDTH*3, HEIGHT*4);
-    }
-
-    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
-
-        SkCanvas::SaveFlags flags[] = { SkCanvas::kMatrix_SaveFlag,
-                                        SkCanvas::kClip_SaveFlag,
-                                        SkCanvas::kMatrixClip_SaveFlag };
-
-        // columns -- flags
-        // rows -- permutations of setting the clip and matrix
-        for (int i = 0; i < static_cast<int>(SK_ARRAY_COUNT(flags)); ++i) {
-            for (int j = 0; j < 2; ++j) {
-                for (int k = 0; k < 2; ++k) {
-                    this->drawTestPattern(i, (2*j)+k, canvas, flags[i],
-                                          SkToBool(j), SkToBool(k));
-                }
-            }
-        }
-    }
-
-
-    virtual uint32_t onGetFlags() const SK_OVERRIDE { return kSkipPicture_Flag; }
-
-private:
-    void drawTestPattern(int x, int y, SkCanvas* canvas,
-                         SkCanvas::SaveFlags flags, bool doClip, bool doScale) {
-        canvas->save();
-        canvas->translate(SkIntToScalar(x*WIDTH), SkIntToScalar(y*HEIGHT));
-
-        canvas->drawRect(fOutlineRect, fStrokePaint);
-        canvas->save(flags);
-        if(doClip) {
-            canvas->clipPath(fPath);
-        }
-        if (doScale) {
-            canvas->scale(SkDoubleToScalar(0.5), SkDoubleToScalar(0.5));
-        }
-        canvas->restore();
-        canvas->drawRect(fFillRect, fFillPaint);
-
-        canvas->restore();
-    }
-
-    typedef GM INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-class CanvasLayerStateGM : public GM {
-public:
-    CanvasLayerStateGM() {
-        fBluePaint.setColor(SK_ColorBLUE);
-        fBluePaint.setStyle(SkPaint::kFill_Style);
-
-        fRect = SkRect::MakeXYWH(SPACER, SPACER, WIDTH-(2*SPACER), (HEIGHT-(2*SPACER)) / 7);
-    }
-
-protected:
-    virtual SkString onShortName() SK_OVERRIDE {
-        return SkString("canvas-layer-state");
-    }
-
-    virtual SkISize onISize() SK_OVERRIDE {
-        return SkISize::Make(WIDTH, HEIGHT);
-    }
-
-    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
-
-        // clear the canvas to red
-        canvas->drawColor(SK_ColorRED);
-
-#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
-        // both rects should appear
-        drawTestPattern(canvas, 255, SkCanvas::kARGB_NoClipLayer_SaveFlag);
-
-        canvas->translate(0, 2*(fRect.height() + 10));
-
-        // only the top rect should appear
-        drawTestPattern(canvas, 255, SkCanvas::kARGB_ClipLayer_SaveFlag);
-
-        canvas->translate(0, 2*(fRect.height() + 10));
-
-        // only the bottom rect should appear
-        drawTestPattern(canvas, 0, SkCanvas::kARGB_NoClipLayer_SaveFlag);
-#endif
-    }
-
-    virtual uint32_t onGetFlags() const SK_OVERRIDE { return kSkipGPU_Flag; }
-
-private:
-    // draw a rect within the layer's bounds and again outside the layer's bounds
-    void drawTestPattern(SkCanvas* canvas, U8CPU layerAlpha, SkCanvas::SaveFlags flags) {
-        canvas->saveLayerAlpha(&fRect, layerAlpha, flags);
-        canvas->drawRect(fRect, fBluePaint);
-        canvas->translate(0, fRect.height() + 10);
-        canvas->drawRect(fRect, fBluePaint);
-        canvas->restore();
-    }
-
-    enum {
-        WIDTH = 400,
-        HEIGHT = 400,
-        SPACER = 10,
-    };
-
-    SkPaint fBluePaint;
-    SkRect fRect;
-
-    typedef GM INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_GM( return SkNEW(CanvasStateGM); )
-DEF_GM( return SkNEW(CanvasLayerStateGM); )
-
-} // end namespace
diff --git a/gm/circularclips.cpp b/gm/circularclips.cpp
index 07b59f0..4730182 100644
--- a/gm/circularclips.cpp
+++ b/gm/circularclips.cpp
@@ -9,15 +9,24 @@
 #include "SkCanvas.h"
 #include "SkPath.h"
 
-namespace skiagm {
+class CircularClipsGM : public skiagm::GM {
+    SkScalar fX1, fX2, fY, fR;
+    SkPath   fCircle1, fCircle2;
 
-class CircularClipsGM : public GM {
 public:
-    CircularClipsGM() {}
+    CircularClipsGM() {
+        fX1 = 80;
+        fX2 = 120;
+        fY = 50;
+        fR = 40;
+
+        fCircle1.addCircle(fX1, fY, fR, SkPath::kCW_Direction);
+        fCircle2.addCircle(fX2, fY, fR, SkPath::kCW_Direction);
+    }
 
 protected:
     virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
+        return kSkipTiled_Flag | kAsBench_Flag;
     }
 
     virtual SkString onShortName() {
@@ -38,45 +47,37 @@
             SkRegion::kReplace_Op,
         };
 
-        SkScalar x1 = 80, x2 = 120;
-        SkScalar y = 50;
-        SkScalar r = 40;
-
-        SkPath circle1, circle2;
-        circle1.addCircle(x1, y, r, SkPath::kCW_Direction);
-        circle2.addCircle(x2, y, r, SkPath::kCW_Direction);
-        SkRect rect = SkRect::MakeLTRB(x1 - r, y - r, x2 + r, y + r);
+        SkRect rect = SkRect::MakeLTRB(fX1 - fR, fY - fR, fX2 + fR, fY + fR);
 
         SkPaint fillPaint;
 
         for (size_t i = 0; i < 4; i++) {
-            circle1.toggleInverseFillType();
+            fCircle1.toggleInverseFillType();
             if (i % 2 == 0) {
-                circle2.toggleInverseFillType();
+                fCircle2.toggleInverseFillType();
             }
 
             canvas->save();
             for (size_t op = 0; op < SK_ARRAY_COUNT(ops); op++) {
                 canvas->save();
 
-                canvas->clipPath(circle1, SkRegion::kReplace_Op);
-                canvas->clipPath(circle2, ops[op]);
+                canvas->clipPath(fCircle1, SkRegion::kReplace_Op);
+                canvas->clipPath(fCircle2, ops[op]);
 
                 canvas->drawRect(rect, fillPaint);
 
                 canvas->restore();
-                canvas->translate(0, 2 * y);
+                canvas->translate(0, 2 * fY);
             }
             canvas->restore();
-            canvas->translate(x1 + x2, 0);
+            canvas->translate(fX1 + fX2, 0);
         }
     }
 
 private:
-    typedef GM INHERITED;
+    typedef skiagm::GM INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
 DEF_GM( return new CircularClipsGM; )
-}
diff --git a/gm/clip_strokerect.cpp b/gm/clip_strokerect.cpp
new file mode 100644
index 0000000..7072292
--- /dev/null
+++ b/gm/clip_strokerect.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkCanvas.h"
+#include "SkPath.h"
+
+class ClipStrokeRectGM : public skiagm::GM {
+public:
+    ClipStrokeRectGM() {
+
+    }
+
+protected:
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("clip_strokerect");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(200, 400);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        SkPaint p;
+        p.setColor(SK_ColorRED);
+        p.setAntiAlias(true);
+        p.setStyle(SkPaint::kStroke_Style);
+        p.setStrokeWidth(22);
+
+        SkRect r = SkRect::MakeXYWH(20, 20, 100, 100);
+        // setting the height of this to 19 causes failure
+        SkRect rect = SkRect::MakeXYWH(20, 0, 100, 20);
+
+        canvas->save();
+        canvas->clipRect(rect, SkRegion::kReplace_Op, true);
+        canvas->drawRect(r, p);
+        canvas->restore();
+
+        p.setColor(SK_ColorBLUE);
+        p.setStrokeWidth(2);
+        canvas->drawRect(rect, p);
+
+        p.setColor(SK_ColorRED);
+        p.setAntiAlias(true);
+        p.setStyle(SkPaint::kStroke_Style);
+        p.setStrokeWidth(22);
+
+        SkRect r2 = SkRect::MakeXYWH(20, 140, 100, 100);
+        // setting the height of this to 19 causes failure
+        SkRect rect2 = SkRect::MakeXYWH(20, 120, 100, 19);
+
+        canvas->save();
+        canvas->clipRect(rect2, SkRegion::kReplace_Op, true);
+        canvas->drawRect(r2, p);
+        canvas->restore();
+
+        p.setColor(SK_ColorBLUE);
+        p.setStrokeWidth(2);
+        canvas->drawRect(rect2, p);
+    }
+
+    virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; }
+
+private:
+    typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return SkNEW(ClipStrokeRectGM); )
+
diff --git a/gm/cmykjpeg.cpp b/gm/cmykjpeg.cpp
index a1a12dc..5371fe2 100644
--- a/gm/cmykjpeg.cpp
+++ b/gm/cmykjpeg.cpp
@@ -26,14 +26,8 @@
         // parameters to the "decode" call
         bool dither = false;
 
-        SkString resourcePath = GetResourcePath();
-        if (!resourcePath.endsWith("/") && !resourcePath.endsWith("\\")) {
-            resourcePath.append("/");
-        }
-
-        resourcePath.append("CMYK.jpg");
-
-        SkFILEStream stream(resourcePath.c_str());
+        SkString jpgFilename = GetResourcePath("CMYK.jpg");
+        SkFILEStream stream(jpgFilename.c_str());
         if (!stream.isValid()) {
             SkDebugf("Could not find CMYK.jpg, please set --resourcePath correctly.\n");
             return;
diff --git a/gm/coloremoji.cpp b/gm/coloremoji.cpp
index cf45008..2eab864 100644
--- a/gm/coloremoji.cpp
+++ b/gm/coloremoji.cpp
@@ -24,14 +24,8 @@
         SkSafeUnref(fTypeface);
     }
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual void onOnceBeforeDraw() SK_OVERRIDE {
-        SkString filename = GetResourcePath();
-        filename.append("/Funkster.ttf");
-
+        SkString filename = GetResourcePath("/Funkster.ttf");
         SkAutoTUnref<SkFILEStream> stream(new SkFILEStream(filename.c_str()));
         if (!stream->isValid()) {
             SkDebugf("Could not find Funkster.ttf, please set --resourcePath correctly.\n");
diff --git a/gm/colortype.cpp b/gm/colortype.cpp
index 2774f3a..1d6dfad 100644
--- a/gm/colortype.cpp
+++ b/gm/colortype.cpp
@@ -26,8 +26,8 @@
         paint.setAntiAlias(true);
         paint.setShader(s)->unref();
 
-        SkTypeface* orig = SkTypeface::CreateFromName("Times",
-                                                      SkTypeface::kBold);
+        SkTypeface* orig = sk_tool_utils::create_portable_typeface("Times",
+                                                            SkTypeface::kBold);
         if (NULL == orig) {
             orig = SkTypeface::RefDefault();
         }
diff --git a/gm/complexclip.cpp b/gm/complexclip.cpp
index 14e77b9..61a19fd 100644
--- a/gm/complexclip.cpp
+++ b/gm/complexclip.cpp
@@ -83,6 +83,7 @@
 
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setTextSize(SkIntToScalar(20));
 
         static const struct {
diff --git a/gm/composeshader.cpp b/gm/composeshader.cpp
index e460cea..c9c8fe4 100644
--- a/gm/composeshader.cpp
+++ b/gm/composeshader.cpp
@@ -49,10 +49,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() SK_OVERRIDE {
         return SkString("composeshader");
     }
@@ -91,11 +87,6 @@
         return SkISize::Make(220, 750);
     }
 
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        // we're only off by 1 bit per-component
-        return kSkipTiled_Flag;
-    }
-
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
         SkAutoTUnref<SkShader> shader0(make_shader(SkXfermode::kDstIn_Mode));
         SkAutoTUnref<SkShader> shader1(make_shader(SkXfermode::kSrcOver_Mode));
diff --git a/gm/convexpolyclip.cpp b/gm/convexpolyclip.cpp
index 6de72dc..328cdb5 100644
--- a/gm/convexpolyclip.cpp
+++ b/gm/convexpolyclip.cpp
@@ -54,6 +54,7 @@
     }
 
     paint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&paint);
     paint.setTextSize(wScalar / 2.2f);
     paint.setShader(0);
     paint.setColor(SK_ColorLTGRAY);
@@ -149,6 +150,7 @@
         SkPaint txtPaint;
         txtPaint.setTextSize(23.f);
         txtPaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&txtPaint);
         txtPaint.setColor(SK_ColorDKGRAY);
         SkScalar textW = txtPaint.measureText(kTxt, SK_ARRAY_COUNT(kTxt)-1);
 
@@ -156,7 +158,7 @@
         int testLayers = kBench_Mode != this->getMode();
         for (int doLayer = 0; doLayer <= testLayers; ++doLayer) {
             for (SkTLList<Clip>::Iter iter(fClips, SkTLList<Clip>::Iter::kHead_IterStart);
-                 NULL != iter.get();
+                 iter.get();
                  iter.next()) {
                 const Clip* clip = iter.get();
                 SkScalar x = startX;
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 08bd887..e567208 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -22,15 +22,9 @@
 
 #include "effects/GrConvexPolyEffect.h"
 
-namespace {
-extern const GrVertexAttrib kAttribs[] = {
-    {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
-};
-}
-
 namespace skiagm {
 /**
- * This GM directly exercises a GrEffect that draws convex polygons.
+ * This GM directly exercises a GrProcessor that draws convex polygons.
  */
 class ConvexPolyEffect : public GM {
 public:
@@ -114,12 +108,12 @@
 
         SkScalar y = 0;
         for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
-             NULL != iter.get();
+             iter.get();
              iter.next()) {
             const SkPath* path = iter.get();
             SkScalar x = 0;
 
-            for (int et = 0; et < kGrEffectEdgeTypeCnt; ++et) {
+            for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
                 GrTestTarget tt;
                 context->getTestTarget(&tt);
                 if (NULL == tt.target()) {
@@ -127,19 +121,18 @@
                     return;
                 }
                 GrDrawState* drawState = tt.target()->drawState();
-                drawState->setVertexAttribs<kAttribs>(SK_ARRAY_COUNT(kAttribs));
 
                 SkMatrix m;
                 SkPath p;
                 m.setTranslate(x, y);
                 path->transform(m, &p);
 
-                GrEffectEdgeType edgeType = (GrEffectEdgeType) et;
-                SkAutoTUnref<GrEffectRef> effect(GrConvexPolyEffect::Create(edgeType, p));
-                if (!effect) {
+                GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
+                SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, p));
+                if (!fp) {
                     continue;
                 }
-                drawState->addCoverageEffect(effect, 1);
+                drawState->addCoverageProcessor(fp);
                 drawState->setIdentityViewMatrix();
                 drawState->setRenderTarget(rt);
                 drawState->setColor(0xff000000);
@@ -172,12 +165,12 @@
         }
 
         for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::Iter::kHead_IterStart);
-             NULL != iter.get();
+             iter.get();
              iter.next()) {
 
             SkScalar x = 0;
 
-            for (int et = 0; et < kGrEffectEdgeTypeCnt; ++et) {
+            for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
                 GrTestTarget tt;
                 context->getTestTarget(&tt);
                 if (NULL == tt.target()) {
@@ -186,15 +179,14 @@
                 }
                 SkRect rect = *iter.get();
                 rect.offset(x, y);
-                GrEffectEdgeType edgeType = (GrEffectEdgeType) et;
-                SkAutoTUnref<GrEffectRef> effect(GrConvexPolyEffect::Create(edgeType, rect));
-                if (!effect) {
+                GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
+                SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, rect));
+                if (!fp) {
                     continue;
                 }
 
                 GrDrawState* drawState = tt.target()->drawState();
-                drawState->setVertexAttribs<kAttribs>(SK_ARRAY_COUNT(kAttribs));
-                drawState->addCoverageEffect(effect, 1);
+                drawState->addCoverageProcessor(fp);
                 drawState->setIdentityViewMatrix();
                 drawState->setRenderTarget(rt);
                 drawState->setColor(0xff000000);
diff --git a/gm/copyTo4444.cpp b/gm/copyTo4444.cpp
index 6465d00..635cc7b 100644
--- a/gm/copyTo4444.cpp
+++ b/gm/copyTo4444.cpp
@@ -32,9 +32,8 @@
 
     virtual void onDraw(SkCanvas* canvas) {
         SkBitmap bm, bm4444;
-        SkString resourcePath = GetResourcePath();
-        SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_512.png");
-        if (!SkImageDecoder::DecodeFile(filename.c_str(), &bm, kN32_SkColorType,
+        SkString pngFilename = GetResourcePath("mandrill_512.png");
+        if (!SkImageDecoder::DecodeFile(pngFilename.c_str(), &bm, kN32_SkColorType,
                                         SkImageDecoder::kDecodePixels_Mode)) {
             SkDebugf("Could not decode the file. Did you forget to set the "
                      "resourcePath?\n");
diff --git a/gm/copy_config.py b/gm/copy_config.py
new file mode 100755
index 0000000..57743ae
--- /dev/null
+++ b/gm/copy_config.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python
+# Copyright (c) 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Utility to duplicate a config in some subset of our GM expectation files.
+
+Created for http://skbug.com/2752 ('split existing "gpu" GM results into "gl"
+and "gles"')
+
+Run with -h to see usage.
+
+Example command lines:
+  copy_config.py gl gles '.*Mac10.7.*'
+
+TODO(epoger): Once https://codereview.chromium.org/397103003/ is committed,
+we should add a unittest.  Until then, we can test this as follows:
+
+OLD=expectations/gm && NEW=/tmp/expectations && \
+  rm -rf $NEW && \
+  cp -a $OLD $NEW && \
+  gm/copy_config.py 8888 8888-copy '.*Mac10.7.*' \
+    --expectations-root $NEW && \
+  diff --recursive $OLD $NEW
+"""
+__author__ = 'Elliot Poger'
+
+import argparse
+import os
+import re
+
+import gm_json
+
+DEFAULT_EXPECTATIONS_ROOT = os.path.join(
+    os.path.dirname(__file__), os.pardir, 'expectations', 'gm')
+IMAGE_FILENAME_RE = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
+
+
+class Copier(object):
+
+  def __init__(self, args):
+    """
+    Params:
+      args: the Namespace object generated by argparse.parse_args()
+    """
+    self._args = args
+
+  def run(self):
+    """Perform all the duplications."""
+    for path in self._get_file_list():
+      self._duplicate_config(path=path,
+                             old=self._args.old_config_name,
+                             new=self._args.new_config_name)
+
+  def _duplicate_config(self, path, old, new):
+    """Duplicates all instances of a config within a GM expectations file.
+
+    Params:
+      path: path to file which will be modified in place
+      old: old config name
+      new: new config name
+    """
+    dic = gm_json.LoadFromFile(file_path=path)
+    expected_results = dic[gm_json.JSONKEY_EXPECTEDRESULTS]
+    orig_keys = expected_results.keys()
+    for key in orig_keys:
+      result = expected_results[key]
+      (testname, config) = IMAGE_FILENAME_RE.match(key).groups()
+      if config == old:
+        config = new
+        key = '%s_%s.png' % (testname, config)
+        expected_results[key] = result
+    gm_json.WriteToFile(json_dict=dic, file_path=path)
+
+  def _get_file_list(self):
+    """Returns the list of files we want to operate on (the complete path
+    to each file)."""
+    root = self._args.expectations_root
+    regex = re.compile(self._args.builder_name_pattern)
+    return [os.path.join(root, builder, 'expected-results.json')
+            for builder in os.listdir(root)
+            if regex.match(builder)]
+
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('old_config_name',
+                      help=('Config we want to duplicate.'))
+  parser.add_argument('new_config_name',
+                      help=('Name of the new config we want to create.'))
+  parser.add_argument('builder_name_pattern',
+                      help=('Regex pattern describing which builders we want '
+                            'to make the duplication for; \'.*\' to perform '
+                            'the duplication on all builders.'))
+  parser.add_argument('--expectations-root',
+                      default=DEFAULT_EXPECTATIONS_ROOT,
+                      help=('Root of the GM expectations dir; defaults to '
+                            '%(default)s'))
+  args = parser.parse_args()
+  copier = Copier(args)
+  copier.run()
+
+if __name__ == '__main__':
+  main()
diff --git a/gm/cubicpaths.cpp b/gm/cubicpaths.cpp
index 3941701..f171522 100644
--- a/gm/cubicpaths.cpp
+++ b/gm/cubicpaths.cpp
@@ -130,6 +130,7 @@
         SkPaint titlePaint;
         titlePaint.setColor(SK_ColorBLACK);
         titlePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&titlePaint);
         titlePaint.setLCDRenderText(true);
         titlePaint.setTextSize(15 * SK_Scalar1);
         const char title[] = "Cubic Drawn Into Rectangle Clips With "
@@ -174,6 +175,7 @@
                     SkPaint labelPaint;
                     labelPaint.setColor(color);
                     labelPaint.setAntiAlias(true);
+                    sk_tool_utils::set_portable_typeface(&labelPaint);
                     labelPaint.setLCDRenderText(true);
                     labelPaint.setTextSize(10 * SK_Scalar1);
                     canvas->drawText(gStyles[style].fName,
@@ -278,6 +280,7 @@
         SkPaint titlePaint;
         titlePaint.setColor(SK_ColorBLACK);
         titlePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&titlePaint);
         titlePaint.setLCDRenderText(true);
         titlePaint.setTextSize(15 * SK_Scalar1);
         const char title[] = "Cubic Closed Drawn Into Rectangle Clips With "
@@ -322,6 +325,7 @@
                     SkPaint labelPaint;
                     labelPaint.setColor(color);
                     labelPaint.setAntiAlias(true);
+                    sk_tool_utils::set_portable_typeface(&labelPaint);
                     labelPaint.setLCDRenderText(true);
                     labelPaint.setTextSize(10 * SK_Scalar1);
                     canvas->drawText(gStyles[style].fName,
diff --git a/gm/dashing.cpp b/gm/dashing.cpp
index 55addc8..7e32bfa 100644
--- a/gm/dashing.cpp
+++ b/gm/dashing.cpp
@@ -12,7 +12,8 @@
 
 static void drawline(SkCanvas* canvas, int on, int off, const SkPaint& paint,
                      SkScalar finalX = SkIntToScalar(600), SkScalar finalY = SkIntToScalar(0),
-                     SkScalar phase = SkIntToScalar(0)) {
+                     SkScalar phase = SkIntToScalar(0), 
+                     SkScalar startX = SkIntToScalar(0), SkScalar startY = SkIntToScalar(0)) {
     SkPaint p(paint);
 
     const SkScalar intervals[] = {
@@ -21,7 +22,7 @@
     };
 
     p.setPathEffect(SkDashPathEffect::Create(intervals, 2, phase))->unref();
-    canvas->drawLine(0, 0, finalX, finalY, p);
+    canvas->drawLine(startX, startY, finalX, finalY, p);
 }
 
 // earlier bug stopped us from drawing very long single-segment dashes, because
@@ -33,6 +34,16 @@
     drawline(canvas, 1, 1, paint, SkIntToScalar(20 * 1000));
 }
 
+static void show_zero_len_dash(SkCanvas* canvas) {
+    SkPaint paint;
+
+    drawline(canvas, 2, 2, paint, SkIntToScalar(0));
+    paint.setStyle(SkPaint::kStroke_Style);
+    paint.setStrokeWidth(SkIntToScalar(2));
+    canvas->translate(0, SkIntToScalar(20));
+    drawline(canvas, 4, 4, paint, SkIntToScalar(0));
+}
+
 class DashingGM : public skiagm::GM {
 public:
     DashingGM() {}
@@ -80,6 +91,8 @@
         }
 
         show_giant_dash(canvas);
+        canvas->translate(0, SkIntToScalar(20));
+        show_zero_len_dash(canvas);
     }
 };
 
@@ -396,12 +409,86 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-static skiagm::GM* F0(void*) { return new DashingGM; }
-static skiagm::GM* F1(void*) { return new Dashing2GM; }
-static skiagm::GM* F2(void*) { return new Dashing3GM; }
-static skiagm::GM* F3(void*) { return new Dashing4GM; }
+class Dashing5GM : public skiagm::GM {
+public:
+    Dashing5GM(bool doAA) : fDoAA(doAA) {}
 
-static skiagm::GMRegistry gR0(F0);
-static skiagm::GMRegistry gR1(F1);
-static skiagm::GMRegistry gR2(F2);
-static skiagm::GMRegistry gR3(F3);
+protected:
+    virtual uint32_t onGetFlags() const SK_OVERRIDE { return kAsBench_Flag | kSkipTiled_Flag; }
+
+    virtual SkString onShortName() SK_OVERRIDE { 
+        if (fDoAA) {
+            return SkString("dashing5_aa");
+        } else {
+            return SkString("dashing5_bw");
+        }
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(400, 200); }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        static const int kOn = 4;
+        static const int kOff = 4;
+        static const int kIntervalLength = kOn + kOff;
+
+        static const SkColor gColors[kIntervalLength] = {
+            SK_ColorRED,
+            SK_ColorGREEN,
+            SK_ColorBLUE,
+            SK_ColorCYAN,
+            SK_ColorMAGENTA,
+            SK_ColorYELLOW,
+            SK_ColorGRAY,
+            SK_ColorDKGRAY
+        };
+
+        SkPaint paint;
+        paint.setStyle(SkPaint::kStroke_Style);
+
+        paint.setAntiAlias(fDoAA);
+
+        SkMatrix rot;
+        rot.setRotate(90);
+        SkASSERT(rot.rectStaysRect());
+
+        canvas->concat(rot);
+
+        int sign;       // used to toggle the direction of the lines
+        int phase = 0;
+
+        for (int x = 0; x < 200; x += 10) {
+            paint.setStrokeWidth(SkIntToScalar(phase+1));
+            paint.setColor(gColors[phase]);
+            sign = (x % 20) ? 1 : -1;
+            drawline(canvas, kOn, kOff, paint, 
+                     SkIntToScalar(x), -sign * SkIntToScalar(10003), 
+                     SkIntToScalar(phase),
+                     SkIntToScalar(x),  sign * SkIntToScalar(10003));
+            phase = (phase + 1) % kIntervalLength;
+        }
+
+        for (int y = -400; y < 0; y += 10) {
+            paint.setStrokeWidth(SkIntToScalar(phase+1));
+            paint.setColor(gColors[phase]);
+            sign = (y % 20) ? 1 : -1;
+            drawline(canvas, kOn, kOff, paint, 
+                     -sign * SkIntToScalar(10003), SkIntToScalar(y), 
+                     SkIntToScalar(phase),
+                      sign * SkIntToScalar(10003), SkIntToScalar(y));
+            phase = (phase + 1) % kIntervalLength;
+        }
+    }
+
+private:
+    bool fDoAA;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM(return SkNEW(DashingGM);)
+DEF_GM(return SkNEW(Dashing2GM);)
+DEF_GM(return SkNEW(Dashing3GM);)
+DEF_GM(return SkNEW(Dashing4GM);)
+DEF_GM(return SkNEW_ARGS(Dashing5GM, (true));)
+DEF_GM(return SkNEW_ARGS(Dashing5GM, (false));)
+
diff --git a/gm/degeneratesegments.cpp b/gm/degeneratesegments.cpp
index e8de515..17bf83b 100644
--- a/gm/degeneratesegments.cpp
+++ b/gm/degeneratesegments.cpp
@@ -291,6 +291,7 @@
         SkPaint titlePaint;
         titlePaint.setColor(SK_ColorBLACK);
         titlePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&titlePaint);
         titlePaint.setLCDRenderText(true);
         titlePaint.setTextSize(15 * SK_Scalar1);
         const char title[] = "Random Paths Drawn Into Rectangle Clips With "
@@ -351,6 +352,7 @@
                 SkPaint labelPaint;
                 labelPaint.setColor(color);
                 labelPaint.setAntiAlias(true);
+                sk_tool_utils::set_portable_typeface(&labelPaint);
                 labelPaint.setLCDRenderText(true);
                 labelPaint.setTextSize(10 * SK_Scalar1);
                 canvas->drawText(style.fName,
diff --git a/gm/deviceproperties.cpp b/gm/deviceproperties.cpp
deleted file mode 100644
index 92a3d51..0000000
--- a/gm/deviceproperties.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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 "gm.h"
-#include "SkBitmapDevice.h"
-#include "SkTypeface.h"
-
-namespace skiagm {
-
-class DevicePropertiesGM : public GM {
-public:
-    DevicePropertiesGM() {
-        this->setBGColor(0xFFFFFFFF);
-    }
-
-    virtual ~DevicePropertiesGM() {
-    }
-
-protected:
-    virtual SkString onShortName() {
-        return SkString("deviceproperties");
-    }
-
-    virtual SkISize onISize() {
-        return SkISize::Make(1450, 750);
-    }
-
-    static void rotate_about(SkCanvas* canvas,
-                             SkScalar degrees,
-                             SkScalar px, SkScalar py) {
-        canvas->translate(px, py);
-        canvas->rotate(degrees);
-        canvas->translate(-px, -py);
-    }
-
-    virtual void onDraw(SkCanvas* originalCanvas) {
-        SkISize size = this->getISize();
-        SkBitmap bitmap;
-        bitmap.allocN32Pixels(size.width(), size.height());
-        SkDeviceProperties properties = SkDeviceProperties::Make(
-            SkDeviceProperties::Geometry::Make(SkDeviceProperties::Geometry::kVertical_Orientation,
-                                               SkDeviceProperties::Geometry::kBGR_Layout),
-            SK_Scalar1);
-        SkBitmapDevice device(bitmap, properties);
-        SkCanvas canvas(&device);
-        canvas.drawColor(SK_ColorWHITE);
-
-        SkPaint paint;
-
-        paint.setAntiAlias(true);
-        paint.setLCDRenderText(true);
-        //With freetype the default (normal hinting) can be really ugly.
-        //Most distros now set slight (vertical hinting only) in any event.
-        paint.setHinting(SkPaint::kSlight_Hinting);
-        SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromName("Times Roman", SkTypeface::kNormal)));
-
-        const char* text = "Hamburgefons ooo mmm";
-        const size_t textLen = strlen(text);
-
-        for (int j = 0; j < 2; ++j) {
-            for (int i = 0; i < 6; ++i) {
-                SkScalar x = SkIntToScalar(10);
-                SkScalar y = SkIntToScalar(20);
-
-                SkAutoCanvasRestore acr(&canvas, true);
-                canvas.translate(SkIntToScalar(50 + i * 230),
-                                  SkIntToScalar(20));
-                rotate_about(&canvas, SkIntToScalar(i * 5), x, y * 10);
-
-                {
-                    SkPaint p;
-                    p.setAntiAlias(true);
-                    SkRect r;
-                    r.set(x - SkIntToScalar(3), SkIntToScalar(15),
-                          x - SkIntToScalar(1), SkIntToScalar(280));
-                    canvas.drawRect(r, p);
-                }
-
-                int index = 0;
-                for (int ps = 6; ps <= 22; ps++) {
-                    paint.setTextSize(SkIntToScalar(ps));
-                    canvas.drawText(text, textLen, x, y, paint);
-                    y += paint.getFontMetrics(NULL);
-                    index += 1;
-                }
-            }
-            canvas.translate(0, SkIntToScalar(360));
-            paint.setSubpixelText(true);
-        }
-        originalCanvas->drawBitmap(bitmap, 0, 0);
-    }
-
-#ifdef SK_BUILD_FOR_ANDROID
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        // On android, we fail due to bad gpu drivers (it seems) by adding too
-        // much to our text atlas (texture).
-        return kSkipGPU_Flag;
-    }
-#endif
-
-private:
-    typedef GM INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-static GM* MyFactory(void*) { return new DevicePropertiesGM; }
-static GMRegistry reg(MyFactory);
-
-}
diff --git a/gm/dftext.cpp b/gm/dftext.cpp
new file mode 100755
index 0000000..5f58cb9
--- /dev/null
+++ b/gm/dftext.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "gm.h"
+#include "SkSurface.h"
+#include "SkTypeface.h"
+
+namespace skiagm {
+
+class DFTextGM : public GM {
+public:
+    DFTextGM() {
+        this->setBGColor(0xFFFFFFFF);
+    }
+
+    virtual ~DFTextGM() {
+    }
+
+protected:
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kGPUOnly_Flag;
+    }
+
+    virtual SkString onShortName() {
+        return SkString("dftext");
+    }
+
+    virtual SkISize onISize() {
+        return SkISize::Make(1024, 768);
+    }
+
+    static void rotate_about(SkCanvas* canvas,
+        SkScalar degrees,
+        SkScalar px, SkScalar py) {
+        canvas->translate(px, py);
+        canvas->rotate(degrees);
+        canvas->translate(-px, -py);
+    }
+
+    virtual void onDraw(SkCanvas* inputCanvas) {
+        SkScalar textSizes[] = { 11.0f, 11.0f*2.0f, 11.0f*5.0f, 11.0f*2.0f*5.0f };
+        SkScalar scales[] = { 2.0f*5.0f, 5.0f, 2.0f, 1.0f };
+
+        // set up offscreen rendering with distance field text
+#if SK_SUPPORT_GPU
+        GrContext* ctx = inputCanvas->getGrContext();
+        SkImageInfo info = SkImageInfo::MakeN32Premul(onISize());
+        SkSurfaceProps props(SkSurfaceProps::kUseDistanceFieldFonts_Flag,
+                             SkSurfaceProps::kLegacyFontHost_InitType);
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, info, 0, &props));
+        SkCanvas* canvas = surface.get() ? surface->getCanvas() : inputCanvas;
+#else
+        SkCanvas* canvas = inputCanvas;
+#endif
+        
+        // apply global scale to test glyph positioning
+        canvas->scale(1.05f, 1.05f);
+        canvas->clear(0xffffffff);
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setSubpixelText(true);
+#if !SK_SUPPORT_GPU
+        paint.setDistanceFieldTextTEMP(true);
+#endif
+        sk_tool_utils::set_portable_typeface(&paint, "Times New Roman", SkTypeface::kNormal);
+
+        const char* text = "Hamburgefons";
+        const size_t textLen = strlen(text);
+
+        // check scaling up
+        SkScalar x = SkIntToScalar(0);
+        SkScalar y = SkIntToScalar(78);
+        for (size_t i = 0; i < SK_ARRAY_COUNT(textSizes); ++i) {
+            SkAutoCanvasRestore acr(canvas, true);
+            canvas->translate(x, y);
+            canvas->scale(scales[i], scales[i]);
+            paint.setTextSize(textSizes[i]);
+            canvas->drawText(text, textLen, 0, 0, paint);
+            y += paint.getFontMetrics(NULL)*scales[i];
+        }
+
+        // check rotation
+        for (size_t i = 0; i < 5; ++i) {
+            SkScalar rotX = SkIntToScalar(10);
+            SkScalar rotY = y;
+
+            SkAutoCanvasRestore acr(canvas, true);
+            canvas->translate(SkIntToScalar(10 + i * 200), -80);
+            rotate_about(canvas, SkIntToScalar(i * 5), rotX, rotY);
+            for (int ps = 6; ps <= 32; ps += 3) {
+                paint.setTextSize(SkIntToScalar(ps));
+                canvas->drawText(text, textLen, rotX, rotY, paint);
+                rotY += paint.getFontMetrics(NULL);
+            }
+        }
+
+        // check scaling down
+        paint.setLCDRenderText(true);
+        x = SkIntToScalar(680);
+        y = SkIntToScalar(20);
+        size_t arraySize = SK_ARRAY_COUNT(textSizes);
+        for (size_t i = 0; i < arraySize; ++i) {
+            SkAutoCanvasRestore acr(canvas, true);
+            canvas->translate(x, y);
+            SkScalar scaleFactor = SkScalarInvert(scales[arraySize - i - 1]);
+            canvas->scale(scaleFactor, scaleFactor);
+            paint.setTextSize(textSizes[i]);
+            canvas->drawText(text, textLen, 0, 0, paint);
+            y += paint.getFontMetrics(NULL)*scaleFactor;
+        }
+
+        // check pos text
+        {
+            SkAutoCanvasRestore acr(canvas, true);
+
+            canvas->scale(2.0f, 2.0f);
+
+            SkAutoTArray<SkPoint>  pos(textLen);
+            SkAutoTArray<SkScalar> widths(textLen);
+            paint.setTextSize(textSizes[0]);
+
+            paint.getTextWidths(text, textLen, &widths[0]);
+
+            SkScalar x = SkIntToScalar(340);
+            SkScalar y = SkIntToScalar(75);
+            for (unsigned int i = 0; i < textLen; ++i) {
+                pos[i].set(x, y);
+                x += widths[i];
+            }
+
+            canvas->drawPosText(text, textLen, &pos[0], paint);
+        }
+
+
+        // check gamma-corrected blending
+        const SkColor fg[] = {
+            0xFFFFFFFF,
+            0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF,
+            0xFFFF0000, 0xFF00FF00, 0xFF0000FF,
+            0xFF000000,
+        };
+
+        paint.setColor(0xFFF1F1F1);
+        SkRect r = SkRect::MakeLTRB(670, 250, 820, 460);
+        canvas->drawRect(r, paint);
+
+        x = SkIntToScalar(680);
+        y = SkIntToScalar(270);
+        paint.setTextSize(SkIntToScalar(22));
+        for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
+            paint.setColor(fg[i]);
+
+            canvas->drawText(text, textLen, x, y, paint);
+            y += paint.getFontMetrics(NULL);
+        }
+
+        paint.setColor(0xFF1F1F1F);
+        r = SkRect::MakeLTRB(820, 250, 970, 460);
+        canvas->drawRect(r, paint);
+
+        x = SkIntToScalar(830);
+        y = SkIntToScalar(270);
+        paint.setTextSize(SkIntToScalar(22));
+        for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
+            paint.setColor(fg[i]);
+
+            canvas->drawText(text, textLen, x, y, paint);
+            y += paint.getFontMetrics(NULL);
+        }
+
+#if SK_SUPPORT_GPU
+        // render offscreen buffer
+        if (surface) {
+            SkImage* image = surface->newImageSnapshot();
+            inputCanvas->drawImage(image, 0, 0, NULL);
+            image->unref();
+        }
+#endif
+    }
+
+private:
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new DFTextGM; }
+static GMRegistry reg(MyFactory);
+
+}
diff --git a/gm/displacement.cpp b/gm/displacement.cpp
index eb4a008..dddf8a5 100644
--- a/gm/displacement.cpp
+++ b/gm/displacement.cpp
@@ -37,6 +37,7 @@
         canvas.clear(0x00000000);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xFF884422);
         paint.setTextSize(SkIntToScalar(96));
         const char* str = "g";
diff --git a/gm/distantclip.cpp b/gm/distantclip.cpp
index 9c44140..54938b0 100644
--- a/gm/distantclip.cpp
+++ b/gm/distantclip.cpp
@@ -27,38 +27,34 @@
     SkISize onISize() { return SkISize::Make(100, 100); }
 
     virtual void onDraw(SkCanvas* canvas) {
-        int offset = 35000;
-        int extents = 1000;
+        static const SkScalar kOffset = 35000.0f;
+        static const SkScalar kExtents = 1000.0f;
 
         SkPictureRecorder recorder;
         // We record a picture of huge vertical extents in which we clear the canvas to red, create
         // a 'extents' by 'extents' round rect clip at a vertical offset of 'offset', then draw
         // green into that.
-        SkCanvas* rec = recorder.beginRecording(100, offset + extents, NULL, 0);
-        rec->drawColor(0xffff0000);
+        SkCanvas* rec = recorder.beginRecording(kExtents, kOffset + kExtents, NULL, 0);
+        rec->drawColor(SK_ColorRED);
         rec->save();
-        SkRect r = {
-            SkIntToScalar(-extents),
-            SkIntToScalar(offset - extents),
-            SkIntToScalar(extents),
-            SkIntToScalar(offset + extents)
-        };
+        SkRect r = SkRect::MakeXYWH(-kExtents, kOffset - kExtents, 2 * kExtents, 2 * kExtents);
         SkPath p;
         p.addRoundRect(r, 5, 5);
         rec->clipPath(p, SkRegion::kIntersect_Op, true);
-        rec->drawColor(0xff00ff00);
+        rec->drawColor(SK_ColorGREEN);
         rec->restore();
         SkAutoTUnref<SkPicture> pict(recorder.endRecording());
 
         // Next we play that picture into another picture of the same size.
-        pict->draw(recorder.beginRecording(100, offset + extents, NULL, 0));
+        pict->playback(recorder.beginRecording(pict->cullRect().width(), 
+                                               pict->cullRect().height(), 
+                                               NULL, 0));
         SkAutoTUnref<SkPicture> pict2(recorder.endRecording());
 
         // Finally we play the part of that second picture that should be green into the canvas.
         canvas->save();
-        canvas->translate(SkIntToScalar(extents / 2),
-                          SkIntToScalar(-(offset - extents / 2)));
-        pict2->draw(canvas);
+        canvas->translate(kExtents / 2, -(kOffset - kExtents / 2));
+        pict2->playback(canvas);
         canvas->restore();
 
         // If the image is red, we erroneously decided the clipPath was empty and didn't record
diff --git a/gm/downsamplebitmap.cpp b/gm/downsamplebitmap.cpp
index a911b83..19faaa0 100644
--- a/gm/downsamplebitmap.cpp
+++ b/gm/downsamplebitmap.cpp
@@ -15,7 +15,7 @@
 #include "SkPaint.h"
 
 static void setTypeface(SkPaint* paint, const char name[], SkTypeface::Style style) {
-    SkSafeUnref(paint->setTypeface(SkTypeface::CreateFromName(name, style)));
+    sk_tool_utils::set_portable_typeface(paint, name, style);
 }
 
 class DownsampleBitmapGM : public skiagm::GM {
@@ -41,10 +41,7 @@
 
 protected:
     virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        if (SkPaint::kHigh_FilterLevel != fFilterLevel) {
-            return kSkipTiled_Flag;
-        }
-        return 0;
+        return kSkipTiled_Flag;
     }
 
     virtual SkString onShortName() SK_OVERRIDE {
@@ -53,7 +50,7 @@
 
     virtual SkISize onISize() SK_OVERRIDE {
         make_bitmap_wrapper();
-        return SkISize::Make(4 * fBM.width(), fBM.height());
+        return SkISize::Make(fBM.width(), 4 * fBM.height());
     }
 
     void make_bitmap_wrapper() {
@@ -68,8 +65,8 @@
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
         make_bitmap_wrapper();
 
-        int curX = 0;
-        int curWidth;
+        int curY = 0;
+        int curHeight;
         float curScale = 1;
         do {
 
@@ -80,14 +77,14 @@
             paint.setFilterLevel(fFilterLevel);
 
             canvas->save();
-            canvas->translate( (SkScalar) curX, 0.f );
+            canvas->translate(0, (SkScalar)curY);
             canvas->drawBitmapMatrix( fBM, matrix, &paint );
             canvas->restore();
 
-            curWidth = (int) (fBM.width() * curScale + 2);
-            curX += curWidth;
+            curHeight = (int) (fBM.height() * curScale + 2);
+            curY += curHeight;
             curScale *= 0.75f;
-        } while (curWidth >= 2 && curX < 4*fBM.width());
+        } while (curHeight >= 2 && curY < 4*fBM.height());
     }
 
 private:
@@ -172,11 +169,8 @@
       int fSize;
 
       virtual void make_bitmap() SK_OVERRIDE {
-          SkString resourcePath = GetResourcePath();
-          resourcePath.append("/");
-          resourcePath.append(fFilename);
-
           SkImageDecoder* codec = NULL;
+          SkString resourcePath = GetResourcePath(fFilename.c_str());
           SkFILEStream stream(resourcePath.c_str());
           if (stream.isValid()) {
               codec = SkImageDecoder::Factory(&stream);
diff --git a/gm/drawbitmaprect.cpp b/gm/drawbitmaprect.cpp
index 9c6fa3b..fd205f5 100644
--- a/gm/drawbitmaprect.cpp
+++ b/gm/drawbitmaprect.cpp
@@ -111,6 +111,7 @@
         blackPaint.setColor(SK_ColorBLACK);
         blackPaint.setTextSize(titleHeight);
         blackPaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&blackPaint);
         SkString title;
         title.printf("Bitmap size: %d x %d", kBmpSize, kBmpSize);
         canvas->drawText(title.c_str(), title.size(), 0,
diff --git a/gm/drawlooper.cpp b/gm/drawlooper.cpp
index a04955b..a1b55bb 100644
--- a/gm/drawlooper.cpp
+++ b/gm/drawlooper.cpp
@@ -27,10 +27,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkISize onISize() {
         return SkISize::Make(520, 160);
     }
@@ -44,6 +40,7 @@
 
         SkPaint  paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setTextSize(SkIntToScalar(72));
         paint.setLooper(fLooper);
 
diff --git a/gm/dropshadowimagefilter.cpp b/gm/dropshadowimagefilter.cpp
index ec849b2..a22ec43 100644
--- a/gm/dropshadowimagefilter.cpp
+++ b/gm/dropshadowimagefilter.cpp
@@ -39,6 +39,7 @@
     paint.setImageFilter(imf);
     paint.setColor(SK_ColorGREEN);
     paint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&paint);
     paint.setTextSize(r.height()/2);
     paint.setTextAlign(SkPaint::kCenter_Align);
     canvas->save();
diff --git a/gm/emboss.cpp b/gm/emboss.cpp
new file mode 100644
index 0000000..c2ee497
--- /dev/null
+++ b/gm/emboss.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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 "gm.h"
+#include "SkBlurMaskFilter.h"
+#include "SkCanvas.h"
+#include "SkColorFilter.h"
+
+#include "SkColorFilter.h"
+static SkBitmap make_bm() {
+    SkBitmap bm;
+    bm.allocN32Pixels(100, 100);
+
+    SkCanvas canvas(bm);
+    canvas.clear(0);
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    canvas.drawCircle(50, 50, 50, paint);
+    return bm;
+}
+
+class EmbossGM : public skiagm::GM {
+public:
+    EmbossGM() {
+    }
+
+protected:
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("emboss");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(600, 120);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        SkPaint paint;
+        SkBitmap bm = make_bm();
+        canvas->drawBitmap(bm, 10, 10, &paint);
+
+        const SkScalar dir[] = { 1, 1, 1 };
+        paint.setMaskFilter(SkBlurMaskFilter::CreateEmboss(3, dir, 0.3f, 0.1f))->unref();
+        canvas->translate(bm.width() + SkIntToScalar(10), 0);
+        canvas->drawBitmap(bm, 10, 10, &paint);
+
+        // this combination of emboss+colorfilter used to crash -- so we exercise it to
+        // confirm that we have a fix.
+        paint.setColorFilter(SkColorFilter::CreateModeFilter(0xFFFF0000, SkXfermode::kSrcATop_Mode))->unref();
+        canvas->translate(bm.width() + SkIntToScalar(10), 0);
+        canvas->drawBitmap(bm, 10, 10, &paint);
+    }
+
+private:
+    typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return SkNEW(EmbossGM); )
diff --git a/gm/emptypath.cpp b/gm/emptypath.cpp
index 6b93222..87e1cc5 100644
--- a/gm/emptypath.cpp
+++ b/gm/emptypath.cpp
@@ -63,6 +63,7 @@
         SkPaint titlePaint;
         titlePaint.setColor(SK_ColorBLACK);
         titlePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&titlePaint);
         titlePaint.setLCDRenderText(true);
         titlePaint.setTextSize(15 * SK_Scalar1);
         const char title[] = "Empty Paths Drawn Into Rectangle Clips With "
@@ -105,6 +106,7 @@
                 SkPaint labelPaint;
                 labelPaint.setColor(color);
                 labelPaint.setAntiAlias(true);
+                sk_tool_utils::set_portable_typeface(&labelPaint);
                 labelPaint.setLCDRenderText(true);
                 labelPaint.setTextSize(12 * SK_Scalar1);
                 canvas->drawText(gStyles[style].fName,
diff --git a/gm/etc1bitmap.cpp b/gm/etc1bitmap.cpp
index e0a59b0..fcf521a 100644
--- a/gm/etc1bitmap.cpp
+++ b/gm/etc1bitmap.cpp
@@ -95,10 +95,8 @@
 
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
         SkBitmap bm;
-        SkString resourcePath = GetResourcePath();
-        SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_128.");
+        SkString filename = GetResourcePath("mandrill_128.");
         filename.append(this->fileExtension());
-
         SkAutoTUnref<SkData> fileData(SkData::NewFromFileName(filename.c_str()));
         if (NULL == fileData) {
             SkDebugf("Could not open the file. Did you forget to set the resourcePath?\n");
@@ -147,6 +145,20 @@
     typedef ETC1BitmapGM INHERITED;
 };
 
+// This class specializes ETC1BitmapGM to load the mandrill_128.r11.ktx file.
+class ETC1Bitmap_R11_KTX_GM : public ETC1BitmapGM {
+public:
+    ETC1Bitmap_R11_KTX_GM() : ETC1BitmapGM() { }
+    virtual ~ETC1Bitmap_R11_KTX_GM() { }
+
+protected:
+
+    virtual SkString fileExtension() const SK_OVERRIDE { return SkString("r11.ktx"); }
+
+private:
+    typedef ETC1BitmapGM INHERITED;
+};
+
 #ifndef SK_IGNORE_ETC1_SUPPORT
 /**
  *  Test decoding an image from a PKM file and then
@@ -170,10 +182,8 @@
 
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
         SkBitmap bm;
-        SkString resourcePath = GetResourcePath();
-        SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_128.pkm");
-
-        SkAutoDataUnref fileData(SkData::NewFromFileName(filename.c_str()));
+        SkString pkmFilename = GetResourcePath("mandrill_128.pkm");
+        SkAutoDataUnref fileData(SkData::NewFromFileName(pkmFilename.c_str()));
         if (NULL == fileData) {
             SkDebugf("Could not open the file. Did you forget to set the resourcePath?\n");
             return;
@@ -215,6 +225,7 @@
 
 DEF_GM( return SkNEW(skiagm::ETC1Bitmap_PKM_GM); )
 DEF_GM( return SkNEW(skiagm::ETC1Bitmap_KTX_GM); )
+DEF_GM( return SkNEW(skiagm::ETC1Bitmap_R11_KTX_GM); )
 
 #ifndef SK_IGNORE_ETC1_SUPPORT
 DEF_GM( return SkNEW(skiagm::ETC1Bitmap_NPOT_GM); )
diff --git a/gm/factory.cpp b/gm/factory.cpp
index 641133c..a9bf519 100644
--- a/gm/factory.cpp
+++ b/gm/factory.cpp
@@ -29,11 +29,10 @@
 
 protected:
     virtual void onOnceBeforeDraw() SK_OVERRIDE {
-        SkString resourcePath = GetResourcePath();
         // Copyright-free file from http://openclipart.org/detail/29213/paper-plane-by-ddoo
-        SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), "plane.png");
-        SkAutoDataUnref data(SkData::NewFromFileName(filename.c_str()));
-        if (NULL != data.get()) {
+        SkString pngFilename = GetResourcePath("plane.png");
+        SkAutoDataUnref data(SkData::NewFromFileName(pngFilename.c_str()));
+        if (data.get()) {
             // Create a cache which will boot the pixels out anytime the
             // bitmap is unlocked.
             SkAutoTUnref<SkDiscardableMemoryPool> pool(
diff --git a/gm/filterbitmap.cpp b/gm/filterbitmap.cpp
index d73318d..26a1886 100644
--- a/gm/filterbitmap.cpp
+++ b/gm/filterbitmap.cpp
@@ -14,7 +14,7 @@
 #include "SkTypeface.h"
 
 static void setTypeface(SkPaint* paint, const char name[], SkTypeface::Style style) {
-    SkSafeUnref(paint->setTypeface(SkTypeface::CreateFromName(name, style)));
+    sk_tool_utils::set_portable_typeface(paint, name, style);
 }
 
 static SkSize computeSize(const SkBitmap& bm, const SkMatrix& mat) {
@@ -194,11 +194,8 @@
       }
 
       void makeBitmap() SK_OVERRIDE {
-          SkString resourcePath = GetResourcePath();
-          resourcePath.append("/");
-          resourcePath.append(fFilename);
-
           SkImageDecoder* codec = NULL;
+          SkString resourcePath = GetResourcePath(fFilename.c_str());
           SkFILEStream stream(resourcePath.c_str());
           if (stream.isValid()) {
               codec = SkImageDecoder::Factory(&stream);
diff --git a/gm/filterindiabox.cpp b/gm/filterindiabox.cpp
index 1987c95..a29f08b 100644
--- a/gm/filterindiabox.cpp
+++ b/gm/filterindiabox.cpp
@@ -71,14 +71,17 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() SK_OVERRIDE {
         return fName;
     }
 
+#ifdef SK_CPU_ARM64
+    // Skip tiled drawing on 64-bit ARM until https://skbug.com/2908 is fixed.
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+#endif
+
     virtual SkISize onISize() SK_OVERRIDE {
         return SkISize::Make(1024, 768);
     }
@@ -104,11 +107,8 @@
       }
 
       void makeBitmap() {
-          SkString resourcePath = GetResourcePath();
-          resourcePath.append("/");
-          resourcePath.append(fFilename);
-
           SkImageDecoder* codec = NULL;
+          SkString resourcePath = GetResourcePath(fFilename.c_str());
           SkFILEStream stream(resourcePath.c_str());
           if (stream.isValid()) {
               codec = SkImageDecoder::Factory(&stream);
diff --git a/gm/fontcache.cpp b/gm/fontcache.cpp
index cb73e91..99554a2 100644
--- a/gm/fontcache.cpp
+++ b/gm/fontcache.cpp
@@ -13,15 +13,15 @@
 // GM to stress the GPU font cache
 
 const char* gFamilyNames[] = {
-    "sans-serif", "serif", "monospace"
+    "sans-serif", "serif"
 };
 
 const SkTypeface::Style gStyles[] = {
-    SkTypeface::kNormal, SkTypeface::kItalic
+    SkTypeface::kNormal, SkTypeface::kItalic, SkTypeface::kBold
 };
 
 const SkScalar gTextSizes[] = {
-    12, 14, 16, 18, 20, 22, 24, 26, 28, 30
+    192, 194, 196, 198, 200, 202, 204, 206
 };
 
 #define TYPEFACE_COUNT (SK_ARRAY_COUNT(gFamilyNames)*SK_ARRAY_COUNT(gStyles))
@@ -52,15 +52,15 @@
     }
 
     virtual SkISize onISize() SK_OVERRIDE {
-        return SkISize::Make(640, 320);
+        return SkISize::Make(1280, 640);
     }
 
     virtual void onOnceBeforeDraw() SK_OVERRIDE {
         int typefaceCount = 0;
         for (size_t i = 0; i < SK_ARRAY_COUNT(gFamilyNames); ++i) {
             for (size_t j = 0; j < SK_ARRAY_COUNT(gStyles); ++j) {
-                fTypefaces[typefaceCount++] = SkTypeface::CreateFromName(gFamilyNames[i],
-                                                                          gStyles[j]);
+                fTypefaces[typefaceCount++] = sk_tool_utils::create_portable_typeface(gFamilyNames[i],
+                                                                               gStyles[j]);
             }
         }
     }
@@ -72,33 +72,18 @@
         paint.setLCDRenderText(true);
         paint.setSubpixelText(true);
 
-        SkString text("Ham");
+        SkString text("H");
 
-        // draw some initial text to partially fill the GPU cache
-        for (size_t i = 0; i < 2; ++i) {
-            paint.setTypeface(fTypefaces[i]);
-            SkScalar x = 20;
-
-            for (size_t j = 0; j < SK_ARRAY_COUNT(gTextSizes); ++j) {
-                paint.setTextSize(gTextSizes[j]);
-                x = draw_string(canvas, text, x, y, paint) + 19;
-            }
-            y += 32;
-        }
-
-        // force a flush
-        canvas->flush();
-
-        // draw again, and more to overflow the cache
+        // draw enough to overflow the cache
         for (size_t i = 0; i < TYPEFACE_COUNT; ++i) {
             paint.setTypeface(fTypefaces[i]);
             SkScalar x = 20;
 
             for (size_t j = 0; j < SK_ARRAY_COUNT(gTextSizes); ++j) {
                 paint.setTextSize(gTextSizes[j]);
-                x = draw_string(canvas, text, x, y, paint) + 19;
+                x = draw_string(canvas, text, x, y, paint) + 10;
             }
-            y += 32;
+            y += 128;
         }
 
     }
diff --git a/gm/fontmgr.cpp b/gm/fontmgr.cpp
index d9a0aa5..e334274 100644
--- a/gm/fontmgr.cpp
+++ b/gm/fontmgr.cpp
@@ -24,6 +24,35 @@
     return x + paint.measureText(text.c_str(), text.size());
 }
 
+static SkScalar drawCharacter(SkCanvas* canvas, uint32_t character, SkScalar x,
+                              SkScalar y, SkPaint& paint, SkFontMgr* fm,
+                              const char* fontName, const char* bpc47,
+                              const SkFontStyle& fontStyle) {
+    // find typeface containing the requested character and draw it
+    SkString ch;
+    ch.appendUnichar(character);
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
+    SkTypeface* typeface = fm->matchFamilyStyleCharacter(fontName, fontStyle, &bpc47, 1, character);
+#else
+    SkTypeface* typeface = fm->matchFamilyStyleCharacter(fontName, fontStyle, bpc47, character);
+#endif
+    SkSafeUnref(paint.setTypeface(typeface));
+    x = drawString(canvas, ch, x, y, paint) + 20;
+
+    if (NULL == typeface) {
+        return x;
+    }
+
+    // repeat the process, but this time use the family name of the typeface
+    // from the first pass.  This emulates the behavior in Blink where it
+    // it expects to get the same glyph when following this pattern.
+    SkString familyName;
+    typeface->getFamilyName(&familyName);
+    SkTypeface* typefaceCopy = fm->legacyCreateTypeface(familyName.c_str(), typeface->style());
+    SkSafeUnref(paint.setTypeface(typefaceCopy));
+    return drawString(canvas, ch, x, y, paint) + 20;
+}
+
 class FontMgrGM : public skiagm::GM {
 public:
     FontMgrGM(SkFontMgr* fontMgr = NULL) {
@@ -44,7 +73,7 @@
     }
 
     virtual SkISize onISize() {
-        return SkISize::Make(640, 1024);
+        return SkISize::Make(1536, 768);
     }
 
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
@@ -75,6 +104,12 @@
 
                 SkSafeUnref(paint.setTypeface(set->createTypeface(j)));
                 x = drawString(canvas, sname, x, y, paint) + 20;
+
+                // check to see that we get different glyphs in japanese and chinese
+                x = drawCharacter(canvas, 0x5203, x, y, paint, fm, fName.c_str(), "zh", fs);
+                x = drawCharacter(canvas, 0x5203, x, y, paint, fm, fName.c_str(), "ja", fs);
+                // check that emoji characters are found
+                x = drawCharacter(canvas, 0x1f601, x, y, paint, fm, fName.c_str(), NULL, fs);
             }
             y += 24;
         }
diff --git a/gm/fontscaler.cpp b/gm/fontscaler.cpp
index 8a97e69..eb38013 100644
--- a/gm/fontscaler.cpp
+++ b/gm/fontscaler.cpp
@@ -47,7 +47,7 @@
         //With freetype the default (normal hinting) can be really ugly.
         //Most distros now set slight (vertical hinting only) in any event.
         paint.setHinting(SkPaint::kSlight_Hinting);
-        SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromName("Times Roman", SkTypeface::kNormal)));
+        sk_tool_utils::set_portable_typeface(&paint, "Times Roman", SkTypeface::kNormal);
 
         const char* text = "Hamburgefons ooo mmm";
         const size_t textLen = strlen(text);
@@ -72,12 +72,10 @@
                     canvas->drawRect(r, p);
                 }
 
-                int index = 0;
                 for (int ps = 6; ps <= 22; ps++) {
                     paint.setTextSize(SkIntToScalar(ps));
                     canvas->drawText(text, textLen, x, y, paint);
                     y += paint.getFontMetrics(NULL);
-                    index += 1;
                 }
             }
             canvas->translate(0, SkIntToScalar(360));
diff --git a/gm/gammatext.cpp b/gm/gammatext.cpp
index f10680e..54b0765 100644
--- a/gm/gammatext.cpp
+++ b/gm/gammatext.cpp
@@ -26,7 +26,7 @@
 }
 
 static bool setFont(SkPaint* paint, const char name[]) {
-    SkTypeface* tf = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
+    SkTypeface* tf = sk_tool_utils::create_portable_typeface(name, SkTypeface::kNormal);
     if (tf) {
         paint->setTypeface(tf)->unref();
         return true;
@@ -99,8 +99,6 @@
 }
 #endif
 
-namespace skiagm {
-
 /**
    Test a set of clipping problems discovered while writing blitAntiRect,
    and test all the code paths through the clipping blitters.
@@ -110,7 +108,7 @@
 
 #define HEIGHT 480
 
-class GammaTextGM : public GM {
+class GammaTextGM : public skiagm::GM {
 public:
     GammaTextGM() {
 
@@ -199,12 +197,89 @@
     }
 
 private:
-    typedef GM INHERITED;
+    typedef skiagm::GM INHERITED;
 };
 
+DEF_GM( return new GammaTextGM; )
+
 //////////////////////////////////////////////////////////////////////////////
 
-static GM* MyFactory(void*) { return new GammaTextGM; }
-static GMRegistry reg(MyFactory);
-
+static SkShader* make_gradient(SkColor c) {
+    const SkPoint pts[] = { { 0, 0 }, { 240, 0 } };
+    SkColor colors[2];
+    colors[0] = c;
+    colors[1] = SkColorSetA(c, 0);
+    return SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
 }
+
+static void set_face(SkPaint* paint) {
+    SkTypeface* face = SkTypeface::CreateFromName("serif", SkTypeface::kItalic);
+    SkSafeUnref(paint->setTypeface(face));
+}
+
+static void draw_pair(SkCanvas* canvas, SkPaint* paint, SkShader* shader) {
+    const char text[] = "Now is the time for all good";
+    const size_t len = strlen(text);
+    
+    paint->setShader(NULL);
+    canvas->drawText(text, len, 10, 20, *paint);
+    paint->setShader(SkShader::CreateColorShader(paint->getColor()))->unref();
+    canvas->drawText(text, len, 10, 40, *paint);
+    paint->setShader(shader);
+    canvas->drawText(text, len, 10, 60, *paint);
+}
+
+class GammaShaderTextGM : public skiagm::GM {
+    SkShader* fShaders[3];
+    SkColor fColors[3];
+
+public:
+    GammaShaderTextGM() {
+        const SkColor colors[] = { SK_ColorBLACK, SK_ColorRED, SK_ColorBLUE };
+        for (size_t i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
+            fShaders[i] = NULL;
+            fColors[i] = colors[i];
+        }
+    }
+
+    virtual ~GammaShaderTextGM() {
+        for (size_t i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
+            SkSafeUnref(fShaders[i]);
+        }
+    }
+
+protected:
+    virtual SkString onShortName() {
+        return SkString("gammagradienttext");
+    }
+    
+    virtual SkISize onISize() {
+        return SkISize::Make(300, 300);
+    }
+
+    virtual void onOnceBeforeDraw() {
+        for (size_t i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
+            fShaders[i] = make_gradient(fColors[i]);
+        }
+    }
+
+    virtual void onDraw(SkCanvas* canvas) {
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setLCDRenderText(true);
+        paint.setTextSize(18);
+        set_face(&paint);
+
+        for (size_t i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
+            paint.setColor(fColors[i]);
+            draw_pair(canvas, &paint, fShaders[i]);
+            canvas->translate(0, 80);
+        }
+    }
+    
+private:
+    typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return new GammaShaderTextGM; )
+
diff --git a/gm/getpostextpath.cpp b/gm/getpostextpath.cpp
index 0f66a97..a411520 100644
--- a/gm/getpostextpath.cpp
+++ b/gm/getpostextpath.cpp
@@ -42,6 +42,7 @@
 
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setTextSize(SkIntToScalar(48));
 
         canvas->translate(SkIntToScalar(10), SkIntToScalar(64));
diff --git a/gm/giantbitmap.cpp b/gm/giantbitmap.cpp
index 1a78fcf..de908fe 100644
--- a/gm/giantbitmap.cpp
+++ b/gm/giantbitmap.cpp
@@ -72,10 +72,14 @@
 
 protected:
     virtual uint32_t onGetFlags() const SK_OVERRIDE {
+#ifdef SK_BUILD_FOR_ANDROID
+        return kSkipTiled_Flag;
+#else
         if (fDoFilter && fDoRotate && fMode != SkShader::kClamp_TileMode) {
             return kSkipTiled_Flag;
         }
         return 0;
+#endif
     }
 
     virtual SkString onShortName() {
diff --git a/gm/glyph_pos.cpp b/gm/glyph_pos.cpp
new file mode 100644
index 0000000..ecb9963
--- /dev/null
+++ b/gm/glyph_pos.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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 "gm.h"
+#include "SkCanvas.h"
+#include "SkTypeface.h"
+
+/* This test tries to define the effect of using hairline strokes on text.
+ * Provides non-hairline images for reference and consistency checks.
+ * glyph_pos_(h/n)_(s/f/b)
+ *   -> test hairline/non-hairline stroke/fill/stroke+fill.
+ */
+static const SkScalar kTextHeight = 14.0f;
+static const char kText[] = "Proportional Hamburgefons #% fi";
+
+namespace skiagm {
+
+class GlyphPosGM : public GM {
+public:
+    GlyphPosGM(SkScalar strokeWidth, SkPaint::Style strokeStyle)
+        : fStrokeWidth(strokeWidth)
+        , fStrokeStyle(strokeStyle) {
+        }
+
+protected:
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+
+    virtual SkString onShortName() SK_OVERRIDE {
+        SkString str("glyph_pos");
+        if (fStrokeWidth == 0.0f) {
+            str.append("_h"); // h == Hairline.
+        } else {
+            str.append("_n"); // n == Normal.
+        }
+        if (fStrokeStyle == SkPaint::kStroke_Style) {
+            str.append("_s");
+        } else if (fStrokeStyle == SkPaint::kFill_Style) {
+            str.append("_f");
+        } else {
+            str.append("_b"); // b == Both.
+        }
+        return str;
+    }
+
+    virtual SkISize onISize() { return SkISize::Make(800, 600); }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        if (!fProp) {
+            fProp.reset(sk_tool_utils::create_portable_typeface("Helvetica", SkTypeface::kNormal));
+        }
+
+        // There's a black pixel at 40, 40 for reference.
+        canvas->drawPoint(40.0f, 40.0f, SK_ColorBLACK);
+
+        // Two reference images.
+        canvas->translate(50.0f, 50.0f);
+        drawTestCase(canvas, 1.0f);
+
+        canvas->translate(0.0f, 50.0f);
+        drawTestCase(canvas, 3.0f);
+
+        // Uniform scaling test.
+        canvas->translate(0.0f, 100.0f);
+        canvas->save();
+        canvas->scale(3.0f, 3.0f);
+        drawTestCase(canvas, 1.0f);
+        canvas->restore();
+
+        // Non-uniform scaling test.
+        canvas->translate(0.0f, 100.0f);
+        canvas->save();
+        canvas->scale(3.0f, 6.0f);
+        drawTestCase(canvas, 1.0f);
+        canvas->restore();
+
+        // Skew test.
+        canvas->translate(0.0f, 80.0f);
+        canvas->save();
+        canvas->scale(3.0f, 3.0f);
+        SkMatrix skew;
+        skew.setIdentity();
+        skew.setSkewX(SkScalarDiv(8.0f,
+                                  25.0f));
+        skew.setSkewY(SkScalarDiv(2.0f,
+                                  25.0f));
+        canvas->concat(skew);
+        drawTestCase(canvas, 1.0f);
+        canvas->restore();
+
+        // Perspective test.
+        canvas->translate(0.0f, 80.0f);
+        canvas->save();
+        SkMatrix perspective;
+        perspective.setIdentity();
+        perspective.setPerspX(-SkScalarDiv(SK_Scalar1, 340.0f));
+        perspective.setSkewX(SkScalarDiv(8.0f,
+                                         25.0f));
+        perspective.setSkewY(SkScalarDiv(2.0f,
+                                         25.0f));
+
+
+        canvas->concat(perspective);
+        drawTestCase(canvas, 1.0f);
+        canvas->restore();
+    }
+
+    void drawTestCase(SkCanvas* canvas, SkScalar textScale) {
+        SkPaint paint;
+        paint.setColor(SK_ColorBLACK);
+        paint.setAntiAlias(true);
+        paint.setTextSize(kTextHeight * textScale);
+        paint.setTypeface(fProp);
+        paint.setDevKernText(true);
+        paint.setStrokeWidth(fStrokeWidth);
+        paint.setStyle(fStrokeStyle);
+
+        // This demonstrates that we can not measure the text if there's a device transform. The
+        // canvas total matrix will end up being a device transform.
+        bool drawRef = !(canvas->getTotalMatrix().getType() &
+                         ~(SkMatrix::kIdentity_Mask | SkMatrix::kTranslate_Mask));
+
+        SkRect bounds;
+        if (drawRef) {
+            SkScalar advance = paint.measureText(kText, sizeof(kText) - 1, &bounds);
+
+            paint.setStrokeWidth(0.0f);
+            paint.setStyle(SkPaint::kStroke_Style);
+
+            // Green box is the measured text bounds.
+            paint.setColor(SK_ColorGREEN);
+            canvas->drawRect(bounds, paint);
+
+            // Red line is the measured advance from the 0,0 of the text position.
+            paint.setColor(SK_ColorRED);
+            canvas->drawLine(0.0f, 0.0f, advance, 0.0f, paint);
+        }
+
+        // Black text is the testcase, eg. the text.
+        paint.setColor(SK_ColorBLACK);
+        paint.setStrokeWidth(fStrokeWidth);
+        paint.setStyle(fStrokeStyle);
+        canvas->drawText(kText, sizeof(kText) - 1, 0.0f, 0.0f, paint);
+
+        if (drawRef) {
+            SkScalar widths[sizeof(kText) - 1];
+            paint.getTextWidths(kText, sizeof(kText) - 1, widths, NULL);
+
+            paint.setStrokeWidth(0.0f);
+            paint.setStyle(SkPaint::kStroke_Style);
+
+            // Magenta lines are the positions for the characters.
+            paint.setColor(SK_ColorMAGENTA);
+            SkScalar w = bounds.x();
+            for (size_t i = 0; i < sizeof(kText) - 1; ++i) {
+                canvas->drawLine(w, 0.0f, w, 5.0f, paint);
+                w += widths[i];
+            }
+        }
+    }
+
+private:
+    SkAutoTUnref<SkTypeface> fProp;
+    SkScalar fStrokeWidth;
+    SkPaint::Style fStrokeStyle;
+
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* GlyphPosHairlineStrokeAndFillFactory(void*) {
+    return new GlyphPosGM(0.0f, SkPaint::kStrokeAndFill_Style);
+}
+static GM* GlyphPosStrokeAndFillFactory(void*) {
+    return new GlyphPosGM(1.2f, SkPaint::kStrokeAndFill_Style);
+}
+static GM* GlyphPosHairlineStrokeFactory(void*) {
+    return new GlyphPosGM(0.0f, SkPaint::kStroke_Style);
+}
+static GM* GlyphPosStrokeFactory(void*) {
+    return new GlyphPosGM(1.2f, SkPaint::kStroke_Style);
+}
+static GM* GlyphPosHairlineFillFactory(void*) {
+    return new GlyphPosGM(0.0f, SkPaint::kFill_Style);
+}
+static GM* GlyphPosFillFactory(void*) {
+    return new GlyphPosGM(1.2f, SkPaint::kFill_Style);
+}
+
+static GMRegistry reg1(GlyphPosHairlineStrokeAndFillFactory);
+static GMRegistry reg2(GlyphPosStrokeAndFillFactory);
+static GMRegistry reg3(GlyphPosHairlineStrokeFactory);
+static GMRegistry reg4(GlyphPosStrokeFactory);
+static GMRegistry reg5(GlyphPosHairlineFillFactory);
+static GMRegistry reg6(GlyphPosFillFactory);
+
+
+}
diff --git a/gm/glyph_pos_align.cpp b/gm/glyph_pos_align.cpp
new file mode 100644
index 0000000..9a94e75
--- /dev/null
+++ b/gm/glyph_pos_align.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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 "gm.h"
+#include "SkCanvas.h"
+#include "SkGradientShader.h"
+
+/**
+ * This test exercises drawPosTextH and drawPosText with every text align.
+ */
+static const int kWidth = 480;
+static const int kHeight = 600;
+static const SkScalar kTextHeight = 64.0f;
+static const int kMaxStringLength = 12;
+
+namespace skiagm {
+
+class GlyphPosAlignGM : public GM {
+protected:
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("glyph_pos_align");
+    }
+
+    virtual SkISize onISize() { return SkISize::Make(kWidth, kHeight); }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        canvas->clear(SK_ColorBLACK);
+
+        SkPaint paint;
+        paint.setTextSize(kTextHeight);
+        paint.setFakeBoldText(true);
+        const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
+        const SkPoint pts[] = {{0, 0}, {kWidth, kHeight}};
+        SkAutoTUnref<SkShader> grad(SkGradientShader::CreateLinear(pts, colors, NULL,
+                                                                   SK_ARRAY_COUNT(colors),
+                                                                   SkShader::kMirror_TileMode));
+        paint.setShader(grad);
+
+
+        paint.setTextAlign(SkPaint::kRight_Align);
+        drawTestCase(canvas, "Right Align", kTextHeight, paint);
+
+        paint.setTextAlign(SkPaint::kCenter_Align);
+        drawTestCase(canvas, "Center Align", 4 * kTextHeight, paint);
+
+        paint.setTextAlign(SkPaint::kLeft_Align);
+        drawTestCase(canvas, "Left Align", 7 * kTextHeight, paint);
+    }
+
+    void drawTestCase(SkCanvas* canvas, const char* text, SkScalar y, const SkPaint& paint) {
+        SkScalar widths[kMaxStringLength];
+        SkScalar posX[kMaxStringLength];
+        SkPoint pos[kMaxStringLength];
+        int length = strlen(text);
+        SkASSERT(length <= kMaxStringLength);
+
+        paint.getTextWidths(text, length, widths);
+
+        float originX;
+        switch (paint.getTextAlign()) {
+            case SkPaint::kRight_Align: originX = 1; break;
+            case SkPaint::kCenter_Align: originX = 0.5f; break;
+            case SkPaint::kLeft_Align: originX = 0; break;
+            default: SkFAIL("Invalid paint origin"); return;
+        }
+
+        float x = kTextHeight;
+        for (int i = 0; i < length; ++i) {
+            posX[i] = x + originX * widths[i];
+            pos[i].set(posX[i], i ? pos[i - 1].y() + 3 : y + kTextHeight);
+            x += widths[i];
+        }
+
+        canvas->drawPosTextH(text, length, posX, y, paint);
+        canvas->drawPosText(text, length, pos, paint);
+    }
+
+private:
+
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* GlyphPosAlignFactory(void*) {
+    return new GlyphPosAlignGM();
+}
+
+static GMRegistry reg(GlyphPosAlignFactory);
+
+}
diff --git a/gm/gm.h b/gm/gm.h
index 70a9025..e48f772 100644
--- a/gm/gm.h
+++ b/gm/gm.h
@@ -14,6 +14,7 @@
 #include "SkSize.h"
 #include "SkString.h"
 #include "SkTRegistry.h"
+#include "sk_tool_utils.h"
 
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
@@ -44,6 +45,8 @@
             kGPUOnly_Flag               = 1 << 9,
 
             kAsBench_Flag               = 1 << 10, // Run the GM as a benchmark in the bench tool
+
+            kNoBBH_Flag                 = 1 << 11, // May draw wrong using a bounding-box hierarchy
         };
 
         enum Mode {
diff --git a/gm/gm_expectations.cpp b/gm/gm_expectations.cpp
index 7089070..db6abdf 100644
--- a/gm/gm_expectations.cpp
+++ b/gm/gm_expectations.cpp
@@ -194,7 +194,7 @@
     // IndividualImageExpectationsSource class...
 
     Expectations IndividualImageExpectationsSource::get(const char *testName) const {
-        SkString path = SkOSPath::SkPathJoin(fRootDir.c_str(), testName);
+        SkString path = SkOSPath::Join(fRootDir.c_str(), testName);
         SkBitmap referenceBitmap;
         bool decodedReferenceBitmap =
             SkImageDecoder::DecodeFile(path.c_str(), &referenceBitmap, kN32_SkColorType,
diff --git a/gm/gm_json.py b/gm/gm_json.py
index 3f43b34..109bba3 100644
--- a/gm/gm_json.py
+++ b/gm/gm_json.py
@@ -48,6 +48,11 @@
 JSONKEY_ACTUALRESULTS_SUCCEEDED = 'succeeded'
 
 
+# Descriptions of the result set as a whole.
+JSONKEY_DESCRIPTIONS = 'descriptions'
+JSONKEY_DESCRIPTIONS_BUILDER = 'builder'
+JSONKEY_DESCRIPTIONS_RENDER_MODE = 'renderMode'
+
 JSONKEY_EXPECTEDRESULTS = 'expected-results'
 
 # One or more [HashType/DigestValue] pairs representing valid results for this
@@ -89,6 +94,7 @@
 JSONKEY_IMAGE_FILEPATH = 'filepath'
 JSONKEY_SOURCE_TILEDIMAGES = 'tiled-images'
 JSONKEY_SOURCE_WHOLEIMAGE = 'whole-image'
+JSONKEY_IMAGE_BASE_GS_URL = 'image-base-gs-url'
 
 
 # Root directory where the buildbots store their actually-generated images...
@@ -163,11 +169,14 @@
 
 def LoadFromString(file_contents):
   """Loads the JSON summary written out by the GM tool.
+
      Returns a dictionary keyed by the values listed as JSONKEY_ constants
-     above."""
+     above; if file_contents is empty, returns None."""
   # TODO(epoger): we should add a version number to the JSON file to ensure
   # that the writer and reader agree on the schema (raising an exception
   # otherwise).
+  if not file_contents:
+    return None
   json_dict = json.loads(file_contents)
   return json_dict
 
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 364e771..94df02c 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -18,6 +18,7 @@
 #include "gm_expectations.h"
 #include "system_preferences.h"
 #include "CrashHandler.h"
+#include "ProcStats.h"
 #include "Resources.h"
 #include "SamplePipeControllers.h"
 #include "SkBitmap.h"
@@ -67,6 +68,7 @@
 class GrContext;
 class GrSurface;
 typedef int GLContextType;
+typedef int GrGLStandard;
 #endif
 
 #define DEBUGFAIL_SEE_STDERR SkDEBUGFAIL("see stderr for message")
@@ -140,7 +142,6 @@
     kNone_BbhType,
     kRTree_BbhType,
     kTileGrid_BbhType,
-    kQuadTree_BbhType
 };
 
 enum ConfigFlags {
@@ -236,7 +237,7 @@
         filename.append(renderModeDescriptor);
         filename.appendUnichar('.');
         filename.append(suffix);
-        return SkOSPath::SkPathJoin(path, filename.c_str());
+        return SkOSPath::Join(path, filename.c_str());
     }
 
     /**
@@ -256,7 +257,7 @@
             filename.append(bitmapDigest.getDigestValue());
             filename.appendUnichar('.');
             filename.append(kPNG_FileExtension);
-            return SkOSPath::SkPathJoin(path, filename.c_str());
+            return SkOSPath::Join(path, filename.c_str());
         } else {
             return make_filename(path, shortName, configName, renderModeDescriptor,
                                  kPNG_FileExtension);
@@ -632,7 +633,7 @@
                     mat.postTranslate(SkIntToScalar(-xTile*tileSize.width()),
                                       SkIntToScalar(-yTile*tileSize.height()));
                     tileCanvas.setMatrix(mat);
-                    pict->draw(&tileCanvas);
+                    pict->playback(&tileCanvas);
                     tileCanvas.flush();
                     tileCanvas.restoreToCount(saveCount);
                     bmpCanvas.drawBitmap(tileBM,
@@ -848,7 +849,7 @@
             // If we have access to a single expected bitmap, log more
             // detail about the mismatch.
             const SkBitmap *expectedBitmapPtr = expectations.asBitmap();
-            if (NULL != expectedBitmapPtr) {
+            if (expectedBitmapPtr) {
                 report_bitmap_diffs(*expectedBitmapPtr, actualBitmapAndDigest.fBitmap,
                                     completeName);
             }
@@ -1010,8 +1011,8 @@
 
     static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t recordFlags,
                                            SkScalar scale = SK_Scalar1) {
-        int width = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().width()), scale));
-        int height = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().height()), scale));
+        SkScalar width = SkScalarMul(SkIntToScalar(gm->getISize().width()), scale);
+        SkScalar height = SkScalarMul(SkIntToScalar(gm->getISize().height()), scale);
 
         SkAutoTDelete<SkBBHFactory> factory;
         if (kTileGrid_BbhType == bbhType) {
@@ -1020,8 +1021,6 @@
             info.fOffset.setZero();
             info.fTileInterval.set(16, 16);
             factory.reset(SkNEW_ARGS(SkTileGridFactory, (info)));
-        } else if (kQuadTree_BbhType == bbhType) {
-            factory.reset(SkNEW(SkQuadTreeFactory));
         } else if (kRTree_BbhType == bbhType) {
             factory.reset(SkNEW(SkRTreeFactory));
         }
@@ -1335,6 +1334,10 @@
 
 static const char kDefaultsConfigStr[] = "defaults";
 static const char kExcludeConfigChar = '~';
+#if SK_SUPPORT_GPU
+static const char kGpuAPINameGL[] = "gl";
+static const char kGpuAPINameGLES[] = "gles";
+#endif
 
 static SkString configUsage() {
     SkString result;
@@ -1418,15 +1421,23 @@
 
 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath").
 DEFINE_string(config, "", configUsage().c_str());
+DEFINE_bool(cpu, true, "Allows non-GPU configs to be run. Applied after --config.");
 DEFINE_string(pdfRasterizers, "default", pdfRasterizerUsage().c_str());
 DEFINE_bool(deferred, false, "Exercise the deferred rendering test pass.");
 DEFINE_bool(dryRun, false, "Don't actually run the tests, just print what would have been done.");
 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip.");
 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing.");
 #if SK_SUPPORT_GPU
+DEFINE_string(gpuAPI, "", "Force use of specific gpu API.  Using \"gl\" "
+              "forces OpenGL API. Using \"gles\" forces OpenGL ES API. "
+              "Defaults to empty string, which selects the API native to the "
+              "system.");
 DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte size or "
               "object count. " TOSTRING(DEFAULT_CACHE_VALUE) " for either value means "
               "use the default. 0 for either disables the cache.");
+DEFINE_bool(gpu, true, "Allows GPU configs to be run. Applied after --config.");
+DEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to "
+                                          "software path rendering.");
 #endif
 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure "
             "when reading/writing files.");
@@ -1452,7 +1463,6 @@
 DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for which "
               "testIndex %% divisor == remainder.");
 DEFINE_bool(pipe, false, "Exercise the SkGPipe replay test pass.");
-DEFINE_bool(quadtree, false, "Exercise the QuadTree variant of SkPicture test pass.");
 DEFINE_string2(readPath, r, "", "Read reference images from this dir, and report "
                "any differences between those and the newly generated ones.");
 DEFINE_bool(replay, false, "Exercise the SkPicture replay test pass.");
@@ -1625,23 +1635,6 @@
         }
     }
 
-    if (FLAGS_quadtree) {
-        const char renderModeDescriptor[] = "-quadtree";
-        if ((gmFlags & GM::kSkipPicture_Flag) || (gmFlags & GM::kSkipTiled_Flag)) {
-            gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
-                                     renderModeDescriptor);
-            errorsForAllModes.add(kIntentionallySkipped_ErrorType);
-        } else {
-            SkPicture* pict = gmmain.generate_new_picture(gm, kQuadTree_BbhType, 0);
-            SkAutoUnref aur(pict);
-            SkBitmap bitmap;
-            gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap);
-            errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
-                gm->getName(), compareConfig.fName, renderModeDescriptor, bitmap,
-                &comparisonBitmap));
-        }
-    }
-
     if (FLAGS_tileGrid) {
         for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); ++scaleIndex) {
             SkScalar replayScale = tileGridReplayScales[scaleIndex];
@@ -1701,12 +1694,14 @@
                                       const SkTDArray<size_t> &configs,
                                       const SkTDArray<const PDFRasterizerData*> &pdfRasterizers,
                                       const SkTDArray<SkScalar> &tileGridReplayScales,
-                                      GrContextFactory *grFactory);
+                                      GrContextFactory *grFactory,
+                                      GrGLStandard gpuAPI);
 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm,
                                       const SkTDArray<size_t> &configs,
                                       const SkTDArray<const PDFRasterizerData*> &pdfRasterizers,
                                       const SkTDArray<SkScalar> &tileGridReplayScales,
-                                      GrContextFactory *grFactory) {
+                                      GrContextFactory *grFactory,
+                                      GrGLStandard gpuAPI) {
     const char renderModeDescriptor[] = "";
     ErrorCombination errorsForAllConfigs;
     uint32_t gmFlags = gm->getFlags();
@@ -1756,7 +1751,7 @@
             if (FLAGS_resetGpuContext) {
                 grFactory->destroyContexts();
             }
-            GrContext* gr = grFactory->get(config.fGLContextType);
+            GrContext* gr = grFactory->get(config.fGLContextType, gpuAPI);
             bool grSuccess = false;
             if (gr) {
                 // create a render target to back the device
@@ -1767,7 +1762,7 @@
                 desc.fHeight = gm->getISize().height();
                 desc.fSampleCnt = config.fSampleCnt;
                 auGpuTarget.reset(gr->createUncachedTexture(desc, NULL, 0));
-                if (NULL != auGpuTarget) {
+                if (auGpuTarget) {
                     gpuTarget = auGpuTarget;
                     grSuccess = true;
                     // Set the user specified cache limits if non-default.
@@ -1927,7 +1922,7 @@
 }
 
 static bool parse_flags_configs(SkTDArray<size_t>* outConfigs,
-                         GrContextFactory* grFactory) {
+                         GrContextFactory* grFactory, GrGLStandard gpuAPI) {
     SkTDArray<size_t> excludeConfigs;
 
     for (int i = 0; i < FLAGS_config.count(); i++) {
@@ -1989,12 +1984,25 @@
         }
     }
 
-#if SK_SUPPORT_GPU
-    SkASSERT(grFactory != NULL);
     for (int i = 0; i < outConfigs->count(); ++i) {
         size_t index = (*outConfigs)[i];
         if (kGPU_Backend == gRec[index].fBackend) {
-            GrContext* ctx = grFactory->get(gRec[index].fGLContextType);
+#if SK_SUPPORT_GPU
+            if (!FLAGS_gpu) {
+                outConfigs->remove(i);
+                --i;
+                continue;
+            }
+#endif
+        } else if (!FLAGS_cpu) {
+            outConfigs->remove(i);
+            --i;
+            continue;
+        }
+#if SK_SUPPORT_GPU
+        SkASSERT(grFactory != NULL);
+        if (kGPU_Backend == gRec[index].fBackend) {
+            GrContext* ctx = grFactory->get(gRec[index].fGLContextType, gpuAPI);
             if (NULL == ctx) {
                 SkDebugf("GrContext could not be created for config %s. Config will be skipped.\n",
                          gRec[index].fName);
@@ -2010,8 +2018,8 @@
                 --i;
             }
         }
-    }
 #endif
+    }
 
     if (outConfigs->isEmpty()) {
         SkDebugf("No configs to run.");
@@ -2148,6 +2156,25 @@
     }
     return true;
 }
+
+static bool parse_flags_gl_standard(GrGLStandard* gpuAPI) {
+    if (0 == FLAGS_gpuAPI.count()) {
+        *gpuAPI = kNone_GrGLStandard;
+        return true;
+    }
+    if (1 == FLAGS_gpuAPI.count()) {
+        if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
+            *gpuAPI = kGL_GrGLStandard;
+            return true;
+        }
+        if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
+            *gpuAPI = kGLES_GrGLStandard;
+            return true;
+        }
+    }
+    SkDebugf("--gpuAPI invalid api value");
+    return false;
+}
 #endif
 
 static bool parse_flags_tile_grid_replay_scales(SkTDArray<SkScalar>* outScales) {
@@ -2238,8 +2265,12 @@
     SkTDArray<const PDFRasterizerData*> pdfRasterizers;
     SkTDArray<SkScalar> tileGridReplayScales;
 #if SK_SUPPORT_GPU
-    GrContextFactory* grFactory = new GrContextFactory;
+    GrGLStandard gpuAPI = kNone_GrGLStandard;
+    GrContext::Options grContextOpts;
+    grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks;
+    GrContextFactory* grFactory = new GrContextFactory(grContextOpts);
 #else
+    GrGLStandard gpuAPI = 0;
     GrContextFactory* grFactory = NULL;
 #endif
 
@@ -2252,10 +2283,11 @@
         !parse_flags_ignore_tests(gmmain.fIgnorableTestNames) ||
 #if SK_SUPPORT_GPU
         !parse_flags_gpu_cache(&gGpuCacheSizeBytes, &gGpuCacheSizeCount) ||
+        !parse_flags_gl_standard(&gpuAPI) ||
 #endif
         !parse_flags_tile_grid_replay_scales(&tileGridReplayScales) ||
         !parse_flags_jpeg_quality() ||
-        !parse_flags_configs(&configs, grFactory) ||
+        !parse_flags_configs(&configs, grFactory, gpuAPI) ||
         !parse_flags_pdf_rasterizers(configs, &pdfRasterizers) ||
         !parse_flags_gmmain_paths(&gmmain)) {
         return -1;
@@ -2265,10 +2297,10 @@
         if (FLAGS_writePath.count() == 1) {
             SkDebugf("writing to %s\n", FLAGS_writePath[0]);
         }
-        if (NULL != gmmain.fMismatchPath) {
+        if (gmmain.fMismatchPath) {
             SkDebugf("writing mismatches to %s\n", gmmain.fMismatchPath);
         }
-        if (NULL != gmmain.fMissingExpectationsPath) {
+        if (gmmain.fMissingExpectationsPath) {
             SkDebugf("writing images without expectations to %s\n",
                      gmmain.fMissingExpectationsPath);
         }
@@ -2292,13 +2324,13 @@
                 return -1;
             }
         }
-        if (NULL != gmmain.fMismatchPath) {
+        if (gmmain.fMismatchPath) {
             if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarchy,
                                         configs, pdfRasterizers)) {
                 return -1;
             }
         }
-        if (NULL != gmmain.fMissingExpectationsPath) {
+        if (gmmain.fMissingExpectationsPath) {
             if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUseFileHierarchy,
                                         configs, pdfRasterizers)) {
                 return -1;
@@ -2334,10 +2366,12 @@
 
         gmsRun++;
         SkISize size = gm->getISize();
-        SkDebugf("%sdrawing... %s [%d %d]\n", moduloStr.c_str(), shortName,
+        SkDebugf("%4dM %sdrawing... %s [%d %d]\n",
+                 sk_tools::getMaxResidentSetSizeMB(), moduloStr.c_str(), shortName,
                  size.width(), size.height());
         if (!FLAGS_dryRun)
-            run_multiple_configs(gmmain, gm, configs, pdfRasterizers, tileGridReplayScales, grFactory);
+            run_multiple_configs(gmmain, gm, configs, pdfRasterizers, tileGridReplayScales,
+                                 grFactory, gpuAPI);
     }
 
     if (FLAGS_dryRun)
@@ -2414,7 +2448,7 @@
         ConfigData config = gRec[configs[i]];
 
         if (FLAGS_verbose && (kGPU_Backend == config.fBackend)) {
-            GrContext* gr = grFactory->get(config.fGLContextType);
+            GrContext* gr = grFactory->get(config.fGLContextType, gpuAPI);
 
             SkDebugf("config: %s %x\n", config.fName, gr);
             gr->printCacheStats();
@@ -2427,7 +2461,7 @@
         ConfigData config = gRec[configs[i]];
 
         if (kGPU_Backend == config.fBackend) {
-            GrContext* gr = grFactory->get(config.fGLContextType);
+            GrContext* gr = grFactory->get(config.fGLContextType, gpuAPI);
 
            gr->dumpFontCache();
         }
diff --git a/gm/gradientDirtyLaundry.cpp b/gm/gradientDirtyLaundry.cpp
index ea41203..a452763 100644
--- a/gm/gradientDirtyLaundry.cpp
+++ b/gm/gradientDirtyLaundry.cpp
@@ -70,10 +70,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     SkString onShortName() SK_OVERRIDE { return SkString("gradient_dirty_laundry"); }
     virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(640, 615); }
 
diff --git a/gm/gradients.cpp b/gm/gradients.cpp
index 277033b..fd02cee 100644
--- a/gm/gradients.cpp
+++ b/gm/gradients.cpp
@@ -295,10 +295,6 @@
     ClampedGradientsGM() {}
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     SkString onShortName() { return SkString("clamped_gradients"); }
 
     virtual SkISize onISize() { return SkISize::Make(640, 510); }
diff --git a/gm/gradients_2pt_conical.cpp b/gm/gradients_2pt_conical.cpp
index 5a6cec2..f43356e 100644
--- a/gm/gradients_2pt_conical.cpp
+++ b/gm/gradients_2pt_conical.cpp
@@ -312,13 +312,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        if (fGradCaseType != kInside_GradCaseType) {
-            return kSkipTiled_Flag;
-        }
-        return 0;
-    }
-
     SkString onShortName() {
         return fName;
     }
diff --git a/gm/gradtext.cpp b/gm/gradtext.cpp
index 5fac185..96ce59f 100644
--- a/gm/gradtext.cpp
+++ b/gm/gradtext.cpp
@@ -47,6 +47,7 @@
     virtual SkISize onISize() { return SkISize::Make(500, 480); }
     virtual void onDraw(SkCanvas* canvas) {
         SkPaint paint;
+        sk_tool_utils::set_portable_typeface(&paint);
         SkRect r = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
 
         canvas->clipRect(r);
@@ -75,6 +76,7 @@
     virtual SkISize onISize() { return SkISize::Make(500, 480); }
     virtual void onDraw(SkCanvas* canvas) {
         SkPaint paint;
+        sk_tool_utils::set_portable_typeface(&paint);
 
         paint.setStyle(SkPaint::kFill_Style);
         canvas->drawText("Normal Fill Text", 16, 0, 50, paint);
@@ -100,11 +102,6 @@
     GradTextGM () {}
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
-
     virtual SkString onShortName() {
         return SkString("gradtext");
     }
@@ -132,6 +129,7 @@
 
     virtual void onDraw(SkCanvas* canvas) {
         SkPaint paint;
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setTextSize(SkIntToScalar(26));
 
         const SkISize& size = this->getISize();
diff --git a/gm/image.cpp b/gm/image.cpp
index 88c1db5..05a3fab 100644
--- a/gm/image.cpp
+++ b/gm/image.cpp
@@ -8,6 +8,7 @@
 #include "gm.h"
 #include "SkSurface.h"
 #include "SkCanvas.h"
+#include "SkDecodingImageGenerator.h"
 #include "SkStream.h"
 #include "SkData.h"
 
@@ -15,28 +16,21 @@
 #include "GrContext.h"
 #endif
 
-static SkData* fileToData(const char path[]) {
-    SkFILEStream stream(path);
-    if (!stream.isValid()) {
-        return SkData::NewEmpty();
-    }
-    size_t size = stream.getLength();
-    void* mem = sk_malloc_throw(size);
-    stream.read(mem, size);
-    return SkData::NewFromMalloc(mem, size);
-}
-
 static void drawJpeg(SkCanvas* canvas, const SkISize& size) {
     // TODO: Make this draw a file that is checked in, so it can
     // be exercised on machines other than mike's. Will require a
     // rebaseline.
-    SkAutoDataUnref data(fileToData("/Users/mike/Downloads/skia.google.jpeg"));
-    SkImage* image = SkImage::NewEncodedData(data);
+    SkAutoDataUnref data(SkData::NewFromFileName("/Users/mike/Downloads/skia.google.jpeg"));
+    if (NULL == data.get()) {
+        return;
+    }
+    SkImage* image = SkImage::NewFromGenerator(
+                SkDecodingImageGenerator::Create(data, SkDecodingImageGenerator::Options()));
     if (image) {
         SkAutoCanvasRestore acr(canvas, true);
         canvas->scale(size.width() * 1.0f / image->width(),
                       size.height() * 1.0f / image->height());
-        image->draw(canvas, 0, 0, NULL);
+        canvas->drawImage(image, 0, 0, NULL);
         image->unref();
     }
 }
@@ -83,8 +77,8 @@
 //    paint.setFilterBitmap(true);
 //    paint.setAlpha(0x80);
 
-    imgR->draw(canvas, 0, 0, usePaint ? &paint : NULL);
-    imgG->draw(canvas, 0, 80, usePaint ? &paint : NULL);
+    canvas->drawImage(imgR, 0, 0, usePaint ? &paint : NULL);
+    canvas->drawImage(imgG, 0, 80, usePaint ? &paint : NULL);
     surf->draw(canvas, 0, 160, usePaint ? &paint : NULL);
 
     SkRect src1, src2, src3;
@@ -99,10 +93,10 @@
     dst3.set(0, 400, 65, 465);
     dst4.set(0, 480, 65, 545);
 
-    imgR->draw(canvas, &src1, dst1, usePaint ? &paint : NULL);
-    imgG->draw(canvas, &src2, dst2, usePaint ? &paint : NULL);
-    imgR->draw(canvas, &src3, dst3, usePaint ? &paint : NULL);
-    imgG->draw(canvas, NULL, dst4, usePaint ? &paint : NULL);
+    canvas->drawImageRect(imgR, &src1, dst1, usePaint ? &paint : NULL);
+    canvas->drawImageRect(imgG, &src2, dst2, usePaint ? &paint : NULL);
+    canvas->drawImageRect(imgR, &src3, dst3, usePaint ? &paint : NULL);
+    canvas->drawImageRect(imgG, NULL, dst4, usePaint ? &paint : NULL);
 
     imgG->unref();
     imgR->unref();
@@ -158,6 +152,7 @@
 
         SkPaint textPaint;
         textPaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&textPaint);
         textPaint.setTextSize(8);
 
         canvas->drawText(kLabel1, strlen(kLabel1), 10,  60, textPaint);
@@ -184,14 +179,14 @@
 #if SK_SUPPORT_GPU
         GrContext* ctx = canvas->getGrContext();
 
-        SkAutoTUnref<SkSurface> surf4(SkSurface::NewRenderTarget(ctx, info, 0));
+        SkAutoTUnref<SkSurface> surf4(SkSurface::NewRenderTarget(ctx, info));
 #endif
 
         test_surface(canvas, surf0, true);
         canvas->translate(80, 0);
         test_surface(canvas, surf1, true);
 #if SK_SUPPORT_GPU
-        if (NULL != ctx) {
+        if (ctx) {
             canvas->translate(80, 0);
             test_surface(canvas, surf4, true);
         }
diff --git a/gm/imageblur.cpp b/gm/imageblur.cpp
index b8e1971..2e85678 100644
--- a/gm/imageblur.cpp
+++ b/gm/imageblur.cpp
@@ -44,6 +44,7 @@
         SkRandom rand;
         SkPaint textPaint;
         textPaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&textPaint);
         for (int i = 0; i < 25; ++i) {
             int x = rand.nextULessThan(WIDTH);
             int y = rand.nextULessThan(HEIGHT);
diff --git a/gm/imageblur2.cpp b/gm/imageblur2.cpp
new file mode 100644
index 0000000..b7c9f9d
--- /dev/null
+++ b/gm/imageblur2.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkBlurImageFilter.h"
+#include "SkRandom.h"
+
+// TODO deprecate imageblur
+
+#define WIDTH 500
+#define HEIGHT 500
+
+static const float kBlurSigmas[] = {
+        0.0, 0.3f, 0.5f, 2.0f, 32.0f, 80.0f };
+
+const char* kTestStrings[] = {
+        "The quick`~",
+        "brown fox[]",
+        "jumped over",
+        "the lazy@#$",
+        "dog.{}!%^&",
+        "*()+=-\\'\"/",
+};
+
+namespace skiagm {
+
+class BlurImageFilter : public GM {
+public:
+    BlurImageFilter() {
+        this->setBGColor(0xFFFFFFFF);
+        fName.printf("imageblur2");
+    }
+
+protected:
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+
+    virtual SkString onShortName() {
+        return fName;
+    }
+
+    virtual SkISize onISize() {
+        return SkISize::Make(WIDTH, HEIGHT);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) {
+        const int sigmaCount = SK_ARRAY_COUNT(kBlurSigmas);
+        const int testStringCount = SK_ARRAY_COUNT(kTestStrings);
+        SkScalar dx = WIDTH / sigmaCount;
+        SkScalar dy = HEIGHT / sigmaCount;
+        const SkScalar textSize = 12;
+
+        for (int x = 0; x < sigmaCount; x++) {
+            SkScalar sigmaX = kBlurSigmas[x];
+            for (int y = 0; y < sigmaCount; y++) {
+                SkScalar sigmaY = kBlurSigmas[y];
+
+                SkPaint paint;
+                paint.setImageFilter(SkBlurImageFilter::Create(sigmaX, sigmaY))->unref();
+                canvas->saveLayer(NULL, &paint);
+
+                SkRandom rand;
+                SkPaint textPaint;
+                textPaint.setAntiAlias(false);
+                textPaint.setColor(rand.nextBits(24) | 0xFF000000);
+                textPaint.setTextSize(textSize);
+
+                for (int i = 0; i < testStringCount; i++) {
+                    canvas->drawText(kTestStrings[i],
+                                     strlen(kTestStrings[i]),
+                                     SkIntToScalar(x * dx),
+                                     SkIntToScalar(y * dy + textSize * i + textSize),
+                                     textPaint);
+                }
+                canvas->restore();
+            }
+        }
+    }
+
+private:
+    SkString fName;
+
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new BlurImageFilter; }
+static GMRegistry reg(MyFactory);
+
+}
diff --git a/gm/imageblurtiled.cpp b/gm/imageblurtiled.cpp
index 0580405..ed4ae6c 100644
--- a/gm/imageblurtiled.cpp
+++ b/gm/imageblurtiled.cpp
@@ -50,6 +50,7 @@
                 };
                 SkPaint textPaint;
                 textPaint.setAntiAlias(true);
+                sk_tool_utils::set_portable_typeface(&textPaint);
                 textPaint.setTextSize(SkIntToScalar(100));
                 int posY = 0;
                 for (unsigned i = 0; i < SK_ARRAY_COUNT(str); i++) {
diff --git a/gm/imagefiltersbase.cpp b/gm/imagefiltersbase.cpp
index 4779c81..d1bd5a7 100644
--- a/gm/imagefiltersbase.cpp
+++ b/gm/imagefiltersbase.cpp
@@ -18,39 +18,69 @@
 
 class FailImageFilter : public SkImageFilter {
 public:
+    class Registrar {
+    public:
+        Registrar() {
+            SkFlattenable::Register("FailImageFilter",
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+                                    FailImageFilter::DeepCreateProc,
+#else
+                                    FailImageFilter::CreateProc,
+#endif
+                                    FailImageFilter::GetFlattenableType());
+        }
+    };
     static FailImageFilter* Create() {
         return SkNEW(FailImageFilter);
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
+
 protected:
-    FailImageFilter() : INHERITED(0) {}
+    FailImageFilter() : INHERITED(0, NULL) {}
+
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
         return false;
     }
 
-    FailImageFilter(SkReadBuffer& buffer)
-      : INHERITED(1, buffer) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    FailImageFilter(SkReadBuffer& buffer) : INHERITED(0, buffer) {}
+#endif
 
 private:
     typedef SkImageFilter INHERITED;
 };
 
-// register the filter with the flattenable registry
-static SkFlattenable::Registrar gFailImageFilterReg("FailImageFilter",
-                                                    FailImageFilter::CreateProc,
-                                                    FailImageFilter::GetFlattenableType());
+static FailImageFilter::Registrar gReg0;
+
+SkFlattenable* FailImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
+    return FailImageFilter::Create();
+}
 
 class IdentityImageFilter : public SkImageFilter {
 public:
-    static IdentityImageFilter* Create() {
-        return SkNEW(IdentityImageFilter);
+    class Registrar {
+    public:
+        Registrar() {
+            SkFlattenable::Register("IdentityImageFilter",
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+                                    IdentityImageFilter::DeepCreateProc,
+#else
+                                    IdentityImageFilter::CreateProc,
+#endif
+                                    IdentityImageFilter::GetFlattenableType());
+        }
+    };
+    static IdentityImageFilter* Create(SkImageFilter* input = NULL) {
+        return SkNEW_ARGS(IdentityImageFilter, (input));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(IdentityImageFilter)
 protected:
-    IdentityImageFilter() : INHERITED(0) {}
+    IdentityImageFilter(SkImageFilter* input) : INHERITED(1, &input) {}
+
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
         *result = src;
@@ -58,18 +88,20 @@
         return true;
     }
 
-    IdentityImageFilter(SkReadBuffer& buffer)
-      : INHERITED(1, buffer) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    IdentityImageFilter(SkReadBuffer& buffer) : INHERITED(1, buffer) {}
+#endif
 
 private:
     typedef SkImageFilter INHERITED;
 };
 
-// register the filter with the flattenable registry
-static SkFlattenable::Registrar gIdentityImageFilterReg("IdentityImageFilter",
-                                                        IdentityImageFilter::CreateProc,
-                                                        IdentityImageFilter::GetFlattenableType());
+static IdentityImageFilter::Registrar gReg1;
 
+SkFlattenable* IdentityImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    return IdentityImageFilter::Create(common.getInput(0));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -113,6 +145,7 @@
     paint.setImageFilter(imf);
     paint.setColor(SK_ColorCYAN);
     paint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&paint);
     paint.setTextSize(r.height()/2);
     paint.setTextAlign(SkPaint::kCenter_Align);
     canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint);
@@ -198,7 +231,7 @@
             FailImageFilter::Create(),
             SkColorFilterImageFilter::Create(cf),
             SkBlurImageFilter::Create(12.0f, 0.0f),
-            SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, SK_ColorBLUE),
+            SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE),
         };
         cf->unref();
 
diff --git a/gm/imagefiltersclipped.cpp b/gm/imagefiltersclipped.cpp
index ec031c9..e836e40 100644
--- a/gm/imagefiltersclipped.cpp
+++ b/gm/imagefiltersclipped.cpp
@@ -100,7 +100,8 @@
 
         SkImageFilter* filters[] = {
             SkBlurImageFilter::Create(SkIntToScalar(12), SkIntToScalar(12)),
-            SkDropShadowImageFilter::Create(SkIntToScalar(10), SkIntToScalar(10), SkIntToScalar(3),
+            SkDropShadowImageFilter::Create(SkIntToScalar(10), SkIntToScalar(10),
+                                            SkIntToScalar(3), SkIntToScalar(3),
                                             SK_ColorGREEN),
             SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
                                             SkDisplacementMapEffect::kR_ChannelSelectorType,
diff --git a/gm/imagefilterscropped.cpp b/gm/imagefilterscropped.cpp
index a128c6b..e7d3790 100644
--- a/gm/imagefilterscropped.cpp
+++ b/gm/imagefilterscropped.cpp
@@ -45,6 +45,7 @@
     paint.setImageFilter(imf);
     paint.setColor(SK_ColorGREEN);
     paint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&paint);
     paint.setTextSize(r.height()/2);
     paint.setTextAlign(SkPaint::kCenter_Align);
     canvas->save();
diff --git a/gm/imagefiltersgraph.cpp b/gm/imagefiltersgraph.cpp
index ec6559f..8af268e 100644
--- a/gm/imagefiltersgraph.cpp
+++ b/gm/imagefiltersgraph.cpp
@@ -25,6 +25,18 @@
 // perform a draw and this one does.
 class SimpleOffsetFilter : public SkImageFilter {
 public:
+    class Registrar {
+    public:
+        Registrar() {
+            SkFlattenable::Register("SimpleOffsetFilter",
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+                                    SimpleOffsetFilter::DeepCreateProc,
+#else
+                                    SimpleOffsetFilter::CreateProc,
+#endif
+                                    SimpleOffsetFilter::GetFlattenableType());
+        }
+    };
     static SkImageFilter* Create(SkScalar dx, SkScalar dy, SkImageFilter* input) {
         return SkNEW_ARGS(SimpleOffsetFilter, (dx, dy, input));
     }
@@ -34,7 +46,7 @@
         SkBitmap source = src;
         SkImageFilter* input = getInput(0);
         SkIPoint srcOffset = SkIPoint::Make(0, 0);
-        if (NULL != input && !input->filterImage(proxy, src, ctx, &source, &srcOffset)) {
+        if (input && !input->filterImage(proxy, src, ctx, &source, &srcOffset)) {
             return false;
         }
 
@@ -57,28 +69,37 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SimpleOffsetFilter);
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SimpleOffsetFilter(SkReadBuffer& buffer)
     : SkImageFilter(1, buffer) {
         fDX = buffer.readScalar();
         fDY = buffer.readScalar();
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        this->SkImageFilter::flatten(buffer);
+        this->INHERITED::flatten(buffer);
         buffer.writeScalar(fDX);
         buffer.writeScalar(fDY);
     }
 
 private:
     SimpleOffsetFilter(SkScalar dx, SkScalar dy, SkImageFilter* input)
-    : SkImageFilter(input), fDX(dx), fDY(dy) {}
+        : SkImageFilter(1, &input), fDX(dx), fDY(dy) {}
 
     SkScalar fDX, fDY;
+
+    typedef SkImageFilter INHERITED;
 };
 
-SkFlattenable::Registrar registrar("SimpleOffsetFilter",
-                                   SimpleOffsetFilter::CreateProc,
-                                   SimpleOffsetFilter::GetFlattenableType());
+static SimpleOffsetFilter::Registrar gReg;
+
+SkFlattenable* SimpleOffsetFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkScalar dx = buffer.readScalar();
+    SkScalar dy = buffer.readScalar();
+    return Create(dx, dy, common.getInput(0));
+}
 
 class ImageFiltersGraphGM : public skiagm::GM {
 public:
@@ -99,6 +120,7 @@
         canvas.clear(0x00000000);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xFFFFFFFF);
         paint.setTextSize(SkIntToScalar(96));
         const char* str = "e";
diff --git a/gm/imagefiltersscaled.cpp b/gm/imagefiltersscaled.cpp
index 57552df..cf4dc4e 100644
--- a/gm/imagefiltersscaled.cpp
+++ b/gm/imagefiltersscaled.cpp
@@ -109,7 +109,8 @@
 
         SkImageFilter* filters[] = {
             SkBlurImageFilter::Create(SkIntToScalar(4), SkIntToScalar(4)),
-            SkDropShadowImageFilter::Create(SkIntToScalar(5), SkIntToScalar(10), SkIntToScalar(3),
+            SkDropShadowImageFilter::Create(SkIntToScalar(5), SkIntToScalar(10),
+                                            SkIntToScalar(3), SkIntToScalar(3),
                                             SK_ColorYELLOW),
             SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
                                             SkDisplacementMapEffect::kR_ChannelSelectorType,
diff --git a/gm/imagemagnifier.cpp b/gm/imagemagnifier.cpp
index 23847e6..e2847b4 100644
--- a/gm/imagemagnifier.cpp
+++ b/gm/imagemagnifier.cpp
@@ -44,6 +44,7 @@
                 100))->unref();
         canvas->saveLayer(NULL, &paint);
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         const char* str = "The quick brown fox jumped over the lazy dog.";
         SkRandom rand;
         for (int i = 0; i < 25; ++i) {
diff --git a/gm/imageresizetiled.cpp b/gm/imageresizetiled.cpp
index ff02020..d09fd27 100644
--- a/gm/imageresizetiled.cpp
+++ b/gm/imageresizetiled.cpp
@@ -22,6 +22,8 @@
     }
 
 protected:
+    virtual uint32_t onGetFlags() const SK_OVERRIDE { return kNoBBH_Flag; }
+
     virtual SkString onShortName() SK_OVERRIDE {
         return SkString("imageresizetiled");
     }
@@ -55,6 +57,7 @@
                 };
                 SkPaint textPaint;
                 textPaint.setAntiAlias(true);
+                sk_tool_utils::set_portable_typeface(&textPaint);
                 textPaint.setTextSize(SkIntToScalar(100));
                 int posY = 0;
                 for (unsigned i = 0; i < SK_ARRAY_COUNT(str); i++) {
diff --git a/gm/internal_links.cpp b/gm/internal_links.cpp
index 7e5ce62..3ba3052 100644
--- a/gm/internal_links.cpp
+++ b/gm/internal_links.cpp
@@ -61,6 +61,7 @@
         canvas->drawRect(rect, paint);
 
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setTextSize(SkIntToScalar(25));
         paint.setColor(SK_ColorBLACK);
         canvas->drawText(text, strlen(text), x, y, paint);
diff --git a/gm/lcdtext.cpp b/gm/lcdtext.cpp
index f48dc9e..b4db0ff 100644
--- a/gm/lcdtext.cpp
+++ b/gm/lcdtext.cpp
@@ -49,6 +49,7 @@
         paint.setColor(SK_ColorBLACK);
         paint.setDither(true);
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setSubpixelText(subpixelTextEnabled);
         paint.setLCDRenderText(lcdRenderTextEnabled);
         paint.setTextSize(textHeight);
diff --git a/gm/lerpmode.cpp b/gm/lerpmode.cpp
index 89301ea..30e6abd 100644
--- a/gm/lerpmode.cpp
+++ b/gm/lerpmode.cpp
@@ -39,10 +39,6 @@
     LerpXfermodeGM() {}
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() SK_OVERRIDE {
         return SkString("lerpmode");
     }
diff --git a/gm/lighting.cpp b/gm/lighting.cpp
index 50698fa..e7842a9 100644
--- a/gm/lighting.cpp
+++ b/gm/lighting.cpp
@@ -34,6 +34,7 @@
         canvas.clear(0x00000000);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xFFFFFFFF);
         paint.setTextSize(SkIntToScalar(96));
         const char* str = "e";
diff --git a/gm/linepaths.cpp b/gm/linepaths.cpp
index ea4fdc8..53a9327 100644
--- a/gm/linepaths.cpp
+++ b/gm/linepaths.cpp
@@ -85,6 +85,7 @@
         SkPaint titlePaint;
         titlePaint.setColor(SK_ColorBLACK);
         titlePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&titlePaint);
         titlePaint.setLCDRenderText(true);
         titlePaint.setTextSize(15 * SK_Scalar1);
         const char title[] = "Line Drawn Into Rectangle Clips With "
@@ -129,6 +130,7 @@
                     SkPaint labelPaint;
                     labelPaint.setColor(color);
                     labelPaint.setAntiAlias(true);
+                    sk_tool_utils::set_portable_typeface(&labelPaint);
                     labelPaint.setLCDRenderText(true);
                     labelPaint.setTextSize(10 * SK_Scalar1);
                     canvas->drawText(gStyles[style].fName,
@@ -227,6 +229,7 @@
         SkPaint titlePaint;
         titlePaint.setColor(SK_ColorBLACK);
         titlePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&titlePaint);
         titlePaint.setLCDRenderText(true);
         titlePaint.setTextSize(15 * SK_Scalar1);
         const char title[] = "Line Closed Drawn Into Rectangle Clips With "
@@ -271,6 +274,7 @@
                     SkPaint labelPaint;
                     labelPaint.setColor(color);
                     labelPaint.setAntiAlias(true);
+                    sk_tool_utils::set_portable_typeface(&labelPaint);
                     labelPaint.setLCDRenderText(true);
                     labelPaint.setTextSize(10 * SK_Scalar1);
                     canvas->drawText(gStyles[style].fName,
diff --git a/gm/lumafilter.cpp b/gm/lumafilter.cpp
index 4414093..521a61b 100644
--- a/gm/lumafilter.cpp
+++ b/gm/lumafilter.cpp
@@ -18,6 +18,7 @@
 static void draw_label(SkCanvas* canvas, const char* label,
                        const SkPoint& offset) {
     SkPaint paint;
+    sk_tool_utils::set_portable_typeface(&paint);
     size_t len = strlen(label);
 
     SkScalar width = paint.measureText(label, len);
diff --git a/gm/matrixconvolution.cpp b/gm/matrixconvolution.cpp
index 592489c..aff3850 100644
--- a/gm/matrixconvolution.cpp
+++ b/gm/matrixconvolution.cpp
@@ -33,6 +33,7 @@
         canvas.clear(0x00000000);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xFFFFFFFF);
         paint.setTextSize(SkIntToScalar(180));
         SkPoint pts[2] = { SkPoint::Make(0, 0),
diff --git a/gm/morphology.cpp b/gm/morphology.cpp
index ff6c1ba..cb321c6 100644
--- a/gm/morphology.cpp
+++ b/gm/morphology.cpp
@@ -31,6 +31,7 @@
         canvas.clear(0x0);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         const char* str1 = "ABC";
         const char* str2 = "XYZ";
         paint.setColor(0xFFFFFFFF);
diff --git a/gm/multipicturedraw.cpp b/gm/multipicturedraw.cpp
new file mode 100644
index 0000000..75a4c89
--- /dev/null
+++ b/gm/multipicturedraw.cpp
@@ -0,0 +1,484 @@
+/*
+ * 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 "gm.h"
+
+#include "SkColorFilter.h"
+#include "SkMultiPictureDraw.h"
+#include "SkPictureRecorder.h"
+#include "SkSurface.h"
+
+static const SkScalar kRoot3Over2 = 0.86602545f;  // sin(60)
+static const SkScalar kRoot3      = 1.73205081f;
+
+static const int kHexSide = 30;
+static const int kNumHexX = 6;
+static const int kNumHexY = 6;
+static const int kPicWidth = kNumHexX * kHexSide;
+static const int kPicHeight = SkScalarCeilToInt((kNumHexY - 0.5f) * 2 * kHexSide * kRoot3Over2);
+static const SkScalar kInset = 20.0f;
+static const int kNumPictures = 3;
+
+static const int kTriSide = 40;
+
+// Create a hexagon centered at (originX, originY)
+static SkPath make_hex_path(SkScalar originX, SkScalar originY) {
+    SkPath hex;
+    hex.moveTo(originX-kHexSide, originY);
+    hex.rLineTo(SkScalarHalf(kHexSide), kRoot3Over2 * kHexSide);
+    hex.rLineTo(SkIntToScalar(kHexSide), 0);
+    hex.rLineTo(SkScalarHalf(kHexSide), -kHexSide * kRoot3Over2);
+    hex.rLineTo(-SkScalarHalf(kHexSide), -kHexSide * kRoot3Over2);
+    hex.rLineTo(-SkIntToScalar(kHexSide), 0);
+    hex.close();
+    return hex;
+}
+
+// Make a picture that is a tiling of the plane with stroked hexagons where
+// each hexagon is in its own layer. The layers are to exercise Ganesh's
+// layer hoisting.
+static const SkPicture* make_hex_plane_picture(SkColor fillColor) {
+
+    // Create a hexagon with its center at the origin
+    SkPath hex = make_hex_path(0, 0);
+
+    SkPaint fill;
+    fill.setStyle(SkPaint::kFill_Style);
+    fill.setColor(fillColor);
+
+    SkPaint stroke;
+    stroke.setStyle(SkPaint::kStroke_Style);
+    stroke.setStrokeWidth(3);
+
+    SkPictureRecorder recorder;
+
+    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
+                                               SkIntToScalar(kPicHeight));
+
+    SkScalar xPos, yPos = 0;
+
+    for (int y = 0; y < kNumHexY; ++y) {
+        xPos = 0;
+
+        for (int x = 0; x < kNumHexX; ++x) {
+            canvas->saveLayer(NULL, NULL);
+            canvas->translate(xPos, yPos + ((x % 2) ? kRoot3Over2 * kHexSide : 0));
+            canvas->drawPath(hex, fill);
+            canvas->drawPath(hex, stroke);
+            canvas->restore();
+
+            xPos += 1.5f * kHexSide;
+        }
+
+        yPos += 2 * kHexSide * kRoot3Over2;
+    }
+
+    return recorder.endRecording();
+}
+
+// Make an equilateral triangle path with its top corner at (originX, originY)
+static SkPath make_tri_path(SkScalar originX, SkScalar originY) {
+    SkPath tri;
+    tri.moveTo(originX, originY);
+    tri.rLineTo(SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3);
+    tri.rLineTo(-kTriSide, 0);
+    tri.close();
+    return tri;
+}
+
+static const SkPicture* make_tri_picture() {
+    SkPath tri = make_tri_path(0, 0);
+
+    SkPaint fill;
+    fill.setStyle(SkPaint::kFill_Style);
+    fill.setColor(SK_ColorLTGRAY);;
+
+    SkPaint stroke;
+    stroke.setStyle(SkPaint::kStroke_Style);
+    stroke.setStrokeWidth(3);
+
+    SkPictureRecorder recorder;
+
+    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
+                                               SkIntToScalar(kPicHeight));
+    // The saveLayer/restore block is to exercise layer hoisting
+    canvas->saveLayer(NULL, NULL);
+        canvas->drawPath(tri, fill);
+        canvas->drawPath(tri, stroke);
+    canvas->restore();
+
+    return recorder.endRecording();
+}
+
+static const SkPicture* make_sub_picture(const SkPicture* tri) {
+    SkPictureRecorder recorder;
+
+    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
+                                               SkIntToScalar(kPicHeight));
+
+    canvas->scale(1.0f/2.0f, 1.0f/2.0f);
+
+    canvas->drawPicture(tri);
+
+    canvas->save();
+    canvas->translate(SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3);
+    canvas->drawPicture(tri);
+    canvas->restore();
+
+    canvas->save();
+    canvas->translate(-SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3);
+    canvas->drawPicture(tri);
+    canvas->restore();
+
+    return recorder.endRecording();
+}
+
+// Create a Sierpinkski-like picture that starts with a top row with a picture
+// that just contains a triangle. Subsequent rows take the prior row's picture,
+// shrinks it and replicates it 3 times then draws and appropriate number of
+// copies of it.
+static const SkPicture* make_sierpinski_picture() {
+    SkAutoTUnref<const SkPicture> pic(make_tri_picture());
+
+    SkPictureRecorder recorder;
+
+    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
+                                               SkIntToScalar(kPicHeight));
+
+    static const int kNumLevels = 4;
+    for (int i = 0; i < kNumLevels; ++i) {
+        canvas->save();
+            canvas->translate(-i*kTriSide / 2.0f, 0);
+            for (int j = 0; j < i+1; ++j) {
+                canvas->drawPicture(pic);
+                canvas->translate(SkIntToScalar(kTriSide), 0);
+            }
+        canvas->restore();
+
+        pic.reset(make_sub_picture(pic));
+
+        canvas->translate(0, 1.5f * kTriSide / kRoot3);
+    }
+
+    return recorder.endRecording();
+}
+
+static SkSurface* create_compat_surface(SkCanvas* canvas, int width, int height) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
+
+    SkSurface* surface = canvas->newSurface(info);
+    if (NULL == surface) {
+        // picture canvas returns NULL so fall back to raster
+        surface = SkSurface::NewRaster(info);
+    }
+
+    return surface;
+}
+
+// This class stores the information required to compose all the result
+// fragments potentially generated by the MultiPictureDraw object
+class ComposeStep {
+public:
+    ComposeStep() : fSurf(NULL), fX(0.0f), fY(0.0f), fPaint(NULL) { }
+    ~ComposeStep() { SkSafeUnref(fSurf);  SkDELETE(fPaint); }
+
+    SkSurface* fSurf;
+    SkScalar   fX;
+    SkScalar   fY;
+    SkPaint*   fPaint;
+};
+
+typedef void (*PFContentMtd)(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]);
+
+// Just a single picture with no clip
+static void no_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]) {
+    canvas->drawPicture(pictures[0]);
+}
+
+// Two pictures with a rect clip on the second one
+static void rect_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]) {
+    canvas->drawPicture(pictures[0]);
+
+    SkRect rect = pictures[0]->cullRect();
+    rect.inset(kInset, kInset);
+
+    canvas->clipRect(rect);
+
+    canvas->drawPicture(pictures[1]);
+}
+
+// Two pictures with a round rect clip on the second one
+static void rrect_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]) {
+    canvas->drawPicture(pictures[0]);
+
+    SkRect rect = pictures[0]->cullRect();
+    rect.inset(kInset, kInset);
+
+    SkRRect rrect;
+    rrect.setRectXY(rect, kInset, kInset);
+
+    canvas->clipRRect(rrect);
+
+    canvas->drawPicture(pictures[1]);
+}
+
+// Two pictures with a clip path on the second one
+static void path_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]) {
+    canvas->drawPicture(pictures[0]);
+
+    // Create a hexagon centered on the middle of the hex grid
+    SkPath hex = make_hex_path((kNumHexX / 2.0f) * kHexSide, kNumHexY * kHexSide * kRoot3Over2);
+
+    canvas->clipPath(hex);
+
+    canvas->drawPicture(pictures[1]);
+}
+
+// Two pictures with an inverse clip path on the second one
+static void invpath_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]) {
+    canvas->drawPicture(pictures[0]);
+
+    // Create a hexagon centered on the middle of the hex grid
+    SkPath hex = make_hex_path((kNumHexX / 2.0f) * kHexSide, kNumHexY * kHexSide * kRoot3Over2);
+    hex.setFillType(SkPath::kInverseEvenOdd_FillType);
+
+    canvas->clipPath(hex);
+
+    canvas->drawPicture(pictures[1]);
+}
+
+// Reuse a single base (triangular) picture a _lot_ (rotated, scaled and translated).
+static void sierpinski(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]) {
+    canvas->save();
+        canvas->translate(kPicWidth / 2.0f, 0.0f);
+        canvas->drawPicture(pictures[2]);
+
+        canvas->rotate(180.0f);
+        canvas->translate(0.0f, -SkIntToScalar(kPicHeight));
+        canvas->drawPicture(pictures[2]);
+    canvas->restore();
+}
+
+static const PFContentMtd gContentMthds[] = {
+    no_clip,
+    rect_clip,
+    rrect_clip,
+    path_clip,
+    invpath_clip,
+    sierpinski
+};
+
+static void create_content(SkMultiPictureDraw* mpd, PFContentMtd pfGen,
+                           const SkPicture* pictures[kNumPictures],
+                           SkCanvas* dest, const SkMatrix& xform) {
+    SkAutoTUnref<SkPicture> composite;
+
+    {
+        SkPictureRecorder recorder;
+
+        SkCanvas* pictureCanvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
+                                                          SkIntToScalar(kPicHeight));
+
+        (*pfGen)(pictureCanvas, pictures);
+
+        composite.reset(recorder.endRecording());
+    }
+
+    mpd->add(dest, composite, &xform);
+}
+
+typedef void(*PFLayoutMtd)(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
+                           PFContentMtd pfGen, const SkPicture* pictures[kNumPictures],
+                           SkTArray<ComposeStep>* composeSteps);
+
+// Draw the content into a single canvas
+static void simple(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
+                   PFContentMtd pfGen,
+                   const SkPicture* pictures[kNumPictures],
+                   SkTArray<ComposeStep> *composeSteps) {
+
+    ComposeStep& step = composeSteps->push_back();
+
+    step.fSurf = create_compat_surface(finalCanvas, kPicWidth, kPicHeight);
+
+    SkCanvas* subCanvas = step.fSurf->getCanvas();
+
+    create_content(mpd, pfGen, pictures, subCanvas, SkMatrix::I());
+}
+
+// Draw the content into multiple canvases/tiles
+static void tiled(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
+                  PFContentMtd pfGen,
+                  const SkPicture* pictures[kNumPictures],
+                  SkTArray<ComposeStep> *composeSteps) {
+    static const int kNumTilesX = 2;
+    static const int kNumTilesY = 2;
+    static const int kTileWidth = kPicWidth / kNumTilesX;
+    static const int kTileHeight = kPicHeight / kNumTilesY;
+
+    SkASSERT(kPicWidth == kNumTilesX * kTileWidth);
+    SkASSERT(kPicHeight == kNumTilesY * kTileHeight);
+
+    static const SkColor colors[kNumTilesX][kNumTilesY] = {
+        { SK_ColorCYAN,   SK_ColorMAGENTA },
+        { SK_ColorYELLOW, SK_ColorGREEN   }
+    };
+
+    for (int y = 0; y < kNumTilesY; ++y) {
+        for (int x = 0; x < kNumTilesX; ++x) {
+            ComposeStep& step = composeSteps->push_back();
+
+            step.fX = SkIntToScalar(x*kTileWidth);
+            step.fY = SkIntToScalar(y*kTileHeight);
+            step.fPaint = SkNEW(SkPaint);
+            step.fPaint->setColorFilter(
+                SkColorFilter::CreateModeFilter(colors[x][y], SkXfermode::kModulate_Mode))->unref();
+
+            step.fSurf = create_compat_surface(finalCanvas, kTileWidth, kTileHeight);
+
+            SkCanvas* subCanvas = step.fSurf->getCanvas();
+
+            SkMatrix trans;
+            trans.setTranslate(-SkIntToScalar(x*kTileWidth), -SkIntToScalar(y*kTileHeight));
+
+            create_content(mpd, pfGen, pictures, subCanvas, trans);
+        }
+    }
+}
+
+static const PFLayoutMtd gLayoutMthds[] = { simple, tiled };
+
+namespace skiagm {
+    /**
+     * This GM exercises the SkMultiPictureDraw object. It tests the
+     * cross product of:
+     *      tiled vs. all-at-once rendering (e.g., into many or just 1 canvas)
+     *      different clips (e.g., none, rect, rrect)
+     *      single vs. multiple pictures (e.g., normal vs. picture-pile-style content)
+     */
+    class MultiPictureDraw : public GM {
+    public:
+        enum Content {
+            kNoClipSingle_Content,
+            kRectClipMulti_Content,
+            kRRectClipMulti_Content,
+            kPathClipMulti_Content,
+            kInvPathClipMulti_Content,
+            kSierpinski_Content,
+
+            kLast_Content = kSierpinski_Content
+        };
+
+        static const int kContentCnt = kLast_Content + 1;
+
+        enum Layout {
+            kSimple_Layout,
+            kTiled_Layout,
+
+            kLast_Layout = kTiled_Layout
+        };
+
+        static const int kLayoutCnt = kLast_Layout + 1;
+
+        MultiPictureDraw(Content content, Layout layout) : fContent(content), fLayout(layout) {
+            SkASSERT(SK_ARRAY_COUNT(gLayoutMthds) == kLayoutCnt);
+            SkASSERT(SK_ARRAY_COUNT(gContentMthds) == kContentCnt);
+
+            for (int i = 0; i < kNumPictures; ++i) {
+                fPictures[i] = NULL;
+            }
+        }
+
+        virtual ~MultiPictureDraw() {
+            for (int i = 0; i < kNumPictures; ++i) {
+                SkSafeUnref(fPictures[i]);
+            }
+        }
+
+    protected:
+        Content          fContent;
+        Layout           fLayout;
+        const SkPicture* fPictures[kNumPictures];
+
+        virtual void onOnceBeforeDraw() SK_OVERRIDE {
+            fPictures[0] = make_hex_plane_picture(SK_ColorWHITE);
+            fPictures[1] = make_hex_plane_picture(SK_ColorGRAY);
+            fPictures[2] = make_sierpinski_picture();
+        }
+
+        virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+            SkMultiPictureDraw mpd;
+            SkTArray<ComposeStep> composeSteps;
+
+            // Fill up the MultiPictureDraw
+            (*gLayoutMthds[fLayout])(canvas, &mpd,
+                                     gContentMthds[fContent],
+                                     fPictures, &composeSteps);
+
+            mpd.draw();
+
+            // Compose all the drawn canvases into the final canvas
+            for (int i = 0; i < composeSteps.count(); ++i) {
+                const ComposeStep& step = composeSteps[i];
+
+                SkAutoTUnref<SkImage> image(step.fSurf->newImageSnapshot());
+
+                canvas->drawImage(image, step.fX, step.fY, step.fPaint);
+            }
+        }
+
+        virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(kPicWidth, kPicHeight); }
+
+        virtual SkString onShortName() SK_OVERRIDE {
+            static const char* gContentNames[] = {
+                "noclip", "rectclip", "rrectclip", "pathclip", "invpathclip", "sierpinski"
+            };
+            static const char* gLayoutNames[] = { "simple", "tiled" };
+
+            SkASSERT(SK_ARRAY_COUNT(gLayoutNames) == kLayoutCnt);
+            SkASSERT(SK_ARRAY_COUNT(gContentNames) == kContentCnt);
+
+            SkString name("multipicturedraw_");
+
+            name.append(gContentNames[fContent]);
+            name.append("_");
+            name.append(gLayoutNames[fLayout]);
+            return name;
+        }
+
+        virtual uint32_t onGetFlags() const SK_OVERRIDE { return kAsBench_Flag | kSkipTiled_Flag; }
+
+    private:
+        typedef GM INHERITED;
+    };
+
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,
+                                                MultiPictureDraw::kSimple_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,
+                                                MultiPictureDraw::kSimple_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,
+                                                MultiPictureDraw::kSimple_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,
+                                                MultiPictureDraw::kSimple_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content,
+                                                MultiPictureDraw::kSimple_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Content,
+                                                MultiPictureDraw::kSimple_Layout));)
+
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,
+                                                MultiPictureDraw::kTiled_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,
+                                                MultiPictureDraw::kTiled_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,
+                                                MultiPictureDraw::kTiled_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,
+                                                MultiPictureDraw::kTiled_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content,
+                                                MultiPictureDraw::kTiled_Layout));)
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Content,
+                                                MultiPictureDraw::kTiled_Layout));)
+}
diff --git a/gm/ninepatchstretch.cpp b/gm/ninepatchstretch.cpp
index b6f1a60..67f6bf4 100644
--- a/gm/ninepatchstretch.cpp
+++ b/gm/ninepatchstretch.cpp
@@ -44,10 +44,6 @@
     NinePatchStretchGM() {}
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() {
         return SkString("ninepatch-stretch");
     }
diff --git a/gm/offsetimagefilter.cpp b/gm/offsetimagefilter.cpp
index ca8a809..7fcbe0a 100644
--- a/gm/offsetimagefilter.cpp
+++ b/gm/offsetimagefilter.cpp
@@ -32,6 +32,7 @@
         canvas.clear(0x00000000);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xD000D000);
         paint.setTextSize(SkIntToScalar(96));
         const char* str = "e";
diff --git a/gm/optimizations.cpp b/gm/optimizations.cpp
index d810420..85ce3e9 100644
--- a/gm/optimizations.cpp
+++ b/gm/optimizations.cpp
@@ -17,9 +17,9 @@
 // heavy-weight operation since we are drawing the picture into a debug canvas
 // to extract the commands.
 static bool check_pattern(SkPicture& input, const SkTDArray<DrawType> &pattern) {
-    SkDebugCanvas debugCanvas(input.width(), input.height());
-    debugCanvas.setBounds(input.width(), input.height());
-    input.draw(&debugCanvas);
+    SkDebugCanvas debugCanvas(SkScalarCeilToInt(input.cullRect().width()), 
+                              SkScalarCeilToInt(input.cullRect().height()));
+    input.playback(&debugCanvas);
 
     if (pattern.count() != debugCanvas.getSize()) {
         return false;
@@ -82,7 +82,7 @@
 
     SkPictureRecorder recorder;
 
-    SkCanvas* canvas = recorder.beginRecording(100, 100, NULL, 0);
+    SkCanvas* canvas = recorder.DEPRECATED_beginRecording(100, 100, NULL, 0);
     // have to disable the optimizations while generating the picture
     recorder.internalOnly_EnableOpts(false);
 
@@ -216,7 +216,7 @@
 
     SkPictureRecorder recorder;
 
-    SkCanvas* canvas = recorder.beginRecording(100, 100, NULL, 0);
+    SkCanvas* canvas = recorder.DEPRECATED_beginRecording(100, 100, NULL, 0);
     // have to disable the optimizations while generating the picture
     recorder.internalOnly_EnableOpts(false);
 
@@ -340,7 +340,7 @@
         };
 
         SkTDArray<DrawType> prePattern, postPattern;
-        int xPos = 0, yPos = 0;
+        SkScalar xPos = 0, yPos = 0;
 
         for (size_t i = 0; i < SK_ARRAY_COUNT(gOpts); ++i) {
             SkAutoTUnref<SkPicture> pre((*gOpts[i])(&prePattern, &postPattern, fCheckerboard));
@@ -351,17 +351,20 @@
             }
 
             canvas->save();
-                canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos));
-                pre->draw(canvas);
-                xPos += pre->width();
+                canvas->translate(xPos, yPos);
+                pre->playback(canvas);
+                xPos += pre->cullRect().width();
             canvas->restore();
 
             // re-render the 'pre' picture and thus 'apply' the optimization
             SkPictureRecorder recorder;
 
-            SkCanvas* recordCanvas = recorder.beginRecording(pre->width(), pre->height(), NULL, 0);
+            SkCanvas* recordCanvas =
+                recorder.DEPRECATED_beginRecording(pre->cullRect().width(), 
+                                                   pre->cullRect().height(), 
+                                                   NULL, 0);
 
-            pre->draw(recordCanvas);
+            pre->playback(recordCanvas);
 
             SkAutoTUnref<SkPicture> post(recorder.endRecording());
 
@@ -371,15 +374,15 @@
             }
 
             canvas->save();
-                canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos));
-                post->draw(canvas);
-                xPos += post->width();
+                canvas->translate(xPos, yPos);
+                post->playback(canvas);
+                xPos += post->cullRect().width();
             canvas->restore();
 
             if (xPos >= kWidth) {
                 // start a new line
                 xPos = 0;
-                yPos += post->height();
+                yPos += post->cullRect().height();
             }
 
             // TODO: we could also render the pre and post pictures to bitmaps
diff --git a/gm/patch.cpp b/gm/patch.cpp
new file mode 100644
index 0000000..2579993
--- /dev/null
+++ b/gm/patch.cpp
@@ -0,0 +1,163 @@
+
+/*
+ * 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 "gm.h"
+#include "SkGradientShader.h"
+#include "SkPatchUtils.h"
+
+static SkShader* make_shader() {
+    const SkColor colors[] = {
+        SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE, SK_ColorMAGENTA, SK_ColorBLUE,
+        SK_ColorYELLOW,
+    };
+    const SkPoint pts[] = { { 100.f / 4.f, 0.f }, { 3.f * 100.f / 4.f, 100.f } };
+    
+    return SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors),
+                                          SkShader::kMirror_TileMode);
+}
+
+static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
+    //draw control points
+    SkPaint paint;
+    SkPoint bottom[SkPatchUtils::kNumPtsCubic];
+    SkPatchUtils::getBottomCubic(cubics, bottom);
+    SkPoint top[SkPatchUtils::kNumPtsCubic];
+    SkPatchUtils::getTopCubic(cubics, top);
+    SkPoint left[SkPatchUtils::kNumPtsCubic];
+    SkPatchUtils::getLeftCubic(cubics, left);
+    SkPoint right[SkPatchUtils::kNumPtsCubic];
+    SkPatchUtils::getRightCubic(cubics, right);
+
+    paint.setColor(SK_ColorBLACK);
+    paint.setStrokeWidth(0.5f);
+    SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
+
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);
+
+    paint.setStrokeWidth(2);
+
+    paint.setColor(SK_ColorRED);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
+
+    paint.setColor(SK_ColorBLUE);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);
+
+    paint.setColor(SK_ColorCYAN);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);
+
+    paint.setColor(SK_ColorYELLOW);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);
+
+    paint.setColor(SK_ColorGREEN);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
+}
+
+namespace skiagm {
+/**
+ * This GM draws a cubics coons patch using the specialized call SkCanvas::drawPatch.
+ */
+class SkPatchGM : public GM {
+    
+public:
+    SkPatchGM() {
+        this->setBGColor(0xFFFFFFFF);
+    }
+
+protected:
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("patch_primitive");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(800, 800);
+    }
+
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+
+        SkPaint paint;
+        
+        // The order of the colors and points is clockwise starting at upper-left corner.
+        const SkPoint cubics[SkPatchUtils::kNumCtrlPts] = {
+            //top points
+            {100,100},{150,50},{250,150}, {300,100},
+            //right points
+            {250, 150},{350,250},
+            //bottom points
+            {300,300},{250,250},{150,350},{100,300},
+            //left points
+            {50,250},{150,150}
+        };
+        
+        const SkColor colors[SkPatchUtils::kNumCorners] = {
+            SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
+        };
+        const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
+            {0.0f, 0.0f}, {100.0f, 0.0f}, {100.0f,100.0f}, {0.0f, 100.0f}}
+        ;
+        
+        const SkXfermode::Mode modes[] = {
+            SkXfermode::kSrc_Mode,
+            SkXfermode::kDst_Mode,
+            SkXfermode::kModulate_Mode,
+        };
+        
+        SkAutoTUnref<SkShader> shader(make_shader());
+        
+        canvas->save();
+        for (int y = 0; y < 3; y++) {
+            SkAutoTUnref<SkXfermode> xfer(SkXfermode::Create(modes[y]));
+
+            for (int x = 0; x < 4; x++) {
+                canvas->save();
+                canvas->translate(x * 350.0f, y * 350.0f);
+                switch (x) {
+                    case 0:
+                        canvas->drawPatch(cubics, NULL, NULL, xfer, paint);
+                        break;
+                    case 1:
+                        canvas->drawPatch(cubics, colors, NULL, xfer, paint);
+                        break;
+                    case 2:
+                        paint.setShader(shader);
+                        canvas->drawPatch(cubics, NULL, texCoords, xfer, paint);
+                        paint.setShader(NULL);
+                        break;
+                    case 3:
+                        paint.setShader(shader);
+                        canvas->drawPatch(cubics, colors, texCoords, xfer, paint);
+                        paint.setShader(NULL);
+                        break;
+                    default:
+                        break;
+                }
+                
+                draw_control_points(canvas, cubics);
+                canvas->restore();
+            }
+        }
+        canvas->restore();
+    }
+
+private:
+    typedef GM INHERITED;
+};
+
+DEF_GM(return SkNEW(SkPatchGM); )
+
+}
diff --git a/gm/patchgrid.cpp b/gm/patchgrid.cpp
new file mode 100644
index 0000000..79baf94
--- /dev/null
+++ b/gm/patchgrid.cpp
@@ -0,0 +1,165 @@
+
+/*
+ * 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 "gm.h"
+#include "SkPatchGrid.h"
+
+static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
+    //draw control points
+    SkPaint paint;
+    SkPoint bottom[4];
+    SkPatchUtils::getBottomCubic(cubics, bottom);
+    SkPoint top[4];
+    SkPatchUtils::getTopCubic(cubics, top);
+    SkPoint left[4];
+    SkPatchUtils::getLeftCubic(cubics, left);
+    SkPoint right[4];
+    SkPatchUtils::getRightCubic(cubics, right);
+
+    paint.setColor(SK_ColorBLACK);
+    paint.setStrokeWidth(0.5);
+    SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom+1, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
+
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top+1, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left+1, paint);
+    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right+1, paint);
+
+    paint.setStrokeWidth(2);
+
+    paint.setColor(SK_ColorRED);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
+
+    paint.setColor(SK_ColorBLUE);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom+1, paint);
+
+    paint.setColor(SK_ColorCYAN);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top+1, paint);
+
+    paint.setColor(SK_ColorYELLOW);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left+1, paint);
+
+    paint.setColor(SK_ColorGREEN);
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right+1, paint);
+}
+
+namespace skiagm {
+/**
+ * This GM draws a grid of patches, it only uses colors so it could be considered a mesh gradient.
+ */
+class SkPatchGridGM : public GM {
+    
+public:
+    SkPatchGridGM() {
+        this->setBGColor(0xFFFFFFFF);
+    }
+
+protected:
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("patch_grid");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(800, 800);
+    }
+
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+
+        SkPaint paint;
+        
+        SkPoint vertices[4][5] = {
+            {{50,50}, {150,50}, {250,50},{350,50},{450,50}},
+            {{50,150}, {120,120}, {250,150},{350,150},{450,150}},
+            {{50,250}, {150,250}, {250,250},{350,250},{450,250}},
+            {{100,300}, {150,350}, {250,350},{350,350},{450,350}}
+        };
+        
+        SkColor cornerColors[4][5] = {
+            {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE},
+            {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED},
+            {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE},
+            {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED},
+        };
+        
+        SkPoint hrzCtrl[4][8] = {
+            {{75,30},{125,45},{175,70},{225,20},{275,50},{325,50},{375,5},{425,90}},
+            {{75,150},{125,150},{175,150},{225,150},{275,150},{325,150},{375,150},{425,150}},
+            {{75,250},{125,250},{175,250},{225,250},{275,200},{325,150},{375,250},{425,250}},
+            {{75,350},{125,350},{175,350},{225,350},{275,350},{325,350},{375,350},{425,350}}
+        };
+        
+        SkPoint vrtCtrl[6][5] = {
+            {{50,75},{150,75},{250,75},{350,75},{450,75}},
+            {{50,125},{150,125},{250,125},{350,125},{450,125}},
+            {{50,175},{150,175},{220,225},{350,175},{470,225}},
+            {{50,225},{150,225},{220,175},{350,225},{470,155}},
+            {{50,275},{150,275},{250,275},{350,275},{400,305}},
+            {{50,325},{150,325},{250,325},{350,325},{450,325}}
+        };
+        
+        static const int kRows = 3;
+        static const int kCols = 4;
+        
+        canvas->scale(3, 3);
+        SkPatchGrid grid(kRows, kCols, SkPatchGrid::kColors_VertexType, NULL);
+        for (int i = 0; i < kRows; i++) {
+            for (int j = 0; j < kCols; j++) {
+                SkPoint points[12];
+                
+                //set corners
+                points[SkPatchUtils::kTopP0_CubicCtrlPts] = vertices[i][j];
+                points[SkPatchUtils::kTopP3_CubicCtrlPts] = vertices[i][j + 1];
+                points[SkPatchUtils::kBottomP0_CubicCtrlPts] = vertices[i + 1][j];
+                points[SkPatchUtils::kBottomP3_CubicCtrlPts] = vertices[i + 1][j + 1];
+                
+                points[SkPatchUtils::kTopP1_CubicCtrlPts] = hrzCtrl[i][j * 2];
+                points[SkPatchUtils::kTopP2_CubicCtrlPts] = hrzCtrl[i][j * 2 + 1];
+                points[SkPatchUtils::kBottomP1_CubicCtrlPts] = hrzCtrl[i + 1][j * 2];
+                points[SkPatchUtils::kBottomP2_CubicCtrlPts] = hrzCtrl[i + 1][j * 2 + 1];
+                
+                points[SkPatchUtils::kLeftP1_CubicCtrlPts] = vrtCtrl[i * 2][j];
+                points[SkPatchUtils::kLeftP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j];
+                points[SkPatchUtils::kRightP1_CubicCtrlPts] = vrtCtrl[i * 2][j + 1];
+                points[SkPatchUtils::kRightP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j + 1];
+                
+                SkColor colors[4];
+                colors[0] = cornerColors[i][j];
+                colors[1] = cornerColors[i][j + 1];
+                colors[3] = cornerColors[i + 1][j];
+                colors[2] = cornerColors[i + 1][j + 1];
+                
+                grid.setPatch(j, i, points, colors, NULL);
+            }
+        }
+        
+        grid.draw(canvas, paint);
+        SkISize dims = grid.getDimensions();
+        for (int y = 0; y < dims.height(); y++) {
+            for (int x = 0; x < dims.width(); x++) {
+                SkPoint cubics[12];
+                grid.getPatch(x, y, cubics, NULL, NULL);
+                draw_control_points(canvas, cubics);
+            }
+        }
+    }
+
+private:
+    typedef GM INHERITED;
+};
+
+DEF_GM(return SkNEW(SkPatchGridGM); )
+
+}
diff --git a/gm/pathinterior.cpp b/gm/pathinterior.cpp
index e587928..559fb89 100644
--- a/gm/pathinterior.cpp
+++ b/gm/pathinterior.cpp
@@ -25,10 +25,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkISize onISize() {
         return SkISize::Make(770, 770);
     }
diff --git a/gm/pathopsinverse.cpp b/gm/pathopsinverse.cpp
index bdd8217..743db22 100644
--- a/gm/pathopsinverse.cpp
+++ b/gm/pathopsinverse.cpp
@@ -50,10 +50,6 @@
         paint->setColor(color);
     }
 
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;  // Only for 565.  8888 is fine.
-    }
-
     virtual SkString onShortName() SK_OVERRIDE {
         return SkString("pathopsinverse");
     }
diff --git a/gm/pathopsskpclip.cpp b/gm/pathopsskpclip.cpp
index 31d532d..5d6e401 100644
--- a/gm/pathopsskpclip.cpp
+++ b/gm/pathopsskpclip.cpp
@@ -24,10 +24,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() SK_OVERRIDE {
         return SkString("pathopsskpclip");
     }
diff --git a/gm/pathreverse.cpp b/gm/pathreverse.cpp
index 77687f4..fd13404 100644
--- a/gm/pathreverse.cpp
+++ b/gm/pathreverse.cpp
@@ -52,8 +52,7 @@
 
     SkPaint paint;
     paint.setTextSize(SkIntToScalar(100));
-    SkTypeface* hira = SkTypeface::CreateFromName("Hiragino Maru Gothic Pro", SkTypeface::kNormal);
-    SkSafeUnref(paint.setTypeface(hira));
+    sk_tool_utils::set_portable_typeface(&paint, "Hiragino Maru Gothic Pro");
     path.reset();
     paint.getTextPath("e", 1, 50, 50, &path);
     canvas->translate(0, 100);
@@ -103,8 +102,7 @@
 
         SkPaint paint;
         paint.setTextSize(SkIntToScalar(100));
-        SkTypeface* hira = SkTypeface::CreateFromName("Hiragino Maru Gothic Pro", SkTypeface::kNormal);
-        SkSafeUnref(paint.setTypeface(hira));
+        sk_tool_utils::set_portable_typeface(&paint, "Hiragino Maru Gothic Pro");
         path.reset();
         paint.getTextPath("e", 1, 50, 50, &path);
         canvas->translate(0, 100);
diff --git a/gm/picture.cpp b/gm/picture.cpp
new file mode 100644
index 0000000..1f7e5c3
--- /dev/null
+++ b/gm/picture.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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 "gm.h"
+#include "SkPaint.h"
+#include "SkPictureRecorder.h"
+
+static SkPicture* make_picture() {
+    SkPictureRecorder rec;
+    SkCanvas* canvas = rec.beginRecording(100, 100);
+
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    SkPath path;
+
+    paint.setColor(0x800000FF);
+    canvas->drawRect(SkRect::MakeWH(100, 100), paint);
+
+    paint.setColor(0x80FF0000);
+    path.moveTo(0, 0); path.lineTo(100, 0); path.lineTo(100, 100);
+    canvas->drawPath(path, paint);
+    
+    paint.setColor(0x8000FF00);
+    path.reset(); path.moveTo(0, 0); path.lineTo(100, 0); path.lineTo(0, 100);
+    canvas->drawPath(path, paint);
+
+    paint.setColor(0x80FFFFFF);
+    paint.setXfermodeMode(SkXfermode::kPlus_Mode);
+    canvas->drawRect(SkRect::MakeXYWH(25, 25, 50, 50), paint);
+
+    return rec.endRecording();
+}
+
+// Exercise the optional arguments to drawPicture
+//
+class PictureGM : public skiagm::GM {
+public:
+    PictureGM() : fPicture(make_picture()) {}
+
+protected:
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("pictures");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(450, 120);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        canvas->translate(10, 10);
+
+        SkMatrix matrix;
+        SkPaint paint;
+
+        canvas->drawPicture(fPicture);
+        
+        matrix.setTranslate(110, 0);
+        canvas->drawPicture(fPicture, &matrix, NULL);
+        
+        matrix.postTranslate(110, 0);
+        canvas->drawPicture(fPicture, &matrix, &paint);
+
+        paint.setAlpha(0x80);
+        matrix.postTranslate(110, 0);
+        canvas->drawPicture(fPicture, &matrix, &paint);
+    }
+
+private:
+    SkAutoTUnref<SkPicture> fPicture;
+
+    typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return SkNEW(PictureGM); )
diff --git a/gm/pictureimagefilter.cpp b/gm/pictureimagefilter.cpp
index b0fd057..4e169f7 100644
--- a/gm/pictureimagefilter.cpp
+++ b/gm/pictureimagefilter.cpp
@@ -28,6 +28,7 @@
         canvas->clear(0x00000000);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xFFFFFFFF);
         paint.setTextSize(SkIntToScalar(96));
         const char* str = "e";
diff --git a/gm/pictureshader.cpp b/gm/pictureshader.cpp
index 8b26e48..152cdf3 100644
--- a/gm/pictureshader.cpp
+++ b/gm/pictureshader.cpp
@@ -30,14 +30,12 @@
 
         // Build the picture.
         SkPictureRecorder recorder;
-        SkCanvas* pictureCanvas = recorder.beginRecording(SkScalarRoundToInt(tileSize),
-                                                          SkScalarRoundToInt(tileSize),
-                                                          NULL, 0);
+        SkCanvas* pictureCanvas = recorder.beginRecording(tileSize, tileSize, NULL, 0);
         this->drawTile(pictureCanvas);
         fPicture.reset(recorder.endRecording());
 
         // Build a reference bitmap.
-        fBitmap.allocN32Pixels(SkScalarRoundToInt(tileSize), SkScalarRoundToInt(tileSize));
+        fBitmap.allocN32Pixels(SkScalarCeilToInt(tileSize), SkScalarCeilToInt(tileSize));
         fBitmap.eraseColor(SK_ColorTRANSPARENT);
         SkCanvas bitmapCanvas(fBitmap);
         this->drawTile(&bitmapCanvas);
@@ -135,7 +133,8 @@
                     fPicture,
                     kTileConfigs[tileMode].tmx,
                     kTileConfigs[tileMode].tmy,
-                    &localMatrix));
+                    &localMatrix,
+                    NULL));
         paint.setShader(pictureShader.get());
         canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
 
diff --git a/gm/pictureshadertile.cpp b/gm/pictureshadertile.cpp
new file mode 100644
index 0000000..ecea553
--- /dev/null
+++ b/gm/pictureshadertile.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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 "gm.h"
+
+#include "SkPaint.h"
+#include "SkPicture.h"
+#include "SkPictureRecorder.h"
+#include "SkShader.h"
+
+static const SkScalar kPictureSize = SK_Scalar1;
+static const SkScalar kFillSize = 100;
+static const unsigned kRowSize = 6;
+
+static const struct {
+    SkScalar x, y, w, h;
+    SkScalar offsetX, offsetY;
+} tiles[] = {
+    {      0,      0,    1,    1,      0,    0 },
+    {   0.5f,   0.5f,    1,    1,      0,    0 },
+    {  -0.5f,  -0.5f,    1,    1,      0,    0 },
+
+    {      0,      0, 1.5f, 1.5f,      0,    0 },
+    {   0.5f,   0.5f, 1.5f, 1.5f,      0,    0 },
+    {  -0.5f,  -0.5f, 1.5f, 1.5f,      0,    0 },
+
+    {      0,      0, 0.5f, 0.5f,      0,    0 },
+    { -0.25f, -0.25f, 0.5f, 0.5f,      0,    0 },
+    {  0.25f,  0.25f, 0.5f, 0.5f,      0,    0 },
+
+    {      0,      0,    1,    1,   0.5f, 0.5f },
+    {   0.5f,   0.5f,    1,    1,   0.5f, 0.5f },
+    {  -0.5f,  -0.5f,    1,    1,   0.5f, 0.5f },
+
+    {      0,      0, 1.5f, 1.5f,   0.5f, 0.5f },
+    {   0.5f,   0.5f, 1.5f, 1.5f,   0.5f, 0.5f },
+    {  -0.5f,  -0.5f, 1.5f, 1.5f,   0.5f, 0.5f },
+
+    {      0,      0, 1.5f,    1,      0,    0 },
+    {   0.5f,   0.5f, 1.5f,    1,      0,    0 },
+    {  -0.5f,  -0.5f, 1.5f,    1,      0,    0 },
+
+    {      0,      0, 0.5f,    1,      0,    0 },
+    { -0.25f, -0.25f, 0.5f,    1,      0,    0 },
+    {  0.25f,  0.25f, 0.5f,    1,      0,    0 },
+
+    {      0,      0,    1, 1.5f,      0,    0 },
+    {   0.5f,   0.5f,    1, 1.5f,      0,    0 },
+    {  -0.5f,  -0.5f,    1, 1.5f,      0,    0 },
+
+    {      0,      0,    1, 0.5f,      0,    0 },
+    { -0.25f, -0.25f,    1, 0.5f,      0,    0 },
+    {  0.25f,  0.25f,    1, 0.5f,      0,    0 },
+};
+
+class PictureShaderTileGM : public skiagm::GM {
+public:
+    PictureShaderTileGM() {
+        SkPictureRecorder recorder;
+        SkCanvas* pictureCanvas = recorder.beginRecording(kPictureSize, kPictureSize, NULL, 0);
+        drawScene(pictureCanvas, kPictureSize);
+        SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+
+        for (unsigned i = 0; i < SK_ARRAY_COUNT(tiles); ++i) {
+            SkRect tile = SkRect::MakeXYWH(tiles[i].x * kPictureSize,
+                                           tiles[i].y * kPictureSize,
+                                           tiles[i].w * kPictureSize,
+                                           tiles[i].h * kPictureSize);
+            SkMatrix localMatrix;
+            localMatrix.setTranslate(tiles[i].offsetX * kPictureSize,
+                                     tiles[i].offsetY * kPictureSize);
+            localMatrix.postScale(kFillSize / (2 * kPictureSize),
+                                  kFillSize / (2 * kPictureSize));
+            fShaders[i].reset(SkShader::CreatePictureShader(picture,
+                              SkShader::kRepeat_TileMode,
+                              SkShader::kRepeat_TileMode,
+                              &localMatrix,
+                              &tile));
+        }
+    }
+
+protected:
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("pictureshadertile");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(800, 600);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        canvas->clear(SK_ColorBLACK);
+
+        SkPaint paint;
+        paint.setStyle(SkPaint::kFill_Style);
+
+        for (unsigned i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
+            paint.setShader(fShaders[i]);
+
+            canvas->save();
+            canvas->translate((i % kRowSize) * kFillSize * 1.1f,
+                              (i / kRowSize) * kFillSize * 1.1f);
+            canvas->drawRect(SkRect::MakeWH(kFillSize, kFillSize), paint);
+            canvas->restore();
+        }
+    }
+
+private:
+    void drawScene(SkCanvas* canvas, SkScalar pictureSize) {
+        canvas->clear(SK_ColorWHITE);
+
+        SkPaint paint;
+        paint.setColor(SK_ColorGREEN);
+        paint.setStyle(SkPaint::kFill_Style);
+        paint.setAntiAlias(true);
+
+        canvas->drawCircle(pictureSize / 4, pictureSize / 4, pictureSize / 4, paint);
+        canvas->drawRect(SkRect::MakeXYWH(pictureSize / 2, pictureSize / 2,
+                                          pictureSize / 2, pictureSize / 2), paint);
+
+        paint.setColor(SK_ColorRED);
+        canvas->drawLine(pictureSize / 2, pictureSize * 1 / 3,
+                         pictureSize / 2, pictureSize * 2 / 3, paint);
+        canvas->drawLine(pictureSize * 1 / 3, pictureSize / 2,
+                         pictureSize * 2 / 3, pictureSize / 2, paint);
+
+        paint.setColor(SK_ColorBLACK);
+        paint.setStyle(SkPaint::kStroke_Style);
+        canvas->drawRect(SkRect::MakeWH(pictureSize, pictureSize), paint);
+    }
+
+    SkAutoTUnref<SkShader> fShaders[SK_ARRAY_COUNT(tiles)];
+
+    typedef GM INHERITED;
+};
+
+DEF_GM( return SkNEW(PictureShaderTileGM); )
diff --git a/gm/poly2poly.cpp b/gm/poly2poly.cpp
index 9e58d9d..191bb0e 100644
--- a/gm/poly2poly.cpp
+++ b/gm/poly2poly.cpp
@@ -37,6 +37,7 @@
 
 SkJSCanvas::SkJSCanvas(SkCanvas* target) : fTarget(target) {
     fFillPaint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&fFillPaint);
     fStrokePaint.setAntiAlias(true);
     fStrokePaint.setStyle(SkPaint::kStroke_Style);
     fStrokePaint.setStrokeWidth(SK_Scalar1);
@@ -229,6 +230,7 @@
 
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setStrokeWidth(SkIntToScalar(4));
         paint.setTextSize(SkIntToScalar(40));
         paint.setTextAlign(SkPaint::kCenter_Align);
diff --git a/gm/quadpaths.cpp b/gm/quadpaths.cpp
index f21fdd9..f2c4cf1 100644
--- a/gm/quadpaths.cpp
+++ b/gm/quadpaths.cpp
@@ -86,6 +86,7 @@
         SkPaint titlePaint;
         titlePaint.setColor(SK_ColorBLACK);
         titlePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&titlePaint);
         titlePaint.setLCDRenderText(true);
         titlePaint.setTextSize(15 * SK_Scalar1);
         const char title[] = "Quad Drawn Into Rectangle Clips With "
@@ -130,6 +131,7 @@
                     SkPaint labelPaint;
                     labelPaint.setColor(color);
                     labelPaint.setAntiAlias(true);
+                    sk_tool_utils::set_portable_typeface(&labelPaint);
                     labelPaint.setLCDRenderText(true);
                     labelPaint.setTextSize(10 * SK_Scalar1);
                     canvas->drawText(gStyles[style].fName,
@@ -233,6 +235,7 @@
         SkPaint titlePaint;
         titlePaint.setColor(SK_ColorBLACK);
         titlePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&titlePaint);
         titlePaint.setLCDRenderText(true);
         titlePaint.setTextSize(15 * SK_Scalar1);
         const char title[] = "Quad Closed Drawn Into Rectangle Clips With "
@@ -277,6 +280,7 @@
                     SkPaint labelPaint;
                     labelPaint.setColor(color);
                     labelPaint.setAntiAlias(true);
+                    sk_tool_utils::set_portable_typeface(&labelPaint);
                     labelPaint.setLCDRenderText(true);
                     labelPaint.setTextSize(10 * SK_Scalar1);
                     canvas->drawText(gStyles[style].fName,
diff --git a/gm/rebaseline_server/__init__.py b/gm/rebaseline_server/__init__.py
new file mode 100644
index 0000000..02d71e9
--- /dev/null
+++ b/gm/rebaseline_server/__init__.py
@@ -0,0 +1 @@
+# Needed so that test_all.py will recurse into this directory.
diff --git a/gm/rebaseline_server/base_unittest.py b/gm/rebaseline_server/base_unittest.py
index 0699db6..b8a6538 100755
--- a/gm/rebaseline_server/base_unittest.py
+++ b/gm/rebaseline_server/base_unittest.py
@@ -10,119 +10,32 @@
 for various unittests within this directory.
 """
 
-import filecmp
+# System-level imports.
 import os
-import shutil
-import tempfile
-import unittest
+import sys
 
-PARENT_DIR = os.path.dirname(os.path.realpath(__file__))
-TRUNK_DIR = os.path.dirname(os.path.dirname(PARENT_DIR))
-TESTDATA_DIR = os.path.join(PARENT_DIR, 'testdata')
-OUTPUT_DIR_ACTUAL = os.path.join(TESTDATA_DIR, 'outputs', 'actual')
-OUTPUT_DIR_EXPECTED = os.path.join(TESTDATA_DIR, 'outputs', 'expected')
+PARENT_DIR = os.path.abspath(os.path.dirname(__file__))
+TRUNK_DIR = os.path.abspath(os.path.join(PARENT_DIR, os.pardir, os.pardir))
+
+# Import the superclass base_unittest module from the tools dir.
+#
+# TODO(epoger): If I don't put this at the beginning of sys.path, the import of
+# tests.base_unittest fails.  That's bad.  I need to come up with a cleaner way
+# of doing this... I think this will involve changing how we import the "boto"
+# library in gs_utils.py, within the common repo.
+TOOLS_DIR = os.path.join(TRUNK_DIR, 'tools')
+if TOOLS_DIR != sys.path[0]:
+  sys.path.insert(0, TOOLS_DIR)
+import tests.base_unittest as superclass_module
 
 
-class TestCase(unittest.TestCase):
+class TestCase(superclass_module.TestCase):
 
-  def setUp(self):
-    self._input_dir = os.path.join(TESTDATA_DIR, 'inputs')
-    self._output_dir_actual   = os.path.join(OUTPUT_DIR_ACTUAL, self.id())
-    self._output_dir_expected = os.path.join(OUTPUT_DIR_EXPECTED, self.id())
-    create_empty_dir(self._output_dir_actual)
-    self._temp_dir = tempfile.mkdtemp()
+  def __init__(self, *args, **kwargs):
+    super(TestCase, self).__init__(*args, **kwargs)
+    # Some of the tests within this package want their output validated,
+    # so we declare where the expected and actual output will be.
+    self._testdata_dir = os.path.join(PARENT_DIR, 'testdata')
 
-  def tearDown(self):
-    shutil.rmtree(self._temp_dir)
-    if os.path.exists(self._output_dir_expected):
-      different_files = find_different_files(self._output_dir_actual,
-                                             self._output_dir_expected)
-      # Maybe we should move this assert elsewhere?  It's unusual to see an
-      # assert within tearDown(), but my thinking was:
-      # 1. Every test case will have some collection of output files that need
-      #    to be validated.
-      # 2. So put that validation within tearDown(), which will be called after
-      #    every test case!
-      #
-      # I have confirmed that the test really does fail if this assert is
-      # triggered.
-      #
-      # Ravi notes: if somebody later comes along and adds cleanup code below
-      # this assert, then if tests fail, the artifacts will not be cleaned up.
-      assert (not different_files), \
-        ('found differing files:\n' +
-         '\n'.join(['tkdiff %s %s &' % (
-             os.path.join(self._output_dir_actual, basename),
-             os.path.join(self._output_dir_expected, basename))
-                    for basename in different_files]))
-
-  def shortDescription(self):
-    """Tell unittest framework to not print docstrings for test cases."""
-    return None
-
-  def find_path_to_program(self, program):
-    """Returns path to an existing program binary.
-
-    Args:
-      program: Basename of the program to find (e.g., 'render_pictures').
-
-    Returns:
-      Absolute path to the program binary, as a string.
-
-    Raises:
-      Exception: unable to find the program binary.
-    """
-    possible_paths = [os.path.join(TRUNK_DIR, 'out', 'Release', program),
-                      os.path.join(TRUNK_DIR, 'out', 'Debug', program),
-                      os.path.join(TRUNK_DIR, 'out', 'Release',
-                                   program + '.exe'),
-                      os.path.join(TRUNK_DIR, 'out', 'Debug',
-                                   program + '.exe')]
-    for try_path in possible_paths:
-      if os.path.isfile(try_path):
-        return try_path
-    raise Exception('cannot find %s in paths %s; maybe you need to '
-                    'build %s?' % (program, possible_paths, program))
-
-
-def create_empty_dir(path):
-  """Create an empty directory at the given path."""
-  if os.path.isdir(path):
-    shutil.rmtree(path)
-  elif os.path.lexists(path):
-    os.remove(path)
-  os.makedirs(path)
-
-
-def find_different_files(dir1, dir2, ignore_subtree_names=None):
-  """Returns a list of any files that differ between the directory trees rooted
-  at dir1 and dir2.
-
-  Args:
-    dir1: root of a directory tree; if nonexistent, will raise OSError
-    dir2: root of another directory tree; if nonexistent, will raise OSError
-    ignore_subtree_names: list of subtree directory names to ignore;
-          defaults to ['.svn'], so all SVN files are ignores
-
-  TODO(epoger): include the dirname within each filename (not just the
-  basename), to make it easier to locate any differences
-  """
-  differing_files = []
-  if ignore_subtree_names is None:
-    ignore_subtree_names = ['.svn']
-  dircmp = filecmp.dircmp(dir1, dir2, ignore=ignore_subtree_names)
-  differing_files.extend(dircmp.left_only)
-  differing_files.extend(dircmp.right_only)
-  differing_files.extend(dircmp.common_funny)
-  differing_files.extend(dircmp.diff_files)
-  differing_files.extend(dircmp.funny_files)
-  for common_dir in dircmp.common_dirs:
-    differing_files.extend(find_different_files(
-        os.path.join(dir1, common_dir), os.path.join(dir2, common_dir)))
-  return differing_files
-
-
-def main(test_case_class):
-  """Run the unit tests within the given class."""
-  suite = unittest.TestLoader().loadTestsFromTestCase(test_case_class)
-  results = unittest.TextTestRunner(verbosity=2).run(suite)
+def main(*args, **kwargs):
+  superclass_module.main(*args, **kwargs)
diff --git a/gm/rebaseline_server/column.py b/gm/rebaseline_server/column.py
index 07b075c..1b9d0bf 100644
--- a/gm/rebaseline_server/column.py
+++ b/gm/rebaseline_server/column.py
@@ -15,6 +15,7 @@
 KEY__EXTRACOLUMNHEADERS__HEADER_URL = 'headerUrl'
 KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE = 'isFilterable'
 KEY__EXTRACOLUMNHEADERS__IS_SORTABLE = 'isSortable'
+KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER = 'useFreeformFilter'
 KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS = 'valuesAndCounts'
 
 
@@ -23,7 +24,7 @@
 
   def __init__(self, header_text, header_url=None,
                is_filterable=True, is_sortable=True,
-               include_values_and_counts=True):
+               use_freeform_filter=False):
     """
     Args:
       header_text: string; text the client should display within column header.
@@ -32,15 +33,16 @@
       is_filterable: boolean; whether client should allow filtering on this
           column.
       is_sortable: boolean; whether client should allow sorting on this column.
-      include_values_and_counts: boolean; whether the set of values found
-          within this column, and their counts, should be available for the
-          client to display.
+      use_freeform_filter: boolean; *recommendation* to the client indicating
+          whether to allow freeform text matching, as opposed to listing all
+          values alongside checkboxes.  If is_filterable==false, this is
+          meaningless.
     """
     self._header_text = header_text
     self._header_url = header_url
     self._is_filterable = is_filterable
     self._is_sortable = is_sortable
-    self._include_values_and_counts = include_values_and_counts
+    self._use_freeform_filter = use_freeform_filter
 
   def create_as_dict(self, values_and_counts_dict=None):
     """Creates the header for this column, in dictionary form.
@@ -58,10 +60,11 @@
         KEY__EXTRACOLUMNHEADERS__HEADER_TEXT: self._header_text,
         KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE: self._is_filterable,
         KEY__EXTRACOLUMNHEADERS__IS_SORTABLE: self._is_sortable,
+        KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER: self._use_freeform_filter,
     }
     if self._header_url:
       asdict[KEY__EXTRACOLUMNHEADERS__HEADER_URL] = self._header_url
-    if self._include_values_and_counts and values_and_counts_dict:
+    if values_and_counts_dict:
       asdict[KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS] = sorted(
           values_and_counts_dict.items())
     return asdict
diff --git a/gm/rebaseline_server/compare_configs.py b/gm/rebaseline_server/compare_configs.py
index 4075da4..36c7f86 100755
--- a/gm/rebaseline_server/compare_configs.py
+++ b/gm/rebaseline_server/compare_configs.py
@@ -11,15 +11,14 @@
 
 # System-level imports
 import argparse
-import fnmatch
-import json
 import logging
-import re
 import time
 
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
+
 # Imports from within Skia
-import fix_pythonpath  # must do this first
-from pyutils import url_utils
+from py.utils import url_utils
 import gm_json
 import imagediffdb
 import imagepair
@@ -49,6 +48,7 @@
       builder_regex_list: List of regular expressions specifying which builders
           we will process. If None, process all builders.
     """
+    super(ConfigComparisons, self).__init__()
     time_start = int(time.time())
     if builder_regex_list != None:
       self.set_match_builders_pattern_list(builder_regex_list)
@@ -112,7 +112,7 @@
 
         tests_found = set()
         for image_name in sorted(results_of_this_type.keys()):
-          (test, config) = results.IMAGE_FILENAME_RE.match(image_name).groups()
+          (test, _) = results.IMAGE_FILENAME_RE.match(image_name).groups()
           tests_found.add(test)
 
         for test in tests_found:
@@ -151,7 +151,8 @@
             try:
               image_pair = imagepair.ImagePair(
                   image_diff_db=self._image_diff_db,
-                  base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
+                  imageA_base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
+                  imageB_base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
                   imageA_relative_url=configA_image_relative_url,
                   imageB_relative_url=configB_image_relative_url,
                   extra_columns=extra_columns_dict)
@@ -160,9 +161,10 @@
                 failing_image_pairs.add_image_pair(image_pair)
             except (KeyError, TypeError):
               logging.exception(
-                  'got exception while creating ImagePair for image_name '
-                  '"%s", builder "%s"' % (image_name, builder))
+                  'got exception while creating ImagePair for test '
+                  '"%s", builder "%s"' % (test, builder))
 
+    # pylint: disable=W0201
     self._results = {
       results.KEY__HEADER__RESULTS_ALL: all_image_pairs.as_dict(),
       results.KEY__HEADER__RESULTS_FAILURES: failing_image_pairs.as_dict(),
diff --git a/gm/rebaseline_server/compare_configs_test.py b/gm/rebaseline_server/compare_configs_test.py
index 756af66..612be99 100755
--- a/gm/rebaseline_server/compare_configs_test.py
+++ b/gm/rebaseline_server/compare_configs_test.py
@@ -10,22 +10,25 @@
 
 TODO(epoger): Create a command to update the expected results (in
 self._output_dir_expected) when appropriate.  For now, you should:
-1. examine the results in self._output_dir_actual and make sure they are ok
+1. examine the results in self.output_dir_actual and make sure they are ok
 2. rm -rf self._output_dir_expected
-3. mv self._output_dir_actual self._output_dir_expected
+3. mv self.output_dir_actual self._output_dir_expected
 Although, if you're using an SVN checkout, this will blow away .svn directories
 within self._output_dir_expected, which wouldn't be good...
 
 """
 
+# System-level imports
 import os
-import sys
+
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
 
 # Imports from within Skia
 import base_unittest
 import compare_configs
+import gm_json
 import results
-import gm_json  # must import results first, so that gm_json will be in sys.path
 
 
 class CompareConfigsTest(base_unittest.TestCase):
@@ -34,14 +37,14 @@
     """Process results of a GM run with the ConfigComparisons object."""
     results_obj = compare_configs.ConfigComparisons(
         configs=('8888', 'gpu'),
-        actuals_root=os.path.join(self._input_dir, 'gm-actuals'),
-        generated_images_root=self._temp_dir,
+        actuals_root=os.path.join(self.input_dir, 'gm-actuals'),
+        generated_images_root=self.temp_dir,
         diff_base_url='/static/generated-images')
     results_obj.get_timestamp = mock_get_timestamp
     gm_json.WriteToFile(
         results_obj.get_packaged_results_of_type(
             results.KEY__HEADER__RESULTS_ALL),
-        os.path.join(self._output_dir_actual, 'gm.json'))
+        os.path.join(self.output_dir_actual, 'gm.json'))
 
 
 def mock_get_timestamp():
diff --git a/gm/rebaseline_server/compare_rendered_pictures.py b/gm/rebaseline_server/compare_rendered_pictures.py
index 73d0627..73cb36b 100755
--- a/gm/rebaseline_server/compare_rendered_pictures.py
+++ b/gm/rebaseline_server/compare_rendered_pictures.py
@@ -7,17 +7,28 @@
 found in the LICENSE file.
 
 Compare results of two render_pictures runs.
+
+TODO(epoger): Start using this module to compare ALL images (whether they
+were generated from GMs or SKPs), and rename it accordingly.
 """
 
 # System-level imports
 import logging
 import os
-import re
+import shutil
+import subprocess
+import tempfile
 import time
 
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
+
 # Imports from within Skia
-import fix_pythonpath  # must do this first
-from pyutils import url_utils
+from py.utils import git_utils
+from py.utils import gs_utils
+from py.utils import url_utils
+import buildbot_globals
+import column
 import gm_json
 import imagediffdb
 import imagepair
@@ -25,148 +36,340 @@
 import results
 
 # URL under which all render_pictures images can be found in Google Storage.
-# TODO(epoger): Move this default value into
-# https://skia.googlesource.com/buildbot/+/master/site_config/global_variables.json
-DEFAULT_IMAGE_BASE_URL = 'http://chromium-skia-gm.commondatastorage.googleapis.com/render_pictures/images'
+#
+# TODO(epoger): In order to allow live-view of GMs and other images, read this
+# from the input summary files, or allow the caller to set it within the
+# GET_live_results call.
+DEFAULT_IMAGE_BASE_GS_URL = 'gs://' + buildbot_globals.Get('skp_images_bucket')
+
+# Column descriptors, and display preferences for them.
+COLUMN__RESULT_TYPE = results.KEY__EXTRACOLUMNS__RESULT_TYPE
+COLUMN__SOURCE_SKP = 'sourceSkpFile'
+COLUMN__TILED_OR_WHOLE = 'tiledOrWhole'
+COLUMN__TILENUM = 'tilenum'
+COLUMN__BUILDER_A = 'builderA'
+COLUMN__RENDER_MODE_A = 'renderModeA'
+COLUMN__BUILDER_B = 'builderB'
+COLUMN__RENDER_MODE_B = 'renderModeB'
+# Known values for some of those columns.
+COLUMN__TILED_OR_WHOLE__TILED = 'tiled'
+COLUMN__TILED_OR_WHOLE__WHOLE = 'whole'
+
+FREEFORM_COLUMN_IDS = [
+    COLUMN__SOURCE_SKP,
+    COLUMN__TILENUM,
+]
+ORDERED_COLUMN_IDS = [
+    COLUMN__RESULT_TYPE,
+    COLUMN__SOURCE_SKP,
+    COLUMN__TILED_OR_WHOLE,
+    COLUMN__TILENUM,
+    COLUMN__BUILDER_A,
+    COLUMN__RENDER_MODE_A,
+    COLUMN__BUILDER_B,
+    COLUMN__RENDER_MODE_B,
+]
+
+# A special "repo:" URL type that we use to refer to Skia repo contents.
+# (Useful for comparing against expectations files we store in our repo.)
+REPO_URL_PREFIX = 'repo:'
+REPO_BASEPATH = os.path.abspath(os.path.join(
+    os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir))
+
+# Which sections within a JSON summary file can contain results.
+ALLOWED_SECTION_NAMES = [
+    gm_json.JSONKEY_ACTUALRESULTS,
+    gm_json.JSONKEY_EXPECTEDRESULTS,
+]
 
 
 class RenderedPicturesComparisons(results.BaseComparisons):
-  """Loads results from two different render_pictures runs into an ImagePairSet.
+  """Loads results from multiple render_pictures runs into an ImagePairSet.
   """
 
-  def __init__(self, subdirs, actuals_root,
-               generated_images_root=results.DEFAULT_GENERATED_IMAGES_ROOT,
-               image_base_url=DEFAULT_IMAGE_BASE_URL,
-               diff_base_url=None):
-    """
+  def __init__(self,
+               setA_dir, setB_dir,
+               setA_section, setB_section,
+               image_diff_db,
+               image_base_gs_url=DEFAULT_IMAGE_BASE_GS_URL, diff_base_url=None,
+               setA_label=None, setB_label=None,
+               gs=None, truncate_results=False, prefetch_only=False,
+               download_all_images=False):
+    """Constructor: downloads images and generates diffs.
+
+    Once the object has been created (which may take a while), you can call its
+    get_packaged_results_of_type() method to quickly retrieve the results...
+    unless you have set prefetch_only to True, in which case we will
+    asynchronously warm up the ImageDiffDB cache but not fill in self._results.
+
     Args:
-      actuals_root: root directory containing all render_pictures-generated
-          JSON files
-      subdirs: (string, string) tuple; pair of subdirectories within
-          actuals_root to compare
-      generated_images_root: directory within which to create all pixel diffs;
-          if this directory does not yet exist, it will be created
-      image_base_url: URL under which all render_pictures result images can
+      setA_dir: root directory to copy all JSON summaries from, and to use as
+          setA within the comparisons. This directory may be specified as a
+          gs:// URL, special "repo:" URL, or local filepath.
+      setB_dir: root directory to copy all JSON summaries from, and to use as
+          setB within the comparisons. This directory may be specified as a
+          gs:// URL, special "repo:" URL, or local filepath.
+      setA_section: which section within setA to examine; must be one of
+          ALLOWED_SECTION_NAMES
+      setB_section: which section within setB to examine; must be one of
+          ALLOWED_SECTION_NAMES
+      image_diff_db: ImageDiffDB instance
+      image_base_gs_url: "gs://" URL pointing at the Google Storage bucket/dir
+          under which all render_pictures result images can
           be found; this will be used to read images for comparison within
-          this code, and included in the ImagePairSet so its consumers know
-          where to download the images from
+          this code, and included in the ImagePairSet (as an HTTP URL) so its
+          consumers know where to download the images from
       diff_base_url: base URL within which the client should look for diff
           images; if not specified, defaults to a "file:///" URL representation
-          of generated_images_root
+          of image_diff_db's storage_root
+      setA_label: description to use for results in setA; if None, will be
+          set to a reasonable default
+      setB_label: description to use for results in setB; if None, will be
+          set to a reasonable default
+      gs: instance of GSUtils object we can use to download summary files
+      truncate_results: FOR MANUAL TESTING: if True, truncate the set of images
+          we process, to speed up testing.
+      prefetch_only: if True, return the new object as quickly as possible
+          with empty self._results (just queue up all the files to process,
+          don't wait around for them to be processed and recorded); otherwise,
+          block until the results have been assembled and recorded in
+          self._results.
+      download_all_images: if True, download all images, even if we don't
+          need them to generate diffs.  This will take much longer to complete,
+          but is useful for warming up the bitmap cache on local disk.
     """
-    time_start = int(time.time())
-    self._image_diff_db = imagediffdb.ImageDiffDB(generated_images_root)
-    self._image_base_url = image_base_url
+    super(RenderedPicturesComparisons, self).__init__()
+    self._image_diff_db = image_diff_db
+    self._image_base_gs_url = image_base_gs_url
     self._diff_base_url = (
         diff_base_url or
-        url_utils.create_filepath_url(generated_images_root))
-    self._load_result_pairs(actuals_root, subdirs)
-    self._timestamp = int(time.time())
-    logging.info('Results complete; took %d seconds.' %
-                 (self._timestamp - time_start))
+        url_utils.create_filepath_url(image_diff_db.storage_root))
+    self._gs = gs
+    self.truncate_results = truncate_results
+    self._prefetch_only = prefetch_only
+    self._download_all_images = download_all_images
 
-  def _load_result_pairs(self, actuals_root, subdirs):
-    """Loads all JSON files found within two subdirs in actuals_root,
-    compares across those two subdirs, and stores the summary in self._results.
+    # If we are comparing two different section types, we can use those
+    # as the default labels for setA and setB.
+    if setA_section != setB_section:
+      self._setA_label = setA_label or setA_section
+      self._setB_label = setB_label or setB_section
+    else:
+      self._setA_label = setA_label or 'setA'
+      self._setB_label = setB_label or 'setB'
+
+    tempdir = tempfile.mkdtemp()
+    try:
+      setA_root = os.path.join(tempdir, 'setA')
+      setB_root = os.path.join(tempdir, 'setB')
+      # TODO(stephana): There is a potential race condition here... we copy
+      # the contents out of the source_dir, and THEN we get the commithash
+      # of source_dir.  If source_dir points at a git checkout, and that
+      # checkout is updated (by a different thread/process) during this
+      # operation, then the contents and commithash will be out of sync.
+      self._copy_dir_contents(source_dir=setA_dir, dest_dir=setA_root)
+      setA_repo_revision = self._get_repo_revision(source_dir=setA_dir)
+      self._copy_dir_contents(source_dir=setB_dir, dest_dir=setB_root)
+      setB_repo_revision = self._get_repo_revision(source_dir=setB_dir)
+
+      self._setA_descriptions = {
+          results.KEY__SET_DESCRIPTIONS__DIR: setA_dir,
+          results.KEY__SET_DESCRIPTIONS__REPO_REVISION: setA_repo_revision,
+          results.KEY__SET_DESCRIPTIONS__SECTION: setA_section,
+      }
+      self._setB_descriptions = {
+          results.KEY__SET_DESCRIPTIONS__DIR: setB_dir,
+          results.KEY__SET_DESCRIPTIONS__REPO_REVISION: setB_repo_revision,
+          results.KEY__SET_DESCRIPTIONS__SECTION: setB_section,
+      }
+
+      time_start = int(time.time())
+      self._results = self._load_result_pairs(
+          setA_root=setA_root, setB_root=setB_root,
+          setA_section=setA_section, setB_section=setB_section)
+      if self._results:
+        self._timestamp = int(time.time())
+        logging.info('Number of download file collisions: %s' %
+                     imagediffdb.global_file_collisions)
+        logging.info('Results complete; took %d seconds.' %
+                     (self._timestamp - time_start))
+    finally:
+      shutil.rmtree(tempdir)
+
+  def _load_result_pairs(self, setA_root, setB_root,
+                         setA_section, setB_section):
+    """Loads all JSON image summaries from 2 directory trees and compares them.
+
+    TODO(stephana): This method is only called from within __init__(); it might
+    make more sense to just roll the content of this method into __init__().
 
     Args:
-      actuals_root: root directory containing all render_pictures-generated
-          JSON files
-      subdirs: (string, string) tuple; pair of subdirectories within
-          actuals_root to compare
+      setA_root: root directory containing JSON summaries of rendering results
+      setB_root: root directory containing JSON summaries of rendering results
+      setA_section: which section (gm_json.JSONKEY_ACTUALRESULTS or
+          gm_json.JSONKEY_EXPECTEDRESULTS) to load from the summaries in setA
+      setB_section: which section (gm_json.JSONKEY_ACTUALRESULTS or
+          gm_json.JSONKEY_EXPECTEDRESULTS) to load from the summaries in setB
+
+    Returns the summary of all image diff results (or None, depending on
+    self._prefetch_only).
     """
-    logging.info(
-        'Reading actual-results JSON files from %s subdirs within %s...' % (
-            subdirs, actuals_root))
-    subdirA, subdirB = subdirs
-    subdirA_dicts = self._read_dicts_from_root(
-        os.path.join(actuals_root, subdirA))
-    subdirB_dicts = self._read_dicts_from_root(
-        os.path.join(actuals_root, subdirB))
-    logging.info('Comparing subdirs %s and %s...' % (subdirA, subdirB))
+    logging.info('Reading JSON image summaries from dirs %s and %s...' % (
+        setA_root, setB_root))
+    setA_dicts = self.read_dicts_from_root(setA_root)
+    setB_dicts = self.read_dicts_from_root(setB_root)
+    logging.info('Comparing summary dicts...')
 
     all_image_pairs = imagepairset.ImagePairSet(
-        descriptions=subdirs,
+        descriptions=(self._setA_label, self._setB_label),
         diff_base_url=self._diff_base_url)
     failing_image_pairs = imagepairset.ImagePairSet(
-        descriptions=subdirs,
+        descriptions=(self._setA_label, self._setB_label),
         diff_base_url=self._diff_base_url)
 
+    # Override settings for columns that should be filtered using freeform text.
+    for column_id in FREEFORM_COLUMN_IDS:
+      factory = column.ColumnHeaderFactory(
+          header_text=column_id, use_freeform_filter=True)
+      all_image_pairs.set_column_header_factory(
+          column_id=column_id, column_header_factory=factory)
+      failing_image_pairs.set_column_header_factory(
+          column_id=column_id, column_header_factory=factory)
+
     all_image_pairs.ensure_extra_column_values_in_summary(
-        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
+        column_id=COLUMN__RESULT_TYPE, values=[
             results.KEY__RESULT_TYPE__FAILED,
             results.KEY__RESULT_TYPE__NOCOMPARISON,
             results.KEY__RESULT_TYPE__SUCCEEDED,
         ])
     failing_image_pairs.ensure_extra_column_values_in_summary(
-        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
+        column_id=COLUMN__RESULT_TYPE, values=[
             results.KEY__RESULT_TYPE__FAILED,
             results.KEY__RESULT_TYPE__NOCOMPARISON,
         ])
 
-    common_dict_paths = sorted(set(subdirA_dicts.keys() + subdirB_dicts.keys()))
-    num_common_dict_paths = len(common_dict_paths)
+    logging.info('Starting to add imagepairs to queue.')
+    self._image_diff_db.log_queue_size_if_changed(limit_verbosity=False)
+
+    union_dict_paths = sorted(set(setA_dicts.keys() + setB_dicts.keys()))
+    num_union_dict_paths = len(union_dict_paths)
     dict_num = 0
-    for dict_path in common_dict_paths:
+    for dict_path in union_dict_paths:
       dict_num += 1
-      logging.info('Generating pixel diffs for dict #%d of %d, "%s"...' %
-                   (dict_num, num_common_dict_paths, dict_path))
-      dictA = subdirA_dicts[dict_path]
-      dictB = subdirB_dicts[dict_path]
+      logging.info(
+          'Asynchronously requesting pixel diffs for dict #%d of %d, "%s"...' %
+          (dict_num, num_union_dict_paths, dict_path))
+
+      dictA = self.get_default(setA_dicts, None, dict_path)
       self._validate_dict_version(dictA)
+      dictA_results = self.get_default(dictA, {}, setA_section)
+
+      dictB = self.get_default(setB_dicts, None, dict_path)
       self._validate_dict_version(dictB)
-      dictA_results = dictA[gm_json.JSONKEY_ACTUALRESULTS]
-      dictB_results = dictB[gm_json.JSONKEY_ACTUALRESULTS]
+      dictB_results = self.get_default(dictB, {}, setB_section)
+
+      image_A_base_url = self.get_default(
+          setA_dicts, self._image_base_gs_url, dict_path,
+          gm_json.JSONKEY_IMAGE_BASE_GS_URL)
+      image_B_base_url = self.get_default(
+          setB_dicts, self._image_base_gs_url, dict_path,
+          gm_json.JSONKEY_IMAGE_BASE_GS_URL)
+
+      # get the builders and render modes for each set
+      builder_A     = self.get_default(dictA, None,
+                        gm_json.JSONKEY_DESCRIPTIONS,
+                        gm_json.JSONKEY_DESCRIPTIONS_BUILDER)
+      render_mode_A = self.get_default(dictA, None,
+                        gm_json.JSONKEY_DESCRIPTIONS,
+                        gm_json.JSONKEY_DESCRIPTIONS_RENDER_MODE)
+      builder_B     = self.get_default(dictB, None,
+                        gm_json.JSONKEY_DESCRIPTIONS,
+                        gm_json.JSONKEY_DESCRIPTIONS_BUILDER)
+      render_mode_B = self.get_default(dictB, None,
+                        gm_json.JSONKEY_DESCRIPTIONS,
+                        gm_json.JSONKEY_DESCRIPTIONS_RENDER_MODE)
+
       skp_names = sorted(set(dictA_results.keys() + dictB_results.keys()))
+      # Just for manual testing... truncate to an arbitrary subset.
+      if self.truncate_results:
+        skp_names = skp_names[1:3]
       for skp_name in skp_names:
         imagepairs_for_this_skp = []
 
-        whole_image_A = RenderedPicturesComparisons.get_multilevel(
-            dictA_results, skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE)
-        whole_image_B = RenderedPicturesComparisons.get_multilevel(
-            dictB_results, skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE)
-        imagepairs_for_this_skp.append(self._create_image_pair(
-            test=skp_name, config=gm_json.JSONKEY_SOURCE_WHOLEIMAGE,
-            image_dict_A=whole_image_A, image_dict_B=whole_image_B))
+        whole_image_A = self.get_default(
+            dictA_results, None,
+            skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE)
+        whole_image_B = self.get_default(
+            dictB_results, None,
+            skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE)
 
-        tiled_images_A = RenderedPicturesComparisons.get_multilevel(
-            dictA_results, skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES)
-        tiled_images_B = RenderedPicturesComparisons.get_multilevel(
-            dictB_results, skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES)
-        # TODO(epoger): Report an error if we find tiles for A but not B?
-        if tiled_images_A and tiled_images_B:
-          # TODO(epoger): Report an error if we find a different number of tiles
-          # for A and B?
-          num_tiles = len(tiled_images_A)
+        imagepairs_for_this_skp.append(self._create_image_pair(
+            image_dict_A=whole_image_A, image_dict_B=whole_image_B,
+            image_A_base_url=image_A_base_url,
+            image_B_base_url=image_B_base_url,
+            builder_A=builder_A, render_mode_A=render_mode_A,
+            builder_B=builder_B, render_mode_B=render_mode_B,
+            source_json_file=dict_path,
+            source_skp_name=skp_name, tilenum=None))
+
+        tiled_images_A = self.get_default(
+            dictA_results, [],
+            skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES)
+        tiled_images_B = self.get_default(
+            dictB_results, [],
+            skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES)
+        if tiled_images_A or tiled_images_B:
+          num_tiles_A = len(tiled_images_A)
+          num_tiles_B = len(tiled_images_B)
+          num_tiles = max(num_tiles_A, num_tiles_B)
           for tile_num in range(num_tiles):
             imagepairs_for_this_skp.append(self._create_image_pair(
-                test=skp_name,
-                config='%s-%d' % (gm_json.JSONKEY_SOURCE_TILEDIMAGES, tile_num),
-                image_dict_A=tiled_images_A[tile_num],
-                image_dict_B=tiled_images_B[tile_num]))
+                image_dict_A=(tiled_images_A[tile_num]
+                              if tile_num < num_tiles_A else None),
+                image_dict_B=(tiled_images_B[tile_num]
+                              if tile_num < num_tiles_B else None),
+                image_A_base_url=image_A_base_url,
+                image_B_base_url=image_B_base_url,
+                builder_A=builder_A, render_mode_A=render_mode_A,
+                builder_B=builder_B, render_mode_B=render_mode_B,
+                source_json_file=dict_path,
+                source_skp_name=skp_name, tilenum=tile_num))
 
-        for imagepair in imagepairs_for_this_skp:
-          if imagepair:
-            all_image_pairs.add_image_pair(imagepair)
-            result_type = imagepair.extra_columns_dict\
-                [results.KEY__EXTRACOLUMNS__RESULT_TYPE]
+        for one_imagepair in imagepairs_for_this_skp:
+          if one_imagepair:
+            all_image_pairs.add_image_pair(one_imagepair)
+            result_type = one_imagepair.extra_columns_dict\
+                [COLUMN__RESULT_TYPE]
             if result_type != results.KEY__RESULT_TYPE__SUCCEEDED:
-              failing_image_pairs.add_image_pair(imagepair)
+              failing_image_pairs.add_image_pair(one_imagepair)
 
-    self._results = {
-      results.KEY__HEADER__RESULTS_ALL: all_image_pairs.as_dict(),
-      results.KEY__HEADER__RESULTS_FAILURES: failing_image_pairs.as_dict(),
-    }
+    logging.info('Finished adding imagepairs to queue.')
+    self._image_diff_db.log_queue_size_if_changed(limit_verbosity=False)
+
+    if self._prefetch_only:
+      return None
+    else:
+      return {
+          results.KEY__HEADER__RESULTS_ALL: all_image_pairs.as_dict(
+              column_ids_in_order=ORDERED_COLUMN_IDS),
+          results.KEY__HEADER__RESULTS_FAILURES: failing_image_pairs.as_dict(
+              column_ids_in_order=ORDERED_COLUMN_IDS),
+      }
 
   def _validate_dict_version(self, result_dict):
     """Raises Exception if the dict is not the type/version we know how to read.
 
     Args:
-      result_dict: dictionary holding output of render_pictures
+      result_dict: dictionary holding output of render_pictures; if None,
+          this method will return without raising an Exception
     """
+    # TODO(stephana): These values should be defined as constants somewhere,
+    # to be kept in sync between this file and writable_expectations.py
     expected_header_type = 'ChecksummedImages'
     expected_header_revision = 1
 
+    if result_dict == None:
+      return
     header = result_dict[gm_json.JSONKEY_HEADER]
     header_type = header[gm_json.JSONKEY_HEADER_TYPE]
     if header_type != expected_header_type:
@@ -177,14 +380,29 @@
       raise Exception('expected header_revision %d, but got %d' % (
           expected_header_revision, header_revision))
 
-  def _create_image_pair(self, test, config, image_dict_A, image_dict_B):
+  def _create_image_pair(self, image_dict_A, image_dict_B,
+                         image_A_base_url, image_B_base_url,
+                         builder_A, render_mode_A,
+                         builder_B, render_mode_B,
+                         source_json_file,
+                         source_skp_name, tilenum):
     """Creates an ImagePair object for this pair of images.
 
     Args:
-      test: string; name of the test
-      config: string; name of the config
       image_dict_A: dict with JSONKEY_IMAGE_* keys, or None if no image
       image_dict_B: dict with JSONKEY_IMAGE_* keys, or None if no image
+      image_A_base_url: base URL for image A
+      image_B_base_url: base URL for image B
+      builder_A: builder that created image set A or None if unknow
+      render_mode_A: render mode used to generate image set A or None if
+                     unknown.
+      builder_B: builder that created image set A or None if unknow
+      render_mode_B: render mode used to generate image set A or None if
+                     unknown.
+      source_json_file: string; relative path of the JSON file where this
+                        result came from, within setA and setB.
+      source_skp_name: string; name of the source SKP file
+      tilenum: which tile, or None if a wholeimage
 
     Returns:
       An ImagePair object, or None if both image_dict_A and image_dict_B are
@@ -196,7 +414,7 @@
     def _checksum_and_relative_url(dic):
       if dic:
         return ((dic[gm_json.JSONKEY_IMAGE_CHECKSUMALGORITHM],
-                 dic[gm_json.JSONKEY_IMAGE_CHECKSUMVALUE]),
+                 int(dic[gm_json.JSONKEY_IMAGE_CHECKSUMVALUE])),
                 dic[gm_json.JSONKEY_IMAGE_FILEPATH])
       else:
         return None, None
@@ -216,28 +434,71 @@
       result_type = results.KEY__RESULT_TYPE__FAILED
 
     extra_columns_dict = {
-        results.KEY__EXTRACOLUMNS__CONFIG: config,
-        results.KEY__EXTRACOLUMNS__RESULT_TYPE: result_type,
-        results.KEY__EXTRACOLUMNS__TEST: test,
-        # TODO(epoger): Right now, the client UI crashes if it receives
-        # results that do not include this column.
-        # Until we fix that, keep the client happy.
-        results.KEY__EXTRACOLUMNS__BUILDER: 'TODO',
+        COLUMN__RESULT_TYPE: result_type,
+        COLUMN__SOURCE_SKP: source_skp_name,
+        COLUMN__BUILDER_A: builder_A,
+        COLUMN__RENDER_MODE_A: render_mode_A,
+        COLUMN__BUILDER_B: builder_B,
+        COLUMN__RENDER_MODE_B: render_mode_B,
     }
+    if tilenum == None:
+      extra_columns_dict[COLUMN__TILED_OR_WHOLE] = COLUMN__TILED_OR_WHOLE__WHOLE
+      extra_columns_dict[COLUMN__TILENUM] = 'N/A'
+    else:
+      extra_columns_dict[COLUMN__TILED_OR_WHOLE] = COLUMN__TILED_OR_WHOLE__TILED
+      extra_columns_dict[COLUMN__TILENUM] = str(tilenum)
 
     try:
       return imagepair.ImagePair(
           image_diff_db=self._image_diff_db,
-          base_url=self._image_base_url,
+          imageA_base_url=image_A_base_url,
+          imageB_base_url=image_B_base_url,
           imageA_relative_url=imageA_relative_url,
           imageB_relative_url=imageB_relative_url,
-          extra_columns=extra_columns_dict)
+          extra_columns=extra_columns_dict,
+          source_json_file=source_json_file,
+          download_all_images=self._download_all_images)
     except (KeyError, TypeError):
       logging.exception(
           'got exception while creating ImagePair for'
-          ' test="%s", config="%s", urlPair=("%s","%s")' % (
-              test, config, imageA_relative_url, imageB_relative_url))
+          ' urlPair=("%s","%s"), source_skp_name="%s", tilenum="%s"' % (
+              imageA_relative_url, imageB_relative_url, source_skp_name,
+              tilenum))
       return None
 
+  def _copy_dir_contents(self, source_dir, dest_dir):
+    """Copy all contents of source_dir into dest_dir, recursing into subdirs.
 
-# TODO(epoger): Add main() so this can be called by vm_run_skia_try.sh
+    Args:
+      source_dir: path to source dir (GS URL, local filepath, or a special
+          "repo:" URL type that points at a file within our Skia checkout)
+      dest_dir: path to destination dir (local filepath)
+
+    The copy operates as a "merge with overwrite": any files in source_dir will
+    be "overlaid" on top of the existing content in dest_dir.  Existing files
+    with the same names will be overwritten.
+    """
+    if gs_utils.GSUtils.is_gs_url(source_dir):
+      (bucket, path) = gs_utils.GSUtils.split_gs_url(source_dir)
+      self._gs.download_dir_contents(source_bucket=bucket, source_dir=path,
+                                     dest_dir=dest_dir)
+    elif source_dir.lower().startswith(REPO_URL_PREFIX):
+      repo_dir = os.path.join(REPO_BASEPATH, source_dir[len(REPO_URL_PREFIX):])
+      shutil.copytree(repo_dir, dest_dir)
+    else:
+      shutil.copytree(source_dir, dest_dir)
+
+  def _get_repo_revision(self, source_dir):
+    """Get the commit hash of source_dir, IF it refers to a git checkout.
+
+    Args:
+      source_dir: path to source dir (GS URL, local filepath, or a special
+          "repo:" URL type that points at a file within our Skia checkout;
+          only the "repo:" URL type will have a commit hash.
+    """
+    if source_dir.lower().startswith(REPO_URL_PREFIX):
+      repo_dir = os.path.join(REPO_BASEPATH, source_dir[len(REPO_URL_PREFIX):])
+      return subprocess.check_output(
+          args=[git_utils.GIT, 'rev-parse', 'HEAD'], cwd=repo_dir).strip()
+    else:
+      return None
diff --git a/gm/rebaseline_server/compare_rendered_pictures_test.py b/gm/rebaseline_server/compare_rendered_pictures_test.py
index e6d2574..2b15462 100755
--- a/gm/rebaseline_server/compare_rendered_pictures_test.py
+++ b/gm/rebaseline_server/compare_rendered_pictures_test.py
@@ -10,23 +10,30 @@
 
 TODO(epoger): Create a command to update the expected results (in
 self._output_dir_expected) when appropriate.  For now, you should:
-1. examine the results in self._output_dir_actual and make sure they are ok
+1. examine the results in self.output_dir_actual and make sure they are ok
 2. rm -rf self._output_dir_expected
-3. mv self._output_dir_actual self._output_dir_expected
+3. mv self.output_dir_actual self._output_dir_expected
 Although, if you're using an SVN checkout, this will blow away .svn directories
 within self._output_dir_expected, which wouldn't be good...
 
 """
 
+# System-level imports
 import os
+import posixpath
 import subprocess
-import sys
+
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
 
 # Imports from within Skia
 import base_unittest
 import compare_rendered_pictures
+import find_run_binary
+import gm_json
+import imagediffdb
+import imagepairset
 import results
-import gm_json  # must import results first, so that gm_json will be in sys.path
 
 
 class CompareRenderedPicturesTest(base_unittest.TestCase):
@@ -34,39 +41,137 @@
   def test_endToEnd(self):
     """Generate two sets of SKPs, run render_pictures over both, and compare
     the results."""
+    setA_subdir = 'before_patch'
+    setB_subdir = 'after_patch'
     self._generate_skps_and_run_render_pictures(
-        subdir='before_patch', skpdict={
+        subdir=setA_subdir, skpdict={
             'changed.skp': 200,
             'unchanged.skp': 100,
             'only-in-before.skp': 128,
         })
     self._generate_skps_and_run_render_pictures(
-        subdir='after_patch', skpdict={
+        subdir=setB_subdir, skpdict={
             'changed.skp': 201,
             'unchanged.skp': 100,
             'only-in-after.skp': 128,
         })
 
     results_obj = compare_rendered_pictures.RenderedPicturesComparisons(
-        actuals_root=self._temp_dir,
-        subdirs=('before_patch', 'after_patch'),
-        generated_images_root=self._temp_dir,
+        setA_dir=os.path.join(self.temp_dir, setA_subdir),
+        setB_dir=os.path.join(self.temp_dir, setB_subdir),
+        setA_section=gm_json.JSONKEY_ACTUALRESULTS,
+        setB_section=gm_json.JSONKEY_ACTUALRESULTS,
+        image_diff_db=imagediffdb.ImageDiffDB(self.temp_dir),
+        image_base_gs_url='gs://fakebucket/fake/path',
         diff_base_url='/static/generated-images')
     results_obj.get_timestamp = mock_get_timestamp
 
+    # Overwrite elements within the results that change from one test run
+    # to the next.
+    # pylint: disable=W0212
+    results_obj._setA_descriptions[results.KEY__SET_DESCRIPTIONS__DIR] = [
+        'before-patch-fake-dir']
+    results_obj._setB_descriptions[results.KEY__SET_DESCRIPTIONS__DIR] = [
+        'after-patch-fake-dir']
+
     gm_json.WriteToFile(
         results_obj.get_packaged_results_of_type(
             results.KEY__HEADER__RESULTS_ALL),
-        os.path.join(self._output_dir_actual, 'compare_rendered_pictures.json'))
+        os.path.join(self.output_dir_actual, 'compare_rendered_pictures.json'))
 
-  def _generate_skps_and_run_render_pictures(self, subdir, skpdict):
+  def test_endToEnd_withImageBaseGSUrl(self):
+    """Generate two sets of SKPs, run render_pictures over both, and compare
+    the results."""
+    setA_subdir = 'before_patch'
+    setB_subdir = 'after_patch'
+    imageA_gs_base = 'superman/kent-camera/pictures'
+    imageB_gs_base = 'batman/batarang/pictures'
+    self._generate_skps_and_run_render_pictures(
+        subdir=setA_subdir, skpdict={
+            'changed.skp': 200,
+            'unchanged.skp': 100,
+            'only-in-before.skp': 128,
+        },
+        image_base_gs_url='gs://%s' % imageA_gs_base)
+    self._generate_skps_and_run_render_pictures(
+        subdir=setB_subdir, skpdict={
+            'changed.skp': 201,
+            'unchanged.skp': 100,
+            'only-in-after.skp': 128,
+        },
+        image_base_gs_url='gs://%s' % imageB_gs_base)
+
+    results_obj = compare_rendered_pictures.RenderedPicturesComparisons(
+        setA_dir=os.path.join(self.temp_dir, setA_subdir),
+        setB_dir=os.path.join(self.temp_dir, setB_subdir),
+        setA_section=gm_json.JSONKEY_ACTUALRESULTS,
+        setB_section=gm_json.JSONKEY_ACTUALRESULTS,
+        image_diff_db=imagediffdb.ImageDiffDB(self.temp_dir),
+        image_base_gs_url='gs://fakebucket/fake/path',
+        diff_base_url='/static/generated-images')
+    results_obj.get_timestamp = mock_get_timestamp
+
+    output_dict = results_obj.get_packaged_results_of_type(
+        results.KEY__HEADER__RESULTS_ALL)
+    # Assert that the baseURLs are as expected.
+    self.assertEquals(
+        output_dict[imagepairset.KEY__ROOT__IMAGESETS]
+                   [imagepairset.KEY__IMAGESETS__SET__IMAGE_A]
+                   [imagepairset.KEY__IMAGESETS__FIELD__BASE_URL],
+        'http://storage.cloud.google.com/%s' % imageA_gs_base)
+    self.assertEquals(
+        output_dict[imagepairset.KEY__ROOT__IMAGESETS]
+                   [imagepairset.KEY__IMAGESETS__SET__IMAGE_B]
+                   [imagepairset.KEY__IMAGESETS__FIELD__BASE_URL],
+        'http://storage.cloud.google.com/%s' % imageB_gs_base)
+    # Overwrite elements within the results that change from one test run
+    # to the next.
+    # pylint: disable=W0212
+    results_obj._setA_descriptions[results.KEY__SET_DESCRIPTIONS__DIR] = [
+        'before-patch-fake-dir']
+    results_obj._setB_descriptions[results.KEY__SET_DESCRIPTIONS__DIR] = [
+        'after-patch-fake-dir']
+
+    gm_json.WriteToFile(
+        output_dict,
+        os.path.join(self.output_dir_actual,
+                               'compare_rendered_pictures.json'))
+
+  def test_repo_url(self):
+    """Use repo: URL to specify summary files."""
+    base_repo_url = 'repo:gm/rebaseline_server/testdata/inputs/skp-summaries'
+    results_obj = compare_rendered_pictures.RenderedPicturesComparisons(
+        setA_dir=posixpath.join(base_repo_url, 'expectations'),
+        setB_dir=posixpath.join(base_repo_url, 'actuals'),
+        setA_section=gm_json.JSONKEY_EXPECTEDRESULTS,
+        setB_section=gm_json.JSONKEY_ACTUALRESULTS,
+        image_diff_db=imagediffdb.ImageDiffDB(self.temp_dir),
+        image_base_gs_url='gs://fakebucket/fake/path',
+        diff_base_url='/static/generated-images')
+    results_obj.get_timestamp = mock_get_timestamp
+
+    # Overwrite elements within the results that change from one test run
+    # to the next.
+    # pylint: disable=W0212
+    results_obj._setA_descriptions\
+        [results.KEY__SET_DESCRIPTIONS__REPO_REVISION] = 'fake-repo-revision'
+    results_obj._setB_descriptions\
+        [results.KEY__SET_DESCRIPTIONS__REPO_REVISION] = 'fake-repo-revision'
+
+    gm_json.WriteToFile(
+        results_obj.get_packaged_results_of_type(
+            results.KEY__HEADER__RESULTS_ALL),
+        os.path.join(self.output_dir_actual, 'compare_rendered_pictures.json'))
+
+  def _generate_skps_and_run_render_pictures(self, subdir, skpdict,
+                                             image_base_gs_url=None):
     """Generate SKPs and run render_pictures on them.
 
     Args:
-      subdir: subdirectory (within self._temp_dir) to write all files into
+      subdir: subdirectory (within self.temp_dir) to write all files into
       skpdict: {skpname: redvalue} dictionary describing the SKP files to render
     """
-    out_path = os.path.join(self._temp_dir, subdir)
+    out_path = os.path.join(self.temp_dir, subdir)
     os.makedirs(out_path)
     for skpname, redvalue in skpdict.iteritems():
       self._run_skpmaker(
@@ -75,15 +180,17 @@
     # TODO(epoger): Add --mode tile 256 256 --writeWholeImage to the unittest,
     # and fix its result!  (imageURLs within whole-image entries are wrong when
     # I tried adding that)
-    binary = self.find_path_to_program('render_pictures')
-    return subprocess.check_output([
+    binary = find_run_binary.find_path_to_program('render_pictures')
+    render_pictures_cmd = [
         binary,
-        '--clone', '1',
         '--config', '8888',
         '-r', out_path,
         '--writeChecksumBasedFilenames',
         '--writeJsonSummaryPath', os.path.join(out_path, 'summary.json'),
-        '--writePath', out_path])
+        '--writePath', out_path]
+    if image_base_gs_url:
+      render_pictures_cmd.extend(['--imageBaseGSUrl', image_base_gs_url])
+    return subprocess.check_output(render_pictures_cmd)
 
   def _run_skpmaker(self, output_path, red=0, green=0, blue=0,
                     width=640, height=400):
@@ -97,7 +204,7 @@
       width: Width of canvas to create.
       height: Height of canvas to create.
     """
-    binary = self.find_path_to_program('skpmaker')
+    binary = find_run_binary.find_path_to_program('skpmaker')
     return subprocess.check_output([
         binary,
         '--red', str(red),
diff --git a/gm/rebaseline_server/compare_to_expectations.py b/gm/rebaseline_server/compare_to_expectations.py
index 1a93c66..303294c 100755
--- a/gm/rebaseline_server/compare_to_expectations.py
+++ b/gm/rebaseline_server/compare_to_expectations.py
@@ -12,16 +12,16 @@
 # System-level imports
 import argparse
 import fnmatch
-import json
 import logging
 import os
-import re
-import sys
 import time
 
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
+
 # Imports from within Skia
-import fix_pythonpath  # must do this first
-from pyutils import url_utils
+from py.utils import url_utils
+import column
 import gm_json
 import imagediffdb
 import imagepair
@@ -33,6 +33,17 @@
     results.KEY__EXPECTATIONS__IGNOREFAILURE,
     results.KEY__EXPECTATIONS__REVIEWED,
 ]
+FREEFORM_COLUMN_IDS = [
+    results.KEY__EXTRACOLUMNS__BUILDER,
+    results.KEY__EXTRACOLUMNS__TEST,
+]
+ORDERED_COLUMN_IDS = [
+    results.KEY__EXTRACOLUMNS__RESULT_TYPE,
+    results.KEY__EXTRACOLUMNS__BUILDER,
+    results.KEY__EXTRACOLUMNS__TEST,
+    results.KEY__EXTRACOLUMNS__CONFIG,
+]
+
 TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
 DEFAULT_EXPECTATIONS_DIR = os.path.join(TRUNK_DIRECTORY, 'expectations', 'gm')
 DEFAULT_IGNORE_FAILURES_FILE = 'ignored-tests.txt'
@@ -50,32 +61,31 @@
   are immutable.  If you want to update the results based on updated JSON
   file contents, you will need to create a new ExpectationComparisons object."""
 
-  def __init__(self, actuals_root=results.DEFAULT_ACTUALS_DIR,
+  def __init__(self, image_diff_db, actuals_root=results.DEFAULT_ACTUALS_DIR,
                expected_root=DEFAULT_EXPECTATIONS_DIR,
                ignore_failures_file=DEFAULT_IGNORE_FAILURES_FILE,
-               generated_images_root=results.DEFAULT_GENERATED_IMAGES_ROOT,
                diff_base_url=None, builder_regex_list=None):
     """
     Args:
+      image_diff_db: instance of ImageDiffDB we use to cache the image diffs
       actuals_root: root directory containing all actual-results.json files
       expected_root: root directory containing all expected-results.json files
       ignore_failures_file: if a file with this name is found within
           expected_root, ignore failures for any tests listed in the file
-      generated_images_root: directory within which to create all pixel diffs;
-          if this directory does not yet exist, it will be created
       diff_base_url: base URL within which the client should look for diff
           images; if not specified, defaults to a "file:///" URL representation
-          of generated_images_root
+          of image_diff_db's storage_root
       builder_regex_list: List of regular expressions specifying which builders
           we will process. If None, process all builders.
     """
+    super(ExpectationComparisons, self).__init__()
     time_start = int(time.time())
     if builder_regex_list != None:
       self.set_match_builders_pattern_list(builder_regex_list)
-    self._image_diff_db = imagediffdb.ImageDiffDB(generated_images_root)
+    self._image_diff_db = image_diff_db
     self._diff_base_url = (
         diff_base_url or
-        url_utils.create_filepath_url(generated_images_root))
+        url_utils.create_filepath_url(image_diff_db.storage_root))
     self._actuals_root = actuals_root
     self._expected_root = expected_root
     self._ignore_failures_on_these_tests = []
@@ -171,7 +181,7 @@
     if not os.path.isdir(root):
       raise IOError('no directory found at path %s' % root)
     actual_builders_written = []
-    for dirpath, dirnames, filenames in os.walk(root):
+    for dirpath, _, filenames in os.walk(root):
       for matching_filename in fnmatch.filter(filenames, pattern):
         builder = os.path.basename(dirpath)
         per_builder_dict = meta_dict.get(builder)
@@ -211,6 +221,15 @@
         descriptions=IMAGEPAIR_SET_DESCRIPTIONS,
         diff_base_url=self._diff_base_url)
 
+    # Override settings for columns that should be filtered using freeform text.
+    for column_id in FREEFORM_COLUMN_IDS:
+      factory = column.ColumnHeaderFactory(
+          header_text=column_id, use_freeform_filter=True)
+      all_image_pairs.set_column_header_factory(
+          column_id=column_id, column_header_factory=factory)
+      failing_image_pairs.set_column_header_factory(
+          column_id=column_id, column_header_factory=factory)
+
     all_image_pairs.ensure_extra_column_values_in_summary(
         column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
             results.KEY__RESULT_TYPE__FAILED,
@@ -328,7 +347,8 @@
           try:
             image_pair = imagepair.ImagePair(
                 image_diff_db=self._image_diff_db,
-                base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
+                imageA_base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
+                imageB_base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
                 imageA_relative_url=expected_image_relative_url,
                 imageB_relative_url=actual_image_relative_url,
                 expectations=expectations_dict,
@@ -339,9 +359,12 @@
           except Exception:
             logging.exception('got exception while creating new ImagePair')
 
+    # pylint: disable=W0201
     self._results = {
-      results.KEY__HEADER__RESULTS_ALL: all_image_pairs.as_dict(),
-      results.KEY__HEADER__RESULTS_FAILURES: failing_image_pairs.as_dict(),
+      results.KEY__HEADER__RESULTS_ALL: all_image_pairs.as_dict(
+          column_ids_in_order=ORDERED_COLUMN_IDS),
+      results.KEY__HEADER__RESULTS_FAILURES: failing_image_pairs.as_dict(
+          column_ids_in_order=ORDERED_COLUMN_IDS),
     }
 
 
@@ -377,11 +400,12 @@
       help='Directory within which to download images and generate diffs; '
       'defaults to \'%(default)s\' .')
   args = parser.parse_args()
+  image_diff_db = imagediffdb.ImageDiffDB(storage_root=args.workdir)
   results_obj = ExpectationComparisons(
+      image_diff_db=image_diff_db,
       actuals_root=args.actuals,
       expected_root=args.expectations,
-      ignore_failures_file=args.ignore_failures_file,
-      generated_images_root=args.workdir)
+      ignore_failures_file=args.ignore_failures_file)
   gm_json.WriteToFile(
       results_obj.get_packaged_results_of_type(results_type=args.results),
       args.outfile)
diff --git a/gm/rebaseline_server/compare_to_expectations_test.py b/gm/rebaseline_server/compare_to_expectations_test.py
index 76e4a7b..2997cde 100755
--- a/gm/rebaseline_server/compare_to_expectations_test.py
+++ b/gm/rebaseline_server/compare_to_expectations_test.py
@@ -10,20 +10,20 @@
 
 TODO(epoger): Create a command to update the expected results (in
 self._output_dir_expected) when appropriate.  For now, you should:
-1. examine the results in self._output_dir_actual and make sure they are ok
+1. examine the results in self.output_dir_actual and make sure they are ok
 2. rm -rf self._output_dir_expected
-3. mv self._output_dir_actual self._output_dir_expected
+3. mv self.output_dir_actual self._output_dir_expected
 Although, if you're using an SVN checkout, this will blow away .svn directories
 within self._output_dir_expected, which wouldn't be good...
 
 """
 
 import os
-import sys
 
 # Imports from within Skia
 import base_unittest
 import compare_to_expectations
+import imagediffdb
 import results
 import gm_json  # must import results first, so that gm_json will be in sys.path
 
@@ -32,16 +32,17 @@
 
   def test_gm(self):
     """Process results of a GM run with the ExpectationComparisons object."""
+    image_diff_db = imagediffdb.ImageDiffDB(storage_root=self.temp_dir)
     results_obj = compare_to_expectations.ExpectationComparisons(
-        actuals_root=os.path.join(self._input_dir, 'gm-actuals'),
-        expected_root=os.path.join(self._input_dir, 'gm-expectations'),
-        generated_images_root=self._temp_dir,
+        image_diff_db=image_diff_db,
+        actuals_root=os.path.join(self.input_dir, 'gm-actuals'),
+        expected_root=os.path.join(self.input_dir, 'gm-expectations'),
         diff_base_url='/static/generated-images')
     results_obj.get_timestamp = mock_get_timestamp
     gm_json.WriteToFile(
         results_obj.get_packaged_results_of_type(
             results.KEY__HEADER__RESULTS_ALL),
-        os.path.join(self._output_dir_actual, 'gm.json'))
+        os.path.join(self.output_dir_actual, 'gm.json'))
 
 
 def mock_get_timestamp():
diff --git a/gm/rebaseline_server/download_actuals.py b/gm/rebaseline_server/download_actuals.py
index 2f92898..c11f191 100755
--- a/gm/rebaseline_server/download_actuals.py
+++ b/gm/rebaseline_server/download_actuals.py
@@ -16,10 +16,12 @@
 import re
 import urllib2
 
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
+
 # Imports from within Skia
-import fix_pythonpath  # must do this first
-from pyutils import gs_utils
-from pyutils import url_utils
+from py.utils import gs_utils
+from py.utils import url_utils
 import buildbot_globals
 import gm_json
 
@@ -91,7 +93,7 @@
     summaries_bucket: Google Cloud Storage bucket containing the summary
         JSON files
   """
-  dirs, _ = gs_utils.list_bucket_contents(bucket=GM_SUMMARIES_BUCKET)
+  dirs, _ = gs_utils.GSUtils().list_bucket_contents(bucket=GM_SUMMARIES_BUCKET)
   return dirs
 
 
diff --git a/gm/rebaseline_server/download_actuals_test.py b/gm/rebaseline_server/download_actuals_test.py
index c405a3c..b982224 100755
--- a/gm/rebaseline_server/download_actuals_test.py
+++ b/gm/rebaseline_server/download_actuals_test.py
@@ -10,9 +10,9 @@
 
 TODO(epoger): Create a command to update the expected results (in
 self._output_dir_expected) when appropriate.  For now, you should:
-1. examine the results in self._output_dir_actual and make sure they are ok
+1. examine the results in self.output_dir_actual and make sure they are ok
 2. rm -rf self._output_dir_expected
-3. mv self._output_dir_actual self._output_dir_expected
+3. mv self.output_dir_actual self._output_dir_expected
 Although, if you're using an SVN checkout, this will blow away .svn directories
 within self._output_dir_expected, which wouldn't be good...
 
@@ -20,13 +20,12 @@
 
 # System-level imports
 import os
-import shutil
-import tempfile
-import urllib
+
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
 
 # Imports from within Skia
-import fix_pythonpath  # must do this first
-from pyutils import url_utils
+from py.utils import url_utils
 import base_unittest
 import download_actuals
 
@@ -37,12 +36,12 @@
     """Tests fetch() of GM results from actual-results.json ."""
     downloader = download_actuals.Download(
         actuals_base_url=url_utils.create_filepath_url(
-            os.path.join(self._input_dir, 'gm-actuals')),
+            os.path.join(self.input_dir, 'gm-actuals')),
         gm_actuals_root_url=url_utils.create_filepath_url(
-            os.path.join(self._input_dir, 'fake-gm-imagefiles')))
+            os.path.join(self.input_dir, 'fake-gm-imagefiles')))
     downloader.fetch(
         builder_name='Test-Android-GalaxyNexus-SGX540-Arm7-Release',
-        dest_dir=self._output_dir_actual)
+        dest_dir=self.output_dir_actual)
 
 
 def main():
diff --git a/gm/rebaseline_server/fix_pythonpath.py b/gm/rebaseline_server/fix_pythonpath.py
deleted file mode 100755
index ed578ce..0000000
--- a/gm/rebaseline_server/fix_pythonpath.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/python
-
-"""
-Copyright 2014 Google Inc.
-
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
-
-Adds [trunk]/gm and [trunk]/tools to PYTHONPATH, if they aren't already there.
-"""
-
-import os
-import sys
-
-TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
-GM_DIRECTORY = os.path.join(TRUNK_DIRECTORY, 'gm')
-TOOLS_DIRECTORY = os.path.join(TRUNK_DIRECTORY, 'tools')
-if GM_DIRECTORY not in sys.path:
-  sys.path.append(GM_DIRECTORY)
-if TOOLS_DIRECTORY not in sys.path:
-  sys.path.append(TOOLS_DIRECTORY)
diff --git a/gm/rebaseline_server/imagediffdb.py b/gm/rebaseline_server/imagediffdb.py
index 6b68414..0bc75cf 100644
--- a/gm/rebaseline_server/imagediffdb.py
+++ b/gm/rebaseline_server/imagediffdb.py
@@ -9,52 +9,67 @@
 Calulate differences between image pairs, and store them in a database.
 """
 
+# System-level imports
 import contextlib
-import csv
+import errno
+import json
 import logging
 import os
+import Queue
 import re
 import shutil
-import sys
 import tempfile
+import threading
+import time
 import urllib
-try:
-  from PIL import Image, ImageChops
-except ImportError:
-  raise ImportError('Requires PIL to be installed; see '
-                    + 'http://www.pythonware.com/products/pil/')
 
-# Set the PYTHONPATH to include the tools directory.
-sys.path.append(
-    os.path.join(
-        os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir,
-                        'tools'))
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
+
+# Imports from within Skia
 import find_run_binary
+from py.utils import gs_utils
+
 
 SKPDIFF_BINARY = find_run_binary.find_path_to_program('skpdiff')
 
 DEFAULT_IMAGE_SUFFIX = '.png'
 DEFAULT_IMAGES_SUBDIR = 'images'
+# TODO(epoger): Figure out a better default number of threads; for now,
+# using a conservative default value.
+DEFAULT_NUM_WORKER_THREADS = 1
 
 DISALLOWED_FILEPATH_CHAR_REGEX = re.compile('[^\w\-]')
 
-DIFFS_SUBDIR = 'diffs'
+RGBDIFFS_SUBDIR = 'diffs'
 WHITEDIFFS_SUBDIR = 'whitediffs'
 
-VALUES_PER_BAND = 256
-
 # Keys used within DiffRecord dictionary representations.
 # NOTE: Keep these in sync with static/constants.js
 KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL = 'maxDiffPerChannel'
 KEY__DIFFERENCES__NUM_DIFF_PIXELS = 'numDifferingPixels'
 KEY__DIFFERENCES__PERCENT_DIFF_PIXELS = 'percentDifferingPixels'
 KEY__DIFFERENCES__PERCEPTUAL_DIFF = 'perceptualDifference'
+KEY__DIFFERENCES__DIFF_URL = 'diffUrl'
+KEY__DIFFERENCES__WHITE_DIFF_URL = 'whiteDiffUrl'
+
+# Special values within ImageDiffDB._diff_dict
+_DIFFRECORD_FAILED = 'failed'
+_DIFFRECORD_PENDING = 'pending'
+
+# How often to report tasks_queue size
+QUEUE_LOGGING_GRANULARITY = 1000
+
+# Temporary variable to keep track of how many times we download
+# the same file in multiple threads.
+# TODO(epoger): Delete this, once we see that the number stays close to 0.
+global_file_collisions = 0
 
 
 class DiffRecord(object):
   """ Record of differences between two images. """
 
-  def __init__(self, storage_root,
+  def __init__(self, gs, storage_root,
                expected_image_url, expected_image_locator,
                actual_image_url, actual_image_locator,
                expected_images_subdir=DEFAULT_IMAGES_SUBDIR,
@@ -63,18 +78,16 @@
     """Download this pair of images (unless we already have them on local disk),
     and prepare a DiffRecord for them.
 
-    TODO(epoger): Make this asynchronously download images, rather than blocking
-    until the images have been downloaded and processed.
-
     Args:
+      gs: instance of GSUtils object we can use to download images
       storage_root: root directory on local disk within which we store all
           images
-      expected_image_url: file or HTTP url from which we will download the
+      expected_image_url: file, GS, or HTTP url from which we will download the
           expected image
       expected_image_locator: a unique ID string under which we will store the
           expected image within storage_root (probably including a checksum to
           guarantee uniqueness)
-      actual_image_url: file or HTTP url from which we will download the
+      actual_image_url: file, GS, or HTTP url from which we will download the
           actual image
       actual_image_locator: a unique ID string under which we will store the
           actual image within storage_root (probably including a checksum to
@@ -87,91 +100,95 @@
     actual_image_locator = _sanitize_locator(actual_image_locator)
 
     # Download the expected/actual images, if we don't have them already.
-    # TODO(rmistry): Add a parameter that makes _download_and_open_image raise
-    # an exception if images are not found locally (instead of trying to
-    # download them).
     expected_image_file = os.path.join(
         storage_root, expected_images_subdir,
         str(expected_image_locator) + image_suffix)
     actual_image_file = os.path.join(
         storage_root, actual_images_subdir,
         str(actual_image_locator) + image_suffix)
-    try:
-      expected_image = _download_and_open_image(
-          expected_image_file, expected_image_url)
-    except Exception:
-      logging.exception('unable to download expected_image_url %s to file %s' %
-                        (expected_image_url, expected_image_file))
-      raise
-    try:
-      actual_image = _download_and_open_image(
-          actual_image_file, actual_image_url)
-    except Exception:
-      logging.exception('unable to download actual_image_url %s to file %s' %
-                        (actual_image_url, actual_image_file))
-      raise
+    for image_file, image_url in [
+        (expected_image_file, expected_image_url),
+        (actual_image_file, actual_image_url)]:
+      if image_file and image_url:
+        try:
+          _download_file(gs, image_file, image_url)
+        except Exception:
+          logging.exception('unable to download image_url %s to file %s' %
+                            (image_url, image_file))
+          raise
 
-    # Generate the diff image (absolute diff at each pixel) and
-    # max_diff_per_channel.
-    diff_image = _generate_image_diff(actual_image, expected_image)
-    diff_histogram = diff_image.histogram()
-    (diff_width, diff_height) = diff_image.size
-    self._max_diff_per_channel = _max_per_band(diff_histogram)
+    # Return early if we do not need to generate diffs.
+    if (expected_image_url == actual_image_url or
+        not expected_image_url or not actual_image_url):
+      return
 
-    # Generate the whitediff image (any differing pixels show as white).
-    # This is tricky, because when you convert color images to grayscale or
-    # black & white in PIL, it has its own ideas about thresholds.
-    # We have to force it: if a pixel has any color at all, it's a '1'.
-    bands = diff_image.split()
-    graydiff_image = ImageChops.lighter(ImageChops.lighter(
-        bands[0], bands[1]), bands[2])
-    whitediff_image = (graydiff_image.point(lambda p: p > 0 and VALUES_PER_BAND)
-                                     .convert('1', dither=Image.NONE))
-
-    # Calculate the perceptual difference percentage.
-    skpdiff_csv_dir = tempfile.mkdtemp()
+    # Get all diff images and values using the skpdiff binary.
+    skpdiff_output_dir = tempfile.mkdtemp()
     try:
-      skpdiff_csv_output = os.path.join(skpdiff_csv_dir, 'skpdiff-output.csv')
-      expected_img = os.path.join(storage_root, expected_images_subdir,
-                                  str(expected_image_locator) + image_suffix)
-      actual_img = os.path.join(storage_root, actual_images_subdir,
-                                str(actual_image_locator) + image_suffix)
+      skpdiff_summary_file = os.path.join(skpdiff_output_dir,
+                                          'skpdiff-output.json')
+      skpdiff_rgbdiff_dir = os.path.join(storage_root, RGBDIFFS_SUBDIR)
+      skpdiff_whitediff_dir = os.path.join(storage_root, WHITEDIFFS_SUBDIR)
+      _mkdir_unless_exists(skpdiff_rgbdiff_dir)
+      _mkdir_unless_exists(skpdiff_rgbdiff_dir)
+
+      # TODO(epoger): Consider calling skpdiff ONCE for all image pairs,
+      # instead of calling it separately for each image pair.
+      # Pro: we'll incur less overhead from making repeated system calls,
+      # spinning up the skpdiff binary, etc.
+      # Con: we would have to wait until all image pairs were loaded before
+      # generating any of the diffs?
+      # Note(stephana): '--longnames' was added to allow for this 
+      # case (multiple files at once) versus specifying output diffs 
+      # directly.
       find_run_binary.run_command(
-          [SKPDIFF_BINARY, '-p', expected_img, actual_img,
-           '--csv', skpdiff_csv_output, '-d', 'perceptual'])
-      with contextlib.closing(open(skpdiff_csv_output)) as csv_file:
-        for row in csv.DictReader(csv_file):
-          perceptual_similarity = float(row[' perceptual'].strip())
-          if not 0 <= perceptual_similarity <= 1:
-            # skpdiff outputs -1 if the images are different sizes. Treat any
-            # output that does not lie in [0, 1] as having 0% perceptual
-            # similarity.
-            perceptual_similarity = 0
-          # skpdiff returns the perceptual similarity, convert it to get the
-          # perceptual difference percentage.
-          self._perceptual_difference = 100 - (perceptual_similarity * 100)
+          [SKPDIFF_BINARY, '-p', expected_image_file, actual_image_file,
+           '--jsonp', 'false',
+           '--longnames', 'true',
+           '--output', skpdiff_summary_file,
+           '--differs', 'perceptual', 'different_pixels',
+           '--rgbDiffDir', skpdiff_rgbdiff_dir,
+           '--whiteDiffDir', skpdiff_whitediff_dir,
+           ])
+
+      # Get information out of the skpdiff_summary_file.
+      with contextlib.closing(open(skpdiff_summary_file)) as fp:
+        data = json.load(fp)
+
+      # For now, we can assume there is only one record in the output summary,
+      # since we passed skpdiff only one pair of images.
+      record = data['records'][0]
+      self._width = record['width']
+      self._height = record['height']
+      self._diffUrl = os.path.split(record['rgbDiffPath'])[1]
+      self._whiteDiffUrl = os.path.split(record['whiteDiffPath'])[1]
+
+      # TODO: make max_diff_per_channel a tuple instead of a list, because the
+      # structure is meaningful (first element is red, second is green, etc.)
+      # See http://stackoverflow.com/a/626871
+      self._max_diff_per_channel = [
+          record['maxRedDiff'], record['maxGreenDiff'], record['maxBlueDiff']]
+      per_differ_stats = record['diffs']
+      for stats in per_differ_stats:
+        differ_name = stats['differName']
+        if differ_name == 'different_pixels':
+          self._num_pixels_differing = stats['pointsOfInterest']
+        elif differ_name == 'perceptual':
+          perceptual_similarity = stats['result']
+
+      # skpdiff returns the perceptual similarity; convert it to get the
+      # perceptual difference percentage.
+      # skpdiff outputs -1 if the images are different sizes. Treat any
+      # output that does not lie in [0, 1] as having 0% perceptual
+      # similarity.
+      if not 0 <= perceptual_similarity <= 1:
+        perceptual_similarity = 0
+      self._perceptual_difference = 100 - (perceptual_similarity * 100)
     finally:
-      shutil.rmtree(skpdiff_csv_dir)
+      shutil.rmtree(skpdiff_output_dir)
 
-    # Final touches on diff_image: use whitediff_image as an alpha mask.
-    # Unchanged pixels are transparent; differing pixels are opaque.
-    diff_image.putalpha(whitediff_image)
-
-    # Store the diff and whitediff images generated above.
-    diff_image_locator = _get_difference_locator(
-        expected_image_locator=expected_image_locator,
-        actual_image_locator=actual_image_locator)
-    basename = str(diff_image_locator) + image_suffix
-    _save_image(diff_image, os.path.join(
-        storage_root, DIFFS_SUBDIR, basename))
-    _save_image(whitediff_image, os.path.join(
-        storage_root, WHITEDIFFS_SUBDIR, basename))
-
-    # Calculate difference metrics.
-    (self._width, self._height) = diff_image.size
-    self._num_pixels_differing = (
-        whitediff_image.histogram()[VALUES_PER_BAND - 1])
-
+  # TODO(epoger): Use properties instead of getters throughout.
+  # See http://stackoverflow.com/a/6618176
   def get_num_pixels_differing(self):
     """Returns the absolute number of pixels that differ."""
     return self._num_pixels_differing
@@ -200,45 +217,137 @@
             self.get_percent_pixels_differing(),
         KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL: self._max_diff_per_channel,
         KEY__DIFFERENCES__PERCEPTUAL_DIFF: self._perceptual_difference,
+        KEY__DIFFERENCES__DIFF_URL: self._diffUrl,
+        KEY__DIFFERENCES__WHITE_DIFF_URL: self._whiteDiffUrl, 
     }
 
 
+
 class ImageDiffDB(object):
   """ Calculates differences between image pairs, maintaining a database of
   them for download."""
 
-  def __init__(self, storage_root):
+  def __init__(self, storage_root, gs=None,
+               num_worker_threads=DEFAULT_NUM_WORKER_THREADS):
     """
     Args:
       storage_root: string; root path within the DB will store all of its stuff
+      gs: instance of GSUtils object we can use to download images
+      num_worker_threads: how many threads that download images and
+          generate diffs simultaneously
     """
     self._storage_root = storage_root
+    self._gs = gs
+
+    # Mechanism for reporting queue size periodically.
+    self._last_queue_size_reported = None
+    self._queue_size_report_lock = threading.RLock()
 
     # Dictionary of DiffRecords, keyed by (expected_image_locator,
     # actual_image_locator) tuples.
+    # Values can also be _DIFFRECORD_PENDING, _DIFFRECORD_FAILED.
+    #
+    # Any thread that modifies _diff_dict must first acquire
+    # _diff_dict_writelock!
+    #
+    # TODO(epoger): Disk is limitless, but RAM is not... so, we should probably
+    # remove items from self._diff_dict if they haven't been accessed for a
+    # long time.  We can always regenerate them by diffing the images we
+    # previously downloaded to local disk.
+    # I guess we should figure out how expensive it is to download vs diff the
+    # image pairs... if diffing them is expensive too, we can write these
+    # _diff_dict objects out to disk if there's too many to hold in RAM.
+    # Or we could use virtual memory to handle that automatically.
     self._diff_dict = {}
+    self._diff_dict_writelock = threading.RLock()
+
+    # Set up the queue for asynchronously loading DiffRecords, and start the
+    # worker threads reading from it.
+    # The queue maxsize must be 0 (infinite size queue), so that asynchronous
+    # calls can return as soon as possible.
+    self._tasks_queue = Queue.Queue(maxsize=0)
+    self._workers = []
+    for i in range(num_worker_threads):
+      worker = threading.Thread(target=self.worker, args=(i,))
+      worker.daemon = True
+      worker.start()
+      self._workers.append(worker)
+
+  def log_queue_size_if_changed(self, limit_verbosity=True):
+    """Log the size of self._tasks_queue, if it has changed since the last call.
+
+    Reports the current queue size, using log.info(), unless the queue is the
+    same size as the last time we reported it.
+
+    Args:
+      limit_verbosity: if True, only log if the queue size is a multiple of
+          QUEUE_LOGGING_GRANULARITY
+    """
+    # Acquire the lock, to synchronize access to self._last_queue_size_reported
+    self._queue_size_report_lock.acquire()
+    try:
+      size = self._tasks_queue.qsize()
+      if size == self._last_queue_size_reported:
+        return
+      if limit_verbosity and (size % QUEUE_LOGGING_GRANULARITY != 0):
+        return
+      logging.info('tasks_queue size is %d' % size)
+      self._last_queue_size_reported = size
+    finally:
+      self._queue_size_report_lock.release()
+
+  def worker(self, worker_num):
+    """Launch a worker thread that pulls tasks off self._tasks_queue.
+
+    Args:
+      worker_num: (integer) which worker this is
+    """
+    while True:
+      self.log_queue_size_if_changed()
+      params = self._tasks_queue.get()
+      key, expected_image_url, actual_image_url = params
+      try:
+        diff_record = DiffRecord(
+            self._gs, self._storage_root,
+            expected_image_url=expected_image_url,
+            expected_image_locator=key[0],
+            actual_image_url=actual_image_url,
+            actual_image_locator=key[1])
+      except Exception:
+        logging.exception(
+            'exception while creating DiffRecord for key %s' % str(key))
+        diff_record = _DIFFRECORD_FAILED
+      self._diff_dict_writelock.acquire()
+      try:
+        self._diff_dict[key] = diff_record
+      finally:
+        self._diff_dict_writelock.release()
+
+  @property
+  def storage_root(self):
+    return self._storage_root
 
   def add_image_pair(self,
                      expected_image_url, expected_image_locator,
                      actual_image_url, actual_image_locator):
-    """Download this pair of images (unless we already have them on local disk),
-    and prepare a DiffRecord for them.
+    """Asynchronously prepare a DiffRecord for a pair of images.
 
-    TODO(epoger): Make this asynchronously download images, rather than blocking
-    until the images have been downloaded and processed.
-    When we do that, we should probably add a new method that will block
-    until all of the images have been downloaded and processed.  Otherwise,
-    we won't know when it's safe to start calling get_diff_record().
-    jcgregorio notes: maybe just make ImageDiffDB thread-safe and create a
-    thread-pool/worker queue at a higher level that just uses ImageDiffDB?
+    This method will return quickly; calls to get_diff_record() will block
+    until the DiffRecord is available (or we have given up on creating it).
+
+    If we already have a DiffRecord for this particular image pair, no work
+    will be done.
+
+    If expected_image_url (or its locator) is None, just download actual_image.
+    If actual_image_url (or its locator) is None, just download expected_image.
 
     Args:
-      expected_image_url: file or HTTP url from which we will download the
+      expected_image_url: file, GS, or HTTP url from which we will download the
           expected image
       expected_image_locator: a unique ID string under which we will store the
           expected image within storage_root (probably including a checksum to
           guarantee uniqueness)
-      actual_image_url: file or HTTP url from which we will download the
+      actual_image_url: file, GS, or HTTP url from which we will download the
           actual image
       actual_image_locator: a unique ID string under which we will store the
           actual image within storage_root (probably including a checksum to
@@ -247,133 +356,97 @@
     expected_image_locator = _sanitize_locator(expected_image_locator)
     actual_image_locator = _sanitize_locator(actual_image_locator)
     key = (expected_image_locator, actual_image_locator)
-    if not key in self._diff_dict:
-      try:
-        new_diff_record = DiffRecord(
-            self._storage_root,
-            expected_image_url=expected_image_url,
-            expected_image_locator=expected_image_locator,
-            actual_image_url=actual_image_url,
-            actual_image_locator=actual_image_locator)
-      except Exception:
-        # If we can't create a real DiffRecord for this (expected, actual) pair,
-        # store None and the UI will show whatever information we DO have.
-        # Fixes http://skbug.com/2368 .
-        logging.exception(
-            'got exception while creating a DiffRecord for '
-            'expected_image_url=%s , actual_image_url=%s; returning None' % (
-                expected_image_url, actual_image_url))
-        new_diff_record = None
-      self._diff_dict[key] = new_diff_record
+    must_add_to_queue = False
+
+    self._diff_dict_writelock.acquire()
+    try:
+      if not key in self._diff_dict:
+        # If we have already requested a diff between these two images,
+        # we don't need to request it again.
+        must_add_to_queue = True
+        self._diff_dict[key] = _DIFFRECORD_PENDING
+    finally:
+      self._diff_dict_writelock.release()
+
+    if must_add_to_queue:
+      self._tasks_queue.put((key, expected_image_url, actual_image_url))
+      self.log_queue_size_if_changed()
 
   def get_diff_record(self, expected_image_locator, actual_image_locator):
     """Returns the DiffRecord for this image pair.
 
-    Raises a KeyError if we don't have a DiffRecord for this image pair.
+    This call will block until the diff record is available, or we were unable
+    to generate it.
+
+    Args:
+      expected_image_locator: a unique ID string under which we will store the
+          expected image within storage_root (probably including a checksum to
+          guarantee uniqueness)
+      actual_image_locator: a unique ID string under which we will store the
+          actual image within storage_root (probably including a checksum to
+          guarantee uniqueness)
+
+    Returns the DiffRecord for this image pair, or None if we were unable to
+    generate one.
     """
     key = (_sanitize_locator(expected_image_locator),
            _sanitize_locator(actual_image_locator))
-    return self._diff_dict[key]
+    diff_record = self._diff_dict[key]
+
+    # If we have no results yet, block until we do.
+    while diff_record == _DIFFRECORD_PENDING:
+      time.sleep(1)
+      diff_record = self._diff_dict[key]
+
+    # Once we have the result...
+    if diff_record == _DIFFRECORD_FAILED:
+      logging.error(
+          'failed to create a DiffRecord for expected_image_locator=%s , '
+          'actual_image_locator=%s' % (
+              expected_image_locator, actual_image_locator))
+      return None
+    else:
+      return diff_record
 
 
 # Utility functions
 
-def _max_per_band(histogram):
-  """Given the histogram of an image, return the maximum value of each band
-  (a.k.a. "color channel", such as R/G/B) across the entire image.
+def _download_file(gs, local_filepath, url):
+  """Download a file from url to local_filepath, unless it is already there.
 
   Args:
-    histogram: PIL histogram
-
-  Returns the maximum value of each band within the image histogram, as a list.
-  """
-  max_per_band = []
-  assert(len(histogram) % VALUES_PER_BAND == 0)
-  num_bands = len(histogram) / VALUES_PER_BAND
-  for band in xrange(num_bands):
-    # Assuming that VALUES_PER_BAND is 256...
-    #  the 'R' band makes up indices 0-255 in the histogram,
-    #  the 'G' band makes up indices 256-511 in the histogram,
-    #  etc.
-    min_index = band * VALUES_PER_BAND
-    index = min_index + VALUES_PER_BAND
-    while index > min_index:
-      index -= 1
-      if histogram[index] > 0:
-        max_per_band.append(index - min_index)
-        break
-  return max_per_band
-
-
-def _generate_image_diff(image1, image2):
-  """Wrapper for ImageChops.difference(image1, image2) that will handle some
-  errors automatically, or at least yield more useful error messages.
-
-  TODO(epoger): Currently, some of the images generated by the bots are RGBA
-  and others are RGB.  I'm not sure why that is.  For now, to avoid confusion
-  within the UI, convert all to RGB when diffing.
-
-  Args:
-    image1: a PIL image object
-    image2: a PIL image object
-
-  Returns: per-pixel diffs between image1 and image2, as a PIL image object
-  """
-  try:
-    return ImageChops.difference(image1.convert('RGB'), image2.convert('RGB'))
-  except ValueError:
-    logging.error('Error diffing image1 [%s] and image2 [%s].' % (
-        repr(image1), repr(image2)))
-    raise
-
-
-def _download_and_open_image(local_filepath, url):
-  """Open the image at local_filepath; if there is no file at that path,
-  download it from url to that path and then open it.
-
-  Args:
+    gs: instance of GSUtils object, in case the url points at Google Storage
     local_filepath: path on local disk where the image should be stored
-    url: URL from which we can download the image if we don't have it yet
-
-  Returns: a PIL image object
+    url: HTTP or GS URL from which we can download the image if we don't have
+        it yet
   """
+  global global_file_collisions
   if not os.path.exists(local_filepath):
     _mkdir_unless_exists(os.path.dirname(local_filepath))
-    with contextlib.closing(urllib.urlopen(url)) as url_handle:
-      with open(local_filepath, 'wb') as file_handle:
-        shutil.copyfileobj(fsrc=url_handle, fdst=file_handle)
-  return _open_image(local_filepath)
 
+    # First download the file contents into a unique filename, and
+    # then rename that file.  That way, if multiple threads are downloading
+    # the same filename at the same time, they won't interfere with each
+    # other (they will both download the file, and one will "win" in the end)
+    temp_filename = '%s-%d' % (local_filepath,
+                               threading.current_thread().ident)
+    if gs_utils.GSUtils.is_gs_url(url):
+      (bucket, path) = gs_utils.GSUtils.split_gs_url(url)
+      gs.download_file(source_bucket=bucket, source_path=path,
+                       dest_path=temp_filename)
+    else:
+      with contextlib.closing(urllib.urlopen(url)) as url_handle:
+        with open(temp_filename, 'wb') as file_handle:
+          shutil.copyfileobj(fsrc=url_handle, fdst=file_handle)
 
-def _open_image(filepath):
-  """Wrapper for Image.open(filepath) that yields more useful error messages.
-
-  Args:
-    filepath: path on local disk to load image from
-
-  Returns: a PIL image object
-  """
-  try:
-    return Image.open(filepath)
-  except IOError:
-    # If we are unable to load an image from the file, delete it from disk
-    # and we will try to fetch it again next time.  Fixes http://skbug.com/2247
-    logging.error('IOError loading image file %s ; deleting it.' % filepath)
-    os.remove(filepath)
-    raise
-
-
-def _save_image(image, filepath, format='PNG'):
-  """Write an image to disk, creating any intermediate directories as needed.
-
-  Args:
-    image: a PIL image object
-    filepath: path on local disk to write image to
-    format: one of the PIL image formats, listed at
-            http://effbot.org/imagingbook/formats.htm
-  """
-  _mkdir_unless_exists(os.path.dirname(filepath))
-  image.save(filepath, format)
+    # Rename the file to its real filename.
+    # Keep count of how many colliding downloads we encounter;
+    # if it's a large number, we may want to change our download strategy
+    # to minimize repeated downloads.
+    if os.path.exists(local_filepath):
+      global_file_collisions += 1
+    else:
+      os.rename(temp_filename, local_filepath)
 
 
 def _mkdir_unless_exists(path):
@@ -382,8 +455,11 @@
   Args:
     path: path on local disk
   """
-  if not os.path.isdir(path):
+  try:
     os.makedirs(path)
+  except OSError as e:
+    if e.errno == errno.EEXIST:
+      pass
 
 
 def _sanitize_locator(locator):
@@ -391,24 +467,11 @@
   characters will have special meaning in filenames).
 
   Args:
-    locator: string, or something that can be represented as a string
+    locator: string, or something that can be represented as a string.
+        If None or '', it is returned without modification, because empty
+        locators have a particular meaning ("there is no image for this")
   """
-  return DISALLOWED_FILEPATH_CHAR_REGEX.sub('_', str(locator))
-
-
-def _get_difference_locator(expected_image_locator, actual_image_locator):
-  """Returns the locator string used to look up the diffs between expected_image
-  and actual_image.
-
-  We must keep this function in sync with getImageDiffRelativeUrl() in
-  static/loader.js
-
-  Args:
-    expected_image_locator: locator string pointing at expected image
-    actual_image_locator: locator string pointing at actual image
-
-  Returns: already-sanitized locator where the diffs between expected and
-      actual images can be found
-  """
-  return "%s-vs-%s" % (_sanitize_locator(expected_image_locator),
-                       _sanitize_locator(actual_image_locator))
+  if locator:
+    return DISALLOWED_FILEPATH_CHAR_REGEX.sub('_', str(locator))
+  else:
+    return locator
diff --git a/gm/rebaseline_server/imagediffdb_test.py b/gm/rebaseline_server/imagediffdb_test.py
index 4fc8c66..186b2f1 100755
--- a/gm/rebaseline_server/imagediffdb_test.py
+++ b/gm/rebaseline_server/imagediffdb_test.py
@@ -10,7 +10,6 @@
 """
 
 # System-level imports
-import logging
 import shutil
 import tempfile
 import unittest
@@ -26,11 +25,11 @@
 class ImageDiffDbTest(unittest.TestCase):
 
   def setUp(self):
-    self._temp_dir = tempfile.mkdtemp()
+    self.temp_dir = tempfile.mkdtemp()
     self.maxDiff = None
 
   def tearDown(self):
-    shutil.rmtree(self._temp_dir)
+    shutil.rmtree(self.temp_dir)
 
   def shortDescription(self):
     """Tell unittest framework to not print docstrings for test cases."""
@@ -38,6 +37,7 @@
 
   def test_sanitize_locator(self):
     """Test _sanitize_locator()."""
+    # pylint: disable=W0212
     self.assertEqual(imagediffdb._sanitize_locator('simple'), 'simple')
     self.assertEqual(imagediffdb._sanitize_locator(1234), '1234')
     self.assertEqual(imagediffdb._sanitize_locator('one/two'),  'one_two')
@@ -76,9 +76,9 @@
     ]
 
     # Add all image pairs to the database
-    db = imagediffdb.ImageDiffDB(self._temp_dir)
+    db = imagediffdb.ImageDiffDB(self.temp_dir)
     for selftest in selftests:
-      retval = db.add_image_pair(
+      db.add_image_pair(
           expected_image_locator=selftest[0], expected_image_url=selftest[1],
           actual_image_locator=selftest[2],   actual_image_url=selftest[3])
 
diff --git a/gm/rebaseline_server/imagepair.py b/gm/rebaseline_server/imagepair.py
index 446858d..e85c219 100644
--- a/gm/rebaseline_server/imagepair.py
+++ b/gm/rebaseline_server/imagepair.py
@@ -20,6 +20,11 @@
 KEY__IMAGEPAIRS__IMAGE_A_URL = 'imageAUrl'
 KEY__IMAGEPAIRS__IMAGE_B_URL = 'imageBUrl'
 KEY__IMAGEPAIRS__IS_DIFFERENT = 'isDifferent'
+KEY__IMAGEPAIRS__SOURCE_JSON_FILE = 'sourceJsonFile'
+
+# If self._diff_record is set to this, we haven't asked ImageDiffDB for the
+# image diff details yet.
+_DIFF_RECORD_STILL_LOADING = 'still_loading'
 
 
 class ImagePair(object):
@@ -27,49 +32,58 @@
   """
 
   def __init__(self, image_diff_db,
-               base_url, imageA_relative_url, imageB_relative_url,
-               expectations=None, extra_columns=None):
+               imageA_base_url, imageB_base_url,
+               imageA_relative_url, imageB_relative_url,
+               expectations=None, extra_columns=None, source_json_file=None,
+               download_all_images=False):
     """
     Args:
       image_diff_db: ImageDiffDB instance we use to generate/store image diffs
-      base_url: base of all image URLs
+      imageA_base_url: string; base URL for image A
+      imageB_base_url: string; base URL for image B
       imageA_relative_url: string; URL pointing at an image, relative to
-          base_url; or None, if this image is missing
+          imageA_base_url; or None, if this image is missing
       imageB_relative_url: string; URL pointing at an image, relative to
-          base_url; or None, if this image is missing
+          imageB_base_url; or None, if this image is missing
       expectations: optional dictionary containing expectations-specific
           metadata (ignore-failure, bug numbers, etc.)
       extra_columns: optional dictionary containing more metadata (test name,
           builder name, etc.)
+      source_json_file: relative path of the JSON file where each image came
+          from; this will be the same for both imageA and imageB, within their
+          respective directories
+      download_all_images: if True, download any images associated with this
+          image pair, even if we don't need them to generate diffs
+          (imageA == imageB, or one of them is missing)
     """
-    self.base_url = base_url
+    self._image_diff_db = image_diff_db
+    self.imageA_base_url = imageA_base_url
+    self.imageB_base_url = imageB_base_url
     self.imageA_relative_url = imageA_relative_url
     self.imageB_relative_url = imageB_relative_url
     self.expectations_dict = expectations
     self.extra_columns_dict = extra_columns
+    self.source_json_file = source_json_file
     if not imageA_relative_url or not imageB_relative_url:
       self._is_different = True
-      self.diff_record = None
+      self._diff_record = None
     elif imageA_relative_url == imageB_relative_url:
       self._is_different = False
-      self.diff_record = None
+      self._diff_record = None
     else:
-      # TODO(epoger): Rather than blocking until image_diff_db can read in
-      # the image pair and generate diffs, it would be better to do it
-      # asynchronously: tell image_diff_db to download a bunch of file pairs,
-      # and only block later if we're still waiting for diff_records to come
-      # back.
+      # Tell image_diff_db to add an entry for this diff asynchronously.
+      # Later on, we will call image_diff_db.get_diff_record() to find it.
       self._is_different = True
+      self._diff_record = _DIFF_RECORD_STILL_LOADING
+
+    if self._diff_record != None or download_all_images:
       image_diff_db.add_image_pair(
           expected_image_locator=imageA_relative_url,
-          expected_image_url=posixpath.join(base_url, imageA_relative_url),
+          expected_image_url=self.posixpath_join(imageA_base_url,
+                                                 imageA_relative_url),
           actual_image_locator=imageB_relative_url,
-          actual_image_url=posixpath.join(base_url, imageB_relative_url))
-      self.diff_record = image_diff_db.get_diff_record(
-          expected_image_locator=imageA_relative_url,
-          actual_image_locator=imageB_relative_url)
-      if self.diff_record and self.diff_record.get_num_pixels_differing() == 0:
-        self._is_different = False
+          actual_image_url=self.posixpath_join(imageB_base_url,
+                                               imageB_relative_url))
 
   def as_dict(self):
     """Returns a dictionary describing this ImagePair.
@@ -85,6 +99,30 @@
       asdict[KEY__IMAGEPAIRS__EXPECTATIONS] = self.expectations_dict
     if self.extra_columns_dict:
       asdict[KEY__IMAGEPAIRS__EXTRACOLUMNS] = self.extra_columns_dict
-    if self.diff_record and (self.diff_record.get_num_pixels_differing() > 0):
-      asdict[KEY__IMAGEPAIRS__DIFFERENCES] = self.diff_record.as_dict()
+    if self.source_json_file:
+      asdict[KEY__IMAGEPAIRS__SOURCE_JSON_FILE] = self.source_json_file
+    if self._diff_record is _DIFF_RECORD_STILL_LOADING:
+      # We have waited as long as we can to ask ImageDiffDB for details of
+      # this image diff.  Now we must block until ImageDiffDB can provide
+      # those details.
+      #
+      # TODO(epoger): Is it wasteful for every imagepair to have its own
+      # reference to image_diff_db?  If so, we could pass an image_diff_db
+      # reference into this method call instead...
+      self._diff_record = self._image_diff_db.get_diff_record(
+          expected_image_locator=self.imageA_relative_url,
+          actual_image_locator=self.imageB_relative_url)
+    if self._diff_record != None:
+      asdict[KEY__IMAGEPAIRS__DIFFERENCES] = self._diff_record.as_dict()
     return asdict
+
+  @staticmethod
+  def posixpath_join(*args):
+    """Wrapper around posixpath.join().
+
+    Returns posixpath.join(*args), or None if any arg is None.
+    """
+    for arg in args:
+      if arg == None:
+        return None
+    return posixpath.join(*args)
diff --git a/gm/rebaseline_server/imagepair_test.py b/gm/rebaseline_server/imagepair_test.py
index 3b4cf8e..773f6a3 100755
--- a/gm/rebaseline_server/imagepair_test.py
+++ b/gm/rebaseline_server/imagepair_test.py
@@ -19,17 +19,18 @@
 import imagepair
 
 
-IMG_URL_BASE = 'http://chromium-skia-gm.commondatastorage.googleapis.com/gm/bitmap-64bitMD5/'
+IMG_URL_BASE = ('http://chromium-skia-gm.commondatastorage.googleapis.com/'
+                'gm/bitmap-64bitMD5/')
 
 
 class ImagePairTest(unittest.TestCase):
 
   def setUp(self):
-    self._temp_dir = tempfile.mkdtemp()
+    self.temp_dir = tempfile.mkdtemp()
     self.maxDiff = None
 
   def tearDown(self):
-    shutil.rmtree(self._temp_dir)
+    shutil.rmtree(self.temp_dir)
 
   def shortDescription(self):
     """Tells unittest framework to not print docstrings for test cases."""
@@ -87,7 +88,11 @@
                     'maxDiffPerChannel': [255, 255, 247],
                     'numDifferingPixels': 662,
                     'percentDifferingPixels': 0.0662,
-                    'perceptualDifference': 0.06620000000000914,
+                    'perceptualDifference': 0.06620300000000157,
+                    'diffUrl': 'arcofzorro_16206093933823793653_png_png-vs-' +
+                        'arcofzorro_13786535001616823825_png_png.png',
+                    'whiteDiffUrl': 'arcofzorro_16206093933823793653_png_png' +
+                        '-vs-arcofzorro_13786535001616823825_png_png.png',
                 },
                 'imageAUrl': 'arcofzorro/16206093933823793653.png',
                 'imageBUrl': 'arcofzorro/13786535001616823825.png',
@@ -114,6 +119,13 @@
                     'numDifferingPixels': 102400,
                     'percentDifferingPixels': 100.00,
                     'perceptualDifference': 100.00,
+                    'diffUrl': 'gradients_degenerate_2pt_10552995703607727960' +
+                               '_png_png-vs-gradients_degenerate_2pt_' +
+                               '11198253335583713230_png_png.png',
+                    'whiteDiffUrl': 'gradients_degenerate_2pt_' +
+                               '10552995703607727960_png_png-vs-' +
+                               'gradients_degenerate_2pt_11198253335583713230' +
+                               '_png_png.png'
                 },
                 'expectations': {
                     'bugs': [1001, 1002],
@@ -160,17 +172,36 @@
                 'isDifferent': True,
             },
         ],
+
+        # One of the two images is missing, but download_all_images=True so we
+        # should download it anyway.
+        [
+            # inputs:
+            None,
+            'arcofzorro/13786535001616823825.png',
+            None,
+            None,
+            # expected output:
+            {
+                'imageAUrl': None,
+                'imageBUrl': 'arcofzorro/13786535001616823825.png',
+                'isDifferent': True,
+            },
+        ],
+
     ]
 
-    db = imagediffdb.ImageDiffDB(self._temp_dir)
+    db = imagediffdb.ImageDiffDB(self.temp_dir)
     for selftest in selftests:
       image_pair = imagepair.ImagePair(
           image_diff_db=db,
-          base_url=IMG_URL_BASE,
+          imageA_base_url=IMG_URL_BASE,
+          imageB_base_url=IMG_URL_BASE,
           imageA_relative_url=selftest[0],
           imageB_relative_url=selftest[1],
           expectations=selftest[2],
-          extra_columns=selftest[3])
+          extra_columns=selftest[3],
+          download_all_images=True)
       self.assertEqual(image_pair.as_dict(), selftest[4])
 
 
diff --git a/gm/rebaseline_server/imagepairset.py b/gm/rebaseline_server/imagepairset.py
index 25d46a9..b492d9f 100644
--- a/gm/rebaseline_server/imagepairset.py
+++ b/gm/rebaseline_server/imagepairset.py
@@ -12,13 +12,18 @@
 # System-level imports
 import posixpath
 
-# Local imports
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
+
+# Imports from within Skia
 import column
-import imagepair
+import imagediffdb
+from py.utils import gs_utils
 
 # Keys used within dictionary representation of ImagePairSet.
 # NOTE: Keep these in sync with static/constants.js
 KEY__ROOT__EXTRACOLUMNHEADERS = 'extraColumnHeaders'
+KEY__ROOT__EXTRACOLUMNORDER = 'extraColumnOrder'
 KEY__ROOT__HEADER = 'header'
 KEY__ROOT__IMAGEPAIRS = 'imagePairs'
 KEY__ROOT__IMAGESETS = 'imageSets'
@@ -52,20 +57,30 @@
     self._descriptions = descriptions or DEFAULT_DESCRIPTIONS
     self._extra_column_tallies = {}  # maps column_id -> values
                                      #                -> instances_per_value
-    self._image_pair_dicts = []
-    self._image_base_url = None
+    self._imageA_base_url = None
+    self._imageB_base_url = None
     self._diff_base_url = diff_base_url
 
+    # We build self._image_pair_objects incrementally as calls come into
+    # add_image_pair(); self._image_pair_dicts is filled in lazily (so that
+    # we put off asking ImageDiffDB for results as long as possible).
+    self._image_pair_objects = []
+    self._image_pair_dicts = None
+
   def add_image_pair(self, image_pair):
     """Adds an ImagePair; this may be repeated any number of times."""
     # Special handling when we add the first ImagePair...
-    if not self._image_pair_dicts:
-      self._image_base_url = image_pair.base_url
+    if not self._image_pair_objects:
+      self._imageA_base_url = image_pair.imageA_base_url
+      self._imageB_base_url = image_pair.imageB_base_url
 
-    if image_pair.base_url != self._image_base_url:
+    if(image_pair.imageA_base_url != self._imageA_base_url):
       raise Exception('added ImagePair with base_url "%s" instead of "%s"' % (
-          image_pair.base_url, self._image_base_url))
-    self._image_pair_dicts.append(image_pair.as_dict())
+          image_pair.imageA_base_url, self._imageA_base_url))
+    if(image_pair.imageB_base_url != self._imageB_base_url):
+      raise Exception('added ImagePair with base_url "%s" instead of "%s"' % (
+          image_pair.imageB_base_url, self._imageB_base_url))
+    self._image_pair_objects.append(image_pair)
     extra_columns_dict = image_pair.extra_columns_dict
     if extra_columns_dict:
       for column_id, value in extra_columns_dict.iteritems():
@@ -135,34 +150,85 @@
           values_for_column)
     return asdict
 
-  def as_dict(self):
+  def as_dict(self, column_ids_in_order=None):
     """Returns a dictionary describing this package of ImagePairs.
 
     Uses the KEY__* constants as keys.
+
+    Args:
+      column_ids_in_order: A list of all extracolumn IDs in the desired display
+          order.  If unspecified, they will be displayed in alphabetical order.
+          If specified, this list must contain all the extracolumn IDs!
+          (It may contain extra column IDs; they will be ignored.)
     """
+    all_column_ids = set(self._extra_column_tallies.keys())
+    if column_ids_in_order == None:
+      column_ids_in_order = sorted(all_column_ids)
+    else:
+      # Make sure the caller listed all column IDs, and throw away any extras.
+      specified_column_ids = set(column_ids_in_order)
+      forgotten_column_ids = all_column_ids - specified_column_ids
+      assert not forgotten_column_ids, (
+          'column_ids_in_order %s missing these column_ids: %s' % (
+              column_ids_in_order, forgotten_column_ids))
+      column_ids_in_order = [c for c in column_ids_in_order
+                             if c in all_column_ids]
+
     key_description = KEY__IMAGESETS__FIELD__DESCRIPTION
     key_base_url = KEY__IMAGESETS__FIELD__BASE_URL
+    if gs_utils.GSUtils.is_gs_url(self._imageA_base_url):
+      valueA_base_url = self._convert_gs_url_to_http_url(self._imageA_base_url)
+    else:
+      valueA_base_url = self._imageA_base_url
+    if gs_utils.GSUtils.is_gs_url(self._imageB_base_url):
+      valueB_base_url = self._convert_gs_url_to_http_url(self._imageB_base_url)
+    else:
+      valueB_base_url = self._imageB_base_url
+
+    # We've waited as long as we can to ask ImageDiffDB for details of the
+    # image diffs, so that it has time to compute them.
+    if self._image_pair_dicts == None:
+      self._image_pair_dicts = [ip.as_dict() for ip in self._image_pair_objects]
+
     return {
         KEY__ROOT__EXTRACOLUMNHEADERS: self._column_headers_as_dict(),
+        KEY__ROOT__EXTRACOLUMNORDER: column_ids_in_order,
         KEY__ROOT__IMAGEPAIRS: self._image_pair_dicts,
         KEY__ROOT__IMAGESETS: {
             KEY__IMAGESETS__SET__IMAGE_A: {
                 key_description: self._descriptions[0],
-                key_base_url: self._image_base_url,
+                key_base_url: valueA_base_url,
             },
             KEY__IMAGESETS__SET__IMAGE_B: {
                 key_description: self._descriptions[1],
-                key_base_url: self._image_base_url,
+                key_base_url: valueB_base_url,
             },
             KEY__IMAGESETS__SET__DIFFS: {
                 key_description: 'color difference per channel',
                 key_base_url: posixpath.join(
-                    self._diff_base_url, 'diffs'),
+                    self._diff_base_url, imagediffdb.RGBDIFFS_SUBDIR),
             },
             KEY__IMAGESETS__SET__WHITEDIFFS: {
                 key_description: 'differing pixels in white',
                 key_base_url: posixpath.join(
-                    self._diff_base_url, 'whitediffs'),
+                    self._diff_base_url, imagediffdb.WHITEDIFFS_SUBDIR),
             },
         },
     }
+
+  @staticmethod
+  def _convert_gs_url_to_http_url(gs_url):
+    """Returns HTTP URL that can be used to download this Google Storage file.
+
+    TODO(epoger): Create functionality like this within gs_utils.py instead of
+    here?  See https://codereview.chromium.org/428493005/ ('create
+    anyfile_utils.py for copying files between HTTP/GS/local filesystem')
+
+    Args:
+      gs_url: "gs://bucket/path" format URL
+    """
+    bucket, path = gs_utils.GSUtils.split_gs_url(gs_url)
+    http_url = 'http://storage.cloud.google.com/' + bucket
+    if path:
+      http_url += '/' + path
+    return http_url
diff --git a/gm/rebaseline_server/imagepairset_test.py b/gm/rebaseline_server/imagepairset_test.py
index c2f17ba..a931e04 100755
--- a/gm/rebaseline_server/imagepairset_test.py
+++ b/gm/rebaseline_server/imagepairset_test.py
@@ -79,9 +79,12 @@
     """Assembles some ImagePairs into an ImagePairSet, and validates results.
     """
     image_pairs = [
-        MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_1_AS_DICT),
-        MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_2_AS_DICT),
-        MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_3_AS_DICT),
+        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+                      dict_to_return=IMAGEPAIR_1_AS_DICT),
+        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+                      dict_to_return=IMAGEPAIR_2_AS_DICT),
+        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+                      dict_to_return=IMAGEPAIR_3_AS_DICT),
     ]
     expected_imageset_dict = {
         'extraColumnHeaders': {
@@ -89,6 +92,7 @@
                 'headerText': 'builder',
                 'isFilterable': True,
                 'isSortable': True,
+                'useFreeformFilter': False,
                 'valuesAndCounts': [('MyBuilder', 3)],
             },
             'test': {
@@ -96,8 +100,13 @@
                 'headerUrl': 'http://learn/about/gm/tests',
                 'isFilterable': True,
                 'isSortable': False,
+                'useFreeformFilter': False,
+                'valuesAndCounts': [('test1', 1),
+                                    ('test2', 1),
+                                    ('test3', 1)],
             },
         },
+        'extraColumnOrder': ['builder', 'test'],
         'imagePairs': [
             IMAGEPAIR_1_AS_DICT,
             IMAGEPAIR_2_AS_DICT,
@@ -136,8 +145,7 @@
             header_text='which GM test',
             header_url='http://learn/about/gm/tests',
             is_filterable=True,
-            is_sortable=False,
-            include_values_and_counts=False))
+            is_sortable=False))
     self.assertEqual(image_pair_set.as_dict(), expected_imageset_dict)
 
   def test_mismatched_base_url(self):
@@ -145,24 +153,46 @@
     image_pair_set = imagepairset.ImagePairSet(
         diff_base_url=DIFF_BASE_URL)
     image_pair_set.add_image_pair(
-        MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_1_AS_DICT))
+        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+                      dict_to_return=IMAGEPAIR_1_AS_DICT))
     image_pair_set.add_image_pair(
-        MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_2_AS_DICT))
+        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+                      dict_to_return=IMAGEPAIR_2_AS_DICT))
     with self.assertRaises(Exception):
       image_pair_set.add_image_pair(
-          MockImagePair(base_url=BASE_URL_2,
+          MockImagePair(imageA_base_url=BASE_URL_2, imageB_base_url=BASE_URL_2,
                         dict_to_return=IMAGEPAIR_3_AS_DICT))
 
+  def test_missing_column_ids(self):
+    """Confirms that passing truncated column_ids_in_order to as_dict()
+    will cause an exception."""
+    image_pair_set = imagepairset.ImagePairSet(
+        diff_base_url=DIFF_BASE_URL)
+    image_pair_set.add_image_pair(
+        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+                      dict_to_return=IMAGEPAIR_1_AS_DICT))
+    image_pair_set.add_image_pair(
+        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+                      dict_to_return=IMAGEPAIR_2_AS_DICT))
+    # Call as_dict() with default or reasonable column_ids_in_order.
+    image_pair_set.as_dict()
+    image_pair_set.as_dict(column_ids_in_order=['test', 'builder'])
+    image_pair_set.as_dict(column_ids_in_order=['test', 'builder', 'extra'])
+    # Call as_dict() with not enough column_ids.
+    with self.assertRaises(Exception):
+      image_pair_set.as_dict(column_ids_in_order=['builder'])
+
 
 class MockImagePair(object):
   """Mock ImagePair object, which will return canned results."""
-  def __init__(self, base_url, dict_to_return):
+  def __init__(self, imageA_base_url, imageB_base_url, dict_to_return):
     """
     Args:
       base_url: base_url attribute for this object
       dict_to_return: dictionary to return from as_dict()
     """
-    self.base_url = base_url
+    self.imageA_base_url = imageA_base_url
+    self.imageB_base_url = imageB_base_url
     self.extra_columns_dict = dict_to_return.get(
         imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS, None)
     self._dict_to_return = dict_to_return
diff --git a/gm/rebaseline_server/results.py b/gm/rebaseline_server/results.py
index d17bc3d..b0027d2 100755
--- a/gm/rebaseline_server/results.py
+++ b/gm/rebaseline_server/results.py
@@ -14,14 +14,16 @@
 import os
 import re
 
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
+
 # Imports from within Skia
-import fix_pythonpath  # must do this first
 import gm_json
 import imagepairset
 
 # Keys used to link an image to a particular GM test.
 # NOTE: Keep these in sync with static/constants.js
-VALUE__HEADER__SCHEMA_VERSION = 3
+VALUE__HEADER__SCHEMA_VERSION = 5
 KEY__EXPECTATIONS__BUGS = gm_json.JSONKEY_EXPECTEDRESULTS_BUGS
 KEY__EXPECTATIONS__IGNOREFAILURE = gm_json.JSONKEY_EXPECTEDRESULTS_IGNOREFAILURE
 KEY__EXPECTATIONS__REVIEWED = gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED
@@ -36,6 +38,8 @@
 KEY__HEADER__RESULTS_ALL = 'all'
 KEY__HEADER__RESULTS_FAILURES = 'failures'
 KEY__HEADER__SCHEMA_VERSION = 'schemaVersion'
+KEY__HEADER__SET_A_DESCRIPTIONS = 'setA'
+KEY__HEADER__SET_B_DESCRIPTIONS = 'setB'
 KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE = 'timeNextUpdateAvailable'
 KEY__HEADER__TIME_UPDATED = 'timeUpdated'
 KEY__HEADER__TYPE = 'type'
@@ -43,6 +47,9 @@
 KEY__RESULT_TYPE__FAILUREIGNORED = gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED
 KEY__RESULT_TYPE__NOCOMPARISON = gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON
 KEY__RESULT_TYPE__SUCCEEDED = gm_json.JSONKEY_ACTUALRESULTS_SUCCEEDED
+KEY__SET_DESCRIPTIONS__DIR = 'dir'
+KEY__SET_DESCRIPTIONS__REPO_REVISION = 'repoRevision'
+KEY__SET_DESCRIPTIONS__SECTION = 'section'
 
 IMAGE_FILENAME_RE = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
 IMAGE_FILENAME_FORMATTER = '%s_%s.png'  # pass in (testname, config)
@@ -66,6 +73,11 @@
   """Base class for generating summary of comparisons between two image sets.
   """
 
+  def __init__(self):
+    """Base constructor; most subclasses will override."""
+    self._setA_descriptions = None
+    self._setB_descriptions = None
+
   def get_results_of_type(self, results_type):
     """Return results of some/all tests (depending on 'results_type' parameter).
 
@@ -92,7 +104,7 @@
     """
     response_dict = self._results[results_type]
     time_updated = self.get_timestamp()
-    response_dict[imagepairset.KEY__ROOT__HEADER] = {
+    header_dict = {
         KEY__HEADER__SCHEMA_VERSION: (
             VALUE__HEADER__SCHEMA_VERSION),
 
@@ -117,6 +129,11 @@
         # Whether the service is accessible from other hosts.
         KEY__HEADER__IS_EXPORTED: is_exported,
     }
+    if self._setA_descriptions:
+      header_dict[KEY__HEADER__SET_A_DESCRIPTIONS] = self._setA_descriptions
+    if self._setB_descriptions:
+      header_dict[KEY__HEADER__SET_B_DESCRIPTIONS] = self._setB_descriptions
+    response_dict[imagepairset.KEY__ROOT__HEADER] = header_dict
     return response_dict
 
   def get_timestamp(self):
@@ -196,12 +213,12 @@
     Raises:
       IOError if root does not refer to an existing directory
     """
-    # I considered making this call _read_dicts_from_root(), but I decided
+    # I considered making this call read_dicts_from_root(), but I decided
     # it was better to prune out the ignored builders within the os.walk().
     if not os.path.isdir(root):
       raise IOError('no directory found at path %s' % root)
     meta_dict = {}
-    for dirpath, dirnames, filenames in os.walk(root):
+    for dirpath, _, filenames in os.walk(root):
       for matching_filename in fnmatch.filter(filenames, pattern):
         builder = os.path.basename(dirpath)
         if self._ignore_builder(builder):
@@ -210,9 +227,13 @@
         meta_dict[builder] = gm_json.LoadFromFile(full_path)
     return meta_dict
 
-  def _read_dicts_from_root(self, root, pattern='*.json'):
+  @staticmethod
+  def read_dicts_from_root(root, pattern='*.json'):
     """Read all JSON dictionaries within a directory tree.
 
+    TODO(stephana): Factor this out into a utility module, as a standalone
+    function (not part of a class).
+
     Args:
       root: path to root of directory tree
       pattern: which files to read within root (fnmatch-style pattern)
@@ -228,7 +249,7 @@
     if not os.path.isdir(root):
       raise IOError('no directory found at path %s' % root)
     meta_dict = {}
-    for abs_dirpath, dirnames, filenames in os.walk(root):
+    for abs_dirpath, _, filenames in os.walk(root):
       rel_dirpath = os.path.relpath(abs_dirpath, root)
       for matching_filename in fnmatch.filter(filenames, pattern):
         abs_path = os.path.join(abs_dirpath, matching_filename)
@@ -293,7 +314,7 @@
     If this would result in any repeated keys, it will raise an Exception.
     """
     output_dict = {}
-    for key, subdict in input_dict.iteritems():
+    for subdict in input_dict.values():
       for subdict_key, subdict_value in subdict.iteritems():
         if subdict_key in output_dict:
           raise Exception('duplicate key %s in combine_subdicts' % subdict_key)
@@ -301,11 +322,22 @@
     return output_dict
 
   @staticmethod
-  def get_multilevel(input_dict, *keys):
-    """ Returns input_dict[key1][key2][...], or None if any key is not found.
+  def get_default(input_dict, default_value, *keys):
+    """Returns input_dict[key1][key2][...], or default_value.
+
+    If input_dict is None, or any key is missing along the way, this returns
+    default_value.
+
+    Args:
+      input_dict: dictionary to look within
+      key: key indicating which value to return from input_dict
+      default_value: value to return if input_dict is None or any key cannot
+          be found along the way
     """
+    if input_dict == None:
+      return default_value
     for key in keys:
-      if input_dict == None:
-        return None
       input_dict = input_dict.get(key, None)
+      if input_dict == None:
+        return default_value
     return input_dict
diff --git a/gm/rebaseline_server/rs_fixpypath.py b/gm/rebaseline_server/rs_fixpypath.py
new file mode 100755
index 0000000..cc32f4a
--- /dev/null
+++ b/gm/rebaseline_server/rs_fixpypath.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+
+"""
+Copyright 2014 Google Inc.
+
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+
+Adds possibly-needed directories to PYTHONPATH, if they aren't already there.
+"""
+
+import os
+import sys
+
+TRUNK_DIRECTORY = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), os.pardir, os.pardir))
+for subdir in ['common', 'gm', 'tools']:
+  fullpath = os.path.join(TRUNK_DIRECTORY, subdir)
+  if fullpath not in sys.path:
+    sys.path.append(fullpath)
diff --git a/gm/rebaseline_server/server.py b/gm/rebaseline_server/server.py
index 0079ec5..6062aed 100755
--- a/gm/rebaseline_server/server.py
+++ b/gm/rebaseline_server/server.py
@@ -23,23 +23,33 @@
 import thread
 import threading
 import time
+import urllib
 import urlparse
 
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
+
 # Imports from within Skia
-import fix_pythonpath  # must do this first
-from pyutils import gs_utils
+from py.utils import gs_utils
+import buildbot_globals
 import gm_json
 
 # Imports from local dir
 #
+# pylint: disable=C0301
 # Note: we import results under a different name, to avoid confusion with the
 # Server.results() property. See discussion at
 # https://codereview.chromium.org/195943004/diff/1/gm/rebaseline_server/server.py#newcode44
+# pylint: enable=C0301
 import compare_configs
+import compare_rendered_pictures
 import compare_to_expectations
 import download_actuals
+import imagediffdb
 import imagepairset
 import results as results_mod
+import writable_expectations as writable_expectations_mod
+
 
 PATHSPLIT_RE = re.compile('/([^/]+)/(.+)')
 
@@ -59,6 +69,9 @@
 KEY__EDITS__MODIFICATIONS = 'modifications'
 KEY__EDITS__OLD_RESULTS_HASH = 'oldResultsHash'
 KEY__EDITS__OLD_RESULTS_TYPE = 'oldResultsType'
+KEY__LIVE_EDITS__MODIFICATIONS = 'modifications'
+KEY__LIVE_EDITS__SET_A_DESCRIPTIONS = 'setA'
+KEY__LIVE_EDITS__SET_B_DESCRIPTIONS = 'setB'
 
 DEFAULT_ACTUALS_DIR = results_mod.DEFAULT_ACTUALS_DIR
 DEFAULT_GM_SUMMARIES_BUCKET = download_actuals.GM_SUMMARIES_BUCKET
@@ -67,9 +80,7 @@
 
 PARENT_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
 TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(PARENT_DIRECTORY))
-# Directory, relative to PARENT_DIRECTORY, within which the server will serve
-# out live results (not static files).
-RESULTS_SUBDIR = 'results'
+
 # Directory, relative to PARENT_DIRECTORY, within which the server will serve
 # out static files.
 STATIC_CONTENTS_SUBDIR = 'static'
@@ -78,17 +89,46 @@
 GENERATED_IMAGES_SUBDIR = 'generated-images'
 GENERATED_JSON_SUBDIR = 'generated-json'
 
+# Directives associated with various HTTP GET requests.
+GET__LIVE_RESULTS = 'live-results'
+GET__PRECOMPUTED_RESULTS = 'results'
+GET__PREFETCH_RESULTS = 'prefetch'
+GET__STATIC_CONTENTS = 'static'
+
+# Parameters we use within do_GET_live_results() and do_GET_prefetch_results()
+LIVE_PARAM__DOWNLOAD_ONLY_DIFFERING = 'downloadOnlyDifferingImages'
+LIVE_PARAM__SET_A_DIR = 'setADir'
+LIVE_PARAM__SET_A_SECTION = 'setASection'
+LIVE_PARAM__SET_B_DIR = 'setBDir'
+LIVE_PARAM__SET_B_SECTION = 'setBSection'
+
 # How often (in seconds) clients should reload while waiting for initial
 # results to load.
 RELOAD_INTERVAL_UNTIL_READY = 10
 
-SUMMARY_TYPES = [
+_GM_SUMMARY_TYPES = [
     results_mod.KEY__HEADER__RESULTS_FAILURES,
     results_mod.KEY__HEADER__RESULTS_ALL,
 ]
 # If --compare-configs is specified, compare these configs.
 CONFIG_PAIRS_TO_COMPARE = [('8888', 'gpu')]
 
+# SKP results that are available to compare.
+#
+# TODO(stephana): We don't actually want to maintain this list of platforms.
+# We are just putting them in here for now, as "convenience" links for testing
+# SKP diffs.
+# Ultimately, we will depend on buildbot steps linking to their own diffs on
+# the shared rebaseline_server instance.
+_SKP_BASE_GS_URL = 'gs://' + buildbot_globals.Get('skp_summaries_bucket')
+_SKP_BASE_REPO_URL = (
+    compare_rendered_pictures.REPO_URL_PREFIX + posixpath.join(
+        'expectations', 'skp'))
+_SKP_PLATFORMS = [
+    'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug',
+    'Test-Ubuntu12-ShuttleA-GTX660-x86-Release',
+]
+
 _HTTP_HEADER_CONTENT_LENGTH = 'Content-Length'
 _HTTP_HEADER_CONTENT_TYPE = 'Content-Type'
 
@@ -153,30 +193,67 @@
         '<!DOCTYPE html><html>'
         '<head><title>rebaseline_server</title></head>'
         '<body><ul>')
-    if SUMMARY_TYPES:
-      file_handle.write('<li>Expectations vs Actuals</li><ul>')
-      for summary_type in SUMMARY_TYPES:
+
+    if _GM_SUMMARY_TYPES:
+      file_handle.write('<li>GM Expectations vs Actuals</li><ul>')
+      for summary_type in _GM_SUMMARY_TYPES:
         file_handle.write(
-            '<li>'
-            '<a href="/%s/view.html#/view.html?resultsToLoad=/%s/%s">'
-            '%s</a></li>' % (
-                STATIC_CONTENTS_SUBDIR, RESULTS_SUBDIR,
-                summary_type, summary_type))
+            '\n<li><a href="/{static_directive}/view.html#/view.html?'
+            'resultsToLoad=/{results_directive}/{summary_type}">'
+            '{summary_type}</a></li>'.format(
+                results_directive=GET__PRECOMPUTED_RESULTS,
+                static_directive=GET__STATIC_CONTENTS,
+                summary_type=summary_type))
       file_handle.write('</ul>')
+
     if config_pairs:
-      file_handle.write('<li>Comparing configs within actual results</li><ul>')
+      file_handle.write(
+          '\n<li>Comparing configs within actual GM results</li><ul>')
       for config_pair in config_pairs:
         file_handle.write('<li>%s vs %s:' % config_pair)
-        for summary_type in SUMMARY_TYPES:
+        for summary_type in _GM_SUMMARY_TYPES:
           file_handle.write(
               ' <a href="/%s/view.html#/view.html?'
               'resultsToLoad=/%s/%s/%s-vs-%s_%s.json">%s</a>' % (
-                  STATIC_CONTENTS_SUBDIR, STATIC_CONTENTS_SUBDIR,
+                  GET__STATIC_CONTENTS, GET__STATIC_CONTENTS,
                   GENERATED_JSON_SUBDIR, config_pair[0], config_pair[1],
                   summary_type, summary_type))
         file_handle.write('</li>')
       file_handle.write('</ul>')
-    file_handle.write('</ul></body></html>')
+
+    if _SKP_PLATFORMS:
+      file_handle.write('\n<li>Rendered SKPs:<ul>')
+      for builder in _SKP_PLATFORMS:
+        file_handle.write(
+            '\n<li><a href="../live-view.html#live-view.html?%s">' %
+            urllib.urlencode({
+                LIVE_PARAM__SET_A_SECTION:
+                    gm_json.JSONKEY_EXPECTEDRESULTS,
+                LIVE_PARAM__SET_A_DIR:
+                    posixpath.join(_SKP_BASE_REPO_URL, builder),
+                LIVE_PARAM__SET_B_SECTION:
+                    gm_json.JSONKEY_ACTUALRESULTS,
+                LIVE_PARAM__SET_B_DIR:
+                    posixpath.join(_SKP_BASE_GS_URL, builder),
+            }))
+        file_handle.write('expected vs actuals on %s</a></li>' % builder)
+      file_handle.write(
+          '\n<li><a href="../live-view.html#live-view.html?%s">' %
+          urllib.urlencode({
+              LIVE_PARAM__SET_A_SECTION:
+                  gm_json.JSONKEY_ACTUALRESULTS,
+              LIVE_PARAM__SET_A_DIR:
+                  posixpath.join(_SKP_BASE_GS_URL, _SKP_PLATFORMS[0]),
+              LIVE_PARAM__SET_B_SECTION:
+                  gm_json.JSONKEY_ACTUALRESULTS,
+              LIVE_PARAM__SET_B_DIR:
+                  posixpath.join(_SKP_BASE_GS_URL, _SKP_PLATFORMS[1]),
+          }))
+      file_handle.write('actuals on %s vs %s</a></li>' % (
+          _SKP_PLATFORMS[0], _SKP_PLATFORMS[1]))
+      file_handle.write('</li>')
+
+    file_handle.write('\n</ul></body></html>')
 
 
 class Server(object):
@@ -187,7 +264,9 @@
                json_filename=DEFAULT_JSON_FILENAME,
                gm_summaries_bucket=DEFAULT_GM_SUMMARIES_BUCKET,
                port=DEFAULT_PORT, export=False, editable=True,
-               reload_seconds=0, config_pairs=None, builder_regex_list=None):
+               reload_seconds=0, config_pairs=None, builder_regex_list=None,
+               boto_file_path=None,
+               imagediffdb_threads=imagediffdb.DEFAULT_NUM_WORKER_THREADS):
     """
     Args:
       actuals_dir: directory under which we will check out the latest actual
@@ -198,7 +277,9 @@
           at all, just compare to whatever files are already in actuals_dir
       port: which TCP port to listen on for HTTP requests
       export: whether to allow HTTP clients on other hosts to access this server
-      editable: whether HTTP clients are allowed to submit new baselines
+      editable: whether HTTP clients are allowed to submit new GM baselines
+          (SKP baseline modifications are performed using an entirely different
+          mechanism, not affected by this parameter)
       reload_seconds: polling interval with which to check for new results;
           if 0, don't check for new results at all
       config_pairs: List of (string, string) tuples; for each tuple, compare
@@ -206,6 +287,10 @@
           don't compare configs at all.
       builder_regex_list: List of regular expressions specifying which builders
           we will process. If None, process all builders.
+      boto_file_path: Path to .boto file giving us credentials to access
+          Google Storage buckets; if None, we will only be able to access
+          public GS buckets.
+      imagediffdb_threads: How many threads to spin up within imagediffdb.
     """
     self._actuals_dir = actuals_dir
     self._json_filename = json_filename
@@ -216,6 +301,13 @@
     self._reload_seconds = reload_seconds
     self._config_pairs = config_pairs or []
     self._builder_regex_list = builder_regex_list
+    self.truncate_results = False
+
+    if boto_file_path:
+      self._gs = gs_utils.GSUtils(boto_file_path=boto_file_path)
+    else:
+      self._gs = gs_utils.GSUtils()
+
     _create_index(
         file_path=os.path.join(
             PARENT_DIRECTORY, STATIC_CONTENTS_SUBDIR, GENERATED_HTML_SUBDIR,
@@ -226,7 +318,16 @@
     # 1. self._results
     # 2. the expected or actual results on local disk
     self.results_rlock = threading.RLock()
-    # self._results will be filled in by calls to update_results()
+
+    # Create a single ImageDiffDB instance that is used by all our differs.
+    self._image_diff_db = imagediffdb.ImageDiffDB(
+        gs=self._gs,
+        storage_root=os.path.join(
+            PARENT_DIRECTORY, STATIC_CONTENTS_SUBDIR,
+            GENERATED_IMAGES_SUBDIR),
+        num_worker_threads=imagediffdb_threads)
+
+    # This will be filled in by calls to update_results()
     self._results = None
 
   @property
@@ -236,6 +337,16 @@
     return self._results
 
   @property
+  def image_diff_db(self):
+    """ Returns reference to our ImageDiffDB object."""
+    return self._image_diff_db
+
+  @property
+  def gs(self):
+    """ Returns reference to our GSUtils object."""
+    return self._gs
+
+  @property
   def is_exported(self):
     """ Returns true iff HTTP clients on other hosts are allowed to access
     this server. """
@@ -243,7 +354,13 @@
 
   @property
   def is_editable(self):
-    """ Returns true iff HTTP clients are allowed to submit new baselines. """
+    """ True iff HTTP clients are allowed to submit new GM baselines.
+
+    TODO(epoger): This only pertains to GM baselines; SKP baselines are
+    editable whenever expectations vs actuals are shown.
+    Once we move the GM baselines to use the same code as the SKP baselines,
+    we can delete this property.
+    """
     return self._editable
 
   @property
@@ -296,7 +413,7 @@
         # TODO(epoger): When this is a large number of builders, we would be
         # better off downloading them in parallel!
         for builder in matching_builders:
-          gs_utils.download_file(
+          self._gs.download_file(
               source_bucket=self._gm_summaries_bucket,
               source_path=posixpath.join(builder, self._json_filename),
               dest_path=os.path.join(self._actuals_dir, builder,
@@ -335,10 +452,8 @@
         _run_command(['gclient', 'sync'], TRUNK_DIRECTORY)
 
       self._results = compare_to_expectations.ExpectationComparisons(
+          image_diff_db=self._image_diff_db,
           actuals_root=self._actuals_dir,
-          generated_images_root=os.path.join(
-              PARENT_DIRECTORY, STATIC_CONTENTS_SUBDIR,
-              GENERATED_IMAGES_SUBDIR),
           diff_base_url=posixpath.join(
               os.pardir, STATIC_CONTENTS_SUBDIR, GENERATED_IMAGES_SUBDIR),
           builder_regex_list=self._builder_regex_list)
@@ -346,7 +461,7 @@
       json_dir = os.path.join(
           PARENT_DIRECTORY, STATIC_CONTENTS_SUBDIR, GENERATED_JSON_SUBDIR)
       if not os.path.isdir(json_dir):
-         os.makedirs(json_dir)
+        os.makedirs(json_dir)
 
       for config_pair in self._config_pairs:
         config_comparisons = compare_configs.ConfigComparisons(
@@ -358,7 +473,7 @@
             diff_base_url=posixpath.join(
                 os.pardir, GENERATED_IMAGES_SUBDIR),
             builder_regex_list=self._builder_regex_list)
-        for summary_type in SUMMARY_TYPES:
+        for summary_type in _GM_SUMMARY_TYPES:
           gm_json.WriteToFile(
               config_comparisons.get_packaged_results_of_type(
                   results_type=summary_type),
@@ -395,6 +510,7 @@
     else:
       host = '127.0.0.1'
       server_address = (host, self._port)
+    # pylint: disable=W0201
     http_server = BaseHTTPServer.HTTPServer(server_address, HTTPRequestHandler)
     self._url = 'http://%s:%d' % (host, http_server.server_port)
     logging.info('Listening for requests on %s' % self._url)
@@ -416,21 +532,22 @@
       logging.debug('do_GET: path="%s"' % self.path)
       if self.path == '' or self.path == '/' or self.path == '/index.html' :
         self.redirect_to('/%s/%s/index.html' % (
-            STATIC_CONTENTS_SUBDIR, GENERATED_HTML_SUBDIR))
+            GET__STATIC_CONTENTS, GENERATED_HTML_SUBDIR))
         return
       if self.path == '/favicon.ico' :
-        self.redirect_to('/%s/favicon.ico' % STATIC_CONTENTS_SUBDIR)
+        self.redirect_to('/%s/favicon.ico' % GET__STATIC_CONTENTS)
         return
 
       # All requests must be of this form:
       #   /dispatcher/remainder
       # where 'dispatcher' indicates which do_GET_* dispatcher to run
       # and 'remainder' is the remaining path sent to that dispatcher.
-      normpath = posixpath.normpath(self.path)
-      (dispatcher_name, remainder) = PATHSPLIT_RE.match(normpath).groups()
+      (dispatcher_name, remainder) = PATHSPLIT_RE.match(self.path).groups()
       dispatchers = {
-          RESULTS_SUBDIR: self.do_GET_results,
-          STATIC_CONTENTS_SUBDIR: self.do_GET_static,
+          GET__LIVE_RESULTS: self.do_GET_live_results,
+          GET__PRECOMPUTED_RESULTS: self.do_GET_precomputed_results,
+          GET__PREFETCH_RESULTS: self.do_GET_prefetch_results,
+          GET__STATIC_CONTENTS: self.do_GET_static,
       }
       dispatcher = dispatchers[dispatcher_name]
       dispatcher(remainder)
@@ -438,14 +555,15 @@
       self.send_error(404)
       raise
 
-  def do_GET_results(self, results_type):
-    """ Handle a GET request for GM results.
+  def do_GET_precomputed_results(self, results_type):
+    """ Handle a GET request for part of the precomputed _SERVER.results object.
 
     Args:
       results_type: string indicating which set of results to return;
             must be one of the results_mod.RESULTS_* constants
     """
-    logging.debug('do_GET_results: sending results of type "%s"' % results_type)
+    logging.debug('do_GET_precomputed_results: sending results of type "%s"' %
+                  results_type)
     # Since we must make multiple calls to the ExpectationComparisons object,
     # grab a reference to it in case it is updated to point at a new
     # ExpectationComparisons object within another thread.
@@ -473,6 +591,72 @@
       }
     self.send_json_dict(response_dict)
 
+  def _get_live_results_or_prefetch(self, url_remainder, prefetch_only=False):
+    """ Handle a GET request for live-generated image diff data.
+
+    Args:
+      url_remainder: string indicating which image diffs to generate
+      prefetch_only: if True, the user isn't waiting around for results
+    """
+    param_dict = urlparse.parse_qs(url_remainder)
+    download_all_images = (
+        param_dict.get(LIVE_PARAM__DOWNLOAD_ONLY_DIFFERING, [''])[0].lower()
+        not in ['1', 'true'])
+    setA_dir = param_dict[LIVE_PARAM__SET_A_DIR][0]
+    setB_dir = param_dict[LIVE_PARAM__SET_B_DIR][0]
+    setA_section = self._validate_summary_section(
+        param_dict.get(LIVE_PARAM__SET_A_SECTION, [None])[0])
+    setB_section = self._validate_summary_section(
+        param_dict.get(LIVE_PARAM__SET_B_SECTION, [None])[0])
+
+    # If the sets show expectations vs actuals, always show expectations on
+    # the left (setA).
+    if ((setA_section == gm_json.JSONKEY_ACTUALRESULTS) and
+        (setB_section == gm_json.JSONKEY_EXPECTEDRESULTS)):
+      setA_dir, setB_dir = setB_dir, setA_dir
+      setA_section, setB_section = setB_section, setA_section
+
+    # Are we comparing some actuals against expectations stored in the repo?
+    # If so, we can allow the user to submit new baselines.
+    is_editable = (
+        (setA_section == gm_json.JSONKEY_EXPECTEDRESULTS) and
+        (setA_dir.startswith(compare_rendered_pictures.REPO_URL_PREFIX)) and
+        (setB_section == gm_json.JSONKEY_ACTUALRESULTS))
+
+    results_obj = compare_rendered_pictures.RenderedPicturesComparisons(
+        setA_dir=setA_dir, setB_dir=setB_dir,
+        setA_section=setA_section, setB_section=setB_section,
+        image_diff_db=_SERVER.image_diff_db,
+        diff_base_url='/static/generated-images',
+        gs=_SERVER.gs, truncate_results=_SERVER.truncate_results,
+        prefetch_only=prefetch_only, download_all_images=download_all_images)
+    if prefetch_only:
+      self.send_response(200)
+    else:
+      self.send_json_dict(results_obj.get_packaged_results_of_type(
+          results_type=results_mod.KEY__HEADER__RESULTS_ALL,
+          is_editable=is_editable))
+
+  def do_GET_live_results(self, url_remainder):
+    """ Handle a GET request for live-generated image diff data.
+
+    Args:
+      url_remainder: string indicating which image diffs to generate
+    """
+    logging.debug('do_GET_live_results: url_remainder="%s"' % url_remainder)
+    self._get_live_results_or_prefetch(
+        url_remainder=url_remainder, prefetch_only=False)
+
+  def do_GET_prefetch_results(self, url_remainder):
+    """ Prefetch image diff data for a future do_GET_live_results() call.
+
+    Args:
+      url_remainder: string indicating which image diffs to generate
+    """
+    logging.debug('do_GET_prefetch_results: url_remainder="%s"' % url_remainder)
+    self._get_live_results_or_prefetch(
+        url_remainder=url_remainder, prefetch_only=True)
+
   def do_GET_static(self, path):
     """ Handle a GET request for a file under STATIC_CONTENTS_SUBDIR .
     Only allow serving of files within STATIC_CONTENTS_SUBDIR that is a
@@ -506,11 +690,11 @@
     normpath = posixpath.normpath(self.path)
     dispatchers = {
       '/edits': self.do_POST_edits,
+      '/live-edits': self.do_POST_live_edits,
     }
     try:
       dispatcher = dispatchers[normpath]
       dispatcher()
-      self.send_response(200)
     except:
       self.send_error(404)
       raise
@@ -570,6 +754,47 @@
     # We can do this in a separate thread; we should return our success message
     # to the UI as soon as possible.
     thread.start_new_thread(_SERVER.update_results, (True,))
+    self.send_response(200)
+
+  def do_POST_live_edits(self):
+    """ Handle a POST request with modifications to SKP expectations, in this
+    format:
+
+    {
+      KEY__LIVE_EDITS__SET_A_DESCRIPTIONS: {
+        # setA descriptions from the original data
+      },
+      KEY__LIVE_EDITS__SET_B_DESCRIPTIONS: {
+        # setB descriptions from the original data
+      },
+      KEY__LIVE_EDITS__MODIFICATIONS: [
+        # as needed by writable_expectations.modify()
+      ],
+    }
+
+    Raises an Exception if there were any problems.
+    """
+    content_type = self.headers[_HTTP_HEADER_CONTENT_TYPE]
+    if content_type != 'application/json;charset=UTF-8':
+      raise Exception('unsupported %s [%s]' % (
+          _HTTP_HEADER_CONTENT_TYPE, content_type))
+
+    content_length = int(self.headers[_HTTP_HEADER_CONTENT_LENGTH])
+    json_data = self.rfile.read(content_length)
+    data = json.loads(json_data)
+    logging.debug('do_POST_live_edits: received new GM expectations data [%s]' %
+                  data)
+    with writable_expectations_mod.WritableExpectations(
+        data[KEY__LIVE_EDITS__SET_A_DESCRIPTIONS]) as writable_expectations:
+      writable_expectations.modify(data[KEY__LIVE_EDITS__MODIFICATIONS])
+      diffs = writable_expectations.get_diffs()
+      # TODO(stephana): Move to a simpler web framework so we don't have to
+      # call these functions.  See http://skbug.com/2856 ('rebaseline_server:
+      # Refactor server to use a simple web framework')
+      self.send_response(200)
+      self.send_header('Content-type', 'text/plain')
+      self.end_headers()
+      self.wfile.write(diffs)
 
   def redirect_to(self, url):
     """ Redirect the HTTP client to a different url.
@@ -618,6 +843,21 @@
     self.end_headers()
     json.dump(json_dict, self.wfile)
 
+  def _validate_summary_section(self, section_name):
+    """Validates the section we have been requested to read within JSON summary.
+
+    Args:
+      section_name: which section of the JSON summary file has been requested
+
+    Returns: the validated section name
+
+    Raises: Exception if an invalid section_name was requested.
+    """
+    if section_name not in compare_rendered_pictures.ALLOWED_SECTION_NAMES:
+      raise Exception('requested section name "%s" not in allowed list %s' % (
+          section_name, compare_rendered_pictures.ALLOWED_SECTION_NAMES))
+    return section_name
+
 
 def main():
   logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
@@ -629,6 +869,12 @@
                           'actual GM results. If this directory does not '
                           'exist, it will be created. Defaults to %(default)s'),
                     default=DEFAULT_ACTUALS_DIR)
+  parser.add_argument('--boto',
+                    help=('Path to .boto file giving us credentials to access '
+                          'Google Storage buckets. If not specified, we will '
+                          'only be able to access public GS buckets (and thus '
+                          'won\'t be able to download SKP images).'),
+                    default='')
   # TODO(epoger): Before https://codereview.chromium.org/310093003 ,
   # when this tool downloaded the JSON summaries from skia-autogen,
   # it had an --actuals-revision the caller could specify to download
@@ -644,7 +890,9 @@
                             'differences between these config pairs: '
                             + str(CONFIG_PAIRS_TO_COMPARE)))
   parser.add_argument('--editable', action='store_true',
-                      help=('Allow HTTP clients to submit new baselines.'))
+                      help=('Allow HTTP clients to submit new GM baselines; '
+                            'SKP baselines can be edited regardless of this '
+                            'setting.'))
   parser.add_argument('--export', action='store_true',
                       help=('Instead of only allowing access from HTTP clients '
                             'on localhost, allow HTTP clients on other hosts '
@@ -674,6 +922,14 @@
                             'By default, we do not reload at all, and you '
                             'must restart the server to pick up new data.'),
                       default=0)
+  parser.add_argument('--threads', type=int,
+                      help=('How many parallel threads we use to download '
+                            'images and generate diffs; defaults to '
+                            '%(default)s'),
+                      default=imagediffdb.DEFAULT_NUM_WORKER_THREADS)
+  parser.add_argument('--truncate', action='store_true',
+                      help=('FOR TESTING ONLY: truncate the set of images we '
+                            'process, to speed up testing.'))
   args = parser.parse_args()
   if args.compare_configs:
     config_pairs = CONFIG_PAIRS_TO_COMPARE
@@ -686,7 +942,10 @@
                    gm_summaries_bucket=args.gm_summaries_bucket,
                    port=args.port, export=args.export, editable=args.editable,
                    reload_seconds=args.reload, config_pairs=config_pairs,
-                   builder_regex_list=args.builders)
+                   builder_regex_list=args.builders, boto_file_path=args.boto,
+                   imagediffdb_threads=args.threads)
+  if args.truncate:
+    _SERVER.truncate_results = True
   _SERVER.run()
 
 
diff --git a/gm/rebaseline_server/static/constants.js b/gm/rebaseline_server/static/constants.js
index 7db245d..a9601ec 100644
--- a/gm/rebaseline_server/static/constants.js
+++ b/gm/rebaseline_server/static/constants.js
@@ -13,6 +13,7 @@
     KEY__EXTRACOLUMNHEADERS__HEADER_URL: 'headerUrl',
     KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE: 'isFilterable',
     KEY__EXTRACOLUMNHEADERS__IS_SORTABLE: 'isSortable',
+    KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER: 'useFreeformFilter',
     KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS: 'valuesAndCounts',
 
     // NOTE: Keep these in sync with ../imagediffdb.py
@@ -20,6 +21,8 @@
     KEY__DIFFERENCES__NUM_DIFF_PIXELS: 'numDifferingPixels',
     KEY__DIFFERENCES__PERCENT_DIFF_PIXELS: 'percentDifferingPixels',
     KEY__DIFFERENCES__PERCEPTUAL_DIFF: 'perceptualDifference',
+    KEY__DIFFERENCES__DIFF_URL: 'diffUrl',
+    KEY__DIFFERENCES__WHITE_DIFF_URL: 'whiteDiffUrl',
 
     // NOTE: Keep these in sync with ../imagepair.py
     KEY__IMAGEPAIRS__DIFFERENCES: 'differenceData',
@@ -28,9 +31,11 @@
     KEY__IMAGEPAIRS__IMAGE_A_URL: 'imageAUrl',
     KEY__IMAGEPAIRS__IMAGE_B_URL: 'imageBUrl',
     KEY__IMAGEPAIRS__IS_DIFFERENT: 'isDifferent',
+    KEY__IMAGEPAIRS__SOURCE_JSON_FILE: 'sourceJsonFile',
 
     // NOTE: Keep these in sync with ../imagepairset.py
     KEY__ROOT__EXTRACOLUMNHEADERS: 'extraColumnHeaders',
+    KEY__ROOT__EXTRACOLUMNORDER: 'extraColumnOrder',
     KEY__ROOT__HEADER: 'header',
     KEY__ROOT__IMAGEPAIRS: 'imagePairs',
     KEY__ROOT__IMAGESETS: 'imageSets',
@@ -59,22 +64,37 @@
     KEY__HEADER__RESULTS_ALL: 'all',
     KEY__HEADER__RESULTS_FAILURES: 'failures',
     KEY__HEADER__SCHEMA_VERSION: 'schemaVersion',
+    KEY__HEADER__SET_A_DESCRIPTIONS: 'setA',
+    KEY__HEADER__SET_B_DESCRIPTIONS: 'setB',
     KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE: 'timeNextUpdateAvailable',
     KEY__HEADER__TIME_UPDATED: 'timeUpdated',
     KEY__HEADER__TYPE: 'type',
-    VALUE__HEADER__SCHEMA_VERSION: 3,
+    VALUE__HEADER__SCHEMA_VERSION: 5,
     //
     KEY__RESULT_TYPE__FAILED: 'failed',
     KEY__RESULT_TYPE__FAILUREIGNORED: 'failure-ignored',
     KEY__RESULT_TYPE__NOCOMPARISON: 'no-comparison',
     KEY__RESULT_TYPE__SUCCEEDED: 'succeeded',
+    //
+    KEY__SET_DESCRIPTIONS__DIR: 'dir',
+    KEY__SET_DESCRIPTIONS__REPO_REVISION: 'repoRevision',
+    KEY__SET_DESCRIPTIONS__SECTION: 'section',
 
     // NOTE: Keep these in sync with ../server.py
     KEY__EDITS__MODIFICATIONS: 'modifications',
     KEY__EDITS__OLD_RESULTS_HASH: 'oldResultsHash',
     KEY__EDITS__OLD_RESULTS_TYPE: 'oldResultsType',
+    KEY__LIVE_EDITS__MODIFICATIONS: 'modifications',
+    KEY__LIVE_EDITS__SET_A_DESCRIPTIONS: 'setA',
+    KEY__LIVE_EDITS__SET_B_DESCRIPTIONS: 'setB',
 
     // These are just used on the client side, no need to sync with server code.
     KEY__IMAGEPAIRS__ROWSPAN: 'rowspan',
+    URL_KEY__SCHEMA_VERSION: 'urlSchemaVersion',
+    URL_VALUE__SCHEMA_VERSION__CURRENT: 1,
+
+    // Utility constants only used on the client side. 
+    ASC: 'asc',
+    DESC: 'desc',
   }
 })())
diff --git a/gm/rebaseline_server/static/live-loader.js b/gm/rebaseline_server/static/live-loader.js
new file mode 100644
index 0000000..ab15aee
--- /dev/null
+++ b/gm/rebaseline_server/static/live-loader.js
@@ -0,0 +1,1024 @@
+/*
+ * Loader:
+ * Reads GM result reports written out by results.py, and imports
+ * them into $scope.extraColumnHeaders and $scope.imagePairs .
+ */
+var Loader = angular.module(
+    'Loader',
+    ['ConstantsModule']
+);
+
+// This configuration is needed to allow downloads of the diff patch.
+// See https://github.com/angular/angular.js/issues/3889
+Loader.config(['$compileProvider', function($compileProvider) {
+  $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|file|blob):/);
+}]);
+
+Loader.directive(
+  'resultsUpdatedCallbackDirective',
+  ['$timeout',
+   function($timeout) {
+     return function(scope, element, attrs) {
+       if (scope.$last) {
+         $timeout(function() {
+           scope.resultsUpdatedCallback();
+         });
+       }
+     };
+   }
+  ]
+);
+
+// TODO(epoger): Combine ALL of our filtering operations (including
+// truncation) into this one filter, so that runs most efficiently?
+// (We would have to make sure truncation still took place after
+// sorting, though.)
+Loader.filter(
+  'removeHiddenImagePairs',
+  function(constants) {
+    return function(unfilteredImagePairs, filterableColumnNames, showingColumnValues,
+                    viewingTab) {
+      var filteredImagePairs = [];
+      for (var i = 0; i < unfilteredImagePairs.length; i++) {
+        var imagePair = unfilteredImagePairs[i];
+        var extraColumnValues = imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS];
+        var allColumnValuesAreVisible = true;
+        // Loop over all columns, and if any of them contain values not found in
+        // showingColumnValues[columnName], don't include this imagePair.
+        //
+        // We use this same filtering mechanism regardless of whether each column
+        // has USE_FREEFORM_FILTER set or not; if that flag is set, then we will
+        // have already used the freeform text entry block to populate
+        // showingColumnValues[columnName].
+        for (var j = 0; j < filterableColumnNames.length; j++) {
+          var columnName = filterableColumnNames[j];
+          var columnValue = extraColumnValues[columnName];
+          if (!showingColumnValues[columnName][columnValue]) {
+            allColumnValuesAreVisible = false;
+            break;
+          }
+        }
+        if (allColumnValuesAreVisible && (viewingTab == imagePair.tab)) {
+          filteredImagePairs.push(imagePair);
+        }
+      }
+      return filteredImagePairs;
+    };
+  }
+);
+
+/**
+ * Limit the input imagePairs to some max number, and merge identical rows
+ * (adjacent rows which have the same (imageA, imageB) pair).
+ *
+ * @param unfilteredImagePairs imagePairs to filter
+ * @param maxPairs maximum number of pairs to output, or <0 for no limit
+ * @param mergeIdenticalRows if true, merge identical rows by setting
+ *     ROWSPAN>1 on the first merged row, and ROWSPAN=0 for the rest
+ */
+Loader.filter(
+  'mergeAndLimit',
+  function(constants) {
+    return function(unfilteredImagePairs, maxPairs, mergeIdenticalRows) {
+      var numPairs = unfilteredImagePairs.length;
+      if ((maxPairs > 0) && (maxPairs < numPairs)) {
+        numPairs = maxPairs;
+      }
+      var filteredImagePairs = [];
+      if (!mergeIdenticalRows || (numPairs == 1)) {
+        // Take a shortcut if we're not merging identical rows.
+        // We still need to set ROWSPAN to 1 for each row, for the HTML viewer.
+        for (var i = numPairs-1; i >= 0; i--) {
+          var imagePair = unfilteredImagePairs[i];
+          imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] = 1;
+          filteredImagePairs[i] = imagePair;
+        }
+      } else if (numPairs > 1) {
+        // General case--there are at least 2 rows, so we may need to merge some.
+        // Work from the bottom up, so we can keep a running total of how many
+        // rows should be merged, and set ROWSPAN of the top row accordingly.
+        var imagePair = unfilteredImagePairs[numPairs-1];
+        var nextRowImageAUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL];
+        var nextRowImageBUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
+        imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] = 1;
+        filteredImagePairs[numPairs-1] = imagePair;
+        for (var i = numPairs-2; i >= 0; i--) {
+          imagePair = unfilteredImagePairs[i];
+          var thisRowImageAUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL];
+          var thisRowImageBUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
+          if ((thisRowImageAUrl == nextRowImageAUrl) &&
+              (thisRowImageBUrl == nextRowImageBUrl)) {
+            imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] =
+                filteredImagePairs[i+1][constants.KEY__IMAGEPAIRS__ROWSPAN] + 1;
+            filteredImagePairs[i+1][constants.KEY__IMAGEPAIRS__ROWSPAN] = 0;
+          } else {
+            imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] = 1;
+            nextRowImageAUrl = thisRowImageAUrl;
+            nextRowImageBUrl = thisRowImageBUrl;
+          }
+          filteredImagePairs[i] = imagePair;
+        }
+      } else {
+        // No results.
+      }
+      return filteredImagePairs;
+    };
+  }
+);
+
+
+Loader.controller(
+  'Loader.Controller',
+    function($scope, $http, $filter, $location, $log, $timeout, constants) {
+    $scope.readyToDisplay = false;
+    $scope.constants = constants;
+    $scope.windowTitle = "Loading GM Results...";
+    $scope.setADir = $location.search().setADir;
+    $scope.setASection = $location.search().setASection;
+    $scope.setBDir = $location.search().setBDir;
+    $scope.setBSection = $location.search().setBSection;
+    $scope.loadingMessage = "please wait...";
+
+    var currSortAsc = true; 
+
+
+    /**
+     * On initial page load, load a full dictionary of results.
+     * Once the dictionary is loaded, unhide the page elements so they can
+     * render the data.
+     */
+    $scope.liveQueryUrl =
+       "/live-results/setADir=" + encodeURIComponent($scope.setADir) +
+       "&setASection=" + encodeURIComponent($scope.setASection) +
+       "&setBDir=" + encodeURIComponent($scope.setBDir) +
+       "&setBSection=" + encodeURIComponent($scope.setBSection);
+    $http.get($scope.liveQueryUrl).success(
+      function(data, status, header, config) {
+        var dataHeader = data[constants.KEY__ROOT__HEADER];
+        if (dataHeader[constants.KEY__HEADER__SCHEMA_VERSION] !=
+            constants.VALUE__HEADER__SCHEMA_VERSION) {
+          $scope.loadingMessage = "ERROR: Got JSON file with schema version "
+              + dataHeader[constants.KEY__HEADER__SCHEMA_VERSION]
+              + " but expected schema version "
+              + constants.VALUE__HEADER__SCHEMA_VERSION;
+        } else if (dataHeader[constants.KEY__HEADER__IS_STILL_LOADING]) {
+          // Apply the server's requested reload delay to local time,
+          // so we will wait the right number of seconds regardless of clock
+          // skew between client and server.
+          var reloadDelayInSeconds =
+              dataHeader[constants.KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE] -
+              dataHeader[constants.KEY__HEADER__TIME_UPDATED];
+          var timeNow = new Date().getTime();
+          var timeToReload = timeNow + reloadDelayInSeconds * 1000;
+          $scope.loadingMessage =
+              "server is still loading results; will retry at " +
+              $scope.localTimeString(timeToReload / 1000);
+          $timeout(
+              function(){location.reload();},
+              timeToReload - timeNow);
+        } else {
+          $scope.loadingMessage = "processing data, please wait...";
+
+          $scope.header = dataHeader;
+          $scope.extraColumnHeaders = data[constants.KEY__ROOT__EXTRACOLUMNHEADERS];
+          $scope.orderedColumnNames = data[constants.KEY__ROOT__EXTRACOLUMNORDER];
+          $scope.imagePairs = data[constants.KEY__ROOT__IMAGEPAIRS];
+          $scope.imageSets = data[constants.KEY__ROOT__IMAGESETS];
+
+          // set the default sort column and make it ascending.
+          $scope.sortColumnSubdict = constants.KEY__IMAGEPAIRS__DIFFERENCES;
+          $scope.sortColumnKey = constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF;
+          currSortAsc = true;
+
+          $scope.showSubmitAdvancedSettings = false;
+          $scope.submitAdvancedSettings = {};
+          $scope.submitAdvancedSettings[
+              constants.KEY__EXPECTATIONS__REVIEWED] = true;
+          $scope.submitAdvancedSettings[
+              constants.KEY__EXPECTATIONS__IGNOREFAILURE] = false;
+          $scope.submitAdvancedSettings['bug'] = '';
+
+          // Create the list of tabs (lists into which the user can file each
+          // test).  This may vary, depending on isEditable.
+          $scope.tabs = [
+            'Unfiled', 'Hidden'
+          ];
+          if (dataHeader[constants.KEY__HEADER__IS_EDITABLE]) {
+            $scope.tabs = $scope.tabs.concat(
+                ['Pending Approval']);
+          }
+          $scope.defaultTab = $scope.tabs[0];
+          $scope.viewingTab = $scope.defaultTab;
+
+          // Track the number of results on each tab.
+          $scope.numResultsPerTab = {};
+          for (var i = 0; i < $scope.tabs.length; i++) {
+            $scope.numResultsPerTab[$scope.tabs[i]] = 0;
+          }
+          $scope.numResultsPerTab[$scope.defaultTab] = $scope.imagePairs.length;
+
+          // Add index and tab fields to all records.
+          for (var i = 0; i < $scope.imagePairs.length; i++) {
+            $scope.imagePairs[i].index = i;
+            $scope.imagePairs[i].tab = $scope.defaultTab;
+          }
+
+          // Arrays within which the user can toggle individual elements.
+          $scope.selectedImagePairs = [];
+
+          // Set up filters.
+          //
+          // filterableColumnNames is a list of all column names we can filter on.
+          // allColumnValues[columnName] is a list of all known values
+          // for a given column.
+          // showingColumnValues[columnName] is a set indicating which values
+          // in a given column would cause us to show a row, rather than hiding it.
+          //
+          // columnStringMatch[columnName] is a string used as a pattern to generate
+          // showingColumnValues[columnName] for columns we filter using free-form text.
+          // It is ignored for any columns with USE_FREEFORM_FILTER == false.
+          $scope.filterableColumnNames = [];
+          $scope.allColumnValues = {};
+          $scope.showingColumnValues = {};
+          $scope.columnStringMatch = {};
+
+          angular.forEach(
+            Object.keys($scope.extraColumnHeaders),
+            function(columnName) {
+              var columnHeader = $scope.extraColumnHeaders[columnName];
+              if (columnHeader[constants.KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE]) {
+                $scope.filterableColumnNames.push(columnName);
+                $scope.allColumnValues[columnName] = $scope.columnSliceOf2DArray(
+                    columnHeader[constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS], 0);
+                $scope.showingColumnValues[columnName] = {};
+                $scope.toggleValuesInSet($scope.allColumnValues[columnName],
+                                         $scope.showingColumnValues[columnName]);
+                $scope.columnStringMatch[columnName] = "";
+              }
+            }
+          );
+
+          // TODO(epoger): Special handling for RESULT_TYPE column:
+          // by default, show only KEY__RESULT_TYPE__FAILED results
+          $scope.showingColumnValues[constants.KEY__EXTRACOLUMNS__RESULT_TYPE] = {};
+          $scope.showingColumnValues[constants.KEY__EXTRACOLUMNS__RESULT_TYPE][
+              constants.KEY__RESULT_TYPE__FAILED] = true;
+
+          // Set up mapping for URL parameters.
+          // parameter name -> copier object to load/save parameter value
+          $scope.queryParameters.map = {
+            'setADir':               $scope.queryParameters.copiers.simple,
+            'setASection':           $scope.queryParameters.copiers.simple,
+            'setBDir':               $scope.queryParameters.copiers.simple,
+            'setBSection':           $scope.queryParameters.copiers.simple,
+            'displayLimitPending':   $scope.queryParameters.copiers.simple,
+            'showThumbnailsPending': $scope.queryParameters.copiers.simple,
+            'mergeIdenticalRowsPending': $scope.queryParameters.copiers.simple,
+            'imageSizePending':      $scope.queryParameters.copiers.simple,
+            'sortColumnSubdict':     $scope.queryParameters.copiers.simple,
+            'sortColumnKey':         $scope.queryParameters.copiers.simple,
+          };
+          // Some parameters are handled differently based on whether they USE_FREEFORM_FILTER.
+          angular.forEach(
+            $scope.filterableColumnNames,
+            function(columnName) {
+              if ($scope.extraColumnHeaders[columnName]
+                  [constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]) {
+                $scope.queryParameters.map[columnName] =
+                    $scope.queryParameters.copiers.columnStringMatch;
+              } else {
+                $scope.queryParameters.map[columnName] =
+                    $scope.queryParameters.copiers.showingColumnValuesSet;
+              }
+            }
+          );
+
+          // If any defaults were overridden in the URL, get them now.
+          $scope.queryParameters.load();
+
+          // Any image URLs which are relative should be relative to the JSON
+          // file's source directory; absolute URLs should be left alone.
+          var baseUrlKey = constants.KEY__IMAGESETS__FIELD__BASE_URL;
+          angular.forEach(
+            $scope.imageSets,
+            function(imageSet) {
+              var baseUrl = imageSet[baseUrlKey];
+              if ((baseUrl.substring(0, 1) != '/') &&
+                  (baseUrl.indexOf('://') == -1)) {
+                imageSet[baseUrlKey] = '/' + baseUrl;
+              }
+            }
+          );
+
+          $scope.readyToDisplay = true;
+          $scope.updateResults();
+          $scope.loadingMessage = "";
+          $scope.windowTitle = "Current GM Results";
+
+          $timeout( function() {
+            make_results_header_sticky();
+          });
+        }
+      }
+    ).error(
+      function(data, status, header, config) {
+        $scope.loadingMessage = "FAILED to load.";
+        $scope.windowTitle = "Failed to Load GM Results";
+      }
+    );
+
+
+    //
+    // Select/Clear/Toggle all tests.
+    //
+
+    /**
+     * Select all currently showing tests.
+     */
+    $scope.selectAllImagePairs = function() {
+      var numImagePairsShowing = $scope.limitedImagePairs.length;
+      for (var i = 0; i < numImagePairsShowing; i++) {
+        var index = $scope.limitedImagePairs[i].index;
+        if (!$scope.isValueInArray(index, $scope.selectedImagePairs)) {
+          $scope.toggleValueInArray(index, $scope.selectedImagePairs);
+        }
+      }
+    }
+
+    /**
+     * Deselect all currently showing tests.
+     */
+    $scope.clearAllImagePairs = function() {
+      var numImagePairsShowing = $scope.limitedImagePairs.length;
+      for (var i = 0; i < numImagePairsShowing; i++) {
+        var index = $scope.limitedImagePairs[i].index;
+        if ($scope.isValueInArray(index, $scope.selectedImagePairs)) {
+          $scope.toggleValueInArray(index, $scope.selectedImagePairs);
+        }
+      }
+    }
+
+    /**
+     * Toggle selection of all currently showing tests.
+     */
+    $scope.toggleAllImagePairs = function() {
+      var numImagePairsShowing = $scope.limitedImagePairs.length;
+      for (var i = 0; i < numImagePairsShowing; i++) {
+        var index = $scope.limitedImagePairs[i].index;
+        $scope.toggleValueInArray(index, $scope.selectedImagePairs);
+      }
+    }
+
+    /**
+     * Toggle selection state of a subset of the currently showing tests.
+     *
+     * @param startIndex index within $scope.limitedImagePairs of the first
+     *     test to toggle selection state of
+     * @param num number of tests (in a contiguous block) to toggle
+     */
+    $scope.toggleSomeImagePairs = function(startIndex, num) {
+      var numImagePairsShowing = $scope.limitedImagePairs.length;
+      for (var i = startIndex; i < startIndex + num; i++) {
+        var index = $scope.limitedImagePairs[i].index;
+        $scope.toggleValueInArray(index, $scope.selectedImagePairs);
+      }
+    }
+
+
+    //
+    // Tab operations.
+    //
+
+    /**
+     * Change the selected tab.
+     *
+     * @param tab (string): name of the tab to select
+     */
+    $scope.setViewingTab = function(tab) {
+      $scope.viewingTab = tab;
+      $scope.updateResults();
+    }
+
+    /**
+     * Move the imagePairs in $scope.selectedImagePairs to a different tab,
+     * and then clear $scope.selectedImagePairs.
+     *
+     * @param newTab (string): name of the tab to move the tests to
+     */
+    $scope.moveSelectedImagePairsToTab = function(newTab) {
+      $scope.moveImagePairsToTab($scope.selectedImagePairs, newTab);
+      $scope.selectedImagePairs = [];
+      $scope.updateResults();
+    }
+
+    /**
+     * Move a subset of $scope.imagePairs to a different tab.
+     *
+     * @param imagePairIndices (array of ints): indices into $scope.imagePairs
+     *        indicating which test results to move
+     * @param newTab (string): name of the tab to move the tests to
+     */
+    $scope.moveImagePairsToTab = function(imagePairIndices, newTab) {
+      var imagePairIndex;
+      var numImagePairs = imagePairIndices.length;
+      for (var i = 0; i < numImagePairs; i++) {
+        imagePairIndex = imagePairIndices[i];
+        $scope.numResultsPerTab[$scope.imagePairs[imagePairIndex].tab]--;
+        $scope.imagePairs[imagePairIndex].tab = newTab;
+      }
+      $scope.numResultsPerTab[newTab] += numImagePairs;
+    }
+
+
+    //
+    // $scope.queryParameters:
+    // Transfer parameter values between $scope and the URL query string.
+    //
+    $scope.queryParameters = {};
+
+    // load and save functions for parameters of each type
+    // (load a parameter value into $scope from nameValuePairs,
+    //  save a parameter value from $scope into nameValuePairs)
+    $scope.queryParameters.copiers = {
+      'simple': {
+        'load': function(nameValuePairs, name) {
+          var value = nameValuePairs[name];
+          if (value) {
+            $scope[name] = value;
+          }
+        },
+        'save': function(nameValuePairs, name) {
+          nameValuePairs[name] = $scope[name];
+        }
+      },
+
+      'columnStringMatch': {
+        'load': function(nameValuePairs, name) {
+          var value = nameValuePairs[name];
+          if (value) {
+            $scope.columnStringMatch[name] = value;
+          }
+        },
+        'save': function(nameValuePairs, name) {
+          nameValuePairs[name] = $scope.columnStringMatch[name];
+        }
+      },
+
+      'showingColumnValuesSet': {
+        'load': function(nameValuePairs, name) {
+          var value = nameValuePairs[name];
+          if (value) {
+            var valueArray = value.split(',');
+            $scope.showingColumnValues[name] = {};
+            $scope.toggleValuesInSet(valueArray, $scope.showingColumnValues[name]);
+          }
+        },
+        'save': function(nameValuePairs, name) {
+          nameValuePairs[name] = Object.keys($scope.showingColumnValues[name]).join(',');
+        }
+      },
+
+    };
+
+    // Loads all parameters into $scope from the URL query string;
+    // any which are not found within the URL will keep their current value.
+    $scope.queryParameters.load = function() {
+      var nameValuePairs = $location.search();
+
+      // If urlSchemaVersion is not specified, we assume the current version.
+      var urlSchemaVersion = constants.URL_VALUE__SCHEMA_VERSION__CURRENT;
+      if (constants.URL_KEY__SCHEMA_VERSION in nameValuePairs) {
+        urlSchemaVersion = nameValuePairs[constants.URL_KEY__SCHEMA_VERSION];
+      } else if ('hiddenResultTypes' in nameValuePairs) {
+        // The combination of:
+        // - absence of an explicit urlSchemaVersion, and
+        // - presence of the old 'hiddenResultTypes' field
+        // tells us that the URL is from the original urlSchemaVersion.
+        // See https://codereview.chromium.org/367173002/
+        urlSchemaVersion = 0;
+      }
+      $scope.urlSchemaVersionLoaded = urlSchemaVersion;
+
+      if (urlSchemaVersion != constants.URL_VALUE__SCHEMA_VERSION__CURRENT) {
+        nameValuePairs = $scope.upconvertUrlNameValuePairs(nameValuePairs, urlSchemaVersion);
+      }
+      angular.forEach($scope.queryParameters.map,
+                      function(copier, paramName) {
+                        copier.load(nameValuePairs, paramName);
+                      }
+                     );
+    };
+
+    // Saves all parameters from $scope into the URL query string.
+    $scope.queryParameters.save = function() {
+      var nameValuePairs = {};
+      nameValuePairs[constants.URL_KEY__SCHEMA_VERSION] = constants.URL_VALUE__SCHEMA_VERSION__CURRENT;
+      angular.forEach($scope.queryParameters.map,
+                      function(copier, paramName) {
+                        copier.save(nameValuePairs, paramName);
+                      }
+                     );
+      $location.search(nameValuePairs);
+    };
+
+    /**
+     * Converts URL name/value pairs that were stored by a previous urlSchemaVersion
+     * to the currently needed format.
+     *
+     * @param oldNValuePairs name/value pairs found in the loaded URL
+     * @param oldUrlSchemaVersion which version of the schema was used to generate that URL
+     *
+     * @returns nameValuePairs as needed by the current URL parser
+     */
+    $scope.upconvertUrlNameValuePairs = function(oldNameValuePairs, oldUrlSchemaVersion) {
+      var newNameValuePairs = {};
+      angular.forEach(oldNameValuePairs,
+                      function(value, name) {
+                        if (oldUrlSchemaVersion < 1) {
+                          if ('hiddenConfigs' == name) {
+                            name = 'config';
+                            var valueSet = {};
+                            $scope.toggleValuesInSet(value.split(','), valueSet);
+                            $scope.toggleValuesInSet(
+                                $scope.allColumnValues[constants.KEY__EXTRACOLUMNS__CONFIG],
+                                valueSet);
+                            value = Object.keys(valueSet).join(',');
+                          } else if ('hiddenResultTypes' == name) {
+                            name = 'resultType';
+                            var valueSet = {};
+                            $scope.toggleValuesInSet(value.split(','), valueSet);
+                            $scope.toggleValuesInSet(
+                                $scope.allColumnValues[constants.KEY__EXTRACOLUMNS__RESULT_TYPE],
+                                valueSet);
+                            value = Object.keys(valueSet).join(',');
+                          }
+                        }
+
+                        newNameValuePairs[name] = value;
+                      }
+                     );
+      return newNameValuePairs;
+    }
+
+
+    //
+    // updateResults() and friends.
+    //
+
+    /**
+     * Set $scope.areUpdatesPending (to enable/disable the Update Results
+     * button).
+     *
+     * TODO(epoger): We could reduce the amount of code by just setting the
+     * variable directly (from, e.g., a button's ng-click handler).  But when
+     * I tried that, the HTML elements depending on the variable did not get
+     * updated.
+     * It turns out that this is due to variable scoping within an ng-repeat
+     * element; see http://stackoverflow.com/questions/15388344/behavior-of-assignment-expression-invoked-by-ng-click-within-ng-repeat
+     *
+     * @param val boolean value to set $scope.areUpdatesPending to
+     */
+    $scope.setUpdatesPending = function(val) {
+      $scope.areUpdatesPending = val;
+    }
+
+    /**
+     * Update the displayed results, based on filters/settings,
+     * and call $scope.queryParameters.save() so that the new filter results
+     * can be bookmarked.
+     */
+    $scope.updateResults = function() {
+      $scope.renderStartTime = window.performance.now();
+      $log.debug("renderStartTime: " + $scope.renderStartTime);
+      $scope.displayLimit = $scope.displayLimitPending;
+      $scope.mergeIdenticalRows = $scope.mergeIdenticalRowsPending;
+
+      // For each USE_FREEFORM_FILTER column, populate showingColumnValues.
+      // This is more efficient than applying the freeform filter within the
+      // tight loop in removeHiddenImagePairs.
+      angular.forEach(
+        $scope.filterableColumnNames,
+        function(columnName) {
+          var columnHeader = $scope.extraColumnHeaders[columnName];
+          if (columnHeader[constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]) {
+            var columnStringMatch = $scope.columnStringMatch[columnName];
+            var showingColumnValues = {};
+            angular.forEach(
+              $scope.allColumnValues[columnName],
+              function(columnValue) {
+                if (-1 != columnValue.indexOf(columnStringMatch)) {
+                  showingColumnValues[columnValue] = true;
+                }
+              }
+            );
+            $scope.showingColumnValues[columnName] = showingColumnValues;
+          }
+        }
+      );
+
+      // TODO(epoger): Every time we apply a filter, AngularJS creates
+      // another copy of the array.  Is there a way we can filter out
+      // the imagePairs as they are displayed, rather than storing multiple
+      // array copies?  (For better performance.)
+
+      if ($scope.viewingTab == $scope.defaultTab) {
+        var doReverse = !currSortAsc;
+
+        $scope.filteredImagePairs =
+            $filter("orderBy")(
+                $filter("removeHiddenImagePairs")(
+                    $scope.imagePairs,
+                    $scope.filterableColumnNames,
+                    $scope.showingColumnValues,
+                    $scope.viewingTab
+                ),
+                [$scope.getSortColumnValue, $scope.getSecondOrderSortValue],
+                doReverse);
+        $scope.limitedImagePairs = $filter("mergeAndLimit")(
+            $scope.filteredImagePairs, $scope.displayLimit, $scope.mergeIdenticalRows);
+      } else {
+        $scope.filteredImagePairs =
+            $filter("orderBy")(
+                $filter("filter")(
+                    $scope.imagePairs,
+                    {tab: $scope.viewingTab},
+                    true
+                ),
+                [$scope.getSortColumnValue, $scope.getSecondOrderSortValue]);
+        $scope.limitedImagePairs = $filter("mergeAndLimit")(
+            $scope.filteredImagePairs, -1, $scope.mergeIdenticalRows);
+      }
+      $scope.showThumbnails = $scope.showThumbnailsPending;
+      $scope.imageSize = $scope.imageSizePending;
+      $scope.setUpdatesPending(false);
+      $scope.queryParameters.save();
+    }
+
+    /**
+     * This function is called when the results have been completely rendered
+     * after updateResults().
+     */
+    $scope.resultsUpdatedCallback = function() {
+      $scope.renderEndTime = window.performance.now();
+      $log.debug("renderEndTime: " + $scope.renderEndTime);
+    }
+
+    /**
+     * Re-sort the displayed results.
+     *
+     * @param subdict (string): which KEY__IMAGEPAIRS__* subdictionary
+     *     the sort column key is within, or 'none' if the sort column
+     *     key is one of KEY__IMAGEPAIRS__*
+     * @param key (string): sort by value associated with this key in subdict
+     */
+    $scope.sortResultsBy = function(subdict, key) {
+      // if we are already sorting by this column then toggle between asc/desc
+      if ((subdict === $scope.sortColumnSubdict) && ($scope.sortColumnKey === key)) {
+        currSortAsc = !currSortAsc;
+      } else {
+        $scope.sortColumnSubdict = subdict;
+        $scope.sortColumnKey = key;
+        currSortAsc = true; 
+      }
+      $scope.updateResults();
+    }
+
+    /**
+     * Returns ASC or DESC (from constants) if currently the data
+     * is sorted by the provided column. 
+     *
+     * @param colName: name of the column for which we need to get the class.
+     */
+
+    $scope.sortedByColumnsCls = function (colName) {
+      if ($scope.sortColumnKey !== colName) {
+        return '';
+      }
+
+      var result = (currSortAsc) ? constants.ASC : constants.DESC;
+      console.log("sort class:", result);
+      return result;
+    };
+
+    /**
+     * For a particular ImagePair, return the value of the column we are
+     * sorting on (according to $scope.sortColumnSubdict and
+     * $scope.sortColumnKey).
+     *
+     * @param imagePair: imagePair to get a column value out of.
+     */
+    $scope.getSortColumnValue = function(imagePair) {
+      if ($scope.sortColumnSubdict in imagePair) {
+        return imagePair[$scope.sortColumnSubdict][$scope.sortColumnKey];
+      } else if ($scope.sortColumnKey in imagePair) {
+        return imagePair[$scope.sortColumnKey];
+      } else {
+        return undefined;
+      }
+    };
+
+    /**
+     * For a particular ImagePair, return the value we use for the
+     * second-order sort (tiebreaker when multiple rows have
+     * the same getSortColumnValue()).
+     *
+     * We join the imageA and imageB urls for this value, so that we merge
+     * adjacent rows as much as possible.
+     *
+     * @param imagePair: imagePair to get a column value out of.
+     */
+    $scope.getSecondOrderSortValue = function(imagePair) {
+      return imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" +
+          imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
+    };
+
+    /**
+     * Set $scope.columnStringMatch[name] = value, and update results.
+     *
+     * @param name
+     * @param value
+     */
+    $scope.setColumnStringMatch = function(name, value) {
+      $scope.columnStringMatch[name] = value;
+      $scope.updateResults();
+    };
+
+    /**
+     * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatch[columnName]
+     * so that ONLY entries with this columnValue are showing, and update the visible results.
+     * (We update both of those, so we cover both freeform and checkbox filtered columns.)
+     *
+     * @param columnName
+     * @param columnValue
+     */
+    $scope.showOnlyColumnValue = function(columnName, columnValue) {
+      $scope.columnStringMatch[columnName] = columnValue;
+      $scope.showingColumnValues[columnName] = {};
+      $scope.toggleValueInSet(columnValue, $scope.showingColumnValues[columnName]);
+      $scope.updateResults();
+    };
+
+    /**
+     * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatch[columnName]
+     * so that ALL entries are showing, and update the visible results.
+     * (We update both of those, so we cover both freeform and checkbox filtered columns.)
+     *
+     * @param columnName
+     */
+    $scope.showAllColumnValues = function(columnName) {
+      $scope.columnStringMatch[columnName] = "";
+      $scope.showingColumnValues[columnName] = {};
+      $scope.toggleValuesInSet($scope.allColumnValues[columnName],
+                               $scope.showingColumnValues[columnName]);
+      $scope.updateResults();
+    };
+
+
+    //
+    // Operations for sending info back to the server.
+    //
+
+    /**
+     * Tell the server that the actual results of these particular tests
+     * are acceptable.
+     *
+     * This assumes that the original expectations are in imageSetA, and the
+     * new expectations are in imageSetB.  That's fine, because the server
+     * mandates that anyway (it will swap the sets if the user requests them
+     * in the opposite order).
+     *
+     * @param imagePairsSubset an array of test results, most likely a subset of
+     *        $scope.imagePairs (perhaps with some modifications)
+     */
+    $scope.submitApprovals = function(imagePairsSubset) {
+      $scope.submitPending = true;
+      $scope.diffResults = "";
+
+      // Convert bug text field to null or 1-item array.
+      var bugs = null;
+      var bugNumber = parseInt($scope.submitAdvancedSettings['bug']);
+      if (!isNaN(bugNumber)) {
+        bugs = [bugNumber];
+      }
+
+      var updatedExpectations = [];
+      for (var i = 0; i < imagePairsSubset.length; i++) {
+        var imagePair = imagePairsSubset[i];
+        var updatedExpectation = {};
+        updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS] =
+            imagePair[constants.KEY__IMAGEPAIRS__EXPECTATIONS];
+        updatedExpectation[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS] =
+            imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS];
+        updatedExpectation[constants.KEY__IMAGEPAIRS__SOURCE_JSON_FILE] =
+            imagePair[constants.KEY__IMAGEPAIRS__SOURCE_JSON_FILE];
+        // IMAGE_B_URL contains the actual image (which is now the expectation)
+        updatedExpectation[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] =
+            imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
+
+        // Advanced settings...
+        if (null == updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]) {
+          updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS] = {};
+        }
+        updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]
+                          [constants.KEY__EXPECTATIONS__REVIEWED] =
+            $scope.submitAdvancedSettings[
+                constants.KEY__EXPECTATIONS__REVIEWED];
+        if (true == $scope.submitAdvancedSettings[
+            constants.KEY__EXPECTATIONS__IGNOREFAILURE]) {
+          // if it's false, don't send it at all (just keep the default)
+          updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]
+                            [constants.KEY__EXPECTATIONS__IGNOREFAILURE] = true;
+        }
+        updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]
+                          [constants.KEY__EXPECTATIONS__BUGS] = bugs;
+
+        updatedExpectations.push(updatedExpectation);
+      }
+      var modificationData = {};
+      modificationData[constants.KEY__LIVE_EDITS__MODIFICATIONS] =
+          updatedExpectations;
+      modificationData[constants.KEY__LIVE_EDITS__SET_A_DESCRIPTIONS] =
+          $scope.header[constants.KEY__HEADER__SET_A_DESCRIPTIONS];
+      modificationData[constants.KEY__LIVE_EDITS__SET_B_DESCRIPTIONS] =
+          $scope.header[constants.KEY__HEADER__SET_B_DESCRIPTIONS];
+      $http({
+        method: "POST",
+        url: "/live-edits",
+        data: modificationData
+      }).success(function(data, status, headers, config) {
+        $scope.diffResults = data;
+        var blob = new Blob([$scope.diffResults], {type: 'text/plain'});
+        $scope.diffResultsBlobUrl = window.URL.createObjectURL(blob);
+        $scope.submitPending = false;
+      }).error(function(data, status, headers, config) {
+        alert("There was an error submitting your baselines.\n\n" +
+            "Please see server-side log for details.");
+        $scope.submitPending = false;
+      });
+    };
+
+
+    //
+    // Operations we use to mimic Set semantics, in such a way that
+    // checking for presence within the Set is as fast as possible.
+    // But getting a list of all values within the Set is not necessarily
+    // possible.
+    // TODO(epoger): move into a separate .js file?
+    //
+
+    /**
+     * Returns the number of values present within set "set".
+     *
+     * @param set an Object which we use to mimic set semantics
+     */
+    $scope.setSize = function(set) {
+      return Object.keys(set).length;
+    };
+
+    /**
+     * Returns true if value "value" is present within set "set".
+     *
+     * @param value a value of any type
+     * @param set an Object which we use to mimic set semantics
+     *        (this should make isValueInSet faster than if we used an Array)
+     */
+    $scope.isValueInSet = function(value, set) {
+      return (true == set[value]);
+    };
+
+    /**
+     * If value "value" is already in set "set", remove it; otherwise, add it.
+     *
+     * @param value a value of any type
+     * @param set an Object which we use to mimic set semantics
+     */
+    $scope.toggleValueInSet = function(value, set) {
+      if (true == set[value]) {
+        delete set[value];
+      } else {
+        set[value] = true;
+      }
+    };
+
+    /**
+     * For each value in valueArray, call toggleValueInSet(value, set).
+     *
+     * @param valueArray
+     * @param set
+     */
+    $scope.toggleValuesInSet = function(valueArray, set) {
+      var arrayLength = valueArray.length;
+      for (var i = 0; i < arrayLength; i++) {
+        $scope.toggleValueInSet(valueArray[i], set);
+      }
+    };
+
+
+    //
+    // Array operations; similar to our Set operations, but operate on a
+    // Javascript Array so we *can* easily get a list of all values in the Set.
+    // TODO(epoger): move into a separate .js file?
+    //
+
+    /**
+     * Returns true if value "value" is present within array "array".
+     *
+     * @param value a value of any type
+     * @param array a Javascript Array
+     */
+    $scope.isValueInArray = function(value, array) {
+      return (-1 != array.indexOf(value));
+    };
+
+    /**
+     * If value "value" is already in array "array", remove it; otherwise,
+     * add it.
+     *
+     * @param value a value of any type
+     * @param array a Javascript Array
+     */
+    $scope.toggleValueInArray = function(value, array) {
+      var i = array.indexOf(value);
+      if (-1 == i) {
+        array.push(value);
+      } else {
+        array.splice(i, 1);
+      }
+    };
+
+
+    //
+    // Miscellaneous utility functions.
+    // TODO(epoger): move into a separate .js file?
+    //
+
+    /**
+     * Returns a single "column slice" of a 2D array.
+     *
+     * For example, if array is:
+     * [[A0, A1],
+     *  [B0, B1],
+     *  [C0, C1]]
+     * and index is 0, this this will return:
+     * [A0, B0, C0]
+     *
+     * @param array a Javascript Array
+     * @param column (numeric): index within each row array
+     */
+    $scope.columnSliceOf2DArray = function(array, column) {
+      var slice = [];
+      var numRows = array.length;
+      for (var row = 0; row < numRows; row++) {
+        slice.push(array[row][column]);
+      }
+      return slice;
+    };
+
+    /**
+     * Returns a human-readable (in local time zone) time string for a
+     * particular moment in time.
+     *
+     * @param secondsPastEpoch (numeric): seconds past epoch in UTC
+     */
+    $scope.localTimeString = function(secondsPastEpoch) {
+      var d = new Date(secondsPastEpoch * 1000);
+      return d.toString();
+    };
+
+    /**
+     * Returns a hex color string (such as "#aabbcc") for the given RGB values.
+     *
+     * @param r (numeric): red channel value, 0-255
+     * @param g (numeric): green channel value, 0-255
+     * @param b (numeric): blue channel value, 0-255
+     */
+    $scope.hexColorString = function(r, g, b) {
+      var rString = r.toString(16);
+      if (r < 16) {
+        rString = "0" + rString;
+      }
+      var gString = g.toString(16);
+      if (g < 16) {
+        gString = "0" + gString;
+      }
+      var bString = b.toString(16);
+      if (b < 16) {
+        bString = "0" + bString;
+      }
+      return '#' + rString + gString + bString;
+    };
+
+    /**
+     * Returns a hex color string (such as "#aabbcc") for the given brightness.
+     *
+     * @param brightnessString (string): 0-255, 0 is completely black
+     *
+     * TODO(epoger): It might be nice to tint the color when it's not completely
+     * black or completely white.
+     */
+    $scope.brightnessStringToHexColor = function(brightnessString) {
+      var v = parseInt(brightnessString);
+      return $scope.hexColorString(v, v, v);
+    };
+  }
+);
diff --git a/gm/rebaseline_server/static/live-view.html b/gm/rebaseline_server/static/live-view.html
new file mode 100644
index 0000000..1662adf
--- /dev/null
+++ b/gm/rebaseline_server/static/live-view.html
@@ -0,0 +1,446 @@
+<!DOCTYPE html>
+
+<html ng-app="Loader" ng-controller="Loader.Controller">
+
+<head>
+  <title ng-bind="windowTitle"></title>
+  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
+  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.js"></script>
+  <script src="constants.js"></script>
+  <script src="live-loader.js"></script>
+  <script src="utils.js"></script>
+
+  <link rel="stylesheet" href="view.css">
+</head>
+
+<body>
+  <h2>
+    Instructions, roadmap, etc. are at
+    <a href="http://tinyurl.com/SkiaRebaselineServer">
+      http://tinyurl.com/SkiaRebaselineServer
+    </a>
+  </h2>
+
+  <em ng-show="!readyToDisplay">
+    Loading results of query:
+    <ul>
+      <li>setA: "{{setASection}}" within {{setADir}}</li>
+      <li>setB: "{{setBSection}}" within {{setBDir}}</li>
+    </ul>
+    <br>
+    {{loadingMessage}}
+  </em>
+
+  <div ng-show="readyToDisplay">
+
+    <div class="warning-div"
+         ng-show="urlSchemaVersionLoaded != constants.URL_VALUE__SCHEMA_VERSION__CURRENT">
+      WARNING!  The URL you loaded used schema version {{urlSchemaVersionLoaded}}, rather than
+      the most recent version {{constants.URL_VALUE__SCHEMA_VERSION__CURRENT}}.  It has been
+      converted to the most recent version on a best-effort basis; you may wish to double-check
+      which records are displayed.
+    </div>
+
+    <div ng-show="header[constants.KEY__HEADER__TIME_UPDATED]">
+      setA: "{{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__SECTION]}}"
+      within {{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__DIR]}}
+      <span ng-show="header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]">at <a href="https://skia.googlesource.com/skia/+/{{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]}}">rev {{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]}}</a></span>
+      <br>
+      setB: "{{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__SECTION]}}"
+      within {{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__DIR]}}
+      <span ng-show="header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]">at <a href="https://skia.googlesource.com/skia/+/{{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]}}">rev {{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__REPO_REVISION]}}</a></span>
+      <br>
+      <a href="{{liveQueryUrl}}">latest raw JSON diffs between these two sets</a><br>
+      These results current as of
+      {{localTimeString(header[constants.KEY__HEADER__TIME_UPDATED])}}
+    </div>
+
+    <div class="tab-wrapper"><!-- tabs -->
+      <div class="tab-spacer" ng-repeat="tab in tabs">
+        <div class="tab tab-{{tab == viewingTab}}"
+             ng-click="setViewingTab(tab)">
+          &nbsp;{{tab}} ({{numResultsPerTab[tab]}})&nbsp;
+        </div>
+        <div class="tab-spacer">
+          &nbsp;
+        </div>
+      </div>
+    </div><!-- tabs -->
+
+    <div class="tab-main"><!-- main display area of selected tab -->
+
+    <br>
+    <!-- We only show the filters/settings table on the Unfiled tab. -->
+    <table ng-show="viewingTab == defaultTab" border="1">
+    <tr>
+      <th colspan="4">
+        Filters
+      </th>
+      <th>
+        Settings
+      </th>
+    </tr>
+    <tr valign="top">
+
+      <!-- filters -->
+      <td ng-repeat="columnName in orderedColumnNames">
+
+        <!-- Only display filterable columns here... -->
+        <div ng-if="extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE]">
+          {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}}<br>
+
+          <!-- If we filter this column using free-form text match... -->
+          <div ng-if="extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]">
+            <input type="text"
+                   ng-model="columnStringMatch[columnName]"
+                   ng-change="setUpdatesPending(true)"/>
+            <br>
+            <button ng-click="setColumnStringMatch(columnName, '')"
+                    ng-disabled="('' == columnStringMatch[columnName])">
+              clear (show all)
+            </button>
+          </div>
+
+          <!-- If we filter this column using checkboxes... -->
+          <div ng-if="!extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]">
+            <label ng-repeat="valueAndCount in extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]">
+              <input type="checkbox"
+                     name="resultTypes"
+                     value="{{valueAndCount[0]}}"
+                     ng-checked="isValueInSet(valueAndCount[0], showingColumnValues[columnName])"
+                     ng-click="toggleValueInSet(valueAndCount[0], showingColumnValues[columnName]); setUpdatesPending(true)">
+              {{valueAndCount[0]}} ({{valueAndCount[1]}})<br>
+            </label>
+            <button ng-click="showingColumnValues[columnName] = {}; toggleValuesInSet(allColumnValues[columnName], showingColumnValues[columnName]); updateResults()"
+                    ng-disabled="!readyToDisplay || allColumnValues[columnName].length == setSize(showingColumnValues[columnName])">
+              all
+            </button>
+            <button ng-click="showingColumnValues[columnName] = {}; updateResults()"
+                    ng-disabled="!readyToDisplay || 0 == setSize(showingColumnValues[columnName])">
+              none
+            </button>
+            <button ng-click="toggleValuesInSet(allColumnValues[columnName], showingColumnValues[columnName]); updateResults()">
+              toggle
+            </button>
+          </div>
+
+        </div>
+      </td>
+
+      <!-- settings -->
+      <td><table>
+        <tr><td>
+          <input type="checkbox" ng-model="showThumbnailsPending"
+                 ng-init="showThumbnailsPending = true"
+                 ng-change="areUpdatesPending = true"/>
+          Show thumbnails
+        </td></tr>
+        <tr><td>
+          <input type="checkbox" ng-model="mergeIdenticalRowsPending"
+                 ng-init="mergeIdenticalRowsPending = true"
+                 ng-change="areUpdatesPending = true"/>
+          Merge identical rows
+        </td></tr>
+        <tr><td>
+          Image width
+          <input type="text" ng-model="imageSizePending"
+                 ng-init="imageSizePending=100"
+                 ng-change="areUpdatesPending = true"
+                 maxlength="4"/>
+        </td></tr>
+        <tr><td>
+          Max records to display
+          <input type="text" ng-model="displayLimitPending"
+                 ng-init="displayLimitPending=50"
+                 ng-change="areUpdatesPending = true"
+                 maxlength="4"/>
+        </td></tr>
+        <tr><td>
+          <button class="update-results-button"
+                  ng-click="updateResults()"
+                  ng-disabled="!areUpdatesPending">
+            Update Results
+          </button>
+        </td></tr>
+      </tr></table></td>
+    </tr>
+  </table>
+
+      <p>
+
+      <!-- Submission UI that we only show in the Pending Approval tab. -->
+      <div ng-show="'Pending Approval' == viewingTab">
+        <div style="display:inline-block">
+          <button style="font-size:20px"
+                  ng-click="submitApprovals(filteredImagePairs)"
+                  ng-disabled="submitPending || (filteredImagePairs.length == 0)">
+            Get a patchfile to update these {{filteredImagePairs.length}} expectations
+          </button>
+        </div>
+        <div style="display:inline-block">
+          <div style="font-size:20px"
+               ng-show="submitPending">
+            Submitting, please wait...
+          </div>
+        </div>
+        <div>
+          Advanced settings...
+          <input type="checkbox" ng-model="showSubmitAdvancedSettings">
+          show
+          <ul ng-show="showSubmitAdvancedSettings">
+            <li ng-repeat="setting in [constants.KEY__EXPECTATIONS__REVIEWED, constants.KEY__EXPECTATIONS__IGNOREFAILURE]">
+              {{setting}}
+              <input type="checkbox" ng-model="submitAdvancedSettings[setting]">
+            </li>
+            <li ng-repeat="setting in ['bug']">
+              {{setting}}
+              <input type="text" ng-model="submitAdvancedSettings[setting]">
+            </li>
+          </ul>
+        </div>
+        <div ng-show="diffResults">
+          <p>
+          Here is the patch to apply to your local checkout:
+          <br>
+          <textarea rows="8" cols="50">{{diffResults}}</textarea>
+          <br>
+          <a download="patch.txt" ng-href="{{diffResultsBlobUrl}}">
+            Click here to download that patch as a text file.
+          </a>
+        </div>
+      </div>
+
+      <p>
+
+    <table border="0"><tr><td> <!-- table holding results header + results table -->
+      <table border="0" width="100%"> <!-- results header -->
+        <tr>
+          <td>
+            Found {{filteredImagePairs.length}} matches;
+            <span ng-show="filteredImagePairs.length > limitedImagePairs.length">
+              displaying the first {{limitedImagePairs.length}}.
+            </span>
+            <span ng-show="filteredImagePairs.length <= limitedImagePairs.length">
+              displaying them all.
+            </span>
+            <span ng-show="renderEndTime > renderStartTime">
+              Rendered in {{(renderEndTime - renderStartTime).toFixed(0)}} ms.
+            </span>
+            <br>
+            (click on the column header radio buttons to re-sort by that column)
+          </td>
+          <td align="right">
+            <div>
+              all tests shown:
+              <button ng-click="selectAllImagePairs()">
+                select
+              </button>
+              <button ng-click="clearAllImagePairs()">
+                clear
+              </button>
+              <button ng-click="toggleAllImagePairs()">
+                toggle
+              </button>
+            </div>
+            <div ng-repeat="otherTab in tabs">
+              <button ng-click="moveSelectedImagePairsToTab(otherTab)"
+                      ng-disabled="selectedImagePairs.length == 0"
+                      ng-show="otherTab != viewingTab">
+                move {{selectedImagePairs.length}} selected tests to {{otherTab}} tab
+              </button>
+            </div>
+          </td>
+        </tr>
+      </table> <!-- results header -->
+      </td></tr><tr><td>
+      <table border="1" ng-app="diff_viewer"> <!-- results -->
+        <tr>
+          <!-- Most column headers are displayed in a common fashion... -->
+          <th ng-repeat="columnName in orderedColumnNames">
+              <a ng-class="'sort-' + sortedByColumnsCls(columnName)"
+                 ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXTRACOLUMNS, columnName)"
+                 href=""
+                 class="sortable-header">
+               {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}}
+             </a>
+          </th>
+          <!-- ... but there are a few columns where we display things differently. -->
+          <th>
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__EXPECTATIONS__BUGS)"
+               ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXPECTATIONS, constants.KEY__EXPECTATIONS__BUGS)"
+               href=""
+               class="sortable-header">
+                  bugs
+            </a>
+          </th>
+          <th width="{{imageSize}}">
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_A_URL)"
+               ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_A_URL)"
+               href=""
+               title="setA: '{{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__SECTION]}}' within {{header[constants.KEY__HEADER__SET_A_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__DIR]}}"
+               class="sortable-header">
+              <span ng-show="'Pending Approval' != viewingTab">
+                {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}}
+              </span>
+              <span ng-show="'Pending Approval' == viewingTab">
+                old expectations
+              </span>
+            </a>
+          </th>
+          <th width="{{imageSize}}">
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_B_URL)"
+               ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_B_URL)"
+               href=""
+               title="setB: '{{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__SECTION]}}' within {{header[constants.KEY__HEADER__SET_B_DESCRIPTIONS][constants.KEY__SET_DESCRIPTIONS__DIR]}}"
+               class="sortable-header">
+              <span ng-show="'Pending Approval' != viewingTab">
+                {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}}
+              </span>
+              <span ng-show="'Pending Approval' == viewingTab">
+                new expectations
+              </span>
+            </a>
+          </th>
+          <th width="{{imageSize}}">
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)"
+               ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)"
+               href=""
+               class="sortable-header">
+                  differing pixels in white
+            </a>
+          </th>
+          <th width="{{imageSize}}">
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)"
+               ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)"
+               href=""
+               class="sortable-header">
+               perceptual difference
+            </a>
+            <br>
+            <input type="range" ng-model="pixelDiffBgColorBrightness"
+                   ng-init="pixelDiffBgColorBrightness=64; pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)"
+                   ng-change="pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)"
+                   title="image background brightness"
+                   min="0" max="255"/>
+          </th>
+          <th>
+            <!-- imagepair-selection checkbox column -->
+          </th>
+        </tr>
+
+        <tr ng-repeat="imagePair in limitedImagePairs" valign="top"
+            ng-class-odd="'results-odd'" ng-class-even="'results-even'"
+            results-updated-callback-directive>
+
+          <td ng-repeat="columnName in orderedColumnNames">
+            {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][columnName]}}
+            <br>
+            <button class="show-only-button"
+                    ng-show="viewingTab == defaultTab"
+                    ng-disabled="1 == setSize(showingColumnValues[columnName])"
+                    ng-click="showOnlyColumnValue(columnName, imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][columnName])"
+                    title="show only results of {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}} {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][columnName]}}">
+              show only
+            </button>
+            <br>
+            <button class="show-all-button"
+                    ng-show="viewingTab == defaultTab"
+                    ng-disabled="allColumnValues[columnName].length == setSize(showingColumnValues[columnName])"
+                    ng-click="showAllColumnValues(columnName)"
+                    title="show results of all {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}}s">
+              show all
+            </button>
+          </td>
+
+          <!-- bugs -->
+          <td>
+            <a ng-repeat="bug in imagePair[constants.KEY__IMAGEPAIRS__EXPECTATIONS][constants.KEY__EXPECTATIONS__BUGS]"
+               href="https://code.google.com/p/skia/issues/detail?id={{bug}}"
+               target="_blank">
+              {{bug}}
+            </a>
+          </td>
+
+          <!-- image A -->
+          <td width="{{imageSize}}" ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}">
+            <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] != null">
+              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL]}}" target="_blank">View Image</a><br/>
+              <img ng-if="showThumbnails"
+                   width="{{imageSize}}"
+                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL]}}" />
+            </div>
+            <div ng-show="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] == null"
+                 style="text-align:center">
+              &ndash;none&ndash;
+            </div>
+          </td>
+
+          <!-- image B -->
+          <td width="{{imageSize}}" ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}">
+            <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] != null">
+              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]}}" target="_blank">View Image</a><br/>
+              <img ng-if="showThumbnails"
+                   width="{{imageSize}}"
+                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]}}" />
+            </div>
+            <div ng-show="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] == null"
+                 style="text-align:center">
+              &ndash;none&ndash;
+            </div>
+          </td>
+
+          <!-- whitediffs: every differing pixel shown in white -->
+          <td width="{{imageSize}}" ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}">
+            <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
+                 title="{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS] | number:0}} of {{(100 * imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS] / imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS]) | number:0}} pixels ({{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS].toFixed(4)}}%) differ from expectation.">
+
+              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__WHITE_DIFF_URL]}}" target="_blank">View Image</a><br/>
+              <img ng-if="showThumbnails"
+                   width="{{imageSize}}"
+                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__WHITE_DIFF_URL]}}" />
+              <br/>
+              {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS].toFixed(4)}}%
+              ({{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS]}})
+            </div>
+            <div ng-show="!imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
+                 style="text-align:center">
+              &ndash;none&ndash;
+            </div>
+          </td>
+
+          <!-- diffs: per-channel RGB deltas -->
+          <td width="{{imageSize}}" ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}">
+            <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
+                 title="Perceptual difference measure is {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF].toFixed(4)}}%.  Maximum difference per channel: R={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][0]}}, G={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][1]}}, B={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][2]}}">
+
+              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__DIFF_URL]}}" target="_blank">View Image</a><br/>
+              <img ng-if="showThumbnails"
+                   ng-style="{backgroundColor: pixelDiffBgColor}"
+                   width="{{imageSize}}"
+                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__DIFF_URL]}}" />
+              <br/>
+              {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF].toFixed(4)}}%
+              {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL]}}
+            </div>
+            <div ng-show="!imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
+                 style="text-align:center">
+              &ndash;none&ndash;
+            </div>
+          </td>
+
+          <td ng-if="imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] > 0" rowspan="{{imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN]}}">
+            <br/>
+            <input type="checkbox"
+                   name="rowSelect"
+                   value="{{imagePair.index}}"
+                   ng-checked="isValueInArray(imagePair.index, selectedImagePairs)"
+                   ng-click="toggleSomeImagePairs($index, imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN])">
+        </tr>
+      </table> <!-- imagePairs -->
+    </td></tr></table> <!-- table holding results header + imagePairs table -->
+
+  </div><!-- main display area of selected tab -->
+  </div><!-- everything: hide until readyToDisplay -->
+
+</body>
+</html>
diff --git a/gm/rebaseline_server/static/loader.js b/gm/rebaseline_server/static/loader.js
index 296689b..bfc639e 100644
--- a/gm/rebaseline_server/static/loader.js
+++ b/gm/rebaseline_server/static/loader.js
@@ -30,24 +30,29 @@
 Loader.filter(
   'removeHiddenImagePairs',
   function(constants) {
-    return function(unfilteredImagePairs, hiddenResultTypes, hiddenConfigs,
-                    builderSubstring, testSubstring, viewingTab) {
+    return function(unfilteredImagePairs, filterableColumnNames, showingColumnValues,
+                    viewingTab) {
       var filteredImagePairs = [];
       for (var i = 0; i < unfilteredImagePairs.length; i++) {
         var imagePair = unfilteredImagePairs[i];
         var extraColumnValues = imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS];
-        // For performance, we examine the "set" objects directly rather
-        // than calling $scope.isValueInSet().
-        // Besides, I don't think we have access to $scope in here...
-        if (!(true == hiddenResultTypes[extraColumnValues[
-                  constants.KEY__EXTRACOLUMNS__RESULT_TYPE]]) &&
-            !(true == hiddenConfigs[extraColumnValues[
-                  constants.KEY__EXTRACOLUMNS__CONFIG]]) &&
-            !(-1 == extraColumnValues[constants.KEY__EXTRACOLUMNS__BUILDER]
-                    .indexOf(builderSubstring)) &&
-            !(-1 == extraColumnValues[constants.KEY__EXTRACOLUMNS__TEST]
-                    .indexOf(testSubstring)) &&
-            (viewingTab == imagePair.tab)) {
+        var allColumnValuesAreVisible = true;
+        // Loop over all columns, and if any of them contain values not found in
+        // showingColumnValues[columnName], don't include this imagePair.
+        //
+        // We use this same filtering mechanism regardless of whether each column
+        // has USE_FREEFORM_FILTER set or not; if that flag is set, then we will
+        // have already used the freeform text entry block to populate
+        // showingColumnValues[columnName].
+        for (var j = 0; j < filterableColumnNames.length; j++) {
+          var columnName = filterableColumnNames[j];
+          var columnValue = extraColumnValues[columnName];
+          if (!showingColumnValues[columnName][columnValue]) {
+            allColumnValuesAreVisible = false;
+            break;
+          }
+        }
+        if (allColumnValuesAreVisible && (viewingTab == imagePair.tab)) {
           filteredImagePairs.push(imagePair);
         }
       }
@@ -119,11 +124,15 @@
 Loader.controller(
   'Loader.Controller',
     function($scope, $http, $filter, $location, $log, $timeout, constants) {
+    $scope.readyToDisplay = false;
     $scope.constants = constants;
     $scope.windowTitle = "Loading GM Results...";
     $scope.resultsToLoad = $location.search().resultsToLoad;
     $scope.loadingMessage = "please wait...";
 
+    var currSortAsc = true; 
+
+
     /**
      * On initial page load, load a full dictionary of results.
      * Once the dictionary is loaded, unhide the page elements so they can
@@ -158,10 +167,14 @@
 
           $scope.header = dataHeader;
           $scope.extraColumnHeaders = data[constants.KEY__ROOT__EXTRACOLUMNHEADERS];
+          $scope.orderedColumnNames = data[constants.KEY__ROOT__EXTRACOLUMNORDER];
           $scope.imagePairs = data[constants.KEY__ROOT__IMAGEPAIRS];
           $scope.imageSets = data[constants.KEY__ROOT__IMAGESETS];
+
+          // set the default sort column and make it ascending.
           $scope.sortColumnSubdict = constants.KEY__IMAGEPAIRS__DIFFERENCES;
           $scope.sortColumnKey = constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF;
+          currSortAsc = true;
 
           $scope.showSubmitAdvancedSettings = false;
           $scope.submitAdvancedSettings = {};
@@ -199,28 +212,69 @@
           // Arrays within which the user can toggle individual elements.
           $scope.selectedImagePairs = [];
 
-          // Sets within which the user can toggle individual elements.
-          $scope.hiddenResultTypes = {};
-          $scope.hiddenResultTypes[
-              constants.KEY__RESULT_TYPE__FAILUREIGNORED] = true;
-          $scope.hiddenResultTypes[
-              constants.KEY__RESULT_TYPE__NOCOMPARISON] = true;
-          $scope.hiddenResultTypes[
-              constants.KEY__RESULT_TYPE__SUCCEEDED] = true;
-          $scope.allResultTypes = $scope.columnSliceOf2DArray(
-              $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMNS__RESULT_TYPE]
-                                       [constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS],
-              0);
-          $scope.hiddenConfigs = {};
-          $scope.allConfigs = $scope.columnSliceOf2DArray(
-              $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMNS__CONFIG]
-                                       [constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS],
-              0);
+          // Set up filters.
+          //
+          // filterableColumnNames is a list of all column names we can filter on.
+          // allColumnValues[columnName] is a list of all known values
+          // for a given column.
+          // showingColumnValues[columnName] is a set indicating which values
+          // in a given column would cause us to show a row, rather than hiding it.
+          //
+          // columnStringMatch[columnName] is a string used as a pattern to generate
+          // showingColumnValues[columnName] for columns we filter using free-form text.
+          // It is ignored for any columns with USE_FREEFORM_FILTER == false.
+          $scope.filterableColumnNames = [];
+          $scope.allColumnValues = {};
+          $scope.showingColumnValues = {};
+          $scope.columnStringMatch = {};
 
-          // Associative array of partial string matches per category.
-          $scope.categoryValueMatch = {};
-          $scope.categoryValueMatch.builder = "";
-          $scope.categoryValueMatch.test = "";
+          angular.forEach(
+            Object.keys($scope.extraColumnHeaders),
+            function(columnName) {
+              var columnHeader = $scope.extraColumnHeaders[columnName];
+              if (columnHeader[constants.KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE]) {
+                $scope.filterableColumnNames.push(columnName);
+                $scope.allColumnValues[columnName] = $scope.columnSliceOf2DArray(
+                    columnHeader[constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS], 0);
+                $scope.showingColumnValues[columnName] = {};
+                $scope.toggleValuesInSet($scope.allColumnValues[columnName],
+                                         $scope.showingColumnValues[columnName]);
+                $scope.columnStringMatch[columnName] = "";
+              }
+            }
+          );
+
+          // TODO(epoger): Special handling for RESULT_TYPE column:
+          // by default, show only KEY__RESULT_TYPE__FAILED results
+          $scope.showingColumnValues[constants.KEY__EXTRACOLUMNS__RESULT_TYPE] = {};
+          $scope.showingColumnValues[constants.KEY__EXTRACOLUMNS__RESULT_TYPE][
+              constants.KEY__RESULT_TYPE__FAILED] = true;
+
+          // Set up mapping for URL parameters.
+          // parameter name -> copier object to load/save parameter value
+          $scope.queryParameters.map = {
+            'resultsToLoad':         $scope.queryParameters.copiers.simple,
+            'displayLimitPending':   $scope.queryParameters.copiers.simple,
+            'showThumbnailsPending': $scope.queryParameters.copiers.simple,
+            'mergeIdenticalRowsPending': $scope.queryParameters.copiers.simple,
+            'imageSizePending':      $scope.queryParameters.copiers.simple,
+            'sortColumnSubdict':     $scope.queryParameters.copiers.simple,
+            'sortColumnKey':         $scope.queryParameters.copiers.simple,
+          };
+          // Some parameters are handled differently based on whether they USE_FREEFORM_FILTER.
+          angular.forEach(
+            $scope.filterableColumnNames,
+            function(columnName) {
+              if ($scope.extraColumnHeaders[columnName]
+                  [constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]) {
+                $scope.queryParameters.map[columnName] =
+                    $scope.queryParameters.copiers.columnStringMatch;
+              } else {
+                $scope.queryParameters.map[columnName] =
+                    $scope.queryParameters.copiers.showingColumnValuesSet;
+              }
+            }
+          );
 
           // If any defaults were overridden in the URL, get them now.
           $scope.queryParameters.load();
@@ -239,9 +293,14 @@
             }
           );
 
+          $scope.readyToDisplay = true;
           $scope.updateResults();
           $scope.loadingMessage = "";
           $scope.windowTitle = "Current GM Results";
+
+          $timeout( function() {
+            make_results_header_sticky();
+          });
         }
       }
     ).error(
@@ -267,7 +326,7 @@
           $scope.toggleValueInArray(index, $scope.selectedImagePairs);
         }
       }
-    }
+    };
 
     /**
      * Deselect all currently showing tests.
@@ -280,7 +339,7 @@
           $scope.toggleValueInArray(index, $scope.selectedImagePairs);
         }
       }
-    }
+    };
 
     /**
      * Toggle selection of all currently showing tests.
@@ -291,7 +350,7 @@
         var index = $scope.limitedImagePairs[i].index;
         $scope.toggleValueInArray(index, $scope.selectedImagePairs);
       }
-    }
+    };
 
     /**
      * Toggle selection state of a subset of the currently showing tests.
@@ -306,7 +365,7 @@
         var index = $scope.limitedImagePairs[i].index;
         $scope.toggleValueInArray(index, $scope.selectedImagePairs);
       }
-    }
+    };
 
 
     //
@@ -321,7 +380,7 @@
     $scope.setViewingTab = function(tab) {
       $scope.viewingTab = tab;
       $scope.updateResults();
-    }
+    };
 
     /**
      * Move the imagePairs in $scope.selectedImagePairs to a different tab,
@@ -333,7 +392,7 @@
       $scope.moveImagePairsToTab($scope.selectedImagePairs, newTab);
       $scope.selectedImagePairs = [];
       $scope.updateResults();
-    }
+    };
 
     /**
      * Move a subset of $scope.imagePairs to a different tab.
@@ -351,7 +410,7 @@
         $scope.imagePairs[imagePairIndex].tab = newTab;
       }
       $scope.numResultsPerTab[newTab] += numImagePairs;
-    }
+    };
 
 
     //
@@ -376,56 +435,56 @@
         }
       },
 
-      'categoryValueMatch': {
+      'columnStringMatch': {
         'load': function(nameValuePairs, name) {
           var value = nameValuePairs[name];
           if (value) {
-            $scope.categoryValueMatch[name] = value;
+            $scope.columnStringMatch[name] = value;
           }
         },
         'save': function(nameValuePairs, name) {
-          nameValuePairs[name] = $scope.categoryValueMatch[name];
+          nameValuePairs[name] = $scope.columnStringMatch[name];
         }
       },
 
-      'set': {
+      'showingColumnValuesSet': {
         'load': function(nameValuePairs, name) {
           var value = nameValuePairs[name];
           if (value) {
             var valueArray = value.split(',');
-            $scope[name] = {};
-            $scope.toggleValuesInSet(valueArray, $scope[name]);
+            $scope.showingColumnValues[name] = {};
+            $scope.toggleValuesInSet(valueArray, $scope.showingColumnValues[name]);
           }
         },
         'save': function(nameValuePairs, name) {
-          nameValuePairs[name] = Object.keys($scope[name]).join(',');
+          nameValuePairs[name] = Object.keys($scope.showingColumnValues[name]).join(',');
         }
       },
 
     };
 
-    // parameter name -> copier objects to load/save parameter value
-    $scope.queryParameters.map = {
-      'resultsToLoad':         $scope.queryParameters.copiers.simple,
-      'displayLimitPending':   $scope.queryParameters.copiers.simple,
-      'showThumbnailsPending': $scope.queryParameters.copiers.simple,
-      'mergeIdenticalRowsPending': $scope.queryParameters.copiers.simple,
-      'imageSizePending':      $scope.queryParameters.copiers.simple,
-      'sortColumnSubdict':     $scope.queryParameters.copiers.simple,
-      'sortColumnKey':         $scope.queryParameters.copiers.simple,
-
-      'hiddenResultTypes': $scope.queryParameters.copiers.set,
-      'hiddenConfigs':     $scope.queryParameters.copiers.set,
-    };
-    $scope.queryParameters.map[constants.KEY__EXTRACOLUMNS__BUILDER] =
-        $scope.queryParameters.copiers.categoryValueMatch;
-    $scope.queryParameters.map[constants.KEY__EXTRACOLUMNS__TEST] =
-        $scope.queryParameters.copiers.categoryValueMatch;
-
     // Loads all parameters into $scope from the URL query string;
     // any which are not found within the URL will keep their current value.
     $scope.queryParameters.load = function() {
       var nameValuePairs = $location.search();
+
+      // If urlSchemaVersion is not specified, we assume the current version.
+      var urlSchemaVersion = constants.URL_VALUE__SCHEMA_VERSION__CURRENT;
+      if (constants.URL_KEY__SCHEMA_VERSION in nameValuePairs) {
+        urlSchemaVersion = nameValuePairs[constants.URL_KEY__SCHEMA_VERSION];
+      } else if ('hiddenResultTypes' in nameValuePairs) {
+        // The combination of:
+        // - absence of an explicit urlSchemaVersion, and
+        // - presence of the old 'hiddenResultTypes' field
+        // tells us that the URL is from the original urlSchemaVersion.
+        // See https://codereview.chromium.org/367173002/
+        urlSchemaVersion = 0;
+      }
+      $scope.urlSchemaVersionLoaded = urlSchemaVersion;
+
+      if (urlSchemaVersion != constants.URL_VALUE__SCHEMA_VERSION__CURRENT) {
+        nameValuePairs = $scope.upconvertUrlNameValuePairs(nameValuePairs, urlSchemaVersion);
+      }
       angular.forEach($scope.queryParameters.map,
                       function(copier, paramName) {
                         copier.load(nameValuePairs, paramName);
@@ -436,6 +495,7 @@
     // Saves all parameters from $scope into the URL query string.
     $scope.queryParameters.save = function() {
       var nameValuePairs = {};
+      nameValuePairs[constants.URL_KEY__SCHEMA_VERSION] = constants.URL_VALUE__SCHEMA_VERSION__CURRENT;
       angular.forEach($scope.queryParameters.map,
                       function(copier, paramName) {
                         copier.save(nameValuePairs, paramName);
@@ -444,6 +504,45 @@
       $location.search(nameValuePairs);
     };
 
+    /**
+     * Converts URL name/value pairs that were stored by a previous urlSchemaVersion
+     * to the currently needed format.
+     *
+     * @param oldNValuePairs name/value pairs found in the loaded URL
+     * @param oldUrlSchemaVersion which version of the schema was used to generate that URL
+     *
+     * @returns nameValuePairs as needed by the current URL parser
+     */
+    $scope.upconvertUrlNameValuePairs = function(oldNameValuePairs, oldUrlSchemaVersion) {
+      var newNameValuePairs = {};
+      angular.forEach(oldNameValuePairs,
+                      function(value, name) {
+                        if (oldUrlSchemaVersion < 1) {
+                          if ('hiddenConfigs' == name) {
+                            name = 'config';
+                            var valueSet = {};
+                            $scope.toggleValuesInSet(value.split(','), valueSet);
+                            $scope.toggleValuesInSet(
+                                $scope.allColumnValues[constants.KEY__EXTRACOLUMNS__CONFIG],
+                                valueSet);
+                            value = Object.keys(valueSet).join(',');
+                          } else if ('hiddenResultTypes' == name) {
+                            name = 'resultType';
+                            var valueSet = {};
+                            $scope.toggleValuesInSet(value.split(','), valueSet);
+                            $scope.toggleValuesInSet(
+                                $scope.allColumnValues[constants.KEY__EXTRACOLUMNS__RESULT_TYPE],
+                                valueSet);
+                            value = Object.keys(valueSet).join(',');
+                          }
+                        }
+
+                        newNameValuePairs[name] = value;
+                      }
+                     );
+      return newNameValuePairs;
+    }
+
 
     //
     // updateResults() and friends.
@@ -476,32 +575,47 @@
       $log.debug("renderStartTime: " + $scope.renderStartTime);
       $scope.displayLimit = $scope.displayLimitPending;
       $scope.mergeIdenticalRows = $scope.mergeIdenticalRowsPending;
+
+      // For each USE_FREEFORM_FILTER column, populate showingColumnValues.
+      // This is more efficient than applying the freeform filter within the
+      // tight loop in removeHiddenImagePairs.
+      angular.forEach(
+        $scope.filterableColumnNames,
+        function(columnName) {
+          var columnHeader = $scope.extraColumnHeaders[columnName];
+          if (columnHeader[constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]) {
+            var columnStringMatch = $scope.columnStringMatch[columnName];
+            var showingColumnValues = {};
+            angular.forEach(
+              $scope.allColumnValues[columnName],
+              function(columnValue) {
+                if (-1 != columnValue.indexOf(columnStringMatch)) {
+                  showingColumnValues[columnValue] = true;
+                }
+              }
+            );
+            $scope.showingColumnValues[columnName] = showingColumnValues;
+          }
+        }
+      );
+
       // TODO(epoger): Every time we apply a filter, AngularJS creates
       // another copy of the array.  Is there a way we can filter out
       // the imagePairs as they are displayed, rather than storing multiple
       // array copies?  (For better performance.)
-
       if ($scope.viewingTab == $scope.defaultTab) {
-
-        // TODO(epoger): Until we allow the user to reverse sort order,
-        // there are certain columns we want to sort in a different order.
-        var doReverse = (
-            ($scope.sortColumnKey ==
-             constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS) ||
-            ($scope.sortColumnKey ==
-             constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF));
+        var doReverse = !currSortAsc;
 
         $scope.filteredImagePairs =
             $filter("orderBy")(
                 $filter("removeHiddenImagePairs")(
                     $scope.imagePairs,
-                    $scope.hiddenResultTypes,
-                    $scope.hiddenConfigs,
-                    $scope.categoryValueMatch.builder,
-                    $scope.categoryValueMatch.test,
+                    $scope.filterableColumnNames,
+                    $scope.showingColumnValues,
                     $scope.viewingTab
                 ),
-                [$scope.getSortColumnValue, $scope.getSecondOrderSortValue],
+                // [$scope.getSortColumnValue, $scope.getSecondOrderSortValue],
+                $scope.getSortColumnValue,
                 doReverse);
         $scope.limitedImagePairs = $filter("mergeAndLimit")(
             $scope.filteredImagePairs, $scope.displayLimit, $scope.mergeIdenticalRows);
@@ -513,7 +627,8 @@
                     {tab: $scope.viewingTab},
                     true
                 ),
-                [$scope.getSortColumnValue, $scope.getSecondOrderSortValue]);
+                // [$scope.getSortColumnValue, $scope.getSecondOrderSortValue]);
+                $scope.getSortColumnValue);
         $scope.limitedImagePairs = $filter("mergeAndLimit")(
             $scope.filteredImagePairs, -1, $scope.mergeIdenticalRows);
       }
@@ -530,7 +645,7 @@
     $scope.resultsUpdatedCallback = function() {
       $scope.renderEndTime = window.performance.now();
       $log.debug("renderEndTime: " + $scope.renderEndTime);
-    }
+    };
 
     /**
      * Re-sort the displayed results.
@@ -541,10 +656,33 @@
      * @param key (string): sort by value associated with this key in subdict
      */
     $scope.sortResultsBy = function(subdict, key) {
-      $scope.sortColumnSubdict = subdict;
-      $scope.sortColumnKey = key;
+      // if we are already sorting by this column then toggle between asc/desc
+      if ((subdict === $scope.sortColumnSubdict) && ($scope.sortColumnKey === key)) {
+        currSortAsc = !currSortAsc;
+      } else {
+        $scope.sortColumnSubdict = subdict;
+        $scope.sortColumnKey = key;
+        currSortAsc = true; 
+      }
       $scope.updateResults();
-    }
+    };
+
+    /**
+     * Returns ASC or DESC (from constants) if currently the data
+     * is sorted by the provided column. 
+     *
+     * @param colName: name of the column for which we need to get the class.
+     */
+
+    $scope.sortedByColumnsCls = function (colName) {
+      if ($scope.sortColumnKey !== colName) {
+        return '';
+      }
+
+      var result = (currSortAsc) ? constants.ASC : constants.DESC;
+      console.log("sort class:", result);
+      return result;
+    };
 
     /**
      * For a particular ImagePair, return the value of the column we are
@@ -561,7 +699,7 @@
       } else {
         return undefined;
       }
-    }
+    };
 
     /**
      * For a particular ImagePair, return the value we use for the
@@ -576,65 +714,48 @@
     $scope.getSecondOrderSortValue = function(imagePair) {
       return imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" +
           imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
-    }
+    };
 
     /**
-     * Set $scope.categoryValueMatch[name] = value, and update results.
+     * Set $scope.columnStringMatch[name] = value, and update results.
      *
      * @param name
      * @param value
      */
-    $scope.setCategoryValueMatch = function(name, value) {
-      $scope.categoryValueMatch[name] = value;
+    $scope.setColumnStringMatch = function(name, value) {
+      $scope.columnStringMatch[name] = value;
       $scope.updateResults();
-    }
+    };
 
     /**
-     * Update $scope.hiddenResultTypes so that ONLY this resultType is showing,
-     * and update the visible results.
+     * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatch[columnName]
+     * so that ONLY entries with this columnValue are showing, and update the visible results.
+     * (We update both of those, so we cover both freeform and checkbox filtered columns.)
      *
-     * @param resultType
+     * @param columnName
+     * @param columnValue
      */
-    $scope.showOnlyResultType = function(resultType) {
-      $scope.hiddenResultTypes = {};
-      // TODO(epoger): Maybe change $scope.allResultTypes to be a Set like
-      // $scope.hiddenResultTypes (rather than an array), so this operation is
-      // simpler (just assign or add allResultTypes to hiddenResultTypes).
-      $scope.toggleValuesInSet($scope.allResultTypes, $scope.hiddenResultTypes);
-      $scope.toggleValueInSet(resultType, $scope.hiddenResultTypes);
+    $scope.showOnlyColumnValue = function(columnName, columnValue) {
+      $scope.columnStringMatch[columnName] = columnValue;
+      $scope.showingColumnValues[columnName] = {};
+      $scope.toggleValueInSet(columnValue, $scope.showingColumnValues[columnName]);
       $scope.updateResults();
-    }
+    };
 
     /**
-     * Update $scope.hiddenResultTypes so that ALL resultTypes are showing,
-     * and update the visible results.
-     */
-    $scope.showAllResultTypes = function() {
-      $scope.hiddenResultTypes = {};
-      $scope.updateResults();
-    }
-
-    /**
-     * Update $scope.hiddenConfigs so that ONLY this config is showing,
-     * and update the visible results.
+     * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatch[columnName]
+     * so that ALL entries are showing, and update the visible results.
+     * (We update both of those, so we cover both freeform and checkbox filtered columns.)
      *
-     * @param config
+     * @param columnName
      */
-    $scope.showOnlyConfig = function(config) {
-      $scope.hiddenConfigs = {};
-      $scope.toggleValuesInSet($scope.allConfigs, $scope.hiddenConfigs);
-      $scope.toggleValueInSet(config, $scope.hiddenConfigs);
+    $scope.showAllColumnValues = function(columnName) {
+      $scope.columnStringMatch[columnName] = "";
+      $scope.showingColumnValues[columnName] = {};
+      $scope.toggleValuesInSet($scope.allColumnValues[columnName],
+                               $scope.showingColumnValues[columnName]);
       $scope.updateResults();
-    }
-
-    /**
-     * Update $scope.hiddenConfigs so that ALL configs are showing,
-     * and update the visible results.
-     */
-    $scope.showAllConfigs = function() {
-      $scope.hiddenConfigs = {};
-      $scope.updateResults();
-    }
+    };
 
 
     //
@@ -744,7 +865,7 @@
             "Please see server-side log for details.");
         $scope.submitPending = false;
       });
-    }
+    };
 
 
     //
@@ -762,7 +883,7 @@
      */
     $scope.setSize = function(set) {
       return Object.keys(set).length;
-    }
+    };
 
     /**
      * Returns true if value "value" is present within set "set".
@@ -773,7 +894,7 @@
      */
     $scope.isValueInSet = function(value, set) {
       return (true == set[value]);
-    }
+    };
 
     /**
      * If value "value" is already in set "set", remove it; otherwise, add it.
@@ -787,7 +908,7 @@
       } else {
         set[value] = true;
       }
-    }
+    };
 
     /**
      * For each value in valueArray, call toggleValueInSet(value, set).
@@ -800,7 +921,7 @@
       for (var i = 0; i < arrayLength; i++) {
         $scope.toggleValueInSet(valueArray[i], set);
       }
-    }
+    };
 
 
     //
@@ -817,7 +938,7 @@
      */
     $scope.isValueInArray = function(value, array) {
       return (-1 != array.indexOf(value));
-    }
+    };
 
     /**
      * If value "value" is already in array "array", remove it; otherwise,
@@ -833,7 +954,7 @@
       } else {
         array.splice(i, 1);
       }
-    }
+    };
 
 
     //
@@ -861,7 +982,7 @@
         slice.push(array[row][column]);
       }
       return slice;
-    }
+    };
 
     /**
      * Returns a human-readable (in local time zone) time string for a
@@ -872,7 +993,7 @@
     $scope.localTimeString = function(secondsPastEpoch) {
       var d = new Date(secondsPastEpoch * 1000);
       return d.toString();
-    }
+    };
 
     /**
      * Returns a hex color string (such as "#aabbcc") for the given RGB values.
@@ -895,7 +1016,7 @@
         bString = "0" + bString;
       }
       return '#' + rString + gString + bString;
-    }
+    };
 
     /**
      * Returns a hex color string (such as "#aabbcc") for the given brightness.
@@ -908,25 +1029,7 @@
     $scope.brightnessStringToHexColor = function(brightnessString) {
       var v = parseInt(brightnessString);
       return $scope.hexColorString(v, v, v);
-    }
-
-    /**
-     * Returns the last path component of image diff URL for a given ImagePair.
-     *
-     * Depending on which diff this is (whitediffs, pixeldiffs, etc.) this
-     * will be relative to different base URLs.
-     *
-     * We must keep this function in sync with _get_difference_locator() in
-     * ../imagediffdb.py
-     *
-     * @param imagePair: ImagePair to generate image diff URL for
-     */
-    $scope.getImageDiffRelativeUrl = function(imagePair) {
-      var before =
-          imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" +
-          imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
-      return before.replace(/[^\w\-]/g, "_") + ".png";
-    }
+    };
 
   }
 );
diff --git a/gm/rebaseline_server/static/new/bower.json b/gm/rebaseline_server/static/new/bower.json
new file mode 100644
index 0000000..775213d
--- /dev/null
+++ b/gm/rebaseline_server/static/new/bower.json
@@ -0,0 +1,22 @@
+{
+  "name": "rebasline",
+  "version": "0.1.0",
+  "authors": [],
+  "description": "Rebaseline Server",
+  "license": "BSD",
+  "private": true,
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "third_party/bower_components",
+    "test",
+    "tests"
+  ],
+  "dependencies": {
+    "angular": "1.2.x",
+    "angular-route": "1.2.x",
+    "angular-bootstrap": "0.11.x",
+    "bootstrap": "3.1.x"
+  }
+}
diff --git a/gm/rebaseline_server/static/new/css/app.css b/gm/rebaseline_server/static/new/css/app.css
new file mode 100644
index 0000000..fb0cc09
--- /dev/null
+++ b/gm/rebaseline_server/static/new/css/app.css
@@ -0,0 +1,71 @@
+/* app css stylesheet */
+
+.formPadding {
+  padding-left: 2em !important;
+  padding-right: 0 !important;
+}
+
+.controlBox { 
+  border-left: 1px solid #ddd;
+  border-right: 1px solid #ddd;
+  border-bottom: 1px solid #ddd;
+  padding-right: 0;
+  width: 100%;
+  padding-top: 2em;
+}
+
+.simpleLegend { 
+  font-size: 16px;
+  margin-bottom: 3px;
+  width: 95%;
+}
+
+.settingsForm {
+  padding-left: 1em;
+  padding-right: 0;
+}
+
+
+.resultsHeaderActions {
+    float: right;
+}
+
+.sticky {
+    position: fixed;
+    top: 2px;
+    box-shadow: -2px 2px 5px 0 rgba(0,0,0,.45);
+    background: white;
+    right: 2px;
+    padding: 10px;
+    border: 2px solid #222;
+}
+
+.sortDesc {
+     background:no-repeat left center url(data:image/gif;base64,R0lGODlhCgAKALMAAHFxcYKCgp2dnaampq+vr83NzeHh4f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAAAgAIf/8SUNDUkdCRzEwMTIAAAUwYXBwbAIgAABtbnRyUkdCIFhZWiAH2QACABkACwAaAAthY3NwQVBQTAAAAABhcHBsAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkc2NtAAABCAAAAvJkZXNjAAAD/AAAAG9nWFlaAAAEbAAAABR3dHB0AAAEgAAAABRyWFlaAAAElAAAABRiWFlaAAAEqAAAABRyVFJDAAAEvAAAAA5jcHJ0AAAEzAAAADhjaGFkAAAFBAAAACxn/1RSQwAABLwAAAAOYlRSQwAABLwAAAAObWx1YwAAAAAAAAARAAAADGVuVVMAAAAmAAACfmVzRVMAAAAmAAABgmRhREsAAAAuAAAB6mRlREUAAAAsAAABqGZpRkkAAAAoAAAA3GZyRlUAAAAoAAABKml0SVQAAAAoAAACVm5sTkwAAAAoAAACGG5iTk8AAAAmAAABBHB0QlIAAAAmAAABgnN2U0UAAAAmAAABBGphSlAAAAAaAAABUmtvS1IAAAAWAAACQHpoVFcAAAAWAAABbHpoQ04AAAAWAAAB1HJ1UlUAAAAiAAACpHBsUEwAAAAsAAACxgBZAGwAZQBpAG4AZf8AbgAgAFIARwBCAC0AcAByAG8AZgBpAGkAbABpAEcAZQBuAGUAcgBpAHMAawAgAFIARwBCAC0AcAByAG8AZgBpAGwAUAByAG8AZgBpAGwAIABHAOkAbgDpAHIAaQBxAHUAZQAgAFIAVgBCTgCCLAAgAFIARwBCACAw1zDtMNUwoTCkMOuQGnUoACAAUgBHAEIAIIJyX2ljz4/wAFAAZQByAGYAaQBsACAAUgBHAEIAIABHAGUAbgDpAHIAaQBjAG8AQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAAUgBHAEIALQBQAHIAbwBmAGkAbGZukBoAIABSAEcAQgAgY8+P8GX/h072AEcAZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIAZQBzAGsAcgBpAHYAZQBsAHMAZQBBAGwAZwBlAG0AZQBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBlAGzHfLwYACAAUgBHAEIAINUEuFzTDMd8AFAAcgBvAGYAaQBsAG8AIABSAEcAQgAgAEcAZQBuAGUAcgBpAGMAbwBHAGUAbgBlAHIAaQBjACAAUgBHAEIAIABQAHIAbwBmAGkAbABlBB4EMQRJBDgEOQAgBD8EQAQ+BEQEOAQ7BEwAIABSAEcAQgBVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBm/wBpAGwAIABSAEcAQgAAZGVzYwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAAPNSAAEAAAABFs9YWVogAAAAAAAAdE0AAD3uAAAD0FhZWiAAAAAAAAAoGgAAFZ8AALg2Y3VydgAAAAAAAAABAc0AAHRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBwbGUgSW5jLkMsIGFsbCByaWdodHMgcmVzZXJ2ZWQuAHNmMzIAAAAAAAEMQgAABd7///MmAAAHkgAA/ZH///ui///9owAAA9wAAMBsACwAAAAACgAKAAAEJZAMIcakQZjNtyhFxwEIIRofAookUnapu26t+6KFLYe1TgQ5VwQAOw%3D%3D);
+}
+
+.sortAsc {
+    background:no-repeat left center url(data:image/gif;base64,R0lGODlhCgAKALMAAHFxcYKCgp2dnaampq+vr83NzeHh4f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAAAgAIf/8SUNDUkdCRzEwMTIAAAUwYXBwbAIgAABtbnRyUkdCIFhZWiAH2QACABkACwAaAAthY3NwQVBQTAAAAABhcHBsAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkc2NtAAABCAAAAvJkZXNjAAAD/AAAAG9nWFlaAAAEbAAAABR3dHB0AAAEgAAAABRyWFlaAAAElAAAABRiWFlaAAAEqAAAABRyVFJDAAAEvAAAAA5jcHJ0AAAEzAAAADhjaGFkAAAFBAAAACxn/1RSQwAABLwAAAAOYlRSQwAABLwAAAAObWx1YwAAAAAAAAARAAAADGVuVVMAAAAmAAACfmVzRVMAAAAmAAABgmRhREsAAAAuAAAB6mRlREUAAAAsAAABqGZpRkkAAAAoAAAA3GZyRlUAAAAoAAABKml0SVQAAAAoAAACVm5sTkwAAAAoAAACGG5iTk8AAAAmAAABBHB0QlIAAAAmAAABgnN2U0UAAAAmAAABBGphSlAAAAAaAAABUmtvS1IAAAAWAAACQHpoVFcAAAAWAAABbHpoQ04AAAAWAAAB1HJ1UlUAAAAiAAACpHBsUEwAAAAsAAACxgBZAGwAZQBpAG4AZf8AbgAgAFIARwBCAC0AcAByAG8AZgBpAGkAbABpAEcAZQBuAGUAcgBpAHMAawAgAFIARwBCAC0AcAByAG8AZgBpAGwAUAByAG8AZgBpAGwAIABHAOkAbgDpAHIAaQBxAHUAZQAgAFIAVgBCTgCCLAAgAFIARwBCACAw1zDtMNUwoTCkMOuQGnUoACAAUgBHAEIAIIJyX2ljz4/wAFAAZQByAGYAaQBsACAAUgBHAEIAIABHAGUAbgDpAHIAaQBjAG8AQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAAUgBHAEIALQBQAHIAbwBmAGkAbGZukBoAIABSAEcAQgAgY8+P8GX/h072AEcAZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIAZQBzAGsAcgBpAHYAZQBsAHMAZQBBAGwAZwBlAG0AZQBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBlAGzHfLwYACAAUgBHAEIAINUEuFzTDMd8AFAAcgBvAGYAaQBsAG8AIABSAEcAQgAgAEcAZQBuAGUAcgBpAGMAbwBHAGUAbgBlAHIAaQBjACAAUgBHAEIAIABQAHIAbwBmAGkAbABlBB4EMQRJBDgEOQAgBD8EQAQ+BEQEOAQ7BEwAIABSAEcAQgBVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBm/wBpAGwAIABSAEcAQgAAZGVzYwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAAPNSAAEAAAABFs9YWVogAAAAAAAAdE0AAD3uAAAD0FhZWiAAAAAAAAAoGgAAFZ8AALg2Y3VydgAAAAAAAAABAc0AAHRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBwbGUgSW5jLkMsIGFsbCByaWdodHMgcmVzZXJ2ZWQuAHNmMzIAAAAAAAEMQgAABd7///MmAAAHkgAA/ZH///ui///9owAAA9wAAMBsACwAAAAACgAKAAAEJRBJREKZsxQDsCSGIVzZFnYTGIqktp7fG46uzAn2TAyCMPC9QAQAOw%3D%3D);
+}
+
+.sortableHeader {
+    padding-right: 3px;
+    padding-left: 13px;
+    margin-left: 4px;
+}
+
+.updateBtn { 
+  padding-top: 1em;
+  margin-left: 0;
+}
+
+.filterBox { 
+  border: 1px solid #DDDDDD;
+  margin-right: 1em;
+  padding-top: 5px;
+  padding-bottom: 5px;
+}
+
+.filterKey { 
+  font-weight: bold;
+}
\ No newline at end of file
diff --git a/gm/rebaseline_server/static/new/js/app.js b/gm/rebaseline_server/static/new/js/app.js
new file mode 100644
index 0000000..0a1fac0
--- /dev/null
+++ b/gm/rebaseline_server/static/new/js/app.js
@@ -0,0 +1,1130 @@
+'use strict';
+
+/**
+ * TODO (stephana@): This is still work in progress. 
+ * It does not offer the same functionality as the current version, but 
+ * will serve as the starting point for a new backend.
+ * It works with the current backend, but does not support rebaselining.
+ */
+
+/*
+ * Wrap everything into an IIFE to not polute the global namespace.
+ */
+(function () {
+
+  // Declare app level module which contains everything of the current app.
+  // ui.bootstrap refers to directives defined in the AngularJS Bootstrap 
+  // UI package (http://angular-ui.github.io/bootstrap/).
+  var app = angular.module('rbtApp', ['ngRoute', 'ui.bootstrap']);
+
+  // Configure the different within app views.
+  app.config(['$routeProvider', function($routeProvider) {
+    $routeProvider.when('/', {templateUrl: 'partials/index-view.html', 
+                              controller: 'IndexCtrl'});
+    $routeProvider.when('/view', {templateUrl: 'partials/rebaseline-view.html',
+                                  controller: 'RebaselineCrtrl'});
+    $routeProvider.otherwise({redirectTo: '/'});
+  }]);
+
+
+  // TODO (stephana): Some of these constants are 'gm' specific. In the 
+  // next iteration we need to remove those as we move the more generic 
+  // 'dm' testing tool. 
+  // 
+  // Shared constants used here and in the markup. These are exported when
+  // when used by a controller.
+  var c = {
+    // Define different view states as we load the data.
+    ST_LOADING: 1,
+    ST_STILL_LOADING: 2,
+    ST_READY: 3,
+
+    // These column types are used by the Column class.
+    COL_T_FILTER: 'filter',
+    COL_T_IMAGE: 'image',
+    COL_T_REGULAR: 'regular',
+
+    // Request parameters used to select between subsets of results.
+    RESULTS_ALL: 'all',
+    RESULTS_FAILURES: 'failures',
+
+    // Filter types are used by the Column class.
+    FILTER_FREE_FORM: 'free_form',
+    FILTER_CHECK_BOX: 'checkbox',
+
+    // Columns either provided by the backend response or added in code. 
+    // TODO (stephana): This should go away once we switch to 'dm'.
+    COL_BUGS: 'bugs',
+    COL_IGNORE_FAILURE: 'ignore-failure',
+    COL_REVIEWED_BY_HUMANS: 'reviewed-by-human',
+
+    // Defines the order in which image columns appear.
+    // TODO (stephana@): needs to be driven by backend data.
+    IMG_COL_ORDER: [
+       {
+        key: 'imageA', 
+        urlField: ['imageAUrl']
+      },
+      {
+        key: 'imageB', 
+        urlField: ['imageBUrl']
+      },
+      {
+        key: 'whiteDiffs',
+        urlField: ['differenceData', 'whiteDiffUrl'],
+        percentField: ['differenceData', 'percentDifferingPixels'],
+        valueField: ['differenceData', 'numDifferingPixels']
+      },
+      {
+        key: 'diffs',
+        urlField: ['differenceData', 'diffUrl'],
+        percentField: ['differenceData', 'perceptualDifference'],
+        valueField: ['differenceData', 'maxDiffPerChannel']
+      }
+    ],
+
+    // Choice of availabe image size selection.
+    IMAGE_SIZES: [
+      100,
+      200,
+      400
+    ],
+
+    // Choice of available number of records selection.
+    MAX_RECORDS: [
+      '100', 
+      '200',
+      '300'
+    ]
+  };  // end constants 
+
+  /*
+   * Index Controller 
+   */
+  // TODO (stephana): Remove $timeout since it only simulates loading delay.
+  app.controller('IndexCtrl', ['$scope', '$timeout', 'dataService', 
+  function($scope, $timeout, dataService) {
+    // init the scope 
+    $scope.c = c;
+    $scope.state = c.ST_LOADING;
+    $scope.qStr = dataService.getQueryString;
+
+    // TODO (stephana): Remove and replace with index data generated by the 
+    // backend to reflect the current "known" image sets to compare.
+    $scope.allSKPs = [
+    {
+      params: {
+        setBSection: 'actual-results',
+        setASection: 'expected-results',
+        setBDir: 'gs://chromium-skia-skp-summaries/' + 
+                 'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug',
+        setADir: 'repo:expectations/skp/' +
+                 'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug'
+      },
+      title: 'expected vs actuals on ' +
+             'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug'
+    }, 
+    {
+      params: {
+        setBSection: 'actual-results',
+        setASection: 'expected-results',
+        setBDir: 'gs://chromium-skia-skp-summaries/' +
+                 'Test-Ubuntu12-ShuttleA-GTX660-x86-Release',
+        setADir: 'repo:expectations/skp/'+
+                 'Test-Ubuntu12-ShuttleA-GTX660-x86-Release'
+      },
+      title: 'expected vs actuals on Test-Ubuntu12-ShuttleA-GTX660-x86-Release'
+    },
+    {
+      params: {
+        setBSection: 'actual-results',
+        setASection: 'actual-results',
+        setBDir: 'gs://chromium-skia-skp-summaries/' + 
+                 'Test-Ubuntu12-ShuttleA-GTX660-x86-Release',
+        setADir: 'gs://chromium-skia-skp-summaries/' + 
+                 'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug'
+      },
+      title: 'Actuals on Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug ' + 
+             'vs Test-Ubuntu12-ShuttleA-GTX660-x86-Release'
+    }
+    ];
+
+    // TODO (stephana): Remove this once we load index data from the server. 
+    $timeout(function () { 
+      $scope.state = c.ST_READY;
+    }); 
+  }]);
+
+  /* 
+   *  RebaselineCtrl
+   *  Controls the main comparison view.
+   *
+   *  @param {service} dataService Service that encapsulates functions to 
+   *                               retrieve data from the backend.
+   *  
+   */
+  app.controller('RebaselineCrtrl', ['$scope', '$timeout', 'dataService', 
+  function($scope, $timeout, dataService) {
+    // determine which to request
+    // TODO (stephana): This should be extracted from the query parameters.
+    var target = c.TARGET_GM;
+
+    // process the rquest arguments
+    // TODO (stephana): This should be determined from the query parameters.
+    var loadFn = dataService.loadAll;
+
+    // controller state variables 
+    var allData = null;
+    var filterFuncs = null;
+    var currentData = null;
+    var selectedData = null;
+
+    // Index of the column that should provide the sort key
+    var sortByIdx = 0;
+
+    // Sort in asending (true) or descending (false) order
+    var sortOrderAsc = true; 
+
+    // Array of functions for each column used for comparison during sort.
+    var compareFunctions = null;
+
+    // Variables to track load and render times
+    var startTime;
+    var loadStartTime;
+
+
+    /** Load the data from the backend **/ 
+    loadStartTime = Date.now();
+    function loadData() { 
+      loadFn().then(
+        function (serverData) {
+          $scope.header = serverData.header;
+          $scope.loadTime = (Date.now() - loadStartTime)/1000;
+
+          // keep polling if the data are not ready yet
+          if ($scope.header.resultsStillLoading) {
+            $scope.state = c.ST_STILL_LOADING;
+            $timeout(loadData, 5000);
+            return;
+          }
+
+          // get the filter colunms and an array to hold filter data by user
+          var fcol = getFilterColumns(serverData);
+          $scope.filterCols = fcol[0];
+          $scope.filterVals = fcol[1];
+
+          // Add extra columns and retrieve the image columns
+          var otherCols = [ Column.regular(c.COL_BUGS) ];
+          var imageCols = getImageColumns(serverData);
+
+          // Concat to get all columns
+          // NOTE: The order is important since filters are rendered first, 
+          // followed by regular columns and images 
+          $scope.allCols = $scope.filterCols.concat(otherCols, imageCols);
+
+          // Pre-process the data and get the filter functions.
+          var dataFilters = getDataAndFilters(serverData, $scope.filterCols, 
+                                              otherCols, imageCols);
+          allData = dataFilters[0];
+          filterFuncs = dataFilters[1];
+
+          // Get regular columns (== not image columns)
+          var regularCols = $scope.filterCols.concat(otherCols);
+
+          // Get the compare functions for regular and image columns. These
+          // are then used to sort by the respective columns. 
+          compareFunctions = DataRow.getCompareFunctions(regularCols, 
+                                                         imageCols);
+
+          // Filter and sort the results to get them ready for rendering
+          updateResults();
+
+          // Data are ready for display
+          $scope.state = c.ST_READY;
+        },
+        function (httpErrResponse) {
+          console.log(httpErrResponse);        
+        });
+    };
+
+    /*
+     * updateResults
+     * Central render function. Everytime settings/filters/etc. changed
+     * this function is called to filter, sort and splice the data. 
+     *
+     * NOTE (stephana): There is room for improvement here: before filtering
+     * and sorting we could check if this is necessary. But this has not been
+     * a bottleneck so far. 
+     */
+    function updateResults () {
+      // run digest before we update the results. This allows
+      // updateResults to be called from functions trigger by ngChange
+      $scope.updating = true;
+      startTime = Date.now();
+
+      // delay by one render cycle so it can be called via ng-change
+      $timeout(function() {
+        // filter data 
+        selectedData = filterData(allData, filterFuncs, $scope.filterVals);
+
+        // sort the selected data.
+        sortData(selectedData, compareFunctions, sortByIdx, sortOrderAsc);
+
+        // only conside the elements that we really need
+        var nRecords = $scope.settings.nRecords;
+        currentData = selectedData.slice(0, parseInt(nRecords));
+
+        DataRow.setRowspanValues(currentData, $scope.mergeIdenticalRows);
+
+        // update the scope with relevant data for rendering.
+        $scope.data = currentData;
+        $scope.totalRecords = allData.length;
+        $scope.showingRecords = currentData.length;
+        $scope.selectedRecords = selectedData.length;
+        $scope.updating = false;
+
+        // measure the filter time and total render time (via timeout).
+        $scope.filterTime = Date.now() - startTime;
+        $timeout(function() { 
+          $scope.renderTime = Date.now() - startTime;
+        });
+      });
+    };
+
+    /**
+     * Generate the style value to set the width of images. 
+     * 
+     * @param {Column} col Column that we are trying to render. 
+     * @param {int} paddingPx Number of padding pixels.
+     * @param {string} defaultVal Default value if not an image column.
+     *
+     * @return {string} Value to be used in ng-style element to set the width 
+     *                  of a image column.
+     **/
+    $scope.getImageWidthStyle = function (col, paddingPx, defaultVal) { 
+      var result = (col.ctype === c.COL_T_IMAGE) ? 
+                   ($scope.imageSize + paddingPx + 'px') : defaultVal;
+      return result;
+    };
+
+    /**
+     * Sets the column by which to sort the data. If called for the 
+     * currently sorted column it will cause the sort to toggle between
+     * ascending and descending. 
+     * 
+     * @param {int} colIdx Index of the column to use for sorting. 
+     **/
+    $scope.sortBy = function (colIdx) { 
+      if (sortByIdx === colIdx) { 
+        sortOrderAsc = !sortOrderAsc;
+      } else {
+        sortByIdx = colIdx;
+        sortOrderAsc = true;
+      }
+      updateResults();
+    };
+
+    /**
+     * Helper function to generate a CSS class indicating whether this column 
+     * is the sort key. If it is a class name with the sort direction (Asc/Desc) is 
+     * return otherwise the default value is returned. In markup we use this 
+     * to display (or not display) an arrow next to the column name. 
+     * 
+     * @param {string} prefix Prefix of the classname to be generated. 
+     * @param {int} idx Index of the target column.
+     * @param {string} defaultVal Value to return if current column is not used
+     *                            for sorting. 
+     *
+     * @return {string} CSS class name that a combination of the prefix and 
+     *                  direction indicator ('Asc' or 'Desc') if the column is 
+     *                  used for sorting. Otherwise the defaultVal is returned.
+     **/
+    $scope.getSortedClass = function (prefix, idx, defaultVal) {
+      if (idx === sortByIdx) { 
+        return prefix + ((sortOrderAsc) ? 'Asc' : 'Desc');
+      }
+
+      return defaultVal; 
+    };
+
+    /**
+     * Checkbox to merge identical records has change. Force an update.
+     **/
+    $scope.mergeRowsChanged = function () {
+      updateResults();
+    }
+
+    /**
+     * Max number of records to display has changed. Force an update. 
+     **/
+    $scope.maxRecordsChanged = function () {
+      updateResults();
+    };
+
+    /**
+     * Filter settings changed. Force an update. 
+     **/
+    $scope.filtersChanged = function () { 
+      updateResults();
+    };
+
+    /**
+     * Sets all possible values of the specified values to the given value.
+     * That means all checkboxes are eiter selected or unselected.
+     * Then force an update.
+     * 
+     * @param {int} idx Index of the target filter column.
+     * @param {boolean} val Value to set the filter values to. 
+     *
+     **/
+    $scope.setFilterAll = function (idx, val) {
+      for(var i=0, len=$scope.filterVals[idx].length; i<len; i++) {
+        $scope.filterVals[idx][i] = val;
+      }
+      updateResults();
+    };
+
+    /**
+     * Toggle the values of a filter. This toggles all values in a 
+     * filter. 
+     * 
+     * @param {int} idx Index of the target filter column.
+     **/
+    $scope.setFilterToggle = function (idx) { 
+      for(var i=0, len=$scope.filterVals[idx].length; i<len; i++) {
+        $scope.filterVals[idx][i] = !$scope.filterVals[idx][i];
+      }
+      updateResults();
+    };
+
+    // ****************************************
+    // Initialize the scope.
+    // ****************************************
+
+    // Inject the constants into the scope and set the initial state. 
+    $scope.c = c;
+    $scope.state = c.ST_LOADING;
+
+    // Initial settings
+    $scope.settings = {
+      showThumbnails: true,
+      imageSize: c.IMAGE_SIZES[0],
+      nRecords: c.MAX_RECORDS[0],
+      mergeIdenticalRows: true
+    };
+
+    // Initial values for filters set in loadData()
+    $scope.filterVals = [];
+
+    // Information about records - set in loadData()
+    $scope.totalRecords = 0;
+    $scope.showingRecords = 0;
+    $scope.updating = false;
+
+    // Trigger the data loading. 
+    loadData();
+
+  }]);
+
+  // data structs to interface with markup and backend
+  /**
+   * Models a column. It aggregates attributes of all 
+   * columns types. Some might be empty. See convenience 
+   * factory methods below for different column types.
+   * 
+   * @param {string} key Uniquely identifies this columns
+   * @param {string} ctype Type of columns. Use COL_* constants. 
+   * @param {string} ctitle Human readable title of the column.
+   * @param {string} ftype Filter type. Use FILTER_* constants.
+   * @param {FilterOpt[]} foptions Filter options. For 'checkbox' filters this 
+                                   is used to render all the checkboxes. 
+                                   For freeform filters this is a list of all
+                                   available values. 
+   * @param {string} baseUrl Baseurl for image columns. All URLs are relative 
+                             to this.
+   *
+   * @return {Column} Instance of the Column class. 
+   **/
+  function Column(key, ctype, ctitle, ftype, foptions, baseUrl) { 
+    this.key = key; 
+    this.ctype = ctype;
+    this.ctitle = ctitle;
+    this.ftype = ftype;
+    this.foptions = foptions;
+    this.baseUrl = baseUrl;
+    this.foptionsArr = [];
+
+    // get the array of filter options for lookup in indexOfOptVal
+    if (this.foptions) {
+      for(var i=0, len=foptions.length; i<len; i++) {
+        this.foptionsArr.push(this.foptions[i].value);
+      }
+    }
+  }
+
+  /**
+   * Find the index of an value in a column with a fixed set
+   * of options. 
+   * 
+   * @param {string} optVal Value of the column.
+   *
+   * @return {int} Index of optVal in this column.
+   **/
+  Column.prototype.indexOfOptVal = function (optVal) {
+    return this.foptionsArr.indexOf(optVal);
+  };
+
+  /**
+   * Set filter options for this column.
+   * 
+   * @param {FilterOpt[]} foptions Possible values for this column. 
+   **/
+  Column.prototype.setFilterOptions = function (foptions) { 
+    this.foptions = foptions;
+  };
+
+  /**
+   * Factory function to create a filter column. Same args as Column()
+   **/
+  Column.filter = function(key, ctitle, ftype, foptions) { 
+    return new Column(key, c.COL_T_FILTER, ctitle || key, ftype, foptions); 
+  }
+
+  /**
+   * Factory function to create an image column. Same args as Column()
+   **/
+  Column.image = function (key, ctitle, baseUrl) { 
+    return new Column(key, c.COL_T_IMAGE, ctitle || key, null, null, baseUrl); 
+  };
+
+  /**
+   * Factory function to create a regular column. Same args as Column()
+   **/
+  Column.regular = function (key, ctitle) { 
+    return new Column(key, c.COL_T_REGULAR, ctitle || key); 
+  }; 
+
+  /**
+   * Helper class to wrap a single option in a filter. 
+   * 
+   * @param {string} value Option value. 
+   * @param {int} count Number of instances of this option in the dataset.
+   *
+   * @return {} Instance of FiltertOpt
+   **/
+  function FilterOpt(value, count) { 
+    this.value = value; 
+    this.count = count;
+  }
+
+  /**
+   * Container for a single row in the dataset.
+   * 
+   * @param {int} rowspan Number of rows (including this and following rows) 
+                          that have identical values. 
+   * @param {string[]} dataCols Values of the respective columns (combination
+                                of filter and regular columns)
+   * @param {ImgVal[]} imageCols Image meta data for the image columns.
+   *
+   * @return {DataRow} Instance of DataRow. 
+   **/
+  function DataRow(rowspan, dataCols, imageCols) { 
+    this.rowspan = rowspan;
+    this.dataCols = dataCols;
+    this.imageCols = imageCols;
+  }
+
+  /**
+   * Gets the comparator functions for the columns in this dataset.
+   * The comparators are then used to sort the dataset by the respective
+   * column. 
+   *
+   * @param {Column[]} dataCols Data columns (= non-image columns)
+   * @param {Column[]} imgCols Image columns.
+   *
+   * @return {Function[]} Array of functions that can be used to sort by the 
+   *                      respective column.
+   **/
+  DataRow.getCompareFunctions = function (dataCols, imgCols) {
+    var result = [];
+    for(var i=0, len=dataCols.length; i<len; i++) { 
+      result.push(( function (col, idx) { 
+        return function (a, b) {
+          return (a.dataCols[idx] < b.dataCols[idx]) ? -1 : 
+                 ((a.dataCols[idx] === b.dataCols[idx]) ? 0 : 1);
+        };
+      }(dataCols[i], i) ));
+    }
+
+    for(var i=0, len=imgCols.length; i<len; i++) { 
+      result.push((function (col, idx) { 
+        return function (a,b) {
+          var aVal = a.imageCols[idx].percent;
+          var bVal = b.imageCols[idx].percent;
+
+          return (aVal < bVal) ? -1 : ((aVal === bVal) ? 0 : 1);
+        };
+      }(imgCols[i], i) ));
+    }
+
+    return result;
+  };
+
+  /**
+  * Set the rowspan values of a given array of DataRow instances.
+  * 
+  * @param {DataRow[]} data Dataset in desired order (after sorting).
+  * @param {mergeRows} mergeRows Indicate whether to sort 
+   **/
+  DataRow.setRowspanValues = function (data, mergeRows) {
+    var curIdx, rowspan, cur;
+    if (mergeRows) { 
+      for(var i=0, len=data.length; i<len;) {
+        curIdx = i;
+        cur = data[i];
+        rowspan = 1;
+        for(i++; ((i<len) && (data[i].dataCols === cur.dataCols)); i++) {
+          rowspan++;
+          data[i].rowspan=0;
+        }
+        data[curIdx].rowspan = rowspan;
+      }
+    } else {
+      for(var i=0, len=data.length; i<len; i++) { 
+        data[i].rowspan = 1;
+      }
+    }
+  };
+
+  /**
+   * Wrapper class for image related data.
+   * 
+   * @param {string} url Relative Url of the image or null if not available.
+   * @param {float} percent Percent of pixels that are differing.
+   * @param {int} value Absolute number of pixes differing.
+   *
+   * @return {ImgVal} Instance of ImgVal.
+   **/
+  function ImgVal(url, percent, value) {
+    this.url = url;
+    this.percent = percent;
+    this.value = value;
+  }
+
+  /**
+   * Extracts the filter columns from the JSON response of the server. 
+   * 
+   * @param {object} data Server response. 
+   *
+   * @return {Column[]} List of filter columns as described in 'header' field. 
+   **/
+  function getFilterColumns(data) {
+    var result = [];
+    var vals = [];
+    var colOrder = data.extraColumnOrder;
+    var colHeaders = data.extraColumnHeaders;
+    var fopts, optVals, val;
+
+    for(var i=0, len=colOrder.length; i<len; i++) {
+      if (colHeaders[colOrder[i]].isFilterable) {
+        if (colHeaders[colOrder[i]].useFreeformFilter) {
+          result.push(Column.filter(colOrder[i], 
+                                    colHeaders[colOrder[i]].headerText, 
+                                    c.FILTER_FREE_FORM));
+          vals.push('');
+        }
+        else {
+          fopts = [];
+          optVals = [];
+
+          // extract the different options for this column
+          for(var j=0, jlen=colHeaders[colOrder[i]].valuesAndCounts.length; 
+              j<jlen; j++) {
+                val = colHeaders[colOrder[i]].valuesAndCounts[j];
+                fopts.push(new FilterOpt(val[0], val[1]));
+                optVals.push(false);
+          }
+
+          // ad the column and values
+          result.push(Column.filter(colOrder[i], 
+                                    colHeaders[colOrder[i]].headerText, 
+                                    c.FILTER_CHECK_BOX, 
+                                    fopts));
+          vals.push(optVals);
+        }
+      }
+    }
+
+    return [result, vals];
+  }
+
+  /**
+   * Extracts the image columns from the JSON response of the server. 
+   * 
+   * @param {object} data Server response. 
+   *
+   * @return {Column[]} List of images columns as described in 'header' field. 
+   **/
+  function getImageColumns(data) {
+    var CO = c.IMG_COL_ORDER;
+    var imgSet;
+    var result = [];
+    for(var i=0, len=CO.length; i<len; i++) { 
+      imgSet = data.imageSets[CO[i].key];
+      result.push(Column.image(CO[i].key, 
+                               imgSet.description, 
+                               ensureTrailingSlash(imgSet.baseUrl)));
+    }
+    return result;
+  }
+
+  /**
+   * Make sure Url has a trailing '/'. 
+   * 
+   * @param {string} url Base url. 
+   * @return {string} Same url with a trailing '/' or same as input if it 
+                      already contained '/'.
+   **/
+  function ensureTrailingSlash(url) { 
+    var result = url.trim();
+
+    // TODO: remove !!!
+    result = fixUrl(url);
+    if (result[result.length-1] !== '/') {
+      result += '/';
+    }
+    return result;
+  }
+
+  // TODO: remove. The backend should provide absoute URLs
+  function fixUrl(url) {
+    url = url.trim();
+    if ('http' === url.substr(0, 4)) {
+      return url;
+    }
+
+    var idx = url.indexOf('static');
+    if (idx != -1) {
+      return '/' + url.substr(idx);
+    }
+
+    return url;
+  };
+
+  /**
+   * Processes that data and returns filter functions. 
+   * 
+   * @param {object} Server response.
+   * @param {Column[]} filterCols Filter columns. 
+   * @param {Column[]} otherCols Columns that are neither filters nor images.
+   * @param {Column[]} imageCols Image columns.
+   *
+   * @return {[]} Returns a pair [dataRows, filterFunctions] where:
+   *       - dataRows is an array of DataRow instances.
+   *       - filterFunctions is an array of functions that can be used to 
+   *         filter the column at the corresponding index. 
+   *
+   **/
+  function getDataAndFilters(data, filterCols, otherCols, imageCols) {
+    var el;
+    var result = [];
+    var lookupIndices = [];
+    var indexerFuncs = [];
+    var temp;
+
+    // initialize the lookupIndices
+    var filterFuncs = initIndices(filterCols, lookupIndices, indexerFuncs);
+
+    // iterate over the data and get the rows
+    for(var i=0, len=data.imagePairs.length; i<len; i++) {
+      el = data.imagePairs[i];
+      temp = new DataRow(1, getColValues(el, filterCols, otherCols),
+                                 getImageValues(el, imageCols));
+      result.push(temp);
+
+      // index the row
+      for(var j=0, jlen=filterCols.length; j < jlen; j++) {
+        indexerFuncs[j](lookupIndices[j], filterCols[j], temp.dataCols[j], i);
+      }
+    }
+
+    setFreeFormFilterOptions(filterCols, lookupIndices);
+    return [result, filterFuncs];
+  }
+
+  /**
+   * Initiazile the lookup indices and indexer functions for the filter
+   * columns. 
+   * 
+   * @param {Column} filterCols Filter columns
+   * @param {[]} lookupIndices Will be filled with datastructures for 
+                               fast lookup (output parameter)
+   * @param {[]} lookupIndices Will be filled with functions to index data 
+                               of the column with the corresponding column.
+   *
+   * @return {[]} Returns an array of filter functions that can be used to 
+                  filter the respective column.  
+   **/
+  function initIndices(filterCols, lookupIndices, indexerFuncs) {
+    var filterFuncs = [];
+    var temp;
+
+    for(var i=0, len=filterCols.length; i<len; i++) { 
+      if (filterCols[i].ftype === c.FILTER_FREE_FORM) {
+        lookupIndices.push({});
+        indexerFuncs.push(indexFreeFormValue);
+        filterFuncs.push(
+          getFreeFormFilterFunc(lookupIndices[lookupIndices.length-1]));
+      }
+      else if (filterCols[i].ftype === c.FILTER_CHECK_BOX) { 
+        temp = [];
+        for(var j=0, jlen=filterCols[i].foptions.length; j<jlen; j++) {
+          temp.push([]);
+        }
+        lookupIndices.push(temp);
+        indexerFuncs.push(indexDiscreteValue);
+        filterFuncs.push(
+          getDiscreteFilterFunc(lookupIndices[lookupIndices.length-1]));
+      }
+    }
+
+    return filterFuncs; 
+  }
+
+  /**
+   * Helper function that extracts the values of free form columns from 
+   * the lookupIndex and injects them into the Column object as FilterOpt 
+   * objects.
+   **/
+  function setFreeFormFilterOptions(filterCols, lookupIndices) {
+    var temp, k;
+    for(var i=0, len=filterCols.length; i<len; i++) { 
+      if (filterCols[i].ftype === c.FILTER_FREE_FORM) { 
+        temp = []
+        for(k in lookupIndices[i]) { 
+          if (lookupIndices[i].hasOwnProperty(k)) { 
+            temp.push(new FilterOpt(k, lookupIndices[i][k].length));
+          }
+        }
+        filterCols[i].setFilterOptions(temp);
+      }
+    }
+  }
+
+  /**
+   * Index a discrete column (column with fixed number of values). 
+   *
+   **/
+  function indexDiscreteValue(lookupIndex, col, dataVal, dataRowIndex) {
+    var i = col.indexOfOptVal(dataVal);
+    lookupIndex[i].push(dataRowIndex);
+  }
+
+  /**
+   * Index a column with free form text (= not fixed upfront)
+   *
+   **/
+  function indexFreeFormValue(lookupIndex, col, dataVal, dataRowIndex) { 
+    if (!lookupIndex[dataVal]) { 
+      lookupIndex[dataVal] = [];
+    }
+    lookupIndex[dataVal].push(dataRowIndex);
+  }
+
+
+  /**
+   * Get the function to filter a column with the given lookup index
+   * for discrete (fixed upfront) values. 
+   * 
+   **/
+  function getDiscreteFilterFunc(lookupIndex) { 
+    return function(filterVal) {
+      var result = [];
+      for(var i=0, len=lookupIndex.length; i < len; i++) {
+        if (filterVal[i]) { 
+          // append the indices to the current array
+          result.push.apply(result, lookupIndex[i]);
+        }
+      }
+      return { nofilter: false, records: result };
+    };
+  }
+
+  /**
+   * Get the function to filter a column with the given lookup index
+   * for free form values.
+   * 
+   **/
+  function getFreeFormFilterFunc(lookupIndex) {
+    return function(filterVal) {
+      filterVal = filterVal.trim();
+      if (filterVal === '') {
+        return { nofilter: true };
+      }
+      return { 
+        nofilter: false, 
+        records: lookupIndex[filterVal] || []
+      };
+    };
+  }
+
+  /**
+   * Filters the data based on the given filterColumns and 
+   * corresponding filter values. 
+   * 
+   * @return {[]} Subset of the input dataset based on the 
+   *              filter values.
+   **/
+  function filterData(data, filterFuncs, filterVals) {
+    var recordSets = [];
+    var filterResult;
+
+    // run through all the filters
+    for(var i=0, len=filterFuncs.length; i<len; i++) { 
+      filterResult = filterFuncs[i](filterVals[i]);
+      if (!filterResult.nofilter) { 
+        recordSets.push(filterResult.records);
+      }
+    }
+
+    // If there are no restrictions then return the whole dataset.
+    if (recordSets.length === 0) {
+      return data;
+    } 
+
+    // intersect the records returned by filters. 
+    var targets = intersectArrs(recordSets);
+    var result = [];
+    for(var i=0, len=targets.length; i<len; i++) {
+      result.push(data[targets[i]]);
+    }
+
+    return result; 
+  }
+
+  /**
+   * Creates an object where the keys are the elements of the input array
+   * and the values are true. To be used for set operations with integer.
+   **/
+  function arrToObj(arr) { 
+    var o = {};
+    var i,len;
+    for(i=0, len=arr.length; i<len; i++) { 
+      o[arr[i]] = true;
+    }
+    return o;
+  }
+
+  /**
+   * Converts the keys of an object to an array after converting 
+   * each key to integer. To be used for set operations with integers.  
+   **/
+  function objToArr(obj) { 
+    var result = [];
+    for(var k in obj) {
+      if (obj.hasOwnProperty(k)) { 
+        result.push(parseInt(k));
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Find the intersection of a set of arrays.
+   **/
+  function intersectArrs(sets) {
+    var temp, obj;
+
+    if (sets.length === 1) { 
+      return sets[0];
+    }
+
+    // sort by size and load the smallest into the object
+    sets.sort(function(a,b) { return a.length - b.length; });
+    obj = arrToObj(sets[0]); 
+
+    // shrink the hash as we fail to find elements in the other sets
+    for(var i=1, len=sets.length; i<len; i++) { 
+      temp = arrToObj(sets[i]);
+      for(var k in obj) {
+        if (obj.hasOwnProperty(k) && !temp[k]) { 
+          delete obj[k];
+        }
+      }
+    }
+    
+    return objToArr(obj);
+  }
+
+  /**
+   * Extract the column values from an ImagePair (contained in the server 
+   * response) into filter and data columns. 
+   *
+   * @return {[]} Array of data contained in one data row.
+   **/
+  function getColValues(imagePair, filterCols, otherCols) { 
+    var result = [];
+    for(var i=0, len=filterCols.length; i<len; i++) { 
+      result.push(imagePair.extraColumns[filterCols[i].key]);
+    }
+
+    for(var i=0, len=otherCols.length; i<len; i++) { 
+      result.push(get_robust(imagePair, ['expectations', otherCols[i].key]));
+    }
+
+    return result;
+  }
+
+  /**
+   * Extract the image meta data from an Image pair returned by the server.
+   **/
+  function getImageValues(imagePair, imageCols) {
+    var result=[];
+    var url, value, percent, diff;
+    var CO = c.IMG_COL_ORDER;
+
+    for(var i=0, len=imageCols.length; i<len; i++) {
+      percent = get_robust(imagePair, CO[i].percentField);
+      value = get_robust(imagePair, CO[i].valueField);
+      url = get_robust(imagePair, CO[i].urlField);
+      if (url) { 
+        url = imageCols[i].baseUrl + url;
+      }
+      result.push(new ImgVal(url, percent, value));
+    }
+
+    return result;
+  }
+
+  /**
+   * Given an object find sub objects for the given index without 
+   * throwing an error if any of the sub objects do not exist. 
+   **/
+  function get_robust(obj, idx) {
+    if (!idx) {
+      return;
+    }
+
+    for(var i=0, len=idx.length; i<len; i++) {
+      if ((typeof obj === 'undefined') || (!idx[i])) {
+        return;  // returns 'undefined'
+      }
+
+      obj = obj[idx[i]];
+    }
+
+    return obj;
+  }
+
+  /**
+   * Set all elements in the array to the given value. 
+   **/
+  function setArrVals(arr, newVal) { 
+    for(var i=0, len=arr.length; i<len; i++) { 
+      arr[i] = newVal;
+    }
+  }
+
+  /**
+   * Toggle the elements of a boolean array. 
+   * 
+   **/
+  function toggleArrVals(arr) { 
+    for(var i=0, len=arr.length; i<len; i++) { 
+      arr[i] = !arr[i];
+    }
+  }
+
+  /**
+   * Sort the array of DataRow instances with the given compare functions 
+   * and the column at the given index either in ascending or descending order.
+   **/
+  function sortData (allData, compareFunctions, sortByIdx, sortOrderAsc) {
+    var cmpFn = compareFunctions[sortByIdx];
+    var useCmp = cmpFn;
+    if (!sortOrderAsc) {
+      useCmp = function ( _ ) {
+        return -cmpFn.apply(this, arguments);
+      };
+    }
+    allData.sort(useCmp);
+  }
+
+
+  // *****************************  Services *********************************
+
+  /**  
+   *  Encapsulates all interactions with the backend by handling 
+   *  Urls and HTTP requests. Also exposes some utility functions
+   *  related to processing Urls. 
+   */
+  app.factory('dataService', [ '$http', function ($http) {
+    /** Backend related constants  **/ 
+    var c = {
+      /** Url to retrieve failures */ 
+      FAILURES: '/results/failures',
+
+      /** Url to retrieve all GM results */ 
+      ALL:      '/results/all'
+    };
+
+    /**
+     * Convenience function to retrieve all results.
+     * 
+     * @return {Promise} Will resolve to either the data (success) or to 
+     *                   the HTTP response (error).
+     **/
+    function loadAll() {
+      return httpGetData(c.ALL);
+    }
+
+    /**
+     * Make a HTTP get request with the given query parameters.
+     * 
+     * @param {} 
+     * @param {}
+     *
+     * @return {} 
+     **/
+    function httpGetData(url, queryParams) {
+      var reqConfig = {
+        method: 'GET',
+        url: url,
+        params: queryParams
+      };
+
+      return $http(reqConfig).then(
+        function(successResp) {
+          return successResp.data;
+        });
+    }
+
+    /**
+     * Takes an arbitrary number of objects and generates a Url encoded
+     * query string.
+     *
+     **/
+    function getQueryString( _params_ ) {
+      var result = [];
+      for(var i=0, len=arguments.length; i < len; i++) {
+        if (arguments[i]) {
+          for(var k in arguments[i]) { 
+            if (arguments[i].hasOwnProperty(k)) {
+              result.push(encodeURIComponent(k) + '=' + 
+                          encodeURIComponent(arguments[i][k]));
+            }
+          }
+        }
+      }
+      return result.join("&");
+    }
+
+    // Interface of the service:
+    return {
+      getQueryString: getQueryString,
+      loadAll: loadAll
+    };
+
+  }]);  
+
+})();
diff --git a/gm/rebaseline_server/static/new/new-index.html b/gm/rebaseline_server/static/new/new-index.html
new file mode 100644
index 0000000..b7067f1
--- /dev/null
+++ b/gm/rebaseline_server/static/new/new-index.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en" ng-app="rbtApp">
+
+<head>
+  <meta name="viewport" content="width=device-width">
+  <meta charset="utf-8">
+  <title>Rebaseline Tool</title>
+  <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
+  <link rel="stylesheet" href="css/app.css">
+</head>
+<body>
+
+
+  <div class="container-fluid">
+      <div class="pull-right">
+        Instructions, roadmap, etc. are at <a href="http://goo.gl/CqeVHq" target="_blank">http://goo.gl/CqeVHq</a>
+      </div>
+  </div>
+
+  <!-- Include the different views here. 
+       Make everything fluid to scale to the maximum size of any screen.   -->
+  <div class="container-fluid">
+     <div ng-view></div>
+  </div>
+
+  <!-- do everything local right now: Move to CDN fix when it's a performance issue -->
+  <script src="bower_components/angular/angular.js"></script>
+  <script src="bower_components/angular-route/angular-route.js"></script>
+
+  <!-- Local includes external libs --> 
+  <script src="bower_components/angular-bootstrap/ui-bootstrap.js"></script>
+  <script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
+
+  <!-- Local JS --> 
+  <script src="js/app.js"></script>
+</body>
+</html>
diff --git a/gm/rebaseline_server/static/new/partials/index-view.html b/gm/rebaseline_server/static/new/partials/index-view.html
new file mode 100644
index 0000000..72db231
--- /dev/null
+++ b/gm/rebaseline_server/static/new/partials/index-view.html
@@ -0,0 +1,22 @@
+<div class="container-fluid ng-cloak" ng-cloak>
+    <div class="row" ng-show="state === c.ST_LOADING">
+        <h4>Loading ...</h4>
+    </div>
+
+    <div class="row" ng-show="state === c.ST_READY">
+        <h4>GM Expectations vs Actuals:</h4>
+        <ul>
+            <li><a href="#/view?{{ qStr({ resultsToLoad: c.RESULTS_FAILURES }) }}">Failures</a></li>
+            <li><a href="#/view?{{ qStr({ resultsToLoad: c.RESULTS_ALL }) }}">All</a></li>
+        </ul>
+
+        <h4>Rendered SKPs:</h4>
+        <ul>
+            <li ng-repeat="oneSKP in allSKPs">
+                <a href="#/view?{{ qStr(oneSKP.params) }}">
+                    {{oneSKP.title}}
+                </a>
+            </li>
+        </ul>
+    </div>
+</div>
diff --git a/gm/rebaseline_server/static/new/partials/rebaseline-view.html b/gm/rebaseline_server/static/new/partials/rebaseline-view.html
new file mode 100644
index 0000000..a2c28f7
--- /dev/null
+++ b/gm/rebaseline_server/static/new/partials/rebaseline-view.html
@@ -0,0 +1,207 @@
+<div class="container-fluid ng-cloak" ng-cloak>
+
+    <div class="row" ng-show="state === c.ST_LOADING">
+        <h4>Loading ...</h4>
+    </div>
+
+    <div class="row" ng-show="state === c.ST_STILL_LOADING">
+        <h4>Still loading from backend.</h4>
+        <div>
+            Load time so far: {{ loadTime | number:0 }} s.
+        </div>
+    </div>
+
+    <div class="row" ng-show="state === c.ST_READY">
+        <tabset>
+            <tab heading="Unfiled">
+                <!-- settings --> 
+                <div class="container controlBox">
+                    <form class="form-inline settingsForm" novalidate >
+                        <legend class="simpleLegend">Settings</legend>
+                            <div class="checkbox formPadding">
+                                <label>
+                                       <input type="checkbox" 
+                                           ng-model="settings.showThumbnails">Show thumbnails
+                                 </label>
+                             </div>
+
+                            <div class="checkbox formPadding">
+                                <label>
+                                       <input type="checkbox" 
+                                     ng-model="settings.mergeIdenticalRows"
+                                      ng-change="mergeRowsChanged(mergeIdenticalRows)"> Merge identical rows
+                                 </label>
+                            </div>
+
+                            <div class="form-group formPadding">
+                                 <label for="imageWidth">Image Width</label>
+                                     <select ng-model="settings.imageSize" 
+                                             ng-options="iSize for iSize in c.IMAGE_SIZES"
+                                             class="form-control input-sm">
+
+                                     </select>
+                            </div>
+                            <div class="form-group formPadding">
+                                 <label>Max records</label>
+                                     <select ng-model="settings.nRecords" 
+                                             ng-options="n for n in c.MAX_RECORDS"
+                                             ng-change="maxRecordsChanged();"
+                                             class="form-control input-sm">
+                                     </select>
+                            </div>
+                    </form>
+                    <br>
+
+                    <form class="form settingsForm" novalidate>
+                        <legend class="simpleLegend">Filters</legend>
+                        <div class="container-fluid">
+                            <div class="col-lg-2 filterBox" ng-repeat="oneCol in filterCols">
+                                  <div class="filterKey">{{ oneCol.key }}</div>
+
+                                  <!-- If we filter this column using free-form text match... -->
+                                  <div ng-if="oneCol.ftype === c.FILTER_FREE_FORM">
+                                    <input type="text"
+                                           ng-model="filterVals[$index]"
+                                           typeahead="opt.value for opt in oneCol.foptions | filter:$viewValue"
+                                           class="form-control input-sm">
+                                    <br>
+                                    <a ng-click="filterVals[$index]=''"
+                                       ng-disabled="'' === filterVals[$index]"
+                                       href="">
+                                      Clear
+                                    </a>
+                                  </div>
+
+                                  <!-- If we filter this column using checkboxes... -->
+                                  <div ng-if="oneCol.ftype === c.FILTER_CHECK_BOX">
+
+                                      <div class="checkbox" ng-repeat="oneOpt in oneCol.foptions">
+                                        <label>
+                                          <input type="checkbox" 
+                                                 ng-model="filterVals[$parent.$index][$index]">{{oneOpt.value}} ({{ oneOpt.count }})
+                                        </label>
+                                    </div>
+                                    <div>
+                                        <a ng-click="setFilterAll($index, true)" href="">All</a> -
+                                        <a ng-click="setFilterAll($index, False)" href="">None</a> - 
+                                        <a ng-click="setFilterToggle($index)" href="">Toggle</a>
+                                    </div>
+                                  </div>
+                            </div>
+                            <br>
+                        </div>
+
+                        <div class="container updateBtn">
+                            <button class="btn btn-success col-lg-4 pull-left"
+                                    ng-click="filtersChanged()"
+                                    ng-disabled="updating">
+                                        {{ updating && 'Updating ...' || 'Update' }}
+                            </button>
+                        </div>
+
+                    </form>
+
+                    <br>
+
+                    <!-- Rows --> 
+
+                    <!-- results header -->
+                    <div class="col-lg-12 resultsHeaderActions well">
+                            <div class="col-lg-6">
+                              <h4>Showing {{showingRecords}} of {{selectedRecords}} (of {{totalRecords}} total)</h4>
+                              <span ng-show="renderTime > 0">
+                                Rendered in {{renderTime | number:0 }} ms (filtered and sorted in {{ filterTime | number:0 }} ms).
+                              </span>
+                              <br>
+                              (click on the column header radio buttons to re-sort by that column)
+                            </div>
+
+
+                            <div class="col-lg-6">
+                                All tests shown: 
+                                <button class="btn btn-default btn-sm" ng-click="selectAllImagePairs()">Select</button>
+                                <button class="btn btn-default btn-sm" ng-click="clearAllImagePairs()">Clear</button>
+                                <button class="btn btn-default btn-sm" ng-click="toggleAllImagePairs()">Toggle</button>
+
+                                <div ng-repeat="otherTab in tabs">
+                                    <button class="btn btn-default btn-sm"
+                                            ng-click="moveSelectedImagePairsToTab(otherTab)"
+                                            ng-disabled="selectedImagePairs.length == 0"
+                                            ng-show="otherTab != viewingTab">
+                                            Move {{selectedImagePairs.length}} selected tests to {{otherTab}} tab
+                                    </button>
+                                </div>
+                            </div>
+                            <br>
+                    </div>
+
+                    <!-- results --> 
+                    <table class="table table-bordered">
+                        <thead>
+                            <tr>
+                                <!-- Most column headers are displayed in a common fashion... -->
+                                <th ng-repeat="oneCol in allCols" ng-style="{ 'min-width': getImageWidthStyle(oneCol, 20, 'auto') }">
+                                    <a ng-class="getSortedClass('sort', $index, '')"
+                                       ng-click="sortBy($index)"
+                                       href=""
+                                       class="sortableHeader">
+                                          {{ oneCol.ctitle }}
+                                    </a>
+                                </th>
+                                <th>
+                                    <div class="checkbox">
+                                        <label>
+                                               <input type="checkbox" ng-model="allChecked" ng-change="checkAll()">All
+                                         </label>
+                                     </div>
+                                </th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <tr ng-repeat="oneRow in data">
+                                <td ng-repeat="oneColVal in oneRow.dataCols">
+                                    {{oneColVal}}
+                                </td>
+
+                                <td ng-repeat="oneCol in oneRow.imageCols" ng-if="oneRow.rowspan > 0" rowspan="{{ oneRow.rowspan }}">
+                                    <div ng-show="oneCol.url">
+                                        <a href="{{ oneCol.url }}" target="_blank">View Image</a><br/>
+                                        <img ng-if="settings.showThumbnails" 
+                                             ng-style="{ width: settings.imageSize+'px' }" 
+                                             ng-src="{{ oneCol.url }}" />
+                                        <div ng-if="oneCol.percent && oneCol.value">
+                                            {{oneCol.percent}}% ({{ oneCol.value }})
+                                        </div>
+                                    </div>
+                                    <div ng-hide="oneCol.url" style="text-align:center">
+                                        <span ng-show="oneCol.url === null">&ndash;none&ndash;</span>
+                                        <span ng-hide="oneCol.url === null">&nbsp;</span>
+                                    </div>
+                                </td>
+
+                                <td ng-if="oneRow.rowspan > 0" rowspan="{{ oneRow.rowspan }}">
+                                    <div class="checkbox">
+                                        <input type="checkbox"
+                                               ng-model="checkRows[$index]" 
+                                               ng-change="rowCheckChanged($index)">
+                                    </div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+
+                </div>
+            </tab>
+
+            <tab heading="Hidden">
+                <h3>Hidden</h3>
+            </tab>
+
+            <tab heading="Pending Approval">
+                <h3>Pending Approval</h3>
+            </tab>
+
+        </tabset>
+
+    </div>
+</div>
diff --git a/gm/rebaseline_server/static/utils.js b/gm/rebaseline_server/static/utils.js
new file mode 100644
index 0000000..e846b90
--- /dev/null
+++ b/gm/rebaseline_server/static/utils.js
@@ -0,0 +1,12 @@
+function make_results_header_sticky( ) {
+  element = $(".results-header-actions");
+  var pos = element.position();
+  $(window).scroll( function() {
+    var windowPos = $(window).scrollTop();
+    if (windowPos > pos.top) {
+      element.addClass("sticky");
+    } else {
+      element.removeClass("sticky");
+    }
+  });
+}
diff --git a/gm/rebaseline_server/static/view.css b/gm/rebaseline_server/static/view.css
index 0e86412..80f2809 100644
--- a/gm/rebaseline_server/static/view.css
+++ b/gm/rebaseline_server/static/view.css
@@ -68,3 +68,37 @@
 .image-link {
     text-decoration: none;
 }
+
+.results-header {
+    overflow: hidden;
+    padding: 10px;
+    background-color: #ccccff;
+}
+
+.results-header-actions {
+    float: right;
+}
+
+.sticky {
+    position: fixed;
+    top: 2px;
+    box-shadow: -2px 2px 5px 0 rgba(0,0,0,.45);
+    background: white;
+    right: 2px;
+    padding: 10px;
+    border: 2px solid #222;
+}
+
+.sort-desc {
+     background:no-repeat left center url(data:image/gif;base64,R0lGODlhCgAKALMAAHFxcYKCgp2dnaampq+vr83NzeHh4f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAAAgAIf/8SUNDUkdCRzEwMTIAAAUwYXBwbAIgAABtbnRyUkdCIFhZWiAH2QACABkACwAaAAthY3NwQVBQTAAAAABhcHBsAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkc2NtAAABCAAAAvJkZXNjAAAD/AAAAG9nWFlaAAAEbAAAABR3dHB0AAAEgAAAABRyWFlaAAAElAAAABRiWFlaAAAEqAAAABRyVFJDAAAEvAAAAA5jcHJ0AAAEzAAAADhjaGFkAAAFBAAAACxn/1RSQwAABLwAAAAOYlRSQwAABLwAAAAObWx1YwAAAAAAAAARAAAADGVuVVMAAAAmAAACfmVzRVMAAAAmAAABgmRhREsAAAAuAAAB6mRlREUAAAAsAAABqGZpRkkAAAAoAAAA3GZyRlUAAAAoAAABKml0SVQAAAAoAAACVm5sTkwAAAAoAAACGG5iTk8AAAAmAAABBHB0QlIAAAAmAAABgnN2U0UAAAAmAAABBGphSlAAAAAaAAABUmtvS1IAAAAWAAACQHpoVFcAAAAWAAABbHpoQ04AAAAWAAAB1HJ1UlUAAAAiAAACpHBsUEwAAAAsAAACxgBZAGwAZQBpAG4AZf8AbgAgAFIARwBCAC0AcAByAG8AZgBpAGkAbABpAEcAZQBuAGUAcgBpAHMAawAgAFIARwBCAC0AcAByAG8AZgBpAGwAUAByAG8AZgBpAGwAIABHAOkAbgDpAHIAaQBxAHUAZQAgAFIAVgBCTgCCLAAgAFIARwBCACAw1zDtMNUwoTCkMOuQGnUoACAAUgBHAEIAIIJyX2ljz4/wAFAAZQByAGYAaQBsACAAUgBHAEIAIABHAGUAbgDpAHIAaQBjAG8AQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAAUgBHAEIALQBQAHIAbwBmAGkAbGZukBoAIABSAEcAQgAgY8+P8GX/h072AEcAZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIAZQBzAGsAcgBpAHYAZQBsAHMAZQBBAGwAZwBlAG0AZQBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBlAGzHfLwYACAAUgBHAEIAINUEuFzTDMd8AFAAcgBvAGYAaQBsAG8AIABSAEcAQgAgAEcAZQBuAGUAcgBpAGMAbwBHAGUAbgBlAHIAaQBjACAAUgBHAEIAIABQAHIAbwBmAGkAbABlBB4EMQRJBDgEOQAgBD8EQAQ+BEQEOAQ7BEwAIABSAEcAQgBVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBm/wBpAGwAIABSAEcAQgAAZGVzYwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAAPNSAAEAAAABFs9YWVogAAAAAAAAdE0AAD3uAAAD0FhZWiAAAAAAAAAoGgAAFZ8AALg2Y3VydgAAAAAAAAABAc0AAHRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBwbGUgSW5jLkMsIGFsbCByaWdodHMgcmVzZXJ2ZWQuAHNmMzIAAAAAAAEMQgAABd7///MmAAAHkgAA/ZH///ui///9owAAA9wAAMBsACwAAAAACgAKAAAEJZAMIcakQZjNtyhFxwEIIRofAookUnapu26t+6KFLYe1TgQ5VwQAOw%3D%3D);
+}
+
+.sort-asc {
+    background:no-repeat left center url(data:image/gif;base64,R0lGODlhCgAKALMAAHFxcYKCgp2dnaampq+vr83NzeHh4f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAAAgAIf/8SUNDUkdCRzEwMTIAAAUwYXBwbAIgAABtbnRyUkdCIFhZWiAH2QACABkACwAaAAthY3NwQVBQTAAAAABhcHBsAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkc2NtAAABCAAAAvJkZXNjAAAD/AAAAG9nWFlaAAAEbAAAABR3dHB0AAAEgAAAABRyWFlaAAAElAAAABRiWFlaAAAEqAAAABRyVFJDAAAEvAAAAA5jcHJ0AAAEzAAAADhjaGFkAAAFBAAAACxn/1RSQwAABLwAAAAOYlRSQwAABLwAAAAObWx1YwAAAAAAAAARAAAADGVuVVMAAAAmAAACfmVzRVMAAAAmAAABgmRhREsAAAAuAAAB6mRlREUAAAAsAAABqGZpRkkAAAAoAAAA3GZyRlUAAAAoAAABKml0SVQAAAAoAAACVm5sTkwAAAAoAAACGG5iTk8AAAAmAAABBHB0QlIAAAAmAAABgnN2U0UAAAAmAAABBGphSlAAAAAaAAABUmtvS1IAAAAWAAACQHpoVFcAAAAWAAABbHpoQ04AAAAWAAAB1HJ1UlUAAAAiAAACpHBsUEwAAAAsAAACxgBZAGwAZQBpAG4AZf8AbgAgAFIARwBCAC0AcAByAG8AZgBpAGkAbABpAEcAZQBuAGUAcgBpAHMAawAgAFIARwBCAC0AcAByAG8AZgBpAGwAUAByAG8AZgBpAGwAIABHAOkAbgDpAHIAaQBxAHUAZQAgAFIAVgBCTgCCLAAgAFIARwBCACAw1zDtMNUwoTCkMOuQGnUoACAAUgBHAEIAIIJyX2ljz4/wAFAAZQByAGYAaQBsACAAUgBHAEIAIABHAGUAbgDpAHIAaQBjAG8AQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAAUgBHAEIALQBQAHIAbwBmAGkAbGZukBoAIABSAEcAQgAgY8+P8GX/h072AEcAZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIAZQBzAGsAcgBpAHYAZQBsAHMAZQBBAGwAZwBlAG0AZQBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBlAGzHfLwYACAAUgBHAEIAINUEuFzTDMd8AFAAcgBvAGYAaQBsAG8AIABSAEcAQgAgAEcAZQBuAGUAcgBpAGMAbwBHAGUAbgBlAHIAaQBjACAAUgBHAEIAIABQAHIAbwBmAGkAbABlBB4EMQRJBDgEOQAgBD8EQAQ+BEQEOAQ7BEwAIABSAEcAQgBVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBm/wBpAGwAIABSAEcAQgAAZGVzYwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAAPNSAAEAAAABFs9YWVogAAAAAAAAdE0AAD3uAAAD0FhZWiAAAAAAAAAoGgAAFZ8AALg2Y3VydgAAAAAAAAABAc0AAHRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBwbGUgSW5jLkMsIGFsbCByaWdodHMgcmVzZXJ2ZWQuAHNmMzIAAAAAAAEMQgAABd7///MmAAAHkgAA/ZH///ui///9owAAA9wAAMBsACwAAAAACgAKAAAEJRBJREKZsxQDsCSGIVzZFnYTGIqktp7fG46uzAn2TAyCMPC9QAQAOw%3D%3D);
+}
+
+.sortable-header {
+    padding-right: 3px;
+    padding-left: 13px;
+    margin-left: 4px;
+}
diff --git a/gm/rebaseline_server/static/view.html b/gm/rebaseline_server/static/view.html
index fda767c..f6ebf5a 100644
--- a/gm/rebaseline_server/static/view.html
+++ b/gm/rebaseline_server/static/view.html
@@ -4,9 +4,11 @@
 
 <head>
   <title ng-bind="windowTitle"></title>
-  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
+  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
+  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.js"></script>
   <script src="constants.js"></script>
   <script src="loader.js"></script>
+  <script src="utils.js"></script>
   <link rel="stylesheet" href="view.css">
 </head>
 
@@ -18,12 +20,20 @@
     </a>
   </h2>
 
-  <em ng-show="!extraColumnHeaders"><!-- show until data is loaded -->
+  <em ng-show="!readyToDisplay">
     Loading results from <a href="{{resultsToLoad}}">{{resultsToLoad}}</a> ...
     {{loadingMessage}}
   </em>
 
-  <div ng-show="extraColumnHeaders"><!-- everything: hide until data is loaded -->
+  <div ng-show="readyToDisplay">
+
+    <div class="warning-div"
+         ng-show="urlSchemaVersionLoaded != constants.URL_VALUE__SCHEMA_VERSION__CURRENT">
+      WARNING!  The URL you loaded used schema version {{urlSchemaVersionLoaded}}, rather than
+      the most recent version {{constants.URL_VALUE__SCHEMA_VERSION__CURRENT}}.  It has been
+      converted to the most recent version on a best-effort basis; you may wish to double-check
+      which records are displayed.
+    </div>
 
     <div class="warning-div"
          ng-show="header[constants.KEY__HEADER__IS_EDITABLE] && header[constants.KEY__HEADER__IS_EXPORTED]">
@@ -66,58 +76,53 @@
       </th>
     </tr>
     <tr valign="top">
-      <td>
-        resultType<br>
-        <label ng-repeat="valueAndCount in extraColumnHeaders[constants.KEY__EXTRACOLUMNS__RESULT_TYPE][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]">
-          <input type="checkbox"
-                 name="resultTypes"
-                 value="{{valueAndCount[0]}}"
-                 ng-checked="!isValueInSet(valueAndCount[0], hiddenResultTypes)"
-                 ng-click="toggleValueInSet(valueAndCount[0], hiddenResultTypes); setUpdatesPending(true)">
-          {{valueAndCount[0]}} ({{valueAndCount[1]}})<br>
-        </label>
-        <button ng-click="hiddenResultTypes = {}; updateResults()">
-          all
-        </button>
-        <button ng-click="hiddenResultTypes = {}; toggleValuesInSet(allResultTypes, hiddenResultTypes); updateResults()">
-          none
-        </button>
-        <button ng-click="toggleValuesInSet(allResultTypes, hiddenResultTypes); updateResults()">
-          toggle
-        </button>
+
+      <!-- filters -->
+      <td ng-repeat="columnName in orderedColumnNames">
+
+        <!-- Only display filterable columns here... -->
+        <div ng-if="extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE]">
+          {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}}<br>
+
+          <!-- If we filter this column using free-form text match... -->
+          <div ng-if="extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]">
+            <input type="text"
+                   ng-model="columnStringMatch[columnName]"
+                   ng-change="setUpdatesPending(true)"/>
+            <br>
+            <button ng-click="setColumnStringMatch(columnName, '')"
+                    ng-disabled="('' == columnStringMatch[columnName])">
+              clear (show all)
+            </button>
+          </div>
+
+          <!-- If we filter this column using checkboxes... -->
+          <div ng-if="!extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__USE_FREEFORM_FILTER]">
+            <label ng-repeat="valueAndCount in extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]">
+              <input type="checkbox"
+                     name="resultTypes"
+                     value="{{valueAndCount[0]}}"
+                     ng-checked="isValueInSet(valueAndCount[0], showingColumnValues[columnName])"
+                     ng-click="toggleValueInSet(valueAndCount[0], showingColumnValues[columnName]); setUpdatesPending(true)">
+              {{valueAndCount[0]}} ({{valueAndCount[1]}})<br>
+            </label>
+            <button ng-click="showingColumnValues[columnName] = {}; toggleValuesInSet(allColumnValues[columnName], showingColumnValues[columnName]); updateResults()"
+                    ng-disabled="!readyToDisplay || allColumnValues[columnName].length == setSize(showingColumnValues[columnName])">
+              all
+            </button>
+            <button ng-click="showingColumnValues[columnName] = {}; updateResults()"
+                    ng-disabled="!readyToDisplay || 0 == setSize(showingColumnValues[columnName])">
+              none
+            </button>
+            <button ng-click="toggleValuesInSet(allColumnValues[columnName], showingColumnValues[columnName]); updateResults()">
+              toggle
+            </button>
+          </div>
+
+        </div>
       </td>
-      <td ng-repeat="category in [constants.KEY__EXTRACOLUMNS__BUILDER, constants.KEY__EXTRACOLUMNS__TEST]">
-        {{category}}
-        <br>
-        <input type="text"
-               ng-model="categoryValueMatch[category]"
-               ng-change="setUpdatesPending(true)"/>
-        <br>
-        <button ng-click="setCategoryValueMatch(category, '')"
-                ng-disabled="('' == categoryValueMatch[category])">
-          clear (show all)
-        </button>
-      </td>
-      <td>
-        config<br>
-        <label ng-repeat="valueAndCount in extraColumnHeaders[constants.KEY__EXTRACOLUMNS__CONFIG][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]">
-          <input type="checkbox"
-                 name="configs"
-                 value="{{valueAndCount[0]}}"
-                 ng-checked="!isValueInSet(valueAndCount[0], hiddenConfigs)"
-                 ng-click="toggleValueInSet(valueAndCount[0], hiddenConfigs); setUpdatesPending(true)">
-          {{valueAndCount[0]}} ({{valueAndCount[1]}})<br>
-        </label>
-        <button ng-click="hiddenConfigs = {}; updateResults()">
-          all
-        </button>
-        <button ng-click="hiddenConfigs = {}; toggleValuesInSet(allConfigs, hiddenConfigs); updateResults()">
-          none
-        </button>
-        <button ng-click="toggleValuesInSet(allConfigs, hiddenConfigs); updateResults()">
-          toggle
-        </button>
-      </td>
+
+      <!-- settings -->
       <td><table>
         <tr><td>
           <input type="checkbox" ng-model="showThumbnailsPending"
@@ -192,98 +197,96 @@
 
       <p>
 
+    <div class="results-header"> <!-- results header -->
+          <div class="results-header-actions">
+            all tests shown:
+            <button ng-click="selectAllImagePairs()">
+              select
+            </button>
+            <button ng-click="clearAllImagePairs()">
+              clear
+            </button>
+            <button ng-click="toggleAllImagePairs()">
+              toggle
+            </button>
+          <div ng-repeat="otherTab in tabs">
+            <button ng-click="moveSelectedImagePairsToTab(otherTab)"
+                    ng-disabled="selectedImagePairs.length == 0"
+                    ng-show="otherTab != viewingTab">
+              move {{selectedImagePairs.length}} selected tests to {{otherTab}} tab
+            </button>
+          </div>
+        </div>
+        <div class="results-header-stats">
+          Found {{filteredImagePairs.length}} matches;
+          <span ng-show="filteredImagePairs.length > limitedImagePairs.length">
+            displaying the first {{limitedImagePairs.length}}.
+          </span>
+          <span ng-show="filteredImagePairs.length <= limitedImagePairs.length">
+            displaying them all.
+          </span>
+          <span ng-show="renderEndTime > renderStartTime">
+            Rendered in {{(renderEndTime - renderStartTime).toFixed(0)}} ms.
+          </span>
+          <br>
+          (click on the column header radio buttons to re-sort by that column)
+        </div>
+    </div> <!-- results header -->
+
     <table border="0"><tr><td> <!-- table holding results header + results table -->
-      <table border="0" width="100%"> <!-- results header -->
-        <tr>
-          <td>
-            Found {{filteredImagePairs.length}} matches;
-            <span ng-show="filteredImagePairs.length > limitedImagePairs.length">
-              displaying the first {{limitedImagePairs.length}}.
-            </span>
-            <span ng-show="filteredImagePairs.length <= limitedImagePairs.length">
-              displaying them all.
-            </span>
-            <span ng-show="renderEndTime > renderStartTime">
-              Rendered in {{(renderEndTime - renderStartTime).toFixed(0)}} ms.
-            </span>
-            <br>
-            (click on the column header radio buttons to re-sort by that column)
-          </td>
-          <td align="right">
-            <div>
-              all tests shown:
-              <button ng-click="selectAllImagePairs()">
-                select
-              </button>
-              <button ng-click="clearAllImagePairs()">
-                clear
-              </button>
-              <button ng-click="toggleAllImagePairs()">
-                toggle
-              </button>
-            </div>
-            <div ng-repeat="otherTab in tabs">
-              <button ng-click="moveSelectedImagePairsToTab(otherTab)"
-                      ng-disabled="selectedImagePairs.length == 0"
-                      ng-show="otherTab != viewingTab">
-                move {{selectedImagePairs.length}} selected tests to {{otherTab}} tab
-              </button>
-            </div>
-          </td>
-        </tr>
-      </table> <!-- results header -->
       </td></tr><tr><td>
-      <table border="1" ng-app="diff_viewer"> <!-- results -->
+      <table border="1"> <!-- results -->
         <tr>
           <!-- Most column headers are displayed in a common fashion... -->
-          <th ng-repeat="categoryName in [constants.KEY__EXTRACOLUMNS__RESULT_TYPE, constants.KEY__EXTRACOLUMNS__BUILDER, constants.KEY__EXTRACOLUMNS__TEST, constants.KEY__EXTRACOLUMNS__CONFIG]">
-            <input type="radio"
-                   name="sortColumnRadio"
-                   value="{{categoryName}}"
-                   ng-checked="(sortColumnKey == categoryName)"
-                   ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXTRACOLUMNS, categoryName)">
-            {{categoryName}}
+          <th ng-repeat="columnName in orderedColumnNames">
+              <a ng-class="'sort-' + sortedByColumnsCls(columnName)"
+                 ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXTRACOLUMNS, columnName)"
+                 href=""
+                 class="sortable-header">
+               {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}}
+             </a>
           </th>
+
           <!-- ... but there are a few columns where we display things differently. -->
           <th>
-            <input type="radio"
-                   name="sortColumnRadio"
-                   value="bugs"
-                   ng-checked="(sortColumnKey == constants.KEY__EXPECTATIONS__BUGS)"
-                   ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXPECTATIONS, constants.KEY__EXPECTATIONS__BUGS)">
-            bugs
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__EXPECTATIONS__BUGS)"
+               ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXPECTATIONS, constants.KEY__EXPECTATIONS__BUGS)"
+               href=""
+               class="sortable-header">
+                  bugs
+            </a>
           </th>
           <th width="{{imageSize}}">
-            <input type="radio"
-                   name="sortColumnRadio"
-                   value="imageA"
-                   ng-checked="(sortColumnKey == constants.KEY__IMAGEPAIRS__IMAGE_A_URL)"
-                   ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_A_URL)">
-            {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}}
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_A_URL)"
+               ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_A_URL)"
+               href=""
+               class="sortable-header">
+                   {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}}
+            </a>
           </th>
           <th width="{{imageSize}}">
-            <input type="radio"
-                   name="sortColumnRadio"
-                   value="imageB"
-                   ng-checked="(sortColumnKey == constants.KEY__IMAGEPAIRS__IMAGE_B_URL)"
-                   ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_B_URL)">
-            {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}}
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_B_URL)"
+               ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_B_URL)"
+               href=""
+               class="sortable-header">
+                  {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}}
+            </a>
           </th>
           <th width="{{imageSize}}">
-            <input type="radio"
-                   name="sortColumnRadio"
-                   value="percentDifferingPixels"
-                   ng-checked="(sortColumnKey == constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)"
-                   ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)">
-            differing pixels in white
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)"
+               ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)"
+               href=""
+               class="sortable-header">
+                  differing pixels in white
+            </a>
           </th>
           <th width="{{imageSize}}">
-            <input type="radio"
-                   name="sortColumnRadio"
-                   value="perceptualDiff"
-                   ng-checked="(sortColumnKey == constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)"
-                   ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)">
-            perceptual difference
+            <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)"
+               ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)"
+               href=""
+               class="sortable-header">
+               perceptual difference
+            </a>
             <br>
             <input type="range" ng-model="pixelDiffBgColorBrightness"
                    ng-init="pixelDiffBgColorBrightness=64; pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)"
@@ -299,61 +302,28 @@
         <tr ng-repeat="imagePair in limitedImagePairs" valign="top"
             ng-class-odd="'results-odd'" ng-class-even="'results-even'"
             results-updated-callback-directive>
-          <td>
-            {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__RESULT_TYPE]}}
+
+          <td ng-repeat="columnName in orderedColumnNames">
+            {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][columnName]}}
             <br>
             <button class="show-only-button"
                     ng-show="viewingTab == defaultTab"
-                    ng-click="showOnlyResultType(imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__RESULT_TYPE])"
-                    title="show only results of type {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__RESULT_TYPE]}}">
+                    ng-disabled="1 == setSize(showingColumnValues[columnName])"
+                    ng-click="showOnlyColumnValue(columnName, imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][columnName])"
+                    title="show only results of {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}} {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][columnName]}}">
               show only
             </button>
             <br>
             <button class="show-all-button"
                     ng-show="viewingTab == defaultTab"
-                    ng-disabled="0 == setSize(hiddenResultTypes)"
-                    ng-click="showAllResultTypes()"
-                    title="show results of all types">
+                    ng-disabled="allColumnValues[columnName].length == setSize(showingColumnValues[columnName])"
+                    ng-click="showAllColumnValues(columnName)"
+                    title="show results of all {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}}s">
               show all
             </button>
           </td>
-          <td ng-repeat="categoryName in [constants.KEY__EXTRACOLUMNS__BUILDER, constants.KEY__EXTRACOLUMNS__TEST]">
-            {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][categoryName]}}
-            <br>
-            <button class="show-only-button"
-                    ng-show="viewingTab == defaultTab"
-                    ng-disabled="imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][categoryName] == categoryValueMatch[categoryName]"
-                    ng-click="setCategoryValueMatch(categoryName, imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][categoryName])"
-                    title="show only results of {{categoryName}} {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][categoryName]}}">
-              show only
-            </button>
-            <br>
-            <button class="show-all-button"
-                    ng-show="viewingTab == defaultTab"
-                    ng-disabled="'' == categoryValueMatch[categoryName]"
-                    ng-click="setCategoryValueMatch(categoryName, '')"
-                    title="show results of all {{categoryName}}s">
-              show all
-            </button>
-          </td>
-          <td>
-            {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__CONFIG]}}
-            <br>
-            <button class="show-only-button"
-                    ng-show="viewingTab == defaultTab"
-                    ng-click="showOnlyConfig(imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__CONFIG])"
-                    title="show only results of config {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__CONFIG]}}">
-              show only
-            </button>
-            <br>
-            <button class="show-all-button"
-                    ng-show="viewingTab == defaultTab"
-                    ng-disabled="0 == setSize(hiddenConfigs)"
-                    ng-click="showAllConfigs()"
-                    title="show results of all configs">
-              show all
-            </button>
-          </td>
+
+          <!-- bugs -->
           <td>
             <a ng-repeat="bug in imagePair[constants.KEY__IMAGEPAIRS__EXPECTATIONS][constants.KEY__EXPECTATIONS__BUGS]"
                href="https://code.google.com/p/skia/issues/detail?id={{bug}}"
@@ -395,10 +365,10 @@
             <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
                  title="{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS] | number:0}} of {{(100 * imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS] / imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS]) | number:0}} pixels ({{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS].toFixed(4)}}%) differ from expectation.">
 
-              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{getImageDiffRelativeUrl(imagePair)}}" target="_blank">View Image</a><br/>
+              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__WHITE_DIFF_URL]}}" target="_blank">View Image</a><br/>
               <img ng-if="showThumbnails"
                    width="{{imageSize}}"
-                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{getImageDiffRelativeUrl(imagePair)}}" />
+                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__WHITE_DIFF_URL]}}" />
               <br/>
               {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS].toFixed(4)}}%
               ({{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS]}})
@@ -414,11 +384,11 @@
             <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
                  title="Perceptual difference measure is {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF].toFixed(4)}}%.  Maximum difference per channel: R={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][0]}}, G={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][1]}}, B={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][2]}}">
 
-              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{getImageDiffRelativeUrl(imagePair)}}" target="_blank">View Image</a><br/>
+              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__DIFF_URL]}}" target="_blank">View Image</a><br/>
               <img ng-if="showThumbnails"
                    ng-style="{backgroundColor: pixelDiffBgColor}"
                    width="{{imageSize}}"
-                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{getImageDiffRelativeUrl(imagePair)}}" />
+                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__DIFF_URL]}}" />
               <br/>
               {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF].toFixed(4)}}%
               {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL]}}
@@ -441,7 +411,7 @@
     </td></tr></table> <!-- table holding results header + imagePairs table -->
 
   </div><!-- main display area of selected tab -->
-  </div><!-- everything: hide until data is loaded -->
+  </div><!-- everything: hide until readyToDisplay -->
 
 </body>
 </html>
diff --git a/gm/rebaseline_server/test_all.py b/gm/rebaseline_server/test_all.py
index 299d134..282ec85 100755
--- a/gm/rebaseline_server/test_all.py
+++ b/gm/rebaseline_server/test_all.py
@@ -7,9 +7,6 @@
 found in the LICENSE file.
 
 Run all unittests within this directory tree, recursing into subdirectories.
-
-TODO(epoger): Launch this automatically on the housekeeper bot, but first make
-sure it works properly after having been checked out (from both git and svn)
 """
 
 import os
diff --git a/gm/rebaseline_server/testdata/inputs/skp-summaries/actuals/summary.json b/gm/rebaseline_server/testdata/inputs/skp-summaries/actuals/summary.json
new file mode 100644
index 0000000..67e8409
--- /dev/null
+++ b/gm/rebaseline_server/testdata/inputs/skp-summaries/actuals/summary.json
@@ -0,0 +1,32 @@
+{
+   "actual-results" : {
+      "changed.skp" : {
+         "whole-image" : {
+            "checksumAlgorithm" : "bitmap-64bitMD5",
+            "checksumValue" : 13623922271964399662,
+            "comparisonResult" : "no-comparison",
+            "filepath" : "changed_skp/bitmap-64bitMD5_13623922271964399662.png"
+         }
+      },
+      "only-in-after.skp" : {
+         "whole-image" : {
+            "checksumAlgorithm" : "bitmap-64bitMD5",
+            "checksumValue" : 2320185040577047131,
+            "comparisonResult" : "no-comparison",
+            "filepath" : "only-in-after_skp/bitmap-64bitMD5_2320185040577047131.png"
+         }
+      },
+      "unchanged.skp" : {
+         "whole-image" : {
+            "checksumAlgorithm" : "bitmap-64bitMD5",
+            "checksumValue" : 3322248763049618493,
+            "comparisonResult" : "no-comparison",
+            "filepath" : "unchanged_skp/bitmap-64bitMD5_3322248763049618493.png"
+         }
+      }
+   },
+   "header" : {
+      "revision" : 1,
+      "type" : "ChecksummedImages"
+   }
+}
diff --git a/gm/rebaseline_server/testdata/inputs/skp-summaries/expectations/summary.json b/gm/rebaseline_server/testdata/inputs/skp-summaries/expectations/summary.json
new file mode 100644
index 0000000..9d64d75
--- /dev/null
+++ b/gm/rebaseline_server/testdata/inputs/skp-summaries/expectations/summary.json
@@ -0,0 +1,32 @@
+{
+   "expected-results" : {
+      "changed.skp" : {
+         "whole-image" : {
+            "checksumAlgorithm" : "bitmap-64bitMD5",
+            "checksumValue" : 3101044995537104462,
+            "comparisonResult" : "no-comparison",
+            "filepath" : "changed_skp/bitmap-64bitMD5_3101044995537104462.png"
+         }
+      },
+      "only-in-before.skp" : {
+         "whole-image" : {
+            "checksumAlgorithm" : "bitmap-64bitMD5",
+            "checksumValue" : 2320185040577047131,
+            "comparisonResult" : "no-comparison",
+            "filepath" : "only-in-before_skp/bitmap-64bitMD5_2320185040577047131.png"
+         }
+      },
+      "unchanged.skp" : {
+         "whole-image" : {
+            "checksumAlgorithm" : "bitmap-64bitMD5",
+            "checksumValue" : 3322248763049618493,
+            "comparisonResult" : "no-comparison",
+            "filepath" : "unchanged_skp/bitmap-64bitMD5_3322248763049618493.png"
+         }
+      }
+   },
+   "header" : {
+      "revision" : 1,
+      "type" : "ChecksummedImages"
+   }
+}
diff --git a/gm/rebaseline_server/testdata/outputs/expected/compare_configs_test.CompareConfigsTest.test_gm/gm.json b/gm/rebaseline_server/testdata/outputs/expected/compare_configs_test.CompareConfigsTest.test_gm/gm.json
index 49a73f7..048abef 100644
--- a/gm/rebaseline_server/testdata/outputs/expected/compare_configs_test.CompareConfigsTest.test_gm/gm.json
+++ b/gm/rebaseline_server/testdata/outputs/expected/compare_configs_test.CompareConfigsTest.test_gm/gm.json
@@ -4,6 +4,7 @@
       "headerText": "builder", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": false, 
       "valuesAndCounts": [
         [
           "Test-Android-GalaxyNexus-SGX540-Arm7-Release", 
@@ -23,6 +24,7 @@
       "headerText": "config", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": false, 
       "valuesAndCounts": [
         [
           "TODO", 
@@ -34,6 +36,7 @@
       "headerText": "resultType", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": false, 
       "valuesAndCounts": [
         [
           "failed", 
@@ -53,6 +56,7 @@
       "headerText": "test", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": false, 
       "valuesAndCounts": [
         [
           "3x3bitmaprect", 
@@ -93,11 +97,17 @@
       ]
     }
   }, 
+  "extraColumnOrder": [
+    "builder", 
+    "config", 
+    "resultType", 
+    "test"
+  ], 
   "header": {
-    "dataHash": "5496105477154010366", 
+    "dataHash": "-8474691963189557240", 
     "isEditable": false, 
     "isExported": true, 
-    "schemaVersion": 3, 
+    "schemaVersion": 5, 
     "timeNextUpdateAvailable": null, 
     "timeUpdated": 12345678, 
     "type": "all"
@@ -182,6 +192,7 @@
     }, 
     {
       "differenceData": {
+        "diffUrl": "bitmap-64bitMD5_displacement_11401048196735046263_png_png-vs-bitmap-64bitMD5_displacement_5698561127291561694_png_png.png", 
         "maxDiffPerChannel": [
           136, 
           68, 
@@ -189,7 +200,8 @@
         ], 
         "numDifferingPixels": 6081, 
         "percentDifferingPixels": 2.4324, 
-        "perceptualDifference": 1.917199999999994
+        "perceptualDifference": 1.9172010000000057, 
+        "whiteDiffUrl": "bitmap-64bitMD5_displacement_11401048196735046263_png_png-vs-bitmap-64bitMD5_displacement_5698561127291561694_png_png.png"
       }, 
       "extraColumns": {
         "builder": "Test-Builder-We-Have-No-Expectations-File-For", 
@@ -203,6 +215,7 @@
     }, 
     {
       "differenceData": {
+        "diffUrl": "bitmap-64bitMD5_bigblurs_17309852422285247848_png_png-vs-bitmap-64bitMD5_bigblurs_1822195599289208664_png_png.png", 
         "maxDiffPerChannel": [
           255, 
           221, 
@@ -210,7 +223,8 @@
         ], 
         "numDifferingPixels": 50097, 
         "percentDifferingPixels": 30.5767822265625, 
-        "perceptualDifference": 3.3917
+        "perceptualDifference": 3.391725000000008, 
+        "whiteDiffUrl": "bitmap-64bitMD5_bigblurs_17309852422285247848_png_png-vs-bitmap-64bitMD5_bigblurs_1822195599289208664_png_png.png"
       }, 
       "extraColumns": {
         "builder": "Test-Builder-We-Have-No-Expectations-File-For", 
@@ -246,6 +260,7 @@
     }, 
     {
       "differenceData": {
+        "diffUrl": "bitmap-64bitMD5_displacement_11401048196735046263_png_png-vs-bitmap-64bitMD5_displacement_5698561127291561694_png_png.png", 
         "maxDiffPerChannel": [
           136, 
           68, 
@@ -253,7 +268,8 @@
         ], 
         "numDifferingPixels": 6081, 
         "percentDifferingPixels": 2.4324, 
-        "perceptualDifference": 1.917199999999994
+        "perceptualDifference": 1.9172010000000057, 
+        "whiteDiffUrl": "bitmap-64bitMD5_displacement_11401048196735046263_png_png-vs-bitmap-64bitMD5_displacement_5698561127291561694_png_png.png"
       }, 
       "extraColumns": {
         "builder": "Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug", 
@@ -267,6 +283,7 @@
     }, 
     {
       "differenceData": {
+        "diffUrl": "bitmap-64bitMD5_bigblurs_17309852422285247848_png_png-vs-bitmap-64bitMD5_bigblurs_1822195599289208664_png_png.png", 
         "maxDiffPerChannel": [
           255, 
           221, 
@@ -274,7 +291,8 @@
         ], 
         "numDifferingPixels": 50097, 
         "percentDifferingPixels": 30.5767822265625, 
-        "perceptualDifference": 3.3917
+        "perceptualDifference": 3.391725000000008, 
+        "whiteDiffUrl": "bitmap-64bitMD5_bigblurs_17309852422285247848_png_png-vs-bitmap-64bitMD5_bigblurs_1822195599289208664_png_png.png"
       }, 
       "extraColumns": {
         "builder": "Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug", 
diff --git a/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd/compare_rendered_pictures.json b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd/compare_rendered_pictures.json
index 464b1d4..1ce3718 100644
--- a/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd/compare_rendered_pictures.json
+++ b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd/compare_rendered_pictures.json
@@ -1,23 +1,49 @@
 {
   "extraColumnHeaders": {
-    "builder": {
-      "headerText": "builder", 
+    "builderA": {
+      "headerText": "builderA", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": false, 
       "valuesAndCounts": [
         [
-          "TODO", 
+          null, 
           4
         ]
       ]
     }, 
-    "config": {
-      "headerText": "config", 
+    "builderB": {
+      "headerText": "builderB", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": false, 
       "valuesAndCounts": [
         [
-          "whole-image", 
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "renderModeA": {
+      "headerText": "renderModeA", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "renderModeB": {
+      "headerText": "renderModeB", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
           4
         ]
       ]
@@ -26,6 +52,7 @@
       "headerText": "resultType", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": false, 
       "valuesAndCounts": [
         [
           "failed", 
@@ -41,10 +68,11 @@
         ]
       ]
     }, 
-    "test": {
-      "headerText": "test", 
+    "sourceSkpFile": {
+      "headerText": "sourceSkpFile", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": true, 
       "valuesAndCounts": [
         [
           "changed.skp", 
@@ -63,13 +91,61 @@
           1
         ]
       ]
+    }, 
+    "tiledOrWhole": {
+      "headerText": "tiledOrWhole", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          "whole", 
+          4
+        ]
+      ]
+    }, 
+    "tilenum": {
+      "headerText": "tilenum", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": true, 
+      "valuesAndCounts": [
+        [
+          "N/A", 
+          4
+        ]
+      ]
     }
   }, 
+  "extraColumnOrder": [
+    "resultType", 
+    "sourceSkpFile", 
+    "tiledOrWhole", 
+    "tilenum", 
+    "builderA", 
+    "renderModeA", 
+    "builderB", 
+    "renderModeB"
+  ], 
   "header": {
-    "dataHash": "-595743736412687673", 
+    "dataHash": "-9145196899696949575", 
     "isEditable": false, 
     "isExported": true, 
-    "schemaVersion": 3, 
+    "schemaVersion": 5, 
+    "setA": {
+      "dir": [
+        "before-patch-fake-dir"
+      ], 
+      "repoRevision": null, 
+      "section": "actual-results"
+    }, 
+    "setB": {
+      "dir": [
+        "after-patch-fake-dir"
+      ], 
+      "repoRevision": null, 
+      "section": "actual-results"
+    }, 
     "timeNextUpdateAvailable": null, 
     "timeUpdated": 12345678, 
     "type": "all"
@@ -77,47 +153,67 @@
   "imagePairs": [
     {
       "extraColumns": {
-        "builder": "TODO", 
-        "config": "whole-image", 
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
         "resultType": "failed", 
-        "test": "changed.skp"
+        "sourceSkpFile": "changed.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
       }, 
-      "imageAUrl": "changed_skp/bitmap-64bitMD5_3101044995537104462.png", 
-      "imageBUrl": "changed_skp/bitmap-64bitMD5_13623922271964399662.png", 
-      "isDifferent": true
+      "imageAUrl": "changed_skp/bitmap-64bitMD5_17527938180154630042.png", 
+      "imageBUrl": "changed_skp/bitmap-64bitMD5_2314401992566164894.png", 
+      "isDifferent": true, 
+      "sourceJsonFile": "./summary.json"
     }, 
     {
       "extraColumns": {
-        "builder": "TODO", 
-        "config": "whole-image", 
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
         "resultType": "no-comparison", 
-        "test": "only-in-after.skp"
+        "sourceSkpFile": "only-in-after.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
       }, 
       "imageAUrl": null, 
-      "imageBUrl": "only-in-after_skp/bitmap-64bitMD5_2320185040577047131.png", 
-      "isDifferent": true
+      "imageBUrl": "only-in-after_skp/bitmap-64bitMD5_6558642089737589931.png", 
+      "isDifferent": true, 
+      "sourceJsonFile": "./summary.json"
     }, 
     {
       "extraColumns": {
-        "builder": "TODO", 
-        "config": "whole-image", 
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
         "resultType": "no-comparison", 
-        "test": "only-in-before.skp"
+        "sourceSkpFile": "only-in-before.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
       }, 
-      "imageAUrl": "only-in-before_skp/bitmap-64bitMD5_2320185040577047131.png", 
+      "imageAUrl": "only-in-before_skp/bitmap-64bitMD5_6558642089737589931.png", 
       "imageBUrl": null, 
-      "isDifferent": true
+      "isDifferent": true, 
+      "sourceJsonFile": "./summary.json"
     }, 
     {
       "extraColumns": {
-        "builder": "TODO", 
-        "config": "whole-image", 
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
         "resultType": "succeeded", 
-        "test": "unchanged.skp"
+        "sourceSkpFile": "unchanged.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
       }, 
-      "imageAUrl": "unchanged_skp/bitmap-64bitMD5_3322248763049618493.png", 
-      "imageBUrl": "unchanged_skp/bitmap-64bitMD5_3322248763049618493.png", 
-      "isDifferent": false
+      "imageAUrl": "unchanged_skp/bitmap-64bitMD5_1094324242976325446.png", 
+      "imageBUrl": "unchanged_skp/bitmap-64bitMD5_1094324242976325446.png", 
+      "isDifferent": false, 
+      "sourceJsonFile": "./summary.json"
     }
   ], 
   "imageSets": {
@@ -126,12 +222,12 @@
       "description": "color difference per channel"
     }, 
     "imageA": {
-      "baseUrl": "http://chromium-skia-gm.commondatastorage.googleapis.com/render_pictures/images", 
-      "description": "before_patch"
+      "baseUrl": "http://storage.cloud.google.com/fakebucket/fake/path", 
+      "description": "setA"
     }, 
     "imageB": {
-      "baseUrl": "http://chromium-skia-gm.commondatastorage.googleapis.com/render_pictures/images", 
-      "description": "after_patch"
+      "baseUrl": "http://storage.cloud.google.com/fakebucket/fake/path", 
+      "description": "setB"
     }, 
     "whiteDiffs": {
       "baseUrl": "/static/generated-images/whitediffs", 
diff --git a/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd_withImageBaseGSUrl/compare_rendered_pictures.json b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd_withImageBaseGSUrl/compare_rendered_pictures.json
new file mode 100644
index 0000000..1026014
--- /dev/null
+++ b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd_withImageBaseGSUrl/compare_rendered_pictures.json
@@ -0,0 +1,237 @@
+{
+  "extraColumnHeaders": {
+    "builderA": {
+      "headerText": "builderA", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "builderB": {
+      "headerText": "builderB", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "renderModeA": {
+      "headerText": "renderModeA", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "renderModeB": {
+      "headerText": "renderModeB", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "resultType": {
+      "headerText": "resultType", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          "failed", 
+          1
+        ], 
+        [
+          "no-comparison", 
+          2
+        ], 
+        [
+          "succeeded", 
+          1
+        ]
+      ]
+    }, 
+    "sourceSkpFile": {
+      "headerText": "sourceSkpFile", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": true, 
+      "valuesAndCounts": [
+        [
+          "changed.skp", 
+          1
+        ], 
+        [
+          "only-in-after.skp", 
+          1
+        ], 
+        [
+          "only-in-before.skp", 
+          1
+        ], 
+        [
+          "unchanged.skp", 
+          1
+        ]
+      ]
+    }, 
+    "tiledOrWhole": {
+      "headerText": "tiledOrWhole", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          "whole", 
+          4
+        ]
+      ]
+    }, 
+    "tilenum": {
+      "headerText": "tilenum", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": true, 
+      "valuesAndCounts": [
+        [
+          "N/A", 
+          4
+        ]
+      ]
+    }
+  }, 
+  "extraColumnOrder": [
+    "resultType", 
+    "sourceSkpFile", 
+    "tiledOrWhole", 
+    "tilenum", 
+    "builderA", 
+    "renderModeA", 
+    "builderB", 
+    "renderModeB"
+  ], 
+  "header": {
+    "dataHash": "-9145196899696949575", 
+    "isEditable": false, 
+    "isExported": true, 
+    "schemaVersion": 5, 
+    "setA": {
+      "dir": [
+        "before-patch-fake-dir"
+      ], 
+      "repoRevision": null, 
+      "section": "actual-results"
+    }, 
+    "setB": {
+      "dir": [
+        "after-patch-fake-dir"
+      ], 
+      "repoRevision": null, 
+      "section": "actual-results"
+    }, 
+    "timeNextUpdateAvailable": null, 
+    "timeUpdated": 12345678, 
+    "type": "all"
+  }, 
+  "imagePairs": [
+    {
+      "extraColumns": {
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
+        "resultType": "failed", 
+        "sourceSkpFile": "changed.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
+      }, 
+      "imageAUrl": "changed_skp/bitmap-64bitMD5_17527938180154630042.png", 
+      "imageBUrl": "changed_skp/bitmap-64bitMD5_2314401992566164894.png", 
+      "isDifferent": true, 
+      "sourceJsonFile": "./summary.json"
+    }, 
+    {
+      "extraColumns": {
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
+        "resultType": "no-comparison", 
+        "sourceSkpFile": "only-in-after.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
+      }, 
+      "imageAUrl": null, 
+      "imageBUrl": "only-in-after_skp/bitmap-64bitMD5_6558642089737589931.png", 
+      "isDifferent": true, 
+      "sourceJsonFile": "./summary.json"
+    }, 
+    {
+      "extraColumns": {
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
+        "resultType": "no-comparison", 
+        "sourceSkpFile": "only-in-before.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
+      }, 
+      "imageAUrl": "only-in-before_skp/bitmap-64bitMD5_6558642089737589931.png", 
+      "imageBUrl": null, 
+      "isDifferent": true, 
+      "sourceJsonFile": "./summary.json"
+    }, 
+    {
+      "extraColumns": {
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
+        "resultType": "succeeded", 
+        "sourceSkpFile": "unchanged.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
+      }, 
+      "imageAUrl": "unchanged_skp/bitmap-64bitMD5_1094324242976325446.png", 
+      "imageBUrl": "unchanged_skp/bitmap-64bitMD5_1094324242976325446.png", 
+      "isDifferent": false, 
+      "sourceJsonFile": "./summary.json"
+    }
+  ], 
+  "imageSets": {
+    "diffs": {
+      "baseUrl": "/static/generated-images/diffs", 
+      "description": "color difference per channel"
+    }, 
+    "imageA": {
+      "baseUrl": "http://storage.cloud.google.com/superman/kent-camera/pictures", 
+      "description": "setA"
+    }, 
+    "imageB": {
+      "baseUrl": "http://storage.cloud.google.com/batman/batarang/pictures", 
+      "description": "setB"
+    }, 
+    "whiteDiffs": {
+      "baseUrl": "/static/generated-images/whitediffs", 
+      "description": "differing pixels in white"
+    }
+  }
+}
\ No newline at end of file
diff --git a/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_repo_url/compare_rendered_pictures.json b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_repo_url/compare_rendered_pictures.json
new file mode 100644
index 0000000..5ee6092
--- /dev/null
+++ b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_repo_url/compare_rendered_pictures.json
@@ -0,0 +1,233 @@
+{
+  "extraColumnHeaders": {
+    "builderA": {
+      "headerText": "builderA", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "builderB": {
+      "headerText": "builderB", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "renderModeA": {
+      "headerText": "renderModeA", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "renderModeB": {
+      "headerText": "renderModeB", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          null, 
+          4
+        ]
+      ]
+    }, 
+    "resultType": {
+      "headerText": "resultType", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          "failed", 
+          1
+        ], 
+        [
+          "no-comparison", 
+          2
+        ], 
+        [
+          "succeeded", 
+          1
+        ]
+      ]
+    }, 
+    "sourceSkpFile": {
+      "headerText": "sourceSkpFile", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": true, 
+      "valuesAndCounts": [
+        [
+          "changed.skp", 
+          1
+        ], 
+        [
+          "only-in-after.skp", 
+          1
+        ], 
+        [
+          "only-in-before.skp", 
+          1
+        ], 
+        [
+          "unchanged.skp", 
+          1
+        ]
+      ]
+    }, 
+    "tiledOrWhole": {
+      "headerText": "tiledOrWhole", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": false, 
+      "valuesAndCounts": [
+        [
+          "whole", 
+          4
+        ]
+      ]
+    }, 
+    "tilenum": {
+      "headerText": "tilenum", 
+      "isFilterable": true, 
+      "isSortable": true, 
+      "useFreeformFilter": true, 
+      "valuesAndCounts": [
+        [
+          "N/A", 
+          4
+        ]
+      ]
+    }
+  }, 
+  "extraColumnOrder": [
+    "resultType", 
+    "sourceSkpFile", 
+    "tiledOrWhole", 
+    "tilenum", 
+    "builderA", 
+    "renderModeA", 
+    "builderB", 
+    "renderModeB"
+  ], 
+  "header": {
+    "dataHash": "-5707186260478709107", 
+    "isEditable": false, 
+    "isExported": true, 
+    "schemaVersion": 5, 
+    "setA": {
+      "dir": "repo:gm/rebaseline_server/testdata/inputs/skp-summaries/expectations", 
+      "repoRevision": "fake-repo-revision", 
+      "section": "expected-results"
+    }, 
+    "setB": {
+      "dir": "repo:gm/rebaseline_server/testdata/inputs/skp-summaries/actuals", 
+      "repoRevision": "fake-repo-revision", 
+      "section": "actual-results"
+    }, 
+    "timeNextUpdateAvailable": null, 
+    "timeUpdated": 12345678, 
+    "type": "all"
+  }, 
+  "imagePairs": [
+    {
+      "extraColumns": {
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
+        "resultType": "failed", 
+        "sourceSkpFile": "changed.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
+      }, 
+      "imageAUrl": "changed_skp/bitmap-64bitMD5_3101044995537104462.png", 
+      "imageBUrl": "changed_skp/bitmap-64bitMD5_13623922271964399662.png", 
+      "isDifferent": true, 
+      "sourceJsonFile": "./summary.json"
+    }, 
+    {
+      "extraColumns": {
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
+        "resultType": "no-comparison", 
+        "sourceSkpFile": "only-in-after.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
+      }, 
+      "imageAUrl": null, 
+      "imageBUrl": "only-in-after_skp/bitmap-64bitMD5_2320185040577047131.png", 
+      "isDifferent": true, 
+      "sourceJsonFile": "./summary.json"
+    }, 
+    {
+      "extraColumns": {
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
+        "resultType": "no-comparison", 
+        "sourceSkpFile": "only-in-before.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
+      }, 
+      "imageAUrl": "only-in-before_skp/bitmap-64bitMD5_2320185040577047131.png", 
+      "imageBUrl": null, 
+      "isDifferent": true, 
+      "sourceJsonFile": "./summary.json"
+    }, 
+    {
+      "extraColumns": {
+        "builderA": null, 
+        "builderB": null, 
+        "renderModeA": null, 
+        "renderModeB": null, 
+        "resultType": "succeeded", 
+        "sourceSkpFile": "unchanged.skp", 
+        "tiledOrWhole": "whole", 
+        "tilenum": "N/A"
+      }, 
+      "imageAUrl": "unchanged_skp/bitmap-64bitMD5_3322248763049618493.png", 
+      "imageBUrl": "unchanged_skp/bitmap-64bitMD5_3322248763049618493.png", 
+      "isDifferent": false, 
+      "sourceJsonFile": "./summary.json"
+    }
+  ], 
+  "imageSets": {
+    "diffs": {
+      "baseUrl": "/static/generated-images/diffs", 
+      "description": "color difference per channel"
+    }, 
+    "imageA": {
+      "baseUrl": "http://storage.cloud.google.com/fakebucket/fake/path", 
+      "description": "expected-results"
+    }, 
+    "imageB": {
+      "baseUrl": "http://storage.cloud.google.com/fakebucket/fake/path", 
+      "description": "actual-results"
+    }, 
+    "whiteDiffs": {
+      "baseUrl": "/static/generated-images/whitediffs", 
+      "description": "differing pixels in white"
+    }
+  }
+}
\ No newline at end of file
diff --git a/gm/rebaseline_server/testdata/outputs/expected/compare_to_expectations_test.CompareToExpectationsTest.test_gm/gm.json b/gm/rebaseline_server/testdata/outputs/expected/compare_to_expectations_test.CompareToExpectationsTest.test_gm/gm.json
index f2f40d5..30d2ab9 100644
--- a/gm/rebaseline_server/testdata/outputs/expected/compare_to_expectations_test.CompareToExpectationsTest.test_gm/gm.json
+++ b/gm/rebaseline_server/testdata/outputs/expected/compare_to_expectations_test.CompareToExpectationsTest.test_gm/gm.json
@@ -4,6 +4,7 @@
       "headerText": "builder", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": true, 
       "valuesAndCounts": [
         [
           "Test-Android-GalaxyNexus-SGX540-Arm7-Release", 
@@ -19,6 +20,7 @@
       "headerText": "config", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": false, 
       "valuesAndCounts": [
         [
           "565", 
@@ -46,6 +48,7 @@
       "headerText": "resultType", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": false, 
       "valuesAndCounts": [
         [
           "failed", 
@@ -69,6 +72,7 @@
       "headerText": "test", 
       "isFilterable": true, 
       "isSortable": true, 
+      "useFreeformFilter": true, 
       "valuesAndCounts": [
         [
           "3x3bitmaprect", 
@@ -109,11 +113,17 @@
       ]
     }
   }, 
+  "extraColumnOrder": [
+    "resultType", 
+    "builder", 
+    "test", 
+    "config"
+  ], 
   "header": {
-    "dataHash": "7849962375815855931", 
+    "dataHash": "6366271140430198826", 
     "isEditable": false, 
     "isExported": true, 
-    "schemaVersion": 3, 
+    "schemaVersion": 5, 
     "timeNextUpdateAvailable": null, 
     "timeUpdated": 12345678, 
     "type": "all"
@@ -121,6 +131,7 @@
   "imagePairs": [
     {
       "differenceData": {
+        "diffUrl": "bitmap-64bitMD5_texdata_2736593828543197285_png_png-vs-bitmap-64bitMD5_texdata_3695033638604474475_png_png.png", 
         "maxDiffPerChannel": [
           128, 
           128, 
@@ -128,7 +139,8 @@
         ], 
         "numDifferingPixels": 120000, 
         "percentDifferingPixels": 75.0, 
-        "perceptualDifference": 50.122499999999995
+        "perceptualDifference": 50.122499, 
+        "whiteDiffUrl": "bitmap-64bitMD5_texdata_2736593828543197285_png_png-vs-bitmap-64bitMD5_texdata_3695033638604474475_png_png.png"
       }, 
       "expectations": {
         "bugs": null, 
@@ -147,6 +159,7 @@
     }, 
     {
       "differenceData": {
+        "diffUrl": "bitmap-64bitMD5_filterbitmap_checkerboard_192_192_9917960313903939620_png_png-vs-bitmap-64bitMD5_filterbitmap_checkerboard_192_192_4719210487426381700_png_png.png", 
         "maxDiffPerChannel": [
           255, 
           255, 
@@ -154,7 +167,8 @@
         ], 
         "numDifferingPixels": 765891, 
         "percentDifferingPixels": 97.38807678222656, 
-        "perceptualDifference": 25.25699999999999
+        "perceptualDifference": 25.256985, 
+        "whiteDiffUrl": "bitmap-64bitMD5_filterbitmap_checkerboard_192_192_9917960313903939620_png_png-vs-bitmap-64bitMD5_filterbitmap_checkerboard_192_192_4719210487426381700_png_png.png"
       }, 
       "expectations": {
         "bugs": [
@@ -175,6 +189,7 @@
     }, 
     {
       "differenceData": {
+        "diffUrl": "bitmap-64bitMD5_filterbitmap_checkerboard_192_192_9917960313903939620_png_png-vs-bitmap-64bitMD5_filterbitmap_checkerboard_192_192_3154864687054945306_png_png.png", 
         "maxDiffPerChannel": [
           255, 
           255, 
@@ -182,7 +197,8 @@
         ], 
         "numDifferingPixels": 422432, 
         "percentDifferingPixels": 53.715006510416664, 
-        "perceptualDifference": 25.120500000000007
+        "perceptualDifference": 25.120543999999995, 
+        "whiteDiffUrl": "bitmap-64bitMD5_filterbitmap_checkerboard_192_192_9917960313903939620_png_png-vs-bitmap-64bitMD5_filterbitmap_checkerboard_192_192_3154864687054945306_png_png.png"
       }, 
       "expectations": {
         "bugs": [
@@ -202,16 +218,6 @@
       "isDifferent": true
     }, 
     {
-      "differenceData": {
-        "maxDiffPerChannel": [
-          222, 
-          223, 
-          222
-        ], 
-        "numDifferingPixels": 53150, 
-        "percentDifferingPixels": 12.035778985507246, 
-        "perceptualDifference": 100
-      }, 
       "expectations": {
         "bugs": [
           1578
@@ -230,16 +236,6 @@
       "isDifferent": true
     }, 
     {
-      "differenceData": {
-        "maxDiffPerChannel": [
-          221, 
-          221, 
-          221
-        ], 
-        "numDifferingPixels": 53773, 
-        "percentDifferingPixels": 12.17685688405797, 
-        "perceptualDifference": 100
-      }, 
       "expectations": {
         "bugs": [
           1578
diff --git a/gm/rebaseline_server/writable_expectations.py b/gm/rebaseline_server/writable_expectations.py
new file mode 100644
index 0000000..09b9cf7
--- /dev/null
+++ b/gm/rebaseline_server/writable_expectations.py
@@ -0,0 +1,183 @@
+#!/usr/bin/python
+
+"""
+Copyright 2014 Google Inc.
+
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+
+Expectations on local disk that we can modify.
+"""
+
+# System-level imports
+import logging
+import os
+import re
+
+# Must fix up PYTHONPATH before importing from within Skia
+import rs_fixpypath  # pylint: disable=W0611
+
+# Imports from within Skia
+from py.utils import git_utils
+import compare_rendered_pictures
+import gm_json
+import imagepair
+import results
+
+FILEPATH_RE = re.compile('.+/' + gm_json.IMAGE_FILENAME_PATTERN)
+
+SKIA_REPO = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), os.pardir, os.pardir, '.git'))
+
+
+class WritableExpectations(git_utils.NewGitCheckout):
+  """Expectations on local disk that we can modify."""
+
+  def __init__(self, set_descriptions):
+    """Creates a sandbox on local disk containing writable expectations.
+
+    You must use the 'with' statement to create this object in such a way that
+    it cleans up after itself:
+
+    with WritableExpectations(*args) as writable_expectations:
+      # make modifications
+      # use the modified results
+    # the sandbox on local disk is automatically cleaned up here
+
+    Args:
+      set_descriptions: SET_DESCRIPTIONS dict describing the set we want to
+          update expectations within; this tells us the subdirectory within the
+          Skia repo where we keep these expectations, and the commithash at
+          which the user evaluated new baselines.
+    """
+    file_section = set_descriptions[results.KEY__SET_DESCRIPTIONS__SECTION]
+    assert file_section == gm_json.JSONKEY_EXPECTEDRESULTS
+
+    source_dir = _unicode_to_ascii(
+        set_descriptions[results.KEY__SET_DESCRIPTIONS__DIR])
+    assert source_dir.startswith(compare_rendered_pictures.REPO_URL_PREFIX)
+    repo_subdir = source_dir[len(compare_rendered_pictures.REPO_URL_PREFIX):]
+    repo_revision = _unicode_to_ascii(
+        set_descriptions[results.KEY__SET_DESCRIPTIONS__REPO_REVISION])
+
+    logging.info('Creating a writable Skia checkout at revision "%s"...' %
+                 repo_revision)
+    super(WritableExpectations, self).__init__(
+        repository=SKIA_REPO, commit=repo_revision, subdir=repo_subdir)
+
+  def modify(self, modifications):
+    """Modify the contents of the checkout, using modifications from the UI.
+
+    Args:
+      modifications: data[KEY__LIVE_EDITS__MODIFICATIONS] coming back from the
+          rebaseline_server UI frontend
+    """
+    logging.info('Reading in dicts from writable Skia checkout in %s ...' %
+                 self.root)
+    dicts = results.BaseComparisons.read_dicts_from_root(self.root)
+
+    # Make sure we have expected-results sections in all our output dicts.
+    for pathname, adict in dicts.iteritems():
+      if not adict:
+        adict = {
+          # TODO(stephana): These values should be defined as constants
+          # somewhere, to be kept in sync between this file and
+          # compare_rendered_pictures.py.
+          gm_json.JSONKEY_HEADER: {
+            gm_json.JSONKEY_HEADER_TYPE: 'ChecksummedImages',
+            gm_json.JSONKEY_HEADER_REVISION: 1,
+          }
+        }
+      if not adict.get(gm_json.JSONKEY_EXPECTEDRESULTS, None):
+        adict[gm_json.JSONKEY_EXPECTEDRESULTS] = {}
+      dicts[pathname] = adict
+
+    for modification in modifications:
+      expectations = modification[imagepair.KEY__IMAGEPAIRS__EXPECTATIONS]
+      _add_image_info_to_expectations(
+          expectations=expectations,
+          filepath=modification[imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL])
+      extra_columns = modification[imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS]
+      dictname = modification[imagepair.KEY__IMAGEPAIRS__SOURCE_JSON_FILE]
+      dict_to_modify = dicts[dictname][gm_json.JSONKEY_EXPECTEDRESULTS]
+      test_name = extra_columns[compare_rendered_pictures.COLUMN__SOURCE_SKP]
+      test_record = dict_to_modify.get(test_name, {})
+      if (extra_columns[compare_rendered_pictures.COLUMN__TILED_OR_WHOLE] ==
+          compare_rendered_pictures.COLUMN__TILED_OR_WHOLE__TILED):
+        test_tiles_list = test_record.get(
+            gm_json.JSONKEY_SOURCE_TILEDIMAGES, [])
+        tilenum = int(extra_columns[compare_rendered_pictures.COLUMN__TILENUM])
+        _replace_list_item(test_tiles_list, tilenum, expectations)
+        test_record[gm_json.JSONKEY_SOURCE_TILEDIMAGES] = test_tiles_list
+      else:
+        test_record[gm_json.JSONKEY_SOURCE_WHOLEIMAGE] = expectations
+      dict_to_modify[test_name] = test_record
+
+    # Write the modified files back to disk.
+    self._write_dicts_to_root(meta_dict=dicts, root=self.root)
+
+  def get_diffs(self):
+    """Return patchfile describing any modifications to this checkout."""
+    return self._run_in_git_root(args=[git_utils.GIT, 'diff'])
+
+  @staticmethod
+  def _write_dicts_to_root(meta_dict, root):
+    """Write out multiple dictionaries in JSON format.
+
+    Args:
+      meta_dict: a builder-keyed meta-dictionary containing all the JSON
+                 dictionaries we want to write out
+      root: path to root of directory tree within which to write files
+    """
+    if not os.path.isdir(root):
+      raise IOError('no directory found at path %s' % root)
+
+    for rel_path in meta_dict.keys():
+      full_path = os.path.join(root, rel_path)
+      gm_json.WriteToFile(meta_dict[rel_path], full_path)
+
+
+def _unicode_to_ascii(unicode_string):
+  """Returns the plain ASCII form of a unicode string.
+
+  TODO(stephana): We created this because we get unicode strings out of the
+  JSON file, while the git filenames and revision tags are plain ASCII.
+  There may be a better way to handle this... maybe set the JSON util to just
+  return ASCII strings?
+  """
+  return unicode_string.encode('ascii', 'ignore')
+
+
+def _replace_list_item(a_list, index, value):
+  """Replaces value at index "index" within a_list.
+
+  Args:
+    a_list: a list
+    index: index indicating which item in a_list to replace
+    value: value to set a_list[index] to
+
+  If a_list does not contain this index, it will be extended with None entries
+  to that length.
+  """
+  length = len(a_list)
+  while index >= length:
+    a_list.append(None)
+    length += 1
+  a_list[index] = value
+
+
+def _add_image_info_to_expectations(expectations, filepath):
+  """Add JSONKEY_IMAGE_* info to an existing expectations dictionary.
+
+  TODO(stephana): This assumes that the checksumAlgorithm and checksumValue
+  can be derived from the filepath, which is currently true but may not always
+  be true.
+
+  Args:
+    expectations: the expectations dict to augment
+    filepath: relative path to the image file
+  """
+  (checksum_algorithm, checksum_value) = FILEPATH_RE.match(filepath).groups()
+  expectations[gm_json.JSONKEY_IMAGE_CHECKSUMALGORITHM] = checksum_algorithm
+  expectations[gm_json.JSONKEY_IMAGE_CHECKSUMVALUE] = checksum_value
+  expectations[gm_json.JSONKEY_IMAGE_FILEPATH] = filepath
diff --git a/gm/rename_config.py b/gm/rename_config.py
new file mode 100755
index 0000000..d1c6d56
--- /dev/null
+++ b/gm/rename_config.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python
+# Copyright (c) 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Utility to rename a config in some subset of our GM expectation files.
+
+Created for http://skbug.com/2752 ('split existing "gpu" GM results into "gl"
+and "gles"')
+
+Run with -h to see usage.
+
+Example command lines:
+  rename_config.py gpu gles '.*Android.*'
+
+TODO(epoger): Once https://codereview.chromium.org/397103003/ is committed,
+we should add a unittest.  Until then, we can test this as follows:
+
+OLD=expectations/gm && NEW=/tmp/expectations && \
+  rm -rf $NEW && \
+  cp -a $OLD $NEW && \
+  gm/rename_config.py msaa4 gles-msaa4 '.*Android.*' \
+    --expectations-root $NEW && \
+  diff --recursive $OLD $NEW
+"""
+__author__ = 'Elliot Poger'
+
+import argparse
+import os
+import re
+
+import gm_json
+
+DEFAULT_EXPECTATIONS_ROOT = os.path.join(
+    os.path.dirname(__file__), os.pardir, 'expectations', 'gm')
+IMAGE_FILENAME_RE = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
+
+
+class Renamer(object):
+
+  def __init__(self, args):
+    """
+    Params:
+      args: the Namespace object generated by argparse.parse_args()
+    """
+    self._args = args
+
+  def run(self):
+    """Perform all the subsitutions."""
+    for path in self._get_file_list():
+      self._rename_config(path=path,
+                          old=self._args.old_config_name,
+                          new=self._args.new_config_name)
+
+  def _rename_config(self, path, old, new):
+    """Renames all instances of a config within a GM expectations file.
+
+    Params:
+      path: path to file which will be modified in place
+      old: old config name
+      new: new config name
+    """
+    dic = gm_json.LoadFromFile(file_path=path)
+    expected_results = dic[gm_json.JSONKEY_EXPECTEDRESULTS]
+    orig_keys = expected_results.keys()
+    for key in orig_keys:
+      result = expected_results.pop(key)
+      (testname, config) = IMAGE_FILENAME_RE.match(key).groups()
+      if config == old:
+        config = new
+      key = '%s_%s.png' % (testname, config)
+      expected_results[key] = result
+    gm_json.WriteToFile(json_dict=dic, file_path=path)
+
+  def _get_file_list(self):
+    """Returns the list of files we want to operate on (the complete path
+    to each file)."""
+    root = self._args.expectations_root
+    regex = re.compile(self._args.builder_name_pattern)
+    return [os.path.join(root, builder, 'expected-results.json')
+            for builder in os.listdir(root)
+            if regex.match(builder)]
+
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('old_config_name',
+                      help=('Config name we want to replace.'))
+  parser.add_argument('new_config_name',
+                      help=('Config name we want to replace the old one with.'))
+  parser.add_argument('builder_name_pattern',
+                      help=('Regex pattern describing which builders we want '
+                            'to make the substitution for; \'.*\' to perform '
+                            'the replacement on all builders.'))
+  parser.add_argument('--expectations-root',
+                      default=DEFAULT_EXPECTATIONS_ROOT,
+                      help=('Root of the GM expectations dir; defaults to '
+                            '%(default)s'))
+  args = parser.parse_args()
+  renamer = Renamer(args)
+  renamer.run()
+
+if __name__ == '__main__':
+  main()
diff --git a/gm/resizeimagefilter.cpp b/gm/resizeimagefilter.cpp
index 6b5fa4a..bb09e0b 100644
--- a/gm/resizeimagefilter.cpp
+++ b/gm/resizeimagefilter.cpp
@@ -21,14 +21,17 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() {
         return SkString("resizeimagefilter");
     }
 
+#ifdef SK_CPU_ARM64
+    // Skip tiled drawing on 64-bit ARM until https://skbug.com/2908 is fixed.
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+#endif
+
     void draw(SkCanvas* canvas,
               const SkRect& rect,
               const SkSize& deviceSize,
diff --git a/gm/rrects.cpp b/gm/rrects.cpp
index 24636ca..b0496e3 100644
--- a/gm/rrects.cpp
+++ b/gm/rrects.cpp
@@ -86,7 +86,7 @@
 #endif
 
 #if SK_SUPPORT_GPU
-        int lastEdgeType = (kEffect_Type == fType) ? kLast_GrEffectEdgeType: 0;
+        int lastEdgeType = (kEffect_Type == fType) ? kLast_GrProcessorEdgeType: 0;
 #else
         int lastEdgeType = 0;
 #endif
@@ -116,10 +116,11 @@
 
                         SkRRect rrect = fRRects[curRRect];
                         rrect.offset(SkIntToScalar(x), SkIntToScalar(y));
-                        GrEffectEdgeType edgeType = (GrEffectEdgeType) et;
-                        SkAutoTUnref<GrEffectRef> effect(GrRRectEffect::Create(edgeType, rrect));
-                        if (effect) {
-                            drawState->addCoverageEffect(effect);
+                        GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
+                        SkAutoTUnref<GrFragmentProcessor> fp(GrRRectEffect::Create(edgeType,
+                                                                                   rrect));
+                        if (fp) {
+                            drawState->addCoverageProcessor(fp);
                             drawState->setIdentityViewMatrix();
                             drawState->setRenderTarget(rt);
                             drawState->setColor(0xff000000);
diff --git a/gm/samplerstress.cpp b/gm/samplerstress.cpp
index ef84f35..29be684 100644
--- a/gm/samplerstress.cpp
+++ b/gm/samplerstress.cpp
@@ -8,12 +8,12 @@
 #include "gm.h"
 #include "SkCanvas.h"
 #include "SkShader.h"
-#include "SkStippleMaskFilter.h"
+#include "SkBlurMaskFilter.h"
 
 namespace skiagm {
 
 /**
- * Stress test the samplers by rendering a textured glyph with a mask and
+ * Stress test the GPU samplers by rendering a textured glyph with a mask and
  * an AA clip
  */
 class SamplerStressGM : public GM {
@@ -33,7 +33,7 @@
     }
 
     virtual SkString onShortName() {
-        return SkString("samplerstress");
+        return SkString("gpusamplerstress");
     }
 
     virtual SkISize onISize() {
@@ -71,7 +71,7 @@
     }
 
     void createShader() {
-        if (NULL != fShader.get()) {
+        if (fShader.get()) {
             return;
         }
 
@@ -83,11 +83,12 @@
     }
 
     void createMaskFilter() {
-        if (NULL != fMaskFilter.get()) {
+        if (fMaskFilter.get()) {
             return;
         }
 
-        fMaskFilter.reset(SkStippleMaskFilter::Create());
+        const SkScalar sigma = 1;
+        fMaskFilter.reset(SkBlurMaskFilter::Create(kNormal_SkBlurStyle, sigma));
     }
 
     virtual void onDraw(SkCanvas* canvas) {
diff --git a/gm/shadertext.cpp b/gm/shadertext.cpp
index ac85846..37be710 100644
--- a/gm/shadertext.cpp
+++ b/gm/shadertext.cpp
@@ -28,15 +28,6 @@
     canvas.drawPaint(paint);
 }
 
-static SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty,
-                           int w, int h) {
-    static SkBitmap bmp;
-    if (bmp.isNull()) {
-        makebm(&bmp, w/2, h/4);
-    }
-    return SkShader::CreateBitmapShader(bmp, tx, ty);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 struct GradData {
@@ -115,8 +106,8 @@
         const int textLen = SK_ARRAY_COUNT(text) - 1;
         const int pointSize = 36;
 
-        int w = pointSize * textLen;
-        int h = pointSize;
+        const int w = pointSize * textLen;
+        const int h = pointSize;
 
         SkPoint pts[2] = {
             { 0, 0 },
@@ -144,17 +135,19 @@
                                                    SkShader::kClamp_TileMode);
             }
         }
+        
+        SkBitmap bm;
+        makebm(&bm, w/16, h/4);
         for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
             for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
-                shaders[shdIdx++] = MakeBitmapShader(tileModes[tx],
-                                                     tileModes[ty],
-                                                     w/8, h);
+                shaders[shdIdx++] = SkShader::CreateBitmapShader(bm, tileModes[tx], tileModes[ty]);
             }
         }
 
         SkPaint paint;
         paint.setDither(true);
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setTextSize(SkIntToScalar(pointSize));
 
         canvas->save();
diff --git a/gm/shadertext2.cpp b/gm/shadertext2.cpp
index f625d6c..d73fb6f 100644
--- a/gm/shadertext2.cpp
+++ b/gm/shadertext2.cpp
@@ -90,11 +90,13 @@
 
         SkPaint fillPaint;
         fillPaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&fillPaint);
         fillPaint.setTextSize(SkIntToScalar(kPointSize));
         fillPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
 
         SkPaint outlinePaint;
         outlinePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&outlinePaint);
         outlinePaint.setTextSize(SkIntToScalar(kPointSize));
         outlinePaint.setStyle(SkPaint::kStroke_Style);
         outlinePaint.setStrokeWidth(0.f);
@@ -110,6 +112,7 @@
         SkPaint labelPaint;
         labelPaint.setColor(0xff000000);
         labelPaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&labelPaint);
         labelPaint.setTextSize(12.f);
 
         canvas->translate(15.f, 15.f);
diff --git a/gm/shadertext3.cpp b/gm/shadertext3.cpp
index 78efe87..ca8dd11 100644
--- a/gm/shadertext3.cpp
+++ b/gm/shadertext3.cpp
@@ -76,6 +76,7 @@
 
         SkPaint outlinePaint;
         outlinePaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&outlinePaint);
         outlinePaint.setTextSize(SkIntToScalar(kPointSize));
         outlinePaint.setStyle(SkPaint::kStroke_Style);
         outlinePaint.setStrokeWidth(0.f);
@@ -109,6 +110,7 @@
 
                 SkPaint fillPaint;
                 fillPaint.setAntiAlias(true);
+                sk_tool_utils::set_portable_typeface(&fillPaint);
                 fillPaint.setTextSize(SkIntToScalar(kPointSize));
                 fillPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
                 fillPaint.setShader(shader);
diff --git a/gm/shadows.cpp b/gm/shadows.cpp
index ca49a02..3ecbdd8 100644
--- a/gm/shadows.cpp
+++ b/gm/shadows.cpp
@@ -36,10 +36,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() {
         return SkString("shadows");
     }
diff --git a/gm/simpleaaclip.cpp b/gm/simpleaaclip.cpp
index 201f9bc..950a1c0 100644
--- a/gm/simpleaaclip.cpp
+++ b/gm/simpleaaclip.cpp
@@ -124,10 +124,6 @@
         canvas->restore();
     }
 
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kPath_GeomType == fGeomType ? kSkipTiled_Flag : 0;
-    }
-
     virtual SkString onShortName() {
         SkString str;
         str.printf("simpleaaclip_%s",
@@ -158,6 +154,7 @@
 
         SkPaint textPaint;
         textPaint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&textPaint);
         textPaint.setTextSize(SK_Scalar1*24);
         int xOff = 0;
 
diff --git a/gm/skbug1719.cpp b/gm/skbug1719.cpp
index 6a4bd92..a57596e 100644
--- a/gm/skbug1719.cpp
+++ b/gm/skbug1719.cpp
@@ -24,10 +24,6 @@
     SkBug1719GM() {}
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() SK_OVERRIDE {
         return SkString("skbug1719");
     }
diff --git a/gm/srcmode.cpp b/gm/srcmode.cpp
index 6aa236f..85a3561 100644
--- a/gm/srcmode.cpp
+++ b/gm/srcmode.cpp
@@ -80,6 +80,7 @@
         canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
 
         SkPaint paint;
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0x80FF0000);
 
         const Proc procs[] = {
@@ -115,18 +116,21 @@
         }
     }
 
-    static SkSurface* compat_surface(SkCanvas* canvas, const SkISize& size,
-                                     bool skipGPU) {
+    static SkSurface* compat_surface(SkCanvas* canvas, const SkISize& size, bool skipGPU) {
         SkImageInfo info = SkImageInfo::MakeN32Premul(size);
+
+        bool callNewSurface = true;
 #if SK_SUPPORT_GPU
-        SkBaseDevice* dev = canvas->getDevice();
-        if (!skipGPU && dev->accessRenderTarget()) {
-            SkGpuDevice* gd = (SkGpuDevice*)dev;
-            GrContext* ctx = gd->context();
-            return SkSurface::NewRenderTarget(ctx, info, 0);
+        if (canvas->getGrContext() && skipGPU) {
+            callNewSurface = false;
         }
 #endif
-        return SkSurface::NewRaster(info);
+        SkSurface* surface = callNewSurface ? canvas->newSurface(info) : NULL;
+        if (NULL == surface) {
+            // picture canvas will return null, so fall-back to raster
+            surface = SkSurface::NewRaster(info);
+        }
+        return surface;
     }
 
     virtual void onDraw(SkCanvas* canvas) {
diff --git a/gm/strokefill.cpp b/gm/strokefill.cpp
index 5f943df..4566eea 100644
--- a/gm/strokefill.cpp
+++ b/gm/strokefill.cpp
@@ -48,12 +48,10 @@
         paint.setTextSize(SkIntToScalar(100));
         paint.setStrokeWidth(SkIntToScalar(5));
 
-        SkTypeface* face = SkTypeface::CreateFromName("Papyrus", SkTypeface::kNormal);
-        SkSafeUnref(paint.setTypeface(face));
+        sk_tool_utils::set_portable_typeface(&paint, "Papyrus");
         show_bold(canvas, "Hello", 5, x, y, paint);
 
-        face = SkTypeface::CreateFromName("Hiragino Maru Gothic Pro", SkTypeface::kNormal);
-        SkSafeUnref(paint.setTypeface(face));
+        sk_tool_utils::set_portable_typeface(&paint, "Hiragino Maru Gothic Pro");
         const unsigned char hyphen[] = { 0xE3, 0x83, 0xBC };
         show_bold(canvas, hyphen, SK_ARRAY_COUNT(hyphen), x + SkIntToScalar(300), y, paint);
 
diff --git a/gm/stroketext.cpp b/gm/stroketext.cpp
index 13c64fa..8ca1402 100644
--- a/gm/stroketext.cpp
+++ b/gm/stroketext.cpp
@@ -87,6 +87,7 @@
         if (true) { test_nulldev(canvas); }
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
 
         paint.setTextSize(kBelowThreshold_TextSize);
         draw_text_set(canvas, paint);
diff --git a/gm/surface.cpp b/gm/surface.cpp
new file mode 100644
index 0000000..dbcced2
--- /dev/null
+++ b/gm/surface.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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 "gm.h"
+#include "SkGradientShader.h"
+#include "SkSurface.h"
+#include "SkSurfaceProps.h"
+
+#define W 200
+#define H 100
+
+static SkShader* make_shader() {
+    int a = 0x99;
+    int b = 0xBB;
+    SkPoint pts[] = { { 0, 0 }, { W, H } };
+    SkColor colors[] = { SkColorSetRGB(a, a, a), SkColorSetRGB(b, b, b) };
+    return SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
+}
+
+static SkSurface* make_surface(GrContext* ctx, const SkImageInfo& info, SkPixelGeometry geo,
+                               int disallowAA, int disallowDither) {
+    uint32_t flags = 0;
+    if (disallowAA) {
+        flags |= SkSurfaceProps::kDisallowAntiAlias_Flag;
+    }
+    if (disallowDither) {
+        flags |= SkSurfaceProps::kDisallowDither_Flag;
+    }
+
+    SkSurfaceProps props(flags, geo);
+    if (ctx) {
+        return SkSurface::NewRenderTarget(ctx, info, 0, &props);
+    } else {
+        return SkSurface::NewRaster(info, &props);
+    }
+}
+
+static void test_draw(SkCanvas* canvas, const char label[]) {
+    SkPaint paint;
+
+    paint.setAntiAlias(true);
+    paint.setLCDRenderText(true);
+    paint.setDither(true);
+
+    paint.setShader(make_shader())->unref();
+    canvas->drawRect(SkRect::MakeWH(W, H), paint);
+    paint.setShader(NULL);
+
+    paint.setColor(SK_ColorWHITE);
+    paint.setTextSize(32);
+    paint.setTextAlign(SkPaint::kCenter_Align);
+    canvas->drawText(label, strlen(label), W / 2, H * 3 / 4, paint);
+}
+
+class SurfacePropsGM : public skiagm::GM {
+public:
+    SurfacePropsGM() {}
+
+protected:
+    SkString onShortName() SK_OVERRIDE {
+        return SkString("surfaceprops");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(W * 4, H * 5);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        GrContext* ctx = canvas->getGrContext();
+
+        // must be opaque to have a hope of testing LCD text
+        const SkImageInfo info = SkImageInfo::MakeN32(W, H, kOpaque_SkAlphaType);
+
+        const struct {
+            SkPixelGeometry fGeo;
+            const char*     fLabel;
+        } rec[] = {
+            { kUnknown_SkPixelGeometry, "Unknown" },
+            { kRGB_H_SkPixelGeometry,   "RGB_H" },
+            { kBGR_H_SkPixelGeometry,   "BGR_H" },
+            { kRGB_V_SkPixelGeometry,   "RGB_V" },
+            { kBGR_V_SkPixelGeometry,   "BGR_V" },
+        };
+    
+        SkScalar x = 0;
+        for (int disallowAA = 0; disallowAA <= 1; ++disallowAA) {
+            for (int disallowDither = 0; disallowDither <= 1; ++disallowDither) {
+                SkScalar y = 0;
+                for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
+                    SkAutoTUnref<SkSurface> surface(make_surface(ctx, info, rec[i].fGeo,
+                                                                 disallowAA, disallowDither));
+                    test_draw(surface->getCanvas(), rec[i].fLabel);
+                    surface->draw(canvas, x, y, NULL);
+                    y += H;
+                }
+                x += W;
+            }
+        }
+    }
+
+private:
+    typedef GM INHERITED;
+};
+
+DEF_GM( return new SurfacePropsGM )
diff --git a/gm/test_all.py b/gm/test_all.py
new file mode 100755
index 0000000..282ec85
--- /dev/null
+++ b/gm/test_all.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+
+"""
+Copyright 2014 Google Inc.
+
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+
+Run all unittests within this directory tree, recursing into subdirectories.
+"""
+
+import os
+import unittest
+
+
+def main():
+  suite = unittest.TestLoader().discover(os.path.dirname(__file__),
+                                         pattern='*_test.py')
+  results = unittest.TextTestRunner(verbosity=2).run(suite)
+  print repr(results)
+  if not results.wasSuccessful():
+    raise Exception('failed one or more unittests')
+
+if __name__ == '__main__':
+  main()
diff --git a/gm/tests/run.sh b/gm/tests/run.sh
index 333f3ef..52ed6f3 100755
--- a/gm/tests/run.sh
+++ b/gm/tests/run.sh
@@ -264,8 +264,8 @@
   assert_fails "python gm/display_json_results.py $GM_OUTPUTS/$CASE/$OUTPUT_EXPECTED_SUBDIR/json-summary.txt"
 done
 
-# Exercise all rebaseline_server unittests.
-assert_passes "python gm/rebaseline_server/test_all.py"
+# Exercise all Python unittests.
+assert_passes "python gm/test_all.py"
 
 echo
 if [ $ENCOUNTERED_ANY_ERRORS == 0 ]; then
diff --git a/gm/texdata.cpp b/gm/texdata.cpp
index ca82292..b979df7 100644
--- a/gm/texdata.cpp
+++ b/gm/texdata.cpp
@@ -91,7 +91,7 @@
                 if (!texture) {
                     return;
                 }
-                SkAutoUnref au(texture);
+                SkAutoTUnref<GrTexture> au(texture);
 
                 GrContext::AutoClip acs(ctx, SkRect::MakeWH(2*S, 2*S));
 
@@ -111,7 +111,7 @@
                 SkMatrix tm;
                 tm = vm;
                 tm.postIDiv(2*S, 2*S);
-                paint.addColorTextureEffect(texture, tm);
+                paint.addColorTextureProcessor(texture, tm);
 
                 ctx->drawRect(paint, SkRect::MakeWH(2*S, 2*S));
 
diff --git a/gm/textblob.cpp b/gm/textblob.cpp
new file mode 100644
index 0000000..a034007
--- /dev/null
+++ b/gm/textblob.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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 "gm.h"
+
+#include "SkCanvas.h"
+#include "SkPoint.h"
+#include "SkTextBlob.h"
+#include "SkTDArray.h"
+
+namespace  {
+
+enum Pos {
+    kDefault_Pos = 0,
+    kScalar_Pos  = 1,
+    kPoint_Pos   = 2,
+};
+
+const struct BlobCfg {
+    unsigned count;
+    Pos      pos;
+    SkScalar scale;
+} blobConfigs[][3][3] = {
+    {
+        { { 1024, kDefault_Pos, 1 }, { 0, kDefault_Pos, 0 }, { 0, kDefault_Pos, 0 } },
+        { { 1024,  kScalar_Pos, 1 }, { 0,  kScalar_Pos, 0 }, { 0,  kScalar_Pos, 0 } },
+        { { 1024,   kPoint_Pos, 1 }, { 0,   kPoint_Pos, 0 }, { 0,   kPoint_Pos, 0 } },
+    },
+    {
+        { { 4, kDefault_Pos, 1 },     { 4, kDefault_Pos, 1 },  { 4, kDefault_Pos, 1 } },
+        { { 4,  kScalar_Pos, 1 },     { 4,  kScalar_Pos, 1 },  { 4,  kScalar_Pos, 1 } },
+        { { 4,   kPoint_Pos, 1 },     { 4,   kPoint_Pos, 1 },  { 4,   kPoint_Pos, 1 } },
+    },
+
+    {
+        { { 4, kDefault_Pos, 1 },     { 4, kDefault_Pos, 1 },  { 4,  kScalar_Pos, 1 } },
+        { { 4,  kScalar_Pos, 1 },     { 4,  kScalar_Pos, 1 },  { 4,   kPoint_Pos, 1 } },
+        { { 4,   kPoint_Pos, 1 },     { 4,   kPoint_Pos, 1 },  { 4, kDefault_Pos, 1 } },
+    },
+
+    {
+        { { 4, kDefault_Pos, 1 },     { 4,  kScalar_Pos, 1 },  { 4,   kPoint_Pos, 1 } },
+        { { 4,  kScalar_Pos, 1 },     { 4,   kPoint_Pos, 1 },  { 4, kDefault_Pos, 1 } },
+        { { 4,   kPoint_Pos, 1 },     { 4, kDefault_Pos, 1 },  { 4,  kScalar_Pos, 1 } },
+    },
+
+    {
+        { { 4, kDefault_Pos, .75f },     { 4, kDefault_Pos, 1 },  { 4,  kScalar_Pos, 1.25f } },
+        { { 4,  kScalar_Pos, .75f },     { 4,  kScalar_Pos, 1 },  { 4,   kPoint_Pos, 1.25f } },
+        { { 4,   kPoint_Pos, .75f },     { 4,   kPoint_Pos, 1 },  { 4, kDefault_Pos, 1.25f } },
+    },
+
+    {
+        { { 4, kDefault_Pos, 1 },     { 4,  kScalar_Pos, .75f },  { 4,   kPoint_Pos, 1.25f } },
+        { { 4,  kScalar_Pos, 1 },     { 4,   kPoint_Pos, .75f },  { 4, kDefault_Pos, 1.25f } },
+        { { 4,   kPoint_Pos, 1 },     { 4, kDefault_Pos, .75f },  { 4,  kScalar_Pos, 1.25f } },
+    },
+};
+
+const SkScalar kFontSize = 16;
+}
+
+class TextBlobGM : public skiagm::GM {
+public:
+    TextBlobGM(const char* txt)
+        : fTypeface(sk_tool_utils::create_portable_typeface("Times", SkTypeface::kNormal)) {
+        SkPaint p;
+        p.setTypeface(fTypeface);
+        size_t txtLen = strlen(txt);
+        int glyphCount = p.textToGlyphs(txt, txtLen, NULL);
+
+        fGlyphs.append(glyphCount);
+        p.textToGlyphs(txt, txtLen, fGlyphs.begin());
+    }
+
+protected:
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("textblob");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(640, 480);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        for (unsigned b = 0; b < SK_ARRAY_COUNT(blobConfigs); ++b) {
+            SkAutoTUnref<const SkTextBlob> blob(this->makeBlob(b));
+
+            SkPaint p;
+            SkPoint offset = SkPoint::Make(SkIntToScalar(10 + 300 * (b % 2)),
+                                           SkIntToScalar(20 + 150 * (b / 2)));
+
+            canvas->drawTextBlob(blob, offset.x(), offset.y(), p);
+
+            p.setColor(SK_ColorBLUE);
+            p.setStyle(SkPaint::kStroke_Style);
+            SkRect box = blob->bounds();
+            box.offset(offset);
+            canvas->drawRect(box, p);
+
+        }
+    }
+
+private:
+    const SkTextBlob* makeBlob(unsigned blobIndex) {
+        SkTextBlobBuilder builder;
+
+        SkPaint font;
+        font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+        font.setAntiAlias(true);
+        font.setSubpixelText(true);
+        font.setTypeface(fTypeface);
+
+        for (unsigned l = 0; l < SK_ARRAY_COUNT(blobConfigs[blobIndex]); ++l) {
+            unsigned currentGlyph = 0;
+
+            for (unsigned c = 0; c < SK_ARRAY_COUNT(blobConfigs[blobIndex][l]); ++c) {
+                const BlobCfg* cfg = &blobConfigs[blobIndex][l][c];
+                unsigned count = cfg->count;
+
+                if (count > fGlyphs.count() - currentGlyph) {
+                    count = fGlyphs.count() - currentGlyph;
+                }
+                if (0 == count) {
+                    break;
+                }
+
+                font.setTextSize(kFontSize * cfg->scale);
+                const SkScalar advanceX = font.getTextSize() * 0.85f;
+                const SkScalar advanceY = font.getTextSize() * 1.5f;
+
+                SkPoint offset = SkPoint::Make(currentGlyph * advanceX + c * advanceX,
+                                               advanceY * l);
+                switch (cfg->pos) {
+                case kDefault_Pos: {
+                    const SkTextBlobBuilder::RunBuffer& buf = builder.allocRun(font, count,
+                                                                               offset.x(),
+                                                                               offset.y());
+                    memcpy(buf.glyphs, fGlyphs.begin() + currentGlyph, count * sizeof(uint16_t));
+                } break;
+                case kScalar_Pos: {
+                    const SkTextBlobBuilder::RunBuffer& buf = builder.allocRunPosH(font, count,
+                                                                                   offset.y());
+                    SkTDArray<SkScalar> pos;
+                    for (unsigned i = 0; i < count; ++i) {
+                        *pos.append() = offset.x() + i * advanceX;
+                    }
+
+                    memcpy(buf.glyphs, fGlyphs.begin() + currentGlyph, count * sizeof(uint16_t));
+                    memcpy(buf.pos, pos.begin(), count * sizeof(SkScalar));
+                } break;
+                case kPoint_Pos: {
+                    const SkTextBlobBuilder::RunBuffer& buf = builder.allocRunPos(font, count);
+
+                    SkTDArray<SkScalar> pos;
+                    for (unsigned i = 0; i < count; ++i) {
+                        *pos.append() = offset.x() + i * advanceX;
+                        *pos.append() = offset.y() + i * (advanceY / count);
+                    }
+
+                    memcpy(buf.glyphs, fGlyphs.begin() + currentGlyph, count * sizeof(uint16_t));
+                    memcpy(buf.pos, pos.begin(), count * sizeof(SkScalar) * 2);
+                } break;
+                default:
+                    SkFAIL("unhandled pos value");
+                }
+
+                currentGlyph += count;
+            }
+        }
+
+        return builder.build();
+    }
+
+    SkTDArray<uint16_t>      fGlyphs;
+    SkAutoTUnref<SkTypeface> fTypeface;
+
+    typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return SkNEW_ARGS(TextBlobGM, ("hamburgefons")); )
diff --git a/gm/textblobshader.cpp b/gm/textblobshader.cpp
new file mode 100644
index 0000000..7ec75b5
--- /dev/null
+++ b/gm/textblobshader.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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 "gm.h"
+
+#include "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkPoint.h"
+#include "SkShader.h"
+#include "SkTextBlob.h"
+#include "SkTDArray.h"
+#include "SkTypeface.h"
+
+// This GM exercises drawTextBlob offset vs. shader space behavior.
+class TextBlobShaderGM : public skiagm::GM {
+public:
+    TextBlobShaderGM(const char* txt) {
+        SkPaint p;
+        size_t txtLen = strlen(txt);
+        fGlyphs.append(p.textToGlyphs(txt, txtLen, NULL));
+        p.textToGlyphs(txt, txtLen, fGlyphs.begin());
+    }
+
+protected:
+
+    virtual void onOnceBeforeDraw() SK_OVERRIDE {
+        SkPaint p;
+        p.setAntiAlias(true);
+        p.setSubpixelText(true);
+        p.setTextSize(30);
+        p.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+
+        SkTextBlobBuilder builder;
+        int glyphCount = fGlyphs.count();
+        const SkTextBlobBuilder::RunBuffer* run;
+
+        run = &builder.allocRun(p, glyphCount, 10, 10, NULL);
+        memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
+
+        run = &builder.allocRunPosH(p, glyphCount,  80, NULL);
+        memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
+        for (int i = 0; i < glyphCount; ++i) {
+            run->pos[i] = p.getTextSize() * i * .75f;
+        }
+
+        run = &builder.allocRunPos(p, glyphCount, NULL);
+        memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
+        for (int i = 0; i < glyphCount; ++i) {
+            run->pos[i * 2] = p.getTextSize() * i * .75f;
+            run->pos[i * 2 + 1] = 150 + 5 * sinf((float)i * 8 / glyphCount);
+        }
+
+        fBlob.reset(builder.build());
+
+        SkColor  colors[2];
+        colors[0] = SK_ColorRED;
+        colors[1] = SK_ColorGREEN;
+
+        SkScalar pos[SK_ARRAY_COUNT(colors)];
+        for (unsigned i = 0; i < SK_ARRAY_COUNT(pos); ++i) {
+            pos[i] = (float)i / (SK_ARRAY_COUNT(pos) - 1);
+        }
+
+        SkISize sz = this->onISize();
+        fShader.reset(SkGradientShader::CreateRadial(SkPoint::Make(SkIntToScalar(sz.width() / 2),
+                                                                   SkIntToScalar(sz.height() / 2)),
+                                                     sz.width() * .66f, colors, pos,
+                                                     SK_ARRAY_COUNT(colors),
+                                                     SkShader::kRepeat_TileMode));
+    }
+
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkip565_Flag;
+    }
+
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("textblobshader");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(640, 480);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        SkPaint p;
+        p.setStyle(SkPaint::kFill_Style);
+        p.setShader(fShader);
+
+        SkISize sz = this->onISize();
+        static const int kXCount = 4;
+        static const int kYCount = 3;
+        for (int i = 0; i < kXCount; ++i) {
+            for (int j = 0; j < kYCount; ++j) {
+                canvas->drawTextBlob(fBlob,
+                                     SkIntToScalar(i * sz.width() / kXCount),
+                                     SkIntToScalar(j * sz.height() / kYCount),
+                                     p);
+            }
+        }
+    }
+
+private:
+    SkTDArray<uint16_t>            fGlyphs;
+    SkAutoTUnref<const SkTextBlob> fBlob;
+    SkAutoTUnref<SkShader>         fShader;
+
+    typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return SkNEW_ARGS(TextBlobShaderGM, ("Blobber")); )
diff --git a/gm/texteffects.cpp b/gm/texteffects.cpp
index 7e6bee4..5bdaf9b 100644
--- a/gm/texteffects.cpp
+++ b/gm/texteffects.cpp
@@ -188,6 +188,7 @@
 
         SkPaint     paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setTextSize(SkIntToScalar(56));
 
         SkScalar    x = SkIntToScalar(20);
diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp
index 5f31977..6534b0c 100644
--- a/gm/texturedomaineffect.cpp
+++ b/gm/texturedomaineffect.cpp
@@ -35,7 +35,10 @@
     }
 
     virtual SkISize onISize() SK_OVERRIDE {
-        return SkISize::Make(400, 800);
+        const SkScalar canvasWidth = kDrawPad +
+                (kTargetWidth + 2 * kDrawPad) * GrTextureDomain::kModeCount +
+                kTestPad * GrTextureDomain::kModeCount;
+        return SkISize::Make(SkScalarCeilToInt(canvasWidth), 800);
     }
 
     virtual uint32_t onGetFlags() const SK_OVERRIDE {
@@ -44,7 +47,7 @@
     }
 
     virtual void onOnceBeforeDraw() SK_OVERRIDE {
-        fBmp.allocN32Pixels(100, 100);
+        fBmp.allocN32Pixels(kTargetWidth, kTargetHeight);
         SkCanvas canvas(fBmp);
         canvas.clear(0x00000000);
         SkPaint paint;
@@ -94,9 +97,6 @@
             return;
         }
 
-        static const SkScalar kDrawPad = 10.f;
-        static const SkScalar kTestPad = 10.f;
-
         SkTArray<SkMatrix> textureMatrices;
         textureMatrices.push_back().setIDiv(texture->width(), texture->height());
         textureMatrices.push_back() = textureMatrices[0];
@@ -122,13 +122,13 @@
                 SkScalar x = kDrawPad + kTestPad;
                 for (int m = 0; m < GrTextureDomain::kModeCount; ++m) {
                     GrTextureDomain::Mode mode = (GrTextureDomain::Mode) m;
-                    SkAutoTUnref<GrEffectRef> effect(
+                    SkAutoTUnref<GrFragmentProcessor> fp(
                         GrTextureDomainEffect::Create(texture, textureMatrices[tm],
                                                 GrTextureDomain::MakeTexelDomain(texture,
                                                                                 texelDomains[d]),
                                                 mode, GrTextureParams::kNone_FilterMode));
 
-                    if (!effect) {
+                    if (!fp) {
                         continue;
                     }
                     SkMatrix viewMatrix;
@@ -136,7 +136,7 @@
                     drawState->reset(viewMatrix);
                     drawState->setRenderTarget(rt);
                     drawState->setColor(0xffffffff);
-                    drawState->addColorEffect(effect, 1);
+                    drawState->addColorProcessor(fp);
 
                     tt.target()->drawSimpleRect(renderRect);
                     x += renderRect.width() + kTestPad;
@@ -148,11 +148,19 @@
     }
 
 private:
+    static const SkScalar kDrawPad;
+    static const SkScalar kTestPad;
+    static const int      kTargetWidth = 100;
+    static const int      kTargetHeight = 100;
     SkBitmap fBmp;
 
     typedef GM INHERITED;
 };
 
+// Windows builds did not like SkScalar initialization in class :(
+const SkScalar TextureDomainEffect::kDrawPad = 10.f;
+const SkScalar TextureDomainEffect::kTestPad = 10.f;
+
 DEF_GM( return SkNEW(TextureDomainEffect); )
 }
 
diff --git a/gm/thinstrokedrects.cpp b/gm/thinstrokedrects.cpp
index 37ffb35..7e3e399 100644
--- a/gm/thinstrokedrects.cpp
+++ b/gm/thinstrokedrects.cpp
@@ -17,10 +17,6 @@
     }
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     virtual SkString onShortName() SK_OVERRIDE {
         return SkString("thinstrokedrects");
     }
diff --git a/gm/tileimagefilter.cpp b/gm/tileimagefilter.cpp
index 210a646..7d1a3f0 100644
--- a/gm/tileimagefilter.cpp
+++ b/gm/tileimagefilter.cpp
@@ -34,6 +34,7 @@
         canvas.clear(0xFF000000);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xD000D000);
         paint.setTextSize(SkIntToScalar(50));
         const char* str = "e";
diff --git a/gm/tilemodes.cpp b/gm/tilemodes.cpp
index 99d3a47..a912cba 100644
--- a/gm/tilemodes.cpp
+++ b/gm/tilemodes.cpp
@@ -100,6 +100,7 @@
                 SkPaint p;
                 SkString str;
                 p.setAntiAlias(true);
+                sk_tool_utils::set_portable_typeface(&p);
                 p.setDither(true);
                 str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
 
@@ -139,6 +140,7 @@
                     SkPaint p;
                     SkString str;
                     p.setAntiAlias(true);
+                    sk_tool_utils::set_portable_typeface(&p);
                     str.printf("%s, %s", gConfigNames[i], gFilterNames[j]);
                     canvas->drawText(str.c_str(), str.size(), x, y + r.height() * 2 / 3, p);
                 }
@@ -221,6 +223,7 @@
 
         SkPaint p;
         p.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&p);
         p.setTextAlign(SkPaint::kCenter_Align);
 
         for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
diff --git a/gm/tilemodes_scaled.cpp b/gm/tilemodes_scaled.cpp
index 88a070a..93a3db3 100644
--- a/gm/tilemodes_scaled.cpp
+++ b/gm/tilemodes_scaled.cpp
@@ -65,13 +65,6 @@
         kNPOTSize = 3,
     };
 
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        if (!fPowerOfTwoSize) {
-            return kSkipTiled_Flag;  // Only for 565.  8888 is fine.
-        }
-        return 0;
-    }
-
     SkString onShortName() {
         SkString name("scaled_tilemodes");
         if (!fPowerOfTwoSize) {
@@ -80,6 +73,13 @@
         return name;
     }
 
+#ifdef SK_CPU_ARM64
+    // Skip tiled drawing on 64-bit ARM until https://skbug.com/2908 is fixed.
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        return kSkipTiled_Flag;
+    }
+#endif
+
     SkISize onISize() { return SkISize::Make(880, 760); }
 
     virtual void onOnceBeforeDraw() SK_OVERRIDE {
@@ -117,6 +117,7 @@
                 SkPaint p;
                 SkString str;
                 p.setAntiAlias(true);
+                sk_tool_utils::set_portable_typeface(&p);
                 p.setDither(true);
                 p.setLooper(fLooper);
                 str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
@@ -158,6 +159,7 @@
                     SkPaint p;
                     SkString str;
                     p.setAntiAlias(true);
+                    sk_tool_utils::set_portable_typeface(&p);
                     p.setLooper(fLooper);
                     str.printf("%s, %s", gColorTypeNames[i], gFilterNames[j]);
                     canvas->drawText(str.c_str(), str.size(), scale*x, scale*(y + r.height() * 2 / 3), p);
@@ -241,6 +243,7 @@
 
         SkPaint p;
         p.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&p);
         p.setTextAlign(SkPaint::kCenter_Align);
 
         for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
diff --git a/gm/twopointradial.cpp b/gm/twopointradial.cpp
index 4118a69..f1a27d3 100644
--- a/gm/twopointradial.cpp
+++ b/gm/twopointradial.cpp
@@ -30,6 +30,7 @@
     SkColor colors[] = { SK_ColorGREEN, SK_ColorRED };
     SkPaint paint;
     paint.setAntiAlias(true);
+    sk_tool_utils::set_portable_typeface(&paint);
 
     SkString str;
     str.printf("%g,%g,%g  %g,%g,%g",
@@ -56,10 +57,6 @@
     TwoPointRadialGM() {}
 
 protected:
-    virtual uint32_t onGetFlags() const SK_OVERRIDE {
-        return kSkipTiled_Flag;
-    }
-
     SkString onShortName() {
         return SkString("twopointconical");
     }
diff --git a/gm/typeface.cpp b/gm/typeface.cpp
index f2c56a5..c329395 100644
--- a/gm/typeface.cpp
+++ b/gm/typeface.cpp
@@ -24,7 +24,7 @@
     TypefaceGM() {
         fFaces = new SkTypeface*[SK_ARRAY_COUNT(gFaces)];
         for (size_t i = 0; i < SK_ARRAY_COUNT(gFaces); i++) {
-            fFaces[i] = SkTypeface::CreateFromName(gFaces[i], SkTypeface::kNormal);
+            fFaces[i] = sk_tool_utils::create_portable_typeface(gFaces[i], SkTypeface::kNormal);
         }
     }
 
@@ -159,8 +159,8 @@
 public:
     TypefaceStylesGM(bool applyKerning) : fApplyKerning(applyKerning) {
         for (int i = 0; i < gFaceStylesCount; i++) {
-            fFaces[i] = SkTypeface::CreateFromName(gFaceStyles[i].fName,
-                                                   gFaceStyles[i].fStyle);
+            fFaces[i] = sk_tool_utils::create_portable_typeface(gFaceStyles[i].fName,
+                                                         gFaceStyles[i].fStyle);
         }
     }
 
diff --git a/gm/variedtext.cpp b/gm/variedtext.cpp
index e174796..ebb3c3b 100644
--- a/gm/variedtext.cpp
+++ b/gm/variedtext.cpp
@@ -59,10 +59,10 @@
         SkScalar h = SkIntToScalar(size.fHeight);
 
         SK_COMPILE_ASSERT(4 == SK_ARRAY_COUNT(fTypefacesToUnref), typeface_cnt);
-        fTypefacesToUnref[0] = SkTypeface::CreateFromName("sans-serif", SkTypeface::kNormal);
-        fTypefacesToUnref[1] = SkTypeface::CreateFromName("sans-serif", SkTypeface::kBold);
-        fTypefacesToUnref[2] = SkTypeface::CreateFromName("serif", SkTypeface::kNormal);
-        fTypefacesToUnref[3] = SkTypeface::CreateFromName("serif", SkTypeface::kBold);
+        fTypefacesToUnref[0] = sk_tool_utils::create_portable_typeface("sans-serif", SkTypeface::kNormal);
+        fTypefacesToUnref[1] = sk_tool_utils::create_portable_typeface("sans-serif", SkTypeface::kBold);
+        fTypefacesToUnref[2] = sk_tool_utils::create_portable_typeface("serif", SkTypeface::kNormal);
+        fTypefacesToUnref[3] = sk_tool_utils::create_portable_typeface("serif", SkTypeface::kBold);
 
         SkRandom random;
         for (int i = 0; i < kCnt; ++i) {
diff --git a/gm/verttext2.cpp b/gm/verttext2.cpp
index b0375ee..0ccdec1 100644
--- a/gm/verttext2.cpp
+++ b/gm/verttext2.cpp
@@ -21,8 +21,8 @@
     VertText2GM() {
         const int pointSize = 24;
         textHeight = SkIntToScalar(pointSize);
-        fProp = SkTypeface::CreateFromName("Helvetica", SkTypeface::kNormal);
-        fMono = SkTypeface::CreateFromName("Courier New", SkTypeface::kNormal);
+        fProp = sk_tool_utils::create_portable_typeface("Helvetica", SkTypeface::kNormal);
+        fMono = sk_tool_utils::create_portable_typeface("Courier New", SkTypeface::kNormal);
     }
 
     virtual ~VertText2GM() {
diff --git a/gm/verylargebitmap.cpp b/gm/verylargebitmap.cpp
index d3b16e9..afb49b9 100644
--- a/gm/verylargebitmap.cpp
+++ b/gm/verylargebitmap.cpp
@@ -99,8 +99,8 @@
         show_bm(canvas, veryBig, small, colors);
     }
 
-    virtual uint32_t onGetFlags() const {
 #ifdef SK_BUILD_FOR_WIN32
+    virtual uint32_t onGetFlags() const {
         // The Windows bot runs out of memory in replay modes on this test in 32bit builds:
         // http://skbug.com/1756
         return kSkipPicture_Flag            |
@@ -108,10 +108,8 @@
                kSkipPipeCrossProcess_Flag   |
                kSkipTiled_Flag              |
                kSkipScaledReplay_Flag;
-#else
-        return kSkipTiled_Flag;
-#endif
     }
+#endif
 
 private:
     typedef skiagm::GM INHERITED;
diff --git a/gm/xfermodeimagefilter.cpp b/gm/xfermodeimagefilter.cpp
index 584e60b..0312141 100644
--- a/gm/xfermodeimagefilter.cpp
+++ b/gm/xfermodeimagefilter.cpp
@@ -34,6 +34,7 @@
         canvas.clear(0x00000000);
         SkPaint paint;
         paint.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&paint);
         paint.setColor(0xD000D000);
         paint.setTextSize(SkIntToScalar(96));
         const char* str = "e";
diff --git a/gm/xfermodes.cpp b/gm/xfermodes.cpp
index c9299b3..721a76e 100644
--- a/gm/xfermodes.cpp
+++ b/gm/xfermodes.cpp
@@ -225,6 +225,7 @@
 
         SkPaint labelP;
         labelP.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&labelP);
         labelP.setTextAlign(SkPaint::kCenter_Align);
 
         const int W = 5;
diff --git a/gm/xfermodes2.cpp b/gm/xfermodes2.cpp
index 0f3735e..b1dd6d8 100644
--- a/gm/xfermodes2.cpp
+++ b/gm/xfermodes2.cpp
@@ -34,6 +34,7 @@
 
         SkPaint labelP;
         labelP.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&labelP);
         labelP.setTextAlign(SkPaint::kCenter_Align);
 
         const int W = 6;
diff --git a/gm/xfermodes3.cpp b/gm/xfermodes3.cpp
index 92367f3..1ca7408 100644
--- a/gm/xfermodes3.cpp
+++ b/gm/xfermodes3.cpp
@@ -46,6 +46,7 @@
 
         SkPaint labelP;
         labelP.setAntiAlias(true);
+        sk_tool_utils::set_portable_typeface(&labelP);
 
         static const SkColor kSolidColors[] = {
             SK_ColorTRANSPARENT,
@@ -123,17 +124,17 @@
     SkCanvas* possiblyCreateTempCanvas(SkCanvas* baseCanvas, int w, int h) {
         SkCanvas* tempCanvas = NULL;
 #if SK_SUPPORT_GPU
-        GrRenderTarget* rt = baseCanvas->getDevice()->accessRenderTarget();
-        if (NULL != rt) {
-            GrContext* context = rt->getContext();
+        GrContext* context = baseCanvas->getGrContext();
+        if (context) {
             GrTextureDesc desc;
             desc.fWidth = w;
             desc.fHeight = h;
-            desc.fConfig = rt->config();
+            desc.fConfig = SkImageInfo2GrPixelConfig(baseCanvas->imageInfo());
             desc.fFlags = kRenderTarget_GrTextureFlagBit;
             SkAutoTUnref<GrSurface> surface(context->createUncachedTexture(desc, NULL, 0));
-            SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(surface.get()));
-            if (NULL != device.get()) {
+            SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(surface.get(),
+                                          SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType)));
+            if (device.get()) {
                 tempCanvas = SkNEW_ARGS(SkCanvas, (device.get()));
             }
         }
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
new file mode 100644
index 0000000..026823e
--- /dev/null
+++ b/gm/yuvtorgbeffect.cpp
@@ -0,0 +1,142 @@
+
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// This test only works with the GPU backend.
+
+#include "gm.h"
+
+#if SK_SUPPORT_GPU
+
+#include "GrContext.h"
+#include "GrTest.h"
+#include "effects/GrYUVtoRGBEffect.h"
+#include "SkBitmap.h"
+#include "SkGr.h"
+#include "SkGradientShader.h"
+
+namespace skiagm {
+/**
+ * This GM directly exercises GrYUVtoRGBEffect.
+ */
+class YUVtoRGBEffect : public GM {
+public:
+    YUVtoRGBEffect() {
+        this->setBGColor(0xFFFFFFFF);
+    }
+
+protected:
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("yuv_to_rgb_effect");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return SkISize::Make(334, 128);
+    }
+
+    virtual uint32_t onGetFlags() const SK_OVERRIDE {
+        // This is a GPU-specific GM.
+        return kGPUOnly_Flag;
+    }
+
+    virtual void onOnceBeforeDraw() SK_OVERRIDE {
+        SkImageInfo info = SkImageInfo::MakeA8(24, 24);
+        fBmp[0].allocPixels(info);
+        fBmp[1].allocPixels(info);
+        fBmp[2].allocPixels(info);
+        unsigned char* pixels[3];
+        for (int i = 0; i < 3; ++i) {
+            pixels[i] = (unsigned char*)fBmp[i].getPixels();
+        }
+        int color[] = {0, 85, 170};
+        const int limit[] = {255, 0, 255};
+        const int invl[]  = {0, 255, 0};
+        const int inc[]   = {1, -1, 1};
+        for (int j = 0; j < 576; ++j) {
+            for (int i = 0; i < 3; ++i) {
+                pixels[i][j] = (unsigned char)color[i];
+                color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i];
+            }
+        }
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
+        if (NULL == rt) {
+            return;
+        }
+        GrContext* context = rt->getContext();
+        if (NULL == context) {
+            return;
+        }
+
+        GrTestTarget tt;
+        context->getTestTarget(&tt);
+        if (NULL == tt.target()) {
+            SkDEBUGFAIL("Couldn't get Gr test target.");
+            return;
+        }
+
+        GrDrawState* drawState = tt.target()->drawState();
+
+        GrTexture* texture[3];
+        texture[0] = GrLockAndRefCachedBitmapTexture(context, fBmp[0], NULL);
+        texture[1] = GrLockAndRefCachedBitmapTexture(context, fBmp[1], NULL);
+        texture[2] = GrLockAndRefCachedBitmapTexture(context, fBmp[2], NULL);
+        if ((NULL == texture[0]) || (NULL == texture[1]) || (NULL == texture[2])) {
+            return;
+        }
+
+        static const SkScalar kDrawPad = 10.f;
+        static const SkScalar kTestPad = 10.f;
+        static const SkScalar kColorSpaceOffset = 64.f;
+
+        for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace;
+             ++space) {
+          SkRect renderRect = SkRect::MakeWH(SkIntToScalar(fBmp[0].width()),
+                                             SkIntToScalar(fBmp[0].height()));
+          renderRect.outset(kDrawPad, kDrawPad);
+
+          SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
+          SkScalar x = kDrawPad + kTestPad;
+
+          const int indices[6][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
+
+          for (int i = 0; i < 6; ++i) {
+              SkAutoTUnref<GrFragmentProcessor> fp(
+                          GrYUVtoRGBEffect::Create(texture[indices[i][0]],
+                                                   texture[indices[i][1]],
+                                                   texture[indices[i][2]],
+                                                   static_cast<SkYUVColorSpace>(space)));
+              if (fp) {
+                  SkMatrix viewMatrix;
+                  viewMatrix.setTranslate(x, y);
+                  drawState->reset(viewMatrix);
+                  drawState->setRenderTarget(rt);
+                  drawState->setColor(0xffffffff);
+                  drawState->addColorProcessor(fp);
+                  tt.target()->drawSimpleRect(renderRect);
+              }
+              x += renderRect.width() + kTestPad;
+          }
+        }
+
+        GrUnlockAndUnrefCachedBitmapTexture(texture[0]);
+        GrUnlockAndUnrefCachedBitmapTexture(texture[1]);
+        GrUnlockAndUnrefCachedBitmapTexture(texture[2]);
+    }
+
+private:
+    SkBitmap fBmp[3];
+
+    typedef GM INHERITED;
+};
+
+DEF_GM( return SkNEW(YUVtoRGBEffect); )
+}
+
+#endif
diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp
index abfc8b7..6f39f71 100644
--- a/gyp/SampleApp.gyp
+++ b/gyp/SampleApp.gyp
@@ -24,6 +24,7 @@
         'gmslides.gypi',
       ],
       'sources': [
+        '../gm/gm.cpp',
         '../samplecode/GMSampleView.h',
         '../samplecode/ClockFaceView.cpp',
         '../samplecode/OverView.cpp',
@@ -71,6 +72,7 @@
         '../samplecode/SampleHairCurves.cpp',
         '../samplecode/SampleHairline.cpp',
         '../samplecode/SampleHairModes.cpp',
+        '../samplecode/SampleIdentityScale.cpp',
         '../samplecode/SampleLayerMask.cpp',
         '../samplecode/SampleLayers.cpp',
         '../samplecode/SampleLCD.cpp',
@@ -134,9 +136,6 @@
         # Lua
         '../src/utils/SkLuaCanvas.cpp',
         '../src/utils/SkLua.cpp',
-
-        # tools
-        '../tools/sk_tool_utils.cpp',
       ],
       'sources!': [
         '../samplecode/SampleSkLayer.cpp', #relies on SkMatrix44 which doesn't compile
@@ -150,8 +149,9 @@
         'flags.gyp:flags',
         'lua.gyp:lua',
         'pdf.gyp:pdf',
-        'resources.gyp:resources',
         'skia_lib.gyp:skia_lib',
+        'tools.gyp:resources',
+        'tools.gyp:sk_tool_utils',
         'views.gyp:views',
         'views_animated.gyp:views_animated',
         'xml.gyp:xml',
@@ -213,6 +213,7 @@
           # TODO: This doesn't build properly yet, but it's getting there.
           'sources!': [
             '../samplecode/SampleDecode.cpp',
+            '../experimental/SimpleiOSApp/SimpleApp.mm',
           ],
           'sources': [
             '../src/views/mac/SkEventNotifier.mm',
@@ -239,7 +240,6 @@
             '../experimental/iOSSampleApp/iPhone/MainWindow_iPhone.xib',
 
             '../src/views/ios/SkOSWindow_iOS.mm',
-            '../src/utils/ios/SkImageDecoder_iOS.mm',
             '../src/utils/ios/SkStream_NSData.mm',
             # Not fully implemented yet
             # '../src/utils/ios/SkOSFile_iOS.mm',
diff --git a/gyp/apptype_console.gypi b/gyp/apptype_console.gypi
index cde8779..53cadf5 100644
--- a/gyp/apptype_console.gypi
+++ b/gyp/apptype_console.gypi
@@ -15,7 +15,7 @@
       [ 'skia_os == "android" and not skia_android_framework', {
         'dependencies': [
           'android_deps.gyp:Android_EntryPoint',
-          'android_system.gyp:skia_launcher',
+          'skia_launcher.gyp:skia_launcher',
         ],
       }],
       [ 'skia_os == "nacl"', {
@@ -27,24 +27,32 @@
         'target_conditions': [
           ['_type == "executable"', {
             'mac_bundle' : 1,
+            'sources': [
+              '../src/views/ios/SkOSWindow_iOS.mm',
+              '../src/views/mac/SkEventNotifier.mm',
+              '../experimental/iOSSampleApp/iPad/AppDelegate_iPad.mm',
+              '../experimental/iOSSampleApp/iPhone/AppDelegate_iPhone.mm',
+              '../experimental/iOSSampleApp/Shared/SkUIView.mm',
+              '../experimental/iOSSampleApp/Shared/skia_ios.mm',
+              '../experimental/SimpleiOSApp/SimpleApp.mm',
+            ],
+            'include_dirs' : [
+              '../experimental/iOSSampleApp/Shared',
+              '../include/views',
+              '../include/xml',
+              '../include/utils/mac',
+              '../src/views/mac',
+            ],
+            'xcode_config_file': '../experimental/iOSSampleApp/SkiOSSampleApp-Base.xcconfig',
+            'mac_bundle_resources' : [
+              '../experimental/SimpleiOSApp/iPad/MainWindow_iPad.xib',
+              '../experimental/SimpleiOSApp/iPhone/MainWindow_iPhone.xib',
+            ],
+            'xcode_settings' : {
+              'INFOPLIST_FILE' : '../experimental/SimpleiOSApp/tool-Info.plist',
+            },
           }],
         ],
-        'include_dirs' : [
-          '../experimental/iOSSampleApp/Shared',
-          '../include/views',
-          '../include/xml',
-          '../include/utils/mac',
-          '../src/views/mac',
-        ],
-        'sources': [
-          '../src/views/ios/SkOSWindow_iOS.mm',
-          '../src/views/mac/SkEventNotifier.mm',
-          '../experimental/iOSSampleApp/iPad/AppDelegate_iPad.mm',
-          '../experimental/iOSSampleApp/iPhone/AppDelegate_iPhone.mm',
-          '../experimental/iOSSampleApp/Shared/SkUIView.mm',
-          '../experimental/iOSSampleApp/Shared/skia_ios.mm',
-          '../experimental/SimpleiOSApp/SimpleApp.mm',
-        ],
         'dependencies': [
           'views.gyp:views',
           'xml.gyp:xml',
@@ -59,14 +67,6 @@
             '$(SDKROOT)/System/Library/Frameworks/UIKit.framework',
           ],
         },
-        'xcode_config_file': '../experimental/iOSSampleApp/SkiOSSampleApp-Base.xcconfig',
-        'mac_bundle_resources' : [
-          '../experimental/SimpleiOSApp/iPad/MainWindow_iPad.xib',
-          '../experimental/SimpleiOSApp/iPhone/MainWindow_iPhone.xib',
-        ],
-        'xcode_settings' : {
-          'INFOPLIST_FILE' : '../experimental/SimpleiOSApp/tool-Info.plist',
-        },
       }],
     ],
   },
diff --git a/gyp/bench.gyp b/gyp/bench.gyp
index 15927e6..26849d5 100644
--- a/gyp/bench.gyp
+++ b/gyp/bench.gyp
@@ -6,107 +6,34 @@
   ],
   'targets': [
     {
-      'target_name': 'bench',
+      'target_name': 'nanobench',
       'type': 'executable',
-      'dependencies': [
-        'bench_timer',
-        'crash_handler.gyp:CrashHandler',
-        'etc1.gyp:libetc1',
-        'flags.gyp:flags',
-        'jsoncpp.gyp:jsoncpp',
-        'resources.gyp:resources',
-        'skia_lib.gyp:skia_lib',
-      ],
       'sources': [
-        '../bench/BenchLogger.cpp',
-        '../bench/BenchLogger.h',
+        '../gm/gm.cpp',
         '../bench/GMBench.cpp',
-        '../bench/GMBench.h',
-        '../bench/ResultsWriter.cpp',
-        '../bench/benchmain.cpp',
-        '../tools/sk_tool_utils.cpp',
-      ],
-      'conditions': [
-        ['skia_gpu == 1',
-          {
-            'include_dirs' : [
-              '../src/gpu',
-            ],
-            'dependencies': [
-              'gputest.gyp:skgputest',
-            ],
-          },
-        ],
-        ['skia_android_framework == 1',
-          {
-            'libraries': [
-              '-lskia',
-            ],
-          },
-        ],
+        '../bench/RecordingBench.cpp',
+        '../bench/SKPBench.cpp',
+        '../bench/nanobench.cpp',
       ],
       'includes': [
         'bench.gypi',
         'gmslides.gypi',
       ],
-    },
-    {
-      'target_name' : 'bench_timer',
-      'type': 'static_library',
-      'sources': [
-        '../bench/BenchTimer.h',
-        '../bench/BenchTimer.cpp',
-        '../bench/BenchSysTimer_mach.h',
-        '../bench/BenchSysTimer_mach.cpp',
-        '../bench/BenchSysTimer_posix.h',
-        '../bench/BenchSysTimer_posix.cpp',
-        '../bench/BenchSysTimer_windows.h',
-        '../bench/BenchSysTimer_windows.cpp',
-      ],
-      'include_dirs': [
-        '../src/core',
-        '../src/gpu',
-        '../tools',
-      ],
-      'direct_dependent_settings': {
-        'include_dirs': ['../bench'],
-      },
       'dependencies': [
+        'flags.gyp:flags_common',
+        'jsoncpp.gyp:jsoncpp',
         'skia_lib.gyp:skia_lib',
+        'tools.gyp:crash_handler',
+        'tools.gyp:proc_stats',
+        'tools.gyp:timer',
       ],
       'conditions': [
-        [ 'skia_os not in ["mac", "ios"]', {
-          'sources!': [
-            '../bench/BenchSysTimer_mach.h',
-            '../bench/BenchSysTimer_mach.cpp',
-          ],
-        }],
-        [ 'skia_os not in ["linux", "freebsd", "openbsd", "solaris", "android", "chromeos"]', {
-          'sources!': [
-            '../bench/BenchSysTimer_posix.h',
-            '../bench/BenchSysTimer_posix.cpp',
-          ],
-        }],
-        [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris", "chromeos"]', {
-          'link_settings': {
-            'libraries': [
-              '-lrt',
-            ],
-          },
-        }],
-        [ 'skia_os != "win"', {
-          'sources!': [
-            '../bench/BenchSysTimer_windows.h',
-            '../bench/BenchSysTimer_windows.cpp',
-          ],
-        }],
-        ['skia_gpu == 1', {
-          'sources': [
-            '../bench/BenchGpuTimer_gl.h',
-            '../bench/BenchGpuTimer_gl.cpp',
+        ['skia_android_framework', {
+          'libraries': [
+            '-lskia',
           ],
         }],
       ],
-    }
+    },
   ],
 }
diff --git a/gyp/bench.gypi b/gyp/bench.gypi
index 06df30b..adb98a1 100644
--- a/gyp/bench.gypi
+++ b/gyp/bench.gypi
@@ -2,18 +2,28 @@
   'include_dirs': [
     '../src/core',
     '../src/effects',
+    '../src/gpu',
     '../src/utils',
     '../tools',
   ],
   'dependencies': [
+    'etc1.gyp:libetc1',
     'skia_lib.gyp:skia_lib',
+    'tools.gyp:resources',
+    'tools.gyp:sk_tool_utils',
+  ],
+  'conditions': [
+    ['skia_gpu == 1', {
+      'include_dirs': [ '../src/gpu' ],
+      'dependencies': [ 'gputest.gyp:skgputest' ],
+    }],
   ],
   'sources': [
     '../bench/Benchmark.cpp',
     '../bench/Benchmark.h',
 
     '../bench/AAClipBench.cpp',
-    '../bench/BicubicBench.cpp',
+    '../bench/AlternatingColorPatternBench.cpp',
     '../bench/BitmapBench.cpp',
     '../bench/BitmapRectBench.cpp',
     '../bench/BitmapScaleBench.cpp',
@@ -30,7 +40,6 @@
     '../bench/CoverageBench.cpp',
     '../bench/DashBench.cpp',
     '../bench/DecodeBench.cpp',
-    '../bench/DeferredCanvasBench.cpp',
     '../bench/DeferredSurfaceCopyBench.cpp',
     '../bench/DisplacementBench.cpp',
     '../bench/ETCBitmapBench.cpp',
@@ -60,14 +69,16 @@
     '../bench/MergeBench.cpp',
     '../bench/MorphologyBench.cpp',
     '../bench/MutexBench.cpp',
+    '../bench/PatchBench.cpp',
+    '../bench/PatchGridBench.cpp',
     '../bench/PathBench.cpp',
     '../bench/PathIterBench.cpp',
     '../bench/PathUtilsBench.cpp',
     '../bench/PerlinNoiseBench.cpp',
+    '../bench/PictureNestingBench.cpp',
     '../bench/PicturePlaybackBench.cpp',
     '../bench/PictureRecordBench.cpp',
     '../bench/PremulAndUnpremulAlphaOpsBench.cpp',
-    '../bench/QuadTreeBench.cpp',
     '../bench/RTreeBench.cpp',
     '../bench/ReadPixBench.cpp',
     '../bench/RectBench.cpp',
@@ -77,11 +88,11 @@
     '../bench/RegionBench.cpp',
     '../bench/RegionContainBench.cpp',
     '../bench/RepeatTileBench.cpp',
+    '../bench/RotatedRectBench.cpp',
     '../bench/ScalarBench.cpp',
     '../bench/ShaderMaskBench.cpp',
     '../bench/SkipZeroesBench.cpp',
     '../bench/SortBench.cpp',
-    '../bench/StackBench.cpp',
     '../bench/StrokeBench.cpp',
     '../bench/TableBench.cpp',
     '../bench/TextBench.cpp',
diff --git a/gyp/canvas_state_lib.gyp b/gyp/canvas_state_lib.gyp
new file mode 100644
index 0000000..1bb2fe4
--- /dev/null
+++ b/gyp/canvas_state_lib.gyp
@@ -0,0 +1,37 @@
+# Building test for running CanvasState
+
+# HOW TO USE:
+# This target is not included in normal Skia builds. In order to build it,
+# you need to run gyp_skia on this file. This target also requires the
+# variable skia_pic to be used during building:
+#
+# GYP_DEFINES=skia_pic=1 ./gyp_skia gyp/canvas_state_lib.gyp
+# ninja -C out/Debug canvas_state_lib
+#
+# This will create the shared library libcanvas_state_lib.so. That can
+# be passed to tests to test passing an SkCanvas between versions of
+# Skia. See tests/CanvasStateTest.cpp for more info.
+{
+  'targets' : [
+    {
+      'target_name' : 'canvas_state_lib',
+      'type' : 'shared_library',
+      # FIXME: Is there a way to ensure that -fPIC was used for skia_lib?
+      'dependencies' : [ 'skia_lib.gyp:skia_lib'],
+      'sources' : [
+        '../tests/CanvasStateHelpers.cpp',
+      ],
+      'cflags' : [
+        '-fPIC',
+      ],
+    },
+    {
+        # Dummy 'most' target, since gyp_skia sets 'most' to be the default.
+        'target_name' : 'most',
+        'type'        : 'none',
+        'dependencies' : [
+          'canvas_state_lib',
+        ],
+    }
+  ],
+}
diff --git a/gyp/common.gypi b/gyp/common.gypi
index 0846fef..54d81cf 100644
--- a/gyp/common.gypi
+++ b/gyp/common.gypi
@@ -16,6 +16,7 @@
       'SK_GAMMA_SRGB',
       'SK_GAMMA_APPLY_TO_A8',
       'SK_SCALAR_TO_FLOAT_EXCLUDED',  # temporary to allow Chrome to call SkFloatToScalar
+      # 'SK_USE_DISCARDABLE_SCALEDIMAGECACHE',  # TODO(reed): Re-enable when tests don't crash with this.
     ],
 
     # Validate the 'skia_os' setting against 'OS', because only certain
@@ -53,12 +54,10 @@
         {
           'defines': [
             'SK_SCALAR_IS_FLOAT',
-            'SK_CAN_USE_FLOAT',
           ],
         }, { # else, skia_scalar != "float"
           'defines': [
             'SK_SCALAR_IS_FIXED',
-            'SK_CAN_USE_FLOAT',  # we can still use floats along the way
           ],
         }
       ],
@@ -94,22 +93,11 @@
         # one makefile and allow someone to add SK_DEBUG etc for their own
         # debugging purposes.
         'configurations': {
-          'Debug': {
-            'defines': [
-              'SK_DEBUG',
-              'SK_DEVELOPER=1',
-            ],
-          },
-          'Release': {
-            'defines': [
-              'SK_RELEASE',
-            ],
-          },
+          'Debug':   { 'defines': [ 'SK_DEVELOPER=1' ] },
+          'Release': { 'defines': [ 'NDEBUG' ] },
           'Release_Developer': {
             'inherit_from': ['Release'],
-            'defines': [
-              'SK_DEVELOPER=1',
-            ],
+            'defines': [ 'SK_DEVELOPER=1' ],
           },
         },
       }],
diff --git a/gyp/common_conditions.gypi b/gyp/common_conditions.gypi
index ed54a58..7fe49d6 100644
--- a/gyp/common_conditions.gypi
+++ b/gyp/common_conditions.gypi
@@ -6,12 +6,27 @@
     'SK_SUPPORT_GPU=<(skia_gpu)',
     'SK_SUPPORT_OPENCL=<(skia_opencl)',
     'SK_FORCE_DISTANCEFIELD_FONTS=<(skia_force_distancefield_fonts)',
+    'SK_PICTURE_USE_SK_RECORD',
+    'SK_PICTURE_OPTIMIZE_SK_RECORD',
   ],
   'conditions' : [
-    [ 'skia_arch_type == "arm64"', {
-      'cflags': [
-        '-ffp-contract=off',
-      ],
+    ['skia_pic', {
+     'cflags': [
+       '-fPIC',
+     ],
+     'conditions' : [
+      # FIXME: The reason we don't do this on Android is due to the way
+      # we build the executables/skia_launcher on Android. See
+      # https://codereview.chromium.org/406613003/diff/1/gyp/common_conditions.gypi#newcode455
+      ['skia_os != "android"', {
+       'target_conditions': [
+         [ '_type == "executable"', {
+           'cflags': [ '-fPIE' ],
+           'ldflags': [ '-pie' ],
+         }],
+       ],
+      }],
+     ],
     }],
 
     # As of M35, Chrome requires SSE2 on x86 (and SSSE3 on Mac).
@@ -30,10 +45,11 @@
           'GR_GL_FUNCTION_TYPE=__stdcall',
         ],
         'msvs_disabled_warnings': [
-            4345,  # This is an FYI about a behavior change from long ago.  Chrome stifles it too.
+            4275,  # An exported class was derived from a class that was not exported
+            4345,  # This is an FYI about a behavior change from long ago. Chrome stifles it too.
+            4355,  # 'this' used in base member initializer list. Off by default in newer compilers.
         ],
         'msvs_cygwin_shell': 0,
-        'msvs_disabled_warnings': [4275],
         'msvs_settings': {
           'VCCLCompilerTool': {
             'WarningLevel': '3',
@@ -86,7 +102,6 @@
               'VCCLCompilerTool': {
                 'DebugInformationFormat': '3',      # programDatabase (/Zi)
                 'Optimization': '<(skia_release_optimization_level)',
-                'WholeProgramOptimization': 'true', #/GL
                # Changing the floating point model requires rebaseling gm images
                #'FloatingPointModel': '2',          # fast (/fp:fast)
                 'FavorSizeOrSpeed': '1',            # speed (/Ot)
@@ -97,10 +112,6 @@
               },
               'VCLinkerTool': {
                 'GenerateDebugInformation': 'true', # /DEBUG
-                'LinkTimeCodeGeneration': '1',      # useLinkTimeCodeGeneration /LTCG
-              },
-              'VCLibrarianTool': {
-                'LinkTimeCodeGeneration': 'true',   # useLinkTimeCodeGeneration /LTCG
               },
             },
           },
@@ -154,6 +165,23 @@
               },
             },
           }],
+          [ 'skia_win_ltcg', {
+            'configurations': {
+              'Release': {
+                'msvs_settings': {
+                  'VCCLCompilerTool': {
+                    'WholeProgramOptimization': 'true', #/GL
+                  },
+                  'VCLinkerTool': {
+                    'LinkTimeCodeGeneration': '1',      # useLinkTimeCodeGeneration /LTCG
+                  },
+                  'VCLibrarianTool': {
+                    'LinkTimeCodeGeneration': 'true',   # useLinkTimeCodeGeneration /LTCG
+                  },
+                },
+              },
+            },
+          }],
         ],
       },
     ],
@@ -171,6 +199,7 @@
           '-Winit-self',
           '-Wpointer-arith',
 
+          '-Wno-c++11-extensions',
           '-Wno-unused-parameter',
         ],
         'cflags_cc': [
@@ -179,10 +208,24 @@
           '-Wno-invalid-offsetof',  # GCC <4.6 is old-school strict about what is POD.
         ],
         'conditions': [
-          [ 'skia_android_framework==0', {
-            'cflags': [
-              # This flag is not supported by Android build system.
-              '-Wno-c++11-extensions',
+          [ 'skia_os != "chromeos"', {
+            'conditions': [
+              [ 'skia_arch_width == 64 and skia_arch_type == "x86"', {
+                'cflags': [
+                  '-m64',
+                ],
+                'ldflags': [
+                  '-m64',
+                ],
+              }],
+              [ 'skia_arch_width == 32 and skia_arch_type == "x86"', {
+                'cflags': [
+                  '-m32',
+                ],
+                'ldflags': [
+                  '-m32',
+                ],
+              }],
             ],
           }],
           [ 'skia_warnings_as_errors', {
@@ -228,7 +271,7 @@
             'conditions': [
               [ 'arm_neon == 1', {
                 'defines': [
-                  '__ARM_HAVE_NEON',
+                  'SK_ARM_HAS_NEON',
                 ],
                 'cflags': [
                   '-mfpu=neon',
@@ -236,7 +279,7 @@
               }],
               [ 'arm_neon_optional == 1', {
                 'defines': [
-                  '__ARM_HAVE_OPTIONAL_NEON_SUPPORT',
+                  'SK_ARM_HAS_OPTIONAL_NEON',
                 ],
               }],
               [ 'skia_os != "chromeos"', {
@@ -260,13 +303,17 @@
                     'cflags': [
                       '-mdsp',
                     ],
+                    'defines': [
+                      'SK_MIPS_HAS_DSP',
+                    ],
                   }],
                   [ 'mips_dsp == 2', {
                     'cflags': [
                       '-mdspr2',
                     ],
                     'defines': [
-                      '__MIPS_HAVE_DSPR2',
+                      'SK_MIPS_HAS_DSP',
+                      'SK_MIPS_HAS_DSPR2',
                     ],
                   }],
                 ],
@@ -305,8 +352,6 @@
         '-mthumb',
         '-mfpu=neon',
         '-mfloat-abi=softfp',
-        # This flag is not supported by Android build system.
-        '-Wno-c++11-extensions',
         '-fno-exceptions',
         '-fstrict-aliasing',
         # Remove flags to turn on warnings, since most people building Android
@@ -332,20 +377,10 @@
         # Optimizations for chromium (m30)
         'GR_GL_CUSTOM_SETUP_HEADER "gl/GrGLConfig_chrome.h"',
         'IGNORE_ROT_AA_RECT_OPT',
-        # Disable this check because it is too strict for some chromium-specific
-        # subclasses of SkPixelRef. See bug: crbug.com/171776.
-        'SK_DISABLE_PIXELREF_LOCKCOUNT_BALANCE_CHECK',
         'SkLONGLONG int64_t',
         'SK_DEFAULT_FONT_CACHE_LIMIT   (768 * 1024)',
-        'SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h"',
-        'SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_pthread.h"',
-        # Still need to switch Android to the new name for N32.
-        'kNative_8888_SkColorType kN32_SkColorType',
-        # Needed until we fix skbug.com/2440.
-        'SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG',
         # Transitional, for deprecated SkCanvas::SaveFlags methods.
         'SK_ATTR_DEPRECATED=SK_NOTHING_ARG1',
-        'SK_SUPPORT_LEGACY_SHADER_LOCALMATRIX',
         'SK_DEFAULT_GLOBAL_DISCARDABLE_MEMORY_POOL_SIZE (512 * 1024)',
         'SK_IGNORE_ETC1_SUPPORT',
         # Defines from skia_for_android_framework_defines.gypi
@@ -375,9 +410,6 @@
         },
         'conditions' : [
           [ 'skia_shared_lib', {
-            'cflags': [
-              '-fPIC',
-            ],
             'defines': [
               'SKIA_DLL',
               'SKIA_IMPLEMENTATION=1',
@@ -402,33 +434,6 @@
                 '-L<(nacl_sdk_root)/ports/lib/newlib_x86_<(skia_arch_width)/Release',
               ],
             },
-          }, { # skia_os != "nacl"
-            'link_settings': {
-              'ldflags': [
-                '-lstdc++',
-                '-lm',
-              ],
-            },
-          }],
-          [ 'skia_os != "chromeos"', {
-            'conditions': [
-              [ 'skia_arch_width == 64 and skia_arch_type == "x86"', {
-                'cflags': [
-                  '-m64',
-                ],
-                'ldflags': [
-                  '-m64',
-                ],
-              }],
-              [ 'skia_arch_width == 32 and skia_arch_type == "x86"', {
-                'cflags': [
-                  '-m32',
-                ],
-                'ldflags': [
-                  '-m32',
-                ],
-              }],
-            ],
           }],
           # Enable asan, tsan, etc.
           [ 'skia_sanitizer', {
@@ -440,31 +445,24 @@
             ],
             'conditions' : [
               [ 'skia_sanitizer == "thread"', {
-                'defines': [ 'DYNAMIC_ANNOTATIONS_ENABLED=1' ],
-                'cflags': [ '-fPIC' ],
-                'target_conditions': [
-                  [ '_type == "executable"', {
-                    'cflags': [ '-fPIE' ],
-                    'ldflags': [ '-pie' ],
-                  }],
-                ],
+                'defines': [ 'SK_DYNAMIC_ANNOTATIONS_ENABLED=1' ],
               }],
               [ 'skia_sanitizer == "undefined"', {
-                'cflags': [ '-fPIC' ],
                 'cflags_cc!': ['-fno-rtti'],
-                'target_conditions': [
-                  [ '_type == "executable"', {
-                    'cflags': [ '-fPIE' ],
-                    'ldflags': [ '-pie' ],
-                  }],
-                ],
               }],
             ],
           }],
           [ 'skia_clang_build', {
+            'cflags_cc': [
+                # Build in C++11 mode to make sure we'll have an easy time switching.
+                '-std=c++11',
+                '-Wno-unknown-warning-option',  # Allows unknown warnings.
+                '-Wno-deprecated',              # From Qt, via debugger (older Clang).
+                '-Wno-deprecated-register',     # From Qt, via debugger (newer Clang).
+            ],
             'cflags': [
-              # Extra warnings we like but that only Clang knows about.
-              '-Wstring-conversion',
+                # Extra warnings we like but that only Clang knows about.
+                '-Wstring-conversion',
             ],
             'cflags!': [
                 '-mfpmath=sse',  # Clang doesn't need to be told this, and sometimes gets confused.
@@ -479,32 +477,7 @@
 
     [ 'skia_os == "mac"',
       {
-        'defines': [
-          'SK_BUILD_FOR_MAC',
-        ],
-        'conditions' : [
-          [ 'skia_arch_width == 64', {
-            'xcode_settings': {
-              'ARCHS': ['x86_64'],
-            },
-          }],
-          [ 'skia_arch_width == 32', {
-            'xcode_settings': {
-              'ARCHS': ['i386'],
-            },
-          }],
-          [ 'skia_warnings_as_errors', {
-            'xcode_settings': {
-              'OTHER_CPLUSPLUSFLAGS': [
-                '-Werror',
-                '-Wall',
-                '-Wextra',
-                '-Wno-unused-parameter',
-                '-Wno-uninitialized',  # Disabled because we think GCC 4.2 is bad at this.
-              ],
-            },
-          }],
-        ],
+        'defines': [ 'SK_BUILD_FOR_MAC' ],
         'configurations': {
           'Coverage': {
             'xcode_settings': {
@@ -514,51 +487,32 @@
             },
           },
           'Debug': {
-            'xcode_settings': {
-              'GCC_OPTIMIZATION_LEVEL': '0',
-            },
+            'xcode_settings': { 'GCC_OPTIMIZATION_LEVEL': '0' },
           },
           'Release': {
-            'xcode_settings': {
-              'GCC_OPTIMIZATION_LEVEL': '<(skia_release_optimization_level)',
-            },
+            'xcode_settings': { 'GCC_OPTIMIZATION_LEVEL': '<(skia_release_optimization_level)', },
             'defines': [ 'NDEBUG' ],
           },
         },
         'xcode_settings': {
-          'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO',
           'conditions': [
+            [ 'skia_warnings_as_errors', { 'GCC_TREAT_WARNINGS_AS_ERRORS': 'YES' }],
+            [ 'skia_arch_width == 32', { 'ARCHS': ['i386']   }],
+            [ 'skia_arch_width == 64', { 'ARCHS': ['x86_64'] }],
             [ 'skia_osx_deployment_target==""', {
-              'MACOSX_DEPLOYMENT_TARGET': '10.6', # -mmacos-version-min, passed in environment to ld.
+              'MACOSX_DEPLOYMENT_TARGET': '10.6', # -mmacos-version-min, passed in env to ld.
             }, {
               'MACOSX_DEPLOYMENT_TARGET': '<(skia_osx_deployment_target)',
             }],
           ],
-# trying to get this to work, but it needs clang I think...
-#          'WARNING_CFLAGS': '-Wexit-time-destructors',
-          'CLANG_WARN_CXX0X_EXTENSIONS': 'NO',
-          'GCC_WARN_64_TO_32_BIT_CONVERSION': 'YES',
-          'GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS': 'YES',
-          'GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO': 'YES',
-          'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES',
-          'GCC_WARN_ABOUT_MISSING_PROTOTYPES': 'YES',
-          'GCC_WARN_ABOUT_POINTER_SIGNEDNESS': 'YES',
-          'GCC_WARN_ABOUT_RETURN_TYPE': 'YES',
-          'GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL': 'YES',
-          'GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED': 'YES',
-          'GCC_WARN_MISSING_PARENTHESES': 'YES',
-          'GCC_WARN_PROTOTYPE_CONVERSION': 'YES',
-          'GCC_WARN_SIGN_COMPARE': 'YES',
-          'GCC_WARN_TYPECHECK_CALLS_TO_PRINTF': 'YES',
-          'GCC_WARN_UNKNOWN_PRAGMAS': 'YES',
-          'GCC_WARN_UNUSED_FUNCTION': 'YES',
-          'GCC_WARN_UNUSED_LABEL': 'YES',
-          'GCC_WARN_UNUSED_VALUE': 'YES',
-          'GCC_WARN_UNUSED_VARIABLE': 'YES',
-          'OTHER_CPLUSPLUSFLAGS': [
-            '-mssse3',
-            '-fvisibility=hidden',
-            '-fvisibility-inlines-hidden',
+          'GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS': 'YES',  # -mssse3
+          'GCC_SYMBOLS_PRIVATE_EXTERN':                'NO',   # -fvisibility=hidden
+          'GCC_INLINES_ARE_PRIVATE_EXTERN':            'NO',   # -fvisibility-inlines-hidden
+          'WARNING_CFLAGS': [
+            '-Wall',
+            '-Wextra',
+            '-Wno-unused-parameter',
+            '-Wno-uninitialized',  # Disabled because we think GCC 4.2 is bad at this.
           ],
         },
       },
@@ -611,7 +565,6 @@
       {
         'defines': [
           'SK_BUILD_FOR_ANDROID',
-          'SK_FONTHOST_DOES_NOT_USE_FONTMGR',
 
           # Android Text Tuning
           'SK_GAMMA_EXPONENT=1.4',
@@ -627,34 +580,31 @@
           },
           'Release': {
             'cflags': ['-O2'],
-            'defines': [ 'NDEBUG' ],
           },
         },
         'libraries': [
-          '-lstdc++',
-          '-lm',
           '-llog',
         ],
         'cflags': [
           '-fuse-ld=gold',
         ],
         'conditions': [
-          [ 'skia_android_framework', {
-            'libraries!': [
-              '-lstdc++',
-              '-lm',
+          [ 'skia_arch_type == "x86"', {
+            'cflags': [
+              '-mssse3',
             ],
+          }],
+          [ 'skia_android_framework', {
             'cflags!': [
               '-fuse-ld=gold',
             ],
           }],
           [ 'skia_shared_lib', {
-            'cflags': [
-              '-fPIC',
-            ],
             'defines': [
               'SKIA_DLL',
               'SKIA_IMPLEMENTATION=1',
+              # Needed until we fix skbug.com/2440.
+              'SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG',
             ],
           }],
           [ 'skia_profile_enabled == 1', {
@@ -678,6 +628,10 @@
       ],
     }],
 
+    [ 'skia_is_bot', {
+      'defines': [ 'SK_CRASH_HANDLER' ],
+    }],
+
   ], # end 'conditions'
   # The Xcode SYMROOT must be at the root. See build/common.gypi in chromium for more details
   'xcode_settings': {
diff --git a/gyp/common_variables.gypi b/gyp/common_variables.gypi
index c414c75..6d791c9 100644
--- a/gyp/common_variables.gypi
+++ b/gyp/common_variables.gypi
@@ -139,7 +139,7 @@
       'skia_resource_cache_mb_limit%': 0,
       'skia_resource_cache_count_limit%': 0,
       'skia_angle%': 0,
-      'skia_directwrite%': 0,
+      'skia_gdi%': 0,
       'skia_gpu%': 1,
       'skia_osx_deployment_target%': '',
       'skia_profile_enabled%': 0,
@@ -180,6 +180,12 @@
         'skia_clang_build%': 0,
         'skia_keep_frame_pointer%': 0,
       }],
+      [ 'skia_shared_lib or skia_sanitizer or skia_os == "android"', {
+          'skia_pic%' : 1,
+        }, {
+          'skia_pic%' : 0,
+        }
+      ],
     ],
 
     # Re-define all variables defined within the level-2 'variables' dict,
@@ -211,9 +217,10 @@
     'skia_arch_width%': '<(skia_arch_width)',
     'skia_arch_type%': '<(skia_arch_type)',
     'skia_chrome_utils%': '<(skia_chrome_utils)',
-    'skia_directwrite%': '<(skia_directwrite)',
+    'skia_gdi%': '<(skia_gdi)',
     'skia_gpu%': '<(skia_gpu)',
     'skia_win_exceptions%': 0,
+    'skia_win_ltcg%': 1,
     'skia_osx_deployment_target%': '<(skia_osx_deployment_target)',
     'skia_profile_enabled%': '<(skia_profile_enabled)',
     'skia_shared_lib%': '<(skia_shared_lib)',
@@ -225,6 +232,7 @@
     'skia_run_pdfviewer_in_gm%': 0,
     'skia_disable_inlining%': 0,
     'skia_moz2d%': 0,
+    'skia_is_bot%': '<!(python -c "import os; print os.environ.get(\'CHROME_HEADLESS\', 0)")',
 
     # These are referenced by our .gypi files that list files (e.g. core.gypi)
     #
diff --git a/gyp/core.gyp b/gyp/core.gyp
index 64cc79b..afbc78a 100644
--- a/gyp/core.gyp
+++ b/gyp/core.gyp
@@ -20,6 +20,7 @@
         '../include/ports',
         '../include/utils',
         '../include/xml',
+        '../include/images',
         '../src/core',
         '../src/sfnt',
         '../src/image',
diff --git a/gyp/core.gypi b/gyp/core.gypi
index e1bdbd5..71d812b 100644
--- a/gyp/core.gypi
+++ b/gyp/core.gypi
@@ -19,6 +19,7 @@
         '<(skia_src_path)/core/SkBBoxHierarchyRecord.cpp',
         '<(skia_src_path)/core/SkBBoxHierarchyRecord.h',
         '<(skia_src_path)/core/SkBitmap.cpp',
+        '<(skia_src_path)/core/SkBitmapCache.cpp',
         '<(skia_src_path)/core/SkBitmapDevice.cpp',
         '<(skia_src_path)/core/SkBitmapFilter.h',
         '<(skia_src_path)/core/SkBitmapFilter.cpp',
@@ -66,6 +67,7 @@
         '<(skia_src_path)/core/SkDevice.cpp',
         '<(skia_src_path)/core/SkDeviceLooper.cpp',
         '<(skia_src_path)/core/SkDeviceProfile.cpp',
+        '<(skia_src_path)/core/SkDeviceProperties.h',
         '<(skia_src_path)/lazy/SkDiscardableMemoryPool.cpp',
         '<(skia_src_path)/lazy/SkDiscardablePixelRef.cpp',
         '<(skia_src_path)/core/SkDistanceFieldGen.cpp',
@@ -112,14 +114,13 @@
         '<(skia_src_path)/core/SkMaskGamma.h',
         '<(skia_src_path)/core/SkMath.cpp',
         '<(skia_src_path)/core/SkMatrix.cpp',
-        '<(skia_src_path)/core/SkMatrixClipStateMgr.cpp',
-        '<(skia_src_path)/core/SkMatrixClipStateMgr.h',
         '<(skia_src_path)/core/SkMessageBus.h',
         '<(skia_src_path)/core/SkMetaData.cpp',
+        '<(skia_src_path)/core/SkMiniData.cpp',
         '<(skia_src_path)/core/SkMipMap.cpp',
+        '<(skia_src_path)/core/SkMultiPictureDraw.cpp',
         '<(skia_src_path)/core/SkPackBits.cpp',
         '<(skia_src_path)/core/SkPaint.cpp',
-        '<(skia_src_path)/core/SkPaintOptionsAndroid.cpp',
         '<(skia_src_path)/core/SkPaintPriv.cpp',
         '<(skia_src_path)/core/SkPaintPriv.h',
         '<(skia_src_path)/core/SkPath.cpp',
@@ -129,6 +130,10 @@
         '<(skia_src_path)/core/SkPathMeasure.cpp',
         '<(skia_src_path)/core/SkPathRef.cpp',
         '<(skia_src_path)/core/SkPicture.cpp',
+        '<(skia_src_path)/core/SkPictureContentInfo.cpp',
+        '<(skia_src_path)/core/SkPictureContentInfo.h',
+        '<(skia_src_path)/core/SkPictureData.cpp',
+        '<(skia_src_path)/core/SkPictureData.h',
         '<(skia_src_path)/core/SkPictureFlat.cpp',
         '<(skia_src_path)/core/SkPictureFlat.h',
         '<(skia_src_path)/core/SkPicturePlayback.cpp',
@@ -146,11 +151,11 @@
         '<(skia_src_path)/core/SkPtrRecorder.cpp',
         '<(skia_src_path)/core/SkQuadClipper.cpp',
         '<(skia_src_path)/core/SkQuadClipper.h',
-        '<(skia_src_path)/core/SkQuadTree.cpp',
-        '<(skia_src_path)/core/SkQuadTree.h',
         '<(skia_src_path)/core/SkRasterClip.cpp',
         '<(skia_src_path)/core/SkRasterizer.cpp',
+        '<(skia_src_path)/core/SkReadBuffer.h',
         '<(skia_src_path)/core/SkReadBuffer.cpp',
+        '<(skia_src_path)/core/SkReader32.h',
         '<(skia_src_path)/core/SkRecordDraw.cpp',
         '<(skia_src_path)/core/SkRecordOpts.cpp',
         '<(skia_src_path)/core/SkRecorder.cpp',
@@ -160,10 +165,10 @@
         '<(skia_src_path)/core/SkRegion.cpp',
         '<(skia_src_path)/core/SkRegionPriv.h',
         '<(skia_src_path)/core/SkRegion_path.cpp',
+        '<(skia_src_path)/core/SkResourceCache.cpp',
         '<(skia_src_path)/core/SkRRect.cpp',
         '<(skia_src_path)/core/SkRTree.h',
         '<(skia_src_path)/core/SkRTree.cpp',
-        '<(skia_src_path)/core/SkScaledImageCache.cpp',
         '<(skia_src_path)/core/SkScalar.cpp',
         '<(skia_src_path)/core/SkScalerContext.cpp',
         '<(skia_src_path)/core/SkScalerContext.h',
@@ -181,6 +186,7 @@
         '<(skia_src_path)/core/SkSpriteBlitter.h',
         '<(skia_src_path)/core/SkSpriteBlitterTemplate.h',
         '<(skia_src_path)/core/SkStream.cpp',
+        '<(skia_src_path)/core/SkStreamPriv.h',
         '<(skia_src_path)/core/SkString.cpp',
         '<(skia_src_path)/core/SkStringUtils.cpp',
         '<(skia_src_path)/core/SkStroke.h',
@@ -188,6 +194,7 @@
         '<(skia_src_path)/core/SkStrokeRec.cpp',
         '<(skia_src_path)/core/SkStrokerPriv.cpp',
         '<(skia_src_path)/core/SkStrokerPriv.h',
+        '<(skia_src_path)/core/SkTextBlob.cpp',
         '<(skia_src_path)/core/SkTextFormatParams.h',
         '<(skia_src_path)/core/SkTextMapStateProc.h',
         '<(skia_src_path)/core/SkTileGrid.cpp',
@@ -212,7 +219,6 @@
 
         '<(skia_src_path)/image/SkImage.cpp',
         '<(skia_src_path)/image/SkImagePriv.cpp',
-        '<(skia_src_path)/image/SkImage_Codec.cpp',
 #        '<(skia_src_path)/image/SkImage_Gpu.cpp',
         '<(skia_src_path)/image/SkImage_Raster.cpp',
         '<(skia_src_path)/image/SkSurface.cpp',
@@ -229,7 +235,6 @@
         '<(skia_include_path)/core/SkBitmapDevice.h',
         '<(skia_include_path)/core/SkBlitRow.h',
         '<(skia_include_path)/core/SkCanvas.h',
-        '<(skia_include_path)/core/SkChecksum.h',
         '<(skia_include_path)/core/SkChunkAlloc.h',
         '<(skia_include_path)/core/SkClipStack.h',
         '<(skia_include_path)/core/SkColor.h',
@@ -240,7 +245,6 @@
         '<(skia_include_path)/core/SkData.h',
         '<(skia_include_path)/core/SkDeque.h',
         '<(skia_include_path)/core/SkDevice.h',
-        '<(skia_include_path)/core/SkDeviceProperties.h',
         '<(skia_include_path)/core/SkDither.h',
         '<(skia_include_path)/core/SkDraw.h',
         '<(skia_include_path)/core/SkDrawFilter.h',
@@ -266,6 +270,7 @@
         '<(skia_include_path)/core/SkMath.h',
         '<(skia_include_path)/core/SkMatrix.h',
         '<(skia_include_path)/core/SkMetaData.h',
+        '<(skia_include_path)/core/SkMultiPictureDraw.h',
         '<(skia_include_path)/core/SkOnce.h',
         '<(skia_include_path)/core/SkOSFile.h',
         '<(skia_include_path)/core/SkPackBits.h',
@@ -280,7 +285,6 @@
         '<(skia_include_path)/core/SkPoint.h',
         '<(skia_include_path)/core/SkPreConfig.h',
         '<(skia_include_path)/core/SkRasterizer.h',
-        '<(skia_include_path)/core/SkReader32.h',
         '<(skia_include_path)/core/SkRect.h',
         '<(skia_include_path)/core/SkRefCnt.h',
         '<(skia_include_path)/core/SkRegion.h',
@@ -299,6 +303,7 @@
         '<(skia_include_path)/core/SkTRegistry.h',
         '<(skia_include_path)/core/SkTSearch.h',
         '<(skia_include_path)/core/SkTemplates.h',
+        '<(skia_include_path)/core/SkTextBlob.h',
         '<(skia_include_path)/core/SkThread.h',
         '<(skia_include_path)/core/SkTime.h',
         '<(skia_include_path)/core/SkTLazy.h',
@@ -340,6 +345,7 @@
         '<(skia_src_path)/pathops/SkPathOpsQuad.cpp',
         '<(skia_src_path)/pathops/SkPathOpsRect.cpp',
         '<(skia_src_path)/pathops/SkPathOpsSimplify.cpp',
+        '<(skia_src_path)/pathops/SkPathOpsTightBounds.cpp',
         '<(skia_src_path)/pathops/SkPathOpsTriangle.cpp',
         '<(skia_src_path)/pathops/SkPathOpsTypes.cpp',
         '<(skia_src_path)/pathops/SkPathWriter.cpp',
diff --git a/gyp/crash_handler.gyp b/gyp/crash_handler.gyp
deleted file mode 100644
index 7e3599c..0000000
--- a/gyp/crash_handler.gyp
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  'targets': [{
-      'target_name': 'CrashHandler',
-          'type': 'static_library',
-          'sources': [ '../tools/CrashHandler.cpp' ],
-          'dependencies': [ 'skia_lib.gyp:skia_lib' ],
-          'direct_dependent_settings': {
-              'include_dirs': [ '../tools' ],
-          },
-          'all_dependent_settings': {
-              'msvs_settings': {
-                  'VCLinkerTool': {
-                      'AdditionalDependencies': [ 'Dbghelp.lib' ],
-                  }
-              },
-          }
-  }]
-}
diff --git a/gyp/debugger.gyp b/gyp/debugger.gyp
index 84f0397..4add743 100644
--- a/gyp/debugger.gyp
+++ b/gyp/debugger.gyp
@@ -96,8 +96,8 @@
       ],
       'dependencies': [
         'skia_lib.gyp:skia_lib',
-        'bench.gyp:bench_timer',
         'tools.gyp:picture_renderer',
+        'tools.gyp:timer',
       ],
       'conditions': [
         [ 'skia_os == "nacl"', {
diff --git a/gyp/dm.gyp b/gyp/dm.gyp
index f69ffe5..e4d6bd6 100644
--- a/gyp/dm.gyp
+++ b/gyp/dm.gyp
@@ -1,66 +1,12 @@
 # GYP for "dm" (Diamond Master, a.k.a Dungeon master, a.k.a GM 2).
-# vim: set expandtab tabstop=4 shiftwidth=4
 {
     'includes': [ 'apptype_console.gypi' ],
 
     'targets': [{
         'target_name': 'dm',
         'type': 'executable',
-        'include_dirs': [
-            '../bench',
-            '../dm',
-            '../gm',
-            '../tests',
-            '../src/images',
-            '../src/lazy',
-            '../src/core',
-            '../src/effects',
-            '../src/pipe/utils/',
-            '../src/utils',
-            '../src/utils/debugger',
-            '../tools',
-        ],
         'includes': [
-            'bench.gypi',
-            'gmslides.gypi',
-            'pathops_unittest.gypi',
-            'tests.gypi',
-        ],
-        'sources': [
-            '../dm/DM.cpp',
-            '../dm/DMBenchTask.cpp',
-            '../dm/DMCpuGMTask.cpp',
-            '../dm/DMExpectationsTask.cpp',
-            '../dm/DMGpuGMTask.cpp',
-            '../dm/DMPDFRasterizeTask.cpp',
-            '../dm/DMPDFTask.cpp',
-            '../dm/DMPipeTask.cpp',
-            '../dm/DMQuiltTask.cpp',
-            '../dm/DMRecordTask.cpp',
-            '../dm/DMReplayTask.cpp',
-            '../dm/DMReporter.cpp',
-            '../dm/DMSKPTask.cpp',
-            '../dm/DMSerializeTask.cpp',
-            '../dm/DMTask.cpp',
-            '../dm/DMTaskRunner.cpp',
-            '../dm/DMTestTask.cpp',
-            '../dm/DMUtil.cpp',
-            '../dm/DMWriteTask.cpp',
-            '../gm/gm.cpp',
-            '../gm/gm_expectations.cpp',
-
-            '../src/pipe/utils/SamplePipeControllers.cpp',
-            '../src/utils/debugger/SkDebugCanvas.cpp',
-            '../src/utils/debugger/SkDrawCommand.cpp',
-            '../src/utils/debugger/SkObjectParser.cpp',
-        ],
-        'dependencies': [
-            'crash_handler.gyp:CrashHandler',
-            'etc1.gyp:libetc1',
-            'flags.gyp:flags',
-            'gputest.gyp:skgputest',
-            'jsoncpp.gyp:jsoncpp',
-            'skia_lib.gyp:skia_lib',
+          'dm.gypi',
         ],
         'conditions': [
           ['skia_android_framework', {
diff --git a/gyp/dm.gypi b/gyp/dm.gypi
new file mode 100644
index 0000000..c744715
--- /dev/null
+++ b/gyp/dm.gypi
@@ -0,0 +1,61 @@
+# GYP for "dm" (Diamond Master, a.k.a Dungeon master, a.k.a GM 2).
+{
+  'include_dirs': [
+    '../dm',
+    '../gm',
+    '../tests',
+    '../src/images',
+    '../src/lazy',
+    '../src/core',
+    '../src/effects',
+    '../src/pipe/utils/',
+    '../src/utils',
+    '../src/utils/debugger',
+    '../tools',
+  ],
+  'dependencies': [
+    'etc1.gyp:libetc1',
+    'flags.gyp:flags',
+    'jsoncpp.gyp:jsoncpp',
+    'skia_lib.gyp:skia_lib',
+    'tools.gyp:crash_handler',
+    'tools.gyp:proc_stats',
+    'tools.gyp:sk_tool_utils',
+  ],
+  'includes': [
+    'gmslides.gypi',
+    'pathops_unittest.gypi',
+    'tests.gypi',
+  ],
+  'sources': [
+    '../dm/DM.cpp',
+    '../dm/DMCpuGMTask.cpp',
+    '../dm/DMGpuGMTask.cpp',
+    '../dm/DMPDFRasterizeTask.cpp',
+    '../dm/DMPDFTask.cpp',
+    '../dm/DMPipeTask.cpp',
+    '../dm/DMQuiltTask.cpp',
+    '../dm/DMReporter.cpp',
+    '../dm/DMSKPTask.cpp',
+    '../dm/DMSerializeTask.cpp',
+    '../dm/DMTask.cpp',
+    '../dm/DMTaskRunner.cpp',
+    '../dm/DMTestTask.cpp',
+    '../dm/DMUtil.cpp',
+    '../dm/DMWriteTask.cpp',
+    '../gm/gm.cpp',
+
+    '../src/utils/SkTaskGroup.cpp',
+
+    '../src/pipe/utils/SamplePipeControllers.cpp',
+    '../src/utils/debugger/SkDebugCanvas.cpp',
+    '../src/utils/debugger/SkDrawCommand.cpp',
+    '../src/utils/debugger/SkObjectParser.cpp',
+    '../tools/LazyDecodeBitmap.cpp',
+  ],
+  'conditions': [
+    [ 'skia_gpu == 1', {
+      'dependencies': [ 'gputest.gyp:skgputest' ],
+    }],
+  ],
+}
diff --git a/gyp/effects.gypi b/gyp/effects.gypi
index e4ee7b1..da2f5db 100644
--- a/gyp/effects.gypi
+++ b/gyp/effects.gypi
@@ -12,7 +12,6 @@
     '<(skia_src_path)/effects/SkAlphaThresholdFilter.cpp',
     '<(skia_src_path)/effects/SkArithmeticMode.cpp',
     '<(skia_src_path)/effects/SkAvoidXfermode.cpp',
-    '<(skia_src_path)/effects/SkBicubicImageFilter.cpp',
     '<(skia_src_path)/effects/SkBitmapSource.cpp',
     '<(skia_src_path)/effects/SkBlurDrawLooper.cpp',
     '<(skia_src_path)/effects/SkBlurMask.cpp',
@@ -51,7 +50,6 @@
     '<(skia_src_path)/effects/SkPixelXorXfermode.cpp',
     '<(skia_src_path)/effects/SkPorterDuff.cpp',
     '<(skia_src_path)/effects/SkRectShaderImageFilter.cpp',
-    '<(skia_src_path)/effects/SkStippleMaskFilter.cpp',
     '<(skia_src_path)/effects/SkTableColorFilter.cpp',
     '<(skia_src_path)/effects/SkTableMaskFilter.cpp',
     '<(skia_src_path)/effects/SkTestImageFilters.cpp',
@@ -60,11 +58,11 @@
     '<(skia_src_path)/effects/SkTransparentShader.cpp',
     '<(skia_src_path)/effects/SkXfermodeImageFilter.cpp',
 
-    '<(skia_src_path)/effects/gradients/SkBitmapCache.cpp',
-    '<(skia_src_path)/effects/gradients/SkBitmapCache.h',
     '<(skia_src_path)/effects/gradients/SkClampRange.cpp',
     '<(skia_src_path)/effects/gradients/SkClampRange.h',
     '<(skia_src_path)/effects/gradients/SkRadialGradient_Table.h',
+    '<(skia_src_path)/effects/gradients/SkGradientBitmapCache.cpp',
+    '<(skia_src_path)/effects/gradients/SkGradientBitmapCache.h',
     '<(skia_src_path)/effects/gradients/SkGradientShader.cpp',
     '<(skia_src_path)/effects/gradients/SkGradientShaderPriv.h',
     '<(skia_src_path)/effects/gradients/SkLinearGradient.cpp',
@@ -113,7 +111,6 @@
     '<(skia_include_path)/effects/SkPixelXorXfermode.h',
     '<(skia_include_path)/effects/SkPorterDuff.h',
     '<(skia_include_path)/effects/SkRectShaderImageFilter.h',
-    '<(skia_include_path)/effects/SkStippleMaskFilter.h',
     '<(skia_include_path)/effects/SkTableColorFilter.h',
     '<(skia_include_path)/effects/SkTableMaskFilter.h',
     '<(skia_include_path)/effects/SkTileImageFilter.h',
diff --git a/gyp/everything.gyp b/gyp/everything.gyp
index c1e7937..78317ef 100644
--- a/gyp/everything.gyp
+++ b/gyp/everything.gyp
@@ -24,7 +24,7 @@
             'pdfviewer.gyp:pdfviewer',
             #'v8.gyp:SkV8Example',
             #'webtry.gyp:webtry',
-            ],
+          ],
         }],
       ],
     },
diff --git a/gyp/experimental.gyp b/gyp/experimental.gyp
index a0daf3d..c3789fa 100644
--- a/gyp/experimental.gyp
+++ b/gyp/experimental.gyp
@@ -23,70 +23,57 @@
       'target_name': 'SkiaExamples',
       'type': 'executable',
       'mac_bundle' : 1,
-      'include_dirs' : [
-        '../tools/flags',
-        ],
-      'includes': [],
-       'sources': [
-         '../experimental/SkiaExamples/SkExample.h',
-         '../experimental/SkiaExamples/SkExample.cpp',
-         '../experimental/SkiaExamples/HelloSkiaExample.cpp',
-       ],
-       'dependencies': [
-         'skia_lib.gyp:skia_lib',
-         'views.gyp:views',
-         'xml.gyp:xml',
-         'flags.gyp:flags'
-       ],
-       'conditions' : [
-         [ 'skia_gpu == 1', {
-           'include_dirs' : [
-             '../src/gpu',  #gl/GrGLUtil.h
-             ]
-         }],
+      'sources': [
+        '../experimental/SkiaExamples/SkExample.h',
+        '../experimental/SkiaExamples/SkExample.cpp',
+        '../experimental/SkiaExamples/HelloSkiaExample.cpp',
+      ],
+      'dependencies': [
+        'flags.gyp:flags',
+        'skia_lib.gyp:skia_lib',
+        'views.gyp:views',
+        'xml.gyp:xml',
+      ],
+      'conditions' : [
+        [ 'skia_gpu == 1', {
+          'include_dirs' : [
+            '../src/gpu',
+          ],
+        }],
         [ 'skia_os == "win"', {
-         'sources' : [
-           '../src/views/win/SkOSWindow_Win.cpp',
-           '../src/views/win/skia_win.cpp',
-           ],
-          },
-        ],
-
+          'sources' : [
+            '../src/views/win/SkOSWindow_Win.cpp',
+            '../src/views/win/skia_win.cpp',
+          ],
+        }],
         [ 'skia_os == "mac"', {
           'sources': [
-
-# SkiaExamples specific files
-          '../experimental/SkiaExamples/SkiaExamples-Info.plist',
-          '../experimental/SkiaExamples/SkExampleNSView.h',
-          '../experimental/SkiaExamples/SkExampleNSView.mm',
-
-# Mac files
-          '../src/views/mac/SampleAppDelegate.h',
-          '../src/views/mac/SampleAppDelegate.mm',
-          '../src/views/mac/SkEventNotifier.mm',
-          '../src/views/mac/skia_mac.mm',
-          '../src/views/mac/SkNSView.h',
-          '../src/views/mac/SkNSView.mm',
-          '../src/views/mac/SkOptionsTableView.h',
-          '../src/views/mac/SkOptionsTableView.mm',
-          '../src/views/mac/SkOSWindow_Mac.mm',
-          '../src/views/mac/SkTextFieldCell.h',
-          '../src/views/mac/SkTextFieldCell.m',
+            '../experimental/SkiaExamples/SkiaExamples-Info.plist',
+            '../experimental/SkiaExamples/SkExampleNSView.h',
+            '../experimental/SkiaExamples/SkExampleNSView.mm',
+            '../src/views/mac/SampleAppDelegate.h',
+            '../src/views/mac/SampleAppDelegate.mm',
+            '../src/views/mac/SkEventNotifier.mm',
+            '../src/views/mac/skia_mac.mm',
+            '../src/views/mac/SkNSView.h',
+            '../src/views/mac/SkNSView.mm',
+            '../src/views/mac/SkOptionsTableView.h',
+            '../src/views/mac/SkOptionsTableView.mm',
+            '../src/views/mac/SkOSWindow_Mac.mm',
+            '../src/views/mac/SkTextFieldCell.h',
+            '../src/views/mac/SkTextFieldCell.m',
           ],
-        'include_dirs' : [
-          '../src/views/mac/'
+          'include_dirs' : [
+            '../src/views/mac/'
           ],
-        'link_settings': {
-        },
-        'xcode_settings' : {
-          'INFOPLIST_FILE' : '../experimental/SkiaExamples/SkiaExamples-Info.plist',
-        },
-        'mac_bundle_resources' : [
-          '../experimental/SkiaExamples/SkiaExamples.xib'
+          'xcode_settings' : {
+            'INFOPLIST_FILE' : '../experimental/SkiaExamples/SkiaExamples-Info.plist',
+          },
+          'mac_bundle_resources' : [
+            '../experimental/SkiaExamples/SkiaExamples.xib'
           ],
-        }
+        }],
       ],
-     ],
     }
   ],
 }
diff --git a/gyp/flags.gyp b/gyp/flags.gyp
index c15624b..02f17dd 100644
--- a/gyp/flags.gyp
+++ b/gyp/flags.gyp
@@ -6,8 +6,8 @@
       'target_name': 'flags',
       'type': 'static_library',
       'sources': [
-        '../tools/flags/SkCommandLineFlags.h',
         '../tools/flags/SkCommandLineFlags.cpp',
+        '../tools/flags/SkCommandLineFlags.h',
       ],
       'dependencies': [
         'skia_lib.gyp:skia_lib',
@@ -18,5 +18,22 @@
         ],
       }
     },
+    {
+      'target_name': 'flags_common',
+      'type': 'static_library',
+      'sources': [
+        '../tools/flags/SkCommonFlags.cpp',
+        '../tools/flags/SkCommonFlags.h',
+      ],
+      'dependencies': [
+        'skia_lib.gyp:skia_lib',
+        'flags.gyp:flags',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '../tools/flags',
+        ],
+      }
+    },
   ],
 }
diff --git a/gyp/gm.gyp b/gyp/gm.gyp
index 0b0054b..658a067 100644
--- a/gyp/gm.gyp
+++ b/gyp/gm.gyp
@@ -5,28 +5,6 @@
   ],
   'targets': [
     {
-      'target_name': 'gm_expectations',
-      'type': 'static_library',
-      'include_dirs' : [
-        '../src/utils/',
-      ],
-      'sources': [
-        '../gm/gm_expectations.h',
-        '../gm/gm_expectations.cpp',
-        '../tools/sk_tool_utils.cpp',
-      ],
-      'dependencies': [
-        'crash_handler.gyp:CrashHandler',
-        'jsoncpp.gyp:jsoncpp',
-        'skia_lib.gyp:skia_lib',
-      ],
-      'direct_dependent_settings': {
-        'include_dirs': [
-          '../gm/',
-        ],
-      },
-    },
-    {
       'target_name': 'gm',
       'type': 'executable',
       'include_dirs' : [
@@ -40,6 +18,7 @@
         'gmslides.gypi',
       ],
       'sources': [
+        '../gm/gm.cpp',
         '../gm/gmmain.cpp',
         '../gm/system_preferences_default.cpp',
 
@@ -49,11 +28,14 @@
       'dependencies': [
         'etc1.gyp:libetc1',
         'flags.gyp:flags',
-        'gm.gyp:gm_expectations',
         'jsoncpp.gyp:jsoncpp',
         'pdf.gyp:pdf',
-        'resources.gyp:resources',
         'skia_lib.gyp:skia_lib',
+        'tools.gyp:crash_handler',
+        'tools.gyp:gm_expectations',
+        'tools.gyp:proc_stats',
+        'tools.gyp:resources',
+        'tools.gyp:sk_tool_utils',
       ],
       'conditions': [
         ['skia_android_framework', {
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
index 18e589b..04301f4 100644
--- a/gyp/gmslides.gypi
+++ b/gyp/gmslides.gypi
@@ -7,193 +7,206 @@
     '../src/images',
     '../src/lazy',
   ],
-  'sources': [
-    # base class for GMs
-    '../gm/gm.cpp',
-    '../gm/gm.h',
-
-    '../gm/aaclip.cpp',
-    '../gm/aarectmodes.cpp',
-    '../gm/alphagradients.cpp',
-    '../gm/arcofzorro.cpp',
-    '../gm/arithmode.cpp',
-    '../gm/beziereffects.cpp',
-    '../gm/bicubicfilter.cpp',
-    '../gm/bigblurs.cpp',
-    '../gm/bigmatrix.cpp',
-    '../gm/bigtext.cpp',
-    '../gm/bitmapcopy.cpp',
-    '../gm/bitmapmatrix.cpp',
-    '../gm/bitmapfilters.cpp',
-    '../gm/bitmappremul.cpp',
-    '../gm/bitmaprect.cpp',
-    '../gm/bitmaprecttest.cpp',
-    '../gm/bitmapscroll.cpp',
-    '../gm/bitmapshader.cpp',
-    '../gm/bitmapsource.cpp',
-    '../gm/bleed.cpp',
-    '../gm/blurcircles.cpp',
-    '../gm/blurs.cpp',
-    '../gm/blurquickreject.cpp',
-    '../gm/blurrect.cpp',
-    '../gm/blurroundrect.cpp',
-    '../gm/canvasstate.cpp',
-    '../gm/circles.cpp',
-    '../gm/circularclips.cpp',
-    '../gm/clippedbitmapshaders.cpp',
-    '../gm/coloremoji.cpp',
-    '../gm/colorfilterimagefilter.cpp',
-    '../gm/colorfilters.cpp',
-    '../gm/colormatrix.cpp',
-    '../gm/colortype.cpp',
-    '../gm/complexclip.cpp',
-    '../gm/complexclip2.cpp',
-    '../gm/composeshader.cpp',
-    #'../gm/conicpaths.cpp',
-    '../gm/convexpaths.cpp',
-    '../gm/convexpolyclip.cpp',
-    '../gm/convexpolyeffect.cpp',
-    '../gm/copyTo4444.cpp',
-    '../gm/cubicpaths.cpp',
-    '../gm/cmykjpeg.cpp',
-    '../gm/degeneratesegments.cpp',
-    '../gm/discard.cpp',
-    '../gm/dashcubics.cpp',
-    '../gm/dashing.cpp',
-    '../gm/deviceproperties.cpp',
-    '../gm/distantclip.cpp',
-    '../gm/displacement.cpp',
-    '../gm/downsamplebitmap.cpp',
-    '../gm/drawbitmaprect.cpp',
-    '../gm/drawlooper.cpp',
-    '../gm/dropshadowimagefilter.cpp',
-    '../gm/drrect.cpp',
-    '../gm/etc1bitmap.cpp',
-    '../gm/extractbitmap.cpp',
-    '../gm/emptypath.cpp',
-    '../gm/fatpathfill.cpp',
-    '../gm/factory.cpp',
-    '../gm/filltypes.cpp',
-    '../gm/filltypespersp.cpp',
-    '../gm/filterbitmap.cpp',
-    '../gm/filterindiabox.cpp',
-    '../gm/fontcache.cpp',
-    '../gm/fontmgr.cpp',
-    '../gm/fontscaler.cpp',
-    '../gm/gammatext.cpp',
-    '../gm/getpostextpath.cpp',
-    '../gm/giantbitmap.cpp',
-    '../gm/gradients.cpp',
-    '../gm/gradients_2pt_conical.cpp',
-    '../gm/gradients_no_texture.cpp',
-    '../gm/gradientDirtyLaundry.cpp',
-    '../gm/gradient_matrix.cpp',
-    '../gm/gradtext.cpp',
-    '../gm/hairlines.cpp',
-    '../gm/hairmodes.cpp',
-    '../gm/hittestpath.cpp',
-    '../gm/imagealphathreshold.cpp',
-    '../gm/imageblur.cpp',
-    '../gm/imageblurtiled.cpp',
-    '../gm/imagemagnifier.cpp',
-    '../gm/imageresizetiled.cpp',
-    '../gm/inversepaths.cpp',
-    '../gm/lerpmode.cpp',
-    '../gm/lighting.cpp',
-    '../gm/lumafilter.cpp',
-    '../gm/image.cpp',
-    '../gm/imagefiltersbase.cpp',
-    '../gm/imagefiltersclipped.cpp',
-    '../gm/imagefilterscropped.cpp',
-    '../gm/imagefilterscropexpand.cpp',
-    '../gm/imagefiltersgraph.cpp',
-    '../gm/imagefiltersscaled.cpp',
-    '../gm/internal_links.cpp',
-    '../gm/lcdtext.cpp',
-    '../gm/linepaths.cpp',
-    '../gm/matrixconvolution.cpp',
-    '../gm/matriximagefilter.cpp',
-    '../gm/megalooper.cpp',
-    '../gm/mixedxfermodes.cpp',
-    '../gm/modecolorfilters.cpp',
-    '../gm/morphology.cpp',
-    '../gm/nested.cpp',
-    '../gm/ninepatchstretch.cpp',
-    '../gm/nonclosedpaths.cpp',
-    '../gm/offsetimagefilter.cpp',
-    '../gm/optimizations.cpp',
-    '../gm/ovals.cpp',
-    '../gm/patheffects.cpp',
-    '../gm/pathfill.cpp',
-    '../gm/pathinterior.cpp',
-    '../gm/pathopsinverse.cpp',
-    '../gm/pathopsskpclip.cpp',
-    '../gm/pathreverse.cpp',
-    '../gm/peekpixels.cpp',
-    '../gm/perlinnoise.cpp',
-    '../gm/pictureimagefilter.cpp',
-    '../gm/pictureshader.cpp',
-    '../gm/points.cpp',
-    '../gm/poly2poly.cpp',
-    '../gm/polygons.cpp',
-    '../gm/quadpaths.cpp',
-    '../gm/rects.cpp',
-    '../gm/resizeimagefilter.cpp',
-    '../gm/rrect.cpp',
-    '../gm/rrects.cpp',
-    '../gm/roundrects.cpp',
-    '../gm/samplerstress.cpp',
-    # '../gm/scalebitmap.cpp',
-    '../gm/shaderbounds.cpp',
-    '../gm/selftest.cpp',
-    '../gm/shadertext.cpp',
-    '../gm/shadertext2.cpp',
-    '../gm/shadertext3.cpp',
-    '../gm/shadows.cpp',
-    '../gm/shallowgradient.cpp',
-    '../gm/simpleaaclip.cpp',
-    '../gm/skbug1719.cpp',
-    '../gm/stringart.cpp',
-    '../gm/spritebitmap.cpp',
-    '../gm/srcmode.cpp',
-    '../gm/strokefill.cpp',
-    '../gm/strokerect.cpp',
-    '../gm/strokerects.cpp',
-    '../gm/strokes.cpp',
-    '../gm/stroketext.cpp',
-    '../gm/tablecolorfilter.cpp',
-    '../gm/texteffects.cpp',
-    '../gm/testimagefilters.cpp',
-    '../gm/texdata.cpp',
-    '../gm/variedtext.cpp',
-    '../gm/texturedomaineffect.cpp',
-    '../gm/thinrects.cpp',
-    '../gm/thinstrokedrects.cpp',
-    '../gm/tileimagefilter.cpp',
-    '../gm/tilemodes.cpp',
-    '../gm/tilemodes_scaled.cpp',
-    '../gm/tinybitmap.cpp',
-    '../gm/twopointradial.cpp',
-    '../gm/typeface.cpp',
-    '../gm/vertices.cpp',
-    '../gm/verttext.cpp',
-    '../gm/verttext2.cpp',
-    '../gm/verylargebitmap.cpp',
-    '../gm/xfermodeimagefilter.cpp',
-    '../gm/xfermodes.cpp',
-    '../gm/xfermodes2.cpp',
-    '../gm/xfermodes3.cpp',
-
-    # Files needed by particular GMs
-    '../src/utils/debugger/SkDrawCommand.h',
-    '../src/utils/debugger/SkDrawCommand.cpp',
-    '../src/utils/debugger/SkDebugCanvas.h',
-    '../src/utils/debugger/SkDebugCanvas.cpp',
-    '../src/utils/debugger/SkObjectParser.h',
-    '../src/utils/debugger/SkObjectParser.cpp',
-
-  ],
   'conditions': [
+    # If we're building SampleApp on the bots, no need to link in the GM slides.
+    # We're not going to run it; we're only making sure it still builds.
+    # It'd be nice to do this in SampleApp.gypi, but I can't find a way to make it work.
+    [ 'not ("<(_target_name)" == "SampleApp" and skia_is_bot)', {
+      'sources': [
+        '../gm/aaclip.cpp',
+        '../gm/aarectmodes.cpp',
+        '../gm/alphagradients.cpp',
+        '../gm/arcofzorro.cpp',
+        '../gm/arithmode.cpp',
+        '../gm/astcbitmap.cpp',
+        '../gm/beziereffects.cpp',
+        '../gm/bigblurs.cpp',
+        '../gm/bigmatrix.cpp',
+        '../gm/bigtext.cpp',
+        '../gm/bitmapcopy.cpp',
+        '../gm/bitmapmatrix.cpp',
+        '../gm/bitmapfilters.cpp',
+        '../gm/bitmappremul.cpp',
+        '../gm/bitmaprect.cpp',
+        '../gm/bitmaprecttest.cpp',
+        '../gm/bitmapscroll.cpp',
+        '../gm/bitmapshader.cpp',
+        '../gm/bitmapsource.cpp',
+        '../gm/bleed.cpp',
+        '../gm/blurcircles.cpp',
+        '../gm/blurs.cpp',
+        '../gm/blurquickreject.cpp',
+        '../gm/blurrect.cpp',
+        '../gm/blurroundrect.cpp',
+        '../gm/circles.cpp',
+        '../gm/circularclips.cpp',
+        '../gm/clip_strokerect.cpp',
+        '../gm/clippedbitmapshaders.cpp',
+        '../gm/coloremoji.cpp',
+        '../gm/colorfilterimagefilter.cpp',
+        '../gm/colorfilters.cpp',
+        '../gm/colormatrix.cpp',
+        '../gm/colortype.cpp',
+        '../gm/complexclip.cpp',
+        '../gm/complexclip2.cpp',
+        '../gm/composeshader.cpp',
+        #'../gm/conicpaths.cpp',
+        '../gm/convexpaths.cpp',
+        '../gm/convexpolyclip.cpp',
+        '../gm/convexpolyeffect.cpp',
+        '../gm/copyTo4444.cpp',
+        '../gm/cubicpaths.cpp',
+        '../gm/cmykjpeg.cpp',
+        '../gm/degeneratesegments.cpp',
+        '../gm/discard.cpp',
+        '../gm/dashcubics.cpp',
+        '../gm/dashing.cpp',
+        '../gm/distantclip.cpp',
+        '../gm/dftext.cpp',
+        '../gm/displacement.cpp',
+        '../gm/downsamplebitmap.cpp',
+        '../gm/drawbitmaprect.cpp',
+        '../gm/drawlooper.cpp',
+        '../gm/dropshadowimagefilter.cpp',
+        '../gm/drrect.cpp',
+        '../gm/etc1bitmap.cpp',
+        '../gm/extractbitmap.cpp',
+        '../gm/emboss.cpp',
+        '../gm/emptypath.cpp',
+        '../gm/fatpathfill.cpp',
+        '../gm/factory.cpp',
+        '../gm/filltypes.cpp',
+        '../gm/filltypespersp.cpp',
+        '../gm/filterbitmap.cpp',
+        '../gm/filterindiabox.cpp',
+        '../gm/fontcache.cpp',
+        '../gm/fontmgr.cpp',
+        '../gm/fontscaler.cpp',
+        '../gm/gammatext.cpp',
+        '../gm/getpostextpath.cpp',
+        '../gm/giantbitmap.cpp',
+        '../gm/glyph_pos.cpp',
+        '../gm/glyph_pos_align.cpp',
+        '../gm/gradients.cpp',
+        '../gm/gradients_2pt_conical.cpp',
+        '../gm/gradients_no_texture.cpp',
+        '../gm/gradientDirtyLaundry.cpp',
+        '../gm/gradient_matrix.cpp',
+        '../gm/gradtext.cpp',
+        '../gm/hairlines.cpp',
+        '../gm/hairmodes.cpp',
+        '../gm/hittestpath.cpp',
+        '../gm/imagealphathreshold.cpp',
+        '../gm/imageblur.cpp',
+        '../gm/imageblur2.cpp',
+        '../gm/imageblurtiled.cpp',
+        '../gm/imagemagnifier.cpp',
+        '../gm/imageresizetiled.cpp',
+        '../gm/inversepaths.cpp',
+        '../gm/lerpmode.cpp',
+        '../gm/lighting.cpp',
+        '../gm/lumafilter.cpp',
+        '../gm/image.cpp',
+        '../gm/imagefiltersbase.cpp',
+        '../gm/imagefiltersclipped.cpp',
+        '../gm/imagefilterscropped.cpp',
+        '../gm/imagefilterscropexpand.cpp',
+        '../gm/imagefiltersgraph.cpp',
+        '../gm/imagefiltersscaled.cpp',
+        '../gm/internal_links.cpp',
+        '../gm/lcdtext.cpp',
+        '../gm/linepaths.cpp',
+        '../gm/matrixconvolution.cpp',
+        '../gm/matriximagefilter.cpp',
+        '../gm/megalooper.cpp',
+        '../gm/mixedxfermodes.cpp',
+        '../gm/modecolorfilters.cpp',
+        '../gm/morphology.cpp',
+        '../gm/multipicturedraw.cpp',
+        '../gm/nested.cpp',
+        '../gm/ninepatchstretch.cpp',
+        '../gm/nonclosedpaths.cpp',
+        '../gm/offsetimagefilter.cpp',
+        '../gm/optimizations.cpp',
+        '../gm/ovals.cpp',
+        '../gm/patch.cpp',
+        '../gm/patchgrid.cpp',
+        '../gm/patheffects.cpp',
+        '../gm/pathfill.cpp',
+        '../gm/pathinterior.cpp',
+        '../gm/pathopsinverse.cpp',
+        '../gm/pathopsskpclip.cpp',
+        '../gm/pathreverse.cpp',
+        '../gm/peekpixels.cpp',
+        '../gm/perlinnoise.cpp',
+        '../gm/picture.cpp',
+        '../gm/pictureimagefilter.cpp',
+        '../gm/pictureshader.cpp',
+        '../gm/pictureshadertile.cpp',
+        '../gm/points.cpp',
+        '../gm/poly2poly.cpp',
+        '../gm/polygons.cpp',
+        '../gm/quadpaths.cpp',
+        '../gm/rects.cpp',
+        '../gm/resizeimagefilter.cpp',
+        '../gm/rrect.cpp',
+        '../gm/rrects.cpp',
+        '../gm/roundrects.cpp',
+        '../gm/samplerstress.cpp',
+        # '../gm/scalebitmap.cpp',
+        '../gm/shaderbounds.cpp',
+        '../gm/selftest.cpp',
+        '../gm/shadertext.cpp',
+        '../gm/shadertext2.cpp',
+        '../gm/shadertext3.cpp',
+        '../gm/shadows.cpp',
+        '../gm/shallowgradient.cpp',
+        '../gm/simpleaaclip.cpp',
+        '../gm/skbug1719.cpp',
+        '../gm/stringart.cpp',
+        '../gm/spritebitmap.cpp',
+        '../gm/srcmode.cpp',
+        '../gm/strokefill.cpp',
+        '../gm/strokerect.cpp',
+        '../gm/strokerects.cpp',
+        '../gm/strokes.cpp',
+        '../gm/stroketext.cpp',
+        '../gm/surface.cpp',
+        '../gm/tablecolorfilter.cpp',
+        '../gm/texteffects.cpp',
+        '../gm/testimagefilters.cpp',
+        '../gm/texdata.cpp',
+        '../gm/variedtext.cpp',
+        '../gm/textblob.cpp',
+        '../gm/textblobshader.cpp',
+        '../gm/texturedomaineffect.cpp',
+        '../gm/thinrects.cpp',
+        '../gm/thinstrokedrects.cpp',
+        '../gm/tileimagefilter.cpp',
+        '../gm/tilemodes.cpp',
+        '../gm/tilemodes_scaled.cpp',
+        '../gm/tinybitmap.cpp',
+        '../gm/twopointradial.cpp',
+        '../gm/typeface.cpp',
+        '../gm/vertices.cpp',
+        '../gm/verttext.cpp',
+        '../gm/verttext2.cpp',
+        '../gm/verylargebitmap.cpp',
+        '../gm/xfermodeimagefilter.cpp',
+        '../gm/xfermodes.cpp',
+        '../gm/xfermodes2.cpp',
+        '../gm/xfermodes3.cpp',
+        '../gm/yuvtorgbeffect.cpp',
+
+        # Files needed by particular GMs
+        '../src/utils/debugger/SkDrawCommand.h',
+        '../src/utils/debugger/SkDrawCommand.cpp',
+        '../src/utils/debugger/SkDebugCanvas.h',
+        '../src/utils/debugger/SkDebugCanvas.cpp',
+        '../src/utils/debugger/SkObjectParser.h',
+        '../src/utils/debugger/SkObjectParser.cpp',
+      ],
+    }],
     # TODO: Several GMs are known to cause particular problems on Android, so
     # we disable them on Android.  See http://skbug.com/2326
     [ 'skia_os == "android"', {
@@ -226,10 +239,6 @@
         # fulfilling. See http://skbug.com/1978
         '../gm/verylargebitmap.cpp',
       ],
-
-      'sources': [
-        '../gm/androidfallback.cpp',
-      ],
     }],
   ],
 }
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp
index 6fbd05a..7bb61f0 100644
--- a/gyp/gpu.gyp
+++ b/gyp/gpu.gyp
@@ -74,9 +74,6 @@
         '../include/gpu',
       ],
     },
-    'defines': [
-      'GR_COMPRESS_ALPHA_MASK=0',
-    ],
   },
   'targets': [
     {
@@ -215,6 +212,9 @@
             '../src/gpu/gl/GrGLDefaultInterface_none.cpp',
             '../src/gpu/gl/GrGLCreateNativeInterface_none.cpp',
           ],
+          'defines': [
+            'GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE=1',
+          ],
           'link_settings': {
             'libraries': [
               '-lGLESv2',
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index c03f8ef..ebc07b2 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -8,27 +8,31 @@
 {
   'variables': {
     'skgpu_sources': [
-      '<(skia_include_path)/gpu/GrBackendEffectFactory.h',
-      '<(skia_include_path)/gpu/GrCacheable.h',
+      '<(skia_include_path)/gpu/GrBackendProcessorFactory.h',
+      '<(skia_include_path)/gpu/GrBinHashKey.h',
       '<(skia_include_path)/gpu/GrClipData.h',
       '<(skia_include_path)/gpu/GrColor.h',
       '<(skia_include_path)/gpu/GrConfig.h',
       '<(skia_include_path)/gpu/GrContext.h',
       '<(skia_include_path)/gpu/GrContextFactory.h',
       '<(skia_include_path)/gpu/GrCoordTransform.h',
-      '<(skia_include_path)/gpu/GrEffect.h',
-      '<(skia_include_path)/gpu/GrEffectStage.h',
-      '<(skia_include_path)/gpu/GrEffectUnitTest.h',
       '<(skia_include_path)/gpu/GrFontScaler.h',
       '<(skia_include_path)/gpu/GrGlyph.h',
-      '<(skia_include_path)/gpu/GrGpuObject.h',
-      '<(skia_include_path)/gpu/GrKey.h',
+      '<(skia_include_path)/gpu/GrGpuResource.h',
       '<(skia_include_path)/gpu/GrPaint.h',
       '<(skia_include_path)/gpu/GrPathRendererChain.h',
+      '<(skia_include_path)/gpu/GrProcessor.h',
+      '<(skia_include_path)/gpu/GrProcessorStage.h',
+      '<(skia_include_path)/gpu/GrProcessorUnitTest.h',
+      '<(skia_include_path)/gpu/GrProgramElement.h',
+      '<(skia_include_path)/gpu/GrProgramElementRef.h',
+      '<(skia_include_path)/gpu/GrGpuResourceRef.h',
       '<(skia_include_path)/gpu/GrRect.h',
       '<(skia_include_path)/gpu/GrRenderTarget.h',
+      '<(skia_include_path)/gpu/GrResourceKey.h',
       '<(skia_include_path)/gpu/GrSurface.h',
-      '<(skia_include_path)/gpu/GrTBackendEffectFactory.h',
+      '<(skia_include_path)/gpu/GrShaderVar.h',
+      '<(skia_include_path)/gpu/GrTBackendProcessorFactory.h',
       '<(skia_include_path)/gpu/GrTexture.h',
       '<(skia_include_path)/gpu/GrTextureAccess.h',
       '<(skia_include_path)/gpu/GrTypes.h',
@@ -38,6 +42,7 @@
       '<(skia_include_path)/gpu/gl/GrGLExtensions.h',
       '<(skia_include_path)/gpu/gl/GrGLFunctions.h',
       '<(skia_include_path)/gpu/gl/GrGLInterface.h',
+      '<(skia_include_path)/gpu/gl/GrGLSLPrettyPrint.h',
 
       '<(skia_src_path)/gpu/GrAAHairLinePathRenderer.cpp',
       '<(skia_src_path)/gpu/GrAAHairLinePathRenderer.h',
@@ -51,16 +56,18 @@
       '<(skia_src_path)/gpu/GrAllocPool.cpp',
       '<(skia_src_path)/gpu/GrAtlas.cpp',
       '<(skia_src_path)/gpu/GrAtlas.h',
-      '<(skia_src_path)/gpu/GrBinHashKey.h',
       '<(skia_src_path)/gpu/GrBitmapTextContext.cpp',
       '<(skia_src_path)/gpu/GrBitmapTextContext.h',
       '<(skia_src_path)/gpu/GrBlend.cpp',
       '<(skia_src_path)/gpu/GrBlend.h',
       '<(skia_src_path)/gpu/GrBufferAllocPool.cpp',
       '<(skia_src_path)/gpu/GrBufferAllocPool.h',
-      '<(skia_src_path)/gpu/GrCacheable.cpp',
       '<(skia_src_path)/gpu/GrCacheID.cpp',
       '<(skia_src_path)/gpu/GrClipData.cpp',
+      '<(skia_src_path)/gpu/GrClipMaskCache.h',
+      '<(skia_src_path)/gpu/GrClipMaskCache.cpp',
+      '<(skia_src_path)/gpu/GrClipMaskManager.h',
+      '<(skia_src_path)/gpu/GrClipMaskManager.cpp',
       '<(skia_src_path)/gpu/GrContext.cpp',
       '<(skia_src_path)/gpu/GrDefaultPathRenderer.cpp',
       '<(skia_src_path)/gpu/GrDefaultPathRenderer.h',
@@ -71,37 +78,47 @@
       '<(skia_src_path)/gpu/GrDrawTarget.cpp',
       '<(skia_src_path)/gpu/GrDrawTarget.h',
       '<(skia_src_path)/gpu/GrDrawTargetCaps.h',
-      '<(skia_src_path)/gpu/GrEffect.cpp',
+      '<(skia_src_path)/gpu/GrFontScaler.cpp',
       '<(skia_src_path)/gpu/GrGeometryBuffer.h',
-      '<(skia_src_path)/gpu/GrClipMaskCache.h',
-      '<(skia_src_path)/gpu/GrClipMaskCache.cpp',
-      '<(skia_src_path)/gpu/GrClipMaskManager.h',
-      '<(skia_src_path)/gpu/GrClipMaskManager.cpp',
       '<(skia_src_path)/gpu/GrGpu.cpp',
       '<(skia_src_path)/gpu/GrGpu.h',
-      '<(skia_src_path)/gpu/GrGpuObject.cpp',
+      '<(skia_src_path)/gpu/GrGpuResource.cpp',
       '<(skia_src_path)/gpu/GrGpuFactory.cpp',
       '<(skia_src_path)/gpu/GrIndexBuffer.h',
       '<(skia_src_path)/gpu/GrInOrderDrawBuffer.cpp',
       '<(skia_src_path)/gpu/GrInOrderDrawBuffer.h',
       '<(skia_src_path)/gpu/GrLayerCache.cpp',
       '<(skia_src_path)/gpu/GrLayerCache.h',
+      '<(skia_src_path)/gpu/GrLayerHoister.cpp',
+      '<(skia_src_path)/gpu/GrLayerHoister.h',
       '<(skia_src_path)/gpu/GrMemoryPool.cpp',
       '<(skia_src_path)/gpu/GrMemoryPool.h',
+      '<(skia_src_path)/gpu/GrMurmur3HashKey.h',
+      '<(skia_src_path)/gpu/GrOptDrawState.cpp',
+      '<(skia_src_path)/gpu/GrOptDrawState.h',
       '<(skia_src_path)/gpu/GrOrderedSet.h',
       '<(skia_src_path)/gpu/GrOvalRenderer.cpp',
       '<(skia_src_path)/gpu/GrOvalRenderer.h',
       '<(skia_src_path)/gpu/GrPaint.cpp',
       '<(skia_src_path)/gpu/GrPath.cpp',
       '<(skia_src_path)/gpu/GrPath.h',
+      '<(skia_src_path)/gpu/GrPathRange.cpp',
+      '<(skia_src_path)/gpu/GrPathRange.h',
       '<(skia_src_path)/gpu/GrPathRendererChain.cpp',
       '<(skia_src_path)/gpu/GrPathRenderer.cpp',
       '<(skia_src_path)/gpu/GrPathRenderer.h',
+      '<(skia_src_path)/gpu/GrPathRendering.cpp',
+      '<(skia_src_path)/gpu/GrPathRendering.h',
       '<(skia_src_path)/gpu/GrPathUtils.cpp',
       '<(skia_src_path)/gpu/GrPathUtils.h',
+      '<(skia_src_path)/gpu/GrProgramElement.cpp',
+      '<(skia_src_path)/gpu/GrProcessor.cpp',
+      '<(skia_src_path)/gpu/GrGpuResourceRef.cpp',
       '<(skia_src_path)/gpu/GrPictureUtils.h',
       '<(skia_src_path)/gpu/GrPictureUtils.cpp',
       '<(skia_src_path)/gpu/GrPlotMgr.h',
+      '<(skia_src_path)/gpu/GrRecordReplaceDraw.cpp',
+      '<(skia_src_path)/gpu/GrRecordReplaceDraw.h',
       '<(skia_src_path)/gpu/GrRectanizer.h',
       '<(skia_src_path)/gpu/GrRectanizer_pow2.cpp',
       '<(skia_src_path)/gpu/GrRectanizer_pow2.h',
@@ -113,10 +130,16 @@
       '<(skia_src_path)/gpu/GrReducedClip.h',
       '<(skia_src_path)/gpu/GrResourceCache.cpp',
       '<(skia_src_path)/gpu/GrResourceCache.h',
+      '<(skia_src_path)/gpu/GrResourceCache2.cpp',
+      '<(skia_src_path)/gpu/GrResourceCache2.h',
+      '<(skia_src_path)/gpu/GrRODrawState.cpp',
+      '<(skia_src_path)/gpu/GrRODrawState.h',
       '<(skia_src_path)/gpu/GrStencil.cpp',
       '<(skia_src_path)/gpu/GrStencil.h',
       '<(skia_src_path)/gpu/GrStencilAndCoverPathRenderer.cpp',
       '<(skia_src_path)/gpu/GrStencilAndCoverPathRenderer.h',
+      '<(skia_src_path)/gpu/GrStencilAndCoverTextContext.cpp',
+      '<(skia_src_path)/gpu/GrStencilAndCoverTextContext.h',
       '<(skia_src_path)/gpu/GrStencilBuffer.cpp',
       '<(skia_src_path)/gpu/GrStencilBuffer.h',
       '<(skia_src_path)/gpu/GrStrokeInfo.h',
@@ -137,7 +160,6 @@
       '<(skia_src_path)/gpu/GrTextStrike_impl.h',
       '<(skia_src_path)/gpu/GrTexture.cpp',
       '<(skia_src_path)/gpu/GrTextureAccess.cpp',
-      '<(skia_src_path)/gpu/GrTHashTable.h',
       '<(skia_src_path)/gpu/GrVertexBuffer.h',
 
       '<(skia_src_path)/gpu/effects/Gr1DKernelEffect.h',
@@ -159,6 +181,8 @@
       '<(skia_src_path)/gpu/effects/GrDistanceFieldTextureEffect.h',
       '<(skia_src_path)/gpu/effects/GrDitherEffect.cpp',
       '<(skia_src_path)/gpu/effects/GrDitherEffect.h',
+      '<(skia_src_path)/gpu/effects/GrMatrixConvolutionEffect.cpp',
+      '<(skia_src_path)/gpu/effects/GrMatrixConvolutionEffect.h',
       '<(skia_src_path)/gpu/effects/GrOvalEffect.cpp',
       '<(skia_src_path)/gpu/effects/GrOvalEffect.h',
       '<(skia_src_path)/gpu/effects/GrRRectEffect.cpp',
@@ -171,6 +195,8 @@
       '<(skia_src_path)/gpu/effects/GrTextureDomain.h',
       '<(skia_src_path)/gpu/effects/GrTextureStripAtlas.cpp',
       '<(skia_src_path)/gpu/effects/GrTextureStripAtlas.h',
+      '<(skia_src_path)/gpu/effects/GrYUVtoRGBEffect.cpp',
+      '<(skia_src_path)/gpu/effects/GrYUVtoRGBEffect.h',
 
       '<(skia_src_path)/gpu/gl/GrGLAssembleInterface.cpp',
       '<(skia_src_path)/gpu/gl/GrGLAssembleInterface.h',
@@ -183,8 +209,7 @@
       '<(skia_src_path)/gpu/gl/GrGLCreateNativeInterface_none.cpp',
       '<(skia_src_path)/gpu/gl/GrGLDefaultInterface_none.cpp',
       '<(skia_src_path)/gpu/gl/GrGLDefines.h',
-      '<(skia_src_path)/gpu/gl/GrGLEffect.h',
-      '<(skia_src_path)/gpu/gl/GrGLVertexEffect.h',
+      '<(skia_src_path)/gpu/gl/GrGLGeometryProcessor.h',
       '<(skia_src_path)/gpu/gl/GrGLExtensions.cpp',
       '<(skia_src_path)/gpu/gl/GrGLIndexBuffer.cpp',
       '<(skia_src_path)/gpu/gl/GrGLIndexBuffer.h',
@@ -196,16 +221,21 @@
       '<(skia_src_path)/gpu/gl/GrGLNoOpInterface.h',
       '<(skia_src_path)/gpu/gl/GrGLPath.cpp',
       '<(skia_src_path)/gpu/gl/GrGLPath.h',
+      '<(skia_src_path)/gpu/gl/GrGLPathRange.cpp',
+      '<(skia_src_path)/gpu/gl/GrGLPathRange.h',
+      '<(skia_src_path)/gpu/gl/GrGLPathRendering.cpp',
+      '<(skia_src_path)/gpu/gl/GrGLPathRendering.h',
+      '<(skia_src_path)/gpu/gl/GrGLProcessor.h',
       '<(skia_src_path)/gpu/gl/GrGLProgram.cpp',
       '<(skia_src_path)/gpu/gl/GrGLProgram.h',
       '<(skia_src_path)/gpu/gl/GrGLProgramDesc.cpp',
       '<(skia_src_path)/gpu/gl/GrGLProgramDesc.h',
       '<(skia_src_path)/gpu/gl/GrGLProgramEffects.cpp',
       '<(skia_src_path)/gpu/gl/GrGLProgramEffects.h',
+      '<(skia_src_path)/gpu/gl/GrGLProgramDataManager.cpp',
+      '<(skia_src_path)/gpu/gl/GrGLProgramDataManager.h',
       '<(skia_src_path)/gpu/gl/GrGLRenderTarget.cpp',
       '<(skia_src_path)/gpu/gl/GrGLRenderTarget.h',
-      '<(skia_src_path)/gpu/gl/GrGLShaderBuilder.cpp',
-      '<(skia_src_path)/gpu/gl/GrGLShaderBuilder.h',
       '<(skia_src_path)/gpu/gl/GrGLShaderVar.h',
       '<(skia_src_path)/gpu/gl/GrGLSL.cpp',
       '<(skia_src_path)/gpu/gl/GrGLSL.h',
@@ -216,8 +246,6 @@
       '<(skia_src_path)/gpu/gl/GrGLTexture.h',
       '<(skia_src_path)/gpu/gl/GrGLUtil.cpp',
       '<(skia_src_path)/gpu/gl/GrGLUtil.h',
-      '<(skia_src_path)/gpu/gl/GrGLUniformManager.cpp',
-      '<(skia_src_path)/gpu/gl/GrGLUniformManager.h',
       '<(skia_src_path)/gpu/gl/GrGLUniformHandle.h',
       '<(skia_src_path)/gpu/gl/GrGLVertexArray.cpp',
       '<(skia_src_path)/gpu/gl/GrGLVertexArray.h',
@@ -227,8 +255,26 @@
       '<(skia_src_path)/gpu/gl/GrGpuGL.h',
       '<(skia_src_path)/gpu/gl/GrGpuGL_program.cpp',
 
+      # Files for building GLSL shaders
+      '<(skia_src_path)/gpu/gl/builders/GrGLSLPrettyPrint.cpp',
+      '<(skia_src_path)/gpu/gl/builders/GrGLShaderBuilder.cpp',
+      '<(skia_src_path)/gpu/gl/builders/GrGLShaderBuilder.h',
+      '<(skia_src_path)/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp',
+      '<(skia_src_path)/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h',
+      '<(skia_src_path)/gpu/gl/builders/GrGLFullProgramBuilder.cpp',
+      '<(skia_src_path)/gpu/gl/builders/GrGLFullProgramBuilder.h',
+      '<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.cpp',
+      '<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.h',
+      '<(skia_src_path)/gpu/gl/builders/GrGLShaderStringBuilder.cpp',
+      '<(skia_src_path)/gpu/gl/builders/GrGLShaderStringBuilder.h',
+      '<(skia_src_path)/gpu/gl/builders/GrGLVertexShaderBuilder.cpp',
+      '<(skia_src_path)/gpu/gl/builders/GrGLVertexShaderBuilder.h',
+      '<(skia_src_path)/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp',
+      '<(skia_src_path)/gpu/gl/builders/GrGLFragmentShaderBuilder.h',
+      '<(skia_src_path)/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp',
+      '<(skia_src_path)/gpu/gl/builders/GrGLGeometryShaderBuilder.h',
+
       # Sk files
-      '<(skia_include_path)/gpu/SkGpuDevice.h',
       '<(skia_include_path)/gpu/SkGr.h',
       '<(skia_include_path)/gpu/SkGrPixelRef.h',
       '<(skia_include_path)/gpu/SkGrTexturePixelRef.h',
@@ -236,8 +282,8 @@
       '<(skia_include_path)/gpu/gl/SkGLContextHelper.h',
 
       '<(skia_src_path)/gpu/SkGpuDevice.cpp',
+      '<(skia_src_path)/gpu/SkGpuDevice.h',
       '<(skia_src_path)/gpu/SkGr.cpp',
-      '<(skia_src_path)/gpu/SkGrFontScaler.cpp',
       '<(skia_src_path)/gpu/SkGrPixelRef.cpp',
       '<(skia_src_path)/gpu/SkGrTexturePixelRef.cpp',
 
diff --git a/gyp/iOSShell.gyp b/gyp/iOSShell.gyp
new file mode 100644
index 0000000..ac2ed30
--- /dev/null
+++ b/gyp/iOSShell.gyp
@@ -0,0 +1,90 @@
+#
+{
+  'conditions' : [
+    [ 'skia_os == "ios"', {
+      'targets': [
+        {
+          'target_name': 'iOSShell',
+          'type': 'executable',
+          'mac_bundle' : 1,
+          'includes': [
+            'bench.gypi',
+            'dm.gypi',
+          ],
+          'dependencies': [
+            'tools.gyp:crash_handler',
+            'tools.gyp:timer',
+            'views.gyp:views',
+            'xml.gyp:xml',
+          ],
+          'sources': [
+            '../bench/GMBench.cpp',
+            '../bench/RecordingBench.cpp',
+            '../bench/SKPBench.cpp',
+            '../bench/nanobench.cpp',
+            '../tests/skia_test.cpp',
+            '../tools/iOSShell.cpp',
+            '../src/views/mac/SkEventNotifier.mm',
+            '../experimental/iOSSampleApp/SkiOSSampleApp-Base.xcconfig',
+            '../experimental/iOSSampleApp/SkiOSSampleApp-Debug.xcconfig',
+            '../experimental/iOSSampleApp/SkiOSSampleApp-Release.xcconfig',
+            '../experimental/iOSShell/iOSShell-Info.plist',
+            '../experimental/iOSSampleApp/Shared/SkUIRootViewController.mm',
+            '../experimental/iOSSampleApp/Shared/SkUIView.mm',
+            '../experimental/iOSSampleApp/Shared/skia_ios.mm',
+
+            # iPad
+            '../experimental/iOSSampleApp/iPad/AppDelegate_iPad.mm',
+            '../experimental/iOSSampleApp/iPad/SkUISplitViewController.mm',
+            '../experimental/iOSSampleApp/iPad/MainWindow_iPad.xib',
+
+            # iPhone
+            '../experimental/iOSSampleApp/iPhone/AppDelegate_iPhone.mm',
+            '../experimental/iOSSampleApp/iPhone/SkUINavigationController.mm',
+            '../experimental/iOSSampleApp/iPhone/MainWindow_iPhone.xib',
+
+            '../src/views/ios/SkOSWindow_iOS.mm',
+            '../src/utils/ios/SkStream_NSData.mm',
+            '../src/utils/mac/SkCreateCGImageRef.cpp',
+          ],
+          'link_settings': {
+            'libraries': [
+              '$(SDKROOT)/System/Library/Frameworks/CoreFoundation.framework',
+              '$(SDKROOT)/System/Library/Frameworks/CoreGraphics.framework',
+              '$(SDKROOT)/System/Library/Frameworks/CoreText.framework',
+              '$(SDKROOT)/System/Library/Frameworks/UIKit.framework',
+              '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+              '$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework',
+              '$(SDKROOT)/System/Library/Frameworks/OpenGLES.framework',
+              '$(SDKROOT)/System/Library/Frameworks/ImageIO.framework',
+              '$(SDKROOT)/System/Library/Frameworks/MobileCoreServices.framework',
+            ],
+          },
+          'include_dirs' : [
+            '../experimental/iOSSampleApp',
+            '../experimental/iOSSampleApp/iPad',
+            '../experimental/iOSSampleApp/iPhone',
+            '../experimental/iOSSampleApp/Shared',
+            '../include/utils/ios',
+            '../src/views/mac',
+          ],
+          'xcode_settings' : {
+            'INFOPLIST_FILE' : '../experimental/iOSShell/iOSShell-Info.plist',
+          },
+          'xcode_config_file': '../experimental/iOSSampleApp/SkiOSSampleApp-Base.xcconfig',
+          'mac_bundle_resources' : [
+            '../experimental/iOSSampleApp/iPad/MainWindow_iPad.xib',
+            '../experimental/iOSSampleApp/iPhone/MainWindow_iPhone.xib',
+          ],
+          'conditions' : [
+            [ 'skia_gpu == 1', {
+              'dependencies': [
+                'gputest.gyp:skgputest',
+              ],
+            }],
+          ],
+        },
+      ],
+    }],
+  ]
+}
diff --git a/gyp/images.gyp b/gyp/images.gyp
index 2b4cfd3..13cf3bb 100644
--- a/gyp/images.gyp
+++ b/gyp/images.gyp
@@ -14,13 +14,6 @@
         'libwebp.gyp:libwebp',
         'utils.gyp:utils',
       ],
-      'conditions': [
-        [ 'skia_android_framework == 0', {
-          'export_dependent_settings': [
-            'libjpeg.gyp:*',
-          ],
-        }],
-      ],
       'include_dirs': [
         '../include/images',
         '../src/lazy',
@@ -28,8 +21,6 @@
         '../src/core/',
         # for access to SkImagePriv.h
         '../src/image/',
-        # So src/ports/SkImageDecoder_CG can access SkStreamHelpers.h
-        '../src/images/',
       ],
       'sources': [
         '../include/images/SkDecodingImageGenerator.h',
@@ -61,6 +52,7 @@
         '../src/images/SkImageDecoder_wbmp.cpp',
         '../src/images/SkImageDecoder_pkm.cpp',
         '../src/images/SkImageDecoder_ktx.cpp',
+        '../src/images/SkImageDecoder_astc.cpp',
         '../src/images/SkImageDecoder_libbmp.cpp',
         '../src/images/SkImageDecoder_libgif.cpp',
         '../src/images/SkImageDecoder_libico.cpp',
@@ -77,8 +69,6 @@
         '../src/images/SkPageFlipper.cpp',
         '../src/images/SkScaledBitmapSampler.cpp',
         '../src/images/SkScaledBitmapSampler.h',
-        '../src/images/SkStreamHelpers.cpp',
-        '../src/images/SkStreamHelpers.h',
 
         '../src/ports/SkImageDecoder_CG.cpp',
         '../src/ports/SkImageDecoder_WIC.cpp',
@@ -144,7 +134,16 @@
           'conditions': [
             [ 'skia_android_framework == 0', {
               'export_dependent_settings': [
-                'android_deps.gyp:png'
+                'android_deps.gyp:png',
+                'libjpeg.gyp:*'
+              ],
+            }, {
+              # The android framework disables these decoders as they are of little use to
+              # Java applications that can't take advantage of the compressed formats.
+              'sources!': [
+                '../src/images/SkImageDecoder_pkm.cpp',
+                '../src/images/SkImageDecoder_ktx.cpp',
+                '../src/images/SkImageDecoder_astc.cpp',
               ],
             }],
           ],
diff --git a/gyp/jsoncpp.gyp b/gyp/jsoncpp.gyp
index 337f716..b6efd87 100644
--- a/gyp/jsoncpp.gyp
+++ b/gyp/jsoncpp.gyp
@@ -1,16 +1,6 @@
 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
-
-# TODO: This file was copied from the external dependency
-# third_party/externals/jsoncpp-chromium/jsoncpp.gyp , at revision 125399,
-# with directory paths modified to work at this level.
-#
-# It would be better for us to depend on that gypfile within the external
-# dependency, but so far we have been unable to make that work reliably.
-# See https://code.google.com/p/skia/issues/detail?id=1023
-# and https://code.google.com/p/skia/source/detail?r=7115
-
 {
   'variables': {
     'skia_warnings_as_errors': 0,
@@ -32,29 +22,16 @@
             'JSON_USE_EXCEPTION=0',
           ],
           'sources': [
-            '../third_party/externals/jsoncpp/include/json/assertions.h',
-            '../third_party/externals/jsoncpp/include/json/autolink.h',
-            '../third_party/externals/jsoncpp/include/json/config.h',
-            '../third_party/externals/jsoncpp/include/json/features.h',
-            '../third_party/externals/jsoncpp/include/json/forwards.h',
-            '../third_party/externals/jsoncpp/include/json/json.h',
-            '../third_party/externals/jsoncpp/include/json/reader.h',
-            '../third_party/externals/jsoncpp-chromium/overrides/include/json/value.h',
-            '../third_party/externals/jsoncpp/include/json/writer.h',
-            '../third_party/externals/jsoncpp/src/lib_json/json_batchallocator.h',
             '../third_party/externals/jsoncpp/src/lib_json/json_reader.cpp',
-            '../third_party/externals/jsoncpp/src/lib_json/json_tool.h',
-            '../third_party/externals/jsoncpp-chromium/overrides/src/lib_json/json_value.cpp',
+            '../third_party/externals/jsoncpp/src/lib_json/json_value.cpp',
             '../third_party/externals/jsoncpp/src/lib_json/json_writer.cpp',
           ],
           'include_dirs': [
-            '../third_party/externals/jsoncpp-chromium/overrides/include/',
             '../third_party/externals/jsoncpp/include/',
             '../third_party/externals/jsoncpp/src/lib_json/',
           ],
           'direct_dependent_settings': {
             'include_dirs': [
-              '../third_party/externals/jsoncpp-chromium/overrides/include/',
               '../third_party/externals/jsoncpp/include/',
             ],
           },
diff --git a/gyp/ktx.gyp b/gyp/ktx.gyp
index 141eba1..dda353d 100644
--- a/gyp/ktx.gyp
+++ b/gyp/ktx.gyp
@@ -8,7 +8,10 @@
     'type': 'static_library',
     'include_dirs' : [
       '../third_party/ktx',
-      '../src/gpu'
+      '../include/gpu',
+      '../src/core',
+      '../src/gpu',
+      '../src/utils',
     ],
     'sources': [
       '../third_party/ktx/ktx.cpp',
diff --git a/gyp/libwebp.gyp b/gyp/libwebp.gyp
index 22a51ba..64ad971 100644
--- a/gyp/libwebp.gyp
+++ b/gyp/libwebp.gyp
@@ -4,6 +4,7 @@
 
 {
   'variables': {
+    'skia_warnings_as_errors': 0,
     'conditions':[
       ['skia_android_framework == 1', {
         'use_system_libwebp': 1,
@@ -159,6 +160,9 @@
             'include_dirs': [
               '../third_party/externals/libwebp/src',
             ],
+            'cflags': [
+              '-Wno-unused-function',  # In C++11 mode, we get this warning when including decode.h.
+            ]
           },
           'conditions': [
             ['OS!="win"', {'product_name': 'webp'}],
diff --git a/gyp/most.gyp b/gyp/most.gyp
index 3b1fa3d..e22629a 100644
--- a/gyp/most.gyp
+++ b/gyp/most.gyp
@@ -15,12 +15,12 @@
         # The minimal set of static libraries for basic Skia functionality.
         'skia_lib.gyp:skia_lib',
 
-        'bench.gyp:bench',
+        'bench.gyp:*',
         'gm.gyp:gm',
         'SampleApp.gyp:SampleApp',
-        'tests.gyp:tests',
         'tools.gyp:tools',
         'pathops_unittest.gyp:*',
+        'pathops_skpclip.gyp:*',
 #       'pdfviewer.gyp:pdfviewer',
         'dm.gyp:dm',
       ],
@@ -30,6 +30,7 @@
         }],
         ['skia_os == "ios"', {
           'dependencies!': [ 'SampleApp.gyp:SampleApp' ],
+          'dependencies': ['iOSShell.gyp:iOSShell' ],
         }],
         ['skia_os == "mac" or skia_os == "linux"', {
           'dependencies': [ 'nanomsg.gyp:*' ],
diff --git a/gyp/nanomsg.gyp b/gyp/nanomsg.gyp
index 1a88c4a..ed6b9df 100644
--- a/gyp/nanomsg.gyp
+++ b/gyp/nanomsg.gyp
@@ -114,10 +114,13 @@
     # To refresh: cd third_party/externals/nanomsg; ./autogen.sh; ./configure; copy from Makefile.
     'conditions': [
       ['skia_os == "linux"', {
-        'cflags': [ '-Wno-missing-field-initializers' ],
-        'libraries': [ '-lanl' ],       # Provides getaddrinfo_a and co.
+        'cflags': [ '-w' ],
+        'libraries': [
+            '-lpthread',
+            '-lanl',  # Provides getaddrinfo_a and co.
+        ],
         'direct_dependent_settings': {
-            'libraries': [ '-lanl' ],
+            'libraries': [ '-lpthread', '-lanl' ],
         },
         'defines=': [             # equals sign throws away most Skia defines (just noise)
           'HAVE_ACCEPT4',
diff --git a/gyp/opts.gyp b/gyp/opts.gyp
index 69e3946..55306e4 100644
--- a/gyp/opts.gyp
+++ b/gyp/opts.gyp
@@ -31,6 +31,7 @@
       'include_dirs': [
         '../src/core',
         '../src/opts',
+        '../src/utils',
       ],
       'conditions': [
         [ 'skia_arch_type == "x86" and skia_os != "ios"', {
@@ -46,6 +47,7 @@
           ],
           'dependencies': [
             'opts_ssse3',
+            'opts_sse4',
           ],
           'sources': [
             '../src/opts/opts_check_x86.cpp',
@@ -55,6 +57,7 @@
             '../src/opts/SkBlitRect_opts_SSE2.cpp',
             '../src/opts/SkBlurImage_opts_SSE2.cpp',
             '../src/opts/SkMorphology_opts_SSE2.cpp',
+            '../src/opts/SkTextureCompression_opts_none.cpp',
             '../src/opts/SkUtils_opts_SSE2.cpp',
             '../src/opts/SkXfermode_opts_SSE2.cpp',
           ],
@@ -81,6 +84,7 @@
             '../src/opts/SkBlitRow_opts_arm.cpp',
             '../src/opts/SkBlurImage_opts_arm.cpp',
             '../src/opts/SkMorphology_opts_arm.cpp',
+            '../src/opts/SkTextureCompression_opts_arm.cpp',
             '../src/opts/SkUtils_opts_arm.cpp',
             '../src/opts/SkXfermode_opts_arm.cpp',
           ],
@@ -102,21 +106,23 @@
         }],
         [ 'skia_arch_type == "mips"', {
           'sources': [
-            '../src/opts/SkBitmapProcState_opts_none.cpp',
             '../src/opts/SkBlitMask_opts_none.cpp',
             '../src/opts/SkBlurImage_opts_none.cpp',
             '../src/opts/SkMorphology_opts_none.cpp',
             '../src/opts/SkUtils_opts_none.cpp',
+            '../src/opts/SkTextureCompression_opts_none.cpp',
             '../src/opts/SkXfermode_opts_none.cpp',
           ],
           'conditions': [
             [ '(mips_arch_variant == "mips32r2") \
                 and (mips_dsp == 1 or mips_dsp == 2)', {
               'sources': [
+                '../src/opts/SkBitmapProcState_opts_mips_dsp.cpp',
                 '../src/opts/SkBlitRow_opts_mips_dsp.cpp',
               ],
             }, {
               'sources': [
+                '../src/opts/SkBitmapProcState_opts_none.cpp',
                 '../src/opts/SkBlitRow_opts_none.cpp',
               ],
             }],
@@ -132,6 +138,7 @@
             '../src/opts/SkBlurImage_opts_none.cpp',
             '../src/opts/SkMorphology_opts_none.cpp',
             '../src/opts/SkUtils_opts_none.cpp',
+            '../src/opts/SkTextureCompression_opts_none.cpp',
             '../src/opts/SkXfermode_opts_none.cpp',
           ],
         }],
@@ -156,6 +163,7 @@
             '../src/opts/SkBlurImage_opts_neon.cpp',
             '../src/opts/SkMorphology_opts_arm.cpp',
             '../src/opts/SkMorphology_opts_neon.cpp',
+            '../src/opts/SkTextureCompression_opts_none.cpp',
             '../src/opts/SkUtils_opts_none.cpp',
             '../src/opts/SkXfermode_opts_arm.cpp',
             '../src/opts/SkXfermode_opts_arm_neon.cpp',
@@ -178,26 +186,80 @@
       ],
       'include_dirs': [
         '../src/core',
+        '../src/utils',
+      ],
+      'sources': [
+        '../src/opts/SkBitmapProcState_opts_SSSE3.cpp',
       ],
       'conditions': [
+        [ 'skia_os == "win"', {
+            'defines' : [ 'SK_CPU_SSE_LEVEL=31' ],
+        }],
+        # (Mac has -mssse3 globally.)
         [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris", "nacl", "chromeos", "android"] \
            and not skia_android_framework', {
           'cflags': [
             '-mssse3',
           ],
         }],
-        # (Mac has -mssse3 globally.)
-        [ 'skia_arch_type == "x86"', {
+      ],
+    },
+    # For the same lame reasons as what is done for skia_opts, we also have to
+    # create another target specifically for SSE4 code as we would not want
+    # to compile the SSE2 code with -msse4 which would potentially allow
+    # gcc to generate SSE4 code.
+    {
+      'target_name': 'opts_sse4',
+      'product_name': 'skia_opts_sse4',
+      'type': 'static_library',
+      'standalone_static_library': 1,
+      'dependencies': [
+        'core.gyp:*',
+        'effects.gyp:*'
+      ],
+      'include_dirs': [
+        '../src/core',
+        '../src/utils',
+      ],
+      'sources': [
+        '../src/opts/SkBlurImage_opts_SSE4.cpp',
+      ],
+      'conditions': [
+        [ 'skia_arch_width == 64', {
           'sources': [
-            '../src/opts/SkBitmapProcState_opts_SSSE3.cpp',
+            '../src/opts/SkBlitRow_opts_SSE4_x64_asm.S',
           ],
         }],
+        [ 'skia_arch_width == 32', {
+          'sources': [
+            '../src/opts/SkBlitRow_opts_SSE4_asm.S',
+          ],
+        }],
+        [ 'skia_os == "win"', {
+            'defines' : [ 'SK_CPU_SSE_LEVEL=41' ],
+        }],
+        [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris", "nacl", "chromeos", "android"] \
+           and not skia_android_framework', {
+          'cflags': [
+            '-msse4.1',
+          ],
+        }],
+        [ 'skia_os == "mac"', {
+          'xcode_settings': {
+            'OTHER_CPLUSPLUSFLAGS!': [
+              '-mssse3',
+            ],
+            'OTHER_CPLUSPLUSFLAGS': [
+              '-msse4.1',
+            ],
+          },
+        }],
       ],
     },
     # NEON code must be compiled with -mfpu=neon which also affects scalar
     # code. To support dynamic NEON code paths, we need to build all
     # NEON-specific sources in a separate static library. The situation
-    # is very similar to the SSSE3 one.
+    # is very similar to the SSSE3 and SSE4 one.
     {
       'target_name': 'opts_neon',
       'product_name': 'skia_opts_neon',
@@ -210,6 +272,7 @@
       'include_dirs': [
         '../src/core',
         '../src/opts',
+        '../src/utils',
       ],
       'cflags!': [
         '-fno-omit-frame-pointer',
@@ -239,6 +302,7 @@
         '../src/opts/SkBlitRow_opts_arm_neon.cpp',
         '../src/opts/SkBlurImage_opts_neon.cpp',
         '../src/opts/SkMorphology_opts_neon.cpp',
+        '../src/opts/SkTextureCompression_opts_neon.cpp',
         '../src/opts/SkXfermode_opts_arm_neon.cpp',
       ],
     },
diff --git a/gyp/pathops_skpclip.gyp b/gyp/pathops_skpclip.gyp
new file mode 100755
index 0000000..32a909b
--- /dev/null
+++ b/gyp/pathops_skpclip.gyp
@@ -0,0 +1,47 @@
+# GYP file to build pathops skp clip test.
+{
+  'includes': [
+    'apptype_console.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'pathops_skpclip',
+      'type': 'executable',
+      'include_dirs': [
+        '../src/core',
+        '../src/effects',
+        '../src/lazy',
+        '../src/pathops',
+        '../src/pipe/utils',
+        '../src/utils',
+      ],
+      'dependencies': [
+        'flags.gyp:flags',
+        'skia_lib.gyp:skia_lib',
+        'tools.gyp:crash_handler',
+        'tools.gyp:resources',
+      ],
+      'sources': [
+		'../tests/PathOpsDebug.cpp',
+        '../tests/PathOpsSkpClipTest.cpp',
+        '../src/utils/SkTaskGroup.cpp',
+      ],
+      'conditions': [
+        [ 'skia_android_framework == 1', {
+          'libraries': [
+            '-lskia',
+          ],
+          'libraries!': [
+            '-lz',
+            '-llog',
+          ],
+        }],
+        [ 'skia_gpu == 1', {
+          'include_dirs': [
+            '../src/gpu',
+          ],
+        }],
+      ],
+    },
+  ],
+}
diff --git a/gyp/pathops_unittest.gyp b/gyp/pathops_unittest.gyp
index 35eeabd..1aaccfa 100644
--- a/gyp/pathops_unittest.gyp
+++ b/gyp/pathops_unittest.gyp
@@ -1,4 +1,4 @@
-# GYP file to build unit tests.
+# GYP file to build pathops unit tests.
 {
   'includes': [
     'apptype_console.gypi',
@@ -7,35 +7,32 @@
     {
       'target_name': 'pathops_unittest',
       'type': 'executable',
-      'suppress_wildcard': '1',
-      'include_dirs' : [
-        '../src/core',
-        '../src/effects',
-        '../src/lazy',
-        '../src/pathops',
-        '../src/pdf',
-        '../src/pipe/utils',
-        '../src/utils',
-        '../tools/',
-      ],
       'includes': [
         'pathops_unittest.gypi',
       ],
+      'dependencies': [
+        'flags.gyp:flags_common',
+        'tools.gyp:crash_handler',
+      ],
       'sources': [
         '../tests/PathOpsAngleIdeas.cpp',
+        '../tests/PathOpsBattles.cpp',
         '../tests/PathOpsCubicLineIntersectionIdeas.cpp',
         '../tests/PathOpsDebug.cpp',
         '../tests/PathOpsOpLoopThreadedTest.cpp',
-        '../tests/PathOpsSkpClipTest.cpp',
-        '../tests/Test.cpp',
         '../tests/skia_test.cpp',
-        '../tests/Test.h',
-      ],
-      'dependencies': [
-        'skia_lib.gyp:skia_lib',
-        'flags.gyp:flags',
+        '../src/utils/SkTaskGroup.cpp',
       ],
       'conditions': [
+        [ 'skia_android_framework == 1', {
+          'libraries': [
+            '-lskia',
+          ],
+          'libraries!': [
+            '-lz',
+            '-llog',
+          ],
+        }],
         [ 'skia_gpu == 1', {
           'include_dirs': [
             '../src/gpu',
diff --git a/gyp/pathops_unittest.gypi b/gyp/pathops_unittest.gypi
index e9f40d6..9e070ab 100644
--- a/gyp/pathops_unittest.gypi
+++ b/gyp/pathops_unittest.gypi
@@ -1,5 +1,22 @@
+# Common gypi for pathops unit tests.
 {
+  'include_dirs': [
+    '../src/core',
+    '../src/effects',
+    '../src/lazy',
+    '../src/pathops',
+    '../src/pipe/utils',
+    '../src/utils',
+  ],
+  'dependencies': [
+    'flags.gyp:flags',
+    'skia_lib.gyp:skia_lib',
+    'tools.gyp:resources',
+  ],
   'sources': [
+    '../tests/Test.cpp',
+    '../tests/Test.h',
+
     '../tests/PathOpsAngleTest.cpp',
     '../tests/PathOpsBoundsTest.cpp',
     '../tests/PathOpsCubicIntersectionTest.cpp',
@@ -38,6 +55,7 @@
     '../tests/PathOpsSkpTest.cpp',
     '../tests/PathOpsTestCommon.cpp',
     '../tests/PathOpsThreadedCommon.cpp',
+    '../tests/PathOpsTightBoundsTest.cpp',
     '../tests/PathOpsCubicIntersectionTestData.h',
     '../tests/PathOpsExtendedTest.h',
     '../tests/PathOpsQuadIntersectionTestData.h',
diff --git a/gyp/ports.gyp b/gyp/ports.gyp
index ea38ba8..268f6fd 100644
--- a/gyp/ports.gyp
+++ b/gyp/ports.gyp
@@ -92,7 +92,7 @@
                 ],
               },
               'sources': [
-                '../src/fonts/SkFontMgr_fontconfig.cpp',
+                '../src/ports/SkFontMgr_fontconfig.cpp',
                 '../src/ports/SkFontHost_fontconfig.cpp',
                 '../src/ports/SkFontConfigInterface_direct.cpp',
               ],
@@ -149,14 +149,14 @@
           ],
           'conditions': [
             #    when we build for win, we only want one of these default files
-            [ 'skia_directwrite', {
-              'sources!': [
-                '../src/ports/SkFontMgr_default_gdi.cpp',
-              ],
-            }, { # else gdi
+            [ 'skia_gdi', {
               'sources!': [
                 '../src/ports/SkFontMgr_default_dw.cpp',
               ],
+            }, { # normally default to direct write
+              'sources!': [
+                '../src/ports/SkFontMgr_default_gdi.cpp',
+              ],
             }],
           ],
         }, { # else !win
@@ -182,9 +182,8 @@
           ],
           'sources': [
             '../src/ports/SkDebug_android.cpp',
-            '../src/ports/SkFontConfigInterface_android.cpp',
             '../src/ports/SkFontConfigParser_android.cpp',
-            '../src/ports/SkFontHost_fontconfig.cpp',
+            '../src/ports/SkFontMgr_android.cpp',
           ],
           'dependencies': [
              'android_deps.gyp:expat',
diff --git a/gyp/public_headers.gypi b/gyp/public_headers.gypi
index f110c8c..6e61b4e 100644
--- a/gyp/public_headers.gypi
+++ b/gyp/public_headers.gypi
@@ -7,283 +7,270 @@
 {
   'variables': {
     'header_filenames': [
-      'pdf/SkPDFDevice.h',
-      'pdf/SkPDFDocument.h',
-      'svg/SkSVGTypes.h',
-      'svg/SkSVGBase.h',
-      'svg/SkSVGAttribute.h',
-      'svg/SkSVGParser.h',
-      'svg/SkSVGPaintState.h',
       'animator/SkAnimator.h',
       'animator/SkAnimatorView.h',
-      'gpu/GrTexture.h',
-      'gpu/SkGr.h',
-      'gpu/GrContext.h',
-      'gpu/gl/GrGLConfig_chrome.h',
-      'gpu/gl/SkNativeGLContext.h',
-      'gpu/gl/SkMesaGLContext.h',
-      'gpu/gl/SkDebugGLContext.h',
-      'gpu/gl/SkANGLEGLContext.h',
-      'gpu/gl/GrGLConfig.h',
-      'gpu/gl/GrGLInterface.h',
-      'gpu/gl/SkNullGLContext.h',
-      'gpu/gl/GrGLFunctions.h',
-      'gpu/gl/SkGLContextHelper.h',
-      'gpu/gl/GrGLExtensions.h',
-      'gpu/SkGpuDevice.h',
-      'gpu/GrTypes.h',
-      'gpu/GrFontScaler.h',
-      'gpu/GrResource.h',
-      'gpu/GrKey.h',
-      'gpu/GrOvalRenderer.h',
-      'gpu/GrEffectUnitTest.h',
-      'gpu/GrConfig.h',
-      'gpu/GrPaint.h',
-      'gpu/GrPathRendererChain.h',
-      'gpu/GrTBackendEffectFactory.h',
-      'gpu/GrDrawEffect.h',
-      'gpu/GrTextContext.h',
-      'gpu/GrEffect.h',
-      'gpu/SkGrTexturePixelRef.h',
-      'gpu/GrTextureAccess.h',
-      'gpu/GrRect.h',
-      'gpu/GrEffectStage.h',
-      'gpu/GrClipData.h',
-      'gpu/GrUserConfig.h',
-      'gpu/SkGrPixelRef.h',
-      'gpu/GrAARectRenderer.h',
-      'gpu/GrColor.h',
-      'gpu/GrGlyph.h',
-      'gpu/GrBackendEffectFactory.h',
-      'gpu/GrContextFactory.h',
-      'gpu/GrRenderTarget.h',
-      'gpu/GrSurface.h',
-      'gpu/GrTypesPriv.h',
-      'config/sk_stdint.h',
       'config/SkUserConfig.h',
-      'pipe/SkGPipe.h',
-      'images/SkMovie.h',
-      'images/SkPageFlipper.h',
-      'images/SkForceLinking.h',
-      'effects/SkMorphologyImageFilter.h',
+      'config/sk_stdint.h',
+      'core/SkAdvancedTypefaceMetrics.h',
+      'core/SkAnnotation.h',
+      'core/SkBitmap.h',
+      'core/SkBlitRow.h',
+      'core/SkCanvas.h',
+      'core/SkChunkAlloc.h',
+      'core/SkClipStack.h',
+      'core/SkColor.h',
+      'core/SkColorFilter.h',
+      'core/SkColorPriv.h',
+      'core/SkColorShader.h',
+      'core/SkColorTable.h',
+      'core/SkComposeShader.h',
+      'core/SkData.h',
+      'core/SkDataTable.h',
+      'core/SkDeque.h',
+      'core/SkDevice.h',
+      'core/SkDither.h',
+      'core/SkDocument.h',
+      'core/SkDraw.h',
+      'core/SkDrawFilter.h',
+      'core/SkDrawLooper.h',
+      'core/SkEndian.h',
+      'core/SkError.h',
+      'core/SkFixed.h',
+      'core/SkFlate.h',
+      'core/SkFlattenable.h',
+      'core/SkFlattenableBuffers.h',
+      'core/SkFlattenableSerialization.h',
+      'core/SkFloatBits.h',
+      'core/SkFloatingPoint.h',
+      'core/SkFontHost.h',
+      'core/SkFontLCDConfig.h',
+      'core/SkGeometry.h',
+      'core/SkGraphics.h',
+      'core/SkImage.h',
+      'core/SkImageDecoder.h',
+      'core/SkImageEncoder.h',
+      'core/SkImageFilter.h',
+      'core/SkInstCnt.h',
+      'core/SkLineClipper.h',
+      'core/SkMallocPixelRef.h',
+      'core/SkMask.h',
+      'core/SkMaskFilter.h',
+      'core/SkMath.h',
+      'core/SkMatrix.h',
+      'core/SkMetaData.h',
+      'core/SkOSFile.h',
+      'core/SkPackBits.h',
+      'core/SkPaint.h',
+      'core/SkPaintOptionsAndroid.h',
+      'core/SkPath.h',
+      'core/SkPathEffect.h',
+      'core/SkPathMeasure.h',
+      'core/SkPicture.h',
+      'core/SkPixelRef.h',
+      'core/SkPoint.h',
+      'core/SkPostConfig.h',
+      'core/SkPreConfig.h',
+      'core/SkRRect.h',
+      'core/SkRasterizer.h',
+      'core/SkRect.h',
+      'core/SkRefCnt.h',
+      'core/SkRegion.h',
+      'core/SkScalar.h',
+      'core/SkShader.h',
+      'core/SkSize.h',
+      'core/SkStream.h',
+      'core/SkString.h',
+      'core/SkStringUtils.h',
+      'core/SkStrokeRec.h',
+      'core/SkSurface.h',
+      'core/SkTArray.h',
+      'core/SkTDArray.h',
+      'core/SkTDStack.h',
+      'core/SkTDict.h',
+      'core/SkTInternalLList.h',
+      'core/SkTLazy.h',
+      'core/SkTRegistry.h',
+      'core/SkTSearch.h',
+      'core/SkTemplates.h',
+      'core/SkThread.h',
+      'core/SkTime.h',
+      'core/SkTypeface.h',
+      'core/SkTypes.h',
+      'core/SkUnPreMultiply.h',
+      'core/SkUtils.h',
+      'core/SkWeakRefCnt.h',
+      'core/SkWriter32.h',
+      'core/SkXfermode.h',
+      'device/xps/SkConstexprMath.h',
+      'device/xps/SkXPSDevice.h',
+      'effects/Sk1DPathEffect.h',
       'effects/Sk2DPathEffect.h',
-      'effects/SkXfermodeImageFilter.h',
       'effects/SkAlphaThresholdFilter.h',
       'effects/SkArithmeticMode.h',
-      'effects/SkMergeImageFilter.h',
-      'effects/SkPerlinNoiseShader.h',
-      'effects/SkLerpXfermode.h',
-      'effects/SkLumaColorFilter.h',
-      'effects/SkRectShaderImageFilter.h',
-      'effects/SkMagnifierImageFilter.h',
-      'effects/SkBicubicImageFilter.h',
-      'effects/SkPorterDuff.h',
-      'effects/SkBlurImageFilter.h',
-      'effects/SkTableMaskFilter.h',
       'effects/SkAvoidXfermode.h',
       'effects/SkBitmapSource.h',
-      'effects/SkCornerPathEffect.h',
-      'effects/SkTransparentShader.h',
-      'effects/SkStippleMaskFilter.h',
-      'effects/SkPaintFlagsDrawFilter.h',
-      'effects/SkOffsetImageFilter.h',
-      'effects/SkDiscretePathEffect.h',
-      'effects/SkTableColorFilter.h',
-      'effects/SkGradientShader.h',
-      'effects/SkEmbossMaskFilter.h',
-      'effects/SkComposeImageFilter.h',
-      'effects/SkTestImageFilters.h',
-      'effects/SkLayerRasterizer.h',
-      'effects/SkDashPathEffect.h',
-      'effects/Sk1DPathEffect.h',
-      'effects/SkBlurMaskFilter.h',
-      'effects/SkDrawExtraPathEffect.h',
-      'effects/SkDisplacementMapEffect.h',
-      'effects/SkPixelXorXfermode.h',
-      'effects/SkColorMatrixFilter.h',
-      'effects/SkColorMatrix.h',
       'effects/SkBlurDrawLooper.h',
+      'effects/SkBlurImageFilter.h',
+      'effects/SkBlurMaskFilter.h',
       'effects/SkColorFilterImageFilter.h',
-      'effects/SkLayerDrawLooper.h',
-      'effects/SkLightingImageFilter.h',
+      'effects/SkColorMatrix.h',
+      'effects/SkColorMatrixFilter.h',
+      'effects/SkComposeImageFilter.h',
+      'effects/SkCornerPathEffect.h',
+      'effects/SkDashPathEffect.h',
+      'effects/SkDiscretePathEffect.h',
+      'effects/SkDisplacementMapEffect.h',
+      'effects/SkDrawExtraPathEffect.h',
       'effects/SkDropShadowImageFilter.h',
+      'effects/SkEmbossMaskFilter.h',
+      'effects/SkGradientShader.h',
+      'effects/SkLayerDrawLooper.h',
+      'effects/SkLayerRasterizer.h',
+      'effects/SkLerpXfermode.h',
+      'effects/SkLightingImageFilter.h',
+      'effects/SkLumaColorFilter.h',
+      'effects/SkMagnifierImageFilter.h',
       'effects/SkMatrixConvolutionImageFilter.h',
+      'effects/SkMergeImageFilter.h',
+      'effects/SkMorphologyImageFilter.h',
+      'effects/SkOffsetImageFilter.h',
+      'effects/SkPaintFlagsDrawFilter.h',
+      'effects/SkPerlinNoiseShader.h',
+      'effects/SkPixelXorXfermode.h',
+      'effects/SkPorterDuff.h',
+      'effects/SkRectShaderImageFilter.h',
+      'effects/SkTableColorFilter.h',
+      'effects/SkTableMaskFilter.h',
+      'effects/SkTestImageFilters.h',
+      'effects/SkTransparentShader.h',
+      'effects/SkXfermodeImageFilter.h',
+      'gpu/GrAARectRenderer.h',
+      'gpu/GrBackendEffectFactory.h',
+      'gpu/GrClipData.h',
+      'gpu/GrColor.h',
+      'gpu/GrConfig.h',
+      'gpu/GrContext.h',
+      'gpu/GrContextFactory.h',
+      'gpu/GrDrawEffect.h',
+      'gpu/GrEffect.h',
+      'gpu/GrEffectStage.h',
+      'gpu/GrEffectUnitTest.h',
+      'gpu/GrFontScaler.h',
+      'gpu/GrGlyph.h',
+      'gpu/GrKey.h',
+      'gpu/GrOvalRenderer.h',
+      'gpu/GrPaint.h',
+      'gpu/GrPathRendererChain.h',
+      'gpu/GrRect.h',
+      'gpu/GrRenderTarget.h',
+      'gpu/GrResource.h',
+      'gpu/GrSurface.h',
+      'gpu/GrTBackendEffectFactory.h',
+      'gpu/GrTextContext.h',
+      'gpu/GrTexture.h',
+      'gpu/GrTextureAccess.h',
+      'gpu/GrTypes.h',
+      'gpu/GrTypesPriv.h',
+      'gpu/GrUserConfig.h',
+      'gpu/SkGpuDevice.h',
+      'gpu/SkGr.h',
+      'gpu/SkGrPixelRef.h',
+      'gpu/SkGrTexturePixelRef.h',
+      'gpu/gl/GrGLConfig.h',
+      'gpu/gl/GrGLConfig_chrome.h',
+      'gpu/gl/GrGLExtensions.h',
+      'gpu/gl/GrGLFunctions.h',
+      'gpu/gl/GrGLInterface.h',
+      'gpu/gl/SkANGLEGLContext.h',
+      'gpu/gl/SkDebugGLContext.h',
+      'gpu/gl/SkGLContextHelper.h',
+      'gpu/gl/SkMesaGLContext.h',
+      'gpu/gl/SkNativeGLContext.h',
+      'gpu/gl/SkNullGLContext.h',
+      'images/SkForceLinking.h',
+      'images/SkMovie.h',
+      'images/SkPageFlipper.h',
+      'pathops/SkPathOps.h',
+      'pdf/SkPDFDevice.h',
+      'pdf/SkPDFDocument.h',
+      'pipe/SkGPipe.h',
+      'ports/SkFontConfigInterface.h',
+      'ports/SkFontMgr.h',
+      'ports/SkFontStyle.h',
+      'ports/SkTypeface_android.h',
+      'ports/SkTypeface_mac.h',
+      'ports/SkTypeface_win.h',
+      'svg/SkSVGAttribute.h',
+      'svg/SkSVGBase.h',
+      'svg/SkSVGPaintState.h',
+      'svg/SkSVGParser.h',
+      'svg/SkSVGTypes.h',
+      'utils/SkBoundaryPatch.h',
+      'utils/SkCamera.h',
+      'utils/SkCubicInterval.h',
+      'utils/SkCullPoints.h',
+      'utils/SkDebugUtils.h',
+      'utils/SkDeferredCanvas.h',
+      'utils/SkDumpCanvas.h',
+      'utils/SkInterpolator.h',
+      'utils/SkLayer.h',
+      'utils/SkLua.h',
+      'utils/SkLuaCanvas.h',
+      'utils/SkMatrix44.h',
+      'utils/SkMeshUtils.h',
+      'utils/SkNWayCanvas.h',
+      'utils/SkNinePatch.h',
+      'utils/SkNullCanvas.h',
+      'utils/SkParse.h',
+      'utils/SkParsePaint.h',
+      'utils/SkParsePath.h',
+      'utils/SkPathUtils.h',
+      'utils/SkPictureUtils.h',
+      'utils/SkProxyCanvas.h',
+      'utils/SkRTConf.h',
+      'utils/SkRandom.h',
+      'utils/SkWGL.h',
+      'utils/ios/SkStream_NSData.h',
+      'utils/mac/SkCGUtils.h',
       'utils/win/SkAutoCoInitialize.h',
       'utils/win/SkHRESULT.h',
       'utils/win/SkIStream.h',
       'utils/win/SkTScopedComPtr.h',
-      'utils/SkBoundaryPatch.h',
-      'utils/SkPictureUtils.h',
-      'utils/SkRandom.h',
-      'utils/SkMeshUtils.h',
-      'utils/SkCullPoints.h',
-      'utils/SkCamera.h',
-      'utils/SkLua.h',
-      'utils/SkParsePaint.h',
-      'utils/SkCountdown.h',
-      'utils/SkRunnable.h',
-      'utils/SkParse.h',
-      'utils/SkThreadPool.h',
-      'utils/SkMatrix44.h',
-      'utils/SkInterpolator.h',
-      'utils/SkWGL.h',
-      'utils/SkDumpCanvas.h',
-      'utils/SkRTConf.h',
-      'utils/SkCubicInterval.h',
-      'utils/SkLuaCanvas.h',
-      'utils/SkDebugUtils.h',
-      'utils/SkLayer.h',
-      'utils/SkProxyCanvas.h',
-      'utils/SkNWayCanvas.h',
-      'utils/SkPathUtils.h',
-      'utils/SkDeferredCanvas.h',
-      'utils/ios/SkStream_NSData.h',
-      'utils/SkNullCanvas.h',
-      'utils/SkParsePath.h',
-      'utils/SkJSON.h',
-      'utils/SkCondVar.h',
-      'utils/SkNinePatch.h',
-      'utils/mac/SkCGUtils.h',
+      'views/SkApplication.h',
+      'views/SkBGViewArtist.h',
+      'views/SkEvent.h',
+      'views/SkEventSink.h',
+      'views/SkKey.h',
+      'views/SkOSMenu.h',
+      'views/SkOSWindow_Android.h',
+      'views/SkOSWindow_Mac.h',
+      'views/SkOSWindow_NaCl.h',
+      'views/SkOSWindow_SDL.h',
+      'views/SkOSWindow_Unix.h',
+      'views/SkOSWindow_Win.h',
+      'views/SkOSWindow_iOS.h',
+      'views/SkStackViewLayout.h',
+      'views/SkSystemEventTypes.h',
+      'views/SkTextBox.h',
+      'views/SkTouchGesture.h',
+      'views/SkView.h',
+      'views/SkViewInflate.h',
+      'views/SkWidget.h',
+      'views/SkWindow.h',
+      'views/android/AndroidKeyToSkKey.h',
+      'views/animated/SkBorderView.h',
+      'views/animated/SkImageView.h',
+      'views/animated/SkProgressBarView.h',
+      'views/animated/SkScrollBarView.h',
+      'views/animated/SkWidgetViews.h',
+      'views/unix/XkeysToSkKeys.h',
+      'views/unix/keysym2ucs.h',
+      'xml/SkBML_WXMLParser.h',
+      'xml/SkBML_XMLParser.h',
       'xml/SkDOM.h',
       'xml/SkJS.h',
       'xml/SkXMLParser.h',
-      'xml/SkBML_XMLParser.h',
-      'xml/SkBML_WXMLParser.h',
       'xml/SkXMLWriter.h',
-      'device/xps/SkXPSDevice.h',
-      'device/xps/SkConstexprMath.h',
-      'ports/SkTypeface_win.h',
-      'ports/SkHarfBuzzFont.h',
-      'ports/SkFontConfigInterface.h',
-      'ports/SkTypeface_mac.h',
-      'ports/SkTypeface_android.h',
-      'ports/SkFontStyle.h',
-      'ports/SkFontMgr.h',
-      'text/SkTextLayout.h',
-      'core/SkColor.h',
-      'core/SkFontHost.h',
-      'core/SkMetaData.h',
-      'core/SkRRect.h',
-      'core/SkMatrix.h',
-      'core/SkDataTable.h',
-      'core/SkScalar.h',
-      'core/SkFlattenableSerialization.h',
-      'core/SkTypeface.h',
-      'core/SkImageEncoder.h',
-      'core/SkDrawFilter.h',
-      'core/SkTDict.h',
-      'core/SkRasterizer.h',
-      'core/SkColorPriv.h',
-      'core/SkFloatingPoint.h',
-      'core/SkOSFile.h',
-      'core/SkPaint.h',
-      'core/SkTDStack.h',
-      'core/SkDither.h',
-      'core/SkFixed.h',
-      'core/SkDocument.h',
-      'core/SkInstCnt.h',
-      'core/SkEndian.h',
-      'core/SkColorTable.h',
-      'core/SkBitmap.h',
-      'core/SkDraw.h',
-      'core/SkPackBits.h',
-      'core/SkFloatBits.h',
-      'core/SkDeque.h',
-      'core/SkTRegistry.h',
-      'core/SkTLazy.h',
-      'core/SkComposeShader.h',
-      'core/SkUtils.h',
-      'core/SkImage.h',
-      'core/SkPaintOptionsAndroid.h',
-      'core/SkDeviceProperties.h',
-      'core/SkGraphics.h',
-      'core/SkCanvas.h',
-      'core/SkPicture.h',
-      'core/SkClipStack.h',
-      'core/SkXfermode.h',
-      'core/SkColorFilter.h',
-      'core/SkRegion.h',
-      'core/SkRefCnt.h',
-      'core/SkStream.h',
-      'core/SkFontLCDConfig.h',
-      'core/SkBlitRow.h',
-      'core/SkGeometry.h',
-      'core/SkStrokeRec.h',
-      'core/SkImageDecoder.h',
-      'core/SkTime.h',
-      'core/SkPathMeasure.h',
-      'core/SkMaskFilter.h',
-      'core/SkFlate.h',
-      'core/SkTDArray.h',
-      'core/SkAnnotation.h',
-      'core/SkChecksum.h',
-      'core/SkMath.h',
-      'core/SkDrawLooper.h',
-      'core/SkFlattenableBuffers.h',
-      'core/SkTemplates.h',
-      'core/SkMask.h',
-      'core/SkMallocPixelRef.h',
-      'core/SkWeakRefCnt.h',
-      'core/SkTypes.h',
-      'core/SkThread.h',
-      'core/SkData.h',
-      'core/SkPoint.h',
-      'core/SkColorShader.h',
-      'core/SkChunkAlloc.h',
-      'core/SkUnPreMultiply.h',
-      'core/SkReader32.h',
-      'core/SkDevice.h',
-      'core/SkImageFilter.h',
-      'core/SkAdvancedTypefaceMetrics.h',
-      'core/SkTInternalLList.h',
-      'core/SkTArray.h',
-      'core/SkStringUtils.h',
-      'core/SkPreConfig.h',
-      'core/SkLineClipper.h',
-      'core/SkPathEffect.h',
-      'core/SkString.h',
-      'core/SkPixelRef.h',
-      'core/SkSize.h',
-      'core/SkEmptyShader.h',
-      'core/SkSurface.h',
-      'core/SkPostConfig.h',
-      'core/SkShader.h',
-      'core/SkWriter32.h',
-      'core/SkError.h',
-      'core/SkPath.h',
-      'core/SkFlattenable.h',
-      'core/SkTSearch.h',
-      'core/SkRect.h',
-      'pathops/SkPathOps.h',
-      'views/SkTouchGesture.h',
-      'views/SkEvent.h',
-      'views/SkOSWindow_NaCl.h',
-      'views/SkTextBox.h',
-      'views/SkViewInflate.h',
-      'views/SkOSWindow_iOS.h',
-      'views/SkBGViewArtist.h',
-      'views/SkOSWindow_SDL.h',
-      'views/SkWindow.h',
-      'views/SkSystemEventTypes.h',
-      'views/SkOSWindow_Android.h',
-      'views/SkOSWindow_Mac.h',
-      'views/android/AndroidKeyToSkKey.h',
-      'views/SkEventSink.h',
-      'views/animated/SkImageView.h',
-      'views/animated/SkWidgetViews.h',
-      'views/animated/SkProgressBarView.h',
-      'views/animated/SkBorderView.h',
-      'views/animated/SkScrollBarView.h',
-      'views/SkStackViewLayout.h',
-      'views/SkApplication.h',
-      'views/unix/keysym2ucs.h',
-      'views/unix/XkeysToSkKeys.h',
-      'views/SkKey.h',
-      'views/SkView.h',
-      'views/SkOSMenu.h',
-      'views/SkOSWindow_Unix.h',
-      'views/SkWidget.h',
-      'views/SkOSWindow_Win.h',
     ],
   },
 }
diff --git a/gyp/resources.gyp b/gyp/resources.gyp
deleted file mode 100644
index 48e96c3..0000000
--- a/gyp/resources.gyp
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2014 Google Inc.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'targets': [
-    {
-      'target_name': 'resources',
-      'type': 'static_library',
-      'sources': [
-        '../tools/Resources.cpp',
-        '../tools/Resources.h',
-      ],
-      'dependencies': [
-        'flags.gyp:flags',
-        'skia_lib.gyp:skia_lib',
-      ],
-      'direct_dependent_settings': {
-        'include_dirs': [
-          '../tools/',
-        ],
-      },
-    },
-  ]
-}
diff --git a/gyp/skia_for_android_framework_defines.gypi b/gyp/skia_for_android_framework_defines.gypi
index 9559f43..ec0725f 100644
--- a/gyp/skia_for_android_framework_defines.gypi
+++ b/gyp/skia_for_android_framework_defines.gypi
@@ -13,17 +13,15 @@
     # If these become 'permanent', they should be moved into common_variables.gypi
     #
     'skia_for_android_framework_defines': [
-      'SK_SUPPORT_LEGACY_SETCONFIG_INFO',
-      'SK_SUPPORT_LEGACY_SETCONFIG',
-      'SK_SUPPORT_LEGACY_IMAGEDECODER_CONFIG',
-      'SK_SUPPORT_LEGACY_DEVICE_VIRTUAL_ISOPAQUE',
-      'SK_SUPPORT_LEGACY_BITMAP_CONFIG',
+      'SK_SUPPORT_LEGACY_PUBLIC_IMAGEINFO_FIELDS',
+      'SK_SUPPORT_LEGACY_ALLOCPIXELS_BOOL',
+      'SK_SUPPORT_LEGACY_GETDEVICE',
       # Needed until we fix skbug.com/2440.
       'SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG',
       # Transitional, for deprecated SkCanvas::SaveFlags methods.
       'SK_ATTR_DEPRECATED=SK_NOTHING_ARG1',
-      'SK_SUPPORT_LEGACY_SHADER_LOCALMATRIX',
-      'SK_SUPPORT_LEGACY_COMPUTE_CONFIG_SIZE',
+      'SK_LEGACY_PICTURE_SIZE_API',
+      'SK_LEGACY_PICTURE_DRAW_API',
     ],
   },
 }
diff --git a/gyp/skia_for_chromium_defines.gypi b/gyp/skia_for_chromium_defines.gypi
index 2212519..e6cb65e 100644
--- a/gyp/skia_for_chromium_defines.gypi
+++ b/gyp/skia_for_chromium_defines.gypi
@@ -13,13 +13,7 @@
     # If these become 'permanent', they should be moved into skia_common.gypi
     #
     'skia_for_chromium_defines': [
-      'SK_SUPPORT_LEGACY_GETTOPDEVICE',
-      'SK_SUPPORT_LEGACY_BITMAP_CONFIG',
-      'SK_SUPPORT_LEGACY_DEVICE_VIRTUAL_ISOPAQUE',
-      'SK_SUPPORT_LEGACY_N32_NAME',
-      'SK_SUPPORT_LEGACY_SETCONFIG',
-      'SK_IGNORE_ETC1_SUPPORT',
-      'SK_IGNORE_GPU_DITHER',
+      'SK_SUPPORT_LEGACY_TEXTRENDERMODE',
     ],
   },
 }
diff --git a/gyp/skia_launcher.gyp b/gyp/skia_launcher.gyp
new file mode 100644
index 0000000..d9970b4
--- /dev/null
+++ b/gyp/skia_launcher.gyp
@@ -0,0 +1,3 @@
+{
+  'includes': [ '../platform_tools/android/gyp/skia_launcher.gypi' ]
+}
diff --git a/gyp/skia_lib.gyp b/gyp/skia_lib.gyp
index 5f3f141..6bf6bc0 100644
--- a/gyp/skia_lib.gyp
+++ b/gyp/skia_lib.gyp
@@ -15,6 +15,7 @@
       [ 'skia_arch_type == "x86" and skia_os != "android"', {
         'component_libs': [
           'opts.gyp:opts_ssse3',
+          'opts.gyp:opts_sse4',
         ],
       }],
       [ 'arm_neon == 1', {
@@ -32,6 +33,7 @@
   'targets': [
     {
       'target_name': 'skia_lib',
+      'sources': [ '<(skia_src_path)/core/SkForceCPlusPlusLinking.cpp', ],
       'conditions': [
         [ 'skia_shared_lib', {
           'conditions': [
diff --git a/gyp/tests.gyp b/gyp/tests.gyp
deleted file mode 100644
index 80768ef..0000000
--- a/gyp/tests.gyp
+++ /dev/null
@@ -1,36 +0,0 @@
-# GYP file to build unit tests.
-{
-  'includes': [
-    'apptype_console.gypi',
-  ],
-  'targets': [
-    {
-      'target_name': 'tests',
-      'type': 'executable',
-      'includes': [
-        'pathops_unittest.gypi',
-        'tests.gypi',
-      ],
-      'dependencies': [ 'crash_handler.gyp:CrashHandler' ],
-      'sources': [
-        '../tests/skia_test.cpp',
-      ],
-      'conditions': [
-        [ 'skia_android_framework == 1', {
-          'libraries': [
-            '-lskia',
-          ],
-          'libraries!': [
-            '-lz',
-            '-llog',
-          ],
-        }],
-        [ 'skia_gpu == 1', {
-          'include_dirs': [
-            '../src/gpu',
-          ],
-        }],
-      ],
-    },
-  ],
-}
diff --git a/gyp/tests.gypi b/gyp/tests.gypi
index 9e418d6..a319722 100644
--- a/gyp/tests.gypi
+++ b/gyp/tests.gypi
@@ -18,11 +18,27 @@
   ],
   'dependencies': [
     'experimental.gyp:experimental',
-    'flags.gyp:flags',
+    'flags.gyp:flags_common',
     'pdf.gyp:pdf',
-    'resources.gyp:resources',
     'skia_lib.gyp:skia_lib',
     'tools.gyp:picture_utils',
+    'tools.gyp:resources',
+    'tools.gyp:sk_tool_utils',
+  ],
+  'conditions': [
+    [ 'skia_os == "android"', {
+      'include_dirs': [
+        '../src/ports',
+      ],
+      'sources': [
+        '../tests/FontConfigParser.cpp',
+      ],
+    }],
+    [ 'skia_android_framework == 1', {
+      'libraries': [
+        '-ldl',
+      ],
+    }],
   ],
   'sources': [
     '../tests/Test.cpp',
@@ -30,7 +46,6 @@
 
     '../tests/AAClipTest.cpp',
     '../tests/ARGBImageEncoderTest.cpp',
-    '../tests/AndroidPaintTest.cpp',
     '../tests/AnnotationTest.cpp',
     '../tests/AsADashTest.cpp',
     '../tests/AtomicTest.cpp',
@@ -45,6 +60,7 @@
     '../tests/BlitRowTest.cpp',
     '../tests/BlurTest.cpp',
     '../tests/CachedDecodingPixelRefTest.cpp',
+    '../tests/CanvasStateHelpers.cpp',
     '../tests/CanvasStateTest.cpp',
     '../tests/CanvasTest.cpp',
     '../tests/ChecksumTest.cpp',
@@ -74,11 +90,12 @@
     '../tests/FitsInTest.cpp',
     '../tests/FlatDataTest.cpp',
     '../tests/FlateTest.cpp',
+    '../tests/FloatingPointTextureTest.cpp',
     '../tests/FontHostStreamTest.cpp',
     '../tests/FontHostTest.cpp',
-    '../tests/FontObjTest.cpp',
     '../tests/FontMgrTest.cpp',
     '../tests/FontNamesTest.cpp',
+    '../tests/FontObjTest.cpp',
     '../tests/FrontBufferedStreamTest.cpp',
     '../tests/GLInterfaceValidationTest.cpp',
     '../tests/GLProgramsTest.cpp',
@@ -86,21 +103,27 @@
     '../tests/GifTest.cpp',
     '../tests/GpuColorFilterTest.cpp',
     '../tests/GpuDrawPathTest.cpp',
+    '../tests/GpuLayerCacheTest.cpp',
     '../tests/GpuRectanizerTest.cpp',
     '../tests/GrBinHashKeyTest.cpp',
     '../tests/GrContextFactoryTest.cpp',
     '../tests/GrDrawTargetTest.cpp',
+    '../tests/GrAllocatorTest.cpp',
     '../tests/GrMemoryPoolTest.cpp',
-    '../tests/GrRedBlackTreeTest.cpp',
     '../tests/GrOrderedSetTest.cpp',
+    '../tests/GrGLSLPrettyPrintTest.cpp',
+    '../tests/GrRedBlackTreeTest.cpp',
     '../tests/GrSurfaceTest.cpp',
     '../tests/GrTBSearchTest.cpp',
     '../tests/GradientTest.cpp',
-    '../tests/HashCacheTest.cpp',
     '../tests/ImageCacheTest.cpp',
     '../tests/ImageDecodingTest.cpp',
     '../tests/ImageFilterTest.cpp',
+    '../tests/ImageGeneratorTest.cpp',
+    '../tests/ImageIsOpaqueTest.cpp',
+    '../tests/ImageNewShaderTest.cpp',
     '../tests/InfRectTest.cpp',
+    '../tests/InterpolatorTest.cpp',
     '../tests/JpegTest.cpp',
     '../tests/KtxTest.cpp',
     '../tests/LListTest.cpp',
@@ -116,11 +139,13 @@
     '../tests/MemsetTest.cpp',
     '../tests/MessageBusTest.cpp',
     '../tests/MetaDataTest.cpp',
+    '../tests/MiniDataTest.cpp',
     '../tests/MipMapTest.cpp',
     '../tests/NameAllocatorTest.cpp',
-    '../tests/ObjectPoolTest.cpp',
     '../tests/OSPathTest.cpp',
+    '../tests/ObjectPoolTest.cpp',
     '../tests/OnceTest.cpp',
+    '../tests/PDFJpegEmbedTest.cpp',
     '../tests/PDFPrimitivesTest.cpp',
     '../tests/PackBitsTest.cpp',
     '../tests/PaintTest.cpp',
@@ -129,24 +154,27 @@
     '../tests/PathMeasureTest.cpp',
     '../tests/PathTest.cpp',
     '../tests/PathUtilsTest.cpp',
-    '../tests/PictureTest.cpp',
     '../tests/PictureShaderTest.cpp',
     '../tests/PictureStateTreeTest.cpp',
+    '../tests/PictureTest.cpp',
     '../tests/PixelRefTest.cpp',
     '../tests/PointTest.cpp',
     '../tests/PremulAlphaRoundTripTest.cpp',
     '../tests/QuickRejectTest.cpp',
+    '../tests/RTConfRegistryTest.cpp',
     '../tests/RTreeTest.cpp',
     '../tests/RandomTest.cpp',
     '../tests/ReadPixelsTest.cpp',
     '../tests/ReadWriteAlphaTest.cpp',
     '../tests/Reader32Test.cpp',
     '../tests/RecordDrawTest.cpp',
+    '../tests/RecordReplaceDrawTest.cpp',
     '../tests/RecordOptsTest.cpp',
     '../tests/RecordPatternTest.cpp',
     '../tests/RecordTest.cpp',
     '../tests/RecorderTest.cpp',
     '../tests/RecordingTest.cpp',
+    '../tests/RecordingXfermodeTest.cpp',
     '../tests/RefCntTest.cpp',
     '../tests/RefDictTest.cpp',
     '../tests/RegionTest.cpp',
@@ -154,13 +182,14 @@
     '../tests/RoundRectTest.cpp',
     '../tests/RuntimeConfigTest.cpp',
     '../tests/SHA1Test.cpp',
+    '../tests/SListTest.cpp',
     '../tests/ScalarTest.cpp',
-    '../tests/ScaledImageCache.cpp',
     '../tests/SerializationTest.cpp',
     '../tests/ShaderImageFilterTest.cpp',
     '../tests/ShaderOpacityTest.cpp',
+    '../tests/SizeTest.cpp',
     '../tests/SkBase64Test.cpp',
-    '../tests/SListTest.cpp',
+    '../tests/SkResourceCacheTest.cpp',
     '../tests/SmallAllocatorTest.cpp',
     '../tests/SortTest.cpp',
     '../tests/SrcOverTest.cpp',
@@ -171,14 +200,13 @@
     '../tests/TArrayTest.cpp',
     '../tests/TLSTest.cpp',
     '../tests/TSetTest.cpp',
-    '../tests/TestSize.cpp',
+    '../tests/TextBlobTest.cpp',
     '../tests/TextureCompressionTest.cpp',
     '../tests/TileGridTest.cpp',
     '../tests/ToUnicodeTest.cpp',
     '../tests/TracingTest.cpp',
     '../tests/TypefaceTest.cpp',
     '../tests/UnicodeTest.cpp',
-    '../tests/UnitTestTest.cpp',
     '../tests/UtilsTest.cpp',
     '../tests/WArrayTest.cpp',
     '../tests/WritePixelsTest.cpp',
@@ -198,7 +226,5 @@
 
     '../tests/TDStackNesterTest.cpp',
     '../experimental/PdfViewer/src/SkTDStackNester.h',
-
-    '../tools/sk_tool_utils.cpp',
   ],
 }
diff --git a/gyp/tools.gyp b/gyp/tools.gyp
index 5ea1272..e689ed1 100644
--- a/gyp/tools.gyp
+++ b/gyp/tools.gyp
@@ -15,8 +15,6 @@
       'dependencies': [
         'bbh_shootout',
         'bench_pictures',
-        'bench_record',
-        'bench_playback',
         'dump_record',
         'filter',
         'gpuveto',
@@ -43,6 +41,105 @@
         ],
       ],
     },
+    {  # This would go in gm.gyp, but it's also used by skimage below.
+      'target_name': 'gm_expectations',
+      'type': 'static_library',
+      'include_dirs' : [ '../src/utils/' ],
+      'sources': [
+        '../gm/gm_expectations.cpp',
+      ],
+      'dependencies': [
+        'jsoncpp.gyp:jsoncpp',
+        'sk_tool_utils',
+        'skia_lib.gyp:skia_lib',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [ '../gm/' ],
+      },
+    },
+    {
+      'target_name': 'crash_handler',
+        'type': 'static_library',
+        'sources': [ '../tools/CrashHandler.cpp' ],
+        'dependencies': [ 'skia_lib.gyp:skia_lib' ],
+        'direct_dependent_settings': {
+          'include_dirs': [ '../tools' ],
+        },
+        'all_dependent_settings': {
+          'msvs_settings': {
+            'VCLinkerTool': {
+              'AdditionalDependencies': [ 'Dbghelp.lib' ],
+            }
+          },
+        }
+    },
+    {
+      'target_name': 'resources',
+      'type': 'static_library',
+      'sources': [ '../tools/Resources.cpp' ],
+      'dependencies': [
+        'flags.gyp:flags',
+        'skia_lib.gyp:skia_lib',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [ '../tools', ],
+      },
+    },
+    {
+      'target_name': 'sk_tool_utils',
+      'type': 'static_library',
+      'sources': [
+        '../tools/sk_tool_utils.cpp',
+        '../tools/sk_tool_utils_font.cpp',
+      ],
+      'include_dirs': [
+        '../src/fonts',
+      ],
+      'dependencies': [
+        'resources',
+        'flags.gyp:flags',
+        'skia_lib.gyp:skia_lib',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [ '../tools', ],
+      },
+    },
+    {
+      'target_name' : 'timer',
+      'type': 'static_library',
+      'sources': [
+        '../tools/timer/Timer.cpp',
+        '../tools/timer/TimerData.cpp',
+      ],
+      'include_dirs': [
+        '../src/core',
+        '../src/gpu',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': ['../tools/timer'],
+      },
+      'dependencies': [
+        'skia_lib.gyp:skia_lib',
+        'jsoncpp.gyp:jsoncpp',
+      ],
+      'conditions': [
+        ['skia_gpu == 1', {
+          'sources': [ '../tools/timer/GpuTimer.cpp' ],
+        }],
+        [ 'skia_os in ["mac", "ios"]', {
+          'sources': [ '../tools/timer/SysTimer_mach.cpp' ],
+        }],
+        [ 'skia_os == "win"', {
+          'sources': [ '../tools/timer/SysTimer_windows.cpp' ],
+        }],
+        [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris", "android", "chromeos"]', {
+          'sources': [ '../tools/timer/SysTimer_posix.cpp' ],
+        }],
+        [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris", "chromeos"]', {
+          'link_settings': { 'libraries': [ '-lrt' ] },
+        }],
+      ],
+    },
     {
       'target_name': 'skdiff',
       'type': 'executable',
@@ -68,14 +165,16 @@
         '../tools/skpdiff/SkImageDiffer.cpp',
         '../tools/skpdiff/SkPMetric.cpp',
         '../tools/skpdiff/skpdiff_util.cpp',
-        '../tools/flags/SkCommandLineFlags.cpp',
+        '../src/utils/SkTaskGroup.cpp',
       ],
       'include_dirs': [
-        '../tools/flags',
         '../src/core/', # needed for SkTLList.h
+        '../tools/',    # needed for picture_utils::replace_char
       ],
       'dependencies': [
+        'flags.gyp:flags',
         'skia_lib.gyp:skia_lib',
+        'tools.gyp:picture_utils',
       ],
       'cflags': [
         '-O3',
@@ -176,10 +275,11 @@
       'include_dirs': [
         # For SkBitmapHasher.h
         '../src/utils/',
+        '../tools/',
       ],
       'dependencies': [
+        'gm_expectations',
         'flags.gyp:flags',
-        'gm.gyp:gm_expectations',
         'jsoncpp.gyp:jsoncpp',
         'skia_lib.gyp:skia_lib',
       ],
@@ -191,7 +291,6 @@
         '../tools/skpinfo.cpp',
       ],
       'include_dirs': [
-        '../tools/flags',
         '../src/core/',
       ],
       'dependencies': [
@@ -210,7 +309,6 @@
         '../src/core/',
         '../src/images',
         '../src/lazy',
-        '../tools/flags',
       ],
       'dependencies': [
         'flags.gyp:flags',
@@ -288,7 +386,6 @@
       'sources': [
         '../bench/BenchLogger.cpp',
         '../bench/BenchLogger.h',
-        '../bench/ResultsWriter.cpp',
         '../tools/PictureBenchmark.cpp',
         '../tools/PictureResultsWriter.h',
         '../tools/bench_pictures_main.cpp',
@@ -299,48 +396,18 @@
         '../src/lazy/',
       ],
       'dependencies': [
-        'bench.gyp:bench_timer',
-        'crash_handler.gyp:CrashHandler',
+        'timer',
+        'crash_handler',
         'flags.gyp:flags',
         'jsoncpp.gyp:jsoncpp',
         'skia_lib.gyp:skia_lib',
         'tools.gyp:picture_renderer',
         'tools.gyp:picture_utils',
-        'tools.gyp:timer_data',
       ],
-    },
-    {
-      'target_name': 'bench_record',
-      'type': 'executable',
-      'sources': [
-        '../tools/bench_record.cpp',
-        '../tools/LazyDecodeBitmap.cpp',
-      ],
-      'include_dirs': [
-        '../src/core/',
-        '../src/images',
-        '../src/lazy',
-      ],
-      'dependencies': [
-        'bench.gyp:bench_timer',
-        'flags.gyp:flags',
-        'skia_lib.gyp:skia_lib',
-      ],
-    },
-    {
-      'target_name': 'bench_playback',
-      'type': 'executable',
-      'sources': [
-        '../tools/bench_playback.cpp',
-      ],
-      'include_dirs': [
-        '../src/core/',
-        '../src/images',
-      ],
-      'dependencies': [
-        'bench.gyp:bench_timer',
-        'flags.gyp:flags',
-        'skia_lib.gyp:skia_lib',
+      'conditions': [
+        ['skia_android_framework == 1', {
+          'libraries': [ '-lskia' ],
+        }],
       ],
     },
     {
@@ -357,7 +424,7 @@
         '../src/lazy',
       ],
       'dependencies': [
-        'bench.gyp:bench_timer',
+        'timer',
         'flags.gyp:flags',
         'skia_lib.gyp:skia_lib',
       ],
@@ -416,17 +483,18 @@
       'type': 'executable',
       'sources': [
         '../tools/render_pdfs_main.cpp',
-        '../tools/PdfRenderer.cpp',
-        '../tools/PdfRenderer.h',
       ],
       'include_dirs': [
+        '../src/core',
         '../src/pipe/utils/',
         '../src/utils/',
       ],
       'dependencies': [
+        'flags.gyp:flags',
         'pdf.gyp:pdf',
         'skia_lib.gyp:skia_lib',
         'tools.gyp:picture_utils',
+        'tools.gyp:proc_stats',
       ],
       'conditions': [
         ['skia_win_debuggers_path and skia_os == "win"',
@@ -505,9 +573,8 @@
         # Bench code:
       ],
       'dependencies': [
-        'bench.gyp:bench_timer',
+        'timer',
         'flags.gyp:flags',
-        'tools.gyp:timer_data',
         'skia_lib.gyp:skia_lib',
         'tools.gyp:picture_renderer',
         'tools.gyp:picture_utils',
@@ -545,16 +612,16 @@
       ],
     },
     {
-      'target_name': 'timer_data',
+      'target_name': 'proc_stats',
       'type': 'static_library',
       'sources': [
-        '../bench/TimerData.cpp',
+        '../tools/ProcStats.h',
+        '../tools/ProcStats.cpp',
       ],
-      'dependencies': [
-        'skia_lib.gyp:skia_lib',
-        'jsoncpp.gyp:jsoncpp'
-      ]
-    }
+      'direct_dependent_settings': {
+        'include_dirs': [ '../tools', ],
+      },
+    },
   ],
   'conditions': [
     ['skia_shared_lib',
@@ -624,5 +691,26 @@
         ],
       },
     ],
+    ['skia_os == "mac"',
+      {
+        'targets': [
+          {
+            'target_name': 'create_test_font',
+            'type': 'executable',
+            'sources': [
+              '../tools/create_test_font.cpp',
+            ],
+            'include_dirs': [
+              '../src/core',
+            ],
+            'dependencies': [
+              'flags.gyp:flags',
+              'skia_lib.gyp:skia_lib',
+              'resources',
+            ],
+          },
+        ],
+      },
+    ],
   ],
 }
diff --git a/gyp/utils.gyp b/gyp/utils.gyp
index 066c901..e12c87a 100644
--- a/gyp/utils.gyp
+++ b/gyp/utils.gyp
@@ -8,6 +8,7 @@
       'standalone_static_library': 1,
       'dependencies': [
         'core.gyp:*',
+        'etc1.gyp:libetc1',
       ],
       'includes': [
         'utils.gypi',
@@ -23,6 +24,7 @@
         '../include/utils/win',
         '../include/xml',
         '../src/core',
+        '../src/opts',
         '../src/utils',
       ],
       'sources': [
diff --git a/gyp/utils.gypi b/gyp/utils.gypi
index 761fbf7..e62d287 100644
--- a/gyp/utils.gypi
+++ b/gyp/utils.gypi
@@ -8,12 +8,9 @@
 {
     'sources': [
         # Classes for a threadpool.
-        '<(skia_include_path)/utils/SkCondVar.h',
-        '<(skia_include_path)/utils/SkCountdown.h',
-        '<(skia_include_path)/utils/SkRunnable.h',
-        '<(skia_include_path)/utils/SkThreadPool.h',
+        '<(skia_src_path)/utils/SkCondVar.h',
+        '<(skia_src_path)/utils/SkRunnable.h',
         '<(skia_src_path)/utils/SkCondVar.cpp',
-        '<(skia_src_path)/utils/SkCountdown.cpp',
 
         '<(skia_include_path)/utils/SkBoundaryPatch.h',
         '<(skia_include_path)/utils/SkFrontBufferedStream.h',
@@ -80,6 +77,10 @@
         '<(skia_src_path)/utils/SkParseColor.cpp',
         '<(skia_src_path)/utils/SkParsePath.cpp',
         '<(skia_src_path)/utils/SkPictureUtils.cpp',
+        '<(skia_src_path)/utils/SkPatchGrid.cpp',
+        '<(skia_src_path)/utils/SkPatchGrid.h',
+        '<(skia_src_path)/utils/SkPatchUtils.cpp',
+        '<(skia_src_path)/utils/SkPatchUtils.h',
         '<(skia_src_path)/utils/SkPathUtils.cpp',
         '<(skia_src_path)/utils/SkProxyCanvas.cpp',
         '<(skia_src_path)/utils/SkSHA1.cpp',
@@ -87,6 +88,13 @@
         '<(skia_src_path)/utils/SkRTConf.cpp',
         '<(skia_src_path)/utils/SkTextureCompressor.cpp',
         '<(skia_src_path)/utils/SkTextureCompressor.h',
+        '<(skia_src_path)/utils/SkTextureCompressor_ASTC.cpp',
+        '<(skia_src_path)/utils/SkTextureCompressor_ASTC.h',
+        '<(skia_src_path)/utils/SkTextureCompressor_Blitter.h',
+        '<(skia_src_path)/utils/SkTextureCompressor_R11EAC.cpp',
+        '<(skia_src_path)/utils/SkTextureCompressor_R11EAC.h',
+        '<(skia_src_path)/utils/SkTextureCompressor_LATC.cpp',
+        '<(skia_src_path)/utils/SkTextureCompressor_LATC.h',
         '<(skia_src_path)/utils/SkThreadUtils.h',
         '<(skia_src_path)/utils/SkThreadUtils_pthread.cpp',
         '<(skia_src_path)/utils/SkThreadUtils_pthread.h',
@@ -121,5 +129,7 @@
         #testing
         '<(skia_src_path)/fonts/SkGScalerContext.cpp',
         '<(skia_src_path)/fonts/SkGScalerContext.h',
+        '<(skia_src_path)/fonts/SkTestScalerContext.cpp',
+        '<(skia_src_path)/fonts/SkTestScalerContext.h',
     ],
 }
diff --git a/gyp/v8.gyp b/gyp/v8.gyp
index b2eb54c..0316d34 100644
--- a/gyp/v8.gyp
+++ b/gyp/v8.gyp
@@ -6,88 +6,83 @@
       'type': 'executable',
       'mac_bundle' : 1,
       'include_dirs' : [
-        '../tools/flags',
         '../third_party/externals/v8/include',
+      ],
+      'sources': [
+        '../experimental/SkV8Example/BaseContext.cpp',
+        '../experimental/SkV8Example/BaseContext.h',
+        '../experimental/SkV8Example/Global.cpp',
+        '../experimental/SkV8Example/Global.h',
+        '../experimental/SkV8Example/JsContext.cpp',
+        '../experimental/SkV8Example/JsContext.h',
+        '../experimental/SkV8Example/Path2D.cpp',
+        '../experimental/SkV8Example/Path2D.h',
+        '../experimental/SkV8Example/SkV8Example.cpp',
+        '../experimental/SkV8Example/SkV8Example.h',
+      ],
+      'dependencies': [
+        'flags.gyp:flags',
+        'skia_lib.gyp:skia_lib',
+        'views.gyp:views',
+        'xml.gyp:xml',
+      ],
+      'link_settings': {
+        'libraries': [
+
+#         'd:/src/v8/build/Debug/lib/v8_base.ia32.lib',
+#         'd:/src/v8/build/Debug/lib/v8_snapshot.lib',
+#         'd:/src/v8/build/Debug/lib/icuuc.lib',
+#         'd:/src/v8/build/Debug/lib/icui18n.lib',
+#         'Ws2_32.lib',
+#         'Winmm.lib',
+
+          '-lpthread',
+          '-lrt',
+          '../../third_party/externals/v8/out/native/obj.target/tools/gyp/libv8_base.x64.a',
+          '../../third_party/externals/v8/out/native/obj.target/tools/gyp/libv8_snapshot.a',
+          '../../third_party/externals/v8/out/native/obj.target/third_party/icu/libicudata.a',
+          '../../third_party/externals/v8/out/native/obj.target/third_party/icu/libicui18n.a',
+          '../../third_party/externals/v8/out/native/obj.target/third_party/icu/libicuuc.a',
+          '../../third_party/externals/v8/out/native/obj.target/icudata/third_party/icu/linux/icudt46l_dat.o',
         ],
-       'sources': [
-         '../experimental/SkV8Example/SkV8Example.cpp',
-         '../experimental/SkV8Example/SkV8Example.h',
-         '../experimental/SkV8Example/Global.cpp',
-         '../experimental/SkV8Example/Global.h',
-         '../experimental/SkV8Example/Path2D.cpp',
-         '../experimental/SkV8Example/Path2D.h',
-         '../experimental/SkV8Example/BaseContext.cpp',
-         '../experimental/SkV8Example/BaseContext.h',
-         '../experimental/SkV8Example/JsContext.cpp',
-         '../experimental/SkV8Example/JsContext.h',
-       ],
-       'dependencies': [
-         'flags.gyp:flags',
-         'skia_lib.gyp:skia_lib',
-         'views.gyp:views',
-         'xml.gyp:xml',
-       ],
-       'link_settings': {
-         'libraries': [
-
-#        'd:/src/v8/build/Debug/lib/v8_base.ia32.lib',
-#        'd:/src/v8/build/Debug/lib/v8_snapshot.lib',
-#        'd:/src/v8/build/Debug/lib/icuuc.lib',
-#        'd:/src/v8/build/Debug/lib/icui18n.lib',
-#        'Ws2_32.lib',
-#        'Winmm.lib',
-
-           '-lpthread',
-           '-lrt',
-           '../../third_party/externals/v8/out/native/obj.target/tools/gyp/libv8_base.x64.a',
-           '../../third_party/externals/v8/out/native/obj.target/tools/gyp/libv8_snapshot.a',
-           '../../third_party/externals/v8/out/native/obj.target/third_party/icu/libicudata.a',
-           '../../third_party/externals/v8/out/native/obj.target/third_party/icu/libicui18n.a',
-           '../../third_party/externals/v8/out/native/obj.target/third_party/icu/libicuuc.a',
-           '../../third_party/externals/v8/out/native/obj.target/icudata/third_party/icu/linux/icudt46l_dat.o',
-           ],
-       },
-       'conditions' : [
-         [ 'skia_gpu == 1', {
-           'include_dirs' : [
-             '../src/gpu',  #gl/GrGLUtil.h
-             ]
-         }],
+      },
+      'conditions' : [
+        [ 'skia_gpu == 1', {
+          'include_dirs' : [
+            '../src/gpu',
+          ]
+        }],
         [ 'skia_os == "win"', {
-         'sources' : [
-           '../src/views/win/SkOSWindow_Win.cpp',
-           '../src/views/win/skia_win.cpp',
-           ],
-          },
-        ],
-
+          'sources' : [
+            '../src/views/win/SkOSWindow_Win.cpp',
+            '../src/views/win/skia_win.cpp',
+          ],
+        }],
         [ 'skia_os == "mac"', {
           'sources': [
-
-          '../src/views/mac/SampleAppDelegate.h',
-          '../src/views/mac/SampleAppDelegate.mm',
-          '../src/views/mac/SkEventNotifier.mm',
-          '../src/views/mac/skia_mac.mm',
-          '../src/views/mac/SkNSView.h',
-          '../src/views/mac/SkNSView.mm',
-          '../src/views/mac/SkOptionsTableView.h',
-          '../src/views/mac/SkOptionsTableView.mm',
-          '../src/views/mac/SkOSWindow_Mac.mm',
-          '../src/views/mac/SkTextFieldCell.h',
-          '../src/views/mac/SkTextFieldCell.m',
+            '../src/views/mac/SampleAppDelegate.h',
+            '../src/views/mac/SampleAppDelegate.mm',
+            '../src/views/mac/SkEventNotifier.mm',
+            '../src/views/mac/skia_mac.mm',
+            '../src/views/mac/SkNSView.h',
+            '../src/views/mac/SkNSView.mm',
+            '../src/views/mac/SkOptionsTableView.h',
+            '../src/views/mac/SkOptionsTableView.mm',
+            '../src/views/mac/SkOSWindow_Mac.mm',
+            '../src/views/mac/SkTextFieldCell.h',
+            '../src/views/mac/SkTextFieldCell.m',
           ],
-        'include_dirs' : [
-          '../src/views/mac/'
+          'include_dirs' : [
+            '../src/views/mac/'
           ],
-        'xcode_settings' : {
-          'INFOPLIST_FILE' : '../experimental/SkiaExamples/SkiaExamples-Info.plist',
-        },
-        'mac_bundle_resources' : [
-          '../experimental/SkiaExamples/SkiaExamples.xib'
+          'xcode_settings' : {
+            'INFOPLIST_FILE' : '../experimental/SkiaExamples/SkiaExamples-Info.plist',
+          },
+          'mac_bundle_resources' : [
+            '../experimental/SkiaExamples/SkiaExamples.xib'
           ],
-        }
+        }],
       ],
-     ],
     }
   ],
 }
diff --git a/include/core/SkBBHFactory.h b/include/core/SkBBHFactory.h
index 4c03844..67c9cd7 100644
--- a/include/core/SkBBHFactory.h
+++ b/include/core/SkBBHFactory.h
@@ -22,14 +22,6 @@
     virtual ~SkBBHFactory() {};
 };
 
-class SK_API SkQuadTreeFactory : public SkBBHFactory {
-public:
-    virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
-private:
-    typedef SkBBHFactory INHERITED;
-};
-
-
 class SK_API SkRTreeFactory : public SkBBHFactory {
 public:
     virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index 13e9aa3..b36a1fd 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -14,6 +14,16 @@
 #include "SkPoint.h"
 #include "SkRefCnt.h"
 
+#ifdef SK_SUPPORT_LEGACY_ALLOCPIXELS_BOOL
+    #define SK_ALLOCPIXELS_RETURN_TYPE  bool
+    #define SK_ALLOCPIXELS_RETURN_TRUE  return true
+    #define SK_ALLOCPIXELS_RETURN_FAIL  return false
+#else
+    #define SK_ALLOCPIXELS_RETURN_TYPE  void
+    #define SK_ALLOCPIXELS_RETURN_TRUE  return
+    #define SK_ALLOCPIXELS_RETURN_FAIL  sk_throw()
+#endif
+
 struct SkMask;
 struct SkIRect;
 struct SkRect;
@@ -38,29 +48,6 @@
 public:
     class SK_API Allocator;
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-    enum Config {
-        kNo_Config,         //!< bitmap has not been configured
-        kA8_Config,         //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
-        kIndex8_Config,     //!< 8-bits per pixel, using SkColorTable to specify the colors
-        kRGB_565_Config,    //!< 16-bits per pixel, (see SkColorPriv.h for packing)
-        kARGB_4444_Config,  //!< 16-bits per pixel, (see SkColorPriv.h for packing)
-        kARGB_8888_Config,  //!< 32-bits per pixel, (see SkColorPriv.h for packing)
-    };
-
-    // do not add this to the Config enum, otherwise the compiler will let us
-    // pass this as a valid parameter for Config.
-    enum {
-        kConfigCount = kARGB_8888_Config + 1
-    };
-
-    /** Return the config for the bitmap. */
-    Config  config() const;
-    
-    SK_ATTR_DEPRECATED("use config()")
-    Config  getConfig() const { return this->config(); }
-#endif
-
     /**
      *  Default construct creates a bitmap with zero width and height, and no pixels.
      *  Its colortype is set to kUnknown_SkColorType.
@@ -91,23 +78,10 @@
 
     const SkImageInfo& info() const { return fInfo; }
 
-    int width() const { return fInfo.fWidth; }
-    int height() const { return fInfo.fHeight; }
-    SkColorType colorType() const { return fInfo.fColorType; }
-    SkAlphaType alphaType() const { return fInfo.fAlphaType; }
-
-#ifdef SK_SUPPORT_LEGACY_ASIMAGEINFO
-    bool asImageInfo(SkImageInfo* info) const {
-        // compatibility: return false for kUnknown
-        if (kUnknown_SkColorType == this->colorType()) {
-            return false;
-        }
-        if (info) {
-            *info = this->info();
-        }
-        return true;
-    }
-#endif
+    int width() const { return fInfo.width(); }
+    int height() const { return fInfo.height(); }
+    SkColorType colorType() const { return fInfo.colorType(); }
+    SkAlphaType alphaType() const { return fInfo.alphaType(); }
 
     /**
      *  Return the number of bytes per pixel based on the colortype. If the colortype is
@@ -168,7 +142,7 @@
         Note this truncates the result to 32bits. Call getSize64() to detect
         if the real size exceeds 32bits.
     */
-    size_t getSize() const { return fInfo.fHeight * fRowBytes; }
+    size_t getSize() const { return fInfo.height() * fRowBytes; }
 
     /** Return the number of bytes from the pointer returned by getPixels()
         to the end of the allocated space in the buffer. Required in
@@ -180,7 +154,7 @@
      *  Return the full size of the bitmap, in bytes.
      */
     int64_t computeSize64() const {
-        return sk_64_mul(fInfo.fHeight, fRowBytes);
+        return sk_64_mul(fInfo.height(), fRowBytes);
     }
 
     /**
@@ -229,28 +203,6 @@
     */
     void reset();
 
-#ifdef SK_SUPPORT_LEGACY_COMPUTE_CONFIG_SIZE
-    /** Given a config and a width, this computes the optimal rowBytes value. This is called automatically
-        if you pass 0 for rowBytes to setConfig().
-    */
-    static size_t ComputeRowBytes(Config c, int width);
-
-    /** Return the bytes-per-pixel for the specified config. If the config is
-        not at least 1-byte per pixel, return 0, including for kNo_Config.
-    */
-    static int ComputeBytesPerPixel(Config c);
-
-    /** Return the shift-per-pixel for the specified config. If the config is
-     not at least 1-byte per pixel, return 0, including for kNo_Config.
-     */
-    static int ComputeShiftPerPixel(Config c) {
-        return ComputeBytesPerPixel(c) >> 1;
-    }
-
-    static int64_t ComputeSize64(Config, int width, int height);
-    static size_t ComputeSize(Config, int width, int height);
-#endif
-
     /**
      *  This will brute-force return true if all of the pixels in the bitmap
      *  are opaque. If it fails to read the pixels, or encounters an error,
@@ -268,53 +220,61 @@
     void getBounds(SkRect* bounds) const;
     void getBounds(SkIRect* bounds) const;
 
-#ifdef SK_SUPPORT_LEGACY_SETCONFIG
-    /** Set the bitmap's config and dimensions. If rowBytes is 0, then
-        ComputeRowBytes() is called to compute the optimal value. This resets
-        any pixel/colortable ownership, just like reset().
-    */
-    bool setConfig(Config, int width, int height, size_t rowBytes, SkAlphaType);
-
-    bool setConfig(Config config, int width, int height, size_t rowBytes = 0) {
-        return this->setConfig(config, width, height, rowBytes,
-                               kPremul_SkAlphaType);
-    }
-#endif
-
     bool setInfo(const SkImageInfo&, size_t rowBytes = 0);
 
-#ifdef SK_SUPPORT_LEGACY_SETCONFIG_INFO
-    bool setConfig(const SkImageInfo& info, size_t rowBytes = 0) {
-        return this->setInfo(info, rowBytes);
-    }
-#endif
-
     /**
-     *  Allocate a pixelref to match the specified image info. If the Factory
+     *  Allocate the bitmap's pixels to match the requested image info. If the Factory
      *  is non-null, call it to allcoate the pixelref. If the ImageInfo requires
      *  a colortable, then ColorTable must be non-null, and will be ref'd.
      *  On failure, the bitmap will be set to empty and return false.
      */
-    bool allocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
+    bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
+
+    SK_ALLOCPIXELS_RETURN_TYPE allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory,
+                                           SkColorTable* ctable) {
+        if (!this->tryAllocPixels(info, factory, ctable)) {
+            SK_ALLOCPIXELS_RETURN_FAIL;
+        }
+        SK_ALLOCPIXELS_RETURN_TRUE;
+    }
 
     /**
-     *  Allocate a pixelref to match the specified image info, using the default
-     *  allocator.
-     *  On success, the bitmap's pixels will be "locked", and return true.
-     *  On failure, the bitmap will be set to empty and return false.
+     *  Allocate the bitmap's pixels to match the requested image info and
+     *  rowBytes. If the request cannot be met (e.g. the info is invalid or
+     *  the requested rowBytes are not compatible with the info
+     *  (e.g. rowBytes < info.minRowBytes() or rowBytes is not aligned with
+     *  the pixel size specified by info.colorType()) then false is returned
+     *  and the bitmap is set to empty.
      */
-    bool allocPixels(const SkImageInfo& info) {
-        return this->allocPixels(info, NULL, NULL);
+    bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes);
+
+    SK_ALLOCPIXELS_RETURN_TYPE allocPixels(const SkImageInfo& info, size_t rowBytes) {
+        if (!this->tryAllocPixels(info, rowBytes)) {
+            SK_ALLOCPIXELS_RETURN_FAIL;
+        }
+        SK_ALLOCPIXELS_RETURN_TRUE;
     }
 
-    bool allocN32Pixels(int width, int height, bool isOpaque = false) {
-        SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
-        if (isOpaque) {
-            info.fAlphaType = kOpaque_SkAlphaType;
-        }
+    bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) {
+        return this->tryAllocPixels(info, info.minRowBytes());
+    }
+
+    SK_ALLOCPIXELS_RETURN_TYPE allocPixels(const SkImageInfo& info) {
+        return this->allocPixels(info, info.minRowBytes());
+    }
+
+    bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false) {
+        SkImageInfo info = SkImageInfo::MakeN32(width, height,
+                                            isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
+        return this->tryAllocPixels(info);
+    }
+    
+    SK_ALLOCPIXELS_RETURN_TYPE allocN32Pixels(int width, int height, bool isOpaque = false) {
+        SkImageInfo info = SkImageInfo::MakeN32(width, height,
+                                            isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
         return this->allocPixels(info);
     }
-
+    
     /**
      *  Install a pixelref that wraps the specified pixels and rowBytes, and
      *  optional ReleaseProc and context. When the pixels are no longer
@@ -325,14 +285,6 @@
     bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkColorTable*,
                        void (*releaseProc)(void* addr, void* context), void* context);
 
-#ifdef SK_SUPPORT_LEGACY_INSTALLPIXELSPARAMS
-    bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
-                       void (*releaseProc)(void* addr, void* context),
-                       void* context) {
-        return this->installPixels(info, pixels, rowBytes, NULL, releaseProc, context);
-    }
-#endif
-
     /**
      *  Call installPixels with no ReleaseProc specified. This means that the
      *  caller must ensure that the specified pixels are valid for the lifetime
@@ -395,7 +347,11 @@
         @return true if the allocation succeeds. If not the pixelref field of
                      the bitmap will be unchanged.
     */
-    bool allocPixels(SkColorTable* ctable = NULL) {
+    bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable* ctable = NULL) {
+        return this->tryAllocPixels(NULL, ctable);
+    }
+
+    SK_ALLOCPIXELS_RETURN_TYPE allocPixels(SkColorTable* ctable = NULL) {
         return this->allocPixels(NULL, ctable);
     }
 
@@ -417,7 +373,14 @@
         @return true if the allocation succeeds. If not the pixelref field of
                      the bitmap will be unchanged.
     */
-    bool allocPixels(Allocator* allocator, SkColorTable* ctable);
+    bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator, SkColorTable* ctable);
+
+    SK_ALLOCPIXELS_RETURN_TYPE allocPixels(Allocator* allocator, SkColorTable* ctable) {
+        if (!this->tryAllocPixels(allocator, ctable)) {
+            SK_ALLOCPIXELS_RETURN_FAIL;
+        }
+        SK_ALLOCPIXELS_RETURN_TRUE;
+    }
 
     /**
      *  Return the current pixelref object or NULL if there is none. This does
@@ -481,7 +444,7 @@
     */
     bool readyToDraw() const {
         return this->getPixels() != NULL &&
-               (this->colorType() != kIndex_8_SkColorType || NULL != fColorTable);
+               (this->colorType() != kIndex_8_SkColorType || fColorTable);
     }
 
     /** Returns the pixelRef's texture, or NULL
@@ -777,9 +740,7 @@
     SkIPoint    fPixelRefOrigin;
 
     enum Flags {
-        kImageIsOpaque_Flag     = 0x01,
         kImageIsVolatile_Flag   = 0x02,
-        kImageIsImmutable_Flag  = 0x04,
 #ifdef SK_BUILD_FOR_ANDROID
         /* A hint for the renderer responsible for drawing this bitmap
          * indicating that it should attempt to use mipmaps when this bitmap
@@ -919,13 +880,4 @@
     return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
 }
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-///////////////////////////////////////////////////////////////////////////////
-//
-// Helpers until we can fully deprecate SkBitmap::Config
-//
-extern SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType);
-extern SkColorType SkBitmapConfigToColorType(SkBitmap::Config);
-#endif
-
 #endif
diff --git a/include/core/SkBitmapDevice.h b/include/core/SkBitmapDevice.h
index cc6d2ad..0ab0234 100644
--- a/include/core/SkBitmapDevice.h
+++ b/include/core/SkBitmapDevice.h
@@ -22,33 +22,22 @@
      *  any drawing to this device will have no effect.
     */
     SkBitmapDevice(const SkBitmap& bitmap);
-
+private:
     /**
      *  Construct a new device with the specified bitmap as its backend. It is
      *  valid for the bitmap to have no pixels associated with it. In that case,
      *  any drawing to this device will have no effect.
     */
     SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties);
-
-    static SkBitmapDevice* Create(const SkImageInfo&,
-                                  const SkDeviceProperties* = NULL);
+    static SkBitmapDevice* Create(const SkImageInfo&, const SkDeviceProperties*);
+public:
+    static SkBitmapDevice* Create(const SkImageInfo& info) {
+        return Create(info, NULL);
+    }
 
     virtual SkImageInfo imageInfo() const SK_OVERRIDE;
 
-    /**
-     * Return the device's associated gpu render target, or NULL.
-     */
-    virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
-
 protected:
-    /**
-     *  Device may filter the text flags for drawing text here. If it wants to
-     *  make a change to the specified values, it should write them into the
-     *  textflags parameter (output) and return true. If the paint is fine as
-     *  is, then ignore the textflags parameter and return false.
-     *
-     *  The baseclass SkDevice filters based on its depth and blitters.
-     */
     virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE;
 
     /** Clears the entire device to the specified color (including alpha).
@@ -149,33 +138,6 @@
     virtual void lockPixels() SK_OVERRIDE;
     virtual void unlockPixels() SK_OVERRIDE;
 
-    /**
-     *  Returns true if the device allows processing of this imagefilter. If
-     *  false is returned, then the filter is ignored. This may happen for
-     *  some subclasses that do not support pixel manipulations after drawing
-     *  has occurred (e.g. printing). The default implementation returns true.
-     */
-    virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE;
-
-    /**
-     *  Override and return true for filters that the device can handle
-     *  intrinsically. Doing so means that SkCanvas will pass-through this
-     *  filter to drawSprite and drawDevice (and potentially filterImage).
-     *  Returning false means the SkCanvas will have apply the filter itself,
-     *  and just pass the resulting image to the device.
-     */
-    virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE;
-
-    /**
-     *  Related (but not required) to canHandleImageFilter, this method returns
-     *  true if the device could apply the filter to the src bitmap and return
-     *  the result (and updates offset as needed).
-     *  If the device does not recognize or support this filter,
-     *  it just returns false and leaves result and offset unchanged.
-     */
-    virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&,
-                             SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
-
 private:
     friend class SkCanvas;
     friend struct DeviceCM; //for setMatrixClip
@@ -193,13 +155,11 @@
 
     virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
 
-    /** Causes any deferred drawing to the device to be completed.
-     */
-    virtual void flush() SK_OVERRIDE {}
-
-    virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
+    virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
     virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes) SK_OVERRIDE;
 
+    virtual SkImageFilter::Cache* getImageFilterCache() SK_OVERRIDE;
+
     SkBitmap    fBitmap;
 
     typedef SkBaseDevice INHERITED;
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 31429f9..5828466 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -16,6 +16,7 @@
 #include "SkRefCnt.h"
 #include "SkPath.h"
 #include "SkRegion.h"
+#include "SkSurfaceProps.h"
 #include "SkXfermode.h"
 
 #ifdef SK_SUPPORT_LEGACY_DRAWTEXT_VIRTUAL
@@ -28,14 +29,22 @@
 class SkBaseDevice;
 class SkDraw;
 class SkDrawFilter;
+class SkImage;
 class SkMetaData;
 class SkPicture;
 class SkRRect;
 class SkSurface;
 class SkSurface_Base;
+class SkTextBlob;
 class GrContext;
 class GrRenderTarget;
 
+class SkCanvasState;
+
+namespace SkCanvasStateUtils {
+    SK_API SkCanvasState* CaptureCanvasState(SkCanvas*);
+}
+
 /** \class SkCanvas
 
     A Canvas encapsulates all of the state about drawing into a device (bitmap).
@@ -164,7 +173,11 @@
      *  the bitmap of the pixels that the canvas draws into. The reference count
      *  of the returned device is not changed by this call.
      */
+#ifndef SK_SUPPORT_LEGACY_GETDEVICE
+protected:  // Can we make this private?
+#endif
     SkBaseDevice* getDevice() const;
+public:
 
     /**
      *  saveLayer() can create another device (which is later drawn onto
@@ -189,8 +202,12 @@
      *  Create a new surface matching the specified info, one that attempts to
      *  be maximally compatible when used with this canvas. If there is no matching Surface type,
      *  NULL is returned.
+     *
+     *  If surfaceprops is specified, those are passed to the new surface, otherwise the new surface
+     *  inherits the properties of the surface that owns this canvas. If this canvas has no parent
+     *  surface, then the new surface is created with default properties.
      */
-    SkSurface* newSurface(const SkImageInfo&);
+    SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL);
 
     /**
      * Return the GPU context of the device that is associated with the canvas.
@@ -294,8 +311,10 @@
 
     enum SaveFlags {
         /** save the matrix state, restoring it on restore() */
+        // [deprecated] kMatrix_SaveFlag            = 0x01,
         kMatrix_SaveFlag            = 0x01,
         /** save the clip state, restoring it on restore() */
+        // [deprecated] kClip_SaveFlag              = 0x02,
         kClip_SaveFlag              = 0x02,
         /** the layer needs to support per-pixel alpha */
         kHasAlphaLayer_SaveFlag     = 0x04,
@@ -309,6 +328,7 @@
         kClipToLayer_SaveFlag       = 0x10,
 
         // helper masks for common choices
+        // [deprecated] kMatrixClip_SaveFlag        = 0x03,
         kMatrixClip_SaveFlag        = 0x03,
 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
         kARGB_NoClipLayer_SaveFlag  = 0x0F,
@@ -327,22 +347,6 @@
     */
     int save();
 
-    /** DEPRECATED - use save() instead.
-
-        This behaves the same as save(), but it allows fine-grained control of
-        which state bits to be saved (and subsequently restored).
-
-        @param flags The flags govern what portion of the Matrix/Clip/drawFilter
-                     state the save (and matching restore) effect. For example,
-                     if only kMatrix is specified, then only the matrix state
-                     will be pushed and popped. Likewise for the clip if kClip
-                     is specified.  However, the drawFilter is always affected
-                     by calls to save/restore.
-        @return The value to pass to restoreToCount() to balance this save()
-    */
-    SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
-    int save(SaveFlags flags);
-
     /** This behaves the same as save(), but in addition it allocates an
         offscreen bitmap. All drawing calls are directed there, and only when
         the balancing call to restore() is made is that offscreen transfered to
@@ -808,6 +812,13 @@
     */
     virtual void drawPath(const SkPath& path, const SkPaint& paint);
 
+    virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top,
+                           const SkPaint* paint = NULL);
+
+    virtual void drawImageRect(const SkImage* image, const SkRect* src,
+                               const SkRect& dst,
+                               const SkPaint* paint = NULL);
+
     /** Draw the specified bitmap, with its top/left corner at (x,y), using the
         specified paint, transformed by the current matrix. Note: if the paint
         contains a maskfilter that generates a mask which extends beyond the
@@ -965,6 +976,14 @@
                                 const SkPath& path, const SkMatrix* matrix,
                                 const SkPaint& paint);
 
+    /** Draw the text blob, offset by (x,y), using the specified paint.
+        @param blob     The text blob to be drawn
+        @param x        The x-offset of the text being drawn
+        @param y        The y-offset of the text being drawn
+        @param paint    The paint used for the text (e.g. color, size, style)
+    */
+    void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
+
     /** PRIVATE / EXPERIMENTAL -- do not call
         Perform back-end analysis/optimization of a picture. This may attach
         optimization data to the picture which can be used by a later
@@ -973,12 +992,6 @@
     */
     void EXPERIMENTAL_optimize(const SkPicture* picture);
 
-    /** PRIVATE / EXPERIMENTAL -- do not call
-        Purge all the discardable optimization information associated with
-        'picture'. If NULL is passed in, purge all discardable information.
-    */
-    void EXPERIMENTAL_purge(const SkPicture* picture);
-
     /** Draw the picture into this canvas. This method effective brackets the
         playback of the picture's draw calls with save/restore, so the state
         of this canvas will be unchanged after this call.
@@ -987,6 +1000,20 @@
     */
     void drawPicture(const SkPicture* picture);
 
+    /**
+     *  Draw the picture into this canvas.
+     *
+     *  If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is
+     *  logically equivalent to
+     *      save/concat/drawPicture/restore
+     *
+     *  If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's
+     *  alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas.
+     *  This is logically equivalent to
+     *      saveLayer(paint)/drawPicture/restore
+     */
+    void drawPicture(const SkPicture*, const SkMatrix* matrix, const SkPaint* paint);
+
     enum VertexMode {
         kTriangles_VertexMode,
         kTriangleStrip_VertexMode,
@@ -1022,6 +1049,22 @@
                               const uint16_t indices[], int indexCount,
                               const SkPaint& paint);
 
+    /**
+     Draw a cubic coons patch
+
+     @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order
+                    starting at the top left corner.
+     @param colors specifies the colors for the corners which will be bilerp across the patch,
+                    their order is clockwise starting at the top left corner.
+     @param texCoords specifies the texture coordinates that will be bilerp across the patch,
+                    their order is the same as the colors.
+     @param xmode specifies how are the colors and the textures combined if both of them are
+                    present.
+     @param paint Specifies the shader/texture if present.
+     */
+    void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                   const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
+
     /** Send a blob of data to the canvas.
         For canvases that draw, this call is effectively a no-op, as the data
         is not parsed, but just ignored. However, this call exists for
@@ -1100,27 +1143,6 @@
     */
     const SkMatrix& getTotalMatrix() const;
 
-#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE
-    enum ClipType {
-        kEmpty_ClipType = 0,
-        kRect_ClipType,
-        kComplex_ClipType
-    };
-    /** Returns a description of the total clip; may be cheaper than
-        getting the clip and querying it directly.
-    */
-    virtual ClipType getClipType() const;
-#endif
-
-#ifdef SK_SUPPORT_LEGACY_GETTOTALCLIP
-    /** DEPRECATED -- need to move this guy to private/friend
-     *  Return the current device clip (concatenation of all clip calls).
-     *  This does not account for the translate in any of the devices.
-     *  @return the current device clip (concatenation of all clip calls).
-     */
-    const SkRegion& getTotalClip() const;
-#endif
-
     /** Return the clip stack. The clip stack stores all the individual
      *  clips organized by the save/restore frame in which they were
      *  added.
@@ -1179,15 +1201,11 @@
     };
 
     // don't call
-    const SkRegion& internal_private_getTotalClip() const;
-    // don't call
-    void internal_private_getTotalClipAsPath(SkPath*) const;
-    // don't call
     GrRenderTarget* internal_private_accessTopLayerRenderTarget();
 
 protected:
     // default impl defers to getDevice()->newSurface(info)
-    virtual SkSurface* onNewSurface(const SkImageInfo&);
+    virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&);
 
     // default impl defers to its device
     virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes);
@@ -1201,14 +1219,12 @@
         kNoLayer_SaveLayerStrategy
     };
 
-    // Transitional, pending external clients cleanup.
-    virtual void willSave(SaveFlags) { this->willSave(); }
-
     virtual void willSave() {}
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) {
         return kFullLayer_SaveLayerStrategy;
     }
     virtual void willRestore() {}
+    virtual void didRestore() {}
     virtual void didConcat(const SkMatrix&) {}
     virtual void didSetMatrix(const SkMatrix&) {}
 
@@ -1228,6 +1244,12 @@
                                   const SkPath& path, const SkMatrix* matrix,
                                   const SkPaint& paint);
 
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint);
+
+    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                           const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
+
     enum ClipEdgeStyle {
         kHard_ClipEdgeStyle,
         kSoft_ClipEdgeStyle
@@ -1240,7 +1262,7 @@
 
     virtual void onDiscard();
 
-    virtual void onDrawPicture(const SkPicture* picture);
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
 
     // Returns the canvas to be used by DrawIter. Default implementation
     // returns this. Subclasses that encapsulate an indirect canvas may
@@ -1256,11 +1278,6 @@
                         SkIRect* intersection,
                         const SkImageFilter* imageFilter = NULL);
 
-    // Called by child classes that override clipPath and clipRRect to only
-    // track fast conservative clip bounds, rather than exact clips.
-    void updateClipConservativelyUsingBounds(const SkRect&, SkRegion::Op,
-                                             bool inverseFilled);
-
     // notify our surface (if we have one) that we are about to draw, so it
     // can perform copy-on-write or invalidate any cached images
     void predrawNotify();
@@ -1278,6 +1295,8 @@
     // the first N recs that can fit here mean we won't call malloc
     uint32_t    fMCRecStorage[32];
 
+    const SkSurfaceProps fProps;
+
     int         fSaveLayerCount;    // number of successful saveLayer calls
     int         fCullCount;         // number of active culls
 
@@ -1299,10 +1318,29 @@
     friend class SkLua;             // needs top layer size and offset
     friend class SkDebugCanvas;     // needs experimental fAllowSimplifyClip
     friend class SkDeferredDevice;  // needs getTopDevice()
+    friend class SkSurface_Raster;  // needs getDevice()
+    friend class SkRecorder;        // InitFlags
+    friend class SkNoSaveLayerCanvas;   // InitFlags
+
+    enum InitFlags {
+        kDefault_InitFlags                  = 0,
+        kConservativeRasterClip_InitFlag    = 1 << 0,
+    };
+    SkCanvas(int width, int height, InitFlags);
+    SkCanvas(SkBaseDevice*, const SkSurfaceProps*, InitFlags);
+    SkCanvas(const SkBitmap&, const SkSurfaceProps&);
+
+    // needs gettotalclip()
+    friend SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas*);
 
     SkBaseDevice* createLayerDevice(const SkImageInfo&);
 
-    SkBaseDevice* init(SkBaseDevice*);
+    // call this each time we attach ourselves to a device
+    //  - constructor
+    //  - internalSaveLayer
+    void setupDevice(SkBaseDevice*);
+
+    SkBaseDevice* init(SkBaseDevice*, InitFlags);
 
     /**
      *  DEPRECATED
@@ -1334,7 +1372,7 @@
     void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
 
     // shared by save() and saveLayer()
-    int internalSave(SaveFlags flags);
+    int internalSave();
     void internalRestore();
     static void DrawRect(const SkDraw& draw, const SkPaint& paint,
                          const SkRect& r, SkScalar textSize);
@@ -1342,6 +1380,9 @@
                                     const char text[], size_t byteLength,
                                     SkScalar x, SkScalar y);
 
+    // only for canvasutils
+    const SkRegion& internal_private_getTotalClip() const;
+
     /*  These maintain a cache of the clip bounds in local coordinates,
         (converted to 2s-compliment if floats are slow).
      */
@@ -1349,6 +1390,7 @@
     mutable bool   fCachedLocalClipBoundsDirty;
     bool fAllowSoftClip;
     bool fAllowSimplifyClip;
+    bool fConservativeRasterClip;
 
     const SkRect& getLocalClipBounds() const {
         if (fCachedLocalClipBoundsDirty) {
@@ -1426,13 +1468,13 @@
 public:
     SkAutoCommentBlock(SkCanvas* canvas, const char* description) {
         fCanvas = canvas;
-        if (NULL != fCanvas) {
+        if (fCanvas) {
             fCanvas->beginCommentGroup(description);
         }
     }
 
     ~SkAutoCommentBlock() {
-        if (NULL != fCanvas) {
+        if (fCanvas) {
             fCanvas->endCommentGroup();
         }
     }
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h
index c26bc07..31d4a01 100644
--- a/include/core/SkColorFilter.h
+++ b/include/core/SkColorFilter.h
@@ -15,7 +15,7 @@
 #include "SkXfermode.h"
 
 class SkBitmap;
-class GrEffectRef;
+class GrProcessor;
 class GrContext;
 
 /**
@@ -126,7 +126,7 @@
     /** A subclass may implement this factory function to work with the GPU backend. If the return
         is non-NULL then the caller owns a ref on the returned object.
      */
-    virtual GrEffectRef* asNewEffect(GrContext*) const;
+    virtual GrFragmentProcessor* asFragmentProcessor(GrContext*) const;
 
     SK_TO_STRING_PUREVIRT()
 
@@ -135,7 +135,9 @@
 
 protected:
     SkColorFilter() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkColorFilter(SkReadBuffer& rb) : INHERITED(rb) {}
+#endif
 
 private:
     typedef SkFlattenable INHERITED;
diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h
index 21e1783..9db7687 100644
--- a/include/core/SkColorPriv.h
+++ b/include/core/SkColorPriv.h
@@ -79,7 +79,7 @@
     #error "SK_PMCOLOR_IS_BGRA does not match SK_*32_SHIFT values"
 #endif
 
-#if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_RGBA)
+#if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA)
     // deduce which to define from the _SHIFT defines
 
     #if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
@@ -306,7 +306,8 @@
     do {
         uint32_t src32 = SkExpand_rgb_16(*src++);
         uint32_t dst32 = SkExpand_rgb_16(*dst);
-        *dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
+        *dst++ = static_cast<uint16_t>(
+            SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)));
     } while (--count > 0);
 }
 
@@ -345,17 +346,15 @@
 #define SkB32Assert(b)  SkASSERT((unsigned)(b) <= SK_B32_MASK)
 
 #ifdef SK_DEBUG
-    static inline void SkPMColorAssert(SkPMColor c) {
-        unsigned a = SkGetPackedA32(c);
-        unsigned r = SkGetPackedR32(c);
-        unsigned g = SkGetPackedG32(c);
-        unsigned b = SkGetPackedB32(c);
-
-        SkA32Assert(a);
-        SkASSERT(r <= a);
-        SkASSERT(g <= a);
-        SkASSERT(b <= a);
-    }
+    #define SkPMColorAssert(color_value)                                    \
+        do {                                                                \
+            SkPMColor pm_color_value = (color_value);                       \
+            uint32_t alpha_color_value = SkGetPackedA32(pm_color_value);    \
+            SkA32Assert(alpha_color_value);                                 \
+            SkASSERT(SkGetPackedR32(pm_color_value) <= alpha_color_value);  \
+            SkASSERT(SkGetPackedG32(pm_color_value) <= alpha_color_value);  \
+            SkASSERT(SkGetPackedB32(pm_color_value) <= alpha_color_value);  \
+        } while (false)
 #else
     #define SkPMColorAssert(c)
 #endif
@@ -787,7 +786,7 @@
                          (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT));
 }
 
-static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) {
+static inline SkPMColor16 SkAlphaMulQ4(SkPMColor16 c, int scale) {
     SkASSERT(scale <= 16);
 
     const unsigned mask = 0xF0F;    //gMask_0F0F;
@@ -797,14 +796,14 @@
     unsigned ag = ((c >> 4) & mask) * scale;
     return (rb & mask) | (ag & ~mask);
 #else
-    c = (c & mask) | ((c & (mask << 4)) << 12);
-    c = c * scale >> 4;
-    return (c & mask) | ((c >> 12) & (mask << 4));
+    unsigned expanded_c = (c & mask) | ((c & (mask << 4)) << 12);
+    unsigned scaled_c = (expanded_c * scale) >> 4;
+    return (scaled_c & mask) | ((scaled_c >> 12) & (mask << 4));
 #endif
 }
 
 /** Expand the SkPMColor16 color into a 32bit value that can be scaled all at
-    once by a value up to 16. Used in conjunction with SkCompact_4444.
+    once by a value up to 16.
 */
 static inline uint32_t SkExpand_4444(U16CPU c) {
     SkASSERT(c == (uint16_t)c);
@@ -813,18 +812,6 @@
     return (c & mask) | ((c & ~mask) << 12);
 }
 
-/** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16.
-    NOTE: this explicitly does not clean the top 16 bits (which may be garbage).
-    It does this for speed, since if it is being written directly to 16bits of
-    memory, the top 16bits will be ignored. Casting the result to uint16_t here
-    would add 2 more instructions, slow us down. It is up to the caller to
-    perform the cast if needed.
-*/
-static inline U16CPU SkCompact_4444(uint32_t c) {
-    const unsigned mask = 0xF0F;    //gMask_0F0F;
-    return (c & mask) | ((c >> 12) & ~mask);
-}
-
 static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) {
     unsigned sa = SkGetPackedA4444(s);
     unsigned sr = SkR4444ToR565(SkGetPackedR4444(s));
@@ -856,22 +843,6 @@
     return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst);
 }
 
-static inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16) {
-    SkASSERT((unsigned)scale16 <= 16);
-
-    uint32_t src32 = SkExpand_4444(src) * scale16;
-    // the scaled srcAlpha is the bottom byte
-#ifdef SK_DEBUG
-    {
-        unsigned srcA = SkGetPackedA4444(src) * scale16;
-        SkASSERT(srcA == (src32 & 0xFF));
-    }
-#endif
-    unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4;
-    uint32_t dst32 = SkExpand_4444(dst) * dstScale;
-    return SkCompact_4444((src32 + dst32) >> 4);
-}
-
 static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) {
     uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) |
                  (SkGetPackedR4444(c) << SK_R32_SHIFT) |
diff --git a/include/core/SkColorShader.h b/include/core/SkColorShader.h
index 8603577..dc45f2d 100644
--- a/include/core/SkColorShader.h
+++ b/include/core/SkColorShader.h
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2007 The Android Open Source Project
  *
@@ -6,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-
 #ifndef SkColorShader_DEFINED
 #define SkColorShader_DEFINED
 
@@ -56,9 +54,8 @@
 
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
 
-    virtual bool asNewEffect(GrContext* context, const SkPaint& paint,
-                             const SkMatrix* localMatrix, GrColor* grColor,
-                             GrEffectRef** grEffect) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                     GrFragmentProcessor**) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader)
@@ -67,9 +64,13 @@
     SkColorShader(SkReadBuffer&);
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
+    virtual bool onAsLuminanceColor(SkColor* lum) const SK_OVERRIDE {
+        *lum = fColor;
+        return true;
+    }
 
 private:
-    SkColor     fColor;         // ignored if fInheritColor is true
+    SkColor fColor;
 
     typedef SkShader INHERITED;
 };
diff --git a/include/core/SkColorTable.h b/include/core/SkColorTable.h
index e4c8c86..c73b431 100644
--- a/include/core/SkColorTable.h
+++ b/include/core/SkColorTable.h
@@ -19,7 +19,7 @@
     SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by
     8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable.
 */
-class SkColorTable : public SkRefCnt {
+class SK_API SkColorTable : public SkRefCnt {
 public:
     SK_DECLARE_INST_COUNT(SkColorTable)
 
diff --git a/include/core/SkData.h b/include/core/SkData.h
index fba2846..e25ef50 100644
--- a/include/core/SkData.h
+++ b/include/core/SkData.h
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
@@ -6,14 +5,13 @@
  * found in the LICENSE file.
  */
 
-
-
 #ifndef SkData_DEFINED
 #define SkData_DEFINED
 
 #include "SkRefCnt.h"
 
 struct SkFILE;
+class SkStream;
 
 /**
  *  SkData holds an immutable data buffer. Not only is the data immutable,
@@ -45,6 +43,19 @@
     }
 
     /**
+     *  USE WITH CAUTION.
+     *  This call will assert that the refcnt is 1, as a precaution against modifying the
+     *  contents when another client/thread has access to the data.
+     */
+    void* writable_data() {
+        if (fSize) {
+            // only assert we're unique if we're not empty
+            SkASSERT(this->unique());
+        }
+        return fPtr;
+    }
+
+    /**
      *  Helper to copy a range of the data into a caller-provided buffer.
      *  Returns the actual number of bytes copied, after clamping offset and
      *  length to the size of the data. If buffer is NULL, it is ignored, and
@@ -70,6 +81,12 @@
     static SkData* NewWithCopy(const void* data, size_t length);
 
     /**
+     *  Create a new data with uninitialized contents. The caller should call writable_data()
+     *  to write into the buffer, but this must be done before another ref() is made.
+     */
+    static SkData* NewUninitialized(size_t length);
+
+    /**
      *  Create a new dataref by copying the specified c-string
      *  (a null-terminated array of bytes). The returned SkData will have size()
      *  equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same
@@ -81,8 +98,15 @@
      *  Create a new dataref, taking the data ptr as is, and using the
      *  releaseproc to free it. The proc may be NULL.
      */
-    static SkData* NewWithProc(const void* data, size_t length,
-                               ReleaseProc proc, void* context);
+    static SkData* NewWithProc(const void* data, size_t length, ReleaseProc proc, void* context);
+
+    /**
+     *  Call this when the data parameter is already const and will outlive the lifetime of the
+     *  SkData. Suitable for with const globals.
+     */
+    static SkData* NewWithoutCopy(const void* data, size_t length) {
+        return NewWithProc(data, length, NULL, NULL);
+    }
 
     /**
      *  Create a new dataref from a pointer allocated by malloc. The Data object
@@ -115,6 +139,13 @@
     static SkData* NewFromFD(int fd);
 
     /**
+     *  Attempt to read size bytes into a SkData. If the read succeeds, return the data,
+     *  else return NULL. Either way the stream's cursor may have been changed as a result
+     *  of calling read().
+     */
+    static SkData* NewFromStream(SkStream*, size_t size);
+
+    /**
      *  Create a new dataref using a subset of the data in the specified
      *  src dataref.
      */
@@ -130,16 +161,22 @@
     ReleaseProc fReleaseProc;
     void*       fReleaseProcContext;
 
-    const void* fPtr;
+    void*       fPtr;
     size_t      fSize;
 
     SkData(const void* ptr, size_t size, ReleaseProc, void* context);
+    SkData(size_t size);   // inplace new/delete
     virtual ~SkData();
 
+    virtual void internal_dispose() const SK_OVERRIDE;
+
     // Called the first time someone calls NewEmpty to initialize the singleton.
     static SkData* NewEmptyImpl();
     static void DeleteEmpty(SkData*);
 
+    // shared internal factory
+    static SkData* PrivateNewWithCopy(const void* srcOrNull, size_t length);
+
     typedef SkRefCnt INHERITED;
 };
 
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index 4b3db12..b19177a 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -12,7 +12,6 @@
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkColor.h"
-#include "SkDeviceProperties.h"
 #include "SkImageFilter.h"
 
 class SkClipStack;
@@ -21,7 +20,7 @@
 class SkMatrix;
 class SkMetaData;
 class SkRegion;
-
+struct SkDeviceProperties;
 class GrRenderTarget;
 
 class SK_API SkBaseDevice : public SkRefCnt {
@@ -32,24 +31,12 @@
      *  Construct a new device.
     */
     SkBaseDevice();
-
-    /**
-     *  Construct a new device.
-    */
-    SkBaseDevice(const SkDeviceProperties& deviceProperties);
-
     virtual ~SkBaseDevice();
 
     SkBaseDevice* createCompatibleDevice(const SkImageInfo&);
 
     SkMetaData& getMetaData();
 
-    /** Return the image properties of the device. */
-    virtual const SkDeviceProperties& getDeviceProperties() const {
-        //Currently, all the properties are leaky.
-        return fLeakyProperties;
-    }
-
     /**
      *  Return ImageInfo for this device. If the canvas is not backed by pixels
      *  (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
@@ -67,27 +54,17 @@
         bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
     }
 
-#ifdef SK_SUPPORT_LEGACY_DEVICE_VIRTUAL_ISOPAQUE
-    virtual int width() const {
-        return this->imageInfo().width();
-    }
-    virtual int height() const {
-        return this->imageInfo().height();
-    }
-    virtual bool isOpaque() const {
-        return this->imageInfo().isOpaque();
-    }
-#else
     int width() const {
         return this->imageInfo().width();
     }
+
     int height() const {
         return this->imageInfo().height();
     }
+
     bool isOpaque() const {
         return this->imageInfo().isOpaque();
     }
-#endif
 
     /** Return the bitmap associated with this device. Call this each time you need
         to access the bitmap, as it notifies the subclass to perform any flushing
@@ -104,7 +81,7 @@
     /**
      * Return the device's associated gpu render target, or NULL.
      */
-    virtual GrRenderTarget* accessRenderTarget() = 0;
+    virtual GrRenderTarget* accessRenderTarget() { return NULL; }
 
 
     /**
@@ -144,12 +121,12 @@
 protected:
     enum Usage {
        kGeneral_Usage,
-       kSaveLayer_Usage  // <! internal use only
+       kSaveLayer_Usage,  // <! internal use only
+       kImageFilter_Usage // <! internal use only
     };
 
     struct TextFlags {
-        uint32_t            fFlags;     // SkPaint::getFlags()
-        SkPaint::Hinting    fHinting;
+        uint32_t    fFlags;     // SkPaint::getFlags()
     };
 
     /**
@@ -157,10 +134,8 @@
      *  make a change to the specified values, it should write them into the
      *  textflags parameter (output) and return true. If the paint is fine as
      *  is, then ignore the textflags parameter and return false.
-     *
-     *  The baseclass SkBaseDevice filters based on its depth and blitters.
      */
-    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) = 0;
+    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) { return false; }
 
     /**
      *
@@ -254,6 +229,12 @@
                               const SkColor colors[], SkXfermode* xmode,
                               const uint16_t indices[], int indexCount,
                               const SkPaint& paint) = 0;
+    // default implementation unrolls the blob runs.
+    virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
+                              const SkPaint& paint);
+    // default implementation calls drawVertices
+    virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
+                           const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
     /** The SkDevice passed will be an SkDevice which was returned by a call to
         onCreateDevice on this device with kSaveLayer_Usage.
      */
@@ -273,8 +254,8 @@
     /** Called when this device is installed into a Canvas. Balanced by a call
         to unlockPixels() when the device is removed from a Canvas.
     */
-    virtual void lockPixels() = 0;
-    virtual void unlockPixels() = 0;
+    virtual void lockPixels() {}
+    virtual void unlockPixels() {}
 
     /**
      *  Returns true if the device allows processing of this imagefilter. If
@@ -282,7 +263,7 @@
      *  some subclasses that do not support pixel manipulations after drawing
      *  has occurred (e.g. printing). The default implementation returns true.
      */
-    virtual bool allowImageFilter(const SkImageFilter*) = 0;
+    virtual bool allowImageFilter(const SkImageFilter*) { return true; }
 
     /**
      *  Override and return true for filters that the device can handle
@@ -291,7 +272,7 @@
      *  Returning false means the SkCanvas will have apply the filter itself,
      *  and just pass the resulting image to the device.
      */
-    virtual bool canHandleImageFilter(const SkImageFilter*) = 0;
+    virtual bool canHandleImageFilter(const SkImageFilter*) { return false; }
 
     /**
      *  Related (but not required) to canHandleImageFilter, this method returns
@@ -302,11 +283,13 @@
      */
     virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
                              const SkImageFilter::Context& ctx,
-                             SkBitmap* result, SkIPoint* offset) = 0;
+                             SkBitmap* result, SkIPoint* offset) {
+        return false;
+    }
 
 protected:
     // default impl returns NULL
-    virtual SkSurface* newSurface(const SkImageInfo&);
+    virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&);
 
     // default impl returns NULL
     virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes);
@@ -338,7 +321,9 @@
      *  If the device does handle a property, that property should be set to the identity value
      *  for that property, effectively making it non-leaky.
      */
-    SkDeviceProperties fLeakyProperties;
+    const SkDeviceProperties& getLeakyProperties() const {
+        return *fLeakyProperties;
+    }
 
     /**
      *  PRIVATE / EXPERIMENTAL -- do not call
@@ -348,13 +333,6 @@
 
     /**
      *  PRIVATE / EXPERIMENTAL -- do not call
-     *  Purge all discardable optimization information for 'picture'. If
-     *  picture is NULL then purge discardable information for all pictures.
-     */
-    virtual void EXPERIMENTAL_purge(const SkPicture* picture);
-
-    /**
-     *  PRIVATE / EXPERIMENTAL -- do not call
      *  This entry point gives the backend an opportunity to take over the rendering
      *  of 'picture'. If optimization data is available (due to an earlier
      *  'optimize' call) this entry point should make use of it and return true
@@ -363,7 +341,10 @@
      *  to perform some device-specific warm up tasks and then let SkCanvas
      *  perform the main rendering loop (by return false from here).
      */
-    virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture);
+    virtual bool EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*,
+                                          const SkPaint*);
+
+    void setPixelGeometry(SkPixelGeometry geo);
 
 private:
     friend class SkCanvas;
@@ -380,12 +361,16 @@
     // but cannot change the width/height, so there should be no change to
     // any clip information.
     // TODO: move to SkBitmapDevice
-    virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0;
+    virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) {}
+
+    virtual bool forceConservativeRasterClip() const { return false; }
 
     // just called by SkCanvas when built as a layer
     void setOrigin(int x, int y) { fOrigin.set(x, y); }
     // just called by SkCanvas for saveLayer
     SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&);
+    // just called by SkCanvas for imagefilter
+    SkBaseDevice* createCompatibleDeviceForImageFilter(const SkImageInfo&);
 
     virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) {
         return NULL;
@@ -393,10 +378,13 @@
 
     /** Causes any deferred drawing to the device to be completed.
      */
-    virtual void flush() = 0;
+    virtual void flush() {}
+
+    virtual SkImageFilter::Cache* getImageFilterCache() { return NULL; }
 
     SkIPoint    fOrigin;
     SkMetaData* fMetaData;
+    SkDeviceProperties* fLeakyProperties;   // will always exist.
 
 #ifdef SK_DEBUG
     bool        fAttachedToCanvas;
diff --git a/include/core/SkDeviceProperties.h b/include/core/SkDeviceProperties.h
deleted file mode 100644
index 80e0177..0000000
--- a/include/core/SkDeviceProperties.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef SkDeviceProperties_DEFINED
-#define SkDeviceProperties_DEFINED
-
-//TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and remove this import.
-#include "SkFontLCDConfig.h"
-
-struct SkDeviceProperties {
-    struct Geometry {
-        /** The orientation of the pixel specifies the interpretation of the
-        *  layout. If the orientation is horizontal, the layout is interpreted as
-        *  left to right. It the orientation is vertical, the layout is
-        *  interpreted top to bottom (rotated 90deg cw from horizontal).
-        */
-        enum Orientation {
-            kUnknown_Orientation      = 0x0,
-            kKnown_Orientation        = 0x2,
-
-            kHorizontal_Orientation   = 0x2,  //!< this is the default
-            kVertical_Orientation     = 0x3,
-
-            kOrientationMask          = 0x3,
-        };
-
-        /** The layout of the pixel specifies its subpixel geometry.
-        *
-        *  kUnknown_Layout means that the subpixel elements are not spatially
-        *  separated in any known or usable fashion.
-        */
-        enum Layout {
-            kUnknown_Layout   = 0x0,
-            kKnown_Layout     = 0x8,
-
-            kRGB_Layout       = 0x8,  //!< this is the default
-            kBGR_Layout       = 0xC,
-
-            kLayoutMask       = 0xC,
-        };
-
-        Orientation getOrientation() {
-            return static_cast<Orientation>(fGeometry & kOrientationMask);
-        }
-        Layout getLayout() {
-            return static_cast<Layout>(fGeometry & kLayoutMask);
-        }
-
-        bool isOrientationKnown() {
-            return SkToBool(fGeometry & kKnown_Orientation);
-        }
-        bool isLayoutKnown() {
-            return SkToBool(fGeometry & kKnown_Layout);
-        }
-
-    private:
-        //TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and replace these calls with constants.
-        static Orientation fromOldOrientation(SkFontLCDConfig::LCDOrientation orientation) {
-            switch (orientation) {
-            case SkFontLCDConfig::kHorizontal_LCDOrientation: return kHorizontal_Orientation;
-            case SkFontLCDConfig::kVertical_LCDOrientation: return kVertical_Orientation;
-            default: return kUnknown_Orientation;
-            }
-        }
-        static Layout fromOldLayout(SkFontLCDConfig::LCDOrder order) {
-            switch (order) {
-            case SkFontLCDConfig::kRGB_LCDOrder: return kRGB_Layout;
-            case SkFontLCDConfig::kBGR_LCDOrder: return kBGR_Layout;
-            default: return kUnknown_Layout;
-            }
-        }
-    public:
-        static Geometry MakeDefault() {
-            Orientation orientation = fromOldOrientation(SkFontLCDConfig::GetSubpixelOrientation()); //kHorizontal_Orientation
-            Layout layout = fromOldLayout(SkFontLCDConfig::GetSubpixelOrder()); //kRGB_Layout
-            Geometry ret = { SkToU8(orientation | layout) };
-            return ret;
-        }
-
-        static Geometry Make(Orientation orientation, Layout layout) {
-            Geometry ret = { SkToU8(orientation | layout) };
-            return ret;
-        }
-
-        uint8_t fGeometry;
-    };
-
-    static SkDeviceProperties MakeDefault() {
-        SkDeviceProperties ret = { Geometry::MakeDefault(), SK_GAMMA_EXPONENT };
-        return ret;
-    }
-
-    static SkDeviceProperties Make(Geometry geometry, SkScalar gamma) {
-        SkDeviceProperties ret = { geometry, gamma };
-        return ret;
-    }
-
-    /** Each pixel of an image will have some number of channels.
-     *  Can the layout of those channels be exploited? */
-    Geometry fGeometry;
-
-    /** Represents the color space of the image. This is a woefully inadequate beginning. */
-    SkScalar fGamma;
-};
-
-#endif
diff --git a/include/core/SkDraw.h b/include/core/SkDraw.h
index 918f233..21d4210 100644
--- a/include/core/SkDraw.h
+++ b/include/core/SkDraw.h
@@ -17,6 +17,7 @@
 class SkBitmap;
 class SkClipStack;
 class SkBaseDevice;
+class SkBlitter;
 class SkMatrix;
 class SkPath;
 class SkRegion;
@@ -49,8 +50,9 @@
         this->drawPath(path, paint, prePathMatrix, pathIsMutable, false);
     }
 
-    void drawPath(const SkPath& path, const SkPaint& paint) const {
-        this->drawPath(path, paint, NULL, false, false);
+    void drawPath(const SkPath& path, const SkPaint& paint,
+                  SkBlitter* customBlitter = NULL) const {
+        this->drawPath(path, paint, NULL, false, false, customBlitter);
     }
 
     void    drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const;
@@ -74,8 +76,9 @@
      *
      *  Only device A8 is supported right now.
      */
-    void drawPathCoverage(const SkPath& src, const SkPaint& paint) const {
-        this->drawPath(src, paint, NULL, false, true);
+    void drawPathCoverage(const SkPath& src, const SkPaint& paint,
+                          SkBlitter* customBlitter = NULL) const {
+        this->drawPath(src, paint, NULL, false, true, customBlitter);
     }
 
     /** Helper function that creates a mask from a path and an optional maskfilter.
@@ -118,7 +121,8 @@
     void    drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
 
     void    drawPath(const SkPath&, const SkPaint&, const SkMatrix* preMatrix,
-                     bool pathIsMutable, bool drawCoverage) const;
+                     bool pathIsMutable, bool drawCoverage,
+                     SkBlitter* customBlitter = NULL) const;
 
     /**
      *  Return the current clip bounds, in local coordinates, with slop to account
diff --git a/include/core/SkDrawLooper.h b/include/core/SkDrawLooper.h
index b92bacc..f771d01 100644
--- a/include/core/SkDrawLooper.h
+++ b/include/core/SkDrawLooper.h
@@ -114,7 +114,9 @@
 
 protected:
     SkDrawLooper() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     typedef SkFlattenable INHERITED;
diff --git a/include/core/SkDrawPictureCallback.h b/include/core/SkDrawPictureCallback.h
new file mode 100644
index 0000000..d5a360e
--- /dev/null
+++ b/include/core/SkDrawPictureCallback.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDrawPictureCallback_DEFINED
+#define SkDrawPictureCallback_DEFINED
+
+#include "SkTypes.h"
+
+/**
+ *  Subclasses of this can be passed to canvas.drawPicture(). During the drawing
+ *  of the picture, this callback will periodically be invoked. If its
+ *  abortDrawing() returns true, then picture playback will be interrupted.
+ *
+ *  The resulting drawing is undefined, as there is no guarantee how often the
+ *  callback will be invoked. If the abort happens inside some level of nested
+ *  calls to save(), restore will automatically be called to return the state
+ *  to the same level it was before the drawPicture call was made.
+ */
+class SK_API SkDrawPictureCallback {
+public:
+    SkDrawPictureCallback() {}
+    virtual ~SkDrawPictureCallback() {}
+
+    virtual bool abortDrawing() = 0;
+};
+
+#endif//SkDrawPictureCallback_DEFINED
diff --git a/include/core/SkDynamicAnnotations.h b/include/core/SkDynamicAnnotations.h
index 6d21cdd..422d98d 100644
--- a/include/core/SkDynamicAnnotations.h
+++ b/include/core/SkDynamicAnnotations.h
@@ -12,13 +12,16 @@
 // namely thread sanitizer.  This is a cut-down version of the full dynamic_annotations library with
 // only the features used by Skia.
 
-// We check the same define to know to enable the annotations, but prefix all our macros with SK_.
-#if DYNAMIC_ANNOTATIONS_ENABLED
+#if SK_DYNAMIC_ANNOTATIONS_ENABLED
 
 extern "C" {
 // TSAN provides these hooks.
 void AnnotateIgnoreReadsBegin(const char* file, int line);
 void AnnotateIgnoreReadsEnd(const char* file, int line);
+void AnnotateIgnoreWritesBegin(const char* file, int line);
+void AnnotateIgnoreWritesEnd(const char* file, int line);
+void AnnotateBenignRaceSized(const char* file, int line,
+                             const volatile void* addr, long size, const char* desc);
 }  // extern "C"
 
 // SK_ANNOTATE_UNPROTECTED_READ can wrap any variable read to tell TSAN to ignore that it appears to
@@ -37,10 +40,74 @@
     return read;
 }
 
-#else  // !DYNAMIC_ANNOTATIONS_ENABLED
+// Like SK_ANNOTATE_UNPROTECTED_READ, but for writes.
+template <typename T>
+inline void SK_ANNOTATE_UNPROTECTED_WRITE(T* ptr, const volatile T& val) {
+    AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
+    *ptr = val;
+    AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
+}
+
+// Ignore racy reads and racy writes to this pointer, indefinitely.
+// If at all possible, use the more precise SK_ANNOTATE_UNPROTECTED_READ.
+template <typename T>
+void SK_ANNOTATE_BENIGN_RACE(T* ptr) {
+    AnnotateBenignRaceSized(__FILE__, __LINE__, ptr, sizeof(*ptr), "SK_ANNOTATE_BENIGN_RACE");
+}
+
+#else  // !SK_DYNAMIC_ANNOTATIONS_ENABLED
 
 #define SK_ANNOTATE_UNPROTECTED_READ(x) (x)
+#define SK_ANNOTATE_UNPROTECTED_WRITE(ptr, val) *(ptr) = (val)
+#define SK_ANNOTATE_BENIGN_RACE(ptr)
 
 #endif
 
+// Can be used to wrap values that are intentionally racy, usually small mutable cached values, e.g.
+//   - SkMatrix type mask
+//   - SkPixelRef genIDs
+template <typename T>
+class SkTRacy {
+public:
+    operator const T() const {
+        return SK_ANNOTATE_UNPROTECTED_READ(fVal);
+    }
+
+    SkTRacy& operator=(const T& val) {
+        SK_ANNOTATE_UNPROTECTED_WRITE(&fVal, val);
+        return *this;
+    }
+
+private:
+    T fVal;
+};
+
+// This is like SkTRacy, but allows you to return the value by reference.
+// TSAN is better at suppressing SkTRacy than SkTRacyReffable, so use SkTRacy when possible.
+//
+// We use this for SkPathRef bounds, which is an SkRect we pass around by reference publically.
+template <typename T>
+class SkTRacyReffable {
+public:
+    SkTRacyReffable() { SK_ANNOTATE_BENIGN_RACE(&fVal); }
+
+    operator const T&() const {
+        return fVal;
+    }
+
+    SkTRacyReffable& operator=(const T& val) {
+        fVal = val;
+        return *this;
+    }
+
+    const T* get() const { return &fVal; }
+          T* get()       { return &fVal; }
+
+    const T* operator->() const { return &fVal; }
+          T* operator->()       { return &fVal; }
+
+private:
+    T fVal;
+};
+
 #endif//SkDynamicAnnotations_DEFINED
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h
index f6d377a..679f640 100644
--- a/include/core/SkFlattenable.h
+++ b/include/core/SkFlattenable.h
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2006 The Android Open Source Project
  *
@@ -6,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-
 #ifndef SkFlattenable_DEFINED
 #define SkFlattenable_DEFINED
 
@@ -15,9 +13,26 @@
 class SkReadBuffer;
 class SkWriteBuffer;
 
-#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
-        SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \
-                                 flattenable::GetFlattenableType());
+#define SK_SUPPORT_LEGACY_DEEPFLATTENING
+
+/*
+ *  Flattening is straight-forward:
+ *      1. call getFactory() so we have a function-ptr to recreate the subclass
+ *      2. call flatten(buffer) to write out enough data for the factory to read
+ *
+ *  Unflattening is easy for the caller: new_instance = factory(buffer)
+ *
+ *  The complexity of supporting this is as follows.
+ *
+ *  If your subclass wants to control unflattening, use this macro in your declaration:
+ *      SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS
+ *  This will provide a getFactory(), and require that the subclass implements CreateProc.
+ *
+ *  For older buffers (before the DEEPFLATTENING change, the macros below declare
+ *  a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep,
+ *  then it calls through to a (usually protected) constructor, passing the buffer.
+ *  If the buffer is newer, then it directly calls the "real" factory: CreateProc.
+ */
 
 #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
 
@@ -30,11 +45,39 @@
 #define SK_DECLARE_UNFLATTENABLE_OBJECT() \
     virtual Factory getFactory() const SK_OVERRIDE { return NULL; }
 
-#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
-    virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } \
-    static SkFlattenable* CreateProc(SkReadBuffer& buffer) { \
-        return SkNEW_ARGS(flattenable, (buffer)); \
-    }
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
+    SkFlattenable::Registrar(#flattenable, flattenable::DeepCreateProc, \
+                             flattenable::GetFlattenableType());
+
+#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
+    private:                                                                \
+    static SkFlattenable* CreateProc(SkReadBuffer&);                        \
+    static SkFlattenable* DeepCreateProc(SkReadBuffer& buffer) {            \
+        if (NeedsDeepUnflatten(buffer)) {                                   \
+            return SkNEW_ARGS(flattenable, (buffer));                       \
+        }                                                                   \
+        return CreateProc(buffer);                                          \
+    }                                                                       \
+    friend class SkPrivateEffectInitializer;                                \
+    public:                                                                 \
+    virtual Factory getFactory() const SK_OVERRIDE {return DeepCreateProc;}
+#else
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
+    SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \
+                             flattenable::GetFlattenableType());
+
+#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
+    private:                                                                \
+    static SkFlattenable* CreateProc(SkReadBuffer&);                        \
+    friend class SkPrivateEffectInitializer;                                \
+    public:                                                                 \
+    virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; }
+#endif
+
+// If your subclass will *never* need to be unflattened, declare this.
+#define SK_DECLARE_NOT_FLATTENABLE_PROCS(flattenable)   \
+    virtual Factory getFactory() const SK_OVERRIDE { return ReturnNullCreateProc; }
 
 /** For SkFlattenable derived objects with a valid type
     This macro should only be used in base class objects in core
@@ -94,14 +137,21 @@
         }
     };
 
-    /** Override this to write data specific to your subclass into the buffer,
-     being sure to call your super-class' version first. This data will later
-     be passed to your Factory function, returned by getFactory().
+    /**
+     *  Override this if your subclass needs to record data that it will need to recreate itself
+     *  from its CreateProc (returned by getFactory()).
      */
-    virtual void flatten(SkWriteBuffer&) const;
+    virtual void flatten(SkWriteBuffer&) const {}
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    static bool NeedsDeepUnflatten(const SkReadBuffer&);
     SkFlattenable(SkReadBuffer&) {}
+#endif
+
+    static SkFlattenable* ReturnNullCreateProc(SkReadBuffer&) {
+        return NULL;
+    }
 
 private:
     static void InitializeFlattenablesIfNeeded();
diff --git a/include/core/SkFlattenableBuffers.h b/include/core/SkFlattenableBuffers.h
index 3e5d5b9..6c7c2ad 100644
--- a/include/core/SkFlattenableBuffers.h
+++ b/include/core/SkFlattenableBuffers.h
@@ -1,10 +1,2 @@
 // Temporary shim to keep a couple dependencies working in Chromium.
-#ifndef SkFlattenableBuffers_DEFINED
-#define SkFlattenableBuffers_DEFINED
-
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
-
-typedef SkReadBuffer SkFlattenableReadBuffer;
-
-#endif//SkFlattenableBuffers_DEFINED
+// TODO(halcanary): delete this file.
diff --git a/include/core/SkFloatBits.h b/include/core/SkFloatBits.h
index 552e712..3ddb9ef 100644
--- a/include/core/SkFloatBits.h
+++ b/include/core/SkFloatBits.h
@@ -95,7 +95,6 @@
 /** Return x cast to a float (i.e. (float)x)
 */
 float SkIntToFloatCast(int x);
-float SkIntToFloatCast_NoOverflowCheck(int x);
 
 /** Return the float cast to an int.
     If the value is out of range, or NaN, return +/- SK_MaxS32
diff --git a/include/core/SkFloatingPoint.h b/include/core/SkFloatingPoint.h
index 6e372d9..2df8f9b 100644
--- a/include/core/SkFloatingPoint.h
+++ b/include/core/SkFloatingPoint.h
@@ -31,7 +31,9 @@
 
 static inline float sk_float_copysign(float x, float y) {
 // c++11 contains a 'float copysign(float, float)' function in <cmath>.
-#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
+// clang-cl reports __cplusplus for clang, not the __cplusplus vc++ version _MSC_VER would report.
+#define SK_BUILD_WITH_CLANG_CL (defined(_MSC_VER) && defined(__clang__))
+#if (!SK_BUILD_WITH_CLANG_CL && __cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
     return copysign(x, y);
 
 // Posix has demanded 'float copysignf(float, float)' (from C99) since Issue 6.
@@ -120,7 +122,7 @@
 
 #if defined(__SSE__)
 #include <xmmintrin.h>
-#elif defined(__ARM_NEON__)
+#elif defined(SK_ARM_HAS_NEON)
 #include <arm_neon.h>
 #endif
 
@@ -136,7 +138,7 @@
     float result;
     _mm_store_ss(&result, _mm_rsqrt_ss(_mm_set_ss(x)));
     return result;
-#elif defined(__ARM_NEON__)
+#elif defined(SK_ARM_HAS_NEON)
     // Get initial estimate.
     const float32x2_t xx = vdup_n_f32(x);  // Clever readers will note we're doing everything 2x.
     float32x2_t estimate = vrsqrte_f32(xx);
diff --git a/include/core/SkFont.h b/include/core/SkFont.h
index 9bdecd6..e4ebebb 100644
--- a/include/core/SkFont.h
+++ b/include/core/SkFont.h
@@ -75,8 +75,8 @@
     enum Flags {
         /**
          *  Use the system's automatic hinting mechanism to hint the typeface.
-         *  If both bytecode and auto hints are specified, attempt to use the bytecodes first.
-         *  If that fails (e.g. there are no codes), then attempt to autohint.
+         *  This is a last resort hinting method applied only if other hinting methods do not apply.
+         *  TODO: where to put auto-normal vs auto-light?
          */
         kEnableAutoHints_Flag       = 1 << 0,
 
@@ -88,6 +88,13 @@
         kEnableByteCodeHints_Flag   = 1 << 1,
 
         /**
+         *  If the typeface contains explicit bitmaps for hinting, use them.
+         *  If both bytecode and auto hints are also specified, attempt to use the bitmaps first;
+         *  if that fails (e.g. there are no bitmaps), then attempt to bytecode or autohint.
+         */
+        kEmbeddedBitmaps_Flag       = 1 << 2,
+
+        /**
          *  Use rounded metric values (e.g. advance).
          *  If either auto or bytecode hinting was used, apply those results to the metrics of the
          *  glyphs as well. If no hinting was applied, the metrics will just be rounded to the
@@ -96,10 +103,9 @@
          *  This applies to calls that return metrics (e.g. measureText) and to drawing the glyphs
          *  (see SkCanvas drawText and drawPosText).
          */
-        kUseNonlinearMetrics_Flag   = 1 << 2,
+        kUseNonlinearMetrics_Flag   = 1 << 3,
 
-        kVertical_Flag              = 1 << 3,
-        kEmbeddedBitmaps_Flag       = 1 << 4,
+        kVertical_Flag              = 1 << 4,
         kGenA8FromLCD_Flag          = 1 << 5,
         kEmbolden_Flag              = 1 << 6,
         kDevKern_Flag               = 1 << 7,   // ifdef ANDROID ?
diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h
index 4c5013f..a2cc04b 100644
--- a/include/core/SkFontHost.h
+++ b/include/core/SkFontHost.h
@@ -90,42 +90,6 @@
     static void SetSubpixelOrder(LCDOrder order);
     /** @deprecated get from Device. */
     static LCDOrder GetSubpixelOrder();
-
-private:
-    /** Return a new, closest matching typeface given either an existing family
-        (specified by a typeface in that family) or by a familyName and a
-        requested style.
-        1) If familyFace is null, use familyName.
-        2) If familyName is null, use data (UTF-16 to cover).
-        3) If all are null, return the default font that best matches style
-     */
-    static SkTypeface* CreateTypeface(const SkTypeface* familyFace,
-                                      const char familyName[],
-                                      SkTypeface::Style style);
-
-    /** Return a new typeface given the data buffer. If the data does not
-        represent a valid font, returns null.
-
-        If a typeface instance is returned, the caller is responsible for
-        calling unref() on the typeface when they are finished with it.
-
-        The returned typeface may or may not have called ref() on the stream
-        parameter. If the typeface has not called ref(), then it may have made
-        a copy of the releveant data. In either case, the caller is still
-        responsible for its refcnt ownership of the stream.
-     */
-    static SkTypeface* CreateTypefaceFromStream(SkStream*);
-
-    /** Return a new typeface from the specified file path. If the file does not
-        represent a valid font, this returns null. If a typeface is returned,
-        the caller is responsible for calling unref() when it is no longer used.
-     */
-    static SkTypeface* CreateTypefaceFromFile(const char path[]);
-
-    ///////////////////////////////////////////////////////////////////////////
-
-    friend class SkScalerContext;
-    friend class SkTypeface;
 };
 
 #endif
diff --git a/include/core/SkGraphics.h b/include/core/SkGraphics.h
index e7865ca..c154df1 100644
--- a/include/core/SkGraphics.h
+++ b/include/core/SkGraphics.h
@@ -86,40 +86,59 @@
      *
      *  This function returns the memory usage of the Scaled Image Cache.
      */
-    static size_t GetImageCacheTotalBytesUsed();
-    /**
-     *  These functions get/set the memory usage limit for the Scaled
-     *  Image Cache.  Bitmaps are purged from the cache when the
-     *  memory useage exceeds this limit.
-     */
-    static size_t GetImageCacheTotalByteLimit();
-    static size_t SetImageCacheTotalByteLimit(size_t newLimit);
+    static size_t GetResourceCacheTotalBytesUsed();
 
-    // DEPRECATED
+    /**
+     *  These functions get/set the memory usage limit for the resource cache, used for temporary
+     *  bitmaps and other resources. Entries are purged from the cache when the memory useage
+     *  exceeds this limit.
+     */
+    static size_t GetResourceCacheTotalByteLimit();
+    static size_t SetResourceCacheTotalByteLimit(size_t newLimit);
+
+    /**
+     *  For debugging purposes, this will attempt to purge the resource cache. It
+     *  does not change the limit.
+     */
+    static void PurgeResourceCache();
+
+    /**
+     *  When the cachable entry is very lage (e.g. a large scaled bitmap), adding it to the cache
+     *  can cause most/all of the existing entries to be purged. To avoid the, the client can set
+     *  a limit for a single allocation. If a cacheable entry would have been cached, but its size
+     *  exceeds this limit, then we do not attempt to cache it at all.
+     *
+     *  Zero is the default value, meaning we always attempt to cache entries.
+     */
+    static size_t GetResourceCacheSingleAllocationByteLimit();
+    static size_t SetResourceCacheSingleAllocationByteLimit(size_t newLimit);
+
+#ifdef SK_SUPPORT_LEGACY_IMAGECACHE_NAME
     static size_t GetImageCacheBytesUsed() {
         return GetImageCacheTotalBytesUsed();
     }
-    // DEPRECATED
     static size_t GetImageCacheByteLimit() {
         return GetImageCacheTotalByteLimit();
     }
-    // DEPRECATED
     static size_t SetImageCacheByteLimit(size_t newLimit) {
         return SetImageCacheTotalByteLimit(newLimit);
     }
-
-    /**
-     *  Scaling bitmaps with the SkPaint::kHigh_FilterLevel setting is
-     *  expensive, so the result is saved in the global Scaled Image
-     *  Cache.  When the resulting bitmap is too large, this can
-     *  overload the cache.  If the ImageCacheSingleAllocationByteLimit
-     *  is set to a non-zero number, and the resulting bitmap would be
-     *  larger than that value, the bitmap scaling algorithm falls
-     *  back onto a cheaper algorithm and does not cache the result.
-     *  Zero is the default value.
-     */
-    static size_t GetImageCacheSingleAllocationByteLimit();
-    static size_t SetImageCacheSingleAllocationByteLimit(size_t newLimit);
+    static size_t GetImageCacheTotalBytesUsed() {
+        return GetResourceCacheTotalBytesUsed();
+    }
+    static size_t GetImageCacheTotalByteLimit() {
+        return GetResourceCacheTotalByteLimit();
+    }
+    static size_t SetImageCacheTotalByteLimit(size_t newLimit) {
+        return SetResourceCacheTotalByteLimit(newLimit);
+    }
+    static size_t GetImageCacheSingleAllocationByteLimit() {
+        return GetResourceCacheSingleAllocationByteLimit();
+    }
+    static size_t SetImageCacheSingleAllocationByteLimit(size_t newLimit) {
+        return SetResourceCacheSingleAllocationByteLimit(newLimit);
+    }
+#endif
 
     /**
      *  Applications with command line options may pass optional state, such
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index c9f9396..5a6c966 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -12,17 +12,15 @@
 #include "SkImageEncoder.h"
 #include "SkRefCnt.h"
 #include "SkScalar.h"
+#include "SkShader.h"
 
 class SkData;
 class SkCanvas;
+class SkImageGenerator;
 class SkPaint;
-class SkShader;
 class GrContext;
 class GrTexture;
 
-// need for TileMode
-#include "SkShader.h"
-
 /**
  *  SkImage is an abstraction for drawing a rectagle of pixels, though the
  *  particular type of image could be actually storing its data on the GPU, or
@@ -41,7 +39,6 @@
 
     static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes);
     static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes);
-    static SkImage* NewEncodedData(SkData*);
 
     /**
      * GrTexture is a more logical parameter for this factory, but its
@@ -50,6 +47,15 @@
      */
     static SkImage* NewTexture(const SkBitmap&);
 
+    virtual bool isOpaque() const { return false; }
+
+    /**
+     *  Construct a new SkImage based on the given ImageGenerator.
+     *  This function will always take ownership of the passed
+     *  ImageGenerator.  Returns NULL on error.
+     */
+    static SkImage* NewFromGenerator(SkImageGenerator*);
+
     int width() const { return fWidth; }
     int height() const { return fHeight; }
     uint32_t uniqueID() const { return fUniqueID; }
@@ -61,19 +67,9 @@
      */
     GrTexture* getTexture();
 
-    SkShader*   newShaderClamp() const;
-    SkShader*   newShader(SkShader::TileMode, SkShader::TileMode) const;
-
-    void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
-
-    /**
-     *  Draw the image, cropped to the src rect, to the dst rect of a canvas.
-     *  If src is larger than the bounds of the image, the rest of the image is
-     *  filled with transparent black pixels.
-     *
-     *  See SkCanvas::drawBitmapRectToRect for similar behavior.
-     */
-    void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*);
+    virtual SkShader* newShader(SkShader::TileMode,
+                                SkShader::TileMode,
+                                const SkMatrix* localMatrix = NULL) const;
 
     /**
      *  If the image has direct access to its pixels (i.e. they are in local
@@ -96,6 +92,17 @@
     SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type,
                    int quality = 80) const;
 
+    void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
+
+    /**
+     *  Draw the image, cropped to the src rect, to the dst rect of a canvas.
+     *  If src is larger than the bounds of the image, the rest of the image is
+     *  filled with transparent black pixels.
+     *
+     *  See SkCanvas::drawBitmapRectToRect for similar behavior.
+     */
+    void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*) const;
+
 protected:
     SkImage(int width, int height) :
         fWidth(width),
diff --git a/include/core/SkImageDecoder.h b/include/core/SkImageDecoder.h
index 9ab32d7..5910d33 100644
--- a/include/core/SkImageDecoder.h
+++ b/include/core/SkImageDecoder.h
@@ -37,6 +37,7 @@
         kWEBP_Format,
         kPKM_Format,
         kKTX_Format,
+        kASTC_Format,
 
         kLastKnownFormat = kKTX_Format,
     };
@@ -159,51 +160,19 @@
     Chooser* setChooser(Chooser*);
 #endif
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
     /**
-     *  Optional table describing the caller's preferred config based on
-     *  information about the src data. Each field should be set to the
-     *  preferred config for a src described in the name of the field. The
-     *  src attributes are described in terms of depth (8-index,
-     *  8bit-grayscale, or 8-bits/component) and whether there is per-pixel
-     *  alpha (does not apply to grayscale). If the caller has no preference
-     *  for a particular src type, its slot should be set to kNo_Config.
+     *  By default, the codec will try to comply with the "pref" colortype
+     *  that is passed to decode() or decodeSubset(). However, this can be called
+     *  to override that, causing the codec to try to match the src depth instead
+     *  (as shown below).
      *
-     *  NOTE ABOUT PREFERRED CONFIGS:
-     *  If a config is preferred, either using a pref table or as a parameter
-     *  to some flavor of decode, it is still at the discretion of the codec
-     *  as to what output config is actually returned, as it may not be able
-     *  to support the caller's preference.
-     *
-     *  If a bitmap is decoded into SkBitmap::A8_Config, the resulting bitmap
-     *  will either be a conversion of the grayscale in the case of a
-     *  grayscale source or the alpha channel in the case of a source with
-     *  an alpha channel.
+     *      src_8Index  -> kIndex_8_SkColorType
+     *      src_8Gray   -> kN32_SkColorType
+     *      src_8bpc    -> kN32_SkColorType
      */
-    struct PrefConfigTable {
-        SkBitmap::Config fPrefFor_8Index_NoAlpha_src;
-        SkBitmap::Config fPrefFor_8Index_YesAlpha_src;
-        SkBitmap::Config fPrefFor_8Gray_src;
-        SkBitmap::Config fPrefFor_8bpc_NoAlpha_src;
-        SkBitmap::Config fPrefFor_8bpc_YesAlpha_src;
-    };
-
-    /**
-     *  Set an optional table for specifying the caller's preferred config
-     *  based on information about the src data.
-     *
-     *  The default is no preference, which will assume the config set by
-     *  decode is preferred.
-     */
-    void setPrefConfigTable(const PrefConfigTable&);
-
-    /**
-     *  Do not use a PrefConfigTable to determine the output config. This
-     *  is the default, so there is no need to call unless a PrefConfigTable
-     *  was previously set.
-     */
-    void resetPrefConfigTable() { fUsePrefTable = false; }
-#endif
+    void setPreserveSrcDepth(bool preserve) {
+        fPreserveSrcDepth = preserve;
+    }
 
     SkBitmap::Allocator* getAllocator() const { return fAllocator; }
     SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*);
@@ -354,27 +323,6 @@
         return DecodeStream(stream, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
     }
 
-#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CONFIG
-    bool decode(SkStream* stream, SkBitmap* bitmap, SkBitmap::Config pref, Mode mode) {
-        return this->decode(stream, bitmap, SkBitmapConfigToColorType(pref), mode);
-    }
-    bool decodeSubset(SkBitmap* bm, const SkIRect& subset, SkBitmap::Config pref) {
-        return this->decodeSubset(bm, subset, SkBitmapConfigToColorType(pref));
-    }
-    static bool DecodeFile(const char file[], SkBitmap* bitmap, SkBitmap::Config pref, Mode mode,
-                           Format* format = NULL) {
-        return DecodeFile(file, bitmap, SkBitmapConfigToColorType(pref), mode, format);
-    }
-    static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap,
-                             SkBitmap::Config pref, Mode mode, Format* format = NULL) {
-        return DecodeMemory(buffer, size, bitmap, SkBitmapConfigToColorType(pref), mode, format);
-    }
-    static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap, SkBitmap::Config pref,
-                             Mode mode, Format* format = NULL) {
-        return DecodeStream(stream, bitmap, SkBitmapConfigToColorType(pref), mode, format);
-    }
-#endif
-
 protected:
     // must be overridden in subclasses. This guy is called by decode(...)
     virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0;
@@ -473,10 +421,7 @@
     SkBitmap::Allocator*    fAllocator;
     int                     fSampleSize;
     SkColorType             fDefaultPref;   // use if fUsePrefTable is false
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-    PrefConfigTable         fPrefTable;     // use if fUsePrefTable is true
-    bool                    fUsePrefTable;
-#endif
+    bool                    fPreserveSrcDepth;
     bool                    fDitherImage;
     bool                    fSkipWritingZeroes;
     mutable bool            fShouldCancelDecode;
@@ -531,6 +476,7 @@
 DECLARE_DECODER_CREATOR(WEBPImageDecoder);
 DECLARE_DECODER_CREATOR(PKMImageDecoder);
 DECLARE_DECODER_CREATOR(KTXImageDecoder);
+DECLARE_DECODER_CREATOR(ASTCImageDecoder);
 
 // Typedefs to make registering decoder and formatter callbacks easier.
 // These have to be defined outside SkImageDecoder. :(
diff --git a/include/core/SkImageEncoder.h b/include/core/SkImageEncoder.h
index 754d5bb..4d4d2a8 100644
--- a/include/core/SkImageEncoder.h
+++ b/include/core/SkImageEncoder.h
@@ -100,6 +100,10 @@
 DECLARE_ENCODER_CREATOR(KTXImageEncoder);
 DECLARE_ENCODER_CREATOR(WEBPImageEncoder);
 
+#ifdef SK_BUILD_FOR_IOS
+DECLARE_ENCODER_CREATOR(PNGImageEncoder_IOS);
+#endif
+
 // Typedef to make registering encoder callback easier
 // This has to be defined outside SkImageEncoder. :(
 typedef SkTRegistry<SkImageEncoder*(*)(SkImageEncoder::Type)> SkImageEncoder_EncodeReg;
diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h
index 9cdd275..9f17f81 100644
--- a/include/core/SkImageFilter.h
+++ b/include/core/SkImageFilter.h
@@ -11,12 +11,13 @@
 #include "SkFlattenable.h"
 #include "SkMatrix.h"
 #include "SkRect.h"
+#include "SkTemplates.h"
 
 class SkBitmap;
 class SkColorFilter;
 class SkBaseDevice;
 struct SkIPoint;
-class GrEffectRef;
+class GrFragmentProcessor;
 class GrTexture;
 
 /**
@@ -48,15 +49,16 @@
         uint32_t fFlags;
     };
 
-    class SK_API Cache : public SkRefCnt {
+    // This cache maps from (filter's unique ID + CTM + clipBounds + src bitmap generation ID) to
+    // (result, offset).
+    class Cache : public SkRefCnt {
     public:
-        // By default, we cache only image filters with 2 or more children.
-        static Cache* Create(int minChildren = 2);
+        struct Key;
         virtual ~Cache() {}
-        virtual bool get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) = 0;
-        virtual void set(const SkImageFilter* key,
-                         const SkBitmap& result, const SkIPoint& offset) = 0;
-        virtual void remove(const SkImageFilter* key) = 0;
+        static Cache* Create(size_t maxBytes);
+        static Cache* Get();
+        virtual bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const = 0;
+        virtual void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) = 0;
     };
 
     class Context {
@@ -70,7 +72,7 @@
     private:
         SkMatrix fCTM;
         SkIRect  fClipBounds;
-        Cache*   fCache;
+        Cache* fCache;
     };
 
     class Proxy {
@@ -112,8 +114,8 @@
     /**
      *  Returns true if the filter can be processed on the GPU.  This is most
      *  often used for multi-pass effects, where intermediate results must be
-     *  rendered to textures.  For single-pass effects, use asNewEffect().
-     *  The default implementation returns asNewEffect(NULL, NULL, SkMatrix::I(),
+     *  rendered to textures.  For single-pass effects, use asFragmentProcessor().
+     *  The default implementation returns asFragmentProcessor(NULL, NULL, SkMatrix::I(),
      *  SkIRect()).
      */
     virtual bool canFilterImageGPU() const;
@@ -121,12 +123,12 @@
     /**
      *  Process this image filter on the GPU.  This is most often used for
      *  multi-pass effects, where intermediate results must be rendered to
-     *  textures.  For single-pass effects, use asNewEffect().  src is the
+     *  textures.  For single-pass effects, use asFragmentProcessor().  src is the
      *  source image for processing, as a texture-backed bitmap.  result is
      *  the destination bitmap, which should contain a texture-backed pixelref
      *  on success.  offset is the amount to translate the resulting image
      *  relative to the src when it is drawn. The default implementation does
-     *  single-pass processing using asNewEffect().
+     *  single-pass processing using asFragmentProcessor().
      */
     virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const Context&,
                                 SkBitmap* result, SkIPoint* offset) const;
@@ -170,7 +172,7 @@
     // Default impl returns union of all input bounds.
     virtual void computeFastBounds(const SkRect&, SkRect*) const;
 
-#ifdef SK_SUPPORT_GPU
+#if SK_SUPPORT_GPU
     /**
      * Wrap the given texture in a texture-backed SkBitmap.
      */
@@ -184,27 +186,47 @@
                            SkBitmap* result, SkIPoint* offset) const;
 #endif
 
-    /**
-     *  Set an external cache to be used for all image filter processing. This
-     *  will replace the default intra-frame cache.
-     */
-    static void SetExternalCache(Cache* cache);
-
-    /**
-     *  Returns the currently-set external cache, or NULL if none is set.
-     */
-    static Cache* GetExternalCache();
-
     SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
 
 protected:
-    SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL);
+    class Common {
+    public:
+        Common() {}
+        ~Common();
 
-    // Convenience constructor for 1-input filters.
-    explicit SkImageFilter(SkImageFilter* input, const CropRect* cropRect = NULL);
+        /**
+         *  Attempt to unflatten the cropRect and the expected number of input filters.
+         *  If any number of input filters is valid, pass -1.
+         *  If this fails (i.e. corrupt buffer or contents) then return false and common will
+         *  be left uninitialized.
+         *  If this returns true, then inputCount() is the number of found input filters, each
+         *  of which may be NULL or a valid imagefilter.
+         */
+        bool unflatten(SkReadBuffer&, int expectedInputs);
 
-    // Convenience constructor for 2-input filters.
-    SkImageFilter(SkImageFilter* input1, SkImageFilter* input2, const CropRect* cropRect = NULL);
+        const CropRect& cropRect() const { return fCropRect; }
+        int             inputCount() const { return fInputs.count(); }
+        SkImageFilter** inputs() const { return fInputs.get(); }
+        uint32_t        uniqueID() const { return fUniqueID; }
+
+        SkImageFilter*  getInput(int index) const { return fInputs[index]; }
+
+        // If the caller wants a copy of the inputs, call this and it will transfer ownership
+        // of the unflattened input filters to the caller. This is just a short-cut for copying
+        // the inputs, calling ref() on each, and then waiting for Common's destructor to call
+        // unref() on each.
+        void detachInputs(SkImageFilter** inputs);
+
+    private:
+        CropRect fCropRect;
+        // most filters accept at most 2 input-filters
+        SkAutoSTArray<2, SkImageFilter*> fInputs;
+        uint32_t fUniqueID;
+
+        void allocInputs(int count);
+    };
+
+    SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL, uint32_t uniqueID = 0);
 
     virtual ~SkImageFilter();
 
@@ -217,7 +239,7 @@
      */
     explicit SkImageFilter(int inputCount, SkReadBuffer& rb);
 
-    virtual void flatten(SkWriteBuffer& wb) const SK_OVERRIDE;
+    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     /**
      *  This is the virtual which should be overridden by the derived class
@@ -268,10 +290,10 @@
 
     /**
      *  Returns true if the filter can be expressed a single-pass
-     *  GrEffect, used to process this filter on the GPU, or false if
+     *  GrProcessor, used to process this filter on the GPU, or false if
      *  not.
      *
-     *  If effect is non-NULL, a new GrEffect instance is stored
+     *  If effect is non-NULL, a new GrProcessor instance is stored
      *  in it.  The caller assumes ownership of the stage, and it is up to the
      *  caller to unref it.
      *
@@ -281,16 +303,29 @@
      *  will be called with (NULL, NULL, SkMatrix::I()) to query for support,
      *  so returning "true" indicates support for all possible matrices.
      */
-    virtual bool asNewEffect(GrEffectRef** effect,
-                             GrTexture*,
-                             const SkMatrix& matrix,
-                             const SkIRect& bounds) const;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+                                     const SkIRect& bounds) const;
 
 private:
+    bool usesSrcInput() const { return fUsesSrcInput; }
+
     typedef SkFlattenable INHERITED;
     int fInputCount;
     SkImageFilter** fInputs;
+    bool fUsesSrcInput;
     CropRect fCropRect;
+    uint32_t fUniqueID; // Globally unique
 };
 
+/**
+ *  Helper to unflatten the common data, and return NULL if we fail.
+ */
+#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount)    \
+    Common localVar;                                                \
+    do {                                                            \
+        if (!localVar.unflatten(buffer, expectedCount)) {           \
+            return NULL;                                            \
+        }                                                           \
+    } while (0)
+
 #endif
diff --git a/include/core/SkImageGenerator.h b/include/core/SkImageGenerator.h
index 157bfdb..fc6b1b4 100644
--- a/include/core/SkImageGenerator.h
+++ b/include/core/SkImageGenerator.h
@@ -8,8 +8,8 @@
 #ifndef SkImageGenerator_DEFINED
 #define SkImageGenerator_DEFINED
 
-#include "SkImageInfo.h"
 #include "SkColor.h"
+#include "SkImageInfo.h"
 
 class SkBitmap;
 class SkData;
@@ -35,12 +35,6 @@
  */
 SK_API bool SkInstallDiscardablePixelRef(SkImageGenerator*, SkBitmap* destination);
 
-/**
- *  Purges all unlocked discardable memory in Skia's global
- *  discardable memory pool.
- */
-SK_API void SkPurgeGlobalDiscardableMemoryPool();
-
 
 /**
  *  An interface that allows a purgeable PixelRef (such as a
@@ -116,12 +110,29 @@
     bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
 #endif
 
+    /**
+     *  If planes or rowBytes is NULL or if any entry in planes is NULL or if any entry in rowBytes
+     *  is 0, this imagegenerator should output the sizes and return true if it can efficiently
+     *  return YUV planar data. If it cannot, it should return false. Note that either planes and
+     *  rowBytes are both fully defined and non NULL/non 0 or they are both NULL or have NULL or 0
+     *  entries only. Having only partial planes/rowBytes information is not supported.
+     *
+     *  If all planes and rowBytes entries are non NULL or non 0, then it should copy the
+     *  associated YUV data into those planes of memory supplied by the caller. It should validate
+     *  that the sizes match what it expected. If the sizes do not match, it should return false.
+     */
+    bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+                       SkYUVColorSpace* colorSpace);
+
 protected:
     virtual SkData* onRefEncodedData();
     virtual bool onGetInfo(SkImageInfo* info);
     virtual bool onGetPixels(const SkImageInfo& info,
                              void* pixels, size_t rowBytes,
                              SkPMColor ctable[], int* ctableCount);
+    virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]);
+    virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+                                 SkYUVColorSpace* colorSpace);
 };
 
 #endif  // SkImageGenerator_DEFINED
diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h
index b955433..7fedfa1 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -67,6 +67,10 @@
 
 /**
  *  Describes how to interpret the components of a pixel.
+ *
+ *  kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native"
+ *  form for skia's blitters. Use this if you don't have a swizzle preference
+ *  for 32bit pixels.
  */
 enum SkColorType {
     kUnknown_SkColorType,
@@ -120,39 +124,57 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
+ *  Return true if alphaType is supported by colorType. If there is a canonical
+ *  alphaType for this colorType, return it in canonical.
+ */
+bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
+                                  SkAlphaType* canonical = NULL);
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Describes the color space a YUV pixel.
+ */
+enum SkYUVColorSpace {
+    /** Standard JPEG color space. */
+    kJPEG_SkYUVColorSpace,
+    /** SDTV standard Rec. 601 color space. Uses "studio swing" [16, 235] color
+       range. See http://en.wikipedia.org/wiki/Rec._601 for details. */
+    kRec601_SkYUVColorSpace,
+
+    kLastEnum_SkYUVColorSpace = kRec601_SkYUVColorSpace
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
  *  Describe an image's dimensions and pixel type.
  */
 struct SkImageInfo {
-    int         fWidth;
-    int         fHeight;
-    SkColorType fColorType;
-    SkAlphaType fAlphaType;
+public:
+    SkImageInfo()
+        : fWidth(0)
+        , fHeight(0)
+        , fColorType(kUnknown_SkColorType)
+        , fAlphaType(kIgnore_SkAlphaType)
+    {}
 
     static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) {
-        SkImageInfo info = {
-            width, height, ct, at
-        };
-        return info;
+        return SkImageInfo(width, height, ct, at);
     }
 
     /**
      *  Sets colortype to the native ARGB32 type.
      */
     static SkImageInfo MakeN32(int width, int height, SkAlphaType at) {
-        SkImageInfo info = {
-            width, height, kN32_SkColorType, at
-        };
-        return info;
+        return SkImageInfo(width, height, kN32_SkColorType, at);
     }
 
     /**
      *  Sets colortype to the native ARGB32 type, and the alphatype to premul.
      */
     static SkImageInfo MakeN32Premul(int width, int height) {
-        SkImageInfo info = {
-            width, height, kN32_SkColorType, kPremul_SkAlphaType
-        };
-        return info;
+        return SkImageInfo(width, height, kN32_SkColorType, kPremul_SkAlphaType);
     }
 
     /**
@@ -163,24 +185,15 @@
     }
 
     static SkImageInfo MakeA8(int width, int height) {
-        SkImageInfo info = {
-            width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType
-        };
-        return info;
+        return SkImageInfo(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType);
     }
 
     static SkImageInfo MakeUnknown(int width, int height) {
-        SkImageInfo info = {
-            width, height, kUnknown_SkColorType, kIgnore_SkAlphaType
-        };
-        return info;
+        return SkImageInfo(width, height, kUnknown_SkColorType, kIgnore_SkAlphaType);
     }
 
     static SkImageInfo MakeUnknown() {
-        SkImageInfo info = {
-            0, 0, kUnknown_SkColorType, kIgnore_SkAlphaType
-        };
-        return info;
+        return SkImageInfo();
     }
 
     int width() const { return fWidth; }
@@ -204,6 +217,14 @@
         return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType);
     }
 
+    SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
+        return SkImageInfo::Make(fWidth, fHeight, fColorType, newAlphaType);
+    }
+    
+    SkImageInfo makeColorType(SkColorType newColorType) const {
+        return SkImageInfo::Make(fWidth, fHeight, newColorType, fAlphaType);
+    }
+    
     int bytesPerPixel() const {
         return SkColorTypeBytesPerPixel(fColorType);
     }
@@ -243,6 +264,24 @@
     }
 
     SkDEBUGCODE(void validate() const;)
+
+#ifdef SK_SUPPORT_LEGACY_PUBLIC_IMAGEINFO_FIELDS
+public:
+#else
+private:
+#endif
+    int         fWidth;
+    int         fHeight;
+    SkColorType fColorType;
+    SkAlphaType fAlphaType;
+
+private:
+    SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at)
+        : fWidth(width)
+        , fHeight(height)
+        , fColorType(ct)
+        , fAlphaType(at)
+    {}
 };
 
 #endif
diff --git a/include/core/SkInstCnt.h b/include/core/SkInstCnt.h
index 1839ee1..e4b43d1 100644
--- a/include/core/SkInstCnt.h
+++ b/include/core/SkInstCnt.h
@@ -73,9 +73,14 @@
             return gChildren;                                               \
         }                                                                   \
                                                                             \
+        static void create_mutex(SkMutex** mutex) {                         \
+            *mutex = SkNEW(SkMutex);                                        \
+        }                                                                   \
         static SkBaseMutex& GetChildrenMutex() {                            \
-            SK_DECLARE_STATIC_MUTEX(childrenMutex);                         \
-            return childrenMutex;                                           \
+            static SkMutex* childrenMutex;                                  \
+            SK_DECLARE_STATIC_ONCE(once);                                   \
+            SkOnce(&once, className::SkInstanceCountHelper::create_mutex, &childrenMutex);\
+            return *childrenMutex;                                          \
         }                                                                   \
                                                                             \
     } fInstanceCountHelper;                                                 \
diff --git a/include/core/SkMallocPixelRef.h b/include/core/SkMallocPixelRef.h
index ce35308..63ed19a 100644
--- a/include/core/SkMallocPixelRef.h
+++ b/include/core/SkMallocPixelRef.h
@@ -78,21 +78,18 @@
     class PRFactory : public SkPixelRefFactory {
     public:
         virtual SkPixelRef* create(const SkImageInfo&,
+                                   size_t rowBytes,
                                    SkColorTable*) SK_OVERRIDE;
     };
 
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMallocPixelRef)
-
 protected:
     // The ownPixels version of this constructor is deprecated.
     SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*,
                      bool ownPixels);
-    SkMallocPixelRef(SkReadBuffer& buffer);
     virtual ~SkMallocPixelRef();
 
     virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
     virtual void onUnlockPixels() SK_OVERRIDE;
-    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
 
 private:
diff --git a/include/core/SkMaskFilter.h b/include/core/SkMaskFilter.h
index 72f20af..026ef40 100644
--- a/include/core/SkMaskFilter.h
+++ b/include/core/SkMaskFilter.h
@@ -63,24 +63,22 @@
 
 #if SK_SUPPORT_GPU
     /**
-     *  Returns true if the filter can be expressed a single-pass GrEffect without requiring an
+     *  Returns true if the filter can be expressed a single-pass GrProcessor without requiring an
      *  explicit input mask. Per-pixel, the effect receives the incoming mask's coverage as
      *  the input color and outputs the filtered covereage value. This means that each pixel's
      *  filtered coverage must only depend on the unfiltered mask value for that pixel and not on
      *  surrounding values.
      *
-     * If effect is non-NULL, a new GrEffect instance is stored in it. The caller assumes ownership
-     * of the effect and must unref it.
+     * If effect is non-NULL, a new GrProcessor instance is stored in it. The caller assumes
+     * ownership of the effect and must unref it.
      */
-    virtual bool asNewEffect(GrEffectRef** effect,
-                             GrTexture*,
-                             const SkMatrix& ctm) const;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix& ctm) const;
 
     /**
-     *  If asNewEffect() fails the filter may be implemented on the GPU by a subclass overriding
-     *  filterMaskGPU (declared below). That code path requires constructing a src mask as input.
-     *  Since that is a potentially expensive operation, the subclass must also override this
-     *  function to indicate whether filterTextureMaskGPU would succeeed if the mask were to be
+     *  If asFragmentProcessor() fails the filter may be implemented on the GPU by a subclass
+     *  overriding filterMaskGPU (declared below). That code path requires constructing a src mask
+     *  as input. Since that is a potentially expensive operation, the subclass must also override
+     *  this function to indicate whether filterTextureMaskGPU would succeeed if the mask were to be
      *  created.
      *
      *  'maskRect' returns the device space portion of the mask that the filter needs. The mask
@@ -155,8 +153,10 @@
 
 protected:
     SkMaskFilter() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     // empty for now, but lets get our subclass to remember to init us for the future
     SkMaskFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     enum FilterReturn {
         kFalse_FilterReturn,
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h
index 84d1a87..a65cd19 100644
--- a/include/core/SkMatrix.h
+++ b/include/core/SkMatrix.h
@@ -10,6 +10,7 @@
 #ifndef SkMatrix_DEFINED
 #define SkMatrix_DEFINED
 
+#include "SkDynamicAnnotations.h"
 #include "SkRect.h"
 
 class SkString;
@@ -59,6 +60,10 @@
         return this->getType() == 0;
     }
 
+    bool isScaleTranslate() const {
+        return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
+    }
+
     /** Returns true if will map a rectangle to another rectangle. This can be
         true if the matrix is identity, scale-only, or rotates a multiple of
         90 degrees.
@@ -80,12 +85,12 @@
                         kPerspective_Mask);
     }
 
-    /** Returns true if the matrix contains only translation, rotation or uniform scale
+    /** Returns true if the matrix contains only translation, rotation/reflection or uniform scale
         Returns false if other transformation types are included or is degenerate
      */
     bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const;
 
-    /** Returns true if the matrix contains only translation, rotation or scale
+    /** Returns true if the matrix contains only translation, rotation/reflection or scale
         (non-uniform scale is allowed).
         Returns false if other transformation types are included or is degenerate
      */
@@ -348,7 +353,7 @@
     bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const {
         // Allow the trivial case to be inlined.
         if (this->isIdentity()) {
-            if (NULL != inverse) {
+            if (inverse) {
                 inverse->reset();
             }
             return true;
@@ -643,7 +648,7 @@
     };
 
     SkScalar         fMat[9];
-    mutable uint32_t fTypeMask;
+    mutable SkTRacy<uint32_t> fTypeMask;
 
     uint8_t computeTypeMask() const;
     uint8_t computePerspectiveTypeMask() const;
@@ -664,7 +669,7 @@
     void clearTypeMask(int mask) {
         // only allow a valid mask
         SkASSERT((mask & kAllMasks) == mask);
-        fTypeMask &= ~mask;
+        fTypeMask = fTypeMask & ~mask;
     }
 
     TypeMask getPerspectiveTypeMaskOnly() const {
diff --git a/include/core/SkMetaData.h b/include/core/SkMetaData.h
index 5db437c..c8ca7f1 100644
--- a/include/core/SkMetaData.h
+++ b/include/core/SkMetaData.h
@@ -81,7 +81,7 @@
     bool hasData(const char name[], const void* data, size_t byteCount) const {
         size_t len;
         const void* ptr = this->findData(name, &len);
-        return NULL != ptr && len == byteCount && !memcmp(ptr, data, len);
+        return ptr && len == byteCount && !memcmp(ptr, data, len);
     }
 
     void setS32(const char name[], int32_t value);
diff --git a/include/core/SkMultiPictureDraw.h b/include/core/SkMultiPictureDraw.h
new file mode 100644
index 0000000..d8d9cb7
--- /dev/null
+++ b/include/core/SkMultiPictureDraw.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkMultiPictureDraw_DEFINED
+#define SkMultiPictureDraw_DEFINED
+
+#include "SkMatrix.h"
+#include "SkTDArray.h"
+
+class SkCanvas;
+class SkPaint;
+class SkPicture;
+
+/** \class SkMultiPictureDraw
+
+    The MultiPictureDraw object accepts several picture/canvas pairs and
+    then attempts to optimally draw the pictures into the canvases, sharing
+    as many resources as possible.
+*/
+class SK_API SkMultiPictureDraw {
+public:
+    /**
+     *  Create an object to optimize the drawing of multiple pictures.
+     *  @param reserve Hint for the number of add calls expected to be issued
+     */
+    SkMultiPictureDraw(int reserve = 0);
+    ~SkMultiPictureDraw() { this->reset(); }
+
+    /**
+     *  Add a canvas/picture pair for later rendering.
+     *  @param canvas   the canvas in which to draw picture
+     *  @param picture  the picture to draw into canvas
+     *  @param matrix   if non-NULL, applied to the CTM when drawing
+     *  @param paint    if non-NULL, draw picture to a temporary buffer
+     *                  and then apply the paint when the result is drawn
+     */
+    void add(SkCanvas* canvas,
+             const SkPicture* picture,
+             const SkMatrix* matrix = NULL, 
+             const SkPaint* paint = NULL);
+
+    /**
+     *  Perform all the previously added draws. This will reset the state
+     *  of this object.
+     */
+    void draw();
+
+    /**
+     *  Abandon all buffered draws and reset to the initial state.
+     */
+    void reset();
+
+private:
+    struct DrawData {
+        SkCanvas*        canvas;  // reffed
+        const SkPicture* picture; // reffed
+        SkMatrix         matrix;
+        SkPaint*         paint;   // owned
+    };
+
+    SkTDArray<DrawData> fDrawData;
+};
+
+#endif
diff --git a/include/core/SkOSFile.h b/include/core/SkOSFile.h
index b75fe6c..69a74df 100644
--- a/include/core/SkOSFile.h
+++ b/include/core/SkOSFile.h
@@ -77,8 +77,10 @@
  */
 int     sk_fileno(SkFILE* f);
 
-// Returns true if something (file, directory, ???) exists at this path.
-bool    sk_exists(const char *path);
+/** Returns true if something (file, directory, ???) exists at this path,
+ *  and has the specified access flags.
+ */
+bool    sk_exists(const char *path, SkFILE_Flags = (SkFILE_Flags)0);
 
 // Returns true if a directory exists at this path.
 bool    sk_isdir(const char *path);
@@ -118,23 +120,10 @@
     };
 };
 
-class SkUTF16_Str {
-public:
-    SkUTF16_Str(const char src[]);
-    ~SkUTF16_Str()
-    {
-        sk_free(fStr);
-    }
-    const uint16_t* get() const { return fStr; }
-
-private:
-    uint16_t*   fStr;
-};
-
 /**
  *  Functions for modifying SkStrings which represent paths on the filesystem.
  */
-class SkOSPath {
+class SkOSPath   {
 public:
     /**
      * Assembles rootPath and relativePath into a single path, like this:
@@ -144,7 +133,7 @@
      *
      * Uses SkPATH_SEPARATOR, to work on all platforms.
      */
-    static SkString SkPathJoin(const char *rootPath, const char *relativePath);
+    static SkString Join(const char* rootPath, const char* relativePath);
 
     /**
      *  Return the name of the file, ignoring the directory structure.
@@ -154,6 +143,18 @@
      *  @return SkString The basename of the file - anything beyond the
      *      final slash, or the full name if there is no slash.
      */
-    static SkString SkBasename(const char* fullPath);
+    static SkString Basename(const char* fullPath);
+
+    /**
+     *  Given a qualified file name returns the directory.
+     *  Behaves like python's os.path.dirname. If the fullPath is
+     *  /dir/subdir/ the return will be /dir/subdir/
+     *  @param fullPath Full path to the file.
+     *  @return SkString The dir containing the file - anything preceding the
+     *      final slash, or the full name if ending in a slash.
+     */
+    static SkString Dirname(const char* fullPath);
+    
 };
+
 #endif
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index f766ca1..9c47f1d 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -15,9 +15,6 @@
 #include "SkDrawLooper.h"
 #include "SkMatrix.h"
 #include "SkXfermode.h"
-#ifdef SK_BUILD_FOR_ANDROID
-#include "SkPaintOptionsAndroid.h"
-#endif
 
 class SkAnnotation;
 class SkAutoGlyphCache;
@@ -59,6 +56,10 @@
 
     SkPaint& operator=(const SkPaint&);
 
+    /** operator== may give false negatives: two paints that draw equivalently
+        may return false.  It will never give false positives: two paints that
+        are not equivalent always return false.
+    */
     SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);
     friend bool operator!=(const SkPaint& a, const SkPaint& b) {
         return !(a == b);
@@ -89,7 +90,7 @@
     };
 
     Hinting getHinting() const {
-        return static_cast<Hinting>(fHinting);
+        return static_cast<Hinting>(fBitfields.fHinting);
     }
 
     void setHinting(Hinting hintingLevel);
@@ -121,7 +122,7 @@
     /** Return the paint's flags. Use the Flag enum to test flag values.
         @return the paint's flags (see enums ending in _Flag for bit masks)
     */
-    uint32_t getFlags() const { return fFlags; }
+    uint32_t getFlags() const { return fBitfields.fFlags; }
 
     /** Set the paint's flags. Use the Flag enum to specific flag values.
         @param flags    The new flag bits for the paint (see Flags enum)
@@ -302,7 +303,9 @@
      *  Return the filter level. This affects the quality (and performance) of
      *  drawing scaled images.
      */
-    FilterLevel getFilterLevel() const { return (FilterLevel)fFilterLevel; }
+    FilterLevel getFilterLevel() const {
+      return (FilterLevel)fBitfields.fFilterLevel;
+    }
 
     /**
      *  Set the filter level. This affects the quality (and performance) of
@@ -350,7 +353,7 @@
         kFill_Style).
         @return the paint's Style
     */
-    Style getStyle() const { return (Style)fStyle; }
+    Style getStyle() const { return (Style)fBitfields.fStyle; }
 
     /** Set the paint's style, used for controlling how primitives'
         geometries are interpreted (except for drawBitmap, which always assumes
@@ -456,7 +459,7 @@
         @return the line cap style for the paint, used whenever the paint's
                 style is Stroke or StrokeAndFill.
     */
-    Cap getStrokeCap() const { return (Cap)fCapType; }
+    Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
 
     /** Set the paint's stroke cap type.
         @param cap  set the paint's line cap style, used whenever the paint's
@@ -468,7 +471,7 @@
         @return the paint's line join style, used whenever the paint's style is
                 Stroke or StrokeAndFill.
     */
-    Join getStrokeJoin() const { return (Join)fJoinType; }
+    Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
 
     /** Set the paint's stroke join type.
         @param join set the paint's line join style, used whenever the paint's
@@ -685,7 +688,7 @@
     /** Return the paint's Align value for drawing text.
         @return the paint's Align value for drawing text.
     */
-    Align   getTextAlign() const { return (Align)fTextAlign; }
+    Align   getTextAlign() const { return (Align)fBitfields.fTextAlign; }
 
     /** Set the paint's text alignment.
         @param align set the paint's Align value for drawing text.
@@ -738,7 +741,9 @@
         kGlyphID_TextEncoding   //!< the text parameters are glyph indices
     };
 
-    TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; }
+    TextEncoding getTextEncoding() const {
+      return (TextEncoding)fBitfields.fTextEncoding;
+    }
 
     void setTextEncoding(TextEncoding encoding);
 
@@ -857,12 +862,9 @@
      *  @param length       Number of bytes of text to measure
      *  @param bounds       If not NULL, returns the bounds of the text,
      *                      relative to (0, 0).
-     *  @param scale        If not 0, return width as if the canvas were scaled
-     *                      by this value
      *  @return             The advance width of the text
      */
-    SkScalar measureText(const void* text, size_t length,
-                         SkRect* bounds, SkScalar scale = 0) const;
+    SkScalar measureText(const void* text, size_t length, SkRect* bounds) const;
 
     /** Return the width of the text. This will return the vertical measure
      *  if isVerticalText() is true, in which case the returned value should
@@ -873,7 +875,7 @@
      *  @return         The advance width of the text
      */
     SkScalar measureText(const void* text, size_t length) const {
-        return this->measureText(text, length, NULL, 0);
+        return this->measureText(text, length, NULL);
     }
 
     /** Specify the direction the text buffer should be processed in breakText()
@@ -937,15 +939,6 @@
 #ifdef SK_BUILD_FOR_ANDROID
     uint32_t getGenerationID() const;
     void setGenerationID(uint32_t generationID);
-
-    /** Returns the base glyph count for the strike associated with this paint
-    */
-    unsigned getBaseGlyphCount(SkUnichar text) const;
-
-    const SkPaintOptionsAndroid& getPaintOptionsAndroid() const {
-        return fPaintOptionsAndroid;
-    }
-    void setPaintOptionsAndroid(const SkPaintOptionsAndroid& options);
 #endif
 
     // returns true if the paint's settings (e.g. xfermode + alpha) resolve to
@@ -1066,14 +1059,11 @@
             unsigned        fHinting : 2;
             unsigned        fFilterLevel : 2;
             //unsigned      fFreeBits : 2;
-        };
-        uint32_t fBitfields;
+        } fBitfields;
+        uint32_t fBitfieldsUInt;
     };
     uint32_t fDirtyBits;
 
-    uint32_t getBitfields() const { return fBitfields; }
-    void setBitfields(uint32_t bitfields);
-
     SkDrawCacheProc    getDrawCacheProc() const;
     SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
                                            bool needFullMetrics) const;
@@ -1117,9 +1107,6 @@
 
     static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM);
 
-    bool tooBigToUseCache() const;
-    bool tooBigToUseCache(const SkMatrix& ctm) const;
-
     // Set flags/hinting/textSize up to use for drawing text as paths.
     // Returns scale factor to restore the original textSize, since will will
     // have change it to kCanonicalTextSizeForPaths.
@@ -1139,12 +1126,13 @@
     friend class SkPDFDevice;
     friend class GrBitmapTextContext;
     friend class GrDistanceFieldTextContext;
+    friend class GrStencilAndCoverTextContext;
+    friend class GrPathRendering;
+    friend class GrGLPathRendering;
     friend class SkTextToPathIter;
     friend class SkCanonicalizePaint;
 
 #ifdef SK_BUILD_FOR_ANDROID
-    SkPaintOptionsAndroid fPaintOptionsAndroid;
-
     // In order for the == operator to work properly this must be the last field
     // in the struct so that we can do a memcmp to this field's offset.
     uint32_t        fGenerationID;
diff --git a/include/core/SkPaintOptionsAndroid.h b/include/core/SkPaintOptionsAndroid.h
deleted file mode 100644
index ab84ec0..0000000
--- a/include/core/SkPaintOptionsAndroid.h
+++ /dev/null
@@ -1,130 +0,0 @@
-
-/*
- * Copyright 2012 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SkPaintOptionsAndroid_DEFINED
-#define SkPaintOptionsAndroid_DEFINED
-
-#include "SkTypes.h"
-#include "SkString.h"
-
-class SkReadBuffer;
-class SkWriteBuffer;
-
-/** \class SkLanguage
-
-    The SkLanguage class represents a human written language, and is used by
-    text draw operations to determine which glyph to draw when drawing
-    characters with variants (ie Han-derived characters).
-*/
-class SkLanguage {
-public:
-    SkLanguage() { }
-    SkLanguage(const SkString& tag) : fTag(tag) { }
-    SkLanguage(const char* tag) : fTag(tag) { }
-    SkLanguage(const char* tag, size_t len) : fTag(tag, len) { }
-    SkLanguage(const SkLanguage& b) : fTag(b.fTag) { }
-
-    /** Gets a BCP 47 language identifier for this SkLanguage.
-        @return a BCP 47 language identifier representing this language
-    */
-    const SkString& getTag() const { return fTag; }
-
-    /** Performs BCP 47 fallback to return an SkLanguage one step more general.
-        @return an SkLanguage one step more general
-    */
-    SkLanguage getParent() const;
-
-    bool operator==(const SkLanguage& b) const {
-        return fTag == b.fTag;
-    }
-    bool operator!=(const SkLanguage& b) const {
-        return fTag != b.fTag;
-    }
-    SkLanguage& operator=(const SkLanguage& b) {
-        fTag = b.fTag;
-        return *this;
-    }
-
-private:
-    //! BCP 47 language identifier
-    SkString fTag;
-};
-
-class SkPaintOptionsAndroid {
-public:
-    SkPaintOptionsAndroid() {
-        fFontVariant = kDefault_Variant;
-        fUseFontFallbacks = false;
-    }
-
-    SkPaintOptionsAndroid& operator=(const SkPaintOptionsAndroid& b) {
-        fLanguage = b.fLanguage;
-        fFontVariant = b.fFontVariant;
-        fUseFontFallbacks = b.fUseFontFallbacks;
-        return *this;
-    }
-
-    bool operator==(const SkPaintOptionsAndroid& b) const {
-        return !(*this != b);
-    }
-
-    bool operator!=(const SkPaintOptionsAndroid& b) const {
-        return fLanguage != b.fLanguage ||
-               fFontVariant != b.fFontVariant ||
-               fUseFontFallbacks != b.fUseFontFallbacks;
-    }
-
-    void flatten(SkWriteBuffer&) const;
-    void unflatten(SkReadBuffer&);
-
-    /** Return the paint's language value used for drawing text.
-        @return the paint's language value used for drawing text.
-    */
-    const SkLanguage& getLanguage() const { return fLanguage; }
-
-    /** Set the paint's language value used for drawing text.
-        @param language set the paint's language value for drawing text.
-    */
-    void setLanguage(const SkLanguage& language) { fLanguage = language; }
-    void setLanguage(const char* languageTag) { fLanguage = SkLanguage(languageTag); }
-
-
-    enum FontVariant {
-       kDefault_Variant = 0x01,
-       kCompact_Variant = 0x02,
-       kElegant_Variant = 0x04,
-       kLast_Variant = kElegant_Variant,
-    };
-
-    /** Return the font variant
-        @return the font variant used by this paint object
-    */
-    FontVariant getFontVariant() const { return fFontVariant; }
-
-    /** Set the font variant
-      @param fontVariant set the paint's font variant for choosing fonts
-    */
-    void setFontVariant(FontVariant fontVariant) {
-        SkASSERT((unsigned)fontVariant <= kLast_Variant);
-        fFontVariant = fontVariant;
-    }
-
-    bool isUsingFontFallbacks() const { return fUseFontFallbacks; }
-
-    void setUseFontFallbacks(bool useFontFallbacks) {
-        fUseFontFallbacks = useFontFallbacks;
-    }
-
-private:
-    SkLanguage fLanguage;
-    FontVariant fFontVariant;
-    bool fUseFontFallbacks;
-};
-
-#endif // #ifndef SkPaintOptionsAndroid_DEFINED
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index d78cd88..57da959 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -21,6 +21,7 @@
 class SkAutoPathBoundsUpdate;
 class SkString;
 class SkRRect;
+class SkWStream;
 
 /** \class SkPath
 
@@ -930,8 +931,9 @@
      */
     bool contains(SkScalar x, SkScalar y) const;
 
-    void dump(bool forceClose, const char title[] = NULL) const;
+    void dump(SkWStream* , bool forceClose, bool dumpAsHex) const;
     void dump() const;
+    void dumpHex() const;
 
     /**
      *  Write the path to the buffer, and return the number of bytes written.
diff --git a/include/core/SkPathEffect.h b/include/core/SkPathEffect.h
index 5620253..454614a 100644
--- a/include/core/SkPathEffect.h
+++ b/include/core/SkPathEffect.h
@@ -135,7 +135,9 @@
 
 protected:
     SkPathEffect() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     // illegal
@@ -157,7 +159,10 @@
 
 protected:
     SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkPairPathEffect(SkReadBuffer&);
+#endif
+
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     // these are visible to our subclasses
@@ -191,7 +196,10 @@
 protected:
     SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
         : INHERITED(outer, inner) {}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkComposePathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     // illegal
@@ -225,7 +233,10 @@
 protected:
     SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
         : INHERITED(first, second) {}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkSumPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     // illegal
diff --git a/include/core/SkPathRef.h b/include/core/SkPathRef.h
index 47a69b7..0b661b4 100644
--- a/include/core/SkPathRef.h
+++ b/include/core/SkPathRef.h
@@ -9,6 +9,7 @@
 #ifndef SkPathRef_DEFINED
 #define SkPathRef_DEFINED
 
+#include "SkDynamicAnnotations.h"
 #include "SkMatrix.h"
 #include "SkPoint.h"
 #include "SkRect.h"
@@ -143,7 +144,7 @@
      *              fact ovals can report false.
      */
     bool isOval(SkRect* rect) const {
-        if (fIsOval && NULL != rect) {
+        if (fIsOval && rect) {
             *rect = getBounds();
         }
 
@@ -290,9 +291,11 @@
     // called, if dirty, by getBounds()
     void computeBounds() const {
         SkDEBUGCODE(this->validate();)
-        SkASSERT(fBoundsIsDirty);
+        // TODO(mtklein): remove fBoundsIsDirty and fIsFinite,
+        // using an inverted rect instead of fBoundsIsDirty and always recalculating fIsFinite.
+        //SkASSERT(fBoundsIsDirty);
 
-        fIsFinite = ComputePtBounds(&fBounds, *this);
+        fIsFinite = ComputePtBounds(fBounds.get(), *this);
         fBoundsIsDirty = false;
     }
 
@@ -300,7 +303,7 @@
         SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom);
         fBounds = rect;
         fBoundsIsDirty = false;
-        fIsFinite = fBounds.isFinite();
+        fIsFinite = fBounds->isFinite();
     }
 
     /** Makes additional room but does not change the counts or change the genID */
@@ -432,11 +435,12 @@
         kMinSize = 256,
     };
 
-    mutable SkRect      fBounds;
-    uint8_t             fSegmentMask;
-    mutable uint8_t     fBoundsIsDirty;
-    mutable SkBool8     fIsFinite;    // only meaningful if bounds are valid
-    mutable SkBool8     fIsOval;
+    mutable SkTRacyReffable<SkRect> fBounds;
+    mutable SkTRacy<uint8_t>        fBoundsIsDirty;
+    mutable SkTRacy<SkBool8>        fIsFinite;    // only meaningful if bounds are valid
+
+    SkBool8  fIsOval;
+    uint8_t  fSegmentMask;
 
     SkPoint*            fPoints; // points to begining of the allocation
     uint8_t*            fVerbs; // points just past the end of the allocation (verbs grow backwards)
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index 7b38230..d8aced1 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -11,25 +11,27 @@
 #define SkPicture_DEFINED
 
 #include "SkBitmap.h"
+#include "SkDrawPictureCallback.h"
 #include "SkImageDecoder.h"
 #include "SkRefCnt.h"
+#include "SkTDArray.h"
 
 #if SK_SUPPORT_GPU
 class GrContext;
 #endif
 
-class SkBBHFactory;
 class SkBBoxHierarchy;
 class SkCanvas;
-class SkDrawPictureCallback;
 class SkData;
-class SkPicturePlayback;
+class SkPictureData;
 class SkPictureRecord;
 class SkStream;
 class SkWStream;
 
 struct SkPictInfo;
 
+class SkRecord;
+
 /** \class SkPicture
 
     The SkPicture class records the drawing commands made to a canvas, to
@@ -60,23 +62,11 @@
         typedef SkRefCnt INHERITED;
     };
 
-    SkPicture();
-    /** Make a copy of the contents of src. If src records more drawing after
-        this call, those elements will not appear in this picture.
-    */
-    SkPicture(const SkPicture& src);
+    /**  PRIVATE / EXPERIMENTAL -- do not call */
+    void EXPERIMENTAL_addAccelData(const AccelData*) const;
 
     /**  PRIVATE / EXPERIMENTAL -- do not call */
-    void EXPERIMENTAL_addAccelData(const AccelData* data) const {
-        SkRefCnt_SafeAssign(fAccelData, data);
-    }
-    /**  PRIVATE / EXPERIMENTAL -- do not call */
-    const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key key) const {
-        if (NULL != fAccelData && fAccelData->getKey() == key) {
-            return fAccelData;
-        }
-        return NULL;
-    }
+    const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key) const;
 
     /**
      *  Function signature defining a function that sets up an SkBitmap from encoded data. On
@@ -114,41 +104,38 @@
 
     virtual ~SkPicture();
 
-    /**
-     *  Swap the contents of the two pictures. Guaranteed to succeed.
-     */
-    void swap(SkPicture& other);
-
+#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
     /**
      *  Creates a thread-safe clone of the picture that is ready for playback.
      */
     SkPicture* clone() const;
+#endif
 
-    /**
-     * Creates multiple thread-safe clones of this picture that are ready for
-     * playback. The resulting clones are stored in the provided array of
-     * SkPictures.
-     */
-    void clone(SkPicture* pictures, int count) const;
-
-    /** Replays the drawing commands on the specified canvas.
+    /** Replays the drawing commands on the specified canvas. Note that
+        this has the effect of unfurling this picture into the destination
+        canvas. Using the SkCanvas::drawPicture entry point gives the destination
+        canvas the option of just taking a ref.
         @param canvas the canvas receiving the drawing commands.
+        @param callback a callback that allows interruption of playback
     */
-    void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL) const;
+    void playback(SkCanvas* canvas, SkDrawPictureCallback* = NULL) const;
 
-    /** Return the width of the picture's recording canvas. This
-        value reflects what was passed to setSize(), and does not necessarily
-        reflect the bounds of what has been recorded into the picture.
-        @return the width of the picture's recording canvas
-    */
-    int width() const { return fWidth; }
+#ifdef SK_LEGACY_PICTURE_DRAW_API
+    void draw(SkCanvas* canvas, SkDrawPictureCallback* callback = NULL) const {
+        this->playback(canvas, callback);
+    }
+#endif
 
-    /** Return the height of the picture's recording canvas. This
-        value reflects what was passed to setSize(), and does not necessarily
-        reflect the bounds of what has been recorded into the picture.
-        @return the height of the picture's recording canvas
+#ifdef SK_LEGACY_PICTURE_SIZE_API
+    int width() const  { return SkScalarCeilToInt(fCullWidth); }
+    int height() const { return SkScalarCeilToInt(fCullHeight); }
+#endif
+
+    /** Return the cull rect used when creating this picture: { 0, 0, cullWidth, cullHeight }.
+        It does not necessarily reflect the bounds of what has been recorded into the picture.
+        @return the cull rect used to create this picture
     */
-    int height() const { return fHeight; }
+    const SkRect cullRect() const { return SkRect::MakeWH(fCullWidth, fCullHeight); }
 
     /** Return a non-zero, unique value representing the picture. This call is
         only valid when not recording. Between a beginRecording/endRecording
@@ -184,19 +171,9 @@
     /**
      * Returns true if any bitmaps may be produced when this SkPicture
      * is replayed.
-     * Returns false if called while still recording.
      */
     bool willPlayBackBitmaps() const;
 
-#ifdef SK_BUILD_FOR_ANDROID
-    /** Signals that the caller is prematurely done replaying the drawing
-        commands. This can be called from a canvas virtual while the picture
-        is drawing. Has no effect if the picture is not drawing.
-        @deprecated preserving for legacy purposes
-    */
-    void abortPlayback();
-#endif
-
     /** Return true if the SkStream/Buffer represents a serialized picture, and
         fills out SkPictInfo. After this function returns, the data source is not
         rewound so it will have to be manually reset before passing to
@@ -206,7 +183,7 @@
         If false is returned, SkPictInfo is unmodified.
     */
     static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*);
-    static bool InternalOnly_BufferIsSKP(SkReadBuffer&, SkPictInfo*);
+    static bool InternalOnly_BufferIsSKP(SkReadBuffer*, SkPictInfo*);
 
     /** Return true if the picture is suitable for rendering on the GPU.
      */
@@ -215,7 +192,26 @@
     bool suitableForGpuRasterization(GrContext*, const char ** = NULL) const;
 #endif
 
-protected:
+    class DeletionListener : public SkRefCnt {
+    public:
+        virtual void onDeletion(uint32_t pictureID) = 0;
+    };
+
+    // Takes ref on listener.
+    void addDeletionListener(DeletionListener* listener) const;
+
+    /** Return the approximate number of operations in this picture.  This
+     *  number may be greater or less than the number of SkCanvas calls
+     *  recorded: some calls may be recorded as more than one operation, or some
+     *  calls may be optimized away.
+     */
+    int approximateOpCount() const;
+
+    /** Return true if this picture contains text.
+     */
+    bool hasText() const;
+
+private:
     // V2 : adds SkPixelRef's generation ID.
     // V3 : PictInfo tag at beginning, and EOF tag at the end
     // V4 : move SkPictInfo to be the header
@@ -245,97 +241,91 @@
     // V26: Removed boolean from SkColorShader for inheriting color from SkPaint.
     // V27: Remove SkUnitMapper from gradients (and skia).
     // V28: No longer call bitmap::flatten inside SkWriteBuffer::writeBitmap.
+    // V29: Removed SaveFlags parameter from save().
+    // V30: Remove redundant SkMatrix from SkLocalMatrixShader.
+    // V31: Add a serialized UniqueID to SkImageFilter.
+    // V32: Removed SkPaintOptionsAndroid from SkPaint
+    // V33: Serialize only public API of effects.
+    // V34: Add SkTextBlob serialization.
+    // V35: Store SkRect (rather then width & height) in header
 
     // Note: If the picture version needs to be increased then please follow the
     // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
 
     // Only SKPs within the min/current picture version range (inclusive) can be read.
     static const uint32_t MIN_PICTURE_VERSION = 19;
-    static const uint32_t CURRENT_PICTURE_VERSION = 28;
+    static const uint32_t CURRENT_PICTURE_VERSION = 35;
 
     mutable uint32_t      fUniqueID;
 
-    // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
-    // install their own SkPicturePlayback-derived players,SkPictureRecord-derived
-    // recorders and set the picture size
-    SkPicturePlayback*    fPlayback;
-    int                   fWidth, fHeight;
-    mutable const AccelData* fAccelData;
+    // TODO: make SkPictureData const when clone method goes away
+    SkAutoTDelete<SkPictureData> fData;
+    const SkScalar                        fCullWidth;
+    const SkScalar                        fCullHeight;
+    mutable SkAutoTUnref<const AccelData> fAccelData;
+
+    mutable SkTDArray<DeletionListener*> fDeletionListeners;  // pointers are refed
 
     void needsNewGenID() { fUniqueID = SK_InvalidGenID; }
+    void callDeletionListeners();
 
-    // Create a new SkPicture from an existing SkPicturePlayback. Ref count of
-    // playback is unchanged.
-    SkPicture(SkPicturePlayback*, int width, int height);
+    // Create a new SkPicture from an existing SkPictureData. The new picture
+    // takes ownership of 'data'.
+    SkPicture(SkPictureData* data, SkScalar width, SkScalar height);
 
-    SkPicture(int width, int height, const SkPictureRecord& record, bool deepCopyOps);
-
-private:
-    static void WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size);
-    static void WriteTagSize(SkWStream* stream, uint32_t tag, size_t size);
+    SkPicture(SkScalar width, SkScalar height, const SkPictureRecord& record, bool deepCopyOps);
 
     // An OperationList encapsulates a set of operation offsets into the picture byte
     // stream along with the CTMs needed for those operation.
     class OperationList : ::SkNoncopyable {
     public:
-        virtual ~OperationList() {}
-
-        // If valid returns false then there is no optimization data
-        // present. All the draw operations need to be issued.
-        virtual bool valid() const { return false; }
-
         // The following three entry points should only be accessed if
         // 'valid' returns true.
-        virtual int numOps() const { SkASSERT(false); return 0; };
+        int numOps() const { return fOps.count(); }
         // The offset in the picture of the operation to execute.
-        virtual uint32_t offset(int index) const { SkASSERT(false); return 0; };
+        uint32_t offset(int index) const;
         // The CTM that must be installed for the operation to behave correctly
-        virtual const SkMatrix& matrix(int index) const { SkASSERT(false); return SkMatrix::I(); }
+        const SkMatrix& matrix(int index) const;
 
-        static const OperationList& InvalidList();
+        SkTDArray<void*> fOps;
     };
 
-    /** PRIVATE / EXPERIMENTAL -- do not call
-        Return the operations required to render the content inside 'queryRect'.
-    */
-    const OperationList& EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) const;
-
-    /** PRIVATE / EXPERIMENTAL -- do not call
-        Return the ID of the operation currently being executed when playing
-        back. 0 indicates no call is active.
-    */
-    size_t EXPERIMENTAL_curOpID() const;
-
     void createHeader(SkPictInfo* info) const;
     static bool IsValidPictInfo(const SkPictInfo& info);
 
-    friend class SkFlatPicture;
-    friend class SkPicturePlayback;
-    friend class SkPictureRecorder; // just for SkPicture-based constructor
-    friend class SkGpuDevice;
-    friend class GrGatherCanvas;
-    friend class GrGatherDevice;
-    friend class SkDebugCanvas;
+    friend class SkPictureData;                // to access OperationList
+    friend class SkPictureRecorder;            // just for SkPicture-based constructor
+    friend class SkGpuDevice;                  // for fData access
+    friend class GrLayerHoister;               // access to fRecord
+    friend class CollectLayers;                // access to fRecord
+    friend class SkPicturePlayback;            // to get fData & OperationList
+    friend class SkPictureReplacementPlayback; // to access OperationList
 
     typedef SkRefCnt INHERITED;
-};
 
-/**
- *  Subclasses of this can be passed to canvas.drawPicture. During the drawing
- *  of the picture, this callback will periodically be invoked. If its
- *  abortDrawing() returns true, then picture playback will be interrupted.
- *
- *  The resulting drawing is undefined, as there is no guarantee how often the
- *  callback will be invoked. If the abort happens inside some level of nested
- *  calls to save(), restore will automatically be called to return the state
- *  to the same level it was before the drawPicture call was made.
- */
-class SK_API SkDrawPictureCallback {
-public:
-    SkDrawPictureCallback() {}
-    virtual ~SkDrawPictureCallback() {}
+    // Takes ownership of the SkRecord, refs the (optional) BBH.
+    SkPicture(SkScalar width, SkScalar height, SkRecord*, SkBBoxHierarchy*);
+    // Return as a new SkPicture that's backed by SkRecord.
+    static SkPicture* Forwardport(const SkPicture&);
 
-    virtual bool abortDrawing() = 0;
+    SkAutoTDelete<SkRecord>       fRecord;
+    SkAutoTUnref<SkBBoxHierarchy> fBBH;
+
+    struct PathCounter;
+
+    struct Analysis {
+        Analysis() {}  // Only used by SkPictureData codepath.
+        explicit Analysis(const SkRecord&);
+
+        bool suitableForGpuRasterization(const char** reason, int sampleCount) const;
+
+        bool        fWillPlaybackBitmaps;
+        bool        fHasText;
+        int         fNumPaintWithPathEffectUses;
+        int         fNumFastPathDashEffects;
+        int         fNumAAConcavePaths;
+        int         fNumAAHairlineConcavePaths;
+    } fAnalysis;
 };
 
 #endif
diff --git a/include/core/SkPictureRecorder.h b/include/core/SkPictureRecorder.h
index cf17e1a..a3f7d48 100644
--- a/include/core/SkPictureRecorder.h
+++ b/include/core/SkPictureRecorder.h
@@ -25,24 +25,41 @@
 
 class SK_API SkPictureRecorder : SkNoncopyable {
 public:
-    SkPictureRecorder() : fPictureRecord(NULL), fRecorder(NULL), fRecord(NULL) { }
+    SkPictureRecorder();
     ~SkPictureRecorder();
 
+#ifdef SK_LEGACY_PICTURE_SIZE_API
+    SkCanvas* beginRecording(int width, int height,
+                             SkBBHFactory* bbhFactory = NULL,
+                             uint32_t recordFlags = 0) {
+        return this->beginRecording(SkIntToScalar(width), SkIntToScalar(height),
+                                    bbhFactory, recordFlags);
+    }
+#endif
+
     /** Returns the canvas that records the drawing commands.
-        @param width the base width for the picture, as if the recording
-                     canvas' bitmap had this width.
-        @param height the base width for the picture, as if the recording
-                     canvas' bitmap had this height.
+        @param width the width of the cull rect used when recording this picture.
+        @param height the height of the cull rect used when recording this picture.
         @param bbhFactory factory to create desired acceleration structure
         @param recordFlags optional flags that control recording.
         @return the canvas.
     */
-    SkCanvas* beginRecording(int width, int height,
+    SkCanvas* beginRecording(SkScalar width, SkScalar height,
                              SkBBHFactory* bbhFactory = NULL,
                              uint32_t recordFlags = 0);
 
-    /** Same as beginRecording(), using a new faster backend. */
-    SkCanvas* EXPERIMENTAL_beginRecording(int width, int height,
+    // As usual, we have a deprecated old version and a maybe almost working
+    // new version.  We currently point beginRecording() to
+    // DEPRECATED_beginRecording() unless SK_PICTURE_USE_SK_RECORD is defined,
+    // then we use EXPERIMENTAL_beginRecording().
+
+    // Old slower backend.
+    SkCanvas* DEPRECATED_beginRecording(SkScalar width, SkScalar height,
+                                        SkBBHFactory* bbhFactory = NULL,
+                                        uint32_t recordFlags = 0);
+
+    // New faster backend.
+    SkCanvas* EXPERIMENTAL_beginRecording(SkScalar width, SkScalar height,
                                           SkBBHFactory* bbhFactory = NULL);
 
     /** Returns the recording canvas if one is active, or NULL if recording is
@@ -77,15 +94,16 @@
     friend class SkPictureRecorderReplayTester; // for unit testing
     void partialReplay(SkCanvas* canvas) const;
 
-    int                     fWidth;
-    int                     fHeight;
+    SkScalar                      fCullWidth;
+    SkScalar                      fCullHeight;
+    SkAutoTUnref<SkBBoxHierarchy> fBBH;
 
-    // Both ref counted.  One of these two will be non-null:
-    SkPictureRecord*        fPictureRecord;   // beginRecording()
-    SkRecorder*             fRecorder;        // EXPERIMENTAL_beginRecording()
+    // One of these two canvases will be non-NULL.
+    SkAutoTUnref<SkPictureRecord> fPictureRecord;  // beginRecording()
+    SkAutoTUnref<SkRecorder>      fRecorder;       // EXPERIMENTAL_beginRecording()
 
-    // Not refcounted.  Used by EXPERIMENTAL_beginRecording().
-    SkRecord* fRecord;
+    // Used by EXPERIMENTAL_beginRecording().
+    SkAutoTDelete<SkRecord> fRecord;
 
     typedef SkNoncopyable INHERITED;
 };
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h
index 339cea1..02d696e 100644
--- a/include/core/SkPixelRef.h
+++ b/include/core/SkPixelRef.h
@@ -9,10 +9,11 @@
 #define SkPixelRef_DEFINED
 
 #include "SkBitmap.h"
+#include "SkDynamicAnnotations.h"
 #include "SkRefCnt.h"
 #include "SkString.h"
-#include "SkFlattenable.h"
 #include "SkImageInfo.h"
+#include "SkSize.h"
 #include "SkTDArray.h"
 
 //#define xed
@@ -46,7 +47,7 @@
 
     This class can be shared/accessed between multiple threads.
 */
-class SK_API SkPixelRef : public SkFlattenable {
+class SK_API SkPixelRef : public SkRefCnt {
 public:
     SK_DECLARE_INST_COUNT(SkPixelRef)
 
@@ -219,6 +220,22 @@
      */
     virtual GrTexture* getTexture() { return NULL; }
 
+    /**
+     *  If any planes or rowBytes is NULL, this should output the sizes and return true
+     *  if it can efficiently return YUV planar data. If it cannot, it should return false.
+     *
+     *  If all planes and rowBytes are not NULL, then it should copy the associated Y,U,V data
+     *  into those planes of memory supplied by the caller. It should validate that the sizes
+     *  match what it expected. If the sizes do not match, it should return false.
+     *
+     *  If colorSpace is not NULL, the YUV color space of the data should be stored in the address
+     *  it points at.
+     */
+    bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+                       SkYUVColorSpace* colorSpace) {
+        return this->onGetYUV8Planes(sizes, planes, rowBytes, colorSpace);
+    }
+
     bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
 
     /**
@@ -250,8 +267,6 @@
     virtual void globalUnref();
 #endif
 
-    SK_DEFINE_FLATTENABLE_TYPE(SkPixelRef)
-
     // Register a listener that may be called the next time our generation ID changes.
     //
     // We'll only call the listener if we're confident that we are the only SkPixelRef with this
@@ -307,6 +322,10 @@
     // default impl returns NULL.
     virtual SkData* onRefEncodedData();
 
+    // default impl returns false.
+    virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+                                 SkYUVColorSpace* colorSpace);
+
     /**
      *  Returns the size (in bytes) of the internally allocated memory.
      *  This should be implemented in all serializable SkPixelRef derived classes.
@@ -322,10 +341,6 @@
     */
     SkBaseMutex* mutex() const { return fMutex; }
 
-    // serialization
-    SkPixelRef(SkReadBuffer&, SkBaseMutex*);
-    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
-
     // only call from constructor. Flags this to always be locked, removing
     // the need to grab the mutex and call onLockPixels/onUnlockPixels.
     // Performance tweak to avoid those calls (esp. in multi-thread use case).
@@ -341,8 +356,8 @@
     LockRec         fRec;
     int             fLockCount;
 
-    mutable uint32_t fGenerationID;
-    mutable bool     fUniqueGenerationID;
+    mutable SkTRacy<uint32_t> fGenerationID;
+    mutable SkTRacy<bool>     fUniqueGenerationID;
 
     SkTDArray<GenIDChangeListener*> fGenIDChangeListeners;  // pointers are owned
 
@@ -363,7 +378,7 @@
     friend class SkBitmap;  // only for cloneGenID
     void cloneGenID(const SkPixelRef&);
 
-    typedef SkFlattenable INHERITED;
+    typedef SkRefCnt INHERITED;
 };
 
 class SkPixelRefFactory : public SkRefCnt {
@@ -374,7 +389,7 @@
      *  the pixelref will ref() the colortable.
      *  On failure return NULL.
      */
-    virtual SkPixelRef* create(const SkImageInfo&, SkColorTable*) = 0;
+    virtual SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) = 0;
 };
 
 #endif
diff --git a/include/core/SkRasterizer.h b/include/core/SkRasterizer.h
index d6e514c..3280f42 100644
--- a/include/core/SkRasterizer.h
+++ b/include/core/SkRasterizer.h
@@ -32,7 +32,9 @@
 
 protected:
     SkRasterizer() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkRasterizer(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
                              const SkIRect* clipBounds,
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index 77051c2..c8fc7c6 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -277,7 +277,6 @@
         rectangle. If either rectangle is empty, do nothing and return false.
     */
     bool intersect(const SkIRect& a, const SkIRect& b) {
-        SkASSERT(&a && &b);
 
         if (!a.isEmpty() && !b.isEmpty() &&
                 a.fLeft < b.fRight && b.fLeft < a.fRight &&
@@ -298,7 +297,6 @@
         we assert that both rectangles are non-empty.
     */
     bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) {
-        SkASSERT(&a && &b);
         SkASSERT(!a.isEmpty() && !b.isEmpty());
 
         if (a.fLeft < b.fRight && b.fLeft < a.fRight &&
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h
index 1724c77..459ad25 100644
--- a/include/core/SkRefCnt.h
+++ b/include/core/SkRefCnt.h
@@ -113,7 +113,6 @@
 
     // The following friends are those which override internal_dispose()
     // and conditionally call SkRefCnt::internal_dispose().
-    friend class GrTexture;
     friend class SkWeakRefCnt;
 
     mutable int32_t fRefCnt;
@@ -169,7 +168,7 @@
 }
 
 template<typename T> static inline void SkSafeSetNull(T*& obj) {
-    if (NULL != obj) {
+    if (obj) {
         obj->unref();
         obj = NULL;
     }
@@ -235,7 +234,7 @@
     BlockRefType *operator->() const {
         return static_cast<BlockRefType*>(fObj);
     }
-    operator T*() { return fObj; }
+    operator T*() const { return fObj; }
 
 private:
     T*  fObj;
@@ -248,45 +247,4 @@
 };
 #define SkAutoUnref(...) SK_REQUIRE_LOCAL_VAR(SkAutoUnref)
 
-class SkAutoRef : SkNoncopyable {
-public:
-    SkAutoRef(SkRefCnt* obj) : fObj(obj) { SkSafeRef(obj); }
-    ~SkAutoRef() { SkSafeUnref(fObj); }
-private:
-    SkRefCnt* fObj;
-};
-#define SkAutoRef(...) SK_REQUIRE_LOCAL_VAR(SkAutoRef)
-
-/** Wrapper class for SkRefCnt pointers. This manages ref/unref of a pointer to
-    a SkRefCnt (or subclass) object.
- */
-template <typename T> class SkRefPtr {
-public:
-    SkRefPtr() : fObj(NULL) {}
-    SkRefPtr(T* obj) : fObj(obj) { SkSafeRef(fObj); }
-    SkRefPtr(const SkRefPtr& o) : fObj(o.fObj) { SkSafeRef(fObj); }
-    ~SkRefPtr() { SkSafeUnref(fObj); }
-
-    SkRefPtr& operator=(const SkRefPtr& rp) {
-        SkRefCnt_SafeAssign(fObj, rp.fObj);
-        return *this;
-    }
-    SkRefPtr& operator=(T* obj) {
-        SkRefCnt_SafeAssign(fObj, obj);
-        return *this;
-    }
-
-    T* get() const { return fObj; }
-    T& operator*() const { return *fObj; }
-    T* operator->() const { return fObj; }
-
-    typedef T* SkRefPtr::*unspecified_bool_type;
-    operator unspecified_bool_type() const {
-        return fObj ? &SkRefPtr::fObj : NULL;
-    }
-
-private:
-    T* fObj;
-};
-
 #endif
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 31f57cc..0fbc1b8 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -20,7 +20,7 @@
 class SkPicture;
 class SkXfermode;
 class GrContext;
-class GrEffectRef;
+class GrFragmentProcessor;
 
 /** \class SkShader
  *
@@ -41,27 +41,20 @@
 
     /**
      *  Returns the local matrix.
+     *
+     *  FIXME: This can be incorrect for a Shader with its own local matrix
+     *  that is also wrapped via CreateLocalMatrixShader.
      */
     const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
 
     /**
      *  Returns true if the local matrix is not an identity matrix.
+     *
+     *  FIXME: This can be incorrect for a Shader with its own local matrix
+     *  that is also wrapped via CreateLocalMatrixShader.
      */
     bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); }
 
-#ifdef SK_SUPPORT_LEGACY_SHADER_LOCALMATRIX
-    /**
-     *  Set the shader's local matrix.
-     *  @param localM   The shader's new local matrix.
-     */
-    void setLocalMatrix(const SkMatrix& localM) { fLocalMatrix = localM; }
-
-    /**
-     *  Reset the shader's local matrix to identity.
-     */
-    void resetLocalMatrix() { fLocalMatrix.reset(); }
-#endif
-
     enum TileMode {
         /** replicate the edge color if the shader draws outside of its
          *  original bounds
@@ -192,6 +185,9 @@
             return SkShader::CanCallShadeSpan16(this->getFlags());
         }
 
+        // Notification from blitter::blitMask in case we need to see the non-alpha channels
+        virtual void set3DMask(const SkMask*) {}
+
     protected:
         // Reference to shader, so we don't have to dupe information.
         const SkShader& fShader;
@@ -374,17 +370,33 @@
 
 
     /**
-     *  Returns true if the shader subclass succeeds in setting the grEffect and the grColor output 
-     *  parameters to a value, returns false if it fails or if there is not an implementation of
-     *  this method in the shader subclass.
-     *  The incoming color to the effect has r=g=b=a all extracted from the SkPaint's alpha.
-     *  The output color should be the computed SkShader premul color modulated by the incoming
-     *  color. The GrContext may be used by the effect to create textures. The GPU device does not
+     *  Returns true if the shader subclass succeeds in creating an effect or if none is required.
+     *  False is returned if it fails or if there is not an implementation of this method in the
+     *  shader subclass.
+     *
+     *  On success an implementation of this method must inspect the SkPaint and set paintColor to
+     *  the color the effect expects as its input color. If the SkShader wishes to emit a solid
+     *  color then it should set paintColor to that color and not create an effect. Note that
+     *  GrColor is always premul. The common patterns are to convert paint's SkColor to GrColor or
+     *  to extract paint's alpha and replicate it to all channels in paintColor. Upon failure
+     *  paintColor should not be modified. It is not recommended to specialize the effect to
+     *  the paint's color as then many GPU shaders may be generated.
+     *
+     *  The GrContext may be used by the effect to create textures. The GPU device does not
      *  call createContext. Instead we pass the SkPaint here in case the shader needs paint info.
      */
-    virtual bool asNewEffect(GrContext* context, const SkPaint& paint,
-                             const SkMatrix* localMatrixOrNull, GrColor* grColor,
-                             GrEffectRef** grEffect) const;
+    virtual bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                     GrFragmentProcessor**) const;
+
+    /**
+     *  If the shader can represent its "average" luminance in a single color, return true and
+     *  if color is not NULL, return that color. If it cannot, return false and ignore the color
+     *  parameter.
+     *
+     *  Note: if this returns true, the returned color will always be opaque, as only the RGB
+     *  components are used to compute luminance.
+     */
+    bool asLuminanceColor(SkColor*) const;
 
 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
     /**
@@ -402,6 +414,12 @@
      */
     static SkShader* CreateEmptyShader();
 
+    /**
+     *  Call this to create a new shader that just draws the specified color. This should always
+     *  draw the same as a paint with this color (and no shader).
+     */
+    static SkShader* CreateColorShader(SkColor);
+
     /** Call this to create a new shader that will draw with the specified bitmap.
      *
      *  If the bitmap cannot be used (e.g. has no pixels, or its dimensions
@@ -428,10 +446,17 @@
      *              FIXME: src cannot be const due to SkCanvas::drawPicture
      *  @param tmx  The tiling mode to use when sampling the bitmap in the x-direction.
      *  @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
+     *  @param tile The tile rectangle in picture coordinates: this represents the subset
+     *              (or superset) of the picture used when building a tile. It is not
+     *              affected by localMatrix and does not imply scaling (only translation
+     *              and cropping). If null, the tile rect is considered equal to the picture
+     *              bounds.
      *  @return     Returns a new shader object. Note: this function never returns null.
     */
-    static SkShader* CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy,
-                                         const SkMatrix* localMatrix = NULL);
+    static SkShader* CreatePictureShader(SkPicture* src,
+                                         TileMode tmx, TileMode tmy,
+                                         const SkMatrix* localMatrix,
+                                         const SkRect* tile);
 
     /**
      *  Return a shader that will apply the specified localMatrix to the proxy shader.
@@ -454,7 +479,9 @@
     SK_DEFINE_FLATTENABLE_TYPE(SkShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkShader(SkReadBuffer& );
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
@@ -465,9 +492,17 @@
      */
     virtual Context* onCreateContext(const ContextRec&, void* storage) const;
 
+    virtual bool onAsLuminanceColor(SkColor*) const {
+        return false;
+    }
 private:
+    // This is essentially const, but not officially so it can be modified in
+    // constructors.
     SkMatrix fLocalMatrix;
-    
+
+    // So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
+    friend class SkLocalMatrixShader;
+
     typedef SkFlattenable INHERITED;
 };
 
diff --git a/include/core/SkStream.h b/include/core/SkStream.h
index 516b036..8e3f375 100644
--- a/include/core/SkStream.h
+++ b/include/core/SkStream.h
@@ -81,12 +81,6 @@
     SkScalar readScalar();
     size_t   readPackedUInt();
 
-    /**
-     *  Reconstitute an SkData object that was written to the stream
-     *  using SkWStream::writeData().
-     */
-    SkData* readData();
-
 //SkStreamRewindable
     /** Rewinds to the beginning of the stream. Returns true if the stream is known
      *  to be at the beginning after this call returns.
@@ -210,16 +204,6 @@
     bool    writeStream(SkStream* input, size_t length);
 
     /**
-     * Append an SkData object to the stream, such that it can be read
-     * out of the stream using SkStream::readData().
-     *
-     * Note that the encoding method used to write the SkData object
-     * to the stream may change over time.  This method DOES NOT
-     * just write the raw content of the SkData object to the stream.
-     */
-    bool writeData(const SkData*);
-
-    /**
      * This returns the number of bytes in the stream required to store
      * 'value'.
      */
diff --git a/include/core/SkString.h b/include/core/SkString.h
index bc06cb0..8a962ae 100644
--- a/include/core/SkString.h
+++ b/include/core/SkString.h
@@ -195,6 +195,7 @@
     void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
     void appendVAList(const char format[], va_list);
     void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
+    void prependVAList(const char format[], va_list);
 
     void remove(size_t offset, size_t length);
 
diff --git a/include/core/SkStrokeRec.h b/include/core/SkStrokeRec.h
index 42bed8c..0c5892f 100644
--- a/include/core/SkStrokeRec.h
+++ b/include/core/SkStrokeRec.h
@@ -30,6 +30,9 @@
         kStroke_Style,
         kStrokeAndFill_Style
     };
+    enum {
+        kStyleCount = kStrokeAndFill_Style + 1
+    };
 
     Style getStyle() const;
     SkScalar getWidth() const { return fWidth; }
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index d049d8c..0e238f8 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -10,6 +10,7 @@
 
 #include "SkRefCnt.h"
 #include "SkImage.h"
+#include "SkSurfaceProps.h"
 
 class SkCanvas;
 class SkPaint;
@@ -35,7 +36,16 @@
      *  If the requested surface cannot be created, or the request is not a
      *  supported configuration, NULL will be returned.
      */
-    static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes);
+    static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes,
+                                      const SkSurfaceProps* = NULL);
+
+    /**
+     *  The same as NewRasterDirect, but also accepts a call-back routine, which is invoked
+     *  when the surface is deleted, and is passed the pixel memory and the specified context.
+     */
+    static SkSurface* NewRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes,
+                                                 void (*releaseProc)(void* pixels, void* context),
+                                                 void* context, const SkSurfaceProps* = NULL);
 
     /**
      *  Return a new surface, with the memory for the pixels automatically
@@ -44,43 +54,36 @@
      *  If the requested surface cannot be created, or the request is not a
      *  supported configuration, NULL will be returned.
      */
-    static SkSurface* NewRaster(const SkImageInfo&);
+    static SkSurface* NewRaster(const SkImageInfo&, const SkSurfaceProps* = NULL);
 
     /**
      *  Helper version of NewRaster. It creates a SkImageInfo with the
      *  specified width and height, and populates the rest of info to match
      *  pixels in SkPMColor format.
      */
-    static SkSurface* NewRasterPMColor(int width, int height) {
-        return NewRaster(SkImageInfo::MakeN32Premul(width, height));
+    static SkSurface* NewRasterPMColor(int width, int height, const SkSurfaceProps* props = NULL) {
+        return NewRaster(SkImageInfo::MakeN32Premul(width, height), props);
     }
 
     /**
-     *  Text rendering modes that can be passed to NewRenderTarget*
-     */
-    enum TextRenderMode {
-        /**
-         *  This will use the standard text rendering method
-         */
-        kStandard_TextRenderMode,
-        /**
-         *  This will use signed distance fields for text rendering when possible
-         */
-        kDistanceField_TextRenderMode,
-    };
-
-    /**
      *  Return a new surface using the specified render target.
      */
-    static SkSurface* NewRenderTargetDirect(GrRenderTarget*,
-                                            TextRenderMode trm = kStandard_TextRenderMode);
-
+    static SkSurface* NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*);
+    
+    static SkSurface* NewRenderTargetDirect(GrRenderTarget* target) {
+        return NewRenderTargetDirect(target, NULL);
+    }
+    
     /**
      *  Return a new surface whose contents will be drawn to an offscreen
      *  render target, allocated by the surface.
      */
-    static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
-                                      TextRenderMode trm = kStandard_TextRenderMode);
+    static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+                                      const SkSurfaceProps* = NULL);
+
+    static SkSurface* NewRenderTarget(GrContext* gr, const SkImageInfo& info) {
+        return NewRenderTarget(gr, info, 0, NULL);
+    }
 
     /**
      *  Return a new surface whose contents will be drawn to an offscreen
@@ -94,8 +97,33 @@
      *  Note: Scratch textures count against the GrContext's cached resource
      *  budget.
      */
-    static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
-                                             TextRenderMode trm = kStandard_TextRenderMode);
+    static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+                                             const SkSurfaceProps* = NULL);
+
+    static SkSurface* NewScratchRenderTarget(GrContext* gr, const SkImageInfo& info) {
+        return NewScratchRenderTarget(gr, info, 0, NULL);
+    }
+
+#ifdef SK_SUPPORT_LEGACY_TEXTRENDERMODE
+    /**
+     *  Text rendering modes that can be passed to NewRenderTarget*
+     */
+    enum TextRenderMode {
+        /**
+         *  This will use the standard text rendering method
+         */
+        kStandard_TextRenderMode,
+        /**
+         *  This will use signed distance fields for text rendering when possible
+         */
+        kDistanceField_TextRenderMode,
+    };
+    static SkSurface* NewRenderTargetDirect(GrRenderTarget*, TextRenderMode);
+    static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+                                      TextRenderMode);
+    static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+                                             TextRenderMode);
+#endif
 
     int width() const { return fWidth; }
     int height() const { return fHeight; }
@@ -184,9 +212,11 @@
      */
     const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
 
+    const SkSurfaceProps& props() const { return fProps; }
+
 protected:
-    SkSurface(int width, int height);
-    SkSurface(const SkImageInfo&);
+    SkSurface(int width, int height, const SkSurfaceProps*);
+    SkSurface(const SkImageInfo&, const SkSurfaceProps*);
 
     // called by subclass if their contents have changed
     void dirtyGenerationID() {
@@ -194,9 +224,10 @@
     }
 
 private:
-    const int   fWidth;
-    const int   fHeight;
-    uint32_t    fGenerationID;
+    const SkSurfaceProps fProps;
+    const int            fWidth;
+    const int            fHeight;
+    uint32_t             fGenerationID;
 
     typedef SkRefCnt INHERITED;
 };
diff --git a/include/core/SkSurfaceProps.h b/include/core/SkSurfaceProps.h
new file mode 100644
index 0000000..0154473
--- /dev/null
+++ b/include/core/SkSurfaceProps.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSurfaceProps_DEFINED
+#define SkSurfaceProps_DEFINED
+
+#include "SkTypes.h"
+
+/**
+ *  Description of how the LCD strips are arranged for each pixel. If this is unknown, or the
+ *  pixels are meant to be "portable" and/or transformed before showing (e.g. rotated, scaled)
+ *  then use kUnknown_SkPixelGeometry.
+ */
+enum SkPixelGeometry {
+    kUnknown_SkPixelGeometry,
+    kRGB_H_SkPixelGeometry,
+    kBGR_H_SkPixelGeometry,
+    kRGB_V_SkPixelGeometry,
+    kBGR_V_SkPixelGeometry,
+};
+
+// Returns true iff geo is a known geometry and is RGB.
+static inline bool SkPixelGeometryIsRGB(SkPixelGeometry geo) {
+    return kRGB_H_SkPixelGeometry == geo || kRGB_V_SkPixelGeometry == geo;
+}
+
+// Returns true iff geo is a known geometry and is BGR.
+static inline bool SkPixelGeometryIsBGR(SkPixelGeometry geo) {
+    return kBGR_H_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo;
+}
+
+// Returns true iff geo is a known geometry and is horizontal.
+static inline bool SkPixelGeometryIsH(SkPixelGeometry geo) {
+    return kRGB_H_SkPixelGeometry == geo || kBGR_H_SkPixelGeometry == geo;
+}
+
+// Returns true iff geo is a known geometry and is vertical.
+static inline bool SkPixelGeometryIsV(SkPixelGeometry geo) {
+    return kRGB_V_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo;
+}
+
+/**
+ *  Describes properties and constraints of a given SkSurface. The rendering engine can parse these
+ *  during drawing, and can sometimes optimize its performance (e.g. disabling an expensive
+ *  feature).
+ */
+class SkSurfaceProps {
+public:
+    enum Flags {
+        kDisallowAntiAlias_Flag     = 1 << 0,
+        kDisallowDither_Flag        = 1 << 1,
+        kUseDistanceFieldFonts_Flag = 1 << 2,
+    };
+    SkSurfaceProps(uint32_t flags, SkPixelGeometry);
+
+    enum InitType {
+        kLegacyFontHost_InitType
+    };
+    SkSurfaceProps(InitType);
+    SkSurfaceProps(uint32_t flags, InitType);
+
+    uint32_t flags() const { return fFlags; }
+    SkPixelGeometry pixelGeometry() const { return fPixelGeometry; }
+
+    bool isDisallowAA() const { return SkToBool(fFlags & kDisallowAntiAlias_Flag); }
+    bool isDisallowDither() const { return SkToBool(fFlags & kDisallowDither_Flag); }
+    bool isUseDistanceFieldFonts() const { return SkToBool(fFlags & kUseDistanceFieldFonts_Flag); }
+
+private:
+    SkSurfaceProps();
+
+    uint32_t        fFlags;
+    SkPixelGeometry fPixelGeometry;
+};
+
+#endif
diff --git a/include/core/SkTArray.h b/include/core/SkTArray.h
index 6c76c78..06a85bc 100644
--- a/include/core/SkTArray.h
+++ b/include/core/SkTArray.h
@@ -384,7 +384,7 @@
                                     gMIN_ALLOC_COUNT;
         fPreAllocMemArray   = preAllocStorage;
         if (fReserveCount >= fCount &&
-            NULL != preAllocStorage) {
+            preAllocStorage) {
             fAllocCount = fReserveCount;
             fMemArray = preAllocStorage;
         } else {
@@ -427,7 +427,7 @@
             fAllocCount = newAllocCount;
             char* newMemArray;
 
-            if (fAllocCount == fReserveCount && NULL != fPreAllocMemArray) {
+            if (fAllocCount == fReserveCount && fPreAllocMemArray) {
                 newMemArray = (char*) fPreAllocMemArray;
             } else {
                 newMemArray = (char*) sk_malloc_throw(fAllocCount*sizeof(T));
diff --git a/include/core/SkTDArray.h b/include/core/SkTDArray.h
index ecbfbd9..92f297c 100644
--- a/include/core/SkTDArray.h
+++ b/include/core/SkTDArray.h
@@ -12,7 +12,7 @@
 
 #include "SkTypes.h"
 
-template <typename T> class SK_API SkTDArray {
+template <typename T> class SkTDArray {
 public:
     SkTDArray() {
         fReserve = fCount = 0;
@@ -282,12 +282,12 @@
     }
 
     // routines to treat the array like a stack
-    T*          push() { return this->append(); }
-    void        push(const T& elem) { *this->append() = elem; }
-    const T&    top() const { return (*this)[fCount - 1]; }
-    T&          top() { return (*this)[fCount - 1]; }
-    void        pop(T* elem) { if (elem) *elem = (*this)[fCount - 1]; --fCount; }
-    void        pop() { --fCount; }
+    T*       push() { return this->append(); }
+    void     push(const T& elem) { *this->append() = elem; }
+    const T& top() const { return (*this)[fCount - 1]; }
+    T&       top() { return (*this)[fCount - 1]; }
+    void     pop(T* elem) { SkASSERT(fCount > 0); if (elem) *elem = (*this)[fCount - 1]; --fCount; }
+    void     pop() { SkASSERT(fCount > 0); --fCount; }
 
     void deleteAll() {
         T*  iter = fArray;
diff --git a/include/core/SkTInternalLList.h b/include/core/SkTInternalLList.h
index 1c82a71..1aa1a12 100644
--- a/include/core/SkTInternalLList.h
+++ b/include/core/SkTInternalLList.h
@@ -46,18 +46,18 @@
     }
 
     void remove(T* entry) {
-        SkASSERT(NULL != fHead && NULL != fTail);
+        SkASSERT(fHead && fTail);
         SkASSERT(this->isInList(entry));
 
         T* prev = entry->fPrev;
         T* next = entry->fNext;
 
-        if (NULL != prev) {
+        if (prev) {
             prev->fNext = next;
         } else {
             fHead = next;
         }
-        if (NULL != next) {
+        if (next) {
             next->fPrev = prev;
         } else {
             fTail = prev;
@@ -77,7 +77,7 @@
 
         entry->fPrev = NULL;
         entry->fNext = fHead;
-        if (NULL != fHead) {
+        if (fHead) {
             fHead->fPrev = entry;
         }
         fHead = entry;
@@ -96,7 +96,7 @@
 
         entry->fPrev = fTail;
         entry->fNext = NULL;
-        if (NULL != fTail) {
+        if (fTail) {
             fTail->fNext = entry;
         }
         fTail = entry;
@@ -115,7 +115,7 @@
      * at the tail.
      */
     void addBefore(T* newEntry, T* existingEntry) {
-        SkASSERT(NULL != newEntry);
+        SkASSERT(newEntry);
 
         if (NULL == existingEntry) {
             this->addToTail(newEntry);
@@ -144,7 +144,7 @@
      * at the head.
      */
     void addAfter(T* newEntry, T* existingEntry) {
-        SkASSERT(NULL != newEntry);
+        SkASSERT(newEntry);
 
         if (NULL == existingEntry) {
             this->addToHead(newEntry);
@@ -227,7 +227,7 @@
     void validate() const {
         SkASSERT(!fHead == !fTail);
         Iter iter;
-        for (T* item = iter.init(*this, Iter::kHead_IterStart); NULL != item; item = iter.next()) {
+        for (T* item = iter.init(*this, Iter::kHead_IterStart); item; item = iter.next()) {
             SkASSERT(this->isInList(item));
             if (NULL == item->fPrev) {
                 SkASSERT(fHead == item);
@@ -255,7 +255,7 @@
      */
     int countEntries() const {
         int count = 0;
-        for (T* entry = fHead; NULL != entry; entry = entry->fNext) {
+        for (T* entry = fHead; entry; entry = entry->fNext) {
             ++count;
         }
         return count;
diff --git a/include/core/SkTLazy.h b/include/core/SkTLazy.h
index a291e22..a1dc001 100644
--- a/include/core/SkTLazy.h
+++ b/include/core/SkTLazy.h
@@ -88,7 +88,7 @@
      *  Returns true if a valid object has been initialized in the SkTLazy,
      *  false otherwise.
      */
-    bool isValid() const { return NULL != fPtr; }
+    bool isValid() const { return SkToBool(fPtr); }
 
     /**
      * Returns the object. This version should only be called when the caller
@@ -166,7 +166,7 @@
      * Returns a writable T*. The first time this is called the initial object is cloned.
      */
     T* writable() {
-        SkASSERT(NULL != fObj);
+        SkASSERT(fObj);
         if (!fLazy.isValid()) {
             fLazy.set(*fObj);
             fObj = fLazy.get();
diff --git a/include/core/SkTemplates.h b/include/core/SkTemplates.h
index a6248f5..5ef28ea 100644
--- a/include/core/SkTemplates.h
+++ b/include/core/SkTemplates.h
@@ -77,7 +77,19 @@
 public:
     SkAutoTCallVProc(T* obj): fObj(obj) {}
     ~SkAutoTCallVProc() { if (fObj) P(fObj); }
+
+    operator T*() const { return fObj; }
+    T* operator->() const { SkASSERT(fObj); return fObj; }
+
     T* detach() { T* obj = fObj; fObj = NULL; return obj; }
+    void reset(T* obj = NULL) {
+        if (fObj != obj) {
+            if (fObj) {
+                P(fObj);
+            }
+            fObj = obj;
+        }
+    }
 private:
     T* fObj;
 };
@@ -115,6 +127,7 @@
     ~SkAutoTDelete() { SkDELETE(fObj); }
 
     T* get() const { return fObj; }
+    operator T*() { return fObj; }
     T& operator*() const { SkASSERT(fObj); return *fObj; }
     T* operator->() const { SkASSERT(fObj); return fObj; }
 
@@ -157,7 +170,7 @@
 public:
     SkAutoTDestroy(T* obj = NULL) : fObj(obj) {}
     ~SkAutoTDestroy() {
-        if (NULL != fObj) {
+        if (fObj) {
             fObj->~T();
         }
     }
@@ -330,7 +343,7 @@
 
     /** Allocates space for 'count' Ts. */
     explicit SkAutoTMalloc(size_t count) {
-        fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
+        fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW);
     }
 
     ~SkAutoTMalloc() {
@@ -345,7 +358,7 @@
     /** Resize the memory area pointed to by the current ptr without preserving contents. */
     void reset(size_t count) {
         sk_free(fPtr);
-        fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
+        fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW);
     }
 
     T* get() const { return fPtr; }
diff --git a/include/core/SkTextBlob.h b/include/core/SkTextBlob.h
new file mode 100644
index 0000000..8ee1d19
--- /dev/null
+++ b/include/core/SkTextBlob.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTextBlob_DEFINED
+#define SkTextBlob_DEFINED
+
+#include "SkPaint.h"
+#include "SkRefCnt.h"
+#include "SkTArray.h"
+#include "SkTDArray.h"
+
+class SkReadBuffer;
+class SkWriteBuffer;
+
+/** \class SkTextBlob
+
+    SkTextBlob combines multiple text runs into an immutable, ref-counted structure.
+*/
+class SK_API SkTextBlob : public SkRefCnt {
+public:
+    /**
+     *  Returns the blob bounding box.
+     */
+    const SkRect& bounds() const { return fBounds; }
+
+    /**
+     *  Return a non-zero, unique value representing the text blob.
+     */
+    uint32_t uniqueID() const;
+
+    /**
+     *  Serialize to a buffer.
+     */
+    void flatten(SkWriteBuffer&) const;
+
+    /**
+     *  Recreate an SkTextBlob that was serialized into a buffer.
+     *
+     *  @param  SkReadBuffer Serialized blob data.
+     *  @return A new SkTextBlob representing the serialized data, or NULL if the buffer is
+     *          invalid.
+     */
+    static const SkTextBlob* CreateFromBuffer(SkReadBuffer&);
+
+private:
+    enum GlyphPositioning {
+        kDefault_Positioning      = 0, // Default glyph advances -- zero scalars per glyph.
+        kHorizontal_Positioning   = 1, // Horizontal positioning -- one scalar per glyph.
+        kFull_Positioning         = 2  // Point positioning -- two scalars per glyph.
+    };
+
+    class RunRecord;
+
+    class RunIterator {
+    public:
+        RunIterator(const SkTextBlob* blob);
+
+        bool done() const;
+        void next();
+
+        uint32_t glyphCount() const;
+        const uint16_t* glyphs() const;
+        const SkScalar* pos() const;
+        const SkPoint& offset() const;
+        void applyFontToPaint(SkPaint*) const;
+        GlyphPositioning positioning() const;
+
+    private:
+        const RunRecord* fCurrentRun;
+        int              fRemainingRuns;
+
+        SkDEBUGCODE(uint8_t* fStorageTop;)
+    };
+
+    SkTextBlob(int runCount, const SkRect& bounds);
+
+    virtual ~SkTextBlob();
+    virtual void internal_dispose() const SK_OVERRIDE;
+
+    static unsigned ScalarsPerGlyph(GlyphPositioning pos);
+
+    friend class SkBaseDevice;
+    friend class SkTextBlobBuilder;
+    friend class TextBlobTester;
+
+    const int        fRunCount;
+    const SkRect     fBounds;
+    mutable uint32_t fUniqueID;
+
+    SkDEBUGCODE(size_t fStorageSize;)
+
+    // The actual payload resides in externally-managed storage, following the object.
+    // (see the .cpp for more details)
+
+    typedef SkRefCnt INHERITED;
+};
+
+/** \class SkTextBlobBuilder
+
+    Helper class for constructing SkTextBlobs.
+ */
+class SK_API SkTextBlobBuilder {
+public:
+    SkTextBlobBuilder();
+
+    ~SkTextBlobBuilder();
+
+    /**
+     *  Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and
+     *  can be reused.
+     */
+    const SkTextBlob* build();
+
+    /**
+     *  Glyph and position buffers associated with a run.
+     *
+     *  A run is a sequence of glyphs sharing the same font metrics and positioning mode.
+     */
+    struct RunBuffer {
+        uint16_t* glyphs;
+        SkScalar* pos;
+    };
+
+    /**
+     *  Allocates a new default-positioned run and returns its writable glyph buffer
+     *  for direct manipulation.
+     *
+     *  @param font    The font to be used for this run.
+     *  @param count   Number of glyphs.
+     *  @param x,y     Position within the blob.
+     *  @param bounds  Optional run bounding box. If known in advance (!= NULL), it will
+     *                 be used when computing the blob bounds, to avoid re-measuring.
+     *
+     *  @return        A writable glyph buffer, valid until the next allocRun() or
+     *                 build() call. The buffer is guaranteed to hold @count@ glyphs.
+     */
+    const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
+                              const SkRect* bounds = NULL);
+
+    /**
+     *  Allocates a new horizontally-positioned run and returns its writable glyph and position
+     *  buffers for direct manipulation.
+     *
+     *  @param font    The font to be used for this run.
+     *  @param count   Number of glyphs.
+     *  @param y       Vertical offset within the blob.
+     *  @param bounds  Optional run bounding box. If known in advance (!= NULL), it will
+     *                 be used when computing the blob bounds, to avoid re-measuring.
+     *
+     *  @return        Writable glyph and position buffers, valid until the next allocRun()
+     *                 or build() call. The buffers are guaranteed to hold @count@ elements.
+     */
+    const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
+                                  const SkRect* bounds = NULL);
+
+    /**
+     *  Allocates a new fully-positioned run and returns its writable glyph and position
+     *  buffers for direct manipulation.
+     *
+     *  @param font   The font to be used for this run.
+     *  @param count  Number of glyphs.
+     *  @param bounds Optional run bounding box. If known in advance (!= NULL), it will
+     *                be used when computing the blob bounds, to avoid re-measuring.
+     *
+     *  @return       Writable glyph and position buffers, valid until the next allocRun()
+     *                or build() call. The glyph buffer and position buffer are
+     *                guaranteed to hold @count@ and 2 * @count@ elements, respectively.
+     */
+    const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL);
+
+private:
+    void reserve(size_t size);
+    void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
+                       int count, SkPoint offset, const SkRect* bounds);
+    bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
+                  int count, SkPoint offset);
+    void updateDeferredBounds();
+
+    SkAutoTMalloc<uint8_t> fStorage;
+    size_t                 fStorageSize;
+    size_t                 fStorageUsed;
+
+    SkRect                 fBounds;
+    int                    fRunCount;
+    bool                   fDeferredBounds;
+    size_t                 fLastRun; // index into fStorage
+
+    RunBuffer              fCurrentRunBuffer;
+};
+
+#endif // SkTextBlob_DEFINED
diff --git a/include/core/SkThread.h b/include/core/SkThread.h
index 4f7f326..bcbc437 100644
--- a/include/core/SkThread.h
+++ b/include/core/SkThread.h
@@ -16,6 +16,7 @@
  *  No additional memory barrier is required; this must act as a compiler barrier.
  */
 static int32_t sk_atomic_inc(int32_t* addr);
+static int64_t sk_atomic_inc(int64_t* addr);
 
 /** Atomically adds inc to the int referenced by addr and returns the previous value.
  *  No additional memory barrier is required; this must act as a compiler barrier.
@@ -49,8 +50,8 @@
  *  and returns the previous value.
  *  No additional memory barrier is required; this must act as a compiler barrier.
  */
-static inline int32_t sk_atomic_conditional_inc(int32_t* addr) {
-    int32_t prev;
+template<typename INT_TYPE> static inline INT_TYPE sk_atomic_conditional_inc(INT_TYPE* addr) {
+    INT_TYPE prev;
     do {
         prev = *addr;
         if (0 == prev) {
@@ -95,7 +96,6 @@
 };
 
 #define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = ...
-#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = ...
 */
 
 #include SK_MUTEX_PLATFORM_H
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
index 0b1c1f2..a080d84 100644
--- a/include/core/SkTypeface.h
+++ b/include/core/SkTypeface.h
@@ -114,13 +114,13 @@
     /** Return a new typeface given a file. If the file does not exist, or is
         not a valid font file, returns null.
     */
-    static SkTypeface* CreateFromFile(const char path[]);
+    static SkTypeface* CreateFromFile(const char path[], int index = 0);
 
     /** Return a new typeface given a stream. If the stream is
         not a valid font file, returns null. Ownership of the stream is
         transferred, so the caller must not reference it again.
     */
-    static SkTypeface* CreateFromStream(SkStream* stream);
+    static SkTypeface* CreateFromStream(SkStream* stream, int index = 0);
 
     /** Write a unique signature to a stream, sufficient to reconstruct a
         typeface referencing the same font when Deserialize is called.
@@ -312,6 +312,12 @@
     virtual bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
                                              int32_t adjustments[]) const;
 
+    /** Returns the family name of the typeface as known by its font manager.
+     *  This name may or may not be produced by the family name iterator.
+     */
+    virtual void onGetFamilyName(SkString* familyName) const = 0;
+
+    /** Returns an iterator over the family names in the font. */
     virtual LocalizedStrings* onCreateFamilyNameIterator() const = 0;
 
     virtual int onGetTableTags(SkFontTableTag tags[]) const = 0;
@@ -322,6 +328,8 @@
     friend class SkGTypeface;
     friend class SkPDFFont;
     friend class SkPDFCIDFont;
+    friend class GrPathRendering;
+    friend class GrGLPathRendering;
 
     /** Retrieve detailed typeface metrics.  Used by the PDF backend.
      @param perGlyphInfo Indicate what glyph specific information (advances,
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index 5ff57f8..0e9e230 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -89,7 +89,7 @@
 #define SK_INIT_TO_AVOID_WARNING    = 0
 
 #ifndef SkDebugf
-    void SkDebugf(const char format[], ...);
+    SK_API void SkDebugf(const char format[], ...);
 #endif
 
 #ifdef SK_DEBUG
@@ -300,6 +300,9 @@
 #define SkAlign8(x)     (((x) + 7) >> 3 << 3)
 #define SkIsAlign8(x)   (0 == ((x) & 7))
 
+#define SkAlignPtr(x)   (sizeof(void*) == 8 ?   SkAlign8(x) :   SkAlign4(x))
+#define SkIsAlignPtr(x) (sizeof(void*) == 8 ? SkIsAlign8(x) : SkIsAlign4(x))
+
 typedef uint32_t SkFourByteTag;
 #define SkSetFourByteTag(a, b, c, d)    (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
 
@@ -325,6 +328,9 @@
 /** The generation IDs in Skia reserve 0 has an invalid marker.
  */
 #define SK_InvalidGenID     0
+/** The unique IDs in Skia reserve 0 has an invalid marker.
+ */
+#define SK_InvalidUniqueID  0
 
 /****************************************************************************
     The rest of these only build with C++
@@ -533,7 +539,7 @@
      */
     void* reset(size_t size, OnShrink shrink = kAlloc_OnShrink,  bool* didChangeAlloc = NULL) {
         if (size == fSize || (kReuse_OnShrink == shrink && size < fSize)) {
-            if (NULL != didChangeAlloc) {
+            if (didChangeAlloc) {
                 *didChangeAlloc = false;
             }
             return fPtr;
@@ -542,7 +548,7 @@
         sk_free(fPtr);
         fPtr = size ? sk_malloc_throw(size) : NULL;
         fSize = size;
-        if (NULL != didChangeAlloc) {
+        if (didChangeAlloc) {
             *didChangeAlloc = true;
         }
 
@@ -637,7 +643,7 @@
                 bool* didChangeAlloc = NULL) {
         size = (size < kSize) ? kSize : size;
         bool alloc = size != fSize && (SkAutoMalloc::kAlloc_OnShrink == shrink || size > fSize);
-        if (NULL != didChangeAlloc) {
+        if (didChangeAlloc) {
             *didChangeAlloc = alloc;
         }
         if (alloc) {
diff --git a/include/core/SkWriter32.h b/include/core/SkWriter32.h
index cadcaa7..fd24ba9 100644
--- a/include/core/SkWriter32.h
+++ b/include/core/SkWriter32.h
@@ -22,7 +22,7 @@
 #include "SkTemplates.h"
 #include "SkTypes.h"
 
-class SkWriter32 : SkNoncopyable {
+class SK_API SkWriter32 : SkNoncopyable {
 public:
     /**
      *  The caller can specify an initial block of storage, which the caller manages.
diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h
index c0a6572..bedcc24 100644
--- a/include/core/SkXfermode.h
+++ b/include/core/SkXfermode.h
@@ -13,7 +13,7 @@
 #include "SkFlattenable.h"
 #include "SkColor.h"
 
-class GrEffectRef;
+class GrFragmentProcessor;
 class GrTexture;
 class SkString;
 
@@ -198,18 +198,16 @@
         fragment shader. If NULL, the effect should request access to destination color
         (setWillReadDstColor()), and use that in the fragment shader (builder->dstColor()).
      */
-    virtual bool asNewEffect(GrEffectRef** effect, GrTexture* background = NULL) const;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture* background = NULL) const;
 
     /** Returns true if the xfermode can be expressed as coeffs (src, dst), or as an effect
-        (effect). This helper calls the asCoeff() and asNewEffect() virtuals. If the xfermode is
-        NULL, it is treated as kSrcOver_Mode. It is legal to call this with all params NULL to
-        simply test the return value.  effect, src, and dst must all be NULL or all non-NULL.
+        (effect). This helper calls the asCoeff() and asFragmentProcessor() virtuals. If the
+        xfermode is NULL, it is treated as kSrcOver_Mode. It is legal to call this with all params
+        NULL to simply test the return value.  effect, src, and dst must all be NULL or all
+        non-NULL.
      */
-    static bool AsNewEffectOrCoeff(SkXfermode*,
-                                   GrEffectRef** effect,
-                                   Coeff* src,
-                                   Coeff* dst,
-                                   GrTexture* background = NULL);
+    static bool asFragmentProcessorOrCoeff(SkXfermode*, GrFragmentProcessor**, Coeff* src,
+                                           Coeff* dst, GrTexture* background = NULL);
 
     SK_TO_STRING_PUREVIRT()
     SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
@@ -217,7 +215,9 @@
 
 protected:
     SkXfermode() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkXfermode(SkReadBuffer& rb) : SkFlattenable(rb) {}
+#endif
 
     /** The default implementation of xfer32/xfer16/xferA8 in turn call this
         method, 1 color at a time (upscaled to a SkPMColor). The default
diff --git a/include/device/xps/SkXPSDevice.h b/include/device/xps/SkXPSDevice.h
index 5170957..2aa7ba8 100644
--- a/include/device/xps/SkXPSDevice.h
+++ b/include/device/xps/SkXPSDevice.h
@@ -26,6 +26,8 @@
 #include "SkTScopedComPtr.h"
 #include "SkTypeface.h"
 
+//#define SK_XPS_USE_DETERMINISTIC_IDS
+
 /** \class SkXPSDevice
 
     The drawing context for the XPS backend.
@@ -172,6 +174,18 @@
 
     SkTArray<TypefaceUse, true> fTypefaces;
 
+    /** Creates a GUID based id and places it into buffer.
+        buffer should have space for at least GUID_ID_LEN wide characters.
+        The string will always be wchar null terminated.
+        XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0
+        The string may begin with a digit,
+        and so may not be suitable as a bare resource key.
+     */
+    HRESULT createId(wchar_t* buffer, size_t bufferSize, wchar_t sep = '-');
+#ifdef SK_XPS_USE_DETERMINISTIC_IDS
+    decltype(GUID::Data1) fNextId = 0;
+#endif
+
     HRESULT initXpsDocumentWriter(IXpsOMImageResource* image);
 
     HRESULT createXpsPage(
diff --git a/include/effects/Sk1DPathEffect.h b/include/effects/Sk1DPathEffect.h
index 85f8ea2..87047e4 100644
--- a/include/effects/Sk1DPathEffect.h
+++ b/include/effects/Sk1DPathEffect.h
@@ -64,7 +64,9 @@
 
 protected:
     SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkPath1DPathEffect(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     // overrides from Sk1DPathEffect
diff --git a/include/effects/Sk2DPathEffect.h b/include/effects/Sk2DPathEffect.h
index 2adf598..80a27a3 100644
--- a/include/effects/Sk2DPathEffect.h
+++ b/include/effects/Sk2DPathEffect.h
@@ -14,14 +14,9 @@
 
 class SK_API Sk2DPathEffect : public SkPathEffect {
 public:
-    static Sk2DPathEffect* Create(const SkMatrix& mat) {
-        return SkNEW_ARGS(Sk2DPathEffect, (mat));
-    }
+    virtual bool filterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
 
-    virtual bool filterPath(SkPath*, const SkPath&,
-                            SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
-
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk2DPathEffect)
+    SK_DECLARE_UNFLATTENABLE_OBJECT()
 
 protected:
     /** New virtual, to be overridden by subclasses.
@@ -44,7 +39,9 @@
 
     // protected so that subclasses can call this during unflattening
     explicit Sk2DPathEffect(const SkMatrix& mat);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit Sk2DPathEffect(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
@@ -73,7 +70,9 @@
 protected:
     SkLine2DPathEffect(SkScalar width, const SkMatrix& matrix)
         : Sk2DPathEffect(matrix), fWidth(width) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkLine2DPathEffect(SkReadBuffer&);
+#endif
 
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
@@ -99,7 +98,9 @@
 
 protected:
     SkPath2DPathEffect(const SkMatrix&, const SkPath&);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkPath2DPathEffect(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual void next(const SkPoint&, int u, int v, SkPath*) const SK_OVERRIDE;
diff --git a/include/effects/SkAlphaThresholdFilter.h b/include/effects/SkAlphaThresholdFilter.h
index 23af56f..f409ee0 100644
--- a/include/effects/SkAlphaThresholdFilter.h
+++ b/include/effects/SkAlphaThresholdFilter.h
@@ -20,7 +20,8 @@
      * The 0,0 point of the region corresponds to the upper left corner of the
      * source image.
      */
-    static SkImageFilter* Create(const SkRegion& region, SkScalar innerThreshold, SkScalar outerThreshold);
+    static SkImageFilter* Create(const SkRegion& region, SkScalar innerThreshold,
+                                 SkScalar outerThreshold, SkImageFilter* input = NULL);
 };
 
 #endif
diff --git a/include/effects/SkAvoidXfermode.h b/include/effects/SkAvoidXfermode.h
index a2599a8..53ce708 100644
--- a/include/effects/SkAvoidXfermode.h
+++ b/include/effects/SkAvoidXfermode.h
@@ -54,12 +54,15 @@
 
 protected:
     SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkAvoidXfermode(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
     SkColor     fOpColor;
-    uint32_t    fDistMul;   // x.14
+    uint32_t    fDistMul;   // x.14 cached from fTolerance
+    uint8_t     fTolerance;
     Mode        fMode;
 
     typedef SkXfermode INHERITED;
diff --git a/include/effects/SkBicubicImageFilter.h b/include/effects/SkBicubicImageFilter.h
deleted file mode 100644
index 7c1e923..0000000
--- a/include/effects/SkBicubicImageFilter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkBicubicImageFilter_DEFINED
-#define SkBicubicImageFilter_DEFINED
-
-#include "SkImageFilter.h"
-#include "SkScalar.h"
-#include "SkSize.h"
-#include "SkPoint.h"
-
-/*! \class SkBicubicImageFilter
-    Bicubic resampling image filter.  This filter does a 16-tap bicubic
-    filter using the given matrix.
- */
-
-class SK_API SkBicubicImageFilter : public SkImageFilter {
-public:
-    virtual ~SkBicubicImageFilter();
-
-    static SkBicubicImageFilter* CreateMitchell(const SkSize& scale, SkImageFilter* input = NULL);
-
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBicubicImageFilter)
-
-protected:
-    /** Construct a (scaling-only) bicubic resampling image filter.
-        @param scale        How much to scale the image.
-        @param coefficients The 16 coefficients of the bicubic matrix.
-        @param input        The input image filter.  If NULL, the src bitmap
-                            passed to filterImage() is used instead.
-    */
-    SkBicubicImageFilter(const SkSize& scale, const SkScalar coefficients[16],
-                         SkImageFilter* input = NULL);
-    SkBicubicImageFilter(SkReadBuffer& buffer);
-    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
-
-    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
-                               SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
-
-#if SK_SUPPORT_GPU
-    virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; }
-    virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
-                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
-#endif
-
-private:
-    SkSize    fScale;
-    SkScalar  fCoefficients[16];
-    typedef SkImageFilter INHERITED;
-};
-
-#endif
diff --git a/include/effects/SkBitmapSource.h b/include/effects/SkBitmapSource.h
index 2aa8fe9..9004a46 100644
--- a/include/effects/SkBitmapSource.h
+++ b/include/effects/SkBitmapSource.h
@@ -27,7 +27,9 @@
 protected:
     explicit SkBitmapSource(const SkBitmap& bitmap);
     SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkBitmapSource(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkBlurDrawLooper.h b/include/effects/SkBlurDrawLooper.h
index 507ec8b..9db9f0d 100644
--- a/include/effects/SkBlurDrawLooper.h
+++ b/include/effects/SkBlurDrawLooper.h
@@ -53,7 +53,9 @@
     SkBlurDrawLooper(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy,
                      uint32_t flags);
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkBlurDrawLooper(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool asABlurShadow(BlurShadowRec*) const SK_OVERRIDE;
diff --git a/include/effects/SkBlurImageFilter.h b/include/effects/SkBlurImageFilter.h
index 732af8f..cfa895a 100644
--- a/include/effects/SkBlurImageFilter.h
+++ b/include/effects/SkBlurImageFilter.h
@@ -16,8 +16,8 @@
     static SkBlurImageFilter* Create(SkScalar sigmaX,
                                      SkScalar sigmaY,
                                      SkImageFilter* input = NULL,
-                                     const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkBlurImageFilter, (sigmaX, sigmaY, input, cropRect));
+                                     const CropRect* cropRect = NULL, uint32_t uniqueID = 0) {
+        return SkNEW_ARGS(SkBlurImageFilter, (sigmaX, sigmaY, input, cropRect, uniqueID));
     }
 
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
@@ -28,8 +28,11 @@
     SkBlurImageFilter(SkScalar sigmaX,
                       SkScalar sigmaY,
                       SkImageFilter* input,
-                      const CropRect* cropRect);
+                      const CropRect* cropRect,
+                      uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkBlurImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkColorFilterImageFilter.h b/include/effects/SkColorFilterImageFilter.h
index 6c88361..46f2d2a 100644
--- a/include/effects/SkColorFilterImageFilter.h
+++ b/include/effects/SkColorFilterImageFilter.h
@@ -16,13 +16,16 @@
 public:
     static SkColorFilterImageFilter* Create(SkColorFilter* cf,
                                             SkImageFilter* input = NULL,
-                                            const CropRect* cropRect = NULL);
+                                            const CropRect* cropRect = NULL,
+                                            uint32_t uniqueID = 0);
     virtual ~SkColorFilterImageFilter();
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorFilterImageFilter)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkColorFilterImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
@@ -33,7 +36,8 @@
 private:
     SkColorFilterImageFilter(SkColorFilter* cf,
                              SkImageFilter* input,
-                             const CropRect* cropRect = NULL);
+                             const CropRect* cropRect,
+                             uint32_t uniqueID);
     SkColorFilter*  fColorFilter;
 
     typedef SkImageFilter INHERITED;
diff --git a/include/effects/SkColorMatrixFilter.h b/include/effects/SkColorMatrixFilter.h
index 5cfa468..dad4062 100644
--- a/include/effects/SkColorMatrixFilter.h
+++ b/include/effects/SkColorMatrixFilter.h
@@ -26,7 +26,7 @@
     virtual uint32_t getFlags() const SK_OVERRIDE;
     virtual bool asColorMatrix(SkScalar matrix[20]) const SK_OVERRIDE;
 #if SK_SUPPORT_GPU
-    virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE;
+    virtual GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
 #endif
 
     struct State {
@@ -41,7 +41,9 @@
 protected:
     explicit SkColorMatrixFilter(const SkColorMatrix&);
     explicit SkColorMatrixFilter(const SkScalar array[20]);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkColorMatrixFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkComposeImageFilter.h b/include/effects/SkComposeImageFilter.h
index 32304b9..26eed37 100644
--- a/include/effects/SkComposeImageFilter.h
+++ b/include/effects/SkComposeImageFilter.h
@@ -14,15 +14,27 @@
 public:
     virtual ~SkComposeImageFilter();
 
-    static SkComposeImageFilter* Create(SkImageFilter* outer, SkImageFilter* inner) {
-        return SkNEW_ARGS(SkComposeImageFilter, (outer, inner));
+    static SkImageFilter* Create(SkImageFilter* outer, SkImageFilter* inner) {
+        if (NULL == outer) {
+            return SkSafeRef(inner);
+        }
+        if (NULL == inner) {
+            return SkRef(outer);
+        }
+        SkImageFilter* inputs[2] = { outer, inner };
+        return SkNEW_ARGS(SkComposeImageFilter, (inputs));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeImageFilter)
 
 protected:
-    SkComposeImageFilter(SkImageFilter* outer, SkImageFilter* inner) : INHERITED(outer, inner) {}
+    explicit SkComposeImageFilter(SkImageFilter* inputs[2]) : INHERITED(2, inputs) {
+        SkASSERT(inputs[0]);
+        SkASSERT(inputs[1]);
+    }
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkComposeImageFilter(SkReadBuffer& buffer);
+#endif
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
diff --git a/include/effects/SkCornerPathEffect.h b/include/effects/SkCornerPathEffect.h
index 8bb7a50..e61d494 100644
--- a/include/effects/SkCornerPathEffect.h
+++ b/include/effects/SkCornerPathEffect.h
@@ -32,7 +32,9 @@
 
 protected:
     explicit SkCornerPathEffect(SkScalar radius);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkCornerPathEffect(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkDashPathEffect.h b/include/effects/SkDashPathEffect.h
index 6fab962..3946224 100644
--- a/include/effects/SkDashPathEffect.h
+++ b/include/effects/SkDashPathEffect.h
@@ -51,13 +51,13 @@
 
     virtual DashType asADash(DashInfo* info) const SK_OVERRIDE;
 
-    virtual Factory getFactory() const SK_OVERRIDE;
-
-    static SkFlattenable* CreateProc(SkReadBuffer&);
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDashPathEffect)
 
 protected:
     SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDashPathEffect(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkDiscretePathEffect.h b/include/effects/SkDiscretePathEffect.h
index cbee20f..8f1082c 100644
--- a/include/effects/SkDiscretePathEffect.h
+++ b/include/effects/SkDiscretePathEffect.h
@@ -45,7 +45,9 @@
     SkDiscretePathEffect(SkScalar segLength,
                          SkScalar deviation,
                          uint32_t seedAssist);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDiscretePathEffect(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkDisplacementMapEffect.h b/include/effects/SkDisplacementMapEffect.h
index 4d64aae..0a658ac 100644
--- a/include/effects/SkDisplacementMapEffect.h
+++ b/include/effects/SkDisplacementMapEffect.h
@@ -27,10 +27,8 @@
                                            ChannelSelectorType yChannelSelector,
                                            SkScalar scale, SkImageFilter* displacement,
                                            SkImageFilter* color = NULL,
-                                           const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale,
-                                                    displacement, color, cropRect));
-    }
+                                           const CropRect* cropRect = NULL,
+                                           uint32_t uniqueID = 0);
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDisplacementMapEffect)
 
@@ -53,10 +51,12 @@
 protected:
     SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
                             ChannelSelectorType yChannelSelector,
-                            SkScalar scale, SkImageFilter* displacement,
-                            SkImageFilter* color = NULL,
-                            const CropRect* cropRect = NULL);
+                            SkScalar scale, SkImageFilter* inputs[2],
+                            const CropRect* cropRect,
+                            uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDisplacementMapEffect(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkDropShadowImageFilter.h b/include/effects/SkDropShadowImageFilter.h
index 59d3145..0d6c24e 100644
--- a/include/effects/SkDropShadowImageFilter.h
+++ b/include/effects/SkDropShadowImageFilter.h
@@ -11,26 +11,23 @@
 
 class SK_API SkDropShadowImageFilter : public SkImageFilter {
 public:
-    static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy, SkScalar sigma,
-                                           SkColor color, SkImageFilter* input = NULL) {
-        return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigma, color, input));
-    }
     static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
                                            SkScalar sigmaX, SkScalar sigmaY, SkColor color,
                                            SkImageFilter* input = NULL,
-                                           const CropRect* cropRect = NULL) {
+                                           const CropRect* cropRect = NULL,
+                                           uint32_t uniqueID = 0) {
         return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY,
-                                                    color, input, cropRect));
+                                                    color, input, cropRect, uniqueID));
     }
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
 
 protected:
-    SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor,
-                            SkImageFilter* input);
     SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
-                            SkImageFilter* input, const CropRect* cropRect);
+                            SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDropShadowImageFilter(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual bool onFilterImage(Proxy*, const SkBitmap& source, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
     virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
diff --git a/include/effects/SkEmbossMaskFilter.h b/include/effects/SkEmbossMaskFilter.h
index a1e2af4..74895fb 100644
--- a/include/effects/SkEmbossMaskFilter.h
+++ b/include/effects/SkEmbossMaskFilter.h
@@ -37,7 +37,9 @@
 
 protected:
     SkEmbossMaskFilter(SkScalar blurSigma, const Light& light);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkEmbossMaskFilter(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkLayerDrawLooper.h b/include/effects/SkLayerDrawLooper.h
index ac56e28..5bb8b66 100644
--- a/include/effects/SkLayerDrawLooper.h
+++ b/include/effects/SkLayerDrawLooper.h
@@ -81,8 +81,14 @@
 
     SK_TO_STRING_OVERRIDE()
 
-    /// Implements Flattenable.
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    static SkFlattenable* DeepCreateProc(SkReadBuffer& buffer) {
+        return CreateProc(buffer);
+    }
+    virtual Factory getFactory() const SK_OVERRIDE { return DeepCreateProc; }
+#else
     virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; }
+#endif
     static SkFlattenable* CreateProc(SkReadBuffer& buffer);
 
 protected:
diff --git a/include/effects/SkLayerRasterizer.h b/include/effects/SkLayerRasterizer.h
index 9d4c823..60b3f20 100644
--- a/include/effects/SkLayerRasterizer.h
+++ b/include/effects/SkLayerRasterizer.h
@@ -64,24 +64,14 @@
         SkDeque* fLayers;
     };
 
-#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API
-    void addLayer(const SkPaint& paint) {
-        this->addLayer(paint, 0, 0);
-    }
-
-    /**    Add a new layer (above any previous layers) to the rasterizer.
-        The layer will extract those fields that affect the mask from
-        the specified paint, but will not retain a reference to the paint
-        object itself, so it may be reused without danger of side-effects.
-    */
-    void addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy);
-#endif
-
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLayerRasterizer)
 
 protected:
+    SkLayerRasterizer();
     SkLayerRasterizer(SkDeque* layers);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkLayerRasterizer(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     // override from SkRasterizer
@@ -89,17 +79,8 @@
                              const SkIRect* clipBounds,
                              SkMask* mask, SkMask::CreateMode mode) const;
 
-#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API
-public:
-#endif
-    SkLayerRasterizer();
-
 private:
-#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API
-    SkDeque* fLayers;
-#else
     const SkDeque* const fLayers;
-#endif
 
     static SkDeque* ReadLayers(SkReadBuffer& buffer);
 
diff --git a/include/effects/SkLerpXfermode.h b/include/effects/SkLerpXfermode.h
index d9186d9..d779f16 100644
--- a/include/effects/SkLerpXfermode.h
+++ b/include/effects/SkLerpXfermode.h
@@ -32,7 +32,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLerpXfermode)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkLerpXfermode(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkLightingImageFilter.h b/include/effects/SkLightingImageFilter.h
index 4a76a9c..5fb0822 100644
--- a/include/effects/SkLightingImageFilter.h
+++ b/include/effects/SkLightingImageFilter.h
@@ -73,15 +73,18 @@
     SkLightingImageFilter(SkLight* light,
                           SkScalar surfaceScale,
                           SkImageFilter* input,
-                          const CropRect* cropRect = NULL);
+                          const CropRect* cropRect,
+                          uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkLightingImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
-    const SkLight* light() const { return fLight; }
+    const SkLight* light() const { return fLight.get(); }
     SkScalar surfaceScale() const { return fSurfaceScale; }
 
 private:
     typedef SkImageFilter INHERITED;
-    SkLight* fLight;
+    SkAutoTUnref<SkLight> fLight;
     SkScalar fSurfaceScale;
 };
 
diff --git a/include/effects/SkLumaColorFilter.h b/include/effects/SkLumaColorFilter.h
index f2cee29..420999f 100644
--- a/include/effects/SkLumaColorFilter.h
+++ b/include/effects/SkLumaColorFilter.h
@@ -28,14 +28,16 @@
     virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const SK_OVERRIDE;
 
 #if SK_SUPPORT_GPU
-    virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE;
+    virtual GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
 #endif
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLumaColorFilter)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkLumaColorFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkMagnifierImageFilter.h b/include/effects/SkMagnifierImageFilter.h
index 9d8a9b6..4dd47ef 100644
--- a/include/effects/SkMagnifierImageFilter.h
+++ b/include/effects/SkMagnifierImageFilter.h
@@ -14,21 +14,22 @@
 
 class SK_API SkMagnifierImageFilter : public SkImageFilter {
 public:
-    static SkMagnifierImageFilter* Create(const SkRect& srcRect, SkScalar inset) {
-        return SkNEW_ARGS(SkMagnifierImageFilter, (srcRect, inset));
-    }
+    static SkImageFilter* Create(const SkRect& src, SkScalar inset, SkImageFilter* input = NULL);
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMagnifierImageFilter)
 
 protected:
-    SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset);
+    SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset, SkImageFilter* input);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkMagnifierImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
 #if SK_SUPPORT_GPU
-    virtual bool asNewEffect(GrEffectRef** effect, GrTexture* texture, const SkMatrix& matrix, const SkIRect& bounds) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+                                     const SkIRect& bounds) const SK_OVERRIDE;
 #endif
 
 private:
diff --git a/include/effects/SkMatrixConvolutionImageFilter.h b/include/effects/SkMatrixConvolutionImageFilter.h
index 606de57..c04d7d1 100644
--- a/include/effects/SkMatrixConvolutionImageFilter.h
+++ b/include/effects/SkMatrixConvolutionImageFilter.h
@@ -23,9 +23,10 @@
 public:
     /*! \enum TileMode */
     enum TileMode {
-      kClamp_TileMode,         /*!< Clamp to the image's edge pixels. */
+      kClamp_TileMode = 0,         /*!< Clamp to the image's edge pixels. */
       kRepeat_TileMode,        /*!< Wrap around to the image's opposite edge. */
       kClampToBlack_TileMode,  /*!< Fill with transparent black. */
+      kMax_TileMode = kClampToBlack_TileMode
     };
 
     virtual ~SkMatrixConvolutionImageFilter();
@@ -59,11 +60,8 @@
                                                   TileMode tileMode,
                                                   bool convolveAlpha,
                                                   SkImageFilter* input = NULL,
-                                                  const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkMatrixConvolutionImageFilter, (kernelSize, kernel, gain, bias,
-                                                           kernelOffset, tileMode, convolveAlpha,
-                                                           input, cropRect));
-    }
+                                                  const CropRect* cropRect = NULL,
+                                                  uint32_t uniqueID = 0);
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixConvolutionImageFilter)
 
@@ -76,8 +74,11 @@
                                    TileMode tileMode,
                                    bool convolveAlpha,
                                    SkImageFilter* input,
-                                   const CropRect* cropRect);
+                                   const CropRect* cropRect,
+                                   uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkMatrixConvolutionImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
@@ -86,10 +87,8 @@
 
 
 #if SK_SUPPORT_GPU
-    virtual bool asNewEffect(GrEffectRef** effect,
-                             GrTexture*,
-                             const SkMatrix& ctm,
-                             const SkIRect& bounds) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+                                     const SkIRect& bounds) const SK_OVERRIDE;
 #endif
 
 private:
diff --git a/include/effects/SkMatrixImageFilter.h b/include/effects/SkMatrixImageFilter.h
index 004c6ef..ae6a0b7 100644
--- a/include/effects/SkMatrixImageFilter.h
+++ b/include/effects/SkMatrixImageFilter.h
@@ -30,7 +30,8 @@
 
     static SkMatrixImageFilter* Create(const SkMatrix& transform,
                                        SkPaint::FilterLevel,
-                                       SkImageFilter* input = NULL);
+                                       SkImageFilter* input = NULL,
+                                       uint32_t uniqueID = 0);
     virtual ~SkMatrixImageFilter();
 
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
@@ -40,8 +41,11 @@
 protected:
     SkMatrixImageFilter(const SkMatrix& transform,
                         SkPaint::FilterLevel,
-                        SkImageFilter* input = NULL);
+                        SkImageFilter* input,
+                        uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkMatrixImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkMergeImageFilter.h b/include/effects/SkMergeImageFilter.h
index 3ac4aaa..5e723aa 100644
--- a/include/effects/SkMergeImageFilter.h
+++ b/include/effects/SkMergeImageFilter.h
@@ -18,25 +18,29 @@
 
     static SkMergeImageFilter* Create(SkImageFilter* first, SkImageFilter* second,
                                       SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
-                                      const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkMergeImageFilter, (first, second, mode, cropRect));
+                                      const CropRect* cropRect = NULL,
+                                      uint32_t uniqueID = 0) {
+        SkImageFilter* inputs[2] = { first, second };
+        SkXfermode::Mode modes[2] = { mode, mode };
+        return SkNEW_ARGS(SkMergeImageFilter, (inputs, 2, modes, cropRect, uniqueID));
     }
     static SkMergeImageFilter* Create(SkImageFilter* filters[], int count,
                                       const SkXfermode::Mode modes[] = NULL,
-                                      const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkMergeImageFilter, (filters, count, modes, cropRect));
+                                      const CropRect* cropRect = NULL,
+                                      uint32_t uniqueID = 0) {
+        return SkNEW_ARGS(SkMergeImageFilter, (filters, count, modes, cropRect, uniqueID));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter)
 
 protected:
-    SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
-                       SkXfermode::Mode = SkXfermode::kSrcOver_Mode,
-                       const CropRect* cropRect = NULL);
     SkMergeImageFilter(SkImageFilter* filters[], int count,
-                       const SkXfermode::Mode modes[] = NULL,
-                       const CropRect* cropRect = NULL);
+                       const SkXfermode::Mode modes[],
+                       const CropRect* cropRect,
+                       uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkMergeImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkMorphologyImageFilter.h b/include/effects/SkMorphologyImageFilter.h
index a464da3..3f2be45 100644
--- a/include/effects/SkMorphologyImageFilter.h
+++ b/include/effects/SkMorphologyImageFilter.h
@@ -30,11 +30,13 @@
 
 protected:
     SkMorphologyImageFilter(int radiusX, int radiusY, SkImageFilter* input,
-                            const CropRect* cropRect);
+                            const CropRect* cropRect, uint32_t uniqueID);
     bool filterImageGeneric(Proc procX, Proc procY,
                             Proxy*, const SkBitmap& src, const Context&,
                             SkBitmap* result, SkIPoint* offset) const;
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkMorphologyImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 #if SK_SUPPORT_GPU
     virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; }
@@ -54,8 +56,12 @@
 public:
     static SkDilateImageFilter* Create(int radiusX, int radiusY,
                                        SkImageFilter* input = NULL,
-                                       const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkDilateImageFilter, (radiusX, radiusY, input, cropRect));
+                                       const CropRect* cropRect = NULL,
+                                       uint32_t uniqueID = 0) {
+        if (radiusX < 0 || radiusY < 0) {
+            return NULL;
+        }
+        return SkNEW_ARGS(SkDilateImageFilter, (radiusX, radiusY, input, cropRect, uniqueID));
     }
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
@@ -68,11 +74,11 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDilateImageFilter)
 
 protected:
-    SkDilateImageFilter(int radiusX, int radiusY,
-                        SkImageFilter* input = NULL,
-                        const CropRect* cropRect = NULL)
-        : INHERITED(radiusX, radiusY, input, cropRect) {}
+    SkDilateImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+        : INHERITED(radiusX, radiusY, input, cropRect, uniqueID) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDilateImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     typedef SkMorphologyImageFilter INHERITED;
@@ -82,8 +88,12 @@
 public:
     static SkErodeImageFilter* Create(int radiusX, int radiusY,
                                       SkImageFilter* input = NULL,
-                                      const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkErodeImageFilter, (radiusX, radiusY, input, cropRect));
+                                      const CropRect* cropRect = NULL,
+                                      uint32_t uniqueID = 0) {
+        if (radiusX < 0 || radiusY < 0) {
+            return NULL;
+        }
+        return SkNEW_ARGS(SkErodeImageFilter, (radiusX, radiusY, input, cropRect, uniqueID));
     }
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
@@ -96,11 +106,11 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkErodeImageFilter)
 
 protected:
-    SkErodeImageFilter(int radiusX, int radiusY,
-                       SkImageFilter* input = NULL,
-                       const CropRect* cropRect = NULL)
-        : INHERITED(radiusX, radiusY, input, cropRect) {}
+    SkErodeImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+        : INHERITED(radiusX, radiusY, input, cropRect, uniqueID) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkErodeImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     typedef SkMorphologyImageFilter INHERITED;
diff --git a/include/effects/SkOffsetImageFilter.h b/include/effects/SkOffsetImageFilter.h
index 7f17e85..a870c0b 100644
--- a/include/effects/SkOffsetImageFilter.h
+++ b/include/effects/SkOffsetImageFilter.h
@@ -16,15 +16,21 @@
 
 public:
     static SkOffsetImageFilter* Create(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL,
-                                       const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkOffsetImageFilter, (dx, dy, input, cropRect));
+                                       const CropRect* cropRect = NULL,
+                                       uint32_t uniqueID = 0) {
+        if (!SkScalarIsFinite(dx) || !SkScalarIsFinite(dy)) {
+            return NULL;
+        }
+        return SkNEW_ARGS(SkOffsetImageFilter, (dx, dy, input, cropRect, uniqueID));
     }
     virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOffsetImageFilter)
 
 protected:
-    SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input, const CropRect* cropRect);
+    SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkOffsetImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkPerlinNoiseShader.h b/include/effects/SkPerlinNoiseShader.h
index 96cad46..2937926 100644
--- a/include/effects/SkPerlinNoiseShader.h
+++ b/include/effects/SkPerlinNoiseShader.h
@@ -23,9 +23,9 @@
     http://www.w3.org/TR/SVG/filters.html#feTurbulenceElement
 */
 class SK_API SkPerlinNoiseShader : public SkShader {
-    struct PaintingData;
 public:
     struct StitchData;
+    struct PaintingData;
 
     /**
      *  About the noise types : the difference between the 2 is just minor tweaks to the algorithm,
@@ -77,7 +77,7 @@
     class PerlinNoiseShaderContext : public SkShader::Context {
     public:
         PerlinNoiseShaderContext(const SkPerlinNoiseShader& shader, const ContextRec&);
-        virtual ~PerlinNoiseShaderContext() {}
+        virtual ~PerlinNoiseShaderContext();
 
         virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
         virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE;
@@ -85,24 +85,27 @@
     private:
         SkPMColor shade(const SkPoint& point, StitchData& stitchData) const;
         SkScalar calculateTurbulenceValueForPoint(
-            int channel, const PaintingData& paintingData,
+            int channel,
             StitchData& stitchData, const SkPoint& point) const;
-        SkScalar noise2D(int channel, const PaintingData& paintingData,
+        SkScalar noise2D(int channel,
                          const StitchData& stitchData, const SkPoint& noiseVector) const;
 
         SkMatrix fMatrix;
+        PaintingData* fPaintingData;
 
         typedef SkShader::Context INHERITED;
     };
 
-    virtual bool asNewEffect(GrContext* context, const SkPaint&, const SkMatrix*, GrColor*,
-                             GrEffectRef**) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrContext* context, const SkPaint&, const SkMatrix*, GrColor*,
+                                     GrFragmentProcessor**) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkPerlinNoiseShader(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
@@ -123,8 +126,6 @@
     /*const*/ SkISize                   fTileSize;
     /*const*/ bool                      fStitchTiles;
 
-    PaintingData* fPaintingData;
-
     typedef SkShader INHERITED;
 };
 
diff --git a/include/effects/SkPictureImageFilter.h b/include/effects/SkPictureImageFilter.h
index fe07215..fbd04f0 100644
--- a/include/effects/SkPictureImageFilter.h
+++ b/include/effects/SkPictureImageFilter.h
@@ -16,23 +16,23 @@
     /**
      *  Refs the passed-in picture.
      */
-    static SkPictureImageFilter* Create(SkPicture* picture) {
-        return SkNEW_ARGS(SkPictureImageFilter, (picture));
+    static SkPictureImageFilter* Create(const SkPicture* picture, int32_t uniqueID = 0) {
+        return SkNEW_ARGS(SkPictureImageFilter, (picture, uniqueID));
     }
 
     /**
      *  Refs the passed-in picture. cropRect can be used to crop or expand the destination rect when
      *  the picture is drawn. (No scaling is implied by the dest rect; only the CTM is applied.)
      */
-    static SkPictureImageFilter* Create(SkPicture* picture, const SkRect& cropRect) {
-        return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect));
+    static SkPictureImageFilter* Create(const SkPicture* picture, const SkRect& cropRect, uint32_t uniqueID = 0) {
+        return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect, uniqueID));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter)
 
 protected:
-    explicit SkPictureImageFilter(SkPicture* picture);
-    SkPictureImageFilter(SkPicture* picture, const SkRect& cropRect);
+    explicit SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID);
+    SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect, uint32_t uniqueID);
     virtual ~SkPictureImageFilter();
     /*  Constructs an SkPictureImageFilter object from an SkReadBuffer.
      *  Note: If the SkPictureImageFilter object construction requires bitmap
@@ -40,7 +40,9 @@
      *  SkReadBuffer::setBitmapDecoder() before calling this constructor.
      *  @param SkReadBuffer Serialized picture data.
      */
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkPictureImageFilter(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
@@ -48,8 +50,8 @@
                                 SkIRect* dst) const SK_OVERRIDE;
 
 private:
-    SkPicture* fPicture;
-    SkRect     fCropRect;
+    const SkPicture* fPicture;
+    SkRect           fCropRect;
     typedef SkImageFilter INHERITED;
 };
 
diff --git a/include/effects/SkPixelXorXfermode.h b/include/effects/SkPixelXorXfermode.h
index 6464845..eb485b4 100644
--- a/include/effects/SkPixelXorXfermode.h
+++ b/include/effects/SkPixelXorXfermode.h
@@ -26,7 +26,9 @@
 
 protected:
     explicit SkPixelXorXfermode(SkColor opColor) : fOpColor(opColor) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkPixelXorXfermode(SkReadBuffer& rb);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     // override from SkXfermode
diff --git a/include/effects/SkRectShaderImageFilter.h b/include/effects/SkRectShaderImageFilter.h
index 817c44e..c4311db 100644
--- a/include/effects/SkRectShaderImageFilter.h
+++ b/include/effects/SkRectShaderImageFilter.h
@@ -28,20 +28,22 @@
     SK_ATTR_DEPRECATED("use Create(SkShader*, const CropRect*)")
     static SkRectShaderImageFilter* Create(SkShader* s, const SkRect& rect);
 
-    static SkRectShaderImageFilter* Create(SkShader* s, const CropRect* rect = NULL);
+    static SkRectShaderImageFilter* Create(SkShader* s, const CropRect* rect = NULL, uint32_t uniqueID = 0);
     virtual ~SkRectShaderImageFilter();
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRectShaderImageFilter)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkRectShaderImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
 
 private:
-    SkRectShaderImageFilter(SkShader* s, const CropRect* rect);
+    SkRectShaderImageFilter(SkShader* s, const CropRect* rect, uint32_t uniqueID = 0);
     SkShader*  fShader;
 
     typedef SkImageFilter INHERITED;
diff --git a/include/effects/SkStippleMaskFilter.h b/include/effects/SkStippleMaskFilter.h
deleted file mode 100644
index 30263a3..0000000
--- a/include/effects/SkStippleMaskFilter.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkStippleMaskFilter_DEFINED
-#define SkStippleMaskFilter_DEFINED
-
-#include "SkMaskFilter.h"
-
-/**
- * Simple MaskFilter that creates a screen door stipple pattern.
- */
-class SK_API SkStippleMaskFilter : public SkMaskFilter {
-public:
-    static SkStippleMaskFilter* Create() {
-        return SkNEW(SkStippleMaskFilter);
-    }
-
-    virtual bool filterMask(SkMask* dst, const SkMask& src,
-                            const SkMatrix& matrix,
-                            SkIPoint* margin) const SK_OVERRIDE;
-
-    // getFormat is from SkMaskFilter
-    virtual SkMask::Format getFormat() const SK_OVERRIDE {
-        return SkMask::kA8_Format;
-    }
-
-    SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkStippleMaskFilter);
-
-protected:
-    SkStippleMaskFilter() : INHERITED() {
-    }
-    explicit SkStippleMaskFilter(SkReadBuffer& buffer)
-        : SkMaskFilter(buffer) {
-    }
-
-private:
-    typedef SkMaskFilter INHERITED;
-};
-
-#endif // SkStippleMaskFilter_DEFINED
diff --git a/include/effects/SkTableMaskFilter.h b/include/effects/SkTableMaskFilter.h
index eda1a1e..8b94179 100644
--- a/include/effects/SkTableMaskFilter.h
+++ b/include/effects/SkTableMaskFilter.h
@@ -55,7 +55,9 @@
 protected:
     SkTableMaskFilter();
     explicit SkTableMaskFilter(const uint8_t table[256]);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkTableMaskFilter(SkReadBuffer& rb);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkTestImageFilters.h b/include/effects/SkTestImageFilters.h
index 4b20936..a8186e0 100644
--- a/include/effects/SkTestImageFilters.h
+++ b/include/effects/SkTestImageFilters.h
@@ -7,15 +7,25 @@
 // Fun mode that scales down (only) and then scales back up to look pixelated
 class SK_API SkDownSampleImageFilter : public SkImageFilter {
 public:
-    static SkDownSampleImageFilter* Create(SkScalar scale) {
-        return SkNEW_ARGS(SkDownSampleImageFilter, (scale));
+    static SkDownSampleImageFilter* Create(SkScalar scale, SkImageFilter* input = NULL) {
+        if (!SkScalarIsFinite(scale)) {
+            return NULL;
+        }
+        // we don't support scale in this range
+        if (scale > SK_Scalar1 || scale <= 0) {
+            return NULL;
+        }
+        return SkNEW_ARGS(SkDownSampleImageFilter, (scale, input));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDownSampleImageFilter)
 
 protected:
-    SkDownSampleImageFilter(SkScalar scale) : INHERITED(0), fScale(scale) {}
+    SkDownSampleImageFilter(SkScalar scale, SkImageFilter* input)
+      : INHERITED(1, &input), fScale(scale) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkDownSampleImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkTileImageFilter.h b/include/effects/SkTileImageFilter.h
index 01d6c64..440337a 100644
--- a/include/effects/SkTileImageFilter.h
+++ b/include/effects/SkTileImageFilter.h
@@ -20,9 +20,7 @@
         @param input    Input from which the subregion defined by srcRect will be tiled
     */
     static SkTileImageFilter* Create(const SkRect& srcRect, const SkRect& dstRect,
-                                     SkImageFilter* input) {
-        return SkNEW_ARGS(SkTileImageFilter, (srcRect, dstRect, input));
-    }
+                                     SkImageFilter* input, uint32_t uniqueID = 0);
 
     virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
                                SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE;
@@ -32,9 +30,11 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTileImageFilter)
 
 protected:
-    SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input)
-        : INHERITED(input), fSrcRect(srcRect), fDstRect(dstRect) {}
+    SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input, uint32_t uniqueID)
+        : INHERITED(1, &input, NULL, uniqueID), fSrcRect(srcRect), fDstRect(dstRect) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkTileImageFilter(SkReadBuffer& buffer);
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
 
diff --git a/include/effects/SkTransparentShader.h b/include/effects/SkTransparentShader.h
index d9a3e5d..e23687c 100644
--- a/include/effects/SkTransparentShader.h
+++ b/include/effects/SkTransparentShader.h
@@ -37,8 +37,13 @@
 protected:
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
+    // we don't need to flatten anything at all
+    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE {}
+
 private:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkTransparentShader(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     typedef SkShader INHERITED;
 };
diff --git a/include/effects/SkXfermodeImageFilter.h b/include/effects/SkXfermodeImageFilter.h
index a5404f9..6736889 100644
--- a/include/effects/SkXfermodeImageFilter.h
+++ b/include/effects/SkXfermodeImageFilter.h
@@ -25,8 +25,10 @@
 
     static SkXfermodeImageFilter* Create(SkXfermode* mode, SkImageFilter* background,
                                          SkImageFilter* foreground = NULL,
-                                         const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkXfermodeImageFilter, (mode, background, foreground, cropRect));
+                                         const CropRect* cropRect = NULL,
+                                         uint32_t uniqueID = 0) {
+        SkImageFilter* inputs[2] = { background, foreground };
+        return SkNEW_ARGS(SkXfermodeImageFilter, (mode, inputs, cropRect, uniqueID));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkXfermodeImageFilter)
@@ -43,9 +45,11 @@
 #endif
 
 protected:
-    SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* background,
-                          SkImageFilter* foreground, const CropRect* cropRect);
+    SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* inputs[2],
+                          const CropRect* cropRect, uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkXfermodeImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/gpu/GrBackendEffectFactory.h b/include/gpu/GrBackendEffectFactory.h
deleted file mode 100644
index 0fc981c..0000000
--- a/include/gpu/GrBackendEffectFactory.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrBackendEffectFactory_DEFINED
-#define GrBackendEffectFactory_DEFINED
-
-#include "GrTypes.h"
-#include "SkTemplates.h"
-#include "SkThread.h"
-#include "SkTypes.h"
-
-/** Given a GrEffect of a particular type, creates the corresponding graphics-backend-specific
-    effect object. Also tracks equivalence of shaders generated via a key. Each factory instance
-    is assigned a generation ID at construction. The ID of the return of GrEffect::getFactory()
-    is used as a type identifier. Thus a GrEffect subclass must return a singleton from
-    getFactory(). GrEffect subclasses should use the derived class GrTBackendEffectFactory that is
-    templated on the GrEffect subclass as their factory object. It requires that the GrEffect
-    subclass has a nested class (or typedef) GLEffect which is its GL implementation and a subclass
-    of GrGLEffect.
- */
-
-class GrEffectRef;
-class GrGLEffect;
-class GrGLCaps;
-class GrDrawEffect;
-
-class GrBackendEffectFactory : SkNoncopyable {
-public:
-    typedef uint32_t EffectKey;
-    enum {
-        kNoEffectKey = 0,
-        kEffectKeyBits = 10,
-        /**
-         * The framework automatically includes coord transforms and texture accesses in their
-         * effect's EffectKey, so effects don't need to account for them in GenKey().
-         */
-        kTextureKeyBits = 4,
-        kTransformKeyBits = 6,
-        kAttribKeyBits = 6,
-        kClassIDBits = 6
-    };
-
-    virtual EffectKey glEffectKey(const GrDrawEffect&, const GrGLCaps&) const = 0;
-    virtual GrGLEffect* createGLInstance(const GrDrawEffect&) const = 0;
-
-    bool operator ==(const GrBackendEffectFactory& b) const {
-        return fEffectClassID == b.fEffectClassID;
-    }
-    bool operator !=(const GrBackendEffectFactory& b) const {
-        return !(*this == b);
-    }
-
-    virtual const char* name() const = 0;
-
-    static EffectKey GetTransformKey(EffectKey key) {
-        return key >> (kEffectKeyBits + kTextureKeyBits) & ((1U << kTransformKeyBits) - 1);
-    }
-
-protected:
-    enum {
-        kIllegalEffectClassID = 0,
-    };
-
-    GrBackendEffectFactory() {
-        fEffectClassID = kIllegalEffectClassID;
-    }
-    virtual ~GrBackendEffectFactory() {}
-
-    static EffectKey GenID() {
-        SkDEBUGCODE(static const int32_t kClassIDBits = 8 * sizeof(EffectKey) -
-                           kTextureKeyBits - kEffectKeyBits - kAttribKeyBits);
-        // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
-        // atomic inc returns the old value not the incremented value. So we add
-        // 1 to the returned value.
-        int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1;
-        SkASSERT(id < (1 << kClassIDBits));
-        return static_cast<EffectKey>(id);
-    }
-
-    EffectKey fEffectClassID;
-
-private:
-    static int32_t fCurrEffectClassID;
-};
-
-#endif
diff --git a/include/gpu/GrBackendProcessorFactory.h b/include/gpu/GrBackendProcessorFactory.h
new file mode 100644
index 0000000..b51a474
--- /dev/null
+++ b/include/gpu/GrBackendProcessorFactory.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrBackendProcessorFactory_DEFINED
+#define GrBackendProcessorFactory_DEFINED
+
+#include "GrTypes.h"
+#include "SkTemplates.h"
+#include "SkThread.h"
+#include "SkTypes.h"
+#include "SkTArray.h"
+
+class GrGLProcessor;
+class GrGLCaps;
+class GrProcessor;
+
+/**
+ * Used by effects to build their keys. It incorporates each per-processor key into a larger shader
+ *  key.
+ */
+class GrProcessorKeyBuilder {
+public:
+    GrProcessorKeyBuilder(SkTArray<unsigned char, true>* data) : fData(data), fCount(0) {
+        SkASSERT(0 == fData->count() % sizeof(uint32_t));
+    }
+
+    void add32(uint32_t v) {
+        ++fCount;
+        fData->push_back_n(4, reinterpret_cast<uint8_t*>(&v));
+    }
+
+    /** Inserts count uint32_ts into the key. The returned pointer is only valid until the next
+        add*() call. */
+    uint32_t* SK_WARN_UNUSED_RESULT add32n(int count) {
+        SkASSERT(count > 0);
+        fCount += count;
+        return reinterpret_cast<uint32_t*>(fData->push_back_n(4 * count));
+    }
+
+    size_t size() const { return sizeof(uint32_t) * fCount; }
+
+private:
+    SkTArray<uint8_t, true>* fData; // unowned ptr to the larger key.
+    int fCount;                     // number of uint32_ts added to fData by the effect.
+};
+
+/**
+ * This class is used to pass the key that was created for a GrGLProcessor back to it
+ * when it emits code. It may allow the emit step to skip calculations that were
+ * performed when computing the key.
+ */
+class GrProcessorKey {
+public:
+    GrProcessorKey(const uint32_t* key, int count) : fKey(key), fCount(count) {
+        SkASSERT(0 == reinterpret_cast<intptr_t>(key) % sizeof(uint32_t));
+    }
+
+    /** Gets the uint32_t values that the effect inserted into the key. */
+    uint32_t get32(int index) const {
+        SkASSERT(index >=0 && index < fCount);
+        return fKey[index];
+    }
+
+    /** Gets the number of uint32_t values that the effect inserted into the key. */
+    int count32() const { return fCount; }
+
+private:
+    const uint32_t* fKey;           // unowned ptr into the larger key.
+    int             fCount;         // number of uint32_ts inserted by the effect into its key.
+};
+
+/**
+ * Given a GrProcessor of a particular type, creates the corresponding graphics-backend-specific
+ * effect object. It also tracks equivalence of shaders generated via a key. The factory for an
+ * effect is accessed via GrProcessor::getFactory(). Each factory instance is assigned an ID at
+ * construction. The ID of GrProcessor::getFactory() is used as a type identifier. Thus, a
+ * GrProcessor subclass must always return the same object from getFactory() and that factory object
+ * must be unique to the GrProcessor subclass (and unique from any further derived subclasses).
+ *
+ * Rather than subclassing this class themselves, it is recommended that GrProcessor authors use 
+ * the templated subclass GrTBackendEffectFactory by writing their getFactory() method as:
+ *
+ * const GrBackendEffectFactory& MyEffect::getFactory() const {
+ *     return GrTBackendEffectFactory<MyEffect>::getInstance();
+ * }
+ *
+ * Using GrTBackendEffectFactory places a few constraints on the effect. See that class's comments.
+ */
+class GrBackendProcessorFactory : SkNoncopyable {
+public:
+    /** 
+     * Generates an effect's key. The key is based on the aspects of the GrProcessor object's
+     * configuration that affect GLSL code generation. Two GrProcessor instances that would cause
+     * this->createGLInstance()->emitCode() to produce different code must produce different keys.
+     */
+    virtual void getGLProcessorKey(const GrProcessor&, const GrGLCaps&,
+                                   GrProcessorKeyBuilder*) const = 0;
+
+    /**
+     * Produces a human-reable name for the effect.
+     */
+    virtual const char* name() const = 0;
+
+    /**
+     * A unique value for every instance of this factory. It is automatically incorporated into the
+     * effect's key. This allows keys generated by getGLProcessorKey() to only be unique within a
+     * GrProcessor subclass and not necessarily across subclasses.
+     */
+    uint32_t effectClassID() const { return fEffectClassID; }
+
+protected:
+    GrBackendProcessorFactory() : fEffectClassID(GenID()) {}
+    virtual ~GrBackendProcessorFactory() {}
+
+private:
+    enum {
+        kIllegalEffectClassID = 0,
+    };
+
+    static uint32_t GenID() {
+        // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
+        // atomic inc returns the old value not the incremented value. So we add
+        // 1 to the returned value.
+        uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&fCurrEffectClassID)) + 1;
+        if (!id) {
+            SkFAIL("This should never wrap as it should only be called once for each GrProcessor "
+                   "subclass.");
+        }
+        return id;
+    }
+
+    const uint32_t fEffectClassID;
+    static int32_t fCurrEffectClassID;
+};
+
+class GrFragmentProcessor;
+class GrGeometryProcessor;
+class GrGLFragmentProcessor;
+class GrGLGeometryProcessor;
+
+/**
+ * Backend processor factory cannot actually create anything, it is up to subclasses to implement
+ * a create binding which matches Gr to GL in a type safe way
+ */
+
+class GrBackendFragmentProcessorFactory : public GrBackendProcessorFactory {
+public:
+    /**
+     * Creates a GrGLProcessor instance that is used both to generate code for the GrProcessor in a
+     * GLSL program and to manage updating uniforms for the program when it is used.
+     */
+    virtual GrGLFragmentProcessor* createGLInstance(const GrFragmentProcessor&) const = 0;
+};
+
+class GrBackendGeometryProcessorFactory : public GrBackendProcessorFactory {
+public:
+    /**
+     * Creates a GrGLProcessor instance that is used both to generate code for the GrProcessor in a
+     * GLSL program and to manage updating uniforms for the program when it is used.
+     */
+    virtual GrGLGeometryProcessor* createGLInstance(const GrGeometryProcessor&) const = 0;
+};
+
+#endif
diff --git a/src/gpu/GrBinHashKey.h b/include/gpu/GrBinHashKey.h
similarity index 100%
rename from src/gpu/GrBinHashKey.h
rename to include/gpu/GrBinHashKey.h
diff --git a/include/gpu/GrCacheable.h b/include/gpu/GrCacheable.h
deleted file mode 100644
index 344ae6b..0000000
--- a/include/gpu/GrCacheable.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrCacheable_DEFINED
-#define GrCacheable_DEFINED
-
-#include "SkRefCnt.h"
-
-class GrResourceCacheEntry;
-
-/**
- * Base class for objects that can be kept in the GrResourceCache.
- */
-class GrCacheable : public SkRefCnt {
-public:
-    SK_DECLARE_INST_COUNT(GrCacheable)
-
-    /**
-     * Retrieves the amount of GPU memory used by this resource in bytes. It is
-     * approximate since we aren't aware of additional padding or copies made
-     * by the driver.
-     *
-     * @return the amount of GPU memory used in bytes
-     */
-    virtual size_t gpuMemorySize() const = 0;
-
-    /**
-     * Checks whether the GPU memory allocated to this resource is still in effect.
-     * It can become invalid if its context is destroyed or lost, in which case it
-     * should no longer count against the GrResourceCache budget.
-     *
-     * @return true if this resource is still holding GPU memory
-     *         false otherwise.
-     */
-    virtual bool isValidOnGpu() const = 0;
-
-    void setCacheEntry(GrResourceCacheEntry* cacheEntry) { fCacheEntry = cacheEntry; }
-    GrResourceCacheEntry* getCacheEntry() { return fCacheEntry; }
-
-    /**
-     * Gets an id that is unique for this GrCacheable object. It is static in that it does
-     * not change when the content of the GrCacheable object changes. This will never return
-     * 0.
-     */
-    uint32_t getGenerationID() const;
-
-protected:
-    GrCacheable()
-        : fCacheEntry(NULL)
-        , fGenID(0) {}
-
-    bool isInCache() const { return NULL != fCacheEntry; }
-
-    /**
-     * This entry point should be called whenever gpuMemorySize() begins
-     * reporting a different size. If the object is in the cache, it will call
-     * gpuMemorySize() immediately and pass the new size on to the resource
-     * cache.
-     */
-    void didChangeGpuMemorySize() const;
-
-private:
-    GrResourceCacheEntry*   fCacheEntry;  // NULL if not in cache
-    mutable uint32_t        fGenID;
-
-    typedef SkRefCnt INHERITED;
-};
-
-#endif
diff --git a/include/gpu/GrClipData.h b/include/gpu/GrClipData.h
index 1dc4b0d..12a23b3 100644
--- a/include/gpu/GrClipData.h
+++ b/include/gpu/GrClipData.h
@@ -35,7 +35,7 @@
             return false;
         }
 
-        if (NULL != fClipStack && NULL != other.fClipStack) {
+        if (fClipStack && other.fClipStack) {
             return *fClipStack == *other.fClipStack;
         }
 
diff --git a/include/gpu/GrColor.h b/include/gpu/GrColor.h
index 1994cc5..4ab709b 100644
--- a/include/gpu/GrColor.h
+++ b/include/gpu/GrColor.h
@@ -88,6 +88,11 @@
     rgba[3] = GrColorUnpackA(color) * ONE_OVER_255;
 }
 
+/** Determines whether the color is opaque or not. */
+static inline bool GrColorIsOpaque(GrColor color) {
+    return (color & (0xFFU << GrColor_SHIFT_A)) == (0xFFU << GrColor_SHIFT_A);
+}
+
 /**
  * Flags used for bitfields of color components. They are defined so that the bit order reflects the
  * GrColor shift order.
@@ -134,18 +139,24 @@
         kRGBA_GrColorComponentFlags,    // kBGRA_8888_GrPixelConfig
         kRGB_GrColorComponentFlags,     // kETC1_GrPixelConfig
         kA_GrColorComponentFlag,        // kLATC_GrPixelConfig
+        kA_GrColorComponentFlag,        // kR11_EAC_GrPixelConfig
+        kRGBA_GrColorComponentFlags,    // kASTC_12x12_GrPixelConfig
+        kRGBA_GrColorComponentFlags,    // kRGBA_float_GrPixelConfig
     };
     return kFlags[config];
 
-    GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig);
-    GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig);
-    GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig);
-    GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig);
-    GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig);
-    GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(7 == kETC1_GrPixelConfig);
-    GR_STATIC_ASSERT(8 == kLATC_GrPixelConfig);
+    GR_STATIC_ASSERT(0  == kUnknown_GrPixelConfig);
+    GR_STATIC_ASSERT(1  == kAlpha_8_GrPixelConfig);
+    GR_STATIC_ASSERT(2  == kIndex_8_GrPixelConfig);
+    GR_STATIC_ASSERT(3  == kRGB_565_GrPixelConfig);
+    GR_STATIC_ASSERT(4  == kRGBA_4444_GrPixelConfig);
+    GR_STATIC_ASSERT(5  == kRGBA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(6  == kBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(7  == kETC1_GrPixelConfig);
+    GR_STATIC_ASSERT(8  == kLATC_GrPixelConfig);
+    GR_STATIC_ASSERT(9  == kR11_EAC_GrPixelConfig);
+    GR_STATIC_ASSERT(10 == kASTC_12x12_GrPixelConfig);
+    GR_STATIC_ASSERT(11 == kRGBA_float_GrPixelConfig);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFlags) == kGrPixelConfigCnt);
 }
 
diff --git a/include/gpu/GrConfig.h b/include/gpu/GrConfig.h
index c0d90a3..86ad63a 100644
--- a/include/gpu/GrConfig.h
+++ b/include/gpu/GrConfig.h
@@ -36,6 +36,10 @@
     #define GR_CACHE_STATS      0
 #endif
 
+#if !defined(GR_GPU_STATS)
+#define GR_GPU_STATS      0
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -232,4 +236,16 @@
     #define GR_STROKE_PATH_RENDERING                 0
 #endif
 
+/**
+ * GR_ALWAYS_ALLOCATE_ON_HEAP determines whether various temporary buffers created
+ * in the GPU backend are always allocated on the heap or are allowed to be
+ * allocated on the stack for smaller memory requests.
+ *
+ * This is only used for memory buffers that are created and then passed through to the
+ * 3D API (e.g. as texture or geometry data)
+ */
+#if !defined(GR_ALWAYS_ALLOCATE_ON_HEAP)
+    #define GR_ALWAYS_ALLOCATE_ON_HEAP 0
+#endif
+
 #endif
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 608ec50..45cd599 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -20,11 +20,10 @@
 
 class GrAARectRenderer;
 class GrAutoScratchTexture;
-class GrCacheable;
 class GrDrawState;
 class GrDrawTarget;
-class GrEffect;
 class GrFontCache;
+class GrFragmentProcessor;
 class GrGpu;
 class GrGpuTraceMarker;
 class GrIndexBuffer;
@@ -36,8 +35,10 @@
 class GrPathRenderer;
 class GrResourceEntry;
 class GrResourceCache;
+class GrResourceCache2;
 class GrStencilBuffer;
 class GrTestTarget;
+class GrTextContext;
 class GrTextureParams;
 class GrVertexBuffer;
 class GrVertexBufferAllocPool;
@@ -49,10 +50,19 @@
 public:
     SK_DECLARE_INST_COUNT(GrContext)
 
+    struct Options {
+        Options() : fDrawPathToCompressedTexture(false) { }
+
+        // EXPERIMENTAL
+        // May be removed in the future, or may become standard depending
+        // on the outcomes of a variety of internal tests.
+        bool fDrawPathToCompressedTexture;
+    };
+
     /**
      * Creates a GrContext for a backend context.
      */
-    static GrContext* Create(GrBackend, GrBackendContext);
+    static GrContext* Create(GrBackend, GrBackendContext, const Options* opts = NULL);
 
     virtual ~GrContext();
 
@@ -85,24 +95,21 @@
     }
 
     /**
-     * Abandons all GPU resources, assumes 3D API state is unknown. Call this
-     * if you have lost the associated GPU context, and thus internal texture,
-     * buffer, etc. references/IDs are now invalid. Should be called even when
-     * GrContext is no longer going to be used for two reasons:
+     * Abandons all GPU resources and assumes the underlying backend 3D API 
+     * context is not longer usable. Call this if you have lost the associated
+     * GPU context, and thus internal texture, buffer, etc. references/IDs are
+     * now invalid. Should be called even when GrContext is no longer going to
+     * be used for two reasons:
      *  1) ~GrContext will not try to free the objects in the 3D API.
-     *  2) If you've created GrGpuObjects that outlive the GrContext they will
-     *     be marked as invalid (GrGpuObjects::isValid()) and won't attempt to
-     *     free their underlying resource in the 3D API.
-     * Content drawn since the last GrContext::flush() may be lost.
+     *  2) Any GrGpuResources created by this GrContext that outlive
+     *     will be marked as invalid (GrGpuResource::wasDestroyed()) and
+     *     when they're destroyed no 3D API calls will be made.
+     * Content drawn since the last GrContext::flush() may be lost. After this
+     * function is called the only valid action on the GrContext or
+     * GrGpuResources it created is to destroy them.
      */
-    void contextLost();
-
-    /**
-     * Similar to contextLost, but makes no attempt to reset state.
-     * Use this method when GrContext destruction is pending, but
-     * the graphics context is destroyed first.
-     */
-    void contextDestroyed();
+    void abandonContext();
+    void contextDestroyed() { this->abandonContext(); }  //  legacy alias
 
     ///////////////////////////////////////////////////////////////////////////
     // Resource Cache
@@ -185,14 +192,24 @@
     /**
      * Stores a custom resource in the cache, based on the specified key.
      */
-    void addResourceToCache(const GrResourceKey&, GrCacheable*);
+    void addResourceToCache(const GrResourceKey&, GrGpuResource*);
 
     /**
      * Finds a resource in the cache, based on the specified key. This is intended for use in
      * conjunction with addResourceToCache(). The return value will be NULL if not found. The
      * caller must balance with a call to unref().
      */
-    GrCacheable* findAndRefCachedResource(const GrResourceKey&);
+    GrGpuResource* findAndRefCachedResource(const GrResourceKey&);
+
+    /**
+     * Creates a new text rendering context that is optimal for the
+     * render target and the context. Caller assumes the ownership
+     * of the returned object. The returned object must be deleted
+     * before the context is destroyed.
+     */
+    GrTextContext* createTextContext(GrRenderTarget*,
+                                     const SkDeviceProperties&,
+                                     bool enableDistanceFieldFonts);
 
     ///////////////////////////////////////////////////////////////////////////
     // Textures
@@ -461,33 +478,26 @@
      *                      Otherwise, if stroke width == 0, then the stroke
      *                      is always a single pixel thick, else the rect is
      *                      mitered/beveled stroked based on stroke width.
-     *                      If the stroke is dashed the rect is sent to drawPath.
-     *  @param matrix       Optional matrix applied to the rect. Applied before
-     *                      context's matrix or the paint's matrix.
      *  The rects coords are used to access the paint (through texture matrix)
      */
     void drawRect(const GrPaint& paint,
                   const SkRect&,
-                  const GrStrokeInfo* strokeInfo = NULL,
-                  const SkMatrix* matrix = NULL);
+                  const GrStrokeInfo* strokeInfo = NULL);
 
     /**
      * Maps a rect of local coordinates onto the a rect of destination
-     * coordinates. Each rect can optionally be transformed. The localRect
-     * is stretched over the dstRect. The dstRect is transformed by the
-     * context's matrix. Additional optional matrices for both rects can be
-     * provided by parameters.
+     * coordinates. The localRect is stretched over the dstRect. The dstRect is
+     * transformed by the context's matrix. An additional optional matrix can be
+     *  provided to transform the local rect.
      *
      * @param paint         describes how to color pixels.
      * @param dstRect       the destination rect to draw.
      * @param localRect     rect of local coordinates to be mapped onto dstRect
-     * @param dstMatrix     Optional matrix to transform dstRect. Applied before context's matrix.
      * @param localMatrix   Optional matrix to transform localRect.
      */
     void drawRectToRect(const GrPaint& paint,
                         const SkRect& dstRect,
                         const SkRect& localRect,
-                        const SkMatrix* dstMatrix = NULL,
                         const SkMatrix* localMatrix = NULL);
 
     /**
@@ -735,7 +745,7 @@
             fContext = context;
         }
         ~AutoRenderTarget() {
-            if (NULL != fContext) {
+            if (fContext) {
                 fContext->setRenderTarget(fPrevTarget);
             }
             SkSafeUnref(fPrevTarget);
@@ -749,7 +759,7 @@
      * Save/restore the view-matrix in the context. It can optionally adjust a paint to account
      * for a coordinate system change. Here is an example of how the paint param can be used:
      *
-     * A GrPaint is setup with GrEffects. The stages will have access to the pre-matrix source
+     * A GrPaint is setup with GrProcessors. The stages will have access to the pre-matrix source
      * geometry positions when the draw is executed. Later on a decision is made to transform the
      * geometry to device space on the CPU. The effects now need to know that the space in which
      * the geometry will be specified has changed.
@@ -769,7 +779,7 @@
          * Initializes by pre-concat'ing the context's current matrix with the preConcat param.
          */
         void setPreConcat(GrContext* context, const SkMatrix& preConcat, GrPaint* paint = NULL) {
-            SkASSERT(NULL != context);
+            SkASSERT(context);
 
             this->restore();
 
@@ -783,11 +793,11 @@
          * update a paint but the matrix cannot be inverted.
          */
         bool setIdentity(GrContext* context, GrPaint* paint = NULL) {
-            SkASSERT(NULL != context);
+            SkASSERT(context);
 
             this->restore();
 
-            if (NULL != paint) {
+            if (paint) {
                 if (!paint->localCoordChangeInverse(context->getMatrix())) {
                     return false;
                 }
@@ -803,7 +813,7 @@
          * required to update a paint but the matrix cannot be inverted.
          */
         bool set(GrContext* context, const SkMatrix& newMatrix, GrPaint* paint = NULL) {
-            if (NULL != paint) {
+            if (paint) {
                 if (!this->setIdentity(context, paint)) {
                     return false;
                 }
@@ -825,7 +835,7 @@
          * performs an incremental update of the paint.
          */
         void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) {
-            if (NULL != paint) {
+            if (paint) {
                 paint->localCoordChange(preConcat);
             }
             fContext->concatMatrix(preConcat);
@@ -835,13 +845,13 @@
          * Returns false if never initialized or the inverse matrix was required to update a paint
          * but the matrix could not be inverted.
          */
-        bool succeeded() const { return NULL != fContext; }
+        bool succeeded() const { return SkToBool(fContext); }
 
         /**
          * If this has been initialized then the context's original matrix is restored.
          */
         void restore() {
-            if (NULL != fContext) {
+            if (fContext) {
                 fContext->setMatrix(fMatrix);
                 fContext = NULL;
             }
@@ -880,7 +890,7 @@
         }
 
         ~AutoClip() {
-            if (NULL != fContext) {
+            if (fContext) {
                 fContext->setClip(fOldClip);
             }
         }
@@ -917,15 +927,11 @@
     GrDrawTarget* getTextTarget();
     const GrIndexBuffer* getQuadIndexBuffer() const;
     GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
+    GrResourceCache2* getResourceCache2() { return fResourceCache2; }
 
     // Called by tests that draw directly to the context via GrDrawTarget
     void getTestTarget(GrTestTarget*);
 
-    // Functions for managing gpu trace markers
-    bool isGpuTracingEnabled() const { return fGpuTracingEnabled; }
-    void enableGpuTracing() { fGpuTracingEnabled = true; }
-    void disableGpuTracing() { fGpuTracingEnabled = false; }
-
     void addGpuTraceMarker(const GrGpuTraceMarker* marker);
     void removeGpuTraceMarker(const GrGpuTraceMarker* marker);
 
@@ -944,10 +950,40 @@
                     GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType,
                     GrPathRendererChain::StencilSupport* stencilSupport = NULL);
 
+    /**
+     *  This returns a copy of the the GrContext::Options that was passed to the
+     *  constructor of this class.
+     */
+    const Options& getOptions() const { return fOptions; }
+
 #if GR_CACHE_STATS
     void printCacheStats() const;
 #endif
 
+    class GPUStats {
+    public:
+#if GR_GPU_STATS
+        GPUStats() { this->reset(); }
+
+        void reset() { fRenderTargetBinds = 0; fShaderCompilations = 0; }
+
+        int renderTargetBinds() const { return fRenderTargetBinds; }
+        void incRenderTargetBinds() { fRenderTargetBinds++; }
+        int shaderCompilations() const { return fShaderCompilations; }
+        void incShaderCompilations() { fShaderCompilations++; }
+    private:
+        int fRenderTargetBinds;
+        int fShaderCompilations;
+#else
+        void incRenderTargetBinds() {}
+        void incShaderCompilations() {}
+#endif
+    };
+
+#if GR_GPU_STATS
+    const GPUStats* gpuStats() const;
+#endif
+
 private:
     // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
     enum BufferedDraw {
@@ -963,6 +999,7 @@
     GrDrawState*                    fDrawState;
 
     GrResourceCache*                fResourceCache;
+    GrResourceCache2*               fResourceCache2;
     GrFontCache*                    fFontCache;
     SkAutoTDelete<GrLayerCache>     fLayerCache;
 
@@ -992,9 +1029,9 @@
 
     int                             fMaxTextureSizeOverride;
 
-    bool                            fGpuTracingEnabled;
+    const Options                   fOptions;
 
-    GrContext(); // init must be called after the constructor.
+    GrContext(const Options&); // init must be called after the constructor.
     bool init(GrBackend, GrBackendContext);
 
     void setupDrawBuffer();
@@ -1018,6 +1055,7 @@
     // addExistingTextureToCache
     friend class GrTexture;
     friend class GrStencilAndCoverPathRenderer;
+    friend class GrStencilAndCoverTextContext;
 
     // Add an existing texture to the texture cache. This is intended solely
     // for use with textures released from an GrAutoScratchTexture.
@@ -1028,12 +1066,8 @@
      * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
      * return NULL.
      */
-    const GrEffectRef* createPMToUPMEffect(GrTexture* texture,
-                                           bool swapRAndB,
-                                           const SkMatrix& matrix);
-    const GrEffectRef* createUPMToPMEffect(GrTexture* texture,
-                                           bool swapRAndB,
-                                           const SkMatrix& matrix);
+    const GrFragmentProcessor* createPMToUPMEffect(GrTexture*, bool swapRAndB, const SkMatrix&);
+    const GrFragmentProcessor* createUPMToPMEffect(GrTexture*, bool swapRAndB, const SkMatrix&);
 
     /**
      *  This callback allows the resource cache to callback into the GrContext
@@ -1041,15 +1075,6 @@
      */
     static bool OverbudgetCB(void* data);
 
-    /** Creates a new gpu path, based on the specified path and stroke and returns it.
-     * The caller owns a ref on the returned path which must be balanced by a call to unref.
-     *
-     * @param skPath the path geometry.
-     * @param stroke the path stroke.
-     * @return a new path or NULL if the operation is not supported by the backend.
-     */
-    GrPath* createPath(const SkPath& skPath, const SkStrokeRec& stroke);
-
     typedef SkRefCnt INHERITED;
 };
 
@@ -1077,7 +1102,7 @@
     }
 
     void reset() {
-        if (NULL != fContext && NULL != fTexture) {
+        if (fContext && fTexture) {
             fContext->unlockScratchTexture(fTexture);
             fTexture->unref();
             fTexture = NULL;
@@ -1107,10 +1132,10 @@
         // The cache also has a ref which we are lending to the caller of detach(). When the caller
         // lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is
         // set and re-ref the texture, thereby restoring the cache's ref.
-        SkASSERT(texture->getRefCnt() > 1);
+        SkASSERT(!texture->unique());
         texture->impl()->setFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit);
         texture->unref();
-        SkASSERT(NULL != texture->getCacheEntry());
+        SkASSERT(texture->getCacheEntry());
 
         return texture;
     }
@@ -1121,7 +1146,7 @@
         this->reset();
 
         fContext = context;
-        if (NULL != fContext) {
+        if (fContext) {
             fTexture = fContext->lockAndRefScratchTexture(desc, match);
             if (NULL == fTexture) {
                 fContext = NULL;
diff --git a/include/gpu/GrContextFactory.h b/include/gpu/GrContextFactory.h
index f09bad9..d78120c 100644
--- a/include/gpu/GrContextFactory.h
+++ b/include/gpu/GrContextFactory.h
@@ -88,26 +88,43 @@
         }
     }
 
-    GrContextFactory() {
-    }
+    explicit GrContextFactory(const GrContext::Options& opts) : fGlobalOptions(opts) { }
+    GrContextFactory() { }
 
     ~GrContextFactory() { this->destroyContexts(); }
 
     void destroyContexts() {
         for (int i = 0; i < fContexts.count(); ++i) {
-            fContexts[i].fGLContext->makeCurrent();
+            if (fContexts[i].fGLContext) {  //  could be abandoned.
+                fContexts[i].fGLContext->makeCurrent();
+            }
             fContexts[i].fGrContext->unref();
-            fContexts[i].fGLContext->unref();
+            if (fContexts[i].fGLContext) {
+                fContexts[i].fGLContext->unref();
+            }
         }
         fContexts.reset();
     }
 
+    void abandonContexts() {
+        for (int i = 0; i < fContexts.count(); ++i) {
+            if (fContexts[i].fGLContext) {
+                fContexts[i].fGLContext->testAbandon();
+                SkSafeSetNull(fContexts[i].fGLContext);
+            }
+            fContexts[i].fGrContext->abandonContext();
+        }
+    }
+
     /**
      * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
      */
-    GrContext* get(GLContextType type) {
-
+    GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard) {
         for (int i = 0; i < fContexts.count(); ++i) {
+            if (forcedGpuAPI != kNone_GrGLStandard &&
+                forcedGpuAPI != fContexts[i].fGLContext->gl()->fStandard)
+                continue;
+
             if (fContexts[i].fType == type) {
                 fContexts[i].fGLContext->makeCurrent();
                 return fContexts[i].fGrContext;
@@ -141,7 +158,7 @@
         if (!glCtx.get()) {
             return NULL;
         }
-        if (!glCtx.get()->init(kBogusSize, kBogusSize)) {
+        if (!glCtx.get()->init(forcedGpuAPI, kBogusSize, kBogusSize)) {
             return NULL;
         }
 
@@ -160,7 +177,7 @@
 
         glCtx->makeCurrent();
         GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get());
-        grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx));
+        grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx, &fGlobalOptions));
         if (!grCtx.get()) {
             return NULL;
         }
@@ -185,13 +202,16 @@
         return NULL;
     }
 
+    const GrContext::Options& getGlobalOptions() const { return fGlobalOptions; }
+
 private:
     struct GPUContext {
         GLContextType             fType;
         SkGLContextHelper*        fGLContext;
         GrContext*                fGrContext;
     };
-    SkTArray<GPUContext, true> fContexts;
+    SkTArray<GPUContext, true>    fContexts;
+    const GrContext::Options      fGlobalOptions;
 };
 
 #endif
diff --git a/include/gpu/GrCoordTransform.h b/include/gpu/GrCoordTransform.h
index f266577..718bbe7 100644
--- a/include/gpu/GrCoordTransform.h
+++ b/include/gpu/GrCoordTransform.h
@@ -8,13 +8,13 @@
 #ifndef GrCoordTransform_DEFINED
 #define GrCoordTransform_DEFINED
 
-#include "GrEffect.h"
+#include "GrProcessor.h"
 #include "SkMatrix.h"
 #include "GrTexture.h"
 #include "GrTypes.h"
 
 /**
- * Coordinates available to GrEffect subclasses for requesting transformations. Transformed
+ * Coordinates available to GrProcessor subclasses for requesting transformations. Transformed
  * coordinates are made available in the the portion of fragment shader emitted by the effect.
  */
 enum GrCoordSet {
@@ -22,21 +22,21 @@
      * The user-space coordinates that map to the fragment being rendered. These coords account for
      * any change of coordinate system done on the CPU by GrContext before rendering, and also are
      * correct for draws that take explicit local coords rather than inferring them from the
-     * primitive's positions (e.g. drawVertices). These are usually the coords a GrEffect wants.
+     * primitive's positions (e.g. drawVertices). These are usually the coords a GrProcessor wants.
      */
     kLocal_GrCoordSet,
 
     /**
      * The actual vertex position. Note that GrContext may not draw using the original view matrix
      * specified by the caller, as it may have transformed vertices into another space. These are
-     * usually not the coordinates a GrEffect wants.
+     * usually not the coordinates a GrProcessor wants.
      */
     kPosition_GrCoordSet
 };
 
 /**
  * A class representing a linear transformation from one of the built-in coordinate sets (local or
- * position). GrEffects just define these transformations, and the framework does the rest of the
+ * position). GrProcessors just define these transformations, and the framework does the rest of the
  * work to make the transformed coordinates available in their fragment shader.
  */
 class GrCoordTransform : SkNoncopyable {
@@ -63,15 +63,15 @@
 
     void reset(GrCoordSet sourceCoords, const GrTexture* texture) {
         SkASSERT(!fInEffect);
-        SkASSERT(NULL != texture);
-        this->reset(sourceCoords, GrEffect::MakeDivByTextureWHMatrix(texture), texture);
+        SkASSERT(texture);
+        this->reset(sourceCoords, MakeDivByTextureWHMatrix(texture), texture);
     }
 
     void reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) {
         SkASSERT(!fInEffect);
         fSourceCoords = sourceCoords;
         fMatrix = m;
-        fReverseY = NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origin();
+        fReverseY = texture && kBottomLeft_GrSurfaceOrigin == texture->origin();
     }
 
     GrCoordTransform& operator= (const GrCoordTransform& other) {
@@ -101,6 +101,15 @@
     const SkMatrix& getMatrix() const { return fMatrix; }
     bool reverseY() const { return fReverseY; }
 
+    /** Useful for effects that want to insert a texture matrix that is implied by the texture
+        dimensions */
+    static inline SkMatrix MakeDivByTextureWHMatrix(const GrTexture* texture) {
+        SkASSERT(texture);
+        SkMatrix mat;
+        mat.setIDiv(texture->width(), texture->height());
+        return mat;
+    }
+
 private:
     GrCoordSet fSourceCoords;
     SkMatrix   fMatrix;
diff --git a/include/gpu/GrDrawEffect.h b/include/gpu/GrDrawEffect.h
deleted file mode 100644
index 9a7a75d..0000000
--- a/include/gpu/GrDrawEffect.h
+++ /dev/null
@@ -1,50 +0,0 @@
-
-#ifndef GrDrawEffect_DEFINED
-#define GrDrawEffect_DEFINED
-
-#include "GrEffectStage.h"
-
-/**
- * This class is used to communicate the particular GrEffect used in a draw to the backend-specific
- * effect subclass (e.g. GrGLEffect). It is used to by the backend-specific class to generate a
- * cache key for the effect, generate code on a program cache miss, and to upload uniform values to
- * the program.
- * In addition to the effect, it also communicates any changes between the relationship between
- * the view matrix and local coordinate system since the effect was installed in its GrDrawState.
- * The typical use case is that sometime after an effect was installed a decision was made to draw
- * in device coordinates (i.e. use an identity view-matrix). In such a case the GrDrawEffect's
- * coord-change-matrix would be the inverse of the view matrix that was set when the effect was
- * installed.
- */
-class GrDrawEffect {
-public:
-    GrDrawEffect(const GrEffectStage& stage, bool explicitLocalCoords)
-        : fEffectStage(&stage)
-        , fExplicitLocalCoords(explicitLocalCoords) {
-        SkASSERT(NULL != fEffectStage);
-        SkASSERT(NULL != fEffectStage->getEffect());
-    }
-    const GrEffectRef* effect() const { return fEffectStage->getEffect(); }
-
-    template <typename T>
-    const T& castEffect() const { return *static_cast<const T*>(this->effect()->get()); }
-
-    const SkMatrix& getCoordChangeMatrix() const {
-        if (fExplicitLocalCoords) {
-            return SkMatrix::I();
-        } else {
-            return fEffectStage->getCoordChangeMatrix();
-        }
-    }
-
-    bool programHasExplicitLocalCoords() const { return fExplicitLocalCoords; }
-
-    const int* getVertexAttribIndices() const { return fEffectStage->getVertexAttribIndices(); }
-    int getVertexAttribIndexCount() const { return fEffectStage->getVertexAttribIndexCount(); }
-
-private:
-    const GrEffectStage*    fEffectStage;
-    bool                    fExplicitLocalCoords;
-};
-
-#endif
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
deleted file mode 100644
index 5fed532..0000000
--- a/include/gpu/GrEffect.h
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrEffect_DEFINED
-#define GrEffect_DEFINED
-
-#include "GrColor.h"
-#include "GrEffectUnitTest.h"
-#include "GrTexture.h"
-#include "GrTextureAccess.h"
-#include "GrTypesPriv.h"
-
-class GrBackendEffectFactory;
-class GrContext;
-class GrCoordTransform;
-class GrEffect;
-class GrVertexEffect;
-class SkString;
-
-/**
- * A Wrapper class for GrEffect. Its ref-count will track owners that may use effects to enqueue
- * new draw operations separately from ownership within a deferred drawing queue. When the
- * GrEffectRef ref count reaches zero the scratch GrResources owned by the effect can be recycled
- * in service of later draws. However, the deferred draw queue may still own direct references to
- * the underlying GrEffect.
- *
- * GrEffectRefs created by new are placed in a per-thread managed pool. The pool is destroyed when
- * the thread ends. Therefore, all dynamically allocated GrEffectRefs must be unreffed before thread
- * termination.
- */
-class GrEffectRef : public SkRefCnt {
-public:
-    SK_DECLARE_INST_COUNT(GrEffectRef);
-    virtual ~GrEffectRef();
-
-    GrEffect* get() { return fEffect; }
-    const GrEffect* get() const { return fEffect; }
-
-    const GrEffect* operator-> () { return fEffect; }
-    const GrEffect* operator-> () const { return fEffect; }
-
-    void* operator new(size_t size);
-    void operator delete(void* target);
-
-    void* operator new(size_t size, void* placement) {
-        return ::operator new(size, placement);
-    }
-    void operator delete(void* target, void* placement) {
-        ::operator delete(target, placement);
-    }
-
-private:
-    friend class GrEffect; // to construct these
-
-    explicit GrEffectRef(GrEffect* effect);
-
-    GrEffect* fEffect;
-
-    typedef SkRefCnt INHERITED;
-};
-
-/** Provides custom vertex shader, fragment shader, uniform data for a particular stage of the
-    Ganesh shading pipeline.
-    Subclasses must have a function that produces a human-readable name:
-        static const char* Name();
-    GrEffect objects *must* be immutable: after being constructed, their fields may not change.
-
-    GrEffect subclass objects should be created by factory functions that return GrEffectRef.
-    There is no public way to wrap a GrEffect in a GrEffectRef. Thus, a factory should be a static
-    member function of a GrEffect subclass.
-
-    Because almost no code should ever handle a GrEffect directly outside of a GrEffectRef, we
-    privately inherit from SkRefCnt to help prevent accidental direct ref'ing/unref'ing of effects.
-
-    Dynamically allocated GrEffects and their corresponding GrEffectRefs are managed by a per-thread
-    memory pool. The ref count of an effect must reach 0 before the thread terminates and the pool
-    is destroyed. To create a static effect use the macro GR_CREATE_STATIC_EFFECT declared below.
-  */
-class GrEffect : private SkRefCnt {
-public:
-    SK_DECLARE_INST_COUNT(GrEffect)
-
-    virtual ~GrEffect();
-
-    /**
-     * This function is used to perform optimizations. When called the color and validFlags params
-     * indicate whether the input components to this effect in the FS will have known values.
-     * validFlags is a bitfield of GrColorComponentFlags. The function updates both params to
-     * indicate known values of its output. A component of the color param only has meaning if the
-     * corresponding bit in validFlags is set.
-     */
-    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const = 0;
-
-    /** Will this effect read the source color value? */
-    bool willUseInputColor() const { return fWillUseInputColor; }
-
-    /** This object, besides creating back-end-specific helper objects, is used for run-time-type-
-        identification. The factory should be an instance of templated class,
-        GrTBackendEffectFactory. It is templated on the subclass of GrEffect. The subclass must have
-        a nested type (or typedef) named GLEffect which will be the subclass of GrGLEffect created
-        by the factory.
-
-        Example:
-        class MyCustomEffect : public GrEffect {
-        ...
-            virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-                return GrTBackendEffectFactory<MyCustomEffect>::getInstance();
-            }
-        ...
-        };
-     */
-    virtual const GrBackendEffectFactory& getFactory() const = 0;
-
-    /** Returns true if this and other effect conservatively draw identically. It can only return
-        true when the two effects are of the same subclass (i.e. they return the same object from
-        from getFactory()).
-
-        A return value of true from isEqual() should not be used to test whether the effects would
-        generate the same shader code. To test for identical code generation use the EffectKey
-        computed by the GrBackendEffectFactory:
-            effectA.getFactory().glEffectKey(effectA) == effectB.getFactory().glEffectKey(effectB).
-     */
-    bool isEqual(const GrEffectRef& other) const {
-        return this->isEqual(*other.get());
-    }
-
-    /** Human-meaningful string to identify this effect; may be embedded
-        in generated shader code. */
-    const char* name() const;
-
-    int numTransforms() const { return fCoordTransforms.count(); }
-
-    /** Returns the coordinate transformation at index. index must be valid according to
-        numTransforms(). */
-    const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
-
-    int numTextures() const { return fTextureAccesses.count(); }
-
-    /** Returns the access pattern for the texture at index. index must be valid according to
-        numTextures(). */
-    const GrTextureAccess& textureAccess(int index) const { return *fTextureAccesses[index]; }
-
-    /** Shortcut for textureAccess(index).texture(); */
-    GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }
-
-    /** Will this effect read the destination pixel value? */
-    bool willReadDstColor() const { return fWillReadDstColor; }
-
-    /** Will this effect read the fragment position? */
-    bool willReadFragmentPosition() const { return fWillReadFragmentPosition; }
-
-    /** Will this effect emit custom vertex shader code?
-        (To set this value the effect must inherit from GrVertexEffect.) */
-    bool hasVertexCode() const { return fHasVertexCode; }
-
-    int numVertexAttribs() const {
-        SkASSERT(0 == fVertexAttribTypes.count() || fHasVertexCode);
-        return fVertexAttribTypes.count();
-    }
-
-    GrSLType vertexAttribType(int index) const { return fVertexAttribTypes[index]; }
-
-    static const int kMaxVertexAttribs = 2;
-
-    /** Useful for effects that want to insert a texture matrix that is implied by the texture
-        dimensions */
-    static inline SkMatrix MakeDivByTextureWHMatrix(const GrTexture* texture) {
-        SkASSERT(NULL != texture);
-        SkMatrix mat;
-        mat.setIDiv(texture->width(), texture->height());
-        return mat;
-    }
-
-    void* operator new(size_t size);
-    void operator delete(void* target);
-
-    void* operator new(size_t size, void* placement) {
-        return ::operator new(size, placement);
-    }
-    void operator delete(void* target, void* placement) {
-        ::operator delete(target, placement);
-    }
-
-    /** These functions are used when recording effects into a deferred drawing queue. The inc call
-        keeps the effect alive outside of GrEffectRef while allowing any resources owned by the
-        effect to be returned to the cache for reuse. The dec call must balance the inc call. */
-    void incDeferredRefCounts() const {
-        this->ref();
-        int count = fTextureAccesses.count();
-        for (int t = 0; t < count; ++t) {
-            fTextureAccesses[t]->getTexture()->incDeferredRefCount();
-        }
-    }
-    void decDeferredRefCounts() const {
-        int count = fTextureAccesses.count();
-        for (int t = 0; t < count; ++t) {
-            fTextureAccesses[t]->getTexture()->decDeferredRefCount();
-        }
-        this->unref();
-    }
-
-protected:
-    /**
-     * Subclasses call this from their constructor to register coordinate transformations. The
-     * effect subclass manages the lifetime of the transformations (this function only stores a
-     * pointer). The GrCoordTransform is typically a member field of the GrEffect subclass. When the
-     * matrix has perspective, the transformed coordinates will have 3 components. Otherwise they'll
-     * have 2. This must only be called from the constructor because GrEffects are immutable.
-     */
-    void addCoordTransform(const GrCoordTransform* coordTransform);
-
-    /**
-     * Subclasses call this from their constructor to register GrTextureAccesses. The effect
-     * subclass manages the lifetime of the accesses (this function only stores a pointer). The
-     * GrTextureAccess is typically a member field of the GrEffect subclass. This must only be
-     * called from the constructor because GrEffects are immutable.
-     */
-    void addTextureAccess(const GrTextureAccess* textureAccess);
-
-    GrEffect()
-        : fWillReadDstColor(false)
-        , fWillReadFragmentPosition(false)
-        , fWillUseInputColor(true)
-        , fHasVertexCode(false)
-        , fEffectRef(NULL) {}
-
-    /** This should be called by GrEffect subclass factories. See the comment on AutoEffectUnref for
-        an example factory function. */
-    static GrEffectRef* CreateEffectRef(GrEffect* effect) {
-        if (NULL == effect->fEffectRef) {
-            effect->fEffectRef = SkNEW_ARGS(GrEffectRef, (effect));
-        } else {
-            effect->fEffectRef->ref();
-        }
-        return effect->fEffectRef;
-    }
-
-    static const GrEffectRef* CreateEffectRef(const GrEffect* effect) {
-        return CreateEffectRef(const_cast<GrEffect*>(effect));
-    }
-
-    /** Used by GR_CREATE_STATIC_EFFECT below */
-    static GrEffectRef* CreateStaticEffectRef(void* refStorage, GrEffect* effect) {
-        SkASSERT(NULL == effect->fEffectRef);
-        effect->fEffectRef = SkNEW_PLACEMENT_ARGS(refStorage, GrEffectRef, (effect));
-        return effect->fEffectRef;
-    }
-
-
-    /** Helper used in subclass factory functions to unref the effect after it has been wrapped in a
-        GrEffectRef. E.g.:
-
-        class EffectSubclass : public GrEffect {
-        public:
-            GrEffectRef* Create(ParamType1 param1, ParamType2 param2, ...) {
-                AutoEffectUnref effect(SkNEW_ARGS(EffectSubclass, (param1, param2, ...)));
-                return CreateEffectRef(effect);
-            }
-     */
-    class AutoEffectUnref {
-    public:
-        AutoEffectUnref(GrEffect* effect) : fEffect(effect) { }
-        ~AutoEffectUnref() { fEffect->unref(); }
-        operator GrEffect*() { return fEffect; }
-    private:
-        GrEffect* fEffect;
-    };
-
-    /** Helper for getting the GrEffect out of a GrEffectRef and down-casting to a GrEffect subclass
-      */
-    template <typename T>
-    static const T& CastEffect(const GrEffect& effectRef) {
-        return *static_cast<const T*>(&effectRef);
-    }
-
-    /**
-     * If the effect subclass will read the destination pixel value then it must call this function
-     * from its constructor. Otherwise, when its generated backend-specific effect class attempts
-     * to generate code that reads the destination pixel it will fail.
-     */
-    void setWillReadDstColor() { fWillReadDstColor = true; }
-
-    /**
-     * If the effect will generate a backend-specific effect that will read the fragment position
-     * in the FS then it must call this method from its constructor. Otherwise, the request to
-     * access the fragment position will be denied.
-     */
-    void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; }
-
-    /**
-     * If the effect will generate a result that does not depend on the input color value then it must
-     * call this function from its constructor. Otherwise, when its generated backend-specific code
-     * might fail during variable binding due to unused variables.
-     */
-    void setWillNotUseInputColor() { fWillUseInputColor = false; }
-
-private:
-    bool isEqual(const GrEffect& other) const {
-        if (&this->getFactory() != &other.getFactory()) {
-            return false;
-        }
-        bool result = this->onIsEqual(other);
-#ifdef SK_DEBUG
-        if (result) {
-            this->assertEquality(other);
-        }
-#endif
-        return result;
-    }
-
-    SkDEBUGCODE(void assertEquality(const GrEffect& other) const;)
-
-    /** Subclass implements this to support isEqual(). It will only be called if it is known that
-        the two effects are of the same subclass (i.e. they return the same object from
-        getFactory()).*/
-    virtual bool onIsEqual(const GrEffect& other) const = 0;
-
-    void EffectRefDestroyed() { fEffectRef = NULL; }
-
-    friend class GrEffectRef;    // to call EffectRefDestroyed()
-    friend class GrEffectStage;  // to rewrap GrEffect in GrEffectRef when restoring an effect-stage
-                                 // from deferred state, to call isEqual on naked GrEffects, and
-                                 // to inc/dec deferred ref counts.
-    friend class GrVertexEffect; // to set fHasVertexCode and build fVertexAttribTypes.
-
-    SkSTArray<4, const GrCoordTransform*, true>  fCoordTransforms;
-    SkSTArray<4, const GrTextureAccess*, true>   fTextureAccesses;
-    SkSTArray<kMaxVertexAttribs, GrSLType, true> fVertexAttribTypes;
-    bool                                         fWillReadDstColor;
-    bool                                         fWillReadFragmentPosition;
-    bool                                         fWillUseInputColor;
-    bool                                         fHasVertexCode;
-    GrEffectRef*                                 fEffectRef;
-
-    typedef SkRefCnt INHERITED;
-};
-
-inline GrEffectRef::GrEffectRef(GrEffect* effect) {
-    SkASSERT(NULL != effect);
-    effect->ref();
-    fEffect = effect;
-}
-
-/**
- * This creates an effect outside of the effect memory pool. The effect's destructor will be called
- * at global destruction time. NAME will be the name of the created GrEffectRef.
- */
-#define GR_CREATE_STATIC_EFFECT(NAME, EFFECT_CLASS, ARGS)                                         \
-enum {                                                                                            \
-    k_##NAME##_EffectRefOffset = GR_CT_ALIGN_UP(sizeof(EFFECT_CLASS), 8),                         \
-    k_##NAME##_StorageSize = k_##NAME##_EffectRefOffset + sizeof(GrEffectRef)                     \
-};                                                                                                \
-static SkAlignedSStorage<k_##NAME##_StorageSize> g_##NAME##_Storage;                              \
-static void* NAME##_RefLocation = (char*)g_##NAME##_Storage.get() + k_##NAME##_EffectRefOffset;   \
-static GrEffect* NAME##_Effect SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), EFFECT_CLASS, ARGS);\
-static SkAutoTDestroy<GrEffect> NAME##_ad(NAME##_Effect);                                         \
-static GrEffectRef* NAME(GrEffect::CreateStaticEffectRef(NAME##_RefLocation, NAME##_Effect));     \
-static SkAutoTDestroy<GrEffectRef> NAME##_Ref_ad(NAME)
-
-
-#endif
diff --git a/include/gpu/GrEffectStage.h b/include/gpu/GrEffectStage.h
deleted file mode 100644
index 8b6cb11..0000000
--- a/include/gpu/GrEffectStage.h
+++ /dev/null
@@ -1,223 +0,0 @@
-
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-
-#ifndef GrEffectStage_DEFINED
-#define GrEffectStage_DEFINED
-
-#include "GrBackendEffectFactory.h"
-#include "GrEffect.h"
-#include "SkMatrix.h"
-#include "GrTypes.h"
-
-#include "SkShader.h"
-
-class GrEffectStage {
-public:
-    explicit GrEffectStage(const GrEffectRef* effectRef, int attrIndex0 = -1, int attrIndex1 = -1)
-    : fEffectRef(SkRef(effectRef)) {
-        fCoordChangeMatrixSet = false;
-        fVertexAttribIndices[0] = attrIndex0;
-        fVertexAttribIndices[1] = attrIndex1;
-    }
-
-    GrEffectStage(const GrEffectStage& other) {
-        *this = other;
-    }
-
-    class DeferredStage;
-    // This constructor balances DeferredStage::saveFrom().
-    explicit GrEffectStage(const DeferredStage& deferredStage) {
-        deferredStage.restoreTo(this);
-    }
-
-    GrEffectStage& operator= (const GrEffectStage& other) {
-        fCoordChangeMatrixSet = other.fCoordChangeMatrixSet;
-        if (other.fCoordChangeMatrixSet) {
-            fCoordChangeMatrix = other.fCoordChangeMatrix;
-        }
-        fEffectRef.reset(SkRef(other.fEffectRef.get()));
-        memcpy(fVertexAttribIndices, other.fVertexAttribIndices, sizeof(fVertexAttribIndices));
-        return *this;
-    }
-
-    bool operator== (const GrEffectStage& other) const {
-        SkASSERT(NULL != fEffectRef.get());
-        SkASSERT(NULL != other.fEffectRef.get());
-
-        if (!(*this->getEffect())->isEqual(*other.getEffect())) {
-            return false;
-        }
-
-        if (fCoordChangeMatrixSet != other.fCoordChangeMatrixSet) {
-            return false;
-        }
-
-        if (!fCoordChangeMatrixSet) {
-            return true;
-        }
-
-        return fCoordChangeMatrix == other.fCoordChangeMatrix;
-    }
-
-    bool operator!= (const GrEffectStage& s) const { return !(*this == s); }
-
-    /**
-     * This is called when the coordinate system in which the geometry is specified will change.
-     *
-     * @param matrix    The transformation from the old coord system in which geometry is specified
-     *                  to the new one from which it will actually be drawn.
-     */
-    void localCoordChange(const SkMatrix& matrix) {
-        if (fCoordChangeMatrixSet) {
-            fCoordChangeMatrix.preConcat(matrix);
-        } else {
-            fCoordChangeMatrixSet = true;
-            fCoordChangeMatrix = matrix;
-        }
-    }
-
-    class SavedCoordChange {
-    private:
-        bool fCoordChangeMatrixSet;
-        SkMatrix fCoordChangeMatrix;
-        SkDEBUGCODE(mutable SkAutoTUnref<const GrEffectRef> fEffectRef;)
-
-        friend class GrEffectStage;
-    };
-
-    /**
-     * This gets the current coordinate system change. It is the accumulation of
-     * localCoordChange calls since the effect was installed. It is used when then caller
-     * wants to temporarily change the source geometry coord system, draw something, and then
-     * restore the previous coord system (e.g. temporarily draw in device coords).
-     */
-    void saveCoordChange(SavedCoordChange* savedCoordChange) const {
-        savedCoordChange->fCoordChangeMatrixSet = fCoordChangeMatrixSet;
-        if (fCoordChangeMatrixSet) {
-            savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
-        }
-        SkASSERT(NULL == savedCoordChange->fEffectRef.get());
-        SkDEBUGCODE(SkRef(fEffectRef.get());)
-        SkDEBUGCODE(savedCoordChange->fEffectRef.reset(fEffectRef.get());)
-    }
-
-    /**
-     * This balances the saveCoordChange call.
-     */
-    void restoreCoordChange(const SavedCoordChange& savedCoordChange) {
-        fCoordChangeMatrixSet = savedCoordChange.fCoordChangeMatrixSet;
-        if (fCoordChangeMatrixSet) {
-            fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix;
-        }
-        SkASSERT(savedCoordChange.fEffectRef.get() == fEffectRef);
-        SkDEBUGCODE(savedCoordChange.fEffectRef.reset(NULL);)
-    }
-
-    /**
-     * Used when storing a deferred GrDrawState. The DeferredStage allows resources owned by its
-     * GrEffect to be recycled through the cache.
-     */
-    class DeferredStage {
-    public:
-        DeferredStage() : fEffect(NULL) {
-            SkDEBUGCODE(fInitialized = false;)
-        }
-
-        ~DeferredStage() {
-            if (NULL != fEffect) {
-                fEffect->decDeferredRefCounts();
-            }
-        }
-
-        void saveFrom(const GrEffectStage& stage) {
-            SkASSERT(!fInitialized);
-            SkASSERT(NULL != stage.fEffectRef.get());
-            stage.fEffectRef->get()->incDeferredRefCounts();
-            fEffect = stage.fEffectRef->get();
-            fCoordChangeMatrixSet = stage.fCoordChangeMatrixSet;
-            if (fCoordChangeMatrixSet) {
-                fCoordChangeMatrix = stage.fCoordChangeMatrix;
-            }
-            fVertexAttribIndices[0] = stage.fVertexAttribIndices[0];
-            fVertexAttribIndices[1] = stage.fVertexAttribIndices[1];
-            SkDEBUGCODE(fInitialized = true;)
-        }
-
-        void restoreTo(GrEffectStage* stage) const {
-            SkASSERT(fInitialized);
-            stage->fEffectRef.reset(GrEffect::CreateEffectRef(fEffect));
-            stage->fCoordChangeMatrixSet = fCoordChangeMatrixSet;
-            if (fCoordChangeMatrixSet) {
-                stage->fCoordChangeMatrix = fCoordChangeMatrix;
-            }
-            stage->fVertexAttribIndices[0] = fVertexAttribIndices[0];
-            stage->fVertexAttribIndices[1] = fVertexAttribIndices[1];
-        }
-
-        bool isEqual(const GrEffectStage& stage, bool ignoreCoordChange) const {
-            if (fVertexAttribIndices[0] != stage.fVertexAttribIndices[0] ||
-                fVertexAttribIndices[1] != stage.fVertexAttribIndices[1]) {
-                return false;
-            }
-
-            if (!(*stage.getEffect())->isEqual(*fEffect)) {
-                return false;
-            }
-
-            if (ignoreCoordChange) {
-                // ignore the coordinate change matrix since there are
-                // explicit uv coordinates
-                return true;
-            }
-
-            if (fCoordChangeMatrixSet != stage.fCoordChangeMatrixSet) {
-                return false;
-            }
-
-            if (!fCoordChangeMatrixSet) {
-                return true;
-            }
-
-            return fCoordChangeMatrix == stage.fCoordChangeMatrix;
-        }
-
-    private:
-        const GrEffect*               fEffect;
-        bool                          fCoordChangeMatrixSet;
-        SkMatrix                      fCoordChangeMatrix;
-        int                           fVertexAttribIndices[2];
-        SkDEBUGCODE(bool fInitialized;)
-    };
-
-    /**
-     * Gets the matrix representing all changes of coordinate system since the GrEffect was
-     * installed in the stage.
-     */
-    const SkMatrix& getCoordChangeMatrix() const {
-        if (fCoordChangeMatrixSet) {
-            return fCoordChangeMatrix;
-        } else {
-            return SkMatrix::I();
-        }
-    }
-
-    const GrEffectRef* getEffect() const { return fEffectRef.get(); }
-
-    const int* getVertexAttribIndices() const { return fVertexAttribIndices; }
-    int getVertexAttribIndexCount() const { return fEffectRef->get()->numVertexAttribs(); }
-
-private:
-    bool                                fCoordChangeMatrixSet;
-    SkMatrix                            fCoordChangeMatrix;
-    SkAutoTUnref<const GrEffectRef>     fEffectRef;
-    int                                 fVertexAttribIndices[2];
-};
-
-#endif
diff --git a/include/gpu/GrEffectUnitTest.h b/include/gpu/GrEffectUnitTest.h
deleted file mode 100644
index f71ab54..0000000
--- a/include/gpu/GrEffectUnitTest.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrEffectUnitTest_DEFINED
-#define GrEffectUnitTest_DEFINED
-
-#include "SkRandom.h"
-#include "SkTArray.h"
-#include "SkTypes.h"
-
-class SkMatrix;
-class GrDrawTargetCaps;
-
-namespace GrEffectUnitTest {
-// Used to access the dummy textures in TestCreate procs.
-enum {
-    kSkiaPMTextureIdx = 0,
-    kAlphaTextureIdx = 1,
-};
-
-/**
- * A helper for use in GrEffect::TestCreate functions.
- */
-const SkMatrix& TestMatrix(SkRandom*);
-
-}
-
-#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
-
-class GrContext;
-class GrEffectRef;
-class GrTexture;
-
-class GrEffectTestFactory : SkNoncopyable {
-public:
-
-    typedef GrEffectRef* (*CreateProc)(SkRandom*,
-                                       GrContext*,
-                                       const GrDrawTargetCaps& caps,
-                                       GrTexture* dummyTextures[]);
-
-    GrEffectTestFactory(CreateProc createProc) {
-        fCreateProc = createProc;
-        GetFactories()->push_back(this);
-    }
-
-    static GrEffectRef* CreateStage(SkRandom* random,
-                                    GrContext* context,
-                                    const GrDrawTargetCaps& caps,
-                                    GrTexture* dummyTextures[]) {
-        uint32_t idx = random->nextRangeU(0, GetFactories()->count() - 1);
-        GrEffectTestFactory* factory = (*GetFactories())[idx];
-        return factory->fCreateProc(random, context, caps, dummyTextures);
-    }
-
-private:
-    CreateProc fCreateProc;
-    static SkTArray<GrEffectTestFactory*, true>* GetFactories();
-};
-
-/** GrEffect subclasses should insert this macro in their declaration to be included in the
- *  program generation unit test.
- */
-#define GR_DECLARE_EFFECT_TEST                                                      \
-    static GrEffectTestFactory gTestFactory;                                        \
-    static GrEffectRef* TestCreate(SkRandom*,                                       \
-                                   GrContext*,                                      \
-                                   const GrDrawTargetCaps&,                         \
-                                   GrTexture* dummyTextures[2])
-
-/** GrEffect subclasses should insert this macro in their implementation file. They must then
- *  also implement this static function:
- *      GrEffect* TestCreate(SkRandom*,
- *                           GrContext*,
- *                           const GrDrawTargetCaps&,
- *                           GrTexture* dummyTextures[2]);
- * dummyTextures[] are valid textures that can optionally be used to construct GrTextureAccesses.
- * The first texture has config kSkia8888_GrPixelConfig and the second has
- * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using
- * the GrContext.
- */
-#define GR_DEFINE_EFFECT_TEST(Effect)                                               \
-    GrEffectTestFactory Effect :: gTestFactory(Effect :: TestCreate)
-
-#else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
-
-// The unit test relies on static initializers. Just declare the TestCreate function so that
-// its definitions will compile.
-#define GR_DECLARE_EFFECT_TEST                                                      \
-    static GrEffectRef* TestCreate(SkRandom*,                                       \
-                                   GrContext*,                                      \
-                                   const GrDrawTargetCaps&,                         \
-                                   GrTexture* dummyTextures[2])
-#define GR_DEFINE_EFFECT_TEST(X)
-
-#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
-#endif
diff --git a/include/gpu/GrFontScaler.h b/include/gpu/GrFontScaler.h
index 0132d51..0376038 100644
--- a/include/gpu/GrFontScaler.h
+++ b/include/gpu/GrFontScaler.h
@@ -9,35 +9,76 @@
 #define GrFontScaler_DEFINED
 
 #include "GrGlyph.h"
-#include "GrKey.h"
+#include "GrTypes.h"
+
+#include "SkDescriptor.h"
 
 class SkPath;
 
-/**
- *  This is a virtual base class which Gr's interface to the host platform's
- *  font scaler.
+/*
+ *  Wrapper class to turn a font cache descriptor into a key 
+ *  for GrFontScaler-related lookups
+ */
+class GrFontDescKey : public SkRefCnt {
+public:
+    SK_DECLARE_INST_COUNT(GrFontDescKey)
+    
+    typedef uint32_t Hash;
+    
+    explicit GrFontDescKey(const SkDescriptor& desc);
+    virtual ~GrFontDescKey();
+    
+    Hash getHash() const { return fHash; }
+    
+    bool operator<(const GrFontDescKey& rh) const {
+        return fHash < rh.fHash || (fHash == rh.fHash && this->lt(rh));
+    }
+    bool operator==(const GrFontDescKey& rh) const {
+        return fHash == rh.fHash && this->eq(rh);
+    }
+    
+private:
+    // helper functions for comparisons
+    bool lt(const GrFontDescKey& rh) const;
+    bool eq(const GrFontDescKey& rh) const;
+    
+    SkDescriptor* fDesc;
+    enum {
+        kMaxStorageInts = 16
+    };
+    uint32_t fStorage[kMaxStorageInts];
+    const Hash fHash;
+    
+    typedef SkRefCnt INHERITED;
+};
+
+/*
+ *  This is Gr's interface to the host platform's font scaler.
  *
- *  The client is responsible for subclassing, and instantiating this. The
- *  instance is created for a specific font+size+matrix.
+ *  The client is responsible for instantiating this. The instance is created 
+ *  for a specific font+size+matrix.
  */
 class GrFontScaler : public SkRefCnt {
 public:
     SK_DECLARE_INST_COUNT(GrFontScaler)
 
-    virtual const GrKey* getKey() = 0;
-    virtual GrMaskFormat getMaskFormat() = 0;
-    virtual bool getPackedGlyphBounds(GrGlyph::PackedID, SkIRect* bounds) = 0;
-    virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
-                                     int rowBytes, void* image) = 0;
-    // get bounds for distance field associated with packed ID
-    virtual bool getPackedGlyphDFBounds(GrGlyph::PackedID, SkIRect* bounds) = 0;
-    // copies distance field bytes into pre-allocated dfImage
-    // (should be width*height bytes in size)
-    virtual bool getPackedGlyphDFImage(GrGlyph::PackedID, int width, int height,
-                                       void* dfImage) = 0;
-    virtual bool getGlyphPath(uint16_t glyphID, SkPath*) = 0;
-
+    explicit GrFontScaler(SkGlyphCache* strike);
+    virtual ~GrFontScaler();
+    
+    const GrFontDescKey* getKey();
+    GrMaskFormat getMaskFormat();
+    bool getPackedGlyphBounds(GrGlyph::PackedID, SkIRect* bounds);
+    bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
+                                     int rowBytes, void* image);
+    bool getPackedGlyphDFBounds(GrGlyph::PackedID, SkIRect* bounds);
+    bool getPackedGlyphDFImage(GrGlyph::PackedID, int width, int height,
+                                       void* image);
+    bool getGlyphPath(uint16_t glyphID, SkPath*);
+    
 private:
+    SkGlyphCache*  fStrike;
+    GrFontDescKey* fKey;
+    
     typedef SkRefCnt INHERITED;
 };
 
diff --git a/include/gpu/GrGeometryProcessor.h b/include/gpu/GrGeometryProcessor.h
new file mode 100644
index 0000000..61659cf
--- /dev/null
+++ b/include/gpu/GrGeometryProcessor.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGeometryProcessor_DEFINED
+#define GrGeometryProcessor_DEFINED
+
+#include "GrProcessor.h"
+class GrBackendGeometryProcessorFactory;
+
+/**
+ * A GrGeomteryProcessor is used to perform computation in the vertex shader and
+ * add support for custom vertex attributes. A GrGemeotryProcessor is typically
+ * tied to the code that does a specific type of high-level primitive rendering
+ * (e.g. anti-aliased circle rendering). The GrGeometryProcessor used for a draw is
+ * specified using GrDrawState. There can only be one geometry processor active for
+ * a draw. The custom vertex attributes required by the geometry processor must be
+ * added to the vertex attribute array specified on the GrDrawState.
+ * GrGeometryProcessor subclasses should be immutable after construction.
+ */
+class GrGeometryProcessor : public GrProcessor {
+public:
+    GrGeometryProcessor() {}
+
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const = 0;
+
+    /*
+     * This only has a max because GLProgramsTest needs to generate test arrays, and these have to
+     * be static
+     * TODO make this truly dynamic
+     */
+    static const int kMaxVertexAttribs = 2;
+    typedef SkTArray<GrShaderVar, true> VertexAttribArray;
+
+    const VertexAttribArray& getVertexAttribs() const { return fVertexAttribs; }
+
+protected:
+    /**
+     * Subclasses call this from their constructor to register vertex attributes (at most
+     * kMaxVertexAttribs). This must only be called from the constructor because GrProcessors are
+     * immutable.
+     */
+    const GrShaderVar& addVertexAttrib(const GrShaderVar& var) {
+        SkASSERT(fVertexAttribs.count() < kMaxVertexAttribs);
+        return fVertexAttribs.push_back(var);
+    }
+
+private:
+    SkSTArray<kMaxVertexAttribs, GrShaderVar, true> fVertexAttribs;
+
+    typedef GrProcessor INHERITED;
+};
+
+/**
+ * This creates an effect outside of the effect memory pool. The effect's destructor will be called
+ * at global destruction time. NAME will be the name of the created GrProcessor.
+ */
+#define GR_CREATE_STATIC_GEOMETRY_PROCESSOR(NAME, GP_CLASS, ARGS)                                 \
+static SkAlignedSStorage<sizeof(GP_CLASS)> g_##NAME##_Storage;                                    \
+static GrGeometryProcessor* NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), GP_CLASS, ARGS);  \
+static SkAutoTDestroy<GrGeometryProcessor> NAME##_ad(NAME);
+
+#endif
diff --git a/include/gpu/GrGlyph.h b/include/gpu/GrGlyph.h
index a7d8341..a379144 100644
--- a/include/gpu/GrGlyph.h
+++ b/include/gpu/GrGlyph.h
@@ -10,6 +10,7 @@
 
 #include "GrRect.h"
 #include "SkPath.h"
+#include "SkChecksum.h"
 
 class GrPlot;
 
@@ -72,7 +73,14 @@
     static inline uint16_t UnpackID(PackedID packed) {
         return (uint16_t)packed;
     }
-};
 
+    static inline const GrGlyph::PackedID& GetKey(const GrGlyph& glyph) {
+        return glyph.fPackedID;
+    }
+
+    static inline uint32_t Hash(GrGlyph::PackedID key) {
+        return SkChecksum::Murmur3(&key, sizeof(key));
+    }
+};
 
 #endif
diff --git a/include/gpu/GrGpuObject.h b/include/gpu/GrGpuObject.h
deleted file mode 100644
index 72d2f89..0000000
--- a/include/gpu/GrGpuObject.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGpuObject_DEFINED
-#define GrGpuObject_DEFINED
-
-#include "GrCacheable.h"
-#include "SkTInternalLList.h"
-
-class GrGpu;
-class GrContext;
-
-/**
- * Base class for the GPU objects created by a GrContext.
- */
-class GrGpuObject : public GrCacheable {
-public:
-    SK_DECLARE_INST_COUNT(GrGpuObject)
-
-    /**
-     * Frees the object in the underlying 3D API. It must be safe to call this
-     * when the object has been previously abandoned.
-     */
-    void release();
-
-    /**
-     * Removes references to objects in the underlying 3D API without freeing
-     * them. Used when the API context has been torn down before the GrContext.
-     */
-    void abandon();
-
-    /**
-     * Tests whether a object has been abandoned or released. All objects will
-     * be in this state after their creating GrContext is destroyed or has
-     * contextLost called. It's up to the client to test wasDestroyed() before
-     * attempting to use an object if it holds refs on objects across
-     * ~GrContext, freeResources with the force flag, or contextLost.
-     *
-     * @return true if the object has been released or abandoned,
-     *         false otherwise.
-     */
-    bool wasDestroyed() const { return NULL == fGpu; }
-
-    /**
-     * Retrieves the context that owns the object. Note that it is possible for
-     * this to return NULL. When objects have been release()ed or abandon()ed
-     * they no longer have an owning context. Destroying a GrContext
-     * automatically releases all its resources.
-     */
-    const GrContext* getContext() const;
-    GrContext* getContext();
-
-    void incDeferredRefCount() const {
-        SkASSERT(fDeferredRefCount >= 0);
-        ++fDeferredRefCount;
-    }
-
-    void decDeferredRefCount() const {
-        SkASSERT(fDeferredRefCount > 0);
-        --fDeferredRefCount;
-        if (0 == fDeferredRefCount && this->needsDeferredUnref()) {
-            SkASSERT(this->getRefCnt() > 1);
-            this->unref();
-        }
-    }
-
-    int getDeferredRefCount() const { return fDeferredRefCount; }
-
-    void setNeedsDeferredUnref() { fFlags |= kDeferredUnref_FlagBit; }
-
-    virtual bool isValidOnGpu() const SK_OVERRIDE { return !this->wasDestroyed(); }
-
-protected:
-    /**
-     * isWrapped indicates we have wrapped a client-created backend object in a GrGpuObject. If it
-     * is true then the client is responsible for the lifetime of the underlying backend object.
-     * Otherwise, our onRelease() should free the object.
-     */
-    GrGpuObject(GrGpu* gpu, bool isWrapped);
-    virtual ~GrGpuObject();
-
-    GrGpu* getGpu() const { return fGpu; }
-
-    // Derived classes should always call their parent class' onRelease
-    // and onAbandon methods in their overrides.
-    virtual void onRelease() {};
-    virtual void onAbandon() {};
-
-    bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
-    bool needsDeferredUnref() const { return SkToBool(kDeferredUnref_FlagBit & fFlags); }
-
-private:
-#ifdef SK_DEBUG
-    friend class GrGpu; // for assert in GrGpu to access getGpu
-#endif
-
-    // We're in an internal doubly linked list
-    SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuObject);
-
-    GrGpu*              fGpu;               // not reffed. The GrGpu can be deleted while there
-                                            // are still live GrGpuObjects. It will call
-                                            // release() on all such objects in its destructor.
-    mutable int         fDeferredRefCount;  // How many references in deferred drawing buffers.
-
-    enum Flags {
-        /**
-         * This object wraps a GPU object given to us by the user.
-         * Lifetime management is left up to the user (i.e., we will not
-         * free it).
-         */
-        kWrapped_FlagBit         = 0x1,
-
-        /**
-         * This texture should be de-refed when the deferred ref count goes
-         * to zero. An object gets into this state when the resource cache
-         * is holding a ref-of-obligation (i.e., someone needs to own it but
-         * no one else wants to) but doesn't really want to keep it around.
-         */
-        kDeferredUnref_FlagBit  = 0x2,
-    };
-    uint32_t         fFlags;
-
-    typedef GrCacheable INHERITED;
-};
-
-#endif
diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h
new file mode 100644
index 0000000..61849e7
--- /dev/null
+++ b/include/gpu/GrGpuResource.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGpuResource_DEFINED
+#define GrGpuResource_DEFINED
+
+#include "SkInstCnt.h"
+#include "SkTInternalLList.h"
+#include "GrResourceKey.h"
+
+class GrResourceCacheEntry;
+class GrResourceCache2;
+class GrGpu;
+class GrContext;
+
+/**
+ * Base class for GrGpuResource. Handles the various types of refs we need. Separated out as a base
+ * class to isolate the ref-cnting behavior and provide friendship without exposing all of
+ * GrGpuResource.
+ * 
+ * Gpu resources can have three types of refs:
+ *   1) Normal ref (+ by ref(), - by unref()): These are used by code that is issuing draw calls
+ *      that read and write the resource via GrDrawTarget and by any object that must own a
+ *      GrGpuResource and is itself owned (directly or indirectly) by Skia-client code.
+ *   2) Pending read (+ by addPendingRead(), - by readCompleted()): GrContext has scheduled a read
+ *      of the resource by the GPU as a result of a skia API call but hasn't executed it yet.
+ *   3) Pending write (+ by addPendingWrite(), - by writeCompleted()): GrContext has scheduled a
+ *      write to the resource by the GPU as a result of a skia API call but hasn't executed it yet.
+ *
+ * The latter two ref types are private and intended only for Gr core code.
+ */
+class GrIORef : public SkNoncopyable {
+public:
+    SK_DECLARE_INST_COUNT_ROOT(GrIORef)
+
+    enum IOType {
+        kRead_IOType,
+        kWrite_IOType,
+        kRW_IOType
+    };
+
+    virtual ~GrIORef();
+
+    // Some of the signatures are written to mirror SkRefCnt so that GrGpuResource can work with
+    // templated helper classes (e.g. SkAutoTUnref). However, we have different categories of
+    // refs (e.g. pending reads). We also don't require thread safety as GrCacheable objects are
+    // not intended to cross thread boundaries.
+    // internal_dispose() exists because of GrTexture's reliance on it. It will be removed
+    // soon.
+    void ref() const {
+        ++fRefCnt;
+        // pre-validate once internal_dispose is removed (and therefore 0 ref cnt is not allowed).
+        this->validate();
+    }
+
+    void unref() const {
+        this->validate();
+        --fRefCnt;
+        if (0 == fRefCnt && 0 == fPendingReads && 0 == fPendingWrites) {
+            this->internal_dispose();
+        }
+    }
+
+    virtual void internal_dispose() const { SkDELETE(this); }
+
+    /** This is exists to service the old mechanism for recycling scratch textures. It will
+        be removed soon. */
+    bool unique() const { return 1 == (fRefCnt + fPendingReads + fPendingWrites); }
+
+    void validate() const {
+#ifdef SK_DEBUG
+        SkASSERT(fRefCnt >= 0);
+        SkASSERT(fPendingReads >= 0);
+        SkASSERT(fPendingWrites >= 0);
+        SkASSERT(fRefCnt + fPendingReads + fPendingWrites > 0);
+#endif
+    }
+
+
+protected:
+    GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) {}
+
+    bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
+    bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
+    bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
+
+private:
+    void addPendingRead() const {
+        this->validate();
+        ++fPendingReads;
+    }
+
+    void completedRead() const {
+        this->validate();
+        --fPendingReads;
+        if (0 == fRefCnt && 0 == fPendingReads && 0 == fPendingWrites) {
+            this->internal_dispose();
+        }
+    }
+
+    void addPendingWrite() const {
+        this->validate();
+        ++fPendingWrites;
+    }
+
+    void completedWrite() const {
+        this->validate();
+        --fPendingWrites;
+        if (0 == fRefCnt && 0 == fPendingReads && 0 == fPendingWrites) {
+            this->internal_dispose();
+        }
+    }
+
+private:
+    mutable int32_t fRefCnt;
+    mutable int32_t fPendingReads;
+    mutable int32_t fPendingWrites;
+
+    // This class is used to manage conversion of refs to pending reads/writes.
+    friend class GrGpuResourceRef;
+    template <typename, IOType> friend class GrPendingIOResource;
+};
+
+/**
+ * Base class for objects that can be kept in the GrResourceCache.
+ */
+class GrGpuResource : public GrIORef {
+public:
+    SK_DECLARE_INST_COUNT(GrGpuResource)
+
+    /**
+     * Frees the object in the underlying 3D API. It must be safe to call this
+     * when the object has been previously abandoned.
+     */
+    void release();
+
+    /**
+     * Removes references to objects in the underlying 3D API without freeing
+     * them. Used when the API context has been torn down before the GrContext.
+     */
+    void abandon();
+
+    /**
+     * Tests whether a object has been abandoned or released. All objects will
+     * be in this state after their creating GrContext is destroyed or has
+     * contextLost called. It's up to the client to test wasDestroyed() before
+     * attempting to use an object if it holds refs on objects across
+     * ~GrContext, freeResources with the force flag, or contextLost.
+     *
+     * @return true if the object has been released or abandoned,
+     *         false otherwise.
+     */
+    bool wasDestroyed() const { return NULL == fGpu; }
+
+    /**
+     * Retrieves the context that owns the object. Note that it is possible for
+     * this to return NULL. When objects have been release()ed or abandon()ed
+     * they no longer have an owning context. Destroying a GrContext
+     * automatically releases all its resources.
+     */
+    const GrContext* getContext() const;
+    GrContext* getContext();
+
+    /**
+     * Retrieves the amount of GPU memory used by this resource in bytes. It is
+     * approximate since we aren't aware of additional padding or copies made
+     * by the driver.
+     *
+     * @return the amount of GPU memory used in bytes
+     */
+    virtual size_t gpuMemorySize() const = 0;
+
+    void setCacheEntry(GrResourceCacheEntry* cacheEntry) { fCacheEntry = cacheEntry; }
+    GrResourceCacheEntry* getCacheEntry() { return fCacheEntry; }
+
+    /** 
+     * If this resource can be used as a scratch resource this returns a valid
+     * scratch key. Otherwise it returns a key for which isNullScratch is true.
+     */
+    const GrResourceKey& getScratchKey() const { return fScratchKey; }
+
+    /**
+     * Gets an id that is unique for this GrGpuResource object. It is static in that it does
+     * not change when the content of the GrGpuResource object changes. This will never return
+     * 0.
+     */
+    uint32_t getUniqueID() const { return fUniqueID; }
+
+protected:
+    // This must be called by every GrGpuObject. It should be called once the object is fully
+    // initialized (i.e. not in a base class constructor).
+    void registerWithCache();
+
+    GrGpuResource(GrGpu*, bool isWrapped);
+    virtual ~GrGpuResource();
+
+    bool isInCache() const { return SkToBool(fCacheEntry); }
+
+    GrGpu* getGpu() const { return fGpu; }
+
+    // Derived classes should always call their parent class' onRelease
+    // and onAbandon methods in their overrides.
+    virtual void onRelease() {};
+    virtual void onAbandon() {};
+
+    bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
+
+    /**
+     * This entry point should be called whenever gpuMemorySize() begins
+     * reporting a different size. If the object is in the cache, it will call
+     * gpuMemorySize() immediately and pass the new size on to the resource
+     * cache.
+     */
+    void didChangeGpuMemorySize() const;
+
+    /**
+     * Optionally called by the GrGpuResource subclass if the resource can be used as scratch.
+     * By default resources are not usable as scratch. This should only be called once.
+     **/
+    void setScratchKey(const GrResourceKey& scratchKey);
+
+private:
+#ifdef SK_DEBUG
+    friend class GrGpu; // for assert in GrGpu to access getGpu
+#endif
+
+    static uint32_t CreateUniqueID();
+
+    // We're in an internal doubly linked list owned by GrResourceCache2
+    SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuResource);
+
+    // This is not ref'ed but abandon() or release() will be called before the GrGpu object
+    // is destroyed. Those calls set will this to NULL.
+    GrGpu* fGpu;
+
+    enum Flags {
+        /**
+         * This object wraps a GPU object given to us by the user.
+         * Lifetime management is left up to the user (i.e., we will not
+         * free it).
+         */
+        kWrapped_FlagBit         = 0x1,
+    };
+
+    uint32_t                fFlags;
+
+    GrResourceCacheEntry*   fCacheEntry;  // NULL if not in cache
+    const uint32_t          fUniqueID;
+
+    GrResourceKey           fScratchKey;
+
+    typedef GrIORef INHERITED;
+};
+
+#endif
diff --git a/include/gpu/GrGpuResourceRef.h b/include/gpu/GrGpuResourceRef.h
new file mode 100644
index 0000000..6b3937b
--- /dev/null
+++ b/include/gpu/GrGpuResourceRef.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGpuResourceRef_DEFINED
+#define GrGpuResourceRef_DEFINED
+
+#include "GrGpuResource.h"
+#include "SkRefCnt.h"
+
+/**
+ * This class is intended only for internal use in core Gr code.
+ *
+ * Class that wraps a resource referenced by a GrProgramElement or GrDrawState. It manages
+ * converting refs to pending IO operations. It allows a resource ownership to be in three
+ * states:
+ *          1. Owns a single ref
+ *          2. Owns a single ref and a pending IO operation (read, write, or read-write)
+ *          3. Owns a single pending IO operation.
+ *
+ * It is legal to destroy the GrGpuResourceRef in any of these states. It starts in state
+ * 1. Calling markPendingIO() converts it from state 1 to state 2. Calling removeRef() goes from
+ * state 2 to state 3. Calling pendingIOComplete() moves from state 2 to state 1. There is no
+ * valid way of going from state 3 back to 2 or 1.
+ *
+ * Like SkAutoTUnref, its constructor and setter adopt a ref from their caller.
+ *
+ * TODO: Once GrDODrawState no longer exists and therefore GrDrawState and GrOptDrawState no
+ * longer share an instance of this class, attempt to make the resource owned by GrGpuResourceRef
+ * only settable via the constructor.
+ */
+class GrGpuResourceRef : SkNoncopyable {
+public:
+    SK_DECLARE_INST_COUNT_ROOT(GrGpuResourceRef);
+
+    ~GrGpuResourceRef();
+
+    GrGpuResource* getResource() const { return fResource; }
+
+    /** Does this object own a pending read or write on the resource it is wrapping. */
+    bool ownsPendingIO() const { return fPendingIO; }
+
+    /** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO
+        is called. */
+    void reset();
+
+protected:
+    GrGpuResourceRef();
+
+    /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
+        pending on the resource when markPendingIO is called. */
+    GrGpuResourceRef(GrGpuResource*, GrIORef::IOType);
+
+    /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
+        pending on the resource when markPendingIO is called. */
+    void setResource(GrGpuResource*, GrIORef::IOType);
+
+private:
+    /** Called by owning GrProgramElement when the program element is first scheduled for
+        execution. It can only be called once. */
+    void markPendingIO() const;
+
+    /** Called when the program element/draw state is no longer owned by GrDrawTarget-client code.
+        This lets the cache know that the drawing code will no longer schedule additional reads or
+        writes to the resource using the program element or draw state. It can only be called once.
+      */
+    void removeRef() const;
+
+    /** Called to indicate that the previous pending IO is complete. Useful when the owning object
+        still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
+        pending executions have been complete. Can only be called if removeRef() was not previously
+        called. */
+    void pendingIOComplete() const;
+
+    friend class GrRODrawState;
+    friend class GrProgramElement;
+
+    GrGpuResource*      fResource;
+    mutable bool        fOwnRef;
+    mutable bool        fPendingIO;
+    GrIORef::IOType     fIOType;
+
+    typedef SkNoncopyable INHERITED;
+};
+
+/** 
+ * Templated version of GrGpuResourceRef to enforce type safety.
+ */
+template <typename T> class GrTGpuResourceRef : public GrGpuResourceRef {
+public:
+    GrTGpuResourceRef() {}
+
+    /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
+        pending on the resource when markPendingIO is called. */
+    GrTGpuResourceRef(T* resource, GrIORef::IOType ioType) : INHERITED(resource, ioType) {}
+
+    T* get() const { return static_cast<T*>(this->getResource()); }
+
+    /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
+        pending on the resource when markPendingIO is called. */
+    void set(T* resource, GrIORef::IOType ioType) { this->setResource(resource, ioType); }
+
+private:
+    typedef GrGpuResourceRef INHERITED;
+};
+
+/**
+ * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
+ * ref.
+ */
+template <typename T, GrIORef::IOType IO_TYPE> class GrPendingIOResource : SkNoncopyable {
+public:
+    GrPendingIOResource(T* resource) : fResource(resource) {
+        if (NULL != fResource) {
+            switch (IO_TYPE) {
+                case GrIORef::kRead_IOType:
+                    fResource->addPendingRead();
+                    break;
+                case GrIORef::kWrite_IOType:
+                    fResource->addPendingWrite();
+                    break;
+                case GrIORef::kRW_IOType:
+                    fResource->addPendingRead();
+                    fResource->addPendingWrite();
+                    break;
+            }
+        }
+    }
+
+    ~GrPendingIOResource() {
+        if (NULL != fResource) {
+            switch (IO_TYPE) {
+                case GrIORef::kRead_IOType:
+                    fResource->completedRead();
+                    break;
+                case GrIORef::kWrite_IOType:
+                    fResource->completedWrite();
+                    break;
+                case GrIORef::kRW_IOType:
+                    fResource->completedRead();
+                    fResource->completedWrite();
+                    break;
+            }
+        }
+    }
+
+    T* get() const { return fResource; }
+
+private:
+    T*      fResource;
+};
+#endif
diff --git a/include/gpu/GrKey.h b/include/gpu/GrKey.h
deleted file mode 100644
index e9d6feb..0000000
--- a/include/gpu/GrKey.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrKey_DEFINED
-#define GrKey_DEFINED
-
-class GrKey : public SkRefCnt {
-public:
-    SK_DECLARE_INST_COUNT(GrKey)
-
-    typedef intptr_t Hash;
-
-    explicit GrKey(Hash hash) : fHash(hash) {}
-
-    intptr_t getHash() const { return fHash; }
-
-    bool operator<(const GrKey& rh) const {
-        return fHash < rh.fHash || (fHash == rh.fHash && this->lt(rh));
-    }
-    bool operator==(const GrKey& rh) const {
-        return fHash == rh.fHash && this->eq(rh);
-    }
-
-protected:
-    virtual bool lt(const GrKey& rh) const = 0;
-    virtual bool eq(const GrKey& rh) const = 0;
-
-private:
-    const Hash fHash;
-
-    typedef SkRefCnt INHERITED;
-};
-
-#endif
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 50a32a5..d0531a3 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -11,7 +11,7 @@
 #define GrPaint_DEFINED
 
 #include "GrColor.h"
-#include "GrEffectStage.h"
+#include "GrProcessorStage.h"
 
 #include "SkXfermode.h"
 
@@ -20,7 +20,7 @@
  * functions and the how color is blended with the destination pixel.
  *
  * The paint allows installation of custom color and coverage stages. New types of stages are
- * created by subclassing GrEffect.
+ * created by subclassing GrProcessor.
  *
  * The primitive color computation starts with the color specified by setColor(). This color is the
  * input to the first color stage. Each color stage feeds its output to the next color stage. The
@@ -39,7 +39,7 @@
  * Note that the coverage is applied after the blend. This is why they are computed as distinct
  * values.
  *
- * TODO: Encapsulate setXfermodeColorFilter in a GrEffect and remove from GrPaint.
+ * TODO: Encapsulate setXfermodeColorFilter in a GrProcessor and remove from GrPaint.
  */
 class GrPaint {
 public:
@@ -85,49 +85,44 @@
     bool isDither() const { return fDither; }
 
     /**
-     * Appends an additional color effect to the color computation.
+     * Appends an additional color processor to the color computation.
      */
-    const GrEffectRef* addColorEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
-        SkASSERT(NULL != effect);
-        if (!(*effect)->willUseInputColor()) {
+    const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* fp) {
+        SkASSERT(fp);
+        if (!fp->willUseInputColor()) {
             fColorStages.reset();
         }
-        SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect, attr0, attr1));
-        return effect;
+        SkNEW_APPEND_TO_TARRAY(&fColorStages, GrProcessorStage, (fp));
+        return fp;
     }
 
     /**
-     * Appends an additional coverage effect to the coverage computation.
+     * Appends an additional coverage processor to the coverage computation.
      */
-    const GrEffectRef* addCoverageEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
-        SkASSERT(NULL != effect);
-        if (!(*effect)->willUseInputColor()) {
+    const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* fp) {
+        SkASSERT(fp);
+        if (!fp->willUseInputColor()) {
             fCoverageStages.reset();
         }
-        SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1));
-        return effect;
+        SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrProcessorStage, (fp));
+        return fp;
     }
 
     /**
      * Helpers for adding color or coverage effects that sample a texture. The matrix is applied
      * to the src space position to compute texture coordinates.
      */
-    void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix);
-    void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix);
-
-    void addColorTextureEffect(GrTexture* texture,
-                               const SkMatrix& matrix,
-                               const GrTextureParams& params);
-    void addCoverageTextureEffect(GrTexture* texture,
-                                  const SkMatrix& matrix,
-                                  const GrTextureParams& params);
+    void addColorTextureProcessor(GrTexture*, const SkMatrix&);
+    void addCoverageTextureProcessor(GrTexture*, const SkMatrix&);
+    void addColorTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
+    void addCoverageTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
 
     int numColorStages() const { return fColorStages.count(); }
     int numCoverageStages() const { return fCoverageStages.count(); }
     int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); }
 
-    const GrEffectStage& getColorStage(int s) const { return fColorStages[s]; }
-    const GrEffectStage& getCoverageStage(int s) const { return fCoverageStages[s]; }
+    const GrFragmentStage& getColorStage(int s) const { return fColorStages[s]; }
+    const GrFragmentStage& getCoverageStage(int s) const { return fCoverageStages[s]; }
 
     GrPaint& operator=(const GrPaint& paint) {
         fSrcBlendCoeff = paint.fSrcBlendCoeff;
@@ -214,9 +209,10 @@
     }
 
     friend class GrContext; // To access above two functions
+    friend class GrStencilAndCoverTextContext;  // To access above two functions
 
-    SkSTArray<4, GrEffectStage> fColorStages;
-    SkSTArray<2, GrEffectStage> fCoverageStages;
+    SkSTArray<4, GrFragmentStage> fColorStages;
+    SkSTArray<2, GrFragmentStage> fCoverageStages;
 
     GrBlendCoeff                fSrcBlendCoeff;
     GrBlendCoeff                fDstBlendCoeff;
diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h
new file mode 100644
index 0000000..7053872
--- /dev/null
+++ b/include/gpu/GrProcessor.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProcessor_DEFINED
+#define GrProcessor_DEFINED
+
+#include "GrBackendProcessorFactory.h"
+#include "GrColor.h"
+#include "GrProcessorUnitTest.h"
+#include "GrProgramElement.h"
+#include "GrShaderVar.h"
+#include "GrTextureAccess.h"
+#include "GrTypesPriv.h"
+#include "SkString.h"
+
+class GrBackendProcessorFactory;
+class GrContext;
+class GrCoordTransform;
+
+/** Provides custom vertex shader, fragment shader, uniform data for a particular stage of the
+    Ganesh shading pipeline.
+    Subclasses must have a function that produces a human-readable name:
+        static const char* Name();
+    GrProcessor objects *must* be immutable: after being constructed, their fields may not change.
+
+    Dynamically allocated GrProcessors are managed by a per-thread memory pool. The ref count of an
+    effect must reach 0 before the thread terminates and the pool is destroyed. To create a static
+    effect use the macro GR_CREATE_STATIC_EFFECT declared below.
+  */
+class GrProcessor : public GrProgramElement {
+public:
+    SK_DECLARE_INST_COUNT(GrProcessor)
+
+    virtual ~GrProcessor();
+
+    /**
+     * This function is used to perform optimizations. When called the color and validFlags params
+     * indicate whether the input components to this effect in the FS will have known values.
+     * validFlags is a bitfield of GrColorComponentFlags. The function updates both params to
+     * indicate known values of its output. A component of the color param only has meaning if the
+     * corresponding bit in validFlags is set.
+     */
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const = 0;
+
+    /** This object, besides creating back-end-specific helper objects, is used for run-time-type-
+        identification. The factory should be an instance of templated class,
+        GrTBackendEffectFactory. It is templated on the subclass of GrProcessor. The subclass must
+        have a nested type (or typedef) named GLProcessor which will be the subclass of
+        GrGLProcessor created by the factory.
+
+        Example:
+        class MyCustomEffect : public GrProcessor {
+        ...
+            virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
+                return GrTBackendEffectFactory<MyCustomEffect>::getInstance();
+            }
+        ...
+        };
+     */
+    virtual const GrBackendProcessorFactory& getFactory() const = 0;
+
+    /** Returns true if this and other effect conservatively draw identically. It can only return
+        true when the two effects are of the same subclass (i.e. they return the same object from
+        from getFactory()).
+
+        A return value of true from isEqual() should not be used to test whether the effects would
+        generate the same shader code. To test for identical code generation use the effects' keys
+        computed by the GrBackendEffectFactory.
+     */
+    bool isEqual(const GrProcessor& other) const {
+        if (&this->getFactory() != &other.getFactory()) {
+            return false;
+        }
+        bool result = this->onIsEqual(other);
+#ifdef SK_DEBUG
+        if (result) {
+            this->assertEquality(other);
+        }
+#endif
+        return result;
+    }
+
+    /** Human-meaningful string to identify this effect; may be embedded
+        in generated shader code. */
+    const char* name() const;
+
+    int numTransforms() const { return fCoordTransforms.count(); }
+
+    /** Returns the coordinate transformation at index. index must be valid according to
+        numTransforms(). */
+    const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
+
+    int numTextures() const { return fTextureAccesses.count(); }
+
+    /** Returns the access pattern for the texture at index. index must be valid according to
+        numTextures(). */
+    const GrTextureAccess& textureAccess(int index) const { return *fTextureAccesses[index]; }
+
+    /** Shortcut for textureAccess(index).texture(); */
+    GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }
+
+    /** Will this effect read the fragment position? */
+    bool willReadFragmentPosition() const { return fWillReadFragmentPosition; }
+
+    void* operator new(size_t size);
+    void operator delete(void* target);
+
+    void* operator new(size_t size, void* placement) {
+        return ::operator new(size, placement);
+    }
+    void operator delete(void* target, void* placement) {
+        ::operator delete(target, placement);
+    }
+
+    /**
+      * Helper for down-casting to a GrProcessor subclass
+      */
+    template <typename T> const T& cast() const { return *static_cast<const T*>(this); }
+
+protected:
+    /**
+     * Subclasses call this from their constructor to register coordinate transformations. The
+     * effect subclass manages the lifetime of the transformations (this function only stores a
+     * pointer). The GrCoordTransform is typically a member field of the GrProcessor subclass. When
+     * the matrix has perspective, the transformed coordinates will have 3 components. Otherwise
+     * they'll have 2. This must only be called from the constructor because GrProcessors are
+     * immutable.
+     */
+    void addCoordTransform(const GrCoordTransform* coordTransform);
+
+    /**
+     * Subclasses call this from their constructor to register GrTextureAccesses. The effect
+     * subclass manages the lifetime of the accesses (this function only stores a pointer). The
+     * GrTextureAccess is typically a member field of the GrProcessor subclass. This must only be
+     * called from the constructor because GrProcessors are immutable.
+     */
+    void addTextureAccess(const GrTextureAccess* textureAccess);
+
+    GrProcessor()
+        : fWillReadFragmentPosition(false) {}
+
+    /**
+     * If the effect will generate a backend-specific effect that will read the fragment position
+     * in the FS then it must call this method from its constructor. Otherwise, the request to
+     * access the fragment position will be denied.
+     */
+    void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; }
+
+private:
+    SkDEBUGCODE(void assertEquality(const GrProcessor& other) const;)
+
+    /** Subclass implements this to support isEqual(). It will only be called if it is known that
+        the two effects are of the same subclass (i.e. they return the same object from
+        getFactory()).*/
+    virtual bool onIsEqual(const GrProcessor& other) const = 0;
+
+    friend class GrGeometryProcessor; // to set fRequiresVertexShader and build fVertexAttribTypes.
+
+    SkSTArray<4, const GrCoordTransform*, true>  fCoordTransforms;
+    SkSTArray<4, const GrTextureAccess*, true>   fTextureAccesses;
+    bool                                         fWillReadFragmentPosition;
+
+    typedef GrProgramElement INHERITED;
+};
+
+class GrFragmentProcessor : public GrProcessor {
+public:
+    GrFragmentProcessor()
+        : INHERITED()
+        , fWillReadDstColor(false)
+        , fWillUseInputColor(true) {}
+
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const = 0;
+
+    /** Will this effect read the destination pixel value? */
+    bool willReadDstColor() const { return fWillReadDstColor; }
+
+    /** Will this effect read the source color value? */
+    bool willUseInputColor() const { return fWillUseInputColor; }
+
+protected:
+    /**
+     * If the effect subclass will read the destination pixel value then it must call this function
+     * from its constructor. Otherwise, when its generated backend-specific effect class attempts
+     * to generate code that reads the destination pixel it will fail.
+     */
+    void setWillReadDstColor() { fWillReadDstColor = true; }
+
+    /**
+     * If the effect will generate a result that does not depend on the input color value then it
+     * must call this function from its constructor. Otherwise, when its generated backend-specific
+     * code might fail during variable binding due to unused variables.
+     */
+    void setWillNotUseInputColor() { fWillUseInputColor = false; }
+
+private:
+    bool                                         fWillReadDstColor;
+    bool                                         fWillUseInputColor;
+
+    typedef GrProcessor INHERITED;
+};
+
+/**
+ * This creates an effect outside of the effect memory pool. The effect's destructor will be called
+ * at global destruction time. NAME will be the name of the created GrProcessor.
+ */
+#define GR_CREATE_STATIC_FRAGMENT_PROCESSOR(NAME, EFFECT_CLASS, ARGS)                             \
+static SkAlignedSStorage<sizeof(EFFECT_CLASS)> g_##NAME##_Storage;                                \
+static GrFragmentProcessor*                                                                       \
+NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), EFFECT_CLASS, ARGS);                          \
+static SkAutoTDestroy<GrFragmentProcessor> NAME##_ad(NAME);
+
+#endif
diff --git a/include/gpu/GrProcessorStage.h b/include/gpu/GrProcessorStage.h
new file mode 100644
index 0000000..1485ca7
--- /dev/null
+++ b/include/gpu/GrProcessorStage.h
@@ -0,0 +1,178 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrProcessorStage_DEFINED
+#define GrProcessorStage_DEFINED
+
+#include "GrBackendProcessorFactory.h"
+#include "GrCoordTransform.h"
+#include "GrProcessor.h"
+#include "GrGeometryProcessor.h"
+#include "GrProgramElementRef.h"
+#include "SkMatrix.h"
+#include "SkShader.h"
+
+// TODO: Make two variations on this class: One for GrDrawState that only owns regular refs
+// and supports compatibility checks and changing local coords. The second is for GrOptDrawState,
+// is immutable, and only owns pending execution refs. This requries removing the common base
+// class from GrDrawState and GrOptDrawState called GrRODrawState and converting to GrOptDrawState
+// when draws are enqueued in the GrInOrderDrawBuffer.
+class GrProcessorStage {
+public:
+    explicit GrProcessorStage(const GrProcessor* proc)
+    : fProc(SkRef(proc)) {
+        fCoordChangeMatrixSet = false;
+    }
+
+    GrProcessorStage(const GrProcessorStage& other) {
+        fCoordChangeMatrixSet = other.fCoordChangeMatrixSet;
+        if (other.fCoordChangeMatrixSet) {
+            fCoordChangeMatrix = other.fCoordChangeMatrix;
+        }
+        fProc.initAndRef(other.fProc);
+    }
+    
+    static bool AreCompatible(const GrProcessorStage& a, const GrProcessorStage& b,
+                              bool usingExplicitLocalCoords) {
+        SkASSERT(a.fProc.get());
+        SkASSERT(b.fProc.get());
+
+        if (!a.getProcessor()->isEqual(*b.getProcessor())) {
+            return false;
+        }
+
+        // We always track the coord change matrix, but it has no effect when explicit local coords
+        // are used.
+        if (usingExplicitLocalCoords) {
+            return true;
+        }
+
+        if (a.fCoordChangeMatrixSet != b.fCoordChangeMatrixSet) {
+            return false;
+        }
+
+        if (!a.fCoordChangeMatrixSet) {
+            return true;
+        }
+
+        return a.fCoordChangeMatrix == b.fCoordChangeMatrix;
+    }
+
+    /**
+     * This is called when the coordinate system in which the geometry is specified will change.
+     *
+     * @param matrix    The transformation from the old coord system in which geometry is specified
+     *                  to the new one from which it will actually be drawn.
+     */
+    void localCoordChange(const SkMatrix& matrix) {
+        if (fCoordChangeMatrixSet) {
+            fCoordChangeMatrix.preConcat(matrix);
+        } else {
+            fCoordChangeMatrixSet = true;
+            fCoordChangeMatrix = matrix;
+        }
+    }
+
+    class SavedCoordChange {
+    public:
+        SkDEBUGCODE(SavedCoordChange() : fEffectUniqueID(SK_InvalidUniqueID) {})
+    private:
+        bool fCoordChangeMatrixSet;
+        SkMatrix fCoordChangeMatrix;
+        SkDEBUGCODE(mutable uint32_t fEffectUniqueID;)
+
+        friend class GrProcessorStage;
+    };
+
+    /**
+     * This gets the current coordinate system change. It is the accumulation of
+     * localCoordChange calls since the effect was installed. It is used when then caller
+     * wants to temporarily change the source geometry coord system, draw something, and then
+     * restore the previous coord system (e.g. temporarily draw in device coords).
+     */
+    void saveCoordChange(SavedCoordChange* savedCoordChange) const {
+        savedCoordChange->fCoordChangeMatrixSet = fCoordChangeMatrixSet;
+        if (fCoordChangeMatrixSet) {
+            savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
+        }
+        SkASSERT(SK_InvalidUniqueID == savedCoordChange->fEffectUniqueID);
+        SkDEBUGCODE(savedCoordChange->fEffectUniqueID = fProc->getUniqueID();)
+    }
+
+    /**
+     * This balances the saveCoordChange call.
+     */
+    void restoreCoordChange(const SavedCoordChange& savedCoordChange) {
+        fCoordChangeMatrixSet = savedCoordChange.fCoordChangeMatrixSet;
+        if (fCoordChangeMatrixSet) {
+            fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix;
+        }
+        SkASSERT(savedCoordChange.fEffectUniqueID == fProc->getUniqueID());
+        SkDEBUGCODE(savedCoordChange.fEffectUniqueID = SK_InvalidUniqueID);
+    }
+
+    /**
+     * Gets the matrix representing all changes of coordinate system since the GrProcessor was
+     * installed in the stage.
+     */
+    const SkMatrix& getCoordChangeMatrix() const {
+        if (fCoordChangeMatrixSet) {
+            return fCoordChangeMatrix;
+        } else {
+            return SkMatrix::I();
+        }
+    }
+
+    bool isPerspectiveCoordTransform(int matrixIndex, bool useExplicitLocalCoords) const {
+        const GrCoordTransform& coordTransform = this->getProcessor()->coordTransform(matrixIndex);
+        SkMatrix::TypeMask type0 = coordTransform.getMatrix().getType();
+        SkMatrix::TypeMask type1 = SkMatrix::kIdentity_Mask;
+        if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
+          type1 = useExplicitLocalCoords ?
+                  SkMatrix::kIdentity_Mask : this->getCoordChangeMatrix().getType();
+        }
+
+        int combinedTypes = type0 | type1;
+        if (SkMatrix::kPerspective_Mask & combinedTypes) {
+          return true;
+        } else {
+          return false;
+        }
+    }
+
+    const GrProcessor* getProcessor() const { return fProc.get(); }
+
+    void convertToPendingExec() { fProc.convertToPendingExec(); }
+
+private:
+    bool                                   fCoordChangeMatrixSet;
+    SkMatrix                               fCoordChangeMatrix;
+    GrProgramElementRef<const GrProcessor> fProc;
+};
+
+class GrFragmentStage : public GrProcessorStage {
+public:
+    GrFragmentStage(const GrFragmentProcessor* fp) : GrProcessorStage(fp) {}
+
+    const GrFragmentProcessor* getFragmentProcessor() const {
+        return static_cast<const GrFragmentProcessor*>(this->getProcessor());
+    }
+};
+
+class GrGeometryStage : public GrProcessorStage {
+public:
+    GrGeometryStage(const GrGeometryProcessor* gp) : GrProcessorStage(gp) {}
+
+    const GrGeometryProcessor* getGeometryProcessor() const {
+        return static_cast<const GrGeometryProcessor*>(this->getProcessor());
+    }
+};
+
+#endif
diff --git a/include/gpu/GrProcessorUnitTest.h b/include/gpu/GrProcessorUnitTest.h
new file mode 100644
index 0000000..04ab2d1
--- /dev/null
+++ b/include/gpu/GrProcessorUnitTest.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProcessorUnitTest_DEFINED
+#define GrProcessorUnitTest_DEFINED
+
+#include "SkRandom.h"
+#include "SkTArray.h"
+#include "SkTypes.h"
+
+class SkMatrix;
+class GrDrawTargetCaps;
+
+namespace GrProcessorUnitTest {
+// Used to access the dummy textures in TestCreate procs.
+enum {
+    kSkiaPMTextureIdx = 0,
+    kAlphaTextureIdx = 1,
+};
+
+/**
+ * A helper for use in GrProcessor::TestCreate functions.
+ */
+const SkMatrix& TestMatrix(SkRandom*);
+
+}
+
+#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+class GrContext;
+class GrProcessor;
+class GrTexture;
+
+template <class Processor>
+class GrProcessorTestFactory : SkNoncopyable {
+public:
+
+    typedef Processor* (*CreateProc)(SkRandom*,
+                                    GrContext*,
+                                    const GrDrawTargetCaps& caps,
+                                    GrTexture* dummyTextures[]);
+
+    GrProcessorTestFactory(CreateProc createProc) {
+        fCreateProc = createProc;
+        GetFactories()->push_back(this);
+    }
+
+    static Processor* CreateStage(SkRandom* random,
+                                 GrContext* context,
+                                 const GrDrawTargetCaps& caps,
+                                 GrTexture* dummyTextures[]) {
+        uint32_t idx = random->nextRangeU(0, GetFactories()->count() - 1);
+        GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx];
+        return factory->fCreateProc(random, context, caps, dummyTextures);
+    }
+
+private:
+    CreateProc fCreateProc;
+
+    #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+    static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories() {
+        static SkTArray<GrProcessorTestFactory<Processor>*, true> gFactories;
+        return &gFactories;
+    }
+    #endif
+};
+
+/** GrProcessor subclasses should insert this macro in their declaration to be included in the
+ *  program generation unit test.
+ */
+
+#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
+    static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory;                               \
+    static GrGeometryProcessor* TestCreate(SkRandom*,                                              \
+                                GrContext*,                                                        \
+                                const GrDrawTargetCaps&,                                           \
+                                GrTexture* dummyTextures[2])
+
+#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
+    static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory;                               \
+    static GrFragmentProcessor* TestCreate(SkRandom*,                                              \
+                                GrContext*,                                                        \
+                                const GrDrawTargetCaps&,                                           \
+                                GrTexture* dummyTextures[2])
+
+/** GrProcessor subclasses should insert this macro in their implementation file. They must then
+ *  also implement this static function:
+ *      GrProcessor* TestCreate(SkRandom*,
+ *                           GrContext*,
+ *                           const GrDrawTargetCaps&,
+ *                           GrTexture* dummyTextures[2]);
+ * dummyTextures[] are valid textures that can optionally be used to construct GrTextureAccesses.
+ * The first texture has config kSkia8888_GrPixelConfig and the second has
+ * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using
+ * the GrContext.
+ */
+#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect)                                                  \
+    GrProcessorTestFactory<GrFragmentProcessor> Effect :: gTestFactory(Effect :: TestCreate)
+
+#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect)                                                  \
+    GrProcessorTestFactory<GrGeometryProcessor> Effect :: gTestFactory(Effect :: TestCreate)
+
+#else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+// The unit test relies on static initializers. Just declare the TestCreate function so that
+// its definitions will compile.
+#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
+    static GrFragmentProcessor* TestCreate(SkRandom*,                                              \
+                                GrContext*,                                                        \
+                                const GrDrawTargetCaps&,                                           \
+                                GrTexture* dummyTextures[2])
+#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
+
+// The unit test relies on static initializers. Just declare the TestCreate function so that
+// its definitions will compile.
+#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
+    static GrGeometryProcessor* TestCreate(SkRandom*,                                              \
+                                GrContext*,                                                        \
+                                const GrDrawTargetCaps&,                                           \
+                                GrTexture* dummyTextures[2])
+#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
+
+#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+#endif
diff --git a/include/gpu/GrProgramElement.h b/include/gpu/GrProgramElement.h
new file mode 100644
index 0000000..245dcd5
--- /dev/null
+++ b/include/gpu/GrProgramElement.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProgramElement_DEFINED
+#define GrProgramElement_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTArray.h"
+
+class GrGpuResourceRef;
+
+/**
+ * Base class for GrProcessor. GrDrawState uses this to manage
+ * transitioning a GrProcessor from being owned by a client to being scheduled for execution. It
+ * converts resources owned by the effect from being ref'ed to having pending reads/writes.
+ *
+ * All GrGpuResource objects owned by a GrProgramElement or derived classes (either directly or
+ * indirectly) must be wrapped in a GrGpuResourceRef and registered with the GrProgramElement using
+ * addGpuResource(). This allows the regular refs to be converted to pending IO events
+ * when the program element is scheduled for deferred execution.
+ */
+class GrProgramElement : public SkNoncopyable {
+public:
+    SK_DECLARE_INST_COUNT_ROOT(GrProgramElement)
+
+    virtual ~GrProgramElement() {
+        // fRefCnt can be one when an effect is created statically using GR_CREATE_STATIC_EFFECT
+        SkASSERT((0 == fRefCnt || 1 == fRefCnt) && 0 == fPendingExecutions);
+        // Set to invalid values.
+        SkDEBUGCODE(fRefCnt = fPendingExecutions = -10;)
+    }
+
+    void ref() const {
+        // Once the ref cnt reaches zero it should never be ref'ed again.
+        SkASSERT(fRefCnt > 0);
+        this->validate();
+        ++fRefCnt;
+    }
+
+    void unref() const {
+        this->validate();
+        --fRefCnt;
+        if (0 == fRefCnt && 0 == fPendingExecutions) {
+            SkDELETE(this);
+        }
+    }
+
+    /**
+     * Gets an id that is unique for this GrProgramElement object. This will never return 0.
+     */
+    uint32_t getUniqueID() const { return fUniqueID; }
+
+    void validate() const {
+#ifdef SK_DEBUG
+        SkASSERT(fRefCnt >= 0);
+        SkASSERT(fPendingExecutions >= 0);
+        SkASSERT(fRefCnt + fPendingExecutions > 0);
+#endif
+    }
+
+protected:
+    GrProgramElement() : fRefCnt(1), fPendingExecutions(0), fUniqueID(CreateUniqueID()) {}
+
+    /** Subclasses registers their resources using this function. It is assumed the GrProgramResouce
+        is and will remain owned by the subclass and this function will retain a raw ptr. Once a
+        GrGpuResourceRef is registered its setResource must not be called.
+     */
+    void addGpuResource(const GrGpuResourceRef* res) {
+        fGpuResources.push_back(res);
+    }
+
+private:
+    static uint32_t CreateUniqueID();
+
+    void convertRefToPendingExecution() const;
+
+    void completedExecution() const;
+
+    mutable int32_t fRefCnt;
+    // Count of deferred executions not yet issued to the 3D API.
+    mutable int32_t fPendingExecutions;
+    uint32_t        fUniqueID;
+
+    SkSTArray<4, const GrGpuResourceRef*, true> fGpuResources;
+
+    // Only this class can access convertRefToPendingExecution() and completedExecution().
+    template <typename T> friend class GrProgramElementRef;
+
+    typedef SkNoncopyable INHERITED;
+};
+
+#endif
diff --git a/include/gpu/GrProgramElementRef.h b/include/gpu/GrProgramElementRef.h
new file mode 100644
index 0000000..ecc8023
--- /dev/null
+++ b/include/gpu/GrProgramElementRef.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProgramElementRef_DEFINED
+#define GrProgramElementRef_DEFINED
+
+#include "SkRefCnt.h"
+#include "GrTypes.h"
+
+/**
+ * Helper for owning a GrProgramElement subclass and being able to convert a ref to pending
+ * execution. It is like an SkAutoTUnref for program elements whose execution can be deferred. Once
+ * in the pending execution state it is illegal to change the object that is owned by the
+ * GrProgramElementRef. Its destructor will either unref the GrProgramElement or signal that
+ * the pending execution has completed, depending on whether convertToPendingExec() was called.
+ */
+template <typename T> class GrProgramElementRef : SkNoncopyable {
+public:
+    GrProgramElementRef() : fOwnPendingExec(false), fObj(NULL) {};
+
+    // Adopts a ref from the caller.
+    explicit GrProgramElementRef(T* obj) : fOwnPendingExec(false), fObj(obj)  {}
+
+    // Adopts a ref from the caller. Do not call after convertToPendingExec.
+    void reset(T* obj) {
+        SkASSERT(!fOwnPendingExec);
+        SkSafeUnref(fObj);
+        fObj = obj;
+    }
+
+    void convertToPendingExec() {
+        SkASSERT(!fOwnPendingExec);
+        fObj->convertRefToPendingExecution();
+        fOwnPendingExec = true;
+    }
+
+    // In the short term we need to support copying a GrProcessorStage and making the copy own
+    // the same type of ref as the source. This function exists to support this. TODO: Once
+    // GrDrawState and GrOptDrawState no longer share a base class they won't have to share
+    // GrProcessorStage and we can have GrOptDrawState always own pending executions rather than
+    // refs on GrProgramElements. At that point we should be able to delete this function.
+    // This function makes assumptions that are valid in the GrProcessorStage use case and should
+    // not be used elsewhere.
+    void initAndRef(const GrProgramElementRef& that) {
+        SkASSERT(!fObj);
+        SkASSERT(that.fObj);
+        if (that.fOwnPendingExec) {
+            SkASSERT(that.fObj->fPendingExecutions > 0);
+            that.fObj->fPendingExecutions++;
+        } else {
+            that.fObj->ref();
+        }
+        this->fOwnPendingExec = that.fOwnPendingExec;
+        this->fObj = that.fObj;
+    }
+
+    T* get() const { return fObj; }
+    operator T*() { return fObj; }
+
+    /** If T is const, the type returned from operator-> will also be const. */
+    typedef typename SkTConstType<typename SkAutoTUnref<T>::template BlockRef<T>,
+                                  SkTIsConst<T>::value>::type BlockRefType;
+
+    /**
+     * GrProgramElementRef assumes ownership of the ref and manages converting the ref to a
+     * pending execution. As a result, it is an error for the user to ref or unref through
+     * GrProgramElementRef. Therefore operator-> returns BlockRef<T>*.
+     */
+    BlockRefType *operator->() const {
+        return static_cast<BlockRefType*>(fObj);
+    }
+
+    ~GrProgramElementRef() {
+        if (fObj) {
+            if (fOwnPendingExec) {
+                fObj->completedExecution();
+            } else {
+                fObj->unref();
+            }
+        }
+    }
+
+private:
+    bool fOwnPendingExec;
+    T*   fObj;
+
+    typedef SkNoncopyable INHERITED;
+};
+#endif
diff --git a/include/gpu/GrRect.h b/include/gpu/GrRect.h
index ddb23b5..14130f8 100644
--- a/include/gpu/GrRect.h
+++ b/include/gpu/GrRect.h
@@ -20,6 +20,18 @@
         return r;
     }
 
+    static GrIRect16 SK_WARN_UNUSED_RESULT MakeWH(int16_t w, int16_t h) {
+        GrIRect16 r;
+        r.set(0, 0, w, h);
+        return r;
+    }
+
+    static GrIRect16 SK_WARN_UNUSED_RESULT MakeXYWH(int16_t x, int16_t y, int16_t w, int16_t h) {
+        GrIRect16 r;
+        r.set(x, y, x + w, y + h);
+        return r;
+    }
+
     int width() const { return fRight - fLeft; }
     int height() const { return fBottom - fTop; }
     int area() const { return this->width() * this->height(); }
@@ -27,6 +39,13 @@
 
     void setEmpty() { memset(this, 0, sizeof(*this)); }
 
+    void set(int16_t left, int16_t top, int16_t right, int16_t bottom) {
+        fLeft = left;
+        fTop = top;
+        fRight = right;
+        fBottom = bottom;
+    }
+
     void set(const SkIRect& r) {
         fLeft   = SkToS16(r.fLeft);
         fTop    = SkToS16(r.fTop);
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index 6a3f26f..4c5ec18 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -162,7 +162,7 @@
     friend class GrTexture;
     // called by ~GrTexture to remove the non-ref'ed back ptr.
     void owningTextureDestroyed() {
-        SkASSERT(NULL != fTexture);
+        SkASSERT(fTexture);
         fTexture = NULL;
     }
 
diff --git a/include/gpu/GrResourceKey.h b/include/gpu/GrResourceKey.h
new file mode 100644
index 0000000..d3e82c8
--- /dev/null
+++ b/include/gpu/GrResourceKey.h
@@ -0,0 +1,113 @@
+
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrResourceKey_DEFINED
+#define GrResourceKey_DEFINED
+
+#include "GrTypes.h"
+#include "GrBinHashKey.h"
+
+class GrResourceKey {
+public:
+    static GrCacheID::Domain ScratchDomain() {
+        static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain();
+        return gDomain;
+    }
+
+    /** Uniquely identifies the GrGpuResource subclass in the key to avoid collisions
+        across resource types. */
+    typedef uint8_t ResourceType;
+
+    /** Flags set by the GrGpuResource subclass. */
+    typedef uint8_t ResourceFlags;
+
+    /** Generate a unique ResourceType */
+    static ResourceType GenerateResourceType();
+
+    /** Creates a key for resource */
+    GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
+        this->init(id.getDomain(), id.getKey(), type, flags);
+    };
+
+    GrResourceKey(const GrResourceKey& src) { fKey = src.fKey; }
+
+    GrResourceKey() { fKey.reset(); }
+
+    void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
+        this->init(id.getDomain(), id.getKey(), type, flags);
+    }
+
+    uint32_t getHash() const { return fKey.getHash(); }
+
+    bool isScratch() const {
+        return ScratchDomain() ==
+            *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() +
+                                                        kCacheIDDomainOffset);
+    }
+
+    ResourceType getResourceType() const {
+        return *reinterpret_cast<const ResourceType*>(fKey.getData() +
+                                                      kResourceTypeOffset);
+    }
+
+    ResourceFlags getResourceFlags() const {
+        return *reinterpret_cast<const ResourceFlags*>(fKey.getData() +
+                                                       kResourceFlagsOffset);
+    }
+
+    bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; }
+
+    // A key indicating that the resource is not usable as a scratch resource.
+    static GrResourceKey& NullScratchKey() {
+        static const GrCacheID::Key kBogusKey = { { {0} } };
+        static GrCacheID kBogusID(ScratchDomain(), kBogusKey);
+        static GrResourceKey kNullScratchKey(kBogusID, NoneResourceType(), 0);
+        return kNullScratchKey;
+    }
+
+    bool isNullScratch() const {
+        return this->isScratch() && NoneResourceType() == this->getResourceType();
+    }
+
+private:
+    enum {
+        kCacheIDKeyOffset = 0,
+        kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key),
+        kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain),
+        kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType),
+        kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags),
+        kKeySize = SkAlign4(kPadOffset),
+        kPadSize = kKeySize - kPadOffset
+    };
+
+    static ResourceType NoneResourceType() {
+        static const ResourceType gNoneResourceType = GenerateResourceType();
+        return gNoneResourceType;
+    }
+
+    void init(const GrCacheID::Domain domain,
+              const GrCacheID::Key& key,
+              ResourceType type,
+              ResourceFlags flags) {
+        union {
+            uint8_t  fKey8[kKeySize];
+            uint32_t fKey32[kKeySize / 4];
+        } keyData;
+
+        uint8_t* k = keyData.fKey8;
+        memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key));
+        memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain));
+        memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType));
+        memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags));
+        memset(k + kPadOffset, 0, kPadSize);
+        fKey.setKeyData(keyData.fKey32);
+    }
+    GrBinHashKey<kKeySize> fKey;
+};
+
+#endif
diff --git a/include/gpu/GrShaderVar.h b/include/gpu/GrShaderVar.h
new file mode 100644
index 0000000..cbc074d
--- /dev/null
+++ b/include/gpu/GrShaderVar.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrShaderVar_DEFINED
+#define GrShaderVar_DEFINED
+
+#include "GrTypesPriv.h"
+#include "SkString.h"
+
+class GrShaderVar {
+public:
+    /**
+     * Early versions of GLSL have Varying and Attribute; those are later
+     * deprecated, but we still need to know whether a Varying variable
+     * should be treated as In or Out.
+     *
+     * TODO This really shouldn't live here, but until we have c++11, there is really no good way
+     * to write extensible enums.  In reality, only none, out, in, inout, and uniform really
+     * make sense on this base class
+     */
+    enum TypeModifier {
+        kNone_TypeModifier,
+        kOut_TypeModifier,
+        kIn_TypeModifier,
+        kInOut_TypeModifier,
+        kUniform_TypeModifier,
+        // GL Specific types below
+        kAttribute_TypeModifier,
+        kVaryingIn_TypeModifier,
+        kVaryingOut_TypeModifier
+    };
+
+    enum Precision {
+        kLow_Precision,         // lowp
+        kMedium_Precision,      // mediump
+        kHigh_Precision,        // highp
+        kDefault_Precision,     // Default for the current context. We make
+                                // fragment shaders default to mediump on ES2
+                                // because highp support is not guaranteed (and
+                                // we haven't been motivated to test for it).
+                                // Otherwise, highp.
+    };
+
+    /**
+     * Defaults to a float with no precision specifier
+     */
+    GrShaderVar()
+        : fType(kFloat_GrSLType)
+        , fTypeModifier(kNone_TypeModifier)
+        , fCount(kNonArray)
+        , fPrecision(kDefault_Precision) {
+    }
+
+    GrShaderVar(const SkString& name, GrSLType type, int arrayCount = kNonArray,
+                Precision precision = kDefault_Precision)
+        : fType(type)
+        , fTypeModifier(kNone_TypeModifier)
+        , fName(name)
+        , fCount(arrayCount)
+        , fPrecision(precision) {
+        SkASSERT(kVoid_GrSLType != type);
+    }
+
+    GrShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
+                  Precision precision = kDefault_Precision)
+        : fType(type)
+        , fTypeModifier(kNone_TypeModifier)
+        , fName(name)
+        , fCount(arrayCount)
+        , fPrecision(precision) {
+        SkASSERT(kVoid_GrSLType != type);
+    }
+
+    GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
+                  int arrayCount = kNonArray, Precision precision = kDefault_Precision)
+        : fType(type)
+        , fTypeModifier(typeModifier)
+        , fName(name)
+        , fCount(arrayCount)
+        , fPrecision(precision) {
+        SkASSERT(kVoid_GrSLType != type);
+    }
+
+    /**
+     * Values for array count that have special meaning. We allow 1-sized arrays.
+     */
+    enum {
+        kNonArray     =  0, // not an array
+        kUnsizedArray = -1, // an unsized array (declared with [])
+    };
+
+    /**
+     * Sets as a non-array.
+     */
+    void set(GrSLType type,
+             TypeModifier typeModifier,
+             const SkString& name,
+             Precision precision = kDefault_Precision) {
+        SkASSERT(kVoid_GrSLType != type);
+        fType = type;
+        fTypeModifier = typeModifier;
+        fName = name;
+        fCount = kNonArray;
+        fPrecision = precision;
+    }
+
+    /**
+     * Sets as a non-array.
+     */
+    void set(GrSLType type,
+             TypeModifier typeModifier,
+             const char* name,
+             Precision precision = kDefault_Precision) {
+        SkASSERT(kVoid_GrSLType != type);
+        fType = type;
+        fTypeModifier = typeModifier;
+        fName = name;
+        fCount = kNonArray;
+        fPrecision = precision;
+    }
+
+    /**
+     * Set all var options
+     */
+    void set(GrSLType type,
+             TypeModifier typeModifier,
+             const SkString& name,
+             int count,
+             Precision precision = kDefault_Precision) {
+        SkASSERT(kVoid_GrSLType != type);
+        fType = type;
+        fTypeModifier = typeModifier;
+        fName = name;
+        fCount = count;
+        fPrecision = precision;
+    }
+
+    /**
+     * Set all var options
+     */
+    void set(GrSLType type,
+             TypeModifier typeModifier,
+             const char* name,
+             int count,
+             Precision precision = kDefault_Precision) {
+        SkASSERT(kVoid_GrSLType != type);
+        fType = type;
+        fTypeModifier = typeModifier;
+        fName = name;
+        fCount = count;
+        fPrecision = precision;
+    }
+
+    /**
+     * Is the var an array.
+     */
+    bool isArray() const { return kNonArray != fCount; }
+    /**
+     * Is this an unsized array, (i.e. declared with []).
+     */
+    bool isUnsizedArray() const { return kUnsizedArray == fCount; }
+    /**
+     * Get the array length of the var.
+     */
+    int getArrayCount() const { return fCount; }
+    /**
+     * Set the array length of the var
+     */
+    void setArrayCount(int count) { fCount = count; }
+    /**
+     * Set to be a non-array.
+     */
+    void setNonArray() { fCount = kNonArray; }
+    /**
+     * Set to be an unsized array.
+     */
+    void setUnsizedArray() { fCount = kUnsizedArray; }
+
+    /**
+     * Access the var name as a writable string
+     */
+    SkString* accessName() { return &fName; }
+    /**
+     * Set the var name
+     */
+    void setName(const SkString& n) { fName = n; }
+    void setName(const char* n) { fName = n; }
+
+    /**
+     * Get the var name.
+     */
+    const SkString& getName() const { return fName; }
+
+    /**
+     * Shortcut for this->getName().c_str();
+     */
+    const char* c_str() const { return this->getName().c_str(); }
+
+    /**
+     * Get the type of the var
+     */
+    GrSLType getType() const { return fType; }
+    /**
+     * Set the type of the var
+     */
+    void setType(GrSLType type) { fType = type; }
+
+    TypeModifier getTypeModifier() const { return fTypeModifier; }
+    void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
+
+    /**
+     * Get the precision of the var
+     */
+    Precision getPrecision() const { return fPrecision; }
+
+    /**
+     * Set the precision of the var
+     */
+    void setPrecision(Precision p) { fPrecision = p; }
+
+protected:
+    GrSLType        fType;
+    TypeModifier    fTypeModifier;
+    SkString        fName;
+    int             fCount;
+    Precision       fPrecision;
+};
+
+#endif
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index a851c9e..24eb39a 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -10,14 +10,14 @@
 #define GrSurface_DEFINED
 
 #include "GrTypes.h"
-#include "GrGpuObject.h"
+#include "GrGpuResource.h"
 #include "SkRect.h"
 
 class GrTexture;
 class GrRenderTarget;
 struct SkImageInfo;
 
-class GrSurface : public GrGpuObject {
+class GrSurface : public GrGpuResource {
 public:
     SK_DECLARE_INST_COUNT(GrSurface);
 
@@ -80,11 +80,11 @@
      */
     bool isSameAs(const GrSurface* other) const {
         const GrRenderTarget* thisRT = this->asRenderTarget();
-        if (NULL != thisRT) {
+        if (thisRT) {
             return thisRT == other->asRenderTarget();
         } else {
             const GrTexture* thisTex = this->asTexture();
-            SkASSERT(NULL != thisTex); // We must be one or the other
+            SkASSERT(thisTex); // We must be one or the other
             return thisTex == other->asTexture();
         }
     }
@@ -135,6 +135,10 @@
      */
     bool savePixels(const char* filename);
 
+    bool hasPendingRead() const;
+    bool hasPendingWrite() const;
+    bool hasPendingIO() const;
+
 protected:
     GrSurface(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
     : INHERITED(gpu, isWrapped)
@@ -144,7 +148,7 @@
     GrTextureDesc fDesc;
 
 private:
-    typedef GrGpuObject INHERITED;
+    typedef GrGpuResource INHERITED;
 };
 
 #endif // GrSurface_DEFINED
diff --git a/include/gpu/GrTBackendEffectFactory.h b/include/gpu/GrTBackendEffectFactory.h
deleted file mode 100644
index fd14b4f..0000000
--- a/include/gpu/GrTBackendEffectFactory.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrTBackendEffectFactory_DEFINED
-#define GrTBackendEffectFactory_DEFINED
-
-#include "GrBackendEffectFactory.h"
-#include "GrDrawEffect.h"
-#include "gl/GrGLProgramEffects.h"
-
-/**
- * Implements GrBackendEffectFactory for a GrEffect subclass as a singleton.
- */
-template <typename EffectClass>
-class GrTBackendEffectFactory : public GrBackendEffectFactory {
-
-public:
-    typedef typename EffectClass::GLEffect GLEffect;
-
-    /** Returns a human-readable name that is accessible via GrEffect or
-        GrGLEffect and is consistent between the two of them.
-     */
-    virtual const char* name() const SK_OVERRIDE { return EffectClass::Name(); }
-
-    /** Returns a value that identifies the GLSL shader code generated by
-        a GrEffect. This enables caching of generated shaders. Part of the
-        id identifies the GrEffect subclass. The remainder is based
-        on the aspects of the GrEffect object's configuration that affect
-        GLSL code generation. */
-    virtual EffectKey glEffectKey(const GrDrawEffect& drawEffect,
-                                  const GrGLCaps& caps) const SK_OVERRIDE {
-        SkASSERT(kIllegalEffectClassID != fEffectClassID);
-        EffectKey effectKey = GLEffect::GenKey(drawEffect, caps);
-        EffectKey textureKey = GrGLProgramEffects::GenTextureKey(drawEffect, caps);
-        EffectKey transformKey = GrGLProgramEffects::GenTransformKey(drawEffect);
-        EffectKey attribKey = GrGLProgramEffects::GenAttribKey(drawEffect);
-#ifdef SK_DEBUG
-        static const EffectKey kIllegalEffectKeyMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
-        SkASSERT(!(kIllegalEffectKeyMask & effectKey));
-
-        static const EffectKey kIllegalTextureKeyMask = (uint16_t) (~((1U << kTextureKeyBits) - 1));
-        SkASSERT(!(kIllegalTextureKeyMask & textureKey));
-
-        static const EffectKey kIllegalTransformKeyMask = (uint16_t) (~((1U << kTransformKeyBits) - 1));
-        SkASSERT(!(kIllegalTransformKeyMask & transformKey));
-
-        static const EffectKey kIllegalAttribKeyMask = (uint16_t) (~((1U << kAttribKeyBits) - 1));
-        SkASSERT(!(kIllegalAttribKeyMask & textureKey));
-
-        static const EffectKey kIllegalClassIDMask = (uint16_t) (~((1U << kClassIDBits) - 1));
-        SkASSERT(!(kIllegalClassIDMask & fEffectClassID));
-#endif
-        return (fEffectClassID << (kEffectKeyBits+kTextureKeyBits+kTransformKeyBits+kAttribKeyBits)) |
-               (attribKey << (kEffectKeyBits+kTextureKeyBits+kTransformKeyBits)) |
-               (transformKey << (kEffectKeyBits+kTextureKeyBits)) |
-               (textureKey << kEffectKeyBits) |
-               (effectKey);
-    }
-
-    /** Returns a new instance of the appropriate *GL* implementation class
-        for the given GrEffect; caller is responsible for deleting
-        the object. */
-    virtual GrGLEffect* createGLInstance(const GrDrawEffect& drawEffect) const SK_OVERRIDE {
-        return SkNEW_ARGS(GLEffect, (*this, drawEffect));
-    }
-
-    /** This class is a singleton. This function returns the single instance.
-     */
-    static const GrBackendEffectFactory& getInstance() {
-        static SkAlignedSTStorage<1, GrTBackendEffectFactory> gInstanceMem;
-        static const GrTBackendEffectFactory* gInstance;
-        if (!gInstance) {
-            gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
-                                        GrTBackendEffectFactory);
-        }
-        return *gInstance;
-    }
-
-protected:
-    GrTBackendEffectFactory() {
-        fEffectClassID = GenID();
-    }
-};
-
-#endif
diff --git a/include/gpu/GrTBackendProcessorFactory.h b/include/gpu/GrTBackendProcessorFactory.h
new file mode 100644
index 0000000..c67f508
--- /dev/null
+++ b/include/gpu/GrTBackendProcessorFactory.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTBackendProcessorFactory_DEFINED
+#define GrTBackendProcessorFactory_DEFINED
+
+#include "GrBackendProcessorFactory.h"
+#include "gl/GrGLProgramEffects.h"
+
+/**
+ * Implements GrBackendEffectFactory for a GrProcessor subclass as a singleton. This can be used by
+ * most GrProcessor subclasses to implement the GrProcessor::getFactory() method:
+ *
+ * const GrBackendEffectFactory& MyEffect::getFactory() const {
+ *     return GrTBackendEffectFactory<MyEffect>::getInstance();
+ * }
+ *
+ * Using this class requires that the GrProcessor subclass always produces the same GrGLProcessor
+ * subclass. Additionally, it adds the following requirements to the GrProcessor and GrGLProcessor
+ * subclasses:
+ *
+ * 1. The GrGLProcessor used by GrProcessor subclass MyEffect must be named or typedef'ed to
+ *    MyEffect::GLProcessor.
+ * 2. MyEffect::GLProcessor must have a static function:
+ *      EffectKey GenKey(const GrProcessor, const GrGLCaps&)
+ *    which generates a key that maps 1 to 1 with code variations emitted by
+ *    MyEffect::GLProcessor::emitCode().
+ * 3. MyEffect must have a static function:
+ *      const char* Name()
+ *    which returns a human-readable name for the effect.
+ */
+template <class ProcessorClass, class BackEnd, class ProcessorBase, class GLProcessorBase>
+class GrTBackendProcessorFactory : public BackEnd {
+public:
+    typedef typename ProcessorClass::GLProcessor GLProcessor;
+
+    /** Returns a human-readable name for the effect. Implemented using GLProcessor::Name as
+     *  described in this class's comment. */
+    virtual const char* name() const SK_OVERRIDE { return ProcessorClass::Name(); }
+
+
+    /** Implemented using GLProcessor::GenKey as described in this class's comment. */
+    virtual void getGLProcessorKey(const GrProcessor& effect,
+                                   const GrGLCaps& caps,
+                                   GrProcessorKeyBuilder* b) const SK_OVERRIDE {
+        GLProcessor::GenKey(effect, caps, b);
+    }
+
+    /** Returns a new instance of the appropriate *GL* implementation class
+        for the given GrProcessor; caller is responsible for deleting
+        the object. */
+    virtual GLProcessorBase* createGLInstance(const ProcessorBase& effect) const SK_OVERRIDE {
+        return SkNEW_ARGS(GLProcessor, (*this, effect));
+    }
+
+    /** This class is a singleton. This function returns the single instance. */
+    static const BackEnd& getInstance() {
+        static SkAlignedSTStorage<1, GrTBackendProcessorFactory> gInstanceMem;
+        static const GrTBackendProcessorFactory* gInstance;
+        if (!gInstance) {
+            gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
+                                        GrTBackendProcessorFactory);
+        }
+        return *gInstance;
+    }
+
+protected:
+    GrTBackendProcessorFactory() {}
+};
+
+/*
+ * Every effect so far derives from one of the following subclasses of GrTBackendProcessorFactory.
+ * All of this machinery is necessary to ensure that creatGLInstace is typesafe and does not
+ * require any casting
+ */
+template <class ProcessorClass>
+class GrTBackendGeometryProcessorFactory
+        : public GrTBackendProcessorFactory<ProcessorClass,
+                                            GrBackendGeometryProcessorFactory,
+                                            GrGeometryProcessor,
+                                            GrGLGeometryProcessor> {
+protected:
+    GrTBackendGeometryProcessorFactory() {}
+};
+
+template <class ProcessorClass>
+class GrTBackendFragmentProcessorFactory
+        : public GrTBackendProcessorFactory<ProcessorClass,
+                                           GrBackendFragmentProcessorFactory,
+                                           GrFragmentProcessor,
+                                           GrGLFragmentProcessor> {
+protected:
+    GrTBackendFragmentProcessorFactory() {}
+};
+
+
+#endif
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index 047bd18..06ba2e4 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -10,8 +10,9 @@
 #define GrTexture_DEFINED
 
 #include "GrSurface.h"
-#include "SkPoint.h"
 #include "GrRenderTarget.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
 
 class GrResourceKey;
 class GrTextureParams;
@@ -89,7 +90,6 @@
 #ifdef SK_DEBUG
     void validate() const {
         this->INHERITED::validate();
-
         this->validateDesc();
     }
 #endif
@@ -119,6 +119,7 @@
     void validateDesc() const;
 
 private:
+    void abandonReleaseCommon();
     virtual void internal_dispose() const SK_OVERRIDE;
 
     // these two shift a fixed-point value into normalized coordinates
@@ -162,10 +163,7 @@
     static bool NeedsBilerp(const GrResourceKey& key);
 
 protected:
-    GrTextureImpl(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
-    : INHERITED(gpu, isWrapped, desc)
-    , fMipMapsStatus(kNotAllocated_MipMapsStatus) {
-    }
+    GrTextureImpl(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc);
 
 private:
     enum MipMapsStatus {
diff --git a/include/gpu/GrTextureAccess.h b/include/gpu/GrTextureAccess.h
index 9f56171..5055e10 100644
--- a/include/gpu/GrTextureAccess.h
+++ b/include/gpu/GrTextureAccess.h
@@ -8,11 +8,10 @@
 #ifndef GrTextureAccess_DEFINED
 #define GrTextureAccess_DEFINED
 
+#include "GrGpuResourceRef.h"
+#include "GrTexture.h"
 #include "SkRefCnt.h"
 #include "SkShader.h"
-#include "SkTypes.h"
-
-class GrTexture;
 
 /**
  * Represents the filtering and tile modes used to access a texture. It is mostly used with
@@ -109,14 +108,16 @@
 /** A class representing the swizzle access pattern for a texture. Note that if the texture is
  *  an alpha-only texture then the alpha channel is substituted for other components. Any mangling
  *  to handle the r,g,b->a conversions for alpha textures is automatically included in the stage
- *  key. However, if a GrEffect uses different swizzles based on its input then it must
+ *  key. However, if a GrProcessor uses different swizzles based on its input then it must
  *  consider that variation in its key-generation.
  */
-class GrTextureAccess : SkNoncopyable {
+class GrTextureAccess : public SkNoncopyable {
 public:
+    SK_DECLARE_INST_COUNT_ROOT(GrTextureAccess);
+
     /**
-     * A default GrTextureAccess must have reset() called on it in a GrEffect subclass's
-     * constructor if it will be accessible via GrEffect::textureAccess().
+     * A default GrTextureAccess must have reset() called on it in a GrProcessor subclass's
+     * constructor if it will be accessible via GrProcessor::textureAccess().
      */
     GrTextureAccess();
 
@@ -155,7 +156,7 @@
                  strcmp(fSwizzle, other.fSwizzle));
 #endif
         return fParams == other.fParams &&
-               (fTexture.get() == other.fTexture.get()) &&
+               (this->getTexture() == other.getTexture()) &&
                (0 == memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1));
     }
 
@@ -164,6 +165,11 @@
     GrTexture* getTexture() const { return fTexture.get(); }
 
     /**
+     * For internal use by GrProcessor.
+     */
+    const GrGpuResourceRef* getProgramTexture() const { return &fTexture; }
+
+    /**
      * Returns a string representing the swizzle. The string is is null-terminated.
      */
     const char* getSwizzle() const { return fSwizzle; }
@@ -177,10 +183,12 @@
 private:
     void setSwizzle(const char*);
 
-    GrTextureParams         fParams;
-    SkAutoTUnref<GrTexture> fTexture;
-    uint32_t                fSwizzleMask;
-    char                    fSwizzle[5];
+    typedef GrTGpuResourceRef<GrTexture> ProgramTexture;
+
+    ProgramTexture                  fTexture;
+    GrTextureParams                 fParams;
+    uint32_t                        fSwizzleMask;
+    char                            fSwizzle[5];
 
     typedef SkNoncopyable INHERITED;
 };
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index a529eed..22b2e22 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -274,7 +274,7 @@
      * Premultiplied. Byte order is b,g,r,a.
      */
     kBGRA_8888_GrPixelConfig,
-    /** 
+    /**
      * ETC1 Compressed Data
      */
     kETC1_GrPixelConfig,
@@ -282,8 +282,29 @@
      * LATC/RGTC/3Dc/BC4 Compressed Data
      */
     kLATC_GrPixelConfig,
+    /**
+     * R11 EAC Compressed Data
+     * (Corresponds to section C.3.5 of the OpenGL 4.4 core profile spec)
+     */
+    kR11_EAC_GrPixelConfig,
 
-    kLast_GrPixelConfig = kLATC_GrPixelConfig
+    /**
+     * 12x12 ASTC Compressed Data
+     * ASTC stands for Adaptive Scalable Texture Compression. It is a technique
+     * that allows for a lot of customization in the compressed representataion
+     * of a block. The only thing fixed in the representation is the block size,
+     * which means that a texture that contains ASTC data must be treated as
+     * having RGBA values. However, there are single-channel encodings which set
+     * the alpha to opaque and all three RGB channels equal effectively making the
+     * compression format a single channel such as R11 EAC and LATC.
+     */
+    kASTC_12x12_GrPixelConfig,
+
+    /**
+     * Byte order is r, g, b, a.  This color format is 32 bits per channel
+     */
+    kRGBA_float_GrPixelConfig,
+    kLast_GrPixelConfig = kRGBA_float_GrPixelConfig
 };
 static const int kGrPixelConfigCnt = kLast_GrPixelConfig + 1;
 
@@ -303,8 +324,11 @@
 // representation.
 static inline bool GrPixelConfigIsCompressed(GrPixelConfig config) {
     switch (config) {
+        case kIndex_8_GrPixelConfig:
         case kETC1_GrPixelConfig:
         case kLATC_GrPixelConfig:
+        case kR11_EAC_GrPixelConfig:
+        case kASTC_12x12_GrPixelConfig:
             return true;
         default:
             return false;
@@ -336,9 +360,9 @@
 }
 
 static inline size_t GrBytesPerPixel(GrPixelConfig config) {
+    SkASSERT(!GrPixelConfigIsCompressed(config));
     switch (config) {
         case kAlpha_8_GrPixelConfig:
-        case kIndex_8_GrPixelConfig:
             return 1;
         case kRGB_565_GrPixelConfig:
         case kRGBA_4444_GrPixelConfig:
@@ -346,6 +370,25 @@
         case kRGBA_8888_GrPixelConfig:
         case kBGRA_8888_GrPixelConfig:
             return 4;
+        case kRGBA_float_GrPixelConfig:
+            return 16;
+        default:
+            return 0;
+    }
+}
+
+static inline size_t GrUnpackAlignment(GrPixelConfig config) {
+    SkASSERT(!GrPixelConfigIsCompressed(config));
+    switch (config) {
+        case kAlpha_8_GrPixelConfig:
+            return 1;
+        case kRGB_565_GrPixelConfig:
+        case kRGBA_4444_GrPixelConfig:
+            return 2;
+        case kRGBA_8888_GrPixelConfig:
+        case kBGRA_8888_GrPixelConfig:
+        case kRGBA_float_GrPixelConfig:
+            return 4;
         default:
             return 0;
     }
@@ -363,7 +406,9 @@
 
 static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) {
     switch (config) {
+        case kR11_EAC_GrPixelConfig:
         case kLATC_GrPixelConfig:
+        case kASTC_12x12_GrPixelConfig:
         case kAlpha_8_GrPixelConfig:
             return true;
         default:
@@ -404,13 +449,6 @@
 
 GR_MAKE_BITFIELD_OPS(GrTextureFlags)
 
-enum {
-   /**
-    *  For Index8 pixel config, the colortable must be 256 entries
-    */
-    kGrColorTableSize = 256 * 4 //sizeof(GrColor)
-};
-
 /**
  * Some textures will be stored such that the upper and left edges of the content meet at the
  * the origin (in texture coord space) and for other textures the lower and left edges meet at
@@ -623,7 +661,7 @@
     // View state stands for scissor and viewport
     kView_GrGLBackendState             = 1 << 2,
     kBlend_GrGLBackendState            = 1 << 3,
-    kAA_GrGLBackendState               = 1 << 4,
+    kMSAAEnable_GrGLBackendState       = 1 << 4,
     kVertex_GrGLBackendState           = 1 << 5,
     kStencil_GrGLBackendState          = 1 << 6,
     kPixelStore_GrGLBackendState       = 1 << 7,
@@ -636,18 +674,27 @@
 
 /**
  * Returns the data size for the given compressed pixel config
- */ 
+ */
 static inline size_t GrCompressedFormatDataSize(GrPixelConfig config,
                                                 int width, int height) {
     SkASSERT(GrPixelConfigIsCompressed(config));
+    static const int kGrIndex8TableSize = 256 * 4; // 4 == sizeof(GrColor)
 
     switch (config) {
+        case kIndex_8_GrPixelConfig:
+            return width * height + kGrIndex8TableSize;
+        case kR11_EAC_GrPixelConfig:
         case kLATC_GrPixelConfig:
         case kETC1_GrPixelConfig:
             SkASSERT((width & 3) == 0);
             SkASSERT((height & 3) == 0);
             return (width >> 2) * (height >> 2) * 8;
 
+        case kASTC_12x12_GrPixelConfig:
+            SkASSERT((width % 12) == 0);
+            SkASSERT((height % 12) == 0);
+            return (width / 12) * (height / 12) * 16;
+
         default:
             SkFAIL("Unknown compressed pixel config");
             return 4 * width * height;
@@ -661,4 +708,20 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+#if GR_ALWAYS_ALLOCATE_ON_HEAP
+    #define GrAutoMallocBaseType SkAutoMalloc
+#else
+    #define GrAutoMallocBaseType SkAutoSMalloc<S>
+#endif
+
+template <size_t S> class GrAutoMalloc : public GrAutoMallocBaseType {
+public:
+    GrAutoMalloc() : INHERITED() {}
+    explicit GrAutoMalloc(size_t size) : INHERITED(size) {}
+    virtual ~GrAutoMalloc() {}
+private:
+    typedef GrAutoMallocBaseType INHERITED;
+};
+
+#undef GrAutoMallocBaseType
 #endif
diff --git a/include/gpu/GrTypesPriv.h b/include/gpu/GrTypesPriv.h
index dfe4153..94ec1d7 100644
--- a/include/gpu/GrTypesPriv.h
+++ b/include/gpu/GrTypesPriv.h
@@ -115,9 +115,9 @@
 }
 
 /**
- * Semantic bindings for vertex attributes. kEffect means that the attribute is input to a GrEffect.
- * Each binding other than kEffect may not appear more than once in the current set of attributes.
- * kPosition must be appear for exactly one attribute.
+ * Semantic bindings for vertex attributes. kEffect means that the attribute is input to a
+ * GrProcessor. Each binding other than kEffect may not appear more than once in the current set of
+ * attributes. kPosition must be appear for exactly one attribute.
  */
 enum GrVertexAttribBinding {
     kPosition_GrVertexAttribBinding,    // required, must have vector count of 2
@@ -127,10 +127,10 @@
 
     kLastFixedFunction_GrVertexAttribBinding = kCoverage_GrVertexAttribBinding,
 
-    kEffect_GrVertexAttribBinding,      // vector length must agree with
-                                        // GrEffect::vertexAttribType() for each effect input to
+    kGeometryProcessor_GrVertexAttribBinding,      // vector length must agree with
+                                        // GrProcessor::vertexAttribType() for each effect input to
                                         // which the attribute is mapped by GrDrawState::setEffect()
-    kLast_GrVertexAttribBinding = kEffect_GrVertexAttribBinding
+    kLast_GrVertexAttribBinding = kGeometryProcessor_GrVertexAttribBinding
 };
 
 static const int kGrVertexAttribBindingCnt = kLast_GrVertexAttribBinding + 1;
@@ -173,48 +173,48 @@
 /**
 * We have coverage effects that clip rendering to the edge of some geometric primitive.
 * This enum specifies how that clipping is performed. Not all factories that take a
-* GrEffectEdgeType will succeed with all values and it is up to the caller to check for
+* GrProcessorEdgeType will succeed with all values and it is up to the caller to check for
 * a NULL return.
 */
-enum GrEffectEdgeType {
-    kFillBW_GrEffectEdgeType,
-    kFillAA_GrEffectEdgeType,
-    kInverseFillBW_GrEffectEdgeType,
-    kInverseFillAA_GrEffectEdgeType,
-    kHairlineAA_GrEffectEdgeType,
+enum GrPrimitiveEdgeType {
+    kFillBW_GrProcessorEdgeType,
+    kFillAA_GrProcessorEdgeType,
+    kInverseFillBW_GrProcessorEdgeType,
+    kInverseFillAA_GrProcessorEdgeType,
+    kHairlineAA_GrProcessorEdgeType,
 
-    kLast_GrEffectEdgeType = kHairlineAA_GrEffectEdgeType
+    kLast_GrProcessorEdgeType = kHairlineAA_GrProcessorEdgeType
 };
 
-static const int kGrEffectEdgeTypeCnt = kLast_GrEffectEdgeType + 1;
+static const int kGrProcessorEdgeTypeCnt = kLast_GrProcessorEdgeType + 1;
 
-static inline bool GrEffectEdgeTypeIsFill(const GrEffectEdgeType edgeType) {
-    return (kFillAA_GrEffectEdgeType == edgeType || kFillBW_GrEffectEdgeType == edgeType);
+static inline bool GrProcessorEdgeTypeIsFill(const GrPrimitiveEdgeType edgeType) {
+    return (kFillAA_GrProcessorEdgeType == edgeType || kFillBW_GrProcessorEdgeType == edgeType);
 }
 
-static inline bool GrEffectEdgeTypeIsInverseFill(const GrEffectEdgeType edgeType) {
-    return (kInverseFillAA_GrEffectEdgeType == edgeType ||
-            kInverseFillBW_GrEffectEdgeType == edgeType);
+static inline bool GrProcessorEdgeTypeIsInverseFill(const GrPrimitiveEdgeType edgeType) {
+    return (kInverseFillAA_GrProcessorEdgeType == edgeType ||
+            kInverseFillBW_GrProcessorEdgeType == edgeType);
 }
 
-static inline bool GrEffectEdgeTypeIsAA(const GrEffectEdgeType edgeType) {
-    return (kFillBW_GrEffectEdgeType != edgeType && kInverseFillBW_GrEffectEdgeType != edgeType);
+static inline bool GrProcessorEdgeTypeIsAA(const GrPrimitiveEdgeType edgeType) {
+    return (kFillBW_GrProcessorEdgeType != edgeType && kInverseFillBW_GrProcessorEdgeType != edgeType);
 }
 
-static inline GrEffectEdgeType GrInvertEffectEdgeType(const GrEffectEdgeType edgeType) {
+static inline GrPrimitiveEdgeType GrInvertProcessorEdgeType(const GrPrimitiveEdgeType edgeType) {
     switch (edgeType) {
-        case kFillBW_GrEffectEdgeType:
-            return kInverseFillBW_GrEffectEdgeType;
-        case kFillAA_GrEffectEdgeType:
-            return kInverseFillAA_GrEffectEdgeType;
-        case kInverseFillBW_GrEffectEdgeType:
-            return kFillBW_GrEffectEdgeType;
-        case kInverseFillAA_GrEffectEdgeType:
-            return kFillAA_GrEffectEdgeType;
-        case kHairlineAA_GrEffectEdgeType:
+        case kFillBW_GrProcessorEdgeType:
+            return kInverseFillBW_GrProcessorEdgeType;
+        case kFillAA_GrProcessorEdgeType:
+            return kInverseFillAA_GrProcessorEdgeType;
+        case kInverseFillBW_GrProcessorEdgeType:
+            return kFillBW_GrProcessorEdgeType;
+        case kInverseFillAA_GrProcessorEdgeType:
+            return kFillAA_GrProcessorEdgeType;
+        case kHairlineAA_GrProcessorEdgeType:
             SkFAIL("Hairline fill isn't invertible.");
     }
-    return kFillAA_GrEffectEdgeType; // suppress warning.
+    return kFillAA_GrProcessorEdgeType; // suppress warning.
 }
 
 #endif
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index 1adac65..df2ae5a 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -16,7 +16,6 @@
 // Gr headers
 #include "GrTypes.h"
 #include "GrContext.h"
-#include "GrFontScaler.h"
 
 // skia headers
 #include "SkBitmap.h"
@@ -45,13 +44,6 @@
 
 #include "SkColorPriv.h"
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-/**
- *  Convert the SkBitmap::Config to the corresponding PixelConfig, or
- *  kUnknown_PixelConfig if the conversion cannot be done.
- */
-GrPixelConfig SkBitmapConfig2GrPixelConfig(SkBitmap::Config);
-#endif
 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType, SkAlphaType);
 
 static inline GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info) {
@@ -85,16 +77,16 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 // Converts a SkPaint to a GrPaint, ignoring the SkPaint's shader.
-// Sets the color of GrPaint to the value of the parameter grColor
+// Sets the color of GrPaint to the value of the parameter paintColor
 // Callers may subsequently modify the GrPaint. Setting constantColor indicates
 // that the final paint will draw the same color at every pixel. This allows
 // an optimization where the the color filter can be applied to the SkPaint's
 // color once while converting to GrPaint and then ignored.
-void SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor grColor,
+void SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor,
                              bool constantColor, GrPaint* grPaint);
 
 // This function is similar to skPaint2GrPaintNoShader but also converts
-// skPaint's shader to a GrTexture/GrEffectStage if possible.
+// skPaint's shader to a GrTexture/GrProcessorStage if possible.
 // constantColor has the same meaning as in skPaint2GrPaintNoShader.
 void SkPaint2GrPaintShader(GrContext* context, const SkPaint& skPaint,
                            bool constantColor, GrPaint* grPaint);
@@ -104,28 +96,6 @@
 
 class SkGlyphCache;
 
-class SkGrFontScaler : public GrFontScaler {
-public:
-    explicit SkGrFontScaler(SkGlyphCache* strike);
-    virtual ~SkGrFontScaler();
-
-    // overrides
-    virtual const GrKey* getKey();
-    virtual GrMaskFormat getMaskFormat();
-    virtual bool getPackedGlyphBounds(GrGlyph::PackedID, SkIRect* bounds) SK_OVERRIDE;
-    virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
-                                     int rowBytes, void* image) SK_OVERRIDE;
-    virtual bool getPackedGlyphDFBounds(GrGlyph::PackedID, SkIRect* bounds) SK_OVERRIDE;
-    virtual bool getPackedGlyphDFImage(GrGlyph::PackedID, int width, int height,
-                                       void* image) SK_OVERRIDE;
-    virtual bool getGlyphPath(uint16_t glyphID, SkPath*);
-
-private:
-    SkGlyphCache* fStrike;
-    GrKey*  fKey;
-//    DECLARE_INSTANCE_COUNTER(SkGrFontScaler);
-};
-
 ////////////////////////////////////////////////////////////////////////////////
 
 #endif
diff --git a/include/gpu/SkGrPixelRef.h b/include/gpu/SkGrPixelRef.h
index 36802a0..7e6a9d0 100644
--- a/include/gpu/SkGrPixelRef.h
+++ b/include/gpu/SkGrPixelRef.h
@@ -51,8 +51,6 @@
     // override from SkPixelRef
     virtual GrTexture* getTexture() SK_OVERRIDE;
 
-    SK_DECLARE_UNFLATTENABLE_OBJECT()
-
 protected:
     // overrides from SkPixelRef
     virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subset) SK_OVERRIDE;
diff --git a/include/gpu/gl/GrGLFunctions.h b/include/gpu/gl/GrGLFunctions.h
index 5ac77a2..45bf582 100644
--- a/include/gpu/gl/GrGLFunctions.h
+++ b/include/gpu/gl/GrGLFunctions.h
@@ -89,6 +89,7 @@
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCompressedTexImage2DProc)(GrGLenum target, GrGLint level, GrGLenum internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLsizei imageSize, const GrGLvoid* data);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCompressedTexSubImage2DProc)(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLsizei imageSize, const GrGLvoid* data);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCopyTexSubImage2DProc)(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCopyTextureCHROMIUMProc)(GrGLenum target, GrGLenum src, GrGLenum dst, GrGLint level, GrGLint format, GrGLenum type);
     typedef GrGLuint (GR_GL_FUNCTION_TYPE* GrGLCreateProgramProc)(void);
     typedef GrGLuint (GR_GL_FUNCTION_TYPE* GrGLCreateShaderProc)(GrGLenum type);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCullFaceProc)(GrGLenum mode);
@@ -214,11 +215,14 @@
     // Experimental: Functions for GL_NV_path_rendering. These will be
     // alphabetized with the above functions once this is fully supported
     // (and functions we are unlikely to use will possibly be omitted).
+    // EXT_direct_state_access
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLMatrixLoadfProc)(GrGLenum matrixMode, const GrGLfloat* m);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLMatrixLoadIdentityProc)(GrGLenum);
+    // ARB_program_interface_query
+    typedef GrGLint (GR_GL_FUNCTION_TYPE* GrGLGetProgramResourceLocationProc)(GrGLuint program, GrGLenum programInterface, const GrGLchar *name);
+    // NV_path_rendering
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathCommandsProc)(GrGLuint path, GrGLsizei numCommands, const GrGLubyte *commands, GrGLsizei numCoords, GrGLenum coordType, const GrGLvoid *coords);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathCoordsProc)(GrGLuint path, GrGLsizei numCoords, GrGLenum coordType, const GrGLvoid *coords);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathSubCommandsProc)(GrGLuint path, GrGLsizei commandStart, GrGLsizei commandsToDelete, GrGLsizei numCommands, const GrGLubyte *commands, GrGLsizei numCoords, GrGLenum coordType, const GrGLvoid *coords);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathSubCoordsProc)(GrGLuint path, GrGLsizei coordStart, GrGLsizei numCoords, GrGLenum coordType, const GrGLvoid *coords);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathStringProc)(GrGLuint path, GrGLenum format, GrGLsizei length, const GrGLvoid *pathString);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathGlyphsProc)(GrGLuint firstPathName, GrGLenum fontTarget, const GrGLvoid *fontName, GrGLbitfield fontStyle, GrGLsizei numGlyphs, GrGLenum type, const GrGLvoid *charcodes, GrGLenum handleMissingGlyphs, GrGLuint pathParameterTemplate, GrGLfloat emScale);
@@ -227,45 +231,29 @@
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCopyPathProc)(GrGLuint resultPath, GrGLuint srcPath);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInterpolatePathsProc)(GrGLuint resultPath, GrGLuint pathA, GrGLuint pathB, GrGLfloat weight);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLTransformPathProc)(GrGLuint resultPath, GrGLuint srcPath, GrGLenum transformType, const GrGLfloat *transformValues);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathParameterivProc)(GrGLuint path, GrGLenum pname, const GrGLint *value);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathParameteriProc)(GrGLuint path, GrGLenum pname, GrGLint value);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathParameterfvProc)(GrGLuint path, GrGLenum pname, const GrGLfloat *value);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathParameterfProc)(GrGLuint path, GrGLenum pname, GrGLfloat value);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathDashArrayProc)(GrGLuint path, GrGLsizei dashCount, const GrGLfloat *dashArray);
     typedef GrGLuint (GR_GL_FUNCTION_TYPE* GrGLGenPathsProc)(GrGLsizei range);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeletePathsProc)(GrGLuint path, GrGLsizei range);
     typedef GrGLboolean (GR_GL_FUNCTION_TYPE* GrGLIsPathProc)(GrGLuint path);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathStencilFuncProc)(GrGLenum func, GrGLint ref, GrGLuint mask);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathStencilDepthOffsetProc)(GrGLfloat factor, GrGLfloat units);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilFillPathProc)(GrGLuint path, GrGLenum fillMode, GrGLuint mask);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilStrokePathProc)(GrGLuint path, GrGLint reference, GrGLuint mask);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilFillPathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum transformType, const GrGLfloat *transformValues);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilStrokePathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum transformType, const GrGLfloat *transformValues);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathCoverDepthFuncProc)(GrGLenum zfunc);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathColorGenProc)(GrGLenum color, GrGLenum genMode, GrGLenum colorFormat, const GrGLfloat *coeffs);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathTexGenProc)(GrGLenum texCoordSet, GrGLenum genMode, GrGLint components, const GrGLfloat *coeffs);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathFogGenProc)(GrGLenum genMode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCoverFillPathProc)(GrGLuint path, GrGLenum coverMode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCoverStrokePathProc)(GrGLuint name, GrGLenum coverMode);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCoverFillPathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCoverStrokePathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat* transformValues);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathParameterivProc)(GrGLuint name, GrGLenum param, GrGLint *value);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathParameterfvProc)(GrGLuint name, GrGLenum param, GrGLfloat *value);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathCommandsProc)(GrGLuint name, GrGLubyte *commands);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathCoordsProc)(GrGLuint name, GrGLfloat *coords);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathDashArrayProc)(GrGLuint name, GrGLfloat *dashArray);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathMetricsProc)(GrGLbitfield metricQueryMask, GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLsizei stride, GrGLfloat *metrics);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathMetricRangeProc)(GrGLbitfield metricQueryMask, GrGLuint fistPathName, GrGLsizei numPaths, GrGLsizei stride, GrGLfloat *metrics);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathSpacingProc)(GrGLenum pathListMode, GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLfloat advanceScale, GrGLfloat kerningScale, GrGLenum transformType, GrGLfloat *returnedSpacing);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathColorGenivProc)(GrGLenum color, GrGLenum pname, GrGLint *value);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathColorGenfvProc)(GrGLenum color, GrGLenum pname, GrGLfloat *value);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathTexGenivProc)(GrGLenum texCoordSet, GrGLenum pname, GrGLint *value);
-    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetPathTexGenfvProc)(GrGLenum texCoordSet, GrGLenum pname, GrGLfloat *value);
-    typedef GrGLboolean (GR_GL_FUNCTION_TYPE* GrGLIsPointInFillPathProc)(GrGLuint path, GrGLuint mask, GrGLfloat x, GrGLfloat y);
-    typedef GrGLboolean (GR_GL_FUNCTION_TYPE* GrGLIsPointInStrokePathProc)(GrGLuint path, GrGLfloat x, GrGLfloat y);
-    typedef GrGLfloat (GR_GL_FUNCTION_TYPE* GrGLGetPathLengthProc)(GrGLuint path, GrGLsizei startSegment, GrGLsizei numSegments);
-    typedef GrGLboolean (GR_GL_FUNCTION_TYPE* GrGLPointAlongPathProc)(GrGLuint path, GrGLsizei startSegment, GrGLsizei numSegments, GrGLfloat distance, GrGLfloat *x, GrGLfloat *y, GrGLfloat *tangentX, GrGLfloat *tangentY);
-
+    // NV_path_rendering v1.2
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilThenCoverFillPathProc)(GrGLuint path, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilThenCoverStrokePathProc)(GrGLuint path, GrGLint reference, GrGLuint mask, GrGLenum coverMode);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilThenCoverFillPathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilThenCoverStrokePathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues);
+    // NV_path_rendering v1.3
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLProgramPathFragmentInputGenProc)(GrGLuint program, GrGLint location, GrGLenum genMode, GrGLint components,const GrGLfloat *coeffs);
+    typedef GrGLenum (GR_GL_FUNCTION_TYPE* GrGLPathMemoryGlyphIndexArrayProc)(GrGLuint firstPathName, GrGLenum fontTarget, GrGLsizeiptr fontSize, const GrGLvoid *fontData, GrGLsizei faceIndex, GrGLuint firstGlyphIndex, GrGLsizei numGlyphs, GrGLuint pathParameterTemplate, GrGLfloat emScale);
 }  // extern "C"
 
 #endif
diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h
index 6c5ab24..32552e6 100644
--- a/include/gpu/gl/GrGLInterface.h
+++ b/include/gpu/gl/GrGLInterface.h
@@ -170,6 +170,7 @@
         GLPtr<GrGLCompressedTexImage2DProc> fCompressedTexImage2D;
         GLPtr<GrGLCompressedTexSubImage2DProc> fCompressedTexSubImage2D;
         GLPtr<GrGLCopyTexSubImage2DProc> fCopyTexSubImage2D;
+        GLPtr<GrGLCopyTextureCHROMIUMProc> fCopyTextureCHROMIUM;
         GLPtr<GrGLCreateProgramProc> fCreateProgram;
         GLPtr<GrGLCreateShaderProc> fCreateShader;
         GLPtr<GrGLCullFaceProc> fCullFace;
@@ -317,55 +318,32 @@
         // Experimental: Functions for GL_NV_path_rendering. These will be
         // alphabetized with the above functions once this is fully supported
         // (and functions we are unlikely to use will possibly be omitted).
+        GLPtr<GrGLGetProgramResourceLocationProc> fGetProgramResourceLocation;
         GLPtr<GrGLPathCommandsProc> fPathCommands;
         GLPtr<GrGLPathCoordsProc> fPathCoords;
-        GLPtr<GrGLPathSubCommandsProc> fPathSubCommands;
-        GLPtr<GrGLPathSubCoordsProc> fPathSubCoords;
-        GLPtr<GrGLPathStringProc> fPathString;
-        GLPtr<GrGLPathGlyphsProc> fPathGlyphs;
-        GLPtr<GrGLPathGlyphRangeProc> fPathGlyphRange;
-        GLPtr<GrGLWeightPathsProc> fWeightPaths;
-        GLPtr<GrGLCopyPathProc> fCopyPath;
-        GLPtr<GrGLInterpolatePathsProc> fInterpolatePaths;
-        GLPtr<GrGLTransformPathProc> fTransformPath;
-        GLPtr<GrGLPathParameterivProc> fPathParameteriv;
         GLPtr<GrGLPathParameteriProc> fPathParameteri;
-        GLPtr<GrGLPathParameterfvProc> fPathParameterfv;
         GLPtr<GrGLPathParameterfProc> fPathParameterf;
-        GLPtr<GrGLPathDashArrayProc> fPathDashArray;
         GLPtr<GrGLGenPathsProc> fGenPaths;
         GLPtr<GrGLDeletePathsProc> fDeletePaths;
         GLPtr<GrGLIsPathProc> fIsPath;
         GLPtr<GrGLPathStencilFuncProc> fPathStencilFunc;
-        GLPtr<GrGLPathStencilDepthOffsetProc> fPathStencilDepthOffset;
         GLPtr<GrGLStencilFillPathProc> fStencilFillPath;
         GLPtr<GrGLStencilStrokePathProc> fStencilStrokePath;
         GLPtr<GrGLStencilFillPathInstancedProc> fStencilFillPathInstanced;
         GLPtr<GrGLStencilStrokePathInstancedProc> fStencilStrokePathInstanced;
-        GLPtr<GrGLPathCoverDepthFuncProc> fPathCoverDepthFunc;
-        GLPtr<GrGLPathColorGenProc> fPathColorGen;
         GLPtr<GrGLPathTexGenProc> fPathTexGen;
-        GLPtr<GrGLPathFogGenProc> fPathFogGen;
         GLPtr<GrGLCoverFillPathProc> fCoverFillPath;
         GLPtr<GrGLCoverStrokePathProc> fCoverStrokePath;
         GLPtr<GrGLCoverFillPathInstancedProc> fCoverFillPathInstanced;
         GLPtr<GrGLCoverStrokePathInstancedProc> fCoverStrokePathInstanced;
-        GLPtr<GrGLGetPathParameterivProc> fGetPathParameteriv;
-        GLPtr<GrGLGetPathParameterfvProc> fGetPathParameterfv;
-        GLPtr<GrGLGetPathCommandsProc> fGetPathCommands;
-        GLPtr<GrGLGetPathCoordsProc> fGetPathCoords;
-        GLPtr<GrGLGetPathDashArrayProc> fGetPathDashArray;
-        GLPtr<GrGLGetPathMetricsProc> fGetPathMetrics;
-        GLPtr<GrGLGetPathMetricRangeProc> fGetPathMetricRange;
-        GLPtr<GrGLGetPathSpacingProc> fGetPathSpacing;
-        GLPtr<GrGLGetPathColorGenivProc> fGetPathColorGeniv;
-        GLPtr<GrGLGetPathColorGenfvProc> fGetPathColorGenfv;
-        GLPtr<GrGLGetPathTexGenivProc> fGetPathTexGeniv;
-        GLPtr<GrGLGetPathTexGenfvProc> fGetPathTexGenfv;
-        GLPtr<GrGLIsPointInFillPathProc> fIsPointInFillPath;
-        GLPtr<GrGLIsPointInStrokePathProc> fIsPointInStrokePath;
-        GLPtr<GrGLGetPathLengthProc> fGetPathLength;
-        GLPtr<GrGLPointAlongPathProc> fPointAlongPath;
+        // NV_path_rendering v1.2
+        GLPtr<GrGLStencilThenCoverFillPathProc> fStencilThenCoverFillPath;
+        GLPtr<GrGLStencilThenCoverStrokePathProc> fStencilThenCoverStrokePath;
+        GLPtr<GrGLStencilThenCoverFillPathInstancedProc> fStencilThenCoverFillPathInstanced;
+        GLPtr<GrGLStencilThenCoverStrokePathInstancedProc> fStencilThenCoverStrokePathInstanced;
+        // NV_path_rendering v1.3
+        GLPtr<GrGLProgramPathFragmentInputGenProc> fProgramPathFragmentInputGen;
+        GLPtr<GrGLPathMemoryGlyphIndexArrayProc> fPathMemoryGlyphIndexArray;
     } fFunctions;
 
     // Per-GL func callback
@@ -373,6 +351,9 @@
     GrGLInterfaceCallbackProc fCallback;
     GrGLInterfaceCallbackData fCallbackData;
 #endif
+
+    // This exists for internal testing.
+    virtual void abandon() const {}
 };
 
 #endif
diff --git a/include/gpu/gl/GrGLSLPrettyPrint.h b/include/gpu/gl/GrGLSLPrettyPrint.h
new file mode 100644
index 0000000..7273aaa
--- /dev/null
+++ b/include/gpu/gl/GrGLSLPrettyPrint.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef GrGLSLPrettyPrint_DEFINED
+#define GrGLSLPrettyPrint_DEFINED
+
+#include "SkString.h"
+
+namespace GrGLSLPrettyPrint {
+    SkString PrettyPrintGLSL(const SkString& input, bool countlines);
+};
+
+#endif /* GRGLPRETTYPRINTSL_H_ */
diff --git a/include/gpu/gl/SkANGLEGLContext.h b/include/gpu/gl/SkANGLEGLContext.h
index 99ef4e9..c5f62ff 100644
--- a/include/gpu/gl/SkANGLEGLContext.h
+++ b/include/gpu/gl/SkANGLEGLContext.h
@@ -36,7 +36,8 @@
     };
 
 protected:
-    virtual const GrGLInterface* createGLContext() SK_OVERRIDE;
+    virtual const GrGLInterface* createGLContext(
+        GrGLStandard forcedGpuAPI) SK_OVERRIDE;
     virtual void destroyGLContext() SK_OVERRIDE;
 
 private:
diff --git a/include/gpu/gl/SkDebugGLContext.h b/include/gpu/gl/SkDebugGLContext.h
index 545ef40..7db9579 100644
--- a/include/gpu/gl/SkDebugGLContext.h
+++ b/include/gpu/gl/SkDebugGLContext.h
@@ -13,13 +13,13 @@
 class SkDebugGLContext : public SkGLContextHelper {
 
 public:
-    SkDebugGLContext() {};
+    SkDebugGLContext() {}
 
-    virtual void makeCurrent() const SK_OVERRIDE {};
-    virtual void swapBuffers() const SK_OVERRIDE {};
+    virtual void makeCurrent() const SK_OVERRIDE {}
+    virtual void swapBuffers() const SK_OVERRIDE {}
 
 protected:
-    virtual const GrGLInterface* createGLContext() SK_OVERRIDE;
+    virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
 
     virtual void destroyGLContext() SK_OVERRIDE {};
 };
diff --git a/include/gpu/gl/SkGLContextHelper.h b/include/gpu/gl/SkGLContextHelper.h
index ea940c8..c4d9bdf 100644
--- a/include/gpu/gl/SkGLContextHelper.h
+++ b/include/gpu/gl/SkGLContextHelper.h
@@ -25,7 +25,7 @@
     /**
      * Initializes the context and makes it current.
      */
-    bool init(const int width, const int height);
+    bool init(GrGLStandard forcedGpuAPI, const int width, const int height);
 
     int getFBOID() const { return fFBO; }
 
@@ -46,10 +46,18 @@
     virtual void swapBuffers() const = 0;
 
     bool hasExtension(const char* extensionName) const {
-        SkASSERT(NULL != fGL);
+        SkASSERT(fGL);
         return fGL->hasExtension(extensionName);
     }
 
+    /**
+     * This notifies the context that we are deliberately testing abandoning
+     * the context. It is useful for debugging contexts that would otherwise
+     * test that GPU resources are properly deleted. It also allows a debugging
+     * context to test that further GL calls are not made by Skia GPU code.
+     */
+    void testAbandon();
+
 protected:
     /**
      * Subclass implements this to make a GL context. The returned GrGLInterface
@@ -57,7 +65,7 @@
      * format and size of backbuffers does not matter since an FBO will be
      * created.
      */
-    virtual const GrGLInterface* createGLContext() = 0;
+    virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) = 0;
 
     /**
      * Subclass should destroy the underlying GL context.
@@ -78,9 +86,9 @@
  * SK_GL(glCtx, GenTextures(1, &texID));
  */
 #define SK_GL(ctx, X) (ctx).gl()->fFunctions.f ## X;    \
-                      SkASSERT(GR_GL_NO_ERROR == (ctx).gl()->fFunctions.fGetError())
+                      SkASSERT(0 == (ctx).gl()->fFunctions.fGetError())
 #define SK_GL_RET(ctx, RET, X) (RET) = (ctx).gl()->fFunctions.f ## X;    \
-                  SkASSERT(GR_GL_NO_ERROR == (ctx).gl()->fFunctions.fGetError())
+                  SkASSERT(0 == (ctx).gl()->fFunctions.fGetError())
 #define SK_GL_NOERRCHECK(ctx, X) (ctx).gl()->fFunctions.f ## X
 #define SK_GL_RET_NOERRCHECK(ctx, RET, X) (RET) = (ctx).gl()->fFunctions.f ## X
 
diff --git a/include/gpu/gl/SkMesaGLContext.h b/include/gpu/gl/SkMesaGLContext.h
index 55235fa..28349dd 100644
--- a/include/gpu/gl/SkMesaGLContext.h
+++ b/include/gpu/gl/SkMesaGLContext.h
@@ -38,7 +38,7 @@
     };
 
 protected:
-    virtual const GrGLInterface* createGLContext() SK_OVERRIDE;
+    virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
     virtual void destroyGLContext() SK_OVERRIDE;
 
 private:
diff --git a/include/gpu/gl/SkNativeGLContext.h b/include/gpu/gl/SkNativeGLContext.h
index 7254de1..3bb6530 100644
--- a/include/gpu/gl/SkNativeGLContext.h
+++ b/include/gpu/gl/SkNativeGLContext.h
@@ -10,6 +10,29 @@
 
 #include "SkGLContextHelper.h"
 
+/* This struct is taken from a mesa demo.  Please update as required */
+static const struct { int major, minor; } gl_versions[] = {
+   {1, 0},
+   {1, 1},
+   {1, 2},
+   {1, 3},
+   {1, 4},
+   {1, 5},
+   {2, 0},
+   {2, 1},
+   {3, 0},
+   {3, 1},
+   {3, 2},
+   {3, 3},
+   {4, 0},
+   {4, 1},
+   {4, 2},
+   {4, 3},
+   {4, 4},
+   {0, 0} /* end of list */
+};
+#define NUM_GL_VERSIONS SK_ARRAY_COUNT(gl_versions)
+
 #if defined(SK_BUILD_FOR_MAC)
     #include <OpenGL/OpenGL.h>
 #elif defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_NACL)
@@ -21,6 +44,7 @@
 #elif defined(SK_BUILD_FOR_WIN32)
     #include <windows.h>
     #include <GL/GL.h>
+    #include "SkWGL.h"
 #endif
 
 class SkNativeGLContext : public SkGLContextHelper {
@@ -58,7 +82,7 @@
     };
 
 protected:
-    virtual const GrGLInterface* createGLContext() SK_OVERRIDE;
+    virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
     virtual void destroyGLContext() SK_OVERRIDE;
 
 private:
@@ -78,6 +102,7 @@
     HDC fDeviceContext;
     HGLRC fGlRenderContext;
     static ATOM gWC;
+    SkWGLPbufferContext* fPbufferContext;
 #elif defined(SK_BUILD_FOR_IOS)
     void* fEAGLContext;
 #endif
diff --git a/include/gpu/gl/SkNullGLContext.h b/include/gpu/gl/SkNullGLContext.h
index 02d968e..6c2a1d7 100644
--- a/include/gpu/gl/SkNullGLContext.h
+++ b/include/gpu/gl/SkNullGLContext.h
@@ -20,7 +20,7 @@
     virtual void swapBuffers() const SK_OVERRIDE {};
 
 protected:
-    virtual const GrGLInterface* createGLContext() SK_OVERRIDE;
+    virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
 
     virtual void destroyGLContext() SK_OVERRIDE {};
 };
diff --git a/include/pathops/SkPathOps.h b/include/pathops/SkPathOps.h
index a98f4ea..ba18f4b 100644
--- a/include/pathops/SkPathOps.h
+++ b/include/pathops/SkPathOps.h
@@ -10,6 +10,7 @@
 #include "SkPreConfig.h"
 
 class SkPath;
+struct SkRect;
 
 // FIXME: move everything below into the SkPath class
 /**
@@ -54,4 +55,12 @@
   */
 bool SK_API Simplify(const SkPath& path, SkPath* result);
 
+/** Set the resulting rectangle to the tight bounds of the path.
+
+    @param path The path measured.
+    @param result The tight bounds of the path.
+    @return True if the bounds could be computed.
+  */
+bool SK_API TightBounds(const SkPath& path, SkRect* result);
+
 #endif
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index e250a6d..6f770af 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -10,7 +10,7 @@
 #ifndef SkPDFDevice_DEFINED
 #define SkPDFDevice_DEFINED
 
-#include "SkBitmapDevice.h"
+#include "SkDevice.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
@@ -45,7 +45,7 @@
 
     The drawing context for the PDF backend.
 */
-class SkPDFDevice : public SkBitmapDevice {
+class SkPDFDevice : public SkBaseDevice {
 public:
     /** Create a PDF drawing context with the given width and height.
      *  72 points/in means letter paper is 612x792.
@@ -82,8 +82,8 @@
                             size_t count, const SkPoint[],
                             const SkPaint& paint) SK_OVERRIDE;
     virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
-    virtual void drawRRect(const SkDraw&, const SkRRect& rr,
-                           const SkPaint& paint) SK_OVERRIDE;
+    virtual void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) SK_OVERRIDE;
+    virtual void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPath(const SkDraw&, const SkPath& origpath,
                           const SkPaint& paint, const SkMatrix* prePathMatrix,
                           bool pathIsMutable) SK_OVERRIDE;
@@ -113,6 +113,7 @@
 
     virtual void onAttachToCanvas(SkCanvas* canvas) SK_OVERRIDE;
     virtual void onDetachFromCanvas() SK_OVERRIDE;
+    virtual SkImageInfo imageInfo() const SK_OVERRIDE;    
 
     enum DrawingArea {
         kContent_DrawingArea,  // Drawing area for the page content.
@@ -208,7 +209,11 @@
     }
 
 protected:
-    virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE;
+    virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE {
+        return fLegacyBitmap;
+    }
+
+    virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
 
 private:
     // TODO(vandebo): push most of SkPDFDevice's state into a core object in
@@ -248,6 +253,8 @@
     SkPicture::EncodeBitmap fEncoder;
     SkScalar fRasterDpi;
 
+    SkBitmap fLegacyBitmap;
+
     SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
                 const SkRegion& existingClipRegion);
 
@@ -323,7 +330,7 @@
     void defineNamedDestination(SkData* nameData, const SkPoint& point,
                                 const SkMatrix& matrix);
 
-    typedef SkBitmapDevice INHERITED;
+    typedef SkBaseDevice INHERITED;
 
     // TODO(edisonn): Only SkDocument_PDF and SkPDFImageShader should be able to create
     // an SkPDFDevice
diff --git a/include/pipe/SkGPipe.h b/include/pipe/SkGPipe.h
index 879ab04..98e081d 100644
--- a/include/pipe/SkGPipe.h
+++ b/include/pipe/SkGPipe.h
@@ -99,7 +99,7 @@
     SkGPipeWriter();
     ~SkGPipeWriter();
 
-    bool isRecording() const { return NULL != fCanvas; }
+    bool isRecording() const { return SkToBool(fCanvas); }
 
     enum Flags {
         /**
diff --git a/include/ports/SkFontConfigInterface.h b/include/ports/SkFontConfigInterface.h
index 8c12a56..c596267 100644
--- a/include/ports/SkFontConfigInterface.h
+++ b/include/ports/SkFontConfigInterface.h
@@ -14,6 +14,8 @@
 #include "SkTArray.h"
 #include "SkTypeface.h"
 
+struct SkBaseMutex;
+
 /**
  *  \class SkFontConfigInterface
  *
@@ -95,8 +97,10 @@
     /**
      *  Return a singleton instance of a direct subclass that calls into
      *  libfontconfig. This does not affect the refcnt of the returned instance.
+     *  The mutex may be used to guarantee the singleton is only constructed once.
      */
-    static SkFontConfigInterface* GetSingletonDirectInterface();
+    static SkFontConfigInterface* GetSingletonDirectInterface
+        (SkBaseMutex* mutex = NULL);
 
     // New APIS, which have default impls for now (which do nothing)
 
diff --git a/include/ports/SkFontMgr.h b/include/ports/SkFontMgr.h
index bb8c7b7..0ffcc27e 100644
--- a/include/ports/SkFontMgr.h
+++ b/include/ports/SkFontMgr.h
@@ -64,14 +64,24 @@
 
     /**
      *  Use the system fallback to find a typeface for the given character.
-     *  Note that bpc47 is a combination of ISO 639, 15924, and 3166-1 codes,
+     *  Note that bcp47 is a combination of ISO 639, 15924, and 3166-1 codes,
      *  so it is fine to just pass a ISO 639 here.
      *
      *  Will return NULL if no family can be found for the character
      *  in the system fallback.
+     *
+     *  bcp47[0] is the least significant fallback, bcp47[bcp47Count-1] is the
+     *  most significant. If no specified bcp47 codes match, any font with the
+     *  requested character will be matched.
      */
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
     SkTypeface* matchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
-                                          const char bpc47[], uint32_t character) const;
+                                          const char* bcp47[], int bcp47Count,
+                                          SkUnichar character) const;
+#else
+    SkTypeface* matchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+                                          const char bcp47[], SkUnichar character) const;
+#endif
 
     SkTypeface* matchFaceStyle(const SkTypeface*, const SkFontStyle&) const;
 
@@ -117,8 +127,14 @@
     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
                                            const SkFontStyle&) const = 0;
     // TODO: pure virtual, implement on all impls.
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
-                                                    const char bpc47[], uint32_t character) const
+                                                    const char* bcp47[], int bcp47Count,
+                                                    SkUnichar character) const
+#else
+    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+                                                    const char bcp47[], SkUnichar character) const
+#endif
     { return NULL; }
     virtual SkTypeface* onMatchFaceStyle(const SkTypeface*,
                                          const SkFontStyle&) const = 0;
diff --git a/include/ports/SkFontMgr_indirect.h b/include/ports/SkFontMgr_indirect.h
index b9ce344..95a2355 100644
--- a/include/ports/SkFontMgr_indirect.h
+++ b/include/ports/SkFontMgr_indirect.h
@@ -39,10 +39,18 @@
     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
                                            const SkFontStyle& fontStyle) const SK_OVERRIDE;
 
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
                                                     const SkFontStyle&,
-                                                    const char bpc47[],
-                                                    uint32_t character) const SK_OVERRIDE;
+                                                    const char* bcp47[],
+                                                    int bcp47Count,
+                                                    SkUnichar character) const SK_OVERRIDE;
+#else
+    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+                                                    const SkFontStyle&,
+                                                    const char bcp47[],
+                                                    SkUnichar character) const SK_OVERRIDE;
+#endif
 
     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
                                          const SkFontStyle& fontStyle) const SK_OVERRIDE;
diff --git a/include/ports/SkHarfBuzzFont.h b/include/ports/SkHarfBuzzFont.h
deleted file mode 100644
index 22749af..0000000
--- a/include/ports/SkHarfBuzzFont.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2009 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkHarfBuzzFont_DEFINED
-#define SkHarfBuzzFont_DEFINED
-
-extern "C" {
-#include "harfbuzz-shaper.h"
-//#include "harfbuzz-unicode.h"
-}
-
-#include "SkTypes.h"
-
-class SkPaint;
-class SkTypeface;
-
-class SkHarfBuzzFont {
-public:
-    /** The subclass returns the typeface for this font, or NULL
-     */
-    virtual SkTypeface* getTypeface() const = 0;
-    /** The subclass sets the text related attributes of the paint.
-        e.g. textSize, typeface, textSkewX, etc.
-        All of the attributes that could effect how the text is measured.
-        Color information (e.g. color, xfermode, shader, etc.) are not required.
-     */
-    virtual void setupPaint(SkPaint*) const = 0;
-
-    /** Implementation of HB_GetFontTableFunc, using SkHarfBuzzFont* as
-        the first parameter.
-     */
-    static HB_Error GetFontTableFunc(void* skharfbuzzfont, const HB_Tag tag,
-                                     HB_Byte* buffer, HB_UInt* len);
-
-    static const HB_FontClass& GetFontClass();
-};
-
-#endif
diff --git a/include/ports/SkRemotableFontMgr.h b/include/ports/SkRemotableFontMgr.h
index bd99497..1ff96a3 100644
--- a/include/ports/SkRemotableFontMgr.h
+++ b/include/ports/SkRemotableFontMgr.h
@@ -133,8 +133,14 @@
      *  Note that bpc47 is a combination of ISO 639, 15924, and 3166-1 codes,
      *  so it is fine to just pass a ISO 639 here.
      */
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
     virtual SkFontIdentity matchNameStyleCharacter(const char familyName[], const SkFontStyle&,
-                                                   const char bpc47[], SkUnichar character) const=0;
+                                                   const char* bcp47[], int bcp47Count,
+                                                   SkUnichar character) const=0;
+#else
+    virtual SkFontIdentity matchNameStyleCharacter(const char familyName[], const SkFontStyle&,
+                                                   const char bcp47[], SkUnichar character) const=0;
+#endif
 
     /**
      *  Returns the data for the given data id.
diff --git a/include/ports/SkTypeface_android.h b/include/ports/SkTypeface_android.h
index 2e04414..588f56d 100644
--- a/include/ports/SkTypeface_android.h
+++ b/include/ports/SkTypeface_android.h
@@ -13,38 +13,6 @@
 
 #ifdef SK_BUILD_FOR_ANDROID
 
-class SkPaintOptionsAndroid;
-
-/**
- *  Get the family name of the font in the fallback font list containing
- *  the specified character using the system's default language. This function
- *  also assumes the only families with the elegant or default variants will be
- *  returned.
- *
- *  @param uni  The unicode character to use for the lookup.
- *  @param name The family name of the font file containing the unicode character
- *              in the default language
- *  @return     true if a font is found and false otherwise
- */
-SK_API bool SkGetFallbackFamilyNameForChar(SkUnichar uni, SkString* name);
-
-/**
- *  Get the family name of the font in the fallback font list containing
- *  the specified character taking into account the provided language. This
- *  function also assumes the only families with the elegant or default variants
- *  will be returned.
- *
- *  @param uni  The unicode character to use for the lookup.
- *  @param lang The null terminated string representing the BCP 47 language
- *              identifier for the preferred language. If there is no unique
- *              fallback chain for that language the system's default language
- *              will be used.
- *  @param name The family name of the font file containing the unicode character
- *              in the preferred language
- *  @return     true if a font is found and false otherwise
- */
-SK_API bool SkGetFallbackFamilyNameForChar(SkUnichar uni, const char* lang, SkString* name);
-
 /**
  *  For test only.
  *  Load font config from given xml files, instead of those from Android system.
@@ -53,56 +21,14 @@
                                     const char* fontsdir);
 
 /**
- *  Given a "current" fontID, return a ref to the next logical typeface
- *  when searching fonts for a given unicode value. Typically the caller
- *  will query a given font, and if a unicode value is not supported, they
- *  will call this, and if 0 is not returned, will search that font, and so
- *  on. This process must be finite, and when the fonthost sees a
- *  font with no logical successor, it must return NULL.
- *
- *  The original fontID is also provided. This is the initial font that was
- *  stored in the typeface of the caller. It is provided as an aid to choose
- *  the best next logical font. e.g. If the original font was bold or serif,
- *  but the 2nd in the logical chain was plain, then a subsequent call to
- *  get the 3rd can still inspect the original, and try to match its
- *  stylistic attributes.
+ *  For test only.
+ *  Returns the information set by SkUseTestFontConfigFile.
+ *  TODO: this should be removed once SkFontConfigInterface_android is removed,
+ *  and then Chromium should be given a better way to set up it's test environment
+ *  than SkUseTestFontConfigFile.
  */
-SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID, SkFontID origFontID,
-                                         const SkPaintOptionsAndroid& options);
-
-/**
- * Given a glyphID (built using fallback font chaining) and its origin typeface
- * return the actual typeface within the fallback chain that this glyphID
- * resolves to. If no suitable typeface is found then NULL is returned. However,
- * if returned typeface is not NULL it is assumed to be globally cached so the
- * caller need not ref it.
- *
- * Optionally, if lower/upper bound params are provided and the returned
- * typeface is not NULL, then these params are populated with the range of
- * glyphIDs that this typeface is capable of resolving. The lower bound is
- * inclusive while the upper bound is exclusive.
- */
-SkTypeface* SkGetTypefaceForGlyphID(uint16_t glyphID, const SkTypeface* origTypeface,
-                                    const SkPaintOptionsAndroid& options,
-                                    int* lowerBounds = NULL, int* upperBounds = NULL);
+void SkGetTestFontConfiguration(const char** mainconf, const char** fallbackconf,
+                                const char** fontsdir);
 
 #endif // #ifdef SK_BUILD_FOR_ANDROID
-#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
-
-#include "SkPaintOptionsAndroid.h"
-#include "../harfbuzz_ng/src/hb.h"
-
-/**
- *  Return a new typeface for a fallback script. If the script is
- *  not valid, or can not map to a font, returns null.
- *  @param  script   The harfbuzz script id.
- *  @param  style    The font style, for example bold
- *  @param  elegant  true if we want the web friendly elegant version of the font
- *  @return          reference to the matching typeface. Caller must call
- *                   unref() when they are done.
- */
-SK_API SkTypeface* SkCreateTypefaceForScript(hb_script_t script, SkTypeface::Style style,
-        SkPaintOptionsAndroid::FontVariant fontVariant = SkPaintOptionsAndroid::kDefault_Variant);
-
-#endif // #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
 #endif // #ifndef SkTypeface_android_DEFINED
diff --git a/include/text/SkTextLayout.h b/include/text/SkTextLayout.h
deleted file mode 100644
index 718acdb..0000000
--- a/include/text/SkTextLayout.h
+++ /dev/null
@@ -1,60 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkTextLayout_DEFINED
-#define SkTextLayout_DEFINED
-
-#include "SkPaint.h"
-#include "SkRefCnt.h"
-
-class SkTextStyle : public SkRefCnt {
-public:
-    SK_DECLARE_INST_COUNT(SkTextStyle)
-
-    SkTextStyle();
-    SkTextStyle(const SkTextStyle&);
-    explicit SkTextStyle(const SkPaint&);
-    virtual ~SkTextStyle();
-
-    const SkPaint& paint() const { return fPaint; }
-    SkPaint& paint() { return fPaint; }
-
-    // todo: bidi-override, language
-
-private:
-    SkPaint fPaint;
-
-    typedef SkRefCnt INHERITED;
-};
-
-class SkTextLayout {
-public:
-    SkTextLayout();
-    ~SkTextLayout();
-
-    void setText(const char text[], size_t length);
-    void setBounds(const SkRect& bounds);
-
-    SkTextStyle* getDefaultStyle() const { return fDefaultStyle; }
-    SkTextStyle* setDefaultStyle(SkTextStyle*);
-
-//    SkTextStyle* setStyle(SkTextStyle*, size_t offset, size_t length);
-
-    void draw(SkCanvas* canvas);
-
-private:
-    SkTDArray<char> fText;
-    SkTextStyle*    fDefaultStyle;
-    SkRect          fBounds;
-
-    // cache
-    struct Line;
-    struct GlyphRun;
-    SkTDArray<Line*> fLines;
-};
-
-#endif
diff --git a/include/utils/SkCountdown.h b/include/utils/SkCountdown.h
deleted file mode 100644
index 6bcec7d..0000000
--- a/include/utils/SkCountdown.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkCountdown_DEFINED
-#define SkCountdown_DEFINED
-
-#include "SkCondVar.h"
-#include "SkRunnable.h"
-#include "SkTypes.h"
-
-class SkCountdown : public SkRunnable {
-public:
-    explicit SkCountdown(int32_t count);
-
-    /**
-     * Resets the countdown to the count provided.
-     */
-    void reset(int32_t count);
-
-    virtual void run() SK_OVERRIDE;
-
-    /**
-     * Blocks until run() has been called count times.
-     */
-    void wait();
-
-private:
-    SkCondVar fReady;
-    int32_t   fCount;
-};
-
-#endif
diff --git a/include/utils/SkDeferredCanvas.h b/include/utils/SkDeferredCanvas.h
index 31ebce4..5f781f8 100644
--- a/include/utils/SkDeferredCanvas.h
+++ b/include/utils/SkDeferredCanvas.h
@@ -89,6 +89,11 @@
     bool isFreshFrame() const;
 
     /**
+     * Returns canvas's size.
+     */
+    SkISize getCanvasSize() const;
+
+    /**
      *  Returns true if the canvas has recorded draw commands that have
      *  not yet been played back.
      */
@@ -131,6 +136,7 @@
      * rendered using the deferred canvas.
      */
     void setBitmapSizeThreshold(size_t sizeThreshold);
+    size_t getBitmapSizeThreshold() const { return fBitmapSizeThreshold; }
 
     /**
      * Executes all pending commands without drawing
@@ -170,7 +176,7 @@
     virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
 
 protected:
-    virtual void willSave(SaveFlags) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
     virtual void willRestore() SK_OVERRIDE;
 
@@ -186,13 +192,18 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
-
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
+    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                             const SkPoint texCoords[4], SkXfermode* xmode,
+                             const SkPaint& paint) SK_OVERRIDE;
+    
     virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
 
-    virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
 public:
     class NotificationClient {
@@ -240,7 +251,12 @@
     bool isFullFrame(const SkRect*, const SkPaint*) const;
     void validate() const;
     void init();
-    bool            fDeferredDrawing;
+
+    size_t fBitmapSizeThreshold;
+    bool   fDeferredDrawing;
+
+    mutable SkISize fCachedCanvasSize;
+    mutable bool    fCachedCanvasSizeDirty;
 
     friend class SkDeferredCanvasTester; // for unit testing
     typedef SkCanvas INHERITED;
diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h
index 0aa5546..c0a105e 100644
--- a/include/utils/SkDumpCanvas.h
+++ b/include/utils/SkDumpCanvas.h
@@ -46,6 +46,7 @@
         kDrawText_Verb,
         kDrawPicture_Verb,
         kDrawVertices_Verb,
+        kDrawPatch_Verb,
         kDrawData_Verb,
 
         kBeginCommentGroup_Verb,
@@ -101,7 +102,7 @@
     virtual void endCommentGroup() SK_OVERRIDE;
 
 protected:
-    virtual void willSave(SaveFlags) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
     virtual void willRestore() SK_OVERRIDE;
 
@@ -117,6 +118,11 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
+    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                             const SkPoint texCoords[4], SkXfermode* xmode,
+                             const SkPaint& paint) SK_OVERRIDE;
     virtual void onPushCull(const SkRect& cullRect) SK_OVERRIDE;
     virtual void onPopCull() SK_OVERRIDE;
 
@@ -125,7 +131,7 @@
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
 
-    virtual void onDrawPicture(const SkPicture*) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
     static const char* EdgeStyleToAAString(ClipEdgeStyle edgeStyle);
 
diff --git a/include/utils/SkInterpolator.h b/include/utils/SkInterpolator.h
index 74789c8..18203d0 100644
--- a/include/utils/SkInterpolator.h
+++ b/include/utils/SkInterpolator.h
@@ -113,7 +113,6 @@
     */
     Result timeToValues(SkMSec time, SkScalar values[] = NULL) const;
 
-    SkDEBUGCODE(static void UnitTest();)
 private:
     SkScalar* fValues;  // pointer into fStorage
 #ifdef SK_DEBUG
diff --git a/include/utils/SkJSON.h b/include/utils/SkJSON.h
deleted file mode 100644
index c601fa8..0000000
--- a/include/utils/SkJSON.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkJSON_DEFINED
-#define SkJSON_DEFINED
-
-#include "SkTypes.h"
-
-class SkStream;
-class SkString;
-
-class SkJSON {
-public:
-    enum Type {
-        kObject,
-        kArray,
-        kString,
-        kInt,
-        kFloat,
-        kBool,
-    };
-
-    class Array;
-
-    class Object {
-    private:
-        struct Slot;
-
-    public:
-        Object();
-        Object(const Object&);
-        ~Object();
-
-        /**
-         *  Create a new slot with the specified name and value. The name
-         *  parameter is copied, but ownership of the Object parameter is
-         *  transferred. The Object parameter may be null, but the name must
-         *  not be null.
-         */
-        void addObject(const char name[], Object* value);
-
-        /**
-         *  Create a new slot with the specified name and value. The name
-         *  parameter is copied, but ownership of the Array parameter is
-         *  transferred. The Array parameter may be null, but the name must
-         *  not be null.
-         */
-        void addArray(const char name[], Array* value);
-
-        /**
-         *  Create a new slot with the specified name and value. Both parameters
-         *  are copied. The value parameter may be null, but the name must
-         *  not be null.
-         */
-        void addString(const char name[], const char value[]);
-
-        /**
-         *  Create a new slot with the specified name and value. The name
-         *  parameter is copied, and must not be null.
-         */
-        void addInt(const char name[], int32_t value);
-
-        /**
-         *  Create a new slot with the specified name and value. The name
-         *  parameter is copied, and must not be null.
-         */
-        void addFloat(const char name[], float value);
-
-        /**
-         *  Create a new slot with the specified name and value. The name
-         *  parameter is copied, and must not be null.
-         */
-        void addBool(const char name[], bool value);
-
-        /**
-         *  Return the number of slots/fields in this object. These can be
-         *  iterated using Iter.
-         */
-        int count() const;
-
-        /**
-         *  Returns true if a slot matching the name and Type is found.
-         */
-        bool find(const char name[], Type) const;
-        bool findObject(const char name[], Object** = NULL) const;
-        bool findArray(const char name[], Array** = NULL) const;
-        bool findString(const char name[], SkString* = NULL) const;
-        bool findInt(const char name[], int32_t* = NULL) const;
-        bool findFloat(const char name[], float* = NULL) const;
-        bool findBool(const char name[], bool* = NULL) const;
-
-        /**
-         *  Finds the first slot matching the name and Type and removes it.
-         *  Returns true if found, false if not.
-         */
-        bool remove(const char name[], Type);
-
-        void toDebugf() const;
-
-        /**
-         *  Iterator class which returns all of the fields/slots in an Object,
-         *  in the order that they were added.
-         */
-        class Iter {
-        public:
-            Iter(const Object&);
-
-            /**
-             *  Returns true when there are no more entries in the iterator.
-             *  In this case, no other methods should be called.
-             */
-            bool done() const;
-
-            /**
-             *  Moves the iterator to the next element. Should only be called
-             *  if done() returns false.
-             */
-            void next();
-
-            /**
-             *  Returns the type of the current element. Should only be called
-             *  if done() returns false.
-             */
-            Type type() const;
-
-            /**
-             *  Returns the name of the current element. Should only be called
-             *  if done() returns false.
-             */
-            const char* name() const;
-
-            /**
-             *  Returns the type of the current element. Should only be called
-             *  if done() returns false and type() returns kObject.
-             */
-            Object* objectValue() const;
-
-            /**
-             *  Returns the type of the current element. Should only be called
-             *  if done() returns false and type() returns kArray.
-             */
-            Array* arrayValue() const;
-
-            /**
-             *  Returns the type of the current element. Should only be called
-             *  if done() returns false and type() returns kString.
-             */
-            const char* stringValue() const;
-
-            /**
-             *  Returns the type of the current element. Should only be called
-             *  if done() returns false and type() returns kInt.
-             */
-            int32_t intValue() const;
-
-            /**
-             *  Returns the type of the current element. Should only be called
-             *  if done() returns false and type() returns kFloat.
-             */
-            float floatValue() const;
-
-            /**
-             *  Returns the type of the current element. Should only be called
-             *  if done() returns false and type() returns kBool.
-             */
-            bool boolValue() const;
-
-        private:
-            Slot* fSlot;
-        };
-
-    private:
-        Slot* fHead;
-        Slot* fTail;
-
-        const Slot* findSlot(const char name[], Type) const;
-        Slot* addSlot(Slot*);
-        void dumpLevel(int level) const;
-
-        friend class Array;
-    };
-
-    class Array {
-    public:
-        /**
-         *  Creates an array with the specified Type and element count. All
-         *  entries are initialized to NULL/0/false.
-         */
-        Array(Type, int count);
-
-        /**
-         *  Creates an array of ints, initialized by copying the specified
-         *  values.
-         */
-        Array(const int32_t values[], int count);
-
-        /**
-         *  Creates an array of floats, initialized by copying the specified
-         *  values.
-         */
-        Array(const float values[], int count);
-
-        /**
-         *  Creates an array of bools, initialized by copying the specified
-         *  values.
-         */
-        Array(const bool values[], int count);
-
-        Array(const Array&);
-        ~Array();
-
-        int count() const { return fCount; }
-        Type type() const { return fType; }
-
-        /**
-         *  Replace the element at the specified index with the specified
-         *  Object (which may be null). Ownership of the Object is transferred.
-         *  Should only be called if the Array's type is kObject.
-         */
-        void setObject(int index, Object*);
-
-        /**
-         *  Replace the element at the specified index with the specified
-         *  Array (which may be null). Ownership of the Array is transferred.
-         *  Should only be called if the Array's type is kArray.
-         */
-        void setArray(int index, Array*);
-
-        /**
-         *  Replace the element at the specified index with a copy of the
-         *  specified string (which may be null). Should only be called if the
-         *  Array's type is kString.
-         */
-        void setString(int index, const char str[]);
-
-        Object* const* objects() const {
-            SkASSERT(kObject == fType);
-            return fArray.fObjects;
-        }
-        Array* const* arrays() const {
-            SkASSERT(kObject == fType);
-            return fArray.fArrays;
-        }
-        const char* const* strings() const {
-            SkASSERT(kString == fType);
-            return fArray.fStrings;
-        }
-        int32_t* ints() const {
-            SkASSERT(kInt == fType);
-            return fArray.fInts;
-        }
-        float* floats() const {
-            SkASSERT(kFloat == fType);
-            return fArray.fFloats;
-        }
-        bool* bools() const {
-            SkASSERT(kBool == fType);
-            return fArray.fBools;
-        }
-
-    private:
-        int fCount;
-        Type fType;
-        union {
-            void*    fVoids;
-            Object** fObjects;
-            Array**  fArrays;
-            char**   fStrings;
-            int32_t* fInts;
-            float*   fFloats;
-            bool*    fBools;
-        } fArray;
-
-        void init(Type, int count, const void* src);
-        void dumpLevel(int level) const;
-
-        friend class Object;
-    };
-};
-
-#endif
diff --git a/include/utils/SkLua.h b/include/utils/SkLua.h
index a7fceaa..ad6f996 100644
--- a/include/utils/SkLua.h
+++ b/include/utils/SkLua.h
@@ -22,6 +22,7 @@
 class SkPath;
 struct SkRect;
 class SkRRect;
+class SkTextBlob;
 
 #define SkScalarToLua(x)    SkScalarToDouble(x)
 #define SkLuaToScalar(x)    SkDoubleToScalar(x)
@@ -60,6 +61,7 @@
     void pushCanvas(SkCanvas*, const char tableKey[] = NULL);
     void pushClipStack(const SkClipStack&, const char tableKey[] = NULL);
     void pushClipStackElement(const SkClipStack::Element& element, const char tableKey[] = NULL);
+    void pushTextBlob(const SkTextBlob*, const char tableKey[] = NULL);
 
     // This SkCanvas lua methods is declared here to benefit from SkLua's friendship with SkCanvas.
     static int lcanvas_getReducedClipStack(lua_State* L);
diff --git a/include/utils/SkLuaCanvas.h b/include/utils/SkLuaCanvas.h
index 6bef868..ea0e692 100644
--- a/include/utils/SkLuaCanvas.h
+++ b/include/utils/SkLuaCanvas.h
@@ -44,7 +44,7 @@
     virtual void drawData(const void* data, size_t length) SK_OVERRIDE;
 
 protected:
-    virtual void willSave(SaveFlags) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
     virtual void willRestore() SK_OVERRIDE;
 
@@ -60,13 +60,15 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
 
     virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
 
-    virtual void onDrawPicture(const SkPicture*) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
 private:
     lua_State*  fL;
diff --git a/include/utils/SkMatrix44.h b/include/utils/SkMatrix44.h
index 26247a0..83b5443 100644
--- a/include/utils/SkMatrix44.h
+++ b/include/utils/SkMatrix44.h
@@ -198,6 +198,10 @@
         return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
     }
 
+    inline bool hasPerspective() const {
+        return SkToBool(this->getType() & kPerspective_Mask);
+    }
+
     void setIdentity();
     inline void reset() { this->setIdentity();}
 
diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h
index bd19355..d3f5cca 100644
--- a/include/utils/SkNWayCanvas.h
+++ b/include/utils/SkNWayCanvas.h
@@ -59,7 +59,7 @@
 protected:
     SkTDArray<SkCanvas*> fList;
 
-    virtual void willSave(SaveFlags) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
     virtual void willRestore() SK_OVERRIDE;
 
@@ -75,13 +75,18 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
-
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
+    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                             const SkPoint texCoords[4], SkXfermode* xmode,
+                             const SkPaint& paint) SK_OVERRIDE;
+    
     virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
 
-    virtual void onDrawPicture(const SkPicture*) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
     class Iter;
 
diff --git a/include/utils/SkNoSaveLayerCanvas.h b/include/utils/SkNoSaveLayerCanvas.h
index 686f179..b692697 100644
--- a/include/utils/SkNoSaveLayerCanvas.h
+++ b/include/utils/SkNoSaveLayerCanvas.h
@@ -16,7 +16,9 @@
 // It also simplifies the clipping calls to only use rectangles.
 class SK_API SkNoSaveLayerCanvas : public SkCanvas {
 public:
-    SkNoSaveLayerCanvas(SkBaseDevice* device) : INHERITED(device) {}
+    SkNoSaveLayerCanvas(SkBaseDevice* device)
+        : INHERITED(device, NULL, kConservativeRasterClip_InitFlag)
+    {}
 
 protected:
     virtual SaveLayerStrategy willSaveLayer(const SkRect* bounds, const SkPaint* paint,
@@ -25,21 +27,6 @@
         return kNoLayer_SaveLayerStrategy;
     }
 
-    // disable aa for speed
-    virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
-        this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle);
-    }
-
-    // for speed, just respect the bounds, and disable AA. May give us a few
-    // false positives and negatives.
-    virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
-        this->updateClipConservativelyUsingBounds(path.getBounds(), op,
-                                                  path.isInverseFillType());
-    }
-    virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
-        this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false);
-    }
-
 private:
     typedef SkCanvas INHERITED;
 };
diff --git a/include/utils/SkPictureUtils.h b/include/utils/SkPictureUtils.h
index c35aca8..c35e1c7 100644
--- a/include/utils/SkPictureUtils.h
+++ b/include/utils/SkPictureUtils.h
@@ -26,7 +26,7 @@
      *  so the returned pointers are only valid while the picture is in scope
      *  and remains unchanged.
      */
-    static SkData* GatherPixelRefs(SkPicture* pict, const SkRect& area);
+    static SkData* GatherPixelRefs(const SkPicture* pict, const SkRect& area);
 
     /**
      * SkPixelRefContainer provides a base class for more elaborate pixel ref
diff --git a/include/utils/SkProxyCanvas.h b/include/utils/SkProxyCanvas.h
index 32f103c..27a8216 100644
--- a/include/utils/SkProxyCanvas.h
+++ b/include/utils/SkProxyCanvas.h
@@ -55,11 +55,8 @@
 
     virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
 
-    // Transitional, to facilitate migrating subclasses to the new willSave API.
-    using SkCanvas::willSave;
-
 protected:
-    virtual void willSave(SaveFlags) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
     virtual void willRestore() SK_OVERRIDE;
 
@@ -75,13 +72,18 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
-
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
+    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                             const SkPoint texCoords[4], SkXfermode* xmode,
+                             const SkPaint& paint) SK_OVERRIDE;
+    
     virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
 
-    virtual void onDrawPicture(const SkPicture*) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
 private:
     SkCanvas*   fProxy;
diff --git a/include/utils/SkRTConf.h b/include/utils/SkRTConf.h
index 4ba6070..dc95cdb 100644
--- a/include/utils/SkRTConf.h
+++ b/include/utils/SkRTConf.h
@@ -84,21 +84,20 @@
     template <typename T> void set(const char *confname,
                                    T value,
                                    bool warnIfNotFound = true);
-#ifdef SK_SUPPORT_UNITTEST
-    static void UnitTest();
-#endif
+
 private:
     template<typename T> friend class SkRTConf;
 
     void registerConf(SkRTConfBase *conf);
+
     template <typename T> bool parse(const char *name, T* value);
 
     SkTDArray<SkString *> fConfigFileKeys, fConfigFileValues;
     typedef SkTDict< SkTDArray<SkRTConfBase *> * > ConfMap;
     ConfMap fConfs;
-#ifdef SK_SUPPORT_UNITTEST
-    SkRTConfRegistry(bool);
-#endif
+
+    template <typename T>
+    friend bool test_rt_conf_parse(SkRTConfRegistry*, const char* name, T* value);
 };
 
 // our singleton registry
diff --git a/include/utils/SkRunnable.h b/include/utils/SkRunnable.h
deleted file mode 100644
index 5acf4db..0000000
--- a/include/utils/SkRunnable.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkRunnable_DEFINED
-#define SkRunnable_DEFINED
-
-template <typename T>
-struct SkTRunnable {
-    virtual ~SkTRunnable() {};
-    virtual void run(T&) = 0;
-};
-
-template <>
-struct SkTRunnable<void> {
-    virtual ~SkTRunnable() {};
-    virtual void run() = 0;
-};
-
-typedef SkTRunnable<void> SkRunnable;
-
-#endif
diff --git a/include/utils/SkThreadPool.h b/include/utils/SkThreadPool.h
deleted file mode 100644
index c99c5c4..0000000
--- a/include/utils/SkThreadPool.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkThreadPool_DEFINED
-#define SkThreadPool_DEFINED
-
-#include "SkCondVar.h"
-#include "SkRunnable.h"
-#include "SkTDArray.h"
-#include "SkTInternalLList.h"
-#include "SkThreadUtils.h"
-#include "SkTypes.h"
-
-#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID)
-#    include <unistd.h>
-#endif
-
-// Returns the number of cores on this machine.
-static inline int num_cores() {
-#if defined(SK_BUILD_FOR_WIN32)
-    SYSTEM_INFO sysinfo;
-    GetSystemInfo(&sysinfo);
-    return sysinfo.dwNumberOfProcessors;
-#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID)
-    return (int) sysconf(_SC_NPROCESSORS_ONLN);
-#else
-    return 1;
-#endif
-}
-
-template <typename T>
-class SkTThreadPool {
-public:
-    /**
-     * Create a threadpool with count threads, or one thread per core if kThreadPerCore.
-     */
-    static const int kThreadPerCore = -1;
-    explicit SkTThreadPool(int count);
-    ~SkTThreadPool();
-
-    /**
-     * Queues up an SkRunnable to run when a thread is available, or synchronously if count is 0.
-     * Does not take ownership. NULL is a safe no-op.  If T is not void, the runnable will be passed
-     * a reference to a T on the thread's local stack.
-     */
-    void add(SkTRunnable<T>*);
-
-    /**
-     * Same as add, but adds the runnable as the very next to run rather than enqueueing it.
-     */
-    void addNext(SkTRunnable<T>*);
-
-    /**
-     * Block until all added SkRunnables have completed.  Once called, calling add() is undefined.
-     */
-    void wait();
-
- private:
-    struct LinkedRunnable {
-        SkTRunnable<T>* fRunnable;  // Unowned.
-        SK_DECLARE_INTERNAL_LLIST_INTERFACE(LinkedRunnable);
-    };
-
-    enum State {
-        kRunning_State,  // Normal case.  We've been constructed and no one has called wait().
-        kWaiting_State,  // wait has been called, but there still might be work to do or being done.
-        kHalting_State,  // There's no work to do and no thread is busy.  All threads can shut down.
-    };
-
-    void addSomewhere(SkTRunnable<T>* r,
-                      void (SkTInternalLList<LinkedRunnable>::*)(LinkedRunnable*));
-
-    SkTInternalLList<LinkedRunnable> fQueue;
-    SkCondVar                        fReady;
-    SkTDArray<SkThread*>             fThreads;
-    State                            fState;
-    int                              fBusyThreads;
-
-    static void Loop(void*);  // Static because we pass in this.
-};
-
-template <typename T>
-SkTThreadPool<T>::SkTThreadPool(int count) : fState(kRunning_State), fBusyThreads(0) {
-    if (count < 0) {
-        count = num_cores();
-    }
-    // Create count threads, all running SkTThreadPool::Loop.
-    for (int i = 0; i < count; i++) {
-        SkThread* thread = SkNEW_ARGS(SkThread, (&SkTThreadPool::Loop, this));
-        *fThreads.append() = thread;
-        thread->start();
-    }
-}
-
-template <typename T>
-SkTThreadPool<T>::~SkTThreadPool() {
-    if (kRunning_State == fState) {
-        this->wait();
-    }
-}
-
-namespace SkThreadPoolPrivate {
-
-template <typename T>
-struct ThreadLocal {
-    void run(SkTRunnable<T>* r) { r->run(data); }
-    T data;
-};
-
-template <>
-struct ThreadLocal<void> {
-    void run(SkTRunnable<void>* r) { r->run(); }
-};
-
-}  // namespace SkThreadPoolPrivate
-
-template <typename T>
-void SkTThreadPool<T>::addSomewhere(SkTRunnable<T>* r,
-                                    void (SkTInternalLList<LinkedRunnable>::* f)(LinkedRunnable*)) {
-    if (r == NULL) {
-        return;
-    }
-
-    if (fThreads.isEmpty()) {
-        SkThreadPoolPrivate::ThreadLocal<T> threadLocal;
-        threadLocal.run(r);
-        return;
-    }
-
-    LinkedRunnable* linkedRunnable = SkNEW(LinkedRunnable);
-    linkedRunnable->fRunnable = r;
-    fReady.lock();
-    SkASSERT(fState != kHalting_State);  // Shouldn't be able to add work when we're halting.
-    (fQueue.*f)(linkedRunnable);
-    fReady.signal();
-    fReady.unlock();
-}
-
-template <typename T>
-void SkTThreadPool<T>::add(SkTRunnable<T>* r) {
-    this->addSomewhere(r, &SkTInternalLList<LinkedRunnable>::addToTail);
-}
-
-template <typename T>
-void SkTThreadPool<T>::addNext(SkTRunnable<T>* r) {
-    this->addSomewhere(r, &SkTInternalLList<LinkedRunnable>::addToHead);
-}
-
-
-template <typename T>
-void SkTThreadPool<T>::wait() {
-    fReady.lock();
-    fState = kWaiting_State;
-    fReady.broadcast();
-    fReady.unlock();
-
-    // Wait for all threads to stop.
-    for (int i = 0; i < fThreads.count(); i++) {
-        fThreads[i]->join();
-        SkDELETE(fThreads[i]);
-    }
-    SkASSERT(fQueue.isEmpty());
-}
-
-template <typename T>
-/*static*/ void SkTThreadPool<T>::Loop(void* arg) {
-    // The SkTThreadPool passes itself as arg to each thread as they're created.
-    SkTThreadPool<T>* pool = static_cast<SkTThreadPool<T>*>(arg);
-    SkThreadPoolPrivate::ThreadLocal<T> threadLocal;
-
-    while (true) {
-        // We have to be holding the lock to read the queue and to call wait.
-        pool->fReady.lock();
-        while(pool->fQueue.isEmpty()) {
-            // Does the client want to stop and are all the threads ready to stop?
-            // If so, we move into the halting state, and whack all the threads so they notice.
-            if (kWaiting_State == pool->fState && pool->fBusyThreads == 0) {
-                pool->fState = kHalting_State;
-                pool->fReady.broadcast();
-            }
-            // Any time we find ourselves in the halting state, it's quitting time.
-            if (kHalting_State == pool->fState) {
-                pool->fReady.unlock();
-                return;
-            }
-            // wait yields the lock while waiting, but will have it again when awoken.
-            pool->fReady.wait();
-        }
-        // We've got the lock back here, no matter if we ran wait or not.
-
-        // The queue is not empty, so we have something to run.  Claim it.
-        LinkedRunnable* r = pool->fQueue.head();
-
-        pool->fQueue.remove(r);
-
-        // Having claimed our SkRunnable, we now give up the lock while we run it.
-        // Otherwise, we'd only ever do work on one thread at a time, which rather
-        // defeats the point of this code.
-        pool->fBusyThreads++;
-        pool->fReady.unlock();
-
-        // OK, now really do the work.
-        threadLocal.run(r->fRunnable);
-        SkDELETE(r);
-
-        // Let everyone know we're not busy.
-        pool->fReady.lock();
-        pool->fBusyThreads--;
-        pool->fReady.unlock();
-    }
-
-    SkASSERT(false); // Unreachable.  The only exit happens when pool->fState is kHalting_State.
-}
-
-typedef SkTThreadPool<void> SkThreadPool;
-
-#endif
diff --git a/include/utils/SkWGL.h b/include/utils/SkWGL.h
index 5f630a1..d502eb0 100644
--- a/include/utils/SkWGL.h
+++ b/include/utils/SkWGL.h
@@ -56,6 +56,8 @@
 #define SK_ERROR_INVALID_VERSION                    0x2095
 #define SK_ERROR_INVALID_PROFILE                    0x2096
 
+DECLARE_HANDLE(HPBUFFER);
+
 class SkWGLExtensions {
 public:
     SkWGLExtensions();
@@ -73,6 +75,13 @@
     BOOL getPixelFormatAttribfv(HDC hdc, int, int, UINT, const int*, FLOAT*) const;
     HGLRC createContextAttribs(HDC, HGLRC, const int *) const;
 
+    BOOL swapInterval(int interval) const;
+
+    HPBUFFER createPbuffer(HDC, int , int, int, const int*) const;
+    HDC getPbufferDC(HPBUFFER) const;
+    int releasePbufferDC(HPBUFFER, HDC) const;
+    BOOL destroyPbuffer(HPBUFFER) const;
+
     /**
      * WGL doesn't have precise rules for the ordering of formats returned
      * by wglChoosePixelFormat. This function helps choose among the set of
@@ -89,27 +98,71 @@
     int selectFormat(const int formats[],
                      int formatCount,
                      HDC dc,
-                     int desiredSampleCount);
+                     int desiredSampleCount) const;
 private:
-    typedef const char* (WINAPI *GetExtensionsStringProc)(HDC hdc);
-    typedef BOOL (WINAPI *ChoosePixelFormatProc)(HDC hdc, const int *, const FLOAT *, UINT, int *, UINT *);
+    typedef const char* (WINAPI *GetExtensionsStringProc)(HDC);
+    typedef BOOL (WINAPI *ChoosePixelFormatProc)(HDC, const int *, const FLOAT *, UINT, int *, UINT *);
     typedef BOOL (WINAPI *GetPixelFormatAttribivProc)(HDC, int, int, UINT, const int*, int*);
-    typedef BOOL (WINAPI *GetPixelFormatAttribfvProc)(HDC hdc, int, int, UINT, const int*, FLOAT*);
-    typedef HGLRC (WINAPI *CreateContextAttribsProc)(HDC hDC, HGLRC, const int *);
+    typedef BOOL (WINAPI *GetPixelFormatAttribfvProc)(HDC, int, int, UINT, const int*, FLOAT*);
+    typedef HGLRC (WINAPI *CreateContextAttribsProc)(HDC, HGLRC, const int *);
+    typedef BOOL (WINAPI* SwapIntervalProc)(int);
+    typedef HPBUFFER (WINAPI* CreatePbufferProc)(HDC, int , int, int, const int*);
+    typedef HDC (WINAPI* GetPbufferDCProc)(HPBUFFER);
+    typedef int (WINAPI* ReleasePbufferDCProc)(HPBUFFER, HDC);
+    typedef BOOL (WINAPI* DestroyPbufferProc)(HPBUFFER);
 
     GetExtensionsStringProc fGetExtensionsString;
     ChoosePixelFormatProc fChoosePixelFormat;
     GetPixelFormatAttribfvProc fGetPixelFormatAttribfv;
     GetPixelFormatAttribivProc fGetPixelFormatAttribiv;
     CreateContextAttribsProc fCreateContextAttribs;
+    SwapIntervalProc fSwapInterval;
+    CreatePbufferProc fCreatePbuffer;
+    GetPbufferDCProc fGetPbufferDC;
+    ReleasePbufferDCProc fReleasePbufferDC;
+    DestroyPbufferProc fDestroyPbuffer;
 };
 
+enum SkWGLContextRequest {
+    /** Requests to create core profile context if possible, otherwise
+        compatibility profile. */
+    kGLPreferCoreProfile_SkWGLContextRequest,
+    /** Requests to create compatibility profile context if possible, otherwise
+        core profile. */
+    kGLPreferCompatibilityProfile_SkWGLContextRequest,
+    /** Requests to create GL ES profile context. */
+    kGLES_SkWGLContextRequest
+};
 /**
  * Helper to create an OpenGL context for a DC using WGL. Configs with a sample count >= to
  * msaaSampleCount are preferred but if none is available then a context with a lower sample count
  * (including non-MSAA) will be created. If preferCoreProfile is true but a core profile cannot be
  * created then a compatible profile context will be created.
  */
-HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool preferCoreProfile);
+HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, SkWGLContextRequest context);
+
+/**
+ * Helper class for creating a pbuffer context and deleting all the handles when finished. This
+ * requires that a device context has been created. However, the pbuffer gets its own device
+ * context. The original device context can be released once the pbuffer context is created.
+ */
+class SkWGLPbufferContext : public SkRefCnt {
+public:
+    static SkWGLPbufferContext* Create(HDC parentDC, int msaaSampleCount,
+                                       SkWGLContextRequest contextType);
+
+    virtual ~SkWGLPbufferContext();
+
+    HDC getDC() const { return fDC; }
+    HGLRC getGLRC() const { return fGLRC; }
+
+private:
+    SkWGLPbufferContext(HPBUFFER pbuffer, HDC dc, HGLRC glrc);
+
+    HPBUFFER        fPbuffer;
+    HDC             fDC;
+    HGLRC           fGLRC;
+    SkWGLExtensions fExtensions;
+};
 
 #endif
diff --git a/include/utils/win/SkTScopedComPtr.h b/include/utils/win/SkTScopedComPtr.h
index 8f18a42..38d1048 100644
--- a/include/utils/win/SkTScopedComPtr.h
+++ b/include/utils/win/SkTScopedComPtr.h
@@ -54,7 +54,7 @@
     T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; }
     T *get() const { return fPtr; }
     void reset() {
-        if (NULL != this->fPtr) {
+        if (this->fPtr) {
             this->fPtr->Release();
             this->fPtr = NULL;
         }
diff --git a/include/views/SkApplication.h b/include/views/SkApplication.h
index 8369f68..8f63539 100644
--- a/include/views/SkApplication.h
+++ b/include/views/SkApplication.h
@@ -16,4 +16,15 @@
 extern void application_init();
 extern void application_term();
 
+#ifdef SK_BUILD_FOR_IOS
+enum IOS_launch_type {
+    kError_iOSLaunchType = -1,
+    kTool_iOSLaunchType = 0,
+    kApplication__iOSLaunchType = 1
+};
+
+extern IOS_launch_type set_cmd_line_args(int argc, char *argv[],
+                                         const char* resourceDir);
+#endif
+
 #endif // SkApplication_DEFINED
diff --git a/include/views/SkOSMenu.h b/include/views/SkOSMenu.h
index 8801a52..7325418 100644
--- a/include/views/SkOSMenu.h
+++ b/include/views/SkOSMenu.h
@@ -129,7 +129,7 @@
      */
     int appendAction(const char label[], SkEventSinkID target);
     int appendList(const char label[], const char slotName[],
-                   SkEventSinkID target, int defaultIndex, const char[] ...);
+                   SkEventSinkID target, int defaultIndex, const char* ...);
     int appendSlider(const char label[], const char slotName[],
                      SkEventSinkID target, SkScalar min, SkScalar max,
                      SkScalar defaultValue);
diff --git a/include/views/SkView.h b/include/views/SkView.h
index d03c741..c083cf1 100644
--- a/include/views/SkView.h
+++ b/include/views/SkView.h
@@ -210,7 +210,7 @@
      *  Return true on success; false on failure
      */
     bool        globalToLocal(SkPoint* pt) const {
-        if (NULL != pt) {
+        if (pt) {
             return this->globalToLocal(pt->fX, pt->fY, pt);
         }
         return true;  // nothing to do so return true
diff --git a/include/views/SkWindow.h b/include/views/SkWindow.h
index 2a9315d..40cc5ec 100644
--- a/include/views/SkWindow.h
+++ b/include/views/SkWindow.h
@@ -21,8 +21,7 @@
 #endif
 //#define USE_GX_SCREEN
 
-class SkCanvas;
-
+class SkSurface;
 class SkOSMenu;
 
 class SkWindow : public SkView {
@@ -59,7 +58,7 @@
     void    preConcat(const SkMatrix&);
     void    postConcat(const SkMatrix&);
 
-    virtual SkCanvas* createCanvas();
+    virtual SkSurface* createSurface();
 
     virtual void onPDFSaved(const char title[], const char desc[],
         const char path[]) {}
diff --git a/platform_tools/android/bin/adb_pull_if_needed b/platform_tools/android/bin/adb_pull_if_needed
new file mode 100755
index 0000000..f4992b2
--- /dev/null
+++ b/platform_tools/android/bin/adb_pull_if_needed
@@ -0,0 +1,10 @@
+#!/bin/bash
+#
+# Copy the contents of a directory from a device to the host.
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source $SCRIPT_DIR/android_setup.sh
+source $SCRIPT_DIR/utils/setup_adb.sh
+
+adb_pull_if_needed ${APP_ARGS[@]}
+exit $?
diff --git a/platform_tools/android/bin/adb_push_if_needed b/platform_tools/android/bin/adb_push_if_needed
new file mode 100755
index 0000000..96e093f
--- /dev/null
+++ b/platform_tools/android/bin/adb_push_if_needed
@@ -0,0 +1,10 @@
+#!/bin/bash
+#
+# Copy the contents of a directory from the host to a device.
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source $SCRIPT_DIR/android_setup.sh
+source $SCRIPT_DIR/utils/setup_adb.sh
+
+adb_push_if_needed ${APP_ARGS[@]}
+exit $?
diff --git a/platform_tools/android/bin/android_gdb_exe b/platform_tools/android/bin/android_gdb_exe
index 64be9bb..4229994 100755
--- a/platform_tools/android/bin/android_gdb_exe
+++ b/platform_tools/android/bin/android_gdb_exe
@@ -29,13 +29,16 @@
     echo "file ${GDB_TMP_DIR}/skia_launcher"
     echo "target remote :${PORT}"
     echo "set solib-absolute-prefix ${GDB_TMP_DIR}"
-    echo "set solib-search-path ${GDB_TMP_DIR}
+    echo "set solib-search-path ${GDB_TMP_DIR}"
 
     # The apps shared library symbols are not loaded by default so we
-    # load them here."
+    # load them here.
     echo "break launch_app"
     echo "continue"
     echo "sharedLibrary ${APP_NAME}"
+
+    # Load libskia_android.so here.
+    echo "sharedLibrary skia_android"
 } > $GDBSETUP
 
 
diff --git a/platform_tools/android/bin/android_gdbserver b/platform_tools/android/bin/android_gdbserver
index 6c98b54..b1391c7 100755
--- a/platform_tools/android/bin/android_gdbserver
+++ b/platform_tools/android/bin/android_gdbserver
@@ -22,7 +22,11 @@
 mkdir -p $GDB_TMP_DIR
 
 echo "Copying symbol files"
-SYSTEM_LIBRARY_PATH=/system/lib
+if [[ $ANDROID_ARCH == *64* ]]; then
+  SYSTEM_LIBRARY_PATH=/system/lib64
+else
+  SYSTEM_LIBRARY_PATH=/system/lib
+fi
 for library_file in \
     libc.so \
     libstdc++.so \
@@ -30,17 +34,28 @@
     liblog.so \
     libz.so \
     libgccdemangle.so \
-    libcorkscrew.so \
+    libsigchain.so \
+    libcutils.so \
+    libunwind.so \
+    libunwind-ptrace.so \
+    libbacktrace.so \
     libutils.so \
     libstlport.so \
     libGLES_trace.so \
     libEGL.so \
     libGLESv2.so \
     ; do
-    adb_pull_if_needed "${SYSTEM_LIBRARY_PATH}/${library_file}" $GDB_TMP_DIR
+    ANDROID_LS=`$ADB $DEVICE_SERIAL shell ls -ld ${SYSTEM_LIBRARY_PATH}/${library_file}`
+    if [ "${ANDROID_LS:0:1}" == "-" ]; then
+      adb_pull_if_needed "${SYSTEM_LIBRARY_PATH}/${library_file}" $GDB_TMP_DIR
+    fi
 done
 
-adb_pull_if_needed /system/bin/linker $GDB_TMP_DIR
+if [[ $ANDROID_ARCH == *64* ]]; then
+  adb_pull_if_needed /system/bin/linker64 $GDB_TMP_DIR
+else
+  adb_pull_if_needed /system/bin/linker $GDB_TMP_DIR
+fi
 
 echo "Pushing app..."
 for file in \
@@ -53,7 +68,7 @@
 done
 
 echo "Pushing gdbserver..."
-adb_push_if_needed $ANDROID_TOOLCHAIN/../gdbserver data/local/tmp
+adb_push_if_needed $ANDROID_TOOLCHAIN/../gdbserver /data/local/tmp
 
 echo "Setting up port forward"
 $ADB forward "tcp:5039" "tcp:5039"
@@ -65,4 +80,4 @@
 
 # Starting up gdbserver in android shell
 echo "Starting gdbserver with command: ${APP_ARGS[@]}"
-$ADB shell /data/local/tmp/gdbserver :5039 /data/local/tmp/skia_launcher ${APP_ARGS[@]} &
+$ADB shell LD_LIBRARY_PATH=/data/local/tmp:\$LD_LIBRARY_PATH /data/local/tmp/gdbserver :5039 /data/local/tmp/skia_launcher ${APP_ARGS[@]} &
diff --git a/platform_tools/android/bin/android_run_skia b/platform_tools/android/bin/android_run_skia
index 7176fd2..81c4fee 100755
--- a/platform_tools/android/bin/android_run_skia
+++ b/platform_tools/android/bin/android_run_skia
@@ -19,10 +19,14 @@
     adb_push_if_needed "${SKIA_OUT}/$BUILDTYPE/lib/libskia_android.so" /data/local/tmp
 fi
 adb_push_if_needed "${SKIA_OUT}/$BUILDTYPE/lib/lib${APP_ARGS[0]}.so" /data/local/tmp
+if [[ -n $RESOURCE_PATH ]]; then
+  adb_push_if_needed "${SKIA_SRC_DIR}/resources" $RESOURCE_PATH
+fi
 
 STATUS_FILENAME="/data/local/tmp/.skia_tmp_$(date +%s%N)"
 $ADB ${DEVICE_SERIAL} shell \
-    "/data/local/tmp/skia_launcher ${APP_ARGS[*]}; echo \$? > ${STATUS_FILENAME}"
+    "LD_LIBRARY_PATH=/data/local/tmp:$LD_LIBRARY_PATH \
+     /data/local/tmp/skia_launcher ${APP_ARGS[*]}; echo \$? > ${STATUS_FILENAME}"
 if [ -z "$($ADB $DEVICE_SERIAL shell 'if [ -f $STATUS_FILENAME ]; then echo exists; fi')" ]; then
   echo "***********************************************************************"
   echo "The application terminated unexpectedly and did not produce an exit code"
diff --git a/platform_tools/android/bin/android_setup.sh b/platform_tools/android/bin/android_setup.sh
index 9ca8454..65774e5 100755
--- a/platform_tools/android/bin/android_setup.sh
+++ b/platform_tools/android/bin/android_setup.sh
@@ -11,6 +11,10 @@
   if [[ "$1" == "-d" ]]; then
     DEVICE_ID=$2
     shift
+  elif [[ "$1" == "-i" || "$1" == "--resourcePath" ]]; then
+    RESOURCE_PATH=$2
+    APP_ARGS=("${APP_ARGS[@]}" "${1}" "${2}")
+    shift
   elif [[ "$1" == "-s" ]]; then
     DEVICE_SERIAL="-s $2"
     shift
@@ -107,16 +111,24 @@
       DEFINES="${DEFINES} skia_resource_cache_mb_limit=32"
       ANDROID_ARCH="arm"
       ;;
-    intel_rhb | razr_i | x86)
+    intel_rhb | razr_i)
       DEFINES="${DEFINES} skia_arch_type=x86 skia_arch_width=32"
       DEFINES="${DEFINES} skia_resource_cache_mb_limit=32"
       ANDROID_ARCH="x86"
       ;;
+    x86)
+      DEFINES="${DEFINES} skia_arch_type=x86 skia_arch_width=32"
+      ANDROID_ARCH="x86"
+      ;;
+    x86_64 | x64)
+      DEFINES="${DEFINES} skia_arch_type=x86 skia_arch_width=64"
+      ANDROID_ARCH="x86_64"
+      ;;
     arm_v7)
       DEFINES="${DEFINES} skia_arch_type=arm arm_neon_optional=1 arm_version=7 arm_thumb=0"
       ANDROID_ARCH="arm"
       ;;
-    arm_v7_thumb | nvidia_logan)
+    arm_v7_thumb | nvidia_logan | nexus_5)
       DEFINES="${DEFINES} skia_arch_type=arm arm_neon_optional=1 arm_version=7 arm_thumb=1"
       ANDROID_ARCH="arm"
       ;;
@@ -128,11 +140,24 @@
       DEFINES="${DEFINES} skia_arch_type=arm arm_neon=0 arm_thumb=1"
       ANDROID_ARCH="arm"
       ;;
+    arm64)
+      DEFINES="${DEFINES} skia_arch_type=arm64 skia_arch_width=64"
+      ANDROID_ARCH="arm64"
+      ;;
     mips)
       DEFINES="${DEFINES} skia_arch_type=mips skia_arch_width=32"
       DEFINES="${DEFINES} skia_resource_cache_mb_limit=32"
       ANDROID_ARCH="mips"
       ;;
+    mips_dsp2)
+      DEFINES="${DEFINES} skia_arch_type=mips skia_arch_width=32"
+      DEFINES="${DEFINES} mips_arch_variant=mips32r2 mips_dsp=2"
+      ANDROID_ARCH="mips"
+      ;;
+    mips64)
+      DEFINES="${DEFINES} skia_arch_type=mips skia_arch_width=64"
+      ANDROID_ARCH="mips64"
+      ;;
     *)
       if [ -z "$ANDROID_IGNORE_UNKNOWN_DEVICE" ]; then
           echo "ERROR: unknown device $TARGET_DEVICE"
@@ -172,12 +197,6 @@
   ANDROID_SRC="$1"
   HOST_DST="$2"
 
-  if [ -d $HOST_DST ];
-  then
-    HOST_DST="${HOST_DST}/$(basename ${ANDROID_SRC})"
-  fi
-
-
   if [ -f $HOST_DST ];
   then
     #get the MD5 for dst and src
@@ -205,11 +224,12 @@
   source $SCRIPT_DIR/utils/setup_adb.sh
 
   # read input params
-  HOST_SRC="$1"
-  ANDROID_DST="$2"
+  local HOST_SRC="$1"
+  local ANDROID_DST="$2"
 
   ANDROID_LS=`$ADB $DEVICE_SERIAL shell ls -ld $ANDROID_DST`
-  if [ "${ANDROID_LS:0:1}" == "d" ];
+  HOST_LS=`ls -ld $HOST_SRC`
+  if [ "${ANDROID_LS:0:1}" == "d" -a "${HOST_LS:0:1}" == "-" ];
   then
     ANDROID_DST="${ANDROID_DST}/$(basename ${HOST_SRC})"
   fi
@@ -229,10 +249,20 @@
       echo -n "$ANDROID_DST "
       $ADB $DEVICE_SERIAL push $HOST_SRC $ANDROID_DST
     fi
+  elif [ "${ANDROID_LS:0:1}" == "d" ]; then
+    for FILE_ITEM in `ls $HOST_SRC`; do
+      adb_push_if_needed "${HOST_SRC}/${FILE_ITEM}" "${ANDROID_DST}/${FILE_ITEM}"
+    done
   else
-    echo -n "$ANDROID_DST "
-    $ADB $DEVICE_SERIAL shell mkdir -p "$(dirname "$ANDROID_DST")"
-    $ADB $DEVICE_SERIAL push $HOST_SRC $ANDROID_DST
+    HOST_LS=`ls -ld $HOST_SRC`
+    if [ "${HOST_LS:0:1}" == "d" ]; then
+      $ADB $DEVICE_SERIAL shell mkdir -p $ANDROID_DST
+      adb_push_if_needed $HOST_SRC $ANDROID_DST
+    else
+      echo -n "$ANDROID_DST "
+      $ADB $DEVICE_SERIAL shell mkdir -p "$(dirname "$ANDROID_DST")"
+      $ADB $DEVICE_SERIAL push $HOST_SRC $ANDROID_DST
+    fi
   fi
 }
 
diff --git a/platform_tools/android/bin/gyp_to_android.py b/platform_tools/android/bin/gyp_to_android.py
index 4015c38..a42471b 100755
--- a/platform_tools/android/bin/gyp_to_android.py
+++ b/platform_tools/android/bin/gyp_to_android.py
@@ -129,24 +129,16 @@
     generate_user_config.generate_user_config(
         original_sk_user_config=user_config,
         require_sk_user_config=require_sk_user_config, target_dir=dst_dir,
-        ordered_set=common.DEFINES)
-
-    tool_makefile_writer.generate_tool(gyp_dir=tmp_folder,
-                                       target_file='tests.gyp',
-                                       skia_trunk=target_dir,
-                                       dest_dir='tests',
-                                       skia_lib_var_dict=common,
-                                       local_module_name='skia_test',
-                                       local_module_tags=['tests'])
+        defines=common.DEFINES)
 
     tool_makefile_writer.generate_tool(gyp_dir=tmp_folder,
                                        target_file='bench.gyp',
                                        skia_trunk=target_dir,
                                        dest_dir='bench',
                                        skia_lib_var_dict=common,
-                                       local_module_name='skia_bench',
+                                       local_module_name='skia_nanobench',
                                        local_module_tags=['tests'],
-                                       place_in_local_tmp=True)
+                                       desired_targets=['nanobench'])
 
     tool_makefile_writer.generate_tool(gyp_dir=tmp_folder,
                                        target_file='gm.gyp',
@@ -154,7 +146,8 @@
                                        dest_dir='gm',
                                        skia_lib_var_dict=common,
                                        local_module_name='skia_gm',
-                                       local_module_tags=['tests'])
+                                       local_module_tags=['tests'],
+                                       desired_targets=['gm'])
 
     tool_makefile_writer.generate_tool(gyp_dir=tmp_folder,
                                        target_file='dm.gyp',
@@ -162,7 +155,8 @@
                                        dest_dir='dm',
                                        skia_lib_var_dict=common,
                                        local_module_name='skia_dm',
-                                       local_module_tags=['tests'])
+                                       local_module_tags=['tests'],
+                                       desired_targets=['dm'])
 
     # Now that the defines have been written to SkUserConfig and they've been
     # used to skip adding them to the tools makefiles, they are not needed in
diff --git a/platform_tools/android/bin/utils/setup_toolchain.sh b/platform_tools/android/bin/utils/setup_toolchain.sh
index 1e90616..ef49150 100755
--- a/platform_tools/android/bin/utils/setup_toolchain.sh
+++ b/platform_tools/android/bin/utils/setup_toolchain.sh
@@ -27,14 +27,19 @@
 fi
 
 function default_toolchain() {
-  API_LEVEL=14
-  NDK_REV=${NDK_REV-8e}
+  NDK_REV=${NDK_REV-10exp}
   ANDROID_ARCH=${ANDROID_ARCH-arm}
+  
+  if [[ $ANDROID_ARCH == *64* ]]; then
+    API_LEVEL=L # Experimental Android L-Release system images
+  else
+    API_LEVEL=14 # Official Android 4.0 system images  
+  fi
 
   TOOLCHAIN_DIR=${SCRIPT_DIR}/../toolchains
   if [ $(uname) == "Darwin" ]; then
     verbose "Using Mac toolchain."
-    TOOLCHAIN_TYPE=ndk-r$NDK_REV-$ANDROID_ARCH-mac_v$API_LEVEL
+    TOOLCHAIN_TYPE=ndk-r$NDK_REV-$ANDROID_ARCH-darwin_v$API_LEVEL
   else
     verbose "Using Linux toolchain."
     TOOLCHAIN_TYPE=ndk-r$NDK_REV-$ANDROID_ARCH-linux_v$API_LEVEL
@@ -93,4 +98,5 @@
 # This is required to build using ninja on a Mac.
 ln -sf $ANDROID_TOOLCHAIN_PREFIX-nm $ANDROID_TOOLCHAIN/nm
 ln -sf $ANDROID_TOOLCHAIN_PREFIX-readelf $ANDROID_TOOLCHAIN/readelf
+ln -sf $ANDROID_TOOLCHAIN_PREFIX-as $ANDROID_TOOLCHAIN/as
 exportVar PATH $ANDROID_TOOLCHAIN:$PATH
diff --git a/platform_tools/android/gyp/skia_android.gypi b/platform_tools/android/gyp/skia_android.gypi
index 9ebee7c..210a61a 100644
--- a/platform_tools/android/gyp/skia_android.gypi
+++ b/platform_tools/android/gyp/skia_android.gypi
@@ -9,16 +9,26 @@
       ],
       'variables': {
         'conditions': [
-          [ 'skia_arch_type == "x86"', {
+          [ 'skia_arch_type == "arm" and arm_version != 7', {
+            'android_arch%': "armeabi",
+          }],
+          [ 'skia_arch_type == "arm" and arm_version == 7', {
+            'android_arch%': "armeabi-v7a",
+          }],
+          [ 'skia_arch_type == "arm64"', {
+            'android_arch%': "arm64-v8a",
+          }],
+          [ 'skia_arch_type == "x86" and skia_arch_width == 32', {
             'android_arch%': "x86",
-          }, {
-            'conditions': [
-              [ 'arm_version == 7', {
-                'android_arch%': "armeabi-v7a",
-              }, {
-               'android_arch%': "armeabi",
-              }],
-            ],
+          }],
+          [ 'skia_arch_type == "x86" and skia_arch_width == 64', {
+            'android_arch%': "x86_64",
+          }],
+          [ 'skia_arch_type == "mips" and skia_arch_width == 32', {
+            'android_arch%': "mips",
+          }],
+          [ 'skia_arch_type == "mips" and skia_arch_width == 64', {
+            'android_arch%': "mips64",
           }],
         ],
       },
@@ -45,13 +55,6 @@
       ],
     },
     {
-      'target_name': 'skia_launcher',
-      'type': 'executable',
-      'sources': [
-        '../launcher/skia_launcher.cpp',
-      ],
-    },
-    {
       'target_name': 'SampleApp_APK',
       'type': 'none',
       'dependencies': [
diff --git a/platform_tools/android/gyp/skia_launcher.gypi b/platform_tools/android/gyp/skia_launcher.gypi
new file mode 100644
index 0000000..f9eec20
--- /dev/null
+++ b/platform_tools/android/gyp/skia_launcher.gypi
@@ -0,0 +1,9 @@
+{
+    'targets': [{
+        'target_name': 'skia_launcher',
+        'type': 'executable',
+        'cflags': [ '-fPIE' ],
+        'ldflags': [ '-pie' ],
+        'sources': [ '../launcher/skia_launcher.cpp' ],
+    }]
+}
diff --git a/platform_tools/android/gyp_gen/generate_user_config.py b/platform_tools/android/gyp_gen/generate_user_config.py
index 957c363..6858d93 100644
--- a/platform_tools/android/gyp_gen/generate_user_config.py
+++ b/platform_tools/android/gyp_gen/generate_user_config.py
@@ -29,7 +29,7 @@
 
 
 def generate_user_config(original_sk_user_config, require_sk_user_config,
-                         target_dir, ordered_set):
+                         target_dir, defines):
   """Generate the SkUserConfig file specific to the Android framework.
 
   Android needs its #defines in its skia/include/core directory, so that other
@@ -48,8 +48,7 @@
           written. Its name will be the same basename as
           original_sk_user_config. If None, the new file will be written to the
           working directory.
-      ordered_set: A vars_dict_lib.OrderedSet, containing a list of defines to
-          be appended to SkUserConfig.
+      defines: Iterable of defines to be appended to SkUserConfig.
 
   Raises:
       AssertionError: If original_sk_user_config does not exist.
@@ -95,7 +94,7 @@
     dst.write('#endif\n\n')
 
     # Now add the defines from the gyp files.
-    for item in ordered_set:
+    for item in sorted(defines):
       # Although our defines may have '=' in them, when written to the header
       # there should be a space between the macro and what it replaces.
       dst.write('#define ' + item.replace('=', ' ') + '\n')
diff --git a/platform_tools/android/gyp_gen/makefile_writer.py b/platform_tools/android/gyp_gen/makefile_writer.py
index e8f9773..d8d0c61 100644
--- a/platform_tools/android/gyp_gen/makefile_writer.py
+++ b/platform_tools/android/gyp_gen/makefile_writer.py
@@ -122,9 +122,6 @@
 # golden-master (fidelity / regression test)
 include $(BASE_PATH)/gm/Android.mk
 
-# unit-tests
-include $(BASE_PATH)/tests/Android.mk
-
 # diamond-master (one test to rule them all)
 include $(BASE_PATH)/dm/Android.mk
 """
@@ -149,28 +146,28 @@
     self.name = name
 
 def write_local_path(f):
-    """Add the LOCAL_PATH line to the makefile.
+  """Add the LOCAL_PATH line to the makefile.
 
-    Args:
-      f: File open for writing.
-    """
-    f.write('LOCAL_PATH:= $(call my-dir)\n')
+  Args:
+    f: File open for writing.
+  """
+  f.write('LOCAL_PATH:= $(call my-dir)\n')
 
 def write_clear_vars(f):
-    """Add the CLEAR_VARS line to the makefile.
+  """Add the CLEAR_VARS line to the makefile.
 
-    Args:
-      f: File open for writing.
-    """
-    f.write('include $(CLEAR_VARS)\n')
+  Args:
+    f: File open for writing.
+  """
+  f.write('include $(CLEAR_VARS)\n')
 
 def write_include_stlport(f):
-    """Add a line to include stlport.
+  """Add a line to include stlport.
 
-    Args:
-      f: File open for writing.
-    """
-    f.write('include external/stlport/libstlport.mk\n')
+  Args:
+    f: File open for writing.
+  """
+  f.write('include external/stlport/libstlport.mk\n')
 
 def write_android_mk(target_dir, common, deviations_from_common):
   """Given all the variables, write the final make file.
@@ -197,6 +194,15 @@
     f.write(DEBUGGING_HELP)
 
     write_clear_vars(f)
+
+    # need flags to enable feedback driven optimization (FDO) when requested
+    # by the build system.
+    f.write('LOCAL_FDO_SUPPORT := true\n')
+    f.write('ifneq ($(strip $(TARGET_FDO_CFLAGS)),)\n')
+    f.write('\t# This should be the last -Oxxx specified in LOCAL_CFLAGS\n')
+    f.write('\tLOCAL_CFLAGS += -O2\n')
+    f.write('endif\n\n')
+
     f.write('LOCAL_ARM_MODE := thumb\n')
 
     # need a flag to tell the C side when we're on devices with large memory
diff --git a/platform_tools/android/gyp_gen/tool_makefile_writer.py b/platform_tools/android/gyp_gen/tool_makefile_writer.py
index ac2a758..451b201 100644
--- a/platform_tools/android/gyp_gen/tool_makefile_writer.py
+++ b/platform_tools/android/gyp_gen/tool_makefile_writer.py
@@ -15,37 +15,30 @@
 import vars_dict_lib
 
 
-def write_tool_android_mk(target_dir, var_dict, place_in_local_tmp):
+def write_tool_android_mk(target_dir, var_dict):
   """Write Android.mk for a Skia tool.
 
   Args:
     target_dir: Destination for the makefile. Must not be None.
     var_dict: VarsDict containing variables for the makefile.
-    place_in_local_tmp: If True, the executable will be synced to
-      /data/local/tmp.
   """
   target_file = os.path.join(target_dir, 'Android.mk')
   with open(target_file, 'w') as f:
     f.write(makefile_writer.AUTOGEN_WARNING)
 
-    if place_in_local_tmp:
-      f.write('local_target_dir := $(TARGET_OUT_DATA)/local/tmp\n')
-
     makefile_writer.write_local_path(f)
     makefile_writer.write_clear_vars(f)
 
     makefile_writer.write_local_vars(f, var_dict, False, None)
 
-    if place_in_local_tmp:
-      f.write('LOCAL_MODULE_PATH := $(local_target_dir)\n')
-
     makefile_writer.write_include_stlport(f)
-    f.write('include $(BUILD_EXECUTABLE)\n')
+
+    f.write('include $(BUILD_NATIVE_TEST)\n')
 
 
 def generate_tool(gyp_dir, target_file, skia_trunk, dest_dir,
                   skia_lib_var_dict, local_module_name, local_module_tags,
-                  place_in_local_tmp=False):
+                  desired_targets):
   """Common steps for building one of the skia tools.
 
   Parse a gyp file and create an Android.mk for this tool.
@@ -62,8 +55,7 @@
       ensure we do not duplicate anything in this Android.mk.
     local_module_name: Name for this tool, to set as LOCAL_MODULE.
     local_module_tags: Tags to pass to LOCAL_MODULE_TAG.
-    place_in_local_tmp: If True, the executable will be synced to
-      /data/local/tmp.
+    desired_targets: List of targets to parse.
   """
   result_file = android_framework_gyp.main(target_dir=gyp_dir,
                                            target_file=target_file,
@@ -75,7 +67,7 @@
   # Add known targets from skia_lib, so we do not reparse them.
   var_dict.KNOWN_TARGETS.set(skia_lib_var_dict.KNOWN_TARGETS)
 
-  gypd_parser.parse_gypd(var_dict, result_file, dest_dir)
+  gypd_parser.parse_gypd(var_dict, result_file, dest_dir, desired_targets)
 
   android_framework_gyp.clean_gypd_files(gyp_dir)
 
@@ -101,5 +93,4 @@
   if not os.path.exists(full_dest):
     os.mkdir(full_dest)
 
-  write_tool_android_mk(target_dir=full_dest, var_dict=var_dict,
-                        place_in_local_tmp=place_in_local_tmp)
+  write_tool_android_mk(target_dir=full_dest, var_dict=var_dict)
diff --git a/platform_tools/android/tests/expectations/Android.mk b/platform_tools/android/tests/expectations/Android.mk
index 36c0e97..f5fbc29 100644
--- a/platform_tools/android/tests/expectations/Android.mk
+++ b/platform_tools/android/tests/expectations/Android.mk
@@ -33,6 +33,12 @@
 ###############################################################################
 
 include $(CLEAR_VARS)
+LOCAL_FDO_SUPPORT := true
+ifneq ($(strip $(TARGET_FDO_CFLAGS)),)
+	# This should be the last -Oxxx specified in LOCAL_CFLAGS
+	LOCAL_CFLAGS += -O2
+endif
+
 LOCAL_ARM_MODE := thumb
 ifeq ($(TARGET_ARCH),arm)
 	ifeq ($(ARCH_ARM_HAVE_VFP),true)
@@ -155,8 +161,5 @@
 # golden-master (fidelity / regression test)
 include $(BASE_PATH)/gm/Android.mk
 
-# unit-tests
-include $(BASE_PATH)/tests/Android.mk
-
 # diamond-master (one test to rule them all)
 include $(BASE_PATH)/dm/Android.mk
diff --git a/platform_tools/android/tests/expectations/SkUserConfig-h.txt b/platform_tools/android/tests/expectations/SkUserConfig-h.txt
index 78b69a4..a9f6a0c 100644
--- a/platform_tools/android/tests/expectations/SkUserConfig-h.txt
+++ b/platform_tools/android/tests/expectations/SkUserConfig-h.txt
@@ -37,7 +37,7 @@
 #define SK_BUILD_FOR_ANDROID
 #define SK_BUILD_FOR_ANDROID_FRAMEWORK
 #define SK_SCALAR_IS_FLOAT
-#define foo
 #define bar
+#define foo
 
 #endif // SkUserConfig_Android_DEFINED
diff --git a/platform_tools/android/tests/expectations/missing-filename.xxx b/platform_tools/android/tests/expectations/missing-filename.xxx
index d0d70d7..7c5319c 100644
--- a/platform_tools/android/tests/expectations/missing-filename.xxx
+++ b/platform_tools/android/tests/expectations/missing-filename.xxx
@@ -27,7 +27,7 @@
 #define SK_BUILD_FOR_ANDROID
 #define SK_BUILD_FOR_ANDROID_FRAMEWORK
 #define SK_SCALAR_IS_FLOAT
-#define foo
 #define bar
+#define foo
 
 #endif // SkUserConfig_Android_DEFINED
diff --git a/platform_tools/android/tests/expectations/tool/Android.mk b/platform_tools/android/tests/expectations/tool/Android.mk
index faac45d..0affe47 100644
--- a/platform_tools/android/tests/expectations/tool/Android.mk
+++ b/platform_tools/android/tests/expectations/tool/Android.mk
@@ -38,4 +38,4 @@
 	local_module
 
 include external/stlport/libstlport.mk
-include $(BUILD_EXECUTABLE)
+include $(BUILD_NATIVE_TEST)
diff --git a/platform_tools/android/tests/generate_user_config_tests.py b/platform_tools/android/tests/generate_user_config_tests.py
index 660757d..90689a6 100644
--- a/platform_tools/android/tests/generate_user_config_tests.py
+++ b/platform_tools/android/tests/generate_user_config_tests.py
@@ -41,7 +41,7 @@
               'bar' ]
   gen_config(original_sk_user_config=original_sk_user_config,
              require_sk_user_config=require_sk_user_config,
-             target_dir=target_dir, ordered_set=defines)
+             target_dir=target_dir, defines=defines)
 
 
 class GenUserConfigTest(unittest.TestCase):
@@ -55,10 +55,10 @@
     # With require_sk_user_config set to True, an AssertionError will be
     # thrown when original_sk_user_config is missing.
     with self.assertRaises(AssertionError):
-      ordered_set = [ 'define' ]
+      defines = [ 'define' ]
       gen_config(original_sk_user_config=original,
                  require_sk_user_config=True,
-                 target_dir=tmp, ordered_set=ordered_set)
+                 target_dir=tmp, defines=defines)
 
     # With require_sk_user_config set to False, it is okay for
     # original_sk_user_config to be missing.
diff --git a/platform_tools/android/tests/gyp_to_android_tests.py b/platform_tools/android/tests/gyp_to_android_tests.py
index 512ce36..434afd1 100644
--- a/platform_tools/android/tests/gyp_to_android_tests.py
+++ b/platform_tools/android/tests/gyp_to_android_tests.py
@@ -37,11 +37,6 @@
                                       test_variables.ANDROID_MK)
     self.assertTrue(os.path.exists(path_to_android_mk))
 
-    # In addition, there should be an 'Android.mk' inside /tests/
-    path_to_tests_android_mk = os.path.join(self.__tmp_dir, 'tests',
-                                            test_variables.ANDROID_MK)
-    self.assertTrue(os.path.exists(path_to_tests_android_mk))
-
   def tearDown(self):
     # Remove self.__tmp_dir, which is no longer needed.
     shutil.rmtree(self.__tmp_dir)
diff --git a/platform_tools/android/tests/makefile_writer_tests.py b/platform_tools/android/tests/makefile_writer_tests.py
index 374c2dd..6b72657 100644
--- a/platform_tools/android/tests/makefile_writer_tests.py
+++ b/platform_tools/android/tests/makefile_writer_tests.py
@@ -119,8 +119,7 @@
   """
   vars_dict = generate_dummy_vars_dict(None)
   tool_makefile_writer.write_tool_android_mk(target_dir=target_dir,
-                                             var_dict=vars_dict,
-                                             place_in_local_tmp=False)
+                                             var_dict=vars_dict)
 
 
 class MakefileWriterTest(unittest.TestCase):
diff --git a/platform_tools/nacl/src/nacl_interface.cpp b/platform_tools/nacl/src/nacl_interface.cpp
index 09d55c3..297458d 100644
--- a/platform_tools/nacl/src/nacl_interface.cpp
+++ b/platform_tools/nacl/src/nacl_interface.cpp
@@ -24,7 +24,7 @@
 SkiaInstance* gPluginInstance;
 
 // Main entry point for the app we're linked into
-extern int tool_main(int, char**);
+extern int test_main();
 
 // Tokenize a command line and store it in argc and argv.
 void SkStringToProgramArgs(const SkString commandLine, int* argc, char*** argv) {
@@ -68,7 +68,7 @@
     int argc;
     char** argv;
     SkStringToProgramArgs(commandLine, &argc, &argv);
-    tool_main(argc, argv);
+    test_main();
 }
 
 
diff --git a/resources/android_fonts/pre_v17/fallback_fonts.xml b/resources/android_fonts/pre_v17/fallback_fonts.xml
new file mode 100644
index 0000000..e23004b
--- /dev/null
+++ b/resources/android_fonts/pre_v17/fallback_fonts.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Fallback Fonts
+
+    This file specifies the fonts, and the priority order, that will be searched for any
+    glyphs not handled by the default fonts specified in /system/etc/system_fonts.xml.
+    Each entry consists of a family tag and a list of files (file names) which support that
+    family. The fonts for each family are listed in the order of the styles that they
+    handle (the order is: regular, bold, italic, and bold-italic). The order in which the
+    families are listed in this file represents the order in which these fallback fonts
+    will be searched for glyphs that are not supported by the default system fonts (which are
+    found in /system/etc/system_fonts.xml).
+
+    Note that there is not nameset for fallback fonts, unlike the fonts specified in
+    system_fonts.xml. The ability to support specific names in fallback fonts may be supported
+    in the future. For now, the lack of files entries here is an indicator to the system that
+    these are fallback fonts, instead of default named system fonts.
+
+    There is another optional file in /vendor/etc/fallback_fonts.xml. That file can be used to
+    provide references to other font families that should be used in addition to the default
+    fallback fonts. That file can also specify the order in which the fallback fonts should be
+    searched, to ensure that a vendor-provided font will be used before another fallback font
+    which happens to handle the same glyph.
+-->
+<familyset>
+    <family>
+        <fileset>
+            <file>DroidNaskh-Regular.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansEthiopic-Regular.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansHebrew-Regular.ttf</file>
+            <file>DroidSansHebrew-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansThai.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansArmenian.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansGeorgian.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>Lohit-Devanagari.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>Lohit-Bengali.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>Lohit-Tamil.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansFallback.ttf</file>
+        </fileset>
+    </family>
+</familyset>
diff --git a/resources/android_fonts/pre_v17/system_fonts.xml b/resources/android_fonts/pre_v17/system_fonts.xml
new file mode 100644
index 0000000..d2fe546
--- /dev/null
+++ b/resources/android_fonts/pre_v17/system_fonts.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    System Fonts
+
+    This file lists the font families that will be used by default for all supported glyphs.
+    Each entry consists of a family, various names that are supported by that family, and
+    up to four font files. The font files are listed in the order of the styles which they
+    support: regular, bold, italic and bold-italic. If less than four styles are listed, then
+    the styles with no associated font file will be supported by the other font files listed.
+
+    The first family is also the default font, which handles font request that have not specified
+    specific font names.
+
+    Any glyph that is not handled by the system fonts will cause a search of the fallback fonts.
+    The default fallback fonts are specified in the file /system/etc/fallback_fonts.xml, and there
+    is an optional file which may be supplied by vendors to specify other fallback fonts to use
+    in /vendor/etc/fallback_fonts.xml.
+-->
+<familyset>
+
+    <family>
+        <nameset>
+            <name>sans-serif</name>
+            <name>arial</name>
+            <name>helvetica</name>
+            <name>tahoma</name>
+            <name>verdana</name>
+        </nameset>
+        <fileset>
+            <file>Roboto-Regular.ttf</file>
+            <file>Roboto-Bold.ttf</file>
+            <file>Roboto-Italic.ttf</file>
+            <file>Roboto-BoldItalic.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>serif</name>
+            <name>times</name>
+            <name>times new roman</name>
+            <name>palatino</name>
+            <name>georgia</name>
+            <name>baskerville</name>
+            <name>goudy</name>
+            <name>fantasy</name>
+            <name>cursive</name>
+            <name>ITC Stone Serif</name>
+        </nameset>
+        <fileset>
+            <file>DroidSerif-Regular.ttf</file>
+            <file>DroidSerif-Bold.ttf</file>
+            <file>DroidSerif-Italic.ttf</file>
+            <file>DroidSerif-BoldItalic.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>Droid Sans</name>
+        </nameset>
+        <fileset>
+            <file>DroidSans.ttf</file>
+            <file>DroidSans-Bold.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>monospace</name>
+            <name>courier</name>
+            <name>courier new</name>
+            <name>monaco</name>
+        </nameset>
+        <fileset>
+            <file>DroidSansMono.ttf</file>
+        </fileset>
+    </family>
+
+</familyset>
diff --git a/resources/android_fonts/v17/fallback_fonts.xml b/resources/android_fonts/v17/fallback_fonts.xml
new file mode 100644
index 0000000..ede7ef4
--- /dev/null
+++ b/resources/android_fonts/v17/fallback_fonts.xml
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Fallback Fonts
+
+    This file specifies the fonts, and the priority order, that will be searched for any
+    glyphs not handled by the default fonts specified in /system/etc/system_fonts.xml.
+    Each entry consists of a family tag and a list of files (file names) which support that
+    family. The fonts for each family are listed in the order of the styles that they
+    handle (the order is: regular, bold, italic, and bold-italic). The order in which the
+    families are listed in this file represents the order in which these fallback fonts
+    will be searched for glyphs that are not supported by the default system fonts (which are
+    found in /system/etc/system_fonts.xml).
+
+    Note that there is not nameset for fallback fonts, unlike the fonts specified in
+    system_fonts.xml. The ability to support specific names in fallback fonts may be supported
+    in the future. For now, the lack of files entries here is an indicator to the system that
+    these are fallback fonts, instead of default named system fonts.
+
+    There is another optional file in /vendor/etc/fallback_fonts.xml. That file can be used to
+    provide references to other font families that should be used in addition to the default
+    fallback fonts. That file can also specify the order in which the fallback fonts should be
+    searched, to ensure that a vendor-provided font will be used before another fallback font
+    which happens to handle the same glyph.
+
+    Han languages (Chinese, Japanese, and Korean) share a common range of unicode characters;
+    their ordering in the fallback or vendor files gives priority to the first in the list.
+    Language-specific ordering can be configured by adding a BCP 47-style "lang" attribute to
+    a "file" element; fonts matching the language of text being drawn will be prioritised over
+    all others.
+-->
+<familyset>
+    <family>
+        <fileset>
+            <file variant="elegant">DroidNaskh-Regular.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">DroidNaskhUI-Regular.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansEthiopic-Regular.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansHebrew-Regular.ttf</file>
+            <file>DroidSansHebrew-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansThai-Regular.ttf</file>
+            <file variant="elegant">NotoSansThai-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansThaiUI-Regular.ttf</file>
+            <file variant="compact">NotoSansThaiUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansArmenian.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansGeorgian.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansDevanagari-Regular.ttf</file>
+            <file variant="elegant">NotoSansDevanagari-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansDevanagariUI-Regular.ttf</file>
+            <file variant="compact">NotoSansDevanagariUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansTamil-Regular.ttf</file>
+            <file variant="elegant">NotoSansTamil-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansTamilUI-Regular.ttf</file>
+            <file variant="compact">NotoSansTamilUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansMalayalam-Regular.ttf</file>
+            <file variant="elegant">NotoSansMalayalam-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansMalayalamUI-Regular.ttf</file>
+            <file variant="compact">NotoSansMalayalamUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansBengali-Regular.ttf</file>
+            <file variant="elegant">NotoSansBengali-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansBengaliUI-Regular.ttf</file>
+            <file variant="compact">NotoSansBengaliUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansTelugu-Regular.ttf</file>
+            <file variant="elegant">NotoSansTelugu-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansTeluguUI-Regular.ttf</file>
+            <file variant="compact">NotoSansTeluguUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansKannada-Regular.ttf</file>
+            <file variant="elegant">NotoSansKannada-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansKannadaUI-Regular.ttf</file>
+            <file variant="compact">NotoSansKannadaUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansKhmer-Regular.ttf</file>
+            <file variant="elegant">NotoSansKhmer-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansKhmerUI-Regular.ttf</file>
+            <file variant="compact">NotoSansKhmerUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansLao-Regular.ttf</file>
+            <file variant="elegant">NotoSansLao-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansLaoUI-Regular.ttf</file>
+            <file variant="compact">NotoSansLaoUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>NanumGothic.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>Padauk-book.ttf</file>
+            <file>Padauk-bookbold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>NotoSansSymbols-Regular.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>AndroidEmoji.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>NotoColorEmoji.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansFallback.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file lang="ja">MTLmr3m.ttf</file>
+        </fileset>
+    </family>
+    <!-- Note: complex scripts (i.e. those requiring shaping in Harfbuzz) have
+         a cumulative limit of 64k glyphs. Thus, if they are placed after the
+         large fonts such as DroidSansFallback, they are likely to render
+         incorrectly. Please use caution when putting fonts toward the end of
+         the list.
+    -->
+</familyset>
diff --git a/resources/android_fonts/v17/system_fonts.xml b/resources/android_fonts/v17/system_fonts.xml
new file mode 100644
index 0000000..549f061
--- /dev/null
+++ b/resources/android_fonts/v17/system_fonts.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    System Fonts
+
+    This file lists the font families that will be used by default for all supported glyphs.
+    Each entry consists of a family, various names that are supported by that family, and
+    up to four font files. The font files are listed in the order of the styles which they
+    support: regular, bold, italic and bold-italic. If less than four styles are listed, then
+    the styles with no associated font file will be supported by the other font files listed.
+
+    The first family is also the default font, which handles font request that have not specified
+    specific font names.
+
+    Any glyph that is not handled by the system fonts will cause a search of the fallback fonts.
+    The default fallback fonts are specified in the file /system/etc/fallback_fonts.xml, and there
+    is an optional file which may be supplied by vendors to specify other fallback fonts to use
+    in /vendor/etc/fallback_fonts.xml.
+-->
+<familyset>
+
+    <family>
+        <nameset>
+            <name>sans-serif</name>
+            <name>arial</name>
+            <name>helvetica</name>
+            <name>tahoma</name>
+            <name>verdana</name>
+        </nameset>
+        <fileset>
+            <file>Roboto-Regular.ttf</file>
+            <file>Roboto-Bold.ttf</file>
+            <file>Roboto-Italic.ttf</file>
+            <file>Roboto-BoldItalic.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>sans-serif-light</name>
+        </nameset>
+        <fileset>
+            <file>Roboto-Light.ttf</file>
+            <file>Roboto-LightItalic.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>sans-serif-thin</name>
+        </nameset>
+        <fileset>
+            <file>Roboto-Thin.ttf</file>
+            <file>Roboto-ThinItalic.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>sans-serif-condensed</name>
+        </nameset>
+        <fileset>
+            <file>RobotoCondensed-Regular.ttf</file>
+            <file>RobotoCondensed-Bold.ttf</file>
+            <file>RobotoCondensed-Italic.ttf</file>
+            <file>RobotoCondensed-BoldItalic.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <nameset>
+            <name>serif</name>
+            <name>times</name>
+            <name>times new roman</name>
+            <name>palatino</name>
+            <name>georgia</name>
+            <name>baskerville</name>
+            <name>goudy</name>
+            <name>fantasy</name>
+            <name>ITC Stone Serif</name>
+        </nameset>
+        <fileset>
+            <file>DroidSerif-Regular.ttf</file>
+            <file>DroidSerif-Bold.ttf</file>
+            <file>DroidSerif-Italic.ttf</file>
+            <file>DroidSerif-BoldItalic.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>Droid Sans</name>
+        </nameset>
+        <fileset>
+            <file>DroidSans.ttf</file>
+            <file>DroidSans-Bold.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>monospace</name>
+            <name>courier</name>
+            <name>courier new</name>
+            <name>monaco</name>
+        </nameset>
+        <fileset>
+            <file>DroidSansMono.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>casual</name>
+        </nameset>
+        <fileset>
+            <file>ComingSoon.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>cursive</name>
+        </nameset>
+        <fileset>
+            <file>DancingScript-Regular.ttf</file>
+            <file>DancingScript-Bold.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>sans-serif-smallcaps</name>
+        </nameset>
+        <fileset>
+            <file>CarroisGothicSC-Regular.ttf</file>
+        </fileset>
+    </family>
+
+</familyset>
diff --git a/resources/android_fonts/v22/fonts.xml b/resources/android_fonts/v22/fonts.xml
new file mode 100644
index 0000000..180d5f7
--- /dev/null
+++ b/resources/android_fonts/v22/fonts.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="utf-8"?>
+<familyset version="21">
+    <!-- first font is default -->
+    <family name="sans-serif">
+        <font weight="100" style="normal">Roboto-Thin.ttf</font>
+        <font weight="100" style="italic">Roboto-ThinItalic.ttf</font>
+        <font weight="300" style="normal">Roboto-Light.ttf</font>
+        <font weight="300" style="italic">Roboto-LightItalic.ttf</font>
+        <font weight="400" style="normal">Roboto-Regular.ttf</font>
+        <font weight="400" style="italic">Roboto-Italic.ttf</font>
+        <font weight="500" style="normal">Roboto-Medium.ttf</font>
+        <font weight="500" style="italic">Roboto-MediumItalic.ttf</font>
+        <font weight="700" style="normal">Roboto-Bold.ttf</font>
+        <font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
+        <font weight="900" style="normal">Roboto-Black.ttf</font>
+        <font weight="900" style="italic">Roboto-BlackItalic.ttf</font>
+    </family>
+    <alias name="sans-serif-thin" to="sans-serif" weight="100" />
+    <alias name="sans-serif-light" to="sans-serif" weight="300" />
+    <alias name="sans-serif-black" to="sans-serif" weight="900" />
+    <alias name="arial" to="sans-serif" />
+    <alias name="helvetica" to="sans-serif" />
+    <alias name="tahoma" to="sans-serif" />
+    <alias name="verdana" to="sans-serif" />
+
+    <family name="sans-serif-condensed">
+        <font weight="300" style="normal">RobotoCondensed-Light.ttf</font>
+        <font weight="300" style="italic">RobotoCondensed-LightItalic.ttf</font>
+        <font weight="400" style="normal">RobotoCondensed-Regular.ttf</font>
+        <font weight="400" style="italic">RobotoCondensed-Italic.ttf</font>
+        <font weight="700" style="normal">RobotoCondensed-Bold.ttf</font>
+        <font weight="700" style="italic">RobotoCondensed-BoldItalic.ttf</font>
+    </family>
+    <alias name="sans-serif-condensed-light" to="sans-serif-condensed" weight="300" />
+
+    <!--- rest of fonts from system_fonts.xml go here -->
+    <family name="serif">
+        <font weight="400" style="normal">NotoSerif-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSerif-Bold.ttf</font>
+        <font weight="400" style="italic">NotoSerif-Italic.ttf</font>
+        <font weight="700" style="italic">NotoSerif-BoldItalic.ttf</font>
+    </family>
+    <alias name="times" to="serif" />
+    <alias name="times new roman" to="serif" />
+    <alias name="palatino" to="serif" />
+    <alias name="georgia" to="serif" />
+    <alias name="baskerville" to="serif" />
+    <alias name="goudy" to="serif" />
+    <alias name="fantasy" to="serif" />
+    <alias name="ITC Stone Serif" to="serif" />
+
+    <family name="monospace">
+        <font weight="400" style="normal">DroidSansMono.ttf</font>
+    </family>
+    <alias name="courier" to="monospace" />
+    <alias name="courier new" to="monospace" />
+    <alias name="monaco" to="monospace" />
+
+    <family name="casual">
+        <font weight="400" style="normal">ComingSoon.ttf</font>
+    </family>
+
+    <family name="cursive">
+        <font weight="400" style="normal">DancingScript-Regular.ttf</font>
+        <font weight="700" style="normal">DancingScript-Bold.ttf</font>
+    </family>
+
+    <family name="ans-serif-smallcaps">
+        <font weight="400" style="normal">CarroisGothicSC-Regular.ttf</font>
+    </family>
+
+    <!-- fallback fonts -->
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoNaskh-Regular.ttf</font>
+        <font weight="700" style="normal">NotoNaskh-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoNaskhUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoNaskhUI-Bold.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoSansEthiopic-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansEthiopic-Bold.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoSansHebrew-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansHebrew-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansThai-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansThai-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansThaiUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansThaiUI-Bold.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoSansArmenian-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansArmenian-Bold.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoSansGeorgian-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansGeorgian-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansDevanagari-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansDevanagari-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansDevanagariUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansDevanagariUI-Bold.ttf</font>
+    </family>
+    <!-- Gujarati should come after Devanagari -->
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansGujarati-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansGujarati-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansGujaratiUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansGujaratiUI-Bold.ttf</font>
+    </family>
+    <!-- Gurmukhi should come after Devanagari -->
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansGurmukhi-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansGurmukhi-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansGurmukhiUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansGurmukhiUI-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansTamil-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansTamil-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansTamilUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansTamilUI-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansMalayalam-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansMalayalam-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansMalayalamUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansMalayalamUI-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansBengali-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansBengali-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansBengaliUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansBengaliUI-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansTelugu-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansTelugu-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansTeluguUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansTeluguUI-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansKannada-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansKannada-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansKannadaUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansKannadaUI-Bold.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoSansSinhala-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansSinhala-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansKhmer-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansKhmer-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansKhmerUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansKhmerUI-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansLao-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansLao-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansLaoUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansLaoUI-Bold.ttf</font>
+    </family>
+    <family variant="elegant">
+        <font weight="400" style="normal">NotoSansMyanmar-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansMyanmar-Bold.ttf</font>
+    </family>
+    <family variant="compact">
+        <font weight="400" style="normal">NotoSansMyanmarUI-Regular.ttf</font>
+        <font weight="700" style="normal">NotoSansMyanmarUI-Bold.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoSansCherokee-Regular.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoSansCanadianAboriginal-Regular.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoSansYi-Regular.ttf</font>
+    </family>
+    <family lang="zh-Hans">
+        <font weight="400" style="normal">NotoSansHans-Regular.otf</font>
+    </family>
+    <family lang="zh-Hant">
+        <font weight="400" style="normal">NotoSansHant-Regular.otf</font>
+    </family>
+    <family lang="ja">
+        <font weight="400" style="normal">NotoSansJP-Regular.otf</font>
+    </family>
+    <family lang="ko">
+        <font weight="400" style="normal">NotoSansKR-Regular.otf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NanumGothic.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted.ttf</font>
+    </family>
+    <family>
+        <font weight="400" style="normal">NotoColorEmoji.ttf</font>
+    </family>
+    <family lang="ja">
+        <font weight="400" style="normal">MTLmr3m.ttf</font>
+    </family>
+</familyset>
diff --git a/resources/mandrill_128.r11.ktx b/resources/mandrill_128.r11.ktx
new file mode 100644
index 0000000..932ac4c
--- /dev/null
+++ b/resources/mandrill_128.r11.ktx
Binary files differ
diff --git a/resources/mandrill_128x128_4x4.astc b/resources/mandrill_128x128_4x4.astc
new file mode 100644
index 0000000..0b22300
--- /dev/null
+++ b/resources/mandrill_128x128_4x4.astc
Binary files differ
diff --git a/resources/mandrill_128x128_8x8.astc b/resources/mandrill_128x128_8x8.astc
new file mode 100644
index 0000000..4c4019e
--- /dev/null
+++ b/resources/mandrill_128x128_8x8.astc
Binary files differ
diff --git a/resources/mandrill_128x130_8x5.astc b/resources/mandrill_128x130_8x5.astc
new file mode 100644
index 0000000..d835665
--- /dev/null
+++ b/resources/mandrill_128x130_8x5.astc
Binary files differ
diff --git a/resources/mandrill_128x132_8x6.astc b/resources/mandrill_128x132_8x6.astc
new file mode 100644
index 0000000..618cb65
--- /dev/null
+++ b/resources/mandrill_128x132_8x6.astc
Binary files differ
diff --git a/resources/mandrill_130x128_10x8.astc b/resources/mandrill_130x128_10x8.astc
new file mode 100644
index 0000000..98597f2
--- /dev/null
+++ b/resources/mandrill_130x128_10x8.astc
Binary files differ
diff --git a/resources/mandrill_130x128_5x4.astc b/resources/mandrill_130x128_5x4.astc
new file mode 100644
index 0000000..cd150a9
--- /dev/null
+++ b/resources/mandrill_130x128_5x4.astc
Binary files differ
diff --git a/resources/mandrill_130x130_10x10.astc b/resources/mandrill_130x130_10x10.astc
new file mode 100644
index 0000000..dcda936
--- /dev/null
+++ b/resources/mandrill_130x130_10x10.astc
Binary files differ
diff --git a/resources/mandrill_130x130_10x5.astc b/resources/mandrill_130x130_10x5.astc
new file mode 100644
index 0000000..f067ee6
--- /dev/null
+++ b/resources/mandrill_130x130_10x5.astc
Binary files differ
diff --git a/resources/mandrill_130x130_5x5.astc b/resources/mandrill_130x130_5x5.astc
new file mode 100644
index 0000000..df82775
--- /dev/null
+++ b/resources/mandrill_130x130_5x5.astc
Binary files differ
diff --git a/resources/mandrill_130x132_10x6.astc b/resources/mandrill_130x132_10x6.astc
new file mode 100644
index 0000000..b8c4ec9
--- /dev/null
+++ b/resources/mandrill_130x132_10x6.astc
Binary files differ
diff --git a/resources/mandrill_132x130_12x10.astc b/resources/mandrill_132x130_12x10.astc
new file mode 100644
index 0000000..db4c989
--- /dev/null
+++ b/resources/mandrill_132x130_12x10.astc
Binary files differ
diff --git a/resources/mandrill_132x130_6x5.astc b/resources/mandrill_132x130_6x5.astc
new file mode 100644
index 0000000..a9f81e2
--- /dev/null
+++ b/resources/mandrill_132x130_6x5.astc
Binary files differ
diff --git a/resources/mandrill_132x132_12x12.astc b/resources/mandrill_132x132_12x12.astc
new file mode 100644
index 0000000..6b6346c
--- /dev/null
+++ b/resources/mandrill_132x132_12x12.astc
Binary files differ
diff --git a/resources/mandrill_132x132_6x6.astc b/resources/mandrill_132x132_6x6.astc
new file mode 100644
index 0000000..34f1c19
--- /dev/null
+++ b/resources/mandrill_132x132_6x6.astc
Binary files differ
diff --git a/resources/mandrill_512_q075.jpg b/resources/mandrill_512_q075.jpg
new file mode 100644
index 0000000..c2c215f
--- /dev/null
+++ b/resources/mandrill_512_q075.jpg
Binary files differ
diff --git a/samplecode/ClockFaceView.cpp b/samplecode/ClockFaceView.cpp
index a887cc6..46d4120 100644
--- a/samplecode/ClockFaceView.cpp
+++ b/samplecode/ClockFaceView.cpp
@@ -90,13 +90,15 @@
         dst->addCircle(loc.fX, loc.fY, fRadius);
     }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     Dot2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
         fRadius = buffer.readScalar();
         fPts = NULL;
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        this->INHERITED::flatten(buffer);
+        buffer.writeMatrix(this->getMatrix());
         buffer.writeScalar(fRadius);
     }
 
@@ -107,6 +109,12 @@
     typedef Sk2DPathEffect INHERITED;
 };
 
+SkFlattenable* Dot2DPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    return SkNEW_ARGS(Dot2DPathEffect, (buffer.readScalar(), matrix, NULL));
+}
+
 class InverseFillPE : public SkPathEffect {
 public:
     InverseFillPE() {}
@@ -119,12 +127,19 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(InverseFillPE)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     InverseFillPE(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
 private:
 
     typedef SkPathEffect INHERITED;
 };
 
+SkFlattenable* InverseFillPE::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW(InverseFillPE);
+}
+
 static SkPathEffect* makepe(float interp, SkTDArray<SkPoint>* pts) {
     SkMatrix    lattice;
     SkScalar    rad = 3 + SkIntToScalar(4) * (1 - interp);
diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp
index 92fe258..19e692f 100644
--- a/samplecode/SampleAll.cpp
+++ b/samplecode/SampleAll.cpp
@@ -172,9 +172,11 @@
         dst->addCircle(loc.fX, loc.fY, fRadius);
     }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     Dot2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
         fRadius = buffer.readScalar();
     }
+#endif
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
         this->INHERITED::flatten(buffer);
         buffer.writeScalar(fRadius);
@@ -320,7 +322,7 @@
             do {
                 canvas->save();
                 canvas->clipRect(clip);
-                picture->draw(canvas);
+                picture->playback(canvas);
                 canvas->restore();
                 if (clip.fRight < SkIntToScalar(320))
                     clip.offset(SkIntToScalar(160), 0);
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 2a4ebdc..6ca67bc 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -8,6 +8,7 @@
 #include "SampleApp.h"
 
 #include "OverView.h"
+#include "Resources.h"
 #include "SampleCode.h"
 #include "SamplePipeControllers.h"
 #include "SkCanvas.h"
@@ -270,17 +271,14 @@
         fBackend = kNone_BackEndType;
     }
 
-    virtual SkCanvas* createCanvas(SampleWindow::DeviceType dType,
-                                   SampleWindow* win) {
+    virtual SkSurface* createSurface(SampleWindow::DeviceType dType,
+                                     SampleWindow* win) SK_OVERRIDE {
 #if SK_SUPPORT_GPU
-        if (IsGpuDeviceType(dType) && NULL != fCurContext) {
-            SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(fCurContext, fCurRenderTarget));
-            return new SkCanvas(device);
-        } else
-#endif
-        {
-            return NULL;
+        if (IsGpuDeviceType(dType) && fCurContext) {
+            return SkSurface::NewRenderTargetDirect(fCurRenderTarget);
         }
+#endif
+        return NULL;
     }
 
     virtual void publishCanvas(SampleWindow::DeviceType dType,
@@ -754,7 +752,7 @@
         SkString filename;
         while (iter.next(&filename)) {
             *fSamples.append() = new PictFileFactory(
-                    SkOSPath::SkPathJoin(FLAGS_pictureDir[0], filename.c_str()));
+                SkOSPath::Join(FLAGS_pictureDir[0], filename.c_str()));
         }
     }
     if (!FLAGS_picture.isEmpty()) {
@@ -768,7 +766,7 @@
         SkString filename;
         while (iter.next(&filename)) {
             *fSamples.append() = new PdfFileViewerFactory(
-                    SkOSPath::SkPathJoin(FLAGS_pictureDir[0], filename.c_str()));
+                SkOSPath::Join(FLAGS_pictureDir[0], filename.c_str()));
         }
     }
 #endif
@@ -973,8 +971,7 @@
 
 SampleWindow::~SampleWindow() {
     delete fPdfCanvas;
-    fTypeface->unref();
-
+    SkSafeUnref(fTypeface);
     SkSafeUnref(fDevManager);
 }
 
@@ -999,7 +996,7 @@
 
 static SkBitmap capture_bitmap(SkCanvas* canvas) {
     SkBitmap bm;
-    if (bm.allocPixels(canvas->imageInfo())) {
+    if (bm.tryAllocPixels(canvas->imageInfo())) {
         canvas->readPixels(&bm, 0, 0);
     }
     return bm;
@@ -1007,7 +1004,7 @@
 
 static bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
                         SkBitmap* diff) {
-    const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
+    SkBitmap src = capture_bitmap(canvas);
 
     SkAutoLockPixels alp0(src);
     SkAutoLockPixels alp1(orig);
@@ -1282,7 +1279,7 @@
 
 SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
     if (fSaveToPdf) {
-        const SkBitmap& bmp = canvas->getDevice()->accessBitmap(false);
+        const SkBitmap bmp = capture_bitmap(canvas);
         SkISize size = SkISize::Make(bmp.width(), bmp.height());
         SkPDFDevice* pdfDevice = new SkPDFDevice(size, size,
                 canvas->getTotalMatrix());
@@ -1308,15 +1305,6 @@
     return canvas;
 }
 
-static void paint_rgn(const SkBitmap& bm, const SkIRect& r,
-                      const SkRegion& rgn) {
-    SkCanvas    canvas(bm);
-    SkRegion    inval(rgn);
-
-    inval.translate(r.fLeft, r.fTop);
-    canvas.clipRegion(inval);
-    canvas.drawColor(0xFFFF8080);
-}
 #include "SkData.h"
 void SampleWindow::afterChildren(SkCanvas* orig) {
     if (fSaveToPdf) {
@@ -1327,7 +1315,8 @@
         SkString name;
         name.printf("%s.pdf", this->getTitle());
         SkPDFDocument doc;
-        SkPDFDevice* device = static_cast<SkPDFDevice*>(fPdfCanvas->getDevice());
+        SkPDFDevice* device = NULL;//static_cast<SkPDFDevice*>(fPdfCanvas->getDevice());
+        SkASSERT(false);
         doc.appendPage(device);
 #ifdef SK_BUILD_FOR_ANDROID
         name.prepend("/sdcard/");
@@ -1357,9 +1346,8 @@
     if (fRequestGrabImage) {
         fRequestGrabImage = false;
 
-        SkBaseDevice* device = orig->getDevice();
-        SkBitmap bmp;
-        if (device->accessBitmap(false).copyTo(&bmp, kN32_SkColorType)) {
+        SkBitmap bmp = capture_bitmap(orig);
+        if (!bmp.isNull()) {
             static int gSampleGrabCounter;
             SkString name;
             name.printf("sample_grab_%d.png", gSampleGrabCounter++);
@@ -1369,13 +1357,11 @@
     }
 
     if (kPicture_DeviceType == fDeviceType) {
-        SkAutoTUnref<SkPicture> picture(fRecorder.endRecording());
+        SkAutoTUnref<const SkPicture> picture(fRecorder.endRecording());
 
         if (true) {
-            SkPicture* pict = new SkPicture(*picture);
             this->installDrawFilter(orig);
-            orig->drawPicture(pict);
-            pict->unref();
+            orig->drawPicture(picture);
         } else if (true) {
             SkDynamicMemoryWStream ostream;
             picture->serialize(&ostream);
@@ -1387,7 +1373,7 @@
                 orig->drawPicture(pict.get());
             }
         } else {
-            picture->draw(orig);
+            picture->playback(orig);
         }
     }
 
@@ -1395,19 +1381,6 @@
     if (fMeasureFPS && fMeasureFPS_StartTime) {
         fMeasureFPS_Time += SkTime::GetMSecs() - fMeasureFPS_StartTime;
     }
-
-    //    if ((fScrollTestX | fScrollTestY) != 0)
-    if (false) {
-        const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
-        int dx = fScrollTestX * 7;
-        int dy = fScrollTestY * 7;
-        SkIRect r;
-        SkRegion inval;
-
-        r.set(50, 50, 50+100, 50+100);
-        bm.scrollRect(&r, dx, dy, &inval);
-        paint_rgn(bm, r, inval);
-    }
 }
 
 void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
@@ -1434,7 +1407,13 @@
         t = SkScalarMul(SkScalarDiv(t, gAnimPeriod), gAnimMag);
         SkMatrix m;
         m.reset();
+#if 1
         m.setPerspY(t);
+#else
+        m.setPerspY(SK_Scalar1 / 1000);
+        m.setSkewX(SkScalarDiv(8, 25));
+        m.dump();
+#endif
         canvas->concat(m);
     }
 
@@ -1685,6 +1664,8 @@
 }
 #endif
 
+DECLARE_bool(portableFonts);
+
 bool SampleWindow::onHandleChar(SkUnichar uni) {
     {
         SkView* view = curr_view(this);
@@ -1738,6 +1719,10 @@
             // only
             toggleFPS();
             break;
+        case 'F':
+            FLAGS_portableFonts ^= true;
+            this->inval(NULL);
+            break;
         case 'g':
             fRequestGrabImage = true;
             this->inval(NULL);
@@ -2071,7 +2056,7 @@
 
 #if SK_SUPPORT_GPU
     if (IsGpuDeviceType(fDeviceType) &&
-        NULL != fDevManager &&
+        fDevManager &&
         fDevManager->getGrRenderTarget() &&
         fDevManager->getGrRenderTarget()->numSamples() > 0) {
         title.appendf(" [MSAA: %d]",
@@ -2249,9 +2234,8 @@
     } else {
         SkGPipeWriter writer;
         SimplePC controller(canvas);
-        TiledPipeController tc(canvas->getDevice()->accessBitmap(false),
-                               &SkImageDecoder::DecodeMemory,
-                               &canvas->getTotalMatrix());
+        SkBitmap bitmap = capture_bitmap(canvas);
+        TiledPipeController tc(bitmap, &SkImageDecoder::DecodeMemory, &canvas->getTotalMatrix());
         SkGPipeController* pc;
         if (SkOSMenu::kMixedState == fPipeState) {
             pc = &tc;
@@ -2403,12 +2387,12 @@
 }
 
 #ifdef SK_BUILD_FOR_IOS
-void save_args(int argc, char *argv[]) {
+IOS_launch_type set_cmd_line_args(int , char *[], const char* resourceDir) {
+    SetResourcePath(resourceDir);
+    return kApplication__iOSLaunchType;
 }
 #endif
 
-// FIXME: this should be in a header
-void application_init();
 void application_init() {
 //    setenv("ANDROID_ROOT", "../../../data", 0);
 #ifdef SK_BUILD_FOR_MAC
@@ -2418,8 +2402,6 @@
     SkEvent::Init();
 }
 
-// FIXME: this should be in a header
-void application_term();
 void application_term() {
     SkEvent::Term();
     SkGraphics::Term();
diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h
index e08ff8a..abb1f24 100644
--- a/samplecode/SampleApp.h
+++ b/samplecode/SampleApp.h
@@ -76,7 +76,7 @@
 
         // called before drawing. should install correct device
         // type on the canvas. Will skip drawing if returns false.
-        virtual SkCanvas* createCanvas(DeviceType dType, SampleWindow* win) = 0;
+        virtual SkSurface* createSurface(DeviceType dType, SampleWindow* win) = 0;
 
         // called after drawing, should get the results onto the
         // screen.
@@ -100,18 +100,18 @@
     SampleWindow(void* hwnd, int argc, char** argv, DeviceManager*);
     virtual ~SampleWindow();
 
-    virtual SkCanvas* createCanvas() SK_OVERRIDE {
-        SkCanvas* canvas = NULL;
+    virtual SkSurface* createSurface() SK_OVERRIDE {
+        SkSurface* surface = NULL;
         if (fDevManager) {
-            canvas = fDevManager->createCanvas(fDeviceType, this);
+            surface = fDevManager->createSurface(fDeviceType, this);
         }
-        if (NULL == canvas) {
-            canvas = this->INHERITED::createCanvas();
+        if (NULL == surface) {
+            surface = this->INHERITED::createSurface();
         }
-        return canvas;
+        return surface;
     }
 
-    virtual void draw(SkCanvas* canvas);
+    virtual void draw(SkCanvas*) SK_OVERRIDE;
 
     void setDeviceType(DeviceType type);
     void toggleRendering();
diff --git a/samplecode/SampleBitmapRect.cpp b/samplecode/SampleBitmapRect.cpp
index cf1196c..006b919 100644
--- a/samplecode/SampleBitmapRect.cpp
+++ b/samplecode/SampleBitmapRect.cpp
@@ -24,12 +24,6 @@
 #include "SkOSFile.h"
 #include "SkStream.h"
 
-#if SK_SUPPORT_GPU
-#include "SkGpuDevice.h"
-#else
-class GrContext;
-#endif
-
 #define INT_SIZE        64
 #define SCALAR_SIZE     SkIntToScalar(INT_SIZE)
 
diff --git a/samplecode/SampleChart.cpp b/samplecode/SampleChart.cpp
index 630ff6e..12a6afe 100644
--- a/samplecode/SampleChart.cpp
+++ b/samplecode/SampleChart.cpp
@@ -60,7 +60,7 @@
         x += xDelta;
     }
 
-    if (NULL != bottomData) {
+    if (bottomData) {
         SkASSERT(bottomData->count() == topData.count());
         // iterate backwards over the previous graph's data to generate the bottom of the filled
         // area (and account for leftShift).
diff --git a/samplecode/SampleFatBits.cpp b/samplecode/SampleFatBits.cpp
index 6057c68..c300733 100644
--- a/samplecode/SampleFatBits.cpp
+++ b/samplecode/SampleFatBits.cpp
@@ -102,8 +102,7 @@
 
         SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
         fMinSurface.reset(SkSurface::NewRaster(info));
-        info.fWidth *= zoom;
-        info.fHeight *= zoom;
+        info = info.makeWH(width * zoom, height * zoom);
         fMaxSurface.reset(SkSurface::NewRaster(info));
     }
 
diff --git a/samplecode/SampleFilterFuzz.cpp b/samplecode/SampleFilterFuzz.cpp
index 7f4c247..a996a4b 100644
--- a/samplecode/SampleFilterFuzz.cpp
+++ b/samplecode/SampleFilterFuzz.cpp
@@ -6,8 +6,6 @@
  */
 #include "SampleCode.h"
 #include "SkAlphaThresholdFilter.h"
-#include "SkBicubicImageFilter.h"
-#include "SkBitmapDevice.h"
 #include "SkBitmapSource.h"
 #include "SkBlurImageFilter.h"
 #include "SkCanvas.h"
@@ -155,7 +153,7 @@
     do {
         info = SkImageInfo::Make(kBitmapSize, kBitmapSize, rand_colortype(),
                                  kPremul_SkAlphaType);
-    } while (!valid_for_raster_canvas(info) || !bitmap->allocPixels(info));
+    } while (!valid_for_raster_canvas(info) || !bitmap->tryAllocPixels(info));
 }
 
 static void make_g_bitmap(SkBitmap& bitmap) {
@@ -235,7 +233,7 @@
     // Add a 1 in 3 chance to get a NULL input
     if (canBeNull && (R(3) == 1)) { return filter; }
 
-    enum { ALPHA_THRESHOLD, BICUBIC, MERGE, COLOR, BLUR, MAGNIFIER,
+    enum { ALPHA_THRESHOLD, MERGE, COLOR, BLUR, MAGNIFIER,
            DOWN_SAMPLE, XFERMODE, OFFSET, MATRIX, MATRIX_CONVOLUTION, COMPOSE,
            DISTANT_LIGHT, POINT_LIGHT, SPOT_LIGHT, NOISE, DROP_SHADOW,
            MORPHOLOGY, BITMAP, DISPLACE, TILE, PICTURE, NUM_FILTERS };
@@ -244,10 +242,6 @@
     case ALPHA_THRESHOLD:
         filter = SkAlphaThresholdFilter::Create(make_region(), make_scalar(), make_scalar());
         break;
-    case BICUBIC:
-        // Scale is set to 1 here so that it can fit in the DAG without resizing the output
-        filter = SkBicubicImageFilter::CreateMitchell(SkSize::Make(1, 1), make_image_filter());
-        break;
     case MERGE:
         filter = SkMergeImageFilter::Create(make_image_filter(), make_image_filter(), make_xfermode());
         break;
@@ -347,7 +341,7 @@
         break;
     case DROP_SHADOW:
         filter = SkDropShadowImageFilter::Create(make_scalar(), make_scalar(),
-                     make_scalar(true), make_color(), make_image_filter());
+                     make_scalar(true), make_scalar(true), make_color(), make_image_filter());
         break;
     case MORPHOLOGY:
         if (R(2) == 1) {
@@ -377,7 +371,9 @@
     {
         SkRTreeFactory factory;
         SkPictureRecorder recorder;
-        SkCanvas* recordingCanvas = recorder.beginRecording(kBitmapSize, kBitmapSize, &factory, 0);
+        SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(kBitmapSize), 
+                                                            SkIntToScalar(kBitmapSize), 
+                                                            &factory, 0);
         drawSomething(recordingCanvas);
         SkAutoTUnref<SkPicture> pict(recorder.endRecording());
         filter = SkPictureImageFilter::Create(pict.get(), make_rect());
@@ -439,7 +435,7 @@
         printf("Fuzzing with %u\n", kSeed);
     }
     numFilters++;
-    if (NULL != filter) {
+    if (filter) {
         numValidFilters++;
     }
     printf("Filter no : %u. Valid filters so far : %u\r", numFilters, numValidFilters);
diff --git a/samplecode/SampleIdentityScale.cpp b/samplecode/SampleIdentityScale.cpp
new file mode 100644
index 0000000..a6b5c5c
--- /dev/null
+++ b/samplecode/SampleIdentityScale.cpp
@@ -0,0 +1,92 @@
+/*
+ * 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 "gm.h"
+
+#include "Resources.h"
+#include "SampleCode.h"
+#include "SkBlurMaskFilter.h"
+#include "SkCanvas.h"
+#include "SkColorPriv.h"
+#include "SkImageDecoder.h"
+#include "SkRandom.h"
+#include "SkStream.h"
+#include "SkTime.h"
+
+// Intended to exercise pixel snapping observed with scaled images (and
+// with non-scaled images, but for a different reason):  Bug 1145
+
+class IdentityScaleView : public SampleView {
+public:
+    IdentityScaleView(const char imageFilename[]) {
+      SkString resourcePath = GetResourcePath(imageFilename);
+      SkImageDecoder* codec = NULL;
+      SkFILEStream stream(resourcePath.c_str());
+      if (stream.isValid()) {
+          codec = SkImageDecoder::Factory(&stream);
+      }
+      if (codec) {
+          stream.rewind();
+          codec->decode(&stream, &fBM, kN32_SkColorType, SkImageDecoder::kDecodePixels_Mode);
+          SkDELETE(codec);
+      } else {
+          fBM.allocN32Pixels(1, 1);
+          *(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad
+      }
+    }
+
+protected:
+    SkBitmap fBM;
+
+    // overrides from SkEventSink
+    virtual bool onQuery(SkEvent* evt) SK_OVERRIDE {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "IdentityScale");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+
+    virtual void onDrawContent(SkCanvas* canvas) SK_OVERRIDE {
+
+        SkPaint paint;
+
+        paint.setAntiAlias(true);
+        paint.setTextSize(48);
+        paint.setFilterLevel(SkPaint::kHigh_FilterLevel);
+
+        SkTime::DateTime time;
+        SkTime::GetDateTime(&time);
+
+        bool use_scale = (time.fSecond % 2 == 1);
+        const char *text;
+
+        canvas->save();
+        if (use_scale) {
+          text = "Scaled = 1";
+        } else {
+
+          SkRect r = { 100, 100, 356, 356 };
+          SkPath clipPath;
+          clipPath.addRoundRect(r, SkIntToScalar(5), SkIntToScalar(5));
+          canvas->clipPath(clipPath, SkRegion::kIntersect_Op, SkToBool(1));
+          text = "Scaled = 0";
+        }
+        canvas->drawBitmap( fBM, 100, 100, &paint );
+        canvas->restore();
+        canvas->drawText( text, strlen(text), 100, 400, paint );
+        this->inval(NULL);
+    }
+
+private:
+    typedef SampleView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new IdentityScaleView("mandrill_256.png"); }
+static SkViewRegister reg(MyFactory);
diff --git a/samplecode/SampleMeasure.cpp b/samplecode/SampleMeasure.cpp
index 257f7d9..86f9b52 100644
--- a/samplecode/SampleMeasure.cpp
+++ b/samplecode/SampleMeasure.cpp
@@ -23,22 +23,15 @@
 
 // exercise scale/linear/devkern
 struct Setting {
-    SkScalar    fScale;
     bool        fLinearText;
     bool        fDevKernText;
 };
 
-static const SkScalar ONE = SkIntToScalar(9999)/10000;
-
 static const Setting gSettings[] = {
-    { 0,            false,  false   },
-    { 0,            false,  true    },
-    { 0,            true,   false   },
-    { 0,            true,   true    },
-    { ONE,   false,  false   },
-    { ONE,   false,  true    },
-    { ONE,   true,   false   },
-    { ONE,   true,   true    }
+    { false,  false   },
+    { false,  true    },
+    { true,   false   },
+    { true,   true    },
 };
 
 static void doMeasure(SkCanvas* canvas, const SkPaint& paint, const char text[]) {
@@ -55,10 +48,9 @@
     for (size_t i = 0; i < SK_ARRAY_COUNT(gSettings); i++) {
         p.setLinearText(gSettings[i].fLinearText);
         p.setDevKernText(gSettings[i].fDevKernText);
-        SkScalar scale = gSettings[i].fScale;
 
         int n = p.getTextWidths(text, len, widths, rects);
-        SkScalar w = p.measureText(text, len, &bounds, scale);
+        SkScalar w = p.measureText(text, len, &bounds);
 
         p.setStyle(SkPaint::kFill_Style);
         p.setColor(0x8888FF88);
diff --git a/samplecode/SamplePatch.cpp b/samplecode/SamplePatch.cpp
index fe94bbf..83849a0 100644
--- a/samplecode/SamplePatch.cpp
+++ b/samplecode/SamplePatch.cpp
@@ -206,18 +206,20 @@
 
 static void drawpatches(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
                         Patch* patch) {
-
     SkAutoCanvasRestore ar(canvas, true);
 
-    patch->draw(canvas, paint, 10, 10, false, false);
+    patch->draw(canvas, paint, nu, nv, false, false);
     canvas->translate(SkIntToScalar(180), 0);
-    patch->draw(canvas, paint, 10, 10, true, false);
+    patch->draw(canvas, paint, nu, nv, true, false);
     canvas->translate(SkIntToScalar(180), 0);
-    patch->draw(canvas, paint, 10, 10, false, true);
+    patch->draw(canvas, paint, nu, nv, false, true);
     canvas->translate(SkIntToScalar(180), 0);
-    patch->draw(canvas, paint, 10, 10, true, true);
+    patch->draw(canvas, paint, nu, nv, true, true);
 }
 
+const SkScalar DX = 20;
+const SkScalar DY = 0;
+
 class PatchView : public SampleView {
     SkShader*   fShader0;
     SkShader*   fShader1;
@@ -267,11 +269,14 @@
     }
 
     virtual void onDrawContent(SkCanvas* canvas) {
+        const int nu = 10;
+        const int nv = 10;
+
         SkPaint paint;
         paint.setDither(true);
         paint.setFilterLevel(SkPaint::kLow_FilterLevel);
 
-        canvas->translate(SkIntToScalar(20), 0);
+        canvas->translate(DX, DY);
 
         Patch   patch;
 
@@ -285,7 +290,7 @@
         patch.setBounds(fSize0.fX, fSize0.fY);
 
         patch.setPatch(fPts);
-        drawpatches(canvas, paint, 10, 10, &patch);
+        drawpatches(canvas, paint, nu, nv, &patch);
 
         paint.setShader(NULL);
         paint.setAntiAlias(true);
@@ -296,13 +301,13 @@
 
         paint.setAntiAlias(false);
         paint.setShader(fShader1);
-        {
+        if (true) {
             SkMatrix m;
             m.setSkew(1, 0);
             SkShader* s = SkShader::CreateLocalMatrixShader(paint.getShader(), m);
             paint.setShader(s)->unref();
         }
-        {
+        if (true) {
             static int gAngle;
             SkMatrix m;
             m.setRotate(SkIntToScalar(gAngle++));
@@ -310,7 +315,7 @@
             paint.setShader(s)->unref();
         }
         patch.setBounds(fSize1.fX, fSize1.fY);
-        drawpatches(canvas, paint, 10, 10, &patch);
+        drawpatches(canvas, paint, nu, nv, &patch);
 
         this->inval(NULL);
     }
@@ -327,6 +332,8 @@
 
     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                               unsigned modi) SK_OVERRIDE {
+        x -= DX;
+        y -= DY;
         for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
             if (hittest(fPts[i], x, y)) {
                 return new PtClick(this, (int)i);
@@ -336,7 +343,7 @@
     }
 
     virtual bool onClick(Click* click) {
-        fPts[((PtClick*)click)->fIndex].set(click->fCurr.fX, click->fCurr.fY);
+        fPts[((PtClick*)click)->fIndex].set(click->fCurr.fX - DX, click->fCurr.fY - DY);
         this->inval(NULL);
         return true;
     }
diff --git a/samplecode/SamplePictFile.cpp b/samplecode/SamplePictFile.cpp
index 9e9764c..df0c369 100644
--- a/samplecode/SamplePictFile.cpp
+++ b/samplecode/SamplePictFile.cpp
@@ -68,9 +68,6 @@
             case kRTree_BBoxType:
                 name.append(" <bbox: R>");
                 break;
-            case kQuadTree_BBoxType:
-                name.append(" <bbox: Q>");
-                break;
             case kTileGrid_BBoxType:
                 name.append(" <bbox: T>");
                 break;
@@ -107,7 +104,6 @@
 private:
     enum BBoxType {
         kNo_BBoxType,
-        kQuadTree_BBoxType,
         kRTree_BBoxType,
         kTileGrid_BBoxType,
 
@@ -127,7 +123,9 @@
         if (SkImageDecoder::DecodeFile(path, &bm)) {
             bm.setImmutable();
             SkPictureRecorder recorder;
-            SkCanvas* can = recorder.beginRecording(bm.width(), bm.height(), NULL, 0);
+            SkCanvas* can = recorder.beginRecording(SkIntToScalar(bm.width()), 
+                                                    SkIntToScalar(bm.height()), 
+                                                    NULL, 0);
             can->drawBitmap(bm, 0, 0, NULL);
             pic.reset(recorder.endRecording());
         } else {
@@ -139,13 +137,16 @@
             }
 
             if (false) {
-                SkSurface* surf = SkSurface::NewRasterPMColor(pic->width(), pic->height());
+                SkSurface* surf = SkSurface::NewRasterPMColor(SkScalarCeilToInt(pic->cullRect().width()), 
+                                                              SkScalarCeilToInt(pic->cullRect().height()));
                 surf->getCanvas()->drawPicture(pic);
                 surf->unref();
             }
             if (false) { // re-record
                 SkPictureRecorder recorder;
-                pic->draw(recorder.beginRecording(pic->width(), pic->height(), NULL, 0));
+                pic->playback(recorder.beginRecording(pic->cullRect().width(),
+                                                      pic->cullRect().height(), 
+                                                      NULL, 0));
                 SkAutoTUnref<SkPicture> p2(recorder.endRecording());
 
                 SkString path2(path);
@@ -167,9 +168,6 @@
         case kRTree_BBoxType:
             factory.reset(SkNEW(SkRTreeFactory));
             break;
-        case kQuadTree_BBoxType:
-            factory.reset(SkNEW(SkQuadTreeFactory));
-            break;
         case kTileGrid_BBoxType: {
             SkASSERT(!fTileSize.isEmpty());
             SkTileGridFactory::TileGridInfo gridInfo;
@@ -184,7 +182,9 @@
         }
 
         SkPictureRecorder recorder;
-        pic->draw(recorder.beginRecording(pic->width(), pic->height(), factory.get(), 0));
+        pic->playback(recorder.beginRecording(pic->cullRect().width(),
+                                              pic->cullRect().height(), 
+                                              factory.get(), 0));
         return recorder.endRecording();
     }
 
diff --git a/samplecode/SamplePicture.cpp b/samplecode/SamplePicture.cpp
index ecc5941..28256e5 100644
--- a/samplecode/SamplePicture.cpp
+++ b/samplecode/SamplePicture.cpp
@@ -37,9 +37,8 @@
 
 static SkBitmap load_bitmap() {
     SkBitmap bm;
-    SkString resourcePath = GetResourcePath();
-    SkString path = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_512.png");
-    SkAutoDataUnref data(SkData::NewFromFileName(path.c_str()));
+    SkString pngFilename = GetResourcePath("mandrill_512.png");
+    SkAutoDataUnref data(SkData::NewFromFileName(pngFilename.c_str()));
     if (data.get() != NULL) {
         SkInstallDiscardablePixelRef(SkDecodingImageGenerator::Create(
             data, SkDecodingImageGenerator::Options()), &bm);
diff --git a/samplecode/SampleSubpixelTranslate.cpp b/samplecode/SampleSubpixelTranslate.cpp
index 41a0f15..4652bc3 100644
--- a/samplecode/SampleSubpixelTranslate.cpp
+++ b/samplecode/SampleSubpixelTranslate.cpp
@@ -24,13 +24,9 @@
     SubpixelTranslateView(const char imageFilename[],
                           float horizontalVelocity,
                           float verticalVelocity)
-      : fFilename(imageFilename),
-        fHorizontalVelocity(horizontalVelocity),
+      : fHorizontalVelocity(horizontalVelocity),
         fVerticalVelocity(verticalVelocity) {
-      SkString resourcePath = GetResourcePath();
-      resourcePath.append("/");
-      resourcePath.append(fFilename);
-
+      SkString resourcePath = GetResourcePath(imageFilename);
       SkImageDecoder* codec = NULL;
       SkFILEStream stream(resourcePath.c_str());
       if (stream.isValid()) {
@@ -50,7 +46,6 @@
 
 protected:
     SkBitmap fBM;
-    SkString fFilename;
     SkScalar fSize;
     float fHorizontalVelocity, fVerticalVelocity;
 
diff --git a/samplecode/SampleText.cpp b/samplecode/SampleText.cpp
index c56ebc8..17456b2 100644
--- a/samplecode/SampleText.cpp
+++ b/samplecode/SampleText.cpp
@@ -63,74 +63,6 @@
     SkASSERT(mm == width);
 }
 
-static SkRandom gRand;
-
-class SkPowerMode : public SkXfermode {
-public:
-    SkPowerMode(SkScalar exponent) { this->init(exponent); }
-
-    virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
-                        const SkAlpha aa[]) const SK_OVERRIDE;
-
-    typedef SkFlattenable* (*Factory)(SkReadBuffer&);
-
-    SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPowerMode)
-
-private:
-    SkScalar fExp;          // user's value
-    uint8_t fTable[256];    // cache
-
-    void init(SkScalar exponent);
-    SkPowerMode(SkReadBuffer& b) : INHERITED(b) {
-        // read the exponent
-        this->init(SkFixedToScalar(b.readFixed()));
-    }
-    virtual void flatten(SkWriteBuffer& b) const SK_OVERRIDE {
-        this->INHERITED::flatten(b);
-        b.writeFixed(SkScalarToFixed(fExp));
-    }
-
-    typedef SkXfermode INHERITED;
-};
-
-void SkPowerMode::init(SkScalar e) {
-    fExp = e;
-    float ee = SkScalarToFloat(e);
-
-    printf("------ %g\n", ee);
-    for (int i = 0; i < 256; i++) {
-        float x = i / 255.f;
-     //   printf(" %d %g", i, x);
-        x = powf(x, ee);
-     //   printf(" %g", x);
-        int xx = SkScalarRoundToInt(x * 255);
-     //   printf(" %d\n", xx);
-        fTable[i] = SkToU8(xx);
-    }
-}
-
-void SkPowerMode::xfer16(uint16_t dst[], const SkPMColor src[], int count,
-                         const SkAlpha aa[]) const {
-    for (int i = 0; i < count; i++) {
-        SkPMColor c = src[i];
-        int r = SkGetPackedR32(c);
-        int g = SkGetPackedG32(c);
-        int b = SkGetPackedB32(c);
-        r = fTable[r];
-        g = fTable[g];
-        b = fTable[b];
-        dst[i] = SkPack888ToRGB16(r, g, b);
-    }
-}
-
-#ifndef SK_IGNORE_TO_STRING
-void SkPowerMode::toString(SkString* str) const {
-    str->append("SkPowerMode: exponent ");
-    str->appendScalar(fExp);
-}
-#endif
-
 static const struct {
     const char* fName;
     uint32_t    fFlags;
diff --git a/samplecode/SampleTextAlpha.cpp b/samplecode/SampleTextAlpha.cpp
index fcef92f..3f4e0db 100644
--- a/samplecode/SampleTextAlpha.cpp
+++ b/samplecode/SampleTextAlpha.cpp
@@ -28,22 +28,6 @@
 #include "SkOSFile.h"
 #include "SkStream.h"
 
-static void check_for_nonwhite(const SkBitmap& bm, int alpha) {
-    if (bm.colorType() != kRGB_565_SkColorType) {
-        return;
-    }
-
-    for (int y = 0; y < bm.height(); y++) {
-        for (int x = 0; x < bm.width(); x++) {
-            uint16_t c = *bm.getAddr16(x, y);
-            if (c != 0xFFFF) {
-                SkDebugf("------ nonwhite alpha=%x [%d %d] %x\n", alpha, x, y, c);
-                return;
-            }
-        }
-    }
-}
-
 class TextAlphaView : public SampleView {
 public:
     TextAlphaView() {
@@ -83,16 +67,6 @@
             canvas->drawText(str, strlen(str), x, y, paint);
             y += paint.getFontMetrics(NULL);
         }
-        if (false) { // avoid bit rot, suppress warning
-            check_for_nonwhite(canvas->getDevice()->accessBitmap(false), fByte);
-            SkDebugf("------ byte %x\n", fByte);
-        }
-
-        if (false) {
-            fByte += 1;
-            fByte &= 0xFF;
-            this->inval(NULL);
-        }
     }
 
     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) SK_OVERRIDE {
diff --git a/samplecode/SampleTextureDomain.cpp b/samplecode/SampleTextureDomain.cpp
index 926c559..af511c7 100644
--- a/samplecode/SampleTextureDomain.cpp
+++ b/samplecode/SampleTextureDomain.cpp
@@ -71,7 +71,7 @@
 
         srcRect.setXYWH(1, 1, 3, 3);
         dstRect.setXYWH(405, 5, 305, 305);
-        image->draw(canvas, &srcRect, dstRect, &paint);
+        canvas->drawImageRect(image, &srcRect, dstRect, &paint);
 
         // Test that bitmap blurring using a subrect
         // renders correctly
@@ -83,7 +83,7 @@
             SkBlurMaskFilter::kHighQuality_BlurFlag |
             SkBlurMaskFilter::kIgnoreTransform_BlurFlag);
         paint.setMaskFilter(mf)->unref();
-        image->draw(canvas, &srcRect, dstRect, &paint);
+        canvas->drawImageRect(image, &srcRect, dstRect, &paint);
 
         // Blur and a rotation + NULL src rect
         // This should not trigger the texture domain code
diff --git a/samplecode/SampleTiling.cpp b/samplecode/SampleTiling.cpp
index 6bb9c74..4f073bd 100644
--- a/samplecode/SampleTiling.cpp
+++ b/samplecode/SampleTiling.cpp
@@ -102,7 +102,7 @@
             textCanvas = recorder.beginRecording(1000, 1000, NULL, 0);
         }
 
-        if (NULL != textCanvas) {
+        if (textCanvas) {
             for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
                 for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
                     SkPaint p;
@@ -139,7 +139,7 @@
                         x += r.width() * 4 / 3;
                     }
                 }
-                if (NULL != textCanvas) {
+                if (textCanvas) {
                     SkPaint p;
                     SkString str;
                     p.setAntiAlias(true);
@@ -152,12 +152,12 @@
             }
         }
 
-        if (NULL != textCanvas) {
+        if (textCanvas) {
             SkASSERT(NULL == fTextPicture);
             fTextPicture.reset(recorder.endRecording());
         }
 
-        SkASSERT(NULL != fTextPicture);
+        SkASSERT(fTextPicture);
         canvas->drawPicture(fTextPicture);
     }
 
diff --git a/samplecode/SampleUnpremul.cpp b/samplecode/SampleUnpremul.cpp
index ab99ecb..992444d 100644
--- a/samplecode/SampleUnpremul.cpp
+++ b/samplecode/SampleUnpremul.cpp
@@ -106,7 +106,7 @@
         }
 
         // Name, size of the file, and whether or not it is premultiplied.
-        SkString header(SkOSPath::SkBasename(fCurrFile.c_str()));
+        SkString header(SkOSPath::Basename(fCurrFile.c_str()));
         header.appendf("     [%dx%d]     %s", fBitmap.width(), fBitmap.height(),
                        (fPremul ? "premultiplied" : "unpremultiplied"));
         canvas->drawText(header.c_str(), header.size(), 0, height, paint);
@@ -128,11 +128,7 @@
             // Copy it to a bitmap which can be drawn, converting
             // to premultiplied:
             SkBitmap bm;
-            if (!bm.allocN32Pixels(fBitmap.width(), fBitmap.height())) {
-                SkString errMsg("allocPixels failed");
-                canvas->drawText(errMsg.c_str(), errMsg.size(), 0, height, paint);
-                return;
-            }
+            bm.allocN32Pixels(fBitmap.width(), fBitmap.height());
             for (int i = 0; i < fBitmap.width(); ++i) {
                 for (int j = 0; j < fBitmap.height(); ++j) {
                     *bm.getAddr32(i, j) = premultiply_unpmcolor(*fBitmap.getAddr32(i, j));
@@ -167,7 +163,7 @@
                 return;
             }
         }
-        fCurrFile = SkOSPath::SkPathJoin(fResPath.c_str(), basename.c_str());
+        fCurrFile = SkOSPath::Join(fResPath.c_str(), basename.c_str());
         this->decodeCurrFile();
     }
 
diff --git a/src/animator/SkDrawBitmap.cpp b/src/animator/SkDrawBitmap.cpp
index f481ee7..5349774 100644
--- a/src/animator/SkDrawBitmap.cpp
+++ b/src/animator/SkDrawBitmap.cpp
@@ -89,8 +89,8 @@
     SkASSERT(height != -1);
     SkASSERT(rowBytes >= 0);
     SkColorType colorType = SkColorType(format);
-    fBitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType), rowBytes);
-    fBitmap.allocPixels();
+    fBitmap.allocPixels(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType),
+                        rowBytes);
     if (fColorSet)
         fBitmap.eraseColor(fColor);
 }
diff --git a/src/animator/SkSnapshot.cpp b/src/animator/SkSnapshot.cpp
index 6f818a6..b61d602 100644
--- a/src/animator/SkSnapshot.cpp
+++ b/src/animator/SkSnapshot.cpp
@@ -60,8 +60,10 @@
         name.append(".jpg");
     else if (type == SkImageEncoder::kPNG_Type)
         name.append(".png");
-    encoder->encodeFile(name.c_str(),
-                        maker.fCanvas->getDevice()->accessBitmap(false),
-                        SkScalarFloorToInt(quality));
+
+    SkBitmap pixels;
+    pixels.allocPixels(maker.fCanvas->imageInfo());
+    maker.fCanvas->readPixels(&pixels, 0, 0);
+    encoder->encodeFile(name.c_str(), pixels, SkScalarFloorToInt(quality));
     return false;
 }
diff --git a/src/core/SkAAClip.cpp b/src/core/SkAAClip.cpp
index 14152f8..58a16f3 100644
--- a/src/core/SkAAClip.cpp
+++ b/src/core/SkAAClip.cpp
@@ -219,6 +219,46 @@
     --yoff;
     SkASSERT(yoff->fY == lastY);
 }
+
+static void dump_one_row(const uint8_t* SK_RESTRICT row,
+                         int width, int leading_num) {
+    if (leading_num) {
+        SkDebugf( "%03d ", leading_num );
+    }
+    while (width > 0) {
+        int n = row[0];
+        int val = row[1];
+        char out = '.';
+        if (val == 0xff) {
+            out = '*';
+        } else if (val > 0) {
+            out = '+';
+        }
+        for (int i = 0 ; i < n ; i++) {
+            SkDebugf( "%c", out );
+        }
+        row += 2;
+        width -= n;
+    }
+    SkDebugf( "\n" );
+}
+
+void SkAAClip::debug(bool compress_y) const {
+    Iter iter(*this);
+    const int width = fBounds.width();
+
+    int y = fBounds.fTop;
+    while (!iter.done()) {
+        if (compress_y) {
+            dump_one_row(iter.data(), width, iter.bottom() - iter.top() + 1);
+        } else {
+            do {
+                dump_one_row(iter.data(), width, 0);
+            } while (++y < iter.bottom());
+        }
+        iter.next();
+    }
+}
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -684,6 +724,34 @@
 #endif
 }
 
+bool SkAAClip::isRect() const {
+    if (this->isEmpty()) {
+        return false;
+    }
+
+    const RunHead* head = fRunHead;
+    if (head->fRowCount != 1) {
+        return false;
+    }
+    const YOffset* yoff = head->yoffsets();
+    if (yoff->fY != fBounds.fBottom - 1) {
+        return false;
+    }
+
+    const uint8_t* row = head->data() + yoff->fOffset;
+    int width = fBounds.width();
+    do {
+        if (row[1] != 0xFF) {
+            return false;
+        }
+        int n = row[0];
+        SkASSERT(n <= width);
+        width -= n;
+        row += 2;
+    } while (width > 0);
+    return true;
+}
+
 bool SkAAClip::setRect(const SkRect& r, bool doAA) {
     if (r.isEmpty()) {
         return this->setEmpty();
diff --git a/src/core/SkAAClip.h b/src/core/SkAAClip.h
index f2cde62..45cc549 100644
--- a/src/core/SkAAClip.h
+++ b/src/core/SkAAClip.h
@@ -29,6 +29,10 @@
     bool isEmpty() const { return NULL == fRunHead; }
     const SkIRect& getBounds() const { return fBounds; }
 
+    // Returns true iff the clip is not empty, and is just a hard-edged rect (no partial alpha).
+    // If true, getBounds() can be used in place of this clip.
+    bool isRect() const;
+
     bool setEmpty();
     bool setRect(const SkIRect&);
     bool setRect(const SkRect&, bool doAA = true);
@@ -71,8 +75,10 @@
 
 #ifdef SK_DEBUG
     void validate() const;
+    void debug(bool compress_y=false) const;
 #else
     void validate() const {}
+    void debug(bool compress_y=false) const {}
 #endif
 
 private:
diff --git a/src/core/SkBBHFactory.cpp b/src/core/SkBBHFactory.cpp
index 7411eb3..c895ff6 100644
--- a/src/core/SkBBHFactory.cpp
+++ b/src/core/SkBBHFactory.cpp
@@ -6,16 +6,10 @@
  */
 
 #include "SkBBHFactory.h"
-#include "SkPictureStateTree.h"
-#include "SkQuadTree.h"
 #include "SkRTree.h"
 #include "SkTileGrid.h"
 
 
-SkBBoxHierarchy* SkQuadTreeFactory::operator()(int width, int height) const {
-    return SkNEW_ARGS(SkQuadTree, (SkIRect::MakeWH(width, height)));
-}
-
 SkBBoxHierarchy* SkRTreeFactory::operator()(int width, int height) const {
     // These values were empirically determined to produce reasonable
     // performance in most cases.
@@ -39,6 +33,5 @@
     // "-1"s below.
     int xTileCount = (width + fInfo.fTileInterval.width() - 1) / fInfo.fTileInterval.width();
     int yTileCount = (height + fInfo.fTileInterval.height() - 1) / fInfo.fTileInterval.height();
-    return SkNEW_ARGS(SkTileGrid, (xTileCount, yTileCount, fInfo,
-                                    SkTileGridNextDatum<SkPictureStateTree::Draw>));
+    return SkNEW_ARGS(SkTileGrid, (xTileCount, yTileCount, fInfo));
 }
diff --git a/src/core/SkBBoxHierarchy.h b/src/core/SkBBoxHierarchy.h
index 36047b9..fd9680c 100644
--- a/src/core/SkBBoxHierarchy.h
+++ b/src/core/SkBBoxHierarchy.h
@@ -49,7 +49,7 @@
      *        structures than repeated inserts) until flushDeferredInserts is called or the first
      *        search.
      */
-    virtual void insert(void* data, const SkIRect& bounds, bool defer = false) = 0;
+    virtual void insert(void* data, const SkRect& bounds, bool defer = false) = 0;
 
     /**
      * If any insertions have been deferred, this forces them to be inserted
@@ -59,7 +59,7 @@
     /**
      * Populate 'results' with data pointers corresponding to bounding boxes that intersect 'query'
      */
-    virtual void search(const SkIRect& query, SkTDArray<void*>* results) = 0;
+    virtual void search(const SkRect& query, SkTDArray<void*>* results) const = 0;
 
     virtual void clear() = 0;
 
diff --git a/src/core/SkBBoxHierarchyRecord.cpp b/src/core/SkBBoxHierarchyRecord.cpp
index 96e6cdf..a9cd05d 100644
--- a/src/core/SkBBoxHierarchyRecord.cpp
+++ b/src/core/SkBBoxHierarchyRecord.cpp
@@ -20,15 +20,13 @@
 }
 
 void SkBBoxHierarchyRecord::handleBBox(const SkRect& bounds) {
-    SkIRect r;
-    bounds.roundOut(&r);
     SkPictureStateTree::Draw* draw = fStateTree->appendDraw(this->writeStream().bytesWritten());
-    fBoundingHierarchy->insert(draw, r, true);
+    fBoundingHierarchy->insert(draw, bounds, true);
 }
 
-void SkBBoxHierarchyRecord::willSave(SaveFlags flags) {
+void SkBBoxHierarchyRecord::willSave() {
     fStateTree->appendSave();
-    this->INHERITED::willSave(flags);
+    this->INHERITED::willSave();
 }
 
 SkCanvas::SaveLayerStrategy SkBBoxHierarchyRecord::willSaveLayer(const SkRect* bounds,
@@ -36,23 +34,45 @@
                                                                  SaveFlags flags) {
     // For now, assume all filters affect transparent black.
     // FIXME: This could be made less conservative as an optimization.
-    bool paintAffectsTransparentBlack = NULL != paint &&
-        ((NULL != paint->getImageFilter()) ||
-         (NULL != paint->getColorFilter()));
-    SkRect drawBounds;
-    if (paintAffectsTransparentBlack) {
-        if (bounds) {
-            drawBounds = *bounds;
-            this->getTotalMatrix().mapRect(&drawBounds);
-        } else {
-            SkIRect deviceBounds;
-            this->getClipDeviceBounds(&deviceBounds);
-            drawBounds.set(deviceBounds);
+    bool paintAffectsTransparentBlack = paint &&
+        ((paint->getImageFilter()) ||
+         (paint->getColorFilter()));
+    bool needToHandleBBox = paintAffectsTransparentBlack;
+    if (!needToHandleBBox && paint) {
+      // Unusual Xfermodes require us to process a saved layer
+      // even with operations outisde the clip.
+      // For example, DstIn is used by masking layers.
+      // https://code.google.com/p/skia/issues/detail?id=1291
+      SkXfermode* xfermode = paint->getXfermode();
+      SkXfermode::Mode mode;
+      // SrcOver is the common case with a NULL xfermode, so we should
+      // make that the fast path and bypass the mode extraction and test.
+      if (xfermode && xfermode->asMode(&mode)) {
+        switch (mode) {
+          case SkXfermode::kClear_Mode:
+          case SkXfermode::kSrc_Mode:
+          case SkXfermode::kSrcIn_Mode:
+          case SkXfermode::kDstIn_Mode:
+          case SkXfermode::kSrcOut_Mode:
+          case SkXfermode::kDstATop_Mode:
+          case SkXfermode::kModulate_Mode:
+            needToHandleBBox = true;
+            break;
+          default:
+            break;
         }
+      }
+    }
+
+    SkRect drawBounds;
+    if (needToHandleBBox) {
+        SkIRect deviceBounds;
+        this->getClipDeviceBounds(&deviceBounds);
+        drawBounds.set(deviceBounds);
     }
     fStateTree->appendSaveLayer(this->writeStream().bytesWritten());
     SkCanvas::SaveLayerStrategy strategy = this->INHERITED::willSaveLayer(bounds, paint, flags);
-    if (paintAffectsTransparentBlack) {
+    if (needToHandleBBox) {
         this->handleBBox(drawBounds);
         this->addNoOp();
     }
diff --git a/src/core/SkBBoxHierarchyRecord.h b/src/core/SkBBoxHierarchyRecord.h
index 51fce0d..7db82d8 100644
--- a/src/core/SkBBoxHierarchyRecord.h
+++ b/src/core/SkBBoxHierarchyRecord.h
@@ -20,6 +20,7 @@
 public:
     /** This will take a ref of h */
     SkBBoxHierarchyRecord(const SkISize& size, uint32_t recordFlags, SkBBoxHierarchy* h);
+    virtual ~SkBBoxHierarchyRecord() { };
 
     virtual void handleBBox(const SkRect& bounds) SK_OVERRIDE;
 
@@ -27,7 +28,7 @@
     virtual bool shouldRewind(void* data) SK_OVERRIDE;
 
 protected:
-    virtual void willSave(SaveFlags) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
     virtual void willRestore() SK_OVERRIDE;
 
diff --git a/src/core/SkBBoxRecord.cpp b/src/core/SkBBoxRecord.cpp
index a40ea8b..5fe42f9 100644
--- a/src/core/SkBBoxRecord.cpp
+++ b/src/core/SkBBoxRecord.cpp
@@ -7,6 +7,13 @@
  */
 
 #include "SkBBoxRecord.h"
+#include "SkPatchUtils.h"
+
+#include "SkTextBlob.h"
+
+SkBBoxRecord::~SkBBoxRecord() {
+    fSaveStack.deleteAll();
+}
 
 void SkBBoxRecord::drawOval(const SkRect& rect, const SkPaint& paint) {
     if (this->transformBounds(rect, &paint)) {
@@ -267,6 +274,20 @@
     }
 }
 
+void SkBBoxRecord::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                  const SkPaint& paint) {
+    SkRect bbox = blob->bounds();
+    bbox.offset(x, y);
+    // FIXME: implement implicit blob bounds!
+    if (bbox.isEmpty()) {
+        this->getClipBounds(&bbox);
+    }
+
+    if (this->transformBounds(bbox, &paint)) {
+        INHERITED::onDrawTextBlob(blob, x, y, paint);
+    }
+}
+
 void SkBBoxRecord::drawVertices(VertexMode mode, int vertexCount,
                                 const SkPoint vertices[], const SkPoint texs[],
                                 const SkColor colors[], SkXfermode* xfer,
@@ -280,13 +301,49 @@
     }
 }
 
-void SkBBoxRecord::onDrawPicture(const SkPicture* picture) {
-    if (picture->width() > 0 && picture->height() > 0 &&
-        this->transformBounds(SkRect::MakeWH(picture->width(), picture->height()), NULL)) {
-        this->INHERITED::onDrawPicture(picture);
+void SkBBoxRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                               const SkPoint texCoords[4], SkXfermode* xmode,
+                               const SkPaint& paint) {
+    SkRect bbox;
+    bbox.set(cubics, SkPatchUtils::kNumCtrlPts);
+    if (this->transformBounds(bbox, &paint)) {
+        INHERITED::onDrawPatch(cubics, colors, texCoords, xmode, paint);
     }
 }
 
+void SkBBoxRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                                 const SkPaint* paint) {
+    SkRect bounds = picture->cullRect();
+    // todo: wonder if we should allow passing an optional matrix to transformBounds so we don't
+    // end up transforming the rect twice.
+    if (matrix) {
+        matrix->mapRect(&bounds);
+    }
+    if (this->transformBounds(bounds, paint)) {
+        this->INHERITED::onDrawPicture(picture, matrix, paint);
+    }
+}
+
+void SkBBoxRecord::willSave() {
+    fSaveStack.push(NULL);
+    this->INHERITED::willSave();
+}
+
+SkCanvas::SaveLayerStrategy SkBBoxRecord::willSaveLayer(const SkRect* bounds,
+                                                        const SkPaint* paint,
+                                                        SaveFlags flags) {
+    // Image filters can affect the effective bounds of primitives drawn inside saveLayer().
+    // Copy the paint so we can compute the modified bounds in transformBounds().
+    fSaveStack.push(paint && paint->getImageFilter() ? new SkPaint(*paint) : NULL);
+    return this->INHERITED::willSaveLayer(bounds, paint, flags);
+}
+
+void SkBBoxRecord::willRestore() {
+    delete fSaveStack.top();
+    fSaveStack.pop();
+    this->INHERITED::willRestore();
+}
+
 bool SkBBoxRecord::transformBounds(const SkRect& bounds, const SkPaint* paint) {
     SkRect outBounds = bounds;
     outBounds.sort();
@@ -305,6 +362,14 @@
         }
     }
 
+    for (int i = fSaveStack.count() - 1; i >= 0; --i) {
+        const SkPaint* paint = fSaveStack.getAt(i);
+        if (paint && paint->canComputeFastBounds()) {
+            SkRect temp;
+            outBounds = paint->computeFastBounds(outBounds, &temp);
+        }
+    }
+
     if (!outBounds.isEmpty() && !this->quickReject(outBounds)) {
         this->getTotalMatrix().mapRect(&outBounds);
         this->handleBBox(outBounds);
diff --git a/src/core/SkBBoxRecord.h b/src/core/SkBBoxRecord.h
index f3d72b0..4833452 100644
--- a/src/core/SkBBoxRecord.h
+++ b/src/core/SkBBoxRecord.h
@@ -10,6 +10,7 @@
 #define SkBBoxRecord_DEFINED
 
 #include "SkPictureRecord.h"
+#include "SkTDArray.h"
 
 /**
   * This is an abstract SkPictureRecord subclass that intercepts draw calls and computes an
@@ -22,7 +23,7 @@
     SkBBoxRecord(const SkISize& size, uint32_t recordFlags)
         : INHERITED(size, recordFlags) {
     }
-    virtual ~SkBBoxRecord() { }
+    virtual ~SkBBoxRecord();
 
     /**
      * This is called each time we get a bounding box, it will be axis-aligned,
@@ -65,7 +66,15 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
-    virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE;
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
+    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                             const SkPoint texCoords[4], SkXfermode* xmode,
+                             const SkPaint& paint) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
+    virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
+    virtual void willRestore() SK_OVERRIDE;
 
 private:
     /**
@@ -75,6 +84,12 @@
      **/
     bool transformBounds(const SkRect& bounds, const SkPaint* paint);
 
+    /**
+     * Paints from currently-active saveLayers that need to be applied to bounding boxes of all
+     * primitives drawn inside them. We own these pointers.
+     **/
+    SkTDArray<const SkPaint*> fSaveStack;
+
     typedef SkPictureRecord INHERITED;
 };
 
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 42254b5..f0ad029 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -91,105 +91,25 @@
     sk_bzero(this, sizeof(*this));
 }
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-SkBitmap::Config SkBitmap::config() const {
-    return SkColorTypeToBitmapConfig(fInfo.colorType());
-}
-#endif
-
-#ifdef SK_SUPPORT_LEGACY_COMPUTE_CONFIG_SIZE
-int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
-    int bpp;
-    switch (config) {
-        case kNo_Config:
-            bpp = 0;   // not applicable
-            break;
-        case kA8_Config:
-        case kIndex8_Config:
-            bpp = 1;
-            break;
-        case kRGB_565_Config:
-        case kARGB_4444_Config:
-            bpp = 2;
-            break;
-        case kARGB_8888_Config:
-            bpp = 4;
-            break;
-        default:
-            SkDEBUGFAIL("unknown config");
-            bpp = 0;   // error
-            break;
-    }
-    return bpp;
-}
-
-size_t SkBitmap::ComputeRowBytes(Config c, int width) {
-    return SkColorTypeMinRowBytes(SkBitmapConfigToColorType(c), width);
-}
-
-int64_t SkBitmap::ComputeSize64(Config config, int width, int height) {
-    SkColorType ct = SkBitmapConfigToColorType(config);
-    int64_t rowBytes = sk_64_mul(SkColorTypeBytesPerPixel(ct), width);
-    return rowBytes * height;
-}
-
-size_t SkBitmap::ComputeSize(Config c, int width, int height) {
-    int64_t size = SkBitmap::ComputeSize64(c, width, height);
-    return sk_64_isS32(size) ? sk_64_asS32(size) : 0;
-}
-#endif
-
 void SkBitmap::getBounds(SkRect* bounds) const {
     SkASSERT(bounds);
     bounds->set(0, 0,
-                SkIntToScalar(fInfo.fWidth), SkIntToScalar(fInfo.fHeight));
+                SkIntToScalar(fInfo.width()), SkIntToScalar(fInfo.height()));
 }
 
 void SkBitmap::getBounds(SkIRect* bounds) const {
     SkASSERT(bounds);
-    bounds->set(0, 0, fInfo.fWidth, fInfo.fHeight);
+    bounds->set(0, 0, fInfo.width(), fInfo.height());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static bool validate_alphaType(SkColorType colorType, SkAlphaType alphaType,
-                               SkAlphaType* canonical = NULL) {
-    switch (colorType) {
-        case kUnknown_SkColorType:
-            alphaType = kIgnore_SkAlphaType;
-            break;
-        case kAlpha_8_SkColorType:
-            if (kUnpremul_SkAlphaType == alphaType) {
-                alphaType = kPremul_SkAlphaType;
-            }
-            // fall-through
-        case kIndex_8_SkColorType:
-        case kARGB_4444_SkColorType:
-        case kRGBA_8888_SkColorType:
-        case kBGRA_8888_SkColorType:
-            if (kIgnore_SkAlphaType == alphaType) {
-                return false;
-            }
-            break;
-        case kRGB_565_SkColorType:
-            alphaType = kOpaque_SkAlphaType;
-            break;
-        default:
-            return false;
-    }
-    if (canonical) {
-        *canonical = alphaType;
-    }
-    return true;
-}
-
-bool SkBitmap::setInfo(const SkImageInfo& origInfo, size_t rowBytes) {
-    SkImageInfo info = origInfo;
-
-    if (!validate_alphaType(info.fColorType, info.fAlphaType,
-                            &info.fAlphaType)) {
+bool SkBitmap::setInfo(const SkImageInfo& info, size_t rowBytes) {
+    SkAlphaType newAT = info.alphaType();
+    if (!SkColorTypeValidateAlphaType(info.colorType(), info.alphaType(), &newAT)) {
         return reset_return_false(this);
     }
+    // don't look at info.alphaType(), since newAT is the real value...
 
     // require that rowBytes fit in 31bits
     int64_t mrb = info.minRowBytes64();
@@ -208,45 +128,37 @@
         rowBytes = 0;
     } else if (0 == rowBytes) {
         rowBytes = (size_t)mrb;
-    } else if (rowBytes < info.minRowBytes()) {
+    } else if (!info.validRowBytes(rowBytes)) {
         return reset_return_false(this);
     }
 
     this->freePixels();
 
-    fInfo = info;
+    fInfo = info.makeAlphaType(newAT);
     fRowBytes = SkToU32(rowBytes);
     return true;
 }
 
-#ifdef SK_SUPPORT_LEGACY_SETCONFIG
-bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes,
-                         SkAlphaType alphaType) {
-    SkColorType ct = SkBitmapConfigToColorType(config);
-    return this->setInfo(SkImageInfo::Make(width, height, ct, alphaType), rowBytes);
-}
-#endif
-
-bool SkBitmap::setAlphaType(SkAlphaType alphaType) {
-    if (!validate_alphaType(fInfo.fColorType, alphaType, &alphaType)) {
+bool SkBitmap::setAlphaType(SkAlphaType newAlphaType) {
+    if (!SkColorTypeValidateAlphaType(fInfo.colorType(), newAlphaType, &newAlphaType)) {
         return false;
     }
-    if (fInfo.fAlphaType != alphaType) {
-        fInfo.fAlphaType = alphaType;
+    if (fInfo.alphaType() != newAlphaType) {
+        fInfo = fInfo.makeAlphaType(newAlphaType);
         if (fPixelRef) {
-            fPixelRef->changeAlphaType(alphaType);
+            fPixelRef->changeAlphaType(newAlphaType);
         }
     }
     return true;
 }
 
 void SkBitmap::updatePixelsFromRef() const {
-    if (NULL != fPixelRef) {
+    if (fPixelRef) {
         if (fPixelLockCount > 0) {
             SkASSERT(fPixelRef->isLocked());
 
             void* p = fPixelRef->pixels();
-            if (NULL != p) {
+            if (p) {
                 p = (char*)p
                     + fPixelRefOrigin.fY * fRowBytes
                     + fPixelRefOrigin.fX * fInfo.bytesPerPixel();
@@ -266,21 +178,21 @@
     if (pr) {
         if (kUnknown_SkColorType != fInfo.colorType()) {
             const SkImageInfo& prInfo = pr->info();
-            SkASSERT(fInfo.fWidth <= prInfo.fWidth);
-            SkASSERT(fInfo.fHeight <= prInfo.fHeight);
-            SkASSERT(fInfo.fColorType == prInfo.fColorType);
-            switch (prInfo.fAlphaType) {
+            SkASSERT(fInfo.width() <= prInfo.width());
+            SkASSERT(fInfo.height() <= prInfo.height());
+            SkASSERT(fInfo.colorType() == prInfo.colorType());
+            switch (prInfo.alphaType()) {
                 case kIgnore_SkAlphaType:
-                    SkASSERT(fInfo.fAlphaType == kIgnore_SkAlphaType);
+                    SkASSERT(fInfo.alphaType() == kIgnore_SkAlphaType);
                     break;
                 case kOpaque_SkAlphaType:
                 case kPremul_SkAlphaType:
-                    SkASSERT(fInfo.fAlphaType == kOpaque_SkAlphaType ||
-                             fInfo.fAlphaType == kPremul_SkAlphaType);
+                    SkASSERT(fInfo.alphaType() == kOpaque_SkAlphaType ||
+                             fInfo.alphaType() == kPremul_SkAlphaType);
                     break;
                 case kUnpremul_SkAlphaType:
-                    SkASSERT(fInfo.fAlphaType == kOpaque_SkAlphaType ||
-                             fInfo.fAlphaType == kUnpremul_SkAlphaType);
+                    SkASSERT(fInfo.alphaType() == kOpaque_SkAlphaType ||
+                             fInfo.alphaType() == kUnpremul_SkAlphaType);
                     break;
             }
         }
@@ -289,8 +201,7 @@
 
     if (pr) {
         const SkImageInfo& info = pr->info();
-        fPixelRefOrigin.set(SkPin32(dx, 0, info.fWidth),
-                            SkPin32(dy, 0, info.fHeight));
+        fPixelRefOrigin.set(SkPin32(dx, 0, info.width()), SkPin32(dy, 0, info.height()));
     } else {
         // ignore dx,dy if there is no pixelref
         fPixelRefOrigin.setZero();
@@ -310,7 +221,7 @@
 }
 
 void SkBitmap::lockPixels() const {
-    if (NULL != fPixelRef && 0 == sk_atomic_inc(&fPixelLockCount)) {
+    if (fPixelRef && 0 == sk_atomic_inc(&fPixelLockCount)) {
         fPixelRef->lockPixels();
         this->updatePixelsFromRef();
     }
@@ -320,7 +231,7 @@
 void SkBitmap::unlockPixels() const {
     SkASSERT(NULL == fPixelRef || fPixelLockCount > 0);
 
-    if (NULL != fPixelRef && 1 == sk_atomic_dec(&fPixelLockCount)) {
+    if (fPixelRef && 1 == sk_atomic_dec(&fPixelLockCount)) {
         fPixelRef->unlockPixels();
         this->updatePixelsFromRef();
     }
@@ -355,7 +266,7 @@
     SkDEBUGCODE(this->validate();)
 }
 
-bool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) {
+bool SkBitmap::tryAllocPixels(Allocator* allocator, SkColorTable* ctable) {
     HeapAllocator stdalloc;
 
     if (NULL == allocator) {
@@ -366,9 +277,38 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-bool SkBitmap::allocPixels(const SkImageInfo& requestedInfo, SkPixelRefFactory* factory,
-                           SkColorTable* ctable) {
-    if (kIndex_8_SkColorType == requestedInfo.fColorType && NULL == ctable) {
+bool SkBitmap::tryAllocPixels(const SkImageInfo& requestedInfo, size_t rowBytes) {
+    if (kIndex_8_SkColorType == requestedInfo.colorType()) {
+        return reset_return_false(this);
+    }
+    if (!this->setInfo(requestedInfo, rowBytes)) {
+        return reset_return_false(this);
+    }
+    
+    // setInfo may have corrected info (e.g. 565 is always opaque).
+    const SkImageInfo& correctedInfo = this->info();
+    // setInfo may have computed a valid rowbytes if 0 were passed in
+    rowBytes = this->rowBytes();
+
+    SkMallocPixelRef::PRFactory defaultFactory;
+    
+    SkPixelRef* pr = defaultFactory.create(correctedInfo, rowBytes, NULL);
+    if (NULL == pr) {
+        return reset_return_false(this);
+    }
+    this->setPixelRef(pr)->unref();
+    
+    // TODO: lockPixels could/should return bool or void*/NULL
+    this->lockPixels();
+    if (NULL == this->getPixels()) {
+        return reset_return_false(this);
+    }
+    return true;
+}
+
+bool SkBitmap::tryAllocPixels(const SkImageInfo& requestedInfo, SkPixelRefFactory* factory,
+                                SkColorTable* ctable) {
+    if (kIndex_8_SkColorType == requestedInfo.colorType() && NULL == ctable) {
         return reset_return_false(this);
     }
     if (!this->setInfo(requestedInfo)) {
@@ -383,7 +323,7 @@
         factory = &defaultFactory;
     }
 
-    SkPixelRef* pr = factory->create(correctedInfo, ctable);
+    SkPixelRef* pr = factory->create(correctedInfo, correctedInfo.minRowBytes(), ctable);
     if (NULL == pr) {
         return reset_return_false(this);
     }
@@ -436,7 +376,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkBitmap::freePixels() {
-    if (NULL != fPixelRef) {
+    if (fPixelRef) {
         if (fPixelLockCount > 0) {
             fPixelRef->unlockPixels();
         }
@@ -525,8 +465,7 @@
             SkAutoLockPixels lock(*this);
             const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels());
             uint8_t* dstP = reinterpret_cast<uint8_t*>(dst);
-            for (int row = 0; row < fInfo.fHeight;
-                 row++, srcP += fRowBytes, dstP += dstRowBytes) {
+            for (int row = 0; row < fInfo.height(); row++, srcP += fRowBytes, dstP += dstRowBytes) {
                 memcpy(dstP, srcP, rowBytes);
             }
 
@@ -538,15 +477,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 bool SkBitmap::isImmutable() const {
-    return fPixelRef ? fPixelRef->isImmutable() :
-        fFlags & kImageIsImmutable_Flag;
+    return fPixelRef ? fPixelRef->isImmutable() : false;
 }
 
 void SkBitmap::setImmutable() {
     if (fPixelRef) {
         fPixelRef->setImmutable();
-    } else {
-        fFlags |= kImageIsImmutable_Flag;
     }
 }
 
@@ -918,10 +854,8 @@
         return false;
     }
     
-    SkImageInfo dstInfo = requestedDstInfo;
     // the intersect may have shrunk info's logical size
-    dstInfo.fWidth = srcR.width();
-    dstInfo.fHeight = srcR.height();
+    const SkImageInfo dstInfo = requestedDstInfo.makeWH(srcR.width(), srcR.height());
     
     // if x or y are negative, then we have to adjust pixels
     if (x > 0) {
@@ -942,9 +876,7 @@
         return false;
     }
     
-    SkImageInfo srcInfo = this->info();
-    srcInfo.fWidth = dstInfo.width();
-    srcInfo.fHeight = dstInfo.height();
+    const SkImageInfo srcInfo = this->info().makeWH(dstInfo.width(), dstInfo.height());
     
     const void* srcPixels = this->getAddr(srcR.x(), srcR.y());
     return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB, srcInfo, srcPixels, this->rowBytes(),
@@ -997,8 +929,7 @@
     // The only way to be readyToDraw is if fPixelRef is non NULL.
     SkASSERT(fPixelRef != NULL);
 
-    SkImageInfo dstInfo = src->info();
-    dstInfo.fColorType = dstColorType;
+    const SkImageInfo dstInfo = src->info().makeColorType(dstColorType);
 
     SkBitmap tmpDst;
     if (!tmpDst.setInfo(dstInfo)) {
@@ -1011,7 +942,7 @@
         // TODO: can we just ref() the src colortable? Is it reentrant-safe?
         ctable.reset(SkNEW_ARGS(SkColorTable, (*src->getColorTable())));
     }
-    if (!tmpDst.allocPixels(alloc, ctable)) {
+    if (!tmpDst.tryAllocPixels(alloc, ctable)) {
         return false;
     }
 
@@ -1070,8 +1001,7 @@
                 rowBytes = 0;
             }
 
-            SkImageInfo info = fInfo;
-            info.fColorType = dstCT;
+            const SkImageInfo info = fInfo.makeColorType(dstCT);
             if (!dst->setInfo(info, rowBytes)) {
                 return false;
             }
@@ -1173,7 +1103,7 @@
     SkMaskFilter* filter = paint ? paint->getMaskFilter() : NULL;
 
     // compute our (larger?) dst bounds if we have a filter
-    if (NULL != filter) {
+    if (filter) {
         identity.reset();
         srcM.fImage = NULL;
         if (!filter->filterMask(&dstM, srcM, identity, NULL)) {
@@ -1183,7 +1113,7 @@
     } else {
     NO_FILTER_CASE:
         tmpBitmap.setInfo(SkImageInfo::MakeA8(this->width(), this->height()), srcM.fRowBytes);
-        if (!tmpBitmap.allocPixels(allocator, NULL)) {
+        if (!tmpBitmap.tryAllocPixels(allocator, NULL)) {
             // Allocation of pixels for alpha bitmap failed.
             SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
                     tmpBitmap.width(), tmpBitmap.height());
@@ -1207,7 +1137,7 @@
 
     tmpBitmap.setInfo(SkImageInfo::MakeA8(dstM.fBounds.width(), dstM.fBounds.height()),
                       dstM.fRowBytes);
-    if (!tmpBitmap.allocPixels(allocator, NULL)) {
+    if (!tmpBitmap.tryAllocPixels(allocator, NULL)) {
         // Allocation of pixels for alpha bitmap failed.
         SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
                 tmpBitmap.width(), tmpBitmap.height());
@@ -1268,6 +1198,11 @@
     SkImageInfo info;
     info.unflatten(*buffer);
 
+    // If there was an error reading "info", don't use it to compute minRowBytes()
+    if (!buffer->validate(true)) {
+        return false;
+    }
+
     const size_t ramRB = info.minRowBytes();
     const int height = info.height();
     const size_t snugSize = snugRB * height;
@@ -1276,9 +1211,9 @@
         return false;
     }
 
-    char* dst = (char*)sk_malloc_throw(ramSize);
+    SkAutoDataUnref data(SkData::NewUninitialized(ramSize));
+    char* dst = (char*)data->writable_data();
     buffer->readByteArray(dst, snugSize);
-    SkAutoDataUnref data(SkData::NewFromMalloc(dst, ramSize));
 
     if (snugSize != ramSize) {
         const char* srcRow = dst + snugRB * (height - 1);
@@ -1309,6 +1244,7 @@
 };
 
 void SkBitmap::legacyUnflatten(SkReadBuffer& buffer) {
+#ifdef SK_SUPPORT_LEGACY_PIXELREF_UNFLATTENABLE
     this->reset();
 
     SkImageInfo info;
@@ -1317,7 +1253,7 @@
     if (!buffer.validate((info.width() >= 0) && (info.height() >= 0) &&
                          SkColorTypeIsValid(info.fColorType) &&
                          SkAlphaTypeIsValid(info.fAlphaType) &&
-                         validate_alphaType(info.fColorType, info.fAlphaType) &&
+                         SkColorTypeValidateAlphaType(info.fColorType, info.fAlphaType) &&
                          info.validRowBytes(rowBytes))) {
         return;
     }
@@ -1334,7 +1270,7 @@
                 origin.fX = buffer.readInt();
                 origin.fY = buffer.readInt();
                 size_t offset = origin.fY * rowBytes + origin.fX * info.bytesPerPixel();
-                SkPixelRef* pr = buffer.readPixelRef();
+                SkPixelRef* pr = buffer.readFlattenable<SkPixelRef>();
                 if (!buffer.validate((NULL == pr) ||
                        (pr->getAllocatedSizeInBytes() >= (offset + this->getSafeSize())))) {
                     origin.setZero();
@@ -1349,6 +1285,9 @@
                 sk_throw();
         }
     }
+#else
+    sk_throw();
+#endif
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1375,11 +1314,11 @@
     }
 
     SkASSERT(fInfo.validRowBytes(fRowBytes));
-    uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImmutable_Flag;
+    uint8_t allFlags = kImageIsVolatile_Flag;
 #ifdef SK_BUILD_FOR_ANDROID
     allFlags |= kHasHardwareMipMap_Flag;
 #endif
-    SkASSERT(fFlags <= allFlags);
+    SkASSERT((~allFlags & fFlags) == 0);
     SkASSERT(fPixelLockCount >= 0);
 
     if (fPixels) {
@@ -1390,7 +1329,7 @@
         SkASSERT(fPixelRefOrigin.fX >= 0);
         SkASSERT(fPixelRefOrigin.fY >= 0);
         SkASSERT(fPixelRef->info().width() >= (int)this->width() + fPixelRefOrigin.fX);
-        SkASSERT(fPixelRef->info().fHeight >= (int)this->height() + fPixelRefOrigin.fY);
+        SkASSERT(fPixelRef->info().height() >= (int)this->height() + fPixelRefOrigin.fY);
         SkASSERT(fPixelRef->rowBytes() >= fInfo.minRowBytes());
     } else {
         SkASSERT(NULL == fColorTable);
@@ -1427,7 +1366,7 @@
         str->appendf(" pixels:%p", this->getPixels());
     } else {
         const char* uri = pr->getURI();
-        if (NULL != uri) {
+        if (uri) {
             str->appendf(" uri:\"%s\"", uri);
         } else {
             str->appendf(" pixelref:%p", pr);
diff --git a/src/core/SkBitmapCache.cpp b/src/core/SkBitmapCache.cpp
new file mode 100644
index 0000000..5044d30
--- /dev/null
+++ b/src/core/SkBitmapCache.cpp
@@ -0,0 +1,165 @@
+/*
+ * 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 "SkBitmapCache.h"
+#include "SkResourceCache.h"
+#include "SkMipMap.h"
+#include "SkRect.h"
+
+SkBitmap::Allocator* SkBitmapCache::GetAllocator() {
+    return SkResourceCache::GetAllocator();
+}
+
+/**
+ This function finds the bounds of the bitmap *within its pixelRef*.
+ If the bitmap lacks a pixelRef, it will return an empty rect, since
+ that doesn't make sense.  This may be a useful enough function that
+ it should be somewhere else (in SkBitmap?).
+ */
+static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) {
+    if (!(bm.pixelRef())) {
+        return SkIRect::MakeEmpty();
+    }
+    SkIPoint origin = bm.pixelRefOrigin();
+    return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
+}
+
+struct BitmapKey : public SkResourceCache::Key {
+public:
+    BitmapKey(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& bounds)
+    : fGenID(genID)
+    , fScaleX(scaleX)
+    , fScaleY(scaleY)
+    , fBounds(bounds)
+    {
+        this->init(sizeof(fGenID) + sizeof(fScaleX) + sizeof(fScaleY) + sizeof(fBounds));
+    }
+
+    uint32_t    fGenID;
+    SkScalar    fScaleX;
+    SkScalar    fScaleY;
+    SkIRect     fBounds;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+struct BitmapRec : public SkResourceCache::Rec {
+    BitmapRec(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& bounds,
+              const SkBitmap& result)
+        : fKey(genID, scaleX, scaleY, bounds)
+        , fBitmap(result)
+    {}
+
+    BitmapKey   fKey;
+    SkBitmap    fBitmap;
+
+    virtual const Key& getKey() const SK_OVERRIDE { return fKey; }
+    virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fBitmap.getSize(); }
+
+    static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextBitmap) {
+        const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec);
+        SkBitmap* result = (SkBitmap*)contextBitmap;
+
+        *result = rec.fBitmap;
+        result->lockPixels();
+        return SkToBool(result->getPixels());
+    }
+};
+
+#define CHECK_LOCAL(localCache, localName, globalName, ...) \
+    (localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__)
+
+bool SkBitmapCache::Find(const SkBitmap& src, SkScalar invScaleX, SkScalar invScaleY, SkBitmap* result,
+                         SkResourceCache* localCache) {
+    if (0 == invScaleX || 0 == invScaleY) {
+        // degenerate, and the key we use for mipmaps
+        return false;
+    }
+    BitmapKey key(src.getGenerationID(), invScaleX, invScaleY, get_bounds_from_bitmap(src));
+
+    return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Visitor, result);
+}
+
+void SkBitmapCache::Add(const SkBitmap& src, SkScalar invScaleX, SkScalar invScaleY,
+                        const SkBitmap& result, SkResourceCache* localCache) {
+    if (0 == invScaleX || 0 == invScaleY) {
+        // degenerate, and the key we use for mipmaps
+        return;
+    }
+    SkASSERT(result.isImmutable());
+    BitmapRec* rec = SkNEW_ARGS(BitmapRec, (src.getGenerationID(), invScaleX, invScaleY,
+                                            get_bounds_from_bitmap(src), result));
+    CHECK_LOCAL(localCache, add, Add, rec);
+}
+
+bool SkBitmapCache::Find(uint32_t genID, const SkIRect& subset, SkBitmap* result,
+                         SkResourceCache* localCache) {
+    BitmapKey key(genID, SK_Scalar1, SK_Scalar1, subset);
+
+    return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Visitor, result);
+}
+
+bool SkBitmapCache::Add(uint32_t genID, const SkIRect& subset, const SkBitmap& result,
+                        SkResourceCache* localCache) {
+    SkASSERT(result.isImmutable());
+
+    if (subset.isEmpty()
+        || subset.top() < 0
+        || subset.left() < 0
+        || result.width() != subset.width()
+        || result.height() != subset.height()) {
+        return false;
+    } else {
+        BitmapRec* rec = SkNEW_ARGS(BitmapRec, (genID, SK_Scalar1, SK_Scalar1, subset, result));
+
+        CHECK_LOCAL(localCache, add, Add, rec);
+        return true;
+    }
+}
+//////////////////////////////////////////////////////////////////////////////////////////
+
+struct MipMapRec : public SkResourceCache::Rec {
+    MipMapRec(const SkBitmap& src, const SkMipMap* result)
+        : fKey(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src))
+        , fMipMap(SkRef(result))
+    {}
+
+    virtual ~MipMapRec() {
+        fMipMap->unref();
+    }
+
+    BitmapKey       fKey;
+    const SkMipMap* fMipMap;
+
+    virtual const Key& getKey() const SK_OVERRIDE { return fKey; }
+    virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fMipMap->getSize(); }
+
+    static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextMip) {
+        const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec);
+        const SkMipMap** result = (const SkMipMap**)contextMip;
+        
+        *result = SkRef(rec.fMipMap);
+        // mipmaps don't use the custom allocator yet, so we don't need to check pixels
+        return true;
+    }
+};
+
+const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmap& src) {
+    BitmapKey key(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src));
+    const SkMipMap* result;
+    if (!SkResourceCache::Find(key, MipMapRec::Visitor, &result)) {
+        result = NULL;
+    }
+    return result;
+}
+
+void SkMipMapCache::Add(const SkBitmap& src, const SkMipMap* result) {
+    if (result) {
+        SkResourceCache::Add(SkNEW_ARGS(MipMapRec, (src, result)));
+    }
+}
+
diff --git a/src/core/SkBitmapCache.h b/src/core/SkBitmapCache.h
new file mode 100644
index 0000000..181c858
--- /dev/null
+++ b/src/core/SkBitmapCache.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBitmapCache_DEFINED
+#define SkBitmapCache_DEFINED
+
+#include "SkScalar.h"
+#include "SkBitmap.h"
+
+class SkResourceCache;
+class SkMipMap;
+
+class SkBitmapCache {
+public:
+    /**
+     * Use this allocator for bitmaps, so they can use ashmem when available.
+     * Returns NULL if the ResourceCache has not been initialized with a DiscardableFactory.
+     */
+    static SkBitmap::Allocator* GetAllocator();
+
+    /**
+     *  Search based on the src bitmap and inverse scales in X and Y. If found, returns true and
+     *  result will be set to the matching bitmap with its pixels already locked.
+     */
+    static bool Find(const SkBitmap& src, SkScalar invScaleX, SkScalar invScaleY, SkBitmap* result,
+                     SkResourceCache* localCache = NULL);
+
+    /*
+     *  result must be marked isImmutable()
+     */
+    static void Add(const SkBitmap& src, SkScalar invScaleX, SkScalar invScaleY,
+            const SkBitmap& result, SkResourceCache* localCache = NULL);
+
+    /**
+     *  Search based on the bitmap's genID and subset. If found, returns true and
+     *  result will be set to the matching bitmap with its pixels already locked.
+     */
+    static bool Find(uint32_t genID, const SkIRect& subset, SkBitmap* result,
+                     SkResourceCache* localCache = NULL);
+
+    /**
+     * The width and the height of the provided subset must be the same as the result bitmap ones.
+     * result must be marked isImmutable()
+     */
+    static bool Add(uint32_t genID, const SkIRect& subset, const SkBitmap& result,
+                    SkResourceCache* localCache = NULL);
+};
+
+class SkMipMapCache {
+public:
+    static const SkMipMap* FindAndRef(const SkBitmap& src);
+    static void Add(const SkBitmap& src, const SkMipMap* result);
+};
+
+#endif
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 1dfc3a6..b48432e 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -61,20 +61,23 @@
     SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL));
 }
 
+#if 0
 SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties)
     : SkBaseDevice(deviceProperties)
     , fBitmap(bitmap)
 {
     SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL));
 }
+#endif
 
 SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
                                        const SkDeviceProperties* props) {
-    SkImageInfo info = origInfo;
-    if (!valid_for_bitmap_device(info, &info.fAlphaType)) {
+    SkAlphaType newAT = origInfo.alphaType();
+    if (!valid_for_bitmap_device(origInfo, &newAT)) {
         return NULL;
     }
 
+    const SkImageInfo info = origInfo.makeAlphaType(newAT);
     SkBitmap bitmap;
 
     if (kUnknown_SkColorType == info.colorType()) {
@@ -82,7 +85,7 @@
             return NULL;
         }
     } else {
-        if (!bitmap.allocPixels(info)) {
+        if (!bitmap.tryAllocPixels(info)) {
             return NULL;
         }
         if (!bitmap.info().isOpaque()) {
@@ -90,8 +93,8 @@
         }
     }
 
-    if (props) {
-        return SkNEW_ARGS(SkBitmapDevice, (bitmap, *props));
+    if (props && false) {
+//        return SkNEW_ARGS(SkBitmapDevice, (bitmap, *props));
     } else {
         return SkNEW_ARGS(SkBitmapDevice, (bitmap));
     }
@@ -109,7 +112,7 @@
 }
 
 SkBaseDevice* SkBitmapDevice::onCreateDevice(const SkImageInfo& info, Usage usage) {
-    return SkBitmapDevice::Create(info, &this->getDeviceProperties());
+    return SkBitmapDevice::Create(info);// &this->getDeviceProperties());
 }
 
 void SkBitmapDevice::lockPixels() {
@@ -132,20 +135,6 @@
     return fBitmap;
 }
 
-bool SkBitmapDevice::canHandleImageFilter(const SkImageFilter*) {
-    return false;
-}
-
-bool SkBitmapDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src,
-                                 const SkImageFilter::Context& ctx, SkBitmap* result,
-                                 SkIPoint* offset) {
-    return false;
-}
-
-bool SkBitmapDevice::allowImageFilter(const SkImageFilter*) {
-    return true;
-}
-
 void* SkBitmapDevice::onAccessPixels(SkImageInfo* info, size_t* rowBytes) {
     if (fBitmap.getPixels()) {
         *info = fBitmap.info();
@@ -156,6 +145,7 @@
 }
 
 #include "SkConfig8888.h"
+#include "SkPixelRef.h"
 
 bool SkBitmapDevice::onWritePixels(const SkImageInfo& srcInfo, const void* srcPixels,
                                    size_t srcRowBytes, int x, int y) {
@@ -164,9 +154,7 @@
         return false;
     }
 
-    SkImageInfo dstInfo = fBitmap.info();
-    dstInfo.fWidth = srcInfo.width();
-    dstInfo.fHeight = srcInfo.height();
+    const SkImageInfo dstInfo = fBitmap.info().makeWH(srcInfo.width(), srcInfo.height());
 
     void* dstPixels = fBitmap.getAddr(x, y);
     size_t dstRowBytes = fBitmap.rowBytes();
@@ -274,8 +262,14 @@
         // the bitmap, we extract a subset.
         SkIRect srcIR;
         tmpSrc.roundOut(&srcIR);
-        if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
-            return;
+        if(bitmap.pixelRef()->getTexture()) {
+            // Accelerated source canvas, don't use extractSubset but readPixels to get the subset.
+            // This way, the pixels are copied in CPU memory instead of GPU memory.
+            bitmap.pixelRef()->readPixels(&tmpBitmap, &srcIR);
+        } else {
+            if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
+                return;
+            }
         }
         bitmapPtr = &tmpBitmap;
 
@@ -363,8 +357,8 @@
     draw.drawSprite(src, x, y, paint);
 }
 
-SkSurface* SkBitmapDevice::newSurface(const SkImageInfo& info) {
-    return SkSurface::NewRaster(info);
+SkSurface* SkBitmapDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
+    return SkSurface::NewRaster(info, &props);
 }
 
 const void* SkBitmapDevice::peekPixels(SkImageInfo* info, size_t* rowBytes) {
@@ -381,6 +375,12 @@
     return NULL;
 }
 
+SkImageFilter::Cache* SkBitmapDevice::getImageFilterCache() {
+    SkImageFilter::Cache* cache = SkImageFilter::Cache::Get();
+    cache->ref();
+    return cache;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 bool SkBitmapDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
@@ -395,9 +395,9 @@
         paint.isFakeBoldText() ||
         paint.getStyle() != SkPaint::kFill_Style ||
         !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)) {
-        // turn off lcd
+        // turn off lcd, but turn on kGenA8
         flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
-        flags->fHinting = paint.getHinting();
+        flags->fFlags |= SkPaint::kGenA8FromLCD_Flag;
         return true;
     }
     // we're cool with the paint as is
diff --git a/src/core/SkBitmapFilter.cpp b/src/core/SkBitmapFilter.cpp
index a9c3223..20a0514 100644
--- a/src/core/SkBitmapFilter.cpp
+++ b/src/core/SkBitmapFilter.cpp
@@ -28,6 +28,7 @@
 void highQualityFilter(ColorPacker pack, const SkBitmapProcState& s, int x, int y, Color* SK_RESTRICT colors, int count) {
     const int maxX = s.fBitmap->width();
     const int maxY = s.fBitmap->height();
+    SkAutoTMalloc<SkScalar> xWeights(maxX);
 
     while (count-- > 0) {
         SkPoint srcPt;
@@ -44,11 +45,16 @@
         int x0 = SkClampMax(SkScalarCeilToInt(srcPt.fX-s.getBitmapFilter()->width()), maxX);
         int x1 = SkClampMax(SkScalarFloorToInt(srcPt.fX+s.getBitmapFilter()->width())+1, maxX);
 
+        for (int srcX = x0; srcX < x1 ; srcX++) {
+            // Looking these up once instead of each loop is a ~15% speedup.
+            xWeights[srcX - x0] = s.getBitmapFilter()->lookupScalar((srcPt.fX - srcX));
+        }
+
         for (int srcY = y0; srcY < y1; srcY++) {
             SkScalar yWeight = s.getBitmapFilter()->lookupScalar((srcPt.fY - srcY));
 
             for (int srcX = x0; srcX < x1 ; srcX++) {
-                SkScalar xWeight = s.getBitmapFilter()->lookupScalar((srcPt.fX - srcX));
+                SkScalar xWeight = xWeights[srcX - x0];
 
                 SkScalar combined_weight = SkScalarMul(xWeight, yWeight);
 
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 8e03a80..9c900d3 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -39,13 +39,14 @@
     fTileModeY = (uint8_t)tmy;
 }
 
-SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     buffer.readBitmap(&fRawBitmap);
     fRawBitmap.setImmutable();
     fTileModeX = buffer.readUInt();
     fTileModeY = buffer.readUInt();
 }
+#endif
 
 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture,
                                                    SkMatrix* texM,
@@ -63,9 +64,21 @@
     return kDefault_BitmapType;
 }
 
-void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
+SkFlattenable* SkBitmapProcShader::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix lm;
+    buffer.readMatrix(&lm);
+    SkBitmap bm;
+    if (!buffer.readBitmap(&bm)) {
+        return NULL;
+    }
+    bm.setImmutable();
+    TileMode mx = (TileMode)buffer.readUInt();
+    TileMode my = (TileMode)buffer.readUInt();
+    return SkShader::CreateBitmapShader(bm, mx, my, &lm);
+}
 
+void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const {
+    buffer.writeMatrix(this->getLocalMatrix());
     buffer.writeBitmap(fRawBitmap);
     buffer.writeUInt(fTileModeX);
     buffer.writeUInt(fTileModeY);
@@ -382,9 +395,9 @@
 #include "effects/GrSimpleTextureEffect.h"
 #include "SkGr.h"
 
-bool SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                     const SkMatrix* localMatrix, GrColor* grColor,
-                                     GrEffectRef** grEffect) const {
+bool SkBitmapProcShader::asFragmentProcessor(GrContext* context, const SkPaint& paint,
+                                             const SkMatrix* localMatrix, GrColor* paintColor,
+                                             GrFragmentProcessor** fp) const {
     SkMatrix matrix;
     matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height());
 
@@ -454,13 +467,14 @@
         return false;
     }
     
-    *grColor = (kAlpha_8_SkColorType == fRawBitmap.colorType()) ? SkColor2GrColor(paint.getColor())
-                                        : SkColor2GrColorJustAlpha(paint.getColor());
+    *paintColor = (kAlpha_8_SkColorType == fRawBitmap.colorType()) ?
+                                                SkColor2GrColor(paint.getColor()) :
+                                                SkColor2GrColorJustAlpha(paint.getColor());
 
     if (useBicubic) {
-        *grEffect = GrBicubicEffect::Create(texture, matrix, tm);
+        *fp = GrBicubicEffect::Create(texture, matrix, tm);
     } else {
-        *grEffect = GrSimpleTextureEffect::Create(texture, matrix, params);
+        *fp = GrSimpleTextureEffect::Create(texture, matrix, params);
     }
     GrUnlockAndUnrefCachedBitmapTexture(texture);
 
@@ -469,9 +483,8 @@
 
 #else 
 
-bool SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                     const SkMatrix* localMatrix, GrColor* grColor,
-                                     GrEffectRef** grEffect) const {
+bool SkBitmapProcShader::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                             GrFragmentProcessor**) const {
     SkDEBUGFAIL("Should not call in GPU-less build");
     return false;
 }
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index 08e8397..cd52d99 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -31,7 +31,8 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader)
 
 
-    bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor*, GrEffectRef**)
+    bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                             GrFragmentProcessor**)
             const SK_OVERRIDE;
 
     class BitmapProcShaderContext : public SkShader::Context {
@@ -55,7 +56,9 @@
     };
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkBitmapProcShader(SkReadBuffer& );
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
@@ -71,7 +74,7 @@
 // an Sk3DBlitter in SkDraw.cpp
 // Note that some contexts may contain other contexts (e.g. for compose shaders), but we've not
 // yet found a situation where the size below isn't big enough.
-typedef SkSmallAllocator<3, 768> SkTBlitterAllocator;
+typedef SkSmallAllocator<3, 1024> SkTBlitterAllocator;
 
 // If alloc is non-NULL, it will be used to allocate the returned SkShader, and MUST outlive
 // the SkShader.
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
index 137bcda..c3801e4 100644
--- a/src/core/SkBitmapProcState.cpp
+++ b/src/core/SkBitmapProcState.cpp
@@ -1,10 +1,11 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
+#include "SkBitmapCache.h"
 #include "SkBitmapProcState.h"
 #include "SkColorPriv.h"
 #include "SkFilterProc.h"
@@ -14,8 +15,8 @@
 #include "SkBitmapScaler.h"
 #include "SkMipMap.h"
 #include "SkPixelRef.h"
-#include "SkScaledImageCache.h"
 #include "SkImageEncoder.h"
+#include "SkResourceCache.h"
 
 #if !SK_ARM_NEON_IS_NONE
 // These are defined in src/opts/SkBitmapProcState_arm_neon.cpp
@@ -107,31 +108,10 @@
     return SkMaxScalar(v1.lengthSqd(), v2.lengthSqd());
 }
 
-class AutoScaledCacheUnlocker {
-public:
-    AutoScaledCacheUnlocker(SkScaledImageCache::ID** idPtr) : fIDPtr(idPtr) {}
-    ~AutoScaledCacheUnlocker() {
-        if (fIDPtr && *fIDPtr) {
-            SkScaledImageCache::Unlock(*fIDPtr);
-            *fIDPtr = NULL;
-        }
-    }
-
-    // forgets the ID, so it won't call Unlock
-    void release() {
-        fIDPtr = NULL;
-    }
-
-private:
-    SkScaledImageCache::ID** fIDPtr;
-};
-#define AutoScaledCacheUnlocker(...) SK_REQUIRE_LOCAL_VAR(AutoScaledCacheUnlocker)
-
 // Check to see that the size of the bitmap that would be produced by
 // scaling by the given inverted matrix is less than the maximum allowed.
 static inline bool cache_size_okay(const SkBitmap& bm, const SkMatrix& invMat) {
-    size_t maximumAllocation
-        = SkScaledImageCache::GetSingleAllocationByteLimit();
+    size_t maximumAllocation = SkResourceCache::GetSingleAllocationByteLimit();
     if (0 == maximumAllocation) {
         return true;
     }
@@ -147,85 +127,93 @@
 // the interface to the cache, but might be well worth it.
 
 bool SkBitmapProcState::possiblyScaleImage() {
-    AutoScaledCacheUnlocker unlocker(&fScaledCacheID);
-
     SkASSERT(NULL == fBitmap);
-    SkASSERT(NULL == fScaledCacheID);
+
+    fAdjustedMatrix = false;
 
     if (fFilterLevel <= SkPaint::kLow_FilterLevel) {
         return false;
     }
     // Check to see if the transformation matrix is simple, and if we're
     // doing high quality scaling.  If so, do the bitmap scale here and
-    // remove the scaling component from the matrix.
+    // remove the (non-fractional) scaling component from the matrix.
+
+    SkScalar invScaleX = fInvMatrix.getScaleX();
+    SkScalar invScaleY = fInvMatrix.getScaleY();
+
+    float trueDestWidth  = fOrigBitmap.width() / invScaleX;
+    float trueDestHeight = fOrigBitmap.height() / invScaleY;
+
+#ifndef SK_IGNORE_PROPER_FRACTIONAL_SCALING
+    float roundedDestWidth = SkScalarRoundToScalar(trueDestWidth);
+    float roundedDestHeight = SkScalarRoundToScalar(trueDestHeight);
+#else
+    float roundedDestWidth = trueDestWidth;
+    float roundedDestHeight = trueDestHeight;
+#endif
 
     if (SkPaint::kHigh_FilterLevel == fFilterLevel &&
         fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask) &&
         kN32_SkColorType == fOrigBitmap.colorType() &&
         cache_size_okay(fOrigBitmap, fInvMatrix)) {
 
-        SkScalar invScaleX = fInvMatrix.getScaleX();
-        SkScalar invScaleY = fInvMatrix.getScaleY();
+        if (SkScalarNearlyEqual(invScaleX,1.0f) &&
+            SkScalarNearlyEqual(invScaleY,1.0f)) {
+            // short-circuit identity scaling; the output is supposed to
+            // be the same as the input, so we might as well go fast.
 
-        fScaledCacheID = SkScaledImageCache::FindAndLock(fOrigBitmap,
-                                                         invScaleX, invScaleY,
-                                                         &fScaledBitmap);
-        if (fScaledCacheID) {
-            fScaledBitmap.lockPixels();
-            if (!fScaledBitmap.getPixels()) {
-                fScaledBitmap.unlockPixels();
-                // found a purged entry (discardablememory?), release it
-                SkScaledImageCache::Unlock(fScaledCacheID);
-                fScaledCacheID = NULL;
-                // fall through to rebuild
-            }
+            // Note(humper): We could also probably do this if the scales
+            // are close to -1 as well, since the flip doesn't require
+            // any fancy re-sampling...
+
+            // Set our filter level to low -- the only post-filtering this
+            // image might require is some interpolation if the translation
+            // is fractional.
+            fFilterLevel = SkPaint::kLow_FilterLevel;
+            return false;
         }
 
-        if (NULL == fScaledCacheID) {
-            float dest_width  = fOrigBitmap.width() / invScaleX;
-            float dest_height = fOrigBitmap.height() / invScaleY;
-
+        if (!SkBitmapCache::Find(fOrigBitmap, roundedDestWidth, roundedDestHeight, &fScaledBitmap)) {
             // All the criteria are met; let's make a new bitmap.
 
-            SkConvolutionProcs simd;
-            sk_bzero(&simd, sizeof(simd));
-            this->platformConvolutionProcs(&simd);
-
             if (!SkBitmapScaler::Resize(&fScaledBitmap,
                                         fOrigBitmap,
                                         SkBitmapScaler::RESIZE_BEST,
-                                        dest_width,
-                                        dest_height,
-                                        simd,
-                                        SkScaledImageCache::GetAllocator())) {
+                                        roundedDestWidth,
+                                        roundedDestHeight,
+                                        SkResourceCache::GetAllocator())) {
                 // we failed to create fScaledBitmap, so just return and let
                 // the scanline proc handle it.
                 return false;
 
             }
 
-            SkASSERT(NULL != fScaledBitmap.getPixels());
-            fScaledCacheID = SkScaledImageCache::AddAndLock(fOrigBitmap,
-                                                            invScaleX,
-                                                            invScaleY,
-                                                            fScaledBitmap);
-            if (!fScaledCacheID) {
-                fScaledBitmap.reset();
-                return false;
-            }
-            SkASSERT(NULL != fScaledBitmap.getPixels());
+            SkASSERT(fScaledBitmap.getPixels());
+            fScaledBitmap.setImmutable();
+            SkBitmapCache::Add(fOrigBitmap, roundedDestWidth, roundedDestHeight, fScaledBitmap);
         }
 
-        SkASSERT(NULL != fScaledBitmap.getPixels());
+        SkASSERT(fScaledBitmap.getPixels());
         fBitmap = &fScaledBitmap;
 
         // set the inv matrix type to translate-only;
         fInvMatrix.setTranslate(fInvMatrix.getTranslateX() / fInvMatrix.getScaleX(),
                                 fInvMatrix.getTranslateY() / fInvMatrix.getScaleY());
 
-        // no need for any further filtering; we just did it!
-        fFilterLevel = SkPaint::kNone_FilterLevel;
-        unlocker.release();
+#ifndef SK_IGNORE_PROPER_FRACTIONAL_SCALING
+        // reintroduce any fractional scaling missed by our integral scale done above.
+
+       float fractionalScaleX = roundedDestWidth/trueDestWidth;
+       float fractionalScaleY = roundedDestHeight/trueDestHeight;
+
+       fInvMatrix.postScale(fractionalScaleX, fractionalScaleY);
+#endif
+        fAdjustedMatrix = true;
+
+        // Set our filter level to low -- the only post-filtering this
+        // image might require is some interpolation if the translation
+        // is fractional or if there's any remaining scaling to be done.
+        fFilterLevel = SkPaint::kLow_FilterLevel;
         return true;
     }
 
@@ -264,48 +252,9 @@
 
     SkASSERT(SkPaint::kMedium_FilterLevel == fFilterLevel);
 
-    /**
-     *  Medium quality means use a mipmap for down-scaling, and just bilper
-     *  for upscaling. Since we're examining the inverse matrix, we look for
-     *  a scale > 1 to indicate down scaling by the CTM.
-     */
-    if (scaleSqd > SK_Scalar1) {
-        const SkMipMap* mip = NULL;
-
-        SkASSERT(NULL == fScaledCacheID);
-        fScaledCacheID = SkScaledImageCache::FindAndLockMip(fOrigBitmap, &mip);
-        if (!fScaledCacheID) {
-            SkASSERT(NULL == mip);
-            mip = SkMipMap::Build(fOrigBitmap);
-            if (mip) {
-                fScaledCacheID = SkScaledImageCache::AddAndLockMip(fOrigBitmap,
-                                                                   mip);
-                SkASSERT(mip->getRefCnt() > 1);
-                mip->unref();   // the cache took a ref
-                SkASSERT(fScaledCacheID);
-            }
-        } else {
-            SkASSERT(mip);
-        }
-
-        if (mip) {
-            SkScalar levelScale = SkScalarInvert(SkScalarSqrt(scaleSqd));
-            SkMipMap::Level level;
-            if (mip->extractLevel(levelScale, &level)) {
-                SkScalar invScaleFixup = level.fScale;
-                fInvMatrix.postScale(invScaleFixup, invScaleFixup);
-
-                SkImageInfo info = fOrigBitmap.info();
-                info.fWidth = level.fWidth;
-                info.fHeight = level.fHeight;
-                fScaledBitmap.installPixels(info, level.fPixels, level.fRowBytes);
-                fBitmap = &fScaledBitmap;
-                fFilterLevel = SkPaint::kLow_FilterLevel;
-                unlocker.release();
-                return true;
-            }
-        }
-    }
+    // HACK: Disable use of mipmaps in M39 since they do not use discardable
+    // memory in the cache.
+    fFilterLevel = SkPaint::kLow_FilterLevel;
 
     return false;
 }
@@ -327,12 +276,8 @@
 }
 
 bool SkBitmapProcState::lockBaseBitmap() {
-    AutoScaledCacheUnlocker unlocker(&fScaledCacheID);
-
     SkPixelRef* pr = fOrigBitmap.pixelRef();
 
-    SkASSERT(NULL == fScaledCacheID);
-
     if (pr->isLocked() || !pr->implementsDecodeInto()) {
         // fast-case, no need to look in our cache
         fScaledBitmap = fOrigBitmap;
@@ -341,21 +286,7 @@
             return false;
         }
     } else {
-        fScaledCacheID = SkScaledImageCache::FindAndLock(fOrigBitmap,
-                                                         SK_Scalar1, SK_Scalar1,
-                                                         &fScaledBitmap);
-        if (fScaledCacheID) {
-            fScaledBitmap.lockPixels();
-            if (!fScaledBitmap.getPixels()) {
-                fScaledBitmap.unlockPixels();
-                // found a purged entry (discardablememory?), release it
-                SkScaledImageCache::Unlock(fScaledCacheID);
-                fScaledCacheID = NULL;
-                // fall through to rebuild
-            }
-        }
-
-        if (NULL == fScaledCacheID) {
+        if (!SkBitmapCache::Find(fOrigBitmap, 1, 1, &fScaledBitmap)) {
             if (!get_locked_pixels(fOrigBitmap, 0, &fScaledBitmap)) {
                 return false;
             }
@@ -363,24 +294,14 @@
             // TODO: if fScaled comes back at a different width/height than fOrig,
             // we need to update the matrix we are using to sample from this guy.
 
-            fScaledCacheID = SkScaledImageCache::AddAndLock(fOrigBitmap,
-                                                            SK_Scalar1, SK_Scalar1,
-                                                            fScaledBitmap);
-            if (!fScaledCacheID) {
-                fScaledBitmap.reset();
-                return false;
-            }
+            SkBitmapCache::Add(fOrigBitmap, 1, 1, fScaledBitmap);
         }
     }
     fBitmap = &fScaledBitmap;
-    unlocker.release();
     return true;
 }
 
 SkBitmapProcState::~SkBitmapProcState() {
-    if (fScaledCacheID) {
-        SkScaledImageCache::Unlock(fScaledCacheID);
-    }
     SkDELETE(fBitmapFilter);
 }
 
@@ -391,8 +312,6 @@
     fInvMatrix = inv;
     fFilterLevel = paint.getFilterLevel();
 
-    SkASSERT(NULL == fScaledCacheID);
-
     // possiblyScaleImage will look to see if it can rescale the image as a
     // preprocess; either by scaling up to the target size, or by selecting
     // a nearby mipmap level.  If it does, it will adjust the working
@@ -420,7 +339,7 @@
     bool clampClamp = SkShader::kClamp_TileMode == fTileModeX &&
                       SkShader::kClamp_TileMode == fTileModeY;
 
-    if (!(clampClamp || trivialMatrix)) {
+    if (!(fAdjustedMatrix || clampClamp || trivialMatrix)) {
         fInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height());
     }
 
@@ -501,6 +420,8 @@
 
     ///////////////////////////////////////////////////////////////////////
 
+    const SkAlphaType at = fBitmap->alphaType();
+
     // No need to do this if we're doing HQ sampling; if filter quality is
     // still set to HQ by the time we get here, then we must have installed
     // the shader procs above and can skip all this.
@@ -520,15 +441,24 @@
         // bits 3,4,5 encoding the source bitmap format
         switch (fBitmap->colorType()) {
             case kN32_SkColorType:
+                if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) {
+                    return false;
+                }
                 index |= 0;
                 break;
             case kRGB_565_SkColorType:
                 index |= 8;
                 break;
             case kIndex_8_SkColorType:
+                if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) {
+                    return false;
+                }
                 index |= 16;
                 break;
             case kARGB_4444_SkColorType:
+                if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) {
+                    return false;
+                }
                 index |= 24;
                 break;
             case kAlpha_8_SkColorType:
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h
index 663bcb8..ac4f1a4 100644
--- a/src/core/SkBitmapProcState.h
+++ b/src/core/SkBitmapProcState.h
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2007 The Android Open Source Project
  *
@@ -6,15 +5,14 @@
  * found in the LICENSE file.
  */
 
-
 #ifndef SkBitmapProcState_DEFINED
 #define SkBitmapProcState_DEFINED
 
 #include "SkBitmap.h"
 #include "SkBitmapFilter.h"
 #include "SkMatrix.h"
+#include "SkMipMap.h"
 #include "SkPaint.h"
-#include "SkScaledImageCache.h"
 
 #define FractionalInt_IS_64BIT
 
@@ -33,11 +31,10 @@
 #endif
 
 class SkPaint;
-struct SkConvolutionProcs;
 
 struct SkBitmapProcState {
 
-    SkBitmapProcState(): fScaledCacheID(NULL), fBitmapFilter(NULL) {}
+    SkBitmapProcState() : fBitmapFilter(NULL) {}
     ~SkBitmapProcState();
 
     typedef void (*ShaderProc32)(const SkBitmapProcState&, int x, int y,
@@ -104,12 +101,6 @@
      */
     void platformProcs();
 
-    /** Platforms can also optionally overwrite the convolution functions
-        if we have SIMD versions of them.
-      */
-
-    void platformConvolutionProcs(SkConvolutionProcs*);
-
     /** Given the byte size of the index buffer to be passed to the matrix proc,
         return the maximum number of resulting pixels that can be computed
         (i.e. the number of SkPMColor values to be written by the sample proc).
@@ -149,7 +140,8 @@
     SkBitmap            fOrigBitmap;        // CONSTRUCTOR
     SkBitmap            fScaledBitmap;      // chooseProcs
 
-    SkScaledImageCache::ID* fScaledCacheID;
+    SkAutoTUnref<const SkMipMap> fCurrMip;
+    bool                fAdjustedMatrix;    // set by possiblyScaleImage
 
     MatrixProc chooseMatrixProc(bool trivial_matrix);
     bool chooseProcs(const SkMatrix& inv, const SkPaint&);
diff --git a/src/core/SkBitmapProcState_matrixProcs.cpp b/src/core/SkBitmapProcState_matrixProcs.cpp
index 02204b6..851389c 100644
--- a/src/core/SkBitmapProcState_matrixProcs.cpp
+++ b/src/core/SkBitmapProcState_matrixProcs.cpp
@@ -477,8 +477,7 @@
 SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) {
 //    test_int_tileprocs();
     // check for our special case when there is no scale/affine/perspective
-    if (trivial_matrix) {
-        SkASSERT(SkPaint::kNone_FilterLevel == fFilterLevel);
+    if (trivial_matrix && SkPaint::kNone_FilterLevel == fFilterLevel) {
         fIntTileProcY = choose_int_tile_proc(fTileModeY);
         switch (fTileModeX) {
             case SkShader::kClamp_TileMode:
diff --git a/src/core/SkBitmapScaler.cpp b/src/core/SkBitmapScaler.cpp
index be32a89..3501ac8 100644
--- a/src/core/SkBitmapScaler.cpp
+++ b/src/core/SkBitmapScaler.cpp
@@ -246,9 +246,11 @@
                             const SkBitmap& source,
                             ResizeMethod method,
                             float destWidth, float destHeight,
-                            const SkConvolutionProcs& convolveProcs,
                             SkBitmap::Allocator* allocator) {
 
+  SkConvolutionProcs convolveProcs= { 0, NULL, NULL, NULL, NULL };
+  PlatformConvolutionProcs(&convolveProcs);
+
   SkRect destSubset = { 0, 0, destWidth, destHeight };
 
   // Ensure that the ResizeMethod enumeration is sound.
@@ -262,6 +264,7 @@
         SkErrorInternals::SetError( kInvalidArgument_SkError,
                                     "Sorry, the destination bitmap scale subset "
                                     "falls outside the full destination bitmap." );
+        return false;
     }
 
     // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just
@@ -312,6 +315,19 @@
 
     *resultPtr = result;
     resultPtr->lockPixels();
-    SkASSERT(NULL != resultPtr->getPixels());
+    SkASSERT(resultPtr->getPixels());
     return true;
 }
+
+// static -- simpler interface to the resizer; returns a default bitmap if scaling
+// fails for any reason.  This is the interface that Chrome expects.
+SkBitmap SkBitmapScaler::Resize(const SkBitmap& source,
+                                ResizeMethod method,
+                                float destWidth, float destHeight,
+                                SkBitmap::Allocator* allocator) {
+  SkBitmap result;
+  if (!Resize(&result, source, method, destWidth, destHeight, allocator)) {
+    return SkBitmap();
+  }
+  return result;
+}
diff --git a/src/core/SkBitmapScaler.h b/src/core/SkBitmapScaler.h
index d6636cf..ec4c817 100644
--- a/src/core/SkBitmapScaler.h
+++ b/src/core/SkBitmapScaler.h
@@ -83,8 +83,18 @@
                        const SkBitmap& source,
                        ResizeMethod method,
                        float dest_width, float dest_height,
-                       const SkConvolutionProcs&,
                        SkBitmap::Allocator* allocator = NULL);
+
+    static SkBitmap Resize(const SkBitmap& source,
+                           ResizeMethod method,
+                           float dest_width, float dest_height,
+                           SkBitmap::Allocator* allocator = NULL);
+
+     /** Platforms can also optionally overwrite the convolution functions
+        if we have SIMD versions of them.
+      */
+
+    static void PlatformConvolutionProcs(SkConvolutionProcs*);
 };
 
 #endif
diff --git a/src/core/SkBitmap_scroll.cpp b/src/core/SkBitmap_scroll.cpp
index 00a72aa..54158c2 100644
--- a/src/core/SkBitmap_scroll.cpp
+++ b/src/core/SkBitmap_scroll.cpp
@@ -15,7 +15,7 @@
         return false;
     }
 
-    if (NULL != subset) {
+    if (subset) {
         SkBitmap tmp;
 
         return  this->extractSubset(&tmp, *subset) &&
@@ -29,14 +29,14 @@
 
     // check if there's nothing to do
     if ((dx | dy) == 0 || width <= 0 || height <= 0) {
-        if (NULL != inval) {
+        if (inval) {
             inval->setEmpty();
         }
         return true;
     }
 
     // compute the inval region now, before we see if there are any pixels
-    if (NULL != inval) {
+    if (inval) {
         SkIRect r;
 
         r.set(0, 0, width, height);
diff --git a/src/core/SkBlitRow_D16.cpp b/src/core/SkBlitRow_D16.cpp
index 1b2be06..e052b35 100644
--- a/src/core/SkBlitRow_D16.cpp
+++ b/src/core/SkBlitRow_D16.cpp
@@ -74,11 +74,8 @@
             SkPMColorAssert(sc);
             if (sc) {
                 uint16_t dc = *dst;
-                unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha);
-                unsigned dr = SkMulS16(SkPacked32ToR16(sc), alpha) + SkMulS16(SkGetPackedR16(dc), dst_scale);
-                unsigned dg = SkMulS16(SkPacked32ToG16(sc), alpha) + SkMulS16(SkGetPackedG16(dc), dst_scale);
-                unsigned db = SkMulS16(SkPacked32ToB16(sc), alpha) + SkMulS16(SkGetPackedB16(dc), dst_scale);
-                *dst = SkPackRGB16(SkDiv255Round(dr), SkDiv255Round(dg), SkDiv255Round(db));
+                SkPMColor res = SkBlendARGB32(sc, SkPixel16ToPixel32(dc), alpha);
+                *dst = SkPixel32ToPixel16(res);
             }
             dst += 1;
         } while (--count != 0);
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index cb84ec7..f4669d5 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -620,7 +620,7 @@
             }
         }
 
-        void setMask(const SkMask* mask) { fMask = mask; }
+        virtual void set3DMask(const SkMask* mask) SK_OVERRIDE { fMask = mask; }
 
         virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE {
             if (fProxyContext) {
@@ -700,7 +700,7 @@
     virtual void toString(SkString* str) const SK_OVERRIDE {
         str->append("Sk3DShader: (");
 
-        if (NULL != fProxy) {
+        if (fProxy) {
             str->append("Proxy: ");
             fProxy->toString(str);
         }
@@ -714,19 +714,17 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) {
         fProxy = buffer.readShader();
         // Leaving this here until we bump the picture version, though this
         // shader should never be recorded.
         buffer.readColor();
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        this->INHERITED::flatten(buffer);
         buffer.writeFlattenable(fProxy);
-        // Leaving this here until we bump the picture version, though this
-        // shader should never be recorded.
-        buffer.writeColor(SkColor());
     }
 
 private:
@@ -735,11 +733,16 @@
     typedef SkShader INHERITED;
 };
 
+SkFlattenable* Sk3DShader::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkShader> shader(buffer.readShader());
+    return SkNEW_ARGS(Sk3DShader, (shader));
+}
+
 class Sk3DBlitter : public SkBlitter {
 public:
-    Sk3DBlitter(SkBlitter* proxy, Sk3DShader::Sk3DShaderContext* shaderContext)
+    Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext)
         : fProxy(proxy)
-        , f3DShaderContext(shaderContext)
+        , fShaderContext(shaderContext)
     {}
 
     virtual void blitH(int x, int y, int width) {
@@ -761,13 +764,13 @@
 
     virtual void blitMask(const SkMask& mask, const SkIRect& clip) {
         if (mask.fFormat == SkMask::k3D_Format) {
-            f3DShaderContext->setMask(&mask);
+            fShaderContext->set3DMask(&mask);
 
             ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
             fProxy->blitMask(mask, clip);
             ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
 
-            f3DShaderContext->setMask(NULL);
+            fShaderContext->set3DMask(NULL);
         } else {
             fProxy->blitMask(mask, clip);
         }
@@ -775,8 +778,8 @@
 
 private:
     // Both pointers are unowned. They will be deleted by SkSmallAllocator.
-    SkBlitter*                     fProxy;
-    Sk3DShader::Sk3DShaderContext* f3DShaderContext;
+    SkBlitter*          fProxy;
+    SkShader::Context*  fShaderContext;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -872,7 +875,7 @@
         shader = shader3D;
     }
 
-    if (NULL != mode) {
+    if (mode) {
         switch (interpret_xfermode(*paint, mode, device.colorType())) {
             case kSrcOver_XferInterp:
                 mode = NULL;
@@ -984,9 +987,9 @@
     if (shader3D) {
         SkBlitter* innerBlitter = blitter;
         // innerBlitter was allocated by allocator, which will delete it.
-        // We know shaderContext is of type Sk3DShaderContext because it belongs to shader3D.
-        blitter = allocator->createT<Sk3DBlitter>(innerBlitter,
-                static_cast<Sk3DShader::Sk3DShaderContext*>(shaderContext));
+        // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to
+        // wrapper the blitter to notify it when we see an emboss mask.
+        blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shaderContext);
     }
     return blitter;
 }
diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h
index a3a2196..e0e77cc 100644
--- a/src/core/SkBlitter.h
+++ b/src/core/SkBlitter.h
@@ -33,6 +33,7 @@
     /// zero-terminated run-length encoding of spans of constant alpha values.
     virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
                            const int16_t runs[]);
+
     /// Blit a vertical run of pixels with a constant alpha value.
     virtual void blitV(int x, int y, int height, SkAlpha alpha);
     /// Blit a solid rectangle one or more pixels wide.
@@ -67,6 +68,24 @@
     virtual bool resetShaderContext(const SkShader::ContextRec&);
     virtual SkShader::Context* getShaderContext() const;
 
+    /**
+     * Special methods for blitters that can blit more than one row at a time.
+     * This function returns the number of rows that this blitter could optimally
+     * process at a time. It is still required to support blitting one scanline
+     * at a time.
+     */
+    virtual int requestRowsPreserved() const { return 1; }
+
+    /**
+     * This function allocates memory for the blitter that the blitter then owns.
+     * The memory can be used by the calling function at will, but it will be
+     * released when the blitter's destructor is called. This function returns
+     * NULL if no persistent memory is needed by the blitter.
+     */
+    virtual void* allocBlitMemory(size_t sz) {
+        return fBlitMemory.reset(sz, SkAutoMalloc::kReuse_OnShrink);
+    }
+
     ///@name non-virtual helpers
     void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
     void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
@@ -89,6 +108,10 @@
                                    SkTBlitterAllocator*);
     ///@}
 
+protected:
+
+    SkAutoMalloc fBlitMemory;
+    
 private:
 };
 
@@ -128,6 +151,14 @@
     virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
     virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
 
+    virtual int requestRowsPreserved() const SK_OVERRIDE {
+        return fBlitter->requestRowsPreserved();
+    }
+
+    virtual void* allocBlitMemory(size_t sz) SK_OVERRIDE {
+        return fBlitter->allocBlitMemory(sz);
+    }
+
 private:
     SkBlitter*  fBlitter;
     SkIRect     fClipRect;
@@ -155,6 +186,14 @@
     virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
     virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
 
+    virtual int requestRowsPreserved() const SK_OVERRIDE {
+        return fBlitter->requestRowsPreserved();
+    }
+
+    virtual void* allocBlitMemory(size_t sz) SK_OVERRIDE {
+        return fBlitter->allocBlitMemory(sz);
+    }
+
 private:
     SkBlitter*      fBlitter;
     const SkRegion* fRgn;
diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp
index 4503a2a..8771c19 100644
--- a/src/core/SkBlitter_RGB16.cpp
+++ b/src/core/SkBlitter_RGB16.cpp
@@ -16,6 +16,12 @@
 #include "SkUtilsArm.h"
 #include "SkXfermode.h"
 
+#if SK_MIPS_HAS_DSP
+extern void blitmask_d565_opaque_mips(int width, int height, uint16_t* device,
+                                      unsigned deviceRB, const uint8_t* alpha,
+                                      uint32_t expanded32, unsigned maskRB);
+#endif
+
 #if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN)
     #include <arm_neon.h>
 #else
@@ -368,9 +374,11 @@
 #define SK_BLITBWMASK_DEVTYPE               uint16_t
 #include "SkBlitBWMaskTemplate.h"
 
+#if !defined(SK_MIPS_HAS_DSP)
 static U16CPU blend_compact(uint32_t src32, uint32_t dst32, unsigned scale5) {
     return SkCompact_rgb_16(dst32 + ((src32 - dst32) * scale5 >> 5));
 }
+#endif
 
 void SkRGB16_Opaque_Blitter::blitMask(const SkMask& mask,
                                       const SkIRect& clip) {
@@ -457,6 +465,8 @@
         alpha += maskRB;
     } while (--height != 0);
 #undef    UNROLL
+#elif SK_MIPS_HAS_DSP
+    blitmask_d565_opaque_mips(width, height, device, deviceRB, alpha, expanded32, maskRB);
 #else   // non-neon code
     do {
         int w = width;
@@ -1027,7 +1037,7 @@
     SkXfermode* mode = paint.getXfermode();
 
     // we require a shader if there is an xfermode, handled by our caller
-    SkASSERT(NULL == mode || NULL != shader);
+    SkASSERT(NULL == mode || shader);
 
     if (shader) {
         SkASSERT(shaderContext != NULL);
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index bdbcd3b..75c0b29 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -5,21 +5,24 @@
  * found in the LICENSE file.
  */
 
-
 #include "SkCanvas.h"
+#include "SkCanvasPriv.h"
 #include "SkBitmapDevice.h"
 #include "SkDeviceImageFilterProxy.h"
 #include "SkDraw.h"
 #include "SkDrawFilter.h"
 #include "SkDrawLooper.h"
+#include "SkImage.h"
 #include "SkMetaData.h"
 #include "SkPathOps.h"
+#include "SkPatchUtils.h"
 #include "SkPicture.h"
 #include "SkRasterClip.h"
 #include "SkRRect.h"
 #include "SkSmallAllocator.h"
 #include "SkSurface_Base.h"
 #include "SkTemplates.h"
+#include "SkTextBlob.h"
 #include "SkTextFormatParams.h"
 #include "SkTLazy.h"
 #include "SkUtils.h"
@@ -54,47 +57,6 @@
     #define dec_canvas()
 #endif
 
-#ifdef SK_DEBUG
-#include "SkPixelRef.h"
-
-/*
- *  Some pixelref subclasses can support being "locked" from another thread
- *  during the lock-scope of skia calling them. In these instances, this balance
- *  check will fail, but may not be indicative of a problem, so we allow a build
- *  flag to disable this check.
- *
- *  Potentially another fix would be to have a (debug-only) virtual or flag on
- *  pixelref, which could tell us at runtime if this check is valid. That would
- *  eliminate the need for this heavy-handed build check.
- */
-#ifdef SK_DISABLE_PIXELREF_LOCKCOUNT_BALANCE_CHECK
-class AutoCheckLockCountBalance {
-public:
-    AutoCheckLockCountBalance(const SkBitmap&) { /* do nothing */ }
-};
-#else
-class AutoCheckLockCountBalance {
-public:
-    AutoCheckLockCountBalance(const SkBitmap& bm) : fPixelRef(bm.pixelRef()) {
-        fLockCount = fPixelRef ? fPixelRef->getLockCount() : 0;
-    }
-    ~AutoCheckLockCountBalance() {
-        const int count = fPixelRef ? fPixelRef->getLockCount() : 0;
-        SkASSERT(count == fLockCount);
-    }
-
-private:
-    const SkPixelRef* fPixelRef;
-    int               fLockCount;
-};
-#endif
-
-#define CHECK_LOCKCOUNT_BALANCE(bitmap)  AutoCheckLockCountBalance clcb(bitmap)
-
-#else
-    #define CHECK_LOCKCOUNT_BALANCE(bitmap)
-#endif
-
 typedef SkTLazy<SkPaint> SkLazyPaint;
 
 void SkCanvas::predrawNotify() {
@@ -105,6 +67,19 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) {
+    const uint32_t propFlags = props.flags();
+    if (propFlags & SkSurfaceProps::kDisallowDither_Flag) {
+        flags &= ~SkPaint::kDither_Flag;
+    }
+    if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) {
+        flags &= ~SkPaint::kAntiAlias_Flag;
+    }
+    return flags;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 /*  This is the record we keep for each SkBaseDevice that the user installs.
     The clip/matrix/proc are fields that reflect the top of the save/restore
     stack. Whenever the canvas changes, it marks a dirty flag, and then before
@@ -119,8 +94,11 @@
     const SkMatrix*     fMatrix;
     SkPaint*            fPaint; // may be null (in the future)
 
-    DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas)
-            : fNext(NULL) {
+    DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas,
+             bool conservativeRasterClip)
+        : fNext(NULL)
+        , fClip(conservativeRasterClip)
+    {
         if (NULL != device) {
             device->ref();
             device->onAttachToCanvas(canvas);
@@ -130,7 +108,7 @@
     }
 
     ~DeviceCM() {
-        if (NULL != fDevice) {
+        if (fDevice) {
             fDevice->onDetachFromCanvas();
             fDevice->unref();
         }
@@ -189,12 +167,10 @@
 */
 class SkCanvas::MCRec {
 public:
-    int             fFlags;
-    SkMatrix*       fMatrix;        // points to either fMatrixStorage or prev MCRec
-    SkRasterClip*   fRasterClip;    // points to either fRegionStorage or prev MCRec
-    SkDrawFilter*   fFilter;        // the current filter (or null)
-
-    DeviceCM*   fLayer;
+    SkRasterClip    fRasterClip;
+    SkMatrix        fMatrix;
+    SkDrawFilter*   fFilter;    // the current filter (or null)
+    DeviceCM*       fLayer;
     /*  If there are any layers in the stack, this points to the top-most
         one that is at or below this level in the stack (so we know what
         bitmap/device to draw into from this level. This value is NOT
@@ -203,35 +179,20 @@
     */
     DeviceCM*   fTopLayer;
 
-    MCRec(const MCRec* prev, int flags) : fFlags(flags) {
-        if (NULL != prev) {
-            if (flags & SkCanvas::kMatrix_SaveFlag) {
-                fMatrixStorage = *prev->fMatrix;
-                fMatrix = &fMatrixStorage;
-            } else {
-                fMatrix = prev->fMatrix;
-            }
+    MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) {
+        fMatrix.reset();
+        fFilter     = NULL;
+        fLayer      = NULL;
+        fTopLayer   = NULL;
 
-            if (flags & SkCanvas::kClip_SaveFlag) {
-                fRasterClipStorage = *prev->fRasterClip;
-                fRasterClip = &fRasterClipStorage;
-            } else {
-                fRasterClip = prev->fRasterClip;
-            }
-
-            fFilter = prev->fFilter;
-            SkSafeRef(fFilter);
-
-            fTopLayer = prev->fTopLayer;
-        } else {   // no prev
-            fMatrixStorage.reset();
-
-            fMatrix     = &fMatrixStorage;
-            fRasterClip = &fRasterClipStorage;
-            fFilter     = NULL;
-            fTopLayer   = NULL;
-        }
+        // don't bother initializing fNext
+        inc_rec();
+    }
+    MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip) {
+        fMatrix = prev.fMatrix;
+        fFilter = SkSafeRef(prev.fFilter);
         fLayer = NULL;
+        fTopLayer = prev.fTopLayer;
 
         // don't bother initializing fNext
         inc_rec();
@@ -241,10 +202,6 @@
         SkDELETE(fLayer);
         dec_rec();
     }
-
-private:
-    SkMatrix        fMatrixStorage;
-    SkRasterClip    fRasterClipStorage;
 };
 
 class SkDrawIter : public SkDraw {
@@ -306,12 +263,12 @@
 
 class AutoDrawLooper {
 public:
-    AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint,
+    AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint,
                    bool skipLayerForImageFilter = false,
                    const SkRect* bounds = NULL) : fOrigPaint(paint) {
         fCanvas = canvas;
         fFilter = canvas->getDrawFilter();
-        fPaint = NULL;
+        fPaint = &fOrigPaint;
         fSaveCount = canvas->getSaveCount();
         fDoClearImageFilter = false;
         fDone = false;
@@ -336,6 +293,15 @@
             // can we be marked as simple?
             fIsSimple = !fFilter && !fDoClearImageFilter;
         }
+
+        uint32_t oldFlags = paint.getFlags();
+        fNewPaintFlags = filter_paint_flags(props, oldFlags);
+        if (fIsSimple && (fNewPaintFlags != oldFlags)) {
+            SkPaint* paint = fLazyPaint.set(fOrigPaint);
+            paint->setFlags(fNewPaintFlags);
+            fPaint = paint;
+            // if we're not simple, doNext() will take care of calling setFlags()
+        }
     }
 
     ~AutoDrawLooper() {
@@ -355,7 +321,6 @@
             return false;
         } else if (fIsSimple) {
             fDone = true;
-            fPaint = &fOrigPaint;
             return !fPaint->nothingToDraw();
         } else {
             return this->doNext(drawType);
@@ -369,6 +334,7 @@
     SkDrawFilter*   fFilter;
     const SkPaint*  fPaint;
     int             fSaveCount;
+    uint32_t        fNewPaintFlags;
     bool            fDoClearImageFilter;
     bool            fDone;
     bool            fIsSimple;
@@ -384,6 +350,7 @@
     SkASSERT(fLooperContext || fFilter || fDoClearImageFilter);
 
     SkPaint* paint = fLazyPaint.set(fOrigPaint);
+    paint->setFlags(fNewPaintFlags);
 
     if (fDoClearImageFilter) {
         paint->setImageFilter(NULL);
@@ -418,19 +385,17 @@
     return true;
 }
 
-#include "SkColorPriv.h"
-
 ////////// macros to place around the internal draw calls //////////////////
 
 #define LOOPER_BEGIN_DRAWDEVICE(paint, type)                        \
     this->predrawNotify();                                          \
-    AutoDrawLooper  looper(this, paint, true);                      \
+    AutoDrawLooper  looper(this, fProps, paint, true);              \
     while (looper.next(type)) {                                     \
         SkDrawIter          iter(this);
 
 #define LOOPER_BEGIN(paint, type, bounds)                           \
     this->predrawNotify();                                          \
-    AutoDrawLooper  looper(this, paint, false, bounds);             \
+    AutoDrawLooper  looper(this, fProps, paint, false, bounds);     \
     while (looper.next(type)) {                                     \
         SkDrawIter          iter(this);
 
@@ -438,59 +403,119 @@
 
 ////////////////////////////////////////////////////////////////////////////
 
-SkBaseDevice* SkCanvas::init(SkBaseDevice* device) {
+void SkCanvas::setupDevice(SkBaseDevice* device) {
+    device->setPixelGeometry(fProps.pixelGeometry());
+}
+
+SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
+    fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag);
     fCachedLocalClipBounds.setEmpty();
     fCachedLocalClipBoundsDirty = true;
     fAllowSoftClip = true;
     fAllowSimplifyClip = false;
-    fDeviceCMDirty = false;
+    fDeviceCMDirty = true;
     fSaveLayerCount = 0;
     fCullCount = 0;
     fMetaData = NULL;
 
     fMCRec = (MCRec*)fMCStack.push_back();
-    new (fMCRec) MCRec(NULL, 0);
+    new (fMCRec) MCRec(fConservativeRasterClip);
 
-    fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL));
+    fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL, fConservativeRasterClip));
     fMCRec->fTopLayer = fMCRec->fLayer;
 
     fSurfaceBase = NULL;
 
-    return this->setRootDevice(device);
+    if (device) {
+        this->setupDevice(device);
+        if (device->forceConservativeRasterClip()) {
+            fConservativeRasterClip = true;
+        }
+        device->onAttachToCanvas(this);
+        fMCRec->fLayer->fDevice = SkRef(device);
+        fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->height()));
+    }
+    return device;
 }
 
 SkCanvas::SkCanvas()
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+    , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
 {
     inc_canvas();
 
-    this->init(NULL);
+    this->init(NULL, kDefault_InitFlags);
 }
 
+static SkBitmap make_nopixels(int width, int height) {
+    SkBitmap bitmap;
+    bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
+    return bitmap;
+}
+
+class SkNoPixelsBitmapDevice : public SkBitmapDevice {
+public:
+    SkNoPixelsBitmapDevice(int width, int height) : INHERITED(make_nopixels(width, height)) {}
+
+private:
+
+    typedef SkBitmapDevice INHERITED;
+};
+
 SkCanvas::SkCanvas(int width, int height)
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+    , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
 {
     inc_canvas();
 
-    SkBitmap bitmap;
-    bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
-    this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)))->unref();
+    this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), kDefault_InitFlags)->unref();
+}
+
+SkCanvas::SkCanvas(int width, int height, InitFlags flags)
+    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+    , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
+{
+    inc_canvas();
+
+    this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref();
+}
+
+SkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags flags)
+    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+    , fProps(SkSurfacePropsCopyOrDefault(props))
+{
+    inc_canvas();
+
+    this->init(device, flags);
 }
 
 SkCanvas::SkCanvas(SkBaseDevice* device)
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+    , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
 {
     inc_canvas();
 
-    this->init(device);
+    this->init(device, kDefault_InitFlags);
+}
+
+SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
+    : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+    , fProps(props)
+{
+    inc_canvas();
+
+    SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
+    this->init(device, kDefault_InitFlags);
 }
 
 SkCanvas::SkCanvas(const SkBitmap& bitmap)
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+    , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
 {
     inc_canvas();
 
-    this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)))->unref();
+    SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
+    this->init(device, kDefault_InitFlags);
 }
 
 SkCanvas::~SkCanvas() {
@@ -581,6 +606,7 @@
 
     SkRefCnt_SafeAssign(rec->fLayer->fDevice, device);
     rootDevice = device;
+    this->setupDevice(device);
 
     fDeviceCMDirty = true;
 
@@ -605,9 +631,9 @@
         bounds.setEmpty();
     }
     // now jam our 1st clip to be bounds, and intersect the rest with that
-    rec->fRasterClip->setRect(bounds);
+    rec->fRasterClip.setRect(bounds);
     while ((rec = (MCRec*)iter.next()) != NULL) {
-        (void)rec->fRasterClip->op(bounds, SkRegion::kIntersect_Op);
+        (void)rec->fRasterClip.op(bounds, SkRegion::kIntersect_Op);
     }
 
     return device;
@@ -620,7 +646,7 @@
 
     bool weAllocated = false;
     if (NULL == bitmap->pixelRef()) {
-        if (!bitmap->allocPixels()) {
+        if (!bitmap->tryAllocPixels()) {
             return false;
         }
         weAllocated = true;
@@ -646,7 +672,7 @@
         return false;
     }
 
-    if (!bitmap->allocN32Pixels(r.width(), r.height())) {
+    if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) {
         // bitmap will already be reset.
         return false;
     }
@@ -683,10 +709,8 @@
         return false;
     }
 
-    SkImageInfo info = origInfo;
     // the intersect may have shrunk info's logical size
-    info.fWidth = srcR.width();
-    info.fHeight = srcR.height();
+    const SkImageInfo info = origInfo.makeWH(srcR.width(), srcR.height());
 
     // if x or y are negative, then we have to adjust pixels
     if (x > 0) {
@@ -738,10 +762,8 @@
         return false;
     }
 
-    SkImageInfo info = origInfo;
     // the intersect may have shrunk info's logical size
-    info.fWidth = target.width();
-    info.fHeight = target.height();
+    const SkImageInfo info = origInfo.makeWH(target.width(), target.height());
 
     // if x or y are negative, then we have to adjust pixels
     if (x > 0) {
@@ -753,6 +775,9 @@
     // here x,y are either 0 or negative
     pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel());
 
+    // Tell our owning surface to bump its generation ID
+    this->predrawNotify();
+
     // The device can assert that the requested area is always contained in its bounds
     return device->writePixels(info, pixels, rowBytes, target.x(), target.y());
 }
@@ -766,7 +791,7 @@
 void SkCanvas::updateDeviceCMCache() {
     if (fDeviceCMDirty) {
         const SkMatrix& totalMatrix = this->getTotalMatrix();
-        const SkRasterClip& totalClip = *fMCRec->fRasterClip;
+        const SkRasterClip& totalClip = fMCRec->fRasterClip;
         DeviceCM*       layer = fMCRec->fTopLayer;
 
         if (NULL == layer->fNext) {   // only one layer
@@ -783,30 +808,21 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-int SkCanvas::internalSave(SaveFlags flags) {
+int SkCanvas::internalSave() {
     int saveCount = this->getSaveCount(); // record this before the actual save
 
     MCRec* newTop = (MCRec*)fMCStack.push_back();
-    new (newTop) MCRec(fMCRec, flags);    // balanced in restore()
-
+    new (newTop) MCRec(*fMCRec);    // balanced in restore()
     fMCRec = newTop;
 
-    if (SkCanvas::kClip_SaveFlag & flags) {
-        fClipStack.save();
-    }
+    fClipStack.save();
 
     return saveCount;
 }
 
 int SkCanvas::save() {
-    this->willSave(kMatrixClip_SaveFlag);
-    return this->internalSave(kMatrixClip_SaveFlag);
-}
-
-int SkCanvas::save(SaveFlags flags) {
-    this->willSave(flags);
-    // call shared impl
-    return this->internalSave(flags);
+    this->willSave();
+    return this->internalSave();
 }
 
 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) {
@@ -826,12 +842,12 @@
     }
 
     if (imageFilter) {
-        imageFilter->filterBounds(clipBounds, *fMCRec->fMatrix, &clipBounds);
+        imageFilter->filterBounds(clipBounds, fMCRec->fMatrix, &clipBounds);
         // Filters may grow the bounds beyond the device bounds.
         op = SkRegion::kReplace_Op;
     }
     SkIRect ir;
-    if (NULL != bounds) {
+    if (bounds) {
         SkRect r;
 
         this->getTotalMatrix().mapRect(&r, *bounds);
@@ -839,7 +855,7 @@
         // early exit if the layer's bounds are clipped out
         if (!ir.intersect(clipBounds)) {
             if (bounds_affects_clip(flags)) {
-                fMCRec->fRasterClip->setEmpty();
+                fMCRec->fRasterClip.setEmpty();
             }
             return false;
         }
@@ -850,7 +866,7 @@
     if (bounds_affects_clip(flags)) {
         fClipStack.clipDevRect(ir, op);
         // early exit if the clip is now empty
-        if (!fMCRec->fRasterClip->op(ir, op)) {
+        if (!fMCRec->fRasterClip.op(ir, op)) {
             return false;
         }
     }
@@ -872,12 +888,6 @@
     return this->internalSaveLayer(bounds, paint, flags, false, strategy);
 }
 
-static SkBaseDevice* create_compatible_device(SkCanvas* canvas,
-                                              const SkImageInfo& info) {
-    SkBaseDevice* device = canvas->getDevice();
-    return device ? device->createCompatibleDevice(info) : NULL;
-}
-
 int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags,
                                 bool justForImageFilter, SaveLayerStrategy strategy) {
 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
@@ -886,7 +896,7 @@
 
     // do this before we create the layer. We don't call the public save() since
     // that would invoke a possibly overridden virtual
-    int count = this->internalSave(flags);
+    int count = this->internalSave();
 
     fDeviceCMDirty = true;
 
@@ -921,7 +931,10 @@
 
     SkBaseDevice* device;
     if (paint && paint->getImageFilter()) {
-        device = create_compatible_device(this, info);
+        device = this->getDevice();
+        if (device) {
+            device = device->createCompatibleDeviceForImageFilter(info);
+        }
     } else {
         device = this->createLayerDevice(info);
     }
@@ -929,9 +942,11 @@
         SkDebugf("Unable to create device for layer.");
         return count;
     }
+    this->setupDevice(device);
 
     device->setOrigin(ir.fLeft, ir.fTop);
-    DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint, this));
+    DeviceCM* layer = SkNEW_ARGS(DeviceCM,
+                                 (device, ir.fLeft, ir.fTop, paint, this, fConservativeRasterClip));
     device->unref();
 
     layer->fNext = fMCRec->fTopLayer;
@@ -962,6 +977,7 @@
     if (fMCStack.count() > 1) {
         this->willRestore();
         this->internalRestore();
+        this->didRestore();
     }
 }
 
@@ -971,9 +987,7 @@
     fDeviceCMDirty = true;
     fCachedLocalClipBoundsDirty = true;
 
-    if (SkCanvas::kClip_SaveFlag & fMCRec->fFlags) {
-        fClipStack.restore();
-    }
+    fClipStack.restore();
 
     // reserve our layer (if any)
     DeviceCM* layer = fMCRec->fLayer;   // may be null
@@ -989,7 +1003,7 @@
         since if we're being recorded, we don't want to record this (the
         recorder will have already recorded the restore).
     */
-    if (NULL != layer) {
+    if (layer) {
         if (layer->fNext) {
             const SkIPoint& origin = layer->fDevice->getOrigin();
             this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
@@ -1024,13 +1038,16 @@
     return fSaveLayerCount > 0;
 }
 
-SkSurface* SkCanvas::newSurface(const SkImageInfo& info) {
-    return this->onNewSurface(info);
+SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) {
+    if (NULL == props) {
+        props = &fProps;
+    }
+    return this->onNewSurface(info, *props);
 }
 
-SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info) {
+SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
     SkBaseDevice* dev = this->getDevice();
-    return dev ? dev->newSurface(info) : NULL;
+    return dev ? dev->newSurface(info, props) : NULL;
 }
 
 SkImageInfo SkCanvas::imageInfo() const {
@@ -1068,7 +1085,7 @@
     fAddr = canvas->peekPixels(&fInfo, &fRowBytes);
     if (NULL == fAddr) {
         fInfo = canvas->imageInfo();
-        if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.allocPixels(fInfo)) {
+        if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.tryAllocPixels(fInfo)) {
             return; // failure, fAddr is NULL
         }
         if (!canvas->readPixels(&fBitmap, 0, 0)) {
@@ -1165,7 +1182,6 @@
     }
 
     SkDEBUGCODE(bitmap.validate();)
-    CHECK_LOCKCOUNT_BALANCE(bitmap);
 
     SkRect storage;
     const SkRect* bounds = NULL;
@@ -1206,13 +1222,8 @@
             SkMatrix matrix = *iter.fMatrix;
             matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()));
             SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height());
-            SkImageFilter::Cache* cache = SkImageFilter::GetExternalCache();
-            SkAutoUnref aur(NULL);
-            if (!cache) {
-                cache = SkImageFilter::Cache::Create();
-                aur.reset(cache);
-            }
-            SkImageFilter::Context ctx(matrix, clipBounds, cache);
+            SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache());
+            SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
             if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) {
                 SkPaint tmpUnfiltered(*paint);
                 tmpUnfiltered.setImageFilter(NULL);
@@ -1232,7 +1243,6 @@
         return;
     }
     SkDEBUGCODE(bitmap.validate();)
-    CHECK_LOCKCOUNT_BALANCE(bitmap);
 
     SkPaint tmp;
     if (NULL == paint) {
@@ -1252,13 +1262,8 @@
             SkMatrix matrix = *iter.fMatrix;
             matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()));
             SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
-            SkImageFilter::Cache* cache = SkImageFilter::GetExternalCache();
-            SkAutoUnref aur(NULL);
-            if (!cache) {
-                cache = SkImageFilter::Cache::Create();
-                aur.reset(cache);
-            }
-            SkImageFilter::Context ctx(matrix, clipBounds, cache);
+            SkAutoTUnref<SkImageFilter::Cache> cache(iter.fDevice->getImageFilterCache());
+            SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
             if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) {
                 SkPaint tmpUnfiltered(*paint);
                 tmpUnfiltered.setImageFilter(NULL);
@@ -1304,7 +1309,7 @@
 
     fDeviceCMDirty = true;
     fCachedLocalClipBoundsDirty = true;
-    fMCRec->fMatrix->preConcat(matrix);
+    fMCRec->fMatrix.preConcat(matrix);
 
     this->didConcat(matrix);
 }
@@ -1312,7 +1317,7 @@
 void SkCanvas::setMatrix(const SkMatrix& matrix) {
     fDeviceCMDirty = true;
     fCachedLocalClipBoundsDirty = true;
-    *fMCRec->fMatrix = matrix;
+    fMCRec->fMatrix = matrix;
     this->didSetMatrix(matrix);
 }
 
@@ -1333,7 +1338,7 @@
 void SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
 #ifdef SK_ENABLE_CLIP_QUICKREJECT
     if (SkRegion::kIntersect_Op == op) {
-        if (fMCRec->fRasterClip->isEmpty()) {
+        if (fMCRec->fRasterClip.isEmpty()) {
             return false;
         }
 
@@ -1342,7 +1347,7 @@
             fCachedLocalClipBoundsDirty = true;
 
             fClipStack.clipEmpty();
-            return fMCRec->fRasterClip->setEmpty();
+            return fMCRec->fRasterClip.setEmpty();
         }
     }
 #endif
@@ -1355,16 +1360,16 @@
         edgeStyle = kHard_ClipEdgeStyle;
     }
 
-    if (fMCRec->fMatrix->rectStaysRect()) {
+    if (fMCRec->fMatrix.rectStaysRect()) {
         // for these simpler matrices, we can stay a rect even after applying
         // the matrix. This means we don't have to a) make a path, and b) tell
         // the region code to scan-convert the path, only to discover that it
         // is really just a rect.
         SkRect      r;
 
-        fMCRec->fMatrix->mapRect(&r, rect);
+        fMCRec->fMatrix.mapRect(&r, rect);
         fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle);
-        fMCRec->fRasterClip->op(r, op, kSoft_ClipEdgeStyle == edgeStyle);
+        fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeStyle == edgeStyle);
     } else {
         // since we're rotated or some such thing, we convert the rect to a path
         // and clip against that, since it can handle any matrix. However, to
@@ -1377,44 +1382,9 @@
     }
 }
 
-static void clip_path_helper(const SkCanvas* canvas, SkRasterClip* currClip,
-                             const SkPath& devPath, SkRegion::Op op, bool doAA) {
-    // base is used to limit the size (and therefore memory allocation) of the
-    // region that results from scan converting devPath.
-    SkRegion base;
-
-    if (SkRegion::kIntersect_Op == op) {
-        // since we are intersect, we can do better (tighter) with currRgn's
-        // bounds, than just using the device. However, if currRgn is complex,
-        // our region blitter may hork, so we do that case in two steps.
-        if (currClip->isRect()) {
-            // FIXME: we should also be able to do this when currClip->isBW(),
-            // but relaxing the test above triggers GM asserts in
-            // SkRgnBuilder::blitH(). We need to investigate what's going on.
-            currClip->setPath(devPath, currClip->bwRgn(), doAA);
-        } else {
-            base.setRect(currClip->getBounds());
-            SkRasterClip clip;
-            clip.setPath(devPath, base, doAA);
-            currClip->op(clip, op);
-        }
-    } else {
-        const SkBaseDevice* device = canvas->getDevice();
-        if (!device) {
-            currClip->setEmpty();
-            return;
-        }
-
-        base.setRect(0, 0, device->width(), device->height());
-
-        if (SkRegion::kReplace_Op == op) {
-            currClip->setPath(devPath, base, doAA);
-        } else {
-            SkRasterClip clip;
-            clip.setPath(devPath, base, doAA);
-            currClip->op(clip, op);
-        }
-    }
+static void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath,
+                            SkRegion::Op op, bool doAA) {
+    rc->op(devPath, canvas->getBaseLayerSize(), op, doAA);
 }
 
 void SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
@@ -1428,7 +1398,7 @@
 
 void SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
     SkRRect transformedRRect;
-    if (rrect.transform(*fMCRec->fMatrix, &transformedRRect)) {
+    if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) {
         AutoValidateClip avc(this);
 
         fDeviceCMDirty = true;
@@ -1442,7 +1412,7 @@
         SkPath devPath;
         devPath.addRRect(transformedRRect);
 
-        clip_path_helper(this, fMCRec->fRasterClip, devPath, op, kSoft_ClipEdgeStyle == edgeStyle);
+        rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeStyle == edgeStyle);
         return;
     }
 
@@ -1465,7 +1435,7 @@
 void SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
 #ifdef SK_ENABLE_CLIP_QUICKREJECT
     if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) {
-        if (fMCRec->fRasterClip->isEmpty()) {
+        if (fMCRec->fRasterClip.isEmpty()) {
             return false;
         }
 
@@ -1474,7 +1444,7 @@
             fCachedLocalClipBoundsDirty = true;
 
             fClipStack.clipEmpty();
-            return fMCRec->fRasterClip->setEmpty();
+            return fMCRec->fRasterClip.setEmpty();
         }
     }
 #endif
@@ -1488,7 +1458,7 @@
     }
 
     SkPath devPath;
-    path.transform(*fMCRec->fMatrix, &devPath);
+    path.transform(fMCRec->fMatrix, &devPath);
 
     // Check if the transfomation, or the original path itself
     // made us empty. Note this can also happen if we contained NaN
@@ -1531,83 +1501,7 @@
         op = SkRegion::kReplace_Op;
     }
 
-    clip_path_helper(this, fMCRec->fRasterClip, devPath, op, edgeStyle);
-}
-
-void SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegion::Op op,
-                                                   bool inverseFilled) {
-    // This is for updating the clip conservatively using only bounds
-    // information.
-    // Contract:
-    //    The current clip must contain the true clip. The true
-    //    clip is the clip that would have normally been computed
-    //    by calls to clipPath and clipRRect
-    // Objective:
-    //    Keep the current clip as small as possible without
-    //    breaking the contract, using only clip bounding rectangles
-    //    (for performance).
-
-    // N.B.: This *never* calls back through a virtual on canvas, so subclasses
-    // don't have to worry about getting caught in a loop. Thus anywhere
-    // we call a virtual method, we explicitly prefix it with
-    // SkCanvas:: to be sure to call the base-class.
-
-    if (inverseFilled) {
-        switch (op) {
-            case SkRegion::kIntersect_Op:
-            case SkRegion::kDifference_Op:
-                // These ops can only shrink the current clip. So leaving
-                // the clip unchanged conservatively respects the contract.
-                break;
-            case SkRegion::kUnion_Op:
-            case SkRegion::kReplace_Op:
-            case SkRegion::kReverseDifference_Op:
-            case SkRegion::kXOR_Op: {
-                    // These ops can grow the current clip up to the extents of
-                    // the input clip, which is inverse filled, so we just set
-                    // the current clip to the device bounds.
-                    SkRect deviceBounds;
-                    SkIRect deviceIBounds;
-                    this->getDevice()->getGlobalBounds(&deviceIBounds);
-                    deviceBounds = SkRect::Make(deviceIBounds);
-
-                    // set the clip in device space
-                    SkMatrix savedMatrix = this->getTotalMatrix();
-                    this->SkCanvas::setMatrix(SkMatrix::I());
-                    this->SkCanvas::onClipRect(deviceBounds, SkRegion::kReplace_Op,
-                                               kHard_ClipEdgeStyle);
-                    this->setMatrix(savedMatrix);
-                    break;
-            }
-            default:
-                SkASSERT(0); // unhandled op?
-        }
-    } else {
-        // Not inverse filled
-        switch (op) {
-            case SkRegion::kIntersect_Op:
-            case SkRegion::kUnion_Op:
-            case SkRegion::kReplace_Op:
-                this->SkCanvas::onClipRect(bounds, op, kHard_ClipEdgeStyle);
-                break;
-            case SkRegion::kDifference_Op:
-                // Difference can only shrink the current clip.
-                // Leaving clip unchanged conservatively fullfills the contract.
-                break;
-            case SkRegion::kReverseDifference_Op:
-                // To reverse, we swap in the bounds with a replace op.
-                // As with difference, leave it unchanged.
-                this->SkCanvas::onClipRect(bounds, SkRegion::kReplace_Op, kHard_ClipEdgeStyle);
-                break;
-            case SkRegion::kXOR_Op:
-                // Be conservative, based on (A XOR B) always included in (A union B),
-                // which is always included in (bounds(A) union bounds(B))
-                this->SkCanvas::onClipRect(bounds, SkRegion::kUnion_Op, kHard_ClipEdgeStyle);
-                break;
-            default:
-                SkASSERT(0); // unhandled op?
-        }
-    }
+    rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle);
 }
 
 void SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) {
@@ -1624,7 +1518,7 @@
     // we have to ignore it, and use the region directly?
     fClipStack.clipDevRect(rgn.getBounds(), op);
 
-    fMCRec->fRasterClip->op(rgn, op);
+    fMCRec->fRasterClip.op(rgn, op);
 }
 
 #ifdef SK_DEBUG
@@ -1638,7 +1532,7 @@
 
     SkIRect ir;
     ir.set(0, 0, device->width(), device->height());
-    SkRasterClip tmpClip(ir);
+    SkRasterClip tmpClip(ir, fConservativeRasterClip);
 
     SkClipStack::B2TIter                iter(fClipStack);
     const SkClipStack::Element* element;
@@ -1654,7 +1548,7 @@
             default: {
                 SkPath path;
                 element->asPath(&path);
-                clip_path_helper(this, &tmpClip, path, element->getOp(), element->isAA());
+                rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA());
                 break;
             }
         }
@@ -1674,28 +1568,27 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 bool SkCanvas::isClipEmpty() const {
-    return fMCRec->fRasterClip->isEmpty();
+    return fMCRec->fRasterClip.isEmpty();
 }
 
 bool SkCanvas::isClipRect() const {
-    return fMCRec->fRasterClip->isRect();
+    return fMCRec->fRasterClip.isRect();
 }
 
 bool SkCanvas::quickReject(const SkRect& rect) const {
-
     if (!rect.isFinite())
         return true;
 
-    if (fMCRec->fRasterClip->isEmpty()) {
+    if (fMCRec->fRasterClip.isEmpty()) {
         return true;
     }
 
-    if (fMCRec->fMatrix->hasPerspective()) {
+    if (fMCRec->fMatrix.hasPerspective()) {
         SkRect dst;
-        fMCRec->fMatrix->mapRect(&dst, rect);
+        fMCRec->fMatrix.mapRect(&dst, rect);
         SkIRect idst;
         dst.roundOut(&idst);
-        return !SkIRect::Intersects(idst, fMCRec->fRasterClip->getBounds());
+        return !SkIRect::Intersects(idst, fMCRec->fRasterClip.getBounds());
     } else {
         const SkRect& clipR = this->getLocalClipBounds();
 
@@ -1723,14 +1616,14 @@
 
     SkMatrix inverse;
     // if we can't invert the CTM, we can't return local clip bounds
-    if (!fMCRec->fMatrix->invert(&inverse)) {
+    if (!fMCRec->fMatrix.invert(&inverse)) {
         if (bounds) {
             bounds->setEmpty();
         }
         return false;
     }
 
-    if (NULL != bounds) {
+    if (bounds) {
         SkRect r;
         // adjust it outwards in case we are antialiasing
         const int inset = 1;
@@ -1743,7 +1636,7 @@
 }
 
 bool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const {
-    const SkRasterClip& clip = *fMCRec->fRasterClip;
+    const SkRasterClip& clip = fMCRec->fRasterClip;
     if (clip.isEmpty()) {
         if (bounds) {
             bounds->setEmpty();
@@ -1751,46 +1644,18 @@
         return false;
     }
 
-    if (NULL != bounds) {
+    if (bounds) {
         *bounds = clip.getBounds();
     }
     return true;
 }
 
 const SkMatrix& SkCanvas::getTotalMatrix() const {
-    return *fMCRec->fMatrix;
+    return fMCRec->fMatrix;
 }
 
-#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE
-SkCanvas::ClipType SkCanvas::getClipType() const {
-    if (fMCRec->fRasterClip->isEmpty()) {
-        return kEmpty_ClipType;
-    }
-    if (fMCRec->fRasterClip->isRect()) {
-        return kRect_ClipType;
-    }
-    return kComplex_ClipType;
-}
-#endif
-
-#ifdef SK_SUPPORT_LEGACY_GETTOTALCLIP
-const SkRegion& SkCanvas::getTotalClip() const {
-    return fMCRec->fRasterClip->forceGetBW();
-}
-#endif
-
 const SkRegion& SkCanvas::internal_private_getTotalClip() const {
-    return fMCRec->fRasterClip->forceGetBW();
-}
-
-void SkCanvas::internal_private_getTotalClipAsPath(SkPath* path) const {
-    path->reset();
-
-    const SkRegion& rgn = fMCRec->fRasterClip->forceGetBW();
-    if (rgn.isEmpty()) {
-        return;
-    }
-    (void)rgn.getBoundaryPath(path);
+    return fMCRec->fRasterClip.forceGetBW();
 }
 
 GrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() {
@@ -1806,9 +1671,9 @@
 GrContext* SkCanvas::getGrContext() {
 #if SK_SUPPORT_GPU
     SkBaseDevice* device = this->getTopDevice();
-    if (NULL != device) {
+    if (device) {
         GrRenderTarget* renderTarget = device->accessRenderTarget();
-        if (NULL != renderTarget) {
+        if (renderTarget) {
             return renderTarget->getContext();
         }
     }
@@ -1851,7 +1716,7 @@
 }
 
 void SkCanvas::onDiscard() {
-    if (NULL != fSurfaceBase) {
+    if (fSurfaceBase) {
         fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode);
     }
 }
@@ -2021,6 +1886,17 @@
     LOOPER_END
 }
 
+void SkCanvas::drawImage(const SkImage* image, SkScalar left, SkScalar top,
+                       const SkPaint* paint) {
+    image->draw(this, left, top, paint);
+}
+
+void SkCanvas::drawImageRect(const SkImage* image, const SkRect* src,
+                           const SkRect& dst,
+                           const SkPaint* paint) {
+    image->draw(this, src, dst, paint);
+}
+
 void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
                           const SkPaint* paint) {
     SkDEBUGCODE(bitmap.validate();)
@@ -2052,8 +1928,6 @@
         return;
     }
 
-    CHECK_LOCKCOUNT_BALANCE(bitmap);
-
     SkRect storage;
     const SkRect* bounds = &dst;
     if (NULL == paint || paint->canComputeFastBounds()) {
@@ -2177,7 +2051,6 @@
         if (device->filterTextFlags(paint, &flags)) {
             SkPaint* newPaint = fLazy.set(paint);
             newPaint->setFlags(flags.fFlags);
-            newPaint->setHinting(flags.fHinting);
             fPaint = newPaint;
         } else {
             fPaint = &paint;
@@ -2315,6 +2188,29 @@
     LOOPER_END
 }
 
+void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                              const SkPaint& paint) {
+
+    // FIXME: temporarily disable quickreject for empty bounds,
+    // pending implicit blob bounds implementation.
+    if (!blob->bounds().isEmpty() && paint.canComputeFastBounds()) {
+        SkRect storage;
+
+        if (this->quickReject(paint.computeFastBounds(blob->bounds().makeOffset(x, y), &storage))) {
+            return;
+        }
+    }
+
+    LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
+
+    while (iter.next()) {
+        SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
+        iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint());
+    }
+
+    LOOPER_END
+}
+
 // These will become non-virtual, so they always call the (virtual) onDraw... method
 void SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
                         const SkPaint& paint) {
@@ -2332,6 +2228,12 @@
                               const SkMatrix* matrix, const SkPaint& paint) {
     this->onDrawTextOnPath(text, byteLength, path, matrix, paint);
 }
+void SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                            const SkPaint& paint) {
+    if (blob) {
+        this->onDrawTextBlob(blob, x, y, paint);
+    }
+}
 
 void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
                             const SkPoint verts[], const SkPoint texs[],
@@ -2349,6 +2251,35 @@
     LOOPER_END
 }
 
+void SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                         const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
+    if (NULL == cubics) {
+        return;
+    }
+
+    // Since a patch is always within the convex hull of the control points, we discard it when its
+    // bounding rectangle is completely outside the current clip.
+    SkRect bounds;
+    bounds.set(cubics, SkPatchUtils::kNumCtrlPts);
+    if (this->quickReject(bounds)) {
+        return;
+    }
+
+    this->onDrawPatch(cubics, colors, texCoords, xmode, paint);
+}
+
+void SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                           const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
+
+    LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL)
+
+    while (iter.next()) {
+        iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint);
+    }
+
+    LOOPER_END
+}
+
 //////////////////////////////////////////////////////////////////////////////
 // These methods are NOT virtual, and therefore must call back into virtual
 // methods, rather than actually drawing themselves.
@@ -2467,37 +2398,40 @@
 ///////////////////////////////////////////////////////////////////////////////
 void SkCanvas::EXPERIMENTAL_optimize(const SkPicture* picture) {
     SkBaseDevice* device = this->getDevice();
-    if (NULL != device) {
+    if (device) {
         device->EXPERIMENTAL_optimize(picture);
     }
 }
 
-void SkCanvas::EXPERIMENTAL_purge(const SkPicture* picture) {
-    SkBaseDevice* device = this->getTopDevice();
-    if (NULL != device) {
-        device->EXPERIMENTAL_purge(picture);
-    }
-}
-
 void SkCanvas::drawPicture(const SkPicture* picture) {
-    if (NULL != picture) {
-        this->onDrawPicture(picture);
+    if (picture) {
+        this->onDrawPicture(picture, NULL, NULL);
     }
 }
 
-void SkCanvas::onDrawPicture(const SkPicture* picture) {
-    SkASSERT(NULL != picture);
+void SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) {
+    if (picture) {
+        if (matrix && matrix->isIdentity()) {
+            matrix = NULL;
+        }
+        this->onDrawPicture(picture, matrix, paint);
+    }
+}
 
+void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                             const SkPaint* paint) {
     SkBaseDevice* device = this->getTopDevice();
-    if (NULL != device) {
+    if (device) {
         // Canvas has to first give the device the opportunity to render
         // the picture itself.
-        if (device->EXPERIMENTAL_drawPicture(this, picture)) {
+        if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) {
             return; // the device has rendered the entire picture
         }
     }
 
-    picture->draw(this);
+    SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
+
+    picture->playback(this);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2573,7 +2507,7 @@
     }
 
     SkBitmap bitmap;
-    if (!bitmap.allocPixels(info)) {
+    if (!bitmap.tryAllocPixels(info)) {
         return NULL;
     }
 
@@ -2595,3 +2529,29 @@
     }
     return SkNEW_ARGS(SkCanvas, (bitmap));
 }
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix,
+                                                 const SkPaint* paint, const SkRect& bounds)
+    : fCanvas(canvas)
+    , fSaveCount(canvas->getSaveCount())
+{
+    if (paint) {
+        SkRect newBounds = bounds;
+        if (matrix) {
+            matrix->mapRect(&newBounds);
+        }
+        canvas->saveLayer(&newBounds, paint);
+    } else if (matrix) {
+        canvas->save();
+    }
+
+    if (matrix) {
+        canvas->concat(*matrix);
+    }
+}
+
+SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
+    fCanvas->restoreToCount(fSaveCount);
+}
diff --git a/src/core/SkCanvasPriv.h b/src/core/SkCanvasPriv.h
new file mode 100644
index 0000000..dfae154
--- /dev/null
+++ b/src/core/SkCanvasPriv.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkCanvasPriv_DEFINED
+#define SkCanvasPriv_DEFINED
+
+#include "SkCanvas.h"
+
+class SkAutoCanvasMatrixPaint : SkNoncopyable {
+public:
+    SkAutoCanvasMatrixPaint(SkCanvas*, const SkMatrix*, const SkPaint*, const SkRect& bounds);
+    ~SkAutoCanvasMatrixPaint();
+
+private:
+    SkCanvas*   fCanvas;
+    int         fSaveCount;
+};
+
+#endif
diff --git a/include/core/SkChecksum.h b/src/core/SkChecksum.h
similarity index 77%
rename from include/core/SkChecksum.h
rename to src/core/SkChecksum.h
index bf3228f..9f2ebf4 100644
--- a/include/core/SkChecksum.h
+++ b/src/core/SkChecksum.h
@@ -36,6 +36,20 @@
     }
 
 public:
+    /**
+     * uint32_t -> uint32_t hash, useful for when you're about to trucate this hash but you
+     * suspect its low bits aren't well mixed.
+     *
+     * This is the Murmur3 finalizer.
+     */
+    static uint32_t Mix(uint32_t hash) {
+        hash ^= hash >> 16;
+        hash *= 0x85ebca6b;
+        hash ^= hash >> 13;
+        hash *= 0xc2b2ae35;
+        hash ^= hash >> 16;
+        return hash;
+    }
 
     /**
      * Calculate 32-bit Murmur hash (murmur3).
@@ -48,12 +62,18 @@
      *  @return hash result
      */
     static uint32_t Murmur3(const uint32_t* data, size_t bytes, uint32_t seed=0) {
-        SkASSERT(SkIsAlign4(bytes));
+        // Use may_alias to remind the compiler we're intentionally violating strict aliasing,
+        // and so not to apply strict-aliasing-based optimizations.
+        typedef uint32_t SK_ATTRIBUTE(may_alias) aliased_uint32_t;
+        const aliased_uint32_t* safe_data = (const aliased_uint32_t*)data;
+
+        SkASSERTF(SkIsAlign4(bytes), "Expected 4-byte multiple, got %zu", bytes);
         const size_t words = bytes/4;
 
+
         uint32_t hash = seed;
         for (size_t i = 0; i < words; i++) {
-            uint32_t k = data[i];
+            uint32_t k = safe_data[i];
             k *= 0xcc9e2d51;
             k = (k << 15) | (k >> 17);
             k *= 0x1b873593;
@@ -64,12 +84,7 @@
             hash += 0xe6546b64;
         }
         hash ^= bytes;
-        hash ^= hash >> 16;
-        hash *= 0x85ebca6b;
-        hash ^= hash >> 13;
-        hash *= 0xc2b2ae35;
-        hash ^= hash >> 16;
-        return hash;
+        return Mix(hash);
     }
 
     /**
@@ -86,6 +101,11 @@
      *  @return checksum result
      */
     static uint32_t Compute(const uint32_t* data, size_t size) {
+        // Use may_alias to remind the compiler we're intentionally violating strict aliasing,
+        // and so not to apply strict-aliasing-based optimizations.
+        typedef uint32_t SK_ATTRIBUTE(may_alias) aliased_uint32_t;
+        const aliased_uint32_t* safe_data = (const aliased_uint32_t*)data;
+
         SkASSERT(SkIsAlign4(size));
 
         /*
@@ -95,7 +115,7 @@
          *  sizeof()).
          */
         uintptr_t result = 0;
-        const uintptr_t* ptr = reinterpret_cast<const uintptr_t*>(data);
+        const uintptr_t* ptr = reinterpret_cast<const uintptr_t*>(safe_data);
 
         /*
          *  count the number of quad element chunks. This takes into account
@@ -111,10 +131,10 @@
         }
         size &= ((sizeof(uintptr_t) << 2) - 1);
 
-        data = reinterpret_cast<const uint32_t*>(ptr);
-        const uint32_t* stop = data + (size >> 2);
-        while (data < stop) {
-            result = Mash(result, *data++);
+        safe_data = reinterpret_cast<const aliased_uint32_t*>(ptr);
+        const aliased_uint32_t* stop = safe_data + (size >> 2);
+        while (safe_data < stop) {
+            result = Mash(result, *safe_data++);
         }
 
         /*
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index a965b1b..cf2e71e 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -597,7 +597,7 @@
 void SkClipStack::getBounds(SkRect* canvFiniteBound,
                             BoundsType* boundType,
                             bool* isIntersectionOfRects) const {
-    SkASSERT(NULL != canvFiniteBound && NULL != boundType);
+    SkASSERT(canvFiniteBound && boundType);
 
     Element* element = (Element*)fDeque.back();
 
@@ -605,7 +605,7 @@
         // the clip is wide open - the infinite plane w/ no pixels un-writeable
         canvFiniteBound->setEmpty();
         *boundType = kInsideOut_BoundsType;
-        if (NULL != isIntersectionOfRects) {
+        if (isIntersectionOfRects) {
             *isIntersectionOfRects = false;
         }
         return;
@@ -613,13 +613,13 @@
 
     *canvFiniteBound = element->fFiniteBound;
     *boundType = element->fFiniteBoundType;
-    if (NULL != isIntersectionOfRects) {
+    if (isIntersectionOfRects) {
         *isIntersectionOfRects = element->fIsIntersectionOfRects;
     }
 }
 
 bool SkClipStack::intersectRectWithClip(SkRect* rect) const {
-    SkASSERT(NULL != rect);
+    SkASSERT(rect);
 
     SkRect bounds;
     SkClipStack::BoundsType bt;
@@ -667,7 +667,7 @@
     SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart);
     Element* prior = (Element*) iter.prev();
 
-    if (NULL != prior) {
+    if (prior) {
         if (prior->canBeIntersectedInPlace(fSaveCount, element.getOp())) {
             switch (prior->fType) {
                 case Element::kEmpty_Type:
@@ -766,7 +766,7 @@
     const SkClipStack::Element* element = NULL;
 
     for (element = (const SkClipStack::Element*) fIter.prev();
-         NULL != element;
+         element;
          element = (const SkClipStack::Element*) fIter.prev()) {
 
         if (op == element->fOp) {
@@ -806,7 +806,7 @@
                                         int maxHeight,
                                         SkRect* devBounds,
                                         bool* isIntersectionOfRects) const {
-    SkASSERT(NULL != devBounds);
+    SkASSERT(devBounds);
 
     devBounds->setLTRB(0, 0,
                        SkIntToScalar(maxWidth), SkIntToScalar(maxHeight));
@@ -891,7 +891,7 @@
             SkDebugf("\n");
             break;
         case kPath_Type:
-            this->getPath().dump(true);
+            this->getPath().dump(NULL, true, false);
             break;
     }
 }
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index 8cf9fc0..aadb29c 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -40,6 +40,6 @@
     return SkUnPreMultiply::PMColorToColor(dst);
 }
 
-GrEffectRef* SkColorFilter::asNewEffect(GrContext*) const {
+GrFragmentProcessor* SkColorFilter::asFragmentProcessor(GrContext*) const {
     return NULL;
 }
diff --git a/src/core/SkColorTable.cpp b/src/core/SkColorTable.cpp
index b8e7b05..4d0a795 100644
--- a/src/core/SkColorTable.cpp
+++ b/src/core/SkColorTable.cpp
@@ -31,7 +31,7 @@
 SkColorTable::SkColorTable(const SkPMColor colors[], int count, SkAlphaType at)
     : f16BitCache(NULL), fAlphaType(SkToU8(at))
 {
-    SkASSERT(0 == count || NULL != colors);
+    SkASSERT(0 == count || colors);
 
     if (count < 0) {
         count = 0;
diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp
index f7de73b..3c5b55a 100644
--- a/src/core/SkComposeShader.cpp
+++ b/src/core/SkComposeShader.cpp
@@ -26,8 +26,8 @@
     SkSafeRef(mode);
 }
 
-SkComposeShader::SkComposeShader(SkReadBuffer& buffer) :
-    INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkComposeShader::SkComposeShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     fShaderA = buffer.readShader();
     if (NULL == fShaderA) {
         fShaderA = SkNEW_ARGS(SkColorShader, ((SkColor)0));
@@ -38,6 +38,7 @@
     }
     fMode = buffer.readXfermode();
 }
+#endif
 
 SkComposeShader::~SkComposeShader() {
     SkSafeUnref(fMode);
@@ -66,8 +67,17 @@
 };
 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore)
 
+SkFlattenable* SkComposeShader::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkShader> shaderA(buffer.readShader());
+    SkAutoTUnref<SkShader> shaderB(buffer.readShader());
+    SkAutoTUnref<SkXfermode> mode(buffer.readXfermode());
+    if (!shaderA.get() || !shaderB.get()) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkComposeShader, (shaderA, shaderB, mode));
+}
+
 void SkComposeShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeFlattenable(fShaderA);
     buffer.writeFlattenable(fShaderB);
     buffer.writeFlattenable(fMode);
diff --git a/src/core/SkConvolver.cpp b/src/core/SkConvolver.cpp
index 0f5cf90..49688db 100644
--- a/src/core/SkConvolver.cpp
+++ b/src/core/SkConvolver.cpp
@@ -158,6 +158,34 @@
         }
     }
 
+    // There's a bug somewhere here with GCC autovectorization (-ftree-vectorize).  We originally
+    // thought this was 32 bit only, but subsequent tests show that some 64 bit gcc compiles
+    // suffer here too.
+    //
+    // Dropping to -O2 disables -ftree-vectorize.  GCC 4.6 needs noinline.  http://skbug.com/2575
+    #if SK_HAS_ATTRIBUTE(optimize) && defined(SK_RELEASE)
+        #define SK_MAYBE_DISABLE_VECTORIZATION __attribute__((optimize("O2"), noinline))
+    #else
+        #define SK_MAYBE_DISABLE_VECTORIZATION
+    #endif
+
+    SK_MAYBE_DISABLE_VECTORIZATION
+    static void ConvolveHorizontallyAlpha(const unsigned char* srcData,
+                                          const SkConvolutionFilter1D& filter,
+                                          unsigned char* outRow) {
+        return ConvolveHorizontally<true>(srcData, filter, outRow);
+    }
+
+    SK_MAYBE_DISABLE_VECTORIZATION
+    static void ConvolveHorizontallyNoAlpha(const unsigned char* srcData,
+                                            const SkConvolutionFilter1D& filter,
+                                            unsigned char* outRow) {
+        return ConvolveHorizontally<false>(srcData, filter, outRow);
+    }
+
+    #undef SK_MAYBE_DISABLE_VECTORIZATION
+
+
 // Does vertical convolution to produce one output row. The filter values and
 // length are given in the first two parameters. These are applied to each
 // of the rows pointed to in the |sourceDataRows| array, with each row
@@ -420,11 +448,11 @@
                         filterX, rowBuffer.advanceRow(), sourceHasAlpha);
                 } else {
                     if (sourceHasAlpha) {
-                        ConvolveHorizontally<true>(
+                        ConvolveHorizontallyAlpha(
                             &sourceData[(uint64_t)nextXRow * sourceByteRowStride],
                             filterX, rowBuffer.advanceRow());
                     } else {
-                        ConvolveHorizontally<false>(
+                        ConvolveHorizontallyNoAlpha(
                             &sourceData[(uint64_t)nextXRow * sourceByteRowStride],
                             filterX, rowBuffer.advanceRow());
                     }
diff --git a/src/core/SkData.cpp b/src/core/SkData.cpp
index c653287..11cab7e 100644
--- a/src/core/SkData.cpp
+++ b/src/core/SkData.cpp
@@ -9,21 +9,52 @@
 #include "SkLazyPtr.h"
 #include "SkOSFile.h"
 #include "SkReadBuffer.h"
+#include "SkStream.h"
 #include "SkWriteBuffer.h"
 
+static void sk_inplace_sentinel_releaseproc(const void*, size_t, void*) {
+    // we should never get called, as we are just a sentinel
+    sk_throw();
+}
+
 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
-    fPtr = ptr;
+    fPtr = const_cast<void*>(ptr);
     fSize = size;
     fReleaseProc = proc;
     fReleaseProcContext = context;
 }
 
+// This constructor means we are inline with our fPtr's contents. Thus we set fPtr
+// to point right after this. We also set our releaseproc to sk_inplace_sentinel_releaseproc,
+// since we need to handle "delete" ourselves. See internal_displose().
+//
+SkData::SkData(size_t size) {
+    fPtr = (char*)(this + 1);   // contents are immediately after this
+    fSize = size;
+    fReleaseProc = sk_inplace_sentinel_releaseproc;
+    fReleaseProcContext = NULL;
+}
+
 SkData::~SkData() {
     if (fReleaseProc) {
         fReleaseProc(fPtr, fSize, fReleaseProcContext);
     }
 }
 
+void SkData::internal_dispose() const {
+    if (sk_inplace_sentinel_releaseproc == fReleaseProc) {
+        const_cast<SkData*>(this)->fReleaseProc = NULL;    // so we don't call it in our destructor
+
+        this->internal_dispose_restore_refcnt_to_1();
+        this->~SkData();        // explicitly call this for refcnt bookkeeping
+
+        sk_free(const_cast<SkData*>(this));
+    } else {
+        this->internal_dispose_restore_refcnt_to_1();
+        SkDELETE(this);
+    }
+}
+
 bool SkData::equals(const SkData* other) const {
     if (NULL == other) {
         return false;
@@ -47,11 +78,24 @@
     return length;
 }
 
+SkData* SkData::PrivateNewWithCopy(const void* srcOrNull, size_t length) {
+    if (0 == length) {
+        return SkData::NewEmpty();
+    }
+    char* storage = (char*)sk_malloc_throw(sizeof(SkData) + length);
+    SkData* data = new (storage) SkData(length);
+    if (srcOrNull) {
+        memcpy(data->writable_data(), srcOrNull, length);
+    }
+    return data;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 SkData* SkData::NewEmptyImpl() {
     return new SkData(NULL, 0, NULL, NULL);
 }
+
 void SkData::DeleteEmpty(SkData* ptr) { SkDELETE(ptr); }
 
 SkData* SkData::NewEmpty() {
@@ -68,14 +112,13 @@
     return new SkData(data, length, sk_free_releaseproc, NULL);
 }
 
-SkData* SkData::NewWithCopy(const void* data, size_t length) {
-    if (0 == length) {
-        return SkData::NewEmpty();
-    }
+SkData* SkData::NewWithCopy(const void* src, size_t length) {
+    SkASSERT(src);
+    return PrivateNewWithCopy(src, length);
+}
 
-    void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc
-    memcpy(copy, data, length);
-    return new SkData(copy, length, sk_free_releaseproc, NULL);
+SkData* SkData::NewUninitialized(size_t length) {
+    return PrivateNewWithCopy(NULL, length);
 }
 
 SkData* SkData::NewWithProc(const void* data, size_t length,
@@ -156,3 +199,14 @@
     }
     return NewWithCopy(cstr, size);
 }
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkData* SkData::NewFromStream(SkStream* stream, size_t size) {
+    SkAutoDataUnref data(SkData::NewUninitialized(size));
+    if (stream->read(data->writable_data(), size) != size) {
+        return NULL;
+    }
+    return data.detach();
+}
+
diff --git a/src/core/SkDeque.cpp b/src/core/SkDeque.cpp
index d210dcf..27f3efc 100644
--- a/src/core/SkDeque.cpp
+++ b/src/core/SkDeque.cpp
@@ -100,7 +100,7 @@
         SkASSERT(NULL == fBack);
         fFront = fBack = begin;
     } else {
-        SkASSERT(NULL != fBack);
+        SkASSERT(fBack);
         fFront = begin;
     }
 
@@ -141,7 +141,7 @@
         SkASSERT(NULL == fFront);
         fFront = fBack = end;
     } else {
-        SkASSERT(NULL != fFront);
+        SkASSERT(fFront);
         fBack = end;
     }
 
@@ -169,14 +169,14 @@
 
     if (begin < fFrontBlock->fEnd) {
         first->fBegin = begin;
-        SkASSERT(NULL != first->fBegin);
+        SkASSERT(first->fBegin);
         fFront = first->fBegin;
     } else {
         first->fBegin = first->fEnd = NULL;  // mark as empty
         if (NULL == first->fNext) {
             fFront = fBack = NULL;
         } else {
-            SkASSERT(NULL != first->fNext->fBegin);
+            SkASSERT(first->fNext->fBegin);
             fFront = first->fNext->fBegin;
         }
     }
@@ -203,14 +203,14 @@
 
     if (end > last->fBegin) {
         last->fEnd = end;
-        SkASSERT(NULL != last->fEnd);
+        SkASSERT(last->fEnd);
         fBack = last->fEnd - fElemSize;
     } else {
         last->fBegin = last->fEnd = NULL;    // mark as empty
         if (NULL == last->fPrev) {
             fFront = fBack = NULL;
         } else {
-            SkASSERT(NULL != last->fPrev->fEnd);
+            SkASSERT(last->fPrev->fEnd);
             fBack = last->fPrev->fEnd - fElemSize;
         }
     }
@@ -293,14 +293,14 @@
     if (kFront_IterStart == startLoc) {
         // initialize the iterator to start at the front
         fCurBlock = d.fFrontBlock;
-        while (NULL != fCurBlock && NULL == fCurBlock->fBegin) {
+        while (fCurBlock && NULL == fCurBlock->fBegin) {
             fCurBlock = fCurBlock->fNext;
         }
         fPos = fCurBlock ? fCurBlock->fBegin : NULL;
     } else {
         // initialize the iterator to start at the back
         fCurBlock = d.fBackBlock;
-        while (NULL != fCurBlock && NULL == fCurBlock->fEnd) {
+        while (fCurBlock && NULL == fCurBlock->fEnd) {
             fCurBlock = fCurBlock->fPrev;
         }
         fPos = fCurBlock ? fCurBlock->fEnd - fElemSize : NULL;
diff --git a/src/core/SkDescriptor.h b/src/core/SkDescriptor.h
index c526451..d550863 100644
--- a/src/core/SkDescriptor.h
+++ b/src/core/SkDescriptor.h
@@ -123,7 +123,7 @@
     static uint32_t ComputeChecksum(const SkDescriptor* desc) {
         const uint32_t* ptr = (const uint32_t*)desc + 1; // skip the checksum field
         size_t len = desc->fLength - sizeof(uint32_t);
-        return SkChecksum::Compute(ptr, len);
+        return SkChecksum::Murmur3(ptr, len);
     }
 
     // private so no one can create one except our factories
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 6a09c0b..0ce119b 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -6,20 +6,15 @@
  */
 
 #include "SkDevice.h"
+#include "SkDeviceProperties.h"
+#include "SkDraw.h"
 #include "SkMetaData.h"
+#include "SkPatchUtils.h"
+#include "SkShader.h"
+#include "SkTextBlob.h"
 
 SkBaseDevice::SkBaseDevice()
-    : fLeakyProperties(SkDeviceProperties::MakeDefault())
-#ifdef SK_DEBUG
-    , fAttachedToCanvas(false)
-#endif
-{
-    fOrigin.setZero();
-    fMetaData = NULL;
-}
-
-SkBaseDevice::SkBaseDevice(const SkDeviceProperties& deviceProperties)
-    : fLeakyProperties(deviceProperties)
+    : fLeakyProperties(SkNEW_ARGS(SkDeviceProperties, (SkDeviceProperties::kLegacyLCD_InitType)))
 #ifdef SK_DEBUG
     , fAttachedToCanvas(false)
 #endif
@@ -29,7 +24,8 @@
 }
 
 SkBaseDevice::~SkBaseDevice() {
-    delete fMetaData;
+    SkDELETE(fLeakyProperties);
+    SkDELETE(fMetaData);
 }
 
 SkBaseDevice* SkBaseDevice::createCompatibleDevice(const SkImageInfo& info) {
@@ -40,6 +36,10 @@
     return this->onCreateDevice(info, kSaveLayer_Usage);
 }
 
+SkBaseDevice* SkBaseDevice::createCompatibleDeviceForImageFilter(const SkImageInfo& info) {
+    return this->onCreateDevice(info, kImageFilter_Usage);
+}
+
 SkMetaData& SkBaseDevice::getMetaData() {
     // metadata users are rare, so we lazily allocate it. If that changes we
     // can decide to just make it a field in the device (rather than a ptr)
@@ -61,7 +61,11 @@
     return bitmap;
 }
 
-SkSurface* SkBaseDevice::newSurface(const SkImageInfo&) { return NULL; }
+void SkBaseDevice::setPixelGeometry(SkPixelGeometry geo) {
+    fLeakyProperties->fPixelGeometry = geo;
+}
+
+SkSurface* SkBaseDevice::newSurface(const SkImageInfo&, const SkSurfaceProps&) { return NULL; }
 
 const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; }
 
@@ -77,6 +81,72 @@
     this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
 }
 
+void SkBaseDevice::drawPatch(const SkDraw& draw, const SkPoint cubics[12], const SkColor colors[4],
+                             const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
+    SkPatchUtils::VertexData data;
+    
+    SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix);
+
+    // It automatically adjusts lodX and lodY in case it exceeds the number of indices.
+    // If it fails to generate the vertices, then we do not draw. 
+    if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
+        this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
+                           data.fTexCoords, data.fColors, xmode, data.fIndices, data.fIndexCount,
+                           paint);
+    }
+}
+
+void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint &paint) {
+
+    SkPaint runPaint = paint;
+    SkMatrix localMatrix;
+    SkDraw localDraw(draw);
+
+    if (x || y) {
+        localMatrix = *draw.fMatrix;
+        localMatrix.preTranslate(x, y);
+        localDraw.fMatrix = &localMatrix;
+
+        if (paint.getShader()) {
+            // FIXME: We need to compensate for the translate above. This is suboptimal but
+            // temporary -- until we get proper derived class drawTextBlob implementations.
+
+            // TODO: pass x,y down to the other methods so they can handle the additional
+            // translate without needing to allocate a new shader.
+            SkMatrix shaderMatrix;
+            shaderMatrix.setTranslate(-x, -y);
+            SkAutoTUnref<SkShader> wrapper(
+                SkShader::CreateLocalMatrixShader(paint.getShader(), shaderMatrix));
+            runPaint.setShader(wrapper);
+        }
+    }
+
+    SkTextBlob::RunIterator it(blob);
+    while (!it.done()) {
+        size_t textLen = it.glyphCount() * sizeof(uint16_t);
+        const SkPoint& offset = it.offset();
+        // applyFontToPaint() always overwrites the exact same attributes,
+        // so it is safe to not re-seed the paint.
+        it.applyFontToPaint(&runPaint);
+
+        switch (it.positioning()) {
+        case SkTextBlob::kDefault_Positioning:
+            this->drawText(localDraw, it.glyphs(), textLen, offset.x(), offset.y(), runPaint);
+            break;
+        case SkTextBlob::kHorizontal_Positioning:
+        case SkTextBlob::kFull_Positioning:
+            this->drawPosText(localDraw, it.glyphs(), textLen, it.pos(), offset.y(),
+                              SkTextBlob::ScalarsPerGlyph(it.positioning()), runPaint);
+            break;
+        default:
+            SkFAIL("unhandled positioning mode");
+        }
+
+        it.next();
+    }
+}
+
 bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowBytes, int x, int y) {
 #ifdef SK_DEBUG
     SkASSERT(info.width() > 0 && info.height() > 0);
@@ -134,11 +204,8 @@
     // The base class doesn't perform any analysis but derived classes may
 }
 
-void SkBaseDevice::EXPERIMENTAL_purge(const SkPicture* picture) {
-    // Derived-classes may have data to purge but not the base class
-}
-
-bool SkBaseDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture) {
+bool SkBaseDevice::EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*,
+                                            const SkPaint*) {
     // The base class doesn't perform any accelerated picture rendering
     return false;
 }
diff --git a/src/core/SkDeviceImageFilterProxy.h b/src/core/SkDeviceImageFilterProxy.h
index 5ee5634..0b83b1a 100644
--- a/src/core/SkDeviceImageFilterProxy.h
+++ b/src/core/SkDeviceImageFilterProxy.h
@@ -15,7 +15,7 @@
     SkDeviceImageFilterProxy(SkBaseDevice* device) : fDevice(device) {}
 
     virtual SkBaseDevice* createDevice(int w, int h) SK_OVERRIDE {
-        return fDevice->createCompatibleDevice(SkImageInfo::MakeN32Premul(w, h));
+        return fDevice->createCompatibleDeviceForImageFilter(SkImageInfo::MakeN32Premul(w, h));
     }
     virtual bool canHandleImageFilter(const SkImageFilter* filter) SK_OVERRIDE {
         return fDevice->canHandleImageFilter(filter);
diff --git a/src/core/SkDeviceLooper.cpp b/src/core/SkDeviceLooper.cpp
index 9346465..a8350cc 100644
--- a/src/core/SkDeviceLooper.cpp
+++ b/src/core/SkDeviceLooper.cpp
@@ -10,9 +10,10 @@
 SkDeviceLooper::SkDeviceLooper(const SkBitmap& base,
                                const SkRasterClip& rc,
                                const SkIRect& bounds, bool aa)
-: fBaseBitmap(base)
-, fBaseRC(rc)
-, fDelta(aa ? kAA_Delta : kBW_Delta)
+    : fBaseBitmap(base)
+    , fBaseRC(rc)
+    , fSubsetRC(rc.isForceConservativeRects())
+    , fDelta(aa ? kAA_Delta : kBW_Delta)
 {
     // sentinels that next() has not yet been called, and so our mapper functions
     // should not be called either.
diff --git a/src/core/SkDeviceProperties.h b/src/core/SkDeviceProperties.h
new file mode 100644
index 0000000..11ecd65
--- /dev/null
+++ b/src/core/SkDeviceProperties.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDeviceProperties_DEFINED
+#define SkDeviceProperties_DEFINED
+
+#include "SkSurfacePriv.h"
+
+struct SkDeviceProperties {
+    enum InitType {
+        kLegacyLCD_InitType
+    };
+    SkDeviceProperties(InitType) : fPixelGeometry(SkSurfacePropsDefaultPixelGeometry()) {}
+    SkDeviceProperties(SkPixelGeometry geo) : fPixelGeometry(geo) {}
+
+    SkPixelGeometry fPixelGeometry;
+
+    // read-only attribute -- until we actually store a value (future CL)
+    float getGamma() const { return SK_GAMMA_EXPONENT; }
+};
+
+#endif
diff --git a/src/core/SkDistanceFieldGen.cpp b/src/core/SkDistanceFieldGen.cpp
index ef0ee86..92cf1af 100755
--- a/src/core/SkDistanceFieldGen.cpp
+++ b/src/core/SkDistanceFieldGen.cpp
@@ -332,8 +332,8 @@
 static bool generate_distance_field_from_image(unsigned char* distanceField,
                                                const unsigned char* copyPtr,
                                                int width, int height) {
-    SkASSERT(NULL != distanceField);
-    SkASSERT(NULL != copyPtr);
+    SkASSERT(distanceField);
+    SkASSERT(copyPtr);
 
     // we expand our temp data by one more on each side to simplify
     // the scanning code -- will always be treated as infinitely far away
@@ -462,8 +462,8 @@
 bool SkGenerateDistanceFieldFromA8Image(unsigned char* distanceField,
                                         const unsigned char* image,
                                         int width, int height, int rowBytes) {
-    SkASSERT(NULL != distanceField);
-    SkASSERT(NULL != image);
+    SkASSERT(distanceField);
+    SkASSERT(image);
 
     // create temp data
     SkAutoSMalloc<1024> copyStorage((width+2)*(height+2)*sizeof(char));
@@ -490,8 +490,8 @@
 bool SkGenerateDistanceFieldFromBWImage(unsigned char* distanceField,
                                         const unsigned char* image,
                                         int width, int height, int rowBytes) {
-    SkASSERT(NULL != distanceField);
-    SkASSERT(NULL != image);
+    SkASSERT(distanceField);
+    SkASSERT(image);
 
     // create temp data
     SkAutoSMalloc<1024> copyStorage((width+2)*(height+2)*sizeof(char));
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index b77eb43..4deefdc 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -54,9 +54,10 @@
     SkBlitter*  get() const { return fBlitter; }
 
     void choose(const SkBitmap& device, const SkMatrix& matrix,
-                const SkPaint& paint) {
+                const SkPaint& paint, bool drawCoverage = false) {
         SkASSERT(!fBlitter);
-        fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator);
+        fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator,
+                                     drawCoverage);
     }
 
 private:
@@ -459,7 +460,7 @@
         return true;
     }
     if (paint.getStrokeCap() != SkPaint::kRound_Cap &&
-            matrix->rectStaysRect() && SkCanvas::kPoints_PointMode == mode) {
+        matrix->isScaleTranslate() && SkCanvas::kPoints_PointMode == mode) {
         SkScalar sx = matrix->get(SkMatrix::kMScaleX);
         SkScalar sy = matrix->get(SkMatrix::kMScaleY);
         if (SkScalarNearlyZero(sx - sy)) {
@@ -627,7 +628,7 @@
             }
             case SkCanvas::kLines_PointMode:
 #ifndef SK_DISABLE_DASHING_OPTIMIZATION
-                if (2 == count && NULL != paint.getPathEffect()) {
+                if (2 == count && paint.getPathEffect()) {
                     // most likely a dashed line - see if it is one of the ones
                     // we can accelerate
                     SkStrokeRec rec(paint);
@@ -816,7 +817,12 @@
     devRect.roundOut(&ir);
     if (paint.getStyle() != SkPaint::kFill_Style) {
         // extra space for hairlines
-        ir.inset(-1, -1);
+        if (paint.getStrokeWidth() == 0) {
+            ir.outset(1, 1);
+        } else {
+            SkScalar radius = SkScalarHalf(paint.getStrokeWidth());
+            ir.outset(radius, radius);
+        }
     }
     if (fRC->quickReject(ir)) {
         return;
@@ -938,7 +944,7 @@
     SkScalar len0 = fast_len(dst[0]);
     SkScalar len1 = fast_len(dst[1]);
     if (len0 <= SK_Scalar1 && len1 <= SK_Scalar1) {
-        if (NULL != coverage) {
+        if (coverage) {
             *coverage = SkScalarAve(len0, len1);
         }
         return true;
@@ -992,7 +998,7 @@
 
 void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
                       const SkMatrix* prePathMatrix, bool pathIsMutable,
-                      bool drawCoverage) const {
+                      bool drawCoverage, SkBlitter* customBlitter) const {
     SkDEBUGCODE(this->validate();)
 
     // nothing to draw
@@ -1078,12 +1084,19 @@
     // transform the path into device space
     pathPtr->transform(*matrix, devPathPtr);
 
-    SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, *paint, drawCoverage);
+    SkBlitter* blitter = NULL;
+    SkAutoBlitterChoose blitterStorage;
+    if (NULL == customBlitter) {
+        blitterStorage.choose(*fBitmap, *fMatrix, *paint, drawCoverage);
+        blitter = blitterStorage.get();
+    } else {
+        blitter = customBlitter;
+    }
 
     if (paint->getMaskFilter()) {
         SkPaint::Style style = doFill ? SkPaint::kFill_Style :
             SkPaint::kStroke_Style;
-        if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blitter.get(), style)) {
+        if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blitter, style)) {
             return; // filterPath() called the blitter, so we're done
         }
     }
@@ -1102,7 +1115,7 @@
             proc = SkScan::HairPath;
         }
     }
-    proc(*devPathPtr, *fRC, blitter.get());
+    proc(*devPathPtr, *fRC, blitter);
 }
 
 /** For the purposes of drawing bitmaps, if a matrix is "almost" translate
@@ -1563,7 +1576,7 @@
 
     SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
 
-    SkAutoGlyphCache    autoCache(paint, &fDevice->fLeakyProperties, fMatrix);
+    SkAutoGlyphCache    autoCache(paint, &fDevice->getLeakyProperties(), fMatrix);
     SkGlyphCache*       cache = autoCache.getCache();
 
     // transform our starting point
@@ -1711,7 +1724,7 @@
     }
 
     SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc();
-    SkAutoGlyphCache    autoCache(paint, &fDevice->fLeakyProperties, fMatrix);
+    SkAutoGlyphCache    autoCache(paint, &fDevice->getLeakyProperties(), fMatrix);
     SkGlyphCache*       cache = autoCache.getCache();
 
     SkAAClipBlitterWrapper wrapper;
@@ -2011,11 +2024,9 @@
     };
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader)
+    SK_DECLARE_NOT_FLATTENABLE_PROCS(SkTriColorShader)
 
 protected:
-    SkTriColorShader(SkReadBuffer& buffer) : SkShader(buffer) {}
-
     virtual Context* onCreateContext(const ContextRec& rec, void* storage) const SK_OVERRIDE {
         return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, rec));
     }
@@ -2124,7 +2135,7 @@
                           const SkColor colors[], SkXfermode* xmode,
                           const uint16_t indices[], int indexCount,
                           const SkPaint& paint) const {
-    SkASSERT(0 == count || NULL != vertices);
+    SkASSERT(0 == count || vertices);
 
     // abort early if there is nothing to draw
     if (count < 3 || (indices && indexCount < 3) || fRC->isEmpty()) {
@@ -2162,7 +2173,7 @@
 
     // setup the custom shader (if needed)
     SkAutoTUnref<SkComposeShader> composeShader;
-    if (NULL != colors) {
+    if (colors) {
         if (NULL == textures) {
             // just colors (no texture)
             shader = p.setShader(&triShader);
@@ -2192,9 +2203,9 @@
     VertState       state(count, indices, indexCount);
     VertState::Proc vertProc = state.chooseProc(vmode);
 
-    if (NULL != textures || NULL != colors) {
+    if (textures || colors) {
         while (vertProc(&state)) {
-            if (NULL != textures) {
+            if (textures) {
                 SkMatrix tempM;
                 if (texture_to_matrix(state, vertices, textures, &tempM)) {
                     SkShader::ContextRec rec(*fBitmap, p, *fMatrix);
@@ -2204,7 +2215,7 @@
                     }
                 }
             }
-            if (NULL != colors) {
+            if (colors) {
                 // Find the context for triShader.
                 SkTriColorShader::TriColorShaderContext* triColorShaderContext;
 
diff --git a/src/core/SkEdge.cpp b/src/core/SkEdge.cpp
index 9ce2558..ac0ca58 100644
--- a/src/core/SkEdge.cpp
+++ b/src/core/SkEdge.cpp
@@ -36,11 +36,18 @@
     SkFDot6 x0, y0, x1, y1;
 
     {
+#ifdef SK_RASTERIZE_EVEN_ROUNDING
+        x0 = SkScalarRoundToFDot6(p0.fX, shift);
+        y0 = SkScalarRoundToFDot6(p0.fY, shift);
+        x1 = SkScalarRoundToFDot6(p1.fX, shift);
+        y1 = SkScalarRoundToFDot6(p1.fY, shift);
+#else
         float scale = float(1 << (shift + 6));
         x0 = int(p0.fX * scale);
         y0 = int(p0.fY * scale);
         x1 = int(p1.fX * scale);
         y1 = int(p1.fY * scale);
+#endif
     }
 
     int winding = 1;
@@ -59,7 +66,7 @@
         return 0;
     }
     // are we completely above or below the clip?
-    if (NULL != clip && (top >= clip->fBottom || bot <= clip->fTop)) {
+    if (clip && (top >= clip->fBottom || bot <= clip->fTop)) {
         return 0;
     }
 
@@ -171,6 +178,14 @@
     SkFDot6 x0, y0, x1, y1, x2, y2;
 
     {
+#ifdef SK_RASTERIZE_EVEN_ROUNDING
+        x0 = SkScalarRoundToFDot6(pts[0].fX, shift);
+        y0 = SkScalarRoundToFDot6(pts[0].fY, shift);
+        x1 = SkScalarRoundToFDot6(pts[1].fX, shift);
+        y1 = SkScalarRoundToFDot6(pts[1].fY, shift);
+        x2 = SkScalarRoundToFDot6(pts[2].fX, shift);
+        y2 = SkScalarRoundToFDot6(pts[2].fY, shift);
+#else
         float scale = float(1 << (shift + 6));
         x0 = int(pts[0].fX * scale);
         y0 = int(pts[0].fY * scale);
@@ -178,6 +193,7 @@
         y1 = int(pts[1].fY * scale);
         x2 = int(pts[2].fX * scale);
         y2 = int(pts[2].fY * scale);
+#endif
     }
 
     int winding = 1;
@@ -321,6 +337,16 @@
     SkFDot6 x0, y0, x1, y1, x2, y2, x3, y3;
 
     {
+#ifdef SK_RASTERIZE_EVEN_ROUNDING
+        x0 = SkScalarRoundToFDot6(pts[0].fX, shift);
+        y0 = SkScalarRoundToFDot6(pts[0].fY, shift);
+        x1 = SkScalarRoundToFDot6(pts[1].fX, shift);
+        y1 = SkScalarRoundToFDot6(pts[1].fY, shift);
+        x2 = SkScalarRoundToFDot6(pts[2].fX, shift);
+        y2 = SkScalarRoundToFDot6(pts[2].fY, shift);
+        x3 = SkScalarRoundToFDot6(pts[3].fX, shift);
+        y3 = SkScalarRoundToFDot6(pts[3].fY, shift);
+#else
         float scale = float(1 << (shift + 6));
         x0 = int(pts[0].fX * scale);
         y0 = int(pts[0].fY * scale);
@@ -330,6 +356,7 @@
         y2 = int(pts[2].fY * scale);
         x3 = int(pts[3].fX * scale);
         y3 = int(pts[3].fY * scale);
+#endif
     }
 
     int winding = 1;
diff --git a/src/core/SkEdge.h b/src/core/SkEdge.h
index 0912236..67a0ee7 100644
--- a/src/core/SkEdge.h
+++ b/src/core/SkEdge.h
@@ -89,11 +89,18 @@
     SkFDot6 x0, y0, x1, y1;
 
     {
+#ifdef SK_RASTERIZE_EVEN_ROUNDING
+        x0 = SkScalarRoundToFDot6(p0.fX, shift);
+        y0 = SkScalarRoundToFDot6(p0.fY, shift);
+        x1 = SkScalarRoundToFDot6(p1.fX, shift);
+        y1 = SkScalarRoundToFDot6(p1.fY, shift);
+#else
         float scale = float(1 << (shift + 6));
         x0 = int(p0.fX * scale);
         y0 = int(p0.fY * scale);
         x1 = int(p1.fX * scale);
         y1 = int(p1.fY * scale);
+#endif
     }
 
     int winding = 1;
diff --git a/include/core/SkEmptyShader.h b/src/core/SkEmptyShader.h
similarity index 95%
rename from include/core/SkEmptyShader.h
rename to src/core/SkEmptyShader.h
index 7de3bc1..250e37a 100644
--- a/include/core/SkEmptyShader.h
+++ b/src/core/SkEmptyShader.h
@@ -30,7 +30,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkEmptyShader(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     virtual SkShader::Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE {
         return NULL;
diff --git a/src/core/SkFDot6.h b/src/core/SkFDot6.h
index 5a0ec57..3da753d 100644
--- a/src/core/SkFDot6.h
+++ b/src/core/SkFDot6.h
@@ -15,6 +15,28 @@
 
 typedef int32_t SkFDot6;
 
+/* This uses the magic number approach suggested here:
+ * http://stereopsis.com/sree/fpu2006.html and used in
+ * _cairo_fixed_from_double. It does banker's rounding
+ * (i.e. round to nearest even)
+ */
+inline SkFDot6 SkScalarRoundToFDot6(SkScalar x, int shift = 0)
+{
+    union {
+        double  fDouble;
+        int32_t fBits[2];
+    } tmp;
+    int fractionalBits = 6 + shift;
+    double magic = (1LL << (52 - (fractionalBits))) * 1.5;
+
+    tmp.fDouble = SkScalarToDouble(x) + magic;
+#ifdef SK_CPU_BENDIAN
+    return tmp.fBits[1];
+#else
+    return tmp.fBits[0];
+#endif
+}
+
 #define SK_FDot6One         (64)
 #define SK_FDot6Half        (32)
 
diff --git a/src/core/SkFilterShader.cpp b/src/core/SkFilterShader.cpp
index 0c92d4c..cb042e6 100644
--- a/src/core/SkFilterShader.cpp
+++ b/src/core/SkFilterShader.cpp
@@ -21,19 +21,28 @@
     filter->ref();
 }
 
-SkFilterShader::SkFilterShader(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkFilterShader::SkFilterShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     fShader = buffer.readShader();
     fFilter = buffer.readColorFilter();
 }
+#endif
 
 SkFilterShader::~SkFilterShader() {
     fFilter->unref();
     fShader->unref();
 }
 
+SkFlattenable* SkFilterShader::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkShader> shader(buffer.readShader());
+    SkAutoTUnref<SkColorFilter> filter(buffer.readColorFilter());
+    if (!shader.get() || !filter.get()) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkFilterShader, (shader, filter));
+}
+
 void SkFilterShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeFlattenable(fShader);
     buffer.writeFlattenable(fFilter);
 }
diff --git a/src/core/SkFilterShader.h b/src/core/SkFilterShader.h
index 1a4b71f..b98fc83 100644
--- a/src/core/SkFilterShader.h
+++ b/src/core/SkFilterShader.h
@@ -30,6 +30,11 @@
         virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
         virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE;
 
+        virtual void set3DMask(const SkMask* mask) SK_OVERRIDE {
+            // forward to our proxy
+            fShaderContext->set3DMask(mask);
+        }
+
     private:
         SkShader::Context* fShaderContext;
 
@@ -40,7 +45,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkFilterShader)
 
 protected:
-    SkFilterShader(SkReadBuffer& );
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    SkFilterShader(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
diff --git a/src/core/SkFlattenable.cpp b/src/core/SkFlattenable.cpp
index 410fe0d..b0c1697 100644
--- a/src/core/SkFlattenable.cpp
+++ b/src/core/SkFlattenable.cpp
@@ -1,22 +1,21 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "SkFlattenable.h"
 #include "SkPtrRecorder.h"
+#include "SkReadBuffer.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkFlattenable::flatten(SkWriteBuffer&) const
-{
-    /*  we don't write anything at the moment, but this allows our subclasses
-        to not know that, since we want them to always call INHERITED::flatten()
-        in their code.
-    */
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+bool SkFlattenable::NeedsDeepUnflatten(const SkReadBuffer& buffer) {
+    return buffer.isVersionLT(SkReadBuffer::kFlattenCreateProc_Version);
 }
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -115,7 +114,7 @@
 }
 
 bool SkFlattenable::NameToType(const char name[], SkFlattenable::Type* type) {
-    SkASSERT(NULL != type);
+    SkASSERT(type);
     InitializeFlattenablesIfNeeded();
 #ifdef SK_DEBUG
     report_no_entries(__FUNCTION__);
diff --git a/src/core/SkFlattenableSerialization.cpp b/src/core/SkFlattenableSerialization.cpp
index b33bca6..3160207 100644
--- a/src/core/SkFlattenableSerialization.cpp
+++ b/src/core/SkFlattenableSerialization.cpp
@@ -15,9 +15,9 @@
     SkWriteBuffer writer(SkWriteBuffer::kValidation_Flag);
     writer.writeFlattenable(flattenable);
     size_t size = writer.bytesWritten();
-    void* data = sk_malloc_throw(size);
-    writer.writeToMemory(data);
-    return SkData::NewFromMalloc(data, size);
+    SkData* data = SkData::NewUninitialized(size);
+    writer.writeToMemory(data->writable_data());
+    return data;
 }
 
 SkFlattenable* SkValidatingDeserializeFlattenable(const void* data, size_t size,
diff --git a/src/core/SkFloatBits.cpp b/src/core/SkFloatBits.cpp
index 39b51ab..8d89dfe 100644
--- a/src/core/SkFloatBits.cpp
+++ b/src/core/SkFloatBits.cpp
@@ -85,7 +85,16 @@
         value = SkApplySign(value, SkExtractSign(packed));
         exp = -exp;
         if (exp > 25) {   // underflow
+#ifdef SK_DISCARD_DENORMALIZED_FOR_SPEED
+        // The iOS ARM processor discards small denormalized numbers to go faster.
+        // The comparision below empirically causes the result to agree with the
+        // tests in MathTest test_float_floor
+            if (exp > 149) {
+                return 0;
+            }
+#else
             exp = 25;
+#endif
         }
         // int add = 0;
         return value >> exp;
@@ -145,7 +154,17 @@
         value = SkApplySign(value, SkExtractSign(packed));
         exp = -exp;
         if (exp > 25) {   // underflow
+#ifdef SK_DISCARD_DENORMALIZED_FOR_SPEED
+        // The iOS ARM processor discards small denormalized numbers to go faster.
+        // The comparision below empirically causes the result to agree with the
+        // tests in MathTest test_float_ceil
+            if (exp > 149) {
+                return 0;
+            }
+            return 0 < value;
+#else
             exp = 25;
+#endif
         }
         int add = (1 << exp) - 1;
         return (value + add) >> exp;
@@ -184,23 +203,3 @@
     data.fSignBitInt = (sign << 31) | (shift << 23) | (value & ~MATISSA_MAGIC_BIG);
     return data.fFloat;
 }
-
-float SkIntToFloatCast_NoOverflowCheck(int32_t value) {
-    if (0 == value) {
-        return 0;
-    }
-
-    int shift = EXP_BIAS;
-
-    // record the sign and make value positive
-    int sign = SkExtractSign(value);
-    value = SkApplySign(value, sign);
-
-    int zeros = SkCLZ(value << 8);
-    value <<= zeros;
-    shift -= zeros;
-
-    SkFloatIntUnion data;
-    data.fSignBitInt = (sign << 31) | (shift << 23) | (value & ~MATISSA_MAGIC_BIG);
-    return data.fFloat;
-}
diff --git a/src/core/SkFontDescriptor.cpp b/src/core/SkFontDescriptor.cpp
index 5088ed7..7426894 100644
--- a/src/core/SkFontDescriptor.cpp
+++ b/src/core/SkFontDescriptor.cpp
@@ -7,6 +7,7 @@
 
 #include "SkFontDescriptor.h"
 #include "SkStream.h"
+#include <SkData.h>
 
 enum {
     // these must match the sfnt 'name' enums
@@ -16,13 +17,12 @@
 
     // These count backwards from 0xFF, so as not to collide with the SFNT
     // defines for names in its 'name' table.
+    kFontIndex      = 0xFD,
     kFontFileName   = 0xFE,
     kSentinel       = 0xFF,
 };
 
-SkFontDescriptor::SkFontDescriptor(SkTypeface::Style style) {
-    fStyle = style;
-}
+SkFontDescriptor::SkFontDescriptor(SkTypeface::Style style) : fFontIndex(0), fStyle(style) { }
 
 static void read_string(SkStream* stream, SkString* string) {
     const uint32_t length = SkToU32(stream->readPackedUInt());
@@ -41,11 +41,20 @@
     }
 }
 
-SkFontDescriptor::SkFontDescriptor(SkStream* stream) {
+static size_t read_uint(SkStream* stream) {
+    return stream->readPackedUInt();
+}
+
+static void write_uint(SkWStream* stream, size_t n, uint32_t id) {
+    stream->writePackedUInt(id);
+    stream->writePackedUInt(n);
+}
+
+SkFontDescriptor::SkFontDescriptor(SkStream* stream) : fFontIndex(0) {
     fStyle = (SkTypeface::Style)stream->readPackedUInt();
 
-    for (;;) {
-        switch (stream->readPackedUInt()) {
+    for (size_t id; (id = stream->readPackedUInt()) != kSentinel;) {
+        switch (id) {
             case kFontFamilyName:
                 read_string(stream, &fFamilyName);
                 break;
@@ -55,16 +64,25 @@
             case kPostscriptName:
                 read_string(stream, &fPostscriptName);
                 break;
+            case kFontIndex:
+                fFontIndex = read_uint(stream);
+                break;
             case kFontFileName:
                 read_string(stream, &fFontFileName);
                 break;
-            case kSentinel:
-                return;
             default:
                 SkDEBUGFAIL("Unknown id used by a font descriptor");
                 return;
         }
     }
+
+    size_t length = stream->readPackedUInt();
+    if (length > 0) {
+        SkAutoTUnref<SkData> data(SkData::NewUninitialized(length));
+        if (stream->read(data->writable_data(), length) == length) {
+            fFontData.reset(SkNEW_ARGS(SkMemoryStream, (data)));
+        }
+    }
 }
 
 void SkFontDescriptor::serialize(SkWStream* stream) {
@@ -74,6 +92,17 @@
     write_string(stream, fFullName, kFullName);
     write_string(stream, fPostscriptName, kPostscriptName);
     write_string(stream, fFontFileName, kFontFileName);
+    if (fFontIndex) {
+        write_uint(stream, fFontIndex, kFontIndex);
+    }
 
     stream->writePackedUInt(kSentinel);
+
+    if (fFontData) {
+        size_t length = fFontData->getLength();
+        stream->writePackedUInt(length);
+        stream->writeStream(fFontData, length);
+    } else {
+        stream->writePackedUInt(0);
+    }
 }
diff --git a/src/core/SkFontDescriptor.h b/src/core/SkFontDescriptor.h
index 5febfd8..5a6ddd5 100644
--- a/src/core/SkFontDescriptor.h
+++ b/src/core/SkFontDescriptor.h
@@ -8,10 +8,10 @@
 #ifndef SkFontDescriptor_DEFINED
 #define SkFontDescriptor_DEFINED
 
+#include "SkStream.h"
 #include "SkString.h"
 #include "SkTypeface.h"
 
-class SkStream;
 class SkWStream;
 
 class SkFontDescriptor {
@@ -24,21 +24,30 @@
     SkTypeface::Style getStyle() { return fStyle; }
     void setStyle(SkTypeface::Style style) { fStyle = style; }
 
-    const char* getFamilyName() { return fFamilyName.c_str(); }
-    const char* getFullName() { return fFullName.c_str(); }
-    const char* getPostscriptName() { return fPostscriptName.c_str(); }
-    const char* getFontFileName() { return fFontFileName.c_str(); }
+    const char* getFamilyName() const { return fFamilyName.c_str(); }
+    const char* getFullName() const { return fFullName.c_str(); }
+    const char* getPostscriptName() const { return fPostscriptName.c_str(); }
+    const char* getFontFileName() const { return fFontFileName.c_str(); }
+    SkStream* getFontData() const { return fFontData; }
+    int getFontIndex() const { return fFontIndex; }
 
     void setFamilyName(const char* name) { fFamilyName.set(name); }
     void setFullName(const char* name) { fFullName.set(name); }
     void setPostscriptName(const char* name) { fPostscriptName.set(name); }
     void setFontFileName(const char* name) { fFontFileName.set(name); }
+    /** Set the font data only if it is necessary for serialization.
+     *  This method takes ownership of the stream (both reference and cursor).
+     */
+    void setFontData(SkStream* stream) { fFontData.reset(stream); }
+    void setFontIndex(int index) { fFontIndex = index; }
 
 private:
     SkString fFamilyName;
     SkString fFullName;
     SkString fPostscriptName;
     SkString fFontFileName;
+    SkAutoTUnref<SkStream> fFontData;
+    int fFontIndex;
 
     SkTypeface::Style fStyle;
 };
diff --git a/src/core/SkFontHost.cpp b/src/core/SkFontHost.cpp
index a16a8c4..ef5d41f 100644
--- a/src/core/SkFontHost.cpp
+++ b/src/core/SkFontHost.cpp
@@ -110,10 +110,18 @@
                                            const SkFontStyle&) const SK_OVERRIDE {
         return NULL;
     }
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
                                                     const SkFontStyle& style,
-                                                    const char bpc47[],
-                                                    uint32_t character) const SK_OVERRIDE {
+                                                    const char* bcp47[],
+                                                    int bcp47Count,
+                                                    SkUnichar character) const SK_OVERRIDE {
+#else
+    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+                                                    const SkFontStyle& style,
+                                                    const char bcp47[],
+                                                    SkUnichar character) const SK_OVERRIDE {
+#endif
         return NULL;
     }
     virtual SkTypeface* onMatchFaceStyle(const SkTypeface*,
@@ -162,10 +170,18 @@
     return this->onMatchFamilyStyle(familyName, fs);
 }
 
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
 SkTypeface* SkFontMgr::matchFamilyStyleCharacter(const char familyName[], const SkFontStyle& style,
-                                                 const char bpc47[], uint32_t character) const {
-    return this->onMatchFamilyStyleCharacter(familyName, style, bpc47, character);
+                                                 const char* bcp47[], int bcp47Count,
+                                                 SkUnichar character) const {
+    return this->onMatchFamilyStyleCharacter(familyName, style, bcp47, bcp47Count, character);
 }
+#else
+SkTypeface* SkFontMgr::matchFamilyStyleCharacter(const char familyName[], const SkFontStyle& style,
+                                                 const char bcp47[], SkUnichar character) const {
+    return this->onMatchFamilyStyleCharacter(familyName, style, bcp47, character);
+}
+#endif
 
 SkTypeface* SkFontMgr::matchFaceStyle(const SkTypeface* face,
                                       const SkFontStyle& fs) const {
@@ -207,50 +223,3 @@
     SK_DECLARE_STATIC_LAZY_PTR(SkFontMgr, singleton, CreateDefault);
     return SkRef(singleton.get());
 }
-
-//////////////////////////////////////////////////////////////////////////
-
-#ifndef SK_FONTHOST_DOES_NOT_USE_FONTMGR
-
-#if 0
-static SkFontStyle TypefaceStyleBitsToFontStyle(SkTypeface::Style styleBits) {
-    SkFontStyle::Weight weight = (styleBits & SkTypeface::kBold) ?
-                                     SkFontStyle::kBold_Weight :
-                                     SkFontStyle::kNormal_Weight;
-    SkFontStyle::Width width = SkFontStyle::kNormal_Width;
-    SkFontStyle::Slant slant = (styleBits & SkTypeface::kItalic) ?
-                                     SkFontStyle::kUpright_Slant :
-                                     SkFontStyle::kItalic_Slant;
-    return SkFontStyle(weight, width, slant);
-}
-#endif
-
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
-                                       const char familyName[],
-                                       SkTypeface::Style style) {
-    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
-    if (familyFace) {
-        bool bold = style & SkTypeface::kBold;
-        bool italic = style & SkTypeface::kItalic;
-        SkFontStyle newStyle = SkFontStyle(bold ? SkFontStyle::kBold_Weight
-                                                : SkFontStyle::kNormal_Weight,
-                                           SkFontStyle::kNormal_Width,
-                                           italic ? SkFontStyle::kItalic_Slant
-                                                  : SkFontStyle::kUpright_Slant);
-        return fm->matchFaceStyle(familyFace, newStyle);
-    } else {
-        return fm->legacyCreateTypeface(familyName, style);
-    }
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
-    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
-    return fm->createFromFile(path);
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
-    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
-    return fm->createFromStream(stream);
-}
-
-#endif
diff --git a/src/core/SkForceCPlusPlusLinking.cpp b/src/core/SkForceCPlusPlusLinking.cpp
new file mode 100644
index 0000000..829d0d3
--- /dev/null
+++ b/src/core/SkForceCPlusPlusLinking.cpp
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// This file is intentionally empty.  We add it to the dependencies of skia_lib
+// so that GYP detects that libskia is a C++ library (implicitly depending on
+// the standard library, -lm, etc.) from its file extension.
+//
+// If we didn't do this, GYP would link libskia.so as a C library and we'd get
+// link-time failures for simple binaries that don't themselves depend on the
+// C++ standard library.
+//
+// Even if we try hard not to depend on the standard library, say, never
+// calling new or delete, the compiler can still insert calls on our behalf
+// that make us depend on it anyway: a handler when we call a for a pure
+// virtual, thread-safety guards around statics, probably other similar
+// language constructs.
diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp
index 646dfb0..254f79b 100644
--- a/src/core/SkGeometry.cpp
+++ b/src/core/SkGeometry.cpp
@@ -102,7 +102,7 @@
     if (SkScalarIsNaN(r)) {
         return 0;
     }
-    SkASSERT(r >= 0 && r < SK_Scalar1);
+    SkASSERTF(r >= 0 && r < SK_Scalar1, "numer %f, denom %f, r %f", numer, denom, r);
     if (r == 0) { // catch underflow if numer <<<< denom
         return 0;
     }
diff --git a/src/core/SkGlyph.h b/src/core/SkGlyph.h
index 73afb13..4290bb8 100644
--- a/src/core/SkGlyph.h
+++ b/src/core/SkGlyph.h
@@ -32,6 +32,7 @@
     void*       fDistanceField;
     uint8_t     fMaskFormat;
     int8_t      fRsbDelta, fLsbDelta;  // used by auto-kerning
+    int8_t      fForceBW;
 
     void init(uint32_t id) {
         fID             = id;
@@ -39,6 +40,7 @@
         fPath           = NULL;
         fDistanceField  = NULL;
         fMaskFormat     = MASK_FORMAT_UNKNOWN;
+        fForceBW        = 0;
     }
 
     /**
@@ -76,12 +78,6 @@
         return ID2Code(fID);
     }
 
-    unsigned getGlyphID(unsigned baseGlyphCount) const {
-        unsigned code = ID2Code(fID);
-        SkASSERT(code >= baseGlyphCount);
-        return code - baseGlyphCount;
-    }
-
     unsigned getSubX() const {
         return ID2SubX(fID);
     }
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp
index 2ab721a..ab816f9 100755
--- a/src/core/SkGlyphCache.cpp
+++ b/src/core/SkGlyphCache.cpp
@@ -339,7 +339,7 @@
             const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size,
                                         SkChunkAlloc::kReturnNil_AllocFailType);
             // check that alloc() actually succeeded
-            if (NULL != glyph.fImage) {
+            if (glyph.fImage) {
                 fScalerContext->getImage(glyph);
                 // TODO: the scaler may have changed the maskformat during
                 // getImage (e.g. from AA or LCD to BW) which means we may have
@@ -373,10 +373,10 @@
             }
             const void* image = this->findImage(glyph);
             // now generate the distance field
-            if (NULL != image) {
+            if (image) {
                 const_cast<SkGlyph&>(glyph).fDistanceField = fGlyphAlloc.alloc(size,
                                             SkChunkAlloc::kReturnNil_AllocFailType);
-                if (NULL != glyph.fDistanceField) {
+                if (glyph.fDistanceField) {
                     SkMask::Format maskFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
                     if (SkMask::kA8_Format == maskFormat) {
                         // make the distance field from the image
@@ -487,23 +487,6 @@
     this->internalPurge(fTotalMemoryUsed);
 }
 
-void SkGlyphCache::VisitAllCaches(bool (*proc)(SkGlyphCache*, void*),
-                                  void* context) {
-    SkGlyphCache_Globals& globals = getGlobals();
-    SkAutoMutexAcquire    ac(globals.fMutex);
-    SkGlyphCache*         cache;
-
-    globals.validate();
-
-    for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext) {
-        if (proc(cache, context)) {
-            break;
-        }
-    }
-
-    globals.validate();
-}
-
 /*  This guy calls the visitor from within the mutext lock, so the visitor
     cannot:
     - take too much time
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 4daf6b0..e27b34c 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -76,14 +76,6 @@
     */
     unsigned getGlyphCount();
 
-#ifdef SK_BUILD_FOR_ANDROID
-    /** Returns the base glyph count for this strike.
-    */
-    unsigned getBaseGlyphCount(SkUnichar charCode) const {
-        return fScalerContext->getBaseGlyphCount(charCode);
-    }
-#endif
-
     /** Return the image associated with the glyph. If it has not been generated
         this will trigger that.
     */
@@ -129,12 +121,6 @@
 
     SkScalerContext* getScalerContext() const { return fScalerContext; }
 
-    /** Call proc on all cache entries, stopping early if proc returns true.
-        The proc should not create or delete caches, since it could produce
-        deadlock.
-    */
-    static void VisitAllCaches(bool (*proc)(SkGlyphCache*, void*), void* ctx);
-
     /** Find a matching cache entry, and call proc() with it. If none is found
         create a new one. If the proc() returns true, detach the cache and
         return it, otherwise leave it and return NULL.
diff --git a/src/core/SkGraphics.cpp b/src/core/SkGraphics.cpp
index a89237f..2256e7f 100644
--- a/src/core/SkGraphics.cpp
+++ b/src/core/SkGraphics.cpp
@@ -128,6 +128,7 @@
 
 void SkGraphics::Term() {
     PurgeFontCache();
+    PurgeResourceCache();
     SkPaint::Term();
 }
 
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 4c4b56b..56c310d 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -8,11 +8,14 @@
 #include "SkImageFilter.h"
 
 #include "SkBitmap.h"
+#include "SkChecksum.h"
 #include "SkDevice.h"
+#include "SkLazyPtr.h"
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
 #include "SkRect.h"
 #include "SkTDynamicHash.h"
+#include "SkTInternalLList.h"
 #include "SkValidationUtils.h"
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
@@ -20,33 +23,106 @@
 #include "SkGr.h"
 #endif
 
-SkImageFilter::Cache* gExternalCache;
+enum { kDefaultCacheSize = 128 * 1024 * 1024 };
 
-SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect)
-  : fInputCount(inputCount),
-    fInputs(new SkImageFilter*[inputCount]),
-    fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)) {
-    for (int i = 0; i < inputCount; ++i) {
-        fInputs[i] = inputs[i];
-        SkSafeRef(fInputs[i]);
+static int32_t next_image_filter_unique_id() {
+    static int32_t gImageFilterUniqueID;
+
+    // Never return 0.
+    int32_t id;
+    do {
+        id = sk_atomic_inc(&gImageFilterUniqueID) + 1;
+    } while (0 == id);
+    return id;
+}
+
+struct SkImageFilter::Cache::Key {
+    Key(const uint32_t uniqueID, const SkMatrix& matrix, const SkIRect& clipBounds, uint32_t srcGenID)
+      : fUniqueID(uniqueID), fMatrix(matrix), fClipBounds(clipBounds), fSrcGenID(srcGenID) {
+        // Assert that Key is tightly-packed, since it is hashed.
+        SK_COMPILE_ASSERT(sizeof(Key) == sizeof(uint32_t) + sizeof(SkMatrix) + sizeof(SkIRect) +
+                                         sizeof(uint32_t), image_filter_key_tight_packing);
+        fMatrix.getType();  // force initialization of type, so hashes match
+    }
+    uint32_t fUniqueID;
+    SkMatrix fMatrix;
+    SkIRect fClipBounds;
+    uint32_t fSrcGenID;
+    bool operator==(const Key& other) const {
+        return fUniqueID == other.fUniqueID
+            && fMatrix == other.fMatrix
+            && fClipBounds == other.fClipBounds
+            && fSrcGenID == other.fSrcGenID;
+    }
+};
+
+SkImageFilter::Common::~Common() {
+    for (int i = 0; i < fInputs.count(); ++i) {
+        SkSafeUnref(fInputs[i]);
     }
 }
 
-SkImageFilter::SkImageFilter(SkImageFilter* input, const CropRect* cropRect)
-  : fInputCount(1),
-    fInputs(new SkImageFilter*[1]),
-    fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)) {
-    fInputs[0] = input;
-    SkSafeRef(fInputs[0]);
+void SkImageFilter::Common::allocInputs(int count) {
+    const size_t size = count * sizeof(SkImageFilter*);
+    fInputs.reset(count);
+    sk_bzero(fInputs.get(), size);
 }
 
-SkImageFilter::SkImageFilter(SkImageFilter* input1, SkImageFilter* input2, const CropRect* cropRect)
-  : fInputCount(2), fInputs(new SkImageFilter*[2]),
-    fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)) {
-    fInputs[0] = input1;
-    fInputs[1] = input2;
-    SkSafeRef(fInputs[0]);
-    SkSafeRef(fInputs[1]);
+void SkImageFilter::Common::detachInputs(SkImageFilter** inputs) {
+    const size_t size = fInputs.count() * sizeof(SkImageFilter*);
+    memcpy(inputs, fInputs.get(), size);
+    sk_bzero(fInputs.get(), size);
+}
+
+bool SkImageFilter::Common::unflatten(SkReadBuffer& buffer, int expectedCount) {
+    const int count = buffer.readInt();
+    if (!buffer.validate(count >= 0)) {
+        return false;
+    }
+    if (!buffer.validate(expectedCount < 0 || count == expectedCount)) {
+        return false;
+    }
+
+    this->allocInputs(count);
+    for (int i = 0; i < count; i++) {
+        if (buffer.readBool()) {
+            fInputs[i] = buffer.readImageFilter();
+        }
+        if (!buffer.isValid()) {
+            return false;
+        }
+    }
+    SkRect rect;
+    buffer.readRect(&rect);
+    if (!buffer.isValid() || !buffer.validate(SkIsValidRect(rect))) {
+        return false;
+    }
+    
+    uint32_t flags = buffer.readUInt();
+    fCropRect = CropRect(rect, flags);
+    if (buffer.isVersionLT(SkReadBuffer::kImageFilterUniqueID_Version)) {
+        fUniqueID = next_image_filter_unique_id();
+    } else {
+        fUniqueID = buffer.readUInt();
+    }
+    return buffer.isValid();
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect, uint32_t uniqueID)
+  : fInputCount(inputCount),
+    fInputs(new SkImageFilter*[inputCount]),
+    fUsesSrcInput(false),
+    fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)),
+    fUniqueID(uniqueID ? uniqueID : next_image_filter_unique_id()) {
+    for (int i = 0; i < inputCount; ++i) {
+        if (NULL == inputs[i] || inputs[i]->usesSrcInput()) {
+            fUsesSrcInput = true;
+        }
+        fInputs[i] = inputs[i];
+        SkSafeRef(fInputs[i]);
+    }
 }
 
 SkImageFilter::~SkImageFilter() {
@@ -56,27 +132,20 @@
     delete[] fInputs;
 }
 
-SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer) {
-    fInputCount = buffer.readInt();
-    if (buffer.validate((fInputCount >= 0) && ((inputCount < 0) || (fInputCount == inputCount)))) {
-        fInputs = new SkImageFilter*[fInputCount];
-        for (int i = 0; i < fInputCount; i++) {
-            if (buffer.readBool()) {
-                fInputs[i] = buffer.readImageFilter();
-            } else {
-                fInputs[i] = NULL;
-            }
-            if (!buffer.isValid()) {
-                fInputCount = i; // Do not use fInputs past that point in the destructor
-                break;
+SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer)
+  : fUsesSrcInput(false) {
+    Common common;
+    if (common.unflatten(buffer, inputCount)) {
+        fCropRect = common.cropRect();
+        fInputCount = common.inputCount();
+        fInputs = SkNEW_ARRAY(SkImageFilter*, fInputCount);
+        common.detachInputs(fInputs);
+        for (int i = 0; i < fInputCount; ++i) {
+            if (NULL == fInputs[i] || fInputs[i]->usesSrcInput()) {
+                fUsesSrcInput = true;
             }
         }
-        SkRect rect;
-        buffer.readRect(&rect);
-        if (buffer.isValid() && buffer.validate(SkIsValidRect(rect))) {
-            uint32_t flags = buffer.readUInt();
-            fCropRect = CropRect(rect, flags);
-        }
+        fUniqueID = buffer.isCrossProcess() ? next_image_filter_unique_id() : common.uniqueID();
     } else {
         fInputCount = 0;
         fInputs = NULL;
@@ -94,17 +163,20 @@
     }
     buffer.writeRect(fCropRect.rect());
     buffer.writeUInt(fCropRect.flags());
+    buffer.writeUInt(fUniqueID);
 }
 
 bool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src,
                                 const Context& context,
                                 SkBitmap* result, SkIPoint* offset) const {
-    Cache* cache = context.cache();
     SkASSERT(result);
     SkASSERT(offset);
-    SkASSERT(cache);
-    if (cache->get(this, result, offset)) {
-        return true;
+    uint32_t srcGenID = fUsesSrcInput ? src.getGenerationID() : 0;
+    Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), srcGenID);
+    if (context.cache()) {
+        if (context.cache()->get(key, result, offset)) {
+            return true;
+        }
     }
     /*
      *  Give the proxy first shot at the filter. If it returns false, ask
@@ -112,7 +184,9 @@
      */
     if ((proxy && proxy->filterImage(this, src, context, result, offset)) ||
         this->onFilterImage(proxy, src, context, result, offset)) {
-        cache->set(this, *result, *offset);
+        if (context.cache()) {
+            context.cache()->set(key, *result, *offset);
+        }
         return true;
     }
     return false;
@@ -122,16 +196,6 @@
                                  SkIRect* dst) const {
     SkASSERT(&src);
     SkASSERT(dst);
-    if (SkImageFilter::GetExternalCache()) {
-        /*
-         *  When the external cache is active, do not intersect the saveLayer
-         *  bounds with the clip bounds. This is so that the cached result
-         *  is always the full size of the primitive's bounds,
-         *  regardless of the clip active on first draw.
-         */
-        *dst = SkIRect::MakeLargest();
-        return true;
-    }
     return this->onFilterBounds(src, ctm, dst);
 }
 
@@ -163,7 +227,7 @@
 }
 
 bool SkImageFilter::canFilterImageGPU() const {
-    return this->asNewEffect(NULL, NULL, SkMatrix::I(), SkIRect());
+    return this->asFragmentProcessor(NULL, NULL, SkMatrix::I(), SkIRect());
 }
 
 bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
@@ -192,21 +256,23 @@
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
     GrAutoScratchTexture dst(context, desc);
+    if (NULL == dst.texture()) {
+        return false;
+    }
     GrContext::AutoMatrix am;
     am.setIdentity(context);
     GrContext::AutoRenderTarget art(context, dst.texture()->asRenderTarget());
     GrContext::AutoClip acs(context, dstRect);
-    GrEffectRef* effect;
+    GrFragmentProcessor* fp;
     offset->fX = bounds.left();
     offset->fY = bounds.top();
     bounds.offset(-srcOffset);
     SkMatrix matrix(ctx.ctm());
     matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
-    this->asNewEffect(&effect, srcTexture, matrix, bounds);
-    SkASSERT(effect);
-    SkAutoUnref effectRef(effect);
+    this->asFragmentProcessor(&fp, srcTexture, matrix, bounds);
+    SkASSERT(fp);
     GrPaint paint;
-    paint.addColorEffect(effect);
+    paint.addColorProcessor(fp)->unref();
     context->drawRectToRect(paint, dstRect, srcRect);
 
     SkAutoTUnref<GrTexture> resultTex(dst.detach());
@@ -299,7 +365,8 @@
     return true;
 }
 
-bool SkImageFilter::asNewEffect(GrEffectRef**, GrTexture*, const SkMatrix&, const SkIRect&) const {
+bool SkImageFilter::asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+                                        const SkIRect&) const {
     return false;
 }
 
@@ -307,14 +374,6 @@
     return false;
 }
 
-void SkImageFilter::SetExternalCache(Cache* cache) {
-    SkRefCnt_SafeAssign(gExternalCache, cache);
-}
-
-SkImageFilter::Cache* SkImageFilter::GetExternalCache() {
-    return gExternalCache;
-}
-
 #if SK_SUPPORT_GPU
 
 void SkImageFilter::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) {
@@ -352,42 +411,23 @@
 }
 #endif
 
-static uint32_t compute_hash(const uint32_t* data, int count) {
-    uint32_t hash = 0;
-
-    for (int i = 0; i < count; ++i) {
-        uint32_t k = data[i];
-        k *= 0xcc9e2d51;
-        k = (k << 15) | (k >> 17);
-        k *= 0x1b873593;
-
-        hash ^= k;
-        hash = (hash << 13) | (hash >> 19);
-        hash *= 5;
-        hash += 0xe6546b64;
-    }
-
-    //    hash ^= size;
-    hash ^= hash >> 16;
-    hash *= 0x85ebca6b;
-    hash ^= hash >> 13;
-    hash *= 0xc2b2ae35;
-    hash ^= hash >> 16;
-
-    return hash;
-}
+namespace {
 
 class CacheImpl : public SkImageFilter::Cache {
 public:
-    explicit CacheImpl(int minChildren) : fMinChildren(minChildren) {}
-    virtual ~CacheImpl();
-    bool get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
-    void set(const SkImageFilter* key, const SkBitmap& result, const SkIPoint& offset) SK_OVERRIDE;
-    void remove(const SkImageFilter* key) SK_OVERRIDE;
-private:
-    typedef const SkImageFilter* Key;
+    CacheImpl(size_t maxBytes) : fMaxBytes(maxBytes), fCurrentBytes(0) {
+    }
+    virtual ~CacheImpl() {
+        SkTDynamicHash<Value, Key>::Iter iter(&fLookup);
+
+        while (!iter.done()) {
+            Value* v = &*iter;
+            ++iter;
+            delete v;
+        }
+    }
     struct Value {
-        Value(Key key, const SkBitmap& bitmap, const SkIPoint& offset)
+        Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset)
             : fKey(key), fBitmap(bitmap), fOffset(offset) {}
         Key fKey;
         SkBitmap fBitmap;
@@ -395,48 +435,68 @@
         static const Key& GetKey(const Value& v) {
             return v.fKey;
         }
-        static uint32_t Hash(Key key) {
-            return compute_hash(reinterpret_cast<const uint32_t*>(&key), sizeof(Key) / sizeof(uint32_t));
+        static uint32_t Hash(const Key& key) {
+            return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&key), sizeof(Key));
         }
+        SK_DECLARE_INTERNAL_LLIST_INTERFACE(Value);
     };
-    SkTDynamicHash<Value, Key> fData;
-    int fMinChildren;
+    virtual bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const {
+        SkAutoMutexAcquire mutex(fMutex);
+        if (Value* v = fLookup.find(key)) {
+            *result = v->fBitmap;
+            *offset = v->fOffset;
+            if (v != fLRU.head()) {
+                fLRU.remove(v);
+                fLRU.addToHead(v);
+            }
+            return true;
+        }
+        return false;
+    }
+    virtual void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) {
+        SkAutoMutexAcquire mutex(fMutex);
+        if (Value* v = fLookup.find(key)) {
+            removeInternal(v);
+        }
+        Value* v = new Value(key, result, offset);
+        fLookup.add(v);
+        fLRU.addToHead(v);
+        fCurrentBytes += result.getSize();
+        while (fCurrentBytes > fMaxBytes) {
+            Value* tail = fLRU.tail();
+            SkASSERT(tail);
+            if (tail == v) {
+                break;
+            }
+            removeInternal(tail);
+        }
+    }
+private:
+    void removeInternal(Value* v) {
+        fCurrentBytes -= v->fBitmap.getSize();
+        fLRU.remove(v);
+        fLookup.remove(v->fKey);
+        delete v;
+    }
+private:
+    SkTDynamicHash<Value, Key>         fLookup;
+    mutable SkTInternalLList<Value>    fLRU;
+    size_t                             fMaxBytes;
+    size_t                             fCurrentBytes;
+    mutable SkMutex                    fMutex;
 };
 
-bool CacheImpl::get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) {
-    Value* v = fData.find(key);
-    if (v) {
-        *result = v->fBitmap;
-        *offset = v->fOffset;
-        return true;
-    }
-    return false;
+SkImageFilter::Cache* CreateCache() {
+    return SkImageFilter::Cache::Create(kDefaultCacheSize);
 }
 
-void CacheImpl::remove(const SkImageFilter* key) {
-    Value* v = fData.find(key);
-    if (v) {
-        fData.remove(key);
-        delete v;
-    }
+} // namespace
+
+SkImageFilter::Cache* SkImageFilter::Cache::Create(size_t maxBytes) {
+    return SkNEW_ARGS(CacheImpl, (maxBytes));
 }
 
-void CacheImpl::set(const SkImageFilter* key, const SkBitmap& result, const SkIPoint& offset) {
-    if (key->getRefCnt() >= fMinChildren) {
-        fData.add(new Value(key, result, offset));
-    }
-}
-
-SkImageFilter::Cache* SkImageFilter::Cache::Create(int minChildren) {
-    return new CacheImpl(minChildren);
-}
-
-CacheImpl::~CacheImpl() {
-    SkTDynamicHash<Value, Key>::Iter iter(&fData);
-
-    while (!iter.done()) {
-        Value* v = &*iter;
-        ++iter;
-        delete v;
-    }
+SkImageFilter::Cache* SkImageFilter::Cache::Get() {
+    SK_DECLARE_STATIC_LAZY_PTR(SkImageFilter::Cache, cache, CreateCache);
+    return cache.get();
 }
diff --git a/src/core/SkImageGenerator.cpp b/src/core/SkImageGenerator.cpp
index daa55a3..c062978 100644
--- a/src/core/SkImageGenerator.cpp
+++ b/src/core/SkImageGenerator.cpp
@@ -57,6 +57,58 @@
 }
 #endif
 
+bool SkImageGenerator::getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+                                     SkYUVColorSpace* colorSpace) {
+#ifdef SK_DEBUG
+    // In all cases, we need the sizes array
+    SkASSERT(sizes);
+
+    bool isValidWithPlanes = (planes) && (rowBytes) &&
+        ((planes[0]) && (planes[1]) && (planes[2]) &&
+         (0  != rowBytes[0]) && (0  != rowBytes[1]) && (0  != rowBytes[2]));
+    bool isValidWithoutPlanes =
+        ((NULL == planes) ||
+         ((NULL == planes[0]) && (NULL == planes[1]) && (NULL == planes[2]))) &&
+        ((NULL == rowBytes) ||
+         ((0 == rowBytes[0]) && (0 == rowBytes[1]) && (0 == rowBytes[2])));
+
+    // Either we have all planes and rowBytes information or we have none of it
+    // Having only partial information is not supported
+    SkASSERT(isValidWithPlanes || isValidWithoutPlanes);
+
+    // If we do have planes information, make sure all sizes are non 0
+    // and all rowBytes are valid
+    SkASSERT(!isValidWithPlanes ||
+             ((sizes[0].fWidth  >= 0) &&
+              (sizes[0].fHeight >= 0) &&
+              (sizes[1].fWidth  >= 0) &&
+              (sizes[1].fHeight >= 0) &&
+              (sizes[2].fWidth  >= 0) &&
+              (sizes[2].fHeight >= 0) &&
+              (rowBytes[0] >= (size_t)sizes[0].fWidth) &&
+              (rowBytes[1] >= (size_t)sizes[1].fWidth) &&
+              (rowBytes[2] >= (size_t)sizes[2].fWidth)));
+#endif
+
+    return this->onGetYUV8Planes(sizes, planes, rowBytes, colorSpace);
+}
+
+bool SkImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]) {
+    return false;
+}
+
+bool SkImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+                                       SkYUVColorSpace* colorSpace) {
+    // In order to maintain compatibility with clients that implemented the original
+    // onGetYUV8Planes interface, we assume that the color space is JPEG.
+    // TODO(rileya): remove this and the old onGetYUV8Planes once clients switch over to
+    // the new interface.
+    if (colorSpace) {
+        *colorSpace = kJPEG_SkYUVColorSpace;
+    }
+    return this->onGetYUV8Planes(sizes, planes, rowBytes);
+}
+
 /////////////////////////////////////////////////////////////////////////////////////////////
 
 SkData* SkImageGenerator::onRefEncodedData() {
diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp
index 27c4573..e61cd7d 100644
--- a/src/core/SkImageInfo.cpp
+++ b/src/core/SkImageInfo.cpp
@@ -38,3 +38,34 @@
     uint32_t packed = (fAlphaType << 8) | fColorType;
     buffer.write32(packed);
 }
+
+bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
+                                  SkAlphaType* canonical) {
+    switch (colorType) {
+        case kUnknown_SkColorType:
+            alphaType = kIgnore_SkAlphaType;
+            break;
+        case kAlpha_8_SkColorType:
+            if (kUnpremul_SkAlphaType == alphaType) {
+                alphaType = kPremul_SkAlphaType;
+            }
+            // fall-through
+        case kIndex_8_SkColorType:
+        case kARGB_4444_SkColorType:
+        case kRGBA_8888_SkColorType:
+        case kBGRA_8888_SkColorType:
+            if (kIgnore_SkAlphaType == alphaType) {
+                return false;
+            }
+            break;
+        case kRGB_565_SkColorType:
+            alphaType = kOpaque_SkAlphaType;
+            break;
+        default:
+            return false;
+    }
+    if (canonical) {
+        *canonical = alphaType;
+    }
+    return true;
+}
diff --git a/src/core/SkLazyPtr.h b/src/core/SkLazyPtr.h
index c25d3c8..13218a7 100644
--- a/src/core/SkLazyPtr.h
+++ b/src/core/SkLazyPtr.h
@@ -88,14 +88,26 @@
 template <typename T> T* sk_new() { return SkNEW(T); }
 template <typename T> void sk_delete(T* ptr) { SkDELETE(ptr); }
 
+// We're basing these implementations here on this article:
+//   http://preshing.com/20140709/the-purpose-of-memory_order_consume-in-cpp11/
+//
+// Because the users of SkLazyPtr and SkLazyPtrArray will read the pointers
+// _through_ our atomically set pointer, there is a data dependency between our
+// atomic and the guarded data, and so we only need writer-releases /
+// reader-consumes memory pairing rather than the more general write-releases /
+// reader-acquires convention.
+//
+// This is nice, because a sk_consume_load is free on all our platforms: x86,
+// ARM, MIPS.  In contrast, sk_acquire_load issues a memory barrier on non-x86.
+
 // This has no constructor and must be zero-initalized (the macro above does this).
 template <typename T, T* (*Create)() = sk_new<T>, void (*Destroy)(T*) = sk_delete<T> >
 class SkLazyPtr {
 public:
     T* get() {
-        // If fPtr has already been filled, we need an acquire barrier when loading it.
+        // If fPtr has already been filled, we need a consume barrier when loading it.
         // If not, we need a release barrier when setting it.  try_cas will do that.
-        T* ptr = (T*)sk_acquire_load(&fPtr);
+        T* ptr = (T*)sk_consume_load(&fPtr);
         return ptr ? ptr : try_cas<T*, Destroy>(&fPtr, Create());
     }
 
@@ -122,9 +134,9 @@
 public:
     T* operator[](int i) {
         SkASSERT(i >= 0 && i < N);
-        // If fPtr has already been filled, we need an acquire barrier when loading it.
+        // If fPtr has already been filled, we need an consume barrier when loading it.
         // If not, we need a release barrier when setting it.  try_cas will do that.
-        T* ptr = (T*)sk_acquire_load(&fArray[i]);
+        T* ptr = (T*)sk_consume_load(&fArray[i]);
         return ptr ? ptr : try_cas<T*, Destroy>(&fArray[i], Create(i));
     }
 
diff --git a/src/core/SkLocalMatrixShader.cpp b/src/core/SkLocalMatrixShader.cpp
index 53580e6..62840dd 100644
--- a/src/core/SkLocalMatrixShader.cpp
+++ b/src/core/SkLocalMatrixShader.cpp
@@ -7,17 +7,30 @@
 
 #include "SkLocalMatrixShader.h"
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLocalMatrixShader::SkLocalMatrixShader(SkReadBuffer& buffer) : INHERITED(buffer) {
-    buffer.readMatrix(&fProxyLocalMatrix);
+    if (buffer.isVersionLT(SkReadBuffer::kSimplifyLocalMatrix_Version)) {
+        buffer.readMatrix(&(INHERITED::fLocalMatrix));
+    }
     fProxyShader.reset(buffer.readShader());
     if (NULL == fProxyShader.get()) {
         sk_throw();
     }
 }
+#endif
+
+SkFlattenable* SkLocalMatrixShader::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix lm;
+    buffer.readMatrix(&lm);
+    SkAutoTUnref<SkShader> shader(buffer.readShader());
+    if (!shader.get()) {
+        return NULL;
+    }
+    return SkShader::CreateLocalMatrixShader(shader, lm);
+}
 
 void SkLocalMatrixShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-    buffer.writeMatrix(fProxyLocalMatrix);
+    buffer.writeMatrix(this->getLocalMatrix());
     buffer.writeFlattenable(fProxyShader.get());
 }
 
@@ -26,10 +39,10 @@
     ContextRec newRec(rec);
     SkMatrix tmp;
     if (rec.fLocalMatrix) {
-        tmp.setConcat(fProxyLocalMatrix, *rec.fLocalMatrix);
+        tmp.setConcat(*rec.fLocalMatrix, this->getLocalMatrix());
         newRec.fLocalMatrix = &tmp;
     } else {
-        newRec.fLocalMatrix = &fProxyLocalMatrix;
+        newRec.fLocalMatrix = &this->getLocalMatrix();
     }
     return fProxyShader->createContext(newRec, storage);
 }
diff --git a/src/core/SkLocalMatrixShader.h b/src/core/SkLocalMatrixShader.h
index 1143f06..b8e4714 100644
--- a/src/core/SkLocalMatrixShader.h
+++ b/src/core/SkLocalMatrixShader.h
@@ -15,8 +15,8 @@
 class SkLocalMatrixShader : public SkShader {
 public:
     SkLocalMatrixShader(SkShader* proxy, const SkMatrix& localMatrix)
-    : fProxyShader(SkRef(proxy))
-    , fProxyLocalMatrix(localMatrix)
+    : INHERITED(&localMatrix)
+    , fProxyShader(SkRef(proxy))
     {}
 
     virtual size_t contextSize() const SK_OVERRIDE {
@@ -34,19 +34,20 @@
 
 #if SK_SUPPORT_GPU
     
-    virtual bool asNewEffect(GrContext* context, const SkPaint& paint, const SkMatrix* localMatrix,
-                             GrColor* grColor, GrEffectRef** grEffect) const SK_OVERRIDE {
-        SkMatrix tmp = fProxyLocalMatrix;
+    virtual bool asFragmentProcessor(GrContext* context, const SkPaint& paint,
+                                     const SkMatrix* localMatrix, GrColor* grColor,
+                                     GrFragmentProcessor** fp) const SK_OVERRIDE {
+        SkMatrix tmp = this->getLocalMatrix();
         if (localMatrix) {
             tmp.preConcat(*localMatrix);
         }
-        return fProxyShader->asNewEffect(context, paint, &tmp, grColor, grEffect);
+        return fProxyShader->asFragmentProcessor(context, paint, &tmp, grColor, fp);
     }
     
 #else 
     
-    virtual bool asNewEffect(GrContext* context, const SkPaint& paint, const SkMatrix* localMatrix,
-                             GrColor* grColor, GrEffectRef** grEffect) const SK_OVERRIDE {
+    virtual bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                     GrFragmentProcessor**) const SK_OVERRIDE {
         SkDEBUGFAIL("Should not call in GPU-less build");
         return false;
     }
@@ -55,7 +56,7 @@
     
     virtual SkShader* refAsALocalMatrixShader(SkMatrix* localMatrix) const SK_OVERRIDE {
         if (localMatrix) {
-            *localMatrix = fProxyLocalMatrix;
+            *localMatrix = this->getLocalMatrix();
         }
         return SkRef(fProxyShader.get());
     }
@@ -64,13 +65,14 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLocalMatrixShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkLocalMatrixShader(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE;
 
 private:
     SkAutoTUnref<SkShader> fProxyShader;
-    SkMatrix  fProxyLocalMatrix;
 
     typedef SkShader INHERITED;
 };
diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp
index 12cb05b..f4ba969 100644
--- a/src/core/SkMallocPixelRef.cpp
+++ b/src/core/SkMallocPixelRef.cpp
@@ -16,10 +16,9 @@
 }
 
 static bool is_valid(const SkImageInfo& info, SkColorTable* ctable) {
-    if (info.fWidth < 0 ||
-        info.fHeight < 0 ||
-        (unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType ||
-        (unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType)
+    if (info.width() < 0 || info.height() < 0 ||
+        (unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType ||
+        (unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType)
     {
         return false;
     }
@@ -31,7 +30,7 @@
     if (kIndex8_SkColorType == info.fColorType && NULL == ctable) {
         return false;
     }
-    if (kIndex8_SkColorType != info.fColorType && NULL != ctable) {
+    if (kIndex8_SkColorType != info.fColorType && ctable) {
         return false;
     }
 #endif
@@ -72,7 +71,7 @@
         rowBytes = minRB;
     }
 
-    int64_t bigSize = (int64_t)info.fHeight * rowBytes;
+    int64_t bigSize = (int64_t)info.height() * rowBytes;
     if (!sk_64_isS32(bigSize)) {
         return NULL;
     }
@@ -142,7 +141,7 @@
     SkASSERT(is_valid(info, ctable));
     SkASSERT(rowBytes >= info.minRowBytes());
 
-    if (kIndex_8_SkColorType != info.fColorType) {
+    if (kIndex_8_SkColorType != info.colorType()) {
         ctable = NULL;
     }
 
@@ -165,7 +164,7 @@
     SkASSERT(is_valid(info, ctable));
     SkASSERT(rowBytes >= info.minRowBytes());
 
-    if (kIndex_8_SkColorType != info.fColorType) {
+    if (kIndex_8_SkColorType != info.colorType()) {
         ctable = NULL;
     }
 
@@ -200,47 +199,9 @@
     return this->info().getSafeSize(fRB);
 }
 
-void SkMallocPixelRef::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
-    buffer.write32(SkToU32(fRB));
-
-    // TODO: replace this bulk write with a chunky one that can trim off any
-    // trailing bytes on each scanline (in case rowbytes > width*size)
-    size_t size = this->info().getSafeSize(fRB);
-    buffer.writeByteArray(fStorage, size);
-    buffer.writeBool(fCTable != NULL);
-    if (fCTable) {
-        fCTable->writeToBuffer(buffer);
-    }
-}
-
-SkMallocPixelRef::SkMallocPixelRef(SkReadBuffer& buffer)
-    : INHERITED(buffer, NULL)
-    , fReleaseProc(sk_free_releaseproc)
-    , fReleaseProcContext(NULL)
-{
-    fRB = buffer.read32();
-    size_t size = buffer.isValid() ? this->info().getSafeSize(fRB) : 0;
-    if (buffer.validateAvailable(size)) {
-        fStorage = sk_malloc_throw(size);
-        buffer.readByteArray(fStorage, size);
-    } else {
-        fStorage = NULL;
-    }
-
-    if (buffer.readBool()) {
-        fCTable = SkNEW_ARGS(SkColorTable, (buffer));
-    } else {
-        fCTable = NULL;
-    }
-
-    this->setPreLocked(fStorage, fRB, fCTable);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
-SkPixelRef* SkMallocPixelRef::PRFactory::create(const SkImageInfo& info,
+SkPixelRef* SkMallocPixelRef::PRFactory::create(const SkImageInfo& info, size_t rowBytes,
                                                 SkColorTable* ctable) {
-    return SkMallocPixelRef::NewAllocate(info, info.minRowBytes(), ctable);
+    return SkMallocPixelRef::NewAllocate(info, rowBytes, ctable);
 }
diff --git a/src/core/SkMaskFilter.cpp b/src/core/SkMaskFilter.cpp
index 2ab2843..86f303c 100644
--- a/src/core/SkMaskFilter.cpp
+++ b/src/core/SkMaskFilter.cpp
@@ -298,7 +298,7 @@
 }
 
 #if SK_SUPPORT_GPU
-bool SkMaskFilter::asNewEffect(GrEffectRef** effect, GrTexture*, const SkMatrix&) const {
+bool SkMaskFilter::asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&) const {
     return false;
 }
 
diff --git a/src/core/SkMaskGamma.h b/src/core/SkMaskGamma.h
index 08ed97f..fb67c1a 100644
--- a/src/core/SkMaskGamma.h
+++ b/src/core/SkMaskGamma.h
@@ -194,9 +194,7 @@
     ~SkTMaskPreBlend() { }
 
     /** True if this PreBlend should be applied. When false, fR, fG, and fB are NULL. */
-    bool isApplicable() const {
-        return NULL != this->fG;
-    }
+    bool isApplicable() const { return SkToBool(this->fG); }
 
     const uint8_t* fR;
     const uint8_t* fG;
diff --git a/src/core/SkMathPriv.h b/src/core/SkMathPriv.h
index f93ab61..e997045 100644
--- a/src/core/SkMathPriv.h
+++ b/src/core/SkMathPriv.h
@@ -10,6 +10,12 @@
 
 #include "SkMath.h"
 
+#ifdef SK_BUILD_FOR_IOS
+// The iOS ARM processor discards small denormalized numbers to go faster.
+// Algorithms that rely on denormalized numbers need alternative implementations.
+#define SK_DISCARD_DENORMALIZED_FOR_SPEED
+#endif
+
 /** Returns -1 if n < 0, else returns 0
  */
 #define SkExtractSign(n)    ((int32_t)(n) >> 31)
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
index 95662fc..956cf46 100644
--- a/src/core/SkMatrix.cpp
+++ b/src/core/SkMatrix.cpp
@@ -176,20 +176,16 @@
         return false;
     }
 
-    // it has scales and skews, but it could also be rotation, check it out.
-    SkVector vec[2];
-    vec[0].set(mx, sx);
-    vec[1].set(sy, my);
-
-    return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) &&
-           SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(),
-                               SkScalarSquare(tol));
+    // upper 2x2 is rotation/reflection + uniform scale if basis vectors
+    // are 90 degree rotations of each other
+    return (SkScalarNearlyEqual(mx, my, tol) && SkScalarNearlyEqual(sx, -sy, tol))
+        || (SkScalarNearlyEqual(mx, -my, tol) && SkScalarNearlyEqual(sx, sy, tol));
 }
 
 bool SkMatrix::preservesRightAngles(SkScalar tol) const {
     TypeMask mask = this->getType();
 
-    if (mask <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
+    if (mask <= kTranslate_Mask) {
         // identity, translate and/or scale
         return true;
     }
@@ -197,7 +193,7 @@
         return false;
     }
 
-    SkASSERT(mask & kAffine_Mask);
+    SkASSERT(mask & (kAffine_Mask | kScale_Mask));
 
     SkScalar mx = fMat[kMScaleX];
     SkScalar my = fMat[kMScaleY];
@@ -208,14 +204,12 @@
         return false;
     }
 
-    // it has scales and skews, but it could also be rotation, check it out.
+    // upper 2x2 is scale + rotation/reflection if basis vectors are orthogonal
     SkVector vec[2];
-    vec[0].set(mx, sx);
-    vec[1].set(sy, my);
+    vec[0].set(mx, sy);
+    vec[1].set(sx, my);
 
-    return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) &&
-           SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(),
-                               SkScalarSquare(tol));
+    return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1067,7 +1061,7 @@
 }
 
 bool SkMatrix::mapRect(SkRect* dst, const SkRect& src) const {
-    SkASSERT(dst && &src);
+    SkASSERT(dst);
 
     if (this->rectStaysRect()) {
         this->mapPoints((SkPoint*)dst, (const SkPoint*)&src, 2);
@@ -1772,15 +1766,15 @@
         sin1 = -sin1;
     }
 
-    if (NULL != scale) {
+    if (scale) {
         scale->fX = SkDoubleToScalar(w1);
         scale->fY = SkDoubleToScalar(w2);
     }
-    if (NULL != rotation1) {
+    if (rotation1) {
         rotation1->fX = cos1;
         rotation1->fY = sin1;
     }
-    if (NULL != rotation2) {
+    if (rotation2) {
         rotation2->fX = cos2;
         rotation2->fY = sin2;
     }
diff --git a/src/core/SkMatrixClipStateMgr.cpp b/src/core/SkMatrixClipStateMgr.cpp
deleted file mode 100644
index 1fc7fe8..0000000
--- a/src/core/SkMatrixClipStateMgr.cpp
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * 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 "SkMatrixClipStateMgr.h"
-#include "SkPictureRecord.h"
-
-bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipPath(SkPictureRecord* picRecord,
-                                                               const SkPath& path,
-                                                               SkRegion::Op op,
-                                                               bool doAA,
-                                                               int matrixID) {
-    int pathID = picRecord->addPathToHeap(path);
-
-    ClipOp* newClip = fClips.append();
-    newClip->fClipType = kPath_ClipType;
-    newClip->fGeom.fPathID = pathID;
-    newClip->fOp = op;
-    newClip->fDoAA = doAA;
-    newClip->fMatrixID = matrixID;
-    return false;
-}
-
-bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipRegion(SkPictureRecord* picRecord,
-                                                                 int regionID,
-                                                                 SkRegion::Op op,
-                                                                 int matrixID) {
-    ClipOp* newClip = fClips.append();
-    newClip->fClipType = kRegion_ClipType;
-    newClip->fGeom.fRegionID = regionID;
-    newClip->fOp = op;
-    newClip->fDoAA = true;      // not necessary but sanity preserving
-    newClip->fMatrixID = matrixID;
-    return false;
-}
-
-void SkMatrixClipStateMgr::writeDeltaMat(int currentMatID, int desiredMatID) {
-    const SkMatrix& current = this->lookupMat(currentMatID);
-    const SkMatrix& desired = this->lookupMat(desiredMatID);
-
-    SkMatrix delta;
-    bool result = current.invert(&delta);
-    if (result) {
-        delta.preConcat(desired);
-    }
-    fPicRecord->recordConcat(delta);
-}
-
-// Note: this only writes out the clips for the current save state. To get the
-// entire clip stack requires iterating of the entire matrix/clip stack.
-void SkMatrixClipStateMgr::MatrixClipState::ClipInfo::writeClip(int* curMatID,
-                                                                SkMatrixClipStateMgr* mgr) {
-    for (int i = 0; i < fClips.count(); ++i) {
-        ClipOp& curClip = fClips[i];
-
-        // TODO: use the matrix ID to skip writing the identity matrix
-        // over and over, i.e.:
-        //  if (*curMatID != curClip.fMatrixID) {
-        //      mgr->writeDeltaMat...
-        //      *curMatID...
-        //  }
-        // Right now this optimization would throw off the testing harness.
-        // TODO: right now we're writing out the delta matrix from the prior
-        // matrix state. This is a side-effect of writing out the entire
-        // clip stack and should be resolved when that is fixed.
-        mgr->writeDeltaMat(*curMatID, curClip.fMatrixID);
-        *curMatID = curClip.fMatrixID;
-
-        size_t offset = 0;
-
-        switch (curClip.fClipType) {
-        case kRect_ClipType:
-            offset = mgr->getPicRecord()->recordClipRect(curClip.fGeom.fRRect.rect(),
-                                                         curClip.fOp, curClip.fDoAA);
-            break;
-        case kRRect_ClipType:
-            offset = mgr->getPicRecord()->recordClipRRect(curClip.fGeom.fRRect, curClip.fOp,
-                                                         curClip.fDoAA);
-            break;
-        case kPath_ClipType:
-            offset = mgr->getPicRecord()->recordClipPath(curClip.fGeom.fPathID, curClip.fOp,
-                                                         curClip.fDoAA);
-            break;
-        case kRegion_ClipType: {
-            const SkRegion* region = mgr->lookupRegion(curClip.fGeom.fRegionID);
-            offset = mgr->getPicRecord()->recordClipRegion(*region, curClip.fOp);
-            break;
-        }
-        default:
-            SkASSERT(0);
-        }
-
-        mgr->addClipOffset(offset);
-    }
-}
-
-SkMatrixClipStateMgr::SkMatrixClipStateMgr()
-    : fPicRecord(NULL)
-    , fMatrixClipStack(sizeof(MatrixClipState),
-                       fMatrixClipStackStorage,
-                       sizeof(fMatrixClipStackStorage))
-    , fCurOpenStateID(kIdentityWideOpenStateID) {
-
-    fSkipOffsets = SkNEW(SkTDArray<int>);
-
-    // The first slot in the matrix dictionary is reserved for the identity matrix
-    fMatrixDict.append()->reset();
-
-    fCurMCState = (MatrixClipState*)fMatrixClipStack.push_back();
-    new (fCurMCState) MatrixClipState(NULL, 0);    // balanced in restore()
-
-#ifdef SK_DEBUG
-    fActualDepth = 0;
-#endif
-}
-
-SkMatrixClipStateMgr::~SkMatrixClipStateMgr() {
-    for (int i = 0; i < fRegionDict.count(); ++i) {
-        SkDELETE(fRegionDict[i]);
-    }
-
-    SkDELETE(fSkipOffsets);
-}
-
-
-int SkMatrixClipStateMgr::MCStackPush(SkCanvas::SaveFlags flags) {
-    MatrixClipState* newTop = (MatrixClipState*)fMatrixClipStack.push_back();
-    new (newTop) MatrixClipState(fCurMCState, flags); // balanced in restore()
-    fCurMCState = newTop;
-
-    SkDEBUGCODE(this->validate();)
-
-    return fMatrixClipStack.count();
-}
-
-int SkMatrixClipStateMgr::save(SkCanvas::SaveFlags flags) {
-    SkDEBUGCODE(this->validate();)
-
-    return this->MCStackPush(flags);
-}
-
-int SkMatrixClipStateMgr::saveLayer(const SkRect* bounds, const SkPaint* paint,
-                                    SkCanvas::SaveFlags flags) {
-#ifdef SK_DEBUG
-    if (fCurMCState->fIsSaveLayer) {
-        SkASSERT(0 == fSkipOffsets->count());
-    }
-#endif
-
-    // Since the saveLayer call draws something we need to potentially dump
-    // out the MC state
-    SkDEBUGCODE(bool saved =) this->call(kOther_CallType);
-
-    int result = this->MCStackPush(flags);
-    ++fCurMCState->fLayerID;
-    fCurMCState->fIsSaveLayer = true;
-
-#ifdef SK_DEBUG
-    if (saved) {
-        fCurMCState->fExpectedDepth++; // 1 for nesting save
-    }
-    fCurMCState->fExpectedDepth++;   // 1 for saveLayer
-#endif
-
-    *fStateIDStack.append() = fCurOpenStateID;
-    fCurMCState->fSavedSkipOffsets = fSkipOffsets;
-
-    // TODO: recycle these rather then new & deleting them on every saveLayer/
-    // restore
-    fSkipOffsets = SkNEW(SkTDArray<int>);
-
-    fPicRecord->recordSaveLayer(bounds, paint, flags | SkCanvas::kMatrixClip_SaveFlag);
-#ifdef SK_DEBUG
-    fActualDepth++;
-#endif
-    return result;
-}
-
-void SkMatrixClipStateMgr::restore() {
-    SkDEBUGCODE(this->validate();)
-
-    if (fCurMCState->fIsSaveLayer) {
-        if (fCurMCState->fHasOpen) {
-            fCurMCState->fHasOpen = false;
-            fPicRecord->recordRestore(); // Close the open block inside the saveLayer
-#ifdef SK_DEBUG
-            SkASSERT(fActualDepth > 0);
-            fActualDepth--;
-#endif
-        } else {
-            SkASSERT(0 == fSkipOffsets->count());
-        }
-
-        // The saveLayer's don't carry any matrix or clip state in the
-        // new scheme so make sure the saveLayer's recordRestore doesn't
-        // try to finalize them (i.e., fill in their skip offsets).
-        fPicRecord->recordRestore(false); // close of saveLayer
-#ifdef SK_DEBUG
-        SkASSERT(fActualDepth > 0);
-        fActualDepth--;
-#endif
-
-        SkASSERT(fStateIDStack.count() >= 1);
-        fCurOpenStateID = fStateIDStack[fStateIDStack.count()-1];
-        fStateIDStack.pop();
-
-        SkASSERT(0 == fSkipOffsets->count());
-        SkASSERT(NULL != fCurMCState->fSavedSkipOffsets);
-
-        SkDELETE(fSkipOffsets);
-        fSkipOffsets = fCurMCState->fSavedSkipOffsets;
-    }
-
-    bool prevHadOpen = fCurMCState->fHasOpen;
-    bool prevWasSaveLayer = fCurMCState->fIsSaveLayer;
-
-    fCurMCState->~MatrixClipState();       // balanced in save()
-    fMatrixClipStack.pop_back();
-    fCurMCState = (MatrixClipState*)fMatrixClipStack.back();
-
-    if (!prevWasSaveLayer) {
-        fCurMCState->fHasOpen = prevHadOpen;
-    }
-
-    if (fCurMCState->fIsSaveLayer) {
-        if (0 != fSkipOffsets->count()) {
-            SkASSERT(fCurMCState->fHasOpen);
-        }
-    }
-
-    SkDEBUGCODE(this->validate();)
-}
-
-// kIdentityWideOpenStateID (0) is reserved for the identity/wide-open clip state
-int32_t SkMatrixClipStateMgr::NewMCStateID() {
-    // TODO: guard against wrap around
-    // TODO: make uint32_t
-    static int32_t gMCStateID = kIdentityWideOpenStateID;
-    ++gMCStateID;
-    return gMCStateID;
-}
-
-bool SkMatrixClipStateMgr::isNestingMCState(int stateID) {
-    return fStateIDStack.count() > 0 && fStateIDStack[fStateIDStack.count()-1] == fCurOpenStateID;
-}
-
-bool SkMatrixClipStateMgr::call(CallType callType) {
-    SkDEBUGCODE(this->validate();)
-
-    if (kMatrix_CallType == callType || kClip_CallType == callType) {
-        fCurMCState->fMCStateID = NewMCStateID();
-        SkDEBUGCODE(this->validate();)
-        return false;
-    }
-
-    SkASSERT(kOther_CallType == callType);
-
-    if (fCurMCState->fMCStateID == fCurOpenStateID) {
-        // Required MC state is already active one - nothing to do
-        SkDEBUGCODE(this->validate();)
-        return false;
-    }
-
-    if (kIdentityWideOpenStateID != fCurOpenStateID &&
-        !this->isNestingMCState(fCurOpenStateID)) {
-        // Don't write a restore if the open state is one in which a saveLayer
-        // is nested. The save after the saveLayer's restore will close it.
-        fPicRecord->recordRestore();    // Close the open block
-        fCurMCState->fHasOpen = false;
-#ifdef SK_DEBUG
-        SkASSERT(fActualDepth > 0);
-        fActualDepth--;
-#endif
-    }
-
-    // Install the required MC state as the active one
-    fCurOpenStateID = fCurMCState->fMCStateID;
-
-    if (kIdentityWideOpenStateID == fCurOpenStateID) {
-        SkASSERT(0 == fActualDepth);
-        SkASSERT(!fCurMCState->fHasOpen);
-        SkASSERT(0 == fSkipOffsets->count());
-        return false;
-    }
-
-    SkASSERT(!fCurMCState->fHasOpen);
-    SkASSERT(0 == fSkipOffsets->count());
-    fCurMCState->fHasOpen = true;
-    fPicRecord->recordSave(SkCanvas::kMatrixClip_SaveFlag);
-#ifdef SK_DEBUG
-    fActualDepth++;
-    SkASSERT(fActualDepth == fCurMCState->fExpectedDepth);
-#endif
-
-    // write out clips
-    SkDeque::Iter iter(fMatrixClipStack, SkDeque::Iter::kBack_IterStart);
-    const MatrixClipState* state;
-    // Loop back across the MC states until the last saveLayer. The MC
-    // state in front of the saveLayer has already been written out.
-    for (state = (const MatrixClipState*) iter.prev();
-         state != NULL;
-         state = (const MatrixClipState*) iter.prev()) {
-        if (state->fIsSaveLayer) {
-            break;
-        }
-    }
-
-    int curMatID;
-
-    if (NULL == state) {
-        // There was no saveLayer in the MC stack so we need to output them all
-        iter.reset(fMatrixClipStack, SkDeque::Iter::kFront_IterStart);
-        state = (const MatrixClipState*) iter.next();
-        curMatID = kIdentityMatID;
-    } else {
-        // SkDeque's iterators actually return the previous location so we
-        // need to reverse and go forward one to get back on track.
-        iter.next();
-        SkDEBUGCODE(const MatrixClipState* test = (const MatrixClipState*)) iter.next();
-        SkASSERT(test == state);
-
-        curMatID = state->fMatrixInfo->getID(this);
-
-        // TODO: this assumes that, in the case of Save|SaveLayer when the SaveLayer
-        // doesn't save the clip, that the SaveLayer doesn't add any additional clip state.
-        // This assumption will be removed when we explicitly store the clip state in
-        // self-contained objects. It is valid for the small set of skps.
-        if (NULL != state->fPrev && state->fClipInfo == state->fPrev->fClipInfo) {
-            // By the above assumption the SaveLayer's MC state has already been
-            // written out by the prior Save so don't output it again.
-            state = (const MatrixClipState*) iter.next();
-        }
-    }
-
-    for ( ; state != NULL; state = (const MatrixClipState*) iter.next()) {
-         state->fClipInfo->writeClip(&curMatID, this);
-    }
-
-    // write out matrix
-    // TODO: this test isn't quite right. It should be:
-    //   if (curMatID != fCurMCState->fMatrixInfo->getID(this)) {
-    // but right now the testing harness always expects a matrix if
-    // the matrices are non-I
-    if (kIdentityMatID != fCurMCState->fMatrixInfo->getID(this)) {
-        // TODO: writing out the delta matrix here is an artifact of the writing
-        // out of the entire clip stack (with its matrices). Ultimately we will
-        // write out the CTM here when the clip state is collapsed to a single path.
-        this->writeDeltaMat(curMatID, fCurMCState->fMatrixInfo->getID(this));
-    }
-
-    SkDEBUGCODE(this->validate();)
-    return true;
-}
-
-// Fill in the skip offsets for all the clips written in the current block
-void SkMatrixClipStateMgr::fillInSkips(SkWriter32* writer, int32_t restoreOffset) {
-    for (int i = 0; i < fSkipOffsets->count(); ++i) {
-        SkDEBUGCODE(int32_t peek = writer->readTAt<int32_t>((*fSkipOffsets)[i]);)
-        SkASSERT(-1 == peek);
-        writer->overwriteTAt<int32_t>((*fSkipOffsets)[i], restoreOffset);
-    }
-
-    fSkipOffsets->rewind();
-    SkASSERT(0 == fSkipOffsets->count());
-}
-
-void SkMatrixClipStateMgr::finish() {
-    if (kIdentityWideOpenStateID != fCurOpenStateID) {
-        fPicRecord->recordRestore();    // Close the open block
-        fCurMCState->fHasOpen = false;
-#ifdef SK_DEBUG
-        SkASSERT(fActualDepth > 0);
-        fActualDepth--;
-#endif
-        fCurOpenStateID = kIdentityWideOpenStateID;
-        SkASSERT(!fCurMCState->fHasOpen);
-    }
-}
-
-#ifdef SK_DEBUG
-void SkMatrixClipStateMgr::validate() {
-    if (fCurOpenStateID == fCurMCState->fMCStateID && !this->isNestingMCState(fCurOpenStateID)) {
-        // The current state is the active one so it should have a skip
-        // offset for each clip
-        SkDeque::Iter iter(fMatrixClipStack, SkDeque::Iter::kBack_IterStart);
-        int clipCount = 0;
-        for (const MatrixClipState* state = (const MatrixClipState*) iter.prev();
-             state != NULL;
-             state = (const MatrixClipState*) iter.prev()) {
-            if (NULL == state->fPrev || state->fPrev->fClipInfo != state->fClipInfo) {
-                clipCount += state->fClipInfo->numClips();
-            }
-            if (state->fIsSaveLayer) {
-                break;
-            }
-        }
-
-        SkASSERT(fSkipOffsets->count() == clipCount);
-    }
-}
-#endif
-
-int SkMatrixClipStateMgr::addRegionToDict(const SkRegion& region) {
-    int index = fRegionDict.count();
-    *fRegionDict.append() = SkNEW(SkRegion(region));
-    return index;
-}
-
-int SkMatrixClipStateMgr::addMatToDict(const SkMatrix& mat) {
-    if (mat.isIdentity()) {
-        return kIdentityMatID;
-    }
-
-    *fMatrixDict.append() = mat;
-    return fMatrixDict.count()-1;
-}
diff --git a/src/core/SkMatrixClipStateMgr.h b/src/core/SkMatrixClipStateMgr.h
deleted file mode 100644
index 016baa0..0000000
--- a/src/core/SkMatrixClipStateMgr.h
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkMatrixClipStateMgr_DEFINED
-#define SkMatrixClipStateMgr_DEFINED
-
-#include "SkCanvas.h"
-#include "SkMatrix.h"
-#include "SkRegion.h"
-#include "SkRRect.h"
-#include "SkTypes.h"
-#include "SkTDArray.h"
-
-class SkPictureRecord;
-class SkWriter32;
-
-// The SkMatrixClipStateMgr collapses the matrix/clip state of an SkPicture into
-// a series of save/restore blocks of consistent matrix clip state, e.g.:
-//
-//   save
-//     clip(s)
-//     concat
-//     ... draw ops ...
-//   restore
-//
-// SaveLayers simply add another level, e.g.:
-//
-//   save
-//     clip(s)
-//     concat
-//     ... draw ops ...
-//     saveLayer
-//       save
-//         clip(s)
-//         concat
-//         ... draw ops ...
-//       restore
-//     restore
-//   restore
-//
-// As a side effect of this process all saves and saveLayers will become
-// kMatrixClip_SaveFlag style saves/saveLayers.
-
-// The SkMatrixClipStateMgr works by intercepting all the save*, restore, clip*,
-// and matrix calls sent to SkCanvas in order to track the current matrix/clip
-// state. All the other canvas calls get funnelled into a generic "call" entry
-// point that signals that a state block is required.
-class SkMatrixClipStateMgr {
-public:
-    static const int32_t kIdentityWideOpenStateID = 0;
-    static const int kIdentityMatID = 0;
-
-    class MatrixClipState : SkNoncopyable {
-    public:
-        class MatrixInfo {
-        public:
-            void reset() {
-                fMatrixID = kIdentityMatID;
-                fMatrix.reset();
-            }
-
-            void preTranslate(SkScalar dx, SkScalar dy) {
-                fMatrixID = -1;
-                fMatrix.preTranslate(dx, dy);
-            }
-
-            void preScale(SkScalar sx, SkScalar sy) {
-                fMatrixID = -1;
-                fMatrix.preScale(sx, sy);
-            }
-
-            void preRotate(SkScalar degrees) {
-                fMatrixID = -1;
-                fMatrix.preRotate(degrees);
-            }
-
-            void preSkew(SkScalar sx, SkScalar sy) {
-                fMatrixID = -1;
-                fMatrix.preSkew(sx, sy);
-            }
-
-            void preConcat(const SkMatrix& matrix) {
-                fMatrixID = -1;
-                fMatrix.preConcat(matrix);
-            }
-
-            void setMatrix(const SkMatrix& matrix) {
-                fMatrixID = -1;
-                fMatrix = matrix;
-            }
-
-            int getID(SkMatrixClipStateMgr* mgr) {
-                if (fMatrixID >= 0) {
-                    return fMatrixID;
-                }
-
-                fMatrixID = mgr->addMatToDict(fMatrix);
-                return fMatrixID;
-            }
-
-        private:
-            SkMatrix fMatrix;
-            int      fMatrixID;
-
-            typedef SkNoncopyable INHERITED;
-        };
-
-        class ClipInfo : SkNoncopyable {
-        public:
-            ClipInfo() {}
-
-            bool clipRect(const SkRect& rect,
-                          SkRegion::Op op,
-                          bool doAA,
-                          int matrixID) {
-                ClipOp* newClip = fClips.append();
-                newClip->fClipType = kRect_ClipType;
-                newClip->fGeom.fRRect.setRect(rect);   // storing the clipRect in the RRect
-                newClip->fOp = op;
-                newClip->fDoAA = doAA;
-                newClip->fMatrixID = matrixID;
-                return false;
-            }
-
-            bool clipRRect(const SkRRect& rrect,
-                           SkRegion::Op op,
-                           bool doAA,
-                           int matrixID) {
-                ClipOp* newClip = fClips.append();
-                newClip->fClipType = kRRect_ClipType;
-                newClip->fGeom.fRRect = rrect;
-                newClip->fOp = op;
-                newClip->fDoAA = doAA;
-                newClip->fMatrixID = matrixID;
-                return false;
-            }
-
-            bool clipPath(SkPictureRecord* picRecord,
-                          const SkPath& path,
-                          SkRegion::Op op,
-                          bool doAA,
-                          int matrixID);
-            bool clipRegion(SkPictureRecord* picRecord,
-                            int regionID,
-                            SkRegion::Op op,
-                            int matrixID);
-            void writeClip(int* curMatID, SkMatrixClipStateMgr* mgr);
-
-            SkDEBUGCODE(int numClips() const { return fClips.count(); })
-
-        private:
-            enum ClipType {
-                kRect_ClipType,
-                kRRect_ClipType,
-                kPath_ClipType,
-                kRegion_ClipType
-            };
-
-            class ClipOp {
-            public:
-                ClipType     fClipType;
-
-                union {
-                    SkRRect fRRect;        // also stores clip rect
-                    int     fPathID;
-                    int     fRegionID;
-                } fGeom;
-
-                bool         fDoAA;
-                SkRegion::Op fOp;
-
-                // The CTM in effect when this clip call was issued
-                int          fMatrixID;
-            };
-
-            SkTDArray<ClipOp> fClips;
-
-            typedef SkNoncopyable INHERITED;
-        };
-
-        MatrixClipState(MatrixClipState* prev, int flags)
-            : fPrev(prev)
-        {
-            fHasOpen = false;
-
-            if (NULL == prev) {
-                fLayerID = 0;
-
-                fMatrixInfoStorage.reset();
-                fMatrixInfo = &fMatrixInfoStorage;
-                fClipInfo = &fClipInfoStorage;  // ctor handles init of fClipInfoStorage
-
-                // The identity/wide-open-clip state is current by default
-                fMCStateID = kIdentityWideOpenStateID;
-#ifdef SK_DEBUG
-                fExpectedDepth = 1;
-#endif
-            }
-            else {
-                fLayerID = prev->fLayerID;
-
-                if (flags & SkCanvas::kMatrix_SaveFlag) {
-                    fMatrixInfoStorage = *prev->fMatrixInfo;
-                    fMatrixInfo = &fMatrixInfoStorage;
-                } else {
-                    fMatrixInfo = prev->fMatrixInfo;
-                }
-
-                if (flags & SkCanvas::kClip_SaveFlag) {
-                    // We don't copy the ClipOps of the previous clip states
-                    fClipInfo = &fClipInfoStorage;
-                } else {
-                    fClipInfo = prev->fClipInfo;
-                }
-
-                // Initially a new save/saveLayer represents the same MC state
-                // as its predecessor.
-                fMCStateID = prev->fMCStateID;
-#ifdef SK_DEBUG
-                fExpectedDepth = prev->fExpectedDepth;
-#endif
-            }
-
-            fIsSaveLayer = false;
-        }
-
-        MatrixInfo*  fMatrixInfo;
-        MatrixInfo   fMatrixInfoStorage;
-
-        ClipInfo*    fClipInfo;
-        ClipInfo     fClipInfoStorage;
-
-        // Tracks the current depth of saveLayers to support the isDrawingToLayer call
-        int          fLayerID;
-        // Does this MC state represent a saveLayer call?
-        bool         fIsSaveLayer;
-
-        // The next field is only valid when fIsSaveLayer is set.
-        SkTDArray<int>* fSavedSkipOffsets;
-
-        // Does the MC state have an open block in the skp?
-        bool         fHasOpen;
-
-        MatrixClipState* fPrev;
-
-#ifdef SK_DEBUG
-        int              fExpectedDepth;    // debugging aid
-#endif
-
-        int32_t     fMCStateID;
-    };
-
-    enum CallType {
-        kMatrix_CallType,
-        kClip_CallType,
-        kOther_CallType
-    };
-
-    SkMatrixClipStateMgr();
-    ~SkMatrixClipStateMgr();
-
-    void init(SkPictureRecord* picRecord) {
-        // Note: we're not taking a ref here. It is expected that the SkMatrixClipStateMgr
-        // is owned by the SkPictureRecord object
-        fPicRecord = picRecord;
-    }
-
-    SkPictureRecord* getPicRecord() { return fPicRecord; }
-
-    // TODO: need to override canvas' getSaveCount. Right now we pass the
-    // save* and restore calls on to the base SkCanvas in SkPictureRecord but
-    // this duplicates effort.
-    int getSaveCount() const { return fMatrixClipStack.count(); }
-
-    int save(SkCanvas::SaveFlags flags);
-
-    int saveLayer(const SkRect* bounds, const SkPaint* paint, SkCanvas::SaveFlags flags);
-
-    bool isDrawingToLayer() const {
-        return fCurMCState->fLayerID > 0;
-    }
-
-    void restore();
-
-    void translate(SkScalar dx, SkScalar dy) {
-        this->call(kMatrix_CallType);
-        fCurMCState->fMatrixInfo->preTranslate(dx, dy);
-    }
-
-    void scale(SkScalar sx, SkScalar sy) {
-        this->call(kMatrix_CallType);
-        fCurMCState->fMatrixInfo->preScale(sx, sy);
-    }
-
-    void rotate(SkScalar degrees) {
-        this->call(kMatrix_CallType);
-        fCurMCState->fMatrixInfo->preRotate(degrees);
-    }
-
-    void skew(SkScalar sx, SkScalar sy) {
-        this->call(kMatrix_CallType);
-        fCurMCState->fMatrixInfo->preSkew(sx, sy);
-    }
-
-    void concat(const SkMatrix& matrix) {
-        this->call(kMatrix_CallType);
-        fCurMCState->fMatrixInfo->preConcat(matrix);
-    }
-
-    void setMatrix(const SkMatrix& matrix) {
-        this->call(kMatrix_CallType);
-        fCurMCState->fMatrixInfo->setMatrix(matrix);
-    }
-
-    bool clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
-        this->call(SkMatrixClipStateMgr::kClip_CallType);
-        return fCurMCState->fClipInfo->clipRect(rect, op, doAA,
-                                                fCurMCState->fMatrixInfo->getID(this));
-    }
-
-    bool clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
-        this->call(SkMatrixClipStateMgr::kClip_CallType);
-        return fCurMCState->fClipInfo->clipRRect(rrect, op, doAA,
-                                                 fCurMCState->fMatrixInfo->getID(this));
-    }
-
-    bool clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
-        this->call(SkMatrixClipStateMgr::kClip_CallType);
-        return fCurMCState->fClipInfo->clipPath(fPicRecord, path, op, doAA,
-                                                fCurMCState->fMatrixInfo->getID(this));
-    }
-
-    bool clipRegion(const SkRegion& region, SkRegion::Op op) {
-        this->call(SkMatrixClipStateMgr::kClip_CallType);
-        int regionID = this->addRegionToDict(region);
-        return fCurMCState->fClipInfo->clipRegion(fPicRecord, regionID, op,
-                                                  fCurMCState->fMatrixInfo->getID(this));
-    }
-
-    bool call(CallType callType);
-
-    void fillInSkips(SkWriter32* writer, int32_t restoreOffset);
-
-    void finish();
-
-protected:
-    SkPictureRecord* fPicRecord;
-
-    uint32_t         fMatrixClipStackStorage[43]; // sized to fit 2 clip states
-    SkDeque          fMatrixClipStack;
-    MatrixClipState* fCurMCState;
-
-    // This dictionary doesn't actually de-duplicate the matrices (except for the
-    // identity matrix). It merely stores the matrices and allows them to be looked
-    // up by ID later. The de-duplication mainly falls upon the matrix/clip stack
-    // which stores the ID so a revisited clip/matrix (via popping the stack) will
-    // use the same ID.
-    SkTDArray<SkMatrix> fMatrixDict;
-
-    SkTDArray<SkRegion*> fRegionDict;
-
-    // The MCStateID of the state currently in effect in the byte stream. 0 if none.
-    int32_t          fCurOpenStateID;
-    // The skip offsets for the current open state. These are the locations in the
-    // skp that must be filled in when the current open state is closed. These are
-    // here rather then distributed across the MatrixClipState's because saveLayers
-    // can cause MC states to be nested.
-    SkTDArray<int32_t>  *fSkipOffsets;  // TODO: should we store u32 or size_t instead?
-
-    SkDEBUGCODE(void validate();)
-
-    int MCStackPush(SkCanvas::SaveFlags flags);
-
-    void addClipOffset(size_t offset) {
-        SkASSERT(NULL != fSkipOffsets);
-        SkASSERT(kIdentityWideOpenStateID != fCurOpenStateID);
-        SkASSERT(fCurMCState->fHasOpen);
-        SkASSERT(!fCurMCState->fIsSaveLayer);
-
-        *fSkipOffsets->append() = SkToS32(offset);
-    }
-
-    void writeDeltaMat(int currentMatID, int desiredMatID);
-    static int32_t   NewMCStateID();
-
-    int addRegionToDict(const SkRegion& region);
-    const SkRegion* lookupRegion(int index) {
-        SkASSERT(index >= 0 && index < fRegionDict.count());
-        return fRegionDict[index];
-    }
-
-    // TODO: add stats to check if the dictionary really does
-    // reduce the size of the SkPicture.
-    int addMatToDict(const SkMatrix& mat);
-    const SkMatrix& lookupMat(int index) {
-        SkASSERT(index >= 0 && index < fMatrixDict.count());
-        return fMatrixDict[index];
-    }
-
-    bool isNestingMCState(int stateID);
-
-#ifdef SK_DEBUG
-    int fActualDepth;
-#endif
-
-    // save layers are nested within a specific MC state. This stack tracks
-    // the nesting MC state's ID as save layers are pushed and popped.
-    SkTDArray<int> fStateIDStack;
-};
-
-#endif
diff --git a/src/core/SkMessageBus.h b/src/core/SkMessageBus.h
index f36c42b..1290ea9 100644
--- a/src/core/SkMessageBus.h
+++ b/src/core/SkMessageBus.h
@@ -85,7 +85,7 @@
 
 template<typename Message>
 void SkMessageBus<Message>::Inbox::poll(SkTDArray<Message>* messages) {
-    SkASSERT(NULL != messages);
+    SkASSERT(messages);
     messages->reset();
     SkAutoMutexAcquire lock(fMessagesMutex);
     messages->swap(fMessages);
diff --git a/src/core/SkMiniData.cpp b/src/core/SkMiniData.cpp
new file mode 100644
index 0000000..ded62d1
--- /dev/null
+++ b/src/core/SkMiniData.cpp
@@ -0,0 +1,80 @@
+#include "SkMiniData.h"
+
+namespace {
+
+// SkMiniData::fRep either stores a LongData* or is punned into a ShortData.
+// We use the low bits to distinguish the two: all pointers from malloc are at
+// least 8-byte aligned, leaving those low bits clear when it's a LongData*.
+
+static bool is_long(uint64_t rep) {
+    // Even on 32-bit machines, we require the bottom 3 bits from malloc'd pointers are clear.
+    // If any of those bottom 3 bits are set, it's from a ShortData's len.  And if no bits are
+    // set anywhere, it's an empty SkMiniData, which also follows the ShortData path.
+    return rep && SkIsAlign8(rep);
+}
+
+// Can be used for any length, but we always use it for >=8.
+struct LongData {
+    size_t len;
+    uint8_t data[8];  // There are actually len >= 8 bytes here.
+
+    static uint64_t Create(const void* data, size_t len) {
+        SkASSERT(len > 7);
+        LongData* s = (LongData*)sk_malloc_throw(sizeof(size_t) + len);
+        s->len = len;
+        memcpy(s->data, data, len);
+
+        uint64_t rep = reinterpret_cast<uint64_t>(s);
+        SkASSERT(is_long(rep));
+        return rep;
+    }
+};
+
+// At most 7 bytes fit, but never mallocs.
+struct ShortData {
+    // Order matters here. len must align with the least signficant bits of a pointer.
+#ifdef SK_CPU_LENDIAN
+    uint8_t len;
+    uint8_t data[7];
+#else  // Warning!  Only the little-endian path has been tested.
+    uint8_t data[7];
+    uint8_t len;
+#endif
+
+    static uint64_t Create(const void* data, size_t len) {
+        SkASSERT(len <= 7);
+#ifdef SK_CPU_LENDIAN
+        ShortData s = { (uint8_t)len, {0, 0, 0, 0, 0, 0, 0} };
+#else  // Warning!  Only the little-endian path has been tested.
+        ShortData s = { {0, 0, 0, 0, 0, 0, 0}, (uint8_t)len };
+#endif
+        memcpy(s.data, data, len);
+        return *reinterpret_cast<uint64_t*>(&s);
+    }
+};
+
+}  // namespace
+
+SkMiniData::SkMiniData(const void* data, size_t len)
+    : fRep(len <= 7 ? ShortData::Create(data, len)
+                    :  LongData::Create(data, len)) {}
+
+SkMiniData::SkMiniData(const SkMiniData& s)
+    : fRep(s.len() <= 7 ? ShortData::Create(s.data(), s.len())
+                        :  LongData::Create(s.data(), s.len())) {}
+
+SkMiniData::~SkMiniData() {
+    if (is_long(fRep)) {
+        sk_free(reinterpret_cast<void*>(fRep));
+    }
+}
+
+const void* SkMiniData::data() const {
+    return is_long(fRep) ? reinterpret_cast<const  LongData*>( fRep)->data
+                         : reinterpret_cast<const ShortData*>(&fRep)->data;
+}
+
+size_t SkMiniData::len() const {
+    return is_long(fRep) ? reinterpret_cast<const  LongData*>( fRep)->len
+                         : reinterpret_cast<const ShortData*>(&fRep)->len;
+}
diff --git a/src/core/SkMiniData.h b/src/core/SkMiniData.h
new file mode 100644
index 0000000..fd22cea
--- /dev/null
+++ b/src/core/SkMiniData.h
@@ -0,0 +1,24 @@
+#ifndef SkMiniData_DEFINED
+#define SkMiniData_DEFINED
+
+// A class that can store any immutable byte string,
+// but optimized to store <=7 bytes.
+
+#include "SkTypes.h"
+
+class SkMiniData {
+public:
+    SkMiniData(const void*, size_t);
+    SkMiniData(const SkMiniData&);
+    ~SkMiniData();
+
+    const void* data() const;
+    size_t len() const;
+
+private:
+    SkMiniData& operator=(const SkMiniData&);
+
+    const uint64_t fRep;
+};
+
+#endif//SkMiniData_DEFINED
diff --git a/src/core/SkMultiPictureDraw.cpp b/src/core/SkMultiPictureDraw.cpp
new file mode 100644
index 0000000..eb1e55e
--- /dev/null
+++ b/src/core/SkMultiPictureDraw.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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 "SkCanvas.h"
+#include "SkMultiPictureDraw.h"
+#include "SkPicture.h"
+
+SkMultiPictureDraw::SkMultiPictureDraw(int reserve) {
+    if (reserve > 0) {
+        fDrawData.setReserve(reserve);
+    }
+}
+
+void SkMultiPictureDraw::reset() {
+    for (int i = 0; i < fDrawData.count(); ++i) {
+        fDrawData[i].picture->unref();
+        fDrawData[i].canvas->unref();
+        SkDELETE(fDrawData[i].paint);
+    }
+
+    fDrawData.rewind();
+}
+
+void SkMultiPictureDraw::add(SkCanvas* canvas, 
+                             const SkPicture* picture,
+                             const SkMatrix* matrix, 
+                             const SkPaint* paint) {
+    if (NULL == canvas || NULL == picture) {
+        SkDEBUGFAIL("parameters to SkMultiPictureDraw::add should be non-NULL");
+        return;
+    }
+
+    DrawData* data = fDrawData.append();
+
+    data->picture = SkRef(picture);
+    data->canvas = SkRef(canvas);
+    if (matrix) {
+        data->matrix = *matrix;
+    } else {
+        data->matrix.setIdentity();
+    }
+    if (paint) {
+        data->paint = SkNEW_ARGS(SkPaint, (*paint));
+    } else {
+        data->paint = NULL;
+    }
+}
+
+void SkMultiPictureDraw::draw() {
+    for (int i = 0; i < fDrawData.count(); ++i) {
+        fDrawData[i].canvas->drawPicture(fDrawData[i].picture, 
+                                         &fDrawData[i].matrix, 
+                                         fDrawData[i].paint);
+    }
+
+    this->reset();
+}
+
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 16d8bb2..ff1cb7e 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -11,6 +11,7 @@
 #include "SkColorFilter.h"
 #include "SkData.h"
 #include "SkDeviceProperties.h"
+#include "SkDraw.h"
 #include "SkFontDescriptor.h"
 #include "SkFontHost.h"
 #include "SkGlyphCache.h"
@@ -20,7 +21,6 @@
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
 #include "SkPaintDefaults.h"
-#include "SkPaintOptionsAndroid.h"
 #include "SkPathEffect.h"
 #include "SkRasterizer.h"
 #include "SkScalar.h"
@@ -54,7 +54,6 @@
     kImageFilter_DirtyBit         = 1 << 13,
     kTypeface_DirtyBit            = 1 << 14,
     kAnnotation_DirtyBit          = 1 << 15,
-    kPaintOptionsAndroid_DirtyBit = 1 << 16,
 };
 
 // define this to get a printf for out-of-range parameter in setters
@@ -81,26 +80,25 @@
     fImageFilter = NULL;
     fAnnotation  = NULL;
 
-    fTextSize     = SkPaintDefaults_TextSize;
-    fTextScaleX   = SK_Scalar1;
-    fTextSkewX    = 0;
-    fColor        = SK_ColorBLACK;
-    fWidth        = 0;
-    fMiterLimit   = SkPaintDefaults_MiterLimit;
+    fTextSize   = SkPaintDefaults_TextSize;
+    fTextScaleX = SK_Scalar1;
+    fTextSkewX  = 0;
+    fColor      = SK_ColorBLACK;
+    fWidth      = 0;
+    fMiterLimit = SkPaintDefaults_MiterLimit;
 
     // Zero all bitfields, then set some non-zero defaults.
-    fBitfields    = 0;
-    fFlags        = SkPaintDefaults_Flags;
-    fCapType      = kDefault_Cap;
-    fJoinType     = kDefault_Join;
-    fTextAlign    = kLeft_Align;
-    fStyle        = kFill_Style;
-    fTextEncoding = kUTF8_TextEncoding;
-    fHinting      = SkPaintDefaults_Hinting;
+    fBitfieldsUInt           = 0;
+    fBitfields.fFlags        = SkPaintDefaults_Flags;
+    fBitfields.fCapType      = kDefault_Cap;
+    fBitfields.fJoinType     = kDefault_Join;
+    fBitfields.fTextAlign    = kLeft_Align;
+    fBitfields.fStyle        = kFill_Style;
+    fBitfields.fTextEncoding = kUTF8_TextEncoding;
+    fBitfields.fHinting      = SkPaintDefaults_Hinting;
 
     fDirtyBits    = 0;
 #ifdef SK_BUILD_FOR_ANDROID
-    new (&fPaintOptionsAndroid) SkPaintOptionsAndroid;
     fGenerationID = 0;
 #endif
 }
@@ -130,7 +128,6 @@
     COPY(fDirtyBits);
 
 #ifdef SK_BUILD_FOR_ANDROID
-    new (&fPaintOptionsAndroid) SkPaintOptionsAndroid(src.fPaintOptionsAndroid);
     COPY(fGenerationID);
 #endif
 
@@ -182,8 +179,6 @@
     COPY(fDirtyBits);
 
 #ifdef SK_BUILD_FOR_ANDROID
-    fPaintOptionsAndroid.~SkPaintOptionsAndroid();
-    new (&fPaintOptionsAndroid) SkPaintOptionsAndroid(src.fPaintOptionsAndroid);
     ++fGenerationID;
 #endif
 
@@ -195,8 +190,10 @@
 
 bool operator==(const SkPaint& a, const SkPaint& b) {
 #define EQUAL(field) (a.field == b.field)
-    // Don't check fGenerationID or fDirtyBits, which can be different for logically equal paints.
-    return EQUAL(fTypeface)
+    // Don't check fGenerationID, which can be different for logically equal paints.
+    // fDirtyBits is a very quick check for non-equality, so check it first.
+    return EQUAL(fDirtyBits)
+        && EQUAL(fTypeface)
         && EQUAL(fPathEffect)
         && EQUAL(fShader)
         && EQUAL(fXfermode)
@@ -212,10 +209,7 @@
         && EQUAL(fColor)
         && EQUAL(fWidth)
         && EQUAL(fMiterLimit)
-        && EQUAL(fBitfields)
-#ifdef SK_BUILD_FOR_ANDROID
-        && EQUAL(fPaintOptionsAndroid)
-#endif
+        && EQUAL(fBitfieldsUInt)
         ;
 #undef EQUAL
 }
@@ -240,93 +234,79 @@
 void SkPaint::setGenerationID(uint32_t generationID) {
     fGenerationID = generationID;
 }
-
-unsigned SkPaint::getBaseGlyphCount(SkUnichar text) const {
-    SkAutoGlyphCache autoCache(*this, NULL, NULL);
-    SkGlyphCache* cache = autoCache.getCache();
-    return cache->getBaseGlyphCount(text);
-}
-
-void SkPaint::setPaintOptionsAndroid(const SkPaintOptionsAndroid& options) {
-    if (options != fPaintOptionsAndroid) {
-        fPaintOptionsAndroid = options;
-        GEN_ID_INC;
-        fDirtyBits |= kPaintOptionsAndroid_DirtyBit;
-    }
-}
 #endif
 
 void SkPaint::setFilterLevel(FilterLevel level) {
-    GEN_ID_INC_EVAL((unsigned) level != fFilterLevel);
-    fFilterLevel = level;
+    GEN_ID_INC_EVAL((unsigned) level != fBitfields.fFilterLevel);
+    fBitfields.fFilterLevel = level;
 }
 
 void SkPaint::setHinting(Hinting hintingLevel) {
-    GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting);
-    fHinting = hintingLevel;
+    GEN_ID_INC_EVAL((unsigned) hintingLevel != fBitfields.fHinting);
+    fBitfields.fHinting = hintingLevel;
 }
 
 void SkPaint::setFlags(uint32_t flags) {
-    GEN_ID_INC_EVAL(fFlags != flags);
-    fFlags = flags;
+    GEN_ID_INC_EVAL(flags != fBitfields.fFlags);
+    fBitfields.fFlags = flags;
 }
 
 void SkPaint::setAntiAlias(bool doAA) {
-    this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doAA, kAntiAlias_Flag));
 }
 
 void SkPaint::setDither(bool doDither) {
-    this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doDither, kDither_Flag));
 }
 
 void SkPaint::setSubpixelText(bool doSubpixel) {
-    this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doSubpixel, kSubpixelText_Flag));
 }
 
 void SkPaint::setLCDRenderText(bool doLCDRender) {
-    this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doLCDRender, kLCDRenderText_Flag));
 }
 
 void SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) {
-    this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag));
 }
 
 void SkPaint::setAutohinted(bool useAutohinter) {
-    this->setFlags(SkSetClearMask(fFlags, useAutohinter, kAutoHinting_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, useAutohinter, kAutoHinting_Flag));
 }
 
 void SkPaint::setLinearText(bool doLinearText) {
-    this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doLinearText, kLinearText_Flag));
 }
 
 void SkPaint::setVerticalText(bool doVertical) {
-    this->setFlags(SkSetClearMask(fFlags, doVertical, kVerticalText_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doVertical, kVerticalText_Flag));
 }
 
 void SkPaint::setUnderlineText(bool doUnderline) {
-    this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doUnderline, kUnderlineText_Flag));
 }
 
 void SkPaint::setStrikeThruText(bool doStrikeThru) {
-    this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doStrikeThru, kStrikeThruText_Flag));
 }
 
 void SkPaint::setFakeBoldText(bool doFakeBold) {
-    this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doFakeBold, kFakeBoldText_Flag));
 }
 
 void SkPaint::setDevKernText(bool doDevKern) {
-    this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doDevKern, kDevKernText_Flag));
 }
 
 void SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) {
-    this->setFlags(SkSetClearMask(fFlags, doDistanceFieldText, kDistanceFieldTextTEMP_Flag));
+    this->setFlags(SkSetClearMask(fBitfields.fFlags, doDistanceFieldText, kDistanceFieldTextTEMP_Flag));
 }
 
 void SkPaint::setStyle(Style style) {
     if ((unsigned)style < kStyleCount) {
-        GEN_ID_INC_EVAL((unsigned)style != fStyle);
-        fStyle = style;
+        GEN_ID_INC_EVAL((unsigned)style != fBitfields.fStyle);
+        fBitfields.fStyle = style;
     } else {
 #ifdef SK_REPORT_API_RANGE_CHECK
         SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
@@ -337,7 +317,7 @@
 void SkPaint::setColor(SkColor color) {
     GEN_ID_INC_EVAL(color != fColor);
     fColor = color;
-    fDirtyBits |= kColor_DirtyBit;
+    fDirtyBits = SkSetClearMask(fDirtyBits, color != SK_ColorBLACK, kColor_DirtyBit);
 }
 
 void SkPaint::setAlpha(U8CPU a) {
@@ -353,7 +333,7 @@
     if (width >= 0) {
         GEN_ID_INC_EVAL(width != fWidth);
         fWidth = width;
-        fDirtyBits |= kStrokeWidth_DirtyBit;
+        fDirtyBits = SkSetClearMask(fDirtyBits, width != 0, kStrokeWidth_DirtyBit);
     } else {
 #ifdef SK_REPORT_API_RANGE_CHECK
         SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
@@ -365,7 +345,9 @@
     if (limit >= 0) {
         GEN_ID_INC_EVAL(limit != fMiterLimit);
         fMiterLimit = limit;
-        fDirtyBits |= kStrokeMiter_DirtyBit;
+        fDirtyBits = SkSetClearMask(fDirtyBits,
+                                    limit != SkPaintDefaults_MiterLimit,
+                                    kStrokeMiter_DirtyBit);
     } else {
 #ifdef SK_REPORT_API_RANGE_CHECK
         SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
@@ -375,8 +357,8 @@
 
 void SkPaint::setStrokeCap(Cap ct) {
     if ((unsigned)ct < kCapCount) {
-        GEN_ID_INC_EVAL((unsigned)ct != fCapType);
-        fCapType = SkToU8(ct);
+        GEN_ID_INC_EVAL((unsigned)ct != fBitfields.fCapType);
+        fBitfields.fCapType = SkToU8(ct);
     } else {
 #ifdef SK_REPORT_API_RANGE_CHECK
         SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
@@ -386,8 +368,8 @@
 
 void SkPaint::setStrokeJoin(Join jt) {
     if ((unsigned)jt < kJoinCount) {
-        GEN_ID_INC_EVAL((unsigned)jt != fJoinType);
-        fJoinType = SkToU8(jt);
+        GEN_ID_INC_EVAL((unsigned)jt != fBitfields.fJoinType);
+        fBitfields.fJoinType = SkToU8(jt);
     } else {
 #ifdef SK_REPORT_API_RANGE_CHECK
         SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
@@ -399,8 +381,8 @@
 
 void SkPaint::setTextAlign(Align align) {
     if ((unsigned)align < kAlignCount) {
-        GEN_ID_INC_EVAL((unsigned)align != fTextAlign);
-        fTextAlign = SkToU8(align);
+        GEN_ID_INC_EVAL((unsigned)align != fBitfields.fTextAlign);
+        fBitfields.fTextAlign = SkToU8(align);
     } else {
 #ifdef SK_REPORT_API_RANGE_CHECK
         SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
@@ -412,7 +394,7 @@
     if (ts >= 0) {
         GEN_ID_INC_EVAL(ts != fTextSize);
         fTextSize = ts;
-        fDirtyBits |= kTextSize_DirtyBit;
+        fDirtyBits = SkSetClearMask(fDirtyBits, ts != SkPaintDefaults_TextSize, kTextSize_DirtyBit);
     } else {
 #ifdef SK_REPORT_API_RANGE_CHECK
         SkDebugf("SkPaint::setTextSize() called with negative value\n");
@@ -423,19 +405,19 @@
 void SkPaint::setTextScaleX(SkScalar scaleX) {
     GEN_ID_INC_EVAL(scaleX != fTextScaleX);
     fTextScaleX = scaleX;
-    fDirtyBits |= kTextScaleX_DirtyBit;
+    fDirtyBits = SkSetClearMask(fDirtyBits, scaleX != SK_Scalar1, kTextScaleX_DirtyBit);
 }
 
 void SkPaint::setTextSkewX(SkScalar skewX) {
     GEN_ID_INC_EVAL(skewX != fTextSkewX);
     fTextSkewX = skewX;
-    fDirtyBits |= kTextSkewX_DirtyBit;
+    fDirtyBits = SkSetClearMask(fDirtyBits, skewX != 0, kTextSkewX_DirtyBit);
 }
 
 void SkPaint::setTextEncoding(TextEncoding encoding) {
     if ((unsigned)encoding <= kGlyphID_TextEncoding) {
-        GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding);
-        fTextEncoding = encoding;
+        GEN_ID_INC_EVAL((unsigned)encoding != fBitfields.fTextEncoding);
+        fBitfields.fTextEncoding = encoding;
     } else {
 #ifdef SK_REPORT_API_RANGE_CHECK
         SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
@@ -445,43 +427,38 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-// Returns dst with the given bitmask enabled or disabled, depending on value.
-inline static uint32_t set_mask(uint32_t dst, uint32_t bitmask, bool value) {
-    return value ? (dst | bitmask) : (dst & ~bitmask);
-}
-
 SkTypeface* SkPaint::setTypeface(SkTypeface* font) {
     SkRefCnt_SafeAssign(fTypeface, font);
     GEN_ID_INC;
-    fDirtyBits = set_mask(fDirtyBits, kTypeface_DirtyBit, font != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, font != NULL, kTypeface_DirtyBit);
     return font;
 }
 
 SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) {
     SkRefCnt_SafeAssign(fRasterizer, r);
     GEN_ID_INC;
-    fDirtyBits = set_mask(fDirtyBits, kRasterizer_DirtyBit, r != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, r != NULL, kRasterizer_DirtyBit);
     return r;
 }
 
 SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) {
     SkRefCnt_SafeAssign(fLooper, looper);
     GEN_ID_INC;
-    fDirtyBits = set_mask(fDirtyBits, kLooper_DirtyBit, looper != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, looper != NULL, kLooper_DirtyBit);
     return looper;
 }
 
 SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) {
     SkRefCnt_SafeAssign(fImageFilter, imageFilter);
     GEN_ID_INC;
-    fDirtyBits = set_mask(fDirtyBits, kImageFilter_DirtyBit, imageFilter != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, imageFilter != NULL, kImageFilter_DirtyBit);
     return imageFilter;
 }
 
 SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) {
     SkRefCnt_SafeAssign(fAnnotation, annotation);
     GEN_ID_INC;
-    fDirtyBits = set_mask(fDirtyBits, kAnnotation_DirtyBit, annotation != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, annotation != NULL, kAnnotation_DirtyBit);
     return annotation;
 }
 
@@ -506,15 +483,6 @@
     return tooBig(matrix, MaxCacheSize2());
 }
 
-bool SkPaint::tooBigToUseCache(const SkMatrix& ctm) const {
-    SkMatrix textM;
-    return TooBigToUseCache(ctm, *this->setTextMatrix(&textM));
-}
-
-bool SkPaint::tooBigToUseCache() const {
-    SkMatrix textM;
-    return tooBig(*this->setTextMatrix(&textM), MaxCacheSize2());
-}
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -961,7 +929,7 @@
     };
 
     unsigned index = this->getTextEncoding();
-    if (fFlags & kSubpixelText_Flag) {
+    if (fBitfields.fFlags & kSubpixelText_Flag) {
         index += 4;
     }
 
@@ -997,7 +965,7 @@
 class SkCanonicalizePaint {
 public:
     SkCanonicalizePaint(const SkPaint& paint) : fPaint(&paint), fScale(0) {
-        if (paint.isLinearText() || paint.tooBigToUseCache()) {
+        if (paint.isLinearText() || SkDraw::ShouldDrawTextAsPaths(paint, SkMatrix::I())) {
             SkPaint* p = fLazy.set(paint);
             fScale = p->setupForAsPaths();
             fPaint = p;
@@ -1071,7 +1039,7 @@
 
     SkMeasureCacheProc glyphCacheProc;
     glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
-                                               NULL != bounds);
+                                               bounds);
 
     int xyIndex;
     JoinBoundsProc joinBoundsProc;
@@ -1131,8 +1099,7 @@
     return Sk48Dot16ToScalar(x);
 }
 
-SkScalar SkPaint::measureText(const void* textData, size_t length,
-                              SkRect* bounds, SkScalar zoom) const {
+SkScalar SkPaint::measureText(const void* textData, size_t length, SkRect* bounds) const {
     const char* text = (const char*)textData;
     SkASSERT(text != NULL || length == 0);
 
@@ -1140,13 +1107,7 @@
     const SkPaint& paint = canon.getPaint();
     SkScalar scale = canon.getScale();
 
-    SkMatrix zoomMatrix, *zoomPtr = NULL;
-    if (zoom) {
-        zoomMatrix.setScale(zoom, zoom);
-        zoomPtr = &zoomMatrix;
-    }
-
-    SkAutoGlyphCache    autoCache(paint, NULL, zoomPtr);
+    SkAutoGlyphCache    autoCache(paint, NULL, NULL);
     SkGlyphCache*       cache = autoCache.getCache();
 
     SkScalar width = 0;
@@ -1336,7 +1297,7 @@
         return 0;
     }
 
-    SkASSERT(NULL != textData);
+    SkASSERT(textData);
 
     if (NULL == widths && NULL == bounds) {
         return this->countText(textData, byteLength);
@@ -1350,7 +1311,7 @@
     SkGlyphCache*       cache = autoCache.getCache();
     SkMeasureCacheProc  glyphCacheProc;
     glyphCacheProc = paint.getMeasureCacheProc(kForward_TextBufferDirection,
-                                               NULL != bounds);
+                                               bounds);
 
     const char* text = (const char*)textData;
     const char* stop = text + byteLength;
@@ -1528,10 +1489,12 @@
 // return true if the paint is just a single color (i.e. not a shader). If its
 // a shader, then we can't compute a const luminance for it :(
 static bool justAColor(const SkPaint& paint, SkColor* color) {
-    if (paint.getShader()) {
+    SkColor c = paint.getColor();
+
+    SkShader* shader = paint.getShader();
+    if (shader && !shader->asLuminanceColor(&c)) {
         return false;
     }
-    SkColor c = paint.getColor();
     if (paint.getColorFilter()) {
         c = paint.getColorFilter()->filterColor(c);
     }
@@ -1584,8 +1547,7 @@
     if (NULL == typeface) {
         typeface = SkTypeface::GetDefaultTypeface();
     }
-    rec->fOrigFontID = typeface->uniqueID();
-    rec->fFontID = rec->fOrigFontID;
+    rec->fFontID = typeface->uniqueID();
     rec->fTextSize = paint.getTextSize();
     rec->fPreScaleX = paint.getTextScaleX();
     rec->fPreSkewX  = paint.getTextSkewX();
@@ -1644,19 +1606,33 @@
 
     rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
 
-    SkDeviceProperties::Geometry geometry = deviceProperties
-                                          ? deviceProperties->fGeometry
-                                          : SkDeviceProperties::Geometry::MakeDefault();
     if (SkMask::kLCD16_Format == rec->fMaskFormat || SkMask::kLCD32_Format == rec->fMaskFormat) {
-        if (!geometry.isOrientationKnown() || !geometry.isLayoutKnown() || tooBigForLCD(*rec)) {
-            // eeek, can't support LCD
+        if (tooBigForLCD(*rec)) {
             rec->fMaskFormat = SkMask::kA8_Format;
+            flags |= SkScalerContext::kGenA8FromLCD_Flag;
         } else {
-            if (SkDeviceProperties::Geometry::kVertical_Orientation == geometry.getOrientation()) {
-                flags |= SkScalerContext::kLCD_Vertical_Flag;
-            }
-            if (SkDeviceProperties::Geometry::kBGR_Layout == geometry.getLayout()) {
-                flags |= SkScalerContext::kLCD_BGROrder_Flag;
+            SkPixelGeometry geometry = deviceProperties
+                                     ? deviceProperties->fPixelGeometry
+                                     : SkSurfacePropsDefaultPixelGeometry();
+            switch (geometry) {
+                case kUnknown_SkPixelGeometry:
+                    // eeek, can't support LCD
+                    rec->fMaskFormat = SkMask::kA8_Format;
+                    flags |= SkScalerContext::kGenA8FromLCD_Flag;
+                    break;
+                case kRGB_H_SkPixelGeometry:
+                    // our default, do nothing.
+                    break;
+                case kBGR_H_SkPixelGeometry:
+                    flags |= SkScalerContext::kLCD_BGROrder_Flag;
+                    break;
+                case kRGB_V_SkPixelGeometry:
+                    flags |= SkScalerContext::kLCD_Vertical_Flag;
+                    break;
+                case kBGR_V_SkPixelGeometry:
+                    flags |= SkScalerContext::kLCD_Vertical_Flag;
+                    flags |= SkScalerContext::kLCD_BGROrder_Flag;
+                    break;
             }
         }
     }
@@ -1687,13 +1663,13 @@
         rec->setDeviceGamma(SK_GAMMA_EXPONENT);
         rec->setPaintGamma(SK_GAMMA_EXPONENT);
     } else {
-        rec->setDeviceGamma(deviceProperties->fGamma);
+        rec->setDeviceGamma(deviceProperties->getGamma());
 
         //For now always set the paint gamma equal to the device gamma.
         //The math in SkMaskGamma can handle them being different,
         //but it requires superluminous masks when
         //Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large.
-        rec->setPaintGamma(deviceProperties->fGamma);
+        rec->setPaintGamma(deviceProperties->getGamma());
     }
 
 #ifdef SK_GAMMA_CONTRAST
@@ -1786,15 +1762,10 @@
         case SkMask::kA8_Format: {
             // filter down the luminance to a single component, since A8 can't
             // use per-component information
-
             SkColor color = rec->getLuminanceColor();
-            U8CPU lum = SkColorSpaceLuminance::computeLuminance(rec->getPaintGamma(), color);
-            //If we are asked to look like LCD, look like LCD.
-            if (!(rec->fFlags & SkScalerContext::kGenA8FromLCD_Flag)) {
-                // HACK: Prevents green from being pre-blended as white.
-                lum -= ((255 - lum) * lum) / 255;
-            }
-
+            U8CPU lum = SkComputeLuminance(SkColorGetR(color),
+                                           SkColorGetG(color),
+                                           SkColorGetB(color));
             // reduce to our finite number of bits
             color = SkColorSetRGB(lum, lum, lum);
             rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color));
@@ -1862,13 +1833,6 @@
         rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
     }
 
-#ifdef SK_BUILD_FOR_ANDROID
-    SkWriteBuffer androidBuffer;
-    fPaintOptionsAndroid.flatten(androidBuffer);
-    descSize += androidBuffer.bytesWritten();
-    entryCount += 1;
-#endif
-
     ///////////////////////////////////////////////////////////////////////////
     // Now that we're done tweaking the rec, call the PostMakeRec cleanup
     SkScalerContext::PostMakeRec(*this, &rec);
@@ -1881,10 +1845,6 @@
     desc->init();
     desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
 
-#ifdef SK_BUILD_FOR_ANDROID
-    add_flattenable(desc, kAndroidOpts_SkDescriptorTag, &androidBuffer);
-#endif
-
     if (pe) {
         add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
     }
@@ -1919,11 +1879,6 @@
         desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
         desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
 
-#ifdef SK_BUILD_FOR_ANDROID
-        add_flattenable(desc1, kAndroidOpts_SkDescriptorTag, &androidBuffer);
-        add_flattenable(desc2, kAndroidOpts_SkDescriptorTag, &androidBuffer);
-#endif
-
         if (pe) {
             add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer);
             add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer);
@@ -2140,11 +2095,6 @@
         asint(this->getImageFilter())) {
         flatFlags |= kHasEffects_FlatFlag;
     }
-#ifdef SK_BUILD_FOR_ANDROID
-    if (this->getPaintOptionsAndroid() != SkPaintOptionsAndroid()) {
-        flatFlags |= kHasNonDefaultPaintOptionsAndroid_FlatFlag;
-    }
-#endif
 
     SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
     uint32_t* ptr = buffer.reserve(kPODPaintSize);
@@ -2183,11 +2133,6 @@
             buffer.writeBool(false);
         }
     }
-#ifdef SK_BUILD_FOR_ANDROID
-    if (flatFlags & kHasNonDefaultPaintOptionsAndroid_FlatFlag) {
-        this->getPaintOptionsAndroid().flatten(buffer);
-    }
-#endif
 }
 
 void SkPaint::unflatten(SkReadBuffer& buffer) {
@@ -2246,15 +2191,12 @@
         this->setImageFilter(NULL);
     }
 
-#ifdef SK_BUILD_FOR_ANDROID
-    this->setPaintOptionsAndroid(SkPaintOptionsAndroid());
-#endif
-    if (flatFlags & kHasNonDefaultPaintOptionsAndroid_FlatFlag) {
-        SkPaintOptionsAndroid options;
-        options.unflatten(buffer);
-#ifdef SK_BUILD_FOR_ANDROID
-        this->setPaintOptionsAndroid(options);
-#endif
+    if (buffer.isVersionLT(SkReadBuffer::kRemoveAndroidPaintOpts_Version) &&
+            flatFlags & kHasNonDefaultPaintOptionsAndroid_FlatFlag) {
+        SkString tag;
+        buffer.readUInt();
+        buffer.readString(&tag);
+        buffer.readBool();
     }
 }
 
@@ -2263,21 +2205,21 @@
 SkShader* SkPaint::setShader(SkShader* shader) {
     GEN_ID_INC_EVAL(shader != fShader);
     SkRefCnt_SafeAssign(fShader, shader);
-    fDirtyBits = set_mask(fDirtyBits, kShader_DirtyBit, shader != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, shader != NULL, kShader_DirtyBit);
     return shader;
 }
 
 SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) {
     GEN_ID_INC_EVAL(filter != fColorFilter);
     SkRefCnt_SafeAssign(fColorFilter, filter);
-    fDirtyBits = set_mask(fDirtyBits, kColorFilter_DirtyBit, filter != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, filter != NULL, kColorFilter_DirtyBit);
     return filter;
 }
 
 SkXfermode* SkPaint::setXfermode(SkXfermode* mode) {
     GEN_ID_INC_EVAL(mode != fXfermode);
     SkRefCnt_SafeAssign(fXfermode, mode);
-    fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, mode != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, mode != NULL, kXfermode_DirtyBit);
     return mode;
 }
 
@@ -2285,21 +2227,21 @@
     SkSafeUnref(fXfermode);
     fXfermode = SkXfermode::Create(mode);
     GEN_ID_INC;
-    fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, fXfermode != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, fXfermode != NULL, kXfermode_DirtyBit);
     return fXfermode;
 }
 
 SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) {
     GEN_ID_INC_EVAL(effect != fPathEffect);
     SkRefCnt_SafeAssign(fPathEffect, effect);
-    fDirtyBits = set_mask(fDirtyBits, kPathEffect_DirtyBit, effect != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, effect != NULL, kPathEffect_DirtyBit);
     return effect;
 }
 
 SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) {
     GEN_ID_INC_EVAL(filter != fMaskFilter);
     SkRefCnt_SafeAssign(fMaskFilter, filter);
-    fDirtyBits = set_mask(fDirtyBits, kMaskFilter_DirtyBit, filter != NULL);
+    fDirtyBits = SkSetClearMask(fDirtyBits, filter != NULL, kMaskFilter_DirtyBit);
     return filter;
 }
 
@@ -2378,17 +2320,16 @@
 }
 
 #ifndef SK_IGNORE_TO_STRING
+
 void SkPaint::toString(SkString* str) const {
     str->append("<dl><dt>SkPaint:</dt><dd><dl>");
 
     SkTypeface* typeface = this->getTypeface();
-    if (NULL != typeface) {
+    if (typeface) {
         SkDynamicMemoryWStream ostream;
         typeface->serialize(&ostream);
-        SkAutoTUnref<SkData> data(ostream.copyToData());
-
-        SkMemoryStream stream(data);
-        SkFontDescriptor descriptor(&stream);
+        SkAutoTUnref<SkStreamAsset> istream(ostream.detachAsStream());
+        SkFontDescriptor descriptor(istream);
 
         str->append("<dt>Font Family Name:</dt><dd>");
         str->append(descriptor.getFamilyName());
@@ -2414,60 +2355,60 @@
     str->append("</dd>");
 
     SkPathEffect* pathEffect = this->getPathEffect();
-    if (NULL != pathEffect) {
+    if (pathEffect) {
         str->append("<dt>PathEffect:</dt><dd>");
         str->append("</dd>");
     }
 
     SkShader* shader = this->getShader();
-    if (NULL != shader) {
+    if (shader) {
         str->append("<dt>Shader:</dt><dd>");
         shader->toString(str);
         str->append("</dd>");
     }
 
     SkXfermode* xfer = this->getXfermode();
-    if (NULL != xfer) {
+    if (xfer) {
         str->append("<dt>Xfermode:</dt><dd>");
         xfer->toString(str);
         str->append("</dd>");
     }
 
     SkMaskFilter* maskFilter = this->getMaskFilter();
-    if (NULL != maskFilter) {
+    if (maskFilter) {
         str->append("<dt>MaskFilter:</dt><dd>");
         maskFilter->toString(str);
         str->append("</dd>");
     }
 
     SkColorFilter* colorFilter = this->getColorFilter();
-    if (NULL != colorFilter) {
+    if (colorFilter) {
         str->append("<dt>ColorFilter:</dt><dd>");
         colorFilter->toString(str);
         str->append("</dd>");
     }
 
     SkRasterizer* rasterizer = this->getRasterizer();
-    if (NULL != rasterizer) {
+    if (rasterizer) {
         str->append("<dt>Rasterizer:</dt><dd>");
         str->append("</dd>");
     }
 
     SkDrawLooper* looper = this->getLooper();
-    if (NULL != looper) {
+    if (looper) {
         str->append("<dt>DrawLooper:</dt><dd>");
         looper->toString(str);
         str->append("</dd>");
     }
 
     SkImageFilter* imageFilter = this->getImageFilter();
-    if (NULL != imageFilter) {
+    if (imageFilter) {
         str->append("<dt>ImageFilter:</dt><dd>");
         str->append("</dd>");
     }
 
     SkAnnotation* annotation = this->getAnnotation();
-    if (NULL != annotation) {
+    if (annotation) {
         str->append("<dt>Annotation:</dt><dd>");
         str->append("</dd>");
     }
@@ -2670,10 +2611,6 @@
     return false;
 }
 
-void SkPaint::setBitfields(uint32_t bitfields) {
-    fBitfields = bitfields;
-}
-
 inline static unsigned popcount(uint8_t x) {
     // As in Hacker's delight, adapted for just 8 bits.
     x = (x & 0x55) + ((x >> 1) & 0x55);  // a b c d w x y z -> a+b c+d w+x y+z
@@ -2691,7 +2628,7 @@
     SkASSERT(flatBytes <= 32);
     uint32_t* u32 = buffer.reserve(flatBytes);
     *u32++ = dirty;
-    *u32++ = paint.getBitfields();
+    *u32++ = paint.fBitfieldsUInt;
     if (0 == dirty) {
         return;
     }
@@ -2717,14 +2654,11 @@
 #undef F
     if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface());
     if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffer);
-#ifdef SK_BUILD_FOR_ANDROID
-    if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().flatten(buffer);
-#endif
 }
 
 void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) {
     const uint32_t dirty = buffer.readUInt();
-    paint->setBitfields(buffer.readUInt());
+    paint->fBitfieldsUInt = buffer.readUInt();
     if (dirty == 0) {
         return;
     }
@@ -2754,12 +2688,5 @@
     if (dirty & kAnnotation_DirtyBit) {
         paint->setAnnotation(SkAnnotation::Create(buffer))->unref();
     }
-#ifdef SK_BUILD_FOR_ANDROID
-    if (dirty & kPaintOptionsAndroid_DirtyBit) {
-        SkPaintOptionsAndroid options;
-        options.unflatten(buffer);
-        paint->setPaintOptionsAndroid(options);
-    }
-#endif
     SkASSERT(dirty == paint->fDirtyBits);
 }
diff --git a/src/core/SkPaintOptionsAndroid.cpp b/src/core/SkPaintOptionsAndroid.cpp
deleted file mode 100644
index 56f1bd1..0000000
--- a/src/core/SkPaintOptionsAndroid.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-
-/*
- * Copyright 2012 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkPaintOptionsAndroid.h"
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
-#include "SkTDict.h"
-#include "SkThread.h"
-#include <cstring>
-
-SkLanguage SkLanguage::getParent() const {
-    SkASSERT(!fTag.isEmpty());
-    const char* tag = fTag.c_str();
-
-    // strip off the rightmost "-.*"
-    const char* parentTagEnd = strrchr(tag, '-');
-    if (parentTagEnd == NULL) {
-        return SkLanguage();
-    }
-    size_t parentTagLen = parentTagEnd - tag;
-    return SkLanguage(tag, parentTagLen);
-}
-
-void SkPaintOptionsAndroid::flatten(SkWriteBuffer& buffer) const {
-    buffer.writeUInt(fFontVariant);
-    buffer.writeString(fLanguage.getTag().c_str());
-    buffer.writeBool(fUseFontFallbacks);
-}
-
-void SkPaintOptionsAndroid::unflatten(SkReadBuffer& buffer) {
-    fFontVariant = (FontVariant)buffer.readUInt();
-    SkString tag;
-    buffer.readString(&tag);
-    fLanguage = SkLanguage(tag);
-    fUseFontFallbacks = buffer.readBool();
-}
diff --git a/src/core/SkPaintPriv.cpp b/src/core/SkPaintPriv.cpp
index a8b52e9..d7b3032 100644
--- a/src/core/SkPaintPriv.cpp
+++ b/src/core/SkPaintPriv.cpp
@@ -85,13 +85,5 @@
      *  Eventually we hope this list will be empty, and we can always return
      *  false.
      */
-    return false
-#ifdef SK_SUPPORT_LEGACY_SHADER_LOCALMATRIX
-           || paint.getShader()
-#endif
-#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API
-           || paint.getRasterizer()
-#endif
-           || paint.getImageFilter()
-           ;
+    return paint.getImageFilter();
 }
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 075cfdb..06f8b7e 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -671,6 +671,8 @@
     fLastMoveToIndex = fPathRef->countPoints();
 
     ed.growForVerb(kMove_Verb)->set(x, y);
+
+    DIRTY_AFTER_EDIT;
 }
 
 void SkPath::rMoveTo(SkScalar x, SkScalar y) {
@@ -1089,11 +1091,6 @@
         this->addRect(bounds, dir);
     } else if (rrect.isOval()) {
         this->addOval(bounds, dir);
-#ifdef SK_IGNORE_QUAD_RR_CORNERS_OPT
-    } else if (rrect.isSimple()) {
-        const SkVector& rad = rrect.getSimpleRadii();
-        this->addRoundRect(bounds, rad.x(), rad.y(), dir);
-#endif
     } else {
         fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction;
 
@@ -1135,10 +1132,6 @@
     return true;
 }
 
-#ifdef SK_IGNORE_QUAD_RR_CORNERS_OPT
-#define CUBIC_ARC_FACTOR    ((SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3)
-#endif
-
 void SkPath::addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
                           Direction dir) {
     assert_known_direction(dir);
@@ -1151,96 +1144,9 @@
         return;
     }
 
-#ifdef SK_IGNORE_QUAD_RR_CORNERS_OPT
-    SkScalar    w = rect.width();
-    SkScalar    halfW = SkScalarHalf(w);
-    SkScalar    h = rect.height();
-    SkScalar    halfH = SkScalarHalf(h);
-
-    if (halfW <= 0 || halfH <= 0) {
-        return;
-    }
-
-    bool skip_hori = rx >= halfW;
-    bool skip_vert = ry >= halfH;
-
-    if (skip_hori && skip_vert) {
-        this->addOval(rect, dir);
-        return;
-    }
-
-    fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction;
-
-    SkAutoPathBoundsUpdate apbu(this, rect);
-    SkAutoDisableDirectionCheck addc(this);
-
-    if (skip_hori) {
-        rx = halfW;
-    } else if (skip_vert) {
-        ry = halfH;
-    }
-    SkScalar    sx = SkScalarMul(rx, CUBIC_ARC_FACTOR);
-    SkScalar    sy = SkScalarMul(ry, CUBIC_ARC_FACTOR);
-
-    this->incReserve(17);
-    this->moveTo(rect.fRight - rx, rect.fTop);                  // top-right
-    if (dir == kCCW_Direction) {
-        if (!skip_hori) {
-            this->lineTo(rect.fLeft + rx, rect.fTop);           // top
-        }
-        this->cubicTo(rect.fLeft + rx - sx, rect.fTop,
-                      rect.fLeft, rect.fTop + ry - sy,
-                      rect.fLeft, rect.fTop + ry);          // top-left
-        if (!skip_vert) {
-            this->lineTo(rect.fLeft, rect.fBottom - ry);        // left
-        }
-        this->cubicTo(rect.fLeft, rect.fBottom - ry + sy,
-                      rect.fLeft + rx - sx, rect.fBottom,
-                      rect.fLeft + rx, rect.fBottom);       // bot-left
-        if (!skip_hori) {
-            this->lineTo(rect.fRight - rx, rect.fBottom);       // bottom
-        }
-        this->cubicTo(rect.fRight - rx + sx, rect.fBottom,
-                      rect.fRight, rect.fBottom - ry + sy,
-                      rect.fRight, rect.fBottom - ry);      // bot-right
-        if (!skip_vert) {
-            this->lineTo(rect.fRight, rect.fTop + ry);          // right
-        }
-        this->cubicTo(rect.fRight, rect.fTop + ry - sy,
-                      rect.fRight - rx + sx, rect.fTop,
-                      rect.fRight - rx, rect.fTop);         // top-right
-    } else {
-        this->cubicTo(rect.fRight - rx + sx, rect.fTop,
-                      rect.fRight, rect.fTop + ry - sy,
-                      rect.fRight, rect.fTop + ry);         // top-right
-        if (!skip_vert) {
-            this->lineTo(rect.fRight, rect.fBottom - ry);       // right
-        }
-        this->cubicTo(rect.fRight, rect.fBottom - ry + sy,
-                      rect.fRight - rx + sx, rect.fBottom,
-                      rect.fRight - rx, rect.fBottom);      // bot-right
-        if (!skip_hori) {
-            this->lineTo(rect.fLeft + rx, rect.fBottom);        // bottom
-        }
-        this->cubicTo(rect.fLeft + rx - sx, rect.fBottom,
-                      rect.fLeft, rect.fBottom - ry + sy,
-                      rect.fLeft, rect.fBottom - ry);       // bot-left
-        if (!skip_vert) {
-            this->lineTo(rect.fLeft, rect.fTop + ry);           // left
-        }
-        this->cubicTo(rect.fLeft, rect.fTop + ry - sy,
-                      rect.fLeft + rx - sx, rect.fTop,
-                      rect.fLeft + rx, rect.fTop);          // top-left
-        if (!skip_hori) {
-            this->lineTo(rect.fRight - rx, rect.fTop);          // top
-        }
-    }
-    this->close();
-#else
     SkRRect rrect;
     rrect.setRectXY(rect, rx, ry);
     this->addRRect(rrect, dir);
-#endif
 }
 
 void SkPath::addOval(const SkRect& oval, Direction dir) {
@@ -2008,7 +1914,7 @@
 }
 
 SkPath::Verb SkPath::RawIter::next(SkPoint pts[4]) {
-    SkASSERT(NULL != pts);
+    SkASSERT(pts);
     if (fVerbs == fVerbStop) {
         return kDone_Verb;
     }
@@ -2101,7 +2007,7 @@
         SkDEBUGCODE(this->validate();)
         buffer.skipToAlign4();
         sizeRead = buffer.pos();
-    } else if (NULL != pathRef) {
+    } else if (pathRef) {
         // If the buffer is not valid, pathRef should be NULL
         sk_throw();
     }
@@ -2111,8 +2017,13 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "SkString.h"
+#include "SkStream.h"
 
-static void append_scalar(SkString* str, SkScalar value) {
+static void append_scalar(SkString* str, SkScalar value, bool dumpAsHex) {
+    if (dumpAsHex) {
+        str->appendf("SkBits2Float(0x%08x)", SkFloat2Bits(value));
+        return;
+    }
     SkString tmp;
     tmp.printf("%g", value);
     if (tmp.contains('.')) {
@@ -2122,7 +2033,7 @@
 }
 
 static void append_params(SkString* str, const char label[], const SkPoint pts[],
-                          int count, SkScalar conicWeight = -1) {
+                          int count, bool dumpAsHex, SkScalar conicWeight = -1) {
     str->append(label);
     str->append("(");
 
@@ -2130,47 +2041,47 @@
     count *= 2;
 
     for (int i = 0; i < count; ++i) {
-        append_scalar(str, values[i]);
+        append_scalar(str, values[i], dumpAsHex);
         if (i < count - 1) {
             str->append(", ");
         }
     }
     if (conicWeight >= 0) {
         str->append(", ");
-        append_scalar(str, conicWeight);
+        append_scalar(str, conicWeight, dumpAsHex);
     }
     str->append(");\n");
 }
 
-void SkPath::dump(bool forceClose, const char title[]) const {
+void SkPath::dump(SkWStream* wStream, bool forceClose, bool dumpAsHex) const {
     Iter    iter(*this, forceClose);
     SkPoint pts[4];
     Verb    verb;
 
-    SkDebugf("path: forceClose=%s %s\n", forceClose ? "true" : "false",
-             title ? title : "");
-
+    if (!wStream) {
+        SkDebugf("path: forceClose=%s\n", forceClose ? "true" : "false");
+    }
     SkString builder;
 
     while ((verb = iter.next(pts, false)) != kDone_Verb) {
         switch (verb) {
             case kMove_Verb:
-                append_params(&builder, "path.moveTo", &pts[0], 1);
+                append_params(&builder, "path.moveTo", &pts[0], 1, dumpAsHex);
                 break;
             case kLine_Verb:
-                append_params(&builder, "path.lineTo", &pts[1], 1);
+                append_params(&builder, "path.lineTo", &pts[1], 1, dumpAsHex);
                 break;
             case kQuad_Verb:
-                append_params(&builder, "path.quadTo", &pts[1], 2);
+                append_params(&builder, "path.quadTo", &pts[1], 2, dumpAsHex);
                 break;
             case kConic_Verb:
-                append_params(&builder, "path.conicTo", &pts[1], 2, iter.conicWeight());
+                append_params(&builder, "path.conicTo", &pts[1], 2, dumpAsHex, iter.conicWeight());
                 break;
             case kCubic_Verb:
-                append_params(&builder, "path.cubicTo", &pts[1], 3);
+                append_params(&builder, "path.cubicTo", &pts[1], 3, dumpAsHex);
                 break;
             case kClose_Verb:
-                builder.append("path.close();");
+                builder.append("path.close();\n");
                 break;
             default:
                 SkDebugf("  path: UNKNOWN VERB %d, aborting dump...\n", verb);
@@ -2178,11 +2089,19 @@
                 break;
         }
     }
-    SkDebugf("%s\n", builder.c_str());
+    if (wStream) {
+        wStream->writeText(builder.c_str());
+    } else {
+        SkDebugf("%s", builder.c_str());
+    }
 }
 
 void SkPath::dump() const {
-    this->dump(false);
+    this->dump(NULL, false, false);
+}
+
+void SkPath::dumpHex() const {
+    this->dump(NULL, false, true);
 }
 
 #ifdef SK_DEBUG
@@ -2223,6 +2142,16 @@
 static int sign(SkScalar x) { return x < 0; }
 #define kValueNeverReturnedBySign   2
 
+enum DirChange {
+    kLeft_DirChange,
+    kRight_DirChange,
+    kStraight_DirChange,
+    kBackwards_DirChange,
+
+    kInvalid_DirChange
+};
+
+
 static bool almost_equal(SkScalar compA, SkScalar compB) {
     // The error epsilon was empirically derived; worse case round rects
     // with a mid point outset by 2x float epsilon in tests had an error
@@ -2237,13 +2166,37 @@
     return aBits < bBits + epsilon && bBits < aBits + epsilon;
 }
 
+static DirChange direction_change(const SkPoint& lastPt, const SkVector& curPt,
+                                  const SkVector& lastVec, const SkVector& curVec) {
+    SkScalar cross = SkPoint::CrossProduct(lastVec, curVec);
+
+    SkScalar smallest = SkTMin(curPt.fX, SkTMin(curPt.fY, SkTMin(lastPt.fX, lastPt.fY)));
+    SkScalar largest = SkTMax(curPt.fX, SkTMax(curPt.fY, SkTMax(lastPt.fX, lastPt.fY)));
+    largest = SkTMax(largest, -smallest);
+
+    if (!almost_equal(largest, largest + cross)) {
+        int sign = SkScalarSignAsInt(cross);
+        if (sign) {
+            return (1 == sign) ? kRight_DirChange : kLeft_DirChange;
+        }
+    }
+
+    if (!SkScalarNearlyZero(lastVec.lengthSqd(), SK_ScalarNearlyZero*SK_ScalarNearlyZero) &&
+        !SkScalarNearlyZero(curVec.lengthSqd(), SK_ScalarNearlyZero*SK_ScalarNearlyZero) &&
+        lastVec.dot(curVec) < 0.0f) {
+        return kBackwards_DirChange;
+    }
+
+    return kStraight_DirChange;
+}
+
 // only valid for a single contour
 struct Convexicator {
     Convexicator()
     : fPtCount(0)
     , fConvexity(SkPath::kConvex_Convexity)
     , fDirection(SkPath::kUnknown_Direction) {
-        fSign = 0;
+        fExpectedDir = kInvalid_DirChange;
         // warnings
         fLastPt.set(0, 0);
         fCurrPt.set(0, 0);
@@ -2302,20 +2255,28 @@
 private:
     void addVec(const SkVector& vec) {
         SkASSERT(vec.fX || vec.fY);
-        SkScalar cross = SkPoint::CrossProduct(fLastVec, vec);
-        SkScalar smallest = SkTMin(fCurrPt.fX, SkTMin(fCurrPt.fY, SkTMin(fLastPt.fX, fLastPt.fY)));
-        SkScalar largest = SkTMax(fCurrPt.fX, SkTMax(fCurrPt.fY, SkTMax(fLastPt.fX, fLastPt.fY)));
-        largest = SkTMax(largest, -smallest);
-        if (!almost_equal(largest, largest + cross)) {
-            int sign = SkScalarSignAsInt(cross);
-            if (0 == fSign) {
-                fSign = sign;
-                fDirection = (1 == sign) ? SkPath::kCW_Direction : SkPath::kCCW_Direction;
-            } else if (sign && fSign != sign) {
-                fConvexity = SkPath::kConcave_Convexity;
-                fDirection = SkPath::kUnknown_Direction;
-            }
-            fLastVec = vec;
+        DirChange dir = direction_change(fLastPt, fCurrPt, fLastVec, vec);
+        switch (dir) {
+            case kLeft_DirChange:       // fall through
+            case kRight_DirChange:
+                if (kInvalid_DirChange == fExpectedDir) {
+                    fExpectedDir = dir;
+                    fDirection = (kRight_DirChange == dir) ? SkPath::kCW_Direction
+                                                           : SkPath::kCCW_Direction;
+                } else if (dir != fExpectedDir) {
+                    fConvexity = SkPath::kConcave_Convexity;
+                    fDirection = SkPath::kUnknown_Direction;
+                }
+                fLastVec = vec;
+                break;
+            case kStraight_DirChange:
+                break;
+            case kBackwards_DirChange:
+                fLastVec = vec;
+                break;
+            case kInvalid_DirChange:
+                SkFAIL("Use of invalid direction change flag");
+                break;
         }
     }
 
@@ -2325,7 +2286,7 @@
     // value with the current vec is deemed to be of a significant value.
     SkVector            fLastVec, fFirstVec;
     int                 fPtCount;   // non-degenerate points
-    int                 fSign;
+    DirChange           fExpectedDir;
     SkPath::Convexity   fConvexity;
     SkPath::Direction   fDirection;
     int                 fDx, fDy, fSx, fSy;
diff --git a/src/core/SkPathEffect.cpp b/src/core/SkPathEffect.cpp
index 01d5d6f..d074867 100644
--- a/src/core/SkPathEffect.cpp
+++ b/src/core/SkPathEffect.cpp
@@ -45,19 +45,26 @@
     Format: [oe0-factory][pe1-factory][pe0-size][pe0-data][pe1-data]
 */
 void SkPairPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeFlattenable(fPE0);
     buffer.writeFlattenable(fPE1);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkPairPathEffect::SkPairPathEffect(SkReadBuffer& buffer) {
     fPE0 = buffer.readPathEffect();
     fPE1 = buffer.readPathEffect();
     // either of these may fail, so we have to check for nulls later on
 }
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
+SkFlattenable* SkComposePathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkPathEffect> pe0(buffer.readPathEffect());
+    SkAutoTUnref<SkPathEffect> pe1(buffer.readPathEffect());
+    return SkComposePathEffect::Create(pe0, pe1);
+}
+
 bool SkComposePathEffect::filterPath(SkPath* dst, const SkPath& src,
                              SkStrokeRec* rec, const SkRect* cullRect) const {
     // we may have failed to unflatten these, so we have to check
@@ -76,6 +83,12 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+SkFlattenable* SkSumPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkPathEffect> pe0(buffer.readPathEffect());
+    SkAutoTUnref<SkPathEffect> pe1(buffer.readPathEffect());
+    return SkSumPathEffect::Create(pe0, pe1);
+}
+
 bool SkSumPathEffect::filterPath(SkPath* dst, const SkPath& src,
                              SkStrokeRec* rec, const SkRect* cullRect) const {
     // use bit-or so that we always call both, even if the first one succeeds
diff --git a/src/core/SkPathRef.cpp b/src/core/SkPathRef.cpp
index de7a8f5..5707693 100644
--- a/src/core/SkPathRef.cpp
+++ b/src/core/SkPathRef.cpp
@@ -30,9 +30,9 @@
 //////////////////////////////////////////////////////////////////////////////
 
 SkPathRef* SkPathRef::CreateEmptyImpl() {
-    SkPathRef* p = SkNEW(SkPathRef);
-    p->computeBounds();   // Preemptively avoid a race to clear fBoundsIsDirty.
-    return p;
+    SkPathRef* empty = SkNEW(SkPathRef);
+    empty->computeBounds();   // Avoids races later to be the first to do this.
+    return empty;
 }
 
 SkPathRef* SkPathRef::CreateEmpty() {
@@ -85,13 +85,13 @@
     if (canXformBounds) {
         (*dst)->fBoundsIsDirty = false;
         if (src.fIsFinite) {
-            matrix.mapRect(&(*dst)->fBounds, src.fBounds);
-            if (!((*dst)->fIsFinite = (*dst)->fBounds.isFinite())) {
-                (*dst)->fBounds.setEmpty();
+            matrix.mapRect((*dst)->fBounds.get(), src.fBounds);
+            if (!((*dst)->fIsFinite = (*dst)->fBounds->isFinite())) {
+                (*dst)->fBounds->setEmpty();
             }
         } else {
             (*dst)->fIsFinite = false;
-            (*dst)->fBounds.setEmpty();
+            (*dst)->fBounds->setEmpty();
         }
     } else {
         (*dst)->fBoundsIsDirty = true;
@@ -345,7 +345,7 @@
     }
 
     if (SkPath::kConic_Verb == verb) {
-        SkASSERT(NULL != weights);
+        SkASSERT(weights);
         *weights = fConicWeights.append(numVbs);
     }
 
@@ -441,14 +441,14 @@
     SkASSERT(this->currSize() ==
                 fFreeSpace + sizeof(SkPoint) * fPointCnt + sizeof(uint8_t) * fVerbCnt);
 
-    if (!fBoundsIsDirty && !fBounds.isEmpty()) {
+    if (!fBoundsIsDirty && !fBounds->isEmpty()) {
         bool isFinite = true;
         for (int i = 0; i < fPointCnt; ++i) {
             SkASSERT(!fPoints[i].isFinite() || (
-                     fBounds.fLeft - fPoints[i].fX   < SK_ScalarNearlyZero &&
-                     fPoints[i].fX - fBounds.fRight  < SK_ScalarNearlyZero &&
-                     fBounds.fTop  - fPoints[i].fY   < SK_ScalarNearlyZero &&
-                     fPoints[i].fY - fBounds.fBottom < SK_ScalarNearlyZero));
+                     fBounds->fLeft - fPoints[i].fX   < SK_ScalarNearlyZero &&
+                     fPoints[i].fX - fBounds->fRight  < SK_ScalarNearlyZero &&
+                     fBounds->fTop  - fPoints[i].fY   < SK_ScalarNearlyZero &&
+                     fPoints[i].fY - fBounds->fBottom < SK_ScalarNearlyZero));
             if (!fPoints[i].isFinite()) {
                 isFinite = false;
             }
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index 76c2b9d..19ff36d 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -8,18 +8,24 @@
 
 
 #include "SkPictureFlat.h"
+#include "SkPictureData.h"
 #include "SkPicturePlayback.h"
 #include "SkPictureRecord.h"
+#include "SkPictureRecorder.h"
+#include "SkPictureStateTree.h"
 
-#include "SkBBHFactory.h"
 #include "SkBitmapDevice.h"
 #include "SkCanvas.h"
 #include "SkChunkAlloc.h"
+#include "SkDrawPictureCallback.h"
 #include "SkPaintPriv.h"
+#include "SkPathEffect.h"
 #include "SkPicture.h"
 #include "SkRegion.h"
+#include "SkShader.h"
 #include "SkStream.h"
 #include "SkTDArray.h"
+#include "SkTLogic.h"
 #include "SkTSearch.h"
 #include "SkTime.h"
 
@@ -32,217 +38,269 @@
 #include "GrContext.h"
 #endif
 
+#include "SkRecord.h"
+#include "SkRecordDraw.h"
+#include "SkRecordOpts.h"
+#include "SkRecorder.h"
+
 template <typename T> int SafeCount(const T* obj) {
     return obj ? obj->count() : 0;
 }
 
-#define DUMP_BUFFER_SIZE 65536
-
-//#define ENABLE_TIME_DRAW    // dumps milliseconds for each draw
-
-
-#ifdef SK_DEBUG
-// enable SK_DEBUG_TRACE to trace DrawType elements when
-//     recorded and played back
-// #define SK_DEBUG_TRACE
-// enable SK_DEBUG_SIZE to see the size of picture components
-// #define SK_DEBUG_SIZE
-// enable SK_DEBUG_DUMP to see the contents of recorded elements
-// #define SK_DEBUG_DUMP
-// enable SK_DEBUG_VALIDATE to check internal structures for consistency
-// #define SK_DEBUG_VALIDATE
-#endif
-
-#if defined SK_DEBUG_TRACE || defined SK_DEBUG_DUMP
-const char* DrawTypeToString(DrawType drawType) {
-    switch (drawType) {
-        case UNUSED: SkDebugf("DrawType UNUSED\n"); SkASSERT(0); break;
-        case CLIP_PATH: return "CLIP_PATH";
-        case CLIP_REGION: return "CLIP_REGION";
-        case CLIP_RECT: return "CLIP_RECT";
-        case CLIP_RRECT: return "CLIP_RRECT";
-        case CONCAT: return "CONCAT";
-        case DRAW_BITMAP: return "DRAW_BITMAP";
-        case DRAW_BITMAP_MATRIX: return "DRAW_BITMAP_MATRIX";
-        case DRAW_BITMAP_NINE: return "DRAW_BITMAP_NINE";
-        case DRAW_BITMAP_RECT_TO_RECT: return "DRAW_BITMAP_RECT_TO_RECT";
-        case DRAW_CLEAR: return "DRAW_CLEAR";
-        case DRAW_DATA: return "DRAW_DATA";
-        case DRAW_OVAL: return "DRAW_OVAL";
-        case DRAW_PAINT: return "DRAW_PAINT";
-        case DRAW_PATH: return "DRAW_PATH";
-        case DRAW_PICTURE: return "DRAW_PICTURE";
-        case DRAW_POINTS: return "DRAW_POINTS";
-        case DRAW_POS_TEXT: return "DRAW_POS_TEXT";
-        case DRAW_POS_TEXT_TOP_BOTTOM: return "DRAW_POS_TEXT_TOP_BOTTOM";
-        case DRAW_POS_TEXT_H: return "DRAW_POS_TEXT_H";
-        case DRAW_POS_TEXT_H_TOP_BOTTOM: return "DRAW_POS_TEXT_H_TOP_BOTTOM";
-        case DRAW_RECT: return "DRAW_RECT";
-        case DRAW_RRECT: return "DRAW_RRECT";
-        case DRAW_SPRITE: return "DRAW_SPRITE";
-        case DRAW_TEXT: return "DRAW_TEXT";
-        case DRAW_TEXT_ON_PATH: return "DRAW_TEXT_ON_PATH";
-        case DRAW_TEXT_TOP_BOTTOM: return "DRAW_TEXT_TOP_BOTTOM";
-        case DRAW_VERTICES: return "DRAW_VERTICES";
-        case RESTORE: return "RESTORE";
-        case ROTATE: return "ROTATE";
-        case SAVE: return "SAVE";
-        case SAVE_LAYER: return "SAVE_LAYER";
-        case SCALE: return "SCALE";
-        case SET_MATRIX: return "SET_MATRIX";
-        case SKEW: return "SKEW";
-        case TRANSLATE: return "TRANSLATE";
-        case NOOP: return "NOOP";
-        default:
-            SkDebugf("DrawType error 0x%08x\n", drawType);
-            SkASSERT(0);
-            break;
-    }
-    SkASSERT(0);
-    return NULL;
-}
-#endif
-
-#ifdef SK_DEBUG_VALIDATE
-static void validateMatrix(const SkMatrix* matrix) {
-    SkScalar scaleX = matrix->getScaleX();
-    SkScalar scaleY = matrix->getScaleY();
-    SkScalar skewX = matrix->getSkewX();
-    SkScalar skewY = matrix->getSkewY();
-    SkScalar perspX = matrix->getPerspX();
-    SkScalar perspY = matrix->getPerspY();
-    if (scaleX != 0 && skewX != 0)
-        SkDebugf("scaleX != 0 && skewX != 0\n");
-    SkASSERT(scaleX == 0 || skewX == 0);
-    SkASSERT(scaleY == 0 || skewY == 0);
-    SkASSERT(perspX == 0);
-    SkASSERT(perspY == 0);
-}
-#endif
-
-
 ///////////////////////////////////////////////////////////////////////////////
 
-SkPicture::SkPicture()
-    : fAccelData(NULL) {
-    this->needsNewGenID();
-    fPlayback = NULL;
-    fWidth = fHeight = 0;
-}
+namespace {
 
-SkPicture::SkPicture(int width, int height,
-                     const SkPictureRecord& record,
-                     bool deepCopyOps)
-    : fWidth(width)
-    , fHeight(height)
-    , fAccelData(NULL) {
-    this->needsNewGenID();
+// Some commands have a paint, some have an optional paint.  Either way, get back a pointer.
+static const SkPaint* AsPtr(const SkPaint& p) { return &p; }
+static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return p; }
 
-    SkPictInfo info;
-    this->createHeader(&info);
-    fPlayback = SkNEW_ARGS(SkPicturePlayback, (record, info, deepCopyOps));
-}
+/** SkRecords visitor to determine whether an instance may require an
+    "external" bitmap to rasterize. May return false positives.
+    Does not return true for bitmap text.
 
-SkPicture::SkPicture(const SkPicture& src)
-    : INHERITED()
-    , fAccelData(NULL) {
-    this->needsNewGenID();
-    fWidth = src.fWidth;
-    fHeight = src.fHeight;
+    Expected use is to determine whether images need to be decoded before
+    rasterizing a particular SkRecord.
+ */
+struct BitmapTester {
+    // Helpers.  These create HasMember_bitmap and HasMember_paint.
+    SK_CREATE_MEMBER_DETECTOR(bitmap);
+    SK_CREATE_MEMBER_DETECTOR(paint);
 
-    if (src.fPlayback) {
-        fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fPlayback));
-        fUniqueID = src.uniqueID();     // need to call method to ensure != 0
-    } else {
-        fPlayback = NULL;
-    }
-}
 
-SkPicture::~SkPicture() {
-    SkDELETE(fPlayback);
-    SkSafeUnref(fAccelData);
-}
+    // Main entry for visitor:
+    // If the command is a DrawPicture, recurse.
+    // If the command has a bitmap directly, return true.
+    // If the command has a paint and the paint has a bitmap, return true.
+    // Otherwise, return false.
+    bool operator()(const SkRecords::DrawPicture& op) { return op.picture->willPlayBackBitmaps(); }
 
-void SkPicture::swap(SkPicture& other) {
-    SkTSwap(fUniqueID, other.fUniqueID);
-    SkTSwap(fPlayback, other.fPlayback);
-    SkTSwap(fAccelData, other.fAccelData);
-    SkTSwap(fWidth, other.fWidth);
-    SkTSwap(fHeight, other.fHeight);
-}
+    template <typename T>
+    bool operator()(const T& r) { return CheckBitmap(r); }
 
-SkPicture* SkPicture::clone() const {
-    SkPicture* clonedPicture = SkNEW(SkPicture);
-    this->clone(clonedPicture, 1);
-    return clonedPicture;
-}
 
-void SkPicture::clone(SkPicture* pictures, int count) const {
-    SkPictCopyInfo copyInfo;
+    // If the command has a bitmap, of course we're going to play back bitmaps.
+    template <typename T>
+    static SK_WHEN(HasMember_bitmap<T>, bool) CheckBitmap(const T&) { return true; }
 
-    for (int i = 0; i < count; i++) {
-        SkPicture* clone = &pictures[i];
+    // If not, look for one in its paint (if it has a paint).
+    template <typename T>
+    static SK_WHEN(!HasMember_bitmap<T>, bool) CheckBitmap(const T& r) { return CheckPaint(r); }
 
-        clone->needsNewGenID();
-        clone->fWidth = fWidth;
-        clone->fHeight = fHeight;
-        SkDELETE(clone->fPlayback);
-
-        /*  We want to copy the src's playback. However, if that hasn't been built
-            yet, we need to fake a call to endRecording() without actually calling
-            it (since it is destructive, and we don't want to change src).
-         */
-        if (fPlayback) {
-            if (!copyInfo.initialized) {
-                int paintCount = SafeCount(fPlayback->fPaints);
-
-                /* The alternative to doing this is to have a clone method on the paint and have it
-                 * make the deep copy of its internal structures as needed. The holdup to doing
-                 * that is at this point we would need to pass the SkBitmapHeap so that we don't
-                 * unnecessarily flatten the pixels in a bitmap shader.
-                 */
-                copyInfo.paintData.setCount(paintCount);
-
-                /* Use an SkBitmapHeap to avoid flattening bitmaps in shaders. If there already is
-                 * one, use it. If this SkPicturePlayback was created from a stream, fBitmapHeap
-                 * will be NULL, so create a new one.
-                 */
-                if (fPlayback->fBitmapHeap.get() == NULL) {
-                    // FIXME: Put this on the stack inside SkPicture::clone.
-                    SkBitmapHeap* heap = SkNEW(SkBitmapHeap);
-                    copyInfo.controller.setBitmapStorage(heap);
-                    heap->unref();
-                } else {
-                    copyInfo.controller.setBitmapStorage(fPlayback->fBitmapHeap);
-                }
-
-                SkDEBUGCODE(int heapSize = SafeCount(fPlayback->fBitmapHeap.get());)
-                for (int i = 0; i < paintCount; i++) {
-                    if (NeedsDeepCopy(fPlayback->fPaints->at(i))) {
-                        copyInfo.paintData[i] =
-                            SkFlatData::Create<SkPaint::FlatteningTraits>(&copyInfo.controller,
-                                                              fPlayback->fPaints->at(i), 0);
-
-                    } else {
-                        // this is our sentinel, which we use in the unflatten loop
-                        copyInfo.paintData[i] = NULL;
-                    }
-                }
-                SkASSERT(SafeCount(fPlayback->fBitmapHeap.get()) == heapSize);
-
-                // needed to create typeface playback
-                copyInfo.controller.setupPlaybacks();
-                copyInfo.initialized = true;
+    // If we have a paint, dig down into the effects looking for a bitmap.
+    template <typename T>
+    static SK_WHEN(HasMember_paint<T>, bool) CheckPaint(const T& r) {
+        const SkPaint* paint = AsPtr(r.paint);
+        if (paint) {
+            const SkShader* shader = paint->getShader();
+            if (shader &&
+                shader->asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType) {
+                return true;
             }
+        }
+        return false;
+    }
 
-            clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, &copyInfo));
-            clone->fUniqueID = this->uniqueID(); // need to call method to ensure != 0
-        } else {
-            clone->fPlayback = NULL;
+    // If we don't have a paint, that non-paint has no bitmap.
+    template <typename T>
+    static SK_WHEN(!HasMember_paint<T>, bool) CheckPaint(const T&) { return false; }
+};
+
+bool WillPlaybackBitmaps(const SkRecord& record) {
+    BitmapTester tester;
+    for (unsigned i = 0; i < record.count(); i++) {
+        if (record.visit<bool>(i, tester)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+// SkRecord visitor to find recorded text.
+struct TextHunter {
+    // All ops with text have that text as a char array member named "text".
+    SK_CREATE_MEMBER_DETECTOR(text);
+    bool operator()(const SkRecords::DrawPicture& op) { return op.picture->hasText(); }
+    template <typename T> SK_WHEN(HasMember_text<T>,  bool) operator()(const T&) { return true;  }
+    template <typename T> SK_WHEN(!HasMember_text<T>, bool) operator()(const T&) { return false; }
+};
+
+} // namespace
+
+/** SkRecords visitor to determine heuristically whether or not a SkPicture
+    will be performant when rasterized on the GPU.
+ */
+struct SkPicture::PathCounter {
+    SK_CREATE_MEMBER_DETECTOR(paint);
+
+    PathCounter()
+        : numPaintWithPathEffectUses (0)
+        , numFastPathDashEffects (0)
+        , numAAConcavePaths (0)
+        , numAAHairlineConcavePaths (0) {
+    }
+
+    // Recurse into nested pictures.
+    void operator()(const SkRecords::DrawPicture& op) {
+        const SkPicture::Analysis& analysis = op.picture->fAnalysis;
+        numPaintWithPathEffectUses += analysis.fNumPaintWithPathEffectUses;
+        numFastPathDashEffects     += analysis.fNumFastPathDashEffects;
+        numAAConcavePaths          += analysis.fNumAAConcavePaths;
+        numAAHairlineConcavePaths  += analysis.fNumAAHairlineConcavePaths;
+    }
+
+    void checkPaint(const SkPaint* paint) {
+        if (paint && paint->getPathEffect()) {
+            numPaintWithPathEffectUses++;
+        }
+    }
+
+    void operator()(const SkRecords::DrawPoints& op) {
+        this->checkPaint(&op.paint);
+        const SkPathEffect* effect = op.paint.getPathEffect();
+        if (effect) {
+            SkPathEffect::DashInfo info;
+            SkPathEffect::DashType dashType = effect->asADash(&info);
+            if (2 == op.count && SkPaint::kRound_Cap != op.paint.getStrokeCap() &&
+                SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) {
+                numFastPathDashEffects++;
+            }
+        }
+    }
+
+    void operator()(const SkRecords::DrawPath& op) {
+        this->checkPaint(&op.paint);
+        if (op.paint.isAntiAlias() && !op.path.isConvex()) {
+            numAAConcavePaths++;
+
+            if (SkPaint::kStroke_Style == op.paint.getStyle() &&
+                0 == op.paint.getStrokeWidth()) {
+                numAAHairlineConcavePaths++;
+            }
+        }
+    }
+
+    template <typename T>
+    SK_WHEN(HasMember_paint<T>, void) operator()(const T& op) {
+        this->checkPaint(AsPtr(op.paint));
+    }
+
+    template <typename T>
+    SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { /* do nothing */ }
+
+    int numPaintWithPathEffectUses;
+    int numFastPathDashEffects;
+    int numAAConcavePaths;
+    int numAAHairlineConcavePaths;
+};
+
+SkPicture::Analysis::Analysis(const SkRecord& record) {
+    fWillPlaybackBitmaps = WillPlaybackBitmaps(record);
+
+    PathCounter counter;
+    for (unsigned i = 0; i < record.count(); i++) {
+        record.visit<void>(i, counter);
+    }
+    fNumPaintWithPathEffectUses = counter.numPaintWithPathEffectUses;
+    fNumFastPathDashEffects     = counter.numFastPathDashEffects;
+    fNumAAConcavePaths          = counter.numAAConcavePaths;
+    fNumAAHairlineConcavePaths  = counter.numAAHairlineConcavePaths;
+
+    fHasText = false;
+    TextHunter text;
+    for (unsigned i = 0; i < record.count(); i++) {
+        if (record.visit<bool>(i, text)) {
+            fHasText = true;
+            break;
         }
     }
 }
 
+bool SkPicture::Analysis::suitableForGpuRasterization(const char** reason,
+                                                      int sampleCount) const {
+    // TODO: the heuristic used here needs to be refined
+    static const int kNumPaintWithPathEffectsUsesTol = 1;
+    static const int kNumAAConcavePathsTol = 5;
+
+    int numNonDashedPathEffects = fNumPaintWithPathEffectUses -
+                                  fNumFastPathDashEffects;
+    bool suitableForDash = (0 == fNumPaintWithPathEffectUses) ||
+                           (numNonDashedPathEffects < kNumPaintWithPathEffectsUsesTol
+                               && 0 == sampleCount);
+
+    bool ret = suitableForDash &&
+               (fNumAAConcavePaths - fNumAAHairlineConcavePaths)
+                   < kNumAAConcavePathsTol;
+
+    if (!ret && reason) {
+        if (!suitableForDash) {
+            if (0 != sampleCount) {
+                *reason = "Can't use multisample on dash effect.";
+            } else {
+                *reason = "Too many non dashed path effects.";
+            }
+        } else if ((fNumAAConcavePaths - fNumAAHairlineConcavePaths)
+                    >= kNumAAConcavePathsTol)
+            *reason = "Too many anti-aliased concave paths.";
+        else
+            *reason = "Unknown reason for GPU unsuitability.";
+    }
+    return ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// fRecord OK
+SkPicture::SkPicture(SkScalar width, SkScalar height,
+                     const SkPictureRecord& record,
+                     bool deepCopyOps)
+    : fCullWidth(width)
+    , fCullHeight(height)
+    , fAnalysis() {
+    this->needsNewGenID();
+
+    SkPictInfo info;
+    this->createHeader(&info);
+    fData.reset(SkNEW_ARGS(SkPictureData, (record, info, deepCopyOps)));
+}
+
+// Create an SkPictureData-backed SkPicture from an SkRecord.
+// This for compatibility with serialization code only.  This is not cheap.
+static SkPicture* backport(const SkRecord& src, const SkRect& cullRect) {
+    SkPictureRecorder recorder;
+    SkRecordDraw(src,
+                 recorder.DEPRECATED_beginRecording(cullRect.width(), cullRect.height()),
+                 NULL/*bbh*/, NULL/*callback*/);
+    return recorder.endRecording();
+}
+
+// fRecord OK
+SkPicture::~SkPicture() {
+    this->callDeletionListeners();
+}
+
+// fRecord OK
+#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
+SkPicture* SkPicture::clone() const {
+    return SkRef(const_cast<SkPicture*>(this));
+}
+#endif//SK_SUPPORT_LEGACY_PICTURE_CLONE
+
+// fRecord OK
+void SkPicture::EXPERIMENTAL_addAccelData(const SkPicture::AccelData* data) const {
+    fAccelData.reset(SkRef(data));
+}
+
+// fRecord OK
+const SkPicture::AccelData* SkPicture::EXPERIMENTAL_getAccelData(
+        SkPicture::AccelData::Key key) const {
+    if (fAccelData.get() && fAccelData->getKey() == key) {
+        return fAccelData.get();
+    }
+    return NULL;
+}
+
+// fRecord OK
 SkPicture::AccelData::Domain SkPicture::AccelData::GenerateDomain() {
     static int32_t gNextID = 0;
 
@@ -256,30 +314,33 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-const SkPicture::OperationList& SkPicture::OperationList::InvalidList() {
-    static OperationList gInvalid;
-    return gInvalid;
+uint32_t SkPicture::OperationList::offset(int index) const {
+    SkASSERT(index < fOps.count());
+    return ((SkPictureStateTree::Draw*)fOps[index])->fOffset;
 }
 
-const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) const {
-    SkASSERT(NULL != fPlayback);
-    if (NULL != fPlayback) {
-        return fPlayback->getActiveOps(queryRect);
+const SkMatrix& SkPicture::OperationList::matrix(int index) const {
+    SkASSERT(index < fOps.count());
+    return *((SkPictureStateTree::Draw*)fOps[index])->fMatrix;
+}
+
+// fRecord OK
+void SkPicture::playback(SkCanvas* canvas, SkDrawPictureCallback* callback) const {
+    SkASSERT(canvas);
+    SkASSERT(fData.get() || fRecord.get());
+
+    // If the query contains the whole picture, don't bother with the BBH.
+    SkRect clipBounds = { 0, 0, 0, 0 };
+    (void)canvas->getClipBounds(&clipBounds);
+    const bool useBBH = !clipBounds.contains(this->cullRect());
+
+    if (fData.get()) {
+        SkPicturePlayback playback(this);
+        playback.setUseBBH(useBBH);
+        playback.draw(canvas, callback);
     }
-    return OperationList::InvalidList();
-}
-
-size_t SkPicture::EXPERIMENTAL_curOpID() const {
-    if (NULL != fPlayback) {
-        return fPlayback->curOpID();
-    }
-    return 0;
-}
-
-void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) const {
-    SkASSERT(NULL != fPlayback);
-    if (NULL != fPlayback) {
-        fPlayback->draw(*surface, callback);
+    if (fRecord.get()) {
+        SkRecordDraw(*fRecord, canvas, useBBH ? fBBH.get() : NULL, callback);
     }
 }
 
@@ -289,6 +350,7 @@
 
 static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' };
 
+// fRecord OK
 bool SkPicture::IsValidPictInfo(const SkPictInfo& info) {
     if (0 != memcmp(info.fMagic, kMagic, sizeof(kMagic))) {
         return false;
@@ -302,6 +364,7 @@
     return true;
 }
 
+// fRecord OK
 bool SkPicture::InternalOnly_StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
     if (NULL == stream) {
         return false;
@@ -310,7 +373,32 @@
     // Check magic bytes.
     SkPictInfo info;
     SkASSERT(sizeof(kMagic) == sizeof(info.fMagic));
-    if (!stream->read(&info, sizeof(info)) || !IsValidPictInfo(info)) {
+
+    if (!stream->read(&info.fMagic, sizeof(kMagic))) {
+        return false;
+    }
+
+    info.fVersion = stream->readU32();
+
+#ifndef V35_COMPATIBILITY_CODE
+    if (info.fVersion < 35) {
+        info.fCullRect.fLeft = 0;
+        info.fCullRect.fTop = 0;
+        info.fCullRect.fRight = SkIntToScalar(stream->readU32());
+        info.fCullRect.fBottom = SkIntToScalar(stream->readU32());
+    } else {
+#endif
+        info.fCullRect.fLeft = stream->readScalar();
+        info.fCullRect.fTop = stream->readScalar();
+        info.fCullRect.fRight = stream->readScalar();
+        info.fCullRect.fBottom = stream->readScalar();
+#ifndef V35_COMPATIBILITY_CODE
+    }
+#endif
+
+    info.fFlags = stream->readU32();
+
+    if (!IsValidPictInfo(info)) {
         return false;
     }
 
@@ -320,11 +408,34 @@
     return true;
 }
 
-bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo) {
+// fRecord OK
+bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer* buffer, SkPictInfo* pInfo) {
     // Check magic bytes.
     SkPictInfo info;
     SkASSERT(sizeof(kMagic) == sizeof(info.fMagic));
-    if (!buffer.readByteArray(&info, sizeof(info)) || !IsValidPictInfo(info)) {
+
+    if (!buffer->readByteArray(&info.fMagic, sizeof(kMagic))) {
+        return false;
+    }
+
+    info.fVersion = buffer->readUInt();
+
+#ifndef V35_COMPATIBILITY_CODE
+    if (info.fVersion < 35) {
+        info.fCullRect.fLeft = 0;
+        info.fCullRect.fTop = 0;
+        info.fCullRect.fRight = SkIntToScalar(buffer->readUInt());
+        info.fCullRect.fBottom = SkIntToScalar(buffer->readUInt());
+    } else {
+#endif
+        buffer->readRect(&info.fCullRect);
+#ifndef V35_COMPATIBILITY_CODE
+    }
+#endif
+
+    info.fFlags = buffer->readUInt();
+
+    if (!IsValidPictInfo(info)) {
         return false;
     }
 
@@ -334,14 +445,24 @@
     return true;
 }
 
-SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height)
-    : fPlayback(playback)
-    , fWidth(width)
-    , fHeight(height)
-    , fAccelData(NULL) {
+// fRecord OK
+SkPicture::SkPicture(SkPictureData* data, SkScalar width, SkScalar height)
+    : fData(data)
+    , fCullWidth(width)
+    , fCullHeight(height)
+    , fAnalysis() {
     this->needsNewGenID();
 }
 
+SkPicture* SkPicture::Forwardport(const SkPicture& src) {
+    SkAutoTDelete<SkRecord> record(SkNEW(SkRecord));
+    SkRecorder canvas(record.get(), src.cullRect().width(), src.cullRect().height());
+    src.playback(&canvas);
+    return SkNEW_ARGS(SkPicture, (src.cullRect().width(), src.cullRect().height(),
+                                  record.detach(), NULL/*bbh*/));
+}
+
+// fRecord OK
 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc proc) {
     SkPictInfo info;
 
@@ -351,37 +472,39 @@
 
     // Check to see if there is a playback to recreate.
     if (stream->readBool()) {
-        SkPicturePlayback* playback = SkPicturePlayback::CreateFromStream(stream, info, proc);
-        if (NULL == playback) {
+        SkPictureData* data = SkPictureData::CreateFromStream(stream, info, proc);
+        if (NULL == data) {
             return NULL;
         }
-
-        return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
+        const SkPicture src(data, info.fCullRect.width(), info.fCullRect.height());
+        return Forwardport(src);
     }
 
     return NULL;
 }
 
+// fRecord OK
 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) {
     SkPictInfo info;
 
-    if (!InternalOnly_BufferIsSKP(buffer, &info)) {
+    if (!InternalOnly_BufferIsSKP(&buffer, &info)) {
         return NULL;
     }
 
     // Check to see if there is a playback to recreate.
     if (buffer.readBool()) {
-        SkPicturePlayback* playback = SkPicturePlayback::CreateFromBuffer(buffer, info);
-        if (NULL == playback) {
+        SkPictureData* data = SkPictureData::CreateFromBuffer(buffer, info);
+        if (NULL == data) {
             return NULL;
         }
-
-        return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
+        const SkPicture src(data, info.fCullRect.width(), info.fCullRect.height());
+        return Forwardport(src);
     }
 
     return NULL;
 }
 
+// fRecord OK
 void SkPicture::createHeader(SkPictInfo* info) const {
     // Copy magic bytes at the beginning of the header
     SkASSERT(sizeof(kMagic) == 8);
@@ -390,8 +513,7 @@
 
     // Set picture info after magic bytes in the header
     info->fVersion = CURRENT_PICTURE_VERSION;
-    info->fWidth = fWidth;
-    info->fHeight = fHeight;
+    info->fCullRect = this->cullRect();
     info->fFlags = SkPictInfo::kCrossProcess_Flag;
     // TODO: remove this flag, since we're always float (now)
     info->fFlags |= SkPictInfo::kScalarIsFloat_Flag;
@@ -401,81 +523,100 @@
     }
 }
 
+// fRecord OK
 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
-    SkPicturePlayback* playback = fPlayback;
+    const SkPictureData* data = fData.get();
+
+    // If we're a new-format picture, backport to old format for serialization.
+    SkAutoTDelete<SkPicture> oldFormat;
+    if (NULL == data && fRecord.get()) {
+        oldFormat.reset(backport(*fRecord, this->cullRect()));
+        data = oldFormat->fData.get();
+        SkASSERT(data);
+    }
 
     SkPictInfo info;
     this->createHeader(&info);
+    SkASSERT(sizeof(SkPictInfo) == 32);
     stream->write(&info, sizeof(info));
-    if (playback) {
+
+    if (data) {
         stream->writeBool(true);
-        playback->serialize(stream, encoder);
-        // delete playback if it is a local version (i.e. cons'd up just now)
-        if (playback != fPlayback) {
-            SkDELETE(playback);
-        }
+        data->serialize(stream, encoder);
     } else {
         stream->writeBool(false);
     }
 }
 
-void SkPicture::WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size) {
-    buffer.writeUInt(tag);
-    buffer.writeUInt(SkToU32(size));
-}
-
-void SkPicture::WriteTagSize(SkWStream* stream, uint32_t tag,  size_t size) {
-    stream->write32(tag);
-    stream->write32(SkToU32(size));
-}
-
+// fRecord OK
 void SkPicture::flatten(SkWriteBuffer& buffer) const {
-    SkPicturePlayback* playback = fPlayback;
+    const SkPictureData* data = fData.get();
+
+    // If we're a new-format picture, backport to old format for serialization.
+    SkAutoTDelete<SkPicture> oldFormat;
+    if (NULL == data && fRecord.get()) {
+        oldFormat.reset(backport(*fRecord, this->cullRect()));
+        data = oldFormat->fData.get();
+        SkASSERT(data);
+    }
 
     SkPictInfo info;
     this->createHeader(&info);
-    buffer.writeByteArray(&info, sizeof(info));
-    if (playback) {
+    buffer.writeByteArray(&info.fMagic, sizeof(info.fMagic));
+    buffer.writeUInt(info.fVersion);
+    buffer.writeRect(info.fCullRect);
+    buffer.writeUInt(info.fFlags);
+
+    if (data) {
         buffer.writeBool(true);
-        playback->flatten(buffer);
-        // delete playback if it is a local version (i.e. cons'd up just now)
-        if (playback != fPlayback) {
-            SkDELETE(playback);
-        }
+        data->flatten(buffer);
     } else {
         buffer.writeBool(false);
     }
 }
 
 #if SK_SUPPORT_GPU
+// fRecord OK
 bool SkPicture::suitableForGpuRasterization(GrContext* context, const char **reason) const {
-    if (NULL == fPlayback) {
-        if (NULL != reason) {
-            *reason = "Missing playback object.";
+    if (fRecord.get()) {
+        return fAnalysis.suitableForGpuRasterization(reason, 0);
+    }
+    if (NULL == fData.get()) {
+        if (reason) {
+            *reason = "Missing internal data.";
         }
         return false;
     }
 
-    return fPlayback->suitableForGpuRasterization(context, reason);
+    return fData->suitableForGpuRasterization(context, reason);
 }
 #endif
 
+// fRecord OK
+bool SkPicture::hasText() const {
+    if (fRecord.get()) {
+        return fAnalysis.fHasText;
+    }
+    if (fData.get()) {
+        return fData->hasText();
+    }
+    SkFAIL("Unreachable");
+    return false;
+}
+
+// fRecord OK
 bool SkPicture::willPlayBackBitmaps() const {
-    if (!fPlayback) {
-        return false;
+    if (fRecord.get()) {
+        return fAnalysis.fWillPlaybackBitmaps;
     }
-    return fPlayback->containsBitmaps();
+    if (fData.get()) {
+        return fData->containsBitmaps();
+    }
+    SkFAIL("Unreachable");
+    return false;
 }
 
-#ifdef SK_BUILD_FOR_ANDROID
-void SkPicture::abortPlayback() {
-    if (NULL == fPlayback) {
-        return;
-    }
-    fPlayback->abort();
-}
-#endif
-
+// fRecord OK
 static int32_t next_picture_generation_id() {
     static int32_t  gPictureGenerationID = 0;
     // do a loop in case our global wraps around, as we never want to
@@ -487,9 +628,62 @@
     return genID;
 }
 
+// fRecord OK
 uint32_t SkPicture::uniqueID() const {
     if (SK_InvalidGenID == fUniqueID) {
         fUniqueID = next_picture_generation_id();
     }
     return fUniqueID;
 }
+
+
+static SkRecord* optimized(SkRecord* r) {
+#ifdef SK_PICTURE_OPTIMIZE_SK_RECORD
+    SkRecordOptimize(r);
+#endif
+    return r;
+}
+
+// fRecord OK
+SkPicture::SkPicture(SkScalar width, SkScalar height, SkRecord* record, SkBBoxHierarchy* bbh)
+    : fCullWidth(width)
+    , fCullHeight(height)
+    , fRecord(optimized(record))
+    , fBBH(SkSafeRef(bbh))
+    , fAnalysis(*fRecord) {
+    // TODO: delay as much of this work until just before first playback?
+    if (fBBH.get()) {
+        SkRecordFillBounds(*fRecord, fBBH.get());
+    }
+    this->needsNewGenID();
+}
+
+// Note that we are assuming that this entry point will only be called from
+// one thread. Currently the only client of this method is
+// SkGpuDevice::EXPERIMENTAL_optimize which should be only called from a single
+// thread.
+void SkPicture::addDeletionListener(DeletionListener* listener) const {
+    SkASSERT(listener);
+
+    *fDeletionListeners.append() = SkRef(listener);
+}
+
+void SkPicture::callDeletionListeners() {
+    for (int i = 0; i < fDeletionListeners.count(); ++i) {
+        fDeletionListeners[i]->onDeletion(this->uniqueID());
+    }
+
+    fDeletionListeners.unrefAll();
+}
+
+// fRecord OK
+int SkPicture::approximateOpCount() const {
+    SkASSERT(fRecord.get() || fData.get());
+    if (fRecord.get()) {
+        return fRecord->count();
+    }
+    if (fData.get()) {
+        return fData->opCount();
+    }
+    return 0;
+}
diff --git a/src/core/SkPictureContentInfo.cpp b/src/core/SkPictureContentInfo.cpp
new file mode 100644
index 0000000..937173c
--- /dev/null
+++ b/src/core/SkPictureContentInfo.cpp
@@ -0,0 +1,167 @@
+/*
+ * 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 "SkPaint.h"
+#include "SkPathEffect.h"
+#include "SkPictureContentInfo.h"
+
+bool SkPictureContentInfo::suitableForGpuRasterization(GrContext* context, const char **reason,
+                                                       int sampleCount) const {
+    // TODO: the heuristic used here needs to be refined
+    static const int kNumPaintWithPathEffectUsesTol = 1;
+    static const int kNumAAConcavePaths = 5;
+
+    SkASSERT(fNumAAHairlineConcavePaths <= fNumAAConcavePaths);
+
+    int numNonDashedPathEffects = fNumPaintWithPathEffectUses -
+                                  fNumFastPathDashEffects;
+
+    bool suitableForDash = (0 == fNumPaintWithPathEffectUses) ||
+                           (numNonDashedPathEffects < kNumPaintWithPathEffectUsesTol
+                            && 0 == sampleCount);
+
+    bool ret = suitableForDash &&
+                    (fNumAAConcavePaths - fNumAAHairlineConcavePaths)
+                    < kNumAAConcavePaths;
+    if (!ret && reason) {
+        if (!suitableForDash) {
+            if (0 != sampleCount) {
+                *reason = "Can't use multisample on dash effect.";
+            } else {
+                *reason = "Too many non dashed path effects.";
+            }
+        } else if ((fNumAAConcavePaths - fNumAAHairlineConcavePaths)
+                    >= kNumAAConcavePaths) {
+            *reason = "Too many anti-aliased concave paths.";
+        } else {
+            *reason = "Unknown reason for GPU unsuitability.";
+        }
+    }
+    return ret;
+}
+
+void SkPictureContentInfo::onDrawPoints(size_t count, const SkPaint& paint) {
+    if (paint.getPathEffect() != NULL) {
+        SkPathEffect::DashInfo info;
+        SkPathEffect::DashType dashType = paint.getPathEffect()->asADash(&info);
+        if (2 == count && SkPaint::kRound_Cap != paint.getStrokeCap() &&
+            SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) {
+            ++fNumFastPathDashEffects;
+        }
+    }
+}
+
+void SkPictureContentInfo::onDrawPath(const SkPath& path, const SkPaint& paint) {
+    if (paint.isAntiAlias() && !path.isConvex()) {
+        ++fNumAAConcavePaths;
+
+        if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) {
+            ++fNumAAHairlineConcavePaths;
+        }
+    }
+}
+
+void SkPictureContentInfo::onAddPaintPtr(const SkPaint* paint) {
+    if (paint && paint->getPathEffect()) {
+        ++fNumPaintWithPathEffectUses;
+    }
+}
+
+void SkPictureContentInfo::onSaveLayer() {
+    *fSaveStack.append() = kSaveLayer_Flag;
+}
+
+void SkPictureContentInfo::onSave() {
+    *fSaveStack.append() = kSave_Flag;
+}
+
+void SkPictureContentInfo::onRestore() {
+    SkASSERT(fSaveStack.count() > 0);
+
+    bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
+
+    if (fSaveStack.top() & kSaveLayer_Flag) {
+        ++fNumLayers;
+        if (containedSaveLayer) {
+            ++fNumInteriorLayers;
+        } else {
+            ++fNumLeafLayers;
+        }
+        containedSaveLayer = true;
+    }
+
+    fSaveStack.pop();
+
+    if (containedSaveLayer && fSaveStack.count() > 0) {
+        fSaveStack.top() |= kContainedSaveLayer_Flag;
+    }
+}
+
+void SkPictureContentInfo::rescindLastSave() {
+    SkASSERT(fSaveStack.count() > 0);
+    SkASSERT(fSaveStack.top() & kSave_Flag);
+
+    bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
+
+    fSaveStack.pop();
+
+    if (containedSaveLayer && fSaveStack.count() > 0) {
+        fSaveStack.top() |= kContainedSaveLayer_Flag;
+    }
+}
+
+void SkPictureContentInfo::rescindLastSaveLayer() {
+    SkASSERT(fSaveStack.count() > 0);
+    SkASSERT(fSaveStack.top() & kSaveLayer_Flag);
+
+    bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
+
+    fSaveStack.pop();
+
+    if (containedSaveLayer && fSaveStack.count() > 0) {
+        fSaveStack.top() |= kContainedSaveLayer_Flag;
+    }
+}
+
+void SkPictureContentInfo::set(const SkPictureContentInfo& src) {
+    fNumOperations = src.fNumOperations;
+    fNumTexts = src.fNumTexts;
+    fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses;
+    fNumFastPathDashEffects = src.fNumFastPathDashEffects;
+    fNumAAConcavePaths = src.fNumAAConcavePaths;
+    fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths;
+    fNumLayers = src.fNumLayers;
+    fNumInteriorLayers = src.fNumInteriorLayers;
+    fNumLeafLayers = src.fNumLeafLayers;
+    fSaveStack = src.fSaveStack;
+}
+
+void SkPictureContentInfo::reset() {
+    fNumOperations = 0;
+    fNumTexts = 0;
+    fNumPaintWithPathEffectUses = 0;
+    fNumFastPathDashEffects = 0;
+    fNumAAConcavePaths = 0;
+    fNumAAHairlineConcavePaths = 0;
+    fNumLayers = 0;
+    fNumInteriorLayers = 0;
+    fNumLeafLayers = 0;
+    fSaveStack.rewind();
+}
+
+void SkPictureContentInfo::swap(SkPictureContentInfo* other) {
+    SkTSwap(fNumOperations, other->fNumOperations);
+    SkTSwap(fNumTexts, other->fNumTexts);
+    SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses);
+    SkTSwap(fNumFastPathDashEffects, other->fNumFastPathDashEffects);
+    SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths);
+    SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths);
+    SkTSwap(fNumLayers, other->fNumLayers);
+    SkTSwap(fNumInteriorLayers, other->fNumInteriorLayers);
+    SkTSwap(fNumLeafLayers, other->fNumLeafLayers);
+    fSaveStack.swap(other->fSaveStack);
+}
diff --git a/src/core/SkPictureContentInfo.h b/src/core/SkPictureContentInfo.h
new file mode 100644
index 0000000..d4d1d4f
--- /dev/null
+++ b/src/core/SkPictureContentInfo.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPictureContentInfo_DEFINED
+#define SkPictureContentInfo_DEFINED
+
+class GrContext;
+
+class SkPictureContentInfo {
+public:
+    SkPictureContentInfo() { this->reset(); }
+    SkPictureContentInfo(const SkPictureContentInfo& src) { this->set(src); }
+
+    int numOperations() const { return fNumOperations; }
+    bool hasText() const { return fNumTexts > 0; }
+
+    int numLayers() const { return fNumLayers; }
+    int numInteriorLayers() const { return fNumInteriorLayers; }
+    int numLeafLayers() const { return fNumLeafLayers; }
+
+    bool suitableForGpuRasterization(GrContext* context, const char **reason,
+                                     int sampleCount) const;
+
+    void addOperation() { ++fNumOperations; }
+
+    void onDrawPoints(size_t count, const SkPaint& paint);
+    void onDrawPath(const SkPath& path, const SkPaint& paint);
+    void onAddPaintPtr(const SkPaint* paint);
+    void onDrawText() { ++fNumTexts; }
+
+    void onSaveLayer();
+    void onSave();
+    void onRestore();
+    void rescindLastSave();
+    void rescindLastSaveLayer();
+
+    void set(const SkPictureContentInfo& src);
+    void reset();
+    void swap(SkPictureContentInfo* other);
+
+private:
+    // Raw count of operations in the picture
+    int fNumOperations;
+    // Count of all forms of drawText
+    int fNumTexts;
+
+    // This field is incremented every time a paint with a path effect is
+    // used (i.e., it is not a de-duplicated count)
+    int fNumPaintWithPathEffectUses;
+    // This field is incremented every time a paint with a path effect that is
+    // dashed, we are drawing a line, and we can use the gpu fast path
+    int fNumFastPathDashEffects;
+    // This field is incremented every time an anti-aliased drawPath call is
+    // issued with a concave path
+    int fNumAAConcavePaths;
+    // This field is incremented every time a drawPath call is
+    // issued for a hairline stroked concave path.
+    int fNumAAHairlineConcavePaths;
+    // These fields track the different layer flavors. fNumLayers is just
+    // a count of all saveLayers, fNumInteriorLayers is the number of layers
+    // with a layer inside them, fNumLeafLayers is the number of layers with
+    // no layer inside them.
+    int fNumLayers;
+    int fNumInteriorLayers;
+    int fNumLeafLayers;
+
+    enum Flags {
+        kSave_Flag      = 0x1,
+        kSaveLayer_Flag = 0x2,
+
+        // Did the current save or saveLayer contain another saveLayer.
+        // Percolated back down the save stack.
+        kContainedSaveLayer_Flag = 0x4
+    };
+
+    // Stack of save vs saveLayer information to track nesting
+    SkTDArray<uint32_t> fSaveStack;
+};
+
+#endif
diff --git a/src/core/SkPictureData.cpp b/src/core/SkPictureData.cpp
new file mode 100644
index 0000000..6565158
--- /dev/null
+++ b/src/core/SkPictureData.cpp
@@ -0,0 +1,670 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <new>
+#include "SkBBoxHierarchy.h"
+#include "SkDrawPictureCallback.h"
+#include "SkPictureData.h"
+#include "SkPictureRecord.h"
+#include "SkReadBuffer.h"
+#include "SkTextBlob.h"
+#include "SkTypeface.h"
+#include "SkTSort.h"
+#include "SkWriteBuffer.h"
+
+#if SK_SUPPORT_GPU
+#include "GrContext.h"
+#endif
+
+template <typename T> int SafeCount(const T* obj) {
+    return obj ? obj->count() : 0;
+}
+
+SkPictureData::SkPictureData(const SkPictInfo& info)
+    : fInfo(info) {
+    this->init();
+}
+
+void SkPictureData::initForPlayback() const {
+    // ensure that the paths bounds are pre-computed
+    if (fPathHeap.get()) {
+        for (int i = 0; i < fPathHeap->count(); i++) {
+            (*fPathHeap.get())[i].updateBoundsCache();
+        }
+    }
+}
+
+SkPictureData::SkPictureData(const SkPictureRecord& record,
+                             const SkPictInfo& info,
+                             bool deepCopyOps)
+    : fInfo(info) {
+
+    this->init();
+
+    fOpData = record.opData(deepCopyOps);
+
+    fBoundingHierarchy = record.fBoundingHierarchy;
+    fStateTree = record.fStateTree;
+
+    SkSafeRef(fBoundingHierarchy);
+    SkSafeRef(fStateTree);
+    fContentInfo.set(record.fContentInfo);
+
+    if (fBoundingHierarchy) {
+        fBoundingHierarchy->flushDeferredInserts();
+    }
+
+    // copy over the refcnt dictionary to our reader
+    record.fFlattenableHeap.setupPlaybacks();
+
+    fBitmaps = record.fBitmapHeap->extractBitmaps();
+    fPaints = record.fPaints.unflattenToArray();
+
+    fBitmapHeap.reset(SkSafeRef(record.fBitmapHeap));
+    fPathHeap.reset(SkSafeRef(record.pathHeap()));
+
+    this->initForPlayback();
+
+    const SkTDArray<const SkPicture* >& pictures = record.getPictureRefs();
+    fPictureCount = pictures.count();
+    if (fPictureCount > 0) {
+        fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
+        for (int i = 0; i < fPictureCount; i++) {
+            fPictureRefs[i] = pictures[i];
+            fPictureRefs[i]->ref();
+        }
+    }
+
+    // templatize to consolidate with similar picture logic?
+    const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs();
+    fTextBlobCount = blobs.count();
+    if (fTextBlobCount > 0) {
+        fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount);
+        for (int i = 0; i < fTextBlobCount; ++i) {
+            fTextBlobRefs[i] = SkRef(blobs[i]);
+        }
+    }
+}
+
+#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
+SkPictureData::SkPictureData(const SkPictureData& src, SkPictCopyInfo* deepCopyInfo)
+    : fInfo(src.fInfo) {
+    this->init();
+
+    fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get()));
+    fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
+
+    fOpData = SkSafeRef(src.fOpData);
+
+    fBoundingHierarchy = src.fBoundingHierarchy;
+    fStateTree = src.fStateTree;
+    fContentInfo.set(src.fContentInfo);
+
+    SkSafeRef(fBoundingHierarchy);
+    SkSafeRef(fStateTree);
+
+    if (deepCopyInfo) {
+        int paintCount = SafeCount(src.fPaints);
+
+        if (src.fBitmaps) {
+            fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src.fBitmaps->count());
+        }
+
+        fPaints = SkTRefArray<SkPaint>::Create(paintCount);
+        SkASSERT(deepCopyInfo->paintData.count() == paintCount);
+        SkBitmapHeap* bmHeap = deepCopyInfo->controller.getBitmapHeap();
+        SkTypefacePlayback* tfPlayback = deepCopyInfo->controller.getTypefacePlayback();
+        for (int i = 0; i < paintCount; i++) {
+            if (deepCopyInfo->paintData[i]) {
+                deepCopyInfo->paintData[i]->unflatten<SkPaint::FlatteningTraits>(
+                    &fPaints->writableAt(i), bmHeap, tfPlayback);
+            } else {
+                // needs_deep_copy was false, so just need to assign
+                fPaints->writableAt(i) = src.fPaints->at(i);
+            }
+        }
+
+    } else {
+        fBitmaps = SkSafeRef(src.fBitmaps);
+        fPaints = SkSafeRef(src.fPaints);
+    }
+
+    fPictureCount = src.fPictureCount;
+    fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
+    for (int i = 0; i < fPictureCount; i++) {
+        if (deepCopyInfo) {
+            fPictureRefs[i] = src.fPictureRefs[i]->clone();
+        } else {
+            fPictureRefs[i] = src.fPictureRefs[i];
+            fPictureRefs[i]->ref();
+        }
+    }
+}
+#endif//SK_SUPPORT_LEGACY_PICTURE_CLONE
+
+void SkPictureData::init() {
+    fBitmaps = NULL;
+    fPaints = NULL;
+    fPictureRefs = NULL;
+    fPictureCount = 0;
+    fTextBlobRefs = NULL;
+    fTextBlobCount = 0;
+    fOpData = NULL;
+    fFactoryPlayback = NULL;
+    fBoundingHierarchy = NULL;
+    fStateTree = NULL;
+}
+
+SkPictureData::~SkPictureData() {
+    SkSafeUnref(fOpData);
+
+    SkSafeUnref(fBitmaps);
+    SkSafeUnref(fPaints);
+    SkSafeUnref(fBoundingHierarchy);
+    SkSafeUnref(fStateTree);
+
+    for (int i = 0; i < fPictureCount; i++) {
+        fPictureRefs[i]->unref();
+    }
+    SkDELETE_ARRAY(fPictureRefs);
+
+    for (int i = 0; i < fTextBlobCount; i++) {
+        fTextBlobRefs[i]->unref();
+    }
+    SkDELETE_ARRAY(fTextBlobRefs);
+
+    SkDELETE(fFactoryPlayback);
+}
+
+bool SkPictureData::containsBitmaps() const {
+    if (fBitmaps && fBitmaps->count() > 0) {
+        return true;
+    }
+    for (int i = 0; i < fPictureCount; ++i) {
+        if (fPictureRefs[i]->willPlayBackBitmaps()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkStream.h"
+
+static size_t compute_chunk_size(SkFlattenable::Factory* array, int count) {
+    size_t size = 4;  // for 'count'
+
+    for (int i = 0; i < count; i++) {
+        const char* name = SkFlattenable::FactoryToName(array[i]);
+        if (NULL == name || 0 == *name) {
+            size += SkWStream::SizeOfPackedUInt(0);
+        } else {
+            size_t len = strlen(name);
+            size += SkWStream::SizeOfPackedUInt(len);
+            size += len;
+        }
+    }
+
+    return size;
+}
+
+static void write_tag_size(SkWriteBuffer& buffer, uint32_t tag, size_t size) {
+    buffer.writeUInt(tag);
+    buffer.writeUInt(SkToU32(size));
+}
+
+static void write_tag_size(SkWStream* stream, uint32_t tag, size_t size) {
+    stream->write32(tag);
+    stream->write32(SkToU32(size));
+}
+
+void SkPictureData::WriteFactories(SkWStream* stream, const SkFactorySet& rec) {
+    int count = rec.count();
+
+    SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count);
+    SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get();
+    rec.copyToArray(array);
+
+    size_t size = compute_chunk_size(array, count);
+
+    // TODO: write_tag_size should really take a size_t
+    write_tag_size(stream, SK_PICT_FACTORY_TAG, (uint32_t) size);
+    SkDEBUGCODE(size_t start = stream->bytesWritten());
+    stream->write32(count);
+
+    for (int i = 0; i < count; i++) {
+        const char* name = SkFlattenable::FactoryToName(array[i]);
+        if (NULL == name || 0 == *name) {
+            stream->writePackedUInt(0);
+        } else {
+            size_t len = strlen(name);
+            stream->writePackedUInt(len);
+            stream->write(name, len);
+        }
+    }
+
+    SkASSERT(size == (stream->bytesWritten() - start));
+}
+
+void SkPictureData::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) {
+    int count = rec.count();
+
+    write_tag_size(stream, SK_PICT_TYPEFACE_TAG, count);
+
+    SkAutoSTMalloc<16, SkTypeface*> storage(count);
+    SkTypeface** array = (SkTypeface**)storage.get();
+    rec.copyToArray((SkRefCnt**)array);
+
+    for (int i = 0; i < count; i++) {
+        array[i]->serialize(stream);
+    }
+}
+
+void SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const {
+    int i, n;
+
+    if ((n = SafeCount(fBitmaps)) > 0) {
+        write_tag_size(buffer, SK_PICT_BITMAP_BUFFER_TAG, n);
+        for (i = 0; i < n; i++) {
+            buffer.writeBitmap((*fBitmaps)[i]);
+        }
+    }
+
+    if ((n = SafeCount(fPaints)) > 0) {
+        write_tag_size(buffer, SK_PICT_PAINT_BUFFER_TAG, n);
+        for (i = 0; i < n; i++) {
+            buffer.writePaint((*fPaints)[i]);
+        }
+    }
+
+    if ((n = SafeCount(fPathHeap.get())) > 0) {
+        write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n);
+        fPathHeap->flatten(buffer);
+    }
+
+    if (fTextBlobCount > 0) {
+        write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount);
+        for (i = 0; i  < fTextBlobCount; ++i) {
+            fTextBlobRefs[i]->flatten(buffer);
+        }
+    }
+}
+
+void SkPictureData::serialize(SkWStream* stream,
+                                  SkPicture::EncodeBitmap encoder) const {
+    write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size());
+    stream->write(fOpData->bytes(), fOpData->size());
+
+    if (fPictureCount > 0) {
+        write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount);
+        for (int i = 0; i < fPictureCount; i++) {
+            fPictureRefs[i]->serialize(stream, encoder);
+        }
+    }
+
+    // Write some of our data into a writebuffer, and then serialize that
+    // into our stream
+    {
+        SkRefCntSet  typefaceSet;
+        SkFactorySet factSet;
+
+        SkWriteBuffer buffer(SkWriteBuffer::kCrossProcess_Flag);
+        buffer.setTypefaceRecorder(&typefaceSet);
+        buffer.setFactoryRecorder(&factSet);
+        buffer.setBitmapEncoder(encoder);
+
+        this->flattenToBuffer(buffer);
+
+        // We have to write these two sets into the stream *before* we write
+        // the buffer, since parsing that buffer will require that we already
+        // have these sets available to use.
+        WriteFactories(stream, factSet);
+        WriteTypefaces(stream, typefaceSet);
+
+        write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten());
+        buffer.writeToStream(stream);
+    }
+
+    stream->write32(SK_PICT_EOF_TAG);
+}
+
+void SkPictureData::flatten(SkWriteBuffer& buffer) const {
+    write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size());
+    buffer.writeByteArray(fOpData->bytes(), fOpData->size());
+
+    if (fPictureCount > 0) {
+        write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount);
+        for (int i = 0; i < fPictureCount; i++) {
+            fPictureRefs[i]->flatten(buffer);
+        }
+    }
+
+    // Write this picture playback's data into a writebuffer
+    this->flattenToBuffer(buffer);
+    buffer.write32(SK_PICT_EOF_TAG);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Return the corresponding SkReadBuffer flags, given a set of
+ *  SkPictInfo flags.
+ */
+static uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
+    static const struct {
+        uint32_t    fSrc;
+        uint32_t    fDst;
+    } gSD[] = {
+        { SkPictInfo::kCrossProcess_Flag,   SkReadBuffer::kCrossProcess_Flag },
+        { SkPictInfo::kScalarIsFloat_Flag,  SkReadBuffer::kScalarIsFloat_Flag },
+        { SkPictInfo::kPtrIs64Bit_Flag,     SkReadBuffer::kPtrIs64Bit_Flag },
+    };
+
+    uint32_t rbMask = 0;
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) {
+        if (pictInfoFlags & gSD[i].fSrc) {
+            rbMask |= gSD[i].fDst;
+        }
+    }
+    return rbMask;
+}
+
+bool SkPictureData::parseStreamTag(SkStream* stream,
+                                   uint32_t tag,
+                                   uint32_t size,
+                                   SkPicture::InstallPixelRefProc proc) {
+    /*
+     *  By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
+     *  its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
+     *  but if they are present, they need to have been seen before the buffer.
+     *
+     *  We assert that if/when we see either of these, that we have not yet seen
+     *  the buffer tag, because if we have, then its too-late to deal with the
+     *  factories or typefaces.
+     */
+    SkDEBUGCODE(bool haveBuffer = false;)
+
+    switch (tag) {
+        case SK_PICT_READER_TAG:
+            SkASSERT(NULL == fOpData);
+            fOpData = SkData::NewFromStream(stream, size);
+            if (!fOpData) {
+                return false;
+            }
+            break;
+        case SK_PICT_FACTORY_TAG: {
+            SkASSERT(!haveBuffer);
+        // Remove this code when v21 and below are no longer supported. At the
+        // same time add a new 'count' variable and use it rather then reusing 'size'.
+#ifndef DISABLE_V21_COMPATIBILITY_CODE
+            if (fInfo.fVersion >= 22) {
+                // in v22 this tag's size represents the size of the chunk in bytes
+                // and the number of factory strings is written out separately
+#endif
+                size = stream->readU32();
+#ifndef DISABLE_V21_COMPATIBILITY_CODE
+            }
+#endif
+            fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (size));
+            for (size_t i = 0; i < size; i++) {
+                SkString str;
+                const size_t len = stream->readPackedUInt();
+                str.resize(len);
+                if (stream->read(str.writable_str(), len) != len) {
+                    return false;
+                }
+                fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str());
+            }
+        } break;
+        case SK_PICT_TYPEFACE_TAG: {
+            SkASSERT(!haveBuffer);
+            const int count = SkToInt(size);
+            fTFPlayback.setCount(count);
+            for (int i = 0; i < count; i++) {
+                SkAutoTUnref<SkTypeface> tf(SkTypeface::Deserialize(stream));
+                if (!tf.get()) {    // failed to deserialize
+                    // fTFPlayback asserts it never has a null, so we plop in
+                    // the default here.
+                    tf.reset(SkTypeface::RefDefault());
+                }
+                fTFPlayback.set(i, tf);
+            }
+        } break;
+        case SK_PICT_PICTURE_TAG: {
+            fPictureCount = size;
+            fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
+            bool success = true;
+            int i = 0;
+            for ( ; i < fPictureCount; i++) {
+                fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc);
+                if (NULL == fPictureRefs[i]) {
+                    success = false;
+                    break;
+                }
+            }
+            if (!success) {
+                // Delete all of the pictures that were already created (up to but excluding i):
+                for (int j = 0; j < i; j++) {
+                    fPictureRefs[j]->unref();
+                }
+                // Delete the array
+                SkDELETE_ARRAY(fPictureRefs);
+                fPictureCount = 0;
+                return false;
+            }
+        } break;
+        case SK_PICT_BUFFER_SIZE_TAG: {
+            SkAutoMalloc storage(size);
+            if (stream->read(storage.get(), size) != size) {
+                return false;
+            }
+
+            SkReadBuffer buffer(storage.get(), size);
+            buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags));
+            buffer.setVersion(fInfo.fVersion);
+
+            fFactoryPlayback->setupBuffer(buffer);
+            fTFPlayback.setupBuffer(buffer);
+            buffer.setBitmapDecoder(proc);
+
+            while (!buffer.eof()) {
+                tag = buffer.readUInt();
+                size = buffer.readUInt();
+                if (!this->parseBufferTag(buffer, tag, size)) {
+                    return false;
+                }
+            }
+            SkDEBUGCODE(haveBuffer = true;)
+        } break;
+    }
+    return true;    // success
+}
+
+bool SkPictureData::parseBufferTag(SkReadBuffer& buffer,
+                                   uint32_t tag, uint32_t size) {
+    switch (tag) {
+        case SK_PICT_BITMAP_BUFFER_TAG: {
+            const int count = SkToInt(size);
+            fBitmaps = SkTRefArray<SkBitmap>::Create(size);
+            for (int i = 0; i < count; ++i) {
+                SkBitmap* bm = &fBitmaps->writableAt(i);
+                buffer.readBitmap(bm);
+                bm->setImmutable();
+            }
+        } break;
+        case SK_PICT_PAINT_BUFFER_TAG: {
+            const int count = SkToInt(size);
+            fPaints = SkTRefArray<SkPaint>::Create(size);
+            for (int i = 0; i < count; ++i) {
+                buffer.readPaint(&fPaints->writableAt(i));
+            }
+        } break;
+        case SK_PICT_PATH_BUFFER_TAG:
+            if (size > 0) {
+                fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
+            }
+            break;
+        case SK_PICT_TEXTBLOB_BUFFER_TAG: {
+            if (!buffer.validate((0 == fTextBlobCount) && (NULL == fTextBlobRefs))) {
+                return false;
+            }
+            fTextBlobCount = size;
+            fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount);
+            bool success = true;
+            int i = 0;
+            for ( ; i < fTextBlobCount; i++) {
+                fTextBlobRefs[i] = SkTextBlob::CreateFromBuffer(buffer);
+                if (NULL == fTextBlobRefs[i]) {
+                    success = false;
+                    break;
+                }
+            }
+            if (!success) {
+                // Delete all of the blobs that were already created (up to but excluding i):
+                for (int j = 0; j < i; j++) {
+                    fTextBlobRefs[j]->unref();
+                }
+                // Delete the array
+                SkDELETE_ARRAY(fTextBlobRefs);
+                fTextBlobRefs = NULL;
+                fTextBlobCount = 0;
+                return false;
+            }
+        } break;
+        case SK_PICT_READER_TAG: {
+            SkAutoDataUnref data(SkData::NewUninitialized(size));
+            if (!buffer.readByteArray(data->writable_data(), size) ||
+                !buffer.validate(NULL == fOpData)) {
+                return false;
+            }
+            SkASSERT(NULL == fOpData);
+            fOpData = data.detach();
+        } break;
+        case SK_PICT_PICTURE_TAG: {
+            if (!buffer.validate((0 == fPictureCount) && (NULL == fPictureRefs))) {
+                return false;
+            }
+            fPictureCount = size;
+            fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
+            bool success = true;
+            int i = 0;
+            for ( ; i < fPictureCount; i++) {
+                fPictureRefs[i] = SkPicture::CreateFromBuffer(buffer);
+                if (NULL == fPictureRefs[i]) {
+                    success = false;
+                    break;
+                }
+            }
+            if (!success) {
+                // Delete all of the pictures that were already created (up to but excluding i):
+                for (int j = 0; j < i; j++) {
+                    fPictureRefs[j]->unref();
+                }
+                // Delete the array
+                SkDELETE_ARRAY(fPictureRefs);
+                fPictureCount = 0;
+                return false;
+            }
+        } break;
+        default:
+            // The tag was invalid.
+            return false;
+    }
+    return true;    // success
+}
+
+SkPictureData* SkPictureData::CreateFromStream(SkStream* stream,
+                                               const SkPictInfo& info,
+                                               SkPicture::InstallPixelRefProc proc) {
+    SkAutoTDelete<SkPictureData> data(SkNEW_ARGS(SkPictureData, (info)));
+
+    if (!data->parseStream(stream, proc)) {
+        return NULL;
+    }
+    return data.detach();
+}
+
+SkPictureData* SkPictureData::CreateFromBuffer(SkReadBuffer& buffer,
+                                               const SkPictInfo& info) {
+    SkAutoTDelete<SkPictureData> data(SkNEW_ARGS(SkPictureData, (info)));
+    buffer.setVersion(info.fVersion);
+
+    if (!data->parseBuffer(buffer)) {
+        return NULL;
+    }
+    return data.detach();
+}
+
+bool SkPictureData::parseStream(SkStream* stream,
+                                SkPicture::InstallPixelRefProc proc) {
+    for (;;) {
+        uint32_t tag = stream->readU32();
+        if (SK_PICT_EOF_TAG == tag) {
+            break;
+        }
+
+        uint32_t size = stream->readU32();
+        if (!this->parseStreamTag(stream, tag, size, proc)) {
+            return false; // we're invalid
+        }
+    }
+    return true;
+}
+
+bool SkPictureData::parseBuffer(SkReadBuffer& buffer) {
+    for (;;) {
+        uint32_t tag = buffer.readUInt();
+        if (SK_PICT_EOF_TAG == tag) {
+            break;
+        }
+
+        uint32_t size = buffer.readUInt();
+        if (!this->parseBufferTag(buffer, tag, size)) {
+            return false; // we're invalid
+        }
+    }
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+const SkPicture::OperationList* SkPictureData::getActiveOps(const SkRect& query) const {
+    if (NULL == fStateTree || NULL == fBoundingHierarchy) {
+        return NULL;
+    }
+
+    SkPicture::OperationList* activeOps = SkNEW(SkPicture::OperationList);
+    fBoundingHierarchy->search(query, &(activeOps->fOps));
+    return activeOps;
+}
+
+#if SK_SUPPORT_GPU
+bool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
+                                                int sampleCount) const {
+    return fContentInfo.suitableForGpuRasterization(context, reason, sampleCount);
+}
+
+bool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
+                                                GrPixelConfig config, SkScalar dpi) const {
+
+    if (context != NULL) {
+        return this->suitableForGpuRasterization(context, reason,
+                                                 context->getRecommendedSampleCount(config, dpi));
+    } else {
+        return this->suitableForGpuRasterization(NULL, reason);
+    }
+}
+
+bool SkPictureData::suitableForLayerOptimization() const {
+    return fContentInfo.numLayers() > 0;
+}
+#endif
+///////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/core/SkPictureData.h b/src/core/SkPictureData.h
new file mode 100644
index 0000000..d2b5b4a
--- /dev/null
+++ b/src/core/SkPictureData.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPictureData_DEFINED
+#define SkPictureData_DEFINED
+
+#include "SkBitmap.h"
+#include "SkPathHeap.h"
+#include "SkPicture.h"
+#include "SkPictureContentInfo.h"
+#include "SkPictureFlat.h"
+#include "SkPictureStateTree.h"
+
+class SkData;
+class SkPictureRecord;
+class SkReader32;
+class SkStream;
+class SkWStream;
+class SkBBoxHierarchy;
+class SkMatrix;
+class SkPaint;
+class SkPath;
+class SkPictureStateTree;
+class SkReadBuffer;
+class SkTextBlob;
+
+struct SkPictInfo {
+    enum Flags {
+        kCrossProcess_Flag      = 1 << 0,
+        kScalarIsFloat_Flag     = 1 << 1,
+        kPtrIs64Bit_Flag        = 1 << 2,
+    };
+
+    char        fMagic[8];
+    uint32_t    fVersion;
+    SkRect      fCullRect;
+    uint32_t    fFlags;
+};
+
+#define SK_PICT_READER_TAG     SkSetFourByteTag('r', 'e', 'a', 'd')
+#define SK_PICT_FACTORY_TAG    SkSetFourByteTag('f', 'a', 'c', 't')
+#define SK_PICT_TYPEFACE_TAG   SkSetFourByteTag('t', 'p', 'f', 'c')
+#define SK_PICT_PICTURE_TAG    SkSetFourByteTag('p', 'c', 't', 'r')
+
+// This tag specifies the size of the ReadBuffer, needed for the following tags
+#define SK_PICT_BUFFER_SIZE_TAG     SkSetFourByteTag('a', 'r', 'a', 'y')
+// these are all inside the ARRAYS tag
+#define SK_PICT_BITMAP_BUFFER_TAG   SkSetFourByteTag('b', 't', 'm', 'p')
+#define SK_PICT_PAINT_BUFFER_TAG    SkSetFourByteTag('p', 'n', 't', ' ')
+#define SK_PICT_PATH_BUFFER_TAG     SkSetFourByteTag('p', 't', 'h', ' ')
+#define SK_PICT_TEXTBLOB_BUFFER_TAG SkSetFourByteTag('b', 'l', 'o', 'b')
+
+// Always write this guy last (with no length field afterwards)
+#define SK_PICT_EOF_TAG     SkSetFourByteTag('e', 'o', 'f', ' ')
+
+#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
+/**
+ * Container for data that is needed to deep copy a SkPicture. The container
+ * enables the data to be generated once and reused for subsequent copies.
+ */
+struct SkPictCopyInfo {
+    SkPictCopyInfo() : controller(1024) {}
+
+    SkChunkFlatController controller;
+    SkTDArray<SkFlatData*> paintData;
+};
+#endif
+
+class SkPictureData {
+public:
+#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
+    SkPictureData(const SkPictureData& src, SkPictCopyInfo* deepCopyInfo = NULL);
+#endif
+    SkPictureData(const SkPictureRecord& record, const SkPictInfo&, bool deepCopyOps);
+    static SkPictureData* CreateFromStream(SkStream*,
+                                           const SkPictInfo&,
+                                           SkPicture::InstallPixelRefProc);
+    static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
+
+    virtual ~SkPictureData();
+
+    const SkPicture::OperationList* getActiveOps(const SkRect& queryRect) const;
+
+    void serialize(SkWStream*, SkPicture::EncodeBitmap) const;
+    void flatten(SkWriteBuffer&) const;
+
+    bool containsBitmaps() const;
+
+    bool hasText() const { return fContentInfo.hasText(); }
+
+    int opCount() const { return fContentInfo.numOperations(); }
+
+    const SkData* opData() const { return fOpData; }
+
+protected:
+    explicit SkPictureData(const SkPictInfo& info);
+
+    bool parseStream(SkStream*, SkPicture::InstallPixelRefProc);
+    bool parseBuffer(SkReadBuffer& buffer);
+
+public:
+    const SkBitmap& getBitmap(SkReader32* reader) const {
+        const int index = reader->readInt();
+        if (SkBitmapHeap::INVALID_SLOT == index) {
+#ifdef SK_DEBUG
+            SkDebugf("An invalid bitmap was recorded!\n");
+#endif
+            return fBadBitmap;
+        }
+        return (*fBitmaps)[index];
+    }
+
+    const SkPath& getPath(SkReader32* reader) const {
+        int index = reader->readInt() - 1;
+        return (*fPathHeap.get())[index];
+    }
+
+    const SkPicture* getPicture(SkReader32* reader) const {
+        int index = reader->readInt();
+        SkASSERT(index > 0 && index <= fPictureCount);
+        return fPictureRefs[index - 1];
+    }
+
+    const SkPaint* getPaint(SkReader32* reader) const {
+        int index = reader->readInt();
+        if (index == 0) {
+            return NULL;
+        }
+        return &(*fPaints)[index - 1];
+    }
+
+    const SkTextBlob* getTextBlob(SkReader32* reader) const {
+        int index = reader->readInt();
+        SkASSERT(index > 0 && index <= fTextBlobCount);
+        return fTextBlobRefs[index - 1];
+    }
+
+    void initIterator(SkPictureStateTree::Iterator* iter,
+                      const SkTDArray<void*>& draws,
+                      SkCanvas* canvas) const {
+        if (fStateTree) {
+            fStateTree->initIterator(iter, draws, canvas);
+        }
+    }
+
+#if SK_SUPPORT_GPU
+    /**
+     * sampleCount is the number of samples-per-pixel or zero if non-MSAA.
+     * It is defaulted to be zero.
+     */
+    bool suitableForGpuRasterization(GrContext* context, const char **reason,
+                                     int sampleCount = 0) const;
+
+    /**
+     * Calls getRecommendedSampleCount with GrPixelConfig and dpi to calculate sampleCount
+     * and then calls the above version of suitableForGpuRasterization
+     */
+    bool suitableForGpuRasterization(GrContext* context, const char **reason,
+                                     GrPixelConfig config, SkScalar dpi) const;
+
+    bool suitableForLayerOptimization() const;
+#endif
+
+private:
+    friend class SkPicture; // needed in SkPicture::clone (rm when it is removed)
+
+    void init();
+
+    // these help us with reading/writing
+    bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size, SkPicture::InstallPixelRefProc);
+    bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
+    void flattenToBuffer(SkWriteBuffer&) const;
+
+    // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty
+    // bitmap allows playback to draw nothing and move on.
+    SkBitmap fBadBitmap;
+
+    SkAutoTUnref<SkBitmapHeap> fBitmapHeap;
+
+    SkTRefArray<SkBitmap>* fBitmaps;
+    SkTRefArray<SkPaint>* fPaints;
+
+    SkData* fOpData;    // opcodes and parameters
+
+    SkAutoTUnref<const SkPathHeap> fPathHeap;  // reference counted
+
+    const SkPicture** fPictureRefs;
+    int fPictureCount;
+    const SkTextBlob** fTextBlobRefs;
+    int fTextBlobCount;
+
+    SkBBoxHierarchy* fBoundingHierarchy;
+    SkPictureStateTree* fStateTree;
+
+    SkPictureContentInfo fContentInfo;
+
+    SkTypefacePlayback fTFPlayback;
+    SkFactoryPlayback* fFactoryPlayback;
+
+    const SkPictInfo fInfo;
+
+    static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
+    static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec);
+
+    void initForPlayback() const;
+};
+
+#endif
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index 5d1a6b5..3530f39 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -8,7 +8,6 @@
 #ifndef SkPictureFlat_DEFINED
 #define SkPictureFlat_DEFINED
 
-//#define SK_DEBUG_SIZE
 
 #include "SkBitmapHeap.h"
 #include "SkChecksum.h"
@@ -67,8 +66,12 @@
     DRAW_DRRECT,
     PUSH_CULL,
     POP_CULL,
+    
+    DRAW_PATCH, // could not add in aphabetical order
+    DRAW_PICTURE_MATRIX_PAINT,
+    DRAW_TEXT_BLOB,
 
-    LAST_DRAWTYPE_ENUM = POP_CULL
+    LAST_DRAWTYPE_ENUM = DRAW_TEXT_BLOB
 };
 
 // In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 1688710..308ce9e 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -1,722 +1,32 @@
 /*
- * Copyright 2011 Google Inc.
+ * 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 <new>
-#include "SkBBoxHierarchy.h"
+
+#include "SkCanvas.h"
+#include "SkPatchUtils.h"
+#include "SkPictureData.h"
 #include "SkPicturePlayback.h"
 #include "SkPictureRecord.h"
 #include "SkPictureStateTree.h"
-#include "SkReadBuffer.h"
-#include "SkTypeface.h"
-#include "SkTSort.h"
-#include "SkWriteBuffer.h"
-
-#if SK_SUPPORT_GPU
-#include "GrContext.h"
-#endif
-
-template <typename T> int SafeCount(const T* obj) {
-    return obj ? obj->count() : 0;
-}
-
-/*  Define this to spew out a debug statement whenever we skip the remainder of
-    a save/restore block because a clip... command returned false (empty).
- */
-#define SPEW_CLIP_SKIPPINGx
-
-SkPicturePlayback::PlaybackReplacements::ReplacementInfo*
-SkPicturePlayback::PlaybackReplacements::push() {
-    SkDEBUGCODE(this->validate());
-    return fReplacements.push();
-}
-
-void SkPicturePlayback::PlaybackReplacements::freeAll() {
-    for (int i = 0; i < fReplacements.count(); ++i) {
-        SkDELETE(fReplacements[i].fBM);
-    }
-    fReplacements.reset();
-}
-
-#ifdef SK_DEBUG
-void SkPicturePlayback::PlaybackReplacements::validate() const {
-    // Check that the ranges are monotonically increasing and non-overlapping
-    if (fReplacements.count() > 0) {
-        SkASSERT(fReplacements[0].fStart < fReplacements[0].fStop);
-
-        for (int i = 1; i < fReplacements.count(); ++i) {
-            SkASSERT(fReplacements[i].fStart < fReplacements[i].fStop);
-            SkASSERT(fReplacements[i-1].fStop < fReplacements[i].fStart);
-        }
-    }
-}
-#endif
-
-SkPicturePlayback::SkPicturePlayback(const SkPictInfo& info)
-    : fInfo(info) {
-    this->init();
-}
-
-void SkPicturePlayback::initForPlayback() const {
-    // ensure that the paths bounds are pre-computed
-    if (NULL != fPathHeap.get()) {
-        for (int i = 0; i < fPathHeap->count(); i++) {
-            (*fPathHeap.get())[i].updateBoundsCache();
-        }
-    }
-}
-
-SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record,
-                                     const SkPictInfo& info,
-                                     bool deepCopyOps)
-    : fInfo(info) {
-#ifdef SK_DEBUG_SIZE
-    size_t overallBytes, bitmapBytes, matricesBytes,
-    paintBytes, pathBytes, pictureBytes, regionBytes;
-    int bitmaps = record.bitmaps(&bitmapBytes);
-    int matrices = record.matrices(&matricesBytes);
-    int paints = record.paints(&paintBytes);
-    int paths = record.paths(&pathBytes);
-    int pictures = record.pictures(&pictureBytes);
-    int regions = record.regions(&regionBytes);
-    SkDebugf("picture record mem used %zd (stream %zd) ", record.size(),
-             record.streamlen());
-    if (bitmaps != 0)
-        SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps);
-    if (matrices != 0)
-        SkDebugf("matrices size %zd (matrices:%d) ", matricesBytes, matrices);
-    if (paints != 0)
-        SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints);
-    if (paths != 0)
-        SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths);
-    if (pictures != 0)
-        SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures);
-    if (regions != 0)
-        SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions);
-    if (record.fPointWrites != 0)
-        SkDebugf("points size %zd (points:%d) ", record.fPointBytes, record.fPointWrites);
-    if (record.fRectWrites != 0)
-        SkDebugf("rects size %zd (rects:%d) ", record.fRectBytes, record.fRectWrites);
-    if (record.fTextWrites != 0)
-        SkDebugf("text size %zd (text strings:%d) ", record.fTextBytes, record.fTextWrites);
-
-    SkDebugf("\n");
-#endif
-#ifdef SK_DEBUG_DUMP
-    record.dumpMatrices();
-    record.dumpPaints();
-#endif
-
-    this->init();
-
-    fOpData = record.opData(deepCopyOps);
-
-    fBoundingHierarchy = record.fBoundingHierarchy;
-    fStateTree = record.fStateTree;
-
-    SkSafeRef(fBoundingHierarchy);
-    SkSafeRef(fStateTree);
-    fContentInfo.set(record.fContentInfo);
-
-    if (NULL != fBoundingHierarchy) {
-        fBoundingHierarchy->flushDeferredInserts();
-    }
-
-    // copy over the refcnt dictionary to our reader
-    record.fFlattenableHeap.setupPlaybacks();
-
-    fBitmaps = record.fBitmapHeap->extractBitmaps();
-    fPaints = record.fPaints.unflattenToArray();
-
-    fBitmapHeap.reset(SkSafeRef(record.fBitmapHeap));
-    fPathHeap.reset(SkSafeRef(record.pathHeap()));
-
-    this->initForPlayback();
-
-    const SkTDArray<const SkPicture* >& pictures = record.getPictureRefs();
-    fPictureCount = pictures.count();
-    if (fPictureCount > 0) {
-        fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
-        for (int i = 0; i < fPictureCount; i++) {
-            fPictureRefs[i] = pictures[i];
-            fPictureRefs[i]->ref();
-        }
-    }
-
-#ifdef SK_DEBUG_SIZE
-    int overall = fPlayback->size(&overallBytes);
-    bitmaps = fPlayback->bitmaps(&bitmapBytes);
-    paints = fPlayback->paints(&paintBytes);
-    paths = fPlayback->paths(&pathBytes);
-    pictures = fPlayback->pictures(&pictureBytes);
-    regions = fPlayback->regions(&regionBytes);
-    SkDebugf("playback size %zd (objects:%d) ", overallBytes, overall);
-    if (bitmaps != 0)
-        SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps);
-    if (paints != 0)
-        SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints);
-    if (paths != 0)
-        SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths);
-    if (pictures != 0)
-        SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures);
-    if (regions != 0)
-        SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions);
-    SkDebugf("\n");
-#endif
-}
-
-SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo)
-    : fInfo(src.fInfo) {
-    this->init();
-
-    fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get()));
-    fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
-
-    fOpData = SkSafeRef(src.fOpData);
-
-    fBoundingHierarchy = src.fBoundingHierarchy;
-    fStateTree = src.fStateTree;
-    fContentInfo.set(src.fContentInfo);
-
-    SkSafeRef(fBoundingHierarchy);
-    SkSafeRef(fStateTree);
-
-    if (deepCopyInfo) {
-        SkASSERT(deepCopyInfo->initialized);
-
-        int paintCount = SafeCount(src.fPaints);
-
-        if (src.fBitmaps) {
-            fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src.fBitmaps->count());
-        }
-
-        fPaints = SkTRefArray<SkPaint>::Create(paintCount);
-        SkASSERT(deepCopyInfo->paintData.count() == paintCount);
-        SkBitmapHeap* bmHeap = deepCopyInfo->controller.getBitmapHeap();
-        SkTypefacePlayback* tfPlayback = deepCopyInfo->controller.getTypefacePlayback();
-        for (int i = 0; i < paintCount; i++) {
-            if (deepCopyInfo->paintData[i]) {
-                deepCopyInfo->paintData[i]->unflatten<SkPaint::FlatteningTraits>(
-                    &fPaints->writableAt(i), bmHeap, tfPlayback);
-            } else {
-                // needs_deep_copy was false, so just need to assign
-                fPaints->writableAt(i) = src.fPaints->at(i);
-            }
-        }
-
-    } else {
-        fBitmaps = SkSafeRef(src.fBitmaps);
-        fPaints = SkSafeRef(src.fPaints);
-    }
-
-    fPictureCount = src.fPictureCount;
-    fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
-    for (int i = 0; i < fPictureCount; i++) {
-        if (deepCopyInfo) {
-            fPictureRefs[i] = src.fPictureRefs[i]->clone();
-        } else {
-            fPictureRefs[i] = src.fPictureRefs[i];
-            fPictureRefs[i]->ref();
-        }
-    }
-}
-
-void SkPicturePlayback::init() {
-    fBitmaps = NULL;
-    fPaints = NULL;
-    fPictureRefs = NULL;
-    fPictureCount = 0;
-    fOpData = NULL;
-    fFactoryPlayback = NULL;
-    fBoundingHierarchy = NULL;
-    fStateTree = NULL;
-    fCachedActiveOps = NULL;
-    fCurOffset = 0;
-    fUseBBH = true;
-    fStart = 0;
-    fStop = 0;
-    fReplacements = NULL;
-}
-
-SkPicturePlayback::~SkPicturePlayback() {
-    SkSafeUnref(fOpData);
-
-    SkSafeUnref(fBitmaps);
-    SkSafeUnref(fPaints);
-    SkSafeUnref(fBoundingHierarchy);
-    SkSafeUnref(fStateTree);
-
-    SkDELETE(fCachedActiveOps);
-
-    for (int i = 0; i < fPictureCount; i++) {
-        fPictureRefs[i]->unref();
-    }
-    SkDELETE_ARRAY(fPictureRefs);
-
-    SkDELETE(fFactoryPlayback);
-}
-
-void SkPicturePlayback::dumpSize() const {
-    SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] paints=%d [%d]\n",
-             fOpData->size(),
-             SafeCount(fBitmaps), SafeCount(fBitmaps) * sizeof(SkBitmap),
-             SafeCount(fPaints), SafeCount(fPaints) * sizeof(SkPaint));
-    SkDebugf("--- picture size: paths=%d\n",
-             SafeCount(fPathHeap.get()));
-}
-
-bool SkPicturePlayback::containsBitmaps() const {
-    if (fBitmaps && fBitmaps->count() > 0) {
-        return true;
-    }
-    for (int i = 0; i < fPictureCount; ++i) {
-        if (fPictureRefs[i]->willPlayBackBitmaps()) {
-            return true;
-        }
-    }
-    return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-#include "SkStream.h"
-
-static size_t compute_chunk_size(SkFlattenable::Factory* array, int count) {
-    size_t size = 4;  // for 'count'
-
-    for (int i = 0; i < count; i++) {
-        const char* name = SkFlattenable::FactoryToName(array[i]);
-        if (NULL == name || 0 == *name) {
-            size += SkWStream::SizeOfPackedUInt(0);
-        } else {
-            size_t len = strlen(name);
-            size += SkWStream::SizeOfPackedUInt(len);
-            size += len;
-        }
-    }
-
-    return size;
-}
-
-void SkPicturePlayback::WriteFactories(SkWStream* stream, const SkFactorySet& rec) {
-    int count = rec.count();
-
-    SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count);
-    SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get();
-    rec.copyToArray(array);
-
-    size_t size = compute_chunk_size(array, count);
-
-    // TODO: write_tag_size should really take a size_t
-    SkPicture::WriteTagSize(stream, SK_PICT_FACTORY_TAG, (uint32_t) size);
-    SkDEBUGCODE(size_t start = stream->bytesWritten());
-    stream->write32(count);
-
-    for (int i = 0; i < count; i++) {
-        const char* name = SkFlattenable::FactoryToName(array[i]);
-//        SkDebugf("---- write factories [%d] %p <%s>\n", i, array[i], name);
-        if (NULL == name || 0 == *name) {
-            stream->writePackedUInt(0);
-        } else {
-            size_t len = strlen(name);
-            stream->writePackedUInt(len);
-            stream->write(name, len);
-        }
-    }
-
-    SkASSERT(size == (stream->bytesWritten() - start));
-}
-
-void SkPicturePlayback::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) {
-    int count = rec.count();
-
-    SkPicture::WriteTagSize(stream, SK_PICT_TYPEFACE_TAG, count);
-
-    SkAutoSTMalloc<16, SkTypeface*> storage(count);
-    SkTypeface** array = (SkTypeface**)storage.get();
-    rec.copyToArray((SkRefCnt**)array);
-
-    for (int i = 0; i < count; i++) {
-        array[i]->serialize(stream);
-    }
-}
-
-void SkPicturePlayback::flattenToBuffer(SkWriteBuffer& buffer) const {
-    int i, n;
-
-    if ((n = SafeCount(fBitmaps)) > 0) {
-        SkPicture::WriteTagSize(buffer, SK_PICT_BITMAP_BUFFER_TAG, n);
-        for (i = 0; i < n; i++) {
-            buffer.writeBitmap((*fBitmaps)[i]);
-        }
-    }
-
-    if ((n = SafeCount(fPaints)) > 0) {
-        SkPicture::WriteTagSize(buffer, SK_PICT_PAINT_BUFFER_TAG, n);
-        for (i = 0; i < n; i++) {
-            buffer.writePaint((*fPaints)[i]);
-        }
-    }
-
-    if ((n = SafeCount(fPathHeap.get())) > 0) {
-        SkPicture::WriteTagSize(buffer, SK_PICT_PATH_BUFFER_TAG, n);
-        fPathHeap->flatten(buffer);
-    }
-}
-
-void SkPicturePlayback::serialize(SkWStream* stream,
-                                  SkPicture::EncodeBitmap encoder) const {
-    SkPicture::WriteTagSize(stream, SK_PICT_READER_TAG, fOpData->size());
-    stream->write(fOpData->bytes(), fOpData->size());
-
-    if (fPictureCount > 0) {
-        SkPicture::WriteTagSize(stream, SK_PICT_PICTURE_TAG, fPictureCount);
-        for (int i = 0; i < fPictureCount; i++) {
-            fPictureRefs[i]->serialize(stream, encoder);
-        }
-    }
-
-    // Write some of our data into a writebuffer, and then serialize that
-    // into our stream
-    {
-        SkRefCntSet  typefaceSet;
-        SkFactorySet factSet;
-
-        SkWriteBuffer buffer(SkWriteBuffer::kCrossProcess_Flag);
-        buffer.setTypefaceRecorder(&typefaceSet);
-        buffer.setFactoryRecorder(&factSet);
-        buffer.setBitmapEncoder(encoder);
-
-        this->flattenToBuffer(buffer);
-
-        // We have to write these two sets into the stream *before* we write
-        // the buffer, since parsing that buffer will require that we already
-        // have these sets available to use.
-        WriteFactories(stream, factSet);
-        WriteTypefaces(stream, typefaceSet);
-
-        SkPicture::WriteTagSize(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten());
-        buffer.writeToStream(stream);
-    }
-
-    stream->write32(SK_PICT_EOF_TAG);
-}
-
-void SkPicturePlayback::flatten(SkWriteBuffer& buffer) const {
-    SkPicture::WriteTagSize(buffer, SK_PICT_READER_TAG, fOpData->size());
-    buffer.writeByteArray(fOpData->bytes(), fOpData->size());
-
-    if (fPictureCount > 0) {
-        SkPicture::WriteTagSize(buffer, SK_PICT_PICTURE_TAG, fPictureCount);
-        for (int i = 0; i < fPictureCount; i++) {
-            fPictureRefs[i]->flatten(buffer);
-        }
-    }
-
-    // Write this picture playback's data into a writebuffer
-    this->flattenToBuffer(buffer);
-    buffer.write32(SK_PICT_EOF_TAG);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- *  Return the corresponding SkReadBuffer flags, given a set of
- *  SkPictInfo flags.
- */
-static uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
-    static const struct {
-        uint32_t    fSrc;
-        uint32_t    fDst;
-    } gSD[] = {
-        { SkPictInfo::kCrossProcess_Flag,   SkReadBuffer::kCrossProcess_Flag },
-        { SkPictInfo::kScalarIsFloat_Flag,  SkReadBuffer::kScalarIsFloat_Flag },
-        { SkPictInfo::kPtrIs64Bit_Flag,     SkReadBuffer::kPtrIs64Bit_Flag },
-    };
-
-    uint32_t rbMask = 0;
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) {
-        if (pictInfoFlags & gSD[i].fSrc) {
-            rbMask |= gSD[i].fDst;
-        }
-    }
-    return rbMask;
-}
-
-bool SkPicturePlayback::parseStreamTag(SkStream* stream,
-                                       uint32_t tag,
-                                       uint32_t size,
-                                       SkPicture::InstallPixelRefProc proc) {
-    /*
-     *  By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
-     *  its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
-     *  but if they are present, they need to have been seen before the buffer.
-     *
-     *  We assert that if/when we see either of these, that we have not yet seen
-     *  the buffer tag, because if we have, then its too-late to deal with the
-     *  factories or typefaces.
-     */
-    SkDEBUGCODE(bool haveBuffer = false;)
-
-    switch (tag) {
-        case SK_PICT_READER_TAG: {
-            SkAutoMalloc storage(size);
-            if (stream->read(storage.get(), size) != size) {
-                return false;
-            }
-            SkASSERT(NULL == fOpData);
-            fOpData = SkData::NewFromMalloc(storage.detach(), size);
-        } break;
-        case SK_PICT_FACTORY_TAG: {
-            SkASSERT(!haveBuffer);
-        // Remove this code when v21 and below are no longer supported. At the
-        // same time add a new 'count' variable and use it rather then reusing 'size'.
-#ifndef DISABLE_V21_COMPATIBILITY_CODE
-            if (fInfo.fVersion >= 22) {
-                // in v22 this tag's size represents the size of the chunk in bytes
-                // and the number of factory strings is written out separately
-#endif
-                size = stream->readU32();
-#ifndef DISABLE_V21_COMPATIBILITY_CODE
-            }
-#endif
-            fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (size));
-            for (size_t i = 0; i < size; i++) {
-                SkString str;
-                const size_t len = stream->readPackedUInt();
-                str.resize(len);
-                if (stream->read(str.writable_str(), len) != len) {
-                    return false;
-                }
-                fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str());
-            }
-        } break;
-        case SK_PICT_TYPEFACE_TAG: {
-            SkASSERT(!haveBuffer);
-            const int count = SkToInt(size);
-            fTFPlayback.setCount(count);
-            for (int i = 0; i < count; i++) {
-                SkAutoTUnref<SkTypeface> tf(SkTypeface::Deserialize(stream));
-                if (!tf.get()) {    // failed to deserialize
-                    // fTFPlayback asserts it never has a null, so we plop in
-                    // the default here.
-                    tf.reset(SkTypeface::RefDefault());
-                }
-                fTFPlayback.set(i, tf);
-            }
-        } break;
-        case SK_PICT_PICTURE_TAG: {
-            fPictureCount = size;
-            fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
-            bool success = true;
-            int i = 0;
-            for ( ; i < fPictureCount; i++) {
-                fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc);
-                if (NULL == fPictureRefs[i]) {
-                    success = false;
-                    break;
-                }
-            }
-            if (!success) {
-                // Delete all of the pictures that were already created (up to but excluding i):
-                for (int j = 0; j < i; j++) {
-                    fPictureRefs[j]->unref();
-                }
-                // Delete the array
-                SkDELETE_ARRAY(fPictureRefs);
-                fPictureCount = 0;
-                return false;
-            }
-        } break;
-        case SK_PICT_BUFFER_SIZE_TAG: {
-            SkAutoMalloc storage(size);
-            if (stream->read(storage.get(), size) != size) {
-                return false;
-            }
-
-            SkReadBuffer buffer(storage.get(), size);
-            buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags));
-            buffer.setVersion(fInfo.fVersion);
-
-            fFactoryPlayback->setupBuffer(buffer);
-            fTFPlayback.setupBuffer(buffer);
-            buffer.setBitmapDecoder(proc);
-
-            while (!buffer.eof()) {
-                tag = buffer.readUInt();
-                size = buffer.readUInt();
-                if (!this->parseBufferTag(buffer, tag, size)) {
-                    return false;
-                }
-            }
-            SkDEBUGCODE(haveBuffer = true;)
-        } break;
-    }
-    return true;    // success
-}
-
-bool SkPicturePlayback::parseBufferTag(SkReadBuffer& buffer,
-                                       uint32_t tag, uint32_t size) {
-    switch (tag) {
-        case SK_PICT_BITMAP_BUFFER_TAG: {
-            const int count = SkToInt(size);
-            fBitmaps = SkTRefArray<SkBitmap>::Create(size);
-            for (int i = 0; i < count; ++i) {
-                SkBitmap* bm = &fBitmaps->writableAt(i);
-                buffer.readBitmap(bm);
-                bm->setImmutable();
-            }
-        } break;
-        case SK_PICT_PAINT_BUFFER_TAG: {
-            const int count = SkToInt(size);
-            fPaints = SkTRefArray<SkPaint>::Create(size);
-            for (int i = 0; i < count; ++i) {
-                buffer.readPaint(&fPaints->writableAt(i));
-            }
-        } break;
-        case SK_PICT_PATH_BUFFER_TAG:
-            if (size > 0) {
-                fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
-            }
-            break;
-        case SK_PICT_READER_TAG: {
-            SkAutoMalloc storage(size);
-            if (!buffer.readByteArray(storage.get(), size) ||
-                !buffer.validate(NULL == fOpData)) {
-                return false;
-            }
-            SkASSERT(NULL == fOpData);
-            fOpData = SkData::NewFromMalloc(storage.detach(), size);
-        } break;
-        case SK_PICT_PICTURE_TAG: {
-            if (!buffer.validate((0 == fPictureCount) && (NULL == fPictureRefs))) {
-                return false;
-            }
-            fPictureCount = size;
-            fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
-            bool success = true;
-            int i = 0;
-            for ( ; i < fPictureCount; i++) {
-                fPictureRefs[i] = SkPicture::CreateFromBuffer(buffer);
-                if (NULL == fPictureRefs[i]) {
-                    success = false;
-                    break;
-                }
-            }
-            if (!success) {
-                // Delete all of the pictures that were already created (up to but excluding i):
-                for (int j = 0; j < i; j++) {
-                    fPictureRefs[j]->unref();
-                }
-                // Delete the array
-                SkDELETE_ARRAY(fPictureRefs);
-                fPictureCount = 0;
-                return false;
-            }
-        } break;
-        default:
-            // The tag was invalid.
-            return false;
-    }
-    return true;    // success
-}
-
-SkPicturePlayback* SkPicturePlayback::CreateFromStream(SkStream* stream,
-                                                       const SkPictInfo& info,
-                                                       SkPicture::InstallPixelRefProc proc) {
-    SkAutoTDelete<SkPicturePlayback> playback(SkNEW_ARGS(SkPicturePlayback, (info)));
-
-    if (!playback->parseStream(stream, proc)) {
-        return NULL;
-    }
-    return playback.detach();
-}
-
-SkPicturePlayback* SkPicturePlayback::CreateFromBuffer(SkReadBuffer& buffer,
-                                                       const SkPictInfo& info) {
-    SkAutoTDelete<SkPicturePlayback> playback(SkNEW_ARGS(SkPicturePlayback, (info)));
-    buffer.setVersion(info.fVersion);
-
-    if (!playback->parseBuffer(buffer)) {
-        return NULL;
-    }
-    return playback.detach();
-}
-
-bool SkPicturePlayback::parseStream(SkStream* stream,
-                                    SkPicture::InstallPixelRefProc proc) {
-    for (;;) {
-        uint32_t tag = stream->readU32();
-        if (SK_PICT_EOF_TAG == tag) {
-            break;
-        }
-
-        uint32_t size = stream->readU32();
-        if (!this->parseStreamTag(stream, tag, size, proc)) {
-            return false; // we're invalid
-        }
-    }
-    return true;
-}
-
-bool SkPicturePlayback::parseBuffer(SkReadBuffer& buffer) {
-    for (;;) {
-        uint32_t tag = buffer.readUInt();
-        if (SK_PICT_EOF_TAG == tag) {
-            break;
-        }
-
-        uint32_t size = buffer.readUInt();
-        if (!this->parseBufferTag(buffer, tag, size)) {
-            return false; // we're invalid
-        }
-    }
-    return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef SPEW_CLIP_SKIPPING
-struct SkipClipRec {
-    int     fCount;
-    size_t  fSize;
-
-    SkipClipRec() {
-        fCount = 0;
-        fSize = 0;
-    }
-
-    void recordSkip(size_t bytes) {
-        fCount += 1;
-        fSize += bytes;
-    }
-};
-#endif
-
-#ifdef SK_DEVELOPER
-bool SkPicturePlayback::preDraw(int opIndex, int type) {
-    return false;
-}
-
-void SkPicturePlayback::postDraw(int opIndex) {
-}
-#endif
+#include "SkReader32.h"
+#include "SkTextBlob.h"
+#include "SkTDArray.h"
+#include "SkTypes.h"
 
 /*
  * Read the next op code and chunk size from 'reader'. The returned size
  * is the entire size of the chunk (including the opcode). Thus, the
- * offset just prior to calling read_op_and_size + 'size' is the offset
+ * offset just prior to calling ReadOpAndSize + 'size' is the offset
  * to the next chunk's op code. This also means that the size of a chunk
  * with no arguments (just an opcode) will be 4.
  */
-static DrawType read_op_and_size(SkReader32* reader, uint32_t* size) {
+DrawType SkPicturePlayback::ReadOpAndSize(SkReader32* reader, uint32_t* size) {
     uint32_t temp = reader->readInt();
     uint32_t op;
-    if (((uint8_t) temp) == temp) {
+    if (((uint8_t)temp) == temp) {
         // old skp file - no size information
         op = temp;
         *size = 0;
@@ -726,1173 +36,489 @@
             *size = reader->readInt();
         }
     }
-    return (DrawType) op;
+    return (DrawType)op;
 }
 
-uint32_t SkPicturePlayback::CachedOperationList::offset(int index) const {
-    SkASSERT(index < fOps.count());
-    return ((SkPictureStateTree::Draw*)fOps[index])->fOffset;
+
+static const SkRect* get_rect_ptr(SkReader32* reader) {
+    if (reader->readBool()) {
+        return &reader->skipT<SkRect>();
+    } else {
+        return NULL;
+    }
 }
 
-const SkMatrix& SkPicturePlayback::CachedOperationList::matrix(int index) const {
-    SkASSERT(index < fOps.count());
-    return *((SkPictureStateTree::Draw*)fOps[index])->fMatrix;
-}
-
-const SkPicture::OperationList& SkPicturePlayback::getActiveOps(const SkIRect& query) {
-    if (NULL == fStateTree || NULL == fBoundingHierarchy) {
-        return SkPicture::OperationList::InvalidList();
-    }
-
-    if (NULL == fCachedActiveOps) {
-        fCachedActiveOps = SkNEW(CachedOperationList);
-    }
-
-    if (query == fCachedActiveOps->fCacheQueryRect) {
-        return *fCachedActiveOps;
-    }
-
-    fCachedActiveOps->fOps.rewind();
-
-    fBoundingHierarchy->search(query, &(fCachedActiveOps->fOps));
-    if (0 != fCachedActiveOps->fOps.count()) {
-        SkTQSort<SkPictureStateTree::Draw>(
-            reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->fOps.begin()),
-            reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->fOps.end()-1));
-    }
-
-    fCachedActiveOps->fCacheQueryRect = query;
-    return *fCachedActiveOps;
-}
-
-class SkAutoResetOpID {
+class TextContainer {
 public:
-    SkAutoResetOpID(SkPicturePlayback* playback) : fPlayback(playback) { }
-    ~SkAutoResetOpID() {
-        if (NULL != fPlayback) {
-            fPlayback->resetOpID();
-        }
-    }
-
-private:
-    SkPicturePlayback* fPlayback;
+    size_t length() { return fByteLength; }
+    const void* text() { return (const void*)fText; }
+    size_t fByteLength;
+    const char* fText;
 };
 
-// TODO: Replace with hash or pass in "lastLookedUp" hint
-SkPicturePlayback::PlaybackReplacements::ReplacementInfo*
-SkPicturePlayback::PlaybackReplacements::lookupByStart(size_t start) {
-    SkDEBUGCODE(this->validate());
-    for (int i = 0; i < fReplacements.count(); ++i) {
-        if (start == fReplacements[i].fStart) {
-            return &fReplacements[i];
-        } else if (start < fReplacements[i].fStart) {
-            return NULL;  // the ranges are monotonically increasing and non-overlapping
+void get_text(SkReader32* reader, TextContainer* text) {
+    size_t length = text->fByteLength = reader->readInt();
+    text->fText = (const char*)reader->skip(length);
+}
+
+// FIXME: SkBitmaps are stateful, so we need to copy them to play back in multiple threads.
+static SkBitmap shallow_copy(const SkBitmap& bitmap) {
+    return bitmap;
+}
+
+const SkPicture::OperationList* SkPicturePlayback::getActiveOps(const SkCanvas* canvas) {
+
+    if (fUseBBH) {
+        SkRect clipBounds;
+        if (canvas->getClipBounds(&clipBounds)) {
+            return fPictureData->getActiveOps(clipBounds);
         }
     }
 
     return NULL;
 }
 
-void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) {
-    SkAutoResetOpID aroi(this);
+// Initialize the state tree iterator. Return false if there is nothing left to draw.
+bool SkPicturePlayback::initIterator(SkPictureStateTree::Iterator* iter,
+                                     SkCanvas* canvas,
+                                     const SkPicture::OperationList *activeOpsList) {
+
+    if (activeOpsList) {
+        if (0 == activeOpsList->numOps()) {
+            return false;  // nothing to draw
+        }
+
+        fPictureData->initIterator(iter, activeOpsList->fOps, canvas);
+    }
+
+    return true;
+}
+
+// If 'iter' is valid use it to skip forward through the picture.
+void SkPicturePlayback::StepIterator(SkPictureStateTree::Iterator* iter, SkReader32* reader) {
+    if (iter->isValid()) {
+        uint32_t skipTo = iter->nextDraw();
+        if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
+            reader->setOffset(reader->size());  // skip to end
+        } else {
+            reader->setOffset(skipTo);
+        }
+    }
+}
+
+// Update the iterator and state tree to catch up with the skipped ops.
+void SkPicturePlayback::SkipIterTo(SkPictureStateTree::Iterator* iter,
+                                   SkReader32* reader,
+                                   uint32_t skipTo) {
+    SkASSERT(skipTo <= reader->size());
+    SkASSERT(reader->offset() <= skipTo); // should only be skipping forward
+
+    if (iter->isValid()) {
+        // If using a bounding box hierarchy, advance the state tree
+        // iterator until at or after skipTo
+        uint32_t adjustedSkipTo;
+        do {
+            adjustedSkipTo = iter->nextDraw();
+        } while (adjustedSkipTo < skipTo);
+        skipTo = adjustedSkipTo;
+    }
+    if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
+        reader->setOffset(reader->size());  // skip to end
+    } else {
+        reader->setOffset(skipTo);
+    }
+}
+
+void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) {
+    AutoResetOpID aroi(this);
     SkASSERT(0 == fCurOffset);
 
-#ifdef ENABLE_TIME_DRAW
-    SkAutoTime  at("SkPicture::draw", 50);
-#endif
+    SkAutoTDelete<const SkPicture::OperationList> activeOpsList(this->getActiveOps(canvas));
+    SkPictureStateTree::Iterator it;
 
-#ifdef SPEW_CLIP_SKIPPING
-    SkipClipRec skipRect, skipRRect, skipRegion, skipPath, skipCull;
-    int opCount = 0;
-#endif
-
-#ifdef SK_BUILD_FOR_ANDROID
-    SkAutoMutexAcquire autoMutex(fDrawMutex);
-#endif
-
-    // kDrawComplete will be the signal that we have reached the end of
-    // the command stream
-    static const uint32_t kDrawComplete = SK_MaxU32;
-
-    SkReader32 reader(fOpData->bytes(), fOpData->size());
-    TextContainer text;
-    const SkTDArray<void*>* activeOps = NULL;
-
-    // When draw limits are enabled (i.e., 0 != fStart || 0 != fStop) the state
-    // tree isn't used to pick and choose the draw operations
-    if (0 == fStart && 0 == fStop) {
-        if (fUseBBH && NULL != fStateTree && NULL != fBoundingHierarchy) {
-            SkRect clipBounds;
-            if (canvas.getClipBounds(&clipBounds)) {
-                SkIRect query;
-                clipBounds.roundOut(&query);
-
-                const SkPicture::OperationList& activeOpsList = this->getActiveOps(query);
-                if (activeOpsList.valid()) {
-                    if (0 == activeOpsList.numOps()) {
-                        return;     // nothing to draw
-                    }
-
-                    // Since the opList is valid we know it is our derived class
-                    activeOps = &((const CachedOperationList&)activeOpsList).fOps;
-                }
-            }
-        }
+    if (!this->initIterator(&it, canvas, activeOpsList.get())) {
+        return;  // nothing to draw
     }
 
-    SkPictureStateTree::Iterator it = (NULL == activeOps) ?
-        SkPictureStateTree::Iterator() :
-        fStateTree->getIterator(*activeOps, &canvas);
+    SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData()->size());
 
-    if (0 != fStart || 0 != fStop) {
-        reader.setOffset(fStart);
-        uint32_t size;
-        SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
-        SkASSERT(SAVE_LAYER == op);
-        reader.setOffset(fStart+size);
-    }
-
-    if (it.isValid()) {
-        uint32_t skipTo = it.nextDraw();
-        if (kDrawComplete == skipTo) {
-            return;
-        }
-        reader.setOffset(skipTo);
-    }
+    StepIterator(&it, &reader);
 
     // Record this, so we can concat w/ it if we encounter a setMatrix()
-    SkMatrix initialMatrix = canvas.getTotalMatrix();
+    SkMatrix initialMatrix = canvas->getTotalMatrix();
 
-    SkAutoCanvasRestore acr(&canvas, false);
-
-#ifdef SK_BUILD_FOR_ANDROID
-    fAbortCurrentPlayback = false;
-#endif
-
-#ifdef SK_DEVELOPER
-    int opIndex = -1;
-#endif
+    SkAutoCanvasRestore acr(canvas, false);
 
     while (!reader.eof()) {
         if (callback && callback->abortDrawing()) {
             return;
         }
-#ifdef SK_BUILD_FOR_ANDROID
-        if (fAbortCurrentPlayback) {
-            return;
-        }
-#endif
-        if (0 != fStart || 0 != fStop) {
-            size_t offset = reader.offset() ;
-            if (offset >= fStop) {
-                uint32_t size;
-                SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
-                SkASSERT(RESTORE == op);
-                return;
-            }
-        }
-
-        if (NULL != fReplacements) {
-            // Potentially replace a block of operations with a single drawBitmap call
-            SkPicturePlayback::PlaybackReplacements::ReplacementInfo* temp =
-                                            fReplacements->lookupByStart(reader.offset());
-            if (NULL != temp) {
-                SkASSERT(NULL != temp->fBM);
-                SkASSERT(NULL != temp->fPaint);
-                canvas.save();
-                canvas.setMatrix(initialMatrix);
-                canvas.drawBitmap(*temp->fBM, temp->fPos.fX, temp->fPos.fY, temp->fPaint);
-                canvas.restore();
-
-                if (it.isValid()) {
-                    // This save is needed since the BBH will automatically issue
-                    // a restore to balanced the saveLayer we're skipping
-                    canvas.save();
-
-                    // At this point we know that the PictureStateTree was aiming
-                    // for some draw op within temp's saveLayer (although potentially
-                    // in a separate saveLayer nested inside it).
-                    // We need to skip all the operations inside temp's range
-                    // along with all the associated state changes but update
-                    // the state tree to the first operation outside temp's range.
-
-                    uint32_t skipTo;
-                    do {
-                        skipTo = it.nextDraw();
-                        if (kDrawComplete == skipTo) {
-                            break;
-                        }
-
-                        if (skipTo <= temp->fStop) {
-                            reader.setOffset(skipTo);
-                            uint32_t size;
-                            DrawType op = read_op_and_size(&reader, &size);
-                            // Since we are relying on the normal SkPictureStateTree
-                            // playback we need to convert any nested saveLayer calls
-                            // it may issue into saves (so that all its internal
-                            // restores will be balanced).
-                            if (SAVE_LAYER == op) {
-                                canvas.save();
-                            }
-                        }
-                    } while (skipTo <= temp->fStop);
-
-                    if (kDrawComplete == skipTo) {
-                        break;
-                    }
-
-                    reader.setOffset(skipTo);
-                } else {
-                    reader.setOffset(temp->fStop);
-                    uint32_t size;
-                    SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
-                    SkASSERT(RESTORE == op);
-                }
-                continue;
-            }
-        }
-
-#ifdef SPEW_CLIP_SKIPPING
-        opCount++;
-#endif
 
         fCurOffset = reader.offset();
         uint32_t size;
-        DrawType op = read_op_and_size(&reader, &size);
-        size_t skipTo = 0;
+        DrawType op = ReadOpAndSize(&reader, &size);
         if (NOOP == op) {
             // NOOPs are to be ignored - do not propagate them any further
-            skipTo = fCurOffset + size;
-#ifdef SK_DEVELOPER
-        } else {
-            opIndex++;
-            if (this->preDraw(opIndex, op)) {
-                skipTo = fCurOffset + size;
-            }
-#endif
-        }
-
-        if (0 != skipTo) {
-            if (it.isValid()) {
-                // If using a bounding box hierarchy, advance the state tree
-                // iterator until at or after skipTo
-                uint32_t adjustedSkipTo;
-                do {
-                    adjustedSkipTo = it.nextDraw();
-                } while (adjustedSkipTo < skipTo);
-                skipTo = adjustedSkipTo;
-            }
-            if (kDrawComplete == skipTo) {
-                break;
-            }
-            reader.setOffset(skipTo);
+            SkipIterTo(&it, &reader, fCurOffset + size);
             continue;
         }
 
-        switch (op) {
-            case CLIP_PATH: {
-                const SkPath& path = getPath(reader);
-                uint32_t packed = reader.readInt();
-                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
-                bool doAA = ClipParams_unpackDoAA(packed);
-                size_t offsetToRestore = reader.readInt();
-                SkASSERT(!offsetToRestore || \
-                    offsetToRestore >= reader.offset());
-                canvas.clipPath(path, regionOp, doAA);
-                if (canvas.isClipEmpty() && offsetToRestore) {
-#ifdef SPEW_CLIP_SKIPPING
-                    skipPath.recordSkip(offsetToRestore - reader.offset());
-#endif
-                    reader.setOffset(offsetToRestore);
-                }
-            } break;
-            case CLIP_REGION: {
-                SkRegion region;
-                this->getRegion(reader, &region);
-                uint32_t packed = reader.readInt();
-                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
-                size_t offsetToRestore = reader.readInt();
-                SkASSERT(!offsetToRestore || \
-                    offsetToRestore >= reader.offset());
-                canvas.clipRegion(region, regionOp);
-                if (canvas.isClipEmpty() && offsetToRestore) {
-#ifdef SPEW_CLIP_SKIPPING
-                    skipRegion.recordSkip(offsetToRestore - reader.offset());
-#endif
-                    reader.setOffset(offsetToRestore);
-                }
-            } break;
-            case CLIP_RECT: {
-                const SkRect& rect = reader.skipT<SkRect>();
-                uint32_t packed = reader.readInt();
-                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
-                bool doAA = ClipParams_unpackDoAA(packed);
-                size_t offsetToRestore = reader.readInt();
-                SkASSERT(!offsetToRestore || \
-                         offsetToRestore >= reader.offset());
-                canvas.clipRect(rect, regionOp, doAA);
-                if (canvas.isClipEmpty() && offsetToRestore) {
-#ifdef SPEW_CLIP_SKIPPING
-                    skipRect.recordSkip(offsetToRestore - reader.offset());
-#endif
-                    reader.setOffset(offsetToRestore);
-                }
-            } break;
-            case CLIP_RRECT: {
-                SkRRect rrect;
-                reader.readRRect(&rrect);
-                uint32_t packed = reader.readInt();
-                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
-                bool doAA = ClipParams_unpackDoAA(packed);
-                size_t offsetToRestore = reader.readInt();
-                SkASSERT(!offsetToRestore || offsetToRestore >= reader.offset());
-                canvas.clipRRect(rrect, regionOp, doAA);
-                if (canvas.isClipEmpty() && offsetToRestore) {
-#ifdef SPEW_CLIP_SKIPPING
-                    skipRRect.recordSkip(offsetToRestore - reader.offset());
-#endif
-                    reader.setOffset(offsetToRestore);
-                }
-            } break;
-            case PUSH_CULL: {
-                const SkRect& cullRect = reader.skipT<SkRect>();
-                size_t offsetToRestore = reader.readInt();
-                if (offsetToRestore && canvas.quickReject(cullRect)) {
-#ifdef SPEW_CLIP_SKIPPING
-                    skipCull.recordSkip(offsetToRestore - reader.offset());
-#endif
-                    reader.setOffset(offsetToRestore);
-                } else {
-                    canvas.pushCull(cullRect);
-                }
-            } break;
-            case POP_CULL:
-                canvas.popCull();
-                break;
-            case CONCAT: {
-                SkMatrix matrix;
-                this->getMatrix(reader, &matrix);
-                canvas.concat(matrix);
-                break;
-            }
-            case DRAW_BITMAP: {
-                const SkPaint* paint = this->getPaint(reader);
-                const SkBitmap& bitmap = this->getBitmap(reader);
-                const SkPoint& loc = reader.skipT<SkPoint>();
-                canvas.drawBitmap(bitmap, loc.fX, loc.fY, paint);
-            } break;
-            case DRAW_BITMAP_RECT_TO_RECT: {
-                const SkPaint* paint = this->getPaint(reader);
-                const SkBitmap& bitmap = this->getBitmap(reader);
-                const SkRect* src = this->getRectPtr(reader);   // may be null
-                const SkRect& dst = reader.skipT<SkRect>();     // required
-                SkCanvas::DrawBitmapRectFlags flags;
-                flags = (SkCanvas::DrawBitmapRectFlags) reader.readInt();
-                canvas.drawBitmapRectToRect(bitmap, src, dst, paint, flags);
-            } break;
-            case DRAW_BITMAP_MATRIX: {
-                const SkPaint* paint = this->getPaint(reader);
-                const SkBitmap& bitmap = this->getBitmap(reader);
-                SkMatrix matrix;
-                this->getMatrix(reader, &matrix);
-                canvas.drawBitmapMatrix(bitmap, matrix, paint);
-            } break;
-            case DRAW_BITMAP_NINE: {
-                const SkPaint* paint = this->getPaint(reader);
-                const SkBitmap& bitmap = this->getBitmap(reader);
-                const SkIRect& src = reader.skipT<SkIRect>();
-                const SkRect& dst = reader.skipT<SkRect>();
-                canvas.drawBitmapNine(bitmap, src, dst, paint);
-            } break;
-            case DRAW_CLEAR:
-                canvas.clear(reader.readInt());
-                break;
-            case DRAW_DATA: {
-                size_t length = reader.readInt();
-                canvas.drawData(reader.skip(length), length);
-                // skip handles padding the read out to a multiple of 4
-            } break;
-            case DRAW_DRRECT: {
-                const SkPaint& paint = *this->getPaint(reader);
-                SkRRect outer, inner;
-                reader.readRRect(&outer);
-                reader.readRRect(&inner);
-                canvas.drawDRRect(outer, inner, paint);
-            } break;
-            case BEGIN_COMMENT_GROUP: {
-                const char* desc = reader.readString();
-                canvas.beginCommentGroup(desc);
-            } break;
-            case COMMENT: {
-                const char* kywd = reader.readString();
-                const char* value = reader.readString();
-                canvas.addComment(kywd, value);
-            } break;
-            case END_COMMENT_GROUP: {
-                canvas.endCommentGroup();
-            } break;
-            case DRAW_OVAL: {
-                const SkPaint& paint = *this->getPaint(reader);
-                canvas.drawOval(reader.skipT<SkRect>(), paint);
-            } break;
-            case DRAW_PAINT:
-                canvas.drawPaint(*this->getPaint(reader));
-                break;
-            case DRAW_PATH: {
-                const SkPaint& paint = *this->getPaint(reader);
-                canvas.drawPath(getPath(reader), paint);
-            } break;
-            case DRAW_PICTURE:
-                canvas.drawPicture(this->getPicture(reader));
-                break;
-            case DRAW_POINTS: {
-                const SkPaint& paint = *this->getPaint(reader);
-                SkCanvas::PointMode mode = (SkCanvas::PointMode)reader.readInt();
-                size_t count = reader.readInt();
-                const SkPoint* pts = (const SkPoint*)reader.skip(sizeof(SkPoint) * count);
-                canvas.drawPoints(mode, count, pts, paint);
-            } break;
-            case DRAW_POS_TEXT: {
-                const SkPaint& paint = *this->getPaint(reader);
-                getText(reader, &text);
-                size_t points = reader.readInt();
-                const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof(SkPoint));
-                canvas.drawPosText(text.text(), text.length(), pos, paint);
-            } break;
-            case DRAW_POS_TEXT_TOP_BOTTOM: {
-                const SkPaint& paint = *this->getPaint(reader);
-                getText(reader, &text);
-                size_t points = reader.readInt();
-                const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof(SkPoint));
-                const SkScalar top = reader.readScalar();
-                const SkScalar bottom = reader.readScalar();
-                if (!canvas.quickRejectY(top, bottom)) {
-                    canvas.drawPosText(text.text(), text.length(), pos, paint);
-                }
-            } break;
-            case DRAW_POS_TEXT_H: {
-                const SkPaint& paint = *this->getPaint(reader);
-                getText(reader, &text);
-                size_t xCount = reader.readInt();
-                const SkScalar constY = reader.readScalar();
-                const SkScalar* xpos = (const SkScalar*)reader.skip(xCount * sizeof(SkScalar));
-                canvas.drawPosTextH(text.text(), text.length(), xpos, constY,
-                                    paint);
-            } break;
-            case DRAW_POS_TEXT_H_TOP_BOTTOM: {
-                const SkPaint& paint = *this->getPaint(reader);
-                getText(reader, &text);
-                size_t xCount = reader.readInt();
-                const SkScalar* xpos = (const SkScalar*)reader.skip((3 + xCount) * sizeof(SkScalar));
-                const SkScalar top = *xpos++;
-                const SkScalar bottom = *xpos++;
-                const SkScalar constY = *xpos++;
-                if (!canvas.quickRejectY(top, bottom)) {
-                    canvas.drawPosTextH(text.text(), text.length(), xpos,
-                                        constY, paint);
-                }
-            } break;
-            case DRAW_RECT: {
-                const SkPaint& paint = *this->getPaint(reader);
-                canvas.drawRect(reader.skipT<SkRect>(), paint);
-            } break;
-            case DRAW_RRECT: {
-                const SkPaint& paint = *this->getPaint(reader);
-                SkRRect rrect;
-                reader.readRRect(&rrect);
-                canvas.drawRRect(rrect, paint);
-            } break;
-            case DRAW_SPRITE: {
-                const SkPaint* paint = this->getPaint(reader);
-                const SkBitmap& bitmap = this->getBitmap(reader);
-                int left = reader.readInt();
-                int top = reader.readInt();
-                canvas.drawSprite(bitmap, left, top, paint);
-            } break;
-            case DRAW_TEXT: {
-                const SkPaint& paint = *this->getPaint(reader);
-                this->getText(reader, &text);
-                SkScalar x = reader.readScalar();
-                SkScalar y = reader.readScalar();
-                canvas.drawText(text.text(), text.length(), x, y, paint);
-            } break;
-            case DRAW_TEXT_TOP_BOTTOM: {
-                const SkPaint& paint = *this->getPaint(reader);
-                this->getText(reader, &text);
-                const SkScalar* ptr = (const SkScalar*)reader.skip(4 * sizeof(SkScalar));
-                // ptr[0] == x
-                // ptr[1] == y
-                // ptr[2] == top
-                // ptr[3] == bottom
-                if (!canvas.quickRejectY(ptr[2], ptr[3])) {
-                    canvas.drawText(text.text(), text.length(), ptr[0], ptr[1],
-                                    paint);
-                }
-            } break;
-            case DRAW_TEXT_ON_PATH: {
-                const SkPaint& paint = *this->getPaint(reader);
-                getText(reader, &text);
-                const SkPath& path = this->getPath(reader);
-                SkMatrix matrix;
-                this->getMatrix(reader, &matrix);
-                canvas.drawTextOnPath(text.text(), text.length(), path, &matrix, paint);
-            } break;
-            case DRAW_VERTICES: {
-                SkAutoTUnref<SkXfermode> xfer;
-                const SkPaint& paint = *this->getPaint(reader);
-                DrawVertexFlags flags = (DrawVertexFlags)reader.readInt();
-                SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader.readInt();
-                int vCount = reader.readInt();
-                const SkPoint* verts = (const SkPoint*)reader.skip(
-                                                    vCount * sizeof(SkPoint));
-                const SkPoint* texs = NULL;
-                const SkColor* colors = NULL;
-                const uint16_t* indices = NULL;
-                int iCount = 0;
-                if (flags & DRAW_VERTICES_HAS_TEXS) {
-                    texs = (const SkPoint*)reader.skip(
-                                                    vCount * sizeof(SkPoint));
-                }
-                if (flags & DRAW_VERTICES_HAS_COLORS) {
-                    colors = (const SkColor*)reader.skip(
-                                                    vCount * sizeof(SkColor));
-                }
-                if (flags & DRAW_VERTICES_HAS_INDICES) {
-                    iCount = reader.readInt();
-                    indices = (const uint16_t*)reader.skip(
-                                                    iCount * sizeof(uint16_t));
-                }
-                if (flags & DRAW_VERTICES_HAS_XFER) {
-                    int mode = reader.readInt();
-                    if (mode < 0 || mode > SkXfermode::kLastMode) {
-                        mode = SkXfermode::kModulate_Mode;
-                    }
-                    xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode));
-                }
-                canvas.drawVertices(vmode, vCount, verts, texs, colors, xfer,
-                                    indices, iCount, paint);
-            } break;
-            case RESTORE:
-                canvas.restore();
-                break;
-            case ROTATE:
-                canvas.rotate(reader.readScalar());
-                break;
-            case SAVE:
-                canvas.save((SkCanvas::SaveFlags) reader.readInt());
-                break;
-            case SAVE_LAYER: {
-                const SkRect* boundsPtr = this->getRectPtr(reader);
-                const SkPaint* paint = this->getPaint(reader);
-                canvas.saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) reader.readInt());
-                } break;
-            case SCALE: {
-                SkScalar sx = reader.readScalar();
-                SkScalar sy = reader.readScalar();
-                canvas.scale(sx, sy);
-            } break;
-            case SET_MATRIX: {
-                SkMatrix matrix;
-                this->getMatrix(reader, &matrix);
-                matrix.postConcat(initialMatrix);
-                canvas.setMatrix(matrix);
-            } break;
-            case SKEW: {
-                SkScalar sx = reader.readScalar();
-                SkScalar sy = reader.readScalar();
-                canvas.skew(sx, sy);
-            } break;
-            case TRANSLATE: {
-                SkScalar dx = reader.readScalar();
-                SkScalar dy = reader.readScalar();
-                canvas.translate(dx, dy);
-            } break;
-            default:
-                SkASSERT(0);
-        }
+        this->handleOp(&reader, op, size, canvas, initialMatrix);
 
-#ifdef SK_DEVELOPER
-        this->postDraw(opIndex);
-#endif
-
-        if (it.isValid()) {
-            uint32_t skipTo = it.nextDraw();
-            if (kDrawComplete == skipTo) {
-                break;
-            }
-            reader.setOffset(skipTo);
-        }
+        StepIterator(&it, &reader);
     }
-
-#ifdef SPEW_CLIP_SKIPPING
-    {
-        size_t size =  skipRect.fSize + skipRRect.fSize + skipPath.fSize + skipRegion.fSize +
-                skipCull.fSize;
-        SkDebugf("--- Clip skips %d%% rect:%d rrect:%d path:%d rgn:%d cull:%d\n",
-             size * 100 / reader.offset(), skipRect.fCount, skipRRect.fCount,
-                 skipPath.fCount, skipRegion.fCount, skipCull.fCount);
-        SkDebugf("--- Total ops: %d\n", opCount);
-    }
-#endif
-//    this->dumpSize();
 }
 
-
-#if SK_SUPPORT_GPU
-bool SkPicturePlayback::suitableForGpuRasterization(GrContext* context, const char **reason,
-                                                    int sampleCount) const {
-    // TODO: the heuristic used here needs to be refined
-    static const int kNumPaintWithPathEffectUsesTol = 1;
-    static const int kNumAAConcavePaths = 5;
-
-    SkASSERT(fContentInfo.numAAHairlineConcavePaths() <= fContentInfo.numAAConcavePaths());
-
-    int numNonDashedPathEffects = fContentInfo.numPaintWithPathEffectUses() -
-                                  fContentInfo.numFastPathDashEffects();
-
-    bool suitableForDash = (0 == fContentInfo.numPaintWithPathEffectUses()) ||
-                           (numNonDashedPathEffects < kNumPaintWithPathEffectUsesTol
-                            && 0 == sampleCount);
-
-    bool ret = suitableForDash &&
-                    (fContentInfo.numAAConcavePaths() - fContentInfo.numAAHairlineConcavePaths()) 
-                    < kNumAAConcavePaths;
-    if (!ret && NULL != reason) {
-        if (!suitableForDash) {
-            if (0 != sampleCount) {
-                *reason = "Can't use multisample on dash effect.";
+void SkPicturePlayback::handleOp(SkReader32* reader,
+                                 DrawType op,
+                                 uint32_t size,
+                                 SkCanvas* canvas,
+                                 const SkMatrix& initialMatrix) {
+    switch (op) {
+        case CLIP_PATH: {
+            const SkPath& path = fPictureData->getPath(reader);
+            uint32_t packed = reader->readInt();
+            SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
+            bool doAA = ClipParams_unpackDoAA(packed);
+            size_t offsetToRestore = reader->readInt();
+            SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
+            canvas->clipPath(path, regionOp, doAA);
+            if (canvas->isClipEmpty() && offsetToRestore) {
+                reader->setOffset(offsetToRestore);
+            }
+        } break;
+        case CLIP_REGION: {
+            SkRegion region;
+            reader->readRegion(&region);
+            uint32_t packed = reader->readInt();
+            SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
+            size_t offsetToRestore = reader->readInt();
+            SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
+            canvas->clipRegion(region, regionOp);
+            if (canvas->isClipEmpty() && offsetToRestore) {
+                reader->setOffset(offsetToRestore);
+            }
+        } break;
+        case CLIP_RECT: {
+            const SkRect& rect = reader->skipT<SkRect>();
+            uint32_t packed = reader->readInt();
+            SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
+            bool doAA = ClipParams_unpackDoAA(packed);
+            size_t offsetToRestore = reader->readInt();
+            SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
+            canvas->clipRect(rect, regionOp, doAA);
+            if (canvas->isClipEmpty() && offsetToRestore) {
+                reader->setOffset(offsetToRestore);
+            }
+        } break;
+        case CLIP_RRECT: {
+            SkRRect rrect;
+            reader->readRRect(&rrect);
+            uint32_t packed = reader->readInt();
+            SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
+            bool doAA = ClipParams_unpackDoAA(packed);
+            size_t offsetToRestore = reader->readInt();
+            SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
+            canvas->clipRRect(rrect, regionOp, doAA);
+            if (canvas->isClipEmpty() && offsetToRestore) {
+                reader->setOffset(offsetToRestore);
+            }
+        } break;
+        case PUSH_CULL: {
+            const SkRect& cullRect = reader->skipT<SkRect>();
+            size_t offsetToRestore = reader->readInt();
+            if (offsetToRestore && canvas->quickReject(cullRect)) {
+                reader->setOffset(offsetToRestore);
             } else {
-                *reason = "Too many non dashed path effects.";
+                canvas->pushCull(cullRect);
             }
-        } else if ((fContentInfo.numAAConcavePaths() - fContentInfo.numAAHairlineConcavePaths()) 
-                    >= kNumAAConcavePaths)
-            *reason = "Too many anti-aliased concave paths.";
-        else
-            *reason = "Unknown reason for GPU unsuitability.";
-    }
-    return ret;
-}
-
-bool SkPicturePlayback::suitableForGpuRasterization(GrContext* context, const char **reason,
-                                                    GrPixelConfig config, SkScalar dpi) const {
-
-    if (context != NULL) {
-        return this->suitableForGpuRasterization(context, reason,
-                                                 context->getRecommendedSampleCount(config, dpi));
-    } else {
-        return this->suitableForGpuRasterization(NULL, reason);
-    }
-}
-
-#endif
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG_SIZE
-int SkPicturePlayback::size(size_t* sizePtr) {
-    int objects = bitmaps(sizePtr);
-    objects += paints(sizePtr);
-    objects += paths(sizePtr);
-    objects += pictures(sizePtr);
-    objects += regions(sizePtr);
-    *sizePtr = fOpData.size();
-    return objects;
-}
-
-int SkPicturePlayback::bitmaps(size_t* size) {
-    size_t result = 0;
-    for (int index = 0; index < fBitmapCount; index++) {
-     //   const SkBitmap& bitmap = fBitmaps[index];
-        result += sizeof(SkBitmap); // bitmap->size();
-    }
-    *size = result;
-    return fBitmapCount;
-}
-
-int SkPicturePlayback::paints(size_t* size) {
-    size_t result = 0;
-    for (int index = 0; index < fPaintCount; index++) {
-    //    const SkPaint& paint = fPaints[index];
-        result += sizeof(SkPaint); // paint->size();
-    }
-    *size = result;
-    return fPaintCount;
-}
-
-int SkPicturePlayback::paths(size_t* size) {
-    size_t result = 0;
-    for (int index = 0; index < fPathCount; index++) {
-        const SkPath& path = fPaths[index];
-        result += path.flatten(NULL);
-    }
-    *size = result;
-    return fPathCount;
-}
-#endif
-
-#ifdef SK_DEBUG_DUMP
-void SkPicturePlayback::dumpBitmap(const SkBitmap& bitmap) const {
-    char pBuffer[DUMP_BUFFER_SIZE];
-    char* bufferPtr = pBuffer;
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-        "BitmapData bitmap%p = {", &bitmap);
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-        "{kWidth, %d}, ", bitmap.width());
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-        "{kHeight, %d}, ", bitmap.height());
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-        "{kRowBytes, %d}, ", bitmap.rowBytes());
-//        start here;
-    SkDebugf("%s{0}};\n", pBuffer);
-}
-
-void dumpMatrix(const SkMatrix& matrix) const {
-    SkMatrix defaultMatrix;
-    defaultMatrix.reset();
-    char pBuffer[DUMP_BUFFER_SIZE];
-    char* bufferPtr = pBuffer;
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-        "MatrixData matrix%p = {", &matrix);
-    SkScalar scaleX = matrix.getScaleX();
-    if (scaleX != defaultMatrix.getScaleX())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kScaleX, %g}, ", SkScalarToFloat(scaleX));
-    SkScalar scaleY = matrix.getScaleY();
-    if (scaleY != defaultMatrix.getScaleY())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kScaleY, %g}, ", SkScalarToFloat(scaleY));
-    SkScalar skewX = matrix.getSkewX();
-    if (skewX != defaultMatrix.getSkewX())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kSkewX, %g}, ", SkScalarToFloat(skewX));
-    SkScalar skewY = matrix.getSkewY();
-    if (skewY != defaultMatrix.getSkewY())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kSkewY, %g}, ", SkScalarToFloat(skewY));
-    SkScalar translateX = matrix.getTranslateX();
-    if (translateX != defaultMatrix.getTranslateX())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kTranslateX, %g}, ", SkScalarToFloat(translateX));
-    SkScalar translateY = matrix.getTranslateY();
-    if (translateY != defaultMatrix.getTranslateY())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kTranslateY, %g}, ", SkScalarToFloat(translateY));
-    SkScalar perspX = matrix.getPerspX();
-    if (perspX != defaultMatrix.getPerspX())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kPerspX, %g}, ", perspX);
-    SkScalar perspY = matrix.getPerspY();
-    if (perspY != defaultMatrix.getPerspY())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kPerspY, %g}, ", perspY);
-    SkDebugf("%s{0}};\n", pBuffer);
-}
-
-void dumpPaint(const SkPaint& paint) const {
-    SkPaint defaultPaint;
-    char pBuffer[DUMP_BUFFER_SIZE];
-    char* bufferPtr = pBuffer;
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-        "PaintPointers paintPtrs%p = {", &paint);
-    const SkTypeface* typeface = paint.getTypeface();
-    if (typeface != defaultPaint.getTypeface())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kTypeface, %p}, ", typeface);
-    const SkPathEffect* pathEffect = paint.getPathEffect();
-    if (pathEffect != defaultPaint.getPathEffect())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kPathEffect, %p}, ", pathEffect);
-    const SkShader* shader = paint.getShader();
-    if (shader != defaultPaint.getShader())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kShader, %p}, ", shader);
-    const SkXfermode* xfermode = paint.getXfermode();
-    if (xfermode != defaultPaint.getXfermode())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kXfermode, %p}, ", xfermode);
-    const SkMaskFilter* maskFilter = paint.getMaskFilter();
-    if (maskFilter != defaultPaint.getMaskFilter())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kMaskFilter, %p}, ", maskFilter);
-    const SkColorFilter* colorFilter = paint.getColorFilter();
-    if (colorFilter != defaultPaint.getColorFilter())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kColorFilter, %p}, ", colorFilter);
-    const SkRasterizer* rasterizer = paint.getRasterizer();
-    if (rasterizer != defaultPaint.getRasterizer())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kRasterizer, %p}, ", rasterizer);
-    const SkDrawLooper* drawLooper = paint.getLooper();
-    if (drawLooper != defaultPaint.getLooper())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kDrawLooper, %p}, ", drawLooper);
-    SkDebugf("%s{0}};\n", pBuffer);
-    bufferPtr = pBuffer;
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-        "PaintScalars paintScalars%p = {", &paint);
-    SkScalar textSize = paint.getTextSize();
-    if (textSize != defaultPaint.getTextSize())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kTextSize, %g}, ", SkScalarToFloat(textSize));
-    SkScalar textScaleX = paint.getTextScaleX();
-    if (textScaleX != defaultPaint.getTextScaleX())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kTextScaleX, %g}, ", SkScalarToFloat(textScaleX));
-    SkScalar textSkewX = paint.getTextSkewX();
-    if (textSkewX != defaultPaint.getTextSkewX())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kTextSkewX, %g}, ", SkScalarToFloat(textSkewX));
-    SkScalar strokeWidth = paint.getStrokeWidth();
-    if (strokeWidth != defaultPaint.getStrokeWidth())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kStrokeWidth, %g}, ", SkScalarToFloat(strokeWidth));
-    SkScalar strokeMiter = paint.getStrokeMiter();
-    if (strokeMiter != defaultPaint.getStrokeMiter())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kStrokeMiter, %g}, ", SkScalarToFloat(strokeMiter));
-    SkDebugf("%s{0}};\n", pBuffer);
-    bufferPtr = pBuffer;
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-        "PaintInts = paintInts%p = {", &paint);
-    unsigned color = paint.getColor();
-    if (color != defaultPaint.getColor())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kColor, 0x%x}, ", color);
-    unsigned flags = paint.getFlags();
-    if (flags != defaultPaint.getFlags())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kFlags, 0x%x}, ", flags);
-    int align = paint.getTextAlign();
-    if (align != defaultPaint.getTextAlign())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kAlign, 0x%x}, ", align);
-    int strokeCap = paint.getStrokeCap();
-    if (strokeCap != defaultPaint.getStrokeCap())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kStrokeCap, 0x%x}, ", strokeCap);
-    int strokeJoin = paint.getStrokeJoin();
-    if (strokeJoin != defaultPaint.getStrokeJoin())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kAlign, 0x%x}, ", strokeJoin);
-    int style = paint.getStyle();
-    if (style != defaultPaint.getStyle())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kStyle, 0x%x}, ", style);
-    int textEncoding = paint.getTextEncoding();
-    if (textEncoding != defaultPaint.getTextEncoding())
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "{kTextEncoding, 0x%x}, ", textEncoding);
-    SkDebugf("%s{0}};\n", pBuffer);
-
-    SkDebugf("PaintData paint%p = {paintPtrs%p, paintScalars%p, paintInts%p};\n",
-        &paint, &paint, &paint, &paint);
-}
-
-void SkPicturePlayback::dumpPath(const SkPath& path) const {
-    SkDebugf("path dump unimplemented\n");
-}
-
-void SkPicturePlayback::dumpPicture(const SkPicture& picture) const {
-    SkDebugf("picture dump unimplemented\n");
-}
-
-void SkPicturePlayback::dumpRegion(const SkRegion& region) const {
-    SkDebugf("region dump unimplemented\n");
-}
-
-int SkPicturePlayback::dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType) {
-    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-        "k%s, ", DrawTypeToString(drawType));
-}
-
-int SkPicturePlayback::dumpInt(char* bufferPtr, char* buffer, char* name) {
-    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-        "%s:%d, ", name, getInt());
-}
-
-int SkPicturePlayback::dumpRect(char* bufferPtr, char* buffer, char* name) {
-    const SkRect* rect = fReader.skipRect();
-    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-        "%s:{l:%g t:%g r:%g b:%g}, ", name, SkScalarToFloat(rect.fLeft),
-        SkScalarToFloat(rect.fTop),
-        SkScalarToFloat(rect.fRight), SkScalarToFloat(rect.fBottom));
-}
-
-int SkPicturePlayback::dumpPoint(char* bufferPtr, char* buffer, char* name) {
-    SkPoint pt;
-    getPoint(&pt);
-    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-        "%s:{x:%g y:%g}, ", name, SkScalarToFloat(pt.fX),
-        SkScalarToFloat(pt.fY));
-}
-
-void SkPicturePlayback::dumpPointArray(char** bufferPtrPtr, char* buffer, int count) {
-    char* bufferPtr = *bufferPtrPtr;
-    const SkPoint* pts = (const SkPoint*)fReadStream.getAtPos();
-    fReadStream.skip(sizeof(SkPoint) * count);
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-        "count:%d {", count);
-    for (int index = 0; index < count; index++)
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-        "{x:%g y:%g}, ", SkScalarToFloat(pts[index].fX),
-        SkScalarToFloat(pts[index].fY));
-    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-        "} ");
-    *bufferPtrPtr = bufferPtr;
-}
-
-int SkPicturePlayback::dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr) {
-    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-        "%s:%p, ", name, ptr);
-}
-
-int SkPicturePlayback::dumpRectPtr(char* bufferPtr, char* buffer, char* name) {
-    char result;
-    fReadStream.read(&result, sizeof(result));
-    if (result)
-        return dumpRect(bufferPtr, buffer, name);
-    else
-        return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-            "%s:NULL, ", name);
-}
-
-int SkPicturePlayback::dumpScalar(char* bufferPtr, char* buffer, char* name) {
-    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
-        "%s:%d, ", name, getScalar());
-}
-
-void SkPicturePlayback::dumpText(char** bufferPtrPtr, char* buffer) {
-    char* bufferPtr = *bufferPtrPtr;
-    int length = getInt();
-    bufferPtr += dumpDrawType(bufferPtr, buffer);
-    fReadStream.skipToAlign4();
-    char* text = (char*) fReadStream.getAtPos();
-    fReadStream.skip(length);
-    bufferPtr += dumpInt(bufferPtr, buffer, "length");
-    int limit = DUMP_BUFFER_SIZE - (bufferPtr - buffer) - 2;
-    length >>= 1;
-    if (limit > length)
-        limit = length;
-    if (limit > 0) {
-        *bufferPtr++ = '"';
-        for (int index = 0; index < limit; index++) {
-            *bufferPtr++ = *(unsigned short*) text;
-            text += sizeof(unsigned short);
+        } break;
+        case POP_CULL:
+            canvas->popCull();
+            break;
+        case CONCAT: {
+            SkMatrix matrix;
+            reader->readMatrix(&matrix);
+            canvas->concat(matrix);
+            break;
         }
-        *bufferPtr++ = '"';
-    }
-    *bufferPtrPtr = bufferPtr;
-}
+        case DRAW_BITMAP: {
+            const SkPaint* paint = fPictureData->getPaint(reader);
+            const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader));
+            const SkPoint& loc = reader->skipT<SkPoint>();
+            canvas->drawBitmap(bitmap, loc.fX, loc.fY, paint);
+        } break;
+        case DRAW_BITMAP_RECT_TO_RECT: {
+            const SkPaint* paint = fPictureData->getPaint(reader);
+            const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader));
+            const SkRect* src = get_rect_ptr(reader);   // may be null
+            const SkRect& dst = reader->skipT<SkRect>();     // required
+            SkCanvas::DrawBitmapRectFlags flags;
+            flags = (SkCanvas::DrawBitmapRectFlags) reader->readInt();
+            canvas->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
+        } break;
+        case DRAW_BITMAP_MATRIX: {
+            const SkPaint* paint = fPictureData->getPaint(reader);
+            const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader));
+            SkMatrix matrix;
+            reader->readMatrix(&matrix);
+            canvas->drawBitmapMatrix(bitmap, matrix, paint);
+        } break;
+        case DRAW_BITMAP_NINE: {
+            const SkPaint* paint = fPictureData->getPaint(reader);
+            const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader));
+            const SkIRect& src = reader->skipT<SkIRect>();
+            const SkRect& dst = reader->skipT<SkRect>();
+            canvas->drawBitmapNine(bitmap, src, dst, paint);
+        } break;
+        case DRAW_CLEAR:
+            canvas->clear(reader->readInt());
+            break;
+        case DRAW_DATA: {
+            size_t length = reader->readInt();
+            canvas->drawData(reader->skip(length), length);
+            // skip handles padding the read out to a multiple of 4
+        } break;
+        case DRAW_DRRECT: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            SkRRect outer, inner;
+            reader->readRRect(&outer);
+            reader->readRRect(&inner);
+            canvas->drawDRRect(outer, inner, paint);
+        } break;
+        case BEGIN_COMMENT_GROUP: {
+            const char* desc = reader->readString();
+            canvas->beginCommentGroup(desc);
+        } break;
+        case COMMENT: {
+            const char* kywd = reader->readString();
+            const char* value = reader->readString();
+            canvas->addComment(kywd, value);
+        } break;
+        case END_COMMENT_GROUP: {
+            canvas->endCommentGroup();
+        } break;
+        case DRAW_OVAL: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            canvas->drawOval(reader->skipT<SkRect>(), paint);
+        } break;
+        case DRAW_PAINT:
+            canvas->drawPaint(*fPictureData->getPaint(reader));
+            break;
+        case DRAW_PATCH: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
 
-#define DUMP_DRAWTYPE(drawType) \
-    bufferPtr += dumpDrawType(bufferPtr, buffer, drawType)
-
-#define DUMP_INT(name) \
-    bufferPtr += dumpInt(bufferPtr, buffer, #name)
-
-#define DUMP_RECT_PTR(name) \
-    bufferPtr += dumpRectPtr(bufferPtr, buffer, #name)
-
-#define DUMP_POINT(name) \
-    bufferPtr += dumpRect(bufferPtr, buffer, #name)
-
-#define DUMP_RECT(name) \
-    bufferPtr += dumpRect(bufferPtr, buffer, #name)
-
-#define DUMP_POINT_ARRAY(count) \
-    dumpPointArray(&bufferPtr, buffer, count)
-
-#define DUMP_PTR(name, ptr) \
-    bufferPtr += dumpPtr(bufferPtr, buffer, #name, (void*) ptr)
-
-#define DUMP_SCALAR(name) \
-    bufferPtr += dumpScalar(bufferPtr, buffer, #name)
-
-#define DUMP_TEXT() \
-    dumpText(&bufferPtr, buffer)
-
-void SkPicturePlayback::dumpStream() {
-    SkDebugf("RecordStream stream = {\n");
-    DrawType drawType;
-    TextContainer text;
-    fReadStream.rewind();
-    char buffer[DUMP_BUFFER_SIZE], * bufferPtr;
-    while (fReadStream.read(&drawType, sizeof(drawType))) {
-        bufferPtr = buffer;
-        DUMP_DRAWTYPE(drawType);
-        switch (drawType) {
-            case CLIP_PATH: {
-                DUMP_PTR(SkPath, &getPath());
-                DUMP_INT(SkRegion::Op);
-                DUMP_INT(offsetToRestore);
-                } break;
-            case CLIP_REGION: {
-                DUMP_INT(SkRegion::Op);
-                DUMP_INT(offsetToRestore);
-            } break;
-            case CLIP_RECT: {
-                DUMP_RECT(rect);
-                DUMP_INT(SkRegion::Op);
-                DUMP_INT(offsetToRestore);
-                } break;
-            case CONCAT:
-                break;
-            case DRAW_BITMAP: {
-                DUMP_PTR(SkPaint, getPaint());
-                DUMP_PTR(SkBitmap, &getBitmap());
-                DUMP_SCALAR(left);
-                DUMP_SCALAR(top);
-                } break;
-            case DRAW_PAINT:
-                DUMP_PTR(SkPaint, getPaint());
-                break;
-            case DRAW_PATH: {
-                DUMP_PTR(SkPaint, getPaint());
-                DUMP_PTR(SkPath, &getPath());
-                } break;
-            case DRAW_PICTURE: {
-                DUMP_PTR(SkPicture, &getPicture());
-                } break;
-            case DRAW_POINTS: {
-                DUMP_PTR(SkPaint, getPaint());
-                (void)getInt(); // PointMode
-                size_t count = getInt();
-                fReadStream.skipToAlign4();
-                DUMP_POINT_ARRAY(count);
-                } break;
-            case DRAW_POS_TEXT: {
-                DUMP_PTR(SkPaint, getPaint());
-                DUMP_TEXT();
-                size_t points = getInt();
-                fReadStream.skipToAlign4();
-                DUMP_POINT_ARRAY(points);
-                } break;
-            case DRAW_POS_TEXT_H: {
-                DUMP_PTR(SkPaint, getPaint());
-                DUMP_TEXT();
-                size_t points = getInt();
-                fReadStream.skipToAlign4();
-                DUMP_SCALAR(top);
-                DUMP_SCALAR(bottom);
-                DUMP_SCALAR(constY);
-                DUMP_POINT_ARRAY(points);
-                } break;
-            case DRAW_RECT: {
-                DUMP_PTR(SkPaint, getPaint());
-                DUMP_RECT(rect);
-                } break;
-            case DRAW_SPRITE: {
-                DUMP_PTR(SkPaint, getPaint());
-                DUMP_PTR(SkBitmap, &getBitmap());
-                DUMP_SCALAR(left);
-                DUMP_SCALAR(top);
-                } break;
-            case DRAW_TEXT: {
-                DUMP_PTR(SkPaint, getPaint());
-                DUMP_TEXT();
-                DUMP_SCALAR(x);
-                DUMP_SCALAR(y);
-                } break;
-            case DRAW_TEXT_ON_PATH: {
-                DUMP_PTR(SkPaint, getPaint());
-                DUMP_TEXT();
-                DUMP_PTR(SkPath, &getPath());
-                } break;
-            case RESTORE:
-                break;
-            case ROTATE:
-                DUMP_SCALAR(rotate);
-                break;
-            case SAVE:
-                DUMP_INT(SkCanvas::SaveFlags);
-                break;
-            case SAVE_LAYER: {
-                DUMP_RECT_PTR(layer);
-                DUMP_PTR(SkPaint, getPaint());
-                DUMP_INT(SkCanvas::SaveFlags);
-                } break;
-            case SCALE: {
-                DUMP_SCALAR(sx);
-                DUMP_SCALAR(sy);
-                } break;
-            case SKEW: {
-                DUMP_SCALAR(sx);
-                DUMP_SCALAR(sy);
-                } break;
-            case TRANSLATE: {
-                DUMP_SCALAR(dx);
-                DUMP_SCALAR(dy);
-                } break;
-            default:
-                SkASSERT(0);
-        }
-        SkDebugf("%s\n", buffer);
+            const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts *
+                                                                 sizeof(SkPoint));
+            uint32_t flag = reader->readInt();
+            const SkColor* colors = NULL;
+            if (flag & DRAW_VERTICES_HAS_COLORS) {
+                colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners * sizeof(SkColor));
+            }
+            const SkPoint* texCoords = NULL;
+            if (flag & DRAW_VERTICES_HAS_TEXS) {
+                texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners *
+                                                         sizeof(SkPoint));
+            }
+            SkAutoTUnref<SkXfermode> xfer;
+            if (flag & DRAW_VERTICES_HAS_XFER) {
+                int mode = reader->readInt();
+                if (mode < 0 || mode > SkXfermode::kLastMode) {
+                    mode = SkXfermode::kModulate_Mode;
+                }
+                xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode));
+            }
+            canvas->drawPatch(cubics, colors, texCoords, xfer, paint);
+        } break;
+        case DRAW_PATH: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            canvas->drawPath(fPictureData->getPath(reader), paint);
+        } break;
+        case DRAW_PICTURE:
+            canvas->drawPicture(fPictureData->getPicture(reader));
+            break;
+        case DRAW_PICTURE_MATRIX_PAINT: {
+            const SkPaint* paint = fPictureData->getPaint(reader);
+            SkMatrix matrix;
+            reader->readMatrix(&matrix);
+            const SkPicture* pic = fPictureData->getPicture(reader);
+            canvas->drawPicture(pic, &matrix, paint);
+        } break;
+        case DRAW_POINTS: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            SkCanvas::PointMode mode = (SkCanvas::PointMode)reader->readInt();
+            size_t count = reader->readInt();
+            const SkPoint* pts = (const SkPoint*)reader->skip(sizeof(SkPoint)* count);
+            canvas->drawPoints(mode, count, pts, paint);
+        } break;
+        case DRAW_POS_TEXT: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            TextContainer text;
+            get_text(reader, &text);
+            size_t points = reader->readInt();
+            const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint));
+            canvas->drawPosText(text.text(), text.length(), pos, paint);
+        } break;
+        case DRAW_POS_TEXT_TOP_BOTTOM: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            TextContainer text;
+            get_text(reader, &text);
+            size_t points = reader->readInt();
+            const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint));
+            const SkScalar top = reader->readScalar();
+            const SkScalar bottom = reader->readScalar();
+            if (!canvas->quickRejectY(top, bottom)) {
+                canvas->drawPosText(text.text(), text.length(), pos, paint);
+            }
+        } break;
+        case DRAW_POS_TEXT_H: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            TextContainer text;
+            get_text(reader, &text);
+            size_t xCount = reader->readInt();
+            const SkScalar constY = reader->readScalar();
+            const SkScalar* xpos = (const SkScalar*)reader->skip(xCount * sizeof(SkScalar));
+            canvas->drawPosTextH(text.text(), text.length(), xpos, constY, paint);
+        } break;
+        case DRAW_POS_TEXT_H_TOP_BOTTOM: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            TextContainer text;
+            get_text(reader, &text);
+            size_t xCount = reader->readInt();
+            const SkScalar* xpos = (const SkScalar*)reader->skip((3 + xCount) * sizeof(SkScalar));
+            const SkScalar top = *xpos++;
+            const SkScalar bottom = *xpos++;
+            const SkScalar constY = *xpos++;
+            if (!canvas->quickRejectY(top, bottom)) {
+                canvas->drawPosTextH(text.text(), text.length(), xpos, constY, paint);
+            }
+        } break;
+        case DRAW_RECT: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            canvas->drawRect(reader->skipT<SkRect>(), paint);
+        } break;
+        case DRAW_RRECT: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            SkRRect rrect;
+            reader->readRRect(&rrect);
+            canvas->drawRRect(rrect, paint);
+        } break;
+        case DRAW_SPRITE: {
+            const SkPaint* paint = fPictureData->getPaint(reader);
+            const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader));
+            int left = reader->readInt();
+            int top = reader->readInt();
+            canvas->drawSprite(bitmap, left, top, paint);
+        } break;
+        case DRAW_TEXT: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            TextContainer text;
+            get_text(reader, &text);
+            SkScalar x = reader->readScalar();
+            SkScalar y = reader->readScalar();
+            canvas->drawText(text.text(), text.length(), x, y, paint);
+        } break;
+        case DRAW_TEXT_BLOB: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            const SkTextBlob* blob = fPictureData->getTextBlob(reader);
+            SkScalar x = reader->readScalar();
+            SkScalar y = reader->readScalar();
+            canvas->drawTextBlob(blob, x, y, paint);
+        } break;
+        case DRAW_TEXT_TOP_BOTTOM: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            TextContainer text;
+            get_text(reader, &text);
+            const SkScalar* ptr = (const SkScalar*)reader->skip(4 * sizeof(SkScalar));
+            // ptr[0] == x
+            // ptr[1] == y
+            // ptr[2] == top
+            // ptr[3] == bottom
+            if (!canvas->quickRejectY(ptr[2], ptr[3])) {
+                canvas->drawText(text.text(), text.length(), ptr[0], ptr[1], paint);
+            }
+        } break;
+        case DRAW_TEXT_ON_PATH: {
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            TextContainer text;
+            get_text(reader, &text);
+            const SkPath& path = fPictureData->getPath(reader);
+            SkMatrix matrix;
+            reader->readMatrix(&matrix);
+            canvas->drawTextOnPath(text.text(), text.length(), path, &matrix, paint);
+        } break;
+        case DRAW_VERTICES: {
+            SkAutoTUnref<SkXfermode> xfer;
+            const SkPaint& paint = *fPictureData->getPaint(reader);
+            DrawVertexFlags flags = (DrawVertexFlags)reader->readInt();
+            SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader->readInt();
+            int vCount = reader->readInt();
+            const SkPoint* verts = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint));
+            const SkPoint* texs = NULL;
+            const SkColor* colors = NULL;
+            const uint16_t* indices = NULL;
+            int iCount = 0;
+            if (flags & DRAW_VERTICES_HAS_TEXS) {
+                texs = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint));
+            }
+            if (flags & DRAW_VERTICES_HAS_COLORS) {
+                colors = (const SkColor*)reader->skip(vCount * sizeof(SkColor));
+            }
+            if (flags & DRAW_VERTICES_HAS_INDICES) {
+                iCount = reader->readInt();
+                indices = (const uint16_t*)reader->skip(iCount * sizeof(uint16_t));
+            }
+            if (flags & DRAW_VERTICES_HAS_XFER) {
+                int mode = reader->readInt();
+                if (mode < 0 || mode > SkXfermode::kLastMode) {
+                    mode = SkXfermode::kModulate_Mode;
+                }
+                xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode));
+            }
+            canvas->drawVertices(vmode, vCount, verts, texs, colors, xfer, indices, iCount, paint);
+        } break;
+        case RESTORE:
+            canvas->restore();
+            break;
+        case ROTATE:
+            canvas->rotate(reader->readScalar());
+            break;
+        case SAVE:
+            // SKPs with version < 29 also store a SaveFlags param.
+            if (size > 4) {
+                SkASSERT(8 == size);
+                reader->readInt();
+            }
+            canvas->save();
+            break;
+        case SAVE_LAYER: {
+            const SkRect* boundsPtr = get_rect_ptr(reader);
+            const SkPaint* paint = fPictureData->getPaint(reader);
+            canvas->saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) reader->readInt());
+        } break;
+        case SCALE: {
+            SkScalar sx = reader->readScalar();
+            SkScalar sy = reader->readScalar();
+            canvas->scale(sx, sy);
+        } break;
+        case SET_MATRIX: {
+            SkMatrix matrix;
+            reader->readMatrix(&matrix);
+            matrix.postConcat(initialMatrix);
+            canvas->setMatrix(matrix);
+        } break;
+        case SKEW: {
+            SkScalar sx = reader->readScalar();
+            SkScalar sy = reader->readScalar();
+            canvas->skew(sx, sy);
+        } break;
+        case TRANSLATE: {
+            SkScalar dx = reader->readScalar();
+            SkScalar dy = reader->readScalar();
+            canvas->translate(dx, dy);
+        } break;
+        default:
+            SkASSERT(0);
     }
 }
 
-void SkPicturePlayback::dump() const {
-    char pBuffer[DUMP_BUFFER_SIZE];
-    char* bufferPtr = pBuffer;
-    int index;
-    if (fBitmapCount > 0)
-        SkDebugf("// bitmaps (%d)\n", fBitmapCount);
-    for (index = 0; index < fBitmapCount; index++) {
-        const SkBitmap& bitmap = fBitmaps[index];
-        dumpBitmap(bitmap);
-    }
-    if (fBitmapCount > 0)
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "Bitmaps bitmaps = {");
-    for (index = 0; index < fBitmapCount; index++)
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "bitmap%p, ", &fBitmaps[index]);
-    if (fBitmapCount > 0)
-        SkDebugf("%s0};\n", pBuffer);
-
-
-    if (fPaintCount > 0)
-        SkDebugf("// paints (%d)\n", fPaintCount);
-    for (index = 0; index < fPaintCount; index++) {
-        const SkPaint& paint = fPaints[index];
-        dumpPaint(paint);
-    }
-    bufferPtr = pBuffer;
-    if (fPaintCount > 0)
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "Paints paints = {");
-    for (index = 0; index < fPaintCount; index++)
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "paint%p, ", &fPaints[index]);
-    if (fPaintCount > 0)
-        SkDebugf("%s0};\n", pBuffer);
-
-    for (index = 0; index < fPathCount; index++) {
-        const SkPath& path = fPaths[index];
-        dumpPath(path);
-    }
-    bufferPtr = pBuffer;
-    if (fPathCount > 0)
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "Paths paths = {");
-    for (index = 0; index < fPathCount; index++)
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "path%p, ", &fPaths[index]);
-    if (fPathCount > 0)
-        SkDebugf("%s0};\n", pBuffer);
-
-    for (index = 0; index < fPictureCount; index++) {
-        dumpPicture(*fPictureRefs[index]);
-    }
-    bufferPtr = pBuffer;
-    if (fPictureCount > 0)
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "Pictures pictures = {");
-    for (index = 0; index < fPictureCount; index++)
-        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
-            "picture%p, ", fPictureRefs[index]);
-    if (fPictureCount > 0)
-        SkDebugf("%s0};\n", pBuffer);
-
-    const_cast<SkPicturePlayback*>(this)->dumpStream();
-}
-
-#endif
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index 3cdd9af..cdfa8ef 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -1,6 +1,5 @@
-
 /*
- * Copyright 2011 Google Inc.
+ * Copyright 2014 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
@@ -9,421 +8,77 @@
 #ifndef SkPicturePlayback_DEFINED
 #define SkPicturePlayback_DEFINED
 
-#include "SkBitmap.h"
-#include "SkPathHeap.h"
-#include "SkPicture.h"
-#include "SkPictureFlat.h"
+#include "SkPictureFlat.h"  // for DrawType
+#include "SkPictureStateTree.h"
 
-#ifdef SK_BUILD_FOR_ANDROID
-#include "SkThread.h"
-#endif
-
-class SkData;
-class SkPictureRecord;
-class SkReader32;
-class SkStream;
-class SkWStream;
-class SkBBoxHierarchy;
-class SkMatrix;
+class SkBitmap;
+class SkCanvas;
+class SkDrawPictureCallback;
 class SkPaint;
-class SkPath;
-class SkPictureStateTree;
-class SkReadBuffer;
-class SkRegion;
+class SkPictureData;
 
-struct SkPictInfo {
-    enum Flags {
-        kCrossProcess_Flag      = 1 << 0,
-        kScalarIsFloat_Flag     = 1 << 1,
-        kPtrIs64Bit_Flag        = 1 << 2,
-    };
-
-    char        fMagic[8];
-    uint32_t    fVersion;
-    uint32_t    fWidth;
-    uint32_t    fHeight;
-    uint32_t    fFlags;
-};
-
-#define SK_PICT_READER_TAG     SkSetFourByteTag('r', 'e', 'a', 'd')
-#define SK_PICT_FACTORY_TAG    SkSetFourByteTag('f', 'a', 'c', 't')
-#define SK_PICT_TYPEFACE_TAG   SkSetFourByteTag('t', 'p', 'f', 'c')
-#define SK_PICT_PICTURE_TAG    SkSetFourByteTag('p', 'c', 't', 'r')
-
-// This tag specifies the size of the ReadBuffer, needed for the following tags
-#define SK_PICT_BUFFER_SIZE_TAG     SkSetFourByteTag('a', 'r', 'a', 'y')
-// these are all inside the ARRAYS tag
-#define SK_PICT_BITMAP_BUFFER_TAG  SkSetFourByteTag('b', 't', 'm', 'p')
-#define SK_PICT_PAINT_BUFFER_TAG   SkSetFourByteTag('p', 'n', 't', ' ')
-#define SK_PICT_PATH_BUFFER_TAG    SkSetFourByteTag('p', 't', 'h', ' ')
-
-// Always write this guy last (with no length field afterwards)
-#define SK_PICT_EOF_TAG     SkSetFourByteTag('e', 'o', 'f', ' ')
-
-// SkPictureContentInfo is not serialized! It is intended solely for use
-// with suitableForGpuRasterization.
-class SkPictureContentInfo {
+// The basic picture playback class replays the provided picture into a canvas.
+// If the picture was generated with a BBH it is used to accelerate drawing
+// unless disabled via setUseBBH.
+class SkPicturePlayback : SkNoncopyable {
 public:
-    SkPictureContentInfo() { this->reset(); }
-
-    SkPictureContentInfo(const SkPictureContentInfo& src) { this->set(src); }
-
-    void set(const SkPictureContentInfo& src) {
-        fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses;
-        fNumFastPathDashEffects = src.fNumFastPathDashEffects;
-        fNumAAConcavePaths = src.fNumAAConcavePaths;
-        fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths;
+    SkPicturePlayback(const SkPicture* picture)
+        : fPictureData(picture->fData.get())
+        , fCurOffset(0)
+        , fUseBBH(true) {
     }
+    virtual ~SkPicturePlayback() { }
 
-    void reset() {
-        fNumPaintWithPathEffectUses = 0;
-        fNumFastPathDashEffects = 0;
-        fNumAAConcavePaths = 0;
-        fNumAAHairlineConcavePaths = 0;
-    }
+    virtual void draw(SkCanvas* canvas, SkDrawPictureCallback*);
 
-    void swap(SkPictureContentInfo* other) {
-        SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses);
-        SkTSwap(fNumFastPathDashEffects, other->fNumFastPathDashEffects);
-        SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths);
-        SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths);
-    }
-
-    void incPaintWithPathEffectUses() { ++fNumPaintWithPathEffectUses; }
-    int numPaintWithPathEffectUses() const { return fNumPaintWithPathEffectUses; }
-
-    void incFastPathDashEffects() { ++fNumFastPathDashEffects; }
-    int numFastPathDashEffects() const { return fNumFastPathDashEffects; }
-
-    void incAAConcavePaths() { ++fNumAAConcavePaths; }
-    int numAAConcavePaths() const { return fNumAAConcavePaths; }
-
-    void incAAHairlineConcavePaths() {
-        ++fNumAAHairlineConcavePaths;
-        SkASSERT(fNumAAHairlineConcavePaths <= fNumAAConcavePaths);
-    }
-    int numAAHairlineConcavePaths() const { return fNumAAHairlineConcavePaths; }
-
-private:
-    // This field is incremented every time a paint with a path effect is
-    // used (i.e., it is not a de-duplicated count)
-    int fNumPaintWithPathEffectUses;
-    // This field is incremented every time a paint with a path effect that is
-    // dashed, we are drawing a line, and we can use the gpu fast path
-    int fNumFastPathDashEffects;
-    // This field is incremented every time an anti-aliased drawPath call is
-    // issued with a concave path
-    int fNumAAConcavePaths;
-    // This field is incremented every time a drawPath call is
-    // issued for a hairline stroked concave path.
-    int fNumAAHairlineConcavePaths;
-};
-
-/**
- * Container for data that is needed to deep copy a SkPicture. The container
- * enables the data to be generated once and reused for subsequent copies.
- */
-struct SkPictCopyInfo {
-    SkPictCopyInfo() : initialized(false), controller(1024) {}
-
-    bool initialized;
-    SkChunkFlatController controller;
-    SkTDArray<SkFlatData*> paintData;
-};
-
-class SkPicturePlayback {
-public:
-    SkPicturePlayback(const SkPicturePlayback& src,
-                      SkPictCopyInfo* deepCopyInfo = NULL);
-    SkPicturePlayback(const SkPictureRecord& record, const SkPictInfo&, bool deepCopyOps);
-    static SkPicturePlayback* CreateFromStream(SkStream*,
-                                               const SkPictInfo&,
-                                               SkPicture::InstallPixelRefProc);
-    static SkPicturePlayback* CreateFromBuffer(SkReadBuffer&,
-                                               const SkPictInfo&);
-
-    virtual ~SkPicturePlayback();
-
-    const SkPicture::OperationList& getActiveOps(const SkIRect& queryRect);
-
-    void setUseBBH(bool useBBH) { fUseBBH = useBBH; }
-
-    void draw(SkCanvas& canvas, SkDrawPictureCallback*);
-
-    void serialize(SkWStream*, SkPicture::EncodeBitmap) const;
-    void flatten(SkWriteBuffer&) const;
-
-    void dumpSize() const;
-
-    bool containsBitmaps() const;
-
-#ifdef SK_BUILD_FOR_ANDROID
-    // Can be called in the middle of playback (the draw() call). WIll abort the
-    // drawing and return from draw() after the "current" op code is done
-    void abort() { fAbortCurrentPlayback = true; }
-#endif
-
+    // TODO: remove the curOp calls after cleaning up GrGatherDevice
+    // Return the ID of the operation currently being executed when playing
+    // back. 0 indicates no call is active.
     size_t curOpID() const { return fCurOffset; }
     void resetOpID() { fCurOffset = 0; }
 
+    // TODO: remove setUseBBH after cleaning up GrGatherCanvas
+    void setUseBBH(bool useBBH) { fUseBBH = useBBH; }
+
 protected:
-    explicit SkPicturePlayback(const SkPictInfo& info);
-
-    bool parseStream(SkStream*, SkPicture::InstallPixelRefProc);
-    bool parseBuffer(SkReadBuffer& buffer);
-#ifdef SK_DEVELOPER
-    virtual bool preDraw(int opIndex, int type);
-    virtual void postDraw(int opIndex);
-#endif
-
-private:
-    class TextContainer {
-    public:
-        size_t length() { return fByteLength; }
-        const void* text() { return (const void*) fText; }
-        size_t fByteLength;
-        const char* fText;
-    };
-
-    const SkBitmap& getBitmap(SkReader32& reader) {
-        const int index = reader.readInt();
-        if (SkBitmapHeap::INVALID_SLOT == index) {
-#ifdef SK_DEBUG
-            SkDebugf("An invalid bitmap was recorded!\n");
-#endif
-            return fBadBitmap;
-        }
-        return (*fBitmaps)[index];
-    }
-
-    void getMatrix(SkReader32& reader, SkMatrix* matrix) {
-        reader.readMatrix(matrix);
-    }
-
-    const SkPath& getPath(SkReader32& reader) {
-        int index = reader.readInt() - 1;
-        return (*fPathHeap.get())[index];
-    }
-
-    const SkPicture* getPicture(SkReader32& reader) {
-        int index = reader.readInt();
-        SkASSERT(index > 0 && index <= fPictureCount);
-        return fPictureRefs[index - 1];
-    }
-
-    const SkPaint* getPaint(SkReader32& reader) {
-        int index = reader.readInt();
-        if (index == 0) {
-            return NULL;
-        }
-        return &(*fPaints)[index - 1];
-    }
-
-    const SkRect* getRectPtr(SkReader32& reader) {
-        if (reader.readBool()) {
-            return &reader.skipT<SkRect>();
-        } else {
-            return NULL;
-        }
-    }
-
-    const SkIRect* getIRectPtr(SkReader32& reader) {
-        if (reader.readBool()) {
-            return &reader.skipT<SkIRect>();
-        } else {
-            return NULL;
-        }
-    }
-
-    void getRegion(SkReader32& reader, SkRegion* region) {
-        reader.readRegion(region);
-    }
-
-    void getText(SkReader32& reader, TextContainer* text) {
-        size_t length = text->fByteLength = reader.readInt();
-        text->fText = (const char*)reader.skip(length);
-    }
-
-    void init();
-
-#ifdef SK_DEBUG_SIZE
-public:
-    int size(size_t* sizePtr);
-    int bitmaps(size_t* size);
-    int paints(size_t* size);
-    int paths(size_t* size);
-#endif
-
-#ifdef SK_DEBUG_DUMP
-private:
-    void dumpBitmap(const SkBitmap& bitmap) const;
-    void dumpMatrix(const SkMatrix& matrix) const;
-    void dumpPaint(const SkPaint& paint) const;
-    void dumpPath(const SkPath& path) const;
-    void dumpPicture(const SkPicture& picture) const;
-    void dumpRegion(const SkRegion& region) const;
-    int dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType);
-    int dumpInt(char* bufferPtr, char* buffer, char* name);
-    int dumpRect(char* bufferPtr, char* buffer, char* name);
-    int dumpPoint(char* bufferPtr, char* buffer, char* name);
-    void dumpPointArray(char** bufferPtrPtr, char* buffer, int count);
-    int dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr);
-    int dumpRectPtr(char* bufferPtr, char* buffer, char* name);
-    int dumpScalar(char* bufferPtr, char* buffer, char* name);
-    void dumpText(char** bufferPtrPtr, char* buffer);
-    void dumpStream();
-
-public:
-    void dump() const;
-#endif
-
-#if SK_SUPPORT_GPU
-    /**
-     * sampleCount is the number of samples-per-pixel or zero if non-MSAA.
-     * It is defaulted to be zero.
-     */
-    bool suitableForGpuRasterization(GrContext* context, const char **reason,
-                                     int sampleCount = 0) const;
-
-    /**
-     * Calls getRecommendedSampleCount with GrPixelConfig and dpi to calculate sampleCount
-     * and then calls the above version of suitableForGpuRasterization
-     */
-    bool suitableForGpuRasterization(GrContext* context, const char **reason,
-                                     GrPixelConfig config, SkScalar dpi) const;
-#endif
-
-private:    // these help us with reading/writing
-    bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size, SkPicture::InstallPixelRefProc);
-    bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
-    void flattenToBuffer(SkWriteBuffer&) const;
-
-private:
-    friend class SkPicture;
-    friend class SkGpuDevice;   // for access to setDrawLimits & setReplacements
-
-    // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty
-    // bitmap allows playback to draw nothing and move on.
-    SkBitmap fBadBitmap;
-
-    SkAutoTUnref<SkBitmapHeap> fBitmapHeap;
-
-    SkTRefArray<SkBitmap>* fBitmaps;
-    SkTRefArray<SkPaint>* fPaints;
-
-    SkData* fOpData;    // opcodes and parameters
-
-    SkAutoTUnref<const SkPathHeap> fPathHeap;  // reference counted
-
-    const SkPicture** fPictureRefs;
-    int fPictureCount;
-
-    SkBBoxHierarchy* fBoundingHierarchy;
-    SkPictureStateTree* fStateTree;
-
-    SkPictureContentInfo fContentInfo;
-
-    // Limit the opcode playback to be between the offsets 'start' and 'stop'.
-    // The opcode at 'start' should be a saveLayer while the opcode at
-    // 'stop' should be a restore. Neither of those commands will be issued.
-    // Set both start & stop to 0 to disable draw limiting
-    // Draw limiting cannot be enabled at the same time as draw replacing
-    void setDrawLimits(size_t start, size_t stop) {
-        SkASSERT(NULL == fReplacements);
-        fStart = start;
-        fStop = stop;
-    }
-
-    // PlaybackReplacements collects op ranges that can be replaced with
-    // a single drawBitmap call (using a precomputed bitmap).
-    class PlaybackReplacements {
-    public:
-        // All the operations between fStart and fStop (inclusive) will be replaced with
-        // a single drawBitmap call using fPos, fBM and fPaint.
-        // fPaint will be NULL if the picture's paint wasn't copyable
-        struct ReplacementInfo {
-            size_t          fStart;
-            size_t          fStop;
-            SkIPoint        fPos;
-            SkBitmap*       fBM;
-            const SkPaint*  fPaint;  // Note: this object doesn't own the paint
-        };
-
-        ~PlaybackReplacements() { this->freeAll(); }
-
-        // Add a new replacement range. The replacement ranges should be
-        // sorted in increasing order and non-overlapping (esp. no nested
-        // saveLayers).
-        ReplacementInfo* push();
-
-    private:
-        friend class SkPicturePlayback; // for access to lookupByStart
-
-        // look up a replacement range by its start offset
-        ReplacementInfo* lookupByStart(size_t start);
-
-        void freeAll();
-
-#ifdef SK_DEBUG
-        void validate() const;
-#endif
-
-        SkTDArray<ReplacementInfo> fReplacements;
-    };
-
-    // Replace all the draw ops in the replacement ranges in 'replacements' with
-    // the associated drawBitmap call
-    // Draw replacing cannot be enabled at the same time as draw limiting
-    void setReplacements(PlaybackReplacements* replacements) {
-        SkASSERT(fStart == 0 && fStop == 0);
-        fReplacements = replacements;
-    }
-
-    bool   fUseBBH;
-    size_t fStart;
-    size_t fStop;
-    PlaybackReplacements* fReplacements;
-
-    class CachedOperationList : public SkPicture::OperationList {
-    public:
-        CachedOperationList() {
-            fCacheQueryRect.setEmpty();
-        }
-
-        virtual bool valid() const { return true; }
-        virtual int numOps() const SK_OVERRIDE { return fOps.count(); }
-        virtual uint32_t offset(int index) const SK_OVERRIDE;
-        virtual const SkMatrix& matrix(int index) const SK_OVERRIDE;
-
-        // The query rect for which the cached active ops are valid
-        SkIRect          fCacheQueryRect;
-
-        // The operations which are active within 'fCachedQueryRect'
-        SkTDArray<void*> fOps;
-
-    private:
-        typedef SkPicture::OperationList INHERITED;
-    };
-
-    CachedOperationList* fCachedActiveOps;
-
-    SkTypefacePlayback fTFPlayback;
-    SkFactoryPlayback* fFactoryPlayback;
+    const SkPictureData* fPictureData;
 
     // The offset of the current operation when within the draw method
     size_t fCurOffset;
 
-    const SkPictInfo fInfo;
+    bool   fUseBBH;
 
-    static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
-    static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec);
+    void handleOp(SkReader32* reader, 
+                  DrawType op, 
+                  uint32_t size, 
+                  SkCanvas* canvas,
+                  const SkMatrix& initialMatrix);
 
-    void initForPlayback() const;
+    const SkPicture::OperationList* getActiveOps(const SkCanvas* canvas);
+    bool initIterator(SkPictureStateTree::Iterator* iter, 
+                      SkCanvas* canvas,
+                      const SkPicture::OperationList *activeOpsList);
+    static void StepIterator(SkPictureStateTree::Iterator* iter, SkReader32* reader);
+    static void SkipIterTo(SkPictureStateTree::Iterator* iter, 
+                           SkReader32* reader, uint32_t skipTo);
 
-#ifdef SK_BUILD_FOR_ANDROID
-    SkMutex fDrawMutex;
-    bool fAbortCurrentPlayback;
-#endif
+    static DrawType ReadOpAndSize(SkReader32* reader, uint32_t* size);
+
+    class AutoResetOpID {
+    public:
+        AutoResetOpID(SkPicturePlayback* playback) : fPlayback(playback) { }
+        ~AutoResetOpID() {
+            if (fPlayback) {
+                fPlayback->resetOpID();
+            }
+        }
+
+    private:
+        SkPicturePlayback* fPlayback;
+    };
+
+private:
+    typedef SkNoncopyable INHERITED;
 };
 
 #endif
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 16856d6..5b28468 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -6,12 +6,14 @@
  */
 
 #include "SkPictureRecord.h"
-#include "SkTSearch.h"
-#include "SkPixelRef.h"
-#include "SkRRect.h"
 #include "SkBBoxHierarchy.h"
 #include "SkDevice.h"
+#include "SkPatchUtils.h"
 #include "SkPictureStateTree.h"
+#include "SkPixelRef.h"
+#include "SkRRect.h"
+#include "SkTextBlob.h"
+#include "SkTSearch.h"
 
 #define HEAP_BLOCK_SIZE 4096
 
@@ -32,7 +34,7 @@
 // A lot of basic types get stored as a uint32_t: bools, ints, paint indices, etc.
 static int const kUInt32Size = 4;
 
-static const uint32_t kSaveSize = 2 * kUInt32Size;
+static const uint32_t kSaveSize = kUInt32Size;
 static const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size;
 static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect);
 
@@ -44,23 +46,12 @@
     , fPaints(&fFlattenableHeap)
     , fRecordFlags(flags)
     , fOptsEnabled(kBeClever) {
-#ifdef SK_DEBUG_SIZE
-    fPointBytes = fRectBytes = fTextBytes = 0;
-    fPointWrites = fRectWrites = fTextWrites = 0;
-#endif
 
     fBitmapHeap = SkNEW(SkBitmapHeap);
     fFlattenableHeap.setBitmapStorage(fBitmapHeap);
 
-#ifndef SK_COLLAPSE_MATRIX_CLIP_STATE
     fFirstSavedLayerIndex = kNoSavedLayerIndex;
-#endif
-
     fInitialSaveCount = kNoInitialSave;
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.init(this);
-#endif
 }
 
 SkPictureRecord::~SkPictureRecord() {
@@ -69,6 +60,7 @@
     SkSafeUnref(fStateTree);
     fFlattenableHeap.setBitmapStorage(NULL);
     fPictureRefs.unrefAll();
+    fTextBlobRefs.unrefAll();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -78,7 +70,7 @@
 // this method)
 static inline size_t getPaintOffset(DrawType op, size_t opSize) {
     // These offsets are where the paint would be if the op size doesn't overflow
-    static const uint8_t gPaintOffsets[LAST_DRAWTYPE_ENUM + 1] = {
+    static const uint8_t gPaintOffsets[] = {
         0,  // UNUSED - no paint
         0,  // CLIP_PATH - no paint
         0,  // CLIP_REGION - no paint
@@ -122,6 +114,9 @@
         1,  // DRAWDRRECT - right after op code
         0,  // PUSH_CULL - no paint
         0,  // POP_CULL - no paint
+        1,  // DRAW_PATCH - right after op code
+        1,  // DRAW_PICTURE_MATRIX_PAINT - right after op code
+        1,  // DRAW_TEXT_BLOB- right after op code
     };
 
     SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1,
@@ -151,35 +146,27 @@
     return gPaintOffsets[op] * sizeof(uint32_t) + overflow;
 }
 
-void SkPictureRecord::willSave(SaveFlags flags) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.save(flags);
-#else
+void SkPictureRecord::willSave() {
     // record the offset to us, making it non-positive to distinguish a save
     // from a clip entry.
     fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten());
-    this->recordSave(flags);
-#endif
+    this->recordSave();
 
-    this->INHERITED::willSave(flags);
+    this->INHERITED::willSave();
 }
 
-void SkPictureRecord::recordSave(SaveFlags flags) {
-    // op + flags
+void SkPictureRecord::recordSave() {
+    fContentInfo.onSave();
+
+    // op only
     size_t size = kSaveSize;
     size_t initialOffset = this->addDraw(SAVE, &size);
-    this->addInt(flags);
 
     this->validate(initialOffset, size);
 }
 
 SkCanvas::SaveLayerStrategy SkPictureRecord::willSaveLayer(const SkRect* bounds,
                                                            const SkPaint* paint, SaveFlags flags) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.saveLayer(bounds, paint, flags);
-#else
     // record the offset to us, making it non-positive to distinguish a save
     // from a clip entry.
     fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten());
@@ -187,7 +174,6 @@
     if (kNoSavedLayerIndex == fFirstSavedLayerIndex) {
         fFirstSavedLayerIndex = fRestoreOffsetStack.count();
     }
-#endif
 
     this->INHERITED::willSaveLayer(bounds, paint, flags);
     /*  No need for a (potentially very big) layer which we don't actually need
@@ -200,9 +186,11 @@
 
 void SkPictureRecord::recordSaveLayer(const SkRect* bounds, const SkPaint* paint,
                                       SaveFlags flags) {
+    fContentInfo.onSaveLayer();
+
     // op + bool for 'bounds'
     size_t size = 2 * kUInt32Size;
-    if (NULL != bounds) {
+    if (bounds) {
         size += sizeof(*bounds); // + rect
     }
     // + paint index + flags
@@ -220,11 +208,7 @@
 }
 
 bool SkPictureRecord::isDrawingToLayer() const {
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    return fMCMgr.isDrawingToLayer();
-#else
     return fFirstSavedLayerIndex != kNoSavedLayerIndex;
-#endif
 }
 
 /*
@@ -251,10 +235,6 @@
     return (DrawType) op;
 }
 
-#ifdef TRACK_COLLAPSE_STATS
-    static int gCollapseCount, gCollapseCalls;
-#endif
-
 // Is the supplied paint simply a color?
 static bool is_simple(const SkPaint& p) {
     intptr_t orAccum = (intptr_t)p.getPathEffect()  |
@@ -320,7 +300,6 @@
         return false;
     }
 
-    curOffset += curSize;
     if (curOffset < writer->bytesWritten()) {
         // Something else between the last command and the end of the stream
         return false;
@@ -458,7 +437,6 @@
  */
 static bool remove_save_layer2(SkWriter32* writer, int32_t offset,
                                SkPaintDictionary* paintDict) {
-
     // back up to the save block
     // TODO: add a stack to track save*/restore offsets rather than searching backwards
     while (offset > 0) {
@@ -482,7 +460,13 @@
 }
 
 static bool is_drawing_op(DrawType op) {
-    return (op > CONCAT && op < ROTATE) || DRAW_DRRECT == op;
+
+    // FIXME: yuck. convert to a lookup table?
+    return (op > CONCAT && op < ROTATE)
+            || DRAW_DRRECT == op
+            || DRAW_PATCH == op
+            || DRAW_PICTURE_MATRIX_PAINT == op
+            || DRAW_TEXT_BLOB == op;
 }
 
 /*
@@ -495,10 +479,6 @@
  */
 static bool collapse_save_clip_restore(SkWriter32* writer, int32_t offset,
                                        SkPaintDictionary* paintDict) {
-#ifdef TRACK_COLLAPSE_STATS
-    gCollapseCalls += 1;
-#endif
-
     int32_t restoreOffset = (int32_t)writer->bytesWritten();
 
     // back up to the save block
@@ -517,15 +497,6 @@
     SkASSERT(SAVE == op);
     SkASSERT(kSaveSize == opSize);
 
-    // get the save flag (last 4-bytes of the space allocated for the opSize)
-    SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags) writer->readTAt<uint32_t>(offset + 4);
-    if (SkCanvas::kMatrixClip_SaveFlag != saveFlags) {
-        // This function's optimization is only correct for kMatrixClip style saves.
-        // TODO: set checkMatrix & checkClip booleans here and then check for the
-        // offending operations in the following loop.
-        return false;
-    }
-
     // Walk forward until we get back to either a draw-verb (abort) or we hit
     // our restore (success).
     int32_t saveOffset = offset;
@@ -540,12 +511,6 @@
         offset += opSize;
     }
 
-#ifdef TRACK_COLLAPSE_STATS
-    gCollapseCount += 1;
-    SkDebugf("Collapse [%d out of %d] %g%spn", gCollapseCount, gCollapseCalls,
-             (double)gCollapseCount / gCollapseCalls, "%");
-#endif
-
     writer->rewindToOffset(saveOffset);
     return true;
 }
@@ -558,8 +523,10 @@
 };
 
 enum PictureRecordOptFlags {
-    kSkipIfBBoxHierarchy_Flag = 0x1,  // Optimization should be skipped if the
-                                      // SkPicture has a bounding box hierarchy.
+    kSkipIfBBoxHierarchy_Flag  = 0x1,  // Optimization should be skipped if the
+                                       // SkPicture has a bounding box hierarchy.
+    kRescindLastSave_Flag      = 0x2,
+    kRescindLastSaveLayer_Flag = 0x4,
 };
 
 struct PictureRecordOpt {
@@ -578,9 +545,10 @@
     // SkPictureStateTree, and applying the optimization introduces significant
     // record time overhead because it requires rewinding contents that were
     // recorded into the BBoxHierarchy.
-    { collapse_save_clip_restore, kRewind_OptType, kSkipIfBBoxHierarchy_Flag },
-    { remove_save_layer1,         kCollapseSaveLayer_OptType, 0 },
-    { remove_save_layer2,         kCollapseSaveLayer_OptType, 0 }
+    { collapse_save_clip_restore, kRewind_OptType, 
+                                                kSkipIfBBoxHierarchy_Flag|kRescindLastSave_Flag },
+    { remove_save_layer1,         kCollapseSaveLayer_OptType, kRescindLastSaveLayer_Flag },
+    { remove_save_layer2,         kCollapseSaveLayer_OptType, kRescindLastSaveLayer_Flag }
 };
 
 // This is called after an optimization has been applied to the command stream
@@ -590,12 +558,12 @@
                                       SkBBoxHierarchy* boundingHierarchy) {
     switch (opt) {
     case kCollapseSaveLayer_OptType:
-        if (NULL != stateTree) {
+        if (stateTree) {
             stateTree->saveCollapsed();
         }
         break;
     case kRewind_OptType:
-        if (NULL != boundingHierarchy) {
+        if (boundingHierarchy) {
             boundingHierarchy->rewindInserts();
         }
         // Note: No need to touch the state tree for this to work correctly.
@@ -615,13 +583,6 @@
     SkASSERT(fRestoreOffsetStack.count() > 1);
 #endif
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    if (fMCMgr.getSaveCount() == 1) {
-        return;
-    }
-
-    fMCMgr.restore();
-#else
     // check for underflow
     if (fRestoreOffsetStack.count() == 0) {
         return;
@@ -635,13 +596,18 @@
     if (fOptsEnabled) {
         for (opt = 0; opt < SK_ARRAY_COUNT(gPictureRecordOpts); ++opt) {
             if (0 != (gPictureRecordOpts[opt].fFlags & kSkipIfBBoxHierarchy_Flag)
-                && NULL != fBoundingHierarchy) {
+                && fBoundingHierarchy) {
                 continue;
             }
             if ((*gPictureRecordOpts[opt].fProc)(&fWriter, fRestoreOffsetStack.top(), &fPaints)) {
                 // Some optimization fired so don't add the RESTORE
                 apply_optimization_to_bbh(gPictureRecordOpts[opt].fType,
                                           fStateTree, fBoundingHierarchy);
+                if (gPictureRecordOpts[opt].fFlags & kRescindLastSave_Flag) {
+                    fContentInfo.rescindLastSave();
+                } else if (gPictureRecordOpts[opt].fFlags & kRescindLastSaveLayer_Flag) {
+                    fContentInfo.rescindLastSaveLayer();
+                } 
                 break;
             }
         }
@@ -653,12 +619,13 @@
     }
 
     fRestoreOffsetStack.pop();
-#endif
 
     this->INHERITED::willRestore();
 }
 
 void SkPictureRecord::recordRestore(bool fillInSkips) {
+    fContentInfo.onRestore();
+
     if (fillInSkips) {
         this->fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten());
     }
@@ -690,10 +657,6 @@
 }
 
 void SkPictureRecord::didConcat(const SkMatrix& matrix) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.concat(matrix);
-#else
     switch (matrix.getType()) {
         case SkMatrix::kTranslate_Mask:
             this->recordTranslate(matrix);
@@ -705,7 +668,6 @@
             this->recordConcat(matrix);
             break;
     }
-#endif
     this->INHERITED::didConcat(matrix);
 }
 
@@ -719,17 +681,12 @@
 }
 
 void SkPictureRecord::didSetMatrix(const SkMatrix& matrix) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.setMatrix(matrix);
-#else
     this->validate(fWriter.bytesWritten(), 0);
     // op + matrix
     size_t size = kUInt32Size + matrix.writeToMemory(NULL);
     size_t initialOffset = this->addDraw(SET_MATRIX, &size);
     this->addMatrix(matrix);
     this->validate(initialOffset, size);
-#endif
     this->INHERITED::didSetMatrix(matrix);
 }
 
@@ -749,11 +706,6 @@
     }
 }
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) {
-    fMCMgr.fillInSkips(&fWriter, restoreOffset);
-}
-#else
 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) {
     int32_t offset = fRestoreOffsetStack.top();
     while (offset > 0) {
@@ -769,7 +721,6 @@
     SkASSERT(SAVE == drawOp || SAVE_LAYER == drawOp);
 #endif
 }
-#endif
 
 void SkPictureRecord::beginRecording() {
     // we have to call this *after* our constructor, to ensure that it gets
@@ -781,18 +732,8 @@
 void SkPictureRecord::endRecording() {
     SkASSERT(kNoInitialSave != fInitialSaveCount);
     this->restoreToCount(fInitialSaveCount);
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.finish();
-#endif
 }
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-int SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) {
-    size_t offset = fWriter.bytesWritten();
-    this->addInt(-1);
-    return offset;
-}
-#else
 size_t SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) {
     if (fRestoreOffsetStack.isEmpty()) {
         return -1;
@@ -822,30 +763,20 @@
     fRestoreOffsetStack.top() = SkToU32(offset);
     return offset;
 }
-#endif
 
 void SkPictureRecord::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.clipRect(rect, op, doAA);
-#else
     this->recordClipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle);
-#endif
     this->INHERITED::onClipRect(rect, op, edgeStyle);
 }
 
 size_t SkPictureRecord::recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
     // id + rect + clip params
     size_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size;
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    size += kUInt32Size;    // + restore offset
-#else
     // recordRestoreOffsetPlaceholder doesn't always write an offset
     if (!fRestoreOffsetStack.isEmpty()) {
         // + restore offset
         size += kUInt32Size;
     }
-#endif
     size_t initialOffset = this->addDraw(CLIP_RECT, &size);
     this->addRect(rect);
     this->addInt(ClipParams_pack(op, doAA));
@@ -856,27 +787,18 @@
 }
 
 void SkPictureRecord::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.clipRRect(rrect, op, doAA);
-#else
     this->recordClipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle);
-#endif
-    this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false);
+    this->INHERITED::onClipRRect(rrect, op, edgeStyle);
 }
 
 size_t SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
     // op + rrect + clip params
     size_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size;
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    size += kUInt32Size;    // + restore offset
-#else
     // recordRestoreOffsetPlaceholder doesn't always write an offset
     if (!fRestoreOffsetStack.isEmpty()) {
         // + restore offset
         size += kUInt32Size;
     }
-#endif
     size_t initialOffset = this->addDraw(CLIP_RRECT, &size);
     this->addRRect(rrect);
     this->addInt(ClipParams_pack(op, doAA));
@@ -886,30 +808,19 @@
 }
 
 void SkPictureRecord::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.clipPath(path, op, doAA);
-#else
     int pathID = this->addPathToHeap(path);
     this->recordClipPath(pathID, op, kSoft_ClipEdgeStyle == edgeStyle);
-#endif
-
-    this->updateClipConservativelyUsingBounds(path.getBounds(), op,
-                                              path.isInverseFillType());
+    this->INHERITED::onClipPath(path, op, edgeStyle);
 }
 
 size_t SkPictureRecord::recordClipPath(int pathID, SkRegion::Op op, bool doAA) {
     // op + path index + clip params
     size_t size = 3 * kUInt32Size;
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    size += kUInt32Size;    // + restore offset
-#else
     // recordRestoreOffsetPlaceholder doesn't always write an offset
     if (!fRestoreOffsetStack.isEmpty()) {
         // + restore offset
         size += kUInt32Size;
     }
-#endif
     size_t initialOffset = this->addDraw(CLIP_PATH, &size);
     this->addInt(pathID);
     this->addInt(ClipParams_pack(op, doAA));
@@ -919,27 +830,18 @@
 }
 
 void SkPictureRecord::onClipRegion(const SkRegion& region, SkRegion::Op op) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.clipRegion(region, op);
-#else
     this->recordClipRegion(region, op);
-#endif
     this->INHERITED::onClipRegion(region, op);
 }
 
 size_t SkPictureRecord::recordClipRegion(const SkRegion& region, SkRegion::Op op) {
     // op + clip params + region
     size_t size = 2 * kUInt32Size + region.writeToMemory(NULL);
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    size += kUInt32Size;    // + restore offset
-#else
     // recordRestoreOffsetPlaceholder doesn't always write an offset
     if (!fRestoreOffsetStack.isEmpty()) {
         // + restore offset
         size += kUInt32Size;
     }
-#endif
     size_t initialOffset = this->addDraw(CLIP_REGION, &size);
     this->addRegion(region);
     this->addInt(ClipParams_pack(op, false));
@@ -950,11 +852,6 @@
 }
 
 void SkPictureRecord::clear(SkColor color) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + color
     size_t size = 2 * kUInt32Size;
     size_t initialOffset = this->addDraw(DRAW_CLEAR, &size);
@@ -963,11 +860,6 @@
 }
 
 void SkPictureRecord::drawPaint(const SkPaint& paint) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + paint index
     size_t size = 2 * kUInt32Size;
     size_t initialOffset = this->addDraw(DRAW_PAINT, &size);
@@ -978,24 +870,14 @@
 
 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
                                  const SkPaint& paint) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
+    fContentInfo.onDrawPoints(count, paint);
 
     // op + paint index + mode + count + point data
     size_t size = 4 * kUInt32Size + count * sizeof(SkPoint);
     size_t initialOffset = this->addDraw(DRAW_POINTS, &size);
     SkASSERT(initialOffset+getPaintOffset(DRAW_POINTS, size) == fWriter.bytesWritten());
     this->addPaint(paint);
-    if (paint.getPathEffect() != NULL) {
-        SkPathEffect::DashInfo info;
-        SkPathEffect::DashType dashType = paint.getPathEffect()->asADash(&info);
-        if (2 == count && SkPaint::kRound_Cap != paint.getStrokeCap() &&
-            SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) {
-            fContentInfo.incFastPathDashEffects();
-        }
-    }
+
     this->addInt(mode);
     this->addInt(SkToInt(count));
     fWriter.writeMul4(pts, count * sizeof(SkPoint));
@@ -1003,11 +885,6 @@
 }
 
 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + paint index + rect
     size_t size = 2 * kUInt32Size + sizeof(oval);
     size_t initialOffset = this->addDraw(DRAW_OVAL, &size);
@@ -1018,11 +895,6 @@
 }
 
 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + paint index + rect
     size_t size = 2 * kUInt32Size + sizeof(rect);
     size_t initialOffset = this->addDraw(DRAW_RECT, &size);
@@ -1033,11 +905,6 @@
 }
 
 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     if (rrect.isRect() && kBeClever) {
         this->SkPictureRecord::drawRect(rrect.getBounds(), paint);
     } else if (rrect.isOval() && kBeClever) {
@@ -1055,11 +922,6 @@
 
 void SkPictureRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
                                    const SkPaint& paint) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + paint index + rrects
     size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory * 2;
     size_t initialOffset = this->addDraw(DRAW_DRRECT, &size);
@@ -1071,19 +933,7 @@
 }
 
 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
-
-    if (paint.isAntiAlias() && !path.isConvex()) {
-        fContentInfo.incAAConcavePaths();
-
-        if (SkPaint::kStroke_Style == paint.getStyle() &&
-            0 == paint.getStrokeWidth()) {
-            fContentInfo.incAAHairlineConcavePaths();
-        }
-    }
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
+    fContentInfo.onDrawPath(path, paint);
 
     // op + paint index + path index
     size_t size = 3 * kUInt32Size;
@@ -1100,10 +950,6 @@
         return;
     }
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + paint index + bitmap index + left + top
     size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar);
     size_t initialOffset = this->addDraw(DRAW_BITMAP, &size);
@@ -1122,12 +968,9 @@
         return;
     }
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
     // id + paint index + bitmap index + bool for 'src' + flags
     size_t size = 5 * kUInt32Size;
-    if (NULL != src) {
+    if (src) {
         size += sizeof(*src);   // + rect
     }
     size += sizeof(dst);        // + rect
@@ -1149,10 +992,6 @@
         return;
     }
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // id + paint index + bitmap index + matrix
     size_t size = 3 * kUInt32Size + matrix.writeToMemory(NULL);
     size_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size);
@@ -1169,10 +1008,6 @@
         return;
     }
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + paint index + bitmap id + center + dst rect
     size_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst);
     size_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size);
@@ -1190,10 +1025,6 @@
         return;
     }
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + paint index + bitmap index + left + top
     size_t size = 5 * kUInt32Size;
     size_t initialOffset = this->addDraw(DRAW_SPRITE, &size);
@@ -1226,11 +1057,6 @@
 
 void SkPictureRecord::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
                                  const SkPaint& paint) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     bool fast = !paint.isVerticalText() && paint.canComputeFastBounds() && kBeClever;
 
     // op + paint index + length + 'length' worth of chars + x + y
@@ -1255,11 +1081,6 @@
 
 void SkPictureRecord::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
                                     const SkPaint& paint) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     int points = paint.countText(text, byteLength);
     if (0 == points)
         return;
@@ -1318,9 +1139,6 @@
     this->addText(text, byteLength);
     this->addInt(points);
 
-#ifdef SK_DEBUG_SIZE
-    size_t start = fWriter.bytesWritten();
-#endif
     if (canUseDrawH) {
         if (fast) {
             this->addFontMetricsTopBottom(paint, *flatPaintData, pos[0].fY, pos[0].fY);
@@ -1335,19 +1153,11 @@
             this->addFontMetricsTopBottom(paint, *flatPaintData, minY, maxY);
         }
     }
-#ifdef SK_DEBUG_SIZE
-    fPointBytes += fWriter.bytesWritten() - start;
-    fPointWrites += points;
-#endif
     this->validate(initialOffset, size);
 }
 
 void SkPictureRecord::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
                                      SkScalar constY, const SkPaint& paint) {
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     const SkFlatData* flatPaintData = this->getFlatPaintData(paint);
     this->drawPosTextHImpl(text, byteLength, xpos, constY, paint, flatPaintData);
 }
@@ -1377,27 +1187,16 @@
     this->addText(text, byteLength);
     this->addInt(points);
 
-#ifdef SK_DEBUG_SIZE
-    size_t start = fWriter.bytesWritten();
-#endif
     if (fast) {
         this->addFontMetricsTopBottom(paint, *flatPaintData, constY, constY);
     }
     this->addScalar(constY);
     fWriter.writeMul4(xpos, points * sizeof(SkScalar));
-#ifdef SK_DEBUG_SIZE
-    fPointBytes += fWriter.bytesWritten() - start;
-    fPointWrites += points;
-#endif
     this->validate(initialOffset, size);
 }
 
 void SkPictureRecord::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                        const SkMatrix* matrix, const SkPaint& paint) {
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + paint index + length + 'length' worth of data + path index + matrix
     const SkMatrix& m = matrix ? *matrix : SkMatrix::I();
     size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + kUInt32Size + m.writeToMemory(NULL);
@@ -1410,16 +1209,41 @@
     this->validate(initialOffset, size);
 }
 
-void SkPictureRecord::onDrawPicture(const SkPicture* picture) {
+void SkPictureRecord::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                     const SkPaint& paint) {
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
+    // op + paint index + blob index + x/y
+    size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar);
+    size_t initialOffset = this->addDraw(DRAW_TEXT_BLOB, &size);
+    SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_BLOB, size) == fWriter.bytesWritten());
 
+    this->addPaint(paint);
+    this->addTextBlob(blob);
+    this->addScalar(x);
+    this->addScalar(y);
+
+    this->validate(initialOffset, size);
+}
+
+void SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                                    const SkPaint* paint) {
     // op + picture index
     size_t size = 2 * kUInt32Size;
-    size_t initialOffset = this->addDraw(DRAW_PICTURE, &size);
-    this->addPicture(picture);
+    size_t initialOffset;
+
+    if (NULL == matrix && NULL == paint) {
+        initialOffset = this->addDraw(DRAW_PICTURE, &size);
+        this->addPicture(picture);
+    } else {
+        const SkMatrix& m = matrix ? *matrix : SkMatrix::I();
+        size += m.writeToMemory(NULL) + kUInt32Size;    // matrix + paint
+        initialOffset = this->addDraw(DRAW_PICTURE_MATRIX_PAINT, &size);
+        SkASSERT(initialOffset + getPaintOffset(DRAW_PICTURE_MATRIX_PAINT, size)
+                 == fWriter.bytesWritten());
+        this->addPaintPtr(paint);
+        this->addMatrix(m);
+        this->addPicture(picture);
+    }
     this->validate(initialOffset, size);
 }
 
@@ -1428,11 +1252,6 @@
                           const SkColor colors[], SkXfermode* xfer,
                           const uint16_t indices[], int indexCount,
                           const SkPaint& paint) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     uint32_t flags = 0;
     if (texs) {
         flags |= DRAW_VERTICES_HAS_TEXS;
@@ -1443,7 +1262,7 @@
     if (indexCount > 0) {
         flags |= DRAW_VERTICES_HAS_INDICES;
     }
-    if (NULL != xfer) {
+    if (xfer) {
         SkXfermode::Mode mode;
         if (xfer->asMode(&mode) && SkXfermode::kModulate_Mode != mode) {
             flags |= DRAW_VERTICES_HAS_XFER;
@@ -1491,12 +1310,50 @@
     this->validate(initialOffset, size);
 }
 
+void SkPictureRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                                  const SkPoint texCoords[4], SkXfermode* xmode,
+                                  const SkPaint& paint) {
+    // op + paint index + patch 12 control points + flag + patch 4 colors + 4 texture coordinates
+    size_t size = 2 * kUInt32Size + SkPatchUtils::kNumCtrlPts * sizeof(SkPoint) + kUInt32Size;
+    uint32_t flag = 0;
+    if (colors) {
+        flag |= DRAW_VERTICES_HAS_COLORS;
+        size += SkPatchUtils::kNumCorners * sizeof(SkColor);
+    }
+    if (texCoords) {
+        flag |= DRAW_VERTICES_HAS_TEXS;
+        size += SkPatchUtils::kNumCorners * sizeof(SkPoint);
+    }
+    if (xmode) {
+        SkXfermode::Mode mode;
+        if (xmode->asMode(&mode) && SkXfermode::kModulate_Mode != mode) {
+            flag |= DRAW_VERTICES_HAS_XFER;
+            size += kUInt32Size;
+        }
+    }
+    
+    size_t initialOffset = this->addDraw(DRAW_PATCH, &size);
+    SkASSERT(initialOffset+getPaintOffset(DRAW_PATCH, size) == fWriter.bytesWritten());
+    this->addPaint(paint);
+    this->addPatch(cubics);
+    this->addInt(flag);
+    
+    // write optional parameters
+    if (colors) {
+        fWriter.write(colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
+    }
+    if (texCoords) {
+        fWriter.write(texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint));
+    }
+    if (flag & DRAW_VERTICES_HAS_XFER) {
+        SkXfermode::Mode mode = SkXfermode::kModulate_Mode;
+        xmode->asMode(&mode);
+        this->addInt(mode);
+    }
+    this->validate(initialOffset, size);
+}
+
 void SkPictureRecord::drawData(const void* data, size_t length) {
-
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
-#endif
-
     // op + length + 'length' worth of data
     size_t size = 2 * kUInt32Size + SkAlign4(length);
     size_t initialOffset = this->addDraw(DRAW_DATA, &size);
@@ -1572,7 +1429,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info) {
+SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) {
     return NULL;
 }
 
@@ -1595,9 +1452,7 @@
 }
 
 const SkFlatData* SkPictureRecord::addPaintPtr(const SkPaint* paint) {
-    if (NULL != paint && NULL != paint->getPathEffect()) {
-        fContentInfo.incPaintWithPathEffectUses();
-    }
+    fContentInfo.onAddPaintPtr(paint);
 
     const SkFlatData* data = paint ? getFlatPaintData(*paint) : NULL;
     this->addFlatPaint(data);
@@ -1624,6 +1479,10 @@
     this->addInt(this->addPathToHeap(path));
 }
 
+void SkPictureRecord::addPatch(const SkPoint cubics[12]) {
+    fWriter.write(cubics, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
+}
+
 void SkPictureRecord::addPicture(const SkPicture* picture) {
     int index = fPictureRefs.find(picture);
     if (index < 0) {    // not found
@@ -1636,22 +1495,11 @@
 }
 
 void SkPictureRecord::addPoint(const SkPoint& point) {
-#ifdef SK_DEBUG_SIZE
-    size_t start = fWriter.bytesWritten();
-#endif
     fWriter.writePoint(point);
-#ifdef SK_DEBUG_SIZE
-    fPointBytes += fWriter.bytesWritten() - start;
-    fPointWrites++;
-#endif
 }
 
 void SkPictureRecord::addPoints(const SkPoint pts[], int count) {
     fWriter.writeMul4(pts, count * sizeof(SkPoint));
-#ifdef SK_DEBUG_SIZE
-    fPointBytes += count * sizeof(SkPoint);
-    fPointWrites++;
-#endif
 }
 
 void SkPictureRecord::addNoOp() {
@@ -1660,14 +1508,7 @@
 }
 
 void SkPictureRecord::addRect(const SkRect& rect) {
-#ifdef SK_DEBUG_SIZE
-    size_t start = fWriter.bytesWritten();
-#endif
     fWriter.writeRect(rect);
-#ifdef SK_DEBUG_SIZE
-    fRectBytes += fWriter.bytesWritten() - start;
-    fRectWrites++;
-#endif
 }
 
 void SkPictureRecord::addRectPtr(const SkRect* rect) {
@@ -1695,147 +1536,18 @@
 }
 
 void SkPictureRecord::addText(const void* text, size_t byteLength) {
-#ifdef SK_DEBUG_SIZE
-    size_t start = fWriter.bytesWritten();
-#endif
+    fContentInfo.onDrawText();
     addInt(SkToInt(byteLength));
     fWriter.writePad(text, byteLength);
-#ifdef SK_DEBUG_SIZE
-    fTextBytes += fWriter.bytesWritten() - start;
-    fTextWrites++;
-#endif
+}
+
+void SkPictureRecord::addTextBlob(const SkTextBlob *blob) {
+    int index = fTextBlobRefs.count();
+    *fTextBlobRefs.append() = blob;
+    blob->ref();
+    // follow the convention of recording a 1-based index
+    this->addInt(index + 1);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-#ifdef SK_DEBUG_SIZE
-size_t SkPictureRecord::size() const {
-    size_t result = 0;
-    size_t sizeData;
-    bitmaps(&sizeData);
-    result += sizeData;
-    matrices(&sizeData);
-    result += sizeData;
-    paints(&sizeData);
-    result += sizeData;
-    paths(&sizeData);
-    result += sizeData;
-    pictures(&sizeData);
-    result += sizeData;
-    regions(&sizeData);
-    result += sizeData;
-    result += streamlen();
-    return result;
-}
-
-int SkPictureRecord::bitmaps(size_t* size) const {
-    size_t result = 0;
-    int count = fBitmaps.count();
-    for (int index = 0; index < count; index++)
-        result += sizeof(fBitmaps[index]) + fBitmaps[index]->size();
-    *size = result;
-    return count;
-}
-
-int SkPictureRecord::matrices(size_t* size) const {
-    int count = fMatrices.count();
-    *size = sizeof(fMatrices[0]) * count;
-    return count;
-}
-
-int SkPictureRecord::paints(size_t* size) const {
-    size_t result = 0;
-    int count = fPaints.count();
-    for (int index = 0; index < count; index++)
-        result += sizeof(fPaints[index]) + fPaints[index]->size();
-    *size = result;
-    return count;
-}
-
-int SkPictureRecord::paths(size_t* size) const {
-    size_t result = 0;
-    int count = fPaths.count();
-    for (int index = 0; index < count; index++)
-        result += sizeof(fPaths[index]) + fPaths[index]->size();
-    *size = result;
-    return count;
-}
-
-int SkPictureRecord::regions(size_t* size) const {
-    size_t result = 0;
-    int count = fRegions.count();
-    for (int index = 0; index < count; index++)
-        result += sizeof(fRegions[index]) + fRegions[index]->size();
-    *size = result;
-    return count;
-}
-
-size_t SkPictureRecord::streamlen() const {
-    return fWriter.size();
-}
-#endif
-
-#ifdef SK_DEBUG_VALIDATE
-void SkPictureRecord::validate(uint32_t initialOffset, uint32_t size) const {
-    SkASSERT(fWriter.size() == initialOffset + size);
-
-    validateBitmaps();
-    validateMatrices();
-    validatePaints();
-    validatePaths();
-    validateRegions();
-}
-
-void SkPictureRecord::validateBitmaps() const {
-    int count = fBitmapHeap->count();
-    SkASSERT((unsigned) count < 0x1000);
-    for (int index = 0; index < count; index++) {
-        const SkBitmap* bitPtr = fBitmapHeap->getBitmap(index);
-        SkASSERT(bitPtr);
-        bitPtr->validate();
-    }
-}
-
-void SkPictureRecord::validateMatrices() const {
-    int count = fMatrices.count();
-    SkASSERT((unsigned) count < 0x1000);
-    for (int index = 0; index < count; index++) {
-        const SkFlatData* matrix = fMatrices[index];
-        SkASSERT(matrix);
-//        matrix->validate();
-    }
-}
-
-void SkPictureRecord::validatePaints() const {
-    int count = fPaints.count();
-    SkASSERT((unsigned) count < 0x1000);
-    for (int index = 0; index < count; index++) {
-        const SkFlatData* paint = fPaints[index];
-        SkASSERT(paint);
-//            paint->validate();
-    }
-}
-
-void SkPictureRecord::validatePaths() const {
-    if (NULL == fPathHeap) {
-        return;
-    }
-
-    int count = fPathHeap->count();
-    SkASSERT((unsigned) count < 0x1000);
-    for (int index = 0; index < count; index++) {
-        const SkPath& path = (*fPathHeap)[index];
-        path.validate();
-    }
-}
-
-void SkPictureRecord::validateRegions() const {
-    int count = fRegions.count();
-    SkASSERT((unsigned) count < 0x1000);
-    for (int index = 0; index < count; index++) {
-        const SkFlatData* region = fRegions[index];
-        SkASSERT(region);
-//        region->validate();
-    }
-}
-#endif
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 7e5c5c6..f8895c9 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -10,12 +10,9 @@
 
 #include "SkCanvas.h"
 #include "SkFlattenable.h"
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-#include "SkMatrixClipStateMgr.h"
-#endif
 #include "SkPathHeap.h"
 #include "SkPicture.h"
-#include "SkPicturePlayback.h"
+#include "SkPictureData.h"
 #include "SkPictureFlat.h"
 #include "SkTemplates.h"
 #include "SkWriter32.h"
@@ -74,6 +71,10 @@
         return fPictureRefs;
     }
 
+    const SkTDArray<const SkTextBlob* >& getTextBlobRefs() const {
+        return fTextBlobRefs;
+    }
+
     SkData* opData(bool deepCopy) const {
         this->validate(fWriter.bytesWritten(), 0);
 
@@ -119,13 +120,11 @@
     size_t recordRestoreOffsetPlaceholder(SkRegion::Op);
     void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset);
 
-#ifndef SK_COLLAPSE_MATRIX_CLIP_STATE
     SkTDArray<int32_t> fRestoreOffsetStack;
     int fFirstSavedLayerIndex;
     enum {
         kNoSavedLayerIndex = -1
     };
-#endif
 
     SkTDArray<uint32_t> fCullOffsetStack;
 
@@ -145,10 +144,7 @@
         size_t offset = fWriter.bytesWritten();
 
         this->predrawNotify();
-
-    #ifdef SK_DEBUG_TRACE
-        SkDebugf("add %s\n", DrawTypeToString(drawType));
-    #endif
+        fContentInfo.addOperation();
 
         SkASSERT(0 != *size);
         SkASSERT(((uint8_t) drawType) == drawType);
@@ -177,6 +173,7 @@
     const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr(&paint); }
     const SkFlatData* addPaintPtr(const SkPaint* paint);
     void addFlatPaint(const SkFlatData* flatPaint);
+    void addPatch(const SkPoint cubics[12]);
     void addPath(const SkPath& path);
     void addPicture(const SkPicture* picture);
     void addPoint(const SkPoint& point);
@@ -188,52 +185,21 @@
     void addRRect(const SkRRect&);
     void addRegion(const SkRegion& region);
     void addText(const void* text, size_t byteLength);
+    void addTextBlob(const SkTextBlob* blob);
 
     int find(const SkBitmap& bitmap);
 
-#ifdef SK_DEBUG_DUMP
-public:
-    void dumpMatrices();
-    void dumpPaints();
-#endif
-
-#ifdef SK_DEBUG_SIZE
-public:
-    size_t size() const;
-    int bitmaps(size_t* size) const;
-    int matrices(size_t* size) const;
-    int paints(size_t* size) const;
-    int paths(size_t* size) const;
-    int regions(size_t* size) const;
-    size_t streamlen() const;
-
-    size_t fPointBytes, fRectBytes, fTextBytes;
-    int fPointWrites, fRectWrites, fTextWrites;
-#endif
-
-#ifdef SK_DEBUG_VALIDATE
-public:
-    void validate(size_t initialOffset, uint32_t size) const;
-private:
-    void validateBitmaps() const;
-    void validateMatrices() const;
-    void validatePaints() const;
-    void validatePaths() const;
-    void validateRegions() const;
-#else
-public:
+protected:
     void validate(size_t initialOffset, size_t size) const {
         SkASSERT(fWriter.bytesWritten() == initialOffset + size);
     }
-#endif
 
-protected:
-    virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
+    virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
     const void* onPeekPixels(SkImageInfo*, size_t*) SK_OVERRIDE {
         return NULL;
     }
 
-    virtual void willSave(SaveFlags) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
     virtual void willRestore() SK_OVERRIDE;
 
@@ -252,13 +218,19 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
+    
+    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                             const SkPoint texCoords[4], SkXfermode* xmode,
+                             const SkPaint& paint) SK_OVERRIDE;
 
     virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
 
-    virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
     // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been
     // tweaked by paint.computeFastBounds().
@@ -293,7 +265,7 @@
     size_t recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA);
     size_t recordClipPath(int pathID, SkRegion::Op op, bool doAA);
     size_t recordClipRegion(const SkRegion& region, SkRegion::Op op);
-    void recordSave(SaveFlags flags);
+    void recordSave();
     void recordSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags);
     void recordRestore(bool fillInSkips = true);
 
@@ -306,9 +278,6 @@
     SkBitmapHeap* fBitmapHeap;
 
 private:
-    friend class MatrixClipState; // for access to *Impl methods
-    friend class SkMatrixClipStateMgr; // for access to *Impl methods
-
     SkPictureContentInfo fContentInfo;
     SkAutoTUnref<SkPathHeap> fPathHeap;
 
@@ -319,19 +288,16 @@
     SkWriter32 fWriter;
 
     // we ref each item in these arrays
-    SkTDArray<const SkPicture*> fPictureRefs;
+    SkTDArray<const SkPicture*>  fPictureRefs;
+    SkTDArray<const SkTextBlob*> fTextBlobRefs;
 
     uint32_t fRecordFlags;
     bool     fOptsEnabled;
     int      fInitialSaveCount;
 
-    friend class SkPicturePlayback;
+    friend class SkPictureData;   // for SkPictureData's SkPictureRecord-based constructor
     friend class SkPictureTester; // for unit testing
 
-#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
-    SkMatrixClipStateMgr fMCMgr;
-#endif
-
     typedef SkCanvas INHERITED;
 };
 
diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp
index f1423e3..77274e6 100644
--- a/src/core/SkPictureRecorder.cpp
+++ b/src/core/SkPictureRecorder.cpp
@@ -6,7 +6,6 @@
  */
 
 #include "SkBBoxHierarchyRecord.h"
-#include "SkPicturePlayback.h"
 #include "SkPictureRecord.h"
 #include "SkPictureRecorder.h"
 #include "SkRecord.h"
@@ -14,77 +13,84 @@
 #include "SkRecorder.h"
 #include "SkTypes.h"
 
-SkPictureRecorder::~SkPictureRecorder() {
-    this->reset();
-}
+SkPictureRecorder::SkPictureRecorder() {}
 
-void SkPictureRecorder::reset() {
-    SkSafeSetNull(fPictureRecord);
-    SkSafeSetNull(fRecorder);
-    SkDELETE(fRecord);
-    fRecord = NULL;
-}
+SkPictureRecorder::~SkPictureRecorder() {}
 
-SkCanvas* SkPictureRecorder::beginRecording(int width, int height,
+SkCanvas* SkPictureRecorder::beginRecording(SkScalar width, SkScalar height,
                                             SkBBHFactory* bbhFactory /* = NULL */,
                                             uint32_t recordFlags /* = 0 */) {
-    this->reset();  // terminate any prior recording(s)
-    fWidth = width;
-    fHeight = height;
+#ifdef SK_PICTURE_USE_SK_RECORD
+    return EXPERIMENTAL_beginRecording(width, height, bbhFactory);
+#else
+    return DEPRECATED_beginRecording(width, height, bbhFactory, recordFlags);
+#endif
+}
+
+SkCanvas* SkPictureRecorder::DEPRECATED_beginRecording(SkScalar width, SkScalar height,
+                                                       SkBBHFactory* bbhFactory /* = NULL */,
+                                                       uint32_t recordFlags /* = 0 */) {
+    fCullWidth = width;
+    fCullHeight = height;
 
     const SkISize size = SkISize::Make(width, height);
 
-    if (NULL != bbhFactory) {
-        SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height));
-        SkASSERT(NULL != tree);
-        fPictureRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (size, recordFlags, tree.get()));
+    if (bbhFactory) {
+        // We don't need to hold a ref on the BBH ourselves, but might as well for
+        // consistency with EXPERIMENTAL_beginRecording(), which does need to.
+        fBBH.reset((*bbhFactory)(width, height));
+        SkASSERT(fBBH.get());
+        fPictureRecord.reset(SkNEW_ARGS(SkBBoxHierarchyRecord, (size, recordFlags, fBBH.get())));
     } else {
-        fPictureRecord = SkNEW_ARGS(SkPictureRecord, (size, recordFlags));
+        fPictureRecord.reset(SkNEW_ARGS(SkPictureRecord, (size, recordFlags)));
     }
 
     fPictureRecord->beginRecording();
     return this->getRecordingCanvas();
 }
 
-SkCanvas* SkPictureRecorder::EXPERIMENTAL_beginRecording(int width, int height,
+SkCanvas* SkPictureRecorder::EXPERIMENTAL_beginRecording(SkScalar width, SkScalar height,
                                                          SkBBHFactory* bbhFactory /* = NULL */) {
-    this->reset();
-    fWidth = width;
-    fHeight = height;
+    fCullWidth = width;
+    fCullHeight = height;
 
-    // TODO: plumb bbhFactory through
-    fRecord   = SkNEW(SkRecord);
-    fRecorder = SkNEW_ARGS(SkRecorder, (fRecord, width, height));
+    if (bbhFactory) {
+        fBBH.reset((*bbhFactory)(width, height));
+        SkASSERT(fBBH.get());
+    }
+
+    fRecord.reset(SkNEW(SkRecord));
+    fRecorder.reset(SkNEW_ARGS(SkRecorder, (fRecord.get(), width, height)));
     return this->getRecordingCanvas();
 }
 
 SkCanvas* SkPictureRecorder::getRecordingCanvas() {
-    if (NULL != fRecorder) {
-        return fRecorder;
+    if (fRecorder.get()) {
+        return fRecorder.get();
     }
-    return fPictureRecord;
+    return fPictureRecord.get();
 }
 
 SkPicture* SkPictureRecorder::endRecording() {
     SkPicture* picture = NULL;
 
-    if (NULL != fRecorder) {
-        // TODO: picture = SkNEW_ARGS(SkPicture, (fWidth, fHeight, fRecord));
-        //       fRecord = NULL;
+    if (fRecord.get()) {
+        picture = SkNEW_ARGS(SkPicture, (fCullWidth, fCullHeight, 
+                                         fRecord.detach(), fBBH.get()));
     }
 
-    if (NULL != fPictureRecord) {
+    if (fPictureRecord.get()) {
         fPictureRecord->endRecording();
         const bool deepCopyOps = false;
-        picture = SkNEW_ARGS(SkPicture, (fWidth, fHeight, *fPictureRecord, deepCopyOps));
+        picture = SkNEW_ARGS(SkPicture, (fCullWidth, fCullHeight, 
+                                         *fPictureRecord.get(), deepCopyOps));
     }
 
-    this->reset();
     return picture;
 }
 
 void SkPictureRecorder::internalOnly_EnableOpts(bool enableOpts) {
-    if (NULL != fPictureRecord) {
+    if (fPictureRecord.get()) {
         fPictureRecord->internalOnly_EnableOpts(enableOpts);
     }
 }
@@ -94,13 +100,14 @@
         return;
     }
 
-    if (NULL != fRecorder) {
-        SkRecordDraw(*fRecord, canvas);
+    if (fRecord.get()) {
+        SkRecordDraw(*fRecord, canvas, NULL/*bbh*/, NULL/*callback*/);
     }
 
-    if (NULL != fPictureRecord) {
+    if (fPictureRecord.get()) {
         const bool deepCopyOps = true;
-        SkPicture picture(fWidth, fHeight, *fPictureRecord, deepCopyOps);
-        picture.draw(canvas);
+        SkPicture picture(fCullWidth, fCullHeight, 
+                          *fPictureRecord.get(), deepCopyOps);
+        picture.playback(canvas);
     }
 }
diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
index 2de8d4d..8a16ea3 100644
--- a/src/core/SkPictureShader.cpp
+++ b/src/core/SkPictureShader.cpp
@@ -18,42 +18,57 @@
 #include "GrContext.h"
 #endif
 
-SkPictureShader::SkPictureShader(SkPicture* picture, TileMode tmx, TileMode tmy,
-                                 const SkMatrix* localMatrix)
+SkPictureShader::SkPictureShader(const SkPicture* picture, TileMode tmx, TileMode tmy,
+                                 const SkMatrix* localMatrix, const SkRect* tile)
     : INHERITED(localMatrix)
     , fPicture(SkRef(picture))
+    , fTile(tile ? *tile : picture->cullRect())
     , fTmx(tmx)
-    , fTmy(tmy) { }
+    , fTmy(tmy) {
+}
 
-SkPictureShader::SkPictureShader(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkPictureShader::SkPictureShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     fTmx = static_cast<SkShader::TileMode>(buffer.read32());
     fTmy = static_cast<SkShader::TileMode>(buffer.read32());
+    buffer.readRect(&fTile);
     fPicture = SkPicture::CreateFromBuffer(buffer);
 }
+#endif
 
 SkPictureShader::~SkPictureShader() {
     fPicture->unref();
 }
 
-SkPictureShader* SkPictureShader::Create(SkPicture* picture, TileMode tmx, TileMode tmy,
-                                         const SkMatrix* localMatrix) {
-    if (!picture || 0 == picture->width() || 0 == picture->height()) {
+SkPictureShader* SkPictureShader::Create(const SkPicture* picture, TileMode tmx, TileMode tmy,
+                                         const SkMatrix* localMatrix, const SkRect* tile) {
+    if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) {
         return NULL;
     }
-    return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy, localMatrix));
+    return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy, localMatrix, tile));
+}
+
+SkFlattenable* SkPictureShader::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix lm;
+    buffer.readMatrix(&lm);
+    TileMode mx = (TileMode)buffer.read32();
+    TileMode my = (TileMode)buffer.read32();
+    SkRect tile;
+    buffer.readRect(&tile);
+    SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromBuffer(buffer));
+    return SkPictureShader::Create(picture, mx, my, &lm, &tile);
 }
 
 void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
+    buffer.writeMatrix(this->getLocalMatrix());
     buffer.write32(fTmx);
     buffer.write32(fTmy);
+    buffer.writeRect(fTile);
     fPicture->flatten(buffer);
 }
 
 SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatrix* localM) const {
-    SkASSERT(fPicture && fPicture->width() > 0 && fPicture->height() > 0);
+    SkASSERT(fPicture && !fPicture->cullRect().isEmpty());
 
     SkMatrix m;
     m.setConcat(matrix, this->getLocalMatrix());
@@ -68,34 +83,41 @@
         scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.getSkewX()),
                   SkScalarSqrt(m.getScaleY() * m.getScaleY() + m.getSkewY() * m.getSkewY()));
     }
-    SkSize scaledSize = SkSize::Make(scale.x() * fPicture->width(), scale.y() * fPicture->height());
+    SkSize scaledSize = SkSize::Make(scale.x() * fTile.width(), scale.y() * fTile.height());
+
+    // Clamp the tile size to about 16M pixels
+    static const SkScalar kMaxTileArea = 4096 * 4096;
+    SkScalar tileArea = SkScalarMul(scaledSize.width(), scaledSize.height());
+    if (tileArea > kMaxTileArea) {
+        SkScalar clampScale = SkScalarSqrt(SkScalarDiv(kMaxTileArea, tileArea));
+        scaledSize.set(SkScalarMul(scaledSize.width(), clampScale),
+                       SkScalarMul(scaledSize.height(), clampScale));
+    }
 
     SkISize tileSize = scaledSize.toRound();
     if (tileSize.isEmpty()) {
         return NULL;
     }
 
-    // The actual scale, compensating for rounding.
-    SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fPicture->width(),
-                                    SkIntToScalar(tileSize.height()) / fPicture->height());
+    // The actual scale, compensating for rounding & clamping.
+    SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fTile.width(),
+                                    SkIntToScalar(tileSize.height()) / fTile.height());
 
     SkAutoMutexAcquire ama(fCachedBitmapShaderMutex);
 
-    // TODO(fmalita): remove fCachedLocalMatrix from this key after getLocalMatrix is removed.
-    if (!fCachedBitmapShader || tileScale != fCachedTileScale ||
-        this->getLocalMatrix() != fCachedLocalMatrix) {
+    if (!fCachedBitmapShader || tileScale != fCachedTileScale) {
         SkBitmap bm;
-        if (!bm.allocN32Pixels(tileSize.width(), tileSize.height())) {
+        if (!bm.tryAllocN32Pixels(tileSize.width(), tileSize.height())) {
             return NULL;
         }
         bm.eraseColor(SK_ColorTRANSPARENT);
 
         SkCanvas canvas(bm);
         canvas.scale(tileScale.width(), tileScale.height());
+        canvas.translate(fTile.x(), fTile.y());
         canvas.drawPicture(fPicture);
 
         fCachedTileScale = tileScale;
-        fCachedLocalMatrix = this->getLocalMatrix();
 
         SkMatrix shaderMatrix = this->getLocalMatrix();
         shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
@@ -177,9 +199,11 @@
         "clamp", "repeat", "mirror"
     };
 
-    str->appendf("PictureShader: [%d:%d] ",
-                 fPicture ? fPicture->width() : 0,
-                 fPicture ? fPicture->height() : 0);
+    str->appendf("PictureShader: [%f:%f:%f:%f] ",
+                 fPicture ? fPicture->cullRect().fLeft : 0,
+                 fPicture ? fPicture->cullRect().fTop : 0,
+                 fPicture ? fPicture->cullRect().fRight : 0,
+                 fPicture ? fPicture->cullRect().fBottom : 0);
 
     str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
 
@@ -188,19 +212,18 @@
 #endif
 
 #if SK_SUPPORT_GPU
-bool SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                  const SkMatrix* localMatrix, GrColor* grColor,
-                                  GrEffectRef** grEffect) const {
+bool SkPictureShader::asFragmentProcessor(GrContext* context, const SkPaint& paint,
+                                          const SkMatrix* localMatrix, GrColor* paintColor,
+                                          GrFragmentProcessor** fp) const {
     SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(context->getMatrix(), localMatrix));
     if (!bitmapShader) {
         return false;
     }
-    return bitmapShader->asNewEffect(context, paint, NULL, grColor, grEffect);
+    return bitmapShader->asFragmentProcessor(context, paint, NULL, paintColor, fp);
 }
 #else
-bool SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                  const SkMatrix* localMatrix, GrColor* grColor,
-                                  GrEffectRef** grEffect) const {
+bool SkPictureShader::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                          GrFragmentProcessor**) const {
     SkDEBUGFAIL("Should not call in GPU-less build");
     return false;
 }
diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h
index 294ffcd..24aa780 100644
--- a/src/core/SkPictureShader.h
+++ b/src/core/SkPictureShader.h
@@ -21,7 +21,8 @@
  */
 class SkPictureShader : public SkShader {
 public:
-    static SkPictureShader* Create(SkPicture*, TileMode, TileMode, const SkMatrix* = NULL);
+    static SkPictureShader* Create(const SkPicture*, TileMode, TileMode, const SkMatrix*,
+                                   const SkRect*);
     virtual ~SkPictureShader();
 
     virtual size_t contextSize() const SK_OVERRIDE;
@@ -29,8 +30,8 @@
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureShader)
 
-    bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor*, GrEffectRef**)
-        const SK_OVERRIDE;
+    bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                             GrFragmentProcessor**) const SK_OVERRIDE;
 
 protected:
     SkPictureShader(SkReadBuffer&);
@@ -38,17 +39,17 @@
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
-    SkPictureShader(SkPicture*, TileMode, TileMode, const SkMatrix* = NULL);
+    SkPictureShader(const SkPicture*, TileMode, TileMode, const SkMatrix*, const SkRect*);
 
     SkShader* refBitmapShader(const SkMatrix&, const SkMatrix* localMatrix) const;
 
-    SkPicture*  fPicture;
-    TileMode    fTmx, fTmy;
+    const SkPicture*  fPicture;
+    SkRect            fTile;
+    TileMode          fTmx, fTmy;
 
     mutable SkMutex                 fCachedBitmapShaderMutex;
     mutable SkAutoTUnref<SkShader>  fCachedBitmapShader;
     mutable SkSize                  fCachedTileScale;
-    mutable SkMatrix                fCachedLocalMatrix;
 
     class PictureShaderContext : public SkShader::Context {
     public:
diff --git a/src/core/SkPictureStateTree.cpp b/src/core/SkPictureStateTree.cpp
index fdd8646..704a04e 100644
--- a/src/core/SkPictureStateTree.cpp
+++ b/src/core/SkPictureStateTree.cpp
@@ -46,7 +46,7 @@
 }
 
 void SkPictureStateTree::saveCollapsed() {
-    SkASSERT(NULL != fLastRestoredNode);
+    SkASSERT(fLastRestoredNode);
     SkASSERT(SkToBool(fLastRestoredNode->fFlags & \
         (Node::kSaveLayer_Flag | Node::kSave_Flag)));
     SkASSERT(fLastRestoredNode->fParent == fCurrentState.fNode);
@@ -73,9 +73,10 @@
     this->appendNode(offset);
 }
 
-SkPictureStateTree::Iterator SkPictureStateTree::getIterator(const SkTDArray<void*>& draws,
-                                                             SkCanvas* canvas) {
-    return Iterator(draws, canvas, &fRoot);
+void SkPictureStateTree::initIterator(SkPictureStateTree::Iterator* iter,
+                                      const SkTDArray<void*>& draws,
+                                      SkCanvas* canvas) {
+    iter->init(draws, canvas, &fRoot);
 }
 
 void SkPictureStateTree::appendNode(size_t offset) {
@@ -88,19 +89,20 @@
     fCurrentState.fNode = n;
 }
 
-SkPictureStateTree::Iterator::Iterator(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root)
-    : fDraws(&draws)
-    , fCanvas(canvas)
-    , fCurrentNode(root)
-    , fPlaybackMatrix(canvas->getTotalMatrix())
-    , fCurrentMatrix(NULL)
-    , fPlaybackIndex(0)
-    , fSave(false)
-    , fValid(true) {
+void SkPictureStateTree::Iterator::init(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root) {
+    SkASSERT(!fValid);
+    fDraws = &draws;
+    fCanvas = canvas;
+    fCurrentNode = root;
+    fPlaybackMatrix = canvas->getTotalMatrix();
+    fCurrentMatrix = NULL;
+    fPlaybackIndex = 0;
+    fSave = false;
+    fValid = true;
 }
 
 void SkPictureStateTree::Iterator::setCurrentMatrix(const SkMatrix* matrix) {
-    SkASSERT(NULL != matrix);
+    SkASSERT(matrix);
 
     if (matrix == fCurrentMatrix) {
         return;
diff --git a/src/core/SkPictureStateTree.h b/src/core/SkPictureStateTree.h
index da51a5b..15bb02f 100644
--- a/src/core/SkPictureStateTree.h
+++ b/src/core/SkPictureStateTree.h
@@ -50,11 +50,13 @@
     Draw* appendDraw(size_t offset);
 
     /**
-     * Given a list of draws, and a canvas, returns an iterator that produces the correct sequence
-     * of offsets into the command buffer to carry out those calls with correct matrix/clip state.
-     * This handles saves/restores, and does all necessary matrix setup.
+     * Given a list of draws, and a canvas, initialize an iterator that produces the correct 
+     * sequence of offsets into the command buffer to carry out those calls with correct 
+     * matrix/clip state. This handles saves/restores, and does all necessary matrix setup.
      */
-    Iterator getIterator(const SkTDArray<void*>& draws, SkCanvas* canvas);
+    void initIterator(SkPictureStateTree::Iterator* iter, 
+                      const SkTDArray<void*>& draws, 
+                      SkCanvas* canvas);
 
     void appendSave();
     void appendSaveLayer(size_t offset);
@@ -83,11 +85,11 @@
         */
         uint32_t nextDraw();
         static const uint32_t kDrawComplete = SK_MaxU32;
-        Iterator() : fPlaybackMatrix(), fValid(false) { }
+        Iterator() : fValid(false) { }
         bool isValid() const { return fValid; }
 
     private:
-        Iterator(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root);
+        void init(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root);
 
         void setCurrentMatrix(const SkMatrix*);
 
@@ -104,7 +106,7 @@
         SkTDArray<Node*> fNodes;
 
         // The matrix of the canvas we're playing back into
-        const SkMatrix fPlaybackMatrix;
+        SkMatrix fPlaybackMatrix;
 
         // Cache of current matrix, so we can avoid redundantly setting it
         const SkMatrix* fCurrentMatrix;
diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp
index bfa4ae2..0aa00e0 100644
--- a/src/core/SkPixelRef.cpp
+++ b/src/core/SkPixelRef.cpp
@@ -1,13 +1,11 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "SkPixelRef.h"
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
 #include "SkThread.h"
 
 #ifdef SK_USE_POSIX_THREADS
@@ -83,7 +81,13 @@
 // just need a > 0 value, so pick a funny one to aid in debugging
 #define SKPIXELREF_PRELOCKED_LOCKCOUNT     123456789
 
-SkPixelRef::SkPixelRef(const SkImageInfo& info) : fInfo(info) {
+static SkImageInfo validate_info(const SkImageInfo& info) {
+    SkAlphaType newAlphaType = info.alphaType();
+    SkAssertResult(SkColorTypeValidateAlphaType(info.colorType(), info.alphaType(), &newAlphaType));
+    return info.makeAlphaType(newAlphaType);
+}
+
+SkPixelRef::SkPixelRef(const SkImageInfo& info) : fInfo(validate_info(info)) {
     this->setMutex(NULL);
     fRec.zero();
     fLockCount = 0;
@@ -93,7 +97,7 @@
 }
 
 
-SkPixelRef::SkPixelRef(const SkImageInfo& info, SkBaseMutex* mutex) : fInfo(info) {
+SkPixelRef::SkPixelRef(const SkImageInfo& info, SkBaseMutex* mutex) : fInfo(validate_info(info)) {
     this->setMutex(mutex);
     fRec.zero();
     fLockCount = 0;
@@ -102,25 +106,6 @@
     fPreLocked = false;
 }
 
-static SkImageInfo read_info(SkReadBuffer& buffer) {
-    SkImageInfo info;
-    info.unflatten(buffer);
-    return info;
-}
-
-SkPixelRef::SkPixelRef(SkReadBuffer& buffer, SkBaseMutex* mutex)
-        : INHERITED(buffer)
-        , fInfo(read_info(buffer))
-{
-    this->setMutex(mutex);
-    fRec.zero();
-    fLockCount = 0;
-    fIsImmutable = buffer.readBool();
-    fGenerationID = buffer.readUInt();
-    fUniqueGenerationID = false;  // Conservatively assuming the original still exists.
-    fPreLocked = false;
-}
-
 SkPixelRef::~SkPixelRef() {
     this->callGenIDChangeListeners();
 }
@@ -149,23 +134,6 @@
 #endif
 }
 
-void SkPixelRef::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-    fInfo.flatten(buffer);
-    buffer.writeBool(fIsImmutable);
-    // We write the gen ID into the picture for within-process recording. This
-    // is safe since the same genID will never refer to two different sets of
-    // pixels (barring overflow). However, each process has its own "namespace"
-    // of genIDs. So for cross-process recording we write a zero which will
-    // trigger assignment of a new genID in playback.
-    if (buffer.isCrossProcess()) {
-        buffer.writeUInt(0);
-    } else {
-        buffer.writeUInt(fGenerationID);
-        fUniqueGenerationID = false;  // Conservative, a copy is probably about to exist.
-    }
-}
-
 bool SkPixelRef::lockPixels(LockRec* rec) {
     SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount);
 
@@ -266,7 +234,7 @@
 }
 
 void SkPixelRef::changeAlphaType(SkAlphaType at) {
-    *const_cast<SkAlphaType*>(&fInfo.fAlphaType) = at;
+    *const_cast<SkImageInfo*>(&fInfo) = fInfo.makeAlphaType(at);
 }
 
 void SkPixelRef::setImmutable() {
@@ -285,6 +253,11 @@
     return NULL;
 }
 
+bool SkPixelRef::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+                                 SkYUVColorSpace* colorSpace) {
+    return false;
+}
+
 size_t SkPixelRef::getAllocatedSizeInBytes() const {
     return 0;
 }
diff --git a/src/core/SkPoint.cpp b/src/core/SkPoint.cpp
index 719ee54..5fee0e8 100644
--- a/src/core/SkPoint.cpp
+++ b/src/core/SkPoint.cpp
@@ -7,6 +7,7 @@
  */
 
 
+#include "SkMathPriv.h"
 #include "SkPoint.h"
 
 void SkIPoint::rotateCW(SkIPoint* dst) const {
@@ -168,7 +169,17 @@
         // divide by inf. and return (0,0) vector.
         double xx = x;
         double yy = y;
+    #ifdef SK_DISCARD_DENORMALIZED_FOR_SPEED
+        // The iOS ARM processor discards small denormalized numbers to go faster.
+        // Casting this to a float would cause the scale to go to zero. Keeping it
+        // as a double for the multiply keeps the scale non-zero.
+        double dscale = length / sqrt(xx * xx + yy * yy);
+        fX = x * dscale;
+        fY = y * dscale;
+        return true;
+    #else
         scale = (float)(length / sqrt(xx * xx + yy * yy));
+    #endif
     }
     fX = x * scale;
     fY = y * scale;
@@ -213,7 +224,7 @@
 
     SkScalar uLengthSqd = u.lengthSqd();
     SkScalar det = u.cross(v);
-    if (NULL != side) {
+    if (side) {
         SkASSERT(-1 == SkPoint::kLeft_Side &&
                   0 == SkPoint::kOn_Side &&
                   1 == kRight_Side);
diff --git a/src/core/SkPtrRecorder.h b/src/core/SkPtrRecorder.h
index 06e14ab..83200f5 100644
--- a/src/core/SkPtrRecorder.h
+++ b/src/core/SkPtrRecorder.h
@@ -58,6 +58,27 @@
      */
     void reset();
 
+    /**
+     * Set iterator.
+     */
+    class Iter {
+    public:
+        Iter(const SkPtrSet& set)
+            : fSet(set)
+            , fIndex(0) {}
+
+        /**
+         * Return the next ptr in the set or null if the end was reached.
+         */
+        void* next() {
+            return fIndex < fSet.fList.count() ? fSet.fList[fIndex++].fPtr : NULL;
+        }
+
+    private:
+        const SkPtrSet& fSet;
+        int             fIndex;
+    };
+
 protected:
     virtual void incPtr(void*) {}
     virtual void decPtr(void*) {}
diff --git a/src/core/SkQuadTree.cpp b/src/core/SkQuadTree.cpp
deleted file mode 100644
index a11613d..0000000
--- a/src/core/SkQuadTree.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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 "SkQuadTree.h"
-#include "SkTSort.h"
-#include <stdio.h>
-
-static const int kSplitThreshold = 8;
-
-enum {
-    kTopLeft,
-    kTopRight,
-    kBottomLeft,
-    kBottomRight,
-};
-enum {
-    kTopLeft_Bit = 1 << kTopLeft,
-    kTopRight_Bit = 1 << kTopRight,
-    kBottomLeft_Bit = 1 << kBottomLeft,
-    kBottomRight_Bit = 1 << kBottomRight,
-};
-enum {
-    kMaskLeft = kTopLeft_Bit | kBottomLeft_Bit,
-    kMaskRight = kTopRight_Bit | kBottomRight_Bit,
-    kMaskTop = kTopLeft_Bit | kTopRight_Bit,
-    kMaskBottom = kBottomLeft_Bit | kBottomRight_Bit,
-};
-
-static U8CPU child_intersect(const SkIRect& query, const SkIPoint& split) {
-    // fast quadrant test
-    U8CPU intersect = 0xf;
-    if (query.fRight <  split.fX) {
-        intersect &= ~kMaskRight;
-    } else if(query.fLeft >= split.fX) {
-        intersect &= ~kMaskLeft;
-    }
-    if (query.fBottom < split.fY) {
-        intersect &= ~kMaskBottom;
-    } else if(query.fTop >= split.fY) {
-        intersect &= ~kMaskTop;
-    }
-    return intersect;
-}
-
-SkQuadTree::SkQuadTree(const SkIRect& bounds) : fRoot(NULL) {
-    SkASSERT((bounds.width() * bounds.height()) > 0);
-    fRootBounds = bounds;
-}
-
-SkQuadTree::~SkQuadTree() {
-}
-
-void SkQuadTree::insert(Node* node, Entry* entry) {
-    // does it belong in a child?
-    if (NULL != node->fChildren[0]) {
-        switch(child_intersect(entry->fBounds, node->fSplitPoint)) {
-            case kTopLeft_Bit:
-                this->insert(node->fChildren[kTopLeft], entry);
-                return;
-            case kTopRight_Bit:
-                this->insert(node->fChildren[kTopRight], entry);
-                return;
-            case kBottomLeft_Bit:
-                this->insert(node->fChildren[kBottomLeft], entry);
-                return;
-            case kBottomRight_Bit:
-                this->insert(node->fChildren[kBottomRight], entry);
-                return;
-            default:
-                node->fEntries.push(entry);
-                return;
-        }
-    }
-    // No children yet, add to this node
-    node->fEntries.push(entry);
-    // should I split?
-    if (node->fEntries.getCount() > kSplitThreshold) {
-        this->split(node);
-    }
-}
-
-void SkQuadTree::split(Node* node) {
-    // Build all the children
-    node->fSplitPoint = SkIPoint::Make(node->fBounds.centerX(),
-                                       node->fBounds.centerY());
-    for(int index=0; index<kChildCount; ++index) {
-        node->fChildren[index] = fNodePool.acquire();
-    }
-    node->fChildren[0]->fBounds = SkIRect::MakeLTRB(
-        node->fBounds.fLeft,    node->fBounds.fTop,
-        node->fSplitPoint.fX,   node->fSplitPoint.fY);
-    node->fChildren[1]->fBounds = SkIRect::MakeLTRB(
-        node->fSplitPoint.fX,   node->fBounds.fTop,
-        node->fBounds.fRight,   node->fSplitPoint.fY);
-    node->fChildren[2]->fBounds = SkIRect::MakeLTRB(
-        node->fBounds.fLeft,    node->fSplitPoint.fY,
-        node->fSplitPoint.fX,   node->fBounds.fBottom);
-    node->fChildren[3]->fBounds = SkIRect::MakeLTRB(
-        node->fSplitPoint.fX,   node->fSplitPoint.fY,
-        node->fBounds.fRight,   node->fBounds.fBottom);
-    // reinsert all the entries of this node to allow child trickle
-    SkTInternalSList<Entry> entries;
-    entries.pushAll(&node->fEntries);
-    while(!entries.isEmpty()) {
-        this->insert(node, entries.pop());
-    }
-}
-
-void SkQuadTree::search(Node* node, const SkIRect& query,
-                        SkTDArray<void*>* results) const {
-    for (Entry* entry = node->fEntries.head(); NULL != entry;
-        entry = entry->getSListNext()) {
-        if (SkIRect::IntersectsNoEmptyCheck(entry->fBounds, query)) {
-            results->push(entry->fData);
-        }
-    }
-    if (NULL == node->fChildren[0]) {
-        return;
-    }
-    U8CPU intersect = child_intersect(query, node->fSplitPoint);
-    for(int index=0; index<kChildCount; ++index) {
-        if (intersect & (1 << index)) {
-            this->search(node->fChildren[index], query, results);
-        }
-    }
-}
-
-void SkQuadTree::clear(Node* node) {
-    // first clear the entries of this node
-    fEntryPool.releaseAll(&node->fEntries);
-    // recurse into and clear all child nodes
-    for(int index=0; index<kChildCount; ++index) {
-        Node* child = node->fChildren[index];
-        node->fChildren[index] = NULL;
-        if (NULL != child) {
-            this->clear(child);
-            fNodePool.release(child);
-        }
-    }
-}
-
-int SkQuadTree::getDepth(Node* node) const {
-    int maxDepth = 0;
-    if (NULL != node) {
-        for(int index=0; index<kChildCount; ++index) {
-            maxDepth = SkMax32(maxDepth, getDepth(node->fChildren[index]));
-        }
-    }
-    return maxDepth + 1;
-}
-
-void SkQuadTree::insert(void* data, const SkIRect& bounds, bool) {
-    if (bounds.isEmpty()) {
-        SkASSERT(false);
-        return;
-    }
-    Entry* entry = fEntryPool.acquire();
-    entry->fData = data;
-    entry->fBounds = bounds;
-    if (NULL == fRoot) {
-        fDeferred.push(entry);
-    } else {
-        this->insert(fRoot, entry);
-    }
-}
-
-void SkQuadTree::search(const SkIRect& query, SkTDArray<void*>* results) {
-    SkASSERT(NULL != fRoot);
-    SkASSERT(NULL != results);
-    if (SkIRect::Intersects(fRootBounds, query)) {
-        this->search(fRoot, query, results);
-    }
-}
-
-void SkQuadTree::clear() {
-    this->flushDeferredInserts();
-    if (NULL != fRoot) {
-        this->clear(fRoot);
-        fNodePool.release(fRoot);
-        fRoot = NULL;
-    }
-    SkASSERT(fEntryPool.allocated() == fEntryPool.available());
-    SkASSERT(fNodePool.allocated() == fNodePool.available());
-}
-
-int SkQuadTree::getDepth() const {
-    return this->getDepth(fRoot);
-}
-
-void SkQuadTree::rewindInserts() {
-    SkASSERT(fClient);
-     // Currently only supports deferred inserts
-    SkASSERT(NULL == fRoot);
-    SkTInternalSList<Entry> entries;
-    entries.pushAll(&fDeferred);
-    while(!entries.isEmpty()) {
-        Entry* entry = entries.pop();
-        if (fClient->shouldRewind(entry->fData)) {
-            entry->fData = NULL;
-            fEntryPool.release(entry);
-        } else {
-            fDeferred.push(entry);
-        }
-    }
-}
-
-void SkQuadTree::flushDeferredInserts() {
-    if (NULL == fRoot) {
-        fRoot = fNodePool.acquire();
-        fRoot->fBounds = fRootBounds;
-    }
-    while(!fDeferred.isEmpty()) {
-        this->insert(fRoot, fDeferred.pop());
-    }
-}
diff --git a/src/core/SkQuadTree.h b/src/core/SkQuadTree.h
deleted file mode 100644
index bf1bc8e..0000000
--- a/src/core/SkQuadTree.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkQuadTree_DEFINED
-#define SkQuadTree_DEFINED
-
-#include "SkRect.h"
-#include "SkTDArray.h"
-#include "SkBBoxHierarchy.h"
-#include "SkTInternalSList.h"
-#include "SkTObjectPool.h"
-
-/**
- * A QuadTree implementation. In short, it is a tree containing a hierarchy of bounding rectangles
- * in which each internal node has exactly four children.
- *
- * For more details see:
- *
- * http://en.wikipedia.org/wiki/Quadtree
- */
-class SkQuadTree : public SkBBoxHierarchy {
-public:
-    SK_DECLARE_INST_COUNT(SkQuadTree)
-
-    /**
-     * Quad tree constructor.
-     * @param bounds The bounding box for the root of the quad tree.
-     *               giving the quad tree bounds that fall outside the root
-     *               bounds may result in pathological but correct behavior.
-     */
-    SkQuadTree(const SkIRect& bounds);
-
-    virtual ~SkQuadTree();
-
-    /**
-     * Insert a node, consisting of bounds and a data value into the tree, if we don't immediately
-     * need to use the tree; we may allow the insert to be deferred (this can allow us to bulk-load
-     * a large batch of nodes at once, which tends to be faster and produce a better tree).
-     *  @param data The data value
-     *  @param bounds The corresponding bounding box
-     *  @param defer Can this insert be deferred? (this may be ignored)
-     */
-    virtual void insert(void* data, const SkIRect& bounds, bool defer = false) SK_OVERRIDE;
-
-    /**
-     * If any inserts have been deferred, this will add them into the tree
-     */
-    virtual void flushDeferredInserts() SK_OVERRIDE;
-
-    /**
-     * Given a query rectangle, populates the passed-in array with the elements it intersects
-     */
-    virtual void search(const SkIRect& query, SkTDArray<void*>* results) SK_OVERRIDE;
-
-    virtual void clear() SK_OVERRIDE;
-
-    /**
-     * Gets the depth of the tree structure
-     */
-    virtual int getDepth() const SK_OVERRIDE;
-
-    /**
-     * This gets the insertion count (rather than the node count)
-     */
-    virtual int getCount() const SK_OVERRIDE {
-        return fEntryPool.allocated() - fEntryPool.available();
-    }
-
-    virtual void rewindInserts() SK_OVERRIDE;
-
-private:
-    struct Entry {
-        Entry() : fData(NULL) {}
-        SkIRect fBounds;
-        void* fData;
-        SK_DECLARE_INTERNAL_SLIST_INTERFACE(Entry);
-    };
-
-    static const int kChildCount = 4;
-
-    struct Node {
-        Node() {
-            for (int index=0; index<kChildCount; ++index) {
-                fChildren[index] = NULL;
-            }
-        }
-        SkTInternalSList<Entry> fEntries;
-        SkIRect fBounds;
-        SkIPoint fSplitPoint; // Only valid if the node has children.
-        Node* fChildren[kChildCount];
-        SK_DECLARE_INTERNAL_SLIST_ADAPTER(Node, fChildren[0]);
-    };
-
-    SkTObjectPool<Entry> fEntryPool;
-    SkTObjectPool<Node> fNodePool;
-    Node* fRoot;
-    SkIRect fRootBounds;
-    SkTInternalSList<Entry> fDeferred;
-
-    void insert(Node* node, Entry* entry);
-    void split(Node* node);
-    void search(Node* node, const SkIRect& query, SkTDArray<void*>* results) const;
-    void clear(Node* node);
-    int getDepth(Node* node) const;
-
-    typedef SkBBoxHierarchy INHERITED;
-};
-
-#endif
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp
index 9bb6725..10d3d76 100644
--- a/src/core/SkRRect.cpp
+++ b/src/core/SkRRect.cpp
@@ -342,6 +342,19 @@
     // At this point, this is guaranteed to succeed, so we can modify dst.
     dst->fRect = newRect;
 
+    // Since the only transforms that were allowed are scale and translate, the type
+    // remains unchanged.
+    dst->fType = fType;
+
+    if (kOval_Type == fType) {
+        for (int i = 0; i < 4; ++i) {
+            dst->fRadii[i].fX = SkScalarHalf(newRect.width());
+            dst->fRadii[i].fY = SkScalarHalf(newRect.height());
+        }
+        SkDEBUGCODE(dst->validate();)
+        return true;
+    }
+
     // Now scale each corner
     SkScalar xScale = matrix.getScaleX();
     const bool flipX = xScale < 0;
@@ -377,10 +390,6 @@
         SkTSwap(dst->fRadii[kUpperRight_Corner], dst->fRadii[kLowerRight_Corner]);
     }
 
-    // Since the only transforms that were allowed are scale and translate, the type
-    // remains unchanged.
-    dst->fType = fType;
-
     SkDEBUGCODE(dst->validate();)
 
     return true;
diff --git a/src/core/SkRTree.cpp b/src/core/SkRTree.cpp
index fe08437..17872ba 100644
--- a/src/core/SkRTree.cpp
+++ b/src/core/SkRTree.cpp
@@ -44,7 +44,14 @@
     this->clear();
 }
 
-void SkRTree::insert(void* data, const SkIRect& bounds, bool defer) {
+void SkRTree::insert(void* data, const SkRect& fbounds, bool defer) {
+    SkIRect bounds;
+    if (fbounds.isLargest()) {
+        bounds.setLargest();
+    } else {
+        fbounds.roundOut(&bounds);
+    }
+
     this->validate();
     if (bounds.isEmpty()) {
         SkASSERT(false);
@@ -68,7 +75,7 @@
     Branch* newSibling = insert(fRoot.fChild.subtree, &newBranch);
     fRoot.fBounds = this->computeBounds(fRoot.fChild.subtree);
 
-    if (NULL != newSibling) {
+    if (newSibling) {
         Node* oldRoot = fRoot.fChild.subtree;
         Node* newRoot = this->allocateNode(oldRoot->fLevel + 1);
         newRoot->fNumChildren = 2;
@@ -102,11 +109,11 @@
     this->validate();
 }
 
-void SkRTree::search(const SkIRect& query, SkTDArray<void*>* results) {
+void SkRTree::search(const SkRect& fquery, SkTDArray<void*>* results) const {
+    SkIRect query;
+    fquery.roundOut(&query);
     this->validate();
-    if (0 != fDeferredInserts.count()) {
-        this->flushDeferredInserts();
-    }
+    SkASSERT(0 == fDeferredInserts.count());  // If this fails, you should have flushed.
     if (!this->isEmpty() && SkIRect::IntersectsNoEmptyCheck(fRoot.fBounds, query)) {
         this->search(fRoot.fChild.subtree, query, results);
     }
@@ -136,7 +143,7 @@
         root->child(childIndex)->fBounds = this->computeBounds(
             root->child(childIndex)->fChild.subtree);
     }
-    if (NULL != toInsert) {
+    if (toInsert) {
         if (root->fNumChildren == fMaxChildren) {
             // handle overflow by splitting. TODO: opportunistic reinsertion
 
@@ -399,7 +406,7 @@
     }
 }
 
-void SkRTree::validate() {
+void SkRTree::validate() const {
 #ifdef SK_DEBUG
     if (this->isEmpty()) {
         return;
@@ -408,7 +415,7 @@
 #endif
 }
 
-int SkRTree::validateSubtree(Node* root, SkIRect bounds, bool isRoot) {
+int SkRTree::validateSubtree(Node* root, SkIRect bounds, bool isRoot) const {
     // make sure the pointer is pointing to a valid place
     SkASSERT(fNodes.contains(static_cast<void*>(root)));
 
diff --git a/src/core/SkRTree.h b/src/core/SkRTree.h
index d21b5f8..8e98024 100644
--- a/src/core/SkRTree.h
+++ b/src/core/SkRTree.h
@@ -67,7 +67,7 @@
      *  @param bounds The corresponding bounding box
      *  @param defer Can this insert be deferred? (this may be ignored)
      */
-    virtual void insert(void* data, const SkIRect& bounds, bool defer = false) SK_OVERRIDE;
+    virtual void insert(void* data, const SkRect& bounds, bool defer = false) SK_OVERRIDE;
 
     /**
      * If any inserts have been deferred, this will add them into the tree
@@ -77,7 +77,7 @@
     /**
      * Given a query rectangle, populates the passed-in array with the elements it intersects
      */
-    virtual void search(const SkIRect& query, SkTDArray<void*>* results) SK_OVERRIDE;
+    virtual void search(const SkRect& query, SkTDArray<void*>* results) const SK_OVERRIDE;
 
     virtual void clear() SK_OVERRIDE;
     bool isEmpty() const { return 0 == fCount; }
@@ -177,8 +177,8 @@
      */
     Branch bulkLoad(SkTDArray<Branch>* branches, int level = 0);
 
-    void validate();
-    int validateSubtree(Node* root, SkIRect bounds, bool isRoot = false);
+    void validate() const;
+    int validateSubtree(Node* root, SkIRect bounds, bool isRoot = false) const;
 
     const int fMinChildren;
     const int fMaxChildren;
diff --git a/src/core/SkRasterClip.cpp b/src/core/SkRasterClip.cpp
index 664211f..f820c5a 100644
--- a/src/core/SkRasterClip.cpp
+++ b/src/core/SkRasterClip.cpp
@@ -6,18 +6,12 @@
  */
 
 #include "SkRasterClip.h"
-
-
-SkRasterClip::SkRasterClip() {
-    fIsBW = true;
-    fIsEmpty = true;
-    fIsRect = false;
-    SkDEBUGCODE(this->validate();)
-}
+#include "SkPath.h"
 
 SkRasterClip::SkRasterClip(const SkRasterClip& src) {
     AUTO_RASTERCLIP_VALIDATE(src);
 
+    fForceConservativeRects = src.fForceConservativeRects;
     fIsBW = src.fIsBW;
     if (fIsBW) {
         fBW = src.fBW;
@@ -30,13 +24,22 @@
     SkDEBUGCODE(this->validate();)
 }
 
-SkRasterClip::SkRasterClip(const SkIRect& bounds) : fBW(bounds) {
+SkRasterClip::SkRasterClip(const SkIRect& bounds, bool forceConservativeRects) : fBW(bounds) {
+    fForceConservativeRects = forceConservativeRects;
     fIsBW = true;
     fIsEmpty = this->computeIsEmpty();  // bounds might be empty, so compute
     fIsRect = !fIsEmpty;
     SkDEBUGCODE(this->validate();)
 }
 
+SkRasterClip::SkRasterClip(bool forceConservativeRects) {
+    fForceConservativeRects = forceConservativeRects;
+    fIsBW = true;
+    fIsEmpty = true;
+    fIsRect = false;
+    SkDEBUGCODE(this->validate();)
+}
+
 SkRasterClip::~SkRasterClip() {
     SkDEBUGCODE(this->validate();)
 }
@@ -70,9 +73,84 @@
     return fIsRect;
 }
 
+/////////////////////////////////////////////////////////////////////////////////////
+
+bool SkRasterClip::setConservativeRect(const SkRect& r, const SkIRect& clipR, bool isInverse) {
+    SkIRect ir;
+    r.roundOut(&ir);
+
+    SkRegion::Op op;
+    if (isInverse) {
+        op = SkRegion::kDifference_Op;
+    } else {
+        op = SkRegion::kIntersect_Op;
+    }
+    fBW.setRect(clipR);
+    fBW.op(ir, op);
+    return this->updateCacheAndReturnNonEmpty();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+enum MutateResult {
+    kDoNothing_MutateResult,
+    kReplaceClippedAgainstGlobalBounds_MutateResult,
+    kContinue_MutateResult,
+};
+
+static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) {
+    if (inverseFilled) {
+        switch (*op) {
+            case SkRegion::kIntersect_Op:
+            case SkRegion::kDifference_Op:
+                // These ops can only shrink the current clip. So leaving
+                // the clip unchanged conservatively respects the contract.
+                return kDoNothing_MutateResult;
+            case SkRegion::kUnion_Op:
+            case SkRegion::kReplace_Op:
+            case SkRegion::kReverseDifference_Op:
+            case SkRegion::kXOR_Op: {
+                // These ops can grow the current clip up to the extents of
+                // the input clip, which is inverse filled, so we just set
+                // the current clip to the device bounds.
+                *op = SkRegion::kReplace_Op;
+                return kReplaceClippedAgainstGlobalBounds_MutateResult;
+            }
+        }
+    } else {
+        // Not inverse filled
+        switch (*op) {
+            case SkRegion::kIntersect_Op:
+            case SkRegion::kUnion_Op:
+            case SkRegion::kReplace_Op:
+                return kContinue_MutateResult;
+            case SkRegion::kDifference_Op:
+                // Difference can only shrink the current clip.
+                // Leaving clip unchanged conservatively fullfills the contract.
+                return kDoNothing_MutateResult;
+            case SkRegion::kReverseDifference_Op:
+                // To reverse, we swap in the bounds with a replace op.
+                // As with difference, leave it unchanged.
+                *op = SkRegion::kReplace_Op;
+                return kContinue_MutateResult;
+            case SkRegion::kXOR_Op:
+                // Be conservative, based on (A XOR B) always included in (A union B),
+                // which is always included in (bounds(A) union bounds(B))
+                *op = SkRegion::kUnion_Op;
+                return kContinue_MutateResult;
+        }
+    }
+    SkFAIL("should not get here");
+    return kDoNothing_MutateResult;
+}
+
 bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) {
     AUTO_RASTERCLIP_VALIDATE(*this);
 
+    if (fForceConservativeRects) {
+        return this->setConservativeRect(path.getBounds(), clip.getBounds(), path.isInverseFillType());
+    }
+
     if (this->isBW() && !doAA) {
         (void)fBW.setPath(path, clip);
     } else {
@@ -86,6 +164,54 @@
     return this->updateCacheAndReturnNonEmpty();
 }
 
+bool SkRasterClip::op(const SkPath& path, const SkISize& size, SkRegion::Op op, bool doAA) {
+    // base is used to limit the size (and therefore memory allocation) of the
+    // region that results from scan converting devPath.
+    SkRegion base;
+
+    if (fForceConservativeRects) {
+        SkIRect ir;
+        switch (mutate_conservative_op(&op, path.isInverseFillType())) {
+            case kDoNothing_MutateResult:
+                return !this->isEmpty();
+            case kReplaceClippedAgainstGlobalBounds_MutateResult:
+                ir = SkIRect::MakeSize(size);
+                break;
+            case kContinue_MutateResult:
+                path.getBounds().roundOut(&ir);
+                break;
+        }
+        return this->op(ir, op);
+    }
+
+    if (SkRegion::kIntersect_Op == op) {
+        // since we are intersect, we can do better (tighter) with currRgn's
+        // bounds, than just using the device. However, if currRgn is complex,
+        // our region blitter may hork, so we do that case in two steps.
+        if (this->isRect()) {
+            // FIXME: we should also be able to do this when this->isBW(),
+            // but relaxing the test above triggers GM asserts in
+            // SkRgnBuilder::blitH(). We need to investigate what's going on.
+            return this->setPath(path, this->bwRgn(), doAA);
+        } else {
+            base.setRect(this->getBounds());
+            SkRasterClip clip(fForceConservativeRects);
+            clip.setPath(path, base, doAA);
+            return this->op(clip, op);
+        }
+    } else {
+        base.setRect(0, 0, size.width(), size.height());
+        
+        if (SkRegion::kReplace_Op == op) {
+            return this->setPath(path, base, doAA);
+        } else {
+            SkRasterClip clip(fForceConservativeRects);
+            clip.setPath(path, base, doAA);
+            return this->op(clip, op);
+        }
+    }
+}
+
 bool SkRasterClip::setPath(const SkPath& path, const SkIRect& clip, bool doAA) {
     SkRegion tmp;
     tmp.setRect(clip);
@@ -149,9 +275,24 @@
     return x - SkScalarFloorToScalar(x) < domain;
 }
 
-bool SkRasterClip::op(const SkRect& r, SkRegion::Op op, bool doAA) {
+bool SkRasterClip::op(const SkRect& r, const SkISize& size, SkRegion::Op op, bool doAA) {
     AUTO_RASTERCLIP_VALIDATE(*this);
 
+    if (fForceConservativeRects) {
+        SkIRect ir;
+        switch (mutate_conservative_op(&op, false)) {
+            case kDoNothing_MutateResult:
+                return !this->isEmpty();
+            case kReplaceClippedAgainstGlobalBounds_MutateResult:
+                ir = SkIRect::MakeSize(size);
+                break;
+            case kContinue_MutateResult:
+                r.roundOut(&ir);
+                break;
+        }
+        return this->op(ir, op);
+    }
+    
     if (fIsBW && doAA) {
         // check that the rect really needs aa, or is it close enought to
         // integer boundaries that we can just treat it as a BW rect?
@@ -218,11 +359,16 @@
 
 void SkRasterClip::convertToAA() {
     AUTO_RASTERCLIP_VALIDATE(*this);
-
+    
+    SkASSERT(!fForceConservativeRects);
+    
     SkASSERT(fIsBW);
     fAA.setRegion(fBW);
     fIsBW = false;
-    (void)this->updateCacheAndReturnNonEmpty();
+    
+    // since we are being explicitly asked to convert-to-aa, we pass false so we don't "optimize"
+    // ourselves back to BW.
+    (void)this->updateCacheAndReturnNonEmpty(false);
 }
 
 #ifdef SK_DEBUG
diff --git a/src/core/SkRasterClip.h b/src/core/SkRasterClip.h
index 0c27233..8a06818 100644
--- a/src/core/SkRasterClip.h
+++ b/src/core/SkRasterClip.h
@@ -13,11 +13,13 @@
 
 class SkRasterClip {
 public:
-    SkRasterClip();
-    SkRasterClip(const SkIRect&);
+    SkRasterClip(bool forceConservativeRects = false);
+    SkRasterClip(const SkIRect&, bool forceConservativeRects = false);
     SkRasterClip(const SkRasterClip&);
     ~SkRasterClip();
 
+    bool isForceConservativeRects() const { return fForceConservativeRects; }
+
     bool isBW() const { return fIsBW; }
     bool isAA() const { return !fIsBW; }
     const SkRegion& bwRgn() const { SkASSERT(fIsBW); return fBW; }
@@ -39,14 +41,11 @@
     bool setEmpty();
     bool setRect(const SkIRect&);
 
-    bool setPath(const SkPath& path, const SkRegion& clip, bool doAA);
-    bool setPath(const SkPath& path, const SkIRect& clip, bool doAA);
-
     bool op(const SkIRect&, SkRegion::Op);
     bool op(const SkRegion&, SkRegion::Op);
-    bool op(const SkRasterClip&, SkRegion::Op);
-    bool op(const SkRect&, SkRegion::Op, bool doAA);
-
+    bool op(const SkRect&, const SkISize&, SkRegion::Op, bool doAA);
+    bool op(const SkPath&, const SkISize&, SkRegion::Op, bool doAA);
+    
     void translate(int dx, int dy, SkRasterClip* dst) const;
     void translate(int dx, int dy) {
         this->translate(dx, dy, this);
@@ -63,8 +62,7 @@
      *  intersect, but returning true is a guarantee that they do not.
      */
     bool quickReject(const SkIRect& rect) const {
-        return this->isEmpty() || rect.isEmpty() ||
-               !SkIRect::Intersects(this->getBounds(), rect);
+        return !SkIRect::Intersects(this->getBounds(), rect);
     }
 
     // hack for SkCanvas::getTotalClip
@@ -79,6 +77,7 @@
 private:
     SkRegion    fBW;
     SkAAClip    fAA;
+    bool        fForceConservativeRects;
     bool        fIsBW;
     // these 2 are caches based on querying the right obj based on fIsBW
     bool        fIsEmpty;
@@ -89,16 +88,29 @@
     }
 
     bool computeIsRect() const {
-        return fIsBW ? fBW.isRect() : false;
+        return fIsBW ? fBW.isRect() : fAA.isRect();
     }
 
-    bool updateCacheAndReturnNonEmpty() {
+    bool updateCacheAndReturnNonEmpty(bool detectAARect = true) {
         fIsEmpty = this->computeIsEmpty();
+
+        // detect that our computed AA is really just a (hard-edged) rect
+        if (detectAARect && !fIsEmpty && !fIsBW && fAA.isRect()) {
+            fBW.setRect(fAA.getBounds());
+            fAA.setEmpty(); // don't need this guy anymore
+            fIsBW = true;
+        }
+
         fIsRect = this->computeIsRect();
         return !fIsEmpty;
     }
 
     void convertToAA();
+
+    bool setPath(const SkPath& path, const SkRegion& clip, bool doAA);
+    bool setPath(const SkPath& path, const SkIRect& clip, bool doAA);
+    bool op(const SkRasterClip&, SkRegion::Op);
+    bool setConservativeRect(const SkRect& r, const SkIRect& clipR, bool isInverse);
 };
 
 class SkAutoRasterClipValidate : SkNoncopyable {
diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp
index cacf989..4358786 100644
--- a/src/core/SkReadBuffer.cpp
+++ b/src/core/SkReadBuffer.cpp
@@ -14,9 +14,7 @@
 
 static uint32_t default_flags() {
     uint32_t flags = 0;
-#ifdef SK_SCALAR_IS_FLOAT
     flags |= SkReadBuffer::kScalarIsFloat_Flag;
-#endif
     if (8 == sizeof(void*)) {
         flags |= SkReadBuffer::kPtrIs64Bit_Flag;
     }
diff --git a/include/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
similarity index 97%
rename from include/core/SkReadBuffer.h
rename to src/core/SkReadBuffer.h
index b792be3..a5b9830 100644
--- a/include/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -17,7 +17,6 @@
 #include "SkPath.h"
 #include "SkPathEffect.h"
 #include "SkPicture.h"
-#include "SkPixelRef.h"
 #include "SkRasterizer.h"
 #include "SkReadBuffer.h"
 #include "SkReader32.h"
@@ -46,6 +45,10 @@
         kColorShaderNoBool_Version         = 26,
         kNoUnitMappers_Version             = 27,
         kNoMoreBitmapFlatten_Version       = 28,
+        kSimplifyLocalMatrix_Version       = 30,
+        kImageFilterUniqueID_Version       = 31,
+        kRemoveAndroidPaintOpts_Version    = 32,
+        kFlattenCreateProc_Version         = 33,
     };
 
     /**
@@ -107,6 +110,7 @@
     virtual void readIRect(SkIRect* rect);
     virtual void readRect(SkRect* rect);
     virtual void readRegion(SkRegion* region);
+    
     virtual void readPath(SkPath* path);
     void readPaint(SkPaint* paint) { paint->unflatten(*this); }
 
@@ -119,7 +123,6 @@
     SkImageFilter* readImageFilter() { return this->readFlattenable<SkImageFilter>(); }
     SkMaskFilter*  readMaskFilter()  { return this->readFlattenable<SkMaskFilter>(); }
     SkPathEffect*  readPathEffect()  { return this->readFlattenable<SkPathEffect>(); }
-    SkPixelRef*    readPixelRef()    { return this->readFlattenable<SkPixelRef>(); }
     SkRasterizer*  readRasterizer()  { return this->readFlattenable<SkRasterizer>(); }
     SkShader*      readShader()      { return this->readFlattenable<SkShader>(); }
     SkXfermode*    readXfermode()    { return this->readFlattenable<SkXfermode>(); }
diff --git a/include/core/SkReader32.h b/src/core/SkReader32.h
similarity index 95%
rename from include/core/SkReader32.h
rename to src/core/SkReader32.h
index 51e28ef..3d874d1 100644
--- a/include/core/SkReader32.h
+++ b/src/core/SkReader32.h
@@ -107,19 +107,19 @@
     uint32_t readU32() { return this->readInt(); }
 
     bool readPath(SkPath* path) {
-        return readObjectFromMemory(path);
+        return this->readObjectFromMemory(path);
     }
 
     bool readMatrix(SkMatrix* matrix) {
-        return readObjectFromMemory(matrix);
+        return this->readObjectFromMemory(matrix);
     }
 
     bool readRRect(SkRRect* rrect) {
-        return readObjectFromMemory(rrect);
+        return this->readObjectFromMemory(rrect);
     }
 
     bool readRegion(SkRegion* rgn) {
-        return readObjectFromMemory(rgn);
+        return this->readObjectFromMemory(rgn);
     }
 
     /**
diff --git a/src/core/SkRecord.h b/src/core/SkRecord.h
index 6c5177e..5362d91 100644
--- a/src/core/SkRecord.h
+++ b/src/core/SkRecord.h
@@ -26,9 +26,12 @@
 // get this wrong.
 
 class SkRecord : SkNoncopyable {
+    enum {
+        kChunkBytes = 4096,
+        kFirstReserveCount = 64 / sizeof(void*),
+    };
 public:
-    SkRecord(size_t chunkBytes = 4096, unsigned firstReserveCount = 64 / sizeof(void*))
-        : fAlloc(chunkBytes), fCount(0), fReserved(0), kFirstReserveCount(firstReserveCount) {}
+    SkRecord() : fAlloc(kChunkBytes), fCount(0), fReserved(0) {}
 
     ~SkRecord() {
         Destroyer destroyer;
@@ -64,8 +67,9 @@
     // Allocate contiguous space for count Ts, to be freed when the SkRecord is destroyed.
     // Here T can be any class, not just those from SkRecords.  Throws on failure.
     template <typename T>
-    T* alloc(unsigned count = 1) {
-        return (T*)fAlloc.allocThrow(sizeof(T) * count);
+    T* alloc(size_t count = 1) {
+        // Bump up to the next pointer width if needed, so all allocations start pointer-aligned.
+        return (T*)fAlloc.allocThrow(SkAlignPtr(sizeof(T) * count));
     }
 
     // Add a new command of type T to the end of this SkRecord.
@@ -73,7 +77,7 @@
     template <typename T>
     T* append() {
         if (fCount == fReserved) {
-            fReserved = SkTMax(kFirstReserveCount, fReserved*2);
+            fReserved = SkTMax<unsigned>(kFirstReserveCount, fReserved*2);
             fRecords.realloc(fReserved);
             fTypes.realloc(fReserved);
         }
@@ -220,7 +224,7 @@
     // chunks, returning a stable handle to that data for later retrieval.
     //
     // fRecords and fTypes need to be data structures that can append fixed length data, and need to
-    // support efficient forward iteration.  (They don't need to be contiguous or indexable.)
+    // support efficient random access and forward iteration.  (They don't need to be contiguous.)
 
     SkChunkAlloc fAlloc;
     SkAutoTMalloc<Record> fRecords;
@@ -228,7 +232,6 @@
     // fCount and fReserved measure both fRecords and fTypes, which always grow in lock step.
     unsigned fCount;
     unsigned fReserved;
-    const unsigned kFirstReserveCount;
 };
 
 #endif//SkRecord_DEFINED
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 2bf7076..c693b05 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -6,25 +6,64 @@
  */
 
 #include "SkRecordDraw.h"
+#include "SkPatchUtils.h"
 
-void SkRecordDraw(const SkRecord& record, SkCanvas* canvas) {
-    for (SkRecords::Draw draw(canvas); draw.index() < record.count(); draw.next()) {
-        record.visit<void>(draw.index(), draw);
+void SkRecordDraw(const SkRecord& record,
+                  SkCanvas* canvas,
+                  const SkBBoxHierarchy* bbh,
+                  SkDrawPictureCallback* callback) {
+    SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
+
+    if (bbh) {
+        // Draw only ops that affect pixels in the canvas's current clip.
+        // The SkRecord and BBH were recorded in identity space.  This canvas
+        // is not necessarily in that same space.  getClipBounds() returns us
+        // this canvas' clip bounds transformed back into identity space, which
+        // lets us query the BBH.
+        SkRect query = { 0, 0, 0, 0 };
+        (void)canvas->getClipBounds(&query);
+
+        SkTDArray<void*> ops;
+        bbh->search(query, &ops);
+
+        SkRecords::Draw draw(canvas);
+        for (int i = 0; i < ops.count(); i++) {
+            if (callback && callback->abortDrawing()) {
+                return;
+            }
+            record.visit<void>((uintptr_t)ops[i], draw);  // See FillBounds below.
+        }
+    } else {
+        // Draw all ops.
+        SkRecords::Draw draw(canvas);
+        for (unsigned i = 0; i < record.count(); i++) {
+            if (callback && callback->abortDrawing()) {
+                return;
+            }
+            record.visit<void>(i, draw);
+        }
+    }
+}
+
+void SkRecordPartialDraw(const SkRecord& record,
+                         SkCanvas* canvas,
+                         const SkRect& clearRect,
+                         unsigned start, unsigned stop,
+                         const SkMatrix& initialCTM) {
+    SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
+
+    stop = SkTMin(stop, record.count());
+    SkRecords::PartialDraw draw(canvas, clearRect, initialCTM);
+    for (unsigned i = start; i < stop; i++) {
+        record.visit<void>(i, draw);
     }
 }
 
 namespace SkRecords {
 
-bool Draw::skip(const PairedPushCull& r) {
-    if (fCanvas->quickReject(r.base->rect)) {
-        fIndex += r.skip;
-        return true;
-    }
-    return false;
-}
-
-bool Draw::skip(const BoundedDrawPosTextH& r) {
-    return fCanvas->quickRejectY(r.minY, r.maxY);
+// FIXME: SkBitmaps are stateful, so we need to copy them to play back in multiple threads.
+static SkBitmap shallow_copy(const SkBitmap& bitmap) {
+    return bitmap;
 }
 
 // NoOps draw nothing.
@@ -32,12 +71,11 @@
 
 #define DRAW(T, call) template <> void Draw::draw(const T& r) { fCanvas->call; }
 DRAW(Restore, restore());
-DRAW(Save, save(r.flags));
+DRAW(Save, save());
 DRAW(SaveLayer, saveLayer(r.bounds, r.paint, r.flags));
 DRAW(PopCull, popCull());
 DRAW(PushCull, pushCull(r.rect));
 DRAW(Clear, clear(r.color));
-DRAW(Concat, concat(r.matrix));
 DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix)));
 
 DRAW(ClipPath, clipPath(r.path, r.op, r.doAA));
@@ -45,27 +83,466 @@
 DRAW(ClipRect, clipRect(r.rect, r.op, r.doAA));
 DRAW(ClipRegion, clipRegion(r.region, r.op));
 
-DRAW(DrawBitmap, drawBitmap(r.bitmap, r.left, r.top, r.paint));
-DRAW(DrawBitmapMatrix, drawBitmapMatrix(r.bitmap, r.matrix, r.paint));
-DRAW(DrawBitmapNine, drawBitmapNine(r.bitmap, r.center, r.dst, r.paint));
-DRAW(DrawBitmapRectToRect, drawBitmapRectToRect(r.bitmap, r.src, r.dst, r.paint, r.flags));
+DRAW(BeginCommentGroup, beginCommentGroup(r.description));
+DRAW(AddComment, addComment(r.key, r.value));
+DRAW(EndCommentGroup, endCommentGroup());
+
+DRAW(DrawBitmap, drawBitmap(shallow_copy(r.bitmap), r.left, r.top, r.paint));
+DRAW(DrawBitmapMatrix, drawBitmapMatrix(shallow_copy(r.bitmap), r.matrix, r.paint));
+DRAW(DrawBitmapNine, drawBitmapNine(shallow_copy(r.bitmap), r.center, r.dst, r.paint));
+DRAW(DrawBitmapRectToRect,
+        drawBitmapRectToRect(shallow_copy(r.bitmap), r.src, r.dst, r.paint, r.flags));
 DRAW(DrawDRRect, drawDRRect(r.outer, r.inner, r.paint));
 DRAW(DrawOval, drawOval(r.oval, r.paint));
 DRAW(DrawPaint, drawPaint(r.paint));
 DRAW(DrawPath, drawPath(r.path, r.paint));
+DRAW(DrawPatch, drawPatch(r.cubics, r.colors, r.texCoords, r.xmode, r.paint));
+DRAW(DrawPicture, drawPicture(r.picture, r.matrix, r.paint));
 DRAW(DrawPoints, drawPoints(r.mode, r.count, r.pts, r.paint));
 DRAW(DrawPosText, drawPosText(r.text, r.byteLength, r.pos, r.paint));
 DRAW(DrawPosTextH, drawPosTextH(r.text, r.byteLength, r.xpos, r.y, r.paint));
 DRAW(DrawRRect, drawRRect(r.rrect, r.paint));
 DRAW(DrawRect, drawRect(r.rect, r.paint));
-DRAW(DrawSprite, drawSprite(r.bitmap, r.left, r.top, r.paint));
+DRAW(DrawSprite, drawSprite(shallow_copy(r.bitmap), r.left, r.top, r.paint));
 DRAW(DrawText, drawText(r.text, r.byteLength, r.x, r.y, r.paint));
+DRAW(DrawTextBlob, drawTextBlob(r.blob, r.x, r.y, r.paint));
 DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, r.matrix, r.paint));
 DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.colors,
                                 r.xmode.get(), r.indices, r.indexCount, r.paint));
+DRAW(DrawData, drawData(r.data, r.length));
 #undef DRAW
 
-template <> void Draw::draw(const PairedPushCull& r) { this->draw(*r.base); }
-template <> void Draw::draw(const BoundedDrawPosTextH& r) { this->draw(*r.base); }
+
+// This is an SkRecord visitor that fills an SkBBoxHierarchy.
+//
+// The interesting part here is how to calculate bounds for ops which don't
+// have intrinsic bounds.  What is the bounds of a Save or a Translate?
+//
+// We answer this by thinking about a particular definition of bounds: if I
+// don't execute this op, pixels in this rectangle might draw incorrectly.  So
+// the bounds of a Save, a Translate, a Restore, etc. are the union of the
+// bounds of Draw* ops that they might have an effect on.  For any given
+// Save/Restore block, the bounds of the Save, the Restore, and any other
+// non-drawing ("control") ops inside are exactly the union of the bounds of
+// the drawing ops inside that block.
+//
+// To implement this, we keep a stack of active Save blocks.  As we consume ops
+// inside the Save/Restore block, drawing ops are unioned with the bounds of
+// the block, and control ops are stashed away for later.  When we finish the
+// block with a Restore, our bounds are complete, and we go back and fill them
+// in for all the control ops we stashed away.
+class FillBounds : SkNoncopyable {
+public:
+    FillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) : fBounds(record.count()) {
+        // Calculate bounds for all ops.  This won't go quite in order, so we'll need
+        // to store the bounds separately then feed them in to the BBH later in order.
+        const Bounds largest = Bounds::MakeLargest();
+        fCTM = &SkMatrix::I();
+        fCurrentClipBounds = largest;
+        for (fCurrentOp = 0; fCurrentOp < record.count(); fCurrentOp++) {
+            record.visit<void>(fCurrentOp, *this);
+        }
+
+        // If we have any lingering unpaired Saves, simulate restores to make
+        // sure all ops in those Save blocks have their bounds calculated.
+        while (!fSaveStack.isEmpty()) {
+            this->popSaveBlock();
+        }
+
+        // Any control ops not part of any Save/Restore block draw everywhere.
+        while (!fControlIndices.isEmpty()) {
+            this->popControl(largest);
+        }
+
+        // Finally feed all stored bounds into the BBH.  They'll be returned in this order.
+        SkASSERT(bbh);
+        for (uintptr_t i = 0; i < record.count(); i++) {
+            if (!fBounds[i].isEmpty()) {
+                bbh->insert((void*)i, fBounds[i], true/*ok to defer*/);
+            }
+        }
+        bbh->flushDeferredInserts();
+    }
+
+    template <typename T> void operator()(const T& op) {
+        this->updateCTM(op);
+        this->updateClipBounds(op);
+        this->trackBounds(op);
+    }
+
+private:
+    // In this file, SkRect are in local coordinates, Bounds are translated back to identity space.
+    typedef SkRect Bounds;
+
+    struct SaveBounds {
+        int controlOps;        // Number of control ops in this Save block, including the Save.
+        Bounds bounds;         // Bounds of everything in the block.
+        const SkPaint* paint;  // Unowned.  If set, adjusts the bounds of all ops in this block.
+    };
+
+    // Only Restore and SetMatrix change the CTM.
+    template <typename T> void updateCTM(const T&) {}
+    void updateCTM(const Restore& op)   { fCTM = &op.matrix; }
+    void updateCTM(const SetMatrix& op) { fCTM = &op.matrix; }
+
+    // Most ops don't change the clip.
+    template <typename T> void updateClipBounds(const T&) {}
+
+    // Clip{Path,RRect,Rect,Region} obviously change the clip.  They all know their bounds already.
+    void updateClipBounds(const ClipPath&   op) { this->updateClipBoundsForClipOp(op.devBounds); }
+    void updateClipBounds(const ClipRRect&  op) { this->updateClipBoundsForClipOp(op.devBounds); }
+    void updateClipBounds(const ClipRect&   op) { this->updateClipBoundsForClipOp(op.devBounds); }
+    void updateClipBounds(const ClipRegion& op) { this->updateClipBoundsForClipOp(op.devBounds); }
+
+    // The bounds of clip ops need to be adjusted for the paints of saveLayers they're inside.
+    void updateClipBoundsForClipOp(const SkIRect& devBounds) {
+        Bounds clip = SkRect::Make(devBounds);
+        // We don't call adjustAndMap() because as its last step it would intersect the adjusted
+        // clip bounds with the previous clip, exactly what we can't do when the clip grows.
+        fCurrentClipBounds = this->adjustForSaveLayerPaints(&clip) ? clip : Bounds::MakeLargest();
+    }
+
+    // Restore holds the devBounds for the clip after the {save,saveLayer}/restore block completes.
+    void updateClipBounds(const Restore& op) {
+        // This is just like the clip ops above, but we need to skip the effects (if any) of our
+        // paired saveLayer (if it is one); it has not yet been popped off the save stack.  Our
+        // devBounds reflect the state of the world after the saveLayer/restore block is done,
+        // so they are not affected by the saveLayer's paint.
+        const int kSavesToIgnore = 1;
+        Bounds clip = SkRect::Make(op.devBounds);
+        fCurrentClipBounds =
+            this->adjustForSaveLayerPaints(&clip, kSavesToIgnore) ? clip : Bounds::MakeLargest();
+    }
+
+    // We also take advantage of SaveLayer bounds when present to further cut the clip down.
+    void updateClipBounds(const SaveLayer& op)  {
+        if (op.bounds) {
+            // adjustAndMap() intersects these layer bounds with the previous clip for us.
+            fCurrentClipBounds = this->adjustAndMap(*op.bounds, op.paint);
+        }
+    }
+
+    // The bounds of these ops must be calculated when we hit the Restore
+    // from the bounds of the ops in the same Save block.
+    void trackBounds(const Save&)          { this->pushSaveBlock(NULL); }
+    void trackBounds(const SaveLayer& op)  { this->pushSaveBlock(op.paint); }
+    void trackBounds(const Restore&) { fBounds[fCurrentOp] = this->popSaveBlock(); }
+
+    void trackBounds(const SetMatrix&)         { this->pushControl(); }
+    void trackBounds(const ClipRect&)          { this->pushControl(); }
+    void trackBounds(const ClipRRect&)         { this->pushControl(); }
+    void trackBounds(const ClipPath&)          { this->pushControl(); }
+    void trackBounds(const ClipRegion&)        { this->pushControl(); }
+    void trackBounds(const PushCull&)          { this->pushControl(); }
+    void trackBounds(const PopCull&)           { this->pushControl(); }
+    void trackBounds(const BeginCommentGroup&) { this->pushControl(); }
+    void trackBounds(const AddComment&)        { this->pushControl(); }
+    void trackBounds(const EndCommentGroup&)   { this->pushControl(); }
+    void trackBounds(const DrawData&)          { this->pushControl(); }
+
+    // For all other ops, we can calculate and store the bounds directly now.
+    template <typename T> void trackBounds(const T& op) {
+        fBounds[fCurrentOp] = this->bounds(op);
+        this->updateSaveBounds(fBounds[fCurrentOp]);
+    }
+
+    void pushSaveBlock(const SkPaint* paint) {
+        // Starting a new Save block.  Push a new entry to represent that.
+        SaveBounds sb = { 0, Bounds::MakeEmpty(), paint };
+        fSaveStack.push(sb);
+        this->pushControl();
+    }
+
+    static bool PaintMayAffectTransparentBlack(const SkPaint* paint) {
+        if (paint) {
+            // FIXME: this is very conservative
+            if (paint->getImageFilter() || paint->getColorFilter()) {
+                return true;
+            }
+
+            // Unusual Xfermodes require us to process a saved layer
+            // even with operations outisde the clip.
+            // For example, DstIn is used by masking layers.
+            // https://code.google.com/p/skia/issues/detail?id=1291
+            // https://crbug.com/401593
+            SkXfermode* xfermode = paint->getXfermode();
+            SkXfermode::Mode mode;
+            // SrcOver is ok, and is also the common case with a NULL xfermode.
+            // So we should make that the fast path and bypass the mode extraction
+            // and test.
+            if (xfermode && xfermode->asMode(&mode)) {
+                switch (mode) {
+                    // For each of the following transfer modes, if the source
+                    // alpha is zero (our transparent black), the resulting
+                    // blended alpha is not necessarily equal to the original
+                    // destination alpha.
+                    case SkXfermode::kClear_Mode:
+                    case SkXfermode::kSrc_Mode:
+                    case SkXfermode::kSrcIn_Mode:
+                    case SkXfermode::kDstIn_Mode:
+                    case SkXfermode::kSrcOut_Mode:
+                    case SkXfermode::kDstATop_Mode:
+                    case SkXfermode::kModulate_Mode:
+                        return true;
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        return false;
+    }
+
+    Bounds popSaveBlock() {
+        // We're done the Save block.  Apply the block's bounds to all control ops inside it.
+        SaveBounds sb;
+        fSaveStack.pop(&sb);
+
+        // If the paint affects transparent black, we can't trust any of our calculated bounds.
+        const Bounds& bounds =
+            PaintMayAffectTransparentBlack(sb.paint) ? fCurrentClipBounds : sb.bounds;
+
+        while (sb.controlOps --> 0) {
+            this->popControl(bounds);
+        }
+
+        // This whole Save block may be part another Save block.
+        this->updateSaveBounds(bounds);
+
+        // If called from a real Restore (not a phony one for balance), it'll need the bounds.
+        return bounds;
+    }
+
+    void pushControl() {
+        fControlIndices.push(fCurrentOp);
+        if (!fSaveStack.isEmpty()) {
+            fSaveStack.top().controlOps++;
+        }
+    }
+
+    void popControl(const Bounds& bounds) {
+        fBounds[fControlIndices.top()] = bounds;
+        fControlIndices.pop();
+    }
+
+    void updateSaveBounds(const Bounds& bounds) {
+        // If we're in a Save block, expand its bounds to cover these bounds too.
+        if (!fSaveStack.isEmpty()) {
+            fSaveStack.top().bounds.join(bounds);
+        }
+    }
+
+    // FIXME: this method could use better bounds
+    Bounds bounds(const DrawText&) const { return fCurrentClipBounds; }
+
+    Bounds bounds(const Clear&) const { return Bounds::MakeLargest(); }  // Ignores the clip.
+    Bounds bounds(const DrawPaint&) const { return fCurrentClipBounds; }
+    Bounds bounds(const NoOp&)  const { return Bounds::MakeEmpty(); }    // NoOps don't draw.
+
+    Bounds bounds(const DrawSprite& op) const {
+        const SkBitmap& bm = op.bitmap;
+        return Bounds::MakeXYWH(op.left, op.top, bm.width(), bm.height());  // Ignores the matrix.
+    }
+
+    Bounds bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); }
+    Bounds bounds(const DrawOval& op) const { return this->adjustAndMap(op.oval, &op.paint); }
+    Bounds bounds(const DrawRRect& op) const {
+        return this->adjustAndMap(op.rrect.rect(), &op.paint);
+    }
+    Bounds bounds(const DrawDRRect& op) const {
+        return this->adjustAndMap(op.outer.rect(), &op.paint);
+    }
+
+    Bounds bounds(const DrawBitmapRectToRect& op) const {
+        return this->adjustAndMap(op.dst, op.paint);
+    }
+    Bounds bounds(const DrawBitmapNine& op) const {
+        return this->adjustAndMap(op.dst, op.paint);
+    }
+    Bounds bounds(const DrawBitmap& op) const {
+        const SkBitmap& bm = op.bitmap;
+        return this->adjustAndMap(SkRect::MakeXYWH(op.left, op.top, bm.width(), bm.height()),
+                                  op.paint);
+    }
+    Bounds bounds(const DrawBitmapMatrix& op) const {
+        const SkBitmap& bm = op.bitmap;
+        SkRect dst = SkRect::MakeWH(bm.width(), bm.height());
+        op.matrix.mapRect(&dst);
+        return this->adjustAndMap(dst, op.paint);
+    }
+
+    Bounds bounds(const DrawPath& op) const {
+        return op.path.isInverseFillType() ? fCurrentClipBounds
+                                           : this->adjustAndMap(op.path.getBounds(), &op.paint);
+    }
+    Bounds bounds(const DrawPoints& op) const {
+        SkRect dst;
+        dst.set(op.pts, op.count);
+
+        // Pad the bounding box a little to make sure hairline points' bounds aren't empty.
+        SkScalar stroke = SkMaxScalar(op.paint.getStrokeWidth(), 0.01f);
+        dst.outset(stroke/2, stroke/2);
+
+        return this->adjustAndMap(dst, &op.paint);
+    }
+    Bounds bounds(const DrawPatch& op) const {
+        SkRect dst;
+        dst.set(op.cubics, SkPatchUtils::kNumCtrlPts);
+        return this->adjustAndMap(dst, &op.paint);
+    }
+    Bounds bounds(const DrawVertices& op) const {
+        SkRect dst;
+        dst.set(op.vertices, op.vertexCount);
+        return this->adjustAndMap(dst, &op.paint);
+    }
+
+    Bounds bounds(const DrawPicture& op) const {
+        SkRect dst = op.picture->cullRect();
+        if (op.matrix) {
+            op.matrix->mapRect(&dst);
+        }
+        return this->adjustAndMap(dst, op.paint);
+    }
+
+    Bounds bounds(const DrawPosText& op) const {
+        const int N = op.paint.countText(op.text, op.byteLength);
+        if (N == 0) {
+            return Bounds::MakeEmpty();
+        }
+
+        SkRect dst;
+        dst.set(op.pos, N);
+        AdjustTextForFontMetrics(&dst, op.paint);
+        return this->adjustAndMap(dst, &op.paint);
+    }
+    Bounds bounds(const DrawPosTextH& op) const {
+        const int N = op.paint.countText(op.text, op.byteLength);
+        if (N == 0) {
+            return Bounds::MakeEmpty();
+        }
+
+        SkScalar left = op.xpos[0], right = op.xpos[0];
+        for (int i = 1; i < N; i++) {
+            left  = SkMinScalar(left,  op.xpos[i]);
+            right = SkMaxScalar(right, op.xpos[i]);
+        }
+        SkRect dst = { left, op.y, right, op.y };
+        AdjustTextForFontMetrics(&dst, op.paint);
+        return this->adjustAndMap(dst, &op.paint);
+    }
+    Bounds bounds(const DrawTextOnPath& op) const {
+        SkRect dst = op.path.getBounds();
+
+        // Pad all sides by the maximum padding in any direction we'd normally apply.
+        SkRect pad = { 0, 0, 0, 0};
+        AdjustTextForFontMetrics(&pad, op.paint);
+
+        // That maximum padding happens to always be the right pad today.
+        SkASSERT(pad.fLeft == -pad.fRight);
+        SkASSERT(pad.fTop  == -pad.fBottom);
+        SkASSERT(pad.fRight > pad.fBottom);
+        dst.outset(pad.fRight, pad.fRight);
+
+        return this->adjustAndMap(dst, &op.paint);
+    }
+
+    Bounds bounds(const DrawTextBlob& op) const {
+        SkRect dst = op.blob->bounds();
+        dst.offset(op.x, op.y);
+        // TODO: remove when implicit bounds are plumbed through
+        if (dst.isEmpty()) {
+            return fCurrentClipBounds;
+        }
+        return this->adjustAndMap(dst, &op.paint);
+    }
+
+    static void AdjustTextForFontMetrics(SkRect* rect, const SkPaint& paint) {
+#ifdef SK_DEBUG
+        SkRect correct = *rect;
+#endif
+        const SkScalar yPad = 2.0f * paint.getTextSize(),  // In practice, this seems to be enough.
+                       xPad = 4.0f * yPad;                 // Hack for very wide Github logo font.
+        rect->outset(xPad, yPad);
+#ifdef SK_DEBUG
+        SkPaint::FontMetrics metrics;
+        paint.getFontMetrics(&metrics);
+        correct.fLeft   += metrics.fXMin;
+        correct.fTop    += metrics.fTop;
+        correct.fRight  += metrics.fXMax;
+        correct.fBottom += metrics.fBottom;
+        // See skia:2862 for why we ignore small text sizes.
+        SkASSERTF(paint.getTextSize() < 0.001f || rect->contains(correct),
+                  "%f %f %f %f vs. %f %f %f %f\n",
+                  -xPad, -yPad, +xPad, +yPad,
+                  metrics.fXMin, metrics.fTop, metrics.fXMax, metrics.fBottom);
+#endif
+    }
+
+    // Returns true if rect was meaningfully adjusted for the effects of paint,
+    // false if the paint could affect the rect in unknown ways.
+    static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) {
+        if (paint) {
+            if (paint->canComputeFastBounds()) {
+                *rect = paint->computeFastBounds(*rect, rect);
+                return true;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    bool adjustForSaveLayerPaints(SkRect* rect, int savesToIgnore = 0) const {
+        for (int i = fSaveStack.count() - 1 - savesToIgnore; i >= 0; i--) {
+            if (!AdjustForPaint(fSaveStack[i].paint, rect)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // Adjust rect for all paints that may affect its geometry, then map it to identity space.
+    Bounds adjustAndMap(SkRect rect, const SkPaint* paint) const {
+        // Inverted rectangles really confuse our BBHs.
+        rect.sort();
+
+        // Adjust the rect for its own paint.
+        if (!AdjustForPaint(paint, &rect)) {
+            // The paint could do anything to our bounds.  The only safe answer is the current clip.
+            return fCurrentClipBounds;
+        }
+
+        // Adjust rect for all the paints from the SaveLayers we're inside.
+        if (!this->adjustForSaveLayerPaints(&rect)) {
+            // Same deal as above.
+            return fCurrentClipBounds;
+        }
+
+        // Map the rect back to identity space.
+        fCTM->mapRect(&rect);
+
+        // Nothing can draw outside the current clip.
+        // (Only bounded ops call into this method, so oddballs like Clear don't matter here.)
+        rect.intersect(fCurrentClipBounds);
+        return rect;
+    }
+
+    // Conservative identity-space bounds for each op in the SkRecord.
+    SkAutoTMalloc<Bounds> fBounds;
+
+    // We walk fCurrentOp through the SkRecord, as we go using updateCTM()
+    // and updateClipBounds() to maintain the exact CTM (fCTM) and conservative
+    // identity-space bounds of the current clip (fCurrentClipBounds).
+    unsigned fCurrentOp;
+    const SkMatrix* fCTM;
+    Bounds fCurrentClipBounds;
+
+    // Used to track the bounds of Save/Restore blocks and the control ops inside them.
+    SkTDArray<SaveBounds> fSaveStack;
+    SkTDArray<unsigned>   fControlIndices;
+};
 
 }  // namespace SkRecords
+
+void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) {
+    SkRecords::FillBounds(record, bbh);
+}
diff --git a/src/core/SkRecordDraw.h b/src/core/SkRecordDraw.h
index 359679a..75921d1 100644
--- a/src/core/SkRecordDraw.h
+++ b/src/core/SkRecordDraw.h
@@ -8,46 +8,67 @@
 #ifndef SkRecordDraw_DEFINED
 #define SkRecordDraw_DEFINED
 
-#include "SkRecord.h"
+#include "SkBBoxHierarchy.h"
 #include "SkCanvas.h"
+#include "SkDrawPictureCallback.h"
+#include "SkMatrix.h"
+#include "SkRecord.h"
+
+// Fill a BBH to be used by SkRecordDraw to accelerate playback.
+void SkRecordFillBounds(const SkRecord&, SkBBoxHierarchy*);
 
 // Draw an SkRecord into an SkCanvas.  A convenience wrapper around SkRecords::Draw.
-void SkRecordDraw(const SkRecord&, SkCanvas*);
+void SkRecordDraw(const SkRecord&, SkCanvas*, const SkBBoxHierarchy*, SkDrawPictureCallback*);
+
+// Draw a portion of an SkRecord into an SkCanvas while replacing clears with drawRects.
+// When drawing a portion of an SkRecord the CTM on the passed in canvas must be
+// the composition of the replay matrix with the record-time CTM (for the portion
+// of the record that is being replayed). For setMatrix calls to behave correctly
+// the initialCTM parameter must set to just the replay matrix.
+void SkRecordPartialDraw(const SkRecord&, SkCanvas*, const SkRect&, unsigned start, unsigned stop,
+                         const SkMatrix& initialCTM);
 
 namespace SkRecords {
 
 // This is an SkRecord visitor that will draw that SkRecord to an SkCanvas.
 class Draw : SkNoncopyable {
 public:
-    explicit Draw(SkCanvas* canvas)
-        : fInitialCTM(canvas->getTotalMatrix()), fCanvas(canvas), fIndex(0) {}
-
-    unsigned index() const { return fIndex; }
-    void next() { ++fIndex; }
+    explicit Draw(SkCanvas* canvas, const SkMatrix* initialCTM = NULL)
+        : fInitialCTM(initialCTM ? *initialCTM : canvas->getTotalMatrix())
+        , fCanvas(canvas) {}
 
     template <typename T> void operator()(const T& r) {
-        if (!this->skip(r)) {
-            this->draw(r);
-        }
+        this->draw(r);
     }
 
 private:
     // No base case, so we'll be compile-time checked that we implement all possibilities.
     template <typename T> void draw(const T&);
 
-    // skip() should return true if we can skip this command, false if not.
-    // It may update fIndex directly to skip more than just this one command.
-
-    // Mostly we just blindly call fCanvas and let it handle quick rejects itself.
-    template <typename T> bool skip(const T&) { return false; }
-
-    // We add our own quick rejects for commands added by optimizations.
-    bool skip(const PairedPushCull&);
-    bool skip(const BoundedDrawPosTextH&);
-
     const SkMatrix fInitialCTM;
     SkCanvas* fCanvas;
-    unsigned fIndex;
+};
+
+// Used by SkRecordPartialDraw.
+class PartialDraw : public Draw {
+public:
+    PartialDraw(SkCanvas* canvas, const SkRect& clearRect, const SkMatrix& initialCTM)
+        : INHERITED(canvas, &initialCTM), fClearRect(clearRect) {}
+
+    // Same as Draw for all ops except Clear.
+    template <typename T> void operator()(const T& r) {
+        this->INHERITED::operator()(r);
+    }
+    void operator()(const Clear& c) {
+        SkPaint p;
+        p.setColor(c.color);
+        DrawRect drawRect(p, fClearRect);
+        this->INHERITED::operator()(drawRect);
+    }
+
+private:
+    const SkRect fClearRect;
+    typedef Draw INHERITED;
 };
 
 }  // namespace SkRecords
diff --git a/src/core/SkRecordOpts.cpp b/src/core/SkRecordOpts.cpp
index 75f7c62..7c24a08 100644
--- a/src/core/SkRecordOpts.cpp
+++ b/src/core/SkRecordOpts.cpp
@@ -14,15 +14,13 @@
 using namespace SkRecords;
 
 void SkRecordOptimize(SkRecord* record) {
-    // TODO(mtklein): fuse independent optimizations to reduce number of passes?
-    SkRecordNoopCulls(record);
-    SkRecordNoopSaveRestores(record);
-    // TODO(mtklein): figure out why we draw differently and reenable
-    //SkRecordNoopSaveLayerDrawRestores(record);
+    // This might be useful  as a first pass in the future if we want to weed
+    // out junk for other optimization passes.  Right now, nothing needs it,
+    // and the bounding box hierarchy will do the work of skipping no-op
+    // Save-NoDraw-Restore sequences better than we can here.
+    //SkRecordNoopSaveRestores(record);
 
-    SkRecordAnnotateCullingPairs(record);
-    SkRecordReduceDrawPosTextStrength(record);  // Helpful to run this before BoundDrawPosTextH.
-    SkRecordBoundDrawPosTextH(record);
+    SkRecordNoopSaveLayerDrawRestores(record);
 }
 
 // Most of the optimizations in this file are pattern-based.  These are all defined as structs with:
@@ -45,21 +43,6 @@
     return changed;
 }
 
-struct CullNooper {
-    typedef Pattern3<Is<PushCull>, Star<Is<NoOp> >, Is<PopCull> > Pattern;
-
-    bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned end) {
-        record->replace<NoOp>(begin);  // PushCull
-        record->replace<NoOp>(end-1);  // PopCull
-        return true;
-    }
-};
-
-void SkRecordNoopCulls(SkRecord* record) {
-    CullNooper pass;
-    while (apply(&pass, record));
-}
-
 // Turns the logical NoOp Save and Restore in Save-Draw*-Restore patterns into actual NoOps.
 struct SaveOnlyDrawsRestoreNooper {
     typedef Pattern3<Is<Save>,
@@ -76,19 +59,16 @@
 // Turns logical no-op Save-[non-drawing command]*-Restore patterns into actual no-ops.
 struct SaveNoDrawsRestoreNooper {
     // Star matches greedily, so we also have to exclude Save and Restore.
+    // Nested SaveLayers need to be excluded, or we'll match their Restore!
     typedef Pattern3<Is<Save>,
-                     Star<Not<Or3<Is<Save>,
+                     Star<Not<Or4<Is<Save>,
+                                  Is<SaveLayer>,
                                   Is<Restore>,
                                   IsDraw> > >,
                      Is<Restore> >
         Pattern;
 
     bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned end) {
-        // If restore doesn't revert both matrix and clip, this isn't safe to noop away.
-        if (pattern->first<Save>()->flags != SkCanvas::kMatrixClip_SaveFlag) {
-            return false;
-        }
-
         // The entire span between Save and Restore (inclusively) does nothing.
         for (unsigned i = begin; i < end; i++) {
             record->replace<NoOp>(i);
@@ -171,133 +151,3 @@
     apply(&pass, record);
 }
 
-
-// Replaces DrawPosText with DrawPosTextH when all Y coordinates are equal.
-struct StrengthReducer {
-    typedef Pattern1<Is<DrawPosText> > Pattern;
-
-    bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned end) {
-        SkASSERT(end == begin + 1);
-        DrawPosText* draw = pattern->first<DrawPosText>();
-
-        const unsigned points = draw->paint.countText(draw->text, draw->byteLength);
-        if (points == 0) {
-            return false;  // No point (ha!).
-        }
-
-        const SkScalar firstY = draw->pos[0].fY;
-        for (unsigned i = 1; i < points; i++) {
-            if (draw->pos[i].fY != firstY) {
-                return false;  // Needs full power of DrawPosText.
-            }
-        }
-        // All ys are the same.  We can replace DrawPosText with DrawPosTextH.
-
-        // draw->pos is points SkPoints, [(x,y),(x,y),(x,y),(x,y), ... ].
-        // We're going to squint and look at that as 2*points SkScalars, [x,y,x,y,x,y,x,y, ...].
-        // Then we'll rearrange things so all the xs are in order up front, clobbering the ys.
-        SK_COMPILE_ASSERT(sizeof(SkPoint) == 2 * sizeof(SkScalar), SquintingIsNotSafe);
-        SkScalar* scalars = &draw->pos[0].fX;
-        for (unsigned i = 0; i < 2*points; i += 2) {
-            scalars[i/2] = scalars[i];
-        }
-
-        // Extend lifetime of draw to the end of the loop so we can copy its paint.
-        Adopted<DrawPosText> adopted(draw);
-        SkNEW_PLACEMENT_ARGS(record->replace<DrawPosTextH>(begin, adopted),
-                             DrawPosTextH,
-                             (draw->paint, draw->text, draw->byteLength, scalars, firstY));
-        return true;
-    }
-};
-void SkRecordReduceDrawPosTextStrength(SkRecord* record) {
-    StrengthReducer pass;
-    apply(&pass, record);
-}
-
-// Tries to replace DrawPosTextH with BoundedDrawPosTextH, which knows conservative upper and lower
-// bounds to use with SkCanvas::quickRejectY.
-struct TextBounder {
-    typedef Pattern1<Is<DrawPosTextH> > Pattern;
-
-    bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned end) {
-        SkASSERT(end == begin + 1);
-        DrawPosTextH* draw = pattern->first<DrawPosTextH>();
-
-        // If we're drawing vertical text, none of the checks we're about to do make any sense.
-        // We'll need to call SkPaint::computeFastBounds() later, so bail if that's not possible.
-        if (draw->paint.isVerticalText() || !draw->paint.canComputeFastBounds()) {
-            return false;
-        }
-
-        // Rather than checking the top and bottom font metrics, we guess.  Actually looking up the
-        // top and bottom metrics is slow, and this overapproximation should be good enough.
-        const SkScalar buffer = draw->paint.getTextSize() * 1.5f;
-        SkDEBUGCODE(SkPaint::FontMetrics metrics;)
-        SkDEBUGCODE(draw->paint.getFontMetrics(&metrics);)
-        SkASSERT(-buffer <= metrics.fTop);
-        SkASSERT(+buffer >= metrics.fBottom);
-
-        // Let the paint adjust the text bounds.  We don't care about left and right here, so we use
-        // 0 and 1 respectively just so the bounds rectangle isn't empty.
-        SkRect bounds;
-        bounds.set(0, draw->y - buffer, SK_Scalar1, draw->y + buffer);
-        SkRect adjusted = draw->paint.computeFastBounds(bounds, &bounds);
-
-        Adopted<DrawPosTextH> adopted(draw);
-        SkNEW_PLACEMENT_ARGS(record->replace<BoundedDrawPosTextH>(begin, adopted),
-                             BoundedDrawPosTextH,
-                             (&adopted, adjusted.fTop, adjusted.fBottom));
-        return true;
-    }
-};
-void SkRecordBoundDrawPosTextH(SkRecord* record) {
-    TextBounder pass;
-    apply(&pass, record);
-}
-
-// Replaces PushCull with PairedPushCull, which lets us skip to the paired PopCull when the canvas
-// can quickReject the cull rect.
-// There's no efficient way (yet?) to express this one as a pattern, so we write a custom pass.
-class CullAnnotator {
-public:
-    // Do nothing to most ops.
-    template <typename T> void operator()(T*) {}
-
-    void operator()(PushCull* push) {
-        Pair pair = { fIndex, push };
-        fPushStack.push(pair);
-    }
-
-    void operator()(PopCull* pop) {
-        Pair push = fPushStack.top();
-        fPushStack.pop();
-
-        SkASSERT(fIndex > push.index);
-        unsigned skip = fIndex - push.index;
-
-        Adopted<PushCull> adopted(push.command);
-        SkNEW_PLACEMENT_ARGS(fRecord->replace<PairedPushCull>(push.index, adopted),
-                             PairedPushCull, (&adopted, skip));
-    }
-
-    void apply(SkRecord* record) {
-        for (fRecord = record, fIndex = 0; fIndex < record->count(); fIndex++) {
-            fRecord->mutate<void>(fIndex, *this);
-        }
-    }
-
-private:
-    struct Pair {
-        unsigned index;
-        PushCull* command;
-    };
-
-    SkTDArray<Pair> fPushStack;
-    SkRecord* fRecord;
-    unsigned fIndex;
-};
-void SkRecordAnnotateCullingPairs(SkRecord* record) {
-    CullAnnotator pass;
-    pass.apply(record);
-}
diff --git a/src/core/SkRecordOpts.h b/src/core/SkRecordOpts.h
index b535ec9..936eeff 100644
--- a/src/core/SkRecordOpts.h
+++ b/src/core/SkRecordOpts.h
@@ -13,9 +13,6 @@
 // Run all optimizations in recommended order.
 void SkRecordOptimize(SkRecord*);
 
-// NoOp away pointless PushCull/PopCull pairs with nothing between them.
-void SkRecordNoopCulls(SkRecord*);
-
 // Turns logical no-op Save-[non-drawing command]*-Restore patterns into actual no-ops.
 void SkRecordNoopSaveRestores(SkRecord*);
 
@@ -23,13 +20,4 @@
 // draw, and no-op the SaveLayer and Restore.
 void SkRecordNoopSaveLayerDrawRestores(SkRecord*);
 
-// Annotates PushCull commands with the relative offset of their paired PopCull.
-void SkRecordAnnotateCullingPairs(SkRecord*);
-
-// Convert DrawPosText to DrawPosTextH when all the Y coordinates are equal.
-void SkRecordReduceDrawPosTextStrength(SkRecord*);
-
-// Calculate min and max Y bounds for DrawPosTextH commands, for use with SkCanvas::quickRejectY.
-void SkRecordBoundDrawPosTextH(SkRecord*);
-
 #endif//SkRecordOpts_DEFINED
diff --git a/src/core/SkRecordPattern.h b/src/core/SkRecordPattern.h
index 57779ff..68a3aa3 100644
--- a/src/core/SkRecordPattern.h
+++ b/src/core/SkRecordPattern.h
@@ -85,6 +85,10 @@
 template <typename A, typename B, typename C>
 struct Or3 : Or<A, Or<B, C> > {};
 
+// Matches if any of A, B, C or D does.  Stores nothing.
+template <typename A, typename B, typename C, typename D>
+struct Or4 : Or<A, Or<B, Or<C, D> > > {};
+
 // Star is a special matcher that greedily matches Matcher 0 or more times.  Stores nothing.
 template <typename Matcher>
 struct Star {
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index 8581257..f6c16d1 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -6,11 +6,14 @@
  */
 
 #include "SkRecorder.h"
+#include "SkPatchUtils.h"
 #include "SkPicture.h"
 
 // SkCanvas will fail in mysterious ways if it doesn't know the real width and height.
 SkRecorder::SkRecorder(SkRecord* record, int width, int height)
-    : SkCanvas(width, height), fRecord(record) {}
+    : SkCanvas(width, height, SkCanvas::kConservativeRasterClip_InitFlag)
+    , fRecord(record)
+    , fSaveLayerCount(0) {}
 
 void SkRecorder::forgetRecord() {
     fRecord = NULL;
@@ -57,12 +60,12 @@
 // This copy() is for arrays.
 // It will work with POD or non-POD, though currently we only use it for POD.
 template <typename T>
-T* SkRecorder::copy(const T src[], unsigned count) {
+T* SkRecorder::copy(const T src[], size_t count) {
     if (NULL == src) {
         return NULL;
     }
     T* dst = fRecord->alloc<T>(count);
-    for (unsigned i = 0; i < count; i++) {
+    for (size_t i = 0; i < count; i++) {
         SkNEW_PLACEMENT_ARGS(dst + i, T, (src[i]));
     }
     return dst;
@@ -72,7 +75,7 @@
 // This measured around 2x faster for copying code points,
 // but I found no corresponding speedup for other arrays.
 template <>
-char* SkRecorder::copy(const char src[], unsigned count) {
+char* SkRecorder::copy(const char src[], size_t count) {
     if (NULL == src) {
         return NULL;
     }
@@ -81,6 +84,13 @@
     return dst;
 }
 
+// As above, assuming and copying a terminating \0.
+template <>
+char* SkRecorder::copy(const char* src) {
+    return this->copy(src, strlen(src)+1);
+}
+
+
 void SkRecorder::clear(SkColor color) {
     APPEND(Clear, color);
 }
@@ -186,8 +196,13 @@
            this->copy(matrix));
 }
 
-void SkRecorder::onDrawPicture(const SkPicture* picture) {
-    picture->draw(this);
+void SkRecorder::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) {
+    APPEND(DrawTextBlob, delay_copy(paint), blob, x, y);
+}
+
+void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, const SkPaint* paint) {
+    APPEND(DrawPicture, this->copy(paint), pic, this->copy(matrix));
 }
 
 void SkRecorder::drawVertices(VertexMode vmode,
@@ -206,22 +221,36 @@
                          indexCount);
 }
 
-void SkRecorder::willSave(SkCanvas::SaveFlags flags) {
-    APPEND(Save, flags);
-    INHERITED(willSave, flags);
+void SkRecorder::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                             const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
+    APPEND(DrawPatch, delay_copy(paint),
+           cubics ? this->copy(cubics, SkPatchUtils::kNumCtrlPts) : NULL,
+           colors ? this->copy(colors, SkPatchUtils::kNumCorners) : NULL,
+           texCoords ? this->copy(texCoords, SkPatchUtils::kNumCorners) : NULL,
+           xmode);
+}
+
+void SkRecorder::willSave() {
+    fSaveIsSaveLayer.push(false);
+    APPEND(Save);
 }
 
 SkCanvas::SaveLayerStrategy SkRecorder::willSaveLayer(const SkRect* bounds,
                                                       const SkPaint* paint,
                                                       SkCanvas::SaveFlags flags) {
+    fSaveLayerCount++;
+    fSaveIsSaveLayer.push(true);
     APPEND(SaveLayer, this->copy(bounds), this->copy(paint), flags);
-    INHERITED(willSaveLayer, bounds, paint, flags);
     return SkCanvas::kNoLayer_SaveLayerStrategy;
 }
 
-void SkRecorder::willRestore() {
-    APPEND(Restore);
-    INHERITED(willRestore);
+void SkRecorder::didRestore() {
+    SkBool8 saveLayer;
+    fSaveIsSaveLayer.pop(&saveLayer);
+    if (saveLayer) {
+        fSaveLayerCount--;
+    }
+    APPEND(Restore, this->devBounds(), this->getTotalMatrix());
 }
 
 void SkRecorder::onPushCull(const SkRect& rect) {
@@ -233,31 +262,54 @@
 }
 
 void SkRecorder::didConcat(const SkMatrix& matrix) {
-    APPEND(Concat, matrix);
-    INHERITED(didConcat, matrix);
+    this->didSetMatrix(this->getTotalMatrix());
 }
 
 void SkRecorder::didSetMatrix(const SkMatrix& matrix) {
+    SkDEVCODE(if (matrix != this->getTotalMatrix()) {
+        matrix.dump();
+        this->getTotalMatrix().dump();
+        SkASSERT(matrix == this->getTotalMatrix());
+    })
     APPEND(SetMatrix, matrix);
-    INHERITED(didSetMatrix, matrix);
 }
 
 void SkRecorder::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
-    APPEND(ClipRect, rect, op, edgeStyle == kSoft_ClipEdgeStyle);
     INHERITED(onClipRect, rect, op, edgeStyle);
+    APPEND(ClipRect, this->devBounds(), rect, op, edgeStyle == kSoft_ClipEdgeStyle);
 }
 
 void SkRecorder::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
-    APPEND(ClipRRect, rrect, op, edgeStyle == kSoft_ClipEdgeStyle);
-    INHERITED(updateClipConservativelyUsingBounds, rrect.getBounds(), op, false);
+    INHERITED(onClipRRect, rrect, op, edgeStyle);
+    APPEND(ClipRRect, this->devBounds(), rrect, op, edgeStyle == kSoft_ClipEdgeStyle);
 }
 
 void SkRecorder::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
-    APPEND(ClipPath, delay_copy(path), op, edgeStyle == kSoft_ClipEdgeStyle);
-    INHERITED(updateClipConservativelyUsingBounds, path.getBounds(), op, path.isInverseFillType());
+    INHERITED(onClipPath, path, op, edgeStyle);
+    APPEND(ClipPath, this->devBounds(), delay_copy(path), op, edgeStyle == kSoft_ClipEdgeStyle);
 }
 
 void SkRecorder::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
-    APPEND(ClipRegion, delay_copy(deviceRgn), op);
     INHERITED(onClipRegion, deviceRgn, op);
+    APPEND(ClipRegion, this->devBounds(), delay_copy(deviceRgn), op);
+}
+
+void SkRecorder::beginCommentGroup(const char* description) {
+    APPEND(BeginCommentGroup, this->copy(description));
+}
+
+void SkRecorder::addComment(const char* key, const char* value) {
+    APPEND(AddComment, this->copy(key), this->copy(value));
+}
+
+void SkRecorder::endCommentGroup() {
+    APPEND(EndCommentGroup);
+}
+
+bool SkRecorder::isDrawingToLayer() const {
+    return fSaveLayerCount > 0;
+}
+
+void SkRecorder::drawData(const void* data, size_t length) {
+    APPEND(DrawData, copy((const char*)data), length);
 }
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 3e2932d..9eb6831 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -11,6 +11,7 @@
 #include "SkCanvas.h"
 #include "SkRecord.h"
 #include "SkRecords.h"
+#include "SkTDArray.h"
 
 // SkRecorder provides an SkCanvas interface for recording into an SkRecord.
 
@@ -62,9 +63,10 @@
                       int indexCount,
                       const SkPaint& paint) SK_OVERRIDE;
 
-    void willSave(SkCanvas::SaveFlags) SK_OVERRIDE;
+    void willSave() SK_OVERRIDE;
     SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SkCanvas::SaveFlags) SK_OVERRIDE;
-    void willRestore() SK_OVERRIDE;
+    void willRestore() SK_OVERRIDE {}
+    void didRestore() SK_OVERRIDE;
 
     void didConcat(const SkMatrix&) SK_OVERRIDE;
     void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
@@ -89,24 +91,49 @@
                           const SkPath& path,
                           const SkMatrix* matrix,
                           const SkPaint& paint) SK_OVERRIDE;
+    void onDrawTextBlob(const SkTextBlob* blob,
+                        SkScalar x,
+                        SkScalar y,
+                        const SkPaint& paint) SK_OVERRIDE;
+    void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                     const SkPoint texCoords[4], SkXfermode* xmode,
+                     const SkPaint& paint) SK_OVERRIDE;
+
     void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE;
     void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE;
     void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE;
     void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) SK_OVERRIDE;
 
-    void onDrawPicture(const SkPicture* picture) SK_OVERRIDE;
+    void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
     void onPushCull(const SkRect& cullRect) SK_OVERRIDE;
     void onPopCull() SK_OVERRIDE;
 
+    void beginCommentGroup(const char*) SK_OVERRIDE;
+    void addComment(const char*, const char*) SK_OVERRIDE;
+    void endCommentGroup() SK_OVERRIDE;
+    void drawData(const void*, size_t) SK_OVERRIDE;
+
+    bool isDrawingToLayer() const SK_OVERRIDE;
+    SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE { return NULL; }
+
 private:
     template <typename T>
     T* copy(const T*);
 
     template <typename T>
-    T* copy(const T[], unsigned count);
+    T* copy(const T[], size_t count);
+
+    SkIRect devBounds() const {
+        SkIRect devBounds;
+        this->getClipDeviceBounds(&devBounds);
+        return devBounds;
+    }
 
     SkRecord* fRecord;
+
+    int fSaveLayerCount;
+    SkTDArray<SkBool8> fSaveIsSaveLayer;
 };
 
 #endif//SkRecorder_DEFINED
diff --git a/src/core/SkRecording.cpp b/src/core/SkRecording.cpp
index 94fabce..368ebb2 100644
--- a/src/core/SkRecording.cpp
+++ b/src/core/SkRecording.cpp
@@ -20,7 +20,7 @@
 
 void SkPlayback::draw(SkCanvas* canvas) const {
     SkASSERT(fRecord.get() != NULL);
-    SkRecordDraw(*fRecord, canvas);
+    SkRecordDraw(*fRecord, canvas, NULL/*bbh*/, NULL/*callback*/);
 }
 
 SkRecording::SkRecording(int width, int height)
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index 581ae21..c06d276 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -9,6 +9,8 @@
 #define SkRecords_DEFINED
 
 #include "SkCanvas.h"
+#include "SkPicture.h"
+#include "SkTextBlob.h"
 
 namespace SkRecords {
 
@@ -29,14 +31,15 @@
     M(SaveLayer)                                                    \
     M(PushCull)                                                     \
     M(PopCull)                                                      \
-    M(PairedPushCull)         /*From SkRecordAnnotateCullingPairs*/ \
-    M(Concat)                                                       \
     M(SetMatrix)                                                    \
     M(ClipPath)                                                     \
     M(ClipRRect)                                                    \
     M(ClipRect)                                                     \
     M(ClipRegion)                                                   \
     M(Clear)                                                        \
+    M(BeginCommentGroup)                                            \
+    M(AddComment)                                                   \
+    M(EndCommentGroup)                                              \
     M(DrawBitmap)                                                   \
     M(DrawBitmapMatrix)                                             \
     M(DrawBitmapNine)                                               \
@@ -45,16 +48,19 @@
     M(DrawOval)                                                     \
     M(DrawPaint)                                                    \
     M(DrawPath)                                                     \
+    M(DrawPatch)                                                    \
+    M(DrawPicture)                                                  \
     M(DrawPoints)                                                   \
     M(DrawPosText)                                                  \
     M(DrawPosTextH)                                                 \
+    M(DrawText)                                                     \
+    M(DrawTextOnPath)                                               \
     M(DrawRRect)                                                    \
     M(DrawRect)                                                     \
     M(DrawSprite)                                                   \
-    M(DrawText)                                                     \
-    M(DrawTextOnPath)                                               \
-    M(DrawVertices)                                                 \
-    M(BoundedDrawPosTextH)    /*From SkRecordBoundDrawPosTextH*/
+    M(DrawTextBlob)                                                 \
+    M(DrawData)                                                     \
+    M(DrawVertices)
 
 // Defines SkRecords::Type, an enum of all record types.
 #define ENUM(T) T##_Type,
@@ -112,11 +118,21 @@
     A a; B b; C c; D d; E e;                                              \
 };
 
-#define ACT_AS_PTR(ptr)                       \
-    operator T*() { return ptr; }             \
-    operator const T*() const { return ptr; } \
-    T* operator->() { return ptr; }           \
-    const T* operator->() const { return ptr; }
+#define ACT_AS_PTR(ptr)                 \
+    operator T*() const { return ptr; } \
+    T* operator->() const { return ptr; }
+
+template <typename T>
+class RefBox : SkNoncopyable {
+public:
+    RefBox(T* obj) : fObj(SkSafeRef(obj)) {}
+    ~RefBox() { SkSafeUnref(fObj); }
+
+    ACT_AS_PTR(fObj);
+
+private:
+    T* fObj;
+};
 
 // An Optional doesn't own the pointer's memory, but may need to destroy non-POD data.
 template <typename T>
@@ -163,7 +179,7 @@
 
 // Like SkBitmap, but deep copies pixels if they're not immutable.
 // Using this, we guarantee the immutability of all bitmaps we record.
-class ImmutableBitmap {
+class ImmutableBitmap : SkNoncopyable {
 public:
     explicit ImmutableBitmap(const SkBitmap& bitmap) {
         if (bitmap.isImmutable()) {
@@ -182,22 +198,26 @@
 
 RECORD0(NoOp);
 
-RECORD0(Restore);
-RECORD1(Save, SkCanvas::SaveFlags, flags);
+RECORD2(Restore, SkIRect, devBounds, SkMatrix, matrix);
+RECORD0(Save);
 RECORD3(SaveLayer, Optional<SkRect>, bounds, Optional<SkPaint>, paint, SkCanvas::SaveFlags, flags);
 
 RECORD1(PushCull, SkRect, rect);
 RECORD0(PopCull);
 
-RECORD1(Concat, SkMatrix, matrix);
 RECORD1(SetMatrix, SkMatrix, matrix);
 
-RECORD3(ClipPath, SkPath, path, SkRegion::Op, op, bool, doAA);
-RECORD3(ClipRRect, SkRRect, rrect, SkRegion::Op, op, bool, doAA);
-RECORD3(ClipRect, SkRect, rect, SkRegion::Op, op, bool, doAA);
-RECORD2(ClipRegion, SkRegion, region, SkRegion::Op, op);
+RECORD4(ClipPath,   SkIRect, devBounds, SkPath,   path,   SkRegion::Op, op, bool, doAA);
+RECORD4(ClipRRect,  SkIRect, devBounds, SkRRect,  rrect,  SkRegion::Op, op, bool, doAA);
+RECORD4(ClipRect,   SkIRect, devBounds, SkRect,   rect,   SkRegion::Op, op, bool, doAA);
+RECORD3(ClipRegion, SkIRect, devBounds, SkRegion, region, SkRegion::Op, op);
 
 RECORD1(Clear, SkColor, color);
+
+RECORD1(BeginCommentGroup, PODArray<char>, description);
+RECORD2(AddComment, PODArray<char>, key, PODArray<char>, value);
+RECORD0(EndCommentGroup);
+
 // While not strictly required, if you have an SkPaint, it's fastest to put it first.
 RECORD4(DrawBitmap, Optional<SkPaint>, paint,
                     ImmutableBitmap, bitmap,
@@ -217,6 +237,9 @@
 RECORD2(DrawOval, SkPaint, paint, SkRect, oval);
 RECORD1(DrawPaint, SkPaint, paint);
 RECORD2(DrawPath, SkPaint, paint, SkPath, path);
+RECORD3(DrawPicture, Optional<SkPaint>, paint,
+                     RefBox<const SkPicture>, picture,
+                     Optional<SkMatrix>, matrix);
 RECORD4(DrawPoints, SkPaint, paint, SkCanvas::PointMode, mode, size_t, count, SkPoint*, pts);
 RECORD4(DrawPosText, SkPaint, paint,
                      PODArray<char>, text,
@@ -235,12 +258,24 @@
                   size_t, byteLength,
                   SkScalar, x,
                   SkScalar, y);
+RECORD4(DrawTextBlob, SkPaint, paint,
+                      RefBox<const SkTextBlob>, blob,
+                      SkScalar, x,
+                      SkScalar, y);
 RECORD5(DrawTextOnPath, SkPaint, paint,
                         PODArray<char>, text,
                         size_t, byteLength,
                         SkPath, path,
                         Optional<SkMatrix>, matrix);
 
+RECORD2(DrawData, PODArray<char>, data, size_t, length);
+
+RECORD5(DrawPatch, SkPaint, paint,
+                   PODArray<SkPoint>, cubics,
+                   PODArray<SkColor>, colors,
+                   PODArray<SkPoint>, texCoords,
+                   RefBox<SkXfermode>, xmode);
+
 // This guy is so ugly we just write it manually.
 struct DrawVertices {
     static const Type kType = DrawVertices_Type;
@@ -275,10 +310,6 @@
     int indexCount;
 };
 
-// Records added by optimizations.
-RECORD2(PairedPushCull, Adopted<PushCull>, base, unsigned, skip);
-RECORD3(BoundedDrawPosTextH, Adopted<DrawPosTextH>, base, SkScalar, minY, SkScalar, maxY);
-
 #undef RECORD0
 #undef RECORD1
 #undef RECORD2
diff --git a/src/core/SkRect.cpp b/src/core/SkRect.cpp
index 3cff5d8..2814375 100644
--- a/src/core/SkRect.cpp
+++ b/src/core/SkRect.cpp
@@ -114,12 +114,10 @@
 }
 
 bool SkRect::intersect(const SkRect& r) {
-    SkASSERT(&r);
     return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom);
 }
 
 bool SkRect::intersect2(const SkRect& r) {
-    SkASSERT(&r);
     SkScalar L = SkMaxScalar(fLeft, r.fLeft);
     SkScalar R = SkMinScalar(fRight, r.fRight);
     if (L >= R) {
@@ -135,7 +133,6 @@
 }
 
 bool SkRect::intersect(const SkRect& a, const SkRect& b) {
-    SkASSERT(&a && &b);
 
     if (!a.isEmpty() && !b.isEmpty() &&
         a.fLeft < b.fRight && b.fLeft < a.fRight &&
diff --git a/src/core/SkRegion_path.cpp b/src/core/SkRegion_path.cpp
index 03830e6..108511c 100644
--- a/src/core/SkRegion_path.cpp
+++ b/src/core/SkRegion_path.cpp
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2006 The Android Open Source Project
  *
@@ -6,13 +5,23 @@
  * found in the LICENSE file.
  */
 
-
 #include "SkRegionPriv.h"
 #include "SkBlitter.h"
 #include "SkScan.h"
 #include "SkTDArray.h"
 #include "SkPath.h"
 
+// The rgnbuilder caller *seems* to pass short counts, possible often seens early failure, so
+// we may not want to promote this to a "std" routine just yet.
+static bool sk_memeq32(const int32_t* SK_RESTRICT a, const int32_t* SK_RESTRICT b, int count) {
+    for (int i = 0; i < count; ++i) {
+        if (a[i] != b[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
 class SkRgnBuilder : public SkBlitter {
 public:
     SkRgnBuilder();
@@ -87,9 +96,7 @@
         if (fPrevScanline != NULL &&
             fPrevScanline->fLastY + 1 == fCurrScanline->fLastY &&
             fPrevScanline->fXCount == fCurrScanline->fXCount &&
-            !memcmp(fPrevScanline->firstX(),
-                    fCurrScanline->firstX(),
-                    fCurrScanline->fXCount * sizeof(SkRegion::RunType)))
+            sk_memeq32(fPrevScanline->firstX(), fCurrScanline->firstX(), fCurrScanline->fXCount))
         {
             // update the height of fPrevScanline
             fPrevScanline->fLastY = fCurrScanline->fLastY;
diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp
new file mode 100644
index 0000000..3098a9a
--- /dev/null
+++ b/src/core/SkResourceCache.cpp
@@ -0,0 +1,502 @@
+/*
+ * 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 "SkChecksum.h"
+#include "SkResourceCache.h"
+#include "SkMipMap.h"
+#include "SkPixelRef.h"
+
+// This can be defined by the caller's build system
+//#define SK_USE_DISCARDABLE_SCALEDIMAGECACHE
+
+#ifndef SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT
+#   define SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT   1024
+#endif
+
+#ifndef SK_DEFAULT_IMAGE_CACHE_LIMIT
+    #define SK_DEFAULT_IMAGE_CACHE_LIMIT     (2 * 1024 * 1024)
+#endif
+
+void SkResourceCache::Key::init(size_t length) {
+    SkASSERT(SkAlign4(length) == length);
+    // 2 is fCount32 and fHash
+    fCount32 = SkToS32(2 + (length >> 2));
+    // skip both of our fields whe computing the murmur
+    fHash = SkChecksum::Murmur3(this->as32() + 2, (fCount32 - 2) << 2);
+}
+
+#include "SkTDynamicHash.h"
+
+class SkResourceCache::Hash :
+    public SkTDynamicHash<SkResourceCache::Rec, SkResourceCache::Key> {};
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkResourceCache::init() {
+    fHead = NULL;
+    fTail = NULL;
+    fHash = new Hash;
+    fTotalBytesUsed = 0;
+    fCount = 0;
+    fSingleAllocationByteLimit = 0;
+    fAllocator = NULL;
+
+    // One of these should be explicit set by the caller after we return.
+    fTotalByteLimit = 0;
+    fDiscardableFactory = NULL;
+}
+
+#include "SkDiscardableMemory.h"
+
+class SkOneShotDiscardablePixelRef : public SkPixelRef {
+public:
+    SK_DECLARE_INST_COUNT(SkOneShotDiscardablePixelRef)
+    // Ownership of the discardablememory is transfered to the pixelref
+    SkOneShotDiscardablePixelRef(const SkImageInfo&, SkDiscardableMemory*, size_t rowBytes);
+    ~SkOneShotDiscardablePixelRef();
+
+protected:
+    virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
+    virtual void onUnlockPixels() SK_OVERRIDE;
+    virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
+
+private:
+    SkDiscardableMemory* fDM;
+    size_t               fRB;
+    bool                 fFirstTime;
+
+    typedef SkPixelRef INHERITED;
+};
+
+SkOneShotDiscardablePixelRef::SkOneShotDiscardablePixelRef(const SkImageInfo& info,
+                                             SkDiscardableMemory* dm,
+                                             size_t rowBytes)
+    : INHERITED(info)
+    , fDM(dm)
+    , fRB(rowBytes)
+{
+    SkASSERT(dm->data());
+    fFirstTime = true;
+}
+
+SkOneShotDiscardablePixelRef::~SkOneShotDiscardablePixelRef() {
+    SkDELETE(fDM);
+}
+
+bool SkOneShotDiscardablePixelRef::onNewLockPixels(LockRec* rec) {
+    if (fFirstTime) {
+        // we're already locked
+        SkASSERT(fDM->data());
+        fFirstTime = false;
+        goto SUCCESS;
+    }
+
+    // A previous call to onUnlock may have deleted our DM, so check for that
+    if (NULL == fDM) {
+        return false;
+    }
+
+    if (!fDM->lock()) {
+        // since it failed, we delete it now, to free-up the resource
+        delete fDM;
+        fDM = NULL;
+        return false;
+    }
+
+SUCCESS:
+    rec->fPixels = fDM->data();
+    rec->fColorTable = NULL;
+    rec->fRowBytes = fRB;
+    return true;
+}
+
+void SkOneShotDiscardablePixelRef::onUnlockPixels() {
+    SkASSERT(!fFirstTime);
+    fDM->unlock();
+}
+
+size_t SkOneShotDiscardablePixelRef::getAllocatedSizeInBytes() const {
+    return this->info().getSafeSize(fRB);
+}
+
+class SkResourceCacheDiscardableAllocator : public SkBitmap::Allocator {
+public:
+    SkResourceCacheDiscardableAllocator(SkResourceCache::DiscardableFactory factory) {
+        SkASSERT(factory);
+        fFactory = factory;
+    }
+
+    virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE;
+
+private:
+    SkResourceCache::DiscardableFactory fFactory;
+};
+
+bool SkResourceCacheDiscardableAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
+    size_t size = bitmap->getSize();
+    uint64_t size64 = bitmap->computeSize64();
+    if (0 == size || size64 > (uint64_t)size) {
+        return false;
+    }
+
+    SkDiscardableMemory* dm = fFactory(size);
+    if (NULL == dm) {
+        return false;
+    }
+
+    // can we relax this?
+    if (kN32_SkColorType != bitmap->colorType()) {
+        return false;
+    }
+
+    SkImageInfo info = bitmap->info();
+    bitmap->setPixelRef(SkNEW_ARGS(SkOneShotDiscardablePixelRef,
+                                   (info, dm, bitmap->rowBytes())))->unref();
+    bitmap->lockPixels();
+    return bitmap->readyToDraw();
+}
+
+SkResourceCache::SkResourceCache(DiscardableFactory factory) {
+    this->init();
+    fDiscardableFactory = factory;
+
+    fAllocator = SkNEW_ARGS(SkResourceCacheDiscardableAllocator, (factory));
+}
+
+SkResourceCache::SkResourceCache(size_t byteLimit) {
+    this->init();
+    fTotalByteLimit = byteLimit;
+}
+
+SkResourceCache::~SkResourceCache() {
+    SkSafeUnref(fAllocator);
+
+    Rec* rec = fHead;
+    while (rec) {
+        Rec* next = rec->fNext;
+        SkDELETE(rec);
+        rec = next;
+    }
+    delete fHash;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool SkResourceCache::find(const Key& key, VisitorProc visitor, void* context) {
+    Rec* rec = fHash->find(key);
+    if (rec) {
+        if (visitor(*rec, context)) {
+            this->moveToHead(rec);  // for our LRU
+            return true;
+        } else {
+            this->remove(rec);  // stale
+            return false;
+        }
+    }
+    return false;
+}
+
+void SkResourceCache::add(Rec* rec) {
+    SkASSERT(rec);
+    // See if we already have this key (racy inserts, etc.)
+    Rec* existing = fHash->find(rec->getKey());
+    if (existing) {
+        SkDELETE(rec);
+        return;
+    }
+    
+    this->addToHead(rec);
+    fHash->add(rec);
+
+    // since the new rec may push us over-budget, we perform a purge check now
+    this->purgeAsNeeded();
+}
+
+void SkResourceCache::remove(Rec* rec) {
+    size_t used = rec->bytesUsed();
+    SkASSERT(used <= fTotalBytesUsed);
+
+    this->detach(rec);
+    fHash->remove(rec->getKey());
+
+    SkDELETE(rec);
+
+    fTotalBytesUsed -= used;
+    fCount -= 1;
+}
+
+void SkResourceCache::purgeAsNeeded(bool forcePurge) {
+    size_t byteLimit;
+    int    countLimit;
+
+    if (fDiscardableFactory) {
+        countLimit = SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT;
+        byteLimit = SK_MaxU32;  // no limit based on bytes
+    } else {
+        countLimit = SK_MaxS32; // no limit based on count
+        byteLimit = fTotalByteLimit;
+    }
+
+    Rec* rec = fTail;
+    while (rec) {
+        if (!forcePurge && fTotalBytesUsed < byteLimit && fCount < countLimit) {
+            break;
+        }
+
+        Rec* prev = rec->fPrev;
+        this->remove(rec);
+        rec = prev;
+    }
+}
+
+size_t SkResourceCache::setTotalByteLimit(size_t newLimit) {
+    size_t prevLimit = fTotalByteLimit;
+    fTotalByteLimit = newLimit;
+    if (newLimit < prevLimit) {
+        this->purgeAsNeeded();
+    }
+    return prevLimit;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkResourceCache::detach(Rec* rec) {
+    Rec* prev = rec->fPrev;
+    Rec* next = rec->fNext;
+
+    if (!prev) {
+        SkASSERT(fHead == rec);
+        fHead = next;
+    } else {
+        prev->fNext = next;
+    }
+
+    if (!next) {
+        fTail = prev;
+    } else {
+        next->fPrev = prev;
+    }
+
+    rec->fNext = rec->fPrev = NULL;
+}
+
+void SkResourceCache::moveToHead(Rec* rec) {
+    if (fHead == rec) {
+        return;
+    }
+
+    SkASSERT(fHead);
+    SkASSERT(fTail);
+
+    this->validate();
+
+    this->detach(rec);
+
+    fHead->fPrev = rec;
+    rec->fNext = fHead;
+    fHead = rec;
+
+    this->validate();
+}
+
+void SkResourceCache::addToHead(Rec* rec) {
+    this->validate();
+
+    rec->fPrev = NULL;
+    rec->fNext = fHead;
+    if (fHead) {
+        fHead->fPrev = rec;
+    }
+    fHead = rec;
+    if (!fTail) {
+        fTail = rec;
+    }
+    fTotalBytesUsed += rec->bytesUsed();
+    fCount += 1;
+
+    this->validate();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_DEBUG
+void SkResourceCache::validate() const {
+    if (NULL == fHead) {
+        SkASSERT(NULL == fTail);
+        SkASSERT(0 == fTotalBytesUsed);
+        return;
+    }
+
+    if (fHead == fTail) {
+        SkASSERT(NULL == fHead->fPrev);
+        SkASSERT(NULL == fHead->fNext);
+        SkASSERT(fHead->bytesUsed() == fTotalBytesUsed);
+        return;
+    }
+
+    SkASSERT(NULL == fHead->fPrev);
+    SkASSERT(fHead->fNext);
+    SkASSERT(NULL == fTail->fNext);
+    SkASSERT(fTail->fPrev);
+
+    size_t used = 0;
+    int count = 0;
+    const Rec* rec = fHead;
+    while (rec) {
+        count += 1;
+        used += rec->bytesUsed();
+        SkASSERT(used <= fTotalBytesUsed);
+        rec = rec->fNext;
+    }
+    SkASSERT(fCount == count);
+
+    rec = fTail;
+    while (rec) {
+        SkASSERT(count > 0);
+        count -= 1;
+        SkASSERT(used >= rec->bytesUsed());
+        used -= rec->bytesUsed();
+        rec = rec->fPrev;
+    }
+
+    SkASSERT(0 == count);
+    SkASSERT(0 == used);
+}
+#endif
+
+void SkResourceCache::dump() const {
+    this->validate();
+
+    SkDebugf("SkResourceCache: count=%d bytes=%d %s\n",
+             fCount, fTotalBytesUsed, fDiscardableFactory ? "discardable" : "malloc");
+}
+
+size_t SkResourceCache::setSingleAllocationByteLimit(size_t newLimit) {
+    size_t oldLimit = fSingleAllocationByteLimit;
+    fSingleAllocationByteLimit = newLimit;
+    return oldLimit;
+}
+
+size_t SkResourceCache::getSingleAllocationByteLimit() const {
+    return fSingleAllocationByteLimit;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkThread.h"
+
+SK_DECLARE_STATIC_MUTEX(gMutex);
+static SkResourceCache* gResourceCache = NULL;
+static void cleanup_gResourceCache() {
+    // We'll clean this up in our own tests, but disable for clients.
+    // Chrome seems to have funky multi-process things going on in unit tests that
+    // makes this unsafe to delete when the main process atexit()s.
+    // SkLazyPtr does the same sort of thing.
+#if SK_DEVELOPER
+    SkDELETE(gResourceCache);
+#endif
+}
+
+/** Must hold gMutex when calling. */
+static SkResourceCache* get_cache() {
+    // gMutex is always held when this is called, so we don't need to be fancy in here.
+    gMutex.assertHeld();
+    if (NULL == gResourceCache) {
+#ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE
+        gResourceCache = SkNEW_ARGS(SkResourceCache, (SkDiscardableMemory::Create));
+#else
+        gResourceCache = SkNEW_ARGS(SkResourceCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT));
+#endif
+        atexit(cleanup_gResourceCache);
+    }
+    return gResourceCache;
+}
+
+size_t SkResourceCache::GetTotalBytesUsed() {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->getTotalBytesUsed();
+}
+
+size_t SkResourceCache::GetTotalByteLimit() {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->getTotalByteLimit();
+}
+
+size_t SkResourceCache::SetTotalByteLimit(size_t newLimit) {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->setTotalByteLimit(newLimit);
+}
+
+SkResourceCache::DiscardableFactory SkResourceCache::GetDiscardableFactory() {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->discardableFactory();
+}
+
+SkBitmap::Allocator* SkResourceCache::GetAllocator() {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->allocator();
+}
+
+void SkResourceCache::Dump() {
+    SkAutoMutexAcquire am(gMutex);
+    get_cache()->dump();
+}
+
+size_t SkResourceCache::SetSingleAllocationByteLimit(size_t size) {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->setSingleAllocationByteLimit(size);
+}
+
+size_t SkResourceCache::GetSingleAllocationByteLimit() {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->getSingleAllocationByteLimit();
+}
+
+void SkResourceCache::PurgeAll() {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->purgeAll();
+}
+
+bool SkResourceCache::Find(const Key& key, VisitorProc visitor, void* context) {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->find(key, visitor, context);
+}
+
+void SkResourceCache::Add(Rec* rec) {
+    SkAutoMutexAcquire am(gMutex);
+    get_cache()->add(rec);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkGraphics.h"
+
+size_t SkGraphics::GetResourceCacheTotalBytesUsed() {
+    return SkResourceCache::GetTotalBytesUsed();
+}
+
+size_t SkGraphics::GetResourceCacheTotalByteLimit() {
+    return SkResourceCache::GetTotalByteLimit();
+}
+
+size_t SkGraphics::SetResourceCacheTotalByteLimit(size_t newLimit) {
+    return SkResourceCache::SetTotalByteLimit(newLimit);
+}
+
+size_t SkGraphics::GetResourceCacheSingleAllocationByteLimit() {
+    return SkResourceCache::GetSingleAllocationByteLimit();
+}
+
+size_t SkGraphics::SetResourceCacheSingleAllocationByteLimit(size_t newLimit) {
+    return SkResourceCache::SetSingleAllocationByteLimit(newLimit);
+}
+
+void SkGraphics::PurgeResourceCache() {
+    return SkResourceCache::PurgeAll();
+}
+
diff --git a/src/core/SkResourceCache.h b/src/core/SkResourceCache.h
new file mode 100644
index 0000000..5219698
--- /dev/null
+++ b/src/core/SkResourceCache.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkResourceCache_DEFINED
+#define SkResourceCache_DEFINED
+
+#include "SkBitmap.h"
+
+class SkDiscardableMemory;
+class SkMipMap;
+
+/**
+ *  Cache object for bitmaps (with possible scale in X Y as part of the key).
+ *
+ *  Multiple caches can be instantiated, but each instance is not implicitly
+ *  thread-safe, so if a given instance is to be shared across threads, the
+ *  caller must manage the access itself (e.g. via a mutex).
+ *
+ *  As a convenience, a global instance is also defined, which can be safely
+ *  access across threads via the static methods (e.g. FindAndLock, etc.).
+ */
+class SkResourceCache {
+public:
+    struct Key {
+        // Call this to access your private contents. Must not use the address after calling init()
+        void* writableContents() { return this + 1; }
+
+        // must call this after your private data has been written.
+        // length must be a multiple of 4
+        void init(size_t length);
+
+        // This is only valid after having called init().
+        uint32_t hash() const { return fHash; }
+
+        bool operator==(const Key& other) const {
+            const uint32_t* a = this->as32();
+            const uint32_t* b = other.as32();
+            for (int i = 0; i < fCount32; ++i) {
+                if (a[i] != b[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+    private:
+        // store fCount32 first, so we don't consider it in operator<
+        int32_t  fCount32;  // 2 + user contents count32
+        uint32_t fHash;
+        /* uint32_t fContents32[] */
+
+        const uint32_t* as32() const { return (const uint32_t*)this; }
+        const uint32_t* as32SkipCount() const { return this->as32() + 1; }
+    };
+
+    struct Rec {
+        typedef SkResourceCache::Key Key;
+
+        Rec() {}
+        virtual ~Rec() {}
+
+        uint32_t getHash() const { return this->getKey().hash(); }
+
+        virtual const Key& getKey() const = 0;
+        virtual size_t bytesUsed() const = 0;
+
+        // for SkTDynamicHash::Traits
+        static uint32_t Hash(const Key& key) { return key.hash(); }
+        static const Key& GetKey(const Rec& rec) { return rec.getKey(); }
+
+    private:
+        Rec*    fNext;
+        Rec*    fPrev;
+
+        friend class SkResourceCache;
+    };
+
+    typedef const Rec* ID;
+
+    /**
+     *  Callback function for find(). If called, the cache will have found a match for the
+     *  specified Key, and will pass in the corresponding Rec, along with a caller-specified
+     *  context. The function can read the data in Rec, and copy whatever it likes into context
+     *  (casting context to whatever it really is).
+     *
+     *  The return value determines what the cache will do with the Rec. If the function returns
+     *  true, then the Rec is considered "valid". If false is returned, the Rec will be considered
+     *  "stale" and will be purged from the cache.
+     */
+    typedef bool (*VisitorProc)(const Rec&, void* context);
+
+    /**
+     *  Returns a locked/pinned SkDiscardableMemory instance for the specified
+     *  number of bytes, or NULL on failure.
+     */
+    typedef SkDiscardableMemory* (*DiscardableFactory)(size_t bytes);
+
+    /*
+     *  The following static methods are thread-safe wrappers around a global
+     *  instance of this cache.
+     */
+
+    /**
+     *  Returns true if the visitor was called on a matching Key, and the visitor returned true.
+     *
+     *  Find() will search the cache for the specified Key. If no match is found, return false and
+     *  do not call the VisitorProc. If a match is found, return whatever the visitor returns.
+     *  Its return value is interpreted to mean:
+     *      true  : Rec is valid
+     *      false : Rec is "stale" -- the cache will purge it.
+     */
+    static bool Find(const Key& key, VisitorProc, void* context);
+    static void Add(Rec*);
+
+    static size_t GetTotalBytesUsed();
+    static size_t GetTotalByteLimit();
+    static size_t SetTotalByteLimit(size_t newLimit);
+
+    static size_t SetSingleAllocationByteLimit(size_t);
+    static size_t GetSingleAllocationByteLimit();
+
+    static void PurgeAll();
+
+    /**
+     *  Returns the DiscardableFactory used by the global cache, or NULL.
+     */
+    static DiscardableFactory GetDiscardableFactory();
+
+    /**
+     * Use this allocator for bitmaps, so they can use ashmem when available.
+     * Returns NULL if the ResourceCache has not been initialized with a DiscardableFactory.
+     */
+    static SkBitmap::Allocator* GetAllocator();
+
+    /**
+     *  Call SkDebugf() with diagnostic information about the state of the cache
+     */
+    static void Dump();
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    /**
+     *  Construct the cache to call DiscardableFactory when it
+     *  allocates memory for the pixels. In this mode, the cache has
+     *  not explicit budget, and so methods like getTotalBytesUsed()
+     *  and getTotalByteLimit() will return 0, and setTotalByteLimit
+     *  will ignore its argument and return 0.
+     */
+    SkResourceCache(DiscardableFactory);
+
+    /**
+     *  Construct the cache, allocating memory with malloc, and respect the
+     *  byteLimit, purging automatically when a new image is added to the cache
+     *  that pushes the total bytesUsed over the limit. Note: The limit can be
+     *  changed at runtime with setTotalByteLimit.
+     */
+    explicit SkResourceCache(size_t byteLimit);
+    ~SkResourceCache();
+
+    /**
+     *  Returns true if the visitor was called on a matching Key, and the visitor returned true.
+     *
+     *  find() will search the cache for the specified Key. If no match is found, return false and
+     *  do not call the VisitorProc. If a match is found, return whatever the visitor returns.
+     *  Its return value is interpreted to mean:
+     *      true  : Rec is valid
+     *      false : Rec is "stale" -- the cache will purge it.
+     */
+    bool find(const Key&, VisitorProc, void* context);
+    void add(Rec*);
+
+    size_t getTotalBytesUsed() const { return fTotalBytesUsed; }
+    size_t getTotalByteLimit() const { return fTotalByteLimit; }
+
+    /**
+     *  This is respected by SkBitmapProcState::possiblyScaleImage.
+     *  0 is no maximum at all; this is the default.
+     *  setSingleAllocationByteLimit() returns the previous value.
+     */
+    size_t setSingleAllocationByteLimit(size_t maximumAllocationSize);
+    size_t getSingleAllocationByteLimit() const;
+    /**
+     *  Set the maximum number of bytes available to this cache. If the current
+     *  cache exceeds this new value, it will be purged to try to fit within
+     *  this new limit.
+     */
+    size_t setTotalByteLimit(size_t newLimit);
+
+    void purgeAll() {
+        this->purgeAsNeeded(true);
+    }
+
+    DiscardableFactory discardableFactory() const { return fDiscardableFactory; }
+    SkBitmap::Allocator* allocator() const { return fAllocator; };
+
+    /**
+     *  Call SkDebugf() with diagnostic information about the state of the cache
+     */
+    void dump() const;
+
+private:
+    Rec*    fHead;
+    Rec*    fTail;
+
+    class Hash;
+    Hash*   fHash;
+
+    DiscardableFactory  fDiscardableFactory;
+    // the allocator is NULL or one that matches discardables
+    SkBitmap::Allocator* fAllocator;
+
+    size_t  fTotalBytesUsed;
+    size_t  fTotalByteLimit;
+    size_t  fSingleAllocationByteLimit;
+    int     fCount;
+
+    void purgeAsNeeded(bool forcePurge = false);
+
+    // linklist management
+    void moveToHead(Rec*);
+    void addToHead(Rec*);
+    void detach(Rec*);
+    void remove(Rec*);
+
+    void init();    // called by constructors
+
+#ifdef SK_DEBUG
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+};
+#endif
diff --git a/src/core/SkScaledImageCache.cpp b/src/core/SkScaledImageCache.cpp
deleted file mode 100644
index 43ff7ef..0000000
--- a/src/core/SkScaledImageCache.cpp
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * 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 "SkScaledImageCache.h"
-#include "SkMipMap.h"
-#include "SkPixelRef.h"
-#include "SkRect.h"
-
-// This can be defined by the caller's build system
-//#define SK_USE_DISCARDABLE_SCALEDIMAGECACHE
-
-#ifndef SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT
-#   define SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT   1024
-#endif
-
-#ifndef SK_DEFAULT_IMAGE_CACHE_LIMIT
-    #define SK_DEFAULT_IMAGE_CACHE_LIMIT     (2 * 1024 * 1024)
-#endif
-
-static inline SkScaledImageCache::ID* rec_to_id(SkScaledImageCache::Rec* rec) {
-    return reinterpret_cast<SkScaledImageCache::ID*>(rec);
-}
-
-static inline SkScaledImageCache::Rec* id_to_rec(SkScaledImageCache::ID* id) {
-    return reinterpret_cast<SkScaledImageCache::Rec*>(id);
-}
-
- // Implemented from en.wikipedia.org/wiki/MurmurHash.
-static uint32_t compute_hash(const uint32_t data[], int count) {
-    uint32_t hash = 0;
-
-    for (int i = 0; i < count; ++i) {
-        uint32_t k = data[i];
-        k *= 0xcc9e2d51;
-        k = (k << 15) | (k >> 17);
-        k *= 0x1b873593;
-
-        hash ^= k;
-        hash = (hash << 13) | (hash >> 19);
-        hash *= 5;
-        hash += 0xe6546b64;
-    }
-
-    //    hash ^= size;
-    hash ^= hash >> 16;
-    hash *= 0x85ebca6b;
-    hash ^= hash >> 13;
-    hash *= 0xc2b2ae35;
-    hash ^= hash >> 16;
-
-    return hash;
-}
-
-struct SkScaledImageCache::Key {
-    Key(uint32_t genID,
-        SkScalar scaleX,
-        SkScalar scaleY,
-        SkIRect  bounds)
-        : fGenID(genID)
-        , fScaleX(scaleX)
-        , fScaleY(scaleY)
-        , fBounds(bounds) {
-        fHash = compute_hash(&fGenID, 7);
-    }
-
-    bool operator<(const Key& other) const {
-        const uint32_t* a = &fGenID;
-        const uint32_t* b = &other.fGenID;
-        for (int i = 0; i < 7; ++i) {
-            if (a[i] < b[i]) {
-                return true;
-            }
-            if (a[i] > b[i]) {
-                return false;
-            }
-        }
-        return false;
-    }
-
-    bool operator==(const Key& other) const {
-        const uint32_t* a = &fHash;
-        const uint32_t* b = &other.fHash;
-        for (int i = 0; i < 8; ++i) {
-            if (a[i] != b[i]) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    uint32_t    fHash;
-    uint32_t    fGenID;
-    float       fScaleX;
-    float       fScaleY;
-    SkIRect     fBounds;
-};
-
-struct SkScaledImageCache::Rec {
-    Rec(const Key& key, const SkBitmap& bm) : fKey(key), fBitmap(bm) {
-        fLockCount = 1;
-        fMip = NULL;
-    }
-
-    Rec(const Key& key, const SkMipMap* mip) : fKey(key) {
-        fLockCount = 1;
-        fMip = mip;
-        mip->ref();
-    }
-
-    ~Rec() {
-        SkSafeUnref(fMip);
-    }
-
-    static const Key& GetKey(const Rec& rec) { return rec.fKey; }
-    static uint32_t Hash(const Key& key) { return key.fHash; }
-
-    size_t bytesUsed() const {
-        return fMip ? fMip->getSize() : fBitmap.getSize();
-    }
-
-    Rec*    fNext;
-    Rec*    fPrev;
-
-    // this guy wants to be 64bit aligned
-    Key     fKey;
-
-    int32_t fLockCount;
-
-    // we use either fBitmap or fMip, but not both
-    SkBitmap fBitmap;
-    const SkMipMap* fMip;
-};
-
-#include "SkTDynamicHash.h"
-
-class SkScaledImageCache::Hash :
-    public SkTDynamicHash<SkScaledImageCache::Rec, SkScaledImageCache::Key> {};
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-// experimental hash to speed things up
-#define USE_HASH
-
-#if !defined(USE_HASH)
-static inline SkScaledImageCache::Rec* find_rec_in_list(
-        SkScaledImageCache::Rec* head, const Key & key) {
-    SkScaledImageCache::Rec* rec = head;
-    while ((rec != NULL) && (rec->fKey != key)) {
-        rec = rec->fNext;
-    }
-    return rec;
-}
-#endif
-
-void SkScaledImageCache::init() {
-    fHead = NULL;
-    fTail = NULL;
-#ifdef USE_HASH
-    fHash = new Hash;
-#else
-    fHash = NULL;
-#endif
-    fTotalBytesUsed = 0;
-    fCount = 0;
-    fSingleAllocationByteLimit = 0;
-    fAllocator = NULL;
-
-    // One of these should be explicit set by the caller after we return.
-    fTotalByteLimit = 0;
-    fDiscardableFactory = NULL;
-}
-
-#include "SkDiscardableMemory.h"
-
-class SkOneShotDiscardablePixelRef : public SkPixelRef {
-public:
-    SK_DECLARE_INST_COUNT(SkOneShotDiscardablePixelRef)
-    // Ownership of the discardablememory is transfered to the pixelref
-    SkOneShotDiscardablePixelRef(const SkImageInfo&, SkDiscardableMemory*, size_t rowBytes);
-    ~SkOneShotDiscardablePixelRef();
-
-    SK_DECLARE_UNFLATTENABLE_OBJECT()
-
-protected:
-    virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
-    virtual void onUnlockPixels() SK_OVERRIDE;
-    virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
-
-private:
-    SkDiscardableMemory* fDM;
-    size_t               fRB;
-    bool                 fFirstTime;
-
-    typedef SkPixelRef INHERITED;
-};
-
-SkOneShotDiscardablePixelRef::SkOneShotDiscardablePixelRef(const SkImageInfo& info,
-                                             SkDiscardableMemory* dm,
-                                             size_t rowBytes)
-    : INHERITED(info)
-    , fDM(dm)
-    , fRB(rowBytes)
-{
-    SkASSERT(dm->data());
-    fFirstTime = true;
-}
-
-SkOneShotDiscardablePixelRef::~SkOneShotDiscardablePixelRef() {
-    SkDELETE(fDM);
-}
-
-bool SkOneShotDiscardablePixelRef::onNewLockPixels(LockRec* rec) {
-    if (fFirstTime) {
-        // we're already locked
-        SkASSERT(fDM->data());
-        fFirstTime = false;
-        goto SUCCESS;
-    }
-
-    // A previous call to onUnlock may have deleted our DM, so check for that
-    if (NULL == fDM) {
-        return false;
-    }
-
-    if (!fDM->lock()) {
-        // since it failed, we delete it now, to free-up the resource
-        delete fDM;
-        fDM = NULL;
-        return false;
-    }
-
-SUCCESS:
-    rec->fPixels = fDM->data();
-    rec->fColorTable = NULL;
-    rec->fRowBytes = fRB;
-    return true;
-}
-
-void SkOneShotDiscardablePixelRef::onUnlockPixels() {
-    SkASSERT(!fFirstTime);
-    fDM->unlock();
-}
-
-size_t SkOneShotDiscardablePixelRef::getAllocatedSizeInBytes() const {
-    return this->info().getSafeSize(fRB);
-}
-
-class SkScaledImageCacheDiscardableAllocator : public SkBitmap::Allocator {
-public:
-    SkScaledImageCacheDiscardableAllocator(
-                            SkScaledImageCache::DiscardableFactory factory) {
-        SkASSERT(factory);
-        fFactory = factory;
-    }
-
-    virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE;
-
-private:
-    SkScaledImageCache::DiscardableFactory fFactory;
-};
-
-bool SkScaledImageCacheDiscardableAllocator::allocPixelRef(SkBitmap* bitmap,
-                                                       SkColorTable* ctable) {
-    size_t size = bitmap->getSize();
-    uint64_t size64 = bitmap->computeSize64();
-    if (0 == size || size64 > (uint64_t)size) {
-        return false;
-    }
-
-    SkDiscardableMemory* dm = fFactory(size);
-    if (NULL == dm) {
-        return false;
-    }
-
-    // can we relax this?
-    if (kN32_SkColorType != bitmap->colorType()) {
-        return false;
-    }
-
-    SkImageInfo info = bitmap->info();
-    bitmap->setPixelRef(SkNEW_ARGS(SkOneShotDiscardablePixelRef,
-                                   (info, dm, bitmap->rowBytes())))->unref();
-    bitmap->lockPixels();
-    return bitmap->readyToDraw();
-}
-
-SkScaledImageCache::SkScaledImageCache(DiscardableFactory factory) {
-    this->init();
-    fDiscardableFactory = factory;
-
-    fAllocator = SkNEW_ARGS(SkScaledImageCacheDiscardableAllocator, (factory));
-}
-
-SkScaledImageCache::SkScaledImageCache(size_t byteLimit) {
-    this->init();
-    fTotalByteLimit = byteLimit;
-}
-
-SkScaledImageCache::~SkScaledImageCache() {
-    SkSafeUnref(fAllocator);
-
-    Rec* rec = fHead;
-    while (rec) {
-        Rec* next = rec->fNext;
-        SkDELETE(rec);
-        rec = next;
-    }
-    delete fHash;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(uint32_t genID,
-                                                        SkScalar scaleX,
-                                                        SkScalar scaleY,
-                                                        const SkIRect& bounds) {
-    const Key key(genID, scaleX, scaleY, bounds);
-    return this->findAndLock(key);
-}
-
-/**
-   This private method is the fully general record finder. All other
-   record finders should call this function or the one above. */
-SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkScaledImageCache::Key& key) {
-    if (key.fBounds.isEmpty()) {
-        return NULL;
-    }
-#ifdef USE_HASH
-    Rec* rec = fHash->find(key);
-#else
-    Rec* rec = find_rec_in_list(fHead, key);
-#endif
-    if (rec) {
-        this->moveToHead(rec);  // for our LRU
-        rec->fLockCount += 1;
-    }
-    return rec;
-}
-
-/**
-   This function finds the bounds of the bitmap *within its pixelRef*.
-   If the bitmap lacks a pixelRef, it will return an empty rect, since
-   that doesn't make sense.  This may be a useful enough function that
-   it should be somewhere else (in SkBitmap?). */
-static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) {
-    if (!(bm.pixelRef())) {
-        return SkIRect::MakeEmpty();
-    }
-    SkIPoint origin = bm.pixelRefOrigin();
-    return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
-}
-
-
-SkScaledImageCache::ID* SkScaledImageCache::findAndLock(uint32_t genID,
-                                                        int32_t width,
-                                                        int32_t height,
-                                                        SkBitmap* bitmap) {
-    Rec* rec = this->findAndLock(genID, SK_Scalar1, SK_Scalar1,
-                                 SkIRect::MakeWH(width, height));
-    if (rec) {
-        SkASSERT(NULL == rec->fMip);
-        SkASSERT(rec->fBitmap.pixelRef());
-        *bitmap = rec->fBitmap;
-    }
-    return rec_to_id(rec);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const SkBitmap& orig,
-                                                        SkScalar scaleX,
-                                                        SkScalar scaleY,
-                                                        SkBitmap* scaled) {
-    if (0 == scaleX || 0 == scaleY) {
-        // degenerate, and the key we use for mipmaps
-        return NULL;
-    }
-    Rec* rec = this->findAndLock(orig.getGenerationID(), scaleX,
-                                 scaleY, get_bounds_from_bitmap(orig));
-    if (rec) {
-        SkASSERT(NULL == rec->fMip);
-        SkASSERT(rec->fBitmap.pixelRef());
-        *scaled = rec->fBitmap;
-    }
-    return rec_to_id(rec);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig,
-                                                           SkMipMap const ** mip) {
-    Rec* rec = this->findAndLock(orig.getGenerationID(), 0, 0,
-                                 get_bounds_from_bitmap(orig));
-    if (rec) {
-        SkASSERT(rec->fMip);
-        SkASSERT(NULL == rec->fBitmap.pixelRef());
-        *mip = rec->fMip;
-    }
-    return rec_to_id(rec);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-/**
-   This private method is the fully general record adder. All other
-   record adders should call this funtion. */
-SkScaledImageCache::ID* SkScaledImageCache::addAndLock(SkScaledImageCache::Rec* rec) {
-    SkASSERT(rec);
-    // See if we already have this key (racy inserts, etc.)
-    Rec* existing = this->findAndLock(rec->fKey);
-    if (NULL != existing) {
-        // Since we already have a matching entry, just delete the new one and return.
-        // Call sites cannot assume the passed in object will live past this call.
-        existing->fBitmap = rec->fBitmap;
-        SkDELETE(rec);
-        return rec_to_id(existing);
-    }
-
-    this->addToHead(rec);
-    SkASSERT(1 == rec->fLockCount);
-#ifdef USE_HASH
-    SkASSERT(fHash);
-    fHash->add(rec);
-#endif
-    // We may (now) be overbudget, so see if we need to purge something.
-    this->purgeAsNeeded();
-    return rec_to_id(rec);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::addAndLock(uint32_t genID,
-                                                       int32_t width,
-                                                       int32_t height,
-                                                       const SkBitmap& bitmap) {
-    Key key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
-    Rec* rec = SkNEW_ARGS(Rec, (key, bitmap));
-    return this->addAndLock(rec);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig,
-                                                       SkScalar scaleX,
-                                                       SkScalar scaleY,
-                                                       const SkBitmap& scaled) {
-    if (0 == scaleX || 0 == scaleY) {
-        // degenerate, and the key we use for mipmaps
-        return NULL;
-    }
-    SkIRect bounds = get_bounds_from_bitmap(orig);
-    if (bounds.isEmpty()) {
-        return NULL;
-    }
-    Key key(orig.getGenerationID(), scaleX, scaleY, bounds);
-    Rec* rec = SkNEW_ARGS(Rec, (key, scaled));
-    return this->addAndLock(rec);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::addAndLockMip(const SkBitmap& orig,
-                                                          const SkMipMap* mip) {
-    SkIRect bounds = get_bounds_from_bitmap(orig);
-    if (bounds.isEmpty()) {
-        return NULL;
-    }
-    Key key(orig.getGenerationID(), 0, 0, bounds);
-    Rec* rec = SkNEW_ARGS(Rec, (key, mip));
-    return this->addAndLock(rec);
-}
-
-void SkScaledImageCache::unlock(SkScaledImageCache::ID* id) {
-    SkASSERT(id);
-
-#ifdef SK_DEBUG
-    {
-        bool found = false;
-        Rec* rec = fHead;
-        while (rec != NULL) {
-            if (rec == id_to_rec(id)) {
-                found = true;
-                break;
-            }
-            rec = rec->fNext;
-        }
-        SkASSERT(found);
-    }
-#endif
-    Rec* rec = id_to_rec(id);
-    SkASSERT(rec->fLockCount > 0);
-    rec->fLockCount -= 1;
-
-    // we may have been over-budget, but now have released something, so check
-    // if we should purge.
-    if (0 == rec->fLockCount) {
-        this->purgeAsNeeded();
-    }
-}
-
-void SkScaledImageCache::purgeAsNeeded() {
-    size_t byteLimit;
-    int    countLimit;
-
-    if (fDiscardableFactory) {
-        countLimit = SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT;
-        byteLimit = SK_MaxU32;  // no limit based on bytes
-    } else {
-        countLimit = SK_MaxS32; // no limit based on count
-        byteLimit = fTotalByteLimit;
-    }
-
-    size_t bytesUsed = fTotalBytesUsed;
-    int    countUsed = fCount;
-
-    Rec* rec = fTail;
-    while (rec) {
-        if (bytesUsed < byteLimit && countUsed < countLimit) {
-            break;
-        }
-
-        Rec* prev = rec->fPrev;
-        if (0 == rec->fLockCount) {
-            size_t used = rec->bytesUsed();
-            SkASSERT(used <= bytesUsed);
-            this->detach(rec);
-#ifdef USE_HASH
-            fHash->remove(rec->fKey);
-#endif
-
-            SkDELETE(rec);
-
-            bytesUsed -= used;
-            countUsed -= 1;
-        }
-        rec = prev;
-    }
-
-    fTotalBytesUsed = bytesUsed;
-    fCount = countUsed;
-}
-
-size_t SkScaledImageCache::setTotalByteLimit(size_t newLimit) {
-    size_t prevLimit = fTotalByteLimit;
-    fTotalByteLimit = newLimit;
-    if (newLimit < prevLimit) {
-        this->purgeAsNeeded();
-    }
-    return prevLimit;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkScaledImageCache::detach(Rec* rec) {
-    Rec* prev = rec->fPrev;
-    Rec* next = rec->fNext;
-
-    if (!prev) {
-        SkASSERT(fHead == rec);
-        fHead = next;
-    } else {
-        prev->fNext = next;
-    }
-
-    if (!next) {
-        fTail = prev;
-    } else {
-        next->fPrev = prev;
-    }
-
-    rec->fNext = rec->fPrev = NULL;
-}
-
-void SkScaledImageCache::moveToHead(Rec* rec) {
-    if (fHead == rec) {
-        return;
-    }
-
-    SkASSERT(fHead);
-    SkASSERT(fTail);
-
-    this->validate();
-
-    this->detach(rec);
-
-    fHead->fPrev = rec;
-    rec->fNext = fHead;
-    fHead = rec;
-
-    this->validate();
-}
-
-void SkScaledImageCache::addToHead(Rec* rec) {
-    this->validate();
-
-    rec->fPrev = NULL;
-    rec->fNext = fHead;
-    if (fHead) {
-        fHead->fPrev = rec;
-    }
-    fHead = rec;
-    if (!fTail) {
-        fTail = rec;
-    }
-    fTotalBytesUsed += rec->bytesUsed();
-    fCount += 1;
-
-    this->validate();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG
-void SkScaledImageCache::validate() const {
-    if (NULL == fHead) {
-        SkASSERT(NULL == fTail);
-        SkASSERT(0 == fTotalBytesUsed);
-        return;
-    }
-
-    if (fHead == fTail) {
-        SkASSERT(NULL == fHead->fPrev);
-        SkASSERT(NULL == fHead->fNext);
-        SkASSERT(fHead->bytesUsed() == fTotalBytesUsed);
-        return;
-    }
-
-    SkASSERT(NULL == fHead->fPrev);
-    SkASSERT(NULL != fHead->fNext);
-    SkASSERT(NULL == fTail->fNext);
-    SkASSERT(NULL != fTail->fPrev);
-
-    size_t used = 0;
-    int count = 0;
-    const Rec* rec = fHead;
-    while (rec) {
-        count += 1;
-        used += rec->bytesUsed();
-        SkASSERT(used <= fTotalBytesUsed);
-        rec = rec->fNext;
-    }
-    SkASSERT(fCount == count);
-
-    rec = fTail;
-    while (rec) {
-        SkASSERT(count > 0);
-        count -= 1;
-        SkASSERT(used >= rec->bytesUsed());
-        used -= rec->bytesUsed();
-        rec = rec->fPrev;
-    }
-
-    SkASSERT(0 == count);
-    SkASSERT(0 == used);
-}
-#endif
-
-void SkScaledImageCache::dump() const {
-    this->validate();
-
-    const Rec* rec = fHead;
-    int locked = 0;
-    while (rec) {
-        locked += rec->fLockCount > 0;
-        rec = rec->fNext;
-    }
-
-    SkDebugf("SkScaledImageCache: count=%d bytes=%d locked=%d %s\n",
-             fCount, fTotalBytesUsed, locked,
-             fDiscardableFactory ? "discardable" : "malloc");
-}
-
-size_t SkScaledImageCache::setSingleAllocationByteLimit(size_t newLimit) {
-    size_t oldLimit = fSingleAllocationByteLimit;
-    fSingleAllocationByteLimit = newLimit;
-    return oldLimit;
-}
-
-size_t SkScaledImageCache::getSingleAllocationByteLimit() const {
-    return fSingleAllocationByteLimit;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#include "SkThread.h"
-
-SK_DECLARE_STATIC_MUTEX(gMutex);
-static SkScaledImageCache* gScaledImageCache = NULL;
-static void cleanup_gScaledImageCache() {
-    // We'll clean this up in our own tests, but disable for clients.
-    // Chrome seems to have funky multi-process things going on in unit tests that
-    // makes this unsafe to delete when the main process atexit()s.
-    // SkLazyPtr does the same sort of thing.
-#if SK_DEVELOPER
-    SkDELETE(gScaledImageCache);
-#endif
-}
-
-/** Must hold gMutex when calling. */
-static SkScaledImageCache* get_cache() {
-    // gMutex is always held when this is called, so we don't need to be fancy in here.
-    gMutex.assertHeld();
-    if (NULL == gScaledImageCache) {
-#ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE
-        gScaledImageCache = SkNEW_ARGS(SkScaledImageCache, (SkDiscardableMemory::Create));
-#else
-        gScaledImageCache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT));
-#endif
-        atexit(cleanup_gScaledImageCache);
-    }
-    return gScaledImageCache;
-}
-
-
-SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(
-                                uint32_t pixelGenerationID,
-                                int32_t width,
-                                int32_t height,
-                                SkBitmap* scaled) {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->findAndLock(pixelGenerationID, width, height, scaled);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(
-                               uint32_t pixelGenerationID,
-                               int32_t width,
-                               int32_t height,
-                               const SkBitmap& scaled) {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->addAndLock(pixelGenerationID, width, height, scaled);
-}
-
-
-SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const SkBitmap& orig,
-                                                        SkScalar scaleX,
-                                                        SkScalar scaleY,
-                                                        SkBitmap* scaled) {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->findAndLock(orig, scaleX, scaleY, scaled);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::FindAndLockMip(const SkBitmap& orig,
-                                                       SkMipMap const ** mip) {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->findAndLockMip(orig, mip);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(const SkBitmap& orig,
-                                                       SkScalar scaleX,
-                                                       SkScalar scaleY,
-                                                       const SkBitmap& scaled) {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->addAndLock(orig, scaleX, scaleY, scaled);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::AddAndLockMip(const SkBitmap& orig,
-                                                          const SkMipMap* mip) {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->addAndLockMip(orig, mip);
-}
-
-void SkScaledImageCache::Unlock(SkScaledImageCache::ID* id) {
-    SkAutoMutexAcquire am(gMutex);
-    get_cache()->unlock(id);
-
-//    get_cache()->dump();
-}
-
-size_t SkScaledImageCache::GetTotalBytesUsed() {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->getTotalBytesUsed();
-}
-
-size_t SkScaledImageCache::GetTotalByteLimit() {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->getTotalByteLimit();
-}
-
-size_t SkScaledImageCache::SetTotalByteLimit(size_t newLimit) {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->setTotalByteLimit(newLimit);
-}
-
-SkBitmap::Allocator* SkScaledImageCache::GetAllocator() {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->allocator();
-}
-
-void SkScaledImageCache::Dump() {
-    SkAutoMutexAcquire am(gMutex);
-    get_cache()->dump();
-}
-
-size_t SkScaledImageCache::SetSingleAllocationByteLimit(size_t size) {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->setSingleAllocationByteLimit(size);
-}
-
-size_t SkScaledImageCache::GetSingleAllocationByteLimit() {
-    SkAutoMutexAcquire am(gMutex);
-    return get_cache()->getSingleAllocationByteLimit();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#include "SkGraphics.h"
-
-size_t SkGraphics::GetImageCacheTotalBytesUsed() {
-    return SkScaledImageCache::GetTotalBytesUsed();
-}
-
-size_t SkGraphics::GetImageCacheTotalByteLimit() {
-    return SkScaledImageCache::GetTotalByteLimit();
-}
-
-size_t SkGraphics::SetImageCacheTotalByteLimit(size_t newLimit) {
-    return SkScaledImageCache::SetTotalByteLimit(newLimit);
-}
-
-size_t SkGraphics::GetImageCacheSingleAllocationByteLimit() {
-    return SkScaledImageCache::GetSingleAllocationByteLimit();
-}
-
-size_t SkGraphics::SetImageCacheSingleAllocationByteLimit(size_t newLimit) {
-    return SkScaledImageCache::SetSingleAllocationByteLimit(newLimit);
-}
-
diff --git a/src/core/SkScaledImageCache.h b/src/core/SkScaledImageCache.h
deleted file mode 100644
index 817147e..0000000
--- a/src/core/SkScaledImageCache.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkScaledImageCache_DEFINED
-#define SkScaledImageCache_DEFINED
-
-#include "SkBitmap.h"
-
-class SkDiscardableMemory;
-class SkMipMap;
-
-/**
- *  Cache object for bitmaps (with possible scale in X Y as part of the key).
- *
- *  Multiple caches can be instantiated, but each instance is not implicitly
- *  thread-safe, so if a given instance is to be shared across threads, the
- *  caller must manage the access itself (e.g. via a mutex).
- *
- *  As a convenience, a global instance is also defined, which can be safely
- *  access across threads via the static methods (e.g. FindAndLock, etc.).
- */
-class SkScaledImageCache {
-public:
-    struct ID;
-
-    /**
-     *  Returns a locked/pinned SkDiscardableMemory instance for the specified
-     *  number of bytes, or NULL on failure.
-     */
-    typedef SkDiscardableMemory* (*DiscardableFactory)(size_t bytes);
-
-    /*
-     *  The following static methods are thread-safe wrappers around a global
-     *  instance of this cache.
-     */
-
-    static ID* FindAndLock(uint32_t pixelGenerationID,
-                           int32_t width,
-                           int32_t height,
-                           SkBitmap* returnedBitmap);
-
-    static ID* FindAndLock(const SkBitmap& original, SkScalar scaleX,
-                           SkScalar scaleY, SkBitmap* returnedBitmap);
-    static ID* FindAndLockMip(const SkBitmap& original,
-                              SkMipMap const** returnedMipMap);
-
-
-    static ID* AddAndLock(uint32_t pixelGenerationID,
-                          int32_t width,
-                          int32_t height,
-                          const SkBitmap& bitmap);
-
-    static ID* AddAndLock(const SkBitmap& original, SkScalar scaleX,
-                          SkScalar scaleY, const SkBitmap& bitmap);
-    static ID* AddAndLockMip(const SkBitmap& original, const SkMipMap* mipMap);
-
-    static void Unlock(ID*);
-
-    static size_t GetTotalBytesUsed();
-    static size_t GetTotalByteLimit();
-    static size_t SetTotalByteLimit(size_t newLimit);
-
-    static size_t SetSingleAllocationByteLimit(size_t);
-    static size_t GetSingleAllocationByteLimit();
-
-    static SkBitmap::Allocator* GetAllocator();
-
-    /**
-     *  Call SkDebugf() with diagnostic information about the state of the cache
-     */
-    static void Dump();
-
-    ///////////////////////////////////////////////////////////////////////////
-
-    /**
-     *  Construct the cache to call DiscardableFactory when it
-     *  allocates memory for the pixels. In this mode, the cache has
-     *  not explicit budget, and so methods like getTotalBytesUsed()
-     *  and getTotalByteLimit() will return 0, and setTotalByteLimit
-     *  will ignore its argument and return 0.
-     */
-    SkScaledImageCache(DiscardableFactory);
-
-    /**
-     *  Construct the cache, allocating memory with malloc, and respect the
-     *  byteLimit, purging automatically when a new image is added to the cache
-     *  that pushes the total bytesUsed over the limit. Note: The limit can be
-     *  changed at runtime with setTotalByteLimit.
-     */
-    SkScaledImageCache(size_t byteLimit);
-
-    ~SkScaledImageCache();
-
-    /**
-     *  Search the cache for a matching bitmap (using generationID,
-     *  width, and height as a search key). If found, return it in
-     *  returnedBitmap, and return its ID pointer. Use the returned
-     *  ptr to unlock the cache when you are done using
-     *  returnedBitmap.
-     *
-     *  If a match is not found, returnedBitmap will be unmodifed, and
-     *  NULL will be returned.
-     *
-     *  This is used if there is no scaling or subsetting, for example
-     *  by SkLazyPixelRef.
-     */
-    ID* findAndLock(uint32_t pixelGenerationID, int32_t width, int32_t height,
-                    SkBitmap* returnedBitmap);
-
-    /**
-     *  Search the cache for a scaled version of original. If found,
-     *  return it in returnedBitmap, and return its ID pointer. Use
-     *  the returned ptr to unlock the cache when you are done using
-     *  returnedBitmap.
-     *
-     *  If a match is not found, returnedBitmap will be unmodifed, and
-     *  NULL will be returned.
-     */
-    ID* findAndLock(const SkBitmap& original, SkScalar scaleX,
-                    SkScalar scaleY, SkBitmap* returnedBitmap);
-    ID* findAndLockMip(const SkBitmap& original,
-                       SkMipMap const** returnedMipMap);
-
-    /**
-     *  To add a new bitmap (or mipMap) to the cache, call
-     *  AddAndLock. Use the returned ptr to unlock the cache when you
-     *  are done using scaled.
-     *
-     *  Use (generationID, width, and height) or (original, scaleX,
-     *  scaleY) or (original) as a search key
-     */
-    ID* addAndLock(uint32_t pixelGenerationID, int32_t width, int32_t height,
-                   const SkBitmap& bitmap);
-    ID* addAndLock(const SkBitmap& original, SkScalar scaleX,
-                   SkScalar scaleY, const SkBitmap& bitmap);
-    ID* addAndLockMip(const SkBitmap& original, const SkMipMap* mipMap);
-
-    /**
-     *  Given a non-null ID ptr returned by either findAndLock or addAndLock,
-     *  this releases the associated resources to be available to be purged
-     *  if needed. After this, the cached bitmap should no longer be
-     *  referenced by the caller.
-     */
-    void unlock(ID*);
-
-    size_t getTotalBytesUsed() const { return fTotalBytesUsed; }
-    size_t getTotalByteLimit() const { return fTotalByteLimit; }
-
-    /**
-     *  This is respected by SkBitmapProcState::possiblyScaleImage.
-     *  0 is no maximum at all; this is the default.
-     *  setSingleAllocationByteLimit() returns the previous value.
-     */
-    size_t setSingleAllocationByteLimit(size_t maximumAllocationSize);
-    size_t getSingleAllocationByteLimit() const;
-    /**
-     *  Set the maximum number of bytes available to this cache. If the current
-     *  cache exceeds this new value, it will be purged to try to fit within
-     *  this new limit.
-     */
-    size_t setTotalByteLimit(size_t newLimit);
-
-    SkBitmap::Allocator* allocator() const { return fAllocator; };
-
-    /**
-     *  Call SkDebugf() with diagnostic information about the state of the cache
-     */
-    void dump() const;
-
-public:
-    struct Rec;
-    struct Key;
-private:
-    Rec*    fHead;
-    Rec*    fTail;
-
-    class Hash;
-    Hash*   fHash;
-
-    DiscardableFactory  fDiscardableFactory;
-    // the allocator is NULL or one that matches discardables
-    SkBitmap::Allocator* fAllocator;
-
-    size_t  fTotalBytesUsed;
-    size_t  fTotalByteLimit;
-    size_t  fSingleAllocationByteLimit;
-    int     fCount;
-
-    Rec* findAndLock(uint32_t generationID, SkScalar sx, SkScalar sy,
-                     const SkIRect& bounds);
-    Rec* findAndLock(const Key& key);
-    ID* addAndLock(Rec* rec);
-
-    void purgeRec(Rec*);
-    void purgeAsNeeded();
-
-    // linklist management
-    void moveToHead(Rec*);
-    void addToHead(Rec*);
-    void detach(Rec*);
-
-    void init();    // called by constructors
-
-#ifdef SK_DEBUG
-    void validate() const;
-#else
-    void validate() const {}
-#endif
-};
-#endif
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index 3e20bf6..4d7f362 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -23,10 +23,6 @@
 #include "SkStroke.h"
 #include "SkThread.h"
 
-#ifdef SK_BUILD_FOR_ANDROID
-    #include "SkTypeface_android.h"
-#endif
-
 #define ComputeBWRowBytes(width)        (((unsigned)(width) + 7) >> 3)
 
 void SkGlyph::toMask(SkMask* mask) const {
@@ -83,7 +79,6 @@
 SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc)
     : fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, NULL)))
 
-    , fBaseGlyphCount(0)
     , fTypeface(SkRef(typeface))
     , fPathEffect(static_cast<SkPathEffect*>(load_flattenable(desc, kPathEffect_SkDescriptorTag,
                                              SkFlattenable::kSkPathEffect_Type)))
@@ -94,8 +89,6 @@
       // Initialize based on our settings. Subclasses can also force this.
     , fGenerateImageFromPath(fRec.fFrameWidth > 0 || fPathEffect != NULL || fRasterizer != NULL)
 
-    , fNextContext(NULL)
-
     , fPreBlend(fMaskFilter ? SkMaskGamma::PreBlend() : SkScalerContext::GetMaskPreBlend(fRec))
     , fPreBlendForFilter(fMaskFilter ? SkScalerContext::GetMaskPreBlend(fRec)
                                      : SkMaskGamma::PreBlend())
@@ -114,192 +107,25 @@
              desc->findEntry(kPathEffect_SkDescriptorTag, NULL),
         desc->findEntry(kMaskFilter_SkDescriptorTag, NULL));
 #endif
-#ifdef SK_BUILD_FOR_ANDROID
-    uint32_t len;
-    const void* data = desc->findEntry(kAndroidOpts_SkDescriptorTag, &len);
-    if (data) {
-        SkReadBuffer buffer(data, len);
-        fPaintOptionsAndroid.unflatten(buffer);
-        SkASSERT(buffer.offset() == buffer.size());
-    }
-#endif
 }
 
 SkScalerContext::~SkScalerContext() {
-    SkDELETE(fNextContext);
-
     SkSafeUnref(fPathEffect);
     SkSafeUnref(fMaskFilter);
     SkSafeUnref(fRasterizer);
 }
 
-// Return the context associated with the next logical typeface, or NULL if
-// there are no more entries in the fallback chain.
-SkScalerContext* SkScalerContext::allocNextContext() const {
-#ifdef SK_BUILD_FOR_ANDROID
-    SkTypeface* newFace = SkAndroidNextLogicalTypeface(fRec.fFontID,
-                                                       fRec.fOrigFontID,
-                                                       fPaintOptionsAndroid);
-    if (0 == newFace) {
-        return NULL;
-    }
-
-    SkAutoTUnref<SkTypeface> aur(newFace);
-    uint32_t newFontID = newFace->uniqueID();
-
-    SkWriteBuffer androidBuffer;
-    fPaintOptionsAndroid.flatten(androidBuffer);
-
-    SkAutoDescriptor    ad(sizeof(fRec) + androidBuffer.bytesWritten()
-                           + SkDescriptor::ComputeOverhead(2));
-    SkDescriptor*       desc = ad.getDesc();
-
-    desc->init();
-    SkScalerContext::Rec* newRec =
-    (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag,
-                                          sizeof(fRec), &fRec);
-    androidBuffer.writeToMemory(desc->addEntry(kAndroidOpts_SkDescriptorTag,
-                                               androidBuffer.bytesWritten(), NULL));
-
-    newRec->fFontID = newFontID;
-    desc->computeChecksum();
-
-    return newFace->createScalerContext(desc);
-#else
-    return NULL;
-#endif
-}
-
-/*  Return the next context, creating it if its not already created, but return
-    NULL if the fonthost says there are no more fonts to fallback to.
- */
-SkScalerContext* SkScalerContext::getNextContext() {
-    SkScalerContext* next = fNextContext;
-    // if next is null, then either it isn't cached yet, or we're at the
-    // end of our possible chain
-    if (NULL == next) {
-        next = this->allocNextContext();
-        if (NULL == next) {
-            return NULL;
-        }
-        // next's base is our base + our local count
-        next->setBaseGlyphCount(fBaseGlyphCount + this->getGlyphCount());
-        // cache the answer
-        fNextContext = next;
-    }
-    return next;
-}
-
-SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
-    unsigned glyphID = glyph.getGlyphID();
-    SkScalerContext* ctx = this;
-    for (;;) {
-        unsigned count = ctx->getGlyphCount();
-        if (glyphID < count) {
-            break;
-        }
-        glyphID -= count;
-        ctx = ctx->getNextContext();
-        if (NULL == ctx) {
-//            SkDebugf("--- no context for glyph %x\n", glyph.getGlyphID());
-            // just return the original context (this)
-            return this;
-        }
-    }
-    return ctx;
-}
-
-SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni,
-                                                     uint16_t* glyphID) {
-    SkScalerContext* ctx = this;
-    for (;;) {
-        const uint16_t glyph = ctx->generateCharToGlyph(uni);
-        if (glyph) {
-            if (NULL != glyphID) {
-                *glyphID = glyph;
-            }
-            break;  // found it
-        }
-        ctx = ctx->getNextContext();
-        if (NULL == ctx) {
-            return NULL;
-        }
-    }
-    return ctx;
-}
-
-#ifdef SK_BUILD_FOR_ANDROID
-SkFontID SkScalerContext::findTypefaceIdForChar(SkUnichar uni) {
-    SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
-    if (NULL != ctx) {
-        return ctx->fRec.fFontID;
-    } else {
-        return 0;
-    }
-}
-
-/*  This loops through all available fallback contexts (if needed) until it
-    finds some context that can handle the unichar and return it.
-
-    As this is somewhat expensive operation, it should only be done on the first
-    char of a run.
- */
-unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) {
-    SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
-    if (NULL != ctx) {
-        return ctx->fBaseGlyphCount;
-    } else {
-        SkDEBUGF(("--- no context for char %x\n", uni));
-        return this->fBaseGlyphCount;
-    }
-}
-#endif
-
-/*  This loops through all available fallback contexts (if needed) until it
-    finds some context that can handle the unichar. If all fail, returns 0
- */
-uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) {
-
-    uint16_t tempID;
-    SkScalerContext* ctx = this->getContextFromChar(uni, &tempID);
-    if (NULL == ctx) {
-        return 0; // no more contexts, return missing glyph
-    }
-    // add the ctx's base, making glyphID unique for chain of contexts
-    unsigned glyphID = tempID + ctx->fBaseGlyphCount;
-    // check for overflow of 16bits, since our glyphID cannot exceed that
-    if (glyphID > 0xFFFF) {
-        glyphID = 0;
-    }
-    return SkToU16(glyphID);
-}
-
-SkUnichar SkScalerContext::glyphIDToChar(uint16_t glyphID) {
-    SkScalerContext* ctx = this;
-    unsigned rangeEnd = 0;
-    do {
-        unsigned rangeStart = rangeEnd;
-
-        rangeEnd += ctx->getGlyphCount();
-        if (rangeStart <= glyphID && glyphID < rangeEnd) {
-            return ctx->generateGlyphToChar(glyphID - rangeStart);
-        }
-        ctx = ctx->getNextContext();
-    } while (NULL != ctx);
-    return 0;
-}
-
 void SkScalerContext::getAdvance(SkGlyph* glyph) {
     // mark us as just having a valid advance
     glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE;
     // we mark the format before making the call, in case the impl
     // internally ends up calling its generateMetrics, which is OK
     // albeit slower than strictly necessary
-    this->getGlyphContext(*glyph)->generateAdvance(glyph);
+    generateAdvance(glyph);
 }
 
 void SkScalerContext::getMetrics(SkGlyph* glyph) {
-    this->getGlyphContext(*glyph)->generateMetrics(glyph);
+    generateMetrics(glyph);
 
     // for now we have separate cache entries for devkerning on and off
     // in the future we might share caches, but make our measure/draw
@@ -611,7 +437,7 @@
     SkBitmap bm;
 
     if (0 == dstRB) {
-        if (!bm.allocPixels(info)) {
+        if (!bm.tryAllocPixels(info)) {
             // can't allocate offscreen, so empty the mask and return
             sk_bzero(mask.fImage, mask.computeImageSize());
             return;
@@ -737,7 +563,7 @@
             generateMask(mask, devPath, fPreBlend);
         }
     } else {
-        this->getGlyphContext(*glyph)->generateImage(*glyph);
+        generateImage(*glyph);
     }
 
     if (fMaskFilter) {
@@ -799,16 +625,7 @@
 }
 
 void SkScalerContext::getFontMetrics(SkPaint::FontMetrics* fm) {
-    // All of this complexity should go away when we change generateFontMetrics
-    // to just take one parameter (since it knows if it is vertical or not)
-    SkPaint::FontMetrics* mx = NULL;
-    SkPaint::FontMetrics* my = NULL;
-    if (fRec.fFlags & kVertical_Flag) {
-        mx = fm;
-    } else {
-        my = fm;
-    }
-    this->generateFontMetrics(mx, my);
+    this->generateFontMetrics(fm);
 }
 
 SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) {
@@ -820,8 +637,7 @@
 void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
                                   SkPath* devPath, SkMatrix* fillToDevMatrix) {
     SkPath  path;
-
-    this->getGlyphContext(glyph)->generatePath(glyph, &path);
+    generatePath(glyph, &path);
 
     if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
         SkFixed dx = glyph.getSubXFixed();
@@ -964,13 +780,9 @@
     }
     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE {}
     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE {}
-    virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
-                                     SkPaint::FontMetrics* my) SK_OVERRIDE {
-        if (mx) {
-            sk_bzero(mx, sizeof(*mx));
-        }
-        if (my) {
-            sk_bzero(my, sizeof(*my));
+    virtual void generateFontMetrics(SkPaint::FontMetrics* metrics) SK_OVERRIDE {
+        if (metrics) {
+            sk_bzero(metrics, sizeof(*metrics));
         }
     }
 };
diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h
index af83685..337b2e0 100644
--- a/src/core/SkScalerContext.h
+++ b/src/core/SkScalerContext.h
@@ -14,10 +14,6 @@
 #include "SkPaint.h"
 #include "SkTypeface.h"
 
-#ifdef SK_BUILD_FOR_ANDROID
-    #include "SkPaintOptionsAndroid.h"
-#endif
-
 struct SkGlyph;
 class SkDescriptor;
 class SkMaskFilter;
@@ -29,7 +25,6 @@
  *  than a nested struct inside SkScalerContext (where it started).
  */
 struct SkScalerContextRec {
-    uint32_t    fOrigFontID;
     uint32_t    fFontID;
     SkScalar    fTextSize, fPreScaleX, fPreSkewX;
     SkScalar    fPost2x2[2][2];
@@ -160,9 +155,8 @@
         return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
     }
 
-    // remember our glyph offset/base
-    void setBaseGlyphCount(unsigned baseGlyphCount) {
-        fBaseGlyphCount = baseGlyphCount;
+    bool isVertical() const {
+        return SkToBool(fRec.fFlags & kVertical_Flag);
     }
 
     /** Return the corresponding glyph for the specified unichar. Since contexts
@@ -170,12 +164,16 @@
         fact correspond to a different font/context. In that case, we use the
         base-glyph-count to know how to translate back into local glyph space.
      */
-    uint16_t charToGlyphID(SkUnichar uni);
+    uint16_t charToGlyphID(SkUnichar uni) {
+        return generateCharToGlyph(uni);
+    }
 
     /** Map the glyphID to its glyph index, and then to its char code. Unmapped
         glyphs return zero.
     */
-    SkUnichar glyphIDToChar(uint16_t glyphID);
+    SkUnichar glyphIDToChar(uint16_t glyphID) {
+        return (glyphID < getGlyphCount()) ? generateGlyphToChar(glyphID) : 0;
+    }
 
     unsigned    getGlyphCount() { return this->generateGlyphCount(); }
     void        getAdvance(SkGlyph*);
@@ -195,14 +193,6 @@
     static void   GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma,
                                   void* data);
 
-#ifdef SK_BUILD_FOR_ANDROID
-    unsigned getBaseGlyphCount(SkUnichar charCode);
-
-    // This function must be public for SkTypeface_android.h, but should not be
-    // called by other callers
-    SkFontID findTypefaceIdForChar(SkUnichar uni);
-#endif
-
     static void MakeRec(const SkPaint&, const SkDeviceProperties* deviceProperties,
                         const SkMatrix*, Rec* rec);
     static inline void PostMakeRec(const SkPaint&, Rec*);
@@ -211,7 +201,6 @@
 
 protected:
     Rec         fRec;
-    unsigned    fBaseGlyphCount;
 
     /** Generates the contents of glyph.fAdvanceX and glyph.fAdvanceY.
      *  May call getMetrics if that would be just as fast.
@@ -245,11 +234,8 @@
      */
     virtual void generatePath(const SkGlyph& glyph, SkPath* path) = 0;
 
-    /** Retrieves font metrics.
-     *  TODO: there is now a vertical bit, no need for two parameters.
-     */
-    virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
-                                     SkPaint::FontMetrics* mY) = 0;
+    /** Retrieves font metrics. */
+    virtual void generateFontMetrics(SkPaint::FontMetrics*) = 0;
 
     /** Returns the number of glyphs in the font. */
     virtual unsigned generateGlyphCount() = 0;
@@ -271,10 +257,6 @@
     // never null
     SkAutoTUnref<SkTypeface> fTypeface;
 
-#ifdef SK_BUILD_FOR_ANDROID
-    SkPaintOptionsAndroid fPaintOptionsAndroid;
-#endif
-
     // optional object, which may be null
     SkPathEffect*   fPathEffect;
     SkMaskFilter*   fMaskFilter;
@@ -287,25 +269,11 @@
     void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
                          SkPath* devPath, SkMatrix* fillToDevMatrix);
 
-    // Return the context associated with the next logical typeface, or NULL if
-    // there are no more entries in the fallback chain.
-    SkScalerContext* allocNextContext() const;
-
-    // return the next context, treating fNextContext as a cache of the answer
-    SkScalerContext* getNextContext();
-
-    // returns the right context from our link-list for this glyph. If no match
-    // is found, just returns the original context (this)
-    SkScalerContext* getGlyphContext(const SkGlyph& glyph);
-
     // returns the right context from our link-list for this char. If no match
     // is found it returns NULL. If a match is found then the glyphID param is
     // set to the glyphID that maps to the provided char.
     SkScalerContext* getContextFromChar(SkUnichar uni, uint16_t* glyphID);
 
-    // link-list of context, to handle missing chars. null-terminated.
-    SkScalerContext* fNextContext;
-
     // SkMaskGamma::PreBlend converts linear masks to gamma correcting masks.
 protected:
     // Visible to subclasses so that generateImage can apply the pre-blend directly.
@@ -320,9 +288,6 @@
 #define kPathEffect_SkDescriptorTag     SkSetFourByteTag('p', 't', 'h', 'e')
 #define kMaskFilter_SkDescriptorTag     SkSetFourByteTag('m', 's', 'k', 'f')
 #define kRasterizer_SkDescriptorTag     SkSetFourByteTag('r', 'a', 's', 't')
-#ifdef SK_BUILD_FOR_ANDROID
-#define kAndroidOpts_SkDescriptorTag    SkSetFourByteTag('a', 'n', 'd', 'r')
-#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp
index e5c67a9..b7d4707 100644
--- a/src/core/SkScan_AntiPath.cpp
+++ b/src/core/SkScan_AntiPath.cpp
@@ -108,7 +108,6 @@
 
     virtual ~SuperBlitter() {
         this->flush();
-        sk_free(fRuns.fRuns);
     }
 
     /// Once fRuns contains a complete supersampled row, flush() blits
@@ -123,31 +122,56 @@
     virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
 
 private:
+    // The next three variables are used to track a circular buffer that
+    // contains the values used in SkAlphaRuns. These variables should only
+    // ever be updated in advanceRuns(), and fRuns should always point to
+    // a valid SkAlphaRuns...
+    int         fRunsToBuffer;
+    void*       fRunsBuffer;
+    int         fCurrentRun;
     SkAlphaRuns fRuns;
+
+    // extra one to store the zero at the end
+    int getRunsSz() const { return (fWidth + 1 + (fWidth + 2)/2) * sizeof(int16_t); }
+
+    // This function updates the fRuns variable to point to the next buffer space
+    // with adequate storage for a SkAlphaRuns. It mostly just advances fCurrentRun
+    // and resets fRuns to point to an empty scanline.
+    void advanceRuns() {
+        const size_t kRunsSz = this->getRunsSz();
+        fCurrentRun = (fCurrentRun + 1) % fRunsToBuffer;
+        fRuns.fRuns = reinterpret_cast<int16_t*>(
+            reinterpret_cast<uint8_t*>(fRunsBuffer) + fCurrentRun * kRunsSz);
+        fRuns.fAlpha = reinterpret_cast<SkAlpha*>(fRuns.fRuns + fWidth + 1);
+        fRuns.reset(fWidth);
+    }
+
     int         fOffsetX;
 };
 
 SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
                            const SkRegion& clip)
         : BaseSuperBlitter(realBlitter, ir, clip) {
-    const int width = fWidth;
+    fRunsToBuffer = realBlitter->requestRowsPreserved();
+    fRunsBuffer = realBlitter->allocBlitMemory(fRunsToBuffer * this->getRunsSz());
+    fCurrentRun = -1;
 
-    // extra one to store the zero at the end
-    fRuns.fRuns = (int16_t*)sk_malloc_throw((width + 1 + (width + 2)/2) * sizeof(int16_t));
-    fRuns.fAlpha = (uint8_t*)(fRuns.fRuns + width + 1);
-    fRuns.reset(width);
+    this->advanceRuns();
 
     fOffsetX = 0;
 }
 
 void SuperBlitter::flush() {
     if (fCurrIY >= fTop) {
+
+        SkASSERT(fCurrentRun < fRunsToBuffer);
         if (!fRuns.empty()) {
-        //  SkDEBUGCODE(fRuns.dump();)
+            // SkDEBUGCODE(fRuns.dump();)
             fRealBlitter->blitAntiH(fLeft, fCurrIY, fRuns.fAlpha, fRuns.fRuns);
-            fRuns.reset(fWidth);
+            this->advanceRuns();
             fOffsetX = 0;
         }
+
         fCurrIY = fTop - 1;
         SkDEBUGCODE(fCurrX = -1;)
     }
diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp
index b32d68e..184f66c 100644
--- a/src/core/SkScan_Path.cpp
+++ b/src/core/SkScan_Path.cpp
@@ -432,7 +432,7 @@
 void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitter,
                   int start_y, int stop_y, int shiftEdgesUp,
                   const SkRegion& clipRgn) {
-    SkASSERT(&path && blitter);
+    SkASSERT(blitter);
 
     SkEdgeBuilder   builder;
 
@@ -727,7 +727,7 @@
 
     SkScanClipper clipper(blitter, clipRgn, ir);
     blitter = clipper.getBlitter();
-    if (NULL != blitter) {
+    if (blitter) {
         sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir);
     }
 }
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 18fb0d2..d8e4085 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "SkBitmapProcShader.h"
+#include "SkColorShader.h"
 #include "SkEmptyShader.h"
 #include "SkReadBuffer.h"
 #include "SkMallocPixelRef.h"
@@ -45,6 +46,7 @@
     }
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkShader::SkShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     inc_shader_counter();
     if (buffer.readBool()) {
@@ -53,6 +55,7 @@
         fLocalMatrix.reset();
     }
 }
+#endif
 
 SkShader::~SkShader() {
     dec_shader_counter();
@@ -79,6 +82,18 @@
     return m->invert(totalInverse);
 }
 
+bool SkShader::asLuminanceColor(SkColor* colorPtr) const {
+    SkColor storage;
+    if (NULL == colorPtr) {
+        colorPtr = &storage;
+    }
+    if (this->onAsLuminanceColor(colorPtr)) {
+        *colorPtr = SkColorSetA(*colorPtr, 0xFF);   // we only return opaque
+        return true;
+    }
+    return false;
+}
+
 SkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage) const {
     if (!this->computeTotalInverse(rec, NULL)) {
         return NULL;
@@ -208,9 +223,8 @@
     return kNone_GradientType;
 }
 
-bool SkShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                           const SkMatrix* localMatrixOrNull, GrColor* grColor,
-                           GrEffectRef** grEffect)  const {
+bool SkShader::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                   GrFragmentProcessor**)  const {
     return false;
 }
 
@@ -222,14 +236,18 @@
     return SkNEW(SkEmptyShader);
 }
 
+SkShader* SkShader::CreateColorShader(SkColor color) {
+    return SkNEW_ARGS(SkColorShader, (color));
+}
+
 SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
                                        const SkMatrix* localMatrix) {
     return ::CreateBitmapShader(src, tmx, tmy, localMatrix, NULL);
 }
 
 SkShader* SkShader::CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy,
-                                       const SkMatrix* localMatrix) {
-    return SkPictureShader::Create(src, tmx, tmy, localMatrix);
+                                        const SkMatrix* localMatrix, const SkRect* tile) {
+    return SkPictureShader::Create(src, tmx, tmy, localMatrix, tile);
 }
 
 #ifndef SK_IGNORE_TO_STRING
@@ -243,7 +261,6 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-#include "SkColorShader.h"
 #include "SkUtils.h"
 
 SkColorShader::SkColorShader(SkColor c)
@@ -254,6 +271,7 @@
     return SkColorGetA(fColor) == 255;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) {
     // V25_COMPATIBILITY_CODE We had a boolean to make the color shader inherit the paint's
     // color. We don't support that any more.
@@ -266,9 +284,13 @@
     }
     fColor = b.readColor();
 }
+#endif
+
+SkFlattenable* SkColorShader::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW_ARGS(SkColorShader, (buffer.readColor()));
+}
 
 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeColor(fColor);
 }
 
@@ -347,21 +369,19 @@
 
 #include "SkGr.h"
 
-bool SkColorShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                const SkMatrix* localMatrix, GrColor* grColor,
-                                GrEffectRef** grEffect) const {
-    *grEffect = NULL;
+bool SkColorShader::asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix*,
+                                        GrColor* paintColor, GrFragmentProcessor** fp) const {
+    *fp = NULL;
     SkColor skColor = fColor;
     U8CPU newA = SkMulDiv255Round(SkColorGetA(fColor), paint.getAlpha());
-    *grColor = SkColor2GrColor(SkColorSetA(skColor, newA));
+    *paintColor = SkColor2GrColor(SkColorSetA(skColor, newA));
     return true;
 }
 
 #else
 
-bool SkColorShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                     const SkMatrix* localMatrix, GrColor* grColor,
-                                     GrEffectRef** grEffect) const {
+bool SkColorShader::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                        GrFragmentProcessor**) const {
     SkDEBUGFAIL("Should not call in GPU-less build");
     return false;
 }
@@ -383,6 +403,10 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+SkFlattenable* SkEmptyShader::CreateProc(SkReadBuffer&) {
+    return SkShader::CreateEmptyShader();
+}
+
 #ifndef SK_IGNORE_TO_STRING
 #include "SkEmptyShader.h"
 
diff --git a/src/core/SkSpriteBlitter_ARGB32.cpp b/src/core/SkSpriteBlitter_ARGB32.cpp
index a4ae41c..142d6ca 100644
--- a/src/core/SkSpriteBlitter_ARGB32.cpp
+++ b/src/core/SkSpriteBlitter_ARGB32.cpp
@@ -135,12 +135,12 @@
         do {
             const SkPMColor* tmp = src;
 
-            if (NULL != colorFilter) {
+            if (colorFilter) {
                 colorFilter->filterSpan(src, width, fBuffer);
                 tmp = fBuffer;
             }
 
-            if (NULL != xfermode) {
+            if (xfermode) {
                 xfermode->xfer32(dst, tmp, width, NULL);
             } else {
                 fProc32(dst, tmp, width, fAlpha);
@@ -183,10 +183,10 @@
         do {
             fillbuffer(buffer, src, width);
 
-            if (NULL != colorFilter) {
+            if (colorFilter) {
                 colorFilter->filterSpan(buffer, width, buffer);
             }
-            if (NULL != xfermode) {
+            if (xfermode) {
                 xfermode->xfer32(dst, buffer, width, NULL);
             } else {
                 fProc32(dst, buffer, width, fAlpha);
diff --git a/src/core/SkSpriteBlitter_RGB16.cpp b/src/core/SkSpriteBlitter_RGB16.cpp
index 1ba3ee2..3d1d28d 100644
--- a/src/core/SkSpriteBlitter_RGB16.cpp
+++ b/src/core/SkSpriteBlitter_RGB16.cpp
@@ -321,15 +321,23 @@
         return NULL;
     }
 
+    const SkAlphaType at = source.alphaType();
+
     SkSpriteBlitter* blitter = NULL;
     unsigned alpha = paint.getAlpha();
 
     switch (source.colorType()) {
         case kN32_SkColorType: {
+            if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) {
+                break;
+            }
             blitter = allocator->createT<Sprite_D16_S32_BlitRowProc>(source);
             break;
         }
         case kARGB_4444_SkColorType:
+            if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) {
+                break;
+            }
             if (255 == alpha) {
                 blitter = allocator->createT<Sprite_D16_S4444_Opaque>(source);
             } else {
@@ -344,6 +352,9 @@
             }
             break;
         case kIndex_8_SkColorType:
+            if (kPremul_SkAlphaType != at && kOpaque_SkAlphaType != at) {
+                break;
+            }
             if (paint.isDither()) {
                 // we don't support dither yet in these special cases
                 break;
diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp
index ebaac9a..ff14a8b 100644
--- a/src/core/SkStream.cpp
+++ b/src/core/SkStream.cpp
@@ -8,10 +8,12 @@
 
 
 #include "SkStream.h"
+#include "SkStreamPriv.h"
 #include "SkData.h"
 #include "SkFixed.h"
 #include "SkString.h"
 #include "SkOSFile.h"
+#include "SkTypes.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -62,17 +64,6 @@
     }
 }
 
-SkData* SkStream::readData() {
-    size_t size = this->readU32();
-    if (0 == size) {
-        return SkData::NewEmpty();
-    } else {
-        void* buffer = sk_malloc_throw(size);
-        this->read(buffer, size);
-        return SkData::NewFromMalloc(buffer, size);
-    }
-}
-
 //////////////////////////////////////////////////////////////////////////////////////
 
 SkWStream::~SkWStream()
@@ -187,16 +178,6 @@
     return true;
 }
 
-bool SkWStream::writeData(const SkData* data) {
-    if (data) {
-        this->write32(SkToU32(data->size()));
-        this->write(data->data(), data->size());
-    } else {
-        this->write32(0);
-    }
-    return true;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 SkFILEStream::SkFILEStream(const char file[]) : fName(file), fOwnership(kCallerPasses_Ownership) {
@@ -253,7 +234,7 @@
         return new SkMemoryStream();
     }
 
-    if (NULL != fData.get()) {
+    if (fData.get()) {
         return new SkMemoryStream(fData);
     }
 
@@ -306,7 +287,7 @@
     if (copyData) {
         return SkData::NewWithCopy(src, size);
     } else {
-        return SkData::NewWithProc(src, size, NULL, NULL);
+        return SkData::NewWithoutCopy(src, size);
     }
 }
 
@@ -316,7 +297,7 @@
 }
 
 SkMemoryStream::SkMemoryStream(size_t size) {
-    fData = SkData::NewFromMalloc(sk_malloc_throw(size), size);
+    fData = SkData::NewUninitialized(size);
     fOffset = 0;
 }
 
@@ -652,12 +633,12 @@
 
 SkData* SkDynamicMemoryWStream::copyToData() const {
     if (NULL == fCopy) {
-        void* buffer = sk_malloc_throw(fBytesWritten);
-        this->copyTo(buffer);
-        fCopy = SkData::NewFromMalloc(buffer, fBytesWritten);
+        SkData* data = SkData::NewUninitialized(fBytesWritten);
+        // be sure to call copyTo() before we assign to fCopy
+        this->copyTo(data->writable_data());
+        fCopy = data;
     }
-    fCopy->ref();
-    return fCopy;
+    return SkRef(fCopy);
 }
 
 void SkDynamicMemoryWStream::invalidateCopy() {
@@ -851,3 +832,80 @@
     }
     return stream;
 }
+
+// Declared in SkStreamPriv.h:
+size_t SkCopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream) {
+    SkASSERT(storage != NULL);
+    SkASSERT(stream != NULL);
+
+    if (stream->hasLength()) {
+        const size_t length = stream->getLength();
+        void* dst = storage->reset(length);
+        if (stream->read(dst, length) != length) {
+            return 0;
+        }
+        return length;
+    }
+
+    SkDynamicMemoryWStream tempStream;
+    // Arbitrary buffer size.
+    const size_t bufferSize = 256 * 1024; // 256KB
+    char buffer[bufferSize];
+    SkDEBUGCODE(size_t debugLength = 0;)
+    do {
+        size_t bytesRead = stream->read(buffer, bufferSize);
+        tempStream.write(buffer, bytesRead);
+        SkDEBUGCODE(debugLength += bytesRead);
+        SkASSERT(tempStream.bytesWritten() == debugLength);
+    } while (!stream->isAtEnd());
+    const size_t length = tempStream.bytesWritten();
+    void* dst = storage->reset(length);
+    tempStream.copyTo(dst);
+    return length;
+}
+
+// Declared in SkStreamPriv.h:
+SkData* SkCopyStreamToData(SkStream* stream) {
+    SkASSERT(stream != NULL);
+
+    if (stream->hasLength()) {
+        return SkData::NewFromStream(stream, stream->getLength());
+    }
+
+    SkDynamicMemoryWStream tempStream;
+    const size_t bufferSize = 4096;
+    char buffer[bufferSize];
+    do {
+        size_t bytesRead = stream->read(buffer, bufferSize);
+        tempStream.write(buffer, bytesRead);
+    } while (!stream->isAtEnd());
+    return tempStream.copyToData();
+}
+
+SkStreamRewindable* SkStreamRewindableFromSkStream(SkStream* stream) {
+    if (!stream) {
+        return NULL;
+    }
+    SkAutoTUnref<SkStreamRewindable> dupStream(stream->duplicate());
+    if (dupStream) {
+        return dupStream.detach();
+    }
+    stream->rewind();
+    if (stream->hasLength()) {
+        size_t length = stream->getLength();
+        if (stream->hasPosition()) {  // If stream has length, but can't rewind.
+            length -= stream->getPosition();
+        }
+        SkAutoTUnref<SkData> data(SkData::NewFromStream(stream, length));
+        return SkNEW_ARGS(SkMemoryStream, (data.get()));
+    }
+    SkDynamicMemoryWStream tempStream;
+    const size_t bufferSize = 4096;
+    char buffer[bufferSize];
+    do {
+        size_t bytesRead = stream->read(buffer, bufferSize);
+        tempStream.write(buffer, bytesRead);
+    } while (!stream->isAtEnd());
+    return tempStream.detachAsStream();  // returns a SkBlockMemoryStream,
+                                         // cheaper than copying to SkData
+}
diff --git a/src/core/SkStreamPriv.h b/src/core/SkStreamPriv.h
new file mode 100644
index 0000000..718097d
--- /dev/null
+++ b/src/core/SkStreamPriv.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkStreamPriv_DEFINED
+#define SkStreamPriv_DEFINED
+
+class SkAutoMalloc;
+class SkStream;
+class SkStreamRewindable;
+class SkData;
+
+/**
+ *  Copy the provided stream to memory allocated by storage.
+ *  Used by SkImageDecoder_libbmp and SkImageDecoder_libico.
+ *  @param storage Allocator to hold the memory. Will be reset to be large
+ *      enough to hold the entire stream. Upon successful return,
+ *      storage->get() will point to data holding the SkStream's entire
+ *      contents.
+ *  @param stream SkStream to be copied into storage.
+ *  @return size_t Total number of bytes in the SkStream, which is also the
+ *      number of bytes pointed to by storage->get(). Returns 0 on failure.
+ */
+size_t SkCopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream);
+
+/**
+ *  Copy the provided stream to an SkData variable.
+ *  @param stream SkStream to be copied into data.
+ *  @return SkData* The resulting SkData after the copy. This data
+ *      will have a ref count of one upon return and belongs to the
+ *      caller. Returns NULL on failure.
+ */
+SkData *SkCopyStreamToData(SkStream* stream);
+
+/**
+ *  Attempt to convert this stream to a StreamRewindable in the
+ *  cheapest possible manner (calling duplicate() if possible, and
+ *  otherwise allocating memory for a copy).  The position of the
+ *  input stream is left in an indeterminate state.
+ */
+SkStreamRewindable* SkStreamRewindableFromSkStream(SkStream* stream);
+
+#endif  // SkStreamPriv_DEFINED
diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
index ba1da41..48459db 100644
--- a/src/core/SkString.cpp
+++ b/src/core/SkString.cpp
@@ -583,30 +583,36 @@
     this->prepend(buffer, strlen(buffer));
 }
 
+void SkString::prependVAList(const char format[], va_list args) {
+    char    buffer[kBufferSize];
+    VSNPRINTF(buffer, kBufferSize, format, args);
+
+    this->prepend(buffer, strlen(buffer));
+}
+
+
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkString::remove(size_t offset, size_t length) {
     size_t size = this->size();
 
     if (offset < size) {
-        if (offset + length > size) {
+        if (length > size - offset) {
             length = size - offset;
         }
+        SkASSERT(length <= size);
+        SkASSERT(offset <= size - length);
         if (length > 0) {
-            SkASSERT(size > length);
             SkString    tmp(size - length);
             char*       dst = tmp.writable_str();
             const char* src = this->c_str();
 
             if (offset) {
-                SkASSERT(offset <= tmp.size());
                 memcpy(dst, src, offset);
             }
-            size_t tail = size - offset - length;
-            SkASSERT((int32_t)tail >= 0);
+            size_t tail = size - (offset + length);
             if (tail) {
-        //      SkASSERT(offset + length <= tmp.size());
-                memcpy(dst + offset, src + offset + length, tail);
+                memcpy(dst + offset, src + (offset + length), tail);
             }
             SkASSERT(dst[tmp.size()] == 0);
             this->swap(tmp);
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp
index b138c32..1e4ae79 100644
--- a/src/core/SkStroke.cpp
+++ b/src/core/SkStroke.cpp
@@ -424,7 +424,8 @@
     bool    degenerateBC = SkPath::IsLineDegenerate(pt1, pt2);
     bool    degenerateCD = SkPath::IsLineDegenerate(pt2, pt3);
 
-    if (degenerateAB + degenerateBC + degenerateCD >= 2) {
+    if (degenerateAB + degenerateBC + degenerateCD >= 2
+            || (degenerateAB && SkPath::IsLineDegenerate(fPrevPt, pt2))) {
         this->lineTo(pt3);
         return;
     }
diff --git a/src/core/SkSurfacePriv.h b/src/core/SkSurfacePriv.h
new file mode 100644
index 0000000..74d19a6
--- /dev/null
+++ b/src/core/SkSurfacePriv.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSurfacePriv_DEFINED
+#define SkSurfacePriv_DEFINED
+
+#include "SkSurfaceProps.h"
+
+static inline SkSurfaceProps SkSurfacePropsCopyOrDefault(const SkSurfaceProps* props) {
+    if (props) {
+        return *props;
+    } else {
+        return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
+    }
+}
+
+static inline SkPixelGeometry SkSurfacePropsDefaultPixelGeometry() {
+    return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType).pixelGeometry();
+}
+
+#endif
diff --git a/src/core/SkTDynamicHash.h b/src/core/SkTDynamicHash.h
index c9a0b3e..23544c8 100644
--- a/src/core/SkTDynamicHash.h
+++ b/src/core/SkTDynamicHash.h
@@ -57,12 +57,40 @@
         int fCurrentIndex;
     };
 
+    class ConstIter {
+    public:
+        explicit ConstIter(const SkTDynamicHash* hash) : fHash(hash), fCurrentIndex(-1) {
+            SkASSERT(hash);
+            ++(*this);
+        }
+        bool done() const {
+            SkASSERT(fCurrentIndex <= fHash->fCapacity);
+            return fCurrentIndex == fHash->fCapacity;
+        }
+        const T& operator*() const {
+            SkASSERT(!this->done());
+            return *this->current();
+        }
+        void operator++() {
+            do {
+                fCurrentIndex++;
+            } while (!this->done() && (this->current() == Empty() || this->current() == Deleted()));
+        }
+
+    private:
+        const T* current() const { return fHash->fArray[fCurrentIndex]; }
+
+        const SkTDynamicHash* fHash;
+        int fCurrentIndex;
+    };
+
     int count() const { return fCount; }
 
     // Return the entry with this key if we have it, otherwise NULL.
     T* find(const Key& key) const {
         int index = this->firstIndex(key);
         for (int round = 0; round < fCapacity; round++) {
+            SkASSERT(index >= 0 && index < fCapacity);
             T* candidate = fArray[index];
             if (Empty() == candidate) {
                 return NULL;
@@ -84,13 +112,29 @@
         SkASSERT(this->validate());
     }
 
-    // Remove the entry with this key.  We reqire that an entry with this key is present.
+    // Remove the entry with this key.  We require that an entry with this key is present.
     void remove(const Key& key) {
-        SkASSERT(NULL != this->find(key));
+        SkASSERT(this->find(key));
         this->innerRemove(key);
         SkASSERT(this->validate());
     }
 
+    void rewind() {
+        if (fArray) {
+            sk_bzero(fArray, sizeof(T*)* fCapacity);
+        }
+        fCount = 0;
+        fDeleted = 0;
+    }
+
+    void reset() { 
+        fCount = 0; 
+        fDeleted = 0; 
+        fCapacity = 0; 
+        sk_free(fArray); 
+        fArray = NULL; 
+    }
+
 protected:
     // These methods are used by tests only.
 
@@ -100,6 +144,7 @@
     int countCollisions(const Key& key) const {
         int index = this->firstIndex(key);
         for (int round = 0; round < fCapacity; round++) {
+            SkASSERT(index >= 0 && index < fCapacity);
             const T* candidate = fArray[index];
             if (Empty() == candidate || Deleted() == candidate || GetKey(*candidate) == key) {
                 return round;
@@ -132,7 +177,7 @@
                     deleted++;
                 } else if (Empty() != fArray[i]) {
                     count++;
-                    SKTDYNAMICHASH_CHECK(NULL != this->find(GetKey(*fArray[i])));
+                    SKTDYNAMICHASH_CHECK(this->find(GetKey(*fArray[i])));
                 }
             }
             SKTDYNAMICHASH_CHECK(count == fCount);
@@ -163,6 +208,7 @@
         const Key& key = GetKey(*newEntry);
         int index = this->firstIndex(key);
         for (int round = 0; round < fCapacity; round++) {
+            SkASSERT(index >= 0 && index < fCapacity);
             const T* candidate = fArray[index];
             if (Empty() == candidate || Deleted() == candidate) {
                 if (Deleted() == candidate) {
@@ -181,6 +227,7 @@
         const int firstIndex = this->firstIndex(key);
         int index = firstIndex;
         for (int round = 0; round < fCapacity; round++) {
+            SkASSERT(index >= 0 && index < fCapacity);
             const T* candidate = fArray[index];
             if (Deleted() != candidate && GetKey(*candidate) == key) {
                 fDeleted++;
diff --git a/src/core/SkTLList.h b/src/core/SkTLList.h
index e2b9691..5cb74cf 100644
--- a/src/core/SkTLList.h
+++ b/src/core/SkTLList.h
@@ -53,7 +53,7 @@
         this->validate();
         typename NodeList::Iter iter;
         Node* node = iter.init(fList, Iter::kHead_IterStart);
-        while (NULL != node) {
+        while (node) {
             SkTCast<T*>(node->fObj)->~T();
             Block* block = node->fBlock;
             node = iter.next();
@@ -126,7 +126,7 @@
     void popHead() {
         this->validate();
         Node* node = fList.head();
-        if (NULL != node) {
+        if (node) {
             this->removeNode(node);
         }
         this->validate();
@@ -135,7 +135,7 @@
     void popTail() {
         this->validate();
         Node* node = fList.head();
-        if (NULL != node) {
+        if (node) {
             this->removeNode(node);
         }
         this->validate();
@@ -175,7 +175,7 @@
         for (Iter a(*this, Iter::kHead_IterStart), b(list, Iter::kHead_IterStart);
              a.get();
              a.next(), b.next()) {
-            SkASSERT(NULL != b.get()); // already checked that counts match.
+            SkASSERT(b.get()); // already checked that counts match.
             if (!(*a.get() == *b.get())) {
                 return false;
             }
@@ -219,7 +219,7 @@
         Node* getNode() { return INHERITED::get(); }
 
         T* nodeToObj(Node* node) {
-            if (NULL != node) {
+            if (node) {
                 return reinterpret_cast<T*>(node->fObj);
             } else {
                 return NULL;
@@ -243,7 +243,7 @@
 
     Node* createNode() {
         Node* node = fFreeList.head();
-        if (NULL != node) {
+        if (node) {
             fFreeList.remove(node);
             ++node->fBlock->fNodesInUse;
         } else {
@@ -263,7 +263,7 @@
     }
 
     void removeNode(Node* node) {
-        SkASSERT(NULL != node);
+        SkASSERT(node);
         fList.remove(node);
         SkTCast<T*>(node->fObj)->~T();
         if (0 == --node->fBlock->fNodesInUse) {
@@ -369,7 +369,7 @@
 void *operator new(size_t, SkTLList<T>* list,
                    typename SkTLList<T>::Placement placement,
                    const typename SkTLList<T>::Iter& location) {
-    SkASSERT(NULL != list);
+    SkASSERT(list);
     if (SkTLList<T>::kBefore_Placement == placement) {
         return list->internalAddBefore(location);
     } else {
diff --git a/src/core/SkTLS.cpp b/src/core/SkTLS.cpp
index f7bf304..3f78a24 100755
--- a/src/core/SkTLS.cpp
+++ b/src/core/SkTLS.cpp
@@ -45,7 +45,7 @@
         SkTLSRec* next = rec->fNext;
         SkDELETE(rec);
         rec = next;
-    } while (NULL != rec);
+    } while (rec);
 }
 
 void* SkTLS::Get(CreateProc createProc, DeleteProc deleteProc) {
diff --git a/src/core/SkTLS.h b/src/core/SkTLS.h
index ad5daa7..e94f835 100644
--- a/src/core/SkTLS.h
+++ b/src/core/SkTLS.h
@@ -1,10 +1,9 @@
-//
-//  SkTLS.h
-//
-//
-//  Created by Mike Reed on 4/21/12.
-//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
-//
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
 
 #ifndef SkTLS_DEFINED
 #define SkTLS_DEFINED
diff --git a/src/gpu/GrTMultiMap.h b/src/core/SkTMultiMap.h
similarity index 89%
rename from src/gpu/GrTMultiMap.h
rename to src/core/SkTMultiMap.h
index 0007a04..70076f0 100644
--- a/src/gpu/GrTMultiMap.h
+++ b/src/core/SkTMultiMap.h
@@ -6,8 +6,8 @@
  * found in the LICENSE file.
  */
 
-#ifndef GrTMultiMap_DEFINED
-#define GrTMultiMap_DEFINED
+#ifndef SkTMultiMap_DEFINED
+#define SkTMultiMap_DEFINED
 
 #include "GrTypes.h"
 #include "SkTDynamicHash.h"
@@ -18,7 +18,7 @@
 template <typename T,
           typename Key,
           typename HashTraits=T>
-class GrTMultiMap {
+class SkTMultiMap {
     struct ValueList {
         explicit ValueList(T* value) : fValue(value), fNext(NULL) {}
 
@@ -28,16 +28,16 @@
         ValueList* fNext;
     };
 public:
-    GrTMultiMap() : fCount(0) {}
+    SkTMultiMap() : fCount(0) {}
 
-    ~GrTMultiMap() {
+    ~SkTMultiMap() {
         SkASSERT(fCount == 0);
         SkASSERT(fHash.count() == 0);
     }
 
     void insert(const Key& key, T* value) {
         ValueList* list = fHash.find(key);
-        if (NULL != list) {
+        if (list) {
             // The new ValueList entry is inserted as the second element in the
             // linked list, and it will contain the value of the first element.
             ValueList* newEntry = SkNEW_ARGS(ValueList, (list->fValue));
@@ -57,19 +57,19 @@
         ValueList* list = fHash.find(key);
         // Since we expect the caller to be fully aware of what is stored, just
         // assert that the caller removes an existing value.
-        SkASSERT(NULL != list);
+        SkASSERT(list);
         ValueList* prev = NULL;
         while (list->fValue != value) {
             prev = list;
             list = list->fNext;
         }
 
-        if (NULL != list->fNext) {
+        if (list->fNext) {
             ValueList* next = list->fNext;
             list->fValue = next->fValue;
             list->fNext = next->fNext;
             SkDELETE(next);
-        } else if (NULL != prev) {
+        } else if (prev) {
             prev->fNext = NULL;
             SkDELETE(list);
         } else {
@@ -82,7 +82,7 @@
 
     T* find(const Key& key) const {
         ValueList* list = fHash.find(key);
-        if (NULL != list) {
+        if (list) {
             return list->fValue;
         }
         return NULL;
@@ -91,7 +91,7 @@
     template<class FindPredicate>
     T* find(const Key& key, const FindPredicate f) {
         ValueList* list = fHash.find(key);
-        while (NULL != list) {
+        while (list) {
             if (f(list->fValue)){
                 return list->fValue;
             }
diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp
new file mode 100644
index 0000000..b815c26
--- /dev/null
+++ b/src/core/SkTextBlob.cpp
@@ -0,0 +1,491 @@
+/*
+ * 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 "SkTextBlob.h"
+
+#include "SkReadBuffer.h"
+#include "SkWriteBuffer.h"
+
+//
+// Textblob data is laid out into externally-managed storage as follows:
+//
+//    -----------------------------------------------------------------------------
+//   | SkTextBlob | RunRecord | Glyphs[] | Pos[] | RunRecord | Glyphs[] | Pos[] | ...
+//    -----------------------------------------------------------------------------
+//
+//  Each run record describes a text blob run, and can be used to determine the (implicit)
+//  location of the following record.
+
+SkDEBUGCODE(static const unsigned kRunRecordMagic = 0xb10bcafe;)
+
+class SkTextBlob::RunRecord {
+public:
+    RunRecord(uint32_t count, const SkPoint& offset, const SkPaint& font, GlyphPositioning pos)
+        : fCount(count)
+        , fOffset(offset)
+        , fFont(font)
+        , fPositioning(pos) {
+        SkDEBUGCODE(fMagic = kRunRecordMagic);
+    }
+
+    uint32_t glyphCount() const {
+        return fCount;
+    }
+
+    const SkPoint& offset() const {
+        return fOffset;
+    }
+
+    const SkPaint& font() const {
+        return fFont;
+    }
+
+    GlyphPositioning positioning() const {
+        return fPositioning;
+    }
+
+    uint16_t* glyphBuffer() const {
+        // Glyph are stored immediately following the record.
+        return reinterpret_cast<uint16_t*>(const_cast<RunRecord*>(this) + 1);
+    }
+
+    SkScalar* posBuffer() const {
+        // Position scalars follow the (aligned) glyph buffer.
+        return reinterpret_cast<SkScalar*>(reinterpret_cast<uint8_t*>(this->glyphBuffer()) +
+                                           SkAlign4(fCount * sizeof(uint16_t)));
+    }
+
+    static size_t StorageSize(int glyphCount, SkTextBlob::GlyphPositioning positioning) {
+        // RunRecord object + (aligned) glyph buffer + position buffer
+        return SkAlignPtr(sizeof(SkTextBlob::RunRecord)
+                        + SkAlign4(glyphCount* sizeof(uint16_t))
+                        + glyphCount * sizeof(SkScalar) * ScalarsPerGlyph(positioning));
+    }
+
+    static const RunRecord* First(const SkTextBlob* blob) {
+        // The first record (if present) is stored following the blob object.
+        return reinterpret_cast<const RunRecord*>(blob + 1);
+    }
+
+    static const RunRecord* Next(const RunRecord* run) {
+        return reinterpret_cast<const RunRecord*>(reinterpret_cast<const uint8_t*>(run)
+            + StorageSize(run->glyphCount(), run->positioning()));
+    }
+
+    void validate(uint8_t* storageTop) const {
+        SkASSERT(kRunRecordMagic == fMagic);
+        SkASSERT((uint8_t*)Next(this) <= storageTop);
+        SkASSERT(glyphBuffer() + fCount <= (uint16_t*)posBuffer());
+        SkASSERT(posBuffer() + fCount * ScalarsPerGlyph(fPositioning) <= (SkScalar*)Next(this));
+    }
+
+private:
+    friend class SkTextBlobBuilder;
+
+    void grow(uint32_t count) {
+        SkScalar* initialPosBuffer = posBuffer();
+        uint32_t initialCount = fCount;
+        fCount += count;
+
+        // Move the initial pos scalars to their new location.
+        size_t copySize = initialCount * sizeof(SkScalar) * ScalarsPerGlyph(fPositioning);
+        SkASSERT((uint8_t*)posBuffer() + copySize <= (uint8_t*)Next(this));
+
+        // memmove, as the buffers may overlap
+        memmove(posBuffer(), initialPosBuffer, copySize);
+    }
+
+    uint32_t         fCount;
+    SkPoint          fOffset;
+    SkPaint          fFont;
+    GlyphPositioning fPositioning;
+
+    SkDEBUGCODE(unsigned fMagic;)
+};
+
+SkTextBlob::SkTextBlob(int runCount, const SkRect& bounds)
+    : fRunCount(runCount)
+    , fBounds(bounds) {
+}
+
+SkTextBlob::~SkTextBlob() {
+    const RunRecord* run = RunRecord::First(this);
+    for (int i = 0; i < fRunCount; ++i) {
+        const RunRecord* nextRun = RunRecord::Next(run);
+        SkDEBUGCODE(run->validate((uint8_t*)this + fStorageSize);)
+        run->~RunRecord();
+        run = nextRun;
+    }
+}
+
+void SkTextBlob::internal_dispose() const {
+    // SkTextBlobs use externally-managed storage.
+    this->internal_dispose_restore_refcnt_to_1();
+    this->~SkTextBlob();
+    sk_free(const_cast<SkTextBlob*>(this));
+}
+
+uint32_t SkTextBlob::uniqueID() const {
+    static int32_t  gTextBlobGenerationID; // = 0;
+
+    // loop in case our global wraps around, as we never want to return SK_InvalidGenID
+    while (SK_InvalidGenID == fUniqueID) {
+        fUniqueID = sk_atomic_inc(&gTextBlobGenerationID) + 1;
+    }
+
+    return fUniqueID;
+}
+
+void SkTextBlob::flatten(SkWriteBuffer& buffer) const {
+    int runCount = fRunCount;
+
+    buffer.write32(runCount);
+    buffer.writeRect(fBounds);
+
+    SkPaint runPaint;
+    RunIterator it(this);
+    while (!it.done()) {
+        SkASSERT(it.glyphCount() > 0);
+
+        buffer.write32(it.glyphCount());
+        buffer.write32(it.positioning());
+        buffer.writePoint(it.offset());
+        // This should go away when switching to SkFont
+        it.applyFontToPaint(&runPaint);
+        buffer.writePaint(runPaint);
+
+        buffer.writeByteArray(it.glyphs(), it.glyphCount() * sizeof(uint16_t));
+        buffer.writeByteArray(it.pos(),
+            it.glyphCount() * sizeof(SkScalar) * ScalarsPerGlyph(it.positioning()));
+
+        it.next();
+        SkDEBUGCODE(runCount--);
+    }
+    SkASSERT(0 == runCount);
+}
+
+const SkTextBlob* SkTextBlob::CreateFromBuffer(SkReadBuffer& reader) {
+    int runCount = reader.read32();
+    if (runCount < 0) {
+        return NULL;
+    }
+
+    SkRect bounds;
+    reader.readRect(&bounds);
+
+    SkTextBlobBuilder blobBuilder;
+    for (int i = 0; i < runCount; ++i) {
+        int glyphCount = reader.read32();
+        GlyphPositioning pos = static_cast<GlyphPositioning>(reader.read32());
+        if (glyphCount <= 0 || pos > kFull_Positioning) {
+            return NULL;
+        }
+
+        SkPoint offset;
+        reader.readPoint(&offset);
+        SkPaint font;
+        reader.readPaint(&font);
+
+        const SkTextBlobBuilder::RunBuffer* buf = NULL;
+        switch (pos) {
+        case kDefault_Positioning:
+            buf = &blobBuilder.allocRun(font, glyphCount, offset.x(), offset.y(), &bounds);
+            break;
+        case kHorizontal_Positioning:
+            buf = &blobBuilder.allocRunPosH(font, glyphCount, offset.y(), &bounds);
+            break;
+        case kFull_Positioning:
+            buf = &blobBuilder.allocRunPos(font, glyphCount, &bounds);
+            break;
+        default:
+            return NULL;
+        }
+
+        if (!reader.readByteArray(buf->glyphs, glyphCount * sizeof(uint16_t)) ||
+            !reader.readByteArray(buf->pos,
+                                  glyphCount * sizeof(SkScalar) * ScalarsPerGlyph(pos))) {
+            return NULL;
+        }
+    }
+
+    return blobBuilder.build();
+}
+
+unsigned SkTextBlob::ScalarsPerGlyph(GlyphPositioning pos) {
+    // GlyphPositioning values are directly mapped to scalars-per-glyph.
+    SkASSERT(pos <= 2);
+    return pos;
+}
+
+SkTextBlob::RunIterator::RunIterator(const SkTextBlob* blob)
+    : fCurrentRun(RunRecord::First(blob))
+    , fRemainingRuns(blob->fRunCount) {
+    SkDEBUGCODE(fStorageTop = (uint8_t*)blob + blob->fStorageSize;)
+}
+
+bool SkTextBlob::RunIterator::done() const {
+    return fRemainingRuns <= 0;
+}
+
+void SkTextBlob::RunIterator::next() {
+    SkASSERT(!this->done());
+
+    if (!this->done()) {
+        SkDEBUGCODE(fCurrentRun->validate(fStorageTop);)
+        fCurrentRun = RunRecord::Next(fCurrentRun);
+        fRemainingRuns--;
+    }
+}
+
+uint32_t SkTextBlob::RunIterator::glyphCount() const {
+    SkASSERT(!this->done());
+    return fCurrentRun->glyphCount();
+}
+
+const uint16_t* SkTextBlob::RunIterator::glyphs() const {
+    SkASSERT(!this->done());
+    return fCurrentRun->glyphBuffer();
+}
+
+const SkScalar* SkTextBlob::RunIterator::pos() const {
+    SkASSERT(!this->done());
+    return fCurrentRun->posBuffer();
+}
+
+const SkPoint& SkTextBlob::RunIterator::offset() const {
+    SkASSERT(!this->done());
+    return fCurrentRun->offset();
+}
+
+SkTextBlob::GlyphPositioning SkTextBlob::RunIterator::positioning() const {
+    SkASSERT(!this->done());
+    return fCurrentRun->positioning();
+}
+
+void SkTextBlob::RunIterator::applyFontToPaint(SkPaint* paint) const {
+    SkASSERT(!this->done());
+
+    const SkPaint& font = fCurrentRun->font();
+
+    paint->setTypeface(font.getTypeface());
+    paint->setTextEncoding(font.getTextEncoding());
+    paint->setTextSize(font.getTextSize());
+    paint->setTextScaleX(font.getTextScaleX());
+    paint->setTextSkewX(font.getTextSkewX());
+    paint->setHinting(font.getHinting());
+
+    uint32_t flagsMask = SkPaint::kAntiAlias_Flag
+                       | SkPaint::kUnderlineText_Flag
+                       | SkPaint::kStrikeThruText_Flag
+                       | SkPaint::kFakeBoldText_Flag
+                       | SkPaint::kLinearText_Flag
+                       | SkPaint::kSubpixelText_Flag
+                       | SkPaint::kDevKernText_Flag
+                       | SkPaint::kLCDRenderText_Flag
+                       | SkPaint::kEmbeddedBitmapText_Flag
+                       | SkPaint::kAutoHinting_Flag
+                       | SkPaint::kVerticalText_Flag
+                       | SkPaint::kGenA8FromLCD_Flag
+                       | SkPaint::kDistanceFieldTextTEMP_Flag;
+    paint->setFlags((paint->getFlags() & ~flagsMask) | (font.getFlags() & flagsMask));
+}
+
+SkTextBlobBuilder::SkTextBlobBuilder()
+    : fStorageSize(0)
+    , fStorageUsed(0)
+    , fRunCount(0)
+    , fDeferredBounds(false)
+    , fLastRun(0) {
+    fBounds.setEmpty();
+}
+
+SkTextBlobBuilder::~SkTextBlobBuilder() {
+    if (NULL != fStorage.get()) {
+        // We are abandoning runs and must destruct the associated font data.
+        // The easiest way to accomplish that is to use the blob destructor.
+        build()->unref();
+    }
+}
+
+void SkTextBlobBuilder::updateDeferredBounds() {
+    SkASSERT(!fDeferredBounds || fRunCount > 0);
+
+    if (!fDeferredBounds) {
+        return;
+    }
+
+    // FIXME: measure the current run & union bounds
+    fDeferredBounds = false;
+}
+
+void SkTextBlobBuilder::reserve(size_t size) {
+    // We don't currently pre-allocate, but maybe someday...
+    if (fStorageUsed + size <= fStorageSize) {
+        return;
+    }
+
+    if (0 == fRunCount) {
+        SkASSERT(NULL == fStorage.get());
+        SkASSERT(0 == fStorageSize);
+        SkASSERT(0 == fStorageUsed);
+
+        // the first allocation also includes blob storage
+        fStorageUsed += sizeof(SkTextBlob);
+    }
+
+    fStorageSize = fStorageUsed + size;
+    // FYI: This relies on everything we store being relocatable, particularly SkPaint.
+    fStorage.realloc(fStorageSize);
+}
+
+bool SkTextBlobBuilder::mergeRun(const SkPaint &font, SkTextBlob::GlyphPositioning positioning,
+                                 int count, SkPoint offset) {
+    if (0 == fLastRun) {
+        SkASSERT(0 == fRunCount);
+        return false;
+    }
+
+    SkASSERT(fLastRun >= sizeof(SkTextBlob));
+    SkTextBlob::RunRecord* run = reinterpret_cast<SkTextBlob::RunRecord*>(fStorage.get() +
+                                                                          fLastRun);
+    SkASSERT(run->glyphCount() > 0);
+
+    if (run->positioning() != positioning
+        || run->font() != font
+        || (run->glyphCount() + count < run->glyphCount())) {
+        return false;
+    }
+
+    // we can merge same-font/same-positioning runs in the following cases:
+    //   * fully positioned run following another fully positioned run
+    //   * horizontally postioned run following another horizontally positioned run with the same
+    //     y-offset
+    if (SkTextBlob::kFull_Positioning != positioning
+        && (SkTextBlob::kHorizontal_Positioning != positioning
+            || run->offset().y() != offset.y())) {
+        return false;
+    }
+
+    size_t sizeDelta = SkTextBlob::RunRecord::StorageSize(run->glyphCount() + count, positioning) -
+                       SkTextBlob::RunRecord::StorageSize(run->glyphCount(), positioning);
+    this->reserve(sizeDelta);
+
+    // reserve may have realloced
+    run = reinterpret_cast<SkTextBlob::RunRecord*>(fStorage.get() + fLastRun);
+    uint32_t preMergeCount = run->glyphCount();
+    run->grow(count);
+
+    // Callers expect the buffers to point at the newly added slice, ant not at the beginning.
+    fCurrentRunBuffer.glyphs = run->glyphBuffer() + preMergeCount;
+    fCurrentRunBuffer.pos = run->posBuffer()
+                          + preMergeCount * SkTextBlob::ScalarsPerGlyph(positioning);
+
+    fStorageUsed += sizeDelta;
+
+    SkASSERT(fStorageUsed <= fStorageSize);
+    run->validate(fStorage.get() + fStorageUsed);
+
+    return true;
+}
+
+void SkTextBlobBuilder::allocInternal(const SkPaint &font,
+                                      SkTextBlob::GlyphPositioning positioning,
+                                      int count, SkPoint offset, const SkRect* bounds) {
+    SkASSERT(count > 0);
+    SkASSERT(SkPaint::kGlyphID_TextEncoding == font.getTextEncoding());
+
+    if (!this->mergeRun(font, positioning, count, offset)) {
+        updateDeferredBounds();
+
+        size_t runSize = SkTextBlob::RunRecord::StorageSize(count, positioning);
+        this->reserve(runSize);
+
+        SkASSERT(fStorageUsed >= sizeof(SkTextBlob));
+        SkASSERT(fStorageUsed + runSize <= fStorageSize);
+
+        SkTextBlob::RunRecord* run = new (fStorage.get() + fStorageUsed)
+                                         SkTextBlob::RunRecord(count, offset, font, positioning);
+
+        fCurrentRunBuffer.glyphs = run->glyphBuffer();
+        fCurrentRunBuffer.pos = run->posBuffer();
+
+        fLastRun = fStorageUsed;
+        fStorageUsed += runSize;
+        fRunCount++;
+
+        SkASSERT(fStorageUsed <= fStorageSize);
+        run->validate(fStorage.get() + fStorageUsed);
+    }
+
+    if (!fDeferredBounds) {
+        if (bounds) {
+            fBounds.join(*bounds);
+        } else {
+            fDeferredBounds = true;
+        }
+    }
+}
+
+const SkTextBlobBuilder::RunBuffer& SkTextBlobBuilder::allocRun(const SkPaint& font, int count,
+                                                                SkScalar x, SkScalar y,
+                                                                const SkRect* bounds) {
+    this->allocInternal(font, SkTextBlob::kDefault_Positioning, count, SkPoint::Make(x, y), bounds);
+
+    return fCurrentRunBuffer;
+}
+
+const SkTextBlobBuilder::RunBuffer& SkTextBlobBuilder::allocRunPosH(const SkPaint& font, int count,
+                                                                    SkScalar y,
+                                                                    const SkRect* bounds) {
+    this->allocInternal(font, SkTextBlob::kHorizontal_Positioning, count, SkPoint::Make(0, y),
+                        bounds);
+
+    return fCurrentRunBuffer;
+}
+
+const SkTextBlobBuilder::RunBuffer& SkTextBlobBuilder::allocRunPos(const SkPaint& font, int count,
+                                                                   const SkRect *bounds) {
+    this->allocInternal(font, SkTextBlob::kFull_Positioning, count, SkPoint::Make(0, 0), bounds);
+
+    return fCurrentRunBuffer;
+}
+
+const SkTextBlob* SkTextBlobBuilder::build() {
+    SkASSERT((fRunCount > 0) == (NULL != fStorage.get()));
+
+    this->updateDeferredBounds();
+
+    if (0 == fRunCount) {
+        SkASSERT(NULL == fStorage.get());
+        fStorageUsed = sizeof(SkTextBlob);
+        fStorage.realloc(fStorageUsed);
+    }
+
+    SkDEBUGCODE(
+        size_t validateSize = sizeof(SkTextBlob);
+        const SkTextBlob::RunRecord* run =
+            SkTextBlob::RunRecord::First(reinterpret_cast<const SkTextBlob*>(fStorage.get()));
+        for (int i = 0; i < fRunCount; ++i) {
+            validateSize += SkTextBlob::RunRecord::StorageSize(run->fCount, run->fPositioning);
+            run->validate(fStorage.get() + fStorageUsed);
+            run = SkTextBlob::RunRecord::Next(run);
+        }
+        SkASSERT(validateSize == fStorageUsed);
+    )
+
+    const SkTextBlob* blob = new (fStorage.detach()) SkTextBlob(fRunCount, fBounds);
+    SkDEBUGCODE(const_cast<SkTextBlob*>(blob)->fStorageSize = fStorageSize;)
+
+    fStorageUsed = 0;
+    fStorageSize = 0;
+    fRunCount = 0;
+    fLastRun = 0;
+    fBounds.setEmpty();
+
+    return blob;
+}
+
diff --git a/src/core/SkTileGrid.cpp b/src/core/SkTileGrid.cpp
index 35f85d2..2eea6db 100644
--- a/src/core/SkTileGrid.cpp
+++ b/src/core/SkTileGrid.cpp
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2012 Google Inc.
  *
@@ -8,125 +7,163 @@
 
 #include "SkTileGrid.h"
 
-SkTileGrid::SkTileGrid(int xTileCount, int yTileCount, const SkTileGridFactory::TileGridInfo& info,
-                       SkTileGridNextDatumFunctionPtr nextDatumFunction) {
-    fXTileCount = xTileCount;
-    fYTileCount = yTileCount;
-    fInfo = info;
+SkTileGrid::SkTileGrid(int xTiles, int yTiles, const SkTileGridFactory::TileGridInfo& info)
+    : fXTiles(xTiles)
+    , fYTiles(yTiles)
+    , fInfo(info)
+    , fCount(0)
+    , fTiles(SkNEW_ARRAY(SkTDArray<Entry>, xTiles * yTiles)) {
     // Margin is offset by 1 as a provision for AA and
     // to cancel-out the outset applied by getClipDeviceBounds.
     fInfo.fMargin.fHeight++;
     fInfo.fMargin.fWidth++;
-    fTileCount = fXTileCount * fYTileCount;
-    fInsertionCount = 0;
-    fGridBounds = SkIRect::MakeXYWH(0, 0, fInfo.fTileInterval.width() * fXTileCount,
-        fInfo.fTileInterval.height() * fYTileCount);
-    fNextDatumFunction = nextDatumFunction;
-    fTileData = SkNEW_ARRAY(SkTDArray<void *>, fTileCount);
 }
 
 SkTileGrid::~SkTileGrid() {
-    SkDELETE_ARRAY(fTileData);
+    SkDELETE_ARRAY(fTiles);
 }
 
-int SkTileGrid::tileCount(int x, int y) {
-    return this->tile(x, y).count();
-}
+void SkTileGrid::insert(void* data, const SkRect& fbounds, bool) {
+    SkASSERT(!fbounds.isEmpty());
+    SkIRect dilatedBounds;
+    if (fbounds.isLargest()) {
+        // Dilating the largest SkIRect will overflow.  Other nearly-largest rects may overflow too,
+        // but we don't make active use of them like we do the largest.
+        dilatedBounds.setLargest();
+    } else {
+        fbounds.roundOut(&dilatedBounds);
+        dilatedBounds.outset(fInfo.fMargin.width(), fInfo.fMargin.height());
+        dilatedBounds.offset(fInfo.fOffset);
+    }
 
-SkTDArray<void *>& SkTileGrid::tile(int x, int y) {
-    return fTileData[y * fXTileCount + x];
-}
-
-void SkTileGrid::insert(void* data, const SkIRect& bounds, bool) {
-    SkASSERT(!bounds.isEmpty());
-    SkIRect dilatedBounds = bounds;
-    dilatedBounds.outset(fInfo.fMargin.width(), fInfo.fMargin.height());
-    dilatedBounds.offset(fInfo.fOffset);
-    if (!SkIRect::Intersects(dilatedBounds, fGridBounds)) {
+    const SkIRect gridBounds =
+        { 0, 0, fInfo.fTileInterval.width() * fXTiles, fInfo.fTileInterval.height() * fYTiles };
+    if (!SkIRect::Intersects(dilatedBounds, gridBounds)) {
         return;
     }
 
     // Note: SkIRects are non-inclusive of the right() column and bottom() row,
-    // hence the "-1"s in the computations of maxTileX and maxTileY.
-    int minTileX = SkMax32(SkMin32(dilatedBounds.left() / fInfo.fTileInterval.width(),
-        fXTileCount - 1), 0);
-    int maxTileX = SkMax32(SkMin32((dilatedBounds.right() - 1) / fInfo.fTileInterval.width(),
-        fXTileCount - 1), 0);
-    int minTileY = SkMax32(SkMin32(dilatedBounds.top() / fInfo.fTileInterval.height(),
-        fYTileCount -1), 0);
-    int maxTileY = SkMax32(SkMin32((dilatedBounds.bottom() -1) / fInfo.fTileInterval.height(),
-        fYTileCount -1), 0);
+    // hence the "-1"s in the computations of maxX and maxY.
+    int minX = SkMax32(0, SkMin32(dilatedBounds.left() / fInfo.fTileInterval.width(), fXTiles - 1));
+    int minY = SkMax32(0, SkMin32(dilatedBounds.top() / fInfo.fTileInterval.height(), fYTiles - 1));
+    int maxX = SkMax32(0, SkMin32((dilatedBounds.right()  - 1) / fInfo.fTileInterval.width(),
+                                  fXTiles - 1));
+    int maxY = SkMax32(0, SkMin32((dilatedBounds.bottom() - 1) / fInfo.fTileInterval.height(),
+                                  fYTiles - 1));
 
-    for (int x = minTileX; x <= maxTileX; x++) {
-        for (int y = minTileY; y <= maxTileY; y++) {
-            this->tile(x, y).push(data);
+    Entry entry = { fCount++, data };
+    for (int y = minY; y <= maxY; y++) {
+        for (int x = minX; x <= maxX; x++) {
+            fTiles[y * fXTiles + x].push(entry);
         }
     }
-    fInsertionCount++;
 }
 
-void SkTileGrid::search(const SkIRect& query, SkTDArray<void*>* results) {
-    SkIRect adjustedQuery = query;
+static int divide_ceil(int x, int y) {
+    return (x + y - 1) / y;
+}
+
+// Number of tiles for which data is allocated on the stack in
+// SkTileGrid::search. If malloc becomes a bottleneck, we may consider
+// increasing this number. Typical large web page, say 2k x 16k, would
+// require 512 tiles of size 256 x 256 pixels.
+static const int kStackAllocationTileCount = 1024;
+
+void SkTileGrid::search(const SkRect& query, SkTDArray<void*>* results) const {
+    SkIRect adjusted;
+    query.roundOut(&adjusted);
+
     // The inset is to counteract the outset that was applied in 'insert'
     // The outset/inset is to optimize for lookups of size
     // 'tileInterval + 2 * margin' that are aligned with the tile grid.
-    adjustedQuery.inset(fInfo.fMargin.width(), fInfo.fMargin.height());
-    adjustedQuery.offset(fInfo.fOffset);
-    adjustedQuery.sort();  // in case the inset inverted the rectangle
+    adjusted.inset(fInfo.fMargin.width(), fInfo.fMargin.height());
+    adjusted.offset(fInfo.fOffset);
+    adjusted.sort();  // in case the inset inverted the rectangle
+
     // Convert the query rectangle from device coordinates to tile coordinates
     // by rounding outwards to the nearest tile boundary so that the resulting tile
-    // region includes the query rectangle. (using truncating division to "floor")
-    int tileStartX = adjustedQuery.left() / fInfo.fTileInterval.width();
-    int tileEndX = (adjustedQuery.right() + fInfo.fTileInterval.width() - 1) /
-        fInfo.fTileInterval.width();
-    int tileStartY = adjustedQuery.top() / fInfo.fTileInterval.height();
-    int tileEndY = (adjustedQuery.bottom() + fInfo.fTileInterval.height() - 1) /
-        fInfo.fTileInterval.height();
+    // region includes the query rectangle.
+    int startX = adjusted.left() / fInfo.fTileInterval.width(),
+        startY = adjusted.top()  / fInfo.fTileInterval.height();
+    int endX = divide_ceil(adjusted.right(),  fInfo.fTileInterval.width()),
+        endY = divide_ceil(adjusted.bottom(), fInfo.fTileInterval.height());
 
-    tileStartX = SkPin32(tileStartX, 0, fXTileCount - 1);
-    tileEndX = SkPin32(tileEndX, tileStartX+1, fXTileCount);
-    tileStartY = SkPin32(tileStartY, 0, fYTileCount - 1);
-    tileEndY = SkPin32(tileEndY, tileStartY+1, fYTileCount);
+    // Logically, we could pin endX to [startX, fXTiles], but we force it
+    // up to (startX, fXTiles] to make sure we hit at least one tile.
+    // This snaps just-out-of-bounds queries to the neighboring border tile.
+    // I don't know if this is an important feature outside of unit tests.
+    startX = SkPin32(startX, 0, fXTiles - 1);
+    startY = SkPin32(startY, 0, fYTiles - 1);
+    endX   = SkPin32(endX, startX + 1, fXTiles);
+    endY   = SkPin32(endY, startY + 1, fYTiles);
 
-    int queryTileCount = (tileEndX - tileStartX) * (tileEndY - tileStartY);
-    SkASSERT(queryTileCount);
-    if (queryTileCount == 1) {
-        *results = this->tile(tileStartX, tileStartY);
-    } else {
-        results->reset();
-        SkAutoSTArray<kStackAllocationTileCount, int> curPositions(queryTileCount);
-        SkAutoSTArray<kStackAllocationTileCount, SkTDArray<void *>*> storage(queryTileCount);
-        SkTDArray<void *>** tileRange = storage.get();
-        int tile = 0;
-        for (int x = tileStartX; x < tileEndX; ++x) {
-            for (int y = tileStartY; y < tileEndY; ++y) {
-                tileRange[tile] = &this->tile(x, y);
-                curPositions[tile] = tileRange[tile]->count() ? 0 : kTileFinished;
-                ++tile;
+    const int tilesHit = (endX - startX) * (endY - startY);
+    SkASSERT(tilesHit > 0);
+
+    if (tilesHit == 1) {
+        // A performance shortcut.  The merging code below would work fine here too.
+        const SkTDArray<Entry>& tile = fTiles[startY * fXTiles + startX];
+        results->setCount(tile.count());
+        for (int i = 0; i < tile.count(); i++) {
+            (*results)[i] = tile[i].data;
+        }
+        return;
+    }
+
+    // We've got to merge the data in many tiles into a single sorted and deduplicated stream.
+    // We do a simple k-way merge based on the order the data was inserted.
+
+    // Gather pointers to the starts and ends of the tiles to merge.
+    SkAutoSTArray<kStackAllocationTileCount, const Entry*> starts(tilesHit), ends(tilesHit);
+    int i = 0;
+    for (int x = startX; x < endX; x++) {
+        for (int y = startY; y < endY; y++) {
+            starts[i] = fTiles[y * fXTiles + x].begin();
+            ends[i]  = fTiles[y * fXTiles + x].end();
+            i++;
+        }
+    }
+
+    // Merge tiles into results until they're fully consumed.
+    results->reset();
+    while (true) {
+        // The tiles themselves are already ordered, so the earliest is at the front of some tile.
+        // It may be at the front of several, even all, tiles.
+        const Entry* earliest = NULL;
+        for (int i = 0; i < starts.count(); i++) {
+            if (starts[i] < ends[i]) {
+                if (NULL == earliest || starts[i]->order < earliest->order) {
+                    earliest = starts[i];
+                }
             }
         }
-        void *nextElement;
-        while(NULL != (nextElement = fNextDatumFunction(tileRange, curPositions))) {
-            results->push(nextElement);
+
+        // If we didn't find an earliest entry, there isn't anything left to merge.
+        if (NULL == earliest) {
+            return;
+        }
+
+        // We did find an earliest entry. Output it, and step forward every tile that contains it.
+        results->push(earliest->data);
+        for (int i = 0; i < starts.count(); i++) {
+            if (starts[i] < ends[i] && starts[i]->order == earliest->order) {
+                starts[i]++;
+            }
         }
     }
 }
 
 void SkTileGrid::clear() {
-    for (int i = 0; i < fTileCount; i++) {
-        fTileData[i].reset();
+    for (int i = 0; i < fXTiles * fYTiles; i++) {
+        fTiles[i].reset();
     }
 }
 
-int SkTileGrid::getCount() const {
-    return fInsertionCount;
-}
-
 void SkTileGrid::rewindInserts() {
     SkASSERT(fClient);
-    for (int i = 0; i < fTileCount; ++i) {
-        while (!fTileData[i].isEmpty() && fClient->shouldRewind(fTileData[i].top())) {
-            fTileData[i].pop();
+    for (int i = 0; i < fXTiles * fYTiles; i++) {
+        while (!fTiles[i].isEmpty() && fClient->shouldRewind(fTiles[i].top().data)) {
+            fTiles[i].pop();
         }
     }
 }
diff --git a/src/core/SkTileGrid.h b/src/core/SkTileGrid.h
index 0ec5c2c..1e34a61 100644
--- a/src/core/SkTileGrid.h
+++ b/src/core/SkTileGrid.h
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2012 Google Inc.
  *
@@ -11,132 +10,59 @@
 
 #include "SkBBHFactory.h"
 #include "SkBBoxHierarchy.h"
-#include "SkPictureStateTree.h"
 
 /**
  * Subclass of SkBBoxHierarchy that stores elements in buckets that correspond
  * to tile regions, disposed in a regular grid.  This is useful when the tile
  * structure that will be use in search() calls is known prior to insertion.
- * Calls to search will return in constant time.
- *
- * Note: Current implementation of search() only supports looking-up regions
- * that are an exact match to a single tile.  Implementation could be augmented
- * to support arbitrary rectangles, but performance would be sub-optimal.
  */
 class SkTileGrid : public SkBBoxHierarchy {
 public:
-    enum {
-        // Number of tiles for which data is allocated on the stack in
-        // SkTileGrid::search. If malloc becomes a bottleneck, we may consider
-        // increasing this number. Typical large web page, say 2k x 16k, would
-        // require 512 tiles of size 256 x 256 pixels.
-        kStackAllocationTileCount = 1024
-    };
-
-    typedef void* (*SkTileGridNextDatumFunctionPtr)(SkTDArray<void*>** tileData, SkAutoSTArray<kStackAllocationTileCount, int>& tileIndices);
-
-    SkTileGrid(int xTileCount, int yTileCount, const SkTileGridFactory::TileGridInfo& info,
-        SkTileGridNextDatumFunctionPtr nextDatumFunction);
+    SkTileGrid(int xTiles, int yTiles, const SkTileGridFactory::TileGridInfo& info);
 
     virtual ~SkTileGrid();
 
     /**
      * Insert a data pointer and corresponding bounding box
-     * @param data The data pointer, may be NULL
-     * @param bounds The bounding box, should not be empty
-     * @param defer Ignored, TileArray does not defer insertions
+     * @param data   An arbitrary data pointer, may be NULL.
+     * @param bounds The bounding box, should not be empty.
+     * @param defer  Ignored; SkTileGrid does not defer insertions.
      */
-    virtual void insert(void* data, const SkIRect& bounds, bool) SK_OVERRIDE;
+    virtual void insert(void* data, const SkRect& bounds, bool) SK_OVERRIDE;
 
     virtual void flushDeferredInserts() SK_OVERRIDE {};
 
     /**
-     * Populate 'results' with data pointers corresponding to bounding boxes that intersect 'query'
-     * The query argument is expected to be an exact match to a tile of the grid
+     * Populate 'results' with data pointers corresponding to bounding boxes that intersect 'query'.
+     * This will be fastest if the query is an exact match to a single grid tile.
      */
-    virtual void search(const SkIRect& query, SkTDArray<void*>* results) SK_OVERRIDE;
+    virtual void search(const SkRect& query, SkTDArray<void*>* results) const SK_OVERRIDE;
 
     virtual void clear() SK_OVERRIDE;
 
-    /**
-     * Gets the number of insertions
-     */
-    virtual int getCount() const SK_OVERRIDE;
+    virtual int getCount() const SK_OVERRIDE { return fCount; }
 
     virtual int getDepth() const SK_OVERRIDE { return -1; }
 
     virtual void rewindInserts() SK_OVERRIDE;
 
-    // Used by search() and in SkTileGridHelper implementations
-    enum {
-        kTileFinished = -1,
-    };
-
-    int tileCount(int x, int y);  // For testing only.
+    // For testing.
+    int tileCount(int x, int y) { return fTiles[y * fXTiles + x].count(); }
 
 private:
-    SkTDArray<void*>& tile(int x, int y);
+    struct Entry {
+        size_t order;  // Insertion order.  Used to preserve order when merging multiple tiles.
+        void*  data;
+    };
 
-    int fXTileCount, fYTileCount, fTileCount;
+    const int fXTiles, fYTiles;
     SkTileGridFactory::TileGridInfo fInfo;
-    SkTDArray<void*>* fTileData;
-    int fInsertionCount;
-    SkIRect fGridBounds;
-    SkTileGridNextDatumFunctionPtr fNextDatumFunction;
+    size_t fCount;
+
+    // (fXTiles * fYTiles) SkTDArrays, each listing data overlapping that tile in insertion order.
+    SkTDArray<Entry>* fTiles;
 
     typedef SkBBoxHierarchy INHERITED;
 };
 
-/**
- * Generic implementation for SkTileGridNextDatumFunctionPtr. user code may instantiate
- * this template to get a valid SkTileGridNextDatumFunction implementation
- *
- * Returns the next element of tileData[i][tileIndices[i]] for all i and advances
- * tileIndices[] past them. The order in which data are returned by successive
- * calls to this method must reflect the order in which the were originally
- * recorded into the tile grid.
- *
- * \param tileData array of pointers to arrays of tile data
- * \param tileIndices per-tile data indices, indices are incremented for tiles that contain
- *     the next datum.
- * \tparam T a type to which it is safe to cast a datum and that has an operator <
- *     such that 'a < b' is true if 'a' was inserted into the tile grid before 'b'.
- */
-template <typename T>
-void* SkTileGridNextDatum(SkTDArray<void*>** tileData, SkAutoSTArray<SkTileGrid::kStackAllocationTileCount, int>& tileIndices) {
-    T* minVal = NULL;
-    int tileCount = tileIndices.count();
-    int minIndex = tileCount;
-    int maxIndex = 0;
-    // Find the next Datum; track where it's found so we reduce the size of the second loop.
-    for (int tile = 0; tile < tileCount; ++tile) {
-        int pos = tileIndices[tile];
-        if (pos != SkTileGrid::kTileFinished) {
-            T* candidate = (T*)(*tileData[tile])[pos];
-            if (NULL == minVal || (*candidate) < (*minVal)) {
-                minVal = candidate;
-                minIndex = tile;
-                maxIndex = tile;
-            } else if (!((*minVal) < (*candidate))) {
-                // We don't require operator==; if !(candidate<minVal) && !(minVal<candidate),
-                // candidate==minVal and we have to add this tile to the range searched.
-                maxIndex = tile;
-            }
-        }
-    }
-    // Increment indices past the next datum
-    if (minVal != NULL) {
-        for (int tile = minIndex; tile <= maxIndex; ++tile) {
-            int pos = tileIndices[tile];
-            if (pos != SkTileGrid::kTileFinished && (*tileData[tile])[pos] == minVal) {
-                if (++(tileIndices[tile]) >= tileData[tile]->count()) {
-                    tileIndices[tile] = SkTileGrid::kTileFinished;
-                }
-            }
-        }
-        return minVal;
-    }
-    return NULL;
-}
-
 #endif
diff --git a/src/core/SkTraceEvent.h b/src/core/SkTraceEvent.h
index 0c7989f..34e3adf 100644
--- a/src/core/SkTraceEvent.h
+++ b/src/core/SkTraceEvent.h
@@ -949,7 +949,7 @@
    public:
     explicit DontMangle(const void* id)
         : data_(static_cast<uint64_t>(
-              reinterpret_cast<unsigned long>(id))) {}
+              reinterpret_cast<uintptr_t>(id))) {}
     explicit DontMangle(uint64_t id) : data_(id) {}
     explicit DontMangle(unsigned int id) : data_(id) {}
     explicit DontMangle(unsigned short id) : data_(id) {}
@@ -992,7 +992,7 @@
 
   TraceID(const void* id, unsigned char* flags)
       : data_(static_cast<uint64_t>(
-              reinterpret_cast<unsigned long>(id))) {
+              reinterpret_cast<uintptr_t>(id))) {
     *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
   }
   TraceID(ForceMangle id, unsigned char* flags) : data_(id.data()) {
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index 48be651..f948787 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -8,7 +8,7 @@
 #include "SkAdvancedTypefaceMetrics.h"
 #include "SkEndian.h"
 #include "SkFontDescriptor.h"
-#include "SkFontHost.h"
+#include "SkFontMgr.h"
 #include "SkLazyPtr.h"
 #include "SkOTTable_OS_2.h"
 #include "SkStream.h"
@@ -67,6 +67,9 @@
     public:
         virtual bool next(SkTypeface::LocalizedString*) SK_OVERRIDE { return false; }
     };
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
+        familyName->reset();
+    }
     virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE {
         return SkNEW(EmptyLocalizedStrings);
     };
@@ -76,15 +79,16 @@
     }
 };
 
+SK_DECLARE_STATIC_MUTEX(gCreateDefaultMutex);
 SkTypeface* SkTypeface::CreateDefault(int style) {
     // If backed by fontconfig, it's not safe to call SkFontHost::CreateTypeface concurrently.
     // To be safe, we serialize here with a mutex so only one call to
     // CreateTypeface is happening at any given time.
     // TODO(bungeman, mtklein): This is sad.  Make our fontconfig code safe?
-    SK_DECLARE_STATIC_MUTEX(mutex);
-    SkAutoMutexAcquire lock(&mutex);
+    SkAutoMutexAcquire lock(&gCreateDefaultMutex);
 
-    SkTypeface* t = SkFontHost::CreateTypeface(NULL, NULL, (Style)style);
+    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+    SkTypeface* t = fm->legacyCreateTypeface(NULL, style);;
     return t ? t : SkEmptyTypeface::Create();
 }
 
@@ -123,23 +127,39 @@
     if (NULL == name) {
         return RefDefault(style);
     }
-    return SkFontHost::CreateTypeface(NULL, name, style);
+    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+    return fm->legacyCreateTypeface(name, style);
 }
 
 SkTypeface* SkTypeface::CreateFromTypeface(const SkTypeface* family, Style s) {
-    if (family && family->style() == s) {
+    if (!family) {
+        return SkTypeface::RefDefault(s);
+    }
+
+    if (family->style() == s) {
         family->ref();
         return const_cast<SkTypeface*>(family);
     }
-    return SkFontHost::CreateTypeface(family, NULL, s);
+
+    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+    bool bold = s & SkTypeface::kBold;
+    bool italic = s & SkTypeface::kItalic;
+    SkFontStyle newStyle = SkFontStyle(bold ? SkFontStyle::kBold_Weight
+                                            : SkFontStyle::kNormal_Weight,
+                                       SkFontStyle::kNormal_Width,
+                                       italic ? SkFontStyle::kItalic_Slant
+                                              : SkFontStyle::kUpright_Slant);
+    return fm->matchFaceStyle(family, newStyle);
 }
 
-SkTypeface* SkTypeface::CreateFromStream(SkStream* stream) {
-    return SkFontHost::CreateTypefaceFromStream(stream);
+SkTypeface* SkTypeface::CreateFromStream(SkStream* stream, int index) {
+    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+    return fm->createFromStream(stream, index);
 }
 
-SkTypeface* SkTypeface::CreateFromFile(const char path[]) {
-    return SkFontHost::CreateTypefaceFromFile(path);
+SkTypeface* SkTypeface::CreateFromFile(const char path[], int index) {
+    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+    return fm->createFromFile(path, index);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -149,45 +169,24 @@
     SkFontDescriptor desc(this->style());
     this->onGetFontDescriptor(&desc, &isLocal);
 
-    desc.serialize(wstream);
-    if (isLocal) {
-        int ttcIndex;   // TODO: write this to the stream?
-        SkAutoTUnref<SkStream> rstream(this->openStream(&ttcIndex));
-        if (rstream.get()) {
-            size_t length = rstream->getLength();
-            wstream->writePackedUInt(length);
-            wstream->writeStream(rstream, length);
-        } else {
-            wstream->writePackedUInt(0);
-        }
-    } else {
-        wstream->writePackedUInt(0);
+    if (isLocal && NULL == desc.getFontData()) {
+        int ttcIndex;
+        desc.setFontData(this->onOpenStream(&ttcIndex));
+        desc.setFontIndex(ttcIndex);
     }
+
+    desc.serialize(wstream);
 }
 
 SkTypeface* SkTypeface::Deserialize(SkStream* stream) {
     SkFontDescriptor desc(stream);
-    size_t length = stream->readPackedUInt();
-    if (length > 0) {
-        void* addr = sk_malloc_flags(length, 0);
-        if (addr) {
-            SkAutoTUnref<SkMemoryStream> localStream(SkNEW(SkMemoryStream));
-            localStream->setMemoryOwned(addr, length);
-
-            if (stream->read(addr, length) == length) {
-                return SkTypeface::CreateFromStream(localStream.get());
-            } else {
-                // Failed to read the full font data, so fall through and try to create from name.
-                // If this is because of EOF, all subsequent reads from the stream will be EOF.
-                // If this is because of a stream error, the stream is in an error state,
-                // do not attempt to skip any remaining bytes.
-            }
-        } else {
-            // failed to allocate, so just skip and create-from-name
-            stream->skip(length);
+    SkStream* data = desc.getFontData();
+    if (data) {
+        SkTypeface* typeface = SkTypeface::CreateFromStream(data, desc.getFontIndex());
+        if (typeface) {
+            return typeface;
         }
     }
-
     return SkTypeface::CreateFromName(desc.getFamilyName(), desc.getStyle());
 }
 
@@ -261,10 +260,8 @@
 }
 
 void SkTypeface::getFamilyName(SkString* name) const {
-    bool isLocal = false;
-    SkFontDescriptor desc(this->style());
-    this->onGetFontDescriptor(&desc, &isLocal);
-    name->set(desc.getFamilyName());
+    SkASSERT(name);
+    this->onGetFamilyName(name);
 }
 
 SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
diff --git a/src/core/SkUtils.cpp b/src/core/SkUtils.cpp
index eff718b..b063071 100644
--- a/src/core/SkUtils.cpp
+++ b/src/core/SkUtils.cpp
@@ -193,7 +193,7 @@
 }
 
 int SkUTF8_CountUnichars(const char utf8[], size_t byteLength) {
-    SkASSERT(NULL != utf8 || 0 == byteLength);
+    SkASSERT(utf8 || 0 == byteLength);
 
     int         count = 0;
     const char* stop = utf8 + byteLength;
@@ -206,7 +206,7 @@
 }
 
 SkUnichar SkUTF8_ToUnichar(const char utf8[]) {
-    SkASSERT(NULL != utf8);
+    SkASSERT(utf8);
 
     const uint8_t*  p = (const uint8_t*)utf8;
     int             c = *p;
@@ -227,7 +227,7 @@
 }
 
 SkUnichar SkUTF8_NextUnichar(const char** ptr) {
-    SkASSERT(NULL != ptr && NULL != *ptr);
+    SkASSERT(ptr && *ptr);
 
     const uint8_t*  p = (const uint8_t*)*ptr;
     int             c = *p;
@@ -249,7 +249,7 @@
 }
 
 SkUnichar SkUTF8_PrevUnichar(const char** ptr) {
-    SkASSERT(NULL != ptr && NULL != *ptr);
+    SkASSERT(ptr && *ptr);
 
     const char* p = *ptr;
 
diff --git a/src/core/SkUtilsArm.cpp b/src/core/SkUtilsArm.cpp
index 58cf115..1ff5bf0 100644
--- a/src/core/SkUtilsArm.cpp
+++ b/src/core/SkUtilsArm.cpp
@@ -16,73 +16,24 @@
 #include <string.h>
 #include <pthread.h>
 
-// Set USE_ANDROID_NDK_CPU_FEATURES to use the Android NDK's
-// cpu-features helper library to detect NEON at runtime. See
-// http://crbug.com/164154 to see why this is needed in Chromium
-// for Android.
-#if !defined(USE_ANDROID_NDK_CPU_FEATURES)
-#  if defined(SK_BUILD_FOR_ANDROID)
-#    define USE_ANDROID_NDK_CPU_FEATURES 1
-#  else
-#    define USE_ANDROID_NDK_CPU_FEATURES 0
-#  endif
-#endif
-
-#if USE_ANDROID_NDK_CPU_FEATURES
+#if SK_BUILD_FOR_ANDROID
 #  include <cpu-features.h>
 #endif
 
-// Set NEON_DEBUG to 1 to allow debugging of the CPU features probing.
-// For now, we always set it for SK_DEBUG builds.
-#ifdef SK_DEBUG
-#  define NEON_DEBUG  1
-#else
-#  define NEON_DEBUG 0
-#endif
-
-#if NEON_DEBUG
-#  ifdef SK_BUILD_FOR_ANDROID
-     // used to declare PROP_VALUE_MAX and __system_property_get()
-#    include <sys/system_properties.h>
-#  endif
-#endif
-
 // A function used to determine at runtime if the target CPU supports
 // the ARM NEON instruction set. This implementation is Linux-specific.
 static bool sk_cpu_arm_check_neon(void) {
+    // If we fail any of the following, assume we don't have NEON instructions
+    // This allows us to return immediately in case of error.
     bool result = false;
 
-#if NEON_DEBUG
-    // Allow forcing the mode through the environment during debugging.
-#  ifdef SK_BUILD_FOR_ANDROID
-    // On Android, we use a system property
-#   define PROP_NAME  "debug.skia.arm_neon_mode"
-    char prop[PROP_VALUE_MAX];
-    if (__system_property_get(PROP_NAME, prop) > 0) {
-#  else
-#   define PROP_NAME   "SKIA_ARM_NEON_MODE"
-    // On ARM Linux, we use an environment variable
-    const char* prop = getenv(PROP_NAME);
-    if (prop != NULL) {
-#  endif
-        SkDebugf("%s: %s", PROP_NAME, prop);
-        if (!strcmp(prop, "1")) {
-            SkDebugf("Forcing ARM Neon mode to full!\n");
-            return true;
-        }
-        if (!strcmp(prop, "0")) {
-            SkDebugf("Disabling ARM NEON mode\n");
-            return false;
-        }
-    }
-    SkDebugf("Running dynamic CPU feature detection\n");
-#endif
-
-#if USE_ANDROID_NDK_CPU_FEATURES
+// Use the Android NDK's cpu-features helper library to detect NEON at runtime.
+// See http://crbug.com/164154 to see why this is needed in Chromium for Android.
+#ifdef SK_BUILD_FOR_ANDROID
 
   result = (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
 
-#else  // USE_ANDROID_NDK_CPU_FEATURES
+#else  // SK_BUILD_FOR_ANDROID
 
     // There is no user-accessible CPUID instruction on ARM that we can use.
     // Instead, we must parse /proc/cpuinfo and look for the 'neon' feature.
@@ -103,10 +54,6 @@
     */
     char   buffer[4096];
 
-    // If we fail any of the following, assume we don't have NEON instructions
-    // This allows us to return immediately in case of error.
-    result = false;
-
     do {
         // open /proc/cpuinfo
         int fd = TEMP_FAILURE_RETRY(open("/proc/cpuinfo", O_RDONLY));
@@ -173,12 +120,12 @@
 
     } while (0);
 
-#endif  // USE_ANDROID_NDK_CPU_FEATURES
+#endif  // SK_BUILD_FOR_ANDROID
 
     if (result) {
-        SkDebugf("Device supports ARM NEON instructions!\n");
+        SkDEBUGF(("Device supports ARM NEON instructions!\n"));
     } else {
-        SkDebugf("Device does NOT support ARM NEON instructions!\n");
+        SkDEBUGF(("Device does NOT support ARM NEON instructions!\n"));
     }
     return result;
 }
diff --git a/src/core/SkUtilsArm.h b/src/core/SkUtilsArm.h
index 09ddaf3..f156481 100644
--- a/src/core/SkUtilsArm.h
+++ b/src/core/SkUtilsArm.h
@@ -21,9 +21,9 @@
 #define SK_ARM_NEON_MODE_ALWAYS   1
 #define SK_ARM_NEON_MODE_DYNAMIC  2
 
-#if defined(SK_CPU_ARM32) && defined(__ARM_HAVE_OPTIONAL_NEON_SUPPORT)
+#if defined(SK_CPU_ARM32) && defined(SK_ARM_HAS_OPTIONAL_NEON)
 #  define SK_ARM_NEON_MODE  SK_ARM_NEON_MODE_DYNAMIC
-#elif defined(SK_CPU_ARM32) && defined(__ARM_HAVE_NEON) || defined(SK_CPU_ARM64)
+#elif defined(SK_CPU_ARM32) && defined(SK_ARM_HAS_NEON) || defined(SK_CPU_ARM64)
 #  define SK_ARM_NEON_MODE  SK_ARM_NEON_MODE_ALWAYS
 #else
 #  define SK_ARM_NEON_MODE  SK_ARM_NEON_MODE_NONE
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index b5f95da..8a3218f 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -676,21 +676,18 @@
     return false;
 }
 
-bool SkXfermode::asNewEffect(GrEffectRef** effect, GrTexture* background) const {
+bool SkXfermode::asFragmentProcessor(GrFragmentProcessor**, GrTexture*) const {
     return false;
 }
 
-bool SkXfermode::AsNewEffectOrCoeff(SkXfermode* xfermode,
-                                    GrEffectRef** effect,
-                                    Coeff* src,
-                                    Coeff* dst,
-                                    GrTexture* background) {
+bool SkXfermode::asFragmentProcessorOrCoeff(SkXfermode* xfermode, GrFragmentProcessor** fp,
+                                            Coeff* src, Coeff* dst, GrTexture* background) {
     if (NULL == xfermode) {
         return ModeAsCoeff(kSrcOver_Mode, src, dst);
     } else if (xfermode->asCoeff(src, dst)) {
         return true;
     } else {
-        return xfermode->asNewEffect(effect, background);
+        return xfermode->asFragmentProcessor(fp, background);
     }
 }
 
@@ -778,27 +775,27 @@
 
 #if SK_SUPPORT_GPU
 
-#include "GrEffect.h"
+#include "GrProcessor.h"
 #include "GrCoordTransform.h"
-#include "GrEffectUnitTest.h"
-#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLEffect.h"
+#include "GrProcessorUnitTest.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 
 /**
- * GrEffect that implements the all the separable xfer modes that cannot be expressed as Coeffs.
+ * GrProcessor that implements the all the separable xfer modes that cannot be expressed as Coeffs.
  */
-class XferEffect : public GrEffect {
+class XferEffect : public GrFragmentProcessor {
 public:
     static bool IsSupportedMode(SkXfermode::Mode mode) {
         return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMode;
     }
 
-    static GrEffectRef* Create(SkXfermode::Mode mode, GrTexture* background) {
+    static GrFragmentProcessor* Create(SkXfermode::Mode mode, GrTexture* background) {
         if (!IsSupportedMode(mode)) {
             return NULL;
         } else {
-            AutoEffectUnref effect(SkNEW_ARGS(XferEffect, (mode, background)));
-            return CreateEffectRef(effect);
+            return SkNEW_ARGS(XferEffect, (mode, background));
         }
     }
 
@@ -807,8 +804,8 @@
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<XferEffect>::getInstance();
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<XferEffect>::getInstance();
     }
 
     static const char* Name() { return "XferEffect"; }
@@ -816,96 +813,98 @@
     SkXfermode::Mode mode() const { return fMode; }
     const GrTextureAccess&  backgroundAccess() const { return fBackgroundAccess; }
 
-    class GLEffect : public GrGLEffect {
+    class GLProcessor : public GrGLFragmentProcessor {
     public:
-        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
-            : GrGLEffect(factory) {
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
+            : INHERITED(factory) {
         }
-        virtual void emitCode(GrGLShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+        virtual void emitCode(GrGLProgramBuilder* builder,
+                              const GrFragmentProcessor& fp,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray& coords,
                               const TextureSamplerArray& samplers) SK_OVERRIDE {
-            SkXfermode::Mode mode = drawEffect.castEffect<XferEffect>().mode();
-            const GrTexture* backgroundTex = drawEffect.castEffect<XferEffect>().backgroundAccess().getTexture();
+            SkXfermode::Mode mode = fp.cast<XferEffect>().mode();
+            const GrTexture* backgroundTex =
+                    fp.cast<XferEffect>().backgroundAccess().getTexture();
+            GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
             const char* dstColor;
             if (backgroundTex) {
                 dstColor = "bgColor";
-                builder->fsCodeAppendf("\t\tvec4 %s = ", dstColor);
-                builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
-                builder->fsCodeAppendf(";\n");
+                fsBuilder->codeAppendf("\t\tvec4 %s = ", dstColor);
+                fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
+                fsBuilder->codeAppendf(";\n");
             } else {
-                dstColor = builder->dstColor();
+                dstColor = fsBuilder->dstColor();
             }
-            SkASSERT(NULL != dstColor);
+            SkASSERT(dstColor);
 
             // We don't try to optimize for this case at all
             if (NULL == inputColor) {
-                builder->fsCodeAppendf("\t\tconst vec4 ones = vec4(1);\n");
+                fsBuilder->codeAppendf("\t\tconst vec4 ones = vec4(1);\n");
                 inputColor = "ones";
             }
-            builder->fsCodeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode));
+            fsBuilder->codeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode));
 
             // These all perform src-over on the alpha channel.
-            builder->fsCodeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n",
+            fsBuilder->codeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n",
                                     outputColor, inputColor, inputColor, dstColor);
 
             switch (mode) {
                 case SkXfermode::kOverlay_Mode:
                     // Overlay is Hard-Light with the src and dst reversed
-                    HardLight(builder, outputColor, dstColor, inputColor);
+                    HardLight(fsBuilder, outputColor, dstColor, inputColor);
                     break;
                 case SkXfermode::kDarken_Mode:
-                    builder->fsCodeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, "
+                    fsBuilder->codeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, "
                                                             "(1.0 - %s.a) * %s.rgb + %s.rgb);\n",
                                             outputColor,
                                             inputColor, dstColor, inputColor,
                                             dstColor, inputColor, dstColor);
                     break;
                 case SkXfermode::kLighten_Mode:
-                    builder->fsCodeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, "
+                    fsBuilder->codeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, "
                                                             "(1.0 - %s.a) * %s.rgb + %s.rgb);\n",
                                             outputColor,
                                             inputColor, dstColor, inputColor,
                                             dstColor, inputColor, dstColor);
                     break;
                 case SkXfermode::kColorDodge_Mode:
-                    ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'r');
-                    ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'g');
-                    ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'b');
+                    ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'r');
+                    ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'g');
+                    ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'b');
                     break;
                 case SkXfermode::kColorBurn_Mode:
-                    ColorBurnComponent(builder, outputColor, inputColor, dstColor, 'r');
-                    ColorBurnComponent(builder, outputColor, inputColor, dstColor, 'g');
-                    ColorBurnComponent(builder, outputColor, inputColor, dstColor, 'b');
+                    ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'r');
+                    ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'g');
+                    ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'b');
                     break;
                 case SkXfermode::kHardLight_Mode:
-                    HardLight(builder, outputColor, inputColor, dstColor);
+                    HardLight(fsBuilder, outputColor, inputColor, dstColor);
                     break;
                 case SkXfermode::kSoftLight_Mode:
-                    builder->fsCodeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor);
-                    builder->fsCodeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor);
-                    builder->fsCodeAppendf("\t\t} else {\n");
-                    SoftLightComponentPosDstAlpha(builder, outputColor, inputColor, dstColor, 'r');
-                    SoftLightComponentPosDstAlpha(builder, outputColor, inputColor, dstColor, 'g');
-                    SoftLightComponentPosDstAlpha(builder, outputColor, inputColor, dstColor, 'b');
-                    builder->fsCodeAppendf("\t\t}\n");
+                    fsBuilder->codeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor);
+                    fsBuilder->codeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor);
+                    fsBuilder->codeAppendf("\t\t} else {\n");
+                    SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'r');
+                    SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'g');
+                    SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'b');
+                    fsBuilder->codeAppendf("\t\t}\n");
                     break;
                 case SkXfermode::kDifference_Mode:
-                    builder->fsCodeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -"
+                    fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -"
                                                        "2.0 * min(%s.rgb * %s.a, %s.rgb * %s.a);\n",
                                            outputColor, inputColor, dstColor, inputColor, dstColor,
                                            dstColor, inputColor);
                     break;
                 case SkXfermode::kExclusion_Mode:
-                    builder->fsCodeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - "
+                    fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - "
                                                         "2.0 * %s.rgb * %s.rgb;\n",
                                            outputColor, dstColor, inputColor, dstColor, inputColor);
                     break;
                 case SkXfermode::kMultiply_Mode:
-                    builder->fsCodeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + "
+                    fsBuilder->codeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + "
                                                         "(1.0 - %s.a) * %s.rgb + "
                                                          "%s.rgb * %s.rgb;\n",
                                            outputColor, inputColor, dstColor, dstColor, inputColor,
@@ -914,52 +913,52 @@
                 case SkXfermode::kHue_Mode: {
                     //  SetLum(SetSat(S * Da, Sat(D * Sa)), Sa*Da, D*Sa) + (1 - Sa) * D + (1 - Da) * S
                     SkString setSat, setLum;
-                    AddSatFunction(builder, &setSat);
-                    AddLumFunction(builder, &setLum);
-                    builder->fsCodeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
+                    AddSatFunction(fsBuilder, &setSat);
+                    AddLumFunction(fsBuilder, &setLum);
+                    fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
                                            dstColor, inputColor);
-                    builder->fsCodeAppendf("\t\t%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
+                    fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
                                            outputColor, setLum.c_str(), setSat.c_str(), inputColor,
                                            dstColor);
-                    builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
+                    fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
                                            outputColor, inputColor, dstColor, dstColor, inputColor);
                     break;
                 }
                 case SkXfermode::kSaturation_Mode: {
                     // SetLum(SetSat(D * Sa, Sat(S * Da)), Sa*Da, D*Sa)) + (1 - Sa) * D + (1 - Da) * S
                     SkString setSat, setLum;
-                    AddSatFunction(builder, &setSat);
-                    AddLumFunction(builder, &setLum);
-                    builder->fsCodeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
+                    AddSatFunction(fsBuilder, &setSat);
+                    AddLumFunction(fsBuilder, &setLum);
+                    fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
                                            dstColor, inputColor);
-                    builder->fsCodeAppendf("\t\t%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
+                    fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
                                            outputColor, setLum.c_str(), setSat.c_str(), inputColor,
                                            dstColor);
-                    builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
+                    fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
                                            outputColor, inputColor, dstColor, dstColor, inputColor);
                     break;
                 }
                 case SkXfermode::kColor_Mode: {
                     //  SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S
                     SkString setLum;
-                    AddLumFunction(builder, &setLum);
-                    builder->fsCodeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
+                    AddLumFunction(fsBuilder, &setLum);
+                    fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
                                            inputColor, dstColor);
-                    builder->fsCodeAppendf("\t\t%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);\n",
+                    fsBuilder->codeAppendf("\t\t%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);\n",
                                            outputColor, setLum.c_str(), dstColor, inputColor);
-                    builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
+                    fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
                                            outputColor, inputColor, dstColor, dstColor, inputColor);
                     break;
                 }
                 case SkXfermode::kLuminosity_Mode: {
                     //  SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S
                     SkString setLum;
-                    AddLumFunction(builder, &setLum);
-                    builder->fsCodeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
+                    AddLumFunction(fsBuilder, &setLum);
+                    fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
                                            inputColor, dstColor);
-                    builder->fsCodeAppendf("\t\t%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);\n",
+                    fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);\n",
                                            outputColor, setLum.c_str(), dstColor, inputColor);
-                    builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
+                    fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
                                            outputColor, inputColor, dstColor, dstColor, inputColor);
                     break;
                 }
@@ -969,124 +968,126 @@
             }
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        static inline void GenKey(const GrProcessor& proc, const GrGLCaps&,
+                                  GrProcessorKeyBuilder* b) {
             // The background may come from the dst or from a texture.
-            int numTextures = (*drawEffect.effect())->numTextures();
-            SkASSERT(numTextures <= 1);
-            return (drawEffect.castEffect<XferEffect>().mode() << 1) | numTextures;
+            uint32_t key = proc.numTextures();
+            SkASSERT(key <= 1);
+            key |= proc.cast<XferEffect>().mode() << 1;
+            b->add32(key);
         }
 
     private:
-        static void HardLight(GrGLShaderBuilder* builder,
+        static void HardLight(GrGLFragmentShaderBuilder* fsBuilder,
                               const char* final,
                               const char* src,
                               const char* dst) {
             static const char kComponents[] = {'r', 'g', 'b'};
             for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) {
                 char component = kComponents[i];
-                builder->fsCodeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
-                builder->fsCodeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", final, component, src, component, dst, component);
-                builder->fsCodeAppend("\t\t} else {\n");
-                builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s.a - %s.%c);\n",
+                fsBuilder->codeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
+                fsBuilder->codeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", final, component, src, component, dst, component);
+                fsBuilder->codeAppend("\t\t} else {\n");
+                fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s.a - %s.%c);\n",
                                        final, component, src, dst, dst, dst, component, src, src, component);
-                builder->fsCodeAppend("\t\t}\n");
+                fsBuilder->codeAppend("\t\t}\n");
             }
-            builder->fsCodeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n",
+            fsBuilder->codeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n",
                                    final, src, dst, dst, src);
         }
 
         // Does one component of color-dodge
-        static void ColorDodgeComponent(GrGLShaderBuilder* builder,
+        static void ColorDodgeComponent(GrGLFragmentShaderBuilder* fsBuilder,
                                         const char* final,
                                         const char* src,
                                         const char* dst,
                                         const char component) {
-            builder->fsCodeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component);
-            builder->fsCodeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
+            fsBuilder->codeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component);
+            fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
                                    final, component, src, component, dst);
-            builder->fsCodeAppend("\t\t} else {\n");
-            builder->fsCodeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component);
-            builder->fsCodeAppend("\t\t\tif (0.0 == d) {\n");
-            builder->fsCodeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
+            fsBuilder->codeAppend("\t\t} else {\n");
+            fsBuilder->codeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component);
+            fsBuilder->codeAppend("\t\t\tif (0.0 == d) {\n");
+            fsBuilder->codeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
                                    final, component, src, dst, src, component, dst, dst, component,
                                    src);
-            builder->fsCodeAppend("\t\t\t} else {\n");
-            builder->fsCodeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n",
+            fsBuilder->codeAppend("\t\t\t} else {\n");
+            fsBuilder->codeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n",
                                    dst, dst, component, src);
-            builder->fsCodeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
+            fsBuilder->codeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
                                    final, component, src, src, component, dst, dst, component, src);
-            builder->fsCodeAppend("\t\t\t}\n");
-            builder->fsCodeAppend("\t\t}\n");
+            fsBuilder->codeAppend("\t\t\t}\n");
+            fsBuilder->codeAppend("\t\t}\n");
         }
 
         // Does one component of color-burn
-        static void ColorBurnComponent(GrGLShaderBuilder* builder,
+        static void ColorBurnComponent(GrGLFragmentShaderBuilder* fsBuilder,
                                        const char* final,
                                        const char* src,
                                        const char* dst,
                                        const char component) {
-            builder->fsCodeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, component);
-            builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
+            fsBuilder->codeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, component);
+            fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
                                    final, component, src, dst, src, component, dst, dst, component,
                                    src);
-            builder->fsCodeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, component);
-            builder->fsCodeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
+            fsBuilder->codeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, component);
+            fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
                                    final, component, dst, component, src);
-            builder->fsCodeAppend("\t\t} else {\n");
-            builder->fsCodeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / %s.%c);\n",
+            fsBuilder->codeAppend("\t\t} else {\n");
+            fsBuilder->codeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / %s.%c);\n",
                                    dst, dst, dst, component, src, src, component);
-            builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
+            fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
                                    final, component, src, src, component, dst, dst, component, src);
-            builder->fsCodeAppend("\t\t}\n");
+            fsBuilder->codeAppend("\t\t}\n");
         }
 
         // Does one component of soft-light. Caller should have already checked that dst alpha > 0.
-        static void SoftLightComponentPosDstAlpha(GrGLShaderBuilder* builder,
+        static void SoftLightComponentPosDstAlpha(GrGLFragmentShaderBuilder* fsBuilder,
                                                   const char* final,
                                                   const char* src,
                                                   const char* dst,
                                                   const char component) {
             // if (2S < Sa)
-            builder->fsCodeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
+            fsBuilder->codeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
             // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1)
-            builder->fsCodeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.%c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n",
+            fsBuilder->codeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.%c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n",
                                    final, component, dst, component, dst, component, src, src,
                                    component, dst, dst, src, component, dst, component, src, src,
                                    component);
             // else if (4D < Da)
-            builder->fsCodeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n",
+            fsBuilder->codeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n",
                                    dst, component, dst);
-            builder->fsCodeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n",
+            fsBuilder->codeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n",
                                    dst, component, dst, component);
-            builder->fsCodeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component);
-            builder->fsCodeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst);
-            builder->fsCodeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst);
+            fsBuilder->codeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component);
+            fsBuilder->codeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst);
+            fsBuilder->codeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst);
             // (Da^3 (-S)+Da^2 (S-D (3 Sa-6 S-1))+12 Da D^2 (Sa-2 S)-16 D^3 (Sa-2 S))/Da^2
-            builder->fsCodeAppendf("\t\t\t\t%s.%c = (-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) + 12.0*%s.a*DSqd*(%s.a - 2.0*%s.%c) - 16.0*DCub * (%s.a - 2.0*%s.%c)) / DaSqd;\n",
+            fsBuilder->codeAppendf("\t\t\t\t%s.%c = (-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) + 12.0*%s.a*DSqd*(%s.a - 2.0*%s.%c) - 16.0*DCub * (%s.a - 2.0*%s.%c)) / DaSqd;\n",
                                    final, component, src, component, src, component, dst, component,
                                    src, src, component, dst, src, src, component, src, src,
                                    component);
-            builder->fsCodeAppendf("\t\t\t} else {\n");
+            fsBuilder->codeAppendf("\t\t\t} else {\n");
             // -sqrt(Da * D) (Sa-2 S)-Da S+D (Sa-2 S+1)+S
-            builder->fsCodeAppendf("\t\t\t\t%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2.0*%s.%c) - %s.a*%s.%c + %s.%c*(%s.a - 2.0*%s.%c + 1.0) + %s.%c;\n",
+            fsBuilder->codeAppendf("\t\t\t\t%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2.0*%s.%c) - %s.a*%s.%c + %s.%c*(%s.a - 2.0*%s.%c + 1.0) + %s.%c;\n",
                                     final, component, dst, dst, component, src, src, component, dst,
                                     src, component, dst, component, src, src, component, src,
                                     component);
-            builder->fsCodeAppendf("\t\t\t}\n");
+            fsBuilder->codeAppendf("\t\t\t}\n");
         }
 
         // Adds a function that takes two colors and an alpha as input. It produces a color with the
         // hue and saturation of the first color, the luminosity of the second color, and the input
         // alpha. It has this signature:
         //      vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor).
-        static void AddLumFunction(GrGLShaderBuilder* builder, SkString* setLumFunction) {
+        static void AddLumFunction(GrGLFragmentShaderBuilder* fsBuilder, SkString* setLumFunction) {
             // Emit a helper that gets the luminance of a color.
             SkString getFunction;
             GrGLShaderVar getLumArgs[] = {
                 GrGLShaderVar("color", kVec3f_GrSLType),
             };
             SkString getLumBody("\treturn dot(vec3(0.3, 0.59, 0.11), color);\n");
-            builder->fsEmitFunction(kFloat_GrSLType,
+            fsBuilder->emitFunction(kFloat_GrSLType,
                                     "luminance",
                                     SK_ARRAY_COUNT(getLumArgs), getLumArgs,
                                     getLumBody.c_str(),
@@ -1111,7 +1112,7 @@
                               "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) / (maxComp - outLum);\n"
                               "\t}\n"
                               "\treturn outColor;\n");
-            builder->fsEmitFunction(kVec3f_GrSLType,
+            fsBuilder->emitFunction(kVec3f_GrSLType,
                                     "set_luminance",
                                     SK_ARRAY_COUNT(setLumArgs), setLumArgs,
                                     setLumBody.c_str(),
@@ -1121,14 +1122,14 @@
         // Adds a function that creates a color with the hue and luminosity of one input color and
         // the saturation of another color. It will have this signature:
         //      float set_saturation(vec3 hueLumColor, vec3 satColor)
-        static void AddSatFunction(GrGLShaderBuilder* builder, SkString* setSatFunction) {
+        static void AddSatFunction(GrGLFragmentShaderBuilder* fsBuilder, SkString* setSatFunction) {
             // Emit a helper that gets the saturation of a color
             SkString getFunction;
             GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLType) };
             SkString getSatBody;
             getSatBody.printf("\treturn max(max(color.r, color.g), color.b) - "
                               "min(min(color.r, color.g), color.b);\n");
-            builder->fsEmitFunction(kFloat_GrSLType,
+            fsBuilder->emitFunction(kFloat_GrSLType,
                                     "saturation",
                                     SK_ARRAY_COUNT(getSatArgs), getSatArgs,
                                     getSatBody.c_str(),
@@ -1154,7 +1155,7 @@
                                               "\t} else {\n"
                                               "\t\treturn vec3(0, 0, 0);\n"
                                               "\t}\n";
-            builder->fsEmitFunction(kVec3f_GrSLType,
+            fsBuilder->emitFunction(kVec3f_GrSLType,
                                     "set_saturation_helper",
                                     SK_ARRAY_COUNT(helperArgs), helperArgs,
                                     kHelperBody,
@@ -1185,7 +1186,7 @@
                                "\treturn hueLumColor;\n",
                                getFunction.c_str(), helpFunc, helpFunc, helpFunc, helpFunc,
                                helpFunc, helpFunc);
-            builder->fsEmitFunction(kVec3f_GrSLType,
+            fsBuilder->emitFunction(kVec3f_GrSLType,
                                     "set_saturation",
                                     SK_ARRAY_COUNT(setSatArgs), setSatArgs,
                                     setSatBody.c_str(),
@@ -1193,10 +1194,10 @@
 
         }
 
-        typedef GrGLEffect INHERITED;
+        typedef GrGLFragmentProcessor INHERITED;
     };
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
 private:
     XferEffect(SkXfermode::Mode mode, GrTexture* background)
@@ -1210,8 +1211,8 @@
             this->setWillReadDstColor();
         }
     }
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
-        const XferEffect& s = CastEffect<XferEffect>(other);
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE {
+        const XferEffect& s = other.cast<XferEffect>();
         return fMode == s.fMode &&
                fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture();
     }
@@ -1220,18 +1221,17 @@
     GrCoordTransform fBackgroundTransform;
     GrTextureAccess  fBackgroundAccess;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
-GR_DEFINE_EFFECT_TEST(XferEffect);
-GrEffectRef* XferEffect::TestCreate(SkRandom* rand,
-                                    GrContext*,
-                                    const GrDrawTargetCaps&,
-                                    GrTexture*[]) {
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(XferEffect);
+GrFragmentProcessor* XferEffect::TestCreate(SkRandom* rand,
+                                            GrContext*,
+                                            const GrDrawTargetCaps&,
+                                            GrTexture*[]) {
     int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLastSeparableMode);
 
-    AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermode::Mode>(mode), NULL)));
-    return CreateEffectRef(gEffect);
+    return SkNEW_ARGS(XferEffect, (static_cast<SkXfermode::Mode>(mode), NULL));
 }
 
 #endif
@@ -1239,6 +1239,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkProcCoeffXfermode::SkProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     uint32_t mode32 = buffer.read32() % SK_ARRAY_COUNT(gProcCoeffs);
     if (mode32 >= SK_ARRAY_COUNT(gProcCoeffs)) {
@@ -1253,6 +1254,19 @@
     fSrcCoeff = rec.fSC;
     fDstCoeff = rec.fDC;
 }
+#endif
+
+SkFlattenable* SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) {
+    uint32_t mode32 = buffer.read32();
+    if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcCoeffs))) {
+        return NULL;
+    }
+    return SkXfermode::Create((SkXfermode::Mode)mode32);
+}
+
+void SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const {
+    buffer.write32(fMode);
+}
 
 bool SkProcCoeffXfermode::asMode(Mode* mode) const {
     if (mode) {
@@ -1282,7 +1296,7 @@
 
     SkXfermodeProc proc = fProc;
 
-    if (NULL != proc) {
+    if (proc) {
         if (NULL == aa) {
             for (int i = count - 1; i >= 0; --i) {
                 dst[i] = proc(src[i], dst[i]);
@@ -1310,7 +1324,7 @@
 
     SkXfermodeProc proc = fProc;
 
-    if (NULL != proc) {
+    if (proc) {
         if (NULL == aa) {
             for (int i = count - 1; i >= 0; --i) {
                 SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
@@ -1339,7 +1353,7 @@
 
     SkXfermodeProc proc = fProc;
 
-    if (NULL != proc) {
+    if (proc) {
         if (NULL == aa) {
             for (int i = count - 1; i >= 0; --i) {
                 SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT);
@@ -1363,12 +1377,12 @@
 }
 
 #if SK_SUPPORT_GPU
-bool SkProcCoeffXfermode::asNewEffect(GrEffectRef** effect,
-                                      GrTexture* background) const {
+bool SkProcCoeffXfermode::asFragmentProcessor(GrFragmentProcessor** fp,
+                                              GrTexture* background) const {
     if (XferEffect::IsSupportedMode(fMode)) {
-        if (NULL != effect) {
-            *effect = XferEffect::Create(fMode, background);
-            SkASSERT(NULL != *effect);
+        if (fp) {
+            *fp = XferEffect::Create(fMode, background);
+            SkASSERT(*fp);
         }
         return true;
     }
@@ -1376,11 +1390,6 @@
 }
 #endif
 
-void SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-    buffer.write32(fMode);
-}
-
 const char* SkXfermode::ModeName(Mode mode) {
     SkASSERT((unsigned) mode <= (unsigned)kLastMode);
     const char* gModeStrings[] = {
@@ -1433,12 +1442,12 @@
     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkClearXfermode)
 
 private:
     SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {}
-    SkClearXfermode(SkReadBuffer& buffer)
-        : SkProcCoeffXfermode(buffer) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    SkClearXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {}
+#endif
 
     typedef SkProcCoeffXfermode INHERITED;
 };
@@ -1498,13 +1507,12 @@
     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSrcXfermode)
 
 private:
     SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {}
-    SkSrcXfermode(SkReadBuffer& buffer)
-        : SkProcCoeffXfermode(buffer) {}
-
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    SkSrcXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {}
+#endif
     typedef SkProcCoeffXfermode INHERITED;
 };
 
@@ -1567,11 +1575,12 @@
     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstInXfermode)
 
 private:
     SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkDstInXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     typedef SkProcCoeffXfermode INHERITED;
 };
@@ -1584,7 +1593,7 @@
     if (count <= 0) {
         return;
     }
-    if (NULL != aa) {
+    if (aa) {
         return this->INHERITED::xfer32(dst, src, count, aa);
     }
 
@@ -1613,12 +1622,12 @@
     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstOutXfermode)
 
 private:
     SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {}
-    SkDstOutXfermode(SkReadBuffer& buffer)
-        : INHERITED(buffer) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    SkDstOutXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     typedef SkProcCoeffXfermode INHERITED;
 };
@@ -1631,7 +1640,7 @@
     if (count <= 0) {
         return;
     }
-    if (NULL != aa) {
+    if (aa) {
         return this->INHERITED::xfer32(dst, src, count, aa);
     }
 
@@ -1692,7 +1701,7 @@
                 break;
             default:
                 // no special-case, just rely in the rec and its function-ptrs
-                xfer = SkProcCoeffXfermode::Create(rec, mode);
+                xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode));
                 break;
         }
     }
@@ -1952,14 +1961,4 @@
 
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode)
-#if !SK_ARM_NEON_IS_NONE
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNEONProcCoeffXfermode)
-#endif
-#if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSSE2ProcCoeffXfermode)
-#endif
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/core/SkXfermode_proccoeff.h b/src/core/SkXfermode_proccoeff.h
index 7edf665..f3b9b24 100644
--- a/src/core/SkXfermode_proccoeff.h
+++ b/src/core/SkXfermode_proccoeff.h
@@ -15,10 +15,14 @@
 
 class SK_API SkProcCoeffXfermode : public SkXfermode {
 public:
-    static SkProcCoeffXfermode* Create(const ProcCoeff& rec, Mode mode) {
-        return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode));
+    SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) {
+        fMode = mode;
+        fProc = rec.fProc;
+        // these may be valid, or may be CANNOT_USE_COEFF
+        fSrcCoeff = rec.fSC;
+        fDstCoeff = rec.fDC;
     }
-
+    
     virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
                         const SkAlpha aa[]) const SK_OVERRIDE;
     virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
@@ -31,23 +35,17 @@
     virtual bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE;
 
 #if SK_SUPPORT_GPU
-    virtual bool asNewEffect(GrEffectRef** effect,
-                             GrTexture* background) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**,
+                                     GrTexture* background) const SK_OVERRIDE;
 #endif
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode)
 
 protected:
-    SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) {
-        fMode = mode;
-        fProc = rec.fProc;
-        // these may be valid, or may be CANNOT_USE_COEFF
-        fSrcCoeff = rec.fSC;
-        fDstCoeff = rec.fDC;
-    }
-
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkProcCoeffXfermode(SkReadBuffer& buffer);
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
 
@@ -60,6 +58,8 @@
     Mode            fMode;
     Coeff           fSrcCoeff, fDstCoeff;
 
+    friend class SkXfermode;
+
     typedef SkXfermode INHERITED;
 };
 
diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp
index bdc612f..1a12153 100644
--- a/src/device/xps/SkXPSDevice.cpp
+++ b/src/device/xps/SkXPSDevice.cpp
@@ -30,6 +30,7 @@
 #include "SkIStream.h"
 #include "SkMaskFilter.h"
 #include "SkPaint.h"
+#include "SkPathOps.h"
 #include "SkPoint.h"
 #include "SkRasterizer.h"
 #include "SkSFNTHeader.h"
@@ -48,9 +49,9 @@
 //make it clear when converting a scalar that this is what is wanted.
 #define SkScalarToFLOAT(n) SkScalarToFloat(n)
 
-//Dummy representation of a GUID from create_id.
+//Dummy representation of a GUID from createId.
 #define L_GUID_ID L"XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX"
-//Length of GUID representation from create_id, including NULL terminator.
+//Length of GUID representation from createId, including NULL terminator.
 #define GUID_ID_LEN SK_ARRAY_COUNT(L_GUID_ID)
 
 /**
@@ -84,18 +85,16 @@
                       guid.Data4[7]);
 }
 
-/**
-   Creates a GUID based id and places it into buffer.
-   buffer should have space for at least GUID_ID_LEN wide characters.
-   The string will always be wchar null terminated.
-   XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0
-   The string may begin with a digit,
-   and so may not be suitable as a bare resource key.
- */
-static HRESULT create_id(wchar_t* buffer, size_t bufferSize,
-                         wchar_t sep = '-') {
+HRESULT SkXPSDevice::createId(wchar_t* buffer, size_t bufferSize, wchar_t sep) {
     GUID guid = {};
+#ifdef SK_XPS_USE_DETERMINISTIC_IDS
+    guid.Data1 = fNextId++;
+    // The following make this a valid Type4 UUID.
+    guid.Data3 = 0x4000;
+    guid.Data4[0] = 0x80;
+#else
     HRM(CoCreateGuid(&guid), "Could not create GUID for id.");
+#endif
 
     if (format_guid(guid, buffer, bufferSize, sep) == -1) {
         HRM(E_UNEXPECTED, "Could not format GUID into id.");
@@ -193,7 +192,7 @@
         swprintf_s(buffer, size, L"/Documents/1/Metadata/%u.png", pageNum);
     } else {
         wchar_t id[GUID_ID_LEN];
-        HR(create_id(id, GUID_ID_LEN));
+        HR(this->createId(id, GUID_ID_LEN));
         swprintf_s(buffer, size, L"/Metadata/%s.png", id);
     }
     HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri),
@@ -647,7 +646,7 @@
         SK_ARRAY_COUNT(L"/Documents/1/Resources/Images/" L_GUID_ID L".png");
     wchar_t buffer[size];
     wchar_t id[GUID_ID_LEN];
-    HR(create_id(id, GUID_ID_LEN));
+    HR(this->createId(id, GUID_ID_LEN));
     swprintf_s(buffer, size, L"/Documents/1/Resources/Images/%s.png", id);
 
     SkTScopedComPtr<IOpcPartUri> imagePartUri;
@@ -810,7 +809,7 @@
 
     SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse;
     HR(this->createXpsTransform(localMatrix, &xpsMatrixToUse));
-    if (NULL != xpsMatrixToUse.get()) {
+    if (xpsMatrixToUse.get()) {
         HRM((*xpsBrush)->SetTransformLocal(xpsMatrixToUse.get()),
             "Could not set transform for image brush.");
     } else {
@@ -839,7 +838,7 @@
                                              IXpsOMBrush** xpsBrush) {
     XPS_POINT startPoint;
     XPS_POINT endPoint;
-    if (NULL != xpsMatrix) {
+    if (xpsMatrix) {
         startPoint = xps_point(info.fPoint[0]);
         endPoint = xps_point(info.fPoint[1]);
     } else {
@@ -867,7 +866,7 @@
                                                      &endPoint,
                                                      &gradientBrush),
         "Could not create linear gradient brush.");
-    if (NULL != xpsMatrix) {
+    if (xpsMatrix) {
         HRM(gradientBrush->SetTransformLocal(xpsMatrix),
             "Could not set transform on linear gradient brush.");
     }
@@ -913,7 +912,7 @@
     XPS_POINT centerPoint;
     XPS_POINT gradientOrigin;
     XPS_SIZE radiiSizes;
-    if (NULL != xpsMatrix) {
+    if (xpsMatrix) {
         centerPoint = xps_point(info.fPoint[0]);
         gradientOrigin = xps_point(info.fPoint[0]);
         radiiSizes.width = SkScalarToFLOAT(info.fRadius[0]);
@@ -944,7 +943,7 @@
                                                      &radiiSizes,
                                                      &gradientBrush),
         "Could not create radial gradient brush.");
-    if (NULL != xpsMatrix) {
+    if (xpsMatrix) {
         HRM(gradientBrush->SetTransformLocal(xpsMatrix),
             "Could not set transform on radial gradient brush.");
     }
@@ -1020,7 +1019,7 @@
         }
 
         SkMatrix localMatrix = shader->getLocalMatrix();
-        if (NULL != parentTransform) {
+        if (parentTransform) {
             localMatrix.preConcat(*parentTransform);
         }
         SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse;
@@ -1066,7 +1065,7 @@
         case SkShader::kDefault_BitmapType: {
             //TODO: outMatrix??
             SkMatrix localMatrix = shader->getLocalMatrix();
-            if (NULL != parentTransform) {
+            if (parentTransform) {
                 localMatrix.preConcat(*parentTransform);
             }
 
@@ -1328,7 +1327,7 @@
     while ((verb = iter.next(points)) != SkPath::kDone_Verb) {
         switch (verb) {
             case SkPath::kMove_Verb: {
-                if (NULL != xpsFigure.get()) {
+                if (xpsFigure.get()) {
                     HR(close_figure(segmentTypes, segmentStrokes, segmentData,
                                     stroke, fill,
                                     xpsFigure.get() , xpsFigures));
@@ -1379,7 +1378,7 @@
                 break;
         }
     }
-    if (NULL != xpsFigure.get()) {
+    if (xpsFigure.get()) {
         HR(close_figure(segmentTypes, segmentStrokes, segmentData,
                         stroke, fill,
                         xpsFigure.get(), xpsFigures));
@@ -1387,162 +1386,6 @@
     return S_OK;
 }
 
-HRESULT SkXPSDevice::drawInverseWindingPath(const SkDraw& d,
-                                            const SkPath& devicePath,
-                                            IXpsOMPath* shadedPath) {
-    const SkRect universeRect = SkRect::MakeLTRB(0, 0,
-        this->fCurrentCanvasSize.fWidth, this->fCurrentCanvasSize.fHeight);
-
-    const XPS_RECT universeRectXps = {
-        0.0f, 0.0f,
-        SkScalarToFLOAT(this->fCurrentCanvasSize.fWidth),
-        SkScalarToFLOAT(this->fCurrentCanvasSize.fHeight),
-    };
-
-    //Get the geometry.
-    SkTScopedComPtr<IXpsOMGeometry> shadedGeometry;
-    HRM(shadedPath->GetGeometry(&shadedGeometry),
-        "Could not get shaded geometry for inverse path.");
-
-    //Get the figures from the geometry.
-    SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures;
-    HRM(shadedGeometry->GetFigures(&shadedFigures),
-        "Could not get shaded figures for inverse path.");
-
-    HRM(shadedGeometry->SetFillRule(XPS_FILL_RULE_NONZERO),
-        "Could not set shaded fill rule for inverse path.");
-
-    //Take everything drawn so far, and make a shared resource out of it.
-    //Replace everything drawn so far with
-    //inverse canvas
-    //  old canvas of everything so far
-    //  world shaded figure, clipped to current clip
-    //  top canvas of everything so far, clipped to path
-    //Note: this is not quite right when there is nothing solid in the
-    //canvas of everything so far, as the bit on top will allow
-    //the world paint to show through.
-
-    //Create new canvas.
-    SkTScopedComPtr<IXpsOMCanvas> newCanvas;
-    HRM(this->fXpsFactory->CreateCanvas(&newCanvas),
-        "Could not create inverse canvas.");
-
-    //Save the old canvas to a dictionary on the new canvas.
-    SkTScopedComPtr<IXpsOMDictionary> newDictionary;
-    HRM(this->fXpsFactory->CreateDictionary(&newDictionary),
-        "Could not create inverse dictionary.");
-    HRM(newCanvas->SetDictionaryLocal(newDictionary.get()),
-        "Could not set inverse dictionary.");
-
-    const size_t size = SK_ARRAY_COUNT(L"ID" L_GUID_ID);
-    wchar_t buffer[size];
-    wchar_t id[GUID_ID_LEN];
-    HR(create_id(id, GUID_ID_LEN, '_'));
-    swprintf_s(buffer, size, L"ID%s", id);
-    HRM(newDictionary->Append(buffer, this->fCurrentXpsCanvas.get()),
-        "Could not add canvas to inverse dictionary.");
-
-    //Start drawing
-    SkTScopedComPtr<IXpsOMVisualCollection> newVisuals;
-    HRM(newCanvas->GetVisuals(&newVisuals),
-        "Could not get inverse canvas visuals.");
-
-    //Draw old canvas from dictionary onto new canvas.
-    SkTScopedComPtr<IXpsOMGeometry> oldGeometry;
-    HRM(this->fXpsFactory->CreateGeometry(&oldGeometry),
-        "Could not create old inverse geometry.");
-
-    SkTScopedComPtr<IXpsOMGeometryFigureCollection> oldFigures;
-    HRM(oldGeometry->GetFigures(&oldFigures),
-        "Could not get old inverse figures.");
-
-    SkTScopedComPtr<IXpsOMGeometryFigure> oldFigure;
-    HR(this->createXpsRect(universeRect, FALSE, TRUE, &oldFigure));
-    HRM(oldFigures->Append(oldFigure.get()),
-        "Could not add old inverse figure.");
-
-    SkTScopedComPtr<IXpsOMVisualBrush> oldBrush;
-    HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps,
-                                             &universeRectXps,
-                                             &oldBrush),
-        "Could not create old inverse brush.");
-
-    SkTScopedComPtr<IXpsOMPath> oldPath;
-    HRM(this->fXpsFactory->CreatePath(&oldPath),
-        "Could not create old inverse path.");
-    HRM(oldPath->SetGeometryLocal(oldGeometry.get()),
-        "Could not set old inverse geometry.");
-    HRM(oldPath->SetFillBrushLocal(oldBrush.get()),
-        "Could not set old inverse fill brush.");
-    //the brush must be parented before setting the lookup.
-    HRM(newVisuals->Append(oldPath.get()),
-        "Could not add old inverse path to new canvas visuals.");
-    HRM(oldBrush->SetVisualLookup(buffer),
-        "Could not set old inverse brush visual lookup.");
-
-    //Draw the clip filling shader.
-    SkTScopedComPtr<IXpsOMGeometryFigure> shadedFigure;
-    HR(this->createXpsRect(universeRect, FALSE, TRUE, &shadedFigure));
-    HRM(shadedFigures->Append(shadedFigure.get()),
-        "Could not add inverse shaded figure.");
-    //the geometry is already set
-    HR(this->clip(shadedPath, d));
-    HRM(newVisuals->Append(shadedPath),
-        "Could not add inverse shaded path to canvas visuals.");
-
-    //Draw the old canvas on top, clipped to the original path.
-    SkTScopedComPtr<IXpsOMCanvas> topCanvas;
-    HRM(this->fXpsFactory->CreateCanvas(&topCanvas),
-        "Could not create top inverse canvas.");
-    //Clip the canvas to prevent alpha spill.
-    //This is the entire reason this canvas exists.
-    HR(this->clip(topCanvas.get(), d));
-
-    SkTScopedComPtr<IXpsOMGeometry> topGeometry;
-    HRM(this->fXpsFactory->CreateGeometry(&topGeometry),
-        "Could not create top inverse geometry.");
-
-    SkTScopedComPtr<IXpsOMGeometryFigureCollection> topFigures;
-    HRM(topGeometry->GetFigures(&topFigures),
-        "Could not get top inverse figures.");
-
-    SkTScopedComPtr<IXpsOMGeometryFigure> topFigure;
-    HR(this->createXpsRect(universeRect, FALSE, TRUE, &topFigure));
-    HRM(topFigures->Append(topFigure.get()),
-        "Could not add old inverse figure.");
-
-    SkTScopedComPtr<IXpsOMVisualBrush> topBrush;
-    HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps,
-                                             &universeRectXps,
-                                             &topBrush),
-        "Could not create top inverse brush.");
-
-    SkTScopedComPtr<IXpsOMPath> topPath;
-    HRM(this->fXpsFactory->CreatePath(&topPath),
-        "Could not create top inverse path.");
-    HRM(topPath->SetGeometryLocal(topGeometry.get()),
-        "Could not set top inverse geometry.");
-    HRM(topPath->SetFillBrushLocal(topBrush.get()),
-        "Could not set top inverse fill brush.");
-    //the brush must be parented before setting the lookup.
-    HRM(newVisuals->Append(topCanvas.get()),
-        "Could not add top canvas to inverse canvas visuals.");
-    SkTScopedComPtr<IXpsOMVisualCollection> topVisuals;
-    HRM(topCanvas->GetVisuals(&topVisuals),
-        "Could not get top inverse canvas visuals.");
-    HRM(topVisuals->Append(topPath.get()),
-        "Could not add top inverse path to top canvas visuals.");
-    HRM(topBrush->SetVisualLookup(buffer),
-        "Could not set top inverse brush visual lookup.");
-
-    HR(this->clipToPath(topPath.get(), devicePath, XPS_FILL_RULE_NONZERO));
-
-    //swap current canvas to new canvas
-    this->fCurrentXpsCanvas.swap(newCanvas);
-
-    return S_OK;
-}
-
 void SkXPSDevice::convertToPpm(const SkMaskFilter* filter,
                                SkMatrix* matrix,
                                SkVector* ppuScale,
@@ -1846,8 +1689,9 @@
     bool xpsTransformsPath = true;
 
     //Set the fill rule.
+    SkPath* xpsCompatiblePath = fillablePath;
     XPS_FILL_RULE xpsFillRule;
-    switch (platonicPath.getFillType()) {
+    switch (fillablePath->getFillType()) {
         case SkPath::kWinding_FillType:
             xpsFillRule = XPS_FILL_RULE_NONZERO;
             break;
@@ -1855,15 +1699,17 @@
             xpsFillRule = XPS_FILL_RULE_EVENODD;
             break;
         case SkPath::kInverseWinding_FillType: {
-            //[Fillable-path -> Device-path]
-            SkPath* devicePath = pathIsMutable ? fillablePath : &modifiedPath;
-            fillablePath->transform(matrix, devicePath);
-
-            HRV(this->drawInverseWindingPath(d,
-                                             *devicePath,
-                                             shadedPath.get()));
-            return;
+            //[Fillable-path (inverse winding) -> XPS-path (inverse even odd)]
+            if (!pathIsMutable) {
+                xpsCompatiblePath = &modifiedPath;
+                pathIsMutable = true;
+            }
+            if (!Simplify(*fillablePath, xpsCompatiblePath)) {
+                SkDEBUGF(("Could not simplify inverse winding path."));
+                return;
+            }
         }
+        // The xpsCompatiblePath is noW inverse even odd, so fall through.
         case SkPath::kInverseEvenOdd_FillType: {
             const SkRect universe = SkRect::MakeLTRB(
                 0, 0,
@@ -1896,11 +1742,11 @@
         }
     }
 
-    SkPath* devicePath = fillablePath;
+    SkPath* devicePath = xpsCompatiblePath;
     if (!xpsTransformsPath) {
         //[Fillable-path -> Device-path]
-        devicePath = pathIsMutable ? fillablePath : &modifiedPath;
-        fillablePath->transform(matrix, devicePath);
+        devicePath = pathIsMutable ? xpsCompatiblePath : &modifiedPath;
+        xpsCompatiblePath->transform(matrix, devicePath);
     }
     HRV(this->addXpsPathGeometry(shadedFigures.get(),
                                  stroke, fill, *devicePath));
@@ -1988,7 +1834,7 @@
     }
 
     SkTScopedComPtr<IXpsOMGeometryFigure> rectFigure;
-    if (NULL != xpsTransform.get()) {
+    if (xpsTransform.get()) {
         const SkShader::TileMode xy[2] = {
             SkShader::kClamp_TileMode,
             SkShader::kClamp_TileMode,
@@ -2058,7 +1904,7 @@
         SK_ARRAY_COUNT(L"/Resources/Fonts/" L_GUID_ID L".odttf");
     wchar_t buffer[size];
     wchar_t id[GUID_ID_LEN];
-    HR(create_id(id, GUID_ID_LEN));
+    HR(this->createId(id, GUID_ID_LEN));
     swprintf_s(buffer, size, L"/Resources/Fonts/%s.odttf", id);
 
     SkTScopedComPtr<IOpcPartUri> partUri;
@@ -2133,12 +1979,12 @@
     SkTScopedComPtr<IXpsOMGlyphsEditor> glyphsEditor;
     HRM(glyphs->GetGlyphsEditor(&glyphsEditor), "Could not get glyph editor.");
 
-    if (NULL != text) {
+    if (text) {
         HRM(glyphsEditor->SetUnicodeString(text),
             "Could not set unicode string.");
     }
 
-    if (NULL != xpsGlyphs) {
+    if (xpsGlyphs) {
         HRM(glyphsEditor->SetGlyphIndices(xpsGlyphsLen, xpsGlyphs),
             "Could not set glyphs.");
     }
diff --git a/src/effects/Sk1DPathEffect.cpp b/src/effects/Sk1DPathEffect.cpp
index 7354cda..47824fd 100644
--- a/src/effects/Sk1DPathEffect.cpp
+++ b/src/effects/Sk1DPathEffect.cpp
@@ -147,6 +147,7 @@
     }
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkPath1DPathEffect::SkPath1DPathEffect(SkReadBuffer& buffer) {
     fAdvance = buffer.readScalar();
     if (fAdvance > 0) {
@@ -160,13 +161,25 @@
         fStyle = kStyleCount;
     }
 }
+#endif
 
 SkScalar SkPath1DPathEffect::begin(SkScalar contourLength) const {
     return fInitialOffset;
 }
 
+SkFlattenable* SkPath1DPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkScalar advance = buffer.readScalar();
+    if (advance > 0) {
+        SkPath path;
+        buffer.readPath(&path);
+        SkScalar phase = buffer.readScalar();
+        Style style = (Style)buffer.readUInt();
+        return SkPath1DPathEffect::Create(path, advance, phase, style);
+    }
+    return NULL;
+}
+
 void SkPath1DPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fAdvance);
     if (fAdvance > 0) {
         buffer.writePath(fPath);
diff --git a/src/effects/Sk2DPathEffect.cpp b/src/effects/Sk2DPathEffect.cpp
index 252866c..cef2266 100644
--- a/src/effects/Sk2DPathEffect.cpp
+++ b/src/effects/Sk2DPathEffect.cpp
@@ -73,10 +73,12 @@
     buffer.writeMatrix(fMatrix);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 Sk2DPathEffect::Sk2DPathEffect(SkReadBuffer& buffer) {
     buffer.readMatrix(&fMatrix);
     fMatrixIsInvertible = fMatrix.invert(&fInverse);
 }
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -102,12 +104,21 @@
     }
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLine2DPathEffect::SkLine2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
     fWidth = buffer.readScalar();
 }
+#endif
+
+SkFlattenable* SkLine2DPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    SkScalar width = buffer.readScalar();
+    return SkLine2DPathEffect::Create(width, matrix);
+}
 
 void SkLine2DPathEffect::flatten(SkWriteBuffer &buffer) const {
-    this->INHERITED::flatten(buffer);
+    buffer.writeMatrix(this->getMatrix());
     buffer.writeScalar(fWidth);
 }
 
@@ -117,13 +128,22 @@
     : INHERITED(m), fPath(p) {
 }
 
-SkPath2DPathEffect::SkPath2DPathEffect(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkPath2DPathEffect::SkPath2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
     buffer.readPath(&fPath);
 }
+#endif
+
+SkFlattenable* SkPath2DPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    SkPath path;
+    buffer.readPath(&path);
+    return SkPath2DPathEffect::Create(matrix, path);
+}
 
 void SkPath2DPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
+    buffer.writeMatrix(this->getMatrix());
     buffer.writePath(fPath);
 }
 
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index 6fcd2b4..09cc618 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -13,19 +13,22 @@
 
 class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter {
 public:
-    SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold, SkScalar outerThreshold);
+    SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold,
+                               SkScalar outerThreshold, SkImageFilter* input);
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAlphaThresholdFilterImpl)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkAlphaThresholdFilterImpl(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
 #if SK_SUPPORT_GPU
-    virtual bool asNewEffect(GrEffectRef** effect, GrTexture* texture,
-                             const SkMatrix& matrix, const SkIRect& bounds) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+                                     const SkIRect& bounds) const SK_OVERRIDE;
 #endif
 
 private:
@@ -37,47 +40,48 @@
 
 SkImageFilter* SkAlphaThresholdFilter::Create(const SkRegion& region,
                                               SkScalar innerThreshold,
-                                              SkScalar outerThreshold) {
-    return SkNEW_ARGS(SkAlphaThresholdFilterImpl, (region, innerThreshold, outerThreshold));
+                                              SkScalar outerThreshold,
+                                              SkImageFilter* input) {
+    return SkNEW_ARGS(SkAlphaThresholdFilterImpl, (region, innerThreshold, outerThreshold, input));
 }
 
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
 #include "GrCoordTransform.h"
-#include "GrEffect.h"
-#include "gl/GrGLEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrProcessor.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
+#include "GrTBackendProcessorFactory.h"
 #include "GrTextureAccess.h"
 
 #include "SkGr.h"
 
 class GrGLAlphaThresholdEffect;
 
-class AlphaThresholdEffect : public GrEffect {
+class AlphaThresholdEffect : public GrFragmentProcessor {
 
 public:
-    static GrEffectRef* Create(GrTexture* texture,
-                               GrTexture* maskTexture,
-                               float innerThreshold,
-                               float outerThreshold) {
-        AutoEffectUnref effect(SkNEW_ARGS(AlphaThresholdEffect, (texture,
-                                                                 maskTexture,
-                                                                 innerThreshold,
-                                                                 outerThreshold)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* texture,
+                                       GrTexture* maskTexture,
+                                       float innerThreshold,
+                                       float outerThreshold) {
+        return SkNEW_ARGS(AlphaThresholdEffect, (texture,
+                                                 maskTexture,
+                                                 innerThreshold,
+                                                 outerThreshold));
     }
 
     virtual ~AlphaThresholdEffect() {};
 
     static const char* Name() { return "Alpha Threshold"; }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
     float innerThreshold() const { return fInnerThreshold; }
     float outerThreshold() const { return fOuterThreshold; }
 
-    typedef GrGLAlphaThresholdEffect GLEffect;
+    typedef GrGLAlphaThresholdEffect GLProcessor;
 
 private:
     AlphaThresholdEffect(GrTexture* texture,
@@ -86,9 +90,11 @@
                          float outerThreshold)
         : fInnerThreshold(innerThreshold)
         , fOuterThreshold(outerThreshold)
-        , fImageCoordTransform(kLocal_GrCoordSet, MakeDivByTextureWHMatrix(texture), texture)
+        , fImageCoordTransform(kLocal_GrCoordSet,
+                               GrCoordTransform::MakeDivByTextureWHMatrix(texture), texture)
         , fImageTextureAccess(texture)
-        , fMaskCoordTransform(kLocal_GrCoordSet, MakeDivByTextureWHMatrix(maskTexture), maskTexture)
+        , fMaskCoordTransform(kLocal_GrCoordSet,
+                              GrCoordTransform::MakeDivByTextureWHMatrix(maskTexture), maskTexture)
         , fMaskTextureAccess(maskTexture) {
         this->addCoordTransform(&fImageCoordTransform);
         this->addTextureAccess(&fImageTextureAccess);
@@ -96,9 +102,9 @@
         this->addTextureAccess(&fMaskTextureAccess);
     }
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     float fInnerThreshold;
     float fOuterThreshold;
@@ -107,68 +113,71 @@
     GrCoordTransform fMaskCoordTransform;
     GrTextureAccess  fMaskTextureAccess;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
-class GrGLAlphaThresholdEffect : public GrGLEffect {
+class GrGLAlphaThresholdEffect : public GrGLFragmentProcessor {
 public:
-    GrGLAlphaThresholdEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLAlphaThresholdEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
 
-    GrGLUniformManager::UniformHandle       fInnerThresholdVar;
-    GrGLUniformManager::UniformHandle       fOuterThresholdVar;
+    GrGLProgramDataManager::UniformHandle fInnerThresholdVar;
+    GrGLProgramDataManager::UniformHandle fOuterThresholdVar;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GrGLAlphaThresholdEffect::GrGLAlphaThresholdEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+GrGLAlphaThresholdEffect::GrGLAlphaThresholdEffect(const GrBackendProcessorFactory& factory,
+                                                   const GrProcessor&)
     : INHERITED(factory) {
 }
 
-void GrGLAlphaThresholdEffect::emitCode(GrGLShaderBuilder* builder,
-                                        const GrDrawEffect&,
-                                        EffectKey key,
+void GrGLAlphaThresholdEffect::emitCode(GrGLProgramBuilder* builder,
+                                        const GrFragmentProcessor&,
+                                        const GrProcessorKey& key,
                                         const char* outputColor,
                                         const char* inputColor,
                                         const TransformedCoordsArray& coords,
                                         const TextureSamplerArray& samplers) {
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
-    SkString maskCoords2D = builder->ensureFSCoords2D(coords, 1);
     fInnerThresholdVar = builder->addUniform(
-        GrGLShaderBuilder::kFragment_Visibility,
+        GrGLProgramBuilder::kFragment_Visibility,
         kFloat_GrSLType, "inner_threshold");
     fOuterThresholdVar = builder->addUniform(
-        GrGLShaderBuilder::kFragment_Visibility,
+        GrGLProgramBuilder::kFragment_Visibility,
         kFloat_GrSLType, "outer_threshold");
 
-    builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
-    builder->fsCodeAppendf("\t\tvec2 mask_coord = %s;\n", maskCoords2D.c_str());
-    builder->fsCodeAppend("\t\tvec4 input_color = ");
-    builder->fsAppendTextureLookup(samplers[0], "coord");
-    builder->fsCodeAppend(";\n");
-    builder->fsCodeAppend("\t\tvec4 mask_color = ");
-    builder->fsAppendTextureLookup(samplers[1], "mask_coord");
-    builder->fsCodeAppend(";\n");
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+    SkString maskCoords2D = fsBuilder->ensureFSCoords2D(coords, 1);
 
-    builder->fsCodeAppendf("\t\tfloat inner_thresh = %s;\n",
+    fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
+    fsBuilder->codeAppendf("\t\tvec2 mask_coord = %s;\n", maskCoords2D.c_str());
+    fsBuilder->codeAppend("\t\tvec4 input_color = ");
+    fsBuilder->appendTextureLookup(samplers[0], "coord");
+    fsBuilder->codeAppend(";\n");
+    fsBuilder->codeAppend("\t\tvec4 mask_color = ");
+    fsBuilder->appendTextureLookup(samplers[1], "mask_coord");
+    fsBuilder->codeAppend(";\n");
+
+    fsBuilder->codeAppendf("\t\tfloat inner_thresh = %s;\n",
                            builder->getUniformCStr(fInnerThresholdVar));
-    builder->fsCodeAppendf("\t\tfloat outer_thresh = %s;\n",
+    fsBuilder->codeAppendf("\t\tfloat outer_thresh = %s;\n",
                            builder->getUniformCStr(fOuterThresholdVar));
-    builder->fsCodeAppend("\t\tfloat mask = mask_color.a;\n");
+    fsBuilder->codeAppend("\t\tfloat mask = mask_color.a;\n");
 
-    builder->fsCodeAppend("vec4 color = input_color;\n");
-    builder->fsCodeAppend("\t\tif (mask < 0.5) {\n"
+    fsBuilder->codeAppend("vec4 color = input_color;\n");
+    fsBuilder->codeAppend("\t\tif (mask < 0.5) {\n"
                           "\t\t\tif (color.a > outer_thresh) {\n"
                           "\t\t\t\tfloat scale = outer_thresh / color.a;\n"
                           "\t\t\t\tcolor.rgb *= scale;\n"
@@ -180,28 +189,27 @@
                           "\t\t\tcolor.a = inner_thresh;\n"
                           "\t\t}\n");
 
-    builder->fsCodeAppendf("%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("%s = %s;\n", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr4("color")).c_str());
 }
 
-void GrGLAlphaThresholdEffect::setData(const GrGLUniformManager& uman,
-                                  const GrDrawEffect& drawEffect) {
-    const AlphaThresholdEffect& alpha_threshold =
-        drawEffect.castEffect<AlphaThresholdEffect>();
-    uman.set1f(fInnerThresholdVar, alpha_threshold.innerThreshold());
-    uman.set1f(fOuterThresholdVar, alpha_threshold.outerThreshold());
+void GrGLAlphaThresholdEffect::setData(const GrGLProgramDataManager& pdman,
+                                       const GrProcessor& proc) {
+    const AlphaThresholdEffect& alpha_threshold = proc.cast<AlphaThresholdEffect>();
+    pdman.set1f(fInnerThresholdVar, alpha_threshold.innerThreshold());
+    pdman.set1f(fOuterThresholdVar, alpha_threshold.outerThreshold());
 }
 
 /////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(AlphaThresholdEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(AlphaThresholdEffect);
 
-GrEffectRef* AlphaThresholdEffect::TestCreate(SkRandom* random,
-                                              GrContext* context,
-                                              const GrDrawTargetCaps&,
-                                              GrTexture** textures) {
-    GrTexture* bmpTex = textures[GrEffectUnitTest::kSkiaPMTextureIdx];
-    GrTexture* maskTex = textures[GrEffectUnitTest::kAlphaTextureIdx];
+GrFragmentProcessor* AlphaThresholdEffect::TestCreate(SkRandom* random,
+                                           GrContext* context,
+                                           const GrDrawTargetCaps&,
+                                           GrTexture** textures) {
+    GrTexture* bmpTex = textures[GrProcessorUnitTest::kSkiaPMTextureIdx];
+    GrTexture* maskTex = textures[GrProcessorUnitTest::kAlphaTextureIdx];
     float inner_thresh = random->nextUScalar1();
     float outer_thresh = random->nextUScalar1();
     return AlphaThresholdEffect::Create(bmpTex, maskTex, inner_thresh, outer_thresh);
@@ -209,12 +217,12 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-const GrBackendEffectFactory& AlphaThresholdEffect::getFactory() const {
-    return GrTBackendEffectFactory<AlphaThresholdEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& AlphaThresholdEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<AlphaThresholdEffect>::getInstance();
 }
 
-bool AlphaThresholdEffect::onIsEqual(const GrEffect& sBase) const {
-    const AlphaThresholdEffect& s = CastEffect<AlphaThresholdEffect>(sBase);
+bool AlphaThresholdEffect::onIsEqual(const GrProcessor& sBase) const {
+    const AlphaThresholdEffect& s = sBase.cast<AlphaThresholdEffect>();
     return (this->texture(0) == s.texture(0) &&
             this->fInnerThreshold == s.fInnerThreshold &&
             this->fOuterThreshold == s.fOuterThreshold);
@@ -231,26 +239,40 @@
 
 #endif
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fInnerThreshold = buffer.readScalar();
     fOuterThreshold = buffer.readScalar();
     buffer.readRegion(&fRegion);
 }
+#endif
+
+SkFlattenable* SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkScalar inner = buffer.readScalar();
+    SkScalar outer = buffer.readScalar();
+    SkRegion rgn;
+    buffer.readRegion(&rgn);
+    return SkAlphaThresholdFilter::Create(rgn, inner, outer, common.getInput(0));
+}
 
 SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(const SkRegion& region,
                                                        SkScalar innerThreshold,
-                                                       SkScalar outerThreshold)
-    : INHERITED(0)
+                                                       SkScalar outerThreshold,
+                                                       SkImageFilter* input)
+    : INHERITED(1, &input)
     , fRegion(region)
     , fInnerThreshold(innerThreshold)
     , fOuterThreshold(outerThreshold) {
 }
 
 #if SK_SUPPORT_GPU
-bool SkAlphaThresholdFilterImpl::asNewEffect(GrEffectRef** effect, GrTexture* texture,
-                                             const SkMatrix& in_matrix, const SkIRect&) const {
-    if (effect) {
+bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp,
+                                                     GrTexture* texture,
+                                                     const SkMatrix& in_matrix,
+                                                     const SkIRect&) const {
+    if (fp) {
         GrContext* context = texture->getContext();
         GrTextureDesc maskDesc;
         if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
@@ -287,10 +309,10 @@
             context->setMatrix(old_matrix);
         }
 
-        *effect = AlphaThresholdEffect::Create(texture,
-                                               maskTexture,
-                                               fInnerThreshold,
-                                               fOuterThreshold);
+        *fp = AlphaThresholdEffect::Create(texture,
+                                           maskTexture,
+                                           fInnerThreshold,
+                                           fOuterThreshold);
     }
     return true;
 }
@@ -323,7 +345,7 @@
         return false;
     }
 
-    if (!dst->allocPixels(src.info())) {
+    if (!dst->tryAllocPixels(src.info())) {
         return false;
     }
 
diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp
index 41cc266..85af19c 100644
--- a/src/effects/SkArithmeticMode.cpp
+++ b/src/effects/SkArithmeticMode.cpp
@@ -14,8 +14,9 @@
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
 #include "GrCoordTransform.h"
-#include "gl/GrGLEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
+#include "GrTBackendProcessorFactory.h"
 #endif
 
 static const bool gUseUnpremul = false;
@@ -34,7 +35,8 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar)
 
 #if SK_SUPPORT_GPU
-    virtual bool asNewEffect(GrEffectRef** effect, GrTexture* background) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**,
+                                     GrTexture* background) const SK_OVERRIDE;
 #endif
 
 private:
@@ -46,6 +48,7 @@
         fEnforcePMColor = enforcePMColor;
     }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkArithmeticMode_scalar(SkReadBuffer& buffer) : INHERITED(buffer) {
         fK[0] = buffer.readScalar();
         fK[1] = buffer.readScalar();
@@ -53,9 +56,9 @@
         fK[3] = buffer.readScalar();
         fEnforcePMColor = buffer.readBool();
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        INHERITED::flatten(buffer);
         buffer.writeScalar(fK[0]);
         buffer.writeScalar(fK[1]);
         buffer.writeScalar(fK[2]);
@@ -65,9 +68,20 @@
     SkScalar fK[4];
     bool fEnforcePMColor;
 
+    friend class SkArithmeticMode;
+
     typedef SkXfermode INHERITED;
 };
 
+SkFlattenable* SkArithmeticMode_scalar::CreateProc(SkReadBuffer& buffer) {
+    const SkScalar k1 = buffer.readScalar();
+    const SkScalar k2 = buffer.readScalar();
+    const SkScalar k3 = buffer.readScalar();
+    const SkScalar k4 = buffer.readScalar();
+    const bool enforcePMColor = buffer.readBool();
+    return Create(k1, k2, k3, k4, enforcePMColor);
+}
+
 static int pinToByte(int value) {
     if (value < 0) {
         value = 0;
@@ -234,46 +248,44 @@
 
 #if SK_SUPPORT_GPU
 
-class GrGLArithmeticEffect : public GrGLEffect {
+class GrGLArithmeticEffect : public GrGLFragmentProcessor {
 public:
-    GrGLArithmeticEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLArithmeticEffect(const GrBackendProcessorFactory&, const GrProcessor&);
     virtual ~GrGLArithmeticEffect();
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
 
 private:
-    GrGLUniformManager::UniformHandle fKUni;
+    GrGLProgramDataManager::UniformHandle fKUni;
     bool fEnforcePMColor;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class GrArithmeticEffect : public GrEffect {
+class GrArithmeticEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create(float k1, float k2, float k3, float k4, bool enforcePMColor,
+    static GrFragmentProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor,
                                GrTexture* background) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor,
-                                                               background)));
-        return CreateEffectRef(effect);
+        return SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor, background));
     }
 
     virtual ~GrArithmeticEffect();
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
-    typedef GrGLArithmeticEffect GLEffect;
+    typedef GrGLArithmeticEffect GLProcessor;
     static const char* Name() { return "Arithmetic"; }
     GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture(); }
 
@@ -286,7 +298,7 @@
     bool enforcePMColor() const { return fEnforcePMColor; }
 
 private:
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     GrArithmeticEffect(float k1, float k2, float k3, float k4, bool enforcePMColor,
                        GrTexture* background);
@@ -295,8 +307,8 @@
     GrCoordTransform            fBackgroundTransform;
     GrTextureAccess             fBackgroundAccess;
 
-    GR_DECLARE_EFFECT_TEST;
-    typedef GrEffect INHERITED;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
+    typedef GrFragmentProcessor INHERITED;
 
 };
 
@@ -318,8 +330,8 @@
 GrArithmeticEffect::~GrArithmeticEffect() {
 }
 
-bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrArithmeticEffect& s = CastEffect<GrArithmeticEffect>(sBase);
+bool GrArithmeticEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrArithmeticEffect& s = sBase.cast<GrArithmeticEffect>();
     return fK1 == s.fK1 &&
            fK2 == s.fK2 &&
            fK3 == s.fK3 &&
@@ -328,8 +340,8 @@
            backgroundTexture() == s.backgroundTexture();
 }
 
-const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrArithmeticEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrArithmeticEffect>::getInstance();
 }
 
 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
@@ -339,8 +351,8 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendEffectFactory& factory,
-                                           const GrDrawEffect& drawEffect)
+GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendProcessorFactory& factory,
+                                           const GrProcessor&)
    : INHERITED(factory),
      fEnforcePMColor(true) {
 }
@@ -348,95 +360,96 @@
 GrGLArithmeticEffect::~GrGLArithmeticEffect() {
 }
 
-void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder,
-                                    const GrDrawEffect& drawEffect,
-                                    EffectKey key,
+void GrGLArithmeticEffect::emitCode(GrGLProgramBuilder* builder,
+                                    const GrFragmentProcessor& fp,
+                                    const GrProcessorKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray& coords,
                                     const TextureSamplerArray& samplers) {
 
-    GrTexture* backgroundTex = drawEffect.castEffect<GrArithmeticEffect>().backgroundTexture();
+    GrTexture* backgroundTex = fp.cast<GrArithmeticEffect>().backgroundTexture();
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
     const char* dstColor;
     if (backgroundTex) {
-        builder->fsCodeAppend("\t\tvec4 bgColor = ");
-        builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
-        builder->fsCodeAppendf(";\n");
+        fsBuilder->codeAppend("\t\tvec4 bgColor = ");
+        fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
+        fsBuilder->codeAppendf(";\n");
         dstColor = "bgColor";
     } else {
-        dstColor = builder->dstColor();
+        dstColor = fsBuilder->dstColor();
     }
 
-    SkASSERT(NULL != dstColor);
-    fKUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    SkASSERT(dstColor);
+    fKUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                 kVec4f_GrSLType, "k");
     const char* kUni = builder->getUniformCStr(fKUni);
 
     // We don't try to optimize for this case at all
     if (NULL == inputColor) {
-        builder->fsCodeAppendf("\t\tconst vec4 src = vec4(1);\n");
+        fsBuilder->codeAppendf("\t\tconst vec4 src = vec4(1);\n");
     } else {
-        builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor);
+        fsBuilder->codeAppendf("\t\tvec4 src = %s;\n", inputColor);
         if (gUseUnpremul) {
-            builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\n");
+            fsBuilder->codeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\n");
         }
     }
 
-    builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor);
+    fsBuilder->codeAppendf("\t\tvec4 dst = %s;\n", dstColor);
     if (gUseUnpremul) {
-        builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n");
+        fsBuilder->codeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n");
     }
 
-    builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni);
-    builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
+    fsBuilder->codeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni);
+    fsBuilder->codeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
     if (gUseUnpremul) {
-        builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
+        fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
     } else if (fEnforcePMColor) {
-        builder->fsCodeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor);
+        fsBuilder->codeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor);
     }
 }
 
-void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
-    const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>();
-    uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
+void GrGLArithmeticEffect::setData(const GrGLProgramDataManager& pdman,
+                                   const GrProcessor& processor) {
+    const GrArithmeticEffect& arith = processor.cast<GrArithmeticEffect>();
+    pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
     fEnforcePMColor = arith.enforcePMColor();
 }
 
-GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                   const GrGLCaps&) {
-    const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>();
-    EffectKey key = arith.enforcePMColor() ? 1 : 0;
+void GrGLArithmeticEffect::GenKey(const GrProcessor& processor,
+                                  const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    const GrArithmeticEffect& arith = processor.cast<GrArithmeticEffect>();
+    uint32_t key = arith.enforcePMColor() ? 1 : 0;
     if (arith.backgroundTexture()) {
         key |= 2;
     }
-    return key;
+    b->add32(key);
 }
 
-GrEffectRef* GrArithmeticEffect::TestCreate(SkRandom* rand,
-                                            GrContext*,
-                                            const GrDrawTargetCaps&,
-                                            GrTexture*[]) {
+GrFragmentProcessor* GrArithmeticEffect::TestCreate(SkRandom* rand,
+                                                    GrContext*,
+                                                    const GrDrawTargetCaps&,
+                                                    GrTexture*[]) {
     float k1 = rand->nextF();
     float k2 = rand->nextF();
     float k3 = rand->nextF();
     float k4 = rand->nextF();
     bool enforcePMColor = rand->nextBool();
 
-    AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect,
-                                       (k1, k2, k3, k4, enforcePMColor, NULL)));
-    return CreateEffectRef(gEffect);
+    return SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor, NULL));
 }
 
-GR_DEFINE_EFFECT_TEST(GrArithmeticEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrArithmeticEffect);
 
-bool SkArithmeticMode_scalar::asNewEffect(GrEffectRef** effect, GrTexture* background) const {
-    if (effect) {
-        *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]),
-                                             SkScalarToFloat(fK[1]),
-                                             SkScalarToFloat(fK[2]),
-                                             SkScalarToFloat(fK[3]),
-                                             fEnforcePMColor,
-                                             background);
+bool SkArithmeticMode_scalar::asFragmentProcessor(GrFragmentProcessor** fp,
+                                                  GrTexture* background) const {
+    if (fp) {
+        *fp = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]),
+                                         SkScalarToFloat(fK[1]),
+                                         SkScalarToFloat(fK[2]),
+                                         SkScalarToFloat(fK[3]),
+                                         fEnforcePMColor,
+                                         background);
     }
     return true;
 }
diff --git a/src/effects/SkAvoidXfermode.cpp b/src/effects/SkAvoidXfermode.cpp
index ffe6a21..b596bfd 100644
--- a/src/effects/SkAvoidXfermode.cpp
+++ b/src/effects/SkAvoidXfermode.cpp
@@ -15,24 +15,30 @@
     if (tolerance > 255) {
         tolerance = 255;
     }
-
+    fTolerance = SkToU8(tolerance);
     fOpColor = opColor;
     fDistMul = (256 << 14) / (tolerance + 1);
     fMode = mode;
 }
 
-SkAvoidXfermode::SkAvoidXfermode(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkAvoidXfermode::SkAvoidXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     fOpColor = buffer.readColor();
     fDistMul = buffer.readUInt();
     fMode = (Mode)buffer.readUInt();
 }
+#endif
+
+SkFlattenable* SkAvoidXfermode::CreateProc(SkReadBuffer& buffer) {
+    const SkColor color = buffer.readColor();
+    const unsigned tolerance = buffer.readUInt();
+    const unsigned mode = buffer.readUInt();
+    return Create(color, tolerance, (Mode)mode);
+}
 
 void SkAvoidXfermode::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
     buffer.writeColor(fOpColor);
-    buffer.writeUInt(fDistMul);
+    buffer.writeUInt(fTolerance);
     buffer.writeUInt(fMode);
 }
 
@@ -102,7 +108,7 @@
         SkASSERT(d <= 256);
 
         if (d > 0) {
-            if (NULL != aa) {
+            if (aa) {
                 d = SkAlphaMul(d, Accurate255To256(*aa++));
                 if (0 == d) {
                     continue;
@@ -151,7 +157,7 @@
         SkASSERT(d <= 32);
 
         if (d > 0) {
-            if (NULL != aa) {
+            if (aa) {
                 d = SkAlphaMul(d, Accurate255To256(*aa++));
                 if (0 == d) {
                     continue;
diff --git a/src/effects/SkBicubicImageFilter.cpp b/src/effects/SkBicubicImageFilter.cpp
deleted file mode 100644
index ea2d13e..0000000
--- a/src/effects/SkBicubicImageFilter.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkBicubicImageFilter.h"
-#include "SkBitmap.h"
-#include "SkColorPriv.h"
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
-#include "SkMatrix.h"
-#include "SkRect.h"
-#include "SkUnPreMultiply.h"
-
-#if SK_SUPPORT_GPU
-#include "effects/GrBicubicEffect.h"
-#include "GrContext.h"
-#include "GrTexture.h"
-#endif
-
-#define DS(x) SkDoubleToScalar(x)
-
-static const SkScalar gMitchellCoefficients[16] = {
-    DS( 1.0 / 18.0), DS(-9.0 / 18.0), DS( 15.0 / 18.0), DS( -7.0 / 18.0),
-    DS(16.0 / 18.0), DS( 0.0 / 18.0), DS(-36.0 / 18.0), DS( 21.0 / 18.0),
-    DS( 1.0 / 18.0), DS( 9.0 / 18.0), DS( 27.0 / 18.0), DS(-21.0 / 18.0),
-    DS( 0.0 / 18.0), DS( 0.0 / 18.0), DS( -6.0 / 18.0), DS(  7.0 / 18.0),
-};
-
-SkBicubicImageFilter::SkBicubicImageFilter(const SkSize& scale, const SkScalar coefficients[16], SkImageFilter* input)
-  : INHERITED(input),
-    fScale(scale) {
-    memcpy(fCoefficients, coefficients, sizeof(fCoefficients));
-}
-
-SkBicubicImageFilter* SkBicubicImageFilter::CreateMitchell(const SkSize& scale,
-                                                           SkImageFilter* input) {
-    return SkNEW_ARGS(SkBicubicImageFilter, (scale, gMitchellCoefficients, input));
-}
-
-SkBicubicImageFilter::SkBicubicImageFilter(SkReadBuffer& buffer)
-  : INHERITED(1, buffer) {
-    SkDEBUGCODE(bool success =) buffer.readScalarArray(fCoefficients, 16);
-    SkASSERT(success);
-    fScale.fWidth = buffer.readScalar();
-    fScale.fHeight = buffer.readScalar();
-    buffer.validate(SkScalarIsFinite(fScale.fWidth) &&
-                    SkScalarIsFinite(fScale.fHeight) &&
-                    (fScale.fWidth >= 0) &&
-                    (fScale.fHeight >= 0));
-}
-
-void SkBicubicImageFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-    buffer.writeScalarArray(fCoefficients, 16);
-    buffer.writeScalar(fScale.fWidth);
-    buffer.writeScalar(fScale.fHeight);
-}
-
-SkBicubicImageFilter::~SkBicubicImageFilter() {
-}
-
-inline SkPMColor cubicBlend(const SkScalar c[16], SkScalar t, SkPMColor c0, SkPMColor c1, SkPMColor c2, SkPMColor c3) {
-    SkScalar t2 = t * t, t3 = t2 * t;
-    SkScalar cc[4];
-    // FIXME:  For the fractx case, this should be refactored out of this function.
-    cc[0] = c[0]  + SkScalarMul(c[1], t) + SkScalarMul(c[2], t2) + SkScalarMul(c[3], t3);
-    cc[1] = c[4]  + SkScalarMul(c[5], t) + SkScalarMul(c[6], t2) + SkScalarMul(c[7], t3);
-    cc[2] = c[8]  + SkScalarMul(c[9], t) + SkScalarMul(c[10], t2) + SkScalarMul(c[11], t3);
-    cc[3] = c[12] + SkScalarMul(c[13], t) + SkScalarMul(c[14], t2) + SkScalarMul(c[15], t3);
-    SkScalar a = SkScalarClampMax(SkScalarMul(cc[0], SkGetPackedA32(c0)) + SkScalarMul(cc[1], SkGetPackedA32(c1)) + SkScalarMul(cc[2], SkGetPackedA32(c2)) + SkScalarMul(cc[3], SkGetPackedA32(c3)), 255);
-    SkScalar r = SkScalarMul(cc[0], SkGetPackedR32(c0)) + SkScalarMul(cc[1], SkGetPackedR32(c1)) + SkScalarMul(cc[2], SkGetPackedR32(c2)) + SkScalarMul(cc[3], SkGetPackedR32(c3));
-    SkScalar g = SkScalarMul(cc[0], SkGetPackedG32(c0)) + SkScalarMul(cc[1], SkGetPackedG32(c1)) + SkScalarMul(cc[2], SkGetPackedG32(c2)) + SkScalarMul(cc[3], SkGetPackedG32(c3));
-    SkScalar b = SkScalarMul(cc[0], SkGetPackedB32(c0)) + SkScalarMul(cc[1], SkGetPackedB32(c1)) + SkScalarMul(cc[2], SkGetPackedB32(c2)) + SkScalarMul(cc[3], SkGetPackedB32(c3));
-    return SkPackARGB32(SkScalarRoundToInt(a),
-                        SkScalarRoundToInt(SkScalarClampMax(r, a)),
-                        SkScalarRoundToInt(SkScalarClampMax(g, a)),
-                        SkScalarRoundToInt(SkScalarClampMax(b, a)));
-}
-
-bool SkBicubicImageFilter::onFilterImage(Proxy* proxy,
-                                         const SkBitmap& source,
-                                         const Context& ctx,
-                                         SkBitmap* result,
-                                         SkIPoint* offset) const {
-    SkBitmap src = source;
-    SkIPoint srcOffset = SkIPoint::Make(0, 0);
-    if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) {
-        return false;
-    }
-
-    if (src.colorType() != kN32_SkColorType) {
-        return false;
-    }
-
-    SkAutoLockPixels alp(src);
-    if (!src.getPixels()) {
-        return false;
-    }
-
-    SkRect dstRect = SkRect::MakeWH(SkScalarMul(SkIntToScalar(src.width()), fScale.fWidth),
-                                    SkScalarMul(SkIntToScalar(src.height()), fScale.fHeight));
-    SkIRect dstIRect;
-    dstRect.roundOut(&dstIRect);
-    if (dstIRect.isEmpty()) {
-        return false;
-    }
-    if (!result->allocPixels(src.info().makeWH(dstIRect.width(), dstIRect.height()))) {
-        return false;
-    }
-
-    SkRect srcRect;
-    src.getBounds(&srcRect);
-    srcRect.offset(SkPoint::Make(SkIntToScalar(srcOffset.fX), SkIntToScalar(srcOffset.fY)));
-    SkMatrix inverse;
-    inverse.setRectToRect(dstRect, srcRect, SkMatrix::kFill_ScaleToFit);
-    inverse.postTranslate(-0.5f, -0.5f);
-
-    for (int y = dstIRect.fTop; y < dstIRect.fBottom; ++y) {
-        SkPMColor* dptr = result->getAddr32(dstIRect.fLeft, y);
-        for (int x = dstIRect.fLeft; x < dstIRect.fRight; ++x) {
-            SkPoint srcPt, dstPt = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
-            inverse.mapPoints(&srcPt, &dstPt, 1);
-            SkScalar fractx = srcPt.fX - SkScalarFloorToScalar(srcPt.fX);
-            SkScalar fracty = srcPt.fY - SkScalarFloorToScalar(srcPt.fY);
-            int sx = SkScalarFloorToInt(srcPt.fX);
-            int sy = SkScalarFloorToInt(srcPt.fY);
-            int x0 = SkClampMax(sx - 1, src.width() - 1);
-            int x1 = SkClampMax(sx    , src.width() - 1);
-            int x2 = SkClampMax(sx + 1, src.width() - 1);
-            int x3 = SkClampMax(sx + 2, src.width() - 1);
-            int y0 = SkClampMax(sy - 1, src.height() - 1);
-            int y1 = SkClampMax(sy    , src.height() - 1);
-            int y2 = SkClampMax(sy + 1, src.height() - 1);
-            int y3 = SkClampMax(sy + 2, src.height() - 1);
-            SkPMColor s00 = *src.getAddr32(x0, y0);
-            SkPMColor s10 = *src.getAddr32(x1, y0);
-            SkPMColor s20 = *src.getAddr32(x2, y0);
-            SkPMColor s30 = *src.getAddr32(x3, y0);
-            SkPMColor s0 = cubicBlend(fCoefficients, fractx, s00, s10, s20, s30);
-            SkPMColor s01 = *src.getAddr32(x0, y1);
-            SkPMColor s11 = *src.getAddr32(x1, y1);
-            SkPMColor s21 = *src.getAddr32(x2, y1);
-            SkPMColor s31 = *src.getAddr32(x3, y1);
-            SkPMColor s1 = cubicBlend(fCoefficients, fractx, s01, s11, s21, s31);
-            SkPMColor s02 = *src.getAddr32(x0, y2);
-            SkPMColor s12 = *src.getAddr32(x1, y2);
-            SkPMColor s22 = *src.getAddr32(x2, y2);
-            SkPMColor s32 = *src.getAddr32(x3, y2);
-            SkPMColor s2 = cubicBlend(fCoefficients, fractx, s02, s12, s22, s32);
-            SkPMColor s03 = *src.getAddr32(x0, y3);
-            SkPMColor s13 = *src.getAddr32(x1, y3);
-            SkPMColor s23 = *src.getAddr32(x2, y3);
-            SkPMColor s33 = *src.getAddr32(x3, y3);
-            SkPMColor s3 = cubicBlend(fCoefficients, fractx, s03, s13, s23, s33);
-            *dptr++ = cubicBlend(fCoefficients, fracty, s0, s1, s2, s3);
-        }
-    }
-    offset->fX = dstIRect.fLeft;
-    offset->fY = dstIRect.fTop;
-    return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#if SK_SUPPORT_GPU
-
-bool SkBicubicImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
-                                          SkBitmap* result, SkIPoint* offset) const {
-    SkBitmap srcBM = src;
-    if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &srcBM, offset)) {
-        return false;
-    }
-    GrTexture* srcTexture = srcBM.getTexture();
-    GrContext* context = srcTexture->getContext();
-
-    SkRect dstRect = SkRect::MakeWH(srcBM.width() * fScale.fWidth,
-                                    srcBM.height() * fScale.fHeight);
-
-    GrTextureDesc desc;
-    desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
-    desc.fWidth = SkScalarCeilToInt(dstRect.width());
-    desc.fHeight = SkScalarCeilToInt(dstRect.height());
-    desc.fConfig = kSkia8888_GrPixelConfig;
-
-    GrAutoScratchTexture ast(context, desc);
-    SkAutoTUnref<GrTexture> dst(ast.detach());
-    if (!dst) {
-        return false;
-    }
-    GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
-    GrPaint paint;
-    paint.addColorEffect(GrBicubicEffect::Create(srcTexture, fCoefficients))->unref();
-    SkRect srcRect;
-    srcBM.getBounds(&srcRect);
-    context->drawRectToRect(paint, dstRect, srcRect);
-    WrapTexture(dst, desc.fWidth, desc.fHeight, result);
-    return true;
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
diff --git a/src/effects/SkBitmapSource.cpp b/src/effects/SkBitmapSource.cpp
index d8d4329..aee4a36 100644
--- a/src/effects/SkBitmapSource.cpp
+++ b/src/effects/SkBitmapSource.cpp
@@ -13,12 +13,12 @@
 #include "SkValidationUtils.h"
 
 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap)
-  : INHERITED(0, 0),
-    fBitmap(bitmap),
-    fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()),
-                            SkIntToScalar(bitmap.height()))),
-    fDstRect(fSrcRect) {
-}
+  : INHERITED(0, 0)
+  , fBitmap(bitmap)
+  , fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()),
+                            SkIntToScalar(bitmap.height())))
+  , fDstRect(fSrcRect)
+{}
 
 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect)
   : INHERITED(0, 0)
@@ -26,6 +26,7 @@
   , fSrcRect(srcRect)
   , fDstRect(dstRect) {}
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkBitmapSource::SkBitmapSource(SkReadBuffer& buffer) : INHERITED(0, buffer) {
     if (buffer.isVersionLT(SkReadBuffer::kNoMoreBitmapFlatten_Version)) {
         fBitmap.legacyUnflatten(buffer);
@@ -36,12 +37,23 @@
     buffer.readRect(&fDstRect);
     buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
 }
+#endif
+
+SkFlattenable* SkBitmapSource::CreateProc(SkReadBuffer& buffer) {
+    SkRect src, dst;
+    buffer.readRect(&src);
+    buffer.readRect(&dst);
+    SkBitmap bitmap;
+    if (!buffer.readBitmap(&bitmap)) {
+        return NULL;
+    }
+    return SkBitmapSource::Create(bitmap, src, dst);
+}
 
 void SkBitmapSource::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-    buffer.writeBitmap(fBitmap);
     buffer.writeRect(fSrcRect);
     buffer.writeRect(fDstRect);
+    buffer.writeBitmap(fBitmap);
 }
 
 bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx,
diff --git a/src/effects/SkBlurDrawLooper.cpp b/src/effects/SkBlurDrawLooper.cpp
index c3b843f..fc9e47b 100644
--- a/src/effects/SkBlurDrawLooper.cpp
+++ b/src/effects/SkBlurDrawLooper.cpp
@@ -62,6 +62,7 @@
     this->initEffects();
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkBlurDrawLooper::SkBlurDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {
 
     fSigma = buffer.readScalar();
@@ -72,13 +73,22 @@
 
     this->initEffects();
 }
+#endif
+
+SkFlattenable* SkBlurDrawLooper::CreateProc(SkReadBuffer& buffer) {
+    const SkColor color = buffer.readColor();
+    const SkScalar sigma = buffer.readScalar();
+    const SkScalar dx = buffer.readScalar();
+    const SkScalar dy = buffer.readScalar();
+    const uint32_t flags = buffer.read32();
+    return Create(color, sigma, dx, dy, flags);
+}
 
 void SkBlurDrawLooper::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
+    buffer.writeColor(fBlurColor);
     buffer.writeScalar(fSigma);
     buffer.writeScalar(fDx);
     buffer.writeScalar(fDy);
-    buffer.writeColor(fBlurColor);
     buffer.write32(fBlurFlags);
 }
 
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index 470dcac..4166d20 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -23,6 +23,15 @@
 // raster paths.
 #define MAX_SIGMA SkIntToScalar(532)
 
+static SkVector mapSigma(const SkSize& localSigma, const SkMatrix& ctm) {
+    SkVector sigma = SkVector::Make(localSigma.width(), localSigma.height());
+    ctm.mapVectors(&sigma, 1);
+    sigma.fX = SkMinScalar(SkScalarAbs(sigma.fX), MAX_SIGMA);
+    sigma.fY = SkMinScalar(SkScalarAbs(sigma.fY), MAX_SIGMA);
+    return sigma;
+}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkBlurImageFilter::SkBlurImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fSigma.fWidth = buffer.readScalar();
@@ -32,13 +41,21 @@
                     (fSigma.fWidth >= 0) &&
                     (fSigma.fHeight >= 0));
 }
+#endif
 
 SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX,
                                      SkScalar sigmaY,
                                      SkImageFilter* input,
-                                     const CropRect* cropRect)
-    : INHERITED(input, cropRect), fSigma(SkSize::Make(sigmaX, sigmaY)) {
-    SkASSERT(sigmaX >= 0 && sigmaY >= 0);
+                                     const CropRect* cropRect,
+                                     uint32_t uniqueID)
+    : INHERITED(1, &input, cropRect, uniqueID), fSigma(SkSize::Make(sigmaX, sigmaY)) {
+}
+
+SkFlattenable* SkBlurImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkScalar sigmaX = buffer.readScalar();
+    SkScalar sigmaY = buffer.readScalar();
+    return Create(sigmaX, sigmaY, common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 void SkBlurImageFilter::flatten(SkWriteBuffer& buffer) const {
@@ -163,15 +180,12 @@
         return false;
     }
 
-    if (!dst->allocPixels(src.info().makeWH(srcBounds.width(), srcBounds.height()))) {
+    if (!dst->tryAllocPixels(src.info().makeWH(srcBounds.width(), srcBounds.height()))) {
         return false;
     }
     dst->getBounds(&dstBounds);
 
-    SkVector sigma = SkVector::Make(fSigma.width(), fSigma.height());
-    ctx.ctm().mapVectors(&sigma, 1);
-    sigma.fX = SkMinScalar(sigma.fX, MAX_SIGMA);
-    sigma.fY = SkMinScalar(sigma.fY, MAX_SIGMA);
+    SkVector sigma = mapSigma(fSigma, ctx.ctm());
 
     int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
     int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
@@ -190,7 +204,7 @@
     }
 
     SkBitmap temp;
-    if (!temp.allocPixels(dst->info())) {
+    if (!temp.tryAllocPixels(dst->info())) {
         return false;
     }
 
@@ -244,13 +258,12 @@
 bool SkBlurImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
                                        SkIRect* dst) const {
     SkIRect bounds = src;
-    if (getInput(0) && !getInput(0)->filterBounds(src, ctm, &bounds)) {
-        return false;
-    }
-    SkVector sigma = SkVector::Make(fSigma.width(), fSigma.height());
-    ctm.mapVectors(&sigma, 1);
+    SkVector sigma = mapSigma(fSigma, ctm);
     bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
                   SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
+    if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
+        return false;
+    }
     *dst = bounds;
     return true;
 }
@@ -268,10 +281,7 @@
         return false;
     }
     GrTexture* source = input.getTexture();
-    SkVector sigma = SkVector::Make(fSigma.width(), fSigma.height());
-    ctx.ctm().mapVectors(&sigma, 1);
-    sigma.fX = SkMinScalar(sigma.fX, MAX_SIGMA);
-    sigma.fY = SkMinScalar(sigma.fY, MAX_SIGMA);
+    SkVector sigma = mapSigma(fSigma, ctx.ctm());
     offset->fX = rect.fLeft;
     offset->fY = rect.fTop;
     rect.offset(-srcOffset);
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index fca38a1..123b9d2 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -20,10 +20,11 @@
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
 #include "GrTexture.h"
-#include "GrEffect.h"
-#include "gl/GrGLEffect.h"
+#include "GrProcessor.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "effects/GrSimpleTextureEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 #include "SkGrPixelRef.h"
 #include "SkDraw.h"
 #endif
@@ -107,6 +108,8 @@
         return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA);
     }
 
+    friend class SkBlurMaskFilter;
+
     typedef SkMaskFilter INHERITED;
 };
 
@@ -521,19 +524,29 @@
              src.fRight + pad, src.fBottom + pad);
 }
 
-SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkReadBuffer& buffer)
-        : SkMaskFilter(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkReadBuffer& buffer) : SkMaskFilter(buffer) {
     fSigma = buffer.readScalar();
     fBlurStyle = (SkBlurStyle)buffer.readInt();
     fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag;
     SkASSERT(fSigma > 0);
     SkASSERT((unsigned)fBlurStyle <= kLastEnum_SkBlurStyle);
 }
+#endif
+
+SkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
+    const SkScalar sigma = buffer.readScalar();
+    const unsigned style = buffer.readUInt();
+    const unsigned flags = buffer.readUInt();
+    if (style <= kLastEnum_SkBlurStyle) {
+        return SkBlurMaskFilter::Create((SkBlurStyle)style, sigma, flags);
+    }
+    return NULL;
+}
 
 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fSigma);
-    buffer.writeInt(fBlurStyle);
+    buffer.writeUInt(fBlurStyle);
     buffer.writeUInt(fBlurFlags);
 }
 
@@ -541,22 +554,21 @@
 
 class GrGLRectBlurEffect;
 
-class GrRectBlurEffect : public GrEffect {
+class GrRectBlurEffect : public GrFragmentProcessor {
 public:
     virtual ~GrRectBlurEffect();
 
     static const char* Name() { return "RectBlur"; }
 
-    typedef GrGLRectBlurEffect GLEffect;
+    typedef GrGLRectBlurEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
     /**
      * Create a simple filter effect with custom bicubic coefficients.
      */
-    static GrEffectRef* Create(GrContext *context, const SkRect& rect,
-                               float sigma) {
+    static GrFragmentProcessor* Create(GrContext *context, const SkRect& rect, float sigma) {
         GrTexture *blurProfileTexture = NULL;
         int doubleProfileSize = SkScalarCeilToInt(12*sigma);
 
@@ -572,8 +584,7 @@
         if (!createdBlurProfileTexture) {
            return NULL;
         }
-        AutoEffectUnref effect(SkNEW_ARGS(GrRectBlurEffect, (rect, sigma, blurProfileTexture)));
-        return CreateEffectRef(effect);
+        return SkNEW_ARGS(GrRectBlurEffect, (rect, sigma, blurProfileTexture));
     }
 
     const SkRect& getRect() const { return fRect; }
@@ -581,7 +592,7 @@
 
 private:
     GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile);
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     static bool CreateBlurProfileTexture(GrContext *context, float sigma,
                                        GrTexture **blurProfileTexture);
@@ -590,59 +601,59 @@
     float           fSigma;
     GrTextureAccess fBlurProfileAccess;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
-class GrGLRectBlurEffect : public GrGLEffect {
+class GrGLRectBlurEffect : public GrGLFragmentProcessor {
 public:
-    GrGLRectBlurEffect(const GrBackendEffectFactory& factory,
-                      const GrDrawEffect&);
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    GrGLRectBlurEffect(const GrBackendProcessorFactory& factory,
+                       const GrProcessor&);
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
-    typedef GrGLUniformManager::UniformHandle        UniformHandle;
+    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 
     UniformHandle       fProxyRectUniform;
     UniformHandle       fProfileSizeUniform;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
 
 
-GrGLRectBlurEffect::GrGLRectBlurEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+GrGLRectBlurEffect::GrGLRectBlurEffect(const GrBackendProcessorFactory& factory, const GrProcessor&)
     : INHERITED(factory) {
 }
 
-void OutputRectBlurProfileLookup(GrGLShaderBuilder* builder,
+void OutputRectBlurProfileLookup(GrGLFragmentShaderBuilder* fsBuilder,
                                  const GrGLShaderBuilder::TextureSampler& sampler,
                                  const char *output,
                                  const char *profileSize, const char *loc,
                                  const char *blurred_width,
                                  const char *sharp_width) {
-    builder->fsCodeAppendf("\tfloat %s;\n", output);
-    builder->fsCodeAppendf("\t\t{\n");
-    builder->fsCodeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/%s;\n",
+    fsBuilder->codeAppendf("\tfloat %s;\n", output);
+    fsBuilder->codeAppendf("\t\t{\n");
+    fsBuilder->codeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/%s;\n",
                            loc, blurred_width, sharp_width, profileSize);
-    builder->fsCodeAppendf("\t\t\t%s = ", output);
-    builder->fsAppendTextureLookup(sampler, "vec2(coord,0.5)");
-    builder->fsCodeAppend(".a;\n");
-    builder->fsCodeAppendf("\t\t}\n");
+    fsBuilder->codeAppendf("\t\t\t%s = ", output);
+    fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)");
+    fsBuilder->codeAppend(".a;\n");
+    fsBuilder->codeAppendf("\t\t}\n");
 }
 
-void GrGLRectBlurEffect::emitCode(GrGLShaderBuilder* builder,
-                                 const GrDrawEffect&,
-                                 EffectKey key,
+void GrGLRectBlurEffect::emitCode(GrGLProgramBuilder* builder,
+                                 const GrFragmentProcessor&,
+                                 const GrProcessorKey& key,
                                  const char* outputColor,
                                  const char* inputColor,
                                  const TransformedCoordsArray& coords,
@@ -651,45 +662,46 @@
     const char *rectName;
     const char *profileSizeName;
 
-    fProxyRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                             kVec4f_GrSLType,
                                             "proxyRect",
                                             &rectName);
-    fProfileSizeUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fProfileSizeUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                             kFloat_GrSLType,
                                             "profileSize",
                                             &profileSizeName);
 
-    const char *fragmentPos = builder->fragmentPosition();
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    const char *fragmentPos = fsBuilder->fragmentPosition();
 
     if (inputColor) {
-        builder->fsCodeAppendf("\tvec4 src=%s;\n", inputColor);
+        fsBuilder->codeAppendf("\tvec4 src=%s;\n", inputColor);
     } else {
-        builder->fsCodeAppendf("\tvec4 src=vec4(1)\n;");
+        fsBuilder->codeAppendf("\tvec4 src=vec4(1)\n;");
     }
 
-    builder->fsCodeAppendf("\tvec2 translatedPos = %s.xy - %s.xy;\n", fragmentPos, rectName );
-    builder->fsCodeAppendf("\tfloat width = %s.z - %s.x;\n", rectName, rectName);
-    builder->fsCodeAppendf("\tfloat height = %s.w - %s.y;\n", rectName, rectName);
+    fsBuilder->codeAppendf("\tvec2 translatedPos = %s.xy - %s.xy;\n", fragmentPos, rectName );
+    fsBuilder->codeAppendf("\tfloat width = %s.z - %s.x;\n", rectName, rectName);
+    fsBuilder->codeAppendf("\tfloat height = %s.w - %s.y;\n", rectName, rectName);
 
-    builder->fsCodeAppendf("\tvec2 smallDims = vec2(width - %s, height-%s);\n", profileSizeName, profileSizeName);
-    builder->fsCodeAppendf("\tfloat center = 2.0 * floor(%s/2.0 + .25) - 1.0;\n", profileSizeName);
-    builder->fsCodeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n");
+    fsBuilder->codeAppendf("\tvec2 smallDims = vec2(width - %s, height-%s);\n", profileSizeName, profileSizeName);
+    fsBuilder->codeAppendf("\tfloat center = 2.0 * floor(%s/2.0 + .25) - 1.0;\n", profileSizeName);
+    fsBuilder->codeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n");
 
-    OutputRectBlurProfileLookup(builder, samplers[0], "horiz_lookup", profileSizeName, "translatedPos.x", "width", "wh.x");
-    OutputRectBlurProfileLookup(builder, samplers[0], "vert_lookup", profileSizeName, "translatedPos.y", "height", "wh.y");
+    OutputRectBlurProfileLookup(fsBuilder, samplers[0], "horiz_lookup", profileSizeName, "translatedPos.x", "width", "wh.x");
+    OutputRectBlurProfileLookup(fsBuilder, samplers[0], "vert_lookup", profileSizeName, "translatedPos.y", "height", "wh.y");
 
-    builder->fsCodeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n");
-    builder->fsCodeAppendf("\t%s = src * vec4(final);\n", outputColor );
+    fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n");
+    fsBuilder->codeAppendf("\t%s = src * vec4(final);\n", outputColor );
 }
 
-void GrGLRectBlurEffect::setData(const GrGLUniformManager& uman,
-                                 const GrDrawEffect& drawEffect) {
-    const GrRectBlurEffect& rbe = drawEffect.castEffect<GrRectBlurEffect>();
+void GrGLRectBlurEffect::setData(const GrGLProgramDataManager& pdman,
+                                 const GrProcessor& proc) {
+    const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>();
     SkRect rect = rbe.getRect();
 
-    uman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-    uman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma()));
+    pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+    pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma()));
 }
 
 bool GrRectBlurEffect::CreateBlurProfileTexture(GrContext *context, float sigma,
@@ -744,12 +756,12 @@
 GrRectBlurEffect::~GrRectBlurEffect() {
 }
 
-const GrBackendEffectFactory& GrRectBlurEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrRectBlurEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrRectBlurEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrRectBlurEffect>::getInstance();
 }
 
-bool GrRectBlurEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrRectBlurEffect& s = CastEffect<GrRectBlurEffect>(sBase);
+bool GrRectBlurEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrRectBlurEffect& s = sBase.cast<GrRectBlurEffect>();
     return this->getSigma() == s.getSigma() && this->getRect() == s.getRect();
 }
 
@@ -758,12 +770,12 @@
     return;
 }
 
-GR_DEFINE_EFFECT_TEST(GrRectBlurEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
 
-GrEffectRef* GrRectBlurEffect::TestCreate(SkRandom* random,
-                                         GrContext* context,
-                                         const GrDrawTargetCaps&,
-                                         GrTexture**) {
+GrFragmentProcessor* GrRectBlurEffect::TestCreate(SkRandom* random,
+                                                  GrContext* context,
+                                                  const GrDrawTargetCaps&,
+                                                  GrTexture**) {
     float sigma = random->nextRangeF(3,8);
     float width = random->nextRangeF(200,300);
     float height = random->nextRangeF(200,300);
@@ -794,9 +806,8 @@
     int pad=SkScalarCeilToInt(6*xformedSigma)/2;
     rect.outset(SkIntToScalar(pad), SkIntToScalar(pad));
 
-    SkAutoTUnref<GrEffectRef> effect(GrRectBlurEffect::Create(
-            context, rect, xformedSigma));
-    if (!effect) {
+    SkAutoTUnref<GrFragmentProcessor> fp(GrRectBlurEffect::Create(context, rect, xformedSigma));
+    if (!fp) {
         return false;
     }
 
@@ -805,7 +816,7 @@
        return false;
     }
 
-    grp->addCoverageEffect(effect);
+    grp->addCoverageProcessor(fp);
 
     context->drawRect(*grp, rect);
     return true;
@@ -813,10 +824,10 @@
 
 class GrGLRRectBlurEffect;
 
-class GrRRectBlurEffect : public GrEffect {
+class GrRRectBlurEffect : public GrFragmentProcessor {
 public:
 
-    static GrEffectRef* Create(GrContext* context, float sigma, const SkRRect&);
+    static GrFragmentProcessor* Create(GrContext* context, float sigma, const SkRRect&);
 
     virtual ~GrRRectBlurEffect() {};
     static const char* Name() { return "GrRRectBlur"; }
@@ -824,28 +835,29 @@
     const SkRRect& getRRect() const { return fRRect; }
     float getSigma() const { return fSigma; }
 
-    typedef GrGLRRectBlurEffect GLEffect;
+    typedef GrGLRRectBlurEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
     GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
     SkRRect             fRRect;
     float               fSigma;
     GrTextureAccess     fNinePatchAccess;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 
-GrEffectRef* GrRRectBlurEffect::Create(GrContext* context, float sigma, const SkRRect& rrect) {
+GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma,
+                                               const SkRRect& rrect) {
     if (!rrect.isSimpleCircular()) {
         return NULL;
     }
@@ -914,16 +926,15 @@
         return NULL;
     }
 
-    return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrRRectBlurEffect,
-                                                      (sigma, rrect, blurNinePatchTexture))));
+    return SkNEW_ARGS(GrRRectBlurEffect, (sigma, rrect, blurNinePatchTexture));
 }
 
 void GrRRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
     *validFlags = 0;
 }
 
-const GrBackendEffectFactory& GrRRectBlurEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrRRectBlurEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrRRectBlurEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrRRectBlurEffect>::getInstance();
 }
 
 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture *ninePatchTexture)
@@ -934,19 +945,19 @@
     this->setWillReadFragmentPosition();
 }
 
-bool GrRRectBlurEffect::onIsEqual(const GrEffect& other) const {
-    const GrRRectBlurEffect& rrbe = CastEffect<GrRRectBlurEffect>(other);
+bool GrRRectBlurEffect::onIsEqual(const GrProcessor& other) const {
+    const GrRRectBlurEffect& rrbe = other.cast<GrRRectBlurEffect>();
     return fRRect.getSimpleRadii().fX == rrbe.fRRect.getSimpleRadii().fX && fSigma == rrbe.fSigma;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrRRectBlurEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect);
 
-GrEffectRef* GrRRectBlurEffect::TestCreate(SkRandom* random,
-                                     GrContext* context,
-                                     const GrDrawTargetCaps& caps,
-                                     GrTexture*[]) {
+GrFragmentProcessor* GrRRectBlurEffect::TestCreate(SkRandom* random,
+                                        GrContext* context,
+                                        const GrDrawTargetCaps& caps,
+                                        GrTexture*[]) {
     SkScalar w = random->nextRangeScalar(100.f, 1000.f);
     SkScalar h = random->nextRangeScalar(100.f, 1000.f);
     SkScalar r = random->nextRangeF(1.f, 9.f);
@@ -958,39 +969,39 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GrGLRRectBlurEffect : public GrGLEffect {
+class GrGLRRectBlurEffect : public GrGLFragmentProcessor {
 public:
-    GrGLRRectBlurEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLRRectBlurEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
-    GrGLUniformManager::UniformHandle   fProxyRectUniform;
-    GrGLUniformManager::UniformHandle   fCornerRadiusUniform;
-    GrGLUniformManager::UniformHandle   fBlurRadiusUniform;
-    typedef GrGLEffect INHERITED;
+    GrGLProgramDataManager::UniformHandle fProxyRectUniform;
+    GrGLProgramDataManager::UniformHandle fCornerRadiusUniform;
+    GrGLProgramDataManager::UniformHandle fBlurRadiusUniform;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GrGLRRectBlurEffect::GrGLRRectBlurEffect(const GrBackendEffectFactory& factory,
-                             const GrDrawEffect& drawEffect)
+GrGLRRectBlurEffect::GrGLRRectBlurEffect(const GrBackendProcessorFactory& factory,
+                                         const GrProcessor&)
     : INHERITED (factory) {
 }
 
-void GrGLRRectBlurEffect::emitCode(GrGLShaderBuilder* builder,
-                             const GrDrawEffect& drawEffect,
-                             EffectKey key,
-                             const char* outputColor,
-                             const char* inputColor,
-                             const TransformedCoordsArray&,
-                             const TextureSamplerArray& samplers) {
+void GrGLRRectBlurEffect::emitCode(GrGLProgramBuilder* builder,
+                                   const GrFragmentProcessor&,
+                                   const GrProcessorKey&,
+                                   const char* outputColor,
+                                   const char* inputColor,
+                                   const TransformedCoordsArray&,
+                                   const TextureSamplerArray& samplers) {
     const char *rectName;
     const char *cornerRadiusName;
     const char *blurRadiusName;
@@ -998,63 +1009,65 @@
     // The proxy rect has left, top, right, and bottom edges correspond to
     // components x, y, z, and w, respectively.
 
-    fProxyRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                             kVec4f_GrSLType,
                                             "proxyRect",
                                             &rectName);
-    fCornerRadiusUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fCornerRadiusUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                  kFloat_GrSLType,
                                                  "cornerRadius",
                                                  &cornerRadiusName);
-    fBlurRadiusUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fBlurRadiusUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                  kFloat_GrSLType,
                                                  "blurRadius",
                                                  &blurRadiusName);
-    const char* fragmentPos = builder->fragmentPosition();
+
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    const char* fragmentPos = fsBuilder->fragmentPosition();
 
     // warp the fragment position to the appropriate part of the 9patch blur texture
 
-    builder->fsCodeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectName, rectName);
-    builder->fsCodeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", fragmentPos, rectName);
-    builder->fsCodeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusName, blurRadiusName );
-    builder->fsCodeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n", rectName, rectName );
+    fsBuilder->codeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectName, rectName);
+    fsBuilder->codeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", fragmentPos, rectName);
+    fsBuilder->codeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusName, blurRadiusName );
+    fsBuilder->codeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n", rectName, rectName );
 
-    builder->fsCodeAppendf("\t\tif (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x+threshold)) {\n" );
-    builder->fsCodeAppendf("\t\t\ttranslatedFragPos.x = threshold;\n");
-    builder->fsCodeAppendf("\t\t} else if (translatedFragPos.x >= (middle.x + threshold)) {\n");
-    builder->fsCodeAppendf("\t\t\ttranslatedFragPos.x -= middle.x - 1.0;\n");
-    builder->fsCodeAppendf("\t\t}\n");
+    fsBuilder->codeAppendf("\t\tif (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x+threshold)) {\n" );
+    fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x = threshold;\n");
+    fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.x >= (middle.x + threshold)) {\n");
+    fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x -= middle.x - 1.0;\n");
+    fsBuilder->codeAppendf("\t\t}\n");
 
-    builder->fsCodeAppendf("\t\tif (translatedFragPos.y > threshold && translatedFragPos.y < (middle.y+threshold)) {\n" );
-    builder->fsCodeAppendf("\t\t\ttranslatedFragPos.y = threshold;\n");
-    builder->fsCodeAppendf("\t\t} else if (translatedFragPos.y >= (middle.y + threshold)) {\n");
-    builder->fsCodeAppendf("\t\t\ttranslatedFragPos.y -= middle.y - 1.0;\n");
-    builder->fsCodeAppendf("\t\t}\n");
+    fsBuilder->codeAppendf("\t\tif (translatedFragPos.y > threshold && translatedFragPos.y < (middle.y+threshold)) {\n" );
+    fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y = threshold;\n");
+    fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.y >= (middle.y + threshold)) {\n");
+    fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y -= middle.y - 1.0;\n");
+    fsBuilder->codeAppendf("\t\t}\n");
 
-    builder->fsCodeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n");
-    builder->fsCodeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n");
+    fsBuilder->codeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n");
+    fsBuilder->codeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n");
 
-    builder->fsCodeAppendf("\t%s = ", outputColor);
-    builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], "texCoord");
-    builder->fsCodeAppend(";\n");
+    fsBuilder->codeAppendf("\t%s = ", outputColor);
+    fsBuilder->appendTextureLookupAndModulate(inputColor, samplers[0], "texCoord");
+    fsBuilder->codeAppend(";\n");
 }
 
-void GrGLRRectBlurEffect::setData(const GrGLUniformManager& uman,
-                                    const GrDrawEffect& drawEffect) {
-    const GrRRectBlurEffect& brre = drawEffect.castEffect<GrRRectBlurEffect>();
+void GrGLRRectBlurEffect::setData(const GrGLProgramDataManager& pdman,
+                                  const GrProcessor& proc) {
+    const GrRRectBlurEffect& brre = proc.cast<GrRRectBlurEffect>();
     SkRRect rrect = brre.getRRect();
 
     float blurRadius = 3.f*SkScalarCeilToScalar(brre.getSigma()-1/6.0f);
-    uman.set1f(fBlurRadiusUniform, blurRadius);
+    pdman.set1f(fBlurRadiusUniform, blurRadius);
 
     SkRect rect = rrect.getBounds();
     rect.outset(blurRadius, blurRadius);
-    uman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+    pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
 
     SkScalar radius = 0;
     SkASSERT(rrect.isSimpleCircular() || rrect.isRect());
     radius = rrect.getSimpleRadii().fX;
-    uman.set1f(fCornerRadiusUniform, radius);
+    pdman.set1f(fCornerRadiusUniform, radius);
 }
 
 
@@ -1076,9 +1089,8 @@
     float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
     proxy_rect.outset(extra, extra);
 
-    SkAutoTUnref<GrEffectRef> effect(GrRRectBlurEffect::Create(
-            context, xformedSigma, rrect));
-    if (!effect) {
+    SkAutoTUnref<GrFragmentProcessor> fp(GrRRectBlurEffect::Create(context, xformedSigma, rrect));
+    if (!fp) {
         return false;
     }
 
@@ -1087,7 +1099,7 @@
        return false;
     }
 
-    grp->addCoverageEffect(effect);
+    grp->addCoverageProcessor(fp);
 
     context->drawRect(*grp, proxy_rect);
     return true;
@@ -1160,7 +1172,7 @@
         matrix.setIDiv(src->width(), src->height());
         // Blend pathTexture over blurTexture.
         GrContext::AutoRenderTarget art(context, (*result)->asRenderTarget());
-        paint.addColorEffect(GrSimpleTextureEffect::Create(src, matrix))->unref();
+        paint.addColorProcessor(GrSimpleTextureEffect::Create(src, matrix))->unref();
         if (kInner_SkBlurStyle == fBlurStyle) {
             // inner:  dst = dst * src
             paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff);
diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp
index f2490e3..2a8df5c 100755
--- a/src/effects/SkColorFilterImageFilter.cpp
+++ b/src/effects/SkColorFilterImageFilter.cpp
@@ -58,39 +58,46 @@
 };
 
 SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf,
-        SkImageFilter* input, const CropRect* cropRect) {
+        SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
     SkASSERT(cf);
     SkScalar colorMatrix[20], inputMatrix[20];
     SkColorFilter* inputColorFilter;
     if (input && cf->asColorMatrix(colorMatrix)
               && input->asColorFilter(&inputColorFilter)
-              && (NULL != inputColorFilter)) {
+              && (inputColorFilter)) {
         SkAutoUnref autoUnref(inputColorFilter);
         if (inputColorFilter->asColorMatrix(inputMatrix) && !matrix_needs_clamping(inputMatrix)) {
             SkScalar combinedMatrix[20];
             mult_color_matrix(colorMatrix, inputMatrix, combinedMatrix);
             SkAutoTUnref<SkColorFilter> newCF(SkColorMatrixFilter::Create(combinedMatrix));
-            return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect));
+            return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect, 0));
         }
     }
-    return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect));
+    return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect, uniqueID));
 }
 
 SkColorFilterImageFilter::SkColorFilterImageFilter(SkColorFilter* cf,
-        SkImageFilter* input, const CropRect* cropRect)
-    : INHERITED(input, cropRect), fColorFilter(cf) {
+        SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+    : INHERITED(1, &input, cropRect, uniqueID), fColorFilter(cf) {
     SkASSERT(cf);
     SkSafeRef(cf);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkColorFilterImageFilter::SkColorFilterImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fColorFilter = buffer.readColorFilter();
 }
+#endif
+
+SkFlattenable* SkColorFilterImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkAutoTUnref<SkColorFilter> cf(buffer.readColorFilter());
+    return Create(cf, common.getInput(0), &common.cropRect(), common.uniqueID());
+}
 
 void SkColorFilterImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-
     buffer.writeFlattenable(fColorFilter);
 }
 
diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp
index 81d70a7..bd0d2aa 100644
--- a/src/effects/SkColorFilters.cpp
+++ b/src/effects/SkColorFilters.cpp
@@ -15,17 +15,9 @@
 #include "SkValidationUtils.h"
 #include "SkColorMatrixFilter.h"
 
-#define ILLEGAL_XFERMODE_MODE   ((SkXfermode::Mode)-1)
-
 // baseclass for filters that store a color and mode
 class SkModeColorFilter : public SkColorFilter {
 public:
-    SkModeColorFilter(SkColor color) {
-        fColor = color;
-        fMode = ILLEGAL_XFERMODE_MODE;
-        this->updateCache();
-    }
-
     SkModeColorFilter(SkColor color, SkXfermode::Mode mode) {
         fColor = color;
         fMode = mode;
@@ -34,14 +26,9 @@
 
     SkColor getColor() const { return fColor; }
     SkXfermode::Mode getMode() const { return fMode; }
-    bool isModeValid() const { return ILLEGAL_XFERMODE_MODE != fMode; }
     SkPMColor getPMColor() const { return fPMColor; }
 
     virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const SK_OVERRIDE {
-        if (ILLEGAL_XFERMODE_MODE == fMode) {
-            return false;
-        }
-
         if (color) {
             *color = fColor;
         }
@@ -87,17 +74,17 @@
 #endif
 
 #if SK_SUPPORT_GPU
-    virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE;
+    virtual GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
 #endif
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter)
 
 protected:
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        this->INHERITED::flatten(buffer);
         buffer.writeColor(fColor);
         buffer.writeUInt(fMode);
     }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkModeColorFilter(SkReadBuffer& buffer) {
         fColor = buffer.readColor();
         fMode = (SkXfermode::Mode)buffer.readUInt();
@@ -106,6 +93,7 @@
             buffer.validate(SkIsValidMode(fMode));
         }
     }
+#endif
 
 private:
     SkColor             fColor;
@@ -121,16 +109,25 @@
         fProc16 = SkXfermode::GetProc16(fMode, fColor);
     }
 
+    friend class SkColorFilter;
+
     typedef SkColorFilter INHERITED;
 };
 
+SkFlattenable* SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
+    SkColor color = buffer.readColor();
+    SkXfermode::Mode mode = (SkXfermode::Mode)buffer.readUInt();
+    return SkColorFilter::CreateModeFilter(color, mode);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 #if SK_SUPPORT_GPU
 #include "GrBlend.h"
-#include "GrEffect.h"
-#include "GrEffectUnitTest.h"
-#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLEffect.h"
+#include "GrProcessor.h"
+#include "GrProcessorUnitTest.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "SkGr.h"
 
 namespace {
@@ -185,9 +182,9 @@
 
 }
 
-class ModeColorFilterEffect : public GrEffect {
+class ModeColorFilterEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create(const GrColor& c, SkXfermode::Mode mode) {
+    static GrFragmentProcessor* Create(const GrColor& c, SkXfermode::Mode mode) {
         // TODO: Make the effect take the coeffs rather than mode since we already do the
         // conversion here.
         SkXfermode::Coeff srcCoeff, dstCoeff;
@@ -195,8 +192,7 @@
             SkDebugf("Failing to create color filter for mode %d\n", mode);
             return NULL;
         }
-        AutoEffectUnref effect(SkNEW_ARGS(ModeColorFilterEffect, (c, mode)));
-        return CreateEffectRef(effect);
+        return SkNEW_ARGS(ModeColorFilterEffect, (c, mode));
     }
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
@@ -211,8 +207,8 @@
         return true;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<ModeColorFilterEffect>::getInstance();
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<ModeColorFilterEffect>::getInstance();
     }
 
     static const char* Name() { return "ModeColorFilterEffect"; }
@@ -220,59 +216,62 @@
     SkXfermode::Mode mode() const { return fMode; }
     GrColor color() const { return fColor; }
 
-    class GLEffect : public GrGLEffect {
+    class GLProcessor : public GrGLFragmentProcessor {
     public:
-        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
             : INHERITED(factory) {
         }
 
-        virtual void emitCode(GrGLShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+        virtual void emitCode(GrGLProgramBuilder* builder,
+                              const GrFragmentProcessor& fp,
+                              const GrProcessorKey&,
                               const char* outputColor,
                               const char* inputColor,
-                              const TransformedCoordsArray& coords,
-                              const TextureSamplerArray& samplers) SK_OVERRIDE {
-            SkXfermode::Mode mode = drawEffect.castEffect<ModeColorFilterEffect>().mode();
+                              const TransformedCoordsArray&,
+                              const TextureSamplerArray&) SK_OVERRIDE {
+            SkXfermode::Mode mode = fp.cast<ModeColorFilterEffect>().mode();
 
             SkASSERT(SkXfermode::kDst_Mode != mode);
             const char* colorFilterColorUniName = NULL;
-            if (drawEffect.castEffect<ModeColorFilterEffect>().willUseFilterColor()) {
-                fFilterColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+            if (fp.cast<ModeColorFilterEffect>().willUseFilterColor()) {
+                fFilterColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                       kVec4f_GrSLType, "FilterColor",
                                                       &colorFilterColorUniName);
             }
 
             GrGLSLExpr4 filter =
-                color_filter_expression(mode, GrGLSLExpr4(colorFilterColorUniName), GrGLSLExpr4(inputColor));
+                color_filter_expression(mode, GrGLSLExpr4(colorFilterColorUniName),
+                                        GrGLSLExpr4(inputColor));
 
-            builder->fsCodeAppendf("\t%s = %s;\n", outputColor, filter.c_str());
+            builder->getFragmentShaderBuilder()->
+                    codeAppendf("\t%s = %s;\n", outputColor, filter.c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect<ModeColorFilterEffect>();
+        static void GenKey(const GrProcessor& fp, const GrGLCaps&,
+                           GrProcessorKeyBuilder* b) {
+            const ModeColorFilterEffect& colorModeFilter = fp.cast<ModeColorFilterEffect>();
             // The SL code does not depend on filter color at the moment, so no need to represent it
             // in the key.
-            EffectKey modeKey = colorModeFilter.mode();
-            return modeKey;
+            b->add32(colorModeFilter.mode());
         }
 
-        virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) SK_OVERRIDE {
+        virtual void setData(const GrGLProgramDataManager& pdman,
+                             const GrProcessor& fp) SK_OVERRIDE {
             if (fFilterColorUni.isValid()) {
-                const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect<ModeColorFilterEffect>();
+                const ModeColorFilterEffect& colorModeFilter = fp.cast<ModeColorFilterEffect>();
                 GrGLfloat c[4];
                 GrColorToRGBAFloat(colorModeFilter.color(), c);
-                uman.set4fv(fFilterColorUni, 1, c);
+                pdman.set4fv(fFilterColorUni, 1, c);
             }
         }
 
     private:
 
-        GrGLUniformManager::UniformHandle fFilterColorUni;
-        typedef GrGLEffect INHERITED;
+        GrGLProgramDataManager::UniformHandle fFilterColorUni;
+        typedef GrGLFragmentProcessor INHERITED;
     };
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
 private:
     ModeColorFilterEffect(GrColor color, SkXfermode::Mode mode)
@@ -283,20 +282,21 @@
         SkXfermode::Coeff srcCoeff;
         SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff));
         // These could be calculated from the blend equation with template trickery..
-        if (SkXfermode::kZero_Coeff == dstCoeff && !GrBlendCoeffRefsDst(sk_blend_to_grblend(srcCoeff))) {
+        if (SkXfermode::kZero_Coeff == dstCoeff &&
+                !GrBlendCoeffRefsDst(sk_blend_to_grblend(srcCoeff))) {
             this->setWillNotUseInputColor();
         }
     }
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
-        const ModeColorFilterEffect& s = CastEffect<ModeColorFilterEffect>(other);
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE {
+        const ModeColorFilterEffect& s = other.cast<ModeColorFilterEffect>();
         return fMode == s.fMode && fColor == s.fColor;
     }
 
     SkXfermode::Mode fMode;
     GrColor fColor;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 namespace {
@@ -396,11 +396,11 @@
     *validFlags = result.getValidComponents();
 }
 
-GR_DEFINE_EFFECT_TEST(ModeColorFilterEffect);
-GrEffectRef* ModeColorFilterEffect::TestCreate(SkRandom* rand,
-                                    GrContext*,
-                                    const GrDrawTargetCaps&,
-                                    GrTexture*[]) {
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ModeColorFilterEffect);
+GrFragmentProcessor* ModeColorFilterEffect::TestCreate(SkRandom* rand,
+                                                       GrContext*,
+                                                       const GrDrawTargetCaps&,
+                                                       GrTexture*[]) {
     SkXfermode::Mode mode = SkXfermode::kDst_Mode;
     while (SkXfermode::kDst_Mode == mode) {
         mode = static_cast<SkXfermode::Mode>(rand->nextRangeU(0, SkXfermode::kLastCoeffMode));
@@ -409,7 +409,7 @@
     return ModeColorFilterEffect::Create(color, mode);
 }
 
-GrEffectRef* SkModeColorFilter::asNewEffect(GrContext*) const {
+GrFragmentProcessor* SkModeColorFilter::asFragmentProcessor(GrContext*) const {
     if (SkXfermode::kDst_Mode != fMode) {
         return ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode);
     }
@@ -443,12 +443,6 @@
         sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count);
     }
 
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Src_SkModeColorFilter)
-
-protected:
-    Src_SkModeColorFilter(SkReadBuffer& buffer)
-        : INHERITED(buffer) {}
-
 private:
     typedef SkModeColorFilter INHERITED;
 };
@@ -479,14 +473,6 @@
         sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count);
     }
 
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SrcOver_SkModeColorFilter)
-
-protected:
-    SrcOver_SkModeColorFilter(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
-            fColor32Proc = SkBlitRow::ColorProcFactory();
-        }
-
 private:
 
     SkBlitRow::ColorProc fColor32Proc;
@@ -496,8 +482,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkColorFilter* SkColorFilter::CreateModeFilter(SkColor color,
-                                               SkXfermode::Mode mode) {
+SkColorFilter* SkColorFilter::CreateModeFilter(SkColor color, SkXfermode::Mode mode) {
+    if (!SkIsValidMode(mode)) {
+        return NULL;
+    }
+
     unsigned alpha = SkColorGetA(color);
 
     // first collaps some modes if possible
@@ -562,6 +551,4 @@
 
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter)
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index bd1df79..5ac4552 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -186,7 +186,7 @@
         analyze the array, so we don't miss the case where the caller has zeros
         which could make us accidentally take the General or Add case.
     */
-    if (NULL != fProc) {
+    if (fProc) {
         int32_t add = 1 << (fState.fShift - 1);
         array[4] += add;
         array[9] += add;
@@ -303,18 +303,26 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkColorMatrixFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     SkASSERT(sizeof(fMatrix.fMat)/sizeof(SkScalar) == 20);
     buffer.writeScalarArray(fMatrix.fMat, 20);
 }
 
-SkColorMatrixFilter::SkColorMatrixFilter(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkColorMatrixFilter::SkColorMatrixFilter(SkReadBuffer& buffer) : INHERITED(buffer) {
     SkASSERT(buffer.getArrayCount() == 20);
     if (buffer.readScalarArray(fMatrix.fMat, 20)) {
         this->initState(fMatrix.fMat);
     }
 }
+#endif
+
+SkFlattenable* SkColorMatrixFilter::CreateProc(SkReadBuffer& buffer) {
+    SkColorMatrix matrix;
+    if (buffer.readScalarArray(matrix.fMat, 20)) {
+        return Create(matrix);
+    }
+    return NULL;
+}
 
 bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) const {
     if (matrix) {
@@ -324,21 +332,21 @@
 }
 
 #if SK_SUPPORT_GPU
-#include "GrEffect.h"
-#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLEffect.h"
+#include "GrProcessor.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 
-class ColorMatrixEffect : public GrEffect {
+class ColorMatrixEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create(const SkColorMatrix& matrix) {
-        AutoEffectUnref effect(SkNEW_ARGS(ColorMatrixEffect, (matrix)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(const SkColorMatrix& matrix) {
+        return SkNEW_ARGS(ColorMatrixEffect, (matrix));
     }
 
     static const char* Name() { return "Color Matrix"; }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<ColorMatrixEffect>::getInstance();
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<ColorMatrixEffect>::getInstance();
     }
 
     virtual void getConstantColorComponents(GrColor* color,
@@ -386,29 +394,29 @@
         *color = static_cast<uint8_t>(SkScalarPin(outputA, 0, 255)) << GrColor_SHIFT_A;
     }
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
-    class GLEffect : public GrGLEffect {
+    class GLProcessor : public GrGLFragmentProcessor {
     public:
         // this class always generates the same code.
-        static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }
+        static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b) {}
 
-        GLEffect(const GrBackendEffectFactory& factory,
-                 const GrDrawEffect&)
+        GLProcessor(const GrBackendProcessorFactory& factory,
+                 const GrProcessor&)
         : INHERITED(factory) {
         }
 
-        virtual void emitCode(GrGLShaderBuilder* builder,
-                              const GrDrawEffect&,
-                              EffectKey,
+        virtual void emitCode(GrGLProgramBuilder* builder,
+                              const GrFragmentProcessor&,
+                              const GrProcessorKey&,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
                               const TextureSamplerArray&) SK_OVERRIDE {
-            fMatrixHandle = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+            fMatrixHandle = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                 kMat44f_GrSLType,
                                                 "ColorMatrix");
-            fVectorHandle = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+            fVectorHandle = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                 kVec4f_GrSLType,
                                                 "ColorMatrixVector");
 
@@ -416,21 +424,22 @@
                 // could optimize this case, but we aren't for now.
                 inputColor = "vec4(1)";
             }
+            GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
             // The max() is to guard against 0 / 0 during unpremul when the incoming color is
             // transparent black.
-            builder->fsCodeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n", inputColor);
-            builder->fsCodeAppendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha) + %s;\n",
+            fsBuilder->codeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n", inputColor);
+            fsBuilder->codeAppendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha) + %s;\n",
                                    outputColor,
                                    builder->getUniformCStr(fMatrixHandle),
                                    inputColor,
                                    builder->getUniformCStr(fVectorHandle));
-            builder->fsCodeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
-            builder->fsCodeAppendf("\t%s.rgb *= %s.a;\n", outputColor, outputColor);
+            fsBuilder->codeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
+            fsBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", outputColor, outputColor);
         }
 
-        virtual void setData(const GrGLUniformManager& uniManager,
-                             const GrDrawEffect& drawEffect) SK_OVERRIDE {
-            const ColorMatrixEffect& cme = drawEffect.castEffect<ColorMatrixEffect>();
+        virtual void setData(const GrGLProgramDataManager& uniManager,
+                             const GrProcessor& proc) SK_OVERRIDE {
+            const ColorMatrixEffect& cme = proc.cast<ColorMatrixEffect>();
             const float* m = cme.fMatrix.fMat;
             // The GL matrix is transposed from SkColorMatrix.
             GrGLfloat mt[]  = {
@@ -448,31 +457,31 @@
         }
 
     private:
-        GrGLUniformManager::UniformHandle fMatrixHandle;
-        GrGLUniformManager::UniformHandle fVectorHandle;
+        GrGLProgramDataManager::UniformHandle fMatrixHandle;
+        GrGLProgramDataManager::UniformHandle fVectorHandle;
 
-        typedef GrGLEffect INHERITED;
+        typedef GrGLFragmentProcessor INHERITED;
     };
 
 private:
     ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {}
 
-    virtual bool onIsEqual(const GrEffect& s) const {
-        const ColorMatrixEffect& cme = CastEffect<ColorMatrixEffect>(s);
+    virtual bool onIsEqual(const GrProcessor& s) const {
+        const ColorMatrixEffect& cme = s.cast<ColorMatrixEffect>();
         return cme.fMatrix == fMatrix;
     }
 
     SkColorMatrix fMatrix;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
-GR_DEFINE_EFFECT_TEST(ColorMatrixEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorMatrixEffect);
 
-GrEffectRef* ColorMatrixEffect::TestCreate(SkRandom* random,
-                                           GrContext*,
-                                           const GrDrawTargetCaps&,
-                                           GrTexture* dummyTextures[2]) {
+GrFragmentProcessor* ColorMatrixEffect::TestCreate(SkRandom* random,
+                                                   GrContext*,
+                                                   const GrDrawTargetCaps&,
+                                                   GrTexture* dummyTextures[2]) {
     SkColorMatrix colorMatrix;
     for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix.fMat); ++i) {
         colorMatrix.fMat[i] = random->nextSScalar1();
@@ -480,7 +489,7 @@
     return ColorMatrixEffect::Create(colorMatrix);
 }
 
-GrEffectRef* SkColorMatrixFilter::asNewEffect(GrContext*) const {
+GrFragmentProcessor* SkColorMatrixFilter::asFragmentProcessor(GrContext*) const {
     return ColorMatrixEffect::Create(fMatrix);
 }
 
diff --git a/src/effects/SkComposeImageFilter.cpp b/src/effects/SkComposeImageFilter.cpp
index 645d633..c055674 100644
--- a/src/effects/SkComposeImageFilter.cpp
+++ b/src/effects/SkComposeImageFilter.cpp
@@ -21,14 +21,6 @@
     SkImageFilter* outer = getInput(0);
     SkImageFilter* inner = getInput(1);
 
-    if (!outer && !inner) {
-        return false;
-    }
-
-    if (!outer || !inner) {
-        return (outer ? outer : inner)->filterImage(proxy, src, ctx, result, offset);
-    }
-
     SkBitmap tmp;
     return inner->filterImage(proxy, src, ctx, &tmp, offset) &&
            outer->filterImage(proxy, tmp, ctx, result, offset);
@@ -40,19 +32,17 @@
     SkImageFilter* outer = getInput(0);
     SkImageFilter* inner = getInput(1);
 
-    if (!outer && !inner) {
-        return false;
-    }
-
-    if (!outer || !inner) {
-        return (outer ? outer : inner)->filterBounds(src, ctm, dst);
-    }
-
     SkIRect tmp;
-    return inner->filterBounds(src, ctm, &tmp) &&
-           outer->filterBounds(tmp, ctm, dst);
+    return inner->filterBounds(src, ctm, &tmp) && outer->filterBounds(tmp, ctm, dst);
 }
 
+SkFlattenable* SkComposeImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
+    return SkComposeImageFilter::Create(common.getInput(0), common.getInput(1));
+}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkComposeImageFilter::SkComposeImageFilter(SkReadBuffer& buffer)
   : INHERITED(2, buffer) {
 }
+#endif
diff --git a/src/effects/SkCornerPathEffect.cpp b/src/effects/SkCornerPathEffect.cpp
index 5b61e06..0655882 100644
--- a/src/effects/SkCornerPathEffect.cpp
+++ b/src/effects/SkCornerPathEffect.cpp
@@ -128,11 +128,16 @@
     return true;
 }
 
+SkFlattenable* SkCornerPathEffect::CreateProc(SkReadBuffer& buffer) {
+    return SkCornerPathEffect::Create(buffer.readScalar());
+}
+
 void SkCornerPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fRadius);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkCornerPathEffect::SkCornerPathEffect(SkReadBuffer& buffer) {
     fRadius = buffer.readScalar();
 }
+#endif
diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp
index 2838b1f..412965e 100644
--- a/src/effects/SkDashPathEffect.cpp
+++ b/src/effects/SkDashPathEffect.cpp
@@ -11,8 +11,11 @@
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
 
-SkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count,
-                                   SkScalar phase) {
+SkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase)
+        : fPhase(0)
+        , fInitialDashLength(0)
+        , fInitialDashIndex(0)
+        , fIntervalLength(0) {
     SkASSERT(intervals);
     SkASSERT(count > 1 && SkAlign2(count) == count);
 
@@ -24,8 +27,8 @@
     }
 
     // set the internal data members
-    SkDashPath::CalcDashParameters(phase, fIntervals, fCount, &fInitialDashLength,
-                                   &fInitialDashIndex, &fIntervalLength, &fPhase);
+    SkDashPath::CalcDashParameters(phase, fIntervals, fCount,
+            &fInitialDashLength, &fInitialDashIndex, &fIntervalLength, &fPhase);
 }
 
 SkDashPathEffect::~SkDashPathEffect() {
@@ -38,6 +41,116 @@
                                       fInitialDashLength, fInitialDashIndex, fIntervalLength);
 }
 
+static void outset_for_stroke(SkRect* rect, const SkStrokeRec& rec) {
+    SkScalar radius = SkScalarHalf(rec.getWidth());
+    if (0 == radius) {
+        radius = SK_Scalar1;    // hairlines
+    }
+    if (SkPaint::kMiter_Join == rec.getJoin()) {
+        radius = SkScalarMul(radius, rec.getMiter());
+    }
+    rect->outset(radius, radius);
+}
+
+// Attempt to trim the line to minimally cover the cull rect (currently 
+// only works for horizontal and vertical lines).
+// Return true if processing should continue; false otherwise.
+static bool cull_line(SkPoint* pts, const SkStrokeRec& rec,
+                      const SkMatrix& ctm, const SkRect* cullRect,
+                      const SkScalar intervalLength) {
+    if (NULL == cullRect) {
+        SkASSERT(false); // Shouldn't ever occur in practice
+        return false;
+    }
+
+    SkScalar dx = pts[1].x() - pts[0].x();
+    SkScalar dy = pts[1].y() - pts[0].y();
+
+    if ((dx && dy) || (!dx && !dy)) {
+        return false;
+    }
+
+    SkRect bounds = *cullRect;
+    outset_for_stroke(&bounds, rec);
+
+    // cullRect is in device space while pts are in the local coordinate system
+    // defined by the ctm. We want our answer in the local coordinate system.
+
+    SkASSERT(ctm.rectStaysRect());
+    SkMatrix inv;
+    if (!ctm.invert(&inv)) {
+        return false;
+    }
+
+    inv.mapRect(&bounds);
+
+    if (dx) {
+        SkASSERT(dx && !dy);
+        SkScalar minX = pts[0].fX;
+        SkScalar maxX = pts[1].fX;
+
+        if (dx < 0) {
+            SkTSwap(minX, maxX);
+        }
+
+        SkASSERT(minX < maxX);
+        if (maxX < bounds.fLeft || minX > bounds.fRight) {
+            return false;
+        }
+
+        // Now we actually perform the chop, removing the excess to the left and
+        // right of the bounds (keeping our new line "in phase" with the dash,
+        // hence the (mod intervalLength).
+
+        if (minX < bounds.fLeft) {
+            minX = bounds.fLeft - SkScalarMod(bounds.fLeft - minX, intervalLength);
+        }
+        if (maxX > bounds.fRight) {
+            maxX = bounds.fRight + SkScalarMod(maxX - bounds.fRight, intervalLength);
+        }
+
+        SkASSERT(maxX > minX);
+        if (dx < 0) {
+            SkTSwap(minX, maxX);
+        }
+        pts[0].fX = minX;
+        pts[1].fX = maxX;
+    } else {
+        SkASSERT(dy && !dx);
+        SkScalar minY = pts[0].fY;
+        SkScalar maxY = pts[1].fY;
+
+        if (dy < 0) {
+            SkTSwap(minY, maxY);
+        }
+
+        SkASSERT(minY < maxY);
+        if (maxY < bounds.fTop || minY > bounds.fBottom) {
+            return false;
+        }
+
+        // Now we actually perform the chop, removing the excess to the top and
+        // bottom of the bounds (keeping our new line "in phase" with the dash,
+        // hence the (mod intervalLength).
+
+        if (minY < bounds.fTop) {
+            minY = bounds.fTop - SkScalarMod(bounds.fTop - minY, intervalLength);
+        }
+        if (maxY > bounds.fBottom) {
+            maxY = bounds.fBottom + SkScalarMod(maxY - bounds.fBottom, intervalLength);
+        }
+
+        SkASSERT(maxY > minY);
+        if (dy < 0) {
+            SkTSwap(minY, maxY);
+        }
+        pts[0].fY = minY;
+        pts[1].fY = maxY;
+    }
+
+    return true;
+}
+
 // Currently asPoints is more restrictive then it needs to be. In the future
 // we need to:
 //      allow kRound_Cap capping (could allow rotations in the matrix with this)
@@ -80,7 +193,12 @@
         return false;
     }
 
-    SkScalar        length = SkPoint::Distance(pts[1], pts[0]);
+    // See if the line can be limited to something plausible.
+    if (!cull_line(pts, rec, matrix, cullRect, fIntervalLength)) {
+        return false;
+    }
+
+    SkScalar length = SkPoint::Distance(pts[1], pts[0]);
 
     SkVector tangent = pts[1] - pts[0];
     if (tangent.isZero()) {
@@ -91,9 +209,11 @@
 
     // TODO: make this test for horizontal & vertical lines more robust
     bool isXAxis = true;
-    if (SK_Scalar1 == tangent.fX || -SK_Scalar1 == tangent.fX) {
+    if (SkScalarNearlyEqual(SK_Scalar1, tangent.fX) ||
+        SkScalarNearlyEqual(-SK_Scalar1, tangent.fX)) {
         results->fSize.set(SkScalarHalf(fIntervals[0]), SkScalarHalf(rec.getWidth()));
-    } else if (SK_Scalar1 == tangent.fY || -SK_Scalar1 == tangent.fY) {
+    } else if (SkScalarNearlyEqual(SK_Scalar1, tangent.fY) ||
+               SkScalarNearlyEqual(-SK_Scalar1, tangent.fY)) {
         results->fSize.set(SkScalarHalf(rec.getWidth()), SkScalarHalf(fIntervals[0]));
         isXAxis = false;
     } else if (SkPaint::kRound_Cap != rec.getCap()) {
@@ -101,7 +221,7 @@
         return false;
     }
 
-    if (NULL != results) {
+    if (results) {
         results->fFlags = 0;
         SkScalar clampedInitialDashLength = SkMinScalar(length, fInitialDashLength);
 
@@ -226,7 +346,7 @@
 
 SkPathEffect::DashType SkDashPathEffect::asADash(DashInfo* info) const {
     if (info) {
-        if (info->fCount >= fCount && NULL != info->fIntervals) {
+        if (info->fCount >= fCount && info->fIntervals) {
             memcpy(info->fIntervals, fIntervals, fCount * sizeof(SkScalar));
         }
         info->fCount = fCount;
@@ -235,21 +355,28 @@
     return kDash_DashType;
 }
 
-SkFlattenable::Factory SkDashPathEffect::getFactory() const {
-    return CreateProc;
-}
-
 void SkDashPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fPhase);
     buffer.writeScalarArray(fIntervals, fCount);
 }
 
 SkFlattenable* SkDashPathEffect::CreateProc(SkReadBuffer& buffer) {
-    return SkNEW_ARGS(SkDashPathEffect, (buffer));
+    const SkScalar phase = buffer.readScalar();
+    uint32_t count = buffer.getArrayCount();
+    SkAutoSTArray<32, SkScalar> intervals(count);
+    if (buffer.readScalarArray(intervals.get(), count)) {
+        return Create(intervals.get(), SkToInt(count), phase);
+    }
+    return NULL;
 }
 
-SkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer)
+        : INHERITED(buffer)
+        , fPhase(0)
+        , fInitialDashLength(0)
+        , fInitialDashIndex(0)
+        , fIntervalLength(0) {
     bool useOldPic = buffer.isVersionLT(SkReadBuffer::kDashWritesPhaseIntervals_Version);
     if (useOldPic) {
         fInitialDashIndex = buffer.readInt();
@@ -280,7 +407,9 @@
     } else {
         // set the internal data members, fPhase should have been between 0 and intervalLength
         // when written to buffer so no need to adjust it
-        SkDashPath::CalcDashParameters(fPhase, fIntervals, fCount, &fInitialDashLength,
-                                       &fInitialDashIndex, &fIntervalLength);
+        SkDashPath::CalcDashParameters(fPhase, fIntervals, fCount,
+                &fInitialDashLength, &fInitialDashIndex, &fIntervalLength);
     }
 }
+#endif
+
diff --git a/src/effects/SkDiscretePathEffect.cpp b/src/effects/SkDiscretePathEffect.cpp
index f6f9112..e8cc6a2 100644
--- a/src/effects/SkDiscretePathEffect.cpp
+++ b/src/effects/SkDiscretePathEffect.cpp
@@ -75,15 +75,24 @@
     return true;
 }
 
+SkFlattenable* SkDiscretePathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkScalar segLength = buffer.readScalar();
+    SkScalar perterb = buffer.readScalar();
+    uint32_t seed = buffer.readUInt();
+    return Create(segLength, perterb, seed);
+}
+
 void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fSegLength);
     buffer.writeScalar(fPerterb);
     buffer.writeUInt(fSeedAssist);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDiscretePathEffect::SkDiscretePathEffect(SkReadBuffer& buffer) {
     fSegLength = buffer.readScalar();
     fPerterb = buffer.readScalar();
     fSeedAssist = buffer.readUInt();
 }
+#endif
+
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index a5519d1..474d9a7 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -13,8 +13,9 @@
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
 #include "GrCoordTransform.h"
-#include "gl/GrGLEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
+#include "GrTBackendProcessorFactory.h"
 #endif
 
 namespace {
@@ -158,13 +159,29 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+SkDisplacementMapEffect* SkDisplacementMapEffect::Create(ChannelSelectorType xChannelSelector,
+                                                         ChannelSelectorType yChannelSelector,
+                                                         SkScalar scale,
+                                                         SkImageFilter* displacement,
+                                                         SkImageFilter* color,
+                                                         const CropRect* cropRect, uint32_t uniqueID) {
+    if (!channel_selector_type_is_valid(xChannelSelector) ||
+        !channel_selector_type_is_valid(yChannelSelector)) {
+        return NULL;
+    }
+
+    SkImageFilter* inputs[2] = { displacement, color };
+    return SkNEW_ARGS(SkDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale,
+                                                inputs, cropRect, uniqueID));
+}
+
 SkDisplacementMapEffect::SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
                                                  ChannelSelectorType yChannelSelector,
                                                  SkScalar scale,
-                                                 SkImageFilter* displacement,
-                                                 SkImageFilter* color,
-                                                 const CropRect* cropRect)
-  : INHERITED(displacement, color, cropRect)
+                                                 SkImageFilter* inputs[2],
+                                                 const CropRect* cropRect,
+                                                 uint32_t uniqueID)
+  : INHERITED(2, inputs, cropRect, uniqueID)
   , fXChannelSelector(xChannelSelector)
   , fYChannelSelector(yChannelSelector)
   , fScale(scale)
@@ -174,6 +191,7 @@
 SkDisplacementMapEffect::~SkDisplacementMapEffect() {
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDisplacementMapEffect::SkDisplacementMapEffect(SkReadBuffer& buffer)
   : INHERITED(2, buffer)
 {
@@ -184,6 +202,15 @@
                     channel_selector_type_is_valid(fYChannelSelector) &&
                     SkScalarIsFinite(fScale));
 }
+#endif
+
+SkFlattenable* SkDisplacementMapEffect::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
+    ChannelSelectorType xsel = (ChannelSelectorType)buffer.readInt();
+    ChannelSelectorType ysel = (ChannelSelectorType)buffer.readInt();
+    SkScalar scale = buffer.readScalar();
+    return Create(xsel, ysel, scale, common.getInput(0), common.getInput(1), &common.cropRect(), common.uniqueID());
+}
 
 void SkDisplacementMapEffect::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
@@ -227,7 +254,7 @@
         return false;
     }
 
-    if (!dst->allocPixels(color.info().makeWH(bounds.width(), bounds.height()))) {
+    if (!dst->tryAllocPixels(color.info().makeWH(bounds.width(), bounds.height()))) {
         return false;
     }
 
@@ -270,66 +297,64 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #if SK_SUPPORT_GPU
-class GrGLDisplacementMapEffect : public GrGLEffect {
+class GrGLDisplacementMapEffect : public GrGLFragmentProcessor {
 public:
-    GrGLDisplacementMapEffect(const GrBackendEffectFactory& factory,
-                              const GrDrawEffect& drawEffect);
+    GrGLDisplacementMapEffect(const GrBackendProcessorFactory&,
+                              const GrProcessor&);
     virtual ~GrGLDisplacementMapEffect();
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
     SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
     SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
-    GrGLUniformManager::UniformHandle fScaleUni;
+    GrGLProgramDataManager::UniformHandle fScaleUni;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class GrDisplacementMapEffect : public GrEffect {
+class GrDisplacementMapEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
-                               SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
-                               SkVector scale,
-                               GrTexture* displacement, const SkMatrix& offsetMatrix,
-                               GrTexture* color) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector,
-                                                                    yChannelSelector,
-                                                                    scale,
-                                                                    displacement,
-                                                                    offsetMatrix,
-                                                                    color)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(
+            SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
+            SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, SkVector scale,
+            GrTexture* displacement, const SkMatrix& offsetMatrix, GrTexture* color) {
+        return SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector,
+                                                    yChannelSelector,
+                                                    scale,
+                                                    displacement,
+                                                    offsetMatrix,
+                                                    color));
     }
 
     virtual ~GrDisplacementMapEffect();
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const
         { return fXChannelSelector; }
     SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const
         { return fYChannelSelector; }
     const SkVector& scale() const { return fScale; }
 
-    typedef GrGLDisplacementMapEffect GLEffect;
+    typedef GrGLDisplacementMapEffect GLProcessor;
     static const char* Name() { return "DisplacementMap"; }
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 private:
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
                             SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
@@ -337,7 +362,7 @@
                             GrTexture* displacement, const SkMatrix& offsetMatrix,
                             GrTexture* color);
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     GrCoordTransform            fDisplacementTransform;
     GrTextureAccess             fDisplacementAccess;
@@ -347,7 +372,7 @@
     SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
     SkVector fScale;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
@@ -390,6 +415,9 @@
     desc.fConfig = kSkia8888_GrPixelConfig;
 
     GrAutoScratchTexture ast(context, desc);
+    if (NULL == ast.texture()) {
+        return false;
+    }
     SkAutoTUnref<GrTexture> dst(ast.detach());
 
     GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
@@ -398,11 +426,11 @@
     ctx.ctm().mapVectors(&scale, 1);
 
     GrPaint paint;
-    SkMatrix offsetMatrix = GrEffect::MakeDivByTextureWHMatrix(displacement);
+    SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displacement);
     offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displacementOffset.fX),
                               SkIntToScalar(colorOffset.fY - displacementOffset.fY));
 
-    paint.addColorEffect(
+    paint.addColorProcessor(
         GrDisplacementMapEffect::Create(fXChannelSelector,
                                         fYChannelSelector,
                                         scale,
@@ -450,8 +478,8 @@
 GrDisplacementMapEffect::~GrDisplacementMapEffect() {
 }
 
-bool GrDisplacementMapEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrDisplacementMapEffect& s = CastEffect<GrDisplacementMapEffect>(sBase);
+bool GrDisplacementMapEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrDisplacementMapEffect& s = sBase.cast<GrDisplacementMapEffect>();
     return fDisplacementAccess.getTexture() == s.fDisplacementAccess.getTexture() &&
            fColorAccess.getTexture() == s.fColorAccess.getTexture() &&
            fXChannelSelector == s.fXChannelSelector &&
@@ -459,8 +487,8 @@
            fScale == s.fScale;
 }
 
-const GrBackendEffectFactory& GrDisplacementMapEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrDisplacementMapEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrDisplacementMapEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrDisplacementMapEffect>::getInstance();
 }
 
 void GrDisplacementMapEffect::getConstantColorComponents(GrColor*,
@@ -475,16 +503,16 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrDisplacementMapEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDisplacementMapEffect);
 
-GrEffectRef* GrDisplacementMapEffect::TestCreate(SkRandom* random,
-                                                 GrContext*,
-                                                 const GrDrawTargetCaps&,
-                                                 GrTexture* textures[]) {
-    int texIdxDispl = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                           GrEffectUnitTest::kAlphaTextureIdx;
-    int texIdxColor = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                           GrEffectUnitTest::kAlphaTextureIdx;
+GrFragmentProcessor* GrDisplacementMapEffect::TestCreate(SkRandom* random,
+                                              GrContext*,
+                                              const GrDrawTargetCaps&,
+                                              GrTexture* textures[]) {
+    int texIdxDispl = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                           GrProcessorUnitTest::kAlphaTextureIdx;
+    int texIdxColor = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                           GrProcessorUnitTest::kAlphaTextureIdx;
     static const int kMaxComponent = 4;
     SkDisplacementMapEffect::ChannelSelectorType xChannelSelector =
         static_cast<SkDisplacementMapEffect::ChannelSelectorType>(
@@ -502,26 +530,26 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrGLDisplacementMapEffect::GrGLDisplacementMapEffect(const GrBackendEffectFactory& factory,
-                                                     const GrDrawEffect& drawEffect)
+GrGLDisplacementMapEffect::GrGLDisplacementMapEffect(const GrBackendProcessorFactory& factory,
+                                                     const GrProcessor& proc)
     : INHERITED(factory)
-    , fXChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().xChannelSelector())
-    , fYChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().yChannelSelector()) {
+    , fXChannelSelector(proc.cast<GrDisplacementMapEffect>().xChannelSelector())
+    , fYChannelSelector(proc.cast<GrDisplacementMapEffect>().yChannelSelector()) {
 }
 
 GrGLDisplacementMapEffect::~GrGLDisplacementMapEffect() {
 }
 
-void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
-                                         const GrDrawEffect&,
-                                         EffectKey key,
+void GrGLDisplacementMapEffect::emitCode(GrGLProgramBuilder* builder,
+                                         const GrFragmentProcessor&,
+                                         const GrProcessorKey& key,
                                          const char* outputColor,
                                          const char* inputColor,
                                          const TransformedCoordsArray& coords,
                                          const TextureSamplerArray& samplers) {
     sk_ignore_unused_variable(inputColor);
 
-    fScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fScaleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                     kVec2f_GrSLType, "Scale");
     const char* scaleUni = builder->getUniformCStr(fScaleUni);
     const char* dColor = "dColor";
@@ -531,29 +559,30 @@
                                    // a number smaller than that to approximate 0, but
                                    // leave room for 32-bit float GPU rounding errors.
 
-    builder->fsCodeAppendf("\t\tvec4 %s = ", dColor);
-    builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
-    builder->fsCodeAppend(";\n");
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    fsBuilder->codeAppendf("\t\tvec4 %s = ", dColor);
+    fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
+    fsBuilder->codeAppend(";\n");
 
     // Unpremultiply the displacement
-    builder->fsCodeAppendf("\t\t%s.rgb = (%s.a < %s) ? vec3(0.0) : clamp(%s.rgb / %s.a, 0.0, 1.0);",
+    fsBuilder->codeAppendf("\t\t%s.rgb = (%s.a < %s) ? vec3(0.0) : clamp(%s.rgb / %s.a, 0.0, 1.0);",
                            dColor, dColor, nearZero, dColor, dColor);
 
-    builder->fsCodeAppendf("\t\tvec2 %s = %s + %s*(%s.",
+    fsBuilder->codeAppendf("\t\tvec2 %s = %s + %s*(%s.",
                            cCoords, coords[1].c_str(), scaleUni, dColor);
 
     switch (fXChannelSelector) {
       case SkDisplacementMapEffect::kR_ChannelSelectorType:
-        builder->fsCodeAppend("r");
+        fsBuilder->codeAppend("r");
         break;
       case SkDisplacementMapEffect::kG_ChannelSelectorType:
-        builder->fsCodeAppend("g");
+        fsBuilder->codeAppend("g");
         break;
       case SkDisplacementMapEffect::kB_ChannelSelectorType:
-        builder->fsCodeAppend("b");
+        fsBuilder->codeAppend("b");
         break;
       case SkDisplacementMapEffect::kA_ChannelSelectorType:
-        builder->fsCodeAppend("a");
+        fsBuilder->codeAppend("a");
         break;
       case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
       default:
@@ -562,53 +591,51 @@
 
     switch (fYChannelSelector) {
       case SkDisplacementMapEffect::kR_ChannelSelectorType:
-        builder->fsCodeAppend("r");
+        fsBuilder->codeAppend("r");
         break;
       case SkDisplacementMapEffect::kG_ChannelSelectorType:
-        builder->fsCodeAppend("g");
+        fsBuilder->codeAppend("g");
         break;
       case SkDisplacementMapEffect::kB_ChannelSelectorType:
-        builder->fsCodeAppend("b");
+        fsBuilder->codeAppend("b");
         break;
       case SkDisplacementMapEffect::kA_ChannelSelectorType:
-        builder->fsCodeAppend("a");
+        fsBuilder->codeAppend("a");
         break;
       case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
       default:
         SkDEBUGFAIL("Unknown Y channel selector");
     }
-    builder->fsCodeAppend("-vec2(0.5));\t\t");
+    fsBuilder->codeAppend("-vec2(0.5));\t\t");
 
     // FIXME : This can be achieved with a "clamp to border" texture repeat mode and
     //         a 0 border color instead of computing if cCoords is out of bounds here.
-    builder->fsCodeAppendf(
+    fsBuilder->codeAppendf(
         "bool %s = (%s.x < 0.0) || (%s.y < 0.0) || (%s.x > 1.0) || (%s.y > 1.0);\t\t",
         outOfBounds, cCoords, cCoords, cCoords, cCoords);
-    builder->fsCodeAppendf("%s = %s ? vec4(0.0) : ", outputColor, outOfBounds);
-    builder->fsAppendTextureLookup(samplers[1], cCoords, coords[1].type());
-    builder->fsCodeAppend(";\n");
+    fsBuilder->codeAppendf("%s = %s ? vec4(0.0) : ", outputColor, outOfBounds);
+    fsBuilder->appendTextureLookup(samplers[1], cCoords, coords[1].getType());
+    fsBuilder->codeAppend(";\n");
 }
 
-void GrGLDisplacementMapEffect::setData(const GrGLUniformManager& uman,
-                                        const GrDrawEffect& drawEffect) {
-    const GrDisplacementMapEffect& displacementMap =
-        drawEffect.castEffect<GrDisplacementMapEffect>();
+void GrGLDisplacementMapEffect::setData(const GrGLProgramDataManager& pdman,
+                                        const GrProcessor& proc) {
+    const GrDisplacementMapEffect& displacementMap = proc.cast<GrDisplacementMapEffect>();
     GrTexture* colorTex = displacementMap.texture(1);
     SkScalar scaleX = SkScalarDiv(displacementMap.scale().fX, SkIntToScalar(colorTex->width()));
     SkScalar scaleY = SkScalarDiv(displacementMap.scale().fY, SkIntToScalar(colorTex->height()));
-    uman.set2f(fScaleUni, SkScalarToFloat(scaleX),
-               colorTex->origin() == kTopLeft_GrSurfaceOrigin ?
-               SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY));
+    pdman.set2f(fScaleUni, SkScalarToFloat(scaleX),
+                colorTex->origin() == kTopLeft_GrSurfaceOrigin ?
+                SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY));
 }
 
-GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                        const GrGLCaps&) {
-    const GrDisplacementMapEffect& displacementMap =
-        drawEffect.castEffect<GrDisplacementMapEffect>();
+void GrGLDisplacementMapEffect::GenKey(const GrProcessor& proc,
+                                       const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    const GrDisplacementMapEffect& displacementMap = proc.cast<GrDisplacementMapEffect>();
 
-    EffectKey xKey = displacementMap.xChannelSelector();
-    EffectKey yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBits;
+    uint32_t xKey = displacementMap.xChannelSelector();
+    uint32_t yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBits;
 
-    return xKey | yKey;
+    b->add32(xKey | yKey);
 }
 #endif
diff --git a/src/effects/SkDropShadowImageFilter.cpp b/src/effects/SkDropShadowImageFilter.cpp
index 032acec..339e955 100644
--- a/src/effects/SkDropShadowImageFilter.cpp
+++ b/src/effects/SkDropShadowImageFilter.cpp
@@ -15,21 +15,11 @@
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
 
-SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma,
-                                                 SkColor color, SkImageFilter* input)
-    : INHERITED(input)
-    , fDx(dx)
-    , fDy(dy)
-    , fSigmaX(sigma)
-    , fSigmaY(sigma)
-    , fColor(color)
-{
-}
-
 SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy,
                                                  SkScalar sigmaX, SkScalar sigmaY, SkColor color,
-                                                 SkImageFilter* input, const CropRect* cropRect)
-    : INHERITED(input, cropRect)
+                                                 SkImageFilter* input, const CropRect* cropRect,
+                                                 uint32_t uniqueID)
+    : INHERITED(1, &input, cropRect, uniqueID)
     , fDx(dx)
     , fDy(dy)
     , fSigmaX(sigmaX)
@@ -38,6 +28,7 @@
 {
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDropShadowImageFilter::SkDropShadowImageFilter(SkReadBuffer& buffer)
  : INHERITED(1, buffer) {
     fDx = buffer.readScalar();
@@ -50,9 +41,19 @@
                     SkScalarIsFinite(fSigmaX) &&
                     SkScalarIsFinite(fSigmaY));
 }
+#endif
 
-void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const
-{
+SkFlattenable* SkDropShadowImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkScalar dx = buffer.readScalar();
+    SkScalar dy = buffer.readScalar();
+    SkScalar sigmaX = buffer.readScalar();
+    SkScalar sigmaY = buffer.readScalar();
+    SkColor color = buffer.readColor();
+    return Create(dx, dy, sigmaX, sigmaY, color, common.getInput(0), &common.cropRect(), common.uniqueID());
+}
+
+void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writeScalar(fDx);
     buffer.writeScalar(fDy);
@@ -121,9 +122,6 @@
 bool SkDropShadowImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
                                              SkIRect* dst) const {
     SkIRect bounds = src;
-    if (getInput(0) && !getInput(0)->filterBounds(src, ctm, &bounds)) {
-        return false;
-    }
     SkVector offsetVec = SkVector::Make(fDx, fDy);
     ctm.mapVectors(&offsetVec, 1);
     bounds.offset(-SkScalarCeilToInt(offsetVec.x()),
@@ -133,6 +131,9 @@
     bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
                   SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
     bounds.join(src);
+    if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
+        return false;
+    }
     *dst = bounds;
     return true;
 }
diff --git a/src/effects/SkEmbossMaskFilter.cpp b/src/effects/SkEmbossMaskFilter.cpp
index cdd55fc..4841b92 100644
--- a/src/effects/SkEmbossMaskFilter.cpp
+++ b/src/effects/SkEmbossMaskFilter.cpp
@@ -124,17 +124,26 @@
     return true;
 }
 
-SkEmbossMaskFilter::SkEmbossMaskFilter(SkReadBuffer& buffer)
-        : SkMaskFilter(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkEmbossMaskFilter::SkEmbossMaskFilter(SkReadBuffer& buffer) : SkMaskFilter(buffer) {
     SkASSERT(buffer.getArrayCount() == sizeof(Light));
     buffer.readByteArray(&fLight, sizeof(Light));
     SkASSERT(fLight.fPad == 0); // for the font-cache lookup to be clean
     fBlurSigma = buffer.readScalar();
 }
+#endif
+
+SkFlattenable* SkEmbossMaskFilter::CreateProc(SkReadBuffer& buffer) {
+    Light light;
+    if (buffer.readByteArray(&light, sizeof(Light))) {
+        light.fPad = 0; // for the font-cache lookup to be clean
+        const SkScalar sigma = buffer.readScalar();
+        return Create(sigma, light);
+    }
+    return NULL;
+}
 
 void SkEmbossMaskFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
     Light tmpLight = fLight;
     tmpLight.fPad = 0;    // for the font-cache lookup to be clean
     buffer.writeByteArray(&tmpLight, sizeof(tmpLight));
diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp
index 9da08e6..76c3b3b 100644
--- a/src/effects/SkGpuBlurUtils.cpp
+++ b/src/effects/SkGpuBlurUtils.cpp
@@ -11,7 +11,7 @@
 
 #if SK_SUPPORT_GPU
 #include "effects/GrConvolutionEffect.h"
-#include "effects/GrTextureDomain.h"
+#include "effects/GrMatrixConvolutionEffect.h"
 #include "GrContext.h"
 #endif
 
@@ -43,21 +43,44 @@
     return sigma;
 }
 
-static void convolve_gaussian_pass(GrContext* context,
-                                   const SkRect& srcRect,
-                                   const SkRect& dstRect,
-                                   GrTexture* texture,
-                                   Gr1DKernelEffect::Direction direction,
-                                   int radius,
-                                   float sigma,
-                                   bool useBounds,
-                                   float bounds[2]) {
+static void convolve_gaussian_1d(GrContext* context,
+                                 const SkRect& srcRect,
+                                 const SkRect& dstRect,
+                                 GrTexture* texture,
+                                 Gr1DKernelEffect::Direction direction,
+                                 int radius,
+                                 float sigma,
+                                 bool useBounds,
+                                 float bounds[2]) {
     GrPaint paint;
     paint.reset();
-    SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(
+    SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian(
         texture, direction, radius, sigma, useBounds, bounds));
     paint.reset();
-    paint.addColorEffect(conv);
+    paint.addColorProcessor(conv);
+    context->drawRectToRect(paint, dstRect, srcRect);
+}
+
+static void convolve_gaussian_2d(GrContext* context,
+                                 const SkRect& srcRect,
+                                 const SkRect& dstRect,
+                                 GrTexture* texture,
+                                 int radiusX,
+                                 int radiusY,
+                                 SkScalar sigmaX,
+                                 SkScalar sigmaY,
+                                 bool useBounds,
+                                 SkIRect bounds) {
+    SkISize size = SkISize::Make(2 * radiusX + 1,  2 * radiusY + 1);
+    SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
+    GrPaint paint;
+    paint.reset();
+    SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaussian(
+            texture, bounds, size, 1.0, 0.0, kernelOffset,
+            useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_Mode,
+            true, sigmaX, sigmaY));
+    paint.reset();
+    paint.addColorProcessor(conv);
     context->drawRectToRect(paint, dstRect, srcRect);
 }
 
@@ -71,8 +94,8 @@
                               bool cropToSrcRect) {
     float bounds[2] = { 0.0f, 1.0f };
     if (!cropToSrcRect) {
-        convolve_gaussian_pass(context, srcRect, dstRect, texture,
-                          direction, radius, sigma, false, bounds);
+        convolve_gaussian_1d(context, srcRect, dstRect, texture,
+                             direction, radius, sigma, false, bounds);
         return;
     }
     SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect;
@@ -103,16 +126,16 @@
     }
     if (radius >= size * SK_ScalarHalf) {
         // Blur radius covers srcRect; use bounds over entire draw
-        convolve_gaussian_pass(context, srcRect, dstRect, texture,
-                          direction, radius, sigma, true, bounds);
+        convolve_gaussian_1d(context, srcRect, dstRect, texture,
+                            direction, radius, sigma, true, bounds);
     } else {
         // Draw upper and lower margins with bounds; middle without.
-        convolve_gaussian_pass(context, lowerSrcRect, lowerDstRect, texture,
-                          direction, radius, sigma, true, bounds);
-        convolve_gaussian_pass(context, upperSrcRect, upperDstRect, texture,
-                          direction, radius, sigma, true, bounds);
-        convolve_gaussian_pass(context, middleSrcRect, middleDstRect, texture,
-                          direction, radius, sigma, false, bounds);
+        convolve_gaussian_1d(context, lowerSrcRect, lowerDstRect, texture,
+                             direction, radius, sigma, true, bounds);
+        convolve_gaussian_1d(context, upperSrcRect, upperDstRect, texture,
+                             direction, radius, sigma, true, bounds);
+        convolve_gaussian_1d(context, middleSrcRect, middleDstRect, texture,
+                             direction, radius, sigma, false, bounds);
     }
 }
 
@@ -123,7 +146,7 @@
                         bool cropToRect,
                         float sigmaX,
                         float sigmaY) {
-    SkASSERT(NULL != context);
+    SkASSERT(context);
 
     GrContext::AutoRenderTarget art(context);
 
@@ -174,16 +197,16 @@
             matrix.mapRect(&domain, rect);
             domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width() : 0.0f,
                          i < scaleFactorY ? SK_ScalarHalf / srcTexture->height() : 0.0f);
-            SkAutoTUnref<GrEffectRef> effect(GrTextureDomainEffect::Create(
+            SkAutoTUnref<GrFragmentProcessor> fp(GrTextureDomainEffect::Create(
                 srcTexture,
                 matrix,
                 domain,
                 GrTextureDomain::kDecal_Mode,
                 GrTextureParams::kBilerp_FilterMode));
-            paint.addColorEffect(effect);
+            paint.addColorProcessor(fp);
         } else {
             GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
-            paint.addColorTextureEffect(srcTexture, matrix, params);
+            paint.addColorTextureProcessor(srcTexture, matrix, params);
         }
         scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
                              i < scaleFactorY ? 0.5f : 1.0f);
@@ -196,39 +219,55 @@
     SkIRect srcIRect;
     srcRect.roundOut(&srcIRect);
 
-    if (sigmaX > 0.0f) {
-        if (scaleFactorX > 1) {
-            // Clear out a radius to the right of the srcRect to prevent the
-            // X convolution from reading garbage.
-            clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
-                                          radiusX, srcIRect.height());
-            context->clear(&clearRect, 0x0, false);
-        }
+    // For really small blurs(Certainly no wider than 5x5 on desktop gpus) it is faster to just
+    // launch a single non separable kernel vs two launches
+    if (sigmaX > 0.0f && sigmaY > 0 &&
+            (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
+        // We shouldn't be scaling because this is a small size blur
+        SkASSERT((scaleFactorX == scaleFactorY) == 1);
         context->setRenderTarget(dstTexture->asRenderTarget());
         SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
-        convolve_gaussian(context, srcRect, dstRect, srcTexture,
-                          Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, cropToRect);
+        convolve_gaussian_2d(context, srcRect, dstRect, srcTexture,
+                radiusX, radiusY, sigmaX, sigmaY, cropToRect, srcIRect);
         srcTexture = dstTexture;
         srcRect = dstRect;
         SkTSwap(dstTexture, tempTexture);
-    }
 
-    if (sigmaY > 0.0f) {
-        if (scaleFactorY > 1 || sigmaX > 0.0f) {
-            // Clear out a radius below the srcRect to prevent the Y
-            // convolution from reading garbage.
-            clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
-                                          srcIRect.width(), radiusY);
-            context->clear(&clearRect, 0x0, false);
+    } else {
+        if (sigmaX > 0.0f) {
+            if (scaleFactorX > 1) {
+                // Clear out a radius to the right of the srcRect to prevent the
+                // X convolution from reading garbage.
+                clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
+                                              radiusX, srcIRect.height());
+                context->clear(&clearRect, 0x0, false);
+            }
+            context->setRenderTarget(dstTexture->asRenderTarget());
+            SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
+            convolve_gaussian(context, srcRect, dstRect, srcTexture,
+                              Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, cropToRect);
+            srcTexture = dstTexture;
+            srcRect = dstRect;
+            SkTSwap(dstTexture, tempTexture);
         }
 
-        context->setRenderTarget(dstTexture->asRenderTarget());
-        SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
-        convolve_gaussian(context, srcRect, dstRect, srcTexture,
-                          Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, cropToRect);
-        srcTexture = dstTexture;
-        srcRect = dstRect;
-        SkTSwap(dstTexture, tempTexture);
+        if (sigmaY > 0.0f) {
+            if (scaleFactorY > 1 || sigmaX > 0.0f) {
+                // Clear out a radius below the srcRect to prevent the Y
+                // convolution from reading garbage.
+                clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
+                                              srcIRect.width(), radiusY);
+                context->clear(&clearRect, 0x0, false);
+            }
+
+            context->setRenderTarget(dstTexture->asRenderTarget());
+            SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
+            convolve_gaussian(context, srcRect, dstRect, srcTexture,
+                              Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, cropToRect);
+            srcTexture = dstTexture;
+            srcRect = dstRect;
+            SkTSwap(dstTexture, tempTexture);
+        }
     }
 
     if (scaleFactorX > 1 || scaleFactorY > 1) {
@@ -247,7 +286,7 @@
         GrPaint paint;
         // FIXME:  this should be mitchell, not bilinear.
         GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
-        paint.addColorTextureEffect(srcTexture, matrix, params);
+        paint.addColorTextureProcessor(srcTexture, matrix, params);
 
         SkRect dstRect(srcRect);
         scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp
index aed2c9b..30709c4 100644
--- a/src/effects/SkLayerDrawLooper.cpp
+++ b/src/effects/SkLayerDrawLooper.cpp
@@ -200,20 +200,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
-#ifdef SK_DEBUG
-    {
-        Rec* rec = fRecs;
-        int count = 0;
-        while (rec) {
-            rec = rec->fNext;
-            count += 1;
-        }
-        SkASSERT(count == fCount);
-    }
-#endif
-
     buffer.writeInt(fCount);
 
     Rec* rec = fRecs;
@@ -245,22 +231,7 @@
         info.fPostTranslate = buffer.readBool();
         buffer.readPaint(builder.addLayerOnTop(info));
     }
-    SkLayerDrawLooper* looper = builder.detachLooper();
-    SkASSERT(count == looper->fCount);
-
-#ifdef SK_DEBUG
-    {
-        Rec* rec = looper->fRecs;
-        int n = 0;
-        while (rec) {
-            rec = rec->fNext;
-            n += 1;
-        }
-        SkASSERT(count == n);
-    }
-#endif
-
-    return looper;
+    return builder.detachLooper();
 }
 
 #ifndef SK_IGNORE_TO_STRING
@@ -366,7 +337,7 @@
     if (NULL == fRecs) {
         fRecs = rec;
     } else {
-        SkASSERT(NULL != fTopRec);
+        SkASSERT(fTopRec);
         fTopRec->fNext = rec;
     }
     fTopRec = rec;
diff --git a/src/effects/SkLayerRasterizer.cpp b/src/effects/SkLayerRasterizer.cpp
index 90fd59b..b331a03 100644
--- a/src/effects/SkLayerRasterizer.cpp
+++ b/src/effects/SkLayerRasterizer.cpp
@@ -50,17 +50,6 @@
     clean_up_layers(const_cast<SkDeque*>(fLayers));
 }
 
-#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API
-void SkLayerRasterizer::addLayer(const SkPaint& paint, SkScalar dx,
-                                 SkScalar dy) {
-    SkASSERT(fLayers);
-    SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)fLayers->push_back();
-
-    SkNEW_PLACEMENT_ARGS(&rec->fPaint, SkPaint, (paint));
-    rec->fOffset.set(dx, dy);
-}
-#endif
-
 static bool compute_bounds(const SkDeque& layers, const SkPath& path,
                            const SkMatrix& matrix,
                            const SkIRect* clipBounds, SkIRect* bounds) {
@@ -159,12 +148,18 @@
     return true;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLayerRasterizer::SkLayerRasterizer(SkReadBuffer& buffer)
     : SkRasterizer(buffer), fLayers(ReadLayers(buffer)) {}
+#endif
+
+SkFlattenable* SkLayerRasterizer::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW_ARGS(SkLayerRasterizer, (ReadLayers(buffer)));
+}
 
 SkDeque* SkLayerRasterizer::ReadLayers(SkReadBuffer& buffer) {
     int count = buffer.readInt();
-
+    
     SkDeque* layers = SkNEW_ARGS(SkDeque, (sizeof(SkLayerRasterizer_Rec)));
     for (int i = 0; i < count; i++) {
         SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)layers->push_back();
diff --git a/src/effects/SkLerpXfermode.cpp b/src/effects/SkLerpXfermode.cpp
index c8389fe..0376a57 100644
--- a/src/effects/SkLerpXfermode.cpp
+++ b/src/effects/SkLerpXfermode.cpp
@@ -23,16 +23,20 @@
 
 SkLerpXfermode::SkLerpXfermode(unsigned scale256) : fScale256(scale256) {}
 
-SkLerpXfermode::SkLerpXfermode(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkLerpXfermode::SkLerpXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     fScale256 = buffer.readUInt();
 }
+#endif
 
 void SkLerpXfermode::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeUInt(fScale256);
 }
 
+SkFlattenable* SkLerpXfermode::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW_ARGS(SkLerpXfermode, (buffer.readUInt()));
+}
+
 void SkLerpXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count,
                              const SkAlpha aa[]) const {
     const int scale = fScale256;
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index c0c605c..f766562 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -16,15 +16,16 @@
 
 #if SK_SUPPORT_GPU
 #include "effects/GrSingleTextureEffect.h"
-#include "gl/GrGLEffect.h"
-#include "GrEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
+#include "GrProcessor.h"
+#include "GrTBackendProcessorFactory.h"
 
 class GrGLDiffuseLightingEffect;
 class GrGLSpecularLightingEffect;
 
 // For brevity
-typedef GrGLUniformManager::UniformHandle UniformHandle;
+typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 #endif
 
 namespace {
@@ -35,13 +36,15 @@
 const SkScalar gOneQuarter = 0.25f;
 
 #if SK_SUPPORT_GPU
-void setUniformPoint3(const GrGLUniformManager& uman, UniformHandle uni, const SkPoint3& point) {
+void setUniformPoint3(const GrGLProgramDataManager& pdman, UniformHandle uni,
+                      const SkPoint3& point) {
     GR_STATIC_ASSERT(sizeof(SkPoint3) == 3 * sizeof(GrGLfloat));
-    uman.set3fv(uni, 1, &point.fX);
+    pdman.set3fv(uni, 1, &point.fX);
 }
 
-void setUniformNormal3(const GrGLUniformManager& uman, UniformHandle uni, const SkPoint3& point) {
-    setUniformPoint3(uman, uni, SkPoint3(point.fX, point.fY, point.fZ));
+void setUniformNormal3(const GrGLProgramDataManager& pdman, UniformHandle uni,
+                       const SkPoint3& point) {
+    setUniformPoint3(pdman, uni, SkPoint3(point.fX, point.fY, point.fZ));
 }
 #endif
 
@@ -59,7 +62,8 @@
 public:
     DiffuseLightingType(SkScalar kd)
         : fKD(kd) {}
-    SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, const SkPoint3& lightColor) const {
+    SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight,
+                    const SkPoint3& lightColor) const {
         SkScalar colorScale = SkScalarMul(fKD, normal.dot(surfaceTolight));
         colorScale = SkScalarClampMax(colorScale, SK_Scalar1);
         SkPoint3 color(lightColor * colorScale);
@@ -76,7 +80,8 @@
 public:
     SpecularLightingType(SkScalar ks, SkScalar shininess)
         : fKS(ks), fShininess(shininess) {}
-    SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, const SkPoint3& lightColor) const {
+    SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight,
+                    const SkPoint3& lightColor) const {
         SkPoint3 halfDir(surfaceTolight);
         halfDir.fZ += SK_Scalar1;        // eye position is always (0, 0, 1)
         halfDir.normalize();
@@ -161,7 +166,9 @@
                          surfaceScale);
 }
 
-template <class LightingType, class LightType> void lightBitmap(const LightingType& lightingType, const SkLight* light, const SkBitmap& src, SkBitmap* dst, SkScalar surfaceScale, const SkIRect& bounds) {
+template <class LightingType, class LightType> void lightBitmap(
+        const LightingType& lightingType, const SkLight* light, const SkBitmap& src, SkBitmap* dst,
+        SkScalar surfaceScale, const SkIRect& bounds) {
     SkASSERT(dst->width() == bounds.width() && dst->height() == bounds.height());
     const LightType* l = static_cast<const LightType*>(light);
     int left = bounds.left(), right = bounds.right();
@@ -178,18 +185,21 @@
         m[7] = SkGetPackedA32(*row2++);
         m[8] = SkGetPackedA32(*row2++);
         SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
-        *dptr++ = lightingType.light(topLeftNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
+        *dptr++ = lightingType.light(topLeftNormal(m, surfaceScale), surfaceToLight,
+                                     l->lightColor(surfaceToLight));
         for (++x; x < right - 1; ++x)
         {
             shiftMatrixLeft(m);
             m[5] = SkGetPackedA32(*row1++);
             m[8] = SkGetPackedA32(*row2++);
             surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
-            *dptr++ = lightingType.light(topNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
+            *dptr++ = lightingType.light(topNormal(m, surfaceScale), surfaceToLight,
+                                         l->lightColor(surfaceToLight));
         }
         shiftMatrixLeft(m);
         surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
-        *dptr++ = lightingType.light(topRightNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
+        *dptr++ = lightingType.light(topRightNormal(m, surfaceScale), surfaceToLight,
+                                     l->lightColor(surfaceToLight));
     }
 
     for (++y; y < bottom - 1; ++y) {
@@ -205,18 +215,21 @@
         m[7] = SkGetPackedA32(*row2++);
         m[8] = SkGetPackedA32(*row2++);
         SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
-        *dptr++ = lightingType.light(leftNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
+        *dptr++ = lightingType.light(leftNormal(m, surfaceScale), surfaceToLight,
+                                     l->lightColor(surfaceToLight));
         for (++x; x < right - 1; ++x) {
             shiftMatrixLeft(m);
             m[2] = SkGetPackedA32(*row0++);
             m[5] = SkGetPackedA32(*row1++);
             m[8] = SkGetPackedA32(*row2++);
             surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
-            *dptr++ = lightingType.light(interiorNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
+            *dptr++ = lightingType.light(interiorNormal(m, surfaceScale), surfaceToLight,
+                                         l->lightColor(surfaceToLight));
         }
         shiftMatrixLeft(m);
         surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
-        *dptr++ = lightingType.light(rightNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
+        *dptr++ = lightingType.light(rightNormal(m, surfaceScale), surfaceToLight,
+                                     l->lightColor(surfaceToLight));
     }
 
     {
@@ -229,18 +242,21 @@
         m[4] = SkGetPackedA32(*row1++);
         m[5] = SkGetPackedA32(*row1++);
         SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
-        *dptr++ = lightingType.light(bottomLeftNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
+        *dptr++ = lightingType.light(bottomLeftNormal(m, surfaceScale), surfaceToLight,
+                                     l->lightColor(surfaceToLight));
         for (++x; x < right - 1; ++x)
         {
             shiftMatrixLeft(m);
             m[2] = SkGetPackedA32(*row0++);
             m[5] = SkGetPackedA32(*row1++);
             surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
-            *dptr++ = lightingType.light(bottomNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
+            *dptr++ = lightingType.light(bottomNormal(m, surfaceScale), surfaceToLight,
+                                         l->lightColor(surfaceToLight));
         }
         shiftMatrixLeft(m);
         surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale);
-        *dptr++ = lightingType.light(bottomRightNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight));
+        *dptr++ = lightingType.light(bottomRightNormal(m, surfaceScale), surfaceToLight,
+                                     l->lightColor(surfaceToLight));
     }
 }
 
@@ -263,46 +279,64 @@
 
 class SkDiffuseLightingImageFilter : public SkLightingImageFilter {
 public:
-    SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale,
-                                 SkScalar kd, SkImageFilter* input, const CropRect* cropRect);
+    static SkImageFilter* Create(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter*,
+                                 const CropRect*, uint32_t uniqueID = 0);
+
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiffuseLightingImageFilter)
     SkScalar kd() const { return fKD; }
 
 protected:
+    SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale,
+                                 SkScalar kd, SkImageFilter* input, const CropRect* cropRect,
+                                 uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDiffuseLightingImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
 #if SK_SUPPORT_GPU
-    virtual bool asNewEffect(GrEffectRef** effect, GrTexture*, const SkMatrix& matrix, const SkIRect& bounds) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+                                     const SkIRect& bounds) const SK_OVERRIDE;
 #endif
 
 private:
+    friend class SkLightingImageFilter;
     typedef SkLightingImageFilter INHERITED;
     SkScalar fKD;
 };
 
 class SkSpecularLightingImageFilter : public SkLightingImageFilter {
 public:
-    SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect);
+    static SkImageFilter* Create(SkLight* light, SkScalar surfaceScale,
+                                 SkScalar ks, SkScalar shininess, SkImageFilter*, const CropRect*,
+                                 uint32_t uniqueID = 0);
+
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSpecularLightingImageFilter)
 
     SkScalar ks() const { return fKS; }
     SkScalar shininess() const { return fShininess; }
 
 protected:
+    SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks,
+                                  SkScalar shininess, SkImageFilter* input, const CropRect*,
+                                  uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkSpecularLightingImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
 #if SK_SUPPORT_GPU
-    virtual bool asNewEffect(GrEffectRef** effect, GrTexture*, const SkMatrix& matrix, const SkIRect& bounds) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+                                     const SkIRect& bounds) const SK_OVERRIDE;
 #endif
 
 private:
-    typedef SkLightingImageFilter INHERITED;
     SkScalar fKS;
     SkScalar fShininess;
+    friend class SkLightingImageFilter;
+    typedef SkLightingImageFilter INHERITED;
 };
 
 #if SK_SUPPORT_GPU
@@ -323,7 +357,7 @@
     }
 
 protected:
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
 private:
     typedef GrSingleTextureEffect INHERITED;
@@ -334,28 +368,27 @@
 
 class GrDiffuseLightingEffect : public GrLightingEffect {
 public:
-    static GrEffectRef* Create(GrTexture* texture,
-                               const SkLight* light,
-                               SkScalar surfaceScale,
-                               const SkMatrix& matrix,
-                               SkScalar kd) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrDiffuseLightingEffect, (texture,
-                                                                    light,
-                                                                    surfaceScale,
-                                                                    matrix,
-                                                                    kd)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* texture,
+                                       const SkLight* light,
+                                       SkScalar surfaceScale,
+                                       const SkMatrix& matrix,
+                                       SkScalar kd) {
+        return SkNEW_ARGS(GrDiffuseLightingEffect, (texture,
+                                                    light,
+                                                    surfaceScale,
+                                                    matrix,
+                                                    kd));
     }
 
     static const char* Name() { return "DiffuseLighting"; }
 
-    typedef GrGLDiffuseLightingEffect GLEffect;
+    typedef GrGLDiffuseLightingEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     SkScalar kd() const { return fKD; }
 
 private:
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     GrDiffuseLightingEffect(GrTexture* texture,
                             const SkLight* light,
@@ -363,37 +396,36 @@
                             const SkMatrix& matrix,
                             SkScalar kd);
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
     typedef GrLightingEffect INHERITED;
     SkScalar fKD;
 };
 
 class GrSpecularLightingEffect : public GrLightingEffect {
 public:
-    static GrEffectRef* Create(GrTexture* texture,
-                               const SkLight* light,
-                               SkScalar surfaceScale,
-                               const SkMatrix& matrix,
-                               SkScalar ks,
-                               SkScalar shininess) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrSpecularLightingEffect, (texture,
-                                                                     light,
-                                                                     surfaceScale,
-                                                                     matrix,
-                                                                     ks,
-                                                                     shininess)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* texture,
+                                       const SkLight* light,
+                                       SkScalar surfaceScale,
+                                       const SkMatrix& matrix,
+                                       SkScalar ks,
+                                       SkScalar shininess) {
+        return SkNEW_ARGS(GrSpecularLightingEffect, (texture,
+                                                     light,
+                                                     surfaceScale,
+                                                     matrix,
+                                                     ks,
+                                                     shininess));
     }
     static const char* Name() { return "SpecularLighting"; }
 
-    typedef GrGLSpecularLightingEffect GLEffect;
+    typedef GrGLSpecularLightingEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     SkScalar ks() const { return fKS; }
     SkScalar shininess() const { return fShininess; }
 
 private:
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     GrSpecularLightingEffect(GrTexture* texture,
                              const SkLight* light,
@@ -402,7 +434,7 @@
                              SkScalar ks,
                              SkScalar shininess);
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
     typedef GrLightingEffect INHERITED;
     SkScalar fKS;
     SkScalar fShininess;
@@ -418,7 +450,7 @@
      * This is called by GrGLLightingEffect::emitCode() before either of the two virtual functions
      * below. It adds a vec3f uniform visible in the FS that represents the constant light color.
      */
-    void emitLightColorUniform(GrGLShaderBuilder*);
+    void emitLightColorUniform(GrGLProgramBuilder*);
 
     /**
      * These two functions are called from GrGLLightingEffect's emitCode() function.
@@ -428,12 +460,12 @@
      * the FS. The default of emitLightColor appends the name of the constant light color uniform
      * and so this function only needs to be overridden if the light color varies spatially.
      */
-    virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) = 0;
-    virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight);
+    virtual void emitSurfaceToLight(GrGLProgramBuilder*, const char* z) = 0;
+    virtual void emitLightColor(GrGLProgramBuilder*, const char *surfaceToLight);
 
     // This is called from GrGLLightingEffect's setData(). Subclasses of GrGLLight must call
     // INHERITED::setData().
-    virtual void setData(const GrGLUniformManager&,
+    virtual void setData(const GrGLProgramDataManager&,
                          const SkLight* light) const;
 
 protected:
@@ -454,9 +486,9 @@
 class GrGLDistantLight : public GrGLLight {
 public:
     virtual ~GrGLDistantLight() {}
-    virtual void setData(const GrGLUniformManager&,
+    virtual void setData(const GrGLProgramDataManager&,
                          const SkLight* light) const SK_OVERRIDE;
-    virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
+    virtual void emitSurfaceToLight(GrGLProgramBuilder*, const char* z) SK_OVERRIDE;
 
 private:
     typedef GrGLLight INHERITED;
@@ -468,9 +500,9 @@
 class GrGLPointLight : public GrGLLight {
 public:
     virtual ~GrGLPointLight() {}
-    virtual void setData(const GrGLUniformManager&,
+    virtual void setData(const GrGLProgramDataManager&,
                          const SkLight* light) const SK_OVERRIDE;
-    virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
+    virtual void emitSurfaceToLight(GrGLProgramBuilder*, const char* z) SK_OVERRIDE;
 
 private:
     typedef GrGLLight INHERITED;
@@ -482,10 +514,10 @@
 class GrGLSpotLight : public GrGLLight {
 public:
     virtual ~GrGLSpotLight() {}
-    virtual void setData(const GrGLUniformManager&,
+    virtual void setData(const GrGLProgramDataManager&,
                          const SkLight* light) const SK_OVERRIDE;
-    virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
-    virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight) SK_OVERRIDE;
+    virtual void emitSurfaceToLight(GrGLProgramBuilder*, const char* z) SK_OVERRIDE;
+    virtual void emitLightColor(GrGLProgramBuilder*, const char *surfaceToLight) SK_OVERRIDE;
 
 private:
     typedef GrGLLight INHERITED;
@@ -829,102 +861,142 @@
 }
 ///////////////////////////////////////////////////////////////////////////////
 
-SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkImageFilter* input, const CropRect* cropRect)
-  : INHERITED(input, cropRect),
-    fLight(light),
-    fSurfaceScale(SkScalarDiv(surfaceScale, SkIntToScalar(255)))
-{
-    SkASSERT(fLight);
-    // our caller knows that we take ownership of the light, so we don't
-    // need to call ref() here.
+SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceScale,
+                                             SkImageFilter* input, const CropRect* cropRect,
+                                             uint32_t uniqueID)
+  : INHERITED(1, &input, cropRect, uniqueID)
+  , fLight(SkRef(light))
+  , fSurfaceScale(surfaceScale / 255)
+{}
+
+SkImageFilter* SkLightingImageFilter::CreateDistantLitDiffuse(const SkPoint3& direction,
+                                                              SkColor lightColor,
+                                                              SkScalar surfaceScale,
+                                                              SkScalar kd,
+                                                              SkImageFilter* input,
+                                                              const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkDistantLight, (direction, lightColor)));
+    return SkDiffuseLightingImageFilter::Create(light, surfaceScale, kd, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreateDistantLitDiffuse(
-    const SkPoint3& direction, SkColor lightColor, SkScalar surfaceScale,
-    SkScalar kd, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkDiffuseLightingImageFilter,
-        (SkNEW_ARGS(SkDistantLight, (direction, lightColor)), surfaceScale, kd,
-        input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreatePointLitDiffuse(const SkPoint3& location,
+                                                            SkColor lightColor,
+                                                            SkScalar surfaceScale,
+                                                            SkScalar kd,
+                                                            SkImageFilter* input,
+                                                            const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkPointLight, (location, lightColor)));
+    return SkDiffuseLightingImageFilter::Create(light, surfaceScale, kd, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreatePointLitDiffuse(
-    const SkPoint3& location, SkColor lightColor, SkScalar surfaceScale,
-    SkScalar kd, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkDiffuseLightingImageFilter,
-        (SkNEW_ARGS(SkPointLight, (location, lightColor)), surfaceScale, kd,
-        input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreateSpotLitDiffuse(const SkPoint3& location,
+                                                           const SkPoint3& target,
+                                                           SkScalar specularExponent,
+                                                           SkScalar cutoffAngle,
+                                                           SkColor lightColor,
+                                                           SkScalar surfaceScale,
+                                                           SkScalar kd,
+                                                           SkImageFilter* input,
+                                                           const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkSpotLight, (location, target, specularExponent,
+                                                         cutoffAngle, lightColor)));
+    return SkDiffuseLightingImageFilter::Create(light, surfaceScale, kd, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreateSpotLitDiffuse(
-    const SkPoint3& location, const SkPoint3& target,
-    SkScalar specularExponent, SkScalar cutoffAngle,
-    SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
-    SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkDiffuseLightingImageFilter,
-        (SkNEW_ARGS(SkSpotLight, (location, target, specularExponent,
-                                  cutoffAngle, lightColor)),
-                    surfaceScale, kd, input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreateDistantLitSpecular(const SkPoint3& direction,
+                                                               SkColor lightColor,
+                                                               SkScalar surfaceScale,
+                                                               SkScalar ks,
+                                                               SkScalar shine,
+                                                               SkImageFilter* input,
+                                                               const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkDistantLight, (direction, lightColor)));
+    return SkSpecularLightingImageFilter::Create(light, surfaceScale, ks, shine, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreateDistantLitSpecular(
-    const SkPoint3& direction, SkColor lightColor, SkScalar surfaceScale,
-    SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkSpecularLightingImageFilter,
-        (SkNEW_ARGS(SkDistantLight, (direction, lightColor)),
-        surfaceScale, ks, shininess, input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreatePointLitSpecular(const SkPoint3& location,
+                                                             SkColor lightColor,
+                                                             SkScalar surfaceScale,
+                                                             SkScalar ks,
+                                                             SkScalar shine,
+                                                             SkImageFilter* input,
+                                                             const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkPointLight, (location, lightColor)));
+    return SkSpecularLightingImageFilter::Create(light, surfaceScale, ks, shine, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreatePointLitSpecular(
-    const SkPoint3& location, SkColor lightColor, SkScalar surfaceScale,
-    SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkSpecularLightingImageFilter,
-        (SkNEW_ARGS(SkPointLight, (location, lightColor)),
-        surfaceScale, ks, shininess, input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreateSpotLitSpecular(const SkPoint3& location,
+                                                            const SkPoint3& target,
+                                                            SkScalar specularExponent,
+                                                            SkScalar cutoffAngle,
+                                                            SkColor lightColor,
+                                                            SkScalar surfaceScale,
+                                                            SkScalar ks,
+                                                            SkScalar shine,
+                                                            SkImageFilter* input,
+                                                            const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkSpotLight, (location, target, specularExponent,
+                                                         cutoffAngle, lightColor)));
+    return SkSpecularLightingImageFilter::Create(light, surfaceScale, ks, shine, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreateSpotLitSpecular(
-    const SkPoint3& location, const SkPoint3& target,
-    SkScalar specularExponent, SkScalar cutoffAngle,
-    SkColor lightColor, SkScalar surfaceScale,
-    SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkSpecularLightingImageFilter,
-        (SkNEW_ARGS(SkSpotLight, (location, target, specularExponent, cutoffAngle, lightColor)),
-        surfaceScale, ks, shininess, input, cropRect));
-}
+SkLightingImageFilter::~SkLightingImageFilter() {}
 
-SkLightingImageFilter::~SkLightingImageFilter() {
-    SkSafeUnref(fLight);
-}
-
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLightingImageFilter::SkLightingImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
-    fLight = SkLight::UnflattenLight(buffer);
+    fLight.reset(SkLight::UnflattenLight(buffer));
     fSurfaceScale = buffer.readScalar();
     buffer.validate(SkScalarIsFinite(fSurfaceScale));
 }
+#endif
 
 void SkLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     fLight->flattenLight(buffer);
-    buffer.writeScalar(fSurfaceScale);
+    buffer.writeScalar(fSurfaceScale * 255);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter* input, const CropRect* cropRect = NULL)
-  : SkLightingImageFilter(light, surfaceScale, input, cropRect),
+SkImageFilter* SkDiffuseLightingImageFilter::Create(SkLight* light, SkScalar surfaceScale,
+                                    SkScalar kd, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
+    if (NULL == light) {
+        return NULL;
+    }
+    if (!SkScalarIsFinite(surfaceScale) || !SkScalarIsFinite(kd)) {
+        return NULL;
+    }
     // According to the spec, kd can be any non-negative number :
     // http://www.w3.org/TR/SVG/filters.html#feDiffuseLightingElement
-    fKD(kd < 0 ? 0 : kd)
+    if (kd < 0) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkDiffuseLightingImageFilter, (light, surfaceScale, kd, input, cropRect, uniqueID));
+}
+
+SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+  : SkLightingImageFilter(light, surfaceScale, input, cropRect, uniqueID),
+    fKD(kd)
 {
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkReadBuffer& buffer)
   : INHERITED(buffer)
 {
     fKD = buffer.readScalar();
     buffer.validate(SkScalarIsFinite(fKD) && (fKD >= 0));
 }
+#endif
+
+SkFlattenable* SkDiffuseLightingImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkAutoTUnref<SkLight> light(SkLight::UnflattenLight(buffer));
+    SkScalar surfaceScale = buffer.readScalar();
+    SkScalar kd = buffer.readScalar();
+    return Create(light, surfaceScale, kd, common.getInput(0), &common.cropRect(), common.uniqueID());
+}
 
 void SkDiffuseLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
@@ -960,7 +1032,7 @@
         return false;
     }
 
-    if (!dst->allocPixels(src.info().makeWH(bounds.width(), bounds.height()))) {
+    if (!dst->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height()))) {
         return false;
     }
 
@@ -986,10 +1058,13 @@
 }
 
 #if SK_SUPPORT_GPU
-bool SkDiffuseLightingImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture, const SkMatrix& matrix, const SkIRect&) const {
-    if (effect) {
+bool SkDiffuseLightingImageFilter::asFragmentProcessor(GrFragmentProcessor** fp,
+                                                       GrTexture* texture,
+                                                       const SkMatrix& matrix,
+                                                       const SkIRect&) const {
+    if (fp) {
         SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
-        *effect = GrDiffuseLightingEffect::Create(texture, light(), scale, matrix, kd());
+        *fp = GrDiffuseLightingEffect::Create(texture, light(), scale, matrix, kd());
     }
     return true;
 }
@@ -997,23 +1072,49 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect)
-  : SkLightingImageFilter(light, surfaceScale, input, cropRect),
+SkImageFilter* SkSpecularLightingImageFilter::Create(SkLight* light, SkScalar surfaceScale,
+                SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
+    if (NULL == light) {
+        return NULL;
+    }
+    if (!SkScalarIsFinite(surfaceScale) || !SkScalarIsFinite(ks) || !SkScalarIsFinite(shininess)) {
+        return NULL;
+    }
     // According to the spec, ks can be any non-negative number :
     // http://www.w3.org/TR/SVG/filters.html#feSpecularLightingElement
-    fKS(ks < 0 ? 0 : ks),
+    if (ks < 0) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkSpecularLightingImageFilter,
+                      (light, surfaceScale, ks, shininess, input, cropRect, uniqueID));
+}
+
+SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+  : SkLightingImageFilter(light, surfaceScale, input, cropRect, uniqueID),
+    fKS(ks),
     fShininess(shininess)
 {
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkReadBuffer& buffer)
-  : INHERITED(buffer)
+    : INHERITED(buffer)
 {
     fKS = buffer.readScalar();
     fShininess = buffer.readScalar();
     buffer.validate(SkScalarIsFinite(fKS) && (fKS >= 0) &&
                     SkScalarIsFinite(fShininess));
 }
+#endif
+
+SkFlattenable* SkSpecularLightingImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkAutoTUnref<SkLight> light(SkLight::UnflattenLight(buffer));
+    SkScalar surfaceScale = buffer.readScalar();
+    SkScalar ks = buffer.readScalar();
+    SkScalar shine = buffer.readScalar();
+    return Create(light, surfaceScale, ks, shine, common.getInput(0), &common.cropRect(), common.uniqueID());
+}
 
 void SkSpecularLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
@@ -1051,7 +1152,7 @@
         return false;
     }
 
-    if (!dst->allocPixels(src.info().makeWH(bounds.width(), bounds.height()))) {
+    if (!dst->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height()))) {
         return false;
     }
 
@@ -1075,10 +1176,13 @@
 }
 
 #if SK_SUPPORT_GPU
-bool SkSpecularLightingImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture, const SkMatrix& matrix, const SkIRect&) const {
-    if (effect) {
+bool SkSpecularLightingImageFilter::asFragmentProcessor(GrFragmentProcessor** fp,
+                                                        GrTexture* texture,
+                                                        const SkMatrix& matrix,
+                                                        const SkIRect&) const {
+    if (fp) {
         SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
-        *effect = GrSpecularLightingEffect::Create(texture, light(), scale, matrix, ks(), shininess());
+        *fp = GrSpecularLightingEffect::Create(texture, light(), scale, matrix, ks(), shininess());
     }
     return true;
 }
@@ -1119,32 +1223,31 @@
 
 }
 
-class GrGLLightingEffect  : public GrGLEffect {
+class GrGLLightingEffect  : public GrGLFragmentProcessor {
 public:
-    GrGLLightingEffect(const GrBackendEffectFactory& factory,
-                       const GrDrawEffect& effect);
+    GrGLLightingEffect(const GrBackendProcessorFactory&, const GrProcessor&);
     virtual ~GrGLLightingEffect();
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b);
 
     /**
      * Subclasses of GrGLLightingEffect must call INHERITED::setData();
      */
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 protected:
-    virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) = 0;
+    virtual void emitLightFunc(GrGLProgramBuilder*, SkString* funcName) = 0;
 
 private:
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 
     UniformHandle       fImageIncrementUni;
     UniformHandle       fSurfaceScaleUni;
@@ -1155,10 +1258,9 @@
 
 class GrGLDiffuseLightingEffect  : public GrGLLightingEffect {
 public:
-    GrGLDiffuseLightingEffect(const GrBackendEffectFactory& factory,
-                              const GrDrawEffect& drawEffect);
-    virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    GrGLDiffuseLightingEffect(const GrBackendProcessorFactory&, const GrProcessor&);
+    virtual void emitLightFunc(GrGLProgramBuilder*, SkString* funcName) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
     typedef GrGLLightingEffect INHERITED;
@@ -1170,10 +1272,9 @@
 
 class GrGLSpecularLightingEffect  : public GrGLLightingEffect {
 public:
-    GrGLSpecularLightingEffect(const GrBackendEffectFactory& factory,
-                               const GrDrawEffect& effect);
-    virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    GrGLSpecularLightingEffect(const GrBackendProcessorFactory&, const GrProcessor&);
+    virtual void emitLightFunc(GrGLProgramBuilder*, SkString* funcName) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
     typedef GrGLLightingEffect INHERITED;
@@ -1188,7 +1289,7 @@
                                    const SkLight* light,
                                    SkScalar surfaceScale,
                                    const SkMatrix& matrix)
-    : INHERITED(texture, MakeDivByTextureWHMatrix(texture))
+    : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
     , fLight(light)
     , fSurfaceScale(surfaceScale)
     , fFilterMatrix(matrix) {
@@ -1202,8 +1303,8 @@
     fLight->unref();
 }
 
-bool GrLightingEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrLightingEffect& s = CastEffect<GrLightingEffect>(sBase);
+bool GrLightingEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrLightingEffect& s = sBase.cast<GrLightingEffect>();
     return this->texture(0) == s.texture(0) &&
            fLight->isEqual(*s.fLight) &&
            fSurfaceScale == s.fSurfaceScale;
@@ -1219,22 +1320,22 @@
     : INHERITED(texture, light, surfaceScale, matrix), fKD(kd) {
 }
 
-const GrBackendEffectFactory& GrDiffuseLightingEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrDiffuseLightingEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrDiffuseLightingEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrDiffuseLightingEffect>::getInstance();
 }
 
-bool GrDiffuseLightingEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrDiffuseLightingEffect& s = CastEffect<GrDiffuseLightingEffect>(sBase);
+bool GrDiffuseLightingEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrDiffuseLightingEffect& s = sBase.cast<GrDiffuseLightingEffect>();
     return INHERITED::onIsEqual(sBase) &&
             this->kd() == s.kd();
 }
 
-GR_DEFINE_EFFECT_TEST(GrDiffuseLightingEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDiffuseLightingEffect);
 
-GrEffectRef* GrDiffuseLightingEffect::TestCreate(SkRandom* random,
-                                                 GrContext* context,
-                                                 const GrDrawTargetCaps&,
-                                                 GrTexture* textures[]) {
+GrFragmentProcessor* GrDiffuseLightingEffect::TestCreate(SkRandom* random,
+                                              GrContext* context,
+                                              const GrDrawTargetCaps&,
+                                              GrTexture* textures[]) {
     SkScalar surfaceScale = random->nextSScalar1();
     SkScalar kd = random->nextUScalar1();
     SkAutoTUnref<SkLight> light(create_random_light(random));
@@ -1242,17 +1343,17 @@
     for (int i = 0; i < 9; i++) {
         matrix[i] = random->nextUScalar1();
     }
-    return GrDiffuseLightingEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx],
+    return GrDiffuseLightingEffect::Create(textures[GrProcessorUnitTest::kAlphaTextureIdx],
                                            light, surfaceScale, matrix, kd);
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrGLLightingEffect::GrGLLightingEffect(const GrBackendEffectFactory& factory,
-                                       const GrDrawEffect& drawEffect)
+GrGLLightingEffect::GrGLLightingEffect(const GrBackendProcessorFactory& factory,
+                                       const GrProcessor& fp)
     : INHERITED(factory) {
-    const GrLightingEffect& m = drawEffect.castEffect<GrLightingEffect>();
+    const GrLightingEffect& m = fp.cast<GrLightingEffect>();
     fLight = m.light()->createGLLight();
 }
 
@@ -1260,19 +1361,17 @@
     delete fLight;
 }
 
-void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
-                                  const GrDrawEffect&,
-                                  EffectKey key,
+void GrGLLightingEffect::emitCode(GrGLProgramBuilder* builder,
+                                  const GrFragmentProcessor&,
+                                  const GrProcessorKey& key,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TransformedCoordsArray& coords,
                                   const TextureSamplerArray& samplers) {
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
-
-    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                               kVec2f_GrSLType,
                                              "ImageIncrement");
-    fSurfaceScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fSurfaceScaleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                            kFloat_GrSLType,
                                            "SurfaceScale");
     fLight->emitLightColorUniform(builder);
@@ -1288,7 +1387,10 @@
         GrGLShaderVar("scale", kFloat_GrSLType),
     };
     SkString sobelFuncName;
-    builder->fsEmitFunction(kFloat_GrSLType,
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+
+    fsBuilder->emitFunction(kFloat_GrSLType,
                             "sobel",
                             SK_ARRAY_COUNT(gSobelArgs),
                             gSobelArgs,
@@ -1300,7 +1402,7 @@
         GrGLShaderVar("scale", kFloat_GrSLType),
     };
     SkString pointToNormalName;
-    builder->fsEmitFunction(kVec3f_GrSLType,
+    fsBuilder->emitFunction(kVec3f_GrSLType,
                             "pointToNormal",
                             SK_ARRAY_COUNT(gPointToNormalArgs),
                             gPointToNormalArgs,
@@ -1319,15 +1421,15 @@
                                 sobelFuncName.c_str(),
                                 sobelFuncName.c_str());
     SkString interiorNormalName;
-    builder->fsEmitFunction(kVec3f_GrSLType,
+    fsBuilder->emitFunction(kVec3f_GrSLType,
                             "interiorNormal",
                             SK_ARRAY_COUNT(gInteriorNormalArgs),
                             gInteriorNormalArgs,
                             interiorNormalBody.c_str(),
                             &interiorNormalName);
 
-    builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
-    builder->fsCodeAppend("\t\tfloat m[9];\n");
+    fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
+    fsBuilder->codeAppend("\t\tfloat m[9];\n");
 
     const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
     const char* surfScale = builder->getUniformCStr(fSurfaceScaleUni);
@@ -1337,53 +1439,53 @@
         for (int dx = -1; dx <= 1; dx++) {
             SkString texCoords;
             texCoords.appendf("coord + vec2(%d, %d) * %s", dx, dy, imgInc);
-            builder->fsCodeAppendf("\t\tm[%d] = ", index++);
-            builder->fsAppendTextureLookup(samplers[0], texCoords.c_str());
-            builder->fsCodeAppend(".a;\n");
+            fsBuilder->codeAppendf("\t\tm[%d] = ", index++);
+            fsBuilder->appendTextureLookup(samplers[0], texCoords.c_str());
+            fsBuilder->codeAppend(".a;\n");
         }
     }
-    builder->fsCodeAppend("\t\tvec3 surfaceToLight = ");
+    fsBuilder->codeAppend("\t\tvec3 surfaceToLight = ");
     SkString arg;
     arg.appendf("%s * m[4]", surfScale);
     fLight->emitSurfaceToLight(builder, arg.c_str());
-    builder->fsCodeAppend(";\n");
-    builder->fsCodeAppendf("\t\t%s = %s(%s(m, %s), surfaceToLight, ",
+    fsBuilder->codeAppend(";\n");
+    fsBuilder->codeAppendf("\t\t%s = %s(%s(m, %s), surfaceToLight, ",
                            outputColor, lightFunc.c_str(), interiorNormalName.c_str(), surfScale);
     fLight->emitLightColor(builder, "surfaceToLight");
-    builder->fsCodeAppend(");\n");
+    fsBuilder->codeAppend(");\n");
     SkString modulate;
     GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
-    builder->fsCodeAppend(modulate.c_str());
+    fsBuilder->codeAppend(modulate.c_str());
 }
 
-GrGLEffect::EffectKey GrGLLightingEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                 const GrGLCaps& caps) {
-    return drawEffect.castEffect<GrLightingEffect>().light()->type();
+void GrGLLightingEffect::GenKey(const GrProcessor& proc,
+                                const GrGLCaps& caps, GrProcessorKeyBuilder* b) {
+    b->add32(proc.cast<GrLightingEffect>().light()->type());
 }
 
-void GrGLLightingEffect::setData(const GrGLUniformManager& uman,
-                                 const GrDrawEffect& drawEffect) {
-    const GrLightingEffect& lighting = drawEffect.castEffect<GrLightingEffect>();
+void GrGLLightingEffect::setData(const GrGLProgramDataManager& pdman,
+                                 const GrProcessor& proc) {
+    const GrLightingEffect& lighting = proc.cast<GrLightingEffect>();
     GrTexture* texture = lighting.texture(0);
     float ySign = texture->origin() == kTopLeft_GrSurfaceOrigin ? -1.0f : 1.0f;
-    uman.set2f(fImageIncrementUni, 1.0f / texture->width(), ySign / texture->height());
-    uman.set1f(fSurfaceScaleUni, lighting.surfaceScale());
+    pdman.set2f(fImageIncrementUni, 1.0f / texture->width(), ySign / texture->height());
+    pdman.set1f(fSurfaceScaleUni, lighting.surfaceScale());
     SkAutoTUnref<SkLight> transformedLight(lighting.light()->transform(lighting.filterMatrix()));
-    fLight->setData(uman, transformedLight);
+    fLight->setData(pdman, transformedLight);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrBackendEffectFactory& factory,
-                                                     const GrDrawEffect& drawEffect)
-    : INHERITED(factory, drawEffect) {
+GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrBackendProcessorFactory& factory,
+                                                     const GrProcessor& proc)
+    : INHERITED(factory, proc) {
 }
 
-void GrGLDiffuseLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) {
+void GrGLDiffuseLightingEffect::emitLightFunc(GrGLProgramBuilder* builder, SkString* funcName) {
     const char* kd;
-    fKDUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fKDUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                  kFloat_GrSLType,
                                  "KD",
                                  &kd);
@@ -1396,19 +1498,19 @@
     SkString lightBody;
     lightBody.appendf("\tfloat colorScale = %s * dot(normal, surfaceToLight);\n", kd);
     lightBody.appendf("\treturn vec4(lightColor * clamp(colorScale, 0.0, 1.0), 1.0);\n");
-    builder->fsEmitFunction(kVec4f_GrSLType,
-                            "light",
-                            SK_ARRAY_COUNT(gLightArgs),
-                            gLightArgs,
-                            lightBody.c_str(),
-                            funcName);
+    builder->getFragmentShaderBuilder()->emitFunction(kVec4f_GrSLType,
+                                                      "light",
+                                                      SK_ARRAY_COUNT(gLightArgs),
+                                                      gLightArgs,
+                                                      lightBody.c_str(),
+                                                      funcName);
 }
 
-void GrGLDiffuseLightingEffect::setData(const GrGLUniformManager& uman,
-                                        const GrDrawEffect& drawEffect) {
-    INHERITED::setData(uman, drawEffect);
-    const GrDiffuseLightingEffect& diffuse = drawEffect.castEffect<GrDiffuseLightingEffect>();
-    uman.set1f(fKDUni, diffuse.kd());
+void GrGLDiffuseLightingEffect::setData(const GrGLProgramDataManager& pdman,
+                                        const GrProcessor& proc) {
+    INHERITED::setData(pdman, proc);
+    const GrDiffuseLightingEffect& diffuse = proc.cast<GrDiffuseLightingEffect>();
+    pdman.set1f(fKDUni, diffuse.kd());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1424,23 +1526,23 @@
       fShininess(shininess) {
 }
 
-const GrBackendEffectFactory& GrSpecularLightingEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrSpecularLightingEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrSpecularLightingEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrSpecularLightingEffect>::getInstance();
 }
 
-bool GrSpecularLightingEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrSpecularLightingEffect& s = CastEffect<GrSpecularLightingEffect>(sBase);
+bool GrSpecularLightingEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrSpecularLightingEffect& s = sBase.cast<GrSpecularLightingEffect>();
     return INHERITED::onIsEqual(sBase) &&
            this->ks() == s.ks() &&
            this->shininess() == s.shininess();
 }
 
-GR_DEFINE_EFFECT_TEST(GrSpecularLightingEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSpecularLightingEffect);
 
-GrEffectRef* GrSpecularLightingEffect::TestCreate(SkRandom* random,
-                                                  GrContext* context,
-                                                  const GrDrawTargetCaps&,
-                                                  GrTexture* textures[]) {
+GrFragmentProcessor* GrSpecularLightingEffect::TestCreate(SkRandom* random,
+                                                          GrContext* context,
+                                                          const GrDrawTargetCaps&,
+                                                          GrTexture* textures[]) {
     SkScalar surfaceScale = random->nextSScalar1();
     SkScalar ks = random->nextUScalar1();
     SkScalar shininess = random->nextUScalar1();
@@ -1449,24 +1551,24 @@
     for (int i = 0; i < 9; i++) {
         matrix[i] = random->nextUScalar1();
     }
-    return GrSpecularLightingEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx],
+    return GrSpecularLightingEffect::Create(textures[GrProcessorUnitTest::kAlphaTextureIdx],
                                             light, surfaceScale, matrix, ks, shininess);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrBackendEffectFactory& factory,
-                                                       const GrDrawEffect& drawEffect)
-    : INHERITED(factory, drawEffect) {
+GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrBackendProcessorFactory& factory,
+                                                       const GrProcessor& proc)
+    : INHERITED(factory, proc) {
 }
 
-void GrGLSpecularLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) {
+void GrGLSpecularLightingEffect::emitLightFunc(GrGLProgramBuilder* builder, SkString* funcName) {
     const char* ks;
     const char* shininess;
 
-    fKSUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fKSUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                  kFloat_GrSLType, "KS", &ks);
-    fShininessUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fShininessUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                         kFloat_GrSLType, "Shininess", &shininess);
 
     static const GrGLShaderVar gLightArgs[] = {
@@ -1479,96 +1581,100 @@
     lightBody.appendf("\tfloat colorScale = %s * pow(dot(normal, halfDir), %s);\n", ks, shininess);
     lightBody.appendf("\tvec3 color = lightColor * clamp(colorScale, 0.0, 1.0);\n");
     lightBody.appendf("\treturn vec4(color, max(max(color.r, color.g), color.b));\n");
-    builder->fsEmitFunction(kVec4f_GrSLType,
-                            "light",
-                            SK_ARRAY_COUNT(gLightArgs),
-                            gLightArgs,
-                            lightBody.c_str(),
-                            funcName);
+    builder->getFragmentShaderBuilder()->emitFunction(kVec4f_GrSLType,
+                                                      "light",
+                                                      SK_ARRAY_COUNT(gLightArgs),
+                                                      gLightArgs,
+                                                      lightBody.c_str(),
+                                                      funcName);
 }
 
-void GrGLSpecularLightingEffect::setData(const GrGLUniformManager& uman,
-                                         const GrDrawEffect& drawEffect) {
-    INHERITED::setData(uman, drawEffect);
-    const GrSpecularLightingEffect& spec = drawEffect.castEffect<GrSpecularLightingEffect>();
-    uman.set1f(fKSUni, spec.ks());
-    uman.set1f(fShininessUni, spec.shininess());
+void GrGLSpecularLightingEffect::setData(const GrGLProgramDataManager& pdman,
+                                         const GrProcessor& effect) {
+    INHERITED::setData(pdman, effect);
+    const GrSpecularLightingEffect& spec = effect.cast<GrSpecularLightingEffect>();
+    pdman.set1f(fKSUni, spec.ks());
+    pdman.set1f(fShininessUni, spec.shininess());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-void GrGLLight::emitLightColorUniform(GrGLShaderBuilder* builder) {
-    fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+void GrGLLight::emitLightColorUniform(GrGLProgramBuilder* builder) {
+    fColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                     kVec3f_GrSLType, "LightColor");
 }
 
-void GrGLLight::emitLightColor(GrGLShaderBuilder* builder,
+void GrGLLight::emitLightColor(GrGLProgramBuilder* builder,
                                const char *surfaceToLight) {
-    builder->fsCodeAppend(builder->getUniformCStr(this->lightColorUni()));
+    builder->getFragmentShaderBuilder()->codeAppend(builder->getUniformCStr(this->lightColorUni()));
 }
 
-void GrGLLight::setData(const GrGLUniformManager& uman,
+void GrGLLight::setData(const GrGLProgramDataManager& pdman,
                         const SkLight* light) const {
-    setUniformPoint3(uman, fColorUni, light->color() * SkScalarInvert(SkIntToScalar(255)));
+    setUniformPoint3(pdman, fColorUni, light->color() * SkScalarInvert(SkIntToScalar(255)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrGLDistantLight::setData(const GrGLUniformManager& uman,
+void GrGLDistantLight::setData(const GrGLProgramDataManager& pdman,
                                const SkLight* light) const {
-    INHERITED::setData(uman, light);
+    INHERITED::setData(pdman, light);
     SkASSERT(light->type() == SkLight::kDistant_LightType);
     const SkDistantLight* distantLight = static_cast<const SkDistantLight*>(light);
-    setUniformNormal3(uman, fDirectionUni, distantLight->direction());
+    setUniformNormal3(pdman, fDirectionUni, distantLight->direction());
 }
 
-void GrGLDistantLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char* z) {
+void GrGLDistantLight::emitSurfaceToLight(GrGLProgramBuilder* builder, const char* z) {
     const char* dir;
-    fDirectionUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec3f_GrSLType,
+    fDirectionUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec3f_GrSLType,
                                         "LightDirection", &dir);
-    builder->fsCodeAppend(dir);
+    builder->getFragmentShaderBuilder()->codeAppend(dir);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrGLPointLight::setData(const GrGLUniformManager& uman,
+void GrGLPointLight::setData(const GrGLProgramDataManager& pdman,
                              const SkLight* light) const {
-    INHERITED::setData(uman, light);
+    INHERITED::setData(pdman, light);
     SkASSERT(light->type() == SkLight::kPoint_LightType);
     const SkPointLight* pointLight = static_cast<const SkPointLight*>(light);
-    setUniformPoint3(uman, fLocationUni, pointLight->location());
+    setUniformPoint3(pdman, fLocationUni, pointLight->location());
 }
 
-void GrGLPointLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char* z) {
+void GrGLPointLight::emitSurfaceToLight(GrGLProgramBuilder* builder, const char* z) {
     const char* loc;
-    fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec3f_GrSLType,
+    fLocationUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec3f_GrSLType,
                                        "LightLocation", &loc);
-    builder->fsCodeAppendf("normalize(%s - vec3(%s.xy, %s))", loc, builder->fragmentPosition(), z);
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    fsBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
+            loc, fsBuilder->fragmentPosition(), z);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrGLSpotLight::setData(const GrGLUniformManager& uman,
+void GrGLSpotLight::setData(const GrGLProgramDataManager& pdman,
                             const SkLight* light) const {
-    INHERITED::setData(uman, light);
+    INHERITED::setData(pdman, light);
     SkASSERT(light->type() == SkLight::kSpot_LightType);
     const SkSpotLight* spotLight = static_cast<const SkSpotLight *>(light);
-    setUniformPoint3(uman, fLocationUni, spotLight->location());
-    uman.set1f(fExponentUni, spotLight->specularExponent());
-    uman.set1f(fCosInnerConeAngleUni, spotLight->cosInnerConeAngle());
-    uman.set1f(fCosOuterConeAngleUni, spotLight->cosOuterConeAngle());
-    uman.set1f(fConeScaleUni, spotLight->coneScale());
-    setUniformNormal3(uman, fSUni, spotLight->s());
+    setUniformPoint3(pdman, fLocationUni, spotLight->location());
+    pdman.set1f(fExponentUni, spotLight->specularExponent());
+    pdman.set1f(fCosInnerConeAngleUni, spotLight->cosInnerConeAngle());
+    pdman.set1f(fCosOuterConeAngleUni, spotLight->cosOuterConeAngle());
+    pdman.set1f(fConeScaleUni, spotLight->coneScale());
+    setUniformNormal3(pdman, fSUni, spotLight->s());
 }
 
-void GrGLSpotLight::emitSurfaceToLight(GrGLShaderBuilder* builder, const char* z) {
+void GrGLSpotLight::emitSurfaceToLight(GrGLProgramBuilder* builder, const char* z) {
     const char* location;
-    fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fLocationUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                        kVec3f_GrSLType, "LightLocation", &location);
-    builder->fsCodeAppendf("normalize(%s - vec3(%s.xy, %s))",
-                           location, builder->fragmentPosition(), z);
+
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    fsBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
+            location, fsBuilder->fragmentPosition(), z);
 }
 
-void GrGLSpotLight::emitLightColor(GrGLShaderBuilder* builder,
+void GrGLSpotLight::emitLightColor(GrGLProgramBuilder* builder,
                                    const char *surfaceToLight) {
 
     const char* color = builder->getUniformCStr(this->lightColorUni()); // created by parent class.
@@ -1578,15 +1684,15 @@
     const char* cosOuter;
     const char* coneScale;
     const char* s;
-    fExponentUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fExponentUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                        kFloat_GrSLType, "Exponent", &exponent);
-    fCosInnerConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fCosInnerConeAngleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                 kFloat_GrSLType, "CosInnerConeAngle", &cosInner);
-    fCosOuterConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fCosOuterConeAngleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                 kFloat_GrSLType, "CosOuterConeAngle", &cosOuter);
-    fConeScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fConeScaleUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                         kFloat_GrSLType, "ConeScale", &coneScale);
-    fSUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fSUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                 kVec3f_GrSLType, "S", &s);
 
     static const GrGLShaderVar gLightColorArgs[] = {
@@ -1603,14 +1709,15 @@
                            color, cosOuter, coneScale);
     lightColorBody.appendf("\t}\n");
     lightColorBody.appendf("\treturn %s;\n", color);
-    builder->fsEmitFunction(kVec3f_GrSLType,
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    fsBuilder->emitFunction(kVec3f_GrSLType,
                             "lightColor",
                             SK_ARRAY_COUNT(gLightColorArgs),
                             gLightColorArgs,
                             lightColorBody.c_str(),
                             &fLightColorFunc);
 
-    builder->fsCodeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight);
+    fsBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight);
 }
 
 #endif
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index ae8b905..ee2bfa6 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -11,9 +11,10 @@
 #include "SkString.h"
 
 #if SK_SUPPORT_GPU
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "GrContext.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 #endif
 
 void SkLumaColorFilter::filterSpan(const SkPMColor src[], int count,
@@ -40,16 +41,17 @@
     return SkNEW(SkLumaColorFilter);
 }
 
-SkLumaColorFilter::SkLumaColorFilter()
-    : INHERITED() {
+SkLumaColorFilter::SkLumaColorFilter() : INHERITED() {}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkLumaColorFilter::SkLumaColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+SkFlattenable* SkLumaColorFilter::CreateProc(SkReadBuffer&) {
+    return SkNEW(SkLumaColorFilter);
 }
 
-SkLumaColorFilter::SkLumaColorFilter(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
-}
-
-void SkLumaColorFilter::flatten(SkWriteBuffer&) const {
-}
+void SkLumaColorFilter::flatten(SkWriteBuffer&) const {}
 
 #ifndef SK_IGNORE_TO_STRING
 void SkLumaColorFilter::toString(SkString* str) const {
@@ -58,17 +60,17 @@
 #endif
 
 #if SK_SUPPORT_GPU
-class LumaColorFilterEffect : public GrEffect {
+class LumaColorFilterEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create() {
-        AutoEffectUnref effect(SkNEW(LumaColorFilterEffect));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create() {
+        GR_CREATE_STATIC_FRAGMENT_PROCESSOR(gLumaEffect, LumaColorFilterEffect, ());
+        return SkRef(gLumaEffect);
     }
 
     static const char* Name() { return "Luminance-to-Alpha"; }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<LumaColorFilterEffect>::getInstance();
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<LumaColorFilterEffect>::getInstance();
     }
 
     virtual void getConstantColorComponents(GrColor* color,
@@ -78,21 +80,18 @@
         *validFlags = kRGB_GrColorComponentFlags;
     }
 
-    class GLEffect : public GrGLEffect {
+    class GLProcessor : public GrGLFragmentProcessor {
     public:
-        GLEffect(const GrBackendEffectFactory& factory,
-                 const GrDrawEffect&)
+        GLProcessor(const GrBackendProcessorFactory& factory,
+                    const GrProcessor&)
         : INHERITED(factory) {
         }
 
-        static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) {
-            // this class always generates the same code.
-            return 0;
-        }
+        static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b) {}
 
-        virtual void emitCode(GrGLShaderBuilder* builder,
-                              const GrDrawEffect&,
-                              EffectKey,
+        virtual void emitCode(GrGLProgramBuilder* builder,
+                              const GrFragmentProcessor&,
+                              const GrProcessorKey&,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -101,27 +100,28 @@
                 inputColor = "vec4(1)";
             }
 
-            builder->fsCodeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
+            GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+            fsBuilder->codeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
                                    SK_ITU_BT709_LUM_COEFF_R,
                                    SK_ITU_BT709_LUM_COEFF_G,
                                    SK_ITU_BT709_LUM_COEFF_B,
                                    inputColor);
-            builder->fsCodeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
+            fsBuilder->codeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
                                    outputColor);
 
         }
 
     private:
-        typedef GrGLEffect INHERITED;
+        typedef GrGLFragmentProcessor INHERITED;
     };
 
 private:
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE {
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE {
         return true;
     }
 };
 
-GrEffectRef* SkLumaColorFilter::asNewEffect(GrContext*) const {
+GrFragmentProcessor* SkLumaColorFilter::asFragmentProcessor(GrContext*) const {
     return LumaColorFilterEffect::Create();
 }
 #endif
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index 99c0176..9d7b918 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -15,38 +15,38 @@
 ////////////////////////////////////////////////////////////////////////////////
 #if SK_SUPPORT_GPU
 #include "effects/GrSingleTextureEffect.h"
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "gl/GrGLSL.h"
 #include "gl/GrGLTexture.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 
 class GrGLMagnifierEffect;
 
 class GrMagnifierEffect : public GrSingleTextureEffect {
 
 public:
-    static GrEffectRef* Create(GrTexture* texture,
-                               float xOffset,
-                               float yOffset,
-                               float xInvZoom,
-                               float yInvZoom,
-                               float xInvInset,
-                               float yInvInset) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrMagnifierEffect, (texture,
-                                                              xOffset,
-                                                              yOffset,
-                                                              xInvZoom,
-                                                              yInvZoom,
-                                                              xInvInset,
-                                                              yInvInset)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* texture,
+                                       float xOffset,
+                                       float yOffset,
+                                       float xInvZoom,
+                                       float yInvZoom,
+                                       float xInvInset,
+                                       float yInvInset) {
+        return SkNEW_ARGS(GrMagnifierEffect, (texture,
+                                              xOffset,
+                                              yOffset,
+                                              xInvZoom,
+                                              yInvZoom,
+                                              xInvInset,
+                                              yInvInset));
     }
 
     virtual ~GrMagnifierEffect() {};
 
     static const char* Name() { return "Magnifier"; }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
     float x_offset() const { return fXOffset; }
@@ -56,7 +56,7 @@
     float x_inv_inset() const { return fXInvInset; }
     float y_inv_inset() const { return fYInvInset; }
 
-    typedef GrGLMagnifierEffect GLEffect;
+    typedef GrGLMagnifierEffect GLProcessor;
 
 private:
     GrMagnifierEffect(GrTexture* texture,
@@ -66,7 +66,7 @@
                       float yInvZoom,
                       float xInvInset,
                       float yInvInset)
-        : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture))
+        : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
         , fXOffset(xOffset)
         , fYOffset(yOffset)
         , fXInvZoom(xInvZoom)
@@ -74,9 +74,9 @@
         , fXInvInset(xInvInset)
         , fYInvInset(yInvInset) {}
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     float fXOffset;
     float fYOffset;
@@ -89,103 +89,105 @@
 };
 
 // For brevity
-typedef GrGLUniformManager::UniformHandle UniformHandle;
+typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 
-class GrGLMagnifierEffect : public GrGLEffect {
+class GrGLMagnifierEffect : public GrGLFragmentProcessor {
 public:
-    GrGLMagnifierEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLMagnifierEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
     UniformHandle       fOffsetVar;
     UniformHandle       fInvZoomVar;
     UniformHandle       fInvInsetVar;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendProcessorFactory& factory,
+                                         const GrProcessor&)
     : INHERITED(factory) {
 }
 
-void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,
-                                   const GrDrawEffect&,
-                                   EffectKey key,
+void GrGLMagnifierEffect::emitCode(GrGLProgramBuilder* builder,
+                                   const GrFragmentProcessor&,
+                                   const GrProcessorKey& key,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TransformedCoordsArray& coords,
                                    const TextureSamplerArray& samplers) {
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
     fOffsetVar = builder->addUniform(
-        GrGLShaderBuilder::kFragment_Visibility |
-        GrGLShaderBuilder::kVertex_Visibility,
+        GrGLProgramBuilder::kFragment_Visibility |
+        GrGLProgramBuilder::kVertex_Visibility,
         kVec2f_GrSLType, "Offset");
     fInvZoomVar = builder->addUniform(
-        GrGLShaderBuilder::kFragment_Visibility |
-        GrGLShaderBuilder::kVertex_Visibility,
+        GrGLProgramBuilder::kFragment_Visibility |
+        GrGLProgramBuilder::kVertex_Visibility,
         kVec2f_GrSLType, "InvZoom");
     fInvInsetVar = builder->addUniform(
-        GrGLShaderBuilder::kFragment_Visibility |
-        GrGLShaderBuilder::kVertex_Visibility,
+        GrGLProgramBuilder::kFragment_Visibility |
+        GrGLProgramBuilder::kVertex_Visibility,
         kVec2f_GrSLType, "InvInset");
 
-    builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
-    builder->fsCodeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n",
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+    fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
+    fsBuilder->codeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n",
                            builder->getUniformCStr(fOffsetVar),
                            coords2D.c_str(),
                            builder->getUniformCStr(fInvZoomVar));
 
-    builder->fsCodeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
+    fsBuilder->codeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
 
-    builder->fsCodeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr(fInvInsetVar));
+    fsBuilder->codeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr(fInvInsetVar));
 
-    builder->fsCodeAppend("\t\tfloat weight = 0.0;\n");
-    builder->fsCodeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
-    builder->fsCodeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n");
-    builder->fsCodeAppend("\t\t\tfloat dist = length(delta);\n");
-    builder->fsCodeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n");
-    builder->fsCodeAppend("\t\t\tweight = min(dist * dist, 1.0);\n");
-    builder->fsCodeAppend("\t\t} else {\n");
-    builder->fsCodeAppend("\t\t\tvec2 delta_squared = delta * delta;\n");
-    builder->fsCodeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared.y), 1.0);\n");
-    builder->fsCodeAppend("\t\t}\n");
+    fsBuilder->codeAppend("\t\tfloat weight = 0.0;\n");
+    fsBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
+    fsBuilder->codeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n");
+    fsBuilder->codeAppend("\t\t\tfloat dist = length(delta);\n");
+    fsBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n");
+    fsBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n");
+    fsBuilder->codeAppend("\t\t} else {\n");
+    fsBuilder->codeAppend("\t\t\tvec2 delta_squared = delta * delta;\n");
+    fsBuilder->codeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared.y), 1.0);\n");
+    fsBuilder->codeAppend("\t\t}\n");
 
-    builder->fsCodeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
-    builder->fsCodeAppend("\t\tvec4 output_color = ");
-    builder->fsAppendTextureLookup(samplers[0], "mix_coord");
-    builder->fsCodeAppend(";\n");
+    fsBuilder->codeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
+    fsBuilder->codeAppend("\t\tvec4 output_color = ");
+    fsBuilder->appendTextureLookup(samplers[0], "mix_coord");
+    fsBuilder->codeAppend(";\n");
 
-    builder->fsCodeAppendf("\t\t%s = output_color;", outputColor);
+    fsBuilder->codeAppendf("\t\t%s = output_color;", outputColor);
     SkString modulate;
     GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
-    builder->fsCodeAppend(modulate.c_str());
+    fsBuilder->codeAppend(modulate.c_str());
 }
 
-void GrGLMagnifierEffect::setData(const GrGLUniformManager& uman,
-                                  const GrDrawEffect& drawEffect) {
-    const GrMagnifierEffect& zoom = drawEffect.castEffect<GrMagnifierEffect>();
-    uman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset());
-    uman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom());
-    uman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset());
+void GrGLMagnifierEffect::setData(const GrGLProgramDataManager& pdman,
+                                  const GrProcessor& effect) {
+    const GrMagnifierEffect& zoom = effect.cast<GrMagnifierEffect>();
+    pdman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset());
+    pdman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom());
+    pdman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset());
 }
 
 /////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrMagnifierEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMagnifierEffect);
 
-GrEffectRef* GrMagnifierEffect::TestCreate(SkRandom* random,
-                                           GrContext* context,
-                                           const GrDrawTargetCaps&,
-                                           GrTexture** textures) {
+GrFragmentProcessor* GrMagnifierEffect::TestCreate(SkRandom* random,
+                                                   GrContext* context,
+                                                   const GrDrawTargetCaps&,
+                                                   GrTexture** textures) {
     GrTexture* texture = textures[0];
     const int kMaxWidth = 200;
     const int kMaxHeight = 200;
@@ -196,7 +198,7 @@
     uint32_t y = random->nextULessThan(kMaxHeight - height);
     uint32_t inset = random->nextULessThan(kMaxInset);
 
-    GrEffectRef* effect = GrMagnifierEffect::Create(
+    GrFragmentProcessor* effect = GrMagnifierEffect::Create(
         texture,
         (float) width / texture->width(),
         (float) height / texture->height(),
@@ -204,18 +206,18 @@
         texture->height() / (float) y,
         (float) inset / texture->width(),
         (float) inset / texture->height());
-    SkASSERT(NULL != effect);
+    SkASSERT(effect);
     return effect;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-const GrBackendEffectFactory& GrMagnifierEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrMagnifierEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrMagnifierEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrMagnifierEffect>::getInstance();
 }
 
-bool GrMagnifierEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrMagnifierEffect& s = CastEffect<GrMagnifierEffect>(sBase);
+bool GrMagnifierEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrMagnifierEffect& s = sBase.cast<GrMagnifierEffect>();
     return (this->texture(0) == s.texture(0) &&
             this->fXOffset == s.fXOffset &&
             this->fYOffset == s.fYOffset &&
@@ -232,6 +234,22 @@
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
+
+SkImageFilter* SkMagnifierImageFilter::Create(const SkRect& srcRect, SkScalar inset,
+                                              SkImageFilter* input) {
+    
+    if (!SkScalarIsFinite(inset) || !SkIsValidRect(srcRect)) {
+        return NULL;
+    }
+    // Negative numbers in src rect are not supported
+    if (srcRect.fLeft < 0 || srcRect.fTop < 0) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkMagnifierImageFilter, (srcRect, inset, input));
+}
+
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkMagnifierImageFilter::SkMagnifierImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     float x = buffer.readScalar();
@@ -245,37 +263,43 @@
                     // Negative numbers in src rect are not supported
                     (fSrcRect.fLeft >= 0) && (fSrcRect.fTop >= 0));
 }
+#endif
 
-// FIXME:  implement single-input semantics
-SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset)
-    : INHERITED(0), fSrcRect(srcRect), fInset(inset) {
+SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset,
+                                               SkImageFilter* input)
+    : INHERITED(1, &input), fSrcRect(srcRect), fInset(inset) {
     SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0);
 }
 
 #if SK_SUPPORT_GPU
-bool SkMagnifierImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture, const SkMatrix&, const SkIRect&) const {
-    if (effect) {
+bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp, GrTexture* texture,
+                                                 const SkMatrix&, const SkIRect&) const {
+    if (fp) {
         SkScalar yOffset = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? fSrcRect.y() :
                            (texture->height() - (fSrcRect.y() + fSrcRect.height()));
         SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1;
-        *effect = GrMagnifierEffect::Create(texture,
-                                            fSrcRect.x() / texture->width(),
-                                            yOffset / texture->height(),
-                                            fSrcRect.width() / texture->width(),
-                                            fSrcRect.height() / texture->height(),
-                                            texture->width() * invInset,
-                                            texture->height() * invInset);
+        *fp = GrMagnifierEffect::Create(texture,
+                                        fSrcRect.x() / texture->width(),
+                                        yOffset / texture->height(),
+                                        fSrcRect.width() / texture->width(),
+                                        fSrcRect.height() / texture->height(),
+                                        texture->width() * invInset,
+                                        texture->height() * invInset);
     }
     return true;
 }
 #endif
 
+SkFlattenable* SkMagnifierImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkRect src;
+    buffer.readRect(&src);
+    return Create(src, buffer.readScalar(), common.getInput(0));
+}
+
 void SkMagnifierImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-    buffer.writeScalar(fSrcRect.x());
-    buffer.writeScalar(fSrcRect.y());
-    buffer.writeScalar(fSrcRect.width());
-    buffer.writeScalar(fSrcRect.height());
+    buffer.writeRect(fSrcRect);
     buffer.writeScalar(fInset);
 }
 
@@ -298,7 +322,7 @@
       return false;
     }
 
-    if (!dst->allocPixels(src.info())) {
+    if (!dst->tryAllocPixels(src.info())) {
         return false;
     }
 
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index ca2cfca..ae29bcb 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -14,24 +14,12 @@
 #include "SkUnPreMultiply.h"
 
 #if SK_SUPPORT_GPU
-#include "gl/GrGLEffect.h"
-#include "effects/GrSingleTextureEffect.h"
-#include "GrTBackendEffectFactory.h"
-#include "GrTexture.h"
-#include "SkMatrix.h"
+#include "effects/GrMatrixConvolutionEffect.h"
 #endif
 
-static bool tile_mode_is_valid(SkMatrixConvolutionImageFilter::TileMode tileMode) {
-    switch (tileMode) {
-    case SkMatrixConvolutionImageFilter::kClamp_TileMode:
-    case SkMatrixConvolutionImageFilter::kRepeat_TileMode:
-    case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode:
-        return true;
-    default:
-        break;
-    }
-    return false;
-}
+// We need to be able to read at most SK_MaxS32 bytes, so divide that
+// by the size of a scalar to know how many scalars we can read.
+static const int32_t gMaxKernelSize = SK_MaxS32 / sizeof(SkScalar);
 
 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(
     const SkISize& kernelSize,
@@ -42,15 +30,16 @@
     TileMode tileMode,
     bool convolveAlpha,
     SkImageFilter* input,
-    const CropRect* cropRect)
-  : INHERITED(input, cropRect),
+    const CropRect* cropRect,
+    uint32_t uniqueID)
+  : INHERITED(1, &input, cropRect, uniqueID),
     fKernelSize(kernelSize),
     fGain(gain),
     fBias(bias),
     fKernelOffset(kernelOffset),
     fTileMode(tileMode),
     fConvolveAlpha(convolveAlpha) {
-    uint32_t size = fKernelSize.fWidth * fKernelSize.fHeight;
+    size_t size = (size_t) sk_64_mul(fKernelSize.width(), fKernelSize.height());
     fKernel = SkNEW_ARRAY(SkScalar, size);
     memcpy(fKernel, kernel, size * sizeof(SkScalar));
     SkASSERT(kernelSize.fWidth >= 1 && kernelSize.fHeight >= 1);
@@ -58,18 +47,53 @@
     SkASSERT(kernelOffset.fY >= 0 && kernelOffset.fY < kernelSize.fHeight);
 }
 
+SkMatrixConvolutionImageFilter* SkMatrixConvolutionImageFilter::Create(
+    const SkISize& kernelSize,
+    const SkScalar* kernel,
+    SkScalar gain,
+    SkScalar bias,
+    const SkIPoint& kernelOffset,
+    TileMode tileMode,
+    bool convolveAlpha,
+    SkImageFilter* input,
+    const CropRect* cropRect,
+    uint32_t uniqueID) {
+    if (kernelSize.width() < 1 || kernelSize.height() < 1) {
+        return NULL;
+    }
+    if (gMaxKernelSize / kernelSize.fWidth < kernelSize.fHeight) {
+        return NULL;
+    }
+    if (!kernel) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkMatrixConvolutionImageFilter, (kernelSize, kernel, gain, bias,
+                                                       kernelOffset, tileMode, convolveAlpha,
+                                                       input, cropRect, uniqueID));
+}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+static bool tile_mode_is_valid(SkMatrixConvolutionImageFilter::TileMode tileMode) {
+    switch (tileMode) {
+        case SkMatrixConvolutionImageFilter::kClamp_TileMode:
+        case SkMatrixConvolutionImageFilter::kRepeat_TileMode:
+        case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode:
+            return true;
+        default:
+            break;
+    }
+    return false;
+}
+
 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(SkReadBuffer& buffer)
     : INHERITED(1, buffer) {
-    // We need to be able to read at most SK_MaxS32 bytes, so divide that
-    // by the size of a scalar to know how many scalars we can read.
-    static const int32_t kMaxSize = SK_MaxS32 / sizeof(SkScalar);
     fKernelSize.fWidth = buffer.readInt();
     fKernelSize.fHeight = buffer.readInt();
     if ((fKernelSize.fWidth >= 1) && (fKernelSize.fHeight >= 1) &&
         // Make sure size won't be larger than a signed int,
         // which would still be extremely large for a kernel,
         // but we don't impose a hard limit for kernel size
-        (kMaxSize / fKernelSize.fWidth >= fKernelSize.fHeight)) {
+        (gMaxKernelSize / fKernelSize.fWidth >= fKernelSize.fHeight)) {
         size_t size = fKernelSize.fWidth * fKernelSize.fHeight;
         fKernel = SkNEW_ARRAY(SkScalar, size);
         SkDEBUGCODE(bool success =) buffer.readScalarArray(fKernel, size);
@@ -90,6 +114,33 @@
                     (fKernelOffset.fX >= 0) && (fKernelOffset.fX < fKernelSize.fWidth) &&
                     (fKernelOffset.fY >= 0) && (fKernelOffset.fY < fKernelSize.fHeight));
 }
+#endif
+
+SkFlattenable* SkMatrixConvolutionImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkISize kernelSize;
+    kernelSize.fWidth = buffer.readInt();
+    kernelSize.fHeight = buffer.readInt();
+    const int count = buffer.getArrayCount();
+
+    const int64_t kernelArea = sk_64_mul(kernelSize.width(), kernelSize.height());
+    if (!buffer.validate(kernelArea == count)) {
+        return NULL;
+    }
+    SkAutoSTArray<16, SkScalar> kernel(count);
+    if (!buffer.readScalarArray(kernel.get(), count)) {
+        return NULL;
+    }
+    SkScalar gain = buffer.readScalar();
+    SkScalar bias = buffer.readScalar();
+    SkIPoint kernelOffset;
+    kernelOffset.fX = buffer.readInt();
+    kernelOffset.fY = buffer.readInt();
+    TileMode tileMode = (TileMode)buffer.readInt();
+    bool convolveAlpha = buffer.readBool();
+    return Create(kernelSize, kernel.get(), gain, bias, kernelOffset, tileMode, convolveAlpha,
+                  common.getInput(0), &common.cropRect(), common.uniqueID());
+}
 
 void SkMatrixConvolutionImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
@@ -240,7 +291,7 @@
         return SkBitmap();
     }
     SkBitmap result;
-    if (!result.allocPixels(src.info())) {
+    if (!result.tryAllocPixels(src.info())) {
         return SkBitmap();
     }
     for (int y = 0; y < src.height(); ++y) {
@@ -282,7 +333,7 @@
         return false;
     }
 
-    if (!result->allocPixels(src.info().makeWH(bounds.width(), bounds.height()))) {
+    if (!result->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height()))) {
         return false;
     }
 
@@ -323,364 +374,38 @@
 
 #if SK_SUPPORT_GPU
 
-///////////////////////////////////////////////////////////////////////////////
-
-class GrGLMatrixConvolutionEffect;
-
-class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
-public:
-    typedef SkMatrixConvolutionImageFilter::TileMode TileMode;
-    static GrEffectRef* Create(GrTexture* texture,
-                               const SkIRect& bounds,
-                               const SkISize& kernelSize,
-                               const SkScalar* kernel,
-                               SkScalar gain,
-                               SkScalar bias,
-                               const SkIPoint& kernelOffset,
-                               TileMode tileMode,
-                               bool convolveAlpha) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
-                                                                      bounds,
-                                                                      kernelSize,
-                                                                      kernel,
-                                                                      gain,
-                                                                      bias,
-                                                                      kernelOffset,
-                                                                      tileMode,
-                                                                      convolveAlpha)));
-        return CreateEffectRef(effect);
-    }
-    virtual ~GrMatrixConvolutionEffect();
-
-    virtual void getConstantColorComponents(GrColor* color,
-                                            uint32_t* validFlags) const SK_OVERRIDE {
-        // TODO: Try to do better?
-        *validFlags = 0;
-    }
-
-    static const char* Name() { return "MatrixConvolution"; }
-    const SkIRect& bounds() const { return fBounds; }
-    const SkISize& kernelSize() const { return fKernelSize; }
-    const float* kernelOffset() const { return fKernelOffset; }
-    const float* kernel() const { return fKernel; }
-    float gain() const { return fGain; }
-    float bias() const { return fBias; }
-    TileMode tileMode() const { return fTileMode; }
-    bool convolveAlpha() const { return fConvolveAlpha; }
-
-    typedef GrGLMatrixConvolutionEffect GLEffect;
-
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-
-private:
-    GrMatrixConvolutionEffect(GrTexture*,
-                              const SkIRect& bounds,
-                              const SkISize& kernelSize,
-                              const SkScalar* kernel,
-                              SkScalar gain,
-                              SkScalar bias,
-                              const SkIPoint& kernelOffset,
-                              TileMode tileMode,
-                              bool convolveAlpha);
-
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
-
-    SkIRect  fBounds;
-    SkISize  fKernelSize;
-    float   *fKernel;
-    float    fGain;
-    float    fBias;
-    float    fKernelOffset[2];
-    TileMode fTileMode;
-    bool     fConvolveAlpha;
-
-    GR_DECLARE_EFFECT_TEST;
-
-    typedef GrSingleTextureEffect INHERITED;
-};
-
-class GrGLMatrixConvolutionEffect : public GrGLEffect {
-public:
-    GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
-                                const GrDrawEffect& effect);
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
-                          const char* outputColor,
-                          const char* inputColor,
-                          const TransformedCoordsArray&,
-                          const TextureSamplerArray&) SK_OVERRIDE;
-
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
-
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
-
-private:
-    typedef GrGLUniformManager::UniformHandle        UniformHandle;
-    typedef SkMatrixConvolutionImageFilter::TileMode TileMode;
-    SkISize             fKernelSize;
-    TileMode            fTileMode;
-    bool                fConvolveAlpha;
-
-    UniformHandle       fBoundsUni;
-    UniformHandle       fKernelUni;
-    UniformHandle       fImageIncrementUni;
-    UniformHandle       fKernelOffsetUni;
-    UniformHandle       fGainUni;
-    UniformHandle       fBiasUni;
-
-    typedef GrGLEffect INHERITED;
-};
-
-GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
-                                                         const GrDrawEffect& drawEffect)
-    : INHERITED(factory) {
-    const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
-    fKernelSize = m.kernelSize();
-    fTileMode = m.tileMode();
-    fConvolveAlpha = m.convolveAlpha();
-}
-
-static void appendTextureLookup(GrGLShaderBuilder* builder,
-                                const GrGLShaderBuilder::TextureSampler& sampler,
-                                const char* coord,
-                                const char* bounds,
-                                SkMatrixConvolutionImageFilter::TileMode tileMode) {
-    SkString clampedCoord;
+static GrTextureDomain::Mode convert_tilemodes(
+        SkMatrixConvolutionImageFilter::TileMode tileMode) {
     switch (tileMode) {
         case SkMatrixConvolutionImageFilter::kClamp_TileMode:
-            clampedCoord.printf("clamp(%s, %s.xy, %s.zw)", coord, bounds, bounds);
-            coord = clampedCoord.c_str();
-            break;
+            return GrTextureDomain::kClamp_Mode;
         case SkMatrixConvolutionImageFilter::kRepeat_TileMode:
-            clampedCoord.printf("mod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", coord, bounds, bounds, bounds, bounds);
-            coord = clampedCoord.c_str();
-            break;
+            return GrTextureDomain::kRepeat_Mode;
         case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode:
-            builder->fsCodeAppendf("clamp(%s, %s.xy, %s.zw) != %s ? vec4(0, 0, 0, 0) : ", coord, bounds, bounds, coord);
-            break;
+            return GrTextureDomain::kDecal_Mode;
+        default:
+            SkASSERT(false);
     }
-    builder->fsAppendTextureLookup(sampler, coord);
+    return GrTextureDomain::kIgnore_Mode;
 }
 
-void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
-                                           const GrDrawEffect&,
-                                           EffectKey key,
-                                           const char* outputColor,
-                                           const char* inputColor,
-                                           const TransformedCoordsArray& coords,
-                                           const TextureSamplerArray& samplers) {
-    sk_ignore_unused_variable(inputColor);
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
-    fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                     kVec4f_GrSLType, "Bounds");
-    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                             kVec2f_GrSLType, "ImageIncrement");
-    fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
-                                             kFloat_GrSLType,
-                                             "Kernel",
-                                             fKernelSize.width() * fKernelSize.height());
-    fKernelOffsetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                             kVec2f_GrSLType, "KernelOffset");
-    fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                   kFloat_GrSLType, "Gain");
-    fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                   kFloat_GrSLType, "Bias");
-
-    const char* bounds = builder->getUniformCStr(fBoundsUni);
-    const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni);
-    const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
-    const char* kernel = builder->getUniformCStr(fKernelUni);
-    const char* gain = builder->getUniformCStr(fGainUni);
-    const char* bias = builder->getUniformCStr(fBiasUni);
-    int kWidth = fKernelSize.width();
-    int kHeight = fKernelSize.height();
-
-    builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n");
-    builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), kernelOffset, imgInc);
-    builder->fsCodeAppendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight);
-    builder->fsCodeAppendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth);
-    builder->fsCodeAppendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth);
-    builder->fsCodeAppendf("\t\t\t\tvec2 coord2 = coord + vec2(x, y) * %s;\n", imgInc);
-    builder->fsCodeAppend("\t\t\t\tvec4 c = ");
-    appendTextureLookup(builder, samplers[0], "coord2", bounds, fTileMode);
-    builder->fsCodeAppend(";\n");
-    if (!fConvolveAlpha) {
-        builder->fsCodeAppend("\t\t\t\tc.rgb /= c.a;\n");
-    }
-    builder->fsCodeAppend("\t\t\t\tsum += c * k;\n");
-    builder->fsCodeAppend("\t\t\t}\n");
-    builder->fsCodeAppend("\t\t}\n");
-    if (fConvolveAlpha) {
-        builder->fsCodeAppendf("\t\t%s = sum * %s + %s;\n", outputColor, gain, bias);
-        builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n",
-            outputColor, outputColor, outputColor);
-    } else {
-        builder->fsCodeAppend("\t\tvec4 c = ");
-        appendTextureLookup(builder, samplers[0], coords2D.c_str(), bounds, fTileMode);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor);
-        builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor, gain, bias);
-        builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
-    }
-}
-
-namespace {
-
-int encodeXY(int x, int y) {
-    SkASSERT(x >= 1 && y >= 1 && x * y <= 32);
-    if (y < x)
-        return 0x40 | encodeXY(y, x);
-    else
-        return (0x40 >> x) | (y - x);
-}
-
-};
-
-GrGLEffect::EffectKey GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                          const GrGLCaps&) {
-    const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
-    EffectKey key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
-    key |= m.tileMode() << 7;
-    key |= m.convolveAlpha() ? 1 << 9 : 0;
-    return key;
-}
-
-void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
-                                          const GrDrawEffect& drawEffect) {
-    const GrMatrixConvolutionEffect& conv = drawEffect.castEffect<GrMatrixConvolutionEffect>();
-    GrTexture& texture = *conv.texture(0);
-    // the code we generated was for a specific kernel size
-    SkASSERT(conv.kernelSize() == fKernelSize);
-    SkASSERT(conv.tileMode() == fTileMode);
-    float imageIncrement[2];
-    float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f;
-    imageIncrement[0] = 1.0f / texture.width();
-    imageIncrement[1] = ySign / texture.height();
-    uman.set2fv(fImageIncrementUni, 1, imageIncrement);
-    uman.set2fv(fKernelOffsetUni, 1, conv.kernelOffset());
-    uman.set1fv(fKernelUni, fKernelSize.width() * fKernelSize.height(), conv.kernel());
-    uman.set1f(fGainUni, conv.gain());
-    uman.set1f(fBiasUni, conv.bias());
-    const SkIRect& bounds = conv.bounds();
-    float left = (float) bounds.left() / texture.width();
-    float top = (float) bounds.top() / texture.height();
-    float right = (float) bounds.right() / texture.width();
-    float bottom = (float) bounds.bottom() / texture.height();
-    if (texture.origin() == kBottomLeft_GrSurfaceOrigin) {
-        uman.set4f(fBoundsUni, left, 1.0f - bottom, right, 1.0f - top);
-    } else {
-        uman.set4f(fBoundsUni, left, top, right, bottom);
-    }
-}
-
-GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
-                                                     const SkIRect& bounds,
-                                                     const SkISize& kernelSize,
-                                                     const SkScalar* kernel,
-                                                     SkScalar gain,
-                                                     SkScalar bias,
-                                                     const SkIPoint& kernelOffset,
-                                                     TileMode tileMode,
-                                                     bool convolveAlpha)
-  : INHERITED(texture, MakeDivByTextureWHMatrix(texture)),
-    fBounds(bounds),
-    fKernelSize(kernelSize),
-    fGain(SkScalarToFloat(gain)),
-    fBias(SkScalarToFloat(bias) / 255.0f),
-    fTileMode(tileMode),
-    fConvolveAlpha(convolveAlpha) {
-    fKernel = new float[kernelSize.width() * kernelSize.height()];
-    for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
-        fKernel[i] = SkScalarToFloat(kernel[i]);
-    }
-    fKernelOffset[0] = static_cast<float>(kernelOffset.x());
-    fKernelOffset[1] = static_cast<float>(kernelOffset.y());
-    this->setWillNotUseInputColor();
-}
-
-GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() {
-    delete[] fKernel;
-}
-
-const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance();
-}
-
-bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrMatrixConvolutionEffect& s = CastEffect<GrMatrixConvolutionEffect>(sBase);
-    return this->texture(0) == s.texture(0) &&
-           fKernelSize == s.kernelSize() &&
-           !memcmp(fKernel, s.kernel(),
-                   fKernelSize.width() * fKernelSize.height() * sizeof(float)) &&
-           fGain == s.gain() &&
-           fBias == s.bias() &&
-           fKernelOffset == s.kernelOffset() &&
-           fTileMode == s.tileMode() &&
-           fConvolveAlpha == s.convolveAlpha();
-}
-
-GR_DEFINE_EFFECT_TEST(GrMatrixConvolutionEffect);
-
-// A little bit less than the minimum # uniforms required by DX9SM2 (32).
-// Allows for a 5x5 kernel (or 25x1, for that matter).
-#define MAX_KERNEL_SIZE 25
-
-GrEffectRef* GrMatrixConvolutionEffect::TestCreate(SkRandom* random,
-                                                   GrContext* context,
-                                                   const GrDrawTargetCaps&,
-                                                   GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
-    int width = random->nextRangeU(1, MAX_KERNEL_SIZE);
-    int height = random->nextRangeU(1, MAX_KERNEL_SIZE / width);
-    SkISize kernelSize = SkISize::Make(width, height);
-    SkAutoTDeleteArray<SkScalar> kernel(new SkScalar[width * height]);
-    for (int i = 0; i < width * height; i++) {
-        kernel.get()[i] = random->nextSScalar1();
-    }
-    SkScalar gain = random->nextSScalar1();
-    SkScalar bias = random->nextSScalar1();
-    SkIPoint kernelOffset = SkIPoint::Make(random->nextRangeU(0, kernelSize.width()),
-                                           random->nextRangeU(0, kernelSize.height()));
-    SkIRect bounds = SkIRect::MakeXYWH(random->nextRangeU(0, textures[texIdx]->width()),
-                                       random->nextRangeU(0, textures[texIdx]->height()),
-                                       random->nextRangeU(0, textures[texIdx]->width()),
-                                       random->nextRangeU(0, textures[texIdx]->height()));
-    TileMode tileMode = static_cast<TileMode>(random->nextRangeU(0, 2));
-    bool convolveAlpha = random->nextBool();
-    return GrMatrixConvolutionEffect::Create(textures[texIdx],
-                                             bounds,
-                                             kernelSize,
-                                             kernel.get(),
-                                             gain,
-                                             bias,
-                                             kernelOffset,
-                                             tileMode,
-                                             convolveAlpha);
-}
-
-bool SkMatrixConvolutionImageFilter::asNewEffect(GrEffectRef** effect,
-                                                 GrTexture* texture,
-                                                 const SkMatrix&,
-                                                 const SkIRect& bounds
-                                                 ) const {
-    if (!effect) {
+bool SkMatrixConvolutionImageFilter::asFragmentProcessor(GrFragmentProcessor** fp,
+                                                         GrTexture* texture,
+                                                         const SkMatrix&,
+                                                         const SkIRect& bounds) const {
+    if (!fp) {
         return fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE;
     }
     SkASSERT(fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE);
-    *effect = GrMatrixConvolutionEffect::Create(texture,
-                                                bounds,
-                                                fKernelSize,
-                                                fKernel,
-                                                fGain,
-                                                fBias,
-                                                fKernelOffset,
-                                                fTileMode,
-                                                fConvolveAlpha);
+    *fp = GrMatrixConvolutionEffect::Create(texture,
+                                            bounds,
+                                            fKernelSize,
+                                            fKernel,
+                                            fGain,
+                                            fBias,
+                                            fKernelOffset,
+                                            convert_tilemodes(fTileMode),
+                                            fConvolveAlpha);
     return true;
 }
-
-///////////////////////////////////////////////////////////////////////////////
-
 #endif
diff --git a/src/effects/SkMatrixImageFilter.cpp b/src/effects/SkMatrixImageFilter.cpp
index 55179d3..34231ba 100644
--- a/src/effects/SkMatrixImageFilter.cpp
+++ b/src/effects/SkMatrixImageFilter.cpp
@@ -17,23 +17,35 @@
 
 SkMatrixImageFilter::SkMatrixImageFilter(const SkMatrix& transform,
                                          SkPaint::FilterLevel filterLevel,
-                                         SkImageFilter* input)
-  : INHERITED(input),
+                                         SkImageFilter* input,
+                                         uint32_t uniqueID)
+  : INHERITED(1, &input, NULL, uniqueID),
     fTransform(transform),
     fFilterLevel(filterLevel) {
 }
 
 SkMatrixImageFilter* SkMatrixImageFilter::Create(const SkMatrix& transform,
                                                  SkPaint::FilterLevel filterLevel,
-                                                 SkImageFilter* input) {
-    return SkNEW_ARGS(SkMatrixImageFilter, (transform, filterLevel, input));
+                                                 SkImageFilter* input,
+                                                 uint32_t uniqueID) {
+    return SkNEW_ARGS(SkMatrixImageFilter, (transform, filterLevel, input, uniqueID));
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkMatrixImageFilter::SkMatrixImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     buffer.readMatrix(&fTransform);
     fFilterLevel = static_cast<SkPaint::FilterLevel>(buffer.readInt());
 }
+#endif
+
+SkFlattenable* SkMatrixImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    SkPaint::FilterLevel level = static_cast<SkPaint::FilterLevel>(buffer.readInt());
+    return Create(matrix, level, common.getInput(0), common.uniqueID());
+}
 
 void SkMatrixImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp
index adf9afe..9e7f4e5 100755
--- a/src/effects/SkMergeImageFilter.cpp
+++ b/src/effects/SkMergeImageFilter.cpp
@@ -40,20 +40,11 @@
     }
 }
 
-SkMergeImageFilter::SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
-                                       SkXfermode::Mode mode,
-                                       const CropRect* cropRect) : INHERITED(first, second, cropRect) {
-    if (SkXfermode::kSrcOver_Mode != mode) {
-        SkXfermode::Mode modes[] = { mode, mode };
-        this->initModes(modes);
-    } else {
-        fModes = NULL;
-    }
-}
-
 SkMergeImageFilter::SkMergeImageFilter(SkImageFilter* filters[], int count,
                                        const SkXfermode::Mode modes[],
-                                       const CropRect* cropRect) : INHERITED(count, filters, cropRect) {
+                                       const CropRect* cropRect,
+                                       uint32_t uniqueID)
+  : INHERITED(count, filters, cropRect, uniqueID) {
     SkASSERT(count >= 0);
     this->initModes(modes);
 }
@@ -116,15 +107,41 @@
     return true;
 }
 
+SkFlattenable* SkMergeImageFilter::CreateProc(SkReadBuffer& buffer) {
+    Common common;
+    if (!common.unflatten(buffer, -1)) {
+        return NULL;
+    }
+
+    const int count = common.inputCount();
+    bool hasModes = buffer.readBool();
+    if (hasModes) {
+        SkAutoSTArray<4, SkXfermode::Mode> modes(count);
+        SkAutoSTArray<4, uint8_t> modes8(count);
+        if (!buffer.readByteArray(modes8.get(), count)) {
+            return NULL;
+        }
+        for (int i = 0; i < count; ++i) {
+            modes[i] = (SkXfermode::Mode)modes8[i];
+            buffer.validate(SkIsValidMode(modes[i]));
+        }
+        if (!buffer.isValid()) {
+            return NULL;
+        }
+        return Create(common.inputs(), count, modes.get(), &common.cropRect(), common.uniqueID());
+    }
+    return Create(common.inputs(), count, NULL, &common.cropRect(), common.uniqueID());
+}
+
 void SkMergeImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-
     buffer.writeBool(fModes != NULL);
     if (fModes) {
         buffer.writeByteArray(fModes, countInputs() * sizeof(fModes[0]));
     }
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkMergeImageFilter::SkMergeImageFilter(SkReadBuffer& buffer)
   : INHERITED(-1, buffer) {
     bool hasModes = buffer.readBool();
@@ -143,3 +160,4 @@
         fModes = 0;
     }
 }
+#endif
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 19a9b68..397e431 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -15,11 +15,13 @@
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
 #include "GrTexture.h"
-#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLEffect.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "effects/Gr1DKernelEffect.h"
 #endif
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkMorphologyImageFilter::SkMorphologyImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fRadius.fWidth = buffer.readInt();
@@ -27,15 +29,16 @@
     buffer.validate((fRadius.fWidth >= 0) &&
                     (fRadius.fHeight >= 0));
 }
+#endif
 
 SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX,
                                                  int radiusY,
                                                  SkImageFilter* input,
-                                                 const CropRect* cropRect)
-    : INHERITED(input, cropRect), fRadius(SkISize::Make(radiusX, radiusY)) {
+                                                 const CropRect* cropRect,
+                                                 uint32_t uniqueID)
+    : INHERITED(1, &input, cropRect, uniqueID), fRadius(SkISize::Make(radiusX, radiusY)) {
 }
 
-
 void SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writeInt(fRadius.fWidth);
@@ -163,7 +166,7 @@
         return false;
     }
 
-    if (!dst->allocPixels(src.info().makeWH(bounds.width(), bounds.height()))) {
+    if (!dst->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height()))) {
         return false;
     }
 
@@ -188,7 +191,7 @@
     }
 
     SkBitmap temp;
-    if (!temp.allocPixels(dst->info())) {
+    if (!temp.tryAllocPixels(dst->info())) {
         return false;
     }
 
@@ -246,17 +249,31 @@
 bool SkMorphologyImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
                                              SkIRect* dst) const {
     SkIRect bounds = src;
-    if (getInput(0) && !getInput(0)->filterBounds(src, ctm, &bounds)) {
-        return false;
-    }
     SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
                                      SkIntToScalar(this->radius().height()));
     ctm.mapVectors(&radius, 1);
     bounds.outset(SkScalarCeilToInt(radius.x()), SkScalarCeilToInt(radius.y()));
+    if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
+        return false;
+    }
     *dst = bounds;
     return true;
 }
 
+SkFlattenable* SkErodeImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    const int width = buffer.readInt();
+    const int height = buffer.readInt();
+    return Create(width, height, common.getInput(0), &common.cropRect(), common.uniqueID());
+}
+
+SkFlattenable* SkDilateImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    const int width = buffer.readInt();
+    const int height = buffer.readInt();
+    return Create(width, height, common.getInput(0), &common.cropRect(), common.uniqueID());
+}
+
 #if SK_SUPPORT_GPU
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -278,9 +295,9 @@
         kDilate_MorphologyType,
     };
 
-    static GrEffectRef* Create(GrTexture* tex, Direction dir, int radius, MorphologyType type) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* tex, Direction dir, int radius,
+                                       MorphologyType type) {
+        return SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type));
     }
 
     virtual ~GrMorphologyEffect();
@@ -289,9 +306,9 @@
 
     static const char* Name() { return "Morphology"; }
 
-    typedef GrGLMorphologyEffect GLEffect;
+    typedef GrGLMorphologyEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 protected:
@@ -299,70 +316,71 @@
     MorphologyType fType;
 
 private:
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     typedef Gr1DKernelEffect INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class GrGLMorphologyEffect : public GrGLEffect {
+class GrGLMorphologyEffect : public GrGLFragmentProcessor {
 public:
-    GrGLMorphologyEffect (const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLMorphologyEffect (const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
     int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); }
 
-    int                                 fRadius;
-    GrMorphologyEffect::MorphologyType  fType;
-    GrGLUniformManager::UniformHandle   fImageIncrementUni;
+    int                                   fRadius;
+    GrMorphologyEffect::MorphologyType    fType;
+    GrGLProgramDataManager::UniformHandle fImageIncrementUni;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendEffectFactory& factory,
-                                           const GrDrawEffect& drawEffect)
+GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendProcessorFactory& factory,
+                                           const GrProcessor& proc)
     : INHERITED(factory) {
-    const GrMorphologyEffect& m = drawEffect.castEffect<GrMorphologyEffect>();
+    const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>();
     fRadius = m.radius();
     fType = m.type();
 }
 
-void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder,
-                                    const GrDrawEffect&,
-                                    EffectKey key,
+void GrGLMorphologyEffect::emitCode(GrGLProgramBuilder* builder,
+                                    const GrFragmentProcessor&,
+                                    const GrProcessorKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray& coords,
                                     const TextureSamplerArray& samplers) {
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
-    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                              kVec2f_GrSLType, "ImageIncrement");
 
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
     const char* func;
     switch (fType) {
         case GrMorphologyEffect::kErode_MorphologyType:
-            builder->fsCodeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", outputColor);
+            fsBuilder->codeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", outputColor);
             func = "min";
             break;
         case GrMorphologyEffect::kDilate_MorphologyType:
-            builder->fsCodeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
+            fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
             func = "max";
             break;
         default:
@@ -372,29 +390,29 @@
     }
     const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
 
-    builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
-    builder->fsCodeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width());
-    builder->fsCodeAppendf("\t\t\t%s = %s(%s, ", outputColor, func, outputColor);
-    builder->fsAppendTextureLookup(samplers[0], "coord");
-    builder->fsCodeAppend(");\n");
-    builder->fsCodeAppendf("\t\t\tcoord += %s;\n", imgInc);
-    builder->fsCodeAppend("\t\t}\n");
+    fsBuilder->codeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
+    fsBuilder->codeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width());
+    fsBuilder->codeAppendf("\t\t\t%s = %s(%s, ", outputColor, func, outputColor);
+    fsBuilder->appendTextureLookup(samplers[0], "coord");
+    fsBuilder->codeAppend(");\n");
+    fsBuilder->codeAppendf("\t\t\tcoord += %s;\n", imgInc);
+    fsBuilder->codeAppend("\t\t}\n");
     SkString modulate;
     GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
-    builder->fsCodeAppend(modulate.c_str());
+    fsBuilder->codeAppend(modulate.c_str());
 }
 
-GrGLEffect::EffectKey GrGLMorphologyEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                   const GrGLCaps&) {
-    const GrMorphologyEffect& m = drawEffect.castEffect<GrMorphologyEffect>();
-    EffectKey key = static_cast<EffectKey>(m.radius());
+void GrGLMorphologyEffect::GenKey(const GrProcessor& proc,
+                                  const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>();
+    uint32_t key = static_cast<uint32_t>(m.radius());
     key |= (m.type() << 8);
-    return key;
+    b->add32(key);
 }
 
-void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman,
-                                   const GrDrawEffect& drawEffect) {
-    const Gr1DKernelEffect& kern = drawEffect.castEffect<Gr1DKernelEffect>();
+void GrGLMorphologyEffect::setData(const GrGLProgramDataManager& pdman,
+                                   const GrProcessor& proc) {
+    const Gr1DKernelEffect& kern = proc.cast<Gr1DKernelEffect>();
     GrTexture& texture = *kern.texture(0);
     // the code we generated was for a specific kernel radius
     SkASSERT(kern.radius() == fRadius);
@@ -409,7 +427,7 @@
         default:
             SkFAIL("Unknown filter direction.");
     }
-    uman.set2fv(fImageIncrementUni, 1, imageIncrement);
+    pdman.set2fv(fImageIncrementUni, 1, imageIncrement);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -425,12 +443,12 @@
 GrMorphologyEffect::~GrMorphologyEffect() {
 }
 
-const GrBackendEffectFactory& GrMorphologyEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrMorphologyEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrMorphologyEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrMorphologyEffect>::getInstance();
 }
 
-bool GrMorphologyEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrMorphologyEffect& s = CastEffect<GrMorphologyEffect>(sBase);
+bool GrMorphologyEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrMorphologyEffect& s = sBase.cast<GrMorphologyEffect>();
     return (this->texture(0) == s.texture(0) &&
             this->radius() == s.radius() &&
             this->direction() == s.direction() &&
@@ -445,14 +463,14 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrMorphologyEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMorphologyEffect);
 
-GrEffectRef* GrMorphologyEffect::TestCreate(SkRandom* random,
-                                            GrContext*,
-                                            const GrDrawTargetCaps&,
-                                            GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
+GrFragmentProcessor* GrMorphologyEffect::TestCreate(SkRandom* random,
+                                                    GrContext*,
+                                                    const GrDrawTargetCaps&,
+                                                    GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                      GrProcessorUnitTest::kAlphaTextureIdx;
     Direction dir = random->nextBool() ? kX_Direction : kY_Direction;
     static const int kMaxRadius = 10;
     int radius = random->nextRangeU(1, kMaxRadius);
@@ -472,10 +490,10 @@
                            GrMorphologyEffect::MorphologyType morphType,
                            Gr1DKernelEffect::Direction direction) {
     GrPaint paint;
-    paint.addColorEffect(GrMorphologyEffect::Create(texture,
-                                                    direction,
-                                                    radius,
-                                                    morphType))->unref();
+    paint.addColorProcessor(GrMorphologyEffect::Create(texture,
+                                                       direction,
+                                                       radius,
+                                                       morphType))->unref();
     context->drawRectToRect(paint, SkRect::Make(dstRect), SkRect::Make(srcRect));
 }
 
@@ -485,7 +503,7 @@
                       SkISize radius,
                       SkBitmap* dst) {
     GrTexture* srcTexture = input.getTexture();
-    SkASSERT(NULL != srcTexture);
+    SkASSERT(srcTexture);
     GrContext* context = srcTexture->getContext();
     srcTexture->ref();
     SkAutoTUnref<GrTexture> src(srcTexture);
@@ -506,6 +524,9 @@
 
     if (radius.fWidth > 0) {
         GrAutoScratchTexture ast(context, desc);
+        if (NULL == ast.texture()) {
+            return false;
+        }
         GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget());
         apply_morphology_pass(context, src, srcRect, dstRect, radius.fWidth,
                               morphType, Gr1DKernelEffect::kX_Direction);
@@ -519,6 +540,9 @@
     }
     if (radius.fHeight > 0) {
         GrAutoScratchTexture ast(context, desc);
+        if (NULL == ast.texture()) {
+            return false;
+        }
         GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget());
         apply_morphology_pass(context, src, srcRect, dstRect, radius.fHeight,
                               morphType, Gr1DKernelEffect::kY_Direction);
diff --git a/src/effects/SkOffsetImageFilter.cpp b/src/effects/SkOffsetImageFilter.cpp
index 7680c62..90528c6 100644
--- a/src/effects/SkOffsetImageFilter.cpp
+++ b/src/effects/SkOffsetImageFilter.cpp
@@ -91,19 +91,29 @@
     return true;
 }
 
+SkFlattenable* SkOffsetImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkPoint offset;
+    buffer.readPoint(&offset);
+    return Create(offset.x(), offset.y(), common.getInput(0), &common.cropRect(), common.uniqueID());
+}
+
 void SkOffsetImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writePoint(fOffset);
 }
 
 SkOffsetImageFilter::SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input,
-                                         const CropRect* cropRect) : INHERITED(input, cropRect) {
+                                         const CropRect* cropRect, uint32_t uniqueID)
+  : INHERITED(1, &input, cropRect, uniqueID) {
     fOffset.set(dx, dy);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkOffsetImageFilter::SkOffsetImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     buffer.readPoint(&fOffset);
     buffer.validate(SkScalarIsFinite(fOffset.fX) &&
                     SkScalarIsFinite(fOffset.fY));
 }
+#endif
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index 84026b6..88e6cad 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -17,8 +17,9 @@
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
 #include "GrCoordTransform.h"
-#include "gl/GrGLEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
+#include "GrTBackendProcessorFactory.h"
 #include "SkGr.h"
 #endif
 
@@ -79,10 +80,19 @@
 
 struct SkPerlinNoiseShader::PaintingData {
     PaintingData(const SkISize& tileSize, SkScalar seed,
-                 SkScalar baseFrequencyX, SkScalar baseFrequencyY)
-      : fTileSize(tileSize)
-      , fBaseFrequency(SkPoint::Make(baseFrequencyX, baseFrequencyY))
+                 SkScalar baseFrequencyX, SkScalar baseFrequencyY,
+                 const SkMatrix& matrix)
     {
+        SkVector wavelength = SkVector::Make(SkScalarInvert(baseFrequencyX),
+                                             SkScalarInvert(baseFrequencyY));
+        matrix.mapVectors(&wavelength, 1);
+        fBaseFrequency.fX = SkScalarInvert(wavelength.fX);
+        fBaseFrequency.fY = SkScalarInvert(wavelength.fY);
+        SkVector sizeVec = SkVector::Make(SkIntToScalar(tileSize.fWidth),
+                                          SkIntToScalar(tileSize.fHeight));
+        matrix.mapVectors(&sizeVec, 1);
+        fTileSize.fWidth = SkScalarRoundToInt(sizeVec.fX);
+        fTileSize.fHeight = SkScalarRoundToInt(sizeVec.fY);
         this->init(seed);
         if (!fTileSize.isEmpty()) {
             this->stitch();
@@ -275,12 +285,10 @@
   , fStitchTiles(!fTileSize.isEmpty())
 {
     SkASSERT(numOctaves >= 0 && numOctaves < 256);
-    fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY));
 }
 
-SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer)
-    : INHERITED(buffer)
-{
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     fType           = (SkPerlinNoiseShader::Type) buffer.readInt();
     fBaseFrequencyX = buffer.readScalar();
     fBaseFrequencyY = buffer.readScalar();
@@ -289,32 +297,47 @@
     fStitchTiles    = buffer.readBool();
     fTileSize.fWidth  = buffer.readInt();
     fTileSize.fHeight = buffer.readInt();
-    fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY));
     buffer.validate(perlin_noise_type_is_valid(fType) &&
                     (fNumOctaves >= 0) && (fNumOctaves <= 255) &&
                     (fStitchTiles != fTileSize.isEmpty()));
 }
+#endif
 
 SkPerlinNoiseShader::~SkPerlinNoiseShader() {
-    // Safety, should have been done in endContext()
-    SkDELETE(fPaintingData);
+}
+
+SkFlattenable* SkPerlinNoiseShader::CreateProc(SkReadBuffer& buffer) {
+    Type type = (Type)buffer.readInt();
+    SkScalar freqX = buffer.readScalar();
+    SkScalar freqY = buffer.readScalar();
+    int octaves = buffer.readInt();
+    SkScalar seed = buffer.readScalar();
+    SkISize tileSize;
+    tileSize.fWidth = buffer.readInt();
+    tileSize.fHeight = buffer.readInt();
+
+    switch (type) {
+        case kFractalNoise_Type:
+            return SkPerlinNoiseShader::CreateFractalNoise(freqX, freqY, octaves, seed, &tileSize);
+        case kTurbulence_Type:
+            return SkPerlinNoiseShader::CreateTubulence(freqX, freqY, octaves, seed, &tileSize);
+        default:
+            return NULL;
+    }
 }
 
 void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeInt((int) fType);
     buffer.writeScalar(fBaseFrequencyX);
     buffer.writeScalar(fBaseFrequencyY);
     buffer.writeInt(fNumOctaves);
     buffer.writeScalar(fSeed);
-    buffer.writeBool(fStitchTiles);
     buffer.writeInt(fTileSize.fWidth);
     buffer.writeInt(fTileSize.fHeight);
 }
 
 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D(
-        int channel, const PaintingData& paintingData,
-        const StitchData& stitchData, const SkPoint& noiseVector) const {
+        int channel, const StitchData& stitchData, const SkPoint& noiseVector) const {
     struct Noise {
         int noisePositionIntegerValue;
         int nextNoisePositionIntegerValue;
@@ -347,9 +370,9 @@
     noiseX.nextNoisePositionIntegerValue &= kBlockMask;
     noiseY.nextNoisePositionIntegerValue &= kBlockMask;
     int i =
-        paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue];
+        fPaintingData->fLatticeSelector[noiseX.noisePositionIntegerValue];
     int j =
-        paintingData.fLatticeSelector[noiseX.nextNoisePositionIntegerValue];
+        fPaintingData->fLatticeSelector[noiseX.nextNoisePositionIntegerValue];
     int b00 = (i + noiseY.noisePositionIntegerValue) & kBlockMask;
     int b10 = (j + noiseY.noisePositionIntegerValue) & kBlockMask;
     int b01 = (i + noiseY.nextNoisePositionIntegerValue) & kBlockMask;
@@ -359,32 +382,31 @@
     // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement
     SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue,
                                           noiseY.noisePositionFractionValue); // Offset (0,0)
-    u = paintingData.fGradient[channel][b00].dot(fractionValue);
+    u = fPaintingData->fGradient[channel][b00].dot(fractionValue);
     fractionValue.fX -= SK_Scalar1; // Offset (-1,0)
-    v = paintingData.fGradient[channel][b10].dot(fractionValue);
+    v = fPaintingData->fGradient[channel][b10].dot(fractionValue);
     SkScalar a = SkScalarInterp(u, v, sx);
     fractionValue.fY -= SK_Scalar1; // Offset (-1,-1)
-    v = paintingData.fGradient[channel][b11].dot(fractionValue);
+    v = fPaintingData->fGradient[channel][b11].dot(fractionValue);
     fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1)
-    u = paintingData.fGradient[channel][b01].dot(fractionValue);
+    u = fPaintingData->fGradient[channel][b01].dot(fractionValue);
     SkScalar b = SkScalarInterp(u, v, sx);
     return SkScalarInterp(a, b, sy);
 }
 
 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValueForPoint(
-        int channel, const PaintingData& paintingData,
-        StitchData& stitchData, const SkPoint& point) const {
+        int channel, StitchData& stitchData, const SkPoint& point) const {
     const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoiseShader&>(fShader);
     if (perlinNoiseShader.fStitchTiles) {
         // Set up TurbulenceInitial stitch values.
-        stitchData = paintingData.fStitchDataInit;
+        stitchData = fPaintingData->fStitchDataInit;
     }
     SkScalar turbulenceFunctionResult = 0;
-    SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), paintingData.fBaseFrequency.fX),
-                                      SkScalarMul(point.y(), paintingData.fBaseFrequency.fY)));
+    SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), fPaintingData->fBaseFrequency.fX),
+                                      SkScalarMul(point.y(), fPaintingData->fBaseFrequency.fY)));
     SkScalar ratio = SK_Scalar1;
     for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) {
-        SkScalar noise = noise2D(channel, paintingData, stitchData, noiseVector);
+        SkScalar noise = noise2D(channel, stitchData, noiseVector);
         turbulenceFunctionResult += SkScalarDiv(
             (perlinNoiseShader.fType == kFractalNoise_Type) ? noise : SkScalarAbs(noise), ratio);
         noiseVector.fX *= 2;
@@ -417,7 +439,6 @@
 
 SkPMColor SkPerlinNoiseShader::PerlinNoiseShaderContext::shade(
         const SkPoint& point, StitchData& stitchData) const {
-    const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoiseShader&>(fShader);
     SkPoint newPoint;
     fMatrix.mapPoints(&newPoint, &point, 1);
     newPoint.fX = SkScalarRoundToScalar(newPoint.fX);
@@ -426,8 +447,7 @@
     U8CPU rgba[4];
     for (int channel = 3; channel >= 0; --channel) {
         rgba[channel] = SkScalarFloorToInt(255 *
-            calculateTurbulenceValueForPoint(channel, *perlinNoiseShader.fPaintingData,
-                                             stitchData, newPoint));
+            calculateTurbulenceValueForPoint(channel, stitchData, newPoint));
     }
     return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
 }
@@ -450,16 +470,14 @@
     if (rec.fLocalMatrix) {
         newMatrix.preConcat(*rec.fLocalMatrix);
     }
-    SkMatrix invMatrix;
-    if (!newMatrix.invert(&invMatrix)) {
-        invMatrix.reset();
-    }
     // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
     // (as opposed to 0 based, usually). The same adjustment is in the setData() function.
-    newMatrix.postTranslate(SK_Scalar1, SK_Scalar1);
-    newMatrix.postConcat(invMatrix);
-    newMatrix.postConcat(invMatrix);
-    fMatrix = newMatrix;
+    fMatrix.setTranslate(-newMatrix.getTranslateX() + SK_Scalar1, -newMatrix.getTranslateY() + SK_Scalar1);
+    fPaintingData = SkNEW_ARGS(PaintingData, (shader.fTileSize, shader.fSeed, shader.fBaseFrequencyX, shader.fBaseFrequencyY, newMatrix));
+}
+
+SkPerlinNoiseShader::PerlinNoiseShaderContext::~PerlinNoiseShaderContext() {
+    SkDELETE(fPaintingData);
 }
 
 void SkPerlinNoiseShader::PerlinNoiseShaderContext::shadeSpan(
@@ -489,134 +507,130 @@
 
 #if SK_SUPPORT_GPU
 
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 
-class GrGLPerlinNoise : public GrGLEffect {
+class GrGLPerlinNoise : public GrGLFragmentProcessor {
 public:
-    GrGLPerlinNoise(const GrBackendEffectFactory& factory,
-                    const GrDrawEffect& drawEffect);
+    GrGLPerlinNoise(const GrBackendProcessorFactory&,
+                    const GrProcessor&);
     virtual ~GrGLPerlinNoise() {}
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b);
 
 private:
 
-    GrGLUniformManager::UniformHandle   fStitchDataUni;
-    SkPerlinNoiseShader::Type           fType;
-    bool                                fStitchTiles;
-    int                                 fNumOctaves;
-    GrGLUniformManager::UniformHandle   fBaseFrequencyUni;
-    GrGLUniformManager::UniformHandle   fAlphaUni;
-    GrGLUniformManager::UniformHandle   fInvMatrixUni;
+    GrGLProgramDataManager::UniformHandle fStitchDataUni;
+    SkPerlinNoiseShader::Type             fType;
+    bool                                  fStitchTiles;
+    int                                   fNumOctaves;
+    GrGLProgramDataManager::UniformHandle fBaseFrequencyUni;
+    GrGLProgramDataManager::UniformHandle fAlphaUni;
 
 private:
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
 /////////////////////////////////////////////////////////////////////
 
-class GrPerlinNoiseEffect : public GrEffect {
+class GrPerlinNoiseEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
-                               int numOctaves, bool stitchTiles,
-                               const SkPerlinNoiseShader::StitchData& stitchData,
-                               GrTexture* permutationsTexture, GrTexture* noiseTexture,
-                               const SkMatrix& matrix, uint8_t alpha) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrPerlinNoiseEffect, (type, baseFrequency, numOctaves,
-            stitchTiles, stitchData, permutationsTexture, noiseTexture, matrix, alpha)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(SkPerlinNoiseShader::Type type,
+                                       int numOctaves, bool stitchTiles,
+                                       SkPerlinNoiseShader::PaintingData* paintingData,
+                                       GrTexture* permutationsTexture, GrTexture* noiseTexture,
+                                       const SkMatrix& matrix, uint8_t alpha) {
+        return SkNEW_ARGS(GrPerlinNoiseEffect, (type, numOctaves, stitchTiles, paintingData,
+                                                permutationsTexture, noiseTexture, matrix, alpha));
     }
 
-    virtual ~GrPerlinNoiseEffect() { }
+    virtual ~GrPerlinNoiseEffect() {
+        SkDELETE(fPaintingData);
+    }
 
     static const char* Name() { return "PerlinNoise"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<GrPerlinNoiseEffect>::getInstance();
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<GrPerlinNoiseEffect>::getInstance();
     }
-    const SkPerlinNoiseShader::StitchData& stitchData() const { return fStitchData; }
+    const SkPerlinNoiseShader::StitchData& stitchData() const { return fPaintingData->fStitchDataInit; }
 
     SkPerlinNoiseShader::Type type() const { return fType; }
     bool stitchTiles() const { return fStitchTiles; }
-    const SkVector& baseFrequency() const { return fBaseFrequency; }
+    const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; }
     int numOctaves() const { return fNumOctaves; }
     const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
     uint8_t alpha() const { return fAlpha; }
 
-    typedef GrGLPerlinNoise GLEffect;
+    typedef GrGLPerlinNoise GLProcessor;
 
 private:
-    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
-        const GrPerlinNoiseEffect& s = CastEffect<GrPerlinNoiseEffect>(sBase);
+    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
+        const GrPerlinNoiseEffect& s = sBase.cast<GrPerlinNoiseEffect>();
         return fType == s.fType &&
-               fBaseFrequency == s.fBaseFrequency &&
+               fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency &&
                fNumOctaves == s.fNumOctaves &&
                fStitchTiles == s.fStitchTiles &&
                fCoordTransform.getMatrix() == s.fCoordTransform.getMatrix() &&
                fAlpha == s.fAlpha &&
                fPermutationsAccess.getTexture() == s.fPermutationsAccess.getTexture() &&
                fNoiseAccess.getTexture() == s.fNoiseAccess.getTexture() &&
-               fStitchData == s.fStitchData;
+               fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataInit;
     }
 
-    GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
+    GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type,
                         int numOctaves, bool stitchTiles,
-                        const SkPerlinNoiseShader::StitchData& stitchData,
+                        SkPerlinNoiseShader::PaintingData* paintingData,
                         GrTexture* permutationsTexture, GrTexture* noiseTexture,
                         const SkMatrix& matrix, uint8_t alpha)
       : fType(type)
-      , fBaseFrequency(baseFrequency)
       , fNumOctaves(numOctaves)
       , fStitchTiles(stitchTiles)
       , fAlpha(alpha)
       , fPermutationsAccess(permutationsTexture)
       , fNoiseAccess(noiseTexture)
-      , fStitchData(stitchData) {
+      , fPaintingData(paintingData) {
         this->addTextureAccess(&fPermutationsAccess);
         this->addTextureAccess(&fNoiseAccess);
-        SkMatrix m = matrix;
-        m.postTranslate(SK_Scalar1, SK_Scalar1);
-        fCoordTransform.reset(kLocal_GrCoordSet, m);
+        fCoordTransform.reset(kLocal_GrCoordSet, matrix);
         this->addCoordTransform(&fCoordTransform);
         this->setWillNotUseInputColor();
     }
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     SkPerlinNoiseShader::Type       fType;
     GrCoordTransform                fCoordTransform;
-    SkVector                        fBaseFrequency;
     int                             fNumOctaves;
     bool                            fStitchTiles;
     uint8_t                         fAlpha;
     GrTextureAccess                 fPermutationsAccess;
     GrTextureAccess                 fNoiseAccess;
-    SkPerlinNoiseShader::StitchData fStitchData;
+    SkPerlinNoiseShader::PaintingData *fPaintingData;
 
     void getConstantColorComponents(GrColor*, uint32_t* validFlags) const SK_OVERRIDE {
         *validFlags = 0; // This is noise. Nothing is constant.
     }
 
 private:
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 /////////////////////////////////////////////////////////////////////
-GR_DEFINE_EFFECT_TEST(GrPerlinNoiseEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrPerlinNoiseEffect);
 
-GrEffectRef* GrPerlinNoiseEffect::TestCreate(SkRandom* random,
-                                             GrContext* context,
-                                             const GrDrawTargetCaps&,
-                                             GrTexture**) {
+GrFragmentProcessor* GrPerlinNoiseEffect::TestCreate(SkRandom* random,
+                                                     GrContext* context,
+                                                     const GrDrawTargetCaps&,
+                                                     GrTexture**) {
     int      numOctaves = random->nextRangeU(2, 10);
     bool     stitchTiles = random->nextBool();
     SkScalar seed = SkIntToScalar(random->nextU());
@@ -633,46 +647,45 @@
                                              stitchTiles ? &tileSize : NULL);
 
     SkPaint paint;
-    GrColor grColor;
-    GrEffectRef* effect;
-    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
+    GrColor paintColor;
+    GrFragmentProcessor* effect;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &effect));
 
     SkDELETE(shader);
 
     return effect;
 }
 
-GrGLPerlinNoise::GrGLPerlinNoise(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
+GrGLPerlinNoise::GrGLPerlinNoise(const GrBackendProcessorFactory& factory,
+                                 const GrProcessor& processor)
   : INHERITED (factory)
-  , fType(drawEffect.castEffect<GrPerlinNoiseEffect>().type())
-  , fStitchTiles(drawEffect.castEffect<GrPerlinNoiseEffect>().stitchTiles())
-  , fNumOctaves(drawEffect.castEffect<GrPerlinNoiseEffect>().numOctaves()) {
+  , fType(processor.cast<GrPerlinNoiseEffect>().type())
+  , fStitchTiles(processor.cast<GrPerlinNoiseEffect>().stitchTiles())
+  , fNumOctaves(processor.cast<GrPerlinNoiseEffect>().numOctaves()) {
 }
 
-void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
-                               const GrDrawEffect&,
-                               EffectKey key,
+void GrGLPerlinNoise::emitCode(GrGLProgramBuilder* builder,
+                               const GrFragmentProcessor&,
+                               const GrProcessorKey& key,
                                const char* outputColor,
                                const char* inputColor,
                                const TransformedCoordsArray& coords,
                                const TextureSamplerArray& samplers) {
     sk_ignore_unused_variable(inputColor);
 
-    SkString vCoords = builder->ensureFSCoords2D(coords, 0);
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString vCoords = fsBuilder->ensureFSCoords2D(coords, 0);
 
-    fInvMatrixUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                        kMat33f_GrSLType, "invMatrix");
-    const char* invMatrixUni = builder->getUniformCStr(fInvMatrixUni);
-    fBaseFrequencyUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fBaseFrequencyUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                             kVec2f_GrSLType, "baseFrequency");
     const char* baseFrequencyUni = builder->getUniformCStr(fBaseFrequencyUni);
-    fAlphaUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fAlphaUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                     kFloat_GrSLType, "alpha");
     const char* alphaUni = builder->getUniformCStr(fAlphaUni);
 
     const char* stitchDataUni = NULL;
     if (fStitchTiles) {
-        fStitchDataUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fStitchDataUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                              kVec2f_GrSLType, "stitchData");
         stitchDataUni = builder->getUniformCStr(fStitchDataUni);
     }
@@ -744,7 +757,7 @@
         xCoords.appendf("vec2(%s.x, 0.5)", floorVal);
 
         noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
-        builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
+        fsBuilder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
         noiseCode.append(".r;");
     }
 
@@ -754,7 +767,7 @@
         xCoords.appendf("vec2(%s.z, 0.5)", floorVal);
 
         noiseCode.appendf("\n\t%s.y = ", latticeIdx);
-        builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
+        fsBuilder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
         noiseCode.append(".r;");
     }
 
@@ -778,7 +791,7 @@
         SkString latticeCoords("");
         latticeCoords.appendf("vec2(%s.x, %s)", bcoords, chanCoord);
         noiseCode.appendf("\n\tvec4 %s = ", lattice);
-        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
+        fsBuilder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
             kVec2f_GrSLType);
         noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
         noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
@@ -790,7 +803,7 @@
         SkString latticeCoords("");
         latticeCoords.appendf("vec2(%s.y, %s)", bcoords, chanCoord);
         noiseCode.append("\n\tlattice = ");
-        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
+        fsBuilder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
             kVec2f_GrSLType);
         noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
         noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
@@ -806,7 +819,7 @@
         SkString latticeCoords("");
         latticeCoords.appendf("vec2(%s.w, %s)", bcoords, chanCoord);
         noiseCode.append("\n\tlattice = ");
-        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
+        fsBuilder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
             kVec2f_GrSLType);
         noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
         noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
@@ -818,7 +831,7 @@
         SkString latticeCoords("");
         latticeCoords.appendf("vec2(%s.z, %s)", bcoords, chanCoord);
         noiseCode.append("\n\tlattice = ");
-        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
+        fsBuilder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
             kVec2f_GrSLType);
         noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
         noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
@@ -831,38 +844,38 @@
 
     SkString noiseFuncName;
     if (fStitchTiles) {
-        builder->fsEmitFunction(kFloat_GrSLType,
+        fsBuilder->emitFunction(kFloat_GrSLType,
                                 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
                                 gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
     } else {
-        builder->fsEmitFunction(kFloat_GrSLType,
+        fsBuilder->emitFunction(kFloat_GrSLType,
                                 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
                                 gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
     }
 
     // There are rounding errors if the floor operation is not performed here
-    builder->fsCodeAppendf("\n\t\tvec2 %s = floor((%s * vec3(%s, 1.0)).xy) * %s;",
-                           noiseVec, invMatrixUni, vCoords.c_str(), baseFrequencyUni);
+    fsBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;",
+                           noiseVec, vCoords.c_str(), baseFrequencyUni);
 
     // Clear the color accumulator
-    builder->fsCodeAppendf("\n\t\t%s = vec4(0.0);", outputColor);
+    fsBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", outputColor);
 
     if (fStitchTiles) {
         // Set up TurbulenceInitial stitch values.
-        builder->fsCodeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
+        fsBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
     }
 
-    builder->fsCodeAppendf("\n\t\tfloat %s = 1.0;", ratio);
+    fsBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio);
 
     // Loop over all octaves
-    builder->fsCodeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
+    fsBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
 
-    builder->fsCodeAppendf("\n\t\t\t%s += ", outputColor);
+    fsBuilder->codeAppendf("\n\t\t\t%s += ", outputColor);
     if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
-        builder->fsCodeAppend("abs(");
+        fsBuilder->codeAppend("abs(");
     }
     if (fStitchTiles) {
-        builder->fsCodeAppendf(
+        fsBuilder->codeAppendf(
             "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s),"
                  "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))",
             noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData,
@@ -870,7 +883,7 @@
             noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData,
             noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData);
     } else {
-        builder->fsCodeAppendf(
+        fsBuilder->codeAppendf(
             "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s),"
                  "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))",
             noiseFuncName.c_str(), chanCoordR, noiseVec,
@@ -879,38 +892,39 @@
             noiseFuncName.c_str(), chanCoordA, noiseVec);
     }
     if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
-        builder->fsCodeAppendf(")"); // end of "abs("
+        fsBuilder->codeAppendf(")"); // end of "abs("
     }
-    builder->fsCodeAppendf(" * %s;", ratio);
+    fsBuilder->codeAppendf(" * %s;", ratio);
 
-    builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
-    builder->fsCodeAppendf("\n\t\t\t%s *= 0.5;", ratio);
+    fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
+    fsBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio);
 
     if (fStitchTiles) {
-        builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
+        fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
     }
-    builder->fsCodeAppend("\n\t\t}"); // end of the for loop on octaves
+    fsBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves
 
     if (fType == SkPerlinNoiseShader::kFractalNoise_Type) {
         // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
         // by fractalNoise and (turbulenceFunctionResult) by turbulence.
-        builder->fsCodeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", outputColor, outputColor);
+        fsBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", outputColor, outputColor);
     }
 
-    builder->fsCodeAppendf("\n\t\t%s.a *= %s;", outputColor, alphaUni);
+    fsBuilder->codeAppendf("\n\t\t%s.a *= %s;", outputColor, alphaUni);
 
     // Clamp values
-    builder->fsCodeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", outputColor, outputColor);
+    fsBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", outputColor, outputColor);
 
     // Pre-multiply the result
-    builder->fsCodeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
+    fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
                   outputColor, outputColor, outputColor, outputColor);
 }
 
-GrGLEffect::EffectKey GrGLPerlinNoise::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
+void GrGLPerlinNoise::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                             GrProcessorKeyBuilder* b) {
+    const GrPerlinNoiseEffect& turbulence = processor.cast<GrPerlinNoiseEffect>();
 
-    EffectKey key = turbulence.numOctaves();
+    uint32_t key = turbulence.numOctaves();
 
     key = key << 3; // Make room for next 3 bits
 
@@ -930,49 +944,42 @@
         key |= 0x4; // Flip the 3rd bit if tile stitching is on
     }
 
-    return key;
+    b->add32(key);
 }
 
-void GrGLPerlinNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
-    INHERITED::setData(uman, drawEffect);
+void GrGLPerlinNoise::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
+    INHERITED::setData(pdman, processor);
 
-    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
+    const GrPerlinNoiseEffect& turbulence = processor.cast<GrPerlinNoiseEffect>();
 
     const SkVector& baseFrequency = turbulence.baseFrequency();
-    uman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
-    uman.set1f(fAlphaUni, SkScalarDiv(SkIntToScalar(turbulence.alpha()), SkIntToScalar(255)));
-
-    SkMatrix m = turbulence.matrix();
-    m.postTranslate(-SK_Scalar1, -SK_Scalar1);
-    SkMatrix invM;
-    if (!m.invert(&invM)) {
-        invM.reset();
-    } else {
-        invM.postConcat(invM); // Square the matrix
-    }
-    uman.setSkMatrix(fInvMatrixUni, invM);
+    pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
+    pdman.set1f(fAlphaUni, SkScalarDiv(SkIntToScalar(turbulence.alpha()), SkIntToScalar(255)));
 
     if (turbulence.stitchTiles()) {
         const SkPerlinNoiseShader::StitchData& stitchData = turbulence.stitchData();
-        uman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth),
+        pdman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth),
                                    SkIntToScalar(stitchData.fHeight));
     }
 }
 
 /////////////////////////////////////////////////////////////////////
 
-bool SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                      const SkMatrix* externalLocalMatrix, GrColor* grColor,
-                                      GrEffectRef** grEffect) const {
-    SkASSERT(NULL != context);
+bool SkPerlinNoiseShader::asFragmentProcessor(GrContext* context, const SkPaint& paint,
+                                              const SkMatrix* externalLocalMatrix,
+                                              GrColor* paintColor, GrFragmentProcessor** fp) const {
+    SkASSERT(context);
     
-    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
-    
+    *paintColor = SkColor2GrColorJustAlpha(paint.getColor());
+
     SkMatrix localMatrix = this->getLocalMatrix();
     if (externalLocalMatrix) {
         localMatrix.preConcat(*externalLocalMatrix);
     }
 
+    SkMatrix matrix = context->getMatrix();
+    matrix.preConcat(localMatrix);
+
     if (0 == fNumOctaves) {
         SkColor clearColor = 0;
         if (kFractalNoise_Type == fType) {
@@ -980,33 +987,42 @@
         }
         SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(
                                                 clearColor, SkXfermode::kSrc_Mode));
-        *grEffect = cf->asNewEffect(context);
+        *fp = cf->asFragmentProcessor(context);
         return true;
     }
 
     // Either we don't stitch tiles, either we have a valid tile size
     SkASSERT(!fStitchTiles || !fTileSize.isEmpty());
 
+    SkPerlinNoiseShader::PaintingData* paintingData =
+            SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY, matrix));
     GrTexture* permutationsTexture = GrLockAndRefCachedBitmapTexture(
-        context, fPaintingData->getPermutationsBitmap(), NULL);
+        context, paintingData->getPermutationsBitmap(), NULL);
     GrTexture* noiseTexture = GrLockAndRefCachedBitmapTexture(
-        context, fPaintingData->getNoiseBitmap(), NULL);
+        context, paintingData->getNoiseBitmap(), NULL);
 
-    *grEffect = (NULL != permutationsTexture) && (NULL != noiseTexture) ?
-        GrPerlinNoiseEffect::Create(fType, fPaintingData->fBaseFrequency,
-                                    fNumOctaves, fStitchTiles,
-                                    fPaintingData->fStitchDataInit,
-                                    permutationsTexture, noiseTexture,
-                                    localMatrix, paint.getAlpha()) :
-        NULL;
+    SkMatrix m = context->getMatrix();
+    m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1);
+    m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1);
+    if ((permutationsTexture) && (noiseTexture)) {
+        *fp = GrPerlinNoiseEffect::Create(fType,
+                                          fNumOctaves,
+                                          fStitchTiles,
+                                          paintingData,
+                                          permutationsTexture, noiseTexture,
+                                          m, paint.getAlpha());
+    } else {
+        SkDELETE(paintingData);
+        *fp = NULL;
+    }
 
     // Unlock immediately, this is not great, but we don't have a way of
     // knowing when else to unlock it currently. TODO: Remove this when
     // unref becomes the unlock replacement for all types of textures.
-    if (NULL != permutationsTexture) {
+    if (permutationsTexture) {
         GrUnlockAndUnrefCachedBitmapTexture(permutationsTexture);
     }
-    if (NULL != noiseTexture) {
+    if (noiseTexture) {
         GrUnlockAndUnrefCachedBitmapTexture(noiseTexture);
     }
 
@@ -1015,9 +1031,8 @@
 
 #else
 
-bool SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                      const SkMatrix* externalLocalMatrix, GrColor* grColor,
-                                      GrEffectRef** grEffect) const {
+bool SkPerlinNoiseShader::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                              GrFragmentProcessor**) const {
     SkDEBUGFAIL("Should not call in GPU-less build");
     return false;
 }
diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp
index 2d2df92..bed19ef 100644
--- a/src/effects/SkPictureImageFilter.cpp
+++ b/src/effects/SkPictureImageFilter.cpp
@@ -12,25 +12,24 @@
 #include "SkWriteBuffer.h"
 #include "SkValidationUtils.h"
 
-SkPictureImageFilter::SkPictureImageFilter(SkPicture* picture)
-  : INHERITED(0, 0),
-    fPicture(picture),
-    fCropRect(SkRect::MakeWH(picture ? SkIntToScalar(picture->width()) : 0,
-                             picture ? SkIntToScalar(picture->height()) : 0)) {
-    SkSafeRef(fPicture);
+SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID)
+    : INHERITED(0, 0, NULL, uniqueID)
+    , fPicture(SkSafeRef(picture))
+    , fCropRect(picture ? picture->cullRect() : SkRect::MakeEmpty()) {
 }
 
-SkPictureImageFilter::SkPictureImageFilter(SkPicture* picture, const SkRect& cropRect)
-  : INHERITED(0, 0),
-    fPicture(picture),
-    fCropRect(cropRect) {
-    SkSafeRef(fPicture);
+SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect,
+                                           uint32_t uniqueID)
+    : INHERITED(0, 0, NULL, uniqueID)
+    , fPicture(SkSafeRef(picture))
+    , fCropRect(cropRect) {
 }
 
 SkPictureImageFilter::~SkPictureImageFilter() {
     SkSafeUnref(fPicture);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkPictureImageFilter::SkPictureImageFilter(SkReadBuffer& buffer)
   : INHERITED(0, buffer),
     fPicture(NULL) {
@@ -43,9 +42,25 @@
     }
     buffer.readRect(&fCropRect);
 }
+#endif
+
+SkFlattenable* SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkPicture> picture;
+    SkRect cropRect;
+
+    if (!buffer.isCrossProcess()) {
+        if (buffer.readBool()) {
+            picture.reset(SkPicture::CreateFromBuffer(buffer));
+        }
+    } else {
+        buffer.validate(!buffer.readBool());
+    }
+    buffer.readRect(&cropRect);
+
+    return Create(picture, cropRect);
+}
 
 void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     if (!buffer.isCrossProcess()) {
         bool hasPicture = (fPicture != NULL);
         buffer.writeBool(hasPicture);
@@ -69,6 +84,9 @@
     SkIRect bounds;
     ctx.ctm().mapRect(&floatBounds, fCropRect);
     floatBounds.roundOut(&bounds);
+    if (!bounds.intersect(ctx.clipBounds())) {
+        return false;
+    }
 
     if (bounds.isEmpty()) {
         offset->fX = offset->fY = 0;
diff --git a/src/effects/SkPixelXorXfermode.cpp b/src/effects/SkPixelXorXfermode.cpp
index 129f182..68b5306 100644
--- a/src/effects/SkPixelXorXfermode.cpp
+++ b/src/effects/SkPixelXorXfermode.cpp
@@ -22,14 +22,18 @@
 }
 
 void SkPixelXorXfermode::flatten(SkWriteBuffer& wb) const {
-    this->INHERITED::flatten(wb);
     wb.writeColor(fOpColor);
 }
 
-SkPixelXorXfermode::SkPixelXorXfermode(SkReadBuffer& rb)
-        : INHERITED(rb) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkPixelXorXfermode::SkPixelXorXfermode(SkReadBuffer& rb) : INHERITED(rb) {
     fOpColor = rb.readColor();
 }
+#endif
+
+SkFlattenable* SkPixelXorXfermode::CreateProc(SkReadBuffer& buffer) {
+    return Create(buffer.readColor());
+}
 
 #ifndef SK_IGNORE_TO_STRING
 void SkPixelXorXfermode::toString(SkString* str) const {
diff --git a/src/effects/SkRectShaderImageFilter.cpp b/src/effects/SkRectShaderImageFilter.cpp
index bed017c..fb34ed0 100644
--- a/src/effects/SkRectShaderImageFilter.cpp
+++ b/src/effects/SkRectShaderImageFilter.cpp
@@ -23,26 +23,34 @@
     return SkNEW_ARGS(SkRectShaderImageFilter, (s, &cropRect));
 }
 
-SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const CropRect* cropRect) {
+SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const CropRect* cropRect, uint32_t uniqueID) {
     SkASSERT(s);
-    return SkNEW_ARGS(SkRectShaderImageFilter, (s, cropRect));
+    return SkNEW_ARGS(SkRectShaderImageFilter, (s, cropRect, uniqueID));
 }
 
-SkRectShaderImageFilter::SkRectShaderImageFilter(SkShader* s, const CropRect* cropRect)
-  : INHERITED(NULL, cropRect)
+SkRectShaderImageFilter::SkRectShaderImageFilter(SkShader* s, const CropRect* cropRect,
+                                                 uint32_t uniqueID)
+  : INHERITED(0, NULL, cropRect, uniqueID)
   , fShader(s) {
     SkASSERT(s);
     s->ref();
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkRectShaderImageFilter::SkRectShaderImageFilter(SkReadBuffer& buffer)
-  : INHERITED(1, buffer) {
+  : INHERITED(0, buffer) {
     fShader = buffer.readShader();
 }
+#endif
+
+SkFlattenable* SkRectShaderImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
+    SkAutoTUnref<SkShader> shader(buffer.readShader());
+    return Create(shader.get(), &common.cropRect(), common.uniqueID());
+}
 
 void SkRectShaderImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-
     buffer.writeFlattenable(fShader);
 }
 
diff --git a/src/effects/SkStippleMaskFilter.cpp b/src/effects/SkStippleMaskFilter.cpp
deleted file mode 100644
index 4aceb11..0000000
--- a/src/effects/SkStippleMaskFilter.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkStippleMaskFilter.h"
-#include "SkString.h"
-
-bool SkStippleMaskFilter::filterMask(SkMask* dst,
-                                     const SkMask& src,
-                                     const SkMatrix& matrix,
-                                     SkIPoint* margin) const {
-
-    if (src.fFormat != SkMask::kA8_Format) {
-        return false;
-    }
-
-    dst->fBounds = src.fBounds;
-    dst->fRowBytes = dst->fBounds.width();
-    dst->fFormat = SkMask::kA8_Format;
-    dst->fImage = NULL;
-
-    if (NULL != src.fImage) {
-        size_t dstSize = dst->computeImageSize();
-        if (0 == dstSize) {
-            return false;   // too big to allocate, abort
-        }
-
-        dst->fImage = SkMask::AllocImage(dstSize);
-
-        uint8_t* srcScanLine = src.fImage;
-        uint8_t* scanline = dst->fImage;
-
-        for (int y = 0; y < src.fBounds.height(); ++y) {
-            for (int x = 0; x < src.fBounds.width(); ++x) {
-                scanline[x] = srcScanLine[x] && ((x+y) & 0x1) ? 0xFF : 0x00;
-            }
-            scanline += dst->fRowBytes;
-            srcScanLine += src.fRowBytes;
-        }
-    }
-
-    return true;
-}
-
-#ifndef SK_IGNORE_TO_STRING
-void SkStippleMaskFilter::toString(SkString* str) const {
-    str->append("SkStippleMaskFilter: ()");
-}
-#endif
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 6a9ab10..4853f73 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -43,7 +43,7 @@
     virtual bool asComponentTable(SkBitmap* table) const SK_OVERRIDE;
 
 #if SK_SUPPORT_GPU
-    virtual GrEffectRef* asNewEffect(GrContext* context) const SK_OVERRIDE;
+    virtual GrFragmentProcessor* asFragmentProcessor(GrContext* context) const SK_OVERRIDE;
 #endif
 
     virtual void filterSpan(const SkPMColor src[], int count,
@@ -61,7 +61,9 @@
     };
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkTable_ColorFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
@@ -70,6 +72,8 @@
     uint8_t fStorage[256 * 4];
     unsigned fFlags;
 
+    friend class SkTableColorFilter;
+
     typedef SkColorFilter INHERITED;
 };
 
@@ -168,19 +172,62 @@
 #include "SkPackBits.h"
 
 void SkTable_ColorFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
     uint8_t storage[5*256];
     int count = gCountNibBits[fFlags & 0xF];
     size_t size = SkPackBits::Pack8(fStorage, count * 256, storage);
     SkASSERT(size <= sizeof(storage));
 
-//    SkDebugf("raw %d packed %d\n", count * 256, size);
-
-    buffer.writeInt(fFlags);
+    buffer.write32(fFlags);
     buffer.writeByteArray(storage, size);
 }
 
+SkFlattenable* SkTable_ColorFilter::CreateProc(SkReadBuffer& buffer) {
+    const int flags = buffer.read32();
+    const size_t count = gCountNibBits[flags & 0xF];
+    SkASSERT(count <= 4);
+
+    uint8_t packedStorage[5*256];
+    size_t packedSize = buffer.getArrayCount();
+    if (!buffer.validate(packedSize <= sizeof(packedStorage))) {
+        return NULL;
+    }
+    if (!buffer.readByteArray(packedStorage, packedSize)) {
+        return NULL;
+    }
+
+    uint8_t unpackedStorage[4*256];
+    size_t unpackedSize = SkPackBits::Unpack8(packedStorage, packedSize, unpackedStorage);
+    // now check that we got the size we expected
+    if (!buffer.validate(unpackedSize == count*256)) {
+        return NULL;
+    }
+
+    const uint8_t* a = NULL;
+    const uint8_t* r = NULL;
+    const uint8_t* g = NULL;
+    const uint8_t* b = NULL;
+    const uint8_t* ptr = unpackedStorage;
+
+    if (flags & kA_Flag) {
+        a = ptr;
+        ptr += 256;
+    }
+    if (flags & kR_Flag) {
+        r = ptr;
+        ptr += 256;
+    }
+    if (flags & kG_Flag) {
+        g = ptr;
+        ptr += 256;
+    }
+    if (flags & kB_Flag) {
+        b = ptr;
+        ptr += 256;
+    }
+    return SkTableColorFilter::CreateARGB(a, r, g, b);
+}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkTable_ColorFilter::SkTable_ColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {
     fBitmap = NULL;
 
@@ -199,6 +246,7 @@
     SkDEBUGCODE(size_t count = gCountNibBits[fFlags & 0xF]);
     SkASSERT(raw == count * 256);
 }
+#endif
 
 bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
     if (table) {
@@ -227,71 +275,71 @@
 
 #if SK_SUPPORT_GPU
 
-#include "GrEffect.h"
-#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLEffect.h"
+#include "GrProcessor.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "SkGr.h"
 
 class GLColorTableEffect;
 
-class ColorTableEffect : public GrEffect {
+class ColorTableEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create(GrTexture* texture, unsigned flags) {
-        AutoEffectUnref effect(SkNEW_ARGS(ColorTableEffect, (texture, flags)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* texture, unsigned flags) {
+        return SkNEW_ARGS(ColorTableEffect, (texture, flags));
     }
 
     virtual ~ColorTableEffect();
 
     static const char* Name() { return "ColorTable"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    typedef GLColorTableEffect GLEffect;
+    typedef GLColorTableEffect GLProcessor;
 
 private:
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     explicit ColorTableEffect(GrTexture* texture, unsigned flags);
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     GrTextureAccess fTextureAccess;
     unsigned        fFlags; // currently not used in shader code, just to assist
                             // getConstantColorComponents().
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
-class GLColorTableEffect : public GrGLEffect {
+class GLColorTableEffect : public GrGLFragmentProcessor {
 public:
-    GLColorTableEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GLColorTableEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b) {}
 
 private:
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GLColorTableEffect::GLColorTableEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+GLColorTableEffect::GLColorTableEffect(const GrBackendProcessorFactory& factory, const GrProcessor&)
     : INHERITED(factory) {
  }
 
-void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
-                                  const GrDrawEffect&,
-                                  EffectKey,
+void GLColorTableEffect::emitCode(GrGLProgramBuilder* builder,
+                                  const GrFragmentProcessor&,
+                                  const GrProcessorKey&,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TransformedCoordsArray&,
@@ -299,42 +347,39 @@
 
     static const float kColorScaleFactor = 255.0f / 256.0f;
     static const float kColorOffsetFactor = 1.0f / 512.0f;
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
     if (NULL == inputColor) {
         // the input color is solid white (all ones).
         static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
-        builder->fsCodeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
+        fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
                                kMaxValue, kMaxValue, kMaxValue, kMaxValue);
 
     } else {
-        builder->fsCodeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
-        builder->fsCodeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
-        builder->fsCodeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
+        fsBuilder->codeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", inputColor);
+        fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n", inputColor);
+        fsBuilder->codeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
                               kColorScaleFactor,
                               kColorOffsetFactor, kColorOffsetFactor,
                               kColorOffsetFactor, kColorOffsetFactor);
     }
 
-    builder->fsCodeAppendf("\t\t%s.a = ", outputColor);
-    builder->fsAppendTextureLookup(samplers[0], "vec2(coord.a, 0.125)");
-    builder->fsCodeAppend(";\n");
+    fsBuilder->codeAppendf("\t\t%s.a = ", outputColor);
+    fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.a, 0.125)");
+    fsBuilder->codeAppend(";\n");
 
-    builder->fsCodeAppendf("\t\t%s.r = ", outputColor);
-    builder->fsAppendTextureLookup(samplers[0], "vec2(coord.r, 0.375)");
-    builder->fsCodeAppend(";\n");
+    fsBuilder->codeAppendf("\t\t%s.r = ", outputColor);
+    fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.r, 0.375)");
+    fsBuilder->codeAppend(";\n");
 
-    builder->fsCodeAppendf("\t\t%s.g = ", outputColor);
-    builder->fsAppendTextureLookup(samplers[0], "vec2(coord.g, 0.625)");
-    builder->fsCodeAppend(";\n");
+    fsBuilder->codeAppendf("\t\t%s.g = ", outputColor);
+    fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.g, 0.625)");
+    fsBuilder->codeAppend(";\n");
 
-    builder->fsCodeAppendf("\t\t%s.b = ", outputColor);
-    builder->fsAppendTextureLookup(samplers[0], "vec2(coord.b, 0.875)");
-    builder->fsCodeAppend(";\n");
+    fsBuilder->codeAppendf("\t\t%s.b = ", outputColor);
+    fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.b, 0.875)");
+    fsBuilder->codeAppend(";\n");
 
-    builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
-}
-
-GrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrDrawEffect&, const GrGLCaps&) {
-    return 0;
+    fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -348,11 +393,11 @@
 ColorTableEffect::~ColorTableEffect() {
 }
 
-const GrBackendEffectFactory&  ColorTableEffect::getFactory() const {
-    return GrTBackendEffectFactory<ColorTableEffect>::getInstance();
+const GrBackendFragmentProcessorFactory&  ColorTableEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<ColorTableEffect>::getInstance();
 }
 
-bool ColorTableEffect::onIsEqual(const GrEffect& sBase) const {
+bool ColorTableEffect::onIsEqual(const GrProcessor& sBase) const {
     return this->texture(0) == sBase.texture(0);
 }
 
@@ -376,32 +421,32 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(ColorTableEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorTableEffect);
 
-GrEffectRef* ColorTableEffect::TestCreate(SkRandom* random,
-                                          GrContext* context,
-                                          const GrDrawTargetCaps&,
-                                          GrTexture* textures[]) {
+GrFragmentProcessor* ColorTableEffect::TestCreate(SkRandom* random,
+                                                  GrContext* context,
+                                                  const GrDrawTargetCaps&,
+                                                  GrTexture* textures[]) {
     static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag |
                                 SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag;
-    return ColorTableEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags);
+    return ColorTableEffect::Create(textures[GrProcessorUnitTest::kAlphaTextureIdx], kAllFlags);
 }
 
-GrEffectRef* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
+GrFragmentProcessor* SkTable_ColorFilter::asFragmentProcessor(GrContext* context) const {
     SkBitmap bitmap;
-    GrEffectRef* effect = NULL;
+    GrFragmentProcessor* fp = NULL;
     this->asComponentTable(&bitmap);
     // passing NULL because this effect does no tiling or filtering.
     GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, bitmap, NULL);
-    if (NULL != texture) {
-        effect = ColorTableEffect::Create(texture, fFlags);
+    if (texture) {
+        fp = ColorTableEffect::Create(texture, fFlags);
 
         // Unlock immediately, this is not great, but we don't have a way of
         // knowing when else to unlock it currently. TODO: Remove this when
         // unref becomes the unlock replacement for all types of textures.
         GrUnlockAndUnrefCachedBitmapTexture(texture);
     }
-    return effect;
+    return fp;
 }
 
 #endif // SK_SUPPORT_GPU
diff --git a/src/effects/SkTableMaskFilter.cpp b/src/effects/SkTableMaskFilter.cpp
index 602302e..42b4ab6 100644
--- a/src/effects/SkTableMaskFilter.cpp
+++ b/src/effects/SkTableMaskFilter.cpp
@@ -71,15 +71,23 @@
 }
 
 void SkTableMaskFilter::flatten(SkWriteBuffer& wb) const {
-    this->INHERITED::flatten(wb);
     wb.writeByteArray(fTable, 256);
 }
 
-SkTableMaskFilter::SkTableMaskFilter(SkReadBuffer& rb)
-        : INHERITED(rb) {
+SkFlattenable* SkTableMaskFilter::CreateProc(SkReadBuffer& buffer) {
+    uint8_t table[256];
+    if (!buffer.readByteArray(table, 256)) {
+        return NULL;
+    }
+    return Create(table);
+}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkTableMaskFilter::SkTableMaskFilter(SkReadBuffer& rb) : INHERITED(rb) {
     SkASSERT(256 == rb.getArrayCount());
     rb.readByteArray(fTable, 256);
 }
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/effects/SkTestImageFilters.cpp b/src/effects/SkTestImageFilters.cpp
index da88316..a414c92 100755
--- a/src/effects/SkTestImageFilters.cpp
+++ b/src/effects/SkTestImageFilters.cpp
@@ -71,14 +71,20 @@
     return true;
 }
 
+SkFlattenable* SkDownSampleImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    return Create(buffer.readScalar(), common.getInput(0));
+}
+
 void SkDownSampleImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-
     buffer.writeScalar(fScale);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDownSampleImageFilter::SkDownSampleImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fScale = buffer.readScalar();
     buffer.validate(SkScalarIsFinite(fScale));
 }
+#endif
diff --git a/src/effects/SkTileImageFilter.cpp b/src/effects/SkTileImageFilter.cpp
index 73c0a58..bebf8f0 100644
--- a/src/effects/SkTileImageFilter.cpp
+++ b/src/effects/SkTileImageFilter.cpp
@@ -16,6 +16,14 @@
 #include "SkShader.h"
 #include "SkValidationUtils.h"
 
+SkTileImageFilter* SkTileImageFilter::Create(const SkRect& srcRect, const SkRect& dstRect,
+                                             SkImageFilter* input, uint32_t uniqueID) {
+    if (!SkIsValidRect(srcRect) || !SkIsValidRect(dstRect)) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkTileImageFilter, (srcRect, dstRect, input, uniqueID));
+}
+
 bool SkTileImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
                                       const Context& ctx,
                                       SkBitmap* dst, SkIPoint* offset) const {
@@ -86,12 +94,22 @@
     return true;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkTileImageFilter::SkTileImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     buffer.readRect(&fSrcRect);
     buffer.readRect(&fDstRect);
     buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
 }
+#endif
+
+SkFlattenable* SkTileImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkRect src, dst;
+    buffer.readRect(&src);
+    buffer.readRect(&dst);
+    return Create(src, dst, common.getInput(0), common.uniqueID());
+}
 
 void SkTileImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/SkTransparentShader.cpp b/src/effects/SkTransparentShader.cpp
index f290d0d..aab5a3d 100644
--- a/src/effects/SkTransparentShader.cpp
+++ b/src/effects/SkTransparentShader.cpp
@@ -115,6 +115,10 @@
     }
 }
 
+SkFlattenable* SkTransparentShader::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW(SkTransparentShader);
+}
+
 #ifndef SK_IGNORE_TO_STRING
 void SkTransparentShader::toString(SkString* str) const {
     str->append("SkTransparentShader: (");
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index acb8fd3..bca5223 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -21,10 +21,10 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 SkXfermodeImageFilter::SkXfermodeImageFilter(SkXfermode* mode,
-                                             SkImageFilter* background,
-                                             SkImageFilter* foreground,
-                                             const CropRect* cropRect)
-  : INHERITED(background, foreground, cropRect), fMode(mode) {
+                                             SkImageFilter* inputs[2],
+                                             const CropRect* cropRect,
+                                             uint32_t uniqueID)
+  : INHERITED(2, inputs, cropRect, uniqueID), fMode(mode) {
     SkSafeRef(fMode);
 }
 
@@ -32,10 +32,18 @@
     SkSafeUnref(fMode);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkXfermodeImageFilter::SkXfermodeImageFilter(SkReadBuffer& buffer)
   : INHERITED(2, buffer) {
     fMode = buffer.readXfermode();
 }
+#endif
+
+SkFlattenable* SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
+    SkAutoTUnref<SkXfermode> mode(buffer.readXfermode());
+    return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect(), common.uniqueID());
+}
 
 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
@@ -100,7 +108,7 @@
 #if SK_SUPPORT_GPU
 
 bool SkXfermodeImageFilter::canFilterImageGPU() const {
-    return fMode && fMode->asNewEffect(NULL, NULL) && !cropRectIsSet();
+    return fMode && fMode->asFragmentProcessor(NULL, NULL) && !cropRectIsSet();
 }
 
 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
@@ -124,7 +132,7 @@
     GrTexture* foregroundTex = foreground.getTexture();
     GrContext* context = foregroundTex->getContext();
 
-    GrEffectRef* xferEffect = NULL;
+    GrFragmentProcessor* xferProcessor = NULL;
 
     GrTextureDesc desc;
     desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
@@ -133,17 +141,20 @@
     desc.fConfig = kSkia8888_GrPixelConfig;
 
     GrAutoScratchTexture ast(context, desc);
+    if (NULL == ast.texture()) {
+        return false;
+    }
     SkAutoTUnref<GrTexture> dst(ast.detach());
 
     GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
 
-    if (!fMode || !fMode->asNewEffect(&xferEffect, backgroundTex)) {
+    if (!fMode || !fMode->asFragmentProcessor(&xferProcessor, backgroundTex)) {
         // canFilterImageGPU() should've taken care of this
         SkASSERT(false);
         return false;
     }
 
-    SkMatrix foregroundMatrix = GrEffect::MakeDivByTextureWHMatrix(foregroundTex);
+    SkMatrix foregroundMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(foregroundTex);
     foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOffset.fX),
                                   SkIntToScalar(backgroundOffset.fY-foregroundOffset.fY));
 
@@ -152,8 +163,8 @@
     src.getBounds(&srcRect);
 
     GrPaint paint;
-    paint.addColorTextureEffect(foregroundTex, foregroundMatrix);
-    paint.addColorEffect(xferEffect)->unref();
+    paint.addColorTextureProcessor(foregroundTex, foregroundMatrix);
+    paint.addColorProcessor(xferProcessor)->unref();
     context->drawRect(paint, srcRect);
 
     offset->fX = backgroundOffset.fX;
diff --git a/src/effects/gradients/SkBitmapCache.cpp b/src/effects/gradients/SkGradientBitmapCache.cpp
similarity index 84%
rename from src/effects/gradients/SkBitmapCache.cpp
rename to src/effects/gradients/SkGradientBitmapCache.cpp
index 95175e4..63d708b 100644
--- a/src/effects/gradients/SkBitmapCache.cpp
+++ b/src/effects/gradients/SkGradientBitmapCache.cpp
@@ -7,9 +7,9 @@
  */
 
 
-#include "SkBitmapCache.h"
+#include "SkGradientBitmapCache.h"
 
-struct SkBitmapCache::Entry {
+struct SkGradientBitmapCache::Entry {
     Entry*      fPrev;
     Entry*      fNext;
 
@@ -33,14 +33,14 @@
     }
 };
 
-SkBitmapCache::SkBitmapCache(int max) : fMaxEntries(max) {
+SkGradientBitmapCache::SkGradientBitmapCache(int max) : fMaxEntries(max) {
     fEntryCount = 0;
     fHead = fTail = NULL;
 
     this->validate();
 }
 
-SkBitmapCache::~SkBitmapCache() {
+SkGradientBitmapCache::~SkGradientBitmapCache() {
     this->validate();
 
     Entry* entry = fHead;
@@ -51,7 +51,7 @@
     }
 }
 
-SkBitmapCache::Entry* SkBitmapCache::detach(Entry* entry) const {
+SkGradientBitmapCache::Entry* SkGradientBitmapCache::detach(Entry* entry) const {
     if (entry->fPrev) {
         SkASSERT(fHead != entry);
         entry->fPrev->fNext = entry->fNext;
@@ -69,7 +69,7 @@
     return entry;
 }
 
-void SkBitmapCache::attachToHead(Entry* entry) const {
+void SkGradientBitmapCache::attachToHead(Entry* entry) const {
     entry->fPrev = NULL;
     entry->fNext = fHead;
     if (fHead) {
@@ -80,7 +80,7 @@
     fHead = entry;
 }
 
-bool SkBitmapCache::find(const void* buffer, size_t size, SkBitmap* bm) const {
+bool SkGradientBitmapCache::find(const void* buffer, size_t size, SkBitmap* bm) const {
     AutoValidate av(this);
 
     Entry* entry = fHead;
@@ -99,7 +99,7 @@
     return false;
 }
 
-void SkBitmapCache::add(const void* buffer, size_t len, const SkBitmap& bm) {
+void SkGradientBitmapCache::add(const void* buffer, size_t len, const SkBitmap& bm) {
     AutoValidate av(this);
 
     if (fEntryCount == fMaxEntries) {
@@ -117,7 +117,7 @@
 
 #ifdef SK_DEBUG
 
-void SkBitmapCache::validate() const {
+void SkGradientBitmapCache::validate() const {
     SkASSERT(fEntryCount >= 0 && fEntryCount <= fMaxEntries);
 
     if (fEntryCount > 0) {
diff --git a/src/effects/gradients/SkBitmapCache.h b/src/effects/gradients/SkGradientBitmapCache.h
similarity index 69%
rename from src/effects/gradients/SkBitmapCache.h
rename to src/effects/gradients/SkGradientBitmapCache.h
index d2af5e1..009b956 100644
--- a/src/effects/gradients/SkBitmapCache.h
+++ b/src/effects/gradients/SkGradientBitmapCache.h
@@ -7,15 +7,15 @@
  */
 
 
-#ifndef SkBitmapCache_DEFINED
-#define SkBitmapCache_DEFINED
+#ifndef SkGradientBitmapCache_DEFINED
+#define SkGradientBitmapCache_DEFINED
 
 #include "SkBitmap.h"
 
-class SkBitmapCache : SkNoncopyable {
+class SkGradientBitmapCache : SkNoncopyable {
 public:
-    SkBitmapCache(int maxEntries);
-    ~SkBitmapCache();
+    SkGradientBitmapCache(int maxEntries);
+    ~SkGradientBitmapCache();
 
     bool find(const void* buffer, size_t len, SkBitmap*) const;
     void add(const void* buffer, size_t len, const SkBitmap&);
@@ -39,10 +39,10 @@
 
     class AutoValidate : SkNoncopyable {
     public:
-        AutoValidate(const SkBitmapCache* bc) : fBC(bc) { bc->validate(); }
+        AutoValidate(const SkGradientBitmapCache* bc) : fBC(bc) { bc->validate(); }
         ~AutoValidate() { fBC->validate(); }
     private:
-        const SkBitmapCache* fBC;
+        const SkGradientBitmapCache* fBC;
     };
 };
 
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 038044d..d25873b 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -12,8 +12,63 @@
 #include "SkTwoPointConicalGradient.h"
 #include "SkSweepGradient.h"
 
-SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc, const SkMatrix* localMatrix)
-    : INHERITED(localMatrix)
+void SkGradientShaderBase::Descriptor::flatten(SkWriteBuffer& buffer) const {
+    buffer.writeColorArray(fColors, fCount);
+    if (fPos) {
+        buffer.writeBool(true);
+        buffer.writeScalarArray(fPos, fCount);
+    } else {
+        buffer.writeBool(false);
+    }
+    buffer.write32(fTileMode);
+    buffer.write32(fGradFlags);
+    if (fLocalMatrix) {
+        buffer.writeBool(true);
+        buffer.writeMatrix(*fLocalMatrix);
+    } else {
+        buffer.writeBool(false);
+    }
+}
+
+bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) {
+    fCount = buffer.getArrayCount();
+    if (fCount > kStorageCount) {
+        size_t allocSize = (sizeof(SkColor) + sizeof(SkScalar)) * fCount;
+        fDynamicStorage.reset(allocSize);
+        fColors = (SkColor*)fDynamicStorage.get();
+        fPos = (SkScalar*)(fColors + fCount);
+    } else {
+        fColors = fColorStorage;
+        fPos = fPosStorage;
+    }
+
+    if (!buffer.readColorArray(const_cast<SkColor*>(fColors), fCount)) {
+        return false;
+    }
+    if (buffer.readBool()) {
+        if (!buffer.readScalarArray(const_cast<SkScalar*>(fPos), fCount)) {
+            return false;
+        }
+    } else {
+        fPos = NULL;
+    }
+
+    fTileMode = (SkShader::TileMode)buffer.read32();
+    fGradFlags = buffer.read32();
+
+    if (buffer.readBool()) {
+        fLocalMatrix = &fLocalMatrixStorage;
+        buffer.readMatrix(&fLocalMatrixStorage);
+    } else {
+        fLocalMatrix = NULL;
+    }
+    return buffer.isValid();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+
+SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc)
+    : INHERITED(desc.fLocalMatrix)
 {
     SkASSERT(desc.fCount > 1);
 
@@ -47,6 +102,9 @@
 
     if (fColorCount > kColorStorageCount) {
         size_t size = sizeof(SkColor) + sizeof(Rec);
+        if (desc.fPos) {
+            size += sizeof(SkScalar);
+        }
         fOrigColors = reinterpret_cast<SkColor*>(
                                         sk_malloc_throw(size * fColorCount));
     }
@@ -67,13 +125,23 @@
         }
     }
 
-    fRecs = (Rec*)(fOrigColors + fColorCount);
+    if (desc.fPos && fColorCount) {
+        fOrigPos = (SkScalar*)(fOrigColors + fColorCount);
+        fRecs = (Rec*)(fOrigPos + fColorCount);
+    } else {
+        fOrigPos = NULL;
+        fRecs = (Rec*)(fOrigColors + fColorCount);
+    }
+
     if (fColorCount > 2) {
         Rec* recs = fRecs;
         recs->fPos = 0;
         //  recs->fScale = 0; // unused;
         recs += 1;
         if (desc.fPos) {
+            SkScalar* origPosPtr = fOrigPos;
+            *origPosPtr++ = 0;
+
             /*  We need to convert the user's array of relative positions into
                 fixed-point positions and scale factors. We need these results
                 to be strictly monotonic (no two values equal or out of order).
@@ -81,26 +149,23 @@
                 value if it sees a segment out of order, and it assures that
                 we start at 0 and end at 1.0
             */
-            SkFixed prev = 0;
+            SkScalar prev = 0;
             int startIndex = dummyFirst ? 0 : 1;
             int count = desc.fCount + dummyLast;
             for (int i = startIndex; i < count; i++) {
                 // force the last value to be 1.0
-                SkFixed curr;
+                SkScalar curr;
                 if (i == desc.fCount) {  // we're really at the dummyLast
-                    curr = SK_Fixed1;
+                    curr = 1;
                 } else {
-                    curr = SkScalarToFixed(desc.fPos[i]);
+                    curr = SkScalarPin(desc.fPos[i], 0, 1);
                 }
-                // pin curr withing range
-                if (curr < 0) {
-                    curr = 0;
-                } else if (curr > SK_Fixed1) {
-                    curr = SK_Fixed1;
-                }
-                recs->fPos = curr;
-                if (curr > prev) {
-                    recs->fScale = (1 << 24) / (curr - prev);
+                *origPosPtr++ = curr;
+
+                recs->fPos = SkScalarToFixed(curr);
+                SkFixed diff = SkScalarToFixed(curr - prev);
+                if (diff > 0) {
+                    recs->fScale = (1 << 24) / diff;
                 } else {
                     recs->fScale = 0; // ignore this segment
                 }
@@ -109,6 +174,8 @@
                 recs += 1;
             }
         } else {    // assume even distribution
+            fOrigPos = NULL;
+
             SkFixed dp = SK_Fixed1 / (desc.fCount - 1);
             SkFixed p = dp;
             SkFixed scale = (desc.fCount - 1) << 8;  // (1 << 24) / dp
@@ -121,16 +188,18 @@
             recs->fPos = SK_Fixed1;
             recs->fScale = scale;
         }
+    } else if (desc.fPos) {
+        SkASSERT(2 == fColorCount);
+        fOrigPos[0] = SkScalarPin(desc.fPos[0], 0, 1);
+        fOrigPos[1] = SkScalarPin(desc.fPos[1], fOrigPos[0], 1);
+        if (0 == fOrigPos[0] && 1 == fOrigPos[1]) {
+            fOrigPos = NULL;
+        }
     }
     this->initCommon();
 }
 
-static uint32_t pack_mode_flags(SkShader::TileMode mode, uint32_t flags) {
-    SkASSERT(0 == (flags >> 28));
-    SkASSERT(0 == ((uint32_t)mode >> 4));
-    return (flags << 4) | mode;
-}
-
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 static SkShader::TileMode unpack_mode(uint32_t packed) {
     return (SkShader::TileMode)(packed & 0xF);
 }
@@ -147,7 +216,7 @@
 
     int colorCount = fColorCount = buffer.getArrayCount();
     if (colorCount > kColorStorageCount) {
-        size_t allocSize = (sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec)) * colorCount;
+        size_t allocSize = (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec)) * colorCount;
         if (buffer.validateAvailable(allocSize)) {
             fOrigColors = reinterpret_cast<SkColor*>(sk_malloc_throw(allocSize));
         } else {
@@ -159,24 +228,31 @@
     }
     buffer.readColorArray(fOrigColors, colorCount);
 
+    fOrigPos = (SkScalar*)(fOrigColors + colorCount);
+
     {
         uint32_t packed = buffer.readUInt();
         fGradFlags = SkToU8(unpack_flags(packed));
         fTileMode = unpack_mode(packed);
     }
     fTileProc = gTileProcs[fTileMode];
-    fRecs = (Rec*)(fOrigColors + colorCount);
+    fRecs = (Rec*)(fOrigPos + colorCount);
     if (colorCount > 2) {
         Rec* recs = fRecs;
         recs[0].fPos = 0;
+        fOrigPos[0] = 0;
         for (int i = 1; i < colorCount; i++) {
             recs[i].fPos = buffer.readInt();
             recs[i].fScale = buffer.readUInt();
+            fOrigPos[i] = SkFixedToScalar(recs[i].fPos);
         }
+    } else {
+        fOrigPos = NULL;
     }
     buffer.readMatrix(&fPtsToUnit);
     this->initCommon();
 }
+#endif
 
 SkGradientShaderBase::~SkGradientShaderBase() {
     if (fOrigColors != fStorage) {
@@ -193,17 +269,16 @@
 }
 
 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-    buffer.writeColorArray(fOrigColors, fColorCount);
-    buffer.writeUInt(pack_mode_flags(fTileMode, fGradFlags));
-    if (fColorCount > 2) {
-        Rec* recs = fRecs;
-        for (int i = 1; i < fColorCount; i++) {
-            buffer.writeInt(recs[i].fPos);
-            buffer.writeUInt(recs[i].fScale);
-        }
-    }
-    buffer.writeMatrix(fPtsToUnit);
+    Descriptor desc;
+    desc.fColors = fOrigColors;
+    desc.fPos = fOrigPos;
+    desc.fCount = fColorCount;
+    desc.fTileMode = fTileMode;
+    desc.fGradFlags = fGradFlags;
+
+    const SkMatrix& m = this->getLocalMatrix();
+    desc.fLocalMatrix = m.isIdentity() ? NULL : &m;
+    desc.flatten(buffer);
 }
 
 SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const {
@@ -251,6 +326,28 @@
     return fColorsAreOpaque;
 }
 
+static unsigned rounded_divide(unsigned numer, unsigned denom) {
+    return (numer + (denom >> 1)) / denom;
+}
+
+bool SkGradientShaderBase::onAsLuminanceColor(SkColor* lum) const {
+    // we just compute an average color.
+    // possibly we could weight this based on the proportional width for each color
+    //   assuming they are not evenly distributed in the fPos array.
+    int r = 0;
+    int g = 0;
+    int b = 0;
+    const int n = fColorCount;
+    for (int i = 0; i < n; ++i) {
+        SkColor c = fOrigColors[i];
+        r += SkColorGetR(c);
+        g += SkColorGetG(c);
+        b += SkColorGetB(c);
+    }
+    *lum = SkColorSetRGB(rounded_divide(r, n), rounded_divide(g, n), rounded_divide(b, n));
+    return true;
+}
+
 SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext(
         const SkGradientShaderBase& shader, const ContextRec& rec)
     : INHERITED(shader, rec)
@@ -525,11 +622,8 @@
 }
 
 void SkGradientShaderBase::GradientShaderCache::initCache32(GradientShaderCache* cache) {
-    SkImageInfo info;
-    info.fWidth = kCache32Count;
-    info.fHeight = 4;   // for our 4 dither rows
-    info.fAlphaType = kPremul_SkAlphaType;
-    info.fColorType = kN32_SkColorType;
+    const int kNumberOfDitherRows = 4;
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(kCache32Count, kNumberOfDitherRows);
 
     SkASSERT(NULL == cache->fCache32PixelRef);
     cache->fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL);
@@ -570,6 +664,7 @@
     return fCache;
 }
 
+SK_DECLARE_STATIC_MUTEX(gGradientCacheMutex);
 /*
  *  Because our caller might rebuild the same (logically the same) gradient
  *  over and over, we'd like to return exactly the same "bitmap" if possible,
@@ -605,14 +700,13 @@
 
     ///////////////////////////////////
 
-    SK_DECLARE_STATIC_MUTEX(gMutex);
-    static SkBitmapCache* gCache;
+    static SkGradientBitmapCache* gCache;
     // each cache cost 1K of RAM, since each bitmap will be 1x256 at 32bpp
     static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32;
-    SkAutoMutexAcquire ama(gMutex);
+    SkAutoMutexAcquire ama(gGradientCacheMutex);
 
     if (NULL == gCache) {
-        gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS));
+        gCache = SkNEW_ARGS(SkGradientBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS));
     }
     size_t size = count * sizeof(int32_t);
 
@@ -698,8 +792,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "SkEmptyShader.h"
-
 // assumes colors is SkColor* and pos is SkScalar*
 #define EXPAND_1_COLOR(count)               \
     SkColor tmp[2];                         \
@@ -713,14 +805,14 @@
     } while (0)
 
 static void desc_init(SkGradientShaderBase::Descriptor* desc,
-                      const SkColor colors[],
-                      const SkScalar pos[], int colorCount,
-                      SkShader::TileMode mode, uint32_t flags) {
+                      const SkColor colors[], const SkScalar pos[], int colorCount,
+                      SkShader::TileMode mode, uint32_t flags, const SkMatrix* localMatrix) {
     desc->fColors       = colors;
     desc->fPos          = pos;
     desc->fCount        = colorCount;
     desc->fTileMode     = mode;
     desc->fGradFlags    = flags;
+    desc->fLocalMatrix  = localMatrix;
 }
 
 SkShader* SkGradientShader::CreateLinear(const SkPoint pts[2],
@@ -735,8 +827,8 @@
     EXPAND_1_COLOR(colorCount);
 
     SkGradientShaderBase::Descriptor desc;
-    desc_init(&desc, colors, pos, colorCount, mode, flags);
-    return SkNEW_ARGS(SkLinearGradient, (pts, desc, localMatrix));
+    desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+    return SkNEW_ARGS(SkLinearGradient, (pts, desc));
 }
 
 SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius,
@@ -751,8 +843,8 @@
     EXPAND_1_COLOR(colorCount);
 
     SkGradientShaderBase::Descriptor desc;
-    desc_init(&desc, colors, pos, colorCount, mode, flags);
-    return SkNEW_ARGS(SkRadialGradient, (center, radius, desc, localMatrix));
+    desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+    return SkNEW_ARGS(SkRadialGradient, (center, radius, desc));
 }
 
 SkShader* SkGradientShader::CreateTwoPointRadial(const SkPoint& start,
@@ -771,9 +863,9 @@
     EXPAND_1_COLOR(colorCount);
 
     SkGradientShaderBase::Descriptor desc;
-    desc_init(&desc, colors, pos, colorCount, mode, flags);
+    desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
     return SkNEW_ARGS(SkTwoPointRadialGradient,
-                      (start, startRadius, end, endRadius, desc, localMatrix));
+                      (start, startRadius, end, endRadius, desc));
 }
 
 SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start,
@@ -790,7 +882,7 @@
         return NULL;
     }
     if (start == end && startRadius == endRadius) {
-        return SkNEW(SkEmptyShader);
+        return SkShader::CreateEmptyShader();
     }
 
     EXPAND_1_COLOR(colorCount);
@@ -800,9 +892,9 @@
     SkGradientShaderBase::Descriptor desc;
 
     if (!flipGradient) {
-        desc_init(&desc, colors, pos, colorCount, mode, flags);
+        desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
         return SkNEW_ARGS(SkTwoPointConicalGradient,
-                          (start, startRadius, end, endRadius, flipGradient, desc, localMatrix));
+                          (start, startRadius, end, endRadius, flipGradient, desc));
     } else {
         SkAutoSTArray<8, SkColor> colorsNew(colorCount);
         SkAutoSTArray<8, SkScalar> posNew(colorCount);
@@ -814,13 +906,13 @@
             for (int i = 0; i < colorCount; ++i) {
                 posNew[i] = 1 - pos[colorCount - i - 1];
             }
-            desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, flags);
+            desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, flags, localMatrix);
         } else {
-            desc_init(&desc, colorsNew.get(), NULL, colorCount, mode, flags);
+            desc_init(&desc, colorsNew.get(), NULL, colorCount, mode, flags, localMatrix);
         }
 
         return SkNEW_ARGS(SkTwoPointConicalGradient,
-                          (end, endRadius, start, startRadius, flipGradient, desc, localMatrix));
+                          (end, endRadius, start, startRadius, flipGradient, desc));
     }
 }
 
@@ -836,8 +928,8 @@
     EXPAND_1_COLOR(colorCount);
 
     SkGradientShaderBase::Descriptor desc;
-    desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags);
-    return SkNEW_ARGS(SkSweepGradient, (cx, cy, desc, localMatrix));
+    desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags, localMatrix);
+    return SkNEW_ARGS(SkSweepGradient, (cx, cy, desc));
 }
 
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader)
@@ -853,102 +945,103 @@
 #if SK_SUPPORT_GPU
 
 #include "effects/GrTextureStripAtlas.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "SkGr.h"
 
-GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory)
+GrGLGradientEffect::GrGLGradientEffect(const GrBackendProcessorFactory& factory)
     : INHERITED(factory)
     , fCachedYCoord(SK_ScalarMax) {
 }
 
 GrGLGradientEffect::~GrGLGradientEffect() { }
 
-void GrGLGradientEffect::emitUniforms(GrGLShaderBuilder* builder, EffectKey key) {
+void GrGLGradientEffect::emitUniforms(GrGLProgramBuilder* builder, uint32_t baseKey) {
 
-    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(key)) { // 2 Color case
-        fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(baseKey)) { // 2 Color case
+        fColorStartUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                              kVec4f_GrSLType, "GradientStartColor");
-        fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fColorEndUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                            kVec4f_GrSLType, "GradientEndColor");
 
-    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(key)){ // 3 Color Case
-        fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(baseKey)){ // 3 Color Case
+        fColorStartUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                              kVec4f_GrSLType, "GradientStartColor");
-        fColorMidUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fColorMidUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                            kVec4f_GrSLType, "GradientMidColor");
-        fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fColorEndUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                              kVec4f_GrSLType, "GradientEndColor");
 
     } else { // if not a fast case
-        fFSYUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fFSYUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                       kFloat_GrSLType, "GradientYCoordFS");
     }
 }
 
-static inline void set_color_uni(const GrGLUniformManager& uman,
-                                 const GrGLUniformManager::UniformHandle uni,
+static inline void set_color_uni(const GrGLProgramDataManager& pdman,
+                                 const GrGLProgramDataManager::UniformHandle uni,
                                  const SkColor* color) {
-       uman.set4f(uni,
-                  SkColorGetR(*color) / 255.f,
-                  SkColorGetG(*color) / 255.f,
-                  SkColorGetB(*color) / 255.f,
-                  SkColorGetA(*color) / 255.f);
+       pdman.set4f(uni,
+                   SkColorGetR(*color) / 255.f,
+                   SkColorGetG(*color) / 255.f,
+                   SkColorGetB(*color) / 255.f,
+                   SkColorGetA(*color) / 255.f);
 }
 
-static inline void set_mul_color_uni(const GrGLUniformManager& uman,
-                                     const GrGLUniformManager::UniformHandle uni,
+static inline void set_mul_color_uni(const GrGLProgramDataManager& pdman,
+                                     const GrGLProgramDataManager::UniformHandle uni,
                                      const SkColor* color){
        float a = SkColorGetA(*color) / 255.f;
        float aDiv255 = a / 255.f;
-       uman.set4f(uni,
-                  SkColorGetR(*color) * aDiv255,
-                  SkColorGetG(*color) * aDiv255,
-                  SkColorGetB(*color) * aDiv255,
-                  a);
+       pdman.set4f(uni,
+                   SkColorGetR(*color) * aDiv255,
+                   SkColorGetG(*color) * aDiv255,
+                   SkColorGetB(*color) * aDiv255,
+                   a);
 }
 
-void GrGLGradientEffect::setData(const GrGLUniformManager& uman,
-                                 const GrDrawEffect& drawEffect) {
+void GrGLGradientEffect::setData(const GrGLProgramDataManager& pdman,
+                                 const GrProcessor& processor) {
 
-    const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
+    const GrGradientEffect& e = processor.cast<GrGradientEffect>();
 
 
     if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()){
 
         if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
-            set_mul_color_uni(uman, fColorStartUni, e.getColors(0));
-            set_mul_color_uni(uman, fColorEndUni,   e.getColors(1));
+            set_mul_color_uni(pdman, fColorStartUni, e.getColors(0));
+            set_mul_color_uni(pdman, fColorEndUni,   e.getColors(1));
         } else {
-            set_color_uni(uman, fColorStartUni, e.getColors(0));
-            set_color_uni(uman, fColorEndUni,   e.getColors(1));
+            set_color_uni(pdman, fColorStartUni, e.getColors(0));
+            set_color_uni(pdman, fColorEndUni,   e.getColors(1));
         }
 
     } else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()){
 
         if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
-            set_mul_color_uni(uman, fColorStartUni, e.getColors(0));
-            set_mul_color_uni(uman, fColorMidUni,   e.getColors(1));
-            set_mul_color_uni(uman, fColorEndUni,   e.getColors(2));
+            set_mul_color_uni(pdman, fColorStartUni, e.getColors(0));
+            set_mul_color_uni(pdman, fColorMidUni,   e.getColors(1));
+            set_mul_color_uni(pdman, fColorEndUni,   e.getColors(2));
         } else {
-            set_color_uni(uman, fColorStartUni, e.getColors(0));
-            set_color_uni(uman, fColorMidUni,   e.getColors(1));
-            set_color_uni(uman, fColorEndUni,   e.getColors(2));
+            set_color_uni(pdman, fColorStartUni, e.getColors(0));
+            set_color_uni(pdman, fColorMidUni,   e.getColors(1));
+            set_color_uni(pdman, fColorEndUni,   e.getColors(2));
         }
     } else {
 
         SkScalar yCoord = e.getYCoord();
         if (yCoord != fCachedYCoord) {
-            uman.set1f(fFSYUni, yCoord);
+            pdman.set1f(fFSYUni, yCoord);
             fCachedYCoord = yCoord;
         }
     }
 }
 
 
-GrGLEffect::EffectKey GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect& drawEffect) {
-    const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
+uint32_t GrGLGradientEffect::GenBaseGradientKey(const GrProcessor& processor) {
+    const GrGradientEffect& e = processor.cast<GrGradientEffect>();
 
-    EffectKey key = 0;
+    uint32_t key = 0;
 
     if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()) {
         key |= kTwoColorKey;
@@ -963,14 +1056,15 @@
     return key;
 }
 
-void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
+void GrGLGradientEffect::emitColor(GrGLProgramBuilder* builder,
                                    const char* gradientTValue,
-                                   EffectKey key,
+                                   uint32_t baseKey,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TextureSamplerArray& samplers) {
-    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(key)){
-        builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(baseKey)){
+        fsBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
                                builder->getUniformVariable(fColorStartUni).c_str(),
                                builder->getUniformVariable(fColorEndUni).c_str(),
                                gradientTValue);
@@ -979,45 +1073,45 @@
         // The gradient SkShader reporting opaque is more restrictive than necessary in the two pt
         // case. Make sure the key reflects this optimization (and note that it can use the same
         // shader as thekBeforeIterp case). This same optimization applies to the 3 color case below.
-        if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(key)) {
-            builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
+        if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(baseKey)) {
+            fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
         }
 
-        builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+        fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
-    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(key)){
-        builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
+    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(baseKey)){
+        fsBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
                                gradientTValue);
-        builder->fsCodeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
+        fsBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
                                builder->getUniformVariable(fColorStartUni).c_str());
         if (kTegra3_GrGLRenderer == builder->ctxInfo().renderer()) {
             // The Tegra3 compiler will sometimes never return if we have
             // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression.
-            builder->fsCodeAppend("\tfloat minAbs = abs(oneMinus2t);\n");
-            builder->fsCodeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n");
-            builder->fsCodeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n",
+            fsBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n");
+            fsBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n");
+            fsBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n",
                                    builder->getUniformVariable(fColorMidUni).c_str());
         } else {
-            builder->fsCodeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n",
+            fsBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n",
                                    builder->getUniformVariable(fColorMidUni).c_str());
         }
-        builder->fsCodeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
+        fsBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
                                builder->getUniformVariable(fColorEndUni).c_str());
-        if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(key)) {
-            builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
+        if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(baseKey)) {
+            fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
         }
 
-        builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+        fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
     } else {
-        builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n",
+        fsBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n",
                                gradientTValue,
                                builder->getUniformVariable(fFSYUni).c_str());
-        builder->fsCodeAppendf("\t%s = ", outputColor);
-        builder->fsAppendTextureLookupAndModulate(inputColor,
+        fsBuilder->codeAppendf("\t%s = ", outputColor);
+        fsBuilder->appendTextureLookupAndModulate(inputColor,
                                                   samplers[0],
                                                   "coord");
-        builder->fsCodeAppend(";\n");
+        fsBuilder->codeAppend(";\n");
     }
 }
 
@@ -1056,7 +1150,7 @@
         desc.fContext = ctx;
         desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info());
         fAtlas = GrTextureStripAtlas::GetAtlas(desc);
-        SkASSERT(NULL != fAtlas);
+        SkASSERT(fAtlas);
 
         // We always filter the gradient table. Each table is one row of a texture, always y-clamp.
         GrTextureParams params;
@@ -1091,8 +1185,8 @@
     }
 }
 
-bool GrGradientEffect::onIsEqual(const GrEffect& effect) const {
-    const GrGradientEffect& s = CastEffect<GrGradientEffect>(effect);
+bool GrGradientEffect::onIsEqual(const GrProcessor& processor) const {
+    const GrGradientEffect& s = processor.cast<GrGradientEffect>();
 
     if (this->fColorType == s.getColorType()){
 
@@ -1145,7 +1239,7 @@
     SkScalar stop = 0.f;
     for (int i = 0; i < outColors; ++i) {
         colors[i] = random->nextU();
-        if (NULL != *stops) {
+        if (*stops) {
             (*stops)[i] = stop;
             stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - stop) : 1.f;
         }
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 9613537..b81b562 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -8,6 +8,7 @@
 #ifndef SkGradientShaderPriv_DEFINED
 #define SkGradientShaderPriv_DEFINED
 
+#include "SkGradientBitmapCache.h"
 #include "SkGradientShader.h"
 #include "SkClampRange.h"
 #include "SkColorPriv.h"
@@ -16,7 +17,6 @@
 #include "SkMallocPixelRef.h"
 #include "SkUtils.h"
 #include "SkTemplates.h"
-#include "SkBitmapCache.h"
 #include "SkShader.h"
 #include "SkOnce.h"
 
@@ -89,15 +89,39 @@
             fTileMode = SkShader::kClamp_TileMode;
         }
 
+        const SkMatrix*     fLocalMatrix;
         const SkColor*      fColors;
         const SkScalar*     fPos;
         int                 fCount;
         SkShader::TileMode  fTileMode;
         uint32_t            fGradFlags;
+
+        void flatten(SkWriteBuffer&) const;
+    };
+
+    class DescriptorScope : public Descriptor {
+    public:
+        DescriptorScope() {}
+        
+        bool unflatten(SkReadBuffer&);
+
+        // fColors and fPos always point into local memory, so they can be safely mutated
+        //
+        SkColor* mutableColors() { return const_cast<SkColor*>(fColors); }
+        SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
+
+    private:
+        enum {
+            kStorageCount = 16
+        };
+        SkColor fColorStorage[kStorageCount];
+        SkScalar fPosStorage[kStorageCount];
+        SkMatrix fLocalMatrixStorage;
+        SkAutoMalloc fDynamicStorage;
     };
 
 public:
-    SkGradientShaderBase(const Descriptor& desc, const SkMatrix* localMatrix);
+    SkGradientShaderBase(const Descriptor& desc);
     virtual ~SkGradientShaderBase();
 
     // The cache is initialized on-demand when getCache16/32 is called.
@@ -213,6 +237,8 @@
 
     void commonAsAGradient(GradientInfo*, bool flipGrad = false) const;
 
+    virtual bool onAsLuminanceColor(SkColor*) const SK_OVERRIDE;
+
     /*
      * Takes in pointers to gradient color and Rec info as colorSrc and recSrc respectively.
      * Count is the number of colors in the gradient
@@ -233,10 +259,11 @@
     enum {
         kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
 
-        kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(Rec))
+        kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec))
     };
     SkColor     fStorage[(kStorageSize + 3) >> 2];
     SkColor*    fOrigColors; // original colors, before modulation by paint in context.
+    SkScalar*   fOrigPos;   // original positions
     bool        fColorsAreOpaque;
 
     GradientShaderCache* refCache(U8CPU alpha) const;
@@ -271,10 +298,10 @@
 #if SK_SUPPORT_GPU
 
 #include "GrCoordTransform.h"
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
 
-class GrEffectStage;
-class GrBackendEffectFactory;
+class GrProcessorStage;
+class GrBackendProcessorFactory;
 
 /*
  * The interpretation of the texture matrix depends on the sample mode. The
@@ -302,7 +329,7 @@
  class GrTextureStripAtlas;
 
 // Base class for Gr gradient effects
-class GrGradientEffect : public GrEffect {
+class GrGradientEffect : public GrFragmentProcessor {
 public:
 
     GrGradientEffect(GrContext* ctx,
@@ -347,7 +374,7 @@
                                     SkScalar** stops,
                                     SkShader::TileMode* tm);
 
-    virtual bool onIsEqual(const GrEffect& effect) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
 
@@ -364,21 +391,44 @@
     SkColor fColors[3]; // More than 3 colors we use texture
     PremulType fPremulType; // This only changes behavior for two and three color special cases.
                             // It is already baked into to the table for texture gradients.
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
 // Base class for GL gradient effects
-class GrGLGradientEffect : public GrGLEffect {
+class GrGLGradientEffect : public GrGLFragmentProcessor {
 public:
-    GrGLGradientEffect(const GrBackendEffectFactory& factory);
+    GrGLGradientEffect(const GrBackendProcessorFactory& factory);
     virtual ~GrGLGradientEffect();
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 protected:
+    /**
+     * Subclasses must call this. It will return a key for the part of the shader code controlled
+     * by the base class. The subclasses must stick it in their key and then pass it to the below
+     * emit* functions from their emitCode function.
+     */
+    static uint32_t GenBaseGradientKey(const GrProcessor&);
+
+    // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
+    // should call this method from their emitCode().
+    void emitUniforms(GrGLProgramBuilder* builder, uint32_t baseKey);
+
+
+    // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
+    // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
+    // native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
+    void emitColor(GrGLProgramBuilder* builder,
+                   const char* gradientTValue,
+                   uint32_t baseKey,
+                   const char* outputColor,
+                   const char* inputColor,
+                   const TextureSamplerArray& samplers);
+
+private:
     enum {
         kPremulTypeKeyBitCnt = 1,
         kPremulTypeMask = 1,
@@ -393,52 +443,31 @@
         // and combine with the result of GenBaseGradientKey.
         kBaseKeyBitCnt = (kPremulTypeKeyBitCnt + kColorKeyBitCnt)
     };
+    GR_STATIC_ASSERT(kBaseKeyBitCnt <= 32);
 
-    static SkGradientShaderBase::GpuColorType ColorTypeFromKey(EffectKey key){
-        if (kTwoColorKey == (key & kColorKeyMask)) {
+    static SkGradientShaderBase::GpuColorType ColorTypeFromKey(uint32_t baseKey){
+        if (kTwoColorKey == (baseKey & kColorKeyMask)) {
             return SkGradientShaderBase::kTwo_GpuColorType;
-        } else if (kThreeColorKey == (key & kColorKeyMask)) {
+        } else if (kThreeColorKey == (baseKey & kColorKeyMask)) {
             return SkGradientShaderBase::kThree_GpuColorType;
         } else {return SkGradientShaderBase::kTexture_GpuColorType;}
     }
 
-    static GrGradientEffect::PremulType PremulTypeFromKey(EffectKey key){
-        if (kPremulBeforeInterpKey == (key & kPremulTypeMask)) {
+    static GrGradientEffect::PremulType PremulTypeFromKey(uint32_t baseKey){
+        if (kPremulBeforeInterpKey == (baseKey & kPremulTypeMask)) {
             return GrGradientEffect::kBeforeInterp_PremulType;
         } else {
             return GrGradientEffect::kAfterInterp_PremulType;
         }
     }
 
-    /**
-     * Subclasses must call this. It will return a value restricted to the lower kBaseKeyBitCnt
-     * bits.
-     */
-    static EffectKey GenBaseGradientKey(const GrDrawEffect&);
-
-    // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
-    // should call this method from their emitCode().
-    void emitUniforms(GrGLShaderBuilder* builder, EffectKey key);
-
-
-    // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
-    // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
-    // native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
-    void emitColor(GrGLShaderBuilder* builder,
-                   const char* gradientTValue,
-                   EffectKey key,
-                   const char* outputColor,
-                   const char* inputColor,
-                   const TextureSamplerArray& samplers);
-
-private:
     SkScalar fCachedYCoord;
-    GrGLUniformManager::UniformHandle fFSYUni;
-    GrGLUniformManager::UniformHandle fColorStartUni;
-    GrGLUniformManager::UniformHandle fColorMidUni;
-    GrGLUniformManager::UniformHandle fColorEndUni;
+    GrGLProgramDataManager::UniformHandle fFSYUni;
+    GrGLProgramDataManager::UniformHandle fColorStartUni;
+    GrGLProgramDataManager::UniformHandle fColorMidUni;
+    GrGLProgramDataManager::UniformHandle fColorEndUni;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
 #endif
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 72b9d47..058e61c 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -52,19 +52,33 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkLinearGradient::SkLinearGradient(const SkPoint pts[2], const Descriptor& desc,
-                                   const SkMatrix* localMatrix)
-    : SkGradientShaderBase(desc, localMatrix)
+SkLinearGradient::SkLinearGradient(const SkPoint pts[2], const Descriptor& desc)
+    : SkGradientShaderBase(desc)
     , fStart(pts[0])
-    , fEnd(pts[1]) {
+    , fEnd(pts[1])
+{
     pts_to_unit_matrix(pts, &fPtsToUnit);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLinearGradient::SkLinearGradient(SkReadBuffer& buffer)
     : INHERITED(buffer)
     , fStart(buffer.readPoint())
     , fEnd(buffer.readPoint()) {
 }
+#endif
+
+SkFlattenable* SkLinearGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    SkPoint pts[2];
+    pts[0] = buffer.readPoint();
+    pts[1] = buffer.readPoint();
+    return SkGradientShader::CreateLinear(pts, desc.fColors, desc.fPos, desc.fCount,
+                                          desc.fTileMode, desc.fGradFlags, desc.fLocalMatrix);
+}
 
 void SkLinearGradient::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
@@ -445,7 +459,8 @@
 
 #if SK_SUPPORT_GPU
 
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "SkGr.h"
 
 /////////////////////////////////////////////////////////////////////
@@ -453,21 +468,21 @@
 class GrGLLinearGradient : public GrGLGradientEffect {
 public:
 
-    GrGLLinearGradient(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+    GrGLLinearGradient(const GrBackendProcessorFactory& factory, const GrProcessor&)
                        : INHERITED (factory) { }
 
     virtual ~GrGLLinearGradient() { }
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-        return GenBaseGradientKey(drawEffect);
+    static void GenKey(const GrProcessor& processor, const GrGLCaps&, GrProcessorKeyBuilder* b) {
+        b->add32(GenBaseGradientKey(processor));
     }
 
 private:
@@ -480,22 +495,21 @@
 class GrLinearGradient : public GrGradientEffect {
 public:
 
-    static GrEffectRef* Create(GrContext* ctx,
-                               const SkLinearGradient& shader,
-                               const SkMatrix& matrix,
-                               SkShader::TileMode tm) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrLinearGradient, (ctx, shader, matrix, tm)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrContext* ctx,
+                                       const SkLinearGradient& shader,
+                                       const SkMatrix& matrix,
+                                       SkShader::TileMode tm) {
+        return SkNEW_ARGS(GrLinearGradient, (ctx, shader, matrix, tm));
     }
 
     virtual ~GrLinearGradient() { }
 
     static const char* Name() { return "Linear Gradient"; }
-    const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<GrLinearGradient>::getInstance();
+    const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<GrLinearGradient>::getInstance();
     }
 
-    typedef GrGLLinearGradient GLEffect;
+    typedef GrGLLinearGradient GLProcessor;
 
 private:
     GrLinearGradient(GrContext* ctx,
@@ -503,19 +517,19 @@
                      const SkMatrix& matrix,
                      SkShader::TileMode tm)
         : INHERITED(ctx, shader, matrix, tm) { }
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     typedef GrGradientEffect INHERITED;
 };
 
 /////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrLinearGradient);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrLinearGradient);
 
-GrEffectRef* GrLinearGradient::TestCreate(SkRandom* random,
-                                          GrContext* context,
-                                          const GrDrawTargetCaps&,
-                                          GrTexture**) {
+GrFragmentProcessor* GrLinearGradient::TestCreate(SkRandom* random,
+                                                  GrContext* context,
+                                                  const GrDrawTargetCaps&,
+                                                  GrTexture**) {
     SkPoint points[] = {{random->nextUScalar1(), random->nextUScalar1()},
                         {random->nextUScalar1(), random->nextUScalar1()}};
 
@@ -528,33 +542,34 @@
                                                                  colors, stops, colorCount,
                                                                  tm));
     SkPaint paint;
-    GrColor grColor;
-    GrEffectRef* effect;
-    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
-    return effect;
+    GrColor paintColor;
+    GrFragmentProcessor* fp;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &fp));
+    return fp;
 }
 
 /////////////////////////////////////////////////////////////////////
 
-void GrGLLinearGradient::emitCode(GrGLShaderBuilder* builder,
-                                  const GrDrawEffect&,
-                                  EffectKey key,
+void GrGLLinearGradient::emitCode(GrGLProgramBuilder* builder,
+                                  const GrFragmentProcessor&,
+                                  const GrProcessorKey& key,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TransformedCoordsArray& coords,
                                   const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
-    SkString t = builder->ensureFSCoords2D(coords, 0);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
+    SkString t = builder->getFragmentShaderBuilder()->ensureFSCoords2D(coords, 0);
     t.append(".x");
-    this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
 /////////////////////////////////////////////////////////////////////
 
-bool SkLinearGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                   const SkMatrix* localMatrix, GrColor* grColor,
-                                   GrEffectRef** grEffect)  const {
-    SkASSERT(NULL != context);
+bool SkLinearGradient::asFragmentProcessor(GrContext* context, const SkPaint& paint,
+                                           const SkMatrix* localMatrix, GrColor* paintColor,
+                                           GrFragmentProcessor** fp)  const {
+    SkASSERT(context);
     
     SkMatrix matrix;
     if (!this->getLocalMatrix().invert(&matrix)) {
@@ -569,17 +584,16 @@
     }
     matrix.postConcat(fPtsToUnit);
     
-    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
-    *grEffect = GrLinearGradient::Create(context, *this, matrix, fTileMode);
+    *paintColor = SkColor2GrColorJustAlpha(paint.getColor());
+    *fp = GrLinearGradient::Create(context, *this, matrix, fTileMode);
     
     return true;
 }
 
 #else
 
-bool SkLinearGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                   const SkMatrix* localMatrix, GrColor* grColor,
-                                   GrEffectRef** grEffect)  const {
+bool SkLinearGradient::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                           GrFragmentProcessor**)  const {
     SkDEBUGFAIL("Should not call in GPU-less build");
     return false;
 }
diff --git a/src/effects/gradients/SkLinearGradient.h b/src/effects/gradients/SkLinearGradient.h
index f412a68..eb6c76e 100644
--- a/src/effects/gradients/SkLinearGradient.h
+++ b/src/effects/gradients/SkLinearGradient.h
@@ -12,7 +12,7 @@
 
 class SkLinearGradient : public SkGradientShaderBase {
 public:
-    SkLinearGradient(const SkPoint pts[2], const Descriptor&, const SkMatrix* localMatrix);
+    SkLinearGradient(const SkPoint pts[2], const Descriptor&);
 
     virtual size_t contextSize() const SK_OVERRIDE;
 
@@ -30,8 +30,8 @@
 
     virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*) const SK_OVERRIDE;
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
-    virtual bool asNewEffect(GrContext* context, const SkPaint& paint, const SkMatrix* localMatrix,
-                             GrColor* grColor, GrEffectRef** grEffect) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*,
+                                     GrColor*, GrFragmentProcessor**) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLinearGradient)
@@ -42,6 +42,7 @@
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
     const SkPoint fStart;
     const SkPoint fEnd;
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index f0cb161..b4ced5e 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -145,11 +145,10 @@
 
 /////////////////////////////////////////////////////////////////////
 
-SkRadialGradient::SkRadialGradient(const SkPoint& center, SkScalar radius,
-                                   const Descriptor& desc, const SkMatrix* localMatrix)
-    : SkGradientShaderBase(desc, localMatrix),
-      fCenter(center),
-      fRadius(radius)
+SkRadialGradient::SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor& desc)
+    : SkGradientShaderBase(desc)
+    , fCenter(center)
+    , fRadius(radius)
 {
     // make sure our table is insync with our current #define for kSQRT_TABLE_SIZE
     SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE);
@@ -253,11 +252,24 @@
     return kRadial_GradientType;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkRadialGradient::SkRadialGradient(SkReadBuffer& buffer)
     : INHERITED(buffer),
       fCenter(buffer.readPoint()),
       fRadius(buffer.readScalar()) {
 }
+#endif
+
+SkFlattenable* SkRadialGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    const SkPoint center = buffer.readPoint();
+    const SkScalar radius = buffer.readScalar();
+    return SkGradientShader::CreateRadial(center, radius, desc.fColors, desc.fPos, desc.fCount,
+                                          desc.fTileMode, desc.fGradFlags, desc.fLocalMatrix);
+}
 
 void SkRadialGradient::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
@@ -457,26 +469,27 @@
 
 #if SK_SUPPORT_GPU
 
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "SkGr.h"
 
 class GrGLRadialGradient : public GrGLGradientEffect {
 public:
 
-    GrGLRadialGradient(const GrBackendEffectFactory& factory,
-                       const GrDrawEffect&) : INHERITED (factory) { }
+    GrGLRadialGradient(const GrBackendProcessorFactory& factory,
+                       const GrProcessor&) : INHERITED (factory) { }
     virtual ~GrGLRadialGradient() { }
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-        return GenBaseGradientKey(drawEffect);
+    static void GenKey(const GrProcessor& processor, const GrGLCaps&, GrProcessorKeyBuilder* b) {
+        b->add32(GenBaseGradientKey(processor));
     }
 
 private:
@@ -489,22 +502,21 @@
 
 class GrRadialGradient : public GrGradientEffect {
 public:
-    static GrEffectRef* Create(GrContext* ctx,
-                               const SkRadialGradient& shader,
-                               const SkMatrix& matrix,
-                               SkShader::TileMode tm) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrRadialGradient, (ctx, shader, matrix, tm)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrContext* ctx,
+                                       const SkRadialGradient& shader,
+                                       const SkMatrix& matrix,
+                                       SkShader::TileMode tm) {
+        return SkNEW_ARGS(GrRadialGradient, (ctx, shader, matrix, tm));
     }
 
     virtual ~GrRadialGradient() { }
 
     static const char* Name() { return "Radial Gradient"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<GrRadialGradient>::getInstance();
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<GrRadialGradient>::getInstance();
     }
 
-    typedef GrGLRadialGradient GLEffect;
+    typedef GrGLRadialGradient GLProcessor;
 
 private:
     GrRadialGradient(GrContext* ctx,
@@ -514,19 +526,19 @@
         : INHERITED(ctx, shader, matrix, tm) {
     }
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     typedef GrGradientEffect INHERITED;
 };
 
 /////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrRadialGradient);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRadialGradient);
 
-GrEffectRef* GrRadialGradient::TestCreate(SkRandom* random,
-                                          GrContext* context,
-                                          const GrDrawTargetCaps&,
-                                          GrTexture**) {
+GrFragmentProcessor* GrRadialGradient::TestCreate(SkRandom* random,
+                                                  GrContext* context,
+                                                  const GrDrawTargetCaps&,
+                                                  GrTexture**) {
     SkPoint center = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius = random->nextUScalar1();
 
@@ -539,34 +551,35 @@
                                                                  colors, stops, colorCount,
                                                                  tm));
     SkPaint paint;
-    GrColor grColor;
-    GrEffectRef* effect;
-    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
-    return effect;
+    GrColor paintColor;
+    GrFragmentProcessor* fp;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &fp));
+    return fp;
 }
 
 /////////////////////////////////////////////////////////////////////
 
-void GrGLRadialGradient::emitCode(GrGLShaderBuilder* builder,
-                                  const GrDrawEffect&,
-                                  EffectKey key,
+void GrGLRadialGradient::emitCode(GrGLProgramBuilder* builder,
+                                  const GrFragmentProcessor&,
+                                  const GrProcessorKey& key,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TransformedCoordsArray& coords,
                                   const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     SkString t("length(");
-    t.append(builder->ensureFSCoords2D(coords, 0));
+    t.append(builder->getFragmentShaderBuilder()->ensureFSCoords2D(coords, 0));
     t.append(")");
-    this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
 /////////////////////////////////////////////////////////////////////
 
-bool SkRadialGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                   const SkMatrix* localMatrix, GrColor* grColor,
-                                   GrEffectRef** grEffect) const {
-    SkASSERT(NULL != context);
+bool SkRadialGradient::asFragmentProcessor(GrContext* context, const SkPaint& paint,
+                                           const SkMatrix* localMatrix, GrColor* paintColor,
+                                           GrFragmentProcessor** fp) const {
+    SkASSERT(context);
     
     SkMatrix matrix;
     if (!this->getLocalMatrix().invert(&matrix)) {
@@ -581,17 +594,16 @@
     }
     matrix.postConcat(fPtsToUnit);
     
-    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
-    *grEffect = GrRadialGradient::Create(context, *this, matrix, fTileMode);
+    *paintColor = SkColor2GrColorJustAlpha(paint.getColor());
+    *fp = GrRadialGradient::Create(context, *this, matrix, fTileMode);
     
     return true;
 }
 
 #else
 
-bool SkRadialGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                   const SkMatrix* localMatrix, GrColor* grColor,
-                                   GrEffectRef** grEffect) const {
+bool SkRadialGradient::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                           GrFragmentProcessor**) const {
     SkDEBUGFAIL("Should not call in GPU-less build");
     return false;
 }
diff --git a/src/effects/gradients/SkRadialGradient.h b/src/effects/gradients/SkRadialGradient.h
index 197c967..633b39f 100644
--- a/src/effects/gradients/SkRadialGradient.h
+++ b/src/effects/gradients/SkRadialGradient.h
@@ -13,8 +13,7 @@
 
 class SkRadialGradient : public SkGradientShaderBase {
 public:
-    SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor&,
-                     const SkMatrix* localMatrix);
+    SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor&);
 
     virtual size_t contextSize() const SK_OVERRIDE;
 
@@ -33,7 +32,8 @@
                                  SkMatrix* matrix,
                                  TileMode* xy) const SK_OVERRIDE;
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
-    virtual bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor*, GrEffectRef**) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                     GrFragmentProcessor**) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRadialGradient)
@@ -44,6 +44,7 @@
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
     const SkPoint fCenter;
     const SkScalar fRadius;
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index 154e3a2..750e80a 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -8,9 +8,8 @@
 
 #include "SkSweepGradient.h"
 
-SkSweepGradient::SkSweepGradient(SkScalar cx, SkScalar cy,
-                                 const Descriptor& desc, const SkMatrix* localMatrix)
-    : SkGradientShaderBase(desc, localMatrix)
+SkSweepGradient::SkSweepGradient(SkScalar cx, SkScalar cy, const Descriptor& desc)
+    : SkGradientShaderBase(desc)
     , fCenter(SkPoint::Make(cx, cy))
 {
     fPtsToUnit.setTranslate(-cx, -cy);
@@ -42,10 +41,22 @@
     return kSweep_GradientType;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkSweepGradient::SkSweepGradient(SkReadBuffer& buffer)
     : INHERITED(buffer),
       fCenter(buffer.readPoint()) {
 }
+#endif
+
+SkFlattenable* SkSweepGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    const SkPoint center = buffer.readPoint();
+    return SkGradientShader::CreateSweep(center.x(), center.y(), desc.fColors, desc.fPos,
+                                         desc.fCount, desc.fGradFlags, desc.fLocalMatrix);
+}
 
 void SkSweepGradient::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
@@ -173,26 +184,27 @@
 
 #if SK_SUPPORT_GPU
 
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "SkGr.h"
 
 class GrGLSweepGradient : public GrGLGradientEffect {
 public:
 
-    GrGLSweepGradient(const GrBackendEffectFactory& factory,
-                      const GrDrawEffect&) : INHERITED (factory) { }
+    GrGLSweepGradient(const GrBackendProcessorFactory& factory,
+                      const GrProcessor&) : INHERITED (factory) { }
     virtual ~GrGLSweepGradient() { }
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-        return GenBaseGradientKey(drawEffect);
+    static void GenKey(const GrProcessor& processor, const GrGLCaps&, GrProcessorKeyBuilder* b) {
+        b->add32(GenBaseGradientKey(processor));
     }
 
 private:
@@ -205,39 +217,37 @@
 
 class GrSweepGradient : public GrGradientEffect {
 public:
-    static GrEffectRef* Create(GrContext* ctx,
-                               const SkSweepGradient& shader,
-                               const SkMatrix& matrix) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrSweepGradient, (ctx, shader, matrix)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrContext* ctx, const SkSweepGradient& shader,
+                                       const SkMatrix& m) {
+        return SkNEW_ARGS(GrSweepGradient, (ctx, shader, m));
     }
     virtual ~GrSweepGradient() { }
 
     static const char* Name() { return "Sweep Gradient"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<GrSweepGradient>::getInstance();
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<GrSweepGradient>::getInstance();
     }
 
-    typedef GrGLSweepGradient GLEffect;
+    typedef GrGLSweepGradient GLProcessor;
 
 private:
     GrSweepGradient(GrContext* ctx,
                     const SkSweepGradient& shader,
                     const SkMatrix& matrix)
     : INHERITED(ctx, shader, matrix, SkShader::kClamp_TileMode) { }
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     typedef GrGradientEffect INHERITED;
 };
 
 /////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrSweepGradient);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSweepGradient);
 
-GrEffectRef* GrSweepGradient::TestCreate(SkRandom* random,
-                                         GrContext* context,
-                                         const GrDrawTargetCaps&,
-                                         GrTexture**) {
+GrFragmentProcessor* GrSweepGradient::TestCreate(SkRandom* random,
+                                                 GrContext* context,
+                                                 const GrDrawTargetCaps&,
+                                                 GrTexture**) {
     SkPoint center = {random->nextUScalar1(), random->nextUScalar1()};
 
     SkColor colors[kMaxRandomGradientColors];
@@ -248,23 +258,24 @@
     SkAutoTUnref<SkShader> shader(SkGradientShader::CreateSweep(center.fX, center.fY,
                                                                 colors, stops, colorCount));
     SkPaint paint;
-    GrEffectRef* effect;
-    GrColor grColor;
-    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
-    return effect;
+    GrFragmentProcessor* fp;
+    GrColor paintColor;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &fp));
+    return fp;
 }
 
 /////////////////////////////////////////////////////////////////////
 
-void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder,
-                                 const GrDrawEffect&,
-                                 EffectKey key,
+void GrGLSweepGradient::emitCode(GrGLProgramBuilder* builder,
+                                 const GrFragmentProcessor&,
+                                 const GrProcessorKey& key,
                                  const char* outputColor,
                                  const char* inputColor,
                                  const TransformedCoordsArray& coords,
                                  const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
+    SkString coords2D = builder->getFragmentShaderBuilder()->ensureFSCoords2D(coords, 0);
     const GrGLContextInfo ctxInfo = builder->ctxInfo();
     SkString t;
     // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi]
@@ -277,15 +288,14 @@
         t.printf("atan(- %s.y, -1.0 * %s.x) * 0.1591549430918 + 0.5",
                  coords2D.c_str(), coords2D.c_str());
     }
-    this->emitColor(builder, t.c_str(), key,
-                          outputColor, inputColor, samplers);
+    this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
 /////////////////////////////////////////////////////////////////////
 
-bool SkSweepGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                  const SkMatrix* localMatrix, GrColor* grColor,
-                                  GrEffectRef** grEffect)  const {
+bool SkSweepGradient::asFragmentProcessor(GrContext* context, const SkPaint& paint,
+                                          const SkMatrix* localMatrix, GrColor* paintColor,
+                                          GrFragmentProcessor** effect)  const {
     
     SkMatrix matrix;
     if (!this->getLocalMatrix().invert(&matrix)) {
@@ -300,17 +310,16 @@
     }
     matrix.postConcat(fPtsToUnit);
     
-    *grEffect = GrSweepGradient::Create(context, *this, matrix);
-    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
+    *effect = GrSweepGradient::Create(context, *this, matrix);
+    *paintColor = SkColor2GrColorJustAlpha(paint.getColor());
     
     return true;
 }
 
 #else
 
-bool SkSweepGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                  const SkMatrix* localMatrix, GrColor* grColor,
-                                  GrEffectRef** grEffect)  const {
+bool SkSweepGradient::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                          GrFragmentProcessor**)  const {
     SkDEBUGFAIL("Should not call in GPU-less build");
     return false;
 }
diff --git a/src/effects/gradients/SkSweepGradient.h b/src/effects/gradients/SkSweepGradient.h
index 0b12e71..d816295 100644
--- a/src/effects/gradients/SkSweepGradient.h
+++ b/src/effects/gradients/SkSweepGradient.h
@@ -13,8 +13,7 @@
 
 class SkSweepGradient : public SkGradientShaderBase {
 public:
-    SkSweepGradient(SkScalar cx, SkScalar cy, const Descriptor&,
-                    const SkMatrix* localMatrix);
+    SkSweepGradient(SkScalar cx, SkScalar cy, const Descriptor&);
 
     virtual size_t contextSize() const SK_OVERRIDE;
 
@@ -35,20 +34,23 @@
 
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
 
-    virtual bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor*, GrEffectRef**)
-        const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                     GrFragmentProcessor**) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSweepGradient)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkSweepGradient(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
     const SkPoint fCenter;
 
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
 };
 
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index 4421b90..bb3b9b3 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -196,14 +196,14 @@
 SkTwoPointConicalGradient::SkTwoPointConicalGradient(
         const SkPoint& start, SkScalar startRadius,
         const SkPoint& end, SkScalar endRadius,
-        bool flippedGrad, const Descriptor& desc,
-        const SkMatrix* localMatrix)
-    : SkGradientShaderBase(desc, localMatrix),
-    fCenter1(start),
-    fCenter2(end),
-    fRadius1(startRadius),
-    fRadius2(endRadius),
-    fFlippedGrad(flippedGrad) {
+        bool flippedGrad, const Descriptor& desc)
+    : SkGradientShaderBase(desc)
+    , fCenter1(start)
+    , fCenter2(end)
+    , fRadius1(startRadius)
+    , fRadius2(endRadius)
+    , fFlippedGrad(flippedGrad)
+{
     // this is degenerate, and should be caught by our caller
     SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2);
     this->init();
@@ -343,6 +343,7 @@
     return kConical_GradientType;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkTwoPointConicalGradient::SkTwoPointConicalGradient(
     SkReadBuffer& buffer)
     : INHERITED(buffer),
@@ -366,9 +367,47 @@
     }
     this->init();
 };
+#endif
 
-void SkTwoPointConicalGradient::flatten(
-    SkWriteBuffer& buffer) const {
+SkFlattenable* SkTwoPointConicalGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    SkPoint c1 = buffer.readPoint();
+    SkPoint c2 = buffer.readPoint();
+    SkScalar r1 = buffer.readScalar();
+    SkScalar r2 = buffer.readScalar();
+
+    if (buffer.readBool()) {    // flipped
+        SkTSwap(c1, c2);
+        SkTSwap(r1, r2);
+
+        SkColor* colors = desc.mutableColors();
+        SkScalar* pos = desc.mutablePos();
+        const int last = desc.fCount - 1;
+        const int half = desc.fCount >> 1;
+        for (int i = 0; i < half; ++i) {
+            SkTSwap(colors[i], colors[last - i]);
+            if (pos) {
+                SkScalar tmp = pos[i];
+                pos[i] = SK_Scalar1 - pos[last - i];
+                pos[last - i] = SK_Scalar1 - tmp;
+            }
+        }
+        if (pos) {
+            if (desc.fCount & 1) {
+                pos[half] = SK_Scalar1 - pos[half];
+            }
+        }
+    }
+
+    return SkGradientShader::CreateTwoPointConical(c1, r1, c2, r2, desc.fColors, desc.fPos,
+                                                   desc.fCount, desc.fTileMode, desc.fGradFlags,
+                                                   desc.fLocalMatrix);
+}
+
+void SkTwoPointConicalGradient::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writePoint(fCenter1);
     buffer.writePoint(fCenter2);
@@ -381,22 +420,23 @@
 
 #include "SkGr.h"
 
-bool SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                             const SkMatrix* localMatrix, GrColor* grColor,
-                                             GrEffectRef** grEffect)  const {
-    SkASSERT(NULL != context);
+bool SkTwoPointConicalGradient::asFragmentProcessor(GrContext* context,
+                                                    const SkPaint& paint,
+                                                    const SkMatrix* localMatrix,
+                                                    GrColor* paintColor,
+                                                    GrFragmentProcessor** fp)  const {
+    SkASSERT(context);
     SkASSERT(fPtsToUnit.isIdentity());
 
-    *grEffect = Gr2PtConicalGradientEffect::Create(context, *this, fTileMode, localMatrix);
-    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
+    *fp = Gr2PtConicalGradientEffect::Create(context, *this, fTileMode, localMatrix);
+    *paintColor = SkColor2GrColorJustAlpha(paint.getColor());
     return true;
 }
 
 #else
 
-bool SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                            const SkMatrix* localMatrix, GrColor* grColor,
-                                            GrEffectRef** grEffect)  const {
+bool SkTwoPointConicalGradient::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*,
+                                                    GrColor*, GrFragmentProcessor**)  const {
     SkDEBUGFAIL("Should not call in GPU-less build");
     return false;
 }
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.h b/src/effects/gradients/SkTwoPointConicalGradient.h
index f345d08..c43f682 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.h
+++ b/src/effects/gradients/SkTwoPointConicalGradient.h
@@ -44,8 +44,7 @@
 public:
     SkTwoPointConicalGradient(const SkPoint& start, SkScalar startRadius,
                               const SkPoint& end, SkScalar endRadius,
-                              bool flippedGrad, const Descriptor&,
-                              const SkMatrix* localMatrix);
+                              bool flippedGrad, const Descriptor&);
 
 
     virtual size_t contextSize() const SK_OVERRIDE;
@@ -65,8 +64,8 @@
                                  SkMatrix* matrix,
                                  TileMode* xy) const;
     virtual SkShader::GradientType asAGradient(GradientInfo* info) const  SK_OVERRIDE;
-    virtual bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor* grColor,
-                             GrEffectRef**) const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+                                     GrFragmentProcessor**) const SK_OVERRIDE;
     virtual bool isOpaque() const SK_OVERRIDE;
 
     SkScalar getCenterX1() const { return SkPoint::Distance(fCenter1, fCenter2); }
@@ -92,6 +91,7 @@
     SkScalar fRadius2;
     bool fFlippedGrad;
 
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
 };
 
diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
index 4f9f758..206d2d9 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
@@ -11,9 +11,10 @@
 #include "SkTwoPointConicalGradient.h"
 
 #if SK_SUPPORT_GPU
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 // For brevity
-typedef GrGLUniformManager::UniformHandle UniformHandle;
+typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 
 static const SkScalar kErrorTol = 0.00001f;
 static const SkScalar kEdgeErrorTol = 5.f * kErrorTol;
@@ -59,29 +60,28 @@
 class Edge2PtConicalEffect : public GrGradientEffect {
 public:
 
-    static GrEffectRef* Create(GrContext* ctx,
-                               const SkTwoPointConicalGradient& shader,
-                               const SkMatrix& matrix,
-                               SkShader::TileMode tm) {
-        AutoEffectUnref effect(SkNEW_ARGS(Edge2PtConicalEffect, (ctx, shader, matrix, tm)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrContext* ctx,
+                                       const SkTwoPointConicalGradient& shader,
+                                       const SkMatrix& matrix,
+                                       SkShader::TileMode tm) {
+        return SkNEW_ARGS(Edge2PtConicalEffect, (ctx, shader, matrix, tm));
     }
 
     virtual ~Edge2PtConicalEffect() {}
 
     static const char* Name() { return "Two-Point Conical Gradient Edge Touching"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
     // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
     SkScalar center() const { return fCenterX1; }
     SkScalar diffRadius() const { return fDiffRadius; }
     SkScalar radius() const { return fRadius0; }
 
-    typedef GLEdge2PtConicalEffect GLEffect;
+    typedef GLEdge2PtConicalEffect GLProcessor;
 
 private:
-    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
-        const Edge2PtConicalEffect& s = CastEffect<Edge2PtConicalEffect>(sBase);
+    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
+        const Edge2PtConicalEffect& s = sBase.cast<Edge2PtConicalEffect>();
         return (INHERITED::onIsEqual(sBase) &&
                 this->fCenterX1 == s.fCenterX1 &&
                 this->fRadius0 == s.fRadius0 &&
@@ -98,9 +98,12 @@
         fDiffRadius(shader.getDiffRadius()){
         // We should only be calling this shader if we are degenerate case with touching circles
         // When deciding if we are in edge case, we scaled by the end radius for cases when the
-        // start radius was close to zero, otherwise we scaled by the start radius
-        SkASSERT(SkScalarAbs(SkScalarAbs(fDiffRadius) - SkScalarAbs(fCenterX1)) <
-                 kEdgeErrorTol * (fRadius0 < kErrorTol ? shader.getEndRadius() : fRadius0));
+        // start radius was close to zero, otherwise we scaled by the start radius.  In addition
+        // Our test for the edge case in set_matrix_circle_conical has a higher tolerance so we
+        // need the sqrt value below
+        SkASSERT(SkScalarAbs(SkScalarAbs(fDiffRadius) - fCenterX1) <
+                 (fRadius0 < kErrorTol ? shader.getEndRadius() * kEdgeErrorTol :
+                                         fRadius0 * sqrt(kEdgeErrorTol)));
 
         // We pass the linear part of the quadratic as a varying.
         //    float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z)
@@ -116,7 +119,7 @@
         this->addCoordTransform(&fBTransform);
     }
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     // @{
     // Cache of values - these can change arbitrarily, EXCEPT
@@ -134,19 +137,19 @@
 
 class GLEdge2PtConicalEffect : public GrGLGradientEffect {
 public:
-    GLEdge2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
+    GLEdge2PtConicalEffect(const GrBackendProcessorFactory& factory, const GrProcessor&);
     virtual ~GLEdge2PtConicalEffect() { }
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
     UniformHandle fParamUni;
@@ -167,16 +170,19 @@
 
 };
 
-const GrBackendEffectFactory& Edge2PtConicalEffect::getFactory() const {
-    return GrTBackendEffectFactory<Edge2PtConicalEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& Edge2PtConicalEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<Edge2PtConicalEffect>::getInstance();
 }
 
-GR_DEFINE_EFFECT_TEST(Edge2PtConicalEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Edge2PtConicalEffect);
 
-GrEffectRef* Edge2PtConicalEffect::TestCreate(SkRandom* random,
-                                              GrContext* context,
-                                              const GrDrawTargetCaps&,
-                                              GrTexture**) {
+/*
+ * All Two point conical gradient test create functions may occasionally create edge case shaders
+ */
+GrFragmentProcessor* Edge2PtConicalEffect::TestCreate(SkRandom* random,
+                                                      GrContext* context,
+                                                      const GrDrawTargetCaps&,
+                                                      GrTexture**) {
     SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius1 = random->nextUScalar1();
     SkPoint center2;
@@ -203,29 +209,30 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    GrEffectRef* effect;
-    GrColor grColor;
-    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
-    return effect;
+    GrFragmentProcessor* fp;
+    GrColor paintColor;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &fp));
+    return fp;
 }
 
-GLEdge2PtConicalEffect::GLEdge2PtConicalEffect(const GrBackendEffectFactory& factory,
-                                               const GrDrawEffect& drawEffect)
+GLEdge2PtConicalEffect::GLEdge2PtConicalEffect(const GrBackendProcessorFactory& factory,
+                                               const GrProcessor&)
     : INHERITED(factory)
     , fVSVaryingName(NULL)
     , fFSVaryingName(NULL)
     , fCachedRadius(-SK_ScalarMax)
     , fCachedDiffRadius(-SK_ScalarMax) {}
 
-void GLEdge2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
-                                      const GrDrawEffect&,
-                                      EffectKey key,
+void GLEdge2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
+                                      const GrFragmentProcessor&,
+                                      const GrProcessorKey& key,
                                       const char* outputColor,
                                       const char* inputColor,
                                       const TransformedCoordsArray& coords,
                                       const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
-    fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
+    fParamUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
                                          kFloat_GrSLType, "Conical2FSParams", 3);
 
     SkString cName("c");
@@ -239,12 +246,14 @@
     builder->getUniformVariable(fParamUni).appendArrayAccess(2, &p2);
 
     // We interpolate the linear component in coords[1].
-    SkASSERT(coords[0].type() == coords[1].type());
+    SkASSERT(coords[0].getType() == coords[1].getType());
     const char* coords2D;
     SkString bVar;
-    if (kVec3f_GrSLType == coords[0].type()) {
-        builder->fsCodeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n",
-                               coords[0].c_str(), coords[0].c_str(), coords[1].c_str(), coords[1].c_str());
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    if (kVec3f_GrSLType == coords[0].getType()) {
+        fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n",
+                               coords[0].c_str(), coords[0].c_str(), coords[1].c_str(),
+                               coords[1].c_str());
         coords2D = "interpolants.xy";
         bVar = "interpolants.z";
     } else {
@@ -254,28 +263,28 @@
 
     // output will default to transparent black (we simply won't write anything
     // else to it if invalid, instead of discarding or returning prematurely)
-    builder->fsCodeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
+    fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
 
     // c = (x^2)+(y^2) - params[1]
-    builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
+    fsBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
                            cName.c_str(), coords2D, coords2D, p1.c_str());
 
     // linear case: t = -c/b
-    builder->fsCodeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
+    fsBuilder->codeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
                            cName.c_str(), bVar.c_str());
 
     // if r(t) > 0, then t will be the x coordinate
-    builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
+    fsBuilder->codeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
                            p2.c_str(), p0.c_str());
-    builder->fsCodeAppend("\t");
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
-    builder->fsCodeAppend("\t}\n");
+    fsBuilder->codeAppend("\t");
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
+    fsBuilder->codeAppend("\t}\n");
 }
 
-void GLEdge2PtConicalEffect::setData(const GrGLUniformManager& uman,
-                                     const GrDrawEffect& drawEffect) {
-    INHERITED::setData(uman, drawEffect);
-    const Edge2PtConicalEffect& data = drawEffect.castEffect<Edge2PtConicalEffect>();
+void GLEdge2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+                                     const GrProcessor& processor) {
+    INHERITED::setData(pdman, processor);
+    const Edge2PtConicalEffect& data = processor.cast<Edge2PtConicalEffect>();
     SkScalar radius0 = data.radius();
     SkScalar diffRadius = data.diffRadius();
 
@@ -288,15 +297,15 @@
             SkScalarToFloat(diffRadius)
         };
 
-        uman.set1fv(fParamUni, 3, values);
+        pdman.set1fv(fParamUni, 3, values);
         fCachedRadius = radius0;
         fCachedDiffRadius = diffRadius;
     }
 }
 
-GrGLEffect::EffectKey GLEdge2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                     const GrGLCaps&) {
-    return GenBaseGradientKey(drawEffect);
+void GLEdge2PtConicalEffect::GenKey(const GrProcessor& processor,
+                                    const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    b->add32(GenBaseGradientKey(processor));
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -366,28 +375,27 @@
 class FocalOutside2PtConicalEffect : public GrGradientEffect {
 public:
 
-    static GrEffectRef* Create(GrContext* ctx,
-                               const SkTwoPointConicalGradient& shader,
-                               const SkMatrix& matrix,
-                               SkShader::TileMode tm,
-                               SkScalar focalX) {
-        AutoEffectUnref effect(SkNEW_ARGS(FocalOutside2PtConicalEffect, (ctx, shader, matrix, tm, focalX)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrContext* ctx,
+                                       const SkTwoPointConicalGradient& shader,
+                                       const SkMatrix& matrix,
+                                       SkShader::TileMode tm,
+                                       SkScalar focalX) {
+        return SkNEW_ARGS(FocalOutside2PtConicalEffect, (ctx, shader, matrix, tm, focalX));
     }
 
     virtual ~FocalOutside2PtConicalEffect() { }
 
     static const char* Name() { return "Two-Point Conical Gradient Focal Outside"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
     bool isFlipped() const { return fIsFlipped; }
     SkScalar focal() const { return fFocalX; }
 
-    typedef GLFocalOutside2PtConicalEffect GLEffect;
+    typedef GLFocalOutside2PtConicalEffect GLProcessor;
 
 private:
-    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
-        const FocalOutside2PtConicalEffect& s = CastEffect<FocalOutside2PtConicalEffect>(sBase);
+    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
+        const FocalOutside2PtConicalEffect& s = sBase.cast<FocalOutside2PtConicalEffect>();
         return (INHERITED::onIsEqual(sBase) &&
                 this->fFocalX == s.fFocalX &&
                 this->fIsFlipped == s.fIsFlipped);
@@ -400,7 +408,7 @@
                                  SkScalar focalX)
     : INHERITED(ctx, shader, matrix, tm), fFocalX(focalX), fIsFlipped(shader.isFlippedGrad()) {}
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     SkScalar         fFocalX;
     bool             fIsFlipped;
@@ -410,19 +418,19 @@
 
 class GLFocalOutside2PtConicalEffect : public GrGLGradientEffect {
 public:
-    GLFocalOutside2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
+    GLFocalOutside2PtConicalEffect(const GrBackendProcessorFactory& factory, const GrProcessor&);
     virtual ~GLFocalOutside2PtConicalEffect() { }
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
     UniformHandle fParamUni;
@@ -444,16 +452,19 @@
 
 };
 
-const GrBackendEffectFactory& FocalOutside2PtConicalEffect::getFactory() const {
-    return GrTBackendEffectFactory<FocalOutside2PtConicalEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& FocalOutside2PtConicalEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<FocalOutside2PtConicalEffect>::getInstance();
 }
 
-GR_DEFINE_EFFECT_TEST(FocalOutside2PtConicalEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(FocalOutside2PtConicalEffect);
 
-GrEffectRef* FocalOutside2PtConicalEffect::TestCreate(SkRandom* random,
-                                                      GrContext* context,
-                                                      const GrDrawTargetCaps&,
-                                                      GrTexture**) {
+/*
+ * All Two point conical gradient test create functions may occasionally create edge case shaders
+ */
+GrFragmentProcessor* FocalOutside2PtConicalEffect::TestCreate(SkRandom* random,
+                                                              GrContext* context,
+                                                              const GrDrawTargetCaps&,
+                                                              GrTexture**) {
     SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius1 = 0.f;
     SkPoint center2;
@@ -477,31 +488,32 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    GrEffectRef* effect;
-    GrColor grColor;
-    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
+    GrFragmentProcessor* effect;
+    GrColor paintColor;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &effect));
     return effect;
 }
 
-GLFocalOutside2PtConicalEffect::GLFocalOutside2PtConicalEffect(const GrBackendEffectFactory& factory,
-                                                               const GrDrawEffect& drawEffect)
+GLFocalOutside2PtConicalEffect::GLFocalOutside2PtConicalEffect(const GrBackendProcessorFactory& factory,
+                                                               const GrProcessor& processor)
     : INHERITED(factory)
     , fVSVaryingName(NULL)
     , fFSVaryingName(NULL)
     , fCachedFocal(SK_ScalarMax) {
-    const FocalOutside2PtConicalEffect& data = drawEffect.castEffect<FocalOutside2PtConicalEffect>();
+    const FocalOutside2PtConicalEffect& data = processor.cast<FocalOutside2PtConicalEffect>();
     fIsFlipped = data.isFlipped();
 }
 
-void GLFocalOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
-                                              const GrDrawEffect&,
-                                              EffectKey key,
+void GLFocalOutside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
+                                              const GrFragmentProcessor&,
+                                              const GrProcessorKey& key,
                                               const char* outputColor,
                                               const char* inputColor,
                                               const TransformedCoordsArray& coords,
                                               const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
-    fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
+    fParamUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
                                          kFloat_GrSLType, "Conical2FSParams", 2);
     SkString tName("t");
     SkString p0; // focalX
@@ -511,39 +523,40 @@
     builder->getUniformVariable(fParamUni).appendArrayAccess(1, &p1);
 
     // if we have a vec3 from being in perspective, convert it to a vec2 first
-    SkString coords2DString = builder->ensureFSCoords2D(coords, 0);
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
     const char* coords2D = coords2DString.c_str();
 
     // t = p.x * focal.x +/- sqrt(p.x^2 + (1 - focal.x^2) * p.y^2)
 
     // output will default to transparent black (we simply won't write anything
     // else to it if invalid, instead of discarding or returning prematurely)
-    builder->fsCodeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
+    fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
 
-    builder->fsCodeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D);
-    builder->fsCodeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D);
-    builder->fsCodeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str());
+    fsBuilder->codeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D);
+    fsBuilder->codeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D);
+    fsBuilder->codeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str());
 
     // Must check to see if we flipped the circle order (to make sure start radius < end radius)
     // If so we must also flip sign on sqrt
     if (!fIsFlipped) {
-        builder->fsCodeAppendf("\tfloat %s = %s.x * %s  + sqrt(d);\n", tName.c_str(),
+        fsBuilder->codeAppendf("\tfloat %s = %s.x * %s  + sqrt(d);\n", tName.c_str(),
                                coords2D, p0.c_str());
     } else {
-        builder->fsCodeAppendf("\tfloat %s = %s.x * %s  - sqrt(d);\n", tName.c_str(),
+        fsBuilder->codeAppendf("\tfloat %s = %s.x * %s  - sqrt(d);\n", tName.c_str(),
                                coords2D, p0.c_str());
     }
 
-    builder->fsCodeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str());
-    builder->fsCodeAppend("\t\t");
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
-    builder->fsCodeAppend("\t}\n");
+    fsBuilder->codeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str());
+    fsBuilder->codeAppend("\t\t");
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
+    fsBuilder->codeAppend("\t}\n");
 }
 
-void GLFocalOutside2PtConicalEffect::setData(const GrGLUniformManager& uman,
-                                             const GrDrawEffect& drawEffect) {
-    INHERITED::setData(uman, drawEffect);
-    const FocalOutside2PtConicalEffect& data = drawEffect.castEffect<FocalOutside2PtConicalEffect>();
+void GLFocalOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+                                             const GrProcessor& processor) {
+    INHERITED::setData(pdman, processor);
+    const FocalOutside2PtConicalEffect& data = processor.cast<FocalOutside2PtConicalEffect>();
     SkASSERT(data.isFlipped() == fIsFlipped);
     SkScalar focal = data.focal();
 
@@ -555,23 +568,16 @@
             SkScalarToFloat(oneMinus2F),
         };
 
-        uman.set1fv(fParamUni, 2, values);
+        pdman.set1fv(fParamUni, 2, values);
         fCachedFocal = focal;
     }
 }
 
-GrGLEffect::EffectKey GLFocalOutside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                             const GrGLCaps&) {
-    enum {
-        kIsFlipped = 1 << kBaseKeyBitCnt,
-    };
-
-    EffectKey key = GenBaseGradientKey(drawEffect);
-
-    if (drawEffect.castEffect<FocalOutside2PtConicalEffect>().isFlipped()) {
-        key |= kIsFlipped;
-    }
-    return key;
+void GLFocalOutside2PtConicalEffect::GenKey(const GrProcessor& processor,
+                                            const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    uint32_t* key = b->add32n(2);
+    key[0] = GenBaseGradientKey(processor);
+    key[1] = processor.cast<FocalOutside2PtConicalEffect>().isFlipped();
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -581,27 +587,26 @@
 class FocalInside2PtConicalEffect : public GrGradientEffect {
 public:
 
-    static GrEffectRef* Create(GrContext* ctx,
-                               const SkTwoPointConicalGradient& shader,
-                               const SkMatrix& matrix,
-                               SkShader::TileMode tm,
-                               SkScalar focalX) {
-        AutoEffectUnref effect(SkNEW_ARGS(FocalInside2PtConicalEffect, (ctx, shader, matrix, tm, focalX)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrContext* ctx,
+                                       const SkTwoPointConicalGradient& shader,
+                                       const SkMatrix& matrix,
+                                       SkShader::TileMode tm,
+                                       SkScalar focalX) {
+        return SkNEW_ARGS(FocalInside2PtConicalEffect, (ctx, shader, matrix, tm, focalX));
     }
 
     virtual ~FocalInside2PtConicalEffect() {}
 
     static const char* Name() { return "Two-Point Conical Gradient Focal Inside"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
     SkScalar focal() const { return fFocalX; }
 
-    typedef GLFocalInside2PtConicalEffect GLEffect;
+    typedef GLFocalInside2PtConicalEffect GLProcessor;
 
 private:
-    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
-        const FocalInside2PtConicalEffect& s = CastEffect<FocalInside2PtConicalEffect>(sBase);
+    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
+        const FocalInside2PtConicalEffect& s = sBase.cast<FocalInside2PtConicalEffect>();
         return (INHERITED::onIsEqual(sBase) &&
                 this->fFocalX == s.fFocalX);
     }
@@ -613,7 +618,7 @@
                                 SkScalar focalX)
         : INHERITED(ctx, shader, matrix, tm), fFocalX(focalX) {}
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     SkScalar         fFocalX;
 
@@ -622,19 +627,19 @@
 
 class GLFocalInside2PtConicalEffect : public GrGLGradientEffect {
 public:
-    GLFocalInside2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
+    GLFocalInside2PtConicalEffect(const GrBackendProcessorFactory& factory, const GrProcessor&);
     virtual ~GLFocalInside2PtConicalEffect() {}
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
     UniformHandle fFocalUni;
@@ -654,16 +659,19 @@
 
 };
 
-const GrBackendEffectFactory& FocalInside2PtConicalEffect::getFactory() const {
-    return GrTBackendEffectFactory<FocalInside2PtConicalEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& FocalInside2PtConicalEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<FocalInside2PtConicalEffect>::getInstance();
 }
 
-GR_DEFINE_EFFECT_TEST(FocalInside2PtConicalEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(FocalInside2PtConicalEffect);
 
-GrEffectRef* FocalInside2PtConicalEffect::TestCreate(SkRandom* random,
-                                                     GrContext* context,
-                                                     const GrDrawTargetCaps&,
-                                                     GrTexture**) {
+/*
+ * All Two point conical gradient test create functions may occasionally create edge case shaders
+ */
+GrFragmentProcessor* FocalInside2PtConicalEffect::TestCreate(SkRandom* random,
+                                                             GrContext* context,
+                                                             const GrDrawTargetCaps&,
+                                                             GrTexture**) {
     SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius1 = 0.f;
     SkPoint center2;
@@ -689,28 +697,29 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    GrColor grColor;
-    GrEffectRef* grEffect;
-    shader->asNewEffect(context, paint, NULL, &grColor, &grEffect);
-    return grEffect;
+    GrColor paintColor;
+    GrFragmentProcessor* fp;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &fp));
+    return fp;
 }
 
-GLFocalInside2PtConicalEffect::GLFocalInside2PtConicalEffect(const GrBackendEffectFactory& factory,
-                                                             const GrDrawEffect& drawEffect)
+GLFocalInside2PtConicalEffect::GLFocalInside2PtConicalEffect(const GrBackendProcessorFactory& factory,
+                                                             const GrProcessor&)
     : INHERITED(factory)
     , fVSVaryingName(NULL)
     , fFSVaryingName(NULL)
     , fCachedFocal(SK_ScalarMax) {}
 
-void GLFocalInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
-                                             const GrDrawEffect&,
-                                             EffectKey key,
+void GLFocalInside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
+                                             const GrFragmentProcessor&,
+                                             const GrProcessorKey& key,
                                              const char* outputColor,
                                              const char* inputColor,
                                              const TransformedCoordsArray& coords,
                                              const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
-    fFocalUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
+    fFocalUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                     kFloat_GrSLType, "Conical2FSParams");
     SkString tName("t");
 
@@ -719,31 +728,32 @@
     GrGLShaderVar focal = builder->getUniformVariable(fFocalUni);
 
     // if we have a vec3 from being in perspective, convert it to a vec2 first
-    SkString coords2DString = builder->ensureFSCoords2D(coords, 0);
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
     const char* coords2D = coords2DString.c_str();
 
     // t = p.x * focalX + length(p)
-    builder->fsCodeAppendf("\tfloat %s = %s.x * %s  + length(%s);\n", tName.c_str(),
+    fsBuilder->codeAppendf("\tfloat %s = %s.x * %s  + length(%s);\n", tName.c_str(),
                            coords2D, focal.c_str(), coords2D);
 
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
-void GLFocalInside2PtConicalEffect::setData(const GrGLUniformManager& uman,
-                                            const GrDrawEffect& drawEffect) {
-    INHERITED::setData(uman, drawEffect);
-    const FocalInside2PtConicalEffect& data = drawEffect.castEffect<FocalInside2PtConicalEffect>();
+void GLFocalInside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+                                            const GrProcessor& processor) {
+    INHERITED::setData(pdman, processor);
+    const FocalInside2PtConicalEffect& data = processor.cast<FocalInside2PtConicalEffect>();
     SkScalar focal = data.focal();
 
     if (fCachedFocal != focal) {
-        uman.set1f(fFocalUni, SkScalarToFloat(focal));
+        pdman.set1f(fFocalUni, SkScalarToFloat(focal));
         fCachedFocal = focal;
     }
 }
 
-GrGLEffect::EffectKey GLFocalInside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                            const GrGLCaps&) {
-    return GenBaseGradientKey(drawEffect);
+void GLFocalInside2PtConicalEffect::GenKey(const GrProcessor& processor,
+                                           const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    b->add32(GenBaseGradientKey(processor));
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -815,19 +825,18 @@
 class CircleInside2PtConicalEffect : public GrGradientEffect {
 public:
 
-    static GrEffectRef* Create(GrContext* ctx,
-                               const SkTwoPointConicalGradient& shader,
-                               const SkMatrix& matrix,
-                               SkShader::TileMode tm,
-                               const CircleConicalInfo& info) {
-        AutoEffectUnref effect(SkNEW_ARGS(CircleInside2PtConicalEffect, (ctx, shader, matrix, tm, info)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrContext* ctx,
+                                       const SkTwoPointConicalGradient& shader,
+                                       const SkMatrix& matrix,
+                                       SkShader::TileMode tm,
+                                       const CircleConicalInfo& info) {
+        return SkNEW_ARGS(CircleInside2PtConicalEffect, (ctx, shader, matrix, tm, info));
     }
 
     virtual ~CircleInside2PtConicalEffect() {}
 
     static const char* Name() { return "Two-Point Conical Gradient Inside"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
     SkScalar centerX() const { return fInfo.fCenterEnd.fX; }
     SkScalar centerY() const { return fInfo.fCenterEnd.fY; }
@@ -835,11 +844,11 @@
     SkScalar B() const { return fInfo.fB; }
     SkScalar C() const { return fInfo.fC; }
 
-    typedef GLCircleInside2PtConicalEffect GLEffect;
+    typedef GLCircleInside2PtConicalEffect GLProcessor;
 
 private:
-    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
-        const CircleInside2PtConicalEffect& s = CastEffect<CircleInside2PtConicalEffect>(sBase);
+    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
+        const CircleInside2PtConicalEffect& s = sBase.cast<CircleInside2PtConicalEffect>();
         return (INHERITED::onIsEqual(sBase) &&
                 this->fInfo.fCenterEnd == s.fInfo.fCenterEnd &&
                 this->fInfo.fA == s.fInfo.fA &&
@@ -854,7 +863,7 @@
                                  const CircleConicalInfo& info)
         : INHERITED(ctx, shader, matrix, tm), fInfo(info) {}
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     const CircleConicalInfo fInfo;
 
@@ -863,19 +872,19 @@
 
 class GLCircleInside2PtConicalEffect : public GrGLGradientEffect {
 public:
-    GLCircleInside2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
+    GLCircleInside2PtConicalEffect(const GrBackendProcessorFactory& factory, const GrProcessor&);
     virtual ~GLCircleInside2PtConicalEffect() {}
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
     UniformHandle fCenterUni;
@@ -900,16 +909,19 @@
 
 };
 
-const GrBackendEffectFactory& CircleInside2PtConicalEffect::getFactory() const {
-    return GrTBackendEffectFactory<CircleInside2PtConicalEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& CircleInside2PtConicalEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<CircleInside2PtConicalEffect>::getInstance();
 }
 
-GR_DEFINE_EFFECT_TEST(CircleInside2PtConicalEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleInside2PtConicalEffect);
 
-GrEffectRef* CircleInside2PtConicalEffect::TestCreate(SkRandom* random,
-                                                      GrContext* context,
-                                                      const GrDrawTargetCaps&,
-                                                      GrTexture**) {
+/*
+ * All Two point conical gradient test create functions may occasionally create edge case shaders
+ */
+GrFragmentProcessor* CircleInside2PtConicalEffect::TestCreate(SkRandom* random,
+                                                              GrContext* context,
+                                                              const GrDrawTargetCaps&,
+                                                              GrTexture**) {
     SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius1 = random->nextUScalar1() + 0.0001f; // make sure radius1 != 0
     SkPoint center2;
@@ -934,14 +946,14 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    GrColor grColor;
-    GrEffectRef* grEffect;
-    shader->asNewEffect(context, paint, NULL, &grColor, &grEffect);
-    return grEffect;
+    GrColor paintColor;
+    GrFragmentProcessor* processor;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &processor));
+    return processor;
 }
 
-GLCircleInside2PtConicalEffect::GLCircleInside2PtConicalEffect(const GrBackendEffectFactory& factory,
-                                                               const GrDrawEffect& drawEffect)
+GLCircleInside2PtConicalEffect::GLCircleInside2PtConicalEffect(const GrBackendProcessorFactory& factory,
+                                                               const GrProcessor& processor)
     : INHERITED(factory)
     , fVSVaryingName(NULL)
     , fFSVaryingName(NULL)
@@ -951,17 +963,18 @@
     , fCachedB(SK_ScalarMax)
     , fCachedC(SK_ScalarMax) {}
 
-void GLCircleInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
-                                              const GrDrawEffect&,
-                                              EffectKey key,
+void GLCircleInside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
+                                              const GrFragmentProcessor&,
+                                              const GrProcessorKey& key,
                                               const char* outputColor,
                                               const char* inputColor,
                                               const TransformedCoordsArray& coords,
                                               const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
-    fCenterUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
+    fCenterUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                      kVec2f_GrSLType, "Conical2FSCenter");
-    fParamUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fParamUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                     kVec3f_GrSLType, "Conical2FSParams");
     SkString tName("t");
 
@@ -972,7 +985,8 @@
     GrGLShaderVar params = builder->getUniformVariable(fParamUni);
 
     // if we have a vec3 from being in perspective, convert it to a vec2 first
-    SkString coords2DString = builder->ensureFSCoords2D(coords, 0);
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
     const char* coords2D = coords2DString.c_str();
 
     // p = coords2D
@@ -983,18 +997,19 @@
     // C = 1 / A
     // d = dot(e, p) + B
     // t = d +/- sqrt(d^2 - A * dot(p, p) + C)
-    builder->fsCodeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D);
-    builder->fsCodeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(), params.c_str());
-    builder->fsCodeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n",
+    fsBuilder->codeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D);
+    fsBuilder->codeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(),
+                           params.c_str());
+    fsBuilder->codeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n",
                            tName.c_str(), params.c_str(), params.c_str());
 
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
-void GLCircleInside2PtConicalEffect::setData(const GrGLUniformManager& uman,
-                                             const GrDrawEffect& drawEffect) {
-    INHERITED::setData(uman, drawEffect);
-    const CircleInside2PtConicalEffect& data = drawEffect.castEffect<CircleInside2PtConicalEffect>();
+void GLCircleInside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+                                             const GrProcessor& processor) {
+    INHERITED::setData(pdman, processor);
+    const CircleInside2PtConicalEffect& data = processor.cast<CircleInside2PtConicalEffect>();
     SkScalar centerX = data.centerX();
     SkScalar centerY = data.centerY();
     SkScalar A = data.A();
@@ -1004,8 +1019,8 @@
     if (fCachedCenterX != centerX || fCachedCenterY != centerY ||
         fCachedA != A || fCachedB != B || fCachedC != C) {
 
-        uman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY));
-        uman.set3f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C));
+        pdman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY));
+        pdman.set3f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C));
 
         fCachedCenterX = centerX;
         fCachedCenterY = centerY;
@@ -1015,10 +1030,9 @@
     }
 }
 
-GrGLEffect::EffectKey GLCircleInside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                             const GrGLCaps&) {
-    EffectKey key = GenBaseGradientKey(drawEffect);
-    return key;
+void GLCircleInside2PtConicalEffect::GenKey(const GrProcessor& processor,
+                                            const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    b->add32(GenBaseGradientKey(processor));
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1028,19 +1042,18 @@
 class CircleOutside2PtConicalEffect : public GrGradientEffect {
 public:
 
-    static GrEffectRef* Create(GrContext* ctx,
-                               const SkTwoPointConicalGradient& shader,
-                               const SkMatrix& matrix,
-                               SkShader::TileMode tm,
-                               const CircleConicalInfo& info) {
-        AutoEffectUnref effect(SkNEW_ARGS(CircleOutside2PtConicalEffect, (ctx, shader, matrix, tm, info)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrContext* ctx,
+                                       const SkTwoPointConicalGradient& shader,
+                                       const SkMatrix& matrix,
+                                       SkShader::TileMode tm,
+                                       const CircleConicalInfo& info) {
+        return SkNEW_ARGS(CircleOutside2PtConicalEffect, (ctx, shader, matrix, tm, info));
     }
 
     virtual ~CircleOutside2PtConicalEffect() {}
 
     static const char* Name() { return "Two-Point Conical Gradient Outside"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
     SkScalar centerX() const { return fInfo.fCenterEnd.fX; }
     SkScalar centerY() const { return fInfo.fCenterEnd.fY; }
@@ -1050,11 +1063,11 @@
     SkScalar tLimit() const { return fTLimit; }
     bool isFlipped() const { return fIsFlipped; }
 
-    typedef GLCircleOutside2PtConicalEffect GLEffect;
+    typedef GLCircleOutside2PtConicalEffect GLProcessor;
 
 private:
-    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
-        const CircleOutside2PtConicalEffect& s = CastEffect<CircleOutside2PtConicalEffect>(sBase);
+    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
+        const CircleOutside2PtConicalEffect& s = sBase.cast<CircleOutside2PtConicalEffect>();
         return (INHERITED::onIsEqual(sBase) &&
                 this->fInfo.fCenterEnd == s.fInfo.fCenterEnd &&
                 this->fInfo.fA == s.fInfo.fA &&
@@ -1071,7 +1084,8 @@
                                   const CircleConicalInfo& info)
         : INHERITED(ctx, shader, matrix, tm), fInfo(info) {
         if (shader.getStartRadius() != shader.getEndRadius()) {
-            fTLimit = SkScalarDiv(shader.getStartRadius(), (shader.getStartRadius() - shader.getEndRadius()));
+            fTLimit = SkScalarDiv(shader.getStartRadius(),
+                                  (shader.getStartRadius() - shader.getEndRadius()));
         } else {
             fTLimit = SK_ScalarMin;
         }
@@ -1079,7 +1093,7 @@
         fIsFlipped = shader.isFlippedGrad();
     }
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     const CircleConicalInfo fInfo;
     SkScalar fTLimit;
@@ -1090,19 +1104,19 @@
 
 class GLCircleOutside2PtConicalEffect : public GrGLGradientEffect {
 public:
-    GLCircleOutside2PtConicalEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&);
+    GLCircleOutside2PtConicalEffect(const GrBackendProcessorFactory&, const GrProcessor&);
     virtual ~GLCircleOutside2PtConicalEffect() {}
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
     UniformHandle fCenterUni;
@@ -1130,16 +1144,19 @@
 
 };
 
-const GrBackendEffectFactory& CircleOutside2PtConicalEffect::getFactory() const {
-    return GrTBackendEffectFactory<CircleOutside2PtConicalEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& CircleOutside2PtConicalEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<CircleOutside2PtConicalEffect>::getInstance();
 }
 
-GR_DEFINE_EFFECT_TEST(CircleOutside2PtConicalEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleOutside2PtConicalEffect);
 
-GrEffectRef* CircleOutside2PtConicalEffect::TestCreate(SkRandom* random,
-                                                       GrContext* context,
-                                                       const GrDrawTargetCaps&,
-                                                       GrTexture**) {
+/*
+ * All Two point conical gradient test create functions may occasionally create edge case shaders
+ */
+GrFragmentProcessor* CircleOutside2PtConicalEffect::TestCreate(SkRandom* random,
+                                                               GrContext* context,
+                                                               const GrDrawTargetCaps&,
+                                                               GrTexture**) {
     SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius1 = random->nextUScalar1() + 0.0001f; // make sure radius1 != 0
     SkPoint center2;
@@ -1149,11 +1166,11 @@
         center2.set(random->nextUScalar1(), random->nextUScalar1());
         // If the circles share a center than we can't be in the outside case
     } while (center1 == center2);
-        SkPoint diff = center2 - center1;
-        diffLen = diff.length();
-        // Below makes sure that circle one is not contained within circle two
-        // and have radius2 >= radius to match sorting on cpu side
-        radius2 = radius1 + random->nextRangeF(0.f, diffLen);
+    SkPoint diff = center2 - center1;
+    diffLen = diff.length();
+    // Below makes sure that circle one is not contained within circle two
+    // and have radius2 >= radius to match sorting on cpu side
+    radius2 = radius1 + random->nextRangeF(0.f, diffLen);
 
     SkColor colors[kMaxRandomGradientColors];
     SkScalar stopsArray[kMaxRandomGradientColors];
@@ -1165,14 +1182,14 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    GrColor grColor;
-    GrEffectRef* grEffect;
-    shader->asNewEffect(context, paint, NULL, &grColor, &grEffect);
-    return grEffect;
+    GrColor paintColor;
+    GrFragmentProcessor* processor;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &processor));
+    return processor;
 }
 
-GLCircleOutside2PtConicalEffect::GLCircleOutside2PtConicalEffect(const GrBackendEffectFactory& factory,
-                                                                 const GrDrawEffect& drawEffect)
+GLCircleOutside2PtConicalEffect::GLCircleOutside2PtConicalEffect(const GrBackendProcessorFactory& factory,
+                                                                 const GrProcessor& processor)
     : INHERITED(factory)
     , fVSVaryingName(NULL)
     , fFSVaryingName(NULL)
@@ -1182,21 +1199,22 @@
     , fCachedB(SK_ScalarMax)
     , fCachedC(SK_ScalarMax)
     , fCachedTLimit(SK_ScalarMax) {
-    const CircleOutside2PtConicalEffect& data = drawEffect.castEffect<CircleOutside2PtConicalEffect>();
+    const CircleOutside2PtConicalEffect& data = processor.cast<CircleOutside2PtConicalEffect>();
     fIsFlipped = data.isFlipped();
     }
 
-void GLCircleOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
-                                               const GrDrawEffect&,
-                                               EffectKey key,
+void GLCircleOutside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
+                                               const GrFragmentProcessor&,
+                                               const GrProcessorKey& key,
                                                const char* outputColor,
                                                const char* inputColor,
                                                const TransformedCoordsArray& coords,
                                                const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
-    fCenterUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
+    fCenterUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                      kVec2f_GrSLType, "Conical2FSCenter");
-    fParamUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fParamUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                     kVec4f_GrSLType, "Conical2FSParams");
     SkString tName("t");
 
@@ -1207,12 +1225,13 @@
     GrGLShaderVar params = builder->getUniformVariable(fParamUni);
 
     // if we have a vec3 from being in perspective, convert it to a vec2 first
-    SkString coords2DString = builder->ensureFSCoords2D(coords, 0);
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
     const char* coords2D = coords2DString.c_str();
 
     // output will default to transparent black (we simply won't write anything
     // else to it if invalid, instead of discarding or returning prematurely)
-    builder->fsCodeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
+    fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
 
     // p = coords2D
     // e = center end
@@ -1223,28 +1242,30 @@
     // d = dot(e, p) + B
     // t = d +/- sqrt(d^2 - A * dot(p, p) + C)
 
-    builder->fsCodeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D);
-    builder->fsCodeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(), params.c_str());
-    builder->fsCodeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(), params.c_str());
+    fsBuilder->codeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D);
+    fsBuilder->codeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(),
+                           params.c_str());
+    fsBuilder->codeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(),
+                           params.c_str());
 
     // Must check to see if we flipped the circle order (to make sure start radius < end radius)
     // If so we must also flip sign on sqrt
     if (!fIsFlipped) {
-        builder->fsCodeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str());
+        fsBuilder->codeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str());
     } else {
-        builder->fsCodeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str());
+        fsBuilder->codeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str());
     }
 
-    builder->fsCodeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str());
-    builder->fsCodeAppend("\t\t");
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
-    builder->fsCodeAppend("\t}\n");
+    fsBuilder->codeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str());
+    fsBuilder->codeAppend("\t\t");
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
+    fsBuilder->codeAppend("\t}\n");
 }
 
-void GLCircleOutside2PtConicalEffect::setData(const GrGLUniformManager& uman,
-                                              const GrDrawEffect& drawEffect) {
-    INHERITED::setData(uman, drawEffect);
-    const CircleOutside2PtConicalEffect& data = drawEffect.castEffect<CircleOutside2PtConicalEffect>();
+void GLCircleOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+                                              const GrProcessor& processor) {
+    INHERITED::setData(pdman, processor);
+    const CircleOutside2PtConicalEffect& data = processor.cast<CircleOutside2PtConicalEffect>();
     SkASSERT(data.isFlipped() == fIsFlipped);
     SkScalar centerX = data.centerX();
     SkScalar centerY = data.centerY();
@@ -1256,8 +1277,8 @@
     if (fCachedCenterX != centerX || fCachedCenterY != centerY ||
         fCachedA != A || fCachedB != B || fCachedC != C || fCachedTLimit != tLimit) {
 
-        uman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY));
-        uman.set4f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C),
+        pdman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY));
+        pdman.set4f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C),
                    SkScalarToFloat(tLimit));
 
         fCachedCenterX = centerX;
@@ -1269,26 +1290,19 @@
     }
 }
 
-GrGLEffect::EffectKey GLCircleOutside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                              const GrGLCaps&) {
-    enum {
-        kIsFlipped = 1 << kBaseKeyBitCnt,
-    };
-
-    EffectKey key = GenBaseGradientKey(drawEffect);
-
-    if (drawEffect.castEffect<CircleOutside2PtConicalEffect>().isFlipped()) {
-        key |= kIsFlipped;
-    }
-    return key;
+void GLCircleOutside2PtConicalEffect::GenKey(const GrProcessor& processor,
+                                             const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    uint32_t* key = b->add32n(2);
+    key[0] = GenBaseGradientKey(processor);
+    key[1] = processor.cast<CircleOutside2PtConicalEffect>().isFlipped();
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GrEffectRef* Gr2PtConicalGradientEffect::Create(GrContext* ctx,
-                                                const SkTwoPointConicalGradient& shader,
-                                                SkShader::TileMode tm,
-                                                const SkMatrix* localMatrix) {
+GrFragmentProcessor* Gr2PtConicalGradientEffect::Create(GrContext* ctx,
+                                                        const SkTwoPointConicalGradient& shader,
+                                                        SkShader::TileMode tm,
+                                                        const SkMatrix* localMatrix) {
     SkMatrix matrix;
     if (!shader.getLocalMatrix().invert(&matrix)) {
         return NULL;
diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.h b/src/effects/gradients/SkTwoPointConicalGradient_gpu.h
index 2b0f061..54937c6 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.h
+++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.h
@@ -10,7 +10,7 @@
 
 #include "SkGradientShaderPriv.h"
 
-class GrEffectRef;
+class GrProcessor;
 class SkTwoPointConicalGradient;
 
 namespace Gr2PtConicalGradientEffect {
@@ -18,8 +18,8 @@
      * Creates an effect that produces a two point conical gradient based on the
      * shader passed in.
      */
-    GrEffectRef* Create(GrContext* ctx, const SkTwoPointConicalGradient& shader,
-                        SkShader::TileMode tm, const SkMatrix* localMatrix);
+    GrFragmentProcessor* Create(GrContext* ctx, const SkTwoPointConicalGradient& shader,
+                                SkShader::TileMode tm, const SkMatrix* localMatrix);
 };
 
 #endif
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index e3d8996..3b4be2d 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -167,15 +167,15 @@
 
 /////////////////////////////////////////////////////////////////////
 
-SkTwoPointRadialGradient::SkTwoPointRadialGradient(
-    const SkPoint& start, SkScalar startRadius,
-    const SkPoint& end, SkScalar endRadius,
-    const Descriptor& desc, const SkMatrix* localMatrix)
-    : SkGradientShaderBase(desc, localMatrix),
-      fCenter1(start),
-      fCenter2(end),
-      fRadius1(startRadius),
-      fRadius2(endRadius) {
+SkTwoPointRadialGradient::SkTwoPointRadialGradient(const SkPoint& start, SkScalar startRadius,
+                                                   const SkPoint& end, SkScalar endRadius,
+                                                   const Descriptor& desc)
+    : SkGradientShaderBase(desc)
+    , fCenter1(start)
+    , fCenter2(end)
+    , fRadius1(startRadius)
+    , fRadius2(endRadius)
+{
     init();
 }
 
@@ -343,8 +343,8 @@
 }
 #endif
 
-SkTwoPointRadialGradient::SkTwoPointRadialGradient(
-    SkReadBuffer& buffer)
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkTwoPointRadialGradient::SkTwoPointRadialGradient(SkReadBuffer& buffer)
     : INHERITED(buffer),
       fCenter1(buffer.readPoint()),
       fCenter2(buffer.readPoint()),
@@ -352,6 +352,21 @@
       fRadius2(buffer.readScalar()) {
     init();
 };
+#endif
+
+SkFlattenable* SkTwoPointRadialGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    const SkPoint c1 = buffer.readPoint();
+    const SkPoint c2 = buffer.readPoint();
+    const SkScalar r1 = buffer.readScalar();
+    const SkScalar r2 = buffer.readScalar();
+    return SkGradientShader::CreateTwoPointRadial(c1, r1, c2, r2, desc.fColors, desc.fPos,
+                                                  desc.fCount, desc.fTileMode, desc.fGradFlags,
+                                                  desc.fLocalMatrix);
+}
 
 void SkTwoPointRadialGradient::flatten(
     SkWriteBuffer& buffer) const {
@@ -382,29 +397,30 @@
 
 #if SK_SUPPORT_GPU
 
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "SkGr.h"
 
 // For brevity
-typedef GrGLUniformManager::UniformHandle UniformHandle;
+typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 
 class GrGLRadial2Gradient : public GrGLGradientEffect {
 
 public:
 
-    GrGLRadial2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffect&);
+    GrGLRadial2Gradient(const GrBackendProcessorFactory& factory, const GrProcessor&);
     virtual ~GrGLRadial2Gradient() { }
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
 
@@ -434,19 +450,18 @@
 
 class GrRadial2Gradient : public GrGradientEffect {
 public:
-    static GrEffectRef* Create(GrContext* ctx,
-                               const SkTwoPointRadialGradient& shader,
-                               const SkMatrix& matrix,
-                               SkShader::TileMode tm) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrRadial2Gradient, (ctx, shader, matrix, tm)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrContext* ctx,
+                                       const SkTwoPointRadialGradient& shader,
+                                       const SkMatrix& matrix,
+                                       SkShader::TileMode tm) {
+        return SkNEW_ARGS(GrRadial2Gradient, (ctx, shader, matrix, tm));
     }
 
     virtual ~GrRadial2Gradient() { }
 
     static const char* Name() { return "Two-Point Radial Gradient"; }
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<GrRadial2Gradient>::getInstance();
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<GrRadial2Gradient>::getInstance();
     }
 
     // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
@@ -455,11 +470,11 @@
     SkScalar radius() const { return fRadius0; }
     bool isPosRoot() const { return SkToBool(fPosRoot); }
 
-    typedef GrGLRadial2Gradient GLEffect;
+    typedef GrGLRadial2Gradient GLProcessor;
 
 private:
-    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
-        const GrRadial2Gradient& s = CastEffect<GrRadial2Gradient>(sBase);
+    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
+        const GrRadial2Gradient& s = sBase.cast<GrRadial2Gradient>();
         return (INHERITED::onIsEqual(sBase) &&
                 this->fCenterX1 == s.fCenterX1 &&
                 this->fRadius0 == s.fRadius0 &&
@@ -487,7 +502,7 @@
         this->addCoordTransform(&fBTransform);
     }
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     // @{
     // Cache of values - these can change arbitrarily, EXCEPT
@@ -505,12 +520,12 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrRadial2Gradient);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRadial2Gradient);
 
-GrEffectRef* GrRadial2Gradient::TestCreate(SkRandom* random,
-                                           GrContext* context,
-                                           const GrDrawTargetCaps&,
-                                           GrTexture**) {
+GrFragmentProcessor* GrRadial2Gradient::TestCreate(SkRandom* random,
+                                                   GrContext* context,
+                                                   const GrDrawTargetCaps&,
+                                                   GrTexture**) {
     SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius1 = random->nextUScalar1();
     SkPoint center2;
@@ -531,16 +546,16 @@
                                                                          colors, stops, colorCount,
                                                                          tm));
     SkPaint paint;
-    GrEffectRef* effect;
-    GrColor grColor;
-    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
-    return effect;
+    GrFragmentProcessor* fp;
+    GrColor paintColor;
+    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &fp));
+    return fp;
 }
 
 /////////////////////////////////////////////////////////////////////
 
-GrGLRadial2Gradient::GrGLRadial2Gradient(const GrBackendEffectFactory& factory,
-                                         const GrDrawEffect& drawEffect)
+GrGLRadial2Gradient::GrGLRadial2Gradient(const GrBackendProcessorFactory& factory,
+                                         const GrProcessor& processor)
     : INHERITED(factory)
     , fVSVaryingName(NULL)
     , fFSVaryingName(NULL)
@@ -548,20 +563,20 @@
     , fCachedRadius(-SK_ScalarMax)
     , fCachedPosRoot(0) {
 
-    const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>();
+    const GrRadial2Gradient& data = processor.cast<GrRadial2Gradient>();
     fIsDegenerate = data.isDegenerate();
 }
 
-void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
-                                   const GrDrawEffect& drawEffect,
-                                   EffectKey key,
+void GrGLRadial2Gradient::emitCode(GrGLProgramBuilder* builder,
+                                   const GrFragmentProcessor&,
+                                   const GrProcessorKey& key,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TransformedCoordsArray& coords,
                                    const TextureSamplerArray& samplers) {
-
-    this->emitUniforms(builder, key);
-    fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
+    fParamUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
                                          kFloat_GrSLType, "Radial2FSParams", 6);
 
     SkString cName("c");
@@ -581,12 +596,13 @@
     builder->getUniformVariable(fParamUni).appendArrayAccess(4, &p4);
     builder->getUniformVariable(fParamUni).appendArrayAccess(5, &p5);
 
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
     // We interpolate the linear component in coords[1].
-    SkASSERT(coords[0].type() == coords[1].type());
+    SkASSERT(coords[0].getType() == coords[1].getType());
     const char* coords2D;
     SkString bVar;
-    if (kVec3f_GrSLType == coords[0].type()) {
-        builder->fsCodeAppendf("\tvec3 interpolants = vec3(%s.xy, %s.x) / %s.z;\n",
+    if (kVec3f_GrSLType == coords[0].getType()) {
+        fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy, %s.x) / %s.z;\n",
                                coords[0].c_str(), coords[1].c_str(), coords[0].c_str());
         coords2D = "interpolants.xy";
         bVar = "interpolants.z";
@@ -596,7 +612,7 @@
     }
 
     // c = (x^2)+(y^2) - params[4]
-    builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
+    fsBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
                            cName.c_str(), coords2D, coords2D, p4.c_str());
 
     // If we aren't degenerate, emit some extra code, and accept a slightly
@@ -604,13 +620,13 @@
     if (!fIsDegenerate) {
 
         // ac4 = 4.0 * params[0] * c
-        builder->fsCodeAppendf("\tfloat %s = %s * 4.0 * %s;\n",
+        fsBuilder->codeAppendf("\tfloat %s = %s * 4.0 * %s;\n",
                                ac4Name.c_str(), p0.c_str(),
                                cName.c_str());
 
         // root = sqrt(b^2-4ac)
         // (abs to avoid exception due to fp precision)
-        builder->fsCodeAppendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
+        fsBuilder->codeAppendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
                                rootName.c_str(), bVar.c_str(), bVar.c_str(),
                                ac4Name.c_str());
 
@@ -622,13 +638,13 @@
         t.printf("-%s / %s", cName.c_str(), bVar.c_str());
     }
 
-    this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
-void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman,
-                                  const GrDrawEffect& drawEffect) {
-    INHERITED::setData(uman, drawEffect);
-    const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>();
+void GrGLRadial2Gradient::setData(const GrGLProgramDataManager& pdman,
+                                  const GrProcessor& processor) {
+    INHERITED::setData(pdman, processor);
+    const GrRadial2Gradient& data = processor.cast<GrRadial2Gradient>();
     SkASSERT(data.isDegenerate() == fIsDegenerate);
     SkScalar centerX1 = data.center();
     SkScalar radius0 = data.radius();
@@ -652,32 +668,26 @@
             data.isPosRoot() ? 1.f : -1.f
         };
 
-        uman.set1fv(fParamUni, 6, values);
+        pdman.set1fv(fParamUni, 6, values);
         fCachedCenter = centerX1;
         fCachedRadius = radius0;
         fCachedPosRoot = data.isPosRoot();
     }
 }
 
-GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrDrawEffect& drawEffect,
-                                                  const GrGLCaps&) {
-    enum {
-        kIsDegenerate = 1 << kBaseKeyBitCnt,
-    };
-
-    EffectKey key = GenBaseGradientKey(drawEffect);
-    if (drawEffect.castEffect<GrRadial2Gradient>().isDegenerate()) {
-        key |= kIsDegenerate;
-    }
-    return key;
+void GrGLRadial2Gradient::GenKey(const GrProcessor& processor,
+                                 const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    uint32_t* key = b->add32n(2);
+    key[0] = GenBaseGradientKey(processor);
+    key[1] = processor.cast<GrRadial2Gradient>().isDegenerate();
 }
 
 /////////////////////////////////////////////////////////////////////
 
-bool SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                           const SkMatrix* localMatrix, GrColor* grColor,
-                                           GrEffectRef** grEffect)  const {
-    SkASSERT(NULL != context);
+bool SkTwoPointRadialGradient::asFragmentProcessor(GrContext* context, const SkPaint& paint,
+                                                   const SkMatrix* localMatrix, GrColor* paintColor,
+                                                   GrFragmentProcessor** fp)  const {
+    SkASSERT(context);
     
     // invert the localM, translate to center1 (fPtsToUni), rotate so center2 is on x axis.
     SkMatrix matrix;
@@ -702,17 +712,16 @@
         matrix.postConcat(rot);
     }
 
-    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
-    *grEffect = GrRadial2Gradient::Create(context, *this, matrix, fTileMode);
+    *paintColor = SkColor2GrColorJustAlpha(paint.getColor());
+    *fp = GrRadial2Gradient::Create(context, *this, matrix, fTileMode);
     
     return true;
 }
 
 #else
 
-bool SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint& paint,
-                                           const SkMatrix* localMatrix, GrColor* grColor,
-                                           GrEffectRef** grEffect)  const {
+bool SkTwoPointRadialGradient::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*,
+                                                   GrColor*, GrFragmentProcessor**)  const {
     SkDEBUGFAIL("Should not call in GPU-less build");
     return false;
 }
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.h b/src/effects/gradients/SkTwoPointRadialGradient.h
index 8916754..da9c5fc 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.h
+++ b/src/effects/gradients/SkTwoPointRadialGradient.h
@@ -14,15 +14,15 @@
 class SkTwoPointRadialGradient : public SkGradientShaderBase {
 public:
     SkTwoPointRadialGradient(const SkPoint& start, SkScalar startRadius,
-                              const SkPoint& end, SkScalar endRadius,
-                              const Descriptor&, const SkMatrix* localMatrix);
+                             const SkPoint& end, SkScalar endRadius,
+                             const Descriptor&);
 
     virtual BitmapType asABitmap(SkBitmap* bitmap,
                                  SkMatrix* matrix,
                                  TileMode* xy) const SK_OVERRIDE;
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
-    virtual bool asNewEffect(GrContext* context, const SkPaint&, const SkMatrix*, GrColor*,
-                             GrEffectRef**)  const SK_OVERRIDE;
+    virtual bool asFragmentProcessor(GrContext* context, const SkPaint&, const SkMatrix*, GrColor*,
+                                     GrFragmentProcessor**)  const SK_OVERRIDE;
 
     virtual size_t contextSize() const SK_OVERRIDE;
 
@@ -58,6 +58,7 @@
 
     void init();
 
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
 };
 
diff --git a/src/fonts/SkFontMgr_fontconfig.cpp b/src/fonts/SkFontMgr_fontconfig.cpp
index 2ffe8e3..a7f8128 100644
--- a/src/fonts/SkFontMgr_fontconfig.cpp
+++ b/src/fonts/SkFontMgr_fontconfig.cpp
@@ -50,11 +50,6 @@
 
 } // namespace
 
-
-// Defined in SkFontHost_FreeType.cpp
-bool find_name_and_attributes(SkStream* stream, SkString* name,
-                              SkTypeface::Style* style, bool* isFixedWidth);
-
 // borrow this global from SkFontHost_fontconfig. eventually that file should
 // go away, and be replaced with this one.
 extern SkFontConfigInterface* SkFontHost_fontconfig_ref_global();
@@ -307,7 +302,7 @@
         // TODO should the caller give us the style or should we get it from freetype?
         SkTypeface::Style style = SkTypeface::kNormal;
         bool isFixedWidth = false;
-        if (!find_name_and_attributes(stream, NULL, &style, &isFixedWidth)) {
+        if (!SkTypeface_FreeType::ScanFont(stream, 0, NULL, &style, &isFixedWidth)) {
             return NULL;
         }
 
diff --git a/src/fonts/SkFontMgr_indirect.cpp b/src/fonts/SkFontMgr_indirect.cpp
index 54f2de8..c9d3025 100644
--- a/src/fonts/SkFontMgr_indirect.cpp
+++ b/src/fonts/SkFontMgr_indirect.cpp
@@ -245,13 +245,25 @@
     return this->createTypefaceFromFontId(id);
 }
 
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
 SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[],
                                                             const SkFontStyle& style,
-                                                            const char bpc47[],
-                                                            uint32_t character) const {
-    SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bpc47, character);
+                                                            const char* bcp47[],
+                                                            int bcp47Count,
+                                                            SkUnichar character) const {
+    SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bcp47,
+                                                        bcp47Count, character);
     return this->createTypefaceFromFontId(id);
 }
+#else
+SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[],
+                                                            const SkFontStyle& style,
+                                                            const char bcp47[],
+                                                            SkUnichar character) const {
+    SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bcp47, character);
+    return this->createTypefaceFromFontId(id);
+}
+#endif
 
 SkTypeface* SkFontMgr_Indirect::onMatchFaceStyle(const SkTypeface* familyMember,
                                                  const SkFontStyle& fontStyle) const {
diff --git a/src/fonts/SkGScalerContext.cpp b/src/fonts/SkGScalerContext.cpp
index e1ab921..34a788a 100644
--- a/src/fonts/SkGScalerContext.cpp
+++ b/src/fonts/SkGScalerContext.cpp
@@ -22,8 +22,7 @@
     virtual void generateMetrics(SkGlyph*) SK_OVERRIDE;
     virtual void generateImage(const SkGlyph&) SK_OVERRIDE;
     virtual void generatePath(const SkGlyph&, SkPath*) SK_OVERRIDE;
-    virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
-                                     SkPaint::FontMetrics* mY) SK_OVERRIDE;
+    virtual void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE;
 
 private:
     SkGTypeface*     fFace;
@@ -138,8 +137,7 @@
     path->transform(fMatrix);
 }
 
-void SkGScalerContext::generateFontMetrics(SkPaint::FontMetrics*,
-                                           SkPaint::FontMetrics* metrics) {
+void SkGScalerContext::generateFontMetrics(SkPaint::FontMetrics* metrics) {
     fProxy->getFontMetrics(metrics);
     if (metrics) {
         SkScalar scale = fMatrix.getScaleY();
@@ -208,6 +206,10 @@
     return fProxy->getUnitsPerEm();
 }
 
+void SkGTypeface::onGetFamilyName(SkString* familyName) const {
+    fProxy->getFamilyName(familyName);
+}
+
 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const {
     return fProxy->createFamilyNameIterator();
 }
diff --git a/src/fonts/SkGScalerContext.h b/src/fonts/SkGScalerContext.h
index faca50e..8ad2817 100644
--- a/src/fonts/SkGScalerContext.h
+++ b/src/fonts/SkGScalerContext.h
@@ -34,6 +34,7 @@
     virtual int onCountGlyphs() const SK_OVERRIDE;
     virtual int onGetUPEM() const SK_OVERRIDE;
 
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE;
     virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
 
     virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
diff --git a/src/fonts/SkTestScalerContext.cpp b/src/fonts/SkTestScalerContext.cpp
new file mode 100644
index 0000000..ee379f0
--- /dev/null
+++ b/src/fonts/SkTestScalerContext.cpp
@@ -0,0 +1,297 @@
+/*
+ * 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 "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkDescriptor.h"
+#include "SkFontDescriptor.h"
+#include "SkGlyph.h"
+#include "SkMask.h"
+// #include "SkOTUtils.h"
+#include "SkScalerContext.h"
+#include "SkTestScalerContext.h"
+#include "SkTypefaceCache.h"
+
+SkTestFont::SkTestFont(const SkTestFontData& fontData)
+    : INHERITED()
+    , fCharCodes(fontData.fCharCodes)
+    , fCharCodesCount(fontData.fCharCodesCount)
+    , fWidths(fontData.fWidths)
+    , fMetrics(fontData.fMetrics)
+    , fName(fontData.fName)
+    , fPaths(NULL)
+{
+    init(fontData.fPoints, fontData.fVerbs);
+#ifdef SK_DEBUG
+    sk_bzero(fDebugBits, sizeof(fDebugBits));
+    sk_bzero(fDebugOverage, sizeof(fDebugOverage));
+#endif
+}
+
+SkTestFont::~SkTestFont() {
+    for (unsigned index = 0; index < fCharCodesCount; ++index) {
+        SkDELETE(fPaths[index]);
+    }
+    SkDELETE_ARRAY(fPaths);
+}
+
+#ifdef SK_DEBUG
+
+#include "SkThread.h"
+SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex);
+
+#endif
+
+int SkTestFont::codeToIndex(SkUnichar charCode) const {
+#ifdef SK_DEBUG  // detect missing test font data
+    {
+        SkAutoMutexAcquire ac(gUsedCharsMutex);
+        if (charCode >= ' ' && charCode <= '~') {
+            int bitOffset = charCode - ' ';
+            fDebugBits[bitOffset >> 3] |= 1 << (bitOffset & 7);
+        } else {
+            int index = 0;
+            while (fDebugOverage[index] != 0 && fDebugOverage[index] != charCode
+                    && index < (int) sizeof(fDebugOverage)) {
+                ++index;
+            }
+            SkASSERT(index < (int) sizeof(fDebugOverage));
+            if (fDebugOverage[index] == 0) {
+                fDebugOverage[index] = charCode;
+            }
+        }
+    }
+#endif
+    for (unsigned index = 0; index < fCharCodesCount; ++index) {
+        if (fCharCodes[index] == (unsigned) charCode) {
+            return (int) index;
+        }
+    }
+    SkDEBUGF(("missing '%c' (%d) from %s %d\n", (char) charCode, charCode,
+            fDebugName, fDebugStyle));
+    return 0;
+}
+
+void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
+    fPaths = SkNEW_ARRAY(SkPath*, fCharCodesCount);
+    for (unsigned index = 0; index < fCharCodesCount; ++index) {
+        SkPath* path = SkNEW(SkPath);
+        SkPath::Verb verb;
+        while ((verb = (SkPath::Verb) *verbs++) != SkPath::kDone_Verb) {
+            switch (verb) {
+                case SkPath::kMove_Verb:
+                    path->moveTo(pts[0], pts[1]);
+                    pts += 2;
+                    break;
+                case SkPath::kLine_Verb:
+                    path->lineTo(pts[0], pts[1]);
+                    pts += 2;
+                    break;
+                case SkPath::kQuad_Verb:
+                    path->quadTo(pts[0], pts[1], pts[2], pts[3]);
+                    pts += 4;
+                    break;
+                case SkPath::kCubic_Verb:
+                    path->cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+                    pts += 6;
+                    break;
+                case SkPath::kClose_Verb:
+                    path->close();
+                    break;
+                default:
+                    SkDEBUGFAIL("bad verb");
+                    return;
+            }
+        }
+        fPaths[index] = path;
+    }
+}
+    
+SkTestTypeface::SkTestTypeface(SkTestFont* testFont, SkTypeface::Style style)
+    : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
+    , fTestFont(testFont) {
+}
+
+void SkTestTypeface::getAdvance(SkGlyph* glyph) {
+    glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
+    glyph->fAdvanceY = 0;
+}
+
+void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) {
+    *metrics = fTestFont->fMetrics;
+}
+
+void SkTestTypeface::getMetrics(SkGlyph* glyph) {
+    glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
+    glyph->fAdvanceY = 0;
+}
+
+void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
+    *path = *fTestFont->fPaths[SkGlyph::ID2Code(glyph.fID)];
+}
+
+void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
+    rec->setHinting(SkPaint::kNo_Hinting);
+    rec->fMaskFormat = SkMask::kA8_Format;
+}
+
+SkAdvancedTypefaceMetrics* SkTestTypeface::onGetAdvancedTypefaceMetrics(
+                                SkAdvancedTypefaceMetrics::PerGlyphInfo ,
+                                const uint32_t* glyphIDs,
+                                uint32_t glyphIDsCount) const {
+// pdf only
+    SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
+    info->fEmSize = 0;
+    info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
+    info->fStyle = 0;
+    info->fFontName.set(fTestFont->fName);
+    info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
+    info->fItalicAngle = 0;
+    info->fAscent = 0;
+    info->fDescent = 0;
+    info->fStemV = 0;
+    info->fCapHeight = 0;
+    info->fBBox = SkIRect::MakeEmpty();
+    return info;
+}
+
+void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
+    desc->setFamilyName(fTestFont->fName);
+    desc->setFontFileName(fTestFont->fName);
+    *isLocal = false;
+}
+
+int SkTestTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
+                            uint16_t glyphs[], int glyphCount) const {
+    SkASSERT(encoding == kUTF16_Encoding);
+    for (int index = 0; index < glyphCount; ++index) {
+        SkUnichar ch = ((SkUnichar*) chars)[index];
+        glyphs[index] = fTestFont->codeToIndex(ch);
+    }
+    return glyphCount;
+}
+
+void SkTestTypeface::onGetFamilyName(SkString* familyName) const {
+    *familyName = fTestFont->fName;
+}
+
+SkTypeface::LocalizedStrings* SkTestTypeface::onCreateFamilyNameIterator() const {
+    SkString familyName(fTestFont->fName);
+    SkString language("und"); //undetermined
+SkASSERT(0);  // incomplete
+    return NULL;
+//     return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
+}
+
+class SkTestScalerContext : public SkScalerContext {
+public:
+    SkTestScalerContext(SkTestTypeface* face, const SkDescriptor* desc)
+        : SkScalerContext(face, desc)
+        , fFace(face)
+    {
+        fRec.getSingleMatrix(&fMatrix);
+        this->forceGenerateImageFromPath();
+    }
+
+    virtual ~SkTestScalerContext() {
+    }
+
+protected:
+    virtual unsigned generateGlyphCount() SK_OVERRIDE {
+        return fFace->onCountGlyphs();
+    }
+
+    virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE {
+        uint16_t glyph;
+        (void) fFace->onCharsToGlyphs((const void *) &uni, SkTypeface::kUTF16_Encoding, &glyph, 1);
+        return glyph;
+    }
+
+    virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE {
+        fFace->getAdvance(glyph);
+
+        SkVector advance;
+        fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
+                      SkFixedToScalar(glyph->fAdvanceY), &advance);
+        glyph->fAdvanceX = SkScalarToFixed(advance.fX);
+        glyph->fAdvanceY = SkScalarToFixed(advance.fY);
+    }
+
+    virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE {
+        fFace->getMetrics(glyph);
+
+        SkVector advance;
+        fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
+                      SkFixedToScalar(glyph->fAdvanceY), &advance);
+        glyph->fAdvanceX = SkScalarToFixed(advance.fX);
+        glyph->fAdvanceY = SkScalarToFixed(advance.fY);
+
+        SkPath path;
+        fFace->getPath(*glyph, &path);
+        path.transform(fMatrix);
+
+        SkRect storage;
+        const SkPaint paint;
+        const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
+                                                            &storage,
+                                                            SkPaint::kFill_Style);
+        SkIRect ibounds;
+        newBounds.roundOut(&ibounds);
+        glyph->fLeft = ibounds.fLeft;
+        glyph->fTop = ibounds.fTop;
+        glyph->fWidth = ibounds.width();
+        glyph->fHeight = ibounds.height();
+        glyph->fMaskFormat = SkMask::kARGB32_Format;
+    }
+
+    virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE {
+        SkPath path;
+        fFace->getPath(glyph, &path);
+
+        SkBitmap bm;
+        bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
+                            glyph.fImage, glyph.rowBytes());
+        bm.eraseColor(0);
+
+        SkCanvas canvas(bm);
+        canvas.translate(-SkIntToScalar(glyph.fLeft),
+                            -SkIntToScalar(glyph.fTop));
+        canvas.concat(fMatrix);
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        canvas.drawPath(path, paint);
+    }
+
+    virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE {
+        fFace->getPath(glyph, path);
+        path->transform(fMatrix);
+    }
+
+    virtual void generateFontMetrics(SkPaint::FontMetrics* metrics) SK_OVERRIDE {
+        fFace->getFontMetrics(metrics);
+        if (metrics) {
+            SkScalar scale = fMatrix.getScaleY();
+            metrics->fTop = SkScalarMul(metrics->fTop, scale);
+            metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
+            metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
+            metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
+            metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
+            metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale);
+            metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
+            metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
+            metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
+        }
+    }
+
+private:
+    SkTestTypeface*  fFace;
+    SkMatrix         fMatrix;
+};
+
+SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
+    return SkNEW_ARGS(SkTestScalerContext, (const_cast<SkTestTypeface*>(this), desc));
+}
diff --git a/src/fonts/SkTestScalerContext.h b/src/fonts/SkTestScalerContext.h
new file mode 100644
index 0000000..42f6049
--- /dev/null
+++ b/src/fonts/SkTestScalerContext.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTestScalerContext_DEFINED
+#define SkTestScalerContext_DEFINED
+
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+#include "SkTypeface.h"
+
+class SkTestFont;
+
+struct SkTestFontData {
+    const SkScalar* fPoints;
+    const unsigned char* fVerbs;
+    const unsigned* fCharCodes;
+    const size_t fCharCodesCount;
+    const SkFixed* fWidths;
+    const SkPaint::FontMetrics& fMetrics;
+    const char* fName;
+    SkTypeface::Style fStyle;
+    SkTestFont* fFontCache;
+};
+
+class SkTestFont : public SkRefCnt {
+public:
+    SK_DECLARE_INST_COUNT(SkTestFont)
+
+    SkTestFont(const SkTestFontData& );
+    virtual ~SkTestFont();
+    int codeToIndex(SkUnichar charCode) const;
+    void init(const SkScalar* pts, const unsigned char* verbs);
+#ifdef SK_DEBUG  // detect missing test font data
+    mutable unsigned char fDebugBits[16];
+    mutable SkUnichar fDebugOverage[8];
+    const char* fDebugName;
+    SkTypeface::Style fDebugStyle;
+    const char* debugFontName() const { return fName; }
+#endif
+private:
+    const unsigned* fCharCodes;
+    const size_t fCharCodesCount;
+    const SkFixed* fWidths;
+    const SkPaint::FontMetrics& fMetrics;
+    const char* fName;
+    SkPath** fPaths;
+    friend class SkTestTypeface;
+    typedef SkRefCnt INHERITED;
+};
+
+
+class SkTestTypeface : public SkTypeface {
+public:
+    SkTestTypeface(SkTestFont* , SkTypeface::Style style);
+    virtual ~SkTestTypeface() {
+        SkSafeUnref(fTestFont);
+    }
+    void getAdvance(SkGlyph* glyph);
+    void getFontMetrics(SkPaint::FontMetrics* metrics);
+    void getMetrics(SkGlyph* glyph);
+    void getPath(const SkGlyph& glyph, SkPath* path);
+protected:
+    virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) const SK_OVERRIDE;
+    virtual void onFilterRec(SkScalerContextRec* rec) const SK_OVERRIDE;
+    virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
+                                    SkAdvancedTypefaceMetrics::PerGlyphInfo ,
+                                    const uint32_t* glyphIDs,
+                                    uint32_t glyphIDsCount) const SK_OVERRIDE;
+
+    virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
+        SkASSERT(0);  // don't expect to get here
+        return NULL;
+    }
+
+    virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const SK_OVERRIDE;
+
+    virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
+                                uint16_t glyphs[], int glyphCount) const SK_OVERRIDE;
+
+    virtual int onCountGlyphs() const SK_OVERRIDE {
+        return (int) fTestFont->fCharCodesCount;
+    }
+
+    virtual int onGetUPEM() const SK_OVERRIDE {
+        SkASSERT(0);  // don't expect to get here
+        return 1;
+    }
+
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE;
+    virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
+
+    virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE {
+        return 0;
+    }
+
+    virtual size_t onGetTableData(SkFontTableTag tag, size_t offset,
+                                  size_t length, void* data) const SK_OVERRIDE {
+        return 0;
+    }
+private:
+    SkTestFont* fTestFont;
+    friend class SkTestScalerContext;
+};
+
+SkTypeface* CreateTestTypeface(const char* name, SkTypeface::Style style);
+
+#endif
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index d0f6e0e..dc74459 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -11,18 +11,19 @@
 #include "GrContext.h"
 #include "GrDrawState.h"
 #include "GrDrawTargetCaps.h"
-#include "GrEffect.h"
+#include "GrProcessor.h"
 #include "GrPathUtils.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 #include "SkString.h"
 #include "SkStrokeRec.h"
 #include "SkTraceEvent.h"
 
-#include "gl/GrGLEffect.h"
+#include "gl/builders/GrGLFullProgramBuilder.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
-#include "gl/GrGLVertexEffect.h"
+#include "gl/GrGLGeometryProcessor.h"
 
-#include "effects/GrVertexEffect.h"
+#include "GrGeometryProcessor.h"
 
 GrAAConvexPathRenderer::GrAAConvexPathRenderer() {
 }
@@ -503,11 +504,11 @@
  * Requires shader derivative instruction support.
  */
 
-class QuadEdgeEffect : public GrVertexEffect {
+class QuadEdgeEffect : public GrGeometryProcessor {
 public:
 
-    static GrEffectRef* Create() {
-        GR_CREATE_STATIC_EFFECT(gQuadEdgeEffect, QuadEdgeEffect, ());
+    static GrGeometryProcessor* Create() {
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gQuadEdgeEffect, QuadEdgeEffect, ());
         gQuadEdgeEffect->ref();
         return gQuadEdgeEffect;
     }
@@ -521,84 +522,90 @@
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<QuadEdgeEffect>::getInstance();
+    const GrShaderVar& inQuadEdge() const { return fInQuadEdge; }
+
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendGeometryProcessorFactory<QuadEdgeEffect>::getInstance();
     }
 
-    class GLEffect : public GrGLVertexEffect {
+    class GLProcessor : public GrGLGeometryProcessor {
     public:
-        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
             : INHERITED (factory) {}
 
-        virtual void emitCode(GrGLFullShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+        virtual void emitCode(GrGLFullProgramBuilder* builder,
+                              const GrGeometryProcessor& geometryProcessor,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
                               const TextureSamplerArray& samplers) SK_OVERRIDE {
             const char *vsName, *fsName;
-            const SkString* attrName =
-                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-            builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n");
-
-            SkAssertResult(builder->enableFeature(
-                                              GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
             builder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName);
 
+            GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+
+            SkAssertResult(fsBuilder->enableFeature(
+                    GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+            fsBuilder->codeAppendf("\t\tfloat edgeAlpha;\n");
+
             // keep the derivative instructions outside the conditional
-            builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
-            builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
-            builder->fsCodeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName);
+            fsBuilder->codeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
+            fsBuilder->codeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
+            fsBuilder->codeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName);
             // today we know z and w are in device space. We could use derivatives
-            builder->fsCodeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName,
+            fsBuilder->codeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName,
                                     fsName);
-            builder->fsCodeAppendf ("\t\t} else {\n");
-            builder->fsCodeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
+            fsBuilder->codeAppendf ("\t\t} else {\n");
+            fsBuilder->codeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
                                    "\t\t\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
                                    fsName, fsName);
-            builder->fsCodeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
+            fsBuilder->codeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
                                     fsName);
-            builder->fsCodeAppendf("\t\t\tedgeAlpha = "
+            fsBuilder->codeAppendf("\t\t\tedgeAlpha = "
                                    "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n\t\t}\n");
 
 
-            builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+            fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
 
-            builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
+            const GrShaderVar& inQuadEdge = geometryProcessor.cast<QuadEdgeEffect>().inQuadEdge();
+            GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+            vsBuilder->codeAppendf("\t%s = %s;\n", vsName, inQuadEdge.c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            return 0x0;
-        }
+        static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
 
-        virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
+        virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
 
     private:
-        typedef GrGLVertexEffect INHERITED;
+        typedef GrGLGeometryProcessor INHERITED;
     };
 
 private:
-    QuadEdgeEffect() {
-        this->addVertexAttrib(kVec4f_GrSLType);
+    QuadEdgeEffect()
+        : fInQuadEdge(this->addVertexAttrib(GrShaderVar("inQuadEdge",
+                                                        kVec4f_GrSLType,
+                                                        GrShaderVar::kAttribute_TypeModifier))) {
     }
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE {
         return true;
     }
 
-    GR_DECLARE_EFFECT_TEST;
+    const GrShaderVar& fInQuadEdge;
 
-    typedef GrVertexEffect INHERITED;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
+
+    typedef GrFragmentProcessor INHERITED;
 };
 
-GR_DEFINE_EFFECT_TEST(QuadEdgeEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(QuadEdgeEffect);
 
-GrEffectRef* QuadEdgeEffect::TestCreate(SkRandom* random,
-                                        GrContext*,
-                                        const GrDrawTargetCaps& caps,
-                                        GrTexture*[]) {
+GrGeometryProcessor* QuadEdgeEffect::TestCreate(SkRandom* random,
+                                                GrContext*,
+                                                const GrDrawTargetCaps& caps,
+                                                GrTexture*[]) {
     // Doesn't work without derivative instructions.
     return caps.shaderDerivativeSupport() ? QuadEdgeEffect::Create() : NULL;
 }
@@ -618,7 +625,7 @@
 // position + edge
 extern const GrVertexAttrib gPathAttribs[] = {
     {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-    {kVec4f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}
+    {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
 };
 
 };
@@ -672,17 +679,15 @@
     // Our computed verts should all be within one pixel of the segment control points.
     devBounds.outset(SK_Scalar1, SK_Scalar1);
 
-    drawState->setVertexAttribs<gPathAttribs>(SK_ARRAY_COUNT(gPathAttribs));
+    drawState->setVertexAttribs<gPathAttribs>(SK_ARRAY_COUNT(gPathAttribs), sizeof(QuadVertex));
 
-    static const int kEdgeAttrIndex = 1;
-    GrEffectRef* quadEffect = QuadEdgeEffect::Create();
-    drawState->addCoverageEffect(quadEffect, kEdgeAttrIndex)->unref();
+    GrGeometryProcessor* quadProcessor = QuadEdgeEffect::Create();
+    drawState->setGeometryProcessor(quadProcessor)->unref();
 
     GrDrawTarget::AutoReleaseGeometry arg(target, vCount, iCount);
     if (!arg.succeeded()) {
         return false;
     }
-    SkASSERT(sizeof(QuadVertex) == drawState->getVertexSize());
     verts = reinterpret_cast<QuadVertex*>(arg.vertices());
     idxs = reinterpret_cast<uint16_t*>(arg.indices());
 
diff --git a/src/gpu/GrAAConvexPathRenderer.h b/src/gpu/GrAAConvexPathRenderer.h
index 62394a3..4dd8585 100644
--- a/src/gpu/GrAAConvexPathRenderer.h
+++ b/src/gpu/GrAAConvexPathRenderer.h
@@ -6,8 +6,10 @@
  * found in the LICENSE file.
  */
 
-#include "GrPathRenderer.h"
+#ifndef GrAAConvexPathRenderer_DEFINED
+#define GrAAConvexPathRenderer_DEFINED
 
+#include "GrPathRenderer.h"
 
 class GrAAConvexPathRenderer : public GrPathRenderer {
 public:
@@ -24,3 +26,5 @@
                             GrDrawTarget* target,
                             bool antiAlias) SK_OVERRIDE;
 };
+
+#endif
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 0014bbe..7347f9c 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -10,11 +10,11 @@
 #include "GrContext.h"
 #include "GrDrawState.h"
 #include "GrDrawTargetCaps.h"
-#include "GrEffect.h"
+#include "GrProcessor.h"
 #include "GrGpu.h"
 #include "GrIndexBuffer.h"
 #include "GrPathUtils.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 #include "SkGeometry.h"
 #include "SkStroke.h"
 #include "SkTemplates.h"
@@ -684,7 +684,7 @@
         (*vert)[5].fPos = b + vec - ortho;
         (*vert)[5].fCoverage = 0;
 
-        if (NULL != toSrc) {
+        if (toSrc) {
             toSrc->mapPointsWithStride(&(*vert)->fPos,
                                        sizeof(LineVertex),
                                        kVertsPerLineSeg);
@@ -708,7 +708,7 @@
 // position + edge
 extern const GrVertexAttrib gHairlineBezierAttribs[] = {
     {kVec2f_GrVertexAttribType, 0,                  kPosition_GrVertexAttribBinding},
-    {kVec4f_GrVertexAttribType, sizeof(SkPoint),    kEffect_GrVertexAttribBinding}
+    {kVec4f_GrVertexAttribType, sizeof(SkPoint),    kGeometryProcessor_GrVertexAttribBinding}
 };
 
 // position + coverage
@@ -731,8 +731,8 @@
 
     int vertCnt = kVertsPerLineSeg * lineCnt;
 
-    drawState->setVertexAttribs<gHairlineLineAttribs>(SK_ARRAY_COUNT(gHairlineLineAttribs));
-    SkASSERT(sizeof(LineVertex) == drawState->getVertexSize());
+    drawState->setVertexAttribs<gHairlineLineAttribs>(SK_ARRAY_COUNT(gHairlineLineAttribs),
+                                                      sizeof(LineVertex));
 
     if (!arg->set(target, vertCnt, 0)) {
         return false;
@@ -778,8 +778,8 @@
 
     int vertCnt = kVertsPerQuad * quadCnt + kVertsPerQuad * conicCnt;
 
-    target->drawState()->setVertexAttribs<gHairlineBezierAttribs>(SK_ARRAY_COUNT(gHairlineBezierAttribs));
-    SkASSERT(sizeof(BezierVertex) == target->getDrawState().getVertexSize());
+    int vAttribCnt = SK_ARRAY_COUNT(gHairlineBezierAttribs);
+    target->drawState()->setVertexAttribs<gHairlineBezierAttribs>(vAttribCnt, sizeof(BezierVertex));
 
     if (!arg->set(target, vertCnt, 0)) {
         return false;
@@ -808,7 +808,7 @@
         seedPts[0] = conics[0];
         seedPts[1] = conics[2];
     }
-    if (NULL != toDevice) {
+    if (toDevice) {
         toDevice->mapPoints(seedPts, 2);
     }
     devBounds->set(seedPts[0], seedPts[1]);
@@ -990,19 +990,17 @@
         }
         GrDrawState* drawState = target->drawState();
 
-        static const int kEdgeAttrIndex = 1;
-
         // Check devBounds
         SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices(),
                                             kVertsPerQuad * quadCnt + kVertsPerQuad * conicCnt));
 
         if (quadCnt > 0) {
-            GrEffectRef* hairQuadEffect = GrQuadEffect::Create(kHairlineAA_GrEffectEdgeType,
-                                                               *target->caps());
-            SkASSERT(NULL != hairQuadEffect);
+            GrGeometryProcessor* hairQuadProcessor =
+                    GrQuadEffect::Create(kHairlineAA_GrProcessorEdgeType, *target->caps());
+            SkASSERT(hairQuadProcessor);
             GrDrawState::AutoRestoreEffects are(drawState);
             target->setIndexSourceToBuffer(fQuadsIndexBuffer);
-            drawState->addCoverageEffect(hairQuadEffect, kEdgeAttrIndex)->unref();
+            drawState->setGeometryProcessor(hairQuadProcessor)->unref();
             int quads = 0;
             while (quads < quadCnt) {
                 int n = SkTMin(quadCnt - quads, kNumQuadsInIdxBuffer);
@@ -1018,10 +1016,10 @@
 
         if (conicCnt > 0) {
             GrDrawState::AutoRestoreEffects are(drawState);
-            GrEffectRef* hairConicEffect = GrConicEffect::Create(kHairlineAA_GrEffectEdgeType,
-                                                                 *target->caps());
-            SkASSERT(NULL != hairConicEffect);
-            drawState->addCoverageEffect(hairConicEffect, 1, 2)->unref();
+            GrGeometryProcessor* hairConicProcessor = GrConicEffect::Create(
+                    kHairlineAA_GrProcessorEdgeType, *target->caps());
+            SkASSERT(hairConicProcessor);
+            drawState->setGeometryProcessor(hairConicProcessor)->unref();
             int conics = 0;
             while (conics < conicCnt) {
                 int n = SkTMin(conicCnt - conics, kNumQuadsInIdxBuffer);
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index 497b3cf..5720982 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -7,20 +7,21 @@
 
 #include "GrAARectRenderer.h"
 #include "GrGpu.h"
-#include "gl/GrGLEffect.h"
-#include "gl/GrGLVertexEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/builders/GrGLFullProgramBuilder.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/GrGLGeometryProcessor.h"
+#include "GrTBackendProcessorFactory.h"
 #include "SkColorPriv.h"
-#include "effects/GrVertexEffect.h"
+#include "GrGeometryProcessor.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 class GrGLAlignedRectEffect;
 
 // Axis Aligned special case
-class GrAlignedRectEffect : public GrVertexEffect {
+class GrAlignedRectEffect : public GrGeometryProcessor {
 public:
-    static GrEffectRef* Create() {
-        GR_CREATE_STATIC_EFFECT(gAlignedRectEffect, GrAlignedRectEffect, ());
+    static GrGeometryProcessor* Create() {
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gAlignedRectEffect, GrAlignedRectEffect, ());
         gAlignedRectEffect->ref();
         return gAlignedRectEffect;
     }
@@ -34,18 +35,20 @@
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<GrAlignedRectEffect>::getInstance();
+    const GrShaderVar& inRect() const { return fInRect; }
+
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendGeometryProcessorFactory<GrAlignedRectEffect>::getInstance();
     }
 
-    class GLEffect : public GrGLVertexEffect {
+    class GLProcessor : public GrGLGeometryProcessor {
     public:
-        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
         : INHERITED (factory) {}
 
-        virtual void emitCode(GrGLFullShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+        virtual void emitCode(GrGLFullProgramBuilder* builder,
+                              const GrGeometryProcessor& geometryProcessor,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -55,68 +58,72 @@
             //      zw -> w/2+0.5, h/2+0.5
             const char *vsRectName, *fsRectName;
             builder->addVarying(kVec4f_GrSLType, "Rect", &vsRectName, &fsRectName);
-            const SkString* attr0Name =
-                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-            builder->vsCodeAppendf("\t%s = %s;\n", vsRectName, attr0Name->c_str());
 
+            const GrShaderVar& inRect = geometryProcessor.cast<GrAlignedRectEffect>().inRect();
+            GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+            vsBuilder->codeAppendf("\t%s = %s;\n", vsRectName, inRect.c_str());
+
+            GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
             // TODO: compute all these offsets, spans, and scales in the VS
-            builder->fsCodeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", fsRectName);
-            builder->fsCodeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", fsRectName);
-            builder->fsCodeAppend("\tfloat outset = 0.5;\n");
+            fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", fsRectName);
+            fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", fsRectName);
+            fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
             // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
             // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
-            builder->fsCodeAppend("\tfloat spanW = insetW + outset;\n");
-            builder->fsCodeAppend("\tfloat spanH = insetH + outset;\n");
+            fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
+            fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
             // For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
             // value of coverage that is used. In other words it is the coverage that is
             // used in the interior of the rect after the ramp.
-            builder->fsCodeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
-            builder->fsCodeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
+            fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
+            fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
 
             // Compute the coverage for the rect's width
-            builder->fsCodeAppendf(
+            fsBuilder->codeAppendf(
                 "\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", fsRectName,
                 fsRectName);
             // Compute the coverage for the rect's height and merge with the width
-            builder->fsCodeAppendf(
+            fsBuilder->codeAppendf(
                 "\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0, 1.0);\n",
                 fsRectName, fsRectName);
 
 
-            builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+            fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("coverage")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            return 0;
-        }
+        static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
 
-        virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE {}
+        virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
 
     private:
-        typedef GrGLVertexEffect INHERITED;
+        typedef GrGLGeometryProcessor INHERITED;
     };
 
 
 private:
-    GrAlignedRectEffect() : GrVertexEffect() {
-        this->addVertexAttrib(kVec4f_GrSLType);
+    GrAlignedRectEffect()
+        : fInRect(this->addVertexAttrib(GrShaderVar("inRect",
+                                                    kVec4f_GrSLType,
+                                                    GrShaderVar::kAttribute_TypeModifier))) {
     }
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { return true; }
+    const GrShaderVar& fInRect;
 
-    GR_DECLARE_EFFECT_TEST;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
 
-    typedef GrVertexEffect INHERITED;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
+
+    typedef GrGeometryProcessor INHERITED;
 };
 
 
-GR_DEFINE_EFFECT_TEST(GrAlignedRectEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrAlignedRectEffect);
 
-GrEffectRef* GrAlignedRectEffect::TestCreate(SkRandom* random,
-                                             GrContext* context,
-                                             const GrDrawTargetCaps&,
-                                             GrTexture* textures[]) {
+GrGeometryProcessor* GrAlignedRectEffect::TestCreate(SkRandom* random,
+                                                     GrContext* context,
+                                                     const GrDrawTargetCaps&,
+                                                     GrTexture* textures[]) {
     return GrAlignedRectEffect::Create();
 }
 
@@ -135,10 +142,11 @@
  * The munged width and height are stored in a vec2 varying ("WidthHeight")
  * with the width in x and the height in y.
  */
-class GrRectEffect : public GrVertexEffect {
+
+class GrRectEffect : public GrGeometryProcessor {
 public:
-    static GrEffectRef* Create() {
-        GR_CREATE_STATIC_EFFECT(gRectEffect, GrRectEffect, ());
+    static GrGeometryProcessor* Create() {
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gRectEffect, GrRectEffect, ());
         gRectEffect->ref();
         return gRectEffect;
     }
@@ -152,18 +160,21 @@
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<GrRectEffect>::getInstance();
+    const GrShaderVar& inRectEdge() const { return fInRectEdge; }
+    const GrShaderVar& inWidthHeight() const { return fInWidthHeight; }
+
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendGeometryProcessorFactory<GrRectEffect>::getInstance();
     }
 
-    class GLEffect : public GrGLVertexEffect {
+    class GLProcessor : public GrGLGeometryProcessor {
     public:
-        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
         : INHERITED (factory) {}
 
-        virtual void emitCode(GrGLFullShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+        virtual void emitCode(GrGLFullProgramBuilder* builder,
+                              const GrGeometryProcessor& geometryProcessor,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -173,107 +184,120 @@
             const char *vsRectEdgeName, *fsRectEdgeName;
             builder->addVarying(kVec4f_GrSLType, "RectEdge",
                                 &vsRectEdgeName, &fsRectEdgeName);
-            const SkString* attr0Name =
-                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-            builder->vsCodeAppendf("\t%s = %s;\n", vsRectEdgeName, attr0Name->c_str());
+
+            const GrRectEffect& rectEffect = geometryProcessor.cast<GrRectEffect>();
+            GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+            vsBuilder->codeAppendf("%s = %s;", vsRectEdgeName, rectEffect.inRectEdge().c_str());
 
             // setup the varying for width/2+.5 and height/2+.5
             const char *vsWidthHeightName, *fsWidthHeightName;
             builder->addVarying(kVec2f_GrSLType, "WidthHeight",
                                 &vsWidthHeightName, &fsWidthHeightName);
-            const SkString* attr1Name =
-                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
-            builder->vsCodeAppendf("\t%s = %s;\n", vsWidthHeightName, attr1Name->c_str());
+            vsBuilder->codeAppendf("%s = %s;",
+                                   vsWidthHeightName,
+                                   rectEffect.inWidthHeight().c_str());
 
+            GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
             // TODO: compute all these offsets, spans, and scales in the VS
-            builder->fsCodeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", fsWidthHeightName);
-            builder->fsCodeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", fsWidthHeightName);
-            builder->fsCodeAppend("\tfloat outset = 0.5;\n");
+            fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", fsWidthHeightName);
+            fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", fsWidthHeightName);
+            fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
             // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
             // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
-            builder->fsCodeAppend("\tfloat spanW = insetW + outset;\n");
-            builder->fsCodeAppend("\tfloat spanH = insetH + outset;\n");
+            fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
+            fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
             // For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
             // value of coverage that is used. In other words it is the coverage that is
             // used in the interior of the rect after the ramp.
-            builder->fsCodeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
-            builder->fsCodeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
+            fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
+            fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
 
             // Compute the coverage for the rect's width
-            builder->fsCodeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
-                                   builder->fragmentPosition(), fsRectEdgeName);
-            builder->fsCodeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
+            fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
+                                   fsBuilder->fragmentPosition(), fsRectEdgeName);
+            fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
                                    fsRectEdgeName, fsRectEdgeName);
-            builder->fsCodeAppendf(
+            fsBuilder->codeAppendf(
                 "\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0);\n",
                 fsWidthHeightName);
 
             // Compute the coverage for the rect's height and merge with the width
-            builder->fsCodeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
+            fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
                                    fsRectEdgeName);
-            builder->fsCodeAppendf(
+            fsBuilder->codeAppendf(
                     "\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);\n",
                     fsWidthHeightName);
 
 
-            builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+            fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("coverage")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            return 0;
-        }
+        static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
 
-        virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE {}
+        virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
 
     private:
-        typedef GrGLVertexEffect INHERITED;
+        typedef GrGLGeometryProcessor INHERITED;
     };
 
 
+
 private:
-    GrRectEffect() : GrVertexEffect() {
-        this->addVertexAttrib(kVec4f_GrSLType);
-        this->addVertexAttrib(kVec2f_GrSLType);
+    GrRectEffect()
+        : fInRectEdge(this->addVertexAttrib(GrShaderVar("inRectEdge",
+                                                        kVec4f_GrSLType,
+                                                        GrShaderVar::kAttribute_TypeModifier)))
+        , fInWidthHeight(this->addVertexAttrib(
+                GrShaderVar("inWidthHeight",
+                            kVec2f_GrSLType,
+                            GrShaderVar::kAttribute_TypeModifier))) {
         this->setWillReadFragmentPosition();
     }
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { return true; }
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
 
-    GR_DECLARE_EFFECT_TEST;
+    const GrShaderVar& fInRectEdge;
+    const GrShaderVar& fInWidthHeight;
 
-    typedef GrVertexEffect INHERITED;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
+
+    typedef GrGeometryProcessor INHERITED;
 };
 
 
-GR_DEFINE_EFFECT_TEST(GrRectEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRectEffect);
 
-GrEffectRef* GrRectEffect::TestCreate(SkRandom* random,
-                                      GrContext* context,
-                                      const GrDrawTargetCaps&,
-                                      GrTexture* textures[]) {
+GrGeometryProcessor* GrRectEffect::TestCreate(SkRandom* random,
+                                              GrContext* context,
+                                              const GrDrawTargetCaps&,
+                                              GrTexture* textures[]) {
     return GrRectEffect::Create();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 namespace {
-
-extern const GrVertexAttrib gAARectCoverageAttribs[] = {
-    {kVec2f_GrVertexAttribType,  0,               kPosition_GrVertexAttribBinding},
-    {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kCoverage_GrVertexAttribBinding},
+extern const GrVertexAttrib gAARectAttribs[] = {
+    {kVec2f_GrVertexAttribType,  0,                                 kPosition_GrVertexAttribBinding},
+    {kVec4ub_GrVertexAttribType, sizeof(SkPoint),                   kColor_GrVertexAttribBinding},
+    {kVec4ub_GrVertexAttribType, sizeof(SkPoint) + sizeof(SkColor), kCoverage_GrVertexAttribBinding},
 };
 
-extern const GrVertexAttrib gAARectColorAttribs[] = {
-    {kVec2f_GrVertexAttribType,  0,               kPosition_GrVertexAttribBinding},
-    {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding},
+// Should the coverage be multiplied into the color attrib or use a separate attrib.
+enum CoverageAttribType {
+    kUseColor_CoverageAttribType,
+    kUseCoverage_CoverageAttribType,
 };
+}
 
-static void set_aa_rect_vertex_attributes(GrDrawState* drawState, bool useCoverage) {
-    if (useCoverage) {
-        drawState->setVertexAttribs<gAARectCoverageAttribs>(SK_ARRAY_COUNT(gAARectCoverageAttribs));
+static CoverageAttribType set_rect_attribs(GrDrawState* drawState) {
+    if (drawState->canTweakAlphaForCoverage()) {
+        drawState->setVertexAttribs<gAARectAttribs>(2, sizeof(SkPoint) + sizeof(SkColor));
+        return kUseColor_CoverageAttribType;
     } else {
-        drawState->setVertexAttribs<gAARectColorAttribs>(SK_ARRAY_COUNT(gAARectColorAttribs));
+        drawState->setVertexAttribs<gAARectAttribs>(3, sizeof(SkPoint) + 2 * sizeof(SkColor));
+        return kUseCoverage_CoverageAttribType;
     }
 }
 
@@ -283,8 +307,6 @@
                     r.fRight - dx, r.fBottom - dy, stride);
 }
 
-};
-
 void GrAARectRenderer::reset() {
     SkSafeSetNull(fAAFillRectIndexBuffer);
     SkSafeSetNull(fAAMiterStrokeRectIndexBuffer);
@@ -310,7 +332,7 @@
 
     if (NULL == fAAFillRectIndexBuffer) {
         fAAFillRectIndexBuffer = gpu->createIndexBuffer(kAAFillRectIndexBufferSize, false);
-        if (NULL != fAAFillRectIndexBuffer) {
+        if (fAAFillRectIndexBuffer) {
             uint16_t* data = (uint16_t*) fAAFillRectIndexBuffer->map();
             bool useTempData = (NULL == data);
             if (useTempData) {
@@ -423,7 +445,7 @@
         if (NULL == fAAMiterStrokeRectIndexBuffer) {
             fAAMiterStrokeRectIndexBuffer =
                 gpu->createIndexBuffer(sizeof(gMiterStrokeAARectIdx), false);
-            if (NULL != fAAMiterStrokeRectIndexBuffer) {
+            if (fAAMiterStrokeRectIndexBuffer) {
 #ifdef SK_DEBUG
                 bool updated =
 #endif
@@ -437,7 +459,7 @@
         if (NULL == fAABevelStrokeRectIndexBuffer) {
             fAABevelStrokeRectIndexBuffer =
                 gpu->createIndexBuffer(sizeof(gBevelStrokeAARectIdx), false);
-            if (NULL != fAABevelStrokeRectIndexBuffer) {
+            if (fAABevelStrokeRectIndexBuffer) {
 #ifdef SK_DEBUG
                 bool updated =
 #endif
@@ -454,11 +476,15 @@
                                           GrDrawTarget* target,
                                           const SkRect& rect,
                                           const SkMatrix& combinedMatrix,
-                                          const SkRect& devRect,
-                                          bool useVertexCoverage) {
+                                          const SkRect& devRect) {
     GrDrawState* drawState = target->drawState();
 
-    set_aa_rect_vertex_attributes(drawState, useVertexCoverage);
+    GrColor color = drawState->getColor();
+
+    CoverageAttribType covAttribType = set_rect_attribs(drawState);
+    if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
+        drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
+    }
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0);
     if (!geo.succeeded()) {
@@ -473,11 +499,10 @@
     }
 
     intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
-    size_t vsize = drawState->getVertexSize();
-    SkASSERT(sizeof(SkPoint) + sizeof(GrColor) == vsize);
+    size_t vstride = drawState->getVertexStride();
 
     SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
-    SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vsize);
+    SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vstride);
 
     SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1);
     inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
@@ -491,8 +516,8 @@
         combinedMatrix.mapRect(&devRect, rect);
 #endif
 
-        set_inset_fan(fan0Pos, vsize, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
-        set_inset_fan(fan1Pos, vsize, devRect, inset,  inset);
+        set_inset_fan(fan0Pos, vstride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
+        set_inset_fan(fan1Pos, vstride, devRect, inset,  inset);
     } else {
         // compute transformed (1, 0) and (0, 1) vectors
         SkVector vec[2] = {
@@ -507,33 +532,39 @@
 
         // create the rotated rect
         fan0Pos->setRectFan(rect.fLeft, rect.fTop,
-                            rect.fRight, rect.fBottom, vsize);
-        combinedMatrix.mapPointsWithStride(fan0Pos, vsize, 4);
+                            rect.fRight, rect.fBottom, vstride);
+        combinedMatrix.mapPointsWithStride(fan0Pos, vstride, 4);
 
         // Now create the inset points and then outset the original
         // rotated points
 
         // TL
-        *((SkPoint*)((intptr_t)fan1Pos + 0 * vsize)) =
-            *((SkPoint*)((intptr_t)fan0Pos + 0 * vsize)) + vec[0] + vec[1];
-        *((SkPoint*)((intptr_t)fan0Pos + 0 * vsize)) -= vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan1Pos + 0 * vstride)) =
+            *((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) + vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) -= vec[0] + vec[1];
         // BL
-        *((SkPoint*)((intptr_t)fan1Pos + 1 * vsize)) =
-            *((SkPoint*)((intptr_t)fan0Pos + 1 * vsize)) + vec[0] - vec[1];
-        *((SkPoint*)((intptr_t)fan0Pos + 1 * vsize)) -= vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan1Pos + 1 * vstride)) =
+            *((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) + vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) -= vec[0] - vec[1];
         // BR
-        *((SkPoint*)((intptr_t)fan1Pos + 2 * vsize)) =
-            *((SkPoint*)((intptr_t)fan0Pos + 2 * vsize)) - vec[0] - vec[1];
-        *((SkPoint*)((intptr_t)fan0Pos + 2 * vsize)) += vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan1Pos + 2 * vstride)) =
+            *((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) - vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) += vec[0] + vec[1];
         // TR
-        *((SkPoint*)((intptr_t)fan1Pos + 3 * vsize)) =
-            *((SkPoint*)((intptr_t)fan0Pos + 3 * vsize)) - vec[0] + vec[1];
-        *((SkPoint*)((intptr_t)fan0Pos + 3 * vsize)) += vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan1Pos + 3 * vstride)) =
+            *((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) - vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) += vec[0] - vec[1];
     }
 
+    // Make verts point to vertex color and then set all the color and coverage vertex attrs values.
     verts += sizeof(SkPoint);
     for (int i = 0; i < 4; ++i) {
-        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
+        if (kUseCoverage_CoverageAttribType == covAttribType) {
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
+            *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = 0;
+        } else {
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = 0;
+        }
     }
 
     int scale;
@@ -544,20 +575,20 @@
         scale = 0xff;
     }
 
-    GrColor innerColor;
-    if (useVertexCoverage) {
-        innerColor = GrColorPackRGBA(scale, scale, scale, scale);
+    GrColor innerCoverage;
+    if (kUseCoverage_CoverageAttribType == covAttribType) {
+        innerCoverage = GrColorPackRGBA(scale, scale, scale, scale); 
     } else {
-        if (0xff == scale) {
-            innerColor = target->getDrawState().getColor();
-        } else {
-            innerColor = SkAlphaMulQ(target->getDrawState().getColor(), scale);
-        }
+        innerCoverage = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
     }
-
-    verts += 4 * vsize;
+    verts += 4 * vstride;
     for (int i = 0; i < 4; ++i) {
-        *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
+        if (kUseCoverage_CoverageAttribType == covAttribType) {
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
+            *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = innerCoverage;
+        } else {
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = innerCoverage;
+        }
     }
 
     target->setIndexSourceToBuffer(indexBuffer);
@@ -580,8 +611,8 @@
 // Rotated
 extern const GrVertexAttrib gAARectVertexAttribs[] = {
     { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding },
-    { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kEffect_GrVertexAttribBinding },
-    { kVec2f_GrVertexAttribType, 3*sizeof(SkPoint), kEffect_GrVertexAttribBinding }
+    { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, 3*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding }
 };
 
 // Axis Aligned
@@ -594,7 +625,7 @@
 // Axis Aligned
 extern const GrVertexAttrib gAAAARectVertexAttribs[] = {
     { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding },
-    { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kEffect_GrVertexAttribBinding },
+    { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding },
 };
 
 };
@@ -620,8 +651,8 @@
 
     SkScalar newWidth = SkScalarHalf(rect.width() * vec[0].length()) + SK_ScalarHalf;
     SkScalar newHeight = SkScalarHalf(rect.height() * vec[1].length()) + SK_ScalarHalf;
-    drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVertexAttribs));
-    SkASSERT(sizeof(RectVertex) == drawState->getVertexSize());
+    drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVertexAttribs),
+                                                      sizeof(RectVertex));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
     if (!geo.succeeded()) {
@@ -631,10 +662,8 @@
 
     RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices());
 
-    GrEffectRef* effect = GrRectEffect::Create();
-    static const int kRectAttrIndex = 1;
-    static const int kWidthIndex = 2;
-    drawState->addCoverageEffect(effect, kRectAttrIndex, kWidthIndex)->unref();
+    GrGeometryProcessor* gp = GrRectEffect::Create();
+    drawState->setGeometryProcessor(gp)->unref();
 
     for (int i = 0; i < 4; ++i) {
         verts[i].fCenter = center;
@@ -670,8 +699,8 @@
     GrDrawState* drawState = target->drawState();
     SkASSERT(combinedMatrix.rectStaysRect());
 
-    drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARectVertexAttribs));
-    SkASSERT(sizeof(AARectVertex) == drawState->getVertexSize());
+    drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARectVertexAttribs),
+                                                        sizeof(AARectVertex));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
     if (!geo.succeeded()) {
@@ -681,9 +710,8 @@
 
     AARectVertex* verts = reinterpret_cast<AARectVertex*>(geo.vertices());
 
-    GrEffectRef* effect = GrAlignedRectEffect::Create();
-    static const int kOffsetIndex = 1;
-    drawState->addCoverageEffect(effect, kOffsetIndex)->unref();
+    GrGeometryProcessor* gp = GrAlignedRectEffect::Create();
+    drawState->setGeometryProcessor(gp)->unref();
 
     SkRect devRect;
     combinedMatrix.mapRect(&devRect, rect);
@@ -726,8 +754,7 @@
                                     const SkRect& rect,
                                     const SkMatrix& combinedMatrix,
                                     const SkRect& devRect,
-                                    const SkStrokeRec& stroke,
-                                    bool useVertexCoverage) {
+                                    const SkStrokeRec& stroke) {
     SkVector devStrokeSize;
     SkScalar width = stroke.getWidth();
     if (width > 0) {
@@ -762,14 +789,15 @@
     devOutside.outset(rx, ry);
 
     bool miterStroke = true;
+    // For hairlines, make bevel and round joins appear the same as mitered ones.
     // small miter limit means right angles show bevel...
-    if (stroke.getJoin() != SkPaint::kMiter_Join || stroke.getMiter() < SK_ScalarSqrt2) {
+    if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join ||
+                        stroke.getMiter() < SK_ScalarSqrt2)) {
         miterStroke = false;
     }
 
     if (spare <= 0 && miterStroke) {
-        this->fillAARect(gpu, target, devOutside, SkMatrix::I(),
-                         devOutside, useVertexCoverage);
+        this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside);
         return;
     }
 
@@ -786,8 +814,7 @@
         devOutsideAssist.outset(0, ry);
     }
 
-    this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist,
-                               devInside, useVertexCoverage, miterStroke);
+    this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist, devInside, miterStroke);
 }
 
 void GrAARectRenderer::geometryStrokeAARect(GrGpu* gpu,
@@ -795,11 +822,15 @@
                                             const SkRect& devOutside,
                                             const SkRect& devOutsideAssist,
                                             const SkRect& devInside,
-                                            bool useVertexCoverage,
                                             bool miterStroke) {
     GrDrawState* drawState = target->drawState();
 
-    set_aa_rect_vertex_attributes(drawState, useVertexCoverage);
+    CoverageAttribType covAttribType = set_rect_attribs(drawState);
+
+    GrColor color = drawState->getColor();
+    if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
+        drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
+    }
 
     int innerVertexNum = 4;
     int outerVertexNum = miterStroke ? 4 : 8;
@@ -817,16 +848,15 @@
     }
 
     intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
-    size_t vsize = drawState->getVertexSize();
-    SkASSERT(sizeof(SkPoint) + sizeof(GrColor) == vsize);
+    size_t vstride = drawState->getVertexStride();
 
     // We create vertices for four nested rectangles. There are two ramps from 0 to full
     // coverage, one on the exterior of the stroke and the other on the interior.
     // The following pointers refer to the four rects, from outermost to innermost.
     SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
-    SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * vsize);
-    SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * vsize);
-    SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts + (2 * outerVertexNum + innerVertexNum) * vsize);
+    SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * vstride);
+    SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * vstride);
+    SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts + (2 * outerVertexNum + innerVertexNum) * vstride);
 
 #ifndef SK_IGNORE_THIN_STROKED_RECT_FIX
     // TODO: this only really works if the X & Y margins are the same all around
@@ -846,33 +876,40 @@
 
     if (miterStroke) {
         // outermost
-        set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
+        set_inset_fan(fan0Pos, vstride, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
         // inner two
-        set_inset_fan(fan1Pos, vsize, devOutside,  inset,  inset);
-        set_inset_fan(fan2Pos, vsize, devInside,  -inset, -inset);
+        set_inset_fan(fan1Pos, vstride, devOutside,  inset,  inset);
+        set_inset_fan(fan2Pos, vstride, devInside,  -inset, -inset);
         // innermost
-        set_inset_fan(fan3Pos, vsize, devInside,   SK_ScalarHalf,  SK_ScalarHalf);
+        set_inset_fan(fan3Pos, vstride, devInside,   SK_ScalarHalf,  SK_ScalarHalf);
     } else {
-        SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vsize);
-        SkPoint* fan1AssistPos = reinterpret_cast<SkPoint*>(verts + (outerVertexNum + 4) * vsize);
+        SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vstride);
+        SkPoint* fan1AssistPos = reinterpret_cast<SkPoint*>(verts + (outerVertexNum + 4) * vstride);
         // outermost
-        set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
-        set_inset_fan(fan0AssistPos, vsize, devOutsideAssist, -SK_ScalarHalf, -SK_ScalarHalf);
+        set_inset_fan(fan0Pos, vstride, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
+        set_inset_fan(fan0AssistPos, vstride, devOutsideAssist, -SK_ScalarHalf, -SK_ScalarHalf);
         // outer one of the inner two
-        set_inset_fan(fan1Pos, vsize, devOutside,  inset,  inset);
-        set_inset_fan(fan1AssistPos, vsize, devOutsideAssist,  inset,  inset);
+        set_inset_fan(fan1Pos, vstride, devOutside,  inset,  inset);
+        set_inset_fan(fan1AssistPos, vstride, devOutsideAssist,  inset,  inset);
         // inner one of the inner two
-        set_inset_fan(fan2Pos, vsize, devInside,  -inset, -inset);
+        set_inset_fan(fan2Pos, vstride, devInside,  -inset, -inset);
         // innermost
-        set_inset_fan(fan3Pos, vsize, devInside,   SK_ScalarHalf,  SK_ScalarHalf);
+        set_inset_fan(fan3Pos, vstride, devInside,   SK_ScalarHalf,  SK_ScalarHalf);
     }
 
+    // Make verts point to vertex color and then set all the color and coverage vertex attrs values.
     // The outermost rect has 0 coverage
     verts += sizeof(SkPoint);
     for (int i = 0; i < outerVertexNum; ++i) {
-        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
+        if (kUseCoverage_CoverageAttribType == covAttribType) {
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
+            *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = 0;
+        } else {
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = 0;
+        }
     }
 
+    // scale is the coverage for the the inner two rects.
     int scale;
     if (inset < SK_ScalarHalf) {
         scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
@@ -881,27 +918,32 @@
         scale = 0xff;
     }
 
-    // The inner two rects have full coverage
-    GrColor innerColor;
-    if (useVertexCoverage) {
-        innerColor = GrColorPackRGBA(scale, scale, scale, scale);
+    verts += outerVertexNum * vstride;
+    GrColor innerCoverage;
+    if (kUseCoverage_CoverageAttribType == covAttribType) {
+        innerCoverage = GrColorPackRGBA(scale, scale, scale, scale);
     } else {
-        if (0xff == scale) {
-            innerColor = target->getDrawState().getColor();
+        innerCoverage = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
+    }
+
+    for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) {
+        if (kUseCoverage_CoverageAttribType == covAttribType) {
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
+            *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = innerCoverage;
         } else {
-            innerColor = SkAlphaMulQ(target->getDrawState().getColor(), scale);
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = innerCoverage;
         }
     }
 
-    verts += outerVertexNum * vsize;
-    for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) {
-        *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
-    }
-
     // The innermost rect has 0 coverage
-    verts += (outerVertexNum + innerVertexNum) * vsize;
+    verts += (outerVertexNum + innerVertexNum) * vstride;
     for (int i = 0; i < innerVertexNum; ++i) {
-        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
+        if (kUseCoverage_CoverageAttribType == covAttribType) {
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
+            *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = 0;
+        } else {
+            *reinterpret_cast<GrColor*>(verts + i * vstride) = 0;
+        }
     }
 
     target->setIndexSourceToBuffer(indexBuffer);
@@ -912,8 +954,7 @@
 void GrAARectRenderer::fillAANestedRects(GrGpu* gpu,
                                          GrDrawTarget* target,
                                          const SkRect rects[2],
-                                         const SkMatrix& combinedMatrix,
-                                         bool useVertexCoverage) {
+                                         const SkMatrix& combinedMatrix) {
     SkASSERT(combinedMatrix.rectStaysRect());
     SkASSERT(!rects[1].isEmpty());
 
@@ -923,10 +964,9 @@
     combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2);
 
     if (devInside.isEmpty()) {
-        this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside, useVertexCoverage);
+        this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside);
         return;
     }
 
-    this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist,
-                               devInside, useVertexCoverage, true);
+    this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist, devInside, true);
 }
diff --git a/src/gpu/GrAARectRenderer.h b/src/gpu/GrAARectRenderer.h
index faaf7e2..bfa295b 100644
--- a/src/gpu/GrAARectRenderer.h
+++ b/src/gpu/GrAARectRenderer.h
@@ -43,8 +43,7 @@
                     GrDrawTarget* target,
                     const SkRect& rect,
                     const SkMatrix& combinedMatrix,
-                    const SkRect& devRect,
-                    bool useVertexCoverage) {
+                    const SkRect& devRect) {
 #ifdef SHADER_AA_FILL_RECT
         if (combinedMatrix.rectStaysRect()) {
             this->shaderFillAlignedAARect(gpu, target,
@@ -54,9 +53,7 @@
                                    rect, combinedMatrix);
         }
 #else
-        this->geometryFillAARect(gpu, target,
-                                 rect, combinedMatrix,
-                                 devRect, useVertexCoverage);
+        this->geometryFillAARect(gpu, target, rect, combinedMatrix, devRect);
 #endif
     }
 
@@ -65,15 +62,13 @@
                       const SkRect& rect,
                       const SkMatrix& combinedMatrix,
                       const SkRect& devRect,
-                      const SkStrokeRec& stroke,
-                      bool useVertexCoverage);
+                      const SkStrokeRec& stroke);
 
     // First rect is outer; second rect is inner
     void fillAANestedRects(GrGpu* gpu,
                            GrDrawTarget* target,
                            const SkRect rects[2],
-                           const SkMatrix& combinedMatrix,
-                           bool useVertexCoverage);
+                           const SkMatrix& combinedMatrix);
 
 private:
     GrIndexBuffer*              fAAFillRectIndexBuffer;
@@ -85,14 +80,11 @@
     static int aaStrokeRectIndexCount(bool miterStroke);
     GrIndexBuffer* aaStrokeRectIndexBuffer(GrGpu* gpu, bool miterStroke);
 
-    // TODO: Remove the useVertexCoverage boolean. Just use it all the time
-    // since we now have a coverage vertex attribute
     void geometryFillAARect(GrGpu* gpu,
                             GrDrawTarget* target,
                             const SkRect& rect,
                             const SkMatrix& combinedMatrix,
-                            const SkRect& devRect,
-                            bool useVertexCoverage);
+                            const SkRect& devRect);
 
     void shaderFillAARect(GrGpu* gpu,
                           GrDrawTarget* target,
@@ -109,7 +101,6 @@
                               const SkRect& devOutside,
                               const SkRect& devOutsideAssist,
                               const SkRect& devInside,
-                              bool useVertexCoverage,
                               bool miterStroke);
 
     typedef SkRefCnt INHERITED;
diff --git a/src/gpu/GrAllocPool.cpp b/src/gpu/GrAllocPool.cpp
index c92ebbd..9594c94 100644
--- a/src/gpu/GrAllocPool.cpp
+++ b/src/gpu/GrAllocPool.cpp
@@ -90,7 +90,7 @@
 void GrAllocPool::release(size_t bytes) {
     this->validate();
 
-    while (bytes && NULL != fBlock) {
+    while (bytes && fBlock) {
         bytes = fBlock->release(bytes);
         if (fBlock->empty()) {
             Block* next = fBlock->fNext;
diff --git a/src/gpu/GrAllocator.h b/src/gpu/GrAllocator.h
index a2ad408..861c3cb 100644
--- a/src/gpu/GrAllocator.h
+++ b/src/gpu/GrAllocator.h
@@ -15,9 +15,7 @@
 
 class GrAllocator : SkNoncopyable {
 public:
-    ~GrAllocator() {
-        reset();
-    }
+    ~GrAllocator() { this->reset(); }
 
     /**
      * Create an allocator
@@ -28,18 +26,171 @@
      *                          Must be at least itemSize*itemsPerBlock sized.
      *                          Caller is responsible for freeing this memory.
      */
-    GrAllocator(size_t itemSize, int itemsPerBlock, void* initialBlock) :
-            fItemSize(itemSize),
-            fItemsPerBlock(itemsPerBlock),
-            fOwnFirstBlock(NULL == initialBlock),
-            fCount(0) {
+    GrAllocator(size_t itemSize, int itemsPerBlock, void* initialBlock)
+        : fItemSize(itemSize)
+        , fItemsPerBlock(itemsPerBlock)
+        , fOwnFirstBlock(NULL == initialBlock)
+        , fCount(0)
+        , fInsertionIndexInBlock(0) {
         SkASSERT(itemsPerBlock > 0);
         fBlockSize = fItemSize * fItemsPerBlock;
-        fBlocks.push_back() = initialBlock;
-        SkDEBUGCODE(if (!fOwnFirstBlock) {*((char*)initialBlock+fBlockSize-1)='a';} );
+        if (fOwnFirstBlock) {
+            // This force us to allocate a new block on push_back().
+            fInsertionIndexInBlock = fItemsPerBlock;
+        } else {
+            fBlocks.push_back() = initialBlock;
+            fInsertionIndexInBlock = 0;
+        }
     }
 
-    /*
+    /**
+     * Adds an item and returns pointer to it.
+     *
+     * @return pointer to the added item.
+     */
+    void* push_back() {
+        // we always have at least one block
+        if (fItemsPerBlock == fInsertionIndexInBlock) {
+            fBlocks.push_back() = sk_malloc_throw(fBlockSize);
+            fInsertionIndexInBlock = 0;
+        }
+        void* ret = (char*)fBlocks.back() + fItemSize * fInsertionIndexInBlock;
+        ++fCount;
+        ++fInsertionIndexInBlock;
+        return ret;
+    }
+
+    /**
+     * Remove the last item, only call if count() != 0
+     */
+    void pop_back() {
+        SkASSERT(fCount);
+        SkASSERT(fInsertionIndexInBlock > 0);
+        --fInsertionIndexInBlock;
+        --fCount;
+        if (0 == fInsertionIndexInBlock) {
+            // Never delete the first block
+            if (fBlocks.count() > 1) {
+                sk_free(fBlocks.back());
+                fBlocks.pop_back();
+                fInsertionIndexInBlock = fItemsPerBlock;
+            }
+        }
+    }
+
+    /**
+     * Removes all added items.
+     */
+    void reset() {
+        int firstBlockToFree = fOwnFirstBlock ? 0 : 1;
+        for (int i = firstBlockToFree; i < fBlocks.count(); ++i) {
+            sk_free(fBlocks[i]);
+        }
+        if (fOwnFirstBlock) {
+            fBlocks.reset();
+            // This force us to allocate a new block on push_back().
+            fInsertionIndexInBlock = fItemsPerBlock;
+        } else {
+            fBlocks.pop_back_n(fBlocks.count() - 1);
+            fInsertionIndexInBlock = 0;
+        }
+        fCount = 0;
+    }
+
+    /**
+     * Returns the item count.
+     */
+    int count() const {
+        return fCount;
+    }
+
+    /**
+     * Is the count 0?
+     */
+    bool empty() const { return 0 == fCount; }
+
+    /**
+     * Access last item, only call if count() != 0
+     */
+    void* back() {
+        SkASSERT(fCount);
+        SkASSERT(fInsertionIndexInBlock > 0);
+        return (char*)(fBlocks.back()) + (fInsertionIndexInBlock - 1) * fItemSize;
+    }
+
+    /**
+     * Access last item, only call if count() != 0
+     */
+    const void* back() const {
+        SkASSERT(fCount);
+        SkASSERT(fInsertionIndexInBlock > 0);
+        return (const char*)(fBlocks.back()) + (fInsertionIndexInBlock - 1) * fItemSize;
+    }
+
+    /**
+     * Iterates through the allocator. This is faster than using operator[] when walking linearly
+     * through the allocator.
+     */
+    class Iter {
+    public:
+        /**
+         * Initializes the iterator. next() must be called before get().
+         */
+        Iter(const GrAllocator* allocator)
+            : fAllocator(allocator)
+            , fBlockIndex(-1)
+            , fIndexInBlock(allocator->fItemsPerBlock - 1)
+            , fItemIndex(-1) {}
+
+        /**
+         * Advances the iterator. Iteration is finished when next() returns false.
+         */
+        bool next() {
+            ++fIndexInBlock;
+            ++fItemIndex;
+            if (fIndexInBlock == fAllocator->fItemsPerBlock) {
+                ++fBlockIndex;
+                fIndexInBlock = 0;
+            }
+            return fItemIndex < fAllocator->fCount;
+        }
+
+        /**
+         * Gets the current iterator value. Call next() at least once before calling. Don't call
+         * after next() returns false.
+         */
+        void* get() const {
+            SkASSERT(fItemIndex >= 0 && fItemIndex < fAllocator->fCount);
+            return (char*) fAllocator->fBlocks[fBlockIndex] + fIndexInBlock * fAllocator->fItemSize;
+        }
+
+    private:
+        const GrAllocator* fAllocator;
+        int                fBlockIndex;
+        int                fIndexInBlock;
+        int                fItemIndex;
+    };
+
+    /**
+     * Access item by index.
+     */
+    void* operator[] (int i) {
+        SkASSERT(i >= 0 && i < fCount);
+        return (char*)fBlocks[i / fItemsPerBlock] +
+               fItemSize * (i % fItemsPerBlock);
+    }
+
+    /**
+     * Access item by index.
+     */
+    const void* operator[] (int i) const {
+        SkASSERT(i >= 0 && i < fCount);
+        return (const char*)fBlocks[i / fItemsPerBlock] +
+               fItemSize * (i % fItemsPerBlock);
+    }
+
+protected:
+    /**
      * Set first block of memory to write into.  Must be called before any other methods.
      * This requires that you have passed NULL in the constructor.
      *
@@ -49,111 +200,34 @@
      */
     void setInitialBlock(void* initialBlock) {
         SkASSERT(0 == fCount);
-        SkASSERT(1 == fBlocks.count());
-        SkASSERT(NULL == fBlocks.back());
+        SkASSERT(0 == fBlocks.count());
+        SkASSERT(fItemsPerBlock == fInsertionIndexInBlock);
         fOwnFirstBlock = false;
-        fBlocks.back() = initialBlock;
+        fBlocks.push_back() = initialBlock;
+        fInsertionIndexInBlock = 0;
     }
 
-    /**
-     * Adds an item and returns pointer to it.
-     *
-     * @return pointer to the added item.
-     */
-    void* push_back() {
-        int indexInBlock = fCount % fItemsPerBlock;
-        // we always have at least one block
-        if (0 == indexInBlock) {
-            if (0 != fCount) {
-                fBlocks.push_back() = sk_malloc_throw(fBlockSize);
-            } else if (fOwnFirstBlock) {
-                fBlocks[0] = sk_malloc_throw(fBlockSize);
-            }
-        }
-        void* ret = (char*)fBlocks[fCount/fItemsPerBlock] +
-                    fItemSize * indexInBlock;
-        ++fCount;
-        return ret;
-    }
-
-    /**
-     * removes all added items
-     */
-    void reset() {
-        int blockCount = SkTMax((unsigned)1,
-                               GrUIDivRoundUp(fCount, fItemsPerBlock));
-        for (int i = 1; i < blockCount; ++i) {
-            sk_free(fBlocks[i]);
-        }
-        if (fOwnFirstBlock) {
-            sk_free(fBlocks[0]);
-            fBlocks[0] = NULL;
-        }
-        fBlocks.pop_back_n(blockCount-1);
-        fCount = 0;
-    }
-
-    /**
-     * count of items
-     */
-    int count() const {
-        return fCount;
-    }
-
-    /**
-     * is the count 0
-     */
-    bool empty() const { return fCount == 0; }
-
-    /**
-     * access last item, only call if count() != 0
-     */
-    void* back() {
-        SkASSERT(fCount);
-        return (*this)[fCount-1];
-    }
-
-    /**
-     * access last item, only call if count() != 0
-     */
-    const void* back() const {
-        SkASSERT(fCount);
-        return (*this)[fCount-1];
-    }
-
-    /**
-     * access item by index.
-     */
-    void* operator[] (int i) {
-        SkASSERT(i >= 0 && i < fCount);
-        return (char*)fBlocks[i / fItemsPerBlock] +
-               fItemSize * (i % fItemsPerBlock);
-    }
-
-    /**
-     * access item by index.
-     */
-    const void* operator[] (int i) const {
-        SkASSERT(i >= 0 && i < fCount);
-        return (const char*)fBlocks[i / fItemsPerBlock] +
-               fItemSize * (i % fItemsPerBlock);
-    }
+    // For access to above function.
+    template <typename T> friend class GrTAllocator;
 
 private:
     static const int NUM_INIT_BLOCK_PTRS = 8;
 
-    SkSTArray<NUM_INIT_BLOCK_PTRS, void*>   fBlocks;
-    size_t                                  fBlockSize;
-    size_t                                  fItemSize;
-    int                                     fItemsPerBlock;
-    bool                                    fOwnFirstBlock;
-    int                                     fCount;
+    SkSTArray<NUM_INIT_BLOCK_PTRS, void*, true>   fBlocks;
+    size_t                                        fBlockSize;
+    size_t                                        fItemSize;
+    int                                           fItemsPerBlock;
+    bool                                          fOwnFirstBlock;
+    int                                           fCount;
+    int                                           fInsertionIndexInBlock;
 
     typedef SkNoncopyable INHERITED;
 };
 
-template <typename T>
-class GrTAllocator : SkNoncopyable {
+template <typename T> class GrTAllocator;
+template <typename T> void* operator new(size_t, GrTAllocator<T>*);
+
+template <typename T> class GrTAllocator : SkNoncopyable {
 public:
     virtual ~GrTAllocator() { this->reset(); };
 
@@ -172,20 +246,28 @@
      */
     T& push_back() {
         void* item = fAllocator.push_back();
-        SkASSERT(NULL != item);
+        SkASSERT(item);
         SkNEW_PLACEMENT(item, T);
         return *(T*)item;
     }
 
     T& push_back(const T& t) {
         void* item = fAllocator.push_back();
-        SkASSERT(NULL != item);
+        SkASSERT(item);
         SkNEW_PLACEMENT_ARGS(item, T, (t));
         return *(T*)item;
     }
 
     /**
-     * removes all added items
+     * Remove the last item, only call if count() != 0
+     */
+    void pop_back() {
+        this->back().~T();
+        fAllocator.pop_back();
+    }
+
+    /**
+     * Removes all added items.
      */
     void reset() {
         int c = fAllocator.count();
@@ -196,40 +278,72 @@
     }
 
     /**
-     * count of items
+     * Returns the item count.
      */
     int count() const {
         return fAllocator.count();
     }
 
     /**
-     * is the count 0
+     * Is the count 0?
      */
     bool empty() const { return fAllocator.empty(); }
 
     /**
-     * access last item, only call if count() != 0
+     * Access last item, only call if count() != 0
      */
     T& back() {
         return *(T*)fAllocator.back();
     }
 
     /**
-     * access last item, only call if count() != 0
+     * Access last item, only call if count() != 0
      */
     const T& back() const {
         return *(const T*)fAllocator.back();
     }
 
     /**
-     * access item by index.
+     * Iterates through the allocator. This is faster than using operator[] when walking linearly
+     * through the allocator.
+     */
+    class Iter {
+    public:
+        /**
+         * Initializes the iterator. next() must be called before get() or ops * and ->.
+         */
+        Iter(const GrTAllocator* allocator) : fImpl(&allocator->fAllocator) {}
+
+        /**
+         * Advances the iterator. Iteration is finished when next() returns false.
+         */
+        bool next() { return fImpl.next(); }
+
+        /**
+         * Gets the current iterator value. Call next() at least once before calling. Don't call
+         * after next() returns false.
+         */
+        T* get() const { return (T*) fImpl.get(); }
+
+        /**
+         * Convenience operators. Same rules for calling apply as get().
+         */
+        T& operator*() const { return *this->get(); }
+        T* operator->() const { return this->get(); }
+
+    private:
+        GrAllocator::Iter fImpl;
+    };
+
+    /**
+     * Access item by index.
      */
     T& operator[] (int i) {
         return *(T*)(fAllocator[i]);
     }
 
     /**
-     * access item by index.
+     * Access item by index.
      */
     const T& operator[] (int i) const {
         return *(const T*)(fAllocator[i]);
@@ -248,6 +362,8 @@
     }
 
 private:
+    friend void* operator new<T>(size_t, GrTAllocator*);
+
     GrAllocator fAllocator;
     typedef SkNoncopyable INHERITED;
 };
@@ -265,4 +381,18 @@
     SkAlignedSTStorage<N, T> fStorage;
 };
 
+template <typename T> void* operator new(size_t size, GrTAllocator<T>* allocator) {
+    return allocator->fAllocator.push_back();
+}
+
+// Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete
+// to match the op new silences warnings about missing op delete when a constructor throws an
+// exception.
+template <typename T> void operator delete(void*, GrTAllocator<T>*) {
+    SK_CRASH();
+}
+
+#define GrNEW_APPEND_TO_ALLOCATOR(allocator_ptr, type_name, args) \
+    new (allocator_ptr) type_name args
+
 #endif
diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp
index ea5ad50..e75f859 100644
--- a/src/gpu/GrAtlas.cpp
+++ b/src/gpu/GrAtlas.cpp
@@ -20,13 +20,15 @@
 static int g_UploadCount = 0;
 #endif
 
-GrPlot::GrPlot() : fDrawToken(NULL, 0)
-                 , fTexture(NULL)
-                 , fRects(NULL)
-                 , fAtlasMgr(NULL)
-                 , fBytesPerPixel(1)
-                 , fDirty(false)
-                 , fBatchUploads(false)
+GrPlot::GrPlot() 
+    : fDrawToken(NULL, 0)
+    , fID(-1)
+    , fTexture(NULL)
+    , fRects(NULL)
+    , fAtlas(NULL)
+    , fBytesPerPixel(1)
+    , fDirty(false)
+    , fBatchUploads(false)
 {
     fOffset.set(0, 0);
 }
@@ -37,10 +39,11 @@
     delete fRects;
 }
 
-void GrPlot::init(GrAtlasMgr* mgr, int offX, int offY, int width, int height, size_t bpp,
+void GrPlot::init(GrAtlas* atlas, int id, int offX, int offY, int width, int height, size_t bpp,
                   bool batchUploads) {
+    fID = id;
     fRects = GrRectanizer::Factory(width, height);
-    fAtlasMgr = mgr;
+    fAtlas = atlas;
     fOffset.set(offX * width, offY * height);
     fBytesPerPixel = bpp;
     fPlotData = NULL;
@@ -54,8 +57,7 @@
     loc->fY += offset.fY;
 }
 
-bool GrPlot::addSubImage(int width, int height, const void* image,
-                         SkIPoint16* loc) {
+bool GrPlot::addSubImage(int width, int height, const void* image, SkIPoint16* loc) {
     float percentFull = fRects->percentFull();
     if (!fRects->addRect(width, height, loc)) {
         return false;
@@ -71,7 +73,7 @@
     }
 
     // if we have backing memory, copy to the memory and set for future upload
-    if (NULL != fPlotData) {
+    if (fPlotData) {
         const unsigned char* imagePtr = (const unsigned char*) image;
         // point ourselves at the right starting spot
         unsigned char* dataPtr = fPlotData;
@@ -88,7 +90,7 @@
         adjust_for_offset(loc, fOffset);
         fDirty = true;
     // otherwise, just upload the image directly
-    } else {
+    } else if (image) {
         adjust_for_offset(loc, fOffset);
         GrContext* context = fTexture->getContext();
         TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "GrPlot::uploadToTexture");
@@ -96,6 +98,8 @@
                                     loc->fX, loc->fY, width, height,
                                     fTexture->config(), image, 0,
                                     GrContext::kDontFlush_PixelOpsFlag);
+    } else {
+        adjust_for_offset(loc, fOffset);
     }
 
 #if FONT_CACHE_STATS
@@ -113,7 +117,7 @@
 
     if (fDirty) {
         TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "GrPlot::uploadToTexture");
-        SkASSERT(NULL != fTexture);
+        SkASSERT(fTexture);
         GrContext* context = fTexture->getContext();
         // We pass the flag that does not force a flush. We assume our caller is
         // smart and hasn't referenced the part of the texture we're about to update
@@ -140,17 +144,18 @@
 }
 
 void GrPlot::resetRects() {
-    SkASSERT(NULL != fRects);
+    SkASSERT(fRects);
     fRects->reset();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config,
-                       const SkISize& backingTextureSize,
-                       int numPlotsX, int numPlotsY, bool batchUploads) {
+GrAtlas::GrAtlas(GrGpu* gpu, GrPixelConfig config, GrTextureFlags flags,
+                 const SkISize& backingTextureSize,
+                 int numPlotsX, int numPlotsY, bool batchUploads) {
     fGpu = SkRef(gpu);
     fPixelConfig = config;
+    fFlags = flags;
     fBackingTextureSize = backingTextureSize;
     fNumPlotsX = numPlotsX;
     fNumPlotsY = numPlotsY;
@@ -176,7 +181,7 @@
     GrPlot* currPlot = fPlotArray;
     for (int y = numPlotsY-1; y >= 0; --y) {
         for (int x = numPlotsX-1; x >= 0; --x) {
-            currPlot->init(this, x, y, plotWidth, plotHeight, bpp, batchUploads);
+            currPlot->init(this, y*numPlotsX+x, x, y, plotWidth, plotHeight, bpp, batchUploads);
 
             // build LRU list
             fPlotList.addToHead(currPlot);
@@ -185,7 +190,7 @@
     }
 }
 
-GrAtlasMgr::~GrAtlasMgr() {
+GrAtlas::~GrAtlas() {
     SkSafeUnref(fTexture);
     SkDELETE_ARRAY(fPlotArray);
 
@@ -195,7 +200,7 @@
 #endif
 }
 
-void GrAtlasMgr::moveToHead(GrPlot* plot) {
+void GrAtlas::makeMRU(GrPlot* plot) {
     if (fPlotList.head() == plot) {
         return;
     }
@@ -204,15 +209,15 @@
     fPlotList.addToHead(plot);
 };
 
-GrPlot* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
-                               int width, int height, const void* image,
-                               SkIPoint16* loc) {
+GrPlot* GrAtlas::addToAtlas(ClientPlotUsage* usage,
+                            int width, int height, const void* image,
+                            SkIPoint16* loc) {
     // iterate through entire plot list for this atlas, see if we can find a hole
     // last one was most recently added and probably most empty
-    for (int i = atlas->fPlots.count()-1; i >= 0; --i) {
-        GrPlot* plot = atlas->fPlots[i];
+    for (int i = usage->fPlots.count()-1; i >= 0; --i) {
+        GrPlot* plot = usage->fPlots[i];
         if (plot->addSubImage(width, height, image, loc)) {
-            this->moveToHead(plot);
+            this->makeMRU(plot);
             return plot;
         }
     }
@@ -221,7 +226,7 @@
     if (NULL == fTexture) {
         // TODO: Update this to use the cache rather than directly creating a texture.
         GrTextureDesc desc;
-        desc.fFlags = kDynamicUpdate_GrTextureFlagBit;
+        desc.fFlags = fFlags | kDynamicUpdate_GrTextureFlagBit;
         desc.fWidth = fBackingTextureSize.width();
         desc.fHeight = fBackingTextureSize.height();
         desc.fConfig = fPixelConfig;
@@ -236,13 +241,14 @@
     GrPlotList::Iter plotIter;
     plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart);
     GrPlot* plot;
-    while (NULL != (plot = plotIter.get())) {
+    while ((plot = plotIter.get())) {
         // make sure texture is set for quick lookup
         plot->fTexture = fTexture;
         if (plot->addSubImage(width, height, image, loc)) {
-            this->moveToHead(plot);
+            this->makeMRU(plot);
             // new plot for atlas, put at end of array
-            *(atlas->fPlots.append()) = plot;
+            SkASSERT(!usage->fPlots.contains(plot));
+            *(usage->fPlots.append()) = plot;
             return plot;
         }
         plotIter.next();
@@ -252,25 +258,19 @@
     return NULL;
 }
 
-bool GrAtlasMgr::removePlot(GrAtlas* atlas, const GrPlot* plot) {
-    // iterate through plot list for this atlas
-    int count = atlas->fPlots.count();
-    for (int i = 0; i < count; ++i) {
-        if (plot == atlas->fPlots[i]) {
-            atlas->fPlots.remove(i);
-            return true;
-        }
+void GrAtlas::RemovePlot(ClientPlotUsage* usage, const GrPlot* plot) {
+    int index = usage->fPlots.find(const_cast<GrPlot*>(plot));
+    if (index >= 0) {
+        usage->fPlots.remove(index);
     }
-
-    return false;
 }
 
 // get a plot that's not being used by the current draw
-GrPlot* GrAtlasMgr::getUnusedPlot() {
+GrPlot* GrAtlas::getUnusedPlot() {
     GrPlotList::Iter plotIter;
     plotIter.init(fPlotList, GrPlotList::Iter::kTail_IterStart);
     GrPlot* plot;
-    while (NULL != (plot = plotIter.get())) {
+    while ((plot = plotIter.get())) {
         if (plot->drawToken().isIssued()) {
             return plot;
         }
@@ -280,12 +280,12 @@
     return NULL;
 }
 
-void GrAtlasMgr::uploadPlotsToTexture() {
+void GrAtlas::uploadPlotsToTexture() {
     if (fBatchUploads) {
         GrPlotList::Iter plotIter;
         plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart);
         GrPlot* plot;
-        while (NULL != (plot = plotIter.get())) {
+        while ((plot = plotIter.get())) {
             plot->uploadToTexture();
             plotIter.next();
         }
diff --git a/src/gpu/GrAtlas.h b/src/gpu/GrAtlas.h
index 47048a8..1e91d1e 100644
--- a/src/gpu/GrAtlas.h
+++ b/src/gpu/GrAtlas.h
@@ -10,29 +10,33 @@
 #define GrAtlas_DEFINED
 
 
-#include "SkPoint.h"
 #include "GrTexture.h"
 #include "GrDrawTarget.h"
+#include "SkPoint.h"
+#include "SkTInternalLList.h"
 
 class GrGpu;
 class GrRectanizer;
-class GrAtlasMgr;
 class GrAtlas;
 
 // The backing GrTexture for a set of GrAtlases is broken into a spatial grid of GrPlots. When
 // a GrAtlas needs space on the texture, it requests a GrPlot. Each GrAtlas can claim one
 // or more GrPlots. The GrPlots keep track of subimage placement via their GrRectanizer. Once a
 // GrPlot is "full" (i.e. there is no room for the new subimage according to the GrRectanizer), the
-// GrAtlas can request a new GrPlot via GrAtlasMgr::addToAtlas().
+// GrAtlas can request a new GrPlot via GrAtlas::addToAtlas().
 //
 // If all GrPlots are allocated, the replacement strategy is up to the client. The drawToken is
 // available to ensure that all draw calls are finished for that particular GrPlot.
-// GrAtlasMgr::removeUnusedPlots() will free up any finished plots for a given GrAtlas.
+// GrAtlas::removeUnusedPlots() will free up any finished plots for a given GrAtlas.
 
 class GrPlot {
 public:
     SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrPlot);
 
+    // This returns a plot ID unique to each plot in a given GrAtlas. They are
+    // consecutive and start at 0.
+    int id() const { return fID; }
+
     GrTexture* texture() const { return fTexture; }
 
     bool addSubImage(int width, int height, const void*, SkIPoint16*);
@@ -47,39 +51,62 @@
 private:
     GrPlot();
     ~GrPlot(); // does not try to delete the fNext field
-    void init(GrAtlasMgr* mgr, int offX, int offY, int width, int height, size_t bpp,
+    void init(GrAtlas* atlas, int id, int offX, int offY, int width, int height, size_t bpp,
               bool batchUploads);
 
     // for recycling
     GrDrawTarget::DrawToken fDrawToken;
 
+    int                     fID;
     unsigned char*          fPlotData;
     GrTexture*              fTexture;
     GrRectanizer*           fRects;
-    GrAtlasMgr*             fAtlasMgr;
+    GrAtlas*                fAtlas;
     SkIPoint16              fOffset;        // the offset of the plot in the backing texture
     size_t                  fBytesPerPixel;
     SkIRect                 fDirtyRect;
     bool                    fDirty;
     bool                    fBatchUploads;
 
-    friend class GrAtlasMgr;
+    friend class GrAtlas;
 };
 
 typedef SkTInternalLList<GrPlot> GrPlotList;
 
-class GrAtlasMgr {
+class GrAtlas {
 public:
-    GrAtlasMgr(GrGpu*, GrPixelConfig, const SkISize& backingTextureSize,
-               int numPlotsX, int numPlotsY, bool batchUploads);
-    ~GrAtlasMgr();
+    // This class allows each client to independently track the GrPlots in
+    // which its data is stored.
+    class ClientPlotUsage {
+    public:
+        bool isEmpty() const { return 0 == fPlots.count(); }
 
-    // add subimage of width, height dimensions to atlas
-    // returns the containing GrPlot and location relative to the backing texture
-    GrPlot* addToAtlas(GrAtlas*, int width, int height, const void*, SkIPoint16*);
+#ifdef SK_DEBUG
+        bool contains(const GrPlot* plot) const { 
+            return fPlots.contains(const_cast<GrPlot*>(plot)); 
+        }
+#endif
+
+    private:
+        SkTDArray<GrPlot*> fPlots;
+
+        friend class GrAtlas;
+    };
+
+    GrAtlas(GrGpu*, GrPixelConfig, GrTextureFlags flags, 
+            const SkISize& backingTextureSize,
+            int numPlotsX, int numPlotsY, bool batchUploads);
+    ~GrAtlas();
+
+    // Adds a width x height subimage to the atlas. Upon success it returns 
+    // the containing GrPlot and absolute location in the backing texture. 
+    // NULL is returned if the subimage cannot fit in the atlas.
+    // If provided, the image data will either be immediately uploaded or
+    // written to the CPU-side backing bitmap.
+    GrPlot* addToAtlas(ClientPlotUsage*, int width, int height, const void* image, SkIPoint16* loc);
 
     // remove reference to this plot
-    bool removePlot(GrAtlas* atlas, const GrPlot* plot);
+    static void RemovePlot(ClientPlotUsage* usage, const GrPlot* plot);
 
     // get a plot that's not being used by the current draw
     // this allows us to overwrite this plot without flushing
@@ -91,34 +118,34 @@
 
     void uploadPlotsToTexture();
 
-private:
-    void moveToHead(GrPlot* plot);
+    enum IterOrder {
+        kLRUFirst_IterOrder,
+        kMRUFirst_IterOrder
+    };
 
-    GrGpu*        fGpu;
-    GrPixelConfig fPixelConfig;
-    GrTexture*    fTexture;
-    SkISize       fBackingTextureSize;
-    int           fNumPlotsX;
-    int           fNumPlotsY;
-    bool          fBatchUploads;
+    typedef GrPlotList::Iter PlotIter;
+    GrPlot* iterInit(PlotIter* iter, IterOrder order) {
+        return iter->init(fPlotList, kLRUFirst_IterOrder == order 
+                                                       ? GrPlotList::Iter::kTail_IterStart
+                                                       : GrPlotList::Iter::kHead_IterStart);
+    }
+
+private:
+    void makeMRU(GrPlot* plot);
+
+    GrGpu*         fGpu;
+    GrPixelConfig  fPixelConfig;
+    GrTextureFlags fFlags;
+    GrTexture*     fTexture;
+    SkISize        fBackingTextureSize;
+    int            fNumPlotsX;
+    int            fNumPlotsY;
+    bool           fBatchUploads;
 
     // allocated array of GrPlots
     GrPlot*       fPlotArray;
-    // LRU list of GrPlots
+    // LRU list of GrPlots (MRU at head - LRU at tail)
     GrPlotList    fPlotList;
 };
 
-class GrAtlas {
-public:
-    GrAtlas() { }
-    ~GrAtlas() { }
-
-    bool isEmpty() { return 0 == fPlots.count(); }
-
-private:
-    SkTDArray<GrPlot*> fPlots;
-
-    friend class GrAtlasMgr;
-};
-
 #endif
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 25c13ec..82784bf 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -30,23 +30,24 @@
 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
                 "Dump the contents of the font cache before every purge.");
 
-static const int kGlyphCoordsNoColorAttributeIndex = 1;
-static const int kGlyphCoordsWithColorAttributeIndex = 2;
-
 namespace {
 // position + texture coord
 extern const GrVertexAttrib gTextVertexAttribs[] = {
     {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, sizeof(SkPoint) , kEffect_GrVertexAttribBinding}
+    {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
 };
 
+static const size_t kTextVASize = 2 * sizeof(SkPoint); 
+
 // position + color + texture coord
 extern const GrVertexAttrib gTextVertexWithColorAttribs[] = {
     {kVec2f_GrVertexAttribType,  0,                                 kPosition_GrVertexAttribBinding},
     {kVec4ub_GrVertexAttribType, sizeof(SkPoint),                   kColor_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType,  sizeof(SkPoint) + sizeof(GrColor), kEffect_GrVertexAttribBinding}
+    {kVec2f_GrVertexAttribType,  sizeof(SkPoint) + sizeof(GrColor), kGeometryProcessor_GrVertexAttribBinding}
 };
 
+static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor); 
+
 };
 
 GrBitmapTextContext::GrBitmapTextContext(GrContext* context,
@@ -56,7 +57,7 @@
 
     fCurrTexture = NULL;
     fCurrVertex = 0;
-    fEffectTextureGenID = 0;
+    fEffectTextureUniqueID = SK_InvalidUniqueID;
 
     fVertices = NULL;
     fMaxVertices = 0;
@@ -94,18 +95,17 @@
         SkASSERT(fCurrTexture);
         GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
 
-        uint32_t textureGenID = fCurrTexture->getGenerationID();
+        uint32_t textureUniqueID = fCurrTexture->getUniqueID();
         
-        if (textureGenID != fEffectTextureGenID) {
-            fCachedEffect.reset(GrCustomCoordsTextureEffect::Create(fCurrTexture, params));
-            fEffectTextureGenID = textureGenID;
+        if (textureUniqueID != fEffectTextureUniqueID) {
+            fCachedGeometryProcessor.reset(GrCustomCoordsTextureEffect::Create(fCurrTexture,
+                                                                               params));
+            fEffectTextureUniqueID = textureUniqueID;
         }
 
         // This effect could be stored with one of the cache objects (atlas?)
-        int coordsIdx = drawState->hasColorVertexAttribute() ? kGlyphCoordsWithColorAttributeIndex :
-                                                               kGlyphCoordsNoColorAttributeIndex;
-        drawState->addCoverageEffect(fCachedEffect.get(), coordsIdx);
-        SkASSERT(NULL != fStrike);
+        drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
+        SkASSERT(fStrike);
         switch (fStrike->getMaskFormat()) {
             // Color bitmap text
             case kARGB_GrMaskFormat:
@@ -138,10 +138,8 @@
             case kA8_GrMaskFormat:
                 // set back to normal in case we took LCD path previously.
                 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
-                //drawState->setColor(fPaint.getColor());
                 // We're using per-vertex color.
                 SkASSERT(drawState->hasColorVertexAttribute());
-                drawState->setColor(0xFFFFFFFF);
                 break;
             default:
                 SkFAIL("Unexepected mask format.");
@@ -457,30 +455,32 @@
     }
 
     if (NULL == glyph->fPlot) {
-        if (fStrike->addGlyphToAtlas(glyph, scaler)) {
-            goto HAS_ATLAS;
-        }
+        if (!fStrike->glyphTooLargeForAtlas(glyph)) {
+            if (fStrike->addGlyphToAtlas(glyph, scaler)) {
+                goto HAS_ATLAS;
+            }
 
-        // try to clear out an unused plot before we flush
-        if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
-            fStrike->addGlyphToAtlas(glyph, scaler)) {
-            goto HAS_ATLAS;
-        }
+            // try to clear out an unused plot before we flush
+            if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
+                fStrike->addGlyphToAtlas(glyph, scaler)) {
+                goto HAS_ATLAS;
+            }
 
-        if (c_DumpFontCache) {
+            if (c_DumpFontCache) {
 #ifdef SK_DEVELOPER
-            fContext->getFontCache()->dump();
+                fContext->getFontCache()->dump();
 #endif
-        }
+            }
 
-        // flush any accumulated draws to allow us to free up a plot
-        this->flushGlyphs();
-        fContext->flush();
+            // flush any accumulated draws to allow us to free up a plot
+            this->flushGlyphs();
+            fContext->flush();
 
-        // we should have an unused plot now
-        if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
-            fStrike->addGlyphToAtlas(glyph, scaler)) {
-            goto HAS_ATLAS;
+            // we should have an unused plot now
+            if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
+                fStrike->addGlyphToAtlas(glyph, scaler)) {
+                goto HAS_ATLAS;
+            }
         }
 
         if (NULL == glyph->fPath) {
@@ -530,10 +530,10 @@
         fMaxVertices = kMinRequestedVerts;
         if (useColorVerts) {
             fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
-                SK_ARRAY_COUNT(gTextVertexWithColorAttribs));
+                SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize);
         } else {
             fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
-                SK_ARRAY_COUNT(gTextVertexAttribs));
+                SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize);
         }
         bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
         if (flush) {
@@ -541,10 +541,10 @@
             fContext->flush();
             if (useColorVerts) {
                 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
-                  SK_ARRAY_COUNT(gTextVertexWithColorAttribs));
+                    SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize);
             } else {
                 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
-                  SK_ARRAY_COUNT(gTextVertexAttribs));
+                    SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize);
             }
         }
         fMaxVertices = kDefaultRequestedVerts;
@@ -579,7 +579,7 @@
     size_t vertSize = useColorVerts ? (2 * sizeof(SkPoint) + sizeof(GrColor)) :
                                       (2 * sizeof(SkPoint));
 
-    SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexSize());
+    SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexStride());
 
     SkPoint* positions = reinterpret_cast<SkPoint*>(
         reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex);
@@ -594,6 +594,9 @@
                               SkFixedToFloat(texture->normalizeFixedY(ty + height)),
                               vertSize);
     if (useColorVerts) {
+        if (0xFF == GrColorUnpackA(fPaint.getColor())) {
+            fDrawTarget->drawState()->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
+        }
         // color comes after position.
         GrColor* colors = reinterpret_cast<GrColor*>(positions + 1);
         for (int i = 0; i < 4; ++i) {
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
index 836cc76..80abf68 100644
--- a/src/gpu/GrBitmapTextContext.h
+++ b/src/gpu/GrBitmapTextContext.h
@@ -10,8 +10,8 @@
 
 #include "GrTextContext.h"
 
+class GrGeometryProcessor;
 class GrTextStrike;
-class GrAtlasMgr;
 
 /*
  * This class implements GrTextContext using standard bitmap fonts
@@ -45,13 +45,14 @@
         kDefaultRequestedVerts   = kDefaultRequestedGlyphs * 4,
     };
 
-    void*                       fVertices;
-    int32_t                     fMaxVertices;
-    GrTexture*                  fCurrTexture;
-    SkAutoTUnref<GrEffectRef>   fCachedEffect;
-    uint32_t                    fEffectTextureGenID;
-    int                         fCurrVertex;
-    SkRect                      fVertexBounds;
+    void*                             fVertices;
+    int32_t                           fMaxVertices;
+    GrTexture*                        fCurrTexture;
+    SkAutoTUnref<GrGeometryProcessor> fCachedGeometryProcessor;
+    // Used to check whether fCachedEffect is still valid.
+    uint32_t                          fEffectTextureUniqueID;
+    int                               fCurrVertex;
+    SkRect                            fVertexBounds;
 };
 
 #endif
diff --git a/src/gpu/GrBlend.cpp b/src/gpu/GrBlend.cpp
index c8631c4..52e335e 100644
--- a/src/gpu/GrBlend.cpp
+++ b/src/gpu/GrBlend.cpp
@@ -59,7 +59,7 @@
                                    GrColor constantColor) {
 
     SkASSERT(!GrBlendCoeffRefsSrc(*srcCoeff));
-    SkASSERT(NULL != srcCoeff);
+    SkASSERT(srcCoeff);
 
     // Check whether srcCoeff can be reduced to kOne or kZero based on known color inputs.
     // We could pick out the coeff r,g,b,a values here and use them to compute the blend term color,
diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp
index 03d43c9..226f451 100644
--- a/src/gpu/GrBufferAllocPool.cpp
+++ b/src/gpu/GrBufferAllocPool.cpp
@@ -14,6 +14,8 @@
 #include "GrTypes.h"
 #include "GrVertexBuffer.h"
 
+#include "SkTraceEvent.h"
+
 #ifdef SK_DEBUG
     #define VALIDATE validate
 #else
@@ -23,6 +25,16 @@
 // page size
 #define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12)
 
+#define UNMAP_BUFFER(block)                                                               \
+do {                                                                                      \
+    TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),                           \
+                         "GrBufferAllocPool Unmapping Buffer",                            \
+                         TRACE_EVENT_SCOPE_THREAD,                                        \
+                         "percent_unwritten",                                             \
+                         (float)((block).fBytesFree) / (block).fBuffer->gpuMemorySize()); \
+    (block).fBuffer->unmap();                                                             \
+} while (false)
+
 GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
                                      BufferType bufferType,
                                      bool frequentResetHint,
@@ -30,7 +42,7 @@
                                      int preallocBufferCnt) :
         fBlocks(SkTMax(8, 2*preallocBufferCnt)) {
 
-    SkASSERT(NULL != gpu);
+    SkASSERT(gpu);
     fGpu = gpu;
     fGpu->ref();
     fGpuIsReffed = true;
@@ -46,7 +58,7 @@
     fPreallocBufferStartIdx = 0;
     for (int i = 0; i < preallocBufferCnt; ++i) {
         GrGeometryBuffer* buffer = this->createBuffer(fMinBlockSize);
-        if (NULL != buffer) {
+        if (buffer) {
             *fPreallocBuffers.append() = buffer;
         }
     }
@@ -57,7 +69,7 @@
     if (fBlocks.count()) {
         GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
         if (buffer->isMapped()) {
-            buffer->unmap();
+            UNMAP_BUFFER(fBlocks.back());
         }
     }
     while (!fBlocks.empty()) {
@@ -80,7 +92,7 @@
     if (fBlocks.count()) {
         GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
         if (buffer->isMapped()) {
-            buffer->unmap();
+            UNMAP_BUFFER(fBlocks.back());
         }
     }
     // fPreallocBuffersInUse will be decremented down to zero in the while loop
@@ -104,13 +116,13 @@
 void GrBufferAllocPool::unmap() {
     VALIDATE();
 
-    if (NULL != fBufferPtr) {
+    if (fBufferPtr) {
         BufferBlock& block = fBlocks.back();
         if (block.fBuffer->isMapped()) {
-            block.fBuffer->unmap();
+            UNMAP_BUFFER(block);
         } else {
             size_t flushSize = block.fBuffer->gpuMemorySize() - block.fBytesFree;
-            this->flushCpuData(fBlocks.back().fBuffer, flushSize);
+            this->flushCpuData(fBlocks.back(), flushSize);
         }
         fBufferPtr = NULL;
     }
@@ -119,7 +131,7 @@
 
 #ifdef SK_DEBUG
 void GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
-    if (NULL != fBufferPtr) {
+    if (fBufferPtr) {
         SkASSERT(!fBlocks.empty());
         if (fBlocks.back().fBuffer->isMapped()) {
             GrGeometryBuffer* buf = fBlocks.back().fBuffer;
@@ -156,10 +168,10 @@
                                    size_t* offset) {
     VALIDATE();
 
-    SkASSERT(NULL != buffer);
-    SkASSERT(NULL != offset);
+    SkASSERT(buffer);
+    SkASSERT(offset);
 
-    if (NULL != fBufferPtr) {
+    if (fBufferPtr) {
         BufferBlock& back = fBlocks.back();
         size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
         size_t pad = GrSizeAlignUpPad(usedBytes,
@@ -186,7 +198,7 @@
     if (!createBlock(size)) {
         return NULL;
     }
-    SkASSERT(NULL != fBufferPtr);
+    SkASSERT(fBufferPtr);
 
     *offset = 0;
     BufferBlock& back = fBlocks.back();
@@ -199,7 +211,7 @@
 
 int GrBufferAllocPool::currentBufferItems(size_t itemSize) const {
     VALIDATE();
-    if (NULL != fBufferPtr) {
+    if (fBufferPtr) {
         const BufferBlock& back = fBlocks.back();
         size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
         size_t pad = GrSizeAlignUpPad(usedBytes, itemSize);
@@ -238,7 +250,7 @@
             // if we locked a vb to satisfy the make space and we're releasing
             // beyond it, then unmap it.
             if (block.fBuffer->isMapped()) {
-                block.fBuffer->unmap();
+                UNMAP_BUFFER(block);
             }
             this->destroyBlock();
         } else {
@@ -283,14 +295,13 @@
     }
 
     block.fBytesFree = size;
-    if (NULL != fBufferPtr) {
+    if (fBufferPtr) {
         SkASSERT(fBlocks.count() > 1);
         BufferBlock& prev = fBlocks.fromBack(1);
         if (prev.fBuffer->isMapped()) {
-            prev.fBuffer->unmap();
+            UNMAP_BUFFER(prev);
         } else {
-            flushCpuData(prev.fBuffer,
-                         prev.fBuffer->gpuMemorySize() - prev.fBytesFree);
+            this->flushCpuData(prev, prev.fBuffer->gpuMemorySize() - prev.fBytesFree);
         }
         fBufferPtr = NULL;
     }
@@ -343,9 +354,9 @@
     fBufferPtr = NULL;
 }
 
-void GrBufferAllocPool::flushCpuData(GrGeometryBuffer* buffer,
-                                     size_t flushSize) {
-    SkASSERT(NULL != buffer);
+void GrBufferAllocPool::flushCpuData(const BufferBlock& block, size_t flushSize) {
+    GrGeometryBuffer* buffer = block.fBuffer;
+    SkASSERT(buffer);
     SkASSERT(!buffer->isMapped());
     SkASSERT(fCpuData.get() == fBufferPtr);
     SkASSERT(flushSize <= buffer->gpuMemorySize());
@@ -354,9 +365,9 @@
     if (GrDrawTargetCaps::kNone_MapFlags != fGpu->caps()->mapBufferFlags() &&
         flushSize > GR_GEOM_BUFFER_MAP_THRESHOLD) {
         void* data = buffer->map();
-        if (NULL != data) {
+        if (data) {
             memcpy(data, fBufferPtr, flushSize);
-            buffer->unmap();
+            UNMAP_BUFFER(block);
             return;
         }
     }
@@ -392,8 +403,8 @@
                                          int* startVertex) {
 
     SkASSERT(vertexCount >= 0);
-    SkASSERT(NULL != buffer);
-    SkASSERT(NULL != startVertex);
+    SkASSERT(buffer);
+    SkASSERT(startVertex);
 
     size_t offset = 0; // assign to suppress warning
     const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning
@@ -414,7 +425,7 @@
                                              const GrVertexBuffer** buffer,
                                              int* startVertex) {
     void* space = makeSpace(vertexSize, vertexCount, buffer, startVertex);
-    if (NULL != space) {
+    if (space) {
         memcpy(space,
                vertices,
                vertexSize * vertexCount);
@@ -450,8 +461,8 @@
                                         int* startIndex) {
 
     SkASSERT(indexCount >= 0);
-    SkASSERT(NULL != buffer);
-    SkASSERT(NULL != startIndex);
+    SkASSERT(buffer);
+    SkASSERT(startIndex);
 
     size_t offset = 0; // assign to suppress warning
     const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning
@@ -471,7 +482,7 @@
                                            const GrIndexBuffer** buffer,
                                            int* startIndex) {
     void* space = makeSpace(indexCount, buffer, startIndex);
-    if (NULL != space) {
+    if (space) {
         memcpy(space, indices, sizeof(uint16_t) * indexCount);
         return true;
     } else {
diff --git a/src/gpu/GrBufferAllocPool.h b/src/gpu/GrBufferAllocPool.h
index 291d781..e3d3982 100644
--- a/src/gpu/GrBufferAllocPool.h
+++ b/src/gpu/GrBufferAllocPool.h
@@ -155,7 +155,7 @@
 
     bool createBlock(size_t requestSize);
     void destroyBlock();
-    void flushCpuData(GrGeometryBuffer* buffer, size_t flushSize);
+    void flushCpuData(const BufferBlock& block, size_t flushSize);
 #ifdef SK_DEBUG
     void validate(bool unusedBlockAllowed = false) const;
 #endif
diff --git a/src/gpu/GrCacheable.cpp b/src/gpu/GrCacheable.cpp
deleted file mode 100644
index 120be78..0000000
--- a/src/gpu/GrCacheable.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * 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 "GrCacheable.h"
-
-uint32_t GrCacheable::getGenerationID() const {
-    static int32_t gPathRefGenerationID;
-    while (!fGenID) {
-        fGenID = static_cast<uint32_t>(sk_atomic_inc(&gPathRefGenerationID) + 1);
-    }
-    return fGenID;
-}
diff --git a/src/gpu/GrClipMaskCache.h b/src/gpu/GrClipMaskCache.h
index b332c7b..6b484e8 100644
--- a/src/gpu/GrClipMaskCache.h
+++ b/src/gpu/GrClipMaskCache.h
@@ -41,6 +41,7 @@
         // We could reuse the mask if bounds is a subset of last bounds. We'd have to communicate
         // an offset to the caller.
         if (back->fLastMask.texture() &&
+            !back->fLastMask.texture()->wasDestroyed() &&
             back->fLastBound == bounds &&
             back->fLastClipGenID == clipGenID) {
             return true;
@@ -179,8 +180,8 @@
         return fContext;
     }
 
-    void releaseResources() {
-
+    //  TODO: Remove this when we hold cache keys instead of refs to textures.
+    void purgeResources() {
         SkDeque::F2BIter iter(fStack);
         for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next();
                 frame != NULL;
@@ -219,7 +220,8 @@
 
         int32_t                 fLastClipGenID;
         // The mask's width & height values are used by GrClipMaskManager to correctly scale the
-        // texture coords for the geometry drawn with this mask.
+        // texture coords for the geometry drawn with this mask. TODO: This should be a cache key
+        // and not a hard ref to a texture.
         GrAutoScratchTexture    fLastMask;
         // fLastBound stores the bounding box of the clip mask in clip-stack space. This rect is
         // used by GrClipMaskManager to position a rect and compute texture coords for the mask.
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index a878894..3ecc922 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -51,7 +51,7 @@
 
     SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
     // This could be a long-lived effect that is cached with the alpha-mask.
-    drawState->addCoverageEffect(
+    drawState->addCoverageProcessor(
         GrTextureDomainEffect::Create(result,
                                       mat,
                                       GrTextureDomain::MakeTexelDomain(result, domainTexels),
@@ -114,7 +114,7 @@
 
     GrDrawState* drawState = fGpu->drawState();
     SkRect boundsInClipSpace;
-    if (NULL != drawBounds) {
+    if (drawBounds) {
         boundsInClipSpace = *drawBounds;
         boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
     }
@@ -126,7 +126,7 @@
     bool setARE = false;
     bool failed = false;
 
-    while (NULL != iter.get()) {
+    while (iter.get()) {
         SkRegion::Op op = iter.get()->getOp();
         bool invert;
         bool skip = false;
@@ -136,7 +136,7 @@
                 // Fallthrough, handled same as intersect.
             case SkRegion::kIntersect_Op:
                 invert = false;
-                if (NULL != drawBounds && iter.get()->contains(boundsInClipSpace)) {
+                if (drawBounds && iter.get()->contains(boundsInClipSpace)) {
                     skip = true;
                 }
                 break;
@@ -154,44 +154,46 @@
         }
 
         if (!skip) {
-            GrEffectEdgeType edgeType;
+            GrPrimitiveEdgeType edgeType;
             if (GR_AA_CLIP && iter.get()->isAA()) {
                 if (rt->isMultisampled()) {
                     // Coverage based AA clips don't place nicely with MSAA.
                     failed = true;
                     break;
                 }
-                edgeType = invert ? kInverseFillAA_GrEffectEdgeType : kFillAA_GrEffectEdgeType;
+                edgeType =
+                        invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_GrProcessorEdgeType;
             } else {
-                edgeType = invert ? kInverseFillBW_GrEffectEdgeType : kFillBW_GrEffectEdgeType;
+                edgeType =
+                        invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType;
             }
-            SkAutoTUnref<GrEffectRef> effect;
+            SkAutoTUnref<GrFragmentProcessor> fp;
             switch (iter.get()->getType()) {
                 case SkClipStack::Element::kPath_Type:
-                    effect.reset(GrConvexPolyEffect::Create(edgeType, iter.get()->getPath(),
+                    fp.reset(GrConvexPolyEffect::Create(edgeType, iter.get()->getPath(),
                         &clipToRTOffset));
                     break;
                 case SkClipStack::Element::kRRect_Type: {
                     SkRRect rrect = iter.get()->getRRect();
                     rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
-                    effect.reset(GrRRectEffect::Create(edgeType, rrect));
+                    fp.reset(GrRRectEffect::Create(edgeType, rrect));
                     break;
                 }
                 case SkClipStack::Element::kRect_Type: {
                     SkRect rect = iter.get()->getRect();
                     rect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
-                    effect.reset(GrConvexPolyEffect::Create(edgeType, rect));
+                    fp.reset(GrConvexPolyEffect::Create(edgeType, rect));
                     break;
                 }
                 default:
                     break;
             }
-            if (effect) {
+            if (fp) {
                 if (!setARE) {
                     are->set(fGpu->drawState());
                     setARE = true;
                 }
-                fGpu->drawState()->addCoverageEffect(effect);
+                fGpu->drawState()->addCoverageProcessor(fp);
             } else {
                 failed = true;
                 break;
@@ -225,7 +227,7 @@
 
     const GrRenderTarget* rt = drawState->getRenderTarget();
     // GrDrawTarget should have filtered this for us
-    SkASSERT(NULL != rt);
+    SkASSERT(rt);
 
     bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWideOpen();
 
@@ -299,7 +301,7 @@
                                                clipSpaceIBounds);
         }
 
-        if (NULL != result) {
+        if (result) {
             // The mask's top left coord should be pinned to the rounded-out top left corner of
             // clipSpace bounds. We determine the mask's position WRT to the render target here.
             SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
@@ -397,17 +399,16 @@
             SkDEBUGFAIL("Should never get here with an empty element.");
             break;
         case Element::kRect_Type:
-            // TODO: Do rects directly to the accumulator using a aa-rect GrEffect that covers the
-            // entire mask bounds and writes 0 outside the rect.
+            // TODO: Do rects directly to the accumulator using a aa-rect GrProcessor that covers
+            // the entire mask bounds and writes 0 outside the rect.
             if (element->isAA()) {
                 getContext()->getAARectRenderer()->fillAARect(fGpu,
                                                               fGpu,
                                                               element->getRect(),
                                                               SkMatrix::I(),
-                                                              element->getRect(),
-                                                              false);
+                                                              element->getRect());
             } else {
-                fGpu->drawSimpleRect(element->getRect(), NULL);
+                fGpu->drawSimpleRect(element->getRect());
             }
             return true;
         default: {
@@ -454,7 +455,7 @@
             GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
             GrPathRendererChain::kStencilAndColor_DrawType;
         *pr = this->getContext()->getPathRenderer(path, stroke, fGpu, false, type);
-        return NULL != *pr;
+        return SkToBool(*pr);
     }
 }
 
@@ -475,19 +476,19 @@
     SkMatrix sampleM;
     sampleM.setIDiv(srcMask->width(), srcMask->height());
 
-    drawState->addColorEffect(
+    drawState->addColorProcessor(
         GrTextureDomainEffect::Create(srcMask,
                                       sampleM,
                                       GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
                                       GrTextureDomain::kDecal_Mode,
                                       GrTextureParams::kNone_FilterMode))->unref();
-    fGpu->drawSimpleRect(SkRect::Make(dstBound), NULL);
+    fGpu->drawSimpleRect(SkRect::Make(dstBound));
 }
 
 // get a texture to act as a temporary buffer for AA clip boolean operations
 // TODO: given the expense of createTexture we may want to just cache this too
 void GrClipMaskManager::getTemp(int width, int height, GrAutoScratchTexture* temp) {
-    if (NULL != temp->texture()) {
+    if (temp->texture()) {
         // we've already allocated the temp texture
         return;
     }
@@ -547,7 +548,7 @@
 
     // First, check for cached texture
     GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBounds);
-    if (NULL != result) {
+    if (result) {
         fCurrClipMaskType = kAlpha_ClipMaskType;
         return result;
     }
@@ -702,7 +703,7 @@
     SkASSERT(drawState->isClipState());
 
     GrRenderTarget* rt = drawState->getRenderTarget();
-    SkASSERT(NULL != rt);
+    SkASSERT(rt);
 
     // TODO: dynamically attach a SB when needed.
     GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
@@ -740,11 +741,11 @@
         SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
         clipBit = (1 << (clipBit-1));
 
-        fGpu->clearStencilClip(stencilSpaceIBounds, kAllIn_InitialState == initialState);
+        fGpu->clearStencilClip(rt, stencilSpaceIBounds, kAllIn_InitialState == initialState);
 
         // walk through each clip element and perform its set op
         // with the existing clip.
-        for (ElementList::Iter iter(elements.headIter()); NULL != iter.get(); iter.next()) {
+        for (ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
             const Element* element = iter.get();
             bool fillInverted = false;
             // enabled at bottom of loop
@@ -812,7 +813,7 @@
                 SET_RANDOM_COLOR
                 if (Element::kRect_Type == element->getType()) {
                     *drawState->stencil() = gDrawToStencil;
-                    fGpu->drawSimpleRect(element->getRect(), NULL);
+                    fGpu->drawSimpleRect(element->getRect());
                 } else {
                     if (!clipPath.isEmpty()) {
                         if (canRenderDirectToStencil) {
@@ -833,7 +834,7 @@
                 if (canDrawDirectToClip) {
                     if (Element::kRect_Type == element->getType()) {
                         SET_RANDOM_COLOR
-                        fGpu->drawSimpleRect(element->getRect(), NULL);
+                        fGpu->drawSimpleRect(element->getRect());
                     } else {
                         SET_RANDOM_COLOR
                         pr->drawPath(clipPath, stroke, fGpu, false);
@@ -842,7 +843,7 @@
                     SET_RANDOM_COLOR
                     // The view matrix is setup to do clip space -> stencil space translation, so
                     // draw rect in clip space.
-                    fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds), NULL);
+                    fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds));
                 }
             }
         }
@@ -947,7 +948,7 @@
     int stencilBits = 0;
     GrStencilBuffer* stencilBuffer =
         drawState.getRenderTarget()->getStencilBuffer();
-    if (NULL != stencilBuffer) {
+    if (stencilBuffer) {
         stencilBits = stencilBuffer->bits();
     }
 
@@ -1046,7 +1047,7 @@
     SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
 
     GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBounds);
-    if (NULL != result) {
+    if (result) {
         return result;
     }
 
@@ -1059,13 +1060,13 @@
     SkMatrix matrix;
     matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft),
                         SkIntToScalar(-clipSpaceIBounds.fTop));
-    helper.init(maskSpaceIBounds, &matrix);
+    helper.init(maskSpaceIBounds, &matrix, false);
 
     helper.clear(kAllIn_InitialState == initialState ? 0xFF : 0x00);
 
     SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
 
-    for (ElementList::Iter iter(elements.headIter()) ; NULL != iter.get(); iter.next()) {
+    for (ElementList::Iter iter(elements.headIter()) ; iter.get(); iter.next()) {
 
         const Element* element = iter.get();
         SkRegion::Op op = element->getOp();
@@ -1113,8 +1114,8 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void GrClipMaskManager::releaseResources() {
-    fAACache.releaseResources();
+void GrClipMaskManager::purgeResources() {
+    fAACache.purgeResources();
 }
 
 void GrClipMaskManager::setGpu(GrGpu* gpu) {
@@ -1141,7 +1142,7 @@
     int stencilBits = 0;
     GrStencilBuffer* stencilBuffer =
         drawState.getRenderTarget()->getStencilBuffer();
-    if (NULL != stencilBuffer) {
+    if (stencilBuffer) {
         stencilBits = stencilBuffer->bits();
         this->adjustStencilParams(settings, clipMode, stencilBits);
     }
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index c3a21fd..ea16fc8 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -53,7 +53,11 @@
     bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*,
                        const SkRect* devBounds);
 
-    void releaseResources();
+    /**
+     * Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs
+     * which will allow ResourceCache2 to automatically purge anything this class has created.
+     */
+    void purgeResources();
 
     bool isClipInStencil() const {
         return kStencil_ClipMaskType == fCurrClipMaskType;
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
old mode 100644
new mode 100755
index 6c90c17..ad1b4c4
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -16,6 +16,7 @@
 #include "GrAARectRenderer.h"
 #include "GrBufferAllocPool.h"
 #include "GrGpu.h"
+#include "GrDistanceFieldTextContext.h"
 #include "GrDrawTargetCaps.h"
 #include "GrIndexBuffer.h"
 #include "GrInOrderDrawBuffer.h"
@@ -24,8 +25,10 @@
 #include "GrPathRenderer.h"
 #include "GrPathUtils.h"
 #include "GrResourceCache.h"
+#include "GrResourceCache2.h"
 #include "GrSoftwarePathRenderer.h"
 #include "GrStencilBuffer.h"
+#include "GrStencilAndCoverTextContext.h"
 #include "GrStrokeInfo.h"
 #include "GrTextStrike.h"
 #include "GrTraceMarker.h"
@@ -70,7 +73,7 @@
 
 class GrContext::AutoCheckFlush {
 public:
-    AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(NULL != context); }
+    AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); }
 
     ~AutoCheckFlush() {
         if (fContext->fFlushToReduceCacheSize) {
@@ -82,8 +85,15 @@
     GrContext* fContext;
 };
 
-GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) {
-    GrContext* context = SkNEW(GrContext);
+GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext,
+                             const Options* opts) {
+    GrContext* context;
+    if (NULL == opts) {
+        context = SkNEW_ARGS(GrContext, (Options()));
+    } else {
+        context = SkNEW_ARGS(GrContext, (*opts));
+    }
+
     if (context->init(backend, backendContext)) {
         return context;
     } else {
@@ -92,13 +102,14 @@
     }
 }
 
-GrContext::GrContext() {
+GrContext::GrContext(const Options& opts) : fOptions(opts) {
     fDrawState = NULL;
     fGpu = NULL;
     fClip = NULL;
     fPathRendererChain = NULL;
     fSoftwarePathRenderer = NULL;
     fResourceCache = NULL;
+    fResourceCache2 = NULL;
     fFontCache = NULL;
     fDrawBuffer = NULL;
     fDrawBufferVBAllocPool = NULL;
@@ -108,7 +119,6 @@
     fOvalRenderer = NULL;
     fViewMatrix.reset();
     fMaxTextureSizeOverride = 1 << 20;
-    fGpuTracingEnabled = false;
 }
 
 bool GrContext::init(GrBackend backend, GrBackendContext backendContext) {
@@ -125,10 +135,11 @@
     fResourceCache = SkNEW_ARGS(GrResourceCache, (MAX_RESOURCE_CACHE_COUNT,
                                                   MAX_RESOURCE_CACHE_BYTES));
     fResourceCache->setOverbudgetCallback(OverbudgetCB, this);
+    fResourceCache2 = SkNEW(GrResourceCache2);
 
     fFontCache = SkNEW_ARGS(GrFontCache, (fGpu));
 
-    fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (fGpu)));
+    fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this)));
 
     fLastDrawWasBuffered = kNo_BufferedDraw;
 
@@ -153,10 +164,8 @@
         (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
     }
 
-    // Since the gpu can hold scratch textures, give it a chance to let go
-    // of them before freeing the texture cache
-    fGpu->purgeResources();
-
+    delete fResourceCache2;
+    fResourceCache2 = NULL;
     delete fResourceCache;
     fResourceCache = NULL;
     delete fFontCache;
@@ -173,15 +182,12 @@
     fDrawState->unref();
 }
 
-void GrContext::contextLost() {
-    this->contextDestroyed();
-    this->setupDrawBuffer();
-}
-
-void GrContext::contextDestroyed() {
+void GrContext::abandonContext() {
     // abandon first to so destructors
     // don't try to free the resources in the API.
-    fGpu->abandonResources();
+    fResourceCache2->abandonAll();
+
+    fGpu->contextAbandoned();
 
     // a path renderer may be holding onto resources that
     // are now unusable
@@ -204,7 +210,6 @@
 
     fFontCache->freeAll();
     fLayerCache->freeAll();
-    fGpu->markContextDirty();
 }
 
 void GrContext::resetContext(uint32_t state) {
@@ -215,6 +220,9 @@
     this->flush();
 
     fGpu->purgeResources();
+    if (fDrawBuffer) {
+        fDrawBuffer->purgeResources();
+    }
 
     fAARectRenderer->reset();
     fOvalRenderer->reset();
@@ -228,21 +236,34 @@
 }
 
 void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
-  if (NULL != resourceCount) {
+  if (resourceCount) {
     *resourceCount = fResourceCache->getCachedResourceCount();
   }
-  if (NULL != resourceBytes) {
+  if (resourceBytes) {
     *resourceBytes = fResourceCache->getCachedResourceBytes();
   }
 }
 
+GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget,
+                                            const SkDeviceProperties&
+                                            leakyProperties,
+                                            bool enableDistanceFieldFonts) {
+    if (fGpu->caps()->pathRenderingSupport()) {
+        if (renderTarget->getStencilBuffer() && renderTarget->isMultisampled()) {
+            return SkNEW_ARGS(GrStencilAndCoverTextContext, (this, leakyProperties));
+        }
+    }
+    return SkNEW_ARGS(GrDistanceFieldTextContext, (this, leakyProperties,
+                                                   enableDistanceFieldFonts));
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 GrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc,
                                         const GrCacheID& cacheID,
                                         const GrTextureParams* params) {
     GrResourceKey resourceKey = GrTextureImpl::ComputeKey(fGpu, params, desc, cacheID);
-    GrCacheable* resource = fResourceCache->find(resourceKey);
+    GrGpuResource* resource = fResourceCache->find(resourceKey);
     SkSafeRef(resource);
     return static_cast<GrTexture*>(resource);
 }
@@ -268,7 +289,7 @@
     GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width,
                                                             height,
                                                             sampleCnt);
-    GrCacheable* resource = fResourceCache->find(resourceKey);
+    GrGpuResource* resource = fResourceCache->find(resourceKey);
     return static_cast<GrStencilBuffer*>(resource);
 }
 
@@ -332,7 +353,7 @@
 
     GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
 
-    if (NULL != texture) {
+    if (texture) {
         GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
         GrDrawState* drawState = fGpu->drawState();
         drawState->setRenderTarget(texture->asRenderTarget());
@@ -342,9 +363,10 @@
         // the original.
         GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTextureParams::kBilerp_FilterMode :
                                                                    GrTextureParams::kNone_FilterMode);
-        drawState->addColorTextureEffect(clampedTexture, SkMatrix::I(), params);
+        drawState->addColorTextureProcessor(clampedTexture, SkMatrix::I(), params);
 
-        drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttribs));
+        drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttribs),
+                                                    2 * sizeof(SkPoint));
 
         GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0);
 
@@ -369,14 +391,14 @@
         SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig));
 
         size_t bpp = GrBytesPerPixel(desc.fConfig);
-        SkAutoSMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHeight);
+        GrAutoMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHeight);
         stretch_image(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight,
                       srcData, desc.fWidth, desc.fHeight, bpp);
 
         size_t stretchedRowBytes = rtDesc.fWidth * bpp;
 
         texture = fGpu->createTexture(rtDesc, stretchedPixels.get(), stretchedRowBytes);
-        SkASSERT(NULL != texture);
+        SkASSERT(texture);
     }
 
     return texture;
@@ -402,13 +424,13 @@
         texture = fGpu->createTexture(desc, srcData, rowBytes);
     }
 
-    if (NULL != texture) {
+    if (texture) {
         // Adding a resource could put us overbudget. Try to free up the
         // necessary space before adding it.
         fResourceCache->purgeAsNeeded(1, texture->gpuMemorySize());
         fResourceCache->addResource(resourceKey, texture);
 
-        if (NULL != cacheKey) {
+        if (cacheKey) {
             *cacheKey = resourceKey;
         }
     }
@@ -420,7 +442,7 @@
                                          GrResourceCache* resourceCache,
                                          const GrTextureDesc& desc) {
     GrTexture* texture = gpu->createTexture(desc, NULL, 0);
-    if (NULL != texture) {
+    if (texture) {
         GrResourceKey key = GrTextureImpl::ComputeScratchKey(texture->desc());
         // Adding a resource could put us overbudget. Try to free up the
         // necessary space before adding it.
@@ -456,7 +478,7 @@
         desc.fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc.fHeight));
     }
 
-    GrCacheable* resource = NULL;
+    GrGpuResource* resource = NULL;
     int origWidth = desc.fWidth;
     int origHeight = desc.fHeight;
 
@@ -464,7 +486,7 @@
         GrResourceKey key = GrTextureImpl::ComputeScratchKey(desc);
         // Ensure we have exclusive access to the texture so future 'find' calls don't return it
         resource = fResourceCache->find(key, GrResourceCache::kHide_OwnershipFlag);
-        if (NULL != resource) {
+        if (resource) {
             resource->ref();
             break;
         }
@@ -502,51 +524,56 @@
 
     // This texture should already have a cache entry since it was once
     // attached
-    SkASSERT(NULL != texture->getCacheEntry());
+    SkASSERT(texture->getCacheEntry());
 
     // Conceptually, the cache entry is going to assume responsibility
     // for the creation ref. Assert refcnt == 1.
-    SkASSERT(texture->unique());
+    // Except that this also gets called when the texture is prematurely
+    // abandoned. In that case the ref count may be > 1.
+    // SkASSERT(texture->unique());
 
-    if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) {
+    if (fGpu->caps()->reuseScratchTextures() || texture->asRenderTarget()) {
         // Since this texture came from an AutoScratchTexture it should
         // still be in the exclusive pile. Recycle it.
         fResourceCache->makeNonExclusive(texture->getCacheEntry());
         this->purgeCache();
-    } else if (texture->getDeferredRefCount() <= 0) {
+    } else {
         // When we aren't reusing textures we know this scratch texture
         // will never be reused and would be just wasting time in the cache
         fResourceCache->makeNonExclusive(texture->getCacheEntry());
         fResourceCache->deleteResource(texture->getCacheEntry());
-    } else {
-        // In this case (fDeferredRefCount > 0) but the cache is the only
-        // one holding a real ref. Mark the object so when the deferred
-        // ref count goes to 0 the texture will be deleted (remember
-        // in this code path scratch textures aren't getting reused).
-        texture->setNeedsDeferredUnref();
     }
 }
 
-
 void GrContext::unlockScratchTexture(GrTexture* texture) {
+    if (texture->wasDestroyed()) {
+        if (texture->getCacheEntry()->key().isScratch()) {
+            // This texture was detached from the cache but the cache still had a ref to it but
+            // not a pointer to it. This will unref the texture and delete its resource cache
+            // entry.
+            delete texture->getCacheEntry();
+        }
+        return;
+    }
+
     ASSERT_OWNED_RESOURCE(texture);
-    SkASSERT(NULL != texture->getCacheEntry());
+    SkASSERT(texture->getCacheEntry());
 
     // If this is a scratch texture we detached it from the cache
     // while it was locked (to avoid two callers simultaneously getting
     // the same texture).
     if (texture->getCacheEntry()->key().isScratch()) {
-        if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) {
+        if (fGpu->caps()->reuseScratchTextures() || texture->asRenderTarget()) {
             fResourceCache->makeNonExclusive(texture->getCacheEntry());
             this->purgeCache();
-        } else if (texture->unique() && texture->getDeferredRefCount() <= 0) {
+        } else if (texture->unique()) {
             // Only the cache now knows about this texture. Since we're never
             // reusing scratch textures (in this code path) it would just be
             // wasting time sitting in the cache.
             fResourceCache->makeNonExclusive(texture->getCacheEntry());
             fResourceCache->deleteResource(texture->getCacheEntry());
         } else {
-            // In this case (fRefCnt > 1 || defRefCnt > 0) but we don't really
+            // In this case (there is still a non-cache ref) but we don't really
             // want to readd it to the cache (since it will never be reused).
             // Instead, give up the cache's ref and leave the decision up to
             // addExistingTextureToCache once its ref count reaches 0. For
@@ -559,13 +586,13 @@
 }
 
 void GrContext::purgeCache() {
-    if (NULL != fResourceCache) {
+    if (fResourceCache) {
         fResourceCache->purgeAsNeeded();
     }
 }
 
 bool GrContext::OverbudgetCB(void* data) {
-    SkASSERT(NULL != data);
+    SkASSERT(data);
 
     GrContext* context = reinterpret_cast<GrContext*>(data);
 
@@ -625,7 +652,7 @@
     bool isPow2 = SkIsPow2(width) && SkIsPow2(height);
 
     if (!isPow2) {
-        bool tiled = NULL != params && params->isTiled();
+        bool tiled = params && params->isTiled();
         if (tiled && !caps->npotTextureTileSupport()) {
             return false;
         }
@@ -639,11 +666,16 @@
 void GrContext::clear(const SkIRect* rect,
                       const GrColor color,
                       bool canIgnoreRect,
-                      GrRenderTarget* target) {
+                      GrRenderTarget* renderTarget) {
+    ASSERT_OWNED_RESOURCE(renderTarget);
     AutoRestoreEffects are;
     AutoCheckFlush acf(this);
-    this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf)->clear(rect, color,
-                                                                canIgnoreRect, target);
+    GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this);
+    GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf);
+    if (NULL == target) {
+        return;
+    }
+    target->clear(rect, color, canIgnoreRect, renderTarget);
 }
 
 void GrContext::drawPaint(const GrPaint& origPaint) {
@@ -656,6 +688,7 @@
     SkMatrix inverse;
     SkTCopyOnFirstWrite<GrPaint> paint(origPaint);
     AutoMatrix am;
+    GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::drawPaint", this);
 
     // We attempt to map r by the inverse matrix and draw that. mapRect will
     // map the four corners and bound them with a new rect. This will not
@@ -709,45 +742,28 @@
     verts[9] = verts[1];
 }
 
-static bool isIRect(const SkRect& r) {
-    return SkScalarIsInt(r.fLeft)  && SkScalarIsInt(r.fTop) &&
-           SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom);
+static inline bool is_irect(const SkRect& r) {
+  return SkScalarIsInt(r.fLeft)  && SkScalarIsInt(r.fTop) &&	
+         SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom);	
 }
 
 static bool apply_aa_to_rect(GrDrawTarget* target,
                              const SkRect& rect,
                              SkScalar strokeWidth,
                              const SkMatrix& combinedMatrix,
-                             SkRect* devBoundRect,
-                             bool* useVertexCoverage) {
-    // we use a simple coverage ramp to do aa on axis-aligned rects
-    // we check if the rect will be axis-aligned, and the rect won't land on
-    // integer coords.
-
-    // we are keeping around the "tweak the alpha" trick because
-    // it is our only hope for the fixed-pipe implementation.
-    // In a shader implementation we can give a separate coverage input
-    // TODO: remove this ugliness when we drop the fixed-pipe impl
-    *useVertexCoverage = false;
-    if (!target->getDrawState().canTweakAlphaForCoverage()) {
-        if (target->shouldDisableCoverageAAForBlend()) {
+                             SkRect* devBoundRect) {
+    if (!target->getDrawState().canTweakAlphaForCoverage() &&
+        target->shouldDisableCoverageAAForBlend()) {
 #ifdef SK_DEBUG
-            //GrPrintf("Turning off AA to correctly apply blend.\n");
+        //GrPrintf("Turning off AA to correctly apply blend.\n");
 #endif
-            return false;
-        } else {
-            *useVertexCoverage = true;
-        }
+        return false;
     }
     const GrDrawState& drawState = target->getDrawState();
     if (drawState.getRenderTarget()->isMultisampled()) {
         return false;
     }
 
-    if (0 == strokeWidth && target->willUseHWAALines()) {
-        return false;
-    }
-
 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
     if (strokeWidth >= 0) {
 #endif
@@ -764,12 +780,11 @@
 #endif
 
     combinedMatrix.mapRect(devBoundRect, rect);
-
     if (strokeWidth < 0) {
-        return !isIRect(*devBoundRect);
-    } else {
-        return true;
+        return !is_irect(*devBoundRect);
     }
+
+    return true;
 }
 
 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) {
@@ -779,9 +794,8 @@
 
 void GrContext::drawRect(const GrPaint& paint,
                          const SkRect& rect,
-                         const GrStrokeInfo* strokeInfo,
-                         const SkMatrix* matrix) {
-    if (NULL != strokeInfo && strokeInfo->isDashed()) {
+                         const GrStrokeInfo* strokeInfo) {
+    if (strokeInfo && strokeInfo->isDashed()) {
         SkPath path;
         path.addRect(rect);
         this->drawPath(paint, path, *strokeInfo);
@@ -791,14 +805,13 @@
     AutoRestoreEffects are;
     AutoCheckFlush acf(this);
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
+    if (NULL == target) {
+        return;
+    }
 
     GR_CREATE_TRACE_MARKER("GrContext::drawRect", target);
-
     SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWidth();
-    SkMatrix combinedMatrix = target->drawState()->getViewMatrix();
-    if (NULL != matrix) {
-        combinedMatrix.preConcat(*matrix);
-    }
+    SkMatrix matrix = target->drawState()->getViewMatrix();
 
     // Check if this is a full RT draw and can be replaced with a clear. We don't bother checking
     // cases where the RT is fully inside a stroke.
@@ -807,7 +820,7 @@
         target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect);
         SkRect clipSpaceRTRect = rtRect;
         bool checkClip = false;
-        if (NULL != this->getClip()) {
+        if (this->getClip()) {
             checkClip = true;
             clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX),
                                    SkIntToScalar(this->getClip()->fOrigin.fY));
@@ -815,7 +828,7 @@
         // Does the clip contain the entire RT?
         if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpaceRTRect)) {
             SkMatrix invM;
-            if (!combinedMatrix.invert(&invM)) {
+            if (!matrix.invert(&invM)) {
                 return;
             }
             // Does the rect bound the RT?
@@ -836,11 +849,9 @@
     }
 
     SkRect devBoundRect;
-    bool useVertexCoverage;
     bool needAA = paint.isAntiAlias() &&
                   !target->getDrawState().getRenderTarget()->isMultisampled();
-    bool doAA = needAA && apply_aa_to_rect(target, rect, width, combinedMatrix, &devBoundRect,
-                                           &useVertexCoverage);
+    bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, &devBoundRect);
 
     const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec();
 
@@ -851,13 +862,12 @@
         }
         if (width >= 0) {
             fAARectRenderer->strokeAARect(this->getGpu(), target, rect,
-                                          combinedMatrix, devBoundRect,
-                                          strokeRec, useVertexCoverage);
+                                          matrix, devBoundRect,
+                                          strokeRec);
         } else {
             // filled AA rect
             fAARectRenderer->fillAARect(this->getGpu(), target,
-                                        rect, combinedMatrix, devBoundRect,
-                                        useVertexCoverage);
+                                        rect, matrix, devBoundRect);
         }
         return;
     }
@@ -895,31 +905,27 @@
             vertex[4].set(rect.fLeft, rect.fTop);
         }
 
-        GrDrawState::AutoViewMatrixRestore avmr;
-        if (NULL != matrix) {
-            GrDrawState* drawState = target->drawState();
-            avmr.set(drawState, *matrix);
-        }
-
         target->drawNonIndexed(primType, 0, vertCount);
     } else {
         // filled BW rect
-        target->drawSimpleRect(rect, matrix);
+        target->drawSimpleRect(rect);
     }
 }
 
 void GrContext::drawRectToRect(const GrPaint& paint,
                                const SkRect& dstRect,
                                const SkRect& localRect,
-                               const SkMatrix* dstMatrix,
                                const SkMatrix* localMatrix) {
     AutoRestoreEffects are;
     AutoCheckFlush acf(this);
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
+    if (NULL == target) {
+        return;
+    }
 
     GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target);
 
-    target->drawRect(dstRect, dstMatrix, &localRect, localMatrix);
+    target->drawRect(dstRect, &localRect, localMatrix);
 }
 
 namespace {
@@ -930,11 +936,17 @@
     {kVec4ub_GrVertexAttribType, 2*sizeof(SkPoint), kColor_GrVertexAttribBinding}
 };
 
+static const size_t kPosUVAttribsSize = 2 * sizeof(SkPoint);
+static const size_t kPosUVColorAttribsSize = 2 * sizeof(SkPoint) + sizeof(GrColor);
+
 extern const GrVertexAttrib gPosColorAttribs[] = {
     {kVec2f_GrVertexAttribType,  0, kPosition_GrVertexAttribBinding},
     {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding},
 };
 
+static const size_t kPosAttribsSize = sizeof(SkPoint);
+static const size_t kPosColorAttribsSize = sizeof(SkPoint) + sizeof(GrColor);
+
 static void set_vertex_attributes(GrDrawState* drawState,
                                   const SkPoint* texCoords,
                                   const GrColor* colors,
@@ -943,18 +955,18 @@
     *texOffset = -1;
     *colorOffset = -1;
 
-    if (NULL != texCoords && NULL != colors) {
+    if (texCoords && colors) {
         *texOffset = sizeof(SkPoint);
         *colorOffset = 2*sizeof(SkPoint);
-        drawState->setVertexAttribs<gPosUVColorAttribs>(3);
-    } else if (NULL != texCoords) {
+        drawState->setVertexAttribs<gPosUVColorAttribs>(3, kPosUVColorAttribsSize);
+    } else if (texCoords) {
         *texOffset = sizeof(SkPoint);
-        drawState->setVertexAttribs<gPosUVColorAttribs>(2);
-    } else if (NULL != colors) {
+        drawState->setVertexAttribs<gPosUVColorAttribs>(2, kPosUVAttribsSize);
+    } else if (colors) {
         *colorOffset = sizeof(SkPoint);
-        drawState->setVertexAttribs<gPosColorAttribs>(2);
+        drawState->setVertexAttribs<gPosColorAttribs>(2, kPosColorAttribsSize);
     } else {
-        drawState->setVertexAttribs<gPosColorAttribs>(1);
+        drawState->setVertexAttribs<gPosColorAttribs>(1, kPosAttribsSize);
     }
 }
 
@@ -973,6 +985,9 @@
     GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope
 
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
+    if (NULL == target) {
+        return;
+    }
     GrDrawState* drawState = target->drawState();
 
     GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target);
@@ -980,8 +995,8 @@
     int colorOffset = -1, texOffset = -1;
     set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset);
 
-    size_t vertexSize = drawState->getVertexSize();
-    if (sizeof(SkPoint) != vertexSize) {
+    size_t VertexStride = drawState->getVertexStride();
+    if (sizeof(SkPoint) != VertexStride) {
         if (!geo.set(target, vertexCount, 0)) {
             GrPrintf("Failed to get space for vertices!\n");
             return;
@@ -997,7 +1012,7 @@
             if (colorOffset >= 0) {
                 *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
             }
-            curVertex = (void*)((intptr_t)curVertex + vertexSize);
+            curVertex = (void*)((intptr_t)curVertex + VertexStride);
         }
     } else {
         target->setVertexSourceToArray(positions, vertexCount);
@@ -1006,7 +1021,7 @@
     // we don't currently apply offscreen AA to this path. Need improved
     // management of GrDrawTarget's geometry to avoid copying points per-tile.
 
-    if (NULL != indices) {
+    if (indices) {
         target->setIndexSourceToArray(indices, indexCount);
         target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
         target->resetIndexSource();
@@ -1034,6 +1049,9 @@
     AutoRestoreEffects are;
     AutoCheckFlush acf(this);
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
+    if (NULL == target) {
+        return;
+    }
 
     GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target);
 
@@ -1091,6 +1109,9 @@
     AutoRestoreEffects are;
     AutoCheckFlush acf(this);
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
+    if (NULL == target) {
+        return;
+    }
 
     GR_CREATE_TRACE_MARKER("GrContext::drawOval", target);
 
@@ -1108,8 +1129,7 @@
 static bool is_nested_rects(GrDrawTarget* target,
                             const SkPath& path,
                             const SkStrokeRec& stroke,
-                            SkRect rects[2],
-                            bool* useVertexCoverage) {
+                            SkRect rects[2]) {
     SkASSERT(stroke.isFillStyle());
 
     if (path.isInverseFillType()) {
@@ -1124,13 +1144,9 @@
         return false;
     }
 
-    *useVertexCoverage = false;
-    if (!target->getDrawState().canTweakAlphaForCoverage()) {
-        if (target->shouldDisableCoverageAAForBlend()) {
-            return false;
-        } else {
-            *useVertexCoverage = true;
-        }
+    if (!target->getDrawState().canTweakAlphaForCoverage() &&
+        target->shouldDisableCoverageAAForBlend()) {
+        return false;
     }
 
     SkPath::Direction dirs[2];
@@ -1174,6 +1190,9 @@
             AutoRestoreEffects are;
             AutoCheckFlush acf(this);
             GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
+            if (NULL == target) {
+                return;
+            }
             GrDrawState* drawState = target->drawState();
 
             SkMatrix origViewMatrix = drawState->getViewMatrix();
@@ -1208,9 +1227,12 @@
     AutoRestoreEffects are;
     AutoCheckFlush acf(this);
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
+    if (NULL == target) {
+        return;
+    }
     GrDrawState* drawState = target->drawState();
 
-    GR_CREATE_TRACE_MARKER("GrContext::drawPath", target);
+    GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isConvex());
 
     const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
 
@@ -1218,20 +1240,16 @@
 
     if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) {
         // Concave AA paths are expensive - try to avoid them for special cases
-        bool useVertexCoverage;
         SkRect rects[2];
 
-        if (is_nested_rects(target, path, strokeRec, rects, &useVertexCoverage)) {
+        if (is_nested_rects(target, path, strokeRec, rects)) {
             SkMatrix origViewMatrix = drawState->getViewMatrix();
             GrDrawState::AutoViewMatrixRestore avmr;
             if (!avmr.setIdentity(target->drawState())) {
                 return;
             }
 
-            fAARectRenderer->fillAANestedRects(this->getGpu(), target,
-                                               rects,
-                                               origViewMatrix,
-                                               useVertexCoverage);
+            fAARectRenderer->fillAANestedRects(this->getGpu(), target, rects, origViewMatrix);
             return;
         }
     }
@@ -1320,7 +1338,7 @@
     ASSERT_OWNED_RESOURCE(texture);
 
     if ((kUnpremul_PixelOpsFlag & flags) || !fGpu->canWriteTexturePixels(texture, config)) {
-        if (NULL != texture->asRenderTarget()) {
+        if (texture->asRenderTarget()) {
             return this->writeRenderTargetPixels(texture->asRenderTarget(),
                                                  left, top, width, height,
                                                  config, buffer, rowBytes, flags);
@@ -1329,7 +1347,7 @@
         }
     }
 
-    if (!(kDontFlush_PixelOpsFlag & flags)) {
+    if (!(kDontFlush_PixelOpsFlag & flags) && texture->hasPendingIO()) {
         this->flush();
     }
 
@@ -1344,7 +1362,7 @@
     ASSERT_OWNED_RESOURCE(texture);
 
     GrRenderTarget* target = texture->asRenderTarget();
-    if (NULL != target) {
+    if (target) {
         return this->readRenderTargetPixels(target,
                                             left, top, width, height,
                                             config, buffer, rowBytes,
@@ -1363,7 +1381,7 @@
         desc.fOrigin = kTopLeft_GrSurfaceOrigin;
         ast.set(this, desc, kExact_ScratchTexMatch);
         GrTexture* dst = ast.texture();
-        if (NULL != dst && NULL != (target = dst->asRenderTarget())) {
+        if (dst && (target = dst->asRenderTarget())) {
             this->copyTexture(texture, target, NULL);
             return this->readRenderTargetPixels(target,
                                                 left, top, width, height,
@@ -1400,7 +1418,7 @@
         }
     }
 
-    if (!(kDontFlush_PixelOpsFlag & flags)) {
+    if (!(kDontFlush_PixelOpsFlag & flags) && target->hasPendingWrite()) {
         this->flush();
     }
 
@@ -1437,7 +1455,7 @@
     // on the read back pixels.
     GrTexture* src = target->asTexture();
     GrAutoScratchTexture ast;
-    if (NULL != src && (swapRAndB || unpremul || flipY)) {
+    if (src && (swapRAndB || unpremul || flipY)) {
         // Make the scratch a render target because we don't have a robust readTexturePixels as of
         // yet. It calls this function.
         GrTextureDesc desc;
@@ -1467,22 +1485,20 @@
             textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top);
             textureMatrix.postIDiv(src->width(), src->height());
 
-            SkAutoTUnref<const GrEffectRef> effect;
+            SkAutoTUnref<const GrFragmentProcessor> fp;
             if (unpremul) {
-                effect.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix));
-                if (NULL != effect) {
+                fp.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix));
+                if (fp) {
                     unpremul = false; // we no longer need to do this on CPU after the read back.
                 }
             }
             // If we failed to create a PM->UPM effect and have no other conversions to perform then
             // there is no longer any point to using the scratch.
-            if (NULL != effect || flipY || swapRAndB) {
-                if (!effect) {
-                    effect.reset(GrConfigConversionEffect::Create(
-                                                    src,
-                                                    swapRAndB,
-                                                    GrConfigConversionEffect::kNone_PMConversion,
-                                                    textureMatrix));
+            if (fp || flipY || swapRAndB) {
+                if (!fp) {
+                    fp.reset(GrConfigConversionEffect::Create(
+                            src, swapRAndB, GrConfigConversionEffect::kNone_PMConversion,
+                            textureMatrix));
                 }
                 swapRAndB = false; // we will handle the swap in the draw.
 
@@ -1491,12 +1507,12 @@
                 // can be invoked in this method
                 GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit);
                 GrDrawState* drawState = fGpu->drawState();
-                SkASSERT(effect);
-                drawState->addColorEffect(effect);
+                SkASSERT(fp);
+                drawState->addColorProcessor(fp);
 
                 drawState->setRenderTarget(texture->asRenderTarget());
                 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
-                fGpu->drawSimpleRect(rect, NULL);
+                fGpu->drawSimpleRect(rect);
                 // we want to read back from the scratch's origin
                 left = 0;
                 top = 0;
@@ -1537,15 +1553,21 @@
     // target. We don't today so we always perform a flush. We don't promise
     // this to our clients, though.
     this->flush();
-    fGpu->resolveRenderTarget(target);
+    if (fGpu) {
+        fGpu->resolveRenderTarget(target);
+    }
 }
 
-void GrContext::discardRenderTarget(GrRenderTarget* target) {
-    SkASSERT(target);
-    ASSERT_OWNED_RESOURCE(target);
+void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) {
+    SkASSERT(renderTarget);
+    ASSERT_OWNED_RESOURCE(renderTarget);
     AutoRestoreEffects are;
     AutoCheckFlush acf(this);
-    this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf)->discard(target);
+    GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf);
+    if (NULL == target) {
+        return;
+    }
+    target->discard(renderTarget);
 }
 
 void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft) {
@@ -1554,29 +1576,22 @@
     }
     ASSERT_OWNED_RESOURCE(src);
 
-    // Writes pending to the source texture are not tracked, so a flush
-    // is required to ensure that the copy captures the most recent contents
-    // of the source texture. See similar behavior in
-    // GrContext::resolveRenderTarget.
-    this->flush();
-
-    GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
-    GrDrawState* drawState = fGpu->drawState();
-    drawState->setRenderTarget(dst);
-    SkMatrix sampleM;
-    sampleM.setIDiv(src->width(), src->height());
     SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height());
-    if (NULL != topLeft) {
+    if (topLeft) {
         srcRect.offset(*topLeft);
     }
     SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height());
     if (!srcRect.intersect(srcBounds)) {
         return;
     }
-    sampleM.preTranslate(SkIntToScalar(srcRect.fLeft), SkIntToScalar(srcRect.fTop));
-    drawState->addColorTextureEffect(src, sampleM);
-    SkRect dstR = SkRect::MakeWH(SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height()));
-    fGpu->drawSimpleRect(dstR, NULL);
+
+    GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, NULL, NULL);
+    if (NULL == target) {
+        return;
+    }
+    SkIPoint dstPoint;
+    dstPoint.setZero();
+    target->copySurface(dst, src, srcRect, dstPoint);
 }
 
 bool GrContext::writeRenderTargetPixels(GrRenderTarget* target,
@@ -1609,7 +1624,7 @@
     // At least some drivers on the Mac get confused when glTexImage2D is called on a texture
     // attached to an FBO. The FBO still sees the old image. TODO: determine what OS versions and/or
     // HW is affected.
-    if (NULL != target->asTexture() && !(kUnpremul_PixelOpsFlag & flags) &&
+    if (target->asTexture() && !(kUnpremul_PixelOpsFlag & flags) &&
         fGpu->canWriteTexturePixels(target->asTexture(), srcConfig)) {
         return this->writeTexturePixels(target->asTexture(),
                                         left, top, width, height,
@@ -1639,7 +1654,7 @@
         return false;
     }
 
-    SkAutoTUnref<const GrEffectRef> effect;
+    SkAutoTUnref<const GrFragmentProcessor> fp;
     SkMatrix textureMatrix;
     textureMatrix.setIDiv(texture->width(), texture->height());
 
@@ -1650,9 +1665,9 @@
         if (!GrPixelConfigIs8888(srcConfig)) {
             return false;
         }
-        effect.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix));
+        fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix));
         // handle the unpremul step on the CPU if we couldn't create an effect to do it.
-        if (NULL == effect) {
+        if (NULL == fp) {
             SkSrcPixelInfo srcPI;
             if (!GrPixelConfig2ColorType(srcConfig, &srcPI.fColorType)) {
                 return false;
@@ -1677,8 +1692,8 @@
             rowBytes = 4 * width;
         }
     }
-    if (NULL == effect) {
-        effect.reset(GrConfigConversionEffect::Create(texture,
+    if (NULL == fp) {
+        fp.reset(GrConfigConversionEffect::Create(texture,
                                                       swapRAndB,
                                                       GrConfigConversionEffect::kNone_PMConversion,
                                                       textureMatrix));
@@ -1691,19 +1706,25 @@
         return false;
     }
 
+    // TODO: Usually this could go to fDrawBuffer but currently
     // writeRenderTargetPixels can be called in the midst of drawing another
     // object (e.g., when uploading a SW path rendering to the gpu while
-    // drawing a rect) so preserve the current geometry.
+    // drawing a rect). So we always draw directly to GrGpu and preserve the current geometry.
+    // But that means we also have to flush the draw buffer if there is a pending IO operation to
+    // the render target.
+    if (!(kDontFlush_PixelOpsFlag & flags) && target->hasPendingIO()) {
+        this->flush();
+    }
     SkMatrix matrix;
     matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
     GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit, &matrix);
     GrDrawState* drawState = fGpu->drawState();
-    SkASSERT(effect);
-    drawState->addColorEffect(effect);
+    SkASSERT(fp);
+    drawState->addColorProcessor(fp);
 
     drawState->setRenderTarget(target);
 
-    fGpu->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)), NULL);
+    fGpu->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)));
     return true;
 }
 ////////////////////////////////////////////////////////////////////////////////
@@ -1714,24 +1735,32 @@
                                        AutoCheckFlush* acf) {
     // All users of this draw state should be freeing up all effects when they're done.
     // Otherwise effects that own resources may keep those resources alive indefinitely.
-    SkASSERT(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageStages());
+    SkASSERT(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageStages() &&
+             !fDrawState->hasGeometryProcessor());
+
+    if (NULL == fGpu) {
+        return NULL;
+    }
 
     if (kNo_BufferedDraw == buffered && kYes_BufferedDraw == fLastDrawWasBuffered) {
         fDrawBuffer->flush();
         fLastDrawWasBuffered = kNo_BufferedDraw;
     }
     ASSERT_OWNED_RESOURCE(fRenderTarget.get());
-    if (NULL != paint) {
-        SkASSERT(NULL != are);
-        SkASSERT(NULL != acf);
+    if (paint) {
+        SkASSERT(are);
+        SkASSERT(acf);
         are->set(fDrawState);
         fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get());
 #if GR_DEBUG_PARTIAL_COVERAGE_CHECK
         if ((paint->hasMask() || 0xff != paint->fCoverage) &&
-            !fGpu->canApplyCoverage()) {
+            !fDrawState->couldApplyCoverage(fGpu->caps())) {
             GrPrintf("Partial pixel coverage will be incorrectly blended.\n");
         }
 #endif
+        // Clear any vertex attributes configured for the previous use of the
+        // GrDrawState which can effect which blend optimizations are in effect.
+        fDrawState->setDefaultVertexAttribs();
     } else {
         fDrawState->reset(fViewMatrix);
         fDrawState->setRenderTarget(fRenderTarget.get());
@@ -1745,7 +1774,7 @@
         fLastDrawWasBuffered = kNo_BufferedDraw;
         target = fGpu;
     }
-    fDrawState->setState(GrDrawState::kClip_StateBit, NULL != fClip &&
+    fDrawState->setState(GrDrawState::kClip_StateBit, fClip &&
                                                      !fClip->fClipStack->isWideOpen());
     target->setClip(fClip);
     SkASSERT(fDrawState == target->drawState());
@@ -1846,9 +1875,9 @@
 }
 }
 
-const GrEffectRef* GrContext::createPMToUPMEffect(GrTexture* texture,
-                                                  bool swapRAndB,
-                                                  const SkMatrix& matrix) {
+const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture,
+                                                          bool swapRAndB,
+                                                          const SkMatrix& matrix) {
     if (!fDidTestPMConversions) {
         test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
         fDidTestPMConversions = true;
@@ -1862,9 +1891,9 @@
     }
 }
 
-const GrEffectRef* GrContext::createUPMToPMEffect(GrTexture* texture,
-                                                  bool swapRAndB,
-                                                  const SkMatrix& matrix) {
+const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture,
+                                                          bool swapRAndB,
+                                                          const SkMatrix& matrix) {
     if (!fDidTestPMConversions) {
         test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
         fDidTestPMConversions = true;
@@ -1878,43 +1907,27 @@
     }
 }
 
-GrPath* GrContext::createPath(const SkPath& inPath, const SkStrokeRec& stroke) {
-    SkASSERT(fGpu->caps()->pathRenderingSupport());
-
-    // TODO: now we add to fResourceCache. This should change to fResourceCache.
-    GrResourceKey resourceKey = GrPath::ComputeKey(inPath, stroke);
-    GrPath* path = static_cast<GrPath*>(fResourceCache->find(resourceKey));
-    if (NULL != path && path->isEqualTo(inPath, stroke)) {
-        path->ref();
-    } else {
-        path = fGpu->createPath(inPath, stroke);
-        fResourceCache->purgeAsNeeded(1, path->gpuMemorySize());
-        fResourceCache->addResource(resourceKey, path);
-    }
-    return path;
-}
-
-void GrContext::addResourceToCache(const GrResourceKey& resourceKey, GrCacheable* resource) {
+void GrContext::addResourceToCache(const GrResourceKey& resourceKey, GrGpuResource* resource) {
     fResourceCache->purgeAsNeeded(1, resource->gpuMemorySize());
     fResourceCache->addResource(resourceKey, resource);
 }
 
-GrCacheable* GrContext::findAndRefCachedResource(const GrResourceKey& resourceKey) {
-    GrCacheable* resource = fResourceCache->find(resourceKey);
+GrGpuResource* GrContext::findAndRefCachedResource(const GrResourceKey& resourceKey) {
+    GrGpuResource* resource = fResourceCache->find(resourceKey);
     SkSafeRef(resource);
     return resource;
 }
 
 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
     fGpu->addGpuTraceMarker(marker);
-    if (NULL != fDrawBuffer) {
+    if (fDrawBuffer) {
         fDrawBuffer->addGpuTraceMarker(marker);
     }
 }
 
 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
     fGpu->removeGpuTraceMarker(marker);
-    if (NULL != fDrawBuffer) {
+    if (fDrawBuffer) {
         fDrawBuffer->removeGpuTraceMarker(marker);
     }
 }
@@ -1925,3 +1938,10 @@
     fResourceCache->printStats();
 }
 #endif
+
+#if GR_GPU_STATS
+const GrContext::GPUStats* GrContext::gpuStats() const {
+    return fGpu->gpuStats();
+}
+#endif
+
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index 01e1a94..9d08997 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -240,7 +240,7 @@
     uint16_t subpathIdxStart = 0;
 
     SkPoint* base = reinterpret_cast<SkPoint*>(arg->vertices());
-    SkASSERT(NULL != base);
+    SkASSERT(base);
     SkPoint* vert = base;
 
     SkPoint pts[4];
@@ -361,7 +361,7 @@
         return false;
     }
 
-    SkASSERT(NULL != target);
+    SkASSERT(target);
     GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
     GrDrawState* drawState = target->drawState();
     bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
@@ -465,7 +465,7 @@
 
     for (int p = 0; p < passCount; ++p) {
         drawState->setDrawFace(drawFace[p]);
-        if (NULL != passes[p]) {
+        if (passes[p]) {
             *drawState->stencil() = *passes[p];
         }
 
@@ -476,7 +476,7 @@
             SkRect bounds;
             GrDrawState::AutoViewMatrixRestore avmr;
             if (reverse) {
-                SkASSERT(NULL != drawState->getRenderTarget());
+                SkASSERT(drawState->getRenderTarget());
                 // draw over the dev bounds (which will be the whole dst surface for inv fill).
                 bounds = devBounds;
                 SkMatrix vmi;
@@ -491,7 +491,7 @@
                 bounds = path.getBounds();
             }
             GrDrawTarget::AutoGeometryAndStatePush agasp(target, GrDrawTarget::kPreserve_ASRInit);
-            target->drawSimpleRect(bounds, NULL);
+            target->drawSimpleRect(bounds);
         } else {
             if (passCount > 1) {
                 drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
@@ -513,7 +513,7 @@
                                         bool antiAlias) const {
     // this class can draw any path with any fill but doesn't do any anti-aliasing.
 
-    return !antiAlias &&
+    return !antiAlias && !(SkPath::kConic_SegmentMask & path.getSegmentMasks()) &&
         (stroke.isFillStyle() ||
          IsStrokeHairlineOrEquivalent(stroke, target->getDrawState().getViewMatrix(), NULL));
 }
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index fe6e50f..9fd024a 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -25,7 +25,8 @@
 #include "SkStrokeRec.h"
 #include "effects/GrDistanceFieldTextureEffect.h"
 
-static const int kGlyphCoordsAttributeIndex = 1;
+SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
+                "Dump the contents of the font cache before every purge.");
 
 static const int kSmallDFFontSize = 32;
 static const int kSmallDFFontLimit = 32;
@@ -33,8 +34,25 @@
 static const int kMediumDFFontLimit = 64;
 static const int kLargeDFFontSize = 128;
 
-SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
-                "Dump the contents of the font cache before every purge.");
+namespace {
+// position + texture coord
+extern const GrVertexAttrib gTextVertexAttribs[] = {
+    {kVec2f_GrVertexAttribType, 0,                kPosition_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType, sizeof(SkPoint) , kGeometryProcessor_GrVertexAttribBinding}
+};
+
+static const size_t kTextVASize = 2 * sizeof(SkPoint); 
+
+// position + color + texture coord
+extern const GrVertexAttrib gTextVertexWithColorAttribs[] = {
+    {kVec2f_GrVertexAttribType,  0,                                 kPosition_GrVertexAttribBinding},
+    {kVec4ub_GrVertexAttribType, sizeof(SkPoint),                   kColor_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType,  sizeof(SkPoint) + sizeof(GrColor), kGeometryProcessor_GrVertexAttribBinding}
+};
+    
+static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor); 
+
+};
 
 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
                                                        const SkDeviceProperties& properties,
@@ -50,9 +68,14 @@
 
     fCurrTexture = NULL;
     fCurrVertex = 0;
+    fEffectTextureUniqueID = SK_InvalidUniqueID;
+    fEffectColor = GrColor_ILLEGAL;
+    fEffectFlags = 0;
 
     fVertices = NULL;
     fMaxVertices = 0;
+
+    fVertexBounds.setLargestInverted();
 }
 
 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
@@ -96,6 +119,58 @@
     return GrColorPackRGBA(r, g, b, 0xff);
 }
 
+void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColor) {
+    GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
+    GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
+    
+    uint32_t textureUniqueID = fCurrTexture->getUniqueID();
+    const SkMatrix& ctm = fContext->getMatrix();
+    
+    // set up any flags
+    uint32_t flags = 0;
+    flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
+    flags |= fUseLCDText ? kUseLCD_DistanceFieldEffectFlag : 0;
+    flags |= fUseLCDText && ctm.rectStaysRect() ?
+    kRectToRect_DistanceFieldEffectFlag : 0;
+    bool useBGR = SkPixelGeometryIsBGR(fDeviceProperties.fPixelGeometry);
+    flags |= fUseLCDText && useBGR ? kBGR_DistanceFieldEffectFlag : 0;
+    
+    // see if we need to create a new effect
+    if (textureUniqueID != fEffectTextureUniqueID ||
+        filteredColor != fEffectColor ||
+        flags != fEffectFlags) {
+        if (fUseLCDText) {
+            GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
+            fCachedGeometryProcessor.reset(
+                    GrDistanceFieldLCDTextureEffect::Create(fCurrTexture,
+                                                            params,
+                                                            fGammaTexture,
+                                                            gammaParams,
+                                                            colorNoPreMul,
+                                                            flags));
+        } else {
+#ifdef SK_GAMMA_APPLY_TO_A8
+            U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.getGamma(),
+                                                                filteredColor);
+            fCachedGeometryProcessor.reset(
+                    GrDistanceFieldTextureEffect::Create(fCurrTexture,
+                                                         params,
+                                                         fGammaTexture,
+                                                         gammaParams,
+                                                         lum/255.f,
+                                                         flags));
+#else
+            fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(fCurrTexture,
+                                                                                params, flags));
+#endif
+        }
+        fEffectTextureUniqueID = textureUniqueID;
+        fEffectColor = filteredColor;
+        fEffectFlags = flags;
+    }
+    
+}
+
 void GrDistanceFieldTextContext::flushGlyphs() {
     if (NULL == fDrawTarget) {
         return;
@@ -103,43 +178,35 @@
 
     GrDrawState* drawState = fDrawTarget->drawState();
     GrDrawState::AutoRestoreEffects are(drawState);
+
     drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
 
     if (fCurrVertex > 0) {
         // setup our sampler state for our text texture/atlas
         SkASSERT(SkIsAlign4(fCurrVertex));
-        SkASSERT(fCurrTexture);
-        GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
-        GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
 
-        // Effects could be stored with one of the cache objects (atlas?)
+        // get our current color
         SkColor filteredColor;
         SkColorFilter* colorFilter = fSkPaint.getColorFilter();
-        if (NULL != colorFilter) {
+        if (colorFilter) {
             filteredColor = colorFilter->filterColor(fSkPaint.getColor());
         } else {
             filteredColor = fSkPaint.getColor();
         }
+        this->setupCoverageEffect(filteredColor);
+       
+        // Effects could be stored with one of the cache objects (atlas?)
+        drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
+        
+        // Set draw state
         if (fUseLCDText) {
             GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
-            bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout ==
-                                                            fDeviceProperties.fGeometry.getLayout();
-            drawState->addCoverageEffect(GrDistanceFieldLCDTextureEffect::Create(
-                                                            fCurrTexture,
-                                                            params,
-                                                            fGammaTexture,
-                                                            gammaParams,
-                                                            colorNoPreMul,
-                                                            fContext->getMatrix().rectStaysRect() &&
-                                                            fContext->getMatrix().isSimilarity(),
-                                                            useBGR),
-                                         kGlyphCoordsAttributeIndex)->unref();
-
             if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
                 kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
                 fPaint.numColorStages()) {
                 GrPrintf("LCD Text will not draw correctly.\n");
             }
+            SkASSERT(!drawState->hasColorVertexAttribute());
             // We don't use the GrPaint's color in this case because it's been premultiplied by
             // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
             // the mask texture color. The end result is that we get
@@ -151,59 +218,36 @@
             drawState->setBlendConstant(colorNoPreMul);
             drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
         } else {
-#ifdef SK_GAMMA_APPLY_TO_A8
-            U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.fGamma,
-                                                                filteredColor);
-            drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create(
-                                                              fCurrTexture, params,
-                                                              fGammaTexture, gammaParams,
-                                                              lum/255.f,
-                                                              fContext->getMatrix().isSimilarity()),
-                                         kGlyphCoordsAttributeIndex)->unref();
-#else
-            drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create(
-                                                              fCurrTexture, params,
-                                                              fContext->getMatrix().isSimilarity()),
-                                         kGlyphCoordsAttributeIndex)->unref();
-#endif
             // set back to normal in case we took LCD path previously.
             drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
-            drawState->setColor(fPaint.getColor());
+            // We're using per-vertex color.
+            SkASSERT(drawState->hasColorVertexAttribute());
         }
-
         int nGlyphs = fCurrVertex / 4;
         fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
         fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
                                           nGlyphs,
-                                          4, 6);
+                                          4, 6, &fVertexBounds);
         fDrawTarget->resetVertexSource();
         fVertices = NULL;
         fMaxVertices = 0;
         fCurrVertex = 0;
         SkSafeSetNull(fCurrTexture);
+        fVertexBounds.setLargestInverted();
     }
 }
 
-namespace {
-
-// position + texture coord
-extern const GrVertexAttrib gTextVertexAttribs[] = {
-    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}
-};
-
-};
-
 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
                                                  SkFixed vx, SkFixed vy,
                                                  GrFontScaler* scaler) {
     if (NULL == fDrawTarget) {
         return;
     }
+    
     if (NULL == fStrike) {
         fStrike = fContext->getFontCache()->getStrike(scaler, true);
     }
-
+    
     GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
     if (NULL == glyph || glyph->fBounds.isEmpty()) {
         return;
@@ -231,30 +275,32 @@
     }
 */
     if (NULL == glyph->fPlot) {
-        if (fStrike->addGlyphToAtlas(glyph, scaler)) {
-            goto HAS_ATLAS;
-        }
+        if (!fStrike->glyphTooLargeForAtlas(glyph)) {
+            if (fStrike->addGlyphToAtlas(glyph, scaler)) {
+                goto HAS_ATLAS;
+            }
 
-        // try to clear out an unused plot before we flush
-        if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
-            fStrike->addGlyphToAtlas(glyph, scaler)) {
-            goto HAS_ATLAS;
-        }
+            // try to clear out an unused plot before we flush
+            if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
+                fStrike->addGlyphToAtlas(glyph, scaler)) {
+                goto HAS_ATLAS;
+            }
 
-        if (c_DumpFontCache) {
+            if (c_DumpFontCache) {
 #ifdef SK_DEVELOPER
-            fContext->getFontCache()->dump();
+                fContext->getFontCache()->dump();
 #endif
-        }
+            }
 
-        // before we purge the cache, we must flush any accumulated draws
-        this->flushGlyphs();
-        fContext->flush();
+            // before we purge the cache, we must flush any accumulated draws
+            this->flushGlyphs();
+            fContext->flush();
 
-        // we should have an unused plot now
-        if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
-            fStrike->addGlyphToAtlas(glyph, scaler)) {
-            goto HAS_ATLAS;
+            // we should have an unused plot now
+            if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
+                fStrike->addGlyphToAtlas(glyph, scaler)) {
+                goto HAS_ATLAS;
+            }
         }
 
         if (NULL == glyph->fPath) {
@@ -292,23 +338,39 @@
         fCurrTexture->ref();
     }
 
+    bool useColorVerts = !fUseLCDText;
+    
     if (NULL == fVertices) {
-       // If we need to reserve vertices allow the draw target to suggest
+        // If we need to reserve vertices allow the draw target to suggest
         // a number of verts to reserve and whether to perform a flush.
         fMaxVertices = kMinRequestedVerts;
-        fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
-            SK_ARRAY_COUNT(gTextVertexAttribs));
+        if (useColorVerts) {
+            fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
+                                                    SK_ARRAY_COUNT(gTextVertexWithColorAttribs),
+                                                    kTextVAColorSize);
+        } else {
+            fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
+                                                    SK_ARRAY_COUNT(gTextVertexAttribs),
+                                                    kTextVASize);
+        }
         bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
         if (flush) {
             this->flushGlyphs();
             fContext->flush();
-            fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
-                SK_ARRAY_COUNT(gTextVertexAttribs));
+            if (useColorVerts) {
+                fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
+                                                    SK_ARRAY_COUNT(gTextVertexWithColorAttribs),
+                                                    kTextVAColorSize);
+            } else {
+                fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
+                                                    SK_ARRAY_COUNT(gTextVertexAttribs),
+                                                    kTextVASize);
+            }
         }
         fMaxVertices = kDefaultRequestedVerts;
         // ignore return, no point in flushing again.
         fDrawTarget->geometryHints(&fMaxVertices, NULL);
-
+        
         int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
         if (fMaxVertices < kMinRequestedVerts) {
             fMaxVertices = kDefaultRequestedVerts;
@@ -318,12 +380,11 @@
         }
         bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
                                                                0,
-                                                               GrTCast<void**>(&fVertices),
+                                                               &fVertices,
                                                                NULL);
         GrAlwaysAssert(success);
-        SkASSERT(2*sizeof(SkPoint) == fDrawTarget->getDrawState().getVertexSize());
     }
-
+    
     SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset);
     SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset);
     SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldInset);
@@ -336,23 +397,49 @@
     sy += dy;
     width *= scale;
     height *= scale;
-
+    
     SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset);
     SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset);
     SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset);
     SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset);
 
-    static const size_t kVertexSize = 2 * sizeof(SkPoint);
-    fVertices[2*fCurrVertex].setRectFan(sx,
-                                        sy,
-                                        sx + width,
-                                        sy + height,
-                                        kVertexSize);
-    fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)),
-                                          SkFixedToFloat(texture->normalizeFixedY(ty)),
-                                          SkFixedToFloat(texture->normalizeFixedX(tx + tw)),
-                                          SkFixedToFloat(texture->normalizeFixedY(ty + th)),
-                                          kVertexSize);
+    SkRect r;
+    r.fLeft = sx;
+    r.fTop = sy;
+    r.fRight = sx + width;
+    r.fBottom = sy + height;
+
+    fVertexBounds.growToInclude(r);
+
+    size_t vertSize = fUseLCDText ? (2 * sizeof(SkPoint))
+                                  : (2 * sizeof(SkPoint) + sizeof(GrColor));
+
+    SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexStride());
+
+    SkPoint* positions = reinterpret_cast<SkPoint*>(
+        reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex);
+    positions->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom, vertSize);
+
+    // The texture coords are last in both the with and without color vertex layouts.
+    SkPoint* textureCoords = reinterpret_cast<SkPoint*>(
+            reinterpret_cast<intptr_t>(positions) + vertSize  - sizeof(SkPoint));
+    textureCoords->setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)),
+                              SkFixedToFloat(texture->normalizeFixedY(ty)),
+                              SkFixedToFloat(texture->normalizeFixedX(tx + tw)),
+                              SkFixedToFloat(texture->normalizeFixedY(ty + th)),
+                              vertSize);
+    if (useColorVerts) {
+        if (0xFF == GrColorUnpackA(fPaint.getColor())) {
+            fDrawTarget->drawState()->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
+        }
+        // color comes after position.
+        GrColor* colors = reinterpret_cast<GrColor*>(positions + 1);
+        for (int i = 0; i < 4; ++i) {
+            *colors = fPaint.getColor();
+            colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(colors) + vertSize);
+        }
+    }
+
     fCurrVertex += 4;
 }
 
@@ -361,20 +448,32 @@
 
     fStrike = NULL;
 
-    fCurrTexture = NULL;
+    const SkMatrix& ctm = fContext->getMatrix();
+
+    // getMaxScale doesn't support perspective, so neither do we at the moment
+    SkASSERT(!ctm.hasPerspective());
+    SkScalar maxScale = ctm.getMaxScale();
+    SkScalar textSize = fSkPaint.getTextSize();
+    SkScalar scaledTextSize = textSize;
+    // if we have non-unity scale, we need to choose our base text size
+    // based on the SkPaint's text size multiplied by the max scale factor
+    // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)?
+    if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) {
+        scaledTextSize *= maxScale;
+    }
+
     fCurrVertex = 0;
 
     fVertices = NULL;
-    fMaxVertices = 0;
 
-    if (fSkPaint.getTextSize() <= kSmallDFFontLimit) {
-        fTextRatio = fSkPaint.getTextSize()/kSmallDFFontSize;
+    if (scaledTextSize <= kSmallDFFontLimit) {
+        fTextRatio = textSize / kSmallDFFontSize;
         fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize));
-    } else if (fSkPaint.getTextSize() <= kMediumDFFontLimit) {
-        fTextRatio = fSkPaint.getTextSize()/kMediumDFFontSize;
+    } else if (scaledTextSize <= kMediumDFFontLimit) {
+        fTextRatio = textSize / kMediumDFFontSize;
         fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize));
     } else {
-        fTextRatio = fSkPaint.getTextSize()/kLargeDFFontSize;
+        fTextRatio = textSize / kLargeDFFontSize;
         fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize));
     }
 
@@ -388,7 +487,7 @@
 }
 
 inline void GrDistanceFieldTextContext::finish() {
-    flushGlyphs();
+    this->flushGlyphs();
 
     GrTextContext::finish();
 }
@@ -405,8 +504,8 @@
 #else
         SkScalar contrast = 0.5f;
 #endif
-        SkScalar paintGamma = deviceProperties.fGamma;
-        SkScalar deviceGamma = deviceProperties.fGamma;
+        SkScalar paintGamma = deviceProperties.getGamma();
+        SkScalar deviceGamma = deviceProperties.getGamma();
 
         size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
                                                 &width, &height);
diff --git a/src/gpu/GrDistanceFieldTextContext.h b/src/gpu/GrDistanceFieldTextContext.h
index 3a602f0..85d9250 100644
--- a/src/gpu/GrDistanceFieldTextContext.h
+++ b/src/gpu/GrDistanceFieldTextContext.h
@@ -10,6 +10,7 @@
 
 #include "GrTextContext.h"
 
+class GrGeometryProcessor;
 class GrTextStrike;
 
 /*
@@ -30,15 +31,21 @@
     virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
 
 private:
-    GrTextStrike*           fStrike;
-    SkScalar                fTextRatio;
-    bool                    fUseLCDText;
-    bool                    fEnableDFRendering;
+    GrTextStrike*                      fStrike;
+    SkScalar                           fTextRatio;
+    bool                               fUseLCDText;
+    bool                               fEnableDFRendering;
+    SkAutoTUnref<GrGeometryProcessor>  fCachedGeometryProcessor;
+    // Used to check whether fCachedEffect is still valid.
+    uint32_t                fEffectTextureUniqueID;
+    SkColor                 fEffectColor;
+    uint32_t                fEffectFlags;
     GrTexture*              fGammaTexture;
 
     void init(const GrPaint&, const SkPaint&);
     void drawPackedGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
     void flushGlyphs();                 // automatically called by destructor
+    void setupCoverageEffect(const SkColor& filteredColor);
     void finish();
 
     enum {
@@ -48,10 +55,11 @@
         kDefaultRequestedVerts   = kDefaultRequestedGlyphs * 4,
     };
 
-    SkPoint*                fVertices;
+    void*                   fVertices;
     int32_t                 fMaxVertices;
     GrTexture*              fCurrTexture;
     int                     fCurrVertex;
+    SkRect                  fVertexBounds;
 };
 
 #endif
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 1bbcc26..168cf0b 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -6,29 +6,182 @@
  */
 
 #include "GrDrawState.h"
+
+#include "GrOptDrawState.h"
 #include "GrPaint.h"
 
+//////////////////////////////////////////////////////////////////////////////s
+
+GrOptDrawState* GrDrawState::createOptState(const GrDrawTargetCaps& caps) const {
+    if (NULL == fCachedOptState || caps.getUniqueID() != fCachedCapsID) {
+        GrBlendCoeff srcCoeff;
+        GrBlendCoeff dstCoeff;
+        BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
+        fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this, blendFlags, srcCoeff, dstCoeff, caps));
+        fCachedCapsID = caps.getUniqueID();
+    } else {
+#ifdef SK_DEBUG
+        GrBlendCoeff srcCoeff;
+        GrBlendCoeff dstCoeff;
+        BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
+        SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff, caps) == *fCachedOptState);
+#endif
+    }
+    fCachedOptState->ref();
+    return fCachedOptState;
+}
+
+//////////////////////////////////////////////////////////////////////////////s
+
+GrDrawState::CombinedState GrDrawState::CombineIfPossible(
+    const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) {
+
+    if (!a.isEqual(b)) {
+        return kIncompatible_CombinedState;
+    }
+
+    // If the general draw states are equal (from check above) we know hasColorVertexAttribute()
+    // is equivalent for both a and b
+    if (a.hasColorVertexAttribute()) {
+        // If one is opaque and the other is not then the combined state is not opaque. Moreover,
+        // if the opaqueness affects the ability to get color/coverage blending correct then we
+        // don't combine the draw states.
+        bool aIsOpaque = (kVertexColorsAreOpaque_Hint & a.fHints);
+        bool bIsOpaque = (kVertexColorsAreOpaque_Hint & b.fHints);
+        if (aIsOpaque != bIsOpaque) {
+            const GrDrawState* opaque;
+            const GrDrawState* nonOpaque;
+            if (aIsOpaque) {
+                opaque = &a;
+                nonOpaque = &b;
+            } else {
+                opaque = &b;
+                nonOpaque = &a;
+            }
+            if (!opaque->hasSolidCoverage() && opaque->couldApplyCoverage(caps)) {
+                SkASSERT(!nonOpaque->hasSolidCoverage());
+                if (!nonOpaque->couldApplyCoverage(caps)) {
+                    return kIncompatible_CombinedState;
+                }
+            }
+            return aIsOpaque ? kB_CombinedState : kA_CombinedState;
+        }
+    }
+    return kAOrB_CombinedState;
+}
+
+//////////////////////////////////////////////////////////////////////////////s
+
+GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix)
+    : fCachedOptState(NULL) {
+    SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
+    *this = state;
+    if (!preConcatMatrix.isIdentity()) {
+        if (this->hasGeometryProcessor()) {
+            fGeometryProcessor->localCoordChange(preConcatMatrix);
+        }
+        for (int i = 0; i < this->numColorStages(); ++i) {
+            fColorStages[i].localCoordChange(preConcatMatrix);
+        }
+        for (int i = 0; i < this->numCoverageStages(); ++i) {
+            fCoverageStages[i].localCoordChange(preConcatMatrix);
+        }
+        this->invalidateOptState();
+    }
+}
+
+GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
+    SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
+    SkASSERT(!that.fRenderTarget.ownsPendingIO());
+    SkASSERT(!this->fRenderTarget.ownsPendingIO());
+    this->setRenderTarget(that.getRenderTarget());
+    fColor = that.fColor;
+    fViewMatrix = that.fViewMatrix;
+    fSrcBlend = that.fSrcBlend;
+    fDstBlend = that.fDstBlend;
+    fBlendConstant = that.fBlendConstant;
+    fFlagBits = that.fFlagBits;
+    fVACount = that.fVACount;
+    fVAPtr = that.fVAPtr;
+    fVAStride = that.fVAStride;
+    fStencilSettings = that.fStencilSettings;
+    fCoverage = that.fCoverage;
+    fDrawFace = that.fDrawFace;
+    if (that.hasGeometryProcessor()) {
+        fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*that.fGeometryProcessor.get())));
+    } else {
+        fGeometryProcessor.reset(NULL);
+    }
+    fColorStages = that.fColorStages;
+    fCoverageStages = that.fCoverageStages;
+
+    fHints = that.fHints;
+
+    SkRefCnt_SafeAssign(fCachedOptState, that.fCachedOptState);
+
+    memcpy(fFixedFunctionVertexAttribIndices,
+            that.fFixedFunctionVertexAttribIndices,
+            sizeof(fFixedFunctionVertexAttribIndices));
+    return *this;
+}
+
+void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
+    SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
+    SkASSERT(!fRenderTarget.ownsPendingIO());
+
+    fGeometryProcessor.reset(NULL);
+    fColorStages.reset();
+    fCoverageStages.reset();
+
+    fRenderTarget.reset();
+
+    this->setDefaultVertexAttribs();
+
+    fColor = 0xffffffff;
+    if (NULL == initialViewMatrix) {
+        fViewMatrix.reset();
+    } else {
+        fViewMatrix = *initialViewMatrix;
+    }
+    fSrcBlend = kOne_GrBlendCoeff;
+    fDstBlend = kZero_GrBlendCoeff;
+    fBlendConstant = 0x0;
+    fFlagBits = 0x0;
+    fStencilSettings.setDisabled();
+    fCoverage = 0xff;
+    fDrawFace = kBoth_DrawFace;
+
+    fHints = 0;
+
+    this->invalidateOptState();
+}
+
 bool GrDrawState::setIdentityViewMatrix()  {
-    if (fColorStages.count() || fCoverageStages.count()) {
+    if (this->numTotalStages()) {
         SkMatrix invVM;
-        if (!fCommon.fViewMatrix.invert(&invVM)) {
+        if (!fViewMatrix.invert(&invVM)) {
             // sad trombone sound
             return false;
         }
-        for (int s = 0; s < fColorStages.count(); ++s) {
+        if (this->hasGeometryProcessor()) {
+            fGeometryProcessor->localCoordChange(invVM);
+        }
+        for (int s = 0; s < this->numColorStages(); ++s) {
             fColorStages[s].localCoordChange(invVM);
         }
-        for (int s = 0; s < fCoverageStages.count(); ++s) {
+        for (int s = 0; s < this->numCoverageStages(); ++s) {
             fCoverageStages[s].localCoordChange(invVM);
         }
     }
-    fCommon.fViewMatrix.reset();
+    this->invalidateOptState();
+    fViewMatrix.reset();
     return true;
 }
 
 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
     SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
 
+    fGeometryProcessor.reset(NULL);
     fColorStages.reset();
     fCoverageStages.reset();
 
@@ -42,13 +195,14 @@
 
     this->setRenderTarget(rt);
 
-    fCommon.fViewMatrix = vm;
+    fViewMatrix = vm;
 
     // These have no equivalent in GrPaint, set them to defaults
-    fCommon.fBlendConstant = 0x0;
-    fCommon.fDrawFace = kBoth_DrawFace;
-    fCommon.fStencilSettings.setDisabled();
+    fBlendConstant = 0x0;
+    fDrawFace = kBoth_DrawFace;
+    fStencilSettings.setDisabled();
     this->resetStateFlags();
+    fHints = 0;
 
     // Enable the clip bit
     this->enableState(GrDrawState::kClip_StateBit);
@@ -59,57 +213,54 @@
 
     this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
     this->setCoverage(paint.getCoverage());
+    this->invalidateOptState();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static size_t vertex_size(const GrVertexAttrib* attribs, int count) {
+static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, size_t stride) {
     // this works as long as we're 4 byte-aligned
 #ifdef SK_DEBUG
     uint32_t overlapCheck = 0;
-#endif
-    SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt);
-    size_t size = 0;
+    SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt);
     for (int index = 0; index < count; ++index) {
         size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType);
-        size += attribSize;
-#ifdef SK_DEBUG
+        size_t attribOffset = attribs[index].fOffset;
+        SkASSERT(attribOffset + attribSize <= stride);
         size_t dwordCount = attribSize >> 2;
         uint32_t mask = (1 << dwordCount)-1;
-        size_t offsetShift = attribs[index].fOffset >> 2;
+        size_t offsetShift = attribOffset >> 2;
         SkASSERT(!(overlapCheck & (mask << offsetShift)));
         overlapCheck |= (mask << offsetShift);
-#endif
     }
-    return size;
-}
-
-size_t GrDrawState::getVertexSize() const {
-    return vertex_size(fCommon.fVAPtr, fCommon.fVACount);
+#endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
+void GrDrawState::internalSetVertexAttribs(const GrVertexAttrib* attribs, int count,
+                                           size_t stride) {
     SkASSERT(count <= kMaxVertexAttribCnt);
 
-    fCommon.fVAPtr = attribs;
-    fCommon.fVACount = count;
+    fVAPtr = attribs;
+    fVACount = count;
+    fVAStride = stride;
+    validate_vertex_attribs(fVAPtr, fVACount, fVAStride);
 
     // Set all the indices to -1
-    memset(fCommon.fFixedFunctionVertexAttribIndices,
+    memset(fFixedFunctionVertexAttribIndices,
            0xff,
-           sizeof(fCommon.fFixedFunctionVertexAttribIndices));
+           sizeof(fFixedFunctionVertexAttribIndices));
 #ifdef SK_DEBUG
     uint32_t overlapCheck = 0;
 #endif
     for (int i = 0; i < count; ++i) {
         if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
             // The fixed function attribs can only be specified once
-            SkASSERT(-1 == fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
+            SkASSERT(-1 == fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
             SkASSERT(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) ==
                      GrVertexAttribTypeVectorCount(attribs[i].fType));
-            fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
+            fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
         }
 #ifdef SK_DEBUG
         size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2;
@@ -119,8 +270,9 @@
         overlapCheck |= (mask << offsetShift);
 #endif
     }
+    this->invalidateOptState();
     // Positions must be specified.
-    SkASSERT(-1 != fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
+    SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -129,281 +281,105 @@
     static const GrVertexAttrib kPositionAttrib =
         {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
 
-    fCommon.fVAPtr = &kPositionAttrib;
-    fCommon.fVACount = 1;
+    fVAPtr = &kPositionAttrib;
+    fVACount = 1;
+    fVAStride = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
 
     // set all the fixed function indices to -1 except position.
-    memset(fCommon.fFixedFunctionVertexAttribIndices,
+    memset(fFixedFunctionVertexAttribIndices,
            0xff,
-           sizeof(fCommon.fFixedFunctionVertexAttribIndices));
-    fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
+           sizeof(fFixedFunctionVertexAttribIndices));
+    fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
+    this->invalidateOptState();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-bool GrDrawState::validateVertexAttribs() const {
-    // check consistency of effects and attributes
-    GrSLType slTypes[kMaxVertexAttribCnt];
-    for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
-        slTypes[i] = static_cast<GrSLType>(-1);
-    }
-    int totalStages = fColorStages.count() + fCoverageStages.count();
-    for (int s = 0; s < totalStages; ++s) {
-        int covIdx = s - fColorStages.count();
-        const GrEffectStage& stage = covIdx < 0 ? fColorStages[s] : fCoverageStages[covIdx];
-        const GrEffectRef* effect = stage.getEffect();
-        SkASSERT(NULL != effect);
-        // make sure that any attribute indices have the correct binding type, that the attrib
-        // type and effect's shader lang type are compatible, and that attributes shared by
-        // multiple effects use the same shader lang type.
-        const int* attributeIndices = stage.getVertexAttribIndices();
-        int numAttributes = stage.getVertexAttribIndexCount();
-        for (int i = 0; i < numAttributes; ++i) {
-            int attribIndex = attributeIndices[i];
-            if (attribIndex >= fCommon.fVACount ||
-                kEffect_GrVertexAttribBinding != fCommon.fVAPtr[attribIndex].fBinding) {
-                return false;
-            }
-
-            GrSLType effectSLType = (*effect)->vertexAttribType(i);
-            GrVertexAttribType attribType = fCommon.fVAPtr[attribIndex].fType;
-            int slVecCount = GrSLTypeVectorCount(effectSLType);
-            int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
-            if (slVecCount != attribVecCount ||
-                (static_cast<GrSLType>(-1) != slTypes[attribIndex] &&
-                    slTypes[attribIndex] != effectSLType)) {
-                return false;
-            }
-            slTypes[attribIndex] = effectSLType;
-        }
-    }
-
-    return true;
-}
-
-bool GrDrawState::willEffectReadDstColor() const {
-    if (!this->isColorWriteDisabled()) {
-        for (int s = 0; s < fColorStages.count(); ++s) {
-            if ((*fColorStages[s].getEffect())->willReadDstColor()) {
-                return true;
-            }
-        }
-    }
-    for (int s = 0; s < fCoverageStages.count(); ++s) {
-        if ((*fCoverageStages[s].getEffect())->willReadDstColor()) {
-            return true;
-        }
-    }
-    return false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-bool GrDrawState::srcAlphaWillBeOne() const {
-    uint32_t validComponentFlags;
-    GrColor color;
-    // Check if per-vertex or constant color may have partial alpha
-    if (this->hasColorVertexAttribute()) {
-        validComponentFlags = 0;
-        color = 0; // not strictly necessary but we get false alarms from tools about uninit.
-    } else {
-        validComponentFlags = kRGBA_GrColorComponentFlags;
-        color = this->getColor();
-    }
-
-    // Run through the color stages
-    for (int s = 0; s < fColorStages.count(); ++s) {
-        const GrEffectRef* effect = fColorStages[s].getEffect();
-        (*effect)->getConstantColorComponents(&color, &validComponentFlags);
-    }
-
-    // Check whether coverage is treated as color. If so we run through the coverage computation.
-    if (this->isCoverageDrawing()) {
-        GrColor coverageColor = this->getCoverageColor();
-        GrColor oldColor = color;
-        color = 0;
-        for (int c = 0; c < 4; ++c) {
-            if (validComponentFlags & (1 << c)) {
-                U8CPU a = (oldColor >> (c * 8)) & 0xff;
-                U8CPU b = (coverageColor >> (c * 8)) & 0xff;
-                color |= (SkMulDiv255Round(a, b) << (c * 8));
-            }
-        }
-        for (int s = 0; s < fCoverageStages.count(); ++s) {
-            const GrEffectRef* effect = fCoverageStages[s].getEffect();
-            (*effect)->getConstantColorComponents(&color, &validComponentFlags);
-        }
-    }
-    return (kA_GrColorComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
-}
-
-bool GrDrawState::hasSolidCoverage() const {
-    // If we're drawing coverage directly then coverage is effectively treated as color.
-    if (this->isCoverageDrawing()) {
+bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
+    if (caps.dualSourceBlendingSupport()) {
         return true;
     }
-
-    GrColor coverage;
-    uint32_t validComponentFlags;
-    // Initialize to an unknown starting coverage if per-vertex coverage is specified.
-    if (this->hasCoverageVertexAttribute()) {
-        validComponentFlags = 0;
-    } else {
-        coverage = fCommon.fCoverage;
-        validComponentFlags = kRGBA_GrColorComponentFlags;
-    }
-
-    // Run through the coverage stages and see if the coverage will be all ones at the end.
-    for (int s = 0; s < fCoverageStages.count(); ++s) {
-        const GrEffectRef* effect = fCoverageStages[s].getEffect();
-        (*effect)->getConstantColorComponents(&coverage, &validComponentFlags);
-    }
-    return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage);
+    // we can correctly apply coverage if a) we have dual source blending
+    // or b) one of our blend optimizations applies
+    // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color
+    GrBlendCoeff srcCoeff;
+    GrBlendCoeff dstCoeff;
+    BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff);
+    return GrRODrawState::kNone_BlendOpt != flag ||
+           (this->willEffectReadDstColor() &&
+            kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
 }
 
-////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
 
-// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
-// others will blend incorrectly.
-bool GrDrawState::canTweakAlphaForCoverage() const {
-    /*
-     The fractional coverage is f.
-     The src and dst coeffs are Cs and Cd.
-     The dst and src colors are S and D.
-     We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha
-     we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
-     term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we
-     find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
-     Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as
-     color by definition.
-     */
-    return kOne_GrBlendCoeff == fCommon.fDstBlend ||
-           kISA_GrBlendCoeff == fCommon.fDstBlend ||
-           kISC_GrBlendCoeff == fCommon.fDstBlend ||
-           this->isCoverageDrawing();
+GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawState) {
+    SkASSERT(drawState);
+    fDrawState = drawState;
+    fVAPtr = drawState->fVAPtr;
+    fVACount = drawState->fVACount;
+    fVAStride = drawState->fVAStride;
+    fDrawState->setDefaultVertexAttribs();
 }
 
-GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
-                                                     GrBlendCoeff* srcCoeff,
-                                                     GrBlendCoeff* dstCoeff) const {
+//////////////////////////////////////////////////////////////////////////////s
 
-    GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
-    if (NULL == srcCoeff) {
-        srcCoeff = &bogusSrcCoeff;
-    }
-    *srcCoeff = this->getSrcBlendCoeff();
-
-    if (NULL == dstCoeff) {
-        dstCoeff = &bogusDstCoeff;
-    }
-    *dstCoeff = this->getDstBlendCoeff();
-
-    if (this->isColorWriteDisabled()) {
-        *srcCoeff = kZero_GrBlendCoeff;
-        *dstCoeff = kOne_GrBlendCoeff;
-    }
-
-    bool srcAIsOne = this->srcAlphaWillBeOne();
-    bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
-                         (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
-    bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
-                         (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
-
-    bool covIsZero = !this->isCoverageDrawing() &&
-                     !this->hasCoverageVertexAttribute() &&
-                     0 == this->getCoverageColor();
-    // When coeffs are (0,1) there is no reason to draw at all, unless
-    // stenciling is enabled. Having color writes disabled is effectively
-    // (0,1). The same applies when coverage is known to be 0.
-    if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) {
-        if (this->getStencil().doesWrite()) {
-            return kDisableBlend_BlendOptFlag |
-                   kEmitCoverage_BlendOptFlag;
+void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
+    if (fDrawState) {
+        // See the big comment on the class definition about GPs.
+        if (SK_InvalidUniqueID == fOriginalGPID) {
+            fDrawState->fGeometryProcessor.reset(NULL);
         } else {
-            return kSkipDraw_BlendOptFlag;
+            SkASSERT(fDrawState->getGeometryProcessor()->getProcessor()->getUniqueID() ==
+                     fOriginalGPID);
+            fOriginalGPID = SK_InvalidUniqueID;
         }
-    }
 
-    // check for coverage due to constant coverage, per-vertex coverage, or coverage stage
-    bool hasCoverage = forceCoverage ||
-                       0xffffffff != this->getCoverageColor() ||
-                       this->hasCoverageVertexAttribute() ||
-                       fCoverageStages.count() > 0;
+        int m = fDrawState->numColorStages() - fColorEffectCnt;
+        SkASSERT(m >= 0);
+        fDrawState->fColorStages.pop_back_n(m);
 
-    // if we don't have coverage we can check whether the dst
-    // has to read at all. If not, we'll disable blending.
-    if (!hasCoverage) {
-        if (dstCoeffIsZero) {
-            if (kOne_GrBlendCoeff == *srcCoeff) {
-                // if there is no coverage and coeffs are (1,0) then we
-                // won't need to read the dst at all, it gets replaced by src
-                return kDisableBlend_BlendOptFlag;
-            } else if (kZero_GrBlendCoeff == *srcCoeff) {
-                // if the op is "clear" then we don't need to emit a color
-                // or blend, just write transparent black into the dst.
-                *srcCoeff = kOne_GrBlendCoeff;
-                *dstCoeff = kZero_GrBlendCoeff;
-                return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag;
-            }
+        int n = fDrawState->numCoverageStages() - fCoverageEffectCnt;
+        SkASSERT(n >= 0);
+        fDrawState->fCoverageStages.pop_back_n(n);
+        if (m + n > 0) {
+            fDrawState->invalidateOptState();
         }
-    } else if (this->isCoverageDrawing()) {
-        // we have coverage but we aren't distinguishing it from alpha by request.
-        return kCoverageAsAlpha_BlendOptFlag;
-    } else {
-        // check whether coverage can be safely rolled into alpha
-        // of if we can skip color computation and just emit coverage
-        if (this->canTweakAlphaForCoverage()) {
-            return kCoverageAsAlpha_BlendOptFlag;
-        }
-        if (dstCoeffIsZero) {
-            if (kZero_GrBlendCoeff == *srcCoeff) {
-                // the source color is not included in the blend
-                // the dst coeff is effectively zero so blend works out to:
-                // (c)(0)D + (1-c)D = (1-c)D.
-                *dstCoeff = kISA_GrBlendCoeff;
-                return  kEmitCoverage_BlendOptFlag;
-            } else if (srcAIsOne) {
-                // the dst coeff is effectively zero so blend works out to:
-                // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
-                // If Sa is 1 then we can replace Sa with c
-                // and set dst coeff to 1-Sa.
-                *dstCoeff = kISA_GrBlendCoeff;
-                return  kCoverageAsAlpha_BlendOptFlag;
-            }
-        } else if (dstCoeffIsOne) {
-            // the dst coeff is effectively one so blend works out to:
-            // cS + (c)(1)D + (1-c)D = cS + D.
-            *dstCoeff = kOne_GrBlendCoeff;
-            return  kCoverageAsAlpha_BlendOptFlag;
-        }
+        SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
     }
-    if (kOne_GrBlendCoeff == *srcCoeff &&
-        kZero_GrBlendCoeff == *dstCoeff &&
-        this->willEffectReadDstColor()) {
-        // In this case the shader will fully resolve the color, coverage, and dst and we don't
-        // need blending.
-        return kDisableBlend_BlendOptFlag;
+    fDrawState = ds;
+    if (NULL != ds) {
+        SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
+        if (NULL != ds->getGeometryProcessor()) {
+            fOriginalGPID = ds->getGeometryProcessor()->getProcessor()->getUniqueID();
+        }
+        fColorEffectCnt = ds->numColorStages();
+        fCoverageEffectCnt = ds->numCoverageStages();
+        SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
     }
-    return kNone_BlendOpt;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrDrawState::AutoViewMatrixRestore::restore() {
-    if (NULL != fDrawState) {
+    if (fDrawState) {
         SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
-        fDrawState->fCommon.fViewMatrix = fViewMatrix;
+        fDrawState->fViewMatrix = fViewMatrix;
         SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
         int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
         SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
 
         int i = 0;
+        if (fHasGeometryProcessor) {
+            SkASSERT(fDrawState->hasGeometryProcessor());
+            fDrawState->fGeometryProcessor->restoreCoordChange(fSavedCoordChanges[i++]);
+        }
         for (int s = 0; s < fNumColorStages; ++s, ++i) {
             fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
         }
         for (int s = 0; s < numCoverageStages; ++s, ++i) {
             fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
         }
+        fDrawState->invalidateOptState();
         fDrawState = NULL;
     }
 }
@@ -419,10 +395,11 @@
     fDrawState = drawState;
 
     fViewMatrix = drawState->getViewMatrix();
-    drawState->fCommon.fViewMatrix.preConcat(preconcatMatrix);
+    drawState->fViewMatrix.preConcat(preconcatMatrix);
 
     this->doEffectCoordChanges(preconcatMatrix);
     SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
+    drawState->invalidateOptState();
 }
 
 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
@@ -436,10 +413,12 @@
         return true;
     }
 
+    drawState->invalidateOptState();
     fViewMatrix = drawState->getViewMatrix();
     if (0 == drawState->numTotalStages()) {
-        drawState->fCommon.fViewMatrix.reset();
+        drawState->fViewMatrix.reset();
         fDrawState = drawState;
+        fHasGeometryProcessor = false;
         fNumColorStages = 0;
         fSavedCoordChanges.reset(0);
         SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
@@ -449,7 +428,7 @@
         if (!fViewMatrix.invert(&inv)) {
             return false;
         }
-        drawState->fCommon.fViewMatrix.reset();
+        drawState->fViewMatrix.reset();
         fDrawState = drawState;
         this->doEffectCoordChanges(inv);
         SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
@@ -461,15 +440,36 @@
     fSavedCoordChanges.reset(fDrawState->numTotalStages());
     int i = 0;
 
+    fHasGeometryProcessor = false;
+    if (fDrawState->hasGeometryProcessor()) {
+        fDrawState->fGeometryProcessor->saveCoordChange(&fSavedCoordChanges[i++]);
+        fDrawState->fGeometryProcessor->localCoordChange(coordChangeMatrix);
+        fHasGeometryProcessor = true;
+    }
+
     fNumColorStages = fDrawState->numColorStages();
     for (int s = 0; s < fNumColorStages; ++s, ++i) {
-        fDrawState->fColorStages[s].saveCoordChange(&fSavedCoordChanges[i]);
+        fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
         fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix);
     }
 
     int numCoverageStages = fDrawState->numCoverageStages();
     for (int s = 0; s < numCoverageStages; ++s, ++i) {
-        fDrawState->fCoverageStages[s].saveCoordChange(&fSavedCoordChanges[i]);
+        fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]);
         fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix);
     }
 }
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrDrawState::invalidateOptState() const {
+    SkSafeSetNull(fCachedOptState);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrDrawState::~GrDrawState() {
+    SkSafeUnref(fCachedOptState);
+    SkASSERT(0 == fBlockEffectRemovalCnt);
+}
+
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 6cefd97..19ea4df 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -8,32 +8,30 @@
 #ifndef GrDrawState_DEFINED
 #define GrDrawState_DEFINED
 
-#include "GrBackendEffectFactory.h"
 #include "GrBlend.h"
-#include "GrColor.h"
-#include "GrEffectStage.h"
-#include "GrPaint.h"
-#include "GrRenderTarget.h"
-#include "GrStencil.h"
-#include "GrTemplates.h"
-#include "GrTexture.h"
-#include "GrTypesPriv.h"
+#include "GrDrawTargetCaps.h"
+#include "GrGpuResourceRef.h"
+#include "GrRODrawState.h"
 #include "effects/GrSimpleTextureEffect.h"
 
-#include "SkMatrix.h"
-#include "SkTypes.h"
-#include "SkXfermode.h"
+class GrOptDrawState;
 
-class GrDrawState : public SkRefCnt {
+/**
+ * Modifiable subclass derived from GrRODrawState. The majority of the data that represents a draw
+ * state is stored in the parent class. GrDrawState contains methods for setting, adding to, etc.
+ * various data members of the draw state. This class is used to configure the state used when
+ * issuing draws via GrDrawTarget.
+ */
+class GrDrawState : public GrRODrawState {
 public:
     SK_DECLARE_INST_COUNT(GrDrawState)
 
-    GrDrawState() {
+    GrDrawState() : fCachedOptState(NULL) {
         SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
         this->reset();
     }
 
-    GrDrawState(const SkMatrix& initialViewMatrix) {
+    GrDrawState(const SkMatrix& initialViewMatrix) : fCachedOptState(NULL) {
         SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
         this->reset(initialViewMatrix);
     }
@@ -41,7 +39,7 @@
     /**
      * Copies another draw state.
      **/
-    GrDrawState(const GrDrawState& state) : INHERITED() {
+    GrDrawState(const GrDrawState& state) : INHERITED(), fCachedOptState(NULL) {
         SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
         *this = state;
     }
@@ -49,23 +47,12 @@
     /**
      * Copies another draw state with a preconcat to the view matrix.
      **/
-    GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) {
-        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
-        *this = state;
-        if (!preConcatMatrix.isIdentity()) {
-            for (int i = 0; i < fColorStages.count(); ++i) {
-                fColorStages[i].localCoordChange(preConcatMatrix);
-            }
-            for (int i = 0; i < fCoverageStages.count(); ++i) {
-                fCoverageStages[i].localCoordChange(preConcatMatrix);
-            }
-        }
-    }
+    GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
 
-    virtual ~GrDrawState() { SkASSERT(0 == fBlockEffectRemovalCnt); }
+    virtual ~GrDrawState();
 
     /**
-     * Resets to the default state. GrEffects will be removed from all stages.
+     * Resets to the default state. GrProcessors will be removed from all stages.
      */
     void reset() { this->onReset(NULL); }
 
@@ -74,7 +61,8 @@
     /**
      * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that
      * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint
-     * equivalents are set to default values. Clipping will be enabled.
+     * equivalents are set to default values with the exception of vertex attribute state which
+     * is unmodified by this function and clipping which will be enabled.
      */
     void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
 
@@ -82,32 +70,26 @@
     /// @name Vertex Attributes
     ////
 
-    enum {
-        kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
-    };
-
    /**
      * The format of vertices is represented as an array of GrVertexAttribs, with each representing
      * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
      * GrTypesPriv.h).
      *
-     * The mapping of attributes with kEffect bindings to GrEffect inputs is specified when
+     * The mapping of attributes with kEffect bindings to GrProcessor inputs is specified when
      * setEffect is called.
      */
 
     /**
      *  Sets vertex attributes for next draw. The object driving the templatization
      *  should be a global GrVertexAttrib array that is never changed.
+     *
+     *  @param count      the number of attributes being set, limited to kMaxVertexAttribCnt.
+     *  @param stride     the number of bytes between successive vertex data.
      */
-    template <const GrVertexAttrib A[]> void setVertexAttribs(int count) {
-        this->setVertexAttribs(A, count);
+    template <const GrVertexAttrib A[]> void setVertexAttribs(int count, size_t stride) {
+        this->internalSetVertexAttribs(A, count, stride);
     }
 
-    const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVAPtr; }
-    int getVertexAttribCount() const { return fCommon.fVACount; }
-
-    size_t getVertexSize() const;
-
     /**
      *  Sets default vertex attributes for next draw. The default is a single attribute:
      *  {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
@@ -115,128 +97,35 @@
     void setDefaultVertexAttribs();
 
     /**
-     * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the
-     * binding does not appear in the current attribs. These bindings should appear only once in
-     * the attrib array.
-     */
-
-    int positionAttributeIndex() const {
-        return fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
-    }
-    int localCoordAttributeIndex() const {
-        return fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
-    }
-    int colorVertexAttributeIndex() const {
-        return fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
-    }
-    int coverageVertexAttributeIndex() const {
-        return fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
-    }
-
-    bool hasLocalCoordAttribute() const {
-        return -1 != fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
-    }
-    bool hasColorVertexAttribute() const {
-        return -1 != fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
-    }
-    bool hasCoverageVertexAttribute() const {
-        return -1 != fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
-    }
-
-    bool validateVertexAttribs() const;
-
-    /**
      * Helper to save/restore vertex attribs
      */
      class AutoVertexAttribRestore {
      public:
-         AutoVertexAttribRestore(GrDrawState* drawState) {
-             SkASSERT(NULL != drawState);
-             fDrawState = drawState;
-             fVAPtr = drawState->fCommon.fVAPtr;
-             fVACount = drawState->fCommon.fVACount;
-             fDrawState->setDefaultVertexAttribs();
-         }
+         AutoVertexAttribRestore(GrDrawState* drawState);
 
-         ~AutoVertexAttribRestore(){
-             fDrawState->setVertexAttribs(fVAPtr, fVACount);
-         }
+         ~AutoVertexAttribRestore() { fDrawState->internalSetVertexAttribs(fVAPtr, fVACount,
+                                                                           fVAStride); }
 
      private:
          GrDrawState*          fDrawState;
          const GrVertexAttrib* fVAPtr;
          int                   fVACount;
+         size_t                fVAStride;
      };
 
-    /**
-     * Accessing positions, local coords, or colors, of a vertex within an array is a hassle
-     * involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit
-     * nicer looking.
-     */
-
-    /**
-     * Gets a pointer to a GrPoint of a vertex's position or texture
-     * coordinate.
-     * @param vertices      the vertex array
-     * @param vertexIndex   the index of the vertex in the array
-     * @param vertexSize    the size of each vertex in the array
-     * @param offset        the offset in bytes of the vertex component.
-     *                      Defaults to zero (corresponding to vertex position)
-     * @return pointer to the vertex component as a GrPoint
-     */
-    static SkPoint* GetVertexPoint(void* vertices,
-                                   int vertexIndex,
-                                   int vertexSize,
-                                   int offset = 0) {
-        intptr_t start = GrTCast<intptr_t>(vertices);
-        return GrTCast<SkPoint*>(start + offset +
-                                 vertexIndex * vertexSize);
-    }
-    static const SkPoint* GetVertexPoint(const void* vertices,
-                                         int vertexIndex,
-                                         int vertexSize,
-                                         int offset = 0) {
-        intptr_t start = GrTCast<intptr_t>(vertices);
-        return GrTCast<const SkPoint*>(start + offset +
-                                       vertexIndex * vertexSize);
-    }
-
-    /**
-     * Gets a pointer to a GrColor inside a vertex within a vertex array.
-     * @param vertices      the vetex array
-     * @param vertexIndex   the index of the vertex in the array
-     * @param vertexSize    the size of each vertex in the array
-     * @param offset        the offset in bytes of the vertex color
-     * @return pointer to the vertex component as a GrColor
-     */
-    static GrColor* GetVertexColor(void* vertices,
-                                   int vertexIndex,
-                                   int vertexSize,
-                                   int offset) {
-        intptr_t start = GrTCast<intptr_t>(vertices);
-        return GrTCast<GrColor*>(start + offset +
-                                 vertexIndex * vertexSize);
-    }
-    static const GrColor* GetVertexColor(const void* vertices,
-                                         int vertexIndex,
-                                         int vertexSize,
-                                         int offset) {
-        const intptr_t start = GrTCast<intptr_t>(vertices);
-        return GrTCast<const GrColor*>(start + offset +
-                                       vertexIndex * vertexSize);
-    }
-
     /// @}
 
     /**
-     * Determines whether src alpha is guaranteed to be one for all src pixels
+     * Depending on features available in the underlying 3D API and the color blend mode requested
+     * it may or may not be possible to correctly blend with fractional pixel coverage generated by
+     * the fragment shader.
+     *
+     * This function considers the current draw state and the draw target's capabilities to
+     * determine whether coverage can be handled correctly. This function assumes that the caller
+     * intends to specify fractional pixel coverage (via setCoverage(), through a coverage vertex
+     * attribute, or a coverage effect) but may not have specified it yet.
      */
-    bool srcAlphaWillBeOne() const;
-
-    /**
-     * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
-     */
-    bool hasSolidCoverage() const;
+    bool couldApplyCoverage(const GrDrawTargetCaps& caps) const;
 
     /// @}
 
@@ -249,9 +138,12 @@
      *
      *  @param color    the color to set.
      */
-    void setColor(GrColor color) { fCommon.fColor = color; }
-
-    GrColor getColor() const { return fCommon.fColor; }
+    void setColor(GrColor color) {
+        if (color != fColor) {
+            fColor = color;
+            this->invalidateOptState();
+        }
+    }
 
     /**
      *  Sets the color to be used for the next draw to be
@@ -259,41 +151,7 @@
      *
      *  @param alpha The alpha value to set as the color.
      */
-    void setAlpha(uint8_t a) {
-        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
-    }
-
-    /**
-     * Constructor sets the color to be 'color' which is undone by the destructor.
-     */
-    class AutoColorRestore : public ::SkNoncopyable {
-    public:
-        AutoColorRestore() : fDrawState(NULL), fOldColor(0) {}
-
-        AutoColorRestore(GrDrawState* drawState, GrColor color) {
-            fDrawState = NULL;
-            this->set(drawState, color);
-        }
-
-        void reset() {
-            if (NULL != fDrawState) {
-                fDrawState->setColor(fOldColor);
-                fDrawState = NULL;
-            }
-        }
-
-        void set(GrDrawState* drawState, GrColor color) {
-            this->reset();
-            fDrawState = drawState;
-            fOldColor = fDrawState->getColor();
-            fDrawState->setColor(color);
-        }
-
-        ~AutoColorRestore() { this->reset(); }
-    private:
-        GrDrawState*    fDrawState;
-        GrColor         fOldColor;
-    };
+    void setAlpha(uint8_t a) { this->setColor((a << 24) | (a << 16) | (a << 8) | a); }
 
     /// @}
 
@@ -307,23 +165,32 @@
      * coverage is ignored when per-vertex coverage is provided.
      */
     void setCoverage(uint8_t coverage) {
-        fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
-    }
-
-    uint8_t getCoverage() const {
-        return GrColorUnpackR(fCommon.fCoverage);
-    }
-
-    GrColor getCoverageColor() const {
-        return fCommon.fCoverage;
+        if (coverage != fCoverage) {
+            fCoverage = coverage;
+            this->invalidateOptState();
+        }
     }
 
     /// @}
 
+    /**
+     * The geometry processor is the sole element of the skia pipeline which can use the vertex,
+     * geometry, and tesselation shaders.  The GP may also compute a coverage in its fragment shader
+     * but is never put in the color processing pipeline.
+     */
+
+    const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
+        SkASSERT(geometryProcessor);
+        SkASSERT(!this->hasGeometryProcessor());
+        fGeometryProcessor.reset(new GrGeometryStage(geometryProcessor));
+        this->invalidateOptState();
+        return geometryProcessor;
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     /// @name Effect Stages
-    /// Each stage hosts a GrEffect. The effect produces an output color or coverage in the fragment
-    /// shader. Its inputs are the output from the previous stage as well as some variables
+    /// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
+    /// fragment shader. Its inputs are the output from the previous stage as well as some variables
     /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
     /// the fragment position, local coordinates).
     ///
@@ -340,97 +207,88 @@
     /// the color / coverage distinction.
     ////
 
-    const GrEffectRef* addColorEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
-        SkASSERT(NULL != effect);
-        SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect, attr0, attr1));
+    const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
+        SkASSERT(effect);
+        SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
+        this->invalidateOptState();
         return effect;
     }
 
-    const GrEffectRef* addCoverageEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
-        SkASSERT(NULL != effect);
-        SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1));
+    const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* effect) {
+        SkASSERT(effect);
+        SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (effect));
+        this->invalidateOptState();
         return effect;
     }
 
     /**
      * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
      */
-    void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
-        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
-        this->addColorEffect(effect)->unref();
+    void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
+        this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
     }
 
-    void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
-        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
-        this->addCoverageEffect(effect)->unref();
+    void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
+        this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
     }
 
-    void addColorTextureEffect(GrTexture* texture,
-                               const SkMatrix& matrix,
-                               const GrTextureParams& params) {
-        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
-        this->addColorEffect(effect)->unref();
-    }
-
-    void addCoverageTextureEffect(GrTexture* texture,
+    void addColorTextureProcessor(GrTexture* texture,
                                   const SkMatrix& matrix,
                                   const GrTextureParams& params) {
-        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
-        this->addCoverageEffect(effect)->unref();
+        this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
+    }
+
+    void addCoverageTextureProcessor(GrTexture* texture,
+                                     const SkMatrix& matrix,
+                                     const GrTextureParams& params) {
+        this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
     }
 
     /**
-     * When this object is destroyed it will remove any effects from the draw state that were added
-     * after its constructor.
+     * When this object is destroyed it will remove any color/coverage effects from the draw state
+     * that were added after its constructor.
+     *
+     * This class has strange behavior around geometry processor. If there is a GP on the draw state
+     * it will assert that the GP is not modified until after the destructor of the ARE. If the
+     * draw state has a NULL GP when the ARE is constructed then it will reset it to null in the
+     * destructor.
+     *
+     * TODO: We'd prefer for the ARE to just save and restore the GP. However, this would add
+     * significant complexity to the multi-ref architecture for deferred drawing. Once GrDrawState
+     * and GrOptDrawState are fully separated then GrDrawState will never be in the deferred
+     * execution state and GrOptDrawState always will be (and will be immutable and therefore
+     * unable to have an ARE). At this point we can restore sanity and have the ARE save and restore
+     * the GP.
      */
     class AutoRestoreEffects : public ::SkNoncopyable {
     public:
-        AutoRestoreEffects() : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {}
+        AutoRestoreEffects() 
+            : fDrawState(NULL)
+            , fOriginalGPID(SK_InvalidUniqueID)
+            , fColorEffectCnt(0)
+            , fCoverageEffectCnt(0) {}
 
-        AutoRestoreEffects(GrDrawState* ds) : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {
+        AutoRestoreEffects(GrDrawState* ds)
+            : fDrawState(NULL)
+            , fOriginalGPID(SK_InvalidUniqueID)
+            , fColorEffectCnt(0)
+            , fCoverageEffectCnt(0) {
             this->set(ds);
         }
 
         ~AutoRestoreEffects() { this->set(NULL); }
 
-        void set(GrDrawState* ds) {
-            if (NULL != fDrawState) {
-                int n = fDrawState->fColorStages.count() - fColorEffectCnt;
-                SkASSERT(n >= 0);
-                fDrawState->fColorStages.pop_back_n(n);
-                n = fDrawState->fCoverageStages.count() - fCoverageEffectCnt;
-                SkASSERT(n >= 0);
-                fDrawState->fCoverageStages.pop_back_n(n);
-                SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
-            }
-            fDrawState = ds;
-            if (NULL != ds) {
-                fColorEffectCnt = ds->fColorStages.count();
-                fCoverageEffectCnt = ds->fCoverageStages.count();
-                SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
-            }
-        }
+        void set(GrDrawState* ds);
 
-        bool isSet() const { return NULL != fDrawState; }
+        bool isSet() const { return SkToBool(fDrawState); }
 
     private:
-        GrDrawState* fDrawState;
-        int fColorEffectCnt;
-        int fCoverageEffectCnt;
+        GrDrawState*    fDrawState;
+        uint32_t        fOriginalGPID;
+        int             fColorEffectCnt;
+        int             fCoverageEffectCnt;
     };
 
-    int numColorStages() const { return fColorStages.count(); }
-    int numCoverageStages() const { return fCoverageStages.count(); }
-    int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); }
-
-    const GrEffectStage& getColorStage(int stageIdx) const { return fColorStages[stageIdx]; }
-    const GrEffectStage& getCoverageStage(int stageIdx) const { return fCoverageStages[stageIdx]; }
-
-    /**
-     * Checks whether any of the effects will read the dst pixel color.
-     */
-    bool willEffectReadDstColor() const;
-
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
@@ -451,8 +309,11 @@
      * @param dstCoef coefficient applied to the dst color.
      */
     void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
-        fCommon.fSrcBlend = srcCoeff;
-        fCommon.fDstBlend = dstCoeff;
+        if (srcCoeff != fSrcBlend || dstCoeff != fDstBlend) {
+            fSrcBlend = srcCoeff;
+            fDstBlend = dstCoeff;
+            this->invalidateOptState();
+        }
     #ifdef SK_DEBUG
         if (GrBlendCoeffRefsDst(dstCoeff)) {
             GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
@@ -463,15 +324,6 @@
     #endif
     }
 
-    GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
-    GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
-
-    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
-                          GrBlendCoeff* dstBlendCoeff) const {
-        *srcBlendCoeff = fCommon.fSrcBlend;
-        *dstBlendCoeff = fCommon.fDstBlend;
-    }
-
     /**
      * Sets the blending function constant referenced by the following blending
      * coefficients:
@@ -482,67 +334,12 @@
      *
      * @param constant the constant to set
      */
-    void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
-
-    /**
-     * Retrieves the last value set by setBlendConstant()
-     * @return the blending constant value
-     */
-    GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
-
-    /**
-     * Determines whether multiplying the computed per-pixel color by the pixel's fractional
-     * coverage before the blend will give the correct final destination color. In general it
-     * will not as coverage is applied after blending.
-     */
-    bool canTweakAlphaForCoverage() const;
-
-    /**
-     * Optimizations for blending / coverage to that can be applied based on the current state.
-     */
-    enum BlendOptFlags {
-        /**
-         * No optimization
-         */
-        kNone_BlendOpt                  = 0,
-        /**
-         * Don't draw at all
-         */
-        kSkipDraw_BlendOptFlag          = 0x1,
-        /**
-         * Emit the src color, disable HW blending (replace dst with src)
-         */
-        kDisableBlend_BlendOptFlag      = 0x2,
-        /**
-         * The coverage value does not have to be computed separately from alpha, the the output
-         * color can be the modulation of the two.
-         */
-        kCoverageAsAlpha_BlendOptFlag   = 0x4,
-        /**
-         * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
-         * "don't cares".
-         */
-        kEmitCoverage_BlendOptFlag      = 0x8,
-        /**
-         * Emit transparent black instead of the src color, no need to compute coverage.
-         */
-        kEmitTransBlack_BlendOptFlag    = 0x10,
-    };
-    GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
-
-    /**
-     * Determines what optimizations can be applied based on the blend. The coefficients may have
-     * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
-     * params that receive the tweaked coefficients. Normally the function looks at the current
-     * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
-     * determine the blend optimizations that would be used if there was partial pixel coverage.
-     *
-     * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
-     * playback) must call this function and respect the flags that replace the output color.
-     */
-    BlendOptFlags getBlendOpts(bool forceCoverage = false,
-                               GrBlendCoeff* srcCoeff = NULL,
-                               GrBlendCoeff* dstCoeff = NULL) const;
+    void setBlendConstant(GrColor constant) {
+        if (constant != fBlendConstant) {
+            fBlendConstant = constant;
+            this->invalidateOptState();
+        }
+    }
 
     /// @}
 
@@ -556,34 +353,6 @@
      */
     bool setIdentityViewMatrix();
 
-    /**
-     * Retrieves the current view matrix
-     * @return the current view matrix.
-     */
-    const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
-
-    /**
-     *  Retrieves the inverse of the current view matrix.
-     *
-     *  If the current view matrix is invertible, return true, and if matrix
-     *  is non-null, copy the inverse into it. If the current view matrix is
-     *  non-invertible, return false and ignore the matrix parameter.
-     *
-     * @param matrix if not null, will receive a copy of the current inverse.
-     */
-    bool getViewInverse(SkMatrix* matrix) const {
-        // TODO: determine whether we really need to leave matrix unmodified
-        // at call sites when inversion fails.
-        SkMatrix inverse;
-        if (fCommon.fViewMatrix.invert(&inverse)) {
-            if (matrix) {
-                *matrix = inverse;
-            }
-            return true;
-        }
-        return false;
-    }
-
     ////////////////////////////////////////////////////////////////////////////
 
     /**
@@ -615,10 +384,11 @@
     private:
         void doEffectCoordChanges(const SkMatrix& coordChangeMatrix);
 
-        GrDrawState*                                        fDrawState;
-        SkMatrix                                            fViewMatrix;
-        int                                                 fNumColorStages;
-        SkAutoSTArray<8, GrEffectStage::SavedCoordChange>   fSavedCoordChanges;
+        GrDrawState*                                           fDrawState;
+        SkMatrix                                               fViewMatrix;
+        int                                                    fNumColorStages;
+        bool                                                   fHasGeometryProcessor;
+        SkAutoSTArray<8, GrProcessorStage::SavedCoordChange>   fSavedCoordChanges;
     };
 
     /// @}
@@ -633,51 +403,10 @@
      * @param target  The render target to set.
      */
     void setRenderTarget(GrRenderTarget* target) {
-        fRenderTarget.reset(SkSafeRef(target));
+        fRenderTarget.set(SkSafeRef(target), GrIORef::kWrite_IOType);
+        this->invalidateOptState();
     }
 
-    /**
-     * Retrieves the currently set render-target.
-     *
-     * @return    The currently set render target.
-     */
-    const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
-    GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
-
-    class AutoRenderTargetRestore : public ::SkNoncopyable {
-    public:
-        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
-        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
-            fDrawState = NULL;
-            fSavedTarget = NULL;
-            this->set(ds, newTarget);
-        }
-        ~AutoRenderTargetRestore() { this->restore(); }
-
-        void restore() {
-            if (NULL != fDrawState) {
-                fDrawState->setRenderTarget(fSavedTarget);
-                fDrawState = NULL;
-            }
-            SkSafeSetNull(fSavedTarget);
-        }
-
-        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
-            this->restore();
-
-            if (NULL != ds) {
-                SkASSERT(NULL == fSavedTarget);
-                fSavedTarget = ds->getRenderTarget();
-                SkSafeRef(fSavedTarget);
-                ds->setRenderTarget(newTarget);
-                fDrawState = ds;
-            }
-        }
-    private:
-        GrDrawState* fDrawState;
-        GrRenderTarget* fSavedTarget;
-    };
-
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
@@ -692,19 +421,23 @@
      * @param settings  the stencil settings to use.
      */
     void setStencil(const GrStencilSettings& settings) {
-        fCommon.fStencilSettings = settings;
+        if (settings != fStencilSettings) {
+            fStencilSettings = settings;
+            this->invalidateOptState();
+        }
     }
 
     /**
      * Shortcut to disable stencil testing and ops.
      */
     void disableStencil() {
-        fCommon.fStencilSettings.setDisabled();
+        if (!fStencilSettings.isDisabled()) {
+            fStencilSettings.setDisabled();
+            this->invalidateOptState();
+        }
     }
 
-    const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
-
-    GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
+    GrStencilSettings* stencil() { return &fStencilSettings; }
 
     /// @}
 
@@ -712,48 +445,11 @@
     /// @name State Flags
     ////
 
-    /**
-     *  Flags that affect rendering. Controlled using enable/disableState(). All
-     *  default to disabled.
-     */
-    enum StateBits {
-        /**
-         * Perform dithering. TODO: Re-evaluate whether we need this bit
-         */
-        kDither_StateBit        = 0x01,
-        /**
-         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
-         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
-         * the 3D API.
-         */
-        kHWAntialias_StateBit   = 0x02,
-        /**
-         * Draws will respect the clip, otherwise the clip is ignored.
-         */
-        kClip_StateBit          = 0x04,
-        /**
-         * Disables writing to the color buffer. Useful when performing stencil
-         * operations.
-         */
-        kNoColorWrites_StateBit = 0x08,
-
-        /**
-         * Usually coverage is applied after color blending. The color is blended using the coeffs
-         * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
-         * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
-         * this case there is no distinction between coverage and color and the caller needs direct
-         * control over the blend coeffs. When set, there will be a single blend step controlled by
-         * setBlendFunc() which will use coverage*color as the src color.
-         */
-         kCoverageDrawing_StateBit = 0x10,
-
-        // Users of the class may add additional bits to the vector
-        kDummyStateBit,
-        kLastPublicStateBit = kDummyStateBit-1,
-    };
-
     void resetStateFlags() {
-        fCommon.fFlagBits = 0;
+        if (0 != fFlagBits) {
+            fFlagBits = 0;
+            this->invalidateOptState();
+        }
     }
 
     /**
@@ -762,7 +458,10 @@
      * @param stateBits bitfield of StateBits specifying the states to enable
      */
     void enableState(uint32_t stateBits) {
-        fCommon.fFlagBits |= stateBits;
+        if (stateBits & ~fFlagBits) {
+            fFlagBits |= stateBits;
+            this->invalidateOptState();
+        }
     }
 
     /**
@@ -771,7 +470,10 @@
      * @param stateBits bitfield of StateBits specifying the states to disable
      */
     void disableState(uint32_t stateBits) {
-        fCommon.fFlagBits &= ~(stateBits);
+        if (stateBits & fFlagBits) {
+            fFlagBits &= ~(stateBits);
+            this->invalidateOptState();
+        }
     }
 
     /**
@@ -788,276 +490,78 @@
         }
     }
 
-    bool isDitherState() const {
-        return 0 != (fCommon.fFlagBits & kDither_StateBit);
-    }
-
-    bool isHWAntialiasState() const {
-        return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
-    }
-
-    bool isClipState() const {
-        return 0 != (fCommon.fFlagBits & kClip_StateBit);
-    }
-
-    bool isColorWriteDisabled() const {
-        return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
-    }
-
-    bool isCoverageDrawing() const {
-        return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
-    }
-
-    bool isStateFlagEnabled(uint32_t stateBit) const {
-        return 0 != (stateBit & fCommon.fFlagBits);
-    }
-
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
     /// @name Face Culling
     ////
 
-    enum DrawFace {
-        kInvalid_DrawFace = -1,
-
-        kBoth_DrawFace,
-        kCCW_DrawFace,
-        kCW_DrawFace,
-    };
-
     /**
      * Controls whether clockwise, counterclockwise, or both faces are drawn.
      * @param face  the face(s) to draw.
      */
     void setDrawFace(DrawFace face) {
         SkASSERT(kInvalid_DrawFace != face);
-        fCommon.fDrawFace = face;
+        fDrawFace = face;
     }
 
-    /**
-     * Gets whether the target is drawing clockwise, counterclockwise,
-     * or both faces.
-     * @return the current draw face(s).
-     */
-    DrawFace getDrawFace() const { return fCommon.fDrawFace; }
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Hints
+    /// Hints that when provided can enable optimizations.
+    ////
+
+    void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); }
 
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
 
-    bool operator ==(const GrDrawState& s) const {
-        if (fRenderTarget.get() != s.fRenderTarget.get() ||
-            fColorStages.count() != s.fColorStages.count() ||
-            fCoverageStages.count() != s.fCoverageStages.count() ||
-            fCommon != s.fCommon) {
-            return false;
-        }
-        for (int i = 0; i < fColorStages.count(); i++) {
-            if (fColorStages[i] != s.fColorStages[i]) {
-                return false;
-            }
-        }
-        for (int i = 0; i < fCoverageStages.count(); i++) {
-            if (fCoverageStages[i] != s.fCoverageStages[i]) {
-                return false;
-            }
-        }
-        return true;
-    }
-    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
-
-    GrDrawState& operator= (const GrDrawState& s) {
-        SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
-        this->setRenderTarget(s.fRenderTarget.get());
-        fCommon = s.fCommon;
-        fColorStages = s.fColorStages;
-        fCoverageStages = s.fCoverageStages;
-        return *this;
-    }
-
-private:
-
-    void onReset(const SkMatrix* initialViewMatrix) {
-        SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
-        fColorStages.reset();
-        fCoverageStages.reset();
-
-        fRenderTarget.reset(NULL);
-
-        this->setDefaultVertexAttribs();
-
-        fCommon.fColor = 0xffffffff;
-        if (NULL == initialViewMatrix) {
-            fCommon.fViewMatrix.reset();
-        } else {
-            fCommon.fViewMatrix = *initialViewMatrix;
-        }
-        fCommon.fSrcBlend = kOne_GrBlendCoeff;
-        fCommon.fDstBlend = kZero_GrBlendCoeff;
-        fCommon.fBlendConstant = 0x0;
-        fCommon.fFlagBits = 0x0;
-        fCommon.fStencilSettings.setDisabled();
-        fCommon.fCoverage = 0xffffffff;
-        fCommon.fDrawFace = kBoth_DrawFace;
-    }
-
-    /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
-    struct CommonState {
-        // These fields are roughly sorted by decreasing likelihood of being different in op==
-        GrColor               fColor;
-        SkMatrix              fViewMatrix;
-        GrBlendCoeff          fSrcBlend;
-        GrBlendCoeff          fDstBlend;
-        GrColor               fBlendConstant;
-        uint32_t              fFlagBits;
-        const GrVertexAttrib* fVAPtr;
-        int                   fVACount;
-        GrStencilSettings     fStencilSettings;
-        GrColor               fCoverage;
-        DrawFace              fDrawFace;
-
-        // This is simply a different representation of info in fVertexAttribs and thus does
-        // not need to be compared in op==.
-        int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
-
-        bool operator== (const CommonState& other) const {
-            bool result = fColor == other.fColor &&
-                          fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
-                          fSrcBlend == other.fSrcBlend &&
-                          fDstBlend == other.fDstBlend &&
-                          fBlendConstant == other.fBlendConstant &&
-                          fFlagBits == other.fFlagBits &&
-                          fVACount == other.fVACount &&
-                          !memcmp(fVAPtr, other.fVAPtr, fVACount * sizeof(GrVertexAttrib)) &&
-                          fStencilSettings == other.fStencilSettings &&
-                          fCoverage == other.fCoverage &&
-                          fDrawFace == other.fDrawFace;
-            SkASSERT(!result || 0 == memcmp(fFixedFunctionVertexAttribIndices,
-                                            other.fFixedFunctionVertexAttribIndices,
-                                            sizeof(fFixedFunctionVertexAttribIndices)));
-            return result;
-        }
-        bool operator!= (const CommonState& other) const { return !(*this == other); }
+    /** Return type for CombineIfPossible. */
+    enum CombinedState {
+        /** The GrDrawStates cannot be combined. */
+        kIncompatible_CombinedState,
+        /** Either draw state can be used in place of the other. */
+        kAOrB_CombinedState,
+        /** Use the first draw state. */
+        kA_CombinedState,
+        /** Use the second draw state. */
+        kB_CombinedState,
     };
 
-    /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
-        DeferredState must directly reference GrEffects, however. */
-    struct SavedEffectStage {
-        SavedEffectStage() : fEffect(NULL) {}
-        const GrEffect*                    fEffect;
-        GrEffectStage::SavedCoordChange    fCoordChange;
-    };
+    /** This function determines whether the GrDrawStates used for two draws can be combined into
+        a single GrDrawState. This is used to avoid storing redundant GrDrawStates and to determine
+        if draws can be batched. The return value indicates whether combining is possible and, if
+        so, which of the two inputs should be used. */
+    static CombinedState CombineIfPossible(const GrDrawState& a, const GrDrawState& b,
+                                           const GrDrawTargetCaps& caps);
 
-public:
+    GrDrawState& operator= (const GrDrawState& that);
+
     /**
-     * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
-     * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
-     * dispose mechanism returns them to the cache. This allows recycling resources through the
-     * the cache while they are in a deferred draw queue.
+     * Returns a snapshot of the current optimized state. If the current drawState has a valid
+     * cached optimiezed state it will simply return a pointer to it otherwise it will create a new
+     * GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the
+     * caller.
      */
-    class DeferredState {
-    public:
-        DeferredState() : fRenderTarget(NULL) {
-            SkDEBUGCODE(fInitialized = false;)
-        }
-        // TODO: Remove this when DeferredState no longer holds a ref to the RT
-        ~DeferredState() { SkSafeUnref(fRenderTarget); }
-
-        void saveFrom(const GrDrawState& drawState) {
-            fCommon = drawState.fCommon;
-            // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
-            fRenderTarget = drawState.fRenderTarget.get();
-            SkSafeRef(fRenderTarget);
-            // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
-            // ref gets fully unref'ed it will cause the underlying effect to unref its resources
-            // and recycle them to the cache (if no one else is holding a ref to the resources).
-            fStages.reset(drawState.fColorStages.count() + drawState.fCoverageStages.count());
-            fColorStageCnt = drawState.fColorStages.count();
-            for (int i = 0; i < fColorStageCnt; ++i) {
-                fStages[i].saveFrom(drawState.fColorStages[i]);
-            }
-            for (int i = 0; i < drawState.fCoverageStages.count(); ++i) {
-                fStages[i + fColorStageCnt].saveFrom(drawState.fCoverageStages[i]);
-            }
-            SkDEBUGCODE(fInitialized = true;)
-        }
-
-        void restoreTo(GrDrawState* drawState) {
-            SkASSERT(fInitialized);
-            drawState->fCommon = fCommon;
-            drawState->setRenderTarget(fRenderTarget);
-            // reinflate color/cov stage arrays.
-            drawState->fColorStages.reset();
-            for (int i = 0; i < fColorStageCnt; ++i) {
-                SkNEW_APPEND_TO_TARRAY(&drawState->fColorStages, GrEffectStage, (fStages[i]));
-            }
-            int coverageStageCnt = fStages.count() - fColorStageCnt;
-            drawState->fCoverageStages.reset();
-            for (int i = 0; i < coverageStageCnt; ++i) {
-                SkNEW_APPEND_TO_TARRAY(&drawState->fCoverageStages,
-                                        GrEffectStage, (fStages[i + fColorStageCnt]));
-            }
-        }
-
-        bool isEqual(const GrDrawState& state) const {
-            int numCoverageStages = fStages.count() - fColorStageCnt;
-            if (fRenderTarget != state.fRenderTarget.get() ||
-                fColorStageCnt != state.fColorStages.count() ||
-                numCoverageStages != state.fCoverageStages.count() ||
-                fCommon != state.fCommon) {
-                return false;
-            }
-            bool explicitLocalCoords = state.hasLocalCoordAttribute();
-            for (int i = 0; i < fColorStageCnt; ++i) {
-                if (!fStages[i].isEqual(state.fColorStages[i], explicitLocalCoords)) {
-                    return false;
-                }
-            }
-            for (int i = 0; i < numCoverageStages; ++i) {
-                int s = fColorStageCnt + i;
-                if (!fStages[s].isEqual(state.fCoverageStages[i], explicitLocalCoords)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-    private:
-        typedef SkAutoSTArray<8, GrEffectStage::DeferredStage> DeferredStageArray;
-
-        GrRenderTarget*                       fRenderTarget;
-        CommonState                           fCommon;
-        int                                   fColorStageCnt;
-        DeferredStageArray                    fStages;
-
-        SkDEBUGCODE(bool fInitialized;)
-    };
+    GrOptDrawState* createOptState(const GrDrawTargetCaps&) const;
 
 private:
+    void invalidateOptState() const;
 
-    SkAutoTUnref<GrRenderTarget>        fRenderTarget;
-    CommonState                         fCommon;
-
-    typedef SkSTArray<4, GrEffectStage> EffectStageArray;
-    EffectStageArray                    fColorStages;
-    EffectStageArray                    fCoverageStages;
+    void onReset(const SkMatrix* initialViewMatrix);
 
     // Some of the auto restore objects assume that no effects are removed during their lifetime.
     // This is used to assert that this condition holds.
     SkDEBUGCODE(int fBlockEffectRemovalCnt;)
 
-    /**
-     *  Sets vertex attributes for next draw.
-     *
-     *  @param attribs    the array of vertex attributes to set.
-     *  @param count      the number of attributes being set, limited to kMaxVertexAttribCnt.
-     */
-    void setVertexAttribs(const GrVertexAttrib attribs[], int count);
+    void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride);
 
-    typedef SkRefCnt INHERITED;
+    mutable GrOptDrawState* fCachedOptState;
+    mutable uint32_t fCachedCapsID;
+
+    typedef GrRODrawState INHERITED;
 };
 
-GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
-
 #endif
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 7cdb743..eb89915 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -13,6 +13,7 @@
 #include "GrDrawTargetCaps.h"
 #include "GrPath.h"
 #include "GrRenderTarget.h"
+#include "GrTemplates.h"
 #include "GrTexture.h"
 #include "GrVertexBuffer.h"
 
@@ -31,7 +32,7 @@
     fVerticesPerInstance    = di.fVerticesPerInstance;
     fIndicesPerInstance     = di.fIndicesPerInstance;
 
-    if (NULL != di.fDevBounds) {
+    if (di.fDevBounds) {
         SkASSERT(di.fDevBounds == &di.fDevBoundsStorage);
         fDevBoundsStorage = di.fDevBoundsStorage;
         fDevBounds = &fDevBoundsStorage;
@@ -90,7 +91,7 @@
     : fClip(NULL)
     , fContext(context)
     , fGpuTraceMarkerCount(0) {
-    SkASSERT(NULL != context);
+    SkASSERT(context);
 
     fDrawState = &fDefaultDrawState;
     // We assume that fDrawState always owns a ref to the object it points at.
@@ -134,7 +135,7 @@
 }
 
 void GrDrawTarget::setDrawState(GrDrawState*  drawState) {
-    SkASSERT(NULL != fDrawState);
+    SkASSERT(fDrawState);
     if (NULL == drawState) {
         drawState = &fDefaultDrawState;
     }
@@ -151,7 +152,7 @@
     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
     bool acquired = false;
     if (vertexCount > 0) {
-        SkASSERT(NULL != vertices);
+        SkASSERT(vertices);
         this->releasePreviousVertexSource();
         geoSrc.fVertexSrc = kNone_GeometrySrcType;
 
@@ -163,7 +164,7 @@
         geoSrc.fVertexSrc = kReserved_GeometrySrcType;
         geoSrc.fVertexCount = vertexCount;
         geoSrc.fVertexSize = vertexSize;
-    } else if (NULL != vertices) {
+    } else if (vertices) {
         *vertices = NULL;
     }
     return acquired;
@@ -174,7 +175,7 @@
     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
     bool acquired = false;
     if (indexCount > 0) {
-        SkASSERT(NULL != indices);
+        SkASSERT(indices);
         this->releasePreviousIndexSource();
         geoSrc.fIndexSrc = kNone_GeometrySrcType;
 
@@ -183,7 +184,7 @@
     if (acquired) {
         geoSrc.fIndexSrc = kReserved_GeometrySrcType;
         geoSrc.fIndexCount = indexCount;
-    } else if (NULL != indices) {
+    } else if (indices) {
         *indices = NULL;
     }
     return acquired;
@@ -194,10 +195,10 @@
                                               int indexCount,
                                               void** vertices,
                                               void** indices) {
-    size_t vertexSize = this->drawState()->getVertexSize();
+    size_t vertexStride = this->drawState()->getVertexStride();
     this->willReserveVertexAndIndexSpace(vertexCount, indexCount);
     if (vertexCount) {
-        if (!this->reserveVertexSpace(vertexSize, vertexCount, vertices)) {
+        if (!this->reserveVertexSpace(vertexStride, vertexCount, vertices)) {
             if (indexCount) {
                 this->resetIndexSource();
             }
@@ -217,10 +218,10 @@
 
 bool GrDrawTarget::geometryHints(int32_t* vertexCount,
                                  int32_t* indexCount) const {
-    if (NULL != vertexCount) {
+    if (vertexCount) {
         *vertexCount = -1;
     }
-    if (NULL != indexCount) {
+    if (indexCount) {
         *indexCount = -1;
     }
     return false;
@@ -277,7 +278,7 @@
     this->releasePreviousVertexSource();
     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
     geoSrc.fVertexSrc = kArray_GeometrySrcType;
-    geoSrc.fVertexSize = this->drawState()->getVertexSize();
+    geoSrc.fVertexSize = this->drawState()->getVertexStride();
     geoSrc.fVertexCount = vertexCount;
     this->onSetVertexSourceToArray(vertexArray, vertexCount);
 }
@@ -297,7 +298,7 @@
     geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
     geoSrc.fVertexBuffer = buffer;
     buffer->ref();
-    geoSrc.fVertexSize = this->drawState()->getVertexSize();
+    geoSrc.fVertexSize = this->drawState()->getVertexStride();
 }
 
 void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
@@ -386,10 +387,19 @@
         }
     }
 
-    SkASSERT(NULL != drawState.getRenderTarget());
+    SkASSERT(drawState.getRenderTarget());
+
+    if (drawState.hasGeometryProcessor()) {
+        const GrGeometryProcessor* gp = drawState.getGeometryProcessor()->getGeometryProcessor();
+        int numTextures = gp->numTextures();
+        for (int t = 0; t < numTextures; ++t) {
+            GrTexture* texture = gp->texture(t);
+            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
+        }
+    }
 
     for (int s = 0; s < drawState.numColorStages(); ++s) {
-        const GrEffectRef& effect = *drawState.getColorStage(s).getEffect();
+        const GrProcessor* effect = drawState.getColorStage(s).getProcessor();
         int numTextures = effect->numTextures();
         for (int t = 0; t < numTextures; ++t) {
             GrTexture* texture = effect->texture(t);
@@ -397,7 +407,7 @@
         }
     }
     for (int s = 0; s < drawState.numCoverageStages(); ++s) {
-        const GrEffectRef& effect = *drawState.getCoverageStage(s).getEffect();
+        const GrProcessor* effect = drawState.getCoverageStage(s).getProcessor();
         int numTextures = effect->numTextures();
         for (int t = 0; t < numTextures; ++t) {
             GrTexture* texture = effect->texture(t);
@@ -422,7 +432,7 @@
     const GrClipData* clip = this->getClip();
     clip->getConservativeBounds(rt, &copyRect);
 
-    if (NULL != drawBounds) {
+    if (drawBounds) {
         SkIRect drawIBounds;
         drawBounds->roundOut(&drawIBounds);
         if (!copyRect.intersect(drawIBounds)) {
@@ -478,7 +488,7 @@
         info.fVerticesPerInstance   = 0;
         info.fIndicesPerInstance    = 0;
 
-        if (NULL != devBounds) {
+        if (devBounds) {
             info.setDevBounds(*devBounds);
         }
         // TODO: We should continue with incorrect blending.
@@ -505,7 +515,7 @@
         info.fVerticesPerInstance   = 0;
         info.fIndicesPerInstance    = 0;
 
-        if (NULL != devBounds) {
+        if (devBounds) {
             info.setDevBounds(*devBounds);
         }
         // TODO: We should continue with incorrect blending.
@@ -518,7 +528,7 @@
 
 void GrDrawTarget::stencilPath(const GrPath* path, SkPath::FillType fill) {
     // TODO: extract portions of checkDraw that are relevant to path stenciling.
-    SkASSERT(NULL != path);
+    SkASSERT(path);
     SkASSERT(this->caps()->pathRenderingSupport());
     SkASSERT(!SkPath::IsInverseFillType(fill));
     this->onStencilPath(path, fill);
@@ -526,7 +536,7 @@
 
 void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) {
     // TODO: extract portions of checkDraw that are relevant to path rendering.
-    SkASSERT(NULL != path);
+    SkASSERT(path);
     SkASSERT(this->caps()->pathRenderingSupport());
     const GrDrawState* drawState = &getDrawState();
 
@@ -548,33 +558,25 @@
     this->onDrawPath(path, fill, dstCopy.texture() ? &dstCopy : NULL);
 }
 
-void GrDrawTarget::drawPaths(int pathCount, const GrPath** paths,
-                             const SkMatrix* transforms,
-                             SkPath::FillType fill, SkStrokeRec::Style stroke) {
-    SkASSERT(pathCount > 0);
-    SkASSERT(NULL != paths);
-    SkASSERT(NULL != paths[0]);
+void GrDrawTarget::drawPaths(const GrPathRange* pathRange,
+                             const uint32_t indices[], int count,
+                             const float transforms[], PathTransformType transformsType,
+                             SkPath::FillType fill) {
     SkASSERT(this->caps()->pathRenderingSupport());
-    SkASSERT(!SkPath::IsInverseFillType(fill));
+    SkASSERT(pathRange);
+    SkASSERT(indices);
+    SkASSERT(transforms);
 
-    const GrDrawState* drawState = &getDrawState();
-
-    SkRect devBounds;
-    for (int i = 0; i < pathCount; ++i) {
-        SkRect mappedPathBounds;
-        transforms[i].mapRect(&mappedPathBounds, paths[i]->getBounds());
-        devBounds.join(mappedPathBounds);
-    }
-
-    SkMatrix viewM = drawState->getViewMatrix();
-    viewM.mapRect(&devBounds);
-
+    // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt
+    // instead for it to just copy the entire dst. Realistically this is a moot
+    // point, because any context that supports NV_path_rendering will also
+    // support NV_blend_equation_advanced.
     GrDeviceCoordTexture dstCopy;
-    if (!this->setupDstReadIfNecessary(&dstCopy, &devBounds)) {
+    if (!this->setupDstReadIfNecessary(&dstCopy, NULL)) {
         return;
     }
 
-    this->onDrawPaths(pathCount, paths, transforms, fill, stroke,
+    this->onDrawPaths(pathRange, indices, count, transforms, transformsType, fill,
                       dstCopy.texture() ? &dstCopy : NULL);
 }
 
@@ -621,28 +623,6 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-bool GrDrawTarget::willUseHWAALines() const {
-    // There is a conflict between using smooth lines and our use of premultiplied alpha. Smooth
-    // lines tweak the incoming alpha value but not in a premul-alpha way. So we only use them when
-    // our alpha is 0xff and tweaking the color for partial coverage is OK
-    if (!this->caps()->hwAALineSupport() ||
-        !this->getDrawState().isHWAntialiasState()) {
-        return false;
-    }
-    GrDrawState::BlendOptFlags opts = this->getDrawState().getBlendOpts();
-    return (GrDrawState::kDisableBlend_BlendOptFlag & opts) &&
-           (GrDrawState::kCoverageAsAlpha_BlendOptFlag & opts);
-}
-
-bool GrDrawTarget::canApplyCoverage() const {
-    // we can correctly apply coverage if a) we have dual source blending
-    // or b) one of our blend optimizations applies.
-    return this->caps()->dualSourceBlendingSupport() ||
-           GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
                                         int instanceCount,
                                         int verticesPerInstance,
@@ -665,7 +645,7 @@
     info.fVerticesPerInstance = verticesPerInstance;
 
     // Set the same bounds for all the draws.
-    if (NULL != devBounds) {
+    if (devBounds) {
         info.setDevBounds(*devBounds);
     }
     // TODO: We should continue with incorrect blending.
@@ -702,25 +682,19 @@
 
 void set_vertex_attributes(GrDrawState* drawState, bool hasUVs) {
     if (hasUVs) {
-        drawState->setVertexAttribs<gBWRectPosUVAttribs>(2);
+        drawState->setVertexAttribs<gBWRectPosUVAttribs>(2, 2 * sizeof(SkPoint));
     } else {
-        drawState->setVertexAttribs<gBWRectPosUVAttribs>(1);
+        drawState->setVertexAttribs<gBWRectPosUVAttribs>(1, sizeof(SkPoint));
     }
 }
 
 };
 
 void GrDrawTarget::onDrawRect(const SkRect& rect,
-                              const SkMatrix* matrix,
                               const SkRect* localRect,
                               const SkMatrix* localMatrix) {
 
-    GrDrawState::AutoViewMatrixRestore avmr;
-    if (NULL != matrix) {
-        avmr.set(this->drawState(), *matrix);
-    }
-
-    set_vertex_attributes(this->drawState(), NULL != localRect);
+    set_vertex_attributes(this->drawState(), SkToBool(localRect));
 
     AutoReleaseGeometry geo(this, 4, 0);
     if (!geo.succeeded()) {
@@ -728,16 +702,16 @@
         return;
     }
 
-    size_t vsize = this->drawState()->getVertexSize();
-    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
-    if (NULL != localRect) {
+    size_t vstride = this->drawState()->getVertexStride();
+    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
+    if (localRect) {
         SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) +
                                             sizeof(SkPoint));
         coords->setRectFan(localRect->fLeft, localRect->fTop,
                            localRect->fRight, localRect->fBottom,
-                           vsize);
-        if (NULL != localMatrix) {
-            localMatrix->mapPointsWithStride(coords, vsize, 4);
+                           vstride);
+        if (localMatrix) {
+            localMatrix->mapPointsWithStride(coords, vstride, 4);
         }
     }
     SkRect bounds;
@@ -763,7 +737,7 @@
 }
 
 GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
-    if (NULL != fDrawTarget) {
+    if (fDrawTarget) {
         fDrawTarget->setDrawState(fSavedState);
         fSavedState->unref();
     }
@@ -843,8 +817,7 @@
     this->reset();
     fTarget = target;
     bool success = true;
-    if (NULL != fTarget) {
-        fTarget = target;
+    if (fTarget) {
         success = target->reserveVertexAndIndexSpace(vertexCount,
                                                      indexCount,
                                                      &fVertices,
@@ -854,16 +827,16 @@
             this->reset();
         }
     }
-    SkASSERT(success == (NULL != fTarget));
+    SkASSERT(success == SkToBool(fTarget));
     return success;
 }
 
 void GrDrawTarget::AutoReleaseGeometry::reset() {
-    if (NULL != fTarget) {
-        if (NULL != fVertices) {
+    if (fTarget) {
+        if (fVertices) {
             fTarget->resetVertexSource();
         }
-        if (NULL != fIndices) {
+        if (fIndices) {
             fTarget->resetIndexSource();
         }
         fTarget = NULL;
@@ -938,8 +911,8 @@
                                GrSurface* src,
                                const SkIRect& srcRect,
                                const SkIPoint& dstPoint) {
-    SkASSERT(NULL != dst);
-    SkASSERT(NULL != src);
+    SkASSERT(dst);
+    SkASSERT(src);
 
     SkIRect clippedSrcRect;
     SkIPoint clippedDstPoint;
@@ -963,8 +936,8 @@
                                   GrSurface* src,
                                   const SkIRect& srcRect,
                                   const SkIPoint& dstPoint) {
-    SkASSERT(NULL != dst);
-    SkASSERT(NULL != src);
+    SkASSERT(dst);
+    SkASSERT(src);
 
     SkIRect clippedSrcRect;
     SkIPoint clippedDstPoint;
@@ -991,7 +964,7 @@
     SkASSERT(dstPoint.fX + srcRect.width() <= dst->width() &&
              dstPoint.fY + srcRect.height() <= dst->height());
 
-    return !dst->isSameAs(src) && NULL != dst->asRenderTarget() && NULL != src->asTexture();
+    return !dst->isSameAs(src) && dst->asRenderTarget() && src->asTexture();
 }
 
 bool GrDrawTarget::onCopySurface(GrSurface* dst,
@@ -1011,7 +984,7 @@
     matrix.setTranslate(SkIntToScalar(srcRect.fLeft - dstPoint.fX),
                         SkIntToScalar(srcRect.fTop - dstPoint.fY));
     matrix.postIDiv(tex->width(), tex->height());
-    this->drawState()->addColorTextureEffect(tex, matrix);
+    this->drawState()->addColorTextureProcessor(tex, matrix);
     SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX,
                                         dstPoint.fY,
                                         srcRect.width(),
@@ -1043,6 +1016,7 @@
     fDiscardRenderTargetSupport = false;
     fReuseScratchTextures = true;
     fGpuTracingSupport = false;
+    fCompressedTexSubImageSupport = false;
 
     fMapBufferFlags = kNone_MapFlags;
 
@@ -1068,6 +1042,7 @@
     fDiscardRenderTargetSupport = other.fDiscardRenderTargetSupport;
     fReuseScratchTextures = other.fReuseScratchTextures;
     fGpuTracingSupport = other.fGpuTracingSupport;
+    fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport;
 
     fMapBufferFlags = other.fMapBufferFlags;
 
@@ -1117,6 +1092,7 @@
     r.appendf("Discard Render Target Support: %s\n", gNY[fDiscardRenderTargetSupport]);
     r.appendf("Reuse Scratch Textures       : %s\n", gNY[fReuseScratchTextures]);
     r.appendf("Gpu Tracing Support          : %s\n", gNY[fGpuTracingSupport]);
+    r.appendf("Compressed Update Support    : %s\n", gNY[fCompressedTexSubImageSupport]);
     r.appendf("Max Texture Size             : %d\n", fMaxTextureSize);
     r.appendf("Max Render Target Size       : %d\n", fMaxRenderTargetSize);
     r.appendf("Max Sample Count             : %d\n", fMaxSampleCount);
@@ -1133,16 +1109,22 @@
         "BGRA8888", // kBGRA_8888_GrPixelConfig,
         "ETC1",     // kETC1_GrPixelConfig,
         "LATC",     // kLATC_GrPixelConfig,
+        "R11EAC",   // kR11_EAC_GrPixelConfig,
+        "ASTC12x12",// kASTC_12x12_GrPixelConfig,
+        "RGBAFloat",  // kRGBA_float_GrPixelConfig
     };
-    GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig);
-    GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig);
-    GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig);
-    GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig);
-    GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig);
-    GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(7 == kETC1_GrPixelConfig);
-    GR_STATIC_ASSERT(8 == kLATC_GrPixelConfig);
+    GR_STATIC_ASSERT(0  == kUnknown_GrPixelConfig);
+    GR_STATIC_ASSERT(1  == kAlpha_8_GrPixelConfig);
+    GR_STATIC_ASSERT(2  == kIndex_8_GrPixelConfig);
+    GR_STATIC_ASSERT(3  == kRGB_565_GrPixelConfig);
+    GR_STATIC_ASSERT(4  == kRGBA_4444_GrPixelConfig);
+    GR_STATIC_ASSERT(5  == kRGBA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(6  == kBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(7  == kETC1_GrPixelConfig);
+    GR_STATIC_ASSERT(8  == kLATC_GrPixelConfig);
+    GR_STATIC_ASSERT(9  == kR11_EAC_GrPixelConfig);
+    GR_STATIC_ASSERT(10 == kASTC_12x12_GrPixelConfig);
+    GR_STATIC_ASSERT(11 == kRGBA_float_GrPixelConfig);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
 
     SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][0]);
@@ -1165,3 +1147,13 @@
 
     return r;
 }
+
+uint32_t GrDrawTargetCaps::CreateUniqueID() {
+    static int32_t gUniqueID = SK_InvalidUniqueID;
+    uint32_t id;
+    do {
+        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
+    } while (id == SK_InvalidUniqueID);
+    return id;
+}
+
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 7898dfd..8ffc681 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -12,6 +12,7 @@
 #include "GrContext.h"
 #include "GrDrawState.h"
 #include "GrIndexBuffer.h"
+#include "GrPathRendering.h"
 #include "GrTraceMarker.h"
 
 #include "SkClipStack.h"
@@ -26,6 +27,7 @@
 class GrClipData;
 class GrDrawTargetCaps;
 class GrPath;
+class GrPathRange;
 class GrVertexBuffer;
 
 class GrDrawTarget : public SkRefCnt {
@@ -35,6 +37,9 @@
 public:
     SK_DECLARE_INST_COUNT(GrDrawTarget)
 
+
+    typedef GrPathRendering::PathTransformType PathTransformType ;
+
     ///////////////////////////////////////////////////////////////////////////
 
     // The context may not be fully constructed and should not be used during GrDrawTarget
@@ -83,41 +88,16 @@
      */
     GrDrawState* drawState() { return fDrawState; }
 
-    /**
-     * Color alpha and coverage are two inputs to the drawing pipeline. For some
-     * blend modes it is safe to fold the coverage into constant or per-vertex
-     * color alpha value. For other blend modes they must be handled separately.
-     * Depending on features available in the underlying 3D API this may or may
-     * not be possible.
-     *
-     * This function considers the current draw state and the draw target's
-     * capabilities to determine whether coverage can be handled correctly. The
-     * following assumptions are made:
-     *    1. The caller intends to somehow specify coverage. This can be
-     *       specified either by enabling a coverage stage on the GrDrawState or
-     *       via the vertex layout.
-     *    2. Other than enabling coverage stages or enabling coverage in the
-     *       layout, the current configuration of the target's GrDrawState is as
-     *       it will be at draw time.
-     */
-    bool canApplyCoverage() const;
-
     /** When we're using coverage AA but the blend is incompatible (given gpu
      * limitations) we should disable AA. */
-    bool shouldDisableCoverageAAForBlend() {
+    bool shouldDisableCoverageAAForBlend() const {
         // Enable below if we should draw with AA even when it produces
         // incorrect blending.
         // return false;
-        return !this->canApplyCoverage();
+        return !this->getDrawState().couldApplyCoverage(*this->caps());
     }
 
     /**
-     * Given the current draw state and hw support, will HW AA lines be used (if
-     * a line primitive type is drawn)?
-     */
-    bool willUseHWAALines() const;
-
-    /**
      * There are three types of "sources" of geometry (vertices and indices) for
      * draw calls made on the target. When performing an indexed draw, the
      * indices and vertices can use different source types. Once a source is
@@ -349,21 +329,24 @@
      * Draws many paths. It will respect the HW
      * antialias flag on the draw state (if possible in the 3D API).
      *
-     * @param transforms array of 2d affine transformations, one for each path.
-     * @param fill the fill type for drawing all the paths. Fill must not be a
-     *             hairline.
-     * @param stroke the stroke for drawing all the paths.
+     * @param pathRange       Source of paths to draw from
+     * @param indices         Array of indices into the the pathRange
+     * @param count           Number of paths to draw (length of indices array)
+     * @param transforms      Array of individual transforms, one for each path
+     * @param transformsType  Type of transformations in the array. Array contains
+                              PathTransformSize(transformsType) * count elements
+     * @param fill            Fill type for drawing all the paths
      */
-    void drawPaths(int pathCount, const GrPath** paths,
-                   const SkMatrix* transforms, SkPath::FillType fill,
-                   SkStrokeRec::Style stroke);
+    void drawPaths(const GrPathRange* pathRange,
+                   const uint32_t indices[], int count,
+                   const float transforms[], PathTransformType transformsType,
+                   SkPath::FillType fill);
 
     /**
      * Helper function for drawing rects. It performs a geometry src push and pop
      * and thus will finalize any reserved geometry.
      *
      * @param rect        the rect to draw
-     * @param matrix      optional matrix applied to rect (before viewMatrix)
      * @param localRect   optional rect that specifies local coords to map onto
      *                    rect. If NULL then rect serves as the local coords.
      * @param localMatrix optional matrix applied to localRect. If
@@ -372,22 +355,21 @@
      *                    srcMatrix can be NULL when no srcMatrix is desired.
      */
     void drawRect(const SkRect& rect,
-                  const SkMatrix* matrix,
                   const SkRect* localRect,
                   const SkMatrix* localMatrix) {
         AutoGeometryPush agp(this);
-        this->onDrawRect(rect, matrix, localRect, localMatrix);
+        this->onDrawRect(rect, localRect, localMatrix);
     }
 
     /**
      * Helper for drawRect when the caller doesn't need separate local rects or matrices.
      */
-    void drawSimpleRect(const SkRect& rect, const SkMatrix* matrix = NULL) {
-        this->drawRect(rect, matrix, NULL, NULL);
+    void drawSimpleRect(const SkRect& rect) {
+        this->drawRect(rect, NULL, NULL);
     }
-    void drawSimpleRect(const SkIRect& irect, const SkMatrix* matrix = NULL) {
+    void drawSimpleRect(const SkIRect& irect) {
         SkRect rect = SkRect::Make(irect);
-        this->drawRect(rect, matrix, NULL, NULL);
+        this->drawRect(rect, NULL, NULL);
     }
 
     /**
@@ -516,17 +498,13 @@
     /**
      * For subclass internal use to invoke a call to onDrawPaths().
      */
-    void executeDrawPaths(int pathCount, const GrPath** paths,
-                          const SkMatrix* transforms, SkPath::FillType fill,
-                          SkStrokeRec::Style stroke,
+    void executeDrawPaths(const GrPathRange* pathRange,
+                          const uint32_t indices[], int count,
+                          const float transforms[], PathTransformType transformsType,
+                          SkPath::FillType fill,
                           const GrDeviceCoordTexture* dstCopy) {
-        this->onDrawPaths(pathCount, paths, transforms, fill, stroke, dstCopy);
+        this->onDrawPaths(pathRange, indices, count, transforms, transformsType, fill, dstCopy);
     }
-
-    inline bool isGpuTracingEnabled() const {
-        return this->getContext()->isGpuTracingEnabled();
-    }
-
     ////////////////////////////////////////////////////////////////////////////
 
     /**
@@ -615,7 +593,7 @@
         bool set(GrDrawTarget*  target,
                  int            vertexCount,
                  int            indexCount);
-        bool succeeded() const { return NULL != fTarget; }
+        bool succeeded() const { return SkToBool(fTarget); }
         void* vertices() const { SkASSERT(this->succeeded()); return fVertices; }
         void* indices() const { SkASSERT(this->succeeded()); return fIndices; }
         SkPoint* positions() const {
@@ -661,7 +639,7 @@
     public:
         AutoGeometryPush(GrDrawTarget* target)
             : fAttribRestore(target->drawState()) {
-            SkASSERT(NULL != target);
+            SkASSERT(target);
             fTarget = target;
             target->pushGeometrySource();
         }
@@ -683,7 +661,7 @@
                                  ASRInit init,
                                  const SkMatrix* viewMatrix = NULL)
             : fState(target, init, viewMatrix) {
-            SkASSERT(NULL != target);
+            SkASSERT(target);
             fTarget = target;
             target->pushGeometrySource();
             if (kPreserve_ASRInit == init) {
@@ -705,7 +683,7 @@
         DrawToken(GrDrawTarget* drawTarget, uint32_t drawID) :
                   fDrawTarget(drawTarget), fDrawID(drawID) {}
 
-        bool isIssued() { return NULL != fDrawTarget && fDrawTarget->isIssued(fDrawID); }
+        bool isIssued() { return fDrawTarget && fDrawTarget->isIssued(fDrawID); }
 
     private:
         GrDrawTarget*  fDrawTarget;
@@ -716,6 +694,10 @@
     virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
 
 protected:
+    // Extend access to GrRODrawState::convertToPEndeingExec to subclasses.
+    void convertDrawStateToPendingExec(GrRODrawState* ds) {
+        ds->convertToPendingExec();
+    }
 
     enum GeometrySrcType {
         kNone_GeometrySrcType,     //<! src has not been specified
@@ -844,7 +826,7 @@
 
         // NULL if no copy of the dst is needed for the draw.
         const GrDeviceCoordTexture* getDstCopy() const {
-            if (NULL != fDstCopy.texture()) {
+            if (fDstCopy.texture()) {
                 return &fDstCopy;
             } else {
                 return NULL;
@@ -902,16 +884,16 @@
     // drawIndexedInstances, ...). The base class draws a two triangle fan using
     // drawNonIndexed from reserved vertex space.
     virtual void onDrawRect(const SkRect& rect,
-                            const SkMatrix* matrix,
                             const SkRect* localRect,
                             const SkMatrix* localMatrix);
 
     virtual void onStencilPath(const GrPath*, SkPath::FillType) = 0;
     virtual void onDrawPath(const GrPath*, SkPath::FillType,
                             const GrDeviceCoordTexture* dstCopy) = 0;
-    virtual void onDrawPaths(int, const GrPath**, const SkMatrix*,
-                             SkPath::FillType, SkStrokeRec::Style,
-                             const GrDeviceCoordTexture* dstCopy) = 0;
+    virtual void onDrawPaths(const GrPathRange*,
+                             const uint32_t indices[], int count,
+                             const float transforms[], PathTransformType,
+                             SkPath::FillType, const GrDeviceCoordTexture*) = 0;
 
     virtual void didAddGpuTraceMarker() = 0;
     virtual void didRemoveGpuTraceMarker() = 0;
diff --git a/src/gpu/GrDrawTargetCaps.h b/src/gpu/GrDrawTargetCaps.h
index dcea79e..e468bc4 100644
--- a/src/gpu/GrDrawTargetCaps.h
+++ b/src/gpu/GrDrawTargetCaps.h
@@ -17,10 +17,14 @@
  */
 class GrDrawTargetCaps : public SkRefCnt {
 public:
-    SK_DECLARE_INST_COUNT(Caps)
+    SK_DECLARE_INST_COUNT(GrDrawTargetCaps)
 
-    GrDrawTargetCaps() { this->reset(); }
-    GrDrawTargetCaps(const GrDrawTargetCaps& other) : INHERITED() { *this = other; }
+    GrDrawTargetCaps() : fUniqueID(CreateUniqueID()) {
+        this->reset();
+    }
+    GrDrawTargetCaps(const GrDrawTargetCaps& other) : INHERITED(), fUniqueID(CreateUniqueID()) {
+        *this = other;
+    }
     GrDrawTargetCaps& operator= (const GrDrawTargetCaps&);
 
     virtual void reset();
@@ -40,6 +44,7 @@
     bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
     bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
     bool gpuTracingSupport() const { return fGpuTracingSupport; }
+    bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
 
     /**
      * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
@@ -76,6 +81,13 @@
         return fConfigTextureSupport[config];
     }
 
+    /**
+     * Gets an id that is unique for this GrDrawTargetCaps object. It is static in that it does
+     * not change when the content of the GrDrawTargetCaps object changes. This will never return
+     * 0.
+     */
+    uint32_t getUniqueID() const { return fUniqueID; }
+
 protected:
     bool fNPOTTextureTileSupport    : 1;
     bool fMipMapSupport             : 1;
@@ -90,6 +102,7 @@
     bool fDiscardRenderTargetSupport: 1;
     bool fReuseScratchTextures      : 1;
     bool fGpuTracingSupport         : 1;
+    bool fCompressedTexSubImageSupport : 1;
 
     uint32_t fMapBufferFlags;
 
@@ -101,6 +114,11 @@
     bool fConfigRenderSupport[kGrPixelConfigCnt][2];
     bool fConfigTextureSupport[kGrPixelConfigCnt];
 
+private:
+    static uint32_t CreateUniqueID();
+
+    const uint32_t          fUniqueID;
+
     typedef SkRefCnt INHERITED;
 };
 
diff --git a/src/gpu/SkGrFontScaler.cpp b/src/gpu/GrFontScaler.cpp
similarity index 83%
rename from src/gpu/SkGrFontScaler.cpp
rename to src/gpu/GrFontScaler.cpp
index 4485690..164768f 100644
--- a/src/gpu/SkGrFontScaler.cpp
+++ b/src/gpu/GrFontScaler.cpp
@@ -8,32 +8,14 @@
 
 
 #include "GrTemplates.h"
-#include "SkGr.h"
+#include "GrFontScaler.h"
 #include "SkDescriptor.h"
 #include "SkDistanceFieldGen.h"
 #include "SkGlyphCache.h"
 
-class SkGrDescKey : public GrKey {
-public:
-    explicit SkGrDescKey(const SkDescriptor& desc);
-    virtual ~SkGrDescKey();
-
-protected:
-    // overrides
-    virtual bool lt(const GrKey& rh) const;
-    virtual bool eq(const GrKey& rh) const;
-
-private:
-    SkDescriptor* fDesc;
-    enum {
-        kMaxStorageInts = 16
-    };
-    uint32_t fStorage[kMaxStorageInts];
-};
-
 ///////////////////////////////////////////////////////////////////////////////
 
-SkGrDescKey::SkGrDescKey(const SkDescriptor& desc) : GrKey(desc.getChecksum()) {
+GrFontDescKey::GrFontDescKey(const SkDescriptor& desc) : fHash(desc.getChecksum()) {
     size_t size = desc.getLength();
     if (size <= sizeof(fStorage)) {
         fDesc = GrTCast<SkDescriptor*>(fStorage);
@@ -43,14 +25,14 @@
     memcpy(fDesc, &desc, size);
 }
 
-SkGrDescKey::~SkGrDescKey() {
+GrFontDescKey::~GrFontDescKey() {
     if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
         SkDescriptor::Free(fDesc);
     }
 }
 
-bool SkGrDescKey::lt(const GrKey& rh) const {
-    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
+bool GrFontDescKey::lt(const GrFontDescKey& rh) const {
+    const SkDescriptor* srcDesc = (&rh)->fDesc;
     size_t lenLH = fDesc->getLength();
     size_t lenRH = srcDesc->getLength();
     int cmp = memcmp(fDesc, srcDesc, SkTMin<size_t>(lenLH, lenRH));
@@ -61,23 +43,23 @@
     }
 }
 
-bool SkGrDescKey::eq(const GrKey& rh) const {
-    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
+bool GrFontDescKey::eq(const GrFontDescKey& rh) const {
+    const SkDescriptor* srcDesc = (&rh)->fDesc;
     return fDesc->equals(*srcDesc);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) {
+GrFontScaler::GrFontScaler(SkGlyphCache* strike) {
     fStrike = strike;
     fKey = NULL;
 }
 
-SkGrFontScaler::~SkGrFontScaler() {
+GrFontScaler::~GrFontScaler() {
     SkSafeUnref(fKey);
 }
 
-GrMaskFormat SkGrFontScaler::getMaskFormat() {
+GrMaskFormat GrFontScaler::getMaskFormat() {
     SkMask::Format format = fStrike->getMaskFormat();
     switch (format) {
         case SkMask::kBW_Format:
@@ -96,14 +78,14 @@
     }
 }
 
-const GrKey* SkGrFontScaler::getKey() {
+const GrFontDescKey* GrFontScaler::getKey() {
     if (NULL == fKey) {
-        fKey = SkNEW_ARGS(SkGrDescKey, (fStrike->getDescriptor()));
+        fKey = SkNEW_ARGS(GrFontDescKey, (fStrike->getDescriptor()));
     }
     return fKey;
 }
 
-bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed, SkIRect* bounds) {
+bool GrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed, SkIRect* bounds) {
     const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
                                                       GrGlyph::UnpackFixedX(packed),
                                                       GrGlyph::UnpackFixedY(packed));
@@ -112,7 +94,7 @@
     return true;
 }
 
-bool SkGrFontScaler::getPackedGlyphDFBounds(GrGlyph::PackedID packed, SkIRect* bounds) {
+bool GrFontScaler::getPackedGlyphDFBounds(GrGlyph::PackedID packed, SkIRect* bounds) {
     const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
                                                       GrGlyph::UnpackFixedX(packed),
                                                       GrGlyph::UnpackFixedY(packed));
@@ -148,7 +130,7 @@
 }
 }
 
-bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
+bool GrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
                                          int width, int height,
                                          int dstRB, void* dst) {
     const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
@@ -200,7 +182,7 @@
     return true;
 }
 
-bool SkGrFontScaler::getPackedGlyphDFImage(GrGlyph::PackedID packed,
+bool GrFontScaler::getPackedGlyphDFImage(GrGlyph::PackedID packed,
                                            int width, int height,
                                            void* dst) {
     const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
@@ -219,7 +201,7 @@
 }
 
 // we should just return const SkPath* (NULL means false)
-bool SkGrFontScaler::getGlyphPath(uint16_t glyphID, SkPath* path) {
+bool GrFontScaler::getGlyphPath(uint16_t glyphID, SkPath* path) {
 
     const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
     const SkPath* skPath = fStrike->findPath(glyph);
diff --git a/src/gpu/GrGeometryBuffer.h b/src/gpu/GrGeometryBuffer.h
index 67e91cc..c3e1c65 100644
--- a/src/gpu/GrGeometryBuffer.h
+++ b/src/gpu/GrGeometryBuffer.h
@@ -10,14 +10,14 @@
 #ifndef GrGeometryBuffer_DEFINED
 #define GrGeometryBuffer_DEFINED
 
-#include "GrGpuObject.h"
+#include "GrGpuResource.h"
 
 class GrGpu;
 
 /**
  * Parent class for vertex and index buffers
  */
-class GrGeometryBuffer : public GrGpuObject {
+class GrGeometryBuffer : public GrGpuResource {
 public:
     SK_DECLARE_INST_COUNT(GrGeometryBuffer);
 
@@ -58,7 +58,7 @@
      * The pointer returned by the previous map call will no longer be valid.
      */
      void unmap() {
-         SkASSERT(NULL != fMapPtr);
+         SkASSERT(fMapPtr);
          this->onUnmap();
          fMapPtr = NULL;
      }
@@ -76,7 +76,7 @@
 
      @return true if the buffer is mapped, false otherwise.
      */
-     bool isMapped() const { return NULL != fMapPtr; }
+     bool isMapped() const { return SkToBool(fMapPtr); }
 
     /**
      * Updates the buffer data.
@@ -98,7 +98,7 @@
         return this->onUpdateData(src, srcSizeInBytes);
     }
 
-    // GrGpuObject overrides
+    // GrGpuResource overrides
     virtual size_t gpuMemorySize() const { return fGpuMemorySize; }
 
 protected:
@@ -119,7 +119,7 @@
     bool     fDynamic;
     bool     fCPUBacked;
 
-    typedef GrGpuObject INHERITED;
+    typedef GrGpuResource INHERITED;
 };
 
 #endif
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index fd249de..1f01e12 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -50,18 +50,6 @@
 }
 
 GrGpu::~GrGpu() {
-    this->releaseResources();
-}
-
-void GrGpu::abandonResources() {
-
-    fClipMaskManager.releaseResources();
-
-    while (NULL != fObjectList.head()) {
-        fObjectList.head()->abandon();
-    }
-
-    SkASSERT(NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed());
     SkSafeSetNull(fQuadIndexBuffer);
     delete fVertexPool;
     fVertexPool = NULL;
@@ -69,42 +57,7 @@
     fIndexPool = NULL;
 }
 
-void GrGpu::releaseResources() {
-
-    fClipMaskManager.releaseResources();
-
-    while (NULL != fObjectList.head()) {
-        fObjectList.head()->release();
-    }
-
-    SkASSERT(NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed());
-    SkSafeSetNull(fQuadIndexBuffer);
-    delete fVertexPool;
-    fVertexPool = NULL;
-    delete fIndexPool;
-    fIndexPool = NULL;
-}
-
-void GrGpu::insertObject(GrGpuObject* object) {
-    SkASSERT(NULL != object);
-    SkASSERT(this == object->getGpu());
-
-    fObjectList.addToHead(object);
-}
-
-void GrGpu::removeObject(GrGpuObject* object) {
-    SkASSERT(NULL != object);
-    SkASSERT(this == object->getGpu());
-
-    fObjectList.remove(object);
-}
-
-
-void GrGpu::unimpl(const char msg[]) {
-#ifdef SK_DEBUG
-    GrPrintf("--- GrGpu unimplemented(\"%s\")\n", msg);
-#endif
-}
+void GrGpu::contextAbandoned() {}
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -134,10 +87,10 @@
     } else {
         this->handleDirtyContext();
         tex = this->onCreateTexture(desc, srcData, rowBytes);
-        if (NULL != tex &&
+        if (tex &&
             (kRenderTarget_GrTextureFlagBit & desc.fFlags) &&
             !(kNoStencil_GrTextureFlagBit & desc.fFlags)) {
-            SkASSERT(NULL != tex->asRenderTarget());
+            SkASSERT(tex->asRenderTarget());
             // TODO: defer this and attach dynamically
             if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) {
                 tex->unref();
@@ -154,7 +107,7 @@
         this->getContext()->findStencilBuffer(rt->width(),
                                               rt->height(),
                                               rt->numSamples());
-    if (NULL != sb) {
+    if (sb) {
         rt->setStencilBuffer(sb);
         bool attached = this->attachStencilBufferToRenderTarget(sb, rt);
         if (!attached) {
@@ -172,8 +125,7 @@
         // We used to clear down in the GL subclass using a special purpose
         // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
         // FBO status.
-        GrDrawState::AutoRenderTargetRestore artr(this->drawState(), rt);
-        this->clearStencil();
+        this->clearStencil(rt);
         return true;
     } else {
         return false;
@@ -188,7 +140,7 @@
     }
     // TODO: defer this and attach dynamically
     GrRenderTarget* tgt = tex->asRenderTarget();
-    if (NULL != tgt &&
+    if (tgt &&
         !this->attachStencilBufferToRenderTarget(tgt)) {
         tex->unref();
         return NULL;
@@ -212,26 +164,19 @@
     return this->onCreateIndexBuffer(size, dynamic);
 }
 
-GrPath* GrGpu::createPath(const SkPath& path, const SkStrokeRec& stroke) {
-    SkASSERT(this->caps()->pathRenderingSupport());
-    this->handleDirtyContext();
-    return this->onCreatePath(path, stroke);
-}
-
 void GrGpu::clear(const SkIRect* rect,
                   GrColor color,
                   bool canIgnoreRect,
                   GrRenderTarget* renderTarget) {
-    GrDrawState::AutoRenderTargetRestore art;
-    if (NULL != renderTarget) {
-        art.set(this->drawState(), renderTarget);
+    if (NULL == renderTarget) {
+        renderTarget = this->getDrawState().getRenderTarget();
     }
-    if (NULL == this->getDrawState().getRenderTarget()) {
+    if (NULL == renderTarget) {
         SkASSERT(0);
         return;
     }
     this->handleDirtyContext();
-    this->onClear(rect, color, canIgnoreRect);
+    this->onClear(renderTarget, rect, color, canIgnoreRect);
 }
 
 bool GrGpu::readPixels(GrRenderTarget* target,
@@ -313,13 +258,14 @@
 }
 
 const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
-    if (NULL == fQuadIndexBuffer) {
+    if (NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed()) {
+        SkSafeUnref(fQuadIndexBuffer);
         static const int SIZE = sizeof(uint16_t) * 6 * MAX_QUADS;
         GrGpu* me = const_cast<GrGpu*>(this);
         fQuadIndexBuffer = me->createIndexBuffer(SIZE, false);
-        if (NULL != fQuadIndexBuffer) {
+        if (fQuadIndexBuffer) {
             uint16_t* indices = (uint16_t*)fQuadIndexBuffer->map();
-            if (NULL != indices) {
+            if (indices) {
                 fill_indices(indices, MAX_QUADS);
                 fQuadIndexBuffer->unmap();
             } else {
@@ -401,7 +347,7 @@
         return;
     }
 
-    this->onGpuStencilPath(path, fill);
+    this->pathRendering()->stencilPath(path, fill);
 }
 
 
@@ -416,13 +362,13 @@
         return;
     }
 
-    this->onGpuDrawPath(path, fill);
+    this->pathRendering()->drawPath(path, fill);
 }
 
-void GrGpu::onDrawPaths(int pathCount, const GrPath** paths,
-                        const SkMatrix* transforms, SkPath::FillType fill,
-                        SkStrokeRec::Style style,
-                        const GrDeviceCoordTexture* dstCopy) {
+void GrGpu::onDrawPaths(const GrPathRange* pathRange,
+                        const uint32_t indices[], int count,
+                        const float transforms[], PathTransformType transformsType,
+                        SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) {
     this->handleDirtyContext();
 
     drawState()->setDefaultVertexAttribs();
@@ -432,16 +378,17 @@
         return;
     }
 
-    this->onGpuDrawPaths(pathCount, paths, transforms, fill, style);
+    pathRange->willDrawPaths(indices, count);
+    this->pathRendering()->drawPaths(pathRange, indices, count, transforms, transformsType, fill);
 }
 
 void GrGpu::finalizeReservedVertices() {
-    SkASSERT(NULL != fVertexPool);
+    SkASSERT(fVertexPool);
     fVertexPool->unmap();
 }
 
 void GrGpu::finalizeReservedIndices() {
-    SkASSERT(NULL != fIndexPool);
+    SkASSERT(fIndexPool);
     fIndexPool->unmap();
 }
 
@@ -477,7 +424,7 @@
     GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
 
     SkASSERT(vertexCount > 0);
-    SkASSERT(NULL != vertices);
+    SkASSERT(vertices);
 
     this->prepareVertexPool();
 
@@ -496,7 +443,7 @@
     GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
 
     SkASSERT(indexCount > 0);
-    SkASSERT(NULL != indices);
+    SkASSERT(indices);
 
     this->prepareIndexPool();
 
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index cd7502e..54fe471 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -10,12 +10,13 @@
 
 #include "GrDrawTarget.h"
 #include "GrClipMaskManager.h"
+#include "GrPathRendering.h"
 #include "SkPath.h"
 
 class GrContext;
-class GrGpuObject;
 class GrIndexBufferAllocPool;
 class GrPath;
+class GrPathRange;
 class GrPathRenderer;
 class GrPathRendererChain;
 class GrStencilBuffer;
@@ -54,6 +55,16 @@
     GrContext* getContext() { return this->INHERITED::getContext(); }
     const GrContext* getContext() const { return this->INHERITED::getContext(); }
 
+    GrPathRendering* pathRendering() {
+        return fPathRendering.get();
+    }
+
+    // Called by GrContext when the underlying backend context has been destroyed.
+    // GrGpu should use this to ensure that no backend API calls will be made from
+    // here onward, including in its destructor. Subclasses should call
+    // INHERITED::contextAbandoned() if they override this.
+    virtual void contextAbandoned();
+
     /**
      * The GrGpu object normally assumes that no outsider is setting state
      * within the underlying 3D API's context/device/whatever. This call informs
@@ -132,12 +143,6 @@
     GrIndexBuffer* createIndexBuffer(size_t size, bool dynamic);
 
     /**
-     * Creates a path object that can be stenciled using stencilPath(). It is
-     * only legal to call this if the caps report support for path stenciling.
-     */
-    GrPath* createPath(const SkPath& path, const SkStrokeRec& stroke);
-
-    /**
      * Returns an index buffer that can be used to render quads.
      * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
      * The max number of quads can be queried using GrIndexBuffer::maxQuads().
@@ -241,30 +246,6 @@
                             GrPixelConfig config, const void* buffer,
                             size_t rowBytes);
 
-    /**
-     * Called to tell GrGpu that all GrGpuObjects have been lost and should
-     * be abandoned. Overrides must call INHERITED::abandonResources().
-     */
-    virtual void abandonResources();
-
-    /**
-     * Called to tell GrGpu to release all GrGpuObjects. Overrides must call
-     * INHERITED::releaseResources().
-     */
-    void releaseResources();
-
-    /**
-     * Add object to list of objects. Should only be called by GrGpuObject.
-     * @param resource  the resource to add.
-     */
-    void insertObject(GrGpuObject* object);
-
-    /**
-     * Remove object from list of objects. Should only be called by GrGpuObject.
-     * @param resource  the resource to remove.
-     */
-    void removeObject(GrGpuObject* object);
-
     // GrDrawTarget overrides
     virtual void clear(const SkIRect* rect,
                        GrColor color,
@@ -274,7 +255,7 @@
     virtual void purgeResources() SK_OVERRIDE {
         // The clip mask manager can rebuild all its clip masks so just
         // get rid of them all.
-        fClipMaskManager.releaseResources();
+        fClipMaskManager.purgeResources();
     }
 
     // After the client interacts directly with the 3D context state the GrGpu
@@ -321,7 +302,7 @@
     // GrGpu subclass sets clip bit in the stencil buffer. The subclass is
     // free to clear the remaining bits to zero if masked clears are more
     // expensive than clearing all bits.
-    virtual void clearStencilClip(const SkIRect& rect, bool insideClip) = 0;
+    virtual void clearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) = 0;
 
     enum PrivateDrawStateStateBits {
         kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
@@ -342,6 +323,12 @@
         kDrawPaths_DrawType,
     };
 
+    static bool IsPathRenderingDrawType(DrawType type) {
+        return kDrawPath_DrawType == type || kDrawPaths_DrawType == type;
+    }
+
+    GrContext::GPUStats* gpuStats() { return &fGPUStats; }
+
 protected:
     DrawType PrimTypeToDrawType(GrPrimitiveType type) {
         switch (type) {
@@ -379,6 +366,8 @@
 
     GrClipMaskManager           fClipMaskManager;
 
+    GrContext::GPUStats         fGPUStats;
+
     struct GeometryPoolState {
         const GrVertexBuffer* fPoolVertexBuffer;
         int                   fPoolStartVertex;
@@ -403,6 +392,8 @@
     void finalizeReservedVertices();
     void finalizeReservedIndices();
 
+    SkAutoTDelete<GrPathRendering> fPathRendering;
+
 private:
     // GrDrawTarget overrides
     virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) SK_OVERRIDE;
@@ -431,22 +422,16 @@
     virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) = 0;
     virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0;
     virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) = 0;
-    virtual GrPath* onCreatePath(const SkPath& path, const SkStrokeRec&) = 0;
 
     // overridden by backend-specific derived class to perform the clear and
     // clearRect. NULL rect means clear whole target. If canIgnoreRect is
     // true, it is okay to perform a full clear instead of a partial clear
-    virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) = 0;
+    virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
+                         bool canIgnoreRect) = 0;
 
     // overridden by backend-specific derived class to perform the draw call.
     virtual void onGpuDraw(const DrawInfo&) = 0;
 
-    // overridden by backend-specific derived class to perform the path stenciling.
-    virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) = 0;
-    virtual void onGpuDrawPath(const GrPath*, SkPath::FillType) = 0;
-    virtual void onGpuDrawPaths(int, const GrPath**, const SkMatrix*,
-                                SkPath::FillType, SkStrokeRec::Style) = 0;
-
     // overridden by backend-specific derived class to perform the read pixels.
     virtual bool onReadPixels(GrRenderTarget* target,
                               int left, int top, int width, int height,
@@ -477,8 +462,8 @@
     // returns false if current state is unsupported.
     virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) = 0;
 
-    // clears the entire stencil buffer to 0
-    virtual void clearStencil() = 0;
+    // clears target's entire stencil buffer to 0
+    virtual void clearStencil(GrRenderTarget* target) = 0;
 
     // Given a rt, find or create a stencil buffer and attach it
     bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
@@ -488,9 +473,10 @@
     virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
     virtual void onDrawPath(const GrPath*, SkPath::FillType,
                             const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
-    virtual void onDrawPaths(int, const GrPath**, const SkMatrix*,
-                             SkPath::FillType, SkStrokeRec::Style,
-                             const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
+    virtual void onDrawPaths(const GrPathRange*,
+                             const uint32_t indices[], int count,
+                             const float transforms[], PathTransformType,
+                             SkPath::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE;
 
     // readies the pools to provide vertex/index data.
     void prepareVertexPool();
@@ -515,7 +501,6 @@
     enum {
         kPreallocGeomPoolStateStackCnt = 4,
     };
-    typedef SkTInternalLList<GrGpuObject> ObjectList;
     SkSTArray<kPreallocGeomPoolStateStackCnt, GeometryPoolState, true>  fGeomPoolStateStack;
     ResetTimestamp                                                      fResetTimestamp;
     uint32_t                                                            fResetBits;
@@ -526,9 +511,6 @@
     int                                                                 fIndexPoolUseCnt;
     // these are mutable so they can be created on-demand
     mutable GrIndexBuffer*                                              fQuadIndexBuffer;
-    // Used to abandon/release all resources created by this GrGpu. TODO: Move this
-    // functionality to GrResourceCache.
-    ObjectList                                                          fObjectList;
 
     typedef GrDrawTarget INHERITED;
 };
diff --git a/src/gpu/GrGpuObject.cpp b/src/gpu/GrGpuObject.cpp
deleted file mode 100644
index 43a86f2..0000000
--- a/src/gpu/GrGpuObject.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#include "GrGpuObject.h"
-#include "GrGpu.h"
-
-GrGpuObject::GrGpuObject(GrGpu* gpu, bool isWrapped) {
-    fGpu              = gpu;
-    fDeferredRefCount = 0;
-    if (isWrapped) {
-        fFlags = kWrapped_FlagBit;
-    } else {
-        fFlags = 0;
-    }
-    fGpu->insertObject(this);
-}
-
-GrGpuObject::~GrGpuObject() {
-    // subclass should have released this.
-    SkASSERT(0 == fDeferredRefCount);
-    SkASSERT(this->wasDestroyed());
-}
-
-void GrGpuObject::release() {
-    if (NULL != fGpu) {
-        this->onRelease();
-        fGpu->removeObject(this);
-        fGpu = NULL;
-    }
-}
-
-void GrGpuObject::abandon() {
-    if (NULL != fGpu) {
-        this->onAbandon();
-        fGpu->removeObject(this);
-        fGpu = NULL;
-    }
-}
-
-const GrContext* GrGpuObject::getContext() const {
-    if (NULL != fGpu) {
-        return fGpu->getContext();
-    } else {
-        return NULL;
-    }
-}
-
-GrContext* GrGpuObject::getContext() {
-    if (NULL != fGpu) {
-        return fGpu->getContext();
-    } else {
-        return NULL;
-    }
-}
diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp
new file mode 100644
index 0000000..bba934e
--- /dev/null
+++ b/src/gpu/GrGpuResource.cpp
@@ -0,0 +1,98 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "GrGpuResource.h"
+#include "GrResourceCache2.h"
+#include "GrGpu.h"
+
+GrIORef::~GrIORef() {
+    SkASSERT(0 == fRefCnt);
+    SkASSERT(0 == fPendingReads);
+    SkASSERT(0 == fPendingWrites);
+    // Set to invalid values.
+    SkDEBUGCODE(fRefCnt = fPendingReads = fPendingWrites = -10;)
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static inline GrResourceCache2* get_resource_cache2(GrGpu* gpu) {
+    SkASSERT(gpu);
+    SkASSERT(gpu->getContext());
+    SkASSERT(gpu->getContext()->getResourceCache2());
+    return gpu->getContext()->getResourceCache2();
+}
+
+GrGpuResource::GrGpuResource(GrGpu* gpu, bool isWrapped)
+    : fGpu(gpu)
+    , fCacheEntry(NULL)
+    , fUniqueID(CreateUniqueID())
+    , fScratchKey(GrResourceKey::NullScratchKey()) {
+    if (isWrapped) {
+        fFlags = kWrapped_FlagBit;
+    } else {
+        fFlags = 0;
+    }
+}
+
+void GrGpuResource::registerWithCache() {
+    get_resource_cache2(fGpu)->insertResource(this);
+}
+
+GrGpuResource::~GrGpuResource() {
+    // subclass should have released this.
+    SkASSERT(this->wasDestroyed());
+}
+
+void GrGpuResource::release() { 
+    if (fGpu) {
+        this->onRelease();
+        get_resource_cache2(fGpu)->removeResource(this);
+        fGpu = NULL;
+    }
+}
+
+void GrGpuResource::abandon() {
+    if (fGpu) {
+        this->onAbandon();
+        get_resource_cache2(fGpu)->removeResource(this);
+        fGpu = NULL;
+    }
+}
+
+const GrContext* GrGpuResource::getContext() const {
+    if (fGpu) {
+        return fGpu->getContext();
+    } else {
+        return NULL;
+    }
+}
+
+GrContext* GrGpuResource::getContext() {
+    if (fGpu) {
+        return fGpu->getContext();
+    } else {
+        return NULL;
+    }
+}
+
+void GrGpuResource::setScratchKey(const GrResourceKey& scratchKey) {
+    SkASSERT(fScratchKey.isNullScratch());
+    SkASSERT(scratchKey.isScratch());
+    SkASSERT(!scratchKey.isNullScratch());
+    fScratchKey = scratchKey;
+}
+
+uint32_t GrGpuResource::CreateUniqueID() {
+    static int32_t gUniqueID = SK_InvalidUniqueID;
+    uint32_t id;
+    do {
+        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
+    } while (id == SK_InvalidUniqueID);
+    return id;
+}
diff --git a/src/gpu/GrGpuResourceRef.cpp b/src/gpu/GrGpuResourceRef.cpp
new file mode 100644
index 0000000..7c521df
--- /dev/null
+++ b/src/gpu/GrGpuResourceRef.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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 "GrGpuResourceRef.h"
+
+GrGpuResourceRef::GrGpuResourceRef() {
+    fResource = NULL;
+    fOwnRef = false;
+    fPendingIO = false;
+}
+
+GrGpuResourceRef::GrGpuResourceRef(GrGpuResource* resource, GrIORef::IOType ioType) {
+    fResource = NULL;
+    fOwnRef = false;
+    fPendingIO = false;
+    this->setResource(resource, ioType);
+}
+
+GrGpuResourceRef::~GrGpuResourceRef() {
+    if (fOwnRef) {
+        SkASSERT(fResource);
+        fResource->unref();
+    }
+    if (fPendingIO) {
+        switch (fIOType) {
+            case GrIORef::kRead_IOType:
+                fResource->completedRead();
+                break;
+            case GrIORef::kWrite_IOType:
+                fResource->completedWrite();
+                break;
+            case GrIORef::kRW_IOType:
+                fResource->completedRead();
+                fResource->completedWrite();
+                break;
+        }
+    }
+}
+
+void GrGpuResourceRef::reset() {
+    SkASSERT(!fPendingIO);
+    SkASSERT(SkToBool(fResource) == fOwnRef);
+    if (fOwnRef) {
+        fResource->unref();
+        fOwnRef = false;
+        fResource = NULL;
+    }
+}
+
+void GrGpuResourceRef::setResource(GrGpuResource* resource, GrIORef::IOType ioType) {
+    SkASSERT(!fPendingIO);
+    SkASSERT(SkToBool(fResource) == fOwnRef);
+    SkSafeUnref(fResource);
+    if (NULL == resource) {
+        fResource = NULL;
+        fOwnRef = false;
+    } else {
+        fResource = resource;
+        fOwnRef = true;
+        fIOType = ioType;
+    }
+}
+
+void GrGpuResourceRef::markPendingIO() const {
+    // This should only be called when the owning GrProgramElement gets its first
+    // pendingExecution ref.
+    SkASSERT(!fPendingIO);
+    SkASSERT(fResource);
+    fPendingIO = true;
+    switch (fIOType) {
+        case GrIORef::kRead_IOType:
+            fResource->addPendingRead();
+            break;
+        case GrIORef::kWrite_IOType:
+            fResource->addPendingWrite();
+            break;
+        case GrIORef::kRW_IOType:
+            fResource->addPendingRead();
+            fResource->addPendingWrite();
+            break;
+    }
+}
+
+void GrGpuResourceRef::pendingIOComplete() const {
+    // This should only be called when the owner's pending executions have ocurred but it is still
+    // reffed.
+    SkASSERT(fOwnRef);
+    SkASSERT(fPendingIO);
+    switch (fIOType) {
+        case GrIORef::kRead_IOType:
+            fResource->completedRead();
+            break;
+        case GrIORef::kWrite_IOType:
+            fResource->completedWrite();
+            break;
+        case GrIORef::kRW_IOType:
+            fResource->completedRead();
+            fResource->completedWrite();
+            break;
+
+    }
+    fPendingIO = false;
+}
+
+void GrGpuResourceRef::removeRef() const {
+    // This should only be called once, when the owners last ref goes away and
+    // there is a pending execution.
+    SkASSERT(fOwnRef);
+    SkASSERT(fPendingIO);
+    SkASSERT(fResource);
+    fResource->unref();
+    fOwnRef = false;
+}
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index deea72b..b9e84c0 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -11,12 +11,8 @@
 #include "GrDrawTargetCaps.h"
 #include "GrTextStrike.h"
 #include "GrGpu.h"
-#include "GrIndexBuffer.h"
-#include "GrPath.h"
-#include "GrRenderTarget.h"
 #include "GrTemplates.h"
 #include "GrTexture.h"
-#include "GrVertexBuffer.h"
 
 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
                                          GrVertexBufferAllocPool* vertexPool,
@@ -33,8 +29,8 @@
     fDstGpu->ref();
     fCaps.reset(SkRef(fDstGpu->caps()));
 
-    SkASSERT(NULL != vertexPool);
-    SkASSERT(NULL != indexPool);
+    SkASSERT(vertexPool);
+    SkASSERT(indexPool);
 
     GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
     poolState.fUsedPoolVertexBytes = 0;
@@ -77,87 +73,53 @@
 
 namespace {
 
-extern const GrVertexAttrib kRectPosColorUVAttribs[] = {
-    {kVec2f_GrVertexAttribType,  0,               kPosition_GrVertexAttribBinding},
-    {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType,  sizeof(SkPoint)+sizeof(GrColor),
-                                                  kLocalCoord_GrVertexAttribBinding},
+extern const GrVertexAttrib kRectAttribs[] = {
+    {kVec2f_GrVertexAttribType,  0,                               kPosition_GrVertexAttribBinding},
+    {kVec4ub_GrVertexAttribType, sizeof(SkPoint),                 kColor_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType,  sizeof(SkPoint)+sizeof(GrColor), kLocalCoord_GrVertexAttribBinding},
 };
-
-extern const GrVertexAttrib kRectPosUVAttribs[] = {
-    {kVec2f_GrVertexAttribType,  0,              kPosition_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding},
-};
-
-static void set_vertex_attributes(GrDrawState* drawState,
-                                  bool hasColor, bool hasUVs,
-                                  int* colorOffset, int* localOffset) {
-    *colorOffset = -1;
-    *localOffset = -1;
-
-    // Using per-vertex colors allows batching across colors. (A lot of rects in a row differing
-    // only in color is a common occurrence in tables). However, having per-vertex colors disables
-    // blending optimizations because we don't know if the color will be solid or not. These
-    // optimizations help determine whether coverage and color can be blended correctly when
-    // dual-source blending isn't available. This comes into play when there is coverage. If colors
-    // were a stage it could take a hint that every vertex's color will be opaque.
-    if (hasColor && hasUVs) {
-        *colorOffset = sizeof(SkPoint);
-        *localOffset = sizeof(SkPoint) + sizeof(GrColor);
-        drawState->setVertexAttribs<kRectPosColorUVAttribs>(3);
-    } else if (hasColor) {
-        *colorOffset = sizeof(SkPoint);
-        drawState->setVertexAttribs<kRectPosColorUVAttribs>(2);
-    } else if (hasUVs) {
-        *localOffset = sizeof(SkPoint);
-        drawState->setVertexAttribs<kRectPosUVAttribs>(2);
-    } else {
-        drawState->setVertexAttribs<kRectPosUVAttribs>(1);
-    }
 }
 
-};
+/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
+    have explicit local coords and sometimes not. We *could* always provide explicit local coords
+    and just duplicate the positions when the caller hasn't provided a local coord rect, but we
+    haven't seen a use case which frequently switches between local rect and no local rect draws.
+
+    The color param is used to determine whether the opaque hint can be set on the draw state.
+    The caller must populate the vertex colors itself.
+
+    The vertex attrib order is always pos, color, [local coords].
+ */
+static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, GrColor color) {
+    if (hasLocalCoords) {
+        drawState->setVertexAttribs<kRectAttribs>(3, 2 * sizeof(SkPoint) + sizeof(SkColor));
+    } else {
+        drawState->setVertexAttribs<kRectAttribs>(2, sizeof(SkPoint) + sizeof(SkColor));
+    }
+    if (0xFF == GrColorUnpackA(color)) {
+        drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
+    }
+}
 
 enum {
     kTraceCmdBit = 0x80,
     kCmdMask = 0x7f,
 };
 
-static uint8_t add_trace_bit(uint8_t cmd) {
-    return cmd | kTraceCmdBit;
-}
+static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; }
 
-static uint8_t strip_trace_bit(uint8_t cmd) {
-    return cmd & kCmdMask;
-}
+static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; }
 
-static bool cmd_has_trace_marker(uint8_t cmd) {
-    return SkToBool(cmd & kTraceCmdBit);
-}
+static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTraceCmdBit); }
 
 void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect,
-                                     const SkMatrix* matrix,
                                      const SkRect* localRect,
                                      const SkMatrix* localMatrix) {
-    GrDrawState::AutoColorRestore acr;
-
     GrDrawState* drawState = this->drawState();
 
     GrColor color = drawState->getColor();
 
-    int colorOffset, localOffset;
-    set_vertex_attributes(drawState,
-                   this->caps()->dualSourceBlendingSupport() || drawState->hasSolidCoverage(),
-                   NULL != localRect,
-                   &colorOffset, &localOffset);
-    if (colorOffset >= 0) {
-        // We set the draw state's color to white here. This is done so that any batching performed
-        // in our subclass's onDraw() won't get a false from GrDrawState::op== due to a color
-        // mismatch. TODO: Once vertex layout is owned by GrDrawState it should skip comparing the
-        // constant color in its op== when the kColor layout bit is set and then we can remove
-        // this.
-        acr.set(drawState, 0xFFFFFFFF);
-    }
+    set_vertex_attributes(drawState, SkToBool(localRect),  color);
 
     AutoReleaseGeometry geo(this, 4, 0);
     if (!geo.succeeded()) {
@@ -166,13 +128,8 @@
     }
 
     // Go to device coords to allow batching across matrix changes
-    SkMatrix combinedMatrix;
-    if (NULL != matrix) {
-        combinedMatrix = *matrix;
-    } else {
-        combinedMatrix.reset();
-    }
-    combinedMatrix.postConcat(drawState->getViewMatrix());
+    SkMatrix matrix = drawState->getViewMatrix();
+
     // When the caller has provided an explicit source rect for a stage then we don't want to
     // modify that stage's matrix. Otherwise if the effect is generating its source rect from
     // the vertex positions then we have to account for the view matrix change.
@@ -181,32 +138,32 @@
         return;
     }
 
-    size_t vsize = drawState->getVertexSize();
+    size_t vstride = drawState->getVertexStride();
 
-    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
-    combinedMatrix.mapPointsWithStride(geo.positions(), vsize, 4);
+    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
+    matrix.mapPointsWithStride(geo.positions(), vstride, 4);
 
     SkRect devBounds;
     // since we already computed the dev verts, set the bounds hint. This will help us avoid
     // unnecessary clipping in our onDraw().
-    get_vertex_bounds(geo.vertices(), vsize, 4, &devBounds);
+    get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds);
 
-    if (localOffset >= 0) {
-        SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + localOffset);
+    if (localRect) {
+        static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
+        SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset);
         coords->setRectFan(localRect->fLeft, localRect->fTop,
                            localRect->fRight, localRect->fBottom,
-                            vsize);
-        if (NULL != localMatrix) {
-            localMatrix->mapPointsWithStride(coords, vsize, 4);
+                           vstride);
+        if (localMatrix) {
+            localMatrix->mapPointsWithStride(coords, vstride, 4);
         }
     }
 
-    if (colorOffset >= 0) {
-        GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + colorOffset);
-        for (int i = 0; i < 4; ++i) {
-            *vertColor = color;
-            vertColor = (GrColor*) ((intptr_t) vertColor + vsize);
-        }
+    static const int kColorOffset = sizeof(SkPoint);
+    GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + kColorOffset);
+    for (int i = 0; i < 4; ++i) {
+        *vertColor = color;
+        vertColor = (GrColor*) ((intptr_t) vertColor + vstride);
     }
 
     this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
@@ -277,15 +234,15 @@
         return 0;
     }
 
-    DrawRecord* draw = &fDraws.back();
+    Draw* draw = &fDraws.back();
     GeometryPoolState& poolState = fGeoPoolStateStack.back();
     const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
 
     if (!draw->isInstanced() ||
         draw->verticesPerInstance() != info.verticesPerInstance() ||
         draw->indicesPerInstance() != info.indicesPerInstance() ||
-        draw->fVertexBuffer != vertexBuffer ||
-        draw->fIndexBuffer != geomSrc.fIndexBuffer) {
+        draw->vertexBuffer() != vertexBuffer ||
+        draw->indexBuffer() != geomSrc.fIndexBuffer) {
         return 0;
     }
     // info does not yet account for the offset from the start of the pool's VB while the previous
@@ -304,7 +261,7 @@
 
     // update the amount of reserved vertex data actually referenced in draws
     size_t vertexBytes = instancesToConcat * info.verticesPerInstance() *
-                         drawState.getVertexSize();
+                         drawState.getVertexStride();
     poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vertexBytes);
 
     draw->adjustInstanceCount(instancesToConcat);
@@ -326,7 +283,7 @@
 public:
     AutoClipReenable() : fDrawState(NULL) {}
     ~AutoClipReenable() {
-        if (NULL != fDrawState) {
+        if (fDrawState) {
             fDrawState->enableState(GrDrawState::kClip_StateBit);
         }
     }
@@ -347,7 +304,7 @@
     AutoClipReenable acr;
 
     if (drawState.isClipState() &&
-        NULL != info.getDevBounds() &&
+        info.getDevBounds() &&
         this->quickInsideClip(*info.getDevBounds())) {
         acr.set(this->drawState());
     }
@@ -355,87 +312,59 @@
     if (this->needsNewClip()) {
        this->recordClip();
     }
-    if (this->needsNewState()) {
-        this->recordState();
+    this->recordStateIfNecessary();
+
+    const GrVertexBuffer* vb;
+    if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
+        vb = this->getGeomSrc().fVertexBuffer;
+    } else {
+        vb = poolState.fPoolVertexBuffer;
     }
 
-    DrawRecord* draw;
+    const GrIndexBuffer* ib = NULL;
+    if (info.isIndexed()) {
+        if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) {
+            ib = this->getGeomSrc().fIndexBuffer;
+        } else {
+            ib = poolState.fPoolIndexBuffer;
+        }
+    }
+
+    Draw* draw;
     if (info.isInstanced()) {
         int instancesConcated = this->concatInstancedDraw(info);
         if (info.instanceCount() > instancesConcated) {
-            draw = this->recordDraw(info);
+            draw = this->recordDraw(info, vb, ib);
             draw->adjustInstanceCount(-instancesConcated);
         } else {
             return;
         }
     } else {
-        draw = this->recordDraw(info);
+        draw = this->recordDraw(info, vb, ib);
     }
 
-    switch (this->getGeomSrc().fVertexSrc) {
-        case kBuffer_GeometrySrcType:
-            draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
-            break;
-        case kReserved_GeometrySrcType: // fallthrough
-        case kArray_GeometrySrcType: {
-            size_t vertexBytes = (info.vertexCount() + info.startVertex()) *
-                                 drawState.getVertexSize();
-            poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vertexBytes);
-            draw->fVertexBuffer = poolState.fPoolVertexBuffer;
-            draw->adjustStartVertex(poolState.fPoolStartVertex);
-            break;
-        }
-        default:
-            SkFAIL("unknown geom src type");
+    // Adjust the starting vertex and index when we are using reserved or array sources to
+    // compensate for the fact that the data was inserted into a larger vb/ib owned by the pool.
+    if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) {
+        size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.getVertexStride();
+        poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes);
+        draw->adjustStartVertex(poolState.fPoolStartVertex);
     }
-    draw->fVertexBuffer->ref();
-
-    if (info.isIndexed()) {
-        switch (this->getGeomSrc().fIndexSrc) {
-            case kBuffer_GeometrySrcType:
-                draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
-                break;
-            case kReserved_GeometrySrcType: // fallthrough
-            case kArray_GeometrySrcType: {
-                size_t indexBytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
-                poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, indexBytes);
-                draw->fIndexBuffer = poolState.fPoolIndexBuffer;
-                draw->adjustStartIndex(poolState.fPoolStartIndex);
-                break;
-            }
-            default:
-                SkFAIL("unknown geom src type");
-        }
-        draw->fIndexBuffer->ref();
-    } else {
-        draw->fIndexBuffer = NULL;
+    
+    if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndexSrc) {
+        size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
+        poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, bytes);
+        draw->adjustStartIndex(poolState.fPoolStartIndex);
     }
 }
 
-GrInOrderDrawBuffer::StencilPath::StencilPath() {}
-GrInOrderDrawBuffer::DrawPath::DrawPath() {}
-GrInOrderDrawBuffer::DrawPaths::DrawPaths() {}
-GrInOrderDrawBuffer::DrawPaths::~DrawPaths() {
-    if (fTransforms) {
-        SkDELETE_ARRAY(fTransforms);
-    }
-    for (int i = 0; i < fPathCount; ++i) {
-        fPaths[i]->unref();
-    }
-    SkDELETE_ARRAY(fPaths);
-}
-
 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fill) {
     if (this->needsNewClip()) {
         this->recordClip();
     }
     // Only compare the subset of GrDrawState relevant to path stenciling?
-    if (this->needsNewState()) {
-        this->recordState();
-    }
-    StencilPath* sp = this->recordStencilPath();
-    sp->fPath.reset(path);
-    path->ref();
+    this->recordStateIfNecessary();
+    StencilPath* sp = this->recordStencilPath(path);
     sp->fFill = fill;
 }
 
@@ -445,46 +374,39 @@
         this->recordClip();
     }
     // TODO: Only compare the subset of GrDrawState relevant to path covering?
-    if (this->needsNewState()) {
-        this->recordState();
-    }
-    DrawPath* cp = this->recordDrawPath();
-    cp->fPath.reset(path);
-    path->ref();
+    this->recordStateIfNecessary();
+    DrawPath* cp = this->recordDrawPath(path);
     cp->fFill = fill;
-    if (NULL != dstCopy) {
+    if (dstCopy) {
         cp->fDstCopy = *dstCopy;
     }
 }
 
-void GrInOrderDrawBuffer::onDrawPaths(int pathCount, const GrPath** paths,
-                                      const SkMatrix* transforms,
-                                      SkPath::FillType fill,
-                                      SkStrokeRec::Style stroke,
-                                      const GrDeviceCoordTexture* dstCopy) {
-    SkASSERT(pathCount);
+void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange,
+                                      const uint32_t indices[], int count,
+                                      const float transforms[], PathTransformType transformsType,
+                                      SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) {
+    SkASSERT(pathRange);
+    SkASSERT(indices);
+    SkASSERT(transforms);
 
     if (this->needsNewClip()) {
         this->recordClip();
     }
-    if (this->needsNewState()) {
-        this->recordState();
-    }
-    DrawPaths* dp = this->recordDrawPaths();
-    dp->fPathCount = pathCount;
-    dp->fPaths = SkNEW_ARRAY(const GrPath*, pathCount);
-    memcpy(dp->fPaths, paths, sizeof(GrPath*) * pathCount);
-    for (int i = 0; i < pathCount; ++i) {
-        dp->fPaths[i]->ref();
-    }
+    this->recordStateIfNecessary();
+    DrawPaths* dp = this->recordDrawPaths(pathRange);
+    dp->fIndices = SkNEW_ARRAY(uint32_t, count); // TODO: Accomplish this without a malloc
+    memcpy(dp->fIndices, indices, sizeof(uint32_t) * count);
+    dp->fCount = count;
 
-    dp->fTransforms = SkNEW_ARRAY(SkMatrix, pathCount);
-    memcpy(dp->fTransforms, transforms, sizeof(SkMatrix) * pathCount);
+    const int transformsLength = GrPathRendering::PathTransformSize(transformsType) * count;
+    dp->fTransforms = SkNEW_ARRAY(float, transformsLength);
+    memcpy(dp->fTransforms, transforms, sizeof(float) * transformsLength);
+    dp->fTransformsType = transformsType;
 
     dp->fFill = fill;
-    dp->fStroke = stroke;
 
-    if (NULL != dstCopy) {
+    if (dstCopy) {
         dp->fDstCopy = *dstCopy;
     }
 }
@@ -494,7 +416,7 @@
     SkIRect r;
     if (NULL == renderTarget) {
         renderTarget = this->drawState()->getRenderTarget();
-        SkASSERT(NULL != renderTarget);
+        SkASSERT(renderTarget);
     }
     if (NULL == rect) {
         // We could do something smart and remove previous draws and clears to
@@ -503,13 +425,11 @@
         r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
         rect = &r;
     }
-    Clear* clr = this->recordClear();
+    Clear* clr = this->recordClear(renderTarget);
     GrColorIsPMAssert(color);
     clr->fColor = color;
     clr->fRect = *rect;
     clr->fCanIgnoreRect = canIgnoreRect;
-    clr->fRenderTarget = renderTarget;
-    renderTarget->ref();
 }
 
 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
@@ -518,25 +438,17 @@
     }
     if (NULL == renderTarget) {
         renderTarget = this->drawState()->getRenderTarget();
-        SkASSERT(NULL != renderTarget);
+        SkASSERT(renderTarget);
     }
-    Clear* clr = this->recordClear();
+    Clear* clr = this->recordClear(renderTarget);
     clr->fColor = GrColor_ILLEGAL;
-    clr->fRenderTarget = renderTarget;
-    renderTarget->ref();
 }
 
 void GrInOrderDrawBuffer::reset() {
     SkASSERT(1 == fGeoPoolStateStack.count());
     this->resetVertexSource();
     this->resetIndexSource();
-    int numDraws = fDraws.count();
-    for (int d = 0; d < numDraws; ++d) {
-        // we always have a VB, but not always an IB
-        SkASSERT(NULL != fDraws[d].fVertexBuffer);
-        fDraws[d].fVertexBuffer->unref();
-        SkSafeUnref(fDraws[d].fIndexBuffer);
-    }
+        
     fCmds.reset();
     fDraws.reset();
     fStencilPaths.reset();
@@ -547,7 +459,6 @@
     fVertexPool.reset();
     fIndexPool.reset();
     fClips.reset();
-    fClipOrigins.reset();
     fCopySurfaces.reset();
     fGpuCmdMarkers.reset();
     fClipSet = true;
@@ -577,93 +488,98 @@
     GrDrawTarget::AutoClipRestore acr(fDstGpu);
     AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit);
 
-    GrDrawState playbackState;
-    GrDrawState* prevDrawState = fDstGpu->drawState();
-    prevDrawState->ref();
-    fDstGpu->setDrawState(&playbackState);
+    GrDrawState* prevDrawState = SkRef(fDstGpu->drawState());
 
     GrClipData clipData;
 
-    int currState       = 0;
-    int currClip        = 0;
-    int currClear       = 0;
-    int currDraw        = 0;
-    int currStencilPath = 0;
-    int currDrawPath    = 0;
-    int currDrawPaths   = 0;
-    int currCopySurface = 0;
+    StateAllocator::Iter stateIter(&fStates);
+    ClipAllocator::Iter clipIter(&fClips);
+    ClearAllocator::Iter clearIter(&fClears);
+    DrawAllocator::Iter drawIter(&fDraws);
+    StencilPathAllocator::Iter stencilPathIter(&fStencilPaths);
+    DrawPathAllocator::Iter drawPathIter(&fDrawPath);
+    DrawPathsAllocator::Iter drawPathsIter(&fDrawPaths);
+    CopySurfaceAllocator::Iter copySurfaceIter(&fCopySurfaces);
+
     int currCmdMarker   = 0;
 
     fDstGpu->saveActiveTraceMarkers();
     for (int c = 0; c < numCmds; ++c) {
         GrGpuTraceMarker newMarker("", -1);
+        SkString traceString;
         if (cmd_has_trace_marker(fCmds[c])) {
-            SkString traceString = fGpuCmdMarkers[currCmdMarker].toString();
+            traceString = fGpuCmdMarkers[currCmdMarker].toString();
             newMarker.fMarker = traceString.c_str();
             fDstGpu->addGpuTraceMarker(&newMarker);
             ++currCmdMarker;
         }
         switch (strip_trace_bit(fCmds[c])) {
             case kDraw_Cmd: {
-                const DrawRecord& draw = fDraws[currDraw];
-                fDstGpu->setVertexSourceToBuffer(draw.fVertexBuffer);
-                if (draw.isIndexed()) {
-                    fDstGpu->setIndexSourceToBuffer(draw.fIndexBuffer);
+                SkASSERT(fDstGpu->drawState() != prevDrawState);
+                SkAssertResult(drawIter.next());
+                fDstGpu->setVertexSourceToBuffer(drawIter->vertexBuffer());
+                if (drawIter->isIndexed()) {
+                    fDstGpu->setIndexSourceToBuffer(drawIter->indexBuffer());
                 }
-                fDstGpu->executeDraw(draw);
-                ++currDraw;
+                fDstGpu->executeDraw(*drawIter);
                 break;
             }
             case kStencilPath_Cmd: {
-                const StencilPath& sp = fStencilPaths[currStencilPath];
-                fDstGpu->stencilPath(sp.fPath.get(), sp.fFill);
-                ++currStencilPath;
+                SkASSERT(fDstGpu->drawState() != prevDrawState);
+                SkAssertResult(stencilPathIter.next());
+                fDstGpu->stencilPath(stencilPathIter->path(), stencilPathIter->fFill);
                 break;
             }
             case kDrawPath_Cmd: {
-                const DrawPath& cp = fDrawPath[currDrawPath];
-                fDstGpu->executeDrawPath(cp.fPath.get(), cp.fFill,
-                                         NULL != cp.fDstCopy.texture() ? &cp.fDstCopy : NULL);
-                ++currDrawPath;
+                SkASSERT(fDstGpu->drawState() != prevDrawState);
+                SkAssertResult(drawPathIter.next());
+                fDstGpu->executeDrawPath(drawPathIter->path(), drawPathIter->fFill,
+                                         drawPathIter->fDstCopy.texture() ?
+                                            &drawPathIter->fDstCopy :
+                                            NULL);
                 break;
             }
             case kDrawPaths_Cmd: {
-                DrawPaths& dp = fDrawPaths[currDrawPaths];
+                SkASSERT(fDstGpu->drawState() != prevDrawState);
+                SkAssertResult(drawPathsIter.next());
                 const GrDeviceCoordTexture* dstCopy =
-                    NULL != dp.fDstCopy.texture() ? &dp.fDstCopy : NULL;
-                fDstGpu->executeDrawPaths(dp.fPathCount, dp.fPaths,
-                                          dp.fTransforms, dp.fFill, dp.fStroke,
+                    drawPathsIter->fDstCopy.texture() ? &drawPathsIter->fDstCopy : NULL;
+                fDstGpu->executeDrawPaths(drawPathsIter->pathRange(),
+                                          drawPathsIter->fIndices,
+                                          drawPathsIter->fCount,
+                                          drawPathsIter->fTransforms,
+                                          drawPathsIter->fTransformsType,
+                                          drawPathsIter->fFill,
                                           dstCopy);
-                ++currDrawPaths;
                 break;
             }
             case kSetState_Cmd:
-                fStates[currState].restoreTo(&playbackState);
-                ++currState;
+                SkAssertResult(stateIter.next());
+                fDstGpu->setDrawState(stateIter.get());
                 break;
             case kSetClip_Cmd:
-                clipData.fClipStack = &fClips[currClip];
-                clipData.fOrigin = fClipOrigins[currClip];
+                SkAssertResult(clipIter.next());
+                clipData.fClipStack = &clipIter->fStack;
+                clipData.fOrigin = clipIter->fOrigin;
                 fDstGpu->setClip(&clipData);
-                ++currClip;
                 break;
             case kClear_Cmd:
-                if (GrColor_ILLEGAL == fClears[currClear].fColor) {
-                    fDstGpu->discard(fClears[currClear].fRenderTarget);
+                SkAssertResult(clearIter.next());
+                if (GrColor_ILLEGAL == clearIter->fColor) {
+                    fDstGpu->discard(clearIter->renderTarget());
                 } else {
-                    fDstGpu->clear(&fClears[currClear].fRect,
-                                   fClears[currClear].fColor,
-                                   fClears[currClear].fCanIgnoreRect,
-                                   fClears[currClear].fRenderTarget);
+                    fDstGpu->clear(&clearIter->fRect,
+                                   clearIter->fColor,
+                                   clearIter->fCanIgnoreRect,
+                                   clearIter->renderTarget());
                 }
-                ++currClear;
                 break;
             case kCopySurface_Cmd:
-                fDstGpu->copySurface(fCopySurfaces[currCopySurface].fDst.get(),
-                                     fCopySurfaces[currCopySurface].fSrc.get(),
-                                     fCopySurfaces[currCopySurface].fSrcRect,
-                                     fCopySurfaces[currCopySurface].fDstPoint);
-                ++currCopySurface;
+                SkAssertResult(copySurfaceIter.next());
+                fDstGpu->copySurface(copySurfaceIter->dst(),
+                                     copySurfaceIter->src(),
+                                     copySurfaceIter->fSrcRect,
+                                     copySurfaceIter->fDstPoint);
                 break;
         }
         if (cmd_has_trace_marker(fCmds[c])) {
@@ -672,12 +588,15 @@
     }
     fDstGpu->restoreActiveTraceMarkers();
     // we should have consumed all the states, clips, etc.
-    SkASSERT(fStates.count() == currState);
-    SkASSERT(fClips.count() == currClip);
-    SkASSERT(fClipOrigins.count() == currClip);
-    SkASSERT(fClears.count() == currClear);
-    SkASSERT(fDraws.count()  == currDraw);
-    SkASSERT(fCopySurfaces.count() == currCopySurface);
+    SkASSERT(!stateIter.next());
+    SkASSERT(!clipIter.next());
+    SkASSERT(!clearIter.next());
+    SkASSERT(!drawIter.next());
+    SkASSERT(!copySurfaceIter.next());
+    SkASSERT(!stencilPathIter.next());
+    SkASSERT(!drawPathIter.next());
+    SkASSERT(!drawPathsIter.next());
+
     SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
 
     fDstGpu->setDrawState(prevDrawState);
@@ -691,9 +610,7 @@
                                         const SkIRect& srcRect,
                                         const SkIPoint& dstPoint) {
     if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) {
-        CopySurface* cs = this->recordCopySurface();
-        cs->fDst.reset(SkRef(dst));
-        cs->fSrc.reset(SkRef(src));
+        CopySurface* cs = this->recordCopySurface(dst, src);
         cs->fSrcRect = srcRect;
         cs->fDstPoint = dstPoint;
         return true;
@@ -754,7 +671,7 @@
     // preallocated buffer but none are left and it can't fit
     // in the current buffer (which may not be prealloced).
     bool flush = false;
-    if (NULL != indexCount) {
+    if (indexCount) {
         int32_t currIndices = fIndexPool.currentBufferIndices();
         if (*indexCount > currIndices &&
             (!fIndexPool.preallocatedBuffersRemaining() &&
@@ -764,12 +681,12 @@
         }
         *indexCount = currIndices;
     }
-    if (NULL != vertexCount) {
-        size_t vertexSize = this->getDrawState().getVertexSize();
-        int32_t currVertices = fVertexPool.currentBufferVertices(vertexSize);
+    if (vertexCount) {
+        size_t vertexStride = this->getDrawState().getVertexStride();
+        int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride);
         if (*vertexCount > currVertices &&
             (!fVertexPool.preallocatedBuffersRemaining() &&
-             *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexSize))) {
+             *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride))) {
 
             flush = true;
         }
@@ -783,26 +700,26 @@
                                                void** vertices) {
     GeometryPoolState& poolState = fGeoPoolStateStack.back();
     SkASSERT(vertexCount > 0);
-    SkASSERT(NULL != vertices);
+    SkASSERT(vertices);
     SkASSERT(0 == poolState.fUsedPoolVertexBytes);
 
     *vertices = fVertexPool.makeSpace(vertexSize,
                                       vertexCount,
                                       &poolState.fPoolVertexBuffer,
                                       &poolState.fPoolStartVertex);
-    return NULL != *vertices;
+    return SkToBool(*vertices);
 }
 
 bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
     GeometryPoolState& poolState = fGeoPoolStateStack.back();
     SkASSERT(indexCount > 0);
-    SkASSERT(NULL != indices);
+    SkASSERT(indices);
     SkASSERT(0 == poolState.fUsedPoolIndexBytes);
 
     *indices = fIndexPool.makeSpace(indexCount,
                                     &poolState.fPoolIndexBuffer,
                                     &poolState.fPoolStartIndex);
-    return NULL != *indices;
+    return SkToBool(*indices);
 }
 
 void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
@@ -844,9 +761,7 @@
     poolState.fPoolStartIndex = 0;
 }
 
-void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
-                                                   int vertexCount) {
-
+void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) {
     GeometryPoolState& poolState = fGeoPoolStateStack.back();
     SkASSERT(0 == poolState.fUsedPoolVertexBytes);
 #ifdef SK_DEBUG
@@ -898,8 +813,7 @@
 #endif
 }
 
-void GrInOrderDrawBuffer::geometrySourceWillPop(
-                                        const GeometrySrcState& restoredState) {
+void GrInOrderDrawBuffer::geometrySourceWillPop(const GeometrySrcState& restoredState) {
     SkASSERT(fGeoPoolStateStack.count() > 1);
     fGeoPoolStateStack.pop_back();
     GeometryPoolState& poolState = fGeoPoolStateStack.back();
@@ -917,17 +831,38 @@
     }
 }
 
-bool GrInOrderDrawBuffer::needsNewState() const {
-    return fStates.empty() || !fStates.back().isEqual(this->getDrawState());
+void GrInOrderDrawBuffer::recordStateIfNecessary() {
+    if (fStates.empty()) {
+        this->convertDrawStateToPendingExec(&fStates.push_back(this->getDrawState()));
+        this->addToCmdBuffer(kSetState_Cmd);
+        return;
+    }
+    const GrDrawState& curr = this->getDrawState();
+    GrDrawState& prev = fStates.back();
+    switch (GrDrawState::CombineIfPossible(prev, curr, *this->caps())) {
+        case GrDrawState::kIncompatible_CombinedState:
+            this->convertDrawStateToPendingExec(&fStates.push_back(curr));
+            this->addToCmdBuffer(kSetState_Cmd);
+            break;
+        case GrDrawState::kA_CombinedState:
+        case GrDrawState::kAOrB_CombinedState: // Treat the same as kA.
+            break;
+        case GrDrawState::kB_CombinedState:
+            // prev has already been converted to pending execution. That is a one-way ticket.
+            // So here we just delete prev and push back a new copy of curr. Note that this
+            // goes away when we move GrIODB over to taking optimized snapshots of draw states.
+            fStates.pop_back();
+            this->convertDrawStateToPendingExec(&fStates.push_back(curr));
+            break;
+    }
 }
 
 bool GrInOrderDrawBuffer::needsNewClip() const {
-    SkASSERT(fClips.count() == fClipOrigins.count());
     if (this->getDrawState().isClipState()) {
        if (fClipSet &&
            (fClips.empty() ||
-            fClips.back() != *this->getClip()->fClipStack ||
-            fClipOrigins.back() != this->getClip()->fOrigin)) {
+            fClips.back().fStack != *this->getClip()->fClipStack ||
+            fClips.back().fOrigin != this->getClip()->fOrigin)) {
            return true;
        }
     }
@@ -946,48 +881,45 @@
 }
 
 void GrInOrderDrawBuffer::recordClip() {
-    fClips.push_back(*this->getClip()->fClipStack);
-    fClipOrigins.push_back() = this->getClip()->fOrigin;
+    fClips.push_back().fStack = *this->getClip()->fClipStack;
+    fClips.back().fOrigin = this->getClip()->fOrigin;
     fClipSet = false;
     this->addToCmdBuffer(kSetClip_Cmd);
 }
 
-void GrInOrderDrawBuffer::recordState() {
-    fStates.push_back().saveFrom(this->getDrawState());
-    this->addToCmdBuffer(kSetState_Cmd);
-}
-
-GrInOrderDrawBuffer::DrawRecord* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info) {
+GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info,
+                                                           const GrVertexBuffer* vb,
+                                                           const GrIndexBuffer* ib) {
     this->addToCmdBuffer(kDraw_Cmd);
-    return &fDraws.push_back(info);
+    return GrNEW_APPEND_TO_ALLOCATOR(&fDraws, Draw, (info, vb, ib));
 }
 
-GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
+GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath(const GrPath* path) {
     this->addToCmdBuffer(kStencilPath_Cmd);
-    return &fStencilPaths.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fStencilPaths, StencilPath, (path));
 }
 
-GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath() {
+GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath(const GrPath* path) {
     this->addToCmdBuffer(kDrawPath_Cmd);
-    return &fDrawPath.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPath, DrawPath, (path));
 }
 
-GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths() {
+GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths(const GrPathRange* pathRange) {
     this->addToCmdBuffer(kDrawPaths_Cmd);
-    return &fDrawPaths.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPaths, DrawPaths, (pathRange));
 }
 
-GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
+GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear(GrRenderTarget* rt) {
     this->addToCmdBuffer(kClear_Cmd);
-    return &fClears.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fClears, Clear, (rt));
 }
 
-GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface() {
+GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface(GrSurface* dst,
+                                                                         GrSurface* src) {
     this->addToCmdBuffer(kCopySurface_Cmd);
-    return &fCopySurfaces.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fCopySurfaces, CopySurface, (dst, src));
 }
 
-
 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {
     INHERITED::clipWillBeSet(newClipData);
     fClipSet = true;
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index 34fb0a7..e6ed06e 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -11,7 +11,12 @@
 #include "GrDrawTarget.h"
 #include "GrAllocPool.h"
 #include "GrAllocator.h"
+#include "GrIndexBuffer.h"
+#include "GrRenderTarget.h"
 #include "GrPath.h"
+#include "GrPathRange.h"
+#include "GrSurface.h"
+#include "GrVertexBuffer.h"
 
 #include "SkClipStack.h"
 #include "SkTemplates.h"
@@ -93,71 +98,116 @@
         kDrawPaths_Cmd      = 8,
     };
 
-    class DrawRecord : public DrawInfo {
+    class Draw : public DrawInfo {
     public:
-        DrawRecord(const DrawInfo& info) : DrawInfo(info) {}
-        const GrVertexBuffer*   fVertexBuffer;
-        const GrIndexBuffer*    fIndexBuffer;
+        Draw(const DrawInfo& info, const GrVertexBuffer* vb, const GrIndexBuffer* ib)
+            : DrawInfo(info)
+            , fVertexBuffer(vb)
+            , fIndexBuffer(ib) {}
+
+        const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
+        const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
+
+    private:
+        GrPendingIOResource<const GrVertexBuffer, GrIORef::kRead_IOType>    fVertexBuffer;
+        GrPendingIOResource<const GrIndexBuffer, GrIORef::kRead_IOType>     fIndexBuffer;
     };
 
     struct StencilPath : public ::SkNoncopyable {
-        StencilPath();
+        StencilPath(const GrPath* path) : fPath(path) {}
 
-        SkAutoTUnref<const GrPath>  fPath;
-        SkPath::FillType            fFill;
+        const GrPath* path() const { return fPath.get(); }
+
+        SkPath::FillType fFill;
+
+    private:
+        GrPendingIOResource<const GrPath, GrIORef::kRead_IOType>   fPath;
     };
 
     struct DrawPath : public ::SkNoncopyable {
-        DrawPath();
+        DrawPath(const GrPath* path) : fPath(path) {}
 
-        SkAutoTUnref<const GrPath>  fPath;
-        SkPath::FillType            fFill;
-        GrDeviceCoordTexture        fDstCopy;
+        const GrPath* path() const { return fPath.get(); }
+
+        SkPath::FillType        fFill;
+        GrDeviceCoordTexture    fDstCopy;
+
+    private:
+        GrPendingIOResource<const GrPath, GrIORef::kRead_IOType> fPath;
     };
 
     struct DrawPaths : public ::SkNoncopyable {
-        DrawPaths();
-        ~DrawPaths();
+        DrawPaths(const GrPathRange* pathRange)
+            : fPathRange(pathRange) {}
 
-        int fPathCount;
-        const GrPath** fPaths;
-        SkMatrix* fTransforms;
-        SkPath::FillType fFill;
-        SkStrokeRec::Style fStroke;
-        GrDeviceCoordTexture fDstCopy;
+        ~DrawPaths() {
+            if (fTransforms) {
+                SkDELETE_ARRAY(fTransforms);
+            }
+            if (fIndices) {
+                SkDELETE_ARRAY(fIndices);
+            }
+        }
+
+        const GrPathRange* pathRange() const { return fPathRange.get();  }
+
+        uint32_t*               fIndices;
+        size_t                  fCount;
+        float*                  fTransforms;
+        PathTransformType       fTransformsType;
+        SkPath::FillType        fFill;
+        GrDeviceCoordTexture    fDstCopy;
+
+    private:
+        GrPendingIOResource<const GrPathRange, GrIORef::kRead_IOType> fPathRange;
     };
 
     // This is also used to record a discard by setting the color to GrColor_ILLEGAL
     struct Clear : public ::SkNoncopyable {
-        Clear() : fRenderTarget(NULL) {}
-        ~Clear() { SkSafeUnref(fRenderTarget); }
+        Clear(GrRenderTarget* rt) : fRenderTarget(rt) {}
+        ~Clear() { }
+        GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
 
-        SkIRect         fRect;
-        GrColor         fColor;
-        bool            fCanIgnoreRect;
-        GrRenderTarget* fRenderTarget;
+        SkIRect fRect;
+        GrColor fColor;
+        bool    fCanIgnoreRect;
+
+    private:
+        GrPendingIOResource<GrRenderTarget, GrIORef::kWrite_IOType> fRenderTarget;
     };
 
     struct CopySurface : public ::SkNoncopyable {
-        SkAutoTUnref<GrSurface> fDst;
-        SkAutoTUnref<GrSurface> fSrc;
-        SkIRect                 fSrcRect;
-        SkIPoint                fDstPoint;
+        CopySurface(GrSurface* dst, GrSurface* src) : fDst(dst), fSrc(src) {}
+
+        GrSurface* dst() const { return fDst.get(); }
+        GrSurface* src() const { return fSrc.get(); }
+
+        SkIPoint    fDstPoint;
+        SkIRect     fSrcRect;
+
+    private:
+        GrPendingIOResource<GrSurface, GrIORef::kWrite_IOType> fDst;
+        GrPendingIOResource<GrSurface, GrIORef::kRead_IOType> fSrc;
+    };
+
+    struct Clip : public ::SkNoncopyable {
+        SkClipStack fStack;
+        SkIPoint    fOrigin;
     };
 
     // overrides from GrDrawTarget
     virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
     virtual void onDrawRect(const SkRect& rect,
-                            const SkMatrix* matrix,
                             const SkRect* localRect,
                             const SkMatrix* localMatrix) SK_OVERRIDE;
 
     virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
     virtual void onDrawPath(const GrPath*, SkPath::FillType,
                             const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
-    virtual void onDrawPaths(int, const GrPath**, const SkMatrix*,
-                             SkPath::FillType, SkStrokeRec::Style,
-                             const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
+    virtual void onDrawPaths(const GrPathRange*,
+                             const uint32_t indices[], int count,
+                             const float transforms[], PathTransformType,
+                             SkPath::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE;
 
     virtual bool onReserveVertexSpace(size_t vertexSize,
                                       int vertexCount,
@@ -194,82 +244,89 @@
     // instanced draw. The caller must have already recorded a new draw state and clip if necessary.
     int concatInstancedDraw(const DrawInfo& info);
 
-    // we lazily record state and clip changes in order to skip clips and states that have no
-    // effect.
-    bool needsNewState() const;
+    // Determines whether the current draw operation requieres a new drawstate and if so records it.
+    void recordStateIfNecessary();
+    // We lazily record clip changes in order to skip clips that have no effect.
     bool needsNewClip() const;
 
     // these functions record a command
     void            recordState();
     void            recordClip();
-    DrawRecord*     recordDraw(const DrawInfo&);
-    StencilPath*    recordStencilPath();
-    DrawPath*       recordDrawPath();
-    DrawPaths*      recordDrawPaths();
-    Clear*          recordClear();
-    CopySurface*    recordCopySurface();
+    Draw*           recordDraw(const DrawInfo&, const GrVertexBuffer*, const GrIndexBuffer*);
+    StencilPath*    recordStencilPath(const GrPath*);
+    DrawPath*       recordDrawPath(const GrPath*);
+    DrawPaths*      recordDrawPaths(const GrPathRange*);
+    Clear*          recordClear(GrRenderTarget*);
+    CopySurface*    recordCopySurface(GrSurface* dst, GrSurface* src);
+
+    virtual bool isIssued(uint32_t drawID) { return drawID != fDrawID; }
+    void addToCmdBuffer(uint8_t cmd);
 
     // TODO: Use a single allocator for commands and records
     enum {
         kCmdPreallocCnt          = 32,
-        kDrawPreallocCnt         = 8,
+        kDrawPreallocCnt         = 16,
         kStencilPathPreallocCnt  = 8,
         kDrawPathPreallocCnt     = 8,
         kDrawPathsPreallocCnt    = 8,
         kStatePreallocCnt        = 8,
         kClipPreallocCnt         = 8,
-        kClearPreallocCnt        = 4,
+        kClearPreallocCnt        = 8,
         kGeoPoolStatePreAllocCnt = 4,
         kCopySurfacePreallocCnt  = 4,
     };
 
-    SkSTArray<kCmdPreallocCnt, uint8_t, true>                          fCmds;
-    GrSTAllocator<kDrawPreallocCnt, DrawRecord>                        fDraws;
-    GrSTAllocator<kStencilPathPreallocCnt, StencilPath>                fStencilPaths;
-    GrSTAllocator<kDrawPathPreallocCnt, DrawPath>                      fDrawPath;
-    GrSTAllocator<kDrawPathsPreallocCnt, DrawPaths>                    fDrawPaths;
-    GrSTAllocator<kStatePreallocCnt, GrDrawState::DeferredState>       fStates;
-    GrSTAllocator<kClearPreallocCnt, Clear>                            fClears;
-    GrSTAllocator<kCopySurfacePreallocCnt, CopySurface>                fCopySurfaces;
-    GrSTAllocator<kClipPreallocCnt, SkClipStack>                       fClips;
-    GrSTAllocator<kClipPreallocCnt, SkIPoint>                          fClipOrigins;
-    SkTArray<GrTraceMarkerSet, false>                                  fGpuCmdMarkers;
+    typedef GrTAllocator<Draw>          DrawAllocator;
+    typedef GrTAllocator<StencilPath>   StencilPathAllocator;
+    typedef GrTAllocator<DrawPath>      DrawPathAllocator;
+    typedef GrTAllocator<DrawPaths>     DrawPathsAllocator;
+    typedef GrTAllocator<GrDrawState>   StateAllocator;
+    typedef GrTAllocator<Clear>         ClearAllocator;
+    typedef GrTAllocator<CopySurface>   CopySurfaceAllocator;
+    typedef GrTAllocator<Clip>          ClipAllocator;
 
-    GrDrawTarget*                   fDstGpu;
+    GrSTAllocator<kDrawPreallocCnt, Draw>               fDraws;
+    GrSTAllocator<kStencilPathPreallocCnt, StencilPath> fStencilPaths;
+    GrSTAllocator<kDrawPathPreallocCnt, DrawPath>       fDrawPath;
+    GrSTAllocator<kDrawPathsPreallocCnt, DrawPaths>     fDrawPaths;
+    GrSTAllocator<kStatePreallocCnt, GrDrawState>       fStates;
+    GrSTAllocator<kClearPreallocCnt, Clear>             fClears;
+    GrSTAllocator<kCopySurfacePreallocCnt, CopySurface> fCopySurfaces;
+    GrSTAllocator<kClipPreallocCnt, Clip>               fClips;
 
-    bool                            fClipSet;
+    SkTArray<GrTraceMarkerSet, false>                   fGpuCmdMarkers;
+    SkSTArray<kCmdPreallocCnt, uint8_t, true>           fCmds;
+    GrDrawTarget*                                       fDstGpu;
+    bool                                                fClipSet;
 
     enum ClipProxyState {
         kUnknown_ClipProxyState,
         kValid_ClipProxyState,
         kInvalid_ClipProxyState
     };
-    ClipProxyState                  fClipProxyState;
-    SkRect                          fClipProxy;
 
-    GrVertexBufferAllocPool&        fVertexPool;
-
-    GrIndexBufferAllocPool&         fIndexPool;
+    ClipProxyState                                      fClipProxyState;
+    SkRect                                              fClipProxy;
+    GrVertexBufferAllocPool&                            fVertexPool;
+    GrIndexBufferAllocPool&                             fIndexPool;
 
     struct GeometryPoolState {
-        const GrVertexBuffer*           fPoolVertexBuffer;
-        int                             fPoolStartVertex;
-        const GrIndexBuffer*            fPoolIndexBuffer;
-        int                             fPoolStartIndex;
+        const GrVertexBuffer*   fPoolVertexBuffer;
+        int                     fPoolStartVertex;
+        const GrIndexBuffer*    fPoolIndexBuffer;
+        int                     fPoolStartIndex;
         // caller may conservatively over reserve vertices / indices.
         // we release unused space back to allocator if possible
         // can only do this if there isn't an intervening pushGeometrySource()
-        size_t                          fUsedPoolVertexBytes;
-        size_t                          fUsedPoolIndexBytes;
+        size_t                  fUsedPoolVertexBytes;
+        size_t                  fUsedPoolIndexBytes;
     };
-    SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
 
-    virtual bool       isIssued(uint32_t drawID) { return drawID != fDrawID; }
+    typedef SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> GeoPoolStateStack;
 
-    void addToCmdBuffer(uint8_t cmd);
-
-    bool                            fFlushing;
-    uint32_t                        fDrawID;
+    GeoPoolStateStack                                   fGeoPoolStateStack;
+    bool                                                fFlushing;
+    uint32_t                                            fDrawID;
 
     typedef GrDrawTarget INHERITED;
 };
diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp
index f6377bf..11a97e4 100644
--- a/src/gpu/GrLayerCache.cpp
+++ b/src/gpu/GrLayerCache.cpp
@@ -9,78 +9,420 @@
 #include "GrGpu.h"
 #include "GrLayerCache.h"
 
-/**
- *  PictureLayerKey just wraps a saveLayer's id in the picture for GrTHashTable.
- */
-class GrLayerCache::PictureLayerKey {
-public:
-    PictureLayerKey(uint32_t pictureID, int layerID)
-        : fPictureID(pictureID)
-        , fLayerID(layerID) {
-    }
+DECLARE_SKMESSAGEBUS_MESSAGE(GrPictureDeletedMessage);
 
-    uint32_t pictureID() const { return fPictureID; }
-    int layerID() const { return fLayerID; }
+#ifdef SK_DEBUG
+void GrCachedLayer::validate(const GrTexture* backingTexture) const {
+    SkASSERT(SK_InvalidGenID != fKey.pictureID());
+    SkASSERT(fKey.start() > 0 && fKey.stop() > 0);
 
-    uint32_t getHash() const { return (fPictureID << 16) | fLayerID; }
 
-    static bool LessThan(const GrCachedLayer& layer, const PictureLayerKey& key) {
-        if (layer.pictureID() == key.pictureID()) {
-            return layer.layerID() < key.layerID();
+    if (fTexture) {
+        // If the layer is in some texture then it must occupy some rectangle
+        SkASSERT(!fRect.isEmpty());
+        if (!this->isAtlased()) {
+            // If it isn't atlased then the rectangle should start at the origin
+            SkASSERT(0.0f == fRect.fLeft && 0.0f == fRect.fTop);
         }
-
-        return layer.pictureID() < key.pictureID();
+    } else {
+        SkASSERT(fRect.isEmpty());
+        SkASSERT(NULL == fPlot);
+        SkASSERT(!fLocked);     // layers without a texture cannot be locked
     }
 
-    static bool Equals(const GrCachedLayer& layer, const PictureLayerKey& key) {
-        return layer.pictureID() == key.pictureID() && layer.layerID() == key.layerID();
+    if (fPlot) {
+        // If a layer has a plot (i.e., is atlased) then it must point to
+        // the backing texture. Additionally, its rect should be non-empty.
+        SkASSERT(fTexture && backingTexture == fTexture);
+        SkASSERT(!fRect.isEmpty());
+    }
+
+    if (fLocked) {
+        // If a layer is locked it must have a texture (though it need not be
+        // the atlas-backing texture) and occupy some space.
+        SkASSERT(fTexture);
+        SkASSERT(!fRect.isEmpty());
+    }
+}
+
+class GrAutoValidateLayer : ::SkNoncopyable {
+public:
+    GrAutoValidateLayer(GrTexture* backingTexture, const GrCachedLayer* layer) 
+        : fBackingTexture(backingTexture)
+        , fLayer(layer) {
+        if (fLayer) {
+            fLayer->validate(backingTexture);
+        }
+    }
+    ~GrAutoValidateLayer() {
+        if (fLayer) {
+            fLayer->validate(fBackingTexture);
+        }
+    }
+    void setBackingTexture(GrTexture* backingTexture) {
+        SkASSERT(NULL == fBackingTexture || fBackingTexture == backingTexture);
+        fBackingTexture = backingTexture;
     }
 
 private:
-    uint32_t fPictureID;
-    int      fLayerID;
+    const GrTexture* fBackingTexture;
+    const GrCachedLayer* fLayer;
 };
+#endif
 
-GrLayerCache::GrLayerCache(GrGpu* gpu)
-    : fGpu(SkRef(gpu))
-    , fLayerPool(16) {      // TODO: may need to increase this later
+GrLayerCache::GrLayerCache(GrContext* context)
+    : fContext(context) {
+    this->initAtlas();
+    memset(fPlotLocks, 0, sizeof(fPlotLocks));
 }
 
 GrLayerCache::~GrLayerCache() {
+
+    SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
+    for (; !iter.done(); ++iter) {
+        GrCachedLayer* layer = &(*iter);
+        this->unlock(layer);
+        SkDELETE(layer);
+    }
+
+    // The atlas only lets go of its texture when the atlas is deleted. 
+    fAtlas.free();    
 }
 
-void GrLayerCache::init() {
-    static const int kAtlasTextureWidth = 1024;
-    static const int kAtlasTextureHeight = 1024;
+void GrLayerCache::initAtlas() {
+    SkASSERT(NULL == fAtlas.get());
 
-    SkASSERT(NULL == fAtlasMgr.get());
-
-    // The layer cache only gets 1 plot
     SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight);
-    fAtlasMgr.reset(SkNEW_ARGS(GrAtlasMgr, (fGpu, kSkia8888_GrPixelConfig,
-                                            textureSize, 1, 1, false)));
+    fAtlas.reset(SkNEW_ARGS(GrAtlas, (fContext->getGpu(), kSkia8888_GrPixelConfig,
+                                      kRenderTarget_GrTextureFlagBit,
+                                      textureSize, kNumPlotsX, kNumPlotsY, false)));
 }
 
 void GrLayerCache::freeAll() {
-    fLayerHash.deleteAll();
-    fAtlasMgr.free();
-}
 
-GrCachedLayer* GrLayerCache::createLayer(const SkPicture* picture, int layerID) {
-    GrCachedLayer* layer = fLayerPool.alloc();
-
-    SkASSERT(picture->uniqueID() != SK_InvalidGenID);
-    layer->init(picture->uniqueID(), layerID);
-    fLayerHash.insert(PictureLayerKey(picture->uniqueID(), layerID), layer);
-    return layer;
-}
-
-
-GrCachedLayer* GrLayerCache::findLayerOrCreate(const SkPicture* picture, int layerID) {
-    SkASSERT(picture->uniqueID() != SK_InvalidGenID);
-    GrCachedLayer* layer = fLayerHash.find(PictureLayerKey(picture->uniqueID(), layerID));
-    if (NULL == layer) {
-        layer = this->createLayer(picture, layerID);
+    SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
+    for (; !iter.done(); ++iter) {
+        GrCachedLayer* layer = &(*iter);
+        this->unlock(layer);
+        SkDELETE(layer);
     }
+    fLayerHash.rewind();
+
+    // The atlas only lets go of its texture when the atlas is deleted. 
+    fAtlas.free();
+    // GrLayerCache always assumes an atlas exists so recreate it. The atlas 
+    // lazily allocates a replacement texture so reallocating a new 
+    // atlas here won't disrupt a GrContext::abandonContext or freeGpuResources.
+    // TODO: Make GrLayerCache lazily allocate the atlas manager?
+    this->initAtlas();
+}
+
+GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID, 
+                                         int start, int stop, 
+                                         const SkIPoint& offset,
+                                         const SkMatrix& ctm,
+                                         const SkPaint* paint) {
+    SkASSERT(pictureID != SK_InvalidGenID && start > 0 && stop > 0);
+
+    GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, offset, ctm, paint));
+    fLayerHash.add(layer);
     return layer;
 }
+
+GrCachedLayer* GrLayerCache::findLayer(uint32_t pictureID,
+                                       int start, int stop, 
+                                       const SkIPoint& offset,
+                                       const SkMatrix& ctm) {
+    SkASSERT(pictureID != SK_InvalidGenID && start > 0 && stop > 0);
+    return fLayerHash.find(GrCachedLayer::Key(pictureID, start, stop, offset, ctm));
+}
+
+GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID,
+                                               int start, int stop,
+                                               const SkIPoint& offset,
+                                               const SkMatrix& ctm,
+                                               const SkPaint* paint) {
+    SkASSERT(pictureID != SK_InvalidGenID && start > 0 && stop > 0);
+    GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(pictureID, start, stop, offset, ctm));
+    if (NULL == layer) {
+        layer = this->createLayer(pictureID, start, stop, offset, ctm, paint);
+    }
+
+    return layer;
+}
+
+bool GrLayerCache::lock(GrCachedLayer* layer, const GrTextureDesc& desc, bool dontAtlas) {
+    SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);)
+
+    if (layer->locked()) {
+        // This layer is already locked
+#ifdef SK_DEBUG
+        if (layer->isAtlased()) {
+            // It claims to be atlased
+            SkASSERT(!dontAtlas);
+            SkASSERT(layer->rect().width() == desc.fWidth);
+            SkASSERT(layer->rect().height() == desc.fHeight);
+        }
+#endif
+        return false;
+    }
+
+    if (layer->isAtlased()) {
+        // Hooray it is still in the atlas - make sure it stays there
+        SkASSERT(!dontAtlas);
+        layer->setLocked(true);
+        fPlotLocks[layer->plot()->id()]++;
+        return false;
+    } else if (!dontAtlas && PlausiblyAtlasable(desc.fWidth, desc.fHeight)) {
+        // Not in the atlas - will it fit?
+        GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
+        if (NULL == pictInfo) {
+            pictInfo = SkNEW_ARGS(GrPictureInfo, (layer->pictureID()));
+            fPictureHash.add(pictInfo);
+        }
+
+        SkIPoint16 loc;
+        for (int i = 0; i < 2; ++i) { // extra pass in case we fail to add but are able to purge
+            GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage,
+                                              desc.fWidth, desc.fHeight,
+                                              NULL, &loc);
+            // addToAtlas can allocate the backing texture
+            SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture()));
+            if (plot) {
+                // The layer was successfully added to the atlas
+                GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY,
+                                                       SkToS16(desc.fWidth),
+                                                       SkToS16(desc.fHeight));
+                layer->setTexture(fAtlas->getTexture(), bounds);
+                layer->setPlot(plot);
+                layer->setLocked(true);
+                fPlotLocks[layer->plot()->id()]++;
+                return true;
+            }
+
+            // The layer was rejected by the atlas (even though we know it is 
+            // plausibly atlas-able). See if a plot can be purged and try again.
+            if (!this->purgePlot()) {
+                break;  // We weren't able to purge any plots
+            }
+        }
+    }
+
+    // The texture wouldn't fit in the cache - give it it's own texture.
+    // This path always uses a new scratch texture and (thus) doesn't cache anything.
+    // This can yield a lot of re-rendering
+    SkAutoTUnref<GrTexture> tex(fContext->lockAndRefScratchTexture(desc,
+                                                        GrContext::kApprox_ScratchTexMatch));
+
+    layer->setTexture(tex, GrIRect16::MakeWH(SkToS16(desc.fWidth), SkToS16(desc.fHeight)));
+    layer->setLocked(true);
+    return true;
+}
+
+void GrLayerCache::unlock(GrCachedLayer* layer) {
+    SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);)
+
+    if (NULL == layer || !layer->locked()) {
+        // invalid or not locked
+        return;
+    }
+
+    if (layer->isAtlased()) {
+        const int plotID = layer->plot()->id();
+
+        SkASSERT(fPlotLocks[plotID] > 0);
+        fPlotLocks[plotID]--;
+        // At this point we could aggressively clear out un-locked plots but
+        // by delaying we may be able to reuse some of the atlased layers later.
+#if DISABLE_CACHING
+        // This testing code aggressively removes the atlased layers. This
+        // can be used to separate the performance contribution of less
+        // render target pingponging from that due to the re-use of cached layers
+        GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
+        SkASSERT(pictInfo);
+        
+        GrAtlas::RemovePlot(&pictInfo->fPlotUsage, layer->plot());
+        
+        layer->setPlot(NULL);
+        layer->setTexture(NULL, GrIRect16::MakeEmpty());
+#endif
+
+    } else {
+        fContext->unlockScratchTexture(layer->texture());
+        layer->setTexture(NULL, GrIRect16::MakeEmpty());
+    }
+
+    layer->setLocked(false);
+}
+
+#ifdef SK_DEBUG
+void GrLayerCache::validate() const {
+    int plotLocks[kNumPlotsX * kNumPlotsY];
+    memset(plotLocks, 0, sizeof(plotLocks));
+
+    SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::ConstIter iter(&fLayerHash);
+    for (; !iter.done(); ++iter) {
+        const GrCachedLayer* layer = &(*iter);
+
+        layer->validate(fAtlas->getTexture());
+
+        const GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
+        if (pictInfo) {
+            // In aggressive cleanup mode a picture info should only exist if
+            // it has some atlased layers
+#if !DISABLE_CACHING
+            SkASSERT(!pictInfo->fPlotUsage.isEmpty());
+#endif
+        } else {
+            // If there is no picture info for this layer then all of its
+            // layers should be non-atlased.
+            SkASSERT(!layer->isAtlased());
+        }
+
+        if (layer->plot()) {
+            SkASSERT(pictInfo);
+            SkASSERT(pictInfo->fPictureID == layer->pictureID());
+
+            SkASSERT(pictInfo->fPlotUsage.contains(layer->plot()));
+
+            if (layer->locked()) {
+                plotLocks[layer->plot()->id()]++;
+            }
+        } 
+    }
+
+    for (int i = 0; i < kNumPlotsX*kNumPlotsY; ++i) {
+        SkASSERT(plotLocks[i] == fPlotLocks[i]);
+    }
+}
+
+class GrAutoValidateCache : ::SkNoncopyable {
+public:
+    explicit GrAutoValidateCache(GrLayerCache* cache)
+        : fCache(cache) {
+        fCache->validate();
+    }
+    ~GrAutoValidateCache() {
+        fCache->validate();
+    }
+private:
+    GrLayerCache* fCache;
+};
+#endif
+
+void GrLayerCache::purge(uint32_t pictureID) {
+
+    SkDEBUGCODE(GrAutoValidateCache avc(this);)
+
+    // We need to find all the layers associated with 'picture' and remove them.
+    SkTDArray<GrCachedLayer*> toBeRemoved;
+
+    SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
+    for (; !iter.done(); ++iter) {
+        if (pictureID == (*iter).pictureID()) {
+            *toBeRemoved.append() = &(*iter);
+        }
+    }
+
+    for (int i = 0; i < toBeRemoved.count(); ++i) {
+        this->unlock(toBeRemoved[i]);
+        fLayerHash.remove(GrCachedLayer::GetKey(*toBeRemoved[i]));
+        SkDELETE(toBeRemoved[i]);
+    }
+
+    GrPictureInfo* pictInfo = fPictureHash.find(pictureID);
+    if (pictInfo) {
+        fPictureHash.remove(pictureID);
+        SkDELETE(pictInfo);
+    }
+}
+
+bool GrLayerCache::purgePlot() {
+    SkDEBUGCODE(GrAutoValidateCache avc(this);)
+
+    GrAtlas::PlotIter iter;
+    GrPlot* plot;
+    for (plot = fAtlas->iterInit(&iter, GrAtlas::kLRUFirst_IterOrder);
+         plot;
+         plot = iter.prev()) {
+        if (fPlotLocks[plot->id()] > 0) {
+            continue;
+        }
+
+        this->purgePlot(plot);
+        return true;
+    }
+
+    return false;
+}
+
+void GrLayerCache::purgePlot(GrPlot* plot) {
+    SkASSERT(0 == fPlotLocks[plot->id()]);
+
+    // We need to find all the layers in 'plot' and remove them.
+    SkTDArray<GrCachedLayer*> toBeRemoved;
+
+    SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
+    for (; !iter.done(); ++iter) {
+        if (plot == (*iter).plot()) {
+            *toBeRemoved.append() = &(*iter);
+        }
+    }
+
+    for (int i = 0; i < toBeRemoved.count(); ++i) {
+        SkASSERT(!toBeRemoved[i]->locked());
+
+        GrPictureInfo* pictInfo = fPictureHash.find(toBeRemoved[i]->pictureID());
+        SkASSERT(pictInfo);
+
+        GrAtlas::RemovePlot(&pictInfo->fPlotUsage, plot);
+
+        // Aggressively remove layers and, if now totally uncached, picture info
+        fLayerHash.remove(GrCachedLayer::GetKey(*toBeRemoved[i]));
+        SkDELETE(toBeRemoved[i]);
+
+        if (pictInfo->fPlotUsage.isEmpty()) {
+            fPictureHash.remove(pictInfo->fPictureID);
+            SkDELETE(pictInfo);
+        }
+    }
+
+    plot->resetRects();
+}
+
+void GrLayerCache::purgeAll() {
+    GrAtlas::PlotIter iter;
+    GrPlot* plot;
+    for (plot = fAtlas->iterInit(&iter, GrAtlas::kLRUFirst_IterOrder);
+         plot;
+         plot = iter.prev()) {
+        SkASSERT(0 == fPlotLocks[plot->id()]);
+
+        this->purgePlot(plot);
+    }
+}
+
+class GrPictureDeletionListener : public SkPicture::DeletionListener {
+    virtual void onDeletion(uint32_t pictureID) SK_OVERRIDE{
+        const GrPictureDeletedMessage message = { pictureID };
+        SkMessageBus<GrPictureDeletedMessage>::Post(message);
+    }
+};
+
+void GrLayerCache::trackPicture(const SkPicture* picture) {
+    if (NULL == fDeletionListener) {
+        fDeletionListener.reset(SkNEW(GrPictureDeletionListener));
+    }
+
+    picture->addDeletionListener(fDeletionListener);
+}
+
+void GrLayerCache::processDeletedPictures() {
+    SkTDArray<GrPictureDeletedMessage> deletedPictures;
+    fPictDeletionInbox.poll(&deletedPictures);
+
+    for (int i = 0; i < deletedPictures.count(); i++) {
+        this->purge(deletedPictures[i].pictureID);
+    }
+}
+
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h
index a957e78..38d4d9b 100644
--- a/src/gpu/GrLayerCache.h
+++ b/src/gpu/GrLayerCache.h
@@ -8,113 +8,266 @@
 #ifndef GrLayerCache_DEFINED
 #define GrLayerCache_DEFINED
 
-#include "GrAllocPool.h"
-#include "GrTHashTable.h"
+#include "GrAtlas.h"
 #include "GrPictureUtils.h"
 #include "GrRect.h"
+#include "SkChecksum.h"
+#include "SkTDynamicHash.h"
+#include "SkMessageBus.h"
 
-class GrAtlasMgr;
-class GrGpu;
-class GrPlot;
 class SkPicture;
 
-// GrAtlasLocation captures an atlased item's position in the atlas. This
-// means the plot in which it resides and its bounds inside the plot.
-// TODO: Make GrGlyph use one of these?
-class GrAtlasLocation {
+// The layer cache listens for these messages to purge picture-related resources.
+struct GrPictureDeletedMessage {
+    uint32_t pictureID;
+};
+
+// GrPictureInfo stores the atlas plots used by a single picture. A single 
+// plot may be used to store layers from multiple pictures.
+struct GrPictureInfo {
 public:
-    GrAtlasLocation() : fPlot(NULL) {}
+    // for SkTDynamicHash - just use the pictureID as the hash key
+    static const uint32_t& GetKey(const GrPictureInfo& pictInfo) { return pictInfo.fPictureID; }
+    static uint32_t Hash(const uint32_t& key) { return SkChecksum::Mix(key); }
 
-    void set(GrPlot* plot, const GrIRect16& bounds) {
-        fPlot = plot;
-        fBounds = bounds;
-    }
+    // GrPictureInfo proper
+    GrPictureInfo(uint32_t pictureID) : fPictureID(pictureID) { }
 
-    const GrPlot* plot() const {
-        return fPlot;
-    }
+    const uint32_t fPictureID;
 
-    const GrIRect16& bounds() const {
-        return fBounds;
-    }
-
-private:
-    GrPlot*   fPlot;
-    GrIRect16 fBounds;  // only valid is fPlot != NULL
+    GrAtlas::ClientPlotUsage  fPlotUsage;
 };
 
 // GrCachedLayer encapsulates the caching information for a single saveLayer.
 //
-// Atlased layers get a ref to their atlas GrTexture and their GrAtlasLocation
-// is filled in.
-// In this case GrCachedLayer is roughly equivalent to a GrGlyph in the font
-// caching system.
-//
-// Non-atlased layers get a ref to the GrTexture in which they reside.
-// TODO: can we easily reuse the empty space in the non-atlased GrTexture's?
+// Atlased layers get a ref to the backing GrTexture while non-atlased layers
+// get a ref to the GrTexture in which they reside. In both cases 'fRect' 
+// contains the layer's extent in its texture.
+// Atlased layers also get a pointer to the plot in which they reside.
+// For non-atlased layers, the lock field just corresponds to locking in
+// the resource cache. For atlased layers, it implements an additional level
+// of locking to allow atlased layers to be reused multiple times.
 struct GrCachedLayer {
 public:
-    uint32_t pictureID() const { return fPictureID; }
-    int layerID() const { return fLayerID; }
+    // For SkTDynamicHash
+    struct Key {
+        Key(uint32_t pictureID, int start, int stop, const SkIPoint& offset, const SkMatrix& ctm) 
+        : fPictureID(pictureID)
+        , fStart(start)
+        , fStop(stop)
+        , fOffset(offset)
+        , fCTM(ctm) {
+            fCTM.getType(); // force initialization of type so hashes match
 
-    void init(uint32_t pictureID, int layerID) {
-        fPictureID = pictureID;
-        fLayerID   = layerID;
-        fTexture   = NULL;
-        fLocation.set(NULL, GrIRect16::MakeEmpty());
-    }
-
-    // This call takes over the caller's ref
-    void setTexture(GrTexture* texture) {
-        if (NULL != fTexture) {
-            fTexture->unref();
+            // Key needs to be tightly packed.
+            GR_STATIC_ASSERT(sizeof(Key) == sizeof(uint32_t) + 2 * sizeof(int) + 
+                                            2 * sizeof(int32_t) +
+                                            9 * sizeof(SkScalar) + sizeof(uint32_t));
         }
 
-        fTexture = texture; // just take over caller's ref
+        bool operator==(const Key& other) const {
+            return fPictureID == other.fPictureID &&
+                   fStart == other.fStart &&
+                   fStop == other.fStop &&
+                   fOffset == other.fOffset &&
+                   fCTM.cheapEqualTo(other.fCTM);
+        }
+
+        uint32_t pictureID() const { return fPictureID; }
+        int start() const { return fStart; }
+        int stop() const { return fStop; }
+        const SkIPoint& offset() const { return fOffset; }
+        const SkMatrix& ctm() const { return fCTM; }
+
+    private:
+        // ID of the picture of which this layer is a part
+        const uint32_t fPictureID;
+        // The range of commands in the picture this layer represents
+        const int      fStart;
+        const int      fStop;
+        // The offset of the layer in device space
+        const SkIPoint fOffset;
+        // The CTM applied to this layer in the picture
+        SkMatrix       fCTM;
+    };
+
+    static const Key& GetKey(const GrCachedLayer& layer) { return layer.fKey; }
+    static uint32_t Hash(const Key& key) { 
+        return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&key), sizeof(Key));
     }
-    GrTexture* getTexture() { return fTexture; }
+
+    // GrCachedLayer proper
+    GrCachedLayer(uint32_t pictureID, int start, int stop,
+                  const SkIPoint& offset, const SkMatrix& ctm,
+                  const SkPaint* paint)
+        : fKey(pictureID, start, stop, offset, ctm)
+        , fPaint(paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL)
+        , fTexture(NULL)
+        , fRect(GrIRect16::MakeEmpty())
+        , fPlot(NULL)
+        , fLocked(false) {
+        SkASSERT(SK_InvalidGenID != pictureID && start >= 0 && stop >= 0);
+    }
+
+    ~GrCachedLayer() {
+        SkSafeUnref(fTexture);
+        SkDELETE(fPaint);
+    }
+
+    uint32_t pictureID() const { return fKey.pictureID(); }
+    int start() const { return fKey.start(); }
+    int stop() const { return fKey.stop(); }
+    const SkIPoint& offset() const { return fKey.offset(); }
+    const SkMatrix& ctm() const { return fKey.ctm(); }
+
+    void setTexture(GrTexture* texture, const GrIRect16& rect) {
+        SkRefCnt_SafeAssign(fTexture, texture);
+        fRect = rect;
+    }
+    GrTexture* texture() { return fTexture; }
+    const SkPaint* paint() const { return fPaint; }
+    const GrIRect16& rect() const { return fRect; }
+
+    void setPlot(GrPlot* plot) {
+        SkASSERT(NULL == plot || NULL == fPlot);
+        fPlot = plot;
+    }
+    GrPlot* plot() { return fPlot; }
+
+    bool isAtlased() const { return SkToBool(fPlot); }
+
+    void setLocked(bool locked) { fLocked = locked; }
+    bool locked() const { return fLocked; }
+
+    SkDEBUGCODE(const GrPlot* plot() const { return fPlot; })
+    SkDEBUGCODE(void validate(const GrTexture* backingTexture) const;)
 
 private:
-    uint32_t        fPictureID;
-    // fLayerID is only valid when fPicture != kInvalidGenID in which case it
-    // is the index of this layer in the picture (one of 0 .. #layers).
-    int             fLayerID;
+    const Key       fKey;
+
+    // The paint used when dropping the layer down into the owning canvas.
+    // Can be NULL. This class makes a copy for itself.
+    const SkPaint*  fPaint;
 
     // fTexture is a ref on the atlasing texture for atlased layers and a
-    // ref on a GrTexture for non-atlased textures. In both cases, if this is
-    // non-NULL, that means that the texture is locked in the texture cache.
+    // ref on a GrTexture for non-atlased textures.
     GrTexture*      fTexture;
 
-    GrAtlasLocation fLocation;       // only valid if the layer is atlased
+    // For both atlased and non-atlased layers 'fRect' contains the  bound of
+    // the layer in whichever texture it resides. It is empty when 'fTexture'
+    // is NULL.
+    GrIRect16       fRect;
+
+    // For atlased layers, fPlot stores the atlas plot in which the layer rests.
+    // It is always NULL for non-atlased layers.
+    GrPlot*         fPlot;
+
+    // For non-atlased layers 'fLocked' should always match "fTexture".
+    // (i.e., if there is a texture it is locked).
+    // For atlased layers, 'fLocked' is true if the layer is in a plot and
+    // actively required for rendering. If the layer is in a plot but not
+    // actively required for rendering, then 'fLocked' is false. If the
+    // layer isn't in a plot then is can never be locked.
+    bool            fLocked;
 };
 
 // The GrLayerCache caches pre-computed saveLayers for later rendering.
 // Non-atlased layers are stored in their own GrTexture while the atlased
 // layers share a single GrTexture.
-// Unlike the GrFontCache, the GrTexture atlas only has one GrAtlasMgr (for 8888)
+// Unlike the GrFontCache, the GrTexture atlas only has one GrAtlas (for 8888)
 // and one GrPlot (for the entire atlas). As such, the GrLayerCache
 // roughly combines the functionality of the GrFontCache and GrTextStrike
 // classes.
 class GrLayerCache {
 public:
-    GrLayerCache(GrGpu*);
+    GrLayerCache(GrContext*);
     ~GrLayerCache();
 
+    // As a cache, the GrLayerCache can be ordered to free up all its cached
+    // elements by the GrContext
     void freeAll();
 
-    GrCachedLayer* findLayerOrCreate(const SkPicture* picture, int id);
+    GrCachedLayer* findLayer(uint32_t pictureID, int start, int stop, 
+                             const SkIPoint& offset, const SkMatrix& ctm);
+    GrCachedLayer* findLayerOrCreate(uint32_t pictureID,
+                                     int start, int stop, 
+                                     const SkIPoint& offset,
+                                     const SkMatrix& ctm,
+                                     const SkPaint* paint);
+
+    // Inform the cache that layer's cached image is now required. 
+    // Return true if the layer must be re-rendered. Return false if the
+    // layer was found in the cache and can be reused.
+    bool lock(GrCachedLayer* layer, const GrTextureDesc& desc, bool dontAtlas);
+
+    // Inform the cache that layer's cached image is not currently required
+    void unlock(GrCachedLayer* layer);
+
+    // Setup to be notified when 'picture' is deleted
+    void trackPicture(const SkPicture* picture);
+
+    // Cleanup after any SkPicture deletions
+    void processDeletedPictures();
+
+    SkDEBUGCODE(void validate() const;)
 
 private:
-    SkAutoTUnref<GrGpu>       fGpu;
-    SkAutoTDelete<GrAtlasMgr> fAtlasMgr; // TODO: could lazily allocate
+    static const int kAtlasTextureWidth = 1024;
+    static const int kAtlasTextureHeight = 1024;
 
-    class PictureLayerKey;
-    GrTHashTable<GrCachedLayer, PictureLayerKey, 7> fLayerHash;
-    GrTAllocPool<GrCachedLayer> fLayerPool;
+    static const int kNumPlotsX = 2;
+    static const int kNumPlotsY = 2;
 
-    void init();
-    GrCachedLayer* createLayer(const SkPicture* picture, int id);
+    static const int kPlotWidth = kAtlasTextureWidth / kNumPlotsX;
+    static const int kPlotHeight = kAtlasTextureHeight / kNumPlotsY;
 
+    GrContext*                fContext;  // pointer back to owning context
+    SkAutoTDelete<GrAtlas>    fAtlas;    // TODO: could lazily allocate
+
+    // We cache this information here (rather then, say, on the owning picture)
+    // because we want to be able to clean it up as needed (e.g., if a picture
+    // is leaked and never cleans itself up we still want to be able to 
+    // remove the GrPictureInfo once its layers are purged from all the atlas
+    // plots).
+    SkTDynamicHash<GrPictureInfo, uint32_t> fPictureHash;
+
+    SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key> fLayerHash;
+
+    SkMessageBus<GrPictureDeletedMessage>::Inbox fPictDeletionInbox;
+
+    SkAutoTUnref<SkPicture::DeletionListener> fDeletionListener;
+
+    // This implements a plot-centric locking mechanism (since the atlas
+    // backing texture is always locked). Each layer that is locked (i.e.,
+    // needed for the current rendering) in a plot increments the plot lock
+    // count for that plot. Similarly, once a rendering is complete all the
+    // layers used in it decrement the lock count for the used plots.
+    // Plots with a 0 lock count are open for recycling/purging.
+    int fPlotLocks[kNumPlotsX * kNumPlotsY];
+
+    void initAtlas();
+    GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop, 
+                               const SkIPoint& offset, const SkMatrix& ctm,
+                               const SkPaint* paint);
+
+    void purgeAll();
+
+    // Remove all the layers (and unlock any resources) associated with 'pictureID'
+    void purge(uint32_t pictureID);
+
+    static bool PlausiblyAtlasable(int width, int height) {
+        return width <= kPlotWidth && height <= kPlotHeight;
+    }
+
+    void purgePlot(GrPlot* plot);
+
+    // Try to find a purgeable plot and clear it out. Return true if a plot
+    // was purged; false otherwise.
+    bool purgePlot();
+
+    // for testing
+    friend class TestingAccess;
+    int numLayers() const { return fLayerHash.count(); }
 };
 
 #endif
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp
new file mode 100644
index 0000000..91d439b
--- /dev/null
+++ b/src/gpu/GrLayerHoister.cpp
@@ -0,0 +1,284 @@
+/*
+ * 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 "GrLayerCache.h"
+#include "GrLayerHoister.h"
+#include "SkCanvas.h"
+#include "SkRecordDraw.h"
+#include "GrRecordReplaceDraw.h"
+#include "SkGrPixelRef.h"
+#include "SkSurface.h"
+
+// Return true if any layers are suitable for hoisting
+bool GrLayerHoister::FindLayersToHoist(const SkPicture* topLevelPicture,
+                                       const SkRect& query,
+                                       SkTDArray<HoistedLayer>* atlased,
+                                       SkTDArray<HoistedLayer>* nonAtlased,
+                                       GrLayerCache* layerCache) {
+    bool anyHoisted = false;
+
+    SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey();
+
+    const SkPicture::AccelData* topLevelData = topLevelPicture->EXPERIMENTAL_getAccelData(key);
+    if (NULL == topLevelData) {
+        return false;
+    }
+
+    const GrAccelData *topLevelGPUData = static_cast<const GrAccelData*>(topLevelData);
+    if (0 == topLevelGPUData->numSaveLayers()) {
+        return false;
+    }
+
+    // Layer hoisting pre-renders the entire layer since it will be cached and potentially
+    // reused with different clips (e.g., in different tiles). Because of this the
+    // clip will not be limiting the size of the pre-rendered layer. kSaveLayerMaxSize
+    // is used to limit which clips are pre-rendered.
+    static const int kSaveLayerMaxSize = 256;
+
+    SkAutoTArray<bool> pullForward(topLevelGPUData->numSaveLayers());
+
+    // Pre-render all the layers that intersect the query rect
+    for (int i = 0; i < topLevelGPUData->numSaveLayers(); ++i) {
+        pullForward[i] = false;
+
+        const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerInfo(i);
+
+        SkRect layerRect = SkRect::MakeXYWH(SkIntToScalar(info.fOffset.fX),
+                                            SkIntToScalar(info.fOffset.fY),
+                                            SkIntToScalar(info.fSize.fWidth),
+                                            SkIntToScalar(info.fSize.fHeight));
+
+        if (!SkRect::Intersects(query, layerRect)) {
+            continue;
+        }
+
+        // TODO: once this code is more stable unsuitable layers can
+        // just be omitted during the optimization stage
+        if (!info.fValid ||
+            kSaveLayerMaxSize < info.fSize.fWidth ||
+            kSaveLayerMaxSize < info.fSize.fHeight ||
+            info.fIsNested) {
+            continue;
+        }
+
+        pullForward[i] = true;
+        anyHoisted = true;
+    }
+
+    if (!anyHoisted) {
+        return false;
+    }
+
+    atlased->setReserve(atlased->reserved() + topLevelGPUData->numSaveLayers());
+
+    // Generate the layer and/or ensure it is locked
+    for (int i = 0; i < topLevelGPUData->numSaveLayers(); ++i) {
+        if (pullForward[i]) {
+            const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerInfo(i);
+            const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture;
+
+            GrCachedLayer* layer = layerCache->findLayerOrCreate(pict->uniqueID(),
+                                                                 info.fSaveLayerOpID,
+                                                                 info.fRestoreOpID,
+                                                                 info.fOffset,
+                                                                 info.fOriginXform,
+                                                                 info.fPaint);
+
+            GrTextureDesc desc;
+            desc.fFlags = kRenderTarget_GrTextureFlagBit;
+            desc.fWidth = info.fSize.fWidth;
+            desc.fHeight = info.fSize.fHeight;
+            desc.fConfig = kSkia8888_GrPixelConfig;
+            // TODO: need to deal with sample count
+
+            bool needsRendering = layerCache->lock(layer, desc,
+                                                   info.fHasNestedLayers || info.fIsNested);
+            if (NULL == layer->texture()) {
+                continue;
+            }
+
+            if (needsRendering) {
+                HoistedLayer* info;
+
+                if (layer->isAtlased()) {
+                    info = atlased->append();
+                } else {
+                    info = nonAtlased->append();
+                }
+
+                info->fLayer = layer;
+                info->fPicture = pict;
+            }
+        }
+    }
+
+    return anyHoisted;
+}
+
+static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* result) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
+    result->setInfo(info);
+    result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
+}
+
+static void convert_layers_to_replacements(const SkTDArray<GrLayerHoister::HoistedLayer>& layers,
+                                           GrReplacements* replacements) {
+    // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer?
+    for (int i = 0; i < layers.count(); ++i) {
+        GrReplacements::ReplacementInfo* layerInfo = replacements->push();
+        layerInfo->fStart = layers[i].fLayer->start();
+        layerInfo->fStop = layers[i].fLayer->stop();
+        layerInfo->fPos = layers[i].fLayer->offset();;
+
+        SkBitmap bm;
+        wrap_texture(layers[i].fLayer->texture(),
+                     !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().width()
+                                                    : layers[i].fLayer->texture()->width(),
+                     !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().height()
+                                                    : layers[i].fLayer->texture()->height(),
+                     &bm);
+        layerInfo->fImage = SkImage::NewTexture(bm);
+
+        layerInfo->fPaint = layers[i].fLayer->paint()
+                                ? SkNEW_ARGS(SkPaint, (*layers[i].fLayer->paint()))
+                                : NULL;
+
+        layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i].fLayer->rect().fLeft,
+                                                layers[i].fLayer->rect().fTop,
+                                                layers[i].fLayer->rect().width(),
+                                                layers[i].fLayer->rect().height());
+    }
+}
+
+void GrLayerHoister::DrawLayers(const SkTDArray<HoistedLayer>& atlased,
+                                const SkTDArray<HoistedLayer>& nonAtlased,
+                                GrReplacements* replacements) {
+    // Render the atlased layers that require it
+    if (atlased.count() > 0) {
+        // All the atlased layers are rendered into the same GrTexture
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
+                                        atlased[0].fLayer->texture()->asRenderTarget(), NULL));
+
+        SkCanvas* atlasCanvas = surface->getCanvas();
+
+        SkPaint paint;
+        paint.setColor(SK_ColorTRANSPARENT);
+        paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref();
+
+        for (int i = 0; i < atlased.count(); ++i) {
+            GrCachedLayer* layer = atlased[i].fLayer;
+            const SkPicture* pict = atlased[i].fPicture;
+
+            atlasCanvas->save();
+
+            // Add a rect clip to make sure the rendering doesn't
+            // extend beyond the boundaries of the atlased sub-rect
+            SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
+                                            SkIntToScalar(layer->rect().fTop),
+                                            SkIntToScalar(layer->rect().width()),
+                                            SkIntToScalar(layer->rect().height()));
+            atlasCanvas->clipRect(bound);
+
+            // Since 'clear' doesn't respect the clip we need to draw a rect
+            // TODO: ensure none of the atlased layers contain a clear call!
+            atlasCanvas->drawRect(bound, paint);
+
+            // info.fCTM maps the layer's top/left to the origin.
+            // Since this layer is atlased, the top/left corner needs
+            // to be offset to the correct location in the backing texture.
+            SkMatrix initialCTM;
+            initialCTM.setTranslate(SkIntToScalar(-layer->offset().fX), 
+                                    SkIntToScalar(-layer->offset().fY));
+            initialCTM.postTranslate(bound.fLeft, bound.fTop);
+            
+            atlasCanvas->translate(SkIntToScalar(-layer->offset().fX), 
+                                   SkIntToScalar(-layer->offset().fY));
+            atlasCanvas->translate(bound.fLeft, bound.fTop);
+            atlasCanvas->concat(layer->ctm());
+
+            SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound,
+                                layer->start()+1, layer->stop(), initialCTM);
+
+            atlasCanvas->restore();
+        }
+
+        atlasCanvas->flush();
+    }
+
+    // Render the non-atlased layers that require it
+    for (int i = 0; i < nonAtlased.count(); ++i) {
+        GrCachedLayer* layer = nonAtlased[i].fLayer;
+        const SkPicture* pict = nonAtlased[i].fPicture;
+
+        // Each non-atlased layer has its own GrTexture
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
+                                        layer->texture()->asRenderTarget(), NULL));
+
+        SkCanvas* layerCanvas = surface->getCanvas();
+
+        // Add a rect clip to make sure the rendering doesn't
+        // extend beyond the boundaries of the atlased sub-rect
+        SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
+                                        SkIntToScalar(layer->rect().fTop),
+                                        SkIntToScalar(layer->rect().width()),
+                                        SkIntToScalar(layer->rect().height()));
+
+        layerCanvas->clipRect(bound); // TODO: still useful?
+
+        layerCanvas->clear(SK_ColorTRANSPARENT);
+
+        SkMatrix initialCTM;
+        initialCTM.setTranslate(SkIntToScalar(-layer->offset().fX), 
+                                SkIntToScalar(-layer->offset().fY));
+
+        layerCanvas->translate(SkIntToScalar(-layer->offset().fX), 
+                               SkIntToScalar(-layer->offset().fY));
+        layerCanvas->concat(layer->ctm());
+
+        SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, bound,
+                            layer->start()+1, layer->stop(), initialCTM);
+
+        layerCanvas->flush();
+    }
+
+    convert_layers_to_replacements(atlased, replacements);
+    convert_layers_to_replacements(nonAtlased, replacements);
+}
+
+static void unlock_layer_in_cache(GrLayerCache* layerCache,
+                                  const SkPicture* picture,
+                                  GrCachedLayer* layer) {
+    layerCache->unlock(layer);
+
+#if DISABLE_CACHING
+    // This code completely clears out the atlas. It is required when
+    // caching is disabled so the atlas doesn't fill up and force more
+    // free floating layers
+    layerCache->purge(picture->uniqueID());
+#endif
+}
+
+void GrLayerHoister::UnlockLayers(GrLayerCache* layerCache, 
+                                  const SkTDArray<HoistedLayer>& atlased,
+                                  const SkTDArray<HoistedLayer>& nonAtlased) {
+
+    for (int i = 0; i < atlased.count(); ++i) {
+        unlock_layer_in_cache(layerCache, atlased[i].fPicture, atlased[i].fLayer);
+    }
+
+    for (int i = 0; i < nonAtlased.count(); ++i) {
+        unlock_layer_in_cache(layerCache, nonAtlased[i].fPicture, nonAtlased[i].fLayer);
+    }
+
+#if DISABLE_CACHING
+    // This code completely clears out the atlas. It is required when
+    // caching is disabled so the atlas doesn't fill up and force more
+    // free floating layers
+    layerCache->purgeAll();
+#endif
+}
+
diff --git a/src/gpu/GrLayerHoister.h b/src/gpu/GrLayerHoister.h
new file mode 100644
index 0000000..acf1901
--- /dev/null
+++ b/src/gpu/GrLayerHoister.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrLayerHoister_DEFINED
+#define GrLayerHoister_DEFINED
+
+#include "SkPicture.h"
+#include "SkTDArray.h"
+
+class GrAccelData;
+struct GrCachedLayer;
+class GrReplacements;
+struct SkRect;
+
+// This class collects the layer hoisting functionality in one place.
+// For each picture rendering:
+//  FindLayersToHoist should be called once to collect the required layers
+//  DrawLayers should be called once to render them
+//  UnlockLayers should be called once to allow the texture resources to be recycled
+class GrLayerHoister {
+public:
+    struct HoistedLayer {
+        const SkPicture* fPicture;
+        GrCachedLayer*   fLayer;
+    };
+
+    /** Find the layers in 'topLevelPicture' that need hoisting. Note that the discovered
+        layers can be inside nested sub-pictures.
+        @param topLevelPicture The top-level picture that is about to be rendered
+        @param query       The rectangle that is about to be drawn.
+        @param atlased     Out parameter storing the layers that should be hoisted to the atlas
+        @param nonAtlased  Out parameter storing the layers that should be hoisted stand alone
+        @param layerCache The source of new layers
+        Return true if any layers are suitable for hoisting; false otherwise
+    */
+    static bool FindLayersToHoist(const SkPicture* topLevelPicture,
+                                  const SkRect& query,
+                                  SkTDArray<HoistedLayer>* altased,
+                                  SkTDArray<HoistedLayer>* nonAtlased,
+                                  GrLayerCache* layerCache);
+
+    /** Draw the specified layers into either the atlas or free floating textures.
+        @param atlased      The layers to be drawn into the atlas
+        @param nonAtlased   The layers to be drawn into their own textures
+        @oaram replacements The replacement structure to fill in with the rendered layer info
+    */
+    static void DrawLayers(const SkTDArray<HoistedLayer>& atlased,
+                           const SkTDArray<HoistedLayer>& nonAtlased,
+                           GrReplacements* replacements);
+
+    /** Unlock unneeded layers in the layer cache.
+        @param layerCache holder of the locked layers
+        @param atlased    Unneeded layers in the atlas
+        @param nonAtlased Unneeded layers in their own textures
+    */
+    static void UnlockLayers(GrLayerCache* layerCache,
+                             const SkTDArray<HoistedLayer>& atlased,
+                             const SkTDArray<HoistedLayer>& nonAtlased);
+};
+
+#endif
diff --git a/src/gpu/GrMemoryPool.cpp b/src/gpu/GrMemoryPool.cpp
index 8839c66..5009f20 100644
--- a/src/gpu/GrMemoryPool.cpp
+++ b/src/gpu/GrMemoryPool.cpp
@@ -127,7 +127,7 @@
     do {
         allocCount += block->fLiveCount;
         SkASSERT(prev == block->fPrev);
-        if (NULL != prev) {
+        if (prev) {
             SkASSERT(prev->fNext == block);
         }
 
diff --git a/src/gpu/GrMurmur3HashKey.h b/src/gpu/GrMurmur3HashKey.h
new file mode 100644
index 0000000..ad1fa7c
--- /dev/null
+++ b/src/gpu/GrMurmur3HashKey.h
@@ -0,0 +1,73 @@
+
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef GrMurmur3HashKey_DEFINED
+#define GrMurmur3HashKey_DEFINED
+
+#include "SkChecksum.h"
+#include "GrTypes.h"
+
+/**
+ *  GrMurmur3HashKey is a hash key class that can take a data chunk of any predetermined
+ *  length. It uses the Murmur3 hash function. It is intended to be used with
+ *  SkTDynamicHash (where GrBinHashKey is for GrTHashTable).
+ */
+template<size_t KEY_SIZE_IN_BYTES>
+class GrMurmur3HashKey {
+public:
+    GrMurmur3HashKey() {
+        this->reset();
+    }
+
+    void reset() {
+        fHash = 0;
+#ifdef SK_DEBUG
+        fIsValid = false;
+#endif
+    }
+
+    void setKeyData(const uint32_t* data) {
+        SK_COMPILE_ASSERT(KEY_SIZE_IN_BYTES % 4 == 0, key_size_mismatch);
+        memcpy(fData, data, KEY_SIZE_IN_BYTES);
+
+        fHash = SkChecksum::Murmur3(fData, KEY_SIZE_IN_BYTES);
+#ifdef SK_DEBUG
+        fIsValid = true;
+#endif
+    }
+
+    bool operator==(const GrMurmur3HashKey& other) const {
+        if (fHash != other.fHash) {
+            return false;
+        }
+
+        return !memcmp(fData, other.fData, KEY_SIZE_IN_BYTES);
+    }
+
+    uint32_t getHash() const {
+        SkASSERT(fIsValid);
+        return fHash;
+    }
+
+    const uint8_t* getData() const {
+        SkASSERT(fIsValid);
+        return reinterpret_cast<const uint8_t*>(fData);
+    }
+
+private:
+    uint32_t fHash;
+    uint32_t fData[KEY_SIZE_IN_BYTES / sizeof(uint32_t)];  // Buffer for key storage.
+
+#ifdef SK_DEBUG
+public:
+    bool                fIsValid;
+#endif
+};
+
+#endif
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
new file mode 100644
index 0000000..8653a8b
--- /dev/null
+++ b/src/gpu/GrOptDrawState.cpp
@@ -0,0 +1,268 @@
+/*
+ * 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 "GrOptDrawState.h"
+
+#include "GrDrawState.h"
+#include "GrDrawTargetCaps.h"
+#include "GrGpu.h"
+
+GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
+                               BlendOptFlags blendOptFlags,
+                               GrBlendCoeff optSrcCoeff,
+                               GrBlendCoeff optDstCoeff,
+                               const GrDrawTargetCaps& caps) : INHERITED(drawState) {
+    fColor = drawState.getColor();
+    fCoverage = drawState.getCoverage();
+    fViewMatrix = drawState.getViewMatrix();
+    fBlendConstant = drawState.getBlendConstant();
+    fFlagBits = drawState.getFlagBits();
+    fVAPtr = drawState.getVertexAttribs();
+    fVACount = drawState.getVertexAttribCount();
+    fVAStride = drawState.getVertexStride();
+    fStencilSettings = drawState.getStencil();
+    fDrawFace = drawState.getDrawFace();
+    fBlendOptFlags = blendOptFlags;
+    fSrcBlend = optSrcCoeff;
+    fDstBlend = optDstCoeff;
+
+    memcpy(fFixedFunctionVertexAttribIndices,
+            drawState.getFixedFunctionVertexAttribIndices(),
+            sizeof(fFixedFunctionVertexAttribIndices));
+
+
+    fInputColorIsUsed = true;
+    fInputCoverageIsUsed = true;
+
+    if (drawState.hasGeometryProcessor()) {
+        fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*drawState.getGeometryProcessor())));
+    } else {
+        fGeometryProcessor.reset(NULL);
+    }
+
+    this->copyEffectiveColorStages(drawState);
+    this->copyEffectiveCoverageStages(drawState);
+    this->adjustFromBlendOpts();
+    this->getStageStats();
+    this->setOutputStateInfo(caps);
+};
+
+void GrOptDrawState::setOutputStateInfo(const GrDrawTargetCaps& caps) {
+    // Set this default and then possibly change our mind if there is coverage.
+    fPrimaryOutputType = kModulate_PrimaryOutputType;
+    fSecondaryOutputType = kNone_SecondaryOutputType;
+
+    // If we do have coverage determine whether it matters.
+    bool separateCoverageFromColor = this->hasGeometryProcessor();
+    if (!this->isCoverageDrawing() &&
+        (this->numCoverageStages() > 0 ||
+         this->hasGeometryProcessor() ||
+         this->hasCoverageVertexAttribute())) {
+
+        if (caps.dualSourceBlendingSupport()) {
+            if (kZero_GrBlendCoeff == fDstBlend) {
+                // write the coverage value to second color
+                fSecondaryOutputType =  kCoverage_SecondaryOutputType;
+                separateCoverageFromColor = true;
+                fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+            } else if (kSA_GrBlendCoeff == fDstBlend) {
+                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+                fSecondaryOutputType = kCoverageISA_SecondaryOutputType;
+                separateCoverageFromColor = true;
+                fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+            } else if (kSC_GrBlendCoeff == fDstBlend) {
+                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+                fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
+                separateCoverageFromColor = true;
+                fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+            }
+        } else if (fReadsDst &&
+                   kOne_GrBlendCoeff == fSrcBlend &&
+                   kZero_GrBlendCoeff == fDstBlend) {
+            fPrimaryOutputType = kCombineWithDst_PrimaryOutputType;
+            separateCoverageFromColor = true;
+        }
+    }
+
+    // TODO: Once we have flag to know if we only multiply on stages, only push coverage into color
+    // stages if everything is multipy
+    if (!separateCoverageFromColor) {
+        for (int s = 0; s < this->numCoverageStages(); ++s) {
+            fColorStages.push_back(this->getCoverageStage(s));
+        }
+        fCoverageStages.reset();
+    }
+}
+
+void GrOptDrawState::adjustFromBlendOpts() {
+
+    switch (fBlendOptFlags) {
+        case kNone_BlendOpt:
+        case kSkipDraw_BlendOptFlag:
+            break;
+        case kCoverageAsAlpha_BlendOptFlag:
+            fFlagBits |= kCoverageDrawing_StateBit;
+            break;
+        case kEmitCoverage_BlendOptFlag:
+            fColor = 0xffffffff;
+            fInputColorIsUsed = true;
+            fColorStages.reset();
+            this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding);
+            break;
+        case kEmitTransBlack_BlendOptFlag:
+            fColor = 0;
+            fCoverage = 0xff;
+            fInputColorIsUsed = true;
+            fInputCoverageIsUsed = true;
+            fColorStages.reset();
+            fCoverageStages.reset();
+            this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding |
+                                                   0x1 << kCoverage_GrVertexAttribBinding);
+            break;
+        default:
+            SkFAIL("Unknown BlendOptFlag");
+
+    }
+}
+
+void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
+    int numToRemove = 0;
+    uint8_t maskCheck = 0x1;
+    // Count the number of vertex attributes that we will actually remove
+    for (int i = 0; i < kGrFixedFunctionVertexAttribBindingCnt; ++i) {
+        if ((maskCheck & removeVAFlag) && -1 != fFixedFunctionVertexAttribIndices[i]) {
+            ++numToRemove;
+        }
+        maskCheck <<= 1;
+    }
+
+    fOptVA.reset(fVACount - numToRemove);
+
+    GrVertexAttrib* dst = fOptVA.get();
+    const GrVertexAttrib* src = fVAPtr;
+
+    for (int i = 0, newIdx = 0; i < fVACount; ++i, ++src) {
+        const GrVertexAttrib& currAttrib = *src;
+        if (currAttrib.fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
+            uint8_t maskCheck = 0x1 << currAttrib.fBinding;
+            if (maskCheck & removeVAFlag) {
+                SkASSERT(-1 != fFixedFunctionVertexAttribIndices[currAttrib.fBinding]);
+                fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
+                continue;
+            }
+            fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
+        }
+        memcpy(dst, src, sizeof(GrVertexAttrib));
+        ++newIdx;
+        ++dst;
+    }
+    fVACount -= numToRemove;
+    fVAPtr = fOptVA.get();
+}
+
+void GrOptDrawState::copyEffectiveColorStages(const GrDrawState& ds) {
+    int firstColorStage = 0;
+
+    // Set up color and flags for ConstantColorComponent checks
+    GrColor color;
+    uint32_t validComponentFlags;
+    if (!this->hasColorVertexAttribute()) {
+        color = ds.getColor();
+        validComponentFlags = kRGBA_GrColorComponentFlags;
+    } else {
+        if (ds.vertexColorsAreOpaque()) {
+            color = 0xFF << GrColor_SHIFT_A;
+            validComponentFlags = kA_GrColorComponentFlag;
+        } else {
+            validComponentFlags = 0;
+            color = 0; // not strictly necessary but we get false alarms from tools about uninit.
+        }
+    }
+
+    for (int i = 0; i < ds.numColorStages(); ++i) {
+        const GrFragmentProcessor* fp = ds.getColorStage(i).getFragmentProcessor();
+        if (!fp->willUseInputColor()) {
+            firstColorStage = i;
+            fInputColorIsUsed = false;
+        }
+        fp->getConstantColorComponents(&color, &validComponentFlags);
+        if (kRGBA_GrColorComponentFlags == validComponentFlags) {
+            firstColorStage = i + 1;
+            fColor = color;
+            fInputColorIsUsed = true;
+            this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding);
+        }
+    }
+    if (firstColorStage < ds.numColorStages()) {
+        fColorStages.reset(&ds.getColorStage(firstColorStage),
+                           ds.numColorStages() - firstColorStage);
+    } else {
+        fColorStages.reset();
+    }
+}
+
+void GrOptDrawState::copyEffectiveCoverageStages(const GrDrawState& ds) {
+    int firstCoverageStage = 0;
+
+    // We do not try to optimize out constantColor coverage effects here. It is extremely rare
+    // to have a coverage effect that returns a constant value for all four channels. Thus we
+    // save having to make extra virtual calls by not checking for it.
+
+    // Don't do any optimizations on coverage stages. It should not be the case where we do not use
+    // input coverage in an effect
+#ifdef OptCoverageStages
+    for (int i = 0; i < ds.numCoverageStages(); ++i) {
+        const GrProcessor* processor = ds.getCoverageStage(i).getProcessor();
+        if (!processor->willUseInputColor()) {
+            firstCoverageStage = i;
+            fInputCoverageIsUsed = false;
+        }
+    }
+#endif
+    if (ds.numCoverageStages() > 0) {
+        fCoverageStages.reset(&ds.getCoverageStage(firstCoverageStage),
+                              ds.numCoverageStages() - firstCoverageStage);
+    } else {
+        fCoverageStages.reset();
+    }
+}
+
+static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool* readsFragPosition) {
+    if (stage.getFragmentProcessor()->willReadDstColor()) {
+        *readsDst = true;
+    }
+    if (stage.getFragmentProcessor()->willReadFragmentPosition()) {
+        *readsFragPosition = true;
+    }
+}
+
+void GrOptDrawState::getStageStats() {
+    // We will need a local coord attrib if there is one currently set on the optState and we are
+    // actually generating some effect code
+    fRequiresLocalCoordAttrib = this->hasLocalCoordAttribute() && this->numTotalStages() > 0;
+
+    fReadsDst = false;
+    fReadsFragPosition = false;
+
+    for (int s = 0; s < this->numColorStages(); ++s) {
+        const GrFragmentStage& stage = this->getColorStage(s);
+        get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
+    }
+    for (int s = 0; s < this->numCoverageStages(); ++s) {
+        const GrFragmentStage& stage = this->getCoverageStage(s);
+        get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
+    }
+    if (this->hasGeometryProcessor()) {
+        const GrGeometryStage& stage = *this->getGeometryProcessor();
+        fReadsFragPosition = fReadsFragPosition || stage.getProcessor()->willReadFragmentPosition();
+    }
+}
+
+bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
+    return this->isEqual(that);
+}
+
diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h
new file mode 100644
index 0000000..b4f59d3
--- /dev/null
+++ b/src/gpu/GrOptDrawState.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrOptDrawState_DEFINED
+#define GrOptDrawState_DEFINED
+
+#include "GrDrawState.h"
+#include "GrRODrawState.h"
+
+/**
+ * Subclass of GrRODrawState that holds an optimized version of a GrDrawState. Like it's parent
+ * it is meant to be an immutable class, and simply adds a few helpful data members not in the
+ * base class.
+ */
+class GrOptDrawState : public GrRODrawState {
+public:
+    bool operator== (const GrOptDrawState& that) const;
+
+    bool inputColorIsUsed() const { return fInputColorIsUsed; }
+    bool inputCoverageIsUsed() const { return fInputCoverageIsUsed; }
+
+    bool readsDst() const { return fReadsDst; }
+    bool readsFragPosition() const { return fReadsFragPosition; }
+    bool requiresLocalCoordAttrib() const { return fRequiresLocalCoordAttrib; }
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Stage Output Types
+    ////
+
+    enum PrimaryOutputType {
+        // Modulate color and coverage, write result as the color output.
+        kModulate_PrimaryOutputType,
+        // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
+        // can only be set if fDstReadKey is non-zero.
+        kCombineWithDst_PrimaryOutputType,
+
+        kPrimaryOutputTypeCnt,
+    };
+
+    enum SecondaryOutputType {
+        // There is no secondary output
+        kNone_SecondaryOutputType,
+        // Writes coverage as the secondary output. Only set if dual source blending is supported
+        // and primary output is kModulate.
+        kCoverage_SecondaryOutputType,
+        // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
+        // is supported and primary output is kModulate.
+        kCoverageISA_SecondaryOutputType,
+        // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
+        // blending is supported and primary output is kModulate.
+        kCoverageISC_SecondaryOutputType,
+
+        kSecondaryOutputTypeCnt,
+    };
+
+    PrimaryOutputType getPrimaryOutputType() const { return fPrimaryOutputType; }
+    SecondaryOutputType getSecondaryOutputType() const { return fSecondaryOutputType; }
+
+    /// @}
+
+private:
+    /**
+     * Constructs and optimized drawState out of a GrRODrawState.
+     */
+    GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags,
+                   GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff,
+                   const GrDrawTargetCaps& caps);
+
+    /**
+     * Loops through all the color stage effects to check if the stage will ignore color input or
+     * always output a constant color. In the ignore color input case we can ignore all previous
+     * stages. In the constant color case, we can ignore all previous stages and
+     * the current one and set the state color to the constant color. Once we determine the so
+     * called first effective stage, we copy all the effective stages into our optimized
+     * state.
+     */
+    void copyEffectiveColorStages(const GrDrawState& ds);
+
+    /**
+     * Loops through all the coverage stage effects to check if the stage will ignore color input.
+     * If a coverage stage will ignore input, then we can ignore all coverage stages before it. We
+     * loop to determine the first effective coverage stage, and then copy all of our effective
+     * coverage stages into our optimized state.
+     */
+    void copyEffectiveCoverageStages(const GrDrawState& ds);
+
+    /**
+     * This function takes in a flag and removes the corresponding fixed function vertex attributes.
+     * The flags are in the same order as GrVertexAttribBinding array. If bit i of removeVAFlags is
+     * set, then vertex attributes with binding (GrVertexAttribute)i will be removed.
+     */
+    void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags);
+
+    /**
+     * Alter the OptDrawState (adjusting stages, vertex attribs, flags, etc.) based on the
+     * BlendOptFlags.
+     */
+    void adjustFromBlendOpts();
+
+    /**
+     * Loop over the effect stages to determine various info like what data they will read and what
+     * shaders they require.
+     */
+    void getStageStats();
+
+    /**
+     * Calculates the primary and secondary output types of the shader. For certain output types
+     * the function may adjust the blend coefficients. After this function is called the src and dst
+     * blend coeffs will represent those used by backend API.
+     */
+    void setOutputStateInfo(const GrDrawTargetCaps&);
+
+    // These flags are needed to protect the code from creating an unused uniform color/coverage
+    // which will cause shader compiler errors.
+    bool            fInputColorIsUsed;
+    bool            fInputCoverageIsUsed;
+
+    // These flags give aggregated info on the effect stages that are used when building programs.
+    bool            fReadsDst;
+    bool            fReadsFragPosition;
+    bool            fRequiresLocalCoordAttrib;
+
+    SkAutoSTArray<4, GrVertexAttrib> fOptVA;
+
+    BlendOptFlags   fBlendOptFlags;
+
+    // Fragment shader color outputs
+    PrimaryOutputType  fPrimaryOutputType : 8;
+    SecondaryOutputType  fSecondaryOutputType : 8;
+
+    friend GrOptDrawState* GrDrawState::createOptState(const GrDrawTargetCaps&) const;
+    typedef GrRODrawState INHERITED;
+};
+
+#endif
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 8a76646..4ae0ebc 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -7,11 +7,12 @@
 
 #include "GrOvalRenderer.h"
 
-#include "GrEffect.h"
-#include "gl/GrGLEffect.h"
+#include "gl/builders/GrGLFullProgramBuilder.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
-#include "gl/GrGLVertexEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLGeometryProcessor.h"
+#include "GrProcessor.h"
+#include "GrTBackendProcessorFactory.h"
 
 #include "GrDrawState.h"
 #include "GrDrawTarget.h"
@@ -21,7 +22,7 @@
 #include "SkStrokeRec.h"
 #include "SkTLazy.h"
 
-#include "effects/GrVertexEffect.h"
+#include "GrGeometryProcessor.h"
 #include "effects/GrRRectEffect.h"
 
 namespace {
@@ -59,11 +60,11 @@
  * specified as offset_x, offset_y (both from center point), outer radius and inner radius.
  */
 
-class CircleEdgeEffect : public GrVertexEffect {
+class CircleEdgeEffect : public GrGeometryProcessor {
 public:
-    static GrEffectRef* Create(bool stroke) {
-        GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true));
-        GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false));
+    static GrGeometryProcessor* Create(bool stroke) {
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gCircleStrokeEdge, CircleEdgeEffect, (true));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gCircleFillEdge, CircleEdgeEffect, (false));
 
         if (stroke) {
             gCircleStrokeEdge->ref();
@@ -79,8 +80,10 @@
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance();
+    const GrShaderVar& inCircleEdge() const { return fInCircleEdge; }
+
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendGeometryProcessorFactory<CircleEdgeEffect>::getInstance();
     }
 
     virtual ~CircleEdgeEffect() {}
@@ -89,74 +92,78 @@
 
     inline bool isStroked() const { return fStroke; }
 
-    class GLEffect : public GrGLVertexEffect {
+    class GLProcessor : public GrGLGeometryProcessor {
     public:
-        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
         : INHERITED (factory) {}
 
-        virtual void emitCode(GrGLFullShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+        virtual void emitCode(GrGLFullProgramBuilder* builder,
+                              const GrGeometryProcessor& geometryProcessor,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
                               const TextureSamplerArray& samplers) SK_OVERRIDE {
-            const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleEdgeEffect>();
+            const CircleEdgeEffect& circleEffect = geometryProcessor.cast<CircleEdgeEffect>();
             const char *vsName, *fsName;
             builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName);
 
-            const SkString* attrName =
-                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-            builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
+            GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();;
+            vsBuilder->codeAppendf("\t%s = %s;\n", vsName, circleEffect.inCircleEdge().c_str());
 
-            builder->fsCodeAppendf("\tfloat d = length(%s.xy);\n", fsName);
-            builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName);
+            GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+            fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName);
+            fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName);
             if (circleEffect.isStroked()) {
-                builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName);
-                builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
+                fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName);
+                fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n");
             }
 
-            builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+            fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleEdgeEffect>();
-
-            return circleEffect.isStroked() ? 0x1 : 0x0;
+        static void GenKey(const GrProcessor& processor, const GrGLCaps&,
+                           GrProcessorKeyBuilder* b) {
+            const CircleEdgeEffect& circleEffect = processor.cast<CircleEdgeEffect>();
+            b->add32(circleEffect.isStroked());
         }
 
-        virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
+        virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
 
     private:
-        typedef GrGLVertexEffect INHERITED;
+        typedef GrGLGeometryProcessor INHERITED;
     };
 
 
 private:
-    CircleEdgeEffect(bool stroke) : GrVertexEffect() {
-        this->addVertexAttrib(kVec4f_GrSLType);
+    CircleEdgeEffect(bool stroke)
+        : fInCircleEdge(this->addVertexAttrib(
+                GrShaderVar("inCircleEdge",
+                            kVec4f_GrSLType,
+                            GrShaderVar::kAttribute_TypeModifier))) {
         fStroke = stroke;
     }
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
-        const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other);
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE {
+        const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>();
         return cee.fStroke == fStroke;
     }
 
+    const GrShaderVar& fInCircleEdge;
     bool fStroke;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrVertexEffect INHERITED;
+    typedef GrGeometryProcessor INHERITED;
 };
 
-GR_DEFINE_EFFECT_TEST(CircleEdgeEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect);
 
-GrEffectRef* CircleEdgeEffect::TestCreate(SkRandom* random,
-                                          GrContext* context,
-                                          const GrDrawTargetCaps&,
-                                          GrTexture* textures[]) {
+GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random,
+                                                  GrContext* context,
+                                                  const GrDrawTargetCaps&,
+                                                  GrTexture* textures[]) {
     return CircleEdgeEffect::Create(random->nextBool());
 }
 
@@ -170,11 +177,11 @@
  * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0.
  */
 
-class EllipseEdgeEffect : public GrVertexEffect {
+class EllipseEdgeEffect : public GrGeometryProcessor {
 public:
-    static GrEffectRef* Create(bool stroke) {
-        GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true));
-        GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false));
+    static GrGeometryProcessor* Create(bool stroke) {
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseStrokeEdge, EllipseEdgeEffect, (true));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseFillEdge, EllipseEdgeEffect, (false));
 
         if (stroke) {
             gEllipseStrokeEdge->ref();
@@ -190,104 +197,115 @@
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance();
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendGeometryProcessorFactory<EllipseEdgeEffect>::getInstance();
     }
 
     virtual ~EllipseEdgeEffect() {}
 
     static const char* Name() { return "EllipseEdge"; }
 
+    const GrShaderVar& inEllipseOffset() const { return fInEllipseOffset; }
+    const GrShaderVar& inEllipseRadii() const { return fInEllipseRadii; }
+
     inline bool isStroked() const { return fStroke; }
 
-    class GLEffect : public GrGLVertexEffect {
+    class GLProcessor : public GrGLGeometryProcessor {
     public:
-        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
         : INHERITED (factory) {}
 
-        virtual void emitCode(GrGLFullShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+        virtual void emitCode(GrGLFullProgramBuilder* builder,
+                              const GrGeometryProcessor& geometryProcessor,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
                               const TextureSamplerArray& samplers) SK_OVERRIDE {
-            const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<EllipseEdgeEffect>();
+            const EllipseEdgeEffect& ellipseEffect = geometryProcessor.cast<EllipseEdgeEffect>();
 
             const char *vsOffsetName, *fsOffsetName;
             const char *vsRadiiName, *fsRadiiName;
 
             builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName, &fsOffsetName);
-            const SkString* attr0Name =
-                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-            builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_str());
+
+            GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+            vsBuilder->codeAppendf("%s = %s;", vsOffsetName,
+                                   ellipseEffect.inEllipseOffset().c_str());
 
             builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &fsRadiiName);
-            const SkString* attr1Name =
-                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
-            builder->vsCodeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str());
+            vsBuilder->codeAppendf("%s = %s;", vsRadiiName, ellipseEffect.inEllipseRadii().c_str());
 
             // for outer curve
-            builder->fsCodeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffsetName, fsRadiiName);
-            builder->fsCodeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
-            builder->fsCodeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fsRadiiName);
-            builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n");
+            GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+            fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffsetName, fsRadiiName);
+            fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
+            fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fsRadiiName);
+            fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
             // avoid calling inversesqrt on zero.
-            builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
-            builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
-            builder->fsCodeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
+            fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
+            fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
+            fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
 
             // for inner curve
             if (ellipseEffect.isStroked()) {
-                builder->fsCodeAppendf("\tscaledOffset = %s*%s.zw;\n", fsOffsetName, fsRadiiName);
-                builder->fsCodeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
-                builder->fsCodeAppendf("\tgrad = 2.0*scaledOffset*%s.zw;\n", fsRadiiName);
-                builder->fsCodeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
-                builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
+                fsBuilder->codeAppendf("\tscaledOffset = %s*%s.zw;\n", fsOffsetName, fsRadiiName);
+                fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
+                fsBuilder->codeAppendf("\tgrad = 2.0*scaledOffset*%s.zw;\n", fsRadiiName);
+                fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
+                fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
             }
 
-            builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+            fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<EllipseEdgeEffect>();
-
-            return ellipseEffect.isStroked() ? 0x1 : 0x0;
+        static void GenKey(const GrProcessor& processor, const GrGLCaps&,
+                           GrProcessorKeyBuilder* b) {
+            const EllipseEdgeEffect& ellipseEffect = processor.cast<EllipseEdgeEffect>();
+            b->add32(ellipseEffect.isStroked());
         }
 
-        virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
+        virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {
         }
 
     private:
-        typedef GrGLVertexEffect INHERITED;
+        typedef GrGLGeometryProcessor INHERITED;
     };
 
 private:
-    EllipseEdgeEffect(bool stroke) : GrVertexEffect() {
-        this->addVertexAttrib(kVec2f_GrSLType);
-        this->addVertexAttrib(kVec4f_GrSLType);
+    EllipseEdgeEffect(bool stroke)
+        : fInEllipseOffset(this->addVertexAttrib(
+                GrShaderVar("inEllipseOffset",
+                            kVec2f_GrSLType,
+                            GrShaderVar::kAttribute_TypeModifier)))
+        , fInEllipseRadii(this->addVertexAttrib(
+                GrShaderVar("inEllipseRadii",
+                            kVec4f_GrSLType,
+                            GrShaderVar::kAttribute_TypeModifier))) {
         fStroke = stroke;
     }
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
-        const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other);
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE {
+        const EllipseEdgeEffect& eee = other.cast<EllipseEdgeEffect>();
         return eee.fStroke == fStroke;
     }
 
+    const GrShaderVar& fInEllipseOffset;
+    const GrShaderVar& fInEllipseRadii;
     bool fStroke;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrVertexEffect INHERITED;
+    typedef GrGeometryProcessor INHERITED;
 };
 
-GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect);
 
-GrEffectRef* EllipseEdgeEffect::TestCreate(SkRandom* random,
-                                           GrContext* context,
-                                           const GrDrawTargetCaps&,
-                                           GrTexture* textures[]) {
+GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random,
+                                                   GrContext* context,
+                                                   const GrDrawTargetCaps&,
+                                                   GrTexture* textures[]) {
     return EllipseEdgeEffect::Create(random->nextBool());
 }
 
@@ -302,14 +320,14 @@
  * The result is device-independent and can be used with any affine matrix.
  */
 
-class DIEllipseEdgeEffect : public GrVertexEffect {
+class DIEllipseEdgeEffect : public GrGeometryProcessor {
 public:
     enum Mode { kStroke = 0, kHairline, kFill };
 
-    static GrEffectRef* Create(Mode mode) {
-        GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStroke));
-        GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHairline));
-        GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill));
+    static GrGeometryProcessor* Create(Mode mode) {
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStroke));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHairline));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill));
 
         if (kStroke == mode) {
             gEllipseStrokeEdge->ref();
@@ -328,122 +346,135 @@
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<DIEllipseEdgeEffect>::getInstance();
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendGeometryProcessorFactory<DIEllipseEdgeEffect>::getInstance();
     }
 
     virtual ~DIEllipseEdgeEffect() {}
 
     static const char* Name() { return "DIEllipseEdge"; }
 
+    const GrShaderVar& inEllipseOffsets0() const { return fInEllipseOffsets0; }
+    const GrShaderVar& inEllipseOffsets1() const { return fInEllipseOffsets1; }
+
     inline Mode getMode() const { return fMode; }
 
-    class GLEffect : public GrGLVertexEffect {
+    class GLProcessor : public GrGLGeometryProcessor {
     public:
-        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
         : INHERITED (factory) {}
 
-        virtual void emitCode(GrGLFullShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+        virtual void emitCode(GrGLFullProgramBuilder* builder,
+                              const GrGeometryProcessor& geometryProcessor,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
                               const TextureSamplerArray& samplers) SK_OVERRIDE {
-            const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIEllipseEdgeEffect>();
-
-            SkAssertResult(builder->enableFeature(
-                                              GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
+            const DIEllipseEdgeEffect& ellipseEffect =
+                    geometryProcessor.cast<DIEllipseEdgeEffect>();
 
             const char *vsOffsetName0, *fsOffsetName0;
             builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0",
                                       &vsOffsetName0, &fsOffsetName0);
-            const SkString* attr0Name =
-                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-            builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Name->c_str());
+
+            GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+            vsBuilder->codeAppendf("%s = %s;", vsOffsetName0,
+                                   ellipseEffect.inEllipseOffsets0().c_str());
             const char *vsOffsetName1, *fsOffsetName1;
             builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1",
                                       &vsOffsetName1, &fsOffsetName1);
-            const SkString* attr1Name =
-                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
-            builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Name->c_str());
+            vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1,
+                                   ellipseEffect.inEllipseOffsets1().c_str());
 
+            GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+            SkAssertResult(fsBuilder->enableFeature(
+                    GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
             // for outer curve
-            builder->fsCodeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetName0);
-            builder->fsCodeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
-            builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0);
-            builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0);
-            builder->fsCodeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
+            fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetName0);
+            fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
+            fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0);
+            fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0);
+            fsBuilder->codeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
                                    "\t                 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
                                    fsOffsetName0, fsOffsetName0, fsOffsetName0, fsOffsetName0);
 
-            builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n");
+            fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
             // avoid calling inversesqrt on zero.
-            builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
-            builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
+            fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
+            fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
             if (kHairline == ellipseEffect.getMode()) {
                 // can probably do this with one step
-                builder->fsCodeAppend("\tfloat edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);\n");
-                builder->fsCodeAppend("\tedgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);\n");
+                fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);\n");
+                fsBuilder->codeAppend("\tedgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);\n");
             } else {
-                builder->fsCodeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
+                fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
             }
 
             // for inner curve
             if (kStroke == ellipseEffect.getMode()) {
-                builder->fsCodeAppendf("\tscaledOffset = %s.xy;\n", fsOffsetName1);
-                builder->fsCodeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
-                builder->fsCodeAppendf("\tduvdx = dFdx(%s);\n", fsOffsetName1);
-                builder->fsCodeAppendf("\tduvdy = dFdy(%s);\n", fsOffsetName1);
-                builder->fsCodeAppendf("\tgrad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
+                fsBuilder->codeAppendf("\tscaledOffset = %s.xy;\n", fsOffsetName1);
+                fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
+                fsBuilder->codeAppendf("\tduvdx = dFdx(%s);\n", fsOffsetName1);
+                fsBuilder->codeAppendf("\tduvdy = dFdy(%s);\n", fsOffsetName1);
+                fsBuilder->codeAppendf("\tgrad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
                                        "\t            2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
                                        fsOffsetName1, fsOffsetName1, fsOffsetName1, fsOffsetName1);
-                builder->fsCodeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
-                builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
+                fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
+                fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
             }
 
-            builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+            fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIEllipseEdgeEffect>();
+        static void GenKey(const GrProcessor& processor, const GrGLCaps&,
+                           GrProcessorKeyBuilder* b) {
+            const DIEllipseEdgeEffect& ellipseEffect = processor.cast<DIEllipseEdgeEffect>();
 
-            return ellipseEffect.getMode();
+            b->add32(ellipseEffect.getMode());
         }
 
-        virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
+        virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {
         }
 
     private:
-        typedef GrGLVertexEffect INHERITED;
+        typedef GrGLGeometryProcessor INHERITED;
     };
 
 private:
-    DIEllipseEdgeEffect(Mode mode) : GrVertexEffect() {
-        this->addVertexAttrib(kVec2f_GrSLType);
-        this->addVertexAttrib(kVec2f_GrSLType);
+    DIEllipseEdgeEffect(Mode mode)
+        : fInEllipseOffsets0(this->addVertexAttrib(
+                GrShaderVar("inEllipseOffsets0",
+                            kVec2f_GrSLType,
+                            GrShaderVar::kAttribute_TypeModifier)))
+        , fInEllipseOffsets1(this->addVertexAttrib(
+                GrShaderVar("inEllipseOffsets1",
+                            kVec2f_GrSLType,
+                            GrShaderVar::kAttribute_TypeModifier))) {
         fMode = mode;
     }
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
-        const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other);
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE {
+        const DIEllipseEdgeEffect& eee = other.cast<DIEllipseEdgeEffect>();
         return eee.fMode == fMode;
     }
 
+    const GrShaderVar& fInEllipseOffsets0;
+    const GrShaderVar& fInEllipseOffsets1;
     Mode fMode;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrVertexEffect INHERITED;
+    typedef GrGeometryProcessor INHERITED;
 };
 
-GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect);
 
-GrEffectRef* DIEllipseEdgeEffect::TestCreate(SkRandom* random,
-                                             GrContext* context,
-                                             const GrDrawTargetCaps&,
-                                             GrTexture* textures[]) {
+GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random,
+                                                     GrContext* context,
+                                                     const GrDrawTargetCaps&,
+                                                     GrTexture* textures[]) {
     return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2)));
 }
 
@@ -488,7 +519,7 @@
 // position + edge
 extern const GrVertexAttrib gCircleVertexAttribs[] = {
     {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-    {kVec4f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}
+    {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
 };
 
 void GrOvalRenderer::drawCircle(GrDrawTarget* target,
@@ -509,8 +540,8 @@
         return;
     }
 
-    drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs));
-    SkASSERT(sizeof(CircleVertex) == drawState->getVertexSize());
+    drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs),
+                                                      sizeof(CircleVertex));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
     if (!geo.succeeded()) {
@@ -541,9 +572,8 @@
         }
     }
 
-    GrEffectRef* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0);
-    static const int kCircleEdgeAttrIndex = 1;
-    drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref();
+    GrGeometryProcessor* gp = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0);
+    drawState->setGeometryProcessor(gp)->unref();
 
     // The radii are outset for two reasons. First, it allows the shader to simply perform
     // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the
@@ -587,15 +617,15 @@
 // position + offset + 1/radii
 extern const GrVertexAttrib gEllipseVertexAttribs[] = {
     {kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, sizeof(SkPoint),   kEffect_GrVertexAttribBinding},
-    {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kEffect_GrVertexAttribBinding}
+    {kVec2f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding},
+    {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}
 };
 
 // position + offsets
 extern const GrVertexAttrib gDIEllipseVertexAttribs[] = {
     {kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, sizeof(SkPoint),   kEffect_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kEffect_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding},
 };
 
 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
@@ -670,8 +700,8 @@
         return false;
     }
 
-    drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs));
-    SkASSERT(sizeof(EllipseVertex) == drawState->getVertexSize());
+    drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs),
+                                                       sizeof(EllipseVertex));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
     if (!geo.succeeded()) {
@@ -681,12 +711,10 @@
 
     EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
 
-    GrEffectRef* effect = EllipseEdgeEffect::Create(isStrokeOnly &&
-                                                    innerXRadius > 0 && innerYRadius > 0);
+    GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly &&
+                                                        innerXRadius > 0 && innerYRadius > 0);
 
-    static const int kEllipseCenterAttrIndex = 1;
-    static const int kEllipseEdgeAttrIndex = 2;
-    drawState->addCoverageEffect(effect, kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref();
+    drawState->setGeometryProcessor(gp)->unref();
 
     // Compute the reciprocals of the radii here to save time in the shader
     SkScalar xRadRecip = SkScalarInvert(xRadius);
@@ -789,8 +817,8 @@
     SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
     SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
 
-    drawState->setVertexAttribs<gDIEllipseVertexAttribs>(SK_ARRAY_COUNT(gDIEllipseVertexAttribs));
-    SkASSERT(sizeof(DIEllipseVertex) == drawState->getVertexSize());
+    drawState->setVertexAttribs<gDIEllipseVertexAttribs>(SK_ARRAY_COUNT(gDIEllipseVertexAttribs),
+                                                         sizeof(DIEllipseVertex));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
     if (!geo.succeeded()) {
@@ -800,12 +828,9 @@
 
     DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices());
 
-    GrEffectRef* effect = DIEllipseEdgeEffect::Create(mode);
+    GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode);
 
-    static const int kEllipseOuterOffsetAttrIndex = 1;
-    static const int kEllipseInnerOffsetAttrIndex = 2;
-    drawState->addCoverageEffect(effect, kEllipseOuterOffsetAttrIndex,
-                                         kEllipseInnerOffsetAttrIndex)->unref();
+    drawState->setGeometryProcessor(gp)->unref();
 
     // This expands the outer rect so that after CTM we end up with a half-pixel border
     SkScalar a = vm[SkMatrix::kMScaleX];
@@ -871,7 +896,7 @@
     if (NULL == fRRectIndexBuffer) {
         fRRectIndexBuffer =
         gpu->createIndexBuffer(sizeof(gRRectIndices), false);
-        if (NULL != fRRectIndexBuffer) {
+        if (fRRectIndexBuffer) {
 #ifdef SK_DEBUG
             bool updated =
 #endif
@@ -896,14 +921,15 @@
                 return false;
             }
         }
-        GrEffectEdgeType edgeType = applyAA ? kInverseFillAA_GrEffectEdgeType :
-                                              kInverseFillBW_GrEffectEdgeType;
-        GrEffectRef* effect = GrRRectEffect::Create(edgeType, *inner);
-        if (NULL == effect) {
+        GrPrimitiveEdgeType edgeType = applyAA ?
+                kInverseFillAA_GrProcessorEdgeType :
+                kInverseFillBW_GrProcessorEdgeType;
+        GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner);
+        if (NULL == fp) {
             return false;
         }
         are.set(target->drawState());
-        target->drawState()->addCoverageEffect(effect)->unref();
+        target->drawState()->addCoverageProcessor(fp)->unref();
     }
 
     SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle);
@@ -918,9 +944,9 @@
             return false;
         }
     }
-    GrEffectEdgeType edgeType = applyAA ? kFillAA_GrEffectEdgeType :
-                                          kFillBW_GrEffectEdgeType;
-    GrEffectRef* effect = GrRRectEffect::Create(edgeType, *outer);
+    GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType :
+                                          kFillBW_GrProcessorEdgeType;
+    GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer);
     if (NULL == effect) {
         return false;
     }
@@ -931,12 +957,12 @@
     if (!avmr.setIdentity(target->drawState())) {
         return false;
     }
-    target->drawState()->addCoverageEffect(effect)->unref();
+    target->drawState()->addCoverageProcessor(effect)->unref();
     SkRect bounds = outer->getBounds();
     if (applyAA) {
         bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
     }
-    target->drawRect(bounds, NULL, NULL, NULL);
+    target->drawRect(bounds, NULL, NULL);
     return true;
 }
 
@@ -1022,8 +1048,8 @@
 
     // if the corners are circles, use the circle renderer
     if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius) {
-        drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs));
-        SkASSERT(sizeof(CircleVertex) == drawState->getVertexSize());
+        drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs),
+                                                          sizeof(CircleVertex));
 
         GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
         if (!geo.succeeded()) {
@@ -1051,9 +1077,8 @@
 
         isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
 
-        GrEffectRef* effect = CircleEdgeEffect::Create(isStrokeOnly);
-        static const int kCircleEdgeAttrIndex = 1;
-        drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref();
+        GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly);
+        drawState->setGeometryProcessor(effect)->unref();
 
         // The radii are outset for two reasons. First, it allows the shader to simply perform
         // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the
@@ -1111,8 +1136,8 @@
 
     // otherwise we use the ellipse renderer
     } else {
-        drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs));
-        SkASSERT(sizeof(EllipseVertex) == drawState->getVertexSize());
+        drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs),
+                                                           sizeof(EllipseVertex));
 
         SkScalar innerXRadius = 0.0f;
         SkScalar innerYRadius = 0.0f;
@@ -1155,11 +1180,8 @@
         }
         EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
 
-        GrEffectRef* effect = EllipseEdgeEffect::Create(isStrokeOnly);
-        static const int kEllipseOffsetAttrIndex = 1;
-        static const int kEllipseRadiiAttrIndex = 2;
-        drawState->addCoverageEffect(effect,
-                                     kEllipseOffsetAttrIndex, kEllipseRadiiAttrIndex)->unref();
+        GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly);
+        drawState->setGeometryProcessor(effect)->unref();
 
         // Compute the reciprocals of the radii here to save time in the shader
         SkScalar xRadRecip = SkScalarInvert(xRadius);
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index 35912a9..84fdf42 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -11,28 +11,24 @@
 #include "GrBlend.h"
 #include "effects/GrSimpleTextureEffect.h"
 
-void GrPaint::addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
-    GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
-    this->addColorEffect(effect)->unref();
+void GrPaint::addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
+    this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
 }
 
-void GrPaint::addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
-    GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
-    this->addCoverageEffect(effect)->unref();
+void GrPaint::addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
+    this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
 }
 
-void GrPaint::addColorTextureEffect(GrTexture* texture,
+void GrPaint::addColorTextureProcessor(GrTexture* texture,
                                     const SkMatrix& matrix,
                                     const GrTextureParams& params) {
-    GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
-    this->addColorEffect(effect)->unref();
+    this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
 }
 
-void GrPaint::addCoverageTextureEffect(GrTexture* texture,
+void GrPaint::addCoverageTextureProcessor(GrTexture* texture,
                                        const SkMatrix& matrix,
                                        const GrTextureParams& params) {
-    GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
-    this->addCoverageEffect(effect)->unref();
+    this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
 }
 
 bool GrPaint::isOpaque() const {
@@ -60,7 +56,7 @@
     uint32_t coverageComps = kRGBA_GrColorComponentFlags;
     int count = fCoverageStages.count();
     for (int i = 0; i < count; ++i) {
-        (*fCoverageStages[i].getEffect())->getConstantColorComponents(&coverage, &coverageComps);
+        fCoverageStages[i].getProcessor()->getConstantColorComponents(&coverage, &coverageComps);
     }
     if (kRGBA_GrColorComponentFlags != coverageComps || 0xffffffff != coverage) {
         return false;
@@ -70,7 +66,7 @@
     uint32_t colorComps = kRGBA_GrColorComponentFlags;
     count = fColorStages.count();
     for (int i = 0; i < count; ++i) {
-        (*fColorStages[i].getEffect())->getConstantColorComponents(&color, &colorComps);
+        fColorStages[i].getProcessor()->getConstantColorComponents(&color, &colorComps);
     }
 
     SkASSERT((NULL == solidColor) == (NULL == solidColorKnownComponents));
@@ -80,7 +76,7 @@
     GrSimplifyBlend(&srcCoeff, &dstCoeff, color, colorComps, 0, 0, 0);
 
     bool opaque = kZero_GrBlendCoeff == dstCoeff && !GrBlendCoeffRefsDst(srcCoeff);
-    if (NULL != solidColor) {
+    if (solidColor) {
         if (opaque) {
             switch (srcCoeff) {
                 case kZero_GrBlendCoeff:
diff --git a/src/gpu/GrPath.cpp b/src/gpu/GrPath.cpp
index adb3fe6..5426e49 100644
--- a/src/gpu/GrPath.cpp
+++ b/src/gpu/GrPath.cpp
@@ -7,25 +7,54 @@
 
 #include "GrPath.h"
 
+template<int NumBits> static uint64_t get_top_n_float_bits(float f) {
+    char* floatData = reinterpret_cast<char*>(&f);
+    uint32_t floatBits = *reinterpret_cast<uint32_t*>(floatData);
+    return floatBits >> (32 - NumBits);
+}
+
 GrResourceKey GrPath::ComputeKey(const SkPath& path, const SkStrokeRec& stroke) {
     static const GrResourceKey::ResourceType gPathResourceType = GrResourceKey::GenerateResourceType();
     static const GrCacheID::Domain gPathDomain = GrCacheID::GenerateDomain();
 
     GrCacheID::Key key;
-    uint32_t* keyData = key.fData32;
+    uint64_t* keyData = key.fData64;
     keyData[0] = path.getGenerationID();
-
-    SK_COMPILE_ASSERT(SkPaint::kJoinCount <= 3, cap_shift_will_be_wrong);
-    keyData[1] = stroke.needToApply();
-    if (0 != keyData[1]) {
-        keyData[1] |= stroke.getJoin() << 1;
-        keyData[1] |= stroke.getCap() << 3;
-        keyData[2] = static_cast<uint32_t>(stroke.getMiter());
-        keyData[3] = static_cast<uint32_t>(stroke.getWidth());
-    } else {
-        keyData[2] = 0;
-        keyData[3] = 0;
-    }
+    keyData[1] = ComputeStrokeKey(stroke);
 
     return GrResourceKey(GrCacheID(gPathDomain, key), gPathResourceType, 0);
 }
+
+uint64_t GrPath::ComputeStrokeKey(const SkStrokeRec& stroke) {
+    enum {
+        kStyleBits = 2,
+        kJoinBits = 2,
+        kCapBits = 2,
+        kWidthBits = 29,
+        kMiterBits = 29,
+
+        kJoinShift = kStyleBits,
+        kCapShift = kJoinShift + kJoinBits,
+        kWidthShift = kCapShift + kCapBits,
+        kMiterShift = kWidthShift + kWidthBits,
+
+        kBitCount = kMiterShift + kMiterBits
+    };
+
+    SK_COMPILE_ASSERT(SkStrokeRec::kStyleCount <= (1 << kStyleBits), style_shift_will_be_wrong);
+    SK_COMPILE_ASSERT(SkPaint::kJoinCount <= (1 << kJoinBits), cap_shift_will_be_wrong);
+    SK_COMPILE_ASSERT(SkPaint::kCapCount <= (1 << kCapBits), miter_shift_will_be_wrong);
+    SK_COMPILE_ASSERT(kBitCount == 64, wrong_stroke_key_size);
+
+    if (!stroke.needToApply()) {
+        return SkStrokeRec::kFill_Style;
+    }
+
+    uint64_t key = stroke.getStyle();
+    key |= stroke.getJoin() << kJoinShift;
+    key |= stroke.getCap() << kCapShift;
+    key |= get_top_n_float_bits<kWidthBits>(stroke.getWidth()) << kWidthShift;
+    key |= get_top_n_float_bits<kMiterBits>(stroke.getMiter()) << kMiterShift;
+
+    return key;
+}
diff --git a/src/gpu/GrPath.h b/src/gpu/GrPath.h
index d324e6a..a571935 100644
--- a/src/gpu/GrPath.h
+++ b/src/gpu/GrPath.h
@@ -8,16 +8,19 @@
 #ifndef GrPath_DEFINED
 #define GrPath_DEFINED
 
-#include "GrGpuObject.h"
+#include "GrGpuResource.h"
 #include "GrResourceCache.h"
 #include "SkPath.h"
 #include "SkRect.h"
 #include "SkStrokeRec.h"
 
-class GrPath : public GrGpuObject {
+class GrPath : public GrGpuResource {
 public:
     SK_DECLARE_INST_COUNT(GrPath);
 
+    /**
+     * Initialize to a path with a fixed stroke. Stroke must not be hairline.
+     */
     GrPath(GrGpu* gpu, bool isWrapped, const SkPath& skPath, const SkStrokeRec& stroke)
         : INHERITED(gpu, isWrapped),
           fSkPath(skPath),
@@ -26,6 +29,7 @@
     }
 
     static GrResourceKey ComputeKey(const SkPath& path, const SkStrokeRec& stroke);
+    static uint64_t ComputeStrokeKey(const SkStrokeRec&);
 
     bool isEqualTo(const SkPath& path, const SkStrokeRec& stroke) {
         return fSkPath == path && fStroke == stroke;
@@ -41,7 +45,7 @@
     SkRect fBounds;
 
 private:
-    typedef GrGpuObject INHERITED;
+    typedef GrGpuResource INHERITED;
 };
 
 #endif
diff --git a/src/gpu/GrPathRange.cpp b/src/gpu/GrPathRange.cpp
new file mode 100644
index 0000000..3d0f7cf
--- /dev/null
+++ b/src/gpu/GrPathRange.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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 "GrPathRange.h"
+#include "SkPath.h"
+
+enum {
+    kPathsPerGroup = 16 // Paths get tracked in groups of 16 for lazy loading.
+};
+
+GrPathRange::GrPathRange(GrGpu* gpu,
+                         PathGenerator* pathGenerator,
+                         const SkStrokeRec& stroke)
+    : INHERITED(gpu, kIsWrapped),
+      fPathGenerator(SkRef(pathGenerator)),
+      fNumPaths(fPathGenerator->getNumPaths()),
+      fStroke(stroke) {
+    const int numGroups = (fNumPaths + kPathsPerGroup - 1) / kPathsPerGroup;
+    fGeneratedPaths.reset((numGroups + 7) / 8); // 1 bit per path group.
+    memset(&fGeneratedPaths.front(), 0, fGeneratedPaths.count());
+}
+
+GrPathRange::GrPathRange(GrGpu* gpu,
+                         int numPaths,
+                         const SkStrokeRec& stroke)
+    : INHERITED(gpu, kIsWrapped),
+      fNumPaths(numPaths),
+      fStroke(stroke) {
+}
+
+void GrPathRange::willDrawPaths(const uint32_t indices[], int count) const {
+    if (NULL == fPathGenerator.get()) {
+        return;
+    }
+
+    bool didLoadPaths = false;
+
+    for (int i = 0; i < count; ++i) {
+        SkASSERT(indices[i] < static_cast<uint32_t>(fNumPaths));
+
+        const int groupIndex = indices[i] / kPathsPerGroup;
+        const int groupByte = groupIndex / 8;
+        const uint8_t groupBit = 1 << (groupIndex % 8);
+
+        const bool hasPath = SkToBool(fGeneratedPaths[groupByte] & groupBit);
+        if (!hasPath) {
+            // We track which paths are loaded in groups of kPathsPerGroup. To
+            // mark a path as loaded we need to load the entire group.
+            const int groupFirstPath = groupIndex * kPathsPerGroup;
+            const int groupLastPath = SkTMin(groupFirstPath + kPathsPerGroup, fNumPaths) - 1;
+
+            SkPath path;
+            for (int pathIdx = groupFirstPath; pathIdx <= groupLastPath; ++pathIdx) {
+                fPathGenerator->generatePath(pathIdx, &path);
+                this->onInitPath(pathIdx, path);
+            }
+
+            fGeneratedPaths[groupByte] |= groupBit;
+            didLoadPaths = true;
+        }
+    }
+
+    if (didLoadPaths) {
+        this->didChangeGpuMemorySize();
+    }
+}
diff --git a/src/gpu/GrPathRange.h b/src/gpu/GrPathRange.h
new file mode 100644
index 0000000..dc8ce1d
--- /dev/null
+++ b/src/gpu/GrPathRange.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrPathRange_DEFINED
+#define GrPathRange_DEFINED
+
+#include "GrGpuResource.h"
+#include "GrResourceCache.h"
+#include "SkRefCnt.h"
+#include "SkStrokeRec.h"
+#include "SkTArray.h"
+
+class SkPath;
+class SkDescriptor;
+
+/**
+ * Represents a contiguous range of GPU path objects, all with a common stroke.
+ * This object is immutable with the exception that individual paths may be
+ * initialized lazily.
+ */
+
+class GrPathRange : public GrGpuResource {
+public:
+    SK_DECLARE_INST_COUNT(GrPathRange);
+
+    static const bool kIsWrapped = false;
+
+    /**
+     * Return the resourceType intended for cache lookups involving GrPathRange.
+     */
+    static GrResourceKey::ResourceType resourceType() {
+        static const GrResourceKey::ResourceType type = GrResourceKey::GenerateResourceType();
+        return type;
+    }
+
+    /**
+     *  Class that generates the paths for a specific range.
+     */
+    class PathGenerator : public SkRefCnt {
+    public:
+        virtual int getNumPaths() = 0;
+        virtual void generatePath(int index, SkPath* out) = 0;
+        virtual bool isEqualTo(const SkDescriptor&) const { return false; }
+        virtual ~PathGenerator() {}
+    };
+
+    /**
+     * Initialize a lazy-loaded path range. This class will generate an SkPath and call
+     * onInitPath() for each path within the range before it is drawn for the first time.
+     */
+    GrPathRange(GrGpu*, PathGenerator*, const SkStrokeRec& stroke);
+
+    /**
+     * Initialize an eager-loaded path range. The subclass is responsible for ensuring all
+     * the paths are initialized up front.
+     */
+    GrPathRange(GrGpu*, int numPaths, const SkStrokeRec& stroke);
+
+    virtual bool isEqualTo(const SkDescriptor& desc) const {
+        return NULL != fPathGenerator.get() && fPathGenerator->isEqualTo(desc);
+    }
+
+    int getNumPaths() const { return fNumPaths; }
+    const SkStrokeRec& getStroke() const { return fStroke; }
+    const PathGenerator* getPathGenerator() const { return fPathGenerator.get(); }
+
+protected:
+    // Initialize a path in the range before drawing. This is only called when
+    // fPathGenerator is non-null. The child class need not call didChangeGpuMemorySize(),
+    // GrPathRange will take care of that after the call is complete.
+    virtual void onInitPath(int index, const SkPath&) const = 0;
+
+private:
+    // Notify when paths will be drawn in case this is a lazy-loaded path range.
+    friend class GrGpu;
+    void willDrawPaths(const uint32_t indices[], int count) const;
+
+    mutable SkAutoTUnref<PathGenerator> fPathGenerator;
+    mutable SkTArray<uint8_t, true /*MEM_COPY*/> fGeneratedPaths;
+    const int fNumPaths;
+    const SkStrokeRec fStroke;
+
+    typedef GrGpuResource INHERITED;
+};
+
+#endif
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index 88665c1..0720c3f 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -49,9 +49,9 @@
     /**
      * A caller may wish to use a path renderer to draw a path into the stencil buffer. However,
      * the path renderer itself may require use of the stencil buffer. Also a path renderer may
-     * use a GrEffect coverage stage that sets coverage to zero to eliminate pixels that are covered
-     * by bounding geometry but outside the path. These exterior pixels would still be rendered into
-     * the stencil.
+     * use a GrProcessor coverage stage that sets coverage to zero to eliminate pixels that are
+     * covered by bounding geometry but outside the path. These exterior pixels would still be
+     * rendered into the stencil.
      *
      * A GrPathRenderer can provide three levels of support for stenciling paths:
      * 1) kNoRestriction: This is the most general. The caller sets up the GrDrawState on the target
@@ -143,7 +143,7 @@
     static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const SkMatrix& matrix,
                                              SkScalar* outCoverage) {
         if (stroke.isHairlineStyle()) {
-            if (NULL != outCoverage) {
+            if (outCoverage) {
                 *outCoverage = SK_Scalar1;
             }
             return true;
diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp
index cac0475..8108572 100644
--- a/src/gpu/GrPathRendererChain.cpp
+++ b/src/gpu/GrPathRendererChain.cpp
@@ -65,7 +65,7 @@
                                                                                       target);
                 if (support < minStencilSupport) {
                     continue;
-                } else if (NULL != stencilSupport) {
+                } else if (stencilSupport) {
                     *stencilSupport = support;
                 }
             }
diff --git a/src/gpu/GrPathRendering.cpp b/src/gpu/GrPathRendering.cpp
new file mode 100644
index 0000000..ed9a1e6
--- /dev/null
+++ b/src/gpu/GrPathRendering.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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 "GrPathRendering.h"
+#include "SkDescriptor.h"
+#include "SkGlyph.h"
+#include "SkMatrix.h"
+#include "SkTypeface.h"
+#include "GrPathRange.h"
+
+class GlyphGenerator : public GrPathRange::PathGenerator {
+public:
+    GlyphGenerator(const SkTypeface& typeface, const SkDescriptor& desc)
+        : fDesc(desc.copy()),
+          fScalerContext(typeface.createScalerContext(fDesc)) {
+        fFlipMatrix.setScale(1, -1);
+    }
+
+    virtual ~GlyphGenerator() {
+        SkDescriptor::Free(fDesc);
+    }
+
+    virtual int getNumPaths() {
+        return fScalerContext->getGlyphCount();
+    }
+
+    virtual void generatePath(int glyphID, SkPath* out) {
+        SkGlyph skGlyph;
+        skGlyph.init(SkGlyph::MakeID(glyphID));
+        fScalerContext->getMetrics(&skGlyph);
+
+        fScalerContext->getPath(skGlyph, out);
+        out->transform(fFlipMatrix); // Load glyphs with the inverted y-direction.
+    }
+
+    virtual bool isEqualTo(const SkDescriptor& desc) const {
+        return fDesc->equals(desc);
+    }
+
+private:
+    SkDescriptor* const fDesc;
+    const SkAutoTDelete<SkScalerContext> fScalerContext;
+    SkMatrix fFlipMatrix;
+};
+
+GrPathRange* GrPathRendering::createGlyphs(const SkTypeface* typeface,
+                                           const SkDescriptor* desc,
+                                           const SkStrokeRec& stroke) {
+    if (NULL == typeface) {
+        typeface = SkTypeface::GetDefaultTypeface();
+        SkASSERT(NULL != typeface);
+    }
+
+    if (desc) {
+        SkAutoTUnref<GlyphGenerator> generator(SkNEW_ARGS(GlyphGenerator, (*typeface, *desc)));
+        return this->createPathRange(generator, stroke);
+    }
+
+    SkScalerContextRec rec;
+    memset(&rec, 0, sizeof(rec));
+    rec.fFontID = typeface->uniqueID();
+    rec.fTextSize = SkPaint::kCanonicalTextSizeForPaths;
+    rec.fPreScaleX = rec.fPost2x2[0][0] = rec.fPost2x2[1][1] = SK_Scalar1;
+    // Don't bake stroke information into the glyphs, we'll let the GPU do the stroking.
+
+    SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
+    SkDescriptor*    genericDesc = ad.getDesc();
+
+    genericDesc->init();
+    genericDesc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
+    genericDesc->computeChecksum();
+
+    SkAutoTUnref<GlyphGenerator> generator(SkNEW_ARGS(GlyphGenerator, (*typeface, *genericDesc)));
+    return this->createPathRange(generator, stroke);
+}
diff --git a/src/gpu/GrPathRendering.h b/src/gpu/GrPathRendering.h
new file mode 100644
index 0000000..26cfa11
--- /dev/null
+++ b/src/gpu/GrPathRendering.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrPathRendering_DEFINED
+#define GrPathRendering_DEFINED
+
+#include "SkPath.h"
+#include "GrPathRange.h"
+
+class SkStrokeRec;
+class SkDescriptor;
+class SkTypeface;
+class GrPath;
+class GrGpu;
+
+/**
+ * Abstract class wrapping HW path rendering API.
+ *
+ * The subclasses of this class use the possible HW API to render paths (as opposed to path
+ * rendering implemented in Skia on top of a "3d" HW API).
+ * The subclasses hold the global state needed to render paths, including shadow of the global HW
+ * API state. Similar to GrGpu.
+ *
+ * It is expected that the lifetimes of GrGpuXX and GrXXPathRendering are the same. The call context
+ * interface (eg.  * the concrete instance of GrGpu subclass) should be provided to the instance
+ * during construction.
+ */
+class GrPathRendering {
+public:
+    virtual ~GrPathRendering() { }
+
+    enum PathTransformType {
+        kNone_PathTransformType,        //!< []
+        kTranslateX_PathTransformType,  //!< [kMTransX]
+        kTranslateY_PathTransformType,  //!< [kMTransY]
+        kTranslate_PathTransformType,   //!< [kMTransX, kMTransY]
+        kAffine_PathTransformType,      //!< [kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY]
+
+        kLast_PathTransformType = kAffine_PathTransformType
+    };
+
+    static inline int PathTransformSize(PathTransformType type) {
+        switch (type) {
+            case kNone_PathTransformType:
+                return 0;
+            case kTranslateX_PathTransformType:
+            case kTranslateY_PathTransformType:
+                return 1;
+            case kTranslate_PathTransformType:
+                return 2;
+            case kAffine_PathTransformType:
+                return 6;
+
+            default:
+                SkFAIL("Unknown path transform type");
+                return 0;
+        }
+    }
+
+    /**
+     * Creates a new gpu path, based on the specified path and stroke and returns it.
+     * The caller owns a ref on the returned path which must be balanced by a call to unref.
+     *
+     * @param skPath the path geometry.
+     * @param stroke the path stroke.
+     * @return a new path.
+     */
+    virtual GrPath* createPath(const SkPath&, const SkStrokeRec&) = 0;
+
+    /**
+     * Creates a range of gpu paths with a common stroke. The caller owns a ref on the
+     * returned path range which must be balanced by a call to unref.
+     *
+     * @param PathGenerator class that generates SkPath objects for each path in the range.
+     * @param SkStrokeRec   the common stroke applied to each path in the range.
+     * @return a new path range.
+     */
+    virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*, const SkStrokeRec&) = 0;
+
+    /**
+     * Creates a range of glyph paths, indexed by glyph id. The glyphs will have an
+     * inverted y-direction in order to match the raw font path data. The caller owns
+     * a ref on the returned path range which must be balanced by a call to unref.
+     *
+     * @param SkTypeface   Typeface that defines the glyphs.
+     *                     If null, the default typeface will be used.
+     *
+     * @param SkDescriptor Additional font configuration that specifies the font's size,
+     *                     stroke, and other flags. This will generally come from an
+     *                     SkGlyphCache.
+     *
+     *                     It is recommended to leave this value null when possible, in
+     *                     which case the glyphs will be loaded directly from the font's
+     *                     raw path data and sized at SkPaint::kCanonicalTextSizeForPaths.
+     *                     This will result in less memory usage and more efficient paths.
+     *
+     *                     If non-null, the glyph paths will match the font descriptor,
+     *                     including with the stroke information baked directly into
+     *                     the outlines.
+     *
+     * @param SkStrokeRec  Common stroke that the GPU will apply to every path. Note that
+     *                     if the glyph outlines contain baked-in strokes from the font
+     *                     descriptor, the GPU stroke will be applied on top of those
+     *                     outlines.
+     *
+     * @return a new path range populated with glyphs.
+     */
+    virtual GrPathRange* createGlyphs(const SkTypeface*, const SkDescriptor*, const SkStrokeRec&) = 0;
+
+    virtual void stencilPath(const GrPath*, SkPath::FillType) = 0;
+    virtual void drawPath(const GrPath*, SkPath::FillType) = 0;
+    virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count,
+                           const float transforms[], PathTransformType, SkPath::FillType) = 0;
+protected:
+    GrPathRendering() { }
+
+private:
+    GrPathRendering& operator=(const GrPathRendering&);
+};
+
+#endif
diff --git a/src/gpu/GrPictureUtils.cpp b/src/gpu/GrPictureUtils.cpp
index 6fed2f6..a4f32e7 100644
--- a/src/gpu/GrPictureUtils.cpp
+++ b/src/gpu/GrPictureUtils.cpp
@@ -6,274 +6,260 @@
  */
 
 #include "GrPictureUtils.h"
-#include "SkDevice.h"
-#include "SkDraw.h"
-#include "SkPaintPriv.h"
-#include "SkPicturePlayback.h"
 
-SkPicture::AccelData::Key GPUAccelData::ComputeAccelDataKey() {
+#include "SkPaintPriv.h"
+#include "SkRecord.h"
+#include "SkRecords.h"
+
+SkPicture::AccelData::Key GrAccelData::ComputeAccelDataKey() {
     static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::GenerateDomain();
 
     return gGPUID;
 }
 
-// The GrGather device performs GPU-backend-specific preprocessing on
-// a picture. The results are stored in a GPUAccelData.
-//
-// Currently the only interesting work is done in drawDevice (i.e., when a
-// saveLayer is collapsed back into its parent) and, maybe, in onCreateDevice.
-// All the current work could be done much more efficiently by just traversing the
-// raw op codes in the SkPicture (although we would still need to replay all the
-// clip calls).
-class GrGatherDevice : public SkBaseDevice {
+// SkRecord visitor to gather saveLayer/restore information.
+class CollectLayers {
 public:
-    SK_DECLARE_INST_COUNT(GrGatherDevice)
+    CollectLayers(const SkPicture* pict, GrAccelData* accelData)
+        : fPictureID(pict->uniqueID())
+        , fCTM(&SkMatrix::I())
+        , fSaveLayersInStack(0)
+        , fAccelData(accelData) {
 
-    GrGatherDevice(int width, int height, const SkPicture* picture, GPUAccelData* accelData,
-                   int saveLayerDepth) {
-        fPicture = picture;
-        fSaveLayerDepth = saveLayerDepth;
-        fInfo.fValid = true;
-        fInfo.fSize.set(width, height);
-        fInfo.fPaint = NULL;
-        fInfo.fSaveLayerOpID = fPicture->EXPERIMENTAL_curOpID();
-        fInfo.fRestoreOpID = 0;
-        fInfo.fHasNestedLayers = false;
-        fInfo.fIsNested = (2 == fSaveLayerDepth);
+        pict->cullRect().roundOut(&fCurrentClipBounds);
 
-        fEmptyBitmap.setInfo(SkImageInfo::MakeUnknown(fInfo.fSize.fWidth, fInfo.fSize.fHeight));
-        fAccelData = accelData;
-        fAlreadyDrawn = false;
-    }
-
-    virtual ~GrGatherDevice() { }
-
-    virtual SkImageInfo imageInfo() const SK_OVERRIDE {
-        return fEmptyBitmap.info();
-    }
-
-#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
-    virtual void writePixels(const SkBitmap& bitmap, int x, int y,
-                             SkCanvas::Config8888 config8888) SK_OVERRIDE {
-        NotSupported();
-    }
-#endif
-    virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
-
-protected:
-    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE {
-        return false;
-    }
-    virtual void clear(SkColor color) SK_OVERRIDE {
-        NothingToDo();
-    }
-    virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
-                            const SkPoint points[], const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawRect(const SkDraw& draw, const SkRect& rect,
-                          const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawOval(const SkDraw& draw, const SkRect& rect,
-                          const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawRRect(const SkDraw& draw, const SkRRect& rrect,
-                           const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawPath(const SkDraw& draw, const SkPath& path,
-                          const SkPaint& paint, const SkMatrix* prePathMatrix,
-                          bool pathIsMutable) SK_OVERRIDE {
-    }
-    virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
-                            const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
-                            int x, int y, const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
-                                const SkRect* srcOrNull, const SkRect& dst,
-                                const SkPaint& paint,
-                                SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE {
-    }
-    virtual void drawText(const SkDraw& draw, const void* text, size_t len,
-                          SkScalar x, SkScalar y,
-                          const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
-                             const SkScalar pos[], SkScalar constY,
-                             int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len,
-                                const SkPath& path, const SkMatrix* matrix,
-                                const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode, int vertexCount,
-                              const SkPoint verts[], const SkPoint texs[],
-                              const SkColor colors[], SkXfermode* xmode,
-                              const uint16_t indices[], int indexCount,
-                              const SkPaint& paint) SK_OVERRIDE {
-    }
-    virtual void drawDevice(const SkDraw& draw, SkBaseDevice* deviceIn, int x, int y,
-                            const SkPaint& paint) SK_OVERRIDE {
-        // deviceIn is the one that is being "restored" back to its parent
-        GrGatherDevice* device = static_cast<GrGatherDevice*>(deviceIn);
-
-        if (device->fAlreadyDrawn) {
+        if (NULL == pict->fRecord.get()) {
             return;
         }
 
-        device->fInfo.fRestoreOpID = fPicture->EXPERIMENTAL_curOpID();
-        device->fInfo.fCTM = *draw.fMatrix;
-        device->fInfo.fCTM.postTranslate(SkIntToScalar(-device->getOrigin().fX),
-                                         SkIntToScalar(-device->getOrigin().fY));
-
-        device->fInfo.fOffset = device->getOrigin();
-
-        if (NeedsDeepCopy(paint)) {
-            // This NULL acts as a signal that the paint was uncopyable (for now)
-            device->fInfo.fPaint = NULL;
-            device->fInfo.fValid = false;
-        } else {
-            device->fInfo.fPaint = SkNEW_ARGS(SkPaint, (paint));
+        for (fCurrentOp = 0; fCurrentOp < pict->fRecord->count(); ++fCurrentOp) {
+            pict->fRecord->visit<void>(fCurrentOp, *this);
         }
 
-        fAccelData->addSaveLayerInfo(device->fInfo);
-        device->fAlreadyDrawn = true;
+        while (!fSaveStack.isEmpty()) {
+            this->popSaveBlock();
+        }
     }
-    // TODO: allow this call to return failure, or move to SkBitmapDevice only.
-    virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE {
-        return fEmptyBitmap;
-    }
-#ifdef SK_SUPPORT_LEGACY_READPIXELSCONFIG
-    virtual bool onReadPixels(const SkBitmap& bitmap,
-                              int x, int y,
-                              SkCanvas::Config8888 config8888) SK_OVERRIDE {
-        NotSupported();
-        return false;
-    }
-#endif
-    virtual void lockPixels() SK_OVERRIDE { NothingToDo(); }
-    virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); }
-    virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
-    virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
-    virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&,
-                             SkBitmap* result, SkIPoint* offset) SK_OVERRIDE {
-        return false;
+
+    template <typename T> void operator()(const T& op) {
+        this->updateCTM(op);
+        this->updateClipBounds(op);
+        this->trackSaveLayers(op);
     }
 
 private:
-    // The picture being processed
-    const SkPicture *fPicture;
 
-    SkBitmap fEmptyBitmap; // legacy -- need to remove
+    class SaveInfo {
+    public:
+        SaveInfo() { }
+        SaveInfo(int opIndex, bool isSaveLayer, const SkPaint* paint, const SkIRect& bounds) 
+            : fStartIndex(opIndex)
+            , fIsSaveLayer(isSaveLayer)
+            , fHasNestedSaveLayer(false)
+            , fPaint(paint)
+            , fBounds(bounds) {
 
-    // All information gathered during the gather process is stored here
-    GPUAccelData* fAccelData;
+        }
 
-    // true if this device has already been drawn back to its parent(s) at least
-    // once.
-    bool   fAlreadyDrawn;
+        int            fStartIndex;
+        bool           fIsSaveLayer;
+        bool           fHasNestedSaveLayer;
+        const SkPaint* fPaint;
+        SkIRect        fBounds;
+    };
 
-    // The information regarding the saveLayer call this device represents.
-    GPUAccelData::SaveLayerInfo fInfo;
+    uint32_t            fPictureID;
+    unsigned int        fCurrentOp;
+    const SkMatrix*     fCTM;
+    SkIRect             fCurrentClipBounds;
+    int                 fSaveLayersInStack;
+    SkTDArray<SaveInfo> fSaveStack;
+    GrAccelData*        fAccelData;
 
-    // The depth of this device in the saveLayer stack
-    int fSaveLayerDepth;
+    template <typename T> void updateCTM(const T&) { /* most ops don't change the CTM */ }
+    void updateCTM(const SkRecords::Restore& op)   { fCTM = &op.matrix; }
+    void updateCTM(const SkRecords::SetMatrix& op) { fCTM = &op.matrix; }
 
-    virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE {
-        NotSupported();
+    template <typename T> void updateClipBounds(const T&) { /* most ops don't change the clip */ }
+    // Each of these devBounds fields is the state of the device bounds after the op.
+    // So Restore's devBounds are those bounds saved by its paired Save or SaveLayer.
+    void updateClipBounds(const SkRecords::Restore& op)    { fCurrentClipBounds = op.devBounds; }
+    void updateClipBounds(const SkRecords::ClipPath& op)   { fCurrentClipBounds = op.devBounds; }
+    void updateClipBounds(const SkRecords::ClipRRect& op)  { fCurrentClipBounds = op.devBounds; }
+    void updateClipBounds(const SkRecords::ClipRect& op)   { fCurrentClipBounds = op.devBounds; }
+    void updateClipBounds(const SkRecords::ClipRegion& op) { fCurrentClipBounds = op.devBounds; }
+    void updateClipBounds(const SkRecords::SaveLayer& op)  {
+        if (op.bounds) {
+            fCurrentClipBounds.intersect(this->adjustAndMap(*op.bounds, op.paint));
+        }
     }
 
-    virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) SK_OVERRIDE {
-        // we expect to only get called via savelayer, in which case it is fine.
-        SkASSERT(kSaveLayer_Usage == usage);
+    template <typename T> void trackSaveLayers(const T& op) { 
+        /* most ops aren't involved in saveLayers */ 
+    }
+    void trackSaveLayers(const SkRecords::Save& s) { this->pushSaveBlock(); }
+    void trackSaveLayers(const SkRecords::SaveLayer& sl) { this->pushSaveLayerBlock(sl.paint); }
+    void trackSaveLayers(const SkRecords::Restore& r) { this->popSaveBlock(); }
+    void trackSaveLayers(const SkRecords::DrawPicture& dp) {
+        // For sub-pictures, we wrap their layer information within the parent
+        // picture's rendering hierarchy
+        const GrAccelData* childData = GPUOptimize(dp.picture);
 
-        fInfo.fHasNestedLayers = true;
-        return SkNEW_ARGS(GrGatherDevice, (info.width(), info.height(), fPicture,
-                                           fAccelData, fSaveLayerDepth+1));
+        for (int i = 0; i < childData->numSaveLayers(); ++i) {
+            const GrAccelData::SaveLayerInfo& src = childData->saveLayerInfo(i);
+
+            this->updateStackForSaveLayer();
+
+            // TODO: need to store an SkRect in GrAccelData::SaveLayerInfo?
+            SkRect srcRect = SkRect::MakeXYWH(SkIntToScalar(src.fOffset.fX),
+                                              SkIntToScalar(src.fOffset.fY),
+                                              SkIntToScalar(src.fSize.width()),
+                                              SkIntToScalar(src.fSize.height()));
+            SkIRect newClip(fCurrentClipBounds);
+            newClip.intersect(this->adjustAndMap(srcRect, dp.paint));
+
+            GrAccelData::SaveLayerInfo& dst = fAccelData->addSaveLayerInfo();
+
+            dst.fValid = true;
+            // If src.fPicture is NULL the layer is in dp.picture; otherwise
+            // it belongs to a sub-picture.
+            dst.fPicture = src.fPicture ? src.fPicture : static_cast<const SkPicture*>(dp.picture);
+            dst.fPicture->ref();
+            dst.fSize = SkISize::Make(newClip.width(), newClip.height());
+            dst.fOffset = SkIPoint::Make(newClip.fLeft, newClip.fTop);
+            dst.fOriginXform = *fCTM;
+            dst.fOriginXform.postConcat(src.fOriginXform);
+            if (src.fPaint) {
+                dst.fPaint = SkNEW_ARGS(SkPaint, (*src.fPaint));
+            }
+            dst.fSaveLayerOpID = src.fSaveLayerOpID;
+            dst.fRestoreOpID = src.fRestoreOpID;
+            dst.fHasNestedLayers = src.fHasNestedLayers;
+            dst.fIsNested = fSaveLayersInStack > 0 || src.fIsNested;
+        }
     }
 
-    virtual void flush() SK_OVERRIDE {}
-
-    static void NotSupported() {
-        SkDEBUGFAIL("this method should never be called");
+    void pushSaveBlock() {
+        fSaveStack.push(SaveInfo(fCurrentOp, false, NULL, SkIRect::MakeEmpty()));
     }
 
-    static void NothingToDo() {}
-
-    typedef SkBaseDevice INHERITED;
-};
-
-// The GrGatherCanvas allows saveLayers but simplifies clipping. It is really
-// only intended to be used as:
-//
-//      GrGatherDevice dev(w, h, picture, accelData);
-//      GrGatherCanvas canvas(..., picture);
-//      canvas.gather();
-//
-// which is all just to fill in 'accelData'
-class SK_API GrGatherCanvas : public SkCanvas {
-public:
-    GrGatherCanvas(GrGatherDevice* device, const SkPicture* pict)
-        : INHERITED(device)
-        , fPicture(pict) {
+    // Inform all the saveLayers already on the stack that they now have a
+    // nested saveLayer inside them
+    void updateStackForSaveLayer() {
+        for (int index = fSaveStack.count() - 1; index >= 0; --index) {
+            if (fSaveStack[index].fHasNestedSaveLayer) {
+                break;
+            }
+            fSaveStack[index].fHasNestedSaveLayer = true;
+            if (fSaveStack[index].fIsSaveLayer) {
+                break;
+            }
+        }
     }
 
-    void gather() {
-        if (NULL == fPicture || 0 == fPicture->width() || 0 == fPicture->height()) {
+    void pushSaveLayerBlock(const SkPaint* paint) {
+        this->updateStackForSaveLayer();
+
+        fSaveStack.push(SaveInfo(fCurrentOp, true, paint, fCurrentClipBounds));
+        ++fSaveLayersInStack;
+    }
+
+    void popSaveBlock() {
+        if (fSaveStack.count() <= 0) {
+            SkASSERT(false);
             return;
         }
 
-        this->clipRect(SkRect::MakeWH(SkIntToScalar(fPicture->width()),
-                                      SkIntToScalar(fPicture->height())),
-                       SkRegion::kIntersect_Op, false);
-        this->drawPicture(fPicture);
-    }
+        SaveInfo si;
+        fSaveStack.pop(&si);
 
-protected:
-    // disable aa for speed
-    virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
-        this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle);
-    }
-
-    // for speed, just respect the bounds, and disable AA. May give us a few
-    // false positives and negatives.
-    virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
-        this->updateClipConservativelyUsingBounds(path.getBounds(), op,
-                                                  path.isInverseFillType());
-    }
-    virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE {
-        this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false);
-    }
-
-    virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE {
-        // BBH-based rendering doesn't re-issue many of the operations the gather
-        // process cares about (e.g., saves and restores) so it must be disabled.
-        if (NULL != picture->fPlayback) {
-            picture->fPlayback->setUseBBH(false);
+        if (!si.fIsSaveLayer) {
+            return;
         }
-        picture->draw(this);
-        if (NULL != picture->fPlayback) {
-            picture->fPlayback->setUseBBH(true);
+
+        --fSaveLayersInStack;
+
+        GrAccelData::SaveLayerInfo& slInfo = fAccelData->addSaveLayerInfo();
+
+        slInfo.fValid = true;
+        SkASSERT(NULL == slInfo.fPicture);  // This layer is in the top-most picture
+        slInfo.fSize = SkISize::Make(si.fBounds.width(), si.fBounds.height());
+        slInfo.fOffset = SkIPoint::Make(si.fBounds.fLeft, si.fBounds.fTop);
+        slInfo.fOriginXform = *fCTM;
+        if (si.fPaint) {
+            slInfo.fPaint = SkNEW_ARGS(SkPaint, (*si.fPaint));
         }
+        slInfo.fSaveLayerOpID = si.fStartIndex;
+        slInfo.fRestoreOpID = fCurrentOp;
+        slInfo.fHasNestedLayers = si.fHasNestedSaveLayer;
+        slInfo.fIsNested = fSaveLayersInStack > 0;
     }
 
-private:
-    const SkPicture* fPicture;
+    // Returns true if rect was meaningfully adjusted for the effects of paint,
+    // false if the paint could affect the rect in unknown ways.
+    static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) {
+        if (paint) {
+            if (paint->canComputeFastBounds()) {
+                *rect = paint->computeFastBounds(*rect, rect);
+                return true;
+            }
+            return false;
+        }
+        return true;
+    }
 
-    typedef SkCanvas INHERITED;
+    // Adjust rect for all paints that may affect its geometry, then map it to device space.
+    SkIRect adjustAndMap(SkRect rect, const SkPaint* paint) const {
+        // Inverted rectangles really confuse our BBHs.
+        rect.sort();
+
+        // Adjust the rect for its own paint.
+        if (!AdjustForPaint(paint, &rect)) {
+            // The paint could do anything to our bounds.  The only safe answer is the current clip.
+            return fCurrentClipBounds;
+        }
+
+        // Adjust rect for all the paints from the SaveLayers we're inside.
+        for (int i = fSaveStack.count() - 1; i >= 0; i--) {
+            if (!AdjustForPaint(fSaveStack[i].fPaint, &rect)) {
+                // Same deal as above.
+                return fCurrentClipBounds;
+            }
+        }
+
+        // Map the rect back to device space.
+        fCTM->mapRect(&rect);
+        SkIRect devRect;
+        rect.roundOut(&devRect);
+
+        // Nothing can draw outside the current clip.
+        // (Only bounded ops call into this method, so oddballs like Clear don't matter here.)
+        devRect.intersect(fCurrentClipBounds);
+        return devRect;
+    }
 };
 
-// GatherGPUInfo is only intended to be called within the context of SkGpuDevice's
+
+// GPUOptimize is only intended to be called within the context of SkGpuDevice's
 // EXPERIMENTAL_optimize method.
-void GatherGPUInfo(const SkPicture* pict, GPUAccelData* accelData) {
-    if (0 == pict->width() || 0 == pict->height()) {
-        return ;
+const GrAccelData* GPUOptimize(const SkPicture* pict) {
+    if (NULL == pict || pict->cullRect().isEmpty()) {
+        return NULL;
     }
 
-    GrGatherDevice device(pict->width(), pict->height(), pict, accelData, 0);
-    GrGatherCanvas canvas(&device, pict);
+    SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey();
 
-    canvas.gather();
+    const GrAccelData* existing = 
+                            static_cast<const GrAccelData*>(pict->EXPERIMENTAL_getAccelData(key));
+    if (existing) {
+        return existing;
+    }
+
+    SkAutoTUnref<GrAccelData> data(SkNEW_ARGS(GrAccelData, (key)));
+
+    pict->EXPERIMENTAL_addAccelData(data);
+
+    CollectLayers collector(pict, data);
+
+    return data;
 }
diff --git a/src/gpu/GrPictureUtils.h b/src/gpu/GrPictureUtils.h
index a730697..f9bab80 100644
--- a/src/gpu/GrPictureUtils.h
+++ b/src/gpu/GrPictureUtils.h
@@ -9,28 +9,36 @@
 #define GrPictureUtils_DEFINED
 
 #include "SkPicture.h"
-#include "SkTDArray.h"
+#include "SkTArray.h"
 
 // This class encapsulates the GPU-backend-specific acceleration data
 // for a single SkPicture
-class GPUAccelData : public SkPicture::AccelData {
+class GrAccelData : public SkPicture::AccelData {
 public:
     // Information about a given saveLayer in an SkPicture
-    struct SaveLayerInfo {
-        // True if the SaveLayerInfo is valid. False if either 'fOffset' is
-        // invalid (due to a non-invertible CTM) or 'fPaint' is NULL (due
-        // to a non-copyable paint).
+    class SaveLayerInfo {
+    public:
+        SaveLayerInfo() : fPicture(NULL), fPaint(NULL) {}
+        ~SaveLayerInfo() { SkSafeUnref(fPicture); SkDELETE(fPaint); }
+
+        // True if the SaveLayerInfo is valid. False if 'fOffset' is
+        // invalid (due to a non-invertible CTM).
+        // TODO: remove fValid
         bool fValid;
+        // The picture owning the layer. If the owning picture is the top-most
+        // one (i.e., the picture for which this GrAccelData was created) then
+        // this pointer is NULL. If it is a nested picture then the pointer
+        // is non-NULL and owns a ref on the picture.
+        const SkPicture* fPicture;
         // The size of the saveLayer
         SkISize fSize;
-        // The CTM in which this layer's draws must occur. It already incorporates
-        // the translation needed to map the layer's top-left point to the origin.
-        SkMatrix fCTM;
+        // The matrix state in which this layer's draws must occur. It does not
+        // include the translation needed to map the layer's top-left point to the origin.
+        SkMatrix fOriginXform;
         // The offset that needs to be passed to drawBitmap to correctly
         // position the pre-rendered layer. It is in device space.
         SkIPoint fOffset;
-        // The paint to use on restore. NULL if the paint was not copyable (and
-        // thus that this layer should not be pulled forward).
+        // The paint to use on restore. Can be NULL since it is optional.
         const SkPaint* fPaint;
         // The ID of this saveLayer in the picture. 0 is an invalid ID.
         size_t  fSaveLayerOpID;
@@ -43,18 +51,11 @@
         bool    fIsNested;
     };
 
-    GPUAccelData(Key key) : INHERITED(key) { }
+    GrAccelData(Key key) : INHERITED(key) { }
 
-    virtual ~GPUAccelData() {
-        for (int i = 0; i < fSaveLayerInfo.count(); ++i) {
-            SkDELETE(fSaveLayerInfo[i].fPaint);
-        }
-    }
+    virtual ~GrAccelData() { }
 
-    void addSaveLayerInfo(const SaveLayerInfo& info) {
-        SkASSERT(info.fSaveLayerOpID < info.fRestoreOpID);
-        *fSaveLayerInfo.push() = info;
-    }
+    SaveLayerInfo& addSaveLayerInfo() { return fSaveLayerInfo.push_back(); }
 
     int numSaveLayers() const { return fSaveLayerInfo.count(); }
 
@@ -69,11 +70,11 @@
     static SkPicture::AccelData::Key ComputeAccelDataKey();
 
 private:
-    SkTDArray<SaveLayerInfo> fSaveLayerInfo;
+    SkTArray<SaveLayerInfo, true> fSaveLayerInfo;
 
     typedef SkPicture::AccelData INHERITED;
 };
 
-void GatherGPUInfo(const SkPicture* pict, GPUAccelData* accelData);
+const GrAccelData* GPUOptimize(const SkPicture* pict);
 
 #endif // GrPictureUtils_DEFINED
diff --git a/src/gpu/GrEffect.cpp b/src/gpu/GrProcessor.cpp
similarity index 60%
rename from src/gpu/GrEffect.cpp
rename to src/gpu/GrProcessor.cpp
index 986e80a..45298b5 100644
--- a/src/gpu/GrEffect.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -5,21 +5,14 @@
  * found in the LICENSE file.
  */
 
-#include "GrEffect.h"
-#include "GrBackendEffectFactory.h"
+#include "GrProcessor.h"
+#include "GrBackendProcessorFactory.h"
 #include "GrContext.h"
 #include "GrCoordTransform.h"
 #include "GrMemoryPool.h"
 #include "SkTLS.h"
 
-#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
-SkTArray<GrEffectTestFactory*, true>* GrEffectTestFactory::GetFactories() {
-    static SkTArray<GrEffectTestFactory*, true> gFactories;
-    return &gFactories;
-}
-#endif
-
-namespace GrEffectUnitTest {
+namespace GrProcessorUnitTest {
 const SkMatrix& TestMatrix(SkRandom* random) {
     static SkMatrix gMatrices[5];
     static bool gOnce;
@@ -39,7 +32,7 @@
 }
 }
 
-class GrEffect_Globals {
+class GrProcessor_Globals {
 public:
     static GrMemoryPool* GetTLS() {
         return (GrMemoryPool*)SkTLS::Get(CreateTLS, DeleteTLS);
@@ -55,53 +48,37 @@
     }
 };
 
-int32_t GrBackendEffectFactory::fCurrEffectClassID = GrBackendEffectFactory::kIllegalEffectClassID;
+int32_t GrBackendProcessorFactory::fCurrEffectClassID =
+        GrBackendProcessorFactory::kIllegalEffectClassID;
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrEffectRef::~GrEffectRef() {
-    SkASSERT(this->unique());
-    fEffect->EffectRefDestroyed();
-    fEffect->unref();
-}
+GrProcessor::~GrProcessor() {}
 
-void* GrEffectRef::operator new(size_t size) {
-    return GrEffect_Globals::GetTLS()->allocate(size);
-}
-
-void GrEffectRef::operator delete(void* target) {
-    GrEffect_Globals::GetTLS()->release(target);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-GrEffect::~GrEffect() {
-    SkASSERT(NULL == fEffectRef);
-}
-
-const char* GrEffect::name() const {
+const char* GrProcessor::name() const {
     return this->getFactory().name();
 }
 
-void GrEffect::addCoordTransform(const GrCoordTransform* transform) {
+void GrProcessor::addCoordTransform(const GrCoordTransform* transform) {
     fCoordTransforms.push_back(transform);
     SkDEBUGCODE(transform->setInEffect();)
 }
 
-void GrEffect::addTextureAccess(const GrTextureAccess* access) {
+void GrProcessor::addTextureAccess(const GrTextureAccess* access) {
     fTextureAccesses.push_back(access);
+    this->addGpuResource(access->getProgramTexture());
 }
 
-void* GrEffect::operator new(size_t size) {
-    return GrEffect_Globals::GetTLS()->allocate(size);
+void* GrProcessor::operator new(size_t size) {
+    return GrProcessor_Globals::GetTLS()->allocate(size);
 }
 
-void GrEffect::operator delete(void* target) {
-    GrEffect_Globals::GetTLS()->release(target);
+void GrProcessor::operator delete(void* target) {
+    GrProcessor_Globals::GetTLS()->release(target);
 }
 
 #ifdef SK_DEBUG
-void GrEffect::assertEquality(const GrEffect& other) const {
+void GrProcessor::assertEquality(const GrProcessor& other) const {
     SkASSERT(this->numTransforms() == other.numTransforms());
     for (int i = 0; i < this->numTransforms(); ++i) {
         SkASSERT(this->coordTransform(i) == other.coordTransform(i));
diff --git a/src/gpu/GrProgramElement.cpp b/src/gpu/GrProgramElement.cpp
new file mode 100644
index 0000000..2c3085f
--- /dev/null
+++ b/src/gpu/GrProgramElement.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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 "GrProgramElement.h"
+#include "GrGpuResourceRef.h"
+
+uint32_t GrProgramElement::CreateUniqueID() {
+    static int32_t gUniqueID = SK_InvalidUniqueID;
+    uint32_t id;
+    do {
+        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
+    } while (id == SK_InvalidUniqueID);
+    return id;
+}
+
+void GrProgramElement::convertRefToPendingExecution() const {
+    // This function makes it so that all the GrGpuResourceRefs own a single ref to their
+    // underlying GrGpuResource if there are any refs to the GrProgramElement and a single
+    // pending read/write if there are any pending executions of the GrProgramElement. The
+    // GrGpuResourceRef will give up its single ref and/or pending read/write in its destructor.
+    SkASSERT(fRefCnt > 0);
+    if (0 == fPendingExecutions) {
+        for (int i = 0; i < fGpuResources.count(); ++i) {
+            fGpuResources[i]->markPendingIO();
+        }
+    }
+    ++fPendingExecutions;
+    this->unref();
+    if (0 == fRefCnt) {
+        for (int i = 0; i < fGpuResources.count(); ++i) {
+            fGpuResources[i]->removeRef();
+        }
+    }
+}
+
+void GrProgramElement::completedExecution() const {
+    this->validate();
+    --fPendingExecutions;
+    if (0 == fPendingExecutions) {
+        if (0 == fRefCnt) {
+            SkDELETE(this);
+        } else {
+            // Now our pending executions have ocurred and we still have refs. Convert
+            // ownership of our resources back to regular refs.
+            for (int i = 0; i < fGpuResources.count(); ++i) {
+                fGpuResources[i]->pendingIOComplete();
+            }
+
+        }
+    }
+}
diff --git a/src/gpu/GrRODrawState.cpp b/src/gpu/GrRODrawState.cpp
new file mode 100644
index 0000000..2a673f3
--- /dev/null
+++ b/src/gpu/GrRODrawState.cpp
@@ -0,0 +1,350 @@
+/*
+ * 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 "GrRODrawState.h"
+
+#include "GrDrawTargetCaps.h"
+#include "GrRenderTarget.h"
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrRODrawState::GrRODrawState(const GrRODrawState& drawState) : INHERITED() {
+    fRenderTarget.setResource(SkSafeRef(drawState.fRenderTarget.getResource()),
+                              GrIORef::kWrite_IOType);
+}
+
+bool GrRODrawState::isEqual(const GrRODrawState& that) const {
+    bool usingVertexColors = this->hasColorVertexAttribute();
+    if (!usingVertexColors && this->fColor != that.fColor) {
+        return false;
+    }
+
+    if (this->getRenderTarget() != that.getRenderTarget() ||
+        this->fColorStages.count() != that.fColorStages.count() ||
+        this->fCoverageStages.count() != that.fCoverageStages.count() ||
+        !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
+        this->fSrcBlend != that.fSrcBlend ||
+        this->fDstBlend != that.fDstBlend ||
+        this->fBlendConstant != that.fBlendConstant ||
+        this->fFlagBits != that.fFlagBits ||
+        this->fVACount != that.fVACount ||
+        this->fVAStride != that.fVAStride ||
+        memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib)) ||
+        this->fStencilSettings != that.fStencilSettings ||
+        this->fDrawFace != that.fDrawFace) {
+        return false;
+    }
+
+    bool usingVertexCoverage = this->hasCoverageVertexAttribute();
+    if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
+        return false;
+    }
+
+    bool explicitLocalCoords = this->hasLocalCoordAttribute();
+    if (this->hasGeometryProcessor()) {
+        if (!that.hasGeometryProcessor()) {
+            return false;
+        } else if (!GrProcessorStage::AreCompatible(*this->getGeometryProcessor(),
+                                                    *that.getGeometryProcessor(),
+                                                    explicitLocalCoords)) {
+            return false;
+        }
+    } else if (that.hasGeometryProcessor()) {
+        return false;
+    }
+
+    for (int i = 0; i < this->numColorStages(); i++) {
+        if (!GrProcessorStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
+                                             explicitLocalCoords)) {
+            return false;
+        }
+    }
+    for (int i = 0; i < this->numCoverageStages(); i++) {
+        if (!GrProcessorStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
+                                             explicitLocalCoords)) {
+            return false;
+        }
+    }
+
+    SkASSERT(0 == memcmp(this->fFixedFunctionVertexAttribIndices,
+                            that.fFixedFunctionVertexAttribIndices,
+                            sizeof(this->fFixedFunctionVertexAttribIndices)));
+
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool GrRODrawState::validateVertexAttribs() const {
+    // check consistency of effects and attributes
+    GrSLType slTypes[kMaxVertexAttribCnt];
+    for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
+        slTypes[i] = static_cast<GrSLType>(-1);
+    }
+
+    if (this->hasGeometryProcessor()) {
+        const GrGeometryStage& stage = *this->getGeometryProcessor();
+        const GrGeometryProcessor* gp = stage.getGeometryProcessor();
+        SkASSERT(gp);
+        // make sure that any attribute indices have the correct binding type, that the attrib
+        // type and effect's shader lang type are compatible, and that attributes shared by
+        // multiple effects use the same shader lang type.
+        const GrGeometryProcessor::VertexAttribArray& s = gp->getVertexAttribs();
+
+        int effectIndex = 0;
+        for (int index = 0; index < fVACount; index++) {
+            if (kGeometryProcessor_GrVertexAttribBinding != fVAPtr[index].fBinding) {
+                // we only care about effect bindings
+                continue;
+            }
+            SkASSERT(effectIndex < s.count());
+            GrSLType effectSLType = s[effectIndex].getType();
+            GrVertexAttribType attribType = fVAPtr[index].fType;
+            int slVecCount = GrSLTypeVectorCount(effectSLType);
+            int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
+            if (slVecCount != attribVecCount ||
+                (static_cast<GrSLType>(-1) != slTypes[index] && slTypes[index] != effectSLType)) {
+                return false;
+            }
+            slTypes[index] = effectSLType;
+            effectIndex++;
+        }
+        // Make sure all attributes are consumed and we were able to find everything
+        SkASSERT(s.count() == effectIndex);
+    }
+
+    return true;
+}
+
+bool GrRODrawState::hasSolidCoverage() const {
+    // If we're drawing coverage directly then coverage is effectively treated as color.
+    if (this->isCoverageDrawing()) {
+        return true;
+    }
+
+    GrColor coverage;
+    uint32_t validComponentFlags;
+    // Initialize to an unknown starting coverage if per-vertex coverage is specified.
+    if (this->hasCoverageVertexAttribute()) {
+        validComponentFlags = 0;
+    } else {
+        coverage = fCoverage;
+        validComponentFlags = kRGBA_GrColorComponentFlags;
+    }
+
+    // Run through the coverage stages and see if the coverage will be all ones at the end.
+    if (this->hasGeometryProcessor()) {
+        const GrGeometryProcessor* gp = fGeometryProcessor->getGeometryProcessor();
+        gp->getConstantColorComponents(&coverage, &validComponentFlags);
+    }
+    for (int s = 0; s < this->numCoverageStages(); ++s) {
+        const GrProcessor* processor = this->getCoverageStage(s).getProcessor();
+        processor->getConstantColorComponents(&coverage, &validComponentFlags);
+    }
+    return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool GrRODrawState::willEffectReadDstColor() const {
+    if (!this->isColorWriteDisabled()) {
+        for (int s = 0; s < this->numColorStages(); ++s) {
+            if (this->getColorStage(s).getFragmentProcessor()->willReadDstColor()) {
+                return true;
+            }
+        }
+    }
+    for (int s = 0; s < this->numCoverageStages(); ++s) {
+        if (this->getCoverageStage(s).getFragmentProcessor()->willReadDstColor()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrRODrawState::BlendOptFlags GrRODrawState::getBlendOpts(bool forceCoverage,
+                                                         GrBlendCoeff* srcCoeff,
+                                                         GrBlendCoeff* dstCoeff) const {
+    GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
+    if (NULL == srcCoeff) {
+        srcCoeff = &bogusSrcCoeff;
+    }
+    if (NULL == dstCoeff) {
+        dstCoeff = &bogusDstCoeff;
+    }
+
+    *srcCoeff = this->getSrcBlendCoeff();
+    *dstCoeff = this->getDstBlendCoeff();
+
+    if (this->isColorWriteDisabled()) {
+        *srcCoeff = kZero_GrBlendCoeff;
+        *dstCoeff = kOne_GrBlendCoeff;
+    }
+
+    bool srcAIsOne = this->srcAlphaWillBeOne();
+    bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
+                         (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
+    bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
+                         (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
+
+    // When coeffs are (0,1) there is no reason to draw at all, unless
+    // stenciling is enabled. Having color writes disabled is effectively
+    // (0,1).
+    if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) {
+        if (this->getStencil().doesWrite()) {
+            return kEmitCoverage_BlendOptFlag;
+        } else {
+            *dstCoeff = kOne_GrBlendCoeff;
+            return kSkipDraw_BlendOptFlag;
+        }
+    }
+
+    bool hasCoverage = forceCoverage || !this->hasSolidCoverage();
+
+    // if we don't have coverage we can check whether the dst
+    // has to read at all. If not, we'll disable blending.
+    if (!hasCoverage) {
+        if (dstCoeffIsZero) {
+            if (kOne_GrBlendCoeff == *srcCoeff) {
+                // if there is no coverage and coeffs are (1,0) then we
+                // won't need to read the dst at all, it gets replaced by src
+                *dstCoeff = kZero_GrBlendCoeff;
+                return kNone_BlendOpt;
+            } else if (kZero_GrBlendCoeff == *srcCoeff) {
+                // if the op is "clear" then we don't need to emit a color
+                // or blend, just write transparent black into the dst.
+                *srcCoeff = kOne_GrBlendCoeff;
+                *dstCoeff = kZero_GrBlendCoeff;
+                return kEmitTransBlack_BlendOptFlag;
+            }
+        }
+    } else if (this->isCoverageDrawing()) {
+        // we have coverage but we aren't distinguishing it from alpha by request.
+        return kCoverageAsAlpha_BlendOptFlag;
+    } else {
+        // check whether coverage can be safely rolled into alpha
+        // of if we can skip color computation and just emit coverage
+        if (this->canTweakAlphaForCoverage()) {
+            return kCoverageAsAlpha_BlendOptFlag;
+        }
+        if (dstCoeffIsZero) {
+            if (kZero_GrBlendCoeff == *srcCoeff) {
+                // the source color is not included in the blend
+                // the dst coeff is effectively zero so blend works out to:
+                // (c)(0)D + (1-c)D = (1-c)D.
+                *dstCoeff = kISA_GrBlendCoeff;
+                return  kEmitCoverage_BlendOptFlag;
+            } else if (srcAIsOne) {
+                // the dst coeff is effectively zero so blend works out to:
+                // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
+                // If Sa is 1 then we can replace Sa with c
+                // and set dst coeff to 1-Sa.
+                *dstCoeff = kISA_GrBlendCoeff;
+                return  kCoverageAsAlpha_BlendOptFlag;
+            }
+        } else if (dstCoeffIsOne) {
+            // the dst coeff is effectively one so blend works out to:
+            // cS + (c)(1)D + (1-c)D = cS + D.
+            *dstCoeff = kOne_GrBlendCoeff;
+            return  kCoverageAsAlpha_BlendOptFlag;
+        }
+    }
+
+    return kNone_BlendOpt;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
+// others will blend incorrectly.
+bool GrRODrawState::canTweakAlphaForCoverage() const {
+    /*
+     The fractional coverage is f.
+     The src and dst coeffs are Cs and Cd.
+     The dst and src colors are S and D.
+     We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha
+     we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
+     term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we
+     find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
+     Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as
+     color by definition.
+     */
+    return kOne_GrBlendCoeff == fDstBlend ||
+           kISA_GrBlendCoeff == fDstBlend ||
+           kISC_GrBlendCoeff == fDstBlend ||
+           this->isCoverageDrawing();
+}
+
+void GrRODrawState::convertToPendingExec() {
+    fRenderTarget.markPendingIO();
+    fRenderTarget.removeRef();
+    for (int i = 0; i < fColorStages.count(); ++i) {
+        fColorStages[i].convertToPendingExec();
+    }
+    if (fGeometryProcessor) {
+        fGeometryProcessor->convertToPendingExec();
+    }
+    for (int i = 0; i < fCoverageStages.count(); ++i) {
+        fCoverageStages[i].convertToPendingExec();
+    }
+}
+
+bool GrRODrawState::srcAlphaWillBeOne() const {
+    uint32_t validComponentFlags;
+    GrColor color;
+    // Check if per-vertex or constant color may have partial alpha
+    if (this->hasColorVertexAttribute()) {
+        if (fHints & kVertexColorsAreOpaque_Hint) {
+            validComponentFlags = kA_GrColorComponentFlag;
+            color = 0xFF << GrColor_SHIFT_A;
+        } else {
+            validComponentFlags = 0;
+            color = 0; // not strictly necessary but we get false alarms from tools about uninit.
+        }
+    } else {
+        validComponentFlags = kRGBA_GrColorComponentFlags;
+        color = this->getColor();
+    }
+
+    // Run through the color stages
+    for (int s = 0; s < this->numColorStages(); ++s) {
+        const GrProcessor* processor = this->getColorStage(s).getProcessor();
+        processor->getConstantColorComponents(&color, &validComponentFlags);
+    }
+
+    // Check whether coverage is treated as color. If so we run through the coverage computation.
+    if (this->isCoverageDrawing()) {
+        // The shader generated for coverage drawing runs the full coverage computation and then
+        // makes the shader output be the multiplication of color and coverage. We mirror that here.
+        GrColor coverage;
+        uint32_t coverageComponentFlags;
+        if (this->hasCoverageVertexAttribute()) {
+            coverageComponentFlags = 0;
+            coverage = 0; // suppresses any warnings.
+        } else {
+            coverageComponentFlags = kRGBA_GrColorComponentFlags;
+            coverage = this->getCoverageColor();
+        }
+
+        // Run through the coverage stages
+        for (int s = 0; s < this->numCoverageStages(); ++s) {
+            const GrProcessor* processor = this->getCoverageStage(s).getProcessor();
+            processor->getConstantColorComponents(&coverage, &coverageComponentFlags);
+        }
+
+        // Since the shader will multiply coverage and color, the only way the final A==1 is if
+        // coverage and color both have A==1.
+        return (kA_GrColorComponentFlag & validComponentFlags & coverageComponentFlags) &&
+                0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage);
+
+    }
+
+    return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnpackA(color);
+}
+
diff --git a/src/gpu/GrRODrawState.h b/src/gpu/GrRODrawState.h
new file mode 100644
index 0000000..ac263ff
--- /dev/null
+++ b/src/gpu/GrRODrawState.h
@@ -0,0 +1,438 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrRODrawState_DEFINED
+#define GrRODrawState_DEFINED
+
+#include "GrProcessorStage.h"
+#include "GrRenderTarget.h"
+#include "GrStencil.h"
+#include "SkMatrix.h"
+
+class GrDrawState;
+class GrDrawTargetCaps;
+class GrPaint;
+class GrTexture;
+
+/**
+ * Read-only base class for GrDrawState. This class contains all the necessary data to represent a
+ * canonical DrawState. All methods in the class are const, thus once created the data in the class
+ * cannot be changed.
+ */
+class GrRODrawState : public SkRefCnt {
+public:
+    SK_DECLARE_INST_COUNT(GrRODrawState)
+
+    GrRODrawState() {}
+
+    GrRODrawState& operator= (const GrRODrawState& that);
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Vertex Attributes
+    ////
+
+    enum {
+        kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
+    };
+
+    const GrVertexAttrib* getVertexAttribs() const { return fVAPtr; }
+    int getVertexAttribCount() const { return fVACount; }
+
+    size_t getVertexStride() const { return fVAStride; }
+
+    /**
+     * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the
+     * binding does not appear in the current attribs. These bindings should appear only once in
+     * the attrib array.
+     */
+
+    int positionAttributeIndex() const {
+        return fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
+    }
+    int localCoordAttributeIndex() const {
+        return fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
+    }
+    int colorVertexAttributeIndex() const {
+        return fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
+    }
+    int coverageVertexAttributeIndex() const {
+        return fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
+    }
+
+    bool hasLocalCoordAttribute() const {
+        return -1 != fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
+    }
+    bool hasColorVertexAttribute() const {
+        return -1 != fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
+    }
+    bool hasCoverageVertexAttribute() const {
+        return -1 != fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
+    }
+
+    const int* getFixedFunctionVertexAttribIndices() const {
+        return fFixedFunctionVertexAttribIndices;
+    }
+
+    bool validateVertexAttribs() const;
+
+    /// @}
+
+    /**
+     * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
+     */
+    bool hasSolidCoverage() const;
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Color
+    ////
+
+    GrColor getColor() const { return fColor; }
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Coverage
+    ////
+
+    uint8_t getCoverage() const { return fCoverage; }
+
+    GrColor getCoverageColor() const {
+        return GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
+    }
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Effect Stages
+    /// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
+    /// fragment shader. Its inputs are the output from the previous stage as well as some variables
+    /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
+    /// the fragment position, local coordinates).
+    ///
+    /// The stages are divided into two sets, color-computing and coverage-computing. The final
+    /// color stage produces the final pixel color. The coverage-computing stages function exactly
+    /// as the color-computing but the output of the final coverage stage is treated as a fractional
+    /// pixel coverage rather than as input to the src/dst color blend step.
+    ///
+    /// The input color to the first color-stage is either the constant color or interpolated
+    /// per-vertex colors. The input to the first coverage stage is either a constant coverage
+    /// (usually full-coverage) or interpolated per-vertex coverage.
+    ///
+    /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
+    /// the color / coverage distinction.
+    ////
+
+    int numColorStages() const { return fColorStages.count(); }
+    int numCoverageStages() const { return fCoverageStages.count(); }
+    int numTotalStages() const {
+         return this->numColorStages() + this->numCoverageStages() +
+                 (this->hasGeometryProcessor() ? 1 : 0);
+    }
+
+    bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
+    const GrGeometryStage* getGeometryProcessor() const { return fGeometryProcessor.get(); }
+    const GrFragmentStage& getColorStage(int stageIdx) const { return fColorStages[stageIdx]; }
+    const GrFragmentStage& getCoverageStage(int stageIdx) const { return fCoverageStages[stageIdx]; }
+
+    /**
+     * Checks whether any of the effects will read the dst pixel color.
+     */
+    bool willEffectReadDstColor() const;
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Blending
+    ////
+
+    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
+    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
+
+    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
+                          GrBlendCoeff* dstBlendCoeff) const {
+        *srcBlendCoeff = fSrcBlend;
+        *dstBlendCoeff = fDstBlend;
+    }
+
+    /**
+     * Retrieves the last value set by setBlendConstant()
+     * @return the blending constant value
+     */
+    GrColor getBlendConstant() const { return fBlendConstant; }
+
+    /**
+     * Determines whether multiplying the computed per-pixel color by the pixel's fractional
+     * coverage before the blend will give the correct final destination color. In general it
+     * will not as coverage is applied after blending.
+     */
+    bool canTweakAlphaForCoverage() const;
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name View Matrix
+    ////
+
+    /**
+     * Retrieves the current view matrix
+     * @return the current view matrix.
+     */
+    const SkMatrix& getViewMatrix() const { return fViewMatrix; }
+
+    /**
+     *  Retrieves the inverse of the current view matrix.
+     *
+     *  If the current view matrix is invertible, return true, and if matrix
+     *  is non-null, copy the inverse into it. If the current view matrix is
+     *  non-invertible, return false and ignore the matrix parameter.
+     *
+     * @param matrix if not null, will receive a copy of the current inverse.
+     */
+    bool getViewInverse(SkMatrix* matrix) const {
+        // TODO: determine whether we really need to leave matrix unmodified
+        // at call sites when inversion fails.
+        SkMatrix inverse;
+        if (fViewMatrix.invert(&inverse)) {
+            if (matrix) {
+                *matrix = inverse;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Render Target
+    ////
+
+    /**
+     * Retrieves the currently set render-target.
+     *
+     * @return    The currently set render target.
+     */
+    GrRenderTarget* getRenderTarget() const {
+        return static_cast<GrRenderTarget*>(fRenderTarget.getResource());
+    }
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Stencil
+    ////
+
+    const GrStencilSettings& getStencil() const { return fStencilSettings; }
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name State Flags
+    ////
+
+    /**
+     *  Flags that affect rendering. Controlled using enable/disableState(). All
+     *  default to disabled.
+     */
+    enum StateBits {
+        /**
+         * Perform dithering. TODO: Re-evaluate whether we need this bit
+         */
+        kDither_StateBit        = 0x01,
+        /**
+         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
+         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
+         * the 3D API.
+         */
+        kHWAntialias_StateBit   = 0x02,
+        /**
+         * Draws will respect the clip, otherwise the clip is ignored.
+         */
+        kClip_StateBit          = 0x04,
+        /**
+         * Disables writing to the color buffer. Useful when performing stencil
+         * operations.
+         */
+        kNoColorWrites_StateBit = 0x08,
+
+        /**
+         * Usually coverage is applied after color blending. The color is blended using the coeffs
+         * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
+         * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
+         * this case there is no distinction between coverage and color and the caller needs direct
+         * control over the blend coeffs. When set, there will be a single blend step controlled by
+         * setBlendFunc() which will use coverage*color as the src color.
+         */
+         kCoverageDrawing_StateBit = 0x10,
+
+        // Users of the class may add additional bits to the vector
+        kDummyStateBit,
+        kLastPublicStateBit = kDummyStateBit-1,
+    };
+
+    uint32_t getFlagBits() const { return fFlagBits; }
+
+    bool isStateFlagEnabled(uint32_t stateBit) const { return 0 != (stateBit & fFlagBits); }
+
+    bool isDitherState() const { return 0 != (fFlagBits & kDither_StateBit); }
+    bool isHWAntialiasState() const { return 0 != (fFlagBits & kHWAntialias_StateBit); }
+    bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
+    bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
+    bool isCoverageDrawing() const { return 0 != (fFlagBits & kCoverageDrawing_StateBit); }
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Face Culling
+    ////
+
+    enum DrawFace {
+        kInvalid_DrawFace = -1,
+
+        kBoth_DrawFace,
+        kCCW_DrawFace,
+        kCW_DrawFace,
+    };
+
+    /**
+     * Gets whether the target is drawing clockwise, counterclockwise,
+     * or both faces.
+     * @return the current draw face(s).
+     */
+    DrawFace getDrawFace() const { return fDrawFace; }
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Hints
+    /// Hints that when provided can enable optimizations.
+    ////
+
+    enum Hints { kVertexColorsAreOpaque_Hint = 0x1, };
+
+    bool vertexColorsAreOpaque() const { return kVertexColorsAreOpaque_Hint & fHints; }
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    /** Return type for CombineIfPossible. */
+    enum CombinedState {
+        /** The GrDrawStates cannot be combined. */
+        kIncompatible_CombinedState,
+        /** Either draw state can be used in place of the other. */
+        kAOrB_CombinedState,
+        /** Use the first draw state. */
+        kA_CombinedState,
+        /** Use the second draw state. */
+        kB_CombinedState,
+    };
+
+protected:
+    /**
+     * Converts refs on GrGpuResources owned directly or indirectly by this GrRODrawState into
+     * pending reads and writes. This should be called when a GrDrawState is recorded into
+     * a GrDrawTarget for later execution. Subclasses of GrRODrawState may add setters. However,
+     * once this call has been made the GrRODrawState is immutable. It is also no longer copyable.
+     * In the future this conversion will automatically happen when converting a GrDrawState into
+     * an optimized draw state.
+     */
+    void convertToPendingExec();
+
+    friend class GrDrawTarget;
+
+    explicit GrRODrawState(const GrRODrawState& drawState);
+
+    bool isEqual(const GrRODrawState& that) const;
+
+    /**
+     * Optimizations for blending / coverage to that can be applied based on the current state.
+     */
+    enum BlendOptFlags {
+        /**
+         * No optimization
+         */
+        kNone_BlendOpt                  = 0,
+        /**
+         * Don't draw at all
+         */
+        kSkipDraw_BlendOptFlag          = 0x1,
+        /**
+         * The coverage value does not have to be computed separately from alpha, the the output
+         * color can be the modulation of the two.
+         */
+        kCoverageAsAlpha_BlendOptFlag   = 0x2,
+        /**
+         * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
+         * "don't cares".
+         */
+        kEmitCoverage_BlendOptFlag      = 0x4,
+        /**
+         * Emit transparent black instead of the src color, no need to compute coverage.
+         */
+        kEmitTransBlack_BlendOptFlag    = 0x8,
+    };
+    GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
+
+    /**
+     * Determines what optimizations can be applied based on the blend. The coefficients may have
+     * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
+     * params that receive the tweaked coefficients. Normally the function looks at the current
+     * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
+     * determine the blend optimizations that would be used if there was partial pixel coverage.
+     *
+     * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
+     * playback) must call this function and respect the flags that replace the output color.
+     *
+     * If the cached BlendOptFlags does not have the invalidate bit set, then getBlendOpts will
+     * simply returned the cached flags and coefficients. Otherwise it will calculate the values. 
+     */
+    BlendOptFlags getBlendOpts(bool forceCoverage = false,
+                               GrBlendCoeff* srcCoeff = NULL,
+                               GrBlendCoeff* dstCoeff = NULL) const;
+
+    typedef GrTGpuResourceRef<GrRenderTarget> ProgramRenderTarget;
+    // These fields are roughly sorted by decreasing likelihood of being different in op==
+    ProgramRenderTarget                 fRenderTarget;
+    GrColor                             fColor;
+    SkMatrix                            fViewMatrix;
+    GrColor                             fBlendConstant;
+    uint32_t                            fFlagBits;
+    const GrVertexAttrib*               fVAPtr;
+    int                                 fVACount;
+    size_t                              fVAStride;
+    GrStencilSettings                   fStencilSettings;
+    uint8_t                             fCoverage;
+    DrawFace                            fDrawFace;
+    GrBlendCoeff                        fSrcBlend;
+    GrBlendCoeff                        fDstBlend;
+
+    typedef SkSTArray<4, GrFragmentStage>   FragmentStageArray;
+    SkAutoTDelete<GrGeometryStage>          fGeometryProcessor;
+    FragmentStageArray                      fColorStages;
+    FragmentStageArray                      fCoverageStages;
+
+    uint32_t                            fHints;
+
+    // This is simply a different representation of info in fVertexAttribs and thus does
+    // not need to be compared in op==.
+    int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
+
+private:
+    /**
+     * Determines whether src alpha is guaranteed to be one for all src pixels
+     */
+    bool srcAlphaWillBeOne() const;
+
+    typedef SkRefCnt INHERITED;
+};
+
+GR_MAKE_BITFIELD_OPS(GrRODrawState::BlendOptFlags);
+
+#endif
diff --git a/src/gpu/GrRecordReplaceDraw.cpp b/src/gpu/GrRecordReplaceDraw.cpp
new file mode 100644
index 0000000..b0e00b8
--- /dev/null
+++ b/src/gpu/GrRecordReplaceDraw.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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 "GrRecordReplaceDraw.h"
+#include "SkImage.h"
+#include "SkRecordDraw.h"
+
+GrReplacements::ReplacementInfo* GrReplacements::push() {
+    SkDEBUGCODE(this->validate());
+    return fReplacements.push();
+}
+
+void GrReplacements::freeAll() {
+    for (int i = 0; i < fReplacements.count(); ++i) {
+        fReplacements[i].fImage->unref();
+        SkDELETE(fReplacements[i].fPaint);
+    }
+    fReplacements.reset();
+}
+
+#ifdef SK_DEBUG
+void GrReplacements::validate() const {
+    // Check that the ranges are monotonically increasing and non-overlapping
+    if (fReplacements.count() > 0) {
+        SkASSERT(fReplacements[0].fStart < fReplacements[0].fStop);
+
+        for (int i = 1; i < fReplacements.count(); ++i) {
+            SkASSERT(fReplacements[i].fStart < fReplacements[i].fStop);
+            SkASSERT(fReplacements[i - 1].fStop < fReplacements[i].fStart);
+        }
+    }
+}
+#endif
+
+const GrReplacements::ReplacementInfo*
+GrReplacements::lookupByStart(size_t start, int* searchStart) const {
+    SkDEBUGCODE(this->validate());
+    for (int i = *searchStart; i < fReplacements.count(); ++i) {
+        if (start == fReplacements[i].fStart) {
+            *searchStart = i + 1;
+            return &fReplacements[i];
+        } else if (start < fReplacements[i].fStart) {
+            return NULL;  // the ranges are monotonically increasing and non-overlapping
+        }
+    }
+
+    return NULL;
+}
+
+static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo* ri,
+                                           SkCanvas* canvas,
+                                           const SkMatrix& initialMatrix) {
+    SkRect src = SkRect::Make(ri->fSrcRect);
+    SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
+                                  SkIntToScalar(ri->fPos.fY),
+                                  SkIntToScalar(ri->fSrcRect.width()),
+                                  SkIntToScalar(ri->fSrcRect.height()));
+
+    canvas->save();
+    canvas->setMatrix(initialMatrix);
+    canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint);
+    canvas->restore();
+}
+
+void GrRecordReplaceDraw(const SkRecord& record,
+                         SkCanvas* canvas,
+                         const SkBBoxHierarchy* bbh,
+                         const GrReplacements* replacements,
+                         SkDrawPictureCallback* callback) {
+    SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
+
+    SkRecords::Draw draw(canvas);
+    const GrReplacements::ReplacementInfo* ri = NULL;
+    int searchStart = 0;
+
+    const SkMatrix initialMatrix = canvas->getTotalMatrix();
+
+    if (bbh) {
+        // Draw only ops that affect pixels in the canvas's current clip.
+        // The SkRecord and BBH were recorded in identity space.  This canvas
+        // is not necessarily in that same space.  getClipBounds() returns us
+        // this canvas' clip bounds transformed back into identity space, which
+        // lets us query the BBH.
+        SkRect query = { 0, 0, 0, 0 };
+        (void)canvas->getClipBounds(&query);
+
+        SkTDArray<void*> ops;
+        bbh->search(query, &ops);
+
+        for (int i = 0; i < ops.count(); i++) {
+            if (callback && callback->abortDrawing()) {
+                return;
+            }
+            ri = replacements->lookupByStart((uintptr_t)ops[i], &searchStart);
+            if (ri) {
+                draw_replacement_bitmap(ri, canvas, initialMatrix);
+
+                while ((uintptr_t)ops[i] < ri->fStop) {
+                    ++i;
+                }
+                SkASSERT((uintptr_t)ops[i] == ri->fStop);
+                continue;
+            }
+
+            record.visit<void>((uintptr_t)ops[i], draw);
+        }
+    } else {
+        for (unsigned int i = 0; i < record.count(); ++i) {
+            if (callback && callback->abortDrawing()) {
+                return;
+            }
+            ri = replacements->lookupByStart(i, &searchStart);
+            if (ri) {
+                draw_replacement_bitmap(ri, canvas, initialMatrix);
+                i = ri->fStop;
+                continue;
+            }
+
+            record.visit<void>(i, draw);
+        }
+    }
+}
diff --git a/src/gpu/GrRecordReplaceDraw.h b/src/gpu/GrRecordReplaceDraw.h
new file mode 100644
index 0000000..3ba43dc
--- /dev/null
+++ b/src/gpu/GrRecordReplaceDraw.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrRecordReplaceDraw_DEFINED
+#define GrRecordReplaceDraw_DEFINED
+
+#include "SkDrawPictureCallback.h"
+#include "SkRect.h"
+#include "SkTDArray.h"
+
+class SkBBoxHierarchy;
+class SkBitmap;
+class SkCanvas;
+class SkImage;
+class SkPaint;
+class SkRecord;
+
+// GrReplacements collects op ranges that can be replaced with
+// a single drawBitmap call (using a precomputed bitmap).
+class GrReplacements {
+public:
+    // All the operations between fStart and fStop (inclusive) will be replaced with
+    // a single drawBitmap call using fPos, fBM and fPaint.
+    struct ReplacementInfo {
+        unsigned        fStart;
+        unsigned        fStop;
+        SkIPoint        fPos;
+        SkImage*        fImage;  // Owns a ref
+        const SkPaint*  fPaint;  // Owned by this object
+
+        SkIRect         fSrcRect;
+    };
+
+    ~GrReplacements() { this->freeAll(); }
+
+    // Add a new replacement range. The replacement ranges should be
+    // sorted in increasing order and non-overlapping (esp. no nested
+    // saveLayers).
+    ReplacementInfo* push();
+
+    // look up a replacement range by its start offset.
+    // lastLookedUp is an in/out parameter that is used to speed up the search.
+    // It should be initialized to 0 on the first call and then passed back in
+    // unmodified on subsequent calls.
+    const ReplacementInfo* lookupByStart(size_t start, int* lastLookedUp) const;
+
+private:
+    SkTDArray<ReplacementInfo> fReplacements;
+
+    void freeAll();
+
+#ifdef SK_DEBUG
+    void validate() const;
+#endif
+};
+
+// Draw an SkRecord into an SkCanvas replacing saveLayer/restore blocks with
+// drawBitmap calls.  A convenience wrapper around SkRecords::Draw.
+void GrRecordReplaceDraw(const SkRecord&, 
+                         SkCanvas*,
+                         const SkBBoxHierarchy*,
+                         const GrReplacements*,
+                         SkDrawPictureCallback*);
+
+#endif // GrRecordReplaceDraw_DEFINED
diff --git a/src/gpu/GrRedBlackTree.h b/src/gpu/GrRedBlackTree.h
index d9b1a04..c58ae27 100644
--- a/src/gpu/GrRedBlackTree.h
+++ b/src/gpu/GrRedBlackTree.h
@@ -204,7 +204,7 @@
     }
     Iter& operator --() {
         SkASSERT(*this != fTree->begin());
-        if (NULL != fN) {
+        if (fN) {
             fN = PredecessorNode(fN);
         } else {
             *this = fTree->last();
@@ -254,7 +254,7 @@
 template <typename T, typename C>
 typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::find(const T& t) {
     Node* n = fRoot;
-    while (NULL != n) {
+    while (n) {
         if (fComp(t, n->fItem)) {
             n = n->fChildren[kLeft_Child];
         } else {
@@ -271,7 +271,7 @@
 typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::findFirst(const T& t) {
     Node* n = fRoot;
     Node* leftMost = NULL;
-    while (NULL != n) {
+    while (n) {
         if (fComp(t, n->fItem)) {
             n = n->fChildren[kLeft_Child];
         } else {
@@ -291,7 +291,7 @@
 typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::findLast(const T& t) {
     Node* n = fRoot;
     Node* rightMost = NULL;
-    while (NULL != n) {
+    while (n) {
         if (fComp(t, n->fItem)) {
             n = n->fChildren[kLeft_Child];
         } else {
@@ -313,7 +313,7 @@
 template <typename T, typename C>
 int GrRedBlackTree<T,C>::onCountOf(const Node* n, const T& t) const {
     // this is count*log(n) :(
-    while (NULL != n) {
+    while (n) {
         if (fComp(t, n->fItem)) {
             n = n->fChildren[kLeft_Child];
         } else {
@@ -360,7 +360,7 @@
 
     bool first = true;
     bool last = true;
-    while (NULL != n) {
+    while (n) {
         gpc = pc;
         pc = fComp(x->fItem, n->fItem) ? kLeft_Child : kRight_Child;
         first = first && kLeft_Child == pc;
@@ -389,10 +389,10 @@
 
     do {
         // assumptions at loop start.
-        SkASSERT(NULL != x);
+        SkASSERT(x);
         SkASSERT(kRed_Color == x->fColor);
         // can't have a grandparent but no parent.
-        SkASSERT(!(NULL != gp && NULL == p));
+        SkASSERT(!(gp && NULL == p));
         // make sure pc and gpc are correct
         SkASSERT(NULL == p  || p->fChildren[pc] == x);
         SkASSERT(NULL == gp || gp->fChildren[gpc] == p);
@@ -403,7 +403,7 @@
             return Iter(returnNode, this);
         }
         // gp must be valid because if p was the root then it is black
-        SkASSERT(NULL != gp);
+        SkASSERT(gp);
         // gp must be black since it's child, p, is red.
         SkASSERT(kBlack_Color == gp->fColor);
 
@@ -413,7 +413,7 @@
         // if x's uncle (p's sibling) is also red then we can flip
         // p and u to black and make gp red. But then we have to recurse
         // up to gp since it's parent may also be red.
-        if (NULL != u && kRed_Color == u->fColor) {
+        if (u && kRed_Color == u->fColor) {
             p->fColor = kBlack_Color;
             u->fColor = kBlack_Color;
             gp->fColor = kRed_Color;
@@ -429,7 +429,7 @@
             gp = p->fParent;
             pc = (p->fChildren[kLeft_Child] == x) ? kLeft_Child :
                                                     kRight_Child;
-            if (NULL != gp) {
+            if (gp) {
                 gpc = (gp->fChildren[kLeft_Child] == p) ? kLeft_Child :
                                                           kRight_Child;
             }
@@ -493,10 +493,10 @@
      */
     Node* d = n->fParent;
     Node* s = n->fChildren[kLeft_Child];
-    SkASSERT(NULL != s);
+    SkASSERT(s);
     Node* b = s->fChildren[kRight_Child];
 
-    if (NULL != d) {
+    if (d) {
         Child c = d->fChildren[kLeft_Child] == n ? kLeft_Child :
                                              kRight_Child;
         d->fChildren[c] = s;
@@ -508,7 +508,7 @@
     s->fChildren[kRight_Child] = n;
     n->fParent = s;
     n->fChildren[kLeft_Child] = b;
-    if (NULL != b) {
+    if (b) {
         b->fParent = n;
     }
 
@@ -525,10 +525,10 @@
 
     Node* d = n->fParent;
     Node* s = n->fChildren[kRight_Child];
-    SkASSERT(NULL != s);
+    SkASSERT(s);
     Node* b = s->fChildren[kLeft_Child];
 
-    if (NULL != d) {
+    if (d) {
         Child c = d->fChildren[kRight_Child] == n ? kRight_Child :
                                                    kLeft_Child;
         d->fChildren[c] = s;
@@ -540,7 +540,7 @@
     s->fChildren[kLeft_Child] = n;
     n->fParent = s;
     n->fChildren[kRight_Child] = b;
-    if (NULL != b) {
+    if (b) {
         b->fParent = n;
     }
 
@@ -554,15 +554,15 @@
 
 template <typename T, typename C>
 typename GrRedBlackTree<T,C>::Node* GrRedBlackTree<T,C>::SuccessorNode(Node* x) {
-    SkASSERT(NULL != x);
-    if (NULL != x->fChildren[kRight_Child]) {
+    SkASSERT(x);
+    if (x->fChildren[kRight_Child]) {
         x = x->fChildren[kRight_Child];
-        while (NULL != x->fChildren[kLeft_Child]) {
+        while (x->fChildren[kLeft_Child]) {
             x = x->fChildren[kLeft_Child];
         }
         return x;
     }
-    while (NULL != x->fParent && x == x->fParent->fChildren[kRight_Child]) {
+    while (x->fParent && x == x->fParent->fChildren[kRight_Child]) {
         x = x->fParent;
     }
     return x->fParent;
@@ -570,15 +570,15 @@
 
 template <typename T, typename C>
 typename GrRedBlackTree<T,C>::Node* GrRedBlackTree<T,C>::PredecessorNode(Node* x) {
-    SkASSERT(NULL != x);
-    if (NULL != x->fChildren[kLeft_Child]) {
+    SkASSERT(x);
+    if (x->fChildren[kLeft_Child]) {
         x = x->fChildren[kLeft_Child];
-        while (NULL != x->fChildren[kRight_Child]) {
+        while (x->fChildren[kRight_Child]) {
             x = x->fChildren[kRight_Child];
         }
         return x;
     }
-    while (NULL != x->fParent && x == x->fParent->fChildren[kLeft_Child]) {
+    while (x->fParent && x == x->fParent->fChildren[kLeft_Child]) {
         x = x->fParent;
     }
     return x->fParent;
@@ -586,12 +586,12 @@
 
 template <typename T, typename C>
 void GrRedBlackTree<T,C>::deleteAtNode(Node* x) {
-    SkASSERT(NULL != x);
+    SkASSERT(x);
     validate();
     --fCount;
 
-    bool hasLeft =  NULL != x->fChildren[kLeft_Child];
-    bool hasRight = NULL != x->fChildren[kRight_Child];
+    bool hasLeft =  SkToBool(x->fChildren[kLeft_Child]);
+    bool hasRight = SkToBool(x->fChildren[kRight_Child]);
     Child c = hasLeft ? kLeft_Child : kRight_Child;
 
     if (hasLeft && hasRight) {
@@ -601,10 +601,10 @@
         // if x is an interior node then we find it's successor
         // and swap them.
         Node* s = x->fChildren[kRight_Child];
-        while (NULL != s->fChildren[kLeft_Child]) {
+        while (s->fChildren[kLeft_Child]) {
             s = s->fChildren[kLeft_Child];
         }
-        SkASSERT(NULL != s);
+        SkASSERT(s);
         // this might be expensive relative to swapping node ptrs around.
         // depends on T.
         x->fItem = s->fItem;
@@ -615,7 +615,7 @@
         // the new root (if the tree is not empty) black.
         SkASSERT(fRoot == x);
         fRoot = x->fChildren[c];
-        if (NULL != fRoot) {
+        if (fRoot) {
             fRoot->fParent = NULL;
             fRoot->fColor = kBlack_Color;
             if (x == fLast) {
@@ -665,7 +665,7 @@
         //s cannot be an implicit black node because the original
         // black-height at x was >= 2 and s's black-height must equal the
         // initial black height of x.
-        SkASSERT(NULL != s);
+        SkASSERT(s);
         SkASSERT(p == s->fParent);
 
         // assigned in loop
@@ -682,7 +682,7 @@
             // be real nodes.
             // The x side of p has a black-height that is one less than the
             // s side. It must be rebalanced.
-            SkASSERT(NULL != s);
+            SkASSERT(s);
             SkASSERT(p == s->fParent);
             SkASSERT(NULL == x || x->fParent == p);
 
@@ -697,8 +697,8 @@
                 SkASSERT(kBlack_Color == p->fColor);
                 // s's children must also be black since s is red. They can't
                 // be implicit since s is red and it's black-height is >= 2.
-                SkASSERT(NULL != sl && kBlack_Color == sl->fColor);
-                SkASSERT(NULL != sr && kBlack_Color == sr->fColor);
+                SkASSERT(sl && kBlack_Color == sl->fColor);
+                SkASSERT(sr && kBlack_Color == sr->fColor);
                 p->fColor = kRed_Color;
                 s->fColor = kBlack_Color;
                 if (kLeft_Child == pc) {
@@ -718,8 +718,8 @@
             SkASSERT(NULL == x || p == x->fParent);
 
             // when x is deleted its subtree will have reduced black-height.
-            slRed = (NULL != sl && kRed_Color == sl->fColor);
-            srRed = (NULL != sr && kRed_Color == sr->fColor);
+            slRed = (sl && kRed_Color == sl->fColor);
+            srRed = (sr && kRed_Color == sr->fColor);
             if (!slRed && !srRed) {
                 // if s can be made red that will balance out x's removal
                 // to make both subtrees of p have the same black-height.
@@ -744,7 +744,7 @@
 
                     }
                     s = p->fChildren[1-pc];
-                    SkASSERT(NULL != s);
+                    SkASSERT(s);
                     SkASSERT(p == s->fParent);
                     continue;
                 } else if (kRed_Color == p->fColor) {
@@ -789,11 +789,11 @@
         s->fColor = p->fColor;
         p->fColor = kBlack_Color;
         if (kLeft_Child == pc) {
-            SkASSERT(NULL != sr && kRed_Color == sr->fColor);
+            SkASSERT(sr && kRed_Color == sr->fColor);
             sr->fColor = kBlack_Color;
             rotateLeft(p);
         } else {
-            SkASSERT(NULL != sl && kRed_Color == sl->fColor);
+            SkASSERT(sl && kRed_Color == sl->fColor);
             sl->fColor = kBlack_Color;
             rotateRight(p);
         }
@@ -815,14 +815,14 @@
         if (x == fFirst) {
             SkASSERT(c == kRight_Child);
             fFirst = c1;
-            while (NULL != fFirst->fChildren[kLeft_Child]) {
+            while (fFirst->fChildren[kLeft_Child]) {
                 fFirst = fFirst->fChildren[kLeft_Child];
             }
             SkASSERT(fFirst == SuccessorNode(x));
         } else if (x == fLast) {
             SkASSERT(c == kLeft_Child);
             fLast = c1;
-            while (NULL != fLast->fChildren[kRight_Child]) {
+            while (fLast->fChildren[kRight_Child]) {
                 fLast = fLast->fChildren[kRight_Child];
             }
             SkASSERT(fLast == PredecessorNode(x));
@@ -838,7 +838,7 @@
 
 template <typename T, typename C>
 void GrRedBlackTree<T,C>::RecursiveDelete(Node* x) {
-    if (NULL != x) {
+    if (x) {
         RecursiveDelete(x->fChildren[kLeft_Child]);
         RecursiveDelete(x->fChildren[kRight_Child]);
         delete x;
@@ -850,8 +850,8 @@
 void GrRedBlackTree<T,C>::validate() const {
     if (fCount) {
         SkASSERT(NULL == fRoot->fParent);
-        SkASSERT(NULL != fFirst);
-        SkASSERT(NULL != fLast);
+        SkASSERT(fFirst);
+        SkASSERT(fLast);
 
         SkASSERT(kBlack_Color == fRoot->fColor);
         if (1 == fCount) {
@@ -874,7 +874,7 @@
 
 template <typename T, typename C>
 int GrRedBlackTree<T,C>::checkNode(Node* n, int* bh) const {
-    if (NULL != n) {
+    if (n) {
         SkASSERT(validateChildRelations(n, false));
         if (kBlack_Color == n->fColor) {
             *bh += 1;
@@ -895,21 +895,21 @@
 template <typename T, typename C>
 bool GrRedBlackTree<T,C>::validateChildRelations(const Node* n,
                                                  bool allowRedRed) const {
-    if (NULL != n) {
-        if (NULL != n->fChildren[kLeft_Child] ||
-            NULL != n->fChildren[kRight_Child]) {
+    if (n) {
+        if (n->fChildren[kLeft_Child] ||
+            n->fChildren[kRight_Child]) {
             if (n->fChildren[kLeft_Child] == n->fChildren[kRight_Child]) {
                 return validateChildRelationsFailed();
             }
             if (n->fChildren[kLeft_Child] == n->fParent &&
-                NULL != n->fParent) {
+                n->fParent) {
                 return validateChildRelationsFailed();
             }
             if (n->fChildren[kRight_Child] == n->fParent &&
-                NULL != n->fParent) {
+                n->fParent) {
                 return validateChildRelationsFailed();
             }
-            if (NULL != n->fChildren[kLeft_Child]) {
+            if (n->fChildren[kLeft_Child]) {
                 if (!allowRedRed &&
                     kRed_Color == n->fChildren[kLeft_Child]->fColor &&
                     kRed_Color == n->fColor) {
@@ -924,7 +924,7 @@
                     return validateChildRelationsFailed();
                 }
             }
-            if (NULL != n->fChildren[kRight_Child]) {
+            if (n->fChildren[kRight_Child]) {
                 if (!allowRedRed &&
                     kRed_Color == n->fChildren[kRight_Child]->fColor &&
                     kRed_Color == n->fColor) {
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 6ad9cc6..2083af9 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -65,21 +65,21 @@
         SkRect isectRect;
         if (stackBounds.contains(scalarQueryBounds)) {
             *initialState = kAllIn_InitialState;
-            if (NULL != tighterBounds) {
+            if (tighterBounds) {
                 *tighterBounds = queryBounds;
             }
-            if (NULL != requiresAA) {
+            if (requiresAA) {
                *requiresAA = false;
             }
         } else if (isectRect.intersect(stackBounds, scalarQueryBounds)) {
             // If the caller asked for tighter integer bounds we may be able to
             // return kAllIn and give the bounds with no elements
-            if (NULL != tighterBounds) {
+            if (tighterBounds) {
                 isectRect.roundOut(tighterBounds);
                 SkRect scalarTighterBounds = SkRect::Make(*tighterBounds);
                 if (scalarTighterBounds == isectRect) {
                     // the round-out didn't add any area outside the clip rect.
-                    if (NULL != requiresAA) {
+                    if (requiresAA) {
                         *requiresAA = false;
                     }
                     *initialState = kAllIn_InitialState;
@@ -91,12 +91,12 @@
             SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart);
             bool doAA = iter.prev()->isAA();
             SkNEW_INSERT_AT_LLIST_HEAD(result, Element, (isectRect, SkRegion::kReplace_Op, doAA));
-            if (NULL != requiresAA) {
+            if (requiresAA) {
                 *requiresAA = doAA;
             }
         } else {
             *initialState = kAllOut_InitialState;
-             if (NULL != requiresAA) {
+             if (requiresAA) {
                 *requiresAA = false;
              }
         }
@@ -105,12 +105,12 @@
         if (SkClipStack::kNormal_BoundsType == stackBoundsType) {
             if (!SkRect::Intersects(stackBounds, scalarQueryBounds)) {
                 *initialState = kAllOut_InitialState;
-                if (NULL != requiresAA) {
+                if (requiresAA) {
                    *requiresAA = false;
                 }
                 return;
             }
-            if (NULL != tighterBounds) {
+            if (tighterBounds) {
                 SkIRect stackIBounds;
                 stackBounds.roundOut(&stackIBounds);
                 tighterBounds->intersect(queryBounds, stackIBounds);
@@ -119,12 +119,12 @@
         } else {
             if (stackBounds.contains(scalarQueryBounds)) {
                 *initialState = kAllOut_InitialState;
-                if (NULL != requiresAA) {
+                if (requiresAA) {
                    *requiresAA = false;
                 }
                 return;
             }
-            if (NULL != tighterBounds) {
+            if (tighterBounds) {
                 *tighterBounds = queryBounds;
             }
         }
@@ -367,7 +367,7 @@
         result->reset();
     } else {
         Element* element = result->headIter().get();
-        while (NULL != element) {
+        while (element) {
             bool skippable = false;
             switch (element->getOp()) {
                 case SkRegion::kDifference_Op:
@@ -435,7 +435,7 @@
             }
         }
     }
-    if (NULL != requiresAA) {
+    if (requiresAA) {
         *requiresAA = numAAElements > 0;
     }
 
diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h
index cbb0346..e3a28cc 100644
--- a/src/gpu/GrReducedClip.h
+++ b/src/gpu/GrReducedClip.h
@@ -6,6 +6,9 @@
  * found in the LICENSE file.
  */
 
+#ifndef GrReducedClip_DEFINED
+#define GrReducedClip_DEFINED
+
 #include "SkClipStack.h"
 #include "SkTLList.h"
 
@@ -41,3 +44,5 @@
                             bool* requiresAA = NULL);
 
 } // namespace GrReducedClip
+
+#endif
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index 13fc229..b976332 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -68,7 +68,7 @@
     if (kUnknown_GrPixelConfig == fDesc.fConfig) {
         colorBits = 32; // don't know, make a guess
     } else {
-        colorBits = GrBytesPerPixel(fDesc.fConfig);
+        colorBits = GrBytesPerPixel(fDesc.fConfig) * 8;
     }
     uint64_t size = fDesc.fWidth;
     size *= fDesc.fHeight;
@@ -79,7 +79,7 @@
 
 void GrRenderTarget::flagAsNeedingResolve(const SkIRect* rect) {
     if (kCanResolve_ResolveType == getResolveType()) {
-        if (NULL != rect) {
+        if (rect) {
             fResolveRect.join(*rect);
             if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
                 fResolveRect.setEmpty();
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index 529c3a5..e9be509 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -9,13 +9,13 @@
 
 
 #include "GrResourceCache.h"
-#include "GrCacheable.h"
+#include "GrGpuResource.h"
 
 DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage);
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrCacheable::didChangeGpuMemorySize() const {
+void GrGpuResource::didChangeGpuMemorySize() const {
     if (this->isInCache()) {
         fCacheEntry->didChangeResourceSize();
     }
@@ -38,7 +38,7 @@
 
 GrResourceCacheEntry::GrResourceCacheEntry(GrResourceCache* resourceCache,
                                            const GrResourceKey& key,
-                                           GrCacheable* resource)
+                                           GrGpuResource* resource)
         : fResourceCache(resourceCache),
           fKey(key),
           fResource(resource),
@@ -117,10 +117,10 @@
 }
 
 void GrResourceCache::getLimits(int* maxResources, size_t* maxResourceBytes) const{
-    if (NULL != maxResources) {
+    if (maxResources) {
         *maxResources = fMaxCount;
     }
-    if (NULL != maxResourceBytes) {
+    if (maxResourceBytes) {
         *maxResourceBytes = fMaxBytes;
     }
 }
@@ -197,7 +197,7 @@
     }
 };
 
-GrCacheable* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershipFlags) {
+GrGpuResource* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershipFlags) {
     GrAutoResourceCacheValidate atcv(this);
 
     GrResourceCacheEntry* entry = NULL;
@@ -226,7 +226,7 @@
 }
 
 void GrResourceCache::addResource(const GrResourceKey& key,
-                                  GrCacheable* resource,
+                                  GrGpuResource* resource,
                                   uint32_t ownershipFlags) {
     SkASSERT(NULL == resource->getCacheEntry());
     // we don't expect to create new resources during a purge. In theory
@@ -267,7 +267,7 @@
 void GrResourceCache::removeInvalidResource(GrResourceCacheEntry* entry) {
     // If the resource went invalid while it was detached then purge it
     // This can happen when a 3D context was lost,
-    // the client called GrContext::contextDestroyed() to notify Gr,
+    // the client called GrContext::abandonContext() to notify Gr,
     // and then later an SkGpuDevice's destructor releases its backing
     // texture (which was invalidated at contextDestroyed time).
     // TODO: Safely delete the GrResourceCacheEntry as well.
@@ -285,7 +285,7 @@
     fExclusiveList.remove(entry);
 #endif
 
-    if (entry->resource()->isValidOnGpu()) {
+    if (!entry->resource()->wasDestroyed()) {
         // Since scratch textures still count against the cache budget even
         // when they have been removed from the cache, re-adding them doesn't
         // alter the budget information.
@@ -343,7 +343,7 @@
     this->internalPurge(extraCount, extraBytes);
     if (((fEntryCount+extraCount) > fMaxCount ||
         (fEntryBytes+extraBytes) > fMaxBytes) &&
-        NULL != fOverbudgetCB) {
+        fOverbudgetCB) {
         // Despite the purge we're still over budget. See if Ganesh can
         // release some resources and purge again.
         if ((*fOverbudgetCB)(fOverbudgetData)) {
@@ -373,7 +373,7 @@
 }
 
 void GrResourceCache::deleteResource(GrResourceCacheEntry* entry) {
-    SkASSERT(1 == entry->fResource->getRefCnt());
+    SkASSERT(entry->fResource->unique());
 
     // remove from our cache
     fCache.remove(entry->key(), entry);
@@ -402,7 +402,7 @@
         // in internalDetach)
         GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart);
 
-        while (NULL != entry) {
+        while (entry) {
             GrAutoResourceCacheValidate atcv(this);
 
             if ((fEntryCount+extraCount) <= fMaxCount &&
@@ -462,7 +462,7 @@
     const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(list),
                                                   EntryList::Iter::kTail_IterStart);
 
-    for ( ; NULL != entry; entry = iter.prev()) {
+    for ( ; entry; entry = iter.prev()) {
         bytes += entry->resource()->gpuMemorySize();
     }
     return bytes;
@@ -487,7 +487,7 @@
     const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fExclusiveList),
                                                   EntryList::Iter::kHead_IterStart);
 
-    for ( ; NULL != entry; entry = iter.next()) {
+    for ( ; entry; entry = iter.next()) {
         entry->validate();
     }
 
@@ -495,7 +495,7 @@
     entry = iter.init(const_cast<EntryList&>(fList), EntryList::Iter::kHead_IterStart);
 
     int count = 0;
-    for ( ; NULL != entry; entry = iter.next()) {
+    for ( ; entry; entry = iter.next()) {
         entry->validate();
         SkASSERT(fCache.find(entry->key()));
         count += 1;
@@ -523,7 +523,7 @@
 
     GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart);
 
-    for ( ; NULL != entry; entry = iter.prev()) {
+    for ( ; entry; entry = iter.prev()) {
         if (entry->fResource->getRefCnt() > 1) {
             ++locked;
         }
diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h
index 1a81fe6..8333780 100644
--- a/src/gpu/GrResourceCache.h
+++ b/src/gpu/GrResourceCache.h
@@ -11,103 +11,15 @@
 #ifndef GrResourceCache_DEFINED
 #define GrResourceCache_DEFINED
 
-#include "GrConfig.h"
-#include "GrTypes.h"
-#include "GrTMultiMap.h"
-#include "GrBinHashKey.h"
+#include "GrResourceKey.h"
+#include "SkTMultiMap.h"
 #include "SkMessageBus.h"
 #include "SkTInternalLList.h"
 
-class GrCacheable;
+class GrGpuResource;
 class GrResourceCache;
 class GrResourceCacheEntry;
 
-class GrResourceKey {
-public:
-    static GrCacheID::Domain ScratchDomain() {
-        static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain();
-        return gDomain;
-    }
-
-    /** Uniquely identifies the GrCacheable subclass in the key to avoid collisions
-        across resource types. */
-    typedef uint8_t ResourceType;
-
-    /** Flags set by the GrCacheable subclass. */
-    typedef uint8_t ResourceFlags;
-
-    /** Generate a unique ResourceType */
-    static ResourceType GenerateResourceType();
-
-    /** Creates a key for resource */
-    GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
-        this->init(id.getDomain(), id.getKey(), type, flags);
-    };
-
-    GrResourceKey(const GrResourceKey& src) {
-        fKey = src.fKey;
-    }
-
-    GrResourceKey() {
-        fKey.reset();
-    }
-
-    void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
-        this->init(id.getDomain(), id.getKey(), type, flags);
-    }
-
-    uint32_t getHash() const {
-        return fKey.getHash();
-    }
-
-    bool isScratch() const {
-        return ScratchDomain() ==
-            *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() +
-                                                        kCacheIDDomainOffset);
-    }
-
-    ResourceType getResourceType() const {
-        return *reinterpret_cast<const ResourceType*>(fKey.getData() +
-                                                      kResourceTypeOffset);
-    }
-
-    ResourceFlags getResourceFlags() const {
-        return *reinterpret_cast<const ResourceFlags*>(fKey.getData() +
-                                                       kResourceFlagsOffset);
-    }
-
-    bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; }
-
-private:
-    enum {
-        kCacheIDKeyOffset = 0,
-        kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key),
-        kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain),
-        kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType),
-        kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags),
-        kKeySize = SkAlign4(kPadOffset),
-        kPadSize = kKeySize - kPadOffset
-    };
-
-    void init(const GrCacheID::Domain domain,
-              const GrCacheID::Key& key,
-              ResourceType type,
-              ResourceFlags flags) {
-        union {
-            uint8_t  fKey8[kKeySize];
-            uint32_t fKey32[kKeySize / 4];
-        } keyData;
-
-        uint8_t* k = keyData.fKey8;
-        memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key));
-        memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain));
-        memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType));
-        memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags));
-        memset(k + kPadOffset, 0, kPadSize);
-        fKey.setKeyData(keyData.fKey32);
-    }
-    GrBinHashKey<kKeySize> fKey;
-};
 
 // The cache listens for these messages to purge junk resources proactively.
 struct GrResourceInvalidatedMessage {
@@ -118,7 +30,7 @@
 
 class GrResourceCacheEntry {
 public:
-    GrCacheable* resource() const { return fResource; }
+    GrGpuResource* resource() const { return fResource; }
     const GrResourceKey& key() const { return fKey; }
 
     static const GrResourceKey& GetKey(const GrResourceCacheEntry& e) { return e.key(); }
@@ -131,7 +43,7 @@
 
     /**
      *  Update the cached size for this entry and inform the resource cache that
-     *  it has changed. Usually invoked from GrCacheable::didChangeGpuMemorySize,
+     *  it has changed. Usually invoked from GrGpuResource::didChangeGpuMemorySize,
      *  not directly from here.
      */
     void didChangeResourceSize();
@@ -139,12 +51,12 @@
 private:
     GrResourceCacheEntry(GrResourceCache* resourceCache,
                          const GrResourceKey& key,
-                         GrCacheable* resource);
+                         GrGpuResource* resource);
     ~GrResourceCacheEntry();
 
     GrResourceCache* fResourceCache;
     GrResourceKey    fKey;
-    GrCacheable*     fResource;
+    GrGpuResource*   fResource;
     size_t           fCachedSize;
     bool             fIsExclusive;
 
@@ -152,12 +64,13 @@
     SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResourceCacheEntry);
 
     friend class GrResourceCache;
+    friend class GrContext;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
- *  Cache of GrCacheable objects.
+ *  Cache of GrGpuResource objects.
  *
  *  These have a corresponding GrResourceKey, built from 128bits identifying the
  *  resource. Multiple resources can map to same GrResourceKey.
@@ -170,7 +83,7 @@
  *  For fast searches, we maintain a hash map based on the GrResourceKey.
  *
  *  It is a goal to make the GrResourceCache the central repository and bookkeeper
- *  of all resources. It should replace the linked list of GrGpuObjects that
+ *  of all resources. It should replace the linked list of GrGpuResources that
  *  GrGpu uses to call abandon/release.
  */
 class GrResourceCache {
@@ -246,8 +159,8 @@
      *  For a resource to be completely exclusive to a caller both kNoOtherOwners
      *  and kHide must be specified.
      */
-    GrCacheable* find(const GrResourceKey& key,
-                      uint32_t ownershipFlags = 0);
+    GrGpuResource* find(const GrResourceKey& key,
+                        uint32_t ownershipFlags = 0);
 
     /**
      *  Add the new resource to the cache (by creating a new cache entry based
@@ -261,14 +174,14 @@
      *  is called.
      */
     void addResource(const GrResourceKey& key,
-                     GrCacheable* resource,
+                     GrGpuResource* resource,
                      uint32_t ownershipFlags = 0);
 
     /**
      * Determines if the cache contains an entry matching a key. If a matching
      * entry exists but was detached then it will not be found.
      */
-    bool hasKey(const GrResourceKey& key) const { return NULL != fCache.find(key); }
+    bool hasKey(const GrResourceKey& key) const { return SkToBool(fCache.find(key)); }
 
     /**
      * Hide 'entry' so that future searches will not find it. Such
@@ -334,7 +247,7 @@
 
     void removeInvalidResource(GrResourceCacheEntry* entry);
 
-    GrTMultiMap<GrResourceCacheEntry, GrResourceKey> fCache;
+    SkTMultiMap<GrResourceCacheEntry, GrResourceKey> fCache;
 
     // We're an internal doubly linked list
     typedef SkTInternalLList<GrResourceCacheEntry> EntryList;
diff --git a/src/gpu/GrResourceCache2.cpp b/src/gpu/GrResourceCache2.cpp
new file mode 100644
index 0000000..e0ba26a
--- /dev/null
+++ b/src/gpu/GrResourceCache2.cpp
@@ -0,0 +1,57 @@
+
+/*
+ * 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 "GrResourceCache2.h"
+#include "GrGpuResource.h"
+
+GrResourceCache2::~GrResourceCache2() {
+    this->releaseAll();
+}
+
+void GrResourceCache2::insertResource(GrGpuResource* resource) {
+    SkASSERT(resource);
+    SkASSERT(!resource->wasDestroyed());
+    SkASSERT(!this->isInCache(resource));
+    fResources.addToHead(resource);
+    ++fCount;
+    if (!resource->getScratchKey().isNullScratch()) {
+        fScratchMap.insert(resource->getScratchKey(), resource);
+    }
+}
+
+void GrResourceCache2::removeResource(GrGpuResource* resource) {
+    SkASSERT(this->isInCache(resource));
+    fResources.remove(resource);    
+    if (!resource->getScratchKey().isNullScratch()) {
+        fScratchMap.remove(resource->getScratchKey(), resource);
+    }
+    --fCount;
+}
+
+void GrResourceCache2::abandonAll() {
+    while (GrGpuResource* head = fResources.head()) {
+        SkASSERT(!head->wasDestroyed());
+        head->abandon();
+        // abandon should have already removed this from the list.
+        SkASSERT(head != fResources.head());
+    }
+    SkASSERT(!fScratchMap.count());
+    SkASSERT(!fCount);
+}
+
+void GrResourceCache2::releaseAll() {
+    while (GrGpuResource* head = fResources.head()) {
+        SkASSERT(!head->wasDestroyed());
+        head->release();
+        // release should have already removed this from the list.
+        SkASSERT(head != fResources.head());
+    }
+    SkASSERT(!fScratchMap.count());
+    SkASSERT(!fCount);
+}
diff --git a/src/gpu/GrResourceCache2.h b/src/gpu/GrResourceCache2.h
new file mode 100644
index 0000000..e05efd7
--- /dev/null
+++ b/src/gpu/GrResourceCache2.h
@@ -0,0 +1,59 @@
+
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrResourceCache2_DEFINED
+#define GrResourceCache2_DEFINED
+
+#include "GrGpuResource.h"
+#include "GrResourceKey.h"
+#include "SkTInternalLList.h"
+#include "SkTMultiMap.h"
+
+/**
+ *  Eventual replacement for GrResourceCache. Currently it simply holds a list
+ *  of all GrGpuResource objects for a GrContext. It is used to invalidate all
+ *  the resources when necessary.
+ */
+class GrResourceCache2 {
+public:
+    GrResourceCache2() : fCount(0) {};
+    ~GrResourceCache2();
+
+    void insertResource(GrGpuResource* resource);
+
+    void removeResource(GrGpuResource* resource);
+
+    void abandonAll();
+
+    void releaseAll();
+
+private:
+#ifdef SK_DEBUG
+    bool isInCache(const GrGpuResource* r) const {
+        return fResources.isInList(r);
+    }
+#endif
+
+
+    void removeScratch(const GrGpuResource* resource);
+    struct ScratchMapTraits {
+        static const GrResourceKey& GetKey(const GrGpuResource& r) {
+            return r.getScratchKey();
+        }
+
+        static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); }
+    };
+    typedef SkTMultiMap<GrGpuResource, GrResourceKey, ScratchMapTraits> ScratchMap;
+
+    int                                 fCount;
+    SkTInternalLList<GrGpuResource>     fResources;
+    // This map holds all resources that can be used as scratch resources.
+    ScratchMap                          fScratchMap; 
+};
+
+#endif
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 15b5457..c80a13c 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -13,7 +13,6 @@
 
 #include "SkData.h"
 #include "SkStrokeRec.h"
-#include "SkTextureCompressor.h"
 
 // TODO: try to remove this #include
 #include "GrContext.h"
@@ -37,6 +36,65 @@
     return modeMap[op];
 }
 
+static inline GrPixelConfig fmt_to_config(SkTextureCompressor::Format fmt) {
+
+    GrPixelConfig config;
+    switch (fmt) {
+        case SkTextureCompressor::kLATC_Format:
+            config = kLATC_GrPixelConfig;
+            break;
+
+        case SkTextureCompressor::kR11_EAC_Format:
+            config = kR11_EAC_GrPixelConfig;
+            break;
+
+        case SkTextureCompressor::kASTC_12x12_Format:
+            config = kASTC_12x12_GrPixelConfig;
+            break;
+
+        case SkTextureCompressor::kETC1_Format:
+            config = kETC1_GrPixelConfig;
+            break;
+
+        default:
+            SkDEBUGFAIL("No GrPixelConfig for compression format!");
+            // Best guess
+            config = kAlpha_8_GrPixelConfig;
+            break;
+    }
+
+    return config;
+}
+
+static bool choose_compressed_fmt(const GrDrawTargetCaps* caps,
+                                  SkTextureCompressor::Format *fmt) {
+    if (NULL == fmt) {
+        return false;
+    }
+
+    // We can't use scratch textures without the ability to update
+    // compressed textures...
+    if (!(caps->compressedTexSubImageSupport())) {
+        return false;
+    }
+
+    // Figure out what our preferred texture type is. If ASTC is available, that always
+    // gives the biggest win. Otherwise, in terms of compression speed and accuracy,
+    // LATC has a slight edge over R11 EAC.
+    if (caps->isConfigTexturable(kASTC_12x12_GrPixelConfig)) {
+        *fmt = SkTextureCompressor::kASTC_12x12_Format;
+        return true;
+    } else if (caps->isConfigTexturable(kLATC_GrPixelConfig)) {
+        *fmt = SkTextureCompressor::kLATC_Format;
+        return true;
+    } else if (caps->isConfigTexturable(kR11_EAC_GrPixelConfig)) {
+        *fmt = SkTextureCompressor::kR11_EAC_Format;
+        return true;
+    }
+
+    return false;
+}
+
 }
 
 /**
@@ -48,6 +106,8 @@
 
     SkXfermode* mode = SkXfermode::Create(op_to_mode(op));
 
+    SkASSERT(kNone_CompressionMode == fCompressionMode);
+
     paint.setXfermode(mode);
     paint.setAntiAlias(antiAlias);
     paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
@@ -79,19 +139,28 @@
     }
     paint.setAntiAlias(antiAlias);
 
+    SkTBlitterAllocator allocator;
+    SkBlitter* blitter = NULL;
+    if (kBlitter_CompressionMode == fCompressionMode) {
+        SkASSERT(fCompressedBuffer.get());
+        blitter = SkTextureCompressor::CreateBlitterForFormat(
+            fBM.width(), fBM.height(), fCompressedBuffer.get(), &allocator, fCompressedFormat);
+    }
+
     if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
         SkASSERT(0xFF == paint.getAlpha());
-        fDraw.drawPathCoverage(path, paint);
+        fDraw.drawPathCoverage(path, paint, blitter);
     } else {
         paint.setXfermodeMode(op_to_mode(op));
         paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
-        fDraw.drawPath(path, paint);
+        fDraw.drawPath(path, paint, blitter);
     }
 }
 
 bool GrSWMaskHelper::init(const SkIRect& resultBounds,
-                          const SkMatrix* matrix) {
-    if (NULL != matrix) {
+                          const SkMatrix* matrix,
+                          bool allowCompression) {
+    if (matrix) {
         fMatrix = *matrix;
     } else {
         fMatrix.setIdentity();
@@ -103,12 +172,51 @@
     SkIRect bounds = SkIRect::MakeWH(resultBounds.width(),
                                      resultBounds.height());
 
-    if (!fBM.allocPixels(SkImageInfo::MakeA8(bounds.fRight, bounds.fBottom))) {
-        return false;
+    if (allowCompression &&
+        fContext->getOptions().fDrawPathToCompressedTexture &&
+        choose_compressed_fmt(fContext->getGpu()->caps(), &fCompressedFormat)) {
+        fCompressionMode = kCompress_CompressionMode;
     }
-    sk_bzero(fBM.getPixels(), fBM.getSafeSize());
+
+    // Make sure that the width is a multiple of the desired block dimensions
+    // to allow for specialized SIMD instructions that compress multiple blocks at a time.
+    int cmpWidth = bounds.fRight;
+    int cmpHeight = bounds.fBottom;
+    if (kCompress_CompressionMode == fCompressionMode) {
+        int dimX, dimY;
+        SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY);
+        cmpWidth = dimX * ((cmpWidth + (dimX - 1)) / dimX);
+        cmpHeight = dimY * ((cmpHeight + (dimY - 1)) / dimY);
+
+        // Can we create a blitter?
+        if (SkTextureCompressor::ExistsBlitterForFormat(fCompressedFormat)) {
+            int cmpSz = SkTextureCompressor::GetCompressedDataSize(
+                fCompressedFormat, cmpWidth, cmpHeight);
+
+            SkASSERT(cmpSz > 0);
+            SkASSERT(NULL == fCompressedBuffer.get());
+            fCompressedBuffer.reset(cmpSz);
+            fCompressionMode = kBlitter_CompressionMode;
+        }
+    } 
+
+    // If we don't have a custom blitter, then we either need a bitmap to compress
+    // from or a bitmap that we're going to use as a texture. In any case, we should
+    // allocate the pixels for a bitmap
+    const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(cmpWidth, cmpHeight);
+    if (kBlitter_CompressionMode != fCompressionMode) {
+        if (!fBM.tryAllocPixels(bmImageInfo)) {
+            return false;
+        }
+
+        sk_bzero(fBM.getPixels(), fBM.getSafeSize());
+    } else {
+        // Otherwise, we just need to remember how big the buffer is...
+        fBM.setInfo(bmImageInfo);
+    }
 
     sk_bzero(&fDraw, sizeof(fDraw));
+
     fRasterClip.setRect(bounds);
     fDraw.fRC    = &fRasterClip;
     fDraw.fClip  = &fRasterClip.bwRgn();
@@ -125,20 +233,23 @@
     GrTextureDesc desc;
     desc.fWidth = fBM.width();
     desc.fHeight = fBM.height();
+    desc.fConfig = kAlpha_8_GrPixelConfig;
 
-#if GR_COMPRESS_ALPHA_MASK
-    static const int kLATCBlockSize = 4;
-    if (desc.fWidth % kLATCBlockSize == 0 && desc.fHeight % kLATCBlockSize == 0) {
-        desc.fConfig = kLATC_GrPixelConfig;
-    } else {
+    if (kNone_CompressionMode != fCompressionMode) {
+
+#ifdef SK_DEBUG
+        int dimX, dimY;
+        SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY);
+        SkASSERT((desc.fWidth % dimX) == 0);
+        SkASSERT((desc.fHeight % dimY) == 0);
 #endif
-        desc.fConfig = kAlpha_8_GrPixelConfig;
-#if GR_COMPRESS_ALPHA_MASK
+
+        desc.fConfig = fmt_to_config(fCompressedFormat);
+        SkASSERT(fContext->getGpu()->caps()->isConfigTexturable(desc.fConfig));
     }
-#endif
 
     texture->set(fContext, desc);
-    return NULL != texture->texture();
+    return SkToBool(texture->texture());
 }
 
 void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrTextureDesc& desc,
@@ -156,6 +267,17 @@
                          reuseScratch ? 0 : GrContext::kDontFlush_PixelOpsFlag);
 }
 
+void GrSWMaskHelper::compressTextureData(GrTexture *texture, const GrTextureDesc& desc) {
+
+    SkASSERT(GrPixelConfigIsCompressed(desc.fConfig));
+    SkASSERT(fmt_to_config(fCompressedFormat) == desc.fConfig);
+
+    SkAutoDataUnref cmpData(SkTextureCompressor::CompressBitmapToFormat(fBM, fCompressedFormat));
+    SkASSERT(cmpData);
+
+    this->sendTextureData(texture, desc, cmpData->data(), 0);
+}
+
 /**
  * Move the result of the software mask generation back to the gpu
  */
@@ -168,15 +290,19 @@
     desc.fConfig = texture->config();
         
     // First see if we should compress this texture before uploading.
-    if (texture->config() == kLATC_GrPixelConfig) {
-        SkTextureCompressor::Format format = SkTextureCompressor::kLATC_Format;
-        SkAutoDataUnref latcData(SkTextureCompressor::CompressBitmapToFormat(fBM, format));
-        SkASSERT(NULL != latcData);
+    switch (fCompressionMode) {
+        case kNone_CompressionMode:
+            this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes());
+            break;
 
-        this->sendTextureData(texture, desc, latcData->data(), 0);
-    } else {
-        // Looks like we have to send a full A8 texture. 
-        this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes());
+        case kCompress_CompressionMode:
+            this->compressTextureData(texture, desc);
+            break;
+
+        case kBlitter_CompressionMode:
+            SkASSERT(fCompressedBuffer.get());
+            this->sendTextureData(texture, desc, fCompressedBuffer.get(), 0);
+            break;
     }
 }
 
@@ -235,7 +361,7 @@
     maskMatrix.preTranslate(SkIntToScalar(-rect.fLeft), SkIntToScalar(-rect.fTop));
     maskMatrix.preConcat(drawState->getViewMatrix());
 
-    drawState->addCoverageEffect(
+    drawState->addCoverageProcessor(
                          GrSimpleTextureEffect::Create(texture,
                                                        maskMatrix,
                                                        GrTextureParams::kNone_FilterMode,
diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h
index 0ffaa64..f8cce8b 100644
--- a/src/gpu/GrSWMaskHelper.h
+++ b/src/gpu/GrSWMaskHelper.h
@@ -15,6 +15,7 @@
 #include "SkMatrix.h"
 #include "SkRasterClip.h"
 #include "SkRegion.h"
+#include "SkTextureCompressor.h"
 #include "SkTypes.h"
 
 class GrAutoScratchTexture;
@@ -41,14 +42,16 @@
 class GrSWMaskHelper : SkNoncopyable {
 public:
     GrSWMaskHelper(GrContext* context)
-    : fContext(context) {
+    : fContext(context)
+    , fCompressionMode(kNone_CompressionMode) {
     }
 
     // set up the internal state in preparation for draws. Since many masks
     // may be accumulated in the helper during creation, "resultBounds"
     // allows the caller to specify the region of interest - to limit the
-    // amount of work.
-    bool init(const SkIRect& resultBounds, const SkMatrix* matrix);
+    // amount of work. allowCompression should be set to false if you plan on using
+    // your own texture to draw into, and not a scratch texture via getTexture().
+    bool init(const SkIRect& resultBounds, const SkMatrix* matrix, bool allowCompression = true);
 
     // Draw a single rect into the accumulation bitmap using the specified op
     void draw(const SkRect& rect, SkRegion::Op op,
@@ -93,7 +96,6 @@
                                          GrDrawTarget* target,
                                          const SkIRect& rect);
 
-protected:
 private:
     GrContext*      fContext;
     SkMatrix        fMatrix;
@@ -101,11 +103,33 @@
     SkDraw          fDraw;
     SkRasterClip    fRasterClip;
 
+    // This enum says whether or not we should compress the mask:
+    // kNone_CompressionMode: compression is not supported on this device.
+    // kCompress_CompressionMode: compress the bitmap before it gets sent to the gpu
+    // kBlitter_CompressionMode: write to the bitmap using a special compressed blitter.
+    enum CompressionMode {
+        kNone_CompressionMode,
+        kCompress_CompressionMode,
+        kBlitter_CompressionMode,
+    } fCompressionMode;
+
+    // This is the buffer into which we store our compressed data. This buffer is
+    // only allocated (non-null) if fCompressionMode is kBlitter_CompressionMode
+    SkAutoMalloc fCompressedBuffer;
+
+    // This is the desired format within which to compress the
+    // texture. This value is only valid if fCompressionMode is not kNone_CompressionMode.
+    SkTextureCompressor::Format fCompressedFormat;
+
     // Actually sends the texture data to the GPU. This is called from
     // toTexture with the data filled in depending on the texture config.
     void sendTextureData(GrTexture *texture, const GrTextureDesc& desc,
                          const void *data, int rowbytes);
 
+    // Compresses the bitmap stored in fBM and sends the compressed data
+    // to the GPU to be stored in 'texture' using sendTextureData.
+    void compressTextureData(GrTexture *texture, const GrTextureDesc& desc);
+
     typedef SkNoncopyable INHERITED;
 };
 
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index d0936d6..0d3ef62 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -15,13 +15,7 @@
                                          const SkStrokeRec&,
                                          const GrDrawTarget*,
                                          bool antiAlias) const {
-    if (!antiAlias || NULL == fContext) {
-        // TODO: We could allow the SW path to also handle non-AA paths but
-        // this would mean that GrDefaultPathRenderer would never be called
-        // (since it appears after the SW renderer in the path renderer
-        // chain). Some testing would need to be done r.e. performance
-        // and consistency of the resulting images before removing
-        // the "!antiAlias" clause from the above test
+    if (NULL == fContext) {
         return false;
     }
 
@@ -90,22 +84,22 @@
     if (devClipBounds.fTop < devPathBounds.fTop) {
         rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
                   devClipBounds.fRight, devPathBounds.fTop);
-        target->drawSimpleRect(rect, NULL);
+        target->drawSimpleRect(rect);
     }
     if (devClipBounds.fLeft < devPathBounds.fLeft) {
         rect.iset(devClipBounds.fLeft, devPathBounds.fTop,
                   devPathBounds.fLeft, devPathBounds.fBottom);
-        target->drawSimpleRect(rect, NULL);
+        target->drawSimpleRect(rect);
     }
     if (devClipBounds.fRight > devPathBounds.fRight) {
         rect.iset(devPathBounds.fRight, devPathBounds.fTop,
                   devClipBounds.fRight, devPathBounds.fBottom);
-        target->drawSimpleRect(rect, NULL);
+        target->drawSimpleRect(rect);
     }
     if (devClipBounds.fBottom > devPathBounds.fBottom) {
         rect.iset(devClipBounds.fLeft, devPathBounds.fBottom,
                   devClipBounds.fRight, devClipBounds.fBottom);
-        target->drawSimpleRect(rect, NULL);
+        target->drawSimpleRect(rect);
     }
 }
 
diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp
index 273c01b..5f55c1a 100644
--- a/src/gpu/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp
@@ -15,8 +15,8 @@
 #include "SkStrokeRec.h"
 
 GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) {
-    SkASSERT(NULL != context);
-    SkASSERT(NULL != context->getGpu());
+    SkASSERT(context);
+    SkASSERT(context->getGpu());
     if (context->getGpu()->caps()->pathRenderingSupport()) {
         return SkNEW_ARGS(GrStencilAndCoverPathRenderer, (context->getGpu()));
     } else {
@@ -40,7 +40,7 @@
                                                 bool antiAlias) const {
     return !stroke.isHairlineStyle() &&
            !antiAlias && // doesn't do per-path AA, relies on the target having MSAA
-           NULL != target->getDrawState().getRenderTarget()->getStencilBuffer() &&
+           target->getDrawState().getRenderTarget()->getStencilBuffer() &&
            target->getDrawState().getStencil().isDisabled();
 }
 
@@ -51,11 +51,22 @@
     return GrPathRenderer::kStencilOnly_StencilSupport;
 }
 
+static GrPath* get_gr_path(GrGpu* gpu, const SkPath& skPath, const SkStrokeRec& stroke) {
+    GrContext* ctx = gpu->getContext();
+    GrResourceKey resourceKey = GrPath::ComputeKey(skPath, stroke);
+    SkAutoTUnref<GrPath> path(static_cast<GrPath*>(ctx->findAndRefCachedResource(resourceKey)));
+    if (NULL == path || !path->isEqualTo(skPath, stroke)) {
+        path.reset(gpu->pathRendering()->createPath(skPath, stroke));
+        ctx->addResourceToCache(resourceKey, path);
+    }
+    return path.detach();
+}
+
 void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path,
                                                   const SkStrokeRec& stroke,
                                                   GrDrawTarget* target) {
     SkASSERT(!path.isInverseFillType());
-    SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(path, stroke));
+    SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
     target->stencilPath(p, path.getFillType());
 }
 
@@ -69,7 +80,7 @@
     GrDrawState* drawState = target->drawState();
     SkASSERT(drawState->getStencil().isDisabled());
 
-    SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(path, stroke));
+    SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
 
     if (path.isInverseFillType()) {
         GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass,
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
new file mode 100644
index 0000000..c1d9e9d
--- /dev/null
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -0,0 +1,426 @@
+/*
+ * 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 "GrStencilAndCoverTextContext.h"
+#include "GrDrawTarget.h"
+#include "GrGpu.h"
+#include "GrPath.h"
+#include "GrPathRange.h"
+#include "SkAutoKern.h"
+#include "SkDraw.h"
+#include "SkDrawProcs.h"
+#include "SkGlyphCache.h"
+#include "SkGpuDevice.h"
+#include "SkPath.h"
+#include "SkTextMapStateProc.h"
+#include "SkTextFormatParams.h"
+
+GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(
+    GrContext* context, const SkDeviceProperties& properties)
+    : GrTextContext(context, properties)
+    , fPendingGlyphCount(0) {
+}
+
+GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() {
+}
+
+void GrStencilAndCoverTextContext::drawText(const GrPaint& paint,
+                                            const SkPaint& skPaint,
+                                            const char text[],
+                                            size_t byteLength,
+                                            SkScalar x, SkScalar y) {
+    SkASSERT(byteLength == 0 || text != NULL);
+
+    if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) {
+        return;
+    }
+
+    // This is the slow path, mainly used by Skia unit tests.  The other
+    // backends (8888, gpu, ...) use device-space dependent glyph caches. In
+    // order to match the glyph positions that the other code paths produce, we
+    // must also use device-space dependent glyph cache. This has the
+    // side-effect that the glyph shape outline will be in device-space,
+    // too. This in turn has the side-effect that NVPR can not stroke the paths,
+    // as the stroke in NVPR is defined in object-space.
+    // NOTE: here we have following coincidence that works at the moment:
+    // - When using the device-space glyphs, the transforms we pass to NVPR
+    // instanced drawing are the global transforms, and the view transform is
+    // identity. NVPR can not use non-affine transforms in the instanced
+    // drawing. This is taken care of by SkDraw::ShouldDrawTextAsPaths since it
+    // will turn off the use of device-space glyphs when perspective transforms
+    // are in use.
+
+    this->init(paint, skPaint, byteLength, kMaxAccuracy_RenderMode);
+
+    // Transform our starting point.
+    if (fNeedsDeviceSpaceGlyphs) {
+        SkPoint loc;
+        fContextInitialMatrix.mapXY(x, y, &loc);
+        x = loc.fX;
+        y = loc.fY;
+    }
+
+    SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
+
+    fTransformType = GrPathRendering::kTranslate_PathTransformType;
+
+    const char* stop = text + byteLength;
+
+    // Measure first if needed.
+    if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
+        SkFixed    stopX = 0;
+        SkFixed    stopY = 0;
+
+        const char* textPtr = text;
+        while (textPtr < stop) {
+            // We don't need x, y here, since all subpixel variants will have the
+            // same advance.
+            const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &textPtr, 0, 0);
+
+            stopX += glyph.fAdvanceX;
+            stopY += glyph.fAdvanceY;
+        }
+        SkASSERT(textPtr == stop);
+
+        SkScalar alignX = SkFixedToScalar(stopX) * fTextRatio;
+        SkScalar alignY = SkFixedToScalar(stopY) * fTextRatio;
+
+        if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) {
+            alignX = SkScalarHalf(alignX);
+            alignY = SkScalarHalf(alignY);
+        }
+
+        x -= alignX;
+        y -= alignY;
+    }
+
+    SkAutoKern autokern;
+
+    SkFixed fixedSizeRatio = SkScalarToFixed(fTextRatio);
+
+    SkFixed fx = SkScalarToFixed(x);
+    SkFixed fy = SkScalarToFixed(y);
+    while (text < stop) {
+        const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
+        fx += SkFixedMul_portable(autokern.adjust(glyph), fixedSizeRatio);
+        if (glyph.fWidth) {
+            this->appendGlyph(glyph.getGlyphID(), SkFixedToScalar(fx), SkFixedToScalar(fy));
+        }
+
+        fx += SkFixedMul_portable(glyph.fAdvanceX, fixedSizeRatio);
+        fy += SkFixedMul_portable(glyph.fAdvanceY, fixedSizeRatio);
+    }
+
+    this->finish();
+}
+
+void GrStencilAndCoverTextContext::drawPosText(const GrPaint& paint,
+                                               const SkPaint& skPaint,
+                                               const char text[],
+                                               size_t byteLength,
+                                               const SkScalar pos[],
+                                               SkScalar constY,
+                                               int scalarsPerPosition) {
+    SkASSERT(byteLength == 0 || text != NULL);
+    SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
+
+    // nothing to draw
+    if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) {
+        return;
+    }
+
+    // This is the fast path.  Here we do not bake in the device-transform to
+    // the glyph outline or the advances. This is because we do not need to
+    // position the glyphs at all, since the caller has done the positioning.
+    // The positioning is based on SkPaint::measureText of individual
+    // glyphs. That already uses glyph cache without device transforms. Device
+    // transform is not part of SkPaint::measureText API, and thus we use the
+    // same glyphs as what were measured.
+
+    const float textTranslateY = (1 == scalarsPerPosition ? constY : 0);
+    this->init(paint, skPaint, byteLength, kMaxPerformance_RenderMode, textTranslateY);
+
+    SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
+
+    const char* stop = text + byteLength;
+
+    if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
+        if (1 == scalarsPerPosition) {
+            fTransformType = GrPathRendering::kTranslateX_PathTransformType;
+            while (text < stop) {
+                const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
+                if (glyph.fWidth) {
+                    this->appendGlyph(glyph.getGlyphID(), *pos);
+                }
+                pos++;
+            }
+        } else {
+            SkASSERT(2 == scalarsPerPosition);
+            fTransformType = GrPathRendering::kTranslate_PathTransformType;
+            while (text < stop) {
+                const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
+                if (glyph.fWidth) {
+                    this->appendGlyph(glyph.getGlyphID(), pos[0], pos[1]);
+                }
+                pos += 2;
+            }
+        }
+    } else {
+        fTransformType = GrPathRendering::kTranslate_PathTransformType;
+        SkTextMapStateProc tmsProc(SkMatrix::I(), 0, scalarsPerPosition);
+        SkTextAlignProcScalar alignProc(fSkPaint.getTextAlign());
+        while (text < stop) {
+            const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
+            if (glyph.fWidth) {
+                SkPoint tmsLoc;
+                tmsProc(pos, &tmsLoc);
+                SkPoint loc;
+                alignProc(tmsLoc, glyph, &loc);
+
+                this->appendGlyph(glyph.getGlyphID(), loc.x(), loc.y());
+            }
+            pos += scalarsPerPosition;
+        }
+    }
+
+    this->finish();
+}
+
+bool GrStencilAndCoverTextContext::canDraw(const SkPaint& paint) {
+    if (paint.getRasterizer()) {
+        return false;
+    }
+    if (paint.getMaskFilter()) {
+        return false;
+    }
+    if (paint.getPathEffect()) {
+        return false;
+    }
+
+    // No hairlines unless we can map the 1 px width to the object space.
+    if (paint.getStyle() == SkPaint::kStroke_Style
+        && paint.getStrokeWidth() == 0
+        && fContext->getMatrix().hasPerspective()) {
+        return false;
+    }
+
+    // No color bitmap fonts.
+    SkScalerContext::Rec    rec;
+    SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec);
+    return rec.getFormat() != SkMask::kARGB32_Format;
+}
+
+static GrPathRange* get_gr_glyphs(GrContext* ctx,
+                                  const SkTypeface* typeface,
+                                  const SkDescriptor* desc,
+                                  const SkStrokeRec& stroke) {
+    static const GrCacheID::Domain gGlyphsDomain = GrCacheID::GenerateDomain();
+
+    GrCacheID::Key key;
+    uint64_t* keyData = key.fData64;
+    keyData[0] = desc ? desc->getChecksum() : 0;
+    keyData[0] = (keyData[0] << 32) | (typeface ? typeface->uniqueID() : 0);
+    keyData[1] = GrPath::ComputeStrokeKey(stroke);
+    GrResourceKey resourceKey = GrResourceKey(GrCacheID(gGlyphsDomain, key),
+                                              GrPathRange::resourceType(), 0);
+
+    SkAutoTUnref<GrPathRange> glyphs(
+        static_cast<GrPathRange*>(ctx->findAndRefCachedResource(resourceKey)));
+    if (NULL == glyphs || (NULL != desc && !glyphs->isEqualTo(*desc))) {
+        glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc, stroke));
+        ctx->addResourceToCache(resourceKey, glyphs);
+    }
+
+    return glyphs.detach();
+}
+
+void GrStencilAndCoverTextContext::init(const GrPaint& paint,
+                                        const SkPaint& skPaint,
+                                        size_t textByteLength,
+                                        RenderMode renderMode,
+                                        SkScalar textTranslateY) {
+    GrTextContext::init(paint, skPaint);
+
+    fContextInitialMatrix = fContext->getMatrix();
+
+    const bool otherBackendsWillDrawAsPaths =
+        SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix);
+
+    fNeedsDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths &&
+                              kMaxAccuracy_RenderMode == renderMode &&
+                              SkToBool(fContextInitialMatrix.getType() &
+                                       (SkMatrix::kScale_Mask | SkMatrix::kAffine_Mask));
+
+    if (fNeedsDeviceSpaceGlyphs) {
+        // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms.
+        SkASSERT(!fContextInitialMatrix.hasPerspective());
+        SkASSERT(0 == textTranslateY); // TODO: Handle textTranslateY in device-space usecase.
+
+        fTextRatio = fTextInverseRatio = 1.0f;
+
+        // Glyphs loaded by GPU path rendering have an inverted y-direction.
+        SkMatrix m;
+        m.setScale(1, -1);
+        fContext->setMatrix(m);
+
+        // Post-flip the initial matrix so we're left with just the flip after
+        // the paint preConcats the inverse.
+        m = fContextInitialMatrix;
+        m.postScale(1, -1);
+        fPaint.localCoordChangeInverse(m);
+
+        // The whole shape (including stroke) will be baked into the glyph outlines. Make
+        // NVPR just fill the baked shapes.
+        fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialMatrix, false);
+        fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTypeface(),
+                                &fGlyphCache->getDescriptor(),
+                                SkStrokeRec(SkStrokeRec::kFill_InitStyle));
+    } else {
+        // Don't bake strokes into the glyph outlines. We will stroke the glyphs
+        // using the GPU instead. This is the fast path.
+        SkStrokeRec gpuStroke = SkStrokeRec(fSkPaint);
+        fSkPaint.setStyle(SkPaint::kFill_Style);
+
+        if (gpuStroke.isHairlineStyle()) {
+            // Approximate hairline stroke.
+            SkScalar strokeWidth = SK_Scalar1 /
+                (SkVector::Make(fContextInitialMatrix.getScaleX(),
+                                fContextInitialMatrix.getSkewY()).length());
+            gpuStroke.setStrokeStyle(strokeWidth, false /*strokeAndFill*/);
+
+        } else if (fSkPaint.isFakeBoldText() &&
+#ifdef SK_USE_FREETYPE_EMBOLDEN
+                   kMaxPerformance_RenderMode == renderMode &&
+#endif
+                   SkStrokeRec::kStroke_Style != gpuStroke.getStyle()) {
+
+            // Instead of baking fake bold into the glyph outlines, do it with the GPU stroke.
+            SkScalar fakeBoldScale = SkScalarInterpFunc(fSkPaint.getTextSize(),
+                                                        kStdFakeBoldInterpKeys,
+                                                        kStdFakeBoldInterpValues,
+                                                        kStdFakeBoldInterpLength);
+            SkScalar extra = SkScalarMul(fSkPaint.getTextSize(), fakeBoldScale);
+            gpuStroke.setStrokeStyle(gpuStroke.needToApply() ? gpuStroke.getWidth() + extra : extra,
+                                     true /*strokeAndFill*/);
+
+            fSkPaint.setFakeBoldText(false);
+        }
+
+        bool canUseRawPaths;
+
+        if (otherBackendsWillDrawAsPaths || kMaxPerformance_RenderMode == renderMode) {
+            // We can draw the glyphs from canonically sized paths.
+            fTextRatio = fSkPaint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
+            fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fSkPaint.getTextSize();
+
+            // Compensate for the glyphs being scaled by fTextRatio.
+            if (!gpuStroke.isFillStyle()) {
+                gpuStroke.setStrokeStyle(gpuStroke.getWidth() / fTextRatio,
+                                         SkStrokeRec::kStrokeAndFill_Style == gpuStroke.getStyle());
+            }
+
+            fSkPaint.setLinearText(true);
+            fSkPaint.setLCDRenderText(false);
+            fSkPaint.setAutohinted(false);
+            fSkPaint.setHinting(SkPaint::kNo_Hinting);
+            fSkPaint.setSubpixelText(true);
+            fSkPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
+
+            canUseRawPaths = SK_Scalar1 == fSkPaint.getTextScaleX() &&
+                             0 == fSkPaint.getTextSkewX() &&
+                             !fSkPaint.isFakeBoldText() &&
+                             !fSkPaint.isVerticalText();
+        } else {
+            fTextRatio = fTextInverseRatio = 1.0f;
+            canUseRawPaths = false;
+        }
+
+        SkMatrix textMatrix;
+        textMatrix.setTranslate(0, textTranslateY);
+        // Glyphs loaded by GPU path rendering have an inverted y-direction.
+        textMatrix.preScale(fTextRatio, -fTextRatio);
+        fPaint.localCoordChange(textMatrix);
+        fContext->concatMatrix(textMatrix);
+
+        fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, NULL, false);
+        fGlyphs = canUseRawPaths ?
+                      get_gr_glyphs(fContext, fSkPaint.getTypeface(), NULL, gpuStroke) :
+                      get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTypeface(),
+                                    &fGlyphCache->getDescriptor(), gpuStroke);
+    }
+
+    fStateRestore.set(fDrawTarget->drawState());
+
+    fDrawTarget->drawState()->setFromPaint(fPaint, fContext->getMatrix(),
+                                           fContext->getRenderTarget());
+
+    GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
+                                 kZero_StencilOp,
+                                 kZero_StencilOp,
+                                 kNotEqual_StencilFunc,
+                                 0xffff,
+                                 0x0000,
+                                 0xffff);
+
+    *fDrawTarget->drawState()->stencil() = kStencilPass;
+
+    SkASSERT(0 == fPendingGlyphCount);
+}
+
+inline void GrStencilAndCoverTextContext::appendGlyph(uint16_t glyphID, float x) {
+    SkASSERT(GrPathRendering::kTranslateX_PathTransformType == fTransformType);
+
+    if (fPendingGlyphCount >= kGlyphBufferSize) {
+        this->flush();
+    }
+
+    fIndexBuffer[fPendingGlyphCount] = glyphID;
+    fTransformBuffer[fPendingGlyphCount] = fTextInverseRatio * x;
+
+    ++fPendingGlyphCount;
+}
+
+inline void GrStencilAndCoverTextContext::appendGlyph(uint16_t glyphID, float x, float y) {
+    SkASSERT(GrPathRendering::kTranslate_PathTransformType == fTransformType);
+
+    if (fPendingGlyphCount >= kGlyphBufferSize) {
+        this->flush();
+    }
+
+    fIndexBuffer[fPendingGlyphCount] = glyphID;
+    fTransformBuffer[2 * fPendingGlyphCount] = fTextInverseRatio * x;
+    fTransformBuffer[2 * fPendingGlyphCount + 1] = -fTextInverseRatio * y;
+
+    ++fPendingGlyphCount;
+}
+
+void GrStencilAndCoverTextContext::flush() {
+    if (0 == fPendingGlyphCount) {
+        return;
+    }
+
+    fDrawTarget->drawPaths(fGlyphs, fIndexBuffer, fPendingGlyphCount,
+                           fTransformBuffer, fTransformType, SkPath::kWinding_FillType);
+
+    fPendingGlyphCount = 0;
+}
+
+void GrStencilAndCoverTextContext::finish() {
+    this->flush();
+
+    fGlyphs->unref();
+    fGlyphs = NULL;
+
+    SkGlyphCache::AttachCache(fGlyphCache);
+    fGlyphCache = NULL;
+
+    fDrawTarget->drawState()->stencil()->setDisabled();
+    fStateRestore.set(NULL);
+    fContext->setMatrix(fContextInitialMatrix);
+    GrTextContext::finish();
+}
+
diff --git a/src/gpu/GrStencilAndCoverTextContext.h b/src/gpu/GrStencilAndCoverTextContext.h
new file mode 100644
index 0000000..5ba4a70
--- /dev/null
+++ b/src/gpu/GrStencilAndCoverTextContext.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrStencilAndCoverTextContext_DEFINED
+#define GrStencilAndCoverTextContext_DEFINED
+
+#include "GrTextContext.h"
+#include "GrDrawState.h"
+#include "GrDrawTarget.h"
+#include "SkStrokeRec.h"
+
+class GrTextStrike;
+class GrPath;
+class GrPathRange;
+
+/*
+ * This class implements text rendering using stencil and cover path rendering
+ * (by the means of GrDrawTarget::drawPath).
+ * This class exposes the functionality through GrTextContext interface.
+ */
+class GrStencilAndCoverTextContext : public GrTextContext {
+public:
+    GrStencilAndCoverTextContext(GrContext*, const SkDeviceProperties&);
+    virtual ~GrStencilAndCoverTextContext();
+
+    virtual void drawText(const GrPaint&, const SkPaint&, const char text[],
+                          size_t byteLength,
+                          SkScalar x, SkScalar y) SK_OVERRIDE;
+    virtual void drawPosText(const GrPaint&, const SkPaint&,
+                             const char text[], size_t byteLength,
+                             const SkScalar pos[], SkScalar constY,
+                             int scalarsPerPosition) SK_OVERRIDE;
+
+    virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
+
+private:
+    static const int kGlyphBufferSize = 1024;
+
+    enum RenderMode {
+        /**
+         * This is the render mode used by drawText(), which is mainly used by
+         * the Skia unit tests. It tries match the other text backends exactly,
+         * with the exception of not implementing LCD text, and doing anti-
+         * aliasing with the built-in MSAA.
+         */
+        kMaxAccuracy_RenderMode,
+
+        /**
+         * This is the render mode used by drawPosText(). It ignores hinting and
+         * LCD text, even if the client provided positions for hinted glyphs,
+         * and renders from a canonically-sized, generic set of paths for the
+         * given typeface. In the future we should work out a system for the
+         * client to know it should not provide hinted glyph positions. This
+         * render mode also tries to use GPU stroking for fake bold, even when
+         * SK_USE_FREETYPE_EMBOLDEN is set.
+         */
+        kMaxPerformance_RenderMode,
+    };
+
+    void init(const GrPaint&, const SkPaint&, size_t textByteLength,
+              RenderMode, SkScalar textTranslateY = 0);
+    void initGlyphs(SkGlyphCache* cache);
+    void appendGlyph(uint16_t glyphID, float x);
+    void appendGlyph(uint16_t glyphID, float x, float y);
+    void flush();
+    void finish();
+
+    GrDrawState::AutoRestoreEffects fStateRestore;
+    SkScalar fTextRatio;
+    float fTextInverseRatio;
+    SkGlyphCache* fGlyphCache;
+    GrPathRange* fGlyphs;
+    uint32_t fIndexBuffer[kGlyphBufferSize];
+    float fTransformBuffer[2 * kGlyphBufferSize];
+    GrDrawTarget::PathTransformType fTransformType;
+    int fPendingGlyphCount;
+    SkMatrix fContextInitialMatrix;
+    bool fNeedsDeviceSpaceGlyphs;
+};
+
+#endif
diff --git a/src/gpu/GrStencilBuffer.h b/src/gpu/GrStencilBuffer.h
index 696ba83..86fef50 100644
--- a/src/gpu/GrStencilBuffer.h
+++ b/src/gpu/GrStencilBuffer.h
@@ -11,12 +11,12 @@
 #define GrStencilBuffer_DEFINED
 
 #include "GrClipData.h"
-#include "GrGpuObject.h"
+#include "GrGpuResource.h"
 
 class GrRenderTarget;
 class GrResourceKey;
 
-class GrStencilBuffer : public GrGpuObject {
+class GrStencilBuffer : public GrGpuResource {
 public:
     SK_DECLARE_INST_COUNT(GrStencilBuffer);
 
@@ -54,7 +54,7 @@
 
 protected:
     GrStencilBuffer(GrGpu* gpu, bool isWrapped, int width, int height, int bits, int sampleCnt)
-        : GrGpuObject(gpu, isWrapped)
+        : GrGpuResource(gpu, isWrapped)
         , fWidth(width)
         , fHeight(height)
         , fBits(bits)
@@ -74,7 +74,7 @@
     SkIRect     fLastClipStackRect;
     SkIPoint    fLastClipSpaceOffset;
 
-    typedef GrGpuObject INHERITED;
+    typedef GrGpuResource INHERITED;
 };
 
 #endif
diff --git a/src/gpu/GrStrokeInfo.h b/src/gpu/GrStrokeInfo.h
index b9ba5ea..2bd056e 100644
--- a/src/gpu/GrStrokeInfo.h
+++ b/src/gpu/GrStrokeInfo.h
@@ -56,7 +56,7 @@
      * dashed effect and we are stroking, otherwise it retruns false.
      */
     bool setDashInfo(const SkPathEffect* pe) {
-        if (NULL != pe && !fStroke.isFillStyle()) {
+        if (pe && !fStroke.isFillStyle()) {
             fDashInfo.fIntervals = NULL;
             fDashType = pe->asADash(&fDashInfo);
             if (SkPathEffect::kDash_DashType == fDashType) {
diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp
index a07fe67..d15cbdf 100644
--- a/src/gpu/GrSurface.cpp
+++ b/src/gpu/GrSurface.cpp
@@ -13,20 +13,16 @@
 #include <stdio.h>
 
 SkImageInfo GrSurface::info() const {
-    SkImageInfo info;
-    if (!GrPixelConfig2ColorType(this->config(), &info.fColorType)) {
+    SkColorType colorType;
+    if (!GrPixelConfig2ColorType(this->config(), &colorType)) {
         sk_throw();
     }
-    info.fWidth = this->width();
-    info.fHeight = this->height();
-    info.fAlphaType = kPremul_SkAlphaType;
-    return info;
+    return SkImageInfo::Make(this->width(), this->height(), colorType, kPremul_SkAlphaType);
 }
 
 bool GrSurface::savePixels(const char* filename) {
     SkBitmap bm;
-    if (!bm.allocPixels(SkImageInfo::MakeN32Premul(this->width(),
-                                                   this->height()))) {
+    if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(this->width(), this->height()))) {
         return false;
     }
 
@@ -48,3 +44,39 @@
 
     return true;
 }
+
+bool GrSurface::hasPendingRead() const {
+    const GrTexture* thisTex = this->asTexture();
+    if (thisTex && thisTex->internalHasPendingRead()) {
+        return true;
+    }
+    const GrRenderTarget* thisRT = this->asRenderTarget();
+    if (thisRT && thisRT->internalHasPendingRead()) {
+        return true;
+    }
+    return false;
+}
+
+bool GrSurface::hasPendingWrite() const {
+    const GrTexture* thisTex = this->asTexture();
+    if (thisTex && thisTex->internalHasPendingWrite()) {
+        return true;
+    }
+    const GrRenderTarget* thisRT = this->asRenderTarget();
+    if (thisRT && thisRT->internalHasPendingWrite()) {
+        return true;
+    }
+    return false;
+}
+
+bool GrSurface::hasPendingIO() const {
+    const GrTexture* thisTex = this->asTexture();
+    if (thisTex && thisTex->internalHasPendingIO()) {
+        return true;
+    }
+    const GrRenderTarget* thisRT = this->asRenderTarget();
+    if (thisRT && thisRT->internalHasPendingIO()) {
+        return true;
+    }
+    return false;
+}
diff --git a/src/gpu/GrTHashTable.h b/src/gpu/GrTHashTable.h
deleted file mode 100644
index 9da4b06..0000000
--- a/src/gpu/GrTHashTable.h
+++ /dev/null
@@ -1,215 +0,0 @@
-
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-
-#ifndef GrTHashTable_DEFINED
-#define GrTHashTable_DEFINED
-
-#include "GrTypes.h"
-#include "SkTDArray.h"
-
-/**
- *  Key needs
- *      static bool Equals(const Entry&, const Key&);
- *      static bool LessThan(const Entry&, const Key&);
- *      static bool Equals(const Entry&, const Entry&); for SK_DEBUG if GrTHashTable::validate() is called
- *      static bool LessThan(const Entry&, const Entry&); for SK_DEBUG if GrTHashTable::validate() is called
- *      uint32_t getHash() const;
- *
- *  Allows duplicate key entries but on find you may get
- *  any of the duplicate entries returned.
- */
-template <typename T, typename Key, size_t kHashBits> class GrTHashTable {
-public:
-    GrTHashTable() { this->clearHash(); }
-    ~GrTHashTable() {}
-
-    int count() const { return fSorted.count(); }
-
-    struct Any {
-        // Return the first resource that matches the key.
-        bool operator()(const T*) const { return true; }
-    };
-
-    T* find(const Key& key) const { return this->find(key, Any()); }
-    template <typename Filter> T* find(const Key&, Filter filter) const;
-
-    // return true if key was unique when inserted.
-    bool insert(const Key&, T*);
-    void remove(const Key&, const T*);
-
-    void deleteAll();
-
-#ifdef SK_DEBUG
-    void validate() const;
-    bool contains(T*) const;
-#endif
-
-    // testing
-    const SkTDArray<T*>& getArray() const { return fSorted; }
-    SkTDArray<T*>& getArray() { return fSorted; }
-private:
-    void clearHash() { sk_bzero(fHash, sizeof(fHash)); }
-
-    enum {
-        kHashCount = 1 << kHashBits,
-        kHashMask  = kHashCount - 1
-    };
-    static unsigned hash2Index(intptr_t hash) {
-#if 0
-        if (sizeof(hash) == 8) {
-            hash ^= hash >> 32;
-        }
-#endif
-        hash ^= hash >> 16;
-        if (kHashBits <= 8) {
-            hash ^= hash >> 8;
-        }
-        return hash & kHashMask;
-    }
-
-    mutable T* fHash[kHashCount];
-    SkTDArray<T*> fSorted;
-
-    // search fSorted, and return the found index, or ~index of where it
-    // should be inserted
-    int searchArray(const Key&) const;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-template <typename T, typename Key, size_t kHashBits>
-int GrTHashTable<T, Key, kHashBits>::searchArray(const Key& key) const {
-    int count = fSorted.count();
-    if (0 == count) {
-        // we should insert it at 0
-        return ~0;
-    }
-
-    const T* const* array = fSorted.begin();
-    int high = count - 1;
-    int low = 0;
-    while (high > low) {
-        int index = (low + high) >> 1;
-        if (Key::LessThan(*array[index], key)) {
-            low = index + 1;
-        } else {
-            high = index;
-        }
-    }
-
-    // check if we found it
-    if (Key::Equals(*array[high], key)) {
-        // above search should have found the first occurrence if there
-        // are multiple.
-        SkASSERT(0 == high || Key::LessThan(*array[high - 1], key));
-        return high;
-    }
-
-    // now return the ~ of where we should insert it
-    if (Key::LessThan(*array[high], key)) {
-        high += 1;
-    }
-    return ~high;
-}
-
-template <typename T, typename Key, size_t kHashBits>
-template <typename Filter>
-T* GrTHashTable<T, Key, kHashBits>::find(const Key& key, Filter filter) const {
-
-    int hashIndex = hash2Index(key.getHash());
-    T* elem = fHash[hashIndex];
-
-    if (NULL != elem && Key::Equals(*elem, key) && filter(elem)) {
-        return elem;
-    }
-
-    // bsearch for the key in our sorted array
-    int index = this->searchArray(key);
-    if (index < 0) {
-        return NULL;
-    }
-
-    const T* const* array = fSorted.begin();
-
-    // above search should have found the first occurrence if there
-    // are multiple.
-    SkASSERT(0 == index || Key::LessThan(*array[index - 1], key));
-
-    for ( ; index < count() && Key::Equals(*array[index], key); ++index) {
-        if (filter(fSorted[index])) {
-            // update the hash
-            fHash[hashIndex] = fSorted[index];
-            return fSorted[index];
-        }
-    }
-
-    return NULL;
-}
-
-template <typename T, typename Key, size_t kHashBits>
-bool GrTHashTable<T, Key, kHashBits>::insert(const Key& key, T* elem) {
-    int index = this->searchArray(key);
-    bool first = index < 0;
-    if (first) {
-        // turn it into the actual index
-        index = ~index;
-    }
-    // add it to our array
-    *fSorted.insert(index) = elem;
-    // update our hash table (overwrites any dupe's position in the hash)
-    fHash[hash2Index(key.getHash())] = elem;
-    return first;
-}
-
-template <typename T, typename Key, size_t kHashBits>
-void GrTHashTable<T, Key, kHashBits>::remove(const Key& key, const T* elem) {
-    int index = hash2Index(key.getHash());
-    if (fHash[index] == elem) {
-        fHash[index] = NULL;
-    }
-
-    // remove from our sorted array
-    index = this->searchArray(key);
-    SkASSERT(index >= 0);
-    // if there are multiple matches searchArray will give us the first match
-    // march forward until we find elem.
-    while (elem != fSorted[index]) {
-        ++index;
-        SkASSERT(index < fSorted.count());
-    }
-    SkASSERT(elem == fSorted[index]);
-    fSorted.remove(index);
-}
-
-template <typename T, typename Key, size_t kHashBits>
-void GrTHashTable<T, Key, kHashBits>::deleteAll() {
-    fSorted.deleteAll();
-    this->clearHash();
-}
-
-#ifdef SK_DEBUG
-template <typename T, typename Key, size_t kHashBits>
-void GrTHashTable<T, Key, kHashBits>::validate() const {
-    int count = fSorted.count();
-    for (int i = 1; i < count; i++) {
-        SkASSERT(Key::LessThan(*fSorted[i - 1], *fSorted[i]) ||
-                 Key::Equals(*fSorted[i - 1], *fSorted[i]));
-    }
-}
-
-template <typename T, typename Key, size_t kHashBits>
-bool GrTHashTable<T, Key, kHashBits>::contains(T* elem) const {
-    int index = fSorted.find(elem);
-    return index >= 0;
-}
-
-#endif
-
-#endif
diff --git a/src/gpu/GrTemplates.h b/src/gpu/GrTemplates.h
index 2cab132..8e43a15 100644
--- a/src/gpu/GrTemplates.h
+++ b/src/gpu/GrTemplates.h
@@ -41,20 +41,20 @@
 
     GrAutoTRestore(T* ptr) {
         fPtr = ptr;
-        if (NULL != ptr) {
+        if (ptr) {
             fVal = *ptr;
         }
     }
 
     ~GrAutoTRestore() {
-        if (NULL != fPtr) {
+        if (fPtr) {
             *fPtr = fVal;
         }
     }
 
     // restores previously saved value (if any) and saves value for passed T*
     void reset(T* ptr) {
-        if (NULL != fPtr) {
+        if (fPtr) {
             *fPtr = fVal;
         }
         fPtr = ptr;
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index bc11671..d281173 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -10,7 +10,7 @@
 
 #include "SkAutoKern.h"
 #include "SkGlyphCache.h"
-#include "SkGr.h"
+#include "GrFontScaler.h"
 
 GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) :
                             fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) {
@@ -69,7 +69,7 @@
         scaler = (GrFontScaler*)auxData;
     }
     if (NULL == scaler) {
-        scaler = SkNEW_ARGS(SkGrFontScaler, (cache));
+        scaler = SkNEW_ARGS(GrFontScaler, (cache));
         cache->setAuxProc(GlyphCacheAuxProc, scaler);
     }
 
diff --git a/src/gpu/GrTextStrike.cpp b/src/gpu/GrTextStrike.cpp
index b03d14f..fa97f73 100644
--- a/src/gpu/GrTextStrike.cpp
+++ b/src/gpu/GrTextStrike.cpp
@@ -32,16 +32,20 @@
 GrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) {
     gpu->ref();
     for (int i = 0; i < kAtlasCount; ++i) {
-        fAtlasMgr[i] = NULL;
+        fAtlases[i] = NULL;
     }
 
     fHead = fTail = NULL;
 }
 
 GrFontCache::~GrFontCache() {
-    fCache.deleteAll();
+    SkTDynamicHash<GrTextStrike, GrFontDescKey>::Iter iter(&fCache);
+    while (!iter.done()) {
+        SkDELETE(&(*iter));
+        ++iter;
+    }
     for (int i = 0; i < kAtlasCount; ++i) {
-        delete fAtlasMgr[i];
+        delete fAtlases[i];
     }
     fGpu->unref();
 #if FONT_CACHE_STATS
@@ -74,23 +78,22 @@
     return sAtlasIndices[format];
 }
 
-GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
-                                          const Key& key) {
+GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler) {
     GrMaskFormat format = scaler->getMaskFormat();
     GrPixelConfig config = mask_format_to_pixel_config(format);
     int atlasIndex = mask_format_to_atlas_index(format);
-    if (NULL == fAtlasMgr[atlasIndex]) {
+    if (NULL == fAtlases[atlasIndex]) {
         SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH,
                                             GR_ATLAS_TEXTURE_HEIGHT);
-        fAtlasMgr[atlasIndex] = SkNEW_ARGS(GrAtlasMgr, (fGpu, config,
-                                                        textureSize,
-                                                        GR_NUM_PLOTS_X,
-                                                        GR_NUM_PLOTS_Y,
-                                                        true));
+        fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrTextureFlags,
+                                                    textureSize,
+                                                    GR_NUM_PLOTS_X,
+                                                    GR_NUM_PLOTS_Y,
+                                                    true));
     }
     GrTextStrike* strike = SkNEW_ARGS(GrTextStrike,
-                                      (this, scaler->getKey(), format, fAtlasMgr[atlasIndex]));
-    fCache.insert(key, strike);
+                                      (this, scaler->getKey(), format, fAtlases[atlasIndex]));
+    fCache.add(strike);
 
     if (fHead) {
         fHead->fPrev = strike;
@@ -106,27 +109,31 @@
 }
 
 void GrFontCache::freeAll() {
-    fCache.deleteAll();
+    SkTDynamicHash<GrTextStrike, GrFontDescKey>::Iter iter(&fCache);
+    while (!iter.done()) {
+        SkDELETE(&(*iter));
+        ++iter;
+    }
+    fCache.rewind();
     for (int i = 0; i < kAtlasCount; ++i) {
-        delete fAtlasMgr[i];
-        fAtlasMgr[i] = NULL;
+        delete fAtlases[i];
+        fAtlases[i] = NULL;
     }
     fHead = NULL;
     fTail = NULL;
 }
 
 void GrFontCache::purgeStrike(GrTextStrike* strike) {
-    const GrFontCache::Key key(strike->fFontScalerKey);
-    fCache.remove(key, strike);
+    fCache.remove(*(strike->fFontScalerKey));
     this->detachStrikeFromList(strike);
     delete strike;
 }
 
 bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) {
-    SkASSERT(NULL != preserveStrike);
+    SkASSERT(preserveStrike);
 
-    GrAtlasMgr* atlasMgr = preserveStrike->fAtlasMgr;
-    GrPlot* plot = atlasMgr->getUnusedPlot();
+    GrAtlas* atlas = preserveStrike->fAtlas;
+    GrPlot* plot = atlas->getUnusedPlot();
     if (NULL == plot) {
         return false;
     }
@@ -145,7 +152,7 @@
         strikeToPurge->removePlot(plot);
 
         // clear out any empty strikes (except this one)
-        if (strikeToPurge != preserveStrike && strikeToPurge->fAtlas.isEmpty()) {
+        if (strikeToPurge != preserveStrike && strikeToPurge->fPlotUsage.isEmpty()) {
             this->purgeStrike(strikeToPurge);
         }
     }
@@ -190,9 +197,9 @@
 void GrFontCache::dump() const {
     static int gDumpCount = 0;
     for (int i = 0; i < kAtlasCount; ++i) {
-        if (NULL != fAtlasMgr[i]) {
-            GrTexture* texture = fAtlasMgr[i]->getTexture();
-            if (NULL != texture) {
+        if (fAtlases[i]) {
+            GrTexture* texture = fAtlases[i]->getTexture();
+            if (texture) {
                 SkString filename;
 #ifdef SK_BUILD_FOR_ANDROID
                 filename.printf("/sdcard/fontcache_%d%d.png", gDumpCount, i);
@@ -220,14 +227,14 @@
     atlas and a position within that texture.
  */
 
-GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
+GrTextStrike::GrTextStrike(GrFontCache* cache, const GrFontDescKey* key,
                            GrMaskFormat format,
-                           GrAtlasMgr* atlasMgr) : fPool(64) {
+                           GrAtlas* atlas) : fPool(64) {
     fFontScalerKey = key;
     fFontScalerKey->ref();
 
     fFontCache = cache;     // no need to ref, it won't go away before we do
-    fAtlasMgr = atlasMgr;   // no need to ref, it won't go away before we do
+    fAtlas = atlas;         // no need to ref, it won't go away before we do
 
     fMaskFormat = format;
 
@@ -237,13 +244,13 @@
 #endif
 }
 
-// this signature is needed because it's used with
-// SkTDArray::visitAll() (see destructor)
-static void free_glyph(GrGlyph*& glyph) { glyph->free(); }
-
 GrTextStrike::~GrTextStrike() {
     fFontScalerKey->unref();
-    fCache.getArray().visitAll(free_glyph);
+    SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache);
+    while (!iter.done()) {
+        (*iter).free();
+        ++iter;
+    }
 
 #ifdef SK_DEBUG
     gCounter -= 1;
@@ -266,21 +273,35 @@
 
     GrGlyph* glyph = fPool.alloc();
     glyph->init(packed, bounds);
-    fCache.insert(packed, glyph);
+    fCache.add(glyph);
     return glyph;
 }
 
 void GrTextStrike::removePlot(const GrPlot* plot) {
-    SkTDArray<GrGlyph*>& glyphArray = fCache.getArray();
-    for (int i = 0; i < glyphArray.count(); ++i) {
-        if (plot == glyphArray[i]->fPlot) {
-            glyphArray[i]->fPlot = NULL;
+    SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache);
+    while (!iter.done()) {
+        if (plot == (*iter).fPlot) {
+            (*iter).fPlot = NULL;
         }
+        ++iter;
     }
 
-    fAtlasMgr->removePlot(&fAtlas, plot);
+    GrAtlas::RemovePlot(&fPlotUsage, plot);
 }
 
+bool GrTextStrike::glyphTooLargeForAtlas(GrGlyph* glyph) {
+    int width = glyph->fBounds.width();
+    int height = glyph->fBounds.height();
+    int pad = fUseDistanceField ? 2 * SK_DistanceFieldPad : 0;
+    if (width + pad > GR_PLOT_WIDTH) {
+        return true;
+    }
+    if (height + pad > GR_PLOT_HEIGHT) {
+        return true;
+    }
+
+    return false;
+}
 
 bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
 #if 0   // testing hack to force us to flush our cache often
@@ -290,15 +311,16 @@
 
     SkASSERT(glyph);
     SkASSERT(scaler);
-    SkASSERT(fCache.contains(glyph));
+    SkASSERT(fCache.find(glyph->fPackedID));
     SkASSERT(NULL == glyph->fPlot);
 
-    SkAutoRef ar(scaler);
+    SkAutoUnref ar(SkSafeRef(scaler));
 
     int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
 
     size_t size = glyph->fBounds.area() * bytesPerPixel;
-    SkAutoSMalloc<1024> storage(size);
+    GrAutoMalloc<1024> storage(size);
+
     if (fUseDistanceField) {
         if (!scaler->getPackedGlyphDFImage(glyph->fPackedID, glyph->width(),
                                            glyph->height(),
@@ -314,9 +336,9 @@
         }
     }
 
-    GrPlot* plot  = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(),
-                                          glyph->height(), storage.get(),
-                                          &glyph->fAtlasLocation);
+    GrPlot* plot  = fAtlas->addToAtlas(&fPlotUsage, glyph->width(),
+                                       glyph->height(), storage.get(),
+                                       &glyph->fAtlasLocation);
 
     if (NULL == plot) {
         return false;
diff --git a/src/gpu/GrTextStrike.h b/src/gpu/GrTextStrike.h
index 955eb7f..401bd73 100644
--- a/src/gpu/GrTextStrike.h
+++ b/src/gpu/GrTextStrike.h
@@ -13,7 +13,7 @@
 
 #include "GrAllocPool.h"
 #include "GrFontScaler.h"
-#include "GrTHashTable.h"
+#include "SkTDynamicHash.h"
 #include "GrGlyph.h"
 #include "GrDrawTarget.h"
 #include "GrAtlas.h"
@@ -28,42 +28,50 @@
  */
 class GrTextStrike {
 public:
-    GrTextStrike(GrFontCache*, const GrKey* fontScalerKey, GrMaskFormat, GrAtlasMgr*);
+    GrTextStrike(GrFontCache*, const GrFontDescKey* fontScalerKey, GrMaskFormat, GrAtlas*);
     ~GrTextStrike();
 
-    const GrKey* getFontScalerKey() const { return fFontScalerKey; }
+    const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; }
     GrFontCache* getFontCache() const { return fFontCache; }
     GrMaskFormat getMaskFormat() const { return fMaskFormat; }
+    GrTexture*   getTexture() const { return fAtlas->getTexture(); }
 
     inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
+    // returns true if glyph (or glyph+padding for distance field)
+    // is too large to ever fit in texture atlas subregions (GrPlots)
+    bool glyphTooLargeForAtlas(GrGlyph*);
+    // returns true if glyph successfully added to texture atlas, false otherwise
     bool addGlyphToAtlas(GrGlyph*, GrFontScaler*);
 
     // testing
-    int countGlyphs() const { return fCache.getArray().count(); }
-    const GrGlyph* glyphAt(int index) const {
-        return fCache.getArray()[index];
-    }
+    int countGlyphs() const { return fCache.count(); }
 
     // remove any references to this plot
     void removePlot(const GrPlot* plot);
 
+    static const GrFontDescKey& GetKey(const GrTextStrike& ts) {
+        return *(ts.fFontScalerKey);
+    }
+    static uint32_t Hash(const GrFontDescKey& key) {
+        return key.getHash();
+    }
+
 public:
     // for easy removal from list
     GrTextStrike*   fPrev;
     GrTextStrike*   fNext;
 
 private:
-    class Key;
-    GrTHashTable<GrGlyph, Key, 7> fCache;
-    const GrKey* fFontScalerKey;
+    SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache;
+    const GrFontDescKey* fFontScalerKey;
     GrTAllocPool<GrGlyph> fPool;
 
     GrFontCache*    fFontCache;
-    GrAtlasMgr*     fAtlasMgr;
+    GrAtlas*        fAtlas;
     GrMaskFormat    fMaskFormat;
     bool            fUseDistanceField;
 
-    GrAtlas         fAtlas;
+    GrAtlas::ClientPlotUsage fPlotUsage;
 
     GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
 
@@ -83,16 +91,13 @@
     bool freeUnusedPlot(GrTextStrike* preserveStrike);
 
     // testing
-    int countStrikes() const { return fCache.getArray().count(); }
-    const GrTextStrike* strikeAt(int index) const {
-        return fCache.getArray()[index];
-    }
+    int countStrikes() const { return fCache.count(); }
     GrTextStrike* getHeadStrike() const { return fHead; }
 
     void updateTextures() {
         for (int i = 0; i < kAtlasCount; ++i) {
-            if (fAtlasMgr[i]) {
-                fAtlasMgr[i]->uploadPlotsToTexture();
+            if (fAtlases[i]) {
+                fAtlases[i]->uploadPlotsToTexture();
             }
         }
     }
@@ -117,16 +122,15 @@
 private:
     friend class GrFontPurgeListener;
 
-    class Key;
-    GrTHashTable<GrTextStrike, Key, 8> fCache;
+    SkTDynamicHash<GrTextStrike, GrFontDescKey> fCache;
     // for LRU
     GrTextStrike* fHead;
     GrTextStrike* fTail;
 
     GrGpu*      fGpu;
-    GrAtlasMgr* fAtlasMgr[kAtlasCount];
+    GrAtlas*    fAtlases[kAtlasCount];
 
-    GrTextStrike* generateStrike(GrFontScaler*, const Key&);
+    GrTextStrike* generateStrike(GrFontScaler*);
     inline void detachStrikeFromList(GrTextStrike*);
     void purgeStrike(GrTextStrike* strike);
 };
diff --git a/src/gpu/GrTextStrike_impl.h b/src/gpu/GrTextStrike_impl.h
index dcfc04a..db1bf27 100644
--- a/src/gpu/GrTextStrike_impl.h
+++ b/src/gpu/GrTextStrike_impl.h
@@ -11,25 +11,6 @@
 #ifndef GrTextStrike_impl_DEFINED
 #define GrTextStrike_impl_DEFINED
 
-class GrFontCache::Key {
-public:
-    explicit Key(const GrKey* fontScalarKey) {
-        fFontScalerKey = fontScalarKey;
-    }
-
-    intptr_t getHash() const { return fFontScalerKey->getHash(); }
-
-    static bool LessThan(const GrTextStrike& strike, const Key& key) {
-        return *strike.getFontScalerKey() < *key.fFontScalerKey;
-    }
-    static bool Equals(const GrTextStrike& strike, const Key& key) {
-        return *strike.getFontScalerKey() == *key.fFontScalerKey;
-    }
-
-private:
-    const GrKey* fFontScalerKey;
-};
-
 void GrFontCache::detachStrikeFromList(GrTextStrike* strike) {
     if (strike->fPrev) {
         SkASSERT(fHead != strike);
@@ -51,10 +32,9 @@
 GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler, bool useDistanceField) {
     this->validate();
 
-    const Key key(scaler->getKey());
-    GrTextStrike* strike = fCache.find(key);
+    GrTextStrike* strike = fCache.find(*(scaler->getKey()));
     if (NULL == strike) {
-        strike = this->generateStrike(scaler, key);
+        strike = this->generateStrike(scaler);
     } else if (strike->fPrev) {
         // Need to put the strike at the head of its dllist, since that is how
         // we age the strikes for purging (we purge from the back of the list)
@@ -72,27 +52,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-/**
- *  This Key just wraps a glyphID, and matches the protocol need for
- *  GrTHashTable
- */
-class GrTextStrike::Key {
-public:
-    Key(GrGlyph::PackedID id) : fPackedID(id) {}
-
-    uint32_t getHash() const { return fPackedID; }
-
-    static bool LessThan(const GrGlyph& glyph, const Key& key) {
-        return glyph.fPackedID < key.fPackedID;
-    }
-    static bool Equals(const GrGlyph& glyph, const Key& key) {
-        return glyph.fPackedID == key.fPackedID;
-    }
-
-private:
-    GrGlyph::PackedID fPackedID;
-};
-
 GrGlyph* GrTextStrike::getGlyph(GrGlyph::PackedID packed,
                                 GrFontScaler* scaler) {
     GrGlyph* glyph = fCache.find(packed);
diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp
index 4f95730..667ddd1 100644
--- a/src/gpu/GrTexture.cpp
+++ b/src/gpu/GrTexture.cpp
@@ -16,7 +16,7 @@
 #include "GrResourceCache.h"
 
 GrTexture::~GrTexture() {
-    if (NULL != fRenderTarget.get()) {
+    if (fRenderTarget.get()) {
         fRenderTarget.get()->owningTextureDestroyed();
     }
 }
@@ -27,9 +27,9 @@
  */
 void GrTexture::internal_dispose() const {
     if (this->impl()->isSetFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit) &&
-        NULL != this->INHERITED::getContext()) {
+        this->INHERITED::getContext()) {
         GrTexture* nonConstThis = const_cast<GrTexture *>(this);
-        this->fRefCnt = 1;      // restore ref count to initial setting
+        this->ref(); // restore ref count to initial setting
 
         nonConstThis->impl()->resetFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit);
         nonConstThis->INHERITED::getContext()->addExistingTextureToCache(nonConstThis);
@@ -39,7 +39,6 @@
         return;
     }
 
-    SkASSERT(0 == this->getDeferredRefCount());
     this->INHERITED::internal_dispose();
 }
 
@@ -59,26 +58,12 @@
 }
 
 size_t GrTexture::gpuMemorySize() const {
-    size_t textureSize =  (size_t) fDesc.fWidth *
-                                   fDesc.fHeight *
-                                   GrBytesPerPixel(fDesc.fConfig);
+    size_t textureSize;
 
     if (GrPixelConfigIsCompressed(fDesc.fConfig)) {
-        // Figure out the width and height corresponding to the data...
-
-        // Both of the available formats (ETC1 and LATC) have 4x4
-        // blocks that compress down to 8 bytes.
-        switch(fDesc.fConfig) {
-            case kETC1_GrPixelConfig:
-            case kLATC_GrPixelConfig:
-                SkASSERT((fDesc.fWidth & 3) == 0);
-                SkASSERT((fDesc.fHeight & 3) == 0);
-                textureSize = (fDesc.fWidth >> 2) * (fDesc.fHeight >> 2) * 8;
-                break;
-
-            default:
-                SkFAIL("Unknown compressed config");
-        }
+        textureSize = GrCompressedFormatDataSize(fDesc.fConfig, fDesc.fWidth, fDesc.fHeight);
+    } else {
+        textureSize = (size_t) fDesc.fWidth * fDesc.fHeight * GrBytesPerPixel(fDesc.fConfig);
     }
 
     if (this->impl()->hasMipMaps()) {
@@ -117,24 +102,39 @@
                                 pixelOpsFlags);
 }
 
+void GrTexture::abandonReleaseCommon() {
+    // In debug builds the resource cache tracks removed/exclusive textures and has an unref'ed ptr.
+    // After abandon() or release() the resource cache will be unreachable (getContext() == NULL).
+    // So we readd the texture to the cache here so that it is removed from the exclusive list and
+    // there is no longer an unref'ed ptr to the texture in the cache.
+    if (this->impl()->isSetFlag((GrTextureFlags)GrTextureImpl::kReturnToCache_FlagBit)) {
+        SkASSERT(!this->wasDestroyed());
+        this->ref();  // restores the ref the resource cache gave up when it marked this exclusive.
+        this->impl()->resetFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit);
+        this->getContext()->addExistingTextureToCache(this);
+    }
+}
+
 void GrTexture::onRelease() {
+    this->abandonReleaseCommon();
     SkASSERT(!this->impl()->isSetFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit));
     INHERITED::onRelease();
 }
 
 void GrTexture::onAbandon() {
-    if (NULL != fRenderTarget.get()) {
+    this->abandonReleaseCommon();
+    if (fRenderTarget.get()) {
         fRenderTarget->abandon();
     }
     INHERITED::onAbandon();
 }
 
 void GrTexture::validateDesc() const {
-    if (NULL != this->asRenderTarget()) {
+    if (this->asRenderTarget()) {
         // This texture has a render target
         SkASSERT(0 != (fDesc.fFlags & kRenderTarget_GrTextureFlagBit));
 
-        if (NULL != this->asRenderTarget()->getStencilBuffer()) {
+        if (this->asRenderTarget()->getStencilBuffer()) {
             SkASSERT(0 != (fDesc.fFlags & kNoStencil_GrTextureFlagBit));
         } else {
             SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrTextureFlagBit));
@@ -170,7 +170,7 @@
                                                const GrTextureParams* params,
                                                const GrTextureDesc& desc) {
     GrResourceKey::ResourceFlags flags = 0;
-    bool tiled = NULL != params && params->isTiled();
+    bool tiled = params && params->isTiled();
     if (tiled && !gpu->caps()->npotTextureTileSupport()) {
         if (!SkIsPow2(desc.fWidth) || !SkIsPow2(desc.fHeight)) {
             flags |= kStretchToPOT_TextureFlag;
@@ -207,6 +207,11 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
+GrTextureImpl::GrTextureImpl(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
+    : INHERITED(gpu, isWrapped, desc)
+    , fMipMapsStatus(kNotAllocated_MipMapsStatus) {
+    this->setScratchKey(ComputeScratchKey(desc));
+}
 
 GrResourceKey GrTextureImpl::ComputeKey(const GrGpu* gpu,
                                     const GrTextureParams* params,
diff --git a/src/gpu/GrTextureAccess.cpp b/src/gpu/GrTextureAccess.cpp
index 91db08b..662ccd6 100644
--- a/src/gpu/GrTextureAccess.cpp
+++ b/src/gpu/GrTextureAccess.cpp
@@ -42,11 +42,11 @@
 void GrTextureAccess::reset(GrTexture* texture,
                             const char* swizzle,
                             const GrTextureParams& params) {
-    SkASSERT(NULL != texture);
+    SkASSERT(texture);
     SkASSERT(strlen(swizzle) >= 1 && strlen(swizzle) <= 4);
 
     fParams = params;
-    fTexture.reset(SkRef(texture));
+    fTexture.set(SkRef(texture), GrIORef::kRead_IOType);
     this->setSwizzle(swizzle);
 }
 
@@ -54,18 +54,18 @@
                             const char* swizzle,
                             GrTextureParams::FilterMode filterMode,
                             SkShader::TileMode tileXAndY) {
-    SkASSERT(NULL != texture);
+    SkASSERT(texture);
     SkASSERT(strlen(swizzle) >= 1 && strlen(swizzle) <= 4);
 
     fParams.reset(tileXAndY, filterMode);
-    fTexture.reset(SkRef(texture));
+    fTexture.set(SkRef(texture), GrIORef::kRead_IOType);
     this->setSwizzle(swizzle);
 }
 
 void GrTextureAccess::reset(GrTexture* texture,
                             const GrTextureParams& params) {
-    SkASSERT(NULL != texture);
-    fTexture.reset(SkRef(texture));
+    SkASSERT(texture);
+    fTexture.set(SkRef(texture), GrIORef::kRead_IOType);
     fParams = params;
     memcpy(fSwizzle, "rgba", 5);
     fSwizzleMask = kRGBA_GrColorComponentFlags;
@@ -74,8 +74,8 @@
 void GrTextureAccess::reset(GrTexture* texture,
                             GrTextureParams::FilterMode filterMode,
                             SkShader::TileMode tileXAndY) {
-    SkASSERT(NULL != texture);
-    fTexture.reset(SkRef(texture));
+    SkASSERT(texture);
+    fTexture.set(SkRef(texture), GrIORef::kRead_IOType);
     fParams.reset(tileXAndY, filterMode);
     memcpy(fSwizzle, "rgba", 5);
     fSwizzleMask = kRGBA_GrColorComponentFlags;
diff --git a/src/gpu/GrTraceMarker.cpp b/src/gpu/GrTraceMarker.cpp
index 11cdd5e..bc6d456 100644
--- a/src/gpu/GrTraceMarker.cpp
+++ b/src/gpu/GrTraceMarker.cpp
@@ -39,6 +39,21 @@
     return this->fMarkerArray.count();
 }
 
+SkString GrTraceMarkerSet::toStringLast() const {
+    const int numMarkers = this->fMarkerArray.count();
+    SkString marker_string;
+    if (numMarkers > 0) {
+        GrGpuTraceMarker& lastMarker = this->fMarkerArray[numMarkers - 1];
+        marker_string.append(lastMarker.fMarker);
+        if (lastMarker.fID != -1) {
+            marker_string.append("(");
+            marker_string.appendS32(lastMarker.fID);
+            marker_string.append(")");
+        }
+    }
+    return marker_string;
+}
+
 SkString GrTraceMarkerSet::toString() const {
     SkTQSort<GrGpuTraceMarker>(this->fMarkerArray.begin(), this->fMarkerArray.end() - 1);
     SkString marker_string;
@@ -57,12 +72,14 @@
         GrGpuTraceMarker& currMarker = this->fMarkerArray[i];
         const char* currCmd = currMarker.fMarker;
         if (currCmd != prevMarkerName) {
-            if (counter != 0) {
+            if (prevMarkerID != -1) {
                 marker_string.append(") ");
             }
             marker_string.append(currCmd);
-            marker_string.append("(");
-            marker_string.appendS32(currMarker.fID);
+            if (currMarker.fID != -1) {
+                marker_string.append("(");
+                marker_string.appendS32(currMarker.fID);
+            }
             prevMarkerName = currCmd;
         } else if (currMarker.fID != prevMarkerID) {
             marker_string.append(", ");
@@ -71,7 +88,7 @@
         prevMarkerID = currMarker.fID;
         ++counter;
     }
-    if (counter > 0) {
+    if (counter > 0 && prevMarkerID != -1) {
         marker_string.append(")");
     }
     return marker_string;
diff --git a/src/gpu/GrTraceMarker.h b/src/gpu/GrTraceMarker.h
index fa4904e..4ecda2c 100644
--- a/src/gpu/GrTraceMarker.h
+++ b/src/gpu/GrTraceMarker.h
@@ -55,6 +55,8 @@
      */
     SkString toString() const;
 
+    SkString toStringLast() const;
+
     class Iter;
 
     Iter begin() const;
diff --git a/src/gpu/GrTracing.h b/src/gpu/GrTracing.h
index 311042f..3327e2c 100644
--- a/src/gpu/GrTracing.h
+++ b/src/gpu/GrTracing.h
@@ -66,43 +66,61 @@
  * cpu and gpu (if gpu tracing enabled) for the current scope.
  * marker is of type const char* and target is of type GrDrawTarget*
  */
-#define GR_CREATE_TRACE_MARKER(name, target)                              \
-    static const char* SK_MACRO_APPEND_LINE(static_name) = name;          \
-    static int SK_MACRO_APPEND_LINE(name_counter) = 0;                    \
-    INTERNAL_GR_CREATE_TRACE_MARKER(SK_MACRO_APPEND_LINE(static_name),    \
-                                    SK_MACRO_APPEND_LINE(name_counter),   \
-                                    target)                               \
-    sk_atomic_inc(&SK_MACRO_APPEND_LINE(name_counter));                   \
+#define GR_CREATE_TRACE_MARKER(name, target)                                      \
+    INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED(name, target)                          
 
-#define INTERNAL_GR_CREATE_TRACE_MARKER(name, name_counter, target)       \
-    GR_CREATE_GPU_TRACE_MARKER(name, name_counter, target)                \
-    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),name,              \
-                 "id", name_counter)                                      \
+#define GR_CREATE_TRACE_MARKER1(name, target, arg1_name, arg1_val)                \
+    INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED(name, target, arg1_name, arg1_val)     
 
-#define GR_CREATE_GPU_TRACE_MARKER(name, name_counter, target)            \
-    GrGpuTraceMarkerGenerator SK_MACRO_APPEND_LINE(TMG)(target);          \
-    if (target->isGpuTracingEnabled()) {                                  \
-        SK_MACRO_APPEND_LINE(TMG).initialize(name, &name_counter);        \
-    }                                                                     \
+#define INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED(name, target, ...)                 \
+    static const char* SK_MACRO_APPEND_LINE(static_name) = name;                  \
+    static int SK_MACRO_APPEND_LINE(name_counter) = 0;                            \
+    INTERNAL_GR_CREATE_TRACE_MARKER(SK_MACRO_APPEND_LINE(static_name),            \
+                                    SK_MACRO_APPEND_LINE(name_counter),           \
+                                    target, ##__VA_ARGS__)                        \
+    sk_atomic_inc(&SK_MACRO_APPEND_LINE(name_counter));                           
 
-#define GR_CREATE_TRACE_MARKER_CONTEXT(name, context)                     \
-    static const char* SK_MACRO_APPEND_LINE(static_name) = name;          \
-    static int SK_MACRO_APPEND_LINE(name_counter) = 0;                    \
-    INTERNAL_GR_CREATE_TRACE_MARKER_C(SK_MACRO_APPEND_LINE(static_name),  \
-                                    SK_MACRO_APPEND_LINE(name_counter),   \
-                                    context)                              \
-    sk_atomic_inc(&SK_MACRO_APPEND_LINE(name_counter));                   \
+#define INTERNAL_GR_CREATE_TRACE_MARKER(name, name_counter, target, ...)          \
+    GR_CREATE_GPU_TRACE_MARKER(name, name_counter, target)                        \
+    INTERNAL_TRACE_EVENT_ADD_SCOPED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),name,   \
+                       "id", name_counter, ##__VA_ARGS__);                        
 
-#define INTERNAL_GR_CREATE_TRACE_MARKER_C(name, name_counter, context)    \
-    GR_CREATE_GPU_TRACE_MARKER_C(name, name_counter, context)             \
-    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),name,              \
-                 "id", name_counter)                                      \
+#define GR_CREATE_GPU_TRACE_MARKER(name, name_counter, target)                     \
+    GrGpuTraceMarkerGenerator SK_MACRO_APPEND_LINE(TMG)(target);                   \
+    bool SK_MACRO_APPEND_LINE(gpuTracingEnabled);                                  \
+    TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),      \
+                                        &SK_MACRO_APPEND_LINE(gpuTracingEnabled)); \
+    if (SK_MACRO_APPEND_LINE(gpuTracingEnabled)) {                                 \
+        SK_MACRO_APPEND_LINE(TMG).initialize(name, &name_counter);                 \
+    }                                                                             
 
-#define GR_CREATE_GPU_TRACE_MARKER_C(name, name_counter, context)         \
-    GrGpuTraceMarkerGeneratorContext SK_MACRO_APPEND_LINE(TMG)(context);  \
-    if (context->isGpuTracingEnabled()) {                                 \
-        SK_MACRO_APPEND_LINE(TMG).initialize(name, &name_counter);        \
-    }                                                                     \
 
+#define GR_CREATE_TRACE_MARKER_CONTEXT(name, context)                             \
+    INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED_C(name, context)                       
+
+#define GR_CREATE_TRACE_MARKER_CONTEXT1(name, context, arg1_name, arg1_val)       \
+    INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED_C(name, context, arg1_name, arg1_val)  
+
+#define INTERNAL_GR_CREATE_TRACE_MARKER_SCOPED_C(name, context, ...)              \
+    static const char* SK_MACRO_APPEND_LINE(static_name) = name;                  \
+    static int SK_MACRO_APPEND_LINE(name_counter) = 0;                            \
+    INTERNAL_GR_CREATE_TRACE_MARKER_C(SK_MACRO_APPEND_LINE(static_name),          \
+                                      SK_MACRO_APPEND_LINE(name_counter),         \
+                                      context, ##__VA_ARGS__)                     \
+    sk_atomic_inc(&SK_MACRO_APPEND_LINE(name_counter));                           
+
+#define INTERNAL_GR_CREATE_TRACE_MARKER_C(name, name_counter, context, ...)       \
+    GR_CREATE_GPU_TRACE_MARKER_C(name, name_counter, context)                     \
+    INTERNAL_TRACE_EVENT_ADD_SCOPED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),name,   \
+                                    "id", name_counter, ##__VA_ARGS__);                        
+
+#define GR_CREATE_GPU_TRACE_MARKER_C(name, name_counter, context)                  \
+    GrGpuTraceMarkerGeneratorContext SK_MACRO_APPEND_LINE(TMG)(context);           \
+    bool SK_MACRO_APPEND_LINE(gpuTracingEnabled);                                  \
+    TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"),      \
+                                        &SK_MACRO_APPEND_LINE(gpuTracingEnabled)); \
+    if (SK_MACRO_APPEND_LINE(gpuTracingEnabled)) {                                 \
+        SK_MACRO_APPEND_LINE(TMG).initialize(name, &name_counter);                 \
+    }                                                                             
 
 #endif
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index d0c32eb..b647613 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -16,7 +16,9 @@
 #include "GrBitmapTextContext.h"
 #include "GrDistanceFieldTextContext.h"
 #include "GrLayerCache.h"
+#include "GrLayerHoister.h"
 #include "GrPictureUtils.h"
+#include "GrRecordReplaceDraw.h"
 #include "GrStrokeInfo.h"
 #include "GrTracing.h"
 
@@ -29,15 +31,19 @@
 #include "SkMaskFilter.h"
 #include "SkPathEffect.h"
 #include "SkPicture.h"
-#include "SkPicturePlayback.h"
+#include "SkPictureData.h"
+#include "SkRecord.h"
 #include "SkRRect.h"
 #include "SkStroke.h"
 #include "SkSurface.h"
 #include "SkTLazy.h"
 #include "SkUtils.h"
 #include "SkVertState.h"
+#include "SkXfermode.h"
 #include "SkErrorInternals.h"
 
+enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
+
 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1
 
 #if 0
@@ -84,12 +90,12 @@
                         GrTexture** texture)
         : fDevice(NULL)
         , fTexture(NULL) {
-        SkASSERT(NULL != texture);
+        SkASSERT(texture);
         *texture = this->set(device, bitmap, params);
     }
 
     ~SkAutoCachedTexture() {
-        if (NULL != fTexture) {
+        if (fTexture) {
             GrUnlockAndUnrefCachedBitmapTexture(fTexture);
         }
     }
@@ -97,7 +103,7 @@
     GrTexture* set(SkGpuDevice* device,
                    const SkBitmap& bitmap,
                    const GrTextureParams* params) {
-        if (NULL != fTexture) {
+        if (fTexture) {
             GrUnlockAndUnrefCachedBitmapTexture(fTexture);
             fTexture = NULL;
         }
@@ -127,91 +133,56 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-/*
- * GrRenderTarget does not know its opaqueness, only its config, so we have
- * to make conservative guesses when we return an "equivalent" bitmap.
- */
-static SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) {
-    SkBitmap bitmap;
-    bitmap.setInfo(renderTarget->info());
-    return bitmap;
-}
-
-SkGpuDevice* SkGpuDevice::Create(GrSurface* surface, unsigned flags) {
-    SkASSERT(NULL != surface);
-    if (NULL == surface->asRenderTarget() || NULL == surface->getContext()) {
+SkGpuDevice* SkGpuDevice::Create(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) {
+    SkASSERT(surface);
+    if (NULL == surface->asRenderTarget() || surface->wasDestroyed()) {
         return NULL;
     }
-    if (surface->asTexture()) {
-        return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asTexture(), flags));
-    } else {
-        return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asRenderTarget(), flags));
-    }
+    return SkNEW_ARGS(SkGpuDevice, (surface, props, flags));
 }
 
-SkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture, unsigned flags)
-    : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) {
-    this->initFromRenderTarget(context, texture->asRenderTarget(), flags);
-}
+SkGpuDevice::SkGpuDevice(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) {
 
-SkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget, unsigned flags)
-    : SkBitmapDevice(make_bitmap(context, renderTarget)) {
-    this->initFromRenderTarget(context, renderTarget, flags);
-}
-
-void SkGpuDevice::initFromRenderTarget(GrContext* context,
-                                       GrRenderTarget* renderTarget,
-                                       unsigned flags) {
     fDrawProcs = NULL;
 
-    fContext = context;
-    fContext->ref();
+    fContext = SkRef(surface->getContext());
 
-    bool useDFFonts = !!(flags & kDFFonts_Flag);
-    fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyProperties,
-                                                               useDFFonts));
-    fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties));
-
-    fRenderTarget = NULL;
     fNeedClear = flags & kNeedClear_Flag;
 
-    SkASSERT(NULL != renderTarget);
-    fRenderTarget = renderTarget;
-    fRenderTarget->ref();
-
-    // Hold onto to the texture in the pixel ref (if there is one) because the texture holds a ref
-    // on the RT but not vice-versa.
-    // TODO: Remove this trickery once we figure out how to make SkGrPixelRef do this without
-    // busting chrome (for a currently unknown reason).
-    GrSurface* surface = fRenderTarget->asTexture();
-    if (NULL == surface) {
-        surface = fRenderTarget;
-    }
+    fRenderTarget = SkRef(surface->asRenderTarget());
 
     SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef,
                                 (surface->info(), surface, SkToBool(flags & kCached_Flag)));
+    fLegacyBitmap.setInfo(surface->info());
+    fLegacyBitmap.setPixelRef(pr)->unref();
 
-    this->setPixelRef(pr)->unref();
+    this->setPixelGeometry(props.pixelGeometry());
+
+    bool useDFFonts = !!(flags & kDFFonts_Flag);
+    fMainTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFFonts);
+    fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, this->getLeakyProperties()));
 }
 
 SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo,
-                                 int sampleCount) {
+                                 const SkSurfaceProps& props, int sampleCount) {
     if (kUnknown_SkColorType == origInfo.colorType() ||
         origInfo.width() < 0 || origInfo.height() < 0) {
         return NULL;
     }
 
-    SkImageInfo info = origInfo;
-    // TODO: perhas we can loosen this check now that colortype is more detailed
+    SkColorType ct = origInfo.colorType();
+    SkAlphaType at = origInfo.alphaType();
+    // TODO: perhaps we can loosen this check now that colortype is more detailed
     // e.g. can we support both RGBA and BGRA here?
-    if (kRGB_565_SkColorType == info.colorType()) {
-        info.fAlphaType = kOpaque_SkAlphaType;  // force this setting
+    if (kRGB_565_SkColorType == ct) {
+        at = kOpaque_SkAlphaType;  // force this setting
     } else {
-        info.fColorType = kN32_SkColorType;
-        if (kOpaque_SkAlphaType != info.alphaType()) {
-            info.fAlphaType = kPremul_SkAlphaType;  // force this setting
+        ct = kN32_SkColorType;
+        if (kOpaque_SkAlphaType != at) {
+            at = kPremul_SkAlphaType;  // force this setting
         }
     }
+    const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at);
 
     GrTextureDesc desc;
     desc.fFlags = kRenderTarget_GrTextureFlagBit;
@@ -225,7 +196,7 @@
         return NULL;
     }
 
-    return SkNEW_ARGS(SkGpuDevice, (context, texture.get()));
+    return SkNEW_ARGS(SkGpuDevice, (texture.get(), props));
 }
 
 SkGpuDevice::~SkGpuDevice() {
@@ -246,19 +217,12 @@
         fContext->setClip(NULL);
     }
 
-    SkSafeUnref(fRenderTarget);
+    fRenderTarget->unref();
     fContext->unref();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkGpuDevice::makeRenderTargetCurrent() {
-    DO_DEFERRED_CLEAR();
-    fContext->setRenderTarget(fRenderTarget);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
 bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
                                int x, int y) {
     DO_DEFERRED_CLEAR();
@@ -291,14 +255,14 @@
     fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels, rowBytes, flags);
 
     // need to bump our genID for compatibility with clients that "know" we have a bitmap
-    this->onAccessBitmap().notifyPixelsChanged();
+    fLegacyBitmap.notifyPixelsChanged();
 
     return true;
 }
 
 const SkBitmap& SkGpuDevice::onAccessBitmap() {
     DO_DEFERRED_CLEAR();
-    return INHERITED::onAccessBitmap();
+    return fLegacyBitmap;
 }
 
 void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) {
@@ -316,7 +280,7 @@
 // call this every draw call, to ensure that the context reflects our state,
 // and not the state from some other canvas/device
 void SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) {
-    SkASSERT(NULL != fClipData.fClipStack);
+    SkASSERT(fClipData.fClipStack);
 
     fContext->setRenderTarget(fRenderTarget);
 
@@ -355,6 +319,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkGpuDevice::clear(SkColor color) {
+    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clear", fContext);
     SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
     fContext->clear(&rect, SkColor2GrColor(color), true, fRenderTarget);
     fNeedClear = false;
@@ -362,6 +327,7 @@
 
 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw, false);
+    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext);
 
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
@@ -461,7 +427,7 @@
     GrStrokeInfo strokeInfo(paint);
 
     const SkPathEffect* pe = paint.getPathEffect();
-    if (!usePath && NULL != pe && !strokeInfo.isDashed()) {
+    if (!usePath && pe && !strokeInfo.isDashed()) {
         usePath = true;
     }
 
@@ -474,7 +440,7 @@
 
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
-  
+
     fContext->drawRect(grPaint, rect, &strokeInfo);
 }
 
@@ -482,12 +448,13 @@
 
 void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
                            const SkPaint& paint) {
+    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRRect", fContext);
     CHECK_FOR_ANNOTATION(paint);
     CHECK_SHOULD_DRAW(draw, false);
 
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
-    
+
     GrStrokeInfo strokeInfo(paint);
     if (paint.getMaskFilter()) {
         // try to hit the fast path for drawing filtered round rects
@@ -524,7 +491,7 @@
         usePath = true;
     } else {
         const SkPathEffect* pe = paint.getPathEffect();
-        if (NULL != pe && !strokeInfo.isDashed()) {
+        if (pe && !strokeInfo.isDashed()) {
             usePath = true;
         }
     }
@@ -536,7 +503,7 @@
         this->drawPath(draw, path, paint, NULL, true);
         return;
     }
-    
+
     fContext->drawRRect(grPaint, rect, strokeInfo);
 }
 
@@ -570,6 +537,7 @@
 
 void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval,
                            const SkPaint& paint) {
+    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawOval", fContext);
     CHECK_FOR_ANNOTATION(paint);
     CHECK_SHOULD_DRAW(draw, false);
 
@@ -581,7 +549,7 @@
         usePath = true;
     } else {
         const SkPathEffect* pe = paint.getPathEffect();
-        if (NULL != pe && !strokeInfo.isDashed()) {
+        if (pe && !strokeInfo.isDashed()) {
             usePath = true;
         }
     }
@@ -620,7 +588,7 @@
     matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
     matrix.postIDiv(mask->width(), mask->height());
 
-    grp->addCoverageEffect(GrSimpleTextureEffect::Create(mask, matrix))->unref();
+    grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix))->unref();
     context->drawRect(*grp, maskRect);
     return true;
 }
@@ -735,6 +703,7 @@
                            bool pathIsMutable) {
     CHECK_FOR_ANNOTATION(paint);
     CHECK_SHOULD_DRAW(draw, false);
+    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext);
 
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
@@ -892,7 +861,7 @@
     }
     SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect);
     inv.mapRect(&clippedSrcRect);
-    if (NULL != srcRectPtr) {
+    if (srcRectPtr) {
         // we've setup src space 0,0 to map to the top left of the src rect.
         clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop);
         if (!clippedSrcRect.intersect(*srcRectPtr)) {
@@ -914,7 +883,7 @@
                                    int* tileSize,
                                    SkIRect* clippedSrcRect) const {
     // if bitmap is explictly texture backed then just use the texture
-    if (NULL != bitmap.getTexture()) {
+    if (bitmap.getTexture()) {
         return false;
     }
 
@@ -1091,7 +1060,7 @@
         srcRect.set(0, 0, w, h);
         flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_DrawBitmapRectFlag);
     } else {
-        SkASSERT(NULL != dstSizePtr);
+        SkASSERT(dstSizePtr);
         srcRect = *srcRectPtr;
         dstSize = *dstSizePtr;
         if (srcRect.fLeft <= 0 && srcRect.fTop <= 0 &&
@@ -1106,7 +1075,7 @@
         SkBitmap        tmp;    // subset of bitmap, if necessary
         const SkBitmap* bitmapPtr = &bitmap;
         SkMatrix localM;
-        if (NULL != srcRectPtr) {
+        if (srcRectPtr) {
             localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop);
             localM.postScale(dstSize.fWidth / srcRectPtr->width(),
                              dstSize.fHeight / srcRectPtr->height());
@@ -1339,7 +1308,7 @@
                       SkScalarMul(srcRect.fBottom, hInv));
 
     SkRect textureDomain = SkRect::MakeEmpty();
-    SkAutoTUnref<GrEffectRef> effect;
+    SkAutoTUnref<GrFragmentProcessor> fp;
     if (needsTextureDomain && !(flags & SkCanvas::kBleed_DrawBitmapRectFlag)) {
         // Use a constrained texture domain to avoid color bleeding
         SkScalar left, top, right, bottom;
@@ -1359,9 +1328,9 @@
         }
         textureDomain.setLTRB(left, top, right, bottom);
         if (bicubic) {
-            effect.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDomain));
+            fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDomain));
         } else {
-            effect.reset(GrTextureDomainEffect::Create(texture,
+            fp.reset(GrTextureDomainEffect::Create(texture,
                                                        SkMatrix::I(),
                                                        textureDomain,
                                                        GrTextureDomain::kClamp_Mode,
@@ -1370,21 +1339,21 @@
     } else if (bicubic) {
         SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode());
         SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTileModeY() };
-        effect.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes));
+        fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes));
     } else {
-        effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
+        fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
     }
 
     // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
     // the rest from the SkPaint.
     GrPaint grPaint;
-    grPaint.addColorEffect(effect);
+    grPaint.addColorProcessor(fp);
     bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType());
-    GrColor grColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()) :
-                                    SkColor2GrColor(paint.getColor());
-    SkPaint2GrPaintNoShader(this->context(), paint, grColor, false, &grPaint);
+    GrColor paintColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()) :
+                                       SkColor2GrColor(paint.getColor());
+    SkPaint2GrPaintNoShader(this->context(), paint, paintColor, false, &grPaint);
 
-    fContext->drawRectToRect(grPaint, dstRect, paintRect, NULL);
+    fContext->drawRectToRect(grPaint, dstRect, paintRect);
 }
 
 static bool filter_texture(SkBaseDevice* device, GrContext* context,
@@ -1425,13 +1394,14 @@
     // This bitmap will own the filtered result as a texture.
     SkBitmap filteredBitmap;
 
-    if (NULL != filter) {
+    if (filter) {
         SkIPoint offset = SkIPoint::Make(0, 0);
         SkMatrix matrix(*draw.fMatrix);
         matrix.postTranslate(SkIntToScalar(-left), SkIntToScalar(-top));
         SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
-        SkImageFilter::Cache* cache = SkImageFilter::Cache::Create();
-        SkAutoUnref aur(cache);
+        SkAutoTUnref<SkImageFilter::Cache> cache(getImageFilterCache());
+        // This cache is transient, and is freed (along with all its contained
+        // textures) when it goes out of scope.
         SkImageFilter::Context ctx(matrix, clipBounds, cache);
         if (filter_texture(this, fContext, texture, filter, w, h, ctx, &filteredBitmap,
                            &offset)) {
@@ -1446,7 +1416,7 @@
     }
 
     GrPaint grPaint;
-    grPaint.addColorTextureEffect(texture, SkMatrix::I());
+    grPaint.addColorTextureProcessor(texture, SkMatrix::I());
 
     SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(paint.getColor()),
                             false, &grPaint);
@@ -1474,7 +1444,7 @@
                      SkIntToScalar(bitmap.height()));
 
     // Compute matrix from the two rectangles
-    if (NULL != src) {
+    if (src) {
         tmpSrc = *src;
     } else {
         tmpSrc = bitmapBounds;
@@ -1483,7 +1453,7 @@
     matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
 
     // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null.
-    if (NULL != src) {
+    if (src) {
         if (!bitmapBounds.contains(tmpSrc)) {
             if (!tmpSrc.intersect(bitmapBounds)) {
                 return; // nothing to draw
@@ -1511,6 +1481,7 @@
 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
                              int x, int y, const SkPaint& paint) {
     // clear of the source device must occur before CHECK_SHOULD_DRAW
+    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext);
     SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
     if (dev->fNeedClear) {
         // TODO: could check here whether we really need to draw at all
@@ -1534,13 +1505,14 @@
     // This bitmap will own the filtered result as a texture.
     SkBitmap filteredBitmap;
 
-    if (NULL != filter) {
+    if (filter) {
         SkIPoint offset = SkIPoint::Make(0, 0);
         SkMatrix matrix(*draw.fMatrix);
         matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
         SkIRect clipBounds = SkIRect::MakeWH(devTex->width(), devTex->height());
-        SkImageFilter::Cache* cache = SkImageFilter::Cache::Create();
-        SkAutoUnref aur(cache);
+        // This cache is transient, and is freed (along with all its contained
+        // textures) when it goes out of scope.
+        SkAutoTUnref<SkImageFilter::Cache> cache(getImageFilterCache());
         SkImageFilter::Context ctx(matrix, clipBounds, cache);
         if (filter_texture(this, fContext, devTex, filter, w, h, ctx, &filteredBitmap,
                            &offset)) {
@@ -1555,7 +1527,7 @@
     }
 
     GrPaint grPaint;
-    grPaint.addColorTextureEffect(devTex, SkMatrix::I());
+    grPaint.addColorTextureProcessor(devTex, SkMatrix::I());
 
     SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(paint.getColor()),
                             false, &grPaint);
@@ -1616,42 +1588,72 @@
                               const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw, false);
 
+    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawVertices", fContext);
+
+    const uint16_t* outIndices;
+    SkAutoTDeleteArray<uint16_t> outAlloc(NULL);
+    GrPrimitiveType primType;
+    GrPaint grPaint;
+
     // If both textures and vertex-colors are NULL, strokes hairlines with the paint's color.
     if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) {
+
         texs = NULL;
+
         SkPaint copy(paint);
         copy.setStyle(SkPaint::kStroke_Style);
         copy.setStrokeWidth(0);
 
+        // we ignore the shader if texs is null.
+        SkPaint2GrPaintNoShader(this->context(), copy, SkColor2GrColor(copy.getColor()),
+                                NULL == colors, &grPaint);
+
+        primType = kLines_GrPrimitiveType;
+        int triangleCount = 0;
+        int n = (NULL == indices) ? vertexCount : indexCount;
+        switch (vmode) {
+            case SkCanvas::kTriangles_VertexMode:
+                triangleCount = n / 3;
+                break;
+            case SkCanvas::kTriangleStrip_VertexMode:
+            case SkCanvas::kTriangleFan_VertexMode:
+                triangleCount = n - 2;
+                break;
+        }
+
         VertState       state(vertexCount, indices, indexCount);
         VertState::Proc vertProc = state.chooseProc(vmode);
 
-        SkPoint* pts = new SkPoint[vertexCount * 6];
+        //number of indices for lines per triangle with kLines
+        indexCount = triangleCount * 6;
+
+        outAlloc.reset(SkNEW_ARRAY(uint16_t, indexCount));
+        outIndices = outAlloc.get();
+        uint16_t* auxIndices = outAlloc.get();
         int i = 0;
         while (vertProc(&state)) {
-            pts[i] = vertices[state.f0];
-            pts[i + 1] = vertices[state.f1];
-            pts[i + 2] = vertices[state.f1];
-            pts[i + 3] = vertices[state.f2];
-            pts[i + 4] = vertices[state.f2];
-            pts[i + 5] = vertices[state.f0];
+            auxIndices[i]     = state.f0;
+            auxIndices[i + 1] = state.f1;
+            auxIndices[i + 2] = state.f1;
+            auxIndices[i + 3] = state.f2;
+            auxIndices[i + 4] = state.f2;
+            auxIndices[i + 5] = state.f0;
             i += 6;
         }
-        draw.drawPoints(SkCanvas::kLines_PointMode, i, pts, copy, true);
-        return;
-    }
-
-    GrPaint grPaint;
-    // we ignore the shader if texs is null.
-    if (NULL == texs) {
-        SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(paint.getColor()),
-                                NULL == colors, &grPaint);
     } else {
-        SkPaint2GrPaintShader(this->context(), paint, NULL == colors, &grPaint);
+        outIndices = indices;
+        primType = gVertexMode2PrimitiveType[vmode];
+
+        if (NULL == texs || NULL == paint.getShader()) {
+            SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(paint.getColor()),
+                                    NULL == colors, &grPaint);
+        } else {
+            SkPaint2GrPaintShader(this->context(), paint, NULL == colors, &grPaint);
+        }
     }
 
 #if 0
-    if (NULL != xmode && NULL != texs && NULL != colors) {
+    if (xmode && texs && colors) {
         if (!SkXfermode::IsMode(xmode, SkXfermode::kModulate_Mode)) {
             SkDebugf("Unsupported vertex-color/texture xfer mode.\n");
             return;
@@ -1660,7 +1662,7 @@
 #endif
 
     SkAutoSTMalloc<128, GrColor> convertedColors(0);
-    if (NULL != colors) {
+    if (colors) {
         // need to convert byte order and from non-PM to PM
         convertedColors.reset(vertexCount);
         SkColor color;
@@ -1674,12 +1676,12 @@
         colors = convertedColors.get();
     }
     fContext->drawVertices(grPaint,
-                           gVertexMode2PrimitiveType[vmode],
+                           primType,
                            vertexCount,
                            vertices,
                            texs,
                            colors,
-                           indices,
+                           outIndices,
                            indexCount);
 }
 
@@ -1689,6 +1691,7 @@
                           size_t byteLength, SkScalar x, SkScalar y,
                           const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw, false);
+    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawText", fContext);
 
     if (fMainTextContext->canDraw(paint)) {
         GrPaint grPaint;
@@ -1764,9 +1767,9 @@
         paint.getPathEffect() ||
         paint.isFakeBoldText() ||
         paint.getStyle() != SkPaint::kFill_Style) {
-        // turn off lcd
+        // turn off lcd, but turn on kGenA8
         flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
-        flags->fHinting = paint.getHinting();
+        flags->fFlags |= SkPaint::kGenA8FromLCD_Flag;
         return true;
     }
     // we're cool with the paint as is
@@ -1803,8 +1806,8 @@
 #else
     texture.reset(fContext->createUncachedTexture(desc, NULL, 0));
 #endif
-    if (NULL != texture.get()) {
-        return SkGpuDevice::Create(texture, flags);
+    if (texture.get()) {
+        return SkGpuDevice::Create(texture, SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType), flags);
     } else {
         GrPrintf("---- failed to create compatible device texture [%d %d]\n",
                  info.width(), info.height());
@@ -1812,204 +1815,65 @@
     }
 }
 
-SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info) {
-    return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples());
+SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
+    return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples(), &props);
 }
 
 void SkGpuDevice::EXPERIMENTAL_optimize(const SkPicture* picture) {
-    SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey();
+    fContext->getLayerCache()->processDeletedPictures();
 
-    const SkPicture::AccelData* existing = picture->EXPERIMENTAL_getAccelData(key);
-    if (NULL != existing) {
+    if (picture->fData.get() && !picture->fData->suitableForLayerOptimization()) {
         return;
     }
 
-    SkAutoTUnref<GPUAccelData> data(SkNEW_ARGS(GPUAccelData, (key)));
+    SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey();
 
-    picture->EXPERIMENTAL_addAccelData(data);
+    const SkPicture::AccelData* existing = picture->EXPERIMENTAL_getAccelData(key);
+    if (existing) {
+        return;
+    }
 
-    GatherGPUInfo(picture, data);
+    GPUOptimize(picture);
+
+    fContext->getLayerCache()->trackPicture(picture);
 }
 
-static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* result) {
-    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
-    result->setInfo(info);
-    result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
-}
-
-void SkGpuDevice::EXPERIMENTAL_purge(const SkPicture* picture) {
-
-}
-
-bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture) {
-
-    SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey();
-
-    const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key);
-    if (NULL == data) {
+bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* mainPicture,
+                                           const SkMatrix* matrix, const SkPaint* paint) {
+    // todo: should handle these natively
+    if (matrix || paint) {
         return false;
     }
 
-    const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data);
-
-    if (0 == gpuData->numSaveLayers()) {
-        return false;
-    }
-
-    SkAutoTArray<bool> pullForward(gpuData->numSaveLayers());
-    for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
-        pullForward[i] = false;
-    }
+    fContext->getLayerCache()->processDeletedPictures();
 
     SkRect clipBounds;
-    if (!canvas->getClipBounds(&clipBounds)) {
+    if (!mainCanvas->getClipBounds(&clipBounds)) {
         return true;
     }
-    SkIRect query;
-    clipBounds.roundOut(&query);
 
-    const SkPicture::OperationList& ops = picture->EXPERIMENTAL_getActiveOps(query);
+    SkTDArray<GrLayerHoister::HoistedLayer> atlased, nonAtlased;
 
-    // This code pre-renders the entire layer since it will be cached and potentially
-    // reused with different clips (e.g., in different tiles). Because of this the
-    // clip will not be limiting the size of the pre-rendered layer. kSaveLayerMaxSize
-    // is used to limit which clips are pre-rendered.
-    static const int kSaveLayerMaxSize = 256;
-
-    if (ops.valid()) {
-        // In this case the picture has been generated with a BBH so we use
-        // the BBH to limit the pre-rendering to just the layers needed to cover
-        // the region being drawn
-        for (int i = 0; i < ops.numOps(); ++i) {
-            uint32_t offset = ops.offset(i);
-
-            // For now we're saving all the layers in the GPUAccelData so they
-            // can be nested. Additionally, the nested layers appear before
-            // their parent in the list.
-            for (int j = 0 ; j < gpuData->numSaveLayers(); ++j) {
-                const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j);
-
-                if (pullForward[j]) {
-                    continue;            // already pulling forward
-                }
-
-                if (offset < info.fSaveLayerOpID || offset > info.fRestoreOpID) {
-                    continue;            // the op isn't in this range
-                }
-
-                // TODO: once this code is more stable unsuitable layers can
-                // just be omitted during the optimization stage
-                if (!info.fValid ||
-                    kSaveLayerMaxSize < info.fSize.fWidth ||
-                    kSaveLayerMaxSize < info.fSize.fHeight ||
-                    info.fIsNested) {
-                    continue;            // this layer is unsuitable
-                }
-
-                pullForward[j] = true;
-            }
-        }
-    } else {
-        // In this case there is no BBH associated with the picture. Pre-render
-        // all the layers that intersect the drawn region
-        for (int j = 0; j < gpuData->numSaveLayers(); ++j) {
-            const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j);
-
-            SkIRect layerRect = SkIRect::MakeXYWH(info.fOffset.fX,
-                                                  info.fOffset.fY,
-                                                  info.fSize.fWidth,
-                                                  info.fSize.fHeight);
-
-            if (!SkIRect::Intersects(query, layerRect)) {
-                continue;
-            }
-
-            // TODO: once this code is more stable unsuitable layers can
-            // just be omitted during the optimization stage
-            if (!info.fValid ||
-                kSaveLayerMaxSize < info.fSize.fWidth ||
-                kSaveLayerMaxSize < info.fSize.fHeight ||
-                info.fIsNested) {
-                continue;
-            }
-
-            pullForward[j] = true;
-        }
+    if (!GrLayerHoister::FindLayersToHoist(mainPicture, clipBounds, &atlased, &nonAtlased,
+                                           fContext->getLayerCache())) {
+        return false;
     }
 
-    SkPicturePlayback::PlaybackReplacements replacements;
+    GrReplacements replacements;
 
-    for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
-        if (pullForward[i]) {
-            GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture, i);
+    GrLayerHoister::DrawLayers(atlased, nonAtlased, &replacements);
 
-            const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
+    // Render the entire picture using new layers
+    GrRecordReplaceDraw(*mainPicture->fRecord, mainCanvas, mainPicture->fBBH.get(), 
+                        &replacements, NULL);
 
-            if (NULL != picture->fPlayback) {
-                SkPicturePlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
-                                                                        replacements.push();
-                layerInfo->fStart = info.fSaveLayerOpID;
-                layerInfo->fStop = info.fRestoreOpID;
-                layerInfo->fPos = info.fOffset;
-
-                GrTextureDesc desc;
-                desc.fFlags = kRenderTarget_GrTextureFlagBit;
-                desc.fWidth = info.fSize.fWidth;
-                desc.fHeight = info.fSize.fHeight;
-                desc.fConfig = kSkia8888_GrPixelConfig;
-                // TODO: need to deal with sample count
-
-                bool bNeedsRendering = true;
-
-                // This just uses scratch textures and doesn't cache the texture.
-                // This can yield a lot of re-rendering
-                if (NULL == layer->getTexture()) {
-                    layer->setTexture(fContext->lockAndRefScratchTexture(desc,
-                                                        GrContext::kApprox_ScratchTexMatch));
-                    if (NULL == layer->getTexture()) {
-                        continue;
-                    }
-                } else {
-                    bNeedsRendering = false;
-                }
-
-                layerInfo->fBM = SkNEW(SkBitmap);
-                wrap_texture(layer->getTexture(), desc.fWidth, desc.fHeight, layerInfo->fBM);
-
-                SkASSERT(info.fPaint);
-                layerInfo->fPaint = info.fPaint;
-
-                if (bNeedsRendering) {
-                    SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
-                                                        layer->getTexture()->asRenderTarget()));
-
-                    SkCanvas* canvas = surface->getCanvas();
-
-                    canvas->setMatrix(info.fCTM);
-                    canvas->clear(SK_ColorTRANSPARENT);
-
-                    picture->fPlayback->setDrawLimits(info.fSaveLayerOpID, info.fRestoreOpID);
-                    picture->fPlayback->draw(*canvas, NULL);
-                    picture->fPlayback->setDrawLimits(0, 0);
-                    canvas->flush();
-                }
-            }
-        }
-    }
-
-    // Playback using new layers
-    picture->fPlayback->setReplacements(&replacements);
-    picture->fPlayback->draw(*canvas, NULL);
-    picture->fPlayback->setReplacements(NULL);
-
-    for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
-        GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture, i);
-
-        if (NULL != layer->getTexture()) {
-            fContext->unlockScratchTexture(layer->getTexture());
-            layer->setTexture(NULL);
-        }
-    }
+    GrLayerHoister::UnlockLayers(fContext->getLayerCache(), atlased, nonAtlased);
 
     return true;
 }
+
+SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
+    // We always return a transient cache, so it is freed after each
+    // filter traversal.
+    return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize);
+}
diff --git a/include/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
similarity index 84%
rename from include/gpu/SkGpuDevice.h
rename to src/gpu/SkGpuDevice.h
index 0b6bbc1..41b53b1 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -13,7 +13,7 @@
 
 #include "SkGr.h"
 #include "SkBitmap.h"
-#include "SkBitmapDevice.h"
+#include "SkDevice.h"
 #include "SkPicture.h"
 #include "SkRegion.h"
 #include "GrContext.h"
@@ -21,13 +21,15 @@
 struct SkDrawProcs;
 struct GrSkDrawProcs;
 
+class GrAccelData;
+struct GrCachedLayer;
 class GrTextContext;
 
 /**
- *  Subclass of SkBitmapDevice, which directs all drawing to the GrGpu owned by the
+ *  Subclass of SkBaseDevice, which directs all drawing to the GrGpu owned by the
  *  canvas.
  */
-class SK_API SkGpuDevice : public SkBitmapDevice {
+class SK_API SkGpuDevice : public SkBaseDevice {
 public:
     enum Flags {
         kNeedClear_Flag = 1 << 0,  //!< Surface requires an initial clear
@@ -41,7 +43,7 @@
      * the kCached_Flag should be specified to make the device responsible for unlocking
      * the surface when it is released.
      */
-    static SkGpuDevice* Create(GrSurface* surface, unsigned flags = 0);
+    static SkGpuDevice* Create(GrSurface* surface, const SkSurfaceProps&, unsigned flags = 0);
 
     /**
      *  New device that will create an offscreen renderTarget based on the
@@ -49,21 +51,8 @@
      *  count against the GrContext's texture cache budget. The device's pixels
      *  will be uninitialized. On failure, returns NULL.
      */
-    static SkGpuDevice* Create(GrContext*, const SkImageInfo&, int sampleCount);
-
-    /**
-     *  DEPRECATED -- need to make this private, call Create(surface)
-     *  New device that will render to the specified renderTarget.
-     */
-    SkGpuDevice(GrContext*, GrRenderTarget*, unsigned flags = 0);
-
-    /**
-     *  DEPRECATED -- need to make this private, call Create(surface)
-     *  New device that will render to the texture (as a rendertarget).
-     *  The GrTexture's asRenderTarget() must be non-NULL or device will not
-     *  function.
-     */
-    SkGpuDevice(GrContext*, GrTexture*, unsigned flags = 0);
+    static SkGpuDevice* Create(GrContext*, const SkImageInfo&, const SkSurfaceProps&,
+                               int sampleCount);
 
     virtual ~SkGpuDevice();
 
@@ -122,12 +111,6 @@
 
     virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE;
 
-    /**
-     * Make's this device's rendertarget current in the underlying 3D API.
-     * Also implicitly flushes.
-     */
-    virtual void makeRenderTargetCurrent();
-
     virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE;
     virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
                              const SkImageFilter::Context&,
@@ -143,9 +126,8 @@
     /**  PRIVATE / EXPERIMENTAL -- do not call */
     virtual void EXPERIMENTAL_optimize(const SkPicture* picture) SK_OVERRIDE;
     /**  PRIVATE / EXPERIMENTAL -- do not call */
-    virtual void EXPERIMENTAL_purge(const SkPicture* picture) SK_OVERRIDE;
-    /**  PRIVATE / EXPERIMENTAL -- do not call */
-    virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture) SK_OVERRIDE;
+    virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture,
+                                          const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
 private:
     GrContext*      fContext;
@@ -161,12 +143,19 @@
     GrRenderTarget*     fRenderTarget;
     bool                fNeedClear;
 
-    // called from rt and tex cons
-    void initFromRenderTarget(GrContext*, GrRenderTarget*, unsigned flags);
+    // remove when our clients don't rely on accessBitmap()
+    SkBitmap fLegacyBitmap;
+
+    SkGpuDevice(GrSurface*, const SkSurfaceProps&, unsigned flags = 0);
 
     virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
 
-    virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
+    virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
+
+    virtual SkImageFilter::Cache* getImageFilterCache() SK_OVERRIDE;
+
+    // temporarily change the return to false, until we understand the issues with filters and persp
+    virtual bool forceConservativeRasterClip() const SK_OVERRIDE { return true; }
 
     // sets the render target, clip, and matrix on GrContext. Use forceIdenity to override
     // SkDraw's matrix and draw in device coords.
@@ -214,7 +203,7 @@
 
     static SkPicture::AccelData::Key ComputeAccelDataKey();
 
-    typedef SkBitmapDevice INHERITED;
+    typedef SkBaseDevice INHERITED;
 };
 
 #endif
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index a1b379f..e81abdb 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -11,10 +11,12 @@
 #include "SkData.h"
 #include "SkMessageBus.h"
 #include "SkPixelRef.h"
+#include "SkTextureCompressor.h"
 #include "GrResourceCache.h"
 #include "GrGpu.h"
 #include "effects/GrDitherEffect.h"
 #include "GrDrawTargetCaps.h"
+#include "effects/GrYUVtoRGBEffect.h"
 
 #ifndef SK_IGNORE_ETC1_SUPPORT
 #  include "ktx.h"
@@ -63,7 +65,7 @@
     ctable->unlockColors();
 
     // always skip a full 256 number of entries, even if we memcpy'd fewer
-    dst += kGrColorTableSize;
+    dst += 256 * sizeof(GrColor);
 
     if ((unsigned)bitmap.width() == bitmap.rowBytes()) {
         memcpy(dst, bitmap.getPixels(), bitmap.getSize());
@@ -129,12 +131,44 @@
 }  // namespace
 
 static void add_genID_listener(GrResourceKey key, SkPixelRef* pixelRef) {
-    SkASSERT(NULL != pixelRef);
+    SkASSERT(pixelRef);
     pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key)));
 }
 
+static GrTexture* sk_gr_allocate_texture(GrContext* ctx,
+                                         bool cache,
+                                         const GrTextureParams* params,
+                                         const SkBitmap& bm,
+                                         GrTextureDesc desc,
+                                         const void* pixels,
+                                         size_t rowBytes) {
+    GrTexture* result;
+    if (cache) {
+        // This texture is likely to be used again so leave it in the cache
+        GrCacheID cacheID;
+        generate_bitmap_cache_id(bm, &cacheID);
+
+        GrResourceKey key;
+        result = ctx->createTexture(params, desc, cacheID, pixels, rowBytes, &key);
+        if (result) {
+            add_genID_listener(key, bm.pixelRef());
+        }
+   } else {
+        // This texture is unlikely to be used again (in its present form) so
+        // just use a scratch texture. This will remove the texture from the
+        // cache so no one else can find it. Additionally, once unlocked, the
+        // scratch texture will go to the end of the list for purging so will
+        // likely be available for this volatile bitmap the next time around.
+        result = ctx->lockAndRefScratchTexture(desc, GrContext::kExact_ScratchTexMatch);
+        if (pixels) {
+            result->writePixels(0, 0, bm.width(), bm.height(), desc.fConfig, pixels, rowBytes);
+        }
+    }
+    return result;
+}
+
 #ifndef SK_IGNORE_ETC1_SUPPORT
-static GrTexture *load_etc1_texture(GrContext* ctx,
+static GrTexture *load_etc1_texture(GrContext* ctx, bool cache,
                                     const GrTextureParams* params,
                                     const SkBitmap &bm, GrTextureDesc desc) {
     SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData());
@@ -164,7 +198,7 @@
         SkKTXFile ktx(data);
 
         // Is it actually an ETC1 texture?
-        if (!ktx.isETC1()) {
+        if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) {
             return NULL;
         }
 
@@ -180,19 +214,81 @@
         return NULL;
     }
 
-    // This texture is likely to be used again so leave it in the cache
-    GrCacheID cacheID;
-    generate_bitmap_cache_id(bm, &cacheID);
-
-    GrResourceKey key;
-    GrTexture* result = ctx->createTexture(params, desc, cacheID, bytes, 0, &key);
-    if (NULL != result) {
-        add_genID_listener(key, bm.pixelRef());
-    }
-    return result;
+    return sk_gr_allocate_texture(ctx, cache, params, bm, desc, bytes, 0);
 }
 #endif   // SK_IGNORE_ETC1_SUPPORT
 
+static GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTextureParams* params,
+                                   const SkBitmap& bm, const GrTextureDesc& desc) {
+    SkPixelRef* pixelRef = bm.pixelRef();
+    SkISize yuvSizes[3];
+    if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL, NULL)) {
+        return NULL;
+    }
+
+    // Allocate the memory for YUV
+    size_t totalSize(0);
+    size_t sizes[3], rowBytes[3];
+    for (int i = 0; i < 3; ++i) {
+        rowBytes[i] = yuvSizes[i].fWidth;
+        totalSize  += sizes[i] = rowBytes[i] * yuvSizes[i].fHeight;
+    }
+    SkAutoMalloc storage(totalSize);
+    void* planes[3];
+    planes[0] = storage.get();
+    planes[1] = (uint8_t*)planes[0] + sizes[0];
+    planes[2] = (uint8_t*)planes[1] + sizes[1];
+
+    SkYUVColorSpace colorSpace;
+
+    // Get the YUV planes
+    if (!pixelRef->getYUV8Planes(yuvSizes, planes, rowBytes, &colorSpace)) {
+        return NULL;
+    }
+
+    GrTextureDesc yuvDesc;
+    yuvDesc.fConfig = kAlpha_8_GrPixelConfig;
+    GrAutoScratchTexture yuvTextures[3];
+    for (int i = 0; i < 3; ++i) {
+        yuvDesc.fWidth  = yuvSizes[i].fWidth;
+        yuvDesc.fHeight = yuvSizes[i].fHeight;
+        yuvTextures[i].set(ctx, yuvDesc);
+        if ((NULL == yuvTextures[i].texture()) ||
+            !ctx->writeTexturePixels(yuvTextures[i].texture(),
+                0, 0, yuvDesc.fWidth, yuvDesc.fHeight,
+                yuvDesc.fConfig, planes[i], rowBytes[i])) {
+            return NULL;
+        }
+    }
+
+    GrTextureDesc rtDesc = desc;
+    rtDesc.fFlags = rtDesc.fFlags |
+                    kRenderTarget_GrTextureFlagBit |
+                    kNoStencil_GrTextureFlagBit;
+
+    GrTexture* result = sk_gr_allocate_texture(ctx, cache, params, bm, rtDesc, NULL, 0);
+
+    GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL;
+    if (renderTarget) {
+        SkAutoTUnref<GrFragmentProcessor> yuvToRgbProcessor(GrYUVtoRGBEffect::Create(
+            yuvTextures[0].texture(), yuvTextures[1].texture(), yuvTextures[2].texture(),
+            colorSpace));
+        GrPaint paint;
+        paint.addColorProcessor(yuvToRgbProcessor);
+        SkRect r = SkRect::MakeWH(SkIntToScalar(yuvSizes[0].fWidth),
+                                  SkIntToScalar(yuvSizes[0].fHeight));
+        GrContext::AutoRenderTarget autoRT(ctx, renderTarget);
+        GrContext::AutoMatrix am;
+        am.setIdentity(ctx);
+        GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip);
+        ctx->drawRect(paint, r);
+    } else {
+        SkSafeSetNull(result);
+    }
+
+    return result;
+}
+
 static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx,
                                               bool cache,
                                               const GrTextureParams* params,
@@ -208,33 +304,16 @@
         // build_compressed_data doesn't do npot->pot expansion
         // and paletted textures can't be sub-updated
         if (ctx->supportsIndex8PixelConfig(params, bitmap->width(), bitmap->height())) {
-            size_t imagesize = bitmap->width() * bitmap->height() + kGrColorTableSize;
-            SkAutoMalloc storage(imagesize);
+            size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig,
+                                                          bitmap->width(), bitmap->height());
+            SkAutoMalloc storage(imageSize);
 
             build_compressed_data(storage.get(), origBitmap);
 
             // our compressed data will be trimmed, so pass width() for its
             // "rowBytes", since they are the same now.
-
-            if (cache) {
-                GrCacheID cacheID;
-                generate_bitmap_cache_id(origBitmap, &cacheID);
-
-                GrResourceKey key;
-                GrTexture* result = ctx->createTexture(params, desc, cacheID,
-                                                       storage.get(), bitmap->width(), &key);
-                if (NULL != result) {
-                    add_genID_listener(key, origBitmap.pixelRef());
-                }
-                return result;
-            } else {
-                GrTexture* result = ctx->lockAndRefScratchTexture(desc,
-                                                            GrContext::kExact_ScratchTexMatch);
-                result->writePixels(0, 0, bitmap->width(),
-                                    bitmap->height(), desc.fConfig,
-                                    storage.get());
-                return result;
-            }
+            return sk_gr_allocate_texture(ctx, cache, params, origBitmap,
+                                          desc, storage.get(), bitmap->width());
         } else {
             origBitmap.copyTo(&tmpBitmap, kN32_SkColorType);
             // now bitmap points to our temp, which has been promoted to 32bits
@@ -257,43 +336,26 @@
         // the bitmap has available pixels, then they might not be what the decompressed
         // data is.
         && !(bitmap->readyToDraw())) {
-        GrTexture *texture = load_etc1_texture(ctx, params, *bitmap, desc);
-        if (NULL != texture) {
+        GrTexture *texture = load_etc1_texture(ctx, cache, params, *bitmap, desc);
+        if (texture) {
             return texture;
         }
     }
 #endif   // SK_IGNORE_ETC1_SUPPORT
 
+    else {
+        GrTexture *texture = load_yuv_texture(ctx, cache, params, *bitmap, desc);
+        if (texture) {
+            return texture;
+        }
+    }
     SkAutoLockPixels alp(*bitmap);
     if (!bitmap->readyToDraw()) {
         return NULL;
     }
-    if (cache) {
-        // This texture is likely to be used again so leave it in the cache
-        GrCacheID cacheID;
-        generate_bitmap_cache_id(origBitmap, &cacheID);
 
-        GrResourceKey key;
-        GrTexture* result = ctx->createTexture(params, desc, cacheID,
-                                               bitmap->getPixels(), bitmap->rowBytes(), &key);
-        if (NULL != result) {
-            add_genID_listener(key, origBitmap.pixelRef());
-        }
-        return result;
-   } else {
-        // This texture is unlikely to be used again (in its present form) so
-        // just use a scratch texture. This will remove the texture from the
-        // cache so no one else can find it. Additionally, once unlocked, the
-        // scratch texture will go to the end of the list for purging so will
-        // likely be available for this volatile bitmap the next time around.
-        GrTexture* result = ctx->lockAndRefScratchTexture(desc, GrContext::kExact_ScratchTexMatch);
-        result->writePixels(0, 0,
-                            bitmap->width(), bitmap->height(),
-                            desc.fConfig,
-                            bitmap->getPixels(),
-                            bitmap->rowBytes());
-        return result;
-    }
+    return sk_gr_allocate_texture(ctx, cache, params, origBitmap, desc,
+                                  bitmap->getPixels(), bitmap->rowBytes());
 }
 
 bool GrIsBitmapInCache(const GrContext* ctx,
@@ -336,7 +398,7 @@
 }
 
 void GrUnlockAndUnrefCachedBitmapTexture(GrTexture* texture) {
-    SkASSERT(NULL != texture->getContext());
+    SkASSERT(texture->getContext());
 
     texture->getContext()->unlockScratchTexture(texture);
     texture->unref();
@@ -344,26 +406,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-GrPixelConfig SkBitmapConfig2GrPixelConfig(SkBitmap::Config config) {
-    switch (config) {
-        case SkBitmap::kA8_Config:
-            return kAlpha_8_GrPixelConfig;
-        case SkBitmap::kIndex8_Config:
-            return kIndex_8_GrPixelConfig;
-        case SkBitmap::kRGB_565_Config:
-            return kRGB_565_GrPixelConfig;
-        case SkBitmap::kARGB_4444_Config:
-            return kRGBA_4444_GrPixelConfig;
-        case SkBitmap::kARGB_8888_Config:
-            return kSkia8888_GrPixelConfig;
-        default:
-            // kNo_Config, kA1_Config missing
-            return kUnknown_GrPixelConfig;
-    }
-}
-#endif
-
 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass
 // alpha info, that will be considered.
 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType) {
@@ -419,7 +461,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor grColor,
+void SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor,
                              bool constantColor, GrPaint* grPaint) {
 
     grPaint->setDither(skPaint.isDither());
@@ -429,10 +471,10 @@
     SkXfermode::Coeff dm;
 
     SkXfermode* mode = skPaint.getXfermode();
-    GrEffectRef* xferEffect = NULL;
-    if (SkXfermode::AsNewEffectOrCoeff(mode, &xferEffect, &sm, &dm)) {
-        if (NULL != xferEffect) {
-            grPaint->addColorEffect(xferEffect)->unref();
+    GrFragmentProcessor* xferProcessor = NULL;
+    if (SkXfermode::asFragmentProcessorOrCoeff(mode, &xferProcessor, &sm, &dm)) {
+        if (xferProcessor) {
+            grPaint->addColorProcessor(xferProcessor)->unref();
             sm = SkXfermode::kOne_Coeff;
             dm = SkXfermode::kZero_Coeff;
         }
@@ -445,19 +487,19 @@
     grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
     
     //set the color of the paint to the one of the parameter
-    grPaint->setColor(grColor);
+    grPaint->setColor(paintColor);
 
     SkColorFilter* colorFilter = skPaint.getColorFilter();
-    if (NULL != colorFilter) {
+    if (colorFilter) {
         // if the source color is a constant then apply the filter here once rather than per pixel
         // in a shader.
         if (constantColor) {
             SkColor filtered = colorFilter->filterColor(skPaint.getColor());
             grPaint->setColor(SkColor2GrColor(filtered));
         } else {
-            SkAutoTUnref<GrEffectRef> effect(colorFilter->asNewEffect(context));
-            if (NULL != effect.get()) {
-                grPaint->addColorEffect(effect);
+            SkAutoTUnref<GrFragmentProcessor> fp(colorFilter->asFragmentProcessor(context));
+            if (fp.get()) {
+                grPaint->addColorProcessor(fp);
             }
         }
     }
@@ -468,7 +510,7 @@
     if (skPaint.isDither() && grPaint->numColorStages() > 0) {
         // What are we rendering into?
         const GrRenderTarget *target = context->getRenderTarget();
-        SkASSERT(NULL != target);
+        SkASSERT(target);
 
         // Suspect the dithering flag has no effect on these configs, otherwise
         // fall back on setting the appropriate state.
@@ -476,9 +518,9 @@
             target->config() == kBGRA_8888_GrPixelConfig) {
             // The dither flag is set and the target is likely
             // not going to be dithered by the GPU.
-            SkAutoTUnref<GrEffectRef> effect(GrDitherEffect::Create());
-            if (NULL != effect.get()) {
-                grPaint->addColorEffect(effect);
+            SkAutoTUnref<GrFragmentProcessor> fp(GrDitherEffect::Create());
+            if (fp.get()) {
+                grPaint->addColorProcessor(fp);
                 grPaint->setDither(false);
             }
         }
@@ -498,7 +540,7 @@
         fContext = context;
     }
     ~AutoMatrix() {
-        SkASSERT(NULL != fContext);
+        SkASSERT(fContext);
         fContext->setMatrix(fMatrix);
     }
 private:
@@ -515,30 +557,30 @@
         return;
     }
 
-    // SkShader::asNewEffect() may do offscreen rendering. Save off the current RT, clip, and
-    // matrix. We don't reset the matrix on the context because SkShader::asNewEffect may use
-    // GrContext::getMatrix() to know the transformation from local coords to device space.
-    GrColor grColor = SkColor2GrColor(skPaint.getColor());
+    GrColor paintColor = SkColor2GrColor(skPaint.getColor());
 
     // Start a new block here in order to preserve our context state after calling
-    // asNewEffect(). Since these calls get passed back to the client, we don't really
+    // asFragmentProcessor(). Since these calls get passed back to the client, we don't really
     // want them messing around with the context.
     {
+        // SkShader::asFragmentProcessor() may do offscreen rendering. Save off the current RT,
+        // clip, and matrix. We don't reset the matrix on the context because
+        // SkShader::asFragmentProcessor may use GrContext::getMatrix() to know the transformation
+        // from local coords to device space.
         GrContext::AutoRenderTarget art(context, NULL);
         GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip);
         AutoMatrix am(context);
 
-        // setup the shader as the first color effect on the paint
-        // the default grColor is the paint's color
-        GrEffectRef* grEffect = NULL;
-        if (shader->asNewEffect(context, skPaint, NULL, &grColor, &grEffect) && NULL != grEffect) {
-            SkAutoTUnref<GrEffectRef> effect(grEffect);
-            grPaint->addColorEffect(effect);
+        // Allow the shader to modify paintColor and also create an effect to be installed as
+        // the first color effect on the GrPaint.
+        GrFragmentProcessor* fp = NULL;
+        if (shader->asFragmentProcessor(context, skPaint, NULL, &paintColor, &fp) && fp) {
+            grPaint->addColorProcessor(fp)->unref();
             constantColor = false;
         }
     }
 
-    // The grcolor is automatically set when calling asneweffect.
+    // The grcolor is automatically set when calling asFragmentProcessor.
     // If the shader can be seen as an effect it returns true and adds its effect to the grpaint.
-    SkPaint2GrPaintNoShader(context, skPaint, grColor, constantColor, grPaint);
+    SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint);
 }
diff --git a/src/gpu/SkGrPixelRef.cpp b/src/gpu/SkGrPixelRef.cpp
index 2131f41..feac9b1 100644
--- a/src/gpu/SkGrPixelRef.cpp
+++ b/src/gpu/SkGrPixelRef.cpp
@@ -9,8 +9,10 @@
 
 
 #include "SkGrPixelRef.h"
+
 #include "GrContext.h"
 #include "GrTexture.h"
+#include "SkBitmapCache.h"
 #include "SkGr.h"
 #include "SkRect.h"
 
@@ -51,7 +53,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkGrPixelRef* copyToTexturePixelRef(GrTexture* texture, SkColorType dstCT,
+static SkGrPixelRef* copy_to_new_texture_pixelref(GrTexture* texture, SkColorType dstCT,
                                            const SkIRect* subset) {
     if (NULL == texture || kUnknown_SkColorType == dstCT) {
         return NULL;
@@ -86,15 +88,10 @@
 
     context->copyTexture(texture, dst->asRenderTarget(), topLeft);
 
-    // TODO: figure out if this is responsible for Chrome canvas errors
-#if 0
-    // The render texture we have created (to perform the copy) isn't fully
-    // functional (since it doesn't have a stencil buffer). Release it here
-    // so the caller doesn't try to render to it.
-    // TODO: we can undo this release when dynamic stencil buffer attach/
-    // detach has been implemented
-    dst->releaseRenderTarget();
-#endif
+    // Blink is relying on the above copy being sent to GL immediately in the case when the source
+    // is a WebGL canvas backing store. We could have a TODO to remove this flush, but we have a
+    // larger TODO to remove SkGrPixelRef entirely.
+    context->flush();
 
     SkImageInfo info = SkImageInfo::Make(desc.fWidth, desc.fHeight, dstCT, kPremul_SkAlphaType);
     SkGrPixelRef* pixelRef = SkNEW_ARGS(SkGrPixelRef, (info, dst));
@@ -106,24 +103,18 @@
 
 SkGrPixelRef::SkGrPixelRef(const SkImageInfo& info, GrSurface* surface,
                            bool transferCacheLock) : INHERITED(info) {
-    // TODO: figure out if this is responsible for Chrome canvas errors
-#if 0
-    // The GrTexture has a ref to the GrRenderTarget but not vice versa.
-    // If the GrTexture exists take a ref to that (rather than the render
-    // target)
-    fSurface = surface->asTexture();
-#else
-    fSurface = NULL;
-#endif
+    // For surfaces that are both textures and render targets, the texture owns the
+    // render target but not vice versa. So we ref the texture to keep both alive for
+    // the lifetime of this pixel ref.
+    fSurface = SkSafeRef(surface->asTexture());
     if (NULL == fSurface) {
-        fSurface = surface;
+        fSurface = SkSafeRef(surface);
     }
     fUnlock = transferCacheLock;
-    SkSafeRef(surface);
 
     if (fSurface) {
-        SkASSERT(info.fWidth <= fSurface->width());
-        SkASSERT(info.fHeight <= fSurface->height());
+        SkASSERT(info.width() <= fSurface->width());
+        SkASSERT(info.height() <= fSurface->height());
     }
 }
 
@@ -131,7 +122,7 @@
     if (fUnlock) {
         GrContext* context = fSurface->getContext();
         GrTexture* texture = fSurface->asTexture();
-        if (NULL != context && NULL != texture) {
+        if (context && texture) {
             context->unlockScratchTexture(texture);
         }
     }
@@ -139,7 +130,7 @@
 }
 
 GrTexture* SkGrPixelRef::getTexture() {
-    if (NULL != fSurface) {
+    if (fSurface) {
         return fSurface->asTexture();
     }
     return NULL;
@@ -149,14 +140,24 @@
     if (NULL == fSurface) {
         return NULL;
     }
-    
+
     // Note that when copying a render-target-backed pixel ref, we
     // return a texture-backed pixel ref instead.  This is because
     // render-target pixel refs are usually created in conjunction with
     // a GrTexture owned elsewhere (e.g., SkGpuDevice), and cannot live
     // independently of that texture.  Texture-backed pixel refs, on the other
     // hand, own their GrTextures, and are thus self-contained.
-    return copyToTexturePixelRef(fSurface->asTexture(), dstCT, subset);
+    return copy_to_new_texture_pixelref(fSurface->asTexture(), dstCT, subset);
+}
+
+static bool tryAllocBitmapPixels(SkBitmap* bitmap) {
+    SkBitmap::Allocator* allocator = SkBitmapCache::GetAllocator();
+    if (NULL != allocator) {
+        return allocator->allocPixelRef(bitmap, 0);
+    } else {
+        // DiscardableMemory is not available, fallback to default allocator
+        return bitmap->tryAllocPixels();
+    }
 }
 
 bool SkGrPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
@@ -164,25 +165,44 @@
         return false;
     }
 
-    int left, top, width, height;
-    if (NULL != subset) {
-        left = subset->fLeft;
-        width = subset->width();
-        top = subset->fTop;
-        height = subset->height();
+    SkIRect bounds;
+    if (subset) {
+        bounds = *subset;
     } else {
-        left = 0;
-        width = this->info().fWidth;
-        top = 0;
-        height = this->info().fHeight;
+        bounds = SkIRect::MakeWH(this->info().width(), this->info().height());
     }
-    if (!dst->allocPixels(SkImageInfo::MakeN32Premul(width, height))) {
-        SkDebugf("SkGrPixelRef::onReadPixels failed to alloc bitmap for result!\n");
-        return false;
-    }
-    SkAutoLockPixels al(*dst);
-    void* buffer = dst->getPixels();
-    return fSurface->readPixels(left, top, width, height,
+
+    //Check the cache
+    if(!SkBitmapCache::Find(this->getGenerationID(), bounds, dst)) {
+        //Cache miss
+
+        SkBitmap cachedBitmap;
+        cachedBitmap.setInfo(this->info().makeWH(bounds.width(), bounds.height()));
+
+        // If we can't alloc the pixels, then fail
+        if (!tryAllocBitmapPixels(&cachedBitmap)) {
+            return false;
+        }
+
+        // Try to read the pixels from the surface
+        void* buffer = cachedBitmap.getPixels();
+        bool readPixelsOk = fSurface->readPixels(bounds.fLeft, bounds.fTop,
+                                bounds.width(), bounds.height(),
                                 kSkia8888_GrPixelConfig,
-                                buffer, dst->rowBytes());
+                                buffer, cachedBitmap.rowBytes());
+
+        if (!readPixelsOk) {
+            return false;
+        }
+
+        // If we are here, pixels were read correctly from the surface.
+        cachedBitmap.setImmutable();
+        //Add to the cache
+        SkBitmapCache::Add(this->getGenerationID(), bounds, cachedBitmap);
+
+        dst->swap(cachedBitmap);
+    }
+
+    return true;
+
 }
diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h
index 1712733..a195b76 100644
--- a/src/gpu/effects/Gr1DKernelEffect.h
+++ b/src/gpu/effects/Gr1DKernelEffect.h
@@ -31,7 +31,7 @@
     Gr1DKernelEffect(GrTexture* texture,
                      Direction direction,
                      int radius)
-        : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture))
+        : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
         , fDirection(direction)
         , fRadius(radius) {}
 
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 862c1d2..fe509b6 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -7,43 +7,44 @@
 
 #include "GrBezierEffect.h"
 
-#include "gl/GrGLEffect.h"
+#include "gl/builders/GrGLFullProgramBuilder.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
-#include "gl/GrGLVertexEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLGeometryProcessor.h"
+#include "GrTBackendProcessorFactory.h"
 
-class GrGLConicEffect : public GrGLVertexEffect {
+class GrGLConicEffect : public GrGLGeometryProcessor {
 public:
-    GrGLConicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLConicEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLFullShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLFullProgramBuilder* builder,
+                          const GrGeometryProcessor& geometryProcessor,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
 
 private:
-    GrEffectEdgeType fEdgeType;
+    GrPrimitiveEdgeType fEdgeType;
 
-    typedef GrGLVertexEffect INHERITED;
+    typedef GrGLGeometryProcessor INHERITED;
 };
 
-GrGLConicEffect::GrGLConicEffect(const GrBackendEffectFactory& factory,
-                                 const GrDrawEffect& drawEffect)
+GrGLConicEffect::GrGLConicEffect(const GrBackendProcessorFactory& factory,
+                                 const GrProcessor& effect)
     : INHERITED (factory) {
-    const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
+    const GrConicEffect& ce = effect.cast<GrConicEffect>();
     fEdgeType = ce.getEdgeType();
 }
 
-void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder,
-                               const GrDrawEffect& drawEffect,
-                               EffectKey key,
+void GrGLConicEffect::emitCode(GrGLFullProgramBuilder* builder,
+                               const GrGeometryProcessor& geometryProcessor,
+                               const GrProcessorKey& key,
                                const char* outputColor,
                                const char* inputColor,
                                const TransformedCoordsArray&,
@@ -52,284 +53,290 @@
 
     builder->addVarying(kVec4f_GrSLType, "ConicCoeffs",
                               &vsName, &fsName);
-    const SkString* attr0Name =
-        builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-    builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
 
-    builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
+    const GrShaderVar& inConicCoeffs = geometryProcessor.cast<GrConicEffect>().inConicCoeffs();
+    GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+    vsBuilder->codeAppendf("%s = %s;", vsName, inConicCoeffs.c_str());
+
+    GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    fsBuilder->codeAppend("float edgeAlpha;");
 
     switch (fEdgeType) {
-        case kHairlineAA_GrEffectEdgeType: {
-            SkAssertResult(builder->enableFeature(
-                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
-            builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
-            builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
-            builder->fsCodeAppendf("\t\tfloat dfdx =\n"
-                                   "\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
+        case kHairlineAA_GrProcessorEdgeType: {
+            SkAssertResult(fsBuilder->enableFeature(
+                    GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+            fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
+            fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
+            fsBuilder->codeAppendf("float dfdx ="
+                                   "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
                                    fsName, fsName, fsName);
-            builder->fsCodeAppendf("\t\tfloat dfdy =\n"
-                                   "\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
+            fsBuilder->codeAppendf("float dfdy ="
+                                   "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
                                    fsName, fsName, fsName);
-            builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
-            builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
-            builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
+            fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
+            fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
+            fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", fsName, fsName,
                                    fsName, fsName);
-            builder->fsCodeAppend("\t\tfunc = abs(func);\n");
-            builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
-            builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
+            fsBuilder->codeAppend("func = abs(func);");
+            fsBuilder->codeAppend("edgeAlpha = func / gFM;");
+            fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
             // Add line below for smooth cubic ramp
-            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+            // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
             break;
         }
-        case kFillAA_GrEffectEdgeType: {
-            SkAssertResult(builder->enableFeature(
-                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
-            builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
-            builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
-            builder->fsCodeAppendf("\t\tfloat dfdx =\n"
-                                   "\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
+        case kFillAA_GrProcessorEdgeType: {
+            SkAssertResult(fsBuilder->enableFeature(
+                    GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+            fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
+            fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
+            fsBuilder->codeAppendf("float dfdx ="
+                                   "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
                                    fsName, fsName, fsName);
-            builder->fsCodeAppendf("\t\tfloat dfdy =\n"
-                                   "\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
+            fsBuilder->codeAppendf("float dfdy ="
+                                   "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
                                    fsName, fsName, fsName);
-            builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
-            builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
-            builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
+            fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
+            fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
+            fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
                                    fsName, fsName);
-            builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
-            builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
+            fsBuilder->codeAppend("edgeAlpha = func / gFM;");
+            fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
             // Add line below for smooth cubic ramp
-            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+            // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
             break;
         }
-        case kFillBW_GrEffectEdgeType: {
-            builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
+        case kFillBW_GrProcessorEdgeType: {
+            fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
                                    fsName, fsName);
-            builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
+            fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
             break;
         }
         default:
             SkFAIL("Shouldn't get here");
     }
 
-    builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("%s = %s;", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
 }
 
-GrGLEffect::EffectKey GrGLConicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-    const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
-    return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+void GrGLConicEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                             GrProcessorKeyBuilder* b) {
+    const GrConicEffect& ce = processor.cast<GrConicEffect>();
+    uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+    b->add32(key);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
 GrConicEffect::~GrConicEffect() {}
 
-const GrBackendEffectFactory& GrConicEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrConicEffect>::getInstance();
+const GrBackendGeometryProcessorFactory& GrConicEffect::getFactory() const {
+    return GrTBackendGeometryProcessorFactory<GrConicEffect>::getInstance();
 }
 
-GrConicEffect::GrConicEffect(GrEffectEdgeType edgeType) : GrVertexEffect() {
-    this->addVertexAttrib(kVec4f_GrSLType);
-    fEdgeType = edgeType;
+GrConicEffect::GrConicEffect(GrPrimitiveEdgeType edgeType)
+    : fEdgeType(edgeType)
+    , fInConicCoeffs(this->addVertexAttrib(GrShaderVar("inConicCoeffs",
+                                                       kVec4f_GrSLType,
+                                                       GrShaderVar::kAttribute_TypeModifier))) {
 }
 
-bool GrConicEffect::onIsEqual(const GrEffect& other) const {
-    const GrConicEffect& ce = CastEffect<GrConicEffect>(other);
+bool GrConicEffect::onIsEqual(const GrProcessor& other) const {
+    const GrConicEffect& ce = other.cast<GrConicEffect>();
     return (ce.fEdgeType == fEdgeType);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrConicEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
 
-GrEffectRef* GrConicEffect::TestCreate(SkRandom* random,
-                                             GrContext*,
-                                             const GrDrawTargetCaps& caps,
-                                             GrTexture*[]) {
-    GrEffectRef* effect;
+GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random,
+                                               GrContext*,
+                                               const GrDrawTargetCaps& caps,
+                                               GrTexture*[]) {
+    GrGeometryProcessor* gp;
     do {
-        GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
-                                                    random->nextULessThan(kGrEffectEdgeTypeCnt));
-        effect = GrConicEffect::Create(edgeType, caps);
-    } while (NULL == effect);
-    return effect;
+        GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
+                                                    random->nextULessThan(kGrProcessorEdgeTypeCnt));
+        gp = GrConicEffect::Create(edgeType, caps);
+    } while (NULL == gp);
+    return gp;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 // Quad
 //////////////////////////////////////////////////////////////////////////////
 
-class GrGLQuadEffect : public GrGLVertexEffect {
+class GrGLQuadEffect : public GrGLGeometryProcessor {
 public:
-    GrGLQuadEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLQuadEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLFullShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLFullProgramBuilder* builder,
+                          const GrGeometryProcessor& geometryProcessor,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
 
 private:
-    GrEffectEdgeType fEdgeType;
+    GrPrimitiveEdgeType fEdgeType;
 
-    typedef GrGLVertexEffect INHERITED;
+    typedef GrGLGeometryProcessor INHERITED;
 };
 
-GrGLQuadEffect::GrGLQuadEffect(const GrBackendEffectFactory& factory,
-                                 const GrDrawEffect& drawEffect)
+GrGLQuadEffect::GrGLQuadEffect(const GrBackendProcessorFactory& factory,
+                                 const GrProcessor& effect)
     : INHERITED (factory) {
-    const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
+    const GrQuadEffect& ce = effect.cast<GrQuadEffect>();
     fEdgeType = ce.getEdgeType();
 }
 
-void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+void GrGLQuadEffect::emitCode(GrGLFullProgramBuilder* builder,
+                              const GrGeometryProcessor& geometryProcessor,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
                               const TextureSamplerArray& samplers) {
     const char *vsName, *fsName;
-
-    const SkString* attrName =
-        builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-    builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n");
-
     builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
 
+    GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+    const GrShaderVar& inHairQuadEdge = geometryProcessor.cast<GrQuadEffect>().inHairQuadEdge();
+    vsBuilder->codeAppendf("%s = %s;", vsName, inHairQuadEdge.c_str());
+
+    GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    fsBuilder->codeAppendf("float edgeAlpha;");
+
     switch (fEdgeType) {
-        case kHairlineAA_GrEffectEdgeType: {
-            SkAssertResult(builder->enableFeature(
-                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
-            builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
-            builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
-            builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
-                                   "\t\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
+        case kHairlineAA_GrProcessorEdgeType: {
+            SkAssertResult(fsBuilder->enableFeature(
+                    GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+            fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
+            fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
+            fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
+                                   "               2.0 * %s.x * duvdy.x - duvdy.y);",
                                    fsName, fsName);
-            builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
-                                   fsName);
-            builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
-            builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
+            fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
+            fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
+            fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
             // Add line below for smooth cubic ramp
-            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+            // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
             break;
         }
-        case kFillAA_GrEffectEdgeType: {
-            SkAssertResult(builder->enableFeature(
-                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
-            builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
-            builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
-            builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
-                                   "\t\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
+        case kFillAA_GrProcessorEdgeType: {
+            SkAssertResult(fsBuilder->enableFeature(
+                    GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+            fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
+            fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
+            fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
+                                   "               2.0 * %s.x * duvdy.x - duvdy.y);",
                                    fsName, fsName);
-            builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
-                                   fsName);
-            builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha / sqrt(dot(gF, gF));\n");
-            builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
+            fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
+            fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
+            fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
             // Add line below for smooth cubic ramp
-            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+            // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
             break;
         }
-        case kFillBW_GrEffectEdgeType: {
-            builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
-                                   fsName);
-            builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
+        case kFillBW_GrProcessorEdgeType: {
+            fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
+            fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
             break;
         }
         default:
             SkFAIL("Shouldn't get here");
     }
 
-    builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("%s = %s;", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
-
-
-    builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
 }
 
-GrGLEffect::EffectKey GrGLQuadEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-    const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
-    return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+void GrGLQuadEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                            GrProcessorKeyBuilder* b) {
+    const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
+    uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+    b->add32(key);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
 GrQuadEffect::~GrQuadEffect() {}
 
-const GrBackendEffectFactory& GrQuadEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrQuadEffect>::getInstance();
+const GrBackendGeometryProcessorFactory& GrQuadEffect::getFactory() const {
+    return GrTBackendGeometryProcessorFactory<GrQuadEffect>::getInstance();
 }
 
-GrQuadEffect::GrQuadEffect(GrEffectEdgeType edgeType) : GrVertexEffect() {
-    this->addVertexAttrib(kVec4f_GrSLType);
-    fEdgeType = edgeType;
+GrQuadEffect::GrQuadEffect(GrPrimitiveEdgeType edgeType)
+    : fEdgeType(edgeType)
+    , fInHairQuadEdge(this->addVertexAttrib(GrShaderVar("inCubicCoeffs",
+                                                        kVec4f_GrSLType,
+                                                        GrShaderVar::kAttribute_TypeModifier))) {
 }
 
-bool GrQuadEffect::onIsEqual(const GrEffect& other) const {
-    const GrQuadEffect& ce = CastEffect<GrQuadEffect>(other);
+bool GrQuadEffect::onIsEqual(const GrProcessor& other) const {
+    const GrQuadEffect& ce = other.cast<GrQuadEffect>();
     return (ce.fEdgeType == fEdgeType);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrQuadEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
 
-GrEffectRef* GrQuadEffect::TestCreate(SkRandom* random,
-                                             GrContext*,
-                                             const GrDrawTargetCaps& caps,
-                                             GrTexture*[]) {
-    GrEffectRef* effect;
+GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random,
+                                              GrContext*,
+                                              const GrDrawTargetCaps& caps,
+                                              GrTexture*[]) {
+    GrGeometryProcessor* gp;
     do {
-        GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
-                                                    random->nextULessThan(kGrEffectEdgeTypeCnt));
-        effect = GrQuadEffect::Create(edgeType, caps);
-    } while (NULL == effect);
-    return effect;
+        GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
+                random->nextULessThan(kGrProcessorEdgeTypeCnt));
+        gp = GrQuadEffect::Create(edgeType, caps);
+    } while (NULL == gp);
+    return gp;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 // Cubic
 //////////////////////////////////////////////////////////////////////////////
 
-class GrGLCubicEffect : public GrGLVertexEffect {
+class GrGLCubicEffect : public GrGLGeometryProcessor {
 public:
-    GrGLCubicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLCubicEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLFullShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLFullProgramBuilder* builder,
+                          const GrGeometryProcessor& geometryProcessor,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
 
 private:
-    GrEffectEdgeType fEdgeType;
+    GrPrimitiveEdgeType fEdgeType;
 
-    typedef GrGLVertexEffect INHERITED;
+    typedef GrGLGeometryProcessor INHERITED;
 };
 
-GrGLCubicEffect::GrGLCubicEffect(const GrBackendEffectFactory& factory,
-                                 const GrDrawEffect& drawEffect)
+GrGLCubicEffect::GrGLCubicEffect(const GrBackendProcessorFactory& factory,
+                                 const GrProcessor& processor)
     : INHERITED (factory) {
-    const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
+    const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
     fEdgeType = ce.getEdgeType();
 }
 
-void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder,
-                               const GrDrawEffect& drawEffect,
-                               EffectKey key,
+void GrGLCubicEffect::emitCode(GrGLFullProgramBuilder* builder,
+                               const GrGeometryProcessor& geometryProcessor,
+                               const GrProcessorKey& key,
                                const char* outputColor,
                                const char* inputColor,
                                const TransformedCoordsArray&,
@@ -337,107 +344,140 @@
     const char *vsName, *fsName;
 
     builder->addVarying(kVec4f_GrSLType, "CubicCoeffs",
-                              &vsName, &fsName);
-    const SkString* attr0Name =
-        builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-    builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
+                              &vsName, &fsName, GrGLShaderVar::kHigh_Precision);
 
-    builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
+    GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+    const GrShaderVar& inCubicCoeffs = geometryProcessor.cast<GrCubicEffect>().inCubicCoeffs();
+    vsBuilder->codeAppendf("%s = %s;", vsName, inCubicCoeffs.c_str());
+
+    GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+
+    GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
+    GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
+    GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
+    GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
+    GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
+    GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
+    GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
+    GrGLShaderVar func("func", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
+
+    fsBuilder->declAppend(edgeAlpha);
+    fsBuilder->declAppend(dklmdx);
+    fsBuilder->declAppend(dklmdy);
+    fsBuilder->declAppend(dfdx);
+    fsBuilder->declAppend(dfdy);
+    fsBuilder->declAppend(gF);
+    fsBuilder->declAppend(gFM);
+    fsBuilder->declAppend(func);
 
     switch (fEdgeType) {
-        case kHairlineAA_GrEffectEdgeType: {
-            SkAssertResult(builder->enableFeature(
-                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
-            builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
-            builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
-            builder->fsCodeAppendf("\t\tfloat dfdx =\n"
-                                   "\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
-                                   fsName, fsName, fsName, fsName);
-            builder->fsCodeAppendf("\t\tfloat dfdy =\n"
-                                   "\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
-                                   fsName, fsName, fsName, fsName);
-            builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
-            builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
-            builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
-                                   fsName, fsName, fsName, fsName, fsName);
-            builder->fsCodeAppend("\t\tfunc = abs(func);\n");
-            builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
-            builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
+        case kHairlineAA_GrProcessorEdgeType: {
+            SkAssertResult(fsBuilder->enableFeature(
+                    GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+            fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
+            fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
+            fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
+                                   dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
+                                   dklmdx.c_str(), fsName, dklmdx.c_str());
+            fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
+                                   dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
+                                   dklmdy.c_str(), fsName, dklmdy.c_str());
+            fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
+            fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
+            fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
+                                   func.c_str(), fsName, fsName, fsName, fsName, fsName);
+            fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
+            fsBuilder->codeAppendf("%s = %s / %s;",
+                                   edgeAlpha.c_str(), func.c_str(), gFM.c_str());
+            fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
+                                   edgeAlpha.c_str(), edgeAlpha.c_str());
             // Add line below for smooth cubic ramp
-            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+            // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
+            //                        edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
+            //                        edgeAlpha.c_str());
             break;
         }
-        case kFillAA_GrEffectEdgeType: {
-            SkAssertResult(builder->enableFeature(
-                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
-            builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
-            builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
-            builder->fsCodeAppendf("\t\tfloat dfdx =\n"
-                                   "\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
-                                   fsName, fsName, fsName, fsName);
-            builder->fsCodeAppendf("\t\tfloat dfdy =\n"
-                                   "\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
-                                   fsName, fsName, fsName, fsName);
-            builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
-            builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
-            builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
-                                   fsName, fsName, fsName, fsName, fsName);
-            builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
-            builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
+        case kFillAA_GrProcessorEdgeType: {
+            SkAssertResult(fsBuilder->enableFeature(
+                    GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+            fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
+            fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
+            fsBuilder->codeAppendf("%s ="
+                                   "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
+                                   dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
+                                   dklmdx.c_str(), fsName, dklmdx.c_str());
+            fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
+                                   dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
+                                   dklmdy.c_str(), fsName, dklmdy.c_str());
+            fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
+            fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
+            fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
+                                   func.c_str(), fsName, fsName, fsName, fsName, fsName);
+            fsBuilder->codeAppendf("%s = %s / %s;",
+                                   edgeAlpha.c_str(), func.c_str(), gFM.c_str());
+            fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
+                                   edgeAlpha.c_str(), edgeAlpha.c_str());
             // Add line below for smooth cubic ramp
-            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
+            // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
+            //                        edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
+            //                        edgeAlpha.c_str());
             break;
         }
-        case kFillBW_GrEffectEdgeType: {
-            builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
-                                   fsName, fsName, fsName, fsName, fsName);
-            builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
+        case kFillBW_GrProcessorEdgeType: {
+            fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
+                                   edgeAlpha.c_str(), fsName, fsName, fsName, fsName, fsName);
+            fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
             break;
         }
         default:
             SkFAIL("Shouldn't get here");
     }
 
-    builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
-                           (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
+    fsBuilder->codeAppendf("%s = %s;", outputColor,
+                           (GrGLSLExpr4(inputColor) * GrGLSLExpr1(edgeAlpha.c_str())).c_str());
 }
 
-GrGLEffect::EffectKey GrGLCubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-    const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
-    return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+void GrGLCubicEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                             GrProcessorKeyBuilder* b) {
+    const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
+    uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+    b->add32(key);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
 GrCubicEffect::~GrCubicEffect() {}
 
-const GrBackendEffectFactory& GrCubicEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrCubicEffect>::getInstance();
+const GrBackendGeometryProcessorFactory& GrCubicEffect::getFactory() const {
+    return GrTBackendGeometryProcessorFactory<GrCubicEffect>::getInstance();
 }
 
-GrCubicEffect::GrCubicEffect(GrEffectEdgeType edgeType) : GrVertexEffect() {
-    this->addVertexAttrib(kVec4f_GrSLType);
-    fEdgeType = edgeType;
+GrCubicEffect::GrCubicEffect(GrPrimitiveEdgeType edgeType)
+    : fEdgeType(edgeType)
+    , fInCubicCoeffs(this->addVertexAttrib(GrShaderVar("inCubicCoeffs",
+                                                       kVec4f_GrSLType,
+                                                       GrShaderVar::kAttribute_TypeModifier))) {
 }
 
-bool GrCubicEffect::onIsEqual(const GrEffect& other) const {
-    const GrCubicEffect& ce = CastEffect<GrCubicEffect>(other);
+bool GrCubicEffect::onIsEqual(const GrProcessor& other) const {
+    const GrCubicEffect& ce = other.cast<GrCubicEffect>();
     return (ce.fEdgeType == fEdgeType);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrCubicEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
 
-GrEffectRef* GrCubicEffect::TestCreate(SkRandom* random,
-                                             GrContext*,
-                                             const GrDrawTargetCaps& caps,
-                                             GrTexture*[]) {
-    GrEffectRef* effect;
+GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random,
+                                               GrContext*,
+                                               const GrDrawTargetCaps& caps,
+                                               GrTexture*[]) {
+    GrGeometryProcessor* gp;
     do {
-        GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
-                                                    random->nextULessThan(kGrEffectEdgeTypeCnt));
-        effect = GrCubicEffect::Create(edgeType, caps);
-    } while (NULL == effect);
-    return effect;
+        GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
+                                                    random->nextULessThan(kGrProcessorEdgeTypeCnt));
+        gp = GrCubicEffect::Create(edgeType, caps);
+    } while (NULL == gp);
+    return gp;
 }
+
diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h
index e2fc592..cb79ac3 100644
--- a/src/gpu/effects/GrBezierEffect.h
+++ b/src/gpu/effects/GrBezierEffect.h
@@ -9,8 +9,8 @@
 #define GrBezierEffect_DEFINED
 
 #include "GrDrawTargetCaps.h"
-#include "GrEffect.h"
-#include "GrVertexEffect.h"
+#include "GrProcessor.h"
+#include "GrGeometryProcessor.h"
 #include "GrTypesPriv.h"
 
 /**
@@ -55,26 +55,30 @@
  */
 class GrGLConicEffect;
 
-class GrConicEffect : public GrVertexEffect {
+class GrConicEffect : public GrGeometryProcessor {
 public:
-    static GrEffectRef* Create(const GrEffectEdgeType edgeType, const GrDrawTargetCaps& caps) {
-        GR_CREATE_STATIC_EFFECT(gConicFillAA, GrConicEffect, (kFillAA_GrEffectEdgeType));
-        GR_CREATE_STATIC_EFFECT(gConicHairAA, GrConicEffect, (kHairlineAA_GrEffectEdgeType));
-        GR_CREATE_STATIC_EFFECT(gConicFillBW, GrConicEffect, (kFillBW_GrEffectEdgeType));
+    static GrGeometryProcessor* Create(const GrPrimitiveEdgeType edgeType,
+                                       const GrDrawTargetCaps& caps) {
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gConicFillAA, GrConicEffect,
+                                            (kFillAA_GrProcessorEdgeType));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gConicHairAA, GrConicEffect,
+                                            (kHairlineAA_GrProcessorEdgeType));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gConicFillBW, GrConicEffect,
+                                            (kFillBW_GrProcessorEdgeType));
         switch (edgeType) {
-            case kFillAA_GrEffectEdgeType:
+            case kFillAA_GrProcessorEdgeType:
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
                 gConicFillAA->ref();
                 return gConicFillAA;
-            case kHairlineAA_GrEffectEdgeType:
+            case kHairlineAA_GrProcessorEdgeType:
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
                 gConicHairAA->ref();
                 return gConicHairAA;
-            case kFillBW_GrEffectEdgeType:
+            case kFillBW_GrProcessorEdgeType:
                 gConicFillBW->ref();
                 return gConicFillBW;
             default:
@@ -86,29 +90,31 @@
 
     static const char* Name() { return "Conic"; }
 
-    inline bool isAntiAliased() const { return GrEffectEdgeTypeIsAA(fEdgeType); }
-    inline bool isFilled() const { return GrEffectEdgeTypeIsFill(fEdgeType); }
-    inline GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    inline const GrShaderVar& inConicCoeffs() const { return fInConicCoeffs; }
+    inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
+    inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
+    inline GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
 
-    typedef GrGLConicEffect GLEffect;
+    typedef GrGLConicEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color,
                                             uint32_t* validFlags) const SK_OVERRIDE {
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    GrConicEffect(GrEffectEdgeType);
+    GrConicEffect(GrPrimitiveEdgeType);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
-    GrEffectEdgeType fEdgeType;
+    GrPrimitiveEdgeType   fEdgeType;
+    const GrShaderVar& fInConicCoeffs;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrVertexEffect INHERITED;
+    typedef GrGeometryProcessor INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -122,26 +128,30 @@
  */
 class GrGLQuadEffect;
 
-class GrQuadEffect : public GrVertexEffect {
+class GrQuadEffect : public GrGeometryProcessor {
 public:
-    static GrEffectRef* Create(const GrEffectEdgeType edgeType, const GrDrawTargetCaps& caps) {
-        GR_CREATE_STATIC_EFFECT(gQuadFillAA, GrQuadEffect, (kFillAA_GrEffectEdgeType));
-        GR_CREATE_STATIC_EFFECT(gQuadHairAA, GrQuadEffect, (kHairlineAA_GrEffectEdgeType));
-        GR_CREATE_STATIC_EFFECT(gQuadFillBW, GrQuadEffect, (kFillBW_GrEffectEdgeType));
+    static GrGeometryProcessor* Create(const GrPrimitiveEdgeType edgeType,
+                                       const GrDrawTargetCaps& caps) {
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gQuadFillAA, GrQuadEffect,
+                                            (kFillAA_GrProcessorEdgeType));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gQuadHairAA, GrQuadEffect,
+                                            (kHairlineAA_GrProcessorEdgeType));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gQuadFillBW, GrQuadEffect,
+                                            (kFillBW_GrProcessorEdgeType));
         switch (edgeType) {
-            case kFillAA_GrEffectEdgeType:
+            case kFillAA_GrProcessorEdgeType:
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
                 gQuadFillAA->ref();
                 return gQuadFillAA;
-            case kHairlineAA_GrEffectEdgeType:
+            case kHairlineAA_GrProcessorEdgeType:
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
                 gQuadHairAA->ref();
                 return gQuadHairAA;
-            case kFillBW_GrEffectEdgeType:
+            case kFillBW_GrProcessorEdgeType:
                 gQuadFillBW->ref();
                 return gQuadFillBW;
             default:
@@ -153,29 +163,31 @@
 
     static const char* Name() { return "Quad"; }
 
-    inline bool isAntiAliased() const { return GrEffectEdgeTypeIsAA(fEdgeType); }
-    inline bool isFilled() const { return GrEffectEdgeTypeIsFill(fEdgeType); }
-    inline GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    inline const GrShaderVar& inHairQuadEdge() const { return fInHairQuadEdge; }
+    inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
+    inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
+    inline GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
 
-    typedef GrGLQuadEffect GLEffect;
+    typedef GrGLQuadEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color,
                                             uint32_t* validFlags) const SK_OVERRIDE {
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    GrQuadEffect(GrEffectEdgeType);
+    GrQuadEffect(GrPrimitiveEdgeType);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
-    GrEffectEdgeType fEdgeType;
+    GrPrimitiveEdgeType   fEdgeType;
+    const GrShaderVar& fInHairQuadEdge;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrVertexEffect INHERITED;
+    typedef GrGeometryProcessor INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -191,26 +203,30 @@
  */
 class GrGLCubicEffect;
 
-class GrCubicEffect : public GrVertexEffect {
+class GrCubicEffect : public GrGeometryProcessor {
 public:
-    static GrEffectRef* Create(const GrEffectEdgeType edgeType, const GrDrawTargetCaps& caps) {
-        GR_CREATE_STATIC_EFFECT(gCubicFillAA, GrCubicEffect, (kFillAA_GrEffectEdgeType));
-        GR_CREATE_STATIC_EFFECT(gCubicHairAA, GrCubicEffect, (kHairlineAA_GrEffectEdgeType));
-        GR_CREATE_STATIC_EFFECT(gCubicFillBW, GrCubicEffect, (kFillBW_GrEffectEdgeType));
+    static GrGeometryProcessor* Create(const GrPrimitiveEdgeType edgeType,
+                                       const GrDrawTargetCaps& caps) {
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gCubicFillAA, GrCubicEffect,
+                                            (kFillAA_GrProcessorEdgeType));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gCubicHairAA, GrCubicEffect,
+                                            (kHairlineAA_GrProcessorEdgeType));
+        GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gCubicFillBW, GrCubicEffect,
+                                            (kFillBW_GrProcessorEdgeType));
         switch (edgeType) {
-            case kFillAA_GrEffectEdgeType:
+            case kFillAA_GrProcessorEdgeType:
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
                 gCubicFillAA->ref();
                 return gCubicFillAA;
-            case kHairlineAA_GrEffectEdgeType:
+            case kHairlineAA_GrProcessorEdgeType:
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
                 gCubicHairAA->ref();
                 return gCubicHairAA;
-            case kFillBW_GrEffectEdgeType:
+            case kFillBW_GrProcessorEdgeType:
                 gCubicFillBW->ref();
                 return gCubicFillBW;
             default:
@@ -222,29 +238,31 @@
 
     static const char* Name() { return "Cubic"; }
 
-    inline bool isAntiAliased() const { return GrEffectEdgeTypeIsAA(fEdgeType); }
-    inline bool isFilled() const { return GrEffectEdgeTypeIsFill(fEdgeType); }
-    inline GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    inline const GrShaderVar& inCubicCoeffs() const { return fInCubicCoeffs; }
+    inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
+    inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
+    inline GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
 
-    typedef GrGLCubicEffect GLEffect;
+    typedef GrGLCubicEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color,
                                             uint32_t* validFlags) const SK_OVERRIDE {
         *validFlags = 0;
     }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    GrCubicEffect(GrEffectEdgeType);
+    GrCubicEffect(GrPrimitiveEdgeType);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
-    GrEffectEdgeType fEdgeType;
+    GrPrimitiveEdgeType   fEdgeType;
+    const GrShaderVar& fInCubicCoeffs;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrVertexEffect INHERITED;
+    typedef GrGeometryProcessor INHERITED;
 };
 
 #endif
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index 9c6d1a3..d73e604 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -1,5 +1,14 @@
+/*
+ * 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 "gl/builders/GrGLProgramBuilder.h"
 #include "GrBicubicEffect.h"
 
+
 #define DS(x) SkDoubleToScalar(x)
 
 const SkScalar GrBicubicEffect::gMitchellCoefficients[16] = {
@@ -10,53 +19,53 @@
 };
 
 
-class GrGLBicubicEffect : public GrGLEffect {
+class GrGLBicubicEffect : public GrGLFragmentProcessor {
 public:
-    GrGLBicubicEffect(const GrBackendEffectFactory& factory,
-                      const GrDrawEffect&);
+    GrGLBicubicEffect(const GrBackendProcessorFactory& factory,
+                      const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-        const GrTextureDomain& domain = drawEffect.castEffect<GrBicubicEffect>().domain();
-        return GrTextureDomain::GLDomain::DomainKey(domain);
+    static inline void GenKey(const GrProcessor& effect, const GrGLCaps&,
+                              GrProcessorKeyBuilder* b) {
+        const GrTextureDomain& domain = effect.cast<GrBicubicEffect>().domain();
+        b->add32(GrTextureDomain::GLDomain::DomainKey(domain));
     }
 
 private:
-    typedef GrGLUniformManager::UniformHandle        UniformHandle;
+    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 
     UniformHandle               fCoefficientsUni;
     UniformHandle               fImageIncrementUni;
     GrTextureDomain::GLDomain   fDomain;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GrGLBicubicEffect::GrGLBicubicEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+GrGLBicubicEffect::GrGLBicubicEffect(const GrBackendProcessorFactory& factory, const GrProcessor&)
     : INHERITED(factory) {
 }
 
-void GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder,
-                                 const GrDrawEffect& drawEffect,
-                                 EffectKey key,
+void GrGLBicubicEffect::emitCode(GrGLProgramBuilder* builder,
+                                 const GrFragmentProcessor& effect,
+                                 const GrProcessorKey& key,
                                  const char* outputColor,
                                  const char* inputColor,
                                  const TransformedCoordsArray& coords,
                                  const TextureSamplerArray& samplers) {
-    const GrTextureDomain& domain = drawEffect.castEffect<GrBicubicEffect>().domain();
+    const GrTextureDomain& domain = effect.cast<GrBicubicEffect>().domain();
 
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
-    fCoefficientsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fCoefficientsUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                            kMat44f_GrSLType, "Coefficients");
-    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                              kVec2f_GrSLType, "ImageIncrement");
 
     const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
@@ -72,7 +81,9 @@
         GrGLShaderVar("c2",            kVec4f_GrSLType),
         GrGLShaderVar("c3",            kVec4f_GrSLType),
     };
-    builder->fsEmitFunction(kVec4f_GrSLType,
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+    fsBuilder->emitFunction(kVec4f_GrSLType,
                             "cubicBlend",
                             SK_ARRAY_COUNT(gCubicBlendArgs),
                             gCubicBlendArgs,
@@ -80,40 +91,40 @@
                             "\tvec4 c = coefficients * ts;\n"
                             "\treturn c.x * c0 + c.y * c1 + c.z * c2 + c.w * c3;\n",
                             &cubicBlendName);
-    builder->fsCodeAppendf("\tvec2 coord = %s - %s * vec2(0.5);\n", coords2D.c_str(), imgInc);
+    fsBuilder->codeAppendf("\tvec2 coord = %s - %s * vec2(0.5);\n", coords2D.c_str(), imgInc);
     // We unnormalize the coord in order to determine our fractional offset (f) within the texel
     // We then snap coord to a texel center and renormalize. The snap prevents cases where the
     // starting coords are near a texel boundary and accumulations of imgInc would cause us to skip/
     // double hit a texel.
-    builder->fsCodeAppendf("\tcoord /= %s;\n", imgInc);
-    builder->fsCodeAppend("\tvec2 f = fract(coord);\n");
-    builder->fsCodeAppendf("\tcoord = (coord - f + vec2(0.5)) * %s;\n", imgInc);
-    builder->fsCodeAppend("\tvec4 rowColors[4];\n");
+    fsBuilder->codeAppendf("\tcoord /= %s;\n", imgInc);
+    fsBuilder->codeAppend("\tvec2 f = fract(coord);\n");
+    fsBuilder->codeAppendf("\tcoord = (coord - f + vec2(0.5)) * %s;\n", imgInc);
+    fsBuilder->codeAppend("\tvec4 rowColors[4];\n");
     for (int y = 0; y < 4; ++y) {
         for (int x = 0; x < 4; ++x) {
             SkString coord;
             coord.printf("coord + %s * vec2(%d, %d)", imgInc, x - 1, y - 1);
             SkString sampleVar;
             sampleVar.printf("rowColors[%d]", x);
-            fDomain.sampleTexture(builder, domain, sampleVar.c_str(), coord, samplers[0]);
+            fDomain.sampleTexture(fsBuilder, domain, sampleVar.c_str(), coord, samplers[0]);
         }
-        builder->fsCodeAppendf("\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n", y, cubicBlendName.c_str(), coeff);
+        fsBuilder->codeAppendf("\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n", y, cubicBlendName.c_str(), coeff);
     }
     SkString bicubicColor;
     bicubicColor.printf("%s(%s, f.y, s0, s1, s2, s3)", cubicBlendName.c_str(), coeff);
-    builder->fsCodeAppendf("\t%s = %s;\n", outputColor, (GrGLSLExpr4(bicubicColor.c_str()) * GrGLSLExpr4(inputColor)).c_str());
+    fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, (GrGLSLExpr4(bicubicColor.c_str()) * GrGLSLExpr4(inputColor)).c_str());
 }
 
-void GrGLBicubicEffect::setData(const GrGLUniformManager& uman,
-                                const GrDrawEffect& drawEffect) {
-    const GrBicubicEffect& effect = drawEffect.castEffect<GrBicubicEffect>();
-    const GrTexture& texture = *effect.texture(0);
+void GrGLBicubicEffect::setData(const GrGLProgramDataManager& pdman,
+                                const GrProcessor& processor) {
+    const GrBicubicEffect& bicubicEffect = processor.cast<GrBicubicEffect>();
+    const GrTexture& texture = *processor.texture(0);
     float imageIncrement[2];
     imageIncrement[0] = 1.0f / texture.width();
     imageIncrement[1] = 1.0f / texture.height();
-    uman.set2fv(fImageIncrementUni, 1, imageIncrement);
-    uman.setMatrix4f(fCoefficientsUni, effect.coefficients());
-    fDomain.setData(uman, effect.domain(), texture.origin());
+    pdman.set2fv(fImageIncrementUni, 1, imageIncrement);
+    pdman.setMatrix4f(fCoefficientsUni, bicubicEffect.coefficients());
+    fDomain.setData(pdman, bicubicEffect.domain(), texture.origin());
 }
 
 static inline void convert_row_major_scalar_coeffs_to_column_major_floats(float dst[16],
@@ -147,14 +158,15 @@
 GrBicubicEffect::~GrBicubicEffect() {
 }
 
-const GrBackendEffectFactory& GrBicubicEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrBicubicEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrBicubicEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrBicubicEffect>::getInstance();
 }
 
-bool GrBicubicEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrBicubicEffect& s = CastEffect<GrBicubicEffect>(sBase);
+bool GrBicubicEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrBicubicEffect& s = sBase.cast<GrBicubicEffect>();
     return this->textureAccess(0) == s.textureAccess(0) &&
-           !memcmp(fCoefficients, s.coefficients(), 16);
+           !memcmp(fCoefficients, s.coefficients(), 16) &&
+           fDomain == s.fDomain;
 }
 
 void GrBicubicEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
@@ -163,14 +175,14 @@
     return;
 }
 
-GR_DEFINE_EFFECT_TEST(GrBicubicEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrBicubicEffect);
 
-GrEffectRef* GrBicubicEffect::TestCreate(SkRandom* random,
-                                         GrContext* context,
-                                         const GrDrawTargetCaps&,
-                                         GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
+GrFragmentProcessor* GrBicubicEffect::TestCreate(SkRandom* random,
+                                                 GrContext* context,
+                                                 const GrDrawTargetCaps&,
+                                                 GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                      GrProcessorUnitTest::kAlphaTextureIdx;
     SkScalar coefficients[16];
     for (int i = 0; i < 16; i++) {
         coefficients[i] = random->nextSScalar1();
diff --git a/src/gpu/effects/GrBicubicEffect.h b/src/gpu/effects/GrBicubicEffect.h
index 1998e68..03476da 100644
--- a/src/gpu/effects/GrBicubicEffect.h
+++ b/src/gpu/effects/GrBicubicEffect.h
@@ -10,9 +10,8 @@
 
 #include "GrSingleTextureEffect.h"
 #include "GrTextureDomain.h"
-#include "GrDrawEffect.h"
-#include "gl/GrGLEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLProcessor.h"
+#include "GrTBackendProcessorFactory.h"
 
 class GrGLBicubicEffect;
 
@@ -27,9 +26,9 @@
     static const char* Name() { return "Bicubic"; }
     const float* coefficients() const { return fCoefficients; }
 
-    typedef GrGLBicubicEffect GLEffect;
+    typedef GrGLBicubicEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
     const GrTextureDomain& domain() const { return fDomain; }
@@ -37,25 +36,25 @@
     /**
      * Create a simple filter effect with custom bicubic coefficients and optional domain.
      */
-    static GrEffectRef* Create(GrTexture* tex, const SkScalar coefficients[16],
-                               const SkRect* domain = NULL) {
+    static GrFragmentProcessor* Create(GrTexture* tex, const SkScalar coefficients[16],
+                            const SkRect* domain = NULL) {
         if (NULL == domain) {
             static const SkShader::TileMode kTileModes[] = { SkShader::kClamp_TileMode,
                                                              SkShader::kClamp_TileMode };
-            return Create(tex, coefficients, MakeDivByTextureWHMatrix(tex), kTileModes);
+            return Create(tex, coefficients, GrCoordTransform::MakeDivByTextureWHMatrix(tex),
+                          kTileModes);
         } else {
-            AutoEffectUnref effect(SkNEW_ARGS(GrBicubicEffect, (tex, coefficients,
-                                                                MakeDivByTextureWHMatrix(tex),
-                                                                *domain)));
-            return CreateEffectRef(effect);
+            return SkNEW_ARGS(GrBicubicEffect, (tex, coefficients,
+                                                GrCoordTransform::MakeDivByTextureWHMatrix(tex),
+                                                *domain));
         }
     }
 
     /**
      * Create a Mitchell filter effect with specified texture matrix and x/y tile modes.
      */
-    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix,
-                               SkShader::TileMode tileModes[2]) {
+    static GrFragmentProcessor* Create(GrTexture* tex, const SkMatrix& matrix,
+                            SkShader::TileMode tileModes[2]) {
         return Create(tex, gMitchellCoefficients, matrix, tileModes);
     }
 
@@ -63,19 +62,18 @@
      * Create a filter effect with custom bicubic coefficients, the texture matrix, and the x/y
      * tilemodes.
      */
-    static GrEffectRef* Create(GrTexture* tex, const SkScalar coefficients[16],
-                               const SkMatrix& matrix, const SkShader::TileMode tileModes[2]) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrBicubicEffect, (tex, coefficients, matrix, tileModes)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* tex, const SkScalar coefficients[16],
+                                       const SkMatrix& matrix,
+                                       const SkShader::TileMode tileModes[2]) {
+        return SkNEW_ARGS(GrBicubicEffect, (tex, coefficients, matrix, tileModes));
     }
 
     /**
      * Create a Mitchell filter effect with a texture matrix and a domain.
      */
-    static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const SkRect& domain) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrBicubicEffect, (tex, gMitchellCoefficients, matrix,
-                                                            domain)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* tex, const SkMatrix& matrix,
+                                       const SkRect& domain) {
+        return SkNEW_ARGS(GrBicubicEffect, (tex, gMitchellCoefficients, matrix, domain));
     }
 
     /**
@@ -93,12 +91,12 @@
                     const SkMatrix &matrix, const SkShader::TileMode tileModes[2]);
     GrBicubicEffect(GrTexture*, const SkScalar coefficients[16],
                     const SkMatrix &matrix, const SkRect& domain);
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     float           fCoefficients[16];
     GrTextureDomain fDomain;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     static const SkScalar gMitchellCoefficients[16];
 
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index f33ad23..3042d86 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -7,79 +7,96 @@
 
 #include "GrConfigConversionEffect.h"
 #include "GrContext.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 #include "GrSimpleTextureEffect.h"
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "SkMatrix.h"
 
-class GrGLConfigConversionEffect : public GrGLEffect {
+class GrGLConfigConversionEffect : public GrGLFragmentProcessor {
 public:
-    GrGLConfigConversionEffect(const GrBackendEffectFactory& factory,
-                               const GrDrawEffect& drawEffect)
+    GrGLConfigConversionEffect(const GrBackendProcessorFactory& factory,
+                               const GrProcessor& processor)
     : INHERITED (factory) {
-        const GrConfigConversionEffect& effect = drawEffect.castEffect<GrConfigConversionEffect>();
-        fSwapRedAndBlue = effect.swapsRedAndBlue();
-        fPMConversion = effect.pmConversion();
+        const GrConfigConversionEffect& configConversionEffect =
+                processor.cast<GrConfigConversionEffect>();
+        fSwapRedAndBlue = configConversionEffect.swapsRedAndBlue();
+        fPMConversion = configConversionEffect.pmConversion();
     }
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect&,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray& coords,
                           const TextureSamplerArray& samplers) SK_OVERRIDE {
-        builder->fsCodeAppendf("\t\t%s = ", outputColor);
-        builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
-        builder->fsCodeAppend(";\n");
+        // Using highp for GLES here in order to avoid some precision issues on specific GPUs.
+        GrGLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
+        SkString tmpDecl;
+        tmpVar.appendDecl(builder->ctxInfo(), &tmpDecl);
+
+        GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+
+        fsBuilder->codeAppendf("%s;", tmpDecl.c_str());
+
+        fsBuilder->codeAppendf("%s = ", tmpVar.c_str());
+        fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
+        fsBuilder->codeAppend(";");
+
         if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) {
             SkASSERT(fSwapRedAndBlue);
-            builder->fsCodeAppendf("\t%s = %s.bgra;\n", outputColor, outputColor);
+            fsBuilder->codeAppendf("%s = %s.bgra;", outputColor, tmpVar.c_str());
         } else {
             const char* swiz = fSwapRedAndBlue ? "bgr" : "rgb";
             switch (fPMConversion) {
                 case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion:
-                    builder->fsCodeAppendf(
-                        "\t\t%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);\n",
-                        outputColor, outputColor, swiz, outputColor, outputColor);
+                    fsBuilder->codeAppendf(
+                        "%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);",
+                        tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
                     break;
                 case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversion:
                     // Add a compensation(0.001) here to avoid the side effect of the floor operation.
                     // In Intel GPUs, the integer value converted from floor(%s.r * 255.0) / 255.0
                     // is less than the integer value converted from  %s.r by 1 when the %s.r is
                     // converted from the integer value 2^n, such as 1, 2, 4, 8, etc.
-                    builder->fsCodeAppendf(
-                        "\t\t%s = vec4(floor(%s.%s * %s.a * 255.0 + 0.001) / 255.0, %s.a);\n",
-                        outputColor, outputColor, swiz, outputColor, outputColor);
+                    fsBuilder->codeAppendf(
+                        "%s = vec4(floor(%s.%s * %s.a * 255.0 + 0.001) / 255.0, %s.a);",
+                        tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
                     break;
                 case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion:
-                    builder->fsCodeAppendf("\t\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s.a * 255.0) / 255.0, %s.a);\n",
-                        outputColor, outputColor, outputColor, swiz, outputColor, outputColor);
+                    fsBuilder->codeAppendf(
+                        "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s.a * 255.0) / 255.0, %s.a);",
+                        tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
                     break;
                 case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion:
-                    builder->fsCodeAppendf("\t\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / %s.a * 255.0) / 255.0, %s.a);\n",
-                        outputColor, outputColor, outputColor, swiz, outputColor, outputColor);
+                    fsBuilder->codeAppendf(
+                        "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / %s.a * 255.0) / 255.0, %s.a);",
+                        tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
                     break;
                 default:
                     SkFAIL("Unknown conversion op.");
                     break;
             }
+            fsBuilder->codeAppendf("%s = %s;", outputColor, tmpVar.c_str());
         }
         SkString modulate;
         GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
-        builder->fsCodeAppend(modulate.c_str());
+        fsBuilder->codeAppend(modulate.c_str());
     }
 
-    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-        const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigConversionEffect>();
-        return static_cast<EffectKey>(conv.swapsRedAndBlue()) | (conv.pmConversion() << 1);
+    static inline void GenKey(const GrProcessor& processor, const GrGLCaps&,
+                              GrProcessorKeyBuilder* b) {
+        const GrConfigConversionEffect& conv = processor.cast<GrConfigConversionEffect>();
+        uint32_t key = (conv.swapsRedAndBlue() ? 0 : 1) | (conv.pmConversion() << 1);
+        b->add32(key);
     }
 
 private:
     bool                                    fSwapRedAndBlue;
     GrConfigConversionEffect::PMConversion  fPMConversion;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 
 };
 
@@ -98,12 +115,12 @@
     SkASSERT(swapRedAndBlue || kNone_PMConversion != pmConversion);
 }
 
-const GrBackendEffectFactory& GrConfigConversionEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrConfigConversionEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrConfigConversionEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrConfigConversionEffect>::getInstance();
 }
 
-bool GrConfigConversionEffect::onIsEqual(const GrEffect& s) const {
-    const GrConfigConversionEffect& other = CastEffect<GrConfigConversionEffect>(s);
+bool GrConfigConversionEffect::onIsEqual(const GrProcessor& s) const {
+    const GrConfigConversionEffect& other = s.cast<GrConfigConversionEffect>();
     return this->texture(0) == s.texture(0) &&
            other.fSwapRedAndBlue == fSwapRedAndBlue &&
            other.fPMConversion == fPMConversion;
@@ -116,12 +133,12 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrConfigConversionEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConfigConversionEffect);
 
-GrEffectRef* GrConfigConversionEffect::TestCreate(SkRandom* random,
-                                                  GrContext*,
-                                                  const GrDrawTargetCaps&,
-                                                  GrTexture* textures[]) {
+GrFragmentProcessor* GrConfigConversionEffect::TestCreate(SkRandom* random,
+                                                          GrContext*,
+                                                          const GrDrawTargetCaps&,
+                                                          GrTexture* textures[]) {
     PMConversion pmConv = static_cast<PMConversion>(random->nextULessThan(kPMConversionCnt));
     bool swapRB;
     if (kNone_PMConversion == pmConv) {
@@ -129,12 +146,11 @@
     } else {
         swapRB = random->nextBool();
     }
-    AutoEffectUnref effect(SkNEW_ARGS(GrConfigConversionEffect,
-                                      (textures[GrEffectUnitTest::kSkiaPMTextureIdx],
+    return SkNEW_ARGS(GrConfigConversionEffect,
+                                      (textures[GrProcessorUnitTest::kSkiaPMTextureIdx],
                                        swapRB,
                                        pmConv,
-                                       GrEffectUnitTest::TestMatrix(random))));
-    return CreateEffectRef(effect);
+                                       GrProcessorUnitTest::TestMatrix(random)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -200,38 +216,31 @@
         // from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
         // We then verify that two reads produced the same values.
 
-        AutoEffectUnref pmToUPM1(SkNEW_ARGS(GrConfigConversionEffect, (dataTex,
-                                                                       false,
-                                                                       *pmToUPMRule,
-                                                                       SkMatrix::I())));
-        AutoEffectUnref upmToPM(SkNEW_ARGS(GrConfigConversionEffect, (readTex,
-                                                                      false,
-                                                                      *upmToPMRule,
-                                                                      SkMatrix::I())));
-        AutoEffectUnref pmToUPM2(SkNEW_ARGS(GrConfigConversionEffect, (tempTex,
-                                                                       false,
-                                                                       *pmToUPMRule,
-                                                                       SkMatrix::I())));
-
-        SkAutoTUnref<GrEffectRef> pmToUPMEffect1(CreateEffectRef(pmToUPM1));
-        SkAutoTUnref<GrEffectRef> upmToPMEffect(CreateEffectRef(upmToPM));
-        SkAutoTUnref<GrEffectRef> pmToUPMEffect2(CreateEffectRef(pmToUPM2));
+        SkAutoTUnref<GrFragmentProcessor> pmToUPM1(
+                SkNEW_ARGS(GrConfigConversionEffect,
+                           (dataTex, false, *pmToUPMRule, SkMatrix::I())));
+        SkAutoTUnref<GrFragmentProcessor> upmToPM(
+                SkNEW_ARGS(GrConfigConversionEffect,
+                           (readTex, false, *upmToPMRule, SkMatrix::I())));
+        SkAutoTUnref<GrFragmentProcessor> pmToUPM2(
+                SkNEW_ARGS(GrConfigConversionEffect,
+                           (tempTex, false, *pmToUPMRule, SkMatrix::I())));
 
         context->setRenderTarget(readTex->asRenderTarget());
         GrPaint paint1;
-        paint1.addColorEffect(pmToUPMEffect1);
+        paint1.addColorProcessor(pmToUPM1);
         context->drawRectToRect(paint1, kDstRect, kSrcRect);
 
         readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead);
 
         context->setRenderTarget(tempTex->asRenderTarget());
         GrPaint paint2;
-        paint2.addColorEffect(upmToPMEffect);
+        paint2.addColorProcessor(upmToPM);
         context->drawRectToRect(paint2, kDstRect, kSrcRect);
         context->setRenderTarget(readTex->asRenderTarget());
 
         GrPaint paint3;
-        paint3.addColorEffect(pmToUPMEffect2);
+        paint3.addColorProcessor(pmToUPM2);
         context->drawRectToRect(paint3, kDstRect, kSrcRect);
 
         readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, secondRead);
@@ -252,10 +261,10 @@
     }
 }
 
-const GrEffectRef* GrConfigConversionEffect::Create(GrTexture* texture,
-                                                    bool swapRedAndBlue,
-                                                    PMConversion pmConversion,
-                                                    const SkMatrix& matrix) {
+const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture,
+                                                 bool swapRedAndBlue,
+                                                 PMConversion pmConversion,
+                                                 const SkMatrix& matrix) {
     if (!swapRedAndBlue && kNone_PMConversion == pmConversion) {
         // If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect
         // then we may pollute our texture cache with redundant shaders. So in the case that no
@@ -268,10 +277,9 @@
             // The PM conversions assume colors are 0..255
             return NULL;
         }
-        AutoEffectUnref effect(SkNEW_ARGS(GrConfigConversionEffect, (texture,
-                                                                     swapRedAndBlue,
-                                                                     pmConversion,
-                                                                     matrix)));
-        return CreateEffectRef(effect);
+        return SkNEW_ARGS(GrConfigConversionEffect, (texture,
+                                                     swapRedAndBlue,
+                                                     pmConversion,
+                                                     matrix));
     }
 }
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index 169c3d7..765e49b 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -10,7 +10,7 @@
 
 #include "GrSingleTextureEffect.h"
 
-class GrEffectStage;
+class GrProcessorStage;
 class GrGLConfigConversionEffect;
 
 /**
@@ -34,16 +34,14 @@
         kPMConversionCnt
     };
 
-    // Installs an effect in the GrEffectStage to perform a config conversion.
-    static const GrEffectRef* Create(GrTexture*,
-                                     bool swapRedAndBlue,
-                                     PMConversion pmConversion,
-                                     const SkMatrix& matrix);
+    // Installs an effect in the GrProcessorStage to perform a config conversion.
+    static const GrFragmentProcessor* Create(GrTexture*, bool swapRedAndBlue, PMConversion,
+                                             const SkMatrix&);
 
     static const char* Name() { return "Config Conversion"; }
-    typedef GrGLConfigConversionEffect GLEffect;
+    typedef GrGLConfigConversionEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
@@ -65,12 +63,12 @@
                             PMConversion pmConversion,
                             const SkMatrix& matrix);
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     bool            fSwapRedAndBlue;
     PMConversion    fPMConversion;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     typedef GrSingleTextureEffect INHERITED;
 };
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index d24b45e..4857a9e 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -5,27 +5,28 @@
  * found in the LICENSE file.
  */
 
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "GrConvexPolyEffect.h"
 
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 
 #include "SkPath.h"
 
 //////////////////////////////////////////////////////////////////////////////
 class GLAARectEffect;
 
-class AARectEffect : public GrEffect {
+class AARectEffect : public GrFragmentProcessor {
 public:
-    typedef GLAARectEffect GLEffect;
+    typedef GLAARectEffect GLProcessor;
 
     const SkRect& getRect() const { return fRect; }
 
     static const char* Name() { return "AARect"; }
 
-    static GrEffectRef* Create(GrEffectEdgeType edgeType, const SkRect& rect) {
-        return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(AARectEffect, (edgeType, rect))));
+    static GrFragmentProcessor* Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) {
+        return SkNEW_ARGS(AARectEffect, (edgeType, rect));
     }
 
     virtual void getConstantColorComponents(GrColor* color,
@@ -39,231 +40,237 @@
         }
     }
 
-    GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    AARectEffect(GrEffectEdgeType edgeType, const SkRect& rect) : fRect(rect), fEdgeType(edgeType) {
+    AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect) : fRect(rect), fEdgeType(edgeType) {
         this->setWillReadFragmentPosition();
     }
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
-        const AARectEffect& aare = CastEffect<AARectEffect>(other);
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE {
+        const AARectEffect& aare = other.cast<AARectEffect>();
         return fRect == aare.fRect;
     }
 
-    SkRect fRect;
-    GrEffectEdgeType fEdgeType;
+    SkRect              fRect;
+    GrPrimitiveEdgeType fEdgeType;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
 };
 
-GR_DEFINE_EFFECT_TEST(AARectEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(AARectEffect);
 
-GrEffectRef* AARectEffect::TestCreate(SkRandom* random,
-                                      GrContext*,
-                                      const GrDrawTargetCaps& caps,
-                                      GrTexture*[]) {
+GrFragmentProcessor* AARectEffect::TestCreate(SkRandom* random,
+                                              GrContext*,
+                                              const GrDrawTargetCaps& caps,
+                                              GrTexture*[]) {
     SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(),
                                    random->nextSScalar1(),
                                    random->nextSScalar1(),
                                    random->nextSScalar1());
-    GrEffectRef* effect;
+    GrFragmentProcessor* fp;
     do {
-        GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(random->nextULessThan(
-                                                                    kGrEffectEdgeTypeCnt));
+        GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->nextULessThan(
+                                                                    kGrProcessorEdgeTypeCnt));
 
-        effect = AARectEffect::Create(edgeType, rect);
-    } while (NULL == effect);
-    return effect;
+        fp = AARectEffect::Create(edgeType, rect);
+    } while (NULL == fp);
+    return fp;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GLAARectEffect : public GrGLEffect {
+class GLAARectEffect : public GrGLFragmentProcessor {
 public:
-    GLAARectEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GLAARectEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor& fp,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
-    GrGLUniformManager::UniformHandle   fRectUniform;
-    SkRect                              fPrevRect;
-    typedef GrGLEffect INHERITED;
+    GrGLProgramDataManager::UniformHandle fRectUniform;
+    SkRect                                fPrevRect;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GLAARectEffect::GLAARectEffect(const GrBackendEffectFactory& factory,
-                               const GrDrawEffect& drawEffect)
+GLAARectEffect::GLAARectEffect(const GrBackendProcessorFactory& factory,
+                               const GrProcessor& effect)
     : INHERITED (factory) {
     fPrevRect.fLeft = SK_ScalarNaN;
 }
 
-void GLAARectEffect::emitCode(GrGLShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+void GLAARectEffect::emitCode(GrGLProgramBuilder* builder,
+                              const GrFragmentProcessor& fp,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
                               const TextureSamplerArray& samplers) {
-    const AARectEffect& aare = drawEffect.castEffect<AARectEffect>();
+    const AARectEffect& aare = fp.cast<AARectEffect>();
     const char *rectName;
     // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5),
     // respectively.
-    fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                        kVec4f_GrSLType,
                                        "rect",
                                        &rectName);
-    const char* fragmentPos = builder->fragmentPosition();
-    if (GrEffectEdgeTypeIsAA(aare.getEdgeType())) {
+
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    const char* fragmentPos = fsBuilder->fragmentPosition();
+    if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) {
         // The amount of coverage removed in x and y by the edges is computed as a pair of negative
         // numbers, xSub and ySub.
-        builder->fsCodeAppend("\t\tfloat xSub, ySub;\n");
-        builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
-        builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
-        builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
-        builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
+        fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
+        fsBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
+        fsBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
+        fsBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
+        fsBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
         // Now compute coverage in x and y and multiply them to get the fraction of the pixel
         // covered.
-        builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
+        fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
     } else {
-        builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n");
-        builder->fsCodeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
-        builder->fsCodeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
-        builder->fsCodeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
-        builder->fsCodeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
+        fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
+        fsBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
+        fsBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
+        fsBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
+        fsBuilder->codeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
     }
 
-    if (GrEffectEdgeTypeIsInverseFill(aare.getEdgeType())) {
-        builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n");
+    if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) {
+        fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
     }
-    builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-void GLAARectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
-    const AARectEffect& aare = drawEffect.castEffect<AARectEffect>();
+void GLAARectEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
+    const AARectEffect& aare = processor.cast<AARectEffect>();
     const SkRect& rect = aare.getRect();
     if (rect != fPrevRect) {
-        uman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
+        pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
                    rect.fRight - 0.5f, rect.fBottom - 0.5f);
         fPrevRect = rect;
     }
 }
 
-GrGLEffect::EffectKey GLAARectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-    const AARectEffect& aare = drawEffect.castEffect<AARectEffect>();
-    return aare.getEdgeType();
+void GLAARectEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                            GrProcessorKeyBuilder* b) {
+    const AARectEffect& aare = processor.cast<AARectEffect>();
+    b->add32(aare.getEdgeType());
 }
 
-const GrBackendEffectFactory& AARectEffect::getFactory() const {
-    return GrTBackendEffectFactory<AARectEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& AARectEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<AARectEffect>::getInstance();
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GrGLConvexPolyEffect : public GrGLEffect {
+class GrGLConvexPolyEffect : public GrGLFragmentProcessor {
 public:
-    GrGLConvexPolyEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLConvexPolyEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor& fp,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
-    GrGLUniformManager::UniformHandle   fEdgeUniform;
-    SkScalar                            fPrevEdges[3 * GrConvexPolyEffect::kMaxEdges];
-    typedef GrGLEffect INHERITED;
+    GrGLProgramDataManager::UniformHandle fEdgeUniform;
+    SkScalar                              fPrevEdges[3 * GrConvexPolyEffect::kMaxEdges];
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GrGLConvexPolyEffect::GrGLConvexPolyEffect(const GrBackendEffectFactory& factory,
-                                           const GrDrawEffect& drawEffect)
+GrGLConvexPolyEffect::GrGLConvexPolyEffect(const GrBackendProcessorFactory& factory,
+                                           const GrProcessor&)
     : INHERITED (factory) {
     fPrevEdges[0] = SK_ScalarNaN;
 }
 
-void GrGLConvexPolyEffect::emitCode(GrGLShaderBuilder* builder,
-                                    const GrDrawEffect& drawEffect,
-                                    EffectKey key,
+void GrGLConvexPolyEffect::emitCode(GrGLProgramBuilder* builder,
+                                    const GrFragmentProcessor& fp,
+                                    const GrProcessorKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray&,
                                     const TextureSamplerArray& samplers) {
-    const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>();
+    const GrConvexPolyEffect& cpe = fp.cast<GrConvexPolyEffect>();
 
     const char *edgeArrayName;
-    fEdgeUniform = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+    fEdgeUniform = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
                                             kVec3f_GrSLType,
                                             "edges",
                                             cpe.getEdgeCount(),
                                             &edgeArrayName);
-    builder->fsCodeAppend("\t\tfloat alpha = 1.0;\n");
-    builder->fsCodeAppend("\t\tfloat edge;\n");
-    const char* fragmentPos = builder->fragmentPosition();
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    fsBuilder->codeAppend("\t\tfloat alpha = 1.0;\n");
+    fsBuilder->codeAppend("\t\tfloat edge;\n");
+    const char* fragmentPos = fsBuilder->fragmentPosition();
     for (int i = 0; i < cpe.getEdgeCount(); ++i) {
-        builder->fsCodeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
+        fsBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
                                edgeArrayName, i, fragmentPos, fragmentPos);
-        if (GrEffectEdgeTypeIsAA(cpe.getEdgeType())) {
-            builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
+        if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) {
+            fsBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
         } else {
-            builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
+            fsBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
         }
-        builder->fsCodeAppend("\t\talpha *= edge;\n");
+        fsBuilder->codeAppend("\t\talpha *= edge;\n");
     }
 
     // Woe is me. See skbug.com/2149.
     if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) {
-        builder->fsCodeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n");
+        fsBuilder->codeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n");
     }
 
-    if (GrEffectEdgeTypeIsInverseFill(cpe.getEdgeType())) {
-        builder->fsCodeAppend("\talpha = 1.0 - alpha;\n");
+    if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) {
+        fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n");
     }
-    builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-void GrGLConvexPolyEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
-    const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>();
+void GrGLConvexPolyEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
+    const GrConvexPolyEffect& cpe = effect.cast<GrConvexPolyEffect>();
     size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar);
     if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) {
-        uman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges());
+        pdman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges());
         memcpy(fPrevEdges, cpe.getEdges(), byteSize);
     }
 }
 
-GrGLEffect::EffectKey GrGLConvexPolyEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                   const GrGLCaps&) {
-    const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>();
-    GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8);
-    return (cpe.getEdgeCount() << 3) | cpe.getEdgeType();
+void GrGLConvexPolyEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                                  GrProcessorKeyBuilder* b) {
+    const GrConvexPolyEffect& cpe = processor.cast<GrConvexPolyEffect>();
+    GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8);
+    uint32_t key = (cpe.getEdgeCount() << 3) | cpe.getEdgeType();
+    b->add32(key);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GrEffectRef* GrConvexPolyEffect::Create(GrEffectEdgeType type, const SkPath& path, const SkVector* offset) {
-    if (kHairlineAA_GrEffectEdgeType == type) {
+GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType type, const SkPath& path,
+                                                const SkVector* offset) {
+    if (kHairlineAA_GrProcessorEdgeType == type) {
         return NULL;
     }
     if (path.getSegmentMasks() != SkPath::kLine_SegmentMask ||
@@ -307,13 +314,13 @@
         }
     }
     if (path.isInverseFillType()) {
-        type = GrInvertEffectEdgeType(type);
+        type = GrInvertProcessorEdgeType(type);
     }
     return Create(type, n, edges);
 }
 
-GrEffectRef* GrConvexPolyEffect::Create(GrEffectEdgeType edgeType, const SkRect& rect) {
-    if (kHairlineAA_GrEffectEdgeType == edgeType){
+GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) {
+    if (kHairlineAA_GrProcessorEdgeType == edgeType){
         return NULL;
     }
     return AARectEffect::Create(edgeType, rect);
@@ -325,11 +332,11 @@
     *validFlags = 0;
 }
 
-const GrBackendEffectFactory& GrConvexPolyEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrConvexPolyEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrConvexPolyEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrConvexPolyEffect>::getInstance();
 }
 
-GrConvexPolyEffect::GrConvexPolyEffect(GrEffectEdgeType edgeType, int n, const SkScalar edges[])
+GrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[])
     : fEdgeType(edgeType)
     , fEdgeCount(n) {
     // Factory function should have already ensured this.
@@ -343,8 +350,8 @@
     this->setWillReadFragmentPosition();
 }
 
-bool GrConvexPolyEffect::onIsEqual(const GrEffect& other) const {
-    const GrConvexPolyEffect& cpe = CastEffect<GrConvexPolyEffect>(other);
+bool GrConvexPolyEffect::onIsEqual(const GrProcessor& other) const {
+    const GrConvexPolyEffect& cpe = other.cast<GrConvexPolyEffect>();
     // ignore the fact that 0 == -0 and just use memcmp.
     return (cpe.fEdgeType == fEdgeType && cpe.fEdgeCount == fEdgeCount &&
             0 == memcmp(cpe.fEdges, fEdges, 3 * fEdgeCount * sizeof(SkScalar)));
@@ -352,23 +359,23 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrConvexPolyEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConvexPolyEffect);
 
-GrEffectRef* GrConvexPolyEffect::TestCreate(SkRandom* random,
-                                            GrContext*,
-                                            const GrDrawTargetCaps& caps,
-                                            GrTexture*[]) {
+GrFragmentProcessor* GrConvexPolyEffect::TestCreate(SkRandom* random,
+                                                    GrContext*,
+                                                    const GrDrawTargetCaps& caps,
+                                                    GrTexture*[]) {
     int count = random->nextULessThan(kMaxEdges) + 1;
     SkScalar edges[kMaxEdges * 3];
     for (int i = 0; i < 3 * count; ++i) {
         edges[i] = random->nextSScalar1();
     }
 
-    GrEffectRef* effect;
+    GrFragmentProcessor* fp;
     do {
-        GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
-                                        random->nextULessThan(kGrEffectEdgeTypeCnt));
-        effect = GrConvexPolyEffect::Create(edgeType, count, edges);
-    } while (NULL == effect);
-    return effect;
+        GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
+                                        random->nextULessThan(kGrProcessorEdgeTypeCnt));
+        fp = GrConvexPolyEffect::Create(edgeType, count, edges);
+    } while (NULL == fp);
+    return fp;
 }
diff --git a/src/gpu/effects/GrConvexPolyEffect.h b/src/gpu/effects/GrConvexPolyEffect.h
index 0e508c7..e474939 100644
--- a/src/gpu/effects/GrConvexPolyEffect.h
+++ b/src/gpu/effects/GrConvexPolyEffect.h
@@ -9,7 +9,7 @@
 #define GrConvexPolyEffect_DEFINED
 
 #include "GrDrawTargetCaps.h"
-#include "GrEffect.h"
+#include "GrProcessor.h"
 #include "GrTypesPriv.h"
 
 class GrGLConvexPolyEffect;
@@ -20,7 +20,7 @@
  * Bounding geometry is rendered and the effect computes coverage based on the fragment's
  * position relative to the polygon.
  */
-class GrConvexPolyEffect : public GrEffect {
+class GrConvexPolyEffect : public GrFragmentProcessor {
 public:
     enum {
         kMaxEdges = 8,
@@ -37,12 +37,12 @@
      * have to modify the effect/shaderbuilder interface to make it possible (e.g. give access
      * to the view matrix or untransformed positions in the fragment shader).
      */
-    static GrEffectRef* Create(GrEffectEdgeType edgeType, int n, const SkScalar edges[]) {
-        if (n <= 0 || n > kMaxEdges || kHairlineAA_GrEffectEdgeType == edgeType) {
+    static GrFragmentProcessor* Create(GrPrimitiveEdgeType edgeType, int n,
+                                       const SkScalar edges[]) {
+        if (n <= 0 || n > kMaxEdges || kHairlineAA_GrProcessorEdgeType == edgeType) {
             return NULL;
         }
-        return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrConvexPolyEffect,
-                                                          (edgeType, n, edges))));
+        return SkNEW_ARGS(GrConvexPolyEffect, (edgeType, n, edges));
     }
 
     /**
@@ -50,41 +50,42 @@
      * inverse filled, or has too many edges, this will return NULL. If offset is non-NULL, then
      * the path is translated by the vector.
      */
-    static GrEffectRef* Create(GrEffectEdgeType, const SkPath&, const SkVector* offset = NULL);
+    static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkPath&,
+                                       const SkVector* offset = NULL);
 
     /**
      * Creates an effect that fills inside the rect with AA edges..
      */
-    static GrEffectRef* Create(GrEffectEdgeType, const SkRect&);
+    static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkRect&);
 
     virtual ~GrConvexPolyEffect();
 
     static const char* Name() { return "ConvexPoly"; }
 
-    GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
 
     int getEdgeCount() const { return fEdgeCount; }
 
     const SkScalar* getEdges() const { return fEdges; }
 
-    typedef GrGLConvexPolyEffect GLEffect;
+    typedef GrGLConvexPolyEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    GrConvexPolyEffect(GrEffectEdgeType edgeType, int n, const SkScalar edges[]);
+    GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[]);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
-    GrEffectEdgeType    fEdgeType;
-    int                 fEdgeCount;
-    SkScalar            fEdges[3 * kMaxEdges];
+    GrPrimitiveEdgeType    fEdgeType;
+    int                    fEdgeCount;
+    SkScalar               fEdges[3 * kMaxEdges];
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index aad7c87..a836d43 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -5,30 +5,31 @@
  * found in the LICENSE file.
  */
 
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "GrConvolutionEffect.h"
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
 #include "gl/GrGLTexture.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 
 // For brevity
-typedef GrGLUniformManager::UniformHandle UniformHandle;
+typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 
-class GrGLConvolutionEffect : public GrGLEffect {
+class GrGLConvolutionEffect : public GrGLFragmentProcessor {
 public:
-    GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLConvolutionEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
 private:
     int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); }
@@ -42,42 +43,44 @@
     UniformHandle       fImageIncrementUni;
     UniformHandle       fBoundsUni;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& factory,
-                                             const GrDrawEffect& drawEffect)
+GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendProcessorFactory& factory,
+                                             const GrProcessor& processor)
     : INHERITED(factory) {
-    const GrConvolutionEffect& c = drawEffect.castEffect<GrConvolutionEffect>();
+    const GrConvolutionEffect& c = processor.cast<GrConvolutionEffect>();
     fRadius = c.radius();
     fUseBounds = c.useBounds();
     fDirection = c.direction();
 }
 
-void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
-                                     const GrDrawEffect&,
-                                     EffectKey key,
+void GrGLConvolutionEffect::emitCode(GrGLProgramBuilder* builder,
+                                     const GrFragmentProcessor&,
+                                     const GrProcessorKey& key,
                                      const char* outputColor,
                                      const char* inputColor,
                                      const TransformedCoordsArray& coords,
                                      const TextureSamplerArray& samplers) {
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
-    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                              kVec2f_GrSLType, "ImageIncrement");
     if (this->useBounds()) {
-        fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fBoundsUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                          kVec2f_GrSLType, "Bounds");
     }
-    fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+    fKernelUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
                                           kFloat_GrSLType, "Kernel", this->width());
 
-    builder->fsCodeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+
+    fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
 
     int width = this->width();
     const GrGLShaderVar& kernel = builder->getUniformVariable(fKernelUni);
     const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
 
-    builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
+    fsBuilder->codeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
 
     // Manually unroll loop because some drivers don't; yields 20-30% speedup.
     for (int i = 0; i < width; i++) {
@@ -85,26 +88,26 @@
         SkString kernelIndex;
         index.appendS32(i);
         kernel.appendArrayAccess(index.c_str(), &kernelIndex);
-        builder->fsCodeAppendf("\t\t%s += ", outputColor);
-        builder->fsAppendTextureLookup(samplers[0], "coord");
+        fsBuilder->codeAppendf("\t\t%s += ", outputColor);
+        fsBuilder->appendTextureLookup(samplers[0], "coord");
         if (this->useBounds()) {
             const char* bounds = builder->getUniformCStr(fBoundsUni);
             const char* component = this->direction() == Gr1DKernelEffect::kY_Direction ? "y" : "x";
-            builder->fsCodeAppendf(" * float(coord.%s >= %s.x && coord.%s <= %s.y)",
+            fsBuilder->codeAppendf(" * float(coord.%s >= %s.x && coord.%s <= %s.y)",
                 component, bounds, component, bounds);
         }
-        builder->fsCodeAppendf(" * %s;\n", kernelIndex.c_str());
-        builder->fsCodeAppendf("\t\tcoord += %s;\n", imgInc);
+        fsBuilder->codeAppendf(" * %s;\n", kernelIndex.c_str());
+        fsBuilder->codeAppendf("\t\tcoord += %s;\n", imgInc);
     }
 
     SkString modulate;
     GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
-    builder->fsCodeAppend(modulate.c_str());
+    fsBuilder->codeAppend(modulate.c_str());
 }
 
-void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman,
-                                    const GrDrawEffect& drawEffect) {
-    const GrConvolutionEffect& conv = drawEffect.castEffect<GrConvolutionEffect>();
+void GrGLConvolutionEffect::setData(const GrGLProgramDataManager& pdman,
+                                    const GrProcessor& processor) {
+    const GrConvolutionEffect& conv = processor.cast<GrConvolutionEffect>();
     GrTexture& texture = *conv.texture(0);
     // the code we generated was for a specific kernel radius
     SkASSERT(conv.radius() == fRadius);
@@ -120,29 +123,29 @@
         default:
             SkFAIL("Unknown filter direction.");
     }
-    uman.set2fv(fImageIncrementUni, 1, imageIncrement);
+    pdman.set2fv(fImageIncrementUni, 1, imageIncrement);
     if (conv.useBounds()) {
         const float* bounds = conv.bounds();
         if (Gr1DKernelEffect::kY_Direction == conv.direction() &&
             texture.origin() != kTopLeft_GrSurfaceOrigin) {
-            uman.set2f(fBoundsUni, 1.0f - bounds[1], 1.0f - bounds[0]);
+            pdman.set2f(fBoundsUni, 1.0f - bounds[1], 1.0f - bounds[0]);
         } else {
-            uman.set2f(fBoundsUni, bounds[0], bounds[1]);
+            pdman.set2f(fBoundsUni, bounds[0], bounds[1]);
         }
     }
-    uman.set1fv(fKernelUni, this->width(), conv.kernel());
+    pdman.set1fv(fKernelUni, this->width(), conv.kernel());
 }
 
-GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                    const GrGLCaps&) {
-    const GrConvolutionEffect& conv = drawEffect.castEffect<GrConvolutionEffect>();
-    EffectKey key = conv.radius();
+void GrGLConvolutionEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                                   GrProcessorKeyBuilder* b) {
+    const GrConvolutionEffect& conv = processor.cast<GrConvolutionEffect>();
+    uint32_t key = conv.radius();
     key <<= 2;
     if (conv.useBounds()) {
         key |= 0x2;
         key |= GrConvolutionEffect::kY_Direction == conv.direction() ? 0x1 : 0x0;
     }
-    return key;
+    b->add32(key);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -155,7 +158,7 @@
                                          float bounds[2])
     : Gr1DKernelEffect(texture, direction, radius), fUseBounds(useBounds) {
     SkASSERT(radius <= kMaxKernelRadius);
-    SkASSERT(NULL != kernel);
+    SkASSERT(kernel);
     int width = this->width();
     for (int i = 0; i < width; i++) {
         fKernel[i] = kernel[i];
@@ -193,12 +196,12 @@
 GrConvolutionEffect::~GrConvolutionEffect() {
 }
 
-const GrBackendEffectFactory& GrConvolutionEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrConvolutionEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrConvolutionEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrConvolutionEffect>::getInstance();
 }
 
-bool GrConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrConvolutionEffect& s = CastEffect<GrConvolutionEffect>(sBase);
+bool GrConvolutionEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrConvolutionEffect& s = sBase.cast<GrConvolutionEffect>();
     return (this->texture(0) == s.texture(0) &&
             this->radius() == s.radius() &&
             this->direction() == s.direction() &&
@@ -209,14 +212,14 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrConvolutionEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConvolutionEffect);
 
-GrEffectRef* GrConvolutionEffect::TestCreate(SkRandom* random,
-                                             GrContext*,
-                                             const GrDrawTargetCaps&,
-                                             GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
+GrFragmentProcessor* GrConvolutionEffect::TestCreate(SkRandom* random,
+                                                     GrContext*,
+                                                     const GrDrawTargetCaps&,
+                                                     GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                      GrProcessorUnitTest::kAlphaTextureIdx;
     Direction dir = random->nextBool() ? kX_Direction : kY_Direction;
     int radius = random->nextRangeU(1, kMaxKernelRadius);
     float kernel[kMaxKernelWidth];
diff --git a/src/gpu/effects/GrConvolutionEffect.h b/src/gpu/effects/GrConvolutionEffect.h
index 56a54b4..f2a2d5a 100644
--- a/src/gpu/effects/GrConvolutionEffect.h
+++ b/src/gpu/effects/GrConvolutionEffect.h
@@ -22,35 +22,33 @@
 public:
 
     /// Convolve with an arbitrary user-specified kernel
-    static GrEffectRef* Create(GrTexture* tex,
-                               Direction dir,
-                               int halfWidth,
-                               const float* kernel,
-                               bool useBounds,
-                               float bounds[2]) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrConvolutionEffect, (tex,
-                                                                dir,
-                                                                halfWidth,
-                                                                kernel,
-                                                                useBounds,
-                                                                bounds)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* tex,
+                                       Direction dir,
+                                       int halfWidth,
+                                       const float* kernel,
+                                       bool useBounds,
+                                       float bounds[2]) {
+        return SkNEW_ARGS(GrConvolutionEffect, (tex,
+                                                dir,
+                                                halfWidth,
+                                                kernel,
+                                                useBounds,
+                                                bounds));
     }
 
     /// Convolve with a Gaussian kernel
-    static GrEffectRef* CreateGaussian(GrTexture* tex,
-                                       Direction dir,
-                                       int halfWidth,
-                                       float gaussianSigma,
-                                       bool useBounds,
-                                       float bounds[2]) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrConvolutionEffect, (tex,
-                                                                dir,
-                                                                halfWidth,
-                                                                gaussianSigma,
-                                                                useBounds,
-                                                                bounds)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* CreateGaussian(GrTexture* tex,
+                                               Direction dir,
+                                               int halfWidth,
+                                               float gaussianSigma,
+                                               bool useBounds,
+                                               float bounds[2]) {
+        return SkNEW_ARGS(GrConvolutionEffect, (tex,
+                                                dir,
+                                                halfWidth,
+                                                gaussianSigma,
+                                                useBounds,
+                                                bounds));
     }
 
     virtual ~GrConvolutionEffect();
@@ -62,9 +60,9 @@
 
     static const char* Name() { return "Convolution"; }
 
-    typedef GrGLConvolutionEffect GLEffect;
+    typedef GrGLConvolutionEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
     virtual void getConstantColorComponents(GrColor*, uint32_t* validFlags) const {
         // If the texture was opaque we could know that the output color if we knew the sum of the
@@ -103,9 +101,9 @@
                         bool useBounds,
                         float bounds[2]);
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     typedef Gr1DKernelEffect INHERITED;
 };
diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
index f85a927..b9794c1 100644
--- a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
+++ b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
@@ -6,26 +6,29 @@
  */
 
 #include "GrCustomCoordsTextureEffect.h"
-#include "gl/GrGLEffect.h"
+#include "gl/builders/GrGLFullProgramBuilder.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
 #include "gl/GrGLTexture.h"
-#include "gl/GrGLVertexEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLGeometryProcessor.h"
+#include "GrTBackendProcessorFactory.h"
 #include "GrTexture.h"
 
-class GrGLCustomCoordsTextureEffect : public GrGLVertexEffect {
+class GrGLCustomCoordsTextureEffect : public GrGLGeometryProcessor {
 public:
-    GrGLCustomCoordsTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
+    GrGLCustomCoordsTextureEffect(const GrBackendProcessorFactory& factory, const GrProcessor&)
         : INHERITED (factory) {}
 
-    virtual void emitCode(GrGLFullShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLFullProgramBuilder* builder,
+                          const GrGeometryProcessor& geometryProcessor,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray& samplers) SK_OVERRIDE {
-        SkASSERT(1 == drawEffect.castEffect<GrCustomCoordsTextureEffect>().numVertexAttribs());
+        const GrCustomCoordsTextureEffect& customCoordsTextureEffect =
+                geometryProcessor.cast<GrCustomCoordsTextureEffect>();
+        SkASSERT(1 == customCoordsTextureEffect.getVertexAttribs().count());
 
         SkString fsCoordName;
         const char* vsVaryingName;
@@ -33,36 +36,39 @@
         builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsVaryingNamePtr);
         fsCoordName = fsVaryingNamePtr;
 
-        const char* attrName =
-            builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
-        builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, attrName);
+        GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+        const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
+        vsBuilder->codeAppendf("\t%s = %s;\n", vsVaryingName, inTextureCoords.c_str());
 
-        builder->fsCodeAppendf("\t%s = ", outputColor);
-        builder->fsAppendTextureLookupAndModulate(inputColor,
+        GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+        fsBuilder->codeAppendf("\t%s = ", outputColor);
+        fsBuilder->appendTextureLookupAndModulate(inputColor,
                                                   samplers[0],
                                                   fsCoordName.c_str(),
                                                   kVec2f_GrSLType);
-        builder->fsCodeAppend(";\n");
+        fsBuilder->codeAppend(";\n");
     }
 
-    virtual void setData(const GrGLUniformManager& uman,
-                         const GrDrawEffect& drawEffect) SK_OVERRIDE {}
+    virtual void setData(const GrGLProgramDataManager&,
+                         const GrProcessor&) SK_OVERRIDE {}
 
 private:
-    typedef GrGLVertexEffect INHERITED;
+    typedef GrGLGeometryProcessor INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
 GrCustomCoordsTextureEffect::GrCustomCoordsTextureEffect(GrTexture* texture,
                                                          const GrTextureParams& params)
-    : fTextureAccess(texture, params) {
+    : fTextureAccess(texture, params)
+    , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
+                                                         kVec2f_GrSLType,
+                                                         GrShaderVar::kAttribute_TypeModifier))) {
     this->addTextureAccess(&fTextureAccess);
-    this->addVertexAttrib(kVec2f_GrSLType);
 }
 
-bool GrCustomCoordsTextureEffect::onIsEqual(const GrEffect& other) const {
-    const GrCustomCoordsTextureEffect& cte = CastEffect<GrCustomCoordsTextureEffect>(other);
+bool GrCustomCoordsTextureEffect::onIsEqual(const GrProcessor& other) const {
+    const GrCustomCoordsTextureEffect& cte = other.cast<GrCustomCoordsTextureEffect>();
     return fTextureAccess == cte.fTextureAccess;
 }
 
@@ -76,20 +82,20 @@
     }
 }
 
-const GrBackendEffectFactory& GrCustomCoordsTextureEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrCustomCoordsTextureEffect>::getInstance();
+const GrBackendGeometryProcessorFactory& GrCustomCoordsTextureEffect::getFactory() const {
+    return GrTBackendGeometryProcessorFactory<GrCustomCoordsTextureEffect>::getInstance();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrCustomCoordsTextureEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCustomCoordsTextureEffect);
 
-GrEffectRef* GrCustomCoordsTextureEffect::TestCreate(SkRandom* random,
-                                                     GrContext*,
-                                                     const GrDrawTargetCaps&,
-                                                     GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
+GrGeometryProcessor* GrCustomCoordsTextureEffect::TestCreate(SkRandom* random,
+                                                             GrContext*,
+                                                             const GrDrawTargetCaps&,
+                                                             GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                      GrProcessorUnitTest::kAlphaTextureIdx;
     static const SkShader::TileMode kTileModes[] = {
         SkShader::kClamp_TileMode,
         SkShader::kRepeat_TileMode,
diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.h b/src/gpu/effects/GrCustomCoordsTextureEffect.h
index 1caecf2..f48a144 100644
--- a/src/gpu/effects/GrCustomCoordsTextureEffect.h
+++ b/src/gpu/effects/GrCustomCoordsTextureEffect.h
@@ -8,8 +8,8 @@
 #ifndef GrCustomCoordsTextureEffect_DEFINED
 #define GrCustomCoordsTextureEffect_DEFINED
 
-#include "GrEffect.h"
-#include "GrVertexEffect.h"
+#include "GrProcessor.h"
+#include "GrGeometryProcessor.h"
 
 class GrGLCustomCoordsTextureEffect;
 
@@ -18,11 +18,10 @@
  * It allows explicit specification of the filtering and wrap modes (GrTextureParams). The input
  * coords are a custom attribute.
  */
-class GrCustomCoordsTextureEffect : public GrVertexEffect {
+class GrCustomCoordsTextureEffect : public GrGeometryProcessor {
 public:
-    static GrEffectRef* Create(GrTexture* tex, const GrTextureParams& p) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrCustomCoordsTextureEffect, (tex, p)));
-        return CreateEffectRef(effect);
+    static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& p) {
+        return SkNEW_ARGS(GrCustomCoordsTextureEffect, (tex, p));
     }
 
     virtual ~GrCustomCoordsTextureEffect() {}
@@ -31,20 +30,23 @@
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    typedef GrGLCustomCoordsTextureEffect GLEffect;
+    const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    typedef GrGLCustomCoordsTextureEffect GLProcessor;
+
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
     GrCustomCoordsTextureEffect(GrTexture* texture, const GrTextureParams& params);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
-    GrTextureAccess fTextureAccess;
+    GrTextureAccess    fTextureAccess;
+    const GrShaderVar& fInTextureCoords;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrVertexEffect INHERITED;
+    typedef GrGeometryProcessor INHERITED;
 };
 
 #endif
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index 8d9c08f..704a6ac 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -9,18 +9,19 @@
 
 #include "../GrAARectRenderer.h"
 
-#include "effects/GrVertexEffect.h"
-#include "gl/GrGLEffect.h"
-#include "gl/GrGLVertexEffect.h"
+#include "GrGeometryProcessor.h"
+#include "gl/builders/GrGLFullProgramBuilder.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/GrGLGeometryProcessor.h"
 #include "gl/GrGLSL.h"
 #include "GrContext.h"
 #include "GrCoordTransform.h"
 #include "GrDrawTarget.h"
 #include "GrDrawTargetCaps.h"
-#include "GrEffect.h"
+#include "GrProcessor.h"
 #include "GrGpu.h"
 #include "GrStrokeInfo.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 #include "SkGr.h"
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -54,7 +55,7 @@
 
     SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap();
     // Current we do don't handle Round or Square cap dashes
-    if (SkPaint::kRound_Cap == cap) {
+    if (SkPaint::kRound_Cap == cap && info.fIntervals[0] != 0.f) {
         return false;
     }
 
@@ -68,9 +69,13 @@
     SkPoint fDashPos;
 };
 
+extern const GrVertexAttrib gDashLineNoAAVertexAttribs[] = {
+    { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding }
+};
+
 extern const GrVertexAttrib gDashLineVertexAttribs[] = {
     { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding },
-    { kVec2f_GrVertexAttribType, sizeof(SkPoint),   kEffect_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding },
 };
 
 };
@@ -204,7 +209,7 @@
     SkScalar perpScale;
     calc_dash_scaling(&parallelScale, &perpScale, vm, ptsRot);
 
-    bool hasCap = SkPaint::kSquare_Cap == cap && 0 != srcStrokeWidth;
+    bool hasCap = SkPaint::kButt_Cap != cap && 0 != srcStrokeWidth;
 
     // We always want to at least stroke out half a pixel on each side in device space
     // so 0.5f / perpScale gives us this min in src space
@@ -339,14 +344,22 @@
         devInfo.fPhase = devPhase;
         devInfo.fCount = 2;
         devInfo.fIntervals = devIntervals;
-        GrEffectEdgeType edgeType= useAA ? kFillAA_GrEffectEdgeType :
-            kFillBW_GrEffectEdgeType;
-        drawState->addCoverageEffect(
-            GrDashingEffect::Create(edgeType, devInfo, strokeWidth), 1)->unref();
-    }
+        GrPrimitiveEdgeType edgeType= useAA ? kFillAA_GrProcessorEdgeType :
+            kFillBW_GrProcessorEdgeType;
+        bool isRoundCap = SkPaint::kRound_Cap == cap;
+        GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_DashCap :
+                                                        GrDashingEffect::kNonRound_DashCap;
+        drawState->setGeometryProcessor(
+                GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType))->unref();
 
-    // Set up the vertex data for the line and start/end dashes
-    drawState->setVertexAttribs<gDashLineVertexAttribs>(SK_ARRAY_COUNT(gDashLineVertexAttribs));
+        // Set up the vertex data for the line and start/end dashes
+        drawState->setVertexAttribs<gDashLineVertexAttribs>(SK_ARRAY_COUNT(gDashLineVertexAttribs),
+                                                            sizeof(DashLineVertex));
+    } else {
+        // Set up the vertex data for the line and start/end dashes
+        drawState->setVertexAttribs<gDashLineNoAAVertexAttribs>(
+                SK_ARRAY_COUNT(gDashLineNoAAVertexAttribs), sizeof(DashLineVertex));
+    }
 
     int totalRectCnt = 0;
 
@@ -364,6 +377,11 @@
 
     int curVIdx = 0;
 
+    if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) {
+        // need to adjust this for round caps to correctly set the dashPos attrib on vertices
+        startOffset -= halfDevStroke;
+    }
+
     // Draw interior part of dashed line
     if (!lineDone) {
         SkPoint devicePts[2];
@@ -404,168 +422,387 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GLDashingLineEffect;
-
-class DashingLineEffect : public GrVertexEffect {
+class GLDashingCircleEffect;
+/*
+ * This effect will draw a dotted line (defined as a dashed lined with round caps and no on
+ * interval). The radius of the dots is given by the strokeWidth and the spacing by the DashInfo.
+ * Both of the previous two parameters are in device space. This effect also requires the setting of
+ * a vec2 vertex attribute for the the four corners of the bounding rect. This attribute is the
+ * "dash position" of each vertex. In other words it is the vertex coords (in device space) if we
+ * transform the line to be horizontal, with the start of line at the origin then shifted to the
+ * right by half the off interval. The line then goes in the positive x direction.
+ */
+class DashingCircleEffect : public GrGeometryProcessor {
 public:
     typedef SkPathEffect::DashInfo DashInfo;
 
-    /**
-     * The effect calculates the coverage for the case of a horizontal line in device space.
-     * The matrix that is passed in should be able to convert a line in source space to a
-     * horizontal line in device space. Additionally, the coord transform matrix should translate
-     * the the start of line to origin, and the shift it along the positive x-axis by the phase
-     * and half the off interval.
-     */
-    static GrEffectRef* Create(GrEffectEdgeType edgeType, const DashInfo& info,
-                               SkScalar strokeWidth);
+    static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType,
+                                       const DashInfo& info,
+                                       SkScalar radius);
 
-    virtual ~DashingLineEffect();
+    virtual ~DashingCircleEffect();
 
-    static const char* Name() { return "DashingEffect"; }
+    static const char* Name() { return "DashingCircleEffect"; }
 
-    GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    const GrShaderVar& inCoord() const { return fInCoord; }
 
-    const SkRect& getRect() const { return fRect; }
+    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
+
+    SkScalar getRadius() const { return fRadius; }
+
+    SkScalar getCenterX() const { return fCenterX; }
 
     SkScalar getIntervalLength() const { return fIntervalLength; }
 
-    typedef GLDashingLineEffect GLEffect;
+    typedef GLDashingCircleEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    DashingLineEffect(GrEffectEdgeType edgeType, const DashInfo& info, SkScalar strokeWidth);
+    DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar radius);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
-    GrEffectEdgeType    fEdgeType;
-    SkRect              fRect;
+    GrPrimitiveEdgeType    fEdgeType;
+    const GrShaderVar&  fInCoord;
     SkScalar            fIntervalLength;
+    SkScalar            fRadius;
+    SkScalar            fCenterX;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrEffect INHERITED;
+    typedef GrGeometryProcessor INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GLDashingLineEffect : public GrGLVertexEffect {
+class GLDashingCircleEffect : public GrGLGeometryProcessor {
 public:
-    GLDashingLineEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GLDashingCircleEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLFullShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLFullProgramBuilder* builder,
+                          const GrGeometryProcessor& geometryProcessor,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
-    GrGLUniformManager::UniformHandle   fRectUniform;
-    GrGLUniformManager::UniformHandle   fIntervalUniform;
-    SkRect                              fPrevRect;
-    SkScalar                            fPrevIntervalLength;
-    typedef GrGLVertexEffect INHERITED;
+    GrGLProgramDataManager::UniformHandle fParamUniform;
+    SkScalar                              fPrevRadius;
+    SkScalar                              fPrevCenterX;
+    SkScalar                              fPrevIntervalLength;
+    typedef GrGLGeometryProcessor INHERITED;
 };
 
-GLDashingLineEffect::GLDashingLineEffect(const GrBackendEffectFactory& factory,
-                                     const GrDrawEffect& drawEffect)
+GLDashingCircleEffect::GLDashingCircleEffect(const GrBackendProcessorFactory& factory,
+                                             const GrProcessor&)
     : INHERITED (factory) {
-    fPrevRect.fLeft = SK_ScalarNaN;
+    fPrevRadius = SK_ScalarMin;
+    fPrevCenterX = SK_ScalarMin;
     fPrevIntervalLength = SK_ScalarMax;
-
 }
 
-void GLDashingLineEffect::emitCode(GrGLFullShaderBuilder* builder,
-                                    const GrDrawEffect& drawEffect,
-                                    EffectKey key,
+void GLDashingCircleEffect::emitCode(GrGLFullProgramBuilder* builder,
+                                    const GrGeometryProcessor& geometryProcessor,
+                                    const GrProcessorKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray&,
                                     const TextureSamplerArray& samplers) {
-    const DashingLineEffect& de = drawEffect.castEffect<DashingLineEffect>();
+    const DashingCircleEffect& dce = geometryProcessor.cast<DashingCircleEffect>();
+    const char *paramName;
+    // The param uniforms, xyz, refer to circle radius - 0.5, cicles center x coord, and
+    // the total interval length of the dash.
+    fParamUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                       kVec3f_GrSLType,
+                                       "params",
+                                       &paramName);
+
+    const char *vsCoordName, *fsCoordName;
+    builder->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName);
+
+    GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+    vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dce.inCoord().c_str());
+
+    // transforms all points so that we can compare them to our test circle
+    GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n",
+                           fsCoordName, fsCoordName, paramName, paramName);
+    fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
+    fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName);
+    fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n");
+    if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) {
+        fsBuilder->codeAppendf("\t\tfloat diff = dist - %s.x;\n", paramName);
+        fsBuilder->codeAppend("\t\tdiff = 1.0 - diff;\n");
+        fsBuilder->codeAppend("\t\tfloat alpha = clamp(diff, 0.0, 1.0);\n");
+    } else {
+        fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
+        fsBuilder->codeAppendf("\t\talpha *=  dist < %s.x + 0.5 ? 1.0 : 0.0;\n", paramName);
+    }
+    fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
+                           (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
+}
+
+void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman
+                                    , const GrProcessor& processor) {
+    const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>();
+    SkScalar radius = dce.getRadius();
+    SkScalar centerX = dce.getCenterX();
+    SkScalar intervalLength = dce.getIntervalLength();
+    if (radius != fPrevRadius || centerX != fPrevCenterX || intervalLength != fPrevIntervalLength) {
+        pdman.set3f(fParamUniform, radius - 0.5f, centerX, intervalLength);
+        fPrevRadius = radius;
+        fPrevCenterX = centerX;
+        fPrevIntervalLength = intervalLength;
+    }
+}
+
+void GLDashingCircleEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                                   GrProcessorKeyBuilder* b) {
+    const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>();
+    b->add32(dce.getEdgeType());
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+GrGeometryProcessor* DashingCircleEffect::Create(GrPrimitiveEdgeType edgeType, const DashInfo& info,
+                                                 SkScalar radius) {
+    if (info.fCount != 2 || info.fIntervals[0] != 0) {
+        return NULL;
+    }
+
+    return SkNEW_ARGS(DashingCircleEffect, (edgeType, info, radius));
+}
+
+DashingCircleEffect::~DashingCircleEffect() {}
+
+void DashingCircleEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
+    *validFlags = 0;
+}
+
+const GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const {
+    return GrTBackendGeometryProcessorFactory<DashingCircleEffect>::getInstance();
+}
+
+DashingCircleEffect::DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info,
+                                         SkScalar radius)
+    : fEdgeType(edgeType)
+    , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord",
+                                                 kVec2f_GrSLType,
+                                                 GrShaderVar::kAttribute_TypeModifier))) {
+    SkScalar onLen = info.fIntervals[0];
+    SkScalar offLen = info.fIntervals[1];
+    fIntervalLength = onLen + offLen;
+    fRadius = radius;
+    fCenterX = SkScalarHalf(offLen);
+}
+
+bool DashingCircleEffect::onIsEqual(const GrProcessor& other) const {
+    const DashingCircleEffect& dce = other.cast<DashingCircleEffect>();
+    return (fEdgeType == dce.fEdgeType &&
+            fIntervalLength == dce.fIntervalLength &&
+            fRadius == dce.fRadius &&
+            fCenterX == dce.fCenterX);
+}
+
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect);
+
+GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random,
+                                                     GrContext*,
+                                                     const GrDrawTargetCaps& caps,
+                                                     GrTexture*[]) {
+    GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->nextULessThan(
+            kGrProcessorEdgeTypeCnt));
+    SkScalar strokeWidth = random->nextRangeScalar(0, 100.f);
+    DashInfo info;
+    info.fCount = 2;
+    SkAutoTArray<SkScalar> intervals(info.fCount);
+    info.fIntervals = intervals.get();
+    info.fIntervals[0] = 0; 
+    info.fIntervals[1] = random->nextRangeScalar(0, 10.f);
+    info.fPhase = random->nextRangeScalar(0, info.fIntervals[1]);
+
+    return DashingCircleEffect::Create(edgeType, info, strokeWidth);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+class GLDashingLineEffect;
+
+/*
+ * This effect will draw a dashed line. The width of the dash is given by the strokeWidth and the
+ * length and spacing by the DashInfo. Both of the previous two parameters are in device space.
+ * This effect also requires the setting of a vec2 vertex attribute for the the four corners of the
+ * bounding rect. This attribute is the "dash position" of each vertex. In other words it is the
+ * vertex coords (in device space) if we transform the line to be horizontal, with the start of
+ * line at the origin then shifted to the right by half the off interval. The line then goes in the
+ * positive x direction.
+ */
+class DashingLineEffect : public GrGeometryProcessor {
+public:
+    typedef SkPathEffect::DashInfo DashInfo;
+
+    static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType,
+                                       const DashInfo& info,
+                                       SkScalar strokeWidth);
+
+    virtual ~DashingLineEffect();
+
+    static const char* Name() { return "DashingEffect"; }
+
+    const GrShaderVar& inCoord() const { return fInCoord; }
+
+    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
+
+    const SkRect& getRect() const { return fRect; }
+
+    SkScalar getIntervalLength() const { return fIntervalLength; }
+
+    typedef GLDashingLineEffect GLProcessor;
+
+    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
+
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
+
+private:
+    DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar strokeWidth);
+
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
+
+    GrPrimitiveEdgeType    fEdgeType;
+    const GrShaderVar&  fInCoord;
+    SkRect              fRect;
+    SkScalar            fIntervalLength;
+
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
+
+    typedef GrGeometryProcessor INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+class GLDashingLineEffect : public GrGLGeometryProcessor {
+public:
+    GLDashingLineEffect(const GrBackendProcessorFactory&, const GrProcessor&);
+
+    virtual void emitCode(GrGLFullProgramBuilder* builder,
+                          const GrGeometryProcessor& geometryProcessor,
+                          const GrProcessorKey& key,
+                          const char* outputColor,
+                          const char* inputColor,
+                          const TransformedCoordsArray&,
+                          const TextureSamplerArray&) SK_OVERRIDE;
+
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
+
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
+
+private:
+    GrGLProgramDataManager::UniformHandle fRectUniform;
+    GrGLProgramDataManager::UniformHandle fIntervalUniform;
+    SkRect                                fPrevRect;
+    SkScalar                              fPrevIntervalLength;
+    typedef GrGLGeometryProcessor INHERITED;
+};
+
+GLDashingLineEffect::GLDashingLineEffect(const GrBackendProcessorFactory& factory,
+                                         const GrProcessor&)
+    : INHERITED (factory) {
+    fPrevRect.fLeft = SK_ScalarNaN;
+    fPrevIntervalLength = SK_ScalarMax;
+}
+
+void GLDashingLineEffect::emitCode(GrGLFullProgramBuilder* builder,
+                                   const GrGeometryProcessor& geometryProcessor,
+                                   const GrProcessorKey& key,
+                                   const char* outputColor,
+                                   const char* inputColor,
+                                   const TransformedCoordsArray&,
+                                   const TextureSamplerArray& samplers) {
+    const DashingLineEffect& de = geometryProcessor.cast<DashingLineEffect>();
     const char *rectName;
     // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5),
     // respectively.
-    fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                        kVec4f_GrSLType,
                                        "rect",
                                        &rectName);
     const char *intervalName;
     // The interval uniform's refers to the total length of the interval (on + off)
-    fIntervalUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fIntervalUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                        kFloat_GrSLType,
                                        "interval",
                                        &intervalName);
 
     const char *vsCoordName, *fsCoordName;
     builder->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName);
-    const SkString* attr0Name =
-        builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
-    builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str());
+    GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+    vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, de.inCoord().c_str());
 
     // transforms all points so that we can compare them to our test rect
-    builder->fsCodeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
+    GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
                            fsCoordName, fsCoordName, intervalName, intervalName);
-    builder->fsCodeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
-    if (GrEffectEdgeTypeIsAA(de.getEdgeType())) {
+    fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
+    if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) {
         // The amount of coverage removed in x and y by the edges is computed as a pair of negative
         // numbers, xSub and ySub.
-        builder->fsCodeAppend("\t\tfloat xSub, ySub;\n");
-        builder->fsCodeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n", rectName);
-        builder->fsCodeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n", rectName);
-        builder->fsCodeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n", rectName);
-        builder->fsCodeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n", rectName);
+        fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
+        fsBuilder->codeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n", rectName);
+        fsBuilder->codeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n", rectName);
+        fsBuilder->codeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n", rectName);
+        fsBuilder->codeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n", rectName);
         // Now compute coverage in x and y and multiply them to get the fraction of the pixel
         // covered.
-        builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
+        fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
     } else {
         // Assuming the bounding geometry is tight so no need to check y values
-        builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n");
-        builder->fsCodeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName);
-        builder->fsCodeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;\n", rectName);
+        fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
+        fsBuilder->codeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName);
+        fsBuilder->codeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;\n", rectName);
     }
-    builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-void GLDashingLineEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
-    const DashingLineEffect& de = drawEffect.castEffect<DashingLineEffect>();
+void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman,
+                                  const GrProcessor& processor) {
+    const DashingLineEffect& de = processor.cast<DashingLineEffect>();
     const SkRect& rect = de.getRect();
     SkScalar intervalLength = de.getIntervalLength();
     if (rect != fPrevRect || intervalLength != fPrevIntervalLength) {
-        uman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
-                   rect.fRight - 0.5f, rect.fBottom - 0.5f);
-        uman.set1f(fIntervalUniform, intervalLength);
+        pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
+                    rect.fRight - 0.5f, rect.fBottom - 0.5f);
+        pdman.set1f(fIntervalUniform, intervalLength);
         fPrevRect = rect;
         fPrevIntervalLength = intervalLength;
     }
 }
 
-GrGLEffect::EffectKey GLDashingLineEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                const GrGLCaps&) {
-    const DashingLineEffect& de = drawEffect.castEffect<DashingLineEffect>();
-    return de.getEdgeType();
+void GLDashingLineEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                                 GrProcessorKeyBuilder* b) {
+    const DashingLineEffect& de = processor.cast<DashingLineEffect>();
+    b->add32(de.getEdgeType());
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GrEffectRef* DashingLineEffect::Create(GrEffectEdgeType edgeType, const DashInfo& info,
-                                       SkScalar strokeWidth) {
+GrGeometryProcessor* DashingLineEffect::Create(GrPrimitiveEdgeType edgeType,
+                                               const DashInfo& info,
+                                               SkScalar strokeWidth) {
     if (info.fCount != 2) {
         return NULL;
     }
 
-    return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(DashingLineEffect,
-                                                      (edgeType, info, strokeWidth))));
+    return SkNEW_ARGS(DashingLineEffect, (edgeType, info, strokeWidth));
 }
 
 DashingLineEffect::~DashingLineEffect() {}
@@ -574,39 +811,39 @@
     *validFlags = 0;
 }
 
-const GrBackendEffectFactory& DashingLineEffect::getFactory() const {
-    return GrTBackendEffectFactory<DashingLineEffect>::getInstance();
+const GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const {
+    return GrTBackendGeometryProcessorFactory<DashingLineEffect>::getInstance();
 }
 
-DashingLineEffect::DashingLineEffect(GrEffectEdgeType edgeType, const DashInfo& info,
+DashingLineEffect::DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info,
                                      SkScalar strokeWidth)
-    : fEdgeType(edgeType) {
+    : fEdgeType(edgeType)
+    , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord",
+                                                 kVec2f_GrSLType,
+                                                 GrShaderVar::kAttribute_TypeModifier))) {
     SkScalar onLen = info.fIntervals[0];
     SkScalar offLen = info.fIntervals[1];
     SkScalar halfOffLen = SkScalarHalf(offLen);
     SkScalar halfStroke = SkScalarHalf(strokeWidth);
     fIntervalLength = onLen + offLen;
     fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke);
-
-    this->addVertexAttrib(kVec2f_GrSLType);
 }
 
-bool DashingLineEffect::onIsEqual(const GrEffect& other) const {
-    const DashingLineEffect& de = CastEffect<DashingLineEffect>(other);
+bool DashingLineEffect::onIsEqual(const GrProcessor& other) const {
+    const DashingLineEffect& de = other.cast<DashingLineEffect>();
     return (fEdgeType == de.fEdgeType &&
             fRect == de.fRect &&
             fIntervalLength == de.fIntervalLength);
 }
 
-GR_DEFINE_EFFECT_TEST(DashingLineEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect);
 
-GrEffectRef* DashingLineEffect::TestCreate(SkRandom* random,
-                                         GrContext*,
-                                         const GrDrawTargetCaps& caps,
-                                         GrTexture*[]) {
-    GrEffectRef* effect;
-    GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(random->nextULessThan(
-            kGrEffectEdgeTypeCnt));
+GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random,
+                                                   GrContext*,
+                                                   const GrDrawTargetCaps& caps,
+                                                   GrTexture*[]) {
+    GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->nextULessThan(
+            kGrProcessorEdgeTypeCnt));
     SkScalar strokeWidth = random->nextRangeScalar(0, 100.f);
     DashInfo info;
     info.fCount = 2;
@@ -616,13 +853,22 @@
     info.fIntervals[1] = random->nextRangeScalar(0, 10.f);
     info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fIntervals[1]);
 
-    effect = DashingLineEffect::Create(edgeType, info, strokeWidth);
-    return effect;
+    return DashingLineEffect::Create(edgeType, info, strokeWidth);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GrEffectRef* GrDashingEffect::Create(GrEffectEdgeType edgeType, const SkPathEffect::DashInfo& info,
-                                     SkScalar strokeWidth) {
-    return DashingLineEffect::Create(edgeType, info, strokeWidth);
+GrGeometryProcessor* GrDashingEffect::Create(GrPrimitiveEdgeType edgeType,
+                                             const SkPathEffect::DashInfo& info,
+                                             SkScalar strokeWidth,
+                                             GrDashingEffect::DashCap cap) {
+    switch (cap) {
+        case GrDashingEffect::kRound_DashCap:
+            return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(strokeWidth));
+        case GrDashingEffect::kNonRound_DashCap:
+            return DashingLineEffect::Create(edgeType, info, strokeWidth);
+        default:
+            SkFAIL("Unexpected dashed cap.");
+    }
+    return NULL;
 }
diff --git a/src/gpu/effects/GrDashingEffect.h b/src/gpu/effects/GrDashingEffect.h
index 8096017..331b6c8 100644
--- a/src/gpu/effects/GrDashingEffect.h
+++ b/src/gpu/effects/GrDashingEffect.h
@@ -14,6 +14,7 @@
 
 class GrGpu;
 class GrDrawTarget;
+class GrGeometryProcessor;
 class GrPaint;
 class GrStrokeInfo;
 
@@ -24,14 +25,21 @@
     bool DrawDashLine(const SkPoint pts[2], const GrPaint& paint, const GrStrokeInfo& strokeInfo,
                       GrGpu* gpu, GrDrawTarget* target, const SkMatrix& vm);
 
+    enum DashCap {
+        kRound_DashCap,
+        kNonRound_DashCap,
+    };
+
     /**
      * An effect that renders a dashed line. It is intended to be used as a coverage effect.
      * The effect is meant for dashed lines that only have a single on/off interval pair.
      * Bounding geometry is rendered and the effect computes coverage based on the fragment's
      * position relative to the dashed line.
      */
-    GrEffectRef* Create(GrEffectEdgeType edgeType, const SkPathEffect::DashInfo& info,
-                        SkScalar strokeWidth);
+    GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType,
+                                const SkPathEffect::DashInfo& info,
+                                SkScalar strokeWidth,
+                                DashCap cap);
 }
 
 #endif
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index 29f0985..d5d3348 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -6,11 +6,12 @@
  */
 
 #include "GrDistanceFieldTextureEffect.h"
-#include "gl/GrGLEffect.h"
+#include "gl/builders/GrGLFullProgramBuilder.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
 #include "gl/GrGLTexture.h"
-#include "gl/GrGLVertexEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "gl/GrGLGeometryProcessor.h"
+#include "GrTBackendProcessorFactory.h"
 #include "GrTexture.h"
 
 #include "SkDistanceFieldGen.h"
@@ -28,25 +29,31 @@
 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2
 #define SK_DistanceFieldAAFactor     "0.7071"
 
-class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect {
+class GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor {
 public:
-    GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory,
-                                   const GrDrawEffect& drawEffect)
+    GrGLDistanceFieldTextureEffect(const GrBackendProcessorFactory& factory,
+                                   const GrProcessor&)
         : INHERITED (factory)
-        , fTextureSize(SkISize::Make(-1,-1)) {}
+        , fTextureSize(SkISize::Make(-1,-1))
+#ifdef SK_GAMMA_APPLY_TO_A8
+        , fLuminance(-1.0f)
+#endif
+        {}
 
-    virtual void emitCode(GrGLFullShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLFullProgramBuilder* builder,
+                          const GrGeometryProcessor& geometryProcessor,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray& samplers) SK_OVERRIDE {
-        SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldTextureEffect>().numVertexAttribs());
-
-        SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
         const GrDistanceFieldTextureEffect& dfTexEffect =
-                                              drawEffect.castEffect<GrDistanceFieldTextureEffect>();
+                geometryProcessor.cast<GrDistanceFieldTextureEffect>();
+        SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
+
+        GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+        SkAssertResult(fsBuilder->enableFeature(
+                GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
 
         SkString fsCoordName;
         const char* vsCoordName;
@@ -54,113 +61,113 @@
         builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
         fsCoordName = fsCoordNamePtr;
 
-        const char* attrName0 =
-            builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
-        builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0);
+        GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+        vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextureCoords().c_str());
 
         const char* textureSizeUniName = NULL;
-        fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                               kVec2f_GrSLType, "TextureSize",
                                               &textureSizeUniName);
 
-        builder->fsCodeAppend("\tvec4 texColor = ");
-        builder->fsAppendTextureLookup(samplers[0],
+        fsBuilder->codeAppend("\tvec4 texColor = ");
+        fsBuilder->appendTextureLookup(samplers[0],
                                        fsCoordName.c_str(),
                                        kVec2f_GrSLType);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppend("\tfloat distance = "
+        fsBuilder->codeAppend(";\n");
+        fsBuilder->codeAppend("\tfloat distance = "
                           SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ")"
                           "+ " SK_DistanceFieldNonLCDFactor ";\n");
 
         // we adjust for the effect of the transformation on the distance by using
         // the length of the gradient of the texture coordinates. We use st coordinates
         // to ensure we're mapping 1:1 from texel space to pixel space.
-        builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
-        builder->fsCodeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
-        builder->fsCodeAppend("\tfloat afwidth;\n");
-        if (dfTexEffect.isSimilarity()) {
+        fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
+        fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
+        fsBuilder->codeAppend("\tfloat afwidth;\n");
+        if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
             // this gives us a smooth step across approximately one fragment
-            builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx(st.x);\n");
+            fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx(st.x);\n");
         } else {
-            builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n");
-            builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n");
+            fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
+            fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
 
-            builder->fsCodeAppend("\tvec2 uv_grad;\n");
+            fsBuilder->codeAppend("\tvec2 uv_grad;\n");
             if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
                 // this is to compensate for the Adreno, which likes to drop tiles on division by 0
-                builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
-                builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n");
-                builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
-                builder->fsCodeAppend("\t} else {\n");
-                builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
-                builder->fsCodeAppend("\t}\n");
+                fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
+                fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
+                fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
+                fsBuilder->codeAppend("\t} else {\n");
+                fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
+                fsBuilder->codeAppend("\t}\n");
             } else {
-                builder->fsCodeAppend("\tuv_grad = normalize(uv);\n");
+                fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
             }
-            builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
-            builder->fsCodeAppend("\t                 uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
+            fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
+            fsBuilder->codeAppend("\t                 uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
 
             // this gives us a smooth step across approximately one fragment
-            builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
+            fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
         }
-        builder->fsCodeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n");
+        fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n");
 
 #ifdef SK_GAMMA_APPLY_TO_A8
         // adjust based on gamma
         const char* luminanceUniName = NULL;
         // width, height, 1/(3*width)
-        fLuminanceUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fLuminanceUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                             kFloat_GrSLType, "Luminance",
                                             &luminanceUniName);
 
-        builder->fsCodeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
-        builder->fsCodeAppend("\tvec4 gammaColor = ");
-        builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppend("\tval = gammaColor.r;\n");
+        fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
+        fsBuilder->codeAppend("\tvec4 gammaColor = ");
+        fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
+        fsBuilder->codeAppend(";\n");
+        fsBuilder->codeAppend("\tval = gammaColor.r;\n");
 #endif
 
-        builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+        fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str());
     }
 
-    virtual void setData(const GrGLUniformManager& uman,
-                         const GrDrawEffect& drawEffect) SK_OVERRIDE {
+    virtual void setData(const GrGLProgramDataManager& pdman,
+                         const GrProcessor& effect) SK_OVERRIDE {
         SkASSERT(fTextureSizeUni.isValid());
 
-        GrTexture* texture = drawEffect.effect()->get()->texture(0);
+        GrTexture* texture = effect.texture(0);
         if (texture->width() != fTextureSize.width() ||
             texture->height() != fTextureSize.height()) {
             fTextureSize = SkISize::Make(texture->width(), texture->height());
-            uman.set2f(fTextureSizeUni,
-                       SkIntToScalar(fTextureSize.width()),
-                       SkIntToScalar(fTextureSize.height()));
+            pdman.set2f(fTextureSizeUni,
+                        SkIntToScalar(fTextureSize.width()),
+                        SkIntToScalar(fTextureSize.height()));
         }
 #ifdef SK_GAMMA_APPLY_TO_A8
         const GrDistanceFieldTextureEffect& dfTexEffect =
-                                              drawEffect.castEffect<GrDistanceFieldTextureEffect>();
+                effect.cast<GrDistanceFieldTextureEffect>();
         float luminance = dfTexEffect.getLuminance();
         if (luminance != fLuminance) {
-            uman.set1f(fLuminanceUni, luminance);
+            pdman.set1f(fLuminanceUni, luminance);
             fLuminance = luminance;
         }
 #endif
     }
 
-    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+    static inline void GenKey(const GrProcessor& processor, const GrGLCaps&,
+                              GrProcessorKeyBuilder* b) {
         const GrDistanceFieldTextureEffect& dfTexEffect =
-                                              drawEffect.castEffect<GrDistanceFieldTextureEffect>();
+                processor.cast<GrDistanceFieldTextureEffect>();
 
-        return dfTexEffect.isSimilarity() ? 0x1 : 0x0;
+        b->add32(dfTexEffect.getFlags());
     }
 
 private:
-    GrGLUniformManager::UniformHandle fTextureSizeUni;
-    SkISize                           fTextureSize;
-    GrGLUniformManager::UniformHandle fLuminanceUni;
-    float                             fLuminance;
+    GrGLProgramDataManager::UniformHandle fTextureSizeUni;
+    SkISize                               fTextureSize;
+    GrGLProgramDataManager::UniformHandle fLuminanceUni;
+    float                                 fLuminance;
 
-    typedef GrGLVertexEffect INHERITED;
+    typedef GrGLGeometryProcessor INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -172,23 +179,31 @@
                                                            const GrTextureParams& gammaParams,
                                                            float luminance,
 #endif
-                                                           bool similarity)
+                                                           uint32_t flags)
     : fTextureAccess(texture, params)
 #ifdef SK_GAMMA_APPLY_TO_A8
     , fGammaTextureAccess(gamma, gammaParams)
     , fLuminance(luminance)
 #endif
-    , fIsSimilarity(similarity) {
+    , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
+    , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
+                                                         kVec2f_GrSLType,
+                                                         GrShaderVar::kAttribute_TypeModifier))) {
+    SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
     this->addTextureAccess(&fTextureAccess);
 #ifdef SK_GAMMA_APPLY_TO_A8
     this->addTextureAccess(&fGammaTextureAccess);
 #endif
-    this->addVertexAttrib(kVec2f_GrSLType);
 }
 
-bool GrDistanceFieldTextureEffect::onIsEqual(const GrEffect& other) const {
-    const GrDistanceFieldTextureEffect& cte = CastEffect<GrDistanceFieldTextureEffect>(other);
-    return fTextureAccess == cte.fTextureAccess;
+bool GrDistanceFieldTextureEffect::onIsEqual(const GrProcessor& other) const {
+    const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureEffect>();
+    return fTextureAccess == cte.fTextureAccess &&
+#ifdef SK_GAMMA_APPLY_TO_A8
+           fGammaTextureAccess == cte.fGammaTextureAccess &&
+           fLuminance == cte.fLuminance &&
+#endif
+           fFlags == cte.fFlags;
 }
 
 void GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color,
@@ -201,23 +216,23 @@
     }
 }
 
-const GrBackendEffectFactory& GrDistanceFieldTextureEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrDistanceFieldTextureEffect>::getInstance();
+const GrBackendGeometryProcessorFactory& GrDistanceFieldTextureEffect::getFactory() const {
+    return GrTBackendGeometryProcessorFactory<GrDistanceFieldTextureEffect>::getInstance();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrDistanceFieldTextureEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect);
 
-GrEffectRef* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
-                                                     GrContext*,
-                                                     const GrDrawTargetCaps&,
-                                                     GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
+GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
+                                                              GrContext*,
+                                                              const GrDrawTargetCaps&,
+                                                              GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                      GrProcessorUnitTest::kAlphaTextureIdx;
 #ifdef SK_GAMMA_APPLY_TO_A8
-    int texIdx2 = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                       GrEffectUnitTest::kAlphaTextureIdx;
+    int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                       GrProcessorUnitTest::kAlphaTextureIdx;
 #endif
     static const SkShader::TileMode kTileModes[] = {
         SkShader::kClamp_TileMode,
@@ -240,30 +255,30 @@
                                                 textures[texIdx2], params2,
                                                 random->nextF(),
 #endif
-                                                random->nextBool());
+                                                random->nextBool() ?
+                                                    kSimilarity_DistanceFieldEffectFlag : 0);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class GrGLDistanceFieldLCDTextureEffect : public GrGLVertexEffect {
+class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor {
 public:
-    GrGLDistanceFieldLCDTextureEffect(const GrBackendEffectFactory& factory,
-                                      const GrDrawEffect& drawEffect)
+    GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory,
+                                      const GrProcessor&)
     : INHERITED (factory)
-    , fTextureSize(SkISize::Make(-1,-1)) {}
+    , fTextureSize(SkISize::Make(-1,-1))
+    , fTextColor(GrColor_ILLEGAL) {}
 
-    virtual void emitCode(GrGLFullShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLFullProgramBuilder* builder,
+                          const GrGeometryProcessor& geometryProcessor,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray& samplers) SK_OVERRIDE {
-        SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>().numVertexAttribs());
-
-        SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
         const GrDistanceFieldLCDTextureEffect& dfTexEffect =
-                                           drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>();
+                geometryProcessor.cast<GrDistanceFieldLCDTextureEffect>();
+        SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
 
         SkString fsCoordName;
         const char* vsCoordName;
@@ -271,48 +286,53 @@
         builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
         fsCoordName = fsCoordNamePtr;
 
-        const char* attrName0 =
-                   builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
-        builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0);
+        GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
+        vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextureCoords().c_str());
 
         const char* textureSizeUniName = NULL;
         // width, height, 1/(3*width)
-        fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                               kVec3f_GrSLType, "TextureSize",
                                               &textureSizeUniName);
 
+        GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+
+        SkAssertResult(fsBuilder->enableFeature(
+                GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
+
         // create LCD offset adjusted by inverse of transform
-        builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
-        builder->fsCodeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName);
-        if (dfTexEffect.isUniformScale()) {
-            builder->fsCodeAppend("\tfloat dx = dFdx(st.x);\n");
-            builder->fsCodeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName);
+        fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
+        fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName);
+        bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
+        if (isUniformScale) {
+            fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n");
+            fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName);
         } else {
-            builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n");
-            builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n");
-            builder->fsCodeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName);
+            fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
+            fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
+            fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName);
         }
 
         // green is distance to uv center
-        builder->fsCodeAppend("\tvec4 texColor = ");
-        builder->fsAppendTextureLookup(samplers[0], "uv", kVec2f_GrSLType);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppend("\tvec3 distance;\n");
-        builder->fsCodeAppend("\tdistance.y = texColor.r;\n");
+        fsBuilder->codeAppend("\tvec4 texColor = ");
+        fsBuilder->appendTextureLookup(samplers[0], "uv", kVec2f_GrSLType);
+        fsBuilder->codeAppend(";\n");
+        fsBuilder->codeAppend("\tvec3 distance;\n");
+        fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
         // red is distance to left offset
-        builder->fsCodeAppend("\tvec2 uv_adjusted = uv - offset;\n");
-        builder->fsCodeAppend("\ttexColor = ");
-        builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppend("\tdistance.x = texColor.r;\n");
+        fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
+        fsBuilder->codeAppend("\ttexColor = ");
+        fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType);
+        fsBuilder->codeAppend(";\n");
+        fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
         // blue is distance to right offset
-        builder->fsCodeAppend("\tuv_adjusted = uv + offset;\n");
-        builder->fsCodeAppend("\ttexColor = ");
-        builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppend("\tdistance.z = texColor.r;\n");
+        fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
+        fsBuilder->codeAppend("\ttexColor = ");
+        fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType);
+        fsBuilder->codeAppend(";\n");
+        fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
 
-        builder->fsCodeAppend("\tdistance = "
+        fsBuilder->codeAppend("\tdistance = "
             "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"))"
             "+ vec3(" SK_DistanceFieldLCDFactor ");\n");
 
@@ -324,107 +344,108 @@
         // for each color component. However, this is only important when using perspective
         // transformations, and even then using a single factor seems like a reasonable
         // trade-off between quality and speed.
-        builder->fsCodeAppend("\tfloat afwidth;\n");
-        if (dfTexEffect.isUniformScale()) {
+        fsBuilder->codeAppend("\tfloat afwidth;\n");
+        if (isUniformScale) {
             // this gives us a smooth step across approximately one fragment
-            builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\n");
+            fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\n");
         } else {
-            builder->fsCodeAppend("\tvec2 uv_grad;\n");
+            fsBuilder->codeAppend("\tvec2 uv_grad;\n");
             if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
                 // this is to compensate for the Adreno, which likes to drop tiles on division by 0
-                builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
-                builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n");
-                builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
-                builder->fsCodeAppend("\t} else {\n");
-                builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
-                builder->fsCodeAppend("\t}\n");
+                fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
+                fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
+                fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
+                fsBuilder->codeAppend("\t} else {\n");
+                fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
+                fsBuilder->codeAppend("\t}\n");
             } else {
-                builder->fsCodeAppend("\tuv_grad = normalize(uv);\n");
+                fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
             }
-            builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
-            builder->fsCodeAppend("\t                 uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
+            fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
+            fsBuilder->codeAppend("\t                 uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
 
             // this gives us a smooth step across approximately one fragment
-            builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
+            fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
         }
 
-        builder->fsCodeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n");
+        fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n");
 
         // adjust based on gamma
         const char* textColorUniName = NULL;
         // width, height, 1/(3*width)
-        fTextColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+        fTextColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                             kVec3f_GrSLType, "TextColor",
                                             &textColorUniName);
 
-        builder->fsCodeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
-        builder->fsCodeAppend("\tvec4 gammaColor = ");
-        builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppend("\tval.x = gammaColor.r;\n");
+        fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
+        fsBuilder->codeAppend("\tvec4 gammaColor = ");
+        fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
+        fsBuilder->codeAppend(";\n");
+        fsBuilder->codeAppend("\tval.x = gammaColor.r;\n");
 
-        builder->fsCodeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
-        builder->fsCodeAppend("\tgammaColor = ");
-        builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppend("\tval.y = gammaColor.r;\n");
+        fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
+        fsBuilder->codeAppend("\tgammaColor = ");
+        fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
+        fsBuilder->codeAppend(";\n");
+        fsBuilder->codeAppend("\tval.y = gammaColor.r;\n");
 
-        builder->fsCodeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
-        builder->fsCodeAppend("\tgammaColor = ");
-        builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppend("\tval.z = gammaColor.r;\n");
+        fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
+        fsBuilder->codeAppend("\tgammaColor = ");
+        fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType);
+        fsBuilder->codeAppend(";\n");
+        fsBuilder->codeAppend("\tval.z = gammaColor.r;\n");
 
-        builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+        fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
                                (GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_str());
     }
 
-    virtual void setData(const GrGLUniformManager& uman,
-                         const GrDrawEffect& drawEffect) SK_OVERRIDE {
+    virtual void setData(const GrGLProgramDataManager& pdman,
+                         const GrProcessor& processor) SK_OVERRIDE {
         SkASSERT(fTextureSizeUni.isValid());
         SkASSERT(fTextColorUni.isValid());
 
         const GrDistanceFieldLCDTextureEffect& dfTexEffect =
-                                    drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>();
-        GrTexture* texture = drawEffect.effect()->get()->texture(0);
+                processor.cast<GrDistanceFieldLCDTextureEffect>();
+        GrTexture* texture = processor.texture(0);
         if (texture->width() != fTextureSize.width() ||
             texture->height() != fTextureSize.height()) {
             fTextureSize = SkISize::Make(texture->width(), texture->height());
             float delta = 1.0f/(3.0f*texture->width());
-            if (dfTexEffect.useBGR()) {
+            if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
                 delta = -delta;
             }
-            uman.set3f(fTextureSizeUni,
-                       SkIntToScalar(fTextureSize.width()),
-                       SkIntToScalar(fTextureSize.height()),
-                       delta);
+            pdman.set3f(fTextureSizeUni,
+                        SkIntToScalar(fTextureSize.width()),
+                        SkIntToScalar(fTextureSize.height()),
+                        delta);
         }
 
         GrColor textColor = dfTexEffect.getTextColor();
         if (textColor != fTextColor) {
             static const float ONE_OVER_255 = 1.f / 255.f;
-            uman.set3f(fTextColorUni,
-                       GrColorUnpackR(textColor) * ONE_OVER_255,
-                       GrColorUnpackG(textColor) * ONE_OVER_255,
-                       GrColorUnpackB(textColor) * ONE_OVER_255);
+            pdman.set3f(fTextColorUni,
+                        GrColorUnpackR(textColor) * ONE_OVER_255,
+                        GrColorUnpackG(textColor) * ONE_OVER_255,
+                        GrColorUnpackB(textColor) * ONE_OVER_255);
             fTextColor = textColor;
         }
     }
 
-    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+    static inline void GenKey(const GrProcessor& processor, const GrGLCaps&,
+                              GrProcessorKeyBuilder* b) {
         const GrDistanceFieldLCDTextureEffect& dfTexEffect =
-                                           drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>();
+                processor.cast<GrDistanceFieldLCDTextureEffect>();
 
-        return dfTexEffect.isUniformScale() ? 0x01 : 0x00;;
+        b->add32(dfTexEffect.getFlags());
     }
 
 private:
-    GrGLUniformManager::UniformHandle fTextureSizeUni;
-    SkISize                           fTextureSize;
-    GrGLUniformManager::UniformHandle fTextColorUni;
-    SkColor                           fTextColor;
+    GrGLProgramDataManager::UniformHandle fTextureSizeUni;
+    SkISize                               fTextureSize;
+    GrGLProgramDataManager::UniformHandle fTextColorUni;
+    SkColor                               fTextColor;
 
-    typedef GrGLVertexEffect INHERITED;
+    typedef GrGLGeometryProcessor INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -433,21 +454,26 @@
                                                   GrTexture* texture, const GrTextureParams& params,
                                                   GrTexture* gamma, const GrTextureParams& gParams,
                                                   SkColor textColor,
-                                                  bool uniformScale, bool useBGR)
+                                                  uint32_t flags)
     : fTextureAccess(texture, params)
     , fGammaTextureAccess(gamma, gParams)
     , fTextColor(textColor)
-    , fUniformScale(uniformScale)
-    , fUseBGR(useBGR) {
+    , fFlags(flags & kLCD_DistanceFieldEffectMask)
+    , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
+                                                         kVec2f_GrSLType,
+                                                         GrShaderVar::kAttribute_TypeModifier))) {
+    SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag));
+        
     this->addTextureAccess(&fTextureAccess);
     this->addTextureAccess(&fGammaTextureAccess);
-    this->addVertexAttrib(kVec2f_GrSLType);
 }
 
-bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrEffect& other) const {
-    const GrDistanceFieldLCDTextureEffect& cte = 
-                                            CastEffect<GrDistanceFieldLCDTextureEffect>(other);
-    return (fTextureAccess == cte.fTextureAccess && fGammaTextureAccess == cte.fGammaTextureAccess);
+bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrProcessor& other) const {
+    const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTextureEffect>();
+    return (fTextureAccess == cte.fTextureAccess &&
+            fGammaTextureAccess == cte.fGammaTextureAccess &&
+            fTextColor == cte.fTextColor &&
+            fFlags == cte.fFlags);
 }
 
 void GrDistanceFieldLCDTextureEffect::getConstantColorComponents(GrColor* color,
@@ -460,22 +486,22 @@
     }
 }
 
-const GrBackendEffectFactory& GrDistanceFieldLCDTextureEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrDistanceFieldLCDTextureEffect>::getInstance();
+const GrBackendGeometryProcessorFactory& GrDistanceFieldLCDTextureEffect::getFactory() const {
+    return GrTBackendGeometryProcessorFactory<GrDistanceFieldLCDTextureEffect>::getInstance();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrDistanceFieldLCDTextureEffect);
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect);
 
-GrEffectRef* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random,
-                                                         GrContext*,
-                                                         const GrDrawTargetCaps&,
-                                                         GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
-    int texIdx2 = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                       GrEffectUnitTest::kAlphaTextureIdx;
+GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random,
+                                                                 GrContext*,
+                                                                 const GrDrawTargetCaps&,
+                                                                 GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                      GrProcessorUnitTest::kAlphaTextureIdx;
+    int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                       GrProcessorUnitTest::kAlphaTextureIdx;
     static const SkShader::TileMode kTileModes[] = {
         SkShader::kClamp_TileMode,
         SkShader::kRepeat_TileMode,
@@ -493,8 +519,11 @@
                                         random->nextULessThan(256),
                                         random->nextULessThan(256),
                                         random->nextULessThan(256));
+    uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
+    flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
+    flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
     return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params,
                                                    textures[texIdx2], params2,
                                                    textColor,
-                                                   random->nextBool(), random->nextBool());
+                                                   flags);
 }
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h
index 692290c..b8d774d 100644
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.h
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h
@@ -8,69 +8,88 @@
 #ifndef GrDistanceFieldTextureEffect_DEFINED
 #define GrDistanceFieldTextureEffect_DEFINED
 
-#include "GrEffect.h"
-#include "GrVertexEffect.h"
+#include "GrProcessor.h"
+#include "GrGeometryProcessor.h"
 
 class GrGLDistanceFieldTextureEffect;
 class GrGLDistanceFieldLCDTextureEffect;
 
+enum GrDistanceFieldEffectFlags {
+    kSimilarity_DistanceFieldEffectFlag = 0x01,   // ctm is similarity matrix
+    kRectToRect_DistanceFieldEffectFlag = 0x02,   // ctm maps rects to rects
+    kUseLCD_DistanceFieldEffectFlag     = 0x04,   // use lcd text
+    kBGR_DistanceFieldEffectFlag        = 0x08,   // lcd display has bgr order
+    kPortrait_DistanceFieldEffectFlag   = 0x10,   // lcd display is in portrait mode (not used yet)
+    
+    kUniformScale_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag |
+                                            kRectToRect_DistanceFieldEffectFlag,
+    // The subset of the flags relevant to GrDistanceFieldTextureEffect
+    kNonLCD_DistanceFieldEffectMask       = kSimilarity_DistanceFieldEffectFlag,
+    // The subset of the flags relevant to GrDistanceFieldLCDTextureEffect
+    kLCD_DistanceFieldEffectMask          = kSimilarity_DistanceFieldEffectFlag |
+                                            kRectToRect_DistanceFieldEffectFlag |
+                                            kUseLCD_DistanceFieldEffectFlag |
+                                            kBGR_DistanceFieldEffectFlag,
+};
+
 /**
  * The output color of this effect is a modulation of the input color and a sample from a
  * distance field texture (using a smoothed step function near 0.5).
  * It allows explicit specification of the filtering and wrap modes (GrTextureParams). The input
  * coords are a custom attribute. Gamma correction is handled via a texture LUT.
  */
-class GrDistanceFieldTextureEffect : public GrVertexEffect {
+class GrDistanceFieldTextureEffect : public GrGeometryProcessor {
 public:
 #ifdef SK_GAMMA_APPLY_TO_A8
-    static GrEffectRef* Create(GrTexture* tex, const GrTextureParams& params,
-                               GrTexture* gamma, const GrTextureParams& gammaParams, float lum,
-                               bool similarity) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, params,
-                                                                         gamma, gammaParams, lum,
-                                                                         similarity)));
-#else
-    static GrEffectRef* Create(GrTexture* tex, const GrTextureParams& params,
-                               bool similarity) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, params,
-                                                                         similarity)));
-#endif
-        return CreateEffectRef(effect);
+    static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params,
+                                       GrTexture* gamma, const GrTextureParams& gammaParams,
+                                       float lum, uint32_t flags) {
+       return SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, params, gamma, gammaParams, lum,
+                                                        flags));
     }
+#else
+    static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params,
+                                       uint32_t flags) {
+        return  SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, params, flags));
+    }
+#endif
 
     virtual ~GrDistanceFieldTextureEffect() {}
 
     static const char* Name() { return "DistanceFieldTexture"; }
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
+
+    const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
 #ifdef SK_GAMMA_APPLY_TO_A8
     float getLuminance() const { return fLuminance; }
 #endif
-    bool isSimilarity() const { return fIsSimilarity; }
+    uint32_t getFlags() const { return fFlags; }
 
-    typedef GrGLDistanceFieldTextureEffect GLEffect;
+    typedef GrGLDistanceFieldTextureEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
     GrDistanceFieldTextureEffect(GrTexture* texture, const GrTextureParams& params,
 #ifdef SK_GAMMA_APPLY_TO_A8
                                  GrTexture* gamma, const GrTextureParams& gammaParams, float lum,
 #endif
-                                 bool uniformScale);
+                                 uint32_t flags);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
-    GrTextureAccess fTextureAccess;
+    GrTextureAccess    fTextureAccess;
 #ifdef SK_GAMMA_APPLY_TO_A8
-    GrTextureAccess fGammaTextureAccess;
-    float           fLuminance;
+    GrTextureAccess    fGammaTextureAccess;
+    float              fLuminance;
 #endif
-    bool            fIsSimilarity;
+    uint32_t           fFlags;
+    const GrShaderVar& fInTextureCoords;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrVertexEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 /**
@@ -79,48 +98,45 @@
  * It allows explicit specification of the filtering and wrap modes (GrTextureParams). The input
  * coords are a custom attribute. Gamma correction is handled via a texture LUT.
  */
-class GrDistanceFieldLCDTextureEffect : public GrVertexEffect {
+class GrDistanceFieldLCDTextureEffect : public GrGeometryProcessor {
 public:
-    static GrEffectRef* Create(GrTexture* tex, const GrTextureParams& params,
-                               GrTexture* gamma, const GrTextureParams& gammaParams, 
-                               SkColor textColor,
-                               bool uniformScale, bool useBGR) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrDistanceFieldLCDTextureEffect,
-                                          (tex, params, gamma, gammaParams, textColor, uniformScale,
-                                           useBGR)));
-        return CreateEffectRef(effect);
+    static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params,
+                                       GrTexture* gamma, const GrTextureParams& gammaParams,
+                                       SkColor textColor, uint32_t flags) {
+        return SkNEW_ARGS(GrDistanceFieldLCDTextureEffect,
+                          (tex, params, gamma, gammaParams, textColor, flags));
     }
 
     virtual ~GrDistanceFieldLCDTextureEffect() {}
 
     static const char* Name() { return "DistanceFieldLCDTexture"; }
 
+    const GrShaderVar& inTextureCoords() const { return fInTextureCoords; }
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
     GrColor getTextColor() const { return fTextColor; }
-    bool isUniformScale() const { return fUniformScale; }
-    bool useBGR() const { return fUseBGR; }
+    uint32_t getFlags() const { return fFlags; }
 
-    typedef GrGLDistanceFieldLCDTextureEffect GLEffect;
+    typedef GrGLDistanceFieldLCDTextureEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
     GrDistanceFieldLCDTextureEffect(GrTexture* texture, const GrTextureParams& params,
                                     GrTexture* gamma, const GrTextureParams& gammaParams,
                                     SkColor textColor,
-                                    bool uniformScale, bool useBGR);
+                                    uint32_t flags);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
-    GrTextureAccess fTextureAccess;
-    GrTextureAccess fGammaTextureAccess;
-    GrColor         fTextColor;
-    bool            fUniformScale;
-    bool            fUseBGR;
+    GrTextureAccess    fTextureAccess;
+    GrTextureAccess    fGammaTextureAccess;
+    GrColor            fTextColor;
+    uint32_t           fFlags;
+    const GrShaderVar& fInTextureCoords;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
 
-    typedef GrVertexEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 #endif
diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp
index 7409e5f..fe7447d 100644
--- a/src/gpu/effects/GrDitherEffect.cpp
+++ b/src/gpu/effects/GrDitherEffect.cpp
@@ -5,11 +5,12 @@
  * found in the LICENSE file.
  */
 
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "GrDitherEffect.h"
 
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 
 #include "SkRect.h"
 
@@ -17,21 +18,22 @@
 
 class GLDitherEffect;
 
-class DitherEffect : public GrEffect {
+class DitherEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create() {
-        return CreateEffectRef(AutoEffectUnref(SkNEW(DitherEffect)));
+    static GrFragmentProcessor* Create() {
+        GR_CREATE_STATIC_FRAGMENT_PROCESSOR(gDitherEffect, DitherEffect, ())
+        return SkRef(gDitherEffect);
     }
 
     virtual ~DitherEffect() {};
     static const char* Name() { return "Dither"; }
 
-    typedef GLDitherEffect GLEffect;
+    typedef GLDitherEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendEffectFactory<DitherEffect>::getInstance();
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<DitherEffect>::getInstance();
     }
 
 private:
@@ -40,11 +42,11 @@
     }
 
     // All dither effects are equal
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { return true; }
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 void DitherEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
@@ -53,45 +55,46 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(DitherEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(DitherEffect);
 
-GrEffectRef* DitherEffect::TestCreate(SkRandom*,
-                                      GrContext*,
-                                      const GrDrawTargetCaps&,
-                                      GrTexture*[]) {
+GrFragmentProcessor* DitherEffect::TestCreate(SkRandom*,
+                                              GrContext*,
+                                              const GrDrawTargetCaps&,
+                                              GrTexture*[]) {
     return DitherEffect::Create();
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GLDitherEffect : public GrGLEffect {
+class GLDitherEffect : public GrGLFragmentProcessor {
 public:
-    GLDitherEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GLDitherEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor& fp,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
 private:
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GLDitherEffect::GLDitherEffect(const GrBackendEffectFactory& factory,
-                               const GrDrawEffect& drawEffect)
+GLDitherEffect::GLDitherEffect(const GrBackendProcessorFactory& factory,
+                               const GrProcessor&)
     : INHERITED (factory) {
 }
 
-void GLDitherEffect::emitCode(GrGLShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+void GLDitherEffect::emitCode(GrGLProgramBuilder* builder,
+                              const GrFragmentProcessor& fp,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
                               const TextureSamplerArray& samplers) {
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
     // Generate a random number based on the fragment position. For this
     // random number generator, we use the "GLSL rand" function
     // that seems to be floating around on the internet. It works under
@@ -101,15 +104,13 @@
 
     // For each channel c, add the random offset to the pixel to either bump
     // it up or let it remain constant during quantization.
-    builder->fsCodeAppendf("\t\tfloat r = "
+    fsBuilder->codeAppendf("\t\tfloat r = "
                            "fract(sin(dot(%s.xy ,vec2(12.9898,78.233))) * 43758.5453);\n",
-                           builder->fragmentPosition());
-    builder->fsCodeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n",
+                           fsBuilder->fragmentPosition());
+    fsBuilder->codeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n",
                            outputColor, GrGLSLExpr4(inputColor).c_str());
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GrEffectRef* GrDitherEffect::Create() {
-    return DitherEffect::Create();
-}
+GrFragmentProcessor* GrDitherEffect::Create() { return DitherEffect::Create(); }
diff --git a/src/gpu/effects/GrDitherEffect.h b/src/gpu/effects/GrDitherEffect.h
index 63036c0..ac4c784 100644
--- a/src/gpu/effects/GrDitherEffect.h
+++ b/src/gpu/effects/GrDitherEffect.h
@@ -11,13 +11,13 @@
 #include "GrTypes.h"
 #include "GrTypesPriv.h"
 
-class GrEffectRef;
+class GrProcessor;
 
 namespace GrDitherEffect {
     /**
      * Creates an effect that dithers the resulting color to an RGBA8 framebuffer
      */
-    GrEffectRef* Create();
+    GrFragmentProcessor* Create();
 };
 
 #endif
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
new file mode 100644
index 0000000..c0080c6
--- /dev/null
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -0,0 +1,276 @@
+/*
+ * 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 "gl/builders/GrGLProgramBuilder.h"
+#include "GrMatrixConvolutionEffect.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/GrGLSL.h"
+#include "gl/GrGLTexture.h"
+#include "GrTBackendProcessorFactory.h"
+
+class GrGLMatrixConvolutionEffect : public GrGLFragmentProcessor {
+public:
+    GrGLMatrixConvolutionEffect(const GrBackendProcessorFactory& factory,
+                                const GrProcessor&);
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
+                          const char* outputColor,
+                          const char* inputColor,
+                          const TransformedCoordsArray&,
+                          const TextureSamplerArray&) SK_OVERRIDE;
+
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
+
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
+
+private:
+    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+    SkISize                     fKernelSize;
+    bool                        fConvolveAlpha;
+
+    UniformHandle               fBoundsUni;
+    UniformHandle               fKernelUni;
+    UniformHandle               fImageIncrementUni;
+    UniformHandle               fKernelOffsetUni;
+    UniformHandle               fGainUni;
+    UniformHandle               fBiasUni;
+    GrTextureDomain::GLDomain   fDomain;
+
+    typedef GrGLFragmentProcessor INHERITED;
+};
+
+GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendProcessorFactory& factory,
+                                                         const GrProcessor& processor)
+    : INHERITED(factory) {
+    const GrMatrixConvolutionEffect& m = processor.cast<GrMatrixConvolutionEffect>();
+    fKernelSize = m.kernelSize();
+    fConvolveAlpha = m.convolveAlpha();
+}
+
+void GrGLMatrixConvolutionEffect::emitCode(GrGLProgramBuilder* builder,
+                                           const GrFragmentProcessor& fp,
+                                           const GrProcessorKey& key,
+                                           const char* outputColor,
+                                           const char* inputColor,
+                                           const TransformedCoordsArray& coords,
+                                           const TextureSamplerArray& samplers) {
+    sk_ignore_unused_variable(inputColor);
+    const GrTextureDomain& domain = fp.cast<GrMatrixConvolutionEffect>().domain();
+
+    fBoundsUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                     kVec4f_GrSLType, "Bounds");
+    fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                             kVec2f_GrSLType, "ImageIncrement");
+    fKernelUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
+                                          kFloat_GrSLType,
+                                          "Kernel",
+                                          fKernelSize.width() * fKernelSize.height());
+    fKernelOffsetUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                           kVec2f_GrSLType, "KernelOffset");
+    fGainUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                   kFloat_GrSLType, "Gain");
+    fBiasUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                   kFloat_GrSLType, "Bias");
+
+    const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni);
+    const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
+    const char* kernel = builder->getUniformCStr(fKernelUni);
+    const char* gain = builder->getUniformCStr(fGainUni);
+    const char* bias = builder->getUniformCStr(fBiasUni);
+    int kWidth = fKernelSize.width();
+    int kHeight = fKernelSize.height();
+
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+    fsBuilder->codeAppend("vec4 sum = vec4(0, 0, 0, 0);");
+    fsBuilder->codeAppendf("vec2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset,
+                           imgInc);
+    fsBuilder->codeAppend("vec4 c;");
+
+    for (int y = 0; y < kHeight; y++) {
+        for (int x = 0; x < kWidth; x++) {
+            GrGLShaderBuilder::ShaderBlock block(fsBuilder);
+            fsBuilder->codeAppendf("float k = %s[%d * %d + %d];", kernel, y, kWidth, x);
+            SkString coord;
+            coord.printf("coord + vec2(%d, %d) * %s", x, y, imgInc);
+            fDomain.sampleTexture(fsBuilder, domain, "c", coord, samplers[0]);
+            if (!fConvolveAlpha) {
+                fsBuilder->codeAppend("c.rgb /= c.a;");
+            }
+            fsBuilder->codeAppend("sum += c * k;");
+        }
+    }
+    if (fConvolveAlpha) {
+        fsBuilder->codeAppendf("%s = sum * %s + %s;", outputColor, gain, bias);
+        fsBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);",
+                               outputColor, outputColor, outputColor);
+    } else {
+        fDomain.sampleTexture(fsBuilder, domain, "c", coords2D, samplers[0]);
+        fsBuilder->codeAppendf("%s.a = c.a;", outputColor);
+        fsBuilder->codeAppendf("%s.rgb = sum.rgb * %s + %s;", outputColor, gain, bias);
+        fsBuilder->codeAppendf("%s.rgb *= %s.a;", outputColor, outputColor);
+    }
+
+    SkString modulate;
+    GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
+    fsBuilder->codeAppend(modulate.c_str());
+}
+
+void GrGLMatrixConvolutionEffect::GenKey(const GrProcessor& processor,
+                                         const GrGLCaps&, GrProcessorKeyBuilder* b) {
+    const GrMatrixConvolutionEffect& m = processor.cast<GrMatrixConvolutionEffect>();
+    SkASSERT(m.kernelSize().width() <= 0x7FFF && m.kernelSize().height() <= 0xFFFF);
+    uint32_t key = m.kernelSize().width() << 16 | m.kernelSize().height();
+    key |= m.convolveAlpha() ? 1 << 31 : 0;
+    b->add32(key);
+    b->add32(GrTextureDomain::GLDomain::DomainKey(m.domain()));
+}
+
+void GrGLMatrixConvolutionEffect::setData(const GrGLProgramDataManager& pdman,
+                                          const GrProcessor& processor) {
+    const GrMatrixConvolutionEffect& conv = processor.cast<GrMatrixConvolutionEffect>();
+    GrTexture& texture = *conv.texture(0);
+    // the code we generated was for a specific kernel size
+    SkASSERT(conv.kernelSize() == fKernelSize);
+    float imageIncrement[2];
+    float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f;
+    imageIncrement[0] = 1.0f / texture.width();
+    imageIncrement[1] = ySign / texture.height();
+    pdman.set2fv(fImageIncrementUni, 1, imageIncrement);
+    pdman.set2fv(fKernelOffsetUni, 1, conv.kernelOffset());
+    pdman.set1fv(fKernelUni, fKernelSize.width() * fKernelSize.height(), conv.kernel());
+    pdman.set1f(fGainUni, conv.gain());
+    pdman.set1f(fBiasUni, conv.bias());
+    fDomain.setData(pdman, conv.domain(), texture.origin());
+}
+
+GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
+                                                     const SkIRect& bounds,
+                                                     const SkISize& kernelSize,
+                                                     const SkScalar* kernel,
+                                                     SkScalar gain,
+                                                     SkScalar bias,
+                                                     const SkIPoint& kernelOffset,
+                                                     GrTextureDomain::Mode tileMode,
+                                                     bool convolveAlpha)
+  : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)),
+    fKernelSize(kernelSize),
+    fGain(SkScalarToFloat(gain)),
+    fBias(SkScalarToFloat(bias) / 255.0f),
+    fConvolveAlpha(convolveAlpha),
+    fDomain(GrTextureDomain::MakeTexelDomain(texture, bounds), tileMode) {
+    for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
+        fKernel[i] = SkScalarToFloat(kernel[i]);
+    }
+    fKernelOffset[0] = static_cast<float>(kernelOffset.x());
+    fKernelOffset[1] = static_cast<float>(kernelOffset.y());
+}
+
+GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() {
+}
+
+const GrBackendFragmentProcessorFactory& GrMatrixConvolutionEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrMatrixConvolutionEffect>::getInstance();
+}
+
+bool GrMatrixConvolutionEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrMatrixConvolutionEffect& s = sBase.cast<GrMatrixConvolutionEffect>();
+    return this->texture(0) == s.texture(0) &&
+           fKernelSize == s.kernelSize() &&
+           !memcmp(fKernel, s.kernel(),
+                   fKernelSize.width() * fKernelSize.height() * sizeof(float)) &&
+           fGain == s.gain() &&
+           fBias == s.bias() &&
+           fKernelOffset == s.kernelOffset() &&
+           fConvolveAlpha == s.convolveAlpha() &&
+           fDomain == s.domain();
+}
+
+// Static function to create a 2D convolution
+GrFragmentProcessor*
+GrMatrixConvolutionEffect::CreateGaussian(GrTexture* texture,
+                                          const SkIRect& bounds,
+                                          const SkISize& kernelSize,
+                                          SkScalar gain,
+                                          SkScalar bias,
+                                          const SkIPoint& kernelOffset,
+                                          GrTextureDomain::Mode tileMode,
+                                          bool convolveAlpha,
+                                          SkScalar sigmaX,
+                                          SkScalar sigmaY) {
+    float kernel[MAX_KERNEL_SIZE];
+    int width = kernelSize.width();
+    int height = kernelSize.height();
+    SkASSERT(width * height <= MAX_KERNEL_SIZE);
+    float sum = 0.0f;
+    float sigmaXDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaX)));
+    float sigmaYDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaY)));
+    int xRadius = width / 2;
+    int yRadius = height / 2;
+    for (int x = 0; x < width; x++) {
+      float xTerm = static_cast<float>(x - xRadius);
+      xTerm = xTerm * xTerm * sigmaXDenom;
+      for (int y = 0; y < height; y++) {
+        float yTerm = static_cast<float>(y - yRadius);
+        float xyTerm = sk_float_exp(-(xTerm + yTerm * yTerm * sigmaYDenom));
+        // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
+       // is dropped here, since we renormalize the kernel below.
+        kernel[y * width + x] = xyTerm;
+        sum += xyTerm;
+      }
+    }
+    // Normalize the kernel
+    float scale = 1.0f / sum;
+    for (int i = 0; i < width * height; ++i) {
+        kernel[i] *= scale;
+    }
+    return SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
+                                                  bounds,
+                                                  kernelSize,
+                                                  kernel,
+                                                  gain,
+                                                  bias,
+                                                  kernelOffset,
+                                                  tileMode,
+                                                  convolveAlpha));
+}
+
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMatrixConvolutionEffect);
+
+GrFragmentProcessor* GrMatrixConvolutionEffect::TestCreate(SkRandom* random,
+                                                           GrContext* context,
+                                                           const GrDrawTargetCaps&,
+                                                           GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                      GrProcessorUnitTest::kAlphaTextureIdx;
+    int width = random->nextRangeU(1, MAX_KERNEL_SIZE);
+    int height = random->nextRangeU(1, MAX_KERNEL_SIZE / width);
+    SkISize kernelSize = SkISize::Make(width, height);
+    SkAutoTDeleteArray<SkScalar> kernel(new SkScalar[width * height]);
+    for (int i = 0; i < width * height; i++) {
+        kernel.get()[i] = random->nextSScalar1();
+    }
+    SkScalar gain = random->nextSScalar1();
+    SkScalar bias = random->nextSScalar1();
+    SkIPoint kernelOffset = SkIPoint::Make(random->nextRangeU(0, kernelSize.width()),
+                                           random->nextRangeU(0, kernelSize.height()));
+    SkIRect bounds = SkIRect::MakeXYWH(random->nextRangeU(0, textures[texIdx]->width()),
+                                       random->nextRangeU(0, textures[texIdx]->height()),
+                                       random->nextRangeU(0, textures[texIdx]->width()),
+                                       random->nextRangeU(0, textures[texIdx]->height()));
+    GrTextureDomain::Mode tileMode = static_cast<GrTextureDomain::Mode>(random->nextRangeU(0, 2));
+    bool convolveAlpha = random->nextBool();
+    return GrMatrixConvolutionEffect::Create(textures[texIdx],
+                                             bounds,
+                                             kernelSize,
+                                             kernel.get(),
+                                             gain,
+                                             bias,
+                                             kernelOffset,
+                                             tileMode,
+                                             convolveAlpha);
+}
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.h b/src/gpu/effects/GrMatrixConvolutionEffect.h
new file mode 100644
index 0000000..4cc4296
--- /dev/null
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrMatrixConvolutionEffect_DEFINED
+#define GrMatrixConvolutionEffect_DEFINED
+
+#include "GrSingleTextureEffect.h"
+#include "GrTextureDomain.h"
+
+// A little bit less than the minimum # uniforms required by DX9SM2 (32).
+// Allows for a 5x5 kernel (or 25x1, for that matter).
+#define MAX_KERNEL_SIZE 25
+
+class GrGLMatrixConvolutionEffect;
+
+class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
+public:
+    static GrFragmentProcessor* Create(GrTexture* texture,
+                                       const SkIRect& bounds,
+                                       const SkISize& kernelSize,
+                                       const SkScalar* kernel,
+                                       SkScalar gain,
+                                       SkScalar bias,
+                                       const SkIPoint& kernelOffset,
+                                       GrTextureDomain::Mode tileMode,
+                                       bool convolveAlpha) {
+        return SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
+                                                      bounds,
+                                                      kernelSize,
+                                                      kernel,
+                                                      gain,
+                                                      bias,
+                                                      kernelOffset,
+                                                      tileMode,
+                                                      convolveAlpha));
+    }
+
+    static GrFragmentProcessor* CreateGaussian(GrTexture* texture,
+                                               const SkIRect& bounds,
+                                               const SkISize& kernelSize,
+                                               SkScalar gain,
+                                               SkScalar bias,
+                                               const SkIPoint& kernelOffset,
+                                               GrTextureDomain::Mode tileMode,
+                                               bool convolveAlpha,
+                                               SkScalar sigmaX,
+                                               SkScalar sigmaY);
+
+    virtual ~GrMatrixConvolutionEffect();
+
+    virtual void getConstantColorComponents(GrColor* color,
+                                            uint32_t* validFlags) const SK_OVERRIDE {
+        // TODO: Try to do better?
+        *validFlags = 0;
+    }
+
+    static const char* Name() { return "MatrixConvolution"; }
+    const SkIRect& bounds() const { return fBounds; }
+    const SkISize& kernelSize() const { return fKernelSize; }
+    const float* kernelOffset() const { return fKernelOffset; }
+    const float* kernel() const { return fKernel; }
+    float gain() const { return fGain; }
+    float bias() const { return fBias; }
+    bool convolveAlpha() const { return fConvolveAlpha; }
+    const GrTextureDomain& domain() const { return fDomain; }
+
+    typedef GrGLMatrixConvolutionEffect GLProcessor;
+
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
+
+private:
+    GrMatrixConvolutionEffect(GrTexture*,
+                              const SkIRect& bounds,
+                              const SkISize& kernelSize,
+                              const SkScalar* kernel,
+                              SkScalar gain,
+                              SkScalar bias,
+                              const SkIPoint& kernelOffset,
+                              GrTextureDomain::Mode tileMode,
+                              bool convolveAlpha);
+
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
+
+    SkIRect         fBounds;
+    SkISize         fKernelSize;
+    float           fKernel[MAX_KERNEL_SIZE];
+    float           fGain;
+    float           fBias;
+    float           fKernelOffset[2];
+    bool            fConvolveAlpha;
+    GrTextureDomain fDomain;
+
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
+
+    typedef GrSingleTextureEffect INHERITED;
+};
+
+#endif
diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp
index f2ee278..10fd8a6 100644
--- a/src/gpu/effects/GrOvalEffect.cpp
+++ b/src/gpu/effects/GrOvalEffect.cpp
@@ -5,11 +5,12 @@
  * found in the LICENSE file.
  */
 
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "GrOvalEffect.h"
 
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 
 #include "SkRect.h"
 
@@ -17,9 +18,9 @@
 
 class GLCircleEffect;
 
-class CircleEffect : public GrEffect {
+class CircleEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create(GrEffectEdgeType, const SkPoint& center, SkScalar radius);
+    static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkPoint& center, SkScalar radius);
 
     virtual ~CircleEffect() {};
     static const char* Name() { return "Circle"; }
@@ -27,158 +28,158 @@
     const SkPoint& getCenter() const { return fCenter; }
     SkScalar getRadius() const { return fRadius; }
 
-    GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
 
-    typedef GLCircleEffect GLEffect;
+    typedef GLCircleEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    CircleEffect(GrEffectEdgeType, const SkPoint& center, SkScalar radius);
+    CircleEffect(GrPrimitiveEdgeType, const SkPoint& center, SkScalar radius);
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     SkPoint             fCenter;
     SkScalar            fRadius;
-    GrEffectEdgeType    fEdgeType;
+    GrPrimitiveEdgeType    fEdgeType;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
-GrEffectRef* CircleEffect::Create(GrEffectEdgeType edgeType,
-                                  const SkPoint& center,
-                                  SkScalar radius) {
+GrFragmentProcessor* CircleEffect::Create(GrPrimitiveEdgeType edgeType, const SkPoint& center,
+                                          SkScalar radius) {
     SkASSERT(radius >= 0);
-    return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEffect,
-                                                      (edgeType, center, radius))));
+    return SkNEW_ARGS(CircleEffect, (edgeType, center, radius));
 }
 
 void CircleEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
     *validFlags = 0;
 }
 
-const GrBackendEffectFactory& CircleEffect::getFactory() const {
-    return GrTBackendEffectFactory<CircleEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& CircleEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<CircleEffect>::getInstance();
 }
 
-CircleEffect::CircleEffect(GrEffectEdgeType edgeType, const SkPoint& c, SkScalar r)
+CircleEffect::CircleEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar r)
     : fCenter(c)
     , fRadius(r)
     , fEdgeType(edgeType) {
     this->setWillReadFragmentPosition();
 }
 
-bool CircleEffect::onIsEqual(const GrEffect& other) const {
-    const CircleEffect& ce = CastEffect<CircleEffect>(other);
+bool CircleEffect::onIsEqual(const GrProcessor& other) const {
+    const CircleEffect& ce = other.cast<CircleEffect>();
     return fEdgeType == ce.fEdgeType && fCenter == ce.fCenter && fRadius == ce.fRadius;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(CircleEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleEffect);
 
-GrEffectRef* CircleEffect::TestCreate(SkRandom* random,
-                                      GrContext*,
-                                      const GrDrawTargetCaps& caps,
-                                      GrTexture*[]) {
+GrFragmentProcessor* CircleEffect::TestCreate(SkRandom* random,
+                                              GrContext*,
+                                              const GrDrawTargetCaps& caps,
+                                              GrTexture*[]) {
     SkPoint center;
     center.fX = random->nextRangeScalar(0.f, 1000.f);
     center.fY = random->nextRangeScalar(0.f, 1000.f);
     SkScalar radius = random->nextRangeF(0.f, 1000.f);
-    GrEffectEdgeType et;
+    GrPrimitiveEdgeType et;
     do {
-        et = (GrEffectEdgeType)random->nextULessThan(kGrEffectEdgeTypeCnt);
-    } while (kHairlineAA_GrEffectEdgeType == et);
+        et = (GrPrimitiveEdgeType)random->nextULessThan(kGrProcessorEdgeTypeCnt);
+    } while (kHairlineAA_GrProcessorEdgeType == et);
     return CircleEffect::Create(et, center, radius);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GLCircleEffect : public GrGLEffect {
+class GLCircleEffect : public GrGLFragmentProcessor {
 public:
-    GLCircleEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GLCircleEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor& fp,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
-    GrGLUniformManager::UniformHandle   fCircleUniform;
-    SkPoint                             fPrevCenter;
-    SkScalar                            fPrevRadius;
+    GrGLProgramDataManager::UniformHandle fCircleUniform;
+    SkPoint                               fPrevCenter;
+    SkScalar                              fPrevRadius;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GLCircleEffect::GLCircleEffect(const GrBackendEffectFactory& factory,
-                               const GrDrawEffect& drawEffect)
+GLCircleEffect::GLCircleEffect(const GrBackendProcessorFactory& factory,
+                               const GrProcessor&)
     : INHERITED (factory) {
     fPrevRadius = -1.f;
 }
 
-void GLCircleEffect::emitCode(GrGLShaderBuilder* builder,
-                              const GrDrawEffect& drawEffect,
-                              EffectKey key,
+void GLCircleEffect::emitCode(GrGLProgramBuilder* builder,
+                              const GrFragmentProcessor& fp,
+                              const GrProcessorKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
                               const TextureSamplerArray& samplers) {
-    const CircleEffect& ce = drawEffect.castEffect<CircleEffect>();
+    const CircleEffect& ce = fp.cast<CircleEffect>();
     const char *circleName;
     // The circle uniform is (center.x, center.y, radius + 0.5) for regular fills and
     // (... ,radius - 0.5) for inverse fills.
-    fCircleUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fCircleUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                          kVec3f_GrSLType,
                                          "circle",
                                          &circleName);
-    const char* fragmentPos = builder->fragmentPosition();
 
-    SkASSERT(kHairlineAA_GrEffectEdgeType != ce.getEdgeType());
-    if (GrEffectEdgeTypeIsInverseFill(ce.getEdgeType())) {
-        builder->fsCodeAppendf("\t\tfloat d = length(%s.xy - %s.xy) - %s.z;\n",
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    const char* fragmentPos = fsBuilder->fragmentPosition();
+
+    SkASSERT(kHairlineAA_GrProcessorEdgeType != ce.getEdgeType());
+    if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) {
+        fsBuilder->codeAppendf("\t\tfloat d = length(%s.xy - %s.xy) - %s.z;\n",
                                 circleName, fragmentPos, circleName);
     } else {
-        builder->fsCodeAppendf("\t\tfloat d = %s.z - length(%s.xy - %s.xy);\n",
+        fsBuilder->codeAppendf("\t\tfloat d = %s.z - length(%s.xy - %s.xy);\n",
                                circleName, fragmentPos, circleName);
     }
-    if (GrEffectEdgeTypeIsAA(ce.getEdgeType())) {
-        builder->fsCodeAppend("\t\td = clamp(d, 0.0, 1.0);\n");
+    if (GrProcessorEdgeTypeIsAA(ce.getEdgeType())) {
+        fsBuilder->codeAppend("\t\td = clamp(d, 0.0, 1.0);\n");
     } else {
-        builder->fsCodeAppend("\t\td = d > 0.5 ? 1.0 : 0.0;\n");
+        fsBuilder->codeAppend("\t\td = d > 0.5 ? 1.0 : 0.0;\n");
     }
 
-    builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("d")).c_str());
 }
 
-GrGLEffect::EffectKey GLCircleEffect::GenKey(const GrDrawEffect& drawEffect,
-                                             const GrGLCaps&) {
-    const CircleEffect& ce = drawEffect.castEffect<CircleEffect>();
-    return ce.getEdgeType();
+void GLCircleEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                            GrProcessorKeyBuilder* b) {
+    const CircleEffect& ce = processor.cast<CircleEffect>();
+    b->add32(ce.getEdgeType());
 }
 
-void GLCircleEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
-    const CircleEffect& ce = drawEffect.castEffect<CircleEffect>();
+void GLCircleEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
+    const CircleEffect& ce = processor.cast<CircleEffect>();
     if (ce.getRadius() != fPrevRadius || ce.getCenter() != fPrevCenter) {
         SkScalar radius = ce.getRadius();
-        if (GrEffectEdgeTypeIsInverseFill(ce.getEdgeType())) {
+        if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) {
             radius -= 0.5f;
         } else {
             radius += 0.5f;
         }
-        uman.set3f(fCircleUniform, ce.getCenter().fX, ce.getCenter().fY, radius);
+        pdman.set3f(fCircleUniform, ce.getCenter().fX, ce.getCenter().fY, radius);
         fPrevCenter = ce.getCenter();
         fPrevRadius = ce.getRadius();
     }
@@ -188,9 +189,10 @@
 
 class GLEllipseEffect;
 
-class EllipseEffect : public GrEffect {
+class EllipseEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create(GrEffectEdgeType, const SkPoint& center, SkScalar rx, SkScalar ry);
+    static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkPoint& center, SkScalar rx,
+                                       SkScalar ry);
 
     virtual ~EllipseEffect() {};
     static const char* Name() { return "Ellipse"; }
@@ -198,169 +200,170 @@
     const SkPoint& getCenter() const { return fCenter; }
     SkVector getRadii() const { return fRadii; }
 
-    GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
 
-    typedef GLEllipseEffect GLEffect;
+    typedef GLEllipseEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    EllipseEffect(GrEffectEdgeType, const SkPoint& center, SkScalar rx, SkScalar ry);
+    EllipseEffect(GrPrimitiveEdgeType, const SkPoint& center, SkScalar rx, SkScalar ry);
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
     SkPoint             fCenter;
     SkVector            fRadii;
-    GrEffectEdgeType    fEdgeType;
+    GrPrimitiveEdgeType    fEdgeType;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
-GrEffectRef* EllipseEffect::Create(GrEffectEdgeType edgeType,
-                                   const SkPoint& center,
-                                   SkScalar rx,
-                                   SkScalar ry) {
+GrFragmentProcessor* EllipseEffect::Create(GrPrimitiveEdgeType edgeType,
+                                           const SkPoint& center,
+                                           SkScalar rx,
+                                           SkScalar ry) {
     SkASSERT(rx >= 0 && ry >= 0);
-    return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEffect,
-                                                      (edgeType, center, rx, ry))));
+    return SkNEW_ARGS(EllipseEffect, (edgeType, center, rx, ry));
 }
 
 void EllipseEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
     *validFlags = 0;
 }
 
-const GrBackendEffectFactory& EllipseEffect::getFactory() const {
-    return GrTBackendEffectFactory<EllipseEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& EllipseEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<EllipseEffect>::getInstance();
 }
 
-EllipseEffect::EllipseEffect(GrEffectEdgeType edgeType, const SkPoint& c, SkScalar rx, SkScalar ry)
+EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx, SkScalar ry)
     : fCenter(c)
     , fRadii(SkVector::Make(rx, ry))
     , fEdgeType(edgeType) {
     this->setWillReadFragmentPosition();
 }
 
-bool EllipseEffect::onIsEqual(const GrEffect& other) const {
-    const EllipseEffect& ee = CastEffect<EllipseEffect>(other);
+bool EllipseEffect::onIsEqual(const GrProcessor& other) const {
+    const EllipseEffect& ee = other.cast<EllipseEffect>();
     return fEdgeType == ee.fEdgeType && fCenter == ee.fCenter && fRadii == ee.fRadii;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(EllipseEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(EllipseEffect);
 
-GrEffectRef* EllipseEffect::TestCreate(SkRandom* random,
-                                       GrContext*,
-                                       const GrDrawTargetCaps& caps,
-                                       GrTexture*[]) {
+GrFragmentProcessor* EllipseEffect::TestCreate(SkRandom* random,
+                                               GrContext*,
+                                               const GrDrawTargetCaps& caps,
+                                               GrTexture*[]) {
     SkPoint center;
     center.fX = random->nextRangeScalar(0.f, 1000.f);
     center.fY = random->nextRangeScalar(0.f, 1000.f);
     SkScalar rx = random->nextRangeF(0.f, 1000.f);
     SkScalar ry = random->nextRangeF(0.f, 1000.f);
-    GrEffectEdgeType et;
+    GrPrimitiveEdgeType et;
     do {
-        et = (GrEffectEdgeType)random->nextULessThan(kGrEffectEdgeTypeCnt);
-    } while (kHairlineAA_GrEffectEdgeType == et);
+        et = (GrPrimitiveEdgeType)random->nextULessThan(kGrProcessorEdgeTypeCnt);
+    } while (kHairlineAA_GrProcessorEdgeType == et);
     return EllipseEffect::Create(et, center, rx, ry);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GLEllipseEffect : public GrGLEffect {
+class GLEllipseEffect : public GrGLFragmentProcessor {
 public:
-    GLEllipseEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GLEllipseEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor& fp,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
-    GrGLUniformManager::UniformHandle   fEllipseUniform;
-    SkPoint                             fPrevCenter;
-    SkVector                            fPrevRadii;
+    GrGLProgramDataManager::UniformHandle fEllipseUniform;
+    SkPoint                               fPrevCenter;
+    SkVector                              fPrevRadii;
 
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GLEllipseEffect::GLEllipseEffect(const GrBackendEffectFactory& factory,
-                                 const GrDrawEffect& drawEffect)
+GLEllipseEffect::GLEllipseEffect(const GrBackendProcessorFactory& factory,
+                                 const GrProcessor& effect)
     : INHERITED (factory) {
     fPrevRadii.fX = -1.f;
 }
 
-void GLEllipseEffect::emitCode(GrGLShaderBuilder* builder,
-                               const GrDrawEffect& drawEffect,
-                               EffectKey key,
+void GLEllipseEffect::emitCode(GrGLProgramBuilder* builder,
+                               const GrFragmentProcessor& fp,
+                               const GrProcessorKey& key,
                                const char* outputColor,
                                const char* inputColor,
                                const TransformedCoordsArray&,
                                const TextureSamplerArray& samplers) {
-    const EllipseEffect& ee = drawEffect.castEffect<EllipseEffect>();
+    const EllipseEffect& ee = fp.cast<EllipseEffect>();
     const char *ellipseName;
     // The ellipse uniform is (center.x, center.y, 1 / rx^2, 1 / ry^2)
-    fEllipseUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fEllipseUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                          kVec4f_GrSLType,
                                          "ellipse",
                                          &ellipseName);
-    const char* fragmentPos = builder->fragmentPosition();
+
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    const char* fragmentPos = fsBuilder->fragmentPosition();
 
     // d is the offset to the ellipse center
-    builder->fsCodeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipseName);
-    builder->fsCodeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName);
+    fsBuilder->codeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipseName);
+    fsBuilder->codeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName);
     // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
-    builder->fsCodeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n");
+    fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n");
     // grad_dot is the squared length of the gradient of the implicit.
-    builder->fsCodeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
+    fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
     // avoid calling inversesqrt on zero.
-    builder->fsCodeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
-    builder->fsCodeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
+    fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
+    fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
 
     switch (ee.getEdgeType()) {
-        case kFillAA_GrEffectEdgeType:
-            builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
+        case kFillAA_GrProcessorEdgeType:
+            fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
             break;
-        case kInverseFillAA_GrEffectEdgeType:
-            builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
+        case kInverseFillAA_GrProcessorEdgeType:
+            fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
             break;
-        case kFillBW_GrEffectEdgeType:
-            builder->fsCodeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1.0;\n");
+        case kFillBW_GrProcessorEdgeType:
+            fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1.0;\n");
             break;
-        case kInverseFillBW_GrEffectEdgeType:
-            builder->fsCodeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n");
+        case kInverseFillBW_GrProcessorEdgeType:
+            fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n");
             break;
-        case kHairlineAA_GrEffectEdgeType:
+        case kHairlineAA_GrProcessorEdgeType:
             SkFAIL("Hairline not expected here.");
     }
 
-    builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-GrGLEffect::EffectKey GLEllipseEffect::GenKey(const GrDrawEffect& drawEffect,
-                                              const GrGLCaps&) {
-    const EllipseEffect& ee = drawEffect.castEffect<EllipseEffect>();
-    return ee.getEdgeType();
+void GLEllipseEffect::GenKey(const GrProcessor& effect, const GrGLCaps&,
+                             GrProcessorKeyBuilder* b) {
+    const EllipseEffect& ee = effect.cast<EllipseEffect>();
+    b->add32(ee.getEdgeType());
 }
 
-void GLEllipseEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
-    const EllipseEffect& ee = drawEffect.castEffect<EllipseEffect>();
+void GLEllipseEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
+    const EllipseEffect& ee = effect.cast<EllipseEffect>();
     if (ee.getRadii() != fPrevRadii || ee.getCenter() != fPrevCenter) {
         SkScalar invRXSqd = 1.f / (ee.getRadii().fX * ee.getRadii().fX);
         SkScalar invRYSqd = 1.f / (ee.getRadii().fY * ee.getRadii().fY);
-        uman.set4f(fEllipseUniform, ee.getCenter().fX, ee.getCenter().fY, invRXSqd, invRYSqd);
+        pdman.set4f(fEllipseUniform, ee.getCenter().fX, ee.getCenter().fY, invRXSqd, invRYSqd);
         fPrevCenter = ee.getCenter();
         fPrevRadii = ee.getRadii();
     }
@@ -368,8 +371,8 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-GrEffectRef* GrOvalEffect::Create(GrEffectEdgeType edgeType, const SkRect& oval) {
-    if (kHairlineAA_GrEffectEdgeType == edgeType) {
+GrFragmentProcessor* GrOvalEffect::Create(GrPrimitiveEdgeType edgeType, const SkRect& oval) {
+    if (kHairlineAA_GrProcessorEdgeType == edgeType) {
         return NULL;
     }
     SkScalar w = oval.width();
diff --git a/src/gpu/effects/GrOvalEffect.h b/src/gpu/effects/GrOvalEffect.h
index 796ee5b..41e22cc 100644
--- a/src/gpu/effects/GrOvalEffect.h
+++ b/src/gpu/effects/GrOvalEffect.h
@@ -11,14 +11,14 @@
 #include "GrTypes.h"
 #include "GrTypesPriv.h"
 
-class GrEffectRef;
+class GrProcessor;
 struct SkRect;
 
 namespace GrOvalEffect {
     /**
      * Creates an effect that performs clipping against an oval.
      */
-    GrEffectRef* Create(GrEffectEdgeType, const SkRect&);
+    GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkRect&);
 };
 
 #endif
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 11d8a18..f5131fe 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -5,13 +5,14 @@
  * found in the LICENSE file.
  */
 
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "GrRRectEffect.h"
 
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
 #include "GrConvexPolyEffect.h"
 #include "GrOvalEffect.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 
 #include "SkRRect.h"
 
@@ -22,7 +23,7 @@
 
 class GLCircularRRectEffect;
 
-class CircularRRectEffect : public GrEffect {
+class CircularRRectEffect : public GrFragmentProcessor {
 public:
 
     enum CornerFlags {
@@ -44,7 +45,8 @@
 
     // The flags are used to indicate which corners are circluar (unflagged corners are assumed to
     // be square).
-    static GrEffectRef* Create(GrEffectEdgeType, uint32_t circularCornerFlags, const SkRRect&);
+    static GrFragmentProcessor* Create(GrPrimitiveEdgeType, uint32_t circularCornerFlags,
+                                       const SkRRect&);
 
     virtual ~CircularRRectEffect() {};
     static const char* Name() { return "CircularRRect"; }
@@ -53,135 +55,137 @@
 
     uint32_t getCircularCornerFlags() const { return fCircularCornerFlags; }
 
-    GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
 
-    typedef GLCircularRRectEffect GLEffect;
+    typedef GLCircularRRectEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    CircularRRectEffect(GrEffectEdgeType, uint32_t circularCornerFlags, const SkRRect&);
+    CircularRRectEffect(GrPrimitiveEdgeType, uint32_t circularCornerFlags, const SkRRect&);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
-    SkRRect             fRRect;
-    GrEffectEdgeType    fEdgeType;
-    uint32_t            fCircularCornerFlags;
+    SkRRect                fRRect;
+    GrPrimitiveEdgeType    fEdgeType;
+    uint32_t               fCircularCornerFlags;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
-GrEffectRef* CircularRRectEffect::Create(GrEffectEdgeType edgeType,
-                                 uint32_t circularCornerFlags,
-                                 const SkRRect& rrect) {
-    if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType != edgeType) {
+GrFragmentProcessor* CircularRRectEffect::Create(GrPrimitiveEdgeType edgeType,
+                                                 uint32_t circularCornerFlags,
+                                                 const SkRRect& rrect) {
+    if (kFillAA_GrProcessorEdgeType != edgeType && kInverseFillAA_GrProcessorEdgeType != edgeType) {
         return NULL;
     }
-    return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircularRRectEffect,
-                                                      (edgeType, circularCornerFlags, rrect))));
+    return SkNEW_ARGS(CircularRRectEffect, (edgeType, circularCornerFlags, rrect));
 }
 
 void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
     *validFlags = 0;
 }
 
-const GrBackendEffectFactory& CircularRRectEffect::getFactory() const {
-    return GrTBackendEffectFactory<CircularRRectEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& CircularRRectEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<CircularRRectEffect>::getInstance();
 }
 
-CircularRRectEffect::CircularRRectEffect(GrEffectEdgeType edgeType, uint32_t circularCornerFlags,
-                         const SkRRect& rrect)
+CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t circularCornerFlags,
+                                         const SkRRect& rrect)
     : fRRect(rrect)
     , fEdgeType(edgeType)
     , fCircularCornerFlags(circularCornerFlags) {
     this->setWillReadFragmentPosition();
 }
 
-bool CircularRRectEffect::onIsEqual(const GrEffect& other) const {
-    const CircularRRectEffect& crre = CastEffect<CircularRRectEffect>(other);
+bool CircularRRectEffect::onIsEqual(const GrProcessor& other) const {
+    const CircularRRectEffect& crre = other.cast<CircularRRectEffect>();
     // The corner flags are derived from fRRect, so no need to check them.
     return fEdgeType == crre.fEdgeType && fRRect == crre.fRRect;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(CircularRRectEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircularRRectEffect);
 
-GrEffectRef* CircularRRectEffect::TestCreate(SkRandom* random,
-                                     GrContext*,
-                                     const GrDrawTargetCaps& caps,
-                                     GrTexture*[]) {
+GrFragmentProcessor* CircularRRectEffect::TestCreate(SkRandom* random,
+                                                     GrContext*,
+                                                     const GrDrawTargetCaps& caps,
+                                                     GrTexture*[]) {
     SkScalar w = random->nextRangeScalar(20.f, 1000.f);
     SkScalar h = random->nextRangeScalar(20.f, 1000.f);
     SkScalar r = random->nextRangeF(kRadiusMin, 9.f);
     SkRRect rrect;
     rrect.setRectXY(SkRect::MakeWH(w, h), r, r);
-    GrEffectRef* effect;
+    GrFragmentProcessor* fp;
     do {
-        GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectEdgeTypeCnt);
-        effect = GrRRectEffect::Create(et, rrect);
-    } while (NULL == effect);
-    return effect;
+        GrPrimitiveEdgeType et =
+                (GrPrimitiveEdgeType)random->nextULessThan(kGrProcessorEdgeTypeCnt);
+        fp = GrRRectEffect::Create(et, rrect);
+    } while (NULL == fp);
+    return fp;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GLCircularRRectEffect : public GrGLEffect {
+class GLCircularRRectEffect : public GrGLFragmentProcessor {
 public:
-    GLCircularRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GLCircularRRectEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor& fp,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
-    GrGLUniformManager::UniformHandle   fInnerRectUniform;
-    GrGLUniformManager::UniformHandle   fRadiusPlusHalfUniform;
-    SkRRect                             fPrevRRect;
-    typedef GrGLEffect INHERITED;
+    GrGLProgramDataManager::UniformHandle fInnerRectUniform;
+    GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform;
+    SkRRect                               fPrevRRect;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendEffectFactory& factory,
-                             const GrDrawEffect& drawEffect)
+GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendProcessorFactory& factory,
+                                             const GrProcessor& )
     : INHERITED (factory) {
     fPrevRRect.setEmpty();
 }
 
-void GLCircularRRectEffect::emitCode(GrGLShaderBuilder* builder,
-                             const GrDrawEffect& drawEffect,
-                             EffectKey key,
+void GLCircularRRectEffect::emitCode(GrGLProgramBuilder* builder,
+                             const GrFragmentProcessor& fp,
+                             const GrProcessorKey& key,
                              const char* outputColor,
                              const char* inputColor,
                              const TransformedCoordsArray&,
                              const TextureSamplerArray& samplers) {
-    const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect>();
+    const CircularRRectEffect& crre = fp.cast<CircularRRectEffect>();
     const char *rectName;
     const char *radiusPlusHalfName;
     // The inner rect is the rrect bounds inset by the radius. Its left, top, right, and bottom
     // edges correspond to components x, y, z, and w, respectively. When a side of the rrect has
     // only rectangular corners, that side's value corresponds to the rect edge's value outset by
     // half a pixel.
-    fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                             kVec4f_GrSLType,
                                             "innerRect",
                                             &rectName);
-    fRadiusPlusHalfUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fRadiusPlusHalfUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                  kFloat_GrSLType,
                                                  "radiusPlusHalf",
                                                  &radiusPlusHalfName);
-    const char* fragmentPos = builder->fragmentPosition();
+
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    const char* fragmentPos = fsBuilder->fragmentPosition();
     // At each quarter-circle corner we compute a vector that is the offset of the fragment position
     // from the circle center. The vector is pinned in x and y to be in the quarter-plane relevant
     // to that corner. This means that points near the interior near the rrect top edge will have
@@ -199,108 +203,108 @@
     // alphas together.
     switch (crre.getCircularCornerFlags()) {
         case CircularRRectEffect::kAll_CornerFlags:
-            builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
-            builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
-            builder->fsCodeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+            fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
+            fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
+            fsBuilder->codeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
             break;
         case CircularRRectEffect::kTopLeft_CornerFlag:
-            builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n",
+            fsBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n",
                                    rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
                                     rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
                                     rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
             break;
         case CircularRRectEffect::kTopRight_CornerFlag:
-            builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);\n",
+            fsBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);\n",
                                    fragmentPos, rectName, rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
                                    fragmentPos, rectName);
-            builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
                                     rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
             break;
         case CircularRRectEffect::kBottomRight_CornerFlag:
-            builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n",
+            fsBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n",
                                    fragmentPos, rectName);
-            builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
                                    fragmentPos, rectName);
-            builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
                                    fragmentPos, rectName);
-            builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
             break;
         case CircularRRectEffect::kBottomLeft_CornerFlag:
-            builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);\n",
+            fsBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);\n",
                                    rectName, fragmentPos, fragmentPos, rectName);
-            builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
                                     rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
                                    fragmentPos, rectName);
-            builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
             break;
         case CircularRRectEffect::kLeft_CornerFlags:
-            builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos, rectName);
-            builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);\n");
-            builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+            fsBuilder->codeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos, rectName);
+            fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);\n");
+            fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
                                     rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
             break;
         case CircularRRectEffect::kTop_CornerFlags:
-            builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos, rectName);
-            builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);\n");
-            builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+            fsBuilder->codeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos, rectName);
+            fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);\n");
+            fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
                                    rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
             break;
         case CircularRRectEffect::kRight_CornerFlags:
-            builder->fsCodeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
-            builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);\n");
-            builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, fragmentPos);
+            fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
+            fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);\n");
+            fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
                                    fragmentPos, rectName);
-            builder->fsCodeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
             break;
         case CircularRRectEffect::kBottom_CornerFlags:
-            builder->fsCodeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
-            builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);\n");
-            builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, fragmentPos);
+            fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
+            fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);\n");
+            fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
                                    fragmentPos, rectName);
-            builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
+            fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
             break;
     }
 
-    if (kInverseFillAA_GrEffectEdgeType == crre.getEdgeType()) {
-        builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n");
+    if (kInverseFillAA_GrProcessorEdgeType == crre.getEdgeType()) {
+        fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
     }
 
-    builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-GrGLEffect::EffectKey GLCircularRRectEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                    const GrGLCaps&) {
-    const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect>();
-    GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8);
-    return (crre.getCircularCornerFlags() << 3) | crre.getEdgeType();
+void GLCircularRRectEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                                   GrProcessorKeyBuilder* b) {
+    const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>();
+    GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8);
+    b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType());
 }
 
-void GLCircularRRectEffect::setData(const GrGLUniformManager& uman,
-                                    const GrDrawEffect& drawEffect) {
-    const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect>();
+void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman,
+                                    const GrProcessor& processor) {
+    const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>();
     const SkRRect& rrect = crre.getRRect();
     if (rrect != fPrevRRect) {
         SkRect rect = rrect.getBounds();
@@ -371,8 +375,8 @@
             default:
                 SkFAIL("Should have been one of the above cases.");
         }
-        uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-        uman.set1f(fRadiusPlusHalfUniform, radius + 0.5f);
+        pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+        pdman.set1f(fRadiusPlusHalfUniform, radius + 0.5f);
         fPrevRRect = rrect;
     }
 }
@@ -381,9 +385,9 @@
 
 class GLEllipticalRRectEffect;
 
-class EllipticalRRectEffect : public GrEffect {
+class EllipticalRRectEffect : public GrFragmentProcessor {
 public:
-    static GrEffectRef* Create(GrEffectEdgeType, const SkRRect&);
+    static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkRRect&);
 
     virtual ~EllipticalRRectEffect() {};
     static const char* Name() { return "EllipticalRRect"; }
@@ -391,61 +395,62 @@
     const SkRRect& getRRect() const { return fRRect; }
 
 
-    GrEffectEdgeType getEdgeType() const { return fEdgeType; }
+    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
 
-    typedef GLEllipticalRRectEffect GLEffect;
+    typedef GLEllipticalRRectEffect GLProcessor;
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
-    EllipticalRRectEffect(GrEffectEdgeType, const SkRRect&);
+    EllipticalRRectEffect(GrPrimitiveEdgeType, const SkRRect&);
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE;
 
     SkRRect             fRRect;
-    GrEffectEdgeType    fEdgeType;
+    GrPrimitiveEdgeType    fEdgeType;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
-GrEffectRef* EllipticalRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect& rrect) {
-    if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType != edgeType) {
+GrFragmentProcessor*
+EllipticalRRectEffect::Create(GrPrimitiveEdgeType edgeType, const SkRRect& rrect) {
+    if (kFillAA_GrProcessorEdgeType != edgeType && kInverseFillAA_GrProcessorEdgeType != edgeType) {
         return NULL;
     }
-    return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect))));
+    return SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect));
 }
 
 void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
     *validFlags = 0;
 }
 
-const GrBackendEffectFactory& EllipticalRRectEffect::getFactory() const {
-    return GrTBackendEffectFactory<EllipticalRRectEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& EllipticalRRectEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<EllipticalRRectEffect>::getInstance();
 }
 
-EllipticalRRectEffect::EllipticalRRectEffect(GrEffectEdgeType edgeType, const SkRRect& rrect)
+EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect)
     : fRRect(rrect)
     , fEdgeType(edgeType){
     this->setWillReadFragmentPosition();
 }
 
-bool EllipticalRRectEffect::onIsEqual(const GrEffect& other) const {
-    const EllipticalRRectEffect& erre = CastEffect<EllipticalRRectEffect>(other);
+bool EllipticalRRectEffect::onIsEqual(const GrProcessor& other) const {
+    const EllipticalRRectEffect& erre = other.cast<EllipticalRRectEffect>();
     return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(EllipticalRRectEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(EllipticalRRectEffect);
 
-GrEffectRef* EllipticalRRectEffect::TestCreate(SkRandom* random,
-                                               GrContext*,
-                                               const GrDrawTargetCaps& caps,
-                                               GrTexture*[]) {
+GrFragmentProcessor* EllipticalRRectEffect::TestCreate(SkRandom* random,
+                                                       GrContext*,
+                                                       const GrDrawTargetCaps& caps,
+                                                       GrTexture*[]) {
     SkScalar w = random->nextRangeScalar(20.f, 1000.f);
     SkScalar h = random->nextRangeScalar(20.f, 1000.f);
     SkVector r[4];
@@ -472,60 +477,62 @@
         rrect.setRectXY(SkRect::MakeWH(w, h), r[SkRRect::kUpperLeft_Corner].fX,
                                               r[SkRRect::kUpperLeft_Corner].fY);
     }
-    GrEffectRef* effect;
+    GrFragmentProcessor* fp;
     do {
-        GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectEdgeTypeCnt);
-        effect = GrRRectEffect::Create(et, rrect);
-    } while (NULL == effect);
-    return effect;
+        GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)random->nextULessThan(kGrProcessorEdgeTypeCnt);
+        fp = GrRRectEffect::Create(et, rrect);
+    } while (NULL == fp);
+    return fp;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GLEllipticalRRectEffect : public GrGLEffect {
+class GLEllipticalRRectEffect : public GrGLFragmentProcessor {
 public:
-    GLEllipticalRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GLEllipticalRRectEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor& effect,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
 private:
-    GrGLUniformManager::UniformHandle   fInnerRectUniform;
-    GrGLUniformManager::UniformHandle   fInvRadiiSqdUniform;
-    SkRRect                             fPrevRRect;
-    typedef GrGLEffect INHERITED;
+    GrGLProgramDataManager::UniformHandle fInnerRectUniform;
+    GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform;
+    SkRRect                               fPrevRRect;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendEffectFactory& factory,
-                             const GrDrawEffect& drawEffect)
+GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendProcessorFactory& factory,
+                             const GrProcessor& effect)
     : INHERITED (factory) {
     fPrevRRect.setEmpty();
 }
 
-void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder,
-                                       const GrDrawEffect& drawEffect,
-                                       EffectKey key,
+void GLEllipticalRRectEffect::emitCode(GrGLProgramBuilder* builder,
+                                       const GrFragmentProcessor& effect,
+                                       const GrProcessorKey& key,
                                        const char* outputColor,
                                        const char* inputColor,
                                        const TransformedCoordsArray&,
                                        const TextureSamplerArray& samplers) {
-    const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEffect>();
+    const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>();
     const char *rectName;
     // The inner rect is the rrect bounds inset by the x/y radii
-    fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+    fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                             kVec4f_GrSLType,
                                             "innerRect",
                                             &rectName);
-    const char* fragmentPos = builder->fragmentPosition();
+
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    const char* fragmentPos = fsBuilder->fragmentPosition();
     // At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos
     // to the ellipse center. The vector is pinned in x and y to be in the quarter-plane relevant
     // to that corner. This means that points near the interior near the rrect top edge will have
@@ -537,31 +544,31 @@
     // The code below is a simplified version of the above that performs maxs on the vector
     // components before computing distances and alpha values so that only one distance computation
     // need be computed to determine the min alpha.
-    builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
-    builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
+    fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+    fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
     switch (erre.getRRect().getType()) {
         case SkRRect::kSimple_Type: {
             const char *invRadiiXYSqdName;
-            fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+            fInvRadiiSqdUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                       kVec2f_GrSLType,
                                                       "invRadiiXY",
                                                       &invRadiiXYSqdName);
-            builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
+            fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
             // Z is the x/y offsets divided by squared radii.
-            builder->fsCodeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName);
+            fsBuilder->codeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName);
             break;
         }
         case SkRRect::kNinePatch_Type: {
             const char *invRadiiLTRBSqdName;
-            fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+            fInvRadiiSqdUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                       kVec4f_GrSLType,
                                                       "invRadiiLTRB",
                                                       &invRadiiLTRBSqdName);
-            builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
+            fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
             // Z is the x/y offsets divided by squared radii. We only care about the (at most) one
             // corner where both the x and y offsets are positive, hence the maxes. (The inverse
             // squared radii will always be positive.)
-            builder->fsCodeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);\n",
+            fsBuilder->codeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);\n",
                                    invRadiiLTRBSqdName, invRadiiLTRBSqdName);
             break;
         }
@@ -569,33 +576,33 @@
             SkFAIL("RRect should always be simple or nine-patch.");
     }
     // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1.
-    builder->fsCodeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n");
+    fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n");
     // grad_dot is the squared length of the gradient of the implicit.
-    builder->fsCodeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
+    fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
     // avoid calling inversesqrt on zero.
-    builder->fsCodeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
-    builder->fsCodeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
+    fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
+    fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
 
-    if (kFillAA_GrEffectEdgeType == erre.getEdgeType()) {
-        builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
+    if (kFillAA_GrProcessorEdgeType == erre.getEdgeType()) {
+        fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
     } else {
-        builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
+        fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
     }
 
-    builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
+    fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-GrGLEffect::EffectKey GLEllipticalRRectEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                      const GrGLCaps&) {
-    const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEffect>();
-    GR_STATIC_ASSERT(kLast_GrEffectEdgeType < (1 << 3));
-    return erre.getRRect().getType() | erre.getEdgeType() << 3;
+void GLEllipticalRRectEffect::GenKey(const GrProcessor& effect, const GrGLCaps&,
+                                     GrProcessorKeyBuilder* b) {
+    const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>();
+    GR_STATIC_ASSERT(kLast_GrProcessorEdgeType < (1 << 3));
+    b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3);
 }
 
-void GLEllipticalRRectEffect::setData(const GrGLUniformManager& uman,
-                                      const GrDrawEffect& drawEffect) {
-    const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEffect>();
+void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman,
+                                      const GrProcessor& effect) {
+    const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>();
     const SkRRect& rrect = erre.getRRect();
     if (rrect != fPrevRRect) {
         SkRect rect = rrect.getBounds();
@@ -605,7 +612,7 @@
         switch (erre.getRRect().getType()) {
             case SkRRect::kSimple_Type:
                 rect.inset(r0.fX, r0.fY);
-                uman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX),
+                pdman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX),
                                                 1.f / (r0.fY * r0.fY));
                 break;
             case SkRRect::kNinePatch_Type: {
@@ -616,7 +623,7 @@
                 rect.fTop += r0.fY;
                 rect.fRight -= r1.fX;
                 rect.fBottom -= r1.fY;
-                uman.set4f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX),
+                pdman.set4f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX),
                                                 1.f / (r0.fY * r0.fY),
                                                 1.f / (r1.fX * r1.fX),
                                                 1.f / (r1.fY * r1.fY));
@@ -625,14 +632,14 @@
         default:
             SkFAIL("RRect should always be simple or nine-patch.");
         }
-        uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+        pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
         fPrevRRect = rrect;
     }
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-GrEffectRef* GrRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect& rrect) {
+GrFragmentProcessor* GrRRectEffect::Create(GrPrimitiveEdgeType edgeType, const SkRRect& rrect) {
     if (rrect.isRect()) {
         return GrConvexPolyEffect::Create(edgeType, rrect.getBounds());
     }
diff --git a/src/gpu/effects/GrRRectEffect.h b/src/gpu/effects/GrRRectEffect.h
index 45ac5f4..eaaf9a0 100644
--- a/src/gpu/effects/GrRRectEffect.h
+++ b/src/gpu/effects/GrRRectEffect.h
@@ -11,7 +11,7 @@
 #include "GrTypes.h"
 #include "GrTypesPriv.h"
 
-class GrEffectRef;
+class GrProcessor;
 class SkRRect;
 
 namespace GrRRectEffect {
@@ -19,7 +19,7 @@
      * Creates an effect that performs anti-aliased clipping against a SkRRect. It doesn't support
      * all varieties of SkRRect so the caller must check for a NULL return.
      */
-    GrEffectRef* Create(GrEffectEdgeType, const SkRRect&);
+    GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkRRect&);
 };
 
 #endif
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
index 841561b..6743ddb 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/GrSimpleTextureEffect.cpp
@@ -5,36 +5,38 @@
  * found in the LICENSE file.
  */
 
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "GrSimpleTextureEffect.h"
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLSL.h"
 #include "gl/GrGLTexture.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
 #include "GrTexture.h"
 
-class GrGLSimpleTextureEffect : public GrGLEffect {
+class GrGLSimpleTextureEffect : public GrGLFragmentProcessor {
 public:
-    GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+    GrGLSimpleTextureEffect(const GrBackendProcessorFactory& factory, const GrProcessor&)
         : INHERITED (factory) {
     }
 
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor& fp,
+                          const GrProcessorKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray& coords,
                           const TextureSamplerArray& samplers) SK_OVERRIDE {
-        builder->fsCodeAppendf("\t%s = ", outputColor);
-        builder->fsAppendTextureLookupAndModulate(inputColor,
+        GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+        fsBuilder->codeAppendf("\t%s = ", outputColor);
+        fsBuilder->appendTextureLookupAndModulate(inputColor,
                                                   samplers[0],
                                                   coords[0].c_str(),
-                                                  coords[0].type());
-        builder->fsCodeAppend(";\n");
+                                                  coords[0].getType());
+        fsBuilder->codeAppend(";\n");
     }
 
 private:
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -43,20 +45,20 @@
     this->updateConstantColorComponentsForModulation(color, validFlags);
 }
 
-const GrBackendEffectFactory& GrSimpleTextureEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrSimpleTextureEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrSimpleTextureEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrSimpleTextureEffect>::getInstance();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrSimpleTextureEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSimpleTextureEffect);
 
-GrEffectRef* GrSimpleTextureEffect::TestCreate(SkRandom* random,
-                                               GrContext*,
-                                               const GrDrawTargetCaps&,
-                                               GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
+GrFragmentProcessor* GrSimpleTextureEffect::TestCreate(SkRandom* random,
+                                                       GrContext*,
+                                                       const GrDrawTargetCaps&,
+                                                       GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                      GrProcessorUnitTest::kAlphaTextureIdx;
     static const SkShader::TileMode kTileModes[] = {
         SkShader::kClamp_TileMode,
         SkShader::kRepeat_TileMode,
@@ -75,6 +77,6 @@
     };
     GrCoordSet coordSet = kCoordSets[random->nextULessThan(SK_ARRAY_COUNT(kCoordSets))];
 
-    const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
+    const SkMatrix& matrix = GrProcessorUnitTest::TestMatrix(random);
     return GrSimpleTextureEffect::Create(textures[texIdx], matrix, coordSet);
 }
diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h
index c326ccf..dc9cf85 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.h
+++ b/src/gpu/effects/GrSimpleTextureEffect.h
@@ -23,29 +23,26 @@
 class GrSimpleTextureEffect : public GrSingleTextureEffect {
 public:
     /* unfiltered, clamp mode */
-    static GrEffectRef* Create(GrTexture* tex,
-                               const SkMatrix& matrix,
-                               GrCoordSet coordSet = kLocal_GrCoordSet) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, GrTextureParams::kNone_FilterMode, coordSet)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* tex,
+                                       const SkMatrix& matrix,
+                                       GrCoordSet coordSet = kLocal_GrCoordSet) {
+        return SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, GrTextureParams::kNone_FilterMode,
+                                                  coordSet));
     }
 
     /* clamp mode */
-    static GrEffectRef* Create(GrTexture* tex,
-                               const SkMatrix& matrix,
-                               GrTextureParams::FilterMode filterMode,
-                               GrCoordSet coordSet = kLocal_GrCoordSet) {
-        AutoEffectUnref effect(
-            SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, filterMode, coordSet)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* tex,
+                                       const SkMatrix& matrix,
+                                       GrTextureParams::FilterMode filterMode,
+                                       GrCoordSet coordSet = kLocal_GrCoordSet) {
+        return SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, filterMode, coordSet));
     }
 
-    static GrEffectRef* Create(GrTexture* tex,
-                               const SkMatrix& matrix,
-                               const GrTextureParams& p,
-                               GrCoordSet coordSet = kLocal_GrCoordSet) {
-        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p, coordSet)));
-        return CreateEffectRef(effect);
+    static GrFragmentProcessor* Create(GrTexture* tex,
+                                       const SkMatrix& matrix,
+                                       const GrTextureParams& p,
+                                       GrCoordSet coordSet = kLocal_GrCoordSet) {
+        return SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p, coordSet));
     }
 
     virtual ~GrSimpleTextureEffect() {}
@@ -54,9 +51,9 @@
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    typedef GrGLSimpleTextureEffect GLEffect;
+    typedef GrGLSimpleTextureEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
 
 private:
     GrSimpleTextureEffect(GrTexture* texture,
@@ -73,12 +70,12 @@
         : GrSingleTextureEffect(texture, matrix, params, coordSet) {
     }
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
-        const GrSimpleTextureEffect& ste = CastEffect<GrSimpleTextureEffect>(other);
+    virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE {
+        const GrSimpleTextureEffect& ste = other.cast<GrSimpleTextureEffect>();
         return this->hasSameTextureParamsMatrixAndSourceCoords(ste);
     }
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     typedef GrSingleTextureEffect INHERITED;
 };
diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h
index a8f9a6d..6349ee7 100644
--- a/src/gpu/effects/GrSingleTextureEffect.h
+++ b/src/gpu/effects/GrSingleTextureEffect.h
@@ -8,7 +8,7 @@
 #ifndef GrSingleTextureEffect_DEFINED
 #define GrSingleTextureEffect_DEFINED
 
-#include "GrEffect.h"
+#include "GrProcessor.h"
 #include "SkMatrix.h"
 #include "GrCoordTransform.h"
 
@@ -18,7 +18,7 @@
  * A base class for effects that draw a single texture with a texture matrix. This effect has no
  * backend implementations. One must be provided by the subclass.
  */
-class GrSingleTextureEffect : public GrEffect {
+class GrSingleTextureEffect : public GrFragmentProcessor {
 public:
     virtual ~GrSingleTextureEffect();
 
@@ -61,7 +61,7 @@
     GrCoordTransform fCoordTransform;
     GrTextureAccess  fTextureAccess;
 
-    typedef GrEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 #endif
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 656000b..1d3b37d 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -5,10 +5,11 @@
  * found in the LICENSE file.
  */
 
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "GrTextureDomain.h"
 #include "GrSimpleTextureEffect.h"
-#include "GrTBackendEffectFactory.h"
-#include "gl/GrGLEffect.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/GrGLProcessor.h"
 #include "SkFloatingPoint.h"
 
 
@@ -43,75 +44,99 @@
                                               const GrTextureDomain& textureDomain,
                                               const char* outColor,
                                               const SkString& inCoords,
-                                              const GrGLEffect::TextureSampler sampler,
+                                              const GrGLProcessor::TextureSampler sampler,
                                               const char* inModulateColor) {
     SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode);
     SkDEBUGCODE(fMode = textureDomain.mode();)
 
-    if (kIgnore_Mode == textureDomain.mode()) {
-        builder->fsCodeAppendf("\t%s = ", outColor);
-        builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
-                                                    inCoords.c_str());
-        builder->fsCodeAppend(";\n");
-        return;
-    }
+    GrGLProgramBuilder* program = builder->getProgramBuilder();
 
-    if (!fDomainUni.isValid()) {
+    if (textureDomain.mode() != kIgnore_Mode && !fDomainUni.isValid()) {
         const char* name;
         SkString uniName("TexDom");
         if (textureDomain.fIndex >= 0) {
             uniName.appendS32(textureDomain.fIndex);
         }
-        fDomainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                            kVec4f_GrSLType, uniName.c_str(), &name);
+        fDomainUni = program->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec4f_GrSLType,
+                uniName.c_str(), &name);
         fDomainName = name;
     }
-    if (kClamp_Mode == textureDomain.mode()) {
-        SkString clampedCoords;
-        clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)",
-                                inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str());
 
-        builder->fsCodeAppendf("\t%s = ", outColor);
-        builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, clampedCoords.c_str());
-        builder->fsCodeAppend(";\n");
-    } else {
-        SkASSERT(GrTextureDomain::kDecal_Mode == textureDomain.mode());
-        // Add a block since we're going to declare variables.
-        GrGLShaderBuilder::FSBlock block(builder);
+    switch (textureDomain.mode()) {
+        case kIgnore_Mode: {
+            builder->codeAppendf("\t%s = ", outColor);
+            builder->appendTextureLookupAndModulate(inModulateColor, sampler,
+                                                      inCoords.c_str());
+            builder->codeAppend(";\n");
+            break;
+        }
+        case kClamp_Mode: {
+            SkString clampedCoords;
+            clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)",
+                                  inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str());
 
-        const char* domain = fDomainName.c_str();
-        if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) {
-            // On the NexusS and GalaxyNexus, the other path (with the 'any'
-            // call) causes the compilation error "Calls to any function that
-            // may require a gradient calculation inside a conditional block
-            // may return undefined results". This appears to be an issue with
-            // the 'any' call since even the simple "result=black; if (any())
-            // result=white;" code fails to compile.
-            builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
-            builder->fsCodeAppend("\tvec4 inside = ");
-            builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str());
-            builder->fsCodeAppend(";\n");
+            builder->codeAppendf("\t%s = ", outColor);
+            builder->appendTextureLookupAndModulate(inModulateColor, sampler,
+                                                      clampedCoords.c_str());
+            builder->codeAppend(";\n");
+            break;
+        }
+        case kDecal_Mode: {
+            // Add a block since we're going to declare variables.
+            GrGLShaderBuilder::ShaderBlock block(builder);
 
-            builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s.x) - 1.0);\n",
-                                    inCoords.c_str(), domain, domain, domain);
-            builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s.y) - 1.0);\n",
-                                    inCoords.c_str(), domain, domain, domain);
-            builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n");
-            builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outColor);
-        } else {
-            builder->fsCodeAppend("\tbvec4 outside;\n");
-            builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCoords.c_str(),
-                                   domain);
-            builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", inCoords.c_str(),
-                                   domain);
-            builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outColor);
-            builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str());
-            builder->fsCodeAppend(";\n");
+            const char* domain = fDomainName.c_str();
+            if (kImagination_GrGLVendor == program->ctxInfo().vendor()) {
+                // On the NexusS and GalaxyNexus, the other path (with the 'any'
+                // call) causes the compilation error "Calls to any function that
+                // may require a gradient calculation inside a conditional block
+                // may return undefined results". This appears to be an issue with
+                // the 'any' call since even the simple "result=black; if (any())
+                // result=white;" code fails to compile.
+                builder->codeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
+                builder->codeAppend("\tvec4 inside = ");
+                builder->appendTextureLookupAndModulate(inModulateColor, sampler,
+                                                          inCoords.c_str());
+                builder->codeAppend(";\n");
+                builder->codeAppendf("\tfloat x = (%s).x;\n", inCoords.c_str());
+                builder->codeAppendf("\tfloat y = (%s).y;\n", inCoords.c_str());
+
+                builder->codeAppendf("\tx = abs(2.0*(x - %s.x)/(%s.z - %s.x) - 1.0);\n",
+                                       domain, domain, domain);
+                builder->codeAppendf("\ty = abs(2.0*(y - %s.y)/(%s.w - %s.y) - 1.0);\n",
+                                       domain, domain, domain);
+                builder->codeAppend("\tfloat blend = step(1.0, max(x, y));\n");
+                builder->codeAppendf("\t%s = mix(inside, outside, blend);\n", outColor);
+            } else {
+                builder->codeAppend("\tbvec4 outside;\n");
+                builder->codeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCoords.c_str(),
+                                       domain);
+                builder->codeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", inCoords.c_str(),
+                                       domain);
+                builder->codeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ",
+                                       outColor);
+                builder->appendTextureLookupAndModulate(inModulateColor, sampler,
+                                                          inCoords.c_str());
+                builder->codeAppend(";\n");
+            }
+            break;
+        }
+        case kRepeat_Mode: {
+            SkString clampedCoords;
+            clampedCoords.printf("\tmod(%s - %s.xy, %s.zw - %s.xy) + %s.xy",
+                                 inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str(),
+                                 fDomainName.c_str(), fDomainName.c_str());
+
+            builder->codeAppendf("\t%s = ", outColor);
+            builder->appendTextureLookupAndModulate(inModulateColor, sampler,
+                                                      clampedCoords.c_str());
+            builder->codeAppend(";\n");
+            break;
         }
     }
 }
 
-void GrTextureDomain::GLDomain::setData(const GrGLUniformManager& uman,
+void GrTextureDomain::GLDomain::setData(const GrGLProgramDataManager& pdman,
                                         const GrTextureDomain& textureDomain,
                                         GrSurfaceOrigin textureOrigin) {
     SkASSERT(textureDomain.mode() == fMode);
@@ -131,7 +156,7 @@
             SkTSwap(values[1], values[3]);
         }
         if (0 != memcmp(values, fPrevDomain, 4 * sizeof(GrGLfloat))) {
-            uman.set4fv(fDomainUni, 1, values);
+            pdman.set4fv(fDomainUni, 1, values);
             memcpy(fPrevDomain, values, 4 * sizeof(GrGLfloat));
         }
     }
@@ -140,82 +165,81 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-class GrGLTextureDomainEffect : public GrGLEffect {
+class GrGLTextureDomainEffect : public GrGLFragmentProcessor {
 public:
-    GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
+    GrGLTextureDomainEffect(const GrBackendProcessorFactory&, const GrProcessor&);
 
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          EffectKey,
+    virtual void emitCode(GrGLProgramBuilder*,
+                          const GrFragmentProcessor&,
+                          const GrProcessorKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
 
 private:
     GrTextureDomain::GLDomain         fGLDomain;
-    typedef GrGLEffect INHERITED;
+    typedef GrGLFragmentProcessor INHERITED;
 };
 
-GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory,
-                                                 const GrDrawEffect&)
+GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendProcessorFactory& factory,
+                                                 const GrProcessor&)
     : INHERITED(factory) {
 }
 
-void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
-                                       const GrDrawEffect& drawEffect,
-                                       EffectKey key,
+void GrGLTextureDomainEffect::emitCode(GrGLProgramBuilder* builder,
+                                       const GrFragmentProcessor& fp,
+                                       const GrProcessorKey& key,
                                        const char* outputColor,
                                        const char* inputColor,
                                        const TransformedCoordsArray& coords,
                                        const TextureSamplerArray& samplers) {
-    const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainEffect>();
-    const GrTextureDomain& domain = effect.textureDomain();
+    const GrTextureDomainEffect& textureDomainEffect = fp.cast<GrTextureDomainEffect>();
+    const GrTextureDomain& domain = textureDomainEffect.textureDomain();
 
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
-    fGLDomain.sampleTexture(builder, domain, outputColor, coords2D, samplers[0], inputColor);
+    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+    SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
+    fGLDomain.sampleTexture(fsBuilder, domain, outputColor, coords2D, samplers[0], inputColor);
 }
 
-void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman,
-                                      const GrDrawEffect& drawEffect) {
-    const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainEffect>();
-    const GrTextureDomain& domain = effect.textureDomain();
-    fGLDomain.setData(uman, domain, effect.texture(0)->origin());
+void GrGLTextureDomainEffect::setData(const GrGLProgramDataManager& pdman,
+                                      const GrProcessor& processor) {
+    const GrTextureDomainEffect& textureDomainEffect = processor.cast<GrTextureDomainEffect>();
+    const GrTextureDomain& domain = textureDomainEffect.textureDomain();
+    fGLDomain.setData(pdman, domain, processor.texture(0)->origin());
 }
 
-GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                      const GrGLCaps&) {
-    const GrTextureDomain& domain = drawEffect.castEffect<GrTextureDomainEffect>().textureDomain();
-    return GrTextureDomain::GLDomain::DomainKey(domain);
+void GrGLTextureDomainEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
+                                     GrProcessorKeyBuilder* b) {
+    const GrTextureDomain& domain = processor.cast<GrTextureDomainEffect>().textureDomain();
+    b->add32(GrTextureDomain::GLDomain::DomainKey(domain));
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture,
-                                           const SkMatrix& matrix,
-                                           const SkRect& domain,
-                                           GrTextureDomain::Mode mode,
-                                           GrTextureParams::FilterMode filterMode,
-                                           GrCoordSet coordSet) {
+GrFragmentProcessor* GrTextureDomainEffect::Create(GrTexture* texture,
+                                                   const SkMatrix& matrix,
+                                                   const SkRect& domain,
+                                                   GrTextureDomain::Mode mode,
+                                                   GrTextureParams::FilterMode filterMode,
+                                                   GrCoordSet coordSet) {
     static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
     if (GrTextureDomain::kIgnore_Mode == mode ||
         (GrTextureDomain::kClamp_Mode == mode && domain.contains(kFullRect))) {
         return GrSimpleTextureEffect::Create(texture, matrix, filterMode);
     } else {
 
-        AutoEffectUnref effect(SkNEW_ARGS(GrTextureDomainEffect, (texture,
-                                                                  matrix,
-                                                                  domain,
-                                                                  mode,
-                                                                  filterMode,
-                                                                  coordSet)));
-        return CreateEffectRef(effect);
-
+        return SkNEW_ARGS(GrTextureDomainEffect, (texture,
+                                                  matrix,
+                                                  domain,
+                                                  mode,
+                                                  filterMode,
+                                                  coordSet));
     }
 }
 
@@ -227,18 +251,20 @@
                                              GrCoordSet coordSet)
     : GrSingleTextureEffect(texture, matrix, filterMode, coordSet)
     , fTextureDomain(domain, mode) {
+    SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
+            filterMode == GrTextureParams::kNone_FilterMode);
 }
 
 GrTextureDomainEffect::~GrTextureDomainEffect() {
 
 }
 
-const GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance();
+const GrBackendFragmentProcessorFactory& GrTextureDomainEffect::getFactory() const {
+    return GrTBackendFragmentProcessorFactory<GrTextureDomainEffect>::getInstance();
 }
 
-bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrTextureDomainEffect& s = CastEffect<GrTextureDomainEffect>(sBase);
+bool GrTextureDomainEffect::onIsEqual(const GrProcessor& sBase) const {
+    const GrTextureDomainEffect& s = sBase.cast<GrTextureDomainEffect>();
     return this->hasSameTextureParamsMatrixAndSourceCoords(s) &&
            this->fTextureDomain == s.fTextureDomain;
 }
@@ -253,14 +279,14 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GR_DEFINE_EFFECT_TEST(GrTextureDomainEffect);
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrTextureDomainEffect);
 
-GrEffectRef* GrTextureDomainEffect::TestCreate(SkRandom* random,
-                                               GrContext*,
-                                               const GrDrawTargetCaps&,
-                                               GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
+GrFragmentProcessor* GrTextureDomainEffect::TestCreate(SkRandom* random,
+                                                       GrContext*,
+                                                       const GrDrawTargetCaps&,
+                                                       GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
+                                      GrProcessorUnitTest::kAlphaTextureIdx;
     SkRect domain;
     domain.fLeft = random->nextUScalar1();
     domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1);
@@ -268,8 +294,8 @@
     domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
     GrTextureDomain::Mode mode =
         (GrTextureDomain::Mode) random->nextULessThan(GrTextureDomain::kModeCount);
-    const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
-    bool bilerp = random->nextBool();
+    const SkMatrix& matrix = GrProcessorUnitTest::TestMatrix(random);
+    bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? random->nextBool() : false;
     GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoordSet;
     return GrTextureDomainEffect::Create(textures[texIdx],
                                          matrix,
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index b4c0b29..5751bad 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -9,8 +9,9 @@
 #define GrTextureDomainEffect_DEFINED
 
 #include "GrSingleTextureEffect.h"
-#include "gl/GrGLEffect.h"
+#include "gl/GrGLProcessor.h"
 
+class GrGLProgramBuilder;
 class GrGLShaderBuilder;
 struct SkRect;
 
@@ -23,11 +24,18 @@
 class GrTextureDomain {
 public:
     enum Mode {
-        kIgnore_Mode,  // Ignore the texture domain rectangle.
-        kClamp_Mode,   // Clamp texture coords to the domain rectangle.
-        kDecal_Mode,   // Treat the area outside the domain rectangle as fully transparent.
+        // Ignore the texture domain rectangle.
+        kIgnore_Mode,
+        // Clamp texture coords to the domain rectangle.
+        kClamp_Mode,
+        // Treat the area outside the domain rectangle as fully transparent.
+        kDecal_Mode,
+        // Wrap texture coordinates.  NOTE: filtering may not work as expected because Bilerp will
+        // read texels outside of the domain.  We could perform additional texture reads and filter
+        // in the shader, but are not currently doing this for performance reasons
+        kRepeat_Mode,
 
-        kLastMode = kDecal_Mode
+        kLastMode = kRepeat_Mode
     };
     static const int kModeCount = kLastMode + 1;
 
@@ -61,11 +69,11 @@
     }
 
     bool operator== (const GrTextureDomain& that) const {
-        return fMode == that.fMode && fDomain == that.fDomain;
+        return fMode == that.fMode && (kIgnore_Mode == fMode || fDomain == that.fDomain);
     }
 
     /**
-     * A GrGLEffect subclass that corresponds to a GrEffect subclass that uses GrTextureDomain
+     * A GrGLProcessor subclass that corresponds to a GrProcessor subclass that uses GrTextureDomain
      * should include this helper. It generates the texture domain GLSL, produces the part of the
      * effect key that reflects the texture domain code, and performs the uniform uploads necessary
      * for texture domains.
@@ -78,7 +86,8 @@
         }
 
         /**
-         * Call this from GrGLEffect::emitCode() to sample the texture W.R.T. the domain and mode.
+         * Call this from GrGLProcessor::emitCode() to sample the texture W.R.T. the domain and
+         * mode.
          *
          * @param outcolor  name of vec4 variable to hold the sampled color.
          * @param inCoords  name of vec2 variable containing the coords to be used with the domain.
@@ -90,14 +99,14 @@
                            const GrTextureDomain& textureDomain,
                            const char* outColor,
                            const SkString& inCoords,
-                           const GrGLEffect::TextureSampler sampler,
+                           const GrGLProcessor::TextureSampler sampler,
                            const char* inModulateColor = NULL);
 
         /**
-         * Call this from GrGLEffect::setData() to upload uniforms necessary for the texture domain.
-         * The rectangle is automatically adjusted to account for the texture's origin.
+         * Call this from GrGLProcessor::setData() to upload uniforms necessary for the texture
+         * domain. The rectangle is automatically adjusted to account for the texture's origin.
          */
-        void setData(const GrGLUniformManager& uman, const GrTextureDomain& textureDomain,
+        void setData(const GrGLProgramDataManager& pdman, const GrTextureDomain& textureDomain,
                      GrSurfaceOrigin textureOrigin);
 
         enum {
@@ -105,19 +114,19 @@
         };
 
         /**
-         * GrGLEffect::GenKey() must call this and include the returned value in it's computed key.
-         * The returned will be limited to the lower kDomainKeyBits bits.
+         * GrGLProcessor::GenKey() must call this and include the returned value in it's computed
+         * key. The returned will be limited to the lower kDomainKeyBits bits.
          */
-        static GrGLEffect::EffectKey DomainKey(const GrTextureDomain& domain) {
+        static uint32_t DomainKey(const GrTextureDomain& domain) {
             GR_STATIC_ASSERT(kModeCount <= 4);
             return domain.mode();
         }
 
     private:
-        SkDEBUGCODE(Mode                  fMode;)
-        GrGLUniformManager::UniformHandle fDomainUni;
-        SkString                          fDomainName;
-        GrGLfloat                         fPrevDomain[4];
+        SkDEBUGCODE(Mode                      fMode;)
+        GrGLProgramDataManager::UniformHandle fDomainUni;
+        SkString                              fDomainName;
+        GrGLfloat                             fPrevDomain[4];
     };
 
 protected:
@@ -136,20 +145,20 @@
 class GrTextureDomainEffect : public GrSingleTextureEffect {
 
 public:
-    static GrEffectRef* Create(GrTexture*,
-                               const SkMatrix&,
-                               const SkRect& domain,
-                               GrTextureDomain::Mode,
-                               GrTextureParams::FilterMode filterMode,
-                               GrCoordSet = kLocal_GrCoordSet);
+    static GrFragmentProcessor* Create(GrTexture*,
+                                       const SkMatrix&,
+                                       const SkRect& domain,
+                                       GrTextureDomain::Mode,
+                                       GrTextureParams::FilterMode filterMode,
+                                       GrCoordSet = kLocal_GrCoordSet);
 
     virtual ~GrTextureDomainEffect();
 
     static const char* Name() { return "TextureDomain"; }
 
-    typedef GrGLTextureDomainEffect GLEffect;
+    typedef GrGLTextureDomainEffect GLProcessor;
 
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
     const GrTextureDomain& textureDomain() const { return fTextureDomain; }
@@ -165,9 +174,9 @@
                           GrTextureParams::FilterMode,
                           GrCoordSet);
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
 
-    GR_DECLARE_EFFECT_TEST;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     typedef GrSingleTextureEffect INHERITED;
 };
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index 0aa9dc3..91df897 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -17,17 +17,17 @@
     #define VALIDATE
 #endif
 
+class GrTextureStripAtlas::Hash : public SkTDynamicHash<GrTextureStripAtlas::AtlasEntry, 
+                                                        GrTextureStripAtlas::AtlasEntry::Key> {};
+
 int32_t GrTextureStripAtlas::gCacheCount = 0;
 
-GrTHashTable<GrTextureStripAtlas::AtlasEntry,
-                GrTextureStripAtlas::AtlasHashKey, 8>*
-                            GrTextureStripAtlas::gAtlasCache = NULL;
+GrTextureStripAtlas::Hash* GrTextureStripAtlas::gAtlasCache = NULL;
 
-GrTHashTable<GrTextureStripAtlas::AtlasEntry, GrTextureStripAtlas::AtlasHashKey, 8>*
-GrTextureStripAtlas::GetCache() {
+GrTextureStripAtlas::Hash* GrTextureStripAtlas::GetCache() {
 
     if (NULL == gAtlasCache) {
-        gAtlasCache = SkNEW((GrTHashTable<AtlasEntry, AtlasHashKey, 8>));
+        gAtlasCache = SkNEW(Hash);
     }
 
     return gAtlasCache;
@@ -35,12 +35,12 @@
 
 // Remove the specified atlas from the cache
 void GrTextureStripAtlas::CleanUp(const GrContext*, void* info) {
-    SkASSERT(NULL != info);
+    SkASSERT(info);
 
     AtlasEntry* entry = static_cast<AtlasEntry*>(info);
 
     // remove the cache entry
-    GetCache()->remove(entry->fKey, entry);
+    GetCache()->remove(entry->fKey);
 
     // remove the actual entry
     SkDELETE(entry);
@@ -52,7 +52,7 @@
 }
 
 GrTextureStripAtlas* GrTextureStripAtlas::GetAtlas(const GrTextureStripAtlas::Desc& desc) {
-    AtlasHashKey key;
+    AtlasEntry::Key key;
     key.setKeyData(desc.asKey());
     AtlasEntry* entry = GetCache()->find(key);
     if (NULL == entry) {
@@ -63,7 +63,7 @@
 
         desc.fContext->addCleanUp(CleanUp, entry);
 
-        GetCache()->insert(key, entry);
+        GetCache()->add(entry);
     }
 
     return entry->fAtlas;
@@ -209,11 +209,11 @@
         this->initLRU();
         fKeyTable.rewind();
     }
-    SkASSERT(NULL != fTexture);
+    SkASSERT(fTexture);
 }
 
 void GrTextureStripAtlas::unlockTexture() {
-    SkASSERT(NULL != fTexture && 0 == fLockedRows);
+    SkASSERT(fTexture && 0 == fLockedRows);
     fTexture->unref();
     fTexture = NULL;
     fDesc.fContext->purgeCache();
@@ -246,8 +246,8 @@
 }
 
 void GrTextureStripAtlas::removeFromLRU(AtlasRow* row) {
-    SkASSERT(NULL != row);
-    if (NULL != row->fNext && NULL != row->fPrev) {
+    SkASSERT(row);
+    if (row->fNext && row->fPrev) {
         row->fPrev->fNext = row->fNext;
         row->fNext->fPrev = row->fPrev;
     } else {
@@ -342,7 +342,7 @@
     if (fLockedRows == 0) {
         SkASSERT(NULL == fTexture);
     } else {
-        SkASSERT(NULL != fTexture);
+        SkASSERT(fTexture);
     }
 }
 #endif
diff --git a/src/gpu/effects/GrTextureStripAtlas.h b/src/gpu/effects/GrTextureStripAtlas.h
index 5227cc3..58539fc 100644
--- a/src/gpu/effects/GrTextureStripAtlas.h
+++ b/src/gpu/effects/GrTextureStripAtlas.h
@@ -8,11 +8,11 @@
 #ifndef GrTextureStripAtlas_DEFINED
 #define GrTextureStripAtlas_DEFINED
 
-#include "GrBinHashKey.h"
-#include "GrTHashTable.h"
+#include "GrMurmur3HashKey.h"
 #include "SkBitmap.h"
 #include "SkGr.h"
 #include "SkTDArray.h"
+#include "SkTDynamicHash.h"
 #include "SkTypes.h"
 
 /**
@@ -135,23 +135,24 @@
     static void CleanUp(const GrContext* context, void* info);
 
     // Hash table entry for atlases
-    class AtlasEntry;
-    class AtlasHashKey : public GrBinHashKey<sizeof(GrTextureStripAtlas::Desc)> {
-    public:
-        static bool Equals(const AtlasEntry& entry, const AtlasHashKey& key);
-        static bool LessThan(const AtlasEntry& entry, const AtlasHashKey& key);
-    };
     class AtlasEntry : public ::SkNoncopyable {
     public:
+        // for SkTDynamicHash
+        class Key : public GrMurmur3HashKey<sizeof(GrTextureStripAtlas::Desc)> {};
+        static const Key& GetKey(const AtlasEntry& entry) { return entry.fKey; }
+        static uint32_t Hash(const Key& key) { return key.getHash(); }
+
+        // AtlasEntry proper
         AtlasEntry() : fAtlas(NULL) {}
         ~AtlasEntry() { SkDELETE(fAtlas); }
-        AtlasHashKey fKey;
+        Key fKey;
         GrTextureStripAtlas* fAtlas;
     };
 
-    static GrTHashTable<AtlasEntry, AtlasHashKey, 8>* gAtlasCache;
+    class Hash;
+    static Hash* gAtlasCache;
 
-    static GrTHashTable<AtlasEntry, AtlasHashKey, 8>* GetCache();
+    static Hash* GetCache();
 
     // We increment gCacheCount for each atlas
     static int32_t gCacheCount;
@@ -181,14 +182,4 @@
     SkTDArray<AtlasRow*> fKeyTable;
 };
 
-inline bool GrTextureStripAtlas::AtlasHashKey::Equals(const AtlasEntry& entry,
-                                                      const AtlasHashKey& key) {
-    return entry.fKey == key;
-}
-
-inline bool GrTextureStripAtlas::AtlasHashKey::LessThan(const AtlasEntry& entry,
-                                                        const AtlasHashKey& key) {
-    return entry.fKey < key;
-}
-
 #endif
diff --git a/src/gpu/effects/GrVertexEffect.h b/src/gpu/effects/GrVertexEffect.h
deleted file mode 100644
index 387ec7a..0000000
--- a/src/gpu/effects/GrVertexEffect.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrVertexEffect_DEFINED
-#define GrVertexEffect_DEFINED
-
-#include "GrEffect.h"
-
-/**
- * If an effect needs specialized vertex shader code, then it must inherit from this class.
- * Otherwise it won't be able to add vertex attribs, and it might be given a vertexless shader
- * program in emitCode.
- */
-class GrVertexEffect : public GrEffect {
-public:
-    GrVertexEffect() { fHasVertexCode = true; }
-
-protected:
-    /**
-     * Subclasses call this from their constructor to register vertex attributes (at most
-     * kMaxVertexAttribs). This must only be called from the constructor because GrEffects are
-     * immutable.
-     */
-    void addVertexAttrib(GrSLType type) {
-        SkASSERT(fVertexAttribTypes.count() < kMaxVertexAttribs);
-        fVertexAttribTypes.push_back(type);
-    }
-
-private:
-    typedef GrEffect INHERITED;
-};
-
-#endif
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp
new file mode 100644
index 0000000..436106c
--- /dev/null
+++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -0,0 +1,147 @@
+/*
+ * 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 "gl/builders/GrGLProgramBuilder.h"
+#include "GrYUVtoRGBEffect.h"
+
+#include "GrCoordTransform.h"
+#include "GrProcessor.h"
+#include "gl/GrGLProcessor.h"
+#include "GrTBackendProcessorFactory.h"
+
+namespace {
+
+class YUVtoRGBEffect : public GrFragmentProcessor {
+public:
+    static GrFragmentProcessor* Create(GrTexture* yTexture, GrTexture* uTexture,
+                                       GrTexture* vTexture, SkYUVColorSpace colorSpace) {
+        return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture, colorSpace));
+    }
+
+    static const char* Name() { return "YUV to RGB"; }
+
+    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendFragmentProcessorFactory<YUVtoRGBEffect>::getInstance();
+    }
+
+    virtual void getConstantColorComponents(GrColor* color,
+                                            uint32_t* validFlags) const SK_OVERRIDE {
+        // YUV is opaque
+        *color = 0xFF;
+        *validFlags = kA_GrColorComponentFlag;
+    }
+
+    SkYUVColorSpace getColorSpace() const {
+        return fColorSpace;
+    }
+
+    class GLProcessor : public GrGLFragmentProcessor {
+    public:
+        static const GrGLfloat kJPEGConversionMatrix[16];
+        static const GrGLfloat kRec601ConversionMatrix[16];
+
+        // this class always generates the same code.
+        static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
+
+        GLProcessor(const GrBackendProcessorFactory& factory,
+                    const GrProcessor&)
+        : INHERITED(factory) {
+        }
+
+        virtual void emitCode(GrGLProgramBuilder* builder,
+                              const GrFragmentProcessor&,
+                              const GrProcessorKey&,
+                              const char* outputColor,
+                              const char* inputColor,
+                              const TransformedCoordsArray& coords,
+                              const TextureSamplerArray& samplers) SK_OVERRIDE {
+            GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+
+            const char* yuvMatrix   = NULL;
+            fMatrixUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                             kMat44f_GrSLType, "YUVMatrix",
+                                             &yuvMatrix);
+            fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", outputColor);
+            fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
+            fsBuilder->codeAppend(".r,\n\t\t");
+            fsBuilder->appendTextureLookup(samplers[1], coords[0].c_str(), coords[0].getType());
+            fsBuilder->codeAppend(".r,\n\t\t");
+            fsBuilder->appendTextureLookup(samplers[2], coords[0].c_str(), coords[0].getType());
+            fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
+        }
+
+        virtual void setData(const GrGLProgramDataManager& pdman,
+                             const GrProcessor& processor) SK_OVERRIDE {
+            const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>();
+            switch (yuvEffect.getColorSpace()) {
+                case kJPEG_SkYUVColorSpace:
+                    pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix);
+                    break;
+                case kRec601_SkYUVColorSpace:
+                    pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix);
+                    break;
+            }
+        }
+
+    private:
+        GrGLProgramDataManager::UniformHandle fMatrixUni;
+
+        typedef GrGLFragmentProcessor INHERITED;
+    };
+
+private:
+    YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
+                   SkYUVColorSpace colorSpace)
+     : fCoordTransform(kLocal_GrCoordSet, GrCoordTransform::MakeDivByTextureWHMatrix(yTexture),
+                       yTexture)
+    , fYAccess(yTexture)
+    , fUAccess(uTexture)
+    , fVAccess(vTexture)
+    , fColorSpace(colorSpace) {
+        this->addCoordTransform(&fCoordTransform);
+        this->addTextureAccess(&fYAccess);
+        this->addTextureAccess(&fUAccess);
+        this->addTextureAccess(&fVAccess);
+        this->setWillNotUseInputColor();
+    }
+
+    virtual bool onIsEqual(const GrProcessor& sBase) const {
+        const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>();
+        return fYAccess.getTexture() == s.fYAccess.getTexture() &&
+               fUAccess.getTexture() == s.fUAccess.getTexture() &&
+               fVAccess.getTexture() == s.fVAccess.getTexture() &&
+               fColorSpace == s.getColorSpace();
+    }
+
+    GrCoordTransform fCoordTransform;
+    GrTextureAccess fYAccess;
+    GrTextureAccess fUAccess;
+    GrTextureAccess fVAccess;
+    SkYUVColorSpace fColorSpace;
+
+    typedef GrFragmentProcessor INHERITED;
+};
+
+const GrGLfloat YUVtoRGBEffect::GLProcessor::kJPEGConversionMatrix[16] = {
+    1.0f,  0.0f,      1.402f,  -0.701f,
+    1.0f, -0.34414f, -0.71414f, 0.529f,
+    1.0f,  1.772f,    0.0f,    -0.886f,
+    0.0f,  0.0f,      0.0f,     1.0};
+const GrGLfloat YUVtoRGBEffect::GLProcessor::kRec601ConversionMatrix[16] = {
+    1.164f,  0.0f,    1.596f, -0.87075f,
+    1.164f, -0.391f, -0.813f,  0.52925f,
+    1.164f,  2.018f,  0.0f,   -1.08175f,
+    0.0f,    0.0f,    0.0f,    1.0};
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+GrFragmentProcessor*
+GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
+                         SkYUVColorSpace colorSpace) {
+    return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, colorSpace);
+}
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.h b/src/gpu/effects/GrYUVtoRGBEffect.h
new file mode 100644
index 0000000..4c057bd
--- /dev/null
+++ b/src/gpu/effects/GrYUVtoRGBEffect.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrYUVtoRGBEffect_DEFINED
+#define GrYUVtoRGBEffect_DEFINED
+
+#include "SkImageInfo.h"
+
+class GrFragmentProcessor;
+class GrTexture;
+
+namespace GrYUVtoRGBEffect {
+    /**
+     * Creates an effect that performs color conversion from YUV to RGB
+     */
+    GrFragmentProcessor* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
+                                SkYUVColorSpace colorSpace);
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLAssembleInterface.cpp b/src/gpu/gl/GrGLAssembleInterface.cpp
index 98dabff..c5c0785 100644
--- a/src/gpu/gl/GrGLAssembleInterface.cpp
+++ b/src/gpu/gl/GrGLAssembleInterface.cpp
@@ -14,6 +14,27 @@
 #define GET_PROC_SUFFIX(F, S) functions->f ## F = (GrGL ## F ## Proc) get(ctx, "gl" #F #S)
 #define GET_PROC_LOCAL(F) GrGL ## F ## Proc F = (GrGL ## F ## Proc) get(ctx, "gl" #F)
 
+const GrGLInterface* GrGLAssembleInterface(void* ctx, GrGLGetProc get) {
+    GET_PROC_LOCAL(GetString);
+    if (NULL == GetString) {
+        return NULL;
+    }
+
+    const char* verStr = reinterpret_cast<const char*>(GetString(GR_GL_VERSION));
+    if (NULL == verStr) {
+        return NULL;
+    }
+
+    GrGLStandard standard = GrGLGetStandardInUseFromString(verStr);
+
+    if (kGLES_GrGLStandard == standard) {
+        return GrGLAssembleGLESInterface(ctx, get);
+    } else if (kGL_GrGLStandard == standard) {
+        return GrGLAssembleGLInterface(ctx, get);
+    }
+    return NULL;
+}
+
 const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
     GET_PROC_LOCAL(GetString);
     GET_PROC_LOCAL(GetStringi);
@@ -224,53 +245,29 @@
     if (extensions.has("GL_NV_path_rendering")) {
         GET_PROC_SUFFIX(PathCommands, NV);
         GET_PROC_SUFFIX(PathCoords, NV);
-        GET_PROC_SUFFIX(PathSubCommands, NV);
-        GET_PROC_SUFFIX(PathSubCoords, NV);
-        GET_PROC_SUFFIX(PathString, NV);
-        GET_PROC_SUFFIX(PathGlyphs, NV);
-        GET_PROC_SUFFIX(PathGlyphRange, NV);
-        GET_PROC_SUFFIX(WeightPaths, NV);
-        GET_PROC_SUFFIX(CopyPath, NV);
-        GET_PROC_SUFFIX(InterpolatePaths, NV);
-        GET_PROC_SUFFIX(TransformPath, NV);
-        GET_PROC_SUFFIX(PathParameteriv, NV);
         GET_PROC_SUFFIX(PathParameteri, NV);
-        GET_PROC_SUFFIX(PathParameterfv, NV);
         GET_PROC_SUFFIX(PathParameterf, NV);
-        GET_PROC_SUFFIX(PathDashArray, NV);
         GET_PROC_SUFFIX(GenPaths, NV);
         GET_PROC_SUFFIX(DeletePaths, NV);
         GET_PROC_SUFFIX(IsPath, NV);
         GET_PROC_SUFFIX(PathStencilFunc, NV);
-        GET_PROC_SUFFIX(PathStencilDepthOffset, NV);
         GET_PROC_SUFFIX(StencilFillPath, NV);
         GET_PROC_SUFFIX(StencilStrokePath, NV);
         GET_PROC_SUFFIX(StencilFillPathInstanced, NV);
         GET_PROC_SUFFIX(StencilStrokePathInstanced, NV);
-        GET_PROC_SUFFIX(PathCoverDepthFunc, NV);
-        GET_PROC_SUFFIX(PathColorGen, NV);
         GET_PROC_SUFFIX(PathTexGen, NV);
-        GET_PROC_SUFFIX(PathFogGen, NV);
         GET_PROC_SUFFIX(CoverFillPath, NV);
         GET_PROC_SUFFIX(CoverStrokePath, NV);
         GET_PROC_SUFFIX(CoverFillPathInstanced, NV);
         GET_PROC_SUFFIX(CoverStrokePathInstanced, NV);
-        GET_PROC_SUFFIX(GetPathParameteriv, NV);
-        GET_PROC_SUFFIX(GetPathParameterfv, NV);
-        GET_PROC_SUFFIX(GetPathCommands, NV);
-        GET_PROC_SUFFIX(GetPathCoords, NV);
-        GET_PROC_SUFFIX(GetPathDashArray, NV);
-        GET_PROC_SUFFIX(GetPathMetrics, NV);
-        GET_PROC_SUFFIX(GetPathMetricRange, NV);
-        GET_PROC_SUFFIX(GetPathSpacing, NV);
-        GET_PROC_SUFFIX(GetPathColorGeniv, NV);
-        GET_PROC_SUFFIX(GetPathColorGenfv, NV);
-        GET_PROC_SUFFIX(GetPathTexGeniv, NV);
-        GET_PROC_SUFFIX(GetPathTexGenfv, NV);
-        GET_PROC_SUFFIX(IsPointInFillPath, NV);
-        GET_PROC_SUFFIX(IsPointInStrokePath, NV);
-        GET_PROC_SUFFIX(GetPathLength, NV);
-        GET_PROC_SUFFIX(PointAlongPath, NV);
+        // NV_path_rendering v1.2 (These methods may not be present)
+        GET_PROC_SUFFIX(StencilThenCoverFillPath, NV);
+        GET_PROC_SUFFIX(StencilThenCoverStrokePath, NV);
+        GET_PROC_SUFFIX(StencilThenCoverFillPathInstanced, NV);
+        GET_PROC_SUFFIX(StencilThenCoverStrokePathInstanced, NV);
+        // NV_path_rendering v1.3 (These methods may not be present)
+        GET_PROC_SUFFIX(ProgramPathFragmentInputGen, NV);
+        GET_PROC_SUFFIX(PathMemoryGlyphIndexArray, NV);
     }
 
     if (extensions.has("GL_EXT_debug_marker")) {
@@ -288,8 +285,230 @@
         GET_PROC(InvalidateTexSubImage);
     }
 
+    if (glVer >= GR_GL_VER(4,3) || extensions.has("GL_ARB_program_interface_query")) {
+        GET_PROC(GetProgramResourceLocation);
+    }
+
     interface->fStandard = kGL_GrGLStandard;
     interface->fExtensions.swap(&extensions);
 
     return interface;
 }
+
+const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get) {
+    GET_PROC_LOCAL(GetString);
+    if (NULL == GetString) {
+        return NULL;
+    }
+
+    const char* verStr = reinterpret_cast<const char*>(GetString(GR_GL_VERSION));
+    GrGLVersion version = GrGLGetVersionFromString(verStr);
+
+    if (version < GR_GL_VER(2,0)) {
+        return NULL;
+    }
+
+    GET_PROC_LOCAL(GetIntegerv);
+    GET_PROC_LOCAL(GetStringi);
+    GrGLExtensions extensions;
+    if (!extensions.init(kGLES_GrGLStandard, GetString, GetStringi, GetIntegerv)) {
+        return NULL;
+    }
+
+    GrGLInterface* interface = SkNEW(GrGLInterface);
+    GrGLInterface::Functions* functions = &interface->fFunctions;
+
+    GET_PROC(ActiveTexture);
+    GET_PROC(AttachShader);
+    GET_PROC(BindAttribLocation);
+    GET_PROC(BindBuffer);
+    GET_PROC(BindTexture);
+    GET_PROC_SUFFIX(BindVertexArray, OES);
+    GET_PROC(BlendColor);
+    GET_PROC(BlendFunc);
+    GET_PROC(BufferData);
+    GET_PROC(BufferSubData);
+    GET_PROC(Clear);
+    GET_PROC(ClearColor);
+    GET_PROC(ClearStencil);
+    GET_PROC(ColorMask);
+    GET_PROC(CompileShader);
+    GET_PROC(CompressedTexImage2D);
+    GET_PROC(CompressedTexSubImage2D);
+    GET_PROC(CopyTexSubImage2D);
+    GET_PROC(CreateProgram);
+    GET_PROC(CreateShader);
+    GET_PROC(CullFace);
+    GET_PROC(DeleteBuffers);
+    GET_PROC(DeleteProgram);
+    GET_PROC(DeleteShader);
+    GET_PROC(DeleteTextures);
+    GET_PROC_SUFFIX(DeleteVertexArrays, OES);
+    GET_PROC(DepthMask);
+    GET_PROC(Disable);
+    GET_PROC(DisableVertexAttribArray);
+    GET_PROC(DrawArrays);
+    GET_PROC(DrawElements);
+    GET_PROC(Enable);
+    GET_PROC(EnableVertexAttribArray);
+    GET_PROC(Finish);
+    GET_PROC(Flush);
+    GET_PROC(FrontFace);
+    GET_PROC(GenBuffers);
+    GET_PROC(GenerateMipmap);
+    GET_PROC(GenTextures);
+    GET_PROC_SUFFIX(GenVertexArrays, OES);
+    GET_PROC(GetBufferParameteriv);
+    GET_PROC(GetError);
+    GET_PROC(GetIntegerv);
+    GET_PROC(GetProgramInfoLog);
+    GET_PROC(GetProgramiv);
+    GET_PROC(GetShaderInfoLog);
+    GET_PROC(GetShaderiv);
+    GET_PROC(GetString);
+    GET_PROC(GetStringi);
+    GET_PROC(GetUniformLocation);
+    GET_PROC(LineWidth);
+    GET_PROC(LinkProgram);
+    GET_PROC(PixelStorei);
+    GET_PROC(ReadPixels);
+    GET_PROC(Scissor);
+    GET_PROC(ShaderSource);
+    GET_PROC(StencilFunc);
+    GET_PROC(StencilFuncSeparate);
+    GET_PROC(StencilMask);
+    GET_PROC(StencilMaskSeparate);
+    GET_PROC(StencilOp);
+    GET_PROC(StencilOpSeparate);
+    GET_PROC(TexImage2D);
+    GET_PROC(TexParameteri);
+    GET_PROC(TexParameteriv);
+    GET_PROC(TexSubImage2D);
+
+    if (version >= GR_GL_VER(3,0)) {
+        GET_PROC(TexStorage2D);
+    } else {
+        GET_PROC_SUFFIX(TexStorage2D, EXT);
+    }
+
+    GET_PROC_SUFFIX(DiscardFramebuffer, EXT);
+    GET_PROC(Uniform1f);
+    GET_PROC(Uniform1i);
+    GET_PROC(Uniform1fv);
+    GET_PROC(Uniform1iv);
+    GET_PROC(Uniform2f);
+    GET_PROC(Uniform2i);
+    GET_PROC(Uniform2fv);
+    GET_PROC(Uniform2iv);
+    GET_PROC(Uniform3f);
+    GET_PROC(Uniform3i);
+    GET_PROC(Uniform3fv);
+    GET_PROC(Uniform3iv);
+    GET_PROC(Uniform4f);
+    GET_PROC(Uniform4i);
+    GET_PROC(Uniform4fv);
+    GET_PROC(Uniform4iv);
+    GET_PROC(UniformMatrix2fv);
+    GET_PROC(UniformMatrix3fv);
+    GET_PROC(UniformMatrix4fv);
+    GET_PROC(UseProgram);
+    GET_PROC(VertexAttrib4fv);
+    GET_PROC(VertexAttribPointer);
+    GET_PROC(Viewport);
+    GET_PROC(BindFramebuffer);
+    GET_PROC(BindRenderbuffer);
+    GET_PROC(CheckFramebufferStatus);
+    GET_PROC(DeleteFramebuffers);
+    GET_PROC(DeleteRenderbuffers);
+    GET_PROC(FramebufferRenderbuffer);
+    GET_PROC(FramebufferTexture2D);
+
+    if (version >= GR_GL_VER(3,0)) {
+        GET_PROC(RenderbufferStorageMultisample);
+        GET_PROC(BlitFramebuffer);
+    }
+
+    if (extensions.has("GL_EXT_multisampled_render_to_texture")) {
+        GET_PROC_SUFFIX(FramebufferTexture2DMultisample, EXT);
+        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) get(ctx, "glRenderbufferStorageMultisampleEXT");
+    } else if (extensions.has("GL_IMG_multisampled_render_to_texture")) {
+        GET_PROC_SUFFIX(FramebufferTexture2DMultisample, IMG);
+        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) get(ctx, "glRenderbufferStorageMultisampleIMG");
+    } else if (extensions.has("GL_APPLE_framebuffer_multisample")) {
+        functions->fRenderbufferStorageMultisampleES2APPLE = (GrGLRenderbufferStorageMultisampleProc) get(ctx, "glRenderbufferStorageMultisampleAPPLE");
+        GET_PROC_SUFFIX(ResolveMultisampleFramebuffer, APPLE);
+    }
+
+    GET_PROC(GenFramebuffers);
+    GET_PROC(GenRenderbuffers);
+    GET_PROC(GetFramebufferAttachmentParameteriv);
+    GET_PROC(GetRenderbufferParameteriv);
+    GET_PROC(RenderbufferStorage);
+
+    GET_PROC_SUFFIX(MapBuffer, OES);
+    GET_PROC_SUFFIX(UnmapBuffer, OES);
+
+    if (version >= GR_GL_VER(3,0)) {
+        GET_PROC(MapBufferRange);
+        GET_PROC(FlushMappedBufferRange);
+    } else if (extensions.has("GL_EXT_map_buffer_range")) {
+        GET_PROC_SUFFIX(MapBufferRange, EXT);
+        GET_PROC_SUFFIX(FlushMappedBufferRange, EXT);
+    }
+
+    if (extensions.has("GL_EXT_debug_marker")) {
+        GET_PROC(InsertEventMarker);
+        GET_PROC(PushGroupMarker);
+        GET_PROC(PopGroupMarker);
+        // The below check is here because a device has been found that has the extension string but
+        // returns NULL from the eglGetProcAddress for the functions
+        if (NULL == functions->fInsertEventMarker ||
+            NULL == functions->fPushGroupMarker ||
+            NULL == functions->fPopGroupMarker) {
+            extensions.remove("GL_EXT_debug_marker");
+        }
+    }
+
+    GET_PROC(InvalidateFramebuffer);
+    GET_PROC(InvalidateSubFramebuffer);
+    GET_PROC(InvalidateBufferData);
+    GET_PROC(InvalidateBufferSubData);
+    GET_PROC(InvalidateTexImage);
+    GET_PROC(InvalidateTexSubImage);
+
+    if (version >= GR_GL_VER(3,1)) {
+        GET_PROC(GetProgramResourceLocation);
+    }
+
+    if (extensions.has("GL_NV_path_rendering")) {
+        GET_PROC_SUFFIX(MatrixLoadf, EXT);
+        GET_PROC_SUFFIX(MatrixLoadIdentity, EXT);
+        GET_PROC_SUFFIX(PathCommands, NV);
+        GET_PROC_SUFFIX(PathCoords, NV);
+        GET_PROC_SUFFIX(PathParameteri, NV);
+        GET_PROC_SUFFIX(PathParameterf, NV);
+        GET_PROC_SUFFIX(GenPaths, NV);
+        GET_PROC_SUFFIX(DeletePaths, NV);
+        GET_PROC_SUFFIX(IsPath, NV);
+        GET_PROC_SUFFIX(PathStencilFunc, NV);
+        GET_PROC_SUFFIX(StencilFillPath, NV);
+        GET_PROC_SUFFIX(StencilStrokePath, NV);
+        GET_PROC_SUFFIX(StencilFillPathInstanced, NV);
+        GET_PROC_SUFFIX(StencilStrokePathInstanced, NV);
+        GET_PROC_SUFFIX(CoverFillPath, NV);
+        GET_PROC_SUFFIX(CoverStrokePath, NV);
+        GET_PROC_SUFFIX(CoverFillPathInstanced, NV);
+        GET_PROC_SUFFIX(CoverStrokePathInstanced, NV);
+        GET_PROC_SUFFIX(StencilThenCoverFillPath, NV);
+        GET_PROC_SUFFIX(StencilThenCoverStrokePath, NV);
+        GET_PROC_SUFFIX(StencilThenCoverFillPathInstanced, NV);
+        GET_PROC_SUFFIX(StencilThenCoverStrokePathInstanced, NV);
+        GET_PROC_SUFFIX(ProgramPathFragmentInputGen, NV);
+        GET_PROC_SUFFIX(PathMemoryGlyphIndexArray, NV);
+    }
+
+    interface->fStandard = kGLES_GrGLStandard;
+    interface->fExtensions.swap(&extensions);
+
+    return interface;
+}
diff --git a/src/gpu/gl/GrGLAssembleInterface.h b/src/gpu/gl/GrGLAssembleInterface.h
index 36a4513..aa0fbca 100644
--- a/src/gpu/gl/GrGLAssembleInterface.h
+++ b/src/gpu/gl/GrGLAssembleInterface.h
@@ -11,8 +11,22 @@
 typedef void(*GrGLFuncPtr)();
 typedef GrGLFuncPtr (*GrGLGetProc)(void* ctx, const char name[]);
 
+
+/**
+ * Generic function for creating a GrGLInterface for an either OpenGL or GLES. It calls
+ * get() to get each function address. ctx is a generic ptr passed to and interpreted by get().
+ */
+const GrGLInterface* GrGLAssembleInterface(void* ctx, GrGLGetProc get);
+
 /**
  * Generic function for creating a GrGLInterface for an OpenGL (but not GLES) context. It calls
  * get() to get each function address. ctx is a generic ptr passed to and interpreted by get().
  */
 const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get);
+
+/**
+ * Generic function for creating a GrGLInterface for an OpenGL ES (but not Open GL) context. It
+ * calls get() to get each function address. ctx is a generic ptr passed to and interpreted by
+ * get().
+ */
+const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get);
diff --git a/src/gpu/gl/GrGLBufferImpl.cpp b/src/gpu/gl/GrGLBufferImpl.cpp
index ae578a2..8b5eda5 100644
--- a/src/gpu/gl/GrGLBufferImpl.cpp
+++ b/src/gpu/gl/GrGLBufferImpl.cpp
@@ -38,7 +38,7 @@
 void GrGLBufferImpl::release(GrGpuGL* gpu) {
     VALIDATE();
     // make sure we've not been abandoned or already released
-    if (NULL != fCPUData) {
+    if (fCPUData) {
         sk_free(fCPUData);
         fCPUData = NULL;
     } else if (fDesc.fID && !fDesc.fIsWrapped) {
@@ -157,7 +157,7 @@
 
 bool GrGLBufferImpl::isMapped() const {
     VALIDATE();
-    return NULL != fMapPtr;
+    return SkToBool(fMapPtr);
 }
 
 bool GrGLBufferImpl::updateData(GrGpuGL* gpu, const void* src, size_t srcSizeInBytes) {
@@ -218,9 +218,9 @@
 void GrGLBufferImpl::validate() const {
     SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType);
     // The following assert isn't valid when the buffer has been abandoned:
-    // SkASSERT((0 == fDesc.fID) == (NULL != fCPUData));
+    // SkASSERT((0 == fDesc.fID) == (fCPUData));
     SkASSERT(0 != fDesc.fID || !fDesc.fIsWrapped);
     SkASSERT(NULL == fCPUData || 0 == fGLSizeInBytes);
-    SkASSERT(NULL == fMapPtr || NULL != fCPUData || fGLSizeInBytes == fDesc.fSizeInBytes);
+    SkASSERT(NULL == fMapPtr || fCPUData || fGLSizeInBytes == fDesc.fSizeInBytes);
     SkASSERT(NULL == fCPUData || NULL == fMapPtr || fCPUData == fMapPtr);
 }
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index fdf6cac..dc4ef4c 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -22,7 +22,6 @@
     fStencilFormats.reset();
     fStencilVerifiedColorConfigs.reset();
     fMSFBOType = kNone_MSFBOType;
-    fFBFetchType = kNone_FBFetchType;
     fInvalidateFBType = kNone_InvalidateFBType;
     fLATCAlias = kLATC_LATCAlias;
     fMapBufferType = kNone_MapBufferType;
@@ -48,6 +47,9 @@
     fIsCoreProfile = false;
     fFullClearIsFree = false;
     fDropsTileOnZeroDivide = false;
+    fFBFetchSupport = false;
+    fFBFetchColorName = NULL;
+    fFBFetchExtensionString = NULL;
 }
 
 GrGLCaps::GrGLCaps(const GrGLCaps& caps) : GrDrawTargetCaps() {
@@ -65,7 +67,6 @@
     fMaxFragmentTextureUnits = caps.fMaxFragmentTextureUnits;
     fMaxFixedFunctionTextureCoords = caps.fMaxFixedFunctionTextureCoords;
     fMSFBOType = caps.fMSFBOType;
-    fFBFetchType = caps.fFBFetchType;
     fInvalidateFBType = caps.fInvalidateFBType;
     fMapBufferType = caps.fMapBufferType;
     fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
@@ -86,6 +87,9 @@
     fIsCoreProfile = caps.fIsCoreProfile;
     fFullClearIsFree = caps.fFullClearIsFree;
     fDropsTileOnZeroDivide = caps.fDropsTileOnZeroDivide;
+    fFBFetchSupport = caps.fFBFetchSupport;
+    fFBFetchColorName = caps.fFBFetchColorName;
+    fFBFetchExtensionString = caps.fFBFetchExtensionString;
 
     return *this;
 }
@@ -205,7 +209,9 @@
     // data for dynamic content on these GPUs. Perhaps we should read the renderer string and
     // limit this decision to specific GPU families rather than basing it on the vendor alone.
     if (!GR_GL_MUST_USE_VBO &&
-        (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor())) {
+        (kARM_GrGLVendor == ctxInfo.vendor() ||
+         kImagination_GrGLVendor == ctxInfo.vendor() ||
+         kQualcomm_GrGLVendor == ctxInfo.vendor())) {
         fUseNonVBOVertexAndIndexDynamicData = true;
     }
 
@@ -233,9 +239,19 @@
 
     if (kGLES_GrGLStandard == standard) {
         if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
-            fFBFetchType = kEXT_FBFetchType;
+            fFBFetchSupport = true;
+            fFBFetchColorName = "gl_LastFragData[0]";
+            fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
         } else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
-            fFBFetchType = kNV_FBFetchType;
+            fFBFetchSupport = true;
+            fFBFetchColorName = "gl_LastFragData[0]";
+            fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
+        } else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
+            // The arm extension also requires an additional flag which we will set onResetContext
+            // This is all temporary.
+            fFBFetchSupport = true;
+            fFBFetchColorName = "gl_LastFragColorARM";
+            fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
         }
     }
 
@@ -311,12 +327,31 @@
     // attachment, hence this min:
     fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
 
-    fPathRenderingSupport = ctxInfo.hasExtension("GL_NV_path_rendering") &&
-        ctxInfo.hasExtension("GL_EXT_direct_state_access");
+    fPathRenderingSupport = ctxInfo.hasExtension("GL_NV_path_rendering");
+
+    if (fPathRenderingSupport) {
+        if (kGL_GrGLStandard == standard) {
+            // We need one of the two possible texturing methods: using fixed function pipeline
+            // (PathTexGen, texcoords, ...)  or using the newer NVPR API additions that support
+            // setting individual fragment inputs with ProgramPathFragmentInputGen. The API
+            // additions are detected by checking the existence of the function. Eventually we may
+            // choose to remove the fixed function codepath.
+            // Set fMaxFixedFunctionTextureCoords = 0 here if you want to force
+            // ProgramPathFragmentInputGen usage on desktop.
+            fPathRenderingSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access") &&
+                (fMaxFixedFunctionTextureCoords > 0 ||
+                 ((ctxInfo.version() >= GR_GL_VER(4,3) ||
+                   ctxInfo.hasExtension("GL_ARB_program_interface_query")) &&
+                  gli->fFunctions.fProgramPathFragmentInputGen));
+        } else {
+            fPathRenderingSupport = ctxInfo.version() >= GR_GL_VER(3,1);
+        }
+    }
 
     fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
 
-    fDstReadInShaderSupport = kNone_FBFetchType != fFBFetchType;
+    // For now these two are equivalent but we could have dst read in shader via some other method
+    fDstReadInShaderSupport = fFBFetchSupport;
 
     // Disable scratch texture reuse on Mali and Adreno devices
     fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() &&
@@ -425,6 +460,10 @@
         }
     }
 
+    if (this->isConfigTexturable(kRGBA_float_GrPixelConfig)) {
+        fConfigRenderSupport[kRGBA_float_GrPixelConfig][kNo_MSAA] = true;
+    }
+
     // If we don't support MSAA then undo any places above where we set a config as renderable with
     // msaa.
     if (kNone_MSFBOType == fMSFBOType) {
@@ -479,13 +518,16 @@
     // however, it is only available on standard OpenGL after version 1.3
     bool hasCompressTex2D = (kGL_GrGLStandard != standard || version >= GR_GL_VER(1, 3));
 
+    fCompressedTexSubImageSupport =
+        hasCompressTex2D && (gli->fFunctions.fCompressedTexSubImage2D);
+
     // Check for ETC1
     bool hasETC1 = false;
 
     // First check version for support
     if (kGL_GrGLStandard == standard) {
         hasETC1 = hasCompressTex2D &&
-            (version >= GR_GL_VER(4, 3) || 
+            (version >= GR_GL_VER(4, 3) ||
              ctxInfo.hasExtension("GL_ARB_ES3_compatibility"));
     } else {
         hasETC1 = hasCompressTex2D &&
@@ -531,6 +573,32 @@
 
     fConfigTextureSupport[kLATC_GrPixelConfig] = hasLATC;
     fLATCAlias = alias;
+
+    // Check for R11_EAC ... We don't support R11_EAC on desktop, as most
+    // cards default to decompressing the textures in the driver, and is
+    // generally slower.
+    if (kGL_GrGLStandard != standard) {
+        fConfigTextureSupport[kR11_EAC_GrPixelConfig] = version >= GR_GL_VER(3, 0);
+    }
+
+    // Check for ASTC
+    fConfigTextureSupport[kASTC_12x12_GrPixelConfig] = 
+        ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") ||
+        ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") ||
+        ctxInfo.hasExtension("GL_OES_texture_compression_astc");
+
+    // Check for floating point texture support
+    // NOTE: We disallow floating point textures on ES devices if linear
+    // filtering modes are not supported.  This is for simplicity, but a more
+    // granular approach is possible.  Coincidentally, floating point textures became part of
+    // the standard in ES3.1 / OGL 3.1, hence the shorthand
+    bool hasFPTextures = version >= GR_GL_VER(3, 1);
+    if (!hasFPTextures) {
+        hasFPTextures = ctxInfo.hasExtension("GL_ARB_texture_float") ||
+                        (ctxInfo.hasExtension("OES_texture_float_linear") &&
+                         ctxInfo.hasExtension("GL_OES_texture_float"));
+    }
+    fConfigTextureSupport[kRGBA_float_GrPixelConfig] = hasFPTextures;
 }
 
 bool GrGLCaps::readPixelsSupported(const GrGLInterface* intf,
@@ -725,16 +793,6 @@
     GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
 
-    static const char* kFBFetchTypeStr[] = {
-        "None",
-        "EXT",
-        "NV",
-    };
-    GR_STATIC_ASSERT(0 == kNone_FBFetchType);
-    GR_STATIC_ASSERT(1 == kEXT_FBFetchType);
-    GR_STATIC_ASSERT(2 == kNV_FBFetchType);
-    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFBFetchTypeStr) == kLast_FBFetchType + 1);
-
     static const char* kInvalidateFBTypeStr[] = {
         "None",
         "Discard",
@@ -759,7 +817,7 @@
 
     r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
     r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
-    r.appendf("FB Fetch Type: %s\n", kFBFetchTypeStr[fFBFetchType]);
+    r.appendf("FB Fetch Support: %s\n", (fFBFetchSupport ? "YES" : "NO"));
     r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
     r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
     r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 7f722f9..887e2e9 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -68,16 +68,6 @@
         kLast_MSFBOType = kES_EXT_MsToTexture_MSFBOType
     };
 
-    enum FBFetchType {
-        kNone_FBFetchType,
-        /** GL_EXT_shader_framebuffer_fetch */
-        kEXT_FBFetchType,
-        /** GL_NV_shader_framebuffer_fetch */
-        kNV_FBFetchType,
-
-        kLast_FBFetchType = kNV_FBFetchType
-    };
-
     enum InvalidateFBType {
         kNone_InvalidateFBType,
         kDiscard_InvalidateFBType,       //<! glDiscardFramebuffer()
@@ -114,7 +104,7 @@
      * Initializes the GrGLCaps to the set of features supported in the current
      * OpenGL context accessible via ctxInfo.
      */
-    bool init(const GrGLContextInfo& ctxInfo, const GrGLInterface* interface);
+    bool init(const GrGLContextInfo& ctxInfo, const GrGLInterface* glInterface);
 
     /**
      * Call to note that a color config has been verified as a valid color
@@ -174,7 +164,16 @@
                kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
     }
 
-    FBFetchType fbFetchType() const { return fFBFetchType; }
+    /**
+     * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
+     *
+     * TODO On desktop opengl 4.2+ we can achieve something similar to this effect
+     */
+    bool fbFetchSupport() const { return fFBFetchSupport; }
+
+    const char* fbFetchColorName() const { return fFBFetchColorName; }
+
+    const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
 
     InvalidateFBType invalidateFBType() const { return fInvalidateFBType; }
 
@@ -340,7 +339,6 @@
     int fMaxFixedFunctionTextureCoords;
 
     MSFBOType           fMSFBOType;
-    FBFetchType         fFBFetchType;
     InvalidateFBType    fInvalidateFBType;
     MapBufferType       fMapBufferType;
     LATCAlias           fLATCAlias;
@@ -363,6 +361,10 @@
     bool fIsCoreProfile : 1;
     bool fFullClearIsFree : 1;
     bool fDropsTileOnZeroDivide : 1;
+    bool fFBFetchSupport : 1;
+
+    const char* fFBFetchColorName;
+    const char* fFBFetchExtensionString;
 
     typedef GrDrawTargetCaps INHERITED;
 };
diff --git a/src/gpu/gl/GrGLContext.cpp b/src/gpu/gl/GrGLContext.cpp
index 5bc5b6f..5373634 100644
--- a/src/gpu/gl/GrGLContext.cpp
+++ b/src/gpu/gl/GrGLContext.cpp
@@ -62,9 +62,7 @@
     return false;
 }
 
-bool GrGLContextInfo::isInitialized() const {
-    return NULL != fInterface.get();
-}
+bool GrGLContextInfo::isInitialized() const { return SkToBool(fInterface.get()); }
 
 void GrGLContextInfo::reset() {
     fInterface.reset(NULL);
diff --git a/src/gpu/gl/GrGLContext.h b/src/gpu/gl/GrGLContext.h
index e6c9f9e..7f46522 100644
--- a/src/gpu/gl/GrGLContext.h
+++ b/src/gpu/gl/GrGLContext.h
@@ -65,6 +65,8 @@
         return fInterface->hasExtension(ext);
     }
 
+    const GrGLExtensions& extensions() const { return fInterface->fExtensions; }
+
     /**
      * Reset the information
      */
diff --git a/src/gpu/gl/GrGLCreateNullInterface.cpp b/src/gpu/gl/GrGLCreateNullInterface.cpp
index d047e73..9cac1c6 100644
--- a/src/gpu/gl/GrGLCreateNullInterface.cpp
+++ b/src/gpu/gl/GrGLCreateNullInterface.cpp
@@ -10,19 +10,18 @@
 #include "GrGLDefines.h"
 #include "SkTDArray.h"
 #include "GrGLNoOpInterface.h"
+#include "SkTLS.h"
 
-// Functions not declared in GrGLBogusInterface.h (not common with the Debug GL interface).
-
-namespace { // added to suppress 'no previous prototype' warning
-
-class GrBufferObj {
+class BufferObj {
 public:
-    GrBufferObj(GrGLuint id) : fID(id), fDataPtr(NULL), fSize(0), fMapped(false) {
+    SK_DECLARE_INST_COUNT_ROOT(BufferObj);
+
+    BufferObj(GrGLuint id) : fID(id), fDataPtr(NULL), fSize(0), fMapped(false) {
     }
-    ~GrBufferObj() { SkDELETE_ARRAY(fDataPtr); }
+    ~BufferObj() { SkDELETE_ARRAY(fDataPtr); }
 
     void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) {
-        if (NULL != fDataPtr) {
+        if (fDataPtr) {
             SkASSERT(0 != fSize);
             SkDELETE_ARRAY(fDataPtr);
         }
@@ -45,54 +44,104 @@
     bool         fMapped;
 };
 
-// In debug builds we do asserts that ensure we agree with GL about when a buffer
-// is mapped.
-static SkTDArray<GrBufferObj*> gBuffers;  // slot 0 is reserved for head of free list
-static GrGLuint gCurrArrayBuffer;
-static GrGLuint gCurrElementArrayBuffer;
+// This class maintains a sparsely populated array of buffer pointers.
+class BufferManager {
+public:
+    SK_DECLARE_INST_COUNT_ROOT(BufferManager);
 
-static GrBufferObj* look_up(GrGLuint id) {
-    GrBufferObj* buffer = gBuffers[id];
-    SkASSERT(NULL != buffer && buffer->id() == id);
-    return buffer;
-}
+    BufferManager() : fFreeListHead(kFreeListEnd) {}
 
-static GrBufferObj* create_buffer() {
-    if (0 == gBuffers.count()) {
-        // slot zero is reserved for the head of the free list
-        *gBuffers.append() = NULL;
+    ~BufferManager() {
+        // NULL out the entries that are really free list links rather than ptrs before deleting.
+        intptr_t curr = fFreeListHead;
+        while (kFreeListEnd != curr) {
+            intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]);
+            fBuffers[SkToS32(curr)] = NULL;
+            curr = next;
+        }
+
+        fBuffers.deleteAll();
     }
 
-    GrGLuint id;
-    GrBufferObj* buffer;
-
-    if (NULL == gBuffers[0]) {
-        // no free slots - create a new one
-        id = gBuffers.count();
-        buffer = SkNEW_ARGS(GrBufferObj, (id));
-        gBuffers.append(1, &buffer);
-    } else {
-        // recycle a slot from the free list
-        id = SkTCast<GrGLuint>(gBuffers[0]);
-        gBuffers[0] = gBuffers[id];
-
-        buffer = SkNEW_ARGS(GrBufferObj, (id));
-        gBuffers[id] = buffer;
+    BufferObj* lookUp(GrGLuint id) {
+        BufferObj* buffer = fBuffers[id];
+        SkASSERT(buffer && buffer->id() == id);
+        return buffer;
     }
 
-    return buffer;
-}
+    BufferObj* create() {
+        GrGLuint id;
+        BufferObj* buffer;
 
-static void delete_buffer(GrBufferObj* buffer) {
-    SkASSERT(gBuffers.count() > 0);
+        if (kFreeListEnd == fFreeListHead) {
+            // no free slots - create a new one
+            id = fBuffers.count();
+            buffer = SkNEW_ARGS(BufferObj, (id));
+            *fBuffers.append() = buffer;
+        } else {
+            // grab the head of the free list and advance the head to the next free slot.
+            id = static_cast<GrGLuint>(fFreeListHead);
+            fFreeListHead = reinterpret_cast<intptr_t>(fBuffers[id]);
 
-    GrGLuint id = buffer->id();
-    SkDELETE(buffer);
+            buffer = SkNEW_ARGS(BufferObj, (id));
+            fBuffers[id] = buffer;
+        }
 
-    // Add this slot to the free list
-    gBuffers[id] = gBuffers[0];
-    gBuffers[0] = SkTCast<GrBufferObj*>((const void*)(intptr_t)id);
-}
+        return buffer;
+    }
+
+    void free(BufferObj* buffer) {
+        SkASSERT(fBuffers.count() > 0);
+
+        GrGLuint id = buffer->id();
+        SkDELETE(buffer);
+
+        fBuffers[id] = reinterpret_cast<BufferObj*>(fFreeListHead);
+        fFreeListHead = id;
+    }
+
+private:
+    static const intptr_t kFreeListEnd = -1;
+    // Index of the first entry of fBuffers in the free list. Free slots in fBuffers are indices to
+    // the next free slot. The last free slot has a value of kFreeListEnd.
+    intptr_t                fFreeListHead;
+    SkTDArray<BufferObj*>   fBuffers;
+};
+
+/**
+ * The global-to-thread state object for the null interface. All null interfaces on the
+ * same thread currently share one of these. This means two null contexts on the same thread
+ * can interfere with each other. It may make sense to more integrate this into SkNullGLContext
+ * and use it's makeCurrent mechanism.
+ */
+struct ThreadContext {
+public:
+    SK_DECLARE_INST_COUNT_ROOT(ThreadContext);
+
+    BufferManager   fBufferManager;
+    GrGLuint        fCurrArrayBuffer;
+    GrGLuint        fCurrElementArrayBuffer;
+    GrGLuint        fCurrProgramID;
+    GrGLuint        fCurrShaderID;
+
+    static ThreadContext* Get() {
+        return reinterpret_cast<ThreadContext*>(SkTLS::Get(Create, Delete));
+    }
+
+    ThreadContext()
+        : fCurrArrayBuffer(0)
+        , fCurrElementArrayBuffer(0)
+        , fCurrProgramID(0)
+        , fCurrShaderID(0) {}
+
+private:
+    static void* Create() { return SkNEW(ThreadContext ); }
+    static void Delete(void* context) { SkDELETE(reinterpret_cast<ThreadContext *>(context)); }
+};
+
+// Functions not declared in GrGLBogusInterface.h (not common with the Debug GL interface).
+
+namespace { // added to suppress 'no previous prototype' warning
 
 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {}
 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shader) {}
@@ -102,9 +151,9 @@
 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {}
 
 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
-
+    ThreadContext* ctx = ThreadContext::Get();
     for (int i = 0; i < n; ++i) {
-        GrBufferObj* buffer = create_buffer();
+        BufferObj* buffer = ctx->fBufferManager.create();
         ids[i] = buffer->id();
     }
 }
@@ -115,14 +164,15 @@
                                               GrGLsizeiptr size,
                                               const GrGLvoid* data,
                                               GrGLenum usage) {
+    ThreadContext* ctx = ThreadContext::Get();
     GrGLuint id = 0;
 
     switch (target) {
     case GR_GL_ARRAY_BUFFER:
-        id = gCurrArrayBuffer;
+        id = ctx->fCurrArrayBuffer;
         break;
     case GR_GL_ELEMENT_ARRAY_BUFFER:
-        id = gCurrElementArrayBuffer;
+        id = ctx->fCurrElementArrayBuffer;
         break;
     default:
         SkFAIL("Unexpected target to nullGLBufferData");
@@ -130,7 +180,7 @@
     }
 
     if (id > 0) {
-        GrBufferObj* buffer = look_up(id);
+        BufferObj* buffer = ctx->fBufferManager.lookUp(id);
         buffer->allocate(size, (const GrGLchar*) data);
     }
 }
@@ -147,13 +197,11 @@
 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
 
 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() {
-    static GrGLuint gCurrID = 0;
-    return ++gCurrID;
+    return ++ThreadContext::Get()->fCurrProgramID;
 }
 
 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) {
-    static GrGLuint gCurrID = 0;
-    return ++gCurrID;
+    return ++ThreadContext::Get()->fCurrShaderID;
 }
 
 // same delete used for shaders and programs
@@ -161,46 +209,49 @@
 }
 
 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer) {
+    ThreadContext* ctx = ThreadContext::Get();
     switch (target) {
     case GR_GL_ARRAY_BUFFER:
-        gCurrArrayBuffer = buffer;
+        ctx->fCurrArrayBuffer = buffer;
         break;
     case GR_GL_ELEMENT_ARRAY_BUFFER:
-        gCurrElementArrayBuffer = buffer;
+        ctx->fCurrElementArrayBuffer = buffer;
         break;
     }
 }
 
 // deleting a bound buffer has the side effect of binding 0
 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) {
+    ThreadContext* ctx = ThreadContext::Get();
     for (int i = 0; i < n; ++i) {
-        if (ids[i] == gCurrArrayBuffer) {
-            gCurrArrayBuffer = 0;
+        if (ids[i] == ctx->fCurrArrayBuffer) {
+            ctx->fCurrArrayBuffer = 0;
         }
-        if (ids[i] == gCurrElementArrayBuffer) {
-            gCurrElementArrayBuffer = 0;
+        if (ids[i] == ctx->fCurrElementArrayBuffer) {
+            ctx->fCurrElementArrayBuffer = 0;
         }
 
-        GrBufferObj* buffer = look_up(ids[i]);
-        delete_buffer(buffer);
+        BufferObj* buffer = ctx->fBufferManager.lookUp(ids[i]);
+        ctx->fBufferManager.free(buffer);
     }
 }
 
 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBufferRange(GrGLenum target, GrGLintptr offset,
                                                    GrGLsizeiptr length, GrGLbitfield access) {
+    ThreadContext* ctx = ThreadContext::Get();
     GrGLuint id = 0;
     switch (target) {
         case GR_GL_ARRAY_BUFFER:
-            id = gCurrArrayBuffer;
+            id = ctx->fCurrArrayBuffer;
             break;
         case GR_GL_ELEMENT_ARRAY_BUFFER:
-            id = gCurrElementArrayBuffer;
+            id = ctx->fCurrElementArrayBuffer;
             break;
     }
 
     if (id > 0) {
         // We just ignore the offset and length here.
-        GrBufferObj* buffer = look_up(id);
+        BufferObj* buffer = ctx->fBufferManager.lookUp(id);
         SkASSERT(!buffer->mapped());
         buffer->setMapped(true);
         return buffer->dataPtr();
@@ -209,18 +260,19 @@
 }
 
 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) {
+    ThreadContext* ctx = ThreadContext::Get();
     GrGLuint id = 0;
     switch (target) {
         case GR_GL_ARRAY_BUFFER:
-            id = gCurrArrayBuffer;
+            id = ctx->fCurrArrayBuffer;
             break;
         case GR_GL_ELEMENT_ARRAY_BUFFER:
-            id = gCurrElementArrayBuffer;
+            id = ctx->fCurrElementArrayBuffer;
             break;
     }
 
     if (id > 0) {
-        GrBufferObj* buffer = look_up(id);
+        BufferObj* buffer = ctx->fBufferManager.lookUp(id);
         SkASSERT(!buffer->mapped());
         buffer->setMapped(true);
         return buffer->dataPtr();
@@ -236,17 +288,18 @@
 
 
 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) {
+    ThreadContext* ctx = ThreadContext::Get();
     GrGLuint id = 0;
     switch (target) {
     case GR_GL_ARRAY_BUFFER:
-        id = gCurrArrayBuffer;
+        id = ctx->fCurrArrayBuffer;
         break;
     case GR_GL_ELEMENT_ARRAY_BUFFER:
-        id = gCurrElementArrayBuffer;
+        id = ctx->fCurrElementArrayBuffer;
         break;
     }
     if (id > 0) {
-        GrBufferObj* buffer = look_up(id);
+        BufferObj* buffer = ctx->fBufferManager.lookUp(id);
         SkASSERT(buffer->mapped());
         buffer->setMapped(false);
         return GR_GL_TRUE;
@@ -257,20 +310,21 @@
 }
 
 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {
+    ThreadContext* ctx = ThreadContext::Get();
     switch (pname) {
         case GR_GL_BUFFER_MAPPED: {
             *params = GR_GL_FALSE;
             GrGLuint id = 0;
             switch (target) {
                 case GR_GL_ARRAY_BUFFER:
-                    id = gCurrArrayBuffer;
+                    id = ctx->fCurrArrayBuffer;
                     break;
                 case GR_GL_ELEMENT_ARRAY_BUFFER:
-                    id = gCurrElementArrayBuffer;
+                    id = ctx->fCurrElementArrayBuffer;
                     break;
             }
             if (id > 0) {
-                GrBufferObj* buffer = look_up(id);
+                BufferObj* buffer = ctx->fBufferManager.lookUp(id);
                 if (buffer->mapped()) {
                     *params = GR_GL_TRUE;
                 }
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index e2ddde8..11dc601 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -731,6 +731,7 @@
 #define GR_GL_RGB5_A1                        0x8057
 #define GR_GL_RGB565                         0x8D62
 #define GR_GL_RGBA8                          0x8058
+#define GR_GL_RGBA32F                        0x8814
 #define GR_GL_RGB8                           0x8051
 #define GR_GL_BGRA8                          0x93A1
 #define GR_GL_SRGB                           0x8C40
@@ -827,19 +828,6 @@
 #define GR_GL_ARC_TO                                        0xFE
 #define GR_GL_RELATIVE_ARC_TO                               0xFF
 
-// path string formats
-#define GR_GL_PATH_FORMAT_SVG                               0x9070
-#define GR_GL_PATH_FORMAT_PS                                0x9071
-
-// font targets
-#define GR_GL_STANDARD_FONT_NAME                            0x9072
-#define GR_GL_SYSTEM_FONT_NAME                              0x9073
-#define GR_GL_FILE_NAME                                     0x9074
-
-// handle missing glyphs
-#define GR_GL_SKIP_MISSING_GLYPH                            0x90A9
-#define GR_GL_USE_MISSING_GLYPH                             0x90AA
-
 // path parameters
 #define GR_GL_PATH_STROKE_WIDTH                             0x9075
 #define GR_GL_PATH_INITIAL_END_CAP                          0x9077
@@ -870,10 +858,6 @@
 #define GR_GL_COUNT_DOWN                                    0x9089
 /*      GL_PATH_FILL_MODE_NV */
 
-// path color gen
-/*      GL_PRIMARY_COLOR */
-#define GR_GL_SECONDARY_COLOR                               0x852D
-
 // gen mode
 /*      GL_NONE */
 /*      GL_EYE_LINEAR */
@@ -897,11 +881,6 @@
 #define GR_GL_TRANSPOSE_AFFINE_2D                           0x9096
 #define GR_GL_TRANSPOSE_AFFINE_3D                           0x9098
 
-// path string types
-#define GR_GL_UTF8                                          0x909A
-#define GR_GL_UTF16                                         0x909B
-
-#define GR_GL_PATH_COMPUTED_LENGTH                          0x90A0
 
 // cap/dash values
 /*      GL_FLAT */
@@ -916,60 +895,33 @@
 #define GR_GL_MITER_REVERT                                  0x90A7
 #define GR_GL_MITER_TRUNCATE                                0x90A8
 
-// path dash reset values
-#define GR_GL_MOVE_TO_RESETS                                0x90B5
-#define GR_GL_MOVE_TO_CONTINUES                             0x90B6
+// glyph loading values
+#define GR_GL_STANDARD_FONT_NAME                            0x9072
+#define GR_GL_SYSTEM_FONT_NAME                              0x9073
+#define GR_GL_FILE_NAME                                     0x9074
+#define GR_GL_STANDARD_FONT_FORMAT                          0x936C
+#define GR_GL_SKIP_MISSING_GLYPH                            0x90A9
+#define GR_GL_USE_MISSING_GLYPH                             0x90AA
+#define GR_GL_FONT_GLYPHS_AVAILABLE                         0x9368
+#define GR_GL_FONT_TARGET_UNAVAILABLE                       0x9369
+#define GR_GL_FONT_UNAVAILABLE                              0x936A
+#define GR_GL_FONT_UNINTELLIGIBLE                           0x936B
+/*      GL_INVALID_ENUM */
+/*      GL_INVALID_VALUE */
+/*      GL_OUT_OF_MEMORY */
 
-// font styles
-/*      GL_NONE */
-#define GR_GL_BOLD_BIT                                      0x01
-#define GR_GL_ITALIC_BIT                                    0x02
+// NV_path_rendering extension to ARB_program_interface_query:
+// .. corresponds to the set of active input variables used by the fragment
+// shader stage of <program> (if a fragment stage exists).
+#define GR_GL_FRAGMENT_INPUT                                0x936D
 
-// pnames for glGet
-#define GR_GL_PATH_ERROR_POSITION                           0x90AB
-#define GR_GL_PATH_FOG_GEN_MODE                             0x90AC
-#define GR_GL_PATH_STENCIL_FUNC                             0x90B7
-#define GR_GL_PATH_STENCIL_REF                              0x90B8
-#define GR_GL_PATH_STENCIL_VALUE_MASK                       0x90B9
-#define GR_GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR              0x90BD
-#define GR_GL_PATH_STENCIL_DEPTH_OFFSET_UNITS               0x90BE
-#define GR_GL_PATH_COVER_DEPTH_FUNC                         0x90BF
+// NV_path_rendering extension to EXT_direct_state_access:
+// [the matrix functions] must support the PATH_PROJECTION_NV and
+// PATH_MODELVIEW_NV tokens for matrixMode.
+#define GR_GL_PATH_PROJECTION                               0x1701
+#define GR_GL_PATH_MODELVIEW                                0x1700
 
-// per-glyph metrics bits in metric mask query
-#define GR_GL_GLYPH_WIDTH_BIT                               0x01
-#define GR_GL_GLYPH_HEIGHT_BIT                              0x02
-#define GR_GL_GLYPH_HORIZONTAL_BEARING_X_BIT                0x04
-#define GR_GL_GLYPH_HORIZONTAL_BEARING_Y_BIT                0x08
-#define GR_GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT          0x10
-#define GR_GL_GLYPH_VERTICAL_BEARING_X_BIT                  0x20
-#define GR_GL_GLYPH_VERTICAL_BEARING_Y_BIT                  0x40
-#define GR_GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT            0x80
-#define GR_GL_GLYPH_HAS_KERNING                             0x100
-
-// per-font face metrics in metric mask query
-#define GR_GL_FONT_X_MIN_BOUNDS                             0x00010000
-#define GR_GL_FONT_Y_MIN_BOUNDS                             0x00020000
-#define GR_GL_FONT_X_MAX_BOUNDS                             0x00040000
-#define GR_GL_FONT_Y_MAX_BOUNDS                             0x00080000
-#define GR_GL_FONT_UNITS_PER_EM                             0x00100000
-#define GR_GL_FONT_ASCENDER                                 0x00200000
-#define GR_GL_FONT_DESCENDER                                0x00400000
-#define GR_GL_FONT_HEIGHT                                   0x00800000
-#define GR_GL_FONT_MAX_ADVANCE_WIDTH                        0x01000000
-#define GR_GL_FONT_MAX_ADVANCE_HEIGHT                       0x02000000
-#define GR_GL_FONT_UNDERLINE_POSITION                       0x04000000
-#define GR_GL_FONT_UNDERLINE_THICKNESS                      0x08000000
-#define GR_GL_FONT_HAS_KERNING                              0x10000000
-
-// path list modes (glGetPathSpacing)
-#define GR_GL_ACCUM_ADJACENT_PAIRS                          0x90AD
-#define GR_GL_ADJACENT_PAIRS                                0x90AE
-#define GR_GL_FIRST_TO_REST                                 0x90AF
-
-//path gen modes
-#define GR_GL_PATH_GEN_MODE                                 0x90B0
-#define GR_GL_PATH_GEN_COEFF                                0x90B1
-#define GR_GL_PATH_GEN_COLOR_FORMAT                         0x90B2
-#define GR_GL_PATH_GEN_COMPONENTS                           0x90B3
+/*  ARM specific define for MSAA support on framebuffer fetch */
+#define GR_GL_FETCH_PER_SAMPLE_ARM                          0x8F65
 
 #endif
diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h
deleted file mode 100644
index 1cc3df2..0000000
--- a/src/gpu/gl/GrGLEffect.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLEffect_DEFINED
-#define GrGLEffect_DEFINED
-
-#include "GrBackendEffectFactory.h"
-#include "GrGLProgramEffects.h"
-#include "GrGLShaderBuilder.h"
-#include "GrGLShaderVar.h"
-#include "GrGLSL.h"
-
-/** @file
-    This file contains specializations for OpenGL of the shader stages declared in
-    include/gpu/GrEffect.h. Objects of type GrGLEffect are responsible for emitting the
-    GLSL code that implements a GrEffect and for uploading uniforms at draw time. If they don't
-    always emit the same GLSL code, they must have a function:
-        static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&)
-    that is used to implement a program cache. When two GrEffects produce the same key this means
-    that their GrGLEffects would emit the same GLSL code.
-
-    The GrGLEffect subclass must also have a constructor of the form:
-        EffectSubclass::EffectSubclass(const GrBackendEffectFactory&, const GrDrawEffect&)
-    The effect held by the GrDrawEffect is guaranteed to be of the type that generated the
-    GrGLEffect subclass instance.
-
-    These objects are created by the factory object returned by the GrEffect::getFactory().
-*/
-
-class GrDrawEffect;
-class GrGLTexture;
-class GrGLVertexEffect;
-
-class GrGLEffect {
-
-public:
-    typedef GrBackendEffectFactory::EffectKey EffectKey;
-    typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
-    typedef GrGLProgramEffects::TextureSampler TextureSampler;
-    typedef GrGLProgramEffects::TextureSamplerArray TextureSamplerArray;
-
-    enum {
-        kNoEffectKey = GrBackendEffectFactory::kNoEffectKey,
-        // the number of bits in EffectKey available to GenKey
-        kEffectKeyBits = GrBackendEffectFactory::kEffectKeyBits,
-    };
-
-    GrGLEffect(const GrBackendEffectFactory& factory)
-        : fFactory(factory)
-        , fIsVertexEffect(false) {
-    }
-
-    virtual ~GrGLEffect() {}
-
-    /** Called when the program stage should insert its code into the shaders. The code in each
-        shader will be in its own block ({}) and so locally scoped names will not collide across
-        stages.
-
-        @param builder      Interface used to emit code in the shaders.
-        @param drawEffect   A wrapper on the effect that generated this program stage.
-        @param key          The key that was computed by GenKey() from the generating GrEffect.
-                            Only the bits indicated by GrBackendEffectFactory::kEffectKeyBits are
-                            guaranteed to match the value produced by GenKey();
-        @param outputColor  A predefined vec4 in the FS in which the stage should place its output
-                            color (or coverage).
-        @param inputColor   A vec4 that holds the input color to the stage in the FS. This may be
-                            NULL in which case the implied input is solid white (all ones).
-                            TODO: Better system for communicating optimization info (e.g. input
-                            color is solid white, trans black, known to be opaque, etc.) that allows
-                            the effect to communicate back similar known info about its output.
-        @param samplers     One entry for each GrTextureAccess of the GrEffect that generated the
-                            GrGLEffect. These can be passed to the builder to emit texture
-                            reads in the generated code.
-        */
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
-                          const char* outputColor,
-                          const char* inputColor,
-                          const TransformedCoordsArray& coords,
-                          const TextureSamplerArray& samplers) = 0;
-
-    /** A GrGLEffect instance can be reused with any GrEffect that produces the same stage
-        key; this function reads data from a stage and uploads any uniform variables required
-        by the shaders created in emitCode(). The GrEffect installed in the GrEffectStage is
-        guaranteed to be of the same type that created this GrGLEffect and to have an identical
-        EffectKey as the one that created this GrGLEffect. Effects that use local coords have
-        to consider whether the GrEffectStage's coord change matrix should be used. When explicit
-        local coordinates are used it can be ignored. */
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) {}
-
-    const char* name() const { return fFactory.name(); }
-
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }
-
-    /** Used by the system when generating shader code, to see if this effect can be downcasted to
-        the internal GrGLVertexEffect type */
-    bool isVertexEffect() const { return fIsVertexEffect; }
-
-protected:
-    const GrBackendEffectFactory& fFactory;
-
-private:
-    friend class GrGLVertexEffect; // to set fIsVertexEffect
-
-    bool fIsVertexEffect;
-};
-
-#endif
diff --git a/src/gpu/gl/GrGLGeometryProcessor.h b/src/gpu/gl/GrGLGeometryProcessor.h
new file mode 100644
index 0000000..b879e12
--- /dev/null
+++ b/src/gpu/gl/GrGLGeometryProcessor.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLGeometryProcessor_DEFINED
+#define GrGLGeometryProcessor_DEFINED
+
+#include "GrGLProcessor.h"
+
+/**
+ * If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit
+ * from this class. Since paths don't have vertices, this class is only meant to be used internally
+ * by skia, for special cases.
+ */
+class GrGLGeometryProcessor : public GrGLProcessor {
+public:
+    GrGLGeometryProcessor(const GrBackendProcessorFactory& factory)
+        : INHERITED(factory) {}
+
+    /**
+     * This is similar to emitCode() in the base class, except it takes a full shader builder.
+     * This allows the effect subclass to emit vertex code.
+     */
+    virtual void emitCode(GrGLFullProgramBuilder* builder,
+                          const GrGeometryProcessor& geometryProcessor,
+                          const GrProcessorKey& key,
+                          const char* outputColor,
+                          const char* inputColor,
+                          const TransformedCoordsArray& coords,
+                          const TextureSamplerArray& samplers) = 0;
+
+private:
+    typedef GrGLProcessor INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLIndexBuffer.cpp b/src/gpu/gl/GrGLIndexBuffer.cpp
index a137348..5991c09 100644
--- a/src/gpu/gl/GrGLIndexBuffer.cpp
+++ b/src/gpu/gl/GrGLIndexBuffer.cpp
@@ -11,6 +11,7 @@
 GrGLIndexBuffer::GrGLIndexBuffer(GrGpuGL* gpu, const Desc& desc)
     : INHERITED(gpu, desc.fIsWrapped, desc.fSizeInBytes, desc.fDynamic, 0 == desc.fID)
     , fImpl(gpu, desc, GR_GL_ELEMENT_ARRAY_BUFFER) {
+    this->registerWithCache();
 }
 
 void GrGLIndexBuffer::onRelease() {
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index b81d9ce..063de56 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -39,57 +39,29 @@
     GrGLInterface* newInterface = GrGLInterface::NewClone(interface);
 
     newInterface->fExtensions.remove("GL_NV_path_rendering");
-
     newInterface->fFunctions.fPathCommands = NULL;
     newInterface->fFunctions.fPathCoords = NULL;
-    newInterface->fFunctions.fPathSubCommands = NULL;
-    newInterface->fFunctions.fPathSubCoords = NULL;
-    newInterface->fFunctions.fPathString = NULL;
-    newInterface->fFunctions.fPathGlyphs = NULL;
-    newInterface->fFunctions.fPathGlyphRange = NULL;
-    newInterface->fFunctions.fWeightPaths = NULL;
-    newInterface->fFunctions.fCopyPath = NULL;
-    newInterface->fFunctions.fInterpolatePaths = NULL;
-    newInterface->fFunctions.fTransformPath = NULL;
-    newInterface->fFunctions.fPathParameteriv = NULL;
     newInterface->fFunctions.fPathParameteri = NULL;
-    newInterface->fFunctions.fPathParameterfv = NULL;
     newInterface->fFunctions.fPathParameterf = NULL;
-    newInterface->fFunctions.fPathDashArray = NULL;
     newInterface->fFunctions.fGenPaths = NULL;
     newInterface->fFunctions.fDeletePaths = NULL;
     newInterface->fFunctions.fIsPath = NULL;
     newInterface->fFunctions.fPathStencilFunc = NULL;
-    newInterface->fFunctions.fPathStencilDepthOffset = NULL;
     newInterface->fFunctions.fStencilFillPath = NULL;
     newInterface->fFunctions.fStencilStrokePath = NULL;
     newInterface->fFunctions.fStencilFillPathInstanced = NULL;
     newInterface->fFunctions.fStencilStrokePathInstanced = NULL;
-    newInterface->fFunctions.fPathCoverDepthFunc = NULL;
-    newInterface->fFunctions.fPathColorGen = NULL;
     newInterface->fFunctions.fPathTexGen = NULL;
-    newInterface->fFunctions.fPathFogGen = NULL;
     newInterface->fFunctions.fCoverFillPath = NULL;
     newInterface->fFunctions.fCoverStrokePath = NULL;
     newInterface->fFunctions.fCoverFillPathInstanced = NULL;
     newInterface->fFunctions.fCoverStrokePathInstanced = NULL;
-    newInterface->fFunctions.fGetPathParameteriv = NULL;
-    newInterface->fFunctions.fGetPathParameterfv = NULL;
-    newInterface->fFunctions.fGetPathCommands = NULL;
-    newInterface->fFunctions.fGetPathCoords = NULL;
-    newInterface->fFunctions.fGetPathDashArray = NULL;
-    newInterface->fFunctions.fGetPathMetrics = NULL;
-    newInterface->fFunctions.fGetPathMetricRange = NULL;
-    newInterface->fFunctions.fGetPathSpacing = NULL;
-    newInterface->fFunctions.fGetPathColorGeniv = NULL;
-    newInterface->fFunctions.fGetPathColorGenfv = NULL;
-    newInterface->fFunctions.fGetPathTexGeniv = NULL;
-    newInterface->fFunctions.fGetPathTexGenfv = NULL;
-    newInterface->fFunctions.fIsPointInFillPath = NULL;
-    newInterface->fFunctions.fIsPointInStrokePath = NULL;
-    newInterface->fFunctions.fGetPathLength = NULL;
-    newInterface->fFunctions.fPointAlongPath = NULL;
-
+    newInterface->fFunctions.fStencilThenCoverFillPath = NULL;
+    newInterface->fFunctions.fStencilThenCoverStrokePath = NULL;
+    newInterface->fFunctions.fStencilThenCoverFillPathInstanced = NULL;
+    newInterface->fFunctions.fStencilThenCoverStrokePathInstanced = NULL;
+    newInterface->fFunctions.fProgramPathFragmentInputGen = NULL;
+    newInterface->fFunctions.fPathMemoryGlyphIndexArray = NULL;
     return newInterface;
 }
 
@@ -103,7 +75,7 @@
 }
 
 GrGLInterface* GrGLInterface::NewClone(const GrGLInterface* interface) {
-    SkASSERT(NULL != interface);
+    SkASSERT(interface);
 
     GrGLInterface* clone = SkNEW(GrGLInterface);
     clone->fStandard = interface->fStandard;
@@ -292,65 +264,6 @@
                 RETURN_FALSE_INTERFACE
             }
         }
-        if (fExtensions.has("GL_EXT_direct_state_access")) {
-            if (NULL == fFunctions.fMatrixLoadf ||
-                NULL == fFunctions.fMatrixLoadIdentity) {
-                RETURN_FALSE_INTERFACE
-            }
-        }
-        if (fExtensions.has("GL_NV_path_rendering")) {
-            if (NULL == fFunctions.fPathCommands ||
-                NULL == fFunctions.fPathCoords ||
-                NULL == fFunctions.fPathSubCommands ||
-                NULL == fFunctions.fPathSubCoords ||
-                NULL == fFunctions.fPathString ||
-                NULL == fFunctions.fPathGlyphs ||
-                NULL == fFunctions.fPathGlyphRange ||
-                NULL == fFunctions.fWeightPaths ||
-                NULL == fFunctions.fCopyPath ||
-                NULL == fFunctions.fInterpolatePaths ||
-                NULL == fFunctions.fTransformPath ||
-                NULL == fFunctions.fPathParameteriv ||
-                NULL == fFunctions.fPathParameteri ||
-                NULL == fFunctions.fPathParameterfv ||
-                NULL == fFunctions.fPathParameterf ||
-                NULL == fFunctions.fPathDashArray ||
-                NULL == fFunctions.fGenPaths ||
-                NULL == fFunctions.fDeletePaths ||
-                NULL == fFunctions.fIsPath ||
-                NULL == fFunctions.fPathStencilFunc ||
-                NULL == fFunctions.fPathStencilDepthOffset ||
-                NULL == fFunctions.fStencilFillPath ||
-                NULL == fFunctions.fStencilStrokePath ||
-                NULL == fFunctions.fStencilFillPathInstanced ||
-                NULL == fFunctions.fStencilStrokePathInstanced ||
-                NULL == fFunctions.fPathCoverDepthFunc ||
-                NULL == fFunctions.fPathColorGen ||
-                NULL == fFunctions.fPathTexGen ||
-                NULL == fFunctions.fPathFogGen ||
-                NULL == fFunctions.fCoverFillPath ||
-                NULL == fFunctions.fCoverStrokePath ||
-                NULL == fFunctions.fCoverFillPathInstanced ||
-                NULL == fFunctions.fCoverStrokePathInstanced ||
-                NULL == fFunctions.fGetPathParameteriv ||
-                NULL == fFunctions.fGetPathParameterfv ||
-                NULL == fFunctions.fGetPathCommands ||
-                NULL == fFunctions.fGetPathCoords ||
-                NULL == fFunctions.fGetPathDashArray ||
-                NULL == fFunctions.fGetPathMetrics ||
-                NULL == fFunctions.fGetPathMetricRange ||
-                NULL == fFunctions.fGetPathSpacing ||
-                NULL == fFunctions.fGetPathColorGeniv ||
-                NULL == fFunctions.fGetPathColorGenfv ||
-                NULL == fFunctions.fGetPathTexGeniv ||
-                NULL == fFunctions.fGetPathTexGenfv ||
-                NULL == fFunctions.fIsPointInFillPath ||
-                NULL == fFunctions.fIsPointInStrokePath ||
-                NULL == fFunctions.fGetPathLength ||
-                NULL == fFunctions.fPointAlongPath) {
-                RETURN_FALSE_INTERFACE
-            }
-        }
     }
 
     // optional function on desktop before 1.3
@@ -526,5 +439,59 @@
             RETURN_FALSE_INTERFACE;
         }
     }
+
+    if ((kGL_GrGLStandard == fStandard && fExtensions.has("GL_EXT_direct_state_access")) ||
+        (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_NV_path_rendering"))) {
+        if (NULL == fFunctions.fMatrixLoadf ||
+            NULL == fFunctions.fMatrixLoadIdentity) {
+            RETURN_FALSE_INTERFACE
+        }
+    }
+
+    if ((kGL_GrGLStandard == fStandard &&
+         (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_program_interface_query"))) ||
+        (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) {
+        if (NULL == fFunctions.fGetProgramResourceLocation) {
+            RETURN_FALSE_INTERFACE
+        }
+    }
+
+    if (fExtensions.has("GL_NV_path_rendering")) {
+        if (NULL == fFunctions.fPathCommands ||
+            NULL == fFunctions.fPathCoords ||
+            NULL == fFunctions.fPathParameteri ||
+            NULL == fFunctions.fPathParameterf ||
+            NULL == fFunctions.fGenPaths ||
+            NULL == fFunctions.fDeletePaths ||
+            NULL == fFunctions.fIsPath ||
+            NULL == fFunctions.fPathStencilFunc ||
+            NULL == fFunctions.fStencilFillPath ||
+            NULL == fFunctions.fStencilStrokePath ||
+            NULL == fFunctions.fStencilFillPathInstanced ||
+            NULL == fFunctions.fStencilStrokePathInstanced ||
+            NULL == fFunctions.fCoverFillPath ||
+            NULL == fFunctions.fCoverStrokePath ||
+            NULL == fFunctions.fCoverFillPathInstanced ||
+            NULL == fFunctions.fCoverStrokePathInstanced) {
+            RETURN_FALSE_INTERFACE
+        }
+        if (kGL_GrGLStandard == fStandard) {
+            // Some methods only exist on desktop
+            if (NULL == fFunctions.fPathTexGen) {
+                RETURN_FALSE_INTERFACE
+            }
+        } else {
+            // All additions through v1.3 exist on GLES
+            if (NULL == fFunctions.fStencilThenCoverFillPath ||
+                NULL == fFunctions.fStencilThenCoverStrokePath ||
+                NULL == fFunctions.fStencilThenCoverFillPathInstanced ||
+                NULL == fFunctions.fStencilThenCoverStrokePathInstanced ||
+                NULL == fFunctions.fProgramPathFragmentInputGen ||
+                NULL == fFunctions.fPathMemoryGlyphIndexArray) {
+                RETURN_FALSE_INTERFACE
+            }
+        }
+    }
+
     return true;
 }
diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp
index bb26b12..6097f46 100644
--- a/src/gpu/gl/GrGLPath.cpp
+++ b/src/gpu/gl/GrGLPath.cpp
@@ -7,13 +7,9 @@
  */
 
 #include "GrGLPath.h"
+#include "GrGLPathRendering.h"
 #include "GrGpuGL.h"
 
-#define GPUGL static_cast<GrGpuGL*>(this->getGpu())
-
-#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
-#define GL_CALL_RET(R, X) GR_GL_CALL_RET(GPUGL->glInterface(), R, X)
-
 namespace {
 inline GrGLubyte verb_to_gl_path_cmd(SkPath::Verb verb) {
     static const GrGLubyte gTable[] = {
@@ -85,57 +81,75 @@
 
 static const bool kIsWrapped = false; // The constructor creates the GL path object.
 
-GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke)
-    : INHERITED(gpu, kIsWrapped, path, stroke) {
-    SkASSERT(!path.isEmpty());
+void GrGLPath::InitPathObject(GrGpuGL* gpu,
+                              GrGLuint pathID,
+                              const SkPath& skPath,
+                              const SkStrokeRec& stroke) {
+    if (!skPath.isEmpty()) {
+        SkSTArray<16, GrGLubyte, true> pathCommands;
+        SkSTArray<16, SkPoint, true> pathPoints;
 
-    fPathID = gpu->createGLPathObject();
+        int verbCnt = skPath.countVerbs();
+        int pointCnt = skPath.countPoints();
+        pathCommands.resize_back(verbCnt);
+        pathPoints.resize_back(pointCnt);
 
-    SkSTArray<16, GrGLubyte, true> pathCommands;
-    SkSTArray<16, SkPoint, true> pathPoints;
+        // TODO: Direct access to path points since we could pass them on directly.
+        skPath.getPoints(&pathPoints[0], pointCnt);
+        skPath.getVerbs(&pathCommands[0], verbCnt);
 
-    int verbCnt = fSkPath.countVerbs();
-    int pointCnt = fSkPath.countPoints();
-    pathCommands.resize_back(verbCnt);
-    pathPoints.resize_back(pointCnt);
+        SkDEBUGCODE(int numPts = 0);
+        for (int i = 0; i < verbCnt; ++i) {
+            SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]);
+            pathCommands[i] = verb_to_gl_path_cmd(v);
+            SkDEBUGCODE(numPts += num_pts(v));
+        }
+        SkASSERT(pathPoints.count() == numPts);
 
-    // TODO: Direct access to path points since we could pass them on directly.
-    fSkPath.getPoints(&pathPoints[0], pointCnt);
-    fSkPath.getVerbs(&pathCommands[0], verbCnt);
-
-    SkDEBUGCODE(int numPts = 0);
-    for (int i = 0; i < verbCnt; ++i) {
-        SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]);
-        pathCommands[i] = verb_to_gl_path_cmd(v);
-        SkDEBUGCODE(numPts += num_pts(v));
+        GR_GL_CALL(gpu->glInterface(),
+                   PathCommands(pathID, verbCnt, &pathCommands[0],
+                                2 * pointCnt, GR_GL_FLOAT, &pathPoints[0]));
+    } else {
+        GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, 0, NULL, 0, GR_GL_FLOAT, NULL));
     }
-    SkASSERT(pathPoints.count() == numPts);
-
-    GL_CALL(PathCommands(fPathID,
-                         verbCnt, &pathCommands[0],
-                         2 * pointCnt, GR_GL_FLOAT, &pathPoints[0]));
 
     if (stroke.needToApply()) {
-        GL_CALL(PathParameterf(fPathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(stroke.getWidth())));
-        GL_CALL(PathParameterf(fPathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(stroke.getMiter())));
+        SkASSERT(!stroke.isHairlineStyle());
+        GR_GL_CALL(gpu->glInterface(),
+            PathParameterf(pathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(stroke.getWidth())));
+        GR_GL_CALL(gpu->glInterface(),
+            PathParameterf(pathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(stroke.getMiter())));
         GrGLenum join = join_to_gl_join(stroke.getJoin());
-        GL_CALL(PathParameteri(fPathID, GR_GL_PATH_JOIN_STYLE, join));
+        GR_GL_CALL(gpu->glInterface(),
+            PathParameteri(pathID, GR_GL_PATH_JOIN_STYLE, join));
         GrGLenum cap = cap_to_gl_cap(stroke.getCap());
-        GL_CALL(PathParameteri(fPathID, GR_GL_PATH_INITIAL_END_CAP, cap));
-        GL_CALL(PathParameteri(fPathID, GR_GL_PATH_TERMINAL_END_CAP, cap));
-
-        // FIXME: try to account for stroking, without rasterizing the stroke.
-        fBounds.outset(SkScalarToFloat(stroke.getWidth()), SkScalarToFloat(stroke.getWidth()));
+        GR_GL_CALL(gpu->glInterface(),
+            PathParameteri(pathID, GR_GL_PATH_INITIAL_END_CAP, cap));
+        GR_GL_CALL(gpu->glInterface(),
+            PathParameteri(pathID, GR_GL_PATH_TERMINAL_END_CAP, cap));
     }
 }
 
+GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke)
+    : INHERITED(gpu, kIsWrapped, path, stroke),
+      fPathID(gpu->glPathRendering()->genPaths(1)) {
+
+    InitPathObject(gpu, fPathID, fSkPath, stroke);
+
+    if (stroke.needToApply()) {
+        // FIXME: try to account for stroking, without rasterizing the stroke.
+        fBounds.outset(stroke.getWidth(), stroke.getWidth());
+    }
+    this->registerWithCache();
+}
+
 GrGLPath::~GrGLPath() {
     this->release();
 }
 
 void GrGLPath::onRelease() {
     if (0 != fPathID && !this->isWrapped()) {
-        static_cast<GrGpuGL*>(this->getGpu())->deleteGLPathObject(fPathID);
+        static_cast<GrGpuGL*>(this->getGpu())->glPathRendering()->deletePaths(fPathID, 1);
         fPathID = 0;
     }
 
diff --git a/src/gpu/gl/GrGLPath.h b/src/gpu/gl/GrGLPath.h
index 3409547..935a2e2 100644
--- a/src/gpu/gl/GrGLPath.h
+++ b/src/gpu/gl/GrGLPath.h
@@ -22,6 +22,11 @@
 
 class GrGLPath : public GrPath {
 public:
+    static void InitPathObject(GrGpuGL*,
+                               GrGLuint pathID,
+                               const SkPath&,
+                               const SkStrokeRec&);
+
     GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke);
     virtual ~GrGLPath();
     GrGLuint pathID() const { return fPathID; }
diff --git a/src/gpu/gl/GrGLPathRange.cpp b/src/gpu/gl/GrGLPathRange.cpp
new file mode 100644
index 0000000..12c96c6
--- /dev/null
+++ b/src/gpu/gl/GrGLPathRange.cpp
@@ -0,0 +1,70 @@
+
+/*
+ * 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 "GrGLPathRange.h"
+#include "GrGLPath.h"
+#include "GrGLPathRendering.h"
+#include "GrGpuGL.h"
+
+GrGLPathRange::GrGLPathRange(GrGpuGL* gpu, PathGenerator* pathGenerator, const SkStrokeRec& stroke)
+    : INHERITED(gpu, pathGenerator, stroke),
+      fBasePathID(gpu->glPathRendering()->genPaths(this->getNumPaths())),
+      fGpuMemorySize(0) {
+    this->registerWithCache();
+}
+
+GrGLPathRange::GrGLPathRange(GrGpuGL* gpu,
+                             GrGLuint basePathID,
+                             int numPaths,
+                             size_t gpuMemorySize,
+                             const SkStrokeRec& stroke)
+    : INHERITED(gpu, numPaths, stroke),
+      fBasePathID(basePathID),
+      fGpuMemorySize(gpuMemorySize) {
+    this->registerWithCache();
+}
+
+GrGLPathRange::~GrGLPathRange() {
+    this->release();
+}
+
+void GrGLPathRange::onInitPath(int index, const SkPath& skPath) const {
+    GrGpuGL* gpu = static_cast<GrGpuGL*>(this->getGpu());
+    if (NULL == gpu) {
+        return;
+    }
+
+    // Make sure the path at this index hasn't been initted already.
+    SkDEBUGCODE(
+        GrGLboolean isPath;
+        GR_GL_CALL_RET(gpu->glInterface(), isPath, IsPath(fBasePathID + index)));
+    SkASSERT(GR_GL_FALSE == isPath);
+
+    GrGLPath::InitPathObject(gpu, fBasePathID + index, skPath, this->getStroke());
+
+    // TODO: Use a better approximation for the individual path sizes.
+    fGpuMemorySize += 100;
+}
+
+void GrGLPathRange::onRelease() {
+    SkASSERT(this->getGpu());
+
+    if (0 != fBasePathID && !this->isWrapped()) {
+        static_cast<GrGpuGL*>(this->getGpu())->glPathRendering()->deletePaths(fBasePathID,
+                                                                              this->getNumPaths());
+        fBasePathID = 0;
+    }
+
+    INHERITED::onRelease();
+}
+
+void GrGLPathRange::onAbandon() {
+    fBasePathID = 0;
+
+    INHERITED::onAbandon();
+}
diff --git a/src/gpu/gl/GrGLPathRange.h b/src/gpu/gl/GrGLPathRange.h
new file mode 100644
index 0000000..f21ce3a
--- /dev/null
+++ b/src/gpu/gl/GrGLPathRange.h
@@ -0,0 +1,61 @@
+
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLPathRange_DEFINED
+#define GrGLPathRange_DEFINED
+
+#include "../GrPathRange.h"
+#include "gl/GrGLFunctions.h"
+
+class GrGpuGL;
+
+/**
+ * Currently this represents a range of GL_NV_path_rendering Path IDs. If we
+ * support other GL path extensions then this would have to have a type enum
+ * and/or be subclassed.
+ */
+
+class GrGLPathRange : public GrPathRange {
+public:
+    /**
+     * Initialize a GL path range from a PathGenerator. This class will allocate
+     * the GPU path objects and initialize them lazily.
+     */
+    GrGLPathRange(GrGpuGL*, PathGenerator*, const SkStrokeRec&);
+
+    /**
+     * Initialize a GL path range from an existing range of pre-initialized GPU
+     * path objects. This class assumes ownership of the GPU path objects and
+     * will delete them when done.
+     */
+    GrGLPathRange(GrGpuGL*,
+                  GrGLuint basePathID,
+                  int numPaths,
+                  size_t gpuMemorySize,
+                  const SkStrokeRec&);
+
+    virtual ~GrGLPathRange();
+
+    GrGLuint basePathID() const { return fBasePathID; }
+
+    virtual size_t gpuMemorySize() const SK_OVERRIDE { return fGpuMemorySize; }
+
+protected:
+    virtual void onInitPath(int index, const SkPath&) const;
+
+    virtual void onRelease() SK_OVERRIDE;
+    virtual void onAbandon() SK_OVERRIDE;
+
+private:
+    GrGLuint fBasePathID;
+    mutable size_t fGpuMemorySize;
+
+    typedef GrPathRange INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
new file mode 100644
index 0000000..26584bc
--- /dev/null
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -0,0 +1,534 @@
+/*
+ * 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 "gl/GrGLPathRendering.h"
+#include "gl/GrGLNameAllocator.h"
+#include "gl/GrGLUtil.h"
+#include "gl/GrGpuGL.h"
+
+#include "GrGLPath.h"
+#include "GrGLPathRange.h"
+#include "GrGLPathRendering.h"
+
+#include "SkStream.h"
+#include "SkTypeface.h"
+
+#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
+#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGpu->glInterface(), RET, X)
+
+
+static const GrGLenum gXformType2GLType[] = {
+    GR_GL_NONE,
+    GR_GL_TRANSLATE_X,
+    GR_GL_TRANSLATE_Y,
+    GR_GL_TRANSLATE_2D,
+    GR_GL_TRANSPOSE_AFFINE_2D
+};
+
+GR_STATIC_ASSERT(0 == GrPathRendering::kNone_PathTransformType);
+GR_STATIC_ASSERT(1 == GrPathRendering::kTranslateX_PathTransformType);
+GR_STATIC_ASSERT(2 == GrPathRendering::kTranslateY_PathTransformType);
+GR_STATIC_ASSERT(3 == GrPathRendering::kTranslate_PathTransformType);
+GR_STATIC_ASSERT(4 == GrPathRendering::kAffine_PathTransformType);
+GR_STATIC_ASSERT(GrPathRendering::kAffine_PathTransformType == GrPathRendering::kLast_PathTransformType);
+
+static GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) {
+    switch (op) {
+        default:
+            SkFAIL("Unexpected path fill.");
+            /* fallthrough */;
+        case kIncClamp_StencilOp:
+            return GR_GL_COUNT_UP;
+        case kInvert_StencilOp:
+            return GR_GL_INVERT;
+    }
+}
+
+GrGLPathRendering::GrGLPathRendering(GrGpuGL* gpu)
+    : fGpu(gpu) {
+    const GrGLInterface* glInterface = gpu->glInterface();
+    fCaps.stencilThenCoverSupport =
+        NULL != glInterface->fFunctions.fStencilThenCoverFillPath &&
+        NULL != glInterface->fFunctions.fStencilThenCoverStrokePath &&
+        NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced &&
+        NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced;
+    fCaps.fragmentInputGenSupport =
+        kGLES_GrGLStandard == glInterface->fStandard &&
+        NULL != glInterface->fFunctions.fProgramPathFragmentInputGen;
+    fCaps.glyphLoadingSupport =
+        NULL != glInterface->fFunctions.fPathMemoryGlyphIndexArray;
+
+    if (!fCaps.fragmentInputGenSupport) {
+        fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords());
+    }
+}
+
+GrGLPathRendering::~GrGLPathRendering() {
+}
+
+void GrGLPathRendering::abandonGpuResources() {
+    fPathNameAllocator.reset(NULL);
+}
+
+void GrGLPathRendering::resetContext() {
+    fHWProjectionMatrixState.invalidate();
+    // we don't use the model view matrix.
+    GrGLenum matrixMode =
+        fGpu->glStandard() == kGLES_GrGLStandard ? GR_GL_PATH_MODELVIEW : GR_GL_MODELVIEW;
+    GL_CALL(MatrixLoadIdentity(matrixMode));
+
+    if (!caps().fragmentInputGenSupport) {
+        for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) {
+            GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
+            fHWPathTexGenSettings[i].fMode = GR_GL_NONE;
+            fHWPathTexGenSettings[i].fNumComponents = 0;
+        }
+        fHWActivePathTexGenSets = 0;
+    }
+    fHWPathStencilSettings.invalidate();
+}
+
+GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const SkStrokeRec& stroke) {
+    return SkNEW_ARGS(GrGLPath, (fGpu, inPath, stroke));
+}
+
+GrPathRange* GrGLPathRendering::createPathRange(GrPathRange::PathGenerator* pathGenerator,
+                                                const SkStrokeRec& stroke) {
+    return SkNEW_ARGS(GrGLPathRange, (fGpu, pathGenerator, stroke));
+}
+
+GrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface,
+                                             const SkDescriptor* desc,
+                                             const SkStrokeRec& stroke) {
+    if (NULL != desc || !caps().glyphLoadingSupport) {
+        return GrPathRendering::createGlyphs(typeface, desc, stroke);
+    }
+
+    if (NULL == typeface) {
+        typeface = SkTypeface::GetDefaultTypeface();
+        SkASSERT(NULL != typeface);
+    }
+
+    int faceIndex;
+    SkAutoTUnref<SkStream> fontStream(typeface->openStream(&faceIndex));
+
+    const size_t fontDataLength = fontStream->getLength();
+    if (0 == fontDataLength) {
+        return GrPathRendering::createGlyphs(typeface, NULL, stroke);
+    }
+
+    SkTArray<uint8_t> fontTempBuffer;
+    const void* fontData = fontStream->getMemoryBase();
+    if (NULL == fontData) {
+        // TODO: Find a more efficient way to pass the font data (e.g. open file descriptor).
+        fontTempBuffer.reset(fontDataLength);
+        fontStream->read(&fontTempBuffer.front(), fontDataLength);
+        fontData = &fontTempBuffer.front();
+    }
+
+    const size_t numPaths = typeface->countGlyphs();
+    const GrGLuint basePathID = this->genPaths(numPaths);
+    SkAutoTUnref<GrGLPath> templatePath(SkNEW_ARGS(GrGLPath, (fGpu, SkPath(), stroke)));
+
+    GrGLenum status;
+    GL_CALL_RET(status, PathMemoryGlyphIndexArray(basePathID, GR_GL_STANDARD_FONT_FORMAT,
+                                                  fontDataLength, fontData, faceIndex, 0,
+                                                  numPaths, templatePath->pathID(),
+                                                  SkPaint::kCanonicalTextSizeForPaths));
+
+    if (GR_GL_FONT_GLYPHS_AVAILABLE != status) {
+        this->deletePaths(basePathID, numPaths);
+        return GrPathRendering::createGlyphs(typeface, NULL, stroke);
+    }
+
+    // This is a crude approximation. We may want to consider giving this class
+    // a pseudo PathGenerator whose sole purpose is to track the approximate gpu
+    // memory size.
+    const size_t gpuMemorySize = fontDataLength / 4;
+    return SkNEW_ARGS(GrGLPathRange, (fGpu, basePathID, numPaths, gpuMemorySize, stroke));
+}
+
+void GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) {
+    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
+    SkASSERT(fGpu->drawState()->getRenderTarget());
+    SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
+
+    this->flushPathStencilSettings(fill);
+    SkASSERT(!fHWPathStencilSettings.isTwoSided());
+
+    GrGLenum fillMode =
+        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
+    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
+    GL_CALL(StencilFillPath(id, fillMode, writeMask));
+}
+
+void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) {
+    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
+    SkASSERT(fGpu->drawState()->getRenderTarget());
+    SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
+
+    this->flushPathStencilSettings(fill);
+    SkASSERT(!fHWPathStencilSettings.isTwoSided());
+
+    const SkStrokeRec& stroke = path->getStroke();
+
+    SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill);
+
+    GrGLenum fillMode =
+        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
+    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
+
+    if (nonInvertedFill == fill) {
+        if (stroke.needToApply()) {
+            if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
+                GL_CALL(StencilFillPath(id, fillMode, writeMask));
+            }
+            this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX);
+        } else {
+            this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX);
+        }
+    } else {
+        if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
+            GL_CALL(StencilFillPath(id, fillMode, writeMask));
+        }
+        if (stroke.needToApply()) {
+            GL_CALL(StencilStrokePath(id, 0xffff, writeMask));
+        }
+
+        GrDrawState* drawState = fGpu->drawState();
+        GrDrawState::AutoViewMatrixRestore avmr;
+        SkRect bounds = SkRect::MakeLTRB(0, 0,
+                                         SkIntToScalar(drawState->getRenderTarget()->width()),
+                                         SkIntToScalar(drawState->getRenderTarget()->height()));
+        SkMatrix vmi;
+        // mapRect through persp matrix may not be correct
+        if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
+            vmi.mapRect(&bounds);
+            // theoretically could set bloat = 0, instead leave it because of matrix inversion
+            // precision.
+            SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
+            bounds.outset(bloat, bloat);
+        } else {
+            avmr.setIdentity(drawState);
+        }
+
+        fGpu->drawSimpleRect(bounds);
+    }
+}
+
+void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count,
+                                  const float transforms[], PathTransformType transformsType,
+                                  SkPath::FillType fill) {
+    SkASSERT(fGpu->caps()->pathRenderingSupport());
+    SkASSERT(fGpu->drawState()->getRenderTarget());
+    SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
+
+    GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();
+
+    this->flushPathStencilSettings(fill);
+    SkASSERT(!fHWPathStencilSettings.isTwoSided());
+
+    const SkStrokeRec& stroke = pathRange->getStroke();
+
+    SkPath::FillType nonInvertedFill =
+        SkPath::ConvertToNonInverseFillType(fill);
+
+    GrGLenum fillMode =
+        gr_stencil_op_to_gl_path_rendering_fill_mode(
+            fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
+    GrGLint writeMask =
+        fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
+
+    if (nonInvertedFill == fill) {
+        if (stroke.needToApply()) {
+            if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
+                GL_CALL(StencilFillPathInstanced(
+                                count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
+                                writeMask, gXformType2GLType[transformsType],
+                                transforms));
+            }
+            this->stencilThenCoverStrokePathInstanced(
+                                count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask,
+                                GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
+                                gXformType2GLType[transformsType], transforms);
+        } else {
+            this->stencilThenCoverFillPathInstanced(
+                                count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask,
+                                GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
+                                gXformType2GLType[transformsType], transforms);
+        }
+    } else {
+        if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
+            GL_CALL(StencilFillPathInstanced(
+                                count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
+                                writeMask, gXformType2GLType[transformsType],
+                                transforms));
+        }
+        if (stroke.needToApply()) {
+            GL_CALL(StencilStrokePathInstanced(
+                                count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff,
+                                writeMask, gXformType2GLType[transformsType],
+                                transforms));
+        }
+
+        GrDrawState* drawState = fGpu->drawState();
+        GrDrawState::AutoViewMatrixRestore avmr;
+        SkRect bounds = SkRect::MakeLTRB(0, 0,
+                                         SkIntToScalar(drawState->getRenderTarget()->width()),
+                                         SkIntToScalar(drawState->getRenderTarget()->height()));
+        SkMatrix vmi;
+        // mapRect through persp matrix may not be correct
+        if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
+            vmi.mapRect(&bounds);
+            // theoretically could set bloat = 0, instead leave it because of matrix inversion
+            // precision.
+            SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
+            bounds.outset(bloat, bloat);
+        } else {
+            avmr.setIdentity(drawState);
+        }
+
+        fGpu->drawSimpleRect(bounds);
+    }
+}
+
+void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents components,
+                                         const GrGLfloat* coefficients) {
+    SkASSERT(components >= kS_PathTexGenComponents &&
+             components <= kSTR_PathTexGenComponents);
+    SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= unitIdx);
+
+    if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode &&
+        components == fHWPathTexGenSettings[unitIdx].fNumComponents &&
+        !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients,
+                3 * components * sizeof(GrGLfloat))) {
+        return;
+    }
+
+    fGpu->setTextureUnit(unitIdx);
+
+    fHWPathTexGenSettings[unitIdx].fNumComponents = components;
+    GL_CALL(PathTexGen(GR_GL_TEXTURE0 + unitIdx, GR_GL_OBJECT_LINEAR, components, coefficients));
+
+    memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients,
+           3 * components * sizeof(GrGLfloat));
+}
+
+void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents components,
+                                         const SkMatrix& matrix) {
+    GrGLfloat coefficients[3 * 3];
+    SkASSERT(components >= kS_PathTexGenComponents &&
+             components <= kSTR_PathTexGenComponents);
+
+    coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
+    coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
+    coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
+
+    if (components >= kST_PathTexGenComponents) {
+        coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
+        coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
+        coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
+    }
+
+    if (components >= kSTR_PathTexGenComponents) {
+        coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
+        coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
+        coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
+    }
+
+    this->enablePathTexGen(unitIdx, components, coefficients);
+}
+
+void GrGLPathRendering::flushPathTexGenSettings(int numUsedTexCoordSets) {
+    SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSets);
+
+    // Only write the inactive path tex gens, since active path tex gens were
+    // written when they were enabled.
+
+    SkDEBUGCODE(
+        for (int i = 0; i < numUsedTexCoordSets; i++) {
+            SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
+        }
+    );
+
+    for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) {
+        SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
+
+        fGpu->setTextureUnit(i);
+        GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
+        fHWPathTexGenSettings[i].fNumComponents = 0;
+    }
+
+    fHWActivePathTexGenSets = numUsedTexCoordSets;
+}
+
+void GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
+                                                             GrGLenum genMode, GrGLint components,
+                                                             const SkMatrix& matrix) {
+    SkASSERT(caps().fragmentInputGenSupport);
+    GrGLfloat coefficients[3 * 3];
+    SkASSERT(components >= 1 && components <= 3);
+
+    coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
+    coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
+    coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
+
+    if (components >= 2) {
+        coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
+        coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
+        coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
+    }
+
+    if (components >= 3) {
+        coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
+        coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
+        coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
+    }
+
+    GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coefficients));
+}
+
+void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix,
+                                  const SkISize& renderTargetSize,
+                                  GrSurfaceOrigin renderTargetOrigin) {
+
+    SkASSERT(fGpu->glCaps().pathRenderingSupport());
+
+    if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin &&
+        renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize &&
+        matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) {
+        return;
+    }
+
+    fHWProjectionMatrixState.fViewMatrix = matrix;
+    fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize;
+    fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin;
+
+    GrGLfloat glMatrix[4 * 4];
+    fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix);
+     GrGLenum matrixMode =
+         fGpu->glStandard() == kGLES_GrGLStandard ? GR_GL_PATH_PROJECTION : GR_GL_PROJECTION;
+     GL_CALL(MatrixLoadf(matrixMode, glMatrix));
+}
+
+GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) {
+    if (range > 1) {
+        GrGLuint name;
+        GL_CALL_RET(name, GenPaths(range));
+        return name;
+    }
+
+    if (NULL == fPathNameAllocator.get()) {
+        static const int range = 65536;
+        GrGLuint firstName;
+        GL_CALL_RET(firstName, GenPaths(range));
+        fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, firstName + range)));
+    }
+
+    // When allocating names one at a time, pull from a client-side pool of
+    // available names in order to save a round trip to the GL server.
+    GrGLuint name = fPathNameAllocator->allocateName();
+
+    if (0 == name) {
+        // Our reserved path names are all in use. Fall back on GenPaths.
+        GL_CALL_RET(name, GenPaths(1));
+    }
+
+    return name;
+}
+
+void GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) {
+    if (range > 1) {
+        // It is not supported to delete names in ranges that were allocated
+        // individually using GrGLPathNameAllocator.
+        SkASSERT(NULL == fPathNameAllocator.get() ||
+                 path + range <= fPathNameAllocator->firstName() ||
+                 path >= fPathNameAllocator->endName());
+        GL_CALL(DeletePaths(path, range));
+        return;
+    }
+
+    if (NULL == fPathNameAllocator.get() ||
+        path < fPathNameAllocator->firstName() ||
+        path >= fPathNameAllocator->endName()) {
+        // If we aren't inside fPathNameAllocator's range then this name was
+        // generated by the GenPaths fallback (or else was never allocated).
+        GL_CALL(DeletePaths(path, 1));
+        return;
+    }
+
+    // Make the path empty to save memory, but don't free the name in the driver.
+    GL_CALL(PathCommands(path, 0, NULL, 0, GR_GL_FLOAT, NULL));
+    fPathNameAllocator->free(path);
+}
+
+void GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) {
+    GrStencilSettings pathStencilSettings;
+    fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings);
+    if (fHWPathStencilSettings != pathStencilSettings) {
+        // Just the func, ref, and mask is set here. The op and write mask are params to the call
+        // that draws the path to the SB (glStencilFillPath)
+        GrGLenum func =
+            GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront_Face));
+        GL_CALL(PathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSettings::kFront_Face),
+                                pathStencilSettings.funcMask(GrStencilSettings::kFront_Face)));
+
+        fHWPathStencilSettings = pathStencilSettings;
+    }
+}
+
+inline void GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
+                                                     GrGLuint mask, GrGLenum coverMode) {
+    if (caps().stencilThenCoverSupport) {
+        GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode));
+        return;
+    }
+    GL_CALL(StencilFillPath(path, fillMode, mask));
+    GL_CALL(CoverFillPath(path, coverMode));
+}
+
+inline void GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
+                                                       GrGLuint mask, GrGLenum coverMode) {
+    if (caps().stencilThenCoverSupport) {
+        GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode));
+        return;
+    }
+    GL_CALL(StencilStrokePath(path, reference, mask));
+    GL_CALL(CoverStrokePath(path, coverMode));
+}
+
+inline void GrGLPathRendering::stencilThenCoverFillPathInstanced(
+             GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
+             GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
+             GrGLenum transformType, const GrGLfloat *transformValues) {
+    if (caps().stencilThenCoverSupport) {
+        GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode,
+                                                  mask, coverMode, transformType, transformValues));
+        return;
+    }
+    GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase,
+                                     fillMode, mask, transformType, transformValues));
+    GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase,
+                                   coverMode, transformType, transformValues));
+}
+
+inline void GrGLPathRendering::stencilThenCoverStrokePathInstanced(
+        GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
+        GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
+        GrGLenum transformType, const GrGLfloat *transformValues) {
+    if (caps().stencilThenCoverSupport) {
+        GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
+                                                    reference, mask, coverMode, transformType,
+                                                    transformValues));
+        return;
+    }
+
+    GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
+                                       reference, mask, transformType, transformValues));
+    GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
+                                     coverMode, transformType, transformValues));
+}
diff --git a/src/gpu/gl/GrGLPathRendering.h b/src/gpu/gl/GrGLPathRendering.h
new file mode 100644
index 0000000..5133506
--- /dev/null
+++ b/src/gpu/gl/GrGLPathRendering.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLPathRendering_DEFINED
+#define GrGLPathRendering_DEFINED
+
+#include "SkRefCnt.h"
+#include "GrPathRendering.h"
+#include "GrStencil.h"
+#include "gl/GrGLFunctions.h"
+#include "gl/GrGLProgram.h"
+
+class GrGLNameAllocator;
+class GrGpuGL;
+
+/**
+ * This class wraps the NV_path_rendering extension and manages its various
+ * API versions. If a method is not present in the GrGLInterface of the GrGpuGL
+ * (because the driver version is old), it tries to provide a backup
+ * implementation. But if a backup implementation is not practical, it marks the
+ * method as not supported.
+ */
+class GrGLPathRendering : public GrPathRendering {
+public:
+    /**
+     * Create a new GrGLPathRendering object from a given GrGpuGL.
+     */
+    GrGLPathRendering(GrGpuGL* gpu);
+    virtual ~GrGLPathRendering();
+
+    // GrPathRendering implementations.
+    virtual GrPath* createPath(const SkPath&, const SkStrokeRec&) SK_OVERRIDE;
+    virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*,
+                                         const SkStrokeRec&) SK_OVERRIDE;
+    virtual GrPathRange* createGlyphs(const SkTypeface*,
+                                      const SkDescriptor*,
+                                      const SkStrokeRec&) SK_OVERRIDE;
+    virtual void stencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
+    virtual void drawPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
+    virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count,
+                           const float transforms[], PathTransformType,
+                           SkPath::FillType) SK_OVERRIDE;
+
+    /* Called when the 3D context state is unknown. */
+    void resetContext();
+
+    /**
+     * Called when the GPU resources have been lost and need to be abandoned
+     * (for example after a context loss).
+     */
+    void abandonGpuResources();
+
+
+    enum TexturingMode {
+        FixedFunction_TexturingMode,
+        SeparableShaders_TexturingMode
+    };
+
+    /** Specifies whether texturing should use fixed fuction pipe or separable shaders
+     * Specifies whether texturing should use fixed fuction pipe or whether
+     * it is ok to use normal vertex and fragment shaders, and for path rendering
+     * populate fragment shaders with setProgramPathFragmentInputTransform.
+     * The fixed function mode will be removed once the other mode is more widely
+     * available.
+     */
+    TexturingMode texturingMode() const  {
+        return caps().fragmentInputGenSupport ?
+            SeparableShaders_TexturingMode : FixedFunction_TexturingMode;
+    }
+
+    // Functions for fixed function texturing support.
+    enum PathTexGenComponents {
+        kS_PathTexGenComponents = 1,
+        kST_PathTexGenComponents = 2,
+        kSTR_PathTexGenComponents = 3
+    };
+    void enablePathTexGen(int unitIdx, PathTexGenComponents, const GrGLfloat* coefficients);
+    void enablePathTexGen(int unitIdx, PathTexGenComponents, const SkMatrix& matrix);
+    void flushPathTexGenSettings(int numUsedTexCoordSets);
+
+    // Functions for "separable shader" texturing support.
+    void setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
+                                              GrGLenum genMode, GrGLint components,
+                                              const SkMatrix&);
+
+    /* Sets the projection matrix for path rendering */
+    void setProjectionMatrix(const SkMatrix& matrix,
+                             const SkISize& renderTargetSize,
+                             GrSurfaceOrigin renderTargetOrigin);
+
+    GrGLuint genPaths(GrGLsizei range);
+    GrGLvoid deletePaths(GrGLuint path, GrGLsizei range);
+
+private:
+    /**
+     * Mark certain functionality as not supported if the driver version is too
+     * old and a backup implementation is not practical.
+     */
+    struct Caps {
+        bool stencilThenCoverSupport : 1;
+        bool fragmentInputGenSupport : 1;
+        bool glyphLoadingSupport     : 1;
+    };
+    const Caps& caps() const { return fCaps; }
+
+    void flushPathStencilSettings(SkPath::FillType fill);
+
+    // NV_path_rendering v1.2
+    void stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
+                                  GrGLuint mask, GrGLenum coverMode);
+
+    void stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
+                                    GrGLuint mask, GrGLenum coverMode);
+
+    void stencilThenCoverFillPathInstanced(
+        GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
+                         GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
+                         GrGLenum transformType, const GrGLfloat *transformValues);
+
+    void stencilThenCoverStrokePathInstanced(
+                         GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
+                         GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
+                         GrGLenum transformType, const GrGLfloat *transformValues);
+
+    GrGpuGL* fGpu;
+    SkAutoTDelete<GrGLNameAllocator> fPathNameAllocator;
+    Caps fCaps;
+    GrGLProgram::MatrixState fHWProjectionMatrixState;
+    GrStencilSettings fHWPathStencilSettings;
+    struct PathTexGenData {
+        GrGLenum  fMode;
+        GrGLint   fNumComponents;
+        GrGLfloat fCoefficients[3 * 3];
+    };
+    int fHWActivePathTexGenSets;
+    SkTArray<PathTexGenData, true> fHWPathTexGenSettings;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLProcessor.h b/src/gpu/gl/GrGLProcessor.h
new file mode 100644
index 0000000..8455305
--- /dev/null
+++ b/src/gpu/gl/GrGLProcessor.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLProcessor_DEFINED
+#define GrGLProcessor_DEFINED
+
+#include "GrBackendProcessorFactory.h"
+#include "GrGLProgramEffects.h"
+#include "GrGLShaderVar.h"
+#include "GrGLSL.h"
+
+/** @file
+    This file contains specializations for OpenGL of the shader stages declared in
+    include/gpu/GrProcessor.h. Objects of type GrGLProcessor are responsible for emitting the
+    GLSL code that implements a GrProcessor and for uploading uniforms at draw time. If they don't
+    always emit the same GLSL code, they must have a function:
+        static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*)
+    that is used to implement a program cache. When two GrProcessors produce the same key this means
+    that their GrGLProcessors would emit the same GLSL code.
+
+    The GrGLProcessor subclass must also have a constructor of the form:
+        EffectSubclass::EffectSubclass(const GrBackendEffectFactory&, const GrProcessor&)
+
+    These objects are created by the factory object returned by the GrProcessor::getFactory().
+*/
+
+class GrGLProcessor {
+public:
+    GrGLProcessor(const GrBackendProcessorFactory& factory)
+        : fFactory(factory) {
+    }
+
+    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+
+    /**
+     * Passed to GrGLProcessors so they can add transformed coordinates to their shader code.
+     */
+    typedef GrShaderVar TransformedCoords;
+    typedef SkTArray<GrShaderVar> TransformedCoordsArray;
+
+    /**
+     * Passed to GrGLProcessors so they can add texture reads to their shader code.
+     */
+    class TextureSampler {
+    public:
+        TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
+            : fSamplerUniform(uniform)
+            , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
+            SkASSERT(0 != fConfigComponentMask);
+            memcpy(fSwizzle, access.getSwizzle(), 5);
+        }
+
+        // bitfield of GrColorComponentFlags present in the texture's config.
+        uint32_t configComponentMask() const { return fConfigComponentMask; }
+        // this is .abcd
+        const char* swizzle() const { return fSwizzle; }
+
+    private:
+        UniformHandle fSamplerUniform;
+        uint32_t      fConfigComponentMask;
+        char          fSwizzle[5];
+
+        friend class GrGLShaderBuilder;
+    };
+
+    typedef SkTArray<TextureSampler> TextureSamplerArray;
+
+    virtual ~GrGLProcessor() {}
+
+    /** A GrGLProcessor instance can be reused with any GrProcessor that produces the same stage
+        key; this function reads data from a GrProcessor and uploads any uniform variables required
+        by the shaders created in emitCode(). The GrProcessor installed in the GrDrawEffect is
+        guaranteed to be of the same type that created this GrGLProcessor and to have an identical
+        effect key as the one that created this GrGLProcessor. Effects that use local coords have
+        to consider whether the GrProcessorStage's coord change matrix should be used. When explicit
+        local coordinates are used it can be ignored. */
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) {}
+
+    const char* name() const { return fFactory.name(); }
+
+    static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
+
+protected:
+    const GrBackendProcessorFactory& fFactory;
+};
+
+class GrGLFragmentProcessor : public GrGLProcessor {
+public:
+    GrGLFragmentProcessor(const GrBackendProcessorFactory& factory)
+        : INHERITED(factory) {
+    }
+
+    virtual ~GrGLFragmentProcessor() {}
+
+    /** Called when the program stage should insert its code into the shaders. The code in each
+        shader will be in its own block ({}) and so locally scoped names will not collide across
+        stages.
+
+        @param builder      Interface used to emit code in the shaders.
+        @param effect       The effect that generated this program stage.
+        @param key          The key that was computed by GenKey() from the generating GrProcessor.
+        @param outputColor  A predefined vec4 in the FS in which the stage should place its output
+                            color (or coverage).
+        @param inputColor   A vec4 that holds the input color to the stage in the FS. This may be
+                            NULL in which case the implied input is solid white (all ones).
+                            TODO: Better system for communicating optimization info (e.g. input
+                            color is solid white, trans black, known to be opaque, etc.) that allows
+                            the effect to communicate back similar known info about its output.
+        @param samplers     Contains one entry for each GrTextureAccess of the GrProcessor. These
+                            can be passed to the builder to emit texture reads in the generated
+                            code.
+        */
+    virtual void emitCode(GrGLProgramBuilder* builder,
+                          const GrFragmentProcessor& effect,
+                          const GrProcessorKey& key,
+                          const char* outputColor,
+                          const char* inputColor,
+                          const TransformedCoordsArray& coords,
+                          const TextureSamplerArray& samplers) = 0;
+
+private:
+    typedef GrGLProcessor INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 435d0cd..aae9bd8 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -7,14 +7,17 @@
 
 #include "GrGLProgram.h"
 
+#include "builders/GrGLFullProgramBuilder.h"
+#include "builders/GrGLFragmentOnlyProgramBuilder.h"
 #include "GrAllocator.h"
-#include "GrEffect.h"
+#include "GrProcessor.h"
 #include "GrCoordTransform.h"
-#include "GrDrawEffect.h"
-#include "GrGLEffect.h"
+#include "GrGLProcessor.h"
 #include "GrGpuGL.h"
+#include "GrGLPathRendering.h"
 #include "GrGLShaderVar.h"
 #include "GrGLSL.h"
+#include "GrOptDrawState.h"
 #include "SkXfermode.h"
 
 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
@@ -22,139 +25,126 @@
 
 GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
                                  const GrGLProgramDesc& desc,
-                                 const GrEffectStage* colorStages[],
-                                 const GrEffectStage* coverageStages[]) {
-    GrGLShaderBuilder::GenProgramOutput output;
-    SkAutoTUnref<GrGLUniformManager> uman(SkNEW_ARGS(GrGLUniformManager, (gpu)));
-    if (GrGLShaderBuilder::GenProgram(gpu, uman, desc, colorStages, coverageStages,
-                                      &output)) {
-        SkASSERT(0 != output.fProgramID);
-        return SkNEW_ARGS(GrGLProgram, (gpu, desc, uman, output));
+                                 const GrGeometryStage* geometryProcessor,
+                                 const GrFragmentStage* colorStages[],
+                                 const GrFragmentStage* coverageStages[]) {
+    SkAutoTDelete<GrGLProgramBuilder> builder;
+    if (desc.getHeader().fUseFragShaderOnly) {
+        SkASSERT(gpu->glCaps().pathRenderingSupport());
+        SkASSERT(gpu->glPathRendering()->texturingMode() ==
+                 GrGLPathRendering::FixedFunction_TexturingMode);
+        SkASSERT(NULL == geometryProcessor);
+        builder.reset(SkNEW_ARGS(GrGLFragmentOnlyProgramBuilder, (gpu, desc)));
+    } else {
+        builder.reset(SkNEW_ARGS(GrGLFullProgramBuilder, (gpu, desc)));
+    }
+    if (builder->genProgram(geometryProcessor, colorStages, coverageStages)) {
+        SkASSERT(0 != builder->getProgramID());
+        return SkNEW_ARGS(GrGLProgram, (gpu, desc, *builder));
     }
     return NULL;
 }
 
 GrGLProgram::GrGLProgram(GrGpuGL* gpu,
                          const GrGLProgramDesc& desc,
-                         GrGLUniformManager* uman,
-                         const GrGLShaderBuilder::GenProgramOutput& builderOutput)
+                         const GrGLProgramBuilder& builder)
     : fColor(GrColor_ILLEGAL)
     , fCoverage(GrColor_ILLEGAL)
     , fDstCopyTexUnit(-1)
-    , fBuilderOutput(builderOutput)
+    , fBuiltinUniformHandles(builder.getBuiltinUniformHandles())
+    , fGeometryProcessor(SkSafeRef(builder.getGeometryProcessor()))
+    , fColorEffects(SkRef(builder.getColorEffects()))
+    , fCoverageEffects(SkRef(builder.getCoverageEffects()))
+    , fProgramID(builder.getProgramID())
+    , fHasVertexShader(builder.hasVertexShader())
+    , fTexCoordSetCnt(builder.getTexCoordSetCount())
     , fDesc(desc)
     , fGpu(gpu)
-    , fUniformManager(SkRef(uman)) {
+    , fProgramDataManager(gpu, this, builder) {
     this->initSamplerUniforms();
 }
 
 GrGLProgram::~GrGLProgram() {
-    if (fBuilderOutput.fProgramID) {
-        GL_CALL(DeleteProgram(fBuilderOutput.fProgramID));
+    if (fProgramID) {
+        GL_CALL(DeleteProgram(fProgramID));
     }
 }
 
 void GrGLProgram::abandon() {
-    fBuilderOutput.fProgramID = 0;
-}
-
-void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
-                                GrBlendCoeff* dstCoeff) const {
-    switch (fDesc.getHeader().fCoverageOutput) {
-        case GrGLProgramDesc::kModulate_CoverageOutput:
-            break;
-        // The prog will write a coverage value to the secondary
-        // output and the dst is blended by one minus that value.
-        case GrGLProgramDesc::kSecondaryCoverage_CoverageOutput:
-        case GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput:
-        case GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput:
-            *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
-            break;
-        case GrGLProgramDesc::kCombineWithDst_CoverageOutput:
-            // We should only have set this if the blend was specified as (1, 0)
-            SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *dstCoeff);
-            break;
-        default:
-            SkFAIL("Unexpected coverage output");
-            break;
-    }
+    fProgramID = 0;
 }
 
 void GrGLProgram::initSamplerUniforms() {
-    GL_CALL(UseProgram(fBuilderOutput.fProgramID));
+    GL_CALL(UseProgram(fProgramID));
     GrGLint texUnitIdx = 0;
-    if (fBuilderOutput.fUniformHandles.fDstCopySamplerUni.isValid()) {
-        fUniformManager->setSampler(fBuilderOutput.fUniformHandles.fDstCopySamplerUni, texUnitIdx);
+    if (fBuiltinUniformHandles.fDstCopySamplerUni.isValid()) {
+        fProgramDataManager.setSampler(fBuiltinUniformHandles.fDstCopySamplerUni, texUnitIdx);
         fDstCopyTexUnit = texUnitIdx++;
     }
-    fBuilderOutput.fColorEffects->initSamplers(*fUniformManager, &texUnitIdx);
-    fBuilderOutput.fCoverageEffects->initSamplers(*fUniformManager, &texUnitIdx);
+    if (fGeometryProcessor.get()) {
+        fGeometryProcessor->initSamplers(fProgramDataManager, &texUnitIdx);
+    }
+    fColorEffects->initSamplers(fProgramDataManager, &texUnitIdx);
+    fCoverageEffects->initSamplers(fProgramDataManager, &texUnitIdx);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
-                          const GrEffectStage* colorStages[],
-                          const GrEffectStage* coverageStages[],
+void GrGLProgram::setData(const GrOptDrawState& optState,
+                          GrGpu::DrawType drawType,
+                          const GrGeometryStage* geometryProcessor,
+                          const GrFragmentStage* colorStages[],
+                          const GrFragmentStage* coverageStages[],
                           const GrDeviceCoordTexture* dstCopy,
                           SharedGLState* sharedState) {
-    const GrDrawState& drawState = fGpu->getDrawState();
+    GrColor color = optState.getColor();
+    GrColor coverage = optState.getCoverageColor();
 
-    GrColor color;
-    GrColor coverage;
-    if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) {
-        color = 0;
-        coverage = 0;
-    } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
-        color = 0xffffffff;
-        coverage = drawState.getCoverageColor();
-    } else {
-        color = drawState.getColor();
-        coverage = drawState.getCoverageColor();
-    }
+    this->setColor(optState, color, sharedState);
+    this->setCoverage(optState, coverage, sharedState);
+    this->setMatrixAndRenderTargetHeight(drawType, optState);
 
-    this->setColor(drawState, color, sharedState);
-    this->setCoverage(drawState, coverage, sharedState);
-    this->setMatrixAndRenderTargetHeight(drawState);
-
-    if (NULL != dstCopy) {
-        if (fBuilderOutput.fUniformHandles.fDstCopyTopLeftUni.isValid()) {
-            fUniformManager->set2f(fBuilderOutput.fUniformHandles.fDstCopyTopLeftUni,
-                                   static_cast<GrGLfloat>(dstCopy->offset().fX),
-                                   static_cast<GrGLfloat>(dstCopy->offset().fY));
-            fUniformManager->set2f(fBuilderOutput.fUniformHandles.fDstCopyScaleUni,
-                                   1.f / dstCopy->texture()->width(),
-                                   1.f / dstCopy->texture()->height());
+    if (dstCopy) {
+        if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) {
+            fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyTopLeftUni,
+                                       static_cast<GrGLfloat>(dstCopy->offset().fX),
+                                       static_cast<GrGLfloat>(dstCopy->offset().fY));
+            fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyScaleUni,
+                                       1.f / dstCopy->texture()->width(),
+                                       1.f / dstCopy->texture()->height());
             GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture());
             static GrTextureParams kParams; // the default is clamp, nearest filtering.
             fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
         } else {
-            SkASSERT(!fBuilderOutput.fUniformHandles.fDstCopyScaleUni.isValid());
-            SkASSERT(!fBuilderOutput.fUniformHandles.fDstCopySamplerUni.isValid());
+            SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
+            SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
         }
     } else {
-        SkASSERT(!fBuilderOutput.fUniformHandles.fDstCopyTopLeftUni.isValid());
-        SkASSERT(!fBuilderOutput.fUniformHandles.fDstCopyScaleUni.isValid());
-        SkASSERT(!fBuilderOutput.fUniformHandles.fDstCopySamplerUni.isValid());
+        SkASSERT(!fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid());
+        SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
+        SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
     }
 
-    fBuilderOutput.fColorEffects->setData(fGpu, *fUniformManager, colorStages);
-    fBuilderOutput.fCoverageEffects->setData(fGpu, *fUniformManager, coverageStages);
-
+    if (fGeometryProcessor.get()) {
+        SkASSERT(geometryProcessor);
+        fGeometryProcessor->setData(fGpu, drawType, fProgramDataManager, geometryProcessor);
+    }
+    fColorEffects->setData(fGpu, drawType, fProgramDataManager, colorStages);
+    fCoverageEffects->setData(fGpu, drawType, fProgramDataManager, coverageStages);
 
     // PathTexGen state applies to the the fixed function vertex shader. For
     // custom shaders, it's ignored, so we don't need to change the texgen
     // settings in that case.
-    if (!fBuilderOutput.fHasVertexShader) {
-        fGpu->flushPathTexGenSettings(fBuilderOutput.fTexCoordSetCnt);
+    if (!fHasVertexShader) {
+        fGpu->glPathRendering()->flushPathTexGenSettings(fTexCoordSetCnt);
     }
 }
 
-void GrGLProgram::setColor(const GrDrawState& drawState,
+void GrGLProgram::setColor(const GrOptDrawState& optState,
                            GrColor color,
                            SharedGLState* sharedState) {
     const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
-    if (!drawState.hasColorVertexAttribute()) {
+    if (!optState.hasColorVertexAttribute()) {
         switch (header.fColorInput) {
             case GrGLProgramDesc::kAttribute_ColorInput:
                 SkASSERT(-1 != header.fColorAttributeIndex);
@@ -169,32 +159,31 @@
                 }
                 break;
             case GrGLProgramDesc::kUniform_ColorInput:
-                if (fColor != color && fBuilderOutput.fUniformHandles.fColorUni.isValid()) {
+                if (fColor != color && fBuiltinUniformHandles.fColorUni.isValid()) {
                     // OpenGL ES doesn't support unsigned byte varieties of glUniform
                     GrGLfloat c[4];
                     GrColorToRGBAFloat(color, c);
-                    fUniformManager->set4fv(fBuilderOutput.fUniformHandles.fColorUni, 1, c);
+                    fProgramDataManager.set4fv(fBuiltinUniformHandles.fColorUni, 1, c);
                     fColor = color;
                 }
                 sharedState->fConstAttribColorIndex = -1;
                 break;
-            case GrGLProgramDesc::kSolidWhite_ColorInput:
-            case GrGLProgramDesc::kTransBlack_ColorInput:
+            case GrGLProgramDesc::kAllOnes_ColorInput:
                 sharedState->fConstAttribColorIndex = -1;
                 break;
             default:
-                SkFAIL("Unknown color type.");
+                SkFAIL("Unexpected color type.");
         }
     } else {
         sharedState->fConstAttribColorIndex = -1;
     }
 }
 
-void GrGLProgram::setCoverage(const GrDrawState& drawState,
+void GrGLProgram::setCoverage(const GrOptDrawState& optState,
                               GrColor coverage,
                               SharedGLState* sharedState) {
     const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
-    if (!drawState.hasCoverageVertexAttribute()) {
+    if (!optState.hasCoverageVertexAttribute()) {
         switch (header.fCoverageInput) {
             case GrGLProgramDesc::kAttribute_ColorInput:
                 if (sharedState->fConstAttribCoverage != coverage ||
@@ -212,54 +201,52 @@
                     // OpenGL ES doesn't support unsigned byte varieties of glUniform
                     GrGLfloat c[4];
                     GrColorToRGBAFloat(coverage, c);
-                    fUniformManager->set4fv(fBuilderOutput.fUniformHandles.fCoverageUni, 1, c);
+                    fProgramDataManager.set4fv(fBuiltinUniformHandles.fCoverageUni, 1, c);
                     fCoverage = coverage;
                 }
                 sharedState->fConstAttribCoverageIndex = -1;
                 break;
-            case GrGLProgramDesc::kSolidWhite_ColorInput:
-            case GrGLProgramDesc::kTransBlack_ColorInput:
+            case GrGLProgramDesc::kAllOnes_ColorInput:
                 sharedState->fConstAttribCoverageIndex = -1;
                 break;
             default:
-                SkFAIL("Unknown coverage type.");
+                SkFAIL("Unexpected coverage type.");
         }
     } else {
         sharedState->fConstAttribCoverageIndex = -1;
     }
 }
 
-void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) {
-    const GrRenderTarget* rt = drawState.getRenderTarget();
+void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
+                                                 const GrOptDrawState& optState) {
+    const GrRenderTarget* rt = optState.getRenderTarget();
     SkISize size;
     size.set(rt->width(), rt->height());
 
     // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
-    if (fBuilderOutput.fUniformHandles.fRTHeightUni.isValid() &&
+    if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
         fMatrixState.fRenderTargetSize.fHeight != size.fHeight) {
-        fUniformManager->set1f(fBuilderOutput.fUniformHandles.fRTHeightUni,
-                               SkIntToScalar(size.fHeight));
+        fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni,
+                                   SkIntToScalar(size.fHeight));
     }
 
-    if (!fBuilderOutput.fHasVertexShader) {
-        SkASSERT(!fBuilderOutput.fUniformHandles.fViewMatrixUni.isValid());
-        SkASSERT(!fBuilderOutput.fUniformHandles.fRTAdjustmentUni.isValid());
-        fGpu->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
+    if (GrGpu::IsPathRenderingDrawType(drawType)) {
+        fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin());
     } else if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
                fMatrixState.fRenderTargetSize != size ||
-               !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix())) {
-        SkASSERT(fBuilderOutput.fUniformHandles.fViewMatrixUni.isValid());
+               !fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) {
+        SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid());
 
-        fMatrixState.fViewMatrix = drawState.getViewMatrix();
+        fMatrixState.fViewMatrix = optState.getViewMatrix();
         fMatrixState.fRenderTargetSize = size;
         fMatrixState.fRenderTargetOrigin = rt->origin();
 
         GrGLfloat viewMatrix[3 * 3];
         fMatrixState.getGLMatrix<3>(viewMatrix);
-        fUniformManager->setMatrix3f(fBuilderOutput.fUniformHandles.fViewMatrixUni, viewMatrix);
+        fProgramDataManager.setMatrix3f(fBuiltinUniformHandles.fViewMatrixUni, viewMatrix);
 
         GrGLfloat rtAdjustmentVec[4];
         fMatrixState.getRTAdjustmentVec(rtAdjustmentVec);
-        fUniformManager->set4fv(fBuilderOutput.fUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
+        fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
     }
 }
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 73a3239..ce7e6b0 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -9,21 +9,20 @@
 #ifndef GrGLProgram_DEFINED
 #define GrGLProgram_DEFINED
 
+#include "builders/GrGLProgramBuilder.h"
 #include "GrDrawState.h"
 #include "GrGLContext.h"
 #include "GrGLProgramDesc.h"
-#include "GrGLShaderBuilder.h"
 #include "GrGLSL.h"
 #include "GrGLTexture.h"
-#include "GrGLUniformManager.h"
+#include "GrGLProgramDataManager.h"
 
 #include "SkString.h"
 #include "SkXfermode.h"
 
-class GrBinHashKeyBuilder;
-class GrGLEffect;
+class GrGLProcessor;
 class GrGLProgramEffects;
-class GrGLShaderBuilder;
+class GrGLProgramBuilder;
 
 /**
  * This class manages a GPU program and records per-program information.
@@ -38,10 +37,13 @@
 public:
     SK_DECLARE_INST_COUNT(GrGLProgram)
 
+    typedef GrGLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
+
     static GrGLProgram* Create(GrGpuGL* gpu,
                                const GrGLProgramDesc& desc,
-                               const GrEffectStage* colorStages[],
-                               const GrEffectStage* coverageStages[]);
+                               const GrGeometryStage* geometryProcessor,
+                               const GrFragmentStage* colorStages[],
+                               const GrFragmentStage* coverageStages[]);
 
     virtual ~GrGLProgram();
 
@@ -50,19 +52,14 @@
      */
     void abandon();
 
-    /**
-     * The shader may modify the blend coefficients. Params are in/out.
-     */
-    void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
-
     const GrGLProgramDesc& getDesc() { return fDesc; }
 
     /**
      * Gets the GL program ID for this program.
      */
-    GrGLuint programID() const { return fBuilderOutput.fProgramID; }
+    GrGLuint programID() const { return fProgramID; }
 
-    bool hasVertexShader() const { return fBuilderOutput.fHasVertexShader; }
+    bool hasVertexShader() const { return fHasVertexShader; }
 
     /**
      * Some GL state that is relevant to programs is not stored per-program. In particular color
@@ -150,38 +147,39 @@
     };
 
     /**
-     * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a
+     * This function uploads uniforms and calls each GrGLProcessor's setData. It is called before a
      * draw occurs using the program after the program has already been bound. It also uses the
-     * GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage
+     * GrGpuGL object to bind the textures required by the GrGLProcessors. The color and coverage
      * stages come from GrGLProgramDesc::Build().
      */
-    void setData(GrDrawState::BlendOptFlags,
-                 const GrEffectStage* colorStages[],
-                 const GrEffectStage* coverageStages[],
+    void setData(const GrOptDrawState&,
+                 GrGpu::DrawType,
+                 const GrGeometryStage* geometryProcessor,
+                 const GrFragmentStage* colorStages[],
+                 const GrFragmentStage* coverageStages[],
                  const GrDeviceCoordTexture* dstCopy, // can be NULL
                  SharedGLState*);
 
 private:
-    typedef GrGLUniformManager::UniformHandle UniformHandle;
+    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 
     GrGLProgram(GrGpuGL*,
                 const GrGLProgramDesc&,
-                GrGLUniformManager*,
-                const GrGLShaderBuilder::GenProgramOutput&);
+                const GrGLProgramBuilder&);
 
     // Sets the texture units for samplers.
     void initSamplerUniforms();
 
     // Helper for setData(). Makes GL calls to specify the initial color when there is not
     // per-vertex colors.
-    void setColor(const GrDrawState&, GrColor color, SharedGLState*);
+    void setColor(const GrOptDrawState&, GrColor color, SharedGLState*);
 
     // Helper for setData(). Makes GL calls to specify the initial coverage when there is not
     // per-vertex coverages.
-    void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*);
+    void setCoverage(const GrOptDrawState&, GrColor coverage, SharedGLState*);
 
     // Helper for setData() that sets the view matrix and loads the render target height uniform
-    void setMatrixAndRenderTargetHeight(const GrDrawState&);
+    void setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState&);
 
     // these reflect the current values of uniforms (GL uniform values travel with program)
     MatrixState                         fMatrixState;
@@ -189,12 +187,18 @@
     GrColor                             fCoverage;
     int                                 fDstCopyTexUnit;
 
-    GrGLShaderBuilder::GenProgramOutput fBuilderOutput;
+    BuiltinUniformHandles               fBuiltinUniformHandles;
+    SkAutoTUnref<GrGLProgramEffects>    fGeometryProcessor;
+    SkAutoTUnref<GrGLProgramEffects>    fColorEffects;
+    SkAutoTUnref<GrGLProgramEffects>    fCoverageEffects;
+    GrGLuint                            fProgramID;
+    bool                                fHasVertexShader;
+    int                                 fTexCoordSetCnt;
 
     GrGLProgramDesc                     fDesc;
     GrGpuGL*                            fGpu;
 
-    SkAutoTUnref<GrGLUniformManager>    fUniformManager;
+    GrGLProgramDataManager              fProgramDataManager;
 
     typedef SkRefCnt INHERITED;
 };
diff --git a/src/gpu/gl/GrGLUniformManager.cpp b/src/gpu/gl/GrGLProgramDataManager.cpp
similarity index 61%
rename from src/gpu/gl/GrGLUniformManager.cpp
rename to src/gpu/gl/GrGLProgramDataManager.cpp
index 29679aa..c53abd7 100644
--- a/src/gpu/gl/GrGLUniformManager.cpp
+++ b/src/gpu/gl/GrGLProgramDataManager.cpp
@@ -5,7 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "gl/GrGLShaderBuilder.h"
+#include "gl/builders/GrGLProgramBuilder.h"
+#include "gl/GrGLPathRendering.h"
 #include "gl/GrGLProgram.h"
 #include "gl/GrGLUniformHandle.h"
 #include "gl/GrGpuGL.h"
@@ -15,24 +16,52 @@
          SkASSERT(arrayCount <= uni.fArrayCount || \
                   (1 == arrayCount && GrGLShaderVar::kNonArray == uni.fArrayCount))
 
-GrGLUniformManager::GrGLUniformManager(GrGpuGL* gpu) : fGpu(gpu) {
-    // skbug.com/2056
-    fUsingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
+GrGLProgramDataManager::GrGLProgramDataManager(GrGpuGL* gpu,
+                                               GrGLProgram* program,
+                                               const GrGLProgramBuilder& builder)
+    : fGpu(gpu),
+      fProgram(program) {
+    int count = builder.getUniformInfos().count();
+    fUniforms.push_back_n(count);
+    for (int i = 0; i < count; i++) {
+        Uniform& uniform = fUniforms[i];
+        const GrGLProgramBuilder::UniformInfo& builderUniform = builder.getUniformInfos()[i];
+        SkASSERT(GrGLShaderVar::kNonArray == builderUniform.fVariable.getArrayCount() ||
+                 builderUniform.fVariable.getArrayCount() > 0);
+        SkDEBUGCODE(
+            uniform.fArrayCount = builderUniform.fVariable.getArrayCount();
+            uniform.fType = builderUniform.fVariable.getType();
+        );
+        // TODO: Move the Xoom uniform array in both FS and VS bug workaround here.
+
+        if (GrGLProgramBuilder::kVertex_Visibility & builderUniform.fVisibility) {
+            uniform.fVSLocation = builderUniform.fLocation;
+        } else {
+            uniform.fVSLocation = kUnusedUniform;
+            }
+        if (GrGLProgramBuilder::kFragment_Visibility & builderUniform.fVisibility) {
+            uniform.fFSLocation = builderUniform.fLocation;
+        } else {
+            uniform.fFSLocation = kUnusedUniform;
+        }
+    }
+
+    count = builder.getSeparableVaryingInfos().count();
+    fVaryings.push_back_n(count);
+    for (int i = 0; i < count; i++) {
+        Varying& varying = fVaryings[i];
+        const GrGLProgramBuilder::SeparableVaryingInfo& builderVarying =
+            builder.getSeparableVaryingInfos()[i];
+        SkASSERT(GrGLShaderVar::kNonArray == builderVarying.fVariable.getArrayCount());
+        SkDEBUGCODE(
+            varying.fType = builderVarying.fVariable.getType();
+        );
+        varying.fLocation = builderVarying.fLocation;
+    }
 }
 
-GrGLUniformManager::UniformHandle GrGLUniformManager::appendUniform(GrSLType type, int arrayCount) {
-    int idx = fUniforms.count();
-    Uniform& uni = fUniforms.push_back();
-    SkASSERT(GrGLShaderVar::kNonArray == arrayCount || arrayCount > 0);
-    uni.fArrayCount = arrayCount;
-    uni.fType = type;
-    uni.fVSLocation = kUnusedUniform;
-    uni.fFSLocation = kUnusedUniform;
-    return GrGLUniformManager::UniformHandle::CreateFromUniformIndex(idx);
-}
-
-void GrGLUniformManager::setSampler(UniformHandle u, GrGLint texUnit) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::setSampler(UniformHandle u, GrGLint texUnit) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kSampler2D_GrSLType);
     SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount);
     // FIXME: We still insert a single sampler uniform for every stage. If the shader does not
@@ -47,8 +76,8 @@
     }
 }
 
-void GrGLUniformManager::set1f(UniformHandle u, GrGLfloat v0) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::set1f(UniformHandle u, GrGLfloat v0) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kFloat_GrSLType);
     SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount);
     SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
@@ -60,10 +89,10 @@
     }
 }
 
-void GrGLUniformManager::set1fv(UniformHandle u,
-                                int arrayCount,
-                                const GrGLfloat v[]) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::set1fv(UniformHandle u,
+                                    int arrayCount,
+                                    const GrGLfloat v[]) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kFloat_GrSLType);
     SkASSERT(arrayCount > 0);
     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
@@ -79,8 +108,8 @@
     }
 }
 
-void GrGLUniformManager::set2f(UniformHandle u, GrGLfloat v0, GrGLfloat v1) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::set2f(UniformHandle u, GrGLfloat v0, GrGLfloat v1) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kVec2f_GrSLType);
     SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount);
     SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
@@ -92,10 +121,10 @@
     }
 }
 
-void GrGLUniformManager::set2fv(UniformHandle u,
-                                int arrayCount,
-                                const GrGLfloat v[]) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::set2fv(UniformHandle u,
+                                    int arrayCount,
+                                    const GrGLfloat v[]) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kVec2f_GrSLType);
     SkASSERT(arrayCount > 0);
     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
@@ -108,8 +137,8 @@
     }
 }
 
-void GrGLUniformManager::set3f(UniformHandle u, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::set3f(UniformHandle u, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kVec3f_GrSLType);
     SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount);
     SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
@@ -121,10 +150,10 @@
     }
 }
 
-void GrGLUniformManager::set3fv(UniformHandle u,
-                                int arrayCount,
-                                const GrGLfloat v[]) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::set3fv(UniformHandle u,
+                                    int arrayCount,
+                                    const GrGLfloat v[]) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kVec3f_GrSLType);
     SkASSERT(arrayCount > 0);
     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
@@ -137,12 +166,12 @@
     }
 }
 
-void GrGLUniformManager::set4f(UniformHandle u,
-                               GrGLfloat v0,
-                               GrGLfloat v1,
-                               GrGLfloat v2,
-                               GrGLfloat v3) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::set4f(UniformHandle u,
+                                   GrGLfloat v0,
+                                   GrGLfloat v1,
+                                   GrGLfloat v2,
+                                   GrGLfloat v3) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kVec4f_GrSLType);
     SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount);
     SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
@@ -154,10 +183,10 @@
     }
 }
 
-void GrGLUniformManager::set4fv(UniformHandle u,
-                                int arrayCount,
-                                const GrGLfloat v[]) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::set4fv(UniformHandle u,
+                                    int arrayCount,
+                                    const GrGLfloat v[]) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kVec4f_GrSLType);
     SkASSERT(arrayCount > 0);
     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
@@ -170,8 +199,8 @@
     }
 }
 
-void GrGLUniformManager::setMatrix3f(UniformHandle u, const GrGLfloat matrix[]) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::setMatrix3f(UniformHandle u, const GrGLfloat matrix[]) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kMat33f_GrSLType);
     SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount);
     // TODO: Re-enable this assert once texture matrices aren't forced on all effects
@@ -184,8 +213,8 @@
     }
 }
 
-void GrGLUniformManager::setMatrix4f(UniformHandle u, const GrGLfloat matrix[]) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::setMatrix4f(UniformHandle u, const GrGLfloat matrix[]) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kMat44f_GrSLType);
     SkASSERT(GrGLShaderVar::kNonArray == uni.fArrayCount);
     SkASSERT(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
@@ -197,10 +226,10 @@
     }
 }
 
-void GrGLUniformManager::setMatrix3fv(UniformHandle u,
-                                      int arrayCount,
-                                      const GrGLfloat matrices[]) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::setMatrix3fv(UniformHandle u,
+                                          int arrayCount,
+                                          const GrGLfloat matrices[]) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kMat33f_GrSLType);
     SkASSERT(arrayCount > 0);
     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
@@ -215,10 +244,10 @@
     }
 }
 
-void GrGLUniformManager::setMatrix4fv(UniformHandle u,
-                                      int arrayCount,
-                                      const GrGLfloat matrices[]) const {
-    const Uniform& uni = fUniforms[u.toUniformIndex()];
+void GrGLProgramDataManager::setMatrix4fv(UniformHandle u,
+                                          int arrayCount,
+                                          const GrGLfloat matrices[]) const {
+    const Uniform& uni = fUniforms[u.toProgramDataIndex()];
     SkASSERT(uni.fType == kMat44f_GrSLType);
     SkASSERT(arrayCount > 0);
     ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
@@ -233,7 +262,7 @@
     }
 }
 
-void GrGLUniformManager::setSkMatrix(UniformHandle u, const SkMatrix& matrix) const {
+void GrGLProgramDataManager::setSkMatrix(UniformHandle u, const SkMatrix& matrix) const {
     GrGLfloat mt[] = {
         matrix.get(SkMatrix::kMScaleX),
         matrix.get(SkMatrix::kMSkewY),
@@ -248,33 +277,13 @@
     this->setMatrix3f(u, mt);
 }
 
-
-void GrGLUniformManager::getUniformLocations(GrGLuint programID, const BuilderUniformArray& uniforms) {
-    SkASSERT(uniforms.count() == fUniforms.count());
-    int count = fUniforms.count();
-    for (int i = 0; i < count; ++i) {
-        SkASSERT(uniforms[i].fVariable.getType() == fUniforms[i].fType);
-        SkASSERT(uniforms[i].fVariable.getArrayCount() == fUniforms[i].fArrayCount);
-        GrGLint location;
-        // TODO: Move the Xoom uniform array in both FS and VS bug workaround here.
-        if (fUsingBindUniform) {
-            location = i;
-            GR_GL_CALL(fGpu->glInterface(),
-                       BindUniformLocation(programID, location, uniforms[i].fVariable.c_str()));
-        } else {
-            GR_GL_CALL_RET(fGpu->glInterface(), location,
-                       GetUniformLocation(programID, uniforms[i].fVariable.c_str()));
-        }
-        if (GrGLShaderBuilder::kVertex_Visibility & uniforms[i].fVisibility) {
-            fUniforms[i].fVSLocation = location;
-        }
-        if (GrGLShaderBuilder::kFragment_Visibility & uniforms[i].fVisibility) {
-            fUniforms[i].fFSLocation = location;
-        }
-    }
-}
-
-const GrGLUniformManager::BuilderUniform&
-GrGLUniformManager::getBuilderUniform(const BuilderUniformArray& array, UniformHandle handle) const {
-    return array[handle.toUniformIndex()];
+void GrGLProgramDataManager::setProgramPathFragmentInputTransform(VaryingHandle i,
+                                                                  unsigned components,
+                                                                  const SkMatrix& matrix) const {
+    const Varying& fragmentInput = fVaryings[i.toProgramDataIndex()];
+    fGpu->glPathRendering()->setProgramPathFragmentInputTransform(fProgram->programID(),
+                                                                  fragmentInput.fLocation,
+                                                                  GR_GL_OBJECT_LINEAR,
+                                                                  components,
+                                                                  matrix);
 }
diff --git a/src/gpu/gl/GrGLProgramDataManager.h b/src/gpu/gl/GrGLProgramDataManager.h
new file mode 100644
index 0000000..8a98a75
--- /dev/null
+++ b/src/gpu/gl/GrGLProgramDataManager.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLProgramDataManager_DEFINED
+#define GrGLProgramDataManager_DEFINED
+
+#include "gl/GrGLShaderVar.h"
+#include "gl/GrGLSL.h"
+#include "GrAllocator.h"
+
+#include "SkTArray.h"
+
+class GrGpuGL;
+class SkMatrix;
+class GrGLProgram;
+class GrGLProgramBuilder;
+
+/** Manages the resources used by a shader program.
+ * The resources are objects the program uses to communicate with the
+ * application code.
+ */
+class GrGLProgramDataManager : public SkRefCnt {
+public:
+    // Opaque handle to a uniform
+    class ShaderResourceHandle {
+    public:
+        bool isValid() const { return -1 != fValue; }
+        ShaderResourceHandle()
+            : fValue(-1) {
+        }
+    protected:
+        ShaderResourceHandle(int value)
+            : fValue(value) {
+            SkASSERT(isValid());
+        }
+        int fValue;
+    };
+
+    class UniformHandle : public ShaderResourceHandle {
+    public:
+        /** Creates a reference to an unifrom of a GrGLShaderBuilder.
+         * The ref can be used to set the uniform with corresponding the GrGLProgramDataManager.*/
+        static UniformHandle CreateFromUniformIndex(int i);
+        UniformHandle() { }
+        bool operator==(const UniformHandle& other) const { return other.fValue == fValue; }
+    private:
+        UniformHandle(int value) : ShaderResourceHandle(value) { }
+        int toProgramDataIndex() const { SkASSERT(isValid()); return fValue; }
+        int toShaderBuilderIndex() const { return toProgramDataIndex(); }
+
+        friend class GrGLProgramDataManager; // For accessing toProgramDataIndex().
+        friend class GrGLProgramBuilder; // For accessing toShaderBuilderIndex().
+    };
+
+    class VaryingHandle : public ShaderResourceHandle {
+    public:
+        /** Creates a reference to a varying in separable varyings of a GrGLShaderBuilder.
+         * The ref can be used to set the varying with the corresponding GrGLProgramDataManager.*/
+        static VaryingHandle CreateFromSeparableVaryingIndex(int i) {
+            return VaryingHandle(i);
+        }
+        VaryingHandle() { }
+        bool operator==(const VaryingHandle& other) const { return other.fValue == fValue; }
+    private:
+        VaryingHandle(int value) : ShaderResourceHandle(value) { }
+        int toProgramDataIndex() const { SkASSERT(isValid()); return fValue; }
+        friend class GrGLProgramDataManager; // For accessing toProgramDataIndex().
+    };
+
+    GrGLProgramDataManager(GrGpuGL*, GrGLProgram*, const GrGLProgramBuilder&);
+
+    /** Functions for uploading uniform values. The varities ending in v can be used to upload to an
+     *  array of uniforms. arrayCount must be <= the array count of the uniform.
+     */
+    void setSampler(UniformHandle, GrGLint texUnit) const;
+    void set1f(UniformHandle, GrGLfloat v0) const;
+    void set1fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
+    void set2f(UniformHandle, GrGLfloat, GrGLfloat) const;
+    void set2fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
+    void set3f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat) const;
+    void set3fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
+    void set4f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat, GrGLfloat) const;
+    void set4fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
+    // matrices are column-major, the first three upload a single matrix, the latter three upload
+    // arrayCount matrices into a uniform array.
+    void setMatrix3f(UniformHandle, const GrGLfloat matrix[]) const;
+    void setMatrix4f(UniformHandle, const GrGLfloat matrix[]) const;
+    void setMatrix3fv(UniformHandle, int arrayCount, const GrGLfloat matrices[]) const;
+    void setMatrix4fv(UniformHandle, int arrayCount, const GrGLfloat matrices[]) const;
+
+    // convenience method for uploading a SkMatrix to a 3x3 matrix uniform
+    void setSkMatrix(UniformHandle, const SkMatrix&) const;
+
+    void setProgramPathFragmentInputTransform(VaryingHandle i,
+                                              unsigned components,
+                                              const SkMatrix& matrix) const;
+
+private:
+    enum {
+        kUnusedUniform = -1,
+    };
+
+    struct Uniform {
+        GrGLint     fVSLocation;
+        GrGLint     fFSLocation;
+        SkDEBUGCODE(
+            GrSLType    fType;
+            int         fArrayCount;
+        );
+    };
+    struct Varying {
+        GrGLint     fLocation;
+        SkDEBUGCODE(
+            GrSLType    fType;
+        );
+    };
+
+    SkTArray<Uniform, true> fUniforms;
+    SkTArray<Varying, true> fVaryings;
+    GrGpuGL* fGpu;
+    GrGLProgram* fProgram;
+
+    typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index 4039eaf..19a26c9 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -5,136 +5,297 @@
  * found in the LICENSE file.
  */
 
+#include "gl/builders/GrGLProgramBuilder.h"
 #include "GrGLProgramDesc.h"
-#include "GrBackendEffectFactory.h"
-#include "GrDrawEffect.h"
-#include "GrEffect.h"
-#include "GrGLShaderBuilder.h"
+#include "GrBackendProcessorFactory.h"
+#include "GrProcessor.h"
 #include "GrGpuGL.h"
+#include "GrOptDrawState.h"
 
 #include "SkChecksum.h"
 
-namespace {
-inline GrGLEffect::EffectKey get_key_and_update_stats(const GrEffectStage& stage,
-                                                      const GrGLCaps& caps,
-                                                      bool useExplicitLocalCoords,
-                                                      bool* setTrueIfReadsDst,
-                                                      bool* setTrueIfReadsPos,
-                                                      bool* setTrueIfHasVertexCode) {
-    const GrEffectRef& effect = *stage.getEffect();
-    const GrBackendEffectFactory& factory = effect->getFactory();
-    GrDrawEffect drawEffect(stage, useExplicitLocalCoords);
-    if (effect->willReadDstColor()) {
-        *setTrueIfReadsDst = true;
+/**
+ * The key for an individual coord transform is made up of a matrix type and a bit that
+ * indicates the source of the input coords.
+ */
+enum {
+    kMatrixTypeKeyBits   = 1,
+    kMatrixTypeKeyMask   = (1 << kMatrixTypeKeyBits) - 1,
+    kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
+    kTransformKeyBits    = kMatrixTypeKeyBits + 1,
+};
+
+/**
+ * We specialize the vertex code for each of these matrix types.
+ */
+enum MatrixType {
+    kNoPersp_MatrixType  = 0,
+    kGeneral_MatrixType  = 1,
+};
+
+/**
+ * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are
+ * present in the texture's config. swizzleComponentMask indicates the channels present in the
+ * shader swizzle.
+ */
+static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
+                                             uint32_t configComponentMask,
+                                             uint32_t swizzleComponentMask) {
+    if (caps.textureSwizzleSupport()) {
+        // Any remapping is handled using texture swizzling not shader modifications.
+        return false;
     }
-    if (effect->willReadFragmentPosition()) {
-        *setTrueIfReadsPos = true;
+    // check if the texture is alpha-only
+    if (kA_GrColorComponentFlag == configComponentMask) {
+        if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) {
+            // we must map the swizzle 'a's to 'r'.
+            return true;
+        }
+        if (kRGB_GrColorComponentFlags & swizzleComponentMask) {
+            // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that
+            // alpha-only textures smear alpha across all four channels when read.
+            return true;
+        }
     }
-    if (effect->hasVertexCode()) {
-        *setTrueIfHasVertexCode = true;
-    }
-    return factory.glEffectKey(drawEffect, caps);
+    return false;
 }
+
+static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) {
+    uint32_t key = 0;
+
+    const GrGeometryProcessor::VertexAttribArray& vars = effect->getVertexAttribs();
+    int numAttributes = vars.count();
+    SkASSERT(numAttributes <= 2);
+    for (int a = 0; a < numAttributes; ++a) {
+        uint32_t value = 1 << a;
+        key |= value;
+    }
+    return key;
 }
-void GrGLProgramDesc::Build(const GrDrawState& drawState,
+
+static uint32_t gen_transform_key(const GrProcessorStage& effectStage,
+                                  bool useExplicitLocalCoords) {
+    uint32_t totalKey = 0;
+    int numTransforms = effectStage.getProcessor()->numTransforms();
+    for (int t = 0; t < numTransforms; ++t) {
+        uint32_t key = 0;
+        if (effectStage.isPerspectiveCoordTransform(t, useExplicitLocalCoords)) {
+            key |= kGeneral_MatrixType;
+        } else {
+            key |= kNoPersp_MatrixType;
+        }
+
+        const GrCoordTransform& coordTransform = effectStage.getProcessor()->coordTransform(t);
+        if (kLocal_GrCoordSet != coordTransform.sourceCoords() && useExplicitLocalCoords) {
+            key |= kPositionCoords_Flag;
+        }
+        key <<= kTransformKeyBits * t;
+        SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap
+        totalKey |= key;
+    }
+    return totalKey;
+}
+
+static uint32_t gen_texture_key(const GrProcessor* effect, const GrGLCaps& caps) {
+    uint32_t key = 0;
+    int numTextures = effect->numTextures();
+    for (int t = 0; t < numTextures; ++t) {
+        const GrTextureAccess& access = effect->textureAccess(t);
+        uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
+        if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
+            key |= 1 << t;
+        }
+    }
+    return key;
+}
+
+/**
+ * A function which emits a meta key into the key builder.  This is required because shader code may
+ * be dependent on properties of the effect that the effect itself doesn't use
+ * in its key (e.g. the pixel format of textures used). So we create a meta-key for
+ * every effect using this function. It is also responsible for inserting the effect's class ID
+ * which must be different for every GrProcessor subclass. It can fail if an effect uses too many
+ * textures, transforms, etc, for the space allotted in the meta-key.
+ */
+
+static uint32_t* get_processor_meta_key(const GrProcessorStage& processorStage,
+                                        bool useExplicitLocalCoords,
+                                        const GrGLCaps& caps,
+                                        GrProcessorKeyBuilder* b) {
+
+    uint32_t textureKey = gen_texture_key(processorStage.getProcessor(), caps);
+    uint32_t transformKey = gen_transform_key(processorStage,useExplicitLocalCoords);
+    uint32_t classID = processorStage.getProcessor()->getFactory().effectClassID();
+
+    // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
+    // don't fit.
+    static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
+    if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) {
+        return NULL;
+    }
+
+    uint32_t* key = b->add32n(2);
+    key[0] = (textureKey << 16 | transformKey);
+    key[1] = (classID << 16);
+    return key;
+}
+
+bool GrGLProgramDesc::GetProcessorKey(const GrProcessorStage& stage,
+                                      const GrGLCaps& caps,
+                                      bool useExplicitLocalCoords,
+                                      GrProcessorKeyBuilder* b,
+                                      uint16_t* processorKeySize) {
+    const GrProcessor& effect = *stage.getProcessor();
+    const GrBackendProcessorFactory& factory = effect.getFactory();
+    factory.getGLProcessorKey(effect, caps, b);
+    size_t size = b->size();
+    if (size > SK_MaxU16) {
+        *processorKeySize = 0; // suppresses a warning.
+        return false;
+    }
+    *processorKeySize = SkToU16(size);
+    if (NULL == get_processor_meta_key(stage, useExplicitLocalCoords, caps, b)) {
+        return false;
+    }
+    return true;
+}
+
+bool GrGLProgramDesc::GetGeometryProcessorKey(const GrGeometryStage& stage,
+                                              const GrGLCaps& caps,
+                                              bool useExplicitLocalCoords,
+                                              GrProcessorKeyBuilder* b,
+                                              uint16_t* processorKeySize) {
+    const GrProcessor& effect = *stage.getProcessor();
+    const GrBackendProcessorFactory& factory = effect.getFactory();
+    factory.getGLProcessorKey(effect, caps, b);
+    size_t size = b->size();
+    if (size > SK_MaxU16) {
+        *processorKeySize = 0; // suppresses a warning.
+        return false;
+    }
+    *processorKeySize = SkToU16(size);
+    uint32_t* key = get_processor_meta_key(stage, useExplicitLocalCoords, caps, b);
+    if (NULL == key) {
+        return false;
+    }
+    uint32_t attribKey = gen_attrib_key(stage.getGeometryProcessor());
+
+    // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
+    // don't fit.
+    static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
+    if ((attribKey) & kMetaKeyInvalidMask) {
+       return false;
+    }
+
+    key[1] |= attribKey;
+    return true;
+}
+
+
+bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
                             GrGpu::DrawType drawType,
-                            GrDrawState::BlendOptFlags blendOpts,
                             GrBlendCoeff srcCoeff,
                             GrBlendCoeff dstCoeff,
-                            const GrGpuGL* gpu,
+                            GrGpuGL* gpu,
                             const GrDeviceCoordTexture* dstCopy,
-                            SkTArray<const GrEffectStage*, true>* colorStages,
-                            SkTArray<const GrEffectStage*, true>* coverageStages,
+                            const GrGeometryStage** geometryProcessor,
+                            SkTArray<const GrFragmentStage*, true>* colorStages,
+                            SkTArray<const GrFragmentStage*, true>* coverageStages,
                             GrGLProgramDesc* desc) {
     colorStages->reset();
     coverageStages->reset();
 
-    // This should already have been caught
-    SkASSERT(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts));
-
-    bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
-
-    bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag |
-                                           GrDrawState::kEmitCoverage_BlendOptFlag));
-    int firstEffectiveColorStage = 0;
-    bool inputColorIsUsed = true;
-    if (!skipColor) {
-        firstEffectiveColorStage = drawState.numColorStages();
-        while (firstEffectiveColorStage > 0 && inputColorIsUsed) {
-            --firstEffectiveColorStage;
-            const GrEffect* effect = drawState.getColorStage(firstEffectiveColorStage).getEffect()->get();
-            inputColorIsUsed = effect->willUseInputColor();
-        }
-    }
-
-    int firstEffectiveCoverageStage = 0;
-    bool inputCoverageIsUsed = true;
-    if (!skipCoverage) {
-        firstEffectiveCoverageStage = drawState.numCoverageStages();
-        while (firstEffectiveCoverageStage > 0 && inputCoverageIsUsed) {
-            --firstEffectiveCoverageStage;
-            const GrEffect* effect = drawState.getCoverageStage(firstEffectiveCoverageStage).getEffect()->get();
-            inputCoverageIsUsed = effect->willUseInputColor();
-        }
-    }
+    bool inputColorIsUsed = optState.inputColorIsUsed();
+    bool inputCoverageIsUsed = optState.inputCoverageIsUsed();
 
     // The descriptor is used as a cache key. Thus when a field of the
     // descriptor will not affect program generation (because of the attribute
     // bindings in use or other descriptor field settings) it should be set
     // to a canonical value to avoid duplicate programs with different keys.
 
-    bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute();
-    bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAttribute();
-    // we only need the local coords if we're actually going to generate effect code
-    bool requiresLocalCoordAttrib = !(skipCoverage  && skipColor) &&
-                                    drawState.hasLocalCoordAttribute();
+    bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib();
 
-    bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
-    bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) ||
-                             (!requiresColorAttrib && 0xffffffff == drawState.getColor()) ||
-                             (!inputColorIsUsed);
+    int numStages = optState.numTotalStages();
 
-    int numEffects = (skipColor ? 0 : (drawState.numColorStages() - firstEffectiveColorStage)) +
-                     (skipCoverage ? 0 : (drawState.numCoverageStages() - firstEffectiveCoverageStage));
+    GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t));
+    // Make room for everything up to and including the array of offsets to effect keys.
+    desc->fKey.reset();
+    desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * numStages);
 
-    size_t newKeyLength = KeyLength(numEffects);
-    bool allocChanged;
-    desc->fKey.reset(newKeyLength, SkAutoMalloc::kAlloc_OnShrink, &allocChanged);
-    if (allocChanged || !desc->fInitialized) {
-        // make sure any padding in the header is zero if we we haven't used this allocation before.
-        memset(desc->header(), 0, kHeaderSize);
-    }
-    // write the key length
-    *desc->atOffset<uint32_t, kLengthOffset>() = SkToU32(newKeyLength);
+    int offsetAndSizeIndex = 0;
 
     KeyHeader* header = desc->header();
-    EffectKey* effectKeys = desc->effectKeys();
+    // make sure any padding in the header is zeroed.
+    memset(desc->header(), 0, kHeaderSize);
 
-    int currEffectKey = 0;
-    bool readsDst = false;
-    bool readFragPosition = false;
-    // We use vertexshader-less shader programs only when drawing paths.
-    bool hasVertexCode = !(GrGpu::kDrawPath_DrawType == drawType ||
-                           GrGpu::kDrawPaths_DrawType == drawType);
+    // We can only have one effect which touches the vertex shader
+    if (optState.hasGeometryProcessor()) {
+        uint16_t* offsetAndSize =
+                reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
+                                            offsetAndSizeIndex * 2 * sizeof(uint16_t));
 
-    if (!skipColor) {
-        for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
-            effectKeys[currEffectKey++] =
-                get_key_and_update_stats(drawState.getColorStage(s), gpu->glCaps(),
-                                         requiresLocalCoordAttrib, &readsDst, &readFragPosition,
-                                         &hasVertexCode);
+        GrProcessorKeyBuilder b(&desc->fKey);
+        uint16_t processorKeySize;
+        uint32_t processorOffset = desc->fKey.count();
+        const GrGeometryStage& gpStage = *optState.getGeometryProcessor();
+        if (processorOffset > SK_MaxU16 ||
+                !GetGeometryProcessorKey(gpStage, gpu->glCaps(), requiresLocalCoordAttrib, &b,
+                                         &processorKeySize)) {
+            desc->fKey.reset();
+            return false;
         }
-    }
-    if (!skipCoverage) {
-        for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) {
-            effectKeys[currEffectKey++] =
-                get_key_and_update_stats(drawState.getCoverageStage(s), gpu->glCaps(),
-                                         requiresLocalCoordAttrib, &readsDst, &readFragPosition,
-                                         &hasVertexCode);
-        }
+
+        offsetAndSize[0] = SkToU16(processorOffset);
+        offsetAndSize[1] = processorKeySize;
+        ++offsetAndSizeIndex;
+        *geometryProcessor = &gpStage;
+        header->fHasGeometryProcessor = true;
     }
 
-    header->fHasVertexCode = hasVertexCode || requiresLocalCoordAttrib;
+    for (int s = 0; s < optState.numColorStages(); ++s) {
+        uint16_t* offsetAndSize =
+            reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
+                                        offsetAndSizeIndex * 2 * sizeof(uint16_t));
+
+        GrProcessorKeyBuilder b(&desc->fKey);
+        uint16_t processorKeySize;
+        uint32_t processorOffset = desc->fKey.count();
+        if (processorOffset > SK_MaxU16 ||
+                !GetProcessorKey(optState.getColorStage(s), gpu->glCaps(),
+                                 requiresLocalCoordAttrib, &b, &processorKeySize)) {
+            desc->fKey.reset();
+            return false;
+        }
+
+        offsetAndSize[0] = SkToU16(processorOffset);
+        offsetAndSize[1] = processorKeySize;
+        ++offsetAndSizeIndex;
+    }
+
+    for (int s = 0; s < optState.numCoverageStages(); ++s) {
+        uint16_t* offsetAndSize =
+            reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
+                                        offsetAndSizeIndex * 2 * sizeof(uint16_t));
+
+        GrProcessorKeyBuilder b(&desc->fKey);
+        uint16_t processorKeySize;
+        uint32_t processorOffset = desc->fKey.count();
+        if (processorOffset > SK_MaxU16 ||
+                !GetProcessorKey(optState.getCoverageStage(s), gpu->glCaps(),
+                                 requiresLocalCoordAttrib, &b, &processorKeySize)) {
+            desc->fKey.reset();
+            return false;
+        }
+
+        offsetAndSize[0] = SkToU16(processorOffset);
+        offsetAndSize[1] = processorKeySize;
+        ++offsetAndSizeIndex;
+    }
+
+    // Because header is a pointer into the dynamic array, we can't push any new data into the key
+    // below here.
+
+
     header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType;
 
     // Currently the experimental GS will only work with triangle prims (and it doesn't do anything
@@ -146,59 +307,68 @@
     header->fExperimentalGS = false;
 #endif
 #endif
-    bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->pathRenderingSupport();
 
-    if (colorIsTransBlack) {
-        header->fColorInput = kTransBlack_ColorInput;
-    } else if (colorIsSolidWhite) {
-        header->fColorInput = kSolidWhite_ColorInput;
-    } else if (defaultToUniformInputs && !requiresColorAttrib) {
+    if (gpu->caps()->pathRenderingSupport() &&
+        GrGpu::IsPathRenderingDrawType(drawType) &&
+        gpu->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunction_TexturingMode) {
+        header->fUseFragShaderOnly = true;
+        SkASSERT(!optState.hasGeometryProcessor());
+    } else {
+        header->fUseFragShaderOnly = false;
+    }
+
+    bool defaultToUniformInputs = GrGpu::IsPathRenderingDrawType(drawType) ||
+                                  GR_GL_NO_CONSTANT_ATTRIBUTES;
+
+    if (!inputColorIsUsed) {
+        header->fColorInput = kAllOnes_ColorInput;
+    } else if (defaultToUniformInputs && !optState.hasColorVertexAttribute()) {
         header->fColorInput = kUniform_ColorInput;
     } else {
         header->fColorInput = kAttribute_ColorInput;
-        header->fHasVertexCode = true;
+        SkASSERT(!header->fUseFragShaderOnly);
     }
 
-    bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor();
+    bool covIsSolidWhite = !optState.hasCoverageVertexAttribute() &&
+                           0xffffffff == optState.getCoverageColor();
 
-    if (skipCoverage) {
-        header->fCoverageInput = kTransBlack_ColorInput;
-    } else if (covIsSolidWhite || !inputCoverageIsUsed) {
-        header->fCoverageInput = kSolidWhite_ColorInput;
-    } else if (defaultToUniformInputs && !requiresCoverageAttrib) {
+    if (covIsSolidWhite || !inputCoverageIsUsed) {
+        header->fCoverageInput = kAllOnes_ColorInput;
+    } else if (defaultToUniformInputs && !optState.hasCoverageVertexAttribute()) {
         header->fCoverageInput = kUniform_ColorInput;
     } else {
         header->fCoverageInput = kAttribute_ColorInput;
-        header->fHasVertexCode = true;
+        SkASSERT(!header->fUseFragShaderOnly);
     }
 
-    if (readsDst) {
-        SkASSERT(NULL != dstCopy || gpu->caps()->dstReadInShaderSupport());
+    if (optState.readsDst()) {
+        SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport());
         const GrTexture* dstCopyTexture = NULL;
-        if (NULL != dstCopy) {
+        if (dstCopy) {
             dstCopyTexture = dstCopy->texture();
         }
-        header->fDstReadKey = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps());
+        header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
+                gpu->glCaps());
         SkASSERT(0 != header->fDstReadKey);
     } else {
         header->fDstReadKey = 0;
     }
 
-    if (readFragPosition) {
-        header->fFragPosKey = GrGLShaderBuilder::KeyForFragmentPosition(drawState.getRenderTarget(),
-                                                                      gpu->glCaps());
+    if (optState.readsFragPosition()) {
+        header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(
+                optState.getRenderTarget(), gpu->glCaps());
     } else {
         header->fFragPosKey = 0;
     }
 
     // Record attribute indices
-    header->fPositionAttributeIndex = drawState.positionAttributeIndex();
-    header->fLocalCoordAttributeIndex = drawState.localCoordAttributeIndex();
+    header->fPositionAttributeIndex = optState.positionAttributeIndex();
+    header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex();
 
     // For constant color and coverage we need an attribute with an index beyond those already set
-    int availableAttributeIndex = drawState.getVertexAttribCount();
-    if (requiresColorAttrib) {
-        header->fColorAttributeIndex = drawState.colorVertexAttributeIndex();
+    int availableAttributeIndex = optState.getVertexAttribCount();
+    if (optState.hasColorVertexAttribute()) {
+        header->fColorAttributeIndex = optState.colorVertexAttributeIndex();
     } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) {
         SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
         header->fColorAttributeIndex = availableAttributeIndex;
@@ -207,8 +377,8 @@
         header->fColorAttributeIndex = -1;
     }
 
-    if (requiresCoverageAttrib) {
-        header->fCoverageAttributeIndex = drawState.coverageVertexAttributeIndex();
+    if (optState.hasCoverageVertexAttribute()) {
+        header->fCoverageAttributeIndex = optState.coverageVertexAttributeIndex();
     } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
         SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
         header->fCoverageAttributeIndex = availableAttributeIndex;
@@ -216,70 +386,36 @@
         header->fCoverageAttributeIndex = -1;
     }
 
-    // Here we deal with whether/how we handle color and coverage separately.
+    header->fPrimaryOutputType = optState.getPrimaryOutputType();
+    header->fSecondaryOutputType = optState.getSecondaryOutputType();
 
-    // Set this default and then possibly change our mind if there is coverage.
-    header->fCoverageOutput = kModulate_CoverageOutput;
+    for (int s = 0; s < optState.numColorStages(); ++s) {
+        colorStages->push_back(&optState.getColorStage(s));
+    }
+    for (int s = 0; s < optState.numCoverageStages(); ++s) {
+        coverageStages->push_back(&optState.getCoverageStage(s));
+    }
 
-    // If we do have coverage determine whether it matters.
-    bool separateCoverageFromColor = false;
-    if (!drawState.isCoverageDrawing() && !skipCoverage &&
-        (drawState.numCoverageStages() > 0 || requiresCoverageAttrib)) {
-
-        if (gpu->caps()->dualSourceBlendingSupport() &&
-            !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag |
-                           GrDrawState::kCoverageAsAlpha_BlendOptFlag))) {
-            if (kZero_GrBlendCoeff == dstCoeff) {
-                // write the coverage value to second color
-                header->fCoverageOutput =  kSecondaryCoverage_CoverageOutput;
-                separateCoverageFromColor = true;
-            } else if (kSA_GrBlendCoeff == dstCoeff) {
-                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
-                header->fCoverageOutput = kSecondaryCoverageISA_CoverageOutput;
-                separateCoverageFromColor = true;
-            } else if (kSC_GrBlendCoeff == dstCoeff) {
-                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
-                header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput;
-                separateCoverageFromColor = true;
-            }
-        } else if (readsDst &&
-                   kOne_GrBlendCoeff == srcCoeff &&
-                   kZero_GrBlendCoeff == dstCoeff) {
-            header->fCoverageOutput = kCombineWithDst_CoverageOutput;
-            separateCoverageFromColor = true;
-        }
-    }
-    if (!skipColor) {
-        for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
-            colorStages->push_back(&drawState.getColorStage(s));
-        }
-    }
-    if (!skipCoverage) {
-        SkTArray<const GrEffectStage*, true>* array;
-        if (separateCoverageFromColor) {
-            array = coverageStages;
-        } else {
-            array = colorStages;
-        }
-        for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) {
-            array->push_back(&drawState.getCoverageStage(s));
-        }
-    }
     header->fColorEffectCnt = colorStages->count();
     header->fCoverageEffectCnt = coverageStages->count();
 
-    *desc->checksum() = 0;
-    *desc->checksum() = SkChecksum::Compute(reinterpret_cast<uint32_t*>(desc->fKey.get()),
-                                            newKeyLength);
-    desc->fInitialized = true;
+    desc->finalize();
+    return true;
+}
+
+void GrGLProgramDesc::finalize() {
+    int keyLength = fKey.count();
+    SkASSERT(0 == (keyLength % 4));
+    *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength);
+
+    uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>();
+    *checksum = 0;
+    *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), keyLength);
 }
 
 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) {
-    fInitialized = other.fInitialized;
-    if (fInitialized) {
-        size_t keyLength = other.keyLength();
-        fKey.reset(keyLength);
-        memcpy(fKey.get(), other.fKey.get(), keyLength);
-    }
+    size_t keyLength = other.keyLength();
+    fKey.reset(keyLength);
+    memcpy(fKey.begin(), other.fKey.begin(), keyLength);
     return *this;
 }
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index 9165f4e..97f00f4 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -8,10 +8,10 @@
 #ifndef GrGLProgramDesc_DEFINED
 #define GrGLProgramDesc_DEFINED
 
-#include "GrGLEffect.h"
+#include "GrGLProcessor.h"
 #include "GrDrawState.h"
-#include "GrGLShaderBuilder.h"
 #include "GrGpu.h"
+#include "GrOptDrawState.h"
 
 class GrGpuGL;
 
@@ -25,18 +25,15 @@
 
 
 /** This class describes a program to generate. It also serves as a program cache key. Very little
-    of this is GL-specific. There is the generation of GrGLEffect::EffectKeys and the dst-read part
-    of the key set by GrGLShaderBuilder. If the interfaces that set those portions were abstracted
-    to be API-neutral then so could this class. */
+    of this is GL-specific. The GL-specific parts could be factored out into a subclass. */
 class GrGLProgramDesc {
 public:
-    GrGLProgramDesc() : fInitialized(false) {}
+    GrGLProgramDesc() {}
     GrGLProgramDesc(const GrGLProgramDesc& desc) { *this = desc; }
 
     // Returns this as a uint32_t array to be used as a key in the program cache.
     const uint32_t* asKey() const {
-        SkASSERT(fInitialized);
-        return reinterpret_cast<const uint32_t*>(fKey.get());
+        return reinterpret_cast<const uint32_t*>(fKey.begin());
     }
 
     // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. When comparing two
@@ -48,40 +45,43 @@
     uint32_t getChecksum() const { return *this->atOffset<uint32_t, kChecksumOffset>(); }
 
     // For unit testing.
-    void setRandom(SkRandom*,
-                   const GrGpuGL* gpu,
+    bool setRandom(SkRandom*,
+                   GrGpuGL*,
                    const GrRenderTarget* dummyDstRenderTarget,
                    const GrTexture* dummyDstCopyTexture,
-                   const GrEffectStage* stages[],
+                   const GrGeometryStage* geometryProcessor,
+                   const GrFragmentStage* stages[],
                    int numColorStages,
                    int numCoverageStages,
-                   int currAttribIndex);
+                   int currAttribIndex,
+                   GrGpu::DrawType);
 
     /**
-     * Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the
-     * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs. It also
-     * outputs the color and coverage stages referenced by the generated descriptor. This may
-     * not contain all stages from the draw state and coverage stages from the drawState may
-     * be treated as color stages in the output.
+     * Builds a program descriptor from a GrOptDrawState. Whether the primitive type is points, and
+     * the caps of the GrGpuGL are also inputs. It also outputs the color and coverage stages
+     * referenced by the generated descriptor. Coverage stages from the drawState may be treated as
+     * color stages in the output.
      */
-    static void Build(const GrDrawState&,
-                      GrGpu::DrawType drawType,
-                      GrDrawState::BlendOptFlags,
+    static bool Build(const GrOptDrawState&,
+                      GrGpu::DrawType,
                       GrBlendCoeff srcCoeff,
                       GrBlendCoeff dstCoeff,
-                      const GrGpuGL* gpu,
+                      GrGpuGL*,
                       const GrDeviceCoordTexture* dstCopy,
-                      SkTArray<const GrEffectStage*, true>* outColorStages,
-                      SkTArray<const GrEffectStage*, true>* outCoverageStages,
-                      GrGLProgramDesc* outDesc);
+                      const GrGeometryStage** geometryProcessor,
+                      SkTArray<const GrFragmentStage*, true>* colorStages,
+                      SkTArray<const GrFragmentStage*, true>* coverageStages,
+                      GrGLProgramDesc*);
+
+    bool hasGeometryProcessor() const {
+        return SkToBool(this->getHeader().fHasGeometryProcessor);
+    }
 
     int numColorEffects() const {
-        SkASSERT(fInitialized);
         return this->getHeader().fColorEffectCnt;
     }
 
     int numCoverageEffects() const {
-        SkASSERT(fInitialized);
         return this->getHeader().fCoverageEffectCnt;
     }
 
@@ -90,7 +90,6 @@
     GrGLProgramDesc& operator= (const GrGLProgramDesc& other);
 
     bool operator== (const GrGLProgramDesc& other) const {
-        SkASSERT(fInitialized && other.fInitialized);
         // The length is masked as a hint to the compiler that the address will be 4 byte aligned.
         return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x3);
     }
@@ -106,59 +105,31 @@
 private:
     // Specifies where the initial color comes from before the stages are applied.
     enum ColorInput {
-        kSolidWhite_ColorInput,
-        kTransBlack_ColorInput,
+        kAllOnes_ColorInput,
         kAttribute_ColorInput,
         kUniform_ColorInput,
 
         kColorInputCnt
     };
 
-    enum CoverageOutput {
-        // modulate color and coverage, write result as the color output.
-        kModulate_CoverageOutput,
-        // Writes color*coverage as the primary color output and also writes coverage as the
-        // secondary output. Only set if dual source blending is supported.
-        kSecondaryCoverage_CoverageOutput,
-        // Writes color*coverage as the primary color output and also writes coverage * (1 - colorA)
-        // as the secondary output. Only set if dual source blending is supported.
-        kSecondaryCoverageISA_CoverageOutput,
-        // Writes color*coverage as the primary color output and also writes coverage *
-        // (1 - colorRGB) as the secondary output. Only set if dual source blending is supported.
-        kSecondaryCoverageISC_CoverageOutput,
-        // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
-        // can only be set if fDstReadKey is non-zero.
-        kCombineWithDst_CoverageOutput,
-
-        kCoverageOutputCnt
-    };
-
-    static bool CoverageOutputUsesSecondaryOutput(CoverageOutput co) {
-        switch (co) {
-            case kSecondaryCoverage_CoverageOutput: //  fallthru
-            case kSecondaryCoverageISA_CoverageOutput:
-            case kSecondaryCoverageISC_CoverageOutput:
-                return true;
-            default:
-                return false;
-        }
-    }
-
     struct KeyHeader {
-        GrGLShaderBuilder::DstReadKey fDstReadKey;      // set by GrGLShaderBuilder if there
+        uint8_t                          fDstReadKey;   // set by GrGLShaderBuilder if there
                                                         // are effects that must read the dst.
                                                         // Otherwise, 0.
-        GrGLShaderBuilder::FragPosKey fFragPosKey;      // set by GrGLShaderBuilder if there are
+        uint8_t                          fFragPosKey;   // set by GrGLShaderBuilder if there are
                                                         // effects that read the fragment position.
                                                         // Otherwise, 0.
 
-        ColorInput                  fColorInput : 8;
-        ColorInput                  fCoverageInput : 8;
-        CoverageOutput              fCoverageOutput : 8;
-
-        SkBool8                     fHasVertexCode;
+        SkBool8                     fUseFragShaderOnly;
         SkBool8                     fEmitsPointSize;
 
+        ColorInput                       fColorInput : 8;
+        ColorInput                       fCoverageInput : 8;
+
+        GrOptDrawState::PrimaryOutputType    fPrimaryOutputType : 8;
+        GrOptDrawState::SecondaryOutputType  fSecondaryOutputType : 8;
+
+
         // To enable experimental geometry shader code (not for use in
         // production)
 #if GR_GL_EXPERIMENTAL_GS
@@ -170,56 +141,117 @@
         int8_t                      fColorAttributeIndex;
         int8_t                      fCoverageAttributeIndex;
 
+        SkBool8                     fHasGeometryProcessor;
         int8_t                      fColorEffectCnt;
         int8_t                      fCoverageEffectCnt;
     };
 
-    // The key is 1 uint32_t for the length, followed another for the checksum, the header, and then
-    // the effect keys. Everything is fixed length except the effect key array.
+    // The key, stored in fKey, is composed of five parts:
+    // 1. uint32_t for total key length.
+    // 2. uint32_t for a checksum.
+    // 3. Header struct defined above.
+    // 4. An array of offsets to effect keys and their sizes (see 5). uint16_t for each
+    //    offset and size.
+    // 5. per-effect keys. Each effect's key is a variable length array of uint32_t.
     enum {
+        // Part 1.
         kLengthOffset = 0,
+        // Part 2.
         kChecksumOffset = kLengthOffset + sizeof(uint32_t),
+        // Part 3.
         kHeaderOffset = kChecksumOffset + sizeof(uint32_t),
         kHeaderSize = SkAlign4(sizeof(KeyHeader)),
-        kEffectKeyOffset = kHeaderOffset + kHeaderSize,
+        // Part 4.
+        // This is the offset in the overall key to the array of per-effect offset,length pairs.
+        kEffectKeyOffsetsAndLengthOffset = kHeaderOffset + kHeaderSize,
     };
 
     template<typename T, size_t OFFSET> T* atOffset() {
-        return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET);
+        return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET);
     }
 
     template<typename T, size_t OFFSET> const T* atOffset() const {
-        return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET);
+        return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET);
     }
 
-    typedef GrGLEffect::EffectKey EffectKey;
-
-    uint32_t* checksum() { return this->atOffset<uint32_t, kChecksumOffset>(); }
     KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); }
-    EffectKey* effectKeys() { return this->atOffset<EffectKey, kEffectKeyOffset>(); }
+
+    // Shared code between setRandom() and Build().
+    static bool GetProcessorKey(const GrProcessorStage& stage,
+                                const GrGLCaps& caps,
+                                bool useExplicitLocalCoords,
+                                GrProcessorKeyBuilder* b,
+                                uint16_t* effectKeySize);
+
+    static bool GetGeometryProcessorKey(const GrGeometryStage& stage,
+                                        const GrGLCaps& caps,
+                                        bool useExplicitLocalCoords,
+                                        GrProcessorKeyBuilder* b,
+                                        uint16_t* effectKeySize);
+    void finalize();
 
     const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
-    const EffectKey* getEffectKeys() const { return this->atOffset<EffectKey, kEffectKeyOffset>(); }
 
-    static size_t KeyLength(int effectCnt) {
-        GR_STATIC_ASSERT(!(sizeof(EffectKey) & 0x3));
-        return kEffectKeyOffset + effectCnt * sizeof(EffectKey);
-    }
+    /** Used to provide effects' keys to their emitCode() function. */
+    class EffectKeyProvider {
+    public:
+        enum EffectType {
+            kGeometryProcessor_EffectType,
+            kColor_EffectType,
+            kCoverage_EffectType,
+        };
 
-    enum {
-        kMaxPreallocEffects = 16,
-        kPreAllocSize = kEffectKeyOffset +  kMaxPreallocEffects * sizeof(EffectKey),
+        EffectKeyProvider(const GrGLProgramDesc* desc, EffectType type) : fDesc(desc) {
+            switch (type) {
+                case kGeometryProcessor_EffectType:
+                    // there can be only one
+                    fBaseIndex = 0;
+                    break;
+                case kColor_EffectType:
+                    fBaseIndex = desc->hasGeometryProcessor() ? 1 : 0;
+                    break;
+                case kCoverage_EffectType:
+                    fBaseIndex = desc->numColorEffects() + (desc->hasGeometryProcessor() ? 1 : 0);
+                    break;
+            }
+        }
+
+        GrProcessorKey get(int index) const {
+            const uint16_t* offsetsAndLengths = reinterpret_cast<const uint16_t*>(
+                fDesc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset);
+            // We store two uint16_ts per effect, one for the offset to the effect's key and one for
+            // its length. Here we just need the offset.
+            uint16_t offset = offsetsAndLengths[2 * (fBaseIndex + index) + 0];
+            uint16_t length = offsetsAndLengths[2 * (fBaseIndex + index) + 1];
+            // Currently effects must add to the key in units of uint32_t.
+            SkASSERT(0 == (length % sizeof(uint32_t)));
+            return GrProcessorKey(reinterpret_cast<const uint32_t*>(fDesc->fKey.begin() + offset),
+                               length / sizeof(uint32_t));
+        }
+    private:
+        const GrGLProgramDesc*  fDesc;
+        int                     fBaseIndex;
     };
 
-    SkAutoSMalloc<kPreAllocSize> fKey;
-    bool fInitialized;
+    enum {
+        kMaxPreallocEffects = 8,
+        kIntsPerEffect      = 4,    // This is an overestimate of the average effect key size.
+        kPreAllocSize = kEffectKeyOffsetsAndLengthOffset +
+                        kMaxPreallocEffects * sizeof(uint32_t) * kIntsPerEffect,
+    };
 
-    // GrGLProgram and GrGLShaderBuilder read the private fields to generate code. TODO: Move all
-    // code generation to GrGLShaderBuilder (and maybe add getters rather than friending).
+    SkSTArray<kPreAllocSize, uint8_t, true> fKey;
+
+    // GrGLProgram and GrGLShaderBuilder read the private fields to generate code. TODO: Split out
+    // part of GrGLShaderBuilder that is used by effects so that this header doesn't need to be
+    // visible to GrGLProcessors. Then make public accessors as necessary and remove friends.
     friend class GrGLProgram;
-    friend class GrGLShaderBuilder;
-    friend class GrGLFullShaderBuilder;
-    friend class GrGLFragmentOnlyShaderBuilder;
+    friend class GrGLProgramBuilder;
+    friend class GrGLFullProgramBuilder;
+    friend class GrGLFragmentOnlyProgramBuilder;
+    friend class GrGLVertexShaderBuilder;
+    friend class GrGLFragmentShaderBuilder;
+    friend class GrGLGeometryShaderBuilder;
 };
 
 #endif
diff --git a/src/gpu/gl/GrGLProgramEffects.cpp b/src/gpu/gl/GrGLProgramEffects.cpp
index 04cebf8..6ab8654 100644
--- a/src/gpu/gl/GrGLProgramEffects.cpp
+++ b/src/gpu/gl/GrGLProgramEffects.cpp
@@ -6,120 +6,33 @@
  */
 
 #include "GrGLProgramEffects.h"
-#include "GrDrawEffect.h"
-#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
-#include "gl/GrGLVertexEffect.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/GrGLPathRendering.h"
+#include "gl/builders/GrGLFullProgramBuilder.h"
+#include "gl/builders/GrGLFragmentOnlyProgramBuilder.h"
+#include "gl/GrGLGeometryProcessor.h"
 #include "gl/GrGpuGL.h"
 
-typedef GrGLProgramEffects::EffectKey EffectKey;
-typedef GrGLProgramEffects::TransformedCoords TransformedCoords;
-typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
-typedef GrGLProgramEffects::TextureSampler TextureSampler;
-typedef GrGLProgramEffects::TextureSamplerArray TextureSamplerArray;
-
-/**
- * We specialize the vertex code for each of these matrix types.
- */
-enum MatrixType {
-    kIdentity_MatrixType = 0,
-    kTrans_MatrixType    = 1,
-    kNoPersp_MatrixType  = 2,
-    kGeneral_MatrixType  = 3,
-};
-
-/**
- * The key for an individual coord transform is made up of a matrix type and a bit that
- * indicates the source of the input coords.
- */
-enum {
-    kMatrixTypeKeyBits   = 2,
-    kMatrixTypeKeyMask   = (1 << kMatrixTypeKeyBits) - 1,
-    kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
-    kTransformKeyBits    = kMatrixTypeKeyBits + 1,
-};
+typedef GrGLProcessor::TransformedCoords TransformedCoords;
+typedef GrGLProcessor::TransformedCoordsArray TransformedCoordsArray;
+typedef GrGLProcessor::TextureSampler TextureSampler;
+typedef GrGLProcessor::TextureSamplerArray TextureSamplerArray;
 
 namespace {
-
-/**
- * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are
- * present in the texture's config. swizzleComponentMask indicates the channels present in the
- * shader swizzle.
- */
-inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
-                                             uint32_t configComponentMask,
-                                             uint32_t swizzleComponentMask) {
-    if (caps.textureSwizzleSupport()) {
-        // Any remapping is handled using texture swizzling not shader modifications.
-        return false;
-    }
-    // check if the texture is alpha-only
-    if (kA_GrColorComponentFlag == configComponentMask) {
-        if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) {
-            // we must map the swizzle 'a's to 'r'.
-            return true;
-        }
-        if (kRGB_GrColorComponentFlags & swizzleComponentMask) {
-            // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that
-            // alpha-only textures smear alpha across all four channels when read.
-            return true;
-        }
-    }
-    return false;
-}
-
-/**
- * Retrieves the matrix type from transformKey for the transform at transformIdx.
- */
-MatrixType get_matrix_type(EffectKey transformKey, int transformIdx) {
-    return static_cast<MatrixType>(
-               (transformKey >> (kTransformKeyBits * transformIdx)) & kMatrixTypeKeyMask);
-}
-
-/**
- * Retrieves the source coords from transformKey for the transform at transformIdx. It may not be
- * the same coordinate set as the original GrCoordTransform if the position and local coords are
- * identical for this program.
- */
-GrCoordSet get_source_coords(EffectKey transformKey, int transformIdx) {
-    return (transformKey >> (kTransformKeyBits * transformIdx)) & kPositionCoords_Flag ?
-               kPosition_GrCoordSet :
-               kLocal_GrCoordSet;
-}
-
-/**
- * Retrieves the final translation that a transform needs to apply to its source coords (and
- * verifies that a translation is all it needs).
- */
-void get_transform_translation(const GrDrawEffect& drawEffect,
-                               int transformIdx,
-                               GrGLfloat* tx,
-                               GrGLfloat* ty) {
-    const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(transformIdx);
-    SkASSERT(!coordTransform.reverseY());
-    const SkMatrix& matrix = coordTransform.getMatrix();
-    if (kLocal_GrCoordSet == coordTransform.sourceCoords() &&
-        !drawEffect.programHasExplicitLocalCoords()) {
-        const SkMatrix& coordChangeMatrix = drawEffect.getCoordChangeMatrix();
-        SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
-        *tx = SkScalarToFloat(matrix[SkMatrix::kMTransX] + coordChangeMatrix[SkMatrix::kMTransX]);
-        *ty = SkScalarToFloat(matrix[SkMatrix::kMTransY] + coordChangeMatrix[SkMatrix::kMTransY]);
-    } else {
-        SkASSERT(SkMatrix::kTranslate_Mask == matrix.getType());
-        *tx = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
-        *ty = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
-    }
-}
-
 /**
  * Retrieves the final matrix that a transform needs to apply to its source coords.
  */
-SkMatrix get_transform_matrix(const GrDrawEffect& drawEffect, int transformIdx) {
-    const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(transformIdx);
+SkMatrix get_transform_matrix(const GrProcessorStage& effectStage,
+                              bool useExplicitLocalCoords,
+                              int transformIdx) {
+    const GrCoordTransform& coordTransform = effectStage.getProcessor()->coordTransform(transformIdx);
     SkMatrix combined;
-    if (kLocal_GrCoordSet == coordTransform.sourceCoords() &&
-        !drawEffect.programHasExplicitLocalCoords()) {
-        combined.setConcat(coordTransform.getMatrix(), drawEffect.getCoordChangeMatrix());
+
+    if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
+        // If we have explicit local coords then we shouldn't need a coord change.
+        const SkMatrix& ccm =
+                useExplicitLocalCoords ? SkMatrix::I() : effectStage.getCoordChangeMatrix();
+        combined.setConcat(coordTransform.getMatrix(), ccm);
     } else {
         combined = coordTransform.getMatrix();
     }
@@ -135,122 +48,38 @@
     }
     return combined;
 }
-
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-EffectKey GrGLProgramEffects::GenAttribKey(const GrDrawEffect& drawEffect) {
-    EffectKey key = 0;
-    int numAttributes = drawEffect.getVertexAttribIndexCount();
-    SkASSERT(numAttributes <= 2);
-    const int* attributeIndices = drawEffect.getVertexAttribIndices();
-    for (int a = 0; a < numAttributes; ++a) {
-        EffectKey value = attributeIndices[a] << 3 * a;
-        SkASSERT(0 == (value & key)); // keys for each attribute ought not to overlap
-        key |= value;
-    }
-    return key;
-}
-
-EffectKey GrGLProgramEffects::GenTransformKey(const GrDrawEffect& drawEffect) {
-    EffectKey totalKey = 0;
-    int numTransforms = (*drawEffect.effect())->numTransforms();
-    for (int t = 0; t < numTransforms; ++t) {
-        EffectKey key = 0;
-        const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(t);
-        SkMatrix::TypeMask type0 = coordTransform.getMatrix().getType();
-        SkMatrix::TypeMask type1;
-        if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
-            type1 = drawEffect.getCoordChangeMatrix().getType();
-        } else {
-            if (drawEffect.programHasExplicitLocalCoords()) {
-                // We only make the key indicate that device coords are referenced when the local coords
-                // are not actually determined by positions. Otherwise the local coords var and position
-                // var are identical.
-                key |= kPositionCoords_Flag;
-            }
-            type1 = SkMatrix::kIdentity_Mask;
-        }
-
-        int combinedTypes = type0 | type1;
-
-        bool reverseY = coordTransform.reverseY();
-
-        if (SkMatrix::kPerspective_Mask & combinedTypes) {
-            key |= kGeneral_MatrixType;
-        } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedTypes) || reverseY) {
-            key |= kNoPersp_MatrixType;
-        } else if (SkMatrix::kTranslate_Mask & combinedTypes) {
-            key |= kTrans_MatrixType;
-        } else {
-            key |= kIdentity_MatrixType;
-        }
-        key <<= kTransformKeyBits * t;
-        SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap
-        totalKey |= key;
-    }
-    return totalKey;
-}
-
-EffectKey GrGLProgramEffects::GenTextureKey(const GrDrawEffect& drawEffect, const GrGLCaps& caps) {
-    EffectKey key = 0;
-    int numTextures = (*drawEffect.effect())->numTextures();
-    for (int t = 0; t < numTextures; ++t) {
-        const GrTextureAccess& access = (*drawEffect.effect())->textureAccess(t);
-        uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
-        if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
-            key |= 1 << t;
-        }
-    }
-    return key;
-}
-
 GrGLProgramEffects::~GrGLProgramEffects() {
-    int numEffects = fGLEffects.count();
+    int numEffects = fGLProcessors.count();
     for (int e = 0; e < numEffects; ++e) {
-        SkDELETE(fGLEffects[e]);
+        SkDELETE(fGLProcessors[e]);
     }
 }
 
-void GrGLProgramEffects::emitSamplers(GrGLShaderBuilder* builder,
-                                      const GrEffectRef& effect,
-                                      TextureSamplerArray* outSamplers) {
-    SkTArray<Sampler, true>& samplers = fSamplers.push_back();
-    int numTextures = effect->numTextures();
-    samplers.push_back_n(numTextures);
-    SkString name;
-    for (int t = 0; t < numTextures; ++t) {
-        name.printf("Sampler%d", t);
-        samplers[t].fUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                                   kSampler2D_GrSLType,
-                                                   name.c_str());
-        SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler,
-                               (samplers[t].fUniform, effect->textureAccess(t)));
-    }
-}
-
-void GrGLProgramEffects::initSamplers(const GrGLUniformManager& uniformManager, int* texUnitIdx) {
-    int numEffects = fGLEffects.count();
+void GrGLProgramEffects::initSamplers(const GrGLProgramDataManager& programResourceManager, int* texUnitIdx) {
+    int numEffects = fGLProcessors.count();
     SkASSERT(numEffects == fSamplers.count());
     for (int e = 0; e < numEffects; ++e) {
         SkTArray<Sampler, true>& samplers = fSamplers[e];
         int numSamplers = samplers.count();
         for (int s = 0; s < numSamplers; ++s) {
             SkASSERT(samplers[s].fUniform.isValid());
-            uniformManager.setSampler(samplers[s].fUniform, *texUnitIdx);
+            programResourceManager.setSampler(samplers[s].fUniform, *texUnitIdx);
             samplers[s].fTextureUnit = (*texUnitIdx)++;
         }
     }
 }
 
-void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, int effectIdx) {
+void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrProcessor& effect, int effectIdx) {
     const SkTArray<Sampler, true>& samplers = fSamplers[effectIdx];
     int numSamplers = samplers.count();
-    SkASSERT(numSamplers == effect->numTextures());
+    SkASSERT(numSamplers == effect.numTextures());
     for (int s = 0; s < numSamplers; ++s) {
         SkASSERT(samplers[s].fTextureUnit >= 0);
-        const GrTextureAccess& textureAccess = effect->textureAccess(s);
+        const GrTextureAccess& textureAccess = effect.textureAccess(s);
         gpu->bindTexture(samplers[s].fTextureUnit,
                          textureAccess.getParams(),
                          static_cast<GrGLTexture*>(textureAccess.getTexture()));
@@ -259,336 +88,117 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder,
-                                          const GrEffectStage& stage,
-                                          EffectKey key,
-                                          const char* outColor,
-                                          const char* inColor,
-                                          int stageIndex) {
-    GrDrawEffect drawEffect(stage, fHasExplicitLocalCoords);
-    const GrEffectRef& effect = *stage.getEffect();
-    SkSTArray<2, TransformedCoords> coords(effect->numTransforms());
-    SkSTArray<4, TextureSampler> samplers(effect->numTextures());
-
-    this->emitAttributes(builder, stage);
-    this->emitTransforms(builder, effect, key, &coords);
-    this->emitSamplers(builder, effect, &samplers);
-
-    GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
-    fGLEffects.push_back(glEffect);
-
-    // Enclose custom code in a block to avoid namespace conflicts
-    SkString openBrace;
-    openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
-    builder->vsCodeAppend(openBrace.c_str());
-    builder->fsCodeAppend(openBrace.c_str());
-
-    if (glEffect->isVertexEffect()) {
-        GrGLVertexEffect* vertexEffect = static_cast<GrGLVertexEffect*>(glEffect);
-        vertexEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
-    } else {
-        glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
-    }
-
-    builder->vsCodeAppend("\t}\n");
-    builder->fsCodeAppend("\t}\n");
-}
-
-void GrGLVertexProgramEffects::emitAttributes(GrGLFullShaderBuilder* builder,
-                                              const GrEffectStage& stage) {
-    int numAttributes = stage.getVertexAttribIndexCount();
-    const int* attributeIndices = stage.getVertexAttribIndices();
-    for (int a = 0; a < numAttributes; ++a) {
-        // TODO: Make addAttribute mangle the name.
-        SkString attributeName("aAttr");
-        attributeName.appendS32(attributeIndices[a]);
-        builder->addEffectAttribute(attributeIndices[a],
-                                    (*stage.getEffect())->vertexAttribType(a),
-                                    attributeName);
-    }
-}
-
-void GrGLVertexProgramEffects::emitTransforms(GrGLFullShaderBuilder* builder,
-                                              const GrEffectRef& effect,
-                                              EffectKey effectKey,
-                                              TransformedCoordsArray* outCoords) {
-    SkTArray<Transform, true>& transforms = fTransforms.push_back();
-    EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey);
-    int numTransforms = effect->numTransforms();
-    transforms.push_back_n(numTransforms);
-    for (int t = 0; t < numTransforms; t++) {
-        GrSLType varyingType = kVoid_GrSLType;
-        const char* uniName;
-        switch (get_matrix_type(totalKey, t)) {
-            case kIdentity_MatrixType:
-                transforms[t].fType = kVoid_GrSLType;
-                uniName = NULL;
-                varyingType = kVec2f_GrSLType;
-                break;
-            case kTrans_MatrixType:
-                transforms[t].fType = kVec2f_GrSLType;
-                uniName = "StageTranslate";
-                varyingType = kVec2f_GrSLType;
-                break;
-            case kNoPersp_MatrixType:
-                transforms[t].fType = kMat33f_GrSLType;
-                uniName = "StageMatrix";
-                varyingType = kVec2f_GrSLType;
-                break;
-            case kGeneral_MatrixType:
-                transforms[t].fType = kMat33f_GrSLType;
-                uniName = "StageMatrix";
-                varyingType = kVec3f_GrSLType;
-                break;
-            default:
-                SkFAIL("Unexpected key.");
-        }
-        SkString suffixedUniName;
-        if (kVoid_GrSLType != transforms[t].fType) {
-            if (0 != t) {
-                suffixedUniName.append(uniName);
-                suffixedUniName.appendf("_%i", t);
-                uniName = suffixedUniName.c_str();
-            }
-            transforms[t].fHandle = builder->addUniform(GrGLShaderBuilder::kVertex_Visibility,
-                                                        transforms[t].fType,
-                                                        uniName,
-                                                        &uniName);
-        }
-
-        const char* varyingName = "MatrixCoord";
-        SkString suffixedVaryingName;
-        if (0 != t) {
-            suffixedVaryingName.append(varyingName);
-            suffixedVaryingName.appendf("_%i", t);
-            varyingName = suffixedVaryingName.c_str();
-        }
-        const char* vsVaryingName;
-        const char* fsVaryingName;
-        builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
-
-        const GrGLShaderVar& coords = kPosition_GrCoordSet == get_source_coords(totalKey, t) ?
-                                          builder->positionAttribute() :
-                                          builder->localCoordsAttribute();
-        // varying = matrix * coords (logically)
-        switch (transforms[t].fType) {
-            case kVoid_GrSLType:
-                SkASSERT(kVec2f_GrSLType == varyingType);
-                builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str());
-                break;
-            case kVec2f_GrSLType:
-                SkASSERT(kVec2f_GrSLType == varyingType);
-                builder->vsCodeAppendf("\t%s = %s + %s;\n",
-                                       vsVaryingName, uniName, coords.c_str());
-                break;
-            case kMat33f_GrSLType: {
-                SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
-                if (kVec2f_GrSLType == varyingType) {
-                    builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
-                                           vsVaryingName, uniName, coords.c_str());
-                } else {
-                    builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
-                                           vsVaryingName, uniName, coords.c_str());
-                }
-                break;
-            }
-            default:
-                SkFAIL("Unexpected uniform type.");
-        }
-        SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords,
-                               (SkString(fsVaryingName), varyingType));
-    }
+void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
+                                       GrGpu::DrawType drawType,
+                                       const GrGLProgramDataManager& programDataManager,
+                                       const GrGeometryStage* effectStages) {
+    SkASSERT(1 == fGLProcessors.count());
+    SkASSERT(1 == fTransforms.count());
+    SkASSERT(1 == fSamplers.count());
+    this->setDataInternal(gpu, drawType, programDataManager, *effectStages, 0);
 }
 
 void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
-                                       const GrGLUniformManager& uniformManager,
-                                       const GrEffectStage* effectStages[]) {
-    int numEffects = fGLEffects.count();
+                                       GrGpu::DrawType drawType,
+                                       const GrGLProgramDataManager& programDataManager,
+                                       const GrFragmentStage* effectStages[]) {
+    int numEffects = fGLProcessors.count();
     SkASSERT(numEffects == fTransforms.count());
     SkASSERT(numEffects == fSamplers.count());
     for (int e = 0; e < numEffects; ++e) {
-        GrDrawEffect drawEffect(*effectStages[e], fHasExplicitLocalCoords);
-        fGLEffects[e]->setData(uniformManager, drawEffect);
-        this->setTransformData(uniformManager, drawEffect, e);
-        this->bindTextures(gpu, *drawEffect.effect(), e);
+        this->setDataInternal(gpu, drawType, programDataManager, *effectStages[e], e);
     }
 }
 
-void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& uniformManager,
-                                                const GrDrawEffect& drawEffect,
+void GrGLVertexProgramEffects::setDataInternal(GrGpuGL* gpu,
+                                               GrGpu::DrawType drawType,
+                                               const GrGLProgramDataManager& programDataManager,
+                                               const GrProcessorStage& effectStage,
+                                               int index) {
+    const GrProcessor& effect = *effectStage.getProcessor();
+    fGLProcessors[index]->setData(programDataManager, effect);
+    if (GrGpu::IsPathRenderingDrawType(drawType)) {
+        this->setPathTransformData(gpu, programDataManager, effectStage, index);
+    } else {
+        this->setTransformData(gpu, programDataManager, effectStage, index);
+    }
+    this->bindTextures(gpu, effect, index);
+}
+
+void GrGLVertexProgramEffects::setTransformData(GrGpuGL* gpu,
+                                                const GrGLProgramDataManager& pdman,
+                                                const GrProcessorStage& effectStage,
                                                 int effectIdx) {
     SkTArray<Transform, true>& transforms = fTransforms[effectIdx];
     int numTransforms = transforms.count();
-    SkASSERT(numTransforms == (*drawEffect.effect())->numTransforms());
+    SkASSERT(numTransforms == effectStage.getProcessor()->numTransforms());
     for (int t = 0; t < numTransforms; ++t) {
-        SkASSERT(transforms[t].fHandle.isValid() != (kVoid_GrSLType == transforms[t].fType));
-        switch (transforms[t].fType) {
-            case kVoid_GrSLType:
-                SkASSERT(get_transform_matrix(drawEffect, t).isIdentity());
-                break;
-            case kVec2f_GrSLType: {
-                GrGLfloat tx, ty;
-                get_transform_translation(drawEffect, t, &tx, &ty);
-                if (transforms[t].fCurrentValue.get(SkMatrix::kMTransX) != tx ||
-                    transforms[t].fCurrentValue.get(SkMatrix::kMTransY) != ty) {
-                    uniformManager.set2f(transforms[t].fHandle, tx, ty);
-                    transforms[t].fCurrentValue.set(SkMatrix::kMTransX, tx);
-                    transforms[t].fCurrentValue.set(SkMatrix::kMTransY, ty);
-                }
-                break;
-            }
-            case kMat33f_GrSLType: {
-                const SkMatrix& matrix = get_transform_matrix(drawEffect, t);
-                if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) {
-                    uniformManager.setSkMatrix(transforms[t].fHandle, matrix);
-                    transforms[t].fCurrentValue = matrix;
-                }
-                break;
-            }
-            default:
-                SkFAIL("Unexpected uniform type.");
+        SkASSERT(transforms[t].fHandle.isValid());
+        const SkMatrix& matrix = get_transform_matrix(effectStage, fHasExplicitLocalCoords, t);
+        if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) {
+            pdman.setSkMatrix(transforms[t].fHandle, matrix);
+            transforms[t].fCurrentValue = matrix;
         }
     }
 }
 
-GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder,
-                                                                 int reserveCount)
-    : fBuilder(builder)
-    , fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects,
-                                 (reserveCount, fBuilder->hasExplicitLocalCoords()))) {
-}
-
-void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
-                                                 GrGLProgramEffects::EffectKey key,
-                                                 const char* outColor,
-                                                 const char* inColor,
-                                                 int stageIndex) {
-    SkASSERT(NULL != fProgramEffects.get());
-    fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex);
+void GrGLVertexProgramEffects::setPathTransformData(GrGpuGL* gpu,
+                                                    const GrGLProgramDataManager& pdman,
+                                                    const GrProcessorStage& effectStage,
+                                                    int effectIdx) {
+    SkTArray<PathTransform, true>& transforms = fPathTransforms[effectIdx];
+    int numTransforms = transforms.count();
+    SkASSERT(numTransforms == effectStage.getProcessor()->numTransforms());
+    for (int t = 0; t < numTransforms; ++t) {
+        SkASSERT(transforms[t].fHandle.isValid());
+        const SkMatrix& transform = get_transform_matrix(effectStage, fHasExplicitLocalCoords, t);
+        if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
+            continue;
+        }
+        transforms[t].fCurrentValue = transform;
+        switch (transforms[t].fType) {
+            case kVec2f_GrSLType:
+                pdman.setProgramPathFragmentInputTransform(transforms[t].fHandle, 2, transform);
+                break;
+            case kVec3f_GrSLType:
+                pdman.setProgramPathFragmentInputTransform(transforms[t].fHandle, 3, transform);
+                break;
+            default:
+                SkFAIL("Unexpected matrix type.");
+        }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrGLPathTexGenProgramEffects::emitEffect(GrGLFragmentOnlyShaderBuilder* builder,
-                                          const GrEffectStage& stage,
-                                          EffectKey key,
-                                          const char* outColor,
-                                          const char* inColor,
-                                          int stageIndex) {
-    GrDrawEffect drawEffect(stage, false);
-    const GrEffectRef& effect = *stage.getEffect();
-    SkSTArray<2, TransformedCoords> coords(effect->numTransforms());
-    SkSTArray<4, TextureSampler> samplers(effect->numTextures());
-
-    SkASSERT(0 == stage.getVertexAttribIndexCount());
-    this->setupPathTexGen(builder, effect, key, &coords);
-    this->emitSamplers(builder, effect, &samplers);
-
-    GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
-    fGLEffects.push_back(glEffect);
-
-    // Enclose custom code in a block to avoid namespace conflicts
-    SkString openBrace;
-    openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
-    builder->fsCodeAppend(openBrace.c_str());
-
-    SkASSERT(!glEffect->isVertexEffect());
-    glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
-
-    builder->fsCodeAppend("\t}\n");
-}
-
-void GrGLPathTexGenProgramEffects::setupPathTexGen(GrGLFragmentOnlyShaderBuilder* builder,
-                                           const GrEffectRef& effect,
-                                           EffectKey effectKey,
-                                           TransformedCoordsArray* outCoords) {
-    int numTransforms = effect->numTransforms();
-    EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey);
-    int texCoordIndex = builder->addTexCoordSets(numTransforms);
-    SkNEW_APPEND_TO_TARRAY(&fTransforms, Transforms, (totalKey, texCoordIndex));
-    SkString name;
-    for (int t = 0; t < numTransforms; ++t) {
-        GrSLType type = kGeneral_MatrixType == get_matrix_type(totalKey, t) ?
-                            kVec3f_GrSLType :
-                            kVec2f_GrSLType;
-        name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++);
-        SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, (name, type));
-    }
-}
-
 void GrGLPathTexGenProgramEffects::setData(GrGpuGL* gpu,
-                                       const GrGLUniformManager& uniformManager,
-                                       const GrEffectStage* effectStages[]) {
-    int numEffects = fGLEffects.count();
+                                           GrGpu::DrawType,
+                                           const GrGLProgramDataManager& pdman,
+                                           const GrFragmentStage* effectStages[]) {
+    int numEffects = fGLProcessors.count();
     SkASSERT(numEffects == fTransforms.count());
     SkASSERT(numEffects == fSamplers.count());
     for (int e = 0; e < numEffects; ++e) {
-        GrDrawEffect drawEffect(*effectStages[e], false);
-        fGLEffects[e]->setData(uniformManager, drawEffect);
-        this->setPathTexGenState(gpu, drawEffect, e);
-        this->bindTextures(gpu, *drawEffect.effect(), e);
+        const GrProcessorStage& effectStage = *effectStages[e];
+        const GrProcessor& effect = *effectStage.getProcessor();
+        fGLProcessors[e]->setData(pdman, effect);
+        this->setPathTexGenState(gpu, effectStage, e);
+        this->bindTextures(gpu, effect, e);
     }
 }
 
 void GrGLPathTexGenProgramEffects::setPathTexGenState(GrGpuGL* gpu,
-                                              const GrDrawEffect& drawEffect,
+                                              const GrProcessorStage& effectStage,
                                               int effectIdx) {
-    EffectKey totalKey = fTransforms[effectIdx].fTransformKey;
     int texCoordIndex = fTransforms[effectIdx].fTexCoordIndex;
-    int numTransforms = (*drawEffect.effect())->numTransforms();
+    int numTransforms = effectStage.getProcessor()->numTransforms();
     for (int t = 0; t < numTransforms; ++t) {
-        switch (get_matrix_type(totalKey, t)) {
-            case kIdentity_MatrixType: {
-                SkASSERT(get_transform_matrix(drawEffect, t).isIdentity());
-                GrGLfloat identity[] = {1, 0, 0,
-                                        0, 1, 0};
-                gpu->enablePathTexGen(texCoordIndex++,
-                                      GrGpuGL::kST_PathTexGenComponents,
-                                      identity);
-                break;
-            }
-            case kTrans_MatrixType: {
-                GrGLfloat tx, ty;
-                get_transform_translation(drawEffect, t, &tx, &ty);
-                GrGLfloat translate[] = {1, 0, tx,
-                                         0, 1, ty};
-                gpu->enablePathTexGen(texCoordIndex++,
-                                      GrGpuGL::kST_PathTexGenComponents,
-                                      translate);
-                break;
-            }
-            case kNoPersp_MatrixType: {
-                const SkMatrix& transform = get_transform_matrix(drawEffect, t);
-                gpu->enablePathTexGen(texCoordIndex++,
-                                      GrGpuGL::kST_PathTexGenComponents,
-                                      transform);
-                break;
-            }
-            case kGeneral_MatrixType: {
-                const SkMatrix& transform = get_transform_matrix(drawEffect, t);
-                gpu->enablePathTexGen(texCoordIndex++,
-                                      GrGpuGL::kSTR_PathTexGenComponents,
-                                      transform);
-                break;
-            }
-            default:
-                SkFAIL("Unexpected matrixs type.");
+        const SkMatrix& transform = get_transform_matrix(effectStage, false, t);
+        GrGLPathRendering::PathTexGenComponents components =
+                GrGLPathRendering::kST_PathTexGenComponents;
+        if (effectStage.isPerspectiveCoordTransform(t, false)) {
+            components = GrGLPathRendering::kSTR_PathTexGenComponents;
         }
+        gpu->glPathRendering()->enablePathTexGen(texCoordIndex++, components, transform);
     }
 }
-
-GrGLPathTexGenProgramEffectsBuilder::GrGLPathTexGenProgramEffectsBuilder(
-        GrGLFragmentOnlyShaderBuilder* builder,
-        int reserveCount)
-    : fBuilder(builder)
-    , fProgramEffects(SkNEW_ARGS(GrGLPathTexGenProgramEffects, (reserveCount))) {
-}
-
-void GrGLPathTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
-                                                     GrGLProgramEffects::EffectKey key,
-                                                     const char* outColor,
-                                                     const char* inColor,
-                                                     int stageIndex) {
-    SkASSERT(NULL != fProgramEffects.get());
-    fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex);
-}
diff --git a/src/gpu/gl/GrGLProgramEffects.h b/src/gpu/gl/GrGLProgramEffects.h
index 48d01c8..6140cde 100644
--- a/src/gpu/gl/GrGLProgramEffects.h
+++ b/src/gpu/gl/GrGLProgramEffects.h
@@ -8,111 +8,61 @@
 #ifndef GrGLProgramEffects_DEFINED
 #define GrGLProgramEffects_DEFINED
 
-#include "GrBackendEffectFactory.h"
+#include "GrBackendProcessorFactory.h"
+#include "GrGLProgramDataManager.h"
+#include "GrGpu.h"
 #include "GrTexture.h"
 #include "GrTextureAccess.h"
-#include "GrGLUniformManager.h"
 
-class GrEffectStage;
+class GrProcessor;
+class GrProcessorStage;
 class GrGLVertexProgramEffectsBuilder;
-class GrGLShaderBuilder;
-class GrGLFullShaderBuilder;
-class GrGLFragmentOnlyShaderBuilder;
+class GrGLProgramBuilder;
+class GrGLFullProgramBuilder;
+class GrGLFragmentOnlyProgramBuilder;
 
 /**
- * This class encapsulates an array of GrGLEffects and their supporting data (coord transforms
+ * This class encapsulates an array of GrGLProcessors and their supporting data (coord transforms
  * and textures). It is built with GrGLProgramEffectsBuilder, then used to manage the necessary GL
  * state and shader uniforms.
  */
 class GrGLProgramEffects : public SkRefCnt {
 public:
-    typedef GrBackendEffectFactory::EffectKey EffectKey;
-    typedef GrGLUniformManager::UniformHandle UniformHandle;
-
-    /**
-     * These methods generate different portions of an effect's final key.
-     */
-    static EffectKey GenAttribKey(const GrDrawEffect&);
-    static EffectKey GenTransformKey(const GrDrawEffect&);
-    static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
-
+    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+    typedef GrGLProgramDataManager::VaryingHandle VaryingHandle;
     virtual ~GrGLProgramEffects();
 
     /**
      * Assigns a texture unit to each sampler. It starts on *texUnitIdx and writes the next
      * available unit to *texUnitIdx when it returns.
      */
-    void initSamplers(const GrGLUniformManager&, int* texUnitIdx);
+    void initSamplers(const GrGLProgramDataManager&, int* texUnitIdx);
 
     /**
      * Calls setData() on each effect, and sets their transformation matrices and texture bindings.
      */
     virtual void setData(GrGpuGL*,
-                         const GrGLUniformManager&,
-                         const GrEffectStage* effectStages[]) = 0;
+                         GrGpu::DrawType,
+                         const GrGLProgramDataManager&,
+                         const GrGeometryStage* effectStages) {
+        SkFAIL("For geometry processor only");
+    }
 
-    /**
-     * Passed to GrGLEffects so they can add transformed coordinates to their shader code.
-     */
-    class TransformedCoords {
-    public:
-        TransformedCoords(const SkString& name, GrSLType type)
-            : fName(name), fType(type) {
-        }
-
-        const char* c_str() const { return fName.c_str(); }
-        GrSLType type() const { return fType; }
-        const SkString& getName() const { return fName; }
-
-    private:
-        SkString fName;
-        GrSLType fType;
-    };
-
-    typedef SkTArray<TransformedCoords> TransformedCoordsArray;
-
-    /**
-     * Passed to GrGLEffects so they can add texture reads to their shader code.
-     */
-    class TextureSampler {
-    public:
-        TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
-            : fSamplerUniform(uniform)
-            , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
-            SkASSERT(0 != fConfigComponentMask);
-            memcpy(fSwizzle, access.getSwizzle(), 5);
-        }
-
-        UniformHandle samplerUniform() const { return fSamplerUniform; }
-        // bitfield of GrColorComponentFlags present in the texture's config.
-        uint32_t configComponentMask() const { return fConfigComponentMask; }
-        const char* swizzle() const { return fSwizzle; }
-
-    private:
-        UniformHandle fSamplerUniform;
-        uint32_t      fConfigComponentMask;
-        char          fSwizzle[5];
-    };
-
-    typedef SkTArray<TextureSampler> TextureSamplerArray;
+    virtual void setData(GrGpuGL*,
+                         GrGpu::DrawType,
+                         const GrGLProgramDataManager&,
+                         const GrFragmentStage* effectStages[]) = 0;
 
 protected:
     GrGLProgramEffects(int reserveCount)
-        : fGLEffects(reserveCount)
+        : fGLProcessors(reserveCount)
         , fSamplers(reserveCount) {
     }
 
     /**
-     * Helper for emitEffect() in a subclasses. Emits uniforms for an effect's texture accesses and
-     * appends the necessary data to the TextureSamplerArray* object so effects can add texture
-     * lookups to their code. This method is only meant to be called during the construction phase.
-     */
-    void emitSamplers(GrGLShaderBuilder*, const GrEffectRef&, TextureSamplerArray*);
-
-    /**
      * Helper for setData(). Binds all the textures for an effect.
      */
-    void bindTextures(GrGpuGL*, const GrEffectRef&, int effectIdx);
+    void bindTextures(GrGpuGL*, const GrProcessor&, int effectIdx);
 
     struct Sampler {
         SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
@@ -120,30 +70,23 @@
         int           fTextureUnit;
     };
 
-    SkTArray<GrGLEffect*>                  fGLEffects;
+    /*
+     * Helpers for shader builders to build up program effects objects alongside shader code
+     */
+    void addEffect(GrGLProcessor* effect) { fGLProcessors.push_back(effect); }
+    SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); }
+
+    SkTArray<GrGLProcessor*>               fGLProcessors;
     SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
 
 private:
+    friend class GrGLProgramBuilder;
+    friend class GrGLFullProgramBuilder;
+    friend class GrGLFragmentOnlyShaderBuilder;
+
     typedef SkRefCnt INHERITED;
 };
 
-/**
- * This is an abstract base class for constructing different types of GrGLProgramEffects objects.
- */
-class GrGLProgramEffectsBuilder {
-public:
-    virtual ~GrGLProgramEffectsBuilder() { }
-
-    /**
-     * Emits the effect's shader code, and stores the necessary uniforms internally.
-     */
-    virtual void emitEffect(const GrEffectStage&,
-                            GrGLProgramEffects::EffectKey,
-                            const char* outColor,
-                            const char* inColor,
-                            int stageIndex) = 0;
-};
-
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
@@ -152,91 +95,65 @@
 class GrGLVertexProgramEffects : public GrGLProgramEffects {
 public:
     virtual void setData(GrGpuGL*,
-                         const GrGLUniformManager&,
-                         const GrEffectStage* effectStages[]) SK_OVERRIDE;
+                         GrGpu::DrawType,
+                         const GrGLProgramDataManager&,
+                         const GrGeometryStage* effectStages) SK_OVERRIDE;
+
+    virtual void setData(GrGpuGL*,
+                         GrGpu::DrawType,
+                         const GrGLProgramDataManager&,
+                         const GrFragmentStage* effectStages[]) SK_OVERRIDE;
 
 private:
-    friend class GrGLVertexProgramEffectsBuilder;
-
     GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords)
         : INHERITED(reserveCount)
         , fTransforms(reserveCount)
         , fHasExplicitLocalCoords(explicitLocalCoords) {
     }
 
-    /**
-     * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
-     * during the construction phase.
-     */
-    void emitEffect(GrGLFullShaderBuilder*,
-                    const GrEffectStage&,
-                    GrGLProgramEffects::EffectKey,
-                    const char* outColor,
-                    const char* inColor,
-                    int stageIndex);
+    struct Transform {
+        Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
+        UniformHandle fHandle;
+        SkMatrix      fCurrentValue;
+    };
 
-    /**
-     * Helper for emitEffect(). Emits any attributes an effect may have.
-     */
-    void emitAttributes(GrGLFullShaderBuilder*, const GrEffectStage&);
+    struct PathTransform {
+        PathTransform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
+        VaryingHandle fHandle;
+        SkMatrix fCurrentValue;
+        GrSLType fType;
+    };
 
-    /**
-     * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
-     * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
-     * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
-     * of the varyings in the VS and FS as well their types are appended to the
-     * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
+    /*
+     * These functions are used by the builders to build up program effects along side the shader
+     * code itself
      */
-    void emitTransforms(GrGLFullShaderBuilder*,
-                        const GrEffectRef&,
-                        EffectKey,
-                        TransformedCoordsArray*);
+    SkSTArray<2, Transform, true>& addTransforms() { return fTransforms.push_back(); }
+    SkTArray<PathTransform, true>& addPathTransforms() { return fPathTransforms.push_back(); }
 
     /**
      * Helper for setData(). Sets all the transform matrices for an effect.
      */
-    void setTransformData(const GrGLUniformManager&, const GrDrawEffect&, int effectIdx);
+    void setDataInternal(GrGpuGL* gpu,
+                         GrGpu::DrawType drawType,
+                         const GrGLProgramDataManager& programDataManager,
+                         const GrProcessorStage& effectStage,
+                         int index);
+    void setTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&, const GrProcessorStage&,
+                          int effectIdx);
+    void setPathTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&,
+                              const GrProcessorStage&, int effectIdx);
 
-    struct Transform {
-        Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
-        UniformHandle fHandle;
-        GrSLType      fType;
-        SkMatrix      fCurrentValue;
-    };
 
     SkTArray<SkSTArray<2, Transform, true> > fTransforms;
+    SkTArray<SkTArray<PathTransform, true> > fPathTransforms;
     bool                                     fHasExplicitLocalCoords;
 
+    friend class GrGLFullProgramBuilder;
+
     typedef GrGLProgramEffects INHERITED;
 };
 
-/**
- * This class is used to construct a GrGLVertexProgramEffects* object.
- */
-class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
-public:
-    GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder*, int reserveCount);
-    virtual ~GrGLVertexProgramEffectsBuilder() { }
-
-    virtual void emitEffect(const GrEffectStage&,
-                            GrGLProgramEffects::EffectKey,
-                            const char* outColor,
-                            const char* inColor,
-                            int stageIndex) SK_OVERRIDE;
-
-    /**
-     * Finalizes the building process and returns the effect array. After this call, the builder
-     * becomes invalid.
-     */
-    GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
-
-private:
-    GrGLFullShaderBuilder*                  fBuilder;
-    SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
-
-    typedef GrGLProgramEffectsBuilder INHERITED;
-};
-
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
@@ -246,83 +163,39 @@
 class GrGLPathTexGenProgramEffects : public GrGLProgramEffects {
 public:
     virtual void setData(GrGpuGL*,
-                         const GrGLUniformManager&,
-                         const GrEffectStage* effectStages[]) SK_OVERRIDE;
+                         GrGpu::DrawType,
+                         const GrGLProgramDataManager&,
+                         const GrFragmentStage* effectStages[]) SK_OVERRIDE;
 
 private:
-    friend class GrGLPathTexGenProgramEffectsBuilder;
-
     GrGLPathTexGenProgramEffects(int reserveCount)
         : INHERITED(reserveCount)
         , fTransforms(reserveCount) {
     }
 
     /**
-     * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
-     * during the construction phase.
-     */
-    void emitEffect(GrGLFragmentOnlyShaderBuilder*,
-                    const GrEffectStage&,
-                    GrGLProgramEffects::EffectKey,
-                    const char* outColor,
-                    const char* inColor,
-                    int stageIndex);
-
-    /**
-     * Helper for emitEffect(). Allocates texture units from the builder for each transform in an
-     * effect. The transforms all use adjacent texture units. They either use two or three of the
-     * coordinates at a given texture unit, depending on if they need perspective interpolation.
-     * The expressions to access the transformed coords (i.e. 'vec2(gl_TexCoord[0])') as well as the
-     * types are appended to the TransformedCoordsArray* object, which is in turn passed to the
-     * effect's emitCode() function.
-     */
-    void setupPathTexGen(GrGLFragmentOnlyShaderBuilder*,
-                         const GrEffectRef&,
-                         EffectKey,
-                         TransformedCoordsArray*);
-
-    /**
      * Helper for setData(). Sets the PathTexGen state for each transform in an effect.
      */
-    void setPathTexGenState(GrGpuGL*, const GrDrawEffect&, int effectIdx);
+    void setPathTexGenState(GrGpuGL*, const GrProcessorStage&, int effectIdx);
 
     struct Transforms {
-        Transforms(EffectKey transformKey, int texCoordIndex)
-            : fTransformKey(transformKey), fTexCoordIndex(texCoordIndex) {}
-        EffectKey fTransformKey;
+        Transforms(int texCoordIndex)
+            : fTexCoordIndex(texCoordIndex) {}
         int fTexCoordIndex;
     };
 
+    /*
+     * Helper for fragment only shader builder to build up the program effects alongside the shader
+     */
+    void addTransforms(int coordIndex) {
+        fTransforms.push_back(Transforms(coordIndex));
+    }
+
     SkTArray<Transforms> fTransforms;
 
+    friend class GrGLFragmentOnlyProgramBuilder;
+
     typedef GrGLProgramEffects INHERITED;
 };
 
-/**
- * This class is used to construct a GrGLPathTexGenProgramEffects* object.
- */
-class GrGLPathTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
-public:
-    GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyShaderBuilder*, int reserveCount);
-    virtual ~GrGLPathTexGenProgramEffectsBuilder() { }
-
-    virtual void emitEffect(const GrEffectStage&,
-                            GrGLProgramEffects::EffectKey,
-                            const char* outColor,
-                            const char* inColor,
-                            int stageIndex) SK_OVERRIDE;
-
-    /**
-     * Finalizes the building process and returns the effect array. After this call, the builder
-     * becomes invalid.
-     */
-    GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
-
-private:
-    GrGLFragmentOnlyShaderBuilder*          fBuilder;
-    SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects;
-
-    typedef GrGLProgramEffectsBuilder INHERITED;
-};
-
 #endif
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp
index f2a0cdc..49186bf 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -21,6 +21,7 @@
     fMSColorRenderbufferID  = desc.fMSColorRenderbufferID;
     fViewport               = viewport;
     fTexIDObj.reset(SkSafeRef(texID));
+    this->registerWithCache();
 }
 
 namespace {
@@ -52,8 +53,8 @@
                          viewport.fWidth, viewport.fHeight,
                          desc.fConfig, desc.fSampleCnt,
                          desc.fOrigin)) {
-    SkASSERT(NULL != texID);
-    SkASSERT(NULL != texture);
+    SkASSERT(texID);
+    SkASSERT(texture);
     // FBO 0 can't also be a texture, right?
     SkASSERT(0 != desc.fRTFBOID);
     SkASSERT(0 != desc.fTexFBOID);
@@ -79,7 +80,6 @@
 }
 
 void GrGLRenderTarget::onRelease() {
-    GPUGL->notifyRenderTargetDelete(this);
     if (!this->isWrapped()) {
         if (fTexFBOID) {
             GL_CALL(DeleteFramebuffers(1, &fTexFBOID));
@@ -102,7 +102,7 @@
     fRTFBOID                = 0;
     fTexFBOID               = 0;
     fMSColorRenderbufferID  = 0;
-    if (NULL != fTexIDObj.get()) {
+    if (fTexIDObj.get()) {
         fTexIDObj->abandon();
         fTexIDObj.reset(NULL);
     }
diff --git a/src/gpu/gl/GrGLSL.cpp b/src/gpu/gl/GrGLSL.cpp
index 468b13b..6c8f883 100644
--- a/src/gpu/gl/GrGLSL.cpp
+++ b/src/gpu/gl/GrGLSL.cpp
@@ -10,7 +10,7 @@
 #include "SkString.h"
 
 bool GrGetGLSLGeneration(const GrGLInterface* gl, GrGLSLGeneration* generation) {
-    SkASSERT(NULL != generation);
+    SkASSERT(generation);
     GrGLSLVersion ver = GrGLGetGLSLVersion(gl);
     if (GR_GLSL_INVALID_VER == ver) {
         return false;
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
deleted file mode 100644
index 4b2778c..0000000
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "gl/GrGLShaderBuilder.h"
-#include "gl/GrGLProgram.h"
-#include "gl/GrGLUniformHandle.h"
-#include "GrCoordTransform.h"
-#include "GrDrawEffect.h"
-#include "GrGpuGL.h"
-#include "GrTexture.h"
-#include "SkRTConf.h"
-#include "SkTraceEvent.h"
-
-#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
-#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
-
-// number of each input/output type in a single allocation block
-static const int kVarsPerBlock = 8;
-
-// except FS outputs where we expect 2 at most.
-static const int kMaxFSOutputs = 2;
-
-// ES2 FS only guarantees mediump and lowp support
-static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
-
-typedef GrGLUniformManager::UniformHandle UniformHandle;
-
-SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
-                "Print the source code for all shaders generated.");
-
-///////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-inline const char* color_attribute_name() { return "aColor"; }
-inline const char* coverage_attribute_name() { return "aCoverage"; }
-inline const char* declared_color_output_name() { return "fsColorOut"; }
-inline const char* dual_source_output_name() { return "dualSourceOut"; }
-inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) {
-    if (kVec2f_GrSLType == type) {
-        return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
-    } else {
-        SkASSERT(kVec3f_GrSLType == type);
-        return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj";
-    }
-}
-
-void append_texture_lookup(SkString* out,
-                           GrGpuGL* gpu,
-                           const char* samplerName,
-                           const char* coordName,
-                           uint32_t configComponentMask,
-                           const char* swizzle,
-                           GrSLType varyingType = kVec2f_GrSLType) {
-    SkASSERT(NULL != coordName);
-
-    out->appendf("%s(%s, %s)",
-                 sample_function_name(varyingType, gpu->glslGeneration()),
-                 samplerName,
-                 coordName);
-
-    char mangledSwizzle[5];
-
-    // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
-    // is available.
-    if (!gpu->glCaps().textureSwizzleSupport() &&
-        (kA_GrColorComponentFlag == configComponentMask)) {
-        char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a';
-        int i;
-        for (i = 0; '\0' != swizzle[i]; ++i) {
-            mangledSwizzle[i] = alphaChar;
-        }
-        mangledSwizzle[i] ='\0';
-        swizzle = mangledSwizzle;
-    }
-    // For shader prettiness we omit the swizzle rather than appending ".rgba".
-    if (memcmp(swizzle, "rgba", 4)) {
-        out->appendf(".%s", swizzle);
-    }
-}
-
-}
-
-static const char kDstCopyColorName[] = "_dstColor";
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool GrGLShaderBuilder::GenProgram(GrGpuGL* gpu,
-                                   GrGLUniformManager* uman,
-                                   const GrGLProgramDesc& desc,
-                                   const GrEffectStage* inColorStages[],
-                                   const GrEffectStage* inCoverageStages[],
-                                   GenProgramOutput* output) {
-    SkAutoTDelete<GrGLShaderBuilder> builder;
-    if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing()) {
-        builder.reset(SkNEW_ARGS(GrGLFullShaderBuilder, (gpu, uman, desc)));
-    } else {
-        builder.reset(SkNEW_ARGS(GrGLFragmentOnlyShaderBuilder, (gpu, uman, desc)));
-    }
-    if (builder->genProgram(inColorStages, inCoverageStages)) {
-        *output = builder->getOutput();
-        return true;
-    }
-    return false;
-}
-
-bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[],
-                                   const GrEffectStage* coverageStages[]) {
-    const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
-
-    ///////////////////////////////////////////////////////////////////////////
-    // emit code to read the dst copy texture, if necessary
-    if (kNoDstRead_DstReadKey != header.fDstReadKey &&
-        GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) {
-        bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey);
-        const char* dstCopyTopLeftName;
-        const char* dstCopyCoordScaleName;
-        const char* dstCopySamplerName;
-        uint32_t configMask;
-        if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) {
-            configMask = kA_GrColorComponentFlag;
-        } else {
-            configMask = kRGBA_GrColorComponentFlags;
-        }
-        fOutput.fUniformHandles.fDstCopySamplerUni =
-            this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopySampler",
-                             &dstCopySamplerName);
-        fOutput.fUniformHandles.fDstCopyTopLeftUni =
-            this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUpperLeft",
-                             &dstCopyTopLeftName);
-        fOutput.fUniformHandles.fDstCopyScaleUni =
-            this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyCoordScale",
-                             &dstCopyCoordScaleName);
-        const char* fragPos = this->fragmentPosition();
-        this->fsCodeAppend("\t// Read color from copy of the destination.\n");
-        this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n",
-                            fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
-        if (!topDown) {
-            this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n");
-        }
-        this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName);
-        append_texture_lookup(&fFSCode,
-                              fGpu,
-                              dstCopySamplerName,
-                              "_dstTexCoord",
-                              configMask,
-                              "rgba");
-        this->fsCodeAppend(";\n\n");
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // get the initial color and coverage to feed into the first effect in each effect chain
-
-    GrGLSLExpr4 inputColor;
-    GrGLSLExpr4 inputCoverage;
-
-    if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
-        const char* name;
-        fOutput.fUniformHandles.fColorUni =
-            this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Color",
-                             &name);
-        inputColor = GrGLSLExpr4(name);
-    } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fColorInput) {
-        inputColor = GrGLSLExpr4(1);
-    } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fColorInput) {
-        inputColor = GrGLSLExpr4(0);
-    }
-
-    if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
-        const char* name;
-        fOutput.fUniformHandles.fCoverageUni =
-            this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Coverage",
-                             &name);
-        inputCoverage = GrGLSLExpr4(name);
-    } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) {
-        inputCoverage = GrGLSLExpr4(1);
-    } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fCoverageInput) {
-        inputCoverage = GrGLSLExpr4(0);
-    }
-
-    if (k110_GrGLSLGeneration != fGpu->glslGeneration()) {
-        fFSOutputs.push_back().set(kVec4f_GrSLType,
-                                   GrGLShaderVar::kOut_TypeModifier,
-                                   declared_color_output_name());
-        fHasCustomColorOutput = true;
-    }
-
-    this->emitCodeBeforeEffects(&inputColor, &inputCoverage);
-
-    ///////////////////////////////////////////////////////////////////////////
-    // emit the per-effect code for both color and coverage effects
-
-    fOutput.fColorEffects.reset(this->createAndEmitEffects(colorStages,
-                                                           this->desc().getEffectKeys(),
-                                                           this->desc().numColorEffects(),
-                                                           &inputColor));
-
-    fOutput.fCoverageEffects.reset(this->createAndEmitEffects(coverageStages,
-                                    this->desc().getEffectKeys() + this->desc().numColorEffects(),
-                                    this->desc().numCoverageEffects(),
-                                    &inputCoverage));
-
-    this->emitCodeAfterEffects();
-
-    ///////////////////////////////////////////////////////////////////////////
-    // write the secondary color output if necessary
-    if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) {
-        const char* secondaryOutputName = this->enableSecondaryOutput();
-
-        // default coeff to ones for kCoverage_DualSrcOutput
-        GrGLSLExpr4 coeff(1);
-        if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) {
-            // Get (1-A) into coeff
-            coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
-        } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput ==
-                   header.fCoverageOutput){
-            // Get (1-RGBA) into coeff
-            coeff = GrGLSLExpr4(1) - inputColor;
-        }
-        // Get coeff * coverage into modulate and then write that to the dual source output.
-        this->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // combine color and coverage as frag color
-
-    // Get "color * coverage" into fragColor
-    GrGLSLExpr4 fragColor = inputColor * inputCoverage;
-    // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
-    if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) {
-        GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
-
-        GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(this->dstColor());
-
-        fragColor = fragColor + dstContribution;
-    }
-    this->fsCodeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str());
-
-    if (!this->finish()) {
-        return false;
-    }
-
-    return true;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
-                                     GrGLUniformManager* uniformManager,
-                                     const GrGLProgramDesc& desc)
-    : fDesc(desc)
-    , fGpu(gpu)
-    , fUniformManager(SkRef(uniformManager))
-    , fFSFeaturesAddedMask(0)
-    , fFSInputs(kVarsPerBlock)
-    , fFSOutputs(kMaxFSOutputs)
-    , fUniforms(kVarsPerBlock)
-    , fSetupFragPosition(false)
-    , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey)
-    , fHasCustomColorOutput(false)
-    , fHasSecondaryOutput(false) {
-}
-
-bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) {
-    switch (feature) {
-        case kStandardDerivatives_GLSLFeature:
-            if (!fGpu->glCaps().shaderDerivativeSupport()) {
-                return false;
-            }
-            if (kGLES_GrGLStandard == fGpu->glStandard()) {
-                this->addFSFeature(1 << kStandardDerivatives_GLSLFeature,
-                                   "GL_OES_standard_derivatives");
-            }
-            return true;
-        default:
-            SkFAIL("Unexpected GLSLFeature requested.");
-            return false;
-    }
-}
-
-bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) {
-    switch (feature) {
-        case kFragCoordConventions_GLSLPrivateFeature:
-            if (!fGpu->glCaps().fragCoordConventionsSupport()) {
-                return false;
-            }
-            if (fGpu->glslGeneration() < k150_GrGLSLGeneration) {
-                this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
-                                   "GL_ARB_fragment_coord_conventions");
-            }
-            return true;
-        case kEXTShaderFramebufferFetch_GLSLPrivateFeature:
-            if (GrGLCaps::kEXT_FBFetchType != fGpu->glCaps().fbFetchType()) {
-                return false;
-            }
-            this->addFSFeature(1 << kEXTShaderFramebufferFetch_GLSLPrivateFeature,
-                               "GL_EXT_shader_framebuffer_fetch");
-            return true;
-        case kNVShaderFramebufferFetch_GLSLPrivateFeature:
-            if (GrGLCaps::kNV_FBFetchType != fGpu->glCaps().fbFetchType()) {
-                return false;
-            }
-            this->addFSFeature(1 << kNVShaderFramebufferFetch_GLSLPrivateFeature,
-                               "GL_NV_shader_framebuffer_fetch");
-            return true;
-        default:
-            SkFAIL("Unexpected GLSLPrivateFeature requested.");
-            return false;
-    }
-}
-
-void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionName) {
-    if (!(featureBit & fFSFeaturesAddedMask)) {
-        fFSExtensions.appendf("#extension %s: require\n", extensionName);
-        fFSFeaturesAddedMask |= featureBit;
-    }
-}
-
-void GrGLShaderBuilder::nameVariable(SkString* out, char prefix, const char* name) {
-    if ('\0' == prefix) {
-        *out = name;
-    } else {
-        out->printf("%c%s", prefix, name);
-    }
-    if (fCodeStage.inStageCode()) {
-        if (out->endsWith('_')) {
-            // Names containing "__" are reserved.
-            out->append("x");
-        }
-        out->appendf("_Stage%d", fCodeStage.stageIndex());
-    }
-}
-
-const char* GrGLShaderBuilder::dstColor() {
-    if (fCodeStage.inStageCode()) {
-        const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect();
-        if (!effect->willReadDstColor()) {
-            SkDEBUGFAIL("GrGLEffect asked for dst color but its generating GrEffect "
-                         "did not request access.");
-            return "";
-        }
-    }
-    static const char kFBFetchColorName[] = "gl_LastFragData[0]";
-    GrGLCaps::FBFetchType fetchType = fGpu->glCaps().fbFetchType();
-    if (GrGLCaps::kEXT_FBFetchType == fetchType) {
-        SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLSLPrivateFeature));
-        return kFBFetchColorName;
-    } else if (GrGLCaps::kNV_FBFetchType == fetchType) {
-        SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSLPrivateFeature));
-        return kFBFetchColorName;
-    } else if (fOutput.fUniformHandles.fDstCopySamplerUni.isValid()) {
-        return kDstCopyColorName;
-    } else {
-        return "";
-    }
-}
-
-void GrGLShaderBuilder::appendTextureLookup(SkString* out,
-                                            const GrGLShaderBuilder::TextureSampler& sampler,
-                                            const char* coordName,
-                                            GrSLType varyingType) const {
-    append_texture_lookup(out,
-                          fGpu,
-                          this->getUniformCStr(sampler.samplerUniform()),
-                          coordName,
-                          sampler.configComponentMask(),
-                          sampler.swizzle(),
-                          varyingType);
-}
-
-void GrGLShaderBuilder::fsAppendTextureLookup(const GrGLShaderBuilder::TextureSampler& sampler,
-                                              const char* coordName,
-                                              GrSLType varyingType) {
-    this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType);
-}
-
-void GrGLShaderBuilder::fsAppendTextureLookupAndModulate(
-                                            const char* modulation,
-                                            const GrGLShaderBuilder::TextureSampler& sampler,
-                                            const char* coordName,
-                                            GrSLType varyingType) {
-    SkString lookup;
-    this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
-    fFSCode.append((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
-}
-
-GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* dstCopy,
-                                                               const GrGLCaps& caps) {
-    uint32_t key = kYesDstRead_DstReadKeyBit;
-    if (GrGLCaps::kNone_FBFetchType != caps.fbFetchType()) {
-        return key;
-    }
-    SkASSERT(NULL != dstCopy);
-    if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->config())) {
-        // The fact that the config is alpha-only must be considered when generating code.
-        key |= kUseAlphaConfig_DstReadKeyBit;
-    }
-    if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) {
-        key |= kTopLeftOrigin_DstReadKeyBit;
-    }
-    SkASSERT(static_cast<DstReadKey>(key) == key);
-    return static_cast<DstReadKey>(key);
-}
-
-GrGLShaderBuilder::FragPosKey GrGLShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst,
-                                                                        const GrGLCaps&) {
-    if (kTopLeft_GrSurfaceOrigin == dst->origin()) {
-        return kTopLeftFragPosRead_FragPosKey;
-    } else {
-        return kBottomLeftFragPosRead_FragPosKey;
-    }
-}
-
-
-const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
-    if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
-        if (caps.textureRedSupport()) {
-            static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
-            return gRedSmear;
-        } else {
-            static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
-                                                    GR_GL_ALPHA, GR_GL_ALPHA };
-            return gAlphaSmear;
-        }
-    } else {
-        static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
-        return gStraight;
-    }
-}
-
-GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t visibility,
-                                                                     GrSLType type,
-                                                                     const char* name,
-                                                                     int count,
-                                                                     const char** outName) {
-    SkASSERT(name && strlen(name));
-    SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFragment_Visibility);
-    SkASSERT(0 == (~kVisibilityMask & visibility));
-    SkASSERT(0 != visibility);
-
-    BuilderUniform& uni = fUniforms.push_back();
-    UniformHandle h = GrGLUniformManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
-    SkDEBUGCODE(UniformHandle h2 =)
-    fUniformManager->appendUniform(type, count);
-    // We expect the uniform manager to initially have no uniforms and that all uniforms are added
-    // by this function. Therefore, the handles should match.
-    SkASSERT(h2 == h);
-    uni.fVariable.setType(type);
-    uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
-    this->nameVariable(uni.fVariable.accessName(), 'u', name);
-    uni.fVariable.setArrayCount(count);
-    uni.fVisibility = visibility;
-
-    // If it is visible in both the VS and FS, the precision must match.
-    // We declare a default FS precision, but not a default VS. So set the var
-    // to use the default FS precision.
-    if ((kVertex_Visibility | kFragment_Visibility) == visibility) {
-        // the fragment and vertex precisions must match
-        uni.fVariable.setPrecision(kDefaultFragmentPrecision);
-    }
-
-    if (NULL != outName) {
-        *outName = uni.fVariable.c_str();
-    }
-
-    return h;
-}
-
-SkString GrGLShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coords, int index) {
-    if (kVec3f_GrSLType != coords[index].type()) {
-        SkASSERT(kVec2f_GrSLType == coords[index].type());
-        return coords[index].getName();
-    }
-
-    SkString coords2D("coords2D");
-    if (0 != index) {
-        coords2D.appendf("_%i", index);
-    }
-    this->fsCodeAppendf("\tvec2 %s = %s.xy / %s.z;",
-                        coords2D.c_str(), coords[index].c_str(), coords[index].c_str());
-    return coords2D;
-}
-
-const char* GrGLShaderBuilder::fragmentPosition() {
-    if (fCodeStage.inStageCode()) {
-        const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect();
-        if (!effect->willReadFragmentPosition()) {
-            SkDEBUGFAIL("GrGLEffect asked for frag position but its generating GrEffect "
-                         "did not request access.");
-            return "";
-        }
-    }
-    // We only declare "gl_FragCoord" when we're in the case where we want to use layout qualifiers
-    // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the
-    // declaration varies in earlier GLSL specs. So it is simpler to omit it.
-    if (fTopLeftFragPosRead) {
-        fSetupFragPosition = true;
-        return "gl_FragCoord";
-    } else if (fGpu->glCaps().fragCoordConventionsSupport()) {
-        if (!fSetupFragPosition) {
-            SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature));
-            fFSInputs.push_back().set(kVec4f_GrSLType,
-                                      GrGLShaderVar::kIn_TypeModifier,
-                                      "gl_FragCoord",
-                                      GrGLShaderVar::kDefault_Precision,
-                                      GrGLShaderVar::kUpperLeft_Origin);
-            fSetupFragPosition = true;
-        }
-        return "gl_FragCoord";
-    } else {
-        static const char* kCoordName = "fragCoordYDown";
-        if (!fSetupFragPosition) {
-            // temporarily change the stage index because we're inserting non-stage code.
-            CodeStage::AutoStageRestore csar(&fCodeStage, NULL);
-
-            SkASSERT(!fOutput.fUniformHandles.fRTHeightUni.isValid());
-            const char* rtHeightName;
-
-            fOutput.fUniformHandles.fRTHeightUni =
-                this->addUniform(kFragment_Visibility, kFloat_GrSLType, "RTHeight", &rtHeightName);
-
-            this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, gl_FragCoord.zw);\n",
-                                   kCoordName, rtHeightName);
-            fSetupFragPosition = true;
-        }
-        SkASSERT(fOutput.fUniformHandles.fRTHeightUni.isValid());
-        return kCoordName;
-    }
-}
-
-void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType,
-                                       const char* name,
-                                       int argCnt,
-                                       const GrGLShaderVar* args,
-                                       const char* body,
-                                       SkString* outName) {
-    fFSFunctions.append(GrGLSLTypeString(returnType));
-    this->nameVariable(outName, '\0', name);
-    fFSFunctions.appendf(" %s", outName->c_str());
-    fFSFunctions.append("(");
-    for (int i = 0; i < argCnt; ++i) {
-        args[i].appendDecl(this->ctxInfo(), &fFSFunctions);
-        if (i < argCnt - 1) {
-            fFSFunctions.append(", ");
-        }
-    }
-    fFSFunctions.append(") {\n");
-    fFSFunctions.append(body);
-    fFSFunctions.append("}\n\n");
-}
-
-namespace {
-
-inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
-                                               GrGLStandard standard,
-                                               SkString* str) {
-    // Desktop GLSL has added precision qualifiers but they don't do anything.
-    if (kGLES_GrGLStandard == standard) {
-        switch (p) {
-            case GrGLShaderVar::kHigh_Precision:
-                str->append("precision highp float;\n");
-                break;
-            case GrGLShaderVar::kMedium_Precision:
-                str->append("precision mediump float;\n");
-                break;
-            case GrGLShaderVar::kLow_Precision:
-                str->append("precision lowp float;\n");
-                break;
-            case GrGLShaderVar::kDefault_Precision:
-                SkFAIL("Default precision now allowed.");
-            default:
-                SkFAIL("Unknown precision value.");
-        }
-    }
-}
-}
-
-void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const {
-    for (int i = 0; i < vars.count(); ++i) {
-        vars[i].appendDecl(this->ctxInfo(), out);
-        out->append(";\n");
-    }
-}
-
-void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility,
-                                           SkString* out) const {
-    for (int i = 0; i < fUniforms.count(); ++i) {
-        if (fUniforms[i].fVisibility & visibility) {
-            fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
-            out->append(";\n");
-        }
-    }
-}
-
-void GrGLShaderBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* programEffectsBuilder,
-                                             const GrEffectStage* effectStages[],
-                                             const EffectKey effectKeys[],
-                                             int effectCnt,
-                                             GrGLSLExpr4* fsInOutColor) {
-    bool effectEmitted = false;
-
-    GrGLSLExpr4 inColor = *fsInOutColor;
-    GrGLSLExpr4 outColor;
-
-    for (int e = 0; e < effectCnt; ++e) {
-        SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect());
-        const GrEffectStage& stage = *effectStages[e];
-
-        CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
-
-        if (inColor.isZeros()) {
-            SkString inColorName;
-
-            // Effects have no way to communicate zeros, they treat an empty string as ones.
-            this->nameVariable(&inColorName, '\0', "input");
-            this->fsCodeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor.c_str());
-            inColor = inColorName;
-        }
-
-        // create var to hold stage result
-        SkString outColorName;
-        this->nameVariable(&outColorName, '\0', "output");
-        this->fsCodeAppendf("\tvec4 %s;\n", outColorName.c_str());
-        outColor = outColorName;
-
-
-        programEffectsBuilder->emitEffect(stage,
-                                          effectKeys[e],
-                                          outColor.c_str(),
-                                          inColor.isOnes() ? NULL : inColor.c_str(),
-                                          fCodeStage.stageIndex());
-
-        inColor = outColor;
-        effectEmitted = true;
-    }
-
-    if (effectEmitted) {
-        *fsInOutColor = outColor;
-    }
-}
-
-const char* GrGLShaderBuilder::getColorOutputName() const {
-    return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor";
-}
-
-const char* GrGLShaderBuilder::enableSecondaryOutput() {
-    if (!fHasSecondaryOutput) {
-        fFSOutputs.push_back().set(kVec4f_GrSLType,
-                                   GrGLShaderVar::kOut_TypeModifier,
-                                   dual_source_output_name());
-        fHasSecondaryOutput = true;
-    }
-    return dual_source_output_name();
-}
-
-bool GrGLShaderBuilder::finish() {
-    SkASSERT(0 == fOutput.fProgramID);
-    GL_CALL_RET(fOutput.fProgramID, CreateProgram());
-    if (!fOutput.fProgramID) {
-        return false;
-    }
-
-    SkTDArray<GrGLuint> shadersToDelete;
-
-    if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) {
-        GL_CALL(DeleteProgram(fOutput.fProgramID));
-        return false;
-    }
-
-    this->bindProgramLocations(fOutput.fProgramID);
-    if (fUniformManager->isUsingBindUniform()) {
-        fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms);
-    }
-
-    GL_CALL(LinkProgram(fOutput.fProgramID));
-
-    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
-    bool checkLinked = !fGpu->ctxInfo().isChromium();
-#ifdef SK_DEBUG
-    checkLinked = true;
-#endif
-    if (checkLinked) {
-        GrGLint linked = GR_GL_INIT_ZERO;
-        GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_LINK_STATUS, &linked));
-        if (!linked) {
-            GrGLint infoLen = GR_GL_INIT_ZERO;
-            GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
-            SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
-            if (infoLen > 0) {
-                // retrieve length even though we don't need it to workaround
-                // bug in chrome cmd buffer param validation.
-                GrGLsizei length = GR_GL_INIT_ZERO;
-                GL_CALL(GetProgramInfoLog(fOutput.fProgramID,
-                                          infoLen+1,
-                                          &length,
-                                          (char*)log.get()));
-                GrPrintf((char*)log.get());
-            }
-            SkDEBUGFAIL("Error linking program");
-            GL_CALL(DeleteProgram(fOutput.fProgramID));
-            fOutput.fProgramID = 0;
-            return false;
-        }
-    }
-
-    if (!fUniformManager->isUsingBindUniform()) {
-        fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms);
-    }
-
-    for (int i = 0; i < shadersToDelete.count(); ++i) {
-      GL_CALL(DeleteShader(shadersToDelete[i]));
-    }
-
-    return true;
-}
-
-// Compiles a GL shader and attaches it to a program. Returns the shader ID if
-// successful, or 0 if not.
-static GrGLuint attach_shader(const GrGLContext& glCtx,
-                              GrGLuint programId,
-                              GrGLenum type,
-                              const SkString& shaderSrc) {
-    const GrGLInterface* gli = glCtx.interface();
-
-    GrGLuint shaderId;
-    GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
-    if (0 == shaderId) {
-        return 0;
-    }
-
-    const GrGLchar* sourceStr = shaderSrc.c_str();
-    GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size());
-    GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
-    GR_GL_CALL(gli, CompileShader(shaderId));
-
-    // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
-    bool checkCompiled = !glCtx.isChromium();
-#ifdef SK_DEBUG
-    checkCompiled = true;
-#endif
-    if (checkCompiled) {
-        GrGLint compiled = GR_GL_INIT_ZERO;
-        GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
-
-        if (!compiled) {
-            GrGLint infoLen = GR_GL_INIT_ZERO;
-            GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
-            SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
-            if (infoLen > 0) {
-                // retrieve length even though we don't need it to workaround bug in Chromium cmd
-                // buffer param validation.
-                GrGLsizei length = GR_GL_INIT_ZERO;
-                GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
-                                                 &length, (char*)log.get()));
-                GrPrintf(shaderSrc.c_str());
-                GrPrintf("\n%s", log.get());
-            }
-            SkDEBUGFAIL("Shader compilation failed!");
-            GR_GL_CALL(gli, DeleteShader(shaderId));
-            return 0;
-        }
-    }
-    if (c_PrintShaders) {
-        GrPrintf(shaderSrc.c_str());
-        GrPrintf("\n");
-    }
-
-    // Attach the shader, but defer deletion until after we have linked the program.
-    // This works around a bug in the Android emulator's GLES2 wrapper which
-    // will immediately delete the shader object and free its memory even though it's
-    // attached to a program, which then causes glLinkProgram to fail.
-    GR_GL_CALL(gli, AttachShader(programId, shaderId));
-
-    return shaderId;
-}
-
-bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const {
-    SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
-    fragShaderSrc.append(fFSExtensions);
-    append_default_precision_qualifier(kDefaultFragmentPrecision,
-                                       fGpu->glStandard(),
-                                       &fragShaderSrc);
-    this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc);
-    this->appendDecls(fFSInputs, &fragShaderSrc);
-    // We shouldn't have declared outputs on 1.10
-    SkASSERT(k110_GrGLSLGeneration != fGpu->glslGeneration() || fFSOutputs.empty());
-    this->appendDecls(fFSOutputs, &fragShaderSrc);
-    fragShaderSrc.append(fFSFunctions);
-    fragShaderSrc.append("void main() {\n");
-    fragShaderSrc.append(fFSCode);
-    fragShaderSrc.append("}\n");
-
-    GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc);
-    if (!fragShaderId) {
-        return false;
-    }
-
-    *shaderIds->append() = fragShaderId;
-
-    return true;
-}
-
-void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const {
-    if (fHasCustomColorOutput) {
-        GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name()));
-    }
-    if (fHasSecondaryOutput) {
-        GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_name()));
-    }
-}
-
-const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const {
-    return fGpu->ctxInfo();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu,
-                                             GrGLUniformManager* uniformManager,
-                                             const GrGLProgramDesc& desc)
-    : INHERITED(gpu, uniformManager, desc)
-    , fVSAttrs(kVarsPerBlock)
-    , fVSOutputs(kVarsPerBlock)
-    , fGSInputs(kVarsPerBlock)
-    , fGSOutputs(kVarsPerBlock) {
-}
-
-void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
-    const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
-
-    fOutput.fHasVertexShader = true;
-
-    fPositionVar = &fVSAttrs.push_back();
-    fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
-    if (-1 != header.fLocalCoordAttributeIndex) {
-        fLocalCoordsVar = &fVSAttrs.push_back();
-        fLocalCoordsVar->set(kVec2f_GrSLType,
-                             GrGLShaderVar::kAttribute_TypeModifier,
-                             "aLocalCoords");
-    } else {
-        fLocalCoordsVar = fPositionVar;
-    }
-
-    const char* viewMName;
-    fOutput.fUniformHandles.fViewMatrixUni =
-        this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kMat33f_GrSLType, "ViewM",
-                          &viewMName);
-
-    // Transform the position into Skia's device coords.
-    this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n",
-                        viewMName, fPositionVar->c_str());
-
-    // we output point size in the GS if present
-    if (header.fEmitsPointSize
-#if GR_GL_EXPERIMENTAL_GS
-        && !header.fExperimentalGS
-#endif
-        ) {
-        this->vsCodeAppend("\tgl_PointSize = 1.0;\n");
-    }
-
-    if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
-        this->addAttribute(kVec4f_GrSLType, color_attribute_name());
-        const char *vsName, *fsName;
-        this->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
-        this->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribute_name());
-        *color = fsName;
-    }
-
-    if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
-        this->addAttribute(kVec4f_GrSLType, coverage_attribute_name());
-        const char *vsName, *fsName;
-        this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
-        this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name());
-        *coverage = fsName;
-    }
-}
-
-void GrGLFullShaderBuilder::emitCodeAfterEffects() {
-    const char* rtAdjustName;
-    fOutput.fUniformHandles.fRTAdjustmentUni =
-        this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType, "rtAdjustment",
-                         &rtAdjustName);
-
-    // Transform from Skia's device coords to GL's normalized device coords.
-    this->vsCodeAppendf(
-        "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);\n",
-        rtAdjustName, rtAdjustName);
-}
-
-bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) {
-    for (int i = 0; i < fVSAttrs.count(); ++i) {
-        const GrGLShaderVar& attr = fVSAttrs[i];
-        // if attribute already added, don't add it again
-        if (attr.getName().equals(name)) {
-            SkASSERT(attr.getType() == type);
-            return false;
-        }
-    }
-    fVSAttrs.push_back().set(type,
-                             GrGLShaderVar::kAttribute_TypeModifier,
-                             name);
-    return true;
-}
-
-bool GrGLFullShaderBuilder::addEffectAttribute(int attributeIndex,
-                                               GrSLType type,
-                                               const SkString& name) {
-    if (!this->addAttribute(type, name.c_str())) {
-        return false;
-    }
-
-    fEffectAttributes.push_back().set(attributeIndex, name);
-    return true;
-}
-
-void GrGLFullShaderBuilder::addVarying(GrSLType type,
-                                       const char* name,
-                                       const char** vsOutName,
-                                       const char** fsInName) {
-    fVSOutputs.push_back();
-    fVSOutputs.back().setType(type);
-    fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
-    this->nameVariable(fVSOutputs.back().accessName(), 'v', name);
-
-    if (vsOutName) {
-        *vsOutName = fVSOutputs.back().getName().c_str();
-    }
-    // input to FS comes either from VS or GS
-    const SkString* fsName;
-#if GR_GL_EXPERIMENTAL_GS
-    if (this->desc().getHeader().fExperimentalGS) {
-        // if we have a GS take each varying in as an array
-        // and output as non-array.
-        fGSInputs.push_back();
-        fGSInputs.back().setType(type);
-        fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
-        fGSInputs.back().setUnsizedArray();
-        *fGSInputs.back().accessName() = fVSOutputs.back().getName();
-        fGSOutputs.push_back();
-        fGSOutputs.back().setType(type);
-        fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
-        this->nameVariable(fGSOutputs.back().accessName(), 'g', name);
-        fsName = fGSOutputs.back().accessName();
-    } else
-#endif
-    {
-        fsName = fVSOutputs.back().accessName();
-    }
-    this->fsInputAppend().set(type, GrGLShaderVar::kVaryingIn_TypeModifier, *fsName);
-    if (fsInName) {
-        *fsInName = fsName->c_str();
-    }
-}
-
-const SkString* GrGLFullShaderBuilder::getEffectAttributeName(int attributeIndex) const {
-    const AttributePair* attribEnd = fEffectAttributes.end();
-    for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
-        if (attrib->fIndex == attributeIndex) {
-            return &attrib->fName;
-        }
-    }
-
-    return NULL;
-}
-
-GrGLProgramEffects* GrGLFullShaderBuilder::createAndEmitEffects(
-        const GrEffectStage* effectStages[],
-        const EffectKey effectKeys[],
-        int effectCnt,
-        GrGLSLExpr4* inOutFSColor) {
-
-    GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt);
-    this->INHERITED::createAndEmitEffects(&programEffectsBuilder,
-                                          effectStages,
-                                          effectKeys,
-                                          effectCnt,
-                                          inOutFSColor);
-    return programEffectsBuilder.finish();
-}
-
-bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId,
-                                                    SkTDArray<GrGLuint>* shaderIds) const {
-    const GrGLContext& glCtx = this->gpu()->glContext();
-    SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
-    this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc);
-    this->appendDecls(fVSAttrs, &vertShaderSrc);
-    this->appendDecls(fVSOutputs, &vertShaderSrc);
-    vertShaderSrc.append("void main() {\n");
-    vertShaderSrc.append(fVSCode);
-    vertShaderSrc.append("}\n");
-    GrGLuint vertShaderId = attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc);
-    if (!vertShaderId) {
-        return false;
-    }
-    *shaderIds->append() = vertShaderId;
-
-#if GR_GL_EXPERIMENTAL_GS
-    if (this->desc().getHeader().fExperimentalGS) {
-        SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration);
-        SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
-        geomShaderSrc.append("layout(triangles) in;\n"
-                             "layout(triangle_strip, max_vertices = 6) out;\n");
-        this->appendDecls(fGSInputs, &geomShaderSrc);
-        this->appendDecls(fGSOutputs, &geomShaderSrc);
-        geomShaderSrc.append("void main() {\n");
-        geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n"
-                             "\t\tgl_Position = gl_in[i].gl_Position;\n");
-        if (this->desc().getHeader().fEmitsPointSize) {
-            geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
-        }
-        SkASSERT(fGSInputs.count() == fGSOutputs.count());
-        for (int i = 0; i < fGSInputs.count(); ++i) {
-            geomShaderSrc.appendf("\t\t%s = %s[i];\n",
-                                  fGSOutputs[i].getName().c_str(),
-                                  fGSInputs[i].getName().c_str());
-        }
-        geomShaderSrc.append("\t\tEmitVertex();\n"
-                             "\t}\n"
-                             "\tEndPrimitive();\n");
-        geomShaderSrc.append("}\n");
-        GrGLuint geomShaderId = attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc);
-        if (!geomShaderId) {
-            return false;
-        }
-        *shaderIds->append() = geomShaderId;
-    }
-#endif
-
-    return this->INHERITED::compileAndAttachShaders(programId, shaderIds);
-}
-
-void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const {
-    this->INHERITED::bindProgramLocations(programId);
-
-    const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
-
-    // Bind the attrib locations to same values for all shaders
-    SkASSERT(-1 != header.fPositionAttributeIndex);
-    GL_CALL(BindAttribLocation(programId,
-                               header.fPositionAttributeIndex,
-                               fPositionVar->c_str()));
-    if (-1 != header.fLocalCoordAttributeIndex) {
-        GL_CALL(BindAttribLocation(programId,
-                                   header.fLocalCoordAttributeIndex,
-                                   fLocalCoordsVar->c_str()));
-    }
-    if (-1 != header.fColorAttributeIndex) {
-        GL_CALL(BindAttribLocation(programId,
-                                   header.fColorAttributeIndex,
-                                   color_attribute_name()));
-    }
-    if (-1 != header.fCoverageAttributeIndex) {
-        GL_CALL(BindAttribLocation(programId,
-                                   header.fCoverageAttributeIndex,
-                                   coverage_attribute_name()));
-    }
-
-    const AttributePair* attribEnd = fEffectAttributes.end();
-    for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
-         GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_str()));
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu,
-                                                             GrGLUniformManager* uniformManager,
-                                                             const GrGLProgramDesc& desc)
-    : INHERITED(gpu, uniformManager, desc) {
-    SkASSERT(!desc.getHeader().fHasVertexCode);
-    SkASSERT(gpu->glCaps().pathRenderingSupport());
-    SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
-    SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
-}
-
-int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) {
-    int firstFreeCoordSet = fOutput.fTexCoordSetCnt;
-    fOutput.fTexCoordSetCnt += count;
-    SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fOutput.fTexCoordSetCnt);
-    return firstFreeCoordSet;
-}
-
-GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects(
-        const GrEffectStage* effectStages[],
-        const EffectKey effectKeys[],
-        int effectCnt,
-        GrGLSLExpr4* inOutFSColor) {
-
-    GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this,
-                                                                 effectCnt);
-    this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder,
-                                          effectStages,
-                                          effectKeys,
-                                          effectCnt,
-                                          inOutFSColor);
-    return pathTexGenEffectsBuilder.finish();
-}
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
deleted file mode 100644
index 7e71acf..0000000
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLShaderBuilder_DEFINED
-#define GrGLShaderBuilder_DEFINED
-
-#include "GrAllocator.h"
-#include "GrBackendEffectFactory.h"
-#include "GrColor.h"
-#include "GrEffect.h"
-#include "SkTypes.h"
-#include "gl/GrGLProgramEffects.h"
-#include "gl/GrGLSL.h"
-#include "gl/GrGLUniformManager.h"
-
-#include <stdarg.h>
-
-class GrGLContextInfo;
-class GrEffectStage;
-class GrGLProgramDesc;
-
-/**
-  Contains all the incremental state of a shader as it is being built,as well as helpers to
-  manipulate that state.
-*/
-class GrGLShaderBuilder {
-public:
-    typedef GrTAllocator<GrGLShaderVar> VarArray;
-    typedef GrBackendEffectFactory::EffectKey EffectKey;
-    typedef GrGLProgramEffects::TextureSampler TextureSampler;
-    typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
-    typedef GrGLUniformManager::BuilderUniform BuilderUniform;
-
-    enum ShaderVisibility {
-        kVertex_Visibility   = 0x1,
-        kGeometry_Visibility = 0x2,
-        kFragment_Visibility = 0x4,
-    };
-
-    typedef GrGLUniformManager::UniformHandle UniformHandle;
-
-    // Handles for program uniforms (other than per-effect uniforms)
-    struct UniformHandles {
-        UniformHandle       fViewMatrixUni;
-        UniformHandle       fRTAdjustmentUni;
-        UniformHandle       fColorUni;
-        UniformHandle       fCoverageUni;
-
-        // We use the render target height to provide a y-down frag coord when specifying
-        // origin_upper_left is not supported.
-        UniformHandle       fRTHeightUni;
-
-        // Uniforms for computing texture coords to do the dst-copy lookup
-        UniformHandle       fDstCopyTopLeftUni;
-        UniformHandle       fDstCopyScaleUni;
-        UniformHandle       fDstCopySamplerUni;
-    };
-
-    struct GenProgramOutput {
-        GenProgramOutput()
-            : fColorEffects(NULL)
-            , fCoverageEffects(NULL)
-            , fHasVertexShader(false)
-            , fTexCoordSetCnt(0)
-            , fProgramID(0) {}
-
-        GenProgramOutput(const GenProgramOutput& other) {
-            *this = other;
-        }
-
-        GenProgramOutput& operator=(const GenProgramOutput& other) {
-            fColorEffects.reset(SkRef(other.fColorEffects.get()));
-            fCoverageEffects.reset(SkRef(other.fCoverageEffects.get()));
-            fUniformHandles = other.fUniformHandles;
-            fHasVertexShader = other.fHasVertexShader;
-            fTexCoordSetCnt = other.fTexCoordSetCnt;
-            fProgramID = other.fProgramID;
-            return *this;
-        }
-
-        SkAutoTUnref<GrGLProgramEffects> fColorEffects;
-        SkAutoTUnref<GrGLProgramEffects> fCoverageEffects;
-        UniformHandles                   fUniformHandles;
-        bool                             fHasVertexShader;
-        int                              fTexCoordSetCnt;
-        GrGLuint                         fProgramID;
-    };
-
-    static bool GenProgram(GrGpuGL* gpu,
-                           GrGLUniformManager* uman,
-                           const GrGLProgramDesc& desc,
-                           const GrEffectStage* inColorStages[],
-                           const GrEffectStage* inCoverageStages[],
-                           GenProgramOutput* output);
-
-    virtual ~GrGLShaderBuilder() {}
-
-    /**
-     * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
-     * if code is added that uses one of these features without calling enableFeature()
-     */
-    enum GLSLFeature {
-        kStandardDerivatives_GLSLFeature = 0,
-
-        kLastGLSLFeature = kStandardDerivatives_GLSLFeature
-    };
-
-    /**
-     * If the feature is supported then true is returned and any necessary #extension declarations
-     * are added to the shaders. If the feature is not supported then false will be returned.
-     */
-    bool enableFeature(GLSLFeature);
-
-    /**
-     * Called by GrGLEffects to add code the fragment shader.
-     */
-    void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
-        va_list args;
-        va_start(args, format);
-        fFSCode.appendVAList(format, args);
-        va_end(args);
-    }
-
-    void fsCodeAppend(const char* str) { fFSCode.append(str); }
-
-    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
-        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
-        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
-    void appendTextureLookup(SkString* out,
-                             const TextureSampler&,
-                             const char* coordName,
-                             GrSLType coordType = kVec2f_GrSLType) const;
-
-    /** Version of above that appends the result to the fragment shader code instead.*/
-    void fsAppendTextureLookup(const TextureSampler&,
-                               const char* coordName,
-                               GrSLType coordType = kVec2f_GrSLType);
-
-
-    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
-        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
-        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
-        called. */
-    void fsAppendTextureLookupAndModulate(const char* modulation,
-                                          const TextureSampler&,
-                                          const char* coordName,
-                                          GrSLType coordType = kVec2f_GrSLType);
-
-    /** Emits a helper function outside of main() in the fragment shader. */
-    void fsEmitFunction(GrSLType returnType,
-                        const char* name,
-                        int argCnt,
-                        const GrGLShaderVar* args,
-                        const char* body,
-                        SkString* outName);
-
-    typedef uint8_t DstReadKey;
-    typedef uint8_t FragPosKey;
-
-    /**  Returns a key for adding code to read the copy-of-dst color in service of effects that
-         require reading the dst. It must not return 0 because 0 indicates that there is no dst
-         copy read at all (in which case this function should not be called). */
-    static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
-
-    /** Returns a key for reading the fragment location. This should only be called if there is an
-        effect that will requires the fragment position. If the fragment position is not required,
-        the key is 0. */
-    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
-
-    /** If texture swizzling is available using tex parameters then it is preferred over mangling
-        the generated shader code. This potentially allows greater reuse of cached shaders. */
-    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
-
-    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
-        visibility is a bitfield of ShaderVisibility values indicating from which shaders the
-        uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
-        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
-        it will refer to the final uniform name after return. Use the addUniformArray variant to add
-        an array of uniforms. */
-    GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
-                                                 GrSLType type,
-                                                 const char* name,
-                                                 const char** outName = NULL) {
-        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
-    }
-    GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
-                                                      GrSLType type,
-                                                      const char* name,
-                                                      int arrayCount,
-                                                      const char** outName = NULL);
-
-    const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
-        return fUniformManager->getBuilderUniform(fUniforms, u).fVariable;
-    }
-
-    /**
-     * Shortcut for getUniformVariable(u).c_str()
-     */
-    const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
-        return this->getUniformVariable(u).c_str();
-    }
-
-    /**
-     * This returns a variable name to access the 2D, perspective correct version of the coords in
-     * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
-     * perspective divide into the fragment shader (xy / z) to convert them to 2D.
-     */
-    SkString ensureFSCoords2D(const TransformedCoordsArray&, int index);
-
-    /** Returns a variable name that represents the position of the fragment in the FS. The position
-        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
-    const char* fragmentPosition();
-
-    /** Returns the variable name that holds the color of the destination pixel. This may be NULL if
-        no effect advertised that it will read the destination. */
-    const char* dstColor();
-
-    const GrGLContextInfo& ctxInfo() const;
-
-    /**
-     * Helper for begining and ending a block in the fragment code. TODO: Make GrGLShaderBuilder
-     * aware of all blocks and turn single \t's into the correct number of tabs (or spaces) so that
-     * our shaders print pretty without effect writers tracking indentation.
-     */
-    class FSBlock {
-    public:
-        FSBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
-            SkASSERT(NULL != builder);
-            fBuilder->fsCodeAppend("\t{\n");
-        }
-
-        ~FSBlock() {
-            fBuilder->fsCodeAppend("\t}\n");
-        }
-    private:
-        GrGLShaderBuilder* fBuilder;
-    };
-
-protected:
-    GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager*, const GrGLProgramDesc&);
-
-    GrGpuGL* gpu() const { return fGpu; }
-
-    const GrGLProgramDesc& desc() const { return fDesc; }
-
-    /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
-    GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
-
-    // Helper for emitEffects().
-    void createAndEmitEffects(GrGLProgramEffectsBuilder*,
-                              const GrEffectStage* effectStages[],
-                              const EffectKey effectKeys[],
-                              int effectCnt,
-                              GrGLSLExpr4* inOutFSColor);
-
-    // Generates a name for a variable. The generated string will be name prefixed by the prefix
-    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
-    // generating stage code.
-    void nameVariable(SkString* out, char prefix, const char* name);
-
-    virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
-
-    virtual void bindProgramLocations(GrGLuint programId) const;
-
-    void appendDecls(const VarArray&, SkString*) const;
-    void appendUniformDecls(ShaderVisibility, SkString*) const;
-
-    const GenProgramOutput& getOutput() const { return fOutput; }
-
-    GenProgramOutput fOutput;
-
-private:
-    class CodeStage : SkNoncopyable {
-    public:
-        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
-
-        bool inStageCode() const {
-            this->validate();
-            return NULL != fEffectStage;
-        }
-
-        const GrEffectStage* effectStage() const {
-            this->validate();
-            return fEffectStage;
-        }
-
-        int stageIndex() const {
-            this->validate();
-            return fCurrentIndex;
-        }
-
-        class AutoStageRestore : SkNoncopyable {
-        public:
-            AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
-                SkASSERT(NULL != codeStage);
-                fSavedIndex = codeStage->fCurrentIndex;
-                fSavedEffectStage = codeStage->fEffectStage;
-
-                if (NULL == newStage) {
-                    codeStage->fCurrentIndex = -1;
-                } else {
-                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
-                }
-                codeStage->fEffectStage = newStage;
-
-                fCodeStage = codeStage;
-            }
-            ~AutoStageRestore() {
-                fCodeStage->fCurrentIndex = fSavedIndex;
-                fCodeStage->fEffectStage = fSavedEffectStage;
-            }
-        private:
-            CodeStage*              fCodeStage;
-            int                     fSavedIndex;
-            const GrEffectStage*    fSavedEffectStage;
-        };
-    private:
-        void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
-        int                     fNextIndex;
-        int                     fCurrentIndex;
-        const GrEffectStage*    fEffectStage;
-    } fCodeStage;
-
-    bool genProgram(const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[]);
-
-    /**
-     * The base class will emit the fragment code that precedes the per-effect code and then call
-     * this function. The subclass can use it to insert additional fragment code that should
-     * execute before the effects' code and/or emit other shaders (e.g. geometry, vertex).
-     *
-     * The subclass can modify the initial color or coverage 
-     */
-    virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) = 0;
-
-    /**
-    * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
-    * deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key
-    * generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and
-    * is updated to be the output color of the last stage.
-    * The handles to texture samplers for effectStage[i] are added to
-    * effectSamplerHandles[i].
-    */
-    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
-                                                     const EffectKey effectKeys[],
-                                                     int effectCnt,
-                                                     GrGLSLExpr4* inOutFSColor) = 0;
-
-    /**
-     * Similar to emitCodeBeforeEffects() but called after per-effect code is emitted.
-     */
-    virtual void emitCodeAfterEffects() = 0;
-
-    /** Enables using the secondary color output and returns the name of the var in which it is
-        to be stored */
-    const char* enableSecondaryOutput();
-    /** Gets the name of the primary color output. */
-    const char* getColorOutputName() const;
-
-    /**
-     * Compiles all the shaders, links them into a program, and writes the program id to the output
-     * struct.
-     **/
-    bool finish();
-
-    /**
-     * Features that should only be enabled by GrGLShaderBuilder itself.
-     */
-    enum GLSLPrivateFeature {
-        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
-        kEXTShaderFramebufferFetch_GLSLPrivateFeature,
-        kNVShaderFramebufferFetch_GLSLPrivateFeature,
-    };
-    bool enablePrivateFeature(GLSLPrivateFeature);
-
-    // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
-    // track the enables separately for each shader.
-    void addFSFeature(uint32_t featureBit, const char* extensionName);
-
-    // Interpretation of DstReadKey when generating code
-    enum {
-        kNoDstRead_DstReadKey           = 0,
-        kYesDstRead_DstReadKeyBit       = 0x1, // Set if we do a dst-copy-read.
-        kUseAlphaConfig_DstReadKeyBit   = 0x2, // Set if dst-copy config is alpha only.
-        kTopLeftOrigin_DstReadKeyBit    = 0x4, // Set if dst-copy origin is top-left.
-    };
-
-    enum {
-        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
-        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
-        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
-    };
-
-    const GrGLProgramDesc&                  fDesc;
-    GrGpuGL*                                fGpu;
-    SkAutoTUnref<GrGLUniformManager>        fUniformManager;
-    uint32_t                                fFSFeaturesAddedMask;
-    SkString                                fFSFunctions;
-    SkString                                fFSExtensions;
-    VarArray                                fFSInputs;
-    VarArray                                fFSOutputs;
-    GrGLUniformManager::BuilderUniformArray fUniforms;
-
-    SkString                                fFSCode;
-
-    bool                                    fSetupFragPosition;
-    bool                                    fTopLeftFragPosRead;
-
-    bool                                    fHasCustomColorOutput;
-    bool                                    fHasSecondaryOutput;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-class GrGLFullShaderBuilder : public GrGLShaderBuilder {
-public:
-    GrGLFullShaderBuilder(GrGpuGL*, GrGLUniformManager*, const GrGLProgramDesc&);
-
-    /**
-     * Called by GrGLEffects to add code to one of the shaders.
-     */
-    void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
-        va_list args;
-        va_start(args, format);
-        fVSCode.appendVAList(format, args);
-        va_end(args);
-    }
-
-    void vsCodeAppend(const char* str) { fVSCode.append(str); }
-
-   /** Add a vertex attribute to the current program that is passed in from the vertex data.
-       Returns false if the attribute was already there, true otherwise. */
-    bool addAttribute(GrSLType type, const char* name);
-
-   /** Add a varying variable to the current program to pass values between vertex and fragment
-        shaders. If the last two parameters are non-NULL, they are filled in with the name
-        generated. */
-    void addVarying(GrSLType type,
-                    const char* name,
-                    const char** vsOutName = NULL,
-                    const char** fsInName = NULL);
-
-    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
-        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
-      */
-    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
-
-    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
-        as positionAttribute() or it may not be. It depends upon whether the rendering code
-        specified explicit local coords or not in the GrDrawState. */
-    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
-
-    /**
-     * Are explicit local coordinates provided as input to the vertex shader.
-     */
-    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
-
-    bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
-    const SkString* getEffectAttributeName(int attributeIndex) const;
-
-private:
-    virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) SK_OVERRIDE;
-
-    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
-                                                     const EffectKey effectKeys[],
-                                                     int effectCnt,
-                                                     GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
-
-    virtual void emitCodeAfterEffects() SK_OVERRIDE;
-
-    virtual bool compileAndAttachShaders(GrGLuint programId,
-                                         SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE;
-
-    virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE;
-
-    VarArray                            fVSAttrs;
-    VarArray                            fVSOutputs;
-    VarArray                            fGSInputs;
-    VarArray                            fGSOutputs;
-
-    SkString                            fVSCode;
-
-    struct AttributePair {
-        void set(int index, const SkString& name) {
-            fIndex = index; fName = name;
-        }
-        int      fIndex;
-        SkString fName;
-    };
-    SkSTArray<10, AttributePair, true>  fEffectAttributes;
-
-    GrGLShaderVar*                      fPositionVar;
-    GrGLShaderVar*                      fLocalCoordsVar;
-
-    typedef GrGLShaderBuilder INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-class GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder {
-public:
-    GrGLFragmentOnlyShaderBuilder(GrGpuGL*, GrGLUniformManager*, const GrGLProgramDesc&);
-
-    int addTexCoordSets(int count);
-
-private:
-    virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) SK_OVERRIDE {}
-
-    virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
-                                                     const EffectKey effectKeys[],
-                                                     int effectCnt,
-                                                     GrGLSLExpr4* inOutFSColor) SK_OVERRIDE;
-
-    virtual void emitCodeAfterEffects() SK_OVERRIDE {}
-
-    typedef GrGLShaderBuilder INHERITED;
-};
-
-#endif
diff --git a/src/gpu/gl/GrGLShaderVar.h b/src/gpu/gl/GrGLShaderVar.h
index 68c4bbd..8e7e36e 100644
--- a/src/gpu/gl/GrGLShaderVar.h
+++ b/src/gpu/gl/GrGLShaderVar.h
@@ -10,43 +10,15 @@
 
 #include "GrGLContext.h"
 #include "GrGLSL.h"
-#include "SkString.h"
+#include "GrShaderVar.h"
 
 #define USE_UNIFORM_FLOAT_ARRAYS true
 
 /**
  * Represents a variable in a shader
  */
-class GrGLShaderVar {
+class GrGLShaderVar : public GrShaderVar {
 public:
-
-    /**
-     * Early versions of GLSL have Varying and Attribute; those are later
-     * deprecated, but we still need to know whether a Varying variable
-     * should be treated as In or Out.
-     */
-    enum TypeModifier {
-        kNone_TypeModifier,
-        kOut_TypeModifier,
-        kIn_TypeModifier,
-        kInOut_TypeModifier,
-        kUniform_TypeModifier,
-        kAttribute_TypeModifier,
-        kVaryingIn_TypeModifier,
-        kVaryingOut_TypeModifier
-    };
-
-    enum Precision {
-        kLow_Precision,         // lowp
-        kMedium_Precision,      // mediump
-        kHigh_Precision,        // highp
-        kDefault_Precision,     // Default for the current context. We make
-                                // fragment shaders default to mediump on ES2
-                                // because highp support is not guaranteed (and
-                                // we haven't been motivated to test for it).
-                                // Otherwise, highp.
-    };
-
     /**
      * See GL_ARB_fragment_coord_conventions.
      */
@@ -58,36 +30,43 @@
     /**
      * Defaults to a float with no precision specifier
      */
-    GrGLShaderVar() {
-        fType = kFloat_GrSLType;
-        fTypeModifier = kNone_TypeModifier;
-        fCount = kNonArray;
-        fPrecision = kDefault_Precision;
-        fOrigin = kDefault_Origin;
-        fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
+    GrGLShaderVar()
+        : GrShaderVar()
+        , fOrigin(kDefault_Origin)
+        , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
     }
 
     GrGLShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
-                  Precision precision = kDefault_Precision) {
+                  Precision precision = kDefault_Precision)
+        : GrShaderVar(name, type, arrayCount, precision)
+        , fOrigin(kDefault_Origin)
+        , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
         SkASSERT(kVoid_GrSLType != type);
-        fType = type;
-        fTypeModifier = kNone_TypeModifier;
-        fCount = arrayCount;
-        fPrecision = precision;
         fOrigin = kDefault_Origin;
         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
-        fName = name;
+    }
+
+    GrGLShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
+                  int arrayCount = kNonArray, Precision precision = kDefault_Precision)
+        : GrShaderVar(name, type, typeModifier, arrayCount, precision)
+        , fOrigin(kDefault_Origin)
+        , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
+        SkASSERT(kVoid_GrSLType != type);
+    }
+
+    GrGLShaderVar(const GrShaderVar& var)
+        : GrShaderVar(var)
+        , fOrigin(kDefault_Origin)
+        , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
+        SkASSERT(kVoid_GrSLType != var.getType());
     }
 
     GrGLShaderVar(const GrGLShaderVar& var)
-        : fType(var.fType)
-        , fTypeModifier(var.fTypeModifier)
-        , fName(var.fName)
-        , fCount(var.fCount)
-        , fPrecision(var.fPrecision)
+        : GrShaderVar(var.c_str(), var.getType(), var.getTypeModifier(),
+                      var.getArrayCount(), var.getPrecision())
         , fOrigin(var.fOrigin)
         , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {
-        SkASSERT(kVoid_GrSLType != var.fType);
+        SkASSERT(kVoid_GrSLType != var.getType());
     }
 
     /**
@@ -108,11 +87,7 @@
              Origin origin = kDefault_Origin,
              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
         SkASSERT(kVoid_GrSLType != type);
-        fType = type;
-        fTypeModifier = typeModifier;
-        fName = name;
-        fCount = kNonArray;
-        fPrecision = precision;
+        INHERITED::set(type, typeModifier, name, precision);
         fOrigin = origin;
         fUseUniformFloatArrays = useUniformFloatArrays;
     }
@@ -127,11 +102,7 @@
              Origin origin = kDefault_Origin,
              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
         SkASSERT(kVoid_GrSLType != type);
-        fType = type;
-        fTypeModifier = typeModifier;
-        fName = name;
-        fCount = kNonArray;
-        fPrecision = precision;
+        INHERITED::set(type, typeModifier, name, precision);
         fOrigin = origin;
         fUseUniformFloatArrays = useUniformFloatArrays;
     }
@@ -147,11 +118,7 @@
              Origin origin = kDefault_Origin,
              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
         SkASSERT(kVoid_GrSLType != type);
-        fType = type;
-        fTypeModifier = typeModifier;
-        fName = name;
-        fCount = count;
-        fPrecision = precision;
+        INHERITED::set(type, typeModifier, name, count, precision);
         fOrigin = origin;
         fUseUniformFloatArrays = useUniformFloatArrays;
     }
@@ -167,83 +134,12 @@
              Origin origin = kDefault_Origin,
              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
         SkASSERT(kVoid_GrSLType != type);
-        fType = type;
-        fTypeModifier = typeModifier;
-        fName = name;
-        fCount = count;
-        fPrecision = precision;
+        INHERITED::set(type, typeModifier, name, count, precision);
         fOrigin = origin;
         fUseUniformFloatArrays = useUniformFloatArrays;
     }
 
     /**
-     * Is the var an array.
-     */
-    bool isArray() const { return kNonArray != fCount; }
-    /**
-     * Is this an unsized array, (i.e. declared with []).
-     */
-    bool isUnsizedArray() const { return kUnsizedArray == fCount; }
-    /**
-     * Get the array length of the var.
-     */
-    int getArrayCount() const { return fCount; }
-    /**
-     * Set the array length of the var
-     */
-    void setArrayCount(int count) { fCount = count; }
-    /**
-     * Set to be a non-array.
-     */
-    void setNonArray() { fCount = kNonArray; }
-    /**
-     * Set to be an unsized array.
-     */
-    void setUnsizedArray() { fCount = kUnsizedArray; }
-
-    /**
-     * Access the var name as a writable string
-     */
-    SkString* accessName() { return &fName; }
-    /**
-     * Set the var name
-     */
-    void setName(const SkString& n) { fName = n; }
-    void setName(const char* n) { fName = n; }
-
-    /**
-     * Get the var name.
-     */
-    const SkString& getName() const { return fName; }
-
-    /**
-     * Shortcut for this->getName().c_str();
-     */
-    const char* c_str() const { return this->getName().c_str(); }
-
-    /**
-     * Get the type of the var
-     */
-    GrSLType getType() const { return fType; }
-    /**
-     * Set the type of the var
-     */
-    void setType(GrSLType type) { fType = type; }
-
-    TypeModifier getTypeModifier() const { return fTypeModifier; }
-    void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
-
-    /**
-     * Get the precision of the var
-     */
-    Precision getPrecision() const { return fPrecision; }
-
-    /**
-     * Set the precision of the var
-     */
-    void setPrecision(Precision p) { fPrecision = p; }
-
-    /**
      * Get the origin of the var
      */
     Origin getOrigin() const { return fOrigin; }
@@ -346,15 +242,12 @@
         }
     }
 
-    GrSLType        fType;
-    TypeModifier    fTypeModifier;
-    SkString        fName;
-    int             fCount;
-    Precision       fPrecision;
     Origin          fOrigin;
     /// Work around driver bugs on some hardware that don't correctly
     /// support uniform float []
     bool            fUseUniformFloatArrays;
+
+    typedef GrShaderVar INHERITED;
 };
 
 #endif
diff --git a/src/gpu/gl/GrGLStencilBuffer.h b/src/gpu/gl/GrGLStencilBuffer.h
index 1cb0a33..024890d 100644
--- a/src/gpu/gl/GrGLStencilBuffer.h
+++ b/src/gpu/gl/GrGLStencilBuffer.h
@@ -32,6 +32,7 @@
         : GrStencilBuffer(gpu, isWrapped, width, height, format.fStencilBits, sampleCnt)
         , fFormat(format)
         , fRenderbufferID(rbid) {
+        this->registerWithCache();
     }
 
     virtual ~GrGLStencilBuffer();
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 856cfb1..202fc42 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -24,7 +24,7 @@
                                            textureDesc.fTextureID,
                                            textureDesc.fIsWrapped)));
 
-    if (NULL != rtDesc) {
+    if (rtDesc) {
         GrGLIRect vp;
         vp.fLeft   = 0;
         vp.fWidth  = textureDesc.fWidth;
@@ -33,6 +33,7 @@
 
         fRenderTarget.reset(SkNEW_ARGS(GrGLRenderTarget, (gpu, *rtDesc, vp, fTexIDObj, this)));
     }
+    this->registerWithCache();
 }
 
 GrGLTexture::GrGLTexture(GrGpuGL* gpu,
@@ -49,13 +50,12 @@
 }
 
 void GrGLTexture::onRelease() {
-    GPUGL->notifyTextureDelete(this);
     fTexIDObj.reset(NULL);
     INHERITED::onRelease();
 }
 
 void GrGLTexture::onAbandon() {
-    if (NULL != fTexIDObj.get()) {
+    if (fTexIDObj.get()) {
         fTexIDObj->abandon();
         fTexIDObj.reset(NULL);
     }
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index a8800fa..23ae3fa 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -89,7 +89,7 @@
         fTexParamsTimestamp = timestamp;
     }
 
-    GrGLuint textureID() const { return (NULL != fTexIDObj.get()) ? fTexIDObj->id() : 0; }
+    GrGLuint textureID() const { return (fTexIDObj.get()) ? fTexIDObj->id() : 0; }
 
 protected:
     // overrides of GrTexture
diff --git a/src/gpu/gl/GrGLUniformHandle.h b/src/gpu/gl/GrGLUniformHandle.h
index 797afff..42dbd10 100644
--- a/src/gpu/gl/GrGLUniformHandle.h
+++ b/src/gpu/gl/GrGLUniformHandle.h
@@ -8,8 +8,8 @@
 #ifndef GrUniformHandle_DEFINED
 #define GrUniformHandle_DEFINED
 
-inline GrGLUniformManager::UniformHandle GrGLUniformManager::UniformHandle::CreateFromUniformIndex(int index) {
-    return GrGLUniformManager::UniformHandle(index);
+inline GrGLProgramDataManager::UniformHandle GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(int index) {
+    return GrGLProgramDataManager::UniformHandle(index);
 }
 
 #endif
diff --git a/src/gpu/gl/GrGLUniformManager.h b/src/gpu/gl/GrGLUniformManager.h
deleted file mode 100644
index 6137bcd..0000000
--- a/src/gpu/gl/GrGLUniformManager.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLUniformManager_DEFINED
-#define GrGLUniformManager_DEFINED
-
-#include "gl/GrGLShaderVar.h"
-#include "gl/GrGLSL.h"
-#include "GrAllocator.h"
-
-#include "SkTArray.h"
-
-class GrGpuGL;
-class SkMatrix;
-
-/** Manages a program's uniforms.
-*/
-class GrGLUniformManager : public SkRefCnt {
-public:
-    // Opaque handle to a uniform
-    class UniformHandle {
-    public:
-        static UniformHandle CreateFromUniformIndex(int i);
-
-        bool isValid() const { return 0 != fValue; }
-
-        bool operator==(const UniformHandle& other) const { return other.fValue == fValue; }
-
-        UniformHandle()
-            : fValue(0) {
-        }
-
-    private:
-        UniformHandle(int value)
-            : fValue(~value) {
-            SkASSERT(isValid());
-        }
-
-        int toUniformIndex() const { SkASSERT(isValid()); return ~fValue; }
-
-        int fValue;
-        friend class GrGLUniformManager; // For accessing toUniformIndex().
-    };
-
-    GrGLUniformManager(GrGpuGL* gpu);
-
-    UniformHandle appendUniform(GrSLType type, int arrayCount = GrGLShaderVar::kNonArray);
-
-    /** Functions for uploading uniform values. The varities ending in v can be used to upload to an
-     *  array of uniforms. arrayCount must be <= the array count of the uniform.
-     */
-    void setSampler(UniformHandle, GrGLint texUnit) const;
-    void set1f(UniformHandle, GrGLfloat v0) const;
-    void set1fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
-    void set2f(UniformHandle, GrGLfloat, GrGLfloat) const;
-    void set2fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
-    void set3f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat) const;
-    void set3fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
-    void set4f(UniformHandle, GrGLfloat, GrGLfloat, GrGLfloat, GrGLfloat) const;
-    void set4fv(UniformHandle, int arrayCount, const GrGLfloat v[]) const;
-    // matrices are column-major, the first three upload a single matrix, the latter three upload
-    // arrayCount matrices into a uniform array.
-    void setMatrix3f(UniformHandle, const GrGLfloat matrix[]) const;
-    void setMatrix4f(UniformHandle, const GrGLfloat matrix[]) const;
-    void setMatrix3fv(UniformHandle, int arrayCount, const GrGLfloat matrices[]) const;
-    void setMatrix4fv(UniformHandle, int arrayCount, const GrGLfloat matrices[]) const;
-
-    // convenience method for uploading a SkMatrix to a 3x3 matrix uniform
-    void setSkMatrix(UniformHandle, const SkMatrix&) const;
-
-    struct BuilderUniform {
-        GrGLShaderVar fVariable;
-        uint32_t      fVisibility;
-    };
-    // This uses an allocator rather than array so that the GrGLShaderVars don't move in memory
-    // after they are inserted. Users of GrGLShaderBuilder get refs to the vars and ptrs to their
-    // name strings. Otherwise, we'd have to hand out copies.
-    typedef GrTAllocator<BuilderUniform> BuilderUniformArray;
-
-    /**
-     * Called by the GrGLShaderBuilder to know if the manager is using
-     * BindUniformLocation. In that case getUniformLocations must be called
-     * before the program is linked.
-     */
-    bool isUsingBindUniform() const { return fUsingBindUniform; }
-
-    /**
-     * Called by the GrGLShaderBuilder to get GL locations for all uniforms.
-     */
-    void getUniformLocations(GrGLuint programID, const BuilderUniformArray& uniforms);
-
-    /**
-     * Called by the GrGLShaderBuilder to access the array by the handle (index).
-     */
-    const BuilderUniform& getBuilderUniform(const BuilderUniformArray&, GrGLUniformManager::UniformHandle) const;
-
-private:
-    enum {
-        kUnusedUniform = -1,
-    };
-
-    struct Uniform {
-        GrGLint     fVSLocation;
-        GrGLint     fFSLocation;
-        GrSLType    fType;
-        int         fArrayCount;
-    };
-
-    bool fUsingBindUniform;
-    SkTArray<Uniform, true> fUniforms;
-    GrGpuGL* fGpu;
-
-    typedef SkRefCnt INHERITED;
-};
-
-#endif
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 0fa2d2c..1ef66e0 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -40,51 +40,16 @@
     uint32_t err = GR_GL_GET_ERROR(gl);
     if (GR_GL_NO_ERROR != err) {
         GrPrintf("---- glGetError 0x%x(%s)", err, get_error_string(err));
-        if (NULL != location) {
+        if (location) {
             GrPrintf(" at\n\t%s", location);
         }
-        if (NULL != call) {
+        if (call) {
             GrPrintf("\n\t\t%s", call);
         }
         GrPrintf("\n");
     }
 }
 
-namespace {
-// Mesa uses a non-standard version string of format: 1.4 Mesa <mesa_major>.<mesa_minor>.
-// The mapping of from mesa version to GL version came from here: http://www.mesa3d.org/intro.html
-bool get_gl_version_for_mesa(int mesaMajorVersion, int* major, int* minor) {
-    switch (mesaMajorVersion) {
-        case 2:
-        case 3:
-        case 4:
-        case 5:
-        case 6:
-            *major = 1;
-            *minor = mesaMajorVersion - 1;
-            return true;
-        case 7:
-            *major = 2;
-            *minor = 1;
-            return true;
-        case 8:
-            *major = 3;
-            *minor = 0;
-            return true;
-        case 9:
-            *major = 3;
-            *minor = 1;
-            return true;
-        case 10:
-            *major = 3;
-            *minor = 3;
-            return true;
-        default:
-            return false;
-    }
-}
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 #if GR_GL_LOG_CALLS
@@ -149,11 +114,7 @@
     int mesaMajor, mesaMinor;
     int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
     if (4 == n) {
-        if (get_gl_version_for_mesa(mesaMajor, &major, &minor)) {
-            return GR_GL_VER(major, minor);
-        } else {
-            return GR_GL_INVALID_VER;
-        }
+        return GR_GL_VER(major, minor);
     }
 
     n = sscanf(versionString, "%d.%d", &major, &minor);
@@ -206,7 +167,7 @@
 }
 
 GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
-    if (NULL != vendorString) {
+    if (vendorString) {
         if (0 == strcmp(vendorString, "ARM")) {
             return kARM_GrGLVendor;
         }
@@ -219,12 +180,15 @@
         if (0 == strcmp(vendorString, "Qualcomm")) {
             return kQualcomm_GrGLVendor;
         }
+        if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
+                return kNVIDIA_GrGLVendor;
+        }
     }
     return kOther_GrGLVendor;
 }
 
 GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
-    if (NULL != rendererString) {
+    if (rendererString) {
         if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
             return kTegra3_GrGLRenderer;
         } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
@@ -300,3 +264,28 @@
     dest[14] = 0;
     dest[15] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
 }
+
+GrGLenum GrToGLStencilFunc(GrStencilFunc basicFunc) {
+    static const GrGLenum gTable[] = {
+        GR_GL_ALWAYS,           // kAlways_StencilFunc
+        GR_GL_NEVER,            // kNever_StencilFunc
+        GR_GL_GREATER,          // kGreater_StencilFunc
+        GR_GL_GEQUAL,           // kGEqual_StencilFunc
+        GR_GL_LESS,             // kLess_StencilFunc
+        GR_GL_LEQUAL,           // kLEqual_StencilFunc,
+        GR_GL_EQUAL,            // kEqual_StencilFunc,
+        GR_GL_NOTEQUAL,         // kNotEqual_StencilFunc,
+    };
+    GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount);
+    GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
+    GR_STATIC_ASSERT(1 == kNever_StencilFunc);
+    GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
+    GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
+    GR_STATIC_ASSERT(4 == kLess_StencilFunc);
+    GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
+    GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
+    GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
+    SkASSERT((unsigned) basicFunc < kBasicStencilFuncCount);
+
+    return gTable[basicFunc];
+}
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 73fcec1..06210ee 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -10,6 +10,7 @@
 
 #include "gl/GrGLInterface.h"
 #include "GrGLDefines.h"
+#include "GrStencil.h"
 
 class SkMatrix;
 
@@ -34,6 +35,7 @@
     kImagination_GrGLVendor,
     kIntel_GrGLVendor,
     kQualcomm_GrGLVendor,
+    kNVIDIA_GrGLVendor,
 
     kOther_GrGLVendor
 };
@@ -180,4 +182,7 @@
 // call glGetError without doing a redundant error check or logging.
 #define GR_GL_GET_ERROR(IFACE) (IFACE)->fFunctions.fGetError()
 
+GrGLenum GrToGLStencilFunc(GrStencilFunc basicFunc);
+
+
 #endif
diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp
index 66feb82..4acf292 100644
--- a/src/gpu/gl/GrGLVertexArray.cpp
+++ b/src/gpu/gl/GrGLVertexArray.cpp
@@ -73,6 +73,7 @@
     , fID(id)
     , fAttribArrays(attribCount)
     , fIndexBufferIDIsValid(false) {
+    this->registerWithCache();
 }
 
 void GrGLVertexArray::onAbandon() {
@@ -99,7 +100,7 @@
 
 GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(const GrGLIndexBuffer* buffer) {
     GrGLAttribArrayState* state = this->bind();
-    if (NULL != state && NULL != buffer) {
+    if (state && buffer) {
         GrGLuint bufferID = buffer->bufferID();
         if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) {
             GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID));
diff --git a/src/gpu/gl/GrGLVertexArray.h b/src/gpu/gl/GrGLVertexArray.h
index 0e5bffe..f4eb3d5 100644
--- a/src/gpu/gl/GrGLVertexArray.h
+++ b/src/gpu/gl/GrGLVertexArray.h
@@ -8,7 +8,7 @@
 #ifndef GrGLVertexArray_DEFINED
 #define GrGLVertexArray_DEFINED
 
-#include "GrGpuObject.h"
+#include "GrGpuResource.h"
 #include "GrTypesPriv.h"
 #include "gl/GrGLDefines.h"
 #include "gl/GrGLFunctions.h"
@@ -130,7 +130,7 @@
  * This class represents an OpenGL vertex array object. It manages the lifetime of the vertex array
  * and is used to track the state of the vertex array to avoid redundant GL calls.
  */
-class GrGLVertexArray : public GrGpuObject {
+class GrGLVertexArray : public GrGpuResource {
 public:
     GrGLVertexArray(GrGpuGL* gpu, GrGLint id, int attribCount);
 
@@ -170,7 +170,7 @@
     GrGLuint                fIndexBufferID;
     bool                    fIndexBufferIDIsValid;
 
-    typedef GrGpuObject INHERITED;
+    typedef GrGpuResource INHERITED;
 };
 
 #endif
diff --git a/src/gpu/gl/GrGLVertexBuffer.cpp b/src/gpu/gl/GrGLVertexBuffer.cpp
index a13ad12..d6b6301 100644
--- a/src/gpu/gl/GrGLVertexBuffer.cpp
+++ b/src/gpu/gl/GrGLVertexBuffer.cpp
@@ -11,6 +11,7 @@
 GrGLVertexBuffer::GrGLVertexBuffer(GrGpuGL* gpu, const Desc& desc)
     : INHERITED(gpu, desc.fIsWrapped, desc.fSizeInBytes, desc.fDynamic, 0 == desc.fID)
     , fImpl(gpu, desc, GR_GL_ARRAY_BUFFER) {
+    this->registerWithCache();
 }
 
 void GrGLVertexBuffer::onRelease() {
diff --git a/src/gpu/gl/GrGLVertexEffect.h b/src/gpu/gl/GrGLVertexEffect.h
deleted file mode 100644
index 40b4b34..0000000
--- a/src/gpu/gl/GrGLVertexEffect.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLVertexEffect_DEFINED
-#define GrGLVertexEffect_DEFINED
-
-#include "GrGLEffect.h"
-
-/**
- * If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit
- * from this class. Since paths don't have vertices, this class is only meant to be used internally
- * by skia, for special cases.
- */
-class GrGLVertexEffect : public GrGLEffect {
-public:
-    GrGLVertexEffect(const GrBackendEffectFactory& factory)
-        : INHERITED(factory) { fIsVertexEffect = true; }
-
-    /**
-     * This is similar to emitCode() in the base class, except it takes a full shader builder.
-     * This allows the effect subclass to emit vertex code.
-     */
-    virtual void emitCode(GrGLFullShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
-                          const char* outputColor,
-                          const char* inputColor,
-                          const TransformedCoordsArray& coords,
-                          const TextureSamplerArray& samplers) = 0;
-
-    /**
-     * Provide a default override for base class's emitCode() function.
-     */
-    virtual void emitCode(GrGLShaderBuilder* builder,
-                          const GrDrawEffect& drawEffect,
-                          EffectKey key,
-                          const char* outputColor,
-                          const char* inputColor,
-                          const TransformedCoordsArray& coords,
-                          const TextureSamplerArray& samplers) SK_OVERRIDE {
-        SkFAIL("GrGLVertexEffect requires GrGLFullShaderBuilder* overload for emitCode().");
-    }
-
-private:
-    typedef GrGLEffect INHERITED;
-};
-
-#endif
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index f1b6da8..a01f7b7 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -7,10 +7,8 @@
 
 
 #include "GrGpuGL.h"
-#include "GrGLNameAllocator.h"
 #include "GrGLStencilBuffer.h"
-#include "GrGLPath.h"
-#include "GrGLShaderBuilder.h"
+#include "GrOptDrawState.h"
 #include "GrTemplates.h"
 #include "GrTypes.h"
 #include "SkStrokeRec.h"
@@ -34,6 +32,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+
 static const GrGLenum gXfermodeCoeff2Blend[] = {
     GR_GL_ZERO,
     GR_GL_ONE,
@@ -120,8 +119,7 @@
     SkASSERT(ctx.isInitialized());
     fCaps.reset(SkRef(ctx.caps()));
 
-    fHWBoundTextures.reset(this->glCaps().maxFragmentTextureUnits());
-    fHWPathTexGenSettings.reset(this->glCaps().maxFixedFunctionTextureCoords());
+    fHWBoundTextureUniqueIDs.reset(this->glCaps().maxFragmentTextureUnits());
 
     GrGLClearErr(fGLContext.interface());
     if (gPrintStartupSpew) {
@@ -137,9 +135,7 @@
         GrPrintf("------ RENDERER %s\n", renderer);
         GrPrintf("------ VERSION %s\n",  version);
         GrPrintf("------ EXTENSIONS\n");
-#if 0  // TODO: Reenable this after GrGLInterface's extensions can be accessed safely.
-       ctx.extensions().print();
-#endif
+        ctx.extensions().print();
         GrPrintf("\n");
         GrPrintf(this->glCaps().dump().c_str());
     }
@@ -150,6 +146,10 @@
 
     fLastSuccessfulStencilFmtIdx = 0;
     fHWProgramID = 0;
+
+    if (this->glCaps().pathRenderingSupport()) {
+        fPathRendering.reset(new GrGLPathRendering(this));
+    }
 }
 
 GrGpuGL::~GrGpuGL() {
@@ -164,9 +164,15 @@
 
     // This must be called by before the GrDrawTarget destructor
     this->releaseGeometry();
-    // This subclass must do this before the base class destructor runs
-    // since we will unref the GrGLInterface.
-    this->releaseResources();
+}
+
+void GrGpuGL::contextAbandoned() {
+    INHERITED::contextAbandoned();
+    fProgramCache->abandon();
+    fHWProgramID = 0;
+    if (this->glCaps().pathRenderingSupport()) {
+        this->glPathRendering()->abandonGpuResources();
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -261,20 +267,27 @@
             // currently part of our gl interface. There are probably others as
             // well.
         }
+
+        if (kGLES_GrGLStandard == this->glStandard() &&
+                fGLContext.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
+            // The arm extension requires specifically enabling MSAA fetching per sample.
+            // On some devices this may have a perf hit.  Also multiple render targets are disabled
+            GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM));
+        }
         fHWWriteToColor = kUnknown_TriState;
         // we only ever use lines in hairline mode
         GL_CALL(LineWidth(1));
     }
 
-    if (resetBits & kAA_GrGLBackendState) {
-        fHWAAState.invalidate();
+    if (resetBits & kMSAAEnable_GrGLBackendState) {
+        fMSAAEnabled = kUnknown_TriState;
     }
 
     fHWActiveTextureUnitIdx = -1; // invalid
 
     if (resetBits & kTextureBinding_GrGLBackendState) {
-        for (int s = 0; s < fHWBoundTextures.count(); ++s) {
-            fHWBoundTextures[s] = NULL;
+        for (int s = 0; s < fHWBoundTextureUniqueIDs.count(); ++s) {
+            fHWBoundTextureUniqueIDs[s] = SK_InvalidUniqueID;
         }
     }
 
@@ -298,23 +311,13 @@
     }
 
     if (resetBits & kRenderTarget_GrGLBackendState) {
-        fHWBoundRenderTarget = NULL;
+        fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
     }
 
     if (resetBits & kPathRendering_GrGLBackendState) {
         if (this->caps()->pathRenderingSupport()) {
-            fHWProjectionMatrixState.invalidate();
-            // we don't use the model view matrix.
-            GL_CALL(MatrixLoadIdentity(GR_GL_MODELVIEW));
-
-            for (int i = 0; i < this->glCaps().maxFixedFunctionTextureCoords(); ++i) {
-                GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
-                fHWPathTexGenSettings[i].fMode = GR_GL_NONE;
-                fHWPathTexGenSettings[i].fNumComponents = 0;
-            }
-            fHWActivePathTexGenSets = 0;
+            this->glPathRendering()->resetContext();
         }
-        fHWPathStencilSettings.invalidate();
     }
 
     // we assume these values
@@ -540,7 +543,7 @@
                             GrPixelConfig dataConfig,
                             const void* data,
                             size_t rowBytes) {
-    SkASSERT(NULL != data || isNewTexture);
+    SkASSERT(data || isNewTexture);
 
     // If we're uploading compressed data then we should be using uploadCompressedTexData
     SkASSERT(!GrPixelConfigIsCompressed(dataConfig));
@@ -553,16 +556,14 @@
     size_t trimRowBytes = width * bpp;
 
     // in case we need a temporary, trimmed copy of the src pixels
-    SkAutoSMalloc<128 * 128> tempStorage;
+    GrAutoMalloc<128 * 128> tempStorage;
 
-    // paletted textures cannot be partially updated
     // We currently lazily create MIPMAPs when the we see a draw with
     // GrTextureParams::kMipMap_FilterMode. Using texture storage requires that the
     // MIP levels are all created when the texture is created. So for now we don't use
     // texture storage.
     bool useTexStorage = false &&
                          isNewTexture &&
-                         kIndex_8_GrPixelConfig != desc.fConfig &&
                          this->glCaps().texStorageSupport();
 
     if (useTexStorage && kGL_GrGLStandard == this->glStandard()) {
@@ -574,19 +575,22 @@
     }
 
     GrGLenum internalFormat;
-    GrGLenum externalFormat;
-    GrGLenum externalType;
+    GrGLenum externalFormat = 0x0; // suprress warning
+    GrGLenum externalType = 0x0;// suprress warning
+
     // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized
     // format for glTexImage, unlike ES3 and desktop. However, we allow the driver to decide the
     // size of the internal format whenever possible and so only use a sized internal format when
     // using texture storage.
-    if (!this->configToGLFormats(dataConfig, useTexStorage, &internalFormat,
-                                 &externalFormat, &externalType)) {
-        return false;
+    bool useSizedFormat = useTexStorage;
+    // At least some versions of the desktop ES3 drivers for NVIDIA won't accept GL_RED in
+    // glTexImage2D for the internal format but will accept GL_R8.
+    if (!useSizedFormat && kNVIDIA_GrGLVendor == this->glContext().vendor() &&
+        kGLES_GrGLStandard == this->glStandard() && this->glVersion() >= GR_GL_VER(3, 0)) {
+        useSizedFormat = true;
     }
-
-    if (!isNewTexture && GR_GL_PALETTE8_RGBA8 == internalFormat) {
-        // paletted textures cannot be updated
+    if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat,
+                                 &externalFormat, &externalType)) {
         return false;
     }
 
@@ -599,7 +603,7 @@
     bool restoreGLRowLength = false;
     bool swFlipY = false;
     bool glFlipY = false;
-    if (NULL != data) {
+    if (data) {
         if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
             if (this->glCaps().unpackFlipYSupport()) {
                 glFlipY = true;
@@ -639,7 +643,8 @@
         if (glFlipY) {
             GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE));
         }
-        GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, static_cast<GrGLint>(bpp)));
+        GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT,
+              static_cast<GrGLint>(GrUnpackAlignment(dataConfig))));
     }
     bool succeeded = true;
     if (isNewTexture &&
@@ -654,27 +659,14 @@
                                        internalFormat,
                                        desc.fWidth, desc.fHeight));
         } else {
-            if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
-                GrGLsizei imageSize = desc.fWidth * desc.fHeight +
-                                      kGrColorTableSize;
-                GL_ALLOC_CALL(this->glInterface(),
-                              CompressedTexImage2D(GR_GL_TEXTURE_2D,
-                                                   0, // level
-                                                   internalFormat,
-                                                   desc.fWidth, desc.fHeight,
-                                                   0, // border
-                                                   imageSize,
-                                                   data));
-            } else {
-                GL_ALLOC_CALL(this->glInterface(),
-                              TexImage2D(GR_GL_TEXTURE_2D,
-                                         0, // level
-                                         internalFormat,
-                                         desc.fWidth, desc.fHeight,
-                                         0, // border
-                                         externalFormat, externalType,
-                                         data));
-            }
+            GL_ALLOC_CALL(this->glInterface(),
+                          TexImage2D(GR_GL_TEXTURE_2D,
+                                     0, // level
+                                     internalFormat,
+                                     desc.fWidth, desc.fHeight,
+                                     0, // border
+                                     externalFormat, externalType,
+                                     data));
         }
         GrGLenum error = check_alloc_error(desc, this->glInterface());
         if (error != GR_GL_NO_ERROR) {
@@ -682,7 +674,7 @@
         } else {
             // if we have data and we used TexStorage to create the texture, we
             // now upload with TexSubImage.
-            if (NULL != data && useTexStorage) {
+            if (data && useTexStorage) {
                 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
                                       0, // level
                                       left, top,
@@ -721,7 +713,7 @@
                                       const void* data,
                                       bool isNewTexture,
                                       int left, int top, int width, int height) {
-    SkASSERT(NULL != data || isNewTexture);
+    SkASSERT(data || isNewTexture);
 
     // No support for software flip y, yet...
     SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin);
@@ -754,10 +746,8 @@
         return false;
     }
 
-    bool succeeded = true;
-    CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
-
     if (isNewTexture) {
+        CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
         GL_ALLOC_CALL(this->glInterface(),
                       CompressedTexImage2D(GR_GL_TEXTURE_2D,
                                            0, // level
@@ -766,22 +756,25 @@
                                            0, // border
                                            dataSize,
                                            data));
+        GrGLenum error = check_alloc_error(desc, this->glInterface());
+        if (error != GR_GL_NO_ERROR) {
+            return false;
+        }
     } else {
-        GL_ALLOC_CALL(this->glInterface(),
-                      CompressedTexSubImage2D(GR_GL_TEXTURE_2D,
-                                              0, // level
-                                              left, top,
-                                              width, height,
-                                              internalFormat,
-                                              dataSize,
-                                              data));
+        // Paletted textures can't be updated.
+        if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
+            return false;
+        }
+        GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D,
+                                        0, // level
+                                        left, top,
+                                        width, height,
+                                        internalFormat,
+                                        dataSize,
+                                        data));
     }
 
-    GrGLenum error = check_alloc_error(desc, this->glInterface());
-    if (error != GR_GL_NO_ERROR) {
-        succeeded = false;
-    }
-    return succeeded;
+    return true;
 }
 
 static bool renderbuffer_storage_msaa(GrGLContext& ctx,
@@ -866,7 +859,7 @@
     }
 
     // below here we may bind the FBO
-    fHWBoundRenderTarget = NULL;
+    fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
     if (desc->fRTFBOID != desc->fTexFBOID) {
         SkASSERT(desc->fSampleCnt > 0);
         GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER,
@@ -877,6 +870,7 @@
                                        width, height)) {
             goto FAILED;
         }
+        fGPUStats.incRenderTargetBinds();
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fRTFBOID));
         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
                                       GR_GL_COLOR_ATTACHMENT0,
@@ -891,6 +885,7 @@
             fGLContext.caps()->markConfigAsValidColorAttachment(desc->fConfig);
         }
     }
+    fGPUStats.incRenderTargetBinds();
     GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
 
     if (this->glCaps().usesImplicitMSAAResolve() && desc->fSampleCnt > 0) {
@@ -1233,7 +1228,7 @@
     GrGLuint fbo = glrt->renderFBOID();
 
     if (NULL == sb) {
-        if (NULL != rt->getStencilBuffer()) {
+        if (rt->getStencilBuffer()) {
             GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
                                             GR_GL_STENCIL_ATTACHMENT,
                                             GR_GL_RENDERBUFFER, 0));
@@ -1251,7 +1246,8 @@
         GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb);
         GrGLuint rb = glsb->renderbufferID();
 
-        fHWBoundRenderTarget = NULL;
+        fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
+        fGPUStats.incRenderTargetBinds();
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo));
         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
                                         GR_GL_STENCIL_ATTACHMENT,
@@ -1357,32 +1353,18 @@
     }
 }
 
-GrPath* GrGpuGL::onCreatePath(const SkPath& inPath, const SkStrokeRec& stroke) {
-    SkASSERT(this->caps()->pathRenderingSupport());
-    return SkNEW_ARGS(GrGLPath, (this, inPath, stroke));
-}
-
-void GrGpuGL::flushScissor() {
+void GrGpuGL::flushScissor(const GrGLIRect& rtViewport, GrSurfaceOrigin rtOrigin) {
     if (fScissorState.fEnabled) {
-        // Only access the RT if scissoring is being enabled. We can call this before performing
-        // a glBitframebuffer for a surface->surface copy, which requires no RT to be bound to the
-        // GrDrawState.
-        const GrDrawState& drawState = this->getDrawState();
-        const GrGLRenderTarget* rt =
-            static_cast<const GrGLRenderTarget*>(drawState.getRenderTarget());
-
-        SkASSERT(NULL != rt);
-        const GrGLIRect& vp = rt->getViewport();
         GrGLIRect scissor;
-        scissor.setRelativeTo(vp,
+        scissor.setRelativeTo(rtViewport,
                               fScissorState.fRect.fLeft,
                               fScissorState.fRect.fTop,
                               fScissorState.fRect.width(),
                               fScissorState.fRect.height(),
-                              rt->origin());
+                              rtOrigin);
         // if the scissor fully contains the viewport then we fall through and
         // disable the scissor test.
-        if (!scissor.contains(vp)) {
+        if (!scissor.contains(rtViewport)) {
             if (fHWScissorSettings.fRect != scissor) {
                 scissor.pushToGLScissor(this->glInterface());
                 fHWScissorSettings.fRect = scissor;
@@ -1401,21 +1383,21 @@
     }
 }
 
-void GrGpuGL::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) {
-    const GrDrawState& drawState = this->getDrawState();
-    const GrRenderTarget* rt = drawState.getRenderTarget();
+void GrGpuGL::onClear(GrRenderTarget* target, const SkIRect* rect, GrColor color,
+                      bool canIgnoreRect) {
     // parent class should never let us get here with no RT
-    SkASSERT(NULL != rt);
+    SkASSERT(target);
+    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
 
     if (canIgnoreRect && this->glCaps().fullClearIsFree()) {
         rect = NULL;
     }
 
     SkIRect clippedRect;
-    if (NULL != rect) {
+    if (rect) {
         // flushScissor expects rect to be clipped to the target.
         clippedRect = *rect;
-        SkIRect rtRect = SkIRect::MakeWH(rt->width(), rt->height());
+        SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height());
         if (clippedRect.intersect(rtRect)) {
             rect = &clippedRect;
         } else {
@@ -1423,13 +1405,13 @@
         }
     }
 
-    this->flushRenderTarget(rect);
+    this->flushRenderTarget(glRT, rect);
     GrAutoTRestore<ScissorState> asr(&fScissorState);
-    fScissorState.fEnabled = (NULL != rect);
+    fScissorState.fEnabled = SkToBool(rect);
     if (fScissorState.fEnabled) {
         fScissorState.fRect = *rect;
     }
-    this->flushScissor();
+    this->flushScissor(glRT->getViewport(), glRT->origin());
 
     GrGLfloat r, g, b, a;
     static const GrGLfloat scale255 = 1.f / 255.f;
@@ -1457,12 +1439,13 @@
     }
 
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
-    if (renderTarget != fHWBoundRenderTarget) {
-        fHWBoundRenderTarget = NULL;
+    if (renderTarget->getUniqueID() != fHWBoundRenderTargetUniqueID) {
+        fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
+        fGPUStats.incRenderTargetBinds();
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRT->renderFBOID()));
     }
     switch (this->glCaps().invalidateFBType()) {
-        case GrGLCaps::kNone_FBFetchType:
+        case GrGLCaps::kNone_InvalidateFBType:
             SkFAIL("Should never get here.");
             break;
         case GrGLCaps::kInvalidate_InvalidateFBType:
@@ -1499,16 +1482,16 @@
 }
 
 
-void GrGpuGL::clearStencil() {
-    if (NULL == this->getDrawState().getRenderTarget()) {
+void GrGpuGL::clearStencil(GrRenderTarget* target) {
+    if (NULL == target) {
         return;
     }
-
-    this->flushRenderTarget(&SkIRect::EmptyIRect());
+    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
+    this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
 
     GrAutoTRestore<ScissorState> asr(&fScissorState);
     fScissorState.fEnabled = false;
-    this->flushScissor();
+    this->flushScissor(glRT->getViewport(), glRT->origin());
 
     GL_CALL(StencilMask(0xffffffff));
     GL_CALL(ClearStencil(0));
@@ -1516,15 +1499,13 @@
     fHWStencilSettings.invalidate();
 }
 
-void GrGpuGL::clearStencilClip(const SkIRect& rect, bool insideClip) {
-    const GrDrawState& drawState = this->getDrawState();
-    const GrRenderTarget* rt = drawState.getRenderTarget();
-    SkASSERT(NULL != rt);
+void GrGpuGL::clearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) {
+    SkASSERT(target);
 
     // this should only be called internally when we know we have a
     // stencil buffer.
-    SkASSERT(NULL != rt->getStencilBuffer());
-    GrGLint stencilBitCount =  rt->getStencilBuffer()->bits();
+    SkASSERT(target->getStencilBuffer());
+    GrGLint stencilBitCount =  target->getStencilBuffer()->bits();
 #if 0
     SkASSERT(stencilBitCount > 0);
     GrGLint clipStencilMask  = (1 << (stencilBitCount - 1));
@@ -1542,12 +1523,13 @@
     } else {
         value = 0;
     }
-    this->flushRenderTarget(&SkIRect::EmptyIRect());
+    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
+    this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
 
     GrAutoTRestore<ScissorState> asr(&fScissorState);
     fScissorState.fEnabled = true;
     fScissorState.fRect = rect;
-    this->flushScissor();
+    this->flushScissor(glRT->getViewport(), glRT->origin());
 
     GL_CALL(StencilMask((uint32_t) clipStencilMask));
     GL_CALL(ClearStencil(value));
@@ -1613,17 +1595,17 @@
 
     // resolve the render target if necessary
     GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target);
-    GrDrawState::AutoRenderTargetRestore artr;
     switch (tgt->getResolveType()) {
         case GrGLRenderTarget::kCantResolve_ResolveType:
             return false;
         case GrGLRenderTarget::kAutoResolves_ResolveType:
-            artr.set(this->drawState(), target);
-            this->flushRenderTarget(&SkIRect::EmptyIRect());
+            this->flushRenderTarget(static_cast<GrGLRenderTarget*>(target),
+                                    &SkIRect::EmptyIRect());
             break;
         case GrGLRenderTarget::kCanResolve_ResolveType:
             this->onResolveRenderTarget(tgt);
             // we don't track the state of the READ FBO ID.
+            fGPUStats.incRenderTargetBinds();
             GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
                                     tgt->textureFBOID()));
             break;
@@ -1646,7 +1628,7 @@
 
     // determine if GL can read using the passed rowBytes or if we need
     // a scratch buffer.
-    SkAutoSMalloc<32 * sizeof(GrColor)> scratch;
+    GrAutoMalloc<32 * sizeof(GrColor)> scratch;
     if (rowBytes != tightRowBytes) {
         if (this->glCaps().packRowLengthSupport()) {
             SkASSERT(!(rowBytes % sizeof(GrColor)));
@@ -1715,14 +1697,14 @@
     return true;
 }
 
-void GrGpuGL::flushRenderTarget(const SkIRect* bound) {
+void GrGpuGL::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound) {
 
-    GrGLRenderTarget* rt =
-        static_cast<GrGLRenderTarget*>(this->drawState()->getRenderTarget());
-    SkASSERT(NULL != rt);
+    SkASSERT(target);
 
-    if (fHWBoundRenderTarget != rt) {
-        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID()));
+    uint32_t rtID = target->getUniqueID();
+    if (fHWBoundRenderTargetUniqueID != rtID) {
+        fGPUStats.incRenderTargetBinds();
+        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID()));
 #ifdef SK_DEBUG
         // don't do this check in Chromium -- this is causing
         // lots of repeated command buffer flushes when the compositor is
@@ -1736,19 +1718,19 @@
             }
         }
 #endif
-        fHWBoundRenderTarget = rt;
-        const GrGLIRect& vp = rt->getViewport();
+        fHWBoundRenderTargetUniqueID = rtID;
+        const GrGLIRect& vp = target->getViewport();
         if (fHWViewport != vp) {
             vp.pushToGLViewport(this->glInterface());
             fHWViewport = vp;
         }
     }
     if (NULL == bound || !bound->isEmpty()) {
-        rt->flagAsNeedingResolve(bound);
+        target->flagAsNeedingResolve(bound);
     }
 
-    GrTexture *texture = rt->asTexture();
-    if (NULL != texture) {
+    GrTexture *texture = target->asTexture();
+    if (texture) {
         texture->impl()->dirtyMipMaps(true);
     }
 }
@@ -1818,192 +1800,19 @@
 #endif
 }
 
-static GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) {
-    switch (op) {
-        default:
-            SkFAIL("Unexpected path fill.");
-            /* fallthrough */;
-        case kIncClamp_StencilOp:
-            return GR_GL_COUNT_UP;
-        case kInvert_StencilOp:
-            return GR_GL_INVERT;
-    }
-}
-
-void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) {
-    SkASSERT(this->caps()->pathRenderingSupport());
-
-    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
-    SkASSERT(NULL != this->drawState()->getRenderTarget());
-    SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer());
-
-    flushPathStencilSettings(fill);
-
-    // Decide how to manipulate the stencil buffer based on the fill rule.
-    SkASSERT(!fHWPathStencilSettings.isTwoSided());
-
-    GrGLenum fillMode =
-        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
-    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
-    GL_CALL(StencilFillPath(id, fillMode, writeMask));
-}
-
-void GrGpuGL::onGpuDrawPath(const GrPath* path, SkPath::FillType fill) {
-    SkASSERT(this->caps()->pathRenderingSupport());
-
-    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
-    SkASSERT(NULL != this->drawState()->getRenderTarget());
-    SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer());
-    SkASSERT(!fCurrentProgram->hasVertexShader());
-
-    flushPathStencilSettings(fill);
-    const SkStrokeRec& stroke = path->getStroke();
-
-    SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill);
-    SkASSERT(!fHWPathStencilSettings.isTwoSided());
-    GrGLenum fillMode =
-        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
-    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
-
-    if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
-        GL_CALL(StencilFillPath(id, fillMode, writeMask));
-    }
-    if (stroke.needToApply()) {
-        GL_CALL(StencilStrokePath(id, 0xffff, writeMask));
-    }
-
-    if (nonInvertedFill == fill) {
-        if (stroke.needToApply()) {
-            GL_CALL(CoverStrokePath(id, GR_GL_BOUNDING_BOX));
-        } else {
-            GL_CALL(CoverFillPath(id, GR_GL_BOUNDING_BOX));
-        }
-    } else {
-        GrDrawState* drawState = this->drawState();
-        GrDrawState::AutoViewMatrixRestore avmr;
-        SkRect bounds = SkRect::MakeLTRB(0, 0,
-                                         SkIntToScalar(drawState->getRenderTarget()->width()),
-                                         SkIntToScalar(drawState->getRenderTarget()->height()));
-        SkMatrix vmi;
-        // mapRect through persp matrix may not be correct
-        if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
-            vmi.mapRect(&bounds);
-            // theoretically could set bloat = 0, instead leave it because of matrix inversion
-            // precision.
-            SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
-            bounds.outset(bloat, bloat);
-        } else {
-            avmr.setIdentity(drawState);
-        }
-
-        this->drawSimpleRect(bounds, NULL);
-    }
-}
-
-void GrGpuGL::onGpuDrawPaths(int pathCount, const GrPath** paths,
-                             const SkMatrix* transforms,
-                             SkPath::FillType fill,
-                             SkStrokeRec::Style stroke) {
-    SkASSERT(this->caps()->pathRenderingSupport());
-    SkASSERT(NULL != this->drawState()->getRenderTarget());
-    SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer());
-    SkASSERT(!fCurrentProgram->hasVertexShader());
-    SkASSERT(stroke != SkStrokeRec::kHairline_Style);
-
-    SkAutoMalloc pathData(pathCount * sizeof(GrGLuint));
-    SkAutoMalloc transformData(pathCount * sizeof(GrGLfloat) * 6);
-    GrGLfloat* transformValues =
-        reinterpret_cast<GrGLfloat*>(transformData.get());
-    GrGLuint* pathIDs = reinterpret_cast<GrGLuint*>(pathData.get());
-
-    for (int i = 0; i < pathCount; ++i) {
-        SkASSERT(transforms[i].asAffine(NULL));
-        const SkMatrix& m = transforms[i];
-        transformValues[i * 6] = m.getScaleX();
-        transformValues[i * 6 + 1] = m.getSkewY();
-        transformValues[i * 6 + 2] = m.getSkewX();
-        transformValues[i * 6 + 3] = m.getScaleY();
-        transformValues[i * 6 + 4] = m.getTranslateX();
-        transformValues[i * 6 + 5] = m.getTranslateY();
-        pathIDs[i] = static_cast<const GrGLPath*>(paths[i])->pathID();
-    }
-
-    flushPathStencilSettings(fill);
-
-    SkPath::FillType nonInvertedFill =
-        SkPath::ConvertToNonInverseFillType(fill);
-
-    SkASSERT(!fHWPathStencilSettings.isTwoSided());
-    GrGLenum fillMode =
-        gr_stencil_op_to_gl_path_rendering_fill_mode(
-            fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
-    GrGLint writeMask =
-        fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
-
-    bool doFill = stroke == SkStrokeRec::kFill_Style
-        || stroke == SkStrokeRec::kStrokeAndFill_Style;
-    bool doStroke = stroke == SkStrokeRec::kStroke_Style
-        || stroke == SkStrokeRec::kStrokeAndFill_Style;
-
-    if (doFill) {
-        GL_CALL(StencilFillPathInstanced(pathCount, GR_GL_UNSIGNED_INT,
-                                         pathIDs, 0,
-                                         fillMode, writeMask,
-                                         GR_GL_AFFINE_2D, transformValues));
-    }
-    if (doStroke) {
-        GL_CALL(StencilStrokePathInstanced(pathCount, GR_GL_UNSIGNED_INT,
-                                           pathIDs, 0,
-                                           0xffff, writeMask,
-                                           GR_GL_AFFINE_2D, transformValues));
-    }
-
-    if (nonInvertedFill == fill) {
-        if (doStroke) {
-            GL_CALL(CoverStrokePathInstanced(
-                        pathCount, GR_GL_UNSIGNED_INT, pathIDs, 0,
-                        GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
-                        GR_GL_AFFINE_2D, transformValues));
-        } else {
-            GL_CALL(CoverFillPathInstanced(
-                        pathCount, GR_GL_UNSIGNED_INT, pathIDs, 0,
-                        GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
-                        GR_GL_AFFINE_2D, transformValues));
-
-        }
-    } else {
-        GrDrawState* drawState = this->drawState();
-        GrDrawState::AutoViewMatrixRestore avmr;
-        SkRect bounds = SkRect::MakeLTRB(0, 0,
-                                         SkIntToScalar(drawState->getRenderTarget()->width()),
-                                         SkIntToScalar(drawState->getRenderTarget()->height()));
-        SkMatrix vmi;
-        // mapRect through persp matrix may not be correct
-        if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
-            vmi.mapRect(&bounds);
-            // theoretically could set bloat = 0, instead leave it because of matrix inversion
-            // precision.
-            SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
-            bounds.outset(bloat, bloat);
-        } else {
-            avmr.setIdentity(drawState);
-        }
-
-        this->drawSimpleRect(bounds, NULL);
-    }
-}
-
 void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
     if (rt->needsResolve()) {
         // Some extensions automatically resolves the texture when it is read.
         if (this->glCaps().usesMSAARenderBuffers()) {
             SkASSERT(rt->textureFBOID() != rt->renderFBOID());
+            fGPUStats.incRenderTargetBinds();
+            fGPUStats.incRenderTargetBinds();
             GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
             GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
             // make sure we go through flushRenderTarget() since we've modified
             // the bound DRAW FBO ID.
-            fHWBoundRenderTarget = NULL;
+            fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
             const GrGLIRect& vp = rt->getViewport();
             const SkIRect dirtyRect = rt->getResolveRect();
             GrGLIRect r;
@@ -2016,17 +1825,16 @@
                 asr.reset(&fScissorState);
                 fScissorState.fEnabled = true;
                 fScissorState.fRect = dirtyRect;
-                this->flushScissor();
+                this->flushScissor(rt->getViewport(), rt->origin());
                 GL_CALL(ResolveMultisampleFramebuffer());
             } else {
-                if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType()) {
-                    // this respects the scissor during the blit, so disable it.
-                    asr.reset(&fScissorState);
-                    fScissorState.fEnabled = false;
-                    this->flushScissor();
-                }
                 int right = r.fLeft + r.fWidth;
                 int top = r.fBottom + r.fHeight;
+
+                // BlitFrameBuffer respects the scissor, so disable it.
+                asr.reset(&fScissorState);
+                fScissorState.fEnabled = false;
+                this->flushScissor(rt->getViewport(), rt->origin());
                 GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top,
                                         r.fLeft, r.fBottom, right, top,
                                         GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
@@ -2038,30 +1846,6 @@
 
 namespace {
 
-GrGLenum gr_to_gl_stencil_func(GrStencilFunc basicFunc) {
-    static const GrGLenum gTable[] = {
-        GR_GL_ALWAYS,           // kAlways_StencilFunc
-        GR_GL_NEVER,            // kNever_StencilFunc
-        GR_GL_GREATER,          // kGreater_StencilFunc
-        GR_GL_GEQUAL,           // kGEqual_StencilFunc
-        GR_GL_LESS,             // kLess_StencilFunc
-        GR_GL_LEQUAL,           // kLEqual_StencilFunc,
-        GR_GL_EQUAL,            // kEqual_StencilFunc,
-        GR_GL_NOTEQUAL,         // kNotEqual_StencilFunc,
-    };
-    GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kBasicStencilFuncCount);
-    GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
-    GR_STATIC_ASSERT(1 == kNever_StencilFunc);
-    GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
-    GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
-    GR_STATIC_ASSERT(4 == kLess_StencilFunc);
-    GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
-    GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
-    GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
-    SkASSERT((unsigned) basicFunc < kBasicStencilFuncCount);
-
-    return gTable[basicFunc];
-}
 
 GrGLenum gr_to_gl_stencil_op(GrStencilOp op) {
     static const GrGLenum gTable[] = {
@@ -2091,7 +1875,7 @@
                     const GrStencilSettings& settings,
                     GrGLenum glFace,
                     GrStencilSettings::Face grFace) {
-    GrGLenum glFunc = gr_to_gl_stencil_func(settings.func(grFace));
+    GrGLenum glFunc = GrToGLStencilFunc(settings.func(grFace));
     GrGLenum glFailOp = gr_to_gl_stencil_op(settings.failOp(grFace));
     GrGLenum glPassOp = gr_to_gl_stencil_op(settings.passOp(grFace));
 
@@ -2147,7 +1931,7 @@
     }
 }
 
-void GrGpuGL::flushAAState(DrawType type) {
+void GrGpuGL::flushAAState(const GrOptDrawState& optState, DrawType type) {
 // At least some ATI linux drivers will render GL_LINES incorrectly when MSAA state is enabled but
 // the target is not multisampled. Single pixel wide lines are rendered thicker than 1 pixel wide.
 #if 0
@@ -2157,118 +1941,60 @@
     #define RT_HAS_MSAA (rt->isMultisampled() || kDrawLines_DrawType == type)
 #endif
 
-    const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
+    const GrRenderTarget* rt = optState.getRenderTarget();
     if (kGL_GrGLStandard == this->glStandard()) {
-        // ES doesn't support toggling GL_MULTISAMPLE and doesn't have
-        // smooth lines.
-        // we prefer smooth lines over multisampled lines
-        bool smoothLines = false;
-
-        if (kDrawLines_DrawType == type) {
-            smoothLines = this->willUseHWAALines();
-            if (smoothLines) {
-                if (kYes_TriState != fHWAAState.fSmoothLineEnabled) {
-                    GL_CALL(Enable(GR_GL_LINE_SMOOTH));
-                    fHWAAState.fSmoothLineEnabled = kYes_TriState;
-                    // must disable msaa to use line smoothing
-                    if (RT_HAS_MSAA &&
-                        kNo_TriState != fHWAAState.fMSAAEnabled) {
-                        GL_CALL(Disable(GR_GL_MULTISAMPLE));
-                        fHWAAState.fMSAAEnabled = kNo_TriState;
-                    }
-                }
-            } else {
-                if (kNo_TriState != fHWAAState.fSmoothLineEnabled) {
-                    GL_CALL(Disable(GR_GL_LINE_SMOOTH));
-                    fHWAAState.fSmoothLineEnabled = kNo_TriState;
-                }
-            }
-        }
-        if (!smoothLines && RT_HAS_MSAA) {
+        if (RT_HAS_MSAA) {
             // FIXME: GL_NV_pr doesn't seem to like MSAA disabled. The paths
             // convex hulls of each segment appear to get filled.
             bool enableMSAA = kStencilPath_DrawType == type ||
-                              this->getDrawState().isHWAntialiasState();
+                              optState.isHWAntialiasState();
             if (enableMSAA) {
-                if (kYes_TriState != fHWAAState.fMSAAEnabled) {
+                if (kYes_TriState != fMSAAEnabled) {
                     GL_CALL(Enable(GR_GL_MULTISAMPLE));
-                    fHWAAState.fMSAAEnabled = kYes_TriState;
+                    fMSAAEnabled = kYes_TriState;
                 }
             } else {
-                if (kNo_TriState != fHWAAState.fMSAAEnabled) {
+                if (kNo_TriState != fMSAAEnabled) {
                     GL_CALL(Disable(GR_GL_MULTISAMPLE));
-                    fHWAAState.fMSAAEnabled = kNo_TriState;
+                    fMSAAEnabled = kNo_TriState;
                 }
             }
         }
     }
 }
 
-void GrGpuGL::flushPathStencilSettings(SkPath::FillType fill) {
-    GrStencilSettings pathStencilSettings;
-    this->getPathStencilSettingsForFillType(fill, &pathStencilSettings);
-    if (fHWPathStencilSettings != pathStencilSettings) {
-        // Just the func, ref, and mask is set here. The op and write mask are params to the call
-        // that draws the path to the SB (glStencilFillPath)
-        GrGLenum func =
-            gr_to_gl_stencil_func(pathStencilSettings.func(GrStencilSettings::kFront_Face));
-        GL_CALL(PathStencilFunc(func,
-                                pathStencilSettings.funcRef(GrStencilSettings::kFront_Face),
-                                pathStencilSettings.funcMask(GrStencilSettings::kFront_Face)));
-
-        fHWPathStencilSettings = pathStencilSettings;
-    }
-}
-
-void GrGpuGL::flushBlend(bool isLines,
-                         GrBlendCoeff srcCoeff,
-                         GrBlendCoeff dstCoeff) {
-    if (isLines && this->willUseHWAALines()) {
+void GrGpuGL::flushBlend(const GrOptDrawState& optState, bool isLines,
+                         GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+    // Any optimization to disable blending should have already been applied and
+    // tweaked the coeffs to (1, 0).
+    bool blendOff = kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff;
+    if (blendOff) {
+        if (kNo_TriState != fHWBlendState.fEnabled) {
+            GL_CALL(Disable(GR_GL_BLEND));
+            fHWBlendState.fEnabled = kNo_TriState;
+        }
+    } else {
         if (kYes_TriState != fHWBlendState.fEnabled) {
             GL_CALL(Enable(GR_GL_BLEND));
             fHWBlendState.fEnabled = kYes_TriState;
         }
-        if (kSA_GrBlendCoeff != fHWBlendState.fSrcCoeff ||
-            kISA_GrBlendCoeff != fHWBlendState.fDstCoeff) {
-            GL_CALL(BlendFunc(gXfermodeCoeff2Blend[kSA_GrBlendCoeff],
-                              gXfermodeCoeff2Blend[kISA_GrBlendCoeff]));
-            fHWBlendState.fSrcCoeff = kSA_GrBlendCoeff;
-            fHWBlendState.fDstCoeff = kISA_GrBlendCoeff;
+        if (fHWBlendState.fSrcCoeff != srcCoeff ||
+            fHWBlendState.fDstCoeff != dstCoeff) {
+            GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
+                              gXfermodeCoeff2Blend[dstCoeff]));
+            fHWBlendState.fSrcCoeff = srcCoeff;
+            fHWBlendState.fDstCoeff = dstCoeff;
         }
-    } else {
-        // any optimization to disable blending should
-        // have already been applied and tweaked the coeffs
-        // to (1, 0).
-        bool blendOff = kOne_GrBlendCoeff == srcCoeff &&
-                        kZero_GrBlendCoeff == dstCoeff;
-        if (blendOff) {
-            if (kNo_TriState != fHWBlendState.fEnabled) {
-                GL_CALL(Disable(GR_GL_BLEND));
-                fHWBlendState.fEnabled = kNo_TriState;
-            }
-        } else {
-            if (kYes_TriState != fHWBlendState.fEnabled) {
-                GL_CALL(Enable(GR_GL_BLEND));
-                fHWBlendState.fEnabled = kYes_TriState;
-            }
-            if (fHWBlendState.fSrcCoeff != srcCoeff ||
-                fHWBlendState.fDstCoeff != dstCoeff) {
-                GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
-                                  gXfermodeCoeff2Blend[dstCoeff]));
-                fHWBlendState.fSrcCoeff = srcCoeff;
-                fHWBlendState.fDstCoeff = dstCoeff;
-            }
-            GrColor blendConst = this->getDrawState().getBlendConstant();
-            if ((BlendCoeffReferencesConstant(srcCoeff) ||
-                 BlendCoeffReferencesConstant(dstCoeff)) &&
-                (!fHWBlendState.fConstColorValid ||
-                 fHWBlendState.fConstColor != blendConst)) {
-                GrGLfloat c[4];
-                GrColorToRGBAFloat(blendConst, c);
-                GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
-                fHWBlendState.fConstColor = blendConst;
-                fHWBlendState.fConstColorValid = true;
-            }
+        GrColor blendConst = optState.getBlendConstant();
+        if ((BlendCoeffReferencesConstant(srcCoeff) ||
+             BlendCoeffReferencesConstant(dstCoeff)) &&
+            (!fHWBlendState.fConstColorValid ||
+             fHWBlendState.fConstColor != blendConst)) {
+            GrGLfloat c[4];
+            GrColorToRGBAFloat(blendConst, c);
+            GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
+            fHWBlendState.fConstColor = blendConst;
+            fHWBlendState.fConstColorValid = true;
         }
     }
 }
@@ -2287,20 +2013,21 @@
 }
 
 void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture) {
-    SkASSERT(NULL != texture);
+    SkASSERT(texture);
 
     // If we created a rt/tex and rendered to it without using a texture and now we're texturing
     // from the rt it will still be the last bound texture, but it needs resolving. So keep this
     // out of the "last != next" check.
     GrGLRenderTarget* texRT =  static_cast<GrGLRenderTarget*>(texture->asRenderTarget());
-    if (NULL != texRT) {
+    if (texRT) {
         this->onResolveRenderTarget(texRT);
     }
 
-    if (fHWBoundTextures[unitIdx] != texture) {
+    uint32_t textureID = texture->getUniqueID();
+    if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) {
         this->setTextureUnit(unitIdx);
         GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID()));
-        fHWBoundTextures[unitIdx] = texture;
+        fHWBoundTextureUniqueIDs[unitIdx] = textureID;
     }
 
     ResetTimestamp timestamp;
@@ -2381,109 +2108,8 @@
     texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
 }
 
-void GrGpuGL::setProjectionMatrix(const SkMatrix& matrix,
-                                  const SkISize& renderTargetSize,
-                                  GrSurfaceOrigin renderTargetOrigin) {
-
-    SkASSERT(this->glCaps().pathRenderingSupport());
-
-    if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin &&
-        renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize &&
-        matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) {
-        return;
-    }
-
-    fHWProjectionMatrixState.fViewMatrix = matrix;
-    fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize;
-    fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin;
-
-    GrGLfloat glMatrix[4 * 4];
-    fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix);
-    GL_CALL(MatrixLoadf(GR_GL_PROJECTION, glMatrix));
-}
-
-void GrGpuGL::enablePathTexGen(int unitIdx,
-                               PathTexGenComponents components,
-                               const GrGLfloat* coefficients) {
-    SkASSERT(this->glCaps().pathRenderingSupport());
-    SkASSERT(components >= kS_PathTexGenComponents &&
-             components <= kSTR_PathTexGenComponents);
-    SkASSERT(this->glCaps().maxFixedFunctionTextureCoords() >= unitIdx);
-
-    if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode &&
-        components == fHWPathTexGenSettings[unitIdx].fNumComponents &&
-        !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients,
-                3 * components * sizeof(GrGLfloat))) {
-        return;
-    }
-
-    this->setTextureUnit(unitIdx);
-
-    fHWPathTexGenSettings[unitIdx].fNumComponents = components;
-    GL_CALL(PathTexGen(GR_GL_TEXTURE0 + unitIdx,
-                       GR_GL_OBJECT_LINEAR,
-                       components,
-                       coefficients));
-
-    memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients,
-           3 * components * sizeof(GrGLfloat));
-}
-
-void GrGpuGL::enablePathTexGen(int unitIdx, PathTexGenComponents components,
-                               const SkMatrix& matrix) {
-    GrGLfloat coefficients[3 * 3];
-    SkASSERT(this->glCaps().pathRenderingSupport());
-    SkASSERT(components >= kS_PathTexGenComponents &&
-             components <= kSTR_PathTexGenComponents);
-
-    coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
-    coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
-    coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
-
-    if (components >= kST_PathTexGenComponents) {
-        coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
-        coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
-        coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
-    }
-
-    if (components >= kSTR_PathTexGenComponents) {
-        coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
-        coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
-        coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
-    }
-
-    enablePathTexGen(unitIdx, components, coefficients);
-}
-
-void GrGpuGL::flushPathTexGenSettings(int numUsedTexCoordSets) {
-    SkASSERT(this->glCaps().pathRenderingSupport());
-    SkASSERT(this->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSets);
-
-    // Only write the inactive path tex gens, since active path tex gens were
-    // written when they were enabled.
-
-    SkDEBUGCODE(
-        for (int i = 0; i < numUsedTexCoordSets; i++) {
-            SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
-        }
-    );
-
-    for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) {
-        SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
-
-        this->setTextureUnit(i);
-        GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
-        fHWPathTexGenSettings[i].fNumComponents = 0;
-    }
-
-    fHWActivePathTexGenSets = numUsedTexCoordSets;
-}
-
-void GrGpuGL::flushMiscFixedFunctionState() {
-
-    const GrDrawState& drawState = this->getDrawState();
-
-    if (drawState.isDitherState()) {
+void GrGpuGL::flushMiscFixedFunctionState(const GrOptDrawState& optState) {
+    if (optState.isDitherState()) {
         if (kYes_TriState != fHWDitherEnabled) {
             GL_CALL(Enable(GR_GL_DITHER));
             fHWDitherEnabled = kYes_TriState;
@@ -2495,7 +2121,7 @@
         }
     }
 
-    if (drawState.isColorWriteDisabled()) {
+    if (optState.isColorWriteDisabled()) {
         if (kNo_TriState != fHWWriteToColor) {
             GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE,
                               GR_GL_FALSE, GR_GL_FALSE));
@@ -2508,8 +2134,8 @@
         }
     }
 
-    if (fHWDrawFace != drawState.getDrawFace()) {
-        switch (this->getDrawState().getDrawFace()) {
+    if (fHWDrawFace != optState.getDrawFace()) {
+        switch (optState.getDrawFace()) {
             case GrDrawState::kCCW_DrawFace:
                 GL_CALL(Enable(GR_GL_CULL_FACE));
                 GL_CALL(CullFace(GR_GL_BACK));
@@ -2524,59 +2150,10 @@
             default:
                 SkFAIL("Unknown draw face.");
         }
-        fHWDrawFace = drawState.getDrawFace();
+        fHWDrawFace = optState.getDrawFace();
     }
 }
 
-void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
-    SkASSERT(NULL != renderTarget);
-    if (fHWBoundRenderTarget == renderTarget) {
-        fHWBoundRenderTarget = NULL;
-    }
-}
-
-void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
-    for (int s = 0; s < fHWBoundTextures.count(); ++s) {
-        if (fHWBoundTextures[s] == texture) {
-            // deleting bound texture does implied bind to 0
-            fHWBoundTextures[s] = NULL;
-       }
-    }
-}
-
-
-GrGLuint GrGpuGL::createGLPathObject() {
-    if (NULL == fPathNameAllocator.get()) {
-        static const int range = 65536;
-        GrGLuint firstName;
-        GL_CALL_RET(firstName, GenPaths(range));
-        fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, firstName + range)));
-    }
-
-    GrGLuint name = fPathNameAllocator->allocateName();
-    if (0 == name) {
-        // Our reserved path names are all in use. Fall back on GenPaths.
-        GL_CALL_RET(name, GenPaths(1));
-    }
-
-    return name;
-}
-
-void GrGpuGL::deleteGLPathObject(GrGLuint name) {
-    if (NULL == fPathNameAllocator.get() ||
-        name < fPathNameAllocator->firstName() ||
-        name >= fPathNameAllocator->endName()) {
-        // If we aren't inside fPathNameAllocator's range then this name was
-        // generated by the GenPaths fallback (or else the name is unallocated).
-        GL_CALL(DeletePaths(name, 1));
-        return;
-    }
-
-    // Make the path empty to save memory, but don't free the name in the driver.
-    GL_CALL(PathCommands(name, 0, NULL, 0, GR_GL_FLOAT, NULL));
-    fPathNameAllocator->free(name);
-}
-
 bool GrGpuGL::configToGLFormats(GrPixelConfig config,
                                 bool getSizedInternalFormat,
                                 GrGLenum* internalFormat,
@@ -2650,12 +2227,8 @@
             *externalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
             break;
         case kIndex_8_GrPixelConfig:
-            // glCompressedTexImage doesn't take external params
-            *externalFormat = GR_GL_PALETTE8_RGBA8;
             // no sized/unsized internal format distinction here
             *internalFormat = GR_GL_PALETTE8_RGBA8;
-            // unused with CompressedTexImage
-            *externalType = GR_GL_UNSIGNED_BYTE;
             break;
         case kAlpha_8_GrPixelConfig:
             if (this->glCaps().textureRedSupport()) {
@@ -2694,6 +2267,20 @@
                     break;
             }
             break;
+        case kR11_EAC_GrPixelConfig:
+            *internalFormat = GR_GL_COMPRESSED_R11;
+            break;
+
+        case kASTC_12x12_GrPixelConfig:
+            *internalFormat = GR_GL_COMPRESSED_RGBA_ASTC_12x12;
+            break;
+
+        case kRGBA_float_GrPixelConfig:
+            *internalFormat = GR_GL_RGBA32F;
+            *externalFormat = GR_GL_RGBA;
+            *externalType = GR_GL_FLOAT;
+            break;
+
         default:
             return false;
     }
@@ -2701,7 +2288,7 @@
 }
 
 void GrGpuGL::setTextureUnit(int unit) {
-    SkASSERT(unit >= 0 && unit < fHWBoundTextures.count());
+    SkASSERT(unit >= 0 && unit < fHWBoundTextureUniqueIDs.count());
     if (unit != fHWActiveTextureUnitIdx) {
         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit));
         fHWActiveTextureUnitIdx = unit;
@@ -2710,14 +2297,14 @@
 
 void GrGpuGL::setScratchTextureUnit() {
     // Bind the last texture unit since it is the least likely to be used by GrGLProgram.
-    int lastUnitIdx = fHWBoundTextures.count() - 1;
+    int lastUnitIdx = fHWBoundTextureUniqueIDs.count() - 1;
     if (lastUnitIdx != fHWActiveTextureUnitIdx) {
         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx));
         fHWActiveTextureUnitIdx = lastUnitIdx;
     }
     // clear out the this field so that if a program does use this unit it will rebind the correct
     // texture.
-    fHWBoundTextures[lastUnitIdx] = NULL;
+    fHWBoundTextureUniqueIDs[lastUnitIdx] = SK_InvalidUniqueID;
 }
 
 namespace {
@@ -2735,7 +2322,7 @@
             (src->desc().fSampleCnt > 0 || src->config() != dst->config())) {
            return false;
         }
-        if (NULL != wouldNeedTempFBO) {
+        if (wouldNeedTempFBO) {
             *wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->asRenderTarget();
         }
         return true;
@@ -2758,21 +2345,20 @@
     const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget());
     // If dst is multisampled (and uses an extension where there is a separate MSAA renderbuffer)
     // then we don't want to copy to the texture but to the MSAA buffer.
-    if (NULL != dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) {
+    if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) {
         return false;
     }
     const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget());
     // If the src is multisampled (and uses an extension where there is a separate MSAA
     // renderbuffer) then it is an invalid operation to call CopyTexSubImage
-    if (NULL != srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) {
+    if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) {
         return false;
     }
     if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) &&
-        NULL != dst->asTexture() &&
+        dst->asTexture() &&
         dst->origin() == src->origin() &&
-        kIndex_8_GrPixelConfig != src->config() &&
         !GrPixelConfigIsCompressed(src->config())) {
-        if (NULL != wouldNeedTempFBO) {
+        if (wouldNeedTempFBO) {
             *wouldNeedTempFBO = NULL == src->asRenderTarget();
         }
         return true;
@@ -2781,38 +2367,37 @@
     }
 }
 
+}
+
 // If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is
 // relative to is output.
-inline GrGLuint bind_surface_as_fbo(const GrGLInterface* gl,
-                                    GrSurface* surface,
-                                    GrGLenum fboTarget,
-                                    GrGLIRect* viewport) {
+GrGLuint GrGpuGL::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport) {
     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
     GrGLuint tempFBOID;
     if (NULL == rt) {
-        SkASSERT(NULL != surface->asTexture());
+        SkASSERT(surface->asTexture());
         GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textureID();
-        GR_GL_CALL(gl, GenFramebuffers(1, &tempFBOID));
-        GR_GL_CALL(gl, BindFramebuffer(fboTarget, tempFBOID));
-        GR_GL_CALL(gl, FramebufferTexture2D(fboTarget,
-                                            GR_GL_COLOR_ATTACHMENT0,
-                                            GR_GL_TEXTURE_2D,
-                                            texID,
-                                            0));
+        GR_GL_CALL(this->glInterface(), GenFramebuffers(1, &tempFBOID));
+        fGPUStats.incRenderTargetBinds();
+        GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, tempFBOID));
+        GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
+                                                             GR_GL_COLOR_ATTACHMENT0,
+                                                             GR_GL_TEXTURE_2D,
+                                                             texID,
+                                                             0));
         viewport->fLeft = 0;
         viewport->fBottom = 0;
         viewport->fWidth = surface->width();
         viewport->fHeight = surface->height();
     } else {
         tempFBOID = 0;
-        GR_GL_CALL(gl, BindFramebuffer(fboTarget, rt->renderFBOID()));
+        fGPUStats.incRenderTargetBinds();
+        GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID()));
         *viewport = rt->getViewport();
     }
     return tempFBOID;
 }
 
-}
-
 void GrGpuGL::initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) {
     // Check for format issues with glCopyTexSubImage2D
     if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInternalFormat() &&
@@ -2829,7 +2414,7 @@
     }
 
     const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget());
-    if (NULL != srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) {
+    if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) {
         // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer.
         INHERITED::initCopySurfaceDstDesc(src, desc);
     } else {
@@ -2850,11 +2435,11 @@
         (!wouldNeedTempFBO || !inheritedCouldCopy)) {
         GrGLuint srcFBO;
         GrGLIRect srcVP;
-        srcFBO = bind_surface_as_fbo(this->glInterface(), src, GR_GL_FRAMEBUFFER, &srcVP);
+        srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP);
         GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture());
-        SkASSERT(NULL != dstTex);
+        SkASSERT(dstTex);
         // We modified the bound FBO
-        fHWBoundRenderTarget = NULL;
+        fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
         GrGLIRect srcGLRect;
         srcGLRect.setRelativeTo(srcVP,
                                 srcRect.fLeft,
@@ -2893,10 +2478,10 @@
             GrGLuint srcFBO;
             GrGLIRect dstVP;
             GrGLIRect srcVP;
-            dstFBO = bind_surface_as_fbo(this->glInterface(), dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP);
-            srcFBO = bind_surface_as_fbo(this->glInterface(), src, GR_GL_READ_FRAMEBUFFER, &srcVP);
+            dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP);
+            srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP);
             // We modified the bound FBO
-            fHWBoundRenderTarget = NULL;
+            fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
             GrGLIRect srcGLRect;
             GrGLIRect dstGLRect;
             srcGLRect.setRelativeTo(srcVP,
@@ -2913,12 +2498,11 @@
                                     dst->origin());
 
             GrAutoTRestore<ScissorState> asr;
-            if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType()) {
-                // The EXT version applies the scissor during the blit, so disable it.
-                asr.reset(&fScissorState);
-                fScissorState.fEnabled = false;
-                this->flushScissor();
-            }
+            // BlitFrameBuffer respects the scissor, so disable it.
+            asr.reset(&fScissorState);
+            fScissorState.fEnabled = false;
+            this->flushScissor(dstGLRect, dst->origin());
+
             GrGLint srcY0;
             GrGLint srcY1;
             // Does the blit need to y-mirror or not?
@@ -2979,7 +2563,7 @@
 void GrGpuGL::didAddGpuTraceMarker() {
     if (this->caps()->gpuTracingSupport()) {
         const GrTraceMarkerSet& markerArray = this->getActiveTraceMarkers();
-        SkString markerString = markerArray.toString();
+        SkString markerString = markerArray.toStringLast();
         GL_CALL(PushGroupMarker(0, markerString.c_str()));
     }
 }
@@ -2995,7 +2579,7 @@
                                                 GrGpuGL* gpu,
                                                 const GrGLVertexBuffer* vbuffer,
                                                 const GrGLIndexBuffer* ibuffer) {
-    SkASSERT(NULL != vbuffer);
+    SkASSERT(vbuffer);
     GrGLAttribArrayState* attribState;
 
     // We use a vertex array if we're on a core profile and the verts are in a VBO.
@@ -3009,7 +2593,7 @@
         }
         attribState = fVBOVertexArray->bindWithIndexBuffer(ibuffer);
     } else {
-        if (NULL != ibuffer) {
+        if (ibuffer) {
             this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID());
         } else {
             this->setVertexArrayID(gpu, 0);
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index a2c636d..65816b5 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -8,31 +8,30 @@
 #ifndef GrGpuGL_DEFINED
 #define GrGpuGL_DEFINED
 
-#include "GrBinHashKey.h"
 #include "GrDrawState.h"
 #include "GrGLContext.h"
 #include "GrGLIRect.h"
 #include "GrGLIndexBuffer.h"
+#include "GrGLPathRendering.h"
 #include "GrGLProgram.h"
 #include "GrGLStencilBuffer.h"
 #include "GrGLTexture.h"
 #include "GrGLVertexArray.h"
 #include "GrGLVertexBuffer.h"
 #include "GrGpu.h"
-#include "GrTHashTable.h"
 #include "SkTypes.h"
 
 #ifdef SK_DEVELOPER
 #define PROGRAM_CACHE_STATS
 #endif
 
-class GrGLNameAllocator;
-
 class GrGpuGL : public GrGpu {
 public:
     GrGpuGL(const GrGLContext& ctx, GrContext* context);
     virtual ~GrGpuGL();
 
+    virtual void contextAbandoned() SK_OVERRIDE;
+
     const GrGLContext& glContext() const { return fGLContext; }
 
     const GrGLInterface* glInterface() const { return fGLContext.interface(); }
@@ -42,25 +41,16 @@
     GrGLSLGeneration glslGeneration() const { return fGLContext.glslGeneration(); }
     const GrGLCaps& glCaps() const { return *fGLContext.caps(); }
 
+    GrGLPathRendering* glPathRendering() {
+        SkASSERT(glCaps().pathRenderingSupport());
+        return static_cast<GrGLPathRendering*>(pathRendering());
+    }
+
     virtual void discard(GrRenderTarget*) SK_OVERRIDE;
 
     // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL
     // state.
     void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
-    void setProjectionMatrix(const SkMatrix& matrix,
-                             const SkISize& renderTargetSize,
-                             GrSurfaceOrigin renderTargetOrigin);
-    enum PathTexGenComponents {
-        kS_PathTexGenComponents = 1,
-        kST_PathTexGenComponents = 2,
-        kSTR_PathTexGenComponents = 3
-    };
-    void enablePathTexGen(int unitIdx, PathTexGenComponents, const GrGLfloat* coefficients);
-    void enablePathTexGen(int unitIdx, PathTexGenComponents, const SkMatrix& matrix);
-    void flushPathTexGenSettings(int numUsedTexCoordSets);
-    bool shouldUseFixedFunctionTexturing() const {
-        return this->glCaps().pathRenderingSupport();
-    }
 
     bool programUnitTest(int maxStages);
 
@@ -80,8 +70,6 @@
 
     virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
 
-    virtual void abandonResources() SK_OVERRIDE;
-
     // These functions should be used to bind GL objects. They track the GL state and skip redundant
     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
     void bindVertexArray(GrGLuint id) {
@@ -105,13 +93,6 @@
     void notifyIndexBufferDelete(GrGLuint id) {
         fHWGeometryState.notifyIndexBufferDelete(id);
     }
-    void notifyTextureDelete(GrGLTexture* texture);
-    void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
-
-    // These functions should be used to generate and delete GL path names. They have their own
-    // allocator that runs on the client side, so they are much faster than going through GenPaths.
-    GrGLuint createGLPathObject();
-    void deleteGLPathObject(GrGLuint);
 
 protected:
     virtual bool onCopySurface(GrSurface* dst,
@@ -135,7 +116,6 @@
                                                  const void* srcData) SK_OVERRIDE;
     virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
     virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
-    virtual GrPath* onCreatePath(const SkPath&, const SkStrokeRec&) SK_OVERRIDE;
     virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) SK_OVERRIDE;
     virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) SK_OVERRIDE;
     virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
@@ -145,7 +125,8 @@
         GrStencilBuffer* sb,
         GrRenderTarget* rt) SK_OVERRIDE;
 
-    virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) SK_OVERRIDE;
+    virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
+                         bool canIgnoreRect) SK_OVERRIDE;
 
     virtual bool onReadPixels(GrRenderTarget* target,
                               int left, int top,
@@ -163,18 +144,13 @@
 
     virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
 
-    virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
-    virtual void onGpuDrawPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
-    virtual void onGpuDrawPaths(int, const GrPath**, const SkMatrix*,
-                                SkPath::FillType,
-                                SkStrokeRec::Style) SK_OVERRIDE;
 
-    virtual void clearStencil() SK_OVERRIDE;
-    virtual void clearStencilClip(const SkIRect& rect,
+    virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
+    virtual void clearStencilClip(GrRenderTarget*, const SkIRect& rect,
                                   bool insideClip) SK_OVERRIDE;
     virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
 
-    // GrDrawTarget ovverides
+    // GrDrawTarget overrides
     virtual void didAddGpuTraceMarker() SK_OVERRIDE;
     virtual void didRemoveGpuTraceMarker() SK_OVERRIDE;
 
@@ -190,7 +166,8 @@
     // The params should be the final coefficients to apply
     // (after any blending optimizations or dual source blending considerations
     // have been accounted for).
-    void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
+    void flushBlend(const GrOptDrawState& optState, bool isLines,
+                    GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
 
     bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
 
@@ -203,8 +180,9 @@
 
         void abandon();
         GrGLProgram* getProgram(const GrGLProgramDesc& desc,
-                                const GrEffectStage* colorStages[],
-                                const GrEffectStage* coverageStages[]);
+                                const GrGeometryStage* geometryProcessor,
+                                const GrFragmentStage* colorStages[],
+                                const GrFragmentStage* coverageStages[]);
 
     private:
         enum {
@@ -239,11 +217,11 @@
     };
 
     // flushes dithering, color-mask, and face culling stat
-    void flushMiscFixedFunctionState();
+    void flushMiscFixedFunctionState(const GrOptDrawState&);
 
     // flushes the scissor. see the note on flushBoundTextureAndParams about
     // flushing the scissor after that function is called.
-    void flushScissor();
+    void flushScissor(const GrGLIRect& rtViewport, GrSurfaceOrigin rtOrigin);
 
     void initFSAASupport();
 
@@ -254,12 +232,12 @@
     // ensures that such operations don't negatively interact with tracking bound textures.
     void setScratchTextureUnit();
 
-    // bound is region that may be modified and therefore has to be resolved.
+    // bounds is region that may be modified and therefore has to be resolved.
     // NULL means whole target. Can be an empty rect.
-    void flushRenderTarget(const SkIRect* bound);
+    void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
+
     void flushStencil(DrawType);
-    void flushAAState(DrawType);
-    void flushPathStencilSettings(SkPath::FillType fill);
+    void flushAAState(const GrOptDrawState&, DrawType);
 
     bool configToGLFormats(GrPixelConfig config,
                            bool getSizedInternal,
@@ -290,6 +268,8 @@
                                    GrGLuint texID,
                                    GrGLRenderTarget::Desc* desc);
 
+    GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport);
+
     GrGLContext fGLContext;
 
     // GL program-related state
@@ -337,7 +317,7 @@
             fDefaultVertexArrayBoundIndexBufferID = false;
             fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
             fDefaultVertexArrayAttribState.invalidate();
-            if (NULL != fVBOVertexArray) {
+            if (fVBOVertexArray) {
                 fVBOVertexArray->invalidateCachedState();
             }
         }
@@ -365,7 +345,7 @@
             if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
                 fBoundVertexBufferID = 0;
             }
-            if (NULL != fVBOVertexArray) {
+            if (fVBOVertexArray) {
                 fVBOVertexArray->notifyVertexBufferDelete(id);
             }
             fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
@@ -376,7 +356,7 @@
                 id == fDefaultVertexArrayBoundIndexBufferID) {
                 fDefaultVertexArrayBoundIndexBufferID = 0;
             }
-            if (NULL != fVBOVertexArray) {
+            if (fVBOVertexArray) {
                 fVBOVertexArray->notifyIndexBufferDelete(id);
             }
         }
@@ -445,44 +425,26 @@
         }
     } fHWBlendState;
 
-    struct {
-        TriState fMSAAEnabled;
-        TriState fSmoothLineEnabled;
-        void invalidate() {
-            fMSAAEnabled = kUnknown_TriState;
-            fSmoothLineEnabled = kUnknown_TriState;
-        }
-    } fHWAAState;
-
-
-    GrGLProgram::MatrixState    fHWProjectionMatrixState;
+    TriState fMSAAEnabled;
 
     GrStencilSettings           fHWStencilSettings;
     TriState                    fHWStencilTestEnabled;
-    GrStencilSettings           fHWPathStencilSettings;
+
 
     GrDrawState::DrawFace       fHWDrawFace;
     TriState                    fHWWriteToColor;
     TriState                    fHWDitherEnabled;
-    GrRenderTarget*             fHWBoundRenderTarget;
-    SkTArray<GrTexture*, true>  fHWBoundTextures;
+    uint32_t                    fHWBoundRenderTargetUniqueID;
+    SkTArray<uint32_t, true>    fHWBoundTextureUniqueIDs;
 
-    struct PathTexGenData {
-        GrGLenum  fMode;
-        GrGLint   fNumComponents;
-        GrGLfloat fCoefficients[3 * 3];
-    };
-    int                         fHWActivePathTexGenSets;
-    SkTArray<PathTexGenData, true>  fHWPathTexGenSettings;
     ///@}
 
     // we record what stencil format worked last time to hopefully exit early
     // from our loop that tries stencil formats and calls check fb status.
     int fLastSuccessfulStencilFmtIdx;
 
-    SkAutoTDelete<GrGLNameAllocator> fPathNameAllocator;
-
     typedef GrGpu INHERITED;
+    friend class GrGLPathRendering; // For accessing setTextureUnit.
 };
 
 #endif
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index bd4758c..2e6bfc4 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -7,10 +7,11 @@
 
 #include "GrGpuGL.h"
 
-#include "GrEffect.h"
-#include "GrGLEffect.h"
+#include "GrProcessor.h"
+#include "GrGLProcessor.h"
+#include "GrGLPathRendering.h"
+#include "GrOptDrawState.h"
 #include "SkRTConf.h"
-#include "GrGLNameAllocator.h"
 #include "SkTSearch.h"
 
 #ifdef PROGRAM_CACHE_STATS
@@ -18,7 +19,7 @@
                 "Display program cache usage.");
 #endif
 
-typedef GrGLUniformManager::UniformHandle UniformHandle;
+typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 
 struct GrGpuGL::ProgramCache::Entry {
     SK_DECLARE_INST_COUNT_ROOT(Entry);
@@ -30,12 +31,12 @@
 
 struct GrGpuGL::ProgramCache::ProgDescLess {
     bool operator() (const GrGLProgramDesc& desc, const Entry* entry) {
-        SkASSERT(NULL != entry->fProgram.get());
+        SkASSERT(entry->fProgram.get());
         return GrGLProgramDesc::Less(desc, entry->fProgram->getDesc());
     }
 
     bool operator() (const Entry* entry, const GrGLProgramDesc& desc) {
-        SkASSERT(NULL != entry->fProgram.get());
+        SkASSERT(entry->fProgram.get());
         return GrGLProgramDesc::Less(entry->fProgram->getDesc(), desc);
     }
 };
@@ -77,9 +78,9 @@
 
 void GrGpuGL::ProgramCache::abandon() {
     for (int i = 0; i < fCount; ++i) {
-        SkASSERT(NULL != fEntries[i]->fProgram.get());
+        SkASSERT(fEntries[i]->fProgram.get());
         fEntries[i]->fProgram->abandon();
-        fEntries[i]->fProgram.reset(NULL);
+        SkDELETE(fEntries[i]);
     }
     fCount = 0;
 }
@@ -90,8 +91,9 @@
 }
 
 GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc,
-                                               const GrEffectStage* colorStages[],
-                                               const GrEffectStage* coverageStages[]) {
+                                               const GrGeometryStage* geometryProcessor,
+                                               const GrFragmentStage* colorStages[],
+                                               const GrFragmentStage* coverageStages[]) {
 #ifdef PROGRAM_CACHE_STATS
     ++fTotalRequests;
 #endif
@@ -105,8 +107,8 @@
     }
     hashIdx &=((1 << kHashBits) - 1);
     Entry* hashedEntry = fHashTable[hashIdx];
-    if (NULL != hashedEntry && hashedEntry->fProgram->getDesc() == desc) {
-        SkASSERT(NULL != hashedEntry->fProgram);
+    if (hashedEntry && hashedEntry->fProgram->getDesc() == desc) {
+        SkASSERT(hashedEntry->fProgram);
         entry = hashedEntry;
     }
 
@@ -126,7 +128,8 @@
 #ifdef PROGRAM_CACHE_STATS
         ++fCacheMisses;
 #endif
-        GrGLProgram* program = GrGLProgram::Create(fGpu, desc, colorStages, coverageStages);
+        GrGLProgram* program = GrGLProgram::Create(fGpu, desc, geometryProcessor,
+                colorStages, coverageStages);
         if (NULL == program) {
             return NULL;
         }
@@ -173,9 +176,9 @@
             fEntries[entryIdx - 1] = entry;
         }
 #ifdef SK_DEBUG
-        SkASSERT(NULL != fEntries[0]->fProgram.get());
+        SkASSERT(fEntries[0]->fProgram.get());
         for (int i = 0; i < fCount - 1; ++i) {
-            SkASSERT(NULL != fEntries[i + 1]->fProgram.get());
+            SkASSERT(fEntries[i + 1]->fProgram.get());
             const GrGLProgramDesc& a = fEntries[i]->fProgram->getDesc();
             const GrGLProgramDesc& b = fEntries[i + 1]->fProgram->getDesc();
             SkASSERT(GrGLProgramDesc::Less(a, b));
@@ -199,53 +202,51 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrGpuGL::abandonResources(){
-    INHERITED::abandonResources();
-    fProgramCache->abandon();
-    fHWProgramID = 0;
-    fPathNameAllocator.reset(NULL);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
 
 bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) {
-    const GrDrawState& drawState = this->getDrawState();
+    SkAutoTUnref<GrOptDrawState> optState(this->getDrawState().createOptState(*this->caps()));
 
     // GrGpu::setupClipAndFlushState should have already checked this and bailed if not true.
-    SkASSERT(NULL != drawState.getRenderTarget());
+    SkASSERT(optState->getRenderTarget());
 
     if (kStencilPath_DrawType == type) {
-        const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
+        const GrRenderTarget* rt = optState->getRenderTarget();
         SkISize size;
         size.set(rt->width(), rt->height());
-        this->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
+        this->glPathRendering()->setProjectionMatrix(optState->getViewMatrix(), size, rt->origin());
     } else {
-        this->flushMiscFixedFunctionState();
+        this->flushMiscFixedFunctionState(*optState.get());
 
-        GrBlendCoeff srcCoeff;
-        GrBlendCoeff dstCoeff;
-        GrDrawState::BlendOptFlags blendOpts = drawState.getBlendOpts(false, &srcCoeff, &dstCoeff);
-        if (GrDrawState::kSkipDraw_BlendOptFlag & blendOpts) {
+        GrBlendCoeff srcCoeff = optState->getSrcBlendCoeff();
+        GrBlendCoeff dstCoeff = optState->getDstBlendCoeff();
+
+        // In these blend coeff's we end up drawing nothing so we can skip draw all together
+        if (kZero_GrBlendCoeff == srcCoeff && kOne_GrBlendCoeff == dstCoeff &&
+            !optState->getStencil().doesWrite()) {
             return false;
         }
 
-        SkSTArray<8, const GrEffectStage*, true> colorStages;
-        SkSTArray<8, const GrEffectStage*, true> coverageStages;
+        const GrGeometryStage* geometryProcessor = NULL;
+        SkSTArray<8, const GrFragmentStage*, true> colorStages;
+        SkSTArray<8, const GrFragmentStage*, true> coverageStages;
         GrGLProgramDesc desc;
-        GrGLProgramDesc::Build(this->getDrawState(),
+        if (!GrGLProgramDesc::Build(*optState.get(),
                                type,
-                               blendOpts,
                                srcCoeff,
                                dstCoeff,
                                this,
                                dstCopy,
+                               &geometryProcessor,
                                &colorStages,
                                &coverageStages,
-                               &desc);
+                               &desc)) {
+            SkDEBUGFAIL("Failed to generate GL program descriptor");
+            return false;
+        }
 
         fCurrentProgram.reset(fProgramCache->getProgram(desc,
+                                                        geometryProcessor,
                                                         colorStages.begin(),
                                                         coverageStages.begin()));
         if (NULL == fCurrentProgram.get()) {
@@ -253,9 +254,6 @@
             return false;
         }
 
-        SkASSERT((kDrawPath_DrawType != type && kDrawPaths_DrawType != type)
-                 || !fCurrentProgram->hasVertexShader());
-
         fCurrentProgram.get()->ref();
 
         GrGLuint programID = fCurrentProgram->programID();
@@ -264,35 +262,39 @@
             fHWProgramID = programID;
         }
 
-        fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff);
-        this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
+        this->flushBlend(*optState.get(), kDrawLines_DrawType == type, srcCoeff, dstCoeff);
 
-        fCurrentProgram->setData(blendOpts,
+        fCurrentProgram->setData(*optState.get(),
+                                 type,
+                                 geometryProcessor,
                                  colorStages.begin(),
                                  coverageStages.begin(),
                                  dstCopy,
                                  &fSharedGLProgramState);
     }
+
+    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState->getRenderTarget());
     this->flushStencil(type);
-    this->flushScissor();
-    this->flushAAState(type);
+    this->flushScissor(glRT->getViewport(), glRT->origin());
+    this->flushAAState(*optState.get(), type);
 
     SkIRect* devRect = NULL;
     SkIRect devClipBounds;
-    if (drawState.isClipState()) {
-        this->getClip()->getConservativeBounds(drawState.getRenderTarget(), &devClipBounds);
+    if (optState->isClipState()) {
+        this->getClip()->getConservativeBounds(optState->getRenderTarget(), &devClipBounds);
         devRect = &devClipBounds;
     }
     // This must come after textures are flushed because a texture may need
     // to be msaa-resolved (which will modify bound FBO state).
-    this->flushRenderTarget(devRect);
+    this->flushRenderTarget(glRT, devRect);
 
     return true;
 }
 
 void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
+    SkAutoTUnref<GrOptDrawState> optState(this->getDrawState().createOptState(*this->caps()));
 
-    GrGLsizei stride = static_cast<GrGLsizei>(this->getDrawState().getVertexSize());
+    GrGLsizei stride = static_cast<GrGLsizei>(optState->getVertexStride());
 
     size_t vertexOffsetInBytes = stride * info.startVertex();
 
@@ -314,13 +316,13 @@
             SkFAIL("Unknown geometry src type!");
     }
 
-    SkASSERT(NULL != vbuf);
+    SkASSERT(vbuf);
     SkASSERT(!vbuf->isMapped());
     vertexOffsetInBytes += vbuf->baseOffset();
 
     GrGLIndexBuffer* ibuf = NULL;
     if (info.isIndexed()) {
-        SkASSERT(NULL != indexOffsetInBytes);
+        SkASSERT(indexOffsetInBytes);
 
         switch (this->getGeomSrc().fIndexSrc) {
         case kBuffer_GeometrySrcType:
@@ -338,7 +340,7 @@
             SkFAIL("Unknown geometry src type!");
         }
 
-        SkASSERT(NULL != ibuf);
+        SkASSERT(ibuf);
         SkASSERT(!ibuf->isMapped());
         *indexOffsetInBytes += ibuf->baseOffset();
     }
@@ -346,13 +348,12 @@
         fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf);
 
     if (fCurrentProgram->hasVertexShader()) {
-        int vertexAttribCount = this->getDrawState().getVertexAttribCount();
+        int vertexAttribCount = optState->getVertexAttribCount();
         uint32_t usedAttribArraysMask = 0;
-        const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs();
+        const GrVertexAttrib* vertexAttrib = optState->getVertexAttribs();
 
         for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
              ++vertexAttribIndex, ++vertexAttrib) {
-
             usedAttribArraysMask |= (1 << vertexAttribIndex);
             GrVertexAttribType attribType = vertexAttrib->fType;
             attribState->set(this,
diff --git a/src/gpu/gl/SkGLContextHelper.cpp b/src/gpu/gl/SkGLContextHelper.cpp
index b06f755..03b70c3 100644
--- a/src/gpu/gl/SkGLContextHelper.cpp
+++ b/src/gpu/gl/SkGLContextHelper.cpp
@@ -27,13 +27,14 @@
     SkSafeUnref(fGL);
 }
 
-bool SkGLContextHelper::init(int width, int height) {
+bool SkGLContextHelper::init(GrGLStandard forcedGpuAPI, int width,
+                             int height) {
     if (fGL) {
         fGL->unref();
         this->destroyGLContext();
     }
 
-    fGL = this->createGLContext();
+    fGL = this->createGLContext(forcedGpuAPI);
     if (fGL) {
         const GrGLubyte* temp;
 
@@ -133,3 +134,9 @@
     }
     return false;
 }
+
+void SkGLContextHelper::testAbandon() {
+    if (fGL) {
+        fGL->abandon();
+    }
+}
diff --git a/src/gpu/gl/SkNullGLContext.cpp b/src/gpu/gl/SkNullGLContext.cpp
index 86c09b2..576ee52 100644
--- a/src/gpu/gl/SkNullGLContext.cpp
+++ b/src/gpu/gl/SkNullGLContext.cpp
@@ -8,6 +8,9 @@
 
 #include "gl/SkNullGLContext.h"
 
-const GrGLInterface* SkNullGLContext::createGLContext() {
+const GrGLInterface* SkNullGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
+    if (kGLES_GrGLStandard == forcedGpuAPI) {
+        return NULL;
+    }
     return GrGLCreateNullInterface();
 };
diff --git a/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp b/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp
index 781e29b..907a816 100644
--- a/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp
+++ b/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp
@@ -1,276 +1,415 @@
-// Modified from chromium/src/webkit/glue/gl_bindings_skia_cmd_buffer.cc
 
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
+/*
+ * 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 "gl/GrGLInterface.h"
 #include "gl/GrGLAssembleInterface.h"
-#include "gl/GrGLExtensions.h"
 #include "gl/GrGLUtil.h"
 
-#ifndef GL_GLEXT_PROTOTYPES
-#define GL_GLEXT_PROTOTYPES
-#endif
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
 #include <EGL/egl.h>
-
-static GrGLInterface* create_es_interface(GrGLVersion version,
-                                          GrGLExtensions* extensions) {
-    if (version < GR_GL_VER(2,0)) {
-        return NULL;
-    }
-
-    GrGLInterface* interface = SkNEW(GrGLInterface);
-    interface->fStandard = kGLES_GrGLStandard;
-    GrGLInterface::Functions* functions = &interface->fFunctions;
-
-    functions->fActiveTexture = glActiveTexture;
-    functions->fAttachShader = glAttachShader;
-    functions->fBindAttribLocation = glBindAttribLocation;
-    functions->fBindBuffer = glBindBuffer;
-    functions->fBindTexture = glBindTexture;
-    functions->fBindVertexArray = glBindVertexArrayOES;
-    functions->fBlendColor = glBlendColor;
-    functions->fBlendFunc = glBlendFunc;
-    functions->fBufferData = glBufferData;
-    functions->fBufferSubData = glBufferSubData;
-    functions->fClear = glClear;
-    functions->fClearColor = glClearColor;
-    functions->fClearStencil = glClearStencil;
-    functions->fColorMask = glColorMask;
-    functions->fCompileShader = glCompileShader;
-    functions->fCompressedTexImage2D = glCompressedTexImage2D;
-    functions->fCompressedTexSubImage2D = glCompressedTexSubImage2D;
-    functions->fCopyTexSubImage2D = glCopyTexSubImage2D;
-    functions->fCreateProgram = glCreateProgram;
-    functions->fCreateShader = glCreateShader;
-    functions->fCullFace = glCullFace;
-    functions->fDeleteBuffers = glDeleteBuffers;
-    functions->fDeleteProgram = glDeleteProgram;
-    functions->fDeleteShader = glDeleteShader;
-    functions->fDeleteTextures = glDeleteTextures;
-    functions->fDeleteVertexArrays = glDeleteVertexArraysOES;
-    functions->fDepthMask = glDepthMask;
-    functions->fDisable = glDisable;
-    functions->fDisableVertexAttribArray = glDisableVertexAttribArray;
-    functions->fDrawArrays = glDrawArrays;
-    functions->fDrawElements = glDrawElements;
-    functions->fEnable = glEnable;
-    functions->fEnableVertexAttribArray = glEnableVertexAttribArray;
-    functions->fFinish = glFinish;
-    functions->fFlush = glFlush;
-    functions->fFrontFace = glFrontFace;
-    functions->fGenBuffers = glGenBuffers;
-    functions->fGenerateMipmap = glGenerateMipmap;
-    functions->fGenTextures = glGenTextures;
-    functions->fGenVertexArrays = glGenVertexArraysOES;
-    functions->fGetBufferParameteriv = glGetBufferParameteriv;
-    functions->fGetError = glGetError;
-    functions->fGetIntegerv = glGetIntegerv;
-    functions->fGetProgramInfoLog = glGetProgramInfoLog;
-    functions->fGetProgramiv = glGetProgramiv;
-    functions->fGetShaderInfoLog = glGetShaderInfoLog;
-    functions->fGetShaderiv = glGetShaderiv;
-    functions->fGetString = glGetString;
-#if GL_ES_VERSION_3_0
-    functions->fGetStringi = glGetStringi;
-#else
-    functions->fGetStringi = (GrGLGetStringiProc) eglGetProcAddress("glGetStringi");
-#endif
-    functions->fGetUniformLocation = glGetUniformLocation;
-    functions->fLineWidth = glLineWidth;
-    functions->fLinkProgram = glLinkProgram;
-    functions->fPixelStorei = glPixelStorei;
-    functions->fReadPixels = glReadPixels;
-    functions->fScissor = glScissor;
-#if GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE
-    functions->fShaderSource = (GrGLShaderSourceProc) glShaderSource;
-#else
-    functions->fShaderSource = glShaderSource;
-#endif
-    functions->fStencilFunc = glStencilFunc;
-    functions->fStencilFuncSeparate = glStencilFuncSeparate;
-    functions->fStencilMask = glStencilMask;
-    functions->fStencilMaskSeparate = glStencilMaskSeparate;
-    functions->fStencilOp = glStencilOp;
-    functions->fStencilOpSeparate = glStencilOpSeparate;
-    functions->fTexImage2D = glTexImage2D;
-    functions->fTexParameteri = glTexParameteri;
-    functions->fTexParameteriv = glTexParameteriv;
-    functions->fTexSubImage2D = glTexSubImage2D;
-
-    if (version >= GR_GL_VER(3,0)) {
-#if GL_ES_VERSION_3_0
-        functions->fTexStorage2D = glTexStorage2D;
-#else
-        functions->fTexStorage2D = (GrGLTexStorage2DProc) eglGetProcAddress("glTexStorage2D");
-#endif
-    } else {
-#if GL_EXT_texture_storage
-        functions->fTexStorage2D = glTexStorage2DEXT;
-#else
-        functions->fTexStorage2D = (GrGLTexStorage2DProc) eglGetProcAddress("glTexStorage2DEXT");
-#endif
-    }
-
-#if GL_EXT_discard_framebuffer
-    functions->fDiscardFramebuffer = glDiscardFramebufferEXT;
-#endif
-    functions->fUniform1f = glUniform1f;
-    functions->fUniform1i = glUniform1i;
-    functions->fUniform1fv = glUniform1fv;
-    functions->fUniform1iv = glUniform1iv;
-    functions->fUniform2f = glUniform2f;
-    functions->fUniform2i = glUniform2i;
-    functions->fUniform2fv = glUniform2fv;
-    functions->fUniform2iv = glUniform2iv;
-    functions->fUniform3f = glUniform3f;
-    functions->fUniform3i = glUniform3i;
-    functions->fUniform3fv = glUniform3fv;
-    functions->fUniform3iv = glUniform3iv;
-    functions->fUniform4f = glUniform4f;
-    functions->fUniform4i = glUniform4i;
-    functions->fUniform4fv = glUniform4fv;
-    functions->fUniform4iv = glUniform4iv;
-    functions->fUniformMatrix2fv = glUniformMatrix2fv;
-    functions->fUniformMatrix3fv = glUniformMatrix3fv;
-    functions->fUniformMatrix4fv = glUniformMatrix4fv;
-    functions->fUseProgram = glUseProgram;
-    functions->fVertexAttrib4fv = glVertexAttrib4fv;
-    functions->fVertexAttribPointer = glVertexAttribPointer;
-    functions->fViewport = glViewport;
-    functions->fBindFramebuffer = glBindFramebuffer;
-    functions->fBindRenderbuffer = glBindRenderbuffer;
-    functions->fCheckFramebufferStatus = glCheckFramebufferStatus;
-    functions->fDeleteFramebuffers = glDeleteFramebuffers;
-    functions->fDeleteRenderbuffers = glDeleteRenderbuffers;
-    functions->fFramebufferRenderbuffer = glFramebufferRenderbuffer;
-    functions->fFramebufferTexture2D = glFramebufferTexture2D;
-
-    if (version >= GR_GL_VER(3,0)) {
-#if GL_ES_VERSION_3_0
-        functions->fRenderbufferStorageMultisample = glRenderbufferStorageMultisample;
-        functions->fBlitFramebuffer = glBlitFramebuffer;
-#else
-        functions->fRenderbufferStorageMultisample = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisample");
-        functions->fBlitFramebuffer = (GrGLBlitFramebufferProc) eglGetProcAddress("glBlitFramebuffer");
-#endif
-    }
-
-    if (extensions->has("GL_EXT_multisampled_render_to_texture")) {
-#if GL_EXT_multisampled_render_to_texture
-        functions->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleEXT;
-        functions->fRenderbufferStorageMultisampleES2EXT = glRenderbufferStorageMultisampleEXT;
-#else
-        functions->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleEXT");
-        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleEXT");
-#endif
-    } else if (extensions->has("GL_IMG_multisampled_render_to_texture")) {
-#if GL_IMG_multisampled_render_to_texture
-        functions->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleIMG;
-        functions->fRenderbufferStorageMultisampleES2EXT = glRenderbufferStorageMultisampleIMG;
-#else
-        functions->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleIMG");
-        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleIMG");
-#endif
-    }
-
-    functions->fGenFramebuffers = glGenFramebuffers;
-    functions->fGenRenderbuffers = glGenRenderbuffers;
-    functions->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
-    functions->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
-    functions->fRenderbufferStorage = glRenderbufferStorage;
-
-#if GL_OES_mapbuffer
-    functions->fMapBuffer = glMapBufferOES;
-    functions->fUnmapBuffer = glUnmapBufferOES;
-#else
-    functions->fMapBuffer = (GrGLMapBufferProc) eglGetProcAddress("glMapBufferOES");
-    functions->fUnmapBuffer = (GrGLUnmapBufferProc) eglGetProcAddress("glUnmapBufferOES");
-
-#endif
-
-    if (version >= GR_GL_VER(3,0)) {
-#if GL_ES_VERSION_3_0
-        functions->fMapBufferRange = glMapBufferRange;
-        functions->fFlushMappedBufferRange = glFlushMappedBufferRange;
-#else
-        functions->fMapBufferRange = (GrGLMapBufferRangeProc) eglGetProcAddress("glMapBufferRange");
-        functions->fFlushMappedBufferRange = (GrGLFlushMappedBufferRangeProc) eglGetProcAddress("glFlushMappedBufferRange");
-#endif
-    } else if (extensions->has("GL_EXT_map_buffer_range")) {
-#if GL_EXT_map_buffer_range
-        functions->fMapBufferRange = glMapBufferRangeEXT;
-        functions->fFlushMappedBufferRange = glFlushMappedBufferRangeEXT;
-#else
-        functions->fMapBufferRange = (GrGLMapBufferRangeProc) eglGetProcAddress("glMapBufferRangeEXT");
-        functions->fFlushMappedBufferRange = (GrGLFlushMappedBufferRangeProc) eglGetProcAddress("glFlushMappedBufferRangeEXT");
-#endif
-    }
-
-    if (extensions->has("GL_EXT_debug_marker")) {
-        functions->fInsertEventMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glInsertEventMarker");
-        functions->fPushGroupMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glPushGroupMarker");
-        functions->fPopGroupMarker = (GrGLPopGroupMarkerProc) eglGetProcAddress("glPopGroupMarker");
-        // The below check is here because a device has been found that has the extension string but
-        // returns NULL from the eglGetProcAddress for the functions
-        if (NULL == functions->fInsertEventMarker ||
-            NULL == functions->fPushGroupMarker ||
-            NULL == functions->fPopGroupMarker) {
-            extensions->remove("GL_EXT_debug_marker");
-        }
-    }
-
-#if GL_ES_VERSION_3_0
-    functions->fInvalidateFramebuffer = glInvalidateFramebuffer;
-    functions->fInvalidateSubFramebuffer = glInvalidateSubFramebuffer;
-#else
-    functions->fInvalidateFramebuffer = (GrGLInvalidateFramebufferProc) eglGetProcAddress("glInvalidateFramebuffer");
-    functions->fInvalidateSubFramebuffer = (GrGLInvalidateSubFramebufferProc) eglGetProcAddress("glInvalidateSubFramebuffer");
-#endif
-    functions->fInvalidateBufferData = (GrGLInvalidateBufferDataProc) eglGetProcAddress("glInvalidateBufferData");
-    functions->fInvalidateBufferSubData = (GrGLInvalidateBufferSubDataProc) eglGetProcAddress("glInvalidateBufferSubData");
-    functions->fInvalidateTexImage = (GrGLInvalidateTexImageProc) eglGetProcAddress("glInvalidateTexImage");
-    functions->fInvalidateTexSubImage = (GrGLInvalidateTexSubImageProc) eglGetProcAddress("glInvalidateTexSubImage");
-
-    return interface;
-}
+#include <GLES2/gl2.h>
 
 static GrGLFuncPtr android_get_gl_proc(void* ctx, const char name[]) {
     SkASSERT(NULL == ctx);
+    // Some older drivers on Android have busted eglGetProcAdddress Functions that
+    // will return the wrong pointer for built in GLES2 functions. This set of functions
+    // was generated on a Xoom by finding mismatches between the function pulled in via gl2.h and
+    // the address returned by eglGetProcAddress.
+    if (0 == strcmp("glActiveTexture", name)) {
+        return (GrGLFuncPtr) glActiveTexture;
+    } else if (0 == strcmp("glAttachShader", name)) {
+        return (GrGLFuncPtr) glAttachShader;
+    } else if (0 == strcmp("glBindAttribLocation", name)) {
+        return (GrGLFuncPtr) glBindAttribLocation;
+    } else if (0 == strcmp("glBindBuffer", name)) {
+        return (GrGLFuncPtr) glBindBuffer;
+    } else if (0 == strcmp("glBindTexture", name)) {
+        return (GrGLFuncPtr) glBindTexture;
+    } else if (0 == strcmp("glBlendColor", name)) {
+        return (GrGLFuncPtr) glBlendColor;
+    } else if (0 == strcmp("glBlendFunc", name)) {
+        return (GrGLFuncPtr) glBlendFunc;
+    } else if (0 == strcmp("glBufferData", name)) {
+        return (GrGLFuncPtr) glBufferData;
+    } else if (0 == strcmp("glBufferSubData", name)) {
+        return (GrGLFuncPtr) glBufferSubData;
+    } else if (0 == strcmp("glClear", name)) {
+        return (GrGLFuncPtr) glClear;
+    } else if (0 == strcmp("glClearColor", name)) {
+        return (GrGLFuncPtr) glClearColor;
+    } else if (0 == strcmp("glClearStencil", name)) {
+        return (GrGLFuncPtr) glClearStencil;
+    } else if (0 == strcmp("glColorMask", name)) {
+        return (GrGLFuncPtr) glColorMask;
+    } else if (0 == strcmp("glCompileShader", name)) {
+        return (GrGLFuncPtr) glCompileShader;
+    } else if (0 == strcmp("glCompressedTexImage2D", name)) {
+        return (GrGLFuncPtr) glCompressedTexImage2D;
+    } else if (0 == strcmp("glCompressedTexSubImage2D", name)) {
+        return (GrGLFuncPtr) glCompressedTexSubImage2D;
+    } else if (0 == strcmp("glCopyTexSubImage2D", name)) {
+        return (GrGLFuncPtr) glCopyTexSubImage2D;
+    } else if (0 == strcmp("glCreateProgram", name)) {
+        return (GrGLFuncPtr) glCreateProgram;
+    } else if (0 == strcmp("glCreateShader", name)) {
+        return (GrGLFuncPtr) glCreateShader;
+    } else if (0 == strcmp("glCullFace", name)) {
+        return (GrGLFuncPtr) glCullFace;
+    } else if (0 == strcmp("glDeleteBuffers", name)) {
+        return (GrGLFuncPtr) glDeleteBuffers;
+    } else if (0 == strcmp("glDeleteProgram", name)) {
+        return (GrGLFuncPtr) glDeleteProgram;
+    } else if (0 == strcmp("glDeleteShader", name)) {
+        return (GrGLFuncPtr) glDeleteShader;
+    } else if (0 == strcmp("glDeleteTextures", name)) {
+        return (GrGLFuncPtr) glDeleteTextures;
+    } else if (0 == strcmp("glDepthMask", name)) {
+        return (GrGLFuncPtr) glDepthMask;
+    } else if (0 == strcmp("glDisable", name)) {
+        return (GrGLFuncPtr) glDisable;
+    } else if (0 == strcmp("glDisableVertexAttribArray", name)) {
+        return (GrGLFuncPtr) glDisableVertexAttribArray;
+    } else if (0 == strcmp("glDrawArrays", name)) {
+        return (GrGLFuncPtr) glDrawArrays;
+    } else if (0 == strcmp("glDrawElements", name)) {
+        return (GrGLFuncPtr) glDrawElements;
+    } else if (0 == strcmp("glEnable", name)) {
+        return (GrGLFuncPtr) glEnable;
+    } else if (0 == strcmp("glEnableVertexAttribArray", name)) {
+        return (GrGLFuncPtr) glEnableVertexAttribArray;
+    } else if (0 == strcmp("glFinish", name)) {
+        return (GrGLFuncPtr) glFinish;
+    } else if (0 == strcmp("glFlush", name)) {
+        return (GrGLFuncPtr) glFlush;
+    } else if (0 == strcmp("glFrontFace", name)) {
+        return (GrGLFuncPtr) glFrontFace;
+    } else if (0 == strcmp("glGenBuffers", name)) {
+        return (GrGLFuncPtr) glGenBuffers;
+    } else if (0 == strcmp("glGenerateMipmap", name)) {
+        return (GrGLFuncPtr) glGenerateMipmap;
+    } else if (0 == strcmp("glGenTextures", name)) {
+        return (GrGLFuncPtr) glGenTextures;
+    } else if (0 == strcmp("glGetBufferParameteriv", name)) {
+        return (GrGLFuncPtr) glGetBufferParameteriv;
+    } else if (0 == strcmp("glGetError", name)) {
+        return (GrGLFuncPtr) glGetError;
+    } else if (0 == strcmp("glGetIntegerv", name)) {
+        return (GrGLFuncPtr) glGetIntegerv;
+    } else if (0 == strcmp("glGetProgramInfoLog", name)) {
+        return (GrGLFuncPtr) glGetProgramInfoLog;
+    } else if (0 == strcmp("glGetProgramiv", name)) {
+        return (GrGLFuncPtr) glGetProgramiv;
+    } else if (0 == strcmp("glGetShaderInfoLog", name)) {
+        return (GrGLFuncPtr) glGetShaderInfoLog;
+    } else if (0 == strcmp("glGetShaderiv", name)) {
+        return (GrGLFuncPtr) glGetShaderiv;
+    } else if (0 == strcmp("glGetString", name)) {
+        return (GrGLFuncPtr) glGetString;
+    } else if (0 == strcmp("glGetUniformLocation", name)) {
+        return (GrGLFuncPtr) glGetUniformLocation;
+    } else if (0 == strcmp("glLineWidth", name)) {
+        return (GrGLFuncPtr) glLineWidth;
+    } else if (0 == strcmp("glLinkProgram", name)) {
+        return (GrGLFuncPtr) glLinkProgram;
+    } else if (0 == strcmp("glPixelStorei", name)) {
+        return (GrGLFuncPtr) glPixelStorei;
+    } else if (0 == strcmp("glReadPixels", name)) {
+        return (GrGLFuncPtr) glReadPixels;
+    } else if (0 == strcmp("glScissor", name)) {
+        return (GrGLFuncPtr) glScissor;
+    } else if (0 == strcmp("glShaderSource", name)) {
+        return (GrGLFuncPtr) glShaderSource;
+    } else if (0 == strcmp("glStencilFunc", name)) {
+        return (GrGLFuncPtr) glStencilFunc;
+    } else if (0 == strcmp("glStencilFuncSeparate", name)) {
+        return (GrGLFuncPtr) glStencilFuncSeparate;
+    } else if (0 == strcmp("glStencilMask", name)) {
+        return (GrGLFuncPtr) glStencilMask;
+    } else if (0 == strcmp("glStencilMaskSeparate", name)) {
+        return (GrGLFuncPtr) glStencilMaskSeparate;
+    } else if (0 == strcmp("glStencilOp", name)) {
+        return (GrGLFuncPtr) glStencilOp;
+    } else if (0 == strcmp("glStencilOpSeparate", name)) {
+        return (GrGLFuncPtr) glStencilOpSeparate;
+    } else if (0 == strcmp("glTexImage2D", name)) {
+        return (GrGLFuncPtr) glTexImage2D;
+    } else if (0 == strcmp("glTexParameteri", name)) {
+        return (GrGLFuncPtr) glTexParameteri;
+    } else if (0 == strcmp("glTexParameteriv", name)) {
+        return (GrGLFuncPtr) glTexParameteriv;
+    } else if (0 == strcmp("glTexSubImage2D", name)) {
+        return (GrGLFuncPtr) glTexSubImage2D;
+    } else if (0 == strcmp("glUniform1f", name)) {
+        return (GrGLFuncPtr) glUniform1f;
+    } else if (0 == strcmp("glUniform1i", name)) {
+        return (GrGLFuncPtr) glUniform1i;
+    } else if (0 == strcmp("glUniform1fv", name)) {
+        return (GrGLFuncPtr) glUniform1fv;
+    } else if (0 == strcmp("glUniform1iv", name)) {
+        return (GrGLFuncPtr) glUniform1iv;
+    } else if (0 == strcmp("glUniform2f", name)) {
+        return (GrGLFuncPtr) glUniform2f;
+    } else if (0 == strcmp("glUniform2i", name)) {
+        return (GrGLFuncPtr) glUniform2i;
+    } else if (0 == strcmp("glUniform2fv", name)) {
+        return (GrGLFuncPtr) glUniform2fv;
+    } else if (0 == strcmp("glUniform2iv", name)) {
+        return (GrGLFuncPtr) glUniform2iv;
+    } else if (0 == strcmp("glUniform3f", name)) {
+        return (GrGLFuncPtr) glUniform3f;
+    } else if (0 == strcmp("glUniform3i", name)) {
+        return (GrGLFuncPtr) glUniform3i;
+    } else if (0 == strcmp("glUniform3fv", name)) {
+        return (GrGLFuncPtr) glUniform3fv;
+    } else if (0 == strcmp("glUniform3iv", name)) {
+        return (GrGLFuncPtr) glUniform3iv;
+    } else if (0 == strcmp("glUniform4f", name)) {
+        return (GrGLFuncPtr) glUniform4f;
+    } else if (0 == strcmp("glUniform4i", name)) {
+        return (GrGLFuncPtr) glUniform4i;
+    } else if (0 == strcmp("glUniform4fv", name)) {
+        return (GrGLFuncPtr) glUniform4fv;
+    } else if (0 == strcmp("glUniform4iv", name)) {
+        return (GrGLFuncPtr) glUniform4iv;
+    } else if (0 == strcmp("glUniformMatrix2fv", name)) {
+        return (GrGLFuncPtr) glUniformMatrix2fv;
+    } else if (0 == strcmp("glUniformMatrix3fv", name)) {
+        return (GrGLFuncPtr) glUniformMatrix3fv;
+    } else if (0 == strcmp("glUniformMatrix4fv", name)) {
+        return (GrGLFuncPtr) glUniformMatrix4fv;
+    } else if (0 == strcmp("glUseProgram", name)) {
+        return (GrGLFuncPtr) glUseProgram;
+    } else if (0 == strcmp("glVertexAttrib4fv", name)) {
+        return (GrGLFuncPtr) glVertexAttrib4fv;
+    } else if (0 == strcmp("glVertexAttribPointer", name)) {
+        return (GrGLFuncPtr) glVertexAttribPointer;
+    } else if (0 == strcmp("glViewport", name)) {
+        return (GrGLFuncPtr) glViewport;
+    } else if (0 == strcmp("glBindFramebuffer", name)) {
+        return (GrGLFuncPtr) glBindFramebuffer;
+    } else if (0 == strcmp("glBindRenderbuffer", name)) {
+        return (GrGLFuncPtr) glBindRenderbuffer;
+    } else if (0 == strcmp("glCheckFramebufferStatus", name)) {
+        return (GrGLFuncPtr) glCheckFramebufferStatus;
+    } else if (0 == strcmp("glDeleteFramebuffers", name)) {
+        return (GrGLFuncPtr) glDeleteFramebuffers;
+    } else if (0 == strcmp("glDeleteRenderbuffers", name)) {
+        return (GrGLFuncPtr) glDeleteRenderbuffers;
+    } else if (0 == strcmp("glFramebufferRenderbuffer", name)) {
+        return (GrGLFuncPtr) glFramebufferRenderbuffer;
+    } else if (0 == strcmp("glFramebufferTexture2D", name)) {
+        return (GrGLFuncPtr) glFramebufferTexture2D;
+    } else if (0 == strcmp("glGenFramebuffers", name)) {
+        return (GrGLFuncPtr) glGenFramebuffers;
+    } else if (0 == strcmp("glGenRenderbuffers", name)) {
+        return (GrGLFuncPtr) glGenRenderbuffers;
+    } else if (0 == strcmp("glGetFramebufferAttachmentParameteriv", name)) {
+        return (GrGLFuncPtr) glGetFramebufferAttachmentParameteriv;
+    } else if (0 == strcmp("glGetRenderbufferParameteriv", name)) {
+        return (GrGLFuncPtr) glGetRenderbufferParameteriv;
+    } else if (0 == strcmp("glRenderbufferStorage", name)) {
+        return (GrGLFuncPtr) glRenderbufferStorage;
+    } else if (0 == strcmp("glActiveTexture", name)) {
+        return (GrGLFuncPtr) glActiveTexture;
+    } else if (0 == strcmp("glAttachShader", name)) {
+        return (GrGLFuncPtr) glAttachShader;
+    } else if (0 == strcmp("glBindAttribLocation", name)) {
+        return (GrGLFuncPtr) glBindAttribLocation;
+    } else if (0 == strcmp("glBindBuffer", name)) {
+        return (GrGLFuncPtr) glBindBuffer;
+    } else if (0 == strcmp("glBindTexture", name)) {
+        return (GrGLFuncPtr) glBindTexture;
+    } else if (0 == strcmp("glBlendColor", name)) {
+        return (GrGLFuncPtr) glBlendColor;
+    } else if (0 == strcmp("glBlendFunc", name)) {
+        return (GrGLFuncPtr) glBlendFunc;
+    } else if (0 == strcmp("glBufferData", name)) {
+        return (GrGLFuncPtr) glBufferData;
+    } else if (0 == strcmp("glBufferSubData", name)) {
+        return (GrGLFuncPtr) glBufferSubData;
+    } else if (0 == strcmp("glClear", name)) {
+        return (GrGLFuncPtr) glClear;
+    } else if (0 == strcmp("glClearColor", name)) {
+        return (GrGLFuncPtr) glClearColor;
+    } else if (0 == strcmp("glClearStencil", name)) {
+        return (GrGLFuncPtr) glClearStencil;
+    } else if (0 == strcmp("glColorMask", name)) {
+        return (GrGLFuncPtr) glColorMask;
+    } else if (0 == strcmp("glCompileShader", name)) {
+        return (GrGLFuncPtr) glCompileShader;
+    } else if (0 == strcmp("glCompressedTexImage2D", name)) {
+        return (GrGLFuncPtr) glCompressedTexImage2D;
+    } else if (0 == strcmp("glCompressedTexSubImage2D", name)) {
+        return (GrGLFuncPtr) glCompressedTexSubImage2D;
+    } else if (0 == strcmp("glCopyTexSubImage2D", name)) {
+        return (GrGLFuncPtr) glCopyTexSubImage2D;
+    } else if (0 == strcmp("glCreateProgram", name)) {
+        return (GrGLFuncPtr) glCreateProgram;
+    } else if (0 == strcmp("glCreateShader", name)) {
+        return (GrGLFuncPtr) glCreateShader;
+    } else if (0 == strcmp("glCullFace", name)) {
+        return (GrGLFuncPtr) glCullFace;
+    } else if (0 == strcmp("glDeleteBuffers", name)) {
+        return (GrGLFuncPtr) glDeleteBuffers;
+    } else if (0 == strcmp("glDeleteProgram", name)) {
+        return (GrGLFuncPtr) glDeleteProgram;
+    } else if (0 == strcmp("glDeleteShader", name)) {
+        return (GrGLFuncPtr) glDeleteShader;
+    } else if (0 == strcmp("glDeleteTextures", name)) {
+        return (GrGLFuncPtr) glDeleteTextures;
+    } else if (0 == strcmp("glDepthMask", name)) {
+        return (GrGLFuncPtr) glDepthMask;
+    } else if (0 == strcmp("glDisable", name)) {
+        return (GrGLFuncPtr) glDisable;
+    } else if (0 == strcmp("glDisableVertexAttribArray", name)) {
+        return (GrGLFuncPtr) glDisableVertexAttribArray;
+    } else if (0 == strcmp("glDrawArrays", name)) {
+        return (GrGLFuncPtr) glDrawArrays;
+    } else if (0 == strcmp("glDrawElements", name)) {
+        return (GrGLFuncPtr) glDrawElements;
+    } else if (0 == strcmp("glEnable", name)) {
+        return (GrGLFuncPtr) glEnable;
+    } else if (0 == strcmp("glEnableVertexAttribArray", name)) {
+        return (GrGLFuncPtr) glEnableVertexAttribArray;
+    } else if (0 == strcmp("glFinish", name)) {
+        return (GrGLFuncPtr) glFinish;
+    } else if (0 == strcmp("glFlush", name)) {
+        return (GrGLFuncPtr) glFlush;
+    } else if (0 == strcmp("glFrontFace", name)) {
+        return (GrGLFuncPtr) glFrontFace;
+    } else if (0 == strcmp("glGenBuffers", name)) {
+        return (GrGLFuncPtr) glGenBuffers;
+    } else if (0 == strcmp("glGenerateMipmap", name)) {
+        return (GrGLFuncPtr) glGenerateMipmap;
+    } else if (0 == strcmp("glGenTextures", name)) {
+        return (GrGLFuncPtr) glGenTextures;
+    } else if (0 == strcmp("glGetBufferParameteriv", name)) {
+        return (GrGLFuncPtr) glGetBufferParameteriv;
+    } else if (0 == strcmp("glGetError", name)) {
+        return (GrGLFuncPtr) glGetError;
+    } else if (0 == strcmp("glGetIntegerv", name)) {
+        return (GrGLFuncPtr) glGetIntegerv;
+    } else if (0 == strcmp("glGetProgramInfoLog", name)) {
+        return (GrGLFuncPtr) glGetProgramInfoLog;
+    } else if (0 == strcmp("glGetProgramiv", name)) {
+        return (GrGLFuncPtr) glGetProgramiv;
+    } else if (0 == strcmp("glGetShaderInfoLog", name)) {
+        return (GrGLFuncPtr) glGetShaderInfoLog;
+    } else if (0 == strcmp("glGetShaderiv", name)) {
+        return (GrGLFuncPtr) glGetShaderiv;
+    } else if (0 == strcmp("glGetString", name)) {
+        return (GrGLFuncPtr) glGetString;
+    } else if (0 == strcmp("glGetUniformLocation", name)) {
+        return (GrGLFuncPtr) glGetUniformLocation;
+    } else if (0 == strcmp("glLineWidth", name)) {
+        return (GrGLFuncPtr) glLineWidth;
+    } else if (0 == strcmp("glLinkProgram", name)) {
+        return (GrGLFuncPtr) glLinkProgram;
+    } else if (0 == strcmp("glPixelStorei", name)) {
+        return (GrGLFuncPtr) glPixelStorei;
+    } else if (0 == strcmp("glReadPixels", name)) {
+        return (GrGLFuncPtr) glReadPixels;
+    } else if (0 == strcmp("glScissor", name)) {
+        return (GrGLFuncPtr) glScissor;
+    } else if (0 == strcmp("glShaderSource", name)) {
+        return (GrGLFuncPtr) glShaderSource;
+    } else if (0 == strcmp("glStencilFunc", name)) {
+        return (GrGLFuncPtr) glStencilFunc;
+    } else if (0 == strcmp("glStencilFuncSeparate", name)) {
+        return (GrGLFuncPtr) glStencilFuncSeparate;
+    } else if (0 == strcmp("glStencilMask", name)) {
+        return (GrGLFuncPtr) glStencilMask;
+    } else if (0 == strcmp("glStencilMaskSeparate", name)) {
+        return (GrGLFuncPtr) glStencilMaskSeparate;
+    } else if (0 == strcmp("glStencilOp", name)) {
+        return (GrGLFuncPtr) glStencilOp;
+    } else if (0 == strcmp("glStencilOpSeparate", name)) {
+        return (GrGLFuncPtr) glStencilOpSeparate;
+    } else if (0 == strcmp("glTexImage2D", name)) {
+        return (GrGLFuncPtr) glTexImage2D;
+    } else if (0 == strcmp("glTexParameteri", name)) {
+        return (GrGLFuncPtr) glTexParameteri;
+    } else if (0 == strcmp("glTexParameteriv", name)) {
+        return (GrGLFuncPtr) glTexParameteriv;
+    } else if (0 == strcmp("glTexSubImage2D", name)) {
+        return (GrGLFuncPtr) glTexSubImage2D;
+    } else if (0 == strcmp("glUniform1f", name)) {
+        return (GrGLFuncPtr) glUniform1f;
+    } else if (0 == strcmp("glUniform1i", name)) {
+        return (GrGLFuncPtr) glUniform1i;
+    } else if (0 == strcmp("glUniform1fv", name)) {
+        return (GrGLFuncPtr) glUniform1fv;
+    } else if (0 == strcmp("glUniform1iv", name)) {
+        return (GrGLFuncPtr) glUniform1iv;
+    } else if (0 == strcmp("glUniform2f", name)) {
+        return (GrGLFuncPtr) glUniform2f;
+    } else if (0 == strcmp("glUniform2i", name)) {
+        return (GrGLFuncPtr) glUniform2i;
+    } else if (0 == strcmp("glUniform2fv", name)) {
+        return (GrGLFuncPtr) glUniform2fv;
+    } else if (0 == strcmp("glUniform2iv", name)) {
+        return (GrGLFuncPtr) glUniform2iv;
+    } else if (0 == strcmp("glUniform3f", name)) {
+        return (GrGLFuncPtr) glUniform3f;
+    } else if (0 == strcmp("glUniform3i", name)) {
+        return (GrGLFuncPtr) glUniform3i;
+    } else if (0 == strcmp("glUniform3fv", name)) {
+        return (GrGLFuncPtr) glUniform3fv;
+    } else if (0 == strcmp("glUniform3iv", name)) {
+        return (GrGLFuncPtr) glUniform3iv;
+    } else if (0 == strcmp("glUniform4f", name)) {
+        return (GrGLFuncPtr) glUniform4f;
+    } else if (0 == strcmp("glUniform4i", name)) {
+        return (GrGLFuncPtr) glUniform4i;
+    } else if (0 == strcmp("glUniform4fv", name)) {
+        return (GrGLFuncPtr) glUniform4fv;
+    } else if (0 == strcmp("glUniform4iv", name)) {
+        return (GrGLFuncPtr) glUniform4iv;
+    } else if (0 == strcmp("glUniformMatrix2fv", name)) {
+        return (GrGLFuncPtr) glUniformMatrix2fv;
+    } else if (0 == strcmp("glUniformMatrix3fv", name)) {
+        return (GrGLFuncPtr) glUniformMatrix3fv;
+    } else if (0 == strcmp("glUniformMatrix4fv", name)) {
+        return (GrGLFuncPtr) glUniformMatrix4fv;
+    } else if (0 == strcmp("glUseProgram", name)) {
+        return (GrGLFuncPtr) glUseProgram;
+    } else if (0 == strcmp("glVertexAttrib4fv", name)) {
+        return (GrGLFuncPtr) glVertexAttrib4fv;
+    } else if (0 == strcmp("glVertexAttribPointer", name)) {
+        return (GrGLFuncPtr) glVertexAttribPointer;
+    } else if (0 == strcmp("glViewport", name)) {
+        return (GrGLFuncPtr) glViewport;
+    } else if (0 == strcmp("glBindFramebuffer", name)) {
+        return (GrGLFuncPtr) glBindFramebuffer;
+    } else if (0 == strcmp("glBindRenderbuffer", name)) {
+        return (GrGLFuncPtr) glBindRenderbuffer;
+    } else if (0 == strcmp("glCheckFramebufferStatus", name)) {
+        return (GrGLFuncPtr) glCheckFramebufferStatus;
+    } else if (0 == strcmp("glDeleteFramebuffers", name)) {
+        return (GrGLFuncPtr) glDeleteFramebuffers;
+    } else if (0 == strcmp("glDeleteRenderbuffers", name)) {
+        return (GrGLFuncPtr) glDeleteRenderbuffers;
+    } else if (0 == strcmp("glFramebufferRenderbuffer", name)) {
+        return (GrGLFuncPtr) glFramebufferRenderbuffer;
+    } else if (0 == strcmp("glFramebufferTexture2D", name)) {
+        return (GrGLFuncPtr) glFramebufferTexture2D;
+    } else if (0 == strcmp("glGenFramebuffers", name)) {
+        return (GrGLFuncPtr) glGenFramebuffers;
+    } else if (0 == strcmp("glGenRenderbuffers", name)) {
+        return (GrGLFuncPtr) glGenRenderbuffers;
+    } else if (0 == strcmp("glGetFramebufferAttachmentParameteriv", name)) {
+        return (GrGLFuncPtr) glGetFramebufferAttachmentParameteriv;
+    } else if (0 == strcmp("glGetRenderbufferParameteriv", name)) {
+        return (GrGLFuncPtr) glGetRenderbufferParameteriv;
+    } else if (0 == strcmp("glRenderbufferStorage", name)) {
+        return (GrGLFuncPtr) glRenderbufferStorage;
+    }
     return eglGetProcAddress(name);
 }
 
-static const GrGLInterface* create_desktop_interface() {
-    return GrGLAssembleGLInterface(NULL, android_get_gl_proc);
-}
-
 const GrGLInterface* GrGLCreateNativeInterface() {
-
-    const char* verStr = reinterpret_cast<const char*>(glGetString(GR_GL_VERSION));
-    GrGLStandard standard = GrGLGetStandardInUseFromString(verStr);
-
-    if (kGLES_GrGLStandard == standard) {
-        GrGLVersion version = GrGLGetVersionFromString(verStr);
-        GrGLExtensions extensions;
-        GrGLGetStringiProc getStringi = (GrGLGetStringiProc) eglGetProcAddress("glGetStringi");
-        if (!extensions.init(standard, glGetString, getStringi, glGetIntegerv)) {
-            return NULL;
-        }
-        GrGLInterface* interface = create_es_interface(version, &extensions);
-
-        if (NULL != interface) {
-            interface->fExtensions.swap(&extensions);
-        }
-
-        return interface;
-    } else if (kGL_GrGLStandard == standard) {
-        return create_desktop_interface();
-    }
-
-    return NULL;
+    return GrGLAssembleInterface(NULL, android_get_gl_proc);
 }
diff --git a/src/gpu/gl/android/SkNativeGLContext_android.cpp b/src/gpu/gl/android/SkNativeGLContext_android.cpp
index 462109a..d4d7219 100644
--- a/src/gpu/gl/android/SkNativeGLContext_android.cpp
+++ b/src/gpu/gl/android/SkNativeGLContext_android.cpp
@@ -15,7 +15,7 @@
 }
 
 SkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
-    if (NULL != fOldDisplay) {
+    if (fOldDisplay) {
         eglMakeCurrent(fOldDisplay, fOldSurface, fOldSurface, fOldEGLContext);
     }
 }
@@ -51,7 +51,7 @@
     }
 }
 
-const GrGLInterface* SkNativeGLContext::createGLContext() {
+const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
     static const EGLint kEGLContextAttribsForOpenGL[] = {
         EGL_NONE
     };
@@ -81,9 +81,18 @@
         },
     };
 
+    size_t apiLimit = SK_ARRAY_COUNT(kAPIs);
+    size_t api = 0;
+    if (forcedGpuAPI == kGL_GrGLStandard) {
+        apiLimit = 1;
+    } else if (forcedGpuAPI == kGLES_GrGLStandard) {
+        api = 1;
+    }
+    SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kAPIs[api].fStandard == forcedGpuAPI);
+
     const GrGLInterface* interface = NULL;
 
-    for (size_t api = 0; NULL == interface && api < SK_ARRAY_COUNT(kAPIs); ++api) {
+    for (; NULL == interface && api < apiLimit; ++api) {
         fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
 
         EGLint majorVersion;
diff --git a/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp b/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp
index 6552f7c..e4f5467 100644
--- a/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp
+++ b/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp
@@ -8,17 +8,19 @@
 
 
 #include "gl/GrGLInterface.h"
+#include "gl/GrGLAssembleInterface.h"
 
-#ifndef GL_GLEXT_PROTOTYPES
-#define GL_GLEXT_PROTOTYPES
-#endif
-
-#include "GLES2/gl2.h"
-#include "GLES2/gl2ext.h"
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
 #include "EGL/egl.h"
 
-#define GET_PROC(name)             \
-    interface->fFunctions.f ## name = (GrGL ## name ## Proc) GetProcAddress(ghANGLELib, "gl" #name);
+static GrGLFuncPtr angle_get_gl_proc(void* ctx, const char name[]) {
+    GrGLFuncPtr proc = (GrGLFuncPtr) GetProcAddress((HMODULE)ctx, name);
+    if (proc) {
+        return proc;
+    }
+    return eglGetProcAddress(name);
+}
 
 const GrGLInterface* GrGLCreateANGLEInterface() {
 
@@ -33,155 +35,5 @@
         return NULL;
     }
 
-    GrGLInterface* interface = SkNEW(GrGLInterface);
-    interface->fStandard = kGLES_GrGLStandard;
-
-    GrGLInterface::Functions* functions = &interface->fFunctions;
-
-    GET_PROC(ActiveTexture);
-    GET_PROC(AttachShader);
-    GET_PROC(BindAttribLocation);
-    GET_PROC(BindBuffer);
-    GET_PROC(BindTexture);
-    functions->fBindVertexArray =
-        (GrGLBindVertexArrayProc) eglGetProcAddress("glBindVertexArrayOES");
-    GET_PROC(BlendColor);
-    GET_PROC(BlendFunc);
-    GET_PROC(BufferData);
-    GET_PROC(BufferSubData);
-    GET_PROC(Clear);
-    GET_PROC(ClearColor);
-    GET_PROC(ClearStencil);
-    GET_PROC(ColorMask);
-    GET_PROC(CompileShader);
-    GET_PROC(CompressedTexImage2D);
-    GET_PROC(CompressedTexSubImage2D);
-    GET_PROC(CopyTexSubImage2D);
-    GET_PROC(CreateProgram);
-    GET_PROC(CreateShader);
-    GET_PROC(CullFace);
-    GET_PROC(DeleteBuffers);
-    GET_PROC(DeleteProgram);
-    GET_PROC(DeleteShader);
-    GET_PROC(DeleteTextures);
-    functions->fDeleteVertexArrays =
-        (GrGLDeleteVertexArraysProc) eglGetProcAddress("glDeleteVertexArraysOES");
-    GET_PROC(DepthMask);
-    GET_PROC(Disable);
-    GET_PROC(DisableVertexAttribArray);
-    GET_PROC(DrawArrays);
-    GET_PROC(DrawElements);
-    GET_PROC(Enable);
-    GET_PROC(EnableVertexAttribArray);
-    GET_PROC(Finish);
-    GET_PROC(Flush);
-    GET_PROC(FrontFace);
-    GET_PROC(GenBuffers);
-    GET_PROC(GenerateMipmap);
-    GET_PROC(GenTextures);
-    functions->fGenVertexArrays =
-        (GrGLGenVertexArraysProc) eglGetProcAddress("glGenVertexArraysOES");
-    GET_PROC(GetBufferParameteriv);
-    GET_PROC(GetError);
-    GET_PROC(GetIntegerv);
-    GET_PROC(GetProgramInfoLog);
-    GET_PROC(GetProgramiv);
-    GET_PROC(GetShaderInfoLog);
-    GET_PROC(GetShaderiv);
-    GET_PROC(GetString);
-    GET_PROC(GetStringi);
-    GET_PROC(GetUniformLocation);
-    GET_PROC(LineWidth);
-    GET_PROC(LinkProgram);
-    GET_PROC(PixelStorei);
-    GET_PROC(ReadPixels);
-    GET_PROC(Scissor);
-    GET_PROC(ShaderSource);
-    GET_PROC(StencilFunc);
-    GET_PROC(StencilFuncSeparate);
-    GET_PROC(StencilMask);
-    GET_PROC(StencilMaskSeparate);
-    GET_PROC(StencilOp);
-    GET_PROC(StencilOpSeparate);
-    GET_PROC(TexImage2D);
-    GET_PROC(TexParameteri);
-    GET_PROC(TexParameteriv);
-    GET_PROC(TexSubImage2D);
-#if GL_ARB_texture_storage
-    GET_PROC(TexStorage2D);
-#elif GL_EXT_texture_storage
-    functions->fTexStorage2D = (GrGLTexStorage2DProc) eglGetProcAddress("glTexStorage2DEXT");
-#endif
-    GET_PROC(Uniform1f);
-    GET_PROC(Uniform1i);
-    GET_PROC(Uniform1fv);
-    GET_PROC(Uniform1iv);
-
-    GET_PROC(Uniform2f);
-    GET_PROC(Uniform2i);
-    GET_PROC(Uniform2fv);
-    GET_PROC(Uniform2iv);
-
-    GET_PROC(Uniform3f);
-    GET_PROC(Uniform3i);
-    GET_PROC(Uniform3fv);
-    GET_PROC(Uniform3iv);
-
-    GET_PROC(Uniform4f);
-    GET_PROC(Uniform4i);
-    GET_PROC(Uniform4fv);
-    GET_PROC(Uniform4iv);
-
-    GET_PROC(UniformMatrix2fv);
-    GET_PROC(UniformMatrix3fv);
-    GET_PROC(UniformMatrix4fv);
-    GET_PROC(UseProgram);
-    GET_PROC(VertexAttrib4fv);
-    GET_PROC(VertexAttribPointer);
-    GET_PROC(Viewport);
-    GET_PROC(BindFramebuffer);
-    GET_PROC(BindRenderbuffer);
-    GET_PROC(CheckFramebufferStatus);
-    GET_PROC(DeleteFramebuffers);
-    GET_PROC(DeleteRenderbuffers);
-    GET_PROC(FramebufferRenderbuffer);
-    GET_PROC(FramebufferTexture2D);
-    GET_PROC(GenFramebuffers);
-    GET_PROC(GenRenderbuffers);
-    GET_PROC(GetFramebufferAttachmentParameteriv);
-    GET_PROC(GetRenderbufferParameteriv);
-    GET_PROC(RenderbufferStorage);
-
-    functions->fMapBuffer = (GrGLMapBufferProc) eglGetProcAddress("glMapBufferOES");
-    functions->fUnmapBuffer = (GrGLUnmapBufferProc) eglGetProcAddress("glUnmapBufferOES");
-
-#if GL_ES_VERSION_3_0
-    functions->fMapBufferRange = GET_PROC(glMapBufferRange);
-    functions->fFlushMappedBufferRange = GET_PROC(glFlushMappedBufferRange);
-#else
-    functions->fMapBufferRange = (GrGLMapBufferRangeProc) eglGetProcAddress("glMapBufferRange");
-    functions->fFlushMappedBufferRange = (GrGLFlushMappedBufferRangeProc) eglGetProcAddress("glFlushMappedBufferRange");
-#endif
-
-    functions->fInsertEventMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glInsertEventMarkerEXT");
-    functions->fPushGroupMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glPushGroupMarkerEXT");
-    functions->fPopGroupMarker = (GrGLPopGroupMarkerProc) eglGetProcAddress("glPopGroupMarkerEXT");
-
-#if GL_ES_VERSION_3_0
-    GET_PROC(InvalidateFramebuffer);
-    GET_PROC(InvalidateSubFramebuffer);
-#else
-    functions->fInvalidateFramebuffer = (GrGLInvalidateFramebufferProc) eglGetProcAddress("glInvalidateFramebuffer");
-    functions->fInvalidateSubFramebuffer = (GrGLInvalidateSubFramebufferProc) eglGetProcAddress("glInvalidateSubFramebuffer");
-#endif
-    functions->fInvalidateBufferData = (GrGLInvalidateBufferDataProc) eglGetProcAddress("glInvalidateBufferData");
-    functions->fInvalidateBufferSubData = (GrGLInvalidateBufferSubDataProc) eglGetProcAddress("glInvalidateBufferSubData");
-    functions->fInvalidateTexImage = (GrGLInvalidateTexImageProc) eglGetProcAddress("glInvalidateTexImage");
-    functions->fInvalidateTexSubImage = (GrGLInvalidateTexSubImageProc) eglGetProcAddress("glInvalidateTexSubImage");
-
-    interface->fExtensions.init(kGLES_GrGLStandard,
-                                functions->fGetString,
-                                functions->fGetStringi,
-                                functions->fGetIntegerv);
-    return interface;
+    return GrGLAssembleGLESInterface(ghANGLELib, angle_get_gl_proc);
 }
diff --git a/src/gpu/gl/angle/SkANGLEGLContext.cpp b/src/gpu/gl/angle/SkANGLEGLContext.cpp
index 2600ec4..81fcceb 100644
--- a/src/gpu/gl/angle/SkANGLEGLContext.cpp
+++ b/src/gpu/gl/angle/SkANGLEGLContext.cpp
@@ -16,7 +16,7 @@
 }
 
 SkANGLEGLContext::AutoContextRestore::~AutoContextRestore() {
-    if (NULL != fOldDisplay) {
+    if (fOldDisplay) {
         eglMakeCurrent(fOldDisplay, fOldSurface, fOldSurface, fOldEGLContext);
     }
 }
@@ -52,7 +52,10 @@
     }
 }
 
-const GrGLInterface* SkANGLEGLContext::createGLContext() {
+const GrGLInterface* SkANGLEGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
+    if (kGL_GrGLStandard == forcedGpuAPI) {
+        return NULL;
+    }
 
     fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
 
diff --git a/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp
new file mode 100644
index 0000000..2c70a75
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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 "GrGLFragmentOnlyProgramBuilder.h"
+#include "../GrGpuGL.h"
+
+GrGLFragmentOnlyProgramBuilder::GrGLFragmentOnlyProgramBuilder(GrGpuGL* gpu,
+                                                               const GrGLProgramDesc& desc)
+    : INHERITED(gpu, desc) {
+    SkASSERT(desc.getHeader().fUseFragShaderOnly);
+    SkASSERT(gpu->glCaps().pathRenderingSupport());
+    SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
+    SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
+}
+
+int GrGLFragmentOnlyProgramBuilder::addTexCoordSets(int count) {
+    int firstFreeCoordSet = fTexCoordSetCnt;
+    fTexCoordSetCnt += count;
+    SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fTexCoordSetCnt);
+    return firstFreeCoordSet;
+}
+
+void
+GrGLFragmentOnlyProgramBuilder::createAndEmitEffects(const GrGeometryStage* geometryProcessor,
+                                                     const GrFragmentStage* colorStages[],
+                                                     const GrFragmentStage* coverageStages[],
+                                                     GrGLSLExpr4* inputColor,
+                                                     GrGLSLExpr4* inputCoverage) {
+    ///////////////////////////////////////////////////////////////////////////
+    // emit the per-effect code for both color and coverage effects
+
+    EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_EffectType);
+    fColorEffects.reset(this->onCreateAndEmitEffects(colorStages,
+                                                     this->desc().numColorEffects(),
+                                                     colorKeyProvider,
+                                                     inputColor));
+
+    EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCoverage_EffectType);
+    fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages,
+                                                        this->desc().numCoverageEffects(),
+                                                        coverageKeyProvider,
+                                                        inputCoverage));
+}
+
+GrGLProgramEffects* GrGLFragmentOnlyProgramBuilder::onCreateAndEmitEffects(
+        const GrFragmentStage* effectStages[], int effectCnt,
+        const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* inOutFSColor) {
+    fProgramEffects.reset(SkNEW_ARGS(GrGLPathTexGenProgramEffects, (effectCnt)));
+    this->INHERITED::createAndEmitEffects(effectStages,
+                                          effectCnt,
+                                          keyProvider,
+                                          inOutFSColor);
+    return fProgramEffects.detach();
+}
+
+void GrGLFragmentOnlyProgramBuilder::emitEffect(const GrProcessorStage& stage,
+                                                const GrProcessorKey& key,
+                                                const char* outColor,
+                                                const char* inColor,
+                                                int stageIndex) {
+    SkASSERT(fProgramEffects.get());
+    const GrProcessor& effect = *stage.getProcessor();
+
+    SkSTArray<2, GrGLProcessor::TransformedCoords> coords(effect.numTransforms());
+    SkSTArray<4, GrGLProcessor::TextureSampler> samplers(effect.numTextures());
+
+    this->setupPathTexGen(stage, &coords);
+    this->emitSamplers(effect, &samplers);
+
+    SkASSERT(fEffectEmitter);
+    GrGLProcessor* glEffect = fEffectEmitter->createGLInstance();
+    fProgramEffects->addEffect(glEffect);
+
+    GrGLFragmentShaderBuilder* fsBuilder = this->getFragmentShaderBuilder();
+    // Enclose custom code in a block to avoid namespace conflicts
+    SkString openBrace;
+    openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
+    fsBuilder->codeAppend(openBrace.c_str());
+
+    fEffectEmitter->emit(key, outColor, inColor, coords, samplers);
+
+    fsBuilder->codeAppend("\t}\n");
+}
+
+void GrGLFragmentOnlyProgramBuilder::setupPathTexGen(
+        const GrProcessorStage& effectStage, GrGLProcessor::TransformedCoordsArray* outCoords) {
+    int numTransforms = effectStage.getProcessor()->numTransforms();
+    int texCoordIndex = this->addTexCoordSets(numTransforms);
+
+    fProgramEffects->addTransforms(texCoordIndex);
+
+    SkString name;
+    for (int t = 0; t < numTransforms; ++t) {
+        GrSLType type =
+                effectStage.isPerspectiveCoordTransform(t, false) ?
+                        kVec3f_GrSLType :
+                        kVec2f_GrSLType;
+
+        name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++);
+        SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, (name, type));
+    }
+}
diff --git a/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h b/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h
new file mode 100644
index 0000000..b1fb88d
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLFragmentOnlyProgramBuilder_DEFINED
+#define GrGLFragmentOnlyProgramBuilder_DEFINED
+
+#include "GrGLProgramBuilder.h"
+
+class GrGLFragmentOnlyProgramBuilder : public GrGLProgramBuilder {
+public:
+    GrGLFragmentOnlyProgramBuilder(GrGpuGL*, const GrGLProgramDesc&);
+
+    int addTexCoordSets(int count);
+
+private:
+    virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor,
+                                      const GrFragmentStage* colorStages[],
+                                      const GrFragmentStage* coverageStages[],
+                                      GrGLSLExpr4* inputColor,
+                                      GrGLSLExpr4* inputCoverage) SK_OVERRIDE;
+
+    GrGLProgramEffects* onCreateAndEmitEffects(const GrFragmentStage* effectStages[],
+                                               int effectCnt,
+                                               const GrGLProgramDesc::EffectKeyProvider&,
+                                                   GrGLSLExpr4* inOutFSColor);
+
+    virtual void emitEffect(const GrProcessorStage& stage,
+                            const GrProcessorKey& key,
+                            const char* outColor,
+                            const char* inColor,
+                            int stageIndex) SK_OVERRIDE;
+
+    /**
+     * Helper for emitEffect(). Allocates texture units from the builder for each transform in an
+     * effect. The transforms all use adjacent texture units. They either use two or three of the
+     * coordinates at a given texture unit, depending on if they need perspective interpolation.
+     * The expressions to access the transformed coords (i.e. 'vec2(gl_TexCoord[0])') as well as the
+     * types are appended to the TransformedCoordsArray* object, which is in turn passed to the
+     * effect's emitCode() function.
+     */
+    void setupPathTexGen(const GrProcessorStage&, GrGLProcessor::TransformedCoordsArray*);
+
+    virtual GrGLProgramEffects* getProgramEffects() SK_OVERRIDE { return fProgramEffects.get(); }
+
+    typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider;
+
+    SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects;
+
+    typedef GrGLProgramBuilder INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
new file mode 100644
index 0000000..4266d9f
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -0,0 +1,368 @@
+/*
+ * 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 "GrGLFragmentShaderBuilder.h"
+#include "GrGLShaderStringBuilder.h"
+#include "GrGLProgramBuilder.h"
+#include "../GrGpuGL.h"
+
+namespace {
+#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
+// ES2 FS only guarantees mediump and lowp support
+static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
+static const char kDstCopyColorName[] = "_dstColor";
+inline const char* declared_color_output_name() { return "fsColorOut"; }
+inline const char* dual_source_output_name() { return "dualSourceOut"; }
+inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
+                                               GrGLStandard standard,
+                                               SkString* str) {
+    // Desktop GLSL has added precision qualifiers but they don't do anything.
+    if (kGLES_GrGLStandard == standard) {
+        switch (p) {
+            case GrGLShaderVar::kHigh_Precision:
+                str->append("precision highp float;\n");
+                break;
+            case GrGLShaderVar::kMedium_Precision:
+                str->append("precision mediump float;\n");
+                break;
+            case GrGLShaderVar::kLow_Precision:
+                str->append("precision lowp float;\n");
+                break;
+            case GrGLShaderVar::kDefault_Precision:
+                SkFAIL("Default precision now allowed.");
+            default:
+                SkFAIL("Unknown precision value.");
+        }
+    }
+}
+}
+
+GrGLFragmentShaderBuilder::DstReadKey GrGLFragmentShaderBuilder::KeyForDstRead(
+        const GrTexture* dstCopy, const GrGLCaps& caps) {
+    uint32_t key = kYesDstRead_DstReadKeyBit;
+    if (caps.fbFetchSupport()) {
+        return key;
+    }
+    SkASSERT(dstCopy);
+    if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->config())) {
+        // The fact that the config is alpha-only must be considered when generating code.
+        key |= kUseAlphaConfig_DstReadKeyBit;
+    }
+    if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) {
+        key |= kTopLeftOrigin_DstReadKeyBit;
+    }
+    SkASSERT(static_cast<DstReadKey>(key) == key);
+    return static_cast<DstReadKey>(key);
+}
+
+GrGLFragmentShaderBuilder::FragPosKey GrGLFragmentShaderBuilder::KeyForFragmentPosition(
+        const GrRenderTarget* dst, const GrGLCaps&) {
+    if (kTopLeft_GrSurfaceOrigin == dst->origin()) {
+        return kTopLeftFragPosRead_FragPosKey;
+    } else {
+        return kBottomLeftFragPosRead_FragPosKey;
+    }
+}
+
+GrGLFragmentShaderBuilder::GrGLFragmentShaderBuilder(GrGLProgramBuilder* program,
+                                                     const GrGLProgramDesc& desc)
+    : INHERITED(program)
+    , fHasCustomColorOutput(false)
+    , fHasSecondaryOutput(false)
+    , fSetupFragPosition(false)
+    , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey){
+}
+
+const char* GrGLFragmentShaderBuilder::dstColor() {
+    if (fProgramBuilder->fCodeStage.inStageCode()) {
+        const GrProcessor* effect = fProgramBuilder->fCodeStage.effectStage()->getProcessor();
+        // TODO GPs can't read dst color, and full program builder only returns a pointer to the
+        // base fragment shader builder which does not have this function.  Unfortunately,
+        // the code stage class only has a GrProcessor pointer so this is required for the time
+        // being
+        if (!static_cast<const GrFragmentProcessor*>(effect)->willReadDstColor()) {
+            SkDEBUGFAIL("GrGLProcessor asked for dst color but its generating GrProcessor "
+                        "did not request access.");
+            return "";
+        }
+    }
+
+    GrGpuGL* gpu = fProgramBuilder->gpu();
+    if (gpu->glCaps().fbFetchSupport()) {
+        this->addFeature(1 << (GrGLFragmentShaderBuilder::kLastGLSLPrivateFeature + 1),
+                         gpu->glCaps().fbFetchExtensionString());
+        return gpu->glCaps().fbFetchColorName();
+    } else if (fProgramBuilder->fUniformHandles.fDstCopySamplerUni.isValid()) {
+        return kDstCopyColorName;
+    } else {
+        return "";
+    }
+}
+
+bool GrGLFragmentShaderBuilder::enableFeature(GLSLFeature feature) {
+    switch (feature) {
+        case kStandardDerivatives_GLSLFeature: {
+            GrGpuGL* gpu = fProgramBuilder->gpu();
+            if (!gpu->glCaps().shaderDerivativeSupport()) {
+                return false;
+            }
+            if (kGLES_GrGLStandard == gpu->glStandard()) {
+                this->addFeature(1 << kStandardDerivatives_GLSLFeature,
+                                 "GL_OES_standard_derivatives");
+            }
+            return true;
+        }
+        default:
+            SkFAIL("Unexpected GLSLFeature requested.");
+            return false;
+    }
+}
+
+SkString GrGLFragmentShaderBuilder::ensureFSCoords2D(
+        const GrGLProcessor::TransformedCoordsArray& coords, int index) {
+    if (kVec3f_GrSLType != coords[index].getType()) {
+        SkASSERT(kVec2f_GrSLType == coords[index].getType());
+        return coords[index].getName();
+    }
+
+    SkString coords2D("coords2D");
+    if (0 != index) {
+        coords2D.appendf("_%i", index);
+    }
+    this->codeAppendf("\tvec2 %s = %s.xy / %s.z;",
+                      coords2D.c_str(), coords[index].c_str(), coords[index].c_str());
+    return coords2D;
+}
+
+const char* GrGLFragmentShaderBuilder::fragmentPosition() {
+    GrGLProgramBuilder::CodeStage* cs = &fProgramBuilder->fCodeStage;
+    if (cs->inStageCode()) {
+        const GrProcessor* effect = cs->effectStage()->getProcessor();
+        if (!effect->willReadFragmentPosition()) {
+            SkDEBUGFAIL("GrGLProcessor asked for frag position but its generating GrProcessor "
+                        "did not request access.");
+            return "";
+        }
+    }
+
+    GrGpuGL* gpu = fProgramBuilder->gpu();
+    // We only declare "gl_FragCoord" when we're in the case where we want to use layout qualifiers
+    // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the
+    // declaration varies in earlier GLSL specs. So it is simpler to omit it.
+    if (fTopLeftFragPosRead) {
+        fSetupFragPosition = true;
+        return "gl_FragCoord";
+    } else if (gpu->glCaps().fragCoordConventionsSupport()) {
+        if (!fSetupFragPosition) {
+            if (gpu->glslGeneration() < k150_GrGLSLGeneration) {
+                this->addFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
+                                 "GL_ARB_fragment_coord_conventions");
+            }
+            fInputs.push_back().set(kVec4f_GrSLType,
+                                    GrGLShaderVar::kIn_TypeModifier,
+                                    "gl_FragCoord",
+                                    GrGLShaderVar::kDefault_Precision,
+                                    GrGLShaderVar::kUpperLeft_Origin);
+            fSetupFragPosition = true;
+        }
+        return "gl_FragCoord";
+    } else {
+        static const char* kCoordName = "fragCoordYDown";
+        if (!fSetupFragPosition) {
+            // temporarily change the stage index because we're inserting non-stage code.
+            GrGLProgramBuilder::CodeStage::AutoStageRestore csar(cs, NULL);
+
+            SkASSERT(!fProgramBuilder->fUniformHandles.fRTHeightUni.isValid());
+            const char* rtHeightName;
+
+            fProgramBuilder->fUniformHandles.fRTHeightUni =
+                    fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                         kFloat_GrSLType,
+                                         "RTHeight",
+                                         &rtHeightName);
+
+            // Using glFragCoord.zw for the last two components tickles an Adreno driver bug that
+            // causes programs to fail to link. Making this function return a vec2() didn't fix the
+            // problem but using 1.0 for the last two components does.
+            this->codePrependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, 1.0, "
+                               "1.0);\n", kCoordName, rtHeightName);
+            fSetupFragPosition = true;
+        }
+        SkASSERT(fProgramBuilder->fUniformHandles.fRTHeightUni.isValid());
+        return kCoordName;
+    }
+}
+
+void GrGLFragmentShaderBuilder::addVarying(GrSLType type,
+               const char* name,
+               const char** fsInName,
+               GrGLShaderVar::Precision fsPrecision) {
+    fInputs.push_back().set(type, GrGLShaderVar::kVaryingIn_TypeModifier, name, fsPrecision);
+    if (fsInName) {
+        *fsInName = name;
+    }
+}
+
+void GrGLFragmentShaderBuilder::bindProgramLocations(GrGLuint programId) {
+    GrGpuGL* gpu = fProgramBuilder->gpu();
+    if (fHasCustomColorOutput) {
+        GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name()));
+    }
+    if (fHasSecondaryOutput) {
+        GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_name()));
+    }
+}
+
+bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
+                                                        SkTDArray<GrGLuint>* shaderIds) const {
+    GrGpuGL* gpu = fProgramBuilder->gpu();
+    SkString fragShaderSrc(GrGetGLSLVersionDecl(gpu->ctxInfo()));
+    fragShaderSrc.append(fExtensions);
+    append_default_precision_qualifier(kDefaultFragmentPrecision,
+                                       gpu->glStandard(),
+                                       &fragShaderSrc);
+    fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kFragment_Visibility, &fragShaderSrc);
+    fProgramBuilder->appendDecls(fInputs, &fragShaderSrc);
+    // We shouldn't have declared outputs on 1.10
+    SkASSERT(k110_GrGLSLGeneration != gpu->glslGeneration() || fOutputs.empty());
+    fProgramBuilder->appendDecls(fOutputs, &fragShaderSrc);
+    fragShaderSrc.append(fFunctions);
+    fragShaderSrc.append("void main() {\n");
+    fragShaderSrc.append(fCode);
+    fragShaderSrc.append("}\n");
+
+    GrGLuint fragShaderId = GrGLCompileAndAttachShader(gpu->glContext(), programId,
+                                                       GR_GL_FRAGMENT_SHADER, fragShaderSrc,
+                                                       gpu->gpuStats());
+    if (!fragShaderId) {
+        return false;
+    }
+
+    *shaderIds->append() = fragShaderId;
+
+    return true;
+}
+
+void GrGLFragmentShaderBuilder::emitCodeBeforeEffects() {
+    const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
+    GrGpuGL* gpu = fProgramBuilder->gpu();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // emit code to read the dst copy texture, if necessary
+    if (kNoDstRead_DstReadKey != header.fDstReadKey && !gpu->glCaps().fbFetchSupport()) {
+        bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey);
+        const char* dstCopyTopLeftName;
+        const char* dstCopyCoordScaleName;
+        const char* dstCopySamplerName;
+        uint32_t configMask;
+        if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) {
+            configMask = kA_GrColorComponentFlag;
+        } else {
+            configMask = kRGBA_GrColorComponentFlags;
+        }
+        fProgramBuilder->fUniformHandles.fDstCopySamplerUni =
+            fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                 kSampler2D_GrSLType,
+                                 "DstCopySampler",
+                                 &dstCopySamplerName);
+        fProgramBuilder->fUniformHandles.fDstCopyTopLeftUni =
+            fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                 kVec2f_GrSLType,
+                                 "DstCopyUpperLeft",
+                                 &dstCopyTopLeftName);
+        fProgramBuilder->fUniformHandles.fDstCopyScaleUni =
+            fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                 kVec2f_GrSLType,
+                                 "DstCopyCoordScale",
+                                 &dstCopyCoordScaleName);
+        const char* fragPos = fragmentPosition();
+
+        this->codeAppend("// Read color from copy of the destination.\n");
+        this->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
+                          fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
+        if (!topDown) {
+            this->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
+        }
+        this->codeAppendf("vec4 %s = ", kDstCopyColorName);
+        this->appendTextureLookup(dstCopySamplerName,
+                                  "_dstTexCoord",
+                                  configMask,
+                                  "rgba");
+        this->codeAppend(";");
+    }
+
+    if (k110_GrGLSLGeneration != gpu->glslGeneration()) {
+        fOutputs.push_back().set(kVec4f_GrSLType,
+                                 GrGLShaderVar::kOut_TypeModifier,
+                                 declared_color_output_name());
+        fHasCustomColorOutput = true;
+    }
+}
+
+void GrGLFragmentShaderBuilder::emitCodeAfterEffects(const GrGLSLExpr4& inputColor, const GrGLSLExpr4& inputCoverage) {
+    const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // write the secondary color output if necessary
+    if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
+        const char* secondaryOutputName = this->enableSecondaryOutput();
+        GrGLSLExpr4 coeff(1);
+        switch (header.fSecondaryOutputType) {
+            case GrOptDrawState::kCoverage_SecondaryOutputType:
+                break;
+            case GrOptDrawState::kCoverageISA_SecondaryOutputType:
+                // Get (1-A) into coeff
+                coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
+                break;
+            case GrOptDrawState::kCoverageISC_SecondaryOutputType:
+                // Get (1-RGBA) into coeff
+                coeff = GrGLSLExpr4(1) - inputColor;
+                break;
+            default:
+                SkFAIL("Unexpected Secondary Output");
+        }
+        // Get coeff * coverage into modulate and then write that to the dual source output.
+        codeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // combine color and coverage as frag color
+
+    // Get "color * coverage" into fragColor
+    GrGLSLExpr4 fragColor = inputColor * inputCoverage;
+    switch (header.fPrimaryOutputType) {
+        case GrOptDrawState::kModulate_PrimaryOutputType:
+            break;
+        case GrOptDrawState::kCombineWithDst_PrimaryOutputType:
+            {
+                // Tack on "+(1-coverage)dst onto the frag color.
+                GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
+                GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(dstColor());
+                fragColor = fragColor + dstContribution;
+            }
+            break;
+        default:
+            SkFAIL("Unknown Primary Output");
+    }
+    codeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str());
+}
+
+const char* GrGLFragmentShaderBuilder::enableSecondaryOutput() {
+    if (!fHasSecondaryOutput) {
+        fOutputs.push_back().set(kVec4f_GrSLType,
+                                 GrGLShaderVar::kOut_TypeModifier,
+                                 dual_source_output_name());
+        fHasSecondaryOutput = true;
+    }
+    return dual_source_output_name();
+}
+
+const char* GrGLFragmentShaderBuilder::getColorOutputName() const {
+    return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor";
+}
+
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
new file mode 100644
index 0000000..38d569e
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLFragmentShaderBuilder_DEFINED
+#define GrGLFragmentShaderBuilder_DEFINED
+#include "GrGLShaderBuilder.h"
+
+class GrGLProgramBuilder;
+
+/*
+ * This base class encapsulates the functionality which all GrProcessors are allowed to use in their
+ * fragment shader
+ */
+class GrGLProcessorFragmentShaderBuilder : public GrGLShaderBuilder {
+public:
+    GrGLProcessorFragmentShaderBuilder(GrGLProgramBuilder* program) : INHERITED(program) {}
+    virtual ~GrGLProcessorFragmentShaderBuilder() {}
+    /**
+     * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
+     * if code is added that uses one of these features without calling enableFeature()
+     */
+    enum GLSLFeature {
+        kStandardDerivatives_GLSLFeature = 0,
+        kLastGLSLFeature = kStandardDerivatives_GLSLFeature
+    };
+
+    /**
+     * If the feature is supported then true is returned and any necessary #extension declarations
+     * are added to the shaders. If the feature is not supported then false will be returned.
+     */
+    virtual bool enableFeature(GLSLFeature) = 0;
+
+    /**
+     * This returns a variable name to access the 2D, perspective correct version of the coords in
+     * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
+     * perspective divide into the fragment shader (xy / z) to convert them to 2D.
+     */
+    virtual SkString ensureFSCoords2D(const GrGLProcessor::TransformedCoordsArray& coords,
+                                      int index) = 0;
+
+
+    /** Returns a variable name that represents the position of the fragment in the FS. The position
+        is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
+    virtual const char* fragmentPosition() = 0;
+
+private:
+    typedef GrGLShaderBuilder INHERITED;
+};
+
+/*
+ * Fragment processor's, in addition to all of the above, may need to use dst color so they use
+ * this builder to create their shader
+ */
+class GrGLFragmentProcessorShaderBuilder : public GrGLProcessorFragmentShaderBuilder {
+public:
+    GrGLFragmentProcessorShaderBuilder(GrGLProgramBuilder* program) : INHERITED(program) {}
+    /** Returns the variable name that holds the color of the destination pixel. This may be NULL if
+        no effect advertised that it will read the destination. */
+    virtual const char* dstColor() = 0;
+
+private:
+    typedef GrGLProcessorFragmentShaderBuilder INHERITED;
+};
+
+class GrGLFragmentShaderBuilder : public GrGLFragmentProcessorShaderBuilder {
+public:
+    typedef uint8_t DstReadKey;
+    typedef uint8_t FragPosKey;
+
+    /**  Returns a key for adding code to read the copy-of-dst color in service of effects that
+        require reading the dst. It must not return 0 because 0 indicates that there is no dst
+        copy read at all (in which case this function should not be called). */
+    static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
+
+    /** Returns a key for reading the fragment location. This should only be called if there is an
+       effect that will requires the fragment position. If the fragment position is not required,
+       the key is 0. */
+    static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
+
+    GrGLFragmentShaderBuilder(GrGLProgramBuilder* program, const GrGLProgramDesc& desc);
+
+    virtual const char* dstColor() SK_OVERRIDE;
+
+    virtual bool enableFeature(GLSLFeature) SK_OVERRIDE;
+
+    virtual SkString ensureFSCoords2D(const GrGLProcessor::TransformedCoordsArray& coords,
+                                      int index) SK_OVERRIDE;
+
+    virtual const char* fragmentPosition() SK_OVERRIDE;
+
+private:
+    /*
+     * An internal call for GrGLFullProgramBuilder to use to add varyings to the vertex shader
+     */
+    void addVarying(GrSLType type,
+                   const char* name,
+                   const char** fsInName,
+                   GrGLShaderVar::Precision fsPrecision = GrGLShaderVar::kDefault_Precision);
+
+    /*
+     * Private functions used by GrGLProgramBuilder for compilation
+    */
+    void bindProgramLocations(GrGLuint programId);
+    bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
+    void emitCodeBeforeEffects();
+    void emitCodeAfterEffects(const GrGLSLExpr4& inputColor, const GrGLSLExpr4& inputCoverage);
+
+    /** Enables using the secondary color output and returns the name of the var in which it is
+        to be stored */
+    const char* enableSecondaryOutput();
+
+    /** Gets the name of the primary color output. */
+    const char* getColorOutputName() const;
+
+    /**
+     * Features that should only be enabled by GrGLFragmentShaderBuilder itself.
+     */
+    enum GLSLPrivateFeature {
+        kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
+        kLastGLSLPrivateFeature = kFragCoordConventions_GLSLPrivateFeature
+    };
+
+    // Interpretation of DstReadKey when generating code
+    enum {
+        kNoDstRead_DstReadKey           = 0,
+        kYesDstRead_DstReadKeyBit       = 0x1, // Set if we do a dst-copy-read.
+        kUseAlphaConfig_DstReadKeyBit   = 0x2, // Set if dst-copy config is alpha only.
+        kTopLeftOrigin_DstReadKeyBit    = 0x4, // Set if dst-copy origin is top-left.
+    };
+
+    enum {
+        kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
+        kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
+        kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
+    };
+
+    bool fHasCustomColorOutput;
+    bool fHasSecondaryOutput;
+    bool fSetupFragPosition;
+    bool fTopLeftFragPosRead;
+
+    friend class GrGLProgramBuilder;
+    friend class GrGLFullProgramBuilder;
+
+    typedef GrGLFragmentProcessorShaderBuilder INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/builders/GrGLFullProgramBuilder.cpp b/src/gpu/gl/builders/GrGLFullProgramBuilder.cpp
new file mode 100644
index 0000000..46db712
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLFullProgramBuilder.cpp
@@ -0,0 +1,221 @@
+/*
+ * 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 "GrGLFullProgramBuilder.h"
+#include "../GrGLGeometryProcessor.h"
+#include "../GrGpuGL.h"
+
+GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu,
+                                               const GrGLProgramDesc& desc)
+    : INHERITED(gpu, desc)
+    , fGLGeometryProcessorEmitter(this)
+    , fGS(this)
+    , fVS(this) {
+}
+
+void
+GrGLFullProgramBuilder::createAndEmitEffects(const GrGeometryStage* geometryProcessor,
+                                             const GrFragmentStage* colorStages[],
+                                             const GrFragmentStage* coverageStages[],
+                                             GrGLSLExpr4* inputColor,
+                                             GrGLSLExpr4* inputCoverage) {
+    fVS.emitCodeBeforeEffects(inputColor, inputCoverage);
+
+    ///////////////////////////////////////////////////////////////////////////
+    // emit the per-effect code for both color and coverage effects
+
+    EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_EffectType);
+    fColorEffects.reset(this->onCreateAndEmitEffects(colorStages,
+                                                     this->desc().numColorEffects(),
+                                                     colorKeyProvider,
+                                                     inputColor));
+
+    if (geometryProcessor) {
+        const GrGeometryProcessor& gp = *geometryProcessor->getGeometryProcessor();
+        fGLGeometryProcessorEmitter.set(&gp);
+        fEffectEmitter = &fGLGeometryProcessorEmitter;
+        fVS.emitAttributes(gp);
+        GrGLSLExpr4 gpInputCoverage = *inputCoverage;
+        GrGLSLExpr4 gpOutputCoverage;
+        EffectKeyProvider gpKeyProvider(&this->desc(),
+                EffectKeyProvider::kGeometryProcessor_EffectType);
+        bool useLocalCoords = this->getVertexShaderBuilder()->hasExplicitLocalCoords();
+        fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, (1, useLocalCoords)));
+        this->INHERITED::emitEffect(*geometryProcessor, 0, gpKeyProvider, &gpInputCoverage,
+                                    &gpOutputCoverage);
+        fGeometryProcessor.reset(fProgramEffects.detach());
+        *inputCoverage = gpOutputCoverage;
+    }
+
+    EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCoverage_EffectType);
+    fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages,
+                                                        this->desc().numCoverageEffects(),
+                                                        coverageKeyProvider,
+                                                        inputCoverage));
+
+     fVS.emitCodeAfterEffects();
+}
+
+void GrGLFullProgramBuilder::addVarying(GrSLType type,
+                                        const char* name,
+                                        const char** vsOutName,
+                                        const char** fsInName,
+                                        GrGLShaderVar::Precision fsPrecision) {
+    fVS.addVarying(type, name, vsOutName);
+
+    SkString* fsInputName = fVS.fOutputs.back().accessName();
+
+#if GR_GL_EXPERIMENTAL_GS
+    if (desc().getHeader().fExperimentalGS) {
+       // TODO let the caller use these names
+       fGS.addVarying(type, fsInputName->c_str(), NULL);
+       fsInputName = fGS.fOutputs.back().accessName();
+    }
+#endif
+    fFS.addVarying(type, fsInputName->c_str(), fsInName, fsPrecision);
+}
+
+GrGLFullProgramBuilder::VaryingHandle
+GrGLFullProgramBuilder::addSeparableVarying(GrSLType type,
+                                            const char* name,
+                                            const char** vsOutName,
+                                            const char** fsInName) {
+    addVarying(type, name, vsOutName, fsInName);
+    SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back();
+    varying.fVariable = fFS.fInputs.back();
+    return VaryingHandle::CreateFromSeparableVaryingIndex(fSeparableVaryingInfos.count() - 1);
+}
+
+GrGLProgramEffects* GrGLFullProgramBuilder::onCreateAndEmitEffects(
+        const GrFragmentStage* effectStages[],
+        int effectCnt,
+        const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+        GrGLSLExpr4* inOutFSColor) {
+    fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects,
+                                 (effectCnt,
+                                  this->getVertexShaderBuilder()->hasExplicitLocalCoords())));
+    this->INHERITED::createAndEmitEffects(effectStages,
+                                          effectCnt,
+                                          keyProvider,
+                                          inOutFSColor);
+    return fProgramEffects.detach();
+}
+
+void GrGLFullProgramBuilder::emitEffect(const GrProcessorStage& stage,
+                                        const GrProcessorKey& key,
+                                        const char* outColor,
+                                        const char* inColor,
+                                        int stageIndex) {
+    SkASSERT(fProgramEffects.get());
+    const GrProcessor& effect = *stage.getProcessor();
+    SkSTArray<2, GrGLProcessor::TransformedCoords> coords(effect.numTransforms());
+    SkSTArray<4, GrGLProcessor::TextureSampler> samplers(effect.numTextures());
+
+    this->emitTransforms(stage, &coords);
+    this->emitSamplers(effect, &samplers);
+
+    SkASSERT(fEffectEmitter);
+    GrGLProcessor* glEffect = fEffectEmitter->createGLInstance();
+    fProgramEffects->addEffect(glEffect);
+
+    // Enclose custom code in a block to avoid namespace conflicts
+    SkString openBrace;
+    openBrace.printf("{ // Stage %d: %s\n", stageIndex, glEffect->name());
+    fFS.codeAppend(openBrace.c_str());
+    fVS.codeAppend(openBrace.c_str());
+
+    fEffectEmitter->emit(key, outColor, inColor, coords, samplers);
+
+    fVS.codeAppend("\t}\n");
+    fFS.codeAppend("\t}\n");
+}
+
+void GrGLFullProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
+                                            GrGLProcessor::TransformedCoordsArray* outCoords) {
+    SkTArray<GrGLVertexProgramEffects::Transform, true>& transforms =
+            fProgramEffects->addTransforms();
+    const GrProcessor* effect = effectStage.getProcessor();
+    int numTransforms = effect->numTransforms();
+    transforms.push_back_n(numTransforms);
+
+    SkTArray<GrGLVertexProgramEffects::PathTransform, true>* pathTransforms = NULL;
+    const GrGLCaps* glCaps = this->ctxInfo().caps();
+    if (glCaps->pathRenderingSupport() &&
+        this->gpu()->glPathRendering()->texturingMode() ==
+           GrGLPathRendering::SeparableShaders_TexturingMode) {
+        pathTransforms = &fProgramEffects->addPathTransforms();
+        pathTransforms->push_back_n(numTransforms);
+    }
+
+    for (int t = 0; t < numTransforms; t++) {
+        const char* uniName = "StageMatrix";
+        GrSLType varyingType =
+                effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalCoords()) ?
+                        kVec3f_GrSLType :
+                        kVec2f_GrSLType;
+
+        SkString suffixedUniName;
+        if (0 != t) {
+            suffixedUniName.append(uniName);
+            suffixedUniName.appendf("_%i", t);
+            uniName = suffixedUniName.c_str();
+        }
+        transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+                                                 kMat33f_GrSLType,
+                                                 uniName,
+                                                 &uniName);
+
+        const char* varyingName = "MatrixCoord";
+        SkString suffixedVaryingName;
+        if (0 != t) {
+            suffixedVaryingName.append(varyingName);
+            suffixedVaryingName.appendf("_%i", t);
+            varyingName = suffixedVaryingName.c_str();
+        }
+        const char* vsVaryingName;
+        const char* fsVaryingName;
+        if (pathTransforms) {
+            (*pathTransforms)[t].fHandle =
+                this->addSeparableVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
+            (*pathTransforms)[t].fType = varyingType;
+        } else {
+            this->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
+        }
+
+        const GrGLShaderVar& coords =
+                kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
+                                          fVS.positionAttribute() :
+                                          fVS.localCoordsAttribute();
+        // varying = matrix * coords (logically)
+        SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
+        if (kVec2f_GrSLType == varyingType) {
+            fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
+                            vsVaryingName, uniName, coords.c_str());
+        } else {
+            fVS.codeAppendf("%s = %s * vec3(%s, 1);",
+                            vsVaryingName, uniName, coords.c_str());
+        }
+        SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
+                               (SkString(fsVaryingName), varyingType));
+    }
+}
+
+bool GrGLFullProgramBuilder::compileAndAttachShaders(GrGLuint programId,
+                                                     SkTDArray<GrGLuint>* shaderIds) const {
+    return INHERITED::compileAndAttachShaders(programId, shaderIds)
+         && fVS.compileAndAttachShaders(programId, shaderIds)
+#if GR_GL_EXPERIMENTAL_GS
+         && (!desc().getHeader().fExperimentalGS
+                 || fGS.compileAndAttachShaders(programId, shaderIds))
+#endif
+         ;
+}
+
+void GrGLFullProgramBuilder::bindProgramLocations(GrGLuint programId) {
+    fVS.bindProgramLocations(programId);
+    INHERITED::bindProgramLocations(programId);
+}
diff --git a/src/gpu/gl/builders/GrGLFullProgramBuilder.h b/src/gpu/gl/builders/GrGLFullProgramBuilder.h
new file mode 100644
index 0000000..41da17f
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLFullProgramBuilder.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLFullProgramBuilder_DEFINED
+#define GrGLFullProgramBuilder_DEFINED
+
+#include "GrGLProgramBuilder.h"
+#include "../GrGLGeometryProcessor.h"
+
+class GrGLVertexProgramEffects;
+
+class GrGLFullProgramBuilder : public GrGLProgramBuilder {
+public:
+    GrGLFullProgramBuilder(GrGpuGL*, const GrGLProgramDesc&);
+
+   /** Add a varying variable to the current program to pass values between vertex and fragment
+        shaders. If the last two parameters are non-NULL, they are filled in with the name
+        generated. */
+    void addVarying(GrSLType type,
+                    const char* name,
+                    const char** vsOutName = NULL,
+                    const char** fsInName = NULL,
+                    GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision);
+
+    /** Add a separable varying input variable to the current program.
+     * A separable varying (fragment shader input) is a varying that can be used also when vertex
+     * shaders are not used. With a vertex shader, the operation is same as with other
+     * varyings. Without a vertex shader, such as with NV_path_rendering, GL APIs are used to
+     * populate the variable. The APIs can refer to the variable through the returned handle.
+     */
+    VaryingHandle addSeparableVarying(GrSLType type,
+                                      const char* name,
+                                      const char** vsOutName,
+                                      const char** fsInName);
+
+    GrGLVertexShaderBuilder* getVertexShaderBuilder() { return &fVS; }
+
+    /*
+     * This non-virtual call will hide the parent call to prevent GPs from accessing fragment shader
+     * functionality they shouldn't be using
+     */
+    GrGLProcessorFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; }
+
+private:
+    virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor,
+                                      const GrFragmentStage* colorStages[],
+                                      const GrFragmentStage* coverageStages[],
+                                      GrGLSLExpr4* inputColor,
+                                      GrGLSLExpr4* inputCoverage) SK_OVERRIDE;
+
+    GrGLProgramEffects* onCreateAndEmitEffects(const GrFragmentStage* effectStages[],
+                                               int effectCnt,
+                                               const GrGLProgramDesc::EffectKeyProvider&,
+                                               GrGLSLExpr4* inOutFSColor);
+
+    class GrGLGeometryProcessorEmitter : public GrGLProgramBuilder::GrGLProcessorEmitterInterface {
+        public:
+            GrGLGeometryProcessorEmitter(GrGLFullProgramBuilder* builder)
+                : fBuilder(builder)
+                , fGeometryProcessor(NULL)
+                , fGLGeometryProcessor(NULL) {}
+            virtual ~GrGLGeometryProcessorEmitter() {}
+            void set(const GrGeometryProcessor* gp) {
+                SkASSERT(NULL == fGeometryProcessor);
+                fGeometryProcessor = gp;
+            }
+            virtual GrGLProcessor* createGLInstance() {
+                SkASSERT(fGeometryProcessor);
+                SkASSERT(NULL == fGLGeometryProcessor);
+                fGLGeometryProcessor =
+                        fGeometryProcessor->getFactory().createGLInstance(*fGeometryProcessor);
+                return fGLGeometryProcessor;
+            }
+            virtual void emit(const GrProcessorKey& key,
+                              const char* outColor,
+                              const char* inColor,
+                              const GrGLProcessor::TransformedCoordsArray& coords,
+                              const GrGLProcessor::TextureSamplerArray& samplers) {
+                SkASSERT(fGeometryProcessor);
+                SkASSERT(fGLGeometryProcessor);
+                fGLGeometryProcessor->emitCode(fBuilder, *fGeometryProcessor, key, outColor,
+                                               inColor, coords, samplers);
+                // this will not leak because it has already been used by createGLInstance
+                fGLGeometryProcessor = NULL;
+                fGeometryProcessor = NULL;
+            }
+        private:
+            GrGLFullProgramBuilder*     fBuilder;
+            const GrGeometryProcessor*  fGeometryProcessor;
+            GrGLGeometryProcessor*      fGLGeometryProcessor;
+        };
+
+    virtual void emitEffect(const GrProcessorStage& stage,
+                            const GrProcessorKey& key,
+                            const char* outColor,
+                            const char* inColor,
+                            int stageIndex) SK_OVERRIDE;
+
+    /**
+     * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
+     * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
+     * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
+     * of the varyings in the VS and FS as well their types are appended to the
+     * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
+     */
+    void emitTransforms(const GrProcessorStage& effectStage,
+                        GrGLProcessor::TransformedCoordsArray* outCoords);
+
+    virtual bool compileAndAttachShaders(GrGLuint programId,
+                                         SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE;
+
+    virtual void bindProgramLocations(GrGLuint programId) SK_OVERRIDE;
+
+    virtual GrGLProgramEffects* getProgramEffects() SK_OVERRIDE { return fProgramEffects.get(); }
+
+    typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider;
+
+    GrGLGeometryProcessorEmitter fGLGeometryProcessorEmitter;
+    GrGLGeometryShaderBuilder fGS;
+    GrGLVertexShaderBuilder   fVS;
+    SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
+
+    typedef GrGLProgramBuilder INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
new file mode 100644
index 0000000..117497b
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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 "GrGLGeometryShaderBuilder.h"
+#include "GrGLShaderStringBuilder.h"
+#include "GrGLProgramBuilder.h"
+#include "../GrGpuGL.h"
+
+GrGLGeometryShaderBuilder::GrGLGeometryShaderBuilder(GrGLFullProgramBuilder* program)
+    : INHERITED(program) {
+
+}
+
+void GrGLGeometryShaderBuilder::addVarying(GrSLType type,
+               const char* name,
+               const char** gsOutName) {
+    // if we have a GS take each varying in as an array
+    // and output as non-array.
+    fInputs.push_back();
+    fInputs.back().setType(type);
+    fInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
+    fInputs.back().setUnsizedArray();
+    *fInputs.back().accessName() = name;
+    fOutputs.push_back();
+    fOutputs.back().setType(type);
+    fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
+    fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'g', name);
+    if (gsOutName) {
+        *gsOutName = fOutputs.back().getName().c_str();
+    }
+}
+
+
+bool GrGLGeometryShaderBuilder::compileAndAttachShaders(GrGLuint programId,
+        SkTDArray<GrGLuint>* shaderIds) const {
+    const GrGLContext& glCtx = fProgramBuilder->gpu()->glContext();
+    SkASSERT(fProgramBuilder->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration);
+    SkString geomShaderSrc(GrGetGLSLVersionDecl(fProgramBuilder->ctxInfo()));
+    geomShaderSrc.append("layout(triangles) in;\n"
+                         "layout(triangle_strip, max_vertices = 6) out;\n");
+    fProgramBuilder->appendDecls(fInputs, &geomShaderSrc);
+    fProgramBuilder->appendDecls(fOutputs, &geomShaderSrc);
+    geomShaderSrc.append("void main() {\n");
+    geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n"
+                         "\t\tgl_Position = gl_in[i].gl_Position;\n");
+    if (fProgramBuilder->desc().getHeader().fEmitsPointSize) {
+        geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
+    }
+    SkASSERT(fInputs.count() == fOutputs.count());
+    for (int i = 0; i < fInputs.count(); ++i) {
+        geomShaderSrc.appendf("\t\t%s = %s[i];\n",
+                              fOutputs[i].getName().c_str(),
+                              fInputs[i].getName().c_str());
+    }
+    geomShaderSrc.append("\t\tEmitVertex();\n"
+                         "\t}\n"
+                         "\tEndPrimitive();\n");
+    geomShaderSrc.append("}\n");
+    GrGLuint geomShaderId =
+        GrGLCompileAndAttachShader(glCtx, programId,
+                                   GR_GL_GEOMETRY_SHADER, geomShaderSrc,
+                                   fProgramBuilder->gpu()->gpuStats());
+    if (!geomShaderId) {
+        return false;
+    }
+    *shaderIds->append() = geomShaderId;
+    return true;
+}
diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h
new file mode 100644
index 0000000..833d317
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLGeometryShaderBuilder_DEFINED
+#define GrGLGeometryShaderBuilder_DEFINED
+
+#include "GrGLShaderBuilder.h"
+
+class GrGLProgramBuilder;
+
+class GrGLGeometryShaderBuilder : public GrGLFullShaderBuilder {
+public:
+    GrGLGeometryShaderBuilder(GrGLFullProgramBuilder* program);
+private:
+    /*
+     * an internal call for GrGLFullProgramBuilder to add varyings
+     */
+    void addVarying(GrSLType type,
+                   const char* name,
+                   const char** gsOutName);
+
+    bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
+
+    friend class GrGLFullProgramBuilder;
+    typedef GrGLFullShaderBuilder INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
new file mode 100644
index 0000000..909ac76
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -0,0 +1,330 @@
+/*
+ * 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 "gl/GrGLProgram.h"
+#include "gl/GrGLSLPrettyPrint.h"
+#include "gl/GrGLUniformHandle.h"
+#include "GrCoordTransform.h"
+#include "../GrGpuGL.h"
+#include "GrGLFragmentShaderBuilder.h"
+#include "GrGLProgramBuilder.h"
+#include "GrTexture.h"
+#include "GrGLVertexShaderBuilder.h"
+#include "SkRTConf.h"
+#include "SkTraceEvent.h"
+
+namespace {
+#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
+
+// number of each input/output type in a single allocation block
+static const int kVarsPerBlock = 8;
+
+// ES2 FS only guarantees mediump and lowp support
+static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool GrGLProgramBuilder::genProgram(const GrGeometryStage* geometryProcessor,
+                                    const GrFragmentStage* colorStages[],
+                                    const GrFragmentStage* coverageStages[]) {
+    const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
+
+    fFS.emitCodeBeforeEffects();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the initial color and coverage to feed into the first effect in each effect chain
+
+    GrGLSLExpr4 inputColor;
+    GrGLSLExpr4 inputCoverage;
+
+    if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
+        const char* name;
+        fUniformHandles.fColorUni =
+            this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                             kVec4f_GrSLType,
+                             "Color",
+                             &name);
+        inputColor = GrGLSLExpr4(name);
+    } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fColorInput) {
+        inputColor = GrGLSLExpr4(1);
+    }
+
+    if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
+        const char* name;
+        fUniformHandles.fCoverageUni =
+            this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                             kVec4f_GrSLType,
+                             "Coverage",
+                             &name);
+        inputCoverage = GrGLSLExpr4(name);
+    } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) {
+        inputCoverage = GrGLSLExpr4(1);
+    }
+
+    // Subclasses drive effect emitting
+    this->createAndEmitEffects(geometryProcessor, colorStages, coverageStages, &inputColor,
+                               &inputCoverage);
+
+    fFS.emitCodeAfterEffects(inputColor, inputCoverage);
+
+    if (!this->finish()) {
+        return false;
+    }
+
+    return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
+                                       const GrGLProgramDesc& desc)
+    : fEffectEmitter(NULL)
+    , fFragOnly(SkToBool(desc.getHeader().fUseFragShaderOnly))
+    , fTexCoordSetCnt(0)
+    , fProgramID(0)
+    , fFS(this, desc)
+    , fSeparableVaryingInfos(kVarsPerBlock)
+    , fGrProcessorEmitter(this)
+    , fDesc(desc)
+    , fGpu(gpu)
+    , fUniforms(kVarsPerBlock) {
+}
+
+void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
+    if ('\0' == prefix) {
+        *out = name;
+    } else {
+        out->printf("%c%s", prefix, name);
+    }
+    if (fCodeStage.inStageCode()) {
+        if (out->endsWith('_')) {
+            // Names containing "__" are reserved.
+            out->append("x");
+        }
+        out->appendf("_Stage%d", fCodeStage.stageIndex());
+    }
+}
+
+GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32_t visibility,
+                                                                          GrSLType type,
+                                                                          const char* name,
+                                                                          int count,
+                                                                          const char** outName) {
+    SkASSERT(name && strlen(name));
+    SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFragment_Visibility);
+    SkASSERT(0 == (~kVisibilityMask & visibility));
+    SkASSERT(0 != visibility);
+
+    UniformInfo& uni = fUniforms.push_back();
+    uni.fVariable.setType(type);
+    uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
+    this->nameVariable(uni.fVariable.accessName(), 'u', name);
+    uni.fVariable.setArrayCount(count);
+    uni.fVisibility = visibility;
+
+    // If it is visible in both the VS and FS, the precision must match.
+    // We declare a default FS precision, but not a default VS. So set the var
+    // to use the default FS precision.
+    if ((kVertex_Visibility | kFragment_Visibility) == visibility) {
+        // the fragment and vertex precisions must match
+        uni.fVariable.setPrecision(kDefaultFragmentPrecision);
+    }
+
+    if (outName) {
+        *outName = uni.fVariable.c_str();
+    }
+    return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
+}
+
+void GrGLProgramBuilder::appendDecls(const VarArray& vars, SkString* out) const {
+    for (int i = 0; i < vars.count(); ++i) {
+        vars[i].appendDecl(this->ctxInfo(), out);
+        out->append(";\n");
+    }
+}
+
+void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
+                                            SkString* out) const {
+    for (int i = 0; i < fUniforms.count(); ++i) {
+        if (fUniforms[i].fVisibility & visibility) {
+            fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
+            out->append(";\n");
+        }
+    }
+}
+
+void GrGLProgramBuilder::createAndEmitEffects(const GrFragmentStage* effectStages[],
+                                              int effectCnt,
+                                              const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+                                              GrGLSLExpr4* fsInOutColor) {
+    bool effectEmitted = false;
+
+    GrGLSLExpr4 inColor = *fsInOutColor;
+    GrGLSLExpr4 outColor;
+
+    for (int e = 0; e < effectCnt; ++e) {
+        fGrProcessorEmitter.set(effectStages[e]->getFragmentProcessor());
+        fEffectEmitter = &fGrProcessorEmitter;
+        // calls into the subclass to emit the actual effect into the program effect object
+        this->emitEffect(*effectStages[e], e, keyProvider, &inColor, &outColor);
+        effectEmitted = true;
+    }
+
+    if (effectEmitted) {
+        *fsInOutColor = outColor;
+    }
+}
+
+void GrGLProgramBuilder::emitEffect(const GrProcessorStage& effectStage,
+                                    int effectIndex,
+                                    const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+                                    GrGLSLExpr4* inColor,
+                                    GrGLSLExpr4* outColor) {
+    SkASSERT(effectStage.getProcessor());
+    CodeStage::AutoStageRestore csar(&fCodeStage, &effectStage);
+
+    if (inColor->isZeros()) {
+        SkString inColorName;
+
+        // Effects have no way to communicate zeros, they treat an empty string as ones.
+        this->nameVariable(&inColorName, '\0', "input");
+        fFS.codeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor->c_str());
+        *inColor = inColorName;
+    }
+
+    // create var to hold stage result
+    SkString outColorName;
+    this->nameVariable(&outColorName, '\0', "output");
+    fFS.codeAppendf("\tvec4 %s;\n", outColorName.c_str());
+    *outColor = outColorName;
+
+    this->emitEffect(effectStage, keyProvider.get(effectIndex), outColor->c_str(),
+                     inColor->isOnes() ? NULL : inColor->c_str(), fCodeStage.stageIndex());
+
+    *inColor = *outColor;
+}
+
+void GrGLProgramBuilder::emitSamplers(const GrProcessor& effect,
+                                      GrGLProcessor::TextureSamplerArray* outSamplers) {
+    SkTArray<GrGLProgramEffects::Sampler, true>& samplers =
+            this->getProgramEffects()->addSamplers();
+    int numTextures = effect.numTextures();
+    samplers.push_back_n(numTextures);
+    SkString name;
+    for (int t = 0; t < numTextures; ++t) {
+        name.printf("Sampler%d", t);
+        samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                                kSampler2D_GrSLType,
+                                                name.c_str());
+        SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
+                               (samplers[t].fUniform, effect.textureAccess(t)));
+    }
+}
+
+bool GrGLProgramBuilder::finish() {
+    SkASSERT(0 == fProgramID);
+    GL_CALL_RET(fProgramID, CreateProgram());
+    if (!fProgramID) {
+        return false;
+    }
+
+    SkTDArray<GrGLuint> shadersToDelete;
+
+    if (!this->compileAndAttachShaders(fProgramID, &shadersToDelete)) {
+        GL_CALL(DeleteProgram(fProgramID));
+        return false;
+    }
+
+    this->bindProgramLocations(fProgramID);
+
+    GL_CALL(LinkProgram(fProgramID));
+
+    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
+    bool checkLinked = !fGpu->ctxInfo().isChromium();
+#ifdef SK_DEBUG
+    checkLinked = true;
+#endif
+    if (checkLinked) {
+        GrGLint linked = GR_GL_INIT_ZERO;
+        GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked));
+        if (!linked) {
+            GrGLint infoLen = GR_GL_INIT_ZERO;
+            GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
+            SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
+            if (infoLen > 0) {
+                // retrieve length even though we don't need it to workaround
+                // bug in chrome cmd buffer param validation.
+                GrGLsizei length = GR_GL_INIT_ZERO;
+                GL_CALL(GetProgramInfoLog(fProgramID,
+                                          infoLen+1,
+                                          &length,
+                                          (char*)log.get()));
+                GrPrintf((char*)log.get());
+            }
+            SkDEBUGFAIL("Error linking program");
+            GL_CALL(DeleteProgram(fProgramID));
+            fProgramID = 0;
+            return false;
+        }
+    }
+
+    this->resolveProgramLocations(fProgramID);
+
+    for (int i = 0; i < shadersToDelete.count(); ++i) {
+      GL_CALL(DeleteShader(shadersToDelete[i]));
+    }
+
+    return true;
+}
+
+bool GrGLProgramBuilder::compileAndAttachShaders(GrGLuint programId,
+                                                 SkTDArray<GrGLuint>* shaderIds) const {
+    return fFS.compileAndAttachShaders(programId, shaderIds);
+}
+
+void GrGLProgramBuilder::bindProgramLocations(GrGLuint programId) {
+    fFS.bindProgramLocations(programId);
+
+    // skbug.com/2056
+    bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
+    if (usingBindUniform) {
+        int count = fUniforms.count();
+        for (int i = 0; i < count; ++i) {
+            GL_CALL(BindUniformLocation(programId, i, fUniforms[i].fVariable.c_str()));
+            fUniforms[i].fLocation = i;
+        }
+    }
+}
+
+void GrGLProgramBuilder::resolveProgramLocations(GrGLuint programId) {
+    bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
+    if (!usingBindUniform) {
+        int count = fUniforms.count();
+        for (int i = 0; i < count; ++i) {
+            GrGLint location;
+            GL_CALL_RET(location,
+                        GetUniformLocation(programId, fUniforms[i].fVariable.c_str()));
+            fUniforms[i].fLocation = location;
+        }
+    }
+
+    int count = fSeparableVaryingInfos.count();
+    for (int i = 0; i < count; ++i) {
+        GrGLint location;
+        GL_CALL_RET(location,
+                    GetProgramResourceLocation(programId,
+                                               GR_GL_FRAGMENT_INPUT,
+                                               fSeparableVaryingInfos[i].fVariable.c_str()));
+        fSeparableVaryingInfos[i].fLocation = location;
+    }
+}
+
+const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
+    return fGpu->ctxInfo();
+}
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
new file mode 100644
index 0000000..f6397d8
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLProgramBuilder_DEFINED
+#define GrGLProgramBuilder_DEFINED
+
+#include "GrAllocator.h"
+#include "GrBackendProcessorFactory.h"
+#include "GrColor.h"
+#include "GrProcessor.h"
+#include "GrGLFragmentShaderBuilder.h"
+#include "GrGLGeometryShaderBuilder.h"
+#include "GrGLVertexShaderBuilder.h"
+#include "SkTypes.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/GrGLProgramDesc.h"
+#include "gl/GrGLProgramEffects.h"
+#include "gl/GrGLSL.h"
+#include "gl/GrGLProgramDataManager.h"
+
+#include <stdarg.h>
+
+class GrGLContextInfo;
+class GrProcessorStage;
+class GrGLProgramDesc;
+
+/**
+  Contains all the incremental state of a shader as it is being built,as well as helpers to
+  manipulate that state.
+*/
+class GrGLProgramBuilder {
+public:
+    enum ShaderVisibility {
+        kVertex_Visibility   = 0x1,
+        kGeometry_Visibility = 0x2,
+        kFragment_Visibility = 0x4,
+    };
+
+    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+    typedef GrGLProgramDataManager::VaryingHandle VaryingHandle;
+
+    // Handles for program uniforms (other than per-effect uniforms)
+    struct BuiltinUniformHandles {
+        UniformHandle       fViewMatrixUni;
+        UniformHandle       fRTAdjustmentUni;
+        UniformHandle       fColorUni;
+        UniformHandle       fCoverageUni;
+
+        // We use the render target height to provide a y-down frag coord when specifying
+        // origin_upper_left is not supported.
+        UniformHandle       fRTHeightUni;
+
+        // Uniforms for computing texture coords to do the dst-copy lookup
+        UniformHandle       fDstCopyTopLeftUni;
+        UniformHandle       fDstCopyScaleUni;
+        UniformHandle       fDstCopySamplerUni;
+    };
+
+    struct UniformInfo {
+        GrGLShaderVar fVariable;
+        uint32_t      fVisibility;
+        GrGLint       fLocation;
+    };
+
+    // This uses an allocator rather than array so that the GrGLShaderVars don't move in memory
+    // after they are inserted. Users of GrGLShaderBuilder get refs to the vars and ptrs to their
+    // name strings. Otherwise, we'd have to hand out copies.
+    typedef GrTAllocator<UniformInfo> UniformInfoArray;
+
+    struct SeparableVaryingInfo {
+        GrGLShaderVar fVariable;
+        GrGLint       fLocation;
+    };
+
+    typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray;
+
+    /** Generates a shader program.
+     *
+     * The program implements what is specified in the stages given as input.
+     * After successful generation, the builder result objects are available
+     * to be used.
+     * @return true if generation was successful.
+     */
+
+    bool genProgram(const GrGeometryStage* inGeometryProcessor,
+                    const GrFragmentStage* inColorStages[],
+                    const GrFragmentStage* inCoverageStages[]);
+
+    GrGLProgramEffects* getGeometryProcessor() const {
+        SkASSERT(fProgramID); return fGeometryProcessor.get();
+    }
+    GrGLProgramEffects* getColorEffects() const { SkASSERT(fProgramID); return fColorEffects.get(); }
+    GrGLProgramEffects* getCoverageEffects() const { SkASSERT(fProgramID); return fCoverageEffects.get(); }
+    const BuiltinUniformHandles& getBuiltinUniformHandles() const {
+        SkASSERT(fProgramID);
+        return fUniformHandles;
+    }
+    GrGLuint getProgramID() const { SkASSERT(fProgramID); return fProgramID; }
+    bool hasVertexShader() const { SkASSERT(fProgramID); return !fFragOnly; }
+    int getTexCoordSetCount() const { SkASSERT(fProgramID); return fTexCoordSetCnt; }
+    const UniformInfoArray& getUniformInfos() const { return fUniforms; }
+    const SeparableVaryingInfoArray& getSeparableVaryingInfos() const {
+        return fSeparableVaryingInfos;
+    }
+
+    virtual ~GrGLProgramBuilder() {}
+
+    /** Add a uniform variable to the current program, that has visibility in one or more shaders.
+        visibility is a bitfield of ShaderVisibility values indicating from which shaders the
+        uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
+        supported at this time. The actual uniform name will be mangled. If outName is not NULL then
+        it will refer to the final uniform name after return. Use the addUniformArray variant to add
+        an array of uniforms. */
+    GrGLProgramDataManager::UniformHandle addUniform(uint32_t visibility,
+                                                     GrSLType type,
+                                                     const char* name,
+                                                     const char** outName = NULL) {
+        return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
+    }
+    GrGLProgramDataManager::UniformHandle addUniformArray(uint32_t visibility,
+                                                          GrSLType type,
+                                                          const char* name,
+                                                          int arrayCount,
+                                                          const char** outName = NULL);
+
+    const GrGLShaderVar& getUniformVariable(GrGLProgramDataManager::UniformHandle u) const {
+        return fUniforms[u.toShaderBuilderIndex()].fVariable;
+    }
+
+    /**
+     * Shortcut for getUniformVariable(u).c_str()
+     */
+    const char* getUniformCStr(GrGLProgramDataManager::UniformHandle u) const {
+        return this->getUniformVariable(u).c_str();
+    }
+
+    const GrGLContextInfo& ctxInfo() const;
+
+    GrGLFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; }
+    GrGpuGL* gpu() const { return fGpu; }
+
+protected:
+    typedef GrTAllocator<GrGLShaderVar> VarArray;
+    GrGLProgramBuilder(GrGpuGL*, const GrGLProgramDesc&);
+
+    const GrGLProgramDesc& desc() const { return fDesc; }
+
+    // Helper for emitEffects().
+    void createAndEmitEffects(const GrFragmentStage* effectStages[],
+                              int effectCnt,
+                              const GrGLProgramDesc::EffectKeyProvider&,
+                              GrGLSLExpr4* inOutFSColor);
+
+    /*
+     * A helper function called to emit the geometry processor as well as individual coverage
+     * and color stages.  this will call into subclasses emit effect
+     */
+    void emitEffect(const GrProcessorStage& effectStage,
+                    int effectIndex,
+                    const GrGLProgramDesc::EffectKeyProvider& keyProvider,
+                    GrGLSLExpr4* inColor,
+                    GrGLSLExpr4* outColor);
+
+    /**
+     * Helper for emitEffect() in subclasses. Emits uniforms for an effect's texture accesses and
+     * appends the necessary data to the TextureSamplerArray* object so effects can add texture
+     * lookups to their code. This method is only meant to be called during the construction phase.
+     */
+    void emitSamplers(const GrProcessor& effect,
+                      GrGLProcessor::TextureSamplerArray* outSamplers);
+
+    // Generates a name for a variable. The generated string will be name prefixed by the prefix
+    // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
+    // generating stage code.
+    void nameVariable(SkString* out, char prefix, const char* name);
+
+    virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
+
+    virtual void bindProgramLocations(GrGLuint programId);
+    void resolveProgramLocations(GrGLuint programId);
+
+    void appendDecls(const VarArray&, SkString*) const;
+    void appendUniformDecls(ShaderVisibility, SkString*) const;
+
+    class CodeStage : SkNoncopyable {
+    public:
+        CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
+
+        bool inStageCode() const {
+            this->validate();
+            return SkToBool(fEffectStage);
+        }
+
+        const GrProcessorStage* effectStage() const {
+            this->validate();
+            return fEffectStage;
+        }
+
+        int stageIndex() const {
+            this->validate();
+            return fCurrentIndex;
+        }
+
+        class AutoStageRestore : SkNoncopyable {
+        public:
+            AutoStageRestore(CodeStage* codeStage, const GrProcessorStage* newStage) {
+                SkASSERT(codeStage);
+                fSavedIndex = codeStage->fCurrentIndex;
+                fSavedEffectStage = codeStage->fEffectStage;
+
+                if (NULL == newStage) {
+                    codeStage->fCurrentIndex = -1;
+                } else {
+                    codeStage->fCurrentIndex = codeStage->fNextIndex++;
+                }
+                codeStage->fEffectStage = newStage;
+
+                fCodeStage = codeStage;
+            }
+            ~AutoStageRestore() {
+                fCodeStage->fCurrentIndex = fSavedIndex;
+                fCodeStage->fEffectStage = fSavedEffectStage;
+            }
+        private:
+            CodeStage*              fCodeStage;
+            int                     fSavedIndex;
+            const GrProcessorStage*    fSavedEffectStage;
+        };
+    private:
+        void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
+        int                     fNextIndex;
+        int                     fCurrentIndex;
+        const GrProcessorStage*    fEffectStage;
+    };
+
+    class GrGLProcessorEmitterInterface {
+     public:
+        virtual ~GrGLProcessorEmitterInterface() {}
+        virtual GrGLProcessor* createGLInstance() = 0;
+        virtual void emit(const GrProcessorKey& key,
+                          const char* outColor,
+                          const char* inColor,
+                          const GrGLProcessor::TransformedCoordsArray& coords,
+                          const GrGLProcessor::TextureSamplerArray& samplers) = 0;
+    };
+
+    class GrGLFragmentProcessorEmitter  : public GrGLProcessorEmitterInterface {
+    public:
+        GrGLFragmentProcessorEmitter(GrGLProgramBuilder* builder)
+            : fBuilder(builder)
+            , fFragmentProcessor(NULL)
+            , fGLFragmentProcessor(NULL) {}
+        virtual ~GrGLFragmentProcessorEmitter() {}
+        void set(const GrFragmentProcessor* fp) {
+            SkASSERT(NULL == fFragmentProcessor);
+            fFragmentProcessor = fp;
+        }
+        virtual GrGLProcessor* createGLInstance() {
+            SkASSERT(fFragmentProcessor);
+            SkASSERT(NULL == fGLFragmentProcessor);
+            fGLFragmentProcessor =
+                    fFragmentProcessor->getFactory().createGLInstance(*fFragmentProcessor);
+            return fGLFragmentProcessor;
+        }
+        virtual void emit(const GrProcessorKey& key,
+                          const char* outColor,
+                          const char* inColor,
+                          const GrGLProcessor::TransformedCoordsArray& coords,
+                          const GrGLProcessor::TextureSamplerArray& samplers) {
+            SkASSERT(fFragmentProcessor);
+            SkASSERT(fGLFragmentProcessor);
+            fGLFragmentProcessor->emitCode(fBuilder, *fFragmentProcessor, key, outColor, inColor,
+                                           coords, samplers);
+            // this will not leak because it hasa already been used by createGLInstance
+            fGLFragmentProcessor = NULL;
+            fFragmentProcessor = NULL;
+        }
+    private:
+        GrGLProgramBuilder*         fBuilder;
+        const GrFragmentProcessor*  fFragmentProcessor;
+        GrGLFragmentProcessor*      fGLFragmentProcessor;
+    };
+
+    GrGLProcessorEmitterInterface*   fEffectEmitter;
+    CodeStage                        fCodeStage;
+    SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor;
+    SkAutoTUnref<GrGLProgramEffects> fColorEffects;
+    SkAutoTUnref<GrGLProgramEffects> fCoverageEffects;
+    BuiltinUniformHandles            fUniformHandles;
+    bool                             fFragOnly;
+    int                              fTexCoordSetCnt;
+    GrGLuint                         fProgramID;
+    GrGLFragmentShaderBuilder        fFS;
+    SeparableVaryingInfoArray        fSeparableVaryingInfos;
+
+private:
+    virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor,
+                                      const GrFragmentStage* colorStages[],
+                                      const GrFragmentStage* coverageStages[],
+                                      GrGLSLExpr4* inputColor,
+                                      GrGLSLExpr4* inputCoverage) = 0;
+    /*
+     * Subclasses override emitEffect below to emit data and code for a specific single effect
+     */
+    virtual void emitEffect(const GrProcessorStage&,
+                            const GrProcessorKey&,
+                            const char* outColor,
+                            const char* inColor,
+                            int stageIndex) = 0;
+
+    /*
+     * Because we have fragment only builders, and those builders need to implement a subclass
+     * of program effects, we have to have base classes overload the program effects here
+     */
+    virtual GrGLProgramEffects* getProgramEffects() = 0;
+
+    /**
+     * Compiles all the shaders, links them into a program, and writes the program id to the output
+     * struct.
+     **/
+    bool finish();
+
+    GrGLFragmentProcessorEmitter            fGrProcessorEmitter;
+
+    const GrGLProgramDesc&                  fDesc;
+    GrGpuGL*                                fGpu;
+    UniformInfoArray                        fUniforms;
+
+    friend class GrGLShaderBuilder;
+    friend class GrGLVertexShaderBuilder;
+    friend class GrGLFragmentShaderBuilder;
+    friend class GrGLGeometryShaderBuilder;
+};
+
+#endif
diff --git a/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp b/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp
new file mode 100644
index 0000000..27f4b44
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp
@@ -0,0 +1,173 @@
+/*
+ * 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 "gl/GrGLSLPrettyPrint.h"
+
+namespace GrGLSLPrettyPrint {
+
+class GLSLPrettyPrint {
+public:
+    GLSLPrettyPrint() {}
+
+    SkString prettify(const SkString& input, bool countlines) {
+        // setup pretty state
+        fIndex = 0;
+        fLength = input.size();
+        fInput = input;
+        fCountlines = countlines;
+        fTabs = 0;
+        fLinecount = 1;
+        fFreshline = true;
+
+        int parensDepth = 0;
+        // number 1st line
+        this->lineNumbering();
+        while (fLength > fIndex) {
+            /* the heart and soul of our prettification algorithm.  The rules should hopefully be
+             * self explanatory.  For '#' and '//' tokens we parse until we reach a newline.
+             *
+             * For long style comments like this one, we search for the ending token.  We also
+             * preserve whitespace in these comments WITH THE CAVEAT that we do the newlines
+             * ourselves.  This allows us to remain in control of line numbers, and matching tabs
+             * Existing tabs in the input string are copied over too, but this will look funny
+             *
+             * '{' and '}' are handled in basically the same way.  We add a newline if we aren't
+             * on a fresh line, dirty the line, then add a second newline, ie braces are always
+             * on their own lines indented properly.  The one funkiness here is structs print with
+             * the semicolon on its own line.  Its not a problem for a glsl compiler though
+             *
+             * '(' and ')' are basically ignored, except as a sign we need to ignore ';' ala
+             * in for loops.
+             *
+             * ';' means add a new line
+             *
+             * '\t' and '\n' are ignored in general parsing for backwards compatability with
+             * existing shader code and we also have a special case for handling whitespace
+             * at the beginning of fresh lines.
+             *
+             * Otherwise just add the new character to the pretty string, indenting if necessary.
+             */
+            if (this->hasToken("#") || this->hasToken("//")) {
+                this->parseUntilNewline();
+            } else if (this->hasToken("/*")) {
+                this->parseUntil("*/");
+            } else if ('{' == fInput[fIndex]) {
+                this->newline();
+                this->appendChar('{');
+                fTabs++;
+                this->newline();
+            } else if ('}' == fInput[fIndex]) {
+                fTabs--;
+                this->newline();
+                this->appendChar('}');
+                this->newline();
+            } else if (this->hasToken(")")) {
+                parensDepth--;
+            } else if (this->hasToken("(")) {
+                parensDepth++;
+            } else if (!parensDepth && this->hasToken(";")) {
+                this->newline();
+            } else if ('\t' == fInput[fIndex] || '\n' == fInput[fIndex] ||
+                    (fFreshline && ' ' == fInput[fIndex])) {
+                fIndex++;
+            } else {
+                this->appendChar(input[fIndex]);
+            }
+        }
+        return fPretty;
+    }
+private:
+    void appendChar(char c) {
+        this->tabString();
+        fPretty.appendf("%c", fInput[fIndex++]);
+        fFreshline = false;
+    }
+
+    // hasToken automatically consumes the next token, if it is a match, and then tabs
+    // if necessary, before inserting the token into the pretty string
+    bool hasToken(const char* token) {
+        size_t i = fIndex;
+        for (size_t j = 0; token[j] && fLength > i; i++, j++) {
+            if (token[j] != fInput[i]) {
+                return false;
+            }
+        }
+        this->tabString();
+        fIndex = i;
+        fPretty.append(token);
+        fFreshline = false;
+        return true;
+    }
+
+    void parseUntilNewline() {
+        while (fLength > fIndex) {
+            if ('\n' == fInput[fIndex]) {
+                fIndex++;
+                this->newline();
+                break;
+            }
+            fPretty.appendf("%c", fInput[fIndex++]);
+        }
+    }
+
+    // this code assumes it is not actually searching for a newline.  If you need to search for a
+    // newline, then use the function above.  If you do search for a newline with this function
+    // it will consume the entire string and the output will certainly not be prettified
+    void parseUntil(const char* token) {
+        while (fLength > fIndex) {
+            // For embedded newlines,  this code will make sure to embed the newline in the
+            // pretty string, increase the linecount, and tab out the next line to the appropriate
+            // place
+            if ('\n' == fInput[fIndex]) {
+                this->newline();
+                this->tabString();
+                fIndex++;
+            }
+            if (this->hasToken(token)) {
+                break;
+            }
+            fFreshline = false;
+            fPretty.appendf("%c", fInput[fIndex++]);
+        }
+    }
+
+    // We only tab if on a newline, otherwise consider the line tabbed
+    void tabString() {
+        if (fFreshline) {
+            for (int t = 0; t < fTabs; t++) {
+                fPretty.append("\t");
+            }
+        }
+    }
+
+    // newline is really a request to add a newline, if we are on a fresh line there is no reason
+    // to add another newline
+    void newline() {
+        if (!fFreshline) {
+            fFreshline = true;
+            fPretty.append("\n");
+            this->lineNumbering();
+        }
+    }
+
+    void lineNumbering() {
+        if (fCountlines) {
+            fPretty.appendf("%4d\t", fLinecount++);
+        }
+    }
+
+    bool fCountlines, fFreshline;
+    int fTabs, fLinecount;
+    size_t fIndex, fLength;
+    SkString fInput, fPretty;
+};
+
+SkString PrettyPrintGLSL(const SkString& input, bool countlines) {
+    GLSLPrettyPrint pp;
+    return pp.prettify(input, countlines);
+}
+
+} // end namespace
diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.cpp b/src/gpu/gl/builders/GrGLShaderBuilder.cpp
new file mode 100644
index 0000000..33474e6
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLShaderBuilder.cpp
@@ -0,0 +1,162 @@
+/*
+ * 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 "GrGLShaderBuilder.h"
+#include "GrGLFullProgramBuilder.h"
+#include "GrGLProgramBuilder.h"
+#include "../GrGpuGL.h"
+#include "../GrGLShaderVar.h"
+
+namespace {
+inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) {
+    if (kVec2f_GrSLType == type) {
+        return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
+    } else {
+        SkASSERT(kVec3f_GrSLType == type);
+        return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj";
+    }
+}
+void append_texture_lookup(SkString* out,
+                           GrGpuGL* gpu,
+                           const char* samplerName,
+                           const char* coordName,
+                           uint32_t configComponentMask,
+                           const char* swizzle,
+                           GrSLType varyingType = kVec2f_GrSLType) {
+    SkASSERT(coordName);
+
+    out->appendf("%s(%s, %s)",
+                 sample_function_name(varyingType, gpu->glslGeneration()),
+                 samplerName,
+                 coordName);
+
+    char mangledSwizzle[5];
+
+    // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
+    // is available.
+    if (!gpu->glCaps().textureSwizzleSupport() &&
+        (kA_GrColorComponentFlag == configComponentMask)) {
+        char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a';
+        int i;
+        for (i = 0; '\0' != swizzle[i]; ++i) {
+            mangledSwizzle[i] = alphaChar;
+        }
+        mangledSwizzle[i] ='\0';
+        swizzle = mangledSwizzle;
+    }
+    // For shader prettiness we omit the swizzle rather than appending ".rgba".
+    if (memcmp(swizzle, "rgba", 4)) {
+        out->appendf(".%s", swizzle);
+    }
+}
+static const int kVarsPerBlock = 8;
+}
+
+GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program)
+    : fProgramBuilder(program)
+    , fInputs(kVarsPerBlock)
+    , fOutputs(kVarsPerBlock)
+    , fFeaturesAddedMask(0) {
+}
+
+void GrGLShaderBuilder::declAppend(const GrGLShaderVar& var) {
+    SkString tempDecl;
+    var.appendDecl(fProgramBuilder->ctxInfo(), &tempDecl);
+    this->codeAppendf("%s;", tempDecl.c_str());
+}
+
+void GrGLShaderBuilder::emitFunction(GrSLType returnType,
+                                     const char* name,
+                                     int argCnt,
+                                     const GrGLShaderVar* args,
+                                     const char* body,
+                                     SkString* outName) {
+    fFunctions.append(GrGLSLTypeString(returnType));
+    fProgramBuilder->nameVariable(outName, '\0', name);
+    fFunctions.appendf(" %s", outName->c_str());
+    fFunctions.append("(");
+    const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo();
+    for (int i = 0; i < argCnt; ++i) {
+        args[i].appendDecl(ctxInfo, &fFunctions);
+        if (i < argCnt - 1) {
+            fFunctions.append(", ");
+        }
+    }
+    fFunctions.append(") {\n");
+    fFunctions.append(body);
+    fFunctions.append("}\n\n");
+}
+
+void GrGLShaderBuilder::appendTextureLookup(SkString* out,
+                                            const TextureSampler& sampler,
+                                            const char* coordName,
+                                            GrSLType varyingType) const {
+    append_texture_lookup(out,
+                          fProgramBuilder->gpu(),
+                          fProgramBuilder->getUniformCStr(sampler.fSamplerUniform),
+                          coordName,
+                          sampler.configComponentMask(),
+                          sampler.swizzle(),
+                          varyingType);
+}
+
+void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler,
+                                            const char* coordName,
+                                            GrSLType varyingType) {
+    this->appendTextureLookup(&fCode, sampler, coordName, varyingType);
+}
+
+void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation,
+                                                       const TextureSampler& sampler,
+                                                       const char* coordName,
+                                                       GrSLType varyingType) {
+    SkString lookup;
+    this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
+    this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
+}
+
+
+const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
+    if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
+        if (caps.textureRedSupport()) {
+            static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
+            return gRedSmear;
+        } else {
+            static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
+                                                    GR_GL_ALPHA, GR_GL_ALPHA };
+            return gAlphaSmear;
+        }
+    } else {
+        static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
+        return gStraight;
+    }
+}
+
+void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) {
+    if (!(featureBit & fFeaturesAddedMask)) {
+        fExtensions.appendf("#extension %s: require\n", extensionName);
+            fFeaturesAddedMask |= featureBit;
+    }
+}
+
+void GrGLShaderBuilder::appendTextureLookup(const char* samplerName,
+                                            const char* coordName,
+                                            uint32_t configComponentMask,
+                                            const char* swizzle) {
+    append_texture_lookup(&fCode,
+                          fProgramBuilder->gpu(),
+                          samplerName,
+                          coordName,
+                          configComponentMask,
+                          swizzle,
+                          kVec2f_GrSLType);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGLFullProgramBuilder* program)
+    : INHERITED(program)
+    , fFullProgramBuilder(program) {}
diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.h b/src/gpu/gl/builders/GrGLShaderBuilder.h
new file mode 100644
index 0000000..e99fcce
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLShaderBuilder.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLShaderBuilder_DEFINED
+#define GrGLShaderBuilder_DEFINED
+
+#include "gl/GrGLProgramDesc.h"
+#include "gl/GrGLProgramEffects.h"
+#include "gl/GrGLSL.h"
+#include "gl/GrGLProgramDataManager.h"
+#include "GrBackendProcessorFactory.h"
+#include "GrColor.h"
+#include "GrProcessor.h"
+#include "SkTypes.h"
+
+#include <stdarg.h>
+
+class GrGLContextInfo;
+class GrProcessorStage;
+class GrGLProgramDesc;
+class GrGLProgramBuilder;
+class GrGLFullProgramBuilder;
+
+/**
+  base class for all shaders builders
+*/
+class GrGLShaderBuilder {
+public:
+    typedef GrGLProcessor::TransformedCoordsArray TransformedCoordsArray;
+    typedef GrGLProcessor::TextureSampler TextureSampler;
+    GrGLShaderBuilder(GrGLProgramBuilder* program);
+
+    void addInput(GrGLShaderVar i) { fInputs.push_back(i); }
+    void addOutput(GrGLShaderVar i) { fOutputs.push_back(i); }
+
+    /*
+     * We put texture lookups in the base class because it is TECHNICALLY possible to do texture
+     * lookups in any kind of shader.  However, for the time being using these calls on non-fragment
+     * shaders will result in a shader compilation error as texture sampler uniforms are only
+     * visible to the fragment shader.  It would not be hard to change this behavior, if someone
+     * actually wants to do texture lookups in a non-fragment shader
+     *
+     * TODO if append texture lookup is used on a non-fragment shader, sampler uniforms should be
+     * made visible to that shaders
+     */
+    /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
+        Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
+        order of the result depends on the GrTextureAccess associated with the TextureSampler. */
+    void appendTextureLookup(SkString* out,
+                             const TextureSampler&,
+                             const char* coordName,
+                             GrSLType coordType = kVec2f_GrSLType) const;
+
+    /** Version of above that appends the result to the fragment shader code instead.*/
+    void appendTextureLookup(const TextureSampler&,
+                             const char* coordName,
+                             GrSLType coordType = kVec2f_GrSLType);
+
+
+    /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
+        always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
+        float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
+        called. */
+    void appendTextureLookupAndModulate(const char* modulation,
+                                        const TextureSampler&,
+                                        const char* coordName,
+                                        GrSLType coordType = kVec2f_GrSLType);
+
+    /** If texture swizzling is available using tex parameters then it is preferred over mangling
+        the generated shader code. This potentially allows greater reuse of cached shaders. */
+    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
+
+    /**
+    * Called by GrGLProcessors to add code to one of the shaders.
+    */
+    void codeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
+       va_list args;
+       va_start(args, format);
+       fCode.appendVAList(format, args);
+       va_end(args);
+    }
+
+    void codeAppend(const char* str) { fCode.append(str); }
+
+    void codePrependf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
+       va_list args;
+       va_start(args, format);
+       fCode.prependVAList(format, args);
+       va_end(args);
+    }
+
+    /**
+     * Appends a variable declaration to one of the shaders
+     */
+    void declAppend(const GrGLShaderVar& var);
+
+    /** Emits a helper function outside of main() in the fragment shader. */
+    void emitFunction(GrSLType returnType,
+                      const char* name,
+                      int argCnt,
+                      const GrGLShaderVar* args,
+                      const char* body,
+                      SkString* outName);
+
+    /*
+     * Get parent builder for adding uniforms
+     */
+    GrGLProgramBuilder* getProgramBuilder() { return fProgramBuilder; }
+
+    /**
+     * Helper for begining and ending a block in the fragment code.
+     */
+    class ShaderBlock {
+    public:
+        ShaderBlock(GrGLShaderBuilder* builder) : fBuilder(builder) {
+            SkASSERT(builder);
+            fBuilder->codeAppend("{");
+        }
+
+        ~ShaderBlock() {
+            fBuilder->codeAppend("}");
+        }
+    private:
+        GrGLShaderBuilder* fBuilder;
+    };
+protected:
+
+    /*
+     * this super low level function is just for use internally to builders
+     */
+    void appendTextureLookup(const char* samplerName,
+                             const char* coordName,
+                             uint32_t configComponentMask,
+                             const char* swizzle);
+
+    /*
+     * A general function which enables an extension in a shader if the feature bit is not present
+     */
+    void addFeature(uint32_t featureBit, const char* extensionName);
+
+    typedef GrTAllocator<GrGLShaderVar> VarArray;
+
+    GrGLProgramBuilder* fProgramBuilder;
+
+    SkString fCode;
+    SkString fFunctions;
+    SkString fExtensions;
+
+    VarArray fInputs;
+    VarArray fOutputs;
+    uint32_t fFeaturesAddedMask;
+};
+
+
+/*
+ * Full Shader builder is the base class for shaders which are only accessible through full program
+ * builder, ie vertex, geometry, and later TCU / TES.  Using this base class, they can access the
+ * full program builder functionality through the full program pointer
+ */
+class GrGLFullShaderBuilder : public GrGLShaderBuilder {
+public:
+    GrGLFullShaderBuilder(GrGLFullProgramBuilder* program);
+
+    GrGLFullProgramBuilder* fullProgramBuilder() { return fFullProgramBuilder; }
+protected:
+    GrGLFullProgramBuilder* fFullProgramBuilder;
+private:
+    typedef GrGLShaderBuilder INHERITED;
+};
+#endif
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
new file mode 100644
index 0000000..6406451
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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 "GrGLShaderStringBuilder.h"
+#include "../GrGpuGL.h"
+#include "gl/GrGLSLPrettyPrint.h"
+#include "SkRTConf.h"
+#include "SkTraceEvent.h"
+
+#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
+
+SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
+                "Print the source code for all shaders generated.");
+
+GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
+                                    GrGLuint programId,
+                                    GrGLenum type,
+                                    const SkString& shaderSrc,
+                                    GrContext::GPUStats* gpuStats) {
+    const GrGLInterface* gli = glCtx.interface();
+
+    GrGLuint shaderId;
+    GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
+    if (0 == shaderId) {
+        return 0;
+    }
+
+#ifdef SK_DEBUG
+    SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, false);
+    const GrGLchar* sourceStr = prettySource.c_str();
+    GrGLint sourceLength = static_cast<GrGLint>(prettySource.size());
+#else
+    GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size());
+    const GrGLchar* sourceStr = shaderSrc.c_str();
+#endif
+    GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
+    gpuStats->incShaderCompilations();
+    GR_GL_CALL(gli, CompileShader(shaderId));
+
+    // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
+    bool checkCompiled = !glCtx.isChromium();
+#ifdef SK_DEBUG
+    checkCompiled = true;
+#endif
+    if (checkCompiled) {
+        GrGLint compiled = GR_GL_INIT_ZERO;
+        GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
+
+        if (!compiled) {
+            GrGLint infoLen = GR_GL_INIT_ZERO;
+            GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
+            SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
+            if (infoLen > 0) {
+                // retrieve length even though we don't need it to workaround bug in Chromium cmd
+                // buffer param validation.
+                GrGLsizei length = GR_GL_INIT_ZERO;
+                GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
+                                                 &length, (char*)log.get()));
+                GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
+                GrPrintf("\n%s", log.get());
+            }
+            SkDEBUGFAIL("Shader compilation failed!");
+            GR_GL_CALL(gli, DeleteShader(shaderId));
+            return 0;
+        }
+    }
+
+    TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader",
+                         TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str()));
+    if (c_PrintShaders) {
+        GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str());
+        GrPrintf("\n");
+    }
+
+    // Attach the shader, but defer deletion until after we have linked the program.
+    // This works around a bug in the Android emulator's GLES2 wrapper which
+    // will immediately delete the shader object and free its memory even though it's
+    // attached to a program, which then causes glLinkProgram to fail.
+    GR_GL_CALL(gli, AttachShader(programId, shaderId));
+
+    return shaderId;
+}
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.h b/src/gpu/gl/builders/GrGLShaderStringBuilder.h
new file mode 100644
index 0000000..ab8734f
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLShaderStringBuilder_DEFINED
+#define GrGLShaderStringBuilder_DEFINED
+
+#include "GrAllocator.h"
+#include "GrContext.h"
+#include "gl/GrGLContext.h"
+#include "SkTypes.h"
+
+GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
+                                    GrGLuint programId,
+                                    GrGLenum type,
+                                    const SkString& shaderSrc,
+                                    GrContext::GPUStats* gpuStats);
+
+#endif
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
new file mode 100644
index 0000000..4877071
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
@@ -0,0 +1,202 @@
+/*
+ * 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 "GrGLVertexShaderBuilder.h"
+#include "GrGLFullProgramBuilder.h"
+#include "GrGLShaderStringBuilder.h"
+#include "../GrGpuGL.h"
+#include "../../GrOptDrawState.h"
+
+#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
+
+namespace {
+inline const char* color_attribute_name() { return "inColor"; }
+inline const char* coverage_attribute_name() { return "inCoverage"; }
+}
+
+GrGLVertexShaderBuilder::GrGLVertexShaderBuilder(GrGLFullProgramBuilder* program)
+    : INHERITED(program)
+    , fPositionVar(NULL)
+    , fLocalCoordsVar(NULL) {
+}
+bool GrGLVertexShaderBuilder::addAttribute(const GrShaderVar& var) {
+    SkASSERT(GrShaderVar::kAttribute_TypeModifier == var.getTypeModifier());
+    for (int i = 0; i < fInputs.count(); ++i) {
+        const GrGLShaderVar& attr = fInputs[i];
+        // if attribute already added, don't add it again
+        if (attr.getName().equals(var.getName())) {
+            return false;
+        }
+    }
+    fInputs.push_back(var);
+    return true;
+}
+
+void GrGLVertexShaderBuilder::emitAttributes(const GrGeometryProcessor& gp) {
+    const GrGeometryProcessor::VertexAttribArray& vars = gp.getVertexAttribs();
+    int numAttributes = vars.count();
+    for (int a = 0; a < numAttributes; ++a) {
+        this->addAttribute(vars[a]);
+    }
+}
+
+void GrGLVertexShaderBuilder::addVarying(GrSLType type, const char* name, const char** vsOutName) {
+    fOutputs.push_back();
+    fOutputs.back().setType(type);
+    fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
+    fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'v', name);
+
+    if (vsOutName) {
+        *vsOutName = fOutputs.back().getName().c_str();
+    }
+}
+
+
+void GrGLVertexShaderBuilder::bindProgramLocations(GrGLuint programId) {
+    const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
+    GrGpuGL* gpu = fProgramBuilder->gpu();
+
+    // Bind the attrib locations to same values for all shaders
+    SkASSERT(-1 != header.fPositionAttributeIndex);
+    GL_CALL(BindAttribLocation(programId,
+                               header.fPositionAttributeIndex,
+                               fPositionVar->c_str()));
+    if (-1 != header.fLocalCoordAttributeIndex) {
+        GL_CALL(BindAttribLocation(programId,
+                                   header.fLocalCoordAttributeIndex,
+                                   fLocalCoordsVar->c_str()));
+    }
+    if (-1 != header.fColorAttributeIndex) {
+        GL_CALL(BindAttribLocation(programId,
+                                   header.fColorAttributeIndex,
+                                   color_attribute_name()));
+    }
+    if (-1 != header.fCoverageAttributeIndex) {
+        GL_CALL(BindAttribLocation(programId,
+                                   header.fCoverageAttributeIndex,
+                                   coverage_attribute_name()));
+    }
+
+    // We pull the current state of attributes off of drawstate's optimized state and bind them in
+    // order. This assumes that the drawState has not changed since we called flushGraphicsState()
+    // higher up in the stack.
+    const GrDrawTargetCaps* caps = fProgramBuilder->gpu()->caps();
+    const GrDrawState& drawState = *fProgramBuilder->gpu()->drawState();
+    SkAutoTUnref<GrOptDrawState> optState(drawState.createOptState(*caps));
+    const GrVertexAttrib* vaPtr = optState->getVertexAttribs();
+    const int vaCount = optState->getVertexAttribCount();
+
+    int i = fEffectAttribOffset;
+    for (int index = 0; index < vaCount; index++) {
+        if (kGeometryProcessor_GrVertexAttribBinding != vaPtr[index].fBinding) {
+            continue;
+        }
+        SkASSERT(index != header.fPositionAttributeIndex &&
+                 index != header.fLocalCoordAttributeIndex &&
+                 index != header.fColorAttributeIndex &&
+                 index != header.fCoverageAttributeIndex);
+        // We should never find another effect attribute if we have bound everything
+        SkASSERT(i < fInputs.count());
+        GL_CALL(BindAttribLocation(programId, index, fInputs[i].c_str()));
+        i++;
+    }
+    // Make sure we bound everything
+    SkASSERT(fInputs.count() == i);
+}
+
+bool GrGLVertexShaderBuilder::compileAndAttachShaders(GrGLuint programId,
+        SkTDArray<GrGLuint>* shaderIds) const {
+    GrGpuGL* gpu = fProgramBuilder->gpu();
+    const GrGLContext& glCtx = gpu->glContext();
+    const GrGLContextInfo& ctxInfo = gpu->ctxInfo();
+    SkString vertShaderSrc(GrGetGLSLVersionDecl(ctxInfo));
+    fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kVertex_Visibility, &vertShaderSrc);
+    fProgramBuilder->appendDecls(fInputs, &vertShaderSrc);
+    fProgramBuilder->appendDecls(fOutputs, &vertShaderSrc);
+    vertShaderSrc.append("void main() {");
+    vertShaderSrc.append(fCode);
+    vertShaderSrc.append("}\n");
+    GrGLuint vertShaderId = GrGLCompileAndAttachShader(glCtx, programId,
+                                                       GR_GL_VERTEX_SHADER, vertShaderSrc,
+                                                       gpu->gpuStats());
+    if (!vertShaderId) {
+        return false;
+    }
+    *shaderIds->append() = vertShaderId;
+    return true;
+}
+
+void GrGLVertexShaderBuilder::emitCodeAfterEffects() {
+    const char* rtAdjustName;
+    fProgramBuilder->fUniformHandles.fRTAdjustmentUni =
+        fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+                             kVec4f_GrSLType,
+                             "rtAdjustment",
+                             &rtAdjustName);
+
+    // Transform from Skia's device coords to GL's normalized device coords.
+    this->codeAppendf(
+        "gl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);",
+        rtAdjustName, rtAdjustName);
+}
+
+void GrGLVertexShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
+    const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
+
+    fPositionVar = &fInputs.push_back();
+    fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "inPosition");
+    if (-1 != header.fLocalCoordAttributeIndex) {
+        fLocalCoordsVar = &fInputs.push_back();
+        fLocalCoordsVar->set(kVec2f_GrSLType,
+                             GrGLShaderVar::kAttribute_TypeModifier,
+                             "inLocalCoords");
+    } else {
+        fLocalCoordsVar = fPositionVar;
+    }
+
+    const char* viewMName;
+    fProgramBuilder->fUniformHandles.fViewMatrixUni =
+            fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+                                 kMat33f_GrSLType,
+                                 "ViewM",
+                                 &viewMName);
+
+    // Transform the position into Skia's device coords.
+    this->codeAppendf("vec3 pos3 = %s * vec3(%s, 1);",
+                      viewMName, fPositionVar->c_str());
+
+    // we output point size in the GS if present
+    if (header.fEmitsPointSize
+#if GR_GL_EXPERIMENTAL_GS
+        && !header.fExperimentalGS
+#endif
+        ) {
+        this->codeAppend("gl_PointSize = 1.0;");
+    }
+
+    if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
+        this->addAttribute(GrShaderVar(color_attribute_name(),
+                                       kVec4f_GrSLType,
+                                       GrShaderVar::kAttribute_TypeModifier));
+        const char *vsName, *fsName;
+        fFullProgramBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
+        this->codeAppendf("%s = %s;", vsName, color_attribute_name());
+        *color = fsName;
+    }
+
+    if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
+        this->addAttribute(GrShaderVar(coverage_attribute_name(),
+                                       kVec4f_GrSLType,
+                                       GrShaderVar::kAttribute_TypeModifier));
+        const char *vsName, *fsName;
+        fFullProgramBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
+        this->codeAppendf("%s = %s;", vsName, coverage_attribute_name());
+        *coverage = fsName;
+    }
+    fEffectAttribOffset = fInputs.count();
+}
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
new file mode 100644
index 0000000..c93b3be
--- /dev/null
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLVertexShader_DEFINED
+#define GrGLVertexShader_DEFINED
+#include "GrGLShaderBuilder.h"
+
+class GrGLProgramBuilder;
+
+class GrGLVertexShaderBuilder : public GrGLFullShaderBuilder {
+public:
+    GrGLVertexShaderBuilder(GrGLFullProgramBuilder* program);
+
+    /*
+     * this call is only for GrGLProgramEffects' internal use
+     */
+    void emitAttributes(const GrGeometryProcessor& gp);
+
+    /**
+     * Are explicit local coordinates provided as input to the vertex shader.
+     */
+    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
+
+    const SkString* getEffectAttributeName(int attributeIndex) const;
+
+    /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
+        as positionAttribute() or it may not be. It depends upon whether the rendering code
+        specified explicit local coords or not in the GrDrawState. */
+    const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
+
+    /** Returns a vertex attribute that represents the vertex position in the VS. This is the
+        pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
+      */
+    const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
+
+private:
+    /*
+     * Add attribute will push a new attribute onto the end.  It will also assert if there is
+     * a duplicate attribute
+     */
+    bool addAttribute(const GrShaderVar& var);
+
+    /*
+     * Internal call for GrGLFullProgramBuilder.addVarying
+     */
+    void addVarying(GrSLType type,
+                   const char* name,
+                   const char** vsOutName);
+
+    /*
+     * private helpers for compilation by GrGLProgramBuilder
+     */
+    void bindProgramLocations(GrGLuint programId);
+    bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
+    void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage);
+    void emitCodeAfterEffects();
+
+    struct AttributePair {
+        void set(int index, const SkString& name) {
+            fIndex = index; fName = name;
+        }
+        int      fIndex;
+        SkString fName;
+    };
+
+    GrGLShaderVar*                      fPositionVar;
+    GrGLShaderVar*                      fLocalCoordsVar;
+    int                                 fEffectAttribOffset;
+
+    friend class GrGLFullProgramBuilder;
+
+    typedef GrGLFullShaderBuilder INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/debug/GrDebugGL.cpp b/src/gpu/gl/debug/GrDebugGL.cpp
index 03ff36d..e5b00c1 100644
--- a/src/gpu/gl/debug/GrDebugGL.cpp
+++ b/src/gpu/gl/debug/GrDebugGL.cpp
@@ -40,7 +40,8 @@
     , fRenderBuffer(NULL)
     , fProgram(NULL)
     , fTexture(NULL)
-    , fVertexArray(NULL)  {
+    , fVertexArray(NULL)
+    , fAbandoned(false) {
 
     for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
 
@@ -111,7 +112,7 @@
 }
 
 void GrDebugGL::setVertexArray(GrVertexArrayObj* vertexArray) {
-    if (NULL != vertexArray) {
+    if (vertexArray) {
         SkASSERT(!vertexArray->getDeleted());
     }
     SkRefCnt_SafeAssign(fVertexArray, vertexArray);
@@ -204,8 +205,10 @@
 
 void GrDebugGL::report() const {
     for (int i = 0; i < fObjects.count(); ++i) {
-        GrAlwaysAssert(0 == fObjects[i]->getRefCount());
         GrAlwaysAssert(0 < fObjects[i]->getHighRefCount());
-        GrAlwaysAssert(fObjects[i]->getDeleted());
+        if (!fAbandoned) {
+            GrAlwaysAssert(0 == fObjects[i]->getRefCount());
+            GrAlwaysAssert(fObjects[i]->getDeleted());
+        }
     }
 }
diff --git a/src/gpu/gl/debug/GrDebugGL.h b/src/gpu/gl/debug/GrDebugGL.h
index ad6edff..9192725 100644
--- a/src/gpu/gl/debug/GrDebugGL.h
+++ b/src/gpu/gl/debug/GrDebugGL.h
@@ -114,6 +114,11 @@
         }
     }
 
+    static void abandon() {
+        SkASSERT(gStaticRefCount > 0);
+        gObj->fAbandoned = true;
+    }
+
 protected:
 
 private:
@@ -132,6 +137,8 @@
     GrTextureUnitObj *fTextureUnits[kDefaultMaxTextureUnits];
     GrVertexArrayObj *fVertexArray;
 
+    bool fAbandoned;
+
     typedef GrFakeRefObj *(*Create)();
 
     static Create gFactoryFunc[kObjTypeCount];
diff --git a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
index 788179c..4bd8f99 100644
--- a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
+++ b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
@@ -256,15 +256,15 @@
 
          for (int i = 0; i < n; ++i) {
 
-             if (NULL != frameBuffer->getColor() &&
+             if (frameBuffer->getColor() &&
                  textures[i] == frameBuffer->getColor()->getID()) {
                  frameBuffer->setColor(NULL);
              }
-             if (NULL != frameBuffer->getDepth() &&
+             if (frameBuffer->getDepth() &&
                  textures[i] == frameBuffer->getDepth()->getID()) {
                  frameBuffer->setDepth(NULL);
              }
-             if (NULL != frameBuffer->getStencil() &&
+             if (frameBuffer->getStencil() &&
                  textures[i] == frameBuffer->getStencil()->getID()) {
                  frameBuffer->setStencil(NULL);
              }
@@ -341,15 +341,15 @@
 
          for (int i = 0; i < n; ++i) {
 
-             if (NULL != frameBuffer->getColor() &&
+             if (frameBuffer->getColor() &&
                  renderBuffers[i] == frameBuffer->getColor()->getID()) {
                  frameBuffer->setColor(NULL);
              }
-             if (NULL != frameBuffer->getDepth() &&
+             if (frameBuffer->getDepth() &&
                  renderBuffers[i] == frameBuffer->getDepth()->getID()) {
                  frameBuffer->setDepth(NULL);
              }
-             if (NULL != frameBuffer->getStencil() &&
+             if (frameBuffer->getStencil() &&
                  renderBuffers[i] == frameBuffer->getStencil()->getID()) {
                  frameBuffer->setStencil(NULL);
              }
@@ -390,7 +390,7 @@
 
      GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
      // A render buffer cannot be attached to the default framebuffer
-     GrAlwaysAssert(NULL != framebuffer);
+     GrAlwaysAssert(framebuffer);
 
      // a renderBufferID of 0 is acceptable - it unbinds the current
      // render buffer
@@ -430,7 +430,7 @@
 
      GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
      // A texture cannot be attached to the default framebuffer
-     GrAlwaysAssert(NULL != framebuffer);
+     GrAlwaysAssert(framebuffer);
 
      // A textureID of 0 is allowed - it unbinds the currently bound texture
      GrTextureObj *texture = GR_FIND(textureID, GrTextureObj,
@@ -566,7 +566,7 @@
 
 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindVertexArray(GrGLuint id) {
     GrVertexArrayObj* array = GR_FIND(id, GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes);
-    GrAlwaysAssert((0 == id) || NULL != array);
+    GrAlwaysAssert((0 == id) || array);
     GrDebugGL::getInstance()->setVertexArray(array);
 }
 
@@ -644,7 +644,7 @@
             break;
     }
 
-    if (NULL != buffer) {
+    if (buffer) {
         GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize());
         GrAlwaysAssert(!buffer->getMapped());
         buffer->setMapped(offset, length);
@@ -695,7 +695,7 @@
             break;
     }
 
-    if (NULL != buffer) {
+    if (buffer) {
         GrAlwaysAssert(buffer->getMapped());
         buffer->resetMapped();
         return GR_GL_TRUE;
@@ -724,7 +724,7 @@
             break;
     }
 
-    if (NULL != buffer) {
+    if (buffer) {
         GrAlwaysAssert(buffer->getMapped());
         GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength());
     } else {
@@ -757,17 +757,17 @@
     switch (value) {
         case GR_GL_BUFFER_MAPPED:
             *params = GR_GL_FALSE;
-            if (NULL != buffer)
+            if (buffer)
                 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
             break;
         case GR_GL_BUFFER_SIZE:
             *params = 0;
-            if (NULL != buffer)
+            if (buffer)
                 *params = SkToInt(buffer->getSize());
             break;
         case GR_GL_BUFFER_USAGE:
             *params = GR_GL_STATIC_DRAW;
-            if (NULL != buffer)
+            if (buffer)
                 *params = buffer->getUsage();
             break;
         default:
@@ -796,6 +796,10 @@
         fWrapped.reset(interface);
     }
 
+    virtual void abandon() const SK_OVERRIDE {
+        GrDebugGL::abandon();
+    }
+
     // TODO: there are some issues w/ wrapping another GL interface inside the
     // debug interface:
     //      Since none of the "gl" methods are member functions they don't get
diff --git a/src/gpu/gl/debug/SkDebugGLContext.cpp b/src/gpu/gl/debug/SkDebugGLContext.cpp
index ae42227..8ea5466 100644
--- a/src/gpu/gl/debug/SkDebugGLContext.cpp
+++ b/src/gpu/gl/debug/SkDebugGLContext.cpp
@@ -8,6 +8,10 @@
 
 #include "gl/SkDebugGLContext.h"
 
-const GrGLInterface* SkDebugGLContext::createGLContext() {
+const GrGLInterface* SkDebugGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
+    if (kGLES_GrGLStandard == forcedGpuAPI) {
+        return NULL;
+    }
+
     return GrGLCreateDebugInterface();
-};
+}
diff --git a/src/gpu/gl/iOS/GrGLCreateNativeInterface_iOS.cpp b/src/gpu/gl/iOS/GrGLCreateNativeInterface_iOS.cpp
index 0408965..ccbc50f 100644
--- a/src/gpu/gl/iOS/GrGLCreateNativeInterface_iOS.cpp
+++ b/src/gpu/gl/iOS/GrGLCreateNativeInterface_iOS.cpp
@@ -1,174 +1,56 @@
 
 /*
- * Copyright 2011 Google Inc.
+ * 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 "gl/GrGLInterface.h"
+#include "gl/GrGLAssembleInterface.h"
+#include <dlfcn.h>
 
-#import <OpenGLES/ES2/gl.h>
-#import <OpenGLES/ES2/glext.h>
+class GLLoader {
+public:
+    GLLoader() {
+        fLibrary = dlopen(
+            "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
+            RTLD_LAZY);
+    }
+
+    ~GLLoader() {
+        if (fLibrary) {
+            dlclose(fLibrary);
+        }
+    }
+
+    void* handle() const {
+        return NULL == fLibrary ? RTLD_DEFAULT : fLibrary;
+    }
+
+private:
+    void* fLibrary;
+};
+
+class GLProcGetter {
+public:
+    GLProcGetter() {}
+
+    GrGLFuncPtr getProc(const char name[]) const {
+        return (GrGLFuncPtr) dlsym(fLoader.handle(), name);
+    }
+    
+private:
+    GLLoader fLoader;
+};
+
+static GrGLFuncPtr ios_get_gl_proc(void* ctx, const char name[]) {
+    SkASSERT(ctx);
+    const GLProcGetter* getter = (const GLProcGetter*) ctx;
+    return getter->getProc(name);
+}
 
 const GrGLInterface* GrGLCreateNativeInterface() {
-    GrGLInterface* interface = SkNEW(GrGLInterface);
-
-    GrGLInterface::Functions* functions = &interface->fFunctions;
-
-    functions->fActiveTexture = glActiveTexture;
-    functions->fAttachShader = glAttachShader;
-    functions->fBindAttribLocation = glBindAttribLocation;
-    functions->fBindBuffer = glBindBuffer;
-    functions->fBindTexture = glBindTexture;
-    functions->fBlendColor = glBlendColor;
-    functions->fBlendFunc = glBlendFunc;
-    functions->fBufferData = (GrGLBufferDataProc)glBufferData;
-    functions->fBufferSubData = (GrGLBufferSubDataProc)glBufferSubData;
-    functions->fClear = glClear;
-    functions->fClearColor = glClearColor;
-    functions->fClearStencil = glClearStencil;
-    functions->fColorMask = glColorMask;
-    functions->fCompileShader = glCompileShader;
-    functions->fCompressedTexImage2D = glCompressedTexImage2D;
-    functions->fCompressedTexSubImage2D = glCompressedTexSubImage2D;
-    functions->fCopyTexSubImage2D = glCopyTexSubImage2D;
-    functions->fCreateProgram = glCreateProgram;
-    functions->fCreateShader = glCreateShader;
-    functions->fCullFace = glCullFace;
-    functions->fDeleteBuffers = glDeleteBuffers;
-    functions->fDeleteProgram = glDeleteProgram;
-    functions->fDeleteShader = glDeleteShader;
-    functions->fDeleteTextures = glDeleteTextures;
-    functions->fDepthMask = glDepthMask;
-    functions->fDisable = glDisable;
-    functions->fDisableVertexAttribArray = glDisableVertexAttribArray;
-    functions->fDrawArrays = glDrawArrays;
-    functions->fDrawBuffer = NULL;
-    functions->fDrawBuffers = NULL;
-    functions->fDrawElements = glDrawElements;
-    functions->fEnable = glEnable;
-    functions->fEnableVertexAttribArray = glEnableVertexAttribArray;
-    functions->fFinish = glFinish;
-    functions->fFlush = glFlush;
-    functions->fFrontFace = glFrontFace;
-    functions->fGenBuffers = glGenBuffers;
-    functions->fGenerateMipmap = glGenerateMipmap;
-    functions->fGetBufferParameteriv = glGetBufferParameteriv;
-    functions->fGetError = glGetError;
-    functions->fGetIntegerv = glGetIntegerv;
-    functions->fGetProgramInfoLog = glGetProgramInfoLog;
-    functions->fGetProgramiv = glGetProgramiv;
-    functions->fGetShaderInfoLog = glGetShaderInfoLog;
-    functions->fGetShaderiv = glGetShaderiv;
-    functions->fGetString = glGetString;
-    functions->fGenTextures = glGenTextures;
-    functions->fGetUniformLocation = glGetUniformLocation;
-    functions->fLineWidth = glLineWidth;
-    functions->fLinkProgram = glLinkProgram;
-    functions->fPixelStorei = glPixelStorei;
-    functions->fReadBuffer = NULL;
-    functions->fReadPixels = glReadPixels;
-    functions->fScissor = glScissor;
-    functions->fShaderSource = (GrGLShaderSourceProc) glShaderSource;
-    functions->fStencilFunc = glStencilFunc;
-    functions->fStencilFuncSeparate = glStencilFuncSeparate;
-    functions->fStencilMask = glStencilMask;
-    functions->fStencilMaskSeparate = glStencilMaskSeparate;
-    functions->fStencilOp = glStencilOp;
-    functions->fStencilOpSeparate = glStencilOpSeparate;
-    // mac uses GLenum for internalFormat param (non-standard)
-    // amounts to int vs. uint.
-    functions->fTexImage2D = (GrGLTexImage2DProc)glTexImage2D;
-#if GL_ARB_texture_storage
-    functions->fTexStorage2D = glTexStorage2D;
-#elif GL_EXT_texture_storage
-    functions->fTexStorage2D = glTexStorage2DEXT;
-#endif
-#if GL_EXT_discard_framebuffer
-    functions->fDiscardFramebuffer = glDiscardFramebufferEXT;
-#endif
-    functions->fTexParameteri = glTexParameteri;
-    functions->fTexParameteriv = glTexParameteriv;
-    functions->fTexSubImage2D = glTexSubImage2D;
-    functions->fUniform1f = glUniform1f;
-    functions->fUniform1i = glUniform1i;
-    functions->fUniform1fv = glUniform1fv;
-    functions->fUniform1iv = glUniform1iv;
-    functions->fUniform2f = glUniform2f;
-    functions->fUniform2i = glUniform2i;
-    functions->fUniform2fv = glUniform2fv;
-    functions->fUniform2iv = glUniform2iv;
-    functions->fUniform3f = glUniform3f;
-    functions->fUniform3i = glUniform3i;
-    functions->fUniform3fv = glUniform3fv;
-    functions->fUniform3iv = glUniform3iv;
-    functions->fUniform4f = glUniform4f;
-    functions->fUniform4i = glUniform4i;
-    functions->fUniform4fv = glUniform4fv;
-    functions->fUniform4iv = glUniform4iv;
-    functions->fUniform4fv = glUniform4fv;
-    functions->fUniformMatrix2fv = glUniformMatrix2fv;
-    functions->fUniformMatrix3fv = glUniformMatrix3fv;
-    functions->fUniformMatrix4fv = glUniformMatrix4fv;
-    functions->fUseProgram = glUseProgram;
-    functions->fVertexAttrib4fv = glVertexAttrib4fv;
-    functions->fVertexAttribPointer = glVertexAttribPointer;
-    functions->fViewport = glViewport;
-    functions->fGenFramebuffers = glGenFramebuffers;
-    functions->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
-    functions->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
-    functions->fBindFramebuffer = glBindFramebuffer;
-    functions->fFramebufferTexture2D = glFramebufferTexture2D;
-    functions->fCheckFramebufferStatus = glCheckFramebufferStatus;
-    functions->fDeleteFramebuffers = glDeleteFramebuffers;
-    functions->fRenderbufferStorage = glRenderbufferStorage;
-    functions->fGenRenderbuffers = glGenRenderbuffers;
-    functions->fDeleteRenderbuffers = glDeleteRenderbuffers;
-    functions->fFramebufferRenderbuffer = glFramebufferRenderbuffer;
-    functions->fBindRenderbuffer = glBindRenderbuffer;
-
-#if GL_OES_mapbuffer
-    functions->fMapBuffer = glMapBufferOES;
-    functions->fUnmapBuffer = glUnmapBufferOES;
-#endif
-
-#if GL_EXT_map_buffer_range || GL_ES_VERSION_3_0
-    functions->fMapBufferRange = glMapBufferRangeEXT;
-    functions->fFlushMappedBufferRange = glFlushMappedBufferRangeEXT;
-#endif
-
-#if GL_APPLE_framebuffer_multisample
-    functions->fRenderbufferStorageMultisampleES2APPLE = glRenderbufferStorageMultisampleAPPLE;
-    functions->fResolveMultisampleFramebuffer = glResolveMultisampleFramebufferAPPLE;
-#endif
-
-#if GL_OES_vertex_array_object
-    functions->fBindVertexArray = glBindVertexArrayOES;
-    functions->fDeleteVertexArrays = glDeleteVertexArraysOES;
-    functions->fGenVertexArrays = glGenVertexArraysOES;
-#endif
-
-#if GL_EXT_debug_marker
-    functions->fInsertEventMarker = glInsertEventMarkerEXT;
-    functions->fPushGroupMarker = glPushGroupMarkerEXT;
-    functions->fPopGroupMarker = glPopGroupMarkerEXT;
-#endif
-
-#if GL_ES_VERSION_3_0 || GL_ARB_invalidate_subdata
-    functions->fInvalidateFramebuffer = glInvalidateFramebuffer;
-    functions->fInvalidateSubFramebuffer = glInvalidateSubFramebuffer;
-#endif
-
-#if GL_ARB_invalidate_subdata
-    functions->fInvalidateBufferData = glInvalidateBufferData;
-    functions->fInvalidateBufferSubData = glInvalidateBufferSubData;
-    functions->fInvalidateTexImage = glInvalidateTexImage;
-    functions->fInvalidateTexSubImage = glInvalidateTexSubImage;
-#endif
-
-    interface->fStandard = kGLES_GrGLStandard;
-    interface->fExtensions.init(kGLES_GrGLStandard, glGetString, NULL, glGetIntegerv);
-
-    return interface;
+    GLProcGetter getter;
+    return GrGLAssembleGLESInterface(&getter, ios_get_gl_proc);
 }
diff --git a/src/gpu/gl/iOS/SkNativeGLContext_iOS.mm b/src/gpu/gl/iOS/SkNativeGLContext_iOS.mm
index a276fd0..1bdaf70 100644
--- a/src/gpu/gl/iOS/SkNativeGLContext_iOS.mm
+++ b/src/gpu/gl/iOS/SkNativeGLContext_iOS.mm
@@ -36,13 +36,20 @@
 }
 
 void SkNativeGLContext::destroyGLContext() {
-    if ([EAGLContext currentContext] == EAGLCTX) {
-        [EAGLContext setCurrentContext:nil];
+    if (fEAGLContext) {
+        if ([EAGLContext currentContext] == EAGLCTX) {
+            [EAGLContext setCurrentContext:nil];
+        }
+        [EAGLCTX release];
+        fEAGLContext = NULL;
     }
-    [EAGLCTX release];
 }
 
-const GrGLInterface* SkNativeGLContext::createGLContext() {
+const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
+    if (kGL_GrGLStandard == forcedGpuAPI) {
+        return NULL;
+    }
+
     fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
     [EAGLContext setCurrentContext:EAGLCTX];
     
@@ -61,4 +68,4 @@
     }
 }
 
-void SkNativeGLContext::swapBuffers() const { }
\ No newline at end of file
+void SkNativeGLContext::swapBuffers() const { }
diff --git a/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp b/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp
index ab3f0ad..a0c50c7 100644
--- a/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp
+++ b/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp
@@ -21,7 +21,7 @@
     }
 
     ~GLLoader() {
-        if (NULL != fLibrary) {
+        if (fLibrary) {
             dlclose(fLibrary);
         }
     }
@@ -47,7 +47,7 @@
 };
 
 static GrGLFuncPtr mac_get_gl_proc(void* ctx, const char name[]) {
-    SkASSERT(NULL != ctx);
+    SkASSERT(ctx);
     const GLProcGetter* getter = (const GLProcGetter*) ctx;
     return getter->getProc(name);
 }
diff --git a/src/gpu/gl/mac/SkNativeGLContext_mac.cpp b/src/gpu/gl/mac/SkNativeGLContext_mac.cpp
index df316d7..f63471c 100644
--- a/src/gpu/gl/mac/SkNativeGLContext_mac.cpp
+++ b/src/gpu/gl/mac/SkNativeGLContext_mac.cpp
@@ -27,13 +27,16 @@
 }
 
 void SkNativeGLContext::destroyGLContext() {
-    if (NULL != fContext) {
+    if (fContext) {
         CGLReleaseContext(fContext);
     }
 }
 
-const GrGLInterface* SkNativeGLContext::createGLContext() {
+const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
     SkASSERT(NULL == fContext);
+    if (kGLES_GrGLStandard == forcedGpuAPI) {
+        return NULL;
+    }
 
     CGLPixelFormatAttribute attributes[] = {
 #if MAC_OS_X_VERSION_10_7
diff --git a/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp b/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp
index a95b6fc..ab48718 100644
--- a/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp
+++ b/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp
@@ -13,7 +13,7 @@
 
 static GrGLFuncPtr osmesa_get(void* ctx, const char name[]) {
     SkASSERT(NULL == ctx);
-    SkASSERT(NULL != OSMesaGetCurrentContext());
+    SkASSERT(OSMesaGetCurrentContext());
     return OSMesaGetProcAddress(name);
 }
 
@@ -21,5 +21,5 @@
     if (NULL == OSMesaGetCurrentContext()) {
         return NULL;
     }
-    return GrGLAssembleGLInterface(NULL, osmesa_get);
+    return GrGLAssembleInterface(NULL, osmesa_get);
 }
diff --git a/src/gpu/gl/mesa/SkMesaGLContext.cpp b/src/gpu/gl/mesa/SkMesaGLContext.cpp
index 0199d12..31402c5 100644
--- a/src/gpu/gl/mesa/SkMesaGLContext.cpp
+++ b/src/gpu/gl/mesa/SkMesaGLContext.cpp
@@ -13,7 +13,7 @@
 
 SkMesaGLContext::AutoContextRestore::AutoContextRestore() {
     fOldContext = (Context)OSMesaGetCurrentContext();
-    if (NULL != (OSMesaContext)fOldContext) {
+    if (fOldContext) {
         OSMesaGetColorBuffer((OSMesaContext)fOldContext,
                               &fOldWidth, &fOldHeight,
                               &fOldFormat, &fOldImage);
@@ -21,7 +21,7 @@
 }
 
 SkMesaGLContext::AutoContextRestore::~AutoContextRestore() {
-    if (NULL != (OSMesaContext)fOldContext) {
+    if (fOldContext) {
         OSMesaMakeCurrent((OSMesaContext)fOldContext, fOldImage,
                           fOldFormat, fOldWidth, fOldHeight);
     }
@@ -53,7 +53,11 @@
 
 static const GrGLint gBOGUS_SIZE = 16;
 
-const GrGLInterface* SkMesaGLContext::createGLContext() {
+const GrGLInterface* SkMesaGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
+    if (kGLES_GrGLStandard == forcedGpuAPI) {
+        return NULL;
+    }
+
     /* Create an RGBA-mode context */
 #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
     /* specify Z, stencil, accum sizes */
diff --git a/src/gpu/gl/nacl/SkNativeGLContext_nacl.cpp b/src/gpu/gl/nacl/SkNativeGLContext_nacl.cpp
index 69a74ca..334be1d 100644
--- a/src/gpu/gl/nacl/SkNativeGLContext_nacl.cpp
+++ b/src/gpu/gl/nacl/SkNativeGLContext_nacl.cpp
@@ -26,7 +26,7 @@
 void SkNativeGLContext::destroyGLContext() {
 }
 
-const GrGLInterface* SkNativeGLContext::createGLContext() {
+const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
     return NULL;
 }
 
diff --git a/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp b/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp
index ddbfe5d..19eec7e 100644
--- a/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp
+++ b/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp
@@ -8,12 +8,13 @@
 
 #include "gl/GrGLInterface.h"
 #include "gl/GrGLAssembleInterface.h"
+#include "gl/GrGLUtil.h"
 
 #include <GL/glx.h>
 
 static GrGLFuncPtr glx_get(void* ctx, const char name[]) {
     SkASSERT(NULL == ctx);
-    SkASSERT(NULL != glXGetCurrentContext());
+    SkASSERT(glXGetCurrentContext());
     return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
 }
 
@@ -21,5 +22,6 @@
     if (NULL == glXGetCurrentContext()) {
         return NULL;
     }
-    return GrGLAssembleGLInterface(NULL, glx_get);
+
+    return GrGLAssembleInterface(NULL, glx_get);
 }
diff --git a/src/gpu/gl/unix/SkNativeGLContext_unix.cpp b/src/gpu/gl/unix/SkNativeGLContext_unix.cpp
index c4bd6f9..bd130b5 100644
--- a/src/gpu/gl/unix/SkNativeGLContext_unix.cpp
+++ b/src/gpu/gl/unix/SkNativeGLContext_unix.cpp
@@ -9,7 +9,7 @@
 
 #include <GL/glu.h>
 
-#define GLX_1_3 1
+/* Note: Skia requires glx 1.3 or newer */
 
 SkNativeGLContext::AutoContextRestore::AutoContextRestore() {
     fOldGLXContext = glXGetCurrentContext();
@@ -18,7 +18,7 @@
 }
 
 SkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
-    if (NULL != fOldDisplay) {
+    if (fOldDisplay) {
         glXMakeCurrent(fOldDisplay, fOldDrawable, fOldGLXContext);
     }
 }
@@ -66,7 +66,7 @@
     }
 }
 
-const GrGLInterface* SkNativeGLContext::createGLContext() {
+const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
     fDisplay = XOpenDisplay(0);
 
     if (!fDisplay) {
@@ -82,7 +82,16 @@
         None
     };
 
-#ifdef GLX_1_3
+    int glx_major, glx_minor;
+
+    // FBConfigs were added in GLX version 1.3.
+    if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) ||
+            ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) {
+        SkDebugf("GLX version 1.3 or higher required.\n");
+        this->destroyGLContext();
+        return NULL;
+    }
+
     //SkDebugf("Getting matching framebuffer configs.\n");
     int fbcount;
     GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay),
@@ -124,36 +133,6 @@
     // Get a visual
     XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc);
     //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid);
-#else
-    int numVisuals;
-    XVisualInfo visTemplate, *visReturn;
-
-    visReturn = XGetVisualInfo(fDisplay, VisualNoMask, &visTemplate, &numVisuals);
-    if (NULL == visReturn)
-    {
-        SkDebugf("Failed to get visual information.\n");
-        this->destroyGLContext();
-        return NULL;
-    }
-
-    int best = -1, best_num_samp = -1;
-
-    for (int i = 0; i < numVisuals; ++i)
-    {
-        int samp_buf, samples;
-
-        glXGetConfig(fDisplay, &visReturn[i], GLX_SAMPLE_BUFFERS, &samp_buf);
-        glXGetConfig(fDisplay, &visReturn[i], GLX_SAMPLES, &samples);
-
-        if (best < 0 || (samp_buf && samples > best_num_samp))
-            best = i, best_num_samp = samples;
-    }
-
-    XVisualInfo temp = visReturn[best];
-    XVisualInfo *vi = &temp;
-
-    XFree(visReturn);
-#endif
 
     fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth);
 
@@ -165,10 +144,8 @@
 
     fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap);
 
-#ifdef GLX_1_3
     // Done with the visual info data
     XFree(vi);
-#endif
 
     // Create the context
 
@@ -187,63 +164,83 @@
     const char *glxExts = glXQueryExtensionsString(
         fDisplay, DefaultScreen(fDisplay)
     );
+
+
     // Check for the GLX_ARB_create_context extension string and the function.
     // If either is not present, use GLX 1.3 context creation method.
-    if (!gluCheckExtension(
-          reinterpret_cast<const GLubyte*>("GLX_ARB_create_context")
-          , reinterpret_cast<const GLubyte*>(glxExts)))
-    {
-        //SkDebugf("GLX_ARB_create_context not found."
-        //       " Using old-style GLX context.\n");
-#ifdef GLX_1_3
-        fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True);
-#else
-        fContext = glXCreateContext(fDisplay, vi, 0, True);
-#endif
-
-    }
-#ifdef GLX_1_3
-    else {
+    if (!gluCheckExtension(reinterpret_cast<const GLubyte*>("GLX_ARB_create_context"),
+                           reinterpret_cast<const GLubyte*>(glxExts))) {
+        if (kGLES_GrGLStandard != forcedGpuAPI) {
+            fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True);
+        }
+    } else {
         //SkDebugf("Creating context.\n");
-
         PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB =
             (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB");
-        int context_attribs[] = {
-            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
-            GLX_CONTEXT_MINOR_VERSION_ARB, 0,
-            //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
-            None
-        };
-        fContext = glXCreateContextAttribsARB(
-            fDisplay, bestFbc, 0, True, context_attribs
-        );
 
-        // Sync to ensure any errors generated are processed.
-        XSync(fDisplay, False);
-        if (!ctxErrorOccurred && fContext) {
-           //SkDebugf( "Created GL 3.0 context.\n" );
+        if (kGLES_GrGLStandard == forcedGpuAPI) {
+            if (gluCheckExtension(
+                    reinterpret_cast<const GLubyte*>("GLX_EXT_create_context_es2_profile"),
+                    reinterpret_cast<const GLubyte*>(glxExts))) {
+                static const int context_attribs_gles[] = {
+                    GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+                    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+                    GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
+                    None
+                };
+                fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True,
+                                                      context_attribs_gles);
+            }
         } else {
+            // Well, unfortunately GLX will not just give us the highest context so instead we have
+            // to do this nastiness
+            for (i = NUM_GL_VERSIONS - 2; i > 0 ; i--) {
+                /* don't bother below GL 3.0 */
+                if (gl_versions[i].major == 3 && gl_versions[i].minor == 0) {
+                    break;
+                }
+                // On Nvidia GPUs, to use Nv Path rendering we need a compatibility profile for the
+                // time being.
+                // TODO when Nvidia implements NVPR on Core profiles, we should start requesting
+                // core here
+                static const int context_attribs_gl[] = {
+                      GLX_CONTEXT_MAJOR_VERSION_ARB, gl_versions[i].major,
+                      GLX_CONTEXT_MINOR_VERSION_ARB, gl_versions[i].minor,
+                      GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+                      None
+                };
+                fContext =
+                        glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True, context_attribs_gl);
+
+                // Sync to ensure any errors generated are processed.
+                XSync(fDisplay, False);
+
+                if (!ctxErrorOccurred && fContext) {
+                    break;
+                }
+                // try again
+                ctxErrorOccurred = false;
+            }
+
             // Couldn't create GL 3.0 context.
             // Fall back to old-style 2.x context.
             // When a context version below 3.0 is requested,
-            // implementations will return the newest context version compatible
-            // with OpenGL versions less than version 3.0.
+            // implementations will return the newest context version
+            // compatible with OpenGL versions less than version 3.0.
+            if (ctxErrorOccurred || !fContext) {
+                static const int context_attribs_gl_fallback[] = {
+                    GLX_CONTEXT_MAJOR_VERSION_ARB, 1,
+                    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+                    None
+                };
 
-            // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
-            context_attribs[1] = 1;
-            // GLX_CONTEXT_MINOR_VERSION_ARB = 0
-            context_attribs[3] = 0;
+                ctxErrorOccurred = false;
 
-            ctxErrorOccurred = false;
-
-            //SkDebugf("Failed to create GL 3.0 context."
-            //       " Using old-style GLX context.\n");
-            fContext = glXCreateContextAttribsARB(
-                fDisplay, bestFbc, 0, True, context_attribs
-            );
+                fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True,
+                                                      context_attribs_gl_fallback);
+            }
         }
     }
-#endif
 
     // Sync to ensure any errors generated are processed.
     XSync(fDisplay, False);
diff --git a/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp b/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp
index 6adaf19..cba380b 100644
--- a/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp
+++ b/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp
@@ -8,6 +8,7 @@
 
 #include "gl/GrGLInterface.h"
 #include "gl/GrGLAssembleInterface.h"
+#include "gl/GrGLUtil.h"
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
@@ -17,7 +18,7 @@
         fModule = LoadLibrary(moduleName);
     }
     ~AutoLibraryUnload() {
-        if (NULL != fModule) {
+        if (fModule) {
             FreeLibrary(fModule);
         }
     }
@@ -31,14 +32,14 @@
 public:
     GLProcGetter() : fGLLib("opengl32.dll") {}
 
-    bool isInitialized() const { return NULL != fGLLib.get(); }
+    bool isInitialized() const { return SkToBool(fGLLib.get()); }
 
     GrGLFuncPtr getProc(const char name[]) const {
         GrGLFuncPtr proc;
-        if (NULL != (proc = (GrGLFuncPtr) GetProcAddress(fGLLib.get(), name))) {
+        if ((proc = (GrGLFuncPtr) GetProcAddress(fGLLib.get(), name))) {
             return proc;
         }
-        if (NULL != (proc = (GrGLFuncPtr) wglGetProcAddress(name))) {
+        if ((proc = (GrGLFuncPtr) wglGetProcAddress(name))) {
             return proc;
         }
         return NULL;
@@ -49,8 +50,8 @@
 };
 
 static GrGLFuncPtr win_get_gl_proc(void* ctx, const char name[]) {
-    SkASSERT(NULL != ctx);
-    SkASSERT(NULL != wglGetCurrentContext());
+    SkASSERT(ctx);
+    SkASSERT(wglGetCurrentContext());
     const GLProcGetter* getter = (const GLProcGetter*) ctx;
     return getter->getProc(name);
 }
@@ -70,5 +71,17 @@
         return NULL;
     }
 
-    return GrGLAssembleGLInterface(&getter, win_get_gl_proc);
+    GrGLGetStringProc getString = (GrGLGetStringProc)getter.getProc("glGetString");
+    if (NULL == getString) {
+        return NULL;
+    }
+    const char* verStr = reinterpret_cast<const char*>(getString(GR_GL_VERSION));
+    GrGLStandard standard = GrGLGetStandardInUseFromString(verStr);
+
+    if (kGLES_GrGLStandard == standard) {
+        return GrGLAssembleGLESInterface(&getter, win_get_gl_proc);
+    } else if (kGL_GrGLStandard == standard) {
+        return GrGLAssembleGLInterface(&getter, win_get_gl_proc);
+    }
+    return NULL;
 }
diff --git a/src/gpu/gl/win/SkNativeGLContext_win.cpp b/src/gpu/gl/win/SkNativeGLContext_win.cpp
index bae97a7..ab66ba4 100644
--- a/src/gpu/gl/win/SkNativeGLContext_win.cpp
+++ b/src/gpu/gl/win/SkNativeGLContext_win.cpp
@@ -7,7 +7,6 @@
  */
 
 #include "gl/SkNativeGLContext.h"
-#include "SkWGL.h"
 
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -28,7 +27,8 @@
 SkNativeGLContext::SkNativeGLContext()
     : fWindow(NULL)
     , fDeviceContext(NULL)
-    , fGlRenderContext(0) {
+    , fGlRenderContext(0)
+    , fPbufferContext(NULL) {
 }
 
 SkNativeGLContext::~SkNativeGLContext() {
@@ -36,18 +36,22 @@
 }
 
 void SkNativeGLContext::destroyGLContext() {
+    SkSafeSetNull(fPbufferContext);
     if (fGlRenderContext) {
         wglDeleteContext(fGlRenderContext);
+        fGlRenderContext = 0;
     }
     if (fWindow && fDeviceContext) {
         ReleaseDC(fWindow, fDeviceContext);
+        fDeviceContext = 0;
     }
     if (fWindow) {
         DestroyWindow(fWindow);
+        fWindow = 0;
     }
 }
 
-const GrGLInterface* SkNativeGLContext::createGLContext() {
+const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
     HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
 
     if (!gWC) {
@@ -85,19 +89,41 @@
         this->destroyGLContext();
         return NULL;
     }
+    // Requesting a Core profile would bar us from using NVPR. So we request
+    // compatibility profile or GL ES.
+    SkWGLContextRequest contextType =
+        kGLES_GrGLStandard == forcedGpuAPI ?
+        kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
 
-    // Requesting a Core profile would bar us from using NVPR. So we pass false.
-    if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false))) {
-        SkDebugf("Could not create rendering context.\n");
-        this->destroyGLContext();
-        return NULL;
+    fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType);
+
+    HDC dc;
+    HGLRC glrc;
+
+    if (NULL == fPbufferContext) {
+        if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, contextType))) {
+            SkDebugf("Could not create rendering context.\n");
+            this->destroyGLContext();
+            return NULL;
+        }
+        dc = fDeviceContext;
+        glrc = fGlRenderContext;
+    } else {
+        ReleaseDC(fWindow, fDeviceContext);
+        fDeviceContext = 0;
+        DestroyWindow(fWindow);
+        fWindow = 0;
+
+        dc = fPbufferContext->getDC();
+        glrc = fPbufferContext->getGLRC();
     }
 
-    if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) {
+    if (!(wglMakeCurrent(dc, glrc))) {
         SkDebugf("Could not set the context.\n");
         this->destroyGLContext();
         return NULL;
     }
+
     const GrGLInterface* interface = GrGLCreateNativeInterface();
     if (NULL == interface) {
         SkDebugf("Could not create GL interface.\n");
@@ -109,13 +135,31 @@
 }
 
 void SkNativeGLContext::makeCurrent() const {
-    if (!wglMakeCurrent(fDeviceContext, fGlRenderContext)) {
+    HDC dc;
+    HGLRC glrc;
+
+    if (NULL == fPbufferContext) {
+        dc = fDeviceContext;
+        glrc = fGlRenderContext;
+    } else {
+        dc = fPbufferContext->getDC();
+        glrc = fPbufferContext->getGLRC();
+    }
+
+    if (!wglMakeCurrent(dc, glrc)) {
         SkDebugf("Could not create rendering context.\n");
     }
 }
 
 void SkNativeGLContext::swapBuffers() const {
-    if (!SwapBuffers(fDeviceContext)) {
+    HDC dc;
+
+    if (NULL == fPbufferContext) {
+        dc = fDeviceContext;
+    } else {
+        dc = fPbufferContext->getDC();
+    }
+    if (!SwapBuffers(dc)) {
         SkDebugf("Could not complete SwapBuffers.\n");
     }
 }
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index e0a13f9..13b6fcd 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -29,13 +29,12 @@
     return id;
 }
 
-void SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
-                   const SkPaint* paint) {
+void SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const {
     as_IB(this)->onDraw(canvas, x, y, paint);
 }
 
 void SkImage::draw(SkCanvas* canvas, const SkRect* src, const SkRect& dst,
-                   const SkPaint* paint) {
+                   const SkPaint* paint) const {
     as_IB(this)->onDrawRectToRect(canvas, src, dst, paint);
 }
 
@@ -78,6 +77,12 @@
     return as_IB(this)->onGetTexture();
 }
 
+SkShader* SkImage::newShader(SkShader::TileMode tileX,
+                             SkShader::TileMode tileY,
+                             const SkMatrix* localMatrix) const {
+    return as_IB(this)->onNewShader(tileX, tileY, localMatrix);
+}
+
 SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const {
     SkBitmap bm;
     if (as_IB(this)->getROPixels(&bm)) {
@@ -89,9 +94,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 static bool raster_canvas_supports(const SkImageInfo& info) {
-    switch (info.fColorType) {
+    switch (info.colorType()) {
         case kN32_SkColorType:
-            return kUnpremul_SkAlphaType != info.fAlphaType;
+            return kUnpremul_SkAlphaType != info.alphaType();
         case kRGB_565_SkColorType:
             return true;
         case kAlpha_8_SkColorType:
@@ -112,9 +117,8 @@
             return false;
         }
     } else {
-        const SkImageInfo info = SkImageInfo::MakeN32Premul(subset.width(), subset.height());
         SkBitmap tmp;
-        if (!tmp.allocPixels(info)) {
+        if (!tmp.tryAllocN32Pixels(subset.width(), subset.height())) {
             return false;
         }
         *bitmap = tmp;
diff --git a/src/image/SkImagePriv.cpp b/src/image/SkImagePriv.cpp
index f5b7858..bde47e7 100644
--- a/src/image/SkImagePriv.cpp
+++ b/src/image/SkImagePriv.cpp
@@ -9,45 +9,6 @@
 #include "SkCanvas.h"
 #include "SkPicture.h"
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType colorType) {
-    switch (colorType) {
-        case kAlpha_8_SkColorType:
-            return SkBitmap::kA8_Config;
-
-        case kARGB_4444_SkColorType:
-            return SkBitmap::kARGB_4444_Config;
-
-        case kRGB_565_SkColorType:
-            return SkBitmap::kRGB_565_Config;
-
-        case kN32_SkColorType:
-            return SkBitmap::kARGB_8888_Config;
-
-        case kIndex_8_SkColorType:
-            return SkBitmap::kIndex8_Config;
-
-        default:
-            // break for unsupported colortypes
-            break;
-    }
-    return SkBitmap::kNo_Config;
-}
-
-SkColorType SkBitmapConfigToColorType(SkBitmap::Config config) {
-    static const SkColorType gCT[] = {
-        kUnknown_SkColorType,   // kNo_Config
-        kAlpha_8_SkColorType,   // kA8_Config
-        kIndex_8_SkColorType,   // kIndex8_Config
-        kRGB_565_SkColorType,   // kRGB_565_Config
-        kARGB_4444_SkColorType, // kARGB_4444_Config
-        kN32_SkColorType,   // kARGB_8888_Config
-    };
-    SkASSERT((unsigned)config < SK_ARRAY_COUNT(gCT));
-    return gCT[config];
-}
-#endif
-
 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
     const SkImageInfo info = bm.info();
     if (kUnknown_SkColorType == info.colorType()) {
diff --git a/src/image/SkImagePriv.h b/src/image/SkImagePriv.h
index 031832b..8990076 100644
--- a/src/image/SkImagePriv.h
+++ b/src/image/SkImagePriv.h
@@ -8,7 +8,6 @@
 #ifndef SkImagePriv_DEFINED
 #define SkImagePriv_DEFINED
 
-#include "SkBitmap.h"
 #include "SkImage.h"
 
 // Call this if you explicitly want to use/share this pixelRef in the image
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index 9fdfcd2..9542ba3 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -14,9 +14,9 @@
 public:
     SkImage_Base(int width, int height) : INHERITED(width, height) {}
 
-    virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) = 0;
+    virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const = 0;
     virtual void onDrawRectToRect(SkCanvas*, const SkRect* src,
-                                  const SkRect& dst, const SkPaint*) = 0;
+                                  const SkRect& dst, const SkPaint*) const = 0;
 
     // Default impl calls onDraw
     virtual bool onReadPixels(SkBitmap*, const SkIRect& subset) const;
@@ -25,12 +25,15 @@
         return NULL;
     }
 
-    virtual GrTexture* onGetTexture() { return NULL; }
+    virtual GrTexture* onGetTexture() const { return NULL; }
 
     // return a read-only copy of the pixels. We promise to not modify them,
     // but only inspect them (or encode them).
     virtual bool getROPixels(SkBitmap*) const { return false; }
 
+    virtual SkShader* onNewShader(SkShader::TileMode,
+                                  SkShader::TileMode,
+                                  const SkMatrix* localMatrix) const { return NULL; };
 private:
     typedef SkImage INHERITED;
 };
diff --git a/src/image/SkImage_Codec.cpp b/src/image/SkImage_Codec.cpp
deleted file mode 100644
index 3d815ce..0000000
--- a/src/image/SkImage_Codec.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkImageDecoder.h"
-#include "SkImage_Base.h"
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkData.h"
-
-class SkImage_Codec : public SkImage_Base {
-public:
-    static SkImage* NewEmpty();
-
-    SkImage_Codec(SkData* encodedData, int width, int height);
-    virtual ~SkImage_Codec();
-
-    virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) SK_OVERRIDE;
-    virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&, const SkPaint*) SK_OVERRIDE;
-
-private:
-    SkData*     fEncodedData;
-    SkBitmap    fBitmap;
-
-    typedef SkImage_Base INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkImage_Codec::SkImage_Codec(SkData* data, int width, int height) : INHERITED(width, height) {
-    fEncodedData = data;
-    fEncodedData->ref();
-}
-
-SkImage_Codec::~SkImage_Codec() {
-    fEncodedData->unref();
-}
-
-void SkImage_Codec::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
-    if (!fBitmap.pixelRef()) {
-        if (!SkImageDecoder::DecodeMemory(fEncodedData->bytes(), fEncodedData->size(), &fBitmap)) {
-            return;
-        }
-    }
-    canvas->drawBitmap(fBitmap, x, y, paint);
-}
-
-void SkImage_Codec::onDrawRectToRect(SkCanvas* canvas, const SkRect* src,
-                                     const SkRect& dst, const SkPaint* paint) {
-    if (!fBitmap.pixelRef()) {
-        if (!SkImageDecoder::DecodeMemory(fEncodedData->bytes(), fEncodedData->size(), &fBitmap)) {
-            return;
-        }
-    }
-    canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkImage* SkImage::NewEncodedData(SkData* data) {
-    if (NULL == data) {
-        return NULL;
-    }
-
-    SkBitmap bitmap;
-    if (!SkImageDecoder::DecodeMemory(data->bytes(), data->size(), &bitmap, kUnknown_SkColorType,
-                                      SkImageDecoder::kDecodeBounds_Mode)) {
-        return NULL;
-    }
-
-    return SkNEW_ARGS(SkImage_Codec, (data, bitmap.width(), bitmap.height()));
-}
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index aa08f44..cf1b493 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -11,7 +11,6 @@
 #include "SkCanvas.h"
 #include "GrContext.h"
 #include "GrTexture.h"
-#include "SkGrPixelRef.h"
 
 class SkImage_Gpu : public SkImage_Base {
 public:
@@ -20,12 +19,19 @@
     explicit SkImage_Gpu(const SkBitmap&);
     virtual ~SkImage_Gpu();
 
-    virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) SK_OVERRIDE;
-    virtual void onDrawRectToRect(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*) SK_OVERRIDE;
-    virtual GrTexture* onGetTexture() SK_OVERRIDE;
+    virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const SK_OVERRIDE;
+    virtual void onDrawRectToRect(SkCanvas*, const SkRect* src, const SkRect& dst,
+                                  const SkPaint*) const SK_OVERRIDE;
+    virtual GrTexture* onGetTexture() const SK_OVERRIDE;
     virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE;
 
-    GrTexture* getTexture() { return fBitmap.getTexture(); }
+    GrTexture* getTexture() const { return fBitmap.getTexture(); }
+
+    virtual SkShader* onNewShader(SkShader::TileMode,
+                                  SkShader::TileMode,
+                                  const SkMatrix* localMatrix) const SK_OVERRIDE;
+
+    virtual bool isOpaque() const SK_OVERRIDE;
 
 private:
     SkBitmap    fBitmap;
@@ -38,23 +44,29 @@
 SkImage_Gpu::SkImage_Gpu(const SkBitmap& bitmap)
     : INHERITED(bitmap.width(), bitmap.height())
     , fBitmap(bitmap) {
-    SkASSERT(NULL != fBitmap.getTexture());
+    SkASSERT(fBitmap.getTexture());
 }
 
 SkImage_Gpu::~SkImage_Gpu() {
 }
 
-void SkImage_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
-                         const SkPaint* paint) {
+SkShader* SkImage_Gpu::onNewShader(SkShader::TileMode tileX,
+                                   SkShader::TileMode tileY,
+                                   const SkMatrix* localMatrix) const
+{
+    return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix);
+}
+
+void SkImage_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const {
     canvas->drawBitmap(fBitmap, x, y, paint);
 }
 
 void SkImage_Gpu::onDrawRectToRect(SkCanvas* canvas, const SkRect* src, const SkRect& dst,
-                         const SkPaint* paint) {
+                                   const SkPaint* paint) const {
     canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
 }
 
-GrTexture* SkImage_Gpu::onGetTexture() {
+GrTexture* SkImage_Gpu::onGetTexture() const {
     return fBitmap.getTexture();
 }
 
@@ -62,6 +74,10 @@
     return fBitmap.copyTo(dst, kN32_SkColorType);
 }
 
+bool SkImage_Gpu::isOpaque() const {
+    return fBitmap.isOpaque();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 SkImage* SkImage::NewTexture(const SkBitmap& bitmap) {
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 68fc1b3..181f194 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -10,7 +10,7 @@
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkData.h"
-#include "SkMallocPixelRef.h"
+#include "SkDecodingImageGenerator.h"
 
 class SkImage_Raster : public SkImage_Base {
 public:
@@ -18,16 +18,16 @@
         const int maxDimension = SK_MaxS32 >> 2;
         const size_t kMaxPixelByteSize = SK_MaxS32;
 
-        if (info.fWidth < 0 || info.fHeight < 0) {
+        if (info.width() < 0 || info.height() < 0) {
             return false;
         }
-        if (info.fWidth > maxDimension || info.fHeight > maxDimension) {
+        if (info.width() > maxDimension || info.height() > maxDimension) {
             return false;
         }
-        if ((unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType) {
+        if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) {
             return false;
         }
-        if ((unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) {
+        if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) {
             return false;
         }
 
@@ -41,7 +41,7 @@
             return false;
         }
 
-        int64_t size = (int64_t)info.fHeight * rowBytes;
+        int64_t size = (int64_t)info.height() * rowBytes;
         if (size > (int64_t)kMaxPixelByteSize) {
             return false;
         }
@@ -53,8 +53,9 @@
     SkImage_Raster(const SkImageInfo&, SkData*, size_t rb);
     virtual ~SkImage_Raster();
 
-    virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) SK_OVERRIDE;
-    virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&, const SkPaint*) SK_OVERRIDE;
+    virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) const SK_OVERRIDE;
+    virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&,
+                                  const SkPaint*) const SK_OVERRIDE;
     virtual bool onReadPixels(SkBitmap*, const SkIRect&) const SK_OVERRIDE;
     virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const SK_OVERRIDE;
     virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE;
@@ -64,6 +65,16 @@
 
     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
 
+    virtual SkShader* onNewShader(SkShader::TileMode,
+                                  SkShader::TileMode,
+                                  const SkMatrix* localMatrix) const SK_OVERRIDE;
+
+    virtual bool isOpaque() const SK_OVERRIDE;
+
+    SkImage_Raster(const SkBitmap& bm)
+        : INHERITED(bm.width(), bm.height())
+        , fBitmap(bm) {}
+
 private:
     SkImage_Raster() : INHERITED(0, 0) {}
 
@@ -90,7 +101,7 @@
 }
 
 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
-    : INHERITED(info.fWidth, info.fHeight)
+    : INHERITED(info.width(), info.height())
 {
     data->ref();
     void* addr = const_cast<void*>(data->data());
@@ -102,7 +113,7 @@
 }
 
 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
-    : INHERITED(info.fWidth, info.fHeight)
+    : INHERITED(info.width(), info.height())
 {
     fBitmap.setInfo(info, rowBytes);
     fBitmap.setPixelRef(pr);
@@ -111,12 +122,17 @@
 
 SkImage_Raster::~SkImage_Raster() {}
 
-void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
+SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
+                                      const SkMatrix* localMatrix) const {
+    return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix);
+}
+
+void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const {
     canvas->drawBitmap(fBitmap, x, y, paint);
 }
 
-void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src,
-                                      const SkRect& dst, const SkPaint* paint) {
+void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src, const SkRect& dst,
+                                      const SkPaint* paint) const {
     canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
 }
 
@@ -132,8 +148,7 @@
     }
 }
 
-const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr,
-                                         size_t* rowBytesPtr) const {
+const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const {
     const SkImageInfo info = fBitmap.info();
     if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) {
         return NULL;
@@ -154,7 +169,7 @@
     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
         return NULL;
     }
-    if (0 == info.fWidth && 0 == info.fHeight) {
+    if (0 == info.width() && 0 == info.height()) {
         return SkImage_Raster::NewEmpty();
     }
     // check this after empty-check
@@ -163,7 +178,7 @@
     }
 
     // Here we actually make a copy of the caller's pixel data
-    SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes));
+    SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.height() * rowBytes));
     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
 }
 
@@ -172,7 +187,7 @@
     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
         return NULL;
     }
-    if (0 == info.fWidth && 0 == info.fHeight) {
+    if (0 == info.width() && 0 == info.height()) {
         return SkImage_Raster::NewEmpty();
     }
     // check this after empty-check
@@ -181,7 +196,7 @@
     }
 
     // did they give us enough data?
-    size_t size = info.fHeight * rowBytes;
+    size_t size = info.height() * rowBytes;
     if (data->size() < size) {
         return NULL;
     }
@@ -189,6 +204,14 @@
     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
 }
 
+SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator) {
+    SkBitmap bitmap;
+    if (!SkInstallDiscardablePixelRef(generator, &bitmap)) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkImage_Raster, (bitmap));
+}
+
 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
                                 size_t rowBytes) {
     return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
@@ -197,3 +220,7 @@
 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
     return ((SkImage_Raster*)image)->getPixelRef();
 }
+
+bool SkImage_Raster::isOpaque() const {
+    return fBitmap.isOpaque();
+}
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index edc6ef5..b10782a 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -9,14 +9,56 @@
 #include "SkImagePriv.h"
 #include "SkCanvas.h"
 
+#include "SkFontLCDConfig.h"
+static SkPixelGeometry compute_default_geometry() {
+    SkFontLCDConfig::LCDOrder order = SkFontLCDConfig::GetSubpixelOrder();
+    if (SkFontLCDConfig::kNONE_LCDOrder == order) {
+        return kUnknown_SkPixelGeometry;
+    } else {
+        // Bit0 is RGB(0), BGR(1)
+        // Bit1 is H(0), V(1)
+        const SkPixelGeometry gGeo[] = {
+            kRGB_H_SkPixelGeometry,
+            kBGR_H_SkPixelGeometry,
+            kRGB_V_SkPixelGeometry,
+            kBGR_V_SkPixelGeometry,
+        };
+        int index = 0;
+        if (SkFontLCDConfig::kBGR_LCDOrder == order) {
+            index |= 1;
+        }
+        if (SkFontLCDConfig::kVertical_LCDOrientation == SkFontLCDConfig::GetSubpixelOrientation()){
+            index |= 2;
+        }
+        return gGeo[index];
+    }
+}
+
+SkSurfaceProps::SkSurfaceProps() : fFlags(0), fPixelGeometry(kUnknown_SkPixelGeometry) {}
+
+SkSurfaceProps::SkSurfaceProps(InitType) : fFlags(0), fPixelGeometry(compute_default_geometry()) {}
+
+SkSurfaceProps::SkSurfaceProps(uint32_t flags, InitType)
+    : fFlags(flags)
+    , fPixelGeometry(compute_default_geometry())
+{}
+
+SkSurfaceProps::SkSurfaceProps(uint32_t flags, SkPixelGeometry pg)
+    : fFlags(flags), fPixelGeometry(pg)
+{}
+
 ///////////////////////////////////////////////////////////////////////////////
 
-SkSurface_Base::SkSurface_Base(int width, int height) : INHERITED(width, height) {
+SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* props)
+    : INHERITED(width, height, props)
+{
     fCachedCanvas = NULL;
     fCachedImage = NULL;
 }
 
-SkSurface_Base::SkSurface_Base(const SkImageInfo& info) : INHERITED(info) {
+SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* props)
+    : INHERITED(info, props)
+{
     fCachedCanvas = NULL;
     fCachedImage = NULL;
 }
@@ -31,11 +73,10 @@
     SkSafeUnref(fCachedCanvas);
 }
 
-void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
-                            const SkPaint* paint) {
+void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
     SkImage* image = this->newImageSnapshot();
     if (image) {
-        image->draw(canvas, x, y, paint);
+        canvas->drawImage(image, x, y, paint);
         image->unref();
     }
 }
@@ -45,7 +86,7 @@
 
     SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
 
-    if (NULL != fCachedImage) {
+    if (fCachedImage) {
         // the surface may need to fork its backend, if its sharing it with
         // the cached image. Note: we only call if there is an outstanding owner
         // on the image (besides us).
@@ -74,15 +115,16 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkSurface::SkSurface(int width, int height) : fWidth(width), fHeight(height) {
+SkSurface::SkSurface(int width, int height, const SkSurfaceProps* props)
+    : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height)
+{
     SkASSERT(fWidth >= 0);
     SkASSERT(fHeight >= 0);
     fGenerationID = 0;
 }
 
-SkSurface::SkSurface(const SkImageInfo& info)
-    : fWidth(info.fWidth)
-    , fHeight(info.fHeight)
+SkSurface::SkSurface(const SkImageInfo& info, const SkSurfaceProps* props)
+    : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(info.width()), fHeight(info.height())
 {
     SkASSERT(fWidth >= 0);
     SkASSERT(fHeight >= 0);
@@ -122,3 +164,50 @@
 const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) {
     return this->getCanvas()->peekPixels(info, rowBytes);
 }
+
+//////////////////////////////////////////////////////////////////////////////////////
+#ifdef SK_SUPPORT_LEGACY_TEXTRENDERMODE
+
+static SkSurfaceProps make_props(SkSurface::TextRenderMode trm) {
+    uint32_t propsFlags = 0;
+    if (SkSurface::kDistanceField_TextRenderMode == trm) {
+        propsFlags |= SkSurfaceProps::kUseDistanceFieldFonts_Flag;
+    }
+    return SkSurfaceProps(propsFlags, SkSurfaceProps::kLegacyFontHost_InitType);
+}
+
+SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, TextRenderMode trm) {
+    SkSurfaceProps props = make_props(trm);
+    return NewRenderTargetDirect(target, &props);
+}
+
+SkSurface* SkSurface::NewRenderTarget(GrContext* gr, const SkImageInfo& info, int sampleCount,
+                                      TextRenderMode trm) {
+    SkSurfaceProps props = make_props(trm);
+    return NewRenderTarget(gr, info, sampleCount, &props);
+}
+
+SkSurface* SkSurface::NewScratchRenderTarget(GrContext* gr, const SkImageInfo& info, int sampleCount,
+                                             TextRenderMode trm) {
+    SkSurfaceProps props = make_props(trm);
+    return NewScratchRenderTarget(gr, info, sampleCount, &props);
+}
+
+#endif
+
+#if !SK_SUPPORT_GPU
+
+SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*) {
+    return NULL;
+}
+
+SkSurface* SkSurface::NewRenderTarget(GrContext*, const SkImageInfo&, int, const SkSurfaceProps*) {
+    return NULL;
+}
+
+SkSurface* SkSurface::NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+                                             const SkSurfaceProps*) {
+    return NULL;
+}
+
+#endif
diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h
index 2314341..4da4cfb 100644
--- a/src/image/SkSurface_Base.h
+++ b/src/image/SkSurface_Base.h
@@ -8,13 +8,14 @@
 #ifndef SkSurface_Base_DEFINED
 #define SkSurface_Base_DEFINED
 
-#include "SkSurface.h"
 #include "SkCanvas.h"
+#include "SkSurface.h"
+#include "SkSurfacePriv.h"
 
 class SkSurface_Base : public SkSurface {
 public:
-    SkSurface_Base(int width, int height);
-    explicit SkSurface_Base(const SkImageInfo&);
+    SkSurface_Base(int width, int height, const SkSurfaceProps*);
+    SkSurface_Base(const SkImageInfo&, const SkSurfaceProps*);
     virtual ~SkSurface_Base();
 
     /**
@@ -79,7 +80,7 @@
 SkCanvas* SkSurface_Base::getCachedCanvas() {
     if (NULL == fCachedCanvas) {
         fCachedCanvas = this->onNewCanvas();
-        if (NULL != fCachedCanvas) {
+        if (fCachedCanvas) {
             fCachedCanvas->setSurfaceBase(this);
         }
     }
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index a34b774..024c151 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -14,7 +14,7 @@
 public:
     SK_DECLARE_INST_COUNT(SkSurface_Gpu)
 
-    SkSurface_Gpu(GrRenderTarget*, bool cached, TextRenderMode trm);
+    SkSurface_Gpu(GrRenderTarget*, bool cached, const SkSurfaceProps*, bool doClear);
     virtual ~SkSurface_Gpu();
 
     virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
@@ -33,14 +33,16 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkSurface_Gpu::SkSurface_Gpu(GrRenderTarget* renderTarget, bool cached, TextRenderMode trm)
-        : INHERITED(renderTarget->width(), renderTarget->height()) {
-    int flags = 0;
-    flags |= cached ? SkGpuDevice::kCached_Flag : 0;
-    flags |= (kDistanceField_TextRenderMode == trm) ? SkGpuDevice::kDFFonts_Flag : 0;
-    fDevice = SkGpuDevice::Create(renderTarget, flags);
+SkSurface_Gpu::SkSurface_Gpu(GrRenderTarget* renderTarget, bool cached, const SkSurfaceProps* props,
+                             bool doClear)
+        : INHERITED(renderTarget->width(), renderTarget->height(), props)
+{
+    int deviceFlags = 0;
+    deviceFlags |= cached ? SkGpuDevice::kCached_Flag : 0;
+    deviceFlags |= this->props().isUseDistanceFieldFonts() ? SkGpuDevice::kDFFonts_Flag : 0;
+    fDevice = SkGpuDevice::Create(renderTarget, this->props(), deviceFlags);
 
-    if (kRGB_565_GrPixelConfig != renderTarget->config()) {
+    if (kRGB_565_GrPixelConfig != renderTarget->config() && doClear) {
         fDevice->clear(0x0);
     }
 }
@@ -50,13 +52,17 @@
 }
 
 SkCanvas* SkSurface_Gpu::onNewCanvas() {
-    return SkNEW_ARGS(SkCanvas, (fDevice));
+    SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags;
+    // When we think this works...
+//    flags |= SkCanvas::kConservativeRasterClip_InitFlag;
+
+    return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), flags));
 }
 
 SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) {
     GrRenderTarget* rt = fDevice->accessRenderTarget();
     int sampleCount = rt->numSamples();
-    return SkSurface::NewRenderTarget(fDevice->context(), info, sampleCount);
+    return SkSurface::NewRenderTarget(fDevice->context(), info, sampleCount, &this->props());
 }
 
 SkImage* SkSurface_Gpu::onNewImageSnapshot() {
@@ -74,7 +80,7 @@
 void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) {
     GrRenderTarget* rt = fDevice->accessRenderTarget();
     // are we sharing our render target with the image?
-    SkASSERT(NULL != this->getCachedImage());
+    SkASSERT(this->getCachedImage());
     if (rt->asTexture() == SkTextureImageGetTexture(this->getCachedImage())) {
         // We call createCompatibleDevice because it uses the texture cache. This isn't
         // necessarily correct (http://skbug.com/2252), but never using the cache causes
@@ -85,7 +91,7 @@
         if (kRetain_ContentChangeMode == mode) {
             fDevice->context()->copyTexture(rt->asTexture(), newDevice->accessRenderTarget());
         }
-        SkASSERT(NULL != this->getCachedCanvas());
+        SkASSERT(this->getCachedCanvas());
         SkASSERT(this->getCachedCanvas()->getDevice() == fDevice);
 
         this->getCachedCanvas()->setRootDevice(newDevice);
@@ -101,15 +107,15 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, TextRenderMode trm) {
+SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
     if (NULL == target) {
         return NULL;
     }
-    return SkNEW_ARGS(SkSurface_Gpu, (target, false, trm));
+    return SkNEW_ARGS(SkSurface_Gpu, (target, false, props, false));
 }
 
 SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImageInfo& info, int sampleCount,
-                                      TextRenderMode trm) {
+                                      const SkSurfaceProps* props) {
     if (NULL == ctx) {
         return NULL;
     }
@@ -126,11 +132,11 @@
         return NULL;
     }
 
-    return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), false, trm));
+    return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), false, props, true));
 }
 
 SkSurface* SkSurface::NewScratchRenderTarget(GrContext* ctx, const SkImageInfo& info,
-                                             int sampleCount, TextRenderMode trm) {
+                                             int sampleCount, const SkSurfaceProps* props) {
     if (NULL == ctx) {
         return NULL;
     }
@@ -148,5 +154,5 @@
         return NULL;
     }
 
-    return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), true, trm));
+    return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), true, props, true));
 }
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index 0b6efe1..cd4f049 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -17,8 +17,10 @@
 public:
     static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue);
 
-    SkSurface_Raster(const SkImageInfo&, void*, size_t rb);
-    SkSurface_Raster(SkPixelRef*);
+    SkSurface_Raster(const SkImageInfo&, void*, size_t rb,
+                     void (*releaseProc)(void* pixels, void* context), void* context,
+                     const SkSurfaceProps*);
+    SkSurface_Raster(SkPixelRef*, const SkSurfaceProps*);
 
     virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
     virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
@@ -40,7 +42,7 @@
     static const size_t kMaxTotalSize = SK_MaxS32;
 
     int shift = 0;
-    switch (info.fColorType) {
+    switch (info.colorType()) {
         case kAlpha_8_SkColorType:
             shift = 0;
             break;
@@ -58,7 +60,7 @@
         return true;
     }
 
-    uint64_t minRB = (uint64_t)info.fWidth << shift;
+    uint64_t minRB = (uint64_t)info.width() << shift;
     if (minRB > rowBytes) {
         return false;
     }
@@ -68,7 +70,7 @@
         return false;
     }
 
-    uint64_t size = sk_64_mul(info.fHeight, rowBytes);
+    uint64_t size = sk_64_mul(info.height(), rowBytes);
     if (size > kMaxTotalSize) {
         return false;
     }
@@ -76,15 +78,17 @@
     return true;
 }
 
-SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb)
-    : INHERITED(info)
+SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb,
+                                   void (*releaseProc)(void* pixels, void* context), void* context,
+                                   const SkSurfaceProps* props)
+    : INHERITED(info, props)
 {
-    fBitmap.installPixels(info, pixels, rb);
+    fBitmap.installPixels(info, pixels, rb, NULL, releaseProc, context);
     fWeOwnThePixels = false;    // We are "Direct"
 }
 
-SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr)
-    : INHERITED(pr->info().fWidth, pr->info().fHeight)
+SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props)
+    : INHERITED(pr->info().width(), pr->info().height(), props)
 {
     const SkImageInfo& info = pr->info();
 
@@ -98,7 +102,7 @@
 }
 
 SkCanvas* SkSurface_Raster::onNewCanvas() {
-    return SkNEW_ARGS(SkCanvas, (fBitmap));
+    return SkNEW_ARGS(SkCanvas, (fBitmap, this->props()));
 }
 
 SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) {
@@ -116,7 +120,7 @@
 
 void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) {
     // are we sharing pixelrefs with the image?
-    SkASSERT(NULL != this->getCachedImage());
+    SkASSERT(this->getCachedImage());
     if (SkBitmapImageGetPixelRef(this->getCachedImage()) == fBitmap.pixelRef()) {
         SkASSERT(fWeOwnThePixels);
         if (kDiscard_ContentChangeMode == mode) {
@@ -129,25 +133,35 @@
         // Now fBitmap is a deep copy of itself (and therefore different from
         // what is being used by the image. Next we update the canvas to use
         // this as its backend, so we can't modify the image's pixels anymore.
-        SkASSERT(NULL != this->getCachedCanvas());
+        SkASSERT(this->getCachedCanvas());
         this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap);
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkSurface* SkSurface::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) {
-    if (!SkSurface_Raster::Valid(info, rowBytes)) {
+SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void* pixels, size_t rb,
+                                                 void (*releaseProc)(void* pixels, void* context),
+                                                 void* context, const SkSurfaceProps* props) {
+    if (NULL == releaseProc) {
+        context = NULL;
+    }
+    if (!SkSurface_Raster::Valid(info, rb)) {
         return NULL;
     }
     if (NULL == pixels) {
         return NULL;
     }
-
-    return SkNEW_ARGS(SkSurface_Raster, (info, pixels, rowBytes));
+    
+    return SkNEW_ARGS(SkSurface_Raster, (info, pixels, rb, releaseProc, context, props));
 }
 
-SkSurface* SkSurface::NewRaster(const SkImageInfo& info) {
+SkSurface* SkSurface::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes,
+                                      const SkSurfaceProps* props) {
+    return NewRasterDirectReleaseProc(info, pixels, rowBytes, NULL, NULL, props);
+}
+
+SkSurface* SkSurface::NewRaster(const SkImageInfo& info, const SkSurfaceProps* props) {
     if (!SkSurface_Raster::Valid(info)) {
         return NULL;
     }
@@ -156,5 +170,5 @@
     if (NULL == pr.get()) {
         return NULL;
     }
-    return SkNEW_ARGS(SkSurface_Raster, (pr));
+    return SkNEW_ARGS(SkSurface_Raster, (pr, props));
 }
diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp
index 88cdef9..3b5cb78 100644
--- a/src/images/SkDecodingImageGenerator.cpp
+++ b/src/images/SkDecodingImageGenerator.cpp
@@ -69,7 +69,7 @@
     virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) {
         if (NULL == fTarget || !equal_modulo_alpha(fInfo, bm->info())) {
             // Call default allocator.
-            return bm->allocPixels(NULL, ct);
+            return bm->tryAllocPixels(NULL, ct);
         }
 
         // TODO(halcanary): verify that all callers of this function
@@ -132,21 +132,17 @@
 SkData* DecodingImageGenerator::onRefEncodedData() {
     // This functionality is used in `gm --serialize`
     // Does not encode options.
-    if (fData != NULL) {
-        return SkSafeRef(fData);
+    if (NULL == fData) {
+        // TODO(halcanary): SkStreamRewindable needs a refData() function
+        // which returns a cheap copy of the underlying data.
+        if (!fStream->rewind()) {
+            return NULL;
+        }
+        size_t length = fStream->getLength();
+        if (length) {
+            fData = SkData::NewFromStream(fStream, length);
+        }
     }
-    // TODO(halcanary): SkStreamRewindable needs a refData() function
-    // which returns a cheap copy of the underlying data.
-    if (!fStream->rewind()) {
-        return NULL;
-    }
-    size_t length = fStream->getLength();
-    if (0 == length) {
-        return NULL;
-    }
-    void* buffer = sk_malloc_flags(length, 0);
-    SkCheckResult(fStream->read(buffer, length), length);
-    fData = SkData::NewFromMalloc(buffer, length);
     return SkSafeRef(fData);
 }
 
@@ -167,8 +163,7 @@
     }
     decoder->setDitherImage(fDitherImage);
     decoder->setSampleSize(fSampleSize);
-    decoder->setRequireUnpremultipliedColors(
-            info.fAlphaType == kUnpremul_SkAlphaType);
+    decoder->setRequireUnpremultipliedColors(info.alphaType() == kUnpremul_SkAlphaType);
 
     SkBitmap bitmap;
     TargetAllocator allocator(fInfo, pixels, rowBytes);
@@ -240,14 +235,20 @@
             SkASSERT(bitmap.colorType() != opts.fRequestedColorType);
             return NULL;  // Can not translate to needed config.
         }
-        info.fColorType = opts.fRequestedColorType;
+        info = info.makeColorType(opts.fRequestedColorType);
     }
 
-    if (opts.fRequireUnpremul && info.fAlphaType != kOpaque_SkAlphaType) {
-        info.fAlphaType = kUnpremul_SkAlphaType;
+    if (opts.fRequireUnpremul && info.alphaType() != kOpaque_SkAlphaType) {
+        info = info.makeAlphaType(kUnpremul_SkAlphaType);
     }
+
+    SkAlphaType newAlphaType = info.alphaType();
+    if (!SkColorTypeValidateAlphaType(info.colorType(), info.alphaType(), &newAlphaType)) {
+        return NULL;
+    }
+
     return SkNEW_ARGS(DecodingImageGenerator,
-                      (data, autoStream.detach(), info,
+                      (data, autoStream.detach(), info.makeAlphaType(newAlphaType),
                        opts.fSampleSize, opts.fDitherImage));
 }
 
diff --git a/src/images/SkForceLinking.cpp b/src/images/SkForceLinking.cpp
index 2c9a389..4f604a2 100644
--- a/src/images/SkForceLinking.cpp
+++ b/src/images/SkForceLinking.cpp
@@ -18,9 +18,13 @@
         CreateWEBPImageDecoder();
         CreateBMPImageDecoder();
         CreateICOImageDecoder();
+        CreateWBMPImageDecoder();
+        // Only link hardware texture codecs on platforms that build them. See images.gyp
+#ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
         CreatePKMImageDecoder();
         CreateKTXImageDecoder();
-        CreateWBMPImageDecoder();
+        CreateASTCImageDecoder();
+#endif
         // Only link GIF and PNG on platforms that build them. See images.gyp
 #if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_WIN) && !defined(SK_BUILD_FOR_NACL) \
         && !defined(SK_BUILD_FOR_IOS)
@@ -29,6 +33,9 @@
 #if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_WIN) && !defined(SK_BUILD_FOR_IOS)
         CreatePNGImageDecoder();
 #endif
+#if defined(SK_BUILD_FOR_IOS)
+        CreatePNGImageEncoder_IOS();
+#endif
         return -1;
     }
     return 0;
diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp
index fe61906..b25e7db 100644
--- a/src/images/SkImageDecoder.cpp
+++ b/src/images/SkImageDecoder.cpp
@@ -22,10 +22,8 @@
     , fAllocator(NULL)
     , fSampleSize(1)
     , fDefaultPref(kUnknown_SkColorType)
+    , fPreserveSrcDepth(false)
     , fDitherImage(true)
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-    , fUsePrefTable(false)
-#endif
     , fSkipWritingZeroes(false)
     , fPreferQualityOverSpeed(false)
     , fRequireUnpremultipliedColors(false) {
@@ -49,13 +47,7 @@
 #endif
     other->setAllocator(fAllocator);
     other->setSampleSize(fSampleSize);
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-    if (fUsePrefTable) {
-        other->setPrefConfigTable(fPrefTable);
-    } else {
-        other->fDefaultPref = fDefaultPref;
-    }
-#endif
+    other->setPreserveSrcDepth(fPreserveSrcDepth);
     other->setDitherImage(fDitherImage);
     other->setSkipWritingZeroes(fSkipWritingZeroes);
     other->setPreferQualityOverSpeed(fPreferQualityOverSpeed);
@@ -84,6 +76,8 @@
             return "PKM";
         case kKTX_Format:
             return "KTX";
+        case kASTC_Format:
+            return "ASTC";
         case kJPEG_Format:
             return "JPEG";
         case kPNG_Format:
@@ -139,44 +133,26 @@
 
 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
                                    SkColorTable* ctable) const {
-    return bitmap->allocPixels(fAllocator, ctable);
+    return bitmap->tryAllocPixels(fAllocator, ctable);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-void SkImageDecoder::setPrefConfigTable(const PrefConfigTable& prefTable) {
-    fUsePrefTable = true;
-    fPrefTable = prefTable;
-}
-#endif
-
-// TODO: use colortype in fPrefTable, fDefaultPref so we can stop using SkBitmapConfigToColorType()
-//
 SkColorType SkImageDecoder::getPrefColorType(SrcDepth srcDepth, bool srcHasAlpha) const {
     SkColorType ct = fDefaultPref;
-#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
-
-    if (fUsePrefTable) {
-        // Until we kill or change the PrefTable, we have to go into Config land for a moment.
-        SkBitmap::Config config = SkBitmap::kNo_Config;
+    if (fPreserveSrcDepth) {
         switch (srcDepth) {
             case kIndex_SrcDepth:
-                config = srcHasAlpha ? fPrefTable.fPrefFor_8Index_YesAlpha_src
-                                     : fPrefTable.fPrefFor_8Index_NoAlpha_src;
+                ct = kIndex_8_SkColorType;
                 break;
             case k8BitGray_SrcDepth:
-                config = fPrefTable.fPrefFor_8Gray_src;
+                ct = kN32_SkColorType;
                 break;
             case k32Bit_SrcDepth:
-                config = srcHasAlpha ? fPrefTable.fPrefFor_8bpc_YesAlpha_src
-                                     : fPrefTable.fPrefFor_8bpc_NoAlpha_src;
+                ct = kN32_SkColorType;
                 break;
         }
-        // now return to SkColorType land
-        ct = SkBitmapConfigToColorType(config);
     }
-#endif
     return ct;
 }
 
@@ -295,7 +271,7 @@
     bool success = false;
     SkImageDecoder* codec = SkImageDecoder::Factory(stream);
 
-    if (NULL != codec) {
+    if (codec) {
         success = codec->decode(stream, bm, pref, mode);
         if (success && format) {
             *format = codec->getFormat();
diff --git a/src/images/SkImageDecoder_astc.cpp b/src/images/SkImageDecoder_astc.cpp
new file mode 100644
index 0000000..79e9804
--- /dev/null
+++ b/src/images/SkImageDecoder_astc.cpp
@@ -0,0 +1,209 @@
+/*
+ * 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 "SkEndian.h"
+#include "SkColorPriv.h"
+#include "SkImageDecoder.h"
+#include "SkScaledBitmapSampler.h"
+#include "SkStream.h"
+#include "SkStreamPriv.h"
+#include "SkTypes.h"
+
+#include "SkTextureCompressor.h"
+
+class SkASTCImageDecoder : public SkImageDecoder {
+public:
+    SkASTCImageDecoder() { }
+
+    virtual Format getFormat() const SK_OVERRIDE {
+        return kASTC_Format;
+    }
+
+protected:
+    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE;
+
+private:
+    typedef SkImageDecoder INHERITED;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static const uint32_t kASTCMagicNumber = 0x5CA1AB13;
+
+static inline int read_24bit(const uint8_t* buf) {
+    // Assume everything is little endian...
+    return
+        static_cast<int>(buf[0]) |
+        (static_cast<int>(buf[1]) << 8) |
+        (static_cast<int>(buf[2]) << 16);
+}
+
+bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
+    SkAutoMalloc autoMal;
+    const size_t length = SkCopyStreamToStorage(&autoMal, stream);
+    if (0 == length) {
+        return false;
+    }
+
+    unsigned char* buf = (unsigned char*)autoMal.get();
+
+    // Make sure that the magic header is there...
+    SkASSERT(SkEndian_SwapLE32(*(reinterpret_cast<uint32_t*>(buf))) == kASTCMagicNumber);
+
+    // Advance past the magic header
+    buf += 4;
+
+    const int blockDimX = buf[0];
+    const int blockDimY = buf[1];
+    const int blockDimZ = buf[2];
+
+    if (1 != blockDimZ) {
+        // We don't support decoding 3D
+        return false;
+    }
+
+    // Choose the proper ASTC format
+    SkTextureCompressor::Format astcFormat;
+    if (4 == blockDimX && 4 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_4x4_Format;
+    } else if (5 == blockDimX && 4 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_5x4_Format;
+    } else if (5 == blockDimX && 5 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_5x5_Format;
+    } else if (6 == blockDimX && 5 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_6x5_Format;
+    } else if (6 == blockDimX && 6 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_6x6_Format;
+    } else if (8 == blockDimX && 5 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_8x5_Format;
+    } else if (8 == blockDimX && 6 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_8x6_Format;
+    } else if (8 == blockDimX && 8 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_8x8_Format;
+    } else if (10 == blockDimX && 5 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_10x5_Format;
+    } else if (10 == blockDimX && 6 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_10x6_Format;
+    } else if (10 == blockDimX && 8 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_10x8_Format;
+    } else if (10 == blockDimX && 10 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_10x10_Format;
+    } else if (12 == blockDimX && 10 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_12x10_Format;
+    } else if (12 == blockDimX && 12 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_12x12_Format;
+    } else {
+        // We don't support any other block dimensions..
+        return false;
+    }
+
+    // Advance buf past the block dimensions
+    buf += 3;
+
+    // Read the width/height/depth from the buffer...
+    const int width = read_24bit(buf);
+    const int height = read_24bit(buf + 3);
+    const int depth = read_24bit(buf + 6);
+
+    if (1 != depth) {
+        // We don't support decoding 3D.
+        return false;
+    }
+
+    // Advance the buffer past the image dimensions
+    buf += 9;
+
+#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
+    // should we allow the Chooser (if present) to pick a config for us???
+    if (!this->chooseFromOneChoice(kN32_SkColorType, width, height)) {
+        return false;
+    }
+#endif
+
+    // Setup the sampler...
+    SkScaledBitmapSampler sampler(width, height, this->getSampleSize());
+
+    // Determine the alpha of the bitmap...
+    SkAlphaType alphaType = kOpaque_SkAlphaType;
+    if (this->getRequireUnpremultipliedColors()) {
+        alphaType = kUnpremul_SkAlphaType;
+    } else {
+        alphaType = kPremul_SkAlphaType;
+    }
+
+    // Set the config...
+    bm->setInfo(SkImageInfo::MakeN32(sampler.scaledWidth(), sampler.scaledHeight(), alphaType));
+
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        return true;
+    }
+
+    if (!this->allocPixelRef(bm, NULL)) {
+        return false;
+    }
+
+    // Lock the pixels, since we're about to write to them...
+    SkAutoLockPixels alp(*bm);
+
+    if (!sampler.begin(bm, SkScaledBitmapSampler::kRGBA, *this)) {
+        return false;
+    }
+
+    // ASTC Data is encoded as RGBA pixels, so we should extract it as such
+    int nPixels = width * height;
+    SkAutoMalloc outRGBAData(nPixels * 4);
+    uint8_t *outRGBADataPtr = reinterpret_cast<uint8_t *>(outRGBAData.get());
+
+    // Decode ASTC
+    if (!SkTextureCompressor::DecompressBufferFromFormat(
+            outRGBADataPtr, width*4, buf, width, height, astcFormat)) {
+    }
+
+    // Set each of the pixels...
+    const int srcRowBytes = width * 4;
+    const int dstHeight = sampler.scaledHeight();
+    const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBADataPtr);
+    srcRow += sampler.srcY0() * srcRowBytes;
+    for (int y = 0; y < dstHeight; ++y) {
+        sampler.next(srcRow);
+        srcRow += sampler.srcDY() * srcRowBytes;
+    }
+
+    return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(ASTCImageDecoder);
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static bool is_astc(SkStreamRewindable* stream) {
+    // Read the ASTC header and make sure it's valid.
+    uint32_t magic;
+    if (stream->read((void*)&magic, 4) != 4) {
+        return false;
+    }
+
+    return kASTCMagicNumber == SkEndian_SwapLE32(magic);
+}
+
+static SkImageDecoder* sk_libastc_dfactory(SkStreamRewindable* stream) {
+    if (is_astc(stream)) {
+        return SkNEW(SkASTCImageDecoder);
+    }
+    return NULL;
+}
+
+static SkImageDecoder_DecodeReg gReg(sk_libastc_dfactory);
+
+static SkImageDecoder::Format get_format_astc(SkStreamRewindable* stream) {
+    if (is_astc(stream)) {
+        return SkImageDecoder::kASTC_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
+static SkImageDecoder_FormatReg gFormatReg(get_format_astc);
diff --git a/src/images/SkImageDecoder_ktx.cpp b/src/images/SkImageDecoder_ktx.cpp
index effc1ed..20c8bbc 100644
--- a/src/images/SkImageDecoder_ktx.cpp
+++ b/src/images/SkImageDecoder_ktx.cpp
@@ -10,7 +10,7 @@
 #include "SkPixelRef.h"
 #include "SkScaledBitmapSampler.h"
 #include "SkStream.h"
-#include "SkStreamHelpers.h"
+#include "SkStreamPriv.h"
 #include "SkTypes.h"
 
 #include "ktx.h"
@@ -49,7 +49,7 @@
 
 bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
     // TODO: Implement SkStream::copyToData() that's cheap for memory and file streams
-    SkAutoDataUnref data(CopyStreamToData(stream));
+    SkAutoDataUnref data(SkCopyStreamToData(stream));
     if (NULL == data) {
         return false;
     }
@@ -91,12 +91,39 @@
         }
     }
 
-    // Set the config...
-    bm->setInfo(SkImageInfo::MakeN32(sampler.scaledWidth(), sampler.scaledHeight(), alphaType));
+    // Search through the compressed formats to see if the KTX file is holding
+    // compressed data
+    bool ktxIsCompressed = false;
+    SkTextureCompressor::Format ktxCompressedFormat;
+    for (int i = 0; i < SkTextureCompressor::kFormatCnt; ++i) {
+        SkTextureCompressor::Format fmt = static_cast<SkTextureCompressor::Format>(i);
+        if (ktxFile.isCompressedFormat(fmt)) {
+            ktxIsCompressed = true;
+            ktxCompressedFormat = fmt;
+            break;
+        }
+    }
+
+    // If the compressed format is a grayscale image, then setup the bitmap properly...
+    bool isCompressedAlpha = ktxIsCompressed &&
+        ((SkTextureCompressor::kLATC_Format == ktxCompressedFormat) ||
+         (SkTextureCompressor::kR11_EAC_Format == ktxCompressedFormat));
+
+    // Set the image dimensions and underlying pixel type.
+    if (isCompressedAlpha) {
+        const int w = sampler.scaledWidth();
+        const int h = sampler.scaledHeight();
+        bm->setInfo(SkImageInfo::MakeA8(w, h));
+    } else {
+        const int w = sampler.scaledWidth();
+        const int h = sampler.scaledHeight();
+        bm->setInfo(SkImageInfo::MakeN32(w, h, alphaType));
+    }
+    
     if (SkImageDecoder::kDecodeBounds_Mode == mode) {
         return true;
     }
-    
+
     // If we've made it this far, then we know how to grok the data.
     if (!this->allocPixelRef(bm, NULL)) {
         return false;
@@ -105,7 +132,36 @@
     // Lock the pixels, since we're about to write to them...
     SkAutoLockPixels alp(*bm);
 
-    if (ktxFile.isETC1()) {
+    if (isCompressedAlpha) {
+        if (!sampler.begin(bm, SkScaledBitmapSampler::kGray, *this)) {
+            return false;
+        }
+
+        // Alpha data is only a single byte per pixel.
+        int nPixels = width * height;
+        SkAutoMalloc outRGBData(nPixels);
+        uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get());
+
+        // Decode the compressed format
+        const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData());
+        if (!SkTextureCompressor::DecompressBufferFromFormat(
+                outRGBDataPtr, width, buf, width, height, ktxCompressedFormat)) {
+            return false;
+        }
+
+        // Set each of the pixels...
+        const int srcRowBytes = width;
+        const int dstHeight = sampler.scaledHeight();
+        const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBDataPtr);
+        srcRow += sampler.srcY0() * srcRowBytes;
+        for (int y = 0; y < dstHeight; ++y) {
+            sampler.next(srcRow);
+            srcRow += sampler.srcDY() * srcRowBytes;
+        }
+
+        return true;
+
+    } else if (ktxFile.isCompressedFormat(SkTextureCompressor::kETC1_Format)) {
         if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) {
             return false;
         }
@@ -113,11 +169,12 @@
         // ETC1 Data is encoded as RGB pixels, so we should extract it as such
         int nPixels = width * height;
         SkAutoMalloc outRGBData(nPixels * 3);
-        etc1_byte *outRGBDataPtr = reinterpret_cast<etc1_byte *>(outRGBData.get());
+        uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get());
 
         // Decode ETC1
-        const etc1_byte *buf = reinterpret_cast<const etc1_byte *>(ktxFile.pixelData());
-        if (etc1_decode_image(buf, outRGBDataPtr, width, height, 3, width*3)) {
+        const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData());
+        if (!SkTextureCompressor::DecompressBufferFromFormat(
+                outRGBDataPtr, width*3, buf, width, height, SkTextureCompressor::kETC1_Format)) {
             return false;
         }
 
@@ -209,10 +266,13 @@
 };
 
 bool SkKTXImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bitmap, int) {
+    if (!bitmap.pixelRef()) {
+        return false;
+    }
     SkAutoDataUnref data(bitmap.pixelRef()->refEncodedData());
 
     // Is this even encoded data?
-    if (NULL != data) {
+    if (data) {
         const uint8_t *bytes = data->bytes();
         if (etc1_pkm_is_valid(bytes)) {
             return this->encodePKM(stream, data);
diff --git a/src/images/SkImageDecoder_libbmp.cpp b/src/images/SkImageDecoder_libbmp.cpp
index f9dd247..7b87e40 100644
--- a/src/images/SkImageDecoder_libbmp.cpp
+++ b/src/images/SkImageDecoder_libbmp.cpp
@@ -12,7 +12,7 @@
 #include "SkImageDecoder.h"
 #include "SkScaledBitmapSampler.h"
 #include "SkStream.h"
-#include "SkStreamHelpers.h"
+#include "SkStreamPriv.h"
 #include "SkTDArray.h"
 
 class SkBMPImageDecoder : public SkImageDecoder {
@@ -99,7 +99,7 @@
     // Allocated space used to hold the data.
     SkAutoMalloc storage;
     // Byte length of all of the data.
-    const size_t length = CopyStreamToStorage(&storage, stream);
+    const size_t length = SkCopyStreamToStorage(&storage, stream);
     if (0 == length) {
         return 0;
     }
diff --git a/src/images/SkImageDecoder_libgif.cpp b/src/images/SkImageDecoder_libgif.cpp
index 0c8461f..745f4e1 100644
--- a/src/images/SkImageDecoder_libgif.cpp
+++ b/src/images/SkImageDecoder_libgif.cpp
@@ -194,7 +194,7 @@
 static void sanitize_indexed_bitmap(SkBitmap* bm) {
     if ((kIndex_8_SkColorType == bm->colorType()) && !(bm->empty())) {
         SkAutoLockPixels alp(*bm);
-        if (NULL != bm->getPixels()) {
+        if (bm->getPixels()) {
             SkColorTable* ct = bm->getColorTable();  // Index8 must have it.
             SkASSERT(ct != NULL);
             uint32_t count = ct->count();
diff --git a/src/images/SkImageDecoder_libico.cpp b/src/images/SkImageDecoder_libico.cpp
index e6ae16f..7855546 100644
--- a/src/images/SkImageDecoder_libico.cpp
+++ b/src/images/SkImageDecoder_libico.cpp
@@ -8,7 +8,7 @@
 #include "SkColorPriv.h"
 #include "SkImageDecoder.h"
 #include "SkStream.h"
-#include "SkStreamHelpers.h"
+#include "SkStreamPriv.h"
 #include "SkTypes.h"
 
 class SkICOImageDecoder : public SkImageDecoder {
@@ -75,7 +75,7 @@
 bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode)
 {
     SkAutoMalloc autoMal;
-    const size_t length = CopyStreamToStorage(&autoMal, stream);
+    const size_t length = SkCopyStreamToStorage(&autoMal, stream);
     if (0 == length) {
         return false;
     }
@@ -152,16 +152,22 @@
     //int reservedToo = readByte(buf, 9 + choice*16);   //0
     //int planes = read2Bytes(buf, 10 + choice*16);       //1 - but often 0
     //int fakeBitCount = read2Bytes(buf, 12 + choice*16); //should be real - usually 0
-    int size = read4Bytes(buf, 14 + choice*16);           //matters?
-    int offset = read4Bytes(buf, 18 + choice*16);
-    if ((size_t)(offset + size) > length)
+    const size_t size = read4Bytes(buf, 14 + choice*16);           //matters?
+    const size_t offset = read4Bytes(buf, 18 + choice*16);
+    // promote the sum to 64-bits to avoid overflow
+    if (((uint64_t)offset + size) > length) {
         return false;
+    }
 
     // Check to see if this is a PNG image inside the ICO
     {
         SkMemoryStream subStream(buf + offset, size, false);
         SkAutoTDelete<SkImageDecoder> otherDecoder(SkImageDecoder::Factory(&subStream));
         if (otherDecoder.get() != NULL) {
+            // Disallow nesting ICO files within one another
+            if (otherDecoder->getFormat() == SkImageDecoder::kICO_Format) {
+                return false;
+            }
             // Set fields on the other decoder to be the same as this one.
             this->copyFieldsToOther(otherDecoder.get());
             if(otherDecoder->decode(&subStream, bm, this->getDefaultPref(), mode)) {
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index 9b93716..99401e6 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -852,7 +852,7 @@
             return return_false(*cinfo, bitmap, "allocPixelRef");
         }
     } else {
-        if (!bitmap.allocPixels()) {
+        if (!bitmap.tryAllocPixels()) {
             return return_false(*cinfo, bitmap, "allocPixels");
         }
     }
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
index 7ff1558..dd1d1c8 100644
--- a/src/images/SkImageDecoder_libpng.cpp
+++ b/src/images/SkImageDecoder_libpng.cpp
@@ -62,7 +62,7 @@
         stream->ref();
     }
     ~SkPNGImageIndex() {
-        if (NULL != fPng_ptr) {
+        if (fPng_ptr) {
             png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL);
         }
     }
@@ -823,7 +823,7 @@
             return false;
         }
     } else {
-        if (!decodedBitmap.allocPixels(NULL, needColorTable ? colorTable : NULL)) {
+        if (!decodedBitmap.tryAllocPixels(NULL, needColorTable ? colorTable : NULL)) {
             return false;
         }
     }
@@ -911,8 +911,7 @@
             for (int i = 0; i < number_passes; i++) {
                 png_configure_decoder(png_ptr, &actualTop, i);
                 for (int j = 0; j < rect.fTop - actualTop; j++) {
-                    uint8_t* bmRow = (uint8_t*)decodedBitmap.getPixels();
-                    png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
+                    png_read_rows(png_ptr, &base, png_bytepp_NULL, 1);
                 }
                 uint8_t* row = base;
                 for (int32_t y = 0; y < rect.height(); y++) {
@@ -935,8 +934,7 @@
             skip_src_rows(png_ptr, srcRow, sampler.srcY0());
 
             for (int i = 0; i < rect.fTop - actualTop; i++) {
-                uint8_t* bmRow = (uint8_t*)decodedBitmap.getPixels();
-                png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
+                png_read_rows(png_ptr, &srcRow, png_bytepp_NULL, 1);
             }
             for (int y = 0; y < height; y++) {
                 uint8_t* tmp = srcRow;
@@ -1163,7 +1161,7 @@
 
     // we must do this after we have locked the pixels
     SkColorTable* ctable = bitmap.getColorTable();
-    if (NULL != ctable) {
+    if (ctable) {
         if (ctable->count() == 0) {
             return false;
         }
diff --git a/src/images/SkImageDecoder_libwebp.cpp b/src/images/SkImageDecoder_libwebp.cpp
index f7cfa8b..f32587d 100644
--- a/src/images/SkImageDecoder_libwebp.cpp
+++ b/src/images/SkImageDecoder_libwebp.cpp
@@ -375,7 +375,7 @@
         // alloc from native heap if it is a temp bitmap. (prevent GC)
         bool allocResult = (bitmap == decodedBitmap)
                                ? allocPixelRef(bitmap, NULL)
-                               : bitmap->allocPixels();
+                               : bitmap->tryAllocPixels();
         if (!allocResult) {
             return return_false(*decodedBitmap, "allocPixelRef");
         }
diff --git a/src/images/SkImageDecoder_pkm.cpp b/src/images/SkImageDecoder_pkm.cpp
index d555c6a..f5fd4b3 100644
--- a/src/images/SkImageDecoder_pkm.cpp
+++ b/src/images/SkImageDecoder_pkm.cpp
@@ -9,7 +9,8 @@
 #include "SkImageDecoder.h"
 #include "SkScaledBitmapSampler.h"
 #include "SkStream.h"
-#include "SkStreamHelpers.h"
+#include "SkStreamPriv.h"
+#include "SkTextureCompressor.h"
 #include "SkTypes.h"
 
 #include "etc1.h"
@@ -33,7 +34,7 @@
 
 bool SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
     SkAutoMalloc autoMal;
-    const size_t length = CopyStreamToStorage(&autoMal, stream);
+    const size_t length = SkCopyStreamToStorage(&autoMal, stream);
     if (0 == length) {
         return false;
     }
@@ -80,10 +81,11 @@
     // ETC1 Data is encoded as RGB pixels, so we should extract it as such
     int nPixels = width * height;
     SkAutoMalloc outRGBData(nPixels * 3);
-    etc1_byte *outRGBDataPtr = reinterpret_cast<etc1_byte *>(outRGBData.get());
+    uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get());
 
     // Decode ETC1
-    if (etc1_decode_image(buf, outRGBDataPtr, width, height, 3, width*3)) {
+    if (!SkTextureCompressor::DecompressBufferFromFormat(
+            outRGBDataPtr, width*3, buf, width, height, SkTextureCompressor::kETC1_Format)) {
         return false;
     }
 
diff --git a/src/images/SkImageDecoder_wbmp.cpp b/src/images/SkImageDecoder_wbmp.cpp
index 0bf1389..ddb7c3d 100644
--- a/src/images/SkImageDecoder_wbmp.cpp
+++ b/src/images/SkImageDecoder_wbmp.cpp
@@ -119,7 +119,7 @@
     }
 
     const SkPMColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
-    SkColorTable* ct = SkNEW_ARGS(SkColorTable, (colors, 2));
+    SkColorTable* ct = SkNEW_ARGS(SkColorTable, (colors, 2, kOpaque_SkAlphaType));
     SkAutoUnref   aur(ct);
 
     if (!this->allocPixelRef(decodedBitmap, ct)) {
diff --git a/src/images/SkMovie_gif.cpp b/src/images/SkMovie_gif.cpp
index decefd5..3810db5 100644
--- a/src/images/SkMovie_gif.cpp
+++ b/src/images/SkMovie_gif.cpp
@@ -364,11 +364,11 @@
         startIndex = 0;
 
         // create bitmap
-        if (!bm->allocPixels(SkImageInfo::MakeN32Premul(width, height))) {
+        if (!bm->tryAllocN32Pixels(width, height)) {
             return false;
         }
         // create bitmap for backup
-        if (!fBackup.allocPixels(SkImageInfo::MakeN32Premul(width, height))) {
+        if (!fBackup.tryAllocN32Pixels(width, height)) {
             return false;
         }
     } else if (startIndex > fCurrIndex) {
diff --git a/src/images/SkStreamHelpers.cpp b/src/images/SkStreamHelpers.cpp
deleted file mode 100644
index c7c66b4..0000000
--- a/src/images/SkStreamHelpers.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 "SkData.h"
-#include "SkStream.h"
-#include "SkStreamHelpers.h"
-#include "SkTypes.h"
-
-size_t CopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream) {
-    SkASSERT(storage != NULL);
-    SkASSERT(stream != NULL);
-
-    if (stream->hasLength()) {
-        const size_t length = stream->getLength();
-        void* dst = storage->reset(length);
-        if (stream->read(dst, length) != length) {
-            return 0;
-        }
-        return length;
-    }
-
-    SkDynamicMemoryWStream tempStream;
-    // Arbitrary buffer size.
-    const size_t bufferSize = 256 * 1024; // 256KB
-    char buffer[bufferSize];
-    SkDEBUGCODE(size_t debugLength = 0;)
-    do {
-        size_t bytesRead = stream->read(buffer, bufferSize);
-        tempStream.write(buffer, bytesRead);
-        SkDEBUGCODE(debugLength += bytesRead);
-        SkASSERT(tempStream.bytesWritten() == debugLength);
-    } while (!stream->isAtEnd());
-    const size_t length = tempStream.bytesWritten();
-    void* dst = storage->reset(length);
-    tempStream.copyTo(dst);
-    return length;
-}
-
-SkData *CopyStreamToData(SkStream* stream) {
-    SkASSERT(stream != NULL);
-
-    if (stream->hasLength()) {
-        const size_t length = stream->getLength();
-        void* dst = sk_malloc_throw(length);
-        if (stream->read(dst, length) != length) {
-            return 0;
-        }
-        return SkData::NewFromMalloc(dst, length);
-    }
-
-    SkDynamicMemoryWStream tempStream;
-    // Arbitrary buffer size.
-    const size_t bufferSize = 256 * 1024; // 256KB
-    char buffer[bufferSize];
-    SkDEBUGCODE(size_t debugLength = 0;)
-    do {
-        size_t bytesRead = stream->read(buffer, bufferSize);
-        tempStream.write(buffer, bytesRead);
-        SkDEBUGCODE(debugLength += bytesRead);
-        SkASSERT(tempStream.bytesWritten() == debugLength);
-    } while (!stream->isAtEnd());
-    return tempStream.copyToData();
-}
diff --git a/src/images/SkStreamHelpers.h b/src/images/SkStreamHelpers.h
deleted file mode 100644
index 008dd8e..0000000
--- a/src/images/SkStreamHelpers.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkStreamHelpers_DEFINED
-#define SkStreamHelpers_DEFINED
-
-class SkAutoMalloc;
-class SkStream;
-class SkData;
-
-/**
- *  Copy the provided stream to memory allocated by storage.
- *  Used by SkImageDecoder_libbmp and SkImageDecoder_libico.
- *  @param storage Allocator to hold the memory. Will be reset to be large
- *      enough to hold the entire stream. Upon successful return,
- *      storage->get() will point to data holding the SkStream's entire
- *      contents.
- *  @param stream SkStream to be copied into storage.
- *  @return size_t Total number of bytes in the SkStream, which is also the
- *      number of bytes pointed to by storage->get(). Returns 0 on failure.
- */
-size_t CopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream);
-
-/**
- *  Copy the provided stream to an SkData variable. Used by SkImageDecoder_libktx.
- *  @param stream SkStream to be copied into data.
- *  @return SkData* The resulting SkData after the copy. This data will have a
- *      ref count of one upon return and belongs to the caller. Returns NULL on failure.
- */
-SkData *CopyStreamToData(SkStream* stream);
-
-#endif // SkStreamHelpers_DEFINED
diff --git a/src/lazy/SkCachingPixelRef.cpp b/src/lazy/SkCachingPixelRef.cpp
index 76510f6..1459567 100644
--- a/src/lazy/SkCachingPixelRef.cpp
+++ b/src/lazy/SkCachingPixelRef.cpp
@@ -6,7 +6,8 @@
  */
 
 #include "SkCachingPixelRef.h"
-#include "SkScaledImageCache.h"
+#include "SkBitmapCache.h"
+#include "SkRect.h"
 
 bool SkCachingPixelRef::Install(SkImageGenerator* generator,
                                 SkBitmap* dst) {
@@ -30,13 +31,11 @@
     : INHERITED(info)
     , fImageGenerator(generator)
     , fErrorInDecoding(false)
-    , fScaledCacheId(NULL)
     , fRowBytes(rowBytes) {
     SkASSERT(fImageGenerator != NULL);
 }
 SkCachingPixelRef::~SkCachingPixelRef() {
     SkDELETE(fImageGenerator);
-    SkASSERT(NULL == fScaledCacheId);
     // Assert always unlock before unref.
 }
 
@@ -46,52 +45,33 @@
     }
 
     const SkImageInfo& info = this->info();
-    SkBitmap bitmap;
-    SkASSERT(NULL == fScaledCacheId);
-    fScaledCacheId = SkScaledImageCache::FindAndLock(this->getGenerationID(),
-                                                     info.fWidth,
-                                                     info.fHeight,
-                                                     &bitmap);
-    if (NULL == fScaledCacheId) {
+    if (!SkBitmapCache::Find(this->getGenerationID(),
+                             SkIRect::MakeWH(info.width(), info.height()),
+                             &fLockedBitmap)) {
         // Cache has been purged, must re-decode.
-        if ((!bitmap.setInfo(info, fRowBytes)) || !bitmap.allocPixels()) {
+        if (!fLockedBitmap.tryAllocPixels(info, fRowBytes)) {
             fErrorInDecoding = true;
             return false;
         }
-        SkAutoLockPixels autoLockPixels(bitmap);
-        if (!fImageGenerator->getPixels(info, bitmap.getPixels(), fRowBytes)) {
+        if (!fImageGenerator->getPixels(info, fLockedBitmap.getPixels(), fRowBytes)) {
             fErrorInDecoding = true;
             return false;
         }
-        fScaledCacheId = SkScaledImageCache::AddAndLock(this->getGenerationID(),
-                                                        info.fWidth,
-                                                        info.fHeight,
-                                                        bitmap);
-        SkASSERT(fScaledCacheId != NULL);
+        fLockedBitmap.setImmutable();
+        SkBitmapCache::Add(this->getGenerationID(),
+                           SkIRect::MakeWH(info.width(), info.height()),
+                           fLockedBitmap);
     }
 
-    // Now bitmap should contain a concrete PixelRef of the decoded
-    // image.
-    SkAutoLockPixels autoLockPixels(bitmap);
-    void* pixels = bitmap.getPixels();
+    // Now bitmap should contain a concrete PixelRef of the decoded image.
+    void* pixels = fLockedBitmap.getPixels();
     SkASSERT(pixels != NULL);
-
-    // At this point, the autoLockPixels will unlockPixels()
-    // to remove bitmap's lock on the pixels.  We will then
-    // destroy bitmap.  The *only* guarantee that this pointer
-    // remains valid is the guarantee made by
-    // SkScaledImageCache that it will not destroy the *other*
-    // bitmap (SkScaledImageCache::Rec.fBitmap) that holds a
-    // reference to the concrete PixelRef while this record is
-    // locked.
     rec->fPixels = pixels;
     rec->fColorTable = NULL;
-    rec->fRowBytes = bitmap.rowBytes();
+    rec->fRowBytes = fLockedBitmap.rowBytes();
     return true;
 }
 
 void SkCachingPixelRef::onUnlockPixels() {
-    SkASSERT(fScaledCacheId != NULL);
-    SkScaledImageCache::Unlock( static_cast<SkScaledImageCache::ID*>(fScaledCacheId));
-    fScaledCacheId = NULL;
+    fLockedBitmap.reset();
 }
diff --git a/src/lazy/SkCachingPixelRef.h b/src/lazy/SkCachingPixelRef.h
index 9fc71c3..306f714 100644
--- a/src/lazy/SkCachingPixelRef.h
+++ b/src/lazy/SkCachingPixelRef.h
@@ -8,6 +8,7 @@
 #ifndef SkCachingPixelRef_DEFINED
 #define SkCachingPixelRef_DEFINED
 
+#include "SkBitmapCache.h"
 #include "SkImageInfo.h"
 #include "SkImageGenerator.h"
 #include "SkPixelRef.h"
@@ -48,19 +49,14 @@
     virtual SkData* onRefEncodedData() SK_OVERRIDE {
         return fImageGenerator->refEncodedData();
     }
-    // No need to flatten this object. When flattening an SkBitmap,
-    // SkWriteBuffer will check the encoded data and write that
-    // instead.
-    // Future implementations of SkWriteBuffer will need to
-    // special case for onRefEncodedData as well.
-    SK_DECLARE_UNFLATTENABLE_OBJECT()
 
 private:
     SkImageGenerator* const fImageGenerator;
     bool                    fErrorInDecoding;
-    void*                   fScaledCacheId;
     const size_t            fRowBytes;
 
+    SkBitmap                fLockedBitmap;
+
     SkCachingPixelRef(const SkImageInfo&, SkImageGenerator*, size_t rowBytes);
 
     typedef SkPixelRef INHERITED;
diff --git a/src/lazy/SkDiscardableMemoryPool.cpp b/src/lazy/SkDiscardableMemoryPool.cpp
index db2754e..f8f44d0 100644
--- a/src/lazy/SkDiscardableMemoryPool.cpp
+++ b/src/lazy/SkDiscardableMemoryPool.cpp
@@ -7,6 +7,7 @@
 
 #include "SkDiscardableMemory.h"
 #include "SkDiscardableMemoryPool.h"
+#include "SkImageGenerator.h"
 #include "SkLazyPtr.h"
 #include "SkTInternalLList.h"
 #include "SkThread.h"
@@ -154,7 +155,7 @@
     typedef SkTInternalLList<PoolDiscardableMemory>::Iter Iter;
     Iter iter;
     PoolDiscardableMemory* cur = iter.init(fList, Iter::kTail_IterStart);
-    while ((fUsed > budget) && (NULL != cur)) {
+    while ((fUsed > budget) && (cur)) {
         if (!cur->fLocked) {
             PoolDiscardableMemory* dm = cur;
             SkASSERT(dm->fPointer != NULL);
@@ -264,8 +265,4 @@
     return global.get();
 }
 
-// defined in SkImageGenerator.h
-void SkPurgeGlobalDiscardableMemoryPool() {
-    SkGetGlobalDiscardableMemoryPool()->dumpPool();
-}
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/lazy/SkDiscardablePixelRef.cpp b/src/lazy/SkDiscardablePixelRef.cpp
index f0d7aff..ec8d5ea 100644
--- a/src/lazy/SkDiscardablePixelRef.cpp
+++ b/src/lazy/SkDiscardablePixelRef.cpp
@@ -40,7 +40,7 @@
     if (fDiscardableMemory != NULL) {
         if (fDiscardableMemory->lock()) {
             rec->fPixels = fDiscardableMemory->data();
-            rec->fColorTable = NULL;
+            rec->fColorTable = fCTable.get();
             rec->fRowBytes = fRowBytes;
             return true;
         }
@@ -105,9 +105,12 @@
         || (!dst->setInfo(info))) {
         return false;
     }
-    SkASSERT(dst->colorType() != kUnknown_SkColorType);
+    // Since dst->setInfo() may have changed/fixed-up info, we copy it back from that bitmap
+    info = dst->info();
+
+    SkASSERT(info.colorType() != kUnknown_SkColorType);
     if (dst->empty()) {  // Use a normal pixelref.
-        return dst->allocPixels();
+        return dst->tryAllocPixels();
     }
     SkAutoTUnref<SkDiscardablePixelRef> ref(
         SkNEW_ARGS(SkDiscardablePixelRef,
diff --git a/src/lazy/SkDiscardablePixelRef.h b/src/lazy/SkDiscardablePixelRef.h
index 52a1d6c..142c8a4 100644
--- a/src/lazy/SkDiscardablePixelRef.h
+++ b/src/lazy/SkDiscardablePixelRef.h
@@ -21,7 +21,6 @@
 class SkDiscardablePixelRef : public SkPixelRef {
 public:
     SK_DECLARE_INST_COUNT(SkDiscardablePixelRef)
-    SK_DECLARE_UNFLATTENABLE_OBJECT()
 
 protected:
     ~SkDiscardablePixelRef();
@@ -49,6 +48,13 @@
                           size_t rowBytes,
                           SkDiscardableMemory::Factory* factory);
 
+    virtual bool onGetYUV8Planes(SkISize sizes[3],
+                                 void* planes[3],
+                                 size_t rowBytes[3],
+                                 SkYUVColorSpace* colorSpace) SK_OVERRIDE {
+        return fGenerator->getYUV8Planes(sizes, planes, rowBytes, colorSpace);
+    }
+
     friend bool SkInstallDiscardablePixelRef(SkImageGenerator*, SkBitmap*,
                                              SkDiscardableMemory::Factory*);
 
diff --git a/src/opts/SkBitmapFilter_opts_SSE2.cpp b/src/opts/SkBitmapFilter_opts_SSE2.cpp
index b040566..04f1486 100644
--- a/src/opts/SkBitmapFilter_opts_SSE2.cpp
+++ b/src/opts/SkBitmapFilter_opts_SSE2.cpp
@@ -46,45 +46,45 @@
 void highQualityFilter_SSE2(const SkBitmapProcState& s, int x, int y,
                             SkPMColor* SK_RESTRICT colors, int count) {
 
-    const int maxX = s.fBitmap->width() - 1;
-    const int maxY = s.fBitmap->height() - 1;
+    const int maxX = s.fBitmap->width();
+    const int maxY = s.fBitmap->height();
+    SkAutoTMalloc<SkScalar> xWeights(maxX);
 
     while (count-- > 0) {
         SkPoint srcPt;
-        s.fInvProc(s.fInvMatrix, SkIntToScalar(x),
-                    SkIntToScalar(y), &srcPt);
+        s.fInvProc(s.fInvMatrix, x + 0.5f, y + 0.5f, &srcPt);
         srcPt.fX -= SK_ScalarHalf;
         srcPt.fY -= SK_ScalarHalf;
 
-        int sx = SkScalarFloorToInt(srcPt.fX);
-        int sy = SkScalarFloorToInt(srcPt.fY);
-
         __m128 weight = _mm_setzero_ps();
         __m128 accum = _mm_setzero_ps();
 
-        int y0 = SkTMax(0, int(ceil(sy-s.getBitmapFilter()->width() + 0.5f)));
-        int y1 = SkTMin(maxY, int(floor(sy+s.getBitmapFilter()->width() + 0.5f)));
-        int x0 = SkTMax(0, int(ceil(sx-s.getBitmapFilter()->width() + 0.5f)));
-        int x1 = SkTMin(maxX, int(floor(sx+s.getBitmapFilter()->width() + 0.5f)));
+        int y0 = SkClampMax(SkScalarCeilToInt(srcPt.fY-s.getBitmapFilter()->width()), maxY);
+        int y1 = SkClampMax(SkScalarFloorToInt(srcPt.fY+s.getBitmapFilter()->width()+1), maxY);
+        int x0 = SkClampMax(SkScalarCeilToInt(srcPt.fX-s.getBitmapFilter()->width()), maxX);
+        int x1 = SkClampMax(SkScalarFloorToInt(srcPt.fX+s.getBitmapFilter()->width())+1, maxX);
 
-        for (int src_y = y0; src_y <= y1; src_y++) {
-            float yweight = SkScalarToFloat(s.getBitmapFilter()->lookupScalar(srcPt.fY - src_y));
+        for (int srcX = x0; srcX < x1 ; srcX++) {
+            // Looking these up once instead of each loop is a ~15% speedup.
+            xWeights[srcX - x0] = s.getBitmapFilter()->lookupScalar((srcPt.fX - srcX));
+        }
 
-            for (int src_x = x0; src_x <= x1 ; src_x++) {
-                float xweight = SkScalarToFloat(s.getBitmapFilter()->lookupScalar(srcPt.fX - src_x));
+        for (int srcY = y0; srcY < y1; srcY++) {
+            SkScalar yWeight = s.getBitmapFilter()->lookupScalar((srcPt.fY - srcY));
 
-                float combined_weight = xweight * yweight;
+            for (int srcX = x0; srcX < x1 ; srcX++) {
+                SkScalar xWeight = xWeights[srcX - x0];
 
-                SkPMColor color = *s.fBitmap->getAddr32(src_x, src_y);
+                SkScalar combined_weight = SkScalarMul(xWeight, yWeight);
 
-                __m128i c = _mm_cvtsi32_si128( color );
+                SkPMColor color = *s.fBitmap->getAddr32(srcX, srcY);
+
+                __m128i c = _mm_cvtsi32_si128(color);
                 c = _mm_unpacklo_epi8(c, _mm_setzero_si128());
                 c = _mm_unpacklo_epi16(c, _mm_setzero_si128());
-
-                __m128 cfloat = _mm_cvtepi32_ps( c );
+                __m128 cfloat = _mm_cvtepi32_ps(c);
 
                 __m128 weightVector = _mm_set1_ps(combined_weight);
-
                 accum = _mm_add_ps(accum, _mm_mul_ps(cfloat, weightVector));
                 weight = _mm_add_ps( weight, weightVector );
             }
@@ -92,15 +92,15 @@
 
         accum = _mm_div_ps(accum, weight);
         accum = _mm_add_ps(accum, _mm_set1_ps(0.5f));
+        __m128i accumInt = _mm_cvttps_epi32(accum);
+        accumInt = _mm_packs_epi32(accumInt, _mm_setzero_si128());
+        accumInt = _mm_packus_epi16(accumInt, _mm_setzero_si128());
+        SkPMColor c = _mm_cvtsi128_si32(accumInt);
 
-        __m128i accumInt = _mm_cvtps_epi32( accum );
-
-        int localResult[4];
-        _mm_storeu_si128((__m128i *) (localResult), accumInt);
-        int a = SkClampMax(localResult[0], 255);
-        int r = SkClampMax(localResult[1], a);
-        int g = SkClampMax(localResult[2], a);
-        int b = SkClampMax(localResult[3], a);
+        int a = SkClampMax(SkGetPackedA32(c), 255);
+        int r = SkClampMax(SkGetPackedR32(c), a);
+        int g = SkClampMax(SkGetPackedG32(c), a);
+        int b = SkClampMax(SkGetPackedB32(c), a);
 
         *colors++ = SkPackARGB32(a, r, g, b);
 
@@ -108,74 +108,6 @@
     }
 }
 
-void highQualityFilter_ScaleOnly_SSE2(const SkBitmapProcState &s, int x, int y,
-                             SkPMColor *SK_RESTRICT colors, int count) {
-    const int maxX = s.fBitmap->width() - 1;
-    const int maxY = s.fBitmap->height() - 1;
-
-    SkPoint srcPt;
-    s.fInvProc(s.fInvMatrix, SkIntToScalar(x),
-                SkIntToScalar(y), &srcPt);
-    srcPt.fY -= SK_ScalarHalf;
-    int sy = SkScalarFloorToInt(srcPt.fY);
-
-    int y0 = SkTMax(0, int(ceil(sy-s.getBitmapFilter()->width() + 0.5f)));
-    int y1 = SkTMin(maxY, int(floor(sy+s.getBitmapFilter()->width() + 0.5f)));
-
-    while (count-- > 0) {
-        srcPt.fX -= SK_ScalarHalf;
-        srcPt.fY -= SK_ScalarHalf;
-
-        int sx = SkScalarFloorToInt(srcPt.fX);
-
-        float weight = 0;
-        __m128 accum = _mm_setzero_ps();
-
-        int x0 = SkTMax(0, int(ceil(sx-s.getBitmapFilter()->width() + 0.5f)));
-        int x1 = SkTMin(maxX, int(floor(sx+s.getBitmapFilter()->width() + 0.5f)));
-
-        for (int src_y = y0; src_y <= y1; src_y++) {
-            float yweight = SkScalarToFloat(s.getBitmapFilter()->lookupScalar(srcPt.fY - src_y));
-
-            for (int src_x = x0; src_x <= x1 ; src_x++) {
-                float xweight = SkScalarToFloat(s.getBitmapFilter()->lookupScalar(srcPt.fX - src_x));
-
-                float combined_weight = xweight * yweight;
-
-                SkPMColor color = *s.fBitmap->getAddr32(src_x, src_y);
-
-                __m128 c = _mm_set_ps((float)SkGetPackedB32(color),
-                                      (float)SkGetPackedG32(color),
-                                      (float)SkGetPackedR32(color),
-                                      (float)SkGetPackedA32(color));
-
-                __m128 weightVector = _mm_set1_ps(combined_weight);
-
-                accum = _mm_add_ps(accum, _mm_mul_ps(c, weightVector));
-                weight += combined_weight;
-            }
-        }
-
-        __m128 totalWeightVector = _mm_set1_ps(weight);
-        accum = _mm_div_ps(accum, totalWeightVector);
-        accum = _mm_add_ps(accum, _mm_set1_ps(0.5f));
-
-        float localResult[4];
-        _mm_storeu_ps(localResult, accum);
-        int a = SkClampMax(int(localResult[0]), 255);
-        int r = SkClampMax(int(localResult[1]), a);
-        int g = SkClampMax(int(localResult[2]), a);
-        int b = SkClampMax(int(localResult[3]), a);
-
-        *colors++ = SkPackARGB32(a, r, g, b);
-
-        x++;
-
-        s.fInvProc(s.fInvMatrix, SkIntToScalar(x),
-                    SkIntToScalar(y), &srcPt);
-    }
-}
-
 // Convolves horizontally along a single row. The row data is given in
 // |src_data| and continues for the num_values() of the filter.
 void convolveHorizontally_SSE2(const unsigned char* src_data,
diff --git a/src/opts/SkBitmapFilter_opts_SSE2.h b/src/opts/SkBitmapFilter_opts_SSE2.h
index 661a824..f03450d 100644
--- a/src/opts/SkBitmapFilter_opts_SSE2.h
+++ b/src/opts/SkBitmapFilter_opts_SSE2.h
@@ -11,8 +11,6 @@
 #include "SkBitmapProcState.h"
 #include "SkConvolver.h"
 
-void highQualityFilter_ScaleOnly_SSE2(const SkBitmapProcState &s, int x, int y,
-                                      SkPMColor *SK_RESTRICT colors, int count);
 void highQualityFilter_SSE2(const SkBitmapProcState &s, int x, int y,
                             SkPMColor *SK_RESTRICT colors, int count);
 
diff --git a/src/opts/SkBitmapProcState_opts_SSSE3.cpp b/src/opts/SkBitmapProcState_opts_SSSE3.cpp
index 5b97215..165f1f5 100644
--- a/src/opts/SkBitmapProcState_opts_SSSE3.cpp
+++ b/src/opts/SkBitmapProcState_opts_SSSE3.cpp
@@ -9,12 +9,11 @@
 #include "SkPaint.h"
 #include "SkUtils.h"
 
-/* With the exception of the Android framework we always build the SSSE3 functions
- * and enable the caller to determine SSSE3 support.  However for the Android framework
- * if the device does not support SSSE3 then the compiler will not supply the required
- * -mssse3 option needed to build this file, so instead we provide a stub implementation.
+/* With the exception of the compilers that don't support it, we always build the
+ * SSSE3 functions and enable the caller to determine SSSE3 support.  However for
+ * compilers that do not support SSSE3 we provide a stub implementation.
  */
-#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) || SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
+#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
 
 #include <tmmintrin.h>  // SSSE3
 
@@ -732,7 +731,7 @@
     S32_generic_D32_filter_DXDY_SSSE3<true>(s, xy, count, colors);
 }
 
-#else // !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) || SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
+#else // SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
 
 void S32_opaque_D32_filter_DX_SSSE3(const SkBitmapProcState& s,
                                     const uint32_t* xy,
diff --git a/src/opts/SkBitmapProcState_opts_arm.cpp b/src/opts/SkBitmapProcState_opts_arm.cpp
index ffa0ccf..8f24c39 100644
--- a/src/opts/SkBitmapProcState_opts_arm.cpp
+++ b/src/opts/SkBitmapProcState_opts_arm.cpp
@@ -6,6 +6,7 @@
  */
 
 
+#include "SkBitmapScaler.h"
 #include "SkBitmapProcState.h"
 #include "SkColorPriv.h"
 #include "SkPaint.h"
@@ -229,6 +230,6 @@
 void platformConvolutionProcs_arm(SkConvolutionProcs* procs) {
 }
 
-void SkBitmapProcState::platformConvolutionProcs(SkConvolutionProcs* procs) {
+void SkBitmapScaler::PlatformConvolutionProcs(SkConvolutionProcs* procs) {
     SK_ARM_NEON_WRAP(platformConvolutionProcs_arm)(procs);
 }
diff --git a/src/opts/SkBitmapProcState_opts_mips_dsp.cpp b/src/opts/SkBitmapProcState_opts_mips_dsp.cpp
new file mode 100644
index 0000000..d4f601b
--- /dev/null
+++ b/src/opts/SkBitmapProcState_opts_mips_dsp.cpp
@@ -0,0 +1,397 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkBitmapProcState.h"
+#include "SkBitmapScaler.h"
+#include "SkColorPriv.h"
+#include "SkPaint.h"
+#include "SkUtils.h"
+
+static void SI8_D16_nofilter_DX_mips_dsp(const SkBitmapProcState& s,
+                                         const uint32_t* SK_RESTRICT xy,
+                                         int count, uint16_t* SK_RESTRICT colors) {
+    SkASSERT(count > 0 && colors != NULL);
+    SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
+    SkASSERT(SkPaint::kNone_FilterLevel == s.fFilterLevel);
+    const uint16_t* SK_RESTRICT table = s.fBitmap->getColorTable()->lock16BitCache();
+    const uint8_t* SK_RESTRICT srcAddr = (const uint8_t*)s.fBitmap->getPixels();
+    SkASSERT((unsigned)xy[0] < (unsigned)s.fBitmap->height());
+    srcAddr = (const uint8_t*)((const char*)srcAddr + xy[0] * s.fBitmap->rowBytes());
+    uint8_t src;
+
+    if (1 == s.fBitmap->width()) {
+        src = srcAddr[0];
+        uint16_t dstValue = table[src];
+        sk_memset16(colors, dstValue, count);
+    } else {
+        int count8;
+        const uint16_t* SK_RESTRICT xx = (const uint16_t*)(xy + 1);
+
+        __asm__ volatile (
+            ".set    push                                \n\t"
+            ".set    noreorder                           \n\t"
+            ".set    noat                                \n\t"
+            "sra     %[count8], %[count],      3         \n\t"
+            "beqz    %[count8], 3f                       \n\t"
+            " addiu  %[count8], %[count8],     -1        \n\t"
+        "1:                                              \n\t"
+            "beqz    %[count8], 2f                       \n\t"
+            " addiu  %[count8], %[count8],     -1        \n\t"
+            "pref    0,         16(%[xx])                \n\t"
+            "lhu     $t0,       0(%[xx])                 \n\t"
+            "lhu     $t1,       2(%[xx])                 \n\t"
+            "lhu     $t2,       4(%[xx])                 \n\t"
+            "lhu     $t3,       6(%[xx])                 \n\t"
+            "lhu     $t4,       8(%[xx])                 \n\t"
+            "lhu     $t5,       10(%[xx])                \n\t"
+            "lhu     $t6,       12(%[xx])                \n\t"
+            "lhu     $t7,       14(%[xx])                \n\t"
+            "pref    0,         8(%[srcAddr])            \n\t"
+            "lbux    $t0,       $t0(%[srcAddr])          \n\t"
+            "lbux    $t1,       $t1(%[srcAddr])          \n\t"
+            "lbux    $t2,       $t2(%[srcAddr])          \n\t"
+            "lbux    $t3,       $t3(%[srcAddr])          \n\t"
+            "lbux    $t4,       $t4(%[srcAddr])          \n\t"
+            "lbux    $t5,       $t5(%[srcAddr])          \n\t"
+            "lbux    $t6,       $t6(%[srcAddr])          \n\t"
+            "lbux    $t7,       $t7(%[srcAddr])          \n\t"
+            "addu    $t0,       $t0,           $t0       \n\t"
+            "addu    $t1,       $t1,           $t1       \n\t"
+            "addu    $t2,       $t2,           $t2       \n\t"
+            "addu    $t3,       $t3,           $t3       \n\t"
+            "addu    $t4,       $t4,           $t4       \n\t"
+            "addu    $t5,       $t5,           $t5       \n\t"
+            "addu    $t6,       $t6,           $t6       \n\t"
+            "addu    $t7,       $t7,           $t7       \n\t"
+            "pref    0,         16(%[table])             \n\t"
+            "lhx     $t0,       $t0(%[table])            \n\t"
+            "lhx     $t1,       $t1(%[table])            \n\t"
+            "lhx     $t2,       $t2(%[table])            \n\t"
+            "lhx     $t3,       $t3(%[table])            \n\t"
+            "lhx     $t4,       $t4(%[table])            \n\t"
+            "lhx     $t5,       $t5(%[table])            \n\t"
+            "lhx     $t6,       $t6(%[table])            \n\t"
+            "lhx     $t7,       $t7(%[table])            \n\t"
+            "sh      $t0,       0(%[colors])             \n\t"
+            "sh      $t1,       2(%[colors])             \n\t"
+            "sh      $t2,       4(%[colors])             \n\t"
+            "sh      $t3,       6(%[colors])             \n\t"
+            "sh      $t4,       8(%[colors])             \n\t"
+            "sh      $t5,       10(%[colors])            \n\t"
+            "sh      $t6,       12(%[colors])            \n\t"
+            "sh      $t7,       14(%[colors])            \n\t"
+            "addiu   %[xx],     %[xx],         16        \n\t"
+            "bgtz    %[count8], 1b                       \n\t"
+            " addiu  %[colors], %[colors],     16        \n\t"
+        "2:                                              \n\t"
+            "lhu     $t0,       0(%[xx])                 \n\t"
+            "lhu     $t1,       2(%[xx])                 \n\t"
+            "lhu     $t2,       4(%[xx])                 \n\t"
+            "lhu     $t3,       6(%[xx])                 \n\t"
+            "lhu     $t4,       8(%[xx])                 \n\t"
+            "lhu     $t5,       10(%[xx])                \n\t"
+            "lhu     $t6,       12(%[xx])                \n\t"
+            "lhu     $t7,       14(%[xx])                \n\t"
+            "lbux    $t0,       $t0(%[srcAddr])          \n\t"
+            "lbux    $t1,       $t1(%[srcAddr])          \n\t"
+            "lbux    $t2,       $t2(%[srcAddr])          \n\t"
+            "lbux    $t3,       $t3(%[srcAddr])          \n\t"
+            "lbux    $t4,       $t4(%[srcAddr])          \n\t"
+            "lbux    $t5,       $t5(%[srcAddr])          \n\t"
+            "lbux    $t6,       $t6(%[srcAddr])          \n\t"
+            "lbux    $t7,       $t7(%[srcAddr])          \n\t"
+            "addu    $t0,       $t0,           $t0       \n\t"
+            "addu    $t1,       $t1,           $t1       \n\t"
+            "addu    $t2,       $t2,           $t2       \n\t"
+            "addu    $t3,       $t3,           $t3       \n\t"
+            "addu    $t4,       $t4,           $t4       \n\t"
+            "addu    $t5,       $t5,           $t5       \n\t"
+            "addu    $t6,       $t6,           $t6       \n\t"
+            "addu    $t7,       $t7,           $t7       \n\t"
+            "lhx     $t0,       $t0(%[table])            \n\t"
+            "lhx     $t1,       $t1(%[table])            \n\t"
+            "lhx     $t2,       $t2(%[table])            \n\t"
+            "lhx     $t3,       $t3(%[table])            \n\t"
+            "lhx     $t4,       $t4(%[table])            \n\t"
+            "lhx     $t5,       $t5(%[table])            \n\t"
+            "lhx     $t6,       $t6(%[table])            \n\t"
+            "lhx     $t7,       $t7(%[table])            \n\t"
+            "sh      $t0,       0(%[colors])             \n\t"
+            "sh      $t1,       2(%[colors])             \n\t"
+            "sh      $t2,       4(%[colors])             \n\t"
+            "sh      $t3,       6(%[colors])             \n\t"
+            "sh      $t4,       8(%[colors])             \n\t"
+            "sh      $t5,       10(%[colors])            \n\t"
+            "sh      $t6,       12(%[colors])            \n\t"
+            "sh      $t7,       14(%[colors])            \n\t"
+            "addiu   %[xx],     %[xx],         16        \n\t"
+            "addiu   %[colors], %[colors],     16        \n\t"
+        "3:                                              \n\t"
+            ".set    pop                                 \n\t"
+            : [xx]"+r"(xx), [count8]"=&r"(count8), [colors]"+r"(colors)
+            : [table]"r"(table), [srcAddr]"r"(srcAddr), [count]"r"(count)
+            : "memory","t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"
+        );
+
+        for (int i = (count & 7); i > 0; --i) {
+            src = srcAddr[*xx++]; *colors++ = table[src];
+        }
+    }
+    s.fBitmap->getColorTable()->unlock16BitCache();
+}
+
+static void SI8_opaque_D32_nofilter_DX_mips_dsp(const SkBitmapProcState& s,
+                                                const uint32_t* SK_RESTRICT xy,
+                                                int count, SkPMColor* SK_RESTRICT colors) {
+    SkASSERT(count > 0 && colors != NULL);
+    SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
+    SkASSERT(SkPaint::kNone_FilterLevel == s.fFilterLevel);
+    const SkPMColor* SK_RESTRICT table = s.fBitmap->getColorTable()->lockColors();
+    const uint8_t* SK_RESTRICT srcAddr = (const uint8_t*)s.fBitmap->getPixels();
+    srcAddr = (const uint8_t*)((const char*)srcAddr + xy[0] * s.fBitmap->rowBytes());
+
+    if (1 == s.fBitmap->width()) {
+        uint8_t src = srcAddr[0];
+        SkPMColor dstValue = table[src];
+        sk_memset32(colors, dstValue, count);
+    } else {
+        const uint16_t* xx = (const uint16_t*)(xy + 1);
+        int s0, s1, s2, s3, s4, s5, s6, s7;
+        __asm__ volatile (
+            ".set    push                                \n\t"
+            ".set    noreorder                           \n\t"
+            ".set    noat                                \n\t"
+            "srl     $t8,       %[count],    4           \n\t"
+            "beqz    $t8,       3f                       \n\t"
+            " nop                                        \n\t"
+        "1:                                              \n\t"
+            "addiu   $t8,       $t8,         -1          \n\t"
+            "beqz    $t8,       2f                       \n\t"
+            " addiu  %[count],  %[count],    -16         \n\t"
+            "pref    0,         32(%[xx])                \n\t"
+            "lhu     $t0,       0(%[xx])                 \n\t"
+            "lhu     $t1,       2(%[xx])                 \n\t"
+            "lhu     $t2,       4(%[xx])                 \n\t"
+            "lhu     $t3,       6(%[xx])                 \n\t"
+            "lhu     $t4,       8(%[xx])                 \n\t"
+            "lhu     $t5,       10(%[xx])                \n\t"
+            "lhu     $t6,       12(%[xx])                \n\t"
+            "lhu     $t7,       14(%[xx])                \n\t"
+            "lhu     %[s0],     16(%[xx])                \n\t"
+            "lhu     %[s1],     18(%[xx])                \n\t"
+            "lhu     %[s2],     20(%[xx])                \n\t"
+            "lhu     %[s3],     22(%[xx])                \n\t"
+            "lhu     %[s4],     24(%[xx])                \n\t"
+            "lhu     %[s5],     26(%[xx])                \n\t"
+            "lhu     %[s6],     28(%[xx])                \n\t"
+            "lhu     %[s7],     30(%[xx])                \n\t"
+            "lbux    $t0,       $t0(%[srcAddr])          \n\t"
+            "lbux    $t1,       $t1(%[srcAddr])          \n\t"
+            "lbux    $t2,       $t2(%[srcAddr])          \n\t"
+            "lbux    $t3,       $t3(%[srcAddr])          \n\t"
+            "lbux    $t4,       $t4(%[srcAddr])          \n\t"
+            "lbux    $t5,       $t5(%[srcAddr])          \n\t"
+            "lbux    $t6,       $t6(%[srcAddr])          \n\t"
+            "lbux    $t7,       $t7(%[srcAddr])          \n\t"
+            "lbux    %[s0],     %[s0](%[srcAddr])        \n\t"
+            "lbux    %[s1],     %[s1](%[srcAddr])        \n\t"
+            "lbux    %[s2],     %[s2](%[srcAddr])        \n\t"
+            "lbux    %[s3],     %[s3](%[srcAddr])        \n\t"
+            "lbux    %[s4],     %[s4](%[srcAddr])        \n\t"
+            "lbux    %[s5],     %[s5](%[srcAddr])        \n\t"
+            "lbux    %[s6],     %[s6](%[srcAddr])        \n\t"
+            "lbux    %[s7],     %[s7](%[srcAddr])        \n\t"
+            "sll     $t0,       $t0,         2           \n\t"
+            "sll     $t1,       $t1,         2           \n\t"
+            "sll     $t2,       $t2,         2           \n\t"
+            "sll     $t3,       $t3,         2           \n\t"
+            "sll     $t4,       $t4,         2           \n\t"
+            "sll     $t5,       $t5,         2           \n\t"
+            "sll     $t6,       $t6,         2           \n\t"
+            "sll     $t7,       $t7,         2           \n\t"
+            "sll     %[s0],     %[s0],       2           \n\t"
+            "sll     %[s1],     %[s1],       2           \n\t"
+            "sll     %[s2],     %[s2],       2           \n\t"
+            "sll     %[s3],     %[s3],       2           \n\t"
+            "sll     %[s4],     %[s4],       2           \n\t"
+            "sll     %[s5],     %[s5],       2           \n\t"
+            "sll     %[s6],     %[s6],       2           \n\t"
+            "sll     %[s7],     %[s7],       2           \n\t"
+            "pref    0,         64(%[table])             \n\t"
+            "lwx     $t0,       $t0(%[table])            \n\t"
+            "lwx     $t1,       $t1(%[table])            \n\t"
+            "lwx     $t2,       $t2(%[table])            \n\t"
+            "lwx     $t3,       $t3(%[table])            \n\t"
+            "lwx     $t4,       $t4(%[table])            \n\t"
+            "lwx     $t5,       $t5(%[table])            \n\t"
+            "lwx     $t6,       $t6(%[table])            \n\t"
+            "lwx     $t7,       $t7(%[table])            \n\t"
+            "lwx     %[s0],     %[s0](%[table])          \n\t"
+            "lwx     %[s1],     %[s1](%[table])          \n\t"
+            "lwx     %[s2],     %[s2](%[table])          \n\t"
+            "lwx     %[s3],     %[s3](%[table])          \n\t"
+            "lwx     %[s4],     %[s4](%[table])          \n\t"
+            "lwx     %[s5],     %[s5](%[table])          \n\t"
+            "lwx     %[s6],     %[s6](%[table])          \n\t"
+            "lwx     %[s7],     %[s7](%[table])          \n\t"
+            "pref    30,        64(%[colors])            \n\t"
+            "sw      $t0,       0(%[colors])             \n\t"
+            "sw      $t1,       4(%[colors])             \n\t"
+            "sw      $t2,       8(%[colors])             \n\t"
+            "sw      $t3,       12(%[colors])            \n\t"
+            "sw      $t4,       16(%[colors])            \n\t"
+            "sw      $t5,       20(%[colors])            \n\t"
+            "sw      $t6,       24(%[colors])            \n\t"
+            "sw      $t7,       28(%[colors])            \n\t"
+            "sw      %[s0],     32(%[colors])            \n\t"
+            "sw      %[s1],     36(%[colors])            \n\t"
+            "sw      %[s2],     40(%[colors])            \n\t"
+            "sw      %[s3],     44(%[colors])            \n\t"
+            "sw      %[s4],     48(%[colors])            \n\t"
+            "sw      %[s5],     52(%[colors])            \n\t"
+            "sw      %[s6],     56(%[colors])            \n\t"
+            "sw      %[s7],     60(%[colors])            \n\t"
+            "addiu   %[xx],     %[xx],       32          \n\t"
+            "b       1b                                  \n\t"
+            " addiu  %[colors], %[colors],   64          \n\t"
+        "2:                                              \n\t"
+            "lhu     $t0,       0(%[xx])                 \n\t"
+            "lhu     $t1,       2(%[xx])                 \n\t"
+            "lhu     $t2,       4(%[xx])                 \n\t"
+            "lhu     $t3,       6(%[xx])                 \n\t"
+            "lhu     $t4,       8(%[xx])                 \n\t"
+            "lhu     $t5,       10(%[xx])                \n\t"
+            "lhu     $t6,       12(%[xx])                \n\t"
+            "lhu     $t7,       14(%[xx])                \n\t"
+            "lhu     %[s0],     16(%[xx])                \n\t"
+            "lhu     %[s1],     18(%[xx])                \n\t"
+            "lhu     %[s2],     20(%[xx])                \n\t"
+            "lhu     %[s3],     22(%[xx])                \n\t"
+            "lhu     %[s4],     24(%[xx])                \n\t"
+            "lhu     %[s5],     26(%[xx])                \n\t"
+            "lhu     %[s6],     28(%[xx])                \n\t"
+            "lhu     %[s7],     30(%[xx])                \n\t"
+            "lbux    $t0,       $t0(%[srcAddr])          \n\t"
+            "lbux    $t1,       $t1(%[srcAddr])          \n\t"
+            "lbux    $t2,       $t2(%[srcAddr])          \n\t"
+            "lbux    $t3,       $t3(%[srcAddr])          \n\t"
+            "lbux    $t4,       $t4(%[srcAddr])          \n\t"
+            "lbux    $t5,       $t5(%[srcAddr])          \n\t"
+            "lbux    $t6,       $t6(%[srcAddr])          \n\t"
+            "lbux    $t7,       $t7(%[srcAddr])          \n\t"
+            "lbux    %[s0],     %[s0](%[srcAddr])        \n\t"
+            "lbux    %[s1],     %[s1](%[srcAddr])        \n\t"
+            "lbux    %[s2],     %[s2](%[srcAddr])        \n\t"
+            "lbux    %[s3],     %[s3](%[srcAddr])        \n\t"
+            "lbux    %[s4],     %[s4](%[srcAddr])        \n\t"
+            "lbux    %[s5],     %[s5](%[srcAddr])        \n\t"
+            "lbux    %[s6],     %[s6](%[srcAddr])        \n\t"
+            "lbux    %[s7],     %[s7](%[srcAddr])        \n\t"
+            "sll     $t0,       $t0,         2           \n\t"
+            "sll     $t1,       $t1,         2           \n\t"
+            "sll     $t2,       $t2,         2           \n\t"
+            "sll     $t3,       $t3,         2           \n\t"
+            "sll     $t4,       $t4,         2           \n\t"
+            "sll     $t5,       $t5,         2           \n\t"
+            "sll     $t6,       $t6,         2           \n\t"
+            "sll     $t7,       $t7,         2           \n\t"
+            "sll     %[s0],     %[s0],       2           \n\t"
+            "sll     %[s1],     %[s1],       2           \n\t"
+            "sll     %[s2],     %[s2],       2           \n\t"
+            "sll     %[s3],     %[s3],       2           \n\t"
+            "sll     %[s4],     %[s4],       2           \n\t"
+            "sll     %[s5],     %[s5],       2           \n\t"
+            "sll     %[s6],     %[s6],       2           \n\t"
+            "sll     %[s7],     %[s7],       2           \n\t"
+            "lwx     $t0,       $t0(%[table])            \n\t"
+            "lwx     $t1,       $t1(%[table])            \n\t"
+            "lwx     $t2,       $t2(%[table])            \n\t"
+            "lwx     $t3,       $t3(%[table])            \n\t"
+            "lwx     $t4,       $t4(%[table])            \n\t"
+            "lwx     $t5,       $t5(%[table])            \n\t"
+            "lwx     $t6,       $t6(%[table])            \n\t"
+            "lwx     $t7,       $t7(%[table])            \n\t"
+            "lwx     %[s0],     %[s0](%[table])          \n\t"
+            "lwx     %[s1],     %[s1](%[table])          \n\t"
+            "lwx     %[s2],     %[s2](%[table])          \n\t"
+            "lwx     %[s3],     %[s3](%[table])          \n\t"
+            "lwx     %[s4],     %[s4](%[table])          \n\t"
+            "lwx     %[s5],     %[s5](%[table])          \n\t"
+            "lwx     %[s6],     %[s6](%[table])          \n\t"
+            "lwx     %[s7],     %[s7](%[table])          \n\t"
+            "sw      $t0,       0(%[colors])             \n\t"
+            "sw      $t1,       4(%[colors])             \n\t"
+            "sw      $t2,       8(%[colors])             \n\t"
+            "sw      $t3,       12(%[colors])            \n\t"
+            "sw      $t4,       16(%[colors])            \n\t"
+            "sw      $t5,       20(%[colors])            \n\t"
+            "sw      $t6,       24(%[colors])            \n\t"
+            "sw      $t7,       28(%[colors])            \n\t"
+            "sw      %[s0],     32(%[colors])            \n\t"
+            "sw      %[s1],     36(%[colors])            \n\t"
+            "sw      %[s2],     40(%[colors])            \n\t"
+            "sw      %[s3],     44(%[colors])            \n\t"
+            "sw      %[s4],     48(%[colors])            \n\t"
+            "sw      %[s5],     52(%[colors])            \n\t"
+            "sw      %[s6],     56(%[colors])            \n\t"
+            "sw      %[s7],     60(%[colors])            \n\t"
+            "addiu   %[xx],     %[xx],       32          \n\t"
+            "beqz    %[count],  4f                       \n\t"
+            " addiu  %[colors], %[colors],   64          \n\t"
+        "3:                                              \n\t"
+            "addiu   %[count],  %[count],    -1          \n\t"
+            "lhu     $t0,       0(%[xx])                 \n\t"
+            "lbux    $t1,       $t0(%[srcAddr])          \n\t"
+            "sll     $t1,       $t1,         2           \n\t"
+            "lwx     $t2,       $t1(%[table])            \n\t"
+            "sw      $t2,       0(%[colors])             \n\t"
+            "addiu   %[xx],     %[xx],       2           \n\t"
+            "bnez    %[count],  3b                       \n\t"
+            " addiu  %[colors], %[colors],   4           \n\t"
+        "4:                                              \n\t"
+            ".set    pop                                 \n\t"
+            : [xx]"+r"(xx), [count]"+r"(count), [colors]"+r"(colors),
+              [s0]"=&r"(s0), [s1]"=&r"(s1), [s2]"=&r"(s2), [s3]"=&r"(s3),
+              [s4]"=&r"(s4), [s5]"=&r"(s5), [s6]"=&r"(s6), [s7]"=&r"(s7)
+            : [table]"r"(table), [srcAddr]"r"(srcAddr)
+            : "memory", "t0", "t1", "t2", "t3",
+              "t4", "t5", "t6", "t7", "t8"
+        );
+    }
+    s.fBitmap->getColorTable()->unlockColors();
+}
+
+/*  If we replace a sampleproc, then we null-out the associated shaderproc,
+    otherwise the shader won't even look at the matrix/sampler
+ */
+
+void SkBitmapProcState::platformProcs() {
+    bool isOpaque = 256 == fAlphaScale;
+    bool justDx = false;
+
+    if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
+        justDx = true;
+    }
+
+    switch (fBitmap->colorType()) {
+        case kIndex_8_SkColorType:
+            if (justDx && SkPaint::kNone_FilterLevel == fFilterLevel) {
+                fSampleProc16 = SI8_D16_nofilter_DX_mips_dsp;
+                fShaderProc16 = NULL;
+                if (isOpaque) {
+                    fSampleProc32 = SI8_opaque_D32_nofilter_DX_mips_dsp;
+                    fShaderProc32 = NULL;
+                }
+            }
+            break;
+        default:
+            break;
+    }
+}
+
+void SkBitmapScaler::PlatformConvolutionProcs(SkConvolutionProcs*) {}
diff --git a/src/opts/SkBitmapProcState_opts_none.cpp b/src/opts/SkBitmapProcState_opts_none.cpp
index 96e711b..88aaa93 100644
--- a/src/opts/SkBitmapProcState_opts_none.cpp
+++ b/src/opts/SkBitmapProcState_opts_none.cpp
@@ -5,6 +5,8 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
+#include "SkBitmapScaler.h"
 #include "SkBitmapProcState.h"
 
 /*  A platform may optionally overwrite any of these with accelerated
@@ -23,4 +25,4 @@
 void SkBitmapProcState::platformProcs() {}
 
 // empty implementation just uses default supplied function pointers
-void SkBitmapProcState::platformConvolutionProcs(SkConvolutionProcs*) {}
+void SkBitmapScaler::PlatformConvolutionProcs(SkConvolutionProcs*) {}
diff --git a/src/opts/SkBlitRow_opts_SSE4.h b/src/opts/SkBlitRow_opts_SSE4.h
new file mode 100644
index 0000000..600e669
--- /dev/null
+++ b/src/opts/SkBlitRow_opts_SSE4.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBlitRow_opts_SSE4_DEFINED
+#define SkBlitRow_opts_SSE4_DEFINED
+
+#include "SkBlitRow.h"
+
+#ifdef CRBUG_399842_FIXED
+
+/* Check if we are able to build assembly code, GCC/AT&T syntax:
+ *  1) Clang and GCC are generally OK.  OS X's old LLVM-GCC 4.2 can't handle it;
+ *  2) We're intentionally not linking this in even when supported (Clang) on Windows;
+ *  3) MemorySanitizer cannot instrument assembly at all.
+ */
+#if /* 1)*/ (defined(__clang__) || (defined(__GNUC__) && !defined(SK_BUILD_FOR_MAC))) \
+    /* 2)*/ && !defined(SK_BUILD_FOR_WIN)                                             \
+    /* 3)*/ && !defined(MEMORY_SANITIZER)
+extern "C" void S32A_Opaque_BlitRow32_SSE4_asm(SkPMColor* SK_RESTRICT dst,
+                                               const SkPMColor* SK_RESTRICT src,
+                                               int count, U8CPU alpha);
+
+#define SK_ATT_ASM_SUPPORTED
+#endif
+
+#endif // CRBUG_399842_FIXED
+
+#endif
+
diff --git a/src/opts/SkBlitRow_opts_SSE4_asm.S b/src/opts/SkBlitRow_opts_SSE4_asm.S
new file mode 100644
index 0000000..0f52817
--- /dev/null
+++ b/src/opts/SkBlitRow_opts_SSE4_asm.S
@@ -0,0 +1,475 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifdef CRBUG_399842_FIXED
+
+#if defined(__clang__) || (defined(__GNUC__) && !defined(SK_BUILD_FOR_MAC))
+
+#define CFI_PUSH(REG) \
+    .cfi_adjust_cfa_offset 4; \
+    .cfi_rel_offset REG, 0
+
+#define CFI_POP(REG) \
+    .cfi_adjust_cfa_offset -4; \
+    .cfi_restore REG
+
+#define PUSH(REG) pushl REG; CFI_PUSH (REG)
+#define POP(REG)  popl REG; CFI_POP (REG)
+#define RETURN    POP(%edi); ret
+
+#define EXTRACT_ALPHA(var1, var2) \
+    movdqa      %var1, %var2;           /* Clone source pixels to extract alpha */\
+    psrlw       $8, %var2;              /* Discard red and blue, leaving alpha and green */\
+    pshufhw     $0xF5, %var2, %var2;    /* Repeat alpha for scaling (high) */\
+    movdqa      %xmm6, %xmm4;           \
+    pshuflw     $0xF5, %var2, %var2;    /* Repeat alpha for scaling (low) */\
+    movdqa      %xmm5, %xmm3;           \
+    psubw       %var2, %xmm4            /* Finalize alpha calculations */
+
+#define SCALE_PIXELS \
+    psllw       $8, %xmm5;              /* Filter out red and blue components */\
+    pmulhuw     %xmm4, %xmm5;           /* Scale red and blue */\
+    psrlw       $8, %xmm3;              /* Filter out alpha and green components */\
+    pmullw      %xmm4, %xmm3            /* Scale alpha and green */
+
+
+/*
+ * void S32A_Opaque_BlitRow32_SSE4(SkPMColor* SK_RESTRICT dst,
+ *                                 const SkPMColor* SK_RESTRICT src,
+ *                                 int count, U8CPU alpha)
+ *
+ * This function is divided into six blocks: initialization, blit 4-15 pixels,
+ * blit 0-3 pixels, align destination for 16+ pixel blits,
+ * blit 16+ pixels with source unaligned, blit 16+ pixels with source aligned.
+ * There are some code reuse between the blocks.
+ *
+ * The primary optimization comes from checking the source pixels' alpha value.
+ * If the alpha is zero, the pixel can be skipped entirely.
+ * If the alpha is fully opaque, the pixel can be copied directly to the destination.
+ * According to collected statistics, these two cases are the most common.
+ * The main loop(s) uses pre-loading and unrolling in an attempt to reduce the
+ * memory latency worse-case.
+ */
+
+#ifdef __clang__
+    .text
+#else
+    .section .text.sse4.2,"ax",@progbits
+    .type S32A_Opaque_BlitRow32_SSE4_asm, @function
+#endif
+    .p2align 4
+#if defined(SK_BUILD_FOR_MAC)
+    .global _S32A_Opaque_BlitRow32_SSE4_asm
+    .private_extern _S32A_Opaque_BlitRow32_SSE4_asm
+_S32A_Opaque_BlitRow32_SSE4_asm:
+#else
+    .global S32A_Opaque_BlitRow32_SSE4_asm
+    .hidden S32A_Opaque_BlitRow32_SSE4_asm
+S32A_Opaque_BlitRow32_SSE4_asm:
+#endif
+    .cfi_startproc
+    movl        8(%esp), %eax           // Source pointer
+    movl        12(%esp), %ecx          // Pixel count
+    movl        4(%esp), %edx           // Destination pointer
+    prefetcht0  (%eax)
+
+    // Setup SSE constants
+    pcmpeqd     %xmm7, %xmm7            // 0xFF000000 mask to check alpha
+    pslld       $24, %xmm7
+    pcmpeqw     %xmm6, %xmm6            // 16-bit 256 to calculate inv. alpha
+    psrlw       $15, %xmm6
+    psllw       $8, %xmm6
+    pcmpeqw     %xmm0, %xmm0            // 0x00FF00FF mask (Must be in xmm0 because of pblendvb)
+    psrlw       $8, %xmm0
+    subl        $4, %ecx                // Check if we have only 0-3 pixels
+    js          .LReallySmall
+    PUSH(%edi)
+    cmpl        $11, %ecx               // Do we have enough pixels to run the main loop?
+    ja          .LBigBlit
+
+    // Handle small blits (4-15 pixels)
+    ////////////////////////////////////////////////////////////////////////////////
+    xorl        %edi, %edi              // Reset offset to zero
+
+.LSmallLoop:
+    lddqu       (%eax, %edi), %xmm1     // Load four source pixels
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LSmallAlphaNotOpaqueOrZero
+    jz          .LSmallAlphaZero        // If all alphas are zero, skip the pixels completely
+    movdqu      %xmm1, (%edx, %edi)     // Store four destination pixels
+.LSmallAlphaZero:
+    addl        $16, %edi
+    subl        $4, %ecx                // Check if there are four additional pixels, at least
+    jns         .LSmallLoop
+    jmp         .LSmallRemaining
+
+    // Handle mixed alphas (calculate and scale)
+    .p2align 4
+.LSmallAlphaNotOpaqueOrZero:
+    lddqu       (%edx, %edi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    addl        $16, %edi
+    subl        $4, %ecx                // Check if there are four additional pixels, at least
+    pblendvb    %xmm5, %xmm3            // Mask in %xmm0, implicitly
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqu      %xmm1, -16(%edx, %edi)  // Store four destination pixels
+    jns         .LSmallLoop
+
+    // Handle the last 0-3 pixels (also used by the main loops)
+.LSmallRemaining:
+    cmpl        $-4, %ecx               // Check if we are done
+    je          .LSmallExit
+    sall        $2, %ecx                // Calculate offset for last pixels
+    addl        %ecx, %edi
+
+    lddqu       (%eax, %edi), %xmm1     // Load last four source pixels (overlapping)
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    jc          .LSmallRemainingStoreAll// If all alphas are opaque, just store (overlapping)
+    jz          .LSmallExit             // If all alphas are zero, skip the pixels completely
+
+    // Handle mixed alphas (calculate and scale)
+    lddqu       (%edx, %edi), %xmm5     // Load last four destination pixels (overlapping)
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+
+    psllw       $8, %xmm3               // Filter out red and blue components
+    pmulhuw     %xmm4, %xmm3            // Scale red and blue
+    movdqa      %xmm5, %xmm2
+    psrlw       $8, %xmm2               // Filter out alpha and green components
+    pmullw      %xmm4, %xmm2            // Scale alpha and green
+
+    cmpl        $-8, %ecx               // Check how many pixels should be written
+    pblendvb    %xmm3, %xmm2            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm2, %xmm1            // Add source and destination pixels together
+    jb          .LSmallPixelsLeft1
+    ja          .LSmallPixelsLeft3      // To avoid double-blending the overlapping pixels...
+    pblendw     $0xF0, %xmm1, %xmm5     // Merge only the final two pixels to the destination
+    movdqu      %xmm5, (%edx, %edi)     // Store last two destination pixels
+.LSmallExit:
+    RETURN
+
+.LSmallPixelsLeft1:
+    pblendw     $0xC0, %xmm1, %xmm5     // Merge only the final pixel to the destination
+    movdqu      %xmm5, (%edx, %edi)     // Store last destination pixel
+    RETURN
+
+.LSmallPixelsLeft3:
+    pblendw     $0xFC, %xmm1, %xmm5     // Merge only the final three pixels to the destination
+    movdqu      %xmm5, (%edx, %edi)     // Store last three destination pixels
+    RETURN
+
+.LSmallRemainingStoreAll:
+    movdqu      %xmm1, (%edx, %edi)     // Store last destination pixels (overwrite)
+    RETURN
+
+    // Handle really small blits (0-3 pixels)
+    ////////////////////////////////////////////////////////////////////////////////
+.LReallySmall:
+    addl        $4, %ecx
+    jle         .LReallySmallExit
+    pcmpeqd     %xmm1, %xmm1
+    cmp         $2, %ecx                // Check how many pixels should be read
+    pinsrd      $0x0, (%eax), %xmm1     // Load one source pixel
+    pinsrd      $0x0, (%edx), %xmm5     // Load one destination pixel
+    jb          .LReallySmallCalc
+    pinsrd      $0x1, 4(%eax), %xmm1    // Load second source pixel
+    pinsrd      $0x1, 4(%edx), %xmm5    // Load second destination pixel
+    je          .LReallySmallCalc
+    pinsrd      $0x2, 8(%eax), %xmm1    // Load third source pixel
+    pinsrd      $0x2, 8(%edx), %xmm5    // Load third destination pixel
+
+.LReallySmallCalc:
+    ptest       %xmm7, %xmm1            // Check if all alphas are opaque
+    jc          .LReallySmallStore      // If all alphas are opaque, just store
+
+    // Handle mixed alphas (calculate and scale)
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+
+    pand        %xmm0, %xmm5            // Filter out red and blue components
+    pmullw      %xmm4, %xmm5            // Scale red and blue
+    psrlw       $8, %xmm3               // Filter out alpha and green components
+    pmullw      %xmm4, %xmm3            // Scale alpha and green
+
+    psrlw       $8, %xmm5               // Combine results
+    pblendvb    %xmm5, %xmm3            // Mask in %xmm0, implicitly
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+
+.LReallySmallStore:
+    cmp         $2, %ecx                // Check how many pixels should be written
+    pextrd      $0x0, %xmm1, (%edx)     // Store one destination pixel
+    jb          .LReallySmallExit
+    pextrd      $0x1, %xmm1, 4(%edx)    // Store second destination pixel
+    je          .LReallySmallExit
+    pextrd      $0x2, %xmm1, 8(%edx)    // Store third destination pixel
+.LReallySmallExit:
+    ret
+
+    // Handle bigger blit operations (16+ pixels)
+    ////////////////////////////////////////////////////////////////////////////////
+    .p2align 4
+.LBigBlit:
+    // Align destination?
+    testl       $0xF, %edx
+    lddqu       (%eax), %xmm1           // Pre-load four source pixels
+    jz          .LAligned
+
+    movl        %edx, %edi              // Calculate alignment of destination pointer
+    negl        %edi
+    andl        $0xF, %edi
+
+    // Handle 1-3 pixels to align destination
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    jz          .LAlignDone             // If all alphas are zero, just skip
+    lddqu       (%edx), %xmm5           // Load four destination pixels
+    jc          .LAlignStore            // If all alphas are opaque, just store
+
+    // Handle mixed alphas (calculate and scale)
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+
+    psllw       $8, %xmm3               // Filter out red and blue components
+    pmulhuw     %xmm4, %xmm3            // Scale red and blue
+    movdqa      %xmm5, %xmm2
+    psrlw       $8, %xmm2               // Filter out alpha and green components
+    pmullw      %xmm4, %xmm2            // Scale alpha and green
+
+    pblendvb    %xmm3, %xmm2            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm2, %xmm1            // Add source and destination pixels together
+
+.LAlignStore:
+    cmp         $8, %edi                // Check how many pixels should be written
+    jb          .LAlignPixelsLeft1
+    ja          .LAlignPixelsLeft3
+    pblendw     $0x0F, %xmm1, %xmm5     // Blend two pixels
+    jmp .LAlignStorePixels
+
+.LAlignPixelsLeft1:
+    pblendw     $0x03, %xmm1, %xmm5     // Blend one pixel
+    jmp .LAlignStorePixels
+
+.LAlignPixelsLeft3:
+    pblendw     $0x3F, %xmm1, %xmm5     // Blend three pixels
+
+.LAlignStorePixels:
+    movdqu      %xmm5, (%edx)           // Store destination pixels
+
+.LAlignDone:
+    addl        %edi, %eax              // Adjust pointers and pixel count
+    addl        %edi, %edx
+    shrl        $2, %edi
+    lddqu       (%eax), %xmm1           // Pre-load new source pixels (after alignment)
+    subl        %edi, %ecx
+
+.LAligned:                              // Destination is guaranteed to be 16 byte aligned
+    xorl        %edi, %edi              // Reset offset to zero
+    subl        $8, %ecx                // Decrease counter (Reserve four pixels for the cleanup)
+    testl       $0xF, %eax              // Check alignment of source pointer
+    jz          .LAlignedLoop
+
+    // Source not aligned to destination
+    ////////////////////////////////////////////////////////////////////////////////
+    .p2align 4
+.LUnalignedLoop:                        // Main loop for unaligned, handles eight pixels per iteration
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero00
+    lddqu       16(%eax, %edi), %xmm2   // Pre-load four source pixels
+    jz          .LAlphaZero00
+    movdqa      %xmm1, (%edx, %edi)     // Store four destination pixels
+
+.LAlphaZero00:
+    ptest       %xmm7, %xmm2            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero01
+    lddqu       32(%eax, %edi), %xmm1   // Pre-load four source pixels
+    jz          .LAlphaZero01
+    movdqa      %xmm2, 16(%edx, %edi)   // Store four destination pixels
+
+.LAlphaZero01:
+    addl        $32, %edi               // Adjust offset and pixel count
+    subl        $8, %ecx
+    jae         .LUnalignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+    jmp         .LLoopCleanup0
+
+    .p2align 4
+.LAlphaNotOpaqueOrZero00:
+    movdqa      (%edx, %edi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    lddqu       16(%eax, %edi), %xmm2   // Pre-load four source pixels
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqa      %xmm1, (%edx, %edi)     // Store four destination pixels
+
+    // Handle next four pixels
+    ptest       %xmm7, %xmm2            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero01
+    lddqu       32(%eax, %edi), %xmm1   // Pre-load four source pixels
+    jz          .LAlphaZero02
+    movdqa      %xmm2, 16(%edx, %edi)   // Store four destination pixels
+.LAlphaZero02:
+    addl        $32, %edi               // Adjust offset and pixel count
+    subl        $8, %ecx
+    jae         .LUnalignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+    jmp         .LLoopCleanup0
+
+    .p2align 4
+.LAlphaNotOpaqueOrZero01:
+    movdqa      16(%edx, %edi), %xmm5   // Load four destination pixels
+    EXTRACT_ALPHA(xmm2, xmm1)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    lddqu       32(%eax, %edi), %xmm1   // Pre-load four source pixels
+    addl        $32, %edi
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm2            // Add source and destination pixels together
+    subl        $8, %ecx
+    movdqa      %xmm2, -16(%edx, %edi)  // Store four destination pixels
+    jae         .LUnalignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+
+    // Cleanup - handle pending pixels from loop
+.LLoopCleanup0:
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero02
+    jz          .LAlphaZero03
+    movdqa      %xmm1, (%edx, %edi)     // Store four destination pixels
+.LAlphaZero03:
+    addl        $16, %edi
+    subl        $4, %ecx
+    js          .LSmallRemaining        // Reuse code from small loop
+
+.LRemain0:
+    lddqu       (%eax, %edi), %xmm1     // Load four source pixels
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero02
+    jz          .LAlphaZero04
+    movdqa      %xmm1, (%edx, %edi)     // Store four destination pixels
+.LAlphaZero04:
+    addl        $16, %edi
+    subl        $4, %ecx
+    jmp         .LSmallRemaining        // Reuse code from small loop
+
+.LAlphaNotOpaqueOrZero02:
+    movdqa      (%edx, %edi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    addl        $16, %edi
+    subl        $4, %ecx
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqa      %xmm1, -16(%edx, %edi)  // Store four destination pixels
+    js          .LSmallRemaining        // Reuse code from small loop
+    jmp         .LRemain0
+
+    // Source aligned to destination
+    ////////////////////////////////////////////////////////////////////////////////
+    .p2align 4
+.LAlignedLoop:                          // Main loop for aligned, handles eight pixels per iteration
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero10
+    movdqa      16(%eax, %edi), %xmm2   // Pre-load four source pixels
+    jz          .LAlphaZero10
+    movdqa      %xmm1, (%edx, %edi)     // Store four destination pixels
+
+.LAlphaZero10:
+    ptest       %xmm7, %xmm2            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero11
+    movdqa      32(%eax, %edi), %xmm1   // Pre-load four source pixels
+    jz          .LAlphaZero11
+    movdqa      %xmm2, 16(%edx, %edi)   // Store four destination pixels
+
+.LAlphaZero11:
+    addl        $32, %edi               // Adjust offset and pixel count
+    subl        $8, %ecx
+    jae         .LAlignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+    jmp         .LLoopCleanup1
+
+    .p2align 4
+.LAlphaNotOpaqueOrZero10:
+    movdqa      (%edx, %edi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    movdqa      16(%eax, %edi), %xmm2   // Pre-load four source pixels
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqa      %xmm1, (%edx, %edi)     // Store four destination pixels
+
+    // Handle next four pixels
+    ptest       %xmm7, %xmm2            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero11
+    movdqa      32(%eax, %edi), %xmm1   // Pre-load four source pixels
+    jz          .LAlphaZero12
+    movdqa      %xmm2, 16(%edx, %edi)   // Store four destination pixels
+.LAlphaZero12:
+    addl        $32, %edi               // Adjust offset and pixel count
+    subl        $8, %ecx
+    jae         .LAlignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+    jmp         .LLoopCleanup1
+
+    .p2align 4
+.LAlphaNotOpaqueOrZero11:
+    movdqa      16(%edx, %edi), %xmm5   // Load four destination pixels
+    EXTRACT_ALPHA(xmm2, xmm1)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+    movdqa      32(%eax, %edi), %xmm1   // Pre-load four source pixels
+
+    addl        $32, %edi
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm2            // Add source and destination pixels together
+    subl        $8, %ecx
+    movdqa      %xmm2, -16(%edx, %edi)  // Store four destination pixels
+    jae         .LAlignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+
+    // Cleanup - handle pending pixels from loop
+.LLoopCleanup1:
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero12
+    jz          .LAlphaZero13
+    movdqa      %xmm1, (%edx, %edi)     // Store four destination pixels
+.LAlphaZero13:
+    addl        $16, %edi
+    subl        $4, %ecx
+    js          .LSmallRemaining        // Reuse code from small loop
+
+.LRemain1:
+    movdqa      (%eax, %edi), %xmm1     // Load four source pixels
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero12
+    jz          .LAlphaZero14
+    movdqa      %xmm1, (%edx, %edi)     // Store four destination pixels
+.LAlphaZero14:
+    addl        $16, %edi
+    subl        $4, %ecx
+    jmp         .LSmallRemaining        // Reuse code from small loop
+
+.LAlphaNotOpaqueOrZero12:
+    movdqa      (%edx, %edi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    addl        $16, %edi
+    subl        $4, %ecx
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqa      %xmm1, -16(%edx, %edi)  // Store four destination pixels
+    js          .LSmallRemaining        // Reuse code from small loop
+    jmp         .LRemain1
+
+    .cfi_endproc
+#ifndef __clang__
+    .size S32A_Opaque_BlitRow32_SSE4_asm, .-S32A_Opaque_BlitRow32_SSE4_asm
+#endif
+#endif
+
+#endif // CRBUG_399842_FIXED
diff --git a/src/opts/SkBlitRow_opts_SSE4_x64_asm.S b/src/opts/SkBlitRow_opts_SSE4_x64_asm.S
new file mode 100644
index 0000000..9a754a6
--- /dev/null
+++ b/src/opts/SkBlitRow_opts_SSE4_x64_asm.S
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifdef CRBUG_399842_FIXED
+
+#if defined(__clang__) || (defined(__GNUC__) && !defined(SK_BUILD_FOR_MAC))
+
+#define EXTRACT_ALPHA(var1, var2) \
+    movdqa      %var1, %var2;           /* Clone source pixels to extract alpha */\
+    psrlw       $8, %var2;              /* Discard red and blue, leaving alpha and green */\
+    pshufhw     $0xF5, %var2, %var2;    /* Repeat alpha for scaling (high) */\
+    movdqa      %xmm6, %xmm4;           \
+    pshuflw     $0xF5, %var2, %var2;    /* Repeat alpha for scaling (low) */\
+    movdqa      %xmm5, %xmm3;           \
+    psubw       %var2, %xmm4            /* Finalize alpha calculations */
+
+#define SCALE_PIXELS \
+    psllw       $8, %xmm5;              /* Filter out red and blue components */\
+    pmulhuw     %xmm4, %xmm5;           /* Scale red and blue */\
+    psrlw       $8, %xmm3;              /* Filter out alpha and green components */\
+    pmullw      %xmm4, %xmm3            /* Scale alpha and green */
+
+
+/*
+ * void S32A_Opaque_BlitRow32_SSE4(SkPMColor* SK_RESTRICT dst,
+ *                                 const SkPMColor* SK_RESTRICT src,
+ *                                 int count, U8CPU alpha)
+ *
+ * This function is divided into six blocks: initialization, blit 4-15 pixels,
+ * blit 0-3 pixels, align destination for 16+ pixel blits,
+ * blit 16+ pixels with source unaligned, blit 16+ pixels with source aligned.
+ * There are some code reuse between the blocks.
+ *
+ * The primary optimization comes from checking the source pixels' alpha value.
+ * If the alpha is zero, the pixel can be skipped entirely.
+ * If the alpha is fully opaque, the pixel can be copied directly to the destination.
+ * According to collected statistics, these two cases are the most common.
+ * The main loop(s) uses pre-loading and unrolling in an attempt to reduce the
+ * memory latency worse-case.
+ */
+
+#ifdef __clang__
+    .text
+#else
+    .section .text.sse4.2,"ax",@progbits
+    .type S32A_Opaque_BlitRow32_SSE4_asm, @function
+#endif
+    .p2align 4
+#if defined(SK_BUILD_FOR_MAC)
+    .global _S32A_Opaque_BlitRow32_SSE4_asm
+    .private_extern _S32A_Opaque_BlitRow32_SSE4_asm
+_S32A_Opaque_BlitRow32_SSE4_asm:
+#else
+    .global S32A_Opaque_BlitRow32_SSE4_asm
+    .hidden S32A_Opaque_BlitRow32_SSE4_asm
+S32A_Opaque_BlitRow32_SSE4_asm:
+#endif
+    .cfi_startproc
+    prefetcht0  (%rsi)
+    movl        %edx, %ecx              // Pixel count
+    movq        %rdi, %rdx              // Destination pointer
+    movq        %rsi, %rax              // Source pointer
+
+    // Setup SSE constants
+    movdqa      .LAlphaCheckMask(%rip), %xmm7  // 0xFF000000 mask to check alpha
+    movdqa      .LInverseAlphaCalc(%rip), %xmm6// 16-bit 256 to calculate inv. alpha
+    movdqa      .LResultMergeMask(%rip), %xmm0 // 0x00FF00FF mask (Must be in xmm0 because of pblendvb)
+
+    subl        $4, %ecx                // Check if we have only 0-3 pixels
+    js          .LReallySmall
+    cmpl        $11, %ecx               // Do we have enough pixels to run the main loop?
+    ja          .LBigBlit
+
+    // Handle small blits (4-15 pixels)
+    ////////////////////////////////////////////////////////////////////////////////
+    xorq        %rdi, %rdi              // Reset offset to zero
+
+.LSmallLoop:
+    lddqu       (%rax, %rdi), %xmm1     // Load four source pixels
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LSmallAlphaNotOpaqueOrZero
+    jz          .LSmallAlphaZero
+    movdqu      %xmm1, (%rdx, %rdi)     // Store four destination pixels
+.LSmallAlphaZero:
+    addq        $16, %rdi
+    subl        $4, %ecx                // Check if there are four additional pixels, at least
+    jns         .LSmallLoop
+    jmp         .LSmallRemaining
+
+    // Handle mixed alphas (calculate and scale)
+    .p2align 4
+.LSmallAlphaNotOpaqueOrZero:
+    lddqu       (%rdx, %rdi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    addq        $16, %rdi
+    subl        $4, %ecx                // Check if there are four additional pixels, at least
+    pblendvb    %xmm5, %xmm3            // Mask in %xmm0, implicitly
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqu      %xmm1, -16(%rdx, %rdi)  // Store four destination pixels
+    jns         .LSmallLoop
+
+    // Handle the last 0-3 pixels (also used by the main loops)
+.LSmallRemaining:
+    cmpl        $-4, %ecx               // Check if we are done
+    je          .LSmallExit
+    sall        $2, %ecx                // Calculate offset for last pixels
+    movslq      %ecx, %rcx
+    addq        %rcx, %rdi
+
+    lddqu       (%rax, %rdi), %xmm1     // Load last four source pixels (overlapping)
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    jc          .LSmallRemainingStoreAll// If all alphas are opaque, just store (overlapping)
+    jz          .LSmallExit             // If all alphas are zero, skip the pixels completely
+
+    // Handle mixed alphas (calculate and scale)
+    lddqu       (%rdx, %rdi), %xmm5     // Load last four destination pixels (overlapping)
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+
+    psllw       $8, %xmm3               // Filter out red and blue components
+    pmulhuw     %xmm4, %xmm3            // Scale red and blue
+    movdqa      %xmm5, %xmm2
+    psrlw       $8, %xmm2               // Filter out alpha and green components
+    pmullw      %xmm4, %xmm2            // Scale alpha and green
+
+    cmpl        $-8, %ecx               // Check how many pixels should be written
+    pblendvb    %xmm3, %xmm2            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm2, %xmm1            // Add source and destination pixels together
+    jb          .LSmallPixelsLeft1
+    ja          .LSmallPixelsLeft3      // To avoid double-blending the overlapping pixels...
+    pblendw     $0xF0, %xmm1, %xmm5     // Merge only the final two pixels to the destination
+    movdqu      %xmm5, (%rdx, %rdi)     // Store last two destination pixels
+.LSmallExit:
+    ret
+
+.LSmallPixelsLeft1:
+    pblendw     $0xC0, %xmm1, %xmm5     // Merge only the final pixel to the destination
+    movdqu      %xmm5, (%rdx, %rdi)     // Store last destination pixel
+    ret
+
+.LSmallPixelsLeft3:
+    pblendw     $0xFC, %xmm1, %xmm5     // Merge only the final three pixels to the destination
+    movdqu      %xmm5, (%rdx, %rdi)     // Store last three destination pixels
+    ret
+
+.LSmallRemainingStoreAll:
+    movdqu      %xmm1, (%rdx, %rdi)     // Store last destination pixels (overwrite)
+    ret
+
+    // Handle really small blits (0-3 pixels)
+    ////////////////////////////////////////////////////////////////////////////////
+.LReallySmall:
+    addl        $4, %ecx
+    jle         .LReallySmallExit
+    pcmpeqd     %xmm1, %xmm1
+    cmpl        $2, %ecx                // Check how many pixels should be read
+    pinsrd      $0x0, (%rax), %xmm1     // Load one source pixel
+    pinsrd      $0x0, (%rdx), %xmm5     // Load one destination pixel
+    jb          .LReallySmallCalc
+    pinsrd      $0x1, 4(%rax), %xmm1    // Load second source pixel
+    pinsrd      $0x1, 4(%rdx), %xmm5    // Load second destination pixel
+    je          .LReallySmallCalc
+    pinsrd      $0x2, 8(%rax), %xmm1    // Load third source pixel
+    pinsrd      $0x2, 8(%rdx), %xmm5    // Load third destination pixel
+
+.LReallySmallCalc:
+    ptest       %xmm7, %xmm1            // Check if all alphas are opaque
+    jc          .LReallySmallStore      // If all alphas are opaque, just store
+
+    // Handle mixed alphas (calculate and scale)
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+
+    pand        %xmm0, %xmm5            // Filter out red and blue components
+    pmullw      %xmm4, %xmm5            // Scale red and blue
+    psrlw       $8, %xmm3               // Filter out alpha and green components
+    pmullw      %xmm4, %xmm3            // Scale alpha and green
+
+    psrlw       $8, %xmm5               // Combine results
+    pblendvb    %xmm5, %xmm3            // Mask in %xmm0, implicitly
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+
+.LReallySmallStore:
+    cmpl        $2, %ecx                // Check how many pixels should be written
+    pextrd      $0x0, %xmm1, (%rdx)     // Store one destination pixel
+    jb          .LReallySmallExit
+    pextrd      $0x1, %xmm1, 4(%rdx)    // Store second destination pixel
+    je          .LReallySmallExit
+    pextrd      $0x2, %xmm1, 8(%rdx)    // Store third destination pixel
+.LReallySmallExit:
+    ret
+
+    // Handle bigger blit operations (16+ pixels)
+    ////////////////////////////////////////////////////////////////////////////////
+    .p2align 4
+.LBigBlit:
+    // Align destination?
+    testl       $0xF, %edx
+    lddqu       (%rax), %xmm1           // Pre-load four source pixels
+    jz          .LAligned
+
+    movq        %rdx, %rdi              // Calculate alignment of destination pointer
+    negq        %rdi
+    andl        $0xF, %edi
+
+    // Handle 1-3 pixels to align destination
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    jz          .LAlignDone             // If all alphas are zero, just skip
+    lddqu       (%rdx), %xmm5           // Load four destination pixels
+    jc          .LAlignStore            // If all alphas are opaque, just store
+
+    // Handle mixed alphas (calculate and scale)
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+
+    psllw       $8, %xmm3               // Filter out red and blue components
+    pmulhuw     %xmm4, %xmm3            // Scale red and blue
+    movdqa      %xmm5, %xmm2
+    psrlw       $8, %xmm2               // Filter out alpha and green components
+    pmullw      %xmm4, %xmm2            // Scale alpha and green
+
+    pblendvb    %xmm3, %xmm2            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm2, %xmm1            // Add source and destination pixels together
+
+.LAlignStore:
+    cmpl        $8, %edi                // Check how many pixels should be written
+    jb          .LAlignPixelsLeft1
+    ja          .LAlignPixelsLeft3
+    pblendw     $0x0F, %xmm1, %xmm5     // Blend two pixels
+    jmp .LAlignStorePixels
+
+.LAlignPixelsLeft1:
+    pblendw     $0x03, %xmm1, %xmm5     // Blend one pixel
+    jmp .LAlignStorePixels
+
+.LAlignPixelsLeft3:
+    pblendw     $0x3F, %xmm1, %xmm5     // Blend three pixels
+
+.LAlignStorePixels:
+    movdqu      %xmm5, (%rdx)           // Store destination pixels
+
+.LAlignDone:
+    addq        %rdi, %rax              // Adjust pointers and pixel count
+    addq        %rdi, %rdx
+    shrq        $2, %rdi
+    lddqu       (%rax), %xmm1           // Pre-load new source pixels (after alignment)
+    subl        %edi, %ecx
+
+.LAligned:                              // Destination is guaranteed to be 16 byte aligned
+    xorq        %rdi, %rdi              // Reset offset to zero
+    subl        $8, %ecx                // Decrease counter (Reserve four pixels for the cleanup)
+    testl       $0xF, %eax              // Check alignment of source pointer
+    jz          .LAlignedLoop
+
+    // Source not aligned to destination
+    ////////////////////////////////////////////////////////////////////////////////
+    .p2align 4
+.LUnalignedLoop:                        // Main loop for unaligned, handles eight pixels per iteration
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero00
+    lddqu       16(%rax, %rdi), %xmm2   // Pre-load four source pixels
+    jz          .LAlphaZero00
+    movdqa      %xmm1, (%rdx, %rdi)     // Store four destination pixels
+
+.LAlphaZero00:
+    ptest       %xmm7, %xmm2            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero01
+    lddqu       32(%rax, %rdi), %xmm1   // Pre-load four source pixels
+    jz          .LAlphaZero01
+    movdqa      %xmm2, 16(%rdx, %rdi)   // Store four destination pixels
+
+.LAlphaZero01:
+    addq        $32, %rdi               // Adjust offset and pixel count
+    subl        $8, %ecx
+    jae         .LUnalignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+    jmp         .LLoopCleanup0
+
+    .p2align 4
+.LAlphaNotOpaqueOrZero00:
+    movdqa      (%rdx, %rdi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    lddqu       16(%rax, %rdi), %xmm2   // Pre-load four source pixels
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqa      %xmm1, (%rdx, %rdi)     // Store four destination pixels
+
+    // Handle next four pixels
+    ptest       %xmm7, %xmm2            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero01
+    lddqu       32(%rax, %rdi), %xmm1   // Pre-load four source pixels
+    jz          .LAlphaZero02
+    movdqa      %xmm2, 16(%rdx, %rdi)   // Store four destination pixels
+.LAlphaZero02:
+    addq        $32, %rdi               // Adjust offset and pixel count
+    subl        $8, %ecx
+    jae         .LUnalignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+    jmp         .LLoopCleanup0
+
+    .p2align 4
+.LAlphaNotOpaqueOrZero01:
+    movdqa      16(%rdx, %rdi), %xmm5   // Load four destination pixels
+    EXTRACT_ALPHA(xmm2, xmm1)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    lddqu       32(%rax, %rdi), %xmm1   // Pre-load four source pixels
+    addq        $32, %rdi
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm2            // Add source and destination pixels together
+    subl        $8, %ecx
+    movdqa      %xmm2, -16(%rdx, %rdi)  // Store four destination pixels
+    jae         .LUnalignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+
+    // Cleanup - handle pending pixels from loop
+.LLoopCleanup0:
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero02
+    jz          .LAlphaZero03
+    movdqa      %xmm1, (%rdx, %rdi)     // Store four destination pixels
+.LAlphaZero03:
+    addq        $16, %rdi
+    subl        $4, %ecx
+    js          .LSmallRemaining        // Reuse code from small loop
+
+.LRemain0:
+    lddqu       (%rax, %rdi), %xmm1     // Load four source pixels
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero02
+    jz          .LAlphaZero04
+    movdqa      %xmm1, (%rdx, %rdi)     // Store four destination pixels
+.LAlphaZero04:
+    addq        $16, %rdi
+    subl        $4, %ecx
+    jmp         .LSmallRemaining        // Reuse code from small loop
+
+.LAlphaNotOpaqueOrZero02:
+    movdqa      (%rdx, %rdi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    addq        $16, %rdi
+    subl        $4, %ecx
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqa      %xmm1, -16(%rdx, %rdi)  // Store four destination pixels
+    js          .LSmallRemaining        // Reuse code from small loop
+    jmp         .LRemain0
+
+    // Source aligned to destination
+    ////////////////////////////////////////////////////////////////////////////////
+    .p2align 4
+.LAlignedLoop:                          // Main loop for aligned, handles eight pixels per iteration
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero10
+    movdqa      16(%rax, %rdi), %xmm2   // Pre-load four source pixels
+    jz          .LAlphaZero10
+    movdqa      %xmm1, (%rdx, %rdi)     // Store four destination pixels
+
+.LAlphaZero10:
+    ptest       %xmm7, %xmm2            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero11
+    movdqa      32(%rax, %rdi), %xmm1   // Pre-load four source pixels
+    jz          .LAlphaZero11
+    movdqa      %xmm2, 16(%rdx, %rdi)   // Store four destination pixels
+
+.LAlphaZero11:
+    addq        $32, %rdi               // Adjust offset and pixel count
+    subl        $8, %ecx
+    jae         .LAlignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+    jmp         .LLoopCleanup1
+
+    .p2align 4
+.LAlphaNotOpaqueOrZero10:
+    movdqa      (%rdx, %rdi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    movdqa      16(%rax, %rdi), %xmm2   // Pre-load four source pixels
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqa      %xmm1, (%rdx, %rdi)     // Store four destination pixels
+
+    // Handle next four pixels
+    ptest       %xmm7, %xmm2            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero11
+    movdqa      32(%rax, %rdi), %xmm1   // Pre-load four source pixels
+    jz          .LAlphaZero12
+    movdqa      %xmm2, 16(%rdx, %rdi)   // Store four destination pixels
+.LAlphaZero12:
+    addq        $32, %rdi               // Adjust offset and pixel count
+    subl        $8, %ecx
+    jae         .LAlignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+    jmp         .LLoopCleanup1
+
+    .p2align 4
+.LAlphaNotOpaqueOrZero11:
+    movdqa      16(%rdx, %rdi), %xmm5   // Load four destination pixels
+    EXTRACT_ALPHA(xmm2, xmm1)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+    movdqa      32(%rax, %rdi), %xmm1   // Pre-load four source pixels
+
+    addq        $32, %rdi
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm2            // Add source and destination pixels together
+    subl        $8, %ecx
+    movdqa      %xmm2, -16(%rdx, %rdi)  // Store four destination pixels
+    jae         .LAlignedLoop
+    addl        $8, %ecx                // Adjust pixel count
+
+    // Cleanup - handle four pending pixels from loop
+.LLoopCleanup1:
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero12
+    jz          .LAlphaZero13
+    movdqa      %xmm1, (%rdx, %rdi)     // Store four destination pixels
+.LAlphaZero13:
+    addq        $16, %rdi
+    subl        $4, %ecx
+    js          .LSmallRemaining        // Reuse code from small loop
+
+.LRemain1:
+    movdqa      (%rax, %rdi), %xmm1     // Pre-load four source pixels
+    ptest       %xmm7, %xmm1            // Check if all alphas are zero or opaque
+    ja          .LAlphaNotOpaqueOrZero12
+    jz          .LAlphaZero14
+    movdqa      %xmm1, (%rdx, %rdi)     // Store four destination pixels
+.LAlphaZero14:
+    addq        $16, %rdi
+    subl        $4, %ecx
+    jmp         .LSmallRemaining        // Reuse code from small loop
+
+.LAlphaNotOpaqueOrZero12:
+    movdqa      (%rdx, %rdi), %xmm5     // Load four destination pixels
+    EXTRACT_ALPHA(xmm1, xmm2)           // Extract and clone alpha value
+    SCALE_PIXELS                        // Scale pixels using alpha
+
+    addq        $16, %rdi
+    subl        $4, %ecx
+    pblendvb    %xmm5, %xmm3            // Combine results (mask in %xmm0, implicitly)
+    paddb       %xmm3, %xmm1            // Add source and destination pixels together
+    movdqa      %xmm1, -16(%rdx, %rdi)  // Store four destination pixels
+    js          .LSmallRemaining        // Reuse code from small loop
+    jmp         .LRemain1
+
+    .cfi_endproc
+#ifndef __clang__
+    .size S32A_Opaque_BlitRow32_SSE4_asm, .-S32A_Opaque_BlitRow32_SSE4_asm
+#endif
+
+    // Constants for SSE code
+#ifndef __clang__
+    .section .rodata
+#endif
+    .p2align 4
+.LAlphaCheckMask:
+    .long   0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000
+.LInverseAlphaCalc:
+    .word   256, 256, 256, 256, 256, 256, 256, 256
+.LResultMergeMask:
+    .long   0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF
+#endif
+
+#endif // CRBUG_399842_FIXED
diff --git a/src/opts/SkBlitRow_opts_arm.cpp b/src/opts/SkBlitRow_opts_arm.cpp
index 34b8564..473a3e9 100644
--- a/src/opts/SkBlitRow_opts_arm.cpp
+++ b/src/opts/SkBlitRow_opts_arm.cpp
@@ -37,7 +37,9 @@
                   "and     r4, r3, #0x0000f8            \n\t"
                   "and     r5, r3, #0x00fc00            \n\t"
                   "and     r6, r3, #0xf80000            \n\t"
+#ifdef SK_ARM_HAS_EDSP
                   "pld     [r1, #32]                    \n\t"
+#endif
                   "lsl     r3, r4, #8                   \n\t"
                   "orr     r3, r3, r5, lsr #5           \n\t"
                   "orr     r3, r3, r6, lsr #19          \n\t"
@@ -51,13 +53,15 @@
                   "ldrh    r4, [%[dst]]                 \n\t"
                   "rsb     r7, r7, #255                 \n\t"
                   "and     r6, r4, #0x001f              \n\t"
-#if SK_ARM_ARCH == 6
+#if SK_ARM_ARCH <= 6
                   "lsl     r5, r4, #21                  \n\t"
                   "lsr     r5, r5, #26                  \n\t"
 #else
                   "ubfx    r5, r4, #5, #6               \n\t"
 #endif
+#ifdef SK_ARM_HAS_EDSP
                   "pld     [r0, #16]                    \n\t"
+#endif
                   "lsr     r4, r4, #11                  \n\t"
 #ifdef SK_ARM_HAS_EDSP
                   "smulbb  r6, r6, r7                   \n\t"
@@ -68,8 +72,14 @@
                   "mul     r5, r5, r7                   \n\t"
                   "mul     r4, r4, r7                   \n\t"
 #endif
+#if SK_ARM_ARCH >= 6
                   "uxtb    r7, r3, ROR #16              \n\t"
                   "uxtb    ip, r3, ROR #8               \n\t"
+#else
+                  "mov     ip, #0xff                    \n\t"
+                  "and     r7, ip, r3, ROR #16          \n\t"
+                  "and     ip, ip, r3, ROR #8           \n\t"
+#endif
                   "and     r3, r3, #0xff                \n\t"
                   "add     r6, r6, #16                  \n\t"
                   "add     r5, r5, #32                  \n\t"
@@ -86,7 +96,9 @@
                   "orr     r6, r6, r5, lsl #3           \n\t"
                   "orr     r4, r6, r4, lsl #8           \n\t"
                   "strh    r4, [%[dst]], #2             \n\t"
+#ifdef SK_ARM_HAS_EDSP
                   "pld     [r1, #32]                    \n\t"
+#endif
                   "subs    %[count], %[count], #1       \n\t"
                   "bne     1b                           \n\t"
                   "b       4f                           \n\t"
diff --git a/src/opts/SkBlitRow_opts_arm_neon.cpp b/src/opts/SkBlitRow_opts_arm_neon.cpp
index 01a6a2a..b372d16 100644
--- a/src/opts/SkBlitRow_opts_arm_neon.cpp
+++ b/src/opts/SkBlitRow_opts_arm_neon.cpp
@@ -299,7 +299,7 @@
 
                       "11:                                        \n\t"
                       // unzips achieve the same as a vld4 operation
-                      "vuzpq.u16  q0, q1                      \n\t"
+                      "vuzp.u16   q0, q1                      \n\t"
                       "vuzp.u8    d0, d1                      \n\t"
                       "vuzp.u8    d2, d3                      \n\t"
                       // expand 0565 q12 to 8888 {d4-d7}
@@ -365,7 +365,105 @@
                       );
     }
 }
+
+#else // #ifdef SK_CPU_ARM32
+
+void S32A_D565_Opaque_neon(uint16_t* SK_RESTRICT dst,
+                           const SkPMColor* SK_RESTRICT src, int count,
+                           U8CPU alpha, int /*x*/, int /*y*/) {
+    SkASSERT(255 == alpha);
+
+    if (count >= 16) {
+        asm (
+            "movi    v4.8h, #0x80                   \t\n"
+
+            "1:                                     \t\n"
+            "sub     %[count], %[count], #16        \t\n"
+            "ld1     {v16.8h-v17.8h}, [%[dst]]      \t\n"
+            "ld4     {v0.16b-v3.16b}, [%[src]], #64 \t\n"
+            "prfm    pldl1keep, [%[src],#512]       \t\n"
+            "prfm    pldl1keep, [%[dst],#256]       \t\n"
+            "ushr    v20.8h, v17.8h, #5             \t\n"
+            "ushr    v31.8h, v16.8h, #5             \t\n"
+            "xtn     v6.8b, v31.8h                  \t\n"
+            "xtn2    v6.16b, v20.8h                 \t\n"
+            "ushr    v20.8h, v17.8h, #11            \t\n"
+            "shl     v19.16b, v6.16b, #2            \t\n"
+            "ushr    v31.8h, v16.8h, #11            \t\n"
+            "xtn     v22.8b, v31.8h                 \t\n"
+            "xtn2    v22.16b, v20.8h                \t\n"
+            "shl     v18.16b, v22.16b, #3           \t\n"
+            "mvn     v3.16b, v3.16b                 \t\n"
+            "xtn     v16.8b, v16.8h                 \t\n"
+            "mov     v7.16b, v4.16b                 \t\n"
+            "xtn2    v16.16b, v17.8h                \t\n"
+            "umlal   v7.8h, v3.8b, v19.8b           \t\n"
+            "shl     v16.16b, v16.16b, #3           \t\n"
+            "mov     v22.16b, v4.16b                \t\n"
+            "ushr    v24.8h, v7.8h, #6              \t\n"
+            "umlal   v22.8h, v3.8b, v18.8b          \t\n"
+            "ushr    v20.8h, v22.8h, #5             \t\n"
+            "addhn   v20.8b, v22.8h, v20.8h         \t\n"
+            "cmp     %[count], #16                  \t\n"
+            "mov     v6.16b, v4.16b                 \t\n"
+            "mov     v5.16b, v4.16b                 \t\n"
+            "umlal   v6.8h, v3.8b, v16.8b           \t\n"
+            "umlal2  v5.8h, v3.16b, v19.16b         \t\n"
+            "mov     v17.16b, v4.16b                \t\n"
+            "ushr    v19.8h, v6.8h, #5              \t\n"
+            "umlal2  v17.8h, v3.16b, v18.16b        \t\n"
+            "addhn   v7.8b, v7.8h, v24.8h           \t\n"
+            "ushr    v18.8h, v5.8h, #6              \t\n"
+            "ushr    v21.8h, v17.8h, #5             \t\n"
+            "addhn2  v7.16b, v5.8h, v18.8h          \t\n"
+            "addhn2  v20.16b, v17.8h, v21.8h        \t\n"
+            "mov     v22.16b, v4.16b                \t\n"
+            "addhn   v6.8b, v6.8h, v19.8h           \t\n"
+            "umlal2  v22.8h, v3.16b, v16.16b        \t\n"
+            "ushr    v5.8h, v22.8h, #5              \t\n"
+            "addhn2  v6.16b, v22.8h, v5.8h          \t\n"
+            "uqadd   v7.16b, v1.16b, v7.16b         \t\n"
+#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
+            "uqadd   v20.16b, v2.16b, v20.16b       \t\n"
+            "uqadd   v6.16b, v0.16b, v6.16b         \t\n"
+#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
+            "uqadd   v20.16b, v0.16b, v20.16b       \t\n"
+            "uqadd   v6.16b, v2.16b, v6.16b         \t\n"
+#else
+#error "This function only supports BGRA and RGBA."
 #endif
+            "shll    v22.8h, v20.8b, #8             \t\n"
+            "shll    v5.8h, v7.8b, #8               \t\n"
+            "sri     v22.8h, v5.8h, #5              \t\n"
+            "shll    v17.8h, v6.8b, #8              \t\n"
+            "shll2   v23.8h, v20.16b, #8            \t\n"
+            "shll2   v7.8h, v7.16b, #8              \t\n"
+            "sri     v22.8h, v17.8h, #11            \t\n"
+            "sri     v23.8h, v7.8h, #5              \t\n"
+            "shll2   v6.8h, v6.16b, #8              \t\n"
+            "st1     {v22.8h}, [%[dst]], #16        \t\n"
+            "sri     v23.8h, v6.8h, #11             \t\n"
+            "st1     {v23.8h}, [%[dst]], #16        \t\n"
+            "b.ge    1b                             \t\n"
+            : [dst] "+&r" (dst), [src] "+&r" (src), [count] "+&r" (count)
+            :: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
+               "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24",
+               "v31"
+        );
+    }
+        // Leftovers
+    if (count > 0) {
+        do {
+            SkPMColor c = *src++;
+            SkPMColorAssert(c);
+            if (c) {
+                *dst = SkSrcOver32To16(c, *dst);
+            }
+            dst += 1;
+        } while (--count != 0);
+    }
+}
+#endif // #ifdef SK_CPU_ARM32
 
 static inline uint16x8_t SkDiv255Round_neon8(uint16x8_t prod) {
     prod += vdupq_n_u16(128);
@@ -1552,12 +1650,13 @@
     // no dither
     S32_D565_Opaque_neon,
     S32_D565_Blend_neon,
-#ifdef SK_CPU_ARM32
     S32A_D565_Opaque_neon,
-#else
-    NULL,
-#endif
+#if 0
     S32A_D565_Blend_neon,
+#else
+    NULL,   // https://code.google.com/p/skia/issues/detail?id=2845
+            // https://code.google.com/p/skia/issues/detail?id=2797
+#endif
 
     // dither
     S32_D565_Opaque_Dither_neon,
diff --git a/src/opts/SkBlitRow_opts_mips_dsp.cpp b/src/opts/SkBlitRow_opts_mips_dsp.cpp
index 30bb4c2..3d4a3a0 100644
--- a/src/opts/SkBlitRow_opts_mips_dsp.cpp
+++ b/src/opts/SkBlitRow_opts_mips_dsp.cpp
@@ -34,7 +34,7 @@
             "and             %[t1],    %[s0],    %[s5]     \n\t"
             "shra.ph         %[t0],    %[s0],    5         \n\t"
             "and             %[t2],    %[t0],    %[s6]     \n\t"
-#ifdef __MIPS_HAVE_DSPR2
+#ifdef SK_MIPS_HAS_DSPR2
             "shrl.ph         %[t3],    %[s0],    11        \n\t"
 #else
             "shra.ph         %[t0],    %[s0],    11        \n\t"
@@ -46,7 +46,7 @@
             "ins             %[s2],    %[s1],    16, 16    \n\t"
             "preceu.ph.qbra  %[t0],    %[s2]               \n\t"
             "shrl.qb         %[t6],    %[t0],    3         \n\t"
-#ifdef __MIPS_HAVE_DSPR2
+#ifdef SK_MIPS_HAS_DSPR2
             "shrl.ph         %[t5],    %[s2],    10        \n\t"
 #else
             "shra.ph         %[t0],    %[s2],    10        \n\t"
@@ -303,7 +303,7 @@
         "lw              %[t2],    4(%[src])           \n\t"
         "precrq.ph.w     %[t3],    %[t0],    %[t2]     \n\t"
         "preceu.ph.qbra  %[t9],    %[t3]               \n\t"
-#ifdef __MIPS_HAVE_DSPR2
+#ifdef SK_MIPS_HAS_DSPR2
         "append          %[t0],    %[t2],    16        \n\t"
         "preceu.ph.qbra  %[t4],    %[t0]               \n\t"
         "preceu.ph.qbla  %[t5],    %[t0]               \n\t"
@@ -328,7 +328,7 @@
         "subu.qb         %[t4],    %[t3],    %[t2]     \n\t"
         "shra.ph         %[t8],    %[t4],    2         \n\t"
         "precrq.ph.w     %[t0],    %[t6],    %[t7]     \n\t"
-#ifdef __MIPS_HAVE_DSPR2
+#ifdef SK_MIPS_HAS_DSPR2
         "append          %[t6],    %[t7],    16        \n\t"
 #else
         "sll             %[t6],    %[t6],    16        \n\t"
@@ -425,7 +425,7 @@
     "5:                                                    \n\t"
         "sll             %[t3],     %[t0],     7           \n\t"
         "sll             %[t4],     %[t1],     7           \n\t"
-#ifdef __MIPS_HAVE_DSPR2
+#ifdef SK_MIPS_HAS_DSPR2
         "append          %[t0],     %[t1],     16          \n\t"
 #else
         "sll             %[t0],     %[t0],     8           \n\t"
@@ -442,7 +442,7 @@
         "preceu.ph.qbra  %[t6],     %[t6]                  \n\t"
         "lh              %[t2],     0(%[dst])              \n\t"
         "lh              %[s1],     2(%[dst])              \n\t"
-#ifdef __MIPS_HAVE_DSPR2
+#ifdef SK_MIPS_HAS_DSPR2
         "append          %[t2],     %[s1],     16          \n\t"
 #else
         "sll             %[s1],     %[s1],     16          \n\t"
@@ -575,7 +575,7 @@
         "lw             %[t1],    4(%[src])             \n\t"
         "precrq.ph.w    %[t2],    %[t0],    %[t1]       \n\t"
         "preceu.ph.qbra %[t8],    %[t2]                 \n\t"
-#ifdef __MIPS_HAVE_DSPR2
+#ifdef SK_MIPS_HAS_DSPR2
         "append         %[t0],    %[t1],    16          \n\t"
 #else
         "sll            %[t0],    %[t0],    16          \n\t"
@@ -592,7 +592,7 @@
         "lh             %[t0],    0(%[dst])             \n\t"
         "lh             %[t1],    2(%[dst])             \n\t"
         "and            %[t1],    %[t1],    0xffff      \n\t"
-#ifdef __MIPS_HAVE_DSPR2
+#ifdef SK_MIPS_HAS_DSPR2
         "append         %[t0],    %[t1],    16          \n\t"
 #else
         "sll            %[t5],    %[t0],    16          \n\t"
@@ -808,6 +808,117 @@
     );
 }
 
+void blitmask_d565_opaque_mips(int width, int height, uint16_t* device,
+                               unsigned deviceRB, const uint8_t* alpha,
+                               uint32_t expanded32, unsigned maskRB) {
+    register uint32_t s0, s1, s2, s3;
+
+    __asm__ volatile (
+        ".set            push                                    \n\t"
+        ".set            noreorder                               \n\t"
+        ".set            noat                                    \n\t"
+        "li              $t9,       0x7E0F81F                    \n\t"
+    "1:                                                          \n\t"
+        "move            $t8,       %[width]                     \n\t"
+        "addiu           %[height], %[height],     -1            \n\t"
+    "2:                                                          \n\t"
+        "beqz            $t8,       4f                           \n\t"
+        " addiu          $t0,       $t8,           -4            \n\t"
+        "bltz            $t0,       3f                           \n\t"
+        " nop                                                    \n\t"
+        "addiu           $t8,       $t8,           -4            \n\t"
+        "lhu             $t0,       0(%[device])                 \n\t"
+        "lhu             $t1,       2(%[device])                 \n\t"
+        "lhu             $t2,       4(%[device])                 \n\t"
+        "lhu             $t3,       6(%[device])                 \n\t"
+        "lbu             $t4,       0(%[alpha])                  \n\t"
+        "lbu             $t5,       1(%[alpha])                  \n\t"
+        "lbu             $t6,       2(%[alpha])                  \n\t"
+        "lbu             $t7,       3(%[alpha])                  \n\t"
+        "replv.ph        $t0,       $t0                          \n\t"
+        "replv.ph        $t1,       $t1                          \n\t"
+        "replv.ph        $t2,       $t2                          \n\t"
+        "replv.ph        $t3,       $t3                          \n\t"
+        "addiu           %[s0],     $t4,           1             \n\t"
+        "addiu           %[s1],     $t5,           1             \n\t"
+        "addiu           %[s2],     $t6,           1             \n\t"
+        "addiu           %[s3],     $t7,           1             \n\t"
+        "srl             %[s0],     %[s0],         3             \n\t"
+        "srl             %[s1],     %[s1],         3             \n\t"
+        "srl             %[s2],     %[s2],         3             \n\t"
+        "srl             %[s3],     %[s3],         3             \n\t"
+        "and             $t0,       $t0,           $t9           \n\t"
+        "and             $t1,       $t1,           $t9           \n\t"
+        "and             $t2,       $t2,           $t9           \n\t"
+        "and             $t3,       $t3,           $t9           \n\t"
+        "subu            $t4,       %[expanded32], $t0           \n\t"
+        "subu            $t5,       %[expanded32], $t1           \n\t"
+        "subu            $t6,       %[expanded32], $t2           \n\t"
+        "subu            $t7,       %[expanded32], $t3           \n\t"
+        "mul             $t4,       $t4,           %[s0]         \n\t"
+        "mul             $t5,       $t5,           %[s1]         \n\t"
+        "mul             $t6,       $t6,           %[s2]         \n\t"
+        "mul             $t7,       $t7,           %[s3]         \n\t"
+        "addiu           %[alpha],  %[alpha],      4             \n\t"
+        "srl             $t4,       $t4,           5             \n\t"
+        "srl             $t5,       $t5,           5             \n\t"
+        "srl             $t6,       $t6,           5             \n\t"
+        "srl             $t7,       $t7,           5             \n\t"
+        "addu            $t4,       $t0,           $t4           \n\t"
+        "addu            $t5,       $t1,           $t5           \n\t"
+        "addu            $t6,       $t2,           $t6           \n\t"
+        "addu            $t7,       $t3,           $t7           \n\t"
+        "and             $t4,       $t4,           $t9           \n\t"
+        "and             $t5,       $t5,           $t9           \n\t"
+        "and             $t6,       $t6,           $t9           \n\t"
+        "and             $t7,       $t7,           $t9           \n\t"
+        "srl             $t0,       $t4,           16            \n\t"
+        "srl             $t1,       $t5,           16            \n\t"
+        "srl             $t2,       $t6,           16            \n\t"
+        "srl             $t3,       $t7,           16            \n\t"
+        "or              %[s0],     $t0,           $t4           \n\t"
+        "or              %[s1],     $t1,           $t5           \n\t"
+        "or              %[s2],     $t2,           $t6           \n\t"
+        "or              %[s3],     $t3,           $t7           \n\t"
+        "sh              %[s0],     0(%[device])                 \n\t"
+        "sh              %[s1],     2(%[device])                 \n\t"
+        "sh              %[s2],     4(%[device])                 \n\t"
+        "sh              %[s3],     6(%[device])                 \n\t"
+        "b               2b                                      \n\t"
+        " addiu          %[device], %[device],     8             \n\t"
+    "3:                                                          \n\t"
+        "lhu             $t0,       0(%[device])                 \n\t"
+        "lbu             $t1,       0(%[alpha])                  \n\t"
+        "addiu           $t8,       $t8,           -1            \n\t"
+        "replv.ph        $t2,       $t0                          \n\t"
+        "and             $t2,       $t2,           $t9           \n\t"
+        "addiu           $t0,       $t1,           1             \n\t"
+        "srl             $t0,       $t0,           3             \n\t"
+        "subu            $t3,       %[expanded32], $t2           \n\t"
+        "mul             $t3,       $t3,           $t0           \n\t"
+        "addiu           %[alpha],  %[alpha],      1             \n\t"
+        "srl             $t3,       $t3,           5             \n\t"
+        "addu            $t3,       $t2,           $t3           \n\t"
+        "and             $t3,       $t3,           $t9           \n\t"
+        "srl             $t4,       $t3,           16            \n\t"
+        "or              %[s0],     $t4,           $t3           \n\t"
+        "sh              %[s0],     0(%[device])                 \n\t"
+        "bnez            $t8,       3b                           \n\t"
+         "addiu          %[device], %[device],     2             \n\t"
+    "4:                                                          \n\t"
+        "addu            %[device], %[device],     %[deviceRB]   \n\t"
+        "bgtz            %[height], 1b                           \n\t"
+        " addu           %[alpha],  %[alpha],      %[maskRB]     \n\t"
+        ".set            pop                                     \n\t"
+        : [height]"+r"(height), [alpha]"+r"(alpha), [device]"+r"(device),
+          [deviceRB]"+r"(deviceRB), [maskRB]"+r"(maskRB), [s0]"=&r"(s0),
+          [s1]"=&r"(s1), [s2]"=&r"(s2), [s3]"=&r"(s3)
+        : [expanded32] "r" (expanded32), [width] "r" (width)
+        : "memory", "hi", "lo", "t0", "t1", "t2", "t3",
+          "t4", "t5", "t6", "t7", "t8", "t9"
+    );
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 const SkBlitRow::Proc platform_565_procs_mips_dsp[] = {
diff --git a/src/opts/SkBlurImage_opts_SSE2.cpp b/src/opts/SkBlurImage_opts_SSE2.cpp
index bbc6a66..d2f8882 100644
--- a/src/opts/SkBlurImage_opts_SSE2.cpp
+++ b/src/opts/SkBlurImage_opts_SSE2.cpp
@@ -55,17 +55,13 @@
         const SkPMColor* sptr = src;
         SkColor* dptr = dst;
         for (int x = 0; x < width; ++x) {
-#if 0
-            // In SSE4.1, this would be
-            __m128i result = _mm_mullo_epi32(sum, scale);
-#else
-            // But SSE2 has no PMULLUD, so we must do AG and RB separately.
+            // SSE2 has no PMULLUD, so we must do AG and RB separately.
             __m128i tmp1 = _mm_mul_epu32(sum, scale);
             __m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(sum, 4),
                                          _mm_srli_si128(scale, 4));
             __m128i result = _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0,0,2,0)),
                                                 _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0,0,2,0)));
-#endif
+
             // sumA*scale+.5 sumB*scale+.5 sumG*scale+.5 sumB*scale+.5
             result = _mm_add_epi32(result, half);
 
diff --git a/src/opts/SkBlurImage_opts_SSE4.cpp b/src/opts/SkBlurImage_opts_SSE4.cpp
new file mode 100644
index 0000000..81748af
--- /dev/null
+++ b/src/opts/SkBlurImage_opts_SSE4.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkBitmap.h"
+#include "SkBlurImage_opts_SSE4.h"
+#include "SkColorPriv.h"
+#include "SkRect.h"
+
+/* With the exception of the compilers that don't support it, we always build the
+ * SSE4 functions and enable the caller to determine SSE4 support.  However for
+ * compilers that do not support SSE4x we provide a stub implementation.
+ */
+#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41
+
+#include <smmintrin.h>
+
+namespace {
+enum BlurDirection {
+    kX, kY
+};
+
+/* Helper function to spread the components of a 32-bit integer into the
+ * lower 8 bits of each 32-bit element of an SSE register.
+ */
+inline __m128i expand(int a) {
+    const __m128i zero = _mm_setzero_si128();
+
+    // 0 0 0 0   0 0 0 0   0 0 0 0   A R G B
+    __m128i result = _mm_cvtsi32_si128(a);
+
+    // 0 0 0 0   0 0 0 0   0 A 0 R   0 G 0 B
+    result = _mm_unpacklo_epi8(result, zero);
+
+    // 0 0 0 A   0 0 0 R   0 0 0 G   0 0 0 B
+    return _mm_unpacklo_epi16(result, zero);
+}
+
+template<BlurDirection srcDirection, BlurDirection dstDirection>
+void SkBoxBlur_SSE4(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSize,
+                    int leftOffset, int rightOffset, int width, int height)
+{
+    const int rightBorder = SkMin32(rightOffset + 1, width);
+    const int srcStrideX = srcDirection == kX ? 1 : srcStride;
+    const int dstStrideX = dstDirection == kX ? 1 : height;
+    const int srcStrideY = srcDirection == kX ? srcStride : 1;
+    const int dstStrideY = dstDirection == kX ? width : 1;
+    const __m128i scale = _mm_set1_epi32((1 << 24) / kernelSize);
+    const __m128i half = _mm_set1_epi32(1 << 23);
+    const __m128i zero = _mm_setzero_si128();
+    for (int y = 0; y < height; ++y) {
+        __m128i sum = zero;
+        const SkPMColor* p = src;
+        for (int i = 0; i < rightBorder; ++i) {
+            sum = _mm_add_epi32(sum, expand(*p));
+            p += srcStrideX;
+        }
+
+        const SkPMColor* sptr = src;
+        SkColor* dptr = dst;
+        for (int x = 0; x < width; ++x) {
+            __m128i result = _mm_mullo_epi32(sum, scale);
+
+            // sumA*scale+.5 sumB*scale+.5 sumG*scale+.5 sumB*scale+.5
+            result = _mm_add_epi32(result, half);
+
+            // 0 0 0 A   0 0 0 R   0 0 0 G   0 0 0 B
+            result = _mm_srli_epi32(result, 24);
+
+            // 0 0 0 0   0 0 0 0   0 A 0 R   0 G 0 B
+            result = _mm_packs_epi32(result, zero);
+
+            // 0 0 0 0   0 0 0 0   0 0 0 0   A R G B
+            result = _mm_packus_epi16(result, zero);
+            *dptr = _mm_cvtsi128_si32(result);
+            if (x >= leftOffset) {
+                SkColor l = *(sptr - leftOffset * srcStrideX);
+                sum = _mm_sub_epi32(sum, expand(l));
+            }
+            if (x + rightOffset + 1 < width) {
+                SkColor r = *(sptr + (rightOffset + 1) * srcStrideX);
+                sum = _mm_add_epi32(sum, expand(r));
+            }
+            sptr += srcStrideX;
+            if (srcDirection == kY) {
+                _mm_prefetch(reinterpret_cast<const char*>(sptr + (rightOffset + 1) * srcStrideX),
+                             _MM_HINT_T0);
+            }
+            dptr += dstStrideX;
+        }
+        src += srcStrideY;
+        dst += dstStrideY;
+    }
+}
+
+} // namespace
+
+bool SkBoxBlurGetPlatformProcs_SSE4(SkBoxBlurProc* boxBlurX,
+                                    SkBoxBlurProc* boxBlurY,
+                                    SkBoxBlurProc* boxBlurXY,
+                                    SkBoxBlurProc* boxBlurYX) {
+    *boxBlurX = SkBoxBlur_SSE4<kX, kX>;
+    *boxBlurY = SkBoxBlur_SSE4<kY, kY>;
+    *boxBlurXY = SkBoxBlur_SSE4<kX, kY>;
+    *boxBlurYX = SkBoxBlur_SSE4<kY, kX>;
+    return true;
+}
+
+#else // SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41
+
+bool SkBoxBlurGetPlatformProcs_SSE4(SkBoxBlurProc* boxBlurX,
+                                    SkBoxBlurProc* boxBlurY,
+                                    SkBoxBlurProc* boxBlurXY,
+                                    SkBoxBlurProc* boxBlurYX) {
+    sk_throw();
+    return false;
+}
+
+
+#endif
diff --git a/src/opts/SkBlurImage_opts_SSE4.h b/src/opts/SkBlurImage_opts_SSE4.h
new file mode 100644
index 0000000..9f346a9
--- /dev/null
+++ b/src/opts/SkBlurImage_opts_SSE4.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBlurImage_opts_SSE4_DEFINED
+#define SkBlurImage_opts_SSE4_DEFINED
+
+#include "SkBlurImage_opts.h"
+
+bool SkBoxBlurGetPlatformProcs_SSE4(SkBoxBlurProc* boxBlurX,
+                                    SkBoxBlurProc* boxBlurY,
+                                    SkBoxBlurProc* boxBlurXY,
+                                    SkBoxBlurProc* boxBlurYX);
+
+#endif
diff --git a/src/opts/SkBlurImage_opts_arm.cpp b/src/opts/SkBlurImage_opts_arm.cpp
index 10d595a..fb61034 100644
--- a/src/opts/SkBlurImage_opts_arm.cpp
+++ b/src/opts/SkBlurImage_opts_arm.cpp
@@ -12,6 +12,9 @@
                                SkBoxBlurProc* boxBlurY,
                                SkBoxBlurProc* boxBlurXY,
                                SkBoxBlurProc* boxBlurYX) {
+    // Temporary workaround for http://skbug.com/2845
+    return false;
+
 #if SK_ARM_NEON_IS_NONE
     return false;
 #else
diff --git a/src/opts/SkTextureCompression_opts.h b/src/opts/SkTextureCompression_opts.h
new file mode 100644
index 0000000..07d645f
--- /dev/null
+++ b/src/opts/SkTextureCompression_opts.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2014
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTextureCompression_opts_DEFINED
+#define SkTextureCompression_opts_DEFINED
+
+#include "SkTextureCompressor.h"
+#include "SkImageInfo.h"
+
+SkTextureCompressor::CompressionProc
+SkTextureCompressorGetPlatformProc(SkColorType colorType, SkTextureCompressor::Format fmt);
+
+// Returns true if dimX and dimY are set to the block size of the supplied
+// compression format according to how the platform can consume them. Returns false otherwise.
+bool SkTextureCompressorGetPlatformDims(SkTextureCompressor::Format fmt, int* dimX, int* dimY);
+
+#endif  // SkTextureCompression_opts_DEFINED
diff --git a/src/opts/SkTextureCompression_opts_arm.cpp b/src/opts/SkTextureCompression_opts_arm.cpp
new file mode 100644
index 0000000..36ff15c
--- /dev/null
+++ b/src/opts/SkTextureCompression_opts_arm.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 "SkTextureCompression_opts.h"
+#include "SkTextureCompression_opts_neon.h"
+#include "SkUtilsArm.h"
+
+SkTextureCompressor::CompressionProc
+SkTextureCompressorGetPlatformProc(SkColorType colorType, SkTextureCompressor::Format fmt) {
+#if SK_ARM_NEON_IS_NONE
+    return NULL;
+#else
+#if SK_ARM_NEON_IS_DYNAMIC
+    if (!sk_cpu_arm_has_neon()) {
+        return NULL;
+    }
+#endif
+    switch (colorType) {
+        case kAlpha_8_SkColorType:
+        {
+            switch (fmt) {
+                case SkTextureCompressor::kR11_EAC_Format:
+                    return CompressA8toR11EAC_NEON;
+                default:
+                    return NULL;
+            }
+        }
+        break;
+
+        default:
+            return NULL;
+    }
+#endif
+}
+
+bool SkTextureCompressorGetPlatformDims(SkTextureCompressor::Format fmt, int* dimX, int* dimY) {
+#if SK_ARM_NEON_IS_NONE
+    return false;
+#else
+#if SK_ARM_NEON_IS_DYNAMIC
+    if (!sk_cpu_arm_has_neon()) {
+        return false;
+    }
+#endif
+    switch (fmt) {
+        case SkTextureCompressor::kR11_EAC_Format:
+            *dimX = 16;
+            *dimY = 4;
+            return true;
+        default:
+            return false;
+    }
+    return false;
+#endif
+}
diff --git a/src/opts/SkTextureCompression_opts_neon.cpp b/src/opts/SkTextureCompression_opts_neon.cpp
new file mode 100644
index 0000000..bd7469b
--- /dev/null
+++ b/src/opts/SkTextureCompression_opts_neon.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2014
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkTextureCompressor.h"
+#include "SkTextureCompression_opts.h"
+
+#include <arm_neon.h>
+
+// Converts indices in each of the four bits of the register from
+// 0, 1, 2, 3, 4, 5, 6, 7
+// to
+// 3, 2, 1, 0, 4, 5, 6, 7
+//
+// A more detailed explanation can be found in SkTextureCompressor::convert_indices
+static inline uint8x16_t convert_indices(const uint8x16_t &x) {
+    static const int8x16_t kThree = {
+        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+    };
+
+    static const int8x16_t kZero = {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    };
+    
+    // Take top three bits
+    int8x16_t sx = vreinterpretq_s8_u8(x);
+
+    // Negate ...
+    sx = vnegq_s8(sx);
+
+    // Add three...
+    sx = vaddq_s8(sx, kThree);
+
+    // Generate negatives mask
+    const int8x16_t mask = vreinterpretq_s8_u8(vcltq_s8(sx, kZero));
+
+    // Absolute value
+    sx = vabsq_s8(sx);
+
+    // Add three to the values that were negative...
+    return vreinterpretq_u8_s8(vaddq_s8(sx, vandq_s8(mask, kThree)));
+}
+
+template<unsigned shift>
+static inline uint64x2_t shift_swap(const uint64x2_t &x, const uint64x2_t &mask) {
+    uint64x2_t t = vandq_u64(mask, veorq_u64(x, vshrq_n_u64(x, shift)));
+    return veorq_u64(x, veorq_u64(t, vshlq_n_u64(t, shift)));
+}
+
+static inline uint64x2_t pack_indices(const uint64x2_t &x) {
+    // x: 00 a e 00 b f 00 c g 00 d h 00 i m 00 j n 00 k o 00 l p
+
+    static const uint64x2_t kMask1 = { 0x3FC0003FC00000ULL, 0x3FC0003FC00000ULL };
+    uint64x2_t ret = shift_swap<10>(x, kMask1);
+
+    // x: b f 00 00 00 a e c g i m 00 00 00 d h j n 00 k o 00 l p
+    static const uint64x2_t kMask2 = { (0x3FULL << 52), (0x3FULL << 52) };
+    static const uint64x2_t kMask3 = { (0x3FULL << 28), (0x3FULL << 28) };
+    const uint64x2_t x1 = vandq_u64(vshlq_n_u64(ret, 52), kMask2);
+    const uint64x2_t x2 = vandq_u64(vshlq_n_u64(ret, 20), kMask3);
+    ret = vshrq_n_u64(vorrq_u64(ret, vorrq_u64(x1, x2)), 16);
+
+    // x: 00 00 00 00 00 00 00 00 b f l p a e c g i m k o d h j n
+
+    static const uint64x2_t kMask4 = { 0xFC0000ULL, 0xFC0000ULL };
+    ret = shift_swap<6>(ret, kMask4);
+
+#if defined (SK_CPU_BENDIAN)
+    // x: 00 00 00 00 00 00 00 00 b f l p a e i m c g k o d h j n
+
+    static const uint64x2_t kMask5 = { 0x3FULL, 0x3FULL };
+    ret = shift_swap<36>(ret, kMask5);
+
+    // x: 00 00 00 00 00 00 00 00 b f j n a e i m c g k o d h l p
+
+    static const uint64x2_t kMask6 = { 0xFFF000000ULL, 0xFFF000000ULL };
+    ret = shift_swap<12>(ret, kMask6);
+#else
+    // x: 00 00 00 00 00 00 00 00 c g i m d h l p b f j n a e k o
+
+    static const uint64x2_t kMask5 = { 0xFC0ULL, 0xFC0ULL };
+    ret = shift_swap<36>(ret, kMask5);
+
+    // x: 00 00 00 00 00 00 00 00 a e i m d h l p b f j n c g k o
+
+    static const uint64x2_t kMask6 = { (0xFFFULL << 36), (0xFFFULL << 36) };
+    static const uint64x2_t kMask7 = { 0xFFFFFFULL, 0xFFFFFFULL };
+    static const uint64x2_t kMask8 = { 0xFFFULL, 0xFFFULL };
+    const uint64x2_t y1 = vandq_u64(ret, kMask6);
+    const uint64x2_t y2 = vshlq_n_u64(vandq_u64(ret, kMask7), 12);
+    const uint64x2_t y3 = vandq_u64(vshrq_n_u64(ret, 24), kMask8);
+    ret = vorrq_u64(y1, vorrq_u64(y2, y3));
+#endif
+
+    // x: 00 00 00 00 00 00 00 00 a e i m b f j n c g k o d h l p
+
+    // Set the header
+    static const uint64x2_t kHeader = { 0x8490000000000000ULL, 0x8490000000000000ULL };
+    return vorrq_u64(kHeader, ret);
+}
+
+// Takes a row of alpha values and places the most significant three bits of each byte into
+// the least significant bits of the same byte
+static inline uint8x16_t make_index_row(const uint8x16_t &x) {
+    static const uint8x16_t kTopThreeMask = {
+        0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
+        0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
+    };
+    return vshrq_n_u8(vandq_u8(x, kTopThreeMask), 5);
+}
+
+// Returns true if all of the bits in x are 0.
+static inline bool is_zero(uint8x16_t x) {
+// First experiments say that this is way slower than just examining the lanes
+// but it might need a little more investigation.
+#if 0
+    // This code path tests the system register for overflow. We trigger
+    // overflow by adding x to a register with all of its bits set. The
+    // first instruction sets the bits.
+    int reg;
+    asm ("VTST.8   %%q0, %q1, %q1\n"
+         "VQADD.u8 %q1, %%q0\n"
+         "VMRS     %0, FPSCR\n"
+         : "=r"(reg) : "w"(vreinterpretq_f32_u8(x)) : "q0", "q1");
+
+    // Bit 21 corresponds to the overflow flag.
+    return reg & (0x1 << 21);
+#else
+    const uint64x2_t cvt = vreinterpretq_u64_u8(x);
+    const uint64_t l1 = vgetq_lane_u64(cvt, 0);
+    return (l1 == 0) && (l1 == vgetq_lane_u64(cvt, 1));
+#endif
+}
+
+#if defined (SK_CPU_BENDIAN)
+static inline uint64x2_t fix_endianness(uint64x2_t x) {
+    return x;
+}
+#else
+static inline uint64x2_t fix_endianness(uint64x2_t x) {
+    return vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(x)));
+}
+#endif
+
+static void compress_r11eac_blocks(uint64_t* dst, const uint8_t* src, int rowBytes) {
+
+    // Try to avoid switching between vector and non-vector ops...
+    const uint8_t *const src1 = src;
+    const uint8_t *const src2 = src + rowBytes;
+    const uint8_t *const src3 = src + 2*rowBytes;
+    const uint8_t *const src4 = src + 3*rowBytes;
+    uint64_t *const dst1 = dst;
+    uint64_t *const dst2 = dst + 2;
+
+    const uint8x16_t alphaRow1 = vld1q_u8(src1);
+    const uint8x16_t alphaRow2 = vld1q_u8(src2);
+    const uint8x16_t alphaRow3 = vld1q_u8(src3);
+    const uint8x16_t alphaRow4 = vld1q_u8(src4);
+
+    const uint8x16_t cmp12 = vceqq_u8(alphaRow1, alphaRow2);
+    const uint8x16_t cmp34 = vceqq_u8(alphaRow3, alphaRow4);
+    const uint8x16_t cmp13 = vceqq_u8(alphaRow1, alphaRow3);
+
+    const uint8x16_t cmp = vandq_u8(vandq_u8(cmp12, cmp34), cmp13);
+    const uint8x16_t ncmp = vmvnq_u8(cmp);
+    const uint8x16_t nAlphaRow1 = vmvnq_u8(alphaRow1);
+    if (is_zero(ncmp)) {
+        if (is_zero(alphaRow1)) {
+            static const uint64x2_t kTransparent = { 0x0020000000002000ULL,
+                                                     0x0020000000002000ULL };
+            vst1q_u64(dst1, kTransparent);
+            vst1q_u64(dst2, kTransparent);
+            return;
+        } else if (is_zero(nAlphaRow1)) {
+            vst1q_u64(dst1, vreinterpretq_u64_u8(cmp));
+            vst1q_u64(dst2, vreinterpretq_u64_u8(cmp));
+            return;
+        }
+    }
+
+    const uint8x16_t indexRow1 = convert_indices(make_index_row(alphaRow1));
+    const uint8x16_t indexRow2 = convert_indices(make_index_row(alphaRow2));
+    const uint8x16_t indexRow3 = convert_indices(make_index_row(alphaRow3));
+    const uint8x16_t indexRow4 = convert_indices(make_index_row(alphaRow4));
+
+    const uint64x2_t indexRow12 = vreinterpretq_u64_u8(
+        vorrq_u8(vshlq_n_u8(indexRow1, 3), indexRow2));
+    const uint64x2_t indexRow34 = vreinterpretq_u64_u8(
+        vorrq_u8(vshlq_n_u8(indexRow3, 3), indexRow4));
+
+    const uint32x4x2_t blockIndices = vtrnq_u32(vreinterpretq_u32_u64(indexRow12),
+                                                vreinterpretq_u32_u64(indexRow34));
+    const uint64x2_t blockIndicesLeft = vreinterpretq_u64_u32(vrev64q_u32(blockIndices.val[0]));
+    const uint64x2_t blockIndicesRight = vreinterpretq_u64_u32(vrev64q_u32(blockIndices.val[1]));
+
+    const uint64x2_t indicesLeft = fix_endianness(pack_indices(blockIndicesLeft));
+    const uint64x2_t indicesRight = fix_endianness(pack_indices(blockIndicesRight));
+
+    const uint64x2_t d1 = vcombine_u64(vget_low_u64(indicesLeft), vget_low_u64(indicesRight));
+    const uint64x2_t d2 = vcombine_u64(vget_high_u64(indicesLeft), vget_high_u64(indicesRight));
+    vst1q_u64(dst1, d1);
+    vst1q_u64(dst2, d2);
+}
+
+bool CompressA8toR11EAC_NEON(uint8_t* dst, const uint8_t* src,
+                             int width, int height, int rowBytes) {
+
+    // Since we're going to operate on 4 blocks at a time, the src width
+    // must be a multiple of 16. However, the height only needs to be a
+    // multiple of 4
+    if (0 == width || 0 == height || (width % 16) != 0 || (height % 4) != 0) {
+        return SkTextureCompressor::CompressBufferToFormat(
+            dst, src,
+            kAlpha_8_SkColorType,
+            width, height, rowBytes,
+            SkTextureCompressor::kR11_EAC_Format, false);
+    }
+
+    const int blocksX = width >> 2;
+    const int blocksY = height >> 2;
+
+    SkASSERT((blocksX % 4) == 0);
+
+    uint64_t* encPtr = reinterpret_cast<uint64_t*>(dst);
+    for (int y = 0; y < blocksY; ++y) {
+        for (int x = 0; x < blocksX; x+=4) {
+            // Compress it
+            compress_r11eac_blocks(encPtr, src + 4*x, rowBytes);
+            encPtr += 4;
+        }
+        src += 4 * rowBytes;
+    }
+    return true;
+}
diff --git a/src/opts/SkTextureCompression_opts_neon.h b/src/opts/SkTextureCompression_opts_neon.h
new file mode 100644
index 0000000..dd5e75d
--- /dev/null
+++ b/src/opts/SkTextureCompression_opts_neon.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTextureCompression_opts_neon_h_
+#define SkTextureCompression_opts_neon_h_
+
+bool CompressA8toR11EAC_NEON(uint8_t* dst, const uint8_t* src,
+                             int width, int height, int rowBytes);
+
+#endif  // SkTextureCompression_opts_neon_h_
diff --git a/src/opts/SkTextureCompression_opts_none.cpp b/src/opts/SkTextureCompression_opts_none.cpp
new file mode 100644
index 0000000..caa2118
--- /dev/null
+++ b/src/opts/SkTextureCompression_opts_none.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2014
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkTextureCompression_opts.h"
+
+SkTextureCompressor::CompressionProc
+SkTextureCompressorGetPlatformProc(SkColorType colorType, SkTextureCompressor::Format fmt) {
+    return NULL;
+}
+
+bool SkTextureCompressorGetPlatformDims(SkTextureCompressor::Format fmt, int* dimX, int* dimY) {
+    return false;
+}
diff --git a/src/opts/SkXfermode_opts_SSE2.cpp b/src/opts/SkXfermode_opts_SSE2.cpp
index 94f9a4a..02ca038 100644
--- a/src/opts/SkXfermode_opts_SSE2.cpp
+++ b/src/opts/SkXfermode_opts_SSE2.cpp
@@ -641,11 +641,12 @@
 
 extern SkXfermodeProcSIMD gSSE2XfermodeProcs[];
 
-SkSSE2ProcCoeffXfermode::SkSSE2ProcCoeffXfermode(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkSSE2ProcCoeffXfermode::SkSSE2ProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     fProcSIMD = reinterpret_cast<void*>(gSSE2XfermodeProcs[this->getMode()]);
     buffer.validate(fProcSIMD != NULL);
 }
+#endif
 
 void SkSSE2ProcCoeffXfermode::xfer32(SkPMColor dst[], const SkPMColor src[],
                                      int count, const SkAlpha aa[]) const {
diff --git a/src/opts/SkXfermode_opts_SSE2.h b/src/opts/SkXfermode_opts_SSE2.h
index bfc1439..8512aee 100644
--- a/src/opts/SkXfermode_opts_SSE2.h
+++ b/src/opts/SkXfermode_opts_SSE2.h
@@ -23,10 +23,11 @@
                         int count, const SkAlpha aa[]) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSSE2ProcCoeffXfermode)
 
 private:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkSSE2ProcCoeffXfermode(SkReadBuffer& buffer);
+#endif
 
     void* fProcSIMD;
     typedef SkProcCoeffXfermode INHERITED;
diff --git a/src/opts/SkXfermode_opts_arm_neon.cpp b/src/opts/SkXfermode_opts_arm_neon.cpp
index 70e92af..f6fbcd3 100644
--- a/src/opts/SkXfermode_opts_arm_neon.cpp
+++ b/src/opts/SkXfermode_opts_arm_neon.cpp
@@ -743,13 +743,15 @@
 
 extern SkXfermodeProcSIMD gNEONXfermodeProcs[];
 
-SkNEONProcCoeffXfermode::SkNEONProcCoeffXfermode(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkNEONProcCoeffXfermode::SkNEONProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     fProcSIMD = reinterpret_cast<void*>(gNEONXfermodeProcs[this->getMode()]);
 }
+#endif
 
-void SkNEONProcCoeffXfermode::xfer32(SkPMColor dst[], const SkPMColor src[],
-                                     int count, const SkAlpha aa[]) const {
+void SkNEONProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
+                                     const SkPMColor* SK_RESTRICT src, int count,
+                                     const SkAlpha* SK_RESTRICT aa) const {
     SkASSERT(dst && src && count >= 0);
 
     SkXfermodeProc proc = this->getProc();
@@ -758,13 +760,16 @@
 
     if (NULL == aa) {
         // Unrolled NEON code
+        // We'd like to just do this (modulo a few casts):
+        // vst4_u8(dst, procSIMD(vld4_u8(src), vld4_u8(dst)));
+        // src += 8;
+        // dst += 8;
+        // but that tends to generate miserable code. Here are a bunch of faster
+        // workarounds for different architectures and compilers.
         while (count >= 8) {
-            uint8x8x4_t vsrc, vdst, vres;
 
-#ifdef SK_CPU_ARM64
-            vsrc = vld4_u8((uint8_t*)src);
-            vdst = vld4_u8((uint8_t*)dst);
-#else
+#ifdef SK_CPU_ARM32
+            uint8x8x4_t vsrc, vdst, vres;
 #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6))
             asm volatile (
                 "vld4.u8    %h[vsrc], [%[src]]!  \t\n"
@@ -797,17 +802,37 @@
             vsrc.val[2] = d2; vdst.val[2] = d6;
             vsrc.val[3] = d3; vdst.val[3] = d7;
 #endif
-#endif // #ifdef SK_CPU_ARM64
 
             vres = procSIMD(vsrc, vdst);
 
             vst4_u8((uint8_t*)dst, vres);
 
-            count -= 8;
             dst += 8;
-#ifdef SK_CPU_ARM64
-            src += 8;
-#endif
+
+#else // #ifdef SK_CPU_ARM32
+
+            asm volatile (
+                "ld4    {v0.8b - v3.8b}, [%[src]], #32 \t\n"
+                "ld4    {v4.8b - v7.8b}, [%[dst]]      \t\n"
+                "blr    %[proc]                        \t\n"
+                "st4    {v0.8b - v3.8b}, [%[dst]], #32 \t\n"
+                : [src] "+&r" (src), [dst] "+&r" (dst)
+                : [proc] "r" (procSIMD)
+                : "cc", "memory",
+                  /* We don't know what proc is going to clobber so we must
+                   * add everything that is not callee-saved.
+                   */
+                  "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9",
+                  "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18",
+                  "x30", /* x30 implicitly clobbered by blr */
+                  "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17",
+                  "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26",
+                  "v27", "v28", "v29", "v30", "v31"
+            );
+
+#endif // #ifdef SK_CPU_ARM32
+
+            count -= 8;
         }
         // Leftovers
         for (int i = 0; i < count; i++) {
diff --git a/src/opts/SkXfermode_opts_arm_neon.h b/src/opts/SkXfermode_opts_arm_neon.h
index 8f3aaae..745bfe2 100644
--- a/src/opts/SkXfermode_opts_arm_neon.h
+++ b/src/opts/SkXfermode_opts_arm_neon.h
@@ -15,10 +15,11 @@
                         int count, const SkAlpha* SK_RESTRICT aa) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNEONProcCoeffXfermode)
 
 private:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkNEONProcCoeffXfermode(SkReadBuffer& buffer);
+#endif
 
     // void* is used to avoid pulling arm_neon.h in the core and having to build
     // it with -mfpu=neon.
diff --git a/src/opts/memset16_neon.S b/src/opts/memset16_neon.S
index b1719fa..7b2b190 100644
--- a/src/opts/memset16_neon.S
+++ b/src/opts/memset16_neon.S
@@ -15,11 +15,12 @@
 
 ***************************************************************************/
 
+        .syntax unified
+
         .code 32
         .fpu neon
         .align 4
         .globl memset16_neon
-        .func
 
 memset16_neon:
         cmp             r2, #0
@@ -70,7 +71,7 @@
         strcs           r1, [r0], #4
         strcs           r1, [r0], #4
         lsls            r12, r12, #2
-        strcsh          r1, [r0], #2
+        strhcs          r1, [r0], #2
 memset_route:
         /*
          * Decide where to route for the maximum copy sizes.  Note that we
@@ -139,5 +140,4 @@
         pop             {r0}
         bx              lr
 
-        .endfunc
         .end
diff --git a/src/opts/memset32_neon.S b/src/opts/memset32_neon.S
index a9eaa0e..fa03476 100644
--- a/src/opts/memset32_neon.S
+++ b/src/opts/memset32_neon.S
@@ -9,7 +9,6 @@
 	.fpu neon
 	.align 4
 	.globl	memset32_neon
-	.func
 
 	/* r0 = buffer, r1 = value, r2 = times to write */
 memset32_neon:
@@ -109,5 +108,4 @@
 	str		r1, [r0, #0]
 	bx		lr
 
-	.endfunc
 	.end
diff --git a/src/opts/opts_check_x86.cpp b/src/opts/opts_check_x86.cpp
index 6af4772..55eb843 100644
--- a/src/opts/opts_check_x86.cpp
+++ b/src/opts/opts_check_x86.cpp
@@ -8,11 +8,14 @@
 #include "SkBitmapFilter_opts_SSE2.h"
 #include "SkBitmapProcState_opts_SSE2.h"
 #include "SkBitmapProcState_opts_SSSE3.h"
+#include "SkBitmapScaler.h"
 #include "SkBlitMask.h"
 #include "SkBlitRect_opts_SSE2.h"
 #include "SkBlitRow.h"
 #include "SkBlitRow_opts_SSE2.h"
+#include "SkBlitRow_opts_SSE4.h"
 #include "SkBlurImage_opts_SSE2.h"
+#include "SkBlurImage_opts_SSE4.h"
 #include "SkMorphology_opts.h"
 #include "SkMorphology_opts_SSE2.h"
 #include "SkRTConf.h"
@@ -82,6 +85,8 @@
     getcpuid(1, cpu_info);
     if ((cpu_info[2] & (1<<20)) != 0) {
         return SK_CPU_SSE_LEVEL_SSE42;
+    } else if ((cpu_info[2] & (1<<19)) != 0) {
+        return SK_CPU_SSE_LEVEL_SSE41;
     } else if ((cpu_info[2] & (1<<9)) != 0) {
         return SK_CPU_SSE_LEVEL_SSSE3;
     } else if ((cpu_info[3] & (1<<26)) != 0) {
@@ -118,9 +123,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-SK_CONF_DECLARE( bool, c_hqfilter_sse, "bitmap.filter.highQualitySSE", false, "Use SSE optimized version of high quality image filters");
+SK_CONF_DECLARE( bool, c_hqfilter_sse, "bitmap.filter.highQualitySSE", true, "Use SSE optimized version of high quality image filters");
 
-void SkBitmapProcState::platformConvolutionProcs(SkConvolutionProcs* procs) {
+void SkBitmapScaler::PlatformConvolutionProcs(SkConvolutionProcs* procs) {
     if (supports_simd(SK_CPU_SSE_LEVEL_SSE2)) {
         procs->fExtraHorizontalReads = 3;
         procs->fConvolveVertically = &convolveVertically_SSE2;
@@ -206,16 +211,30 @@
     }
 }
 
-static SkBlitRow::Proc32 platform_32_procs[] = {
+static SkBlitRow::Proc32 platform_32_procs_SSE2[] = {
     NULL,                               // S32_Opaque,
     S32_Blend_BlitRow32_SSE2,           // S32_Blend,
     S32A_Opaque_BlitRow32_SSE2,         // S32A_Opaque
     S32A_Blend_BlitRow32_SSE2,          // S32A_Blend,
 };
 
+#if defined(SK_ATT_ASM_SUPPORTED)
+static SkBlitRow::Proc32 platform_32_procs_SSE4[] = {
+    NULL,                               // S32_Opaque,
+    S32_Blend_BlitRow32_SSE2,           // S32_Blend,
+    S32A_Opaque_BlitRow32_SSE4_asm,     // S32A_Opaque
+    S32A_Blend_BlitRow32_SSE2,          // S32A_Blend,
+};
+#endif
+
 SkBlitRow::Proc32 SkBlitRow::PlatformProcs32(unsigned flags) {
+#if defined(SK_ATT_ASM_SUPPORTED)
+    if (supports_simd(SK_CPU_SSE_LEVEL_SSE41)) {
+        return platform_32_procs_SSE4[flags];
+    } else
+#endif
     if (supports_simd(SK_CPU_SSE_LEVEL_SSE2)) {
-        return platform_32_procs[flags];
+        return platform_32_procs_SSE2[flags];
     } else {
         return NULL;
     }
@@ -340,10 +359,13 @@
 #ifdef SK_DISABLE_BLUR_DIVISION_OPTIMIZATION
     return false;
 #else
-    if (!supports_simd(SK_CPU_SSE_LEVEL_SSE2)) {
-        return false;
+    if (supports_simd(SK_CPU_SSE_LEVEL_SSE41)) {
+        return SkBoxBlurGetPlatformProcs_SSE4(boxBlurX, boxBlurY, boxBlurXY, boxBlurYX);
     }
-    return SkBoxBlurGetPlatformProcs_SSE2(boxBlurX, boxBlurY, boxBlurXY, boxBlurYX);
+    else if (supports_simd(SK_CPU_SSE_LEVEL_SSE2)) {
+        return SkBoxBlurGetPlatformProcs_SSE2(boxBlurX, boxBlurY, boxBlurXY, boxBlurYX);
+    }
+    return false;
 #endif
 }
 
diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp
index 52e751b..27422ed 100644
--- a/src/pathops/SkAddIntersections.cpp
+++ b/src/pathops/SkAddIntersections.cpp
@@ -434,7 +434,7 @@
 
 // resolve any coincident pairs found while intersecting, and
 // see if coincidence is formed by clipping non-concident segments
-void CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) {
+bool CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) {
     int contourCount = (*contourList).count();
     for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
         SkOpContour* contour = (*contourList)[cIndex];
@@ -446,10 +446,13 @@
     }
     for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
         SkOpContour* contour = (*contourList)[cIndex];
-        contour->calcCoincidentWinding();
+        if (!contour->calcCoincidentWinding()) {
+            return false;
+        }
     }
     for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
         SkOpContour* contour = (*contourList)[cIndex];
         contour->calcPartialCoincidentWinding();
     }
+    return true;
 }
diff --git a/src/pathops/SkAddIntersections.h b/src/pathops/SkAddIntersections.h
index 94ea436..4c1947b 100644
--- a/src/pathops/SkAddIntersections.h
+++ b/src/pathops/SkAddIntersections.h
@@ -13,6 +13,6 @@
 
 bool AddIntersectTs(SkOpContour* test, SkOpContour* next);
 void AddSelfIntersectTs(SkOpContour* test);
-void CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total);
+bool CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total);
 
 #endif
diff --git a/src/pathops/SkDLineIntersection.cpp b/src/pathops/SkDLineIntersection.cpp
index 9ae0107..b209474 100644
--- a/src/pathops/SkDLineIntersection.cpp
+++ b/src/pathops/SkDLineIntersection.cpp
@@ -173,21 +173,24 @@
             nearCount += t >= 0;
         }
         if (nearCount > 0) {
-            for (int iA = 0; iA < 2; ++iA) {
-                if (!aNotB[iA]) {
-                    continue;
+            // Skip if each segment contributes to one end point.
+            if (nearCount != 2 || aNotB[0] == aNotB[1]) {
+                for (int iA = 0; iA < 2; ++iA) {
+                    if (!aNotB[iA]) {
+                        continue;
+                    }
+                    int nearer = aNearB[iA] > 0.5;
+                    if (!bNotA[nearer]) {
+                        continue;
+                    }
+                    SkASSERT(a[iA] != b[nearer]);
+                    SkASSERT(iA == (bNearA[nearer] > 0.5));
+                    fNearlySame[iA] = true;
+                    insertNear(iA, nearer, a[iA], b[nearer]);
+                    aNearB[iA] = -1;
+                    bNearA[nearer] = -1;
+                    nearCount -= 2;
                 }
-                int nearer = aNearB[iA] > 0.5;
-                if (!bNotA[nearer]) {
-                    continue;
-                }
-                SkASSERT(a[iA] != b[nearer]);
-                SkASSERT(iA == (bNearA[nearer] > 0.5));
-                fNearlySame[iA] = true;
-                insertNear(iA, nearer, a[iA], b[nearer]);
-                aNearB[iA] = -1;
-                bNearA[nearer] = -1;
-                nearCount -= 2;
             }
             if (nearCount > 0) {
                 for (int iA = 0; iA < 2; ++iA) {
diff --git a/src/pathops/SkDQuadIntersection.cpp b/src/pathops/SkDQuadIntersection.cpp
index 5a8bafc..239711c 100644
--- a/src/pathops/SkDQuadIntersection.cpp
+++ b/src/pathops/SkDQuadIntersection.cpp
@@ -486,8 +486,8 @@
         if (r1Count == 1 && used() == 0) {
             if (pts1[0].approximatelyEqual(pts2[0])) {
                 insert(roots1Copy[0], roots2Copy[0], pts1[0]);
-            } else if (pts1[0].moreRoughlyEqual(pts2[0])) {
-                // experiment: try to find intersection by chasing t
+            } else {
+                // find intersection by chasing t
                 if (binary_search(q1, q2, roots1Copy, roots2Copy, pts1)) {
                     insert(roots1Copy[0], roots2Copy[0], pts1[0]);
                 }
diff --git a/src/pathops/SkIntersections.cpp b/src/pathops/SkIntersections.cpp
index 56eba27..62c1e41 100644
--- a/src/pathops/SkIntersections.cpp
+++ b/src/pathops/SkIntersections.cpp
@@ -13,14 +13,14 @@
     }
 }
 
-int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar, SkScalar, SkScalar, bool) = {
+int (SkIntersections::* const CurveVertical[])(const SkPoint[], SkScalar, SkScalar, SkScalar, bool) = {
     NULL,
     &SkIntersections::verticalLine,
     &SkIntersections::verticalQuad,
     &SkIntersections::verticalCubic
 };
 
-int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine&) = {
+int ( SkIntersections::* const CurveRay[])(const SkPoint[], const SkDLine&) = {
     NULL,
     &SkIntersections::lineRay,
     &SkIntersections::quadRay,
diff --git a/src/pathops/SkIntersections.h b/src/pathops/SkIntersections.h
index 0186b37..0406710 100644
--- a/src/pathops/SkIntersections.h
+++ b/src/pathops/SkIntersections.h
@@ -287,8 +287,8 @@
 #endif
 };
 
-extern int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine& );
-extern int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar top, SkScalar bottom,
+extern int (SkIntersections::* const CurveRay[])(const SkPoint[], const SkDLine& );
+extern int (SkIntersections::* const CurveVertical[])(const SkPoint[], SkScalar top, SkScalar bottom,
             SkScalar x, bool flipped);
 
 #endif
diff --git a/src/pathops/SkLineParameters.h b/src/pathops/SkLineParameters.h
index 92343c6..073d036 100644
--- a/src/pathops/SkLineParameters.h
+++ b/src/pathops/SkLineParameters.h
@@ -4,6 +4,10 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
+#ifndef SkLineParameters_DEFINED
+#define SkLineParameters_DEFINED
+
 #include "SkPathOpsCubic.h"
 #include "SkPathOpsLine.h"
 #include "SkPathOpsQuad.h"
@@ -173,3 +177,5 @@
     double fB;
     double fC;
 };
+
+#endif
diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp
index 894758c..0c87d3b 100644
--- a/src/pathops/SkOpAngle.cpp
+++ b/src/pathops/SkOpAngle.cpp
@@ -286,12 +286,9 @@
 // would cause it to intersect one of the adjacent angles
 bool SkOpAngle::computeSector() {
     if (fComputedSector) {
-        // FIXME: logically, this should return !fUnorderable, but doing so breaks testQuadratic51
-        // -- but in general, this code may not work so this may be the least of problems
-        // adding the bang fixes testQuads46x in release, however
         return !fUnorderable;
     }
-    SkASSERT(fSegment->verb() != SkPath::kLine_Verb && small());
+//    SkASSERT(fSegment->verb() != SkPath::kLine_Verb && small());
     fComputedSector = true;
     int step = fStart < fEnd ? 1 : -1;
     int limit = step > 0 ? fSegment->count() : -1;
@@ -633,7 +630,7 @@
         {{ 6,  3,  0}, { 7, -1, 15}, { 8, 11, 14}},  // abs(x) >  abs(y)
     };
     int sector = sedecimant[(xy >= 0) + (xy > 0)][(y >= 0) + (y > 0)][(x >= 0) + (x > 0)] * 2 + 1;
-    SkASSERT(SkPath::kLine_Verb == verb || sector >= 0);
+//    SkASSERT(SkPath::kLine_Verb == verb || sector >= 0);
     return sector;
 }
 
@@ -934,12 +931,12 @@
 void SkOpAngle::setSector() {
     SkPath::Verb verb = fSegment->verb();
     if (SkPath::kLine_Verb != verb && small()) {
-        fSectorStart = fSectorEnd = -1;
-        fSectorMask = 0;
-        fComputeSector = true;  // can't determine sector until segment length can be found
-        return;
+        goto deferTilLater;
     }
     fSectorStart = findSector(verb, fSweep[0].fX, fSweep[0].fY);
+    if (fSectorStart < 0) {
+        goto deferTilLater;
+    }
     if (!fIsCurve) {  // if it's a line or line-like, note that both sectors are the same
         SkASSERT(fSectorStart >= 0);
         fSectorEnd = fSectorStart;
@@ -948,6 +945,13 @@
     }
     SkASSERT(SkPath::kLine_Verb != verb);
     fSectorEnd = findSector(verb, fSweep[1].fX, fSweep[1].fY);
+    if (fSectorEnd < 0) {
+deferTilLater:
+        fSectorStart = fSectorEnd = -1;
+        fSectorMask = 0;
+        fComputeSector = true;  // can't determine sector until segment length can be found
+        return;
+    }
     if (fSectorEnd == fSectorStart) {
         SkASSERT((fSectorStart & 3) != 3);  // if the sector has no span, it can't be an exact angle
         fSectorMask = 1 << fSectorStart;
diff --git a/src/pathops/SkOpAngle.h b/src/pathops/SkOpAngle.h
index 63d378d..098c470 100644
--- a/src/pathops/SkOpAngle.h
+++ b/src/pathops/SkOpAngle.h
@@ -160,10 +160,10 @@
     void reset();
 private:
     void dump() const;  // utility to be called by user from debugger
+    SkChunkAlloc* fAngles;
 #if DEBUG_ANGLE
     int fCount;
 #endif
-    SkChunkAlloc* fAngles;
 };
 
 #endif
diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp
index 5ef702d..6d6ad79 100644
--- a/src/pathops/SkOpContour.cpp
+++ b/src/pathops/SkOpContour.cpp
@@ -57,6 +57,21 @@
     return NULL;
 }
 
+// if one is very large the smaller may have collapsed to nothing
+static void bump_out_close_span(double* startTPtr, double* endTPtr) {
+    double startT = *startTPtr;
+    double endT = *endTPtr;
+    if (approximately_negative(endT - startT)) {
+        if (endT <= 1 - FLT_EPSILON) {
+            *endTPtr += FLT_EPSILON;
+            SkASSERT(*endTPtr <= 1);
+        } else {
+            *startTPtr -= FLT_EPSILON;
+            SkASSERT(*startTPtr >= 0);
+        }
+    }
+}
+
 // first pass, add missing T values
 // second pass, determine winding values of overlaps
 void SkOpContour::addCoincidentPoints() {
@@ -82,15 +97,7 @@
         if ((cancelers = startSwapped = startT > endT)) {
             SkTSwap(startT, endT);
         }
-        if (startT == endT) { // if one is very large the smaller may have collapsed to nothing
-            if (endT <= 1 - FLT_EPSILON) {
-                endT += FLT_EPSILON;
-                SkASSERT(endT <= 1);
-            } else {
-                startT -= FLT_EPSILON;
-                SkASSERT(startT >= 0);
-            }
-        }
+        bump_out_close_span(&startT, &endT);
         SkASSERT(!approximately_negative(endT - startT));
         double oStartT = coincidence.fTs[1][0];
         double oEndT = coincidence.fTs[1][1];
@@ -98,6 +105,7 @@
             SkTSwap(oStartT, oEndT);
             cancelers ^= true;
         }
+        bump_out_close_span(&oStartT, &oEndT);
         SkASSERT(!approximately_negative(oEndT - oStartT));
         const SkPoint& startPt = coincidence.fPts[0][startSwapped];
         if (cancelers) {
@@ -259,7 +267,7 @@
     return true;
 }
 
-void SkOpContour::calcCoincidentWinding() {
+bool SkOpContour::calcCoincidentWinding() {
     int count = fCoincidences.count();
 #if DEBUG_CONCIDENT
     if (count > 0) {
@@ -268,8 +276,11 @@
 #endif
     for (int index = 0; index < count; ++index) {
         SkCoincidence& coincidence = fCoincidences[index];
-         calcCommonCoincidentWinding(coincidence);
+        if (!calcCommonCoincidentWinding(coincidence)) {
+            return false;
+        }
     }
+    return true;
 }
 
 void SkOpContour::calcPartialCoincidentWinding() {
@@ -452,16 +463,22 @@
     }
     if (cancelers) {
         if (missingT1 >= 0) {
+            if (addTo1->reversePoints(missingPt1, missingPt2)) {
+                SkTSwap(missingPt1, missingPt2);
+            }
             addTo1->addTCancel(missingPt1, missingPt2, addOther1);
         } else {
+            if (addTo2->reversePoints(missingPt1, missingPt2)) {
+                SkTSwap(missingPt1, missingPt2);
+            }
             addTo2->addTCancel(missingPt1, missingPt2, addOther2);
         }
     } else if (missingT1 >= 0) {
-        addTo1->addTCoincident(missingPt1, missingPt2, addTo1 == addTo2 ? missingT2 : otherT2,
-                addOther1);
+        SkAssertResult(addTo1->addTCoincident(missingPt1, missingPt2,
+                addTo1 == addTo2 ? missingT2 : otherT2, addOther1));
     } else {
-        addTo2->addTCoincident(missingPt2, missingPt1, addTo2 == addTo1 ? missingT1 : otherT1,
-                addOther2);
+        SkAssertResult(addTo2->addTCoincident(missingPt2, missingPt1,
+                addTo2 == addTo1 ? missingT1 : otherT1, addOther2));
     }
 }
 
@@ -529,20 +546,20 @@
     }
 }
 
-void SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) {
+bool SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) {
     if (coincidence.fNearly[0] && coincidence.fNearly[1]) {
-        return;
+        return true;
     }
     int thisIndex = coincidence.fSegments[0];
     SkOpSegment& thisOne = fSegments[thisIndex];
     if (thisOne.done()) {
-        return;
+        return true;
     }
     SkOpContour* otherContour = coincidence.fOther;
     int otherIndex = coincidence.fSegments[1];
     SkOpSegment& other = otherContour->fSegments[otherIndex];
     if (other.done()) {
-        return;
+        return true;
     }
     double startT = coincidence.fTs[0][0];
     double endT = coincidence.fTs[0][1];
@@ -553,15 +570,7 @@
         SkTSwap<double>(startT, endT);
         SkTSwap<const SkPoint*>(startPt, endPt);
     }
-    if (startT == endT) { // if span is very large, the smaller may have collapsed to nothing
-        if (endT <= 1 - FLT_EPSILON) {
-            endT += FLT_EPSILON;
-            SkASSERT(endT <= 1);
-        } else {
-            startT -= FLT_EPSILON;
-            SkASSERT(startT >= 0);
-        }
-    }
+    bump_out_close_span(&startT, &endT);
     SkASSERT(!approximately_negative(endT - startT));
     double oStartT = coincidence.fTs[1][0];
     double oEndT = coincidence.fTs[1][1];
@@ -569,16 +578,19 @@
         SkTSwap<double>(oStartT, oEndT);
         cancelers ^= true;
     }
+    bump_out_close_span(&oStartT, &oEndT);
     SkASSERT(!approximately_negative(oEndT - oStartT));
+    bool success = true;
     if (cancelers) {
         thisOne.addTCancel(*startPt, *endPt, &other);
     } else {
-        thisOne.addTCoincident(*startPt, *endPt, endT, &other);
+        success = thisOne.addTCoincident(*startPt, *endPt, endT, &other);
     }
 #if DEBUG_CONCIDENT
     thisOne.debugShowTs("p");
     other.debugShowTs("o");
 #endif
+    return success;
 }
 
 void SkOpContour::resolveNearCoincidence() {
diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h
index d1b3cd0..899367a 100644
--- a/src/pathops/SkOpContour.h
+++ b/src/pathops/SkOpContour.h
@@ -114,7 +114,7 @@
     }
 
     bool calcAngles();
-    void calcCoincidentWinding();
+    bool calcCoincidentWinding();
     void calcPartialCoincidentWinding();
 
     void checkDuplicates() {
@@ -325,7 +325,7 @@
 private:
     void alignPt(int index, SkPoint* point, int zeroPt) const;
     int alignT(bool swap, int tIndex, SkIntersections* ts) const;
-    void calcCommonCoincidentWinding(const SkCoincidence& );
+    bool calcCommonCoincidentWinding(const SkCoincidence& );
     void checkCoincidentPair(const SkCoincidence& oneCoin, int oneIdx,
                              const SkCoincidence& twoCoin, int twoIdx, bool partial);
     void joinCoincidence(const SkTArray<SkCoincidence, true>& , bool partial);
diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp
index 31a446b..8503af3 100644
--- a/src/pathops/SkOpEdgeBuilder.cpp
+++ b/src/pathops/SkOpEdgeBuilder.cpp
@@ -47,6 +47,17 @@
     fPathVerbs.push_back(SkPath::kClose_Verb);
 }
 
+// very tiny points cause numerical instability : don't allow them
+static void force_small_to_zero(SkPoint* pt) {
+    if (SkScalarAbs(pt->fX) < FLT_EPSILON_ORDERABLE_ERR) {
+        pt->fX = 0;
+    }
+    if (SkScalarAbs(pt->fY) < FLT_EPSILON_ORDERABLE_ERR) {
+        pt->fY = 0;
+    }
+}
+
+
 int SkOpEdgeBuilder::preFetch() {
     if (!fPath->isFinite()) {
         fUnparseable = true;
@@ -68,11 +79,13 @@
                     closeContour(curve[0], curveStart);
                 }
                 fPathVerbs.push_back(verb);
+                force_small_to_zero(&pts[0]);
                 fPathPts.push_back(pts[0]);
                 curveStart = curve[0] = pts[0];
                 lastCurve = false;
                 continue;
             case SkPath::kLine_Verb:
+                force_small_to_zero(&pts[1]);
                 if (SkDPoint::ApproximatelyEqual(curve[0], pts[1])) {
                     uint8_t lastVerb = fPathVerbs.back();
                     if (lastVerb != SkPath::kLine_Verb && lastVerb != SkPath::kMove_Verb) {
@@ -82,6 +95,8 @@
                 }
                 break;
             case SkPath::kQuad_Verb:
+                force_small_to_zero(&pts[1]);
+                force_small_to_zero(&pts[2]);
                 curve[1] = pts[1];
                 curve[2] = pts[2];
                 verb = SkReduceOrder::Quad(curve, pts);
@@ -102,6 +117,9 @@
                 }
                 continue;
             case SkPath::kCubic_Verb:
+                force_small_to_zero(&pts[1]);
+                force_small_to_zero(&pts[2]);
+                force_small_to_zero(&pts[3]);
                 curve[1] = pts[1];
                 curve[2] = pts[2];
                 curve[3] = pts[3];
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
index 4e8b5d2..2dda11a 100644
--- a/src/pathops/SkOpSegment.cpp
+++ b/src/pathops/SkOpSegment.cpp
@@ -251,8 +251,8 @@
                     fTs[tIndexStart].fT, xyAtT(tIndexStart).fX,
                     xyAtT(tIndexStart).fY);
 #endif
-            addTPair(fTs[tIndexStart].fT, other, other->fTs[oIndex].fT, false,
-                    fTs[tIndexStart].fPt);
+            SkPoint copy = fTs[tIndexStart].fPt;  // add t pair may move the point array
+            addTPair(fTs[tIndexStart].fT, other, other->fTs[oIndex].fT, false, copy);
         }
         if (nextT < 1 && fTs[tIndex].fWindValue) {
 #if DEBUG_CONCIDENT
@@ -261,7 +261,8 @@
                     fTs[tIndex].fT, xyAtT(tIndex).fX,
                     xyAtT(tIndex).fY);
 #endif
-            addTPair(fTs[tIndex].fT, other, other->fTs[oIndexStart].fT, false, fTs[tIndex].fPt);
+            SkPoint copy = fTs[tIndex].fPt;  // add t pair may move the point array
+            addTPair(fTs[tIndex].fT, other, other->fTs[oIndexStart].fT, false, copy);
         }
     } else {
         SkASSERT(!other->fTs[oIndexStart].fWindValue);
@@ -405,12 +406,15 @@
 }
 
 void SkOpSegment::addEndSpan(int endIndex) {
+    SkASSERT(span(endIndex).fT == 1 || (span(endIndex).fTiny
+//            && approximately_greater_than_one(span(endIndex).fT)
+    ));
     int spanCount = fTs.count();
     int startIndex = endIndex - 1;
     while (fTs[startIndex].fT == 1 || fTs[startIndex].fTiny) {
-        ++startIndex;
-        SkASSERT(startIndex < spanCount - 1);
-        ++endIndex;
+        --startIndex;
+        SkASSERT(startIndex > 0);
+        --endIndex;
     }
     SkOpAngle& angle = fAngles.push_back();
     angle.set(this, spanCount - 1, startIndex);
@@ -616,6 +620,7 @@
     int less = -1;
 // FIXME: note that this relies on spans being a continguous array
 // find range of spans with nearly the same point as this one
+    // FIXME: SkDPoint::ApproximatelyEqual is better but breaks tests at the moment
     while (&span[less + 1] - fTs.begin() > 0 && AlmostEqualUlps(span[less].fPt, pt)) {
         if (fVerb == SkPath::kCubic_Verb) {
             double tInterval = newT - span[less].fT;
@@ -628,6 +633,7 @@
         --less;
     }
     int more = 1;
+    // FIXME: SkDPoint::ApproximatelyEqual is better but breaks tests at the moment
     while (fTs.end() - &span[more - 1] > 1 && AlmostEqualUlps(span[more].fPt, pt)) {
         if (fVerb == SkPath::kCubic_Verb) {
             double tEndInterval = span[more].fT - newT;
@@ -701,7 +707,9 @@
     double oStartT = other->fTs[oIndex].fT;
     // look for first point beyond match
     while (startPt == other->fTs[--oIndex].fPt || precisely_equal(oStartT, other->fTs[oIndex].fT)) {
-        SkASSERT(oIndex > 0);
+        if (!oIndex) {
+            return;  // tiny spans may move in the wrong direction
+        }
     }
     SkOpSpan* test = &fTs[index];
     SkOpSpan* oTest = &other->fTs[oIndex];
@@ -815,7 +823,11 @@
 // FIXME? assert that only one other span has a valid windValue or oppValue
 void SkOpSegment::addSimpleAngle(int index) {
     SkOpSpan* span = &fTs[index];
-    if (index == 0) {
+    int idx;
+    int start, end;
+    if (span->fT == 0) {
+        idx = 0;
+        span = &fTs[0];
         do {
             if (span->fToAngle) {
                 SkASSERT(span->fToAngle->loopCount() == 2);
@@ -823,13 +835,15 @@
                 span->fFromAngle = span->fToAngle->next();
                 return;
             }
-            span = &fTs[++index];
+            span = &fTs[++idx];
         } while (span->fT == 0);
-        SkASSERT(index == 1);
-        index = 0;
-        SkASSERT(!fTs[0].fTiny && fTs[1].fT > 0);
-        addStartSpan(1);
+        SkASSERT(!fTs[0].fTiny && fTs[idx].fT > 0);
+        addStartSpan(idx);
+        start = 0;
+        end = idx;
     } else {
+        idx = count() - 1;
+        span = &fTs[idx];
         do {
             if (span->fFromAngle) {
                 SkASSERT(span->fFromAngle->loopCount() == 2);
@@ -837,29 +851,48 @@
                 span->fToAngle = span->fFromAngle->next();
                 return;
             }
-            span = &fTs[--index];
+            span = &fTs[--idx];
         } while (span->fT == 1);
-        SkASSERT(index == count() - 2);
-        index = count() - 1;
-        SkASSERT(!fTs[index - 1].fTiny && fTs[index - 1].fT < 1);
-        addEndSpan(index);
+        SkASSERT(!fTs[idx].fTiny && fTs[idx].fT < 1);
+        addEndSpan(++idx);
+        start = idx;
+        end = count();
     }
-    span = &fTs[index];
-    SkOpSegment* other = span->fOther;
-    SkOpSpan& oSpan = other->fTs[span->fOtherIndex];
+    SkOpSegment* other;
+    SkOpSpan* oSpan;
+    index = start;
+    do {
+        span = &fTs[index];
+        other = span->fOther;
+        int oFrom = span->fOtherIndex;
+        oSpan = &other->fTs[oFrom];
+        if (oSpan->fT < 1 && oSpan->fWindValue) {
+            break;
+        }
+        if (oSpan->fT == 0) {
+            continue;
+        }
+        oFrom = other->nextExactSpan(oFrom, -1);
+        SkOpSpan* oFromSpan = &other->fTs[oFrom];
+        SkASSERT(oFromSpan->fT < 1);
+        if (oFromSpan->fWindValue) {
+            break;
+        }
+    } while (++index < end);
     SkOpAngle* angle, * oAngle;
-    if (index == 0) {
+    if (span->fT == 0) {
         SkASSERT(span->fOtherIndex - 1 >= 0);
         SkASSERT(span->fOtherT == 1);
-        SkDEBUGCODE(SkOpSpan& oPrior = other->fTs[span->fOtherIndex - 1]);
+        SkDEBUGCODE(int oPriorIndex = other->nextExactSpan(span->fOtherIndex, -1));
+        SkDEBUGCODE(const SkOpSpan& oPrior = other->span(oPriorIndex));
         SkASSERT(!oPrior.fTiny && oPrior.fT < 1);
         other->addEndSpan(span->fOtherIndex);
         angle = span->fToAngle;
-        oAngle = oSpan.fFromAngle;
+        oAngle = oSpan->fFromAngle;
     } else {
         SkASSERT(span->fOtherIndex + 1 < other->count());
         SkASSERT(span->fOtherT == 0);
-        SkASSERT(!oSpan.fTiny && (other->fTs[span->fOtherIndex + 1].fT > 0
+        SkASSERT(!oSpan->fTiny && (other->fTs[span->fOtherIndex + 1].fT > 0
                 || (other->fTs[span->fOtherIndex + 1].fFromAngle == NULL
                 && other->fTs[span->fOtherIndex + 1].fToAngle == NULL)));
         int oIndex = 1;
@@ -873,7 +906,7 @@
         } while (true);
         other->addStartSpan(oIndex);
         angle = span->fFromAngle;
-        oAngle = oSpan.fToAngle;
+        oAngle = oSpan->fToAngle;
     }
     angle->insert(oAngle);
 }
@@ -1238,7 +1271,7 @@
 
 // set spans from start to end to increment the greater by one and decrement
 // the lesser
-void SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
+bool SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
         SkOpSegment* other) {
     bool binary = fOperand != other->fOperand;
     int index = 0;
@@ -1266,10 +1299,14 @@
     double testT = test->fT;
     SkOpSpan* oTest = &other->fTs[oIndex];
     const SkPoint* oTestPt = &oTest->fPt;
-    SkASSERT(AlmostEqualUlps(*testPt, *oTestPt));
+    // paths with extreme data will fail this test and eject out of pathops altogether later on
+    // SkASSERT(AlmostEqualUlps(*testPt, *oTestPt));
     do {
         SkASSERT(test->fT < 1);
-        SkASSERT(oTest->fT < 1);
+        if (oTest->fT == 1) {
+            // paths with extreme data may be so mismatched that we fail here
+            return false;
+        }
 
         // consolidate the winding count even if done
         if ((test->fWindValue == 0 && test->fOppValue == 0)
@@ -1348,7 +1385,10 @@
                     success = true;
                     break;
                 }
-                oPeek = &other->fTs[++oPeekIndex];
+                if (++oPeekIndex == oCount) {
+                    break;
+                }
+                oPeek = &other->fTs[oPeekIndex];
             } while (endPt == oPeek->fPt);
         }
         if (success) {
@@ -1372,10 +1412,12 @@
     }
     setCoincidentRange(startPt, endPt, other);
     other->setCoincidentRange(startPt, endPt, this);
+    return true;
 }
 
 // FIXME: this doesn't prevent the same span from being added twice
 // fix in caller, SkASSERT here?
+// FIXME: this may erroneously reject adds for cubic loops
 const SkOpSpan* SkOpSegment::addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
         const SkPoint& pt, const SkPoint& pt2) {
     int tCount = fTs.count();
@@ -1384,19 +1426,44 @@
         if (!approximately_negative(span.fT - t)) {
             break;
         }
-        if (approximately_negative(span.fT - t) && span.fOther == other
-                && approximately_equal(span.fOtherT, otherT)) {
+        if (span.fOther == other) {
+            bool tsMatch = approximately_equal(span.fT, t);
+            bool otherTsMatch = approximately_equal(span.fOtherT, otherT);
+            // FIXME: add cubic loop detecting logic here
+            // if fLoop bit is set on span, that could be enough if addOtherT copies the bit
+            // or if a new bit is added ala fOtherLoop
+            if (tsMatch || otherTsMatch) {
 #if DEBUG_ADD_T_PAIR
-            SkDebugf("%s addTPair duplicate this=%d %1.9g other=%d %1.9g\n",
-                    __FUNCTION__, fID, t, other->fID, otherT);
+                SkDebugf("%s addTPair duplicate this=%d %1.9g other=%d %1.9g\n",
+                        __FUNCTION__, fID, t, other->fID, otherT);
 #endif
-            return NULL;
+                return NULL;
+            }
+        }
+    }
+    int oCount = other->count();
+    for (int oIndex = 0; oIndex < oCount; ++oIndex) {
+        const SkOpSpan& oSpan = other->span(oIndex);
+        if (!approximately_negative(oSpan.fT - otherT)) {
+            break;
+        }
+        if (oSpan.fOther == this) {
+            bool otherTsMatch = approximately_equal(oSpan.fT, otherT);
+            bool tsMatch = approximately_equal(oSpan.fOtherT, t);
+            if (otherTsMatch || tsMatch) {
+#if DEBUG_ADD_T_PAIR
+                SkDebugf("%s addTPair other duplicate this=%d %1.9g other=%d %1.9g\n",
+                        __FUNCTION__, fID, t, other->fID, otherT);
+#endif
+                return NULL;
+            }
         }
     }
 #if DEBUG_ADD_T_PAIR
     SkDebugf("%s addTPair this=%d %1.9g other=%d %1.9g\n",
             __FUNCTION__, fID, t, other->fID, otherT);
 #endif
+    SkASSERT(other != this);
     int insertedAt = addT(other, pt, t);
     int otherInsertedAt = other->addT(this, pt2, otherT);
     addOtherT(insertedAt, otherT, otherInsertedAt);
@@ -1446,6 +1513,9 @@
     const SkOpSpan* span = &fTs[0];
     if (firstSpan->fT == 0 || span->fTiny || span->fOtherT != 1 || span->fOther->multipleEnds()) {
         index = findStartSpan(0);  // curve start intersects
+        if (fTs[index].fT == 0) {
+            return false;
+        }
         SkASSERT(index > 0);
         if (activePrior >= 0) {
             addStartSpan(index);
@@ -1534,7 +1604,7 @@
 int SkOpSegment::computeSum(int startIndex, int endIndex, SkOpAngle::IncludeType includeType) {
     SkASSERT(includeType != SkOpAngle::kUnaryXor);
     SkOpAngle* firstAngle = spanToAngle(endIndex, startIndex);
-    if (NULL == firstAngle) {
+    if (NULL == firstAngle || NULL == firstAngle->next()) {
         return SK_NaN32;
     }
     // if all angles have a computed winding,
@@ -2127,6 +2197,7 @@
                 MissingSpan& missing = missingSpans.push_back();
                 SkDEBUGCODE(sk_bzero(&missing, sizeof(missing)));
                 missing.fT = t;
+                SkASSERT(this != match);
                 missing.fOther = match;
                 missing.fOtherT = matchT;
                 missing.fPt = peekSpan.fPt;
@@ -2169,10 +2240,14 @@
     const SkOpSpan* test = base;
     const SkOpSpan* missing = NULL;
     while (test > first && (--test)->fPt == base->fPt) {
+        if (this == test->fOther) {
+            continue;
+        }
         CheckOneLink(test, oSpan, oFirst, oLast, &missing, missingSpans);
     }
     test = base;
     while (test < last && (++test)->fPt == base->fPt) {
+        SkASSERT(this != test->fOther);
         CheckOneLink(test, oSpan, oFirst, oLast, &missing, missingSpans);
     }
 }
@@ -2264,9 +2339,10 @@
         }
         const SkOpSpan& firstSpan = this->firstSpan(*thisSpan);
         const SkOpSpan& lastSpan = this->lastSpan(*thisSpan);
+        const SkOpSpan* nextSpan = &firstSpan + 1;
         ptrdiff_t smallCount = &lastSpan - &firstSpan + 1;
         SkASSERT(1 <= smallCount && smallCount < count());
-        if (smallCount <= 1) {
+        if (smallCount <= 1 && !nextSpan->fSmall) {
             SkASSERT(1 == smallCount);
             checkSmallCoincidence(firstSpan, NULL);
             continue;
@@ -2350,8 +2426,8 @@
             do {
                 ++nextSpan;
             } while (nextSpan->fSmall);
-            missing.fSegment->addTCoincident(missing.fPt, nextSpan->fPt, nextSpan->fT,
-                    missingOther);
+            SkAssertResult(missing.fSegment->addTCoincident(missing.fPt, nextSpan->fPt,
+                    nextSpan->fT, missingOther));
         } else if (otherSpan.fT > 0) {
             const SkOpSpan* priorSpan = &otherSpan;
             do {
@@ -2420,9 +2496,9 @@
     if (checkMultiple && !oSpan.fSmall) {
         return;
     }
-    SkASSERT(oSpan.fSmall);
+//    SkASSERT(oSpan.fSmall);
     if (oStartIndex < oEndIndex) {
-        addTCoincident(span.fPt, next->fPt, next->fT, other);
+        SkAssertResult(addTCoincident(span.fPt, next->fPt, next->fT, other));
     } else {
         addTCancel(span.fPt, next->fPt, other);
     }
@@ -2467,7 +2543,7 @@
                         oTest->fOtherT, tTest->fT);
 #endif
                 if (tTest->fT < oTest->fOtherT) {
-                    addTCoincident(span.fPt, next->fPt, next->fT, testOther);
+                    SkAssertResult(addTCoincident(span.fPt, next->fPt, next->fT, testOther));
                 } else {
                     addTCancel(span.fPt, next->fPt, testOther);
                 }
@@ -2541,6 +2617,7 @@
                 SkDEBUGCODE(sk_bzero(&missing, sizeof(missing)));
                 missing.fSegment = thisOther;
                 missing.fT = thisSpan->fOtherT;
+                SkASSERT(this != nextOther);
                 missing.fOther = nextOther;
                 missing.fOtherT = nextSpan->fOtherT;
                 missing.fPt = thisSpan->fPt;
@@ -3037,6 +3114,13 @@
 
 int SkOpSegment::findT(double t, const SkPoint& pt, const SkOpSegment* match) const {
     int count = this->count();
+    // prefer exact matches over approximate matches
+    for (int index = 0; index < count; ++index) {
+        const SkOpSpan& span = fTs[index];
+        if (span.fT == t && span.fOther == match) {
+            return index;
+        }
+    }
     for (int index = 0; index < count; ++index) {
         const SkOpSpan& span = fTs[index];
         if (approximately_equal_orderable(span.fT, t) && span.fOther == match) {
@@ -3348,7 +3432,7 @@
             if (cancel) {
                 match->addTCancel(startPt, endPt, other);
             } else {
-                match->addTCoincident(startPt, endPt, endT, other);
+                SkAssertResult(match->addTCoincident(startPt, endPt, endT, other));
             }
             return true;
         }
@@ -3402,7 +3486,7 @@
     SkOpSegment* other = this;
     while ((other = other->nextChase(&index, &step, &min, &last))) {
         if (other->fTs[min].fWindSum != SK_MinS32) {
-            SkASSERT(other->fTs[min].fWindSum == winding);
+//            SkASSERT(other->fTs[min].fWindSum == winding);
             SkASSERT(!last);
             break;
         }
@@ -3444,7 +3528,8 @@
 // FIXME: this is probably a bug -- rects3 asserts here
 //                    SkASSERT(other->fTs[min].fOppSum == oppWinding);
                 } else {
-                    SkASSERT(other->fTs[min].fWindSum == oppWinding);
+// FIXME: this is probably a bug -- issue414409b asserts here
+//                    SkASSERT(other->fTs[min].fWindSum == oppWinding);
 // FIXME: this is probably a bug -- skpwww_joomla_org_23 asserts here
 //                    SkASSERT(other->fTs[min].fOppSum == winding);
                 }
@@ -3859,6 +3944,9 @@
             return set_last(last, &endSpan);
         }
         const SkOpAngle* next = angle->next();
+        if (NULL == next) {
+            return NULL;
+        }
         if (angle->sign() != next->sign()) {
 #if DEBUG_WINDING
             SkDebugf("%s mismatched signs\n", __FUNCTION__);
@@ -3874,7 +3962,10 @@
         return set_last(last, &endSpan);
     }
     SkASSERT(*indexPtr >= 0);
-    SkASSERT(otherEnd >= 0);
+    if (otherEnd < 0) {
+        return NULL;
+    }
+//    SkASSERT(otherEnd >= 0);
 #if 1
     int origMin = origIndex + (step < 0 ? step : 0);
     const SkOpSpan& orig = this->span(origMin);
@@ -3956,6 +4047,24 @@
     }
 }
 
+bool SkOpSegment::reversePoints(const SkPoint& p1, const SkPoint& p2) const {
+    SkASSERT(p1 != p2);
+    int spanCount = count();
+    int p1IndexMin = -1;
+    int p2IndexMax = spanCount;
+    for (int index = 0; index < spanCount; ++index) {
+        const SkOpSpan& span = fTs[index];
+        if (span.fPt == p1) {
+            if (p1IndexMin < 0) {
+                p1IndexMin = index;
+            }
+        } else if (span.fPt == p2) {
+            p2IndexMax = index;
+        }
+    }
+    return p1IndexMin > p2IndexMax;
+}
+
 void SkOpSegment::setCoincidentRange(const SkPoint& startPt, const SkPoint& endPt, 
         SkOpSegment* other) {
     int count = this->count();
diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
index d191e88..24d08bd 100644
--- a/src/pathops/SkOpSegment.h
+++ b/src/pathops/SkOpSegment.h
@@ -177,6 +177,8 @@
         fTs.reset();
     }
 
+    bool reversePoints(const SkPoint& p1, const SkPoint& p2) const;
+
     void setOppXor(bool isOppXor) {
         fOppXor = isOppXor;
     }
@@ -282,7 +284,7 @@
     void addStartSpan(int endIndex);
     int addT(SkOpSegment* other, const SkPoint& pt, double newT);
     void addTCancel(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
-    void addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
+    bool addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
                         SkOpSegment* other);
     const SkOpSpan* addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
                              const SkPoint& pt);
diff --git a/src/pathops/SkPathOpsBounds.cpp b/src/pathops/SkPathOpsBounds.cpp
index 106cd30..e5b26ee 100644
--- a/src/pathops/SkPathOpsBounds.cpp
+++ b/src/pathops/SkPathOpsBounds.cpp
@@ -32,7 +32,7 @@
             SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom));
 }
 
-void (SkPathOpsBounds::*SetCurveBounds[])(const SkPoint[]) = {
+void (SkPathOpsBounds::* const SetCurveBounds[])(const SkPoint[]) = {
     NULL,
     &SkPathOpsBounds::setLineBounds,
     &SkPathOpsBounds::setQuadBounds,
diff --git a/src/pathops/SkPathOpsBounds.h b/src/pathops/SkPathOpsBounds.h
index 07ad5d4..cabc639 100644
--- a/src/pathops/SkPathOpsBounds.h
+++ b/src/pathops/SkPathOpsBounds.h
@@ -67,6 +67,6 @@
     typedef SkRect INHERITED;
 };
 
-extern void (SkPathOpsBounds::*SetCurveBounds[])(const SkPoint[]);
+extern void (SkPathOpsBounds::* const SetCurveBounds[])(const SkPoint[]);
 
 #endif
diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp
index 9a8a2cf..f7b7273 100644
--- a/src/pathops/SkPathOpsCommon.cpp
+++ b/src/pathops/SkPathOpsCommon.cpp
@@ -699,7 +699,9 @@
 #if DEBUG_SHOW_WINDING
     SkOpContour::debugShowWindingValues(contourList);
 #endif
-    CoincidenceCheck(contourList, total);
+    if (!CoincidenceCheck(contourList, total)) {
+        return false;
+    }
 #if DEBUG_SHOW_WINDING
     SkOpContour::debugShowWindingValues(contourList);
 #endif
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index 96029b3..7db93f5 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -108,6 +108,7 @@
     const SkOpAngle* next = this;
     do {
         next->dumpOne(true);
+        SkDebugf("\n");
         next = next->fNext;
     } while (next && next != first);
 }
diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h
index 9dc562f..18097e7 100644
--- a/src/pathops/SkPathOpsDebug.h
+++ b/src/pathops/SkPathOpsDebug.h
@@ -86,7 +86,7 @@
 #define DEBUG_CHECK_TINY 1
 #define DEBUG_CONCIDENT 1
 #define DEBUG_CROSS 01
-#define DEBUG_CUBIC_BINARY_SEARCH 1
+#define DEBUG_CUBIC_BINARY_SEARCH 0
 #define DEBUG_DUPLICATES 1
 #define DEBUG_FLAT_QUADS 0
 #define DEBUG_FLOW 1
@@ -169,6 +169,7 @@
         SkPathOpsDebug::DeleteNameStr)))
     static void BumpTestName(char* );
 #endif
+    static void ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration);
     static void ShowPath(const SkPath& one, const SkPath& two, SkPathOp op, const char* name);
     static void DumpCoincidence(const SkTArray<class SkOpContour, true>& contours);
     static void DumpCoincidence(const SkTArray<class SkOpContour* , true>& contours);
diff --git a/src/pathops/SkPathOpsLine.cpp b/src/pathops/SkPathOpsLine.cpp
index 6229619..e4fc97b 100644
--- a/src/pathops/SkPathOpsLine.cpp
+++ b/src/pathops/SkPathOpsLine.cpp
@@ -89,7 +89,7 @@
     if (unequal) {
         *unequal = (float) largest != (float) (largest + dist);
     }
-    t = SkPinT(t);
+    t = SkPinT(t);  // a looser pin breaks skpwww_lptemp_com_3
     SkASSERT(between(0, t, 1));
     return t;
 }
diff --git a/src/pathops/SkPathOpsTightBounds.cpp b/src/pathops/SkPathOpsTightBounds.cpp
new file mode 100644
index 0000000..0f63f39
--- /dev/null
+++ b/src/pathops/SkPathOpsTightBounds.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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 "SkOpEdgeBuilder.h"
+#include "SkPathOpsCommon.h"
+
+bool TightBounds(const SkPath& path, SkRect* result) {
+    // turn path into list of segments
+    SkTArray<SkOpContour> contours;
+    SkOpEdgeBuilder builder(path, contours);
+    if (!builder.finish()) {
+        return false;
+    }
+    SkTArray<SkOpContour*, true> contourList;
+    MakeContourList(contours, contourList, false, false);
+    SkOpContour** currentPtr = contourList.begin();
+    result->setEmpty();
+    if (!currentPtr) {
+        return true;
+    }
+    SkOpContour** listEnd = contourList.end();
+    SkOpContour* current = *currentPtr++;
+    SkPathOpsBounds bounds = current->bounds();
+    while (currentPtr != listEnd) {
+        current = *currentPtr++;
+        bounds.add(current->bounds());
+    }
+    *result = bounds;
+    return true;
+}
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index ab4d71d..7369ff8 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -8,6 +8,7 @@
 #include "SkPDFDevice.h"
 
 #include "SkAnnotation.h"
+#include "SkBitmapDevice.h"
 #include "SkColor.h"
 #include "SkClipStack.h"
 #include "SkData.h"
@@ -29,27 +30,12 @@
 #include "SkRect.h"
 #include "SkRRect.h"
 #include "SkString.h"
+#include "SkSurface.h"
 #include "SkTextFormatParams.h"
 #include "SkTemplates.h"
 #include "SkTypefacePriv.h"
 #include "SkTSet.h"
 
-#ifdef SK_BUILD_FOR_ANDROID
-#include "SkTypeface_android.h"
-
-struct TypefaceFallbackData {
-    SkTypeface* typeface;
-    int lowerBounds;
-    int upperBounds;
-
-    bool operator==(const TypefaceFallbackData& b) const {
-        return typeface == b.typeface &&
-               lowerBounds == b.lowerBounds &&
-               upperBounds == b.upperBounds;
-    }
-};
-#endif
-
 #define DPI_FOR_RASTER_SCALE_ONE 72
 
 // Utility functions
@@ -133,7 +119,7 @@
 
 static int force_glyph_encoding(const SkPaint& paint, const void* text,
                                 size_t len, SkGlyphStorage* storage,
-                                uint16_t** glyphIDs) {
+                                const uint16_t** glyphIDs) {
     // Make sure we have a glyph id encoding.
     if (paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) {
         int numGlyphs = paint.textToGlyphs(text, len, NULL);
@@ -146,8 +132,7 @@
     // For user supplied glyph ids we need to validate them.
     SkASSERT((len & 1) == 0);
     int numGlyphs = SkToInt(len / 2);
-    const uint16_t* input =
-        reinterpret_cast<uint16_t*>(const_cast<void*>((text)));
+    const uint16_t* input = static_cast<const uint16_t*>(text);
 
     int maxGlyphID = max_glyphid_for_typeface(paint.getTypeface());
     int validated;
@@ -157,7 +142,7 @@
         }
     }
     if (validated >= numGlyphs) {
-        *glyphIDs = reinterpret_cast<uint16_t*>(const_cast<void*>((text)));
+        *glyphIDs = static_cast<const uint16_t*>(text);
         return numGlyphs;
     }
 
@@ -583,6 +568,15 @@
 }
 
 SkBaseDevice* SkPDFDevice::onCreateDevice(const SkImageInfo& info, Usage usage) {
+    // PDF does not support image filters, so render them on CPU.
+    // Note that this rendering is done at "screen" resolution (100dpi), not
+    // printer resolution.
+    // FIXME: It may be possible to express some filters natively using PDF
+    // to improve quality and file size (http://skbug.com/3043)
+    if (kImageFilter_Usage == usage) {
+        return SkBitmapDevice::Create(info);
+    }
+
     SkMatrix initialTransform;
     initialTransform.reset();
     SkISize size = SkISize::Make(info.width(), info.height());
@@ -702,8 +696,8 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static inline SkBitmap makeContentBitmap(const SkISize& contentSize,
-                                         const SkMatrix* initialTransform) {
+static inline SkImageInfo make_content_info(const SkISize& contentSize,
+                                            const SkMatrix* initialTransform) {
     SkImageInfo info;
     if (initialTransform) {
         // Compute the size of the drawing area.
@@ -723,24 +717,22 @@
         info = SkImageInfo::MakeUnknown(abs(contentSize.fWidth),
                                         abs(contentSize.fHeight));
     }
-
-    SkBitmap bitmap;
-    bitmap.setInfo(info);
-    return bitmap;
+    return info;
 }
 
 // TODO(vandebo) change pageSize to SkSize.
-// TODO: inherit from SkBaseDevice instead of SkBitmapDevice
 SkPDFDevice::SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
                          const SkMatrix& initialTransform)
-    : SkBitmapDevice(makeContentBitmap(contentSize, &initialTransform)),
-      fPageSize(pageSize),
-      fContentSize(contentSize),
-      fLastContentEntry(NULL),
-      fLastMarginContentEntry(NULL),
-      fClipStack(NULL),
-      fEncoder(NULL),
-      fRasterDpi(72.0f) {
+    : fPageSize(pageSize)
+    , fContentSize(contentSize)
+    , fLastContentEntry(NULL)
+    , fLastMarginContentEntry(NULL)
+    , fClipStack(NULL)
+    , fEncoder(NULL)
+    , fRasterDpi(72.0f)
+{
+    const SkImageInfo info = make_content_info(contentSize, &initialTransform);
+
     // Just report that PDF does not supports perspective in the
     // initial transform.
     NOT_IMPLEMENTED(initialTransform.hasPerspective(), true);
@@ -751,10 +743,10 @@
     fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight));
     fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1);
     fInitialTransform.preConcat(initialTransform);
+    fLegacyBitmap.setInfo(info);
 
-    SkIRect existingClip = SkIRect::MakeWH(this->width(), this->height());
+    SkIRect existingClip = SkIRect::MakeWH(info.width(), info.height());
     fExistingClipRegion.setRect(existingClip);
-
     this->init();
 }
 
@@ -762,17 +754,19 @@
 SkPDFDevice::SkPDFDevice(const SkISize& layerSize,
                          const SkClipStack& existingClipStack,
                          const SkRegion& existingClipRegion)
-    : SkBitmapDevice(makeContentBitmap(layerSize, NULL)),
-      fPageSize(layerSize),
-      fContentSize(layerSize),
-      fExistingClipStack(existingClipStack),
-      fExistingClipRegion(existingClipRegion),
-      fLastContentEntry(NULL),
-      fLastMarginContentEntry(NULL),
-      fClipStack(NULL),
-      fEncoder(NULL),
-      fRasterDpi(72.0f) {
+    : fPageSize(layerSize)
+    , fContentSize(layerSize)
+    , fExistingClipStack(existingClipStack)
+    , fExistingClipRegion(existingClipRegion)
+    , fLastContentEntry(NULL)
+    , fLastMarginContentEntry(NULL)
+    , fClipStack(NULL)
+    , fEncoder(NULL)
+    , fRasterDpi(72.0f)
+{
     fInitialTransform.reset();
+    fLegacyBitmap.setInfo(make_content_info(layerSize, NULL));
+
     this->init();
 }
 
@@ -961,13 +955,18 @@
                           &content.entry()->fContent);
 }
 
-void SkPDFDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect,
-                            const SkPaint& paint) {
+void SkPDFDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
     SkPath  path;
     path.addRRect(rrect);
     this->drawPath(draw, path, paint, NULL, true);
 }
 
+void SkPDFDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
+    SkPath  path;
+    path.addOval(oval);
+    this->drawPath(draw, path, paint, NULL, true);
+}
+
 void SkPDFDevice::drawPath(const SkDraw& d, const SkPath& origPath,
                            const SkPaint& paint, const SkMatrix* prePathMatrix,
                            bool pathIsMutable) {
@@ -1125,7 +1124,7 @@
     }
 
     SkGlyphStorage storage(0);
-    uint16_t* glyphIDs = NULL;
+    const uint16_t* glyphIDs = NULL;
     int numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphIDs);
     textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
 
@@ -1138,8 +1137,9 @@
     while (numGlyphs > consumedGlyphCount) {
         updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry());
         SkPDFFont* font = content.entry()->fState.fFont;
+        //TODO: the const_cast here is a bug if the encoding started out as glyph encoding.
         int availableGlyphs =
-            font->glyphsToPDFFontEncoding(glyphIDs + consumedGlyphCount,
+            font->glyphsToPDFFontEncoding(const_cast<uint16_t*>(glyphIDs) + consumedGlyphCount,
                                           numGlyphs - consumedGlyphCount);
         fFontGlyphUsage->noteGlyphUsage(font, glyphIDs + consumedGlyphCount,
                                         availableGlyphs);
@@ -1169,120 +1169,9 @@
         return;
     }
 
-#ifdef SK_BUILD_FOR_ANDROID
-    /*
-     * In the case that we have enabled fallback fonts on Android we need to
-     * take the following steps to ensure that the PDF draws all characters,
-     * regardless of their underlying font file, correctly.
-     *
-     * 1. Convert input into GlyphID encoding if it currently is not
-     * 2. Iterate over the glyphIDs and identify the actual typeface that each
-     *    glyph resolves to
-     * 3. Iterate over those typefaces and recursively call this function with
-     *    only the glyphs (and their positions) that the typeface is capable of
-     *    resolving.
-     */
-    if (paint.getPaintOptionsAndroid().isUsingFontFallbacks()) {
-        uint16_t* glyphIDs = NULL;
-        SkGlyphStorage tmpStorage(0);
-        size_t numGlyphs = 0;
-
-        // convert to glyphIDs
-        if (paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding) {
-            numGlyphs = len / 2;
-            glyphIDs = reinterpret_cast<uint16_t*>(const_cast<void*>(text));
-        } else {
-            numGlyphs = paint.textToGlyphs(text, len, NULL);
-            tmpStorage.reset(numGlyphs);
-            paint.textToGlyphs(text, len, tmpStorage.get());
-            glyphIDs = tmpStorage.get();
-        }
-
-        // if no typeface is provided in the paint get the default
-        SkAutoTUnref<SkTypeface> origFace(SkSafeRef(paint.getTypeface()));
-        if (NULL == origFace.get()) {
-            origFace.reset(SkTypeface::RefDefault());
-        }
-        const uint16_t origGlyphCount = origFace->countGlyphs();
-
-        // keep a list of the already visited typefaces and some data about them
-        SkTDArray<TypefaceFallbackData> visitedTypefaces;
-
-        // find all the typefaces needed to resolve this run of text
-        bool usesOriginalTypeface = false;
-        for (uint16_t x = 0; x < numGlyphs; ++x) {
-            // optimization that checks to see if original typeface can resolve
-            // the glyph
-            if (glyphIDs[x] < origGlyphCount) {
-                usesOriginalTypeface = true;
-                continue;
-            }
-
-            // find the fallback typeface that supports this glyph
-            TypefaceFallbackData data;
-            data.typeface =
-                    SkGetTypefaceForGlyphID(glyphIDs[x], origFace.get(),
-                                            paint.getPaintOptionsAndroid(),
-                                            &data.lowerBounds,
-                                            &data.upperBounds);
-            // add the typeface and its data if we don't have it
-            if (data.typeface && !visitedTypefaces.contains(data)) {
-                visitedTypefaces.push(data);
-            }
-        }
-
-        // if the original font was used then add it to the list as well
-        if (usesOriginalTypeface) {
-            TypefaceFallbackData* data = visitedTypefaces.push();
-            data->typeface = origFace.get();
-            data->lowerBounds = 0;
-            data->upperBounds = origGlyphCount;
-        }
-
-        // keep a scratch glyph and pos storage
-        SkAutoTMalloc<SkScalar> posStorage(len * scalarsPerPos);
-        SkScalar* tmpPos = posStorage.get();
-        SkGlyphStorage glyphStorage(numGlyphs);
-        uint16_t* tmpGlyphIDs = glyphStorage.get();
-
-        // loop through all the valid typefaces, trim the glyphs to only those
-        // resolved by the typeface, and then draw that run of glyphs
-        for (int x = 0; x < visitedTypefaces.count(); ++x) {
-            const TypefaceFallbackData& data = visitedTypefaces[x];
-
-            int tmpGlyphCount = 0;
-            for (uint16_t y = 0; y < numGlyphs; ++y) {
-                if (glyphIDs[y] >= data.lowerBounds &&
-                        glyphIDs[y] < data.upperBounds) {
-                    tmpGlyphIDs[tmpGlyphCount] = glyphIDs[y] - data.lowerBounds;
-                    memcpy(&(tmpPos[tmpGlyphCount * scalarsPerPos]),
-                           &(pos[y * scalarsPerPos]),
-                           scalarsPerPos * sizeof(SkScalar));
-                    tmpGlyphCount++;
-                }
-            }
-
-            // recursively call this function with the right typeface
-            SkPaint tmpPaint = paint;
-            tmpPaint.setTypeface(data.typeface);
-            tmpPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-
-            // turn off fallback chaining
-            SkPaintOptionsAndroid paintOpts = tmpPaint.getPaintOptionsAndroid();
-            paintOpts.setUseFontFallbacks(false);
-            tmpPaint.setPaintOptionsAndroid(paintOpts);
-
-            this->drawPosText(d, tmpGlyphIDs, tmpGlyphCount * 2, tmpPos, constY,
-                              scalarsPerPos, tmpPaint);
-        }
-        return;
-    }
-#endif
-
     SkGlyphStorage storage(0);
-    uint16_t* glyphIDs = NULL;
-    size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage,
-                                            &glyphIDs);
+    const uint16_t* glyphIDs = NULL;
+    size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphIDs);
     textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
 
     SkDrawCacheProc glyphCacheProc = textPaint.getDrawCacheProc();
@@ -1292,19 +1181,23 @@
         SkPDFFont* font = content.entry()->fState.fFont;
         uint16_t encodedValue = glyphIDs[i];
         if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
+            // The current pdf font cannot encode the current glyph.
+            // Try to get a pdf font which can encode the current glyph.
             updateFont(textPaint, glyphIDs[i], content.entry());
-            i--;
-            continue;
+            font = content.entry()->fState.fFont;
+            if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
+                SkDEBUGFAIL("PDF could not encode glyph.");
+                continue;
+            }
         }
+
         fFontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1);
         SkScalar x = pos[i * scalarsPerPos];
         SkScalar y = scalarsPerPos == 1 ? constY : pos[i * scalarsPerPos + 1];
         align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y);
-        set_text_transform(x, y, textPaint.getTextSkewX(),
-                           &content.entry()->fContent);
+        set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fContent);
         SkString encodedString =
-            SkPDFString::FormatString(&encodedValue, 1,
-                                      font->multiByteGlyphs());
+            SkPDFString::FormatString(&encodedValue, 1, font->multiByteGlyphs());
         content.entry()->fContent.writeText(encodedString.c_str());
         content.entry()->fContent.writeText(" Tj\n");
     }
@@ -1364,6 +1257,10 @@
     fFontGlyphUsage->merge(pdfDevice->getFontGlyphUsage());
 }
 
+SkImageInfo SkPDFDevice::imageInfo() const {
+    return fLegacyBitmap.info();
+}
+
 void SkPDFDevice::onAttachToCanvas(SkCanvas* canvas) {
     INHERITED::onAttachToCanvas(canvas);
 
@@ -1377,6 +1274,10 @@
     fClipStack = NULL;
 }
 
+SkSurface* SkPDFDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
+    return SkSurface::NewRaster(info, &props);
+}
+
 ContentEntry* SkPDFDevice::getLastContentEntry() {
     if (fDrawingArea == kContent_DrawingArea) {
         return fLastContentEntry;
@@ -2232,13 +2133,12 @@
 
         const int w = SkScalarCeilToInt(physicalPerspectiveOutline.getBounds().width());
         const int h = SkScalarCeilToInt(physicalPerspectiveOutline.getBounds().height());
-        if (!perspectiveBitmap.allocPixels(SkImageInfo::MakeN32Premul(w, h))) {
+        if (!perspectiveBitmap.tryAllocN32Pixels(w, h)) {
             return;
         }
         perspectiveBitmap.eraseColor(SK_ColorTRANSPARENT);
 
-        SkBitmapDevice device(perspectiveBitmap);
-        SkCanvas canvas(&device);
+        SkCanvas canvas(perspectiveBitmap);
 
         SkScalar deltaX = bounds.left();
         SkScalar deltaY = bounds.top();
@@ -2295,8 +2195,8 @@
         return;
     }
 
-    SkAutoTUnref<SkPDFImage> image(
-        SkPDFImage::CreateImage(*bitmap, subset, fEncoder));
+    SkAutoTUnref<SkPDFObject> image(
+            SkPDFCreateImageObject(*bitmap, subset, fEncoder));
     if (!image) {
         return;
     }
@@ -2305,6 +2205,3 @@
                                 &content.entry()->fContent);
 }
 
-bool SkPDFDevice::allowImageFilter(const SkImageFilter*) {
-    return false;
-}
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index 49d383b..7d8b29b 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -150,8 +150,8 @@
     return -1;
 }
 
-SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen,
-                            size_t* dataLen, size_t* trailerLen) {
+static SkData* handle_type1_stream(SkStream* srcStream, size_t* headerLen,
+                                   size_t* dataLen, size_t* trailerLen) {
     // srcStream may be backed by a file or a unseekable fd, so we may not be
     // able to use skip(), rewind(), or getMemoryBase().  read()ing through
     // the input only once is doable, but very ugly. Furthermore, it'd be nice
@@ -199,26 +199,42 @@
     SkAutoDataUnref aud(data);
 
     if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
-        SkMemoryStream* result =
-            new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
-        memcpy((char*)result->getAtPos(), src + 6, *headerLen);
-        result->seek(*headerLen);
-        memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6, *dataLen);
-        result->seek(*headerLen + *dataLen);
-        memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6 + *dataLen,
-               *trailerLen);
-        result->rewind();
-        return result;
+        static const int kPFBSectionHeaderLength = 6;
+        const size_t length = *headerLen + *dataLen + *trailerLen;
+        SkASSERT(length > 0);
+        SkASSERT(length + (2 * kPFBSectionHeaderLength) <= srcLen);
+
+        SkData* data = SkData::NewUninitialized(length);
+
+        const uint8_t* const srcHeader = src + kPFBSectionHeaderLength;
+        // There is a six-byte section header before header and data
+        // (but not trailer) that we're not going to copy.
+        const uint8_t* const srcData = srcHeader + *headerLen + kPFBSectionHeaderLength;
+        const uint8_t* const srcTrailer = srcData + *headerLen;
+
+        uint8_t* const resultHeader = (uint8_t*)data->writable_data();
+        uint8_t* const resultData = resultHeader + *headerLen;
+        uint8_t* const resultTrailer = resultData + *dataLen;
+
+        SkASSERT(resultTrailer + *trailerLen == resultHeader + length);
+
+        memcpy(resultHeader,  srcHeader,  *headerLen);
+        memcpy(resultData,    srcData,    *dataLen);
+        memcpy(resultTrailer, srcTrailer, *trailerLen);
+
+        return data;
     }
 
     // A PFA has to be converted for PDF.
     size_t hexDataLen;
     if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
                  trailerLen)) {
-        SkMemoryStream* result =
-            new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
-        memcpy((char*)result->getAtPos(), src, *headerLen);
-        result->seek(*headerLen);
+        const size_t length = *headerLen + *dataLen + *trailerLen;
+        SkASSERT(length > 0);
+        SkAutoTMalloc<uint8_t> buffer(length);
+
+        memcpy(buffer.get(), src, *headerLen);
+        uint8_t* const resultData = &(buffer[*headerLen]);
 
         const uint8_t* hexData = src + *headerLen;
         const uint8_t* trailer = hexData + hexDataLen;
@@ -236,21 +252,19 @@
             } else {
                 dataByte |= curNibble;
                 highNibble = true;
-                ((char *)result->getAtPos())[outputOffset++] = dataByte;
+                resultData[outputOffset++] = dataByte;
             }
         }
         if (!highNibble) {
-            ((char *)result->getAtPos())[outputOffset++] = dataByte;
+            resultData[outputOffset++] = dataByte;
         }
         SkASSERT(outputOffset == *dataLen);
-        result->seek(*headerLen + outputOffset);
 
-        memcpy((char *)result->getAtPos(), src + *headerLen + hexDataLen,
-               *trailerLen);
-        result->rewind();
-        return result;
+        uint8_t* const resultTrailer = &(buffer[*headerLen + outputOffset]);
+        memcpy(resultTrailer, src + *headerLen + hexDataLen, *trailerLen);
+
+        return SkData::NewFromMalloc(buffer.detach(), length);
     }
-
     return NULL;
 }
 
@@ -556,9 +570,8 @@
     append_cmap_sections(glyphToUnicode, subset, &cmap, multiByteGlyphs,
                          firstGlyphID, lastGlyphID);
     append_cmap_footer(&cmap);
-    SkAutoTUnref<SkMemoryStream> cmapStream(new SkMemoryStream());
-    cmapStream->setData(cmap.copyToData())->unref();
-    return new SkPDFStream(cmapStream.get());
+    SkAutoTUnref<SkData> cmapData(cmap.copyToData());
+    return new SkPDFStream(cmapData.get());
 }
 
 #if defined (SK_SFNTLY_SUBSETTER)
@@ -574,6 +587,7 @@
                                      SkPDFStream** fontStream) {
     int ttcIndex;
     SkAutoTUnref<SkStream> fontData(typeface->openStream(&ttcIndex));
+    SkASSERT(fontData.get());
 
     size_t fontSize = fontData->getLength();
 
@@ -816,7 +830,7 @@
         return CanonicalFonts()[relatedFontIndex].fFont;
     }
 
-    SkAutoTUnref<SkAdvancedTypefaceMetrics> fontMetrics;
+    SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics;
     SkPDFDict* relatedFontDescriptor = NULL;
     if (relatedFontIndex >= 0) {
         SkPDFFont* relatedFont = CanonicalFonts()[relatedFontIndex].fFont;
@@ -872,16 +886,14 @@
 
 // static
 SkTDArray<SkPDFFont::FontRec>& SkPDFFont::CanonicalFonts() {
-    // This initialization is only thread safe with gcc.
+    SkPDFFont::CanonicalFontsMutex().assertHeld();
     static SkTDArray<FontRec> gCanonicalFonts;
     return gCanonicalFonts;
 }
 
+SK_DECLARE_STATIC_MUTEX(gCanonicalFontsMutex);
 // static
 SkBaseMutex& SkPDFFont::CanonicalFontsMutex() {
-    // This initialization is only thread safe with gcc, or when
-    // POD-style mutex initialization is used.
-    SK_DECLARE_STATIC_MUTEX(gCanonicalFontsMutex);
     return gCanonicalFontsMutex;
 }
 
@@ -898,7 +910,8 @@
     return false;
 }
 
-SkPDFFont::SkPDFFont(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
+SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info,
+                     SkTypeface* typeface,
                      SkPDFDict* relatedFontDescriptor)
         : SkPDFDict("Font"),
           fTypeface(ref_or_default(typeface)),
@@ -915,7 +928,7 @@
 }
 
 // static
-SkPDFFont* SkPDFFont::Create(SkAdvancedTypefaceMetrics* info,
+SkPDFFont* SkPDFFont::Create(const SkAdvancedTypefaceMetrics* info,
                              SkTypeface* typeface, uint16_t glyphID,
                              SkPDFDict* relatedFontDescriptor) {
     SkAdvancedTypefaceMetrics::FontType type =
@@ -946,11 +959,11 @@
     return new SkPDFType3Font(info, typeface, glyphID);
 }
 
-SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() {
+const SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() {
     return fFontInfo.get();
 }
 
-void SkPDFFont::setFontInfo(SkAdvancedTypefaceMetrics* info) {
+void SkPDFFont::setFontInfo(const SkAdvancedTypefaceMetrics* info) {
     if (info == NULL || info == fFontInfo.get()) {
         return;
     }
@@ -1000,6 +1013,7 @@
             scaleFromFontUnits(fFontInfo->fDescent, emSize));
     fDescriptor->insertScalar("StemV",
             scaleFromFontUnits(fFontInfo->fStemV, emSize));
+
     fDescriptor->insertScalar("CapHeight",
             scaleFromFontUnits(fFontInfo->fCapHeight, emSize));
     fDescriptor->insertInt("ItalicAngle", fFontInfo->fItalicAngle);
@@ -1013,7 +1027,7 @@
     return true;
 }
 
-void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(int16_t glyphID) {
+void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) {
     // Single byte glyph encoding supports a max of 255 glyphs.
     fFirstGlyphID = glyphID - (glyphID - 1) % 255;
     if (fLastGlyphID > fFirstGlyphID + 255 - 1) {
@@ -1065,7 +1079,7 @@
 // class SkPDFType0Font
 ///////////////////////////////////////////////////////////////////////////////
 
-SkPDFType0Font::SkPDFType0Font(SkAdvancedTypefaceMetrics* info,
+SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info,
                                SkTypeface* typeface)
         : SkPDFFont(info, typeface, NULL) {
     SkDEBUGCODE(fPopulated = false);
@@ -1115,7 +1129,7 @@
 // class SkPDFCIDFont
 ///////////////////////////////////////////////////////////////////////////////
 
-SkPDFCIDFont::SkPDFCIDFont(SkAdvancedTypefaceMetrics* info,
+SkPDFCIDFont::SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info,
                            SkTypeface* typeface, const SkPDFGlyphSet* subset)
         : SkPDFFont(info, typeface, NULL) {
     populate(subset);
@@ -1205,7 +1219,7 @@
                   info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo);
         uint32_t* glyphs = (glyphIDs.count() == 0) ? NULL : glyphIDs.begin();
         uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0;
-        SkAutoTUnref<SkAdvancedTypefaceMetrics> fontMetrics(
+        SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics(
             typeface()->getAdvancedTypefaceMetrics(info, glyphs, glyphsCount));
         setFontInfo(fontMetrics.get());
         addFontDescriptor(0, &glyphIDs);
@@ -1271,7 +1285,7 @@
 // class SkPDFType1Font
 ///////////////////////////////////////////////////////////////////////////////
 
-SkPDFType1Font::SkPDFType1Font(SkAdvancedTypefaceMetrics* info,
+SkPDFType1Font::SkPDFType1Font(const SkAdvancedTypefaceMetrics* info,
                                SkTypeface* typeface,
                                uint16_t glyphID,
                                SkPDFDict* relatedFontDescriptor)
@@ -1297,13 +1311,13 @@
     size_t data SK_INIT_TO_AVOID_WARNING;
     size_t trailer SK_INIT_TO_AVOID_WARNING;
     SkAutoTUnref<SkStream> rawFontData(typeface()->openStream(&ttcIndex));
-    SkStream* fontData = handleType1Stream(rawFontData.get(), &header, &data,
-                                           &trailer);
-    if (fontData == NULL) {
+    SkAutoTUnref<SkData> fontData(handle_type1_stream(rawFontData.get(), &header,
+                                                      &data, &trailer));
+    if (fontData.get() == NULL) {
         return false;
     }
     if (canEmbed()) {
-        SkAutoTUnref<SkPDFStream> fontStream(new SkPDFStream(fontData));
+        SkAutoTUnref<SkPDFStream> fontStream(new SkPDFStream(fontData.get()));
         addResource(fontStream.get());
         fontStream->insertInt("Length1", header);
         fontStream->insertInt("Length2", data);
@@ -1401,7 +1415,7 @@
 // class SkPDFType3Font
 ///////////////////////////////////////////////////////////////////////////////
 
-SkPDFType3Font::SkPDFType3Font(SkAdvancedTypefaceMetrics* info,
+SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
                                SkTypeface* typeface,
                                uint16_t glyphID)
         : SkPDFFont(info, typeface, NULL) {
@@ -1410,7 +1424,7 @@
 
 SkPDFType3Font::~SkPDFType3Font() {}
 
-bool SkPDFType3Font::populate(int16_t glyphID) {
+bool SkPDFType3Font::populate(uint16_t glyphID) {
     SkPaint paint;
     paint.setTypeface(typeface());
     paint.setTextSize(1000);
diff --git a/src/pdf/SkPDFFont.h b/src/pdf/SkPDFFont.h
index 058a042..27f1b5b 100644
--- a/src/pdf/SkPDFFont.h
+++ b/src/pdf/SkPDFFont.h
@@ -141,12 +141,12 @@
 
 protected:
     // Common constructor to handle common members.
-    SkPDFFont(SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
+    SkPDFFont(const SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
               SkPDFDict* relatedFontDescriptor);
 
     // Accessors for subclass.
-    SkAdvancedTypefaceMetrics* fontInfo();
-    void setFontInfo(SkAdvancedTypefaceMetrics* info);
+    const SkAdvancedTypefaceMetrics* fontInfo();
+    void setFontInfo(const SkAdvancedTypefaceMetrics* info);
     uint16_t firstGlyphID() const;
     uint16_t lastGlyphID() const;
     void setLastGlyphID(uint16_t glyphID);
@@ -164,14 +164,14 @@
     /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
      *  including the passed glyphID.
      */
-    void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
+    void adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID);
 
     // Generate ToUnicode table according to glyph usage subset.
     // If subset is NULL, all available glyph ids will be used.
     void populateToUnicodeTable(const SkPDFGlyphSet* subset);
 
     // Create instances of derived types based on fontInfo.
-    static SkPDFFont* Create(SkAdvancedTypefaceMetrics* fontInfo,
+    static SkPDFFont* Create(const SkAdvancedTypefaceMetrics* fontInfo,
                              SkTypeface* typeface, uint16_t glyphID,
                              SkPDFDict* relatedFontDescriptor);
 
@@ -195,7 +195,7 @@
     // this will be a subset if the font has more than 255 glyphs.
     uint16_t fFirstGlyphID;
     uint16_t fLastGlyphID;
-    SkAutoTUnref<SkAdvancedTypefaceMetrics> fFontInfo;
+    SkAutoTUnref<const SkAdvancedTypefaceMetrics> fFontInfo;
     SkTDArray<SkPDFObject*> fResources;
     SkAutoTUnref<SkPDFDict> fDescriptor;
 
diff --git a/src/pdf/SkPDFFontImpl.h b/src/pdf/SkPDFFontImpl.h
index 4b49683..842e1c9 100644
--- a/src/pdf/SkPDFFontImpl.h
+++ b/src/pdf/SkPDFFontImpl.h
@@ -29,7 +29,7 @@
     typedef SkPDFDict INHERITED;
 #endif
 
-    SkPDFType0Font(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface);
+    SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, SkTypeface* typeface);
 
     bool populate(const SkPDFGlyphSet* subset);
 };
@@ -42,7 +42,7 @@
 private:
     friend class SkPDFType0Font;  // to access the constructor
 
-    SkPDFCIDFont(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
+    SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
                  const SkPDFGlyphSet* subset);
 
     bool populate(const SkPDFGlyphSet* subset);
@@ -58,7 +58,7 @@
 private:
     friend class SkPDFFont;  // to access the constructor
 
-    SkPDFType1Font(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
+    SkPDFType1Font(const SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
                    uint16_t glyphID, SkPDFDict* relatedFontDescriptor);
 
     bool populate(int16_t glyphID);
@@ -75,9 +75,10 @@
 private:
     friend class SkPDFFont;  // to access the constructor
 
-    SkPDFType3Font(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface, uint16_t glyphID);
+    SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
+                   SkTypeface* typeface, uint16_t glyphID);
 
-    bool populate(int16_t glyphID);
+    bool populate(uint16_t glyphID);
 };
 
 #endif
diff --git a/src/pdf/SkPDFGraphicState.cpp b/src/pdf/SkPDFGraphicState.cpp
index 1b49534..7664ed6 100644
--- a/src/pdf/SkPDFGraphicState.cpp
+++ b/src/pdf/SkPDFGraphicState.cpp
@@ -5,10 +5,10 @@
  * found in the LICENSE file.
  */
 
+#include "SkData.h"
 #include "SkPDFFormXObject.h"
 #include "SkPDFGraphicState.h"
 #include "SkPDFUtils.h"
-#include "SkStream.h"
 #include "SkTypes.h"
 
 static const char* blend_mode_from_xfermode(SkXfermode::Mode mode) {
@@ -88,9 +88,9 @@
     return gCanonicalPaints;
 }
 
+SK_DECLARE_STATIC_MUTEX(gCanonicalPaintsMutex);
 // static
 SkBaseMutex& SkPDFGraphicState::CanonicalPaintsMutex() {
-    SK_DECLARE_STATIC_MUTEX(gCanonicalPaintsMutex);
     return gCanonicalPaintsMutex;
 }
 
@@ -121,8 +121,9 @@
         domainAndRange->appendInt(1);
 
         static const char psInvert[] = "{1 exch sub}";
-        SkAutoTUnref<SkMemoryStream> psInvertStream(
-            new SkMemoryStream(&psInvert, strlen(psInvert), true));
+        // Do not copy the trailing '\0' into the SkData.
+        SkAutoTUnref<SkData> psInvertStream(
+                SkData::NewWithoutCopy(psInvert, strlen(psInvert)));
 
         invertFunction = new SkPDFStream(psInvertStream.get());
         invertFunction->insertInt("FunctionType", 4);
diff --git a/src/pdf/SkPDFImage.cpp b/src/pdf/SkPDFImage.cpp
index 77fd84e..0c9b741 100644
--- a/src/pdf/SkPDFImage.cpp
+++ b/src/pdf/SkPDFImage.cpp
@@ -13,6 +13,7 @@
 #include "SkData.h"
 #include "SkFlate.h"
 #include "SkPDFCatalog.h"
+#include "SkPixelRef.h"
 #include "SkRect.h"
 #include "SkStream.h"
 #include "SkString.h"
@@ -377,8 +378,8 @@
     outBitmap.allocPixels(bitmap.info().makeWH(srcRect.width(), srcRect.height()));
     int dstRow = 0;
 
-    outBitmap.lockPixels();
-    bitmap.lockPixels();
+    SkAutoLockPixels outBitmapPixelLock(outBitmap);
+    SkAutoLockPixels bitmapPixelLock(bitmap);
     switch (bitmap.colorType()) {
         case kARGB_4444_SkColorType: {
             for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
@@ -428,8 +429,6 @@
         default:
             SkASSERT(false);
     }
-    bitmap.unlockPixels();
-    outBitmap.unlockPixels();
 
     outBitmap.setImmutable();
 
@@ -512,7 +511,7 @@
     }
 
     if (stream != NULL) {
-        setData(stream);
+        this->setData(stream);
         fStreamValid = true;
     } else {
         fStreamValid = false;
@@ -598,13 +597,11 @@
             SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset));
             if (data.get() && data->size() < get_uncompressed_size(fBitmap,
                                                                    fSrcRect)) {
-                SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream,
-                                                         (data)));
-                setData(stream.get());
+                this->setData(data.get());
 
                 insertName("Filter", "DCTDecode");
                 insertInt("ColorTransform", kNoColorTransform);
-                insertInt("Length", getData()->getLength());
+                insertInt("Length", this->dataSize());
                 setState(kCompressed_State);
                 return true;
             }
@@ -613,7 +610,7 @@
         if (!fStreamValid) {
             SkAutoTUnref<SkStream> stream(
                     extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL));
-            setData(stream);
+            this->setData(stream);
             fStreamValid = true;
         }
         return INHERITED::populate(catalog);
@@ -631,3 +628,91 @@
     }
     return true;
 }
+
+namespace {
+/**
+ *  This PDFObject assumes that its constructor was handed
+ *  Jpeg-encoded data that can be directly embedded into a PDF.
+ */
+class PDFJPEGImage : public SkPDFObject {
+    SkAutoTUnref<SkData> fData;
+    int fWidth;
+    int fHeight;
+public:
+    PDFJPEGImage(SkData* data, int width, int height)
+        : fData(SkRef(data)), fWidth(width), fHeight(height) {}
+    virtual void getResources(const SkTSet<SkPDFObject*>&,
+                              SkTSet<SkPDFObject*>*) SK_OVERRIDE {}
+    virtual void emitObject(
+            SkWStream* stream,
+            SkPDFCatalog* catalog, bool indirect) SK_OVERRIDE {
+        if (indirect) {
+            this->emitIndirectObject(stream, catalog);
+            return;
+        }
+        SkASSERT(fData.get());
+        const char kPrefaceFormat[] =
+            "<<"
+            "/Type /XObject\n"
+            "/Subtype /Image\n"
+            "/Width %d\n"
+            "/Height %d\n"
+            "/ColorSpace /DeviceRGB\n"
+            "/BitsPerComponent 8\n"
+            "/Filter /DCTDecode\n"
+            "/ColorTransform 0\n"
+            "/Length " SK_SIZE_T_SPECIFIER "\n"
+            ">> stream\n";
+        SkString preface(
+                SkStringPrintf(kPrefaceFormat, fWidth, fHeight, fData->size()));
+        const char kPostface[] = "\nendstream";
+        stream->write(preface.c_str(), preface.size());
+        stream->write(fData->data(), fData->size());
+        stream->write(kPostface, sizeof(kPostface));
+    }
+};
+
+/**
+ *  If the bitmap is not subsetted, return its encoded data, if
+ *  availible.
+ */
+static inline SkData* ref_encoded_data(const SkBitmap& bm) {
+    if ((NULL == bm.pixelRef())
+        || !bm.pixelRefOrigin().isZero()
+        || (bm.info().dimensions() != bm.pixelRef()->info().dimensions())) {
+        return NULL;
+    }
+    return bm.pixelRef()->refEncodedData();
+}
+
+/*
+ *  This functions may give false negatives but no false positives.
+ */
+static bool is_jfif_jpeg(SkData* data) {
+    if (!data || (data->size() < 11)) {
+        return false;
+    }
+    const uint8_t bytesZeroToThree[] = {0xFF, 0xD8, 0xFF, 0xE0};
+    const uint8_t bytesSixToTen[] = {'J', 'F', 'I', 'F', 0};
+    // 0   1   2   3   4   5   6   7   8   9   10
+    // FF  D8  FF  E0  ??  ??  'J' 'F' 'I' 'F' 00 ...
+    return ((0 == memcmp(data->bytes(), bytesZeroToThree,
+                         sizeof(bytesZeroToThree)))
+            && (0 == memcmp(data->bytes() + 6, bytesSixToTen,
+                            sizeof(bytesSixToTen))));
+}
+}  // namespace
+
+SkPDFObject* SkPDFCreateImageObject(
+        const SkBitmap& bitmap,
+        const SkIRect& subset,
+        SkPicture::EncodeBitmap encoder) {
+    if (SkIRect::MakeWH(bitmap.width(), bitmap.height()) == subset) {
+        SkAutoTUnref<SkData> encodedData(ref_encoded_data(bitmap));
+        if (is_jfif_jpeg(encodedData)) {
+            return SkNEW_ARGS(PDFJPEGImage,
+                              (encodedData, bitmap.width(), bitmap.height()));
+        }
+    }
+    return SkPDFImage::CreateImage(bitmap, subset, encoder);
+}
diff --git a/src/pdf/SkPDFImage.h b/src/pdf/SkPDFImage.h
index 10f8be6..5c026da 100644
--- a/src/pdf/SkPDFImage.h
+++ b/src/pdf/SkPDFImage.h
@@ -17,9 +17,20 @@
 #include "SkRefCnt.h"
 
 class SkBitmap;
+class SkData;
 class SkPDFCatalog;
 struct SkIRect;
 
+/**
+ *  Return the mose efficient availible encoding of the given bitmap.
+ *
+ *  If the bitmap has encoded JPEG data and that data can be embedded
+ *  into the PDF output stream directly, use that.  Otherwise, fall
+ *  back on SkPDFImage::CreateImage.
+ */
+SkPDFObject* SkPDFCreateImageObject(
+        const SkBitmap&, const SkIRect& subset, SkPicture::EncodeBitmap);
+
 /** \class SkPDFImage
 
     An image XObject.
diff --git a/src/pdf/SkPDFPage.cpp b/src/pdf/SkPDFPage.cpp
index 8961d2f..cfb6790 100644
--- a/src/pdf/SkPDFPage.cpp
+++ b/src/pdf/SkPDFPage.cpp
@@ -7,11 +7,11 @@
  */
 
 
+#include "SkData.h"
 #include "SkPDFCatalog.h"
 #include "SkPDFDevice.h"
 #include "SkPDFPage.h"
 #include "SkPDFResourceDict.h"
-#include "SkStream.h"
 
 SkPDFPage::SkPDFPage(SkPDFDevice* content)
     : SkPDFDict("Page"),
@@ -36,7 +36,7 @@
             }
         }
 
-        SkAutoTUnref<SkStream> content(fDevice->content());
+        SkAutoTUnref<SkData> content(fDevice->copyContentToData());
         fContentStream.reset(new SkPDFStream(content.get()));
         insert("Contents", new SkPDFObjRef(fContentStream.get()))->unref();
     }
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index 62adf58..d9b701c 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -659,22 +659,20 @@
 
 // static
 SkTDArray<SkPDFShader::ShaderCanonicalEntry>& SkPDFShader::CanonicalShaders() {
-    // This initialization is only thread safe with gcc.
+    SkPDFShader::CanonicalShadersMutex().assertHeld();
     static SkTDArray<ShaderCanonicalEntry> gCanonicalShaders;
     return gCanonicalShaders;
 }
 
+SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex);
 // static
 SkBaseMutex& SkPDFShader::CanonicalShadersMutex() {
-    // This initialization is only thread safe with gcc or when
-    // POD-style mutex initialization is used.
-    SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex);
     return gCanonicalShadersMutex;
 }
 
 // static
 SkPDFObject* SkPDFFunctionShader::RangeObject() {
-    // This initialization is only thread safe with gcc.
+    SkPDFShader::CanonicalShadersMutex().assertHeld();
     static SkPDFArray* range = NULL;
     // This method is only used with CanonicalShadersMutex, so it's safe to
     // populate domain.
@@ -1162,10 +1160,8 @@
     fState.get()->fImage.unlockPixels();
 }
 
-SkPDFStream* SkPDFFunctionShader::makePSFunction(const SkString& psCode,
-                                                 SkPDFArray* domain) {
-    SkAutoDataUnref funcData(SkData::NewWithCopy(psCode.c_str(),
-                                                 psCode.size()));
+SkPDFStream* SkPDFFunctionShader::makePSFunction(const SkString& psCode, SkPDFArray* domain) {
+    SkAutoDataUnref funcData(SkData::NewWithCopy(psCode.c_str(), psCode.size()));
     SkPDFStream* result = new SkPDFStream(funcData.get());
     result->insertInt("FunctionType", 4);
     result->insert("Domain", domain);
@@ -1173,14 +1169,12 @@
     return result;
 }
 
-SkPDFShader::ShaderCanonicalEntry::ShaderCanonicalEntry(SkPDFObject* pdfShader,
-                                                        const State* state)
-    : fPDFShader(pdfShader),
-      fState(state) {
-}
+SkPDFShader::ShaderCanonicalEntry::ShaderCanonicalEntry(SkPDFObject* pdfShader, const State* state)
+    : fPDFShader(pdfShader)
+    , fState(state)
+{}
 
-bool SkPDFShader::ShaderCanonicalEntry::operator==(
-        const ShaderCanonicalEntry& b) const {
+bool SkPDFShader::ShaderCanonicalEntry::operator==(const ShaderCanonicalEntry& b) const {
     return fPDFShader == b.fPDFShader ||
            (fState != NULL && b.fState != NULL && *fState == *b.fState);
 }
diff --git a/src/pdf/SkPDFStream.cpp b/src/pdf/SkPDFStream.cpp
index e570976..c310998 100644
--- a/src/pdf/SkPDFStream.cpp
+++ b/src/pdf/SkPDFStream.cpp
@@ -12,6 +12,7 @@
 #include "SkPDFCatalog.h"
 #include "SkPDFStream.h"
 #include "SkStream.h"
+#include "SkStreamPriv.h"
 
 static bool skip_compression(SkPDFCatalog* catalog) {
     return SkToBool(catalog->getDocumentFlags() &
@@ -19,32 +20,26 @@
 }
 
 SkPDFStream::SkPDFStream(SkStream* stream) : fState(kUnused_State) {
-    setData(stream);
+    this->setData(stream);
 }
 
 SkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) {
-    setData(data);
+    this->setData(data);
 }
 
 SkPDFStream::SkPDFStream(const SkPDFStream& pdfStream)
         : SkPDFDict(),
           fState(kUnused_State) {
-    setData(pdfStream.fData.get());
+    this->setData(pdfStream.fDataStream.get());
     bool removeLength = true;
     // Don't uncompress an already compressed stream, but we could.
     if (pdfStream.fState == kCompressed_State) {
         fState = kCompressed_State;
         removeLength = false;
     }
-    SkPDFDict::Iter dict(pdfStream);
-    SkPDFName* key;
-    SkPDFObject* value;
-    SkPDFName lengthName("Length");
-    for (key = dict.next(&value); key != NULL; key = dict.next(&value)) {
-        if (removeLength && *key == lengthName) {
-            continue;
-        }
-        this->insert(key, value);
+    this->mergeFrom(pdfStream);
+    if (removeLength) {
+        this->remove("Length");
     }
 }
 
@@ -55,14 +50,15 @@
     if (indirect) {
         return emitIndirectObject(stream, catalog);
     }
+    SkAutoMutexAcquire lock(fMutex);  // multiple threads could be calling emit
     if (!this->populate(catalog)) {
         return fSubstitute->emitObject(stream, catalog, indirect);
     }
 
     this->INHERITED::emitObject(stream, catalog, false);
     stream->writeText(" stream\n");
-    stream->writeStream(fData.get(), fData->getLength());
-    fData->rewind();
+    stream->writeStream(fDataStream.get(), fDataStream->getLength());
+    SkAssertResult(fDataStream->rewind());
     stream->writeText("\nendstream");
 }
 
@@ -70,30 +66,43 @@
     if (indirect) {
         return getIndirectOutputSize(catalog);
     }
+    SkAutoMutexAcquire lock(fMutex);  // multiple threads could be calling emit
     if (!this->populate(catalog)) {
         return fSubstitute->getOutputSize(catalog, indirect);
     }
 
     return this->INHERITED::getOutputSize(catalog, false) +
-        strlen(" stream\n\nendstream") + fData->getLength();
+        strlen(" stream\n\nendstream") + this->dataSize();
 }
 
 SkPDFStream::SkPDFStream() : fState(kUnused_State) {}
 
 void SkPDFStream::setData(SkData* data) {
-    SkMemoryStream* stream = new SkMemoryStream;
-    stream->setData(data);
-    fData.reset(stream);  // Transfer ownership.
+    fMemoryStream.setData(data);
+    if (&fMemoryStream != fDataStream.get()) {
+        fDataStream.reset(SkRef(&fMemoryStream));
+    }
 }
 
 void SkPDFStream::setData(SkStream* stream) {
     // Code assumes that the stream starts at the beginning and is rewindable.
-    if (stream) {
-        SkASSERT(stream->getPosition() == 0);
-        SkASSERT(stream->rewind());
+    if (&fMemoryStream == fDataStream.get()) {
+        SkASSERT(&fMemoryStream != stream);
+        fMemoryStream.setData(NULL);
     }
-    fData.reset(stream);
-    SkSafeRef(stream);
+    SkASSERT(0 == fMemoryStream.getLength());
+    if (stream) {
+        // SkStreamRewindableFromSkStream will try stream->duplicate().
+        fDataStream.reset(SkStreamRewindableFromSkStream(stream));
+        SkASSERT(fDataStream.get());
+    } else {
+        fDataStream.reset(SkRef(&fMemoryStream));
+    }
+}
+
+size_t SkPDFStream::dataSize() const {
+    SkASSERT(fDataStream->hasLength());
+    return fDataStream->getLength();
 }
 
 bool SkPDFStream::populate(SkPDFCatalog* catalog) {
@@ -101,18 +110,20 @@
         if (!skip_compression(catalog) && SkFlate::HaveFlate()) {
             SkDynamicMemoryWStream compressedData;
 
-            SkAssertResult(SkFlate::Deflate(fData.get(), &compressedData));
-            if (compressedData.getOffset() < fData->getLength()) {
-                SkMemoryStream* stream = new SkMemoryStream;
-                stream->setData(compressedData.copyToData())->unref();
-                fData.reset(stream);  // Transfer ownership.
+            SkAssertResult(
+                    SkFlate::Deflate(fDataStream.get(), &compressedData));
+            SkAssertResult(fDataStream->rewind());
+            if (compressedData.getOffset() < this->dataSize()) {
+                SkAutoTUnref<SkStream> compressed(
+                        compressedData.detachAsStream());
+                this->setData(compressed.get());
                 insertName("Filter", "FlateDecode");
             }
             fState = kCompressed_State;
         } else {
             fState = kNoCompression_State;
         }
-        insertInt("Length", fData->getLength());
+        insertInt("Length", this->dataSize());
     } else if (fState == kNoCompression_State && !skip_compression(catalog) &&
                SkFlate::HaveFlate()) {
         if (!fSubstitute.get()) {
diff --git a/src/pdf/SkPDFStream.h b/src/pdf/SkPDFStream.h
index 6371bc1..f908fbf 100644
--- a/src/pdf/SkPDFStream.h
+++ b/src/pdf/SkPDFStream.h
@@ -21,27 +21,26 @@
 
     A stream object in a PDF.  Note, all streams must be indirect objects (via
     SkObjRef).
-    TODO(vandebo): SkStream should be replaced by SkStreamRewindable when that
-    is feasible.
 */
 class SkPDFStream : public SkPDFDict {
     SK_DECLARE_INST_COUNT(SkPDFStream)
 public:
     /** Create a PDF stream. A Length entry is automatically added to the
-     *  stream dictionary. The stream may be retained (stream->ref() may be
-     *  called) so its contents must not be changed after calling this.
-     *  @param data  The data part of the stream.
+     *  stream dictionary.
+     *  @param data   The data part of the stream.  Will be ref()ed.
      */
     explicit SkPDFStream(SkData* data);
-    /** Deprecated constructor. */
-    explicit SkPDFStream(SkStream* stream);
-    /** Create a PDF stream with the same content and dictionary entries
-     *  as the passed one.
+
+    /** Create a PDF stream. A Length entry is automatically added to the
+     *  stream dictionary.
+     *  @param stream The data part of the stream.  Will be duplicate()d.
      */
-    explicit SkPDFStream(const SkPDFStream& pdfStream);
+    explicit SkPDFStream(SkStream* stream);
+
     virtual ~SkPDFStream();
 
-    // The SkPDFObject interface.
+    // The SkPDFObject interface.  These two methods use a mutex to
+    // allow multiple threads to call at the same time.
     virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                             bool indirect);
     virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
@@ -54,6 +53,11 @@
         kCompressed_State,     //!< The stream's already been compressed.
     };
 
+    /** Create a PDF stream with the same content and dictionary entries
+     *  as the passed one.
+     */
+    explicit SkPDFStream(const SkPDFStream& pdfStream);
+
     /* Create a PDF stream with no data.  The setData method must be called to
      * set the data.
      */
@@ -67,22 +71,20 @@
         fSubstitute.reset(stream);
     }
 
-    SkPDFStream* getSubstitute() {
+    SkPDFStream* getSubstitute() const {
         return fSubstitute.get();
     }
 
     void setData(SkData* data);
     void setData(SkStream* stream);
 
-    SkStream* getData() {
-        return fData.get();
-    }
+    size_t dataSize() const;
 
     void setState(State state) {
         fState = state;
     }
 
-    State getState() {
+    State getState() const {
         return fState;
     }
 
@@ -90,8 +92,13 @@
     // Indicates what form (or if) the stream has been requested.
     State fState;
 
-    // TODO(vandebo): Use SkData (after removing deprecated constructor).
-    SkAutoTUnref<SkStream> fData;
+    // Mutex guards fState, fDataStream, and fSubstitute in public interface.
+    SkMutex fMutex;
+
+    SkMemoryStream fMemoryStream;  // Used by fDataStream when
+                                   // fDataStream needs to be backed
+                                   // by SkData.
+    SkAutoTUnref<SkStreamRewindable> fDataStream;
     SkAutoTUnref<SkPDFStream> fSubstitute;
 
     typedef SkPDFDict INHERITED;
diff --git a/src/pdf/SkPDFTypes.cpp b/src/pdf/SkPDFTypes.cpp
index e3cc90c..7b79e41 100644
--- a/src/pdf/SkPDFTypes.cpp
+++ b/src/pdf/SkPDFTypes.cpp
@@ -396,14 +396,26 @@
     clear();
 }
 
+int SkPDFDict::size() const {
+    SkAutoMutexAcquire lock(fMutex);
+    return fValue.count();
+}
+
+
 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect) {
     if (indirect) {
         return emitIndirectObject(stream, catalog);
     }
 
+    SkAutoMutexAcquire lock(fMutex); // If another thread triggers a
+                                     // resize while this thread is in
+                                     // the for-loop, we can be left
+                                     // with a bad fValue[i] reference.
     stream->writeText("<<");
     for (int i = 0; i < fValue.count(); i++) {
+        SkASSERT(fValue[i].key);
+        SkASSERT(fValue[i].value);
         fValue[i].key->emitObject(stream, catalog, false);
         stream->writeText(" ");
         fValue[i].value->emit(stream, catalog, false);
@@ -417,69 +429,84 @@
         return getIndirectOutputSize(catalog);
     }
 
+    SkAutoMutexAcquire lock(fMutex); // If another thread triggers a
+                                     // resize while this thread is in
+                                     // the for-loop, we can be left
+                                     // with a bad fValue[i] reference.
     size_t result = strlen("<<>>") + (fValue.count() * 2);
     for (int i = 0; i < fValue.count(); i++) {
+        SkASSERT(fValue[i].key);
+        SkASSERT(fValue[i].value);
         result += fValue[i].key->getOutputSize(catalog, false);
         result += fValue[i].value->getOutputSize(catalog, false);
     }
     return result;
 }
 
-SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) {
-    key->ref();
-    value->ref();
-    struct Rec* newEntry = fValue.append();
-    newEntry->key = key;
-    newEntry->value = value;
+SkPDFObject*  SkPDFDict::append(SkPDFName* key, SkPDFObject* value) {
+    SkASSERT(key);
+    SkASSERT(value);
+    SkAutoMutexAcquire lock(fMutex); // If the SkTDArray resizes while
+                                     // two threads access array, one
+                                     // is left with a bad pointer.
+    *(fValue.append()) = Rec(key, value);
     return value;
 }
 
+SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) {
+    return this->append(SkRef(key), SkRef(value));
+}
+
 SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) {
-    value->ref();
-    struct Rec* newEntry = fValue.append();
-    newEntry->key = new SkPDFName(key);
-    newEntry->value = value;
-    return value;
+    return this->append(new SkPDFName(key), SkRef(value));
 }
 
 void SkPDFDict::insertInt(const char key[], int32_t value) {
-    struct Rec* newEntry = fValue.append();
-    newEntry->key = new SkPDFName(key);
-    newEntry->value = new SkPDFInt(value);
+    (void)this->append(new SkPDFName(key), new SkPDFInt(value));
 }
 
 void SkPDFDict::insertScalar(const char key[], SkScalar value) {
-    struct Rec* newEntry = fValue.append();
-    newEntry->key = new SkPDFName(key);
-    newEntry->value = new SkPDFScalar(value);
+    (void)this->append(new SkPDFName(key), new SkPDFScalar(value));
 }
 
 void SkPDFDict::insertName(const char key[], const char name[]) {
-    struct Rec* newEntry = fValue.append();
-    newEntry->key = new SkPDFName(key);
-    newEntry->value = new SkPDFName(name);
+    (void)this->append(new SkPDFName(key), new SkPDFName(name));
 }
 
 void SkPDFDict::clear() {
+    SkAutoMutexAcquire lock(fMutex);
     for (int i = 0; i < fValue.count(); i++) {
+        SkASSERT(fValue[i].key);
+        SkASSERT(fValue[i].value);
         fValue[i].key->unref();
         fValue[i].value->unref();
     }
     fValue.reset();
 }
 
-SkPDFDict::Iter::Iter(const SkPDFDict& dict)
-    : fIter(dict.fValue.begin()),
-      fStop(dict.fValue.end()) {
+void SkPDFDict::remove(const char key[]) {
+    SkASSERT(key);
+    SkPDFName name(key);
+    SkAutoMutexAcquire lock(fMutex);
+    for (int i = 0; i < fValue.count(); i++) {
+        SkASSERT(fValue[i].key);
+        if (*(fValue[i].key) == name) {
+            fValue[i].key->unref();
+            SkASSERT(fValue[i].value);
+            fValue[i].value->unref();
+            fValue.removeShuffle(i);
+            return;
+        }
+    }
 }
 
-SkPDFName* SkPDFDict::Iter::next(SkPDFObject** value) {
-    if (fIter != fStop) {
-        const Rec* cur = fIter;
-        fIter++;
-        *value = cur->value;
-        return cur->key;
+void SkPDFDict::mergeFrom(const SkPDFDict& other) {
+    SkAutoMutexAcquire lockOther(other.fMutex);
+    SkTDArray<Rec> copy(other.fValue);
+    lockOther.release();  // Do not hold both mutexes at once.
+
+    SkAutoMutexAcquire lock(fMutex);
+    for (int i = 0; i < copy.count(); i++) {
+        *(fValue.append()) = Rec(SkRef(copy[i].key), SkRef(copy[i].value));
     }
-    *value = NULL;
-    return NULL;
 }
diff --git a/src/pdf/SkPDFTypes.h b/src/pdf/SkPDFTypes.h
index 1f06c4c..004c767 100644
--- a/src/pdf/SkPDFTypes.h
+++ b/src/pdf/SkPDFTypes.h
@@ -369,7 +369,7 @@
 
     /** The size of the dictionary.
      */
-    int size() { return fValue.count(); }
+    int size() const;
 
     /** Add the value to the dictionary with the given key.  Refs value.
      *  @param key   The key for this dictionary entry.
@@ -424,28 +424,30 @@
      */
     void clear();
 
+protected:
+    /** Use to remove a single key from the dictionary.
+     */
+    void remove(const char key[]);
+
+    /** Insert references to all of the key-value pairs from the other
+     *  dictionary into this one.
+     */
+    void mergeFrom(const SkPDFDict& other);
+
 private:
     struct Rec {
-      SkPDFName* key;
-      SkPDFObject* value;
+        SkPDFName* key;
+        SkPDFObject* value;
+        Rec(SkPDFName* k, SkPDFObject* v) : key(k), value(v) {}
     };
 
-public:
-    class Iter {
-    public:
-        explicit Iter(const SkPDFDict& dict);
-        SkPDFName* next(SkPDFObject** value);
-
-    private:
-        const Rec* fIter;
-        const Rec* fStop;
-    };
-
-private:
     static const int kMaxLen = 4095;
 
+    mutable SkMutex fMutex;  // protects modifications to fValue
     SkTDArray<struct Rec> fValue;
 
+    SkPDFObject* append(SkPDFName* key, SkPDFObject* value);
+
     typedef SkPDFObject INHERITED;
 };
 
diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h
index 58cafe8..121512d 100644
--- a/src/pipe/SkGPipePriv.h
+++ b/src/pipe/SkGPipePriv.h
@@ -48,6 +48,7 @@
     kDrawDRRect_DrawOp,
     kDrawOval_DrawOp,
     kDrawPaint_DrawOp,
+    kDrawPatch_DrawOp,
     kDrawPath_DrawOp,
     kDrawPicture_DrawOp,
     kDrawPoints_DrawOp,
@@ -57,6 +58,7 @@
     kDrawRRect_DrawOp,
     kDrawSprite_DrawOp,
     kDrawText_DrawOp,
+    kDrawTextBlob_DrawOp,
     kDrawTextOnPath_DrawOp,
     kDrawVertices_DrawOp,
     kRestore_DrawOp,
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp
index 41c417f..8cb0e34 100644
--- a/src/pipe/SkGPipeRead.cpp
+++ b/src/pipe/SkGPipeRead.cpp
@@ -21,10 +21,12 @@
 #include "SkImageFilter.h"
 #include "SkMaskFilter.h"
 #include "SkReadBuffer.h"
+#include "SkPatchUtils.h"
 #include "SkPathEffect.h"
 #include "SkRasterizer.h"
 #include "SkRRect.h"
 #include "SkShader.h"
+#include "SkTextBlob.h"
 #include "SkTypeface.h"
 #include "SkXfermode.h"
 
@@ -192,8 +194,8 @@
         *fTypefaces.append() = SkTypeface::Deserialize(&stream);
     }
 
-    void setTypeface(SkPaint* paint, unsigned id) {
-        paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
+    SkTypeface* getTypeface(unsigned id) const {
+        return id ? fTypefaces[id - 1] : NULL;
     }
 
 private:
@@ -317,7 +319,7 @@
 
 static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
                     SkGPipeState* state) {
-    canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
+    canvas->save();
 }
 
 static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@@ -404,6 +406,34 @@
     }
 }
 
+static void drawPatch_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
+                         SkGPipeState* state) {
+    
+    unsigned flags = DrawOp_unpackFlags(op32);
+    
+    const SkPoint* cubics = skip<SkPoint>(reader, SkPatchUtils::kNumCtrlPts);
+    
+    const SkColor* colors = NULL;
+    if (flags & kDrawVertices_HasColors_DrawOpFlag) {
+        colors = skip<SkColor>(reader, SkPatchUtils::kNumCorners);
+    }
+    const SkPoint* texCoords = NULL;
+    if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
+        texCoords = skip<SkPoint>(reader, SkPatchUtils::kNumCorners);
+    }
+    SkAutoTUnref<SkXfermode> xfer;
+    if (flags & kDrawVertices_HasXfermode_DrawOpFlag) {
+        int mode = reader->readInt();
+        if (mode < 0 || mode > SkXfermode::kLastMode) {
+            mode = SkXfermode::kModulate_Mode;
+        }
+        xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode));
+    }
+    if (state->shouldDraw()) {
+        canvas->drawPatch(cubics, colors, texCoords, xfer, state->paint());
+    }
+}
+
 static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
                         SkGPipeState* state) {
     SkPath path;
@@ -641,6 +671,33 @@
     UNIMPLEMENTED
 }
 
+static void drawTextBlob_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
+                            SkGPipeState* state) {
+    SkScalar x = reader->readScalar();
+    SkScalar y = reader->readScalar();
+
+    int typefaceCount = reader->readU32();
+    SkAutoSTMalloc<16, SkTypeface*> typefaceArray(typefaceCount);
+    if (state->getFlags() & SkGPipeWriter::kCrossProcess_Flag) {
+        for (int i = 0; i < typefaceCount; ++i) {
+            typefaceArray[i] = state->getTypeface(reader->readU32());
+        }
+    } else {
+        reader->read(typefaceArray.get(), typefaceCount * sizeof(SkTypeface*));
+    }
+
+    size_t blobSize = reader->readU32();
+    const void* data = reader->skip(SkAlign4(blobSize));
+
+    if (state->shouldDraw()) {
+        SkReadBuffer blobBuffer(data, blobSize);
+        blobBuffer.setTypefaceArray(typefaceArray.get(), typefaceCount);
+        SkAutoTUnref<const SkTextBlob> blob(SkTextBlob::CreateFromBuffer(blobBuffer));
+        SkASSERT(blob.get());
+
+        canvas->drawTextBlob(blob, x, y, state->paint());
+    }
+}
 ///////////////////////////////////////////////////////////////////////////////
 
 static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
@@ -685,7 +742,8 @@
             case kTypeface_PaintOp:
                 SkASSERT(SkToBool(state->getFlags() &
                                   SkGPipeWriter::kCrossProcess_Flag));
-                state->setTypeface(p, data); break;
+                p->setTypeface(state->getTypeface(data));
+                break;
             default: SkDEBUGFAIL("bad paintop"); return;
         }
         SkASSERT(reader->offset() <= stop);
@@ -775,6 +833,7 @@
     drawDRRect_rp,
     drawOval_rp,
     drawPaint_rp,
+    drawPatch_rp,
     drawPath_rp,
     drawPicture_rp,
     drawPoints_rp,
@@ -784,6 +843,7 @@
     drawRRect_rp,
     drawSprite_rp,
     drawText_rp,
+    drawTextBlob_rp,
     drawTextOnPath_rp,
     drawVertices_rp,
     restore_rp,
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index a3c3864..41b0234 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -19,12 +19,15 @@
 #include "SkMaskFilter.h"
 #include "SkWriteBuffer.h"
 #include "SkPaint.h"
+#include "SkPatchUtils.h"
 #include "SkPathEffect.h"
 #include "SkPictureFlat.h"
+#include "SkPtrRecorder.h"
 #include "SkRasterizer.h"
 #include "SkRRect.h"
 #include "SkShader.h"
 #include "SkStream.h"
+#include "SkTextBlob.h"
 #include "SkTSearch.h"
 #include "SkTypeface.h"
 #include "SkWriter32.h"
@@ -33,7 +36,7 @@
     kSizeOfFlatRRect = sizeof(SkRect) + 4 * sizeof(SkVector)
 };
 
-static bool isCrossProcess(uint32_t flags) {
+static bool is_cross_process(uint32_t flags) {
     return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag);
 }
 
@@ -266,7 +269,7 @@
     bool shuttleBitmap(const SkBitmap&, int32_t slot);
 
 protected:
-    virtual void willSave(SaveFlags) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
     virtual void willRestore() SK_OVERRIDE;
 
@@ -282,13 +285,17 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
-
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
+    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                             const SkPoint texCoords[4], SkXfermode* xmode,
+                             const SkPaint& paint) SK_OVERRIDE;
     virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
 
-    virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
 private:
     void recordTranslate(const SkMatrix&);
@@ -332,6 +339,10 @@
         }
     }
 
+    typedef SkAutoSTMalloc<128, uint8_t> TypefaceBuffer;
+    size_t getInProcessTypefaces(const SkRefCntSet& typefaceSet, TypefaceBuffer*);
+    size_t getCrossProcessTypefaces(const SkRefCntSet& typefaceSet, TypefaceBuffer*);
+
     // Should be called after any calls to an SkFlatDictionary::findAndReplace
     // if a new SkFlatData was added when in cross process mode
     void flattenFactoryNames();
@@ -405,7 +416,7 @@
     fBitmapHeap->endAddingOwnersDeferral(added);
     int index = flat->index();
     if (added) {
-        if (isCrossProcess(fFlags)) {
+        if (is_cross_process(fFlags)) {
             this->flattenFactoryNames();
         }
         size_t flatSize = flat->flatSize();
@@ -430,10 +441,10 @@
                              SkWriter32* writer, uint32_t flags,
                              uint32_t width, uint32_t height)
     : SkCanvas(width, height)
-    , fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL)
+    , fFactorySet(is_cross_process(flags) ? SkNEW(SkNamedFactorySet) : NULL)
     , fWriter(*writer)
     , fFlags(flags)
-    , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, isCrossProcess(flags))
+    , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, is_cross_process(flags))
     , fFlatDictionary(&fFlattenableHeap)
 {
     fController = controller;
@@ -475,12 +486,14 @@
     }
 
     needed += 4;  // size of DrawOp atom
-    needed = SkTMax<size_t>(MIN_BLOCK_SIZE, needed);
     needed = SkAlign4(needed);
     if (fWriter.bytesWritten() + needed > fBlockSize) {
-        // Before we wipe out any data that has already been written, read it
-        // out.
+        // Before we wipe out any data that has already been written, read it out.
         this->doNotify();
+
+        // If we're going to allocate a new block, allocate enough to make it worthwhile.
+        needed = SkTMax<size_t>(MIN_BLOCK_SIZE, needed);
+
         void* block = fController->requestBlock(needed, &fBlockSize);
         if (NULL == block) {
             // Do not notify the readers, which would call this function again.
@@ -515,13 +528,13 @@
 #define NOTIFY_SETUP(canvas)    \
     AutoPipeNotify apn(canvas)
 
-void SkGPipeCanvas::willSave(SaveFlags flags) {
+void SkGPipeCanvas::willSave() {
     NOTIFY_SETUP(this);
     if (this->needOpBytes()) {
-        this->writeOp(kSave_DrawOp, 0, flags);
+        this->writeOp(kSave_DrawOp);
     }
 
-    this->INHERITED::willSave(flags);
+    this->INHERITED::willSave();
 }
 
 SkCanvas::SaveLayerStrategy SkGPipeCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
@@ -930,9 +943,87 @@
     }
 }
 
-void SkGPipeCanvas::onDrawPicture(const SkPicture* picture) {
+size_t SkGPipeCanvas::getInProcessTypefaces(const SkRefCntSet& typefaceSet,
+                                            TypefaceBuffer* buffer) {
+    // When in-process, we simply write out the typeface pointers.
+    size_t size = typefaceSet.count() * sizeof(SkTypeface*);
+    buffer->reset(size);
+    typefaceSet.copyToArray(reinterpret_cast<SkRefCnt**>(buffer->get()));
+
+    return size;
+}
+
+size_t SkGPipeCanvas::getCrossProcessTypefaces(const SkRefCntSet& typefaceSet,
+                                               TypefaceBuffer* buffer) {
+    // For cross-process we use typeface IDs.
+    size_t size = typefaceSet.count() * sizeof(uint32_t);
+    buffer->reset(size);
+
+    uint32_t* idBuffer = reinterpret_cast<uint32_t*>(buffer->get());
+    SkRefCntSet::Iter iter(typefaceSet);
+    int i = 0;
+
+    for (void* setPtr = iter.next(); setPtr; setPtr = iter.next()) {
+        idBuffer[i++] = this->getTypefaceID(reinterpret_cast<SkTypeface*>(setPtr));
+    }
+
+    SkASSERT(i == typefaceSet.count());
+
+    return size;
+}
+
+void SkGPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                   const SkPaint& paint) {
+    NOTIFY_SETUP(this);
+    this->writePaint(paint);
+
+    // FIXME: this is inefficient but avoids duplicating the blob serialization logic.
+    SkRefCntSet typefaceSet;
+    SkWriteBuffer blobBuffer;
+    blobBuffer.setTypefaceRecorder(&typefaceSet);
+    blob->flatten(blobBuffer);
+
+    // Unlike most draw ops (which only use one paint/typeface), text blobs may reference
+    // an arbitrary number of typefaces. Since the one-paint-per-op model is not applicable,
+    // we need to serialize these explicitly.
+    TypefaceBuffer typefaceBuffer;
+    size_t typefaceSize = is_cross_process(fFlags)
+        ? this->getCrossProcessTypefaces(typefaceSet, &typefaceBuffer)
+        : this->getInProcessTypefaces(typefaceSet, &typefaceBuffer);
+
+    // blob byte count + typeface count + x + y + blob data + an index (cross-process)
+    // or pointer (in-process) for each typeface
+    size_t size = 2 * sizeof(uint32_t)
+                + 2 * sizeof(SkScalar)
+                + blobBuffer.bytesWritten()
+                + typefaceSize;
+
+    if (this->needOpBytes(size)) {
+        this->writeOp(kDrawTextBlob_DrawOp);
+        SkDEBUGCODE(size_t initialOffset = fWriter.bytesWritten();)
+
+        fWriter.writeScalar(x);
+        fWriter.writeScalar(y);
+
+        fWriter.write32(typefaceSet.count());
+        fWriter.write(typefaceBuffer.get(), typefaceSize);
+
+        fWriter.write32(SkToU32(blobBuffer.bytesWritten()));
+        uint32_t* pad = fWriter.reservePad(blobBuffer.bytesWritten());
+        blobBuffer.writeToMemory(pad);
+
+        SkASSERT(initialOffset + size == fWriter.bytesWritten());
+    }
+}
+
+void SkGPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                                  const SkPaint* paint) {
     // we want to playback the picture into individual draw calls
-    this->INHERITED::onDrawPicture(picture);
+    //
+    // todo: do we always have to unroll? If the pipe is not cross-process, seems like
+    // we could just ref the picture and move on...? <reed, scroggo>
+    //
+    this->INHERITED::onDrawPicture(picture, matrix, paint);
 }
 
 void SkGPipeCanvas::drawVertices(VertexMode vmode, int vertexCount,
@@ -995,6 +1086,51 @@
     }
 }
 
+void SkGPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                                const SkPoint texCoords[4], SkXfermode* xmode,
+                                const SkPaint& paint) {
+    NOTIFY_SETUP(this);
+    
+    size_t size = SkPatchUtils::kNumCtrlPts * sizeof(SkPoint);
+    unsigned flags = 0;
+    if (colors) {
+        flags |= kDrawVertices_HasColors_DrawOpFlag;
+        size += SkPatchUtils::kNumCorners * sizeof(SkColor);
+    }
+    if (texCoords) {
+        flags |= kDrawVertices_HasTexs_DrawOpFlag;
+        size += SkPatchUtils::kNumCorners * sizeof(SkPoint);
+    }
+    if (xmode) {
+        SkXfermode::Mode mode;
+        if (xmode->asMode(&mode) && SkXfermode::kModulate_Mode != mode) {
+            flags |= kDrawVertices_HasXfermode_DrawOpFlag;
+            size += sizeof(int32_t);
+        }
+    }
+    
+    this->writePaint(paint);
+    if (this->needOpBytes(size)) {
+        this->writeOp(kDrawPatch_DrawOp, flags, 0);
+        
+        fWriter.write(cubics, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
+        
+        if (colors) {
+            fWriter.write(colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
+        }
+        
+        if (texCoords) {
+            fWriter.write(texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint));
+        }
+        
+        if (flags & kDrawVertices_HasXfermode_DrawOpFlag) {
+            SkXfermode::Mode mode = SkXfermode::kModulate_Mode;
+            SkAssertResult(xmode->asMode(&mode));
+            fWriter.write32(mode);
+        }
+    }
+}
+
 void SkGPipeCanvas::drawData(const void* ptr, size_t size) {
     if (size && ptr) {
         NOTIFY_SETUP(this);
@@ -1119,7 +1255,7 @@
     }
 
     if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) {
-        if (isCrossProcess(fFlags)) {
+        if (is_cross_process(fFlags)) {
             uint32_t id = this->getTypefaceID(paint.getTypeface());
             *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id);
         } else if (this->needOpBytes(sizeof(void*))) {
diff --git a/src/ports/SkAtomics_sync.h b/src/ports/SkAtomics_sync.h
index b0d1752..9389c00 100644
--- a/src/ports/SkAtomics_sync.h
+++ b/src/ports/SkAtomics_sync.h
@@ -16,6 +16,18 @@
     return __sync_fetch_and_add(addr, 1);
 }
 
+static inline __attribute__((always_inline)) int64_t sk_atomic_inc(int64_t* addr) {
+#if defined(__mips__) && !defined(__LP64__) && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
+    /** Some versions of the GCC 32-bit MIPS toolchains (e.g. 4.8) for android are missing
+     * support for the __sync* functions that operate on 64-bit values. The workaround
+     * is to use __atomic* functions until we can move everything to <stdatomic.h>.
+     */
+    return __atomic_fetch_add(addr, 1, __ATOMIC_SEQ_CST);
+#else
+    return __sync_fetch_and_add(addr, 1);
+#endif
+}
+
 static inline __attribute__((always_inline)) int32_t sk_atomic_add(int32_t* addr, int32_t inc) {
     return __sync_fetch_and_add(addr, inc);
 }
diff --git a/src/ports/SkAtomics_win.h b/src/ports/SkAtomics_win.h
index 1692394..a1876d2 100644
--- a/src/ports/SkAtomics_win.h
+++ b/src/ports/SkAtomics_win.h
@@ -25,6 +25,11 @@
     return _InterlockedIncrement(reinterpret_cast<long*>(addr)) - 1;
 }
 
+static inline int64_t sk_atomic_inc(int64_t* addr) {
+    // InterlockedIncrement returns the new value, we want to return the old.
+    return InterlockedIncrement64(addr) - 1;
+}
+
 static inline int32_t sk_atomic_add(int32_t* addr, int32_t inc) {
     return _InterlockedExchangeAdd(reinterpret_cast<long*>(addr), static_cast<long>(inc));
 }
diff --git a/src/ports/SkBarriers_arm.h b/src/ports/SkBarriers_arm.h
index 9161cdd..386294e 100644
--- a/src/ports/SkBarriers_arm.h
+++ b/src/ports/SkBarriers_arm.h
@@ -18,6 +18,16 @@
 }
 
 template <typename T>
+T sk_consume_load(T* ptr) {
+    T val = *ptr;
+    // Unlike acquire, consume loads (data-dependent loads) are guaranteed not to reorder on ARM.
+    // No memory barrier is needed, so we just use a compiler barrier.
+    // C.f. http://preshing.com/20140709/the-purpose-of-memory_order_consume-in-cpp11/
+    sk_compiler_barrier();
+    return val;
+}
+
+template <typename T>
 void sk_release_store(T* ptr, T val) {
     __sync_synchronize();  // Issue a full barrier, which is an overkill release barrier.
     *ptr = val;
diff --git a/src/ports/SkBarriers_tsan.h b/src/ports/SkBarriers_tsan.h
index 6f27390..d72dbfd 100644
--- a/src/ports/SkBarriers_tsan.h
+++ b/src/ports/SkBarriers_tsan.h
@@ -17,6 +17,12 @@
 }
 
 template <typename T>
+T sk_consume_load(T* ptr) {
+    SkASSERT(__atomic_always_lock_free(sizeof(T), ptr));
+    return __atomic_load_n(ptr, __ATOMIC_CONSUME);
+}
+
+template <typename T>
 void sk_release_store(T* ptr, T val) {
     SkASSERT(__atomic_always_lock_free(sizeof(T), ptr));
     return __atomic_store_n(ptr, val, __ATOMIC_RELEASE);
diff --git a/src/ports/SkBarriers_x86.h b/src/ports/SkBarriers_x86.h
index fc57615..56e2658 100644
--- a/src/ports/SkBarriers_x86.h
+++ b/src/ports/SkBarriers_x86.h
@@ -24,6 +24,12 @@
 }
 
 template <typename T>
+T sk_consume_load(T* ptr) {
+    // On x86, consume is the same as acquire, i.e. a normal load.
+    return sk_acquire_load(ptr);
+}
+
+template <typename T>
 void sk_release_store(T* ptr, T val) {
     // On x86, all stores are release stores, so we only need a compiler barrier.
     sk_compiler_barrier();
diff --git a/src/ports/SkDebug_android.cpp b/src/ports/SkDebug_android.cpp
index 70029fb..b41abd3 100644
--- a/src/ports/SkDebug_android.cpp
+++ b/src/ports/SkDebug_android.cpp
@@ -22,15 +22,17 @@
 }
 
 void SkDebugf(const char format[], ...) {
-    va_list args;
-    va_start(args, format);
-    __android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, format, args);
+    va_list args1, args2;
+    va_start(args1, format);
+    va_copy(args2, args1);
+    __android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, format, args1);
 
     // Print debug output to stdout as well.  This is useful for command
     // line applications (e.g. skia_launcher)
     if (gSkDebugToStdOut) {
-        vprintf(format, args);
+        vprintf(format, args2);
     }
 
-    va_end(args);
+    va_end(args1);
+    va_end(args2);
 }
diff --git a/src/ports/SkFontConfigInterface_android.cpp b/src/ports/SkFontConfigInterface_android.cpp
deleted file mode 100644
index 20e6c5e..0000000
--- a/src/ports/SkFontConfigInterface_android.cpp
+++ /dev/null
@@ -1,915 +0,0 @@
-
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkFontConfigInterface.h"
-#include "SkTypeface_android.h"
-
-#include "SkFontConfigParser_android.h"
-#include "SkFontConfigTypeface.h"
-#include "SkFontMgr.h"
-#include "SkGlyphCache.h"
-#include "SkPaint.h"
-#include "SkString.h"
-#include "SkStream.h"
-#include "SkThread.h"
-#include "SkTypefaceCache.h"
-#include "SkTArray.h"
-#include "SkTDict.h"
-#include "SkTSearch.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#ifndef SK_DEBUG_FONTS
-    #define SK_DEBUG_FONTS 0
-#endif
-
-#if SK_DEBUG_FONTS
-    #define DEBUG_FONT(args) SkDebugf args
-#else
-    #define DEBUG_FONT(args)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
-// For test only.
-static const char* gTestMainConfigFile = NULL;
-static const char* gTestFallbackConfigFile = NULL;
-static const char* gTestFontFilePrefix = NULL;
-
-///////////////////////////////////////////////////////////////////////////////
-
-typedef int32_t FontRecID;
-#define INVALID_FONT_REC_ID -1
-
-typedef int32_t FamilyRecID;
-#define INVALID_FAMILY_REC_ID -1
-
-// used to record our notion of the pre-existing fonts
-struct FontRec {
-    SkRefPtr<SkTypeface> fTypeface;
-    SkString fFileName;
-    SkTypeface::Style fStyle;
-    bool fIsValid;
-    FamilyRecID fFamilyRecID;
-};
-
-struct FamilyRec {
-    FamilyRec() {
-        memset(fFontRecID, INVALID_FONT_REC_ID, sizeof(fFontRecID));
-    }
-
-    static const int FONT_STYLE_COUNT = 4;
-    FontRecID fFontRecID[FONT_STYLE_COUNT];
-    bool fIsFallbackFont;
-    SkString fFallbackName;
-    SkPaintOptionsAndroid fPaintOptions;
-};
-
-
-typedef SkTDArray<FamilyRecID> FallbackFontList;
-
-class SkFontConfigInterfaceAndroid : public SkFontConfigInterface {
-public:
-    SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*>& fontFamilies);
-    virtual ~SkFontConfigInterfaceAndroid();
-
-    virtual bool matchFamilyName(const char familyName[],
-                                 SkTypeface::Style requested,
-                                 FontIdentity* outFontIdentifier,
-                                 SkString* outFamilyName,
-                                 SkTypeface::Style* outStyle) SK_OVERRIDE;
-    virtual SkStream* openStream(const FontIdentity&) SK_OVERRIDE;
-
-    // new APIs
-    virtual SkDataTable* getFamilyNames() SK_OVERRIDE;
-    virtual bool matchFamilySet(const char inFamilyName[],
-                                SkString* outFamilyName,
-                                SkTArray<FontIdentity>*) SK_OVERRIDE;
-
-    /**
-     *  Get the family name of the font in the default fallback font list that
-     *  contains the specified chararacter. if no font is found, returns false.
-     */
-    bool getFallbackFamilyNameForChar(SkUnichar uni, const char* lang, SkString* name);
-    /**
-     *
-     */
-    SkTypeface* getTypefaceForChar(SkUnichar uni, SkTypeface::Style style,
-                                   SkPaintOptionsAndroid::FontVariant fontVariant);
-    SkTypeface* nextLogicalTypeface(SkFontID currFontID, SkFontID origFontID,
-                                    const SkPaintOptionsAndroid& options);
-    SkTypeface* getTypefaceForGlyphID(uint16_t glyphID, const SkTypeface* origTypeface,
-                                      const SkPaintOptionsAndroid& options,
-                                      int* lowerBounds, int* upperBounds);
-
-private:
-    void addFallbackFamily(FamilyRecID fontRecID);
-    SkTypeface* getTypefaceForFontRec(FontRecID fontRecID);
-    FallbackFontList* getCurrentLocaleFallbackFontList();
-    FallbackFontList* findFallbackFontList(const SkLanguage& lang, bool isOriginal = true);
-
-    SkTArray<FontRec> fFonts;
-    SkTArray<FamilyRec> fFontFamilies;
-    SkTDict<FamilyRecID> fFamilyNameDict;
-    FamilyRecID fDefaultFamilyRecID;
-
-    // (SkLanguage)<->(fallback chain index) translation
-    SkTDict<FallbackFontList*> fFallbackFontDict;
-    SkTDict<FallbackFontList*> fFallbackFontAliasDict;
-    FallbackFontList fDefaultFallbackList;
-
-    // fallback info for current locale
-    SkString fCachedLocale;
-    FallbackFontList* fLocaleFallbackFontList;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-static SkFontConfigInterfaceAndroid* getSingletonInterface() {
-    SK_DECLARE_STATIC_MUTEX(gMutex);
-    static SkFontConfigInterfaceAndroid* gFontConfigInterface;
-
-    SkAutoMutexAcquire ac(gMutex);
-    if (NULL == gFontConfigInterface) {
-        // load info from a configuration file that we can use to populate the
-        // system/fallback font structures
-        SkTDArray<FontFamily*> fontFamilies;
-        if (!gTestMainConfigFile) {
-            SkFontConfigParser::GetFontFamilies(fontFamilies);
-        } else {
-            SkFontConfigParser::GetTestFontFamilies(fontFamilies, gTestMainConfigFile,
-                                                    gTestFallbackConfigFile);
-        }
-
-        gFontConfigInterface = new SkFontConfigInterfaceAndroid(fontFamilies);
-
-        // cleanup the data we received from the parser
-        fontFamilies.deleteAll();
-    }
-    return gFontConfigInterface;
-}
-
-SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface() {
-    return getSingletonInterface();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-static bool has_font(const SkTArray<FontRec>& array, const SkString& filename) {
-    for (int i = 0; i < array.count(); i++) {
-        if (array[i].fFileName == filename) {
-            return true;
-        }
-    }
-    return false;
-}
-
-#ifndef SK_FONT_FILE_PREFIX
-    #define SK_FONT_FILE_PREFIX          "/fonts/"
-#endif
-
-static void get_path_for_sys_fonts(SkString* full, const SkString& name) {
-    if (gTestFontFilePrefix) {
-        full->set(gTestFontFilePrefix);
-    } else {
-        full->set(getenv("ANDROID_ROOT"));
-        full->append(SK_FONT_FILE_PREFIX);
-    }
-    full->append(name);
-}
-
-static void insert_into_name_dict(SkTDict<FamilyRecID>& familyNameDict,
-                                  const char* name, FamilyRecID familyRecID) {
-    SkAutoAsciiToLC tolc(name);
-    if (familyNameDict.find(tolc.lc())) {
-        SkDebugf("---- system font attempting to use a the same name [%s] for"
-                 "multiple families. skipping subsequent occurrences", tolc.lc());
-    } else {
-        familyNameDict.set(tolc.lc(), familyRecID);
-    }
-}
-
-// Defined in SkFontHost_FreeType.cpp
-bool find_name_and_attributes(SkStream* stream, SkString* name,
-                              SkTypeface::Style* style, bool* isFixedWidth);
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkFontConfigInterfaceAndroid::SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*>& fontFamilies) :
-        fFonts(fontFamilies.count()),
-        fFontFamilies(fontFamilies.count() / FamilyRec::FONT_STYLE_COUNT),
-        fFamilyNameDict(1024),
-        fDefaultFamilyRecID(INVALID_FAMILY_REC_ID),
-        fFallbackFontDict(128),
-        fFallbackFontAliasDict(128),
-        fLocaleFallbackFontList(NULL) {
-
-    for (int i = 0; i < fontFamilies.count(); ++i) {
-        FontFamily* family = fontFamilies[i];
-
-        // defer initializing the familyRec until we can be sure that at least
-        // one of it's children contains a valid font file
-        FamilyRec* familyRec = NULL;
-        FamilyRecID familyRecID = INVALID_FAMILY_REC_ID;
-
-        for (int j = 0; j < family->fFontFiles.count(); ++j) {
-            SkString filename;
-            get_path_for_sys_fonts(&filename, family->fFontFiles[j].fFileName);
-
-            if (has_font(fFonts, filename)) {
-                SkDebugf("---- system font and fallback font files specify a duplicate "
-                        "font %s, skipping the second occurrence", filename.c_str());
-                continue;
-            }
-
-            FontRec& fontRec = fFonts.push_back();
-            fontRec.fFileName = filename;
-            fontRec.fStyle = SkTypeface::kNormal;
-            fontRec.fIsValid = false;
-            fontRec.fFamilyRecID = familyRecID;
-
-            const FontRecID fontRecID = fFonts.count() - 1;
-
-            SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(filename.c_str()));
-            if (stream.get() != NULL) {
-                bool isFixedWidth;
-                SkString name;
-                fontRec.fIsValid = find_name_and_attributes(stream.get(), &name,
-                                                            &fontRec.fStyle, &isFixedWidth);
-            } else {
-                if (!family->fIsFallbackFont) {
-                    SkDebugf("---- failed to open <%s> as a font\n", filename.c_str());
-                }
-            }
-
-            if (fontRec.fIsValid) {
-                DEBUG_FONT(("---- SystemFonts[%d][%d] fallback=%d file=%s",
-                           i, fFonts.count() - 1, family->fIsFallbackFont, filename.c_str()));
-            } else {
-                DEBUG_FONT(("---- SystemFonts[%d][%d] fallback=%d file=%s (INVALID)",
-                           i, fFonts.count() - 1, family->fIsFallbackFont, filename.c_str()));
-                continue;
-            }
-
-            // create a familyRec now that we know that at least one font in
-            // the family is valid
-            if (familyRec == NULL) {
-                familyRec = &fFontFamilies.push_back();
-                familyRecID = fFontFamilies.count() - 1;
-                fontRec.fFamilyRecID = familyRecID;
-
-                familyRec->fIsFallbackFont = family->fIsFallbackFont;
-                familyRec->fPaintOptions = family->fFontFiles[j].fPaintOptions;
-
-            } else if (familyRec->fPaintOptions != family->fFontFiles[j].fPaintOptions) {
-                SkDebugf("Every font file within a family must have identical"
-                         "language and variant attributes");
-                sk_throw();
-            }
-
-            // add this font to the current familyRec
-            if (INVALID_FONT_REC_ID != familyRec->fFontRecID[fontRec.fStyle]) {
-                DEBUG_FONT(("Overwriting familyRec for style[%d] old,new:(%d,%d)",
-                            fontRec.fStyle, familyRec->fFontRecID[fontRec.fStyle],
-                            fontRecID));
-            }
-            familyRec->fFontRecID[fontRec.fStyle] = fontRecID;
-        }
-
-        if (familyRec) {
-            if (familyRec->fIsFallbackFont) {
-                // add the font to the appropriate fallback chains and also insert a
-                // unique name into the familyNameDict for internal usage
-                addFallbackFamily(familyRecID);
-            } else {
-                // add the names that map to this family to the dictionary for easy lookup
-                const SkTArray<SkString>& names = family->fNames;
-                if (names.empty()) {
-                    SkDEBUGFAIL("ERROR: non-fallback font with no name");
-                    continue;
-                }
-
-                for (int i = 0; i < names.count(); i++) {
-                    insert_into_name_dict(fFamilyNameDict, names[i].c_str(), familyRecID);
-                }
-            }
-        }
-    }
-
-    DEBUG_FONT(("---- We have %d system fonts", fFonts.count()));
-
-    if (fFontFamilies.count() > 0) {
-        fDefaultFamilyRecID = 0;
-    }
-
-    // scans the default fallback font chain, adding every entry to every other
-    // fallback font chain to which it does not belong. this results in every
-    // language-specific fallback font chain having all of its fallback fonts at
-    // the front of the chain, and everything else at the end.
-    FallbackFontList* fallbackList;
-    SkTDict<FallbackFontList*>::Iter iter(fFallbackFontDict);
-    const char* fallbackLang = iter.next(&fallbackList);
-    while(fallbackLang != NULL) {
-        for (int i = 0; i < fDefaultFallbackList.count(); i++) {
-            FamilyRecID familyRecID = fDefaultFallbackList[i];
-            const SkString& fontLang = fFontFamilies[familyRecID].fPaintOptions.getLanguage().getTag();
-            if (strcmp(fallbackLang, fontLang.c_str()) != 0) {
-                fallbackList->push(familyRecID);
-            }
-        }
-        // move to the next fallback list in the dictionary
-        fallbackLang = iter.next(&fallbackList);
-    }
-}
-
-SkFontConfigInterfaceAndroid::~SkFontConfigInterfaceAndroid() {
-    // iterate through and cleanup fFallbackFontDict
-    SkTDict<FallbackFontList*>::Iter iter(fFallbackFontDict);
-    FallbackFontList* fallbackList;
-    while(iter.next(&fallbackList) != NULL) {
-        SkDELETE(fallbackList);
-    }
-}
-
-void SkFontConfigInterfaceAndroid::addFallbackFamily(FamilyRecID familyRecID) {
-    SkASSERT(familyRecID < fFontFamilies.count());
-    FamilyRec& familyRec = fFontFamilies[familyRecID];
-    SkASSERT(familyRec.fIsFallbackFont);
-
-    // add the fallback family to the name dictionary.  This is
-    // needed by getFallbackFamilyNameForChar() so that fallback
-    // families can be identified by a unique name. The unique
-    // identifier that we've chosen is the familyID in hex (e.g. '0F##fallback').
-    familyRec.fFallbackName.printf("%.2x##fallback", familyRecID);
-    insert_into_name_dict(fFamilyNameDict, familyRec.fFallbackName.c_str(), familyRecID);
-
-    // add to the default fallback list
-    fDefaultFallbackList.push(familyRecID);
-
-    // stop here if it is the default language tag
-    const SkString& languageTag = familyRec.fPaintOptions.getLanguage().getTag();
-    if (languageTag.isEmpty()) {
-        return;
-    }
-
-    // add to the appropriate language's custom fallback list
-    FallbackFontList* customList = NULL;
-    if (!fFallbackFontDict.find(languageTag.c_str(), &customList)) {
-        DEBUG_FONT(("----  Created fallback list for \"%s\"", languageTag.c_str()));
-        customList = SkNEW(FallbackFontList);
-        fFallbackFontDict.set(languageTag.c_str(), customList);
-    }
-    SkASSERT(customList != NULL);
-    customList->push(familyRecID);
-}
-
-
-static FontRecID find_best_style(const FamilyRec& family, SkTypeface::Style style) {
-
-    const FontRecID* fontRecIDs = family.fFontRecID;
-
-    if (fontRecIDs[style] != INVALID_FONT_REC_ID) { // exact match
-        return fontRecIDs[style];
-    }
-    // look for a matching bold
-    style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
-    if (fontRecIDs[style] != INVALID_FONT_REC_ID) {
-        return fontRecIDs[style];
-    }
-    // look for the plain
-    if (fontRecIDs[SkTypeface::kNormal] != INVALID_FONT_REC_ID) {
-        return fontRecIDs[SkTypeface::kNormal];
-    }
-    // look for anything
-    for (int i = 0; i < FamilyRec::FONT_STYLE_COUNT; i++) {
-        if (fontRecIDs[i] != INVALID_FONT_REC_ID) {
-            return fontRecIDs[i];
-        }
-    }
-    // should never get here, since the fontRecID list should not be empty
-    SkDEBUGFAIL("No valid fonts exist for this family");
-    return -1;
-}
-
-bool SkFontConfigInterfaceAndroid::matchFamilyName(const char familyName[],
-                                                   SkTypeface::Style style,
-                                                   FontIdentity* outFontIdentifier,
-                                                   SkString* outFamilyName,
-                                                   SkTypeface::Style* outStyle) {
-    // clip to legal style bits
-    style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
-
-    bool exactNameMatch = false;
-
-    FamilyRecID familyRecID = INVALID_FAMILY_REC_ID;
-    if (NULL != familyName) {
-        SkAutoAsciiToLC tolc(familyName);
-        if (fFamilyNameDict.find(tolc.lc(), &familyRecID)) {
-            exactNameMatch = true;
-        }
-    } else {
-        familyRecID = fDefaultFamilyRecID;
-
-    }
-
-    // If no matching family name is found then return false. This allows clients
-    // to be able to search for other fonts instead of forcing them to use the
-    // default font.
-    if (INVALID_FAMILY_REC_ID == familyRecID) {
-        return false;
-    }
-
-    FontRecID fontRecID = find_best_style(fFontFamilies[familyRecID], style);
-    FontRec& fontRec = fFonts[fontRecID];
-
-    if (NULL != outFontIdentifier) {
-        outFontIdentifier->fID = fontRecID;
-        outFontIdentifier->fTTCIndex = 0;
-        outFontIdentifier->fString.set(fontRec.fFileName);
-//        outFontIdentifier->fStyle = fontRec.fStyle;
-    }
-
-    if (NULL != outFamilyName) {
-        if (exactNameMatch) {
-            outFamilyName->set(familyName);
-        } else {
-            // find familyName from list of names
-            const char* familyName = NULL;
-            SkAssertResult(fFamilyNameDict.findKey(familyRecID, &familyName));
-            SkASSERT(familyName);
-            outFamilyName->set(familyName);
-        }
-    }
-
-    if (NULL != outStyle) {
-        *outStyle = fontRec.fStyle;
-    }
-
-    return true;
-}
-
-SkStream* SkFontConfigInterfaceAndroid::openStream(const FontIdentity& identity) {
-    return SkStream::NewFromFile(identity.fString.c_str());
-}
-
-SkDataTable* SkFontConfigInterfaceAndroid::getFamilyNames() {
-    SkTDArray<const char*> names;
-    SkTDArray<size_t> sizes;
-
-    SkTDict<FamilyRecID>::Iter iter(fFamilyNameDict);
-    const char* familyName = iter.next(NULL);
-    while(familyName != NULL) {
-        *names.append() = familyName;
-        *sizes.append() = strlen(familyName) + 1;
-
-        // move to the next familyName in the dictionary
-        familyName = iter.next(NULL);
-    }
-
-    return SkDataTable::NewCopyArrays((const void*const*)names.begin(),
-                                      sizes.begin(), names.count());
-}
-
-bool SkFontConfigInterfaceAndroid::matchFamilySet(const char inFamilyName[],
-                                                  SkString* outFamilyName,
-                                                  SkTArray<FontIdentity>*) {
-    return false;
-}
-
-static bool find_proc(SkTypeface* face, SkTypeface::Style style, void* ctx) {
-    const FontRecID* fontRecID = (const FontRecID*)ctx;
-    FontRecID currFontRecID = ((FontConfigTypeface*)face)->getIdentity().fID;
-    return currFontRecID == *fontRecID;
-}
-
-SkTypeface* SkFontConfigInterfaceAndroid::getTypefaceForFontRec(FontRecID fontRecID) {
-    FontRec& fontRec = fFonts[fontRecID];
-    SkTypeface* face = fontRec.fTypeface.get();
-    if (!face) {
-        // look for it in the typeface cache
-        face = SkTypefaceCache::FindByProcAndRef(find_proc, &fontRecID);
-
-        // if it is not in the cache then create it
-        if (!face) {
-            const char* familyName = NULL;
-            SkAssertResult(fFamilyNameDict.findKey(fontRec.fFamilyRecID, &familyName));
-            SkASSERT(familyName);
-            face = SkTypeface::CreateFromName(familyName, fontRec.fStyle);
-        }
-
-        // store the result for subsequent lookups
-        fontRec.fTypeface = face;
-    }
-    SkASSERT(face);
-    return face;
-}
-
-bool SkFontConfigInterfaceAndroid::getFallbackFamilyNameForChar(SkUnichar uni,
-                                                                const char* lang,
-                                                                SkString* name) {
-    FallbackFontList* fallbackFontList = NULL;
-    const SkString langTag(lang);
-    if (langTag.isEmpty()) {
-        fallbackFontList = this->getCurrentLocaleFallbackFontList();
-    } else {
-        fallbackFontList = this->findFallbackFontList(langTag);
-    }
-
-    for (int i = 0; i < fallbackFontList->count(); i++) {
-        FamilyRecID familyRecID = fallbackFontList->getAt(i);
-
-        // if it is not one of the accepted variants then move to the next family
-        int32_t acceptedVariants = SkPaintOptionsAndroid::kDefault_Variant |
-                                   SkPaintOptionsAndroid::kElegant_Variant;
-        if (!(fFontFamilies[familyRecID].fPaintOptions.getFontVariant() & acceptedVariants)) {
-            continue;
-        }
-
-        FontRecID fontRecID = find_best_style(fFontFamilies[familyRecID], SkTypeface::kNormal);
-        SkTypeface* face = this->getTypefaceForFontRec(fontRecID);
-
-        SkPaint paint;
-        paint.setTypeface(face);
-        paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
-
-        uint16_t glyphID;
-        paint.textToGlyphs(&uni, sizeof(uni), &glyphID);
-        if (glyphID != 0) {
-            name->set(fFontFamilies[familyRecID].fFallbackName);
-            return true;
-        }
-    }
-    return false;
-}
-
-SkTypeface* SkFontConfigInterfaceAndroid::getTypefaceForChar(SkUnichar uni,
-                                                             SkTypeface::Style style,
-                                                             SkPaintOptionsAndroid::FontVariant fontVariant) {
-    FontRecID fontRecID = find_best_style(fFontFamilies[fDefaultFamilyRecID], style);
-    SkTypeface* face = this->getTypefaceForFontRec(fontRecID);
-
-    SkPaintOptionsAndroid paintOptions;
-    paintOptions.setFontVariant(fontVariant);
-    paintOptions.setUseFontFallbacks(true);
-
-    SkPaint paint;
-    paint.setTypeface(face);
-    paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
-    paint.setPaintOptionsAndroid(paintOptions);
-
-    SkAutoGlyphCache autoCache(paint, NULL, NULL);
-    SkGlyphCache*    cache = autoCache.getCache();
-
-    SkScalerContext* ctx = cache->getScalerContext();
-    if (ctx) {
-        SkFontID fontID = ctx->findTypefaceIdForChar(uni);
-        return SkTypefaceCache::FindByID(fontID);
-    }
-    return NULL;
-}
-
-FallbackFontList* SkFontConfigInterfaceAndroid::getCurrentLocaleFallbackFontList() {
-    SkString locale = SkFontConfigParser::GetLocale();
-    if (NULL == fLocaleFallbackFontList || locale != fCachedLocale) {
-        fCachedLocale = locale;
-        fLocaleFallbackFontList = this->findFallbackFontList(locale);
-    }
-    return fLocaleFallbackFontList;
-}
-
-FallbackFontList* SkFontConfigInterfaceAndroid::findFallbackFontList(const SkLanguage& lang,
-                                                                     bool isOriginal) {
-    const SkString& langTag = lang.getTag();
-    if (langTag.isEmpty()) {
-        return &fDefaultFallbackList;
-    }
-
-    FallbackFontList* fallbackFontList;
-    if (fFallbackFontDict.find(langTag.c_str(), langTag.size(), &fallbackFontList) ||
-        fFallbackFontAliasDict.find(langTag.c_str(), langTag.size(), &fallbackFontList)) {
-        return fallbackFontList;
-    }
-
-    // attempt a recursive fuzzy match
-    SkLanguage parent = lang.getParent();
-    fallbackFontList = findFallbackFontList(parent, false);
-
-    // cache the original lang so we don't have to do the recursion again.
-    if (isOriginal) {
-        DEBUG_FONT(("----  Created fallback list alias for \"%s\"", langTag.c_str()));
-        fFallbackFontAliasDict.set(langTag.c_str(), fallbackFontList);
-    }
-    return fallbackFontList;
-}
-
-SkTypeface* SkFontConfigInterfaceAndroid::nextLogicalTypeface(SkFontID currFontID,
-                                                              SkFontID origFontID,
-                                                              const SkPaintOptionsAndroid& opts) {
-    // Skia does not support font fallback by default. This enables clients such
-    // as WebKit to customize their font selection. In any case, clients can use
-    // GetFallbackFamilyNameForChar() to get the fallback font for individual
-    // characters.
-    if (!opts.isUsingFontFallbacks()) {
-        return NULL;
-    }
-
-    FallbackFontList* currentFallbackList = findFallbackFontList(opts.getLanguage());
-    SkASSERT(currentFallbackList);
-
-    SkTypeface::Style origStyle = SkTypeface::kNormal;
-    const SkTypeface* origTypeface = SkTypefaceCache::FindByID(origFontID);
-    if (NULL != origTypeface) {
-        origStyle = origTypeface->style();
-    }
-
-    // we must convert currTypeface into a FontRecID
-    FontRecID currFontRecID = INVALID_FONT_REC_ID;
-    const SkTypeface* currTypeface = SkTypefaceCache::FindByID(currFontID);
-    // non-system fonts are not in the font cache so if we are asked to fallback
-    // for a non-system font we will start at the front of the chain.
-    if (NULL != currTypeface) {
-        currFontRecID = ((FontConfigTypeface*)currTypeface)->getIdentity().fID;
-        SkASSERT(INVALID_FONT_REC_ID != currFontRecID);
-    }
-
-    FamilyRecID currFamilyRecID = INVALID_FAMILY_REC_ID;
-    if (INVALID_FONT_REC_ID != currFontRecID) {
-        currFamilyRecID = fFonts[currFontRecID].fFamilyRecID;
-    }
-
-    // lookup the index next font in the chain
-    int currFallbackFontIndex = currentFallbackList->find(currFamilyRecID);
-    // We add 1 to the returned index for 2 reasons: (1) if find succeeds it moves
-    // our index to the next entry in the list; (2) if find() fails it returns
-    // -1 and incrementing it will set our starting index to 0 (the head of the list)
-    int nextFallbackFontIndex = currFallbackFontIndex + 1;
-
-    if(nextFallbackFontIndex >= currentFallbackList->count()) {
-        return NULL;
-    }
-
-    // If a rec object is set to prefer "kDefault_Variant" it means they have no preference
-    // In this case, we set the value to "kCompact_Variant"
-    SkPaintOptionsAndroid::FontVariant variant = opts.getFontVariant();
-    if (variant == SkPaintOptionsAndroid::kDefault_Variant) {
-        variant = SkPaintOptionsAndroid::kCompact_Variant;
-    }
-
-    int32_t acceptedVariants = SkPaintOptionsAndroid::kDefault_Variant | variant;
-
-    SkTypeface* nextLogicalTypeface = 0;
-    while (nextFallbackFontIndex < currentFallbackList->count()) {
-        FamilyRecID familyRecID = currentFallbackList->getAt(nextFallbackFontIndex);
-        if ((fFontFamilies[familyRecID].fPaintOptions.getFontVariant() & acceptedVariants) != 0) {
-            FontRecID matchedFont = find_best_style(fFontFamilies[familyRecID], origStyle);
-            nextLogicalTypeface = this->getTypefaceForFontRec(matchedFont);
-            break;
-        }
-        nextFallbackFontIndex++;
-    }
-
-    DEBUG_FONT(("---- nextLogicalFont: currFontID=%d, origFontID=%d, currRecID=%d, "
-                "lang=%s, variant=%d, nextFallbackIndex[%d,%d] => nextLogicalTypeface=%d",
-                currFontID, origFontID, currFontRecID, opts.getLanguage().getTag().c_str(),
-                variant, nextFallbackFontIndex, currentFallbackList->getAt(nextFallbackFontIndex),
-                (nextLogicalTypeface) ? nextLogicalTypeface->uniqueID() : 0));
-    return SkSafeRef(nextLogicalTypeface);
-}
-
-SkTypeface* SkFontConfigInterfaceAndroid::getTypefaceForGlyphID(uint16_t glyphID,
-                                                                const SkTypeface* origTypeface,
-                                                                const SkPaintOptionsAndroid& opts,
-                                                                int* lBounds, int* uBounds) {
-    // If we aren't using fallbacks then we shouldn't be calling this
-    SkASSERT(opts.isUsingFontFallbacks());
-    SkASSERT(origTypeface);
-
-    SkTypeface* currentTypeface = NULL;
-    int lowerBounds = 0; //inclusive
-    int upperBounds = origTypeface->countGlyphs(); //exclusive
-
-    // check to see if the glyph is in the bounds of the origTypeface
-    if (glyphID < upperBounds) {
-        currentTypeface = const_cast<SkTypeface*>(origTypeface);
-    } else {
-        FallbackFontList* currentFallbackList = findFallbackFontList(opts.getLanguage());
-        SkASSERT(currentFallbackList);
-
-        // If an object is set to prefer "kDefault_Variant" it means they have no preference
-        // In this case, we set the value to "kCompact_Variant"
-        SkPaintOptionsAndroid::FontVariant variant = opts.getFontVariant();
-        if (variant == SkPaintOptionsAndroid::kDefault_Variant) {
-            variant = SkPaintOptionsAndroid::kCompact_Variant;
-        }
-
-        int32_t acceptedVariants = SkPaintOptionsAndroid::kDefault_Variant | variant;
-        SkTypeface::Style origStyle = origTypeface->style();
-
-        for (int x = 0; x < currentFallbackList->count(); ++x) {
-            const FamilyRecID familyRecID = currentFallbackList->getAt(x);
-            const SkPaintOptionsAndroid& familyOptions = fFontFamilies[familyRecID].fPaintOptions;
-            if ((familyOptions.getFontVariant() & acceptedVariants) != 0) {
-                FontRecID matchedFont = find_best_style(fFontFamilies[familyRecID], origStyle);
-                currentTypeface = this->getTypefaceForFontRec(matchedFont);
-                lowerBounds = upperBounds;
-                upperBounds += currentTypeface->countGlyphs();
-                if (glyphID < upperBounds) {
-                    break;
-                }
-            }
-        }
-    }
-
-    if (NULL != currentTypeface) {
-        if (lBounds) {
-            *lBounds = lowerBounds;
-        }
-        if (uBounds) {
-            *uBounds = upperBounds;
-        }
-    }
-    return currentTypeface;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool SkGetFallbackFamilyNameForChar(SkUnichar uni, SkString* name) {
-    SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface();
-    return fontConfig->getFallbackFamilyNameForChar(uni, NULL, name);
-}
-
-bool SkGetFallbackFamilyNameForChar(SkUnichar uni, const char* lang, SkString* name) {
-    SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface();
-    return fontConfig->getFallbackFamilyNameForChar(uni, lang, name);
-}
-
-void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackconf,
-                             const char* fontsdir) {
-    gTestMainConfigFile = mainconf;
-    gTestFallbackConfigFile = fallbackconf;
-    gTestFontFilePrefix = fontsdir;
-    SkASSERT(gTestMainConfigFile);
-    SkASSERT(gTestFallbackConfigFile);
-    SkASSERT(gTestFontFilePrefix);
-    SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s",
-              gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix));
-}
-
-SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID, SkFontID origFontID,
-                                         const SkPaintOptionsAndroid& options) {
-    SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface();
-    return fontConfig->nextLogicalTypeface(currFontID, origFontID, options);
-
-}
-
-SkTypeface* SkGetTypefaceForGlyphID(uint16_t glyphID, const SkTypeface* origTypeface,
-                                    const SkPaintOptionsAndroid& options,
-                                    int* lowerBounds, int* upperBounds) {
-    SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface();
-    return fontConfig->getTypefaceForGlyphID(glyphID, origTypeface, options,
-                                             lowerBounds, upperBounds);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
-
-struct HB_UnicodeMapping {
-    hb_script_t script;
-    const SkUnichar unicode;
-};
-
-/*
- * The following scripts are not complex fonts and we do not expect them to be parsed by this table
- * HB_SCRIPT_COMMON,
- * HB_SCRIPT_GREEK,
- * HB_SCRIPT_CYRILLIC,
- * HB_SCRIPT_HANGUL
- * HB_SCRIPT_INHERITED
- */
-
-/* Harfbuzz (old) is missing a number of scripts in its table. For these,
- * we include a value which can never happen. We won't get complex script
- * shaping in these cases, but the library wouldn't know how to shape
- * them anyway. */
-#define HB_Script_Unknown HB_ScriptCount
-
-static HB_UnicodeMapping HB_UnicodeMappingArray[] = {
-    {HB_SCRIPT_ARMENIAN,    0x0531},
-    {HB_SCRIPT_HEBREW,      0x0591},
-    {HB_SCRIPT_ARABIC,      0x0600},
-    {HB_SCRIPT_SYRIAC,      0x0710},
-    {HB_SCRIPT_THAANA,      0x0780},
-    {HB_SCRIPT_NKO,         0x07C0},
-    {HB_SCRIPT_DEVANAGARI,  0x0901},
-    {HB_SCRIPT_BENGALI,     0x0981},
-    {HB_SCRIPT_GURMUKHI,    0x0A10},
-    {HB_SCRIPT_GUJARATI,    0x0A90},
-    {HB_SCRIPT_ORIYA,       0x0B10},
-    {HB_SCRIPT_TAMIL,       0x0B82},
-    {HB_SCRIPT_TELUGU,      0x0C10},
-    {HB_SCRIPT_KANNADA,     0x0C90},
-    {HB_SCRIPT_MALAYALAM,   0x0D10},
-    {HB_SCRIPT_SINHALA,     0x0D90},
-    {HB_SCRIPT_THAI,        0x0E01},
-    {HB_SCRIPT_LAO,         0x0E81},
-    {HB_SCRIPT_TIBETAN,     0x0F00},
-    {HB_SCRIPT_MYANMAR,     0x1000},
-    {HB_SCRIPT_GEORGIAN,    0x10A0},
-    {HB_SCRIPT_ETHIOPIC,    0x1200},
-    {HB_SCRIPT_CHEROKEE,    0x13A0},
-    {HB_SCRIPT_OGHAM,       0x1680},
-    {HB_SCRIPT_RUNIC,       0x16A0},
-    {HB_SCRIPT_KHMER,       0x1780},
-    {HB_SCRIPT_TAI_LE,      0x1950},
-    {HB_SCRIPT_NEW_TAI_LUE, 0x1980},
-    {HB_SCRIPT_TAI_THAM,    0x1A20},
-    {HB_SCRIPT_CHAM,        0xAA00},
-};
-
-// returns 0 for "Not Found"
-static SkUnichar getUnicodeFromHBScript(hb_script_t script) {
-    SkUnichar unichar = 0;
-    int numSupportedFonts = sizeof(HB_UnicodeMappingArray) / sizeof(HB_UnicodeMapping);
-    for (int i = 0; i < numSupportedFonts; i++) {
-        if (script == HB_UnicodeMappingArray[i].script) {
-            unichar = HB_UnicodeMappingArray[i].unicode;
-            break;
-        }
-    }
-    return unichar;
-}
-
-struct TypefaceLookupStruct {
-    hb_script_t script;
-    SkTypeface::Style style;
-    SkPaintOptionsAndroid::FontVariant fontVariant;
-    SkTypeface* typeface;
-};
-
-SK_DECLARE_STATIC_MUTEX(gTypefaceTableMutex);  // This is the mutex for gTypefaceTable
-static SkTDArray<TypefaceLookupStruct> gTypefaceTable;  // This is protected by gTypefaceTableMutex
-
-static int typefaceLookupCompare(const TypefaceLookupStruct& first,
-                                 const TypefaceLookupStruct& second) {
-    if (first.script != second.script) {
-        return (first.script > second.script) ? 1 : -1;
-    }
-    if (first.style != second.style) {
-        return (first.style > second.style) ? 1 : -1;
-    }
-    if (first.fontVariant != second.fontVariant) {
-        return (first.fontVariant > second.fontVariant) ? 1 : -1;
-    }
-    return 0;
-}
-
-SkTypeface* SkCreateTypefaceForScript(hb_script_t script, SkTypeface::Style style,
-                                      SkPaintOptionsAndroid::FontVariant fontVariant) {
-    SkAutoMutexAcquire ac(gTypefaceTableMutex);
-
-    TypefaceLookupStruct key;
-    key.script = script;
-    key.style = style;
-    key.fontVariant = fontVariant;
-
-    int index = SkTSearch<TypefaceLookupStruct>(
-            (const TypefaceLookupStruct*) gTypefaceTable.begin(),
-            gTypefaceTable.count(), key, sizeof(TypefaceLookupStruct),
-            typefaceLookupCompare);
-
-    SkTypeface* retTypeface = NULL;
-    if (index >= 0) {
-        retTypeface = gTypefaceTable[index].typeface;
-    }
-    else {
-        SkUnichar unichar = getUnicodeFromHBScript(script);
-        if (!unichar) {
-            return NULL;
-        }
-
-        SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface();
-        retTypeface = fontConfig->getTypefaceForChar(unichar, style, fontVariant);
-
-        // add to the lookup table
-        key.typeface = retTypeface;
-        *gTypefaceTable.insert(~index) = key;
-    }
-
-    // we ref(), the caller is expected to unref when they are done
-    return SkSafeRef(retTypeface);
-}
-
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkFontMgr* SkFontMgr::Factory() {
-    return NULL;
-}
diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp
index dc9afba..039d868 100644
--- a/src/ports/SkFontConfigInterface_direct.cpp
+++ b/src/ports/SkFontConfigInterface_direct.cpp
@@ -7,7 +7,6 @@
 
 /* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */
 
-#include <string>
 #include <unistd.h>
 #include <fcntl.h>
 
@@ -17,6 +16,7 @@
 #include "SkFontConfigInterface.h"
 #include "SkLazyPtr.h"
 #include "SkStream.h"
+#include "SkString.h"
 
 size_t SkFontConfigInterface::FontIdentity::writeToMemory(void* addr) const {
     size_t size = sizeof(fID) + sizeof(fTTCIndex);
@@ -124,9 +124,13 @@
     SkMutex mutex_;
 };
 
-SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface() {
-    SK_DECLARE_STATIC_LAZY_PTR(SkFontConfigInterfaceDirect, direct);
-    return direct.get();
+SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface(SkBaseMutex* mutex) {
+    SkAutoMutexAcquire ac(mutex);
+    static SkFontConfigInterfaceDirect* singleton = NULL;
+    if (singleton == NULL) {
+        singleton = SkNEW(SkFontConfigInterfaceDirect);
+    }
+    return singleton;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -217,6 +221,7 @@
         { PGOTHIC, "MS PGothic" },
         { PGOTHIC, "\xef\xbc\xad\xef\xbc\xb3 \xef\xbc\xb0"
                    "\xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf" },
+        { PGOTHIC, "Noto Sans CJK JP" },
         { PGOTHIC, "IPAPGothic" },
         { PGOTHIC, "MotoyaG04Gothic" },
 
@@ -255,6 +260,7 @@
         // 黑体
         { SIMHEI, "Simhei" },
         { SIMHEI, "\xe9\xbb\x91\xe4\xbd\x93" },
+        { SIMHEI, "Noto Sans CJK SC" },
         { SIMHEI, "MYingHeiGB18030" },
         { SIMHEI, "MYingHeiB5HK" },
 
@@ -314,9 +320,9 @@
 // cases, the request either doesn't specify a font or is one of the
 // basic font names like "Sans", "Serif" or "Monospace". This function
 // tells you whether a given request is for such a fallback.
-bool IsFallbackFontAllowed(const std::string& family) {
+bool IsFallbackFontAllowed(const SkString& family) {
   const char* family_cstr = family.c_str();
-  return family.empty() ||
+  return family.isEmpty() ||
          strcasecmp(family_cstr, "sans") == 0 ||
          strcasecmp(family_cstr, "serif") == 0 ||
          strcasecmp(family_cstr, "monospace") == 0;
@@ -345,7 +351,7 @@
 // Find matching font from |font_set| for the given font family.
 FcPattern* MatchFont(FcFontSet* font_set,
                      const char* post_config_family,
-                     const std::string& family) {
+                     const SkString& family) {
   // Older versions of fontconfig have a bug where they cannot select
   // only scalable fonts so we have to manually filter the results.
   FcPattern* match = NULL;
@@ -437,8 +443,8 @@
                                                   FontIdentity* outIdentity,
                                                   SkString* outFamilyName,
                                                   SkTypeface::Style* outStyle) {
-    std::string familyStr(familyName ? familyName : "");
-    if (familyStr.length() > kMaxFontFamilyLength) {
+    SkString familyStr(familyName ? familyName : "");
+    if (familyStr.size() > kMaxFontFamilyLength) {
         return false;
     }
 
@@ -604,8 +610,8 @@
     SkAutoMutexAcquire ac(mutex_);
 
 #if 0
-    std::string familyStr(familyName ? familyName : "");
-    if (familyStr.length() > kMaxFontFamilyLength) {
+    SkString familyStr(familyName ? familyName : "");
+    if (familyStr.size() > kMaxFontFamilyLength) {
         return false;
     }
 
diff --git a/src/ports/SkFontConfigParser_android.cpp b/src/ports/SkFontConfigParser_android.cpp
index 38a6ee6..41f5c4a 100644
--- a/src/ports/SkFontConfigParser_android.cpp
+++ b/src/ports/SkFontConfigParser_android.cpp
@@ -7,16 +7,38 @@
 
 #include "SkFontConfigParser_android.h"
 #include "SkTDArray.h"
+#include "SkTSearch.h"
 #include "SkTypeface.h"
 
 #include <expat.h>
+#include <dirent.h>
 #include <stdio.h>
-#include <sys/system_properties.h>
 
-#define SYSTEM_FONTS_FILE "/system/etc/system_fonts.xml"
+#include <limits>
+
+
+
+// From Android version LMP onwards, all font files collapse into
+// /system/etc/fonts.xml. Instead of trying to detect which version
+// we're on, try to open fonts.xml; if that fails, fall back to the
+// older filename.
+#define LMP_SYSTEM_FONTS_FILE "/system/etc/fonts.xml"
+#define OLD_SYSTEM_FONTS_FILE "/system/etc/system_fonts.xml"
 #define FALLBACK_FONTS_FILE "/system/etc/fallback_fonts.xml"
 #define VENDOR_FONTS_FILE "/vendor/etc/fallback_fonts.xml"
 
+#define LOCALE_FALLBACK_FONTS_SYSTEM_DIR "/system/etc"
+#define LOCALE_FALLBACK_FONTS_VENDOR_DIR "/vendor/etc"
+#define LOCALE_FALLBACK_FONTS_PREFIX "fallback_fonts-"
+#define LOCALE_FALLBACK_FONTS_SUFFIX ".xml"
+
+/**
+ * This file contains TWO parsers: one for JB and earlier (system_fonts.xml /
+ * fallback_fonts.xml), one for LMP and later (fonts.xml).
+ * We start with the JB parser, and if we detect a <familyset> tag with
+ * version 21 or higher we switch to the LMP parser.
+ */
+
 // These defines are used to determine the kind of tag that we're currently
 // populating with data. We only care about the sibling tags nameset and fileset
 // for now.
@@ -29,33 +51,252 @@
  * can read these variables that are relevant to the current parsing.
  */
 struct FamilyData {
-    FamilyData(XML_Parser *parserRef, SkTDArray<FontFamily*> &familiesRef) :
+    FamilyData(XML_Parser* parserRef, SkTDArray<FontFamily*> &familiesRef) :
         parser(parserRef),
         families(familiesRef),
         currentFamily(NULL),
         currentFontInfo(NULL),
         currentTag(NO_TAG) {};
 
-    XML_Parser *parser;                // The expat parser doing the work
+    XML_Parser* parser;                // The expat parser doing the work
     SkTDArray<FontFamily*> &families;  // The array that each family is put into as it is parsed
-    FontFamily *currentFamily;         // The current family being created
-    FontFileInfo *currentFontInfo;     // The current fontInfo being created
+    FontFamily* currentFamily;         // The current family being created
+    FontFileInfo* currentFontInfo;     // The current fontInfo being created
     int currentTag;                    // A flag to indicate whether we're in nameset/fileset tags
 };
 
+/** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-negative-def */
+template <typename T> static bool parseNonNegativeInteger(const char* s, T* value) {
+    SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer);
+    const T nMax = std::numeric_limits<T>::max() / 10;
+    const T dMax = std::numeric_limits<T>::max() - (nMax * 10);
+    T n = 0;
+    for (; *s; ++s) {
+        // Check if digit
+        if (*s < '0' || '9' < *s) {
+            return false;
+        }
+        int d = *s - '0';
+        // Check for overflow
+        if (n > nMax || (n == nMax && d > dMax)) {
+            return false;
+        }
+        n = (n * 10) + d;
+    }
+    *value = n;
+    return true;
+}
+
+namespace lmpParser {
+
+void familyElementHandler(FontFamily* family, const char** attributes) {
+    // A non-fallback <family> tag must have a canonical name attribute.
+    // A fallback <family> tag has no name, and may have lang and variant
+    // attributes.
+    family->fIsFallbackFont = true;
+    for (size_t i = 0; attributes[i] != NULL &&
+                       attributes[i+1] != NULL; i += 2) {
+        const char* name = attributes[i];
+        const char* value = attributes[i+1];
+        size_t nameLen = strlen(name);
+        size_t valueLen = strlen(value);
+        if (nameLen == 4 && !strncmp("name", name, nameLen)) {
+            SkAutoAsciiToLC tolc(value);
+            family->fNames.push_back().set(tolc.lc());
+            family->fIsFallbackFont = false;
+        } else if (nameLen == 4 && !strncmp("lang", name, nameLen)) {
+            family->fLanguage = SkLanguage (value);
+        } else if (nameLen == 7 && !strncmp("variant", name, nameLen)) {
+            // Value should be either elegant or compact.
+            if (valueLen == 7 && !strncmp("elegant", value, valueLen)) {
+                family->fVariant = kElegant_FontVariant;
+            } else if (valueLen == 7 && !strncmp("compact", value, valueLen)) {
+                family->fVariant = kCompact_FontVariant;
+            }
+        }
+    }
+}
+
+void fontFileNameHandler(void* data, const char* s, int len) {
+    FamilyData* familyData = (FamilyData*) data;
+    familyData->currentFontInfo->fFileName.set(s, len);
+}
+
+void fontElementHandler(XML_Parser* parser, FontFileInfo* file, const char** attributes) {
+    // A <font> should have weight (integer) and style (normal, italic) attributes.
+    // NOTE: we ignore the style.
+    // The element should contain a filename.
+    for (size_t i = 0; attributes[i] != NULL &&
+                       attributes[i+1] != NULL; i += 2) {
+        const char* name = attributes[i];
+        const char* value = attributes[i+1];
+        size_t nameLen = strlen(name);
+        if (nameLen == 6 && !strncmp("weight", name, nameLen)) {
+            if (!parseNonNegativeInteger(value, &file->fWeight)) {
+                SkDebugf("---- Font weight %s (INVALID)", value);
+                file->fWeight = 0;
+            }
+        }
+    }
+    XML_SetCharacterDataHandler(*parser, fontFileNameHandler);
+}
+
+FontFamily* findFamily(FamilyData* familyData, const char* familyName) {
+    size_t nameLen = strlen(familyName);
+    for (int i = 0; i < familyData->families.count(); i++) {
+        FontFamily* candidate = familyData->families[i];
+        for (int j = 0; j < candidate->fNames.count(); j++) {
+            if (!strncmp(candidate->fNames[j].c_str(), familyName, nameLen) &&
+                nameLen == strlen(candidate->fNames[j].c_str())) {
+                return candidate;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+void aliasElementHandler(FamilyData* familyData, const char** attributes) {
+    // An <alias> must have name and to attributes.
+    //   It may have weight (integer).
+    // If it *does not* have a weight, it is a variant name for a <family>.
+    // If it *does* have a weight, it names the <font>(s) of a specific weight
+    //   from a <family>.
+
+    SkString aliasName;
+    SkString to;
+    int weight = 0;
+    for (size_t i = 0; attributes[i] != NULL &&
+                       attributes[i+1] != NULL; i += 2) {
+        const char* name = attributes[i];
+        const char* value = attributes[i+1];
+        size_t nameLen = strlen(name);
+        if (nameLen == 4 && !strncmp("name", name, nameLen)) {
+            SkAutoAsciiToLC tolc(value);
+            aliasName.set(tolc.lc());
+        } else if (nameLen == 2 && !strncmp("to", name, nameLen)) {
+            to.set(value);
+        } else if (nameLen == 6 && !strncmp("weight", name, nameLen)) {
+            parseNonNegativeInteger(value, &weight);
+        }
+    }
+
+    // Assumes that the named family is already declared
+    FontFamily* targetFamily = findFamily(familyData, to.c_str());
+    if (!targetFamily) {
+        SkDebugf("---- Font alias target %s (NOT FOUND)", to.c_str());
+        return;
+    }
+
+    if (weight) {
+        FontFamily* family = new FontFamily();
+        family->fNames.push_back().set(aliasName);
+
+        for (int i = 0; i < targetFamily->fFonts.count(); i++) {
+            if (targetFamily->fFonts[i].fWeight == weight) {
+                family->fFonts.push_back(targetFamily->fFonts[i]);
+            }
+        }
+        *familyData->families.append() = family;
+    } else {
+        targetFamily->fNames.push_back().set(aliasName);
+    }
+}
+
+bool findWeight400(FontFamily* family) {
+    for (int i = 0; i < family->fFonts.count(); i++) {
+        if (family->fFonts[i].fWeight == 400) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool desiredWeight(int weight) {
+    return (weight == 400 || weight == 700);
+}
+
+int countDesiredWeight(FontFamily* family) {
+    int count = 0;
+    for (int i = 0; i < family->fFonts.count(); i++) {
+        if (desiredWeight(family->fFonts[i].fWeight)) {
+            count++;
+        }
+    }
+    return count;
+}
+
+// To meet Skia's expectations, any family that contains weight=400
+// fonts should *only* contain {400,700}
+void purgeUndesiredWeights(FontFamily* family) {
+    int count = countDesiredWeight(family);
+    for (int i = 1, j = 0; i < family->fFonts.count(); i++) {
+        if (desiredWeight(family->fFonts[j].fWeight)) {
+            j++;
+        }
+        if ((i != j) && desiredWeight(family->fFonts[i].fWeight)) {
+            family->fFonts[j] = family->fFonts[i];
+        }
+    }
+    family->fFonts.resize_back(count);
+}
+
+void familysetElementEndHandler(FamilyData* familyData) {
+    for (int i = 0; i < familyData->families.count(); i++) {
+        if (findWeight400(familyData->families[i])) {
+            purgeUndesiredWeights(familyData->families[i]);
+        }
+    }
+}
+
+void startElementHandler(void* data, const char* tag,
+                         const char** attributes) {
+    FamilyData* familyData = (FamilyData*) data;
+    size_t len = strlen(tag);
+    if (len == 6 && !strncmp(tag, "family", len)) {
+        familyData->currentFamily = new FontFamily();
+        familyElementHandler(familyData->currentFamily, attributes);
+    } else if (len == 4 && !strncmp(tag, "font", len)) {
+        FontFileInfo* file = &familyData->currentFamily->fFonts.push_back();
+        familyData->currentFontInfo = file;
+        fontElementHandler(familyData->parser, file, attributes);
+    } else if (len == 5 && !strncmp(tag, "alias", len)) {
+        aliasElementHandler(familyData, attributes);
+    }
+}
+
+void endElementHandler(void* data, const char* tag) {
+    FamilyData* familyData = (FamilyData*) data;
+    size_t len = strlen(tag);
+    if (len == 9 && strncmp(tag, "familyset", len) == 0) {
+        familysetElementEndHandler(familyData);
+    } else if (len == 6 && strncmp(tag, "family", len) == 0) {
+        *familyData->families.append() = familyData->currentFamily;
+        familyData->currentFamily = NULL;
+    } else if (len == 4 && !strncmp(tag, "font", len)) {
+        XML_SetCharacterDataHandler(*familyData->parser, NULL);
+    }
+}
+
+} // lmpParser
+
+namespace jbParser {
+
 /**
  * Handler for arbitrary text. This is used to parse the text inside each name
  * or file tag. The resulting strings are put into the fNames or FontFileInfo arrays.
  */
-static void textHandler(void *data, const char *s, int len) {
-    FamilyData *familyData = (FamilyData*) data;
+static void textHandler(void* data, const char* s, int len) {
+    FamilyData* familyData = (FamilyData*) data;
     // Make sure we're in the right state to store this name information
     if (familyData->currentFamily &&
             (familyData->currentTag == NAMESET_TAG || familyData->currentTag == FILESET_TAG)) {
         switch (familyData->currentTag) {
-        case NAMESET_TAG:
-            familyData->currentFamily->fNames.push_back().set(s, len);
+        case NAMESET_TAG: {
+            SkAutoAsciiToLC tolc(s, len);
+            familyData->currentFamily->fNames.push_back().set(tolc.lc(), len);
             break;
+        }
         case FILESET_TAG:
             if (familyData->currentFontInfo) {
                 familyData->currentFontInfo->fFileName.set(s, len);
@@ -72,24 +313,45 @@
  * Handler for font files. This processes the attributes for language and
  * variants then lets textHandler handle the actual file name
  */
-static void fontFileElementHandler(FamilyData *familyData, const char **attributes) {
-
-    FontFileInfo& newFileInfo = familyData->currentFamily->fFontFiles.push_back();
+static void fontFileElementHandler(FamilyData* familyData, const char** attributes) {
+    FontFileInfo& newFileInfo = familyData->currentFamily->fFonts.push_back();
     if (attributes) {
-        int currentAttributeIndex = 0;
-        while (attributes[currentAttributeIndex]) {
+        size_t currentAttributeIndex = 0;
+        while (attributes[currentAttributeIndex] &&
+               attributes[currentAttributeIndex + 1]) {
             const char* attributeName = attributes[currentAttributeIndex];
             const char* attributeValue = attributes[currentAttributeIndex+1];
-            int nameLength = strlen(attributeName);
-            int valueLength = strlen(attributeValue);
-            if (strncmp(attributeName, "variant", nameLength) == 0) {
-                if (strncmp(attributeValue, "elegant", valueLength) == 0) {
-                    newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndroid::kElegant_Variant);
-                } else if (strncmp(attributeValue, "compact", valueLength) == 0) {
-                    newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndroid::kCompact_Variant);
+            size_t nameLength = strlen(attributeName);
+            size_t valueLength = strlen(attributeValue);
+            if (nameLength == 7 && strncmp(attributeName, "variant", nameLength) == 0) {
+                const FontVariant prevVariant = familyData->currentFamily->fVariant;
+                if (valueLength == 7 && strncmp(attributeValue, "elegant", valueLength) == 0) {
+                    familyData->currentFamily->fVariant = kElegant_FontVariant;
+                } else if (valueLength == 7 &&
+                           strncmp(attributeValue, "compact", valueLength) == 0) {
+                    familyData->currentFamily->fVariant = kCompact_FontVariant;
                 }
-            } else if (strncmp(attributeName, "lang", nameLength) == 0) {
-                newFileInfo.fPaintOptions.setLanguage(attributeValue);
+                if (familyData->currentFamily->fFonts.count() > 1 &&
+                        familyData->currentFamily->fVariant != prevVariant) {
+                    SkDebugf("Every font file within a family must have identical variants");
+                    sk_throw();
+                }
+
+            } else if (nameLength == 4 && strncmp(attributeName, "lang", nameLength) == 0) {
+                SkLanguage prevLang = familyData->currentFamily->fLanguage;
+                familyData->currentFamily->fLanguage = SkLanguage(attributeValue);
+                if (familyData->currentFamily->fFonts.count() > 1 &&
+                        familyData->currentFamily->fLanguage != prevLang) {
+                    SkDebugf("Every font file within a family must have identical languages");
+                    sk_throw();
+                }
+            } else if (nameLength == 5 && strncmp(attributeName, "index", nameLength) == 0) {
+                int value;
+                if (parseNonNegativeInteger(attributeValue, &value)) {
+                    newFileInfo.fIndex = value;
+                } else {
+                    SkDebugf("---- SystemFonts index=%s (INVALID)", attributeValue);
+                }
             }
             //each element is a pair of attributeName/attributeValue string pairs
             currentAttributeIndex += 2;
@@ -100,33 +362,46 @@
 }
 
 /**
- * Handler for the start of a tag. The only tags we expect are family, nameset,
- * fileset, name, and file.
+ * Handler for the start of a tag. The only tags we expect are familyset, family,
+ * nameset, fileset, name, and file.
  */
-static void startElementHandler(void *data, const char *tag, const char **atts) {
-    FamilyData *familyData = (FamilyData*) data;
-    int len = strlen(tag);
-    if (strncmp(tag, "family", len)== 0) {
+static void startElementHandler(void* data, const char* tag, const char** atts) {
+    FamilyData* familyData = (FamilyData*) data;
+    size_t len = strlen(tag);
+    if (len == 9 && strncmp(tag, "familyset", len) == 0) {
+        // The familyset tag has an optional "version" attribute with an integer value >= 0
+        for (size_t i = 0; atts[i] != NULL &&
+                           atts[i+1] != NULL; i += 2) {
+            size_t nameLen = strlen(atts[i]);
+            if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue;
+            const char* valueString = atts[i+1];
+            int version;
+            if (parseNonNegativeInteger(valueString, &version) && (version >= 21)) {
+                XML_SetElementHandler(*familyData->parser,
+                                      lmpParser::startElementHandler,
+                                      lmpParser::endElementHandler);
+            }
+        }
+    } else if (len == 6 && strncmp(tag, "family", len) == 0) {
         familyData->currentFamily = new FontFamily();
-        familyData->currentFamily->order = -1;
         // The Family tag has an optional "order" attribute with an integer value >= 0
         // If this attribute does not exist, the default value is -1
-        for (int i = 0; atts[i] != NULL; i += 2) {
+        for (size_t i = 0; atts[i] != NULL &&
+                           atts[i+1] != NULL; i += 2) {
             const char* valueString = atts[i+1];
             int value;
-            int len = sscanf(valueString, "%d", &value);
-            if (len > 0) {
-                familyData->currentFamily->order = value;
+            if (parseNonNegativeInteger(valueString, &value)) {
+                familyData->currentFamily->fOrder = value;
             }
         }
     } else if (len == 7 && strncmp(tag, "nameset", len) == 0) {
         familyData->currentTag = NAMESET_TAG;
     } else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
         familyData->currentTag = FILESET_TAG;
-    } else if (strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) {
+    } else if (len == 4 && strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) {
         // If it's a Name, parse the text inside
         XML_SetCharacterDataHandler(*familyData->parser, textHandler);
-    } else if (strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG) {
+    } else if (len == 4 && strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG) {
         // If it's a file, parse the attributes, then parse the text inside
         fontFileElementHandler(familyData, atts);
     }
@@ -136,10 +411,10 @@
  * Handler for the end of tags. We only care about family, nameset, fileset,
  * name, and file.
  */
-static void endElementHandler(void *data, const char *tag) {
-    FamilyData *familyData = (FamilyData*) data;
-    int len = strlen(tag);
-    if (strncmp(tag, "family", len)== 0) {
+static void endElementHandler(void* data, const char* tag) {
+    FamilyData* familyData = (FamilyData*) data;
+    size_t len = strlen(tag);
+    if (len == 6 && strncmp(tag, "family", len)== 0) {
         // Done parsing a Family - store the created currentFamily in the families array
         *familyData->families.append() = familyData->currentFamily;
         familyData->currentFamily = NULL;
@@ -147,52 +422,26 @@
         familyData->currentTag = NO_TAG;
     } else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
         familyData->currentTag = NO_TAG;
-    } else if ((strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) ||
-            (strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG)) {
+    } else if ((len == 4 &&
+                strncmp(tag, "name", len) == 0 &&
+                familyData->currentTag == NAMESET_TAG) ||
+               (len == 4 &&
+                strncmp(tag, "file", len) == 0 &&
+                familyData->currentTag == FILESET_TAG)) {
         // Disable the arbitrary text handler installed to load Name data
         XML_SetCharacterDataHandler(*familyData->parser, NULL);
     }
 }
 
+} // namespace jbParser
+
 /**
  * This function parses the given filename and stores the results in the given
  * families array.
  */
-static void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &families) {
+static void parseConfigFile(const char* filename, SkTDArray<FontFamily*> &families) {
 
-    FILE* file = NULL;
-
-#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
-    // if we are using a version of Android prior to Android 4.2 (JellyBean MR1
-    // at API Level 17) then we need to look for files with a different suffix.
-    char sdkVersion[PROP_VALUE_MAX];
-    __system_property_get("ro.build.version.sdk", sdkVersion);
-    const int sdkVersionInt = atoi(sdkVersion);
-
-    if (0 != *sdkVersion && sdkVersionInt < 17) {
-        SkString basename;
-        SkString updatedFilename;
-        SkString locale = SkFontConfigParser::GetLocale();
-
-        basename.set(filename);
-        // Remove the .xml suffix. We'll add it back in a moment.
-        if (basename.endsWith(".xml")) {
-            basename.resize(basename.size()-4);
-        }
-        // Try first with language and region
-        updatedFilename.printf("%s-%s.xml", basename.c_str(), locale.c_str());
-        file = fopen(updatedFilename.c_str(), "r");
-        if (!file) {
-            // If not found, try next with just language
-            updatedFilename.printf("%s-%.2s.xml", basename.c_str(), locale.c_str());
-            file = fopen(updatedFilename.c_str(), "r");
-        }
-    }
-#endif
-
-    if (NULL == file) {
-        file = fopen(filename, "r");
-    }
+    FILE* file = fopen(filename, "r");
 
     // Some of the files we attempt to parse (in particular, /vendor/etc/fallback_fonts.xml)
     // are optional - failure here is okay because one of these optional files may not exist.
@@ -201,15 +450,16 @@
     }
 
     XML_Parser parser = XML_ParserCreate(NULL);
-    FamilyData *familyData = new FamilyData(&parser, families);
+    FamilyData* familyData = new FamilyData(&parser, families);
     XML_SetUserData(parser, familyData);
-    XML_SetElementHandler(parser, startElementHandler, endElementHandler);
+    // Start parsing oldschool; switch these in flight if we detect a newer version of the file.
+    XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endElementHandler);
 
     char buffer[512];
     bool done = false;
     while (!done) {
         fgets(buffer, sizeof(buffer), file);
-        int len = strlen(buffer);
+        size_t len = strlen(buffer);
         if (feof(file) != 0) {
             done = true;
         }
@@ -220,7 +470,66 @@
 }
 
 static void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
-    parseConfigFile(SYSTEM_FONTS_FILE, fontFamilies);
+    int initialCount = fontFamilies.count();
+    parseConfigFile(LMP_SYSTEM_FONTS_FILE, fontFamilies);
+
+    if (initialCount == fontFamilies.count()) {
+        parseConfigFile(OLD_SYSTEM_FONTS_FILE, fontFamilies);
+    }
+}
+
+/**
+ * In some versions of Android prior to Android 4.2 (JellyBean MR1 at API
+ * Level 17) the fallback fonts for certain locales were encoded in their own
+ * XML files with a suffix that identified the locale.  We search the provided
+ * directory for those files,add all of their entries to the fallback chain, and
+ * include the locale as part of each entry.
+ */
+static void getFallbackFontFamiliesForLocale(SkTDArray<FontFamily*> &fallbackFonts, const char* dir) {
+#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
+    // The framework is beyond Android 4.2 and can therefore skip this function
+    return;
+#endif
+
+    DIR* fontDirectory = opendir(dir);
+    if (fontDirectory != NULL){
+        struct dirent* dirEntry = readdir(fontDirectory);
+        while (dirEntry) {
+
+            // The size of both the prefix, suffix, and a minimum valid language code
+            static const size_t minSize = strlen(LOCALE_FALLBACK_FONTS_PREFIX) +
+                                          strlen(LOCALE_FALLBACK_FONTS_SUFFIX) + 2;
+
+            SkString fileName(dirEntry->d_name);
+            if (fileName.size() >= minSize &&
+                    fileName.startsWith(LOCALE_FALLBACK_FONTS_PREFIX) &&
+                    fileName.endsWith(LOCALE_FALLBACK_FONTS_SUFFIX)) {
+
+                static const size_t fixedLen = strlen(LOCALE_FALLBACK_FONTS_PREFIX) -
+                                               strlen(LOCALE_FALLBACK_FONTS_SUFFIX);
+
+                SkString locale(fileName.c_str() - strlen(LOCALE_FALLBACK_FONTS_PREFIX),
+                                fileName.size() - fixedLen);
+
+                SkString absoluteFilename;
+                absoluteFilename.printf("%s/%s", dir, fileName.c_str());
+
+                SkTDArray<FontFamily*> langSpecificFonts;
+                parseConfigFile(absoluteFilename.c_str(), langSpecificFonts);
+
+                for (int i = 0; i < langSpecificFonts.count(); ++i) {
+                    FontFamily* family = langSpecificFonts[i];
+                    family->fLanguage = SkLanguage(locale);
+                    *fallbackFonts.append() = family;
+                }
+            }
+
+            // proceed to the next entry in the directory
+            dirEntry = readdir(fontDirectory);
+        }
+        // cleanup the directory reference
+        closedir(fontDirectory);
+    }
 }
 
 static void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts) {
@@ -228,12 +537,15 @@
     parseConfigFile(FALLBACK_FONTS_FILE, fallbackFonts);
     parseConfigFile(VENDOR_FONTS_FILE, vendorFonts);
 
+    getFallbackFontFamiliesForLocale(fallbackFonts, LOCALE_FALLBACK_FONTS_SYSTEM_DIR);
+    getFallbackFontFamiliesForLocale(vendorFonts, LOCALE_FALLBACK_FONTS_VENDOR_DIR);
+
     // This loop inserts the vendor fallback fonts in the correct order in the
     // overall fallbacks list.
     int currentOrder = -1;
     for (int i = 0; i < vendorFonts.count(); ++i) {
         FontFamily* family = vendorFonts[i];
-        int order = family->order;
+        int order = family->fOrder;
         if (order < 0) {
             if (currentOrder < 0) {
                 // Default case - just add it to the end of the fallback list
@@ -275,7 +587,9 @@
     parseConfigFile(testMainConfigFile, fontFamilies);
 
     SkTDArray<FontFamily*> fallbackFonts;
-    parseConfigFile(testFallbackConfigFile, fallbackFonts);
+    if (testFallbackConfigFile) {
+        parseConfigFile(testFallbackConfigFile, fallbackFonts);
+    }
 
     // Append all fallback fonts to system fonts
     for (int i = 0; i < fallbackFonts.count(); ++i) {
@@ -284,32 +598,15 @@
     }
 }
 
-/**
- * Read the persistent locale.
- */
-SkString SkFontConfigParser::GetLocale()
-{
-    char propLang[PROP_VALUE_MAX], propRegn[PROP_VALUE_MAX];
-    __system_property_get("persist.sys.language", propLang);
-    __system_property_get("persist.sys.country", propRegn);
+SkLanguage SkLanguage::getParent() const {
+    SkASSERT(!fTag.isEmpty());
+    const char* tag = fTag.c_str();
 
-    if (*propLang == 0 && *propRegn == 0) {
-        /* Set to ro properties, default is en_US */
-        __system_property_get("ro.product.locale.language", propLang);
-        __system_property_get("ro.product.locale.region", propRegn);
-        if (*propLang == 0 && *propRegn == 0) {
-            strcpy(propLang, "en");
-            strcpy(propRegn, "US");
-        }
+    // strip off the rightmost "-.*"
+    const char* parentTagEnd = strrchr(tag, '-');
+    if (parentTagEnd == NULL) {
+        return SkLanguage();
     }
-
-    SkString locale(6);
-    char* localeCStr = locale.writable_str();
-
-    strncpy(localeCStr, propLang, 2);
-    localeCStr[2] = '-';
-    strncpy(&localeCStr[3], propRegn, 2);
-    localeCStr[5] = '\0';
-
-    return locale;
+    size_t parentTagLen = parentTagEnd - tag;
+    return SkLanguage(tag, parentTagLen);
 }
diff --git a/src/ports/SkFontConfigParser_android.h b/src/ports/SkFontConfigParser_android.h
index e2247ef..117a108 100644
--- a/src/ports/SkFontConfigParser_android.h
+++ b/src/ports/SkFontConfigParser_android.h
@@ -8,32 +8,84 @@
 #ifndef SKFONTCONFIGPARSER_ANDROID_H_
 #define SKFONTCONFIGPARSER_ANDROID_H_
 
-#include "SkTypes.h"
-
-#include "SkPaintOptionsAndroid.h"
 #include "SkString.h"
 #include "SkTDArray.h"
 
+/** \class SkLanguage
+
+    The SkLanguage class represents a human written language, and is used by
+    text draw operations to determine which glyph to draw when drawing
+    characters with variants (ie Han-derived characters).
+*/
+class SkLanguage {
+public:
+    SkLanguage() { }
+    SkLanguage(const SkString& tag) : fTag(tag) { }
+    SkLanguage(const char* tag) : fTag(tag) { }
+    SkLanguage(const char* tag, size_t len) : fTag(tag, len) { }
+    SkLanguage(const SkLanguage& b) : fTag(b.fTag) { }
+
+    /** Gets a BCP 47 language identifier for this SkLanguage.
+        @return a BCP 47 language identifier representing this language
+    */
+    const SkString& getTag() const { return fTag; }
+
+    /** Performs BCP 47 fallback to return an SkLanguage one step more general.
+        @return an SkLanguage one step more general
+    */
+    SkLanguage getParent() const;
+
+    bool operator==(const SkLanguage& b) const {
+        return fTag == b.fTag;
+    }
+    bool operator!=(const SkLanguage& b) const {
+        return fTag != b.fTag;
+    }
+    SkLanguage& operator=(const SkLanguage& b) {
+        fTag = b.fTag;
+        return *this;
+    }
+
+private:
+    //! BCP 47 language identifier
+    SkString fTag;
+};
+
+enum FontVariants {
+   kDefault_FontVariant = 0x01,
+   kCompact_FontVariant = 0x02,
+   kElegant_FontVariant = 0x04,
+   kLast_FontVariant = kElegant_FontVariant,
+};
+typedef uint32_t FontVariant;
+
 struct FontFileInfo {
+    FontFileInfo() : fIndex(0), fWeight(0) { }
+
     SkString              fFileName;
-    SkPaintOptionsAndroid fPaintOptions;
+    int                   fIndex;
+    int                   fWeight;
 };
 
 /**
- * The FontFamily data structure is created during parsing and handed back to
- * Skia to fold into its representation of font families. fNames is the list of
- * font names that alias to a font family. fontFileArray is the list of information
- * about each file.  Order is the priority order for the font. This is
- * used internally to determine the order in which to place fallback fonts as
- * they are read from the configuration files.
+ * A font family provides one or more names for a collection of fonts, each of
+ * which has a different style (normal, italic) or weight (thin, light, bold,
+ * etc).
+ * Some fonts may occur in compact variants for use in the user interface.
+ * Android distinguishes "fallback" fonts to support non-ASCII character sets.
  */
 struct FontFamily {
-    FontFamily() : fIsFallbackFont(false), order(-1) {}
+    FontFamily()
+        : fVariant(kDefault_FontVariant)
+        , fOrder(-1)
+        , fIsFallbackFont(false) { }
 
-    SkTArray<SkString> fNames;
-    SkTArray<FontFileInfo> fFontFiles;
-    bool fIsFallbackFont;
-    int order; // only used internally by SkFontConfigParser
+    SkTArray<SkString>                 fNames;
+    SkTArray<FontFileInfo>             fFonts;
+    SkLanguage                         fLanguage;
+    FontVariant                        fVariant;
+    int                                fOrder; // internal to SkFontConfigParser
+    bool                               fIsFallbackFont;
 };
 
 namespace SkFontConfigParser {
@@ -52,8 +104,6 @@
                          const char* testMainConfigFile,
                          const char* testFallbackConfigFile);
 
-SkString GetLocale();
-
 } // SkFontConfigParser namespace
 
 #endif /* SKFONTCONFIGPARSER_ANDROID_H_ */
diff --git a/src/ports/SkFontConfigTypeface.h b/src/ports/SkFontConfigTypeface.h
index b6f8797..f62d99d 100644
--- a/src/ports/SkFontConfigTypeface.h
+++ b/src/ports/SkFontConfigTypeface.h
@@ -65,6 +65,7 @@
         SkSafeRef(localStream);
     }
 
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE;
     virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
 
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 12edc49..85f8ab9 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -143,13 +143,13 @@
 #elif defined(SK_CAN_USE_DLOPEN) && SK_CAN_USE_DLOPEN == 1
         //The FreeType library is already loaded, so symbols are available in process.
         void* self = dlopen(NULL, RTLD_LAZY);
-        if (NULL != self) {
+        if (self) {
             FT_Library_SetLcdFilterWeightsProc setLcdFilterWeights;
             //The following cast is non-standard, but safe for POSIX.
             *reinterpret_cast<void**>(&setLcdFilterWeights) = dlsym(self, "FT_Library_SetLcdFilterWeights");
             dlclose(self);
 
-            if (NULL != setLcdFilterWeights) {
+            if (setLcdFilterWeights) {
                 err = setLcdFilterWeights(gFTLibrary, gGaussianLikeHeavyWeights);
             }
         }
@@ -200,8 +200,7 @@
     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
-    virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
-                                     SkPaint::FontMetrics* my) SK_OVERRIDE;
+    virtual void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE;
     virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE;
 
 private:
@@ -317,7 +316,7 @@
     memset(&args, 0, sizeof(args));
     const void* memoryBase = strm->getMemoryBase();
 
-    if (NULL != memoryBase) {
+    if (memoryBase) {
 //printf("mmap(%s)\n", keyString.c_str());
         args.flags = FT_OPEN_MEMORY;
         args.memory_base = (const FT_Byte*)memoryBase;
@@ -954,6 +953,10 @@
             case SkPaint::kNormal_Hinting:
                 if (fRec.fFlags & SkScalerContext::kForceAutohinting_Flag) {
                     loadFlags = FT_LOAD_FORCE_AUTOHINT;
+#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
+                } else {
+                    loadFlags = FT_LOAD_NO_AUTOHINT;
+#endif
                 }
                 break;
             case SkPaint::kFull_Hinting:
@@ -1116,7 +1119,7 @@
         FT_Error    error;
         FT_Fixed    advance;
 
-        error = FT_Get_Advance( fFace, glyph->getGlyphID(fBaseGlyphCount),
+        error = FT_Get_Advance( fFace, glyph->getGlyphID(),
                                 fLoadGlyphFlags | FT_ADVANCE_FLAG_FAST_ONLY,
                                 &advance );
         if (0 == error) {
@@ -1218,11 +1221,11 @@
         goto ERROR;
     }
 
-    err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags );
+    err = FT_Load_Glyph( fFace, glyph->getGlyphID(), fLoadGlyphFlags );
     if (err != 0) {
 #if 0
         SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph(glyph:%d flags:%x) returned 0x%x\n",
-                    fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags, err));
+                    fFaceRec->fFontID, glyph->getGlyphID(), fLoadGlyphFlags, err));
 #endif
     ERROR:
         glyph->zeroMetrics();
@@ -1298,7 +1301,9 @@
         }
     }
 
-    if (fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP && fScaleY && fFace->size->metrics.y_ppem) {
+    // If the font isn't scalable, scale the metrics from the non-scalable strike.
+    // This means do not try to scale embedded bitmaps; only scale bitmaps in bitmap only fonts.
+    if (!FT_IS_SCALABLE(fFace) && fScaleY && fFace->size->metrics.y_ppem) {
         // NOTE: both dimensions are scaled by y_ppem. this is WAI.
         scaleGlyphMetrics(*glyph, SkScalarDiv(SkFixedToScalar(fScaleY),
                                               SkIntToScalar(fFace->size->metrics.y_ppem)));
@@ -1306,7 +1311,7 @@
 
 #ifdef ENABLE_GLYPH_SPEW
     SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY));
-    SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags, glyph->fWidth));
+    SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(), fLoadGlyphFlags, glyph->fWidth));
 #endif
 }
 
@@ -1320,10 +1325,10 @@
         goto ERROR;
     }
 
-    err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags);
+    err = FT_Load_Glyph( fFace, glyph.getGlyphID(), fLoadGlyphFlags);
     if (err != 0) {
         SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph:%d width:%d height:%d rb:%d flags:%d) returned 0x%x\n",
-                    glyph.getGlyphID(fBaseGlyphCount), glyph.fWidth, glyph.fHeight, glyph.rowBytes(), fLoadGlyphFlags, err));
+                    glyph.getGlyphID(), glyph.fWidth, glyph.fHeight, glyph.rowBytes(), fLoadGlyphFlags, err));
     ERROR:
         memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
         return;
@@ -1338,7 +1343,7 @@
                                             SkPath* path) {
     SkAutoMutexAcquire  ac(gFTMutex);
 
-    SkASSERT(&glyph && path);
+    SkASSERT(path);
 
     if (this->setupSize()) {
         path->reset();
@@ -1349,11 +1354,11 @@
     flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
     flags &= ~FT_LOAD_RENDER;   // don't scan convert (we just want the outline)
 
-    FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), flags);
+    FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(), flags);
 
     if (err != 0) {
         SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:%d flags:%d) returned 0x%x\n",
-                    glyph.getGlyphID(fBaseGlyphCount), flags, err));
+                    glyph.getGlyphID(), flags, err));
         path->reset();
         return;
     }
@@ -1372,22 +1377,16 @@
     }
 }
 
-void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
-                                                   SkPaint::FontMetrics* my) {
-    if (NULL == mx && NULL == my) {
+void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* metrics) {
+    if (NULL == metrics) {
         return;
     }
 
-    SkAutoMutexAcquire  ac(gFTMutex);
+    SkAutoMutexAcquire ac(gFTMutex);
 
     if (this->setupSize()) {
         ERROR:
-        if (mx) {
-            sk_bzero(mx, sizeof(SkPaint::FontMetrics));
-        }
-        if (my) {
-            sk_bzero(my, sizeof(SkPaint::FontMetrics));
-        }
+        sk_bzero(metrics, sizeof(*metrics));
         return;
     }
 
@@ -1434,14 +1433,9 @@
         underlinePosition = -SkIntToScalar(face->underline_position +
                                            face->underline_thickness / 2) / upem;
 
-        if(mx) {
-            mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-            mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
-        }
-        if(my){
-            my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-            my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
-        }
+        metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+        metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+
         // we may be able to synthesize x_height and cap_height from outline
         if (!x_height) {
             FT_BBox bbox;
@@ -1469,14 +1463,8 @@
         underlineThickness = 0;
         underlinePosition = 0;
 
-        if(mx) {
-            mx->fFlags &= ~SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-            mx->fFlags &= ~SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
-        }
-        if(my){
-            my->fFlags &= ~SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-            my->fFlags &= ~SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
-        }
+        metrics->fFlags &= ~SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+        metrics->fFlags &= ~SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
     } else {
         goto ERROR;
     }
@@ -1497,34 +1485,22 @@
         leading = 0.0f;
     }
 
-    if (mx) {
-        mx->fTop = ymax * mxy;
-        mx->fAscent = ascent * mxy;
-        mx->fDescent = descent * mxy;
-        mx->fBottom = ymin * mxy;
-        mx->fLeading = leading * mxy;
-        mx->fAvgCharWidth = avgCharWidth * mxy;
-        mx->fXMin = xmin;
-        mx->fXMax = xmax;
-        mx->fXHeight = x_height;
-        mx->fCapHeight = cap_height;
-        mx->fUnderlineThickness = underlineThickness * mxy;
-        mx->fUnderlinePosition = underlinePosition * mxy;
+    SkScalar scale = myy;
+    if (this->isVertical()) {
+        scale = mxy;
     }
-    if (my) {
-        my->fTop = ymax * myy;
-        my->fAscent = ascent * myy;
-        my->fDescent = descent * myy;
-        my->fBottom = ymin * myy;
-        my->fLeading = leading * myy;
-        my->fAvgCharWidth = avgCharWidth * myy;
-        my->fXMin = xmin;
-        my->fXMax = xmax;
-        my->fXHeight = x_height;
-        my->fCapHeight = cap_height;
-        my->fUnderlineThickness = underlineThickness * myy;
-        my->fUnderlinePosition = underlinePosition * myy;
-    }
+    metrics->fTop = ymax * scale;
+    metrics->fAscent = ascent * scale;
+    metrics->fDescent = descent * scale;
+    metrics->fBottom = ymin * scale;
+    metrics->fLeading = leading * scale;
+    metrics->fAvgCharWidth = avgCharWidth * scale;
+    metrics->fXMin = xmin;
+    metrics->fXMax = xmax;
+    metrics->fXHeight = x_height;
+    metrics->fCapHeight = cap_height;
+    metrics->fUnderlineThickness = underlineThickness * scale;
+    metrics->fUnderlinePosition = underlinePosition * scale;
 }
 
 void SkScalerContext_FreeType::emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph)
@@ -1534,13 +1510,6 @@
         return;
     }
 
-#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
-    // Android doesn't want to embolden a font that is already bold.
-    if ((fFace->style_flags & FT_STYLE_FLAG_BOLD)) {
-        return;
-    }
-#endif
-
     switch (glyph->format) {
         case FT_GLYPH_FORMAT_OUTLINE:
             FT_Pos strength;
@@ -1687,7 +1656,7 @@
         return 0;
     }
     FT_ULong size = SkTMin((FT_ULong)length, tableLength - (FT_ULong)offset);
-    if (NULL != data) {
+    if (data) {
         error = FT_Load_Sfnt_Table(face, tag, offset, reinterpret_cast<FT_Byte*>(data), &size);
         if (error) {
             return 0;
@@ -1700,11 +1669,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
-/*  Export this so that other parts of our FonttHost port can make use of our
-    ability to extract the name+style from a stream, using FreeType's api.
-*/
-bool find_name_and_attributes(SkStream* stream, SkString* name,
-                              SkTypeface::Style* style, bool* isFixedPitch) {
+/*static*/ bool SkTypeface_FreeType::ScanFont(
+    SkStream* stream, int ttcIndex, SkString* name, SkTypeface::Style* style, bool* isFixedPitch)
+{
     FT_Library  library;
     if (FT_Init_FreeType(&library)) {
         return false;
@@ -1716,7 +1683,7 @@
     const void* memoryBase = stream->getMemoryBase();
     FT_StreamRec    streamRec;
 
-    if (NULL != memoryBase) {
+    if (memoryBase) {
         args.flags = FT_OPEN_MEMORY;
         args.memory_base = (const FT_Byte*)memoryBase;
         args.memory_size = stream->getLength();
@@ -1732,7 +1699,7 @@
     }
 
     FT_Face face;
-    if (FT_Open_Face(library, &args, 0, &face)) {
+    if (FT_Open_Face(library, &args, ttcIndex, &face)) {
         FT_Done_FreeType(library);
         return false;
     }
diff --git a/src/ports/SkFontHost_FreeType_common.cpp b/src/ports/SkFontHost_FreeType_common.cpp
index b27ae96..b53f9e3 100644
--- a/src/ports/SkFontHost_FreeType_common.cpp
+++ b/src/ports/SkFontHost_FreeType_common.cpp
@@ -463,7 +463,7 @@
             canvas.scale(SkIntToScalar(glyph.fWidth) / SkIntToScalar(face->glyph->bitmap.width),
                          SkIntToScalar(glyph.fHeight) / SkIntToScalar(face->glyph->bitmap.rows));
             SkPaint paint;
-            paint.setFilterLevel(SkPaint::kLow_FilterLevel);
+            paint.setFilterLevel(SkPaint::kMedium_FilterLevel);
             canvas.drawBitmap(unscaledBitmap, 0, 0, &paint);
 
             // If the destination is BW or LCD, convert from A8.
diff --git a/src/ports/SkFontHost_FreeType_common.h b/src/ports/SkFontHost_FreeType_common.h
index aef4d82..f093dba 100644
--- a/src/ports/SkFontHost_FreeType_common.h
+++ b/src/ports/SkFontHost_FreeType_common.h
@@ -26,7 +26,6 @@
     #define SkASSERT_CONTINUE(pred)
 #endif
 
-
 class SkScalerContext_FreeType_Base : public SkScalerContext {
 protected:
     // See http://freetype.sourceforge.net/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden
@@ -45,6 +44,13 @@
 };
 
 class SkTypeface_FreeType : public SkTypeface {
+public:
+    /** For SkFontMgrs to make use of our ability to extract
+     *  name and style from a stream, using FreeType's API.
+     */
+    static bool ScanFont(SkStream* stream, int ttcIndex,
+                         SkString* name, SkTypeface::Style* style, bool* isFixedPitch);
+
 protected:
     SkTypeface_FreeType(Style style, SkFontID uniqueID, bool isFixedPitch)
         : INHERITED(style, uniqueID, isFixedPitch)
diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp
index 07bfbd0..b3a893e 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -15,10 +15,6 @@
 #include "SkTypeface.h"
 #include "SkTypefaceCache.h"
 
-// Defined in SkFontHost_FreeType.cpp
-bool find_name_and_attributes(SkStream* stream, SkString* name,
-                              SkTypeface::Style* style, bool* isFixedWidth);
-
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -50,7 +46,7 @@
         if (fci) {
             return fci;
         }
-        fci = SkFontConfigInterface::GetSingletonDirectInterface();
+        fci = SkFontConfigInterface::GetSingletonDirectInterface(&gFontConfigInterfaceMutex);
         SkFontConfigInterface::SetGlobal(fci);
     }
 }
@@ -124,45 +120,6 @@
     return face;
 }
 
-#ifdef SK_FONTHOST_DOES_NOT_USE_FONTMGR
-
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
-                                       const char familyName[],
-                                       SkTypeface::Style style) {
-    return FontConfigTypeface::LegacyCreateTypeface(familyFace, familyName,
-                                                    style);
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
-    if (!stream) {
-        return NULL;
-    }
-    const size_t length = stream->getLength();
-    if (!length) {
-        return NULL;
-    }
-    if (length >= 1024 * 1024 * 1024) {
-        return NULL;  // don't accept too large fonts (>= 1GB) for safety.
-    }
-
-    // ask freetype for reported style and if it is a fixed width font
-    SkTypeface::Style style = SkTypeface::kNormal;
-    bool isFixedWidth = false;
-    if (!find_name_and_attributes(stream, NULL, &style, &isFixedWidth)) {
-        return NULL;
-    }
-
-    SkTypeface* face = SkNEW_ARGS(FontConfigTypeface, (style, isFixedWidth, stream));
-    return face;
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
-    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
-    return stream.get() ? CreateTypefaceFromStream(stream) : NULL;
-}
-
-#endif
-
 ///////////////////////////////////////////////////////////////////////////////
 
 SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const {
@@ -180,7 +137,7 @@
         size_t length = stream->getLength();
 
         const void* memory = stream->getMemoryBase();
-        if (NULL != memory) {
+        if (memory) {
             return new SkMemoryStream(memory, length, true);
         }
 
@@ -205,8 +162,13 @@
     return stream;
 }
 
+void FontConfigTypeface::onGetFamilyName(SkString* familyName) const {
+    *familyName = this->getFamilyName();
+}
+
 void FontConfigTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
                                              bool* isLocalStream) const {
     desc->setFamilyName(this->getFamilyName());
+    desc->setFontIndex(this->getIdentity().fTTCIndex);
     *isLocalStream = SkToBool(this->getLocalStream());
 }
diff --git a/src/ports/SkFontHost_linux.cpp b/src/ports/SkFontHost_linux.cpp
index d6a0200..a4202aa 100644
--- a/src/ports/SkFontHost_linux.cpp
+++ b/src/ports/SkFontHost_linux.cpp
@@ -25,17 +25,15 @@
 #    define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/"
 #endif
 
-bool find_name_and_attributes(SkStream* stream, SkString* name,
-                              SkTypeface::Style* style, bool* isFixedPitch);
-
 ///////////////////////////////////////////////////////////////////////////////
 
 /** The base SkTypeface implementation for the custom font manager. */
 class SkTypeface_Custom : public SkTypeface_FreeType {
 public:
-    SkTypeface_Custom(Style style, bool sysFont, bool isFixedPitch, const SkString familyName)
+    SkTypeface_Custom(Style style, bool isFixedPitch,
+                      bool sysFont, const SkString familyName, int index)
         : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch)
-        , fIsSysFont(sysFont), fFamilyName(familyName)
+        , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
     { }
 
     bool isSysFont() const { return fIsSysFont; }
@@ -43,15 +41,23 @@
     virtual const char* getUniqueString() const = 0;
 
 protected:
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
+        *familyName = fFamilyName;
+    }
+
     virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const SK_OVERRIDE {
         desc->setFamilyName(fFamilyName.c_str());
         desc->setFontFileName(this->getUniqueString());
+        desc->setFontIndex(fIndex);
         *isLocal = !this->isSysFont();
     }
 
+    int getIndex() const { return fIndex; }
+
 private:
-    bool fIsSysFont;
-    SkString fFamilyName;
+    const bool fIsSysFont;
+    const SkString fFamilyName;
+    const int fIndex;
 
     typedef SkTypeface_FreeType INHERITED;
 };
@@ -61,7 +67,7 @@
  */
 class SkTypeface_Empty : public SkTypeface_Custom {
 public:
-    SkTypeface_Empty() : INHERITED(SkTypeface::kNormal, true, false, SkString()) {}
+    SkTypeface_Empty() : INHERITED(SkTypeface::kNormal, false, true, SkString(), 0) {}
 
     virtual const char* getUniqueString() const SK_OVERRIDE { return NULL; }
 
@@ -75,9 +81,9 @@
 /** The stream SkTypeface implementation for the custom font manager. */
 class SkTypeface_Stream : public SkTypeface_Custom {
 public:
-    SkTypeface_Stream(Style style, bool sysFont, SkStream* stream,
-                      bool isFixedPitch, const SkString familyName)
-        : INHERITED(style, sysFont, isFixedPitch, familyName)
+    SkTypeface_Stream(Style style, bool isFixedPitch, bool sysFont, const SkString familyName,
+                      SkStream* stream, int ttcIndex)
+        : INHERITED(style, isFixedPitch, sysFont, familyName, ttcIndex)
         , fStream(SkRef(stream))
     { }
 
@@ -85,12 +91,12 @@
 
 protected:
     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
-        *ttcIndex = 0;
+        *ttcIndex = this->getIndex();
         return fStream->duplicate();
     }
 
 private:
-    SkAutoTUnref<SkStream> fStream;
+    const SkAutoTUnref<const SkStream> fStream;
 
     typedef SkTypeface_Custom INHERITED;
 };
@@ -98,9 +104,9 @@
 /** The file SkTypeface implementation for the custom font manager. */
 class SkTypeface_File : public SkTypeface_Custom {
 public:
-    SkTypeface_File(Style style, bool sysFont, const char path[],
-                    bool isFixedPitch, const SkString familyName)
-        : INHERITED(style, sysFont, isFixedPitch, familyName)
+    SkTypeface_File(Style style, bool isFixedPitch, bool sysFont, const SkString familyName,
+                    const char path[], int index)
+        : INHERITED(style, isFixedPitch, sysFont, familyName, index)
         , fPath(path)
     { }
 
@@ -114,7 +120,7 @@
 
 protected:
     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
-        *ttcIndex = 0;
+        *ttcIndex = this->getIndex();
         return SkStream::NewFromFile(fPath.c_str());
     }
 
@@ -269,8 +275,9 @@
         bool isFixedPitch;
         SkTypeface::Style style;
         SkString name;
-        if (find_name_and_attributes(stream, &name, &style, &isFixedPitch)) {
-            return SkNEW_ARGS(SkTypeface_Stream, (style, false, stream, isFixedPitch, name));
+        if (SkTypeface_FreeType::ScanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) {
+            return SkNEW_ARGS(SkTypeface_Stream, (style, isFixedPitch, false, name,
+                                                  stream, ttcIndex));
         } else {
             return NULL;
         }
@@ -294,7 +301,7 @@
                                                  : SkFontStyle::kUpright_Slant);
         SkTypeface* tf = NULL;
 
-        if (NULL != familyName) {
+        if (familyName) {
             tf = this->onMatchFamilyStyle(familyName, style);
         }
 
@@ -311,7 +318,7 @@
                                    SkTypeface::Style* style, bool* isFixedPitch) {
         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
         if (stream.get()) {
-            return find_name_and_attributes(stream, name, style, isFixedPitch);
+            return SkTypeface_FreeType::ScanFont(stream, 0, name, style, isFixedPitch);
         } else {
             SkDebugf("---- failed to open <%s> as a font\n", path);
             return false;
@@ -324,7 +331,7 @@
 
         while (iter.next(&name, false)) {
             SkString filename(
-                SkOSPath::SkPathJoin(directory.c_str(), name.c_str()));
+                SkOSPath::Join(directory.c_str(), name.c_str()));
 
             bool isFixedPitch;
             SkString realname;
@@ -337,10 +344,10 @@
 
             SkTypeface_Custom* tf = SkNEW_ARGS(SkTypeface_File, (
                                                 style,
-                                                true,  // system-font (cannot delete)
-                                                filename.c_str(),
                                                 isFixedPitch,
-                                                realname));
+                                                true,  // system-font (cannot delete)
+                                                realname,
+                                                filename.c_str(), 0));
 
             SkFontStyleSet_Custom* addTo = this->onMatchFamily(realname.c_str());
             if (NULL == addTo) {
@@ -355,8 +362,7 @@
             if (name.startsWith(".")) {
                 continue;
             }
-            SkString dirname(
-                SkOSPath::SkPathJoin(directory.c_str(), name.c_str()));
+            SkString dirname(SkOSPath::Join(directory.c_str(), name.c_str()));
             load_directory_fonts(dirname);
         }
     }
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index e00b87b..aae7464 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -82,14 +82,10 @@
     ~AutoCFRelease() { CFSafeRelease(fCFRef); }
 
     void reset(CFRef that = NULL) {
-        CFSafeRetain(that);
-        CFSafeRelease(fCFRef);
-        fCFRef = that;
-    }
-
-    AutoCFRelease& operator =(CFRef that) {
-        reset(that);
-        return *this;
+        if (that != fCFRef) {
+            CFSafeRelease(fCFRef);
+            fCFRef = that;
+        }
     }
 
     operator CFRef() const { return fCFRef; }
@@ -426,21 +422,23 @@
 class SkTypeface_Mac : public SkTypeface {
 public:
     SkTypeface_Mac(SkTypeface::Style style, SkFontID fontID, bool isFixedPitch,
-                   CTFontRef fontRef, const char name[])
+                   CTFontRef fontRef, const char name[], bool isLocalStream)
         : SkTypeface(style, fontID, isFixedPitch)
         , fName(name)
         , fFontRef(fontRef) // caller has already called CFRetain for us
         , fFontStyle(stylebits2fontstyle(style))
+        , fIsLocalStream(isLocalStream)
     {
         SkASSERT(fontRef);
     }
 
     SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch,
-                   CTFontRef fontRef, const char name[])
+                   CTFontRef fontRef, const char name[], bool isLocalStream)
         : SkTypeface(fontstyle2stylebits(fs), fontID, isFixedPitch)
         , fName(name)
         , fFontRef(fontRef) // caller has already called CFRetain for us
         , fFontStyle(fs)
+        , fIsLocalStream(isLocalStream)
     {
         SkASSERT(fontRef);
     }
@@ -454,6 +452,7 @@
 
     virtual int onGetUPEM() const SK_OVERRIDE;
     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE;
     virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
     virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
     virtual size_t onGetTableData(SkFontTableTag, size_t offset,
@@ -469,17 +468,18 @@
     virtual int onCountGlyphs() const SK_OVERRIDE;
 
 private:
+    bool fIsLocalStream;
 
     typedef SkTypeface INHERITED;
 };
 
-static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[]) {
+static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isLocalStream) {
     SkASSERT(fontRef);
     bool isFixedPitch;
     SkTypeface::Style style = computeStyleBits(fontRef, &isFixedPitch);
     SkFontID fontID = CTFontRef_to_SkFontID(fontRef);
 
-    return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name);
+    return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLocalStream);
 }
 
 static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theStyle) {
@@ -524,12 +524,12 @@
         }
     }
 
-    return ctFont ? NewFromFontRef(ctFont, familyName) : NULL;
+    return ctFont ? NewFromFontRef(ctFont, familyName, false) : NULL;
 }
 
+SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex);
 static SkTypeface* GetDefaultFace() {
-    SK_DECLARE_STATIC_MUTEX(gMutex);
-    SkAutoMutexAcquire ma(gMutex);
+    SkAutoMutexAcquire ma(gGetDefaultFaceMutex);
 
     static SkTypeface* gDefaultFace;
 
@@ -557,7 +557,7 @@
     if (face) {
         face->ref();
     } else {
-        face = NewFromFontRef(fontRef, NULL);
+        face = NewFromFontRef(fontRef, NULL, false);
         SkTypefaceCache::Add(face, face->style());
         // NewFromFontRef doesn't retain the parameter, but the typeface it
         // creates does release it in its destructor, so we balance that with
@@ -653,7 +653,7 @@
     void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
     void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
     void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
-    void generateFontMetrics(SkPaint::FontMetrics* mX, SkPaint::FontMetrics* mY) SK_OVERRIDE;
+    void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE;
 
 private:
     static void CTPathElement(void *info, const CGPathElement *element);
@@ -746,16 +746,16 @@
             AutoCFRelease<CFNumberRef> cfVertical(CFNumberCreate(
                     kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientation));
             CFDictionaryAddValue(cfAttributes, kCTFontOrientationAttribute, cfVertical);
-            ctFontDesc = CTFontDescriptorCreateWithAttributes(cfAttributes);
+            ctFontDesc.reset(CTFontDescriptorCreateWithAttributes(cfAttributes));
         }
     }
     // Since our matrix includes everything, we pass 1 for size.
-    fCTFont = CTFontCreateCopyWithAttributes(ctFont, 1, &transform, ctFontDesc);
-    fCGFont = CTFontCopyGraphicsFont(fCTFont, NULL);
+    fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, 1, &transform, ctFontDesc));
+    fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, NULL));
     if (fVertical) {
         CGAffineTransform rotateLeft = CGAffineTransformMake(0, -1, 1, 0, 0, 0);
         transform = CGAffineTransformConcat(rotateLeft, transform);
-        fCTVerticalFont = CTFontCreateCopyWithAttributes(ctFont, 1, &transform, NULL);
+        fCTVerticalFont.reset(CTFontCreateCopyWithAttributes(ctFont, 1, &transform, NULL));
     }
 
     SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont)));
@@ -769,7 +769,7 @@
         //It doesn't appear to matter what color space is specified.
         //Regular blends and antialiased text are always (s*a + d*(1-a))
         //and smoothed text is always g=2.0.
-        fRGBSpace = CGColorSpaceCreateDeviceRGB();
+        fRGBSpace.reset(CGColorSpaceCreateDeviceRGB());
     }
 
     // default to kBW_Format
@@ -798,8 +798,8 @@
 
         rowBytes = fSize.fWidth * sizeof(CGRGBPixel);
         void* image = fImageStorage.reset(rowBytes * fSize.fHeight);
-        fCG = CGBitmapContextCreate(image, fSize.fWidth, fSize.fHeight, 8,
-                                    rowBytes, fRGBSpace, BITMAP_INFO_RGB);
+        fCG.reset(CGBitmapContextCreate(image, fSize.fWidth, fSize.fHeight, 8,
+                                        rowBytes, fRGBSpace, BITMAP_INFO_RGB));
 
         // skia handles quantization itself, so we disable this for cg to get
         // full fractional data from them.
@@ -898,7 +898,7 @@
 
 bool SkScalerContext_Mac::generateBBoxes() {
     if (fGeneratedFBoundingBoxes) {
-        return NULL != fFBoundingBoxes.get();
+        return SkToBool(fFBoundingBoxes.get());
     }
     fGeneratedFBoundingBoxes = true;
 
@@ -959,7 +959,7 @@
 }
 
 void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) {
-    const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID(fBaseGlyphCount);
+    const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID();
     glyph->zeroMetrics();
 
     // The following block produces cgAdvance in CG units (pixels, y up).
@@ -1204,7 +1204,7 @@
 }
 
 void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
-    CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(fBaseGlyphCount);
+    CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID();
 
     // FIXME: lcd smoothed un-hinted rasterization unsupported.
     bool generateA8FromLCD = fRec.getHinting() != SkPaint::kNo_Hinting;
@@ -1343,7 +1343,7 @@
         font = CTFontCreateCopyWithAttributes(fCTFont, 1, &xform, NULL);
     }
 
-    CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(fBaseGlyphCount);
+    CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID();
     AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, NULL));
 
     path->reset();
@@ -1365,32 +1365,27 @@
     }
 }
 
-void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* mx,
-                                              SkPaint::FontMetrics* my) {
+void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) {
+    if (NULL == metrics) {
+        return;
+    }
+
     CGRect theBounds = CTFontGetBoundingBox(fCTFont);
 
-    SkPaint::FontMetrics theMetrics;
-    theMetrics.fTop          = CGToScalar(-CGRectGetMaxY_inline(theBounds));
-    theMetrics.fAscent       = CGToScalar(-CTFontGetAscent(fCTFont));
-    theMetrics.fDescent      = CGToScalar( CTFontGetDescent(fCTFont));
-    theMetrics.fBottom       = CGToScalar(-CGRectGetMinY_inline(theBounds));
-    theMetrics.fLeading      = CGToScalar( CTFontGetLeading(fCTFont));
-    theMetrics.fAvgCharWidth = CGToScalar( CGRectGetWidth_inline(theBounds));
-    theMetrics.fXMin         = CGToScalar( CGRectGetMinX_inline(theBounds));
-    theMetrics.fXMax         = CGToScalar( CGRectGetMaxX_inline(theBounds));
-    theMetrics.fXHeight      = CGToScalar( CTFontGetXHeight(fCTFont));
-    theMetrics.fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont));
-    theMetrics.fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont));
+    metrics->fTop          = CGToScalar(-CGRectGetMaxY_inline(theBounds));
+    metrics->fAscent       = CGToScalar(-CTFontGetAscent(fCTFont));
+    metrics->fDescent      = CGToScalar( CTFontGetDescent(fCTFont));
+    metrics->fBottom       = CGToScalar(-CGRectGetMinY_inline(theBounds));
+    metrics->fLeading      = CGToScalar( CTFontGetLeading(fCTFont));
+    metrics->fAvgCharWidth = CGToScalar( CGRectGetWidth_inline(theBounds));
+    metrics->fXMin         = CGToScalar( CGRectGetMinX_inline(theBounds));
+    metrics->fXMax         = CGToScalar( CGRectGetMaxX_inline(theBounds));
+    metrics->fXHeight      = CGToScalar( CTFontGetXHeight(fCTFont));
+    metrics->fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont));
+    metrics->fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont));
 
-    theMetrics.fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-    theMetrics.fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
-
-    if (mx != NULL) {
-        *mx = theMetrics;
-    }
-    if (my != NULL) {
-        *my = theMetrics;
-    }
+    metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+    metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
 }
 
 void SkScalerContext_Mac::CTPathElement(void *info, const CGPathElement *element) {
@@ -1438,7 +1433,7 @@
         return NULL;
     }
     CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, NULL, NULL);
-    return cg ? SkCreateTypefaceFromCTFont(ct) : NULL;
+    return ct ? NewFromFontRef(ct, NULL, true) : NULL;
 }
 
 // Web fonts added to the the CTFont registry do not return their character set.
@@ -1517,7 +1512,7 @@
     return true;
 }
 
-// we might move this into our CGUtils...
+/** Assumes src and dst are not NULL. */
 static void CFStringToSkString(CFStringRef src, SkString* dst) {
     // Reserve enough room for the worst-case string,
     // plus 1 byte for the trailing null.
@@ -1541,7 +1536,9 @@
 
     {
         AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont));
-        CFStringToSkString(fontName, &info->fFontName);
+        if (fontName.get()) {
+            CFStringToSkString(fontName, &info->fFontName);
+        }
     }
 
     CFIndex glyphCount = CTFontGetGlyphCount(ctFont);
@@ -1896,11 +1893,18 @@
 
 // we take ownership of the ref
 static const char* get_str(CFStringRef ref, SkString* str) {
+    if (NULL == ref) {
+        return NULL;
+    }
     CFStringToSkString(ref, str);
     CFSafeRelease(ref);
     return str->c_str();
 }
 
+void SkTypeface_Mac::onGetFamilyName(SkString* familyName) const {
+    get_str(CTFontCopyFamilyName(fFontRef), familyName);
+}
+
 void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc,
                                          bool* isLocalStream) const {
     SkString tmpStr;
@@ -1908,8 +1912,7 @@
     desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr));
     desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr));
     desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr));
-    // TODO: need to add support for local-streams (here and openStream)
-    *isLocalStream = false;
+    *isLocalStream = fIsLocalStream;
 }
 
 int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding,
@@ -1978,10 +1981,10 @@
     if (srcCount > glyphCount) {
         int extra = 0;
         for (int i = 0; i < glyphCount; ++i) {
+            compactedGlyphs[i] = macGlyphs[i + extra];
             if (SkUTF16_IsHighSurrogate(src[i + extra])) {
                 ++extra;
             }
-            compactedGlyphs[i] = macGlyphs[i + extra];
         }
     }
 
@@ -2128,7 +2131,7 @@
     SkFontID fontID = CTFontRef_to_SkFontID(ctFont);
 
     face = SkNEW_ARGS(SkTypeface_Mac, (rec.fFontStyle, fontID, isFixedPitch,
-                                       ctFont, str.c_str()));
+                                       ctFont, str.c_str(), false));
     SkTypefaceCache::Add(face, face->style());
     return face;
 }
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 5a90214..1290c00 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -276,6 +276,7 @@
                                 uint16_t glyphs[], int glyphCount) const SK_OVERRIDE;
     virtual int onCountGlyphs() const SK_OVERRIDE;
     virtual int onGetUPEM() const SK_OVERRIDE;
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE;
     virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
     virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
     virtual size_t onGetTableData(SkFontTableTag, size_t offset,
@@ -559,8 +560,7 @@
     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
-    virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
-                                     SkPaint::FontMetrics* mY) SK_OVERRIDE;
+    virtual void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE;
 
 private:
     DWORD getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
@@ -874,7 +874,7 @@
 
     if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_GDI::kLine_Type) {
         SIZE size;
-        WORD glyphs = glyph->getGlyphID(0);
+        WORD glyphs = glyph->getGlyphID();
         if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) {
             glyph->fWidth = SkToS16(fTM.tmMaxCharWidth);
         } else {
@@ -912,7 +912,7 @@
         return;
     }
 
-    UINT glyphId = glyph->getGlyphID(0);
+    UINT glyphId = glyph->getGlyphID();
 
     GLYPHMETRICS gm;
     sk_bzero(&gm, sizeof(gm));
@@ -978,43 +978,27 @@
 }
 
 static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
-void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {
-    if (!(mx || my)) {
-      return;
+void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* metrics) {
+    if (NULL == metrics) {
+        return;
     }
-
-    if (mx) {
-        sk_bzero(mx, sizeof(*mx));
-    }
-    if (my) {
-        sk_bzero(my, sizeof(*my));
-    }
+    sk_bzero(metrics, sizeof(*metrics));
 
     SkASSERT(fDDC);
 
 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
     if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_GDI::kLine_Type) {
 #endif
-        if (mx) {
-            mx->fTop = SkIntToScalar(-fTM.tmAscent);
-            mx->fAscent = SkIntToScalar(-fTM.tmAscent);
-            mx->fDescent = SkIntToScalar(fTM.tmDescent);
-            mx->fBottom = SkIntToScalar(fTM.tmDescent);
-            mx->fLeading = SkIntToScalar(fTM.tmExternalLeading);
-        }
-
-        if (my) {
-            my->fTop = SkIntToScalar(-fTM.tmAscent);
-            my->fAscent = SkIntToScalar(-fTM.tmAscent);
-            my->fDescent = SkIntToScalar(fTM.tmDescent);
-            my->fBottom = SkIntToScalar(fTM.tmDescent);
-            my->fLeading = SkIntToScalar(fTM.tmExternalLeading);
-            my->fAvgCharWidth = SkIntToScalar(fTM.tmAveCharWidth);
-            my->fMaxCharWidth = SkIntToScalar(fTM.tmMaxCharWidth);
-            my->fXMin = 0;
-            my->fXMax = my->fMaxCharWidth;
-            //my->fXHeight = 0;
-        }
+        metrics->fTop = SkIntToScalar(-fTM.tmAscent);
+        metrics->fAscent = SkIntToScalar(-fTM.tmAscent);
+        metrics->fDescent = SkIntToScalar(fTM.tmDescent);
+        metrics->fBottom = SkIntToScalar(fTM.tmDescent);
+        metrics->fLeading = SkIntToScalar(fTM.tmExternalLeading);
+        metrics->fAvgCharWidth = SkIntToScalar(fTM.tmAveCharWidth);
+        metrics->fMaxCharWidth = SkIntToScalar(fTM.tmMaxCharWidth);
+        metrics->fXMin = 0;
+        metrics->fXMax = metrics->fMaxCharWidth;
+        //metrics->fXHeight = 0;
 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
         return;
     }
@@ -1031,45 +1015,29 @@
         return;
     }
 
-    if (mx) {
-        mx->fTop = SkIntToScalar(-otm.otmrcFontBox.left);
-        mx->fAscent = SkIntToScalar(-otm.otmAscent);
-        mx->fDescent = SkIntToScalar(-otm.otmDescent);
-        mx->fBottom = SkIntToScalar(otm.otmrcFontBox.right);
-        mx->fLeading = SkIntToScalar(otm.otmLineGap);
-        mx->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize);
-        mx->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition);
-
-        mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-        mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
-    }
-
-    if (my) {
 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
-        my->fTop = SkIntToScalar(-otm.otmrcFontBox.top);
-        my->fAscent = SkIntToScalar(-otm.otmAscent);
-        my->fDescent = SkIntToScalar(-otm.otmDescent);
-        my->fBottom = SkIntToScalar(-otm.otmrcFontBox.bottom);
-        my->fLeading = SkIntToScalar(otm.otmLineGap);
-        my->fAvgCharWidth = SkIntToScalar(otm.otmTextMetrics.tmAveCharWidth);
-        my->fMaxCharWidth = SkIntToScalar(otm.otmTextMetrics.tmMaxCharWidth);
-        my->fXMin = SkIntToScalar(otm.otmrcFontBox.left);
-        my->fXMax = SkIntToScalar(otm.otmrcFontBox.right);
+    metrics->fTop = SkIntToScalar(-otm.otmrcFontBox.top);
+    metrics->fAscent = SkIntToScalar(-otm.otmAscent);
+    metrics->fDescent = SkIntToScalar(-otm.otmDescent);
+    metrics->fBottom = SkIntToScalar(-otm.otmrcFontBox.bottom);
+    metrics->fLeading = SkIntToScalar(otm.otmLineGap);
+    metrics->fAvgCharWidth = SkIntToScalar(otm.otmTextMetrics.tmAveCharWidth);
+    metrics->fMaxCharWidth = SkIntToScalar(otm.otmTextMetrics.tmMaxCharWidth);
+    metrics->fXMin = SkIntToScalar(otm.otmrcFontBox.left);
+    metrics->fXMax = SkIntToScalar(otm.otmrcFontBox.right);
 #endif
-        my->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize);
-        my->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition);
+    metrics->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize);
+    metrics->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition);
 
-        my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-        my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+    metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+    metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
 
-        my->fXHeight = SkIntToScalar(otm.otmsXHeight);
-
-        GLYPHMETRICS gm;
-        sk_bzero(&gm, sizeof(gm));
-        DWORD len = GetGlyphOutlineW(fDDC, 'x', GGO_METRICS, &gm, 0, 0, &gMat2Identity);
-        if (len != GDI_ERROR && gm.gmBlackBoxY > 0) {
-            my->fXHeight = SkIntToScalar(gm.gmBlackBoxY);
-        }
+    metrics->fXHeight = SkIntToScalar(otm.otmsXHeight);
+    GLYPHMETRICS gm;
+    sk_bzero(&gm, sizeof(gm));
+    DWORD len = GetGlyphOutlineW(fDDC, 'x', GGO_METRICS, &gm, 0, 0, &gMat2Identity);
+    if (len != GDI_ERROR && gm.gmBlackBoxY > 0) {
+        metrics->fXHeight = SkIntToScalar(gm.gmBlackBoxY);
     }
 }
 
@@ -1706,7 +1674,8 @@
             LogFontTypeface::EnsureAccessible(this->getTypeface());
             total_size = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, 0, NULL, &fMat22);
             if (GDI_ERROR == total_size) {
-                SkASSERT(false);
+                // GetGlyphOutlineW is known to fail for some characters, such as spaces.
+                // In these cases, just return that the glyph does not have a shape.
                 return 0;
             }
         }
@@ -1793,16 +1762,14 @@
 #endif
 }
 
-void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
-                                          bool* isLocalStream) const {
+void LogFontTypeface::onGetFamilyName(SkString* familyName) const {
     // Get the actual name of the typeface. The logfont may not know this.
     HFONT font = CreateFontIndirect(&fLogFont);
 
     HDC deviceContext = ::CreateCompatibleDC(NULL);
     HFONT savefont = (HFONT)SelectObject(deviceContext, font);
 
-    SkString familyName;
-    dcfontname_to_skstring(deviceContext, fLogFont, &familyName);
+    dcfontname_to_skstring(deviceContext, fLogFont, familyName);
 
     if (deviceContext) {
         ::SelectObject(deviceContext, savefont);
@@ -1811,7 +1778,12 @@
     if (font) {
         ::DeleteObject(font);
     }
+}
 
+void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
+                                          bool* isLocalStream) const {
+    SkString familyName;
+    this->onGetFamilyName(&familyName);
     desc->setFamilyName(familyName.c_str());
     *isLocalStream = this->fSerializeAsStream;
 }
@@ -2408,7 +2380,8 @@
         rec->fFlags |= SkScalerContext::kGenA8FromLCD_Flag;
     }
 
-    unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
+    unsigned flagsWeDontSupport = SkScalerContext::kVertical_Flag |
+                                  SkScalerContext::kDevKernText_Flag |
                                   SkScalerContext::kForceAutohinting_Flag |
                                   SkScalerContext::kEmbeddedBitmapText_Flag |
                                   SkScalerContext::kEmbolden_Flag |
diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp
new file mode 100644
index 0000000..1126b75
--- /dev/null
+++ b/src/ports/SkFontMgr_android.cpp
@@ -0,0 +1,568 @@
+/*
+ * 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 "SkFontConfigParser_android.h"
+#include "SkFontDescriptor.h"
+#include "SkFontHost_FreeType_common.h"
+#include "SkFontMgr.h"
+#include "SkFontStyle.h"
+#include "SkStream.h"
+#include "SkTDArray.h"
+#include "SkTSearch.h"
+#include "SkTypeface.h"
+#include "SkTypeface_android.h"
+#include "SkTypefaceCache.h"
+
+#include <limits>
+#include <stdlib.h>
+
+#ifndef SK_FONT_FILE_PREFIX
+#    define SK_FONT_FILE_PREFIX "/fonts/"
+#endif
+
+#ifndef SK_DEBUG_FONTS
+    #define SK_DEBUG_FONTS 0
+#endif
+
+#if SK_DEBUG_FONTS
+#    define DEBUG_FONT(args) SkDebugf args
+#else
+#    define DEBUG_FONT(args)
+#endif
+
+// For test only.
+static const char* gTestMainConfigFile = NULL;
+static const char* gTestFallbackConfigFile = NULL;
+static const char* gTestFontFilePrefix = NULL;
+
+class SkTypeface_Android : public SkTypeface_FreeType {
+public:
+    SkTypeface_Android(int index,
+                       Style style,
+                       bool isFixedPitch,
+                       const SkString familyName)
+        : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch)
+        , fIndex(index)
+        , fFamilyName(familyName) { }
+
+protected:
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
+        *familyName = fFamilyName;
+    }
+
+    int fIndex;
+    SkString fFamilyName;
+
+private:
+    typedef SkTypeface_FreeType INHERITED;
+};
+
+class SkTypeface_AndroidSystem : public SkTypeface_Android {
+public:
+    SkTypeface_AndroidSystem(const SkString pathName,
+                             int index,
+                             Style style,
+                             bool isFixedPitch,
+                             const SkString familyName,
+                             const SkLanguage& lang,
+                             FontVariant variantStyle)
+        : INHERITED(index, style, isFixedPitch, familyName)
+        , fPathName(pathName)
+        , fLang(lang)
+        , fVariantStyle(variantStyle) { }
+
+    virtual void onGetFontDescriptor(SkFontDescriptor* desc,
+                                     bool* serialize) const SK_OVERRIDE {
+        SkASSERT(desc);
+        SkASSERT(serialize);
+        desc->setFamilyName(fFamilyName.c_str());
+        desc->setFontFileName(fPathName.c_str());
+        desc->setFontIndex(fIndex);
+        *serialize = false;
+    }
+    virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
+        *ttcIndex = fIndex;
+        return SkStream::NewFromFile(fPathName.c_str());
+    }
+
+    const SkString fPathName;
+    const SkLanguage fLang;
+    const FontVariant fVariantStyle;
+
+    typedef SkTypeface_Android INHERITED;
+};
+
+class SkTypeface_AndroidStream : public SkTypeface_Android {
+public:
+    SkTypeface_AndroidStream(SkStream* stream,
+                             int index,
+                             Style style,
+                             bool isFixedPitch,
+                             const SkString familyName)
+        : INHERITED(index, style, isFixedPitch, familyName)
+        , fStream(SkRef(stream)) { }
+
+    virtual void onGetFontDescriptor(SkFontDescriptor* desc,
+                                     bool* serialize) const SK_OVERRIDE {
+        SkASSERT(desc);
+        SkASSERT(serialize);
+        desc->setFamilyName(fFamilyName.c_str());
+        desc->setFontFileName(NULL);
+        *serialize = true;
+    }
+
+    virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
+        *ttcIndex = fIndex;
+        return fStream->duplicate();
+    }
+
+private:
+    SkAutoTUnref<SkStream> fStream;
+
+    typedef SkTypeface_Android INHERITED;
+};
+
+void get_path_for_sys_fonts(const char* basePath, const SkString& name, SkString* full) {
+    if (basePath) {
+        full->set(basePath);
+    } else {
+        full->set(getenv("ANDROID_ROOT"));
+        full->append(SK_FONT_FILE_PREFIX);
+    }
+    full->append(name);
+}
+
+class SkFontStyleSet_Android : public SkFontStyleSet {
+public:
+    explicit SkFontStyleSet_Android(const FontFamily& family, const char* basePath) {
+        const SkString* cannonicalFamilyName = NULL;
+        if (family.fNames.count() > 0) {
+            cannonicalFamilyName = &family.fNames[0];
+        }
+        // TODO? make this lazy
+        for (int i = 0; i < family.fFonts.count(); ++i) {
+            const FontFileInfo& fontFile = family.fFonts[i];
+
+            SkString pathName;
+            get_path_for_sys_fonts(basePath, fontFile.fFileName, &pathName);
+
+            SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(pathName.c_str()));
+            if (!stream.get()) {
+                DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, pathName.c_str()));
+                continue;
+            }
+
+            const int ttcIndex = fontFile.fIndex;
+            SkString familyName;
+            SkTypeface::Style style;
+            bool isFixedWidth;
+            if (!SkTypeface_FreeType::ScanFont(stream.get(), ttcIndex,
+                                               &familyName, &style, &isFixedWidth)) {
+                DEBUG_FONT(("---- SystemFonts[%d] file=%s (INVALID)", i, pathName.c_str()));
+                continue;
+            }
+
+            const SkLanguage& lang = family.fLanguage;
+            uint32_t variant = family.fVariant;
+            if (kDefault_FontVariant == variant) {
+                variant = kCompact_FontVariant | kElegant_FontVariant;
+            }
+
+            // The first specified family name overrides the family name found in the font.
+            // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return
+            // all of the specified family names in addition to the names found in the font.
+            if (cannonicalFamilyName != NULL) {
+                familyName = *cannonicalFamilyName;
+            }
+
+            fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem,
+                                                 (pathName, ttcIndex,
+                                                  style, isFixedWidth, familyName,
+                                                  lang, variant)));
+        }
+    }
+
+    virtual int count() SK_OVERRIDE {
+        return fStyles.count();
+    }
+    virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVERRIDE {
+        if (index < 0 || fStyles.count() <= index) {
+            return;
+        }
+        if (style) {
+            *style = this->style(index);
+        }
+        if (name) {
+            name->reset();
+        }
+    }
+    virtual SkTypeface_AndroidSystem* createTypeface(int index) SK_OVERRIDE {
+        if (index < 0 || fStyles.count() <= index) {
+            return NULL;
+        }
+        return SkRef(fStyles[index].get());
+    }
+
+    /** Find the typeface in this style set that most closely matches the given pattern.
+     *  TODO: consider replacing with SkStyleSet_Indirect::matchStyle();
+     *  this simpler version using match_score() passes all our tests.
+     */
+    virtual SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE {
+        if (0 == fStyles.count()) {
+            return NULL;
+        }
+        SkTypeface_AndroidSystem* closest = fStyles[0];
+        int minScore = std::numeric_limits<int>::max();
+        for (int i = 0; i < fStyles.count(); ++i) {
+            SkFontStyle style = this->style(i);
+            int score = match_score(pattern, style);
+            if (score < minScore) {
+                closest = fStyles[i];
+                minScore = score;
+            }
+        }
+        return SkRef(closest);
+    }
+
+private:
+    SkFontStyle style(int index) {
+        return SkFontStyle(this->weight(index), SkFontStyle::kNormal_Width,
+                           this->slant(index));
+    }
+    SkFontStyle::Weight weight(int index) {
+        if (fStyles[index]->isBold()) return SkFontStyle::kBold_Weight;
+        return SkFontStyle::kNormal_Weight;
+    }
+    SkFontStyle::Slant slant(int index) {
+        if (fStyles[index]->isItalic()) return SkFontStyle::kItalic_Slant;
+        return SkFontStyle::kUpright_Slant;
+    }
+    static int match_score(const SkFontStyle& pattern, const SkFontStyle& candidate) {
+        int score = 0;
+        score += abs((pattern.width() - candidate.width()) * 100);
+        score += abs((pattern.isItalic() == candidate.isItalic()) ? 0 : 1000);
+        score += abs(pattern.weight() - candidate.weight());
+        return score;
+    }
+
+    SkTArray<SkAutoTUnref<SkTypeface_AndroidSystem>, true> fStyles;
+
+    friend struct NameToFamily;
+    friend class SkFontMgr_Android;
+
+    typedef SkFontStyleSet INHERITED;
+};
+
+/** On Android a single family can have many names, but our API assumes unique names.
+ *  Map names to the back end so that all names for a given family refer to the same
+ *  (non-replicated) set of typefaces.
+ *  SkTDict<> doesn't let us do index-based lookup, so we write our own mapping.
+ */
+struct NameToFamily {
+    SkString name;
+    SkFontStyleSet_Android* styleSet;
+};
+
+class SkFontMgr_Android : public SkFontMgr {
+public:
+    SkFontMgr_Android() {
+        SkTDArray<FontFamily*> fontFamilies;
+        SkFontConfigParser::GetFontFamilies(fontFamilies);
+        this->buildNameToFamilyMap(fontFamilies, NULL);
+        this->findDefaultFont();
+    }
+    SkFontMgr_Android(const char* mainConfigFile, const char* fallbackConfigFile,
+                      const char* basePath)
+    {
+        SkTDArray<FontFamily*> fontFamilies;
+        SkFontConfigParser::GetTestFontFamilies(fontFamilies, mainConfigFile, fallbackConfigFile);
+        this->buildNameToFamilyMap(fontFamilies, basePath);
+        this->findDefaultFont();
+    }
+
+protected:
+    /** Returns not how many families we have, but how many unique names
+     *  exist among the families.
+     */
+    virtual int onCountFamilies() const SK_OVERRIDE {
+        return fNameToFamilyMap.count();
+    }
+
+    virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE {
+        if (index < 0 || fNameToFamilyMap.count() <= index) {
+            familyName->reset();
+            return;
+        }
+        familyName->set(fNameToFamilyMap[index].name);
+    }
+
+    virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE {
+        if (index < 0 || fNameToFamilyMap.count() <= index) {
+            return NULL;
+        }
+        return SkRef(fNameToFamilyMap[index].styleSet);
+    }
+
+    virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
+        if (!familyName) {
+            return NULL;
+        }
+        SkAutoAsciiToLC tolc(familyName);
+        for (int i = 0; i < fNameToFamilyMap.count(); ++i) {
+            if (fNameToFamilyMap[i].name.equals(tolc.lc())) {
+                return SkRef(fNameToFamilyMap[i].styleSet);
+            }
+        }
+        // TODO: eventually we should not need to name fallback families.
+        for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) {
+            if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) {
+                return SkRef(fFallbackNameToFamilyMap[i].styleSet);
+            }
+        }
+        return NULL;
+    }
+
+    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
+                                           const SkFontStyle& style) const SK_OVERRIDE {
+        SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
+        return sset->matchStyle(style);
+    }
+
+    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface,
+                                         const SkFontStyle& style) const SK_OVERRIDE {
+        for (int i = 0; i < fFontStyleSets.count(); ++i) {
+            for (int j = 0; j < fFontStyleSets[i]->fStyles.count(); ++j) {
+                if (fFontStyleSets[i]->fStyles[j] == typeface) {
+                    return fFontStyleSets[i]->matchStyle(style);
+                }
+            }
+        }
+        return NULL;
+    }
+
+static SkTypeface_AndroidSystem* find_family_style_character(
+        const SkTDArray<NameToFamily>& fallbackNameToFamilyMap,
+        const SkFontStyle& style, bool elegant,
+        const SkString& langTag, SkUnichar character)
+{
+    for (int i = 0; i < fallbackNameToFamilyMap.count(); ++i) {
+        SkFontStyleSet_Android* family = fallbackNameToFamilyMap[i].styleSet;
+        SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(style));
+
+        if (!langTag.isEmpty() && !face->fLang.getTag().startsWith(langTag.c_str())) {
+            continue;
+        }
+
+        if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) {
+            continue;
+        }
+
+        SkPaint paint;
+        paint.setTypeface(face);
+        paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
+
+        uint16_t glyphID;
+        paint.textToGlyphs(&character, sizeof(character), &glyphID);
+        if (glyphID != 0) {
+            return face.detach();
+        }
+    }
+    return NULL;
+}
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
+    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+                                                    const SkFontStyle& style,
+                                                    const char* bcp47[],
+                                                    int bcp47Count,
+                                                    SkUnichar character) const SK_OVERRIDE
+    {
+#else
+    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+                                                    const SkFontStyle& style,
+                                                    const char bcp47_val[],
+                                                    SkUnichar character) const SK_OVERRIDE
+    {
+        const char** bcp47 = &bcp47_val;
+        int bcp47Count = bcp47_val ? 1 : 0;
+#endif
+        // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascent/descent'.
+        // The variant 'default' means 'compact and elegant'.
+        // As a result, it is not possible to know the variant context from the font alone.
+        // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request.
+
+        // The first time match anything elegant, second time anything not elegant.
+        for (int elegant = 2; elegant --> 0;) {
+            for (int bcp47Index = bcp47Count; bcp47Index --> 0;) {
+                SkLanguage lang(bcp47[bcp47Index]);
+                while (!lang.getTag().isEmpty()) {
+                    SkTypeface_AndroidSystem* matchingTypeface =
+                        find_family_style_character(fFallbackNameToFamilyMap,
+                                                    style, SkToBool(elegant),
+                                                    lang.getTag(), character);
+                    if (matchingTypeface) {
+                        return matchingTypeface;
+                    }
+
+                    lang = lang.getParent();
+                }
+            }
+            SkTypeface_AndroidSystem* matchingTypeface =
+                find_family_style_character(fFallbackNameToFamilyMap,
+                                            style, SkToBool(elegant),
+                                            SkString(), character);
+            if (matchingTypeface) {
+                return matchingTypeface;
+            }
+        }
+        return NULL;
+    }
+
+    virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
+        SkAutoTUnref<SkStream> stream(new SkMemoryStream(data));
+        return this->createFromStream(stream, ttcIndex);
+    }
+
+    virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
+        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
+        return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL;
+    }
+
+    virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
+        bool isFixedPitch;
+        SkTypeface::Style style;
+        SkString name;
+        if (!SkTypeface_FreeType::ScanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) {
+            return NULL;
+        }
+        return SkNEW_ARGS(SkTypeface_AndroidStream, (stream, ttcIndex,
+                                                     style, isFixedPitch, name));
+    }
+
+
+    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
+                                               unsigned styleBits) const SK_OVERRIDE {
+        SkTypeface::Style oldStyle = (SkTypeface::Style)styleBits;
+        SkFontStyle style = SkFontStyle(oldStyle & SkTypeface::kBold
+                                                 ? SkFontStyle::kBold_Weight
+                                                 : SkFontStyle::kNormal_Weight,
+                                        SkFontStyle::kNormal_Width,
+                                        oldStyle & SkTypeface::kItalic
+                                                 ? SkFontStyle::kItalic_Slant
+                                                 : SkFontStyle::kUpright_Slant);
+
+        if (familyName) {
+            // On Android, we must return NULL when we can't find the requested
+            // named typeface so that the system/app can provide their own recovery
+            // mechanism. On other platforms we'd provide a typeface from the
+            // default family instead.
+            return this->onMatchFamilyStyle(familyName, style);
+        }
+        return fDefaultFamily->matchStyle(style);
+    }
+
+
+private:
+
+    SkTArray<SkAutoTUnref<SkFontStyleSet_Android>, true> fFontStyleSets;
+    SkFontStyleSet* fDefaultFamily;
+    SkTypeface* fDefaultTypeface;
+
+    SkTDArray<NameToFamily> fNameToFamilyMap;
+    SkTDArray<NameToFamily> fFallbackNameToFamilyMap;
+
+    void buildNameToFamilyMap(SkTDArray<FontFamily*> families, const char* basePath) {
+        for (int i = 0; i < families.count(); i++) {
+            FontFamily& family = *families[i];
+
+            SkTDArray<NameToFamily>* nameToFamily = &fNameToFamilyMap;
+            if (family.fIsFallbackFont) {
+                nameToFamily = &fFallbackNameToFamilyMap;
+
+                if (0 == family.fNames.count()) {
+                    SkString& fallbackName = family.fNames.push_back();
+                    fallbackName.printf("%.2x##fallback", i);
+                }
+            }
+
+            SkFontStyleSet_Android* newSet = SkNEW_ARGS(SkFontStyleSet_Android, (family, basePath));
+            if (0 == newSet->count()) {
+                SkDELETE(newSet);
+                continue;
+            }
+            fFontStyleSets.push_back().reset(newSet);
+
+            for (int j = 0; j < family.fNames.count(); j++) {
+                NameToFamily* nextEntry = nameToFamily->append();
+                SkNEW_PLACEMENT_ARGS(&nextEntry->name, SkString, (family.fNames[j]));
+                nextEntry->styleSet = newSet;
+            }
+        }
+    }
+
+    void findDefaultFont() {
+        SkASSERT(!fFontStyleSets.empty());
+
+        static const char* gDefaultNames[] = { "sans-serif" };
+        for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) {
+            SkFontStyleSet* set = this->onMatchFamily(gDefaultNames[i]);
+            if (NULL == set) {
+                continue;
+            }
+            SkTypeface* tf = set->matchStyle(SkFontStyle());
+            if (NULL == tf) {
+                continue;
+            }
+            fDefaultFamily = set;
+            fDefaultTypeface = tf;
+            break;
+        }
+        if (NULL == fDefaultTypeface) {
+            fDefaultFamily = fFontStyleSets[0];
+            fDefaultTypeface = fDefaultFamily->createTypeface(0);
+        }
+        SkASSERT(fDefaultFamily);
+        SkASSERT(fDefaultTypeface);
+    }
+
+    typedef SkFontMgr INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkFontMgr* SkFontMgr::Factory() {
+    // The call to SkGetTestFontConfiguration is so that Chromium can override the environment.
+    // TODO: these globals need to be removed, in favor of a constructor / separate Factory
+    // which can be used instead.
+    const char* mainConfigFile;
+    const char* fallbackConfigFile;
+    const char* basePath;
+    SkGetTestFontConfiguration(&mainConfigFile, &fallbackConfigFile, &basePath);
+    if (mainConfigFile) {
+        return SkNEW_ARGS(SkFontMgr_Android, (mainConfigFile, fallbackConfigFile, basePath));
+    }
+
+    return SkNEW(SkFontMgr_Android);
+}
+
+void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackconf,
+                             const char* fontsdir) {
+    gTestMainConfigFile = mainconf;
+    gTestFallbackConfigFile = fallbackconf;
+    gTestFontFilePrefix = fontsdir;
+    SkASSERT(gTestMainConfigFile);
+    SkASSERT(gTestFallbackConfigFile);
+    SkASSERT(gTestFontFilePrefix);
+    SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s",
+              gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix));
+}
+
+void SkGetTestFontConfiguration(const char** mainconf, const char** fallbackconf,
+                                const char** fontsdir) {
+    *mainconf = gTestMainConfigFile;
+    *fallbackconf = gTestFallbackConfigFile;
+    *fontsdir = gTestFontFilePrefix;
+}
diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp
new file mode 100644
index 0000000..38f0e3a
--- /dev/null
+++ b/src/ports/SkFontMgr_fontconfig.cpp
@@ -0,0 +1,875 @@
+/*
+ * 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 "SkDataTable.h"
+#include "SkFontDescriptor.h"
+#include "SkFontHost_FreeType_common.h"
+#include "SkFontMgr.h"
+#include "SkFontStyle.h"
+#include "SkMath.h"
+#include "SkString.h"
+#include "SkStream.h"
+#include "SkTDArray.h"
+#include "SkThread.h"
+#include "SkTypefaceCache.h"
+#include "SkOSFile.h"
+
+#include <fontconfig/fontconfig.h>
+
+// FC_POSTSCRIPT_NAME was added with b561ff20 which ended up in 2.10.92
+// Ubuntu 12.04 is on 2.8.0, 13.10 is on 2.10.93
+// Debian 7 is on 2.9.0, 8 is on 2.11
+// OpenSUSE 12.2 is on 2.9.0, 12.3 is on 2.10.2, 13.1 2.11.0
+// Fedora 19 is on 2.10.93
+#ifndef FC_POSTSCRIPT_NAME
+#    define FC_POSTSCRIPT_NAME  "postscriptname"
+#endif
+
+#ifdef SK_DEBUG
+#    include "SkTLS.h"
+#endif
+
+/** Since FontConfig is poorly documented, this gives a high level overview:
+ *
+ *  FcConfig is a handle to a FontConfig configuration instance. Each 'configuration' is independent
+ *  from any others which may exist. There exists a default global configuration which is created
+ *  and destroyed by FcInit and FcFini, but this default should not normally be used.
+ *  Instead, one should use FcConfigCreate and FcInit* to have a named local state.
+ *
+ *  FcPatterns are {objectName -> [element]} (maps from object names to a list of elements).
+ *  Each element is some internal data plus an FcValue which is a variant (a union with a type tag).
+ *  Lists of elements are not typed, except by convention. Any collection of FcValues must be
+ *  assumed to be heterogeneous by the code, but the code need not do anything particularly
+ *  interesting if the values go against convention.
+ *
+ *  Somewhat like DirectWrite, FontConfig supports synthetics through FC_EMBOLDEN and FC_MATRIX.
+ *  Like all synthetic information, such information must be passed with the font data.
+ */
+
+namespace {
+
+// Fontconfig is not threadsafe before 2.10.91. Before that, we lock with a global mutex.
+// See http://skbug.com/1497 for background.
+SK_DECLARE_STATIC_MUTEX(gFCMutex);
+
+#ifdef SK_DEBUG
+    void *CreateThreadFcLocked() { return SkNEW_ARGS(bool, (false)); }
+    void DeleteThreadFcLocked(void* v) { SkDELETE(static_cast<bool*>(v)); }
+#   define THREAD_FC_LOCKED \
+        static_cast<bool*>(SkTLS::Get(CreateThreadFcLocked, DeleteThreadFcLocked))
+#endif
+
+struct FCLocker {
+    // Assume FcGetVersion() has always been thread safe.
+
+    FCLocker() {
+        if (FcGetVersion() < 21091) {
+            gFCMutex.acquire();
+        } else {
+            SkDEBUGCODE(bool* threadLocked = THREAD_FC_LOCKED);
+            SkASSERT(false == *threadLocked);
+            SkDEBUGCODE(*threadLocked = true);
+        }
+    }
+
+    ~FCLocker() {
+        AssertHeld();
+        if (FcGetVersion() < 21091) {
+            gFCMutex.release();
+        } else {
+            SkDEBUGCODE(*THREAD_FC_LOCKED = false);
+        }
+    }
+
+    static void AssertHeld() { SkDEBUGCODE(
+        if (FcGetVersion() < 21091) {
+            gFCMutex.assertHeld();
+        } else {
+            SkASSERT(true == *THREAD_FC_LOCKED);
+        }
+    ) }
+};
+
+} // namespace
+
+template<typename T, void (*D)(T*)> void FcTDestroy(T* t) {
+    FCLocker::AssertHeld();
+    D(t);
+}
+template <typename T, T* (*C)(), void (*D)(T*)> class SkAutoFc
+    : public SkAutoTCallVProc<T, FcTDestroy<T, D> > {
+public:
+    SkAutoFc() : SkAutoTCallVProc<T, FcTDestroy<T, D> >(C()) {
+        T* obj = this->operator T*();
+        SK_ALWAYSBREAK(NULL != obj);
+    }
+    explicit SkAutoFc(T* obj) : SkAutoTCallVProc<T, FcTDestroy<T, D> >(obj) {}
+};
+
+typedef SkAutoFc<FcCharSet, FcCharSetCreate, FcCharSetDestroy> SkAutoFcCharSet;
+typedef SkAutoFc<FcConfig, FcConfigCreate, FcConfigDestroy> SkAutoFcConfig;
+typedef SkAutoFc<FcFontSet, FcFontSetCreate, FcFontSetDestroy> SkAutoFcFontSet;
+typedef SkAutoFc<FcLangSet, FcLangSetCreate, FcLangSetDestroy> SkAutoFcLangSet;
+typedef SkAutoFc<FcObjectSet, FcObjectSetCreate, FcObjectSetDestroy> SkAutoFcObjectSet;
+typedef SkAutoFc<FcPattern, FcPatternCreate, FcPatternDestroy> SkAutoFcPattern;
+
+static int get_int(FcPattern* pattern, const char object[], int missing) {
+    int value;
+    if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) {
+        return missing;
+    }
+    return value;
+}
+
+static const char* get_string(FcPattern* pattern, const char object[], const char* missing = "") {
+    FcChar8* value;
+    if (FcPatternGetString(pattern, object, 0, &value) != FcResultMatch) {
+        return missing;
+    }
+    return (const char*)value;
+}
+
+enum SkWeakReturn {
+    kIsWeak_WeakReturn,
+    kIsStrong_WeakReturn,
+    kNoId_WeakReturn
+};
+/** Ideally there  would exist a call like
+ *  FcResult FcPatternIsWeak(pattern, object, id, FcBool* isWeak);
+ *
+ *  However, there is no such call and as of Fc 2.11.0 even FcPatternEquals ignores the weak bit.
+ *  Currently, the only reliable way of finding the weak bit is by its effect on matching.
+ *  The weak bit only affects the matching of FC_FAMILY and FC_POSTSCRIPT_NAME object values.
+ *  A element with the weak bit is scored after FC_LANG, without the weak bit is scored before.
+ *  Note that the weak bit is stored on the element, not on the value it holds.
+ */
+static SkWeakReturn is_weak(FcPattern* pattern, const char object[], int id) {
+    FCLocker::AssertHeld();
+
+    FcResult result;
+
+    // Create a copy of the pattern with only the value 'pattern'['object'['id']] in it.
+    // Internally, FontConfig pattern objects are linked lists, so faster to remove from head.
+    SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, NULL));
+    SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly));
+    FcBool hasId = true;
+    for (int i = 0; hasId && i < id; ++i) {
+        hasId = FcPatternRemove(minimal, object, 0);
+    }
+    if (!hasId) {
+        return kNoId_WeakReturn;
+    }
+    FcValue value;
+    result = FcPatternGet(minimal, object, 0, &value);
+    if (result != FcResultMatch) {
+        return kNoId_WeakReturn;
+    }
+    while (hasId) {
+        hasId = FcPatternRemove(minimal, object, 1);
+    }
+
+    // Create a font set with two patterns.
+    // 1. the same 'object' as minimal and a lang object with only 'nomatchlang'.
+    // 2. a different 'object' from minimal and a lang object with only 'matchlang'.
+    SkAutoFcFontSet fontSet;
+
+    SkAutoFcLangSet strongLangSet;
+    FcLangSetAdd(strongLangSet, (const FcChar8*)"nomatchlang");
+    SkAutoFcPattern strong(FcPatternDuplicate(minimal));
+    FcPatternAddLangSet(strong, FC_LANG, strongLangSet);
+
+    SkAutoFcLangSet weakLangSet;
+    FcLangSetAdd(weakLangSet, (const FcChar8*)"matchlang");
+    SkAutoFcPattern weak;
+    FcPatternAddString(weak, object, (const FcChar8*)"nomatchstring");
+    FcPatternAddLangSet(weak, FC_LANG, weakLangSet);
+
+    FcFontSetAdd(fontSet, strong.detach());
+    FcFontSetAdd(fontSet, weak.detach());
+
+    // Add 'matchlang' to the copy of the pattern.
+    FcPatternAddLangSet(minimal, FC_LANG, weakLangSet);
+
+    // Run a match against the copy of the pattern.
+    // If the 'id' was weak, then we should match the pattern with 'matchlang'.
+    // If the 'id' was strong, then we should match the pattern with 'nomatchlang'.
+
+    // Note that this config is only used for FcFontRenderPrepare, which we don't even want.
+    // However, there appears to be no way to match/sort without it.
+    SkAutoFcConfig config;
+    FcFontSet* fontSets[1] = { fontSet };
+    SkAutoFcPattern match(FcFontSetMatch(config, fontSets, SK_ARRAY_COUNT(fontSets),
+                                         minimal, &result));
+
+    FcLangSet* matchLangSet;
+    FcPatternGetLangSet(match, FC_LANG, 0, &matchLangSet);
+    return FcLangEqual == FcLangSetHasLang(matchLangSet, (const FcChar8*)"matchlang")
+                        ? kIsWeak_WeakReturn : kIsStrong_WeakReturn;
+}
+
+/** Removes weak elements from either FC_FAMILY or FC_POSTSCRIPT_NAME objects in the property.
+ *  This can be quite expensive, and should not be used more than once per font lookup.
+ *  This removes all of the weak elements after the last strong element.
+ */
+static void remove_weak(FcPattern* pattern, const char object[]) {
+    FCLocker::AssertHeld();
+
+    SkAutoFcObjectSet requestedObjectOnly(FcObjectSetBuild(object, NULL));
+    SkAutoFcPattern minimal(FcPatternFilter(pattern, requestedObjectOnly));
+
+    int lastStrongId = -1;
+    int numIds;
+    SkWeakReturn result;
+    for (int id = 0; ; ++id) {
+        result = is_weak(minimal, object, 0);
+        if (kNoId_WeakReturn == result) {
+            numIds = id;
+            break;
+        }
+        if (kIsStrong_WeakReturn == result) {
+            lastStrongId = id;
+        }
+        SkAssertResult(FcPatternRemove(minimal, object, 0));
+    }
+
+    // If they were all weak, then leave the pattern alone.
+    if (lastStrongId < 0) {
+        return;
+    }
+
+    // Remove everything after the last strong.
+    for (int id = lastStrongId + 1; id < numIds; ++id) {
+        SkAssertResult(FcPatternRemove(pattern, object, lastStrongId + 1));
+    }
+}
+
+static int map_range(SkFixed value,
+                     SkFixed old_min, SkFixed old_max,
+                     SkFixed new_min, SkFixed new_max)
+{
+    SkASSERT(old_min < old_max);
+    SkASSERT(new_min <= new_max);
+    return new_min + SkMulDiv(value - old_min, new_max - new_min, old_max - old_min);
+}
+
+static int ave(SkFixed a, SkFixed b) {
+    return SkFixedAve(a, b);
+}
+
+struct MapRanges {
+    SkFixed old_val;
+    SkFixed new_val;
+};
+
+static SkFixed map_ranges_fixed(SkFixed val, MapRanges const ranges[], int rangesCount) {
+    // -Inf to [0]
+    if (val < ranges[0].old_val) {
+        return ranges[0].new_val;
+    }
+
+    // Linear from [i] to ave([i], [i+1]), then from ave([i], [i+1]) to [i+1]
+    for (int i = 0; i < rangesCount - 1; ++i) {
+        if (val < ave(ranges[i].old_val, ranges[i+1].old_val)) {
+            return map_range(val, ranges[i].old_val, ave(ranges[i].old_val, ranges[i+1].old_val),
+                                  ranges[i].new_val, ave(ranges[i].new_val, ranges[i+1].new_val));
+        }
+        if (val < ranges[i+1].old_val) {
+            return map_range(val, ave(ranges[i].old_val, ranges[i+1].old_val), ranges[i+1].old_val,
+                                  ave(ranges[i].new_val, ranges[i+1].new_val), ranges[i+1].new_val);
+        }
+    }
+
+    // From [n] to +Inf
+    // if (fcweight < Inf)
+    return ranges[rangesCount-1].new_val;
+}
+
+static int map_ranges(int val, MapRanges const ranges[], int rangesCount) {
+    return SkFixedRoundToInt(map_ranges_fixed(SkIntToFixed(val), ranges, rangesCount));
+}
+
+template<int n> struct SkTFixed {
+    SK_COMPILE_ASSERT(-32768 <= n && n <= 32767, SkTFixed_n_not_in_range);
+    static const SkFixed value = static_cast<SkFixed>(n << 16);
+};
+
+static SkFontStyle skfontstyle_from_fcpattern(FcPattern* pattern) {
+    typedef SkFontStyle SkFS;
+
+    static const MapRanges weightRanges[] = {
+        { SkTFixed<FC_WEIGHT_THIN>::value,       SkTFixed<SkFS::kThin_Weight>::value },
+        { SkTFixed<FC_WEIGHT_EXTRALIGHT>::value, SkTFixed<SkFS::kExtraLight_Weight>::value },
+        { SkTFixed<FC_WEIGHT_LIGHT>::value,      SkTFixed<SkFS::kLight_Weight>::value },
+        { SkTFixed<FC_WEIGHT_REGULAR>::value,    SkTFixed<SkFS::kNormal_Weight>::value },
+        { SkTFixed<FC_WEIGHT_MEDIUM>::value,     SkTFixed<SkFS::kMedium_Weight>::value },
+        { SkTFixed<FC_WEIGHT_DEMIBOLD>::value,   SkTFixed<SkFS::kSemiBold_Weight>::value },
+        { SkTFixed<FC_WEIGHT_BOLD>::value,       SkTFixed<SkFS::kBold_Weight>::value },
+        { SkTFixed<FC_WEIGHT_EXTRABOLD>::value,  SkTFixed<SkFS::kExtraBold_Weight>::value },
+        { SkTFixed<FC_WEIGHT_BLACK>::value,      SkTFixed<SkFS::kBlack_Weight>::value },
+        { SkTFixed<FC_WEIGHT_EXTRABLACK>::value, SkTFixed<1000>::value },
+    };
+    int weight = map_ranges(get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR),
+                            weightRanges, SK_ARRAY_COUNT(weightRanges));
+
+    static const MapRanges widthRanges[] = {
+        { SkTFixed<FC_WIDTH_ULTRACONDENSED>::value, SkTFixed<SkFS::kUltraCondensed_Width>::value },
+        { SkTFixed<FC_WIDTH_EXTRACONDENSED>::value, SkTFixed<SkFS::kExtraCondensed_Width>::value },
+        { SkTFixed<FC_WIDTH_CONDENSED>::value,      SkTFixed<SkFS::kCondensed_Width>::value },
+        { SkTFixed<FC_WIDTH_SEMICONDENSED>::value,  SkTFixed<SkFS::kSemiCondensed_Width>::value },
+        { SkTFixed<FC_WIDTH_NORMAL>::value,         SkTFixed<SkFS::kNormal_Width>::value },
+        { SkTFixed<FC_WIDTH_SEMIEXPANDED>::value,   SkTFixed<SkFS::kSemiExpanded_Width>::value },
+        { SkTFixed<FC_WIDTH_EXPANDED>::value,       SkTFixed<SkFS::kExpanded_Width>::value },
+        { SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value,  SkTFixed<SkFS::kExtraExpanded_Width>::value },
+        { SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value,  SkTFixed<SkFS::kUltaExpanded_Width>::value },
+    };
+    int width = map_ranges(get_int(pattern, FC_WIDTH, FC_WIDTH_NORMAL),
+                           widthRanges, SK_ARRAY_COUNT(widthRanges));
+
+    SkFS::Slant slant = get_int(pattern, FC_SLANT, FC_SLANT_ROMAN) > 0
+                             ? SkFS::kItalic_Slant
+                             : SkFS::kUpright_Slant;
+
+    return SkFontStyle(weight, width, slant);
+}
+
+static void fcpattern_from_skfontstyle(SkFontStyle style, FcPattern* pattern) {
+    FCLocker::AssertHeld();
+
+    typedef SkFontStyle SkFS;
+
+    static const MapRanges weightRanges[] = {
+        { SkTFixed<SkFS::kThin_Weight>::value,       SkTFixed<FC_WEIGHT_THIN>::value },
+        { SkTFixed<SkFS::kExtraLight_Weight>::value, SkTFixed<FC_WEIGHT_EXTRALIGHT>::value },
+        { SkTFixed<SkFS::kLight_Weight>::value,      SkTFixed<FC_WEIGHT_LIGHT>::value },
+        { SkTFixed<SkFS::kNormal_Weight>::value,     SkTFixed<FC_WEIGHT_REGULAR>::value },
+        { SkTFixed<SkFS::kMedium_Weight>::value,     SkTFixed<FC_WEIGHT_MEDIUM>::value },
+        { SkTFixed<SkFS::kSemiBold_Weight>::value,   SkTFixed<FC_WEIGHT_DEMIBOLD>::value },
+        { SkTFixed<SkFS::kBold_Weight>::value,       SkTFixed<FC_WEIGHT_BOLD>::value },
+        { SkTFixed<SkFS::kExtraBold_Weight>::value,  SkTFixed<FC_WEIGHT_EXTRABOLD>::value },
+        { SkTFixed<SkFS::kBlack_Weight>::value,      SkTFixed<FC_WEIGHT_BLACK>::value },
+        { SkTFixed<1000>::value,                     SkTFixed<FC_WEIGHT_EXTRABLACK>::value },
+    };
+    int weight = map_ranges(style.weight(), weightRanges, SK_ARRAY_COUNT(weightRanges));
+
+    static const MapRanges widthRanges[] = {
+        { SkTFixed<SkFS::kUltraCondensed_Width>::value, SkTFixed<FC_WIDTH_ULTRACONDENSED>::value },
+        { SkTFixed<SkFS::kExtraCondensed_Width>::value, SkTFixed<FC_WIDTH_EXTRACONDENSED>::value },
+        { SkTFixed<SkFS::kCondensed_Width>::value,      SkTFixed<FC_WIDTH_CONDENSED>::value },
+        { SkTFixed<SkFS::kSemiCondensed_Width>::value,  SkTFixed<FC_WIDTH_SEMICONDENSED>::value },
+        { SkTFixed<SkFS::kNormal_Width>::value,         SkTFixed<FC_WIDTH_NORMAL>::value },
+        { SkTFixed<SkFS::kSemiExpanded_Width>::value,   SkTFixed<FC_WIDTH_SEMIEXPANDED>::value },
+        { SkTFixed<SkFS::kExpanded_Width>::value,       SkTFixed<FC_WIDTH_EXPANDED>::value },
+        { SkTFixed<SkFS::kExtraExpanded_Width>::value,  SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value },
+        { SkTFixed<SkFS::kUltaExpanded_Width>::value,   SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value },
+    };
+    int width = map_ranges(style.width(), widthRanges, SK_ARRAY_COUNT(widthRanges));
+
+    FcPatternAddInteger(pattern, FC_WEIGHT, weight);
+    FcPatternAddInteger(pattern, FC_WIDTH, width);
+    FcPatternAddInteger(pattern, FC_SLANT, style.isItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
+}
+
+static SkTypeface::Style sktypefacestyle_from_fcpattern(FcPattern* pattern) {
+    int fcweight = get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR);
+    int fcslant = get_int(pattern, FC_SLANT, FC_SLANT_ROMAN);
+    return (SkTypeface::Style)((fcweight >= FC_WEIGHT_BOLD ? SkTypeface::kBold : 0) |
+                                (fcslant > FC_SLANT_ROMAN ? SkTypeface::kItalic : 0));
+}
+
+class SkTypeface_stream : public SkTypeface_FreeType {
+public:
+    /** @param stream does not take ownership of the reference, does take ownership of the stream.*/
+    SkTypeface_stream(SkTypeface::Style style, bool fixedWidth, int ttcIndex, SkStreamAsset* stream)
+        : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth)
+        , fStream(SkRef(stream))
+        , fIndex(ttcIndex)
+    { };
+
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
+        familyName->reset();
+    }
+
+    virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const SK_OVERRIDE {
+        desc->setFontIndex(fIndex);
+        *serialize = true;
+    }
+
+    virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
+        *ttcIndex = fIndex;
+        return fStream->duplicate();
+    }
+
+private:
+    SkAutoTUnref<SkStreamAsset> fStream;
+    int fIndex;
+
+    typedef SkTypeface_FreeType INHERITED;
+};
+
+class SkTypeface_fontconfig : public SkTypeface_FreeType {
+public:
+    /** @param pattern takes ownership of the reference. */
+    static SkTypeface_fontconfig* Create(FcPattern* pattern) {
+        return SkNEW_ARGS(SkTypeface_fontconfig, (pattern));
+    }
+    mutable SkAutoFcPattern fPattern;
+
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
+        *familyName = get_string(fPattern, FC_FAMILY);
+    }
+
+    virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const SK_OVERRIDE {
+        FCLocker lock;
+        desc->setFamilyName(get_string(fPattern, FC_FAMILY));
+        desc->setFullName(get_string(fPattern, FC_FULLNAME));
+        desc->setPostscriptName(get_string(fPattern, FC_POSTSCRIPT_NAME));
+        desc->setFontFileName(get_string(fPattern, FC_FILE));
+        desc->setFontIndex(get_int(fPattern, FC_INDEX, 0));
+        *serialize = false;
+    }
+
+    virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
+        FCLocker lock;
+        *ttcIndex = get_int(fPattern, FC_INDEX, 0);
+        return SkStream::NewFromFile(get_string(fPattern, FC_FILE));
+    }
+
+    virtual ~SkTypeface_fontconfig() {
+        // Hold the lock while unrefing the pattern.
+        FCLocker lock;
+        fPattern.reset();
+    }
+
+private:
+    /** @param pattern takes ownership of the reference. */
+    SkTypeface_fontconfig(FcPattern* pattern)
+        : INHERITED(sktypefacestyle_from_fcpattern(pattern),
+                    SkTypefaceCache::NewFontID(),
+                    FC_PROPORTIONAL != get_int(pattern, FC_SPACING, FC_PROPORTIONAL))
+        , fPattern(pattern)
+    { };
+
+    typedef SkTypeface_FreeType INHERITED;
+};
+
+class SkFontMgr_fontconfig : public SkFontMgr {
+    mutable SkAutoFcConfig fFC;
+    SkAutoTUnref<SkDataTable> fFamilyNames;
+
+    class StyleSet : public SkFontStyleSet {
+    public:
+        /** @param parent does not take ownership of the reference.
+         *  @param fontSet takes ownership of the reference.
+         */
+        StyleSet(const SkFontMgr_fontconfig* parent, FcFontSet* fontSet)
+            : fFontMgr(SkRef(parent)), fFontSet(fontSet)
+        { }
+
+        virtual ~StyleSet() {
+            // Hold the lock while unrefing the font set.
+            FCLocker lock;
+            fFontSet.reset();
+        }
+
+        virtual int count() SK_OVERRIDE { return fFontSet->nfont; }
+
+        virtual void getStyle(int index, SkFontStyle* style, SkString* styleName) SK_OVERRIDE {
+            if (index < 0 || fFontSet->nfont <= index) {
+                return;
+            }
+
+            FCLocker lock;
+            if (style) {
+                *style = skfontstyle_from_fcpattern(fFontSet->fonts[index]);
+            }
+            if (styleName) {
+                *styleName = get_string(fFontSet->fonts[index], FC_STYLE);
+            }
+        }
+
+        virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
+            FCLocker lock;
+
+            FcPattern* match = fFontSet->fonts[index];
+            return fFontMgr->createTypefaceFromFcPattern(match);
+        }
+
+        virtual SkTypeface* matchStyle(const SkFontStyle& style) SK_OVERRIDE {
+            FCLocker lock;
+
+            SkAutoFcPattern pattern;
+            fcpattern_from_skfontstyle(style, pattern);
+            FcConfigSubstitute(fFontMgr->fFC, pattern, FcMatchPattern);
+            FcDefaultSubstitute(pattern);
+
+            FcResult result;
+            FcFontSet* fontSets[1] = { fFontSet };
+            SkAutoFcPattern match(FcFontSetMatch(fFontMgr->fFC,
+                                                 fontSets, SK_ARRAY_COUNT(fontSets),
+                                                 pattern, &result));
+            if (NULL == match) {
+                return NULL;
+            }
+
+            return fFontMgr->createTypefaceFromFcPattern(match);
+        }
+
+    private:
+        SkAutoTUnref<const SkFontMgr_fontconfig> fFontMgr;
+        SkAutoFcFontSet fFontSet;
+    };
+
+    static bool FindName(const SkTDArray<const char*>& list, const char* str) {
+        int count = list.count();
+        for (int i = 0; i < count; ++i) {
+            if (!strcmp(list[i], str)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static SkDataTable* GetFamilyNames(FcConfig* fcconfig) {
+        FCLocker lock;
+
+        SkTDArray<const char*> names;
+        SkTDArray<size_t> sizes;
+
+        static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication };
+        for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) {
+            // Return value of FcConfigGetFonts must not be destroyed.
+            FcFontSet* allFonts(FcConfigGetFonts(fcconfig, fcNameSet[setIndex]));
+            if (NULL == allFonts) {
+                continue;
+            }
+
+            for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) {
+                FcPattern* current = allFonts->fonts[fontIndex];
+                for (int id = 0; ; ++id) {
+                    FcChar8* fcFamilyName;
+                    FcResult result = FcPatternGetString(current, FC_FAMILY, id, &fcFamilyName);
+                    if (FcResultNoId == result) {
+                        break;
+                    }
+                    if (FcResultMatch != result) {
+                        continue;
+                    }
+                    const char* familyName = reinterpret_cast<const char*>(fcFamilyName);
+                    if (familyName && !FindName(names, familyName)) {
+                        *names.append() = familyName;
+                        *sizes.append() = strlen(familyName) + 1;
+                    }
+                }
+            }
+        }
+
+        return SkDataTable::NewCopyArrays((void const *const *)names.begin(),
+                                          sizes.begin(), names.count());
+    }
+
+    static bool FindByFcPattern(SkTypeface* cached, SkTypeface::Style, void* ctx) {
+        SkTypeface_fontconfig* cshFace = static_cast<SkTypeface_fontconfig*>(cached);
+        FcPattern* ctxPattern = static_cast<FcPattern*>(ctx);
+        return FcTrue == FcPatternEqual(cshFace->fPattern, ctxPattern);
+    }
+
+    mutable SkMutex fTFCacheMutex;
+    mutable SkTypefaceCache fTFCache;
+    /** Creates a typeface using a typeface cache.
+     *  @param pattern a complete pattern from FcFontRenderPrepare.
+     */
+    SkTypeface* createTypefaceFromFcPattern(FcPattern* pattern) const {
+        FCLocker::AssertHeld();
+        SkAutoMutexAcquire ama(fTFCacheMutex);
+        SkTypeface* face = fTFCache.findByProcAndRef(FindByFcPattern, pattern);
+        if (NULL == face) {
+            FcPatternReference(pattern);
+            face = SkTypeface_fontconfig::Create(pattern);
+            if (face) {
+                fTFCache.add(face, SkTypeface::kNormal, true);
+            }
+        }
+        return face;
+    }
+
+public:
+    SkFontMgr_fontconfig()
+        : fFC(FcInitLoadConfigAndFonts())
+        , fFamilyNames(GetFamilyNames(fFC)) { }
+
+    /** Takes control of the reference to 'config'. */
+    explicit SkFontMgr_fontconfig(FcConfig* config)
+        : fFC(config)
+        , fFamilyNames(GetFamilyNames(fFC)) { }
+
+    virtual ~SkFontMgr_fontconfig() {
+        // Hold the lock while unrefing the config.
+        FCLocker lock;
+        fFC.reset();
+    }
+
+protected:
+    virtual int onCountFamilies() const SK_OVERRIDE {
+        return fFamilyNames->count();
+    }
+
+    virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE {
+        familyName->set(fFamilyNames->atStr(index));
+    }
+
+    virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE {
+        return this->onMatchFamily(fFamilyNames->atStr(index));
+    }
+
+    /** True if any string object value in the font is the same
+     *         as a string object value in the pattern.
+     */
+    static bool AnyMatching(FcPattern* font, FcPattern* pattern, const char* object) {
+        FcChar8* fontString;
+        FcChar8* patternString;
+        FcResult result;
+        // Set an arbitrary limit on the number of pattern object values to consider.
+        // TODO: re-write this to avoid N*M
+        static const int maxId = 16;
+        for (int patternId = 0; patternId < maxId; ++patternId) {
+            result = FcPatternGetString(pattern, object, patternId, &patternString);
+            if (FcResultNoId == result) {
+                break;
+            }
+            if (FcResultMatch != result) {
+                continue;
+            }
+            for (int fontId = 0; fontId < maxId; ++fontId) {
+                result = FcPatternGetString(font, object, fontId, &fontString);
+                if (FcResultNoId == result) {
+                    break;
+                }
+                if (FcResultMatch != result) {
+                    continue;
+                }
+                if (0 == FcStrCmpIgnoreCase(patternString, fontString)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    static bool FontAccessible(FcPattern* font) {
+        // FontConfig can return fonts which are unreadable.
+        const char* filename = get_string(font, FC_FILE, NULL);
+        if (NULL == filename) {
+            return false;
+        }
+        return sk_exists(filename, kRead_SkFILE_Flag);
+    }
+
+    static bool FontFamilyNameMatches(FcPattern* font, FcPattern* pattern) {
+        return AnyMatching(font, pattern, FC_FAMILY);
+    }
+
+    static bool FontContainsCharacter(FcPattern* font, uint32_t character) {
+        FcResult result;
+        FcCharSet* matchCharSet;
+        for (int charSetId = 0; ; ++charSetId) {
+            result = FcPatternGetCharSet(font, FC_CHARSET, charSetId, &matchCharSet);
+            if (FcResultNoId == result) {
+                break;
+            }
+            if (FcResultMatch != result) {
+                continue;
+            }
+            if (FcCharSetHasChar(matchCharSet, character)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
+        FCLocker lock;
+
+        SkAutoFcPattern pattern;
+        FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
+        FcConfigSubstitute(fFC, pattern, FcMatchPattern);
+        FcDefaultSubstitute(pattern);
+
+        FcPattern* matchPattern;
+        SkAutoFcPattern strongPattern(NULL);
+        if (familyName) {
+            strongPattern.reset(FcPatternDuplicate(pattern));
+            remove_weak(strongPattern, FC_FAMILY);
+            matchPattern = strongPattern;
+        } else {
+            matchPattern = pattern;
+        }
+
+        SkAutoFcFontSet matches;
+        // TODO: Some families have 'duplicates' due to symbolic links.
+        // The patterns are exactly the same except for the FC_FILE.
+        // It should be possible to collapse these patterns by normalizing.
+        static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication };
+        for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setIndex) {
+            // Return value of FcConfigGetFonts must not be destroyed.
+            FcFontSet* allFonts(FcConfigGetFonts(fFC, fcNameSet[setIndex]));
+            if (NULL == allFonts) {
+                continue;
+            }
+
+            for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) {
+                FcPattern* font = allFonts->fonts[fontIndex];
+                if (FontAccessible(font) && FontFamilyNameMatches(font, matchPattern)) {
+                    FcFontSetAdd(matches, FcFontRenderPrepare(fFC, pattern, font));
+                }
+            }
+        }
+
+        return SkNEW_ARGS(StyleSet, (this, matches.detach()));
+    }
+
+    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
+                                           const SkFontStyle& style) const SK_OVERRIDE
+    {
+        FCLocker lock;
+
+        SkAutoFcPattern pattern;
+        FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
+        fcpattern_from_skfontstyle(style, pattern);
+        FcConfigSubstitute(fFC, pattern, FcMatchPattern);
+        FcDefaultSubstitute(pattern);
+
+        // We really want to match strong (prefered) and same (acceptable) only here.
+        // If a family name was specified, assume that any weak matches after the last strong match
+        // are weak (default) and ignore them.
+        // The reason for is that after substitution the pattern for 'sans-serif' looks like
+        // "wwwwwwwwwwwwwwswww" where there are many weak but preferred names, followed by defaults.
+        // So it is possible to have weakly matching but preferred names.
+        // In aliases, bindings are weak by default, so this is easy and common.
+        // If no family name was specified, we'll probably only get weak matches, but that's ok.
+        FcPattern* matchPattern;
+        SkAutoFcPattern strongPattern(NULL);
+        if (familyName) {
+            strongPattern.reset(FcPatternDuplicate(pattern));
+            remove_weak(strongPattern, FC_FAMILY);
+            matchPattern = strongPattern;
+        } else {
+            matchPattern = pattern;
+        }
+
+        FcResult result;
+        SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result));
+        if (NULL == font || !FontAccessible(font) || !FontFamilyNameMatches(font, matchPattern)) {
+            return NULL;
+        }
+
+        return createTypefaceFromFcPattern(font);
+    }
+
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
+    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+                                                    const SkFontStyle& style,
+                                                    const char* bcp47[],
+                                                    int bcp47Count,
+                                                    SkUnichar character) const SK_OVERRIDE
+    {
+#else
+    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+                                                    const SkFontStyle& style,
+                                                    const char bcp47_val[],
+                                                    SkUnichar character) const SK_OVERRIDE
+    {
+        const char** bcp47 = &bcp47_val;
+        int bcp47Count = bcp47_val ? 1 : 0;
+#endif
+        FCLocker lock;
+
+        SkAutoFcPattern pattern;
+        FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
+        fcpattern_from_skfontstyle(style, pattern);
+
+        SkAutoFcCharSet charSet;
+        FcCharSetAddChar(charSet, character);
+        FcPatternAddCharSet(pattern, FC_CHARSET, charSet);
+
+        if (bcp47Count > 0) {
+            SkASSERT(bcp47);
+            SkAutoFcLangSet langSet;
+            for (int i = bcp47Count; i --> 0;) {
+                FcLangSetAdd(langSet, (const FcChar8*)bcp47[i]);
+            }
+            FcPatternAddLangSet(pattern, FC_LANG, langSet);
+        }
+
+        FcConfigSubstitute(fFC, pattern, FcMatchPattern);
+        FcDefaultSubstitute(pattern);
+
+        FcResult result;
+        SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result));
+        if (NULL == font || !FontAccessible(font) || !FontContainsCharacter(font, character)) {
+            return NULL;
+        }
+
+        return createTypefaceFromFcPattern(font);
+    }
+
+    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface,
+                                         const SkFontStyle& style) const SK_OVERRIDE
+    {
+        //TODO: should the SkTypeface_fontconfig know its family?
+        const SkTypeface_fontconfig* fcTypeface =
+                static_cast<const SkTypeface_fontconfig*>(typeface);
+        return this->matchFamilyStyle(get_string(fcTypeface->fPattern, FC_FAMILY), style);
+    }
+
+    /** @param stream does not take ownership of the reference. */
+    virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
+        const size_t length = stream->getLength();
+        if (length <= 0 || (1u << 30) < length) {
+            return NULL;
+        }
+
+        SkTypeface::Style style = SkTypeface::kNormal;
+        bool isFixedWidth = false;
+        if (!SkTypeface_FreeType::ScanFont(stream, ttcIndex, NULL, &style, &isFixedWidth)) {
+            return NULL;
+        }
+
+        return SkNEW_ARGS(SkTypeface_stream, (style, isFixedWidth, ttcIndex,
+                                              static_cast<SkStreamAsset*>(stream)));
+    }
+
+    virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
+        SkAutoTUnref<SkStreamAsset> stream(SkNEW_ARGS(SkMemoryStream, (data)));
+        return this->createFromStream(stream, ttcIndex);
+    }
+
+    virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
+        SkAutoTUnref<SkStreamAsset> stream(SkStream::NewFromFile(path));
+        return this->createFromStream(stream, ttcIndex);
+    }
+
+    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
+                                               unsigned styleBits) const SK_OVERRIDE {
+        bool bold = styleBits & SkTypeface::kBold;
+        bool italic = styleBits & SkTypeface::kItalic;
+        SkFontStyle style = SkFontStyle(bold ? SkFontStyle::kBold_Weight
+                                             : SkFontStyle::kNormal_Weight,
+                                        SkFontStyle::kNormal_Width,
+                                        italic ? SkFontStyle::kItalic_Slant
+                                               : SkFontStyle::kUpright_Slant);
+        SkAutoTUnref<SkTypeface> typeface(this->matchFamilyStyle(familyName, style));
+        if (typeface.get()) {
+            return typeface.detach();
+        }
+
+        return this->matchFamilyStyle(NULL, style);
+    }
+};
+
+SkFontMgr* SkFontMgr::Factory() {
+    return SkNEW(SkFontMgr_fontconfig);
+}
diff --git a/src/ports/SkGlobalInitialization_chromium.cpp b/src/ports/SkGlobalInitialization_chromium.cpp
index 9721636..1893ed0 100644
--- a/src/ports/SkGlobalInitialization_chromium.cpp
+++ b/src/ports/SkGlobalInitialization_chromium.cpp
@@ -17,7 +17,6 @@
 #include "Sk2DPathEffect.h"
 #include "SkArithmeticMode.h"
 #include "SkAvoidXfermode.h"
-#include "SkBicubicImageFilter.h"
 #include "SkBitmapSource.h"
 #include "SkBlurDrawLooper.h"
 #include "SkBlurImageFilter.h"
@@ -54,72 +53,70 @@
 #include "SkPictureShader.h"
 #include "SkPixelXorXfermode.h"
 #include "SkRectShaderImageFilter.h"
-#include "SkStippleMaskFilter.h"
 #include "SkTableColorFilter.h"
 #include "SkTestImageFilters.h"
 #include "SkTileImageFilter.h"
 #include "SkMatrixImageFilter.h"
 #include "SkXfermodeImageFilter.h"
 
-static void InitializeFlattenables() {
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBicubicImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorMatrixFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDilateImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiscretePathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDisplacementMapEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDropShadowImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkErodeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerRasterizer)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLerpXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLocalMatrixShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Sk2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkStippleMaskFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMagnifierImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixConvolutionImageFilter)
+class SkPrivateEffectInitializer {
+public:
+    static void Init() {
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorMatrixFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDilateImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiscretePathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDisplacementMapEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDropShadowImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkErodeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerRasterizer)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLerpXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLocalMatrixShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMagnifierImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixConvolutionImageFilter)
 
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOffsetImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMergeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorFilterImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDownSampleImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMallocPixelRef)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOffsetImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMergeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorFilterImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDownSampleImageFilter)
 
-    SkArithmeticMode::InitializeFlattenables();
-    SkBlurMaskFilter::InitializeFlattenables();
-    SkColorFilter::InitializeFlattenables();
-    SkGradientShader::InitializeFlattenables();
-    SkLightingImageFilter::InitializeFlattenables();
-    SkTableColorFilter::InitializeFlattenables();
-    SkXfermode::InitializeFlattenables();
-}
+        SkArithmeticMode::InitializeFlattenables();
+        SkBlurMaskFilter::InitializeFlattenables();
+        SkColorFilter::InitializeFlattenables();
+        SkGradientShader::InitializeFlattenables();
+        SkLightingImageFilter::InitializeFlattenables();
+        SkTableColorFilter::InitializeFlattenables();
+        SkXfermode::InitializeFlattenables();
+    }
+};
 
 void SkFlattenable::InitializeFlattenablesIfNeeded() {
     SK_DECLARE_STATIC_ONCE(once);
-    SkOnce(&once, InitializeFlattenables);
+    SkOnce(&once, SkPrivateEffectInitializer::Init);
 }
diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp
index 60c34f2..1893ed0 100644
--- a/src/ports/SkGlobalInitialization_default.cpp
+++ b/src/ports/SkGlobalInitialization_default.cpp
@@ -17,7 +17,6 @@
 #include "Sk2DPathEffect.h"
 #include "SkArithmeticMode.h"
 #include "SkAvoidXfermode.h"
-#include "SkBicubicImageFilter.h"
 #include "SkBitmapSource.h"
 #include "SkBlurDrawLooper.h"
 #include "SkBlurImageFilter.h"
@@ -54,73 +53,70 @@
 #include "SkPictureShader.h"
 #include "SkPixelXorXfermode.h"
 #include "SkRectShaderImageFilter.h"
-#include "SkStippleMaskFilter.h"
 #include "SkTableColorFilter.h"
 #include "SkTestImageFilters.h"
 #include "SkTileImageFilter.h"
 #include "SkMatrixImageFilter.h"
 #include "SkXfermodeImageFilter.h"
 
-static void InitializeFlattenables() {
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBicubicImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorMatrixFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDilateImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiscretePathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDisplacementMapEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDropShadowImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkErodeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerRasterizer)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLerpXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLocalMatrixShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Sk2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkStippleMaskFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMagnifierImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixConvolutionImageFilter)
+class SkPrivateEffectInitializer {
+public:
+    static void Init() {
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorMatrixFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDilateImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiscretePathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDisplacementMapEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDropShadowImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkErodeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerRasterizer)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLerpXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLocalMatrixShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMagnifierImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixConvolutionImageFilter)
 
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOffsetImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMergeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorFilterImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDownSampleImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMallocPixelRef)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOffsetImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMergeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorFilterImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDownSampleImageFilter)
 
-    SkArithmeticMode::InitializeFlattenables();
-    SkBlurMaskFilter::InitializeFlattenables();
-    SkColorFilter::InitializeFlattenables();
-    SkGradientShader::InitializeFlattenables();
-    SkLightingImageFilter::InitializeFlattenables();
-    SkTableColorFilter::InitializeFlattenables();
-    SkXfermode::InitializeFlattenables();
-
-}
+        SkArithmeticMode::InitializeFlattenables();
+        SkBlurMaskFilter::InitializeFlattenables();
+        SkColorFilter::InitializeFlattenables();
+        SkGradientShader::InitializeFlattenables();
+        SkLightingImageFilter::InitializeFlattenables();
+        SkTableColorFilter::InitializeFlattenables();
+        SkXfermode::InitializeFlattenables();
+    }
+};
 
 void SkFlattenable::InitializeFlattenablesIfNeeded() {
     SK_DECLARE_STATIC_ONCE(once);
-    SkOnce(&once, InitializeFlattenables);
+    SkOnce(&once, SkPrivateEffectInitializer::Init);
 }
diff --git a/src/ports/SkImageDecoder_CG.cpp b/src/ports/SkImageDecoder_CG.cpp
index 8545ac8..3e3075c 100644
--- a/src/ports/SkImageDecoder_CG.cpp
+++ b/src/ports/SkImageDecoder_CG.cpp
@@ -11,7 +11,7 @@
 #include "SkImageEncoder.h"
 #include "SkMovie.h"
 #include "SkStream.h"
-#include "SkStreamHelpers.h"
+#include "SkStreamPriv.h"
 #include "SkTemplates.h"
 #include "SkUnPreMultiply.h"
 
@@ -32,7 +32,7 @@
 static CGDataProviderRef SkStreamToDataProvider(SkStream* stream) {
     // TODO: use callbacks, so we don't have to load all the data into RAM
     SkAutoMalloc storage;
-    const size_t len = CopyStreamToStorage(&storage, stream);
+    const size_t len = SkCopyStreamToStorage(&storage, stream);
     void* data = storage.detach();
 
     return CGDataProviderCreateWithData(data, data, len, malloc_release_proc);
@@ -40,6 +40,7 @@
 
 static CGImageSourceRef SkStreamToCGImageSource(SkStream* stream) {
     CGDataProviderRef data = SkStreamToDataProvider(stream);
+    SkASSERT(data);
     CGImageSourceRef imageSrc = CGImageSourceCreateWithDataProvider(data, 0);
     CGDataProviderRelease(data);
     return imageSrc;
@@ -50,6 +51,56 @@
     virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
 };
 
+static void argb_4444_force_opaque(void* row, int count) {
+    uint16_t* row16 = (uint16_t*)row;
+    for (int i = 0; i < count; ++i) {
+        row16[i] |= 0xF000;
+    }
+}
+
+static void argb_8888_force_opaque(void* row, int count) {
+    // can use RGBA or BGRA, they have the same shift for alpha
+    const uint32_t alphaMask = 0xFF << SK_RGBA_A32_SHIFT;
+    uint32_t* row32 = (uint32_t*)row;
+    for (int i = 0; i < count; ++i) {
+        row32[i] |= alphaMask;
+    }
+}
+
+static void alpha_8_force_opaque(void* row, int count) {
+    memset(row, 0xFF, count);
+}
+
+static void force_opaque(SkBitmap* bm) {
+    SkAutoLockPixels alp(*bm);
+    if (!bm->getPixels()) {
+        return;
+    }
+
+    void (*proc)(void*, int);
+    switch (bm->colorType()) {
+        case kARGB_4444_SkColorType:
+            proc = argb_4444_force_opaque;
+            break;
+        case kRGBA_8888_SkColorType:
+        case kBGRA_8888_SkColorType:
+            proc = argb_8888_force_opaque;
+            break;
+        case kAlpha_8_SkColorType:
+            proc = alpha_8_force_opaque;
+            break;
+        default:
+            return;
+    }
+
+    char* row = (char*)bm->getPixels();
+    for (int y = 0; y < bm->height(); ++y) {
+        proc(row, bm->width());
+        row += bm->rowBytes();
+    }
+    bm->setAlphaType(kOpaque_SkAlphaType);
+}
+
 #define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast)
 
 bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
@@ -89,8 +140,10 @@
         case kCGImageAlphaNone:
         case kCGImageAlphaNoneSkipLast:
         case kCGImageAlphaNoneSkipFirst:
-            SkASSERT(SkBitmap::ComputeIsOpaque(*bm));
-            bm->setAlphaType(kOpaque_SkAlphaType);
+            // We're opaque, but we can't rely on the data always having 0xFF
+            // in the alpha slot (which Skia wants), so we have to ram it in
+            // ourselves.
+            force_opaque(bm);
             break;
         default:
             // we don't know if we're opaque or not, so compute it.
@@ -248,6 +301,17 @@
 
 static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_cg_factory);
 
+#ifdef SK_BUILD_FOR_IOS
+class SkPNGImageEncoder_IOS : public SkImageEncoder_CG {
+public:
+    SkPNGImageEncoder_IOS()
+        : SkImageEncoder_CG(kPNG_Type) {
+    }
+};
+
+DEFINE_ENCODER_CREATOR(PNGImageEncoder_IOS);
+#endif
+
 struct FormatConversion {
     CFStringRef             fUTType;
     SkImageDecoder::Format  fFormat;
diff --git a/src/ports/SkMemory_malloc.cpp b/src/ports/SkMemory_malloc.cpp
index 3a5608e..0b936c9 100644
--- a/src/ports/SkMemory_malloc.cpp
+++ b/src/ports/SkMemory_malloc.cpp
@@ -9,10 +9,19 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#define SK_DEBUGFAILF(fmt, ...) \
+    SkASSERT((SkDebugf(fmt"\n", __VA_ARGS__), false))
+
+static inline void sk_out_of_memory(size_t size) {
+    SK_DEBUGFAILF("sk_out_of_memory (asked for " SK_SIZE_T_SPECIFIER " bytes)",
+                  size);
+    abort();
+}
+
 static inline void* throw_on_failure(size_t size, void* p) {
     if (size > 0 && p == NULL) {
         // If we've got a NULL here, the only reason we should have failed is running out of RAM.
-        sk_out_of_memory();
+        sk_out_of_memory(size);
     }
     return p;
 }
diff --git a/src/ports/SkMutex_pthread.h b/src/ports/SkMutex_pthread.h
index 1904140..9aaa061 100644
--- a/src/ports/SkMutex_pthread.h
+++ b/src/ports/SkMutex_pthread.h
@@ -13,22 +13,27 @@
 #include <errno.h>
 #include <pthread.h>
 
+// This isn't technically portable, but on Linux and Android pthread_t is some sort of int, and
+// on Darwin it's a pointer.  So assuming pthread_self() never returns 0, it works as a sentinel.
+SkDEBUGCODE(static const pthread_t kNoOwner = 0;)
+
 // A SkBaseMutex is a POD structure that can be directly initialized
 // at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the
 // generation of a static initializer in the final machine code (and
 // a corresponding static finalizer).
 struct SkBaseMutex {
     void acquire() {
+        SkASSERT(0 == pthread_equal(fOwner, pthread_self()));  // SkMutex is not re-entrant
         pthread_mutex_lock(&fMutex);
         SkDEBUGCODE(fOwner = pthread_self();)
     }
     void release() {
         this->assertHeld();
-        SkDEBUGCODE(fOwner = 0;)
+        SkDEBUGCODE(fOwner = kNoOwner;)
         pthread_mutex_unlock(&fMutex);
     }
     void assertHeld() {
-        SkASSERT(pthread_self() == fOwner);
+        SkASSERT(0 != pthread_equal(fOwner, pthread_self()));
     }
 
     pthread_mutex_t fMutex;
@@ -46,6 +51,7 @@
                 print_pthread_error(status);
                 SkASSERT(0 == status);
             }
+            fOwner = kNoOwner;
         )
     }
 
@@ -83,9 +89,13 @@
 #define SK_BASE_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, SkDEBUGCODE(0) }
 
 // Using POD-style initialization prevents the generation of a static initializer.
-#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = SK_BASE_MUTEX_INIT
-
-// Special case used when the static mutex must be available globally.
-#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = SK_BASE_MUTEX_INIT
+//
+// Without magic statics there are no thread safety guarantees on initialization
+// of local statics (even POD). As a result, it is illegal to use
+// SK_DECLARE_STATIC_MUTEX in a function.
+//
+// Because SkBaseMutex is not a primitive, a static SkBaseMutex cannot be
+// initialized in a class with this macro.
+#define SK_DECLARE_STATIC_MUTEX(name) namespace {} static SkBaseMutex name = SK_BASE_MUTEX_INIT
 
 #endif
diff --git a/src/ports/SkMutex_win.h b/src/ports/SkMutex_win.h
index d12fd03..fe06336 100644
--- a/src/ports/SkMutex_win.h
+++ b/src/ports/SkMutex_win.h
@@ -31,15 +31,17 @@
 #endif
 
 // On Windows, SkBaseMutex and SkMutex are the same thing,
-// we can't easily get rid of static initializers.
-class SkMutex {
+// we can't easily get rid of static initializers. However,
+// we preserve the same inheritance pattern as other platforms
+// so that we can forward-declare cleanly.
+struct SkBaseMutex {
 public:
-    SkMutex() {
+    SkBaseMutex() {
         InitializeCriticalSection(&fStorage);
         SkDEBUGCODE(fOwner = 0;)
     }
 
-    ~SkMutex() {
+    ~SkBaseMutex() {
         SkASSERT(0 == fOwner);
         DeleteCriticalSection(&fStorage);
     }
@@ -59,18 +61,19 @@
         SkASSERT(GetCurrentThreadId() == fOwner);
     }
 
-private:
-    SkMutex(const SkMutex&);
-    SkMutex& operator=(const SkMutex&);
-
+protected:
     CRITICAL_SECTION fStorage;
     SkDEBUGCODE(DWORD fOwner;)
+
+private:
+    SkBaseMutex(const SkBaseMutex&);
+    SkBaseMutex& operator=(const SkBaseMutex&);
 };
 
-typedef SkMutex SkBaseMutex;
+class SkMutex : public SkBaseMutex { };
 
 // Windows currently provides no documented means of POD initializing a CRITICAL_SECTION.
-#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name
-#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name
+// As a result, it is illegal to SK_DECLARE_STATIC_MUTEX in a function.
+#define SK_DECLARE_STATIC_MUTEX(name) namespace{} static SkBaseMutex name
 
 #endif
diff --git a/src/ports/SkOSFile_none.cpp b/src/ports/SkOSFile_none.cpp
index 7ed8ab4..11723c2 100644
--- a/src/ports/SkOSFile_none.cpp
+++ b/src/ports/SkOSFile_none.cpp
@@ -7,6 +7,10 @@
 
 #include "SkOSFile.h"
 
+bool sk_exists(const char *path, SkFILE_Flags flags) {
+    return false;
+}
+
 bool sk_fidentical(SkFILE* a, SkFILE* b) {
     return false;
 }
diff --git a/src/ports/SkOSFile_posix.cpp b/src/ports/SkOSFile_posix.cpp
index 93918b2..b5dc4ac 100644
--- a/src/ports/SkOSFile_posix.cpp
+++ b/src/ports/SkOSFile_posix.cpp
@@ -13,6 +13,18 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <unistd.h>
+
+bool sk_exists(const char *path, SkFILE_Flags flags) {
+    int mode = F_OK;
+    if (flags & kRead_SkFILE_Flag) {
+        mode |= R_OK;
+    }
+    if (flags & kWrite_SkFILE_Flag) {
+        mode |= W_OK;
+    }
+    return (0 == access(path, mode));
+}
 
 typedef struct {
     dev_t dev;
diff --git a/src/ports/SkOSFile_stdio.cpp b/src/ports/SkOSFile_stdio.cpp
index ad26c80..d634625 100644
--- a/src/ports/SkOSFile_stdio.cpp
+++ b/src/ports/SkOSFile_stdio.cpp
@@ -15,8 +15,6 @@
 #ifdef _WIN32
 #include <direct.h>
 #include <io.h>
-#else
-#include <unistd.h>
 #endif
 
 SkFILE* sk_fopen(const char path[], SkFILE_Flags flags) {
@@ -123,14 +121,6 @@
     ::fclose((FILE*)f);
 }
 
-bool sk_exists(const char *path) {
-#ifdef _WIN32
-    return (0 == _access(path, 0));
-#else
-    return (0 == access(path, 0));
-#endif
-}
-
 bool sk_isdir(const char *path) {
     struct stat status;
     if (0 != stat(path, &status)) {
diff --git a/src/ports/SkOSFile_win.cpp b/src/ports/SkOSFile_win.cpp
index a084891..ded5858 100644
--- a/src/ports/SkOSFile_win.cpp
+++ b/src/ports/SkOSFile_win.cpp
@@ -13,6 +13,17 @@
 #include <stdio.h>
 #include <sys/stat.h>
 
+bool sk_exists(const char *path, SkFILE_Flags flags) {
+    int mode = 0; // existence
+    if (flags & kRead_SkFILE_Flag) {
+        mode |= 4; // read
+    }
+    if (flags & kWrite_SkFILE_Flag) {
+        mode |= 2; // write
+    }
+    return (0 == _access(path, mode));
+}
+
 typedef struct {
     ULONGLONG fVolume;
     ULONGLONG fLsbSize;
@@ -55,7 +66,7 @@
     SkAutoNullKernelHandle(const HANDLE handle) : fHandle(handle) { }
     ~SkAutoNullKernelHandle() { CloseHandle(fHandle); }
     operator HANDLE() const { return fHandle; }
-    bool isValid() const { return NULL != fHandle; }
+    bool isValid() const { return SkToBool(fHandle); }
 private:
     HANDLE fHandle;
 };
diff --git a/src/ports/SkRemotableFontMgr_win_dw.cpp b/src/ports/SkRemotableFontMgr_win_dw.cpp
index d979683..498f21f 100644
--- a/src/ports/SkRemotableFontMgr_win_dw.cpp
+++ b/src/ports/SkRemotableFontMgr_win_dw.cpp
@@ -408,11 +408,21 @@
         SkFontIdentity fIdentity;
     };
 
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
     virtual SkFontIdentity matchNameStyleCharacter(const char familyName[],
                                                    const SkFontStyle& pattern,
-                                                   const char bpc47[],
-                                                   SkUnichar character) const  SK_OVERRIDE
+                                                   const char* bcp47[], int bcp47Count,
+                                                   SkUnichar character) const SK_OVERRIDE
     {
+#else
+    virtual SkFontIdentity matchNameStyleCharacter(const char familyName[],
+                                                   const SkFontStyle& pattern,
+                                                   const char bcp47_val[],
+                                                   SkUnichar character) const SK_OVERRIDE
+    {
+        const char** bcp47 = &bcp47_val;
+        int bcp47Count = bcp47_val ? 1 : 0;
+#endif
         SkFontIdentity identity = { SkFontIdentity::kInvalidDataId };
 
         IDWriteFactory* dwFactory = sk_get_dwrite_factory();
@@ -431,13 +441,14 @@
             HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), NULL, identity);
         }
 
-        const SkSMallocWCHAR* dwBpc47;
-        SkSMallocWCHAR dwBpc47Local;
-        if (NULL == bpc47) {
-            dwBpc47 = &fLocaleName;
+        const SkSMallocWCHAR* dwBcp47;
+        SkSMallocWCHAR dwBcp47Local;
+        if (bcp47Count < 1) {
+            dwBcp47 = &fLocaleName;
         } else {
-            HR_GENERAL(sk_cstring_to_wchar(bpc47, &dwBpc47Local), NULL, identity);
-            dwBpc47 = &dwBpc47Local;
+            //TODO: support fallback stack.
+            HR_GENERAL(sk_cstring_to_wchar(bcp47[bcp47Count-1], &dwBcp47Local), NULL, identity);
+            dwBcp47 = &dwBcp47Local;
         }
 
         SkTScopedComPtr<IDWriteTextFormat> fallbackFormat;
@@ -447,7 +458,7 @@
                                                dwStyle.fSlant,
                                                dwStyle.fWidth,
                                                72.0f,
-                                               *dwBpc47,
+                                               *dwBcp47,
                                                &fallbackFormat),
                    "Could not create text format.",
                    identity);
diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp
index 28d41c1..7884b13 100644
--- a/src/ports/SkScalerContext_win_dw.cpp
+++ b/src/ports/SkScalerContext_win_dw.cpp
@@ -26,7 +26,9 @@
 #include "SkTypeface_win_dw.h"
 
 #include <dwrite.h>
-#include <dwrite_1.h>
+#if SK_HAS_DWRITE_1_H
+#  include <dwrite_1.h>
+#endif
 
 static bool isLCD(const SkScalerContext::Rec& rec) {
     return SkMask::kLCD16_Format == rec.fMaskFormat ||
@@ -74,7 +76,7 @@
     if (gasp->version != SkOTTableGridAndScanProcedure::version0 &&
         gasp->version != SkOTTableGridAndScanProcedure::version1)
     {
-        return ;
+        return;
     }
 
     uint16_t numRanges = SkEndianSwap16(gasp->numRanges);
@@ -100,8 +102,6 @@
         }
         minPPEM = maxPPEM;
     }
-
-    return;
 }
 
 static bool has_bitmap_strike(DWriteFontTypeface* typeface, PPEMRange range) {
@@ -384,10 +384,6 @@
                                        SkIntToScalar(gm.advanceWidth),
                                        SkIntToScalar(dwfm.designUnitsPerEm));
 
-    if (!this->isSubpixel()) {
-        advanceX = SkScalarRoundToScalar(advanceX);
-    }
-
     SkVector vecs[1] = { { advanceX, 0 } };
     if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
         DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
@@ -404,11 +400,11 @@
     glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY);
 }
 
-void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
-    glyph->fWidth = 0;
-
-    this->generateAdvance(glyph);
-
+HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph,
+                                           DWRITE_RENDERING_MODE renderingMode,
+                                           DWRITE_TEXTURE_TYPE textureType,
+                                           RECT* bbox)
+{
     //Measure raster size.
     fXform.dx = SkFixedToFloat(glyph->getSubXFixed());
     fXform.dy = SkFixedToFloat(glyph->getSubYFixed());
@@ -432,38 +428,78 @@
     run.glyphOffsets = &offset;
 
     SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
-    HRVM(fTypeface->fFactory->CreateGlyphRunAnalysis(
-             &run,
-             1.0f, // pixelsPerDip,
-             &fXform,
-             fRenderingMode,
-             fMeasuringMode,
-             0.0f, // baselineOriginX,
-             0.0f, // baselineOriginY,
-             &glyphRunAnalysis),
-         "Could not create glyph run analysis.");
+    HRM(fTypeface->fFactory->CreateGlyphRunAnalysis(
+            &run,
+            1.0f, // pixelsPerDip,
+            &fXform,
+            renderingMode,
+            fMeasuringMode,
+            0.0f, // baselineOriginX,
+            0.0f, // baselineOriginY,
+            &glyphRunAnalysis),
+        "Could not create glyph run analysis.");
 
-    RECT bbox;
-    HRVM(glyphRunAnalysis->GetAlphaTextureBounds(fTextureType, &bbox),
-         "Could not get texture bounds.");
+    HRM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox),
+        "Could not get texture bounds.");
 
+    return S_OK;
+}
+
+/** GetAlphaTextureBounds succeeds but sometimes returns empty bounds like
+ *  { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }
+ *  for small, but not quite zero, sized glyphs.
+ *  Only set as non-empty if the returned bounds are non-empty.
+ */
+static bool glyph_check_and_set_bounds(SkGlyph* glyph, const RECT& bbox) {
+    if (bbox.left >= bbox.right || bbox.top >= bbox.bottom) {
+        return false;
+    }
     glyph->fWidth = SkToU16(bbox.right - bbox.left);
     glyph->fHeight = SkToU16(bbox.bottom - bbox.top);
     glyph->fLeft = SkToS16(bbox.left);
     glyph->fTop = SkToS16(bbox.top);
+    return true;
 }
 
-void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx,
-                                             SkPaint::FontMetrics* my) {
-    if (!(mx || my))
-      return;
+void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
+    glyph->fWidth = 0;
+    glyph->fHeight = 0;
+    glyph->fLeft = 0;
+    glyph->fTop = 0;
 
-    if (mx) {
-        sk_bzero(mx, sizeof(*mx));
+    this->generateAdvance(glyph);
+
+    RECT bbox;
+    HRVM(this->getBoundingBox(glyph, fRenderingMode, fTextureType, &bbox),
+         "Requested bounding box could not be determined.");
+
+    if (glyph_check_and_set_bounds(glyph, bbox)) {
+        return;
     }
-    if (my) {
-        sk_bzero(my, sizeof(*my));
+
+    // GetAlphaTextureBounds succeeds but returns an empty RECT if there are no
+    // glyphs of the specified texture type. When this happens, try with the
+    // alternate texture type.
+    if (DWRITE_TEXTURE_CLEARTYPE_3x1 == fTextureType) {
+        HRVM(this->getBoundingBox(glyph,
+                                  DWRITE_RENDERING_MODE_ALIASED,
+                                  DWRITE_TEXTURE_ALIASED_1x1,
+                                  &bbox),
+             "Fallback bounding box could not be determined.");
+        if (glyph_check_and_set_bounds(glyph, bbox)) {
+            glyph->fForceBW = 1;
+        }
     }
+    // TODO: handle the case where a request for DWRITE_TEXTURE_ALIASED_1x1
+    // fails, and try DWRITE_TEXTURE_CLEARTYPE_3x1.
+}
+
+void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) {
+    if (NULL == metrics) {
+        return;
+    }
+
+    sk_bzero(metrics, sizeof(*metrics));
 
     DWRITE_FONT_METRICS dwfm;
     if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
@@ -479,58 +515,49 @@
     }
 
     SkScalar upem = SkIntToScalar(dwfm.designUnitsPerEm);
-    if (mx) {
-        mx->fTop = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem;
-        mx->fAscent = mx->fTop;
-        mx->fDescent = fTextSizeRender * SkIntToScalar(dwfm.descent) / upem;
-        mx->fBottom = mx->fDescent;
-        mx->fLeading = fTextSizeRender * SkIntToScalar(dwfm.lineGap) / upem;
-        mx->fXHeight = fTextSizeRender * SkIntToScalar(dwfm.xHeight) / upem;
-        mx->fUnderlineThickness = fTextSizeRender * SkIntToScalar(dwfm.underlineThickness) / upem;
-        mx->fUnderlinePosition = -(fTextSizeRender * SkIntToScalar(dwfm.underlinePosition) / upem);
 
-        mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-        mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+    metrics->fAscent = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem;
+    metrics->fDescent = fTextSizeRender * SkIntToScalar(dwfm.descent) / upem;
+    metrics->fLeading = fTextSizeRender * SkIntToScalar(dwfm.lineGap) / upem;
+    metrics->fXHeight = fTextSizeRender * SkIntToScalar(dwfm.xHeight) / upem;
+    metrics->fUnderlineThickness = fTextSizeRender * SkIntToScalar(dwfm.underlineThickness) / upem;
+    metrics->fUnderlinePosition = -(fTextSizeRender * SkIntToScalar(dwfm.underlinePosition) / upem);
+
+    metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+    metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+
+#if SK_HAS_DWRITE_1_H
+    if (fTypeface->fDWriteFontFace1.get()) {
+        DWRITE_FONT_METRICS1 dwfm1;
+        fTypeface->fDWriteFontFace1->GetMetrics(&dwfm1);
+        metrics->fTop = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxTop) / upem;
+        metrics->fBottom = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxBottom) / upem;
+        metrics->fXMin = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxLeft) / upem;
+        metrics->fXMax = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxRight) / upem;
+
+        metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin;
+        return;
+    }
+#else
+#  pragma message("No dwrite_1.h is available, font metrics may be affected.")
+#endif
+
+    AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get());
+    if (head.fExists &&
+        head.fSize >= sizeof(SkOTTableHead) &&
+        head->version == SkOTTableHead::version1)
+    {
+        metrics->fTop = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMax) / upem;
+        metrics->fBottom = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMin) / upem;
+        metrics->fXMin = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMin) / upem;
+        metrics->fXMax = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMax) / upem;
+
+        metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin;
+        return;
     }
 
-    if (my) {
-        my->fAscent = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem;
-        my->fDescent = fTextSizeRender * SkIntToScalar(dwfm.descent) / upem;
-        my->fLeading = fTextSizeRender * SkIntToScalar(dwfm.lineGap) / upem;
-        my->fXHeight = fTextSizeRender * SkIntToScalar(dwfm.xHeight) / upem;
-        my->fUnderlineThickness = fTextSizeRender * SkIntToScalar(dwfm.underlineThickness) / upem;
-        my->fUnderlinePosition = -(fTextSizeRender * SkIntToScalar(dwfm.underlinePosition) / upem);
-
-        my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-        my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
-
-        if (NULL != fTypeface->fDWriteFontFace1.get()) {
-            DWRITE_FONT_METRICS1 dwfm1;
-            fTypeface->fDWriteFontFace1->GetMetrics(&dwfm1);
-            my->fTop = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxTop) / upem;
-            my->fBottom = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxBottom) / upem;
-            my->fXMin = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxLeft) / upem;
-            my->fXMax = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxRight) / upem;
-
-            my->fMaxCharWidth = my->fXMax - my->fXMin;
-        } else {
-            AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get());
-            if (head.fExists &&
-                head.fSize >= sizeof(SkOTTableHead) &&
-                head->version == SkOTTableHead::version1)
-            {
-                my->fTop = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMax) / upem;
-                my->fBottom = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMin) / upem;
-                my->fXMin = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMin) / upem;
-                my->fXMax = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMax) / upem;
-
-                my->fMaxCharWidth = my->fXMax - my->fXMin;
-            } else {
-                my->fTop = my->fAscent;
-                my->fBottom = my->fDescent;
-            }
-        }
-    }
+    metrics->fTop = metrics->fAscent;
+    metrics->fBottom = metrics->fDescent;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -628,9 +655,12 @@
     }
 }
 
-const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) {
+const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
+                                           DWRITE_RENDERING_MODE renderingMode,
+                                           DWRITE_TEXTURE_TYPE textureType)
+{
     int sizeNeeded = glyph.fWidth * glyph.fHeight;
-    if (DWRITE_RENDERING_MODE_ALIASED != fRenderingMode) {
+    if (DWRITE_RENDERING_MODE_ALIASED != renderingMode) {
         sizeNeeded *= 3;
     }
     if (sizeNeeded > fBits.count()) {
@@ -665,7 +695,7 @@
     HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run,
                                           1.0f, // pixelsPerDip,
                                           &fXform,
-                                          fRenderingMode,
+                                          renderingMode,
                                           fMeasuringMode,
                                           0.0f, // baselineOriginX,
                                           0.0f, // baselineOriginY,
@@ -679,7 +709,7 @@
     bbox.top = glyph.fTop;
     bbox.right = glyph.fLeft + glyph.fWidth;
     bbox.bottom = glyph.fTop + glyph.fHeight;
-    HRNM(glyphRunAnalysis->CreateAlphaTexture(fTextureType,
+    HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType,
                                               &bbox,
                                               fBits.begin(),
                                               sizeNeeded),
@@ -689,7 +719,13 @@
 
 void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
     //Create the mask.
-    const void* bits = this->drawDWMask(glyph);
+    DWRITE_RENDERING_MODE renderingMode = fRenderingMode;
+    DWRITE_TEXTURE_TYPE textureType = fTextureType;
+    if (glyph.fForceBW) {
+        renderingMode = DWRITE_RENDERING_MODE_ALIASED;
+        textureType = DWRITE_TEXTURE_ALIASED_1x1;
+    }
+    const void* bits = this->drawDWMask(glyph, renderingMode, textureType);
     if (!bits) {
         sk_bzero(glyph.fImage, glyph.computeImageSize());
         return;
@@ -697,7 +733,7 @@
 
     //Copy the mask into the glyph.
     const uint8_t* src = (const uint8_t*)bits;
-    if (DWRITE_RENDERING_MODE_ALIASED == fRenderingMode) {
+    if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) {
         bilevel_to_bw(src, glyph);
         const_cast<SkGlyph&>(glyph).fMaskFormat = SkMask::kBW_Format;
     } else if (!isLCD(fRec)) {
diff --git a/src/ports/SkScalerContext_win_dw.h b/src/ports/SkScalerContext_win_dw.h
index e3dbd29..0bd79e7 100644
--- a/src/ports/SkScalerContext_win_dw.h
+++ b/src/ports/SkScalerContext_win_dw.h
@@ -30,11 +30,17 @@
     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
-    virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
-                                     SkPaint::FontMetrics* mY) SK_OVERRIDE;
+    virtual void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE;
 
 private:
-    const void* drawDWMask(const SkGlyph& glyph);
+    const void* drawDWMask(const SkGlyph& glyph,
+                           DWRITE_RENDERING_MODE renderingMode,
+                           DWRITE_TEXTURE_TYPE textureType);
+
+    HRESULT getBoundingBox(SkGlyph* glyph,
+                           DWRITE_RENDERING_MODE renderingMode,
+                           DWRITE_TEXTURE_TYPE textureType,
+                           RECT* bbox);
 
     SkTDArray<uint8_t> fBits;
     /** The total matrix without the text height scale. */
diff --git a/src/ports/SkTypeface_win_dw.cpp b/src/ports/SkTypeface_win_dw.cpp
index 6ff8412..8b9ed16 100644
--- a/src/ports/SkTypeface_win_dw.cpp
+++ b/src/ports/SkTypeface_win_dw.cpp
@@ -5,6 +5,14 @@
  * found in the LICENSE file.
  */
 
+#include "SkTypes.h"
+// SkTypes will include Windows.h, which will pull in all of the GDI defines.
+// GDI #defines GetGlyphIndices to GetGlyphIndicesA or GetGlyphIndicesW, but
+// IDWriteFontFace has a method called GetGlyphIndices. Since this file does
+// not use GDI, undefing GetGlyphIndices makes things less confusing.
+#undef GetGlyphIndices
+
+#include "SkDWrite.h"
 #include "SkDWriteFontFileStream.h"
 #include "SkFontDescriptor.h"
 #include "SkFontStream.h"
@@ -15,25 +23,26 @@
 #include "SkScalerContext.h"
 #include "SkScalerContext_win_dw.h"
 #include "SkTypeface_win_dw.h"
-#include "SkTypes.h"
 #include "SkUtils.h"
 
+void DWriteFontTypeface::onGetFamilyName(SkString* familyName) const {
+    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
+    HRV(fDWriteFontFamily->GetFamilyNames(&familyNames));
+
+    sk_get_locale_string(familyNames.get(), NULL/*fMgr->fLocaleName.get()*/, familyName);
+}
+
 void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
                                              bool* isLocalStream) const {
     // Get the family name.
-    SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames;
-    HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames));
-
-    UINT32 dwFamilyNamesLength;
-    HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength));
-
-    SkSMallocWCHAR dwFamilyNameChar(dwFamilyNamesLength+1);
-    HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.get(), dwFamilyNamesLength+1));
+    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
+    HRV(fDWriteFontFamily->GetFamilyNames(&familyNames));
 
     SkString utf8FamilyName;
-    HRV(sk_wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName));
+    sk_get_locale_string(familyNames.get(), NULL/*fMgr->fLocaleName.get()*/, &utf8FamilyName);
 
     desc->setFamilyName(utf8FamilyName.c_str());
+    desc->setFontIndex(fDWriteFontFace->GetIndex());
     *isLocalStream = SkToBool(fDWriteFontFileLoader.get());
 }
 
@@ -134,24 +143,22 @@
         }
 
         // String
-        UINT32 stringLength;
-        HRBM(fStrings->GetStringLength(fIndex, &stringLength), "Could not get string length.");
-        stringLength += 1;
+        UINT32 stringLen;
+        HRBM(fStrings->GetStringLength(fIndex, &stringLen), "Could not get string length.");
 
-        SkSMallocWCHAR wString(stringLength);
-        HRBM(fStrings->GetString(fIndex, wString.get(), stringLength), "Could not get string.");
+        SkSMallocWCHAR wString(stringLen+1);
+        HRBM(fStrings->GetString(fIndex, wString.get(), stringLen+1), "Could not get string.");
 
-        HRB(sk_wchar_to_skstring(wString.get(), &localizedString->fString));
+        HRB(sk_wchar_to_skstring(wString.get(), stringLen, &localizedString->fString));
 
         // Locale
-        UINT32 localeLength;
-        HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLength), "Could not get locale length.");
-        localeLength += 1;
+        UINT32 localeLen;
+        HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLen), "Could not get locale length.");
 
-        SkSMallocWCHAR wLocale(localeLength);
-        HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLength), "Could not get locale.");
+        SkSMallocWCHAR wLocale(localeLen+1);
+        HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLen+1), "Could not get locale.");
 
-        HRB(sk_wchar_to_skstring(wLocale.get(), &localizedString->fLanguage));
+        HRB(sk_wchar_to_skstring(wLocale.get(), localeLen, &localizedString->fLanguage));
 
         ++fIndex;
         return true;
@@ -195,7 +202,7 @@
         return 0;
     }
     size_t size = SkTMin(length, table.fSize - offset);
-    if (NULL != data) {
+    if (data) {
         memcpy(data, table.fData + offset, size);
     }
 
@@ -242,7 +249,8 @@
         rec->fMaskFormat = SkMask::kA8_Format;
     }
 
-    unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
+    unsigned flagsWeDontSupport = SkScalerContext::kVertical_Flag |
+                                  SkScalerContext::kDevKernText_Flag |
                                   SkScalerContext::kForceAutohinting_Flag |
                                   SkScalerContext::kEmbolden_Flag |
                                   SkScalerContext::kLCD_BGROrder_Flag |
@@ -277,9 +285,6 @@
 // Construct Glyph to Unicode table.
 // Unicode code points that require conjugate pairs in utf16 are not
 // supported.
-// TODO(arthurhsu): Add support for conjugate pairs. It looks like that may
-// require parsing the TTF cmap table (platform 4, encoding 12) directly instead
-// of calling GetFontUnicodeRange().
 // TODO(bungeman): This never does what anyone wants.
 // What is really wanted is the text to glyphs mapping
 static void populate_glyph_to_unicode(IDWriteFontFace* fontFace,
@@ -288,45 +293,19 @@
     HRESULT hr = S_OK;
 
     //Do this like free type instead
-    UINT32 count = 0;
+    SkAutoTMalloc<SkUnichar> glyphToUni(glyphCount);
+    int maxGlyph = -1;
     for (UINT32 c = 0; c < 0x10FFFF; ++c) {
         UINT16 glyph;
         hr = fontFace->GetGlyphIndices(&c, 1, &glyph);
-        if (glyph > 0) {
-            ++count;
+        SkASSERT(glyph < glyphCount);
+        if (0 < glyph) {
+            maxGlyph = SkTMax(static_cast<int>(glyph), maxGlyph);
+            glyphToUni[glyph] = c;
         }
     }
 
-    SkAutoTArray<UINT32> chars(count);
-    count = 0;
-    for (UINT32 c = 0; c < 0x10FFFF; ++c) {
-        UINT16 glyph;
-        hr = fontFace->GetGlyphIndices(&c, 1, &glyph);
-        if (glyph > 0) {
-            chars[count] = c;
-            ++count;
-        }
-    }
-
-    SkAutoTArray<UINT16> glyph(count);
-    fontFace->GetGlyphIndices(chars.get(), count, glyph.get());
-
-    USHORT maxGlyph = 0;
-    for (USHORT j = 0; j < count; ++j) {
-        if (glyph[j] > maxGlyph) maxGlyph = glyph[j];
-    }
-
-    glyphToUnicode->setCount(maxGlyph+1);
-    for (USHORT j = 0; j < maxGlyph+1u; ++j) {
-        (*glyphToUnicode)[j] = 0;
-    }
-
-    //'invert'
-    for (USHORT j = 0; j < count; ++j) {
-        if (glyph[j] < glyphCount && (*glyphToUnicode)[glyph[j]] == 0) {
-            (*glyphToUnicode)[glyph[j]] = chars[j];
-        }
-    }
+    SkTDArray<SkUnichar>(glyphToUni, maxGlyph + 1).swap(*glyphToUnicode);
 }
 
 static bool getWidthAdvance(IDWriteFontFace* fontFace, int gId, int16_t* advance) {
@@ -371,14 +350,13 @@
     SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
     hr = fDWriteFontFamily->GetFamilyNames(&familyNames);
 
-    UINT32 familyNameLength;
-    hr = familyNames->GetStringLength(0, &familyNameLength);
+    UINT32 familyNameLen;
+    hr = familyNames->GetStringLength(0, &familyNameLen);
 
-    UINT32 size = familyNameLength+1;
-    SkSMallocWCHAR wFamilyName(size);
-    hr = familyNames->GetString(0, wFamilyName.get(), size);
+    SkSMallocWCHAR familyName(familyNameLen+1);
+    hr = familyNames->GetString(0, familyName.get(), familyNameLen+1);
 
-    hr = sk_wchar_to_skstring(wFamilyName.get(), &info->fFontName);
+    hr = sk_wchar_to_skstring(familyName.get(), familyNameLen, &info->fFontName);
 
     if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) {
         populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGlyphToUnicode));
diff --git a/src/ports/SkTypeface_win_dw.h b/src/ports/SkTypeface_win_dw.h
index 465db34..531dc51 100644
--- a/src/ports/SkTypeface_win_dw.h
+++ b/src/ports/SkTypeface_win_dw.h
@@ -17,7 +17,9 @@
 #include "SkTypes.h"
 
 #include <dwrite.h>
-#include <dwrite_1.h>
+#if SK_HAS_DWRITE_1_H
+#  include <dwrite_1.h>
+#endif
 
 class SkFontDescriptor;
 struct SkScalerContextRec;
@@ -52,11 +54,13 @@
         , fDWriteFont(SkRefComPtr(font))
         , fDWriteFontFace(SkRefComPtr(fontFace))
     {
+#if SK_HAS_DWRITE_1_H
         if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
             // IUnknown::QueryInterface states that if it fails, punk will be set to NULL.
             // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
             SK_ALWAYSBREAK(NULL == fDWriteFontFace1.get());
         }
+#endif
     }
 
 public:
@@ -66,7 +70,9 @@
     SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
     SkTScopedComPtr<IDWriteFont> fDWriteFont;
     SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
+#if SK_HAS_DWRITE_1_H
     SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
+#endif
 
     static DWriteFontTypeface* Create(IDWriteFactory* factory,
                                       IDWriteFontFace* fontFace,
@@ -105,6 +111,7 @@
                                 uint16_t glyphs[], int glyphCount) const SK_OVERRIDE;
     virtual int onCountGlyphs() const SK_OVERRIDE;
     virtual int onGetUPEM() const SK_OVERRIDE;
+    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE;
     virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
     virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
     virtual size_t onGetTableData(SkFontTableTag, size_t offset,
diff --git a/src/sfnt/SkOTTable_maxp_CFF.h b/src/sfnt/SkOTTable_maxp_CFF.h
index 873fb66..f97bff9 100644
--- a/src/sfnt/SkOTTable_maxp_CFF.h
+++ b/src/sfnt/SkOTTable_maxp_CFF.h
@@ -24,7 +24,7 @@
 
 
 #include <stddef.h>
-SK_COMPILE_ASSERT(offsetof(SkOTTableMaximumProfile_CFF, numGlyphs) == 4, SkOTTableHead_glyphDataFormat_not_at_2);
-SK_COMPILE_ASSERT(sizeof(SkOTTableMaximumProfile_CFF) == 6, sizeof_SkOTTableHead_not_4);
+SK_COMPILE_ASSERT(offsetof(SkOTTableMaximumProfile_CFF, numGlyphs) == 4, SkOTTableMaximumProfile_CFF_numGlyphs_not_at_4);
+SK_COMPILE_ASSERT(sizeof(SkOTTableMaximumProfile_CFF) == 6, sizeof_SkOTTableMaximumProfile_CFF_not_6);
 
 #endif
diff --git a/src/sfnt/SkOTTable_maxp_TT.h b/src/sfnt/SkOTTable_maxp_TT.h
index ad472a1..9aa557f 100644
--- a/src/sfnt/SkOTTable_maxp_TT.h
+++ b/src/sfnt/SkOTTable_maxp_TT.h
@@ -24,7 +24,7 @@
     SK_OT_USHORT maxCompositePoints;
     SK_OT_USHORT maxCompositeContours;
     struct MaxZones {
-        SK_TYPED_ENUM(Value, SK_OT_SHORT,
+        SK_TYPED_ENUM(Value, SK_OT_USHORT,
             ((DoesNotUseTwilightZone, SkTEndian_SwapBE16(1)))
             ((UsesTwilightZone, SkTEndian_SwapBE16(2)))
             SK_SEQ_END,
@@ -36,6 +36,7 @@
     SK_OT_USHORT maxInstructionDefs;
     SK_OT_USHORT maxStackElements;
     SK_OT_USHORT maxSizeOfInstructions;
+    SK_OT_USHORT maxComponentElements;
     SK_OT_USHORT maxComponentDepth;
 };
 
@@ -43,7 +44,7 @@
 
 
 #include <stddef.h>
-SK_COMPILE_ASSERT(offsetof(SkOTTableMaximumProfile_TT, maxComponentDepth) == 28, SkOTTableMaximumProfile_TT_maxComponentDepth_not_at_26);
-SK_COMPILE_ASSERT(sizeof(SkOTTableMaximumProfile_TT) == 30, sizeof_SkOTTableMaximumProfile_TT_not_28);
+SK_COMPILE_ASSERT(offsetof(SkOTTableMaximumProfile_TT, maxComponentDepth) == 30, SkOTTableMaximumProfile_TT_maxComponentDepth_not_at_30);
+SK_COMPILE_ASSERT(sizeof(SkOTTableMaximumProfile_TT) == 32, sizeof_SkOTTableMaximumProfile_TT_not_32);
 
 #endif
diff --git a/src/sfnt/SkOTTable_name.h b/src/sfnt/SkOTTable_name.h
index f3dae40..ab38d72 100644
--- a/src/sfnt/SkOTTable_name.h
+++ b/src/sfnt/SkOTTable_name.h
@@ -560,9 +560,9 @@
         }
 
         struct Record {
-            SK_OT_USHORT type;
             SkString name;
             SkString language;
+            SK_OT_USHORT type;
         };
         bool next(Record&);
 
diff --git a/src/sfnt/SkOTUtils.cpp b/src/sfnt/SkOTUtils.cpp
index e76d1da..0e00952 100644
--- a/src/sfnt/SkOTUtils.cpp
+++ b/src/sfnt/SkOTUtils.cpp
@@ -83,8 +83,8 @@
     size_t originalDataSize = fontData->getLength() - oldNameTablePhysicalSize;
     size_t newDataSize = originalDataSize + nameTablePhysicalSize;
 
-    SK_OT_BYTE* data = static_cast<SK_OT_BYTE*>(sk_malloc_throw(newDataSize));
-    SkAutoTUnref<SkData> rewrittenFontData(SkData::NewFromMalloc(data, newDataSize));
+    SkAutoTUnref<SkData> rewrittenFontData(SkData::NewUninitialized(newDataSize));
+    SK_OT_BYTE* data = static_cast<SK_OT_BYTE*>(rewrittenFontData->writable_data());
 
     if (fontData->read(data, oldNameTableOffset) < oldNameTableOffset) {
         return NULL;
diff --git a/src/utils/SkCanvasStateUtils.cpp b/src/utils/SkCanvasStateUtils.cpp
index e286c91..a6806dd 100644
--- a/src/utils/SkCanvasStateUtils.cpp
+++ b/src/utils/SkCanvasStateUtils.cpp
@@ -20,6 +20,11 @@
  * ANY CHANGES TO THE STRUCTS BELOW THAT IMPACT THE ABI SHOULD RESULT IN A NEW
  * NEW SUBCLASS OF SkCanvasState. SUCH CHANGES SHOULD ONLY BE MADE IF ABSOLUTELY
  * NECESSARY!
+ *
+ * In order to test changes, run the CanvasState tests. gyp/canvas_state_lib.gyp
+ * describes how to create a library to pass to the CanvasState tests. The tests
+ * should succeed when building the library with your changes and passing that to
+ * the tests running in the unchanged Skia.
  */
 enum RasterConfigs {
   kUnknown_RasterConfig   = 0,
diff --git a/include/utils/SkCondVar.h b/src/utils/SkCondVar.h
similarity index 85%
rename from include/utils/SkCondVar.h
rename to src/utils/SkCondVar.h
index 861a2ab..6f18e1a 100644
--- a/include/utils/SkCondVar.h
+++ b/src/utils/SkCondVar.h
@@ -8,10 +8,20 @@
 #ifndef SkCondVar_DEFINED
 #define SkCondVar_DEFINED
 
+/**
+ * Import any thread model setting from configuration files.
+ */
+#include "SkTypes.h"
+
 #ifdef SK_USE_POSIX_THREADS
 #include <pthread.h>
 #elif defined(SK_BUILD_FOR_WIN32)
 #include <windows.h>
+#else
+/**
+ * Warn if the implementation of this class is empty, i.e. thread safety is not working.
+ */
+#warning "Thread safety class SkCondVar has no implementation!"
 #endif
 
 /**
diff --git a/src/utils/SkCountdown.cpp b/src/utils/SkCountdown.cpp
deleted file mode 100644
index 98b3545..0000000
--- a/src/utils/SkCountdown.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkCountdown.h"
-#include "SkThread.h"
-
-SkCountdown::SkCountdown(int32_t count)
-: fCount(count) {}
-
-void SkCountdown::reset(int32_t count) {
-    fCount = count;
-}
-
-void SkCountdown::run() {
-    if (sk_atomic_dec(&fCount) == 1) {
-        fReady.lock();
-        fReady.signal();
-        fReady.unlock();
-    }
-}
-
-void SkCountdown::wait() {
-    fReady.lock();
-    while (fCount > 0) {
-        fReady.wait();
-    }
-    fReady.unlock();
-}
diff --git a/src/utils/SkDashPath.cpp b/src/utils/SkDashPath.cpp
index 3c4aef3..4b2b33d 100644
--- a/src/utils/SkDashPath.cpp
+++ b/src/utils/SkDashPath.cpp
@@ -115,14 +115,15 @@
     SkScalar minX = pts[0].fX;
     SkScalar maxX = pts[1].fX;
 
-    if (maxX < bounds.fLeft || minX > bounds.fRight) {
-        return false;
-    }
-
     if (dx < 0) {
         SkTSwap(minX, maxX);
     }
 
+    SkASSERT(minX <= maxX);
+    if (maxX < bounds.fLeft || minX > bounds.fRight) {
+        return false;
+    }
+
     // Now we actually perform the chop, removing the excess to the left and
     // right of the bounds (keeping our new line "in phase" with the dash,
     // hence the (mod intervalLength).
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index 641974b..c8402dd 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -30,8 +30,8 @@
     kSilent_PlaybackMode,
 };
 
-static bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint,
-                           size_t bitmapSizeThreshold) {
+static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint,
+                                    size_t bitmapSizeThreshold) {
     if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
         (bitmap->getSize() > bitmapSizeThreshold))) {
         return true;
@@ -46,7 +46,7 @@
         if (shader && !shader->asAGradient(NULL)) {
             SkBitmap bm;
             if (shader->asABitmap(&bm, NULL, NULL) &&
-                NULL != bm.getTexture()) {
+                bm.getTexture()) {
                 return true;
             }
         }
@@ -150,8 +150,6 @@
     bool hasPendingCommands();
     size_t storageAllocatedForRecording() const;
     size_t freeMemoryIfPossible(size_t bytesToFree);
-    size_t getBitmapSizeThreshold() const;
-    void setBitmapSizeThreshold(size_t sizeThreshold);
     void flushPendingCommands(PlaybackMode);
     void skipPendingCommands();
     void setMaxRecordingStorage(size_t);
@@ -163,7 +161,7 @@
 
     virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
 
-    virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
+    virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
 
 protected:
     virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE;
@@ -226,6 +224,10 @@
                                 SkXfermode* xmode, const uint16_t indices[],
                                 int indexCount, const SkPaint& paint) SK_OVERRIDE
         {SkASSERT(0);}
+    virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
+                           const SkPoint texCoords[4], SkXfermode* xmode,
+                           const SkPaint& paint) SK_OVERRIDE
+        {SkASSERT(0);}
     virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
                             const SkPaint&) SK_OVERRIDE
         {SkASSERT(0);}
@@ -263,7 +265,6 @@
     bool fCanDiscardCanvasContents;
     size_t fMaxRecordingStorageBytes;
     size_t fPreviousStorageAllocated;
-    size_t fBitmapSizeThreshold;
 };
 
 SkDeferredDevice::SkDeferredDevice(SkSurface* surface) {
@@ -286,7 +287,6 @@
     fFreshFrame = true;
     fCanDiscardCanvasContents = false;
     fPreviousStorageAllocated = 0;
-    fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
     fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
     fNotificationClient = NULL;
     this->beginRecording();
@@ -336,11 +336,11 @@
 
 void SkDeferredDevice::aboutToDraw()
 {
-    if (NULL != fNotificationClient) {
+    if (fNotificationClient) {
         fNotificationClient->prepareForDraw();
     }
     if (fCanDiscardCanvasContents) {
-        if (NULL != fSurface) {
+        if (fSurface) {
             fSurface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
         }
         fCanDiscardCanvasContents = false;
@@ -378,14 +378,6 @@
     return val;
 }
 
-size_t SkDeferredDevice::getBitmapSizeThreshold() const {
-    return fBitmapSizeThreshold;
-}
-
-void SkDeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) {
-    fBitmapSizeThreshold = sizeThreshold;
-}
-
 size_t SkDeferredDevice::storageAllocatedForRecording() const {
     return (fPipeController.storageAllocatedForRecording()
             + fPipeWriter.storageAllocatedForRecording());
@@ -482,8 +474,8 @@
     return immediateDevice()->createCompatibleDevice(info);
 }
 
-SkSurface* SkDeferredDevice::newSurface(const SkImageInfo& info) {
-    return this->immediateDevice()->newSurface(info);
+SkSurface* SkDeferredDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
+    return this->immediateDevice()->newSurface(info, props);
 }
 
 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
@@ -509,11 +501,9 @@
         }
     }
 private:
-    void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint)
-    {
-        SkDeferredDevice* device = static_cast<SkDeferredDevice*>(canvas.getDevice());
-        if (canvas.isDeferredDrawing() && (NULL != device) &&
-            shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold())) {
+    void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint) {
+        if (canvas.isDeferredDrawing() &&
+            should_draw_immediately(bitmap, paint, canvas.getBitmapSizeThreshold())) {
             canvas.setDeferredDrawing(false);
             fCanvas = &canvas;
         } else {
@@ -534,7 +524,10 @@
 }
 
 void SkDeferredCanvas::init() {
+    fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
     fDeferredDrawing = true; // On by default
+    fCachedCanvasSize.setEmpty();
+    fCachedCanvasSizeDirty = true;
 }
 
 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
@@ -551,9 +544,7 @@
 }
 
 void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
-    SkDeferredDevice* deferredDevice = this->getDeferredDevice();
-    SkASSERT(deferredDevice);
-    deferredDevice->setBitmapSizeThreshold(sizeThreshold);
+    fBitmapSizeThreshold = sizeThreshold;
 }
 
 void SkDeferredCanvas::recordedDrawCommand() {
@@ -600,6 +591,14 @@
     return this->getDeferredDevice()->isFreshFrame();
 }
 
+SkISize SkDeferredCanvas::getCanvasSize() const {
+    if (fCachedCanvasSizeDirty) {
+        fCachedCanvasSize = this->getBaseLayerSize();
+        fCachedCanvasSizeDirty = false;
+    }
+    return fCachedCanvasSize;
+}
+
 bool SkDeferredCanvas::hasPendingCommands() const {
     return this->getDeferredDevice()->hasPendingCommands();
 }
@@ -615,11 +614,12 @@
 
 SkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) {
     SkDeferredDevice* deferredDevice = this->getDeferredDevice();
-    SkASSERT(NULL != deferredDevice);
+    SkASSERT(deferredDevice);
     // By swapping the surface into the existing device, we preserve
     // all pending commands, which can help to seamlessly recover from
     // a lost accelerated graphics context.
     deferredDevice->setSurface(surface);
+    fCachedCanvasSizeDirty = true;
     return surface;
 }
 
@@ -643,7 +643,7 @@
 bool SkDeferredCanvas::isFullFrame(const SkRect* rect,
                                    const SkPaint* paint) const {
     SkCanvas* canvas = this->drawingCanvas();
-    SkISize canvasSize = this->getDeviceSize();
+    SkISize canvasSize = this->getCanvasSize();
     if (rect) {
         if (!canvas->getTotalMatrix().rectStaysRect()) {
             return false; // conservative
@@ -678,10 +678,10 @@
         SkIntToScalar(canvasSize.fWidth), SkIntToScalar(canvasSize.fHeight)));
 }
 
-void SkDeferredCanvas::willSave(SaveFlags flags) {
-    this->drawingCanvas()->save(flags);
+void SkDeferredCanvas::willSave() {
+    this->drawingCanvas()->save();
     this->recordedDrawCommand();
-    this->INHERITED::willSave(flags);
+    this->INHERITED::willSave();
 }
 
 SkCanvas::SaveLayerStrategy SkDeferredCanvas::willSaveLayer(const SkRect* bounds,
@@ -912,8 +912,16 @@
     this->recordedDrawCommand();
 }
 
-void SkDeferredCanvas::onDrawPicture(const SkPicture* picture) {
-    this->drawingCanvas()->drawPicture(picture);
+void SkDeferredCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                      const SkPaint& paint) {
+    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
+    this->drawingCanvas()->drawTextBlob(blob, x, y, paint);
+    this->recordedDrawCommand();
+}
+
+void SkDeferredCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                                     const SkPaint* paint) {
+    this->drawingCanvas()->drawPicture(picture, matrix, paint);
     this->recordedDrawCommand();
 }
 
@@ -929,6 +937,14 @@
     this->recordedDrawCommand();
 }
 
+void SkDeferredCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                                   const SkPoint texCoords[4], SkXfermode* xmode,
+                                   const SkPaint& paint) {
+    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
+    this->drawingCanvas()->drawPatch(cubics, colors, texCoords, xmode, paint);
+    this->recordedDrawCommand();
+}
+
 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
     this->drawingCanvas()->setDrawFilter(filter);
     this->INHERITED::setDrawFilter(filter);
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 4dfed39..e7b64a4 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -9,10 +9,12 @@
 #include "SkDumpCanvas.h"
 
 #ifdef SK_DEVELOPER
+#include "SkPatchUtils.h"
 #include "SkPicture.h"
 #include "SkPixelRef.h"
 #include "SkRRect.h"
 #include "SkString.h"
+#include "SkTextBlob.h"
 #include <stdarg.h>
 #include <stdio.h>
 
@@ -192,9 +194,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkDumpCanvas::willSave(SaveFlags flags) {
-    this->dump(kSave_Verb, NULL, "save(0x%X)", flags);
-    this->INHERITED::willSave(flags);
+void SkDumpCanvas::willSave() {
+    this->dump(kSave_Verb, NULL, "save()");
+    this->INHERITED::willSave();
 }
 
 SkCanvas::SaveLayerStrategy SkDumpCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
@@ -422,14 +424,25 @@
                str.c_str(), byteLength);
 }
 
-void SkDumpCanvas::onDrawPicture(const SkPicture* picture) {
-    this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p) %d:%d", picture,
-               picture->width(), picture->height());
+void SkDumpCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                  const SkPaint& paint) {
+    SkString str;
+    toString(blob->bounds(), &str);
+    this->dump(kDrawText_Verb, &paint, "drawTextBlob(%p) [%s]", blob, str.c_str());
+    // FIXME: dump the actual blob content?
+}
+
+void SkDumpCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                                 const SkPaint* paint) {
+    this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p) %f:%f:%f:%f", picture,
+               picture->cullRect().fLeft, picture->cullRect().fTop,
+               picture->cullRect().fRight, picture->cullRect().fBottom);
     fNestLevel += 1;
-    this->INHERITED::onDrawPicture(picture);
+    this->INHERITED::onDrawPicture(picture, matrix, paint);
     fNestLevel -= 1;
-    this->dump(kDrawPicture_Verb, NULL, "endPicture(%p) %d:%d", &picture,
-               picture->width(), picture->height());
+    this->dump(kDrawPicture_Verb, NULL, "endPicture(%p) %f:%f:%f:%f", &picture,
+               picture->cullRect().fLeft, picture->cullRect().fTop,
+               picture->cullRect().fRight, picture->cullRect().fBottom);
 }
 
 void SkDumpCanvas::drawVertices(VertexMode vmode, int vertexCount,
@@ -442,6 +455,26 @@
                SkScalarToFloat(vertices[0].fY));
 }
 
+void SkDumpCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                               const SkPoint texCoords[4], SkXfermode* xmode,
+                               const SkPaint& paint) {
+    //dumps corner points and colors in clockwise order starting on upper-left corner
+    this->dump(kDrawPatch_Verb, &paint, "drawPatch(Vertices{[%f, %f], [%f, %f], [%f, %f], [%f, %f]}\
+              | Colors{[0x%x], [0x%x], [0x%x], [0x%x]} | TexCoords{[%f,%f], [%f,%f], [%f,%f], \
+               [%f,%f]})",
+              cubics[SkPatchUtils::kTopP0_CubicCtrlPts].fX,
+              cubics[SkPatchUtils::kTopP0_CubicCtrlPts].fY,
+              cubics[SkPatchUtils::kTopP3_CubicCtrlPts].fX,
+              cubics[SkPatchUtils::kTopP3_CubicCtrlPts].fY,
+              cubics[SkPatchUtils::kBottomP3_CubicCtrlPts].fX,
+              cubics[SkPatchUtils::kBottomP3_CubicCtrlPts].fY,
+              cubics[SkPatchUtils::kBottomP0_CubicCtrlPts].fX,
+              cubics[SkPatchUtils::kBottomP0_CubicCtrlPts].fY,
+              colors[0], colors[1], colors[2], colors[3],
+              texCoords[0].x(), texCoords[0].y(), texCoords[1].x(), texCoords[1].y(),
+              texCoords[2].x(), texCoords[2].y(), texCoords[3].x(), texCoords[3].y());
+}
+
 void SkDumpCanvas::drawData(const void* data, size_t length) {
 //    this->dump(kDrawData_Verb, NULL, "drawData(%d)", length);
     this->dump(kDrawData_Verb, NULL, "drawData(%d) %.*s", length,
diff --git a/src/utils/SkEventTracer.cpp b/src/utils/SkEventTracer.cpp
index 65e8372..694becf 100644
--- a/src/utils/SkEventTracer.cpp
+++ b/src/utils/SkEventTracer.cpp
@@ -54,6 +54,6 @@
 SkEventTracer* SkEventTracer::GetInstance() {
     SK_DECLARE_STATIC_ONCE(once);
     SkOnce(&once, intialize_default_tracer, SkEventTracer::gInstance);
-    SkASSERT(NULL != SkEventTracer::gInstance);
+    SkASSERT(SkEventTracer::gInstance);
     return SkEventTracer::gInstance;
 }
diff --git a/src/utils/SkGatherPixelRefsAndRects.cpp b/src/utils/SkGatherPixelRefsAndRects.cpp
index f46fe8e..ee5b147 100644
--- a/src/utils/SkGatherPixelRefsAndRects.cpp
+++ b/src/utils/SkGatherPixelRefsAndRects.cpp
@@ -11,15 +11,15 @@
 
 void SkPictureUtils::GatherPixelRefsAndRects(SkPicture* pict,
                                              SkPictureUtils::SkPixelRefContainer* prCont) {
-    if (0 == pict->width() || 0 == pict->height()) {
+    if (pict->cullRect().isEmpty()) {
         return ;
     }
 
-    SkGatherPixelRefsAndRectsDevice device(pict->width(), pict->height(), prCont);
+    SkGatherPixelRefsAndRectsDevice device(SkScalarCeilToInt(pict->cullRect().width()), 
+                                           SkScalarCeilToInt(pict->cullRect().height()), 
+                                           prCont);
     SkNoSaveLayerCanvas canvas(&device);
 
-    canvas.clipRect(SkRect::MakeWH(SkIntToScalar(pict->width()),
-                                   SkIntToScalar(pict->height())),
-                    SkRegion::kIntersect_Op, false);
+    canvas.clipRect(pict->cullRect(), SkRegion::kIntersect_Op, false);
     canvas.drawPicture(pict);
 }
diff --git a/src/utils/SkGatherPixelRefsAndRects.h b/src/utils/SkGatherPixelRefsAndRects.h
index df3651e..e1e5ccd 100644
--- a/src/utils/SkGatherPixelRefsAndRects.h
+++ b/src/utils/SkGatherPixelRefsAndRects.h
@@ -39,12 +39,7 @@
         return fEmptyBitmap.info();
     }
 
-    virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
-
 protected:
-    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE {
-        return false;
-    }
     virtual void clear(SkColor color) SK_OVERRIDE {
         NothingToDo();
     }
@@ -108,7 +103,7 @@
         }
 
         SkRect pathBounds = path.getBounds();
-        if (NULL != prePathMatrix) {
+        if (prePathMatrix) {
             prePathMatrix->mapRect(&pathBounds);
         }
 
@@ -300,7 +295,7 @@
 
     static bool GetBitmapFromPaint(const SkPaint &paint, SkBitmap* bitmap) {
         SkShader* shader = paint.getShader();
-        if (NULL != shader) {
+        if (shader) {
             if (SkShader::kNone_GradientType == shader->asAGradient(NULL)) {
                 return SkShader::kNone_BitmapType != shader->asABitmap(bitmap, NULL, NULL);
             }
@@ -319,8 +314,6 @@
                           (info.width(), info.height(), fPRCont));
     }
 
-    virtual void flush() SK_OVERRIDE {}
-
     static void NotSupported() {
         SkDEBUGFAIL("this method should never be called");
     }
diff --git a/src/utils/SkInterpolator.cpp b/src/utils/SkInterpolator.cpp
index dd884b8..97574e4 100644
--- a/src/utils/SkInterpolator.cpp
+++ b/src/utils/SkInterpolator.cpp
@@ -269,59 +269,3 @@
     C = 3*(b - c) + Dot14_ONE;
     return SkFixedToScalar(eval_cubic(t, A, B, C) << 2);
 }
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG
-
-#ifdef SK_SUPPORT_UNITTEST
-    static SkScalar* iset(SkScalar array[3], int a, int b, int c) {
-        array[0] = SkIntToScalar(a);
-        array[1] = SkIntToScalar(b);
-        array[2] = SkIntToScalar(c);
-        return array;
-    }
-#endif
-
-void SkInterpolator::UnitTest() {
-#ifdef SK_SUPPORT_UNITTEST
-    SkInterpolator  inter(3, 2);
-    SkScalar        v1[3], v2[3], v[3], vv[3];
-    Result          result;
-
-    inter.setKeyFrame(0, 100, iset(v1, 10, 20, 30), 0);
-    inter.setKeyFrame(1, 200, iset(v2, 110, 220, 330));
-
-    result = inter.timeToValues(0, v);
-    SkASSERT(result == kFreezeStart_Result);
-    SkASSERT(memcmp(v, v1, sizeof(v)) == 0);
-
-    result = inter.timeToValues(99, v);
-    SkASSERT(result == kFreezeStart_Result);
-    SkASSERT(memcmp(v, v1, sizeof(v)) == 0);
-
-    result = inter.timeToValues(100, v);
-    SkASSERT(result == kNormal_Result);
-    SkASSERT(memcmp(v, v1, sizeof(v)) == 0);
-
-    result = inter.timeToValues(200, v);
-    SkASSERT(result == kNormal_Result);
-    SkASSERT(memcmp(v, v2, sizeof(v)) == 0);
-
-    result = inter.timeToValues(201, v);
-    SkASSERT(result == kFreezeEnd_Result);
-    SkASSERT(memcmp(v, v2, sizeof(v)) == 0);
-
-    result = inter.timeToValues(150, v);
-    SkASSERT(result == kNormal_Result);
-    SkASSERT(memcmp(v, iset(vv, 60, 120, 180), sizeof(v)) == 0);
-
-    result = inter.timeToValues(125, v);
-    SkASSERT(result == kNormal_Result);
-    result = inter.timeToValues(175, v);
-    SkASSERT(result == kNormal_Result);
-#endif
-}
-
-#endif
diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp
index 5047877..9880fe4 100644
--- a/src/utils/SkLua.cpp
+++ b/src/utils/SkLua.cpp
@@ -13,6 +13,7 @@
 
 #include "SkCanvas.h"
 #include "SkData.h"
+#include "SkDecodingImageGenerator.h"
 #include "SkDocument.h"
 #include "SkImage.h"
 #include "SkMatrix.h"
@@ -21,6 +22,7 @@
 #include "SkPixelRef.h"
 #include "SkRRect.h"
 #include "SkString.h"
+#include "SkTextBlob.h"
 #include "SkTypeface.h"
 
 extern "C" {
@@ -45,6 +47,7 @@
 DEF_MTNAME(SkPaint)
 DEF_MTNAME(SkPathEffect)
 DEF_MTNAME(SkShader)
+DEF_MTNAME(SkTextBlob)
 DEF_MTNAME(SkTypeface)
 
 template <typename T> T* push_new(lua_State* L) {
@@ -273,6 +276,11 @@
     CHECK_SETFIELD(key);
 }
 
+void SkLua::pushTextBlob(const SkTextBlob* blob, const char key[]) {
+    push_ref(fL, const_cast<SkTextBlob*>(blob));
+    CHECK_SETFIELD(key);
+}
+
 static const char* element_type(SkClipStack::Element::Type type) {
     switch (type) {
         case SkClipStack::Element::kEmpty_Type:
@@ -310,7 +318,7 @@
     SkClipStack::B2TIter iter(stack);
     const SkClipStack::Element* element;
     int i = 0;
-    while (NULL != (element = iter.next())) {
+    while ((element = iter.next())) {
         this->pushClipStackElement(*element);
         lua_rawseti(fL, -2, ++i);
     }
@@ -448,7 +456,7 @@
         paint.setAlpha(SkScalarRoundToInt(lua2scalar(L, 5) * 255));
         paintPtr = &paint;
     }
-    image->draw(canvas, x, y, paintPtr);
+    canvas->drawImage(image, x, y, paintPtr);
     return 0;
 }
 
@@ -514,7 +522,7 @@
     GrReducedClip::ElementList::Iter iter(elements);
     int i = 0;
     lua_newtable(L);
-    while(NULL != iter.get()) {
+    while(iter.get()) {
         SkLua(L).pushClipStackElement(*iter.get());
         iter.next();
         lua_rawseti(L, -2, ++i);
@@ -1157,7 +1165,7 @@
     return result;
 }
 
-static int lpath_getSegementTypes(lua_State* L) {
+static int lpath_getSegmentTypes(lua_State* L) {
     uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
     SkLua(L).pushString(segment_masks_to_str(segMasks));
     return 1;
@@ -1257,7 +1265,7 @@
 static const struct luaL_Reg gSkPath_Methods[] = {
     { "getBounds", lpath_getBounds },
     { "getFillType", lpath_getFillType },
-    { "getSegmentTypes", lpath_getSegementTypes },
+    { "getSegmentTypes", lpath_getSegmentTypes },
     { "isConvex", lpath_isConvex },
     { "isEmpty", lpath_isEmpty },
     { "isRect", lpath_isRect },
@@ -1453,7 +1461,9 @@
         const char* name = lua_tolstring(L, 1, NULL);
         SkAutoDataUnref data(SkData::NewFromFileName(name));
         if (data.get()) {
-            SkImage* image = SkImage::NewEncodedData(data.get());
+            SkImage* image = SkImage::NewFromGenerator(
+                SkDecodingImageGenerator::Create(data, SkDecodingImageGenerator::Options()));
+
             if (image) {
                 push_ref(L, image);
                 image->unref();
diff --git a/src/utils/SkLuaCanvas.cpp b/src/utils/SkLuaCanvas.cpp
index d9c5dc1..8fe1aa2 100644
--- a/src/utils/SkLuaCanvas.cpp
+++ b/src/utils/SkLuaCanvas.cpp
@@ -81,9 +81,9 @@
 
 SkLuaCanvas::~SkLuaCanvas() {}
 
-void SkLuaCanvas::willSave(SaveFlags flags) {
+void SkLuaCanvas::willSave() {
     AUTO_LUA("save");
-    this->INHERITED::willSave(flags);
+    this->INHERITED::willSave();
 }
 
 SkCanvas::SaveLayerStrategy SkLuaCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
@@ -268,10 +268,20 @@
     lua.pushPaint(paint, "paint");
 }
 
-void SkLuaCanvas::onDrawPicture(const SkPicture* picture) {
+void SkLuaCanvas::onDrawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y,
+                                 const SkPaint &paint) {
+    AUTO_LUA("drawTextBlob");
+    lua.pushTextBlob(blob, "blob");
+    lua.pushScalar(x, "x");
+    lua.pushScalar(y, "y");
+    lua.pushPaint(paint, "paint");
+}
+
+void SkLuaCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                                const SkPaint* paint) {
     AUTO_LUA("drawPicture");
     // call through so we can see the nested picture ops
-    this->INHERITED::onDrawPicture(picture);
+    this->INHERITED::onDrawPicture(picture, matrix, paint);
 }
 
 void SkLuaCanvas::drawVertices(VertexMode vmode, int vertexCount,
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index 505c05c..90fd017 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -57,13 +57,13 @@
     SkCanvas* fCanvas;
 };
 
-void SkNWayCanvas::willSave(SaveFlags flags) {
+void SkNWayCanvas::willSave() {
     Iter iter(fList);
     while (iter.next()) {
-        iter->save(flags);
+        iter->save();
     }
 
-    this->INHERITED::willSave(flags);
+    this->INHERITED::willSave();
 }
 
 SkCanvas::SaveLayerStrategy SkNWayCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
@@ -265,10 +265,19 @@
     }
 }
 
-void SkNWayCanvas::onDrawPicture(const SkPicture* picture) {
+void SkNWayCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                  const SkPaint &paint) {
     Iter iter(fList);
     while (iter.next()) {
-        iter->drawPicture(picture);
+        iter->drawTextBlob(blob, x, y, paint);
+    }
+}
+
+void SkNWayCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                                 const SkPaint* paint) {
+    Iter iter(fList);
+    while (iter.next()) {
+        iter->drawPicture(picture, matrix, paint);
     }
 }
 
@@ -284,6 +293,15 @@
     }
 }
 
+void SkNWayCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                               const SkPoint texCoords[4], SkXfermode* xmode,
+                               const SkPaint& paint) {
+    Iter iter(fList);
+    while (iter.next()) {
+        iter->drawPatch(cubics, colors, texCoords, xmode, paint);
+    }
+}
+
 void SkNWayCanvas::drawData(const void* data, size_t length) {
     Iter iter(fList);
     while (iter.next()) {
diff --git a/src/utils/SkOSFile.cpp b/src/utils/SkOSFile.cpp
index 0a40375..04a4fe9 100644
--- a/src/utils/SkOSFile.cpp
+++ b/src/utils/SkOSFile.cpp
@@ -6,16 +6,16 @@
  */
 #include "SkOSFile.h"
 
-SkString SkOSPath::SkPathJoin(const char *rootPath, const char *relativePath) {
+SkString SkOSPath::Join(const char *rootPath, const char *relativePath) {
     SkString result(rootPath);
-    if (!result.endsWith(SkPATH_SEPARATOR)) {
+    if (!result.endsWith(SkPATH_SEPARATOR) && !result.isEmpty()) {
         result.appendUnichar(SkPATH_SEPARATOR);
     }
     result.append(relativePath);
     return result;
 }
 
-SkString SkOSPath::SkBasename(const char* fullPath) {
+SkString SkOSPath::Basename(const char* fullPath) {
     if (!fullPath) {
         return SkString();
     }
@@ -28,6 +28,21 @@
     return SkString(filename);
 }
 
+SkString SkOSPath::Dirname(const char* fullPath) {
+    if (!fullPath) {
+        return SkString();
+    }
+    const char* end = strrchr(fullPath, SkPATH_SEPARATOR);
+    if (NULL == end) {
+        return SkString();
+    }
+    if (end == fullPath) {
+        SkASSERT(fullPath[0] == SkPATH_SEPARATOR);
+        ++end;
+    }
+    return SkString(fullPath, end - fullPath);
+}
+
 #ifdef SK_BUILD_FOR_WIN
 
 static uint16_t* concat_to_16(const char src[], const char suffix[])
@@ -54,17 +69,6 @@
     return dst;
 }
 
-SkUTF16_Str::SkUTF16_Str(const char src[])
-{
-    size_t  len = strlen(src);
-
-    fStr = (uint16_t*)sk_malloc_throw((len + 1) * sizeof(uint16_t));
-    size_t i;
-    for (i = 0; i < len; i++)
-        fStr[i] = src[i];
-    fStr[i] = 0;
-}
-
 ////////////////////////////////////////////////////////////////////////////
 
 SkOSFile::Iter::Iter() : fHandle(0), fPath16(NULL)
diff --git a/src/utils/SkPDFRasterizer.cpp b/src/utils/SkPDFRasterizer.cpp
index 6663480..1cb792f 100644
--- a/src/utils/SkPDFRasterizer.cpp
+++ b/src/utils/SkPDFRasterizer.cpp
@@ -50,7 +50,7 @@
   char *imgData = image.data();
 
   SkBitmap bitmap;
-  if (!bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height))) {
+  if (!bitmap.tryAllocN32Pixels(width, height)) {
     return false;
   }
   bitmap.eraseColor(SK_ColorWHITE);
diff --git a/src/utils/SkPatchGrid.cpp b/src/utils/SkPatchGrid.cpp
new file mode 100644
index 0000000..96e3c8f
--- /dev/null
+++ b/src/utils/SkPatchGrid.cpp
@@ -0,0 +1,189 @@
+/*
+ * 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 "SkPatchGrid.h"
+#include "SkPatchUtils.h"
+
+SkPatchGrid::SkPatchGrid(int rows, int cols, VertexType flags, SkXfermode* xfer)
+    : fRows(0)
+    , fCols(0)
+    , fModeFlags(kNone_VertexType)
+    , fCornerPts(NULL)
+    , fCornerColors(NULL)
+    , fTexCoords(NULL)
+    , fHrzCtrlPts(NULL)
+    , fVrtCtrlPts(NULL)
+    , fXferMode(NULL) {
+        this->reset(rows, cols, flags, xfer);
+}
+
+SkPatchGrid::~SkPatchGrid() {
+    SkDELETE_ARRAY(fCornerPts);
+    SkDELETE_ARRAY(fCornerColors);
+    SkDELETE_ARRAY(fTexCoords);
+    SkDELETE_ARRAY(fHrzCtrlPts);
+    SkDELETE_ARRAY(fVrtCtrlPts);
+}
+
+bool SkPatchGrid::setPatch(int x, int y, const SkPoint cubics[12], const SkColor colors[4],
+                           const SkPoint texCoords[4]) {
+    // Check for the passed paramaters to be within the range of the grid dimensions and a valid
+    // pointer for the cubics' control points.
+    if (x < 0 || y < 0 || x > fCols - 1 || y > fRows - 1 || NULL == cubics) {
+        return false;
+    }
+    
+    // setup corners and colors
+    int cornerPos = y * (fCols + 1) + x;
+    fCornerPts[cornerPos] = cubics[SkPatchUtils::kTopP0_CubicCtrlPts];
+    fCornerPts[cornerPos + 1] = cubics[SkPatchUtils::kTopP3_CubicCtrlPts];
+    fCornerPts[cornerPos + (fCols + 1)] = cubics[SkPatchUtils::kBottomP0_CubicCtrlPts];
+    fCornerPts[cornerPos + (fCols + 1) + 1] = cubics[SkPatchUtils::kBottomP3_CubicCtrlPts];
+    
+    // set horizontal control points
+    int hrzPos = y * (fCols * 2) + (x * 2);
+    fHrzCtrlPts[hrzPos] = cubics[SkPatchUtils::kTopP1_CubicCtrlPts];
+    fHrzCtrlPts[hrzPos + 1] = cubics[SkPatchUtils::kTopP2_CubicCtrlPts];
+    fHrzCtrlPts[hrzPos + (fCols * 2)] = cubics[SkPatchUtils::kBottomP1_CubicCtrlPts];
+    fHrzCtrlPts[hrzPos + (fCols * 2) + 1] = cubics[SkPatchUtils::kBottomP2_CubicCtrlPts];
+    
+    // set vertical control points
+    int vrtPos = (y*2) * (fCols + 1) + x;
+    fVrtCtrlPts[vrtPos] = cubics[SkPatchUtils::kLeftP1_CubicCtrlPts];
+    fVrtCtrlPts[vrtPos + 1] = cubics[SkPatchUtils::kRightP1_CubicCtrlPts];
+    fVrtCtrlPts[vrtPos + (fCols + 1)] = cubics[SkPatchUtils::kLeftP2_CubicCtrlPts];
+    fVrtCtrlPts[vrtPos + (fCols + 1) + 1] = cubics[SkPatchUtils::kRightP2_CubicCtrlPts];
+    
+    // set optional values (colors and texture coordinates)
+    if ((fModeFlags & kColors_VertexType)  && colors) {
+        fCornerColors[cornerPos] = colors[0];
+        fCornerColors[cornerPos + 1] = colors[1];
+        fCornerColors[cornerPos + (fCols + 1)] = colors[3];
+        fCornerColors[cornerPos + (fCols + 1) + 1] = colors[2];
+    }
+    
+    if ((fModeFlags & kTexs_VertexType) && texCoords) {
+        fTexCoords[cornerPos] = texCoords[0];
+        fTexCoords[cornerPos + 1] = texCoords[1];
+        fTexCoords[cornerPos + (fCols + 1)] = texCoords[3];
+        fTexCoords[cornerPos + (fCols + 1) + 1] = texCoords[2];
+    }
+    
+    return true;
+}
+
+bool SkPatchGrid::getPatch(int x, int y, SkPoint cubics[12], SkColor colors[4],
+                           SkPoint texCoords[4]) const {
+    
+    if (x < 0 || y < 0 || x > fCols - 1 || y > fRows - 1 || NULL == cubics) {
+        return false;
+    }
+    
+    // set the patch by building the array of points and colors with the corresponding values.
+    int cornerPos = y * (fCols + 1) + x;
+    cubics[SkPatchUtils::kTopP0_CubicCtrlPts] = fCornerPts[cornerPos];
+    cubics[SkPatchUtils::kTopP3_CubicCtrlPts] = fCornerPts[cornerPos + 1];
+    cubics[SkPatchUtils::kBottomP0_CubicCtrlPts] = fCornerPts[cornerPos + (fCols + 1)];
+    cubics[SkPatchUtils::kBottomP3_CubicCtrlPts] = fCornerPts[cornerPos + (fCols + 1) + 1];
+    
+    int hrzPos = y * (fCols * 2) + (x * 2);
+    cubics[SkPatchUtils::kTopP1_CubicCtrlPts] = fHrzCtrlPts[hrzPos];
+    cubics[SkPatchUtils::kTopP2_CubicCtrlPts] = fHrzCtrlPts[hrzPos + 1];
+    cubics[SkPatchUtils::kBottomP1_CubicCtrlPts] = fHrzCtrlPts[hrzPos + (fCols * 2)];
+    cubics[SkPatchUtils::kBottomP2_CubicCtrlPts] = fHrzCtrlPts[hrzPos + (fCols * 2) + 1];
+    
+    int vrtPos = (y*2) * (fCols + 1) + x;
+    cubics[SkPatchUtils::kLeftP1_CubicCtrlPts] = fVrtCtrlPts[vrtPos];
+    cubics[SkPatchUtils::kRightP1_CubicCtrlPts] = fVrtCtrlPts[vrtPos + 1];
+    cubics[SkPatchUtils::kLeftP2_CubicCtrlPts] = fVrtCtrlPts[vrtPos + (fCols + 1)];
+    cubics[SkPatchUtils::kRightP2_CubicCtrlPts] = fVrtCtrlPts[vrtPos + (fCols + 1) + 1];
+    
+    if ((fModeFlags & kColors_VertexType)  && colors) {
+        colors[0] = fCornerColors[cornerPos];
+        colors[1] = fCornerColors[cornerPos + 1];
+        colors[3] = fCornerColors[cornerPos + (fCols + 1)];
+        colors[2] = fCornerColors[cornerPos + (fCols + 1) + 1];
+    }
+    
+    if ((fModeFlags & kTexs_VertexType)  && texCoords) {
+        texCoords[0] = fTexCoords[cornerPos];
+        texCoords[1] = fTexCoords[cornerPos + 1];
+        texCoords[3] = fTexCoords[cornerPos + (fCols + 1)];
+        texCoords[2] = fTexCoords[cornerPos + (fCols + 1) + 1];
+    }
+    
+    return true;
+}
+
+void SkPatchGrid::reset(int rows, int cols, VertexType flags, SkXfermode* xMode) {
+    SkDELETE_ARRAY(fCornerPts);
+    SkDELETE_ARRAY(fCornerColors);
+    SkDELETE_ARRAY(fTexCoords);
+    SkDELETE_ARRAY(fHrzCtrlPts);
+    SkDELETE_ARRAY(fVrtCtrlPts);
+    
+    fCols = cols;
+    fRows = rows;
+    fModeFlags = flags;
+    fXferMode = xMode;
+    
+    fCornerPts = SkNEW_ARRAY(SkPoint, (fRows + 1) * (fCols + 1));
+    fHrzCtrlPts = SkNEW_ARRAY(SkPoint, (fRows + 1) * fCols * 2);
+    fVrtCtrlPts = SkNEW_ARRAY(SkPoint, fRows * 2 * (fCols + 1));
+    memset(fCornerPts, 0, (fRows + 1) * (fCols + 1) * sizeof(SkPoint));
+    memset(fHrzCtrlPts, 0, (fRows + 1) * fCols * 2 * sizeof(SkPoint));
+    memset(fVrtCtrlPts, 0, fRows * 2 * (fCols + 1) * sizeof(SkPoint));
+    
+    if (fModeFlags & kColors_VertexType) {
+        fCornerColors = SkNEW_ARRAY(SkColor, (fRows + 1) * (fCols + 1));
+        memset(fCornerColors, 0, (fRows + 1) * (fCols + 1) * sizeof(SkColor));
+    }
+    
+    if (fModeFlags & kTexs_VertexType) {
+        fTexCoords = SkNEW_ARRAY(SkPoint, (fRows + 1) * (fCols + 1));
+        memset(fTexCoords, 0, (fRows + 1) * (fCols + 1) * sizeof(SkPoint));
+    }
+}
+
+void SkPatchGrid::draw(SkCanvas* canvas, SkPaint& paint) {
+    int* maxCols = SkNEW_ARRAY(int, fCols);
+    int* maxRows = SkNEW_ARRAY(int, fRows);
+    memset(maxCols, 0, fCols * sizeof(int));
+    memset(maxRows, 0, fRows * sizeof(int));
+    
+    // Get the maximum level of detail per axis for each row and column
+    for (int y = 0; y < fRows; y++) {
+        for (int x = 0; x < fCols; x++) {
+            SkPoint cubics[12];
+            this->getPatch(x, y, cubics, NULL, NULL);
+            SkMatrix matrix = canvas->getTotalMatrix();
+            SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &matrix);
+            maxCols[x] = SkMax32(maxCols[x], lod.width());
+            maxRows[y] = SkMax32(maxRows[y], lod.height());
+        }
+    }
+    // Draw the patches by generating their geometry with the maximum level of detail per axis.
+    for (int x = 0; x < fCols; x++) {
+        for (int y = 0; y < fRows; y++) {
+            SkPoint cubics[12];
+            SkPoint texCoords[4];
+            SkColor colors[4];
+            this->getPatch(x, y, cubics, colors, texCoords);
+            SkPatchUtils::VertexData data;
+            if (SkPatchUtils::getVertexData(&data, cubics,
+                                            fModeFlags & kColors_VertexType ? colors : NULL,
+                                            fModeFlags & kTexs_VertexType ? texCoords : NULL,
+                                            maxCols[x], maxRows[y])) {
+                canvas->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount,
+                                     data.fPoints, data.fTexCoords, data.fColors, fXferMode,
+                                     data.fIndices, data.fIndexCount, paint);
+            }
+        }
+    }
+    SkDELETE_ARRAY(maxCols);
+    SkDELETE_ARRAY(maxRows);
+}
diff --git a/src/utils/SkPatchGrid.h b/src/utils/SkPatchGrid.h
new file mode 100644
index 0000000..cf90098
--- /dev/null
+++ b/src/utils/SkPatchGrid.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPatchGrid_DEFINED
+#define SkPatchGrid_DEFINED
+
+#include "SkCanvas.h"
+#include "SkPatchUtils.h"
+#include "SkXfermode.h"
+
+/**
+ * Class that represents a grid of patches. Adjacent patches share their corners and a color is 
+ * specified at each one of them. The colors are bilinearly interpolated across the patch.
+ *
+ * This implementation defines a bidimensional array of patches. There are 3 arrays to store the 
+ * control points of the patches to avoid storing repeated data since there are several points
+ * shared between adjacent patches. 
+ *
+ * The array fCornerPts stores the corner control points of the patches.
+ * The array fHrzPts holds the intermidiate control points of the top and bottom curves of a patch.
+ * The array fVrtPts holds the intermidiate control points of the left and right curves of a patch.
+ * The array fCornerColors holds the corner colors in the same format as fCornerPts.
+ * The array fTexCoords holds the texture coordinates in the same format as fCornerpts.
+ *
+ *               fCornerPts               fHrzPts                  fVrtPts
+ *             --------------       -------------------         --------------
+ *            | C0 | C1 | C2 |     | H0 | H1 | H2 | H3 |       | V0 | V1 | V2 |
+ *             --------------       ------------------         ---------------
+ *            | C3 | C4 | C5 |     | H4 | H5 | H6 | H7 |       | V4 | V5 | V6 |
+ *             --------------       -------------------         --------------
+ *            | C6 | C7 | C8 |     | H8 | H9 | H10| H11|       | V6 | V7 | V8 |
+ *             --------------       -------------------         --------------
+ *                                                             | V9 | V10| V11|
+ *                                                              --------------
+ *
+ * With the above configuration we would have a 2x2 grid of patches:
+ *               H0     H1 H2   H3
+ *              /        \/      \
+ *              C0-------C1-------C2
+ *             /|        |        |\
+ *           v0 |        v1       | v2
+ *           v3 |        V4       | v5
+ *             \|        |        |/
+ *              C3-H4-H5-C4-H6-H7-C5
+ *             /|        |        |\
+ *           v6 |        v7       | v8
+ *           v9 |        v10      | v11
+ *             \|        |        |/
+ *              C6-------C7-------C8
+ *               \      / \      /
+ *                H8   H9  H10  H11
+ *
+ * When trying to get a patch at a certain position it justs builds it with the corresponding 
+ * points.
+ * When adding a patch it tries to add the points at their corresponding position trying to comply
+ * with the adjacent points or overwriting them.
+ * 
+ * Based the idea on the SVG2 spec for mesh gradients in which a grid of patches is build as in the
+ * the following example:
+ * <meshGradient x="100" y="100">
+ *      <meshRow>
+ *          <meshPatch>
+ *              <stop .../>
+ *              Up to four stops in first patch. See details below.
+ *          </meshPatch>
+ *          <meshPatch>
+ *              Any number of meshPatches in row.
+ *          </meshPatch>
+ *      </meshRow>
+ *      <meshRow>
+ *          Any number of meshRows, each with the same number of meshPatches as in the first row.
+ *      </meshRow>
+ * </meshGradient>
+ */
+class SkPatchGrid {
+    
+public:
+    
+    enum VertexType {
+        kNone_VertexType = 0X00,
+        kColors_VertexType = 0x01,
+        kTexs_VertexType = 0x02,
+        kColorsAndTexs_VertexType = 0x03
+    };
+    
+    SkPatchGrid(int rows = 0, int cols = 0, VertexType flags = kNone_VertexType,
+                SkXfermode* xfer = NULL);
+    
+    ~SkPatchGrid();
+    
+    /**
+     * Add a patch at location (x,y) overwriting the previous patch and shared points so they 
+     * mantain C0 connectivity.
+     * The control points must be passed in a clockwise order starting at the top left corner.
+     * The colors and texCoords are the values at the corners of the patch which will be bilerp 
+     * across it, they must also be in counterclockwise order starting at the top left corner.
+     */
+    bool setPatch(int x, int y, const SkPoint cubics[12], const SkColor colors[4],
+                  const SkPoint texCoords[4]);
+    
+    /**
+     * Get patch at location (x,y). If cubics, colors or texCoords is not NULL it sets patch's
+     * array with its corresponding values.
+     * The function returns false if the cubics parameter is NULL or if the (x,y) coordinates are 
+     * not within the range of the grid.
+     */
+    bool getPatch(int x, int y, SkPoint cubics[12], SkColor colors[4], SkPoint texCoords[4]) const;
+    
+    /**
+     * Resets the grid of patches to contain rows and cols of patches.
+     */
+    void reset(int rows, int cols, VertexType flags, SkXfermode* xMode);
+    
+    /**
+     * Draws the grid of patches. The patches are drawn starting at patch (0,0) drawing columns, so 
+     * for a 2x2 grid the order would be (0,0)->(0,1)->(1,0)->(1,1). The order follows the order 
+     * of the parametric coordinates of the coons patch.
+     */
+    void draw(SkCanvas* canvas, SkPaint& paint);
+    
+    /**
+     * Get the dimensions of the grid of patches.
+     */
+    SkISize getDimensions() const {
+        return SkISize::Make(fCols, fRows);
+    }
+    
+private:
+    int fRows, fCols;
+    VertexType fModeFlags;
+    SkPoint* fCornerPts;
+    SkColor* fCornerColors;
+    SkPoint* fTexCoords;
+    SkPoint* fHrzCtrlPts;
+    SkPoint* fVrtCtrlPts;
+    SkXfermode* fXferMode;
+};
+
+
+#endif
diff --git a/src/utils/SkPatchUtils.cpp b/src/utils/SkPatchUtils.cpp
new file mode 100644
index 0000000..c9c526e
--- /dev/null
+++ b/src/utils/SkPatchUtils.cpp
@@ -0,0 +1,341 @@
+/*
+ * 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 "SkPatchUtils.h"
+
+#include "SkColorPriv.h"
+#include "SkGeometry.h"
+
+/**
+ * Evaluator to sample the values of a cubic bezier using forward differences.
+ * Forward differences is a method for evaluating a nth degree polynomial at a uniform step by only
+ * adding precalculated values.
+ * For a linear example we have the function f(t) = m*t+b, then the value of that function at t+h
+ * would be f(t+h) = m*(t+h)+b. If we want to know the uniform step that we must add to the first
+ * evaluation f(t) then we need to substract f(t+h) - f(t) = m*t + m*h + b - m*t + b = mh. After
+ * obtaining this value (mh) we could just add this constant step to our first sampled point
+ * to compute the next one.
+ *
+ * For the cubic case the first difference gives as a result a quadratic polynomial to which we can
+ * apply again forward differences and get linear function to which we can apply again forward
+ * differences to get a constant difference. This is why we keep an array of size 4, the 0th
+ * position keeps the sampled value while the next ones keep the quadratic, linear and constant
+ * difference values.
+ */
+
+class FwDCubicEvaluator {
+    
+public:
+    FwDCubicEvaluator()
+    : fMax(0)
+    , fCurrent(0)
+    , fDivisions(0) {
+        memset(fPoints, 0, 4 * sizeof(SkPoint));
+        memset(fPoints, 0, 4 * sizeof(SkPoint));
+        memset(fPoints, 0, 4 * sizeof(SkPoint));
+    }
+    
+    /**
+     * Receives the 4 control points of the cubic bezier.
+     */
+    FwDCubicEvaluator(SkPoint a, SkPoint b, SkPoint c, SkPoint d) {
+        fPoints[0] = a;
+        fPoints[1] = b;
+        fPoints[2] = c;
+        fPoints[3] = d;
+        
+        SkScalar cx[4], cy[4];
+        SkGetCubicCoeff(fPoints, cx, cy);
+        fCoefs[0].set(cx[0], cy[0]);
+        fCoefs[1].set(cx[1], cy[1]);
+        fCoefs[2].set(cx[2], cy[2]);
+        fCoefs[3].set(cx[3], cy[3]);
+        
+        this->restart(1);
+    }
+    
+    explicit FwDCubicEvaluator(const SkPoint points[4])  {
+        memcpy(fPoints, points, 4 * sizeof(SkPoint));
+        
+        SkScalar cx[4], cy[4];
+        SkGetCubicCoeff(fPoints, cx, cy);
+        fCoefs[0].set(cx[0], cy[0]);
+        fCoefs[1].set(cx[1], cy[1]);
+        fCoefs[2].set(cx[2], cy[2]);
+        fCoefs[3].set(cx[3], cy[3]);
+        
+        this->restart(1);
+    }
+    
+    /**
+     * Restarts the forward differences evaluator to the first value of t = 0.
+     */
+    void restart(int divisions)  {
+        fDivisions = divisions;
+        SkScalar h  = 1.f / fDivisions;
+        fCurrent    = 0;
+        fMax        = fDivisions + 1;
+        fFwDiff[0]  = fCoefs[3];
+        SkScalar h2 = h * h;
+        SkScalar h3 = h2 * h;
+        
+        fFwDiff[3].set(6.f * fCoefs[0].x() * h3, 6.f * fCoefs[0].y() * h3); //6ah^3
+        fFwDiff[2].set(fFwDiff[3].x() + 2.f * fCoefs[1].x() * h2, //6ah^3 + 2bh^2
+                       fFwDiff[3].y() + 2.f * fCoefs[1].y() * h2);
+        fFwDiff[1].set(fCoefs[0].x() * h3 + fCoefs[1].x() * h2 + fCoefs[2].x() * h,//ah^3 + bh^2 +ch
+                       fCoefs[0].y() * h3 + fCoefs[1].y() * h2 + fCoefs[2].y() * h);
+    }
+    
+    /**
+     * Check if the evaluator is still within the range of 0<=t<=1
+     */
+    bool done() const {
+        return fCurrent > fMax;
+    }
+    
+    /**
+     * Call next to obtain the SkPoint sampled and move to the next one.
+     */
+    SkPoint next() {
+        SkPoint point = fFwDiff[0];
+        fFwDiff[0]    += fFwDiff[1];
+        fFwDiff[1]    += fFwDiff[2];
+        fFwDiff[2]    += fFwDiff[3];
+        fCurrent++;
+        return point;
+    }
+    
+    const SkPoint* getCtrlPoints() const {
+        return fPoints;
+    }
+    
+private:
+    int fMax, fCurrent, fDivisions;
+    SkPoint fFwDiff[4], fCoefs[4], fPoints[4];
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+// size in pixels of each partition per axis, adjust this knob
+static const int kPartitionSize = 10;
+
+/**
+ * Calculate the approximate arc length given a bezier curve's control points.
+ */
+static SkScalar approx_arc_length(SkPoint* points, int count) {
+    if (count < 2) {
+        return 0;
+    }
+    SkScalar arcLength = 0;
+    for (int i = 0; i < count - 1; i++) {
+        arcLength += SkPoint::Distance(points[i], points[i + 1]);
+    }
+    return arcLength;
+}
+
+static SkScalar bilerp(SkScalar tx, SkScalar ty, SkScalar c00, SkScalar c10, SkScalar c01,
+                      SkScalar c11) {
+    SkScalar a = c00 * (1.f - tx) + c10 * tx;
+    SkScalar b = c01 * (1.f - tx) + c11 * tx;
+    return a * (1.f - ty) + b * ty;
+}
+
+SkISize SkPatchUtils::GetLevelOfDetail(const SkPoint cubics[12], const SkMatrix* matrix) {
+    
+    // Approximate length of each cubic.
+    SkPoint pts[kNumPtsCubic];
+    SkPatchUtils::getTopCubic(cubics, pts);
+    matrix->mapPoints(pts, kNumPtsCubic);
+    SkScalar topLength = approx_arc_length(pts, kNumPtsCubic);
+    
+    SkPatchUtils::getBottomCubic(cubics, pts);
+    matrix->mapPoints(pts, kNumPtsCubic);
+    SkScalar bottomLength = approx_arc_length(pts, kNumPtsCubic);
+    
+    SkPatchUtils::getLeftCubic(cubics, pts);
+    matrix->mapPoints(pts, kNumPtsCubic);
+    SkScalar leftLength = approx_arc_length(pts, kNumPtsCubic);
+    
+    SkPatchUtils::getRightCubic(cubics, pts);
+    matrix->mapPoints(pts, kNumPtsCubic);
+    SkScalar rightLength = approx_arc_length(pts, kNumPtsCubic);
+    
+    // Level of detail per axis, based on the larger side between top and bottom or left and right
+    int lodX = static_cast<int>(SkMaxScalar(topLength, bottomLength) / kPartitionSize);
+    int lodY = static_cast<int>(SkMaxScalar(leftLength, rightLength) / kPartitionSize);
+    
+    return SkISize::Make(SkMax32(8, lodX), SkMax32(8, lodY));
+}
+
+void SkPatchUtils::getTopCubic(const SkPoint cubics[12], SkPoint points[4]) {
+    points[0] = cubics[kTopP0_CubicCtrlPts];
+    points[1] = cubics[kTopP1_CubicCtrlPts];
+    points[2] = cubics[kTopP2_CubicCtrlPts];
+    points[3] = cubics[kTopP3_CubicCtrlPts];
+}
+
+void SkPatchUtils::getBottomCubic(const SkPoint cubics[12], SkPoint points[4]) {
+    points[0] = cubics[kBottomP0_CubicCtrlPts];
+    points[1] = cubics[kBottomP1_CubicCtrlPts];
+    points[2] = cubics[kBottomP2_CubicCtrlPts];
+    points[3] = cubics[kBottomP3_CubicCtrlPts];
+}
+
+void SkPatchUtils::getLeftCubic(const SkPoint cubics[12], SkPoint points[4]) {
+    points[0] = cubics[kLeftP0_CubicCtrlPts];
+    points[1] = cubics[kLeftP1_CubicCtrlPts];
+    points[2] = cubics[kLeftP2_CubicCtrlPts];
+    points[3] = cubics[kLeftP3_CubicCtrlPts];
+}
+
+void SkPatchUtils::getRightCubic(const SkPoint cubics[12], SkPoint points[4]) {
+    points[0] = cubics[kRightP0_CubicCtrlPts];
+    points[1] = cubics[kRightP1_CubicCtrlPts];
+    points[2] = cubics[kRightP2_CubicCtrlPts];
+    points[3] = cubics[kRightP3_CubicCtrlPts];
+}
+
+bool SkPatchUtils::getVertexData(SkPatchUtils::VertexData* data, const SkPoint cubics[12],
+                   const SkColor colors[4], const SkPoint texCoords[4], int lodX, int lodY) {
+    if (lodX < 1 || lodY < 1 || NULL == cubics || NULL == data) {
+        return false;
+    }
+
+    // check for overflow in multiplication
+    const int64_t lodX64 = (lodX + 1),
+                   lodY64 = (lodY + 1),
+                   mult64 = lodX64 * lodY64;
+    if (mult64 > SK_MaxS32) {
+        return false;
+    }
+    data->fVertexCount = SkToS32(mult64);
+
+    // it is recommended to generate draw calls of no more than 65536 indices, so we never generate
+    // more than 60000 indices. To accomplish that we resize the LOD and vertex count
+    if (data->fVertexCount > 10000 || lodX > 200 || lodY > 200) {
+        SkScalar weightX = static_cast<SkScalar>(lodX) / (lodX + lodY);
+        SkScalar weightY = static_cast<SkScalar>(lodY) / (lodX + lodY);
+
+        // 200 comes from the 100 * 2 which is the max value of vertices because of the limit of
+        // 60000 indices ( sqrt(60000 / 6) that comes from data->fIndexCount = lodX * lodY * 6)
+        lodX = static_cast<int>(weightX * 200);
+        lodY = static_cast<int>(weightY * 200);
+        data->fVertexCount = (lodX + 1) * (lodY + 1);
+    }
+    data->fIndexCount = lodX * lodY * 6;
+    
+    data->fPoints = SkNEW_ARRAY(SkPoint, data->fVertexCount);
+    data->fIndices = SkNEW_ARRAY(uint16_t, data->fIndexCount);
+    
+    // if colors is not null then create array for colors
+    SkPMColor colorsPM[kNumCorners];
+    if (colors) {
+        // premultiply colors to avoid color bleeding.
+        for (int i = 0; i < kNumCorners; i++) {
+            colorsPM[i] = SkPreMultiplyColor(colors[i]);
+        }
+        data->fColors = SkNEW_ARRAY(uint32_t, data->fVertexCount);
+    }
+    
+    // if texture coordinates are not null then create array for them
+    if (texCoords) {
+        data->fTexCoords = SkNEW_ARRAY(SkPoint, data->fVertexCount);
+    }
+    
+    SkPoint pts[kNumPtsCubic];
+    SkPatchUtils::getBottomCubic(cubics, pts);
+    FwDCubicEvaluator fBottom(pts);
+    SkPatchUtils::getTopCubic(cubics, pts);
+    FwDCubicEvaluator fTop(pts);
+    SkPatchUtils::getLeftCubic(cubics, pts);
+    FwDCubicEvaluator fLeft(pts);
+    SkPatchUtils::getRightCubic(cubics, pts);
+    FwDCubicEvaluator fRight(pts);
+    
+    fBottom.restart(lodX);
+    fTop.restart(lodX);
+    
+    SkScalar u = 0.0f;
+    int stride = lodY + 1;
+    for (int x = 0; x <= lodX; x++) {
+        SkPoint bottom = fBottom.next(), top = fTop.next();
+        fLeft.restart(lodY);
+        fRight.restart(lodY);
+        SkScalar v = 0.f;
+        for (int y = 0; y <= lodY; y++) {
+            int dataIndex = x * (lodY + 1) + y;
+            
+            SkPoint left = fLeft.next(), right = fRight.next();
+            
+            SkPoint s0 = SkPoint::Make((1.0f - v) * top.x() + v * bottom.x(),
+                                       (1.0f - v) * top.y() + v * bottom.y());
+            SkPoint s1 = SkPoint::Make((1.0f - u) * left.x() + u * right.x(),
+                                       (1.0f - u) * left.y() + u * right.y());
+            SkPoint s2 = SkPoint::Make(
+                                       (1.0f - v) * ((1.0f - u) * fTop.getCtrlPoints()[0].x()
+                                                     + u * fTop.getCtrlPoints()[3].x())
+                                       + v * ((1.0f - u) * fBottom.getCtrlPoints()[0].x()
+                                              + u * fBottom.getCtrlPoints()[3].x()),
+                                       (1.0f - v) * ((1.0f - u) * fTop.getCtrlPoints()[0].y()
+                                                     + u * fTop.getCtrlPoints()[3].y())
+                                       + v * ((1.0f - u) * fBottom.getCtrlPoints()[0].y()
+                                              + u * fBottom.getCtrlPoints()[3].y()));
+            data->fPoints[dataIndex] = s0 + s1 - s2;
+            
+            if (colors) {
+                uint8_t a = uint8_t(bilerp(u, v,
+                                   SkScalar(SkColorGetA(colorsPM[kTopLeft_Corner])),
+                                   SkScalar(SkColorGetA(colorsPM[kTopRight_Corner])),
+                                   SkScalar(SkColorGetA(colorsPM[kBottomLeft_Corner])),
+                                   SkScalar(SkColorGetA(colorsPM[kBottomRight_Corner]))));
+                uint8_t r = uint8_t(bilerp(u, v,
+                                   SkScalar(SkColorGetR(colorsPM[kTopLeft_Corner])),
+                                   SkScalar(SkColorGetR(colorsPM[kTopRight_Corner])),
+                                   SkScalar(SkColorGetR(colorsPM[kBottomLeft_Corner])),
+                                   SkScalar(SkColorGetR(colorsPM[kBottomRight_Corner]))));
+                uint8_t g = uint8_t(bilerp(u, v,
+                                   SkScalar(SkColorGetG(colorsPM[kTopLeft_Corner])),
+                                   SkScalar(SkColorGetG(colorsPM[kTopRight_Corner])),
+                                   SkScalar(SkColorGetG(colorsPM[kBottomLeft_Corner])),
+                                   SkScalar(SkColorGetG(colorsPM[kBottomRight_Corner]))));
+                uint8_t b = uint8_t(bilerp(u, v,
+                                   SkScalar(SkColorGetB(colorsPM[kTopLeft_Corner])),
+                                   SkScalar(SkColorGetB(colorsPM[kTopRight_Corner])),
+                                   SkScalar(SkColorGetB(colorsPM[kBottomLeft_Corner])),
+                                   SkScalar(SkColorGetB(colorsPM[kBottomRight_Corner]))));
+                data->fColors[dataIndex] = SkPackARGB32(a,r,g,b);
+            }
+            
+            if (texCoords) {
+                data->fTexCoords[dataIndex] = SkPoint::Make(
+                                            bilerp(u, v, texCoords[kTopLeft_Corner].x(),
+                                                   texCoords[kTopRight_Corner].x(),
+                                                   texCoords[kBottomLeft_Corner].x(),
+                                                   texCoords[kBottomRight_Corner].x()),
+                                            bilerp(u, v, texCoords[kTopLeft_Corner].y(),
+                                                   texCoords[kTopRight_Corner].y(),
+                                                   texCoords[kBottomLeft_Corner].y(),
+                                                   texCoords[kBottomRight_Corner].y()));
+                
+            }
+            
+            if(x < lodX && y < lodY) {
+                int i = 6 * (x * lodY + y);
+                data->fIndices[i] = x * stride + y;
+                data->fIndices[i + 1] = x * stride + 1 + y;
+                data->fIndices[i + 2] = (x + 1) * stride + 1 + y;
+                data->fIndices[i + 3] = data->fIndices[i];
+                data->fIndices[i + 4] = data->fIndices[i + 2];
+                data->fIndices[i + 5] = (x + 1) * stride + y;
+            }
+            v = SkScalarClampMax(v + 1.f / lodY, 1);
+        }
+        u = SkScalarClampMax(u + 1.f / lodX, 1);
+    }
+    return true;
+
+}
diff --git a/src/utils/SkPatchUtils.h b/src/utils/SkPatchUtils.h
new file mode 100644
index 0000000..879053a
--- /dev/null
+++ b/src/utils/SkPatchUtils.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPatchUtils_DEFINED
+#define SkPatchUtils_DEFINED
+
+#include "SkColorPriv.h"
+#include "SkMatrix.h"
+
+class SK_API SkPatchUtils {
+    
+public:
+    /**
+     * Structure that holds the vertex data related to the tessellation of a patch. It is passed
+     * as a parameter to the function getVertexData which sets the points, colors and texture
+     * coordinates of the vertices and the indices for them to be drawn as triangles.
+     */
+    struct VertexData {
+        int fVertexCount, fIndexCount;
+        SkPoint* fPoints;
+        SkPoint* fTexCoords;
+        uint32_t* fColors;
+        uint16_t* fIndices;
+        
+        VertexData()
+        : fVertexCount(0)
+        , fIndexCount(0)
+        , fPoints(NULL)
+        , fTexCoords(NULL)
+        , fColors(NULL)
+        , fIndices(NULL) { }
+        
+        ~VertexData() {
+            SkDELETE_ARRAY(fPoints);
+            SkDELETE_ARRAY(fTexCoords);
+            SkDELETE_ARRAY(fColors);
+            SkDELETE_ARRAY(fIndices);
+        }
+    };
+    
+    // Enums for control points based on the order specified in the constructor (clockwise).
+    enum CubicCtrlPts {
+        kTopP0_CubicCtrlPts = 0,
+        kTopP1_CubicCtrlPts = 1,
+        kTopP2_CubicCtrlPts = 2,
+        kTopP3_CubicCtrlPts = 3,
+        
+        kRightP0_CubicCtrlPts = 3,
+        kRightP1_CubicCtrlPts = 4,
+        kRightP2_CubicCtrlPts = 5,
+        kRightP3_CubicCtrlPts = 6,
+        
+        kBottomP0_CubicCtrlPts = 9,
+        kBottomP1_CubicCtrlPts = 8,
+        kBottomP2_CubicCtrlPts = 7,
+        kBottomP3_CubicCtrlPts = 6,
+        
+        kLeftP0_CubicCtrlPts = 0,
+        kLeftP1_CubicCtrlPts = 11,
+        kLeftP2_CubicCtrlPts = 10,
+        kLeftP3_CubicCtrlPts = 9,
+    };
+    
+    // Enum for corner also clockwise.
+    enum Corner {
+        kTopLeft_Corner = 0,
+        kTopRight_Corner,
+        kBottomRight_Corner,
+        kBottomLeft_Corner
+    };
+    
+    enum {
+        kNumCtrlPts = 12,
+        kNumCorners = 4,
+        kNumPtsCubic = 4
+    };
+    
+    /**
+     * Method that calculates a level of detail (number of subdivisions) for a patch in both axis. 
+     */
+    static SkISize GetLevelOfDetail(const SkPoint cubics[12], const SkMatrix* matrix);
+    
+    /**
+     * Get the points corresponding to the top cubic of cubics.
+     */
+    static void getTopCubic(const SkPoint cubics[12], SkPoint points[4]);
+    
+    /**
+     * Get the points corresponding to the bottom cubic of cubics.
+     */
+    static void getBottomCubic(const SkPoint cubics[12], SkPoint points[4]);
+    
+    /**
+     * Get the points corresponding to the left cubic of cubics.
+     */
+    static void getLeftCubic(const SkPoint cubics[12], SkPoint points[4]);
+    
+    /**
+     * Get the points corresponding to the right cubic of cubics.
+     */
+    static void getRightCubic(const SkPoint cubics[12], SkPoint points[4]);
+    
+    /**
+     * Function that evaluates the coons patch interpolation.
+     * data refers to the pointer of the PatchData struct in which the tessellation data is set.
+     * cubics refers to the points of the cubics.
+     * lod refers the level of detail for each axis.
+     * colors refers to the corner colors that will be bilerp across the patch (optional parameter)
+     * texCoords refers to the corner texture coordinates that will be bilerp across the patch 
+        (optional parameter)
+     */
+    static bool getVertexData(SkPatchUtils::VertexData* data, const SkPoint cubics[12],
+                              const SkColor colors[4], const SkPoint texCoords[4],
+                              int lodX, int lodY);
+};
+
+#endif
diff --git a/src/utils/SkPictureUtils.cpp b/src/utils/SkPictureUtils.cpp
index 702a78d..4f4d2bf 100644
--- a/src/utils/SkPictureUtils.cpp
+++ b/src/utils/SkPictureUtils.cpp
@@ -190,22 +190,22 @@
     typedef SkBaseDevice INHERITED;
 };
 
-SkData* SkPictureUtils::GatherPixelRefs(SkPicture* pict, const SkRect& area) {
+SkData* SkPictureUtils::GatherPixelRefs(const SkPicture* pict, const SkRect& area) {
     if (NULL == pict) {
         return NULL;
     }
 
     // this test also handles if either area or pict's width/height are empty
-    if (!SkRect::Intersects(area,
-                            SkRect::MakeWH(SkIntToScalar(pict->width()),
-                                           SkIntToScalar(pict->height())))) {
+    if (!SkRect::Intersects(area, pict->cullRect())) {
         return NULL;
     }
 
     SkTDArray<SkPixelRef*> array;
     PixelRefSet prset(&array);
 
-    GatherPixelRefDevice device(pict->width(), pict->height(), &prset);
+    GatherPixelRefDevice device(SkScalarCeilToInt(pict->cullRect().width()), 
+                                SkScalarCeilToInt(pict->cullRect().height()), 
+                                &prset);
     SkNoSaveLayerCanvas canvas(&device);
 
     canvas.clipRect(area, SkRegion::kIntersect_Op, false);
diff --git a/src/utils/SkProxyCanvas.cpp b/src/utils/SkProxyCanvas.cpp
index 5cb5469..1677daf 100644
--- a/src/utils/SkProxyCanvas.cpp
+++ b/src/utils/SkProxyCanvas.cpp
@@ -21,9 +21,9 @@
 
 ///////////////////////////////// Overrides ///////////
 
-void SkProxyCanvas::willSave(SaveFlags flags) {
-    fProxy->save(flags);
-    this->INHERITED::willSave(flags);
+void SkProxyCanvas::willSave() {
+    fProxy->save();
+    this->INHERITED::willSave();
 }
 
 SkCanvas::SaveLayerStrategy SkProxyCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
@@ -136,8 +136,14 @@
     fProxy->drawTextOnPath(text, byteLength, path, matrix, paint);
 }
 
-void SkProxyCanvas::onDrawPicture(const SkPicture* picture) {
-    fProxy->drawPicture(picture);
+void SkProxyCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                   const SkPaint& paint) {
+    fProxy->drawTextBlob(blob, x, y, paint);
+}
+
+void SkProxyCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                                  const SkPaint* paint) {
+    fProxy->drawPicture(picture, matrix, paint);
 }
 
 void SkProxyCanvas::drawVertices(VertexMode vmode, int vertexCount,
@@ -149,6 +155,12 @@
                                      xmode, indices, indexCount, paint);
 }
 
+void SkProxyCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                                const SkPoint texCoords[4], SkXfermode* xmode,
+                                const SkPaint& paint) {
+    fProxy->drawPatch(cubics, colors, texCoords, xmode, paint);
+}
+
 void SkProxyCanvas::drawData(const void* data, size_t length) {
     fProxy->drawData(data, length);
 }
diff --git a/src/utils/SkRTConf.cpp b/src/utils/SkRTConf.cpp
index bb6cb23..20b8b43 100644
--- a/src/utils/SkRTConf.cpp
+++ b/src/utils/SkRTConf.cpp
@@ -28,7 +28,7 @@
         if (commentptr == line) {
             continue;
         }
-        if (NULL != commentptr) {
+        if (commentptr) {
             *commentptr = '\0';
         }
 
@@ -99,7 +99,7 @@
 void SkRTConfRegistry::printAll(const char *fname) const {
     SkWStream *o;
 
-    if (NULL != fname) {
+    if (fname) {
         o = new SkFILEWStream(fname);
     } else {
         o = new SkDebugWStream();
@@ -133,7 +133,7 @@
 void SkRTConfRegistry::printNonDefault(const char *fname) const {
     SkWStream *o;
 
-    if (NULL != fname) {
+    if (fname) {
         o = new SkFILEWStream(fname);
     } else {
         o = new SkDebugWStream();
@@ -321,30 +321,3 @@
     static SkRTConfRegistry r;
     return r;
 }
-
-
-#ifdef SK_SUPPORT_UNITTEST
-
-#ifdef SK_BUILD_FOR_WIN32
-static void sk_setenv(const char* key, const char* value) {
-    _putenv_s(key, value);
-}
-#else
-static void sk_setenv(const char* key, const char* value) {
-    setenv(key, value, 1);
-}
-#endif
-
-void SkRTConfRegistry::UnitTest() {
-    SkRTConfRegistry registryWithoutContents(true);
-
-    sk_setenv("skia_nonexistent_item", "132");
-    int result = 0;
-    registryWithoutContents.parse("nonexistent.item", &result);
-    SkASSERT(result == 132);
-}
-
-SkRTConfRegistry::SkRTConfRegistry(bool)
-    : fConfs(100) {
-}
-#endif
diff --git a/src/utils/SkRunnable.h b/src/utils/SkRunnable.h
new file mode 100644
index 0000000..7a93b60
--- /dev/null
+++ b/src/utils/SkRunnable.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkRunnable_DEFINED
+#define SkRunnable_DEFINED
+
+struct SkRunnable {
+    virtual ~SkRunnable() {};
+    virtual void run() = 0;
+};
+
+#endif
diff --git a/src/utils/SkTaskGroup.cpp b/src/utils/SkTaskGroup.cpp
new file mode 100644
index 0000000..7449eb6
--- /dev/null
+++ b/src/utils/SkTaskGroup.cpp
@@ -0,0 +1,148 @@
+#include "SkTaskGroup.h"
+
+#include "SkCondVar.h"
+#include "SkTDArray.h"
+#include "SkThread.h"
+#include "SkThreadUtils.h"
+
+#if defined(SK_BUILD_FOR_WIN32)
+    static inline int num_cores() {
+        SYSTEM_INFO sysinfo;
+        GetSystemInfo(&sysinfo);
+        return sysinfo.dwNumberOfProcessors;
+    }
+#else
+    #include <unistd.h>
+    static inline int num_cores() {
+        return (int) sysconf(_SC_NPROCESSORS_ONLN);
+    }
+#endif
+
+namespace {
+
+class ThreadPool : SkNoncopyable {
+public:
+    static void Add(SkRunnable* task, int32_t* pending) {
+        if (!gGlobal) {  // If we have no threads, run synchronously.
+            return task->run();
+        }
+        gGlobal->add(task, pending);
+    }
+
+    static void Wait(int32_t* pending) {
+        if (!gGlobal) {  // If we have no threads, the work must already be done.
+            SkASSERT(*pending == 0);
+            return;
+        }
+        while (sk_acquire_load(pending) > 0) {  // Pairs with sk_atomic_dec here or in Loop.
+            // Lend a hand until our SkTaskGroup of interest is done.
+            Work work;
+            {
+                AutoLock lock(&gGlobal->fReady);
+                if (gGlobal->fWork.isEmpty()) {
+                    // Someone has picked up all the work (including ours).  How nice of them!
+                    // (They may still be working on it, so we can't assert *pending == 0 here.)
+                    continue;
+                }
+                gGlobal->fWork.pop(&work);
+            }
+            // This Work isn't necessarily part of our SkTaskGroup of interest, but that's fine.
+            // We threads gotta stick together.  We're always making forward progress.
+            work.task->run();
+            sk_atomic_dec(work.pending);  // Release pairs with the sk_acquire_load() just above.
+        }
+    }
+
+private:
+    struct AutoLock {
+        AutoLock(SkCondVar* c) : fC(c) { fC->lock(); }
+        ~AutoLock() { fC->unlock(); }
+    private:
+        SkCondVar* fC;
+    };
+
+    struct Work {
+        SkRunnable* task;  // A task to ->run(),
+        int32_t* pending;  // then sk_atomic_dec(pending) afterwards.
+    };
+
+    explicit ThreadPool(int threads) : fDraining(false) {
+        if (threads == 0) {
+            threads = num_cores();
+        }
+        for (int i = 0; i < threads; i++) {
+            fThreads.push(SkNEW_ARGS(SkThread, (&ThreadPool::Loop, this)));
+            fThreads.top()->start();
+        }
+    }
+
+    ~ThreadPool() {
+        SkASSERT(fWork.isEmpty());  // All SkTaskGroups should be destroyed by now.
+        {
+            AutoLock lock(&fReady);
+            fDraining = true;
+            fReady.broadcast();
+        }
+        for (int i = 0; i < fThreads.count(); i++) {
+            fThreads[i]->join();
+        }
+        SkASSERT(fWork.isEmpty());  // Can't hurt to double check.
+        fThreads.deleteAll();
+    }
+
+    void add(SkRunnable* task, int32_t* pending) {
+        Work work = { task, pending };
+        sk_atomic_inc(pending);  // No barrier needed.
+        {
+            AutoLock lock(&fReady);
+            fWork.push(work);
+            fReady.signal();
+        }
+    }
+
+    static void Loop(void* arg) {
+        ThreadPool* pool = (ThreadPool*)arg;
+        Work work;
+        while (true) {
+            {
+                AutoLock lock(&pool->fReady);
+                while (pool->fWork.isEmpty()) {
+                    if (pool->fDraining) {
+                        return;
+                    }
+                    pool->fReady.wait();
+                }
+                pool->fWork.pop(&work);
+            }
+            work.task->run();
+            sk_atomic_dec(work.pending);  // Release pairs with sk_acquire_load() in Wait().
+        }
+    }
+
+    SkTDArray<Work>      fWork;
+    SkTDArray<SkThread*> fThreads;
+    SkCondVar            fReady;
+    bool                 fDraining;
+
+    static ThreadPool* gGlobal;
+    friend struct SkTaskGroup::Enabler;
+};
+ThreadPool* ThreadPool::gGlobal = NULL;
+
+}  // namespace
+
+SkTaskGroup::Enabler::Enabler(int threads) {
+    SkASSERT(ThreadPool::gGlobal == NULL);
+    ThreadPool::gGlobal = SkNEW_ARGS(ThreadPool, (threads));
+}
+
+SkTaskGroup::Enabler::~Enabler() {
+    SkASSERT(ThreadPool::gGlobal != NULL);
+    SkDELETE(ThreadPool::gGlobal);
+}
+
+SkTaskGroup::SkTaskGroup() : fPending(0) {}
+
+void SkTaskGroup::add(SkRunnable* task) { ThreadPool::Add(task, &fPending); }
+void SkTaskGroup::wait()                { ThreadPool::Wait(&fPending); }
+
diff --git a/src/utils/SkTaskGroup.h b/src/utils/SkTaskGroup.h
new file mode 100644
index 0000000..d9e6f59
--- /dev/null
+++ b/src/utils/SkTaskGroup.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTaskGroup_DEFINED
+#define SkTaskGroup_DEFINED
+
+#include "SkTypes.h"
+#include "SkRunnable.h"
+
+class SkTaskGroup : SkNoncopyable {
+public:
+    // Create one of these in main() to enable SkTaskGroups globally.
+    struct Enabler : SkNoncopyable {
+        explicit Enabler(int threads = 0);  // Default is system-reported core count.
+        ~Enabler();
+    };
+
+    SkTaskGroup();
+    ~SkTaskGroup() { this->wait(); }
+
+    // Add a task to this SkTaskGroup.  It will likely run() on another thread.
+    void add(SkRunnable*);
+
+    // Block until all Tasks previously add()ed to this SkTaskGroup have run().
+    // You may safely reuse this SkTaskGroup after wait() returns.
+    void wait();
+
+private:
+    /*atomic*/ int32_t fPending;
+};
+
+#endif//SkTaskGroup_DEFINED
diff --git a/src/utils/SkTextureCompressor.cpp b/src/utils/SkTextureCompressor.cpp
index fb41928..799eadc 100644
--- a/src/utils/SkTextureCompressor.cpp
+++ b/src/utils/SkTextureCompressor.cpp
@@ -6,205 +6,257 @@
  */
 
 #include "SkTextureCompressor.h"
+#include "SkTextureCompressor_ASTC.h"
+#include "SkTextureCompressor_LATC.h"
+#include "SkTextureCompressor_R11EAC.h"
 
 #include "SkBitmap.h"
+#include "SkBitmapProcShader.h"
 #include "SkData.h"
 #include "SkEndian.h"
 
-////////////////////////////////////////////////////////////////////////////////
-//
-// Utility Functions
-//
-////////////////////////////////////////////////////////////////////////////////
+#include "SkTextureCompression_opts.h"
 
-// Absolute difference between two values. More correct than SkTAbs(a - b)
-// because it works on unsigned values.
-template <typename T> inline T abs_diff(const T &a, const T &b) {
-    return (a > b) ? (a - b) : (b - a);
-}
+#ifndef SK_IGNORE_ETC1_SUPPORT
+#  include "etc1.h"
+#endif
 
-////////////////////////////////////////////////////////////////////////////////
-//
-// LATC compressor
-//
-////////////////////////////////////////////////////////////////////////////////
-
-// Return the squared minimum error cost of approximating 'pixel' using the
-// provided palette. Return this in the middle 16 bits of the integer. Return
-// the best index in the palette for this pixel in the bottom 8 bits.
-static uint32_t compute_error(uint8_t pixel, uint8_t palette[8]) {
-    int minIndex = 0;
-    uint8_t error = abs_diff(palette[0], pixel);
-    for (int i = 1; i < 8; ++i) {
-        uint8_t diff = abs_diff(palette[i], pixel);
-        if (diff < error) {
-            minIndex = i;
-            error = diff;
-        }
-    }
-    uint16_t errSq = static_cast<uint16_t>(error) * static_cast<uint16_t>(error);
-    SkASSERT(minIndex >= 0 && minIndex < 8);
-    return (static_cast<uint32_t>(errSq) << 8) | static_cast<uint32_t>(minIndex);
-}
-
-// Compress LATC block. Each 4x4 block of pixels is decompressed by LATC from two
-// values LUM0 and LUM1, and an index into the generated palette. LATC constructs
-// a palette of eight colors from LUM0 and LUM1 using the algorithm:
-//
-// LUM0,              if lum0 > lum1 and code(x,y) == 0
-// LUM1,              if lum0 > lum1 and code(x,y) == 1
-// (6*LUM0+  LUM1)/7, if lum0 > lum1 and code(x,y) == 2
-// (5*LUM0+2*LUM1)/7, if lum0 > lum1 and code(x,y) == 3
-// (4*LUM0+3*LUM1)/7, if lum0 > lum1 and code(x,y) == 4
-// (3*LUM0+4*LUM1)/7, if lum0 > lum1 and code(x,y) == 5
-// (2*LUM0+5*LUM1)/7, if lum0 > lum1 and code(x,y) == 6
-// (  LUM0+6*LUM1)/7, if lum0 > lum1 and code(x,y) == 7
-//
-// LUM0,              if lum0 <= lum1 and code(x,y) == 0
-// LUM1,              if lum0 <= lum1 and code(x,y) == 1
-// (4*LUM0+  LUM1)/5, if lum0 <= lum1 and code(x,y) == 2
-// (3*LUM0+2*LUM1)/5, if lum0 <= lum1 and code(x,y) == 3
-// (2*LUM0+3*LUM1)/5, if lum0 <= lum1 and code(x,y) == 4
-// (  LUM0+4*LUM1)/5, if lum0 <= lum1 and code(x,y) == 5
-// 0,                 if lum0 <= lum1 and code(x,y) == 6
-// 255,               if lum0 <= lum1 and code(x,y) == 7
-//
-// We compute the LATC palette using the following simple algorithm:
-// 1. Choose the minimum and maximum values in the block as LUM0 and LUM1
-// 2. Figure out which of the two possible palettes is better.
-
-static uint64_t compress_latc_block(uint8_t block[16]) {
-    // Just do a simple min/max but choose which of the
-    // two palettes is better
-    uint8_t maxVal = 0;
-    uint8_t minVal = 255;
-    for (int i = 0; i < 16; ++i) {
-        maxVal = SkMax32(maxVal, block[i]);
-        minVal = SkMin32(minVal, block[i]);
-    }
-
-    // Generate palettes
-    uint8_t palettes[2][8];
-
-    // Straight linear ramp
-    palettes[0][0] = maxVal;
-    palettes[0][1] = minVal;
-    for (int i = 1; i < 7; ++i) {
-        palettes[0][i+1] = ((7-i)*maxVal + i*minVal) / 7;
-    }
-
-    // Smaller linear ramp with min and max byte values at the end.
-    palettes[1][0] = minVal;
-    palettes[1][1] = maxVal;
-    for (int i = 1; i < 5; ++i) {
-        palettes[1][i+1] = ((5-i)*maxVal + i*minVal) / 5;
-    }
-    palettes[1][6] = 0;
-    palettes[1][7] = 255;
-
-    // Figure out which of the two is better:
-    //  -  accumError holds the accumulated error for each pixel from
-    //     the associated palette
-    //  -  indices holds the best indices for each palette in the
-    //     bottom 48 (16*3) bits.
-    uint32_t accumError[2] = { 0, 0 };
-    uint64_t indices[2] = { 0, 0 };
-    for (int i = 15; i >= 0; --i) {
-        // For each palette:
-        // 1. Retreive the result of this pixel
-        // 2. Store the error in accumError
-        // 3. Store the minimum palette index in indices.
-        for (int p = 0; p < 2; ++p) {
-            uint32_t result = compute_error(block[i], palettes[p]);
-            accumError[p] += (result >> 8);
-            indices[p] <<= 3;
-            indices[p] |= result & 7;
-        }
-    }
-
-    SkASSERT(indices[0] < (static_cast<uint64_t>(1) << 48));
-    SkASSERT(indices[1] < (static_cast<uint64_t>(1) << 48));
-
-    uint8_t paletteIdx = (accumError[0] > accumError[1]) ? 0 : 1;
-
-    // Assemble the compressed block.
-    uint64_t result = 0;
-
-    // Jam the first two palette entries into the bottom 16 bits of
-    // a 64 bit integer. Based on the palette that we chose, one will
-    // be larger than the other and it will select the proper palette.
-    result |= static_cast<uint64_t>(palettes[paletteIdx][0]);
-    result |= static_cast<uint64_t>(palettes[paletteIdx][1]) << 8;
-
-    // Jam the indices into the top 48 bits.
-    result |= indices[paletteIdx] << 16;
-
-    // We assume everything is little endian, if it's not then make it so.
-    return SkEndian_SwapLE64(result);
-}
-
-static SkData *compress_a8_to_latc(const SkBitmap &bm) {
-    // LATC compressed texels down into square 4x4 blocks
-    static const int kLATCBlockSize = 4;
-
-    // Make sure that our data is well-formed enough to be
-    // considered for LATC compression
-    if (bm.width() == 0 || bm.height() == 0 ||
-        (bm.width() % kLATCBlockSize) != 0 ||
-        (bm.height() % kLATCBlockSize) != 0 ||
-        (bm.colorType() != kAlpha_8_SkColorType)) {
-        return NULL;
-    }
-
-    // The LATC format is 64 bits per 4x4 block.
-    static const int kLATCEncodedBlockSize = 8;
-
-    int blocksX = bm.width() / kLATCBlockSize;
-    int blocksY = bm.height() / kLATCBlockSize;
-
-    int compressedDataSize = blocksX * blocksY * kLATCEncodedBlockSize;
-    uint64_t* dst = reinterpret_cast<uint64_t*>(sk_malloc_throw(compressedDataSize));
-
-    uint8_t block[16];
-    const uint8_t* row = reinterpret_cast<const uint8_t*>(bm.getPixels());
-    uint64_t* encPtr = dst;
-    for (int y = 0; y < blocksY; ++y) {
-        for (int x = 0; x < blocksX; ++x) {
-            memcpy(block, row + (kLATCBlockSize * x), 4);
-            memcpy(block + 4, row + bm.rowBytes() + (kLATCBlockSize * x), 4);
-            memcpy(block + 8, row + 2*bm.rowBytes() + (kLATCBlockSize * x), 4);
-            memcpy(block + 12, row + 3*bm.rowBytes() + (kLATCBlockSize * x), 4);
-
-            *encPtr = compress_latc_block(block);
-            ++encPtr;
-        }
-        row += kLATCBlockSize * bm.rowBytes();
-    }
-
-    return SkData::NewFromMalloc(dst, compressedDataSize);
+// Convert ETC1 functions to our function signatures
+static bool compress_etc1_565(uint8_t* dst, const uint8_t* src,
+                              int width, int height, int rowBytes) {
+#ifndef SK_IGNORE_ETC1_SUPPORT
+    return 0 == etc1_encode_image(src, width, height, 2, rowBytes, dst);
+#else
+    return false;
+#endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 namespace SkTextureCompressor {
 
-typedef SkData *(*CompressBitmapProc)(const SkBitmap &bitmap);
+void GetBlockDimensions(Format format, int* dimX, int* dimY, bool matchSpec) {
+    if (NULL == dimX || NULL == dimY) {
+        return;
+    }
 
-SkData *CompressBitmapToFormat(const SkBitmap &bitmap, Format format) {
+    if (!matchSpec && SkTextureCompressorGetPlatformDims(format, dimX, dimY)) {
+        return;
+    }
+
+    // No specialized arguments, return the dimensions as they are in the spec.
+    static const struct FormatDimensions {
+        const int fBlockSizeX;
+        const int fBlockSizeY;
+    } kFormatDimensions[kFormatCnt] = {
+        { 4, 4 }, // kLATC_Format
+        { 4, 4 }, // kR11_EAC_Format
+        { 4, 4 }, // kETC1_Format
+        { 4, 4 }, // kASTC_4x4_Format
+        { 5, 4 }, // kASTC_5x4_Format
+        { 5, 5 }, // kASTC_5x5_Format
+        { 6, 5 }, // kASTC_6x5_Format
+        { 6, 6 }, // kASTC_6x6_Format
+        { 8, 5 }, // kASTC_8x5_Format
+        { 8, 6 }, // kASTC_8x6_Format
+        { 8, 8 }, // kASTC_8x8_Format
+        { 10, 5 }, // kASTC_10x5_Format
+        { 10, 6 }, // kASTC_10x6_Format
+        { 10, 8 }, // kASTC_10x8_Format
+        { 10, 10 }, // kASTC_10x10_Format
+        { 12, 10 }, // kASTC_12x10_Format
+        { 12, 12 }, // kASTC_12x12_Format
+    };
+
+    *dimX = kFormatDimensions[format].fBlockSizeX;
+    *dimY = kFormatDimensions[format].fBlockSizeY;
+}
+
+int GetCompressedDataSize(Format fmt, int width, int height) {
+    int dimX, dimY;
+    GetBlockDimensions(fmt, &dimX, &dimY, true);
+
+    int encodedBlockSize = 0;
+            
+    switch (fmt) {
+        // These formats are 64 bits per 4x4 block.
+        case kLATC_Format:
+        case kR11_EAC_Format:
+        case kETC1_Format:
+            encodedBlockSize = 8;
+            break;
+
+        // This format is 128 bits.
+        case kASTC_4x4_Format:
+        case kASTC_5x4_Format:
+        case kASTC_5x5_Format:
+        case kASTC_6x5_Format:
+        case kASTC_6x6_Format:
+        case kASTC_8x5_Format:
+        case kASTC_8x6_Format:
+        case kASTC_8x8_Format:
+        case kASTC_10x5_Format:
+        case kASTC_10x6_Format:
+        case kASTC_10x8_Format:
+        case kASTC_10x10_Format:
+        case kASTC_12x10_Format:
+        case kASTC_12x12_Format:
+            encodedBlockSize = 16;
+            break;
+
+        default:
+            SkFAIL("Unknown compressed format!");
+            return -1;
+    }
+
+    if(((width % dimX) == 0) && ((height % dimY) == 0)) {
+        const int blocksX = width / dimX;
+        const int blocksY = height / dimY;
+
+        return blocksX * blocksY * encodedBlockSize;
+    }
+
+    return -1;
+}
+
+bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcColorType,
+                            int width, int height, int rowBytes, Format format, bool opt) {
+    CompressionProc proc = NULL;
+    if (opt) {
+        proc = SkTextureCompressorGetPlatformProc(srcColorType, format);
+    }
+
+    if (NULL == proc) {
+        switch (srcColorType) {
+            case kAlpha_8_SkColorType:
+            {
+                switch (format) {
+                    case kLATC_Format:
+                        proc = CompressA8ToLATC;
+                        break;
+                    case kR11_EAC_Format:
+                        proc = CompressA8ToR11EAC;
+                        break;
+                    case kASTC_12x12_Format:
+                        proc = CompressA8To12x12ASTC;
+                        break;
+                    default:
+                        // Do nothing...
+                        break;
+                }
+            }
+            break;
+
+            case kRGB_565_SkColorType:
+            {
+                switch (format) {
+                    case kETC1_Format:
+                        proc = compress_etc1_565;
+                        break;
+                    default:
+                        // Do nothing...
+                        break;
+                }
+            }
+            break;
+
+            default:
+                // Do nothing...
+                break;
+        }
+    }
+
+    if (proc) {
+        return proc(dst, src, width, height, rowBytes);
+    }
+
+    return false;
+}
+
+SkData* CompressBitmapToFormat(const SkBitmap &bitmap, Format format) {
     SkAutoLockPixels alp(bitmap);
 
-    CompressBitmapProc kProcMap[kLastEnum_SkColorType + 1][kFormatCnt];
-    memset(kProcMap, 0, sizeof(kProcMap));
+    int compressedDataSize = GetCompressedDataSize(format, bitmap.width(), bitmap.height());
+    if (compressedDataSize < 0) {
+        return NULL;
+    }
 
-    // Map available bitmap configs to compression functions
-    kProcMap[kAlpha_8_SkColorType][kLATC_Format] = compress_a8_to_latc;
+    const uint8_t* src = reinterpret_cast<const uint8_t*>(bitmap.getPixels());
+    SkData* dst = SkData::NewUninitialized(compressedDataSize);
 
-    CompressBitmapProc proc = kProcMap[bitmap.colorType()][format];
-    if (NULL != proc) {
-        return proc(bitmap);
+    if (!CompressBufferToFormat((uint8_t*)dst->writable_data(), src, bitmap.colorType(),
+                                bitmap.width(), bitmap.height(), bitmap.rowBytes(), format)) {
+        dst->unref();
+        dst = NULL;
+    }
+    return dst;
+}
+
+SkBlitter* CreateBlitterForFormat(int width, int height, void* compressedBuffer,
+                                  SkTBlitterAllocator *allocator, Format format) {
+    switch(format) {
+        case kLATC_Format:
+            return CreateLATCBlitter(width, height, compressedBuffer, allocator);
+
+        case kR11_EAC_Format:
+            return CreateR11EACBlitter(width, height, compressedBuffer, allocator);
+
+        case kASTC_12x12_Format:
+            return CreateASTCBlitter(width, height, compressedBuffer, allocator);
+
+        default:
+            return NULL;
     }
 
     return NULL;
 }
 
+bool DecompressBufferFromFormat(uint8_t* dst, int dstRowBytes, const uint8_t* src,
+                                int width, int height, Format format) {
+    int dimX, dimY;
+    GetBlockDimensions(format, &dimX, &dimY, true);
+
+    if (width < 0 || ((width % dimX) != 0) || height < 0 || ((height % dimY) != 0)) {
+        return false;
+    }
+
+    switch(format) {
+        case kLATC_Format:
+            DecompressLATC(dst, dstRowBytes, src, width, height);
+            return true;
+
+        case kR11_EAC_Format:
+            DecompressR11EAC(dst, dstRowBytes, src, width, height);
+            return true;
+
+#ifndef SK_IGNORE_ETC1_SUPPORT
+        case kETC1_Format:
+            return 0 == etc1_decode_image(src, dst, width, height, 3, dstRowBytes);
+#endif
+
+        case kASTC_4x4_Format:
+        case kASTC_5x4_Format:
+        case kASTC_5x5_Format:
+        case kASTC_6x5_Format:
+        case kASTC_6x6_Format:
+        case kASTC_8x5_Format:
+        case kASTC_8x6_Format:
+        case kASTC_8x8_Format:
+        case kASTC_10x5_Format:
+        case kASTC_10x6_Format:
+        case kASTC_10x8_Format:
+        case kASTC_10x10_Format:
+        case kASTC_12x10_Format:
+        case kASTC_12x12_Format:
+            DecompressASTC(dst, dstRowBytes, src, width, height, dimX, dimY);
+            return true;
+
+        default:
+            // Do nothing...
+            break;
+    }
+
+    return false;
+}
+
 }  // namespace SkTextureCompressor
diff --git a/src/utils/SkTextureCompressor.h b/src/utils/SkTextureCompressor.h
index 38fb5ea..d5c1d25 100644
--- a/src/utils/SkTextureCompressor.h
+++ b/src/utils/SkTextureCompressor.h
@@ -8,24 +8,111 @@
 #ifndef SkTextureCompressor_DEFINED
 #define SkTextureCompressor_DEFINED
 
+#include "SkBitmapProcShader.h"
+#include "SkImageInfo.h"
+
 class SkBitmap;
+class SkBlitter;
 class SkData;
 
 namespace SkTextureCompressor {
     // Various texture compression formats that we support.
     enum Format {
-        // Alpha only format.
-        kLATC_Format,
+        // Alpha only formats.
+        kLATC_Format,       // 4x4 blocks, (de)compresses A8
+        kR11_EAC_Format,    // 4x4 blocks, (de)compresses A8
 
-        kLast_Format = kLATC_Format
+        // RGB only formats
+        kETC1_Format,       // 4x4 blocks, compresses RGB 565, decompresses 8-bit RGB
+                            //    NOTE: ETC1 supports 8-bit RGB compression, but we
+                            //    currently don't have any RGB8 SkColorTypes. We could
+                            //    support 8-bit RGBA but we would have to preprocess the
+                            //    bitmap to insert alphas.
+
+        // Multi-purpose formats
+        kASTC_4x4_Format,   // 4x4 blocks, no compression, decompresses RGBA
+        kASTC_5x4_Format,   // 5x4 blocks, no compression, decompresses RGBA
+        kASTC_5x5_Format,   // 5x5 blocks, no compression, decompresses RGBA
+        kASTC_6x5_Format,   // 6x5 blocks, no compression, decompresses RGBA
+        kASTC_6x6_Format,   // 6x6 blocks, no compression, decompresses RGBA
+        kASTC_8x5_Format,   // 8x5 blocks, no compression, decompresses RGBA
+        kASTC_8x6_Format,   // 8x6 blocks, no compression, decompresses RGBA
+        kASTC_8x8_Format,   // 8x8 blocks, no compression, decompresses RGBA
+        kASTC_10x5_Format,  // 10x5 blocks, no compression, decompresses RGBA
+        kASTC_10x6_Format,  // 10x6 blocks, no compression, decompresses RGBA
+        kASTC_10x8_Format,  // 10x8 blocks, no compression, decompresses RGBA
+        kASTC_10x10_Format, // 10x10 blocks, no compression, decompresses RGBA
+        kASTC_12x10_Format, // 12x10 blocks, no compression, decompresses RGBA
+        kASTC_12x12_Format, // 12x12 blocks, compresses A8, decompresses RGBA
+
+        kLast_Format = kASTC_12x12_Format
     };
     static const int kFormatCnt = kLast_Format + 1;
 
+    // Returns the size of the compressed data given the width, height, and
+    // desired compression format. If the width and height are not an appropriate
+    // multiple of the block size, then this function returns an error (-1).
+    int GetCompressedDataSize(Format fmt, int width, int height);
+
     // Returns an SkData holding a blob of compressed data that corresponds
     // to the bitmap. If the bitmap colorType cannot be compressed using the 
     // associated format, then we return NULL. The caller is responsible for
     // calling unref() on the returned data.
     SkData* CompressBitmapToFormat(const SkBitmap& bitmap, Format format);
+
+    // Compresses the given src data into dst. The src data is assumed to be
+    // large enough to hold width*height pixels. The dst data is expected to
+    // be large enough to hold the compressed data according to the format.
+    bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcColorType,
+                                int width, int height, int rowBytes, Format format,
+                                bool opt = true /* Use optimization if available */);
+
+    // Decompresses the given src data from the format specified into the
+    // destination buffer. The width and height of the data passed corresponds
+    // to the width and height of the uncompressed image. The destination buffer (dst)
+    // is assumed to be large enough to hold the entire decompressed image. The
+    // decompressed image colors are determined based on the passed format.
+    //
+    // Note, CompressBufferToFormat compresses A8 data into ASTC. However,
+    // general ASTC data encodes RGBA data, so that is what the decompressor
+    // operates on.
+    //
+    // Returns true if successfully decompresses the src data.
+    bool DecompressBufferFromFormat(uint8_t* dst, int dstRowBytes, const uint8_t* src,
+                                    int width, int height, Format format);
+
+    // This typedef defines what the nominal aspects of a compression function
+    // are. The typedef is not meant to be used by clients of the API, but rather
+    // allows SIMD optimized compression functions to be implemented.
+    typedef bool (*CompressionProc)(uint8_t* dst, const uint8_t* src,
+                                    int width, int height, int rowBytes);
+
+    // Returns true if there exists a blitter for the specified format.
+    inline bool ExistsBlitterForFormat(Format format) {
+        switch (format) {
+            case kLATC_Format:
+            case kR11_EAC_Format:
+            case kASTC_12x12_Format:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    // Returns the blitter for the given compression format. Note, the blitter
+    // is intended to be used with the proper input. I.e. if you try to blit
+    // RGB source data into an R11 EAC texture, you're gonna have a bad time.
+    SkBlitter* CreateBlitterForFormat(int width, int height, void* compressedBuffer,
+                                      SkTBlitterAllocator *allocator, Format format);
+
+    // Returns the desired dimensions of the block size for the given format. These dimensions
+    // don't necessarily correspond to the specification's dimensions, since there may
+    // be specialized algorithms that operate on multiple blocks at once. If the
+    // flag 'matchSpec' is true, then the actual dimensions from the specification are
+    // returned. If the flag is false, then these dimensions reflect the appropriate operable
+    // dimensions of the compression functions.
+    void GetBlockDimensions(Format format, int* dimX, int* dimY, bool matchSpec = false);
 }
 
 #endif
diff --git a/src/utils/SkTextureCompressor_ASTC.cpp b/src/utils/SkTextureCompressor_ASTC.cpp
new file mode 100644
index 0000000..7c77c6b
--- /dev/null
+++ b/src/utils/SkTextureCompressor_ASTC.cpp
@@ -0,0 +1,2101 @@
+/*
+ * 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 "SkTextureCompressor_ASTC.h"
+#include "SkTextureCompressor_Blitter.h"
+
+#include "SkBlitter.h"
+#include "SkEndian.h"
+#include "SkMath.h"
+
+// This table contains the weight values for each texel. This is used in determining
+// how to convert a 12x12 grid of alpha values into a 6x5 grid of index values. Since
+// we have a 6x5 grid, that gives 30 values that we have to compute. For each index,
+// we store up to 20 different triplets of values. In order the triplets are:
+// weight, texel-x, texel-y
+// The weight value corresponds to the amount that this index contributes to the final
+// index value of the given texel. Hence, we need to reconstruct the 6x5 index grid
+// from their relative contribution to the 12x12 texel grid.
+//
+// The algorithm is something like this:
+// foreach index i:
+//    total-weight = 0;
+//    total-alpha = 0;
+//    for w = 1 to 20:
+//       weight = table[i][w*3];
+//       texel-x = table[i][w*3 + 1];
+//       texel-y = table[i][w*3 + 2];
+//       if weight >= 0:
+//           total-weight += weight;
+//           total-alpha += weight * alphas[texel-x][texel-y];
+//
+//    total-alpha /= total-weight;
+//    index = top three bits of total-alpha
+//
+// If the associated index does not contribute to 20 different texels (e.g. it's in
+// a corner), then the extra texels are stored with -1's in the table.
+
+static const int8_t k6x5To12x12Table[30][60] = {
+{ 16, 0, 0, 9, 1, 0, 1, 2, 0, 10, 0, 1, 6, 1, 1, 1, 2, 1, 4, 0, 2, 2,
+  1, 2, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 7, 1, 0, 15, 2, 0, 10, 3, 0, 3, 4, 0, 4, 1, 1, 9, 2, 1, 6, 3, 1, 2,
+  4, 1, 2, 1, 2, 4, 2, 2, 3, 3, 2, 1, 4, 2, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 6, 3, 0, 13, 4, 0, 12, 5, 0, 4, 6, 0, 4, 3, 1, 8, 4, 1, 8, 5, 1, 3,
+  6, 1, 1, 3, 2, 3, 4, 2, 3, 5, 2, 1, 6, 2, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 4, 5, 0, 12, 6, 0, 13, 7, 0, 6, 8, 0, 2, 5, 1, 7, 6, 1, 8, 7, 1, 4,
+  8, 1, 1, 5, 2, 3, 6, 2, 3, 7, 2, 2, 8, 2, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 3, 7, 0, 10, 8, 0, 15, 9, 0, 7, 10, 0, 2, 7, 1, 6, 8, 1, 9, 9, 1, 4,
+  10, 1, 1, 7, 2, 2, 8, 2, 4, 9, 2, 2, 10, 2, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 1, 9, 0, 9, 10, 0, 16, 11, 0, 1, 9, 1, 6, 10, 1, 10, 11, 1, 2, 10, 2, 4,
+  11, 2, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 6, 0, 1, 3, 1, 1, 12, 0, 2, 7, 1, 2, 1, 2, 2, 15, 0, 3, 8, 1, 3, 1,
+  2, 3, 9, 0, 4, 5, 1, 4, 1, 2, 4, 3, 0, 5, 2, 1, 5, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 3, 1, 1, 6, 2, 1, 4, 3, 1, 1, 4, 1, 5, 1, 2, 11, 2, 2, 7, 3, 2, 2,
+  4, 2, 7, 1, 3, 14, 2, 3, 9, 3, 3, 3, 4, 3, 4, 1, 4, 8, 2, 4, 6, 3,
+  4, 2, 4, 4, 1, 1, 5, 3, 2, 5, 2, 3, 5, 1, 4, 5}, // n = 20
+{ 2, 3, 1, 5, 4, 1, 4, 5, 1, 1, 6, 1, 5, 3, 2, 10, 4, 2, 9, 5, 2, 3,
+  6, 2, 6, 3, 3, 12, 4, 3, 11, 5, 3, 4, 6, 3, 3, 3, 4, 7, 4, 4, 7, 5,
+  4, 2, 6, 4, 1, 3, 5, 2, 4, 5, 2, 5, 5, 1, 6, 5}, // n = 20
+{ 2, 5, 1, 5, 6, 1, 5, 7, 1, 2, 8, 1, 3, 5, 2, 9, 6, 2, 10, 7, 2, 4,
+  8, 2, 4, 5, 3, 11, 6, 3, 12, 7, 3, 6, 8, 3, 2, 5, 4, 7, 6, 4, 7, 7,
+  4, 3, 8, 4, 1, 5, 5, 2, 6, 5, 2, 7, 5, 1, 8, 5}, // n = 20
+{ 1, 7, 1, 4, 8, 1, 6, 9, 1, 3, 10, 1, 2, 7, 2, 8, 8, 2, 11, 9, 2, 5,
+  10, 2, 3, 7, 3, 9, 8, 3, 14, 9, 3, 7, 10, 3, 2, 7, 4, 6, 8, 4, 8, 9,
+  4, 4, 10, 4, 1, 7, 5, 2, 8, 5, 3, 9, 5, 1, 10, 5}, // n = 20
+{ 3, 10, 1, 6, 11, 1, 1, 9, 2, 7, 10, 2, 12, 11, 2, 1, 9, 3, 8, 10, 3, 15,
+  11, 3, 1, 9, 4, 5, 10, 4, 9, 11, 4, 2, 10, 5, 3, 11, 5, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 1, 0, 3, 1, 1, 3, 7, 0, 4, 4, 1, 4, 13, 0, 5, 7, 1, 5, 1, 2, 5, 13,
+  0, 6, 7, 1, 6, 1, 2, 6, 7, 0, 7, 4, 1, 7, 1, 0, 8, 1, 1, 8, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 1, 2, 3, 1, 3, 3, 3, 1, 4, 7, 2, 4, 4, 3, 4, 1, 4, 4, 6, 1, 5, 12,
+  2, 5, 8, 3, 5, 2, 4, 5, 6, 1, 6, 12, 2, 6, 8, 3, 6, 2, 4, 6, 3, 1,
+  7, 7, 2, 7, 4, 3, 7, 1, 4, 7, 1, 2, 8, 1, 3, 8}, // n = 20
+{ 1, 4, 3, 1, 5, 3, 3, 3, 4, 6, 4, 4, 5, 5, 4, 2, 6, 4, 5, 3, 5, 11,
+  4, 5, 10, 5, 5, 3, 6, 5, 5, 3, 6, 11, 4, 6, 10, 5, 6, 3, 6, 6, 3, 3,
+  7, 6, 4, 7, 5, 5, 7, 2, 6, 7, 1, 4, 8, 1, 5, 8}, // n = 20
+{ 1, 6, 3, 1, 7, 3, 2, 5, 4, 5, 6, 4, 6, 7, 4, 3, 8, 4, 3, 5, 5, 10,
+  6, 5, 11, 7, 5, 5, 8, 5, 3, 5, 6, 10, 6, 6, 11, 7, 6, 5, 8, 6, 2, 5,
+  7, 5, 6, 7, 6, 7, 7, 3, 8, 7, 1, 6, 8, 1, 7, 8}, // n = 20
+{ 1, 8, 3, 1, 9, 3, 1, 7, 4, 4, 8, 4, 7, 9, 4, 3, 10, 4, 2, 7, 5, 8,
+  8, 5, 12, 9, 5, 6, 10, 5, 2, 7, 6, 8, 8, 6, 12, 9, 6, 6, 10, 6, 1, 7,
+  7, 4, 8, 7, 7, 9, 7, 3, 10, 7, 1, 8, 8, 1, 9, 8}, // n = 20
+{ 1, 10, 3, 1, 11, 3, 4, 10, 4, 7, 11, 4, 1, 9, 5, 7, 10, 5, 13, 11, 5, 1,
+  9, 6, 7, 10, 6, 13, 11, 6, 4, 10, 7, 7, 11, 7, 1, 10, 8, 1, 11, 8, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 3, 0, 6, 2, 1, 6, 9, 0, 7, 5, 1, 7, 1, 2, 7, 15, 0, 8, 8, 1, 8, 1,
+  2, 8, 12, 0, 9, 7, 1, 9, 1, 2, 9, 6, 0, 10, 3, 1, 10, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 1, 1, 6, 3, 2, 6, 2, 3, 6, 1, 4, 6, 4, 1, 7, 8, 2, 7, 6, 3, 7, 2,
+  4, 7, 7, 1, 8, 14, 2, 8, 9, 3, 8, 3, 4, 8, 5, 1, 9, 11, 2, 9, 8, 3,
+  9, 2, 4, 9, 3, 1, 10, 6, 2, 10, 4, 3, 10, 1, 4, 10}, // n = 20
+{ 1, 3, 6, 2, 4, 6, 2, 5, 6, 1, 6, 6, 3, 3, 7, 7, 4, 7, 7, 5, 7, 2,
+  6, 7, 6, 3, 8, 12, 4, 8, 11, 5, 8, 4, 6, 8, 4, 3, 9, 10, 4, 9, 9, 5,
+  9, 3, 6, 9, 2, 3, 10, 5, 4, 10, 5, 5, 10, 2, 6, 10}, // n = 20
+{ 1, 5, 6, 2, 6, 6, 2, 7, 6, 1, 8, 6, 2, 5, 7, 7, 6, 7, 7, 7, 7, 3,
+  8, 7, 4, 5, 8, 11, 6, 8, 12, 7, 8, 6, 8, 8, 3, 5, 9, 9, 6, 9, 10, 7,
+  9, 5, 8, 9, 1, 5, 10, 4, 6, 10, 5, 7, 10, 2, 8, 10}, // n = 20
+{ 1, 7, 6, 2, 8, 6, 3, 9, 6, 1, 10, 6, 2, 7, 7, 6, 8, 7, 8, 9, 7, 4,
+  10, 7, 3, 7, 8, 9, 8, 8, 14, 9, 8, 7, 10, 8, 2, 7, 9, 7, 8, 9, 11, 9,
+  9, 5, 10, 9, 1, 7, 10, 4, 8, 10, 6, 9, 10, 3, 10, 10}, // n = 20
+{ 2, 10, 6, 3, 11, 6, 1, 9, 7, 5, 10, 7, 9, 11, 7, 1, 9, 8, 8, 10, 8, 15,
+  11, 8, 1, 9, 9, 7, 10, 9, 12, 11, 9, 3, 10, 10, 6, 11, 10, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 4, 0, 9, 2, 1, 9, 10, 0, 10, 6, 1, 10, 1, 2, 10, 16, 0, 11, 9, 1, 11, 1,
+  2, 11, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 2, 1, 9, 4, 2, 9, 2, 3, 9, 1, 4, 9, 4, 1, 10, 9, 2, 10, 6, 3, 10, 2,
+  4, 10, 7, 1, 11, 15, 2, 11, 10, 3, 11, 3, 4, 11, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 2, 3, 9, 3, 4, 9, 3, 5, 9, 1, 6, 9, 4, 3, 10, 8, 4, 10, 7, 5, 10, 2,
+  6, 10, 6, 3, 11, 13, 4, 11, 12, 5, 11, 4, 6, 11, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 1, 5, 9, 3, 6, 9, 3, 7, 9, 1, 8, 9, 3, 5, 10, 8, 6, 10, 8, 7, 10, 4,
+  8, 10, 4, 5, 11, 12, 6, 11, 13, 7, 11, 6, 8, 11, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 1, 7, 9, 3, 8, 9, 4, 9, 9, 2, 10, 9, 2, 7, 10, 6, 8, 10, 9, 9, 10, 4,
+  10, 10, 3, 7, 11, 10, 8, 11, 15, 9, 11, 7, 10, 11, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0}, // n = 20
+{ 2, 10, 9, 4, 11, 9, 1, 9, 10, 6, 10, 10, 10, 11, 10, 1, 9, 11, 9, 10, 11, 16,
+  11, 11, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
+  0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0} // n = 20
+};
+
+// Returns the alpha value of a texel at position (x, y) from src.
+// (x, y) are assumed to be in the range [0, 12).
+inline uint8_t GetAlpha(const uint8_t *src, int rowBytes, int x, int y) {
+    SkASSERT(x >= 0 && x < 12);
+    SkASSERT(y >= 0 && y < 12);
+    SkASSERT(rowBytes >= 12);
+    return *(src + y*rowBytes + x);
+}
+
+inline uint8_t GetAlphaTranspose(const uint8_t *src, int rowBytes, int x, int y) {
+    return GetAlpha(src, rowBytes, y, x);
+}
+
+// Output the 16 bytes stored in top and bottom and advance the pointer. The bytes
+// are stored as the integers are represented in memory, so they should be swapped
+// if necessary.
+static inline void send_packing(uint8_t** dst, const uint64_t top, const uint64_t bottom) {
+    uint64_t* dst64 = reinterpret_cast<uint64_t*>(*dst);
+    dst64[0] = top;
+    dst64[1] = bottom;
+    *dst += 16;
+}
+
+// Compresses an ASTC block, by looking up the proper contributions from
+// k6x5To12x12Table and computing an index from the associated values.
+typedef uint8_t (*GetAlphaProc)(const uint8_t* src, int rowBytes, int x, int y);
+
+template<GetAlphaProc getAlphaProc>
+static void compress_a8_astc_block(uint8_t** dst, const uint8_t* src, int rowBytes) {
+    // Check for single color
+    bool constant = true;
+    const uint32_t firstInt = *(reinterpret_cast<const uint32_t*>(src));
+    for (int i = 0; i < 12; ++i) {
+        const uint32_t *rowInt = reinterpret_cast<const uint32_t *>(src + i*rowBytes);
+        constant = constant && (rowInt[0] == firstInt);
+        constant = constant && (rowInt[1] == firstInt);
+        constant = constant && (rowInt[2] == firstInt);
+    }
+
+    if (constant) {
+        if (0 == firstInt) {
+            // All of the indices are set to zero, and the colors are
+            // v0 = 0, v1 = 255, so everything will be transparent.
+            send_packing(dst, SkTEndian_SwapLE64(0x0000000001FE000173ULL), 0);
+            return;
+        } else if (0xFFFFFFFF == firstInt) {
+            // All of the indices are set to zero, and the colors are
+            // v0 = 255, v1 = 0, so everything will be opaque.
+            send_packing(dst, SkTEndian_SwapLE64(0x000000000001FE0173ULL), 0);
+            return;
+        }
+    }
+
+    uint8_t indices[30]; // 6x5 index grid
+    for (int idx = 0; idx < 30; ++idx) {
+        int weightTot = 0;
+        int alphaTot = 0;
+        for (int w = 0; w < 20; ++w) {
+            const int8_t weight = k6x5To12x12Table[idx][w*3];
+            if (weight > 0) {
+                const int x = k6x5To12x12Table[idx][w*3 + 1];
+                const int y = k6x5To12x12Table[idx][w*3 + 2];
+                weightTot += weight;
+                alphaTot += weight * getAlphaProc(src, rowBytes, x, y);
+            } else {
+                // In our table, not every entry has 20 weights, and all
+                // of them are nonzero. Once we hit a negative weight, we
+                // know that all of the other weights are not valid either.
+                break;
+            }
+        }
+
+        indices[idx] = (alphaTot / weightTot) >> 5;
+    }
+
+    // Pack indices... The ASTC block layout is fairly complicated. An extensive
+    // description can be found here:
+    // https://www.opengl.org/registry/specs/KHR/texture_compression_astc_hdr.txt
+    //
+    // Here is a summary of the options that we've chosen:
+    // 1. Block mode: 0b00101110011
+    //     - 6x5 texel grid
+    //     - Single plane
+    //     - Low-precision index values
+    //     - Index range 0-7 (three bits per index)
+    // 2. Partitions: 0b00 
+    //     - One partition
+    // 3. Color Endpoint Mode: 0b0000
+    //     - Direct luminance -- e0=(v0,v0,v0,0xFF); e1=(v1,v1,v1,0xFF);
+    // 4. 8-bit endpoints:
+    //     v0 = 0, v1 = 255
+    //
+    // The rest of the block contains the 30 index values from before, which
+    // are currently stored in the indices variable.
+
+    uint64_t top = 0x0000000001FE000173ULL;
+    uint64_t bottom = 0;
+
+    for (int idx = 0; idx <= 20; ++idx) {
+        const uint8_t index = indices[idx];
+        bottom |= static_cast<uint64_t>(index) << (61-(idx*3));
+    }
+
+    // index 21 straddles top and bottom
+    {
+        const uint8_t index = indices[21];
+        bottom |= index & 1;
+        top |= static_cast<uint64_t>((index >> 2) | (index & 2)) << 62;
+    }
+
+    for (int idx = 22; idx < 30; ++idx) {
+        const uint8_t index = indices[idx];
+        top |= static_cast<uint64_t>(index) << (59-(idx-22)*3);
+    }
+
+    // Reverse each 3-bit index since indices are read in reverse order...
+    uint64_t t = (bottom ^ (bottom >> 2)) & 0x2492492492492492ULL;
+    bottom = bottom ^ t ^ (t << 2);
+
+    t = (top ^ (top >> 2)) & 0x0924924000000000ULL;
+    top = top ^ t ^ (t << 2);
+
+    send_packing(dst, SkEndian_SwapLE64(top), SkEndian_SwapLE64(bottom));
+}
+
+inline void CompressA8ASTCBlockVertical(uint8_t* dst, const uint8_t* src) {
+    compress_a8_astc_block<GetAlphaTranspose>(&dst, src, 12);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// ASTC Decoder
+//
+// Full details available in the spec:
+// http://www.khronos.org/registry/gles/extensions/OES/OES_texture_compression_astc.txt
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// Enable this to assert whenever a decoded block has invalid ASTC values. Otherwise, 
+// each invalid block will result in a disgusting magenta color.
+#define ASSERT_ASTC_DECODE_ERROR 0
+
+// Reverse 64-bit integer taken from TAOCP 4a, although it's better
+// documented at this site:
+// http://matthewarcus.wordpress.com/2012/11/18/reversing-a-64-bit-word/
+
+template <typename T, T m, int k>
+static inline T swap_bits(T p) {
+    T q = ((p>>k)^p) & m;
+    return p^q^(q<<k);
+}
+
+static inline uint64_t reverse64(uint64_t n) {
+    static const uint64_t m0 = 0x5555555555555555ULL;
+    static const uint64_t m1 = 0x0300c0303030c303ULL;
+    static const uint64_t m2 = 0x00c0300c03f0003fULL;
+    static const uint64_t m3 = 0x00000ffc00003fffULL;
+    n = ((n>>1)&m0) | (n&m0)<<1;
+    n = swap_bits<uint64_t, m1, 4>(n);
+    n = swap_bits<uint64_t, m2, 8>(n);
+    n = swap_bits<uint64_t, m3, 20>(n);
+    n = (n >> 34) | (n << 30);
+    return n;
+}
+
+// An ASTC block is 128 bits. We represent it as two 64-bit integers in order
+// to efficiently operate on the block using bitwise operations.
+struct ASTCBlock {
+    uint64_t fLow;
+    uint64_t fHigh;
+
+    // Reverses the bits of an ASTC block, making the LSB of the
+    // 128 bit block the MSB.
+    inline void reverse() {
+        const uint64_t newLow = reverse64(this->fHigh);
+        this->fHigh = reverse64(this->fLow);
+        this->fLow = newLow;
+    }
+};
+
+// Writes the given color to every pixel in the block. This is used by void-extent
+// blocks (a special constant-color encoding of a block) and by the error function.
+static inline void write_constant_color(uint8_t* dst, int blockDimX, int blockDimY,
+                                        int dstRowBytes, SkColor color) {
+    for (int y = 0; y < blockDimY; ++y) {
+        SkColor *dstColors = reinterpret_cast<SkColor*>(dst);
+        for (int x = 0; x < blockDimX; ++x) {
+            dstColors[x] = color;
+        }
+        dst += dstRowBytes;
+    }
+}
+
+// Sets the entire block to the ASTC "error" color, a disgusting magenta
+// that's not supposed to appear in natural images.
+static inline void write_error_color(uint8_t* dst, int blockDimX, int blockDimY,
+                                     int dstRowBytes) {
+    static const SkColor kASTCErrorColor = SkColorSetRGB(0xFF, 0, 0xFF);
+
+#if ASSERT_ASTC_DECODE_ERROR
+    SkDEBUGFAIL("ASTC decoding error!\n");
+#endif
+
+    write_constant_color(dst, blockDimX, blockDimY, dstRowBytes, kASTCErrorColor);
+}
+
+// Reads up to 64 bits of the ASTC block starting from bit
+// 'from' and going up to but not including bit 'to'. 'from' starts
+// counting from the LSB, counting up to the MSB. Returns -1 on
+// error.
+static uint64_t read_astc_bits(const ASTCBlock &block, int from, int to) {
+    SkASSERT(0 <= from && from <= 128);
+    SkASSERT(0 <= to && to <= 128);
+
+    const int nBits = to - from;
+    if (0 == nBits) {
+        return 0;
+    }
+
+    if (nBits < 0 || 64 <= nBits) {
+        SkDEBUGFAIL("ASTC -- shouldn't read more than 64 bits");
+        return -1;
+    }
+
+    // Remember, the 'to' bit isn't read.
+    uint64_t result = 0;
+    if (to <= 64) {
+        // All desired bits are in the low 64-bits.
+        result = (block.fLow >> from) & ((1ULL << nBits) - 1);
+    } else if (from >= 64) {
+        // All desired bits are in the high 64-bits.
+        result = (block.fHigh >> (from - 64)) & ((1ULL << nBits) - 1);
+    } else {
+        // from < 64 && to > 64
+        SkASSERT(nBits > (64 - from));
+        const int nLow = 64 - from;
+        const int nHigh = nBits - nLow;
+        result = 
+            ((block.fLow >> from) & ((1ULL << nLow) - 1)) |
+            ((block.fHigh & ((1ULL << nHigh) - 1)) << nLow);
+    }
+
+    return result;
+}
+
+// Returns the number of bits needed to represent a number
+// in the given power-of-two range (excluding the power of two itself).
+static inline int bits_for_range(int x) {
+    SkASSERT(SkIsPow2(x));
+    SkASSERT(0 != x);
+    // Since we know it's a power of two, there should only be one bit set,
+    // meaning the number of trailing zeros is 31 minus the number of leading
+    // zeros.
+    return 31 - SkCLZ(x);
+}
+
+// Clamps an integer to the range [0, 255]
+static inline int clamp_byte(int x) {
+    return SkClampMax(x, 255);
+}
+
+// Helper function defined in the ASTC spec, section C.2.14
+// It transfers a few bits of precision from one value to another.
+static inline void bit_transfer_signed(int *a, int *b) {
+    *b >>= 1;
+    *b |= *a & 0x80;
+    *a >>= 1;
+    *a &= 0x3F;
+    if ( (*a & 0x20) != 0 ) {
+        *a -= 0x40;
+    }
+}
+
+// Helper function defined in the ASTC spec, section C.2.14
+// It uses the value in the blue channel to tint the red and green
+static inline SkColor blue_contract(int a, int r, int g, int b) {
+    return SkColorSetARGB(a, (r + b) >> 1, (g + b) >> 1, b);
+}
+
+// Helper function that decodes two colors from eight values. If isRGB is true,
+// then the pointer 'v' contains six values and the last two are considered to be
+// 0xFF. If isRGB is false, then all eight values come from the pointer 'v'. This
+// corresponds to the decode procedure for the following endpoint modes:
+//   kLDR_RGB_Direct_ColorEndpointMode
+//   kLDR_RGBA_Direct_ColorEndpointMode
+static inline void decode_rgba_direct(const int *v, SkColor *endpoints, bool isRGB) {
+
+    int v6 = 0xFF;
+    int v7 = 0xFF;
+    if (!isRGB) {
+        v6 = v[6];
+        v7 = v[7];
+    }
+
+    const int s0 = v[0] + v[2] + v[4];
+    const int s1 = v[1] + v[3] + v[5];
+
+    if (s1 >= s0) {
+        endpoints[0] = SkColorSetARGB(v6, v[0], v[2], v[4]);
+        endpoints[1] = SkColorSetARGB(v7, v[1], v[3], v[5]);
+    } else {
+        endpoints[0] = blue_contract(v7, v[1], v[3], v[5]);
+        endpoints[1] = blue_contract(v6, v[0], v[2], v[4]);
+    }
+}
+
+// Helper function that decodes two colors from six values. If isRGB is true,
+// then the pointer 'v' contains four values and the last two are considered to be
+// 0xFF. If isRGB is false, then all six values come from the pointer 'v'. This
+// corresponds to the decode procedure for the following endpoint modes:
+//   kLDR_RGB_BaseScale_ColorEndpointMode
+//   kLDR_RGB_BaseScaleWithAlpha_ColorEndpointMode
+static inline void decode_rgba_basescale(const int *v, SkColor *endpoints, bool isRGB) {
+
+    int v4 = 0xFF;
+    int v5 = 0xFF;
+    if (!isRGB) {
+        v4 = v[4];
+        v5 = v[5];
+    }
+                  
+    endpoints[0] = SkColorSetARGB(v4,
+                                  (v[0]*v[3]) >> 8,
+                                  (v[1]*v[3]) >> 8,
+                                  (v[2]*v[3]) >> 8);
+    endpoints[1] = SkColorSetARGB(v5, v[0], v[1], v[2]);
+}
+
+// Helper function that decodes two colors from eight values. If isRGB is true,
+// then the pointer 'v' contains six values and the last two are considered to be
+// 0xFF. If isRGB is false, then all eight values come from the pointer 'v'. This
+// corresponds to the decode procedure for the following endpoint modes:
+//   kLDR_RGB_BaseOffset_ColorEndpointMode
+//   kLDR_RGBA_BaseOffset_ColorEndpointMode
+//
+// If isRGB is true, then treat this as if v6 and v7 are meant to encode full alpha values.
+static inline void decode_rgba_baseoffset(const int *v, SkColor *endpoints, bool isRGB) {
+    int v0 = v[0];
+    int v1 = v[1];
+    int v2 = v[2];
+    int v3 = v[3];
+    int v4 = v[4];
+    int v5 = v[5];
+    int v6 = isRGB ? 0xFF : v[6];
+    // The 0 is here because this is an offset, not a direct value
+    int v7 = isRGB ? 0 : v[7];
+
+    bit_transfer_signed(&v1, &v0);
+    bit_transfer_signed(&v3, &v2);
+    bit_transfer_signed(&v5, &v4);
+    if (!isRGB) {
+        bit_transfer_signed(&v7, &v6);
+    }
+
+    int c[2][4];
+    if ((v1 + v3 + v5) >= 0) {
+        c[0][0] = v6;
+        c[0][1] = v0;
+        c[0][2] = v2;
+        c[0][3] = v4;
+
+        c[1][0] = v6 + v7;
+        c[1][1] = v0 + v1;
+        c[1][2] = v2 + v3;
+        c[1][3] = v4 + v5;
+    } else {
+        c[0][0] = v6 + v7;
+        c[0][1] = (v0 + v1 + v4 + v5) >> 1;
+        c[0][2] = (v2 + v3 + v4 + v5) >> 1;
+        c[0][3] = v4 + v5;
+
+        c[1][0] = v6;
+        c[1][1] = (v0 + v4) >> 1;
+        c[1][2] = (v2 + v4) >> 1;
+        c[1][3] = v4;
+    }
+
+    endpoints[0] = SkColorSetARGB(clamp_byte(c[0][0]),
+                                  clamp_byte(c[0][1]),
+                                  clamp_byte(c[0][2]),
+                                  clamp_byte(c[0][3]));
+
+    endpoints[1] = SkColorSetARGB(clamp_byte(c[1][0]),
+                                  clamp_byte(c[1][1]),
+                                  clamp_byte(c[1][2]),
+                                  clamp_byte(c[1][3]));
+}
+
+
+// A helper class used to decode bit values from standard integer values.
+// We can't use this class with ASTCBlock because then it would need to
+// handle multi-value ranges, and it's non-trivial to lookup a range of bits
+// that splits across two different ints.
+template <typename T>
+class SkTBits {
+public:
+    SkTBits(const T val) : fVal(val) { }
+
+    // Returns the bit at the given position
+    T operator [](const int idx) const {
+        return (fVal >> idx) & 1;
+    }
+
+    // Returns the bits in the given range, inclusive
+    T operator ()(const int end, const int start) const {
+        SkASSERT(end >= start);
+        return (fVal >> start) & ((1ULL << ((end - start) + 1)) - 1);
+    }
+
+private:
+    const T fVal;
+};
+
+// This algorithm matches the trit block decoding in the spec (Table C.2.14)
+static void decode_trit_block(int* dst, int nBits, const uint64_t &block) {
+
+    SkTBits<uint64_t> blockBits(block);
+
+    // According to the spec, a trit block, which contains five values,
+    // has the following layout:
+    //
+    // 27  26  25  24  23  22  21  20  19  18  17  16
+    //  -----------------------------------------------
+    // |T7 |     m4        |T6  T5 |     m3        |T4 |
+    //  -----------------------------------------------
+    //
+    // 15  14  13  12  11  10  9   8   7   6   5   4   3   2   1   0
+    //  --------------------------------------------------------------
+    // |    m2        |T3  T2 |      m1       |T1  T0 |      m0       |
+    //  --------------------------------------------------------------
+    //
+    // Where the m's are variable width depending on the number of bits used
+    // to encode the values (anywhere from 0 to 6). Since 3^5 = 243, the extra
+    // byte labeled T (whose bits are interleaved where 0 is the LSB and 7 is
+    // the MSB), contains five trit values. To decode the trit values, the spec
+    // says that we need to follow the following algorithm:
+    //
+    // if T[4:2] = 111
+    //     C = { T[7:5], T[1:0] }; t4 = t3 = 2
+    // else
+    //     C = T[4:0]
+    //
+    // if T[6:5] = 11
+    //     t4 = 2; t3 = T[7]
+    // else
+    //     t4 = T[7]; t3 = T[6:5]
+    //
+    // if C[1:0] = 11
+    //     t2 = 2; t1 = C[4]; t0 = { C[3], C[2]&~C[3] }
+    // else if C[3:2] = 11
+    //     t2 = 2; t1 = 2; t0 = C[1:0]
+    // else
+    //     t2 = C[4]; t1 = C[3:2]; t0 = { C[1], C[0]&~C[1] }
+    //
+    // The following C++ code is meant to mirror this layout and algorithm as
+    // closely as possible.
+
+    int m[5];
+    if (0 == nBits) {
+        memset(m, 0, sizeof(m));
+    } else {
+        SkASSERT(nBits < 8);
+        m[0] = static_cast<int>(blockBits(nBits - 1, 0));
+        m[1] = static_cast<int>(blockBits(2*nBits - 1 + 2, nBits + 2));
+        m[2] = static_cast<int>(blockBits(3*nBits - 1 + 4, 2*nBits + 4));
+        m[3] = static_cast<int>(blockBits(4*nBits - 1 + 5, 3*nBits + 5));
+        m[4] = static_cast<int>(blockBits(5*nBits - 1 + 7, 4*nBits + 7));
+    }
+
+    int T =
+        static_cast<int>(blockBits(nBits + 1, nBits)) |
+        (static_cast<int>(blockBits(2*nBits + 2 + 1, 2*nBits + 2)) << 2) |
+        (static_cast<int>(blockBits[3*nBits + 4] << 4)) |
+        (static_cast<int>(blockBits(4*nBits + 5 + 1, 4*nBits + 5)) << 5) |
+        (static_cast<int>(blockBits[5*nBits + 7] << 7));
+
+    int t[5];
+
+    int C;
+    SkTBits<int> Tbits(T);
+    if (0x7 == Tbits(4, 2)) {
+        C = (Tbits(7, 5) << 2) | Tbits(1, 0);
+        t[3] = t[4] = 2;
+    } else {
+        C = Tbits(4, 0);
+        if (Tbits(6, 5) == 0x3) {
+            t[4] = 2; t[3] = Tbits[7];
+        } else {
+            t[4] = Tbits[7]; t[3] = Tbits(6, 5);
+        }
+    }
+
+    SkTBits<int> Cbits(C);
+    if (Cbits(1, 0) == 0x3) {
+        t[2] = 2;
+        t[1] = Cbits[4];
+        t[0] = (Cbits[3] << 1) | (Cbits[2] & (0x1 & ~(Cbits[3])));
+    } else if (Cbits(3, 2) == 0x3) {
+        t[2] = 2;
+        t[1] = 2;
+        t[0] = Cbits(1, 0);
+    } else {
+        t[2] = Cbits[4];
+        t[1] = Cbits(3, 2);
+        t[0] = (Cbits[1] << 1) | (Cbits[0] & (0x1 & ~(Cbits[1])));
+    }
+
+#ifdef SK_DEBUG
+    // Make sure all of the decoded values have a trit less than three
+    // and a bit value within the range of the allocated bits.
+    for (int i = 0; i < 5; ++i) {
+        SkASSERT(t[i] < 3);
+        SkASSERT(m[i] < (1 << nBits));
+    }
+#endif
+
+    for (int i = 0; i < 5; ++i) {
+        *dst = (t[i] << nBits) + m[i];
+        ++dst;
+    }
+}
+
+// This algorithm matches the quint block decoding in the spec (Table C.2.15)
+static void decode_quint_block(int* dst, int nBits, const uint64_t &block) {
+    SkTBits<uint64_t> blockBits(block);
+
+    // According to the spec, a quint block, which contains three values,
+    // has the following layout:
+    //
+    //
+    // 18  17  16  15  14  13  12  11  10  9   8   7   6   5   4   3   2   1   0
+    //  --------------------------------------------------------------------------
+    // |Q6  Q5 |     m2       |Q4  Q3 |     m1        |Q2  Q1  Q0 |      m0       |
+    //  --------------------------------------------------------------------------
+    //
+    // Where the m's are variable width depending on the number of bits used
+    // to encode the values (anywhere from 0 to 4). Since 5^3 = 125, the extra
+    // 7-bit value labeled Q (whose bits are interleaved where 0 is the LSB and 6 is
+    // the MSB), contains three quint values. To decode the quint values, the spec
+    // says that we need to follow the following algorithm:
+    //
+    // if Q[2:1] = 11 and Q[6:5] = 00
+    //     q2 = { Q[0], Q[4]&~Q[0], Q[3]&~Q[0] }; q1 = q0 = 4
+    // else
+    //     if Q[2:1] = 11
+    //         q2 = 4; C = { Q[4:3], ~Q[6:5], Q[0] }
+    //     else
+    //         q2 = T[6:5]; C = Q[4:0]
+    //
+    //     if C[2:0] = 101
+    //         q1 = 4; q0 = C[4:3]
+    //     else
+    //         q1 = C[4:3]; q0 = C[2:0]
+    //
+    // The following C++ code is meant to mirror this layout and algorithm as
+    // closely as possible.
+
+    int m[3];
+    if (0 == nBits) {
+        memset(m, 0, sizeof(m));
+    } else {
+        SkASSERT(nBits < 8);
+        m[0] = static_cast<int>(blockBits(nBits - 1, 0));
+        m[1] = static_cast<int>(blockBits(2*nBits - 1 + 3, nBits + 3));
+        m[2] = static_cast<int>(blockBits(3*nBits - 1 + 5, 2*nBits + 5));
+    }
+
+    int Q =
+        static_cast<int>(blockBits(nBits + 2, nBits)) |
+        (static_cast<int>(blockBits(2*nBits + 3 + 1, 2*nBits + 3)) << 3) |
+        (static_cast<int>(blockBits(3*nBits + 5 + 1, 3*nBits + 5)) << 5);
+
+    int q[3];
+    SkTBits<int> Qbits(Q); // quantum?
+
+    if (Qbits(2, 1) == 0x3 && Qbits(6, 5) == 0) {
+        const int notBitZero = (0x1 & ~(Qbits[0]));
+        q[2] = (Qbits[0] << 2) | ((Qbits[4] & notBitZero) << 1) | (Qbits[3] & notBitZero);
+        q[1] = 4;
+        q[0] = 4;
+    } else {
+        int C;
+        if (Qbits(2, 1) == 0x3) {
+            q[2] = 4;
+            C = (Qbits(4, 3) << 3) | ((0x3 & ~(Qbits(6, 5))) << 1) | Qbits[0];
+        } else {
+            q[2] = Qbits(6, 5);
+            C = Qbits(4, 0);
+        }
+
+        SkTBits<int> Cbits(C);
+        if (Cbits(2, 0) == 0x5) {
+            q[1] = 4;
+            q[0] = Cbits(4, 3);
+        } else {
+            q[1] = Cbits(4, 3);
+            q[0] = Cbits(2, 0);
+        }
+    }
+
+#ifdef SK_DEBUG
+    for (int i = 0; i < 3; ++i) {
+        SkASSERT(q[i] < 5);
+        SkASSERT(m[i] < (1 << nBits));
+    }
+#endif
+
+    for (int i = 0; i < 3; ++i) {
+        *dst = (q[i] << nBits) + m[i];
+        ++dst;
+    }
+}
+
+// Function that decodes a sequence of integers stored as an ISE (Integer
+// Sequence Encoding) bit stream. The full details of this function are outlined
+// in section C.2.12 of the ASTC spec. A brief overview is as follows:
+//
+// - Each integer in the sequence is bounded by a specific range r.
+// - The range of each value determines the way the bit stream is interpreted,
+// - If the range is a power of two, then the sequence is a sequence of bits
+// - If the range is of the form 3*2^n, then the sequence is stored as a
+//   sequence of blocks, each block contains 5 trits and 5 bit sequences, which
+//   decodes into 5 values.
+// - Similarly, if the range is of the form 5*2^n, then the sequence is stored as a
+//   sequence of blocks, each block contains 3 quints and 3 bit sequences, which
+//   decodes into 3 values.
+static bool decode_integer_sequence(
+    int* dst,                 // The array holding the destination bits
+    int dstSize,              // The maximum size of the array
+    int nVals,                // The number of values that we'd like to decode
+    const ASTCBlock &block,   // The block that we're decoding from
+    int startBit,             // The bit from which we're going to do the reading
+    int endBit,               // The bit at which we stop reading (not inclusive)
+    bool bReadForward,        // If true, then read LSB -> MSB, else read MSB -> LSB
+    int nBits,                // The number of bits representing this encoding
+    int nTrits,               // The number of trits representing this encoding
+    int nQuints               // The number of quints representing this encoding
+) {
+    // If we want more values than we have, then fail.
+    if (nVals > dstSize) {
+        return false;
+    }
+
+    ASTCBlock src = block;
+
+    if (!bReadForward) {
+        src.reverse();
+        startBit = 128 - startBit;
+        endBit = 128 - endBit;
+    }
+
+    while (nVals > 0) {
+
+        if (nTrits > 0) {
+            SkASSERT(0 == nQuints);
+
+            int endBlockBit = startBit + 8 + 5*nBits;
+            if (endBlockBit > endBit) {
+                endBlockBit = endBit;
+            }
+
+            // Trit blocks are three values large.
+            int trits[5];
+            decode_trit_block(trits, nBits, read_astc_bits(src, startBit, endBlockBit));
+            memcpy(dst, trits, SkMin32(nVals, 5)*sizeof(int));
+
+            dst += 5;
+            nVals -= 5;
+            startBit = endBlockBit;
+
+        } else if (nQuints > 0) {
+            SkASSERT(0 == nTrits);
+
+            int endBlockBit = startBit + 7 + 3*nBits;
+            if (endBlockBit > endBit) {
+                endBlockBit = endBit;
+            }
+
+            // Quint blocks are three values large
+            int quints[3];
+            decode_quint_block(quints, nBits, read_astc_bits(src, startBit, endBlockBit));
+            memcpy(dst, quints, SkMin32(nVals, 3)*sizeof(int));
+
+            dst += 3;
+            nVals -= 3;
+            startBit = endBlockBit;
+
+        } else {
+            // Just read the bits, but don't read more than we have...
+            int endValBit = startBit + nBits;
+            if (endValBit > endBit) {
+                endValBit = endBit;
+            }
+
+            SkASSERT(endValBit - startBit < 31);
+            *dst = static_cast<int>(read_astc_bits(src, startBit, endValBit));
+            ++dst;
+            --nVals;
+            startBit = endValBit;
+        }
+    }
+
+    return true;
+}
+
+// Helper function that unquantizes some (seemingly random) generated
+// numbers... meant to match the ASTC hardware. This function is used
+// to unquantize both colors (Table C.2.16) and weights (Table C.2.26)
+static inline int unquantize_value(unsigned mask, int A, int B, int C, int D) {
+    int T = D * C + B;
+    T = T ^ A;
+    T = (A & mask) | (T >> 2);
+    SkASSERT(T < 256);
+    return T;
+}
+
+// Helper function to replicate the bits in x that represents an oldPrec
+// precision integer into a prec precision integer. For example:
+//   255 == replicate_bits(7, 3, 8);
+static inline int replicate_bits(int x, int oldPrec, int prec) {
+    while (oldPrec < prec) {
+        const int toShift = SkMin32(prec-oldPrec, oldPrec);
+        x = (x << toShift) | (x >> (oldPrec - toShift));
+        oldPrec += toShift;
+    }
+
+    // Make sure that no bits are set outside the desired precision.
+    SkASSERT((-(1 << prec) & x) == 0);
+    return x;
+}
+
+// Returns the unquantized value of a color that's represented only as
+// a set of bits.
+static inline int unquantize_bits_color(int val, int nBits) {
+    return replicate_bits(val, nBits, 8);
+}
+
+// Returns the unquantized value of a color that's represented as a
+// trit followed by nBits bits. This algorithm follows the sequence
+// defined in section C.2.13 of the ASTC spec.
+static inline int unquantize_trit_color(int val, int nBits) {
+    SkASSERT(nBits > 0);
+    SkASSERT(nBits < 7);
+
+    const int D = (val >> nBits) & 0x3;
+    SkASSERT(D < 3);
+
+    const int A = -(val & 0x1) & 0x1FF;
+
+    static const int Cvals[6] = { 204, 93, 44, 22, 11, 5 };
+    const int C = Cvals[nBits - 1];
+
+    int B = 0;
+    const SkTBits<int> valBits(val);
+    switch (nBits) {
+        case 1:
+            B = 0;
+            break;
+
+        case 2: {
+            const int b = valBits[1];
+            B = (b << 1) | (b << 2) | (b << 4) | (b << 8);
+        }
+        break;
+
+        case 3: {
+            const int cb = valBits(2, 1);
+            B = cb | (cb << 2) | (cb << 7);
+        }
+        break;
+
+        case 4: {
+            const int dcb = valBits(3, 1);
+            B = dcb | (dcb << 6);
+        }
+        break;
+
+        case 5: {
+            const int edcb = valBits(4, 1);
+            B = (edcb << 5) | (edcb >> 2);
+        }
+        break;
+
+        case 6: {
+            const int fedcb = valBits(5, 1);
+            B = (fedcb << 4) | (fedcb >> 4);
+        }
+        break;
+    }
+
+    return unquantize_value(0x80, A, B, C, D);
+}
+
+// Returns the unquantized value of a color that's represented as a
+// quint followed by nBits bits. This algorithm follows the sequence
+// defined in section C.2.13 of the ASTC spec.
+static inline int unquantize_quint_color(int val, int nBits) {
+    const int D = (val >> nBits) & 0x7;
+    SkASSERT(D < 5);
+
+    const int A = -(val & 0x1) & 0x1FF;
+
+    static const int Cvals[5] = { 113, 54, 26, 13, 6 };
+    SkASSERT(nBits > 0);
+    SkASSERT(nBits < 6);
+
+    const int C = Cvals[nBits - 1];
+
+    int B = 0;
+    const SkTBits<int> valBits(val);
+    switch (nBits) {
+        case 1:
+            B = 0;
+            break;
+
+        case 2: {
+            const int b = valBits[1];
+            B = (b << 2) | (b << 3) | (b << 8);
+        }
+        break;
+
+        case 3: {
+            const int cb = valBits(2, 1);
+            B = (cb >> 1) | (cb << 1) | (cb << 7);
+        }
+        break;
+
+        case 4: {
+            const int dcb = valBits(3, 1);
+            B = (dcb >> 1) | (dcb << 6);
+        }
+        break;
+
+        case 5: {
+            const int edcb = valBits(4, 1);
+            B = (edcb << 5) | (edcb >> 3);
+        }
+        break;
+    }
+
+    return unquantize_value(0x80, A, B, C, D);
+}
+
+// This algorithm takes a list of integers, stored in vals, and unquantizes them
+// in place. This follows the algorithm laid out in section C.2.13 of the ASTC spec.
+static void unquantize_colors(int *vals, int nVals, int nBits, int nTrits, int nQuints) {
+    for (int i = 0; i < nVals; ++i) {
+        if (nTrits > 0) {
+            SkASSERT(nQuints == 0);
+            vals[i] = unquantize_trit_color(vals[i], nBits);
+        } else if (nQuints > 0) {
+            SkASSERT(nTrits == 0);
+            vals[i] = unquantize_quint_color(vals[i], nBits);
+        } else {
+            SkASSERT(nQuints == 0 && nTrits == 0);
+            vals[i] = unquantize_bits_color(vals[i], nBits);
+        }
+    }
+}
+
+// Returns an interpolated value between c0 and c1 based on the weight. This
+// follows the algorithm laid out in section C.2.19 of the ASTC spec.
+static int interpolate_channel(int c0, int c1, int weight) {
+    SkASSERT(0 <= c0 && c0 < 256);
+    SkASSERT(0 <= c1 && c1 < 256);
+
+    c0 = (c0 << 8) | c0;
+    c1 = (c1 << 8) | c1;
+
+    const int result = ((c0*(64 - weight) + c1*weight + 32) / 64) >> 8;
+
+    if (result > 255) {
+        return 255;
+    }
+
+    SkASSERT(result >= 0);
+    return result;
+}
+
+// Returns an interpolated color between the two endpoints based on the weight.
+static SkColor interpolate_endpoints(const SkColor endpoints[2], int weight) {
+    return SkColorSetARGB(
+        interpolate_channel(SkColorGetA(endpoints[0]), SkColorGetA(endpoints[1]), weight),
+        interpolate_channel(SkColorGetR(endpoints[0]), SkColorGetR(endpoints[1]), weight),
+        interpolate_channel(SkColorGetG(endpoints[0]), SkColorGetG(endpoints[1]), weight),
+        interpolate_channel(SkColorGetB(endpoints[0]), SkColorGetB(endpoints[1]), weight));
+}
+
+// Returns an interpolated color between the two endpoints based on the weight.
+// It uses separate weights for the channel depending on the value of the 'plane'
+// variable. By default, all channels will use weight 0, and the value of plane
+// means that weight1 will be used for:
+// 0: red
+// 1: green
+// 2: blue
+// 3: alpha
+static SkColor interpolate_dual_endpoints(
+    const SkColor endpoints[2], int weight0, int weight1, int plane) {
+    int a = interpolate_channel(SkColorGetA(endpoints[0]), SkColorGetA(endpoints[1]), weight0);
+    int r = interpolate_channel(SkColorGetR(endpoints[0]), SkColorGetR(endpoints[1]), weight0);
+    int g = interpolate_channel(SkColorGetG(endpoints[0]), SkColorGetG(endpoints[1]), weight0);
+    int b = interpolate_channel(SkColorGetB(endpoints[0]), SkColorGetB(endpoints[1]), weight0);
+
+    switch (plane) {
+
+        case 0:
+            r = interpolate_channel(
+                SkColorGetR(endpoints[0]), SkColorGetR(endpoints[1]), weight1);
+            break;
+
+        case 1:
+            g = interpolate_channel(
+                SkColorGetG(endpoints[0]), SkColorGetG(endpoints[1]), weight1);
+            break;
+
+        case 2:
+            b = interpolate_channel(
+                SkColorGetB(endpoints[0]), SkColorGetB(endpoints[1]), weight1);
+            break;
+
+        case 3:
+            a = interpolate_channel(
+                SkColorGetA(endpoints[0]), SkColorGetA(endpoints[1]), weight1);
+            break;
+
+        default:
+            SkDEBUGFAIL("Plane should be 0-3");
+            break;
+    }
+
+    return SkColorSetARGB(a, r, g, b);
+}
+
+// A struct of decoded values that we use to carry around information
+// about the block. dimX and dimY are the dimension in texels of the block,
+// for which there is only a limited subset of valid values:
+//
+// 4x4, 5x4, 5x5, 6x5, 6x6, 8x5, 8x6, 8x8, 10x5, 10x6, 10x8, 10x10, 12x10, 12x12
+
+struct ASTCDecompressionData {
+    ASTCDecompressionData(int dimX, int dimY) : fDimX(dimX), fDimY(dimY) { }
+    const int   fDimX;      // the X dimension of the decompressed block
+    const int   fDimY;      // the Y dimension of the decompressed block
+    ASTCBlock   fBlock;     // the block data
+    int         fBlockMode; // the block header that contains the block mode.
+
+    bool fDualPlaneEnabled; // is this block compressing dual weight planes?
+    int  fDualPlane;        // the independent plane in dual plane mode.
+
+    bool fVoidExtent;       // is this block a single color?
+    bool fError;            // does this block have an error encoding?
+
+    int  fWeightDimX;       // the x dimension of the weight grid
+    int  fWeightDimY;       // the y dimension of the weight grid
+
+    int  fWeightBits;       // the number of bits used for each weight value
+    int  fWeightTrits;      // the number of trits used for each weight value
+    int  fWeightQuints;     // the number of quints used for each weight value
+
+    int  fPartCount;        // the number of partitions in this block
+    int  fPartIndex;        // the partition index: only relevant if fPartCount > 0
+
+    // CEM values can be anything in the range 0-15, and each corresponds to a different
+    // mode that represents the color data. We only support LDR modes.
+    enum ColorEndpointMode {
+        kLDR_Luminance_Direct_ColorEndpointMode          = 0,
+        kLDR_Luminance_BaseOffset_ColorEndpointMode      = 1,
+        kHDR_Luminance_LargeRange_ColorEndpointMode      = 2,
+        kHDR_Luminance_SmallRange_ColorEndpointMode      = 3,
+        kLDR_LuminanceAlpha_Direct_ColorEndpointMode     = 4,
+        kLDR_LuminanceAlpha_BaseOffset_ColorEndpointMode = 5,
+        kLDR_RGB_BaseScale_ColorEndpointMode             = 6,
+        kHDR_RGB_BaseScale_ColorEndpointMode             = 7,
+        kLDR_RGB_Direct_ColorEndpointMode                = 8,
+        kLDR_RGB_BaseOffset_ColorEndpointMode            = 9,
+        kLDR_RGB_BaseScaleWithAlpha_ColorEndpointMode    = 10,
+        kHDR_RGB_ColorEndpointMode                       = 11,
+        kLDR_RGBA_Direct_ColorEndpointMode               = 12,
+        kLDR_RGBA_BaseOffset_ColorEndpointMode           = 13,
+        kHDR_RGB_LDRAlpha_ColorEndpointMode              = 14,
+        kHDR_RGB_HDRAlpha_ColorEndpointMode              = 15
+    };
+    static const int kMaxColorEndpointModes = 16;
+
+    // the color endpoint modes for this block.
+    static const int kMaxPartitions = 4;
+    ColorEndpointMode fCEM[kMaxPartitions];
+
+    int  fColorStartBit;    // The bit position of the first bit of the color data
+    int  fColorEndBit;      // The bit position of the last *possible* bit of the color data
+
+    // Returns the number of partitions for this block.
+    int numPartitions() const {
+        return fPartCount;
+    }
+
+    // Returns the total number of weight values that are stored in this block
+    int numWeights() const {
+        return fWeightDimX * fWeightDimY * (fDualPlaneEnabled ? 2 : 1);
+    }
+
+#ifdef SK_DEBUG
+    // Returns the maximum value that any weight can take. We really only use
+    // this function for debugging.
+    int maxWeightValue() const {
+        int maxVal = (1 << fWeightBits);
+        if (fWeightTrits > 0) {
+            SkASSERT(0 == fWeightQuints);
+            maxVal *= 3;
+        } else if (fWeightQuints > 0) {
+            SkASSERT(0 == fWeightTrits);
+            maxVal *= 5;
+        }
+        return maxVal - 1;
+    }
+#endif
+
+    // The number of bits needed to represent the texel weight data. This
+    // comes from the 'data size determination' section of the ASTC spec (C.2.22)
+    int numWeightBits() const {
+        const int nWeights = this->numWeights();
+        return
+            ((nWeights*8*fWeightTrits + 4) / 5) +
+            ((nWeights*7*fWeightQuints + 2) / 3) +
+            (nWeights*fWeightBits);
+    }
+
+    // Returns the number of color values stored in this block. The number of
+    // values stored is directly a function of the color endpoint modes.
+    int numColorValues() const {
+        int numValues = 0;
+        for (int i = 0; i < this->numPartitions(); ++i) {
+            int cemInt = static_cast<int>(fCEM[i]);
+            numValues += ((cemInt >> 2) + 1) * 2;
+        }
+
+        return numValues;
+    }
+
+    // Figures out the number of bits available for color values, and fills
+    // in the maximum encoding that will fit the number of color values that
+    // we need. Returns false on error. (See section C.2.22 of the spec)
+    bool getColorValueEncoding(int *nBits, int *nTrits, int *nQuints) const {
+        if (NULL == nBits || NULL == nTrits || NULL == nQuints) {
+            return false;
+        }
+
+        const int nColorVals = this->numColorValues();
+        if (nColorVals <= 0) {
+            return false;
+        }
+
+        const int colorBits = fColorEndBit - fColorStartBit;
+        SkASSERT(colorBits > 0);
+
+        // This is the minimum amount of accuracy required by the spec.
+        if (colorBits < ((13 * nColorVals + 4) / 5)) {
+            return false;
+        }
+
+        // Values can be represented as at most 8-bit values.
+        // !SPEED! place this in a lookup table based on colorBits and nColorVals
+        for (int i = 255; i > 0; --i) {
+            int range = i + 1;
+            int bits = 0, trits = 0, quints = 0;
+            bool valid = false;
+            if (SkIsPow2(range)) {
+                bits = bits_for_range(range);
+                valid = true;
+            } else if ((range % 3) == 0 && SkIsPow2(range/3)) {
+                trits = 1;
+                bits = bits_for_range(range/3);
+                valid = true;
+            } else if ((range % 5) == 0 && SkIsPow2(range/5)) {
+                quints = 1;
+                bits = bits_for_range(range/5);
+                valid = true;
+            }
+
+            if (valid) {
+                const int actualColorBits =
+                    ((nColorVals*8*trits + 4) / 5) +
+                    ((nColorVals*7*quints + 2) / 3) +
+                    (nColorVals*bits);
+                if (actualColorBits <= colorBits) {
+                    *nTrits = trits;
+                    *nQuints = quints;
+                    *nBits = bits;
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    // Converts the sequence of color values into endpoints. The algorithm here
+    // corresponds to the values determined by section C.2.14 of the ASTC spec
+    void colorEndpoints(SkColor endpoints[4][2], const int* colorValues) const {
+        for (int i = 0; i < this->numPartitions(); ++i) {
+            switch (fCEM[i]) {
+                case kLDR_Luminance_Direct_ColorEndpointMode: {
+                    const int* v = colorValues;
+                    endpoints[i][0] = SkColorSetARGB(0xFF, v[0], v[0], v[0]);
+                    endpoints[i][1] = SkColorSetARGB(0xFF, v[1], v[1], v[1]);
+
+                    colorValues += 2;
+                }
+                break;
+
+                case kLDR_Luminance_BaseOffset_ColorEndpointMode: {
+                    const int* v = colorValues;
+                    const int L0 = (v[0] >> 2) | (v[1] & 0xC0);
+                    const int L1 = clamp_byte(L0 + (v[1] & 0x3F));
+
+                    endpoints[i][0] = SkColorSetARGB(0xFF, L0, L0, L0);
+                    endpoints[i][1] = SkColorSetARGB(0xFF, L1, L1, L1);
+
+                    colorValues += 2;
+                }
+                break;
+
+                case kLDR_LuminanceAlpha_Direct_ColorEndpointMode: {
+                    const int* v = colorValues;
+                    
+                    endpoints[i][0] = SkColorSetARGB(v[2], v[0], v[0], v[0]);
+                    endpoints[i][1] = SkColorSetARGB(v[3], v[1], v[1], v[1]);
+
+                    colorValues += 4;
+                }
+                break;
+
+                case kLDR_LuminanceAlpha_BaseOffset_ColorEndpointMode: {
+                    int v0 = colorValues[0];
+                    int v1 = colorValues[1];
+                    int v2 = colorValues[2];
+                    int v3 = colorValues[3];
+
+                    bit_transfer_signed(&v1, &v0);
+                    bit_transfer_signed(&v3, &v2);
+                    
+                    endpoints[i][0] = SkColorSetARGB(v2, v0, v0, v0);
+                    endpoints[i][1] = SkColorSetARGB(
+                        clamp_byte(v3+v2),
+                        clamp_byte(v1+v0),
+                        clamp_byte(v1+v0),
+                        clamp_byte(v1+v0));
+
+                    colorValues += 4;
+                }
+                break;
+
+                case kLDR_RGB_BaseScale_ColorEndpointMode: {
+                    decode_rgba_basescale(colorValues, endpoints[i], true);
+                    colorValues += 4;
+                }
+                break;
+
+                case kLDR_RGB_Direct_ColorEndpointMode: {
+                    decode_rgba_direct(colorValues, endpoints[i], true);
+                    colorValues += 6;
+                }
+                break;
+
+                case kLDR_RGB_BaseOffset_ColorEndpointMode: {
+                    decode_rgba_baseoffset(colorValues, endpoints[i], true);
+                    colorValues += 6;
+                }
+                break;
+
+                case kLDR_RGB_BaseScaleWithAlpha_ColorEndpointMode: {
+                    decode_rgba_basescale(colorValues, endpoints[i], false);
+                    colorValues += 6;
+                }
+                break;
+
+                case kLDR_RGBA_Direct_ColorEndpointMode: {
+                    decode_rgba_direct(colorValues, endpoints[i], false);
+                    colorValues += 8;
+                }
+                break;
+
+                case kLDR_RGBA_BaseOffset_ColorEndpointMode: {
+                    decode_rgba_baseoffset(colorValues, endpoints[i], false);
+                    colorValues += 8;
+                }
+                break;
+
+                default:
+                    SkDEBUGFAIL("HDR mode unsupported! This should be caught sooner.");
+                    break;
+            }
+        }
+    }
+
+    // Follows the procedure from section C.2.17 of the ASTC specification
+    int unquantizeWeight(int x) const {
+        SkASSERT(x <= this->maxWeightValue());
+
+        const int D = (x >> fWeightBits) & 0x7;
+        const int A = -(x & 0x1) & 0x7F;
+
+        SkTBits<int> xbits(x);
+
+        int T = 0;
+        if (fWeightTrits > 0) {
+            SkASSERT(0 == fWeightQuints);
+            switch (fWeightBits) {
+                case 0: {
+                    // x is a single trit
+                    SkASSERT(x < 3);
+
+                    static const int kUnquantizationTable[3] = { 0, 32, 63 };
+                    T = kUnquantizationTable[x];
+                }
+                break;
+
+                case 1: {
+                    const int B = 0;
+                    const int C = 50;
+                    T = unquantize_value(0x20, A, B, C, D);
+                }
+                break;
+
+                case 2: {
+                    const int b = xbits[1];
+                    const int B = b | (b << 2) | (b << 6);
+                    const int C = 23;
+                    T = unquantize_value(0x20, A, B, C, D);
+                }
+                break;
+
+                case 3: {
+                    const int cb = xbits(2, 1);
+                    const int B = cb | (cb << 5);
+                    const int C = 11;
+                    T = unquantize_value(0x20, A, B, C, D);
+                }
+                break;
+
+                default:
+                    SkDEBUGFAIL("Too many bits for trit encoding");
+                    break;
+            }
+
+        } else if (fWeightQuints > 0) {
+            SkASSERT(0 == fWeightTrits);
+            switch (fWeightBits) {
+                case 0: {
+                    // x is a single quint
+                    SkASSERT(x < 5);
+
+                    static const int kUnquantizationTable[5] = { 0, 16, 32, 47, 63 };
+                    T = kUnquantizationTable[x];
+                }
+                break;
+
+                case 1: {
+                    const int B = 0;
+                    const int C = 28;
+                    T = unquantize_value(0x20, A, B, C, D);
+                }
+                break;
+
+                case 2: {
+                    const int b = xbits[1];
+                    const int B = (b << 1) | (b << 6);
+                    const int C = 13;
+                    T = unquantize_value(0x20, A, B, C, D);
+                }
+                break;
+
+                default:
+                    SkDEBUGFAIL("Too many bits for quint encoding");
+                    break;
+            }
+        } else {
+            SkASSERT(0 == fWeightTrits);
+            SkASSERT(0 == fWeightQuints);
+
+            T = replicate_bits(x, fWeightBits, 6);
+        }
+
+        // This should bring the value within [0, 63]..
+        SkASSERT(T <= 63);
+
+        if (T > 32) {
+            T += 1;
+        }
+
+        SkASSERT(T <= 64);
+
+        return T;
+    }
+
+    // Returns the weight at the associated index. If the index is out of bounds, it
+    // returns zero. It also chooses the weight appropriately based on the given dual
+    // plane.
+    int getWeight(const int* unquantizedWeights, int idx, bool dualPlane) const {
+        const int maxIdx = (fDualPlaneEnabled ? 2 : 1) * fWeightDimX * fWeightDimY - 1;
+        if (fDualPlaneEnabled) {
+            const int effectiveIdx = 2*idx + (dualPlane ? 1 : 0);
+            if (effectiveIdx > maxIdx) {
+                return 0;
+            }
+            return unquantizedWeights[effectiveIdx];
+        }
+
+        SkASSERT(!dualPlane);
+
+        if (idx > maxIdx) {
+            return 0;
+        } else {
+            return unquantizedWeights[idx];
+        }
+    }
+
+    // This computes the effective weight at location (s, t) of the block. This
+    // weight is computed by sampling the texel weight grid (it's usually not 1-1), and
+    // then applying a bilerp. The algorithm outlined here follows the algorithm
+    // defined in section C.2.18 of the ASTC spec.
+    int infillWeight(const int* unquantizedValues, int s, int t, bool dualPlane) const {
+        const int Ds = (1024 + fDimX/2) / (fDimX - 1);
+        const int Dt = (1024 + fDimY/2) / (fDimY - 1);
+
+        const int cs = Ds * s;
+        const int ct = Dt * t;
+
+        const int gs = (cs*(fWeightDimX - 1) + 32) >> 6;
+        const int gt = (ct*(fWeightDimY - 1) + 32) >> 6;
+
+        const int js = gs >> 4;
+        const int jt = gt >> 4;
+
+        const int fs = gs & 0xF;
+        const int ft = gt & 0xF;
+
+        const int idx = js + jt*fWeightDimX;
+        const int p00 = this->getWeight(unquantizedValues, idx, dualPlane);
+        const int p01 = this->getWeight(unquantizedValues, idx + 1, dualPlane);
+        const int p10 = this->getWeight(unquantizedValues, idx + fWeightDimX, dualPlane);
+        const int p11 = this->getWeight(unquantizedValues, idx + fWeightDimX + 1, dualPlane);
+
+        const int w11 = (fs*ft + 8) >> 4;
+        const int w10 = ft - w11;
+        const int w01 = fs - w11;
+        const int w00 = 16 - fs - ft + w11;
+
+        const int weight = (p00*w00 + p01*w01 + p10*w10 + p11*w11 + 8) >> 4;
+        SkASSERT(weight <= 64);
+        return weight;
+    }
+
+    // Unquantizes the decoded texel weights as described in section C.2.17 of
+    // the ASTC specification. Additionally, it populates texelWeights with
+    // the expanded weight grid, which is computed according to section C.2.18
+    void texelWeights(int texelWeights[2][12][12], const int* texelValues) const {
+        // Unquantized texel weights...
+        int unquantizedValues[144*2]; // 12x12 blocks with dual plane decoding...
+        SkASSERT(this->numWeights() <= 144*2);
+
+        // Unquantize the weights and cache them
+        for (int j = 0; j < this->numWeights(); ++j) {
+            unquantizedValues[j] = this->unquantizeWeight(texelValues[j]);
+        }
+
+        // Do weight infill...
+        for (int y = 0; y < fDimY; ++y) {
+            for (int x = 0; x < fDimX; ++x) {
+                texelWeights[0][x][y] = this->infillWeight(unquantizedValues, x, y, false);
+                if (fDualPlaneEnabled) {
+                    texelWeights[1][x][y] = this->infillWeight(unquantizedValues, x, y, true);
+                }
+            }
+        }
+    }
+
+    // Returns the partition for the texel located at position (x, y).
+    // Adapted from C.2.21 of the ASTC specification
+    int getPartition(int x, int y) const {
+        const int partitionCount = this->numPartitions();
+        int seed = fPartIndex;
+        if ((fDimX * fDimY) < 31) {
+            x <<= 1;
+            y <<= 1;
+        }
+
+        seed += (partitionCount - 1) * 1024;
+
+        uint32_t p = seed;
+        p ^= p >> 15;  p -= p << 17;  p += p << 7; p += p <<  4;
+        p ^= p >>  5;  p += p << 16;  p ^= p >> 7; p ^= p >> 3;
+        p ^= p <<  6;  p ^= p >> 17;
+
+        uint32_t rnum = p;
+        uint8_t seed1  =  rnum        & 0xF;
+        uint8_t seed2  = (rnum >>  4) & 0xF;
+        uint8_t seed3  = (rnum >>  8) & 0xF;
+        uint8_t seed4  = (rnum >> 12) & 0xF;
+        uint8_t seed5  = (rnum >> 16) & 0xF;
+        uint8_t seed6  = (rnum >> 20) & 0xF;
+        uint8_t seed7  = (rnum >> 24) & 0xF;
+        uint8_t seed8  = (rnum >> 28) & 0xF;
+        uint8_t seed9  = (rnum >> 18) & 0xF;
+        uint8_t seed10 = (rnum >> 22) & 0xF;
+        uint8_t seed11 = (rnum >> 26) & 0xF;
+        uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF;
+
+        seed1 *= seed1;     seed2 *= seed2;
+        seed3 *= seed3;     seed4 *= seed4;
+        seed5 *= seed5;     seed6 *= seed6;
+        seed7 *= seed7;     seed8 *= seed8;
+        seed9 *= seed9;     seed10 *= seed10;
+        seed11 *= seed11;   seed12 *= seed12;
+
+        int sh1, sh2, sh3;
+        if (0 != (seed & 1)) {
+            sh1 = (0 != (seed & 2))? 4 : 5;
+            sh2 = (partitionCount == 3)? 6 : 5;
+        } else {
+            sh1 = (partitionCount==3)? 6 : 5;
+            sh2 = (0 != (seed & 2))? 4 : 5;
+        }
+        sh3 = (0 != (seed & 0x10))? sh1 : sh2;
+
+        seed1 >>= sh1; seed2  >>= sh2; seed3  >>= sh1; seed4  >>= sh2;
+        seed5 >>= sh1; seed6  >>= sh2; seed7  >>= sh1; seed8  >>= sh2;
+        seed9 >>= sh3; seed10 >>= sh3; seed11 >>= sh3; seed12 >>= sh3;
+
+        const int z = 0;
+        int a = seed1*x + seed2*y + seed11*z + (rnum >> 14);
+        int b = seed3*x + seed4*y + seed12*z + (rnum >> 10);
+        int c = seed5*x + seed6*y + seed9 *z + (rnum >>  6);
+        int d = seed7*x + seed8*y + seed10*z + (rnum >>  2);
+
+        a &= 0x3F;
+        b &= 0x3F;
+        c &= 0x3F;
+        d &= 0x3F;
+
+        if (partitionCount < 4) {
+            d = 0;
+        }
+
+        if (partitionCount < 3) {
+            c = 0;
+        }
+
+        if (a >= b && a >= c && a >= d) {
+            return 0;
+        } else if (b >= c && b >= d) {
+            return 1;
+        } else if (c >= d) {
+            return 2;
+        } else {
+            return 3;
+        }
+    }
+
+    // Performs the proper interpolation of the texel based on the
+    // endpoints and weights.
+    SkColor getTexel(const SkColor endpoints[4][2],
+                     const int weights[2][12][12],
+                     int x, int y) const {
+        int part = 0;
+        if (this->numPartitions() > 1) {
+            part = this->getPartition(x, y);
+        }
+
+        SkColor result;
+        if (fDualPlaneEnabled) {
+            result = interpolate_dual_endpoints(
+                endpoints[part], weights[0][x][y], weights[1][x][y], fDualPlane);
+        } else {
+            result = interpolate_endpoints(endpoints[part], weights[0][x][y]);
+        }
+
+#if 1
+        // !FIXME! if we're writing directly to a bitmap, then we don't need
+        // to swap the red and blue channels, but since we're usually being used
+        // by the SkImageDecoder_astc module, the results are expected to be in RGBA.
+        result = SkColorSetARGB(
+            SkColorGetA(result), SkColorGetB(result), SkColorGetG(result), SkColorGetR(result));
+#endif
+
+        return result;
+    }
+
+    void decode() {
+        // First decode the block mode.
+        this->decodeBlockMode();
+
+        // Now we can decode the partition information.
+        fPartIndex = static_cast<int>(read_astc_bits(fBlock, 11, 23));
+        fPartCount = (fPartIndex & 0x3) + 1;
+        fPartIndex >>= 2;
+
+        // This is illegal
+        if (fDualPlaneEnabled && this->numPartitions() == 4) {
+            fError = true;
+            return;
+        }
+
+        // Based on the partition info, we can decode the color information.
+        this->decodeColorData();
+    }
+
+    // Decodes the dual plane based on the given bit location. The final
+    // location, if the dual plane is enabled, is also the end of our color data.
+    // This function is only meant to be used from this->decodeColorData()
+    void decodeDualPlane(int bitLoc) {
+        if (fDualPlaneEnabled) {
+            fDualPlane = static_cast<int>(read_astc_bits(fBlock, bitLoc - 2, bitLoc));
+            fColorEndBit = bitLoc - 2;
+        } else {
+            fColorEndBit = bitLoc;
+        }
+    }
+
+    // Decodes the color information based on the ASTC spec.
+    void decodeColorData() {
+
+        // By default, the last color bit is at the end of the texel weights
+        const int lastWeight = 128 - this->numWeightBits();
+
+        // If we have a dual plane then it will be at this location, too.
+        int dualPlaneBitLoc = lastWeight;
+
+        // If there's only one partition, then our job is (relatively) easy.
+        if (this->numPartitions() == 1) {
+            fCEM[0] = static_cast<ColorEndpointMode>(read_astc_bits(fBlock, 13, 17));
+            fColorStartBit = 17;
+
+            // Handle dual plane mode...
+            this->decodeDualPlane(dualPlaneBitLoc);
+
+            return;
+        } 
+
+        // If we have more than one partition, then we need to make
+        // room for the partition index.
+        fColorStartBit = 29;
+
+        // Read the base CEM. If it's zero, then we have no additional
+        // CEM data and the endpoints for each partition share the same CEM.
+        const int baseCEM = static_cast<int>(read_astc_bits(fBlock, 23, 25));
+        if (0 == baseCEM) {
+
+            const ColorEndpointMode sameCEM =
+                static_cast<ColorEndpointMode>(read_astc_bits(fBlock, 25, 29));
+
+            for (int i = 0; i < kMaxPartitions; ++i) {
+                fCEM[i] = sameCEM;
+            }
+
+            // Handle dual plane mode...
+            this->decodeDualPlane(dualPlaneBitLoc);
+
+            return;
+        } 
+
+        // Move the dual plane selector bits down based on how many
+        // partitions the block contains.
+        switch (this->numPartitions()) {
+            case 2:
+                dualPlaneBitLoc -= 2;
+                break;
+
+            case 3:
+                dualPlaneBitLoc -= 5;
+                break;
+
+            case 4:
+                dualPlaneBitLoc -= 8;
+                break;
+
+            default:
+                SkDEBUGFAIL("Internal ASTC decoding error.");
+                break;
+        }
+
+        // The rest of the CEM config will be between the dual plane bit selector
+        // and the texel weight grid.
+        const int lowCEM = static_cast<int>(read_astc_bits(fBlock, 23, 29));
+        SkASSERT(lastWeight >= dualPlaneBitLoc);
+        SkASSERT(lastWeight - dualPlaneBitLoc < 31);
+        int fullCEM = static_cast<int>(read_astc_bits(fBlock, dualPlaneBitLoc, lastWeight));
+
+        // Attach the config at the end of the weight grid to the CEM values
+        // in the beginning of the block.
+        fullCEM = (fullCEM << 6) | lowCEM;
+
+        // Ignore the two least significant bits, since those are our baseCEM above.
+        fullCEM = fullCEM >> 2;
+
+        int C[kMaxPartitions]; // Next, decode C and M from the spec (Table C.2.12)
+        for (int i = 0; i < this->numPartitions(); ++i) {
+            C[i] = fullCEM & 1;
+            fullCEM = fullCEM >> 1;
+        }
+
+        int M[kMaxPartitions];
+        for (int i = 0; i < this->numPartitions(); ++i) {
+            M[i] = fullCEM & 0x3;
+            fullCEM = fullCEM >> 2;
+        }
+
+        // Construct our CEMs..
+        SkASSERT(baseCEM > 0);
+        for (int i = 0; i < this->numPartitions(); ++i) {
+            int cem = (baseCEM - 1) * 4;
+            cem += (0 == C[i])? 0 : 4;
+            cem += M[i];
+
+            SkASSERT(cem < 16);
+            fCEM[i] = static_cast<ColorEndpointMode>(cem);
+        }
+
+        // Finally, if we have dual plane mode, then read the plane selector.
+        this->decodeDualPlane(dualPlaneBitLoc);
+    }
+
+    // Decodes the block mode. This function determines whether or not we use
+    // dual plane encoding, the size of the texel weight grid, and the number of
+    // bits, trits and quints that are used to encode it. For more information, 
+    // see section C.2.10 of the ASTC spec.
+    //
+    // For 2D blocks, the Block Mode field is laid out as follows:
+    //
+    // -------------------------------------------------------------------------
+    // 10  9   8   7   6   5   4   3   2   1   0   Width Height Notes
+    // -------------------------------------------------------------------------
+    // D   H     B       A     R0  0   0   R2  R1  B+4   A+2
+    // D   H     B       A     R0  0   1   R2  R1  B+8   A+2
+    // D   H     B       A     R0  1   0   R2  R1  A+2   B+8
+    // D   H   0   B     A     R0  1   1   R2  R1  A+2   B+6
+    // D   H   1   B     A     R0  1   1   R2  R1  B+2   A+2
+    // D   H   0   0     A     R0  R2  R1  0   0   12    A+2
+    // D   H   0   1     A     R0  R2  R1  0   0   A+2   12
+    // D   H   1   1   0   0   R0  R2  R1  0   0   6     10
+    // D   H   1   1   0   1   R0  R2  R1  0   0   10    6
+    //   B     1   0     A     R0  R2  R1  0   0   A+6   B+6   D=0, H=0
+    // x   x   1   1   1   1   1   1   1   0   0   -     -     Void-extent
+    // x   x   1   1   1   x   x   x   x   0   0   -     -     Reserved*
+    // x   x   x   x   x   x   x   0   0   0   0   -     -     Reserved
+    // -------------------------------------------------------------------------
+    //
+    // D - dual plane enabled
+    // H, R - used to determine the number of bits/trits/quints in texel weight encoding
+    //        R is a three bit value whose LSB is R0 and MSB is R1
+    // Width, Height - dimensions of the texel weight grid (determined by A and B)
+
+    void decodeBlockMode() {
+        const int blockMode = static_cast<int>(read_astc_bits(fBlock, 0, 11));
+
+        // Check for special void extent encoding
+        fVoidExtent = (blockMode & 0x1FF) == 0x1FC;
+
+        // Check for reserved block modes
+        fError = ((blockMode & 0x1C3) == 0x1C0) || ((blockMode & 0xF) == 0);
+
+        // Neither reserved nor void-extent, decode as usual
+        // This code corresponds to table C.2.8 of the ASTC spec
+        bool highPrecision = false;
+        int R = 0;
+        if ((blockMode & 0x3) == 0) {
+            R = ((0xC & blockMode) >> 1) | ((0x10 & blockMode) >> 4);
+            const int bitsSevenAndEight = (blockMode & 0x180) >> 7;
+            SkASSERT(0 <= bitsSevenAndEight && bitsSevenAndEight < 4);
+
+            const int A = (blockMode >> 5) & 0x3;
+            const int B = (blockMode >> 9) & 0x3;
+
+            fDualPlaneEnabled = (blockMode >> 10) & 0x1;
+            highPrecision = (blockMode >> 9) & 0x1;
+
+            switch (bitsSevenAndEight) {
+                default:
+                case 0:
+                    fWeightDimX = 12;
+                    fWeightDimY = A + 2;
+                    break;
+
+                case 1:
+                    fWeightDimX = A + 2;
+                    fWeightDimY = 12;
+                    break;
+
+                case 2:
+                    fWeightDimX = A + 6;
+                    fWeightDimY = B + 6;
+                    fDualPlaneEnabled = false;
+                    highPrecision = false;
+                    break;
+
+                case 3:
+                    if (0 == A) {
+                        fWeightDimX = 6;
+                        fWeightDimY = 10;
+                    } else {
+                        fWeightDimX = 10;
+                        fWeightDimY = 6;
+                    }
+                    break;
+            }
+        } else { // (blockMode & 0x3) != 0
+            R = ((blockMode & 0x3) << 1) | ((blockMode & 0x10) >> 4);
+
+            const int bitsTwoAndThree = (blockMode >> 2) & 0x3;
+            SkASSERT(0 <= bitsTwoAndThree && bitsTwoAndThree < 4);
+
+            const int A = (blockMode >> 5) & 0x3;
+            const int B = (blockMode >> 7) & 0x3;
+
+            fDualPlaneEnabled = (blockMode >> 10) & 0x1;
+            highPrecision = (blockMode >> 9) & 0x1;
+
+            switch (bitsTwoAndThree) {
+                case 0:
+                    fWeightDimX = B + 4;
+                    fWeightDimY = A + 2;
+                    break;
+                case 1:
+                    fWeightDimX = B + 8;
+                    fWeightDimY = A + 2;
+                    break;
+                case 2:
+                    fWeightDimX = A + 2;
+                    fWeightDimY = B + 8;
+                    break;
+                case 3:
+                    if ((B & 0x2) == 0) {
+                        fWeightDimX = A + 2;
+                        fWeightDimY = (B & 1) + 6;
+                    } else {
+                        fWeightDimX = (B & 1) + 2;
+                        fWeightDimY = A + 2;
+                    }
+                    break;
+            }
+        }
+
+        // We should have set the values of R and highPrecision
+        // from decoding the block mode, these are used to determine
+        // the proper dimensions of our weight grid.
+        if ((R & 0x6) == 0) {
+            fError = true;
+        } else {
+            static const int kBitAllocationTable[2][6][3] = {
+                {
+                    {  1, 0, 0 },
+                    {  0, 1, 0 },
+                    {  2, 0, 0 },
+                    {  0, 0, 1 },
+                    {  1, 1, 0 },
+                    {  3, 0, 0 }
+                },
+                {
+                    {  1, 0, 1 },
+                    {  2, 1, 0 },
+                    {  4, 0, 0 },
+                    {  2, 0, 1 },
+                    {  3, 1, 0 },
+                    {  5, 0, 0 }
+                }
+            };
+
+            fWeightBits = kBitAllocationTable[highPrecision][R - 2][0];
+            fWeightTrits = kBitAllocationTable[highPrecision][R - 2][1];
+            fWeightQuints = kBitAllocationTable[highPrecision][R - 2][2];
+        }
+    }
+};
+
+// Reads an ASTC block from the given pointer.
+static inline void read_astc_block(ASTCDecompressionData *dst, const uint8_t* src) {
+    const uint64_t* qword = reinterpret_cast<const uint64_t*>(src);
+    dst->fBlock.fLow = SkEndian_SwapLE64(qword[0]);
+    dst->fBlock.fHigh = SkEndian_SwapLE64(qword[1]);
+    dst->decode();
+}
+
+// Take a known void-extent block, and write out the values as a constant color.
+static void decompress_void_extent(uint8_t* dst, int dstRowBytes,
+                                   const ASTCDecompressionData &data) {
+    // The top 64 bits contain 4 16-bit RGBA values.
+    int a = (static_cast<int>(read_astc_bits(data.fBlock, 112, 128)) + 255) >> 8;
+    int b = (static_cast<int>(read_astc_bits(data.fBlock, 96, 112)) + 255) >> 8;
+    int g = (static_cast<int>(read_astc_bits(data.fBlock, 80, 96)) + 255) >> 8;
+    int r = (static_cast<int>(read_astc_bits(data.fBlock, 64, 80)) + 255) >> 8;
+
+    write_constant_color(dst, data.fDimX, data.fDimY, dstRowBytes, SkColorSetARGB(a, r, g, b));
+}
+
+// Decompresses a single ASTC block. It's assumed that data.fDimX and data.fDimY are
+// set and that the block has already been decoded (i.e. data.decode() has been called)
+static void decompress_astc_block(uint8_t* dst, int dstRowBytes,
+                                  const ASTCDecompressionData &data) {
+    if (data.fError) {
+        write_error_color(dst, data.fDimX, data.fDimY, dstRowBytes);
+        return;
+    }
+
+    if (data.fVoidExtent) {
+        decompress_void_extent(dst, dstRowBytes, data);
+        return;
+    }
+
+    // According to the spec, any more than 64 values is illegal. (C.2.24)
+    static const int kMaxTexelValues = 64;
+
+    // Decode the texel weights.
+    int texelValues[kMaxTexelValues];
+    bool success = decode_integer_sequence(
+        texelValues, kMaxTexelValues, data.numWeights(),
+        // texel data goes to the end of the 128 bit block.
+        data.fBlock, 128, 128 - data.numWeightBits(), false,
+        data.fWeightBits, data.fWeightTrits, data.fWeightQuints);
+
+    if (!success) {
+        write_error_color(dst, data.fDimX, data.fDimY, dstRowBytes);
+        return;
+    }
+
+    // Decode the color endpoints
+    int colorBits, colorTrits, colorQuints;
+    if (!data.getColorValueEncoding(&colorBits, &colorTrits, &colorQuints)) {
+        write_error_color(dst, data.fDimX, data.fDimY, dstRowBytes);
+        return;
+    }
+
+    // According to the spec, any more than 18 color values is illegal. (C.2.24)
+    static const int kMaxColorValues = 18;
+
+    int colorValues[kMaxColorValues];
+    success = decode_integer_sequence(
+        colorValues, kMaxColorValues, data.numColorValues(),
+        data.fBlock, data.fColorStartBit, data.fColorEndBit, true,
+        colorBits, colorTrits, colorQuints);
+
+    if (!success) {
+        write_error_color(dst, data.fDimX, data.fDimY, dstRowBytes);
+        return;
+    }
+
+    // Unquantize the color values after they've been decoded.
+    unquantize_colors(colorValues, data.numColorValues(), colorBits, colorTrits, colorQuints);
+
+    // Decode the colors into the appropriate endpoints.
+    SkColor endpoints[4][2];
+    data.colorEndpoints(endpoints, colorValues);
+
+    // Do texel infill and decode the texel values.
+    int texelWeights[2][12][12];
+    data.texelWeights(texelWeights, texelValues);
+
+    // Write the texels by interpolating them based on the information
+    // stored in the block.
+    dst += data.fDimY * dstRowBytes;
+    for (int y = 0; y < data.fDimY; ++y) {
+        dst -= dstRowBytes;
+        SkColor* colorPtr = reinterpret_cast<SkColor*>(dst);
+        for (int x = 0; x < data.fDimX; ++x) {
+            colorPtr[x] = data.getTexel(endpoints, texelWeights, x, y);
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// ASTC Comrpession Struct
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// This is the type passed as the CompressorType argument of the compressed
+// blitter for the ASTC format. The static functions required to be in this
+// struct are documented in SkTextureCompressor_Blitter.h
+struct CompressorASTC {
+    static inline void CompressA8Vertical(uint8_t* dst, const uint8_t* src) {
+        compress_a8_astc_block<GetAlphaTranspose>(&dst, src, 12);
+    }
+
+    static inline void CompressA8Horizontal(uint8_t* dst, const uint8_t* src,
+                                            int srcRowBytes) {
+        compress_a8_astc_block<GetAlpha>(&dst, src, srcRowBytes);
+    }
+
+#if PEDANTIC_BLIT_RECT
+    static inline void UpdateBlock(uint8_t* dst, const uint8_t* src, int srcRowBytes,
+                                   const uint8_t* mask) {
+        // TODO: krajcevski
+        // This is kind of difficult for ASTC because the weight values are calculated
+        // as an average of the actual weights. The best we can do is decompress the
+        // weights and recalculate them based on the new texel values. This should
+        // be "not too bad" since we know that anytime we hit this function, we're
+        // compressing 12x12 block dimension alpha-only, and we know the layout
+        // of the block
+        SkFAIL("Implement me!");
+    }
+#endif
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace SkTextureCompressor {
+
+bool CompressA8To12x12ASTC(uint8_t* dst, const uint8_t* src,
+                           int width, int height, int rowBytes) {
+    if (width < 0 || ((width % 12) != 0) || height < 0 || ((height % 12) != 0)) {
+        return false;
+    }
+
+    uint8_t** dstPtr = &dst;
+    for (int y = 0; y < height; y += 12) {
+        for (int x = 0; x < width; x += 12) {
+            compress_a8_astc_block<GetAlpha>(dstPtr, src + y*rowBytes + x, rowBytes);
+        }
+    }
+
+    return true;
+}
+
+SkBlitter* CreateASTCBlitter(int width, int height, void* outputBuffer,
+                             SkTBlitterAllocator* allocator) {
+    if ((width % 12) != 0 || (height % 12) != 0) {
+        return NULL;
+    }
+
+    // Memset the output buffer to an encoding that decodes to zero. We must do this
+    // in order to avoid having uninitialized values in the buffer if the blitter
+    // decides not to write certain scanlines (and skip entire rows of blocks).
+    // In the case of ASTC, if everything index is zero, then the interpolated value
+    // will decode to zero provided we have the right header. We use the encoding
+    // from recognizing all zero blocks from above.
+    const int nBlocks = (width * height / 144);
+    uint8_t *dst = reinterpret_cast<uint8_t *>(outputBuffer);
+    for (int i = 0; i < nBlocks; ++i) {
+        send_packing(&dst, SkTEndian_SwapLE64(0x0000000001FE000173ULL), 0);
+    }
+
+    return allocator->createT<
+        SkTCompressedAlphaBlitter<12, 16, CompressorASTC>, int, int, void* >
+        (width, height, outputBuffer);
+}
+
+void DecompressASTC(uint8_t* dst, int dstRowBytes, const uint8_t* src,
+                    int width, int height, int blockDimX, int blockDimY) {
+    // ASTC is encoded in what they call "raster order", so that the first
+    // block is the bottom-left block in the image, and the first pixel
+    // is the bottom-left pixel of the image
+    dst += height * dstRowBytes;
+
+    ASTCDecompressionData data(blockDimX, blockDimY);
+    for (int y = 0; y < height; y += blockDimY) {
+        dst -= blockDimY * dstRowBytes;
+        SkColor *colorPtr = reinterpret_cast<SkColor*>(dst);
+        for (int x = 0; x < width; x += blockDimX) {
+            read_astc_block(&data, src);
+            decompress_astc_block(reinterpret_cast<uint8_t*>(colorPtr + x), dstRowBytes, data);
+
+            // ASTC encoded blocks are 16 bytes (128 bits) large.
+            src += 16;
+        }
+    }
+}
+
+}  // SkTextureCompressor
diff --git a/src/utils/SkTextureCompressor_ASTC.h b/src/utils/SkTextureCompressor_ASTC.h
new file mode 100644
index 0000000..bdbe630
--- /dev/null
+++ b/src/utils/SkTextureCompressor_ASTC.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTextureCompressor_ASTC_DEFINED
+#define SkTextureCompressor_ASTC_DEFINED
+
+#include "SkBitmapProcShader.h"
+
+class SkBlitter;
+
+namespace SkTextureCompressor {
+
+    bool CompressA8To12x12ASTC(uint8_t* dst, const uint8_t* src,
+                               int width, int height, int rowBytes);
+
+    SkBlitter* CreateASTCBlitter(int width, int height, void* outputBuffer,
+                                 SkTBlitterAllocator *allocator);
+
+    void DecompressASTC(uint8_t* dst, int dstRowBytes, const uint8_t* src,
+                        int width, int height, int blockDimX, int blockDimY);
+}
+
+#endif  // SkTextureCompressor_ASTC_DEFINED
diff --git a/src/utils/SkTextureCompressor_Blitter.h b/src/utils/SkTextureCompressor_Blitter.h
new file mode 100644
index 0000000..3d30501
--- /dev/null
+++ b/src/utils/SkTextureCompressor_Blitter.h
@@ -0,0 +1,732 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTextureCompressor_Blitter_DEFINED
+#define SkTextureCompressor_Blitter_DEFINED
+
+#include "SkTypes.h"
+#include "SkBlitter.h"
+
+namespace SkTextureCompressor {
+
+// Ostensibly, SkBlitter::BlitRect is supposed to set a rect of pixels to full
+// alpha. This becomes problematic when using compressed texture blitters, since
+// the rect rarely falls along block boundaries. The proper way to handle this is
+// to update the compressed encoding of a block by resetting the proper parameters
+// (and even recompressing the block) where a rect falls inbetween block boundaries.
+// PEDANTIC_BLIT_RECT attempts to do this by requiring the struct passed to
+// SkTCompressedAlphaBlitter to implement an UpdateBlock function call.
+//
+// However, the way that BlitRect gets used almost exclusively is to bracket inverse
+// fills for paths. In other words, the top few rows and bottom few rows of a path
+// that's getting inverse filled are called using blitRect. The rest are called using
+// the standard blitAntiH. As a result, we can just call  blitAntiH with a faux RLE
+// of full alpha values, and then check in our flush() call that we don't run off the
+// edge of the buffer. This is why we do not need this flag to be turned on.
+//
+// NOTE: This code is unfinished, but is inteded as a starting point if an when
+// bugs are introduced from the existing code.
+#define PEDANTIC_BLIT_RECT 0
+
+// This class implements a blitter that blits directly into a buffer that will
+// be used as an compressed alpha texture. We compute this buffer by
+// buffering scan lines and then outputting them all at once. The number of
+// scan lines buffered is controlled by kBlockSize
+//
+// The CompressorType is a struct with a bunch of static methods that provides
+// the specialized compression functionality of the blitter. A complete CompressorType
+// will implement the following static functions;
+//
+// struct CompressorType {
+//     // The function used to compress an A8 block. The layout of the
+//     // block is also expected to be in column-major order.
+//     static void CompressA8Vertical(uint8_t* dst, const uint8_t block[]);
+//
+//     // The function used to compress an A8 block. The layout of the
+//     // block is also expected to be in row-major order.
+//     static void CompressA8Horizontal(uint8_t* dst, const uint8_t* src, int srcRowBytes);
+//
+#if PEDANTIC_BLIT_RECT
+//     // The function used to update an already compressed block. This will
+//     // most likely be implementation dependent. The mask variable will have
+//     // 0xFF in positions where the block should be updated and 0 in positions
+//     // where it shouldn't. src contains an uncompressed buffer of pixels.
+//     static void UpdateBlock(uint8_t* dst, const uint8_t* src, int srcRowBytes, 
+//                             const uint8_t* mask);
+#endif
+// };
+template<int BlockDim, int EncodedBlockSize, typename CompressorType>
+class SkTCompressedAlphaBlitter : public SkBlitter {
+public:
+    SkTCompressedAlphaBlitter(int width, int height, void *compressedBuffer)
+        // 0x7FFE is one minus the largest positive 16-bit int. We use it for
+        // debugging to make sure that we're properly setting the nextX distance
+        // in flushRuns(). 
+#ifdef SK_DEBUG
+        : fCalledOnceWithNonzeroY(false)
+        , fBlitMaskCalled(false),
+#else
+        :
+#endif
+        kLongestRun(0x7FFE), kZeroAlpha(0)
+        , fNextRun(0)
+        , fWidth(width)
+        , fHeight(height)
+        , fBuffer(compressedBuffer)
+        {
+            SkASSERT((width % BlockDim) == 0);
+            SkASSERT((height % BlockDim) == 0);
+        }
+
+    virtual ~SkTCompressedAlphaBlitter() { this->flushRuns(); }
+
+    // Blit a horizontal run of one or more pixels.
+    virtual void blitH(int x, int y, int width) SK_OVERRIDE {
+        // This function is intended to be called from any standard RGB
+        // buffer, so we should never encounter it. However, if some code
+        // path does end up here, then this needs to be investigated.
+        SkFAIL("Not implemented!");
+    }
+    
+    // Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
+    // zero-terminated run-length encoding of spans of constant alpha values.
+    virtual void blitAntiH(int x, int y,
+                           const SkAlpha antialias[],
+                           const int16_t runs[]) SK_OVERRIDE {
+        SkASSERT(0 == x);
+
+        // Make sure that the new row to blit is either the first
+        // row that we're blitting, or it's exactly the next scan row
+        // since the last row that we blit. This is to ensure that when
+        // we go to flush the runs, that they are all the same four
+        // runs.
+        if (fNextRun > 0 &&
+            ((x != fBufferedRuns[fNextRun-1].fX) ||
+             (y-1 != fBufferedRuns[fNextRun-1].fY))) {
+            this->flushRuns();
+        }
+
+        // Align the rows to a block boundary. If we receive rows that
+        // are not on a block boundary, then fill in the preceding runs
+        // with zeros. We do this by producing a single RLE that says
+        // that we have 0x7FFE pixels of zero (0x7FFE = 32766).
+        const int row = BlockDim * (y / BlockDim);
+        while ((row + fNextRun) < y) {
+            fBufferedRuns[fNextRun].fAlphas = &kZeroAlpha;
+            fBufferedRuns[fNextRun].fRuns = &kLongestRun;
+            fBufferedRuns[fNextRun].fX = 0;
+            fBufferedRuns[fNextRun].fY = row + fNextRun;
+            ++fNextRun;
+        }
+
+        // Make sure that our assumptions aren't violated...
+        SkASSERT(fNextRun == (y % BlockDim));
+        SkASSERT(fNextRun == 0 || fBufferedRuns[fNextRun - 1].fY < y);
+
+        // Set the values of the next run
+        fBufferedRuns[fNextRun].fAlphas = antialias;
+        fBufferedRuns[fNextRun].fRuns = runs;
+        fBufferedRuns[fNextRun].fX = x;
+        fBufferedRuns[fNextRun].fY = y;
+
+        // If we've output a block of scanlines in a row that don't violate our
+        // assumptions, then it's time to flush them...
+        if (BlockDim == ++fNextRun) {
+            this->flushRuns();
+        }
+    }
+    
+    // Blit a vertical run of pixels with a constant alpha value.
+    virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE {
+        // This function is currently not implemented. It is not explicitly
+        // required by the contract, but if at some time a code path runs into
+        // this function (which is entirely possible), it needs to be implemented.
+        //
+        // TODO (krajcevski):
+        // This function will be most easily implemented in one of two ways:
+        // 1. Buffer each vertical column value and then construct a list
+        //    of alpha values and output all of the blocks at once. This only
+        //    requires a write to the compressed buffer
+        // 2. Replace the indices of each block with the proper indices based
+        //    on the alpha value. This requires a read and write of the compressed
+        //    buffer, but much less overhead.
+        SkFAIL("Not implemented!");
+    }
+
+    // Blit a solid rectangle one or more pixels wide. It's assumed that blitRect
+    // is called as a way to bracket blitAntiH where above and below the path the
+    // called path just needs a solid rectangle to fill in the mask.
+#ifdef SK_DEBUG
+    bool fCalledOnceWithNonzeroY;
+#endif
+    virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE {
+
+        // Assumptions:
+        SkASSERT(0 == x);
+        SkASSERT(width <= fWidth);
+
+        // Make sure that we're only ever bracketing calls to blitAntiH.
+        SkASSERT((0 == y) || (!fCalledOnceWithNonzeroY && (fCalledOnceWithNonzeroY = true)));
+        
+#if !(PEDANTIC_BLIT_RECT)
+        for (int i = 0; i < height; ++i) {
+            const SkAlpha kFullAlpha = 0xFF;
+            this->blitAntiH(x, y+i, &kFullAlpha, &kLongestRun);
+        }
+#else
+        const int startBlockX = (x / BlockDim) * BlockDim;
+        const int startBlockY = (y / BlockDim) * BlockDim;
+
+        const int endBlockX = ((x + width) / BlockDim) * BlockDim;
+        const int endBlockY = ((y + height) / BlockDim) * BlockDim;
+
+        // If start and end are the same, then we only need to update a single block...
+        if (startBlockY == endBlockY && startBlockX == endBlockX) {
+            uint8_t mask[BlockDim*BlockDim];
+            memset(mask, 0, sizeof(mask));
+
+            const int xoff = x - startBlockX;
+            SkASSERT((xoff + width) <= BlockDim);
+
+            const int yoff = y - startBlockY;
+            SkASSERT((yoff + height) <= BlockDim);
+            
+            for (int j = 0; j < height; ++j) {
+                memset(mask + (j + yoff)*BlockDim + xoff, 0xFF, width);
+            }
+
+            uint8_t* dst = this->getBlock(startBlockX, startBlockY);
+            CompressorType::UpdateBlock(dst, mask, BlockDim, mask);
+
+        // If start and end are the same in the y dimension, then we can freely update an
+        // entire row of blocks...
+        } else if (startBlockY == endBlockY) {
+
+            this->updateBlockRow(x, y, width, height, startBlockY, startBlockX, endBlockX);
+
+        // Similarly, if the start and end are in the same column, then we can just update
+        // an entire column of blocks...
+        } else if (startBlockX == endBlockX) {
+
+            this->updateBlockCol(x, y, width, height, startBlockX, startBlockY, endBlockY);
+
+        // Otherwise, the rect spans a non-trivial region of blocks, and we have to construct
+        // a kind of 9-patch to update each of the pieces of the rect. The top and bottom
+        // rows are updated using updateBlockRow, and the left and right columns are updated
+        // using updateBlockColumn. Anything in the middle is simply memset to an opaque block
+        // encoding.
+        } else {
+
+            const int innerStartBlockX = startBlockX + BlockDim;
+            const int innerStartBlockY = startBlockY + BlockDim;
+
+            // Blit top row
+            const int topRowHeight = innerStartBlockY - y;
+            this->updateBlockRow(x, y, width, topRowHeight, startBlockY,
+                                 startBlockX, endBlockX);
+
+            // Advance y
+            y += topRowHeight;
+            height -= topRowHeight;
+
+            // Blit middle
+            if (endBlockY > innerStartBlockY) {
+
+                // Update left row
+                this->updateBlockCol(x, y, innerStartBlockX - x, endBlockY, startBlockY,
+                                     startBlockX, innerStartBlockX);
+
+                // Update the middle with an opaque encoding...
+                uint8_t mask[BlockDim*BlockDim];
+                memset(mask, 0xFF, sizeof(mask));
+
+                uint8_t opaqueEncoding[EncodedBlockSize];
+                CompressorType::CompressA8Horizontal(opaqueEncoding, mask, BlockDim);
+
+                for (int j = innerStartBlockY; j < endBlockY; j += BlockDim) {
+                    uint8_t* opaqueDst = this->getBlock(innerStartBlockX, j);
+                    for (int i = innerStartBlockX; i < endBlockX; i += BlockDim) {
+                        memcpy(opaqueDst, opaqueEncoding, EncodedBlockSize);
+                        opaqueDst += EncodedBlockSize;
+                    }
+                }
+
+                // If we need to update the right column, do that too
+                if (x + width > endBlockX) {
+                    this->updateBlockCol(endBlockX, y, x + width - endBlockX, endBlockY,
+                                         endBlockX, innerStartBlockY, endBlockY);
+                }
+
+                // Advance y
+                height = y + height - endBlockY;
+                y = endBlockY;
+            }
+
+            // If we need to update the last row, then do that, too.
+            if (height > 0) {
+                this->updateBlockRow(x, y, width, height, endBlockY,
+                                     startBlockX, endBlockX);
+            }
+        }
+#endif
+    }
+
+    // Blit a rectangle with one alpha-blended column on the left,
+    // width (zero or more) opaque pixels, and one alpha-blended column
+    // on the right. The result will always be at least two pixels wide.
+    virtual void blitAntiRect(int x, int y, int width, int height,
+                              SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE {
+        // This function is currently not implemented. It is not explicitly
+        // required by the contract, but if at some time a code path runs into
+        // this function (which is entirely possible), it needs to be implemented.
+        //
+        // TODO (krajcevski):
+        // This function will be most easily implemented as follows:
+        // 1. If width/height are smaller than a block, then update the
+        //    indices of the affected blocks.
+        // 2. If width/height are larger than a block, then construct a 9-patch
+        //    of block encodings that represent the rectangle, and write them
+        //    to the compressed buffer as necessary. Whether or not the blocks
+        //    are overwritten by zeros or just their indices are updated is up
+        //    to debate.
+        SkFAIL("Not implemented!");
+    }
+
+    // Blit a pattern of pixels defined by a rectangle-clipped mask; We make an
+    // assumption here that if this function gets called, then it will replace all
+    // of the compressed texture blocks that it touches. Hence, two separate calls
+    // to blitMask that have clips next to one another will cause artifacts. Most
+    // of the time, however, this function gets called because constructing the mask
+    // was faster than constructing the RLE for blitAntiH, and this function will
+    // only be called once.
+#ifdef SK_DEBUG
+    bool fBlitMaskCalled;
+#endif
+    virtual void blitMask(const SkMask& mask, const SkIRect& clip) SK_OVERRIDE {
+
+        // Assumptions:
+        SkASSERT(!fBlitMaskCalled && (fBlitMaskCalled = true));
+        SkASSERT(SkMask::kA8_Format == mask.fFormat);
+        SkASSERT(mask.fBounds.contains(clip));
+
+        // Start from largest block boundary less than the clip boundaries.
+        const int startI = BlockDim * (clip.left() / BlockDim);
+        const int startJ = BlockDim * (clip.top() / BlockDim);
+
+        for (int j = startJ; j < clip.bottom(); j += BlockDim) {
+
+            // Get the destination for this block row
+            uint8_t* dst = this->getBlock(startI, j);
+            for (int i = startI; i < clip.right(); i += BlockDim) {
+
+                // At this point, the block should intersect the clip.
+                SkASSERT(SkIRect::IntersectsNoEmptyCheck(
+                             SkIRect::MakeXYWH(i, j, BlockDim, BlockDim), clip));
+
+                // Do we need to pad it?
+                if (i < clip.left() || j < clip.top() ||
+                    i + BlockDim > clip.right() || j + BlockDim > clip.bottom()) {
+
+                    uint8_t block[BlockDim*BlockDim];
+                    memset(block, 0, sizeof(block));
+
+                    const int startX = SkMax32(i, clip.left());
+                    const int startY = SkMax32(j, clip.top());
+
+                    const int endX = SkMin32(i + BlockDim, clip.right());
+                    const int endY = SkMin32(j + BlockDim, clip.bottom());
+
+                    for (int y = startY; y < endY; ++y) {
+                        const int col = startX - i;
+                        const int row = y - j;
+                        const int valsWide = endX - startX;
+                        SkASSERT(valsWide <= BlockDim);
+                        SkASSERT(0 <= col && col < BlockDim);
+                        SkASSERT(0 <= row && row < BlockDim);
+                        memcpy(block + row*BlockDim + col,
+                               mask.getAddr8(startX, j + row), valsWide);
+                    }
+
+                    CompressorType::CompressA8Horizontal(dst, block, BlockDim);
+                } else {
+                    // Otherwise, just compress it.
+                    uint8_t*const src = mask.getAddr8(i, j);
+                    const uint32_t rb = mask.fRowBytes;
+                    CompressorType::CompressA8Horizontal(dst, src, rb);
+                }
+
+                dst += EncodedBlockSize;
+            }
+        }
+    }
+
+    // If the blitter just sets a single value for each pixel, return the
+    // bitmap it draws into, and assign value. If not, return NULL and ignore
+    // the value parameter.
+    virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE {
+        return NULL;
+    }
+
+    /**
+     * Compressed texture blitters only really work correctly if they get
+     * BlockDim rows at a time. That being said, this blitter tries it's best
+     * to preserve semantics if blitAntiH doesn't get called in too many
+     * weird ways...
+     */
+    virtual int requestRowsPreserved() const { return BlockDim; }
+
+private:
+    static const int kPixelsPerBlock = BlockDim * BlockDim;
+
+    // The longest possible run of pixels that this blitter will receive.
+    // This is initialized in the constructor to 0x7FFE, which is one less
+    // than the largest positive 16-bit integer. We make sure that it's one
+    // less for debugging purposes. We also don't make this variable static
+    // in order to make sure that we can construct a valid pointer to it.
+    const int16_t kLongestRun;
+
+    // Usually used in conjunction with kLongestRun. This is initialized to
+    // zero.
+    const SkAlpha kZeroAlpha;
+
+    // This is the information that we buffer whenever we're asked to blit
+    // a row with this blitter.
+    struct BufferedRun {
+        const SkAlpha* fAlphas;
+        const int16_t* fRuns;
+        int fX, fY;
+    } fBufferedRuns[BlockDim];
+
+    // The next row [0, BlockDim) that we need to blit.
+    int fNextRun;
+
+    // The width and height of the image that we're blitting
+    const int fWidth;
+    const int fHeight;
+
+    // The compressed buffer that we're blitting into. It is assumed that the buffer
+    // is large enough to store a compressed image of size fWidth*fHeight.
+    void* const fBuffer;
+
+    // Various utility functions
+    int blocksWide() const { return fWidth / BlockDim; }
+    int blocksTall() const { return fHeight / BlockDim; }
+    int totalBlocks() const { return (fWidth * fHeight) / kPixelsPerBlock; }
+
+    // Returns the block index for the block containing pixel (x, y). Block
+    // indices start at zero and proceed in raster order.
+    int getBlockOffset(int x, int y) const {
+        SkASSERT(x < fWidth);
+        SkASSERT(y < fHeight);
+        const int blockCol = x / BlockDim;
+        const int blockRow = y / BlockDim;
+        return blockRow * this->blocksWide() + blockCol;
+    }
+
+    // Returns a pointer to the block containing pixel (x, y)
+    uint8_t *getBlock(int x, int y) const {
+        uint8_t* ptr = reinterpret_cast<uint8_t*>(fBuffer);
+        return ptr + EncodedBlockSize*this->getBlockOffset(x, y);
+    }
+
+    // Updates the block whose columns are stored in block. curAlphai is expected
+    // to store the alpha values that will be placed within each of the columns in
+    // the range [col, col+colsLeft).
+    typedef uint32_t Column[BlockDim/4];
+    typedef uint32_t Block[BlockDim][BlockDim/4];
+    inline void updateBlockColumns(Block block, const int col,
+                                   const int colsLeft, const Column curAlphai) {
+        SkASSERT(block);
+        SkASSERT(col + colsLeft <= BlockDim);
+
+        for (int i = col; i < (col + colsLeft); ++i) {
+            memcpy(block[i], curAlphai, sizeof(Column));
+        }
+    }
+
+    // The following function writes the buffered runs to compressed blocks.
+    // If fNextRun < BlockDim, then we fill the runs that we haven't buffered with
+    // the constant zero buffer.
+    void flushRuns() {
+        // If we don't have any runs, then just return.
+        if (0 == fNextRun) {
+            return;
+        }
+
+#ifndef NDEBUG
+        // Make sure that if we have any runs, they all match
+        for (int i = 1; i < fNextRun; ++i) {
+            SkASSERT(fBufferedRuns[i].fY == fBufferedRuns[i-1].fY + 1);
+            SkASSERT(fBufferedRuns[i].fX == fBufferedRuns[i-1].fX);
+        }
+#endif
+
+        // If we don't have as many runs as we have rows, fill in the remaining
+        // runs with constant zeros.
+        for (int i = fNextRun; i < BlockDim; ++i) {
+            fBufferedRuns[i].fY = fBufferedRuns[0].fY + i;
+            fBufferedRuns[i].fX = fBufferedRuns[0].fX;
+            fBufferedRuns[i].fAlphas = &kZeroAlpha;
+            fBufferedRuns[i].fRuns = &kLongestRun;
+        }
+
+        // Make sure that our assumptions aren't violated.
+        SkASSERT(fNextRun > 0 && fNextRun <= BlockDim);
+        SkASSERT((fBufferedRuns[0].fY % BlockDim) == 0);
+
+        // The following logic walks BlockDim rows at a time and outputs compressed
+        // blocks to the buffer passed into the constructor.
+        // We do the following:
+        //
+        //      c1 c2 c3 c4
+        // -----------------------------------------------------------------------
+        // ... |  |  |  |  |  ----> fBufferedRuns[0]
+        // -----------------------------------------------------------------------
+        // ... |  |  |  |  |  ----> fBufferedRuns[1]
+        // -----------------------------------------------------------------------
+        // ... |  |  |  |  |  ----> fBufferedRuns[2]
+        // -----------------------------------------------------------------------
+        // ... |  |  |  |  |  ----> fBufferedRuns[3]
+        // -----------------------------------------------------------------------
+        // 
+        // curX -- the macro X value that we've gotten to.
+        // c[BlockDim] -- the buffers that represent the columns of the current block
+        //                  that we're operating on
+        // curAlphaColumn -- buffer containing the column of alpha values from fBufferedRuns.
+        // nextX -- for each run, the next point at which we need to update curAlphaColumn
+        //          after the value of curX.
+        // finalX -- the minimum of all the nextX values.
+        //
+        // curX advances to finalX outputting any blocks that it passes along
+        // the way. Since finalX will not change when we reach the end of a
+        // run, the termination criteria will be whenever curX == finalX at the
+        // end of a loop.
+
+        // Setup:
+        Block block;
+        sk_bzero(block, sizeof(block));
+
+        Column curAlphaColumn;
+        sk_bzero(curAlphaColumn, sizeof(curAlphaColumn));
+
+        SkAlpha *curAlpha = reinterpret_cast<SkAlpha*>(&curAlphaColumn);
+
+        int nextX[BlockDim];
+        for (int i = 0; i < BlockDim; ++i) {
+            nextX[i] = 0x7FFFFF;
+        }
+
+        uint8_t* outPtr = this->getBlock(fBufferedRuns[0].fX, fBufferedRuns[0].fY);
+
+        // Populate the first set of runs and figure out how far we need to
+        // advance on the first step
+        int curX = 0;
+        int finalX = 0xFFFFF;
+        for (int i = 0; i < BlockDim; ++i) {
+            nextX[i] = *(fBufferedRuns[i].fRuns);
+            curAlpha[i] = *(fBufferedRuns[i].fAlphas);
+
+            finalX = SkMin32(nextX[i], finalX);
+        }
+
+        // Make sure that we have a valid right-bound X value
+        SkASSERT(finalX < 0xFFFFF);
+
+        // If the finalX is the longest run, then just blit until we have
+        // width...
+        if (kLongestRun == finalX) {
+            finalX = fWidth;
+        }
+
+        // Run the blitter...
+        while (curX != finalX) {
+            SkASSERT(finalX >= curX);
+
+            // Do we need to populate the rest of the block?
+            if ((finalX - (BlockDim*(curX / BlockDim))) >= BlockDim) {
+                const int col = curX % BlockDim;
+                const int colsLeft = BlockDim - col;
+                SkASSERT(curX + colsLeft <= finalX);
+
+                this->updateBlockColumns(block, col, colsLeft, curAlphaColumn);
+
+                // Write this block
+                CompressorType::CompressA8Vertical(outPtr, reinterpret_cast<uint8_t*>(block));
+                outPtr += EncodedBlockSize;
+                curX += colsLeft;
+            }
+
+            // If we can advance even further, then just keep memsetting the block
+            if ((finalX - curX) >= BlockDim) {
+                SkASSERT((curX % BlockDim) == 0);
+
+                const int col = 0;
+                const int colsLeft = BlockDim;
+
+                this->updateBlockColumns(block, col, colsLeft, curAlphaColumn);
+
+                // While we can keep advancing, just keep writing the block.
+                uint8_t lastBlock[EncodedBlockSize];
+                CompressorType::CompressA8Vertical(lastBlock, reinterpret_cast<uint8_t*>(block));
+                while((finalX - curX) >= BlockDim) {
+                    memcpy(outPtr, lastBlock, EncodedBlockSize);
+                    outPtr += EncodedBlockSize;
+                    curX += BlockDim;
+                }
+            }
+
+            // If we haven't advanced within the block then do so.
+            if (curX < finalX) {
+                const int col = curX % BlockDim;
+                const int colsLeft = finalX - curX;
+
+                this->updateBlockColumns(block, col, colsLeft, curAlphaColumn);
+                curX += colsLeft;
+            }
+
+            SkASSERT(curX == finalX);
+
+            // Figure out what the next advancement is...
+            if (finalX < fWidth) {
+                for (int i = 0; i < BlockDim; ++i) {
+                    if (nextX[i] == finalX) {
+                        const int16_t run = *(fBufferedRuns[i].fRuns);
+                        fBufferedRuns[i].fRuns += run;
+                        fBufferedRuns[i].fAlphas += run;
+                        curAlpha[i] = *(fBufferedRuns[i].fAlphas);
+                        nextX[i] += *(fBufferedRuns[i].fRuns);
+                    }
+                }
+
+                finalX = 0xFFFFF;
+                for (int i = 0; i < BlockDim; ++i) {
+                    finalX = SkMin32(nextX[i], finalX);
+                }
+            } else {
+                curX = finalX;
+            }
+        }
+
+        // If we didn't land on a block boundary, output the block...
+        if ((curX % BlockDim) > 0) {
+#ifdef SK_DEBUG
+            for (int i = 0; i < BlockDim; ++i) {
+                SkASSERT(nextX[i] == kLongestRun || nextX[i] == curX);
+            }
+#endif
+            const int col = curX % BlockDim;
+            const int colsLeft = BlockDim - col;
+
+            memset(curAlphaColumn, 0, sizeof(curAlphaColumn));
+            this->updateBlockColumns(block, col, colsLeft, curAlphaColumn);
+
+            CompressorType::CompressA8Vertical(outPtr, reinterpret_cast<uint8_t*>(block));
+        }
+
+        fNextRun = 0;
+    }
+
+#if PEDANTIC_BLIT_RECT
+    void updateBlockRow(int x, int y, int width, int height,
+                        int blockRow, int startBlockX, int endBlockX) {
+        if (0 == width || 0 == height || startBlockX == endBlockX) {
+            return;
+        }
+
+        uint8_t* dst = this->getBlock(startBlockX, BlockDim * (y / BlockDim));
+
+        // One horizontal strip to update
+        uint8_t mask[BlockDim*BlockDim];
+        memset(mask, 0, sizeof(mask));
+
+        // Update the left cap
+        int blockX = startBlockX;
+        const int yoff = y - blockRow;
+        for (int j = 0; j < height; ++j) {
+            const int xoff = x - blockX;
+            memset(mask + (j + yoff)*BlockDim + xoff, 0xFF, BlockDim - xoff);
+        }
+        CompressorType::UpdateBlock(dst, mask, BlockDim, mask);
+        dst += EncodedBlockSize;
+        blockX += BlockDim;
+
+        // Update the middle
+        if (blockX < endBlockX) {
+            for (int j = 0; j < height; ++j) {
+                memset(mask + (j + yoff)*BlockDim, 0xFF, BlockDim);
+            }
+            while (blockX < endBlockX) {
+                CompressorType::UpdateBlock(dst, mask, BlockDim, mask);
+                dst += EncodedBlockSize;
+                blockX += BlockDim;
+            }
+        }
+
+        SkASSERT(endBlockX == blockX);
+
+        // Update the right cap (if we need to)
+        if (x + width > endBlockX) {
+            memset(mask, 0, sizeof(mask));
+            for (int j = 0; j < height; ++j) {
+                const int xoff = (x+width-blockX);
+                memset(mask + (j+yoff)*BlockDim, 0xFF, xoff);
+            }
+            CompressorType::UpdateBlock(dst, mask, BlockDim, mask);
+        }
+    }
+
+    void updateBlockCol(int x, int y, int width, int height,
+                        int blockCol, int startBlockY, int endBlockY) {
+        if (0 == width || 0 == height || startBlockY == endBlockY) {
+            return;
+        }
+
+        // One vertical strip to update
+        uint8_t mask[BlockDim*BlockDim];
+        memset(mask, 0, sizeof(mask));
+        const int maskX0 = x - blockCol;
+        const int maskWidth = maskX0 + width;
+        SkASSERT(maskWidth <= BlockDim);
+
+        // Update the top cap
+        int blockY = startBlockY;
+        for (int j = (y - blockY); j < BlockDim; ++j) {
+            memset(mask + maskX0 + j*BlockDim, 0xFF, maskWidth);
+        }
+        CompressorType::UpdateBlock(this->getBlock(blockCol, blockY), mask, BlockDim, mask);
+        blockY += BlockDim;
+
+        // Update middle
+        if (blockY < endBlockY) {
+            for (int j = 0; j < BlockDim; ++j) {
+                memset(mask + maskX0 + j*BlockDim, 0xFF, maskWidth);
+            }
+            while (blockY < endBlockY) {
+                CompressorType::UpdateBlock(this->getBlock(blockCol, blockY),
+                                            mask, BlockDim, mask);
+                blockY += BlockDim;
+            }
+        }
+
+        SkASSERT(endBlockY == blockY);
+
+        // Update bottom
+        if (y + height > endBlockY) {
+            for (int j = y+height; j < endBlockY + BlockDim; ++j) {
+                memset(mask + (j-endBlockY)*BlockDim, 0, BlockDim);
+            }
+            CompressorType::UpdateBlock(this->getBlock(blockCol, blockY),
+                                        mask, BlockDim, mask);
+        }
+    }
+#endif  // PEDANTIC_BLIT_RECT
+
+};
+
+}  // namespace SkTextureCompressor
+
+#endif  // SkTextureCompressor_Blitter_DEFINED
diff --git a/src/utils/SkTextureCompressor_LATC.cpp b/src/utils/SkTextureCompressor_LATC.cpp
new file mode 100644
index 0000000..1e5e142
--- /dev/null
+++ b/src/utils/SkTextureCompressor_LATC.cpp
@@ -0,0 +1,518 @@
+/*
+ * 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 "SkTextureCompressor_LATC.h"
+#include "SkTextureCompressor_Blitter.h"
+
+#include "SkBlitter.h"
+#include "SkEndian.h"
+
+// Compression options. In general, the slow version is much more accurate, but
+// much slower. The fast option is much faster, but much less accurate. YMMV.
+#define COMPRESS_LATC_SLOW 0
+#define COMPRESS_LATC_FAST 1
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Generates an LATC palette. LATC constructs
+// a palette of eight colors from LUM0 and LUM1 using the algorithm:
+//
+// LUM0,              if lum0 > lum1 and code(x,y) == 0
+// LUM1,              if lum0 > lum1 and code(x,y) == 1
+// (6*LUM0+  LUM1)/7, if lum0 > lum1 and code(x,y) == 2
+// (5*LUM0+2*LUM1)/7, if lum0 > lum1 and code(x,y) == 3
+// (4*LUM0+3*LUM1)/7, if lum0 > lum1 and code(x,y) == 4
+// (3*LUM0+4*LUM1)/7, if lum0 > lum1 and code(x,y) == 5
+// (2*LUM0+5*LUM1)/7, if lum0 > lum1 and code(x,y) == 6
+// (  LUM0+6*LUM1)/7, if lum0 > lum1 and code(x,y) == 7
+//
+// LUM0,              if lum0 <= lum1 and code(x,y) == 0
+// LUM1,              if lum0 <= lum1 and code(x,y) == 1
+// (4*LUM0+  LUM1)/5, if lum0 <= lum1 and code(x,y) == 2
+// (3*LUM0+2*LUM1)/5, if lum0 <= lum1 and code(x,y) == 3
+// (2*LUM0+3*LUM1)/5, if lum0 <= lum1 and code(x,y) == 4
+// (  LUM0+4*LUM1)/5, if lum0 <= lum1 and code(x,y) == 5
+// 0,                 if lum0 <= lum1 and code(x,y) == 6
+// 255,               if lum0 <= lum1 and code(x,y) == 7
+
+static const int kLATCPaletteSize = 8;
+static void generate_latc_palette(uint8_t palette[], uint8_t lum0, uint8_t lum1) {
+    palette[0] = lum0;
+    palette[1] = lum1;
+    if (lum0 > lum1) {
+        for (int i = 1; i < 7; i++) {
+            palette[i+1] = ((7-i)*lum0 + i*lum1) / 7;
+        }
+    } else {
+        for (int i = 1; i < 5; i++) {
+            palette[i+1] = ((5-i)*lum0 + i*lum1) / 5;
+        }
+        palette[6] = 0;
+        palette[7] = 255;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#if COMPRESS_LATC_SLOW
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Utility Functions
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// Absolute difference between two values. More correct than SkTAbs(a - b)
+// because it works on unsigned values.
+template <typename T> inline T abs_diff(const T &a, const T &b) {
+    return (a > b) ? (a - b) : (b - a);
+}
+
+static bool is_extremal(uint8_t pixel) {
+    return 0 == pixel || 255 == pixel;
+}
+
+typedef uint64_t (*A84x4To64BitProc)(const uint8_t block[]);
+
+// This function is used by both R11 EAC and LATC to compress 4x4 blocks
+// of 8-bit alpha into 64-bit values that comprise the compressed data.
+// For both formats, we need to make sure that the dimensions of the 
+// src pixels are divisible by 4, and copy 4x4 blocks one at a time
+// for compression.
+static bool compress_4x4_a8_to_64bit(uint8_t* dst, const uint8_t* src,
+                                     int width, int height, int rowBytes,
+                                     A84x4To64BitProc proc) {
+    // Make sure that our data is well-formed enough to be considered for compression
+    if (0 == width || 0 == height || (width % 4) != 0 || (height % 4) != 0) {
+        return false;
+    }
+
+    int blocksX = width >> 2;
+    int blocksY = height >> 2;
+
+    uint8_t block[16];
+    uint64_t* encPtr = reinterpret_cast<uint64_t*>(dst);
+    for (int y = 0; y < blocksY; ++y) {
+        for (int x = 0; x < blocksX; ++x) {
+            // Load block
+            for (int k = 0; k < 4; ++k) {
+                memcpy(block + k*4, src + k*rowBytes + 4*x, 4);
+            }
+
+            // Compress it
+            *encPtr = proc(block);
+            ++encPtr;
+        }
+        src += 4 * rowBytes;
+    }
+
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// LATC compressor
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// LATC compressed texels down into square 4x4 blocks
+static const int kLATCBlockSize = 4;
+static const int kLATCPixelsPerBlock = kLATCBlockSize * kLATCBlockSize;
+
+// Compress a block by using the bounding box of the pixels. It is assumed that
+// there are no extremal pixels in this block otherwise we would have used
+// compressBlockBBIgnoreExtremal.
+static uint64_t compress_latc_block_bb(const uint8_t pixels[]) {
+    uint8_t minVal = 255;
+    uint8_t maxVal = 0;
+    for (int i = 0; i < kLATCPixelsPerBlock; ++i) {
+        minVal = SkTMin(pixels[i], minVal);
+        maxVal = SkTMax(pixels[i], maxVal);
+    }
+
+    SkASSERT(!is_extremal(minVal));
+    SkASSERT(!is_extremal(maxVal));
+
+    uint8_t palette[kLATCPaletteSize];
+    generate_latc_palette(palette, maxVal, minVal);
+
+    uint64_t indices = 0;
+    for (int i = kLATCPixelsPerBlock - 1; i >= 0; --i) {
+
+        // Find the best palette index
+        uint8_t bestError = abs_diff(pixels[i], palette[0]);
+        uint8_t idx = 0;
+        for (int j = 1; j < kLATCPaletteSize; ++j) {
+            uint8_t error = abs_diff(pixels[i], palette[j]);
+            if (error < bestError) {
+                bestError = error;
+                idx = j;
+            }
+        }
+
+        indices <<= 3;
+        indices |= idx;
+    }
+
+    return
+        SkEndian_SwapLE64(
+            static_cast<uint64_t>(maxVal) |
+            (static_cast<uint64_t>(minVal) << 8) |
+            (indices << 16));
+}
+
+// Compress a block by using the bounding box of the pixels without taking into
+// account the extremal values. The generated palette will contain extremal values
+// and fewer points along the line segment to interpolate.
+static uint64_t compress_latc_block_bb_ignore_extremal(const uint8_t pixels[]) {
+    uint8_t minVal = 255;
+    uint8_t maxVal = 0;
+    for (int i = 0; i < kLATCPixelsPerBlock; ++i) {
+        if (is_extremal(pixels[i])) {
+            continue;
+        }
+
+        minVal = SkTMin(pixels[i], minVal);
+        maxVal = SkTMax(pixels[i], maxVal);
+    }
+
+    SkASSERT(!is_extremal(minVal));
+    SkASSERT(!is_extremal(maxVal));
+
+    uint8_t palette[kLATCPaletteSize];
+    generate_latc_palette(palette, minVal, maxVal);
+
+    uint64_t indices = 0;
+    for (int i = kLATCPixelsPerBlock - 1; i >= 0; --i) {
+
+        // Find the best palette index
+        uint8_t idx = 0;
+        if (is_extremal(pixels[i])) {
+            if (0xFF == pixels[i]) {
+                idx = 7;
+            } else if (0 == pixels[i]) {
+                idx = 6;
+            } else {
+                SkFAIL("Pixel is extremal but not really?!");
+            }
+        } else {
+            uint8_t bestError = abs_diff(pixels[i], palette[0]);
+            for (int j = 1; j < kLATCPaletteSize - 2; ++j) {
+                uint8_t error = abs_diff(pixels[i], palette[j]);
+                if (error < bestError) {
+                    bestError = error;
+                    idx = j;
+                }
+            }
+        }
+
+        indices <<= 3;
+        indices |= idx;
+    }
+
+    return
+        SkEndian_SwapLE64(
+            static_cast<uint64_t>(minVal) |
+            (static_cast<uint64_t>(maxVal) << 8) |
+            (indices << 16));
+}
+
+
+// Compress LATC block. Each 4x4 block of pixels is decompressed by LATC from two
+// values LUM0 and LUM1, and an index into the generated palette. Details of how
+// the palette is generated can be found in the comments of generatePalette above.
+//
+// We choose which palette type to use based on whether or not 'pixels' contains
+// any extremal values (0 or 255). If there are extremal values, then we use the
+// palette that has the extremal values built in. Otherwise, we use the full bounding
+// box.
+
+static uint64_t compress_latc_block(const uint8_t pixels[]) {
+    // Collect unique pixels
+    int nUniquePixels = 0;
+    uint8_t uniquePixels[kLATCPixelsPerBlock];
+    for (int i = 0; i < kLATCPixelsPerBlock; ++i) {
+        bool foundPixel = false;
+        for (int j = 0; j < nUniquePixels; ++j) {
+            foundPixel = foundPixel || uniquePixels[j] == pixels[i];
+        }
+
+        if (!foundPixel) {
+            uniquePixels[nUniquePixels] = pixels[i];
+            ++nUniquePixels;
+        }
+    }
+
+    // If there's only one unique pixel, then our compression is easy.
+    if (1 == nUniquePixels) {
+        return SkEndian_SwapLE64(pixels[0] | (pixels[0] << 8));
+
+    // Similarly, if there are only two unique pixels, then our compression is
+    // easy again: place the pixels in the block header, and assign the indices
+    // with one or zero depending on which pixel they belong to.
+    } else if (2 == nUniquePixels) {
+        uint64_t outBlock = 0;
+        for (int i = kLATCPixelsPerBlock - 1; i >= 0; --i) {
+            int idx = 0;
+            if (pixels[i] == uniquePixels[1]) {
+                idx = 1;
+            }
+
+            outBlock <<= 3;
+            outBlock |= idx;
+        }
+        outBlock <<= 16;
+        outBlock |= (uniquePixels[0] | (uniquePixels[1] << 8));
+        return SkEndian_SwapLE64(outBlock);
+    }
+
+    // Count non-maximal pixel values
+    int nonExtremalPixels = 0;
+    for (int i = 0; i < nUniquePixels; ++i) {
+        if (!is_extremal(uniquePixels[i])) {
+            ++nonExtremalPixels;
+        }
+    }
+
+    // If all the pixels are nonmaximal then compute the palette using
+    // the bounding box of all the pixels.
+    if (nonExtremalPixels == nUniquePixels) {
+        // This is really just for correctness, in all of my tests we
+        // never take this step. We don't lose too much perf here because
+        // most of the processing in this function is worth it for the 
+        // 1 == nUniquePixels optimization.
+        return compress_latc_block_bb(pixels);
+    } else {
+        return compress_latc_block_bb_ignore_extremal(pixels);
+    }
+}
+
+#endif  // COMPRESS_LATC_SLOW
+
+////////////////////////////////////////////////////////////////////////////////
+
+#if COMPRESS_LATC_FAST
+
+// Take the top three bits of each index and pack them into the low 12
+// bits of the integer.
+static inline uint32_t pack_index(uint32_t x) {
+    // Pack it in...
+#if defined (SK_CPU_BENDIAN)
+    return
+        (x >> 24) |
+        ((x >> 13) & 0x38) |
+        ((x >> 2) & 0x1C0) |
+        ((x << 9) & 0xE00);
+#else
+    return
+        (x & 0x7) |
+        ((x >> 5) & 0x38) |
+        ((x >> 10) & 0x1C0) |
+        ((x >> 15) & 0xE00);
+#endif
+}
+
+// Converts each 8-bit byte in the integer into an LATC index, and then packs
+// the indices into the low 12 bits of the integer.
+static inline uint32_t convert_index(uint32_t x) {
+    // Since the palette is 
+    // 255, 0, 219, 182, 146, 109, 73, 36
+    // we need to map the high three bits of each byte in the integer
+    // from
+    // 0 1 2 3 4 5 6 7
+    // to
+    // 1 7 6 5 4 3 2 0
+    //
+    // This first operation takes the mapping from
+    // 0 1 2 3 4 5 6 7  -->  7 6 5 4 3 2 1 0
+    x = 0x07070707 - ((x >> 5) & 0x07070707);
+
+    // mask is 1 if index is non-zero
+    const uint32_t mask = (x | (x >> 1) | (x >> 2)) & 0x01010101;
+
+    // add mask:
+    // 7 6 5 4 3 2 1 0 --> 8 7 6 5 4 3 2 0
+    x = (x + mask);
+
+    // Handle overflow:
+    // 8 7 6 5 4 3 2 0 --> 9 7 6 5 4 3 2 0
+    x |= (x >> 3) & 0x01010101;
+
+    // Mask out high bits:
+    // 9 7 6 5 4 3 2 0 --> 1 7 6 5 4 3 2 0
+    x &= 0x07070707;
+    
+    return pack_index(x);
+}
+
+typedef uint64_t (*PackIndicesProc)(const uint8_t* alpha, int rowBytes);
+template<PackIndicesProc packIndicesProc>
+static void compress_a8_latc_block(uint8_t** dstPtr, const uint8_t* src, int rowBytes) {
+    *(reinterpret_cast<uint64_t*>(*dstPtr)) =
+        SkEndian_SwapLE64(0xFF | (packIndicesProc(src, rowBytes) << 16));
+    *dstPtr += 8;
+}
+
+inline uint64_t PackRowMajor(const uint8_t *indices, int rowBytes) {
+    uint64_t result = 0;
+    for (int i = 0; i < 4; ++i) {
+        const uint32_t idx = *(reinterpret_cast<const uint32_t*>(indices + i*rowBytes));
+        result |= static_cast<uint64_t>(convert_index(idx)) << 12*i;
+    }
+    return result;
+}
+
+inline uint64_t PackColumnMajor(const uint8_t *indices, int rowBytes) {
+    // !SPEED! Blarg, this is kind of annoying. SSE4 can make this
+    // a LOT faster.
+    uint8_t transposed[16];
+    for (int i = 0; i < 4; ++i) {
+        for (int j = 0; j < 4; ++j) {
+            transposed[j*4+i] = indices[i*rowBytes + j];
+        }
+    }
+
+    return PackRowMajor(transposed, 4);
+}
+
+static bool compress_4x4_a8_latc(uint8_t* dst, const uint8_t* src,
+                                 int width, int height, int rowBytes) {
+
+    if (width < 0 || ((width % 4) != 0) || height < 0 || ((height % 4) != 0)) {
+        return false;
+    }
+
+    uint8_t** dstPtr = &dst;
+    for (int y = 0; y < height; y += 4) {
+        for (int x = 0; x < width; x += 4) {
+            compress_a8_latc_block<PackRowMajor>(dstPtr, src + y*rowBytes + x, rowBytes);
+        }
+    }
+
+    return true;
+}
+
+void CompressA8LATCBlockVertical(uint8_t* dst, const uint8_t block[]) {
+    compress_a8_latc_block<PackColumnMajor>(&dst, block, 4);
+}
+
+#endif  // COMPRESS_LATC_FAST
+
+void decompress_latc_block(uint8_t* dst, int dstRowBytes, const uint8_t* src) {
+    uint64_t block = SkEndian_SwapLE64(*(reinterpret_cast<const uint64_t *>(src)));
+    uint8_t lum0 = block & 0xFF;
+    uint8_t lum1 = (block >> 8) & 0xFF;
+
+    uint8_t palette[kLATCPaletteSize];
+    generate_latc_palette(palette, lum0, lum1);
+
+    block >>= 16;
+    for (int j = 0; j < 4; ++j) {
+        for (int i = 0; i < 4; ++i) {
+            dst[i] = palette[block & 0x7];
+            block >>= 3;
+        }
+        dst += dstRowBytes;
+    }
+}
+
+// This is the type passed as the CompressorType argument of the compressed
+// blitter for the LATC format. The static functions required to be in this
+// struct are documented in SkTextureCompressor_Blitter.h
+struct CompressorLATC {
+    static inline void CompressA8Vertical(uint8_t* dst, const uint8_t block[]) {
+        compress_a8_latc_block<PackColumnMajor>(&dst, block, 4);
+    }
+
+    static inline void CompressA8Horizontal(uint8_t* dst, const uint8_t* src,
+                                            int srcRowBytes) {
+        compress_a8_latc_block<PackRowMajor>(&dst, src, srcRowBytes);
+    }
+
+#if PEDANTIC_BLIT_RECT
+    static inline void UpdateBlock(uint8_t* dst, const uint8_t* src, int srcRowBytes,
+                                   const uint8_t* mask) {
+        // Pack the mask
+        uint64_t cmpMask = 0;
+        for (int i = 0; i < 4; ++i) {
+            const uint32_t idx = *(reinterpret_cast<const uint32_t*>(src + i*srcRowBytes));
+            cmpMask |= static_cast<uint64_t>(pack_index(idx)) << 12*i;
+        }
+        cmpMask = SkEndian_SwapLE64(cmpMask << 16); // avoid header
+
+        uint64_t cmpSrc;
+        uint8_t *cmpSrcPtr = reinterpret_cast<uint8_t*>(&cmpSrc);
+        compress_a8_latc_block<PackRowMajor>(&cmpSrcPtr, src, srcRowBytes);
+
+        // Mask out header
+        cmpSrc = cmpSrc & cmpMask;
+
+        // Read destination encoding
+        uint64_t *cmpDst = reinterpret_cast<uint64_t*>(dst);
+
+        // If the destination is the encoding for a blank block, then we need
+        // to properly set the header
+        if (0 == cmpDst) {
+            *cmpDst = SkTEndian_SwapLE64(0x24924924924900FFULL);
+        }
+
+        // Set the new indices
+        *cmpDst &= ~cmpMask;
+        *cmpDst |= cmpSrc;
+    }
+#endif  // PEDANTIC_BLIT_RECT
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace SkTextureCompressor {
+
+bool CompressA8ToLATC(uint8_t* dst, const uint8_t* src, int width, int height, int rowBytes) {
+#if COMPRESS_LATC_FAST
+    return compress_4x4_a8_latc(dst, src, width, height, rowBytes);
+#elif COMPRESS_LATC_SLOW
+    return compress_4x4_a8_to_64bit(dst, src, width, height, rowBytes, compress_latc_block);
+#else
+#error "Must choose either fast or slow LATC compression"
+#endif
+}
+
+SkBlitter* CreateLATCBlitter(int width, int height, void* outputBuffer,
+                             SkTBlitterAllocator* allocator) {
+    if ((width % 4) != 0 || (height % 4) != 0) {
+        return NULL;
+    }
+
+#if COMPRESS_LATC_FAST
+    // Memset the output buffer to an encoding that decodes to zero. We must do this
+    // in order to avoid having uninitialized values in the buffer if the blitter
+    // decides not to write certain scanlines (and skip entire rows of blocks).
+    // In the case of LATC, if everything is zero, then LUM0 and LUM1 are also zero,
+    // and they will only be non-zero (0xFF) if the index is 7. So bzero will do just fine.
+    // (8 bytes per block) * (w * h / 16 blocks) = w * h / 2
+    sk_bzero(outputBuffer, width * height / 2);
+
+    return allocator->createT<
+        SkTCompressedAlphaBlitter<4, 8, CompressorLATC>, int, int, void* >
+        (width, height, outputBuffer);
+#elif COMPRESS_LATC_SLOW
+    // TODO (krajcevski)
+    return NULL;
+#endif
+}
+
+void DecompressLATC(uint8_t* dst, int dstRowBytes, const uint8_t* src, int width, int height) {
+    for (int j = 0; j < height; j += 4) {
+        for (int i = 0; i < width; i += 4) {
+            decompress_latc_block(dst + i, dstRowBytes, src);
+            src += 8;
+        }
+        dst += 4 * dstRowBytes;
+    }
+}
+
+}  // SkTextureCompressor
diff --git a/src/utils/SkTextureCompressor_LATC.h b/src/utils/SkTextureCompressor_LATC.h
new file mode 100644
index 0000000..e41a249
--- /dev/null
+++ b/src/utils/SkTextureCompressor_LATC.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTextureCompressor_LATC_DEFINED
+#define SkTextureCompressor_LATC_DEFINED
+
+#include "SkBitmapProcShader.h"
+
+class SkBlitter;
+
+namespace SkTextureCompressor {
+
+    bool CompressA8ToLATC(uint8_t* dst, const uint8_t* src,
+                          int width, int height, int rowBytes);
+
+    SkBlitter* CreateLATCBlitter(int width, int height, void* outputBuffer,
+                                 SkTBlitterAllocator *allocator);
+
+    void DecompressLATC(uint8_t* dst, int dstRowBytes, const uint8_t* src, int width, int height);
+}
+
+#endif  // SkTextureCompressor_LATC_DEFINED
diff --git a/src/utils/SkTextureCompressor_R11EAC.cpp b/src/utils/SkTextureCompressor_R11EAC.cpp
new file mode 100644
index 0000000..9996eb9
--- /dev/null
+++ b/src/utils/SkTextureCompressor_R11EAC.cpp
@@ -0,0 +1,669 @@
+/*
+ * 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 "SkTextureCompressor.h"
+#include "SkTextureCompressor_Blitter.h"
+
+#include "SkBlitter.h"
+#include "SkEndian.h"
+
+// #define COMPRESS_R11_EAC_SLOW 1
+// #define COMPRESS_R11_EAC_FAST 1
+#define COMPRESS_R11_EAC_FASTEST 1
+
+// Blocks compressed into R11 EAC are represented as follows:
+// 0000000000000000000000000000000000000000000000000000000000000000
+// |base_cw|mod|mul|  ----------------- indices -------------------
+//
+// To reconstruct the value of a given pixel, we use the formula:
+// clamp[0, 2047](base_cw * 8 + 4 + mod_val*mul*8)
+//
+// mod_val is chosen from a palette of values based on the index of the
+// given pixel. The palette is chosen by the value stored in mod.
+// This formula returns a value between 0 and 2047, which is converted
+// to a float from 0 to 1 in OpenGL.
+//
+// If mul is zero, then we set mul = 1/8, so that the formula becomes
+// clamp[0, 2047](base_cw * 8 + 4 + mod_val)
+
+static const int kNumR11EACPalettes = 16;
+static const int kR11EACPaletteSize = 8;
+static const int kR11EACModifierPalettes[kNumR11EACPalettes][kR11EACPaletteSize] = {
+    {-3, -6, -9, -15, 2, 5, 8, 14},
+    {-3, -7, -10, -13, 2, 6, 9, 12},
+    {-2, -5, -8, -13, 1, 4, 7, 12},
+    {-2, -4, -6, -13, 1, 3, 5, 12},
+    {-3, -6, -8, -12, 2, 5, 7, 11},
+    {-3, -7, -9, -11, 2, 6, 8, 10},
+    {-4, -7, -8, -11, 3, 6, 7, 10},
+    {-3, -5, -8, -11, 2, 4, 7, 10},
+    {-2, -6, -8, -10, 1, 5, 7, 9},
+    {-2, -5, -8, -10, 1, 4, 7, 9},
+    {-2, -4, -8, -10, 1, 3, 7, 9},
+    {-2, -5, -7, -10, 1, 4, 6, 9},
+    {-3, -4, -7, -10, 2, 3, 6, 9},
+    {-1, -2, -3, -10, 0, 1, 2, 9},
+    {-4, -6, -8, -9, 3, 5, 7, 8},
+    {-3, -5, -7, -9, 2, 4, 6, 8}
+};
+
+#if COMPRESS_R11_EAC_SLOW
+
+// Pack the base codeword, palette, and multiplier into the 64 bits necessary
+// to decode it.
+static uint64_t pack_r11eac_block(uint16_t base_cw, uint16_t palette, uint16_t multiplier,
+                                  uint64_t indices) {
+    SkASSERT(palette < 16);
+    SkASSERT(multiplier < 16);
+    SkASSERT(indices < (static_cast<uint64_t>(1) << 48));
+
+    const uint64_t b = static_cast<uint64_t>(base_cw) << 56;
+    const uint64_t m = static_cast<uint64_t>(multiplier) << 52;
+    const uint64_t p = static_cast<uint64_t>(palette) << 48;
+    return SkEndian_SwapBE64(b | m | p | indices);
+}
+
+// Given a base codeword, a modifier, and a multiplier, compute the proper
+// pixel value in the range [0, 2047].
+static uint16_t compute_r11eac_pixel(int base_cw, int modifier, int multiplier) {
+    int ret = (base_cw * 8 + 4) + (modifier * multiplier * 8);
+    return (ret > 2047)? 2047 : ((ret < 0)? 0 : ret);
+}
+
+// Compress a block into R11 EAC format.
+// The compression works as follows:
+// 1. Find the center of the span of the block's values. Use this as the base codeword.
+// 2. Choose a multiplier based roughly on the size of the span of block values
+// 3. Iterate through each palette and choose the one with the most accurate
+// modifiers.
+static inline uint64_t compress_heterogeneous_r11eac_block(const uint8_t block[16]) {
+    // Find the center of the data...
+    uint16_t bmin = block[0];
+    uint16_t bmax = block[0];
+    for (int i = 1; i < 16; ++i) {
+        bmin = SkTMin<uint16_t>(bmin, block[i]);
+        bmax = SkTMax<uint16_t>(bmax, block[i]);
+    }
+
+    uint16_t center = (bmax + bmin) >> 1;
+    SkASSERT(center <= 255);
+
+    // Based on the min and max, we can guesstimate a proper multiplier
+    // This is kind of a magic choice to start with.
+    uint16_t multiplier = (bmax - center) / 10;
+
+    // Now convert the block to 11 bits and transpose it to match
+    // the proper layout
+    uint16_t cblock[16];
+    for (int i = 0; i < 4; ++i) {
+        for (int j = 0; j < 4; ++j) {
+            int srcIdx = i*4+j;
+            int dstIdx = j*4+i;
+            cblock[dstIdx] = (block[srcIdx] << 3) | (block[srcIdx] >> 5);
+        }
+    }
+
+    // Finally, choose the proper palette and indices
+    uint32_t bestError = 0xFFFFFFFF;
+    uint64_t bestIndices = 0;
+    uint16_t bestPalette = 0;
+    for (uint16_t paletteIdx = 0; paletteIdx < kNumR11EACPalettes; ++paletteIdx) {
+        const int *palette = kR11EACModifierPalettes[paletteIdx];
+
+        // Iterate through each pixel to find the best palette index
+        // and update the indices with the choice. Also store the error
+        // for this palette to be compared against the best error...
+        uint32_t error = 0;
+        uint64_t indices = 0;
+        for (int pixelIdx = 0; pixelIdx < 16; ++pixelIdx) {
+            const uint16_t pixel = cblock[pixelIdx];
+
+            // Iterate through each palette value to find the best index
+            // for this particular pixel for this particular palette.
+            uint16_t bestPixelError =
+                abs_diff(pixel, compute_r11eac_pixel(center, palette[0], multiplier));
+            int bestIndex = 0;
+            for (int i = 1; i < kR11EACPaletteSize; ++i) {
+                const uint16_t p = compute_r11eac_pixel(center, palette[i], multiplier);
+                const uint16_t perror = abs_diff(pixel, p);
+
+                // Is this index better?
+                if (perror < bestPixelError) {
+                    bestIndex = i;
+                    bestPixelError = perror;
+                }
+            }
+
+            SkASSERT(bestIndex < 8);
+
+            error += bestPixelError;
+            indices <<= 3;
+            indices |= bestIndex;
+        }
+
+        SkASSERT(indices < (static_cast<uint64_t>(1) << 48));
+
+        // Is this palette better?
+        if (error < bestError) {
+            bestPalette = paletteIdx;
+            bestIndices = indices;
+            bestError = error;
+        }
+    }
+
+    // Finally, pack everything together...
+    return pack_r11eac_block(center, bestPalette, multiplier, bestIndices);
+}
+#endif // COMPRESS_R11_EAC_SLOW
+
+#if COMPRESS_R11_EAC_FAST
+// This function takes into account that most blocks that we compress have a gradation from
+// fully opaque to fully transparent. The compression scheme works by selecting the
+// palette and multiplier that has the tightest fit to the 0-255 range. This is encoded
+// as the block header (0x8490). The indices are then selected by considering the top
+// three bits of each alpha value. For alpha masks, this reduces the dynamic range from
+// 17 to 8, but the quality is still acceptable.
+//
+// There are a few caveats that need to be taken care of...
+//
+// 1. The block is read in as scanlines, so the indices are stored as:
+//     0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+//    However, the decomrpession routine reads them in column-major order, so they
+//    need to be packed as:
+//     0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15
+//    So when reading, they must be transposed.
+//
+// 2. We cannot use the top three bits as an index directly, since the R11 EAC palettes
+//    above store the modulation values first decreasing and then increasing:
+//      e.g. {-3, -6, -9, -15, 2, 5, 8, 14}
+//    Hence, we need to convert the indices with the following mapping:
+//      From: 0 1 2 3 4 5 6 7
+//      To:   3 2 1 0 4 5 6 7
+static inline uint64_t compress_heterogeneous_r11eac_block(const uint8_t block[16]) {
+    uint64_t retVal = static_cast<uint64_t>(0x8490) << 48;
+    for(int i = 0; i < 4; ++i) {
+        for(int j = 0; j < 4; ++j) {
+            const int shift = 45-3*(j*4+i);
+            SkASSERT(shift <= 45);
+            const uint64_t idx = block[i*4+j] >> 5;
+            SkASSERT(idx < 8);
+
+            // !SPEED! This is slightly faster than having an if-statement.
+            switch(idx) {
+                case 0:
+                case 1:
+                case 2:
+                case 3:
+                    retVal |= (3-idx) << shift;
+                    break;
+                default:
+                    retVal |= idx << shift;
+                    break;
+            }
+        }
+    }
+
+    return SkEndian_SwapBE64(retVal);
+}
+#endif // COMPRESS_R11_EAC_FAST
+
+#if (COMPRESS_R11_EAC_SLOW) || (COMPRESS_R11_EAC_FAST)
+static uint64_t compress_r11eac_block(const uint8_t block[16]) {
+    // Are all blocks a solid color?
+    bool solid = true;
+    for (int i = 1; i < 16; ++i) {
+        if (block[i] != block[0]) {
+            solid = false;
+            break;
+        }
+    }
+
+    if (solid) {
+        switch(block[0]) {
+            // Fully transparent? We know the encoding...
+            case 0:
+                // (0x0020 << 48) produces the following:
+                // basw_cw: 0
+                // mod: 0, palette: {-3, -6, -9, -15, 2, 5, 8, 14}
+                // multiplier: 2
+                // mod_val: -3
+                //
+                // this gives the following formula:
+                // clamp[0, 2047](0*8+4+(-3)*2*8) = 0
+                // 
+                // Furthermore, it is impervious to endianness:
+                // 0x0020000000002000ULL
+                // Will produce one pixel with index 2, which gives:
+                // clamp[0, 2047](0*8+4+(-9)*2*8) = 0
+                return 0x0020000000002000ULL;
+
+            // Fully opaque? We know this encoding too...
+            case 255:
+            
+                // -1 produces the following:
+                // basw_cw: 255
+                // mod: 15, palette: {-3, -5, -7, -9, 2, 4, 6, 8}
+                // mod_val: 8
+                //
+                // this gives the following formula:
+                // clamp[0, 2047](255*8+4+8*8*8) = clamp[0, 2047](2556) = 2047
+                return 0xFFFFFFFFFFFFFFFFULL;
+
+            default:
+                // !TODO! krajcevski:
+                // This will probably never happen, since we're using this format
+                // primarily for compressing alpha maps. Usually the only
+                // non-fullly opaque or fully transparent blocks are not a solid
+                // intermediate color. If we notice that they are, then we can
+                // add another optimization...
+                break;
+        }
+    }
+
+    return compress_heterogeneous_r11eac_block(block);
+}
+
+// This function is used by R11 EAC to compress 4x4 blocks
+// of 8-bit alpha into 64-bit values that comprise the compressed data.
+// We need to make sure that the dimensions of the src pixels are divisible
+// by 4, and copy 4x4 blocks one at a time for compression.
+typedef uint64_t (*A84x4To64BitProc)(const uint8_t block[]);
+
+static bool compress_4x4_a8_to_64bit(uint8_t* dst, const uint8_t* src,
+                                     int width, int height, int rowBytes,
+                                     A84x4To64BitProc proc) {
+    // Make sure that our data is well-formed enough to be considered for compression
+    if (0 == width || 0 == height || (width % 4) != 0 || (height % 4) != 0) {
+        return false;
+    }
+
+    int blocksX = width >> 2;
+    int blocksY = height >> 2;
+
+    uint8_t block[16];
+    uint64_t* encPtr = reinterpret_cast<uint64_t*>(dst);
+    for (int y = 0; y < blocksY; ++y) {
+        for (int x = 0; x < blocksX; ++x) {
+            // Load block
+            for (int k = 0; k < 4; ++k) {
+                memcpy(block + k*4, src + k*rowBytes + 4*x, 4);
+            }
+
+            // Compress it
+            *encPtr = proc(block);
+            ++encPtr;
+        }
+        src += 4 * rowBytes;
+    }
+
+    return true;
+}
+#endif  // (COMPRESS_R11_EAC_SLOW) || (COMPRESS_R11_EAC_FAST)
+
+// This function converts an integer containing four bytes of alpha
+// values into an integer containing four bytes of indices into R11 EAC.
+// Note, there needs to be a mapping of indices:
+// 0 1 2 3 4 5 6 7
+// 3 2 1 0 4 5 6 7
+//
+// To compute this, we first negate each byte, and then add three, which
+// gives the mapping
+// 3 2 1 0 -1 -2 -3 -4
+//
+// Then we mask out the negative values, take their absolute value, and
+// add three.
+//
+// Most of the voodoo in this function comes from Hacker's Delight, section 2-18
+static inline uint32_t convert_indices(uint32_t x) {
+    // Take the top three bits...
+    x = (x & 0xE0E0E0E0) >> 5;
+
+    // Negate...
+    x = ~((0x80808080 - x) ^ 0x7F7F7F7F);
+
+    // Add three
+    const uint32_t s = (x & 0x7F7F7F7F) + 0x03030303;
+    x = ((x ^ 0x03030303) & 0x80808080) ^ s;
+
+    // Absolute value
+    const uint32_t a = x & 0x80808080;
+    const uint32_t b = a >> 7;
+
+    // Aside: mask negatives (m is three if the byte was negative)
+    const uint32_t m = (a >> 6) | b;
+
+    // .. continue absolute value
+    x = (x ^ ((a - b) | a)) + b;
+
+    // Add three
+    return x + m;
+}
+
+#if COMPRESS_R11_EAC_FASTEST
+template<unsigned shift>
+static inline uint64_t swap_shift(uint64_t x, uint64_t mask) {
+    const uint64_t t = (x ^ (x >> shift)) & mask;
+    return x ^ t ^ (t << shift);
+}
+
+static inline uint64_t interleave6(uint64_t topRows, uint64_t bottomRows) {
+    // If our 3-bit block indices are laid out as:
+    // a b c d
+    // e f g h
+    // i j k l
+    // m n o p
+    //
+    // This function expects topRows and bottomRows to contain the first two rows
+    // of indices interleaved in the least significant bits of a and b. In other words...
+    //
+    // If the architecture is big endian, then topRows and bottomRows will contain the following:
+    // Bits 31-0:
+    // a: 00 a e 00 b f 00 c g 00 d h
+    // b: 00 i m 00 j n 00 k o 00 l p
+    //
+    // If the architecture is little endian, then topRows and bottomRows will contain
+    // the following:
+    // Bits 31-0:
+    // a: 00 d h 00 c g 00 b f 00 a e
+    // b: 00 l p 00 k o 00 j n 00 i m
+    //
+    // This function returns a 48-bit packing of the form:
+    // a e i m b f j n c g k o d h l p
+    //
+    // !SPEED! this function might be even faster if certain SIMD intrinsics are
+    // used..
+
+    // For both architectures, we can figure out a packing of the bits by
+    // using a shuffle and a few shift-rotates...
+    uint64_t x = (static_cast<uint64_t>(topRows) << 32) | static_cast<uint64_t>(bottomRows);
+
+    // x: 00 a e 00 b f 00 c g 00 d h 00 i m 00 j n 00 k o 00 l p
+
+    x = swap_shift<10>(x, 0x3FC0003FC00000ULL);
+
+    // x: b f 00 00 00 a e c g i m 00 00 00 d h j n 00 k o 00 l p
+
+    x = (x | ((x << 52) & (0x3FULL << 52)) | ((x << 20) & (0x3FULL << 28))) >> 16;
+
+    // x: 00 00 00 00 00 00 00 00 b f l p a e c g i m k o d h j n
+
+    x = swap_shift<6>(x, 0xFC0000ULL);
+
+#if defined (SK_CPU_BENDIAN)
+    // x: 00 00 00 00 00 00 00 00 b f l p a e i m c g k o d h j n
+
+    x = swap_shift<36>(x, 0x3FULL);
+
+    // x: 00 00 00 00 00 00 00 00 b f j n a e i m c g k o d h l p
+
+    x = swap_shift<12>(x, 0xFFF000000ULL);
+#else
+    // If our CPU is little endian, then the above logic will
+    // produce the following indices:
+    // x: 00 00 00 00 00 00 00 00 c g i m d h l p b f j n a e k o
+
+    x = swap_shift<36>(x, 0xFC0ULL);
+
+    // x: 00 00 00 00 00 00 00 00 a e i m d h l p b f j n c g k o
+    
+    x = (x & (0xFFFULL << 36)) | ((x & 0xFFFFFFULL) << 12) | ((x >> 24) & 0xFFFULL);
+#endif
+
+    // x: 00 00 00 00 00 00 00 00 a e i m b f j n c g k o d h l p
+    return x;
+}
+
+// This function follows the same basic procedure as compress_heterogeneous_r11eac_block
+// above when COMPRESS_R11_EAC_FAST is defined, but it avoids a few loads/stores and
+// tries to optimize where it can using SIMD.
+static uint64_t compress_r11eac_block_fast(const uint8_t* src, int rowBytes) {
+    // Store each row of alpha values in an integer
+    const uint32_t alphaRow1 = *(reinterpret_cast<const uint32_t*>(src));
+    const uint32_t alphaRow2 = *(reinterpret_cast<const uint32_t*>(src + rowBytes));
+    const uint32_t alphaRow3 = *(reinterpret_cast<const uint32_t*>(src + 2*rowBytes));
+    const uint32_t alphaRow4 = *(reinterpret_cast<const uint32_t*>(src + 3*rowBytes));
+
+    // Check for solid blocks. The explanations for these values
+    // can be found in the comments of compress_r11eac_block above
+    if (alphaRow1 == alphaRow2 && alphaRow1 == alphaRow3 && alphaRow1 == alphaRow4) {
+        if (0 == alphaRow1) {
+            // Fully transparent block
+            return 0x0020000000002000ULL;
+        } else if (0xFFFFFFFF == alphaRow1) {
+            // Fully opaque block
+            return 0xFFFFFFFFFFFFFFFFULL;
+        }
+    }
+
+    // Convert each integer of alpha values into an integer of indices
+    const uint32_t indexRow1 = convert_indices(alphaRow1);
+    const uint32_t indexRow2 = convert_indices(alphaRow2);
+    const uint32_t indexRow3 = convert_indices(alphaRow3);
+    const uint32_t indexRow4 = convert_indices(alphaRow4);
+
+    // Interleave the indices from the top two rows and bottom two rows
+    // prior to passing them to interleave6. Since each index is at most
+    // three bits, then each byte can hold two indices... The way that the
+    // compression scheme expects the packing allows us to efficiently pack
+    // the top two rows and bottom two rows. Interleaving each 6-bit sequence
+    // and tightly packing it into a uint64_t is a little trickier, which is
+    // taken care of in interleave6.
+    const uint32_t r1r2 = (indexRow1 << 3) | indexRow2;
+    const uint32_t r3r4 = (indexRow3 << 3) | indexRow4;
+    const uint64_t indices = interleave6(r1r2, r3r4);
+
+    // Return the packed incdices in the least significant bits with the magic header
+    return SkEndian_SwapBE64(0x8490000000000000ULL | indices);
+}
+
+static bool compress_a8_to_r11eac_fast(uint8_t* dst, const uint8_t* src,
+                                       int width, int height, int rowBytes) {
+    // Make sure that our data is well-formed enough to be considered for compression
+    if (0 == width || 0 == height || (width % 4) != 0 || (height % 4) != 0) {
+        return false;
+    }
+
+    const int blocksX = width >> 2;
+    const int blocksY = height >> 2;
+
+    uint64_t* encPtr = reinterpret_cast<uint64_t*>(dst);
+    for (int y = 0; y < blocksY; ++y) {
+        for (int x = 0; x < blocksX; ++x) {
+            // Compress it
+            *encPtr = compress_r11eac_block_fast(src + 4*x, rowBytes);
+            ++encPtr;
+        }
+        src += 4 * rowBytes;
+    }
+    return true;
+}
+#endif // COMPRESS_R11_EAC_FASTEST
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Utility functions used by the blitter
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// The R11 EAC format expects that indices are given in column-major order. Since
+// we receive alpha values in raster order, this usually means that we have to use
+// pack6 above to properly pack our indices. However, if our indices come from the
+// blitter, then each integer will be a column of indices, and hence can be efficiently
+// packed. This function takes the bottom three bits of each byte and places them in
+// the least significant 12 bits of the resulting integer.
+static inline uint32_t pack_indices_vertical(uint32_t x) {
+#if defined (SK_CPU_BENDIAN)
+    return 
+        (x & 7) |
+        ((x >> 5) & (7 << 3)) |
+        ((x >> 10) & (7 << 6)) |
+        ((x >> 15) & (7 << 9));
+#else
+    return 
+        ((x >> 24) & 7) |
+        ((x >> 13) & (7 << 3)) |
+        ((x >> 2) & (7 << 6)) |
+        ((x << 9) & (7 << 9));
+#endif
+}
+
+// This function returns the compressed format of a block given as four columns of
+// alpha values. Each column is assumed to be loaded from top to bottom, and hence
+// must first be converted to indices and then packed into the resulting 64-bit
+// integer.
+inline void compress_block_vertical(uint8_t* dstPtr, const uint8_t *block) {
+
+    const uint32_t* src = reinterpret_cast<const uint32_t*>(block);
+    uint64_t* dst = reinterpret_cast<uint64_t*>(dstPtr);
+
+    const uint32_t alphaColumn0 = src[0];
+    const uint32_t alphaColumn1 = src[1];
+    const uint32_t alphaColumn2 = src[2];
+    const uint32_t alphaColumn3 = src[3];
+
+    if (alphaColumn0 == alphaColumn1 &&
+        alphaColumn2 == alphaColumn3 &&
+        alphaColumn0 == alphaColumn2) {
+
+        if (0 == alphaColumn0) {
+            // Transparent
+            *dst = 0x0020000000002000ULL;
+            return;
+        }
+        else if (0xFFFFFFFF == alphaColumn0) {
+            // Opaque
+            *dst = 0xFFFFFFFFFFFFFFFFULL;
+            return;
+        }
+    }
+
+    const uint32_t indexColumn0 = convert_indices(alphaColumn0);
+    const uint32_t indexColumn1 = convert_indices(alphaColumn1);
+    const uint32_t indexColumn2 = convert_indices(alphaColumn2);
+    const uint32_t indexColumn3 = convert_indices(alphaColumn3);
+
+    const uint32_t packedIndexColumn0 = pack_indices_vertical(indexColumn0);
+    const uint32_t packedIndexColumn1 = pack_indices_vertical(indexColumn1);
+    const uint32_t packedIndexColumn2 = pack_indices_vertical(indexColumn2);
+    const uint32_t packedIndexColumn3 = pack_indices_vertical(indexColumn3);
+
+    *dst = SkEndian_SwapBE64(0x8490000000000000ULL |
+                             (static_cast<uint64_t>(packedIndexColumn0) << 36) |
+                             (static_cast<uint64_t>(packedIndexColumn1) << 24) |
+                             static_cast<uint64_t>(packedIndexColumn2 << 12) |
+                             static_cast<uint64_t>(packedIndexColumn3));
+}
+
+static inline int get_r11_eac_index(uint64_t block, int x, int y) {
+    SkASSERT(x >= 0 && x < 4);
+    SkASSERT(y >= 0 && y < 4);
+    const int idx = x*4 + y;
+    return (block >> ((15-idx)*3)) & 0x7;
+}
+
+static void decompress_r11_eac_block(uint8_t* dst, int dstRowBytes, const uint8_t* src) {
+    const uint64_t block = SkEndian_SwapBE64(*(reinterpret_cast<const uint64_t *>(src)));
+
+    const int base_cw = (block >> 56) & 0xFF;
+    const int mod = (block >> 52) & 0xF;
+    const int palette_idx = (block >> 48) & 0xF;
+
+    const int* palette = kR11EACModifierPalettes[palette_idx];
+
+    for (int j = 0; j < 4; ++j) {
+        for (int i = 0; i < 4; ++i) {
+            const int idx = get_r11_eac_index(block, i, j);
+            const int val = base_cw*8 + 4 + palette[idx]*mod*8;
+            if (val < 0) {
+                dst[i] = 0;
+            } else if (val > 2047) {
+                dst[i] = 0xFF;
+            } else {
+                dst[i] = (val >> 3) & 0xFF;
+            }
+        }
+        dst += dstRowBytes;
+    }
+}
+
+// This is the type passed as the CompressorType argument of the compressed
+// blitter for the R11 EAC format. The static functions required to be in this
+// struct are documented in SkTextureCompressor_Blitter.h
+struct CompressorR11EAC {
+    static inline void CompressA8Vertical(uint8_t* dst, const uint8_t* src) {
+        compress_block_vertical(dst, src);
+    }
+
+    static inline void CompressA8Horizontal(uint8_t* dst, const uint8_t* src,
+                                            int srcRowBytes) {
+        *(reinterpret_cast<uint64_t*>(dst)) = compress_r11eac_block_fast(src, srcRowBytes);
+    }
+
+#if PEDANTIC_BLIT_RECT
+    static inline void UpdateBlock(uint8_t* dst, const uint8_t* src, int srcRowBytes,
+                                   const uint8_t* mask) {
+        // TODO: krajcevski
+        // The implementation of this function should be similar to that of LATC, since
+        // the R11EAC indices directly correspond to pixel values.
+        SkFAIL("Implement me!");
+    }
+#endif
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace SkTextureCompressor {
+
+bool CompressA8ToR11EAC(uint8_t* dst, const uint8_t* src, int width, int height, int rowBytes) {
+
+#if (COMPRESS_R11_EAC_SLOW) || (COMPRESS_R11_EAC_FAST)
+
+    return compress_4x4_a8_to_64bit(dst, src, width, height, rowBytes, compress_r11eac_block);
+
+#elif COMPRESS_R11_EAC_FASTEST
+
+    return compress_a8_to_r11eac_fast(dst, src, width, height, rowBytes);
+
+#else
+#error "Must choose R11 EAC algorithm"
+#endif
+}
+
+SkBlitter* CreateR11EACBlitter(int width, int height, void* outputBuffer,
+                               SkTBlitterAllocator* allocator) {
+
+    if ((width % 4) != 0 || (height % 4) != 0) {
+        return NULL;
+    }
+
+    // Memset the output buffer to an encoding that decodes to zero. We must do this
+    // in order to avoid having uninitialized values in the buffer if the blitter
+    // decides not to write certain scanlines (and skip entire rows of blocks).
+    // In the case of R11, we use the encoding from recognizing all zero pixels from above.
+    const int nBlocks = (width * height / 16);  // 4x4 pixel blocks.
+    uint64_t *dst = reinterpret_cast<uint64_t *>(outputBuffer);
+    for (int i = 0; i < nBlocks; ++i) {
+        *dst = 0x0020000000002000ULL;
+        ++dst;
+    }
+
+    return allocator->createT<
+        SkTCompressedAlphaBlitter<4, 8, CompressorR11EAC>, int, int, void*>
+        (width, height, outputBuffer);
+}
+
+void DecompressR11EAC(uint8_t* dst, int dstRowBytes, const uint8_t* src, int width, int height) {
+    for (int j = 0; j < height; j += 4) {
+        for (int i = 0; i < width; i += 4) {
+            decompress_r11_eac_block(dst + i, dstRowBytes, src);
+            src += 8;
+        }
+        dst += 4 * dstRowBytes;
+    }    
+}
+
+}  // namespace SkTextureCompressor
diff --git a/src/utils/SkTextureCompressor_R11EAC.h b/src/utils/SkTextureCompressor_R11EAC.h
new file mode 100644
index 0000000..6786513
--- /dev/null
+++ b/src/utils/SkTextureCompressor_R11EAC.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTextureCompressor_R11EAC_DEFINED
+#define SkTextureCompressor_R11EAC_DEFINED
+
+#include "SkBitmapProcShader.h"
+
+class SkBlitter;
+
+namespace SkTextureCompressor {
+
+    bool CompressA8ToR11EAC(uint8_t* dst, const uint8_t* src,
+                            int width, int height, int rowBytes);
+
+    SkBlitter* CreateR11EACBlitter(int width, int height, void* outputBuffer,
+                                   SkTBlitterAllocator* allocator);
+
+    void DecompressR11EAC(uint8_t* dst, int dstRB, const uint8_t* src, int width, int height);
+}
+
+#endif  // SkTextureCompressor_R11EAC_DEFINED
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index 8f6dc1b..85fb7a4 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -14,11 +14,10 @@
 #include "SkDevice.h"
 #include "SkXfermode.h"
 
-SkDebugCanvas::SkDebugCanvas(int width, int height)
-        : INHERITED(width, height)
+SkDebugCanvas::SkDebugCanvas(int windowWidth, int windowHeight)
+        : INHERITED(windowWidth, windowHeight)
         , fPicture(NULL)
-        , fWidth(width)
-        , fHeight(height)
+        , fWindowSize(SkISize::Make(windowWidth, windowHeight))
         , fFilter(false)
         , fMegaVizMode(false)
         , fIndex(0)
@@ -76,7 +75,7 @@
 
     SkCanvas canvas(bitmap);
     canvas.translate(SkIntToScalar(-x), SkIntToScalar(-y));
-    applyUserTransform(&canvas);
+    this->applyUserTransform(&canvas);
 
     int layer = 0;
     SkColor prev = bitmap.getColor(0,0);
@@ -255,10 +254,10 @@
         }
         canvas->clear(SK_ColorTRANSPARENT);
         canvas->resetMatrix();
-        SkRect rect = SkRect::MakeWH(SkIntToScalar(fWidth),
-                                     SkIntToScalar(fHeight));
-        canvas->clipRect(rect, SkRegion::kReplace_Op );
-        applyUserTransform(canvas);
+        SkRect rect = SkRect::MakeWH(SkIntToScalar(fWindowSize.fWidth), 
+                                     SkIntToScalar(fWindowSize.fHeight));
+        canvas->clipRect(rect, SkRegion::kReplace_Op);
+        this->applyUserTransform(canvas);
         fOutstandingSaveCount = 0;
     }
 
@@ -292,17 +291,7 @@
 
     for (; i <= index; i++) {
         if (i == index && fFilter) {
-            SkPaint p;
-            p.setColor(0xAAFFFFFF);
-            canvas->save();
-            canvas->resetMatrix();
-            SkRect mask;
-            mask.set(SkIntToScalar(0), SkIntToScalar(0),
-                    SkIntToScalar(fWidth), SkIntToScalar(fHeight));
-            canvas->clipRect(mask, SkRegion::kReplace_Op, false);
-            canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
-                    SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
-            canvas->restore();
+            canvas->clear(0xAAFFFFFF);
         }
 
         if (fCommandVector[i]->isVisible()) {
@@ -321,12 +310,13 @@
     }
 
     if (fMegaVizMode) {
-        SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight));
+        SkRect r = SkRect::MakeWH(SkIntToScalar(fWindowSize.fWidth), 
+                                  SkIntToScalar(fWindowSize.fHeight));
         r.outset(SK_Scalar1, SK_Scalar1);
 
         canvas->save();
         // nuke the CTM
-        canvas->setMatrix(SkMatrix::I());
+        canvas->resetMatrix();
         // turn off clipping
         canvas->clipRect(r, SkRegion::kReplace_Op);
 
@@ -519,8 +509,10 @@
     this->addDrawCommand(new SkDrawPathCommand(path, paint));
 }
 
-void SkDebugCanvas::onDrawPicture(const SkPicture* picture) {
-    this->addDrawCommand(new SkDrawPictureCommand(picture));
+void SkDebugCanvas::onDrawPicture(const SkPicture* picture, 
+                                  const SkMatrix* matrix, 
+                                  const SkPaint* paint) {
+    this->addDrawCommand(new SkDrawPictureCommand(picture, matrix, paint));
 }
 
 void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
@@ -569,6 +561,11 @@
         new SkDrawTextOnPathCommand(text, byteLength, path, matrix, paint));
 }
 
+void SkDebugCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                   const SkPaint& paint) {
+    this->addDrawCommand(new SkDrawTextBlobCommand(blob, x, y, paint));
+}
+
 void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
         const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
         SkXfermode*, const uint16_t indices[], int indexCount,
@@ -590,9 +587,9 @@
     this->INHERITED::willRestore();
 }
 
-void SkDebugCanvas::willSave(SaveFlags flags) {
-    this->addDrawCommand(new SkSaveCommand(flags));
-    this->INHERITED::willSave(flags);
+void SkDebugCanvas::willSave() {
+    this->addDrawCommand(new SkSaveCommand());
+    this->INHERITED::willSave();
 }
 
 SkCanvas::SaveLayerStrategy SkDebugCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
diff --git a/src/utils/debugger/SkDebugCanvas.h b/src/utils/debugger/SkDebugCanvas.h
index f15b397..c61627d 100644
--- a/src/utils/debugger/SkDebugCanvas.h
+++ b/src/utils/debugger/SkDebugCanvas.h
@@ -145,10 +145,7 @@
      */
     void toggleCommand(int index, bool toggle);
 
-    void setBounds(int width, int height) {
-        fWidth = width;
-        fHeight = height;
-    }
+    void setWindowSize(int width, int height) { fWindowSize.set(width, height); }
 
     void setUserMatrix(SkMatrix matrix) {
         fUserMatrix = matrix;
@@ -210,28 +207,23 @@
 
     virtual bool isClipEmpty() const SK_OVERRIDE { return false; }
     virtual bool isClipRect() const SK_OVERRIDE { return true; }
-#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE
-    virtual ClipType getClipType() const SK_OVERRIDE {
-        return kRect_ClipType;
-    }
-#endif
     virtual bool getClipBounds(SkRect* bounds) const SK_OVERRIDE {
-        if (NULL != bounds) {
+        if (bounds) {
             bounds->setXYWH(0, 0,
-                            SkIntToScalar(this->imageInfo().fWidth),
-                            SkIntToScalar(this->imageInfo().fHeight));
+                            SkIntToScalar(this->imageInfo().width()),
+                            SkIntToScalar(this->imageInfo().height()));
         }
         return true;
     }
     virtual bool getClipDeviceBounds(SkIRect* bounds) const SK_OVERRIDE {
-        if (NULL != bounds) {
+        if (bounds) {
             bounds->setLargest();
         }
         return true;
     }
 
 protected:
-    virtual void willSave(SaveFlags) SK_OVERRIDE;
+    virtual void willSave() SK_OVERRIDE;
     virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
     virtual void willRestore() SK_OVERRIDE;
 
@@ -247,6 +239,8 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
     virtual void onPushCull(const SkRect& cullRect) SK_OVERRIDE;
     virtual void onPopCull() SK_OVERRIDE;
 
@@ -255,15 +249,14 @@
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion& region, SkRegion::Op) SK_OVERRIDE;
 
-    virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
 
     void markActiveCommands(int index);
 
 private:
     SkTDArray<SkDrawCommand*> fCommandVector;
     SkPicture* fPicture;
-    int fWidth;
-    int fHeight;
+    SkISize fWindowSize;
     bool fFilter;
     bool fMegaVizMode;
     int fIndex;
@@ -314,9 +307,11 @@
     void applyUserTransform(SkCanvas* canvas);
 
     size_t getOpID() const {
-        if (NULL != fPicture) {
+#if 0
+        if (fPicture) {
             return fPicture->EXPERIMENTAL_curOpID();
         }
+#endif
         return 0;
     }
 
diff --git a/src/utils/debugger/SkDrawCommand.cpp b/src/utils/debugger/SkDrawCommand.cpp
index 7c73cec..0da8f98 100644
--- a/src/utils/debugger/SkDrawCommand.cpp
+++ b/src/utils/debugger/SkDrawCommand.cpp
@@ -10,6 +10,8 @@
 #include "SkDrawCommand.h"
 #include "SkObjectParser.h"
 
+#include "SkTextBlob.h"
+
 // TODO(chudy): Refactor into non subclass model.
 
 SkDrawCommand::SkDrawCommand(DrawType type)
@@ -52,6 +54,7 @@
         case DRAW_RRECT: return "Draw RRect";
         case DRAW_SPRITE: return "Draw Sprite";
         case DRAW_TEXT: return "Draw Text";
+        case DRAW_TEXT_BLOB: return "Draw Text Blob";
         case DRAW_TEXT_ON_PATH: return "Draw Text On Path";
         case DRAW_VERTICES: return "Draw Vertices";
         case RESTORE: return "Restore";
@@ -145,7 +148,7 @@
     canvas->clear(0xFFFFFFFF);
     canvas->drawBitmapRect(input, NULL, dst);
 
-    if (NULL != srcRect) {
+    if (srcRect) {
         SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
                                     srcRect->fTop * yScale + SK_Scalar1,
                                     srcRect->fRight * xScale + SK_Scalar1,
@@ -273,12 +276,12 @@
 }
 
 SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
-                       const SkPaint* paint)
+                                         const SkPaint* paint)
     : INHERITED(DRAW_BITMAP) {
     fBitmap = bitmap;
     fLeft = left;
     fTop = top;
-    if (NULL != paint) {
+    if (paint) {
         fPaint = *paint;
         fPaintPtr = &fPaint;
     } else {
@@ -288,7 +291,7 @@
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
     fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
-    if (NULL != paint) {
+    if (paint) {
         fInfo.push(SkObjectParser::PaintToString(*paint));
     }
 }
@@ -308,7 +311,7 @@
     : INHERITED(DRAW_BITMAP_MATRIX) {
     fBitmap = bitmap;
     fMatrix = matrix;
-    if (NULL != paint) {
+    if (paint) {
         fPaint = *paint;
         fPaintPtr = &fPaint;
     } else {
@@ -317,7 +320,7 @@
 
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     fInfo.push(SkObjectParser::MatrixToString(matrix));
-    if (NULL != paint) {
+    if (paint) {
         fInfo.push(SkObjectParser::PaintToString(*paint));
     }
 }
@@ -337,7 +340,7 @@
     fBitmap = bitmap;
     fCenter = center;
     fDst = dst;
-    if (NULL != paint) {
+    if (paint) {
         fPaint = *paint;
         fPaintPtr = &fPaint;
     } else {
@@ -347,7 +350,7 @@
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     fInfo.push(SkObjectParser::IRectToString(center));
     fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
-    if (NULL != paint) {
+    if (paint) {
         fInfo.push(SkObjectParser::PaintToString(*paint));
     }
 }
@@ -366,14 +369,14 @@
                                                  SkCanvas::DrawBitmapRectFlags flags)
     : INHERITED(DRAW_BITMAP_RECT_TO_RECT) {
     fBitmap = bitmap;
-    if (NULL != src) {
+    if (src) {
         fSrc = *src;
     } else {
         fSrc.setEmpty();
     }
     fDst = dst;
 
-    if (NULL != paint) {
+    if (paint) {
         fPaint = *paint;
         fPaintPtr = &fPaint;
     } else {
@@ -382,11 +385,11 @@
     fFlags = flags;
 
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
-    if (NULL != src) {
+    if (src) {
         fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
     }
     fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
-    if (NULL != paint) {
+    if (paint) {
         fInfo.push(SkObjectParser::PaintToString(*paint));
     }
     fInfo.push(SkObjectParser::IntToString(fFlags, "Flags: "));
@@ -502,25 +505,45 @@
     return true;
 }
 
-SkDrawPictureCommand::SkDrawPictureCommand(const SkPicture* picture)
+SkDrawPictureCommand::SkDrawPictureCommand(const SkPicture* picture,
+                                           const SkMatrix* matrix,
+                                           const SkPaint* paint)
     : INHERITED(DRAW_PICTURE)
-    , fPicture(SkRef(picture)) {
+    , fPicture(SkRef(picture))
+    , fMatrixPtr(NULL)
+    , fPaintPtr(NULL) {
+
+    if (matrix) {
+        fMatrix = *matrix;
+        fMatrixPtr = &fMatrix;
+    }
+    if (paint) {
+        fPaint = *paint;
+        fPaintPtr = &fPaint;
+    }
+
     SkString* temp = new SkString;
-    temp->appendf("SkPicture: W: %d H: %d", picture->width(), picture->height());
+    temp->appendf("SkPicture: L: %f T: %f R: %f B: %f",
+                  picture->cullRect().fLeft, picture->cullRect().fTop,
+                  picture->cullRect().fRight, picture->cullRect().fBottom);
     fInfo.push(temp);
+    if (matrix) {
+        fInfo.push(SkObjectParser::MatrixToString(*matrix));
+    }
+    if (paint) {
+        fInfo.push(SkObjectParser::PaintToString(*paint));
+    }
 }
 
 void SkDrawPictureCommand::execute(SkCanvas* canvas) {
-    canvas->drawPicture(fPicture);
+    canvas->drawPicture(fPicture, fMatrixPtr, fPaintPtr);
 }
 
 bool SkDrawPictureCommand::render(SkCanvas* canvas) const {
     canvas->clear(0xFFFFFFFF);
     canvas->save();
 
-    SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
-                                   SkIntToScalar(fPicture->height()));
-    xlate_and_scale_to_bounds(canvas, bounds);
+    xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
 
     canvas->drawPicture(fPicture.get());
 
@@ -623,6 +646,40 @@
     canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
 }
 
+SkDrawTextBlobCommand::SkDrawTextBlobCommand(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                             const SkPaint& paint)
+    : INHERITED(DRAW_TEXT_BLOB)
+    , fBlob(blob)
+    , fXPos(x)
+    , fYPos(y)
+    , fPaint(paint) {
+
+    blob->ref();
+
+    // FIXME: push blob info
+    fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: "));
+    fInfo.push(SkObjectParser::ScalarToString(x, "YPOS: "));
+    fInfo.push(SkObjectParser::PaintToString(paint));
+}
+
+void SkDrawTextBlobCommand::execute(SkCanvas* canvas) {
+    canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
+}
+
+bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
+    canvas->clear(SK_ColorWHITE);
+    canvas->save();
+
+    SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
+    xlate_and_scale_to_bounds(canvas, bounds);
+
+    canvas->drawTextBlob(fBlob.get(), fXPos, fYPos, fPaint);
+
+    canvas->restore();
+
+    return true;
+}
+
 SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
     : INHERITED(DRAW_RECT) {
     fRect = rect;
@@ -682,7 +739,7 @@
     fBitmap = bitmap;
     fLeft = left;
     fTop = top;
-    if (NULL != paint) {
+    if (paint) {
         fPaint = *paint;
         fPaintPtr = &fPaint;
     } else {
@@ -692,7 +749,7 @@
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     fInfo.push(SkObjectParser::IntToString(left, "Left: "));
     fInfo.push(SkObjectParser::IntToString(top, "Top: "));
-    if (NULL != paint) {
+    if (paint) {
         fInfo.push(SkObjectParser::PaintToString(*paint));
     }
 }
@@ -734,7 +791,7 @@
     memcpy(fText, text, byteLength);
     fByteLength = byteLength;
     fPath = path;
-    if (NULL != matrix) {
+    if (matrix) {
         fMatrix = *matrix;
     } else {
         fMatrix.setIdentity();
@@ -743,7 +800,7 @@
 
     fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
     fInfo.push(SkObjectParser::PathToString(path));
-    if (NULL != matrix) {
+    if (matrix) {
         fInfo.push(SkObjectParser::MatrixToString(*matrix));
     }
     fInfo.push(SkObjectParser::PaintToString(paint));
@@ -768,14 +825,14 @@
     fVertices = new SkPoint[vertexCount];
     memcpy(fVertices, vertices, vertexCount * sizeof(SkPoint));
 
-    if (NULL != texs) {
+    if (texs) {
         fTexs = new SkPoint[vertexCount];
         memcpy(fTexs, texs, vertexCount * sizeof(SkPoint));
     } else {
         fTexs = NULL;
     }
 
-    if (NULL != colors) {
+    if (colors) {
         fColors = new SkColor[vertexCount];
         memcpy(fColors, colors, vertexCount * sizeof(SkColor));
     } else {
@@ -783,7 +840,7 @@
     }
 
     fXfermode = xfermode;
-    if (NULL != fXfermode) {
+    if (fXfermode) {
         fXfermode->ref();
     }
 
@@ -840,14 +897,12 @@
     canvas->rotate(fDegrees);
 }
 
-SkSaveCommand::SkSaveCommand(SkCanvas::SaveFlags flags)
+SkSaveCommand::SkSaveCommand()
     : INHERITED(SAVE) {
-    fFlags = flags;
-    fInfo.push(SkObjectParser::SaveFlagsToString(flags));
 }
 
 void SkSaveCommand::execute(SkCanvas* canvas) {
-    canvas->save(fFlags);
+    canvas->save();
 }
 
 void SkSaveCommand::trackSaveState(int* state) {
@@ -857,13 +912,13 @@
 SkSaveLayerCommand::SkSaveLayerCommand(const SkRect* bounds, const SkPaint* paint,
                                        SkCanvas::SaveFlags flags)
     : INHERITED(SAVE_LAYER) {
-    if (NULL != bounds) {
+    if (bounds) {
         fBounds = *bounds;
     } else {
         fBounds.setEmpty();
     }
 
-    if (NULL != paint) {
+    if (paint) {
         fPaint = *paint;
         fPaintPtr = &fPaint;
     } else {
@@ -871,10 +926,10 @@
     }
     fFlags = flags;
 
-    if (NULL != bounds) {
+    if (bounds) {
         fInfo.push(SkObjectParser::RectToString(*bounds, "Bounds: "));
     }
-    if (NULL != paint) {
+    if (paint) {
         fInfo.push(SkObjectParser::PaintToString(*paint));
     }
     fInfo.push(SkObjectParser::SaveFlagsToString(flags));
diff --git a/src/utils/debugger/SkDrawCommand.h b/src/utils/debugger/SkDrawCommand.h
index a0bfb2d..def0db4 100644
--- a/src/utils/debugger/SkDrawCommand.h
+++ b/src/utils/debugger/SkDrawCommand.h
@@ -343,12 +343,16 @@
 
 class SkDrawPictureCommand : public SkDrawCommand {
 public:
-    SkDrawPictureCommand(const SkPicture* picture);
+    SkDrawPictureCommand(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
 
 private:
     SkAutoTUnref<const SkPicture> fPicture;
+    SkMatrix                      fMatrix;
+    SkMatrix*                     fMatrixPtr;
+    SkPaint                       fPaint;
+    SkPaint*                      fPaintPtr;
 
     typedef SkDrawCommand INHERITED;
 };
@@ -432,6 +436,22 @@
     typedef SkDrawCommand INHERITED;
 };
 
+class SkDrawTextBlobCommand : public SkDrawCommand {
+public:
+    SkDrawTextBlobCommand(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
+
+    virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
+    virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
+
+private:
+    SkAutoTUnref<const SkTextBlob> fBlob;
+    SkScalar                       fXPos;
+    SkScalar                       fYPos;
+    SkPaint                        fPaint;
+
+    typedef SkDrawCommand INHERITED;
+};
+
 class SkDrawRectCommand : public SkDrawCommand {
 public:
     SkDrawRectCommand(const SkRect& rect, const SkPaint& paint);
@@ -522,13 +542,11 @@
 
 class SkSaveCommand : public SkDrawCommand {
 public:
-    SkSaveCommand(SkCanvas::SaveFlags flags);
+    SkSaveCommand();
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
     virtual void trackSaveState(int* state) SK_OVERRIDE;
     virtual Action action() const SK_OVERRIDE { return kPushLayer_Action; }
 private:
-    SkCanvas::SaveFlags fFlags;
-
     typedef SkDrawCommand INHERITED;
 };
 
diff --git a/src/utils/debugger/SkObjectParser.cpp b/src/utils/debugger/SkObjectParser.cpp
index b932036..798db95 100644
--- a/src/utils/debugger/SkObjectParser.cpp
+++ b/src/utils/debugger/SkObjectParser.cpp
@@ -174,7 +174,7 @@
 
     SkString* boundStr = SkObjectParser::RectToString(path.getBounds(), "    Bound: ");
 
-    if (NULL != boundStr) {
+    if (boundStr) {
         mPath->append(*boundStr);
         SkDELETE(boundStr);
     }
@@ -300,12 +300,6 @@
 
 SkString* SkObjectParser::SaveFlagsToString(SkCanvas::SaveFlags flags) {
     SkString* mFlags = new SkString("SkCanvas::SaveFlags: ");
-    if (flags & SkCanvas::kMatrix_SaveFlag) {
-        mFlags->append("kMatrix_SaveFlag ");
-    }
-    if (flags & SkCanvas::kClip_SaveFlag) {
-        mFlags->append("kClip_SaveFlag ");
-    }
     if (flags & SkCanvas::kHasAlphaLayer_SaveFlag) {
         mFlags->append("kHasAlphaLayer_SaveFlag ");
     }
diff --git a/src/utils/ios/SkImageDecoder_iOS.mm b/src/utils/ios/SkImageDecoder_iOS.mm
index 5e4261f..f3db65e 100755
--- a/src/utils/ios/SkImageDecoder_iOS.mm
+++ b/src/utils/ios/SkImageDecoder_iOS.mm
@@ -29,8 +29,7 @@
     
     const int width = uimage.size.width;
     const int height = uimage.size.height;
-    SkColorType ct = SkBitmapConfigToColorType(SkBitmap::kARGB_8888_Config);
-    bm->setInfo(SkImageInfo::Make(width, height, ct, kPremul_SkAlphaType), 0);
+    bm->setInfo(SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType), 0);
     if (SkImageDecoder::kDecodeBounds_Mode == mode) {
         return true;
     }
@@ -63,7 +62,4 @@
     return NULL;
 }
 
-SkImageEncoder* SkImageEncoder::Create(Type t) {
-    return NULL;
-}
 
diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp
index 01b774d..14a24d8 100644
--- a/src/utils/mac/SkCreateCGImageRef.cpp
+++ b/src/utils/mac/SkCreateCGImageRef.cpp
@@ -221,7 +221,7 @@
     int h = (int)CGRectGetHeight(bounds);
 
     SkBitmap bitmap;
-    if (!bitmap.allocPixels(SkImageInfo::MakeN32Premul(w, h))) {
+    if (!bitmap.tryAllocN32Pixels(w, h)) {
         return false;
     }
     bitmap.eraseColor(SK_ColorWHITE);
@@ -287,7 +287,7 @@
     SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
 
     SkBitmap tmp;
-    if (!tmp.allocPixels(info)) {
+    if (!tmp.tryAllocPixels(info)) {
         return false;
     }
 
diff --git a/src/utils/win/SkDWrite.cpp b/src/utils/win/SkDWrite.cpp
index 87826b5..7801059 100644
--- a/src/utils/win/SkDWrite.cpp
+++ b/src/utils/win/SkDWrite.cpp
@@ -67,23 +67,19 @@
 }
 
 /** Converts a WCHAR string to a utf8 string. */
-HRESULT sk_wchar_to_skstring(WCHAR* name, SkString* skname) {
-    int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL);
+HRESULT sk_wchar_to_skstring(WCHAR* name, int nameLen, SkString* skname) {
+    int len = WideCharToMultiByte(CP_UTF8, 0, name, nameLen, NULL, 0, NULL, NULL);
     if (0 == len) {
+        if (nameLen <= 0) {
+            skname->reset();
+            return S_OK;
+        }
         HRM(HRESULT_FROM_WIN32(GetLastError()),
             "Could not get length for utf-8 to wchar conversion.");
     }
-    skname->resize(len - 1);
+    skname->resize(len);
 
-    // TODO: remove after https://code.google.com/p/skia/issues/detail?id=1989 is fixed.
-    // If we resize to 0 then the skname points to gEmptyRec (the unique empty SkString::Rec).
-    // gEmptyRec is static const and on Windows this means the value is in a read only page.
-    // Writing to it in the following call to WideCharToMultiByte will cause an access violation.
-    if (1 == len) {
-        return S_OK;
-    }
-
-    len = WideCharToMultiByte(CP_UTF8, 0, name, -1, skname->writable_str(), len, NULL, NULL);
+    len = WideCharToMultiByte(CP_UTF8, 0, name, nameLen, skname->writable_str(), len, NULL, NULL);
     if (0 == len) {
         HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert utf-8 to wchar.");
     }
@@ -105,14 +101,13 @@
         }
     }
 
-    UINT32 nameLength;
-    HRVM(names->GetStringLength(nameIndex, &nameLength), "Could not get name length.");
-    nameLength += 1;
+    UINT32 nameLen;
+    HRVM(names->GetStringLength(nameIndex, &nameLen), "Could not get name length.");
 
-    SkSMallocWCHAR name(nameLength);
-    HRVM(names->GetString(nameIndex, name.get(), nameLength), "Could not get string.");
+    SkSMallocWCHAR name(nameLen+1);
+    HRVM(names->GetString(nameIndex, name.get(), nameLen+1), "Could not get string.");
 
-    HRV(sk_wchar_to_skstring(name.get(), skname));
+    HRV(sk_wchar_to_skstring(name.get(), nameLen, skname));
 }
 
 HRESULT SkGetGetUserDefaultLocaleNameProc(SkGetUserDefaultLocaleNameProc* proc) {
diff --git a/src/utils/win/SkDWrite.h b/src/utils/win/SkDWrite.h
index 679447d..5b56673 100644
--- a/src/utils/win/SkDWrite.h
+++ b/src/utils/win/SkDWrite.h
@@ -11,12 +11,17 @@
 #include "SkTemplates.h"
 
 #include <dwrite.h>
+#include <winsdkver.h>
 
 class SkString;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Factory
 
+#ifndef SK_HAS_DWRITE_1_H
+#define SK_HAS_DWRITE_1_H (WINVER_MAXVER >= 0x0602)
+#endif
+
 IDWriteFactory* sk_get_dwrite_factory();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -28,8 +33,10 @@
 /** Converts a utf8 string to a WCHAR string. */
 HRESULT sk_cstring_to_wchar(const char* skname, SkSMallocWCHAR* name);
 
-/** Converts a WCHAR string to a utf8 string. */
-HRESULT sk_wchar_to_skstring(WCHAR* name, SkString* skname);
+/** Converts a WCHAR string to a utf8 string.
+ *  @param nameLen the number of WCHARs in the name.
+ */
+HRESULT sk_wchar_to_skstring(WCHAR* name, int nameLen, SkString* skname);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Locale
@@ -37,7 +44,7 @@
 void sk_get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* preferedLocale,
                        SkString* skname);
 
-typedef decltype(GetUserDefaultLocaleName)* SkGetUserDefaultLocaleNameProc;
+typedef int (WINAPI *SkGetUserDefaultLocaleNameProc)(LPWSTR, int);
 HRESULT SkGetGetUserDefaultLocaleNameProc(SkGetUserDefaultLocaleNameProc* proc);
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/utils/win/SkDWriteFontFileStream.cpp b/src/utils/win/SkDWriteFontFileStream.cpp
index c7dc3b2..0f0c628 100644
--- a/src/utils/win/SkDWriteFontFileStream.cpp
+++ b/src/utils/win/SkDWriteFontFileStream.cpp
@@ -188,7 +188,7 @@
     }
 
     const void* data = fStream->getMemoryBase();
-    if (NULL != data) {
+    if (data) {
         *fragmentStart = static_cast<BYTE const*>(data) + static_cast<size_t>(fileOffset);
         *fragmentContext = NULL;
 
diff --git a/src/utils/win/SkHRESULT.cpp b/src/utils/win/SkHRESULT.cpp
index 495f074..0aea4a6 100644
--- a/src/utils/win/SkHRESULT.cpp
+++ b/src/utils/win/SkHRESULT.cpp
@@ -10,7 +10,7 @@
 #include "SkHRESULT.h"
 
 void SkTraceHR(const char* file, unsigned long line, HRESULT hr, const char* msg) {
-    if (NULL != msg) {
+    if (msg) {
         SkDebugf("%s\n", msg);
     }
     SkDebugf("%s(%lu) : error 0x%x: ", file, line, hr);
diff --git a/src/utils/win/SkIStream.cpp b/src/utils/win/SkIStream.cpp
index 74d814c..6274e71 100644
--- a/src/utils/win/SkIStream.cpp
+++ b/src/utils/win/SkIStream.cpp
@@ -113,7 +113,7 @@
 }
 
 SkIStream::~SkIStream() {
-    if (NULL != this->fSkStream && fUnrefOnRelease) {
+    if (this->fSkStream && fUnrefOnRelease) {
         this->fSkStream->unref();
     }
 }
@@ -196,7 +196,7 @@
         break;
     }
 
-    if (NULL != lpNewFilePointer) {
+    if (lpNewFilePointer) {
         lpNewFilePointer->QuadPart = this->fLocation.QuadPart;
     }
     return hr;
@@ -228,7 +228,7 @@
 { }
 
 SkWIStream::~SkWIStream() {
-    if (NULL != this->fSkWStream) {
+    if (this->fSkWStream) {
         this->fSkWStream->flush();
     }
 }
diff --git a/src/utils/win/SkWGL_win.cpp b/src/utils/win/SkWGL_win.cpp
index 3b1966d..5c46138 100644
--- a/src/utils/win/SkWGL_win.cpp
+++ b/src/utils/win/SkWGL_win.cpp
@@ -75,6 +75,30 @@
     return fCreateContextAttribs(hDC, hShareContext, attribList);
 }
 
+BOOL SkWGLExtensions::swapInterval(int interval) const {
+    return fSwapInterval(interval);
+}
+
+HPBUFFER SkWGLExtensions::createPbuffer(HDC hDC,
+                                        int iPixelFormat,
+                                        int iWidth,
+                                        int iHeight,
+                                        const int *piAttribList) const {
+    return fCreatePbuffer(hDC, iPixelFormat, iWidth, iHeight, piAttribList);
+}
+
+HDC SkWGLExtensions::getPbufferDC(HPBUFFER hPbuffer) const {
+    return fGetPbufferDC(hPbuffer);
+}
+
+int SkWGLExtensions::releasePbufferDC(HPBUFFER hPbuffer, HDC hDC) const {
+    return fReleasePbufferDC(hPbuffer, hDC);
+}
+
+BOOL SkWGLExtensions::destroyPbuffer(HPBUFFER hPbuffer) const {
+    return fDestroyPbuffer(hPbuffer);
+}
+
 namespace {
 
 struct PixelFormat {
@@ -98,7 +122,7 @@
 int SkWGLExtensions::selectFormat(const int formats[],
                                   int formatCount,
                                   HDC dc,
-                                  int desiredSampleCount) {
+                                  int desiredSampleCount) const {
     PixelFormat desiredFormat = {
         0,
         desiredSampleCount,
@@ -207,7 +231,13 @@
     , fChoosePixelFormat(NULL)
     , fGetPixelFormatAttribfv(NULL)
     , fGetPixelFormatAttribiv(NULL)
-    , fCreateContextAttribs(NULL) {
+    , fCreateContextAttribs(NULL)
+    , fSwapInterval(NULL)
+    , fCreatePbuffer(NULL)
+    , fGetPbufferDC(NULL)
+    , fReleasePbufferDC(NULL)
+    , fDestroyPbuffer(NULL)
+ {
     HDC prevDC = wglGetCurrentDC();
     HGLRC prevGLRC = wglGetCurrentContext();
 
@@ -236,6 +266,11 @@
         GET_PROC(GetPixelFormatAttribiv, ARB);
         GET_PROC(GetPixelFormatAttribfv, ARB);
         GET_PROC(CreateContextAttribs, ARB);
+        GET_PROC(SwapInterval, EXT);
+        GET_PROC(CreatePbuffer, ARB);
+        GET_PROC(GetPbufferDC, ARB);
+        GET_PROC(ReleasePbufferDC, ARB);
+        GET_PROC(DestroyPbuffer, ARB);
 
         wglMakeCurrent(dummyDC, NULL);
         wglDeleteContext(dummyGLRC);
@@ -245,21 +280,14 @@
     wglMakeCurrent(prevDC, prevGLRC);
 }
 
-HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool preferCoreProfile) {
-    SkWGLExtensions extensions;
-    if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
-        return NULL;
-    }
+///////////////////////////////////////////////////////////////////////////////
 
-    HDC prevDC = wglGetCurrentDC();
-    HGLRC prevGLRC = wglGetCurrentContext();
-    PIXELFORMATDESCRIPTOR pfd;
-
-    int format = 0;
-
-    static const int iAttrs[] = {
+static void get_pixel_formats_to_try(HDC dc, const SkWGLExtensions& extensions,
+                                     bool doubleBuffered, int msaaSampleCount,
+                                     int formatsToTry[2]) {
+    int iAttrs[] = {
         SK_WGL_DRAW_TO_WINDOW, TRUE,
-        SK_WGL_DOUBLE_BUFFER, TRUE,
+        SK_WGL_DOUBLE_BUFFER, (doubleBuffered ? TRUE : FALSE),
         SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION,
         SK_WGL_SUPPORT_OPENGL, TRUE,
         SK_WGL_COLOR_BITS, 24,
@@ -270,6 +298,7 @@
 
     float fAttrs[] = {0, 0};
 
+    // Get a MSAA format if requested and possible.
     if (msaaSampleCount > 0 &&
         extensions.hasExtension(dc, "WGL_ARB_multisample")) {
         static const int kIAttrsCount = SK_ARRAY_COUNT(iAttrs);
@@ -287,47 +316,60 @@
         int formats[64];
         extensions.choosePixelFormat(dc, msaaIAttrs, fAttrs, 64, formats, &num);
         num = SkTMin(num, 64U);
-        int formatToTry = extensions.selectFormat(formats,
-                                                  num,
-                                                  dc,
-                                                  msaaSampleCount);
-        DescribePixelFormat(dc, formatToTry, sizeof(pfd), &pfd);
-        if (SetPixelFormat(dc, formatToTry, &pfd)) {
-            format = formatToTry;
-        }
+        formatsToTry[0] = extensions.selectFormat(formats, num, dc, msaaSampleCount);
     }
 
-    if (0 == format) {
-        // Either MSAA wasn't requested or creation failed
-        unsigned int num;
-        extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, &format, &num);
-        DescribePixelFormat(dc, format, sizeof(pfd), &pfd);
-        SkDEBUGCODE(BOOL set =) SetPixelFormat(dc, format, &pfd);
-        SkASSERT(TRUE == set);
-    }
+    // Get a non-MSAA format
+    int* format = -1 == formatsToTry[0] ? &formatsToTry[0] : &formatsToTry[1];
+    unsigned int num;
+    extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, format, &num);
+}
+
+static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextRequest contextType) {
+    HDC prevDC = wglGetCurrentDC();
+    HGLRC prevGLRC = wglGetCurrentContext();
 
     HGLRC glrc = NULL;
-    if (preferCoreProfile && extensions.hasExtension(dc, "WGL_ARB_create_context")) {
-        static const int kCoreGLVersions[] = {
-            4, 3,
-            4, 2,
-            4, 1,
-            4, 0,
-            3, 3,
-            3, 2,
-        };
-        int coreProfileAttribs[] = {
-            SK_WGL_CONTEXT_MAJOR_VERSION, -1,
-            SK_WGL_CONTEXT_MINOR_VERSION, -1,
-            SK_WGL_CONTEXT_PROFILE_MASK,  SK_WGL_CONTEXT_CORE_PROFILE_BIT,
+    if (kGLES_SkWGLContextRequest == contextType) {
+        if (!extensions.hasExtension(dc, "WGL_EXT_create_context_es2_profile")) {
+            wglMakeCurrent(prevDC, prevGLRC);
+            return NULL;
+        }
+        static const int glesAttribs[] = {
+            SK_WGL_CONTEXT_MAJOR_VERSION, 3,
+            SK_WGL_CONTEXT_MINOR_VERSION, 0,
+            SK_WGL_CONTEXT_PROFILE_MASK,  SK_WGL_CONTEXT_ES2_PROFILE_BIT,
             0,
         };
-        for (int v = 0; v < SK_ARRAY_COUNT(kCoreGLVersions) / 2; ++v) {
-            coreProfileAttribs[1] = kCoreGLVersions[2 * v];
-            coreProfileAttribs[3] = kCoreGLVersions[2 * v + 1];
-            glrc = extensions.createContextAttribs(dc, NULL, coreProfileAttribs);
-            if (NULL != glrc) {
-                break;
+        glrc = extensions.createContextAttribs(dc, NULL, glesAttribs);
+        if (NULL == glrc) {
+            wglMakeCurrent(prevDC, prevGLRC);
+            return NULL;
+        }
+    } else {
+        if (kGLPreferCoreProfile_SkWGLContextRequest == contextType &&
+            extensions.hasExtension(dc, "WGL_ARB_create_context")) {
+            static const int kCoreGLVersions[] = {
+                4, 3,
+                4, 2,
+                4, 1,
+                4, 0,
+                3, 3,
+                3, 2,
+            };
+            int coreProfileAttribs[] = {
+                SK_WGL_CONTEXT_MAJOR_VERSION, -1,
+                SK_WGL_CONTEXT_MINOR_VERSION, -1,
+                SK_WGL_CONTEXT_PROFILE_MASK,  SK_WGL_CONTEXT_CORE_PROFILE_BIT,
+                0,
+            };
+            for (int v = 0; v < SK_ARRAY_COUNT(kCoreGLVersions) / 2; ++v) {
+                coreProfileAttribs[1] = kCoreGLVersions[2 * v];
+                coreProfileAttribs[3] = kCoreGLVersions[2 * v + 1];
+                glrc = extensions.createContextAttribs(dc, NULL, coreProfileAttribs);
+                if (glrc) {
+                    break;
+                }
             }
         }
     }
@@ -338,5 +380,78 @@
     SkASSERT(glrc);
 
     wglMakeCurrent(prevDC, prevGLRC);
+
+    // This might help make the context non-vsynced.
+    if (extensions.hasExtension(dc, "WGL_EXT_swap_control")) {
+        extensions.swapInterval(-1);
+    }
     return glrc;
 }
+
+HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, SkWGLContextRequest contextType) {
+    SkWGLExtensions extensions;
+    if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
+        return NULL;
+    }
+
+    BOOL set = FALSE;
+
+    int pixelFormatsToTry[] = { -1, -1 };
+    get_pixel_formats_to_try(dc, extensions, true, msaaSampleCount, pixelFormatsToTry);
+    for (int f = 0;
+         !set && -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsToTry);
+         ++f) {
+        PIXELFORMATDESCRIPTOR pfd;
+        DescribePixelFormat(dc, pixelFormatsToTry[f], sizeof(pfd), &pfd);
+        set = SetPixelFormat(dc, pixelFormatsToTry[f], &pfd);
+    }
+
+    if (!set) {
+        return NULL;
+    }
+
+    return create_gl_context(dc, extensions, contextType);}
+
+SkWGLPbufferContext* SkWGLPbufferContext::Create(HDC parentDC, int msaaSampleCount,
+                                                 SkWGLContextRequest contextType) {
+    SkWGLExtensions extensions;
+    if (!extensions.hasExtension(parentDC, "WGL_ARB_pixel_format") ||
+        !extensions.hasExtension(parentDC, "WGL_ARB_pbuffer")) {
+        return NULL;
+    }
+
+    // try for single buffer first
+    for (int dblBuffer = 0; dblBuffer < 2; ++dblBuffer) {
+        int pixelFormatsToTry[] = { -1, -1 };
+        get_pixel_formats_to_try(parentDC, extensions, (0 != dblBuffer), msaaSampleCount,
+                                 pixelFormatsToTry);
+        for (int f = 0; -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsToTry); ++f) {
+            HPBUFFER pbuf = extensions.createPbuffer(parentDC, pixelFormatsToTry[f], 1, 1, NULL);
+            if (0 != pbuf) {
+                HDC dc = extensions.getPbufferDC(pbuf);
+                if (dc) {
+                    HGLRC glrc = create_gl_context(dc, extensions, contextType);
+                    if (glrc) {
+                        return SkNEW_ARGS(SkWGLPbufferContext, (pbuf, dc, glrc));
+                    }
+                    extensions.releasePbufferDC(pbuf, dc);
+                }
+                extensions.destroyPbuffer(pbuf);
+            }
+        }
+    }
+    return NULL;
+}
+
+SkWGLPbufferContext::~SkWGLPbufferContext() {
+    SkASSERT(fExtensions.hasExtension(fDC, "WGL_ARB_pbuffer"));
+    wglDeleteContext(fGLRC);
+    fExtensions.releasePbufferDC(fPbuffer, fDC);
+    fExtensions.destroyPbuffer(fPbuffer);
+}
+
+SkWGLPbufferContext::SkWGLPbufferContext(HPBUFFER pbuffer, HDC dc, HGLRC glrc)
+    : fPbuffer(pbuffer)
+    , fDC(dc)
+    , fGLRC(glrc) {
+}
diff --git a/src/views/SkOSMenu.cpp b/src/views/SkOSMenu.cpp
index 3de0a9e..ad0c73f 100644
--- a/src/views/SkOSMenu.cpp
+++ b/src/views/SkOSMenu.cpp
@@ -32,7 +32,7 @@
 }
 
 void SkOSMenu::getItems(const SkOSMenu::Item* items[]) const {
-    if (NULL != items) {
+    if (items) {
         for (int i = 0; i < fItems.count(); ++i) {
             items[i] = fItems[i];
         }
@@ -204,7 +204,7 @@
 }
 
 bool SkOSMenu::FindListItems(const SkEvent& evt, SkString items[]) {
-    if (evt.isType(gMenuEventType) && NULL != items) {
+    if (evt.isType(gMenuEventType) && items) {
         const char* text = evt.findString(gList_Items_Str);
         if (text != NULL) {
             SkString temp(text);
diff --git a/src/views/SkTextBox.cpp b/src/views/SkTextBox.cpp
index b0a42cd..55d75a6 100644
--- a/src/views/SkTextBox.cpp
+++ b/src/views/SkTextBox.cpp
@@ -167,7 +167,7 @@
 
 void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPaint& paint)
 {
-    SkASSERT(canvas && &paint && (text || len == 0));
+    SkASSERT(canvas && (text || len == 0));
 
     SkScalar marginWidth = fBox.width();
 
diff --git a/src/views/SkTouchGesture.cpp b/src/views/SkTouchGesture.cpp
index 9b02417..e6a8eae 100644
--- a/src/views/SkTouchGesture.cpp
+++ b/src/views/SkTouchGesture.cpp
@@ -203,7 +203,9 @@
 void SkTouchGesture::touchMoved(void* owner, float x, float y) {
 //    GrPrintf("--- %d touchMoved %p %g %g\n", fTouches.count(), owner, x, y);
 
-    SkASSERT(kEmpty_State != fState);
+    if (kEmpty_State == fState) {
+        return;
+    }
 
     int index = this->findRec(owner);
     if (index < 0) {
diff --git a/src/views/SkView.cpp b/src/views/SkView.cpp
index f211ad9..0070201 100644
--- a/src/views/SkView.cpp
+++ b/src/views/SkView.cpp
@@ -637,7 +637,7 @@
 {
     SkASSERT(this);
 
-    if (NULL != local) {
+    if (local) {
         SkMatrix m;
         this->localToGlobal(&m);
         if (!m.invert(&m)) {
diff --git a/src/views/SkViewPriv.cpp b/src/views/SkViewPriv.cpp
index 048ff08..6d90814 100644
--- a/src/views/SkViewPriv.cpp
+++ b/src/views/SkViewPriv.cpp
@@ -17,7 +17,7 @@
 
 void SkView::Artist::inflate(const SkDOM& dom, const SkDOM::Node* node)
 {
-    SkASSERT(&dom && node);
+    SkASSERT(node);
     this->onInflate(dom, node);
 }
 
@@ -63,7 +63,7 @@
 
 void SkView::Layout::inflate(const SkDOM& dom, const SkDOM::Node* node)
 {
-    SkASSERT(&dom && node);
+    SkASSERT(node);
     this->onInflate(dom, node);
 }
 
diff --git a/src/views/SkWindow.cpp b/src/views/SkWindow.cpp
index 99c2d30..90ef280 100644
--- a/src/views/SkWindow.cpp
+++ b/src/views/SkWindow.cpp
@@ -1,14 +1,14 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "SkWindow.h"
 #include "SkCanvas.h"
-#include "SkDevice.h"
 #include "SkOSMenu.h"
+#include "SkSurface.h"
 #include "SkSystemEventTypes.h"
 #include "SkTime.h"
 
@@ -32,8 +32,9 @@
     fMenus.deleteAll();
 }
 
-SkCanvas* SkWindow::createCanvas() {
-    return new SkCanvas(this->getBitmap());
+SkSurface* SkWindow::createSurface() {
+    const SkBitmap& bm = this->getBitmap();
+    return SkSurface::NewRasterDirect(bm.info(), bm.getPixels(), bm.rowBytes());
 }
 
 void SkWindow::setMatrix(const SkMatrix& matrix) {
@@ -126,7 +127,8 @@
         bm.setPixels(buffer);
 #endif
 
-        SkAutoTUnref<SkCanvas> canvas(this->createCanvas());
+        SkAutoTUnref<SkSurface> surface(this->createSurface());
+        SkCanvas* canvas = surface->getCanvas();
 
         canvas->clipRegion(fDirtyRgn);
         if (updateArea)
diff --git a/src/views/mac/SkNSView.mm b/src/views/mac/SkNSView.mm
index 80bfd67..6714167 100644
--- a/src/views/mac/SkNSView.mm
+++ b/src/views/mac/SkNSView.mm
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
@@ -8,6 +7,7 @@
 
 #import "SkNSView.h"
 #include "SkCanvas.h"
+#include "SkSurface.h"
 #include "SkCGUtils.h"
 #include "SkEvent.h"
 SK_COMPILE_ASSERT(SK_SUPPORT_GPU, not_implemented_for_non_gpu_build);
@@ -50,7 +50,7 @@
                                           selector:@selector(backingPropertiesChanged:)
                                           name:@"NSWindowDidChangeBackingPropertiesNotification"
                                           object:[self window]];
-    if (NULL != fWind) {
+    if (fWind) {
         fWind->setVisibleP(true);
         NSSize size = self.frame.size;
 #if RETINA_API_AVAILABLE
@@ -103,12 +103,9 @@
 #if RETINA_API_AVAILABLE
     newSize = [self convertSizeToBacking:newSize];
 #endif
-    if (NULL != fWind &&
-            (fWind->width()  != newSize.width ||
-             fWind->height() != newSize.height))
-    {
+    if (fWind && (fWind->width()  != newSize.width || fWind->height() != newSize.height)) {
         fWind->resize((int) newSize.width, (int) newSize.height);
-        if (NULL != fGLContext) {
+        if (fGLContext) {
             glClear(GL_STENCIL_BUFFER_BIT);
             [fGLContext update];
         }
@@ -131,9 +128,9 @@
 
 - (void)drawSkia {
     fRedrawRequestPending = false;
-    if (NULL != fWind) {
-        SkAutoTUnref<SkCanvas> canvas(fWind->createCanvas());
-        fWind->draw(canvas);
+    if (fWind) {
+        SkAutoTUnref<SkSurface> surface(fWind->createSurface());
+        fWind->draw(surface->getCanvas());
 #ifdef FORCE_REDRAW
         fWind->inval(NULL);
 #endif
@@ -268,7 +265,7 @@
     NSPoint p = [event locationInWindow];
     unsigned modi = convertNSModifiersToSk([event modifierFlags]);
 
-    if ([self mouse:p inRect:[self bounds]] && NULL != fWind) {
+    if ([self mouse:p inRect:[self bounds]] && fWind) {
         NSPoint loc = [self convertPoint:p fromView:nil];
 #if RETINA_API_AVAILABLE
         loc = [self convertPointToBacking:loc]; //y-up
@@ -283,7 +280,7 @@
     NSPoint p = [event locationInWindow];
     unsigned modi = convertNSModifiersToSk([event modifierFlags]);
 
-    if ([self mouse:p inRect:[self bounds]] && NULL != fWind) {
+    if ([self mouse:p inRect:[self bounds]] && fWind) {
         NSPoint loc = [self convertPoint:p fromView:nil];
 #if RETINA_API_AVAILABLE
         loc = [self convertPointToBacking:loc]; //y-up
@@ -298,7 +295,7 @@
     NSPoint p = [event locationInWindow];
     unsigned modi = convertNSModifiersToSk([event modifierFlags]);
     
-    if ([self mouse:p inRect:[self bounds]] && NULL != fWind) {
+    if ([self mouse:p inRect:[self bounds]] && fWind) {
         NSPoint loc = [self convertPoint:p fromView:nil];
 #if RETINA_API_AVAILABLE
         loc = [self convertPointToBacking:loc]; //y-up
@@ -313,7 +310,7 @@
     NSPoint p = [event locationInWindow];
     unsigned modi = convertNSModifiersToSk([event modifierFlags]);
     
-    if ([self mouse:p inRect:[self bounds]] && NULL != fWind) {
+    if ([self mouse:p inRect:[self bounds]] && fWind) {
         NSPoint loc = [self convertPoint:p fromView:nil];
 #if RETINA_API_AVAILABLE
         loc = [self convertPointToBacking:loc]; //y-up
diff --git a/src/views/unix/SkOSWindow_Unix.cpp b/src/views/unix/SkOSWindow_Unix.cpp
index 078a9f9..e22377a 100644
--- a/src/views/unix/SkOSWindow_Unix.cpp
+++ b/src/views/unix/SkOSWindow_Unix.cpp
@@ -46,9 +46,9 @@
 }
 
 void SkOSWindow::closeWindow() {
-    if (NULL != fUnixWindow.fDisplay) {
+    if (fUnixWindow.fDisplay) {
         this->detach();
-        SkASSERT(NULL != fUnixWindow.fGc);
+        SkASSERT(fUnixWindow.fGc);
         XFreeGC(fUnixWindow.fDisplay, fUnixWindow.fGc);
         fUnixWindow.fGc = NULL;
         XDestroyWindow(fUnixWindow.fDisplay, fUnixWindow.fWin);
@@ -64,9 +64,9 @@
         this->closeWindow();
     }
     // presence of fDisplay means we already have a window
-    if (NULL != fUnixWindow.fDisplay) {
-        if (NULL != info) {
-            if (NULL != fVi) {
+    if (fUnixWindow.fDisplay) {
+        if (info) {
+            if (fVi) {
                 glXGetConfig(fUnixWindow.fDisplay, fVi, GLX_SAMPLES_ARB, &info->fSampleCount);
                 glXGetConfig(fUnixWindow.fDisplay, fVi, GLX_STENCIL_SIZE, &info->fStencilBits);
             } else {
@@ -110,7 +110,7 @@
     }
 
     if (fVi) {
-        if (NULL != info) {
+        if (info) {
             glXGetConfig(dsp, fVi, GLX_SAMPLES_ARB, &info->fSampleCount);
             glXGetConfig(dsp, fVi, GLX_STENCIL_SIZE, &info->fStencilBits);
         }
@@ -132,7 +132,7 @@
                                          CWEventMask | CWColormap,
                                          &swa);
     } else {
-        if (NULL != info) {
+        if (info) {
             info->fSampleCount = 0;
             info->fStencilBits = 0;
         }
@@ -200,11 +200,13 @@
     return true;
 }
 
+static Atom wm_delete_window_message;
+
 SkOSWindow::NextXEventResult SkOSWindow::nextXEvent() {
     XEvent evt;
     Display* dsp = fUnixWindow.fDisplay;
 
-    if (!MyXNextEventWithDelay(fUnixWindow.fDisplay, &evt)) {
+    if (!MyXNextEventWithDelay(dsp, &evt)) {
         return kContinue_NextXEventResult;
     }
 
@@ -248,6 +250,11 @@
         case KeyRelease:
             this->handleKeyUp(XKeyToSkKey(XkbKeycodeToKeysym(dsp, evt.xkey.keycode, 0, 0)));
             break;
+        case ClientMessage:
+            if ((Atom)evt.xclient.data.l[0] == wm_delete_window_message) {
+                return kQuitRequest_NextXEventResult;
+            }
+            // fallthrough
         default:
             // Do nothing for other events
             break;
@@ -262,6 +269,9 @@
     }
     Window win = fUnixWindow.fWin;
 
+    wm_delete_window_message = XInternAtom(dsp, "WM_DELETE_WINDOW", False);
+    XSetWMProtocols(dsp, win, &wm_delete_window_message, 1);
+
     XSelectInput(dsp, win, EVENT_MASK);
 
     bool sentExposeEvent = false;
@@ -300,7 +310,7 @@
 }
 
 void SkOSWindow::mapWindowAndWait() {
-    SkASSERT(NULL != fUnixWindow.fDisplay);
+    SkASSERT(fUnixWindow.fDisplay);
     Display* dsp = fUnixWindow.fDisplay;
     Window win = fUnixWindow.fWin;
     XMapWindow(dsp, win);
@@ -323,7 +333,7 @@
         return false;
     }
     if (NULL == fUnixWindow.fGLContext) {
-        SkASSERT(NULL != fVi);
+        SkASSERT(fVi);
 
         fUnixWindow.fGLContext = glXCreateContext(fUnixWindow.fDisplay,
                                                   fVi,
@@ -355,7 +365,7 @@
 }
 
 void SkOSWindow::present() {
-    if (NULL != fUnixWindow.fDisplay && NULL != fUnixWindow.fGLContext) {
+    if (fUnixWindow.fDisplay && fUnixWindow.fGLContext) {
         glXSwapBuffers(fUnixWindow.fDisplay, fUnixWindow.fWin);
     }
 }
@@ -395,7 +405,7 @@
         return;
     }
     // If we are drawing with GL, we don't need XPutImage.
-    if (NULL != fUnixWindow.fGLContext) {
+    if (fUnixWindow.fGLContext) {
         return;
     }
     // Draw the bitmap to the screen.
diff --git a/src/views/win/SkOSWindow_win.cpp b/src/views/win/SkOSWindow_win.cpp
index 027bc66..447a5af 100644
--- a/src/views/win/SkOSWindow_win.cpp
+++ b/src/views/win/SkOSWindow_win.cpp
@@ -60,7 +60,7 @@
 
 SkOSWindow::~SkOSWindow() {
 #if SK_SUPPORT_GPU
-    if (NULL != fHGLRC) {
+    if (fHGLRC) {
         wglDeleteContext((HGLRC)fHGLRC);
     }
 #if SK_ANGLE
@@ -331,7 +331,8 @@
 bool SkOSWindow::attachGL(int msaaSampleCount, AttachmentInfo* info) {
     HDC dc = GetDC((HWND)fHWND);
     if (NULL == fHGLRC) {
-        fHGLRC = SkCreateWGLContext(dc, msaaSampleCount, false);
+        fHGLRC = SkCreateWGLContext(dc, msaaSampleCount,
+                kGLPreferCompatibilityProfile_SkWGLContextRequest);
         if (NULL == fHGLRC) {
             return false;
         }
diff --git a/src/views/win/skia_win.cpp b/src/views/win/skia_win.cpp
index 72ff54f..e2f0fda 100644
--- a/src/views/win/skia_win.cpp
+++ b/src/views/win/skia_win.cpp
@@ -100,7 +100,7 @@
 char* tchar_to_utf8(const TCHAR* str) {
 #ifdef _UNICODE
     int size = WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), NULL, 0, NULL, NULL);
-    char* str8 = (char*) malloc(size+1);
+    char* str8 = (char*) sk_malloc_throw(size+1);
     WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), str8, size, NULL, NULL);
     str8[size] = '\0';
     return str8;
@@ -150,7 +150,7 @@
 
    gSkWind = create_sk_window(hWnd, argc, argv);
    for (int i = 0; i < argc; ++i) {
-      free(argv[i]);
+      sk_free(argv[i]);
    }
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
diff --git a/tests/AAClipTest.cpp b/tests/AAClipTest.cpp
index 26c1ec1..64e3784 100644
--- a/tests/AAClipTest.cpp
+++ b/tests/AAClipTest.cpp
@@ -318,6 +318,30 @@
     }
 }
 
+static void test_really_a_rect(skiatest::Reporter* reporter) {
+    SkRRect rrect;
+    rrect.setRectXY(SkRect::MakeWH(100, 100), 5, 5);
+
+    SkPath path;
+    path.addRRect(rrect);
+
+    SkAAClip clip;
+    clip.setPath(path);
+
+    REPORTER_ASSERT(reporter, clip.getBounds() == SkIRect::MakeWH(100, 100));
+    REPORTER_ASSERT(reporter, !clip.isRect());
+
+    // This rect should intersect the clip, but slice-out all of the "soft" parts,
+    // leaving just a rect.
+    const SkIRect ir = SkIRect::MakeLTRB(10, -10, 50, 90);
+    
+    clip.op(ir, SkRegion::kIntersect_Op);
+
+    REPORTER_ASSERT(reporter, clip.getBounds() == SkIRect::MakeLTRB(10, 0, 50, 90));
+    // the clip recognized that that it is just a rect!
+    REPORTER_ASSERT(reporter, clip.isRect());
+}
+
 #include "SkRasterClip.h"
 
 static void copyToMask(const SkRasterClip& rc, SkMask* mask) {
@@ -347,6 +371,7 @@
 
 static void did_dx_affect(skiatest::Reporter* reporter, const SkScalar dx[],
                           size_t count, bool changed) {
+    const SkISize baseSize = SkISize::Make(10, 10);
     SkIRect ir = { 0, 0, 10, 10 };
 
     for (size_t i = 0; i < count; ++i) {
@@ -357,11 +382,11 @@
         SkRasterClip rc1(ir);
         SkRasterClip rc2(ir);
 
-        rc0.op(r, SkRegion::kIntersect_Op, false);
+        rc0.op(r, baseSize, SkRegion::kIntersect_Op, false);
         r.offset(dx[i], 0);
-        rc1.op(r, SkRegion::kIntersect_Op, true);
+        rc1.op(r, baseSize, SkRegion::kIntersect_Op, true);
         r.offset(-2*dx[i], 0);
-        rc2.op(r, SkRegion::kIntersect_Op, true);
+        rc2.op(r, baseSize, SkRegion::kIntersect_Op, true);
 
         REPORTER_ASSERT(reporter, changed != (rc0 == rc1));
         REPORTER_ASSERT(reporter, changed != (rc0 == rc2));
@@ -404,4 +429,5 @@
     test_path_with_hole(reporter);
     test_regressions();
     test_nearly_integral(reporter);
+    test_really_a_rect(reporter);
 }
diff --git a/tests/ARGBImageEncoderTest.cpp b/tests/ARGBImageEncoderTest.cpp
index 18f315f..4d16f4c 100644
--- a/tests/ARGBImageEncoderTest.cpp
+++ b/tests/ARGBImageEncoderTest.cpp
@@ -35,9 +35,8 @@
         // A bitmap that should generate the above bytes:
         SkBitmap bitmap;
         {
-            bool success = bitmap.allocPixels(SkImageInfo::Make(kWidth, kHeight,
-                                                        gColorTypes[ctIndex], kOpaque_SkAlphaType));
-            REPORTER_ASSERT(reporter, success);
+            bitmap.allocPixels(SkImageInfo::Make(kWidth, kHeight, gColorTypes[ctIndex],
+                                                 kOpaque_SkAlphaType));
             bitmap.eraseColor(SK_ColorBLUE);
             // Change rows [0,1] from blue to [red,green].
             SkCanvas canvas(bitmap);
diff --git a/tests/AndroidPaintTest.cpp b/tests/AndroidPaintTest.cpp
deleted file mode 100644
index 0fc2f9b..0000000
--- a/tests/AndroidPaintTest.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-// SkPaints only have an SkPaintOptionsAndroid if SK_BUILD_FOR_ANDROID is true.
-#ifdef SK_BUILD_FOR_ANDROID
-
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
-#include "SkPaint.h"
-#include "SkPaintOptionsAndroid.h"
-#include "Test.h"
-
-static size_t Reconstruct(const SkPaint& src, SkPaint* dst) {
-    SkWriteBuffer writer;
-    src.flatten(writer);
-
-    const size_t size = writer.bytesWritten();
-    SkAutoMalloc bytes(size);
-    writer.writeToMemory(bytes.get());
-
-    SkReadBuffer reader(bytes.get(), size);
-    dst->unflatten(reader);
-
-    return size;
-}
-
-DEF_TEST(AndroidOptionsSerialization, reporter) {
-    // We want to make sure that Android's paint options survive a flatten/unflatten round trip.
-    // These are all non-default options.
-    SkPaintOptionsAndroid options;
-    options.setLanguage("ja-JP");
-    options.setFontVariant(SkPaintOptionsAndroid::kElegant_Variant);
-    options.setUseFontFallbacks(true);
-
-    SkPaint paint;
-    paint.setPaintOptionsAndroid(options);
-
-    SkPaint reconstructed;
-    Reconstruct(paint, &reconstructed);
-
-    REPORTER_ASSERT(reporter, options == reconstructed.getPaintOptionsAndroid());
-}
-
-DEF_TEST(AndroidOptionsSerializationReverse, reporter) {
-    // Opposite test of above: make sure the serialized default values of a paint overwrite
-    // non-default values on the paint we're unflattening into.
-    const SkPaint defaultOptions;
-
-    SkPaintOptionsAndroid options;
-    options.setLanguage("ja-JP");
-    options.setFontVariant(SkPaintOptionsAndroid::kElegant_Variant);
-    options.setUseFontFallbacks(true);
-    SkPaint nonDefaultOptions;
-    nonDefaultOptions.setPaintOptionsAndroid(options);
-
-    Reconstruct(defaultOptions, &nonDefaultOptions);
-
-    REPORTER_ASSERT(reporter,
-            defaultOptions.getPaintOptionsAndroid() ==
-            nonDefaultOptions.getPaintOptionsAndroid());
-}
-
-DEF_TEST(AndroidOptionsSize, reporter) {
-    // A paint with default android options should serialize to something smaller than
-    // a paint with non-default android options.
-
-    SkPaint defaultOptions;
-
-    SkPaintOptionsAndroid options;
-    options.setUseFontFallbacks(true);
-    SkPaint nonDefaultOptions;
-    nonDefaultOptions.setPaintOptionsAndroid(options);
-
-    SkPaint dummy;
-
-    REPORTER_ASSERT(reporter,
-                    Reconstruct(defaultOptions, &dummy) < Reconstruct(nonDefaultOptions, &dummy));
-}
-
-#endif  // SK_BUILD_FOR_ANDROID
diff --git a/tests/BBoxHierarchyTest.cpp b/tests/BBoxHierarchyTest.cpp
index 662cc37..71b9699 100644
--- a/tests/BBoxHierarchyTest.cpp
+++ b/tests/BBoxHierarchyTest.cpp
@@ -7,33 +7,30 @@
 
 #include "Test.h"
 #include "SkRandom.h"
-#include "SkQuadTree.h"
 #include "SkRTree.h"
 #include "SkTSort.h"
 
 static const size_t RTREE_MIN_CHILDREN = 6;
 static const size_t RTREE_MAX_CHILDREN = 11;
-static const size_t QUADTREE_MIN_CHILDREN = 0;
-static const size_t QUADTREE_MAX_CHILDREN = 0; // No hard limit for quadtree
 
 static const int NUM_RECTS = 200;
 static const size_t NUM_ITERATIONS = 100;
 static const size_t NUM_QUERIES = 50;
 
-static const int MAX_SIZE = 1000;
+static const SkScalar MAX_SIZE = 1000.0f;
 
 struct DataRect {
-    SkIRect rect;
+    SkRect rect;
     void* data;
 };
 
-static SkIRect random_rect(SkRandom& rand) {
-    SkIRect rect = {0,0,0,0};
+static SkRect random_rect(SkRandom& rand) {
+    SkRect rect = {0,0,0,0};
     while (rect.isEmpty()) {
-        rect.fLeft   = rand.nextS() % MAX_SIZE;
-        rect.fRight  = rand.nextS() % MAX_SIZE;
-        rect.fTop    = rand.nextS() % MAX_SIZE;
-        rect.fBottom = rand.nextS() % MAX_SIZE;
+        rect.fLeft   = rand.nextRangeF(0, MAX_SIZE);
+        rect.fRight  = rand.nextRangeF(0, MAX_SIZE);
+        rect.fTop    = rand.nextRangeF(0, MAX_SIZE);
+        rect.fBottom = rand.nextRangeF(0, MAX_SIZE);
         rect.sort();
     }
     return rect;
@@ -46,12 +43,15 @@
     }
 }
 
-static bool verify_query(SkIRect query, DataRect rects[],
+static bool verify_query(SkRect query, DataRect rects[],
                          SkTDArray<void*>& found) {
+    // TODO(mtklein): no need to do this after everything's SkRects
+    query.roundOut();
+
     SkTDArray<void*> expected;
     // manually intersect with every rectangle
     for (int i = 0; i < NUM_RECTS; ++i) {
-        if (SkIRect::IntersectsNoEmptyCheck(query, rects[i].rect)) {
+        if (SkRect::Intersects(query, rects[i].rect)) {
             expected.push(rects[i].data);
         }
     }
@@ -76,7 +76,7 @@
                         SkBBoxHierarchy& tree) {
     for (size_t i = 0; i < NUM_QUERIES; ++i) {
         SkTDArray<void*> hits;
-        SkIRect query = random_rect(rand);
+        SkRect query = random_rect(rand);
         tree.search(query, &hits);
         REPORTER_ASSERT(reporter, verify_query(query, rects, hits));
     }
@@ -86,7 +86,7 @@
                            skiatest::Reporter* reporter) {
     DataRect rects[NUM_RECTS];
     SkRandom rand;
-    REPORTER_ASSERT(reporter, NULL != tree);
+    REPORTER_ASSERT(reporter, tree);
 
     int expectedDepthMin = -1;
     int expectedDepthMax = -1;
@@ -167,18 +167,4 @@
         SkAutoUnref auo(unsortedRtree);
         tree_test_main(unsortedRtree, RTREE_MIN_CHILDREN, RTREE_MAX_CHILDREN, reporter);
     }
-
-    // QuadTree
-    {
-        SkQuadTree* quadtree = SkNEW_ARGS(SkQuadTree, (
-            SkIRect::MakeLTRB(-MAX_SIZE, -MAX_SIZE, MAX_SIZE, MAX_SIZE)));
-        SkAutoUnref au(quadtree);
-        tree_test_main(quadtree, QUADTREE_MIN_CHILDREN, QUADTREE_MAX_CHILDREN, reporter);
-
-        // QuadTree that orders input rectangles on deferred insert.
-        SkQuadTree* unsortedQuadTree = SkNEW_ARGS(SkQuadTree, (
-            SkIRect::MakeLTRB(-MAX_SIZE, -MAX_SIZE, MAX_SIZE, MAX_SIZE)));
-        SkAutoUnref auo(unsortedQuadTree);
-        tree_test_main(unsortedQuadTree, QUADTREE_MIN_CHILDREN, QUADTREE_MAX_CHILDREN, reporter);
-    }
 }
diff --git a/tests/BitmapCopyTest.cpp b/tests/BitmapCopyTest.cpp
index 4a49a6b..3923846 100644
--- a/tests/BitmapCopyTest.cpp
+++ b/tests/BitmapCopyTest.cpp
@@ -387,14 +387,16 @@
                 ct = init_ctable(kPremul_SkAlphaType);
             }
 
+            int localSubW;
             if (isExtracted[copyCase]) { // A larger image to extract from.
-                src.allocPixels(SkImageInfo::Make(2 * subW + 1, subH,
-                                                  gPairs[i].fColorType,
-                                                  kPremul_SkAlphaType));
+                localSubW = 2 * subW + 1;
             } else { // Tests expect a 2x2 bitmap, so make smaller.
-                src.allocPixels(SkImageInfo::Make(subW, subH,
-                                                  gPairs[i].fColorType,
-                                                  kPremul_SkAlphaType));
+                localSubW = subW;
+            }
+            // could fail if we pass kIndex_8 for the colortype
+            if (src.tryAllocPixels(SkImageInfo::Make(localSubW, subH, gPairs[i].fColorType,
+                                                     kPremul_SkAlphaType))) {
+                // failure is fine, as we will notice later on
             }
             SkSafeUnref(ct);
 
@@ -607,8 +609,8 @@
     for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
         clear_4x4_pixels(dstPixels);
 
-        dstInfo.fWidth = gRec[i].fRequestedDstSize.width();
-        dstInfo.fHeight = gRec[i].fRequestedDstSize.height();
+        dstInfo = dstInfo.makeWH(gRec[i].fRequestedDstSize.width(),
+                                 gRec[i].fRequestedDstSize.height());
         bool success = srcBM.readPixels(dstInfo, dstPixels, rowBytes,
                                         gRec[i].fRequestedSrcLoc.x(), gRec[i].fRequestedSrcLoc.y());
         
diff --git a/tests/BitmapHasherTest.cpp b/tests/BitmapHasherTest.cpp
index e39439a..3b51706 100644
--- a/tests/BitmapHasherTest.cpp
+++ b/tests/BitmapHasherTest.cpp
@@ -17,8 +17,7 @@
 // Fill in bitmap with test data.
 static void CreateTestBitmap(SkBitmap* bitmap, int width, int height,
                              SkColor color, skiatest::Reporter* reporter) {
-    SkImageInfo info = SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType);
-    REPORTER_ASSERT(reporter, bitmap->allocPixels(info));
+    bitmap->allocN32Pixels(width, height, kOpaque_SkAlphaType);
     bitmap->eraseColor(color);
 }
 
diff --git a/tests/BitmapTest.cpp b/tests/BitmapTest.cpp
index ef560aa..ef69531 100644
--- a/tests/BitmapTest.cpp
+++ b/tests/BitmapTest.cpp
@@ -9,14 +9,49 @@
 
 #include "Test.h"
 
+static void test_allocpixels(skiatest::Reporter* reporter) {
+    const int width = 10;
+    const int height = 10;
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
+    const size_t explicitRowBytes = info.minRowBytes() + 24;
+
+    SkBitmap bm;
+    bm.setInfo(info);
+    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());
+    bm.allocPixels();
+    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());
+    bm.reset();
+    bm.allocPixels(info);
+    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());
+
+    bm.setInfo(info, explicitRowBytes);
+    REPORTER_ASSERT(reporter, explicitRowBytes == bm.rowBytes());
+    bm.allocPixels();
+    REPORTER_ASSERT(reporter, explicitRowBytes == bm.rowBytes());
+    bm.reset();
+    bm.allocPixels(info, explicitRowBytes);
+    REPORTER_ASSERT(reporter, explicitRowBytes == bm.rowBytes());
+
+    bm.reset();
+    bm.setInfo(info, 0);
+    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());
+    bm.reset();
+    bm.allocPixels(info, 0);
+    REPORTER_ASSERT(reporter, info.minRowBytes() == bm.rowBytes());
+
+    bm.reset();
+    bool success = bm.setInfo(info, info.minRowBytes() - 1);   // invalid for 32bit
+    REPORTER_ASSERT(reporter, !success);
+    REPORTER_ASSERT(reporter, bm.isNull());
+}
+
 static void test_bigwidth(skiatest::Reporter* reporter) {
     SkBitmap bm;
     int width = 1 << 29;    // *4 will be the high-bit of 32bit int
 
     SkImageInfo info = SkImageInfo::MakeA8(width, 1);
     REPORTER_ASSERT(reporter, bm.setInfo(info));
-    info.fColorType = kRGB_565_SkColorType;
-    REPORTER_ASSERT(reporter, bm.setInfo(info));
+    REPORTER_ASSERT(reporter, bm.setInfo(info.makeColorType(kRGB_565_SkColorType)));
 
     // for a 4-byte config, this width will compute a rowbytes of 0x80000000,
     // which does not fit in a int32_t. setConfig should detect this, and fail.
@@ -24,8 +59,7 @@
     // TODO: perhaps skia can relax this, and only require that rowBytes fit
     //       in a uint32_t (or larger), but for now this is the constraint.
 
-    info.fColorType = kN32_SkColorType;
-    REPORTER_ASSERT(reporter, !bm.setInfo(info));
+    REPORTER_ASSERT(reporter, !bm.setInfo(info.makeColorType(kN32_SkColorType)));
 }
 
 /**
@@ -39,11 +73,12 @@
             bool setConf = bm.setInfo(SkImageInfo::MakeN32Premul(width, height));
             REPORTER_ASSERT(reporter, setConf);
             if (setConf) {
-                REPORTER_ASSERT(reporter, bm.allocPixels(NULL));
+                bm.allocPixels();
             }
             REPORTER_ASSERT(reporter, SkToBool(width & height) != bm.empty());
         }
     }
 
     test_bigwidth(reporter);
+    test_allocpixels(reporter);
 }
diff --git a/tests/BlitRowTest.cpp b/tests/BlitRowTest.cpp
index 911f2a0..4689a30 100644
--- a/tests/BlitRowTest.cpp
+++ b/tests/BlitRowTest.cpp
@@ -212,7 +212,7 @@
                                          kPremul_SkAlphaType);
 
     for (size_t i = 0; i < SK_ARRAY_COUNT(gDstColorType); i++) {
-        info.fColorType = gDstColorType[i];
+        info = info.makeColorType(gDstColorType[i]);
 
         SkBitmap dstBM0, dstBM1;
         dstBM0.allocPixels(info);
diff --git a/tests/CachedDecodingPixelRefTest.cpp b/tests/CachedDecodingPixelRefTest.cpp
index 8de7da7..b3eb532 100644
--- a/tests/CachedDecodingPixelRefTest.cpp
+++ b/tests/CachedDecodingPixelRefTest.cpp
@@ -13,7 +13,7 @@
 #include "SkDiscardableMemoryPool.h"
 #include "SkImageDecoder.h"
 #include "SkImageGeneratorPriv.h"
-#include "SkScaledImageCache.h"
+#include "SkResourceCache.h"
 #include "SkStream.h"
 #include "SkUtils.h"
 
@@ -63,8 +63,8 @@
     if (b1.isNull() || b1.empty()) {
         return;
     }
-    REPORTER_ASSERT(reporter, NULL != b1.getPixels());
-    REPORTER_ASSERT(reporter, NULL != b2.getPixels());
+    REPORTER_ASSERT(reporter, b1.getPixels());
+    REPORTER_ASSERT(reporter, b2.getPixels());
     if ((!(b1.getPixels())) || (!(b2.getPixels()))) {
         return;
     }
@@ -122,7 +122,7 @@
         REPORTER_ASSERT(reporter, NULL == lazy.getPixels());
         {
             SkAutoLockPixels autoLockPixels(lazy);  // now pixels are good.
-            REPORTER_ASSERT(reporter, NULL != lazy.getPixels());
+            REPORTER_ASSERT(reporter, lazy.getPixels());
             if (NULL == lazy.getPixels()) {
                 continue;
             }
@@ -131,7 +131,7 @@
         REPORTER_ASSERT(reporter, NULL == lazy.getPixels());
         {
             SkAutoLockPixels autoLockPixels(lazy);  // now pixels are good.
-            REPORTER_ASSERT(reporter, NULL != lazy.getPixels());
+            REPORTER_ASSERT(reporter, lazy.getPixels());
             if (NULL == lazy.getPixels()) {
                 continue;
             }
@@ -175,7 +175,7 @@
     };
     static int Width() { return 10; }
     static int Height() { return 10; }
-    static SkColor Color() { return SK_ColorCYAN; }
+    static uint32_t Color() { return 0xff123456; }
     TestImageGenerator(TestType type, skiatest::Reporter* reporter)
         : fType(type), fReporter(reporter) {
         SkASSERT((fType <= kLast_TestType) && (fType >= 0));
@@ -184,32 +184,30 @@
 
 protected:
     virtual bool onGetInfo(SkImageInfo* info) SK_OVERRIDE {
-        REPORTER_ASSERT(fReporter, NULL != info);
+        REPORTER_ASSERT(fReporter, info);
         if ((NULL == info) || (kFailGetInfo_TestType == fType)) {
             return false;
         }
-        info->fWidth = TestImageGenerator::Width();
-        info->fHeight = TestImageGenerator::Height();
-        info->fColorType = kN32_SkColorType;
-        info->fAlphaType = kOpaque_SkAlphaType;
+        *info = SkImageInfo::MakeN32(TestImageGenerator::Width(),
+                                     TestImageGenerator::Height(),
+                                     kOpaque_SkAlphaType);
         return true;
     }
 
     virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
                              SkPMColor ctable[], int* ctableCount) SK_OVERRIDE {
         REPORTER_ASSERT(fReporter, pixels != NULL);
-        size_t minRowBytes
-            = static_cast<size_t>(info.fWidth * info.bytesPerPixel());
+        size_t minRowBytes = static_cast<size_t>(info.width() * info.bytesPerPixel());
         REPORTER_ASSERT(fReporter, rowBytes >= minRowBytes);
         if ((NULL == pixels)
             || (fType != kSucceedGetPixels_TestType)
-            || (info.fColorType != kN32_SkColorType)) {
+            || (info.colorType() != kN32_SkColorType)) {
             return false;
         }
         char* bytePtr = static_cast<char*>(pixels);
-        for (int y = 0; y < info.fHeight; ++y) {
+        for (int y = 0; y < info.height(); ++y) {
             sk_memset32(reinterpret_cast<SkColor*>(bytePtr),
-                        TestImageGenerator::Color(), info.fWidth);
+                        TestImageGenerator::Color(), info.width());
             bytePtr += rowBytes;
         }
         return true;
@@ -225,7 +223,7 @@
     REPORTER_ASSERT(reporter, TestImageGenerator::Width() == bm.width());
     REPORTER_ASSERT(reporter, TestImageGenerator::Height() == bm.height());
     SkAutoLockPixels autoLockPixels(bm);
-    REPORTER_ASSERT(reporter, NULL != bm.getPixels());
+    REPORTER_ASSERT(reporter, bm.getPixels());
     if (NULL == bm.getPixels()) {
         return;
     }
@@ -257,7 +255,7 @@
     SkBitmap lazy;
     bool success;
     if (kSkCaching_PixelRefType == pixelRefType) {
-        // Ignore factory; use global SkScaledImageCache.
+        // Ignore factory; use global cache.
         success = SkCachingPixelRef::Install(gen.detach(), &lazy);
     } else {
         success = SkInstallDiscardablePixelRef(gen.detach(), &lazy, factory);
@@ -322,3 +320,42 @@
     check_pixelref(TestImageGenerator::kSucceedGetPixels_TestType,
                    reporter, kSkDiscardable_PixelRefType, globalPool);
 }
+
+////////////////////////////////////////////////////////////////////////////////
+
+DEF_TEST(Image_NewFromGenerator, r) {
+    TestImageGenerator::TestType testTypes[] = {
+        TestImageGenerator::kFailGetInfo_TestType,
+        TestImageGenerator::kFailGetPixels_TestType,
+        TestImageGenerator::kSucceedGetPixels_TestType,
+    };
+    for (size_t i = 0; i < SK_ARRAY_COUNT(testTypes); ++i) {
+        TestImageGenerator::TestType test = testTypes[i];
+        SkImageGenerator* gen = SkNEW_ARGS(TestImageGenerator, (test, r));
+        SkAutoTUnref<SkImage> image(SkImage::NewFromGenerator(gen));
+        if (TestImageGenerator::kFailGetInfo_TestType == test) {
+            REPORTER_ASSERT(r, NULL == image.get());
+            continue;
+        }
+        if (NULL == image.get()) {
+            ERRORF(r, "SkImage::NewFromGenerator unexpecedly failed ["
+                   SK_SIZE_T_SPECIFIER "]", i);
+            continue;
+        }
+        REPORTER_ASSERT(r, TestImageGenerator::Width() == image->width());
+        REPORTER_ASSERT(r, TestImageGenerator::Height() == image->height());
+
+        SkBitmap bitmap;
+        bitmap.allocN32Pixels(TestImageGenerator::Width(), TestImageGenerator::Height());
+        SkCanvas canvas(bitmap);
+        const SkColor kDefaultColor = 0xffabcdef;
+        canvas.clear(kDefaultColor);
+        canvas.drawImage(image, 0, 0, NULL);
+        if (TestImageGenerator::kSucceedGetPixels_TestType == test) {
+            REPORTER_ASSERT(
+                    r, TestImageGenerator::Color() == *bitmap.getAddr32(0, 0));
+        } else {
+            REPORTER_ASSERT(r, kDefaultColor == bitmap.getColor(0,0));
+        }
+    }
+}
diff --git a/tests/CanvasStateHelpers.cpp b/tests/CanvasStateHelpers.cpp
new file mode 100644
index 0000000..96972b8
--- /dev/null
+++ b/tests/CanvasStateHelpers.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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 "CanvasStateHelpers.h"
+#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
+#include "SkCanvas.h"
+#include "SkCanvasStateUtils.h"
+#include "SkPaint.h"
+#include "SkRect.h"
+#include "SkRegion.h"
+
+void complex_layers_draw(SkCanvas* canvas, float left, float top,
+                         float right, float bottom, int32_t spacer) {
+    SkPaint bluePaint;
+    bluePaint.setColor(SK_ColorBLUE);
+    bluePaint.setStyle(SkPaint::kFill_Style);
+
+    SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
+    canvas->drawRect(rect, bluePaint);
+    canvas->translate(0, rect.height() + spacer);
+    canvas->drawRect(rect, bluePaint);
+}
+
+extern "C" bool complex_layers_draw_from_canvas_state(SkCanvasState* state,
+        float left, float top, float right, float bottom, int32_t spacer) {
+    SkCanvas* canvas = SkCanvasStateUtils::CreateFromCanvasState(state);
+    if (!canvas) {
+        return false;
+    }
+    complex_layers_draw(canvas, left, top, right, bottom, spacer);
+    canvas->unref();
+    return true;
+}
+
+void complex_clips_draw(SkCanvas* canvas, int32_t left, int32_t top,
+        int32_t right, int32_t bottom, int32_t clipOp, const SkRegion& localRegion) {
+    canvas->save();
+    SkRect clipRect = SkRect::MakeLTRB(SkIntToScalar(left), SkIntToScalar(top),
+                                       SkIntToScalar(right), SkIntToScalar(bottom));
+    canvas->clipRect(clipRect, (SkRegion::Op) clipOp);
+    canvas->drawColor(SK_ColorBLUE);
+    canvas->restore();
+
+    canvas->clipRegion(localRegion, (SkRegion::Op) clipOp);
+    canvas->drawColor(SK_ColorBLUE);
+}
+
+extern "C" bool complex_clips_draw_from_canvas_state(SkCanvasState* state,
+        int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t clipOp,
+        int32_t regionRects, int32_t* rectCoords) {
+    SkCanvas* canvas = SkCanvasStateUtils::CreateFromCanvasState(state);
+    if (!canvas) {
+        return false;
+    }
+
+    SkRegion localRegion;
+    for (int32_t i = 0; i < regionRects; ++i) {
+        localRegion.op(rectCoords[0], rectCoords[1], rectCoords[2], rectCoords[3],
+                       SkRegion::kUnion_Op);
+        rectCoords += 4;
+    }
+
+    complex_clips_draw(canvas, left, top, right, bottom, clipOp, localRegion);
+    canvas->unref();
+    return true;
+}
+#endif // SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
diff --git a/tests/CanvasStateHelpers.h b/tests/CanvasStateHelpers.h
new file mode 100644
index 0000000..aa3c178
--- /dev/null
+++ b/tests/CanvasStateHelpers.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef CanvasStateHelpers_DEFINED
+#define CanvasStateHelpers_DEFINED
+
+#include "SkTypes.h"
+
+#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
+class SkCanvas;
+class SkCanvasState;
+class SkRegion;
+
+/*
+ *  Helper function to perform drawing to an SkCanvas. Used by both
+ *  test_complex_layers and complex_layers_draw_from_canvas_state.
+ */
+void complex_layers_draw(SkCanvas* canvas, float left, float top,
+                         float right, float bottom, int32_t spacer);
+
+/*
+ *  Create an SkCanvas from state and draw to it. Return true on success.
+ *
+ *  Used by test_complex_layers test in CanvasStateTest. Marked as extern
+ *  so it can be called from a separate library.
+ */
+extern "C" bool complex_layers_draw_from_canvas_state(SkCanvasState* state,
+        float left, float top, float right, float bottom, int32_t spacer);
+
+/*
+ *  Helper function to perform drawing to an SkCanvas. Used both by test_complex_clips
+ *  and complex_clips_draw_from_canvas_state.
+ */
+void complex_clips_draw(SkCanvas* canvas, int32_t left, int32_t top,
+        int32_t right, int32_t bottom, int32_t clipOp, const SkRegion& localRegion);
+
+/*
+ *  Create an SkCanvas from state and draw to it. Return true on success.
+ *
+ *  Used by test_complex_clips test in CanvasStateTest. Marked as extern
+ *  so it can be called from a separate library.
+ */
+extern "C" bool complex_clips_draw_from_canvas_state(SkCanvasState* state,
+        int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t clipOp,
+        int32_t regionRects, int32_t* rectCoords);
+
+#endif // SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
+#endif // CanvasStateHelpers_DEFINED
diff --git a/tests/CanvasStateTest.cpp b/tests/CanvasStateTest.cpp
index 5c7e473..8364a4b 100644
--- a/tests/CanvasStateTest.cpp
+++ b/tests/CanvasStateTest.cpp
@@ -5,9 +5,10 @@
  * found in the LICENSE file.
  */
 
-#include "SkBitmapDevice.h"
+#include "CanvasStateHelpers.h"
 #include "SkCanvas.h"
 #include "SkCanvasStateUtils.h"
+#include "SkCommandLineFlags.h"
 #include "SkDrawFilter.h"
 #include "SkError.h"
 #include "SkPaint.h"
@@ -15,8 +16,48 @@
 #include "SkRect.h"
 #include "Test.h"
 
-static void test_complex_layers(skiatest::Reporter* reporter) {
+// dlopen and the library flag are only used for tests which require this flag.
 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
+#include <dlfcn.h>
+
+DEFINE_string(library, "", "Support library to use for CanvasState test. If empty (the default), "
+                           "the test will be run without crossing a library boundary. Otherwise, "
+                           "it is expected to be a full path to a shared library file, which will"
+                           " be dynamically loaded. Functions from the library will be called to "
+                           "test SkCanvasState. Instructions for generating the library are in "
+                           "gyp/canvas_state_lib.gyp");
+
+
+// This class calls dlopen on the library passed in to the command line flag library, and handles
+// calling dlclose when it goes out of scope.
+class OpenLibResult {
+public:
+    // If the flag library was passed to this run of the test, attempt to open it using dlopen and
+    // report whether it succeeded.
+    OpenLibResult(skiatest::Reporter* reporter) {
+        if (FLAGS_library.count() == 1) {
+            fHandle = dlopen(FLAGS_library[0], RTLD_LAZY | RTLD_LOCAL);
+            REPORTER_ASSERT_MESSAGE(reporter, fHandle != NULL, "Failed to open library!");
+        } else {
+            fHandle = NULL;
+        }
+    }
+
+    // Automatically call dlclose when going out of scope.
+    ~OpenLibResult() {
+        if (fHandle) {
+            dlclose(fHandle);
+        }
+    }
+
+    // Pointer to the shared library object.
+    void* handle() { return fHandle; }
+
+private:
+    void* fHandle;
+};
+
+DEF_TEST(CanvasState_test_complex_layers, reporter) {
     const int WIDTH = 400;
     const int HEIGHT = 400;
     const int SPACER = 10;
@@ -28,7 +69,6 @@
     const SkColorType colorTypes[] = {
         kRGB_565_SkColorType, kN32_SkColorType
     };
-    const int configCount = sizeof(colorTypes) / sizeof(SkBitmap::Config);
 
     const int layerAlpha[] = { 255, 255, 0 };
     const SkCanvas::SaveFlags flags[] = { SkCanvas::kARGB_NoClipLayer_SaveFlag,
@@ -36,9 +76,24 @@
                                           SkCanvas::kARGB_NoClipLayer_SaveFlag
     };
     REPORTER_ASSERT(reporter, sizeof(layerAlpha) == sizeof(flags));
-    const int layerCombinations = sizeof(layerAlpha) / sizeof(int);
 
-    for (int i = 0; i < configCount; ++i) {
+    bool (*drawFn)(SkCanvasState* state, float l, float t,
+                   float r, float b, int32_t s);
+
+    OpenLibResult openLibResult(reporter);
+    if (openLibResult.handle() != NULL) {
+        *(void**) (&drawFn) = dlsym(openLibResult.handle(),
+                                    "complex_layers_draw_from_canvas_state");
+    } else {
+        drawFn = complex_layers_draw_from_canvas_state;
+    }
+
+    REPORTER_ASSERT(reporter, drawFn);
+    if (!drawFn) {
+        return;
+    }
+
+    for (size_t i = 0; i < SK_ARRAY_COUNT(colorTypes); ++i) {
         SkBitmap bitmaps[2];
         for (int j = 0; j < 2; ++j) {
             bitmaps[j].allocPixels(SkImageInfo::Make(WIDTH, HEIGHT,
@@ -49,32 +104,28 @@
 
             canvas.drawColor(SK_ColorRED);
 
-            for (int k = 0; k < layerCombinations; ++k) {
+            for (size_t k = 0; k < SK_ARRAY_COUNT(layerAlpha); ++k) {
                 // draw a rect within the layer's bounds and again outside the layer's bounds
                 canvas.saveLayerAlpha(&rect, layerAlpha[k], flags[k]);
 
-                SkCanvasState* state = NULL;
-                SkCanvas* tmpCanvas = NULL;
                 if (j) {
-                    state = SkCanvasStateUtils::CaptureCanvasState(&canvas);
+                    // Capture from the first Skia.
+                    SkCanvasState* state = SkCanvasStateUtils::CaptureCanvasState(&canvas);
                     REPORTER_ASSERT(reporter, state);
-                    tmpCanvas = SkCanvasStateUtils::CreateFromCanvasState(state);
-                    REPORTER_ASSERT(reporter, tmpCanvas);
+
+                    // And draw to it in the second Skia.
+                    bool success = complex_layers_draw_from_canvas_state(state,
+                            rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, SPACER);
+                    REPORTER_ASSERT(reporter, success);
+
+                    // And release it in the *first* Skia.
+                    SkCanvasStateUtils::ReleaseCanvasState(state);
                 } else {
-                    tmpCanvas = SkRef(&canvas);
+                    // Draw in the first Skia.
+                    complex_layers_draw(&canvas, rect.fLeft, rect.fTop,
+                                        rect.fRight, rect.fBottom, SPACER);
                 }
 
-                SkPaint bluePaint;
-                bluePaint.setColor(SK_ColorBLUE);
-                bluePaint.setStyle(SkPaint::kFill_Style);
-
-                tmpCanvas->drawRect(rect, bluePaint);
-                tmpCanvas->translate(0, rect.height() + SPACER);
-                tmpCanvas->drawRect(rect, bluePaint);
-
-                tmpCanvas->unref();
-                SkCanvasStateUtils::ReleaseCanvasState(state);
-
                 canvas.restore();
 
                 // translate the canvas for the next iteration
@@ -88,13 +139,13 @@
                                           bitmaps[1].getPixels(),
                                           bitmaps[0].getSize()));
     }
-#endif
 }
+#endif
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static void test_complex_clips(skiatest::Reporter* reporter) {
 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
+DEF_TEST(CanvasState_test_complex_clips, reporter) {
     const int WIDTH = 400;
     const int HEIGHT = 400;
     const int SPACER = 10;
@@ -126,7 +177,23 @@
                                           SkCanvas::kARGB_NoClipLayer_SaveFlag,
     };
     REPORTER_ASSERT(reporter, sizeof(clipOps) == sizeof(flags));
-    const int layerCombinations = sizeof(flags) / sizeof(SkCanvas::SaveFlags);
+
+    bool (*drawFn)(SkCanvasState* state, int32_t l, int32_t t,
+                   int32_t r, int32_t b, int32_t clipOp,
+                   int32_t regionRects, int32_t* rectCoords);
+
+    OpenLibResult openLibResult(reporter);
+    if (openLibResult.handle() != NULL) {
+        *(void**) (&drawFn) = dlsym(openLibResult.handle(),
+                                    "complex_clips_draw_from_canvas_state");
+    } else {
+        drawFn = complex_clips_draw_from_canvas_state;
+    }
+
+    REPORTER_ASSERT(reporter, drawFn);
+    if (!drawFn) {
+        return;
+    }
 
     SkBitmap bitmaps[2];
     for (int i = 0; i < 2; ++i) {
@@ -138,32 +205,35 @@
 
         SkRegion localRegion = clipRegion;
 
-        for (int j = 0; j < layerCombinations; ++j) {
+        for (size_t j = 0; j < SK_ARRAY_COUNT(flags); ++j) {
             SkRect layerBounds = SkRect::Make(layerRect);
             canvas.saveLayerAlpha(&layerBounds, 128, flags[j]);
 
-            SkCanvasState* state = NULL;
-            SkCanvas* tmpCanvas = NULL;
             if (i) {
-                state = SkCanvasStateUtils::CaptureCanvasState(&canvas);
+                SkCanvasState* state = SkCanvasStateUtils::CaptureCanvasState(&canvas);
                 REPORTER_ASSERT(reporter, state);
-                tmpCanvas = SkCanvasStateUtils::CreateFromCanvasState(state);
-                REPORTER_ASSERT(reporter, tmpCanvas);
+
+                SkRegion::Iterator iter(localRegion);
+                SkTDArray<int32_t> rectCoords;
+                for (; !iter.done(); iter.next()) {
+                    const SkIRect& rect = iter.rect();
+                    *rectCoords.append() = rect.fLeft;
+                    *rectCoords.append() = rect.fTop;
+                    *rectCoords.append() = rect.fRight;
+                    *rectCoords.append() = rect.fBottom;
+                }
+                bool success = drawFn(state, clipRect.fLeft, clipRect.fTop,
+                                      clipRect.fRight, clipRect.fBottom, clipOps[j],
+                                      rectCoords.count() / 4, rectCoords.begin());
+                REPORTER_ASSERT(reporter, success);
+
+                SkCanvasStateUtils::ReleaseCanvasState(state);
             } else {
-                tmpCanvas = SkRef(&canvas);
+                complex_clips_draw(&canvas, clipRect.fLeft, clipRect.fTop,
+                                   clipRect.fRight, clipRect.fBottom, clipOps[j],
+                                   localRegion);
             }
 
-            tmpCanvas->save();
-            tmpCanvas->clipRect(SkRect::Make(clipRect), clipOps[j]);
-            tmpCanvas->drawColor(SK_ColorBLUE);
-            tmpCanvas->restore();
-
-            tmpCanvas->clipRegion(localRegion, clipOps[j]);
-            tmpCanvas->drawColor(SK_ColorBLUE);
-
-            tmpCanvas->unref();
-            SkCanvasStateUtils::ReleaseCanvasState(state);
-
             canvas.restore();
 
             // translate the canvas and region for the next iteration
@@ -177,8 +247,8 @@
     REPORTER_ASSERT(reporter, !memcmp(bitmaps[0].getPixels(),
                                       bitmaps[1].getPixels(),
                                       bitmaps[0].getSize()));
-#endif
 }
+#endif
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -187,7 +257,7 @@
     virtual bool filter(SkPaint*, Type) SK_OVERRIDE { return true; }
 };
 
-static void test_draw_filters(skiatest::Reporter* reporter) {
+DEF_TEST(CanvasState_test_draw_filters, reporter) {
     TestDrawFilter drawFilter;
     SkBitmap bitmap;
     bitmap.allocN32Pixels(10, 10);
@@ -200,7 +270,7 @@
     SkCanvas* tmpCanvas = SkCanvasStateUtils::CreateFromCanvasState(state);
     REPORTER_ASSERT(reporter, tmpCanvas);
 
-    REPORTER_ASSERT(reporter, NULL != canvas.getDrawFilter());
+    REPORTER_ASSERT(reporter, canvas.getDrawFilter());
     REPORTER_ASSERT(reporter, NULL == tmpCanvas->getDrawFilter());
 
     tmpCanvas->unref();
@@ -212,7 +282,7 @@
 // we need this function to prevent SkError from printing to stdout
 static void error_callback(SkError code, void* ctx) {}
 
-static void test_soft_clips(skiatest::Reporter* reporter) {
+DEF_TEST(CanvasState_test_soft_clips, reporter) {
     SkBitmap bitmap;
     bitmap.allocN32Pixels(10, 10);
     SkCanvas canvas(bitmap);
@@ -231,8 +301,8 @@
     SkClearLastError();
 }
 
-static void test_saveLayer_clip(skiatest::Reporter* reporter) {
 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
+DEF_TEST(CanvasState_test_saveLayer_clip, reporter) {
     const int WIDTH = 100;
     const int HEIGHT = 100;
     const int LAYER_WIDTH = 50;
@@ -263,13 +333,5 @@
     REPORTER_ASSERT(reporter, clipStackBounds.height() == LAYER_HEIGHT);
 
     canvas.restore();
+}
 #endif
-}
-
-DEF_TEST(CanvasState, reporter) {
-    test_complex_layers(reporter);
-    test_complex_clips(reporter);
-    test_draw_filters(reporter);
-    test_soft_clips(reporter);
-    test_saveLayer_clip(reporter);
-}
diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp
index f8e856a..216a408 100644
--- a/tests/CanvasTest.cpp
+++ b/tests/CanvasTest.cpp
@@ -367,45 +367,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 // Complex test steps
 
-// Save/restore calls cannot be in isolated simple test steps because the test
-// cases that use SkPicture require that save and restore calls be balanced.
-static void SaveMatrixStep(SkCanvas* canvas,
-                           skiatest::Reporter* reporter,
-                           CanvasTestStep* testStep) {
-    int saveCount = canvas->getSaveCount();
-    canvas->save(SkCanvas::kMatrix_SaveFlag);
-    canvas->clipRegion(kTestRegion);
-    canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
-    canvas->restore();
-    REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
-        testStep->assertMessage());
-    REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalMatrix().isIdentity(),
-        testStep->assertMessage());
-//    REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() == kTestRegion, testStep->assertMessage());
-}
-TEST_STEP(SaveMatrix, SaveMatrixStep);
-
-static void SaveClipStep(SkCanvas* canvas,
-                         skiatest::Reporter* reporter,
-                         CanvasTestStep* testStep) {
-    int saveCount = canvas->getSaveCount();
-    canvas->save(SkCanvas::kClip_SaveFlag);
-    canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
-    canvas->clipRegion(kTestRegion);
-    canvas->restore();
-    REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
-        testStep->assertMessage());
-    REPORTER_ASSERT_MESSAGE(reporter, !canvas->getTotalMatrix().isIdentity(),
-        testStep->assertMessage());
-//    REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() != kTestRegion, testStep->assertMessage());
-}
-TEST_STEP(SaveClip, SaveClipStep);
-
 static void SaveMatrixClipStep(SkCanvas* canvas,
                                skiatest::Reporter* reporter,
                                CanvasTestStep* testStep) {
     int saveCount = canvas->getSaveCount();
-    canvas->save(SkCanvas::kMatrixClip_SaveFlag);
+    canvas->save();
     canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
     canvas->clipRegion(kTestRegion);
     canvas->restore();
@@ -497,7 +463,8 @@
                                 skiatest::Reporter*,
                                 CanvasTestStep*) {
     SkPictureRecorder recorder;
-    SkCanvas* testCanvas = recorder.beginRecording(kWidth, kHeight, NULL, 0);
+    SkCanvas* testCanvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight), 
+                                                   NULL, 0);
     testCanvas->scale(SkIntToScalar(2), SkIntToScalar(1));
     testCanvas->clipRect(kTestRect);
     testCanvas->drawRect(kTestRect, kTestPaint);
@@ -721,13 +688,17 @@
         // are flattened during the second execution
         testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat);
         SkPictureRecorder referenceRecorder;
-        SkCanvas* referenceCanvas = referenceRecorder.beginRecording(kWidth, kHeight,
-                                                                     NULL, recordFlags);
+        SkCanvas* referenceCanvas =
+            referenceRecorder.DEPRECATED_beginRecording(SkIntToScalar(kWidth), 
+                                                        SkIntToScalar(kHeight), 
+                                                        NULL, recordFlags);
         testStep->draw(referenceCanvas, reporter);
 
         SkPictureRecorder testRecorder;
-        SkCanvas* testCanvas = testRecorder.beginRecording(kWidth, kHeight,
-                                                           NULL, recordFlags);
+        SkCanvas* testCanvas =
+            testRecorder.DEPRECATED_beginRecording(SkIntToScalar(kWidth), 
+                                                   SkIntToScalar(kHeight), 
+                                                   NULL, recordFlags);
         testStep->draw(testCanvas, reporter);
         testStep->setAssertMessageFormat(kPictureSecondDrawAssertMessageFormat);
         testStep->draw(testCanvas, reporter);
@@ -805,8 +776,7 @@
 
     SkBitmap indirectStore;
     createBitmap(&indirectStore, 0xFFFFFFFF);
-    SkBitmapDevice indirectDevice(indirectStore);
-    SkCanvas indirectCanvas(&indirectDevice);
+    SkCanvas indirectCanvas(indirectStore);
     SkProxyCanvas proxyCanvas(&indirectCanvas);
     testStep->setAssertMessageFormat(kProxyDrawAssertMessageFormat);
     testStep->draw(&proxyCanvas, reporter);
@@ -828,13 +798,11 @@
 
     SkBitmap indirectStore1;
     createBitmap(&indirectStore1, 0xFFFFFFFF);
-    SkBitmapDevice indirectDevice1(indirectStore1);
-    SkCanvas indirectCanvas1(&indirectDevice1);
+    SkCanvas indirectCanvas1(indirectStore1);
 
     SkBitmap indirectStore2;
     createBitmap(&indirectStore2, 0xFFFFFFFF);
-    SkBitmapDevice indirectDevice2(indirectStore2);
-    SkCanvas indirectCanvas2(&indirectDevice2);
+    SkCanvas indirectCanvas2(indirectStore2);
 
     SkISize canvasSize = referenceCanvas.getDeviceSize();
     SkNWayCanvas nWayCanvas(canvasSize.width(), canvasSize.height());
@@ -866,8 +834,7 @@
                                          CanvasTestStep* testStep) {
     SkBitmap referenceStore;
     createBitmap(&referenceStore, 0xFFFFFFFF);
-    SkBitmapDevice referenceDevice(referenceStore);
-    SkCanvas referenceCanvas(&referenceDevice);
+    SkCanvas referenceCanvas(referenceStore);
     testStep->setAssertMessageFormat(kCanvasDrawAssertMessageFormat);
     testStep->draw(&referenceCanvas, reporter);
 
@@ -916,17 +883,15 @@
     SkDELETE(canvas);
 
     // now try a deliberately bad info
-    info.fWidth = -1;
+    info = info.makeWH(-1, info.height());
     REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info));
 
     // too big
-    info.fWidth = 1 << 30;
-    info.fHeight = 1 << 30;
+    info = info.makeWH(1 << 30, 1 << 30);
     REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info));
 
     // not a valid pixel type
-    info.fWidth = info.fHeight = 10;
-    info.fColorType = kUnknown_SkColorType;
+    info = SkImageInfo::Make(10, 10, kUnknown_SkColorType, info.alphaType());
     REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info));
 
     // We should succeed with a zero-sized valid info
diff --git a/tests/ClipCacheTest.cpp b/tests/ClipCacheTest.cpp
index 77f0137..d9f3b57 100644
--- a/tests/ClipCacheTest.cpp
+++ b/tests/ClipCacheTest.cpp
@@ -57,7 +57,7 @@
         return;
     }
 
-    SkAutoUnref au(texture);
+    SkAutoTUnref<GrTexture> au(texture);
 
     SkIRect intScreen = SkIRect::MakeWH(kXSize, kYSize);
     SkRect screen;
@@ -164,14 +164,12 @@
 
     // check that the set took
     check_state(reporter, cache, clip1, texture1, bound1);
-    REPORTER_ASSERT(reporter, texture1->getRefCnt());
 
     // push the state
     cache.push();
 
     // verify that the pushed state is initially empty
     check_empty_state(reporter, cache);
-    REPORTER_ASSERT(reporter, texture1->getRefCnt());
 
     // modify the new state
     SkIRect bound2;
@@ -189,8 +187,6 @@
 
     // check that the changes took
     check_state(reporter, cache, clip2, texture2, bound2);
-    REPORTER_ASSERT(reporter, texture1->getRefCnt());
-    REPORTER_ASSERT(reporter, texture2->getRefCnt());
 
     // check to make sure canReuse works
     REPORTER_ASSERT(reporter, cache.canReuse(clip2.getTopmostGenID(), bound2));
@@ -201,7 +197,6 @@
 
     // verify that the old state is restored
     check_state(reporter, cache, clip1, texture1, bound1);
-    REPORTER_ASSERT(reporter, texture1->getRefCnt());
 
     // manually clear the state
     cache.reset();
diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp
index 0620df9..662e680 100644
--- a/tests/ClipStackTest.cpp
+++ b/tests/ClipStackTest.cpp
@@ -980,12 +980,12 @@
             // whether the result is bounded or not, the whole plane should start outside the clip.
             reducedStack.clipEmpty();
         }
-        for (ElementList::Iter iter = reducedClips.headIter(); NULL != iter.get(); iter.next()) {
+        for (ElementList::Iter iter = reducedClips.headIter(); iter.get(); iter.next()) {
             add_elem_to_stack(*iter.get(), &reducedStack);
         }
 
         // GrReducedClipStack assumes that the final result is clipped to the returned bounds
-        if (NULL != tightBounds) {
+        if (tightBounds) {
             reducedStack.clipDevRect(*tightBounds, SkRegion::kIntersect_Op);
         }
 
@@ -1191,7 +1191,7 @@
     SkRect answer;
     answer.iset(25, 25, 75, 75);
 
-    REPORTER_ASSERT(reporter, NULL != element);
+    REPORTER_ASSERT(reporter, element);
     REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->getType());
     REPORTER_ASSERT(reporter, SkRegion::kIntersect_Op == element->getOp());
     REPORTER_ASSERT(reporter, element->getRect() == answer);
diff --git a/tests/DataRefTest.cpp b/tests/DataRefTest.cpp
index adb05f9..6a58c16 100644
--- a/tests/DataRefTest.cpp
+++ b/tests/DataRefTest.cpp
@@ -179,7 +179,7 @@
         return;
     }
 
-    SkString path = SkOSPath::SkPathJoin(tmpDir.c_str(), "data_test");
+    SkString path = SkOSPath::Join(tmpDir.c_str(), "data_test");
 
     const char s[] = "abcdefghijklmnopqrstuvwxyz";
     {
diff --git a/tests/DeferredCanvasTest.cpp b/tests/DeferredCanvasTest.cpp
index 747b23b..d234c8c 100644
--- a/tests/DeferredCanvasTest.cpp
+++ b/tests/DeferredCanvasTest.cpp
@@ -49,26 +49,9 @@
     return pixel;
 }
 
-static void TestDeferredCanvasBitmapAccess(skiatest::Reporter* reporter) {
-    SkBitmap store;
-
-    SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF));
-    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));
-
-    canvas->clear(0x00000000);
-
-    // verify that the clear() was deferred
-    REPORTER_ASSERT(reporter, 0xFFFFFFFF == read_pixel(surface, 0, 0));
-
-    SkBitmap accessed = canvas->getDevice()->accessBitmap(false);
-
-    // verify that clear was executed
-    REPORTER_ASSERT(reporter, 0 == read_pixel(surface, 0, 0));
-}
-
 class MockSurface : public SkSurface_Base {
 public:
-    MockSurface(int width, int height) : SkSurface_Base(width, height) {
+    MockSurface(int width, int height) : SkSurface_Base(width, height, NULL) {
         clearCounts();
         fBitmap.allocN32Pixels(width, height);
     }
@@ -487,6 +470,7 @@
     SkBitmap sourceImage;
     // 100 by 100 image, takes 40,000 bytes in memory
     sourceImage.allocN32Pixels(100, 100);
+    sourceImage.eraseColor(SK_ColorGREEN);
 
     for (int i = 0; i < 5; i++) {
         sourceImage.notifyPixelsChanged(); // to force re-serialization
@@ -520,6 +504,7 @@
     SkBitmap sourceImages[imageCount];
     for (int i = 0; i < imageCount; i++) {
         sourceImages[i].allocN32Pixels(100, 100);
+        sourceImages[i].eraseColor(SK_ColorGREEN);
     }
 
     size_t bitmapSize = sourceImages[0].getSize();
@@ -547,7 +532,7 @@
     canvas->drawBitmap(sourceImages[0], 0, 0, NULL);
     REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedCount);
     canvas->drawBitmap(sourceImages[0], 0, 0, NULL);
-    REPORTER_ASSERT(reporter, 3 == notificationCounter.fStorageAllocatedChangedCount);
+    REPORTER_ASSERT(reporter, 2 == notificationCounter.fStorageAllocatedChangedCount);
     REPORTER_ASSERT(reporter, 1 == notificationCounter.fFlushedDrawCommandsCount);
     REPORTER_ASSERT(reporter, canvas->storageAllocatedForRecording() < 2 * bitmapSize);
 
@@ -619,6 +604,7 @@
             SkPaint paint;
             SkBitmap paintPattern;
             paintPattern.allocN32Pixels(10, 10);
+            paintPattern.eraseColor(SK_ColorGREEN);
             paint.setShader(SkNEW_ARGS(SkBitmapProcShader,
                 (paintPattern, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)))->unref();
             canvas->drawPaint(paint);
@@ -647,6 +633,7 @@
     SkBitmap sourceImage;
     // 100 by 100 image, takes 40,000 bytes in memory
     sourceImage.allocN32Pixels(100, 100);
+    sourceImage.eraseColor(SK_ColorGREEN);
 
     // 1 under : should not store the image
     {
@@ -677,122 +664,158 @@
 }
 
 
-typedef void* PixelPtr;
+typedef const void* PixelPtr;
 // Returns an opaque pointer which, either points to a GrTexture or RAM pixel
 // buffer. Used to test pointer equality do determine whether a surface points
 // to the same pixel data storage as before.
-static PixelPtr getSurfacePixelPtr(SkSurface* surface, bool useGpu) {
-    return useGpu ? surface->getCanvas()->getDevice()->accessBitmap(false).getTexture() :
-        surface->getCanvas()->getDevice()->accessBitmap(false).getPixels();
+static PixelPtr get_surface_ptr(SkSurface* surface, bool useGpu) {
+#if SK_SUPPORT_GPU
+    if (useGpu) {
+        return surface->getCanvas()->internal_private_accessTopLayerRenderTarget()->asTexture();
+    } else
+#endif
+    {
+        return surface->peekPixels(NULL, NULL);
+    }
 }
 
 static void TestDeferredCanvasSurface(skiatest::Reporter* reporter, GrContextFactory* factory) {
     SkImageInfo imageSpec = SkImageInfo::MakeN32Premul(10, 10);
-    SkSurface* surface;
-    bool useGpu = NULL != factory;
+    bool useGpu = SkToBool(factory);
+    int cnt;
 #if SK_SUPPORT_GPU
     if (useGpu) {
-        GrContext* context = factory->get(GrContextFactory::kNative_GLContextType);
-        if (NULL == context) {
-            return;
-        }
-
-        surface = SkSurface::NewRenderTarget(context, imageSpec);
+        cnt = GrContextFactory::kGLContextTypeCnt;
     } else {
-        surface = SkSurface::NewRaster(imageSpec);
+        cnt = 1;
     }
 #else
     SkASSERT(!useGpu);
-    surface = SkSurface::NewRaster(imageSpec);
+    cnt = 1;
 #endif
-    SkASSERT(NULL != surface);
-    SkAutoTUnref<SkSurface> aur(surface);
-    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface));
+    for (int i = 0; i < cnt; ++i) {
+        SkSurface* surface;
+#if SK_SUPPORT_GPU
+        if (useGpu) {
+            GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+            if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
+                continue;
+            }
+            GrContext* context = factory->get(glCtxType);
+            if (NULL == context) {
+                return;
+            }
 
-    SkImage* image1 = canvas->newImageSnapshot();
-    SkAutoTUnref<SkImage> aur_i1(image1);
-    PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu);
-    // The following clear would normally trigger a copy on write, but
-    // it won't because rendering is deferred.
-    canvas->clear(SK_ColorBLACK);
-    // Obtaining a snapshot directly from the surface (as opposed to the
-    // SkDeferredCanvas) will not trigger a flush of deferred draw operations
-    // and will therefore return the same image as the previous snapshot.
-    SkImage* image2 = surface->newImageSnapshot();
-    SkAutoTUnref<SkImage> aur_i2(image2);
-    // Images identical because of deferral
-    REPORTER_ASSERT(reporter, image1->uniqueID() == image2->uniqueID());
-    // Now we obtain a snpshot via the deferred canvas, which triggers a flush.
-    // Because there is a pending clear, this will generate a different image.
-    SkImage* image3 = canvas->newImageSnapshot();
-    SkAutoTUnref<SkImage> aur_i3(image3);
-    REPORTER_ASSERT(reporter, image1->uniqueID() != image3->uniqueID());
-    // Verify that backing store is now a different buffer because of copy on
-    // write
-    PixelPtr pixels2 = getSurfacePixelPtr(surface, useGpu);
-    REPORTER_ASSERT(reporter, pixels1 != pixels2);
-    // Verify copy-on write with a draw operation that gets deferred by
-    // the in order draw buffer.
-    SkPaint paint;
-    canvas->drawPaint(paint);
-    SkImage* image4 = canvas->newImageSnapshot();  // implicit flush
-    SkAutoTUnref<SkImage> aur_i4(image4);
-    REPORTER_ASSERT(reporter, image4->uniqueID() != image3->uniqueID());
-    PixelPtr pixels3 = getSurfacePixelPtr(surface, useGpu);
-    REPORTER_ASSERT(reporter, pixels2 != pixels3);
-    // Verify that a direct canvas flush with a pending draw does not trigger
-    // a copy on write when the surface is not sharing its buffer with an
-    // SkImage.
-    canvas->clear(SK_ColorWHITE);
-    canvas->flush();
-    PixelPtr pixels4 = getSurfacePixelPtr(surface, useGpu);
-    canvas->drawPaint(paint);
-    canvas->flush();
-    PixelPtr pixels5 = getSurfacePixelPtr(surface, useGpu);
-    REPORTER_ASSERT(reporter, pixels4 == pixels5);
+            surface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
+        } else
+#endif
+        {
+           surface = SkSurface::NewRaster(imageSpec);
+        }
+        SkASSERT(surface);
+        SkAutoTUnref<SkSurface> aur(surface);
+        SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface));
+
+        SkImage* image1 = canvas->newImageSnapshot();
+        SkAutoTUnref<SkImage> aur_i1(image1);
+        PixelPtr pixels1 = get_surface_ptr(surface, useGpu);
+        // The following clear would normally trigger a copy on write, but
+        // it won't because rendering is deferred.
+        canvas->clear(SK_ColorBLACK);
+        // Obtaining a snapshot directly from the surface (as opposed to the
+        // SkDeferredCanvas) will not trigger a flush of deferred draw operations
+        // and will therefore return the same image as the previous snapshot.
+        SkImage* image2 = surface->newImageSnapshot();
+        SkAutoTUnref<SkImage> aur_i2(image2);
+        // Images identical because of deferral
+        REPORTER_ASSERT(reporter, image1->uniqueID() == image2->uniqueID());
+        // Now we obtain a snpshot via the deferred canvas, which triggers a flush.
+        // Because there is a pending clear, this will generate a different image.
+        SkImage* image3 = canvas->newImageSnapshot();
+        SkAutoTUnref<SkImage> aur_i3(image3);
+        REPORTER_ASSERT(reporter, image1->uniqueID() != image3->uniqueID());
+        // Verify that backing store is now a different buffer because of copy on
+        // write
+        PixelPtr pixels2 = get_surface_ptr(surface, useGpu);
+        REPORTER_ASSERT(reporter, pixels1 != pixels2);
+        // Verify copy-on write with a draw operation that gets deferred by
+        // the in order draw buffer.
+        SkPaint paint;
+        canvas->drawPaint(paint);
+        SkImage* image4 = canvas->newImageSnapshot();  // implicit flush
+        SkAutoTUnref<SkImage> aur_i4(image4);
+        REPORTER_ASSERT(reporter, image4->uniqueID() != image3->uniqueID());
+        PixelPtr pixels3 = get_surface_ptr(surface, useGpu);
+        REPORTER_ASSERT(reporter, pixels2 != pixels3);
+        // Verify that a direct canvas flush with a pending draw does not trigger
+        // a copy on write when the surface is not sharing its buffer with an
+        // SkImage.
+        canvas->clear(SK_ColorWHITE);
+        canvas->flush();
+        PixelPtr pixels4 = get_surface_ptr(surface, useGpu);
+        canvas->drawPaint(paint);
+        canvas->flush();
+        PixelPtr pixels5 = get_surface_ptr(surface, useGpu);
+        REPORTER_ASSERT(reporter, pixels4 == pixels5);
+    }
 }
 
 static void TestDeferredCanvasSetSurface(skiatest::Reporter* reporter, GrContextFactory* factory) {
     SkImageInfo imageSpec = SkImageInfo::MakeN32Premul(10, 10);
     SkSurface* surface;
     SkSurface* alternateSurface;
-    bool useGpu = NULL != factory;
+    bool useGpu = SkToBool(factory);
+    int cnt;
 #if SK_SUPPORT_GPU
     if (useGpu) {
-        GrContext* context = factory->get(GrContextFactory::kNative_GLContextType);
-        if (NULL == context) {
-            return;
-        }
-        surface = SkSurface::NewRenderTarget(context, imageSpec);
-        alternateSurface = SkSurface::NewRenderTarget(context, imageSpec);
+        cnt = GrContextFactory::kGLContextTypeCnt;
     } else {
-        surface = SkSurface::NewRaster(imageSpec);
-        alternateSurface = SkSurface::NewRaster(imageSpec);
+        cnt = 1;
     }
 #else
     SkASSERT(!useGpu);
-    surface = SkSurface::NewRaster(imageSpec);
-    alternateSurface = SkSurface::NewRaster(imageSpec);
+    cnt = 1;
 #endif
-    SkASSERT(NULL != surface);
-    SkASSERT(NULL != alternateSurface);
-    SkAutoTUnref<SkSurface> aur1(surface);
-    SkAutoTUnref<SkSurface> aur2(alternateSurface);
-    PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu);
-    PixelPtr pixels2 = getSurfacePixelPtr(alternateSurface, useGpu);
-    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface));
-    SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot());
-    canvas->setSurface(alternateSurface);
-    SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot());
-    REPORTER_ASSERT(reporter, image1->uniqueID() != image2->uniqueID());
-    // Verify that none of the above operations triggered a surface copy on write.
-    REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1);
-    REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) == pixels2);
-    // Verify that a flushed draw command will trigger a copy on write on alternateSurface.
-    canvas->clear(SK_ColorWHITE);
-    canvas->flush();
-    REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1);
-    REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) != pixels2);
+
+    for (int i = 0; i < cnt; ++i) {
+#if SK_SUPPORT_GPU
+        if (useGpu) {
+            GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+            if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
+                continue;
+            }
+            GrContext* context = factory->get(glCtxType);
+            if (NULL == context) {
+                continue;
+            }
+            surface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
+            alternateSurface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
+        } else
+#endif
+        {
+            surface = SkSurface::NewRaster(imageSpec);
+            alternateSurface = SkSurface::NewRaster(imageSpec);
+        }
+        SkASSERT(surface);
+        SkASSERT(alternateSurface);
+        SkAutoTUnref<SkSurface> aur1(surface);
+        SkAutoTUnref<SkSurface> aur2(alternateSurface);
+        PixelPtr pixels1 = get_surface_ptr(surface, useGpu);
+        PixelPtr pixels2 = get_surface_ptr(alternateSurface, useGpu);
+        SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface));
+        SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot());
+        canvas->setSurface(alternateSurface);
+        SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot());
+        REPORTER_ASSERT(reporter, image1->uniqueID() != image2->uniqueID());
+        // Verify that none of the above operations triggered a surface copy on write.
+        REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1);
+        REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) == pixels2);
+        // Verify that a flushed draw command will trigger a copy on write on alternateSurface.
+        canvas->clear(SK_ColorWHITE);
+        canvas->flush();
+        REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1);
+        REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) != pixels2);
+    }
 }
 
 static void TestDeferredCanvasCreateCompatibleDevice(skiatest::Reporter* reporter) {
@@ -816,8 +839,60 @@
     REPORTER_ASSERT(reporter, notificationCounter.fStorageAllocatedChangedCount == 1);
 }
 
+static void TestDeferredCanvasGetCanvasSize(skiatest::Reporter* reporter) {
+    SkRect rect;
+    rect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(gWidth), SkIntToScalar(gHeight));
+    SkRect clip;
+    clip.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(1), SkIntToScalar(1));
+
+    SkPaint paint;
+    SkISize size = SkISize::Make(gWidth, gHeight);
+
+    SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF));
+    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));
+    SkSurface* newSurface = SkSurface::NewRasterPMColor(4, 4);
+    SkAutoTUnref<SkSurface> aur(newSurface);
+
+    for (int i = 0; i < 2; ++i) {
+        if (i == 1) {
+            canvas->setSurface(newSurface);
+            size = SkISize::Make(4, 4);
+        }
+
+        // verify that canvas size is correctly initialized or set
+        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());
+
+        // Verify that clear, clip and draw the canvas will not change its size
+        canvas->clear(0x00000000);
+        canvas->clipRect(clip, SkRegion::kIntersect_Op, false);
+        canvas->drawRect(rect, paint);
+        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());
+
+        // Verify that flush the canvas will not change its size
+        canvas->flush();
+        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());
+
+        // Verify that clear canvas with saved state will not change its size
+        canvas->save();
+        canvas->clear(0xFFFFFFFF);
+        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());
+
+        // Verify that restore canvas state will not change its size
+        canvas->restore();
+        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());
+
+        // Verify that clear within a layer will not change canvas size
+        canvas->saveLayer(&clip, &paint);
+        canvas->clear(0x00000000);
+        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());
+
+        // Verify that restore from a layer will not change canvas size
+        canvas->restore();
+        REPORTER_ASSERT(reporter, size == canvas->getCanvasSize());
+    }
+}
+
 DEF_TEST(DeferredCanvas_CPU, reporter) {
-    TestDeferredCanvasBitmapAccess(reporter);
     TestDeferredCanvasFlush(reporter);
     TestDeferredCanvasSilentFlush(reporter);
     TestDeferredCanvasFreshFrame(reporter);
@@ -828,6 +903,7 @@
     TestDeferredCanvasBitmapSizeThreshold(reporter);
     TestDeferredCanvasCreateCompatibleDevice(reporter);
     TestDeferredCanvasWritePixelsToSurface(reporter);
+    TestDeferredCanvasGetCanvasSize(reporter);
     TestDeferredCanvasSurface(reporter, NULL);
     TestDeferredCanvasSetSurface(reporter, NULL);
 }
diff --git a/tests/DequeTest.cpp b/tests/DequeTest.cpp
index 5d5dc09..04b1f40 100644
--- a/tests/DequeTest.cpp
+++ b/tests/DequeTest.cpp
@@ -19,8 +19,8 @@
         REPORTER_ASSERT(reporter, !deq.empty());
         REPORTER_ASSERT(reporter, count == deq.count());
         REPORTER_ASSERT(reporter, sizeof(int) == deq.elemSize());
-        REPORTER_ASSERT(reporter, NULL != deq.front());
-        REPORTER_ASSERT(reporter, NULL != deq.back());
+        REPORTER_ASSERT(reporter, deq.front());
+        REPORTER_ASSERT(reporter, deq.back());
         if (1 == count) {
             REPORTER_ASSERT(reporter, deq.back() == deq.front());
         } else {
@@ -36,7 +36,7 @@
     void* ptr;
 
     int value = max;
-    while (NULL != (ptr = iter.next())) {
+    while ((ptr = iter.next())) {
         REPORTER_ASSERT(reporter, value == *(int*)ptr);
         value -= 1;
     }
@@ -46,7 +46,7 @@
     iter.reset(deq, SkDeque::Iter::kBack_IterStart);
 
     value = min;
-    while (NULL != (ptr = iter.prev())) {
+    while ((ptr = iter.prev())) {
         REPORTER_ASSERT(reporter, value == *(int*)ptr);
         value += 1;
     }
@@ -57,12 +57,12 @@
 
     value = max;
     // forward iteration half-way
-    for (int i = 0; i < deq.count()/2 && NULL != (ptr = iter.next()); i++) {
+    for (int i = 0; i < deq.count()/2 && (ptr = iter.next()); i++) {
         REPORTER_ASSERT(reporter, value == *(int*)ptr);
         value -= 1;
     }
     // then back down w/ reverse iteration
-    while (NULL != (ptr = iter.prev())) {
+    while ((ptr = iter.prev())) {
         REPORTER_ASSERT(reporter, value == *(int*)ptr);
         value += 1;
     }
diff --git a/tests/DocumentTest.cpp b/tests/DocumentTest.cpp
index 73510f8..97aefcb 100644
--- a/tests/DocumentTest.cpp
+++ b/tests/DocumentTest.cpp
@@ -37,7 +37,7 @@
                  // allways, then all these tests will be disabled.
     }
 
-    SkString path = SkOSPath::SkPathJoin(tmpDir.c_str(), "aborted.pdf");
+    SkString path = SkOSPath::Join(tmpDir.c_str(), "aborted.pdf");
 
     // Make sure doc's destructor is called to flush.
     {
@@ -65,7 +65,7 @@
                  // allways, then all these tests will be disabled.
     }
 
-    SkString path = SkOSPath::SkPathJoin(tmpDir.c_str(), "file.pdf");
+    SkString path = SkOSPath::Join(tmpDir.c_str(), "file.pdf");
 
     SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(path.c_str()));
 
diff --git a/tests/DrawBitmapRectTest.cpp b/tests/DrawBitmapRectTest.cpp
index 6dca98b..71ad2cf 100644
--- a/tests/DrawBitmapRectTest.cpp
+++ b/tests/DrawBitmapRectTest.cpp
@@ -25,10 +25,7 @@
 
 protected:
     virtual bool onGetInfo(SkImageInfo* info) SK_OVERRIDE {
-        info->fWidth = 100;
-        info->fHeight = 100;
-        info->fColorType = kN32_SkColorType;
-        info->fAlphaType = kPremul_SkAlphaType;
+        *info = SkImageInfo::MakeN32Premul(100, 100);
         return true;
     }
     // default onGetPixels() returns false, which is what we want.
@@ -190,7 +187,9 @@
     c.concat(matrix);
 
     SkBitmap bm;
-    bm.allocN32Pixels(width, height);
+    if (bm.tryAllocN32Pixels(width, height)) {
+        // allow this to fail silently, to test the code downstream
+    }
     bm.eraseColor(SK_ColorRED);
 
     matrix.setAll(0.0078740157f,
diff --git a/tests/DynamicHashTest.cpp b/tests/DynamicHashTest.cpp
index b2da6f3..4a5bb85 100644
--- a/tests/DynamicHashTest.cpp
+++ b/tests/DynamicHashTest.cpp
@@ -136,12 +136,12 @@
     ASSERT(hash.find(5)->value == 3.0);
 }
 
-DEF_TEST(DynamicHash_iterator, reporter) {
+template<typename T> static void TestIter(skiatest::Reporter* reporter) {
     Hash hash;
 
     int count = 0;
     // this should fall out of loop immediately
-    for (Hash::Iter iter(&hash); !iter.done(); ++iter) {
+    for (T iter(&hash); !iter.done(); ++iter) {
         ++count;
     }
     ASSERT(0 == count);
@@ -158,7 +158,7 @@
     // should see all 3 unique keys when iterating over hash
     count = 0;
     int keys[3] = {0, 0, 0};
-    for (Hash::Iter iter(&hash); !iter.done(); ++iter) {
+    for (T iter(&hash); !iter.done(); ++iter) {
         int key = (*iter).key;
         keys[count] = key;
         ASSERT(hash.find(key) != NULL);
@@ -172,8 +172,8 @@
     // should see 2 unique keys when iterating over hash that aren't 1
     hash.remove(1);
     count = 0;
-    memset(keys,0,sizeof(keys));
-    for (Hash::Iter iter(&hash); !iter.done(); ++iter) {
+    memset(keys, 0, sizeof(keys));
+    for (T iter(&hash); !iter.done(); ++iter) {
         int key = (*iter).key;
         keys[count] = key;
         ASSERT(key != 1);
@@ -183,3 +183,46 @@
     ASSERT(2 == count);
     ASSERT(keys[0] != keys[1]);
 }
+
+DEF_TEST(DynamicHash_iterator, reporter) {
+    TestIter<Hash::Iter>(reporter);
+    TestIter<Hash::ConstIter>(reporter);
+}
+
+static void TestResetOrRewind(skiatest::Reporter* reporter, bool testReset) {
+    Hash hash;
+    Entry a = { 1, 2.0 };
+    Entry b = { 2, 3.0 };
+
+    ASSERT(hash.capacity() == 0);
+    hash.add(&a);
+    hash.add(&b);
+    ASSERT(hash.count() == 2);
+    ASSERT(hash.capacity() == 4);
+
+    if (testReset) {
+        hash.reset();
+        ASSERT(hash.capacity() == 0);
+    } else {
+        hash.rewind();
+        ASSERT(hash.capacity() == 4);
+    }
+    ASSERT(hash.count() == 0);
+
+    // make sure things still work
+    hash.add(&a);
+    hash.add(&b);
+    ASSERT(hash.count() == 2);
+    ASSERT(hash.capacity() == 4);
+
+    ASSERT(hash.find(1) != NULL);
+    ASSERT(hash.find(2) != NULL);
+}
+
+DEF_TEST(DynamicHash_reset, reporter) {
+    TestResetOrRewind(reporter, true);
+}
+
+DEF_TEST(DynamicHash_rewind, reporter) {
+    TestResetOrRewind(reporter, false);
+}
diff --git a/tests/ErrorTest.cpp b/tests/ErrorTest.cpp
index 89e920a..4802d53 100644
--- a/tests/ErrorTest.cpp
+++ b/tests/ErrorTest.cpp
@@ -28,6 +28,9 @@
 }
 
 DEF_TEST(Error, reporter) {
+    // Some previous user of this thread may have left an error laying around.
+    SkClearLastError();
+
     SkError err;
 
     unsigned int test_value = 0xdeadbeef;
diff --git a/tests/FlateTest.cpp b/tests/FlateTest.cpp
index aacde34..75c6f3f 100644
--- a/tests/FlateTest.cpp
+++ b/tests/FlateTest.cpp
@@ -5,9 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include <stdlib.h>
-#include <string.h>
-
 #include "SkData.h"
 #include "SkFlate.h"
 #include "SkStream.h"
@@ -28,72 +25,95 @@
     static const size_t kGetSizeKey = 0xDEADBEEF;
 };
 
+// Returns a deterministic data of the given size that should be
+// very compressible.
+static SkData* new_test_data(size_t dataSize) {
+    SkAutoTMalloc<uint8_t> testBuffer(dataSize);
+    for (size_t i = 0; i < dataSize; ++i) {
+        testBuffer[i] = i % 64;
+    }
+    return SkData::NewFromMalloc(testBuffer.detach(), dataSize);
+}
+
 static void TestFlate(skiatest::Reporter* reporter, SkMemoryStream* testStream,
                       size_t dataSize) {
-    if (testStream == NULL)
-      return;
+    SkASSERT(testStream != NULL);
 
-    SkMemoryStream testData(dataSize);
-    uint8_t* data = (uint8_t*)testData.getMemoryBase();
-    srand(0);  // Make data deterministic.
-    for (size_t i = 0; i < dataSize; i++)
-        data[i] = rand() & 0xFF;
+    SkAutoDataUnref testData(new_test_data(dataSize));
+    SkASSERT(testData->size() == dataSize);
 
-    testStream->setMemory(testData.getMemoryBase(), dataSize, true);
+    testStream->setMemory(testData->data(), dataSize, /*copyData=*/ true);
     SkDynamicMemoryWStream compressed;
-    bool status = SkFlate::Deflate(testStream, &compressed);
-    REPORTER_ASSERT(reporter, status);
+    bool deflateSuccess = SkFlate::Deflate(testStream, &compressed);
+    REPORTER_ASSERT(reporter, deflateSuccess);
 
     // Check that the input data wasn't changed.
     size_t inputSize = testStream->getLength();
-    if (inputSize == 0)
+    if (inputSize == 0) {
         inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
-    REPORTER_ASSERT(reporter, testData.getLength() == inputSize);
-    REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(),
-                                     testStream->getMemoryBase(),
-                                     testData.getLength()) == 0);
+    }
+    REPORTER_ASSERT(reporter, dataSize == inputSize);
+    if (dataSize == inputSize) {
+        REPORTER_ASSERT(reporter, memcmp(testData->data(),
+                                         testStream->getMemoryBase(),
+                                         dataSize) == 0);
+    }
 
-    // Assume there are two test sizes, big and small.
-    if (dataSize < 1024)
-      REPORTER_ASSERT(reporter, compressed.getOffset() < 1024);
-    else
-      REPORTER_ASSERT(reporter, compressed.getOffset() > 1024);
+    size_t compressedSize = compressed.getOffset();
 
-    SkAutoDataUnref data1(compressed.copyToData());
+    SkAutoDataUnref compressedData(compressed.copyToData());
+    testStream->setData(compressedData.get());
 
-    testStream->setData(data1.get())->unref();
     SkDynamicMemoryWStream uncompressed;
-    status = SkFlate::Inflate(testStream, &uncompressed);
-    REPORTER_ASSERT(reporter, status);
+    bool inflateSuccess = SkFlate::Inflate(testStream, &uncompressed);
+    REPORTER_ASSERT(reporter, inflateSuccess);
 
     // Check that the input data wasn't changed.
     inputSize = testStream->getLength();
-    if (inputSize == 0)
+    if (inputSize == 0) {
         inputSize = testStream->read(NULL, SkZeroSizeMemStream::kGetSizeKey);
-    REPORTER_ASSERT(reporter, data1->size() == inputSize);
-    REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(),
-                                     data1->data(),
-                                     data1->size()) == 0);
+    }
+    REPORTER_ASSERT(reporter,  compressedSize == inputSize);
+    if (compressedData->size() == inputSize) {
+        REPORTER_ASSERT(reporter, memcmp(testStream->getMemoryBase(),
+                                         compressedData->data(),
+                                         compressedData->size()) == 0);
+    }
 
     // Check that the uncompressed data matches the source data.
-    SkAutoDataUnref data2(uncompressed.copyToData());
-    REPORTER_ASSERT(reporter, testData.getLength() == uncompressed.getOffset());
-    REPORTER_ASSERT(reporter, memcmp(testData.getMemoryBase(),
-                                     data2->data(),
-                                     testData.getLength()) == 0);
+    SkAutoDataUnref uncompressedData(uncompressed.copyToData());
+    REPORTER_ASSERT(reporter, dataSize == uncompressedData->size());
+    if (dataSize == uncompressedData->size()) {
+        REPORTER_ASSERT(reporter, memcmp(testData->data(),
+                                         uncompressedData->data(),
+                                         dataSize) == 0);
+    }
+
+    if (compressedSize < 1) { return; }
+
+    double compressionRatio = static_cast<double>(dataSize) / compressedSize;
+    // Assert that some compression took place.
+    REPORTER_ASSERT(reporter, compressionRatio > 1.2);
+
+    if (reporter->verbose()) {
+        SkDebugf("Flate Test: \t input size: " SK_SIZE_T_SPECIFIER
+                 "\tcompressed size: " SK_SIZE_T_SPECIFIER
+                 "\tratio: %.4g\n",
+                 dataSize, compressedSize, compressionRatio);
+    }
 }
 
 DEF_TEST(Flate, reporter) {
-    TestFlate(reporter, NULL, 0);
-#if defined(SK_ZLIB_INCLUDE) && !defined(SK_DEBUG)
+#ifdef SK_HAS_ZLIB
     REPORTER_ASSERT(reporter, SkFlate::HaveFlate());
-
-    SkMemoryStream memStream;
-    TestFlate(reporter, &memStream, 512);
-    TestFlate(reporter, &memStream, 10240);
-
-    SkZeroSizeMemStream fileStream;
-    TestFlate(reporter, &fileStream, 512);
-    TestFlate(reporter, &fileStream, 10240);
 #endif
+    if (SkFlate::HaveFlate()) {
+        SkMemoryStream memStream;
+        TestFlate(reporter, &memStream, 512);
+        TestFlate(reporter, &memStream, 10240);
+
+        SkZeroSizeMemStream fileStream;
+        TestFlate(reporter, &fileStream, 512);
+        TestFlate(reporter, &fileStream, 10240);
+    }
 }
diff --git a/tests/FloatingPointTextureTest.cpp b/tests/FloatingPointTextureTest.cpp
new file mode 100644
index 0000000..d367659
--- /dev/null
+++ b/tests/FloatingPointTextureTest.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * This is a straightforward test of floating point textures, which are
+ * supported on some platforms.  As of right now, this test only supports
+ * 32 bit floating point textures, and indeed floating point test values
+ * have been selected to require 32 bits of precision and full IEEE conformance
+ */
+#if SK_SUPPORT_GPU
+#include <float.h>
+#include "Test.h"
+#include "GrContext.h"
+#include "GrTexture.h"
+#include "GrContextFactory.h"
+#include "SkGpuDevice.h"
+
+static const int DEV_W = 100, DEV_H = 100;
+static const int FP_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * sizeof(float);
+static const float kMaxIntegerRepresentableInSPFloatingPoint = 16777216;  // 2 ^ 24
+
+static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H);
+
+DEF_GPUTEST(FloatingPointTextureTest, reporter, factory) {
+    float controlPixelData[FP_CONTROL_ARRAY_SIZE];
+    float readBuffer[FP_CONTROL_ARRAY_SIZE];
+    for (int i = 0; i < FP_CONTROL_ARRAY_SIZE; i += 4) {
+        controlPixelData[i] = FLT_MIN;
+        controlPixelData[i + 1] = FLT_MAX;
+        controlPixelData[i + 2] = FLT_EPSILON;
+        controlPixelData[i + 3] = kMaxIntegerRepresentableInSPFloatingPoint;
+    }
+
+    for (int origin = 0; origin < 2; ++origin) {
+        int glCtxTypeCnt = 1;
+        glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt;
+        for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) {
+            GrTextureDesc desc;
+            desc.fFlags = kRenderTarget_GrTextureFlagBit;
+            desc.fWidth = DEV_W;
+            desc.fHeight = DEV_H;
+            desc.fConfig = kRGBA_float_GrPixelConfig;
+            desc.fOrigin = 0 == origin ?
+                kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
+
+            GrContext* context = NULL;
+            GrContextFactory::GLContextType type =
+                    static_cast<GrContextFactory::GLContextType>(glCtxType);
+            if (!GrContextFactory::IsRenderingGLContext(type)) {
+                continue;
+            }
+            context = factory->get(type);
+            if (NULL == context){
+                continue;
+            }
+
+            SkAutoTUnref<GrTexture> fpTexture(context->createUncachedTexture(desc,
+                                                                             NULL,
+                                                                             0));
+
+            // Floating point textures are NOT supported everywhere
+            if (NULL == fpTexture) {
+                continue;
+            }
+
+            // write square
+            context->writeTexturePixels(fpTexture, 0, 0, DEV_W, DEV_H, desc.fConfig,
+                    controlPixelData, 0);
+            context->readTexturePixels(fpTexture, 0, 0, DEV_W, DEV_H, desc.fConfig, readBuffer, 0);
+            for (int j = 0; j < FP_CONTROL_ARRAY_SIZE; ++j) {
+                REPORTER_ASSERT(reporter, readBuffer[j] == controlPixelData[j]);
+            }
+        }
+    }
+}
+
+#endif
diff --git a/tests/FontConfigParser.cpp b/tests/FontConfigParser.cpp
new file mode 100644
index 0000000..86b2b1d
--- /dev/null
+++ b/tests/FontConfigParser.cpp
@@ -0,0 +1,115 @@
+/*
+ * 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 "Resources.h"
+#include "SkFontConfigParser_android.h"
+#include "Test.h"
+
+int CountFallbacks(SkTDArray<FontFamily*> fontFamilies) {
+    int countOfFallbackFonts = 0;
+    for (int i = 0; i < fontFamilies.count(); i++) {
+        if (fontFamilies[i]->fIsFallbackFont) {
+            countOfFallbackFonts++;
+        }
+    }
+    return countOfFallbackFonts;
+}
+
+void ValidateLoadedFonts(SkTDArray<FontFamily*> fontFamilies,
+                         skiatest::Reporter* reporter) {
+    REPORTER_ASSERT(reporter, fontFamilies[0]->fNames.count() == 5);
+    REPORTER_ASSERT(reporter, !strcmp(fontFamilies[0]->fNames[0].c_str(), "sans-serif"));
+    REPORTER_ASSERT(reporter,
+                    !strcmp(fontFamilies[0]->fFonts[0].fFileName.c_str(),
+                            "Roboto-Regular.ttf"));
+    REPORTER_ASSERT(reporter, !fontFamilies[0]->fIsFallbackFont);
+}
+
+void DumpLoadedFonts(SkTDArray<FontFamily*> fontFamilies) {
+#if SK_DEBUG_FONTS
+    for (int i = 0; i < fontFamilies.count(); ++i) {
+        SkDebugf("Family %d:\n", i);
+        switch(fontFamilies[i]->fVariant) {
+            case SkPaintOptionsAndroid::kElegant_Variant: SkDebugf("  elegant"); break;
+            case SkPaintOptionsAndroid::kCompact_Variant: SkDebugf("  compact"); break;
+            default: break;
+        }
+        if (!fontFamilies[i]->fLanguage.getTag().isEmpty()) {
+            SkDebugf("  language: %s", fontFamilies[i]->fLanguage.getTag().c_str());
+        }
+        for (int j = 0; j < fontFamilies[i]->fNames.count(); ++j) {
+            SkDebugf("  name %s\n", fontFamilies[i]->fNames[j].c_str());
+        }
+        for (int j = 0; j < fontFamilies[i]->fFonts.count(); ++j) {
+            const FontFileInfo& ffi = fontFamilies[i]->fFonts[j];
+            SkDebugf("  file (%d %s %d) %s\n",
+                     ffi.fWeight,
+                     ffi.fPaintOptions.getLanguage().getTag().isEmpty() ? "" :
+                         ffi.fPaintOptions.getLanguage().getTag().c_str(),
+                     ffi.fPaintOptions.getFontVariant(),
+                     ffi.fFileName.c_str());
+        }
+    }
+#endif // SK_DEBUG_FONTS
+}
+
+DEF_TEST(FontConfigParserAndroid, reporter) {
+
+    bool resourcesMissing = false;
+
+    SkTDArray<FontFamily*> preV17FontFamilies;
+    SkFontConfigParser::GetTestFontFamilies(preV17FontFamilies,
+        GetResourcePath("android_fonts/pre_v17/system_fonts.xml").c_str(),
+        GetResourcePath("android_fonts/pre_v17/fallback_fonts.xml").c_str());
+
+    if (preV17FontFamilies.count() > 0) {
+        REPORTER_ASSERT(reporter, preV17FontFamilies.count() == 14);
+        REPORTER_ASSERT(reporter, CountFallbacks(preV17FontFamilies) == 10);
+
+        DumpLoadedFonts(preV17FontFamilies);
+        ValidateLoadedFonts(preV17FontFamilies, reporter);
+    } else {
+        resourcesMissing = true;
+    }
+
+
+    SkTDArray<FontFamily*> v17FontFamilies;
+    SkFontConfigParser::GetTestFontFamilies(v17FontFamilies,
+        GetResourcePath("android_fonts/v17/system_fonts.xml").c_str(),
+        GetResourcePath("android_fonts/v17/fallback_fonts.xml").c_str());
+
+    if (v17FontFamilies.count() > 0) {
+        REPORTER_ASSERT(reporter, v17FontFamilies.count() == 41);
+        REPORTER_ASSERT(reporter, CountFallbacks(v17FontFamilies) == 31);
+
+        DumpLoadedFonts(v17FontFamilies);
+        ValidateLoadedFonts(v17FontFamilies, reporter);
+    } else {
+        resourcesMissing = true;
+    }
+
+
+    SkTDArray<FontFamily*> v22FontFamilies;
+    SkFontConfigParser::GetTestFontFamilies(v22FontFamilies,
+        GetResourcePath("android_fonts/v22/fonts.xml").c_str(),
+        NULL);
+
+    if (v22FontFamilies.count() > 0) {
+        REPORTER_ASSERT(reporter, v22FontFamilies.count() == 53);
+        REPORTER_ASSERT(reporter, CountFallbacks(v22FontFamilies) == 42);
+
+        DumpLoadedFonts(v22FontFamilies);
+        ValidateLoadedFonts(v22FontFamilies, reporter);
+    } else {
+        resourcesMissing = true;
+    }
+
+    if (resourcesMissing) {
+        SkDebugf("---- Resource files missing for FontConfigParser test\n");
+    }
+}
+
diff --git a/tests/FontHostStreamTest.cpp b/tests/FontHostStreamTest.cpp
index 5f959f3..a2254fd 100644
--- a/tests/FontHostStreamTest.cpp
+++ b/tests/FontHostStreamTest.cpp
@@ -8,6 +8,7 @@
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkColor.h"
+#include "SkFontDescriptor.h"
 #include "SkFontHost.h"
 #include "SkGraphics.h"
 #include "SkPaint.h"
@@ -98,6 +99,12 @@
         int ttcIndex;
         SkAutoTUnref<SkStream> fontData(origTypeface->openStream(&ttcIndex));
         SkTypeface* streamTypeface = SkTypeface::CreateFromStream(fontData);
+
+        SkFontDescriptor desc;
+        bool isLocalStream = false;
+        streamTypeface->getFontDescriptor(&desc, &isLocalStream);
+        REPORTER_ASSERT(reporter, isLocalStream);
+
         SkSafeUnref(paint.setTypeface(streamTypeface));
         drawBG(&streamCanvas);
         streamCanvas.drawPosText("A", 1, &point, paint);
diff --git a/tests/FontHostTest.cpp b/tests/FontHostTest.cpp
index 23625b3..249fe7b 100644
--- a/tests/FontHostTest.cpp
+++ b/tests/FontHostTest.cpp
@@ -27,7 +27,6 @@
 } gKnownTableSizes[] = {
     {   kFontTableTag_head,         54 },
     {   kFontTableTag_hhea,         36 },
-    {   kFontTableTag_maxp,         32 },
 };
 
 // Test that getUnitsPerEm() agrees with a direct lookup in the 'head' table
@@ -69,9 +68,10 @@
 }
 
 // The following three are all the same code points in various encodings.
-static uint8_t utf8Chars[] = { 0x61, 0xE4, 0xB8, 0xAD, 0xD0, 0xAF, 0xD7, 0x99, 0xD7, 0x95, 0xF0, 0x9D, 0x84, 0x9E, 0x61 };
-static uint16_t utf16Chars[] = { 0x0061, 0x4E2D, 0x042F, 0x05D9, 0x05D5, 0xD834, 0xDD1E, 0x0061 };
-static uint32_t utf32Chars[] = { 0x00000061, 0x00004E2D, 0x0000042F, 0x000005D9, 0x000005D5, 0x0001D11E, 0x00000061 };
+// a中Яיו𝄞a𠮟
+static uint8_t utf8Chars[] = { 0x61, 0xE4,0xB8,0xAD, 0xD0,0xAF, 0xD7,0x99, 0xD7,0x95, 0xF0,0x9D,0x84,0x9E, 0x61, 0xF0,0xA0,0xAE,0x9F };
+static uint16_t utf16Chars[] = { 0x0061, 0x4E2D, 0x042F, 0x05D9, 0x05D5, 0xD834,0xDD1E, 0x0061, 0xD842,0xDF9F };
+static uint32_t utf32Chars[] = { 0x00000061, 0x00004E2D, 0x0000042F, 0x000005D9, 0x000005D5, 0x0001D11E, 0x00000061, 0x00020B9F };
 
 struct CharsToGlyphs_TestData {
     const void* chars;
@@ -80,9 +80,9 @@
     SkTypeface::Encoding typefaceEncoding;
     const char* name;
 } static charsToGlyphs_TestData[] = {
-    { utf8Chars, 7, sizeof(utf8Chars), SkTypeface::kUTF8_Encoding, "Simple UTF-8" },
-    { utf16Chars, 7, sizeof(utf16Chars), SkTypeface::kUTF16_Encoding, "Simple UTF-16" },
-    { utf32Chars, 7, sizeof(utf32Chars), SkTypeface::kUTF32_Encoding, "Simple UTF-32" },
+    { utf8Chars, 8, sizeof(utf8Chars), SkTypeface::kUTF8_Encoding, "Simple UTF-8" },
+    { utf16Chars, 8, sizeof(utf16Chars), SkTypeface::kUTF16_Encoding, "Simple UTF-16" },
+    { utf32Chars, 8, sizeof(utf32Chars), SkTypeface::kUTF32_Encoding, "Simple UTF-32" },
 };
 
 // Test that SkPaint::textToGlyphs agrees with SkTypeface::charsToGlyphs.
@@ -155,7 +155,7 @@
         SkDebugf("Could not run fontstream test because resourcePath not specified.");
         return;
     }
-    SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), "test.ttc");
+    SkString filename = SkOSPath::Join(resourcePath.c_str(), "test.ttc");
 
     SkFILEStream stream(filename.c_str());
     if (stream.isValid()) {
@@ -211,8 +211,11 @@
 static void test_tables(skiatest::Reporter* reporter) {
     static const char* const gNames[] = {
         NULL,   // default font
-        "Arial", "Times", "Times New Roman", "Helvetica", "Courier",
-        "Courier New", "Terminal", "MS Sans Serif",
+        "Helvetica", "Arial",
+        "Times", "Times New Roman",
+        "Courier", "Courier New",
+        "Terminal", "MS Sans Serif",
+        "Hiragino Mincho ProN", "MS PGothic",
     };
 
     for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) {
diff --git a/tests/FontMgrTest.cpp b/tests/FontMgrTest.cpp
index c9aa778..a1dc9dc 100644
--- a/tests/FontMgrTest.cpp
+++ b/tests/FontMgrTest.cpp
@@ -16,7 +16,7 @@
     uint32_t flags = 0;
     SkAutoTUnref<SkFont> font(SkFont::Create(NULL, 24, SkFont::kA8_MaskType, flags));
 
-    REPORTER_ASSERT(reporter, NULL != font->getTypeface());
+    REPORTER_ASSERT(reporter, font->getTypeface());
     REPORTER_ASSERT(reporter, 24 == font->getSize());
     REPORTER_ASSERT(reporter, 1 == font->getScaleX());
     REPORTER_ASSERT(reporter, 0 == font->getSkewX());
diff --git a/tests/FontNamesTest.cpp b/tests/FontNamesTest.cpp
index e4966b0..5c314e4 100644
--- a/tests/FontNamesTest.cpp
+++ b/tests/FontNamesTest.cpp
@@ -152,10 +152,6 @@
             set->getStyle(j, &fs, &sname);
 
             SkAutoTUnref<SkTypeface> typeface(set->createTypeface(j));
-            if (NULL == typeface.get()) {
-                //TODO: SkFontMgr_fontconfig always returns NULL?
-                continue;
-            }
 
             SkString familyName;
             typeface->getFamilyName(&familyName);
@@ -169,7 +165,7 @@
             while (familyNamesIter->next(&familyNameLocalized)) {
                 if (verbose) {
                     SkDebugf("(%s) <%s>\n", familyNameLocalized.fString.c_str(),
-                                          familyNameLocalized.fLanguage.c_str());
+                                            familyNameLocalized.fLanguage.c_str());
                 }
             }
 
diff --git a/tests/GLInterfaceValidationTest.cpp b/tests/GLInterfaceValidationTest.cpp
index 541af8f..797ba72 100755
--- a/tests/GLInterfaceValidationTest.cpp
+++ b/tests/GLInterfaceValidationTest.cpp
@@ -22,14 +22,14 @@
         // We're supposed to fail the NVPR context type when we the native context that does not
         // support the NVPR extension.
         if (GrContextFactory::kNVPR_GLContextType == glCtxType &&
-            NULL != factory->getGLContext(GrContextFactory::kNative_GLContextType) &&
+            factory->getGLContext(GrContextFactory::kNative_GLContextType) &&
             !factory->getGLContext(GrContextFactory::kNative_GLContextType)->hasExtension("GL_NV_path_rendering")) {
             REPORTER_ASSERT(reporter, NULL == glCtxHelper);
             continue;
         }
 
-        REPORTER_ASSERT(reporter, NULL != glCtxHelper);
-        if (NULL != glCtxHelper) {
+        REPORTER_ASSERT(reporter, glCtxHelper);
+        if (glCtxHelper) {
             const GrGLInterface* interface = glCtxHelper->gl();
             REPORTER_ASSERT(reporter, interface->validate());
         }
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 3df08a7..a16173b 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -12,31 +12,100 @@
 
 #if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
 
-#include "GrBackendEffectFactory.h"
+#include "GrBackendProcessorFactory.h"
 #include "GrContextFactory.h"
-#include "GrDrawEffect.h"
+#include "GrOptDrawState.h"
 #include "effects/GrConfigConversionEffect.h"
+#include "gl/GrGLPathRendering.h"
 #include "gl/GrGpuGL.h"
-
 #include "SkChecksum.h"
 #include "SkRandom.h"
 #include "Test.h"
 
-void GrGLProgramDesc::setRandom(SkRandom* random,
-                                const GrGpuGL* gpu,
+static void get_stage_stats(const GrFragmentStage stage, bool* readsDst,
+                            bool* readsFragPosition, bool* requiresVertexShader) {
+    if (stage.getFragmentProcessor()->willReadDstColor()) {
+        *readsDst = true;
+    }
+    if (stage.getProcessor()->willReadFragmentPosition()) {
+        *readsFragPosition = true;
+    }
+}
+
+bool GrGLProgramDesc::setRandom(SkRandom* random,
+                                GrGpuGL* gpu,
                                 const GrRenderTarget* dstRenderTarget,
                                 const GrTexture* dstCopyTexture,
-                                const GrEffectStage* stages[],
+                                const GrGeometryStage* geometryProcessor,
+                                const GrFragmentStage* stages[],
                                 int numColorStages,
                                 int numCoverageStages,
-                                int currAttribIndex) {
-    int numEffects = numColorStages + numCoverageStages;
-    size_t keyLength = KeyLength(numEffects);
-    fKey.reset(keyLength);
-    *this->atOffset<uint32_t, kLengthOffset>() = static_cast<uint32_t>(keyLength);
-    memset(this->header(), 0, kHeaderSize);
+                                int currAttribIndex,
+                                GrGpu::DrawType drawType) {
+    bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType);
+    bool useLocalCoords = !isPathRendering &&
+                          random->nextBool() &&
+                          currAttribIndex < GrDrawState::kMaxVertexAttribCnt;
+
+    int numStages = numColorStages + numCoverageStages;
+    fKey.reset();
+
+    GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t));
+
+    // Make room for everything up to and including the array of offsets to effect keys.
+    fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * (numStages +
+            (geometryProcessor ? 1 : 0)));
+
+    bool dstRead = false;
+    bool fragPos = false;
+    bool vertexShader = SkToBool(geometryProcessor);
+    int offset = 0;
+    if (geometryProcessor) {
+        const GrGeometryStage* stage = geometryProcessor;
+        uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() +
+                                                              kEffectKeyOffsetsAndLengthOffset +
+                                                              offset * 2 * sizeof(uint16_t));
+        uint32_t effectKeyOffset = fKey.count();
+        if (effectKeyOffset > SK_MaxU16) {
+            fKey.reset();
+            return false;
+        }
+        GrProcessorKeyBuilder b(&fKey);
+        uint16_t effectKeySize;
+        if (!GetProcessorKey(*stage, gpu->glCaps(), useLocalCoords, &b, &effectKeySize)) {
+            fKey.reset();
+            return false;
+        }
+        vertexShader = true;
+        fragPos = stage->getProcessor()->willReadFragmentPosition();
+        offsetAndSize[0] = effectKeyOffset;
+        offsetAndSize[1] = effectKeySize;
+        offset++;
+    }
+
+    for (int s = 0; s < numStages; ++s, ++offset) {
+        const GrFragmentStage* stage = stages[s];
+        uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() +
+                                                              kEffectKeyOffsetsAndLengthOffset +
+                                                              offset * 2 * sizeof(uint16_t));
+        uint32_t effectKeyOffset = fKey.count();
+        if (effectKeyOffset > SK_MaxU16) {
+            fKey.reset();
+            return false;
+        }
+        GrProcessorKeyBuilder b(&fKey);
+        uint16_t effectKeySize;
+        if (!GetProcessorKey(*stages[s], gpu->glCaps(), useLocalCoords, &b, &effectKeySize)) {
+            fKey.reset();
+            return false;
+        }
+        get_stage_stats(*stage, &dstRead, &fragPos, &vertexShader);
+        offsetAndSize[0] = effectKeyOffset;
+        offsetAndSize[1] = effectKeySize;
+    }
 
     KeyHeader* header = this->header();
+    memset(header, 0, kHeaderSize);
     header->fEmitsPointSize = random->nextBool();
 
     header->fPositionAttributeIndex = 0;
@@ -45,8 +114,8 @@
     // don't try to use color or coverage attributes as input
     do {
         header->fColorInput = static_cast<GrGLProgramDesc::ColorInput>(
-                                  random->nextULessThan(kColorInputCnt));
-    } while (GrDrawState::kMaxVertexAttribCnt <= currAttribIndex &&
+                                     random->nextULessThan(kColorInputCnt));
+    } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRendering) &&
              kAttribute_ColorInput == header->fColorInput);
     header->fColorAttributeIndex = (header->fColorInput == kAttribute_ColorInput) ?
                                         currAttribIndex++ :
@@ -55,74 +124,95 @@
     do {
         header->fCoverageInput = static_cast<GrGLProgramDesc::ColorInput>(
                                      random->nextULessThan(kColorInputCnt));
-    } while (GrDrawState::kMaxVertexAttribCnt <= currAttribIndex  &&
+    } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRendering)  &&
              kAttribute_ColorInput == header->fCoverageInput);
     header->fCoverageAttributeIndex = (header->fCoverageInput == kAttribute_ColorInput) ?
                                         currAttribIndex++ :
                                         -1;
-
+    bool useGS = random->nextBool();
 #if GR_GL_EXPERIMENTAL_GS
-    header->fExperimentalGS = gpu->caps()->geometryShaderSupport() && random->nextBool();
+    header->fExperimentalGS = gpu->caps()->geometryShaderSupport() && useGS;
+#else
+    (void) useGS;
 #endif
 
-    bool useLocalCoords = random->nextBool() && currAttribIndex < GrDrawState::kMaxVertexAttribCnt;
     header->fLocalCoordAttributeIndex = useLocalCoords ? currAttribIndex++ : -1;
 
     header->fColorEffectCnt = numColorStages;
     header->fCoverageEffectCnt = numCoverageStages;
 
-    bool dstRead = false;
-    bool fragPos = false;
-    bool vertexCode = false;
-    int numStages = numColorStages + numCoverageStages;
-    for (int s = 0; s < numStages; ++s) {
-        const GrBackendEffectFactory& factory = (*stages[s]->getEffect())->getFactory();
-        GrDrawEffect drawEffect(*stages[s], useLocalCoords);
-        this->effectKeys()[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
-        if ((*stages[s]->getEffect())->willReadDstColor()) {
-            dstRead = true;
-        }
-        if ((*stages[s]->getEffect())->willReadFragmentPosition()) {
-            fragPos = true;
-        }
-        if ((*stages[s]->getEffect())->hasVertexCode()) {
-            vertexCode = true;
-        }
-    }
-
     if (dstRead) {
-        header->fDstReadKey = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps());
+        header->fDstReadKey = SkToU8(GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
+                                                                      gpu->glCaps()));
     } else {
         header->fDstReadKey = 0;
     }
     if (fragPos) {
-        header->fFragPosKey = GrGLShaderBuilder::KeyForFragmentPosition(dstRenderTarget,
-                                                                         gpu->glCaps());
+        header->fFragPosKey = SkToU8(GrGLFragmentShaderBuilder::KeyForFragmentPosition(dstRenderTarget,
+                                                                               gpu->glCaps()));
     } else {
         header->fFragPosKey = 0;
     }
 
-    header->fHasVertexCode = vertexCode ||
-                             useLocalCoords ||
-                             kAttribute_ColorInput == header->fColorInput ||
-                             kAttribute_ColorInput == header->fCoverageInput;
+    header->fUseFragShaderOnly = isPathRendering && gpu->glPathRendering()->texturingMode() ==
+                                                    GrGLPathRendering::FixedFunction_TexturingMode;
+    header->fHasGeometryProcessor = vertexShader;
 
-    CoverageOutput coverageOutput;
-    bool illegalCoverageOutput;
-    do {
-        coverageOutput = static_cast<CoverageOutput>(random->nextULessThan(kCoverageOutputCnt));
-        illegalCoverageOutput = (!gpu->caps()->dualSourceBlendingSupport() &&
-                                 CoverageOutputUsesSecondaryOutput(coverageOutput)) ||
-                                (!dstRead && kCombineWithDst_CoverageOutput == coverageOutput);
-    } while (illegalCoverageOutput);
+    GrOptDrawState::PrimaryOutputType primaryOutput;
+    GrOptDrawState::SecondaryOutputType secondaryOutput;
+    if (!dstRead) {
+        primaryOutput = GrOptDrawState::kModulate_PrimaryOutputType;
+    } else {
+        primaryOutput = static_cast<GrOptDrawState::PrimaryOutputType>(
+            random->nextULessThan(GrOptDrawState::kPrimaryOutputTypeCnt));
+    }
 
-    header->fCoverageOutput = coverageOutput;
+    if (GrOptDrawState::kCombineWithDst_PrimaryOutputType == primaryOutput ||
+        !gpu->caps()->dualSourceBlendingSupport()) {
+        secondaryOutput = GrOptDrawState::kNone_SecondaryOutputType;
+    } else {
+        secondaryOutput = static_cast<GrOptDrawState::SecondaryOutputType>(
+            random->nextULessThan(GrOptDrawState::kSecondaryOutputTypeCnt));
+    }
 
-    *this->checksum() = 0;
-    *this->checksum() = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.get()), keyLength);
-    fInitialized = true;
+    header->fPrimaryOutputType = primaryOutput;
+    header->fSecondaryOutputType = secondaryOutput;
+
+    this->finalize();
+    return true;
 }
 
+// TODO clean this up, we have to do this to test geometry processors but there has got to be
+// a better way.  In the mean time, we actually fill out these generic vertex attribs below with
+// the correct vertex attribs from the GP.  We have to ensure, however, we don't try to add more
+// than two attributes.
+GrVertexAttrib genericVertexAttribs[] = {
+    { kVec2f_GrVertexAttribType, 0,   kPosition_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, 0,   kGeometryProcessor_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, 0,   kGeometryProcessor_GrVertexAttribBinding }
+};
+
+/*
+ * convert sl type to vertexattrib type, not a complete implementation, only use for debugging
+ */
+GrVertexAttribType convert_sltype_to_attribtype(GrSLType type) {
+    switch (type) {
+        case kFloat_GrSLType:
+            return kFloat_GrVertexAttribType;
+        case kVec2f_GrSLType:
+            return kVec2f_GrVertexAttribType;
+        case kVec3f_GrSLType:
+            return kVec3f_GrVertexAttribType;
+        case kVec4f_GrSLType:
+            return kVec4f_GrVertexAttribType;
+        default:
+            SkFAIL("Type isn't convertible");
+            return kFloat_GrVertexAttribType;
+    }
+}
+// TODO end test hack
+
+
 bool GrGpuGL::programUnitTest(int maxStages) {
 
     GrTextureDesc dummyDesc;
@@ -137,6 +227,10 @@
     dummyDesc.fHeight = 22;
     SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0));
 
+    if (!dummyTexture1 || ! dummyTexture2) {
+        return false;
+    }
+
     static const int NUM_TESTS = 512;
 
     SkRandom random;
@@ -154,65 +248,93 @@
 
         int currAttribIndex = 1;  // we need to always leave room for position
         int currTextureCoordSet = 0;
-        int attribIndices[2] = { 0, 0 };
         GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
 
         int numStages = random.nextULessThan(maxStages + 1);
         int numColorStages = random.nextULessThan(numStages + 1);
         int numCoverageStages = numStages - numColorStages;
 
-        SkAutoSTMalloc<8, const GrEffectStage*> stages(numStages);
+        SkAutoSTMalloc<8, const GrFragmentStage*> stages(numStages);
 
-        bool useFixedFunctionTexturing = this->shouldUseFixedFunctionTexturing();
+        bool usePathRendering = this->glCaps().pathRenderingSupport() && random.nextBool();
 
+        GrGpu::DrawType drawType = usePathRendering ? GrGpu::kDrawPath_DrawType :
+                                                      GrGpu::kDrawPoints_DrawType;
+
+        SkAutoTDelete<GrGeometryStage> geometryProcessor;
+        bool hasGeometryProcessor = usePathRendering ? false : random.nextBool();
+        if (hasGeometryProcessor) {
+            while (true) {
+                SkAutoTUnref<const GrGeometryProcessor> effect(
+                        GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(&random, this->getContext(), *this->caps(),
+                                                         dummyTextures));
+                SkASSERT(effect);
+                // Only geometryProcessor can use vertex shader
+                GrGeometryStage* stage = SkNEW_ARGS(GrGeometryStage, (effect.get()));
+                geometryProcessor.reset(stage);
+
+                // we have to set dummy vertex attribs
+                const GrGeometryProcessor::VertexAttribArray& v = effect->getVertexAttribs();
+                int numVertexAttribs = v.count();
+
+                SkASSERT(GrGeometryProcessor::kMaxVertexAttribs == 2 &&
+                         GrGeometryProcessor::kMaxVertexAttribs >= numVertexAttribs);
+                size_t runningStride = GrVertexAttribTypeSize(genericVertexAttribs[0].fType);
+                for (int i = 0; i < numVertexAttribs; i++) {
+                    genericVertexAttribs[i + 1].fOffset = runningStride;
+                    genericVertexAttribs[i + 1].fType =
+                            convert_sltype_to_attribtype(v[i].getType());
+                    runningStride += GrVertexAttribTypeSize(genericVertexAttribs[i + 1].fType);
+                }
+
+                // update the vertex attributes with the ds
+                GrDrawState* ds = this->drawState();
+                ds->setVertexAttribs<genericVertexAttribs>(numVertexAttribs + 1, runningStride);
+                currAttribIndex = numVertexAttribs + 1;
+                break;
+            }
+        }
         for (int s = 0; s < numStages;) {
-            SkAutoTUnref<const GrEffectRef> effect(GrEffectTestFactory::CreateStage(
+            SkAutoTUnref<const GrFragmentProcessor> effect(
+                    GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(
                                                                             &random,
                                                                             this->getContext(),
                                                                             *this->caps(),
                                                                             dummyTextures));
             SkASSERT(effect);
-            int numAttribs = (*effect)->numVertexAttribs();
-
-            // If adding this effect would exceed the max attrib count then generate a
-            // new random effect.
-            if (currAttribIndex + numAttribs > GrDrawState::kMaxVertexAttribCnt) {
-                continue;
-            }
-
 
             // If adding this effect would exceed the max texture coord set count then generate a
             // new random effect.
-            if (useFixedFunctionTexturing && !(*effect)->hasVertexCode()) {
-                int numTransforms = (*effect)->numTransforms();
+            if (usePathRendering && this->glPathRendering()->texturingMode() ==
+                                    GrGLPathRendering::FixedFunction_TexturingMode) {;
+                int numTransforms = effect->numTransforms();
                 if (currTextureCoordSet + numTransforms > this->glCaps().maxFixedFunctionTextureCoords()) {
                     continue;
                 }
                 currTextureCoordSet += numTransforms;
             }
+            GrFragmentStage* stage = SkNEW_ARGS(GrFragmentStage, (effect.get()));
 
-            useFixedFunctionTexturing = useFixedFunctionTexturing && !(*effect)->hasVertexCode();
-
-            for (int i = 0; i < numAttribs; ++i) {
-                attribIndices[i] = currAttribIndex++;
-            }
-            GrEffectStage* stage = SkNEW_ARGS(GrEffectStage,
-                                              (effect.get(), attribIndices[0], attribIndices[1]));
             stages[s] = stage;
             ++s;
         }
         const GrTexture* dstTexture = random.nextBool() ? dummyTextures[0] : dummyTextures[1];
-        pdesc.setRandom(&random,
-                        this,
-                        dummyTextures[0]->asRenderTarget(),
-                        dstTexture,
-                        stages.get(),
-                        numColorStages,
-                        numCoverageStages,
-                        currAttribIndex);
+        if (!pdesc.setRandom(&random,
+                             this,
+                             dummyTextures[0]->asRenderTarget(),
+                             dstTexture,
+                             geometryProcessor.get(),
+                             stages.get(),
+                             numColorStages,
+                             numCoverageStages,
+                             currAttribIndex,
+                             drawType)) {
+            return false;
+        }
 
         SkAutoTUnref<GrGLProgram> program(GrGLProgram::Create(this,
                                                               pdesc,
+                                                              geometryProcessor.get(),
                                                               stages,
                                                               stages + numColorStages));
         for (int s = 0; s < numStages; ++s) {
@@ -221,6 +343,9 @@
         if (NULL == program.get()) {
             return false;
         }
+
+        // We have to reset the drawstate because we might have added a gp
+        this->drawState()->reset();
     }
     return true;
 }
@@ -228,7 +353,7 @@
 DEF_GPUTEST(GLPrograms, reporter, factory) {
     for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
         GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(type));
-        if (NULL != context) {
+        if (context) {
             GrGpuGL* gpu = static_cast<GrGpuGL*>(context->getGpu());
             int maxStages = 6;
 #if SK_ANGLE
@@ -257,7 +382,7 @@
 void forceLinking() {
     SkLightingImageFilter::CreateDistantLitDiffuse(SkPoint3(0,0,0), 0, 0, 0);
     SkAlphaThresholdFilter::Create(SkRegion(), .5f, .5f);
-    SkAutoTUnref<SkMagnifierImageFilter> mag(SkMagnifierImageFilter::Create(
+    SkAutoTUnref<SkImageFilter> mag(SkMagnifierImageFilter::Create(
         SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1));
     GrConfigConversionEffect::Create(NULL,
                                      false,
diff --git a/tests/GpuColorFilterTest.cpp b/tests/GpuColorFilterTest.cpp
index 9ba9431..202756b 100644
--- a/tests/GpuColorFilterTest.cpp
+++ b/tests/GpuColorFilterTest.cpp
@@ -10,7 +10,7 @@
 
 #include "GrContext.h"
 #include "GrContextFactory.h"
-#include "GrEffect.h"
+#include "GrProcessor.h"
 #include "SkColorFilter.h"
 #include "SkGr.h"
 #include "Test.h"
@@ -98,10 +98,10 @@
     for (size_t i = 0; i < SK_ARRAY_COUNT(filterTests); ++i) {
         const GetConstantComponentTestCase& test = filterTests[i];
         SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
-        SkAutoTUnref<GrEffectRef> grEffect(cf->asNewEffect(grContext));
+        SkAutoTUnref<GrFragmentProcessor> effect(cf->asFragmentProcessor(grContext));
         GrColor color = test.inputColor;
         uint32_t components = test.inputComponents;
-        grEffect->get()->getConstantColorComponents(&color, &components);
+        effect->getConstantColorComponents(&color, &components);
 
         REPORTER_ASSERT(reporter, filterColor(color, components) == test.outputColor);
         REPORTER_ASSERT(reporter, test.outputComponents == components);
diff --git a/tests/GpuDrawPathTest.cpp b/tests/GpuDrawPathTest.cpp
index 3dcba52..3e47a05 100644
--- a/tests/GpuDrawPathTest.cpp
+++ b/tests/GpuDrawPathTest.cpp
@@ -12,10 +12,10 @@
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkColor.h"
-#include "SkGpuDevice.h"
 #include "SkPaint.h"
 #include "SkRRect.h"
 #include "SkRect.h"
+#include "SkSurface.h"
 #include "Test.h"
 
 static void test_drawPathEmpty(skiatest::Reporter*, SkCanvas* canvas) {
@@ -54,20 +54,11 @@
         static const int sampleCounts[] = { 0, 4, 16 };
 
         for (size_t i = 0; i < SK_ARRAY_COUNT(sampleCounts); ++i) {
-            const int W = 255;
-            const int H = 255;
-
-            GrTextureDesc desc;
-            desc.fConfig = kSkia8888_GrPixelConfig;
-            desc.fFlags = kRenderTarget_GrTextureFlagBit;
-            desc.fWidth = W;
-            desc.fHeight = H;
-            desc.fSampleCnt = sampleCounts[i];
-            SkAutoTUnref<GrTexture> texture(grContext->createUncachedTexture(desc, NULL, 0));
-            SkAutoTUnref<SkGpuDevice> device(SkNEW_ARGS(SkGpuDevice, (grContext, texture.get())));
-            SkCanvas drawingCanvas(device.get());
-
-            test_drawPathEmpty(reporter, &drawingCanvas);
+            SkImageInfo info = SkImageInfo::MakeN32Premul(255, 255);
+            
+            SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(grContext, info,
+                                                                       sampleCounts[i], NULL));
+            test_drawPathEmpty(reporter, surface->getCanvas());
         }
     }
 }
diff --git a/tests/GpuLayerCacheTest.cpp b/tests/GpuLayerCacheTest.cpp
new file mode 100644
index 0000000..c9b88f5
--- /dev/null
+++ b/tests/GpuLayerCacheTest.cpp
@@ -0,0 +1,214 @@
+/*
+* Copyright 2014 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#if SK_SUPPORT_GPU
+
+#include "GrContext.h"
+#include "GrContextFactory.h"
+#include "GrLayerCache.h"
+#include "SkPictureRecorder.h"
+#include "Test.h"
+
+class TestingAccess {
+public:
+    static int NumLayers(GrLayerCache* cache) {
+        return cache->numLayers();
+    }
+    static void Purge(GrLayerCache* cache, uint32_t pictureID) {
+        cache->purge(pictureID);
+    }
+};
+
+// Add several layers to the cache
+static void create_layers(skiatest::Reporter* reporter,
+                          GrLayerCache* cache,
+                          const SkPicture& picture,
+                          int numToAdd,
+                          int idOffset) {
+
+    for (int i = 0; i < numToAdd; ++i) {
+        GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(), 
+                                                        idOffset+i+1, idOffset+i+2, 
+                                                        SkIPoint::Make(0, 0),
+                                                        SkMatrix::I(),
+                                                        NULL);
+        REPORTER_ASSERT(reporter, layer);
+        GrCachedLayer* temp = cache->findLayer(picture.uniqueID(), idOffset+i+1, idOffset+i+2, 
+                                               SkIPoint::Make(0, 0), SkMatrix::I());
+        REPORTER_ASSERT(reporter, temp == layer);
+
+        REPORTER_ASSERT(reporter, TestingAccess::NumLayers(cache) == idOffset + i + 1);
+
+        REPORTER_ASSERT(reporter, picture.uniqueID() == layer->pictureID());
+        REPORTER_ASSERT(reporter, layer->start() == idOffset + i + 1);
+        REPORTER_ASSERT(reporter, layer->stop() == idOffset + i + 2);
+        REPORTER_ASSERT(reporter, layer->ctm() == SkMatrix::I());
+        REPORTER_ASSERT(reporter, NULL == layer->texture());
+        REPORTER_ASSERT(reporter, NULL == layer->paint());
+        REPORTER_ASSERT(reporter, !layer->isAtlased());
+    }
+
+    cache->trackPicture(&picture);
+}
+
+static void lock_layer(skiatest::Reporter* reporter,
+                       GrLayerCache* cache,
+                       GrCachedLayer* layer) {
+    // Make the layer 512x512 (so it can be atlased)
+    GrTextureDesc desc;
+    desc.fWidth = 512;
+    desc.fHeight = 512;
+    desc.fConfig = kSkia8888_GrPixelConfig;
+
+    bool needsRerendering = cache->lock(layer, desc, false);
+    REPORTER_ASSERT(reporter, needsRerendering);
+
+    needsRerendering = cache->lock(layer, desc, false);
+    REPORTER_ASSERT(reporter, !needsRerendering);
+
+    REPORTER_ASSERT(reporter, layer->texture());
+    REPORTER_ASSERT(reporter, layer->locked());
+}
+
+// This test case exercises the public API of the GrLayerCache class.
+// In particular it checks its interaction with the resource cache (w.r.t.
+// locking & unlocking textures).
+// TODO: need to add checks on VRAM usage!
+DEF_GPUTEST(GpuLayerCache, reporter, factory) {
+    static const int kInitialNumLayers = 5;
+
+    for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
+        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+
+        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
+            continue;
+        }
+
+        GrContext* context = factory->get(glCtxType);
+
+        if (NULL == context) {
+            continue;
+        }
+
+        SkPictureRecorder recorder;
+        recorder.beginRecording(1, 1);
+        SkAutoTUnref<const SkPicture> picture(recorder.endRecording());
+
+        GrLayerCache cache(context);
+
+        create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
+
+        for (int i = 0; i < kInitialNumLayers; ++i) {
+            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, i+2, 
+                                                   SkIPoint::Make(0, 0), SkMatrix::I());
+            REPORTER_ASSERT(reporter, layer);
+
+            lock_layer(reporter, &cache, layer);
+
+            // The first 4 layers should be in the atlas (and thus have non-empty
+            // rects)
+            if (i < 4) {
+                REPORTER_ASSERT(reporter, layer->isAtlased());
+            } else {
+                // The 5th layer couldn't fit in the atlas
+                REPORTER_ASSERT(reporter, !layer->isAtlased());
+            }
+        }
+
+        // Unlock the textures
+        for (int i = 0; i < kInitialNumLayers; ++i) {
+            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, i+2, 
+                                                   SkIPoint::Make(0, 0), SkMatrix::I());
+            REPORTER_ASSERT(reporter, layer);
+            cache.unlock(layer);
+        }
+
+        for (int i = 0; i < kInitialNumLayers; ++i) {
+            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, i+2, 
+                                                   SkIPoint::Make(0, 0), SkMatrix::I());
+            REPORTER_ASSERT(reporter, layer);
+
+            REPORTER_ASSERT(reporter, !layer->locked());
+            // The first 4 layers should still be in the atlas.
+            if (i < 4) {
+                REPORTER_ASSERT(reporter, layer->texture());
+                REPORTER_ASSERT(reporter, layer->isAtlased());
+            } else {
+                // The final layer should be unlocked.
+                REPORTER_ASSERT(reporter, NULL == layer->texture());
+                REPORTER_ASSERT(reporter, !layer->isAtlased());
+            }
+        }
+
+        {
+            // Add an additional layer. Since all the layers are unlocked this 
+            // will force out the first atlased layer
+            create_layers(reporter, &cache, *picture, 1, kInitialNumLayers);
+            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), 
+                                                   kInitialNumLayers+1, kInitialNumLayers+2, 
+                                                   SkIPoint::Make(0, 0), SkMatrix::I());
+            REPORTER_ASSERT(reporter, layer);
+
+            lock_layer(reporter, &cache, layer);
+            cache.unlock(layer);
+        }
+
+        for (int i = 0; i < kInitialNumLayers+1; ++i) {
+            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, i+2, 
+                                                   SkIPoint::Make(0, 0), SkMatrix::I());
+            // 3 old layers plus the new one should be in the atlas.
+            if (1 == i || 2 == i || 3 == i || 5 == i) {
+                REPORTER_ASSERT(reporter, layer);
+                REPORTER_ASSERT(reporter, !layer->locked());
+                REPORTER_ASSERT(reporter, layer->texture());
+                REPORTER_ASSERT(reporter, layer->isAtlased());
+            } else if (4 == i) {
+                // The one that was never atlased should still be around
+                REPORTER_ASSERT(reporter, layer);
+
+                REPORTER_ASSERT(reporter, NULL == layer->texture());
+                REPORTER_ASSERT(reporter, !layer->isAtlased());
+            } else {
+                // The one bumped out of the atlas (i.e., 0) should be gone
+                REPORTER_ASSERT(reporter, NULL == layer);
+            }
+        }
+
+        //--------------------------------------------------------------------
+        // Free them all SkGpuDevice-style. This will not free up the
+        // atlas' texture but will eliminate all the layers.
+        TestingAccess::Purge(&cache, picture->uniqueID());
+
+        REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
+        // TODO: add VRAM/resource cache check here
+
+        //--------------------------------------------------------------------
+        // Test out the GrContext-style purge. This should remove all the layers
+        // and the atlas.
+        // Re-create the layers
+        create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
+
+        // Free them again GrContext-style. This should free up everything.
+        cache.freeAll();
+
+        REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
+        // TODO: add VRAM/resource cache check here
+
+        //--------------------------------------------------------------------
+        // Test out the MessageBus-style purge. This will not free the atlas
+        // but should eliminate the free-floating layers.
+        create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
+
+        picture.reset(NULL);
+        cache.processDeletedPictures();
+
+        REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
+        // TODO: add VRAM/resource cache check here
+    }
+}
+
+#endif
diff --git a/tests/GrAllocatorTest.cpp b/tests/GrAllocatorTest.cpp
new file mode 100644
index 0000000..c02a7ca
--- /dev/null
+++ b/tests/GrAllocatorTest.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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 "Test.h"
+// This is a GPU-backend specific test
+#if SK_SUPPORT_GPU
+#include "GrAllocator.h"
+
+namespace {
+struct C {
+    C() : fID(-1) { ++gInstCnt; }
+    C(int id) : fID(id) { ++gInstCnt; }
+    ~C() { --gInstCnt; }
+    int fID;
+
+    static int gInstCnt;
+};
+
+int C::gInstCnt = 0;
+}
+
+static void check_allocator_helper(GrTAllocator<C>* allocator, int cnt, int popCnt,
+                                   skiatest::Reporter* reporter);
+
+// Adds cnt items to the allocator, tests the cnts and iterators, pops popCnt items and checks
+// again. Finally it resets the allocator and checks again.
+static void check_allocator(GrTAllocator<C>* allocator, int cnt, int popCnt,
+                            skiatest::Reporter* reporter) {
+    SkASSERT(allocator);
+    SkASSERT(allocator->empty());
+    for (int i = 0; i < cnt; ++i) {
+        // Try both variations of push_back().
+        if (i % 1) {
+            allocator->push_back(C(i));
+        } else {
+            allocator->push_back() = C(i);
+        }
+    }
+    check_allocator_helper(allocator, cnt, popCnt, reporter);
+    allocator->reset();
+    check_allocator_helper(allocator, 0, 0, reporter);
+}
+
+// Checks that the allocator has the correct count, etc and that the element IDs are correct.
+// Then pops popCnt items and checks again.
+static void check_allocator_helper(GrTAllocator<C>* allocator, int cnt, int popCnt,
+                                   skiatest::Reporter* reporter) {
+    REPORTER_ASSERT(reporter, (0 == cnt) == allocator->empty());
+    REPORTER_ASSERT(reporter, cnt == allocator->count());
+    REPORTER_ASSERT(reporter, cnt == C::gInstCnt);
+
+    GrTAllocator<C>::Iter iter(allocator);
+    for (int i = 0; i < cnt; ++i) {
+        REPORTER_ASSERT(reporter, iter.next() && i == iter.get()->fID);
+    }
+    REPORTER_ASSERT(reporter, !iter.next());
+    if (cnt > 0) {
+        REPORTER_ASSERT(reporter, cnt-1 == allocator->back().fID);
+    }
+
+    if (popCnt > 0) {
+        for (int i = 0; i < popCnt; ++i) {
+            allocator->pop_back();
+        }
+        check_allocator_helper(allocator, cnt - popCnt, 0, reporter);
+    }
+}
+
+DEF_TEST(GrAllocator, reporter) {
+
+    // Test combinations of allocators with and without stack storage and with different block
+    // sizes.
+    SkTArray<GrTAllocator<C>*> allocators;
+    GrTAllocator<C> a1(1);
+    allocators.push_back(&a1);
+    GrTAllocator<C> a2(2);
+    allocators.push_back(&a2);
+    GrTAllocator<C> a5(5);
+    allocators.push_back(&a5);
+
+    GrSTAllocator<1, C> sa1;
+    allocators.push_back(&a1);
+    GrSTAllocator<3, C> sa3;
+    allocators.push_back(&sa3);
+    GrSTAllocator<4, C> sa4;
+    allocators.push_back(&sa4);
+
+    for (int i = 0; i < allocators.count(); ++i) {
+        check_allocator(allocators[i], 0, 0, reporter);
+        check_allocator(allocators[i], 1, 1, reporter);
+        check_allocator(allocators[i], 2, 2, reporter);
+        check_allocator(allocators[i], 10, 1, reporter);
+        check_allocator(allocators[i], 10, 5, reporter);
+        check_allocator(allocators[i], 10, 10, reporter);
+        check_allocator(allocators[i], 100, 10, reporter);
+    }
+}
+
+#endif
diff --git a/tests/GrBinHashKeyTest.cpp b/tests/GrBinHashKeyTest.cpp
index 96b851f..605fd9f 100644
--- a/tests/GrBinHashKeyTest.cpp
+++ b/tests/GrBinHashKeyTest.cpp
@@ -8,23 +8,21 @@
 // This is a GPU-backend specific test
 #if SK_SUPPORT_GPU
 
+#include "GrMurmur3HashKey.h"
 #include "GrBinHashKey.h"
 
 #include "Test.h"
 
-DEF_TEST(GrBinHashKeyTest, reporter) {
+template<typename KeyType> static void TestHash(skiatest::Reporter* reporter) {
     const char* testStringA_ = "abcdABCD";
     const char* testStringB_ = "abcdBBCD";
     const uint32_t* testStringA = reinterpret_cast<const uint32_t*>(testStringA_);
     const uint32_t* testStringB = reinterpret_cast<const uint32_t*>(testStringB_);
-    enum {
-        kDataLenUsedForKey = 8
-    };
 
-    GrBinHashKey<kDataLenUsedForKey> keyA;
+    KeyType keyA;
     keyA.setKeyData(testStringA);
     // test copy constructor and comparison
-    GrBinHashKey<kDataLenUsedForKey> keyA2(keyA);
+    KeyType keyA2(keyA);
     REPORTER_ASSERT(reporter, keyA == keyA2);
     REPORTER_ASSERT(reporter, keyA.getHash() == keyA2.getHash());
     // test re-init
@@ -32,10 +30,19 @@
     REPORTER_ASSERT(reporter, keyA == keyA2);
     REPORTER_ASSERT(reporter, keyA.getHash() == keyA2.getHash());
     // test sorting
-    GrBinHashKey<kDataLenUsedForKey> keyB;
+    KeyType keyB;
     keyB.setKeyData(testStringB);
-    REPORTER_ASSERT(reporter, keyA < keyB);
     REPORTER_ASSERT(reporter, keyA.getHash() != keyB.getHash());
 }
 
+
+DEF_TEST(GrBinHashKey, reporter) {
+    enum {
+        kDataLenUsedForKey = 8
+    };
+
+    TestHash<GrBinHashKey<kDataLenUsedForKey> >(reporter);
+    TestHash<GrMurmur3HashKey<kDataLenUsedForKey> >(reporter);
+}
+
 #endif
diff --git a/tests/GrContextFactoryTest.cpp b/tests/GrContextFactoryTest.cpp
index 461a57a..1d884ac 100644
--- a/tests/GrContextFactoryTest.cpp
+++ b/tests/GrContextFactoryTest.cpp
@@ -10,23 +10,23 @@
 #include "GrContextFactory.h"
 #include "Test.h"
 
-DEF_GPUTEST(GrContextFactoryTest, reporter, factory) {
+DEF_GPUTEST(GrContextFactory, reporter, factory) {
     // Reset in case some other test has been using it first.
     factory->destroyContexts();
 
     // Before we ask for a context, we expect the GL context to not be there.
     REPORTER_ASSERT(reporter,
-                    NULL == factory->getGLContext(GrContextFactory::kNative_GLContextType));
+                    NULL == factory->getGLContext(GrContextFactory::kNull_GLContextType));
 
     // After we ask for a context, we expect that the GL context to be there.
-    factory->get(GrContextFactory::kNative_GLContextType);
+    factory->get(GrContextFactory::kNull_GLContextType);
     REPORTER_ASSERT(reporter,
-                    factory->getGLContext(GrContextFactory::kNative_GLContextType) != NULL);
+                    factory->getGLContext(GrContextFactory::kNull_GLContextType) != NULL);
 
     // If we did not ask for a context with the particular GL context, we would
     // expect the particular GL context to not be there.
     REPORTER_ASSERT(reporter,
-                    NULL == factory->getGLContext(GrContextFactory::kNull_GLContextType));
+                    NULL == factory->getGLContext(GrContextFactory::kDebug_GLContextType));
 }
 
 #endif
diff --git a/tests/GrGLSLPrettyPrintTest.cpp b/tests/GrGLSLPrettyPrintTest.cpp
new file mode 100644
index 0000000..9977488
--- /dev/null
+++ b/tests/GrGLSLPrettyPrintTest.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#if SK_SUPPORT_GPU
+#include "Test.h"
+#include "gl/GrGLSLPrettyPrint.h"
+
+#define ASSERT(x) REPORTER_ASSERT(r, x)
+
+const SkString input1("#this is not a realshader\nvec4 some stuff;outside of a function;"
+                     "int i(int b, int c) { { some stuff;} fake block; //comments\n return i;}"
+                     "void main()"
+                     "{nowin a function;{indenting;{abit more;dreadedfor((;;)(;)((;;);)){doingstuff"
+                     ";for(;;;){and more stufff;mixed garbage\n\n\t\t\t\t\n/*using this"
+                     " comment\n is"
+                     " dangerous\ndo so at your own\n risk*/;\n\n\t\t\t\n"
+                     "//a comment\n}}a; little ;  love; for   ; leading;  spaces;} "
+                     "an struct = { int a; int b; };"
+                     "int[5] arr = int[5](1,2,3,4,5);} some code at the bottom; for(;;) {} }");
+
+const SkString output1(
+        "   1\t#this is not a realshader\n"
+        "   2\tvec4 some stuff;\n"
+        "   3\toutside of a function;\n"
+        "   4\tint i(int b, int c) \n"
+        "   5\t{\n"
+        "   6\t\t{\n"
+        "   7\t\t\tsome stuff;\n"
+        "   8\t\t}\n"
+        "   9\t\tfake block;\n"
+        "  10\t\t//comments\n"
+        "  11\t\treturn i;\n"
+        "  12\t}\n"
+        "  13\tvoid main()\n"
+        "  14\t{\n"
+        "  15\t\tnowin a function;\n"
+        "  16\t\t{\n"
+        "  17\t\t\tindenting;\n"
+        "  18\t\t\t{\n"
+        "  19\t\t\t\tabit more;\n"
+        "  20\t\t\t\tdreadedfor((;;)(;)((;;);))\n"
+        "  21\t\t\t\t{\n"
+        "  22\t\t\t\t\tdoingstuff;\n"
+        "  23\t\t\t\t\tfor(;;;)\n"
+        "  24\t\t\t\t\t{\n"
+        "  25\t\t\t\t\t\tand more stufff;\n"
+        "  26\t\t\t\t\t\tmixed garbage/*using this comment\n"
+        "  27\t\t\t\t\t\t is dangerous\n"
+        "  28\t\t\t\t\t\tdo so at your own\n"
+        "  29\t\t\t\t\t\t risk*/;\n"
+        "  30\t\t\t\t\t\t//a comment\n"
+        "  31\t\t\t\t\t}\n"
+        "  32\t\t\t\t}\n"
+        "  33\t\t\t\ta;\n"
+        "  34\t\t\t\tlittle ;\n"
+        "  35\t\t\t\tlove;\n"
+        "  36\t\t\t\tfor   ;\n"
+        "  37\t\t\t\tleading;\n"
+        "  38\t\t\t\tspaces;\n"
+        "  39\t\t\t}\n"
+        "  40\t\t\tan struct = \n"
+        "  41\t\t\t{\n"
+        "  42\t\t\t\tint a;\n"
+        "  43\t\t\t\tint b;\n"
+        "  44\t\t\t}\n"
+        "  45\t\t\t;\n"
+        "  46\t\t\tint[5] arr = int[5](1,2,3,4,5);\n"
+        "  47\t\t}\n"
+        "  48\t\tsome code at the bottom;\n"
+        "  49\t\tfor(;;) \n"
+        "  50\t\t{\n"
+        "  51\t\t}\n"
+        "  52\t}\n"
+        "  53\t");
+
+const SkString input2("{;;{{{{;;;{{{{{{{{{{{###\n##\n#####(((((((((((((unbalanced verything;;;"
+        "}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}"
+        ";;;;;;/////");
+
+DEF_TEST(GrGLSLPrettyPrint, r) {
+    SkString test = GrGLSLPrettyPrint::PrettyPrintGLSL(input1, true);
+    ASSERT(output1 == test);
+
+    // Just test we don't crash with garbage input
+    ASSERT(GrGLSLPrettyPrint::PrettyPrintGLSL(input2, true).c_str() != NULL);
+}
+
+#endif
diff --git a/tests/GrOrderedSetTest.cpp b/tests/GrOrderedSetTest.cpp
index e449fa2..7b3db9d 100644
--- a/tests/GrOrderedSetTest.cpp
+++ b/tests/GrOrderedSetTest.cpp
@@ -14,7 +14,7 @@
 typedef GrOrderedSet<int> Set;
 typedef GrOrderedSet<const char*, GrStrLess> Set2;
 
-DEF_TEST(GrOrderedSetTest, reporter) {
+DEF_TEST(GrOrderedSet, reporter) {
     Set set;
 
     REPORTER_ASSERT(reporter, set.empty());
diff --git a/tests/GrRedBlackTreeTest.cpp b/tests/GrRedBlackTreeTest.cpp
index bb0fa15..c517cf2 100644
--- a/tests/GrRedBlackTreeTest.cpp
+++ b/tests/GrRedBlackTreeTest.cpp
@@ -14,7 +14,7 @@
 
 typedef GrRedBlackTree<int> Tree;
 
-DEF_TEST(GrRedBlackTreeTest, reporter) {
+DEF_TEST(GrRedBlackTree, reporter) {
     Tree tree;
 
     SkRandom r;
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index b73adc0..a2ed629 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -14,9 +14,9 @@
 #include "SkTypes.h"
 #include "Test.h"
 
-DEF_GPUTEST(GrSurfaceTest, reporter, factory) {
+DEF_GPUTEST(GrSurface, reporter, factory) {
     GrContext* context = factory->get(GrContextFactory::kNull_GLContextType);
-    if (NULL != context) {
+    if (context) {
         GrTextureDesc desc;
         desc.fConfig = kSkia8888_GrPixelConfig;
         desc.fFlags = kRenderTarget_GrTextureFlagBit;
diff --git a/tests/GrTBSearchTest.cpp b/tests/GrTBSearchTest.cpp
index 70a24d3..d057807 100644
--- a/tests/GrTBSearchTest.cpp
+++ b/tests/GrTBSearchTest.cpp
@@ -22,7 +22,7 @@
 
 #include "GrTBSearch.h"
 
-DEF_TEST(GrTBSearchTest, reporter) {
+DEF_TEST(GrTBSearch, reporter) {
     const int array[] = {
         1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99
     };
diff --git a/tests/GradientTest.cpp b/tests/GradientTest.cpp
index 3e40010..e6fd7b9 100644
--- a/tests/GradientTest.cpp
+++ b/tests/GradientTest.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SkBitmapDevice.h"
+#include "SkCanvas.h"
 #include "SkColorShader.h"
-#include "SkEmptyShader.h"
 #include "SkGradientShader.h"
 #include "SkShader.h"
 #include "SkTemplates.h"
@@ -43,7 +42,7 @@
 
 
 static void none_gradproc(skiatest::Reporter* reporter, const GradRec&) {
-    SkAutoTUnref<SkShader> s(new SkEmptyShader);
+    SkAutoTUnref<SkShader> s(SkShader::CreateEmptyShader());
     REPORTER_ASSERT(reporter, SkShader::kNone_GradientType == s->asAGradient(NULL));
 }
 
diff --git a/tests/HashCacheTest.cpp b/tests/HashCacheTest.cpp
deleted file mode 100644
index 93877cb..0000000
--- a/tests/HashCacheTest.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "Test.h"
-
-// This is a GR test
-#if SK_SUPPORT_GPU
-#include "GrTHashTable.h"
-
-struct HashElement {
-    int     fKey;
-    int     fValue;
-};
-
-class GrFindPositivesFunctor {
-public:
-    // only return elements with positive values
-    bool operator()(const HashElement* elem) const {
-        return elem->fValue > 0;
-    }
-};
-
-class GrFindNegativesFunctor {
-public:
-    // only return elements with negative values
-    bool operator()(const HashElement* elem) const {
-        return elem->fValue < 0;
-    }
-};
-
-class HashKey {
-public:
-    HashKey(int key) : fKey(key) {}
-
-    uint32_t getHash() const { return fKey; }
-
-    static bool LessThan(const HashElement& entry, const HashKey& key) {
-        return entry.fKey < key.fKey;
-    }
-    static bool Equals(const HashElement& entry, const HashKey& key) {
-        return entry.fKey == key.fKey;
-    }
-
-#ifdef SK_DEBUG
-    static bool LessThan(const HashElement& a, const HashElement& b) {
-        return a.fKey < b.fKey;
-    }
-    static bool Equals(const HashElement& a, const HashElement& b) {
-        return a.fKey == b.fKey;
-    }
-#endif
-
-protected:
-    int fKey;
-};
-
-DEF_TEST(HashCache, reporter) {
-    GrTHashTable<HashElement, HashKey, 4> cache;
-
-    HashElement negHashElements[10] = {
-        { 0,  0 },
-        { 1, -1 },
-        { 2, -2 },
-        { 3, -3 },
-        { 4, -4 },
-        { 5, -5 },
-        { 6, -6 },
-        { 7, -7 },
-        { 8, -8 },
-        { 9, -9 }
-    };
-    HashElement posHashElements[10] = {
-        { 0, 0 },
-        { 1, 1 },
-        { 2, 2 },
-        { 3, 3 },
-        { 4, 4 },
-        { 5, 5 },
-        { 6, 6 },
-        { 7, 7 },
-        { 8, 8 },
-        { 9, 9 }
-    };
-
-    // add i: -i pairs
-    for (int i = 0; i < 10; ++i) {
-        cache.insert(HashKey(i), &negHashElements[i]);
-    }
-
-    REPORTER_ASSERT(reporter, 10 == cache.count());
-
-    // look for all i's and assert we found the -i's
-    for (int i = 0; i < 10; ++i) {
-        HashElement* found = cache.find(i);
-        REPORTER_ASSERT(reporter, NULL != found && -i == found->fValue);
-    }
-
-    // look for something not in the cache
-    {
-        HashElement* found = cache.find(10);
-        REPORTER_ASSERT(reporter, NULL == found);
-    }
-
-    // add i:i duplicates (so each i will have a positive & negative entry)
-    for (int i = 0; i < 10; ++i) {
-        cache.insert(i, &posHashElements[i]);
-    }
-
-    REPORTER_ASSERT(reporter, 20 == cache.count());
-
-    // test out the find functor to find all the positive values
-    {
-        GrFindPositivesFunctor findPos;
-
-        HashElement* found = cache.find(0, findPos);
-        REPORTER_ASSERT(reporter, NULL == found);
-
-        for (int i = 1; i < 10; ++i) {
-            found = cache.find(i, findPos);
-
-            REPORTER_ASSERT(reporter, NULL != found && found->fValue > 0);
-        }
-    }
-
-    // make sure finding the positives wasn't a fluke - find the negatives
-    {
-        GrFindNegativesFunctor findNeg;
-
-        HashElement* found = cache.find(0, findNeg);
-        REPORTER_ASSERT(reporter, NULL == found);
-
-        for (int i = 1; i < 10; ++i) {
-            found = cache.find(i, findNeg);
-
-            REPORTER_ASSERT(reporter, NULL != found && found->fValue < 0);
-        }
-    }
-
-    // remove the 0:0 entries
-    {
-        cache.remove(0, &negHashElements[0]);
-        cache.remove(0, &posHashElements[0]);
-        REPORTER_ASSERT(reporter, 18 == cache.count());
-
-        HashElement* found = cache.find(0);
-        REPORTER_ASSERT(reporter, NULL == found);
-    }
-}
-
-#endif
diff --git a/tests/ImageCacheTest.cpp b/tests/ImageCacheTest.cpp
index 00f6c77..9f893bb 100644
--- a/tests/ImageCacheTest.cpp
+++ b/tests/ImageCacheTest.cpp
@@ -6,72 +6,67 @@
  */
 
 #include "SkDiscardableMemory.h"
-#include "SkScaledImageCache.h"
+#include "SkResourceCache.h"
 #include "Test.h"
 
-static void make_bm(SkBitmap* bm, int w, int h) {
-    bm->allocN32Pixels(w, h);
+namespace {
+static void* gGlobalAddress;
+struct TestingKey : public SkResourceCache::Key {
+    void*       fPtr;
+    intptr_t    fValue;
+
+    TestingKey(intptr_t value) : fPtr(&gGlobalAddress), fValue(value) {
+        this->init(sizeof(fPtr) + sizeof(fValue));
+    }
+};
+struct TestingRec : public SkResourceCache::Rec {
+    TestingRec(const TestingKey& key, uint32_t value) : fKey(key), fValue(value) {}
+
+    TestingKey  fKey;
+    intptr_t    fValue;
+
+    virtual const Key& getKey() const SK_OVERRIDE { return fKey; }
+    virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + sizeof(fValue); }
+
+    static bool Visitor(const SkResourceCache::Rec& baseRec, void* context) {
+        const TestingRec& rec = static_cast<const TestingRec&>(baseRec);
+        intptr_t* result = (intptr_t*)context;
+        
+        *result = rec.fValue;
+        return true;
+    }
+};
 }
 
 static const int COUNT = 10;
 static const int DIM = 256;
 
-static void test_cache(skiatest::Reporter* reporter, SkScaledImageCache& cache,
-                       bool testPurge) {
-    SkScaledImageCache::ID* id;
-
-    SkBitmap bm[COUNT];
-
-    const SkScalar scale = 2;
+static void test_cache(skiatest::Reporter* reporter, SkResourceCache& cache, bool testPurge) {
     for (int i = 0; i < COUNT; ++i) {
-        make_bm(&bm[i], DIM, DIM);
-    }
+        TestingKey key(i);
+        intptr_t value = -1;
 
-    for (int i = 0; i < COUNT; ++i) {
-        SkBitmap tmp;
+        REPORTER_ASSERT(reporter, !cache.find(key, TestingRec::Visitor, &value));
+        REPORTER_ASSERT(reporter, -1 == value);
 
-        SkScaledImageCache::ID* id = cache.findAndLock(bm[i], scale, scale, &tmp);
-        REPORTER_ASSERT(reporter, NULL == id);
+        cache.add(SkNEW_ARGS(TestingRec, (key, i)));
 
-        make_bm(&tmp, DIM, DIM);
-        id = cache.addAndLock(bm[i], scale, scale, tmp);
-        REPORTER_ASSERT(reporter, NULL != id);
-
-        SkBitmap tmp2;
-        SkScaledImageCache::ID* id2 = cache.findAndLock(bm[i], scale, scale,
-                                                        &tmp2);
-        REPORTER_ASSERT(reporter, id == id2);
-        REPORTER_ASSERT(reporter, tmp.pixelRef() == tmp2.pixelRef());
-        REPORTER_ASSERT(reporter, tmp.width() == tmp2.width());
-        REPORTER_ASSERT(reporter, tmp.height() == tmp2.height());
-        cache.unlock(id2);
-
-        cache.unlock(id);
+        REPORTER_ASSERT(reporter, cache.find(key, TestingRec::Visitor, &value));
+        REPORTER_ASSERT(reporter, i == value);
     }
 
     if (testPurge) {
         // stress test, should trigger purges
-        float incScale = 2;
         for (size_t i = 0; i < COUNT * 100; ++i) {
-            incScale += 1;
-
-            SkBitmap tmp;
-            make_bm(&tmp, DIM, DIM);
-
-            SkScaledImageCache::ID* id = cache.addAndLock(bm[0], incScale,
-                                                          incScale, tmp);
-            REPORTER_ASSERT(reporter, NULL != id);
-            cache.unlock(id);
+            TestingKey key(i);
+            cache.add(SkNEW_ARGS(TestingRec, (key, i)));
         }
     }
 
     // test the originals after all that purging
     for (int i = 0; i < COUNT; ++i) {
-        SkBitmap tmp;
-        id = cache.findAndLock(bm[i], scale, scale, &tmp);
-        if (id) {
-            cache.unlock(id);
-        }
+        intptr_t value;
+        (void)cache.find(TestingKey(i), TestingRec::Visitor, &value);
     }
 
     cache.setTotalByteLimit(0);
@@ -89,45 +84,33 @@
     static const size_t defLimit = DIM * DIM * 4 * COUNT + 1024;    // 1K slop
 
     {
-        SkScaledImageCache cache(defLimit);
+        SkResourceCache cache(defLimit);
         test_cache(reporter, cache, true);
     }
     {
         SkAutoTUnref<SkDiscardableMemoryPool> pool(
                 SkDiscardableMemoryPool::Create(defLimit, NULL));
         gPool = pool.get();
-        SkScaledImageCache cache(pool_factory);
+        SkResourceCache cache(pool_factory);
         test_cache(reporter, cache, true);
     }
     {
-        SkScaledImageCache cache(SkDiscardableMemory::Create);
+        SkResourceCache cache(SkDiscardableMemory::Create);
         test_cache(reporter, cache, false);
     }
 }
 
 DEF_TEST(ImageCache_doubleAdd, r) {
     // Adding the same key twice should be safe.
-    SkScaledImageCache cache(4096);
+    SkResourceCache cache(4096);
 
-    SkBitmap original;
-    original.allocN32Pixels(40, 40);
+    TestingKey key(1);
 
-    SkBitmap scaled1;
-    scaled1.allocN32Pixels(20, 20);
+    cache.add(SkNEW_ARGS(TestingRec, (key, 2)));
+    cache.add(SkNEW_ARGS(TestingRec, (key, 3)));
 
-    SkBitmap scaled2;
-    scaled2.allocN32Pixels(20, 20);
-
-    SkScaledImageCache::ID* id1 = cache.addAndLock(original, 0.5f, 0.5f, scaled1);
-    SkScaledImageCache::ID* id2 = cache.addAndLock(original, 0.5f, 0.5f, scaled2);
-    // We don't really care if id1 == id2 as long as unlocking both works.
-    cache.unlock(id1);
-    cache.unlock(id2);
-
-    SkBitmap tmp;
-    // Lookup should return the value that was added last.
-    SkScaledImageCache::ID* id = cache.findAndLock(original, 0.5f, 0.5f, &tmp);
-    REPORTER_ASSERT(r, NULL != id);
-    REPORTER_ASSERT(r, tmp.getGenerationID() == scaled2.getGenerationID());
-    cache.unlock(id);
+    // Lookup can return either value.
+    intptr_t value = -1;
+    REPORTER_ASSERT(r, cache.find(key, TestingRec::Visitor, &value));
+    REPORTER_ASSERT(r, 2 == value || 3 == value);
 }
diff --git a/tests/ImageDecodingTest.cpp b/tests/ImageDecodingTest.cpp
index 89db399..30665a6 100644
--- a/tests/ImageDecodingTest.cpp
+++ b/tests/ImageDecodingTest.cpp
@@ -55,9 +55,10 @@
         // decoders do not, so skip them as well.
         case SkImageDecoder::kICO_Format:
         case SkImageDecoder::kBMP_Format:
-        // KTX is a Texture format so it's not particularly clear how to 
-        // decode the alpha from it.
+        // KTX and ASTC are texture formats so it's not particularly clear how to 
+        // decode the alpha from them.
         case SkImageDecoder::kKTX_Format:
+        case SkImageDecoder::kASTC_Format:
         // The rest of these are opaque.
         case SkImageDecoder::kPKM_Format:
         case SkImageDecoder::kWBMP_Format:
@@ -158,7 +159,7 @@
     SkString basename;
     if (iter.next(&basename)) {
         do {
-            SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), basename.c_str());
+            SkString filename = SkOSPath::Join(resourcePath.c_str(), basename.c_str());
             // SkDebugf("about to decode \"%s\"\n", filename.c_str());
             compare_unpremul(reporter, filename);
         } while (iter.next(&basename));
@@ -241,7 +242,7 @@
     SkString basename;
     if (iter.next(&basename)) {
         do {
-            SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), basename.c_str());
+            SkString filename = SkOSPath::Join(resourcePath.c_str(), basename.c_str());
             for (int truth = 0; truth <= 1; ++truth) {
                 test_alphaType(reporter, filename, SkToBool(truth));
             }
@@ -264,7 +265,7 @@
 
     for (size_t i = 0; i < SK_ARRAY_COUNT(suffixes); ++i) {
         SkString basename = SkStringPrintf("%s%s", root, suffixes[i]);
-        SkString fullName = SkOSPath::SkPathJoin(resourcePath.c_str(), basename.c_str());
+        SkString fullName = SkOSPath::Join(resourcePath.c_str(), basename.c_str());
 
         SkBitmap bm;
         SkFILEStream stream(fullName.c_str());
@@ -277,7 +278,7 @@
 
         // This should never fail since we know the images we're decoding.
         SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream));
-        REPORTER_ASSERT(reporter, NULL != decoder.get());
+        REPORTER_ASSERT(reporter, decoder.get());
         if (NULL == decoder.get()) {
             continue;
         }
@@ -503,18 +504,15 @@
  *  SkInstallDiscardablePixelRef functions.
  */
 DEF_TEST(ImprovedBitmapFactory, reporter) {
-    SkString resourcePath = GetResourcePath();
-    SkString path = SkOSPath::SkPathJoin(
-            resourcePath.c_str(), "randPixels.png");
-    SkAutoTUnref<SkStreamRewindable> stream(
-        SkStream::NewFromFile(path.c_str()));
-    if (sk_exists(path.c_str())) {
+    SkString pngFilename = GetResourcePath("randPixels.png");
+    SkAutoTUnref<SkStreamRewindable> stream(SkStream::NewFromFile(pngFilename.c_str()));
+    if (sk_exists(pngFilename.c_str())) {
         SkBitmap bm;
         SkAssertResult(bm.setInfo(SkImageInfo::MakeN32Premul(1, 1)));
         REPORTER_ASSERT(reporter,
-            NULL != install_pixel_ref(&bm, stream.detach(), 1, true));
+            install_pixel_ref(&bm, stream.detach(), 1, true));
         SkAutoLockPixels alp(bm);
-        REPORTER_ASSERT(reporter, NULL != bm.getPixels());
+        REPORTER_ASSERT(reporter, bm.getPixels());
     }
 }
 
@@ -695,7 +693,7 @@
     const bool useDataList[] = {true, false};
 
     for (size_t fidx = 0; fidx < SK_ARRAY_COUNT(files); ++fidx) {
-        SkString path = SkOSPath::SkPathJoin(resourceDir.c_str(), files[fidx]);
+        SkString path = SkOSPath::Join(resourceDir.c_str(), files[fidx]);
         if (!sk_exists(path.c_str())) {
             continue;
         }
@@ -726,3 +724,96 @@
         }
     }
 }
+
+DEF_TEST(DiscardablePixelRef_SecondLockColorTableCheck, r) {
+    SkString resourceDir = GetResourcePath();
+    SkString path = SkOSPath::Join(resourceDir.c_str(), "randPixels.gif");
+    if (!sk_exists(path.c_str())) {
+        return;
+    }
+    SkAutoDataUnref encoded(SkData::NewFromFileName(path.c_str()));
+    SkBitmap bitmap;
+    if (!SkInstallDiscardablePixelRef(
+            SkDecodingImageGenerator::Create(
+                    encoded, SkDecodingImageGenerator::Options()), &bitmap)) {
+        #ifndef SK_BUILD_FOR_WIN
+        ERRORF(r, "SkInstallDiscardablePixelRef [randPixels.gif] failed.");
+        #endif
+        return;
+    }
+    if (kIndex_8_SkColorType != bitmap.colorType()) {
+        return;
+    }
+    {
+        SkAutoLockPixels alp(bitmap);
+        REPORTER_ASSERT(r, bitmap.getColorTable() && "first pass");
+    }
+    {
+        SkAutoLockPixels alp(bitmap);
+        REPORTER_ASSERT(r, bitmap.getColorTable() && "second pass");
+    }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+class SingleAllocator : public SkBitmap::Allocator {
+public:
+    SingleAllocator(void* p, size_t s) : fPixels(p), fSize(s) { }
+    ~SingleAllocator() {}
+    // If the pixels in fPixels are big enough, use them.
+    virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE {
+        SkASSERT(bm);
+        if (bm->info().getSafeSize(bm->rowBytes()) <= fSize) {
+            bm->setPixels(fPixels, ct);
+            fPixels = NULL;
+            fSize = 0;
+            return true;
+        }
+        return bm->tryAllocPixels(NULL, ct);
+    }
+    bool ready() { return fPixels != NULL; }
+private:
+    void* fPixels;
+    size_t fSize;
+};
+}  // namespace
+
+/*  This tests for a bug in libjpeg where INT32 is typedefed to long
+    and memory can be written to outside of the array. */
+DEF_TEST(ImageDecoding_JpegOverwrite, r) {
+    SkString resourceDir = GetResourcePath();
+    SkString path = SkOSPath::Join(resourceDir.c_str(), "randPixels.jpg");
+    SkAutoTUnref<SkStreamAsset> stream(
+            SkStream::NewFromFile(path.c_str()));
+    if (!stream.get()) {
+        SkDebugf("\nPath '%s' missing.\n", path.c_str());
+        return;
+    }
+    SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
+    if (NULL == decoder.get()) {
+        ERRORF(r, "\nSkImageDecoder::Factory failed.\n");
+        return;
+    }
+    SkAssertResult(stream->rewind());
+
+    static const uint16_t sentinal = 0xBEEF;
+    static const int pixelCount = 16;
+    SkAutoTMalloc<uint16_t> pixels(pixelCount + 1);
+    // pixels.get() should be 4-byte aligned.
+    // This is necessary to reproduce the bug.
+
+    pixels[pixelCount] = sentinal;  // This value should not be changed.
+
+    SkAutoTUnref<SingleAllocator> allocator(
+            SkNEW_ARGS(SingleAllocator,
+                       ((void*)pixels.get(), sizeof(uint16_t) * pixelCount)));
+    decoder->setAllocator(allocator);
+    decoder->setSampleSize(2);
+    SkBitmap bitmap;
+    bool success = decoder->decode(stream, &bitmap, kRGB_565_SkColorType,
+                                   SkImageDecoder::kDecodePixels_Mode);
+    REPORTER_ASSERT(r, success);
+    REPORTER_ASSERT(r, !allocator->ready());  // Decoder used correct memory
+    REPORTER_ASSERT(r, sentinal == pixels[pixelCount]);
+}
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index 4a1cdf2..d0fa93f 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkBicubicImageFilter.h"
 #include "SkBitmap.h"
 #include "SkBitmapDevice.h"
 #include "SkBitmapSource.h"
@@ -16,7 +15,6 @@
 #include "SkDeviceImageFilterProxy.h"
 #include "SkDisplacementMapEffect.h"
 #include "SkDropShadowImageFilter.h"
-#include "SkFlattenableBuffers.h"
 #include "SkFlattenableSerialization.h"
 #include "SkGradientShader.h"
 #include "SkLightingImageFilter.h"
@@ -28,6 +26,7 @@
 #include "SkPicture.h"
 #include "SkPictureImageFilter.h"
 #include "SkPictureRecorder.h"
+#include "SkReadBuffer.h"
 #include "SkRect.h"
 #include "SkTileImageFilter.h"
 #include "SkXfermodeImageFilter.h"
@@ -45,7 +44,7 @@
 class MatrixTestImageFilter : public SkImageFilter {
 public:
     MatrixTestImageFilter(skiatest::Reporter* reporter, const SkMatrix& expectedMatrix)
-      : SkImageFilter(0), fReporter(reporter), fExpectedMatrix(expectedMatrix) {
+      : SkImageFilter(0, NULL), fReporter(reporter), fExpectedMatrix(expectedMatrix) {
     }
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context& ctx,
@@ -57,12 +56,15 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(MatrixTestImageFilter)
 
 protected:
-    explicit MatrixTestImageFilter(SkReadBuffer& buffer) : SkImageFilter(0) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    explicit MatrixTestImageFilter(SkReadBuffer& buffer) : SkImageFilter(0, NULL) {
         fReporter = static_cast<skiatest::Reporter*>(buffer.readFunctionPtr());
         buffer.readMatrix(&fExpectedMatrix);
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
+        this->INHERITED::flatten(buffer);
         buffer.writeFunctionPtr(fReporter);
         buffer.writeMatrix(fExpectedMatrix);
     }
@@ -70,10 +72,20 @@
 private:
     skiatest::Reporter* fReporter;
     SkMatrix fExpectedMatrix;
+    
+    typedef SkImageFilter INHERITED;
 };
 
 }
 
+SkFlattenable* MatrixTestImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    skiatest::Reporter* reporter = (skiatest::Reporter*)buffer.readFunctionPtr();
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    return SkNEW_ARGS(MatrixTestImageFilter, (reporter, matrix));
+}
+
 static void make_small_bitmap(SkBitmap& bitmap) {
     bitmap.allocN32Pixels(kBitmapSize, kBitmapSize);
     SkCanvas canvas(bitmap);
@@ -140,7 +152,7 @@
         // Check that a clipping color matrix followed by a grayscale does not concatenate into a single filter.
         SkAutoTUnref<SkImageFilter> doubleBrightness(make_scale(2.0f));
         SkAutoTUnref<SkImageFilter> halfBrightness(make_scale(0.5f, doubleBrightness));
-        REPORTER_ASSERT(reporter, NULL != halfBrightness->getInput(0));
+        REPORTER_ASSERT(reporter, halfBrightness->getInput(0));
     }
 
     {
@@ -211,22 +223,6 @@
                                       SkIntToScalar(kBitmapSize));
             canvas.drawRect(r, paint);
         }
-
-        {
-            // This tests for scale bringing width to 0
-            SkSize scale = SkSize::Make(-0.001f, SK_Scalar1);
-            SkAutoTUnref<SkImageFilter> bmSrc(SkBitmapSource::Create(bitmap));
-            SkAutoTUnref<SkBicubicImageFilter> bicubic(
-                SkBicubicImageFilter::CreateMitchell(scale, bmSrc));
-            SkBitmapDevice device(bitmap);
-            SkDeviceImageFilterProxy proxy(&device);
-            SkIPoint loc = SkIPoint::Make(0, 0);
-            // An empty input should early return and return false
-            SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(2));
-            SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeEmpty(), cache.get());
-            REPORTER_ASSERT(reporter,
-                            !bicubic->filterImage(&proxy, bitmap, ctx, &result, &loc));
-        }
     }
 }
 
@@ -279,8 +275,7 @@
         SkIPoint offset;
         SkString str;
         str.printf("filter %d", static_cast<int>(i));
-        SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(2));
-        SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeLargest(), cache.get());
+        SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeLargest(), NULL);
         REPORTER_ASSERT_MESSAGE(reporter, filter->filterImage(&proxy, bitmap, ctx,
                                 &result, &offset), str.c_str());
         REPORTER_ASSERT_MESSAGE(reporter, offset.fX == 20 && offset.fY == 30, str.c_str());
@@ -312,6 +307,63 @@
     return bitmap;
 }
 
+static void test_negative_blur_sigma(SkBaseDevice* device, skiatest::Reporter* reporter) {
+    // Check that SkBlurImageFilter will accept a negative sigma, either in
+    // the given arguments or after CTM application.
+    int width = 32, height = 32;
+    SkDeviceImageFilterProxy proxy(device);
+    SkScalar five = SkIntToScalar(5);
+
+    SkAutoTUnref<SkBlurImageFilter> positiveFilter(
+        SkBlurImageFilter::Create(five, five)
+    );
+
+    SkAutoTUnref<SkBlurImageFilter> negativeFilter(
+        SkBlurImageFilter::Create(-five, five)
+    );
+
+    SkBitmap gradient = make_gradient_circle(width, height);
+    SkBitmap positiveResult1, negativeResult1;
+    SkBitmap positiveResult2, negativeResult2;
+    SkIPoint offset;
+    SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeLargest(), NULL);
+    positiveFilter->filterImage(&proxy, gradient, ctx, &positiveResult1, &offset);
+    negativeFilter->filterImage(&proxy, gradient, ctx, &negativeResult1, &offset);
+    SkMatrix negativeScale;
+    negativeScale.setScale(-SK_Scalar1, SK_Scalar1);
+    SkImageFilter::Context negativeCTX(negativeScale, SkIRect::MakeLargest(), NULL);
+    positiveFilter->filterImage(&proxy, gradient, negativeCTX, &negativeResult2, &offset);
+    negativeFilter->filterImage(&proxy, gradient, negativeCTX, &positiveResult2, &offset);
+    SkAutoLockPixels lockP1(positiveResult1);
+    SkAutoLockPixels lockP2(positiveResult2);
+    SkAutoLockPixels lockN1(negativeResult1);
+    SkAutoLockPixels lockN2(negativeResult2);
+    for (int y = 0; y < height; y++) {
+        int diffs = memcmp(positiveResult1.getAddr32(0, y), negativeResult1.getAddr32(0, y), positiveResult1.rowBytes());
+        REPORTER_ASSERT(reporter, !diffs);
+        if (diffs) {
+            break;
+        }
+        diffs = memcmp(positiveResult1.getAddr32(0, y), negativeResult2.getAddr32(0, y), positiveResult1.rowBytes());
+        REPORTER_ASSERT(reporter, !diffs);
+        if (diffs) {
+            break;
+        }
+        diffs = memcmp(positiveResult1.getAddr32(0, y), positiveResult2.getAddr32(0, y), positiveResult1.rowBytes());
+        REPORTER_ASSERT(reporter, !diffs);
+        if (diffs) {
+            break;
+        }
+    }
+}
+
+DEF_TEST(TestNegativeBlurSigma, reporter) {
+    SkBitmap temp;
+    temp.allocN32Pixels(100, 100);
+    SkBitmapDevice device(temp);
+    test_negative_blur_sigma(&device, reporter);
+}
+
 DEF_TEST(ImageFilterDrawTiled, reporter) {
     // Check that all filters when drawn tiled (with subsequent clip rects) exactly
     // match the same filters drawn with a single full-canvas bitmap draw.
@@ -426,6 +478,169 @@
     }
 }
 
+static void draw_saveLayer_picture(int width, int height, int tileSize, 
+                                   SkBBHFactory* factory, SkBitmap* result) {
+
+    SkMatrix matrix;
+    matrix.setTranslate(SkIntToScalar(50), 0);
+
+    SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorWHITE, SkXfermode::kSrc_Mode));
+    SkAutoTUnref<SkImageFilter> cfif(SkColorFilterImageFilter::Create(cf.get()));
+    SkAutoTUnref<SkImageFilter> imageFilter(SkMatrixImageFilter::Create(matrix, SkPaint::kNone_FilterLevel, cfif.get()));
+
+    SkPaint paint;
+    paint.setImageFilter(imageFilter.get());
+    SkPictureRecorder recorder;
+    SkRect bounds = SkRect::Make(SkIRect::MakeXYWH(0, 0, 50, 50));
+    SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(width), 
+                                                        SkIntToScalar(height), 
+                                                        factory, 0);
+    recordingCanvas->translate(-55, 0);
+    recordingCanvas->saveLayer(&bounds, &paint);
+    recordingCanvas->restore();
+    SkAutoTUnref<SkPicture> picture1(recorder.endRecording());
+
+    result->allocN32Pixels(width, height);
+    SkCanvas canvas(*result);
+    canvas.clear(0);
+    canvas.clipRect(SkRect::Make(SkIRect::MakeWH(tileSize, tileSize)));
+    canvas.drawPicture(picture1.get());
+}
+
+DEF_TEST(ImageFilterDrawMatrixBBH, reporter) {
+    // Check that matrix filter when drawn tiled with BBH exactly
+    // matches the same thing drawn without BBH.
+    // Tests pass by not asserting.
+
+    const int width = 200, height = 200;
+    const int tileSize = 100;
+    SkBitmap result1, result2;
+    SkRTreeFactory factory;
+
+    draw_saveLayer_picture(width, height, tileSize, &factory, &result1);
+    draw_saveLayer_picture(width, height, tileSize, NULL, &result2);
+
+    for (int y = 0; y < height; y++) {
+        int diffs = memcmp(result1.getAddr32(0, y), result2.getAddr32(0, y), result1.rowBytes());
+        REPORTER_ASSERT(reporter, !diffs);
+        if (diffs) {
+            break;
+        }
+    }
+}
+
+static SkImageFilter* makeBlur(SkImageFilter* input = NULL) {
+    return SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1, input);
+}
+
+static SkImageFilter* makeDropShadow(SkImageFilter* input = NULL) {
+    return SkDropShadowImageFilter::Create(
+        SkIntToScalar(100), SkIntToScalar(100),
+        SkIntToScalar(10), SkIntToScalar(10),
+        SK_ColorBLUE, input);
+}
+
+DEF_TEST(ImageFilterBlurThenShadowBounds, reporter) {
+    SkAutoTUnref<SkImageFilter> filter1(makeBlur());
+    SkAutoTUnref<SkImageFilter> filter2(makeDropShadow(filter1.get()));
+
+    SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100);
+    SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236);
+    filter2->filterBounds(bounds, SkMatrix::I(), &bounds);
+
+    REPORTER_ASSERT(reporter, bounds == expectedBounds);
+}
+
+DEF_TEST(ImageFilterShadowThenBlurBounds, reporter) {
+    SkAutoTUnref<SkImageFilter> filter1(makeDropShadow());
+    SkAutoTUnref<SkImageFilter> filter2(makeBlur(filter1.get()));
+
+    SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100);
+    SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236);
+    filter2->filterBounds(bounds, SkMatrix::I(), &bounds);
+
+    REPORTER_ASSERT(reporter, bounds == expectedBounds);
+}
+
+DEF_TEST(ImageFilterDilateThenBlurBounds, reporter) {
+    SkAutoTUnref<SkImageFilter> filter1(SkDilateImageFilter::Create(2, 2));
+    SkAutoTUnref<SkImageFilter> filter2(makeDropShadow(filter1.get()));
+
+    SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100);
+    SkIRect expectedBounds = SkIRect::MakeXYWH(-132, -132, 234, 234);
+    filter2->filterBounds(bounds, SkMatrix::I(), &bounds);
+
+    REPORTER_ASSERT(reporter, bounds == expectedBounds);
+}
+
+static void draw_blurred_rect(SkCanvas* canvas) {
+    SkAutoTUnref<SkImageFilter> filter(SkBlurImageFilter::Create(SkIntToScalar(8), 0));
+    SkPaint filterPaint;
+    filterPaint.setColor(SK_ColorWHITE);
+    filterPaint.setImageFilter(filter);
+    canvas->saveLayer(NULL, &filterPaint);
+    SkPaint whitePaint;
+    whitePaint.setColor(SK_ColorWHITE);
+    canvas->drawRect(SkRect::Make(SkIRect::MakeWH(4, 4)), whitePaint);
+    canvas->restore();
+}
+
+static void draw_picture_clipped(SkCanvas* canvas, const SkRect& clipRect, const SkPicture* picture) {
+    canvas->save();
+    canvas->clipRect(clipRect);
+    canvas->drawPicture(picture);
+    canvas->restore();
+}
+
+DEF_TEST(ImageFilterDrawTiledBlurRTree, reporter) {
+    // Check that the blur filter when recorded with RTree acceleration,
+    // and drawn tiled (with subsequent clip rects) exactly
+    // matches the same filter drawn with without RTree acceleration.
+    // This tests that the "bleed" from the blur into the otherwise-blank
+    // tiles is correctly rendered.
+    // Tests pass by not asserting.
+
+    int width = 16, height = 8;
+    SkBitmap result1, result2;
+    result1.allocN32Pixels(width, height);
+    result2.allocN32Pixels(width, height);
+    SkCanvas canvas1(result1);
+    SkCanvas canvas2(result2);
+    int tileSize = 8;
+
+    canvas1.clear(0);
+    canvas2.clear(0);
+
+    SkRTreeFactory factory;
+
+    SkPictureRecorder recorder1, recorder2;
+    // The only difference between these two pictures is that one has RTree aceleration.
+    SkCanvas* recordingCanvas1 = recorder1.beginRecording(SkIntToScalar(width), 
+                                                          SkIntToScalar(height), 
+                                                          NULL, 0);
+    SkCanvas* recordingCanvas2 = recorder2.beginRecording(SkIntToScalar(width), 
+                                                          SkIntToScalar(height), 
+                                                          &factory, 0);
+    draw_blurred_rect(recordingCanvas1);
+    draw_blurred_rect(recordingCanvas2);
+    SkAutoTUnref<SkPicture> picture1(recorder1.endRecording());
+    SkAutoTUnref<SkPicture> picture2(recorder2.endRecording());
+    for (int y = 0; y < height; y += tileSize) {
+        for (int x = 0; x < width; x += tileSize) {
+            SkRect tileRect = SkRect::Make(SkIRect::MakeXYWH(x, y, tileSize, tileSize));
+            draw_picture_clipped(&canvas1, tileRect, picture1);
+            draw_picture_clipped(&canvas2, tileRect, picture2);
+        }
+    }
+    for (int y = 0; y < height; y++) {
+        int diffs = memcmp(result1.getAddr32(0, y), result2.getAddr32(0, y), result1.rowBytes());
+        REPORTER_ASSERT(reporter, !diffs);
+        if (diffs) {
+            break;
+        }
+    }
+}
+
 DEF_TEST(ImageFilterMatrixConvolution, reporter) {
     // Check that a 1x3 filter does not cause a spurious assert.
     SkScalar kernel[3] = {
@@ -491,7 +706,7 @@
     test_crop_rects(&device, reporter);
 }
 
-DEF_TEST(ImageFilterMatrixTest, reporter) {
+DEF_TEST(ImageFilterMatrix, reporter) {
     SkBitmap temp;
     temp.allocN32Pixels(100, 100);
     SkBitmapDevice device(temp);
@@ -521,8 +736,7 @@
     canvas.drawPicture(picture);
 }
 
-DEF_TEST(ImageFilterPictureImageFilterTest, reporter) {
-
+DEF_TEST(ImageFilterCrossProcessPictureImageFilter, reporter) {
     SkRTreeFactory factory;
     SkPictureRecorder recorder;
     SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0);
@@ -581,8 +795,31 @@
     REPORTER_ASSERT(reporter, pixel != SK_ColorGREEN);
 }
 
-DEF_TEST(ImageFilterEmptySaveLayerTest, reporter) {
+DEF_TEST(ImageFilterClippedPictureImageFilter, reporter) {
+    SkRTreeFactory factory;
+    SkPictureRecorder recorder;
+    SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0);
 
+    // Create an SkPicture which simply draws a green 1x1 rectangle.
+    SkPaint greenPaint;
+    greenPaint.setColor(SK_ColorGREEN);
+    recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), greenPaint);
+    SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+
+    SkAutoTUnref<SkImageFilter> imageFilter(
+        SkPictureImageFilter::Create(picture.get()));
+
+    SkBitmap result;
+    SkIPoint offset;
+    SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(1, 1, 1, 1), NULL);
+    SkBitmap bitmap;
+    bitmap.allocN32Pixels(2, 2);
+    SkBitmapDevice device(bitmap);
+    SkDeviceImageFilterProxy proxy(&device);
+    REPORTER_ASSERT(reporter, !imageFilter->filterImage(&proxy, bitmap, ctx, &result, &offset));
+}
+
+DEF_TEST(ImageFilterEmptySaveLayer, reporter) {
     // Even when there's an empty saveLayer()/restore(), ensure that an image
     // filter or color filter which affects transparent black still draws.
 
@@ -658,6 +895,60 @@
     test_huge_blur(&device, reporter);
 }
 
+DEF_TEST(MatrixConvolutionSanityTest, reporter) {
+    SkScalar kernel[1] = { 0 };
+    SkScalar gain = SK_Scalar1, bias = 0;
+    SkIPoint kernelOffset = SkIPoint::Make(1, 1);
+
+    // Check that an enormous (non-allocatable) kernel gives a NULL filter.
+    SkAutoTUnref<SkImageFilter> conv(SkMatrixConvolutionImageFilter::Create(
+        SkISize::Make(1<<30, 1<<30),
+        kernel,
+        gain,
+        bias,
+        kernelOffset,
+        SkMatrixConvolutionImageFilter::kRepeat_TileMode,
+        false));
+
+    REPORTER_ASSERT(reporter, NULL == conv.get());
+
+    // Check that a NULL kernel gives a NULL filter.
+    conv.reset(SkMatrixConvolutionImageFilter::Create(
+        SkISize::Make(1, 1),
+        NULL,
+        gain,
+        bias,
+        kernelOffset,
+        SkMatrixConvolutionImageFilter::kRepeat_TileMode,
+        false));
+
+    REPORTER_ASSERT(reporter, NULL == conv.get());
+
+    // Check that a kernel width < 1 gives a NULL filter.
+    conv.reset(SkMatrixConvolutionImageFilter::Create(
+        SkISize::Make(0, 1),
+        kernel,
+        gain,
+        bias,
+        kernelOffset,
+        SkMatrixConvolutionImageFilter::kRepeat_TileMode,
+        false));
+
+    REPORTER_ASSERT(reporter, NULL == conv.get());
+
+    // Check that kernel height < 1 gives a NULL filter.
+    conv.reset(SkMatrixConvolutionImageFilter::Create(
+        SkISize::Make(1, -1),
+        kernel,
+        gain,
+        bias,
+        kernelOffset,
+        SkMatrixConvolutionImageFilter::kRepeat_TileMode,
+        false));
+
+    REPORTER_ASSERT(reporter, NULL == conv.get());
+}
+
 static void test_xfermode_cropped_input(SkBaseDevice* device, skiatest::Reporter* reporter) {
     SkCanvas canvas(device);
     canvas.clear(0);
@@ -763,10 +1054,13 @@
 }
 
 #if SK_SUPPORT_GPU
+const SkSurfaceProps gProps = SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
+
 DEF_GPUTEST(ImageFilterCropRectGPU, reporter, factory) {
     GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
                                                          SkImageInfo::MakeN32Premul(100, 100),
+                                                         gProps,
                                                          0));
     test_crop_rects(device, reporter);
 }
@@ -775,6 +1069,7 @@
     GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
                                                          SkImageInfo::MakeN32Premul(100, 100),
+                                                         gProps,
                                                          0));
     test_huge_blur(device, reporter);
 }
@@ -783,7 +1078,17 @@
     GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
                                                          SkImageInfo::MakeN32Premul(1, 1),
+                                                         gProps,
                                                          0));
     test_xfermode_cropped_input(device, reporter);
 }
+
+DEF_GPUTEST(TestNegativeBlurSigmaGPU, reporter, factory) {
+    GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
+    SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
+                                                         SkImageInfo::MakeN32Premul(1, 1),
+                                                         gProps,
+                                                         0));
+    test_negative_blur_sigma(device, reporter);
+}
 #endif
diff --git a/tests/ImageGeneratorTest.cpp b/tests/ImageGeneratorTest.cpp
new file mode 100644
index 0000000..1f960ea
--- /dev/null
+++ b/tests/ImageGeneratorTest.cpp
@@ -0,0 +1,34 @@
+/*
+ * 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 "SkImageGenerator.h"
+#include "Test.h"
+
+DEF_TEST(ImageGenerator, reporter) {
+    SkImageGenerator ig;
+    SkISize sizes[3];
+    sizes[0] = SkISize::Make(200, 200);
+    sizes[1] = SkISize::Make(100, 100);
+    sizes[2] = SkISize::Make( 50,  50);
+    void*   planes[3] = { NULL };
+    size_t  rowBytes[3] = { 0 };
+    SkYUVColorSpace colorSpace;
+
+    // Check that the YUV decoding API does not cause any crashes
+    ig.getYUV8Planes(sizes, NULL, NULL, &colorSpace);
+    ig.getYUV8Planes(sizes, NULL, NULL, NULL);
+    ig.getYUV8Planes(sizes, planes, NULL, NULL);
+    ig.getYUV8Planes(sizes, NULL, rowBytes, NULL);
+    ig.getYUV8Planes(sizes, planes, rowBytes, NULL);
+    ig.getYUV8Planes(sizes, planes, rowBytes, &colorSpace);
+
+    int dummy;
+    planes[0] = planes[1] = planes[2] = &dummy;
+    rowBytes[0] = rowBytes[1] = rowBytes[2] = 250;
+
+    ig.getYUV8Planes(sizes, planes, rowBytes, &colorSpace);
+}
diff --git a/tests/ImageIsOpaqueTest.cpp b/tests/ImageIsOpaqueTest.cpp
new file mode 100644
index 0000000..3fe5b3d
--- /dev/null
+++ b/tests/ImageIsOpaqueTest.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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 "SkTypes.h"
+#if SK_SUPPORT_GPU
+#include "GrContextFactory.h"
+#endif
+#include "SkImage.h"
+#include "SkSurface.h"
+
+#include "Test.h"
+
+static void check_isopaque(skiatest::Reporter* reporter, SkSurface* surface, bool expectedOpaque) {
+    SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
+    REPORTER_ASSERT(reporter, image->isOpaque() == expectedOpaque);
+}
+
+DEF_TEST(ImageIsOpaqueTest, reporter) {
+    SkImageInfo infoTransparent = SkImageInfo::MakeN32Premul(5, 5);
+    SkAutoTUnref<SkSurface> surfaceTransparent(SkSurface::NewRaster(infoTransparent));
+    check_isopaque(reporter, surfaceTransparent, false);
+
+    SkImageInfo infoOpaque = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType);
+    SkAutoTUnref<SkSurface> surfaceOpaque(SkSurface::NewRaster(infoOpaque));
+    check_isopaque(reporter, surfaceOpaque, true);
+}
+
+#if SK_SUPPORT_GPU
+
+DEF_GPUTEST(ImageIsOpaqueTest_GPU, reporter, factory) {
+    for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
+        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+
+        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
+            continue;
+        }
+
+        GrContext* context = factory->get(glCtxType);
+
+        if (NULL == context) {
+            continue;
+        }
+
+        SkImageInfo infoTransparent = SkImageInfo::MakeN32Premul(5, 5);
+        SkAutoTUnref<SkSurface> surfaceTransparent(SkSurface::NewRenderTarget(context, infoTransparent));
+        check_isopaque(reporter, surfaceTransparent, false);
+
+        SkImageInfo infoOpaque = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType);
+        SkAutoTUnref<SkSurface> surfaceOpaque(SkSurface::NewRenderTarget(context, infoOpaque));
+#if 0
+        // this is failing right now : TODO fix me
+        check_isopaque(reporter, surfaceOpaque, true);
+#endif
+    }
+}
+
+#endif
diff --git a/tests/ImageNewShaderTest.cpp b/tests/ImageNewShaderTest.cpp
new file mode 100644
index 0000000..dfc5a24
--- /dev/null
+++ b/tests/ImageNewShaderTest.cpp
@@ -0,0 +1,167 @@
+/*
+ * 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 "SkTypes.h"
+#if SK_SUPPORT_GPU
+#include "GrContextFactory.h"
+#endif
+#include "SkCanvas.h"
+#include "SkImage.h"
+#include "SkShader.h"
+#include "SkSurface.h"
+
+#include "Test.h"
+
+void testBitmapEquality(skiatest::Reporter* reporter, SkBitmap& bm1, SkBitmap& bm2) {
+    SkAutoLockPixels lockBm1(bm1);
+    SkAutoLockPixels lockBm2(bm2);
+
+    REPORTER_ASSERT(reporter, bm1.getSize() == bm2.getSize());
+    REPORTER_ASSERT(reporter, 0 == memcmp(bm1.getPixels(), bm2.getPixels(), bm1.getSize()));
+}
+
+void paintSource(SkSurface* sourceSurface) {
+    SkCanvas* sourceCanvas = sourceSurface->getCanvas();
+    sourceCanvas->clear(0xFFDEDEDE);
+
+    SkPaint paintColor;
+    paintColor.setColor(0xFFFF0000);
+    paintColor.setStyle(SkPaint::kFill_Style);
+
+    SkRect rect = SkRect::MakeXYWH(
+            SkIntToScalar(1),
+            SkIntToScalar(0),
+            SkIntToScalar(1),
+            SkIntToScalar(sourceSurface->height()));
+
+    sourceCanvas->drawRect(rect, paintColor);
+}
+
+void runShaderTest(skiatest::Reporter* reporter, SkSurface* sourceSurface, SkSurface* destinationSurface, SkImageInfo& info) {
+    paintSource(sourceSurface);
+
+    SkAutoTUnref<SkImage> sourceImage(sourceSurface->newImageSnapshot());
+    SkAutoTUnref<SkShader> sourceShader(sourceImage->newShader(
+            SkShader::kRepeat_TileMode,
+            SkShader::kRepeat_TileMode));
+
+    SkPaint paint;
+    paint.setShader(sourceShader);
+
+    SkCanvas* destinationCanvas = destinationSurface->getCanvas();
+    destinationCanvas->clear(SK_ColorTRANSPARENT);
+    destinationCanvas->drawPaint(paint);
+
+    SkIRect rect = SkIRect::MakeWH(info.width(), info.height());
+
+    SkBitmap bmOrig;
+    sourceSurface->getCanvas()->readPixels(rect, &bmOrig);
+
+
+    SkBitmap bm;
+    destinationCanvas->readPixels(rect, &bm);
+
+    testBitmapEquality(reporter, bmOrig, bm);
+
+
+
+    // Test with a translated shader
+    SkMatrix matrix;
+    matrix.setTranslate(SkIntToScalar(-1), SkIntToScalar(0));
+
+    SkAutoTUnref<SkShader> sourceShaderTranslated(sourceImage->newShader(
+            SkShader::kRepeat_TileMode,
+            SkShader::kRepeat_TileMode,
+            &matrix));
+
+    destinationCanvas->clear(SK_ColorTRANSPARENT);
+
+    SkPaint paintTranslated;
+    paintTranslated.setShader(sourceShaderTranslated);
+
+    destinationCanvas->drawPaint(paintTranslated);
+
+    SkBitmap bmt;
+    destinationCanvas->readPixels(rect, &bmt);
+
+    //  Test correctness
+    {
+        SkAutoLockPixels lockBm(bmt);
+        for (int y = 0; y < info.height(); y++) {
+            REPORTER_ASSERT(reporter, 0xFFFF0000 == bmt.getColor(0, y));
+
+            for (int x = 1; x < info.width(); x++) {
+                REPORTER_ASSERT(reporter, 0xFFDEDEDE == bmt.getColor(x, y));
+            }
+        }
+    }
+}
+
+DEF_TEST(ImageNewShader, reporter) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
+
+    SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRaster(info));
+    SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRaster(info));
+
+    runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
+}
+
+#if SK_SUPPORT_GPU
+
+void gpuToGpu(skiatest::Reporter* reporter, GrContext* context) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
+
+    SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRenderTarget(context, info));
+    SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRenderTarget(context, info));
+
+    runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
+}
+
+void gpuToRaster(skiatest::Reporter* reporter, GrContext* context) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
+
+    SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRenderTarget(context, info));
+    SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRaster(info));
+
+    runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
+}
+
+void rasterToGpu(skiatest::Reporter* reporter, GrContext* context) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
+
+    SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRaster(info));
+    SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRenderTarget(context, info));
+
+    runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
+}
+
+DEF_GPUTEST(ImageNewShader_GPU, reporter, factory) {
+    for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
+        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+
+        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
+            continue;
+        }
+
+        GrContext* context = factory->get(glCtxType);
+
+        if (NULL == context) {
+            continue;
+        }
+
+        //  GPU -> GPU
+        gpuToGpu(reporter, context);
+
+        //  GPU -> RASTER
+        gpuToRaster(reporter, context);
+
+        //  RASTER -> GPU
+        rasterToGpu(reporter, context);
+    }
+}
+
+#endif
diff --git a/tests/InterpolatorTest.cpp b/tests/InterpolatorTest.cpp
new file mode 100644
index 0000000..3cfd19f
--- /dev/null
+++ b/tests/InterpolatorTest.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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 "SkInterpolator.h"
+
+#include "Test.h"
+
+static SkScalar* iset(SkScalar array[3], int a, int b, int c) {
+    array[0] = SkIntToScalar(a);
+    array[1] = SkIntToScalar(b);
+    array[2] = SkIntToScalar(c);
+    return array;
+}
+
+DEF_TEST(Interpolator, reporter) {
+    SkInterpolator  inter(3, 2);
+    SkScalar        v1[3], v2[3], v[3];
+    SkInterpolator::Result          result;
+
+    inter.setKeyFrame(0, 100, iset(v1, 10, 20, 30), 0);
+    inter.setKeyFrame(1, 200, iset(v2, 110, 220, 330));
+
+    result = inter.timeToValues(0, v);
+    REPORTER_ASSERT(reporter, result == SkInterpolator::kFreezeStart_Result);
+    REPORTER_ASSERT(reporter, memcmp(v, v1, sizeof(v)) == 0);
+
+    result = inter.timeToValues(99, v);
+    REPORTER_ASSERT(reporter, result == SkInterpolator::kFreezeStart_Result);
+    REPORTER_ASSERT(reporter, memcmp(v, v1, sizeof(v)) == 0);
+
+    result = inter.timeToValues(100, v);
+    REPORTER_ASSERT(reporter, result == SkInterpolator::kNormal_Result);
+    REPORTER_ASSERT(reporter, memcmp(v, v1, sizeof(v)) == 0);
+
+    result = inter.timeToValues(200, v);
+    REPORTER_ASSERT(reporter, result == SkInterpolator::kNormal_Result);
+    REPORTER_ASSERT(reporter, memcmp(v, v2, sizeof(v)) == 0);
+
+    result = inter.timeToValues(201, v);
+    REPORTER_ASSERT(reporter, result == SkInterpolator::kFreezeEnd_Result);
+    REPORTER_ASSERT(reporter, memcmp(v, v2, sizeof(v)) == 0);
+
+    result = inter.timeToValues(150, v);
+    REPORTER_ASSERT(reporter, result == SkInterpolator::kNormal_Result);
+
+// Found failing when we re-enabled this test:
+#if 0
+    SkScalar vv[3];
+    REPORTER_ASSERT(reporter, memcmp(v, iset(vv, 60, 120, 180), sizeof(v)) == 0);
+#endif
+
+    result = inter.timeToValues(125, v);
+    REPORTER_ASSERT(reporter, result == SkInterpolator::kNormal_Result);
+    result = inter.timeToValues(175, v);
+    REPORTER_ASSERT(reporter, result == SkInterpolator::kNormal_Result);
+
+}
diff --git a/tests/JpegTest.cpp b/tests/JpegTest.cpp
index 2897883..f8784a2 100644
--- a/tests/JpegTest.cpp
+++ b/tests/JpegTest.cpp
@@ -437,8 +437,13 @@
     REPORTER_ASSERT(reporter, bm8888.getColor(27, 34) == 0xffffffff);
     REPORTER_ASSERT(reporter, bm8888.getColor(71, 18) == 0xff000000);
 
+#ifdef SK_BUILD_FOR_IOS  // the iOS jpeg decoder fills to gray
+    REPORTER_ASSERT(reporter, bm8888.getColor(127, 127) == 0xff808080
+            || bm8888.getColor(127, 127) == SK_ColorWHITE);
+#else
     // This is the fill color
     REPORTER_ASSERT(reporter, bm8888.getColor(127, 127) == SK_ColorWHITE);
+#endif
 
     #if JPEG_TEST_WRITE_TO_FILE_FOR_DEBUGGING
     // Check to see that the resulting bitmap is nice
diff --git a/tests/KtxTest.cpp b/tests/KtxTest.cpp
index e9c4217..1a61f3a 100644
--- a/tests/KtxTest.cpp
+++ b/tests/KtxTest.cpp
@@ -28,11 +28,10 @@
     SkRandom rand(0x1005cbad);
 
     SkBitmap bm8888;
-    bool pixelsAllocated = bm8888.allocN32Pixels(128, 128);
-    REPORTER_ASSERT(reporter, pixelsAllocated);
+    bm8888.allocN32Pixels(128, 128);
 
     uint8_t *pixels = reinterpret_cast<uint8_t*>(bm8888.getPixels());
-    REPORTER_ASSERT(reporter, NULL != pixels);
+    REPORTER_ASSERT(reporter, pixels);
 
     if (NULL == pixels) {
         return;
@@ -54,10 +53,10 @@
     REPORTER_ASSERT(reporter, !(bm8888.empty()));
 
     SkAutoDataUnref encodedData(SkImageEncoder::EncodeData(bm8888, SkImageEncoder::kKTX_Type, 0));
-    REPORTER_ASSERT(reporter, NULL != encodedData);
+    REPORTER_ASSERT(reporter, encodedData);
 
     SkAutoTUnref<SkMemoryStream> stream(SkNEW_ARGS(SkMemoryStream, (encodedData)));
-    REPORTER_ASSERT(reporter, NULL != stream);
+    REPORTER_ASSERT(reporter, stream);
 
     SkBitmap decodedBitmap;
     bool imageDecodeSuccess = SkImageDecoder::DecodeStream(stream, &decodedBitmap);
@@ -70,7 +69,7 @@
     REPORTER_ASSERT(reporter, !(decodedBitmap.empty()));
 
     uint8_t *decodedPixels = reinterpret_cast<uint8_t*>(decodedBitmap.getPixels());
-    REPORTER_ASSERT(reporter, NULL != decodedPixels);
+    REPORTER_ASSERT(reporter, decodedPixels);
     REPORTER_ASSERT(reporter, decodedBitmap.getSize() == bm8888.getSize());
 
     if (NULL == decodedPixels) {
@@ -110,7 +109,7 @@
 
     SkAutoTUnref<SkMemoryStream> stream(
         SkNEW_ARGS(SkMemoryStream, (kHalfWhiteKTX, sizeof(kHalfWhiteKTX))));
-    REPORTER_ASSERT(reporter, NULL != stream);
+    REPORTER_ASSERT(reporter, stream);
 
     SkBitmap decodedBitmap;
     bool imageDecodeSuccess = SkImageDecoder::DecodeStream(stream, &decodedBitmap);
@@ -123,7 +122,7 @@
     REPORTER_ASSERT(reporter, !(decodedBitmap.empty()));
 
     uint8_t *decodedPixels = reinterpret_cast<uint8_t*>(decodedBitmap.getPixels());
-    REPORTER_ASSERT(reporter, NULL != decodedPixels);
+    REPORTER_ASSERT(reporter, decodedPixels);
 
     uint8_t *row = decodedPixels;
     for (int j = 0; j < decodedBitmap.height(); ++j) {
@@ -141,13 +140,15 @@
  * the PKM to the KTX should produce an identical KTX to the one we have on file)
  */
 DEF_TEST(KtxReexportPKM, reporter) {
-    SkString resourcePath = GetResourcePath();
-    SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_128.pkm");
+    SkString pkmFilename = GetResourcePath("mandrill_128.pkm");
 
     // Load PKM file into a bitmap
     SkBitmap etcBitmap;
-    SkAutoTUnref<SkData> fileData(SkData::NewFromFileName(filename.c_str()));
-    REPORTER_ASSERT(reporter, NULL != fileData);
+    SkAutoTUnref<SkData> fileData(SkData::NewFromFileName(pkmFilename.c_str()));
+    REPORTER_ASSERT(reporter, fileData);
+    if (NULL == fileData) {
+        return;
+    }
 
     bool installDiscardablePixelRefSuccess =
         SkInstallDiscardablePixelRef(
@@ -158,10 +159,10 @@
     // Write the bitmap out to a KTX file.
     SkData *ktxDataPtr = SkImageEncoder::EncodeData(etcBitmap, SkImageEncoder::kKTX_Type, 0);
     SkAutoDataUnref newKtxData(ktxDataPtr);
-    REPORTER_ASSERT(reporter, NULL != ktxDataPtr);
+    REPORTER_ASSERT(reporter, ktxDataPtr);
 
     // See is this data is identical to data in existing ktx file.
-    SkString ktxFilename = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_128.ktx");
+    SkString ktxFilename = GetResourcePath("mandrill_128.ktx");
     SkAutoDataUnref oldKtxData(SkData::NewFromFileName(ktxFilename.c_str()));
     REPORTER_ASSERT(reporter, oldKtxData->equals(newKtxData));
 }
diff --git a/tests/LListTest.cpp b/tests/LListTest.cpp
index 20151c3..8fb0117 100644
--- a/tests/LListTest.cpp
+++ b/tests/LListTest.cpp
@@ -73,12 +73,12 @@
     Iter iter;
 
     ListElement* cur = iter.init(list, Iter::kHead_IterStart);
-    for (int i = 0; NULL != cur; ++i, cur = iter.next()) {
+    for (int i = 0; cur; ++i, cur = iter.next()) {
         REPORTER_ASSERT(reporter, cur->fID == 3-i);
     }
 
     cur = iter.init(list, Iter::kTail_IterStart);
-    for (int i = 0; NULL != cur; ++i, cur = iter.prev()) {
+    for (int i = 0; cur; ++i, cur = iter.prev()) {
         REPORTER_ASSERT(reporter, cur->fID == i);
     }
 
@@ -114,7 +114,7 @@
     check_list(list, reporter, false, 4, true, true, true, true, elements);
 
     cur = iter.init(list, Iter::kHead_IterStart);
-    for (int i = 0; NULL != cur; ++i, cur = iter.next()) {
+    for (int i = 0; cur; ++i, cur = iter.next()) {
         REPORTER_ASSERT(reporter, cur->fID == i);
     }
 }
@@ -228,7 +228,7 @@
                         next.next();
                         prev.prev();
 
-                        SkASSERT(NULL != iter.get());
+                        SkASSERT(iter.get());
                         // insert either before or after the iterator, then check that the
                         // surrounding sequence is correct.
                         if (2 == insertionMethod) {
@@ -237,10 +237,10 @@
                             newItem.prev();
                             REPORTER_ASSERT(reporter, newItem.get()->fID == id);
 
-                            if (NULL != next.get()) {
+                            if (next.get()) {
                                 REPORTER_ASSERT(reporter, next.prev()->fID == iter.get()->fID);
                             }
-                            if (NULL != prev.get()) {
+                            if (prev.get()) {
                                 REPORTER_ASSERT(reporter, prev.next()->fID == id);
                             }
                         } else {
@@ -249,10 +249,10 @@
                             newItem.next();
                             REPORTER_ASSERT(reporter, newItem.get()->fID == id);
 
-                            if (NULL != next.get()) {
+                            if (next.get()) {
                                 REPORTER_ASSERT(reporter, next.prev()->fID == id);
                             }
-                            if (NULL != prev.get()) {
+                            if (prev.get()) {
                                 REPORTER_ASSERT(reporter, prev.next()->fID == iter.get()->fID);
                             }
                         }
@@ -276,10 +276,10 @@
                 // find the element
                 Iter iter(list1, start);
                 while (n--) {
-                    REPORTER_ASSERT(reporter, NULL != iter.get());
+                    REPORTER_ASSERT(reporter, iter.get());
                     (iter.*incrFunc)();
                 }
-                REPORTER_ASSERT(reporter, NULL != iter.get());
+                REPORTER_ASSERT(reporter, iter.get());
 
                 // remember the prev and next elements from the element to be removed
                 Iter prev = iter;
diff --git a/tests/LayerRasterizerTest.cpp b/tests/LayerRasterizerTest.cpp
index 640c581..4b236ac 100644
--- a/tests/LayerRasterizerTest.cpp
+++ b/tests/LayerRasterizerTest.cpp
@@ -33,11 +33,9 @@
 
     static int GetCount() { return gCount; }
 
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DummyRasterizer)
+    SK_DECLARE_NOT_FLATTENABLE_PROCS(DummyRasterizer)
 
 private:
-    DummyRasterizer(SkReadBuffer&) {}
-
     static int gCount;
 
     typedef SkRasterizer INHERITED;
diff --git a/tests/MallocPixelRefTest.cpp b/tests/MallocPixelRefTest.cpp
index cf5e054..e267d6f 100644
--- a/tests/MallocPixelRefTest.cpp
+++ b/tests/MallocPixelRefTest.cpp
@@ -32,22 +32,18 @@
     {
         size_t rowBytes = info.minRowBytes() - 1;
         size_t size = info.getSafeSize(rowBytes);
-        void* addr = sk_malloc_throw(size);
-        SkAutoDataUnref data(SkData::NewFromMalloc(addr, size));
+        SkAutoDataUnref data(SkData::NewUninitialized(size));
         SkAutoTUnref<SkMallocPixelRef> pr(
-            SkMallocPixelRef::NewWithData(info, rowBytes,
-                                          NULL, data.get()));
+            SkMallocPixelRef::NewWithData(info, rowBytes, NULL, data));
         // rowbytes too small.
         REPORTER_ASSERT(reporter, NULL == pr.get());
     }
     {
         size_t rowBytes = info.minRowBytes() + 2;
         size_t size = info.getSafeSize(rowBytes) - 1;
-        void* addr = sk_malloc_throw(size);
-        SkAutoDataUnref data(SkData::NewFromMalloc(addr, size));
+        SkAutoDataUnref data(SkData::NewUninitialized(size));
         SkAutoTUnref<SkMallocPixelRef> pr(
-            SkMallocPixelRef::NewWithData(info, rowBytes, NULL,
-                                          data.get()));
+            SkMallocPixelRef::NewWithData(info, rowBytes, NULL, data));
         // data too small.
         REPORTER_ASSERT(reporter, NULL == pr.get());
     }
@@ -64,7 +60,7 @@
         SkAutoTUnref<SkMallocPixelRef> pr(
             SkMallocPixelRef::NewAllocate(info, rowBytes, NULL));
         REPORTER_ASSERT(reporter, pr.get() != NULL);
-        REPORTER_ASSERT(reporter, NULL != pr->pixels());
+        REPORTER_ASSERT(reporter, pr->pixels());
     }
     {
         void* addr = static_cast<void*>(new uint8_t[size]);
@@ -77,7 +73,6 @@
     {
         int x = 0;
         SkAutoMalloc memory(size);
-        REPORTER_ASSERT(reporter, memory.get() != NULL);
         SkAutoTUnref<SkMallocPixelRef> pr(
             SkMallocPixelRef::NewWithProc(info, rowBytes, NULL,
                                           memory.get(), set_to_one_proc,
@@ -98,9 +93,7 @@
         REPORTER_ASSERT(reporter, addr == pr->pixels());
     }
     {
-        void* addr = sk_malloc_throw(size);
-        SkAutoDataUnref data(SkData::NewFromMalloc(addr, size));
-        REPORTER_ASSERT(reporter, data.get() != NULL);
+        SkAutoDataUnref data(SkData::NewUninitialized(size));
         SkData* dataPtr = data.get();
         REPORTER_ASSERT(reporter, dataPtr->unique());
         SkAutoTUnref<SkMallocPixelRef> pr(
diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp
index 4205ce6..2053936 100644
--- a/tests/MathTest.cpp
+++ b/tests/MathTest.cpp
@@ -264,9 +264,7 @@
 static void test_int2float(skiatest::Reporter* reporter, int ival) {
     float x0 = (float)ival;
     float x1 = SkIntToFloatCast(ival);
-    float x2 = SkIntToFloatCast_NoOverflowCheck(ival);
     REPORTER_ASSERT(reporter, x0 == x1);
-    REPORTER_ASSERT(reporter, x0 == x2);
 }
 
 static void unittest_fastfloat(skiatest::Reporter* reporter) {
diff --git a/tests/Matrix44Test.cpp b/tests/Matrix44Test.cpp
index 443086d..0bd4a8b 100644
--- a/tests/Matrix44Test.cpp
+++ b/tests/Matrix44Test.cpp
@@ -521,6 +521,35 @@
     REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec4transformed2[3]));
 }
 
+static void test_has_perspective(skiatest::Reporter* reporter) {
+    SkMatrix44 transform(SkMatrix44::kIdentity_Constructor);
+
+    transform.set(3, 2, -0.1);
+    REPORTER_ASSERT(reporter, transform.hasPerspective());
+
+    transform.reset();
+    REPORTER_ASSERT(reporter, !transform.hasPerspective());
+
+    transform.set(3, 0, -1.0);
+    REPORTER_ASSERT(reporter, transform.hasPerspective());
+
+    transform.reset();
+    transform.set(3, 1, -1.0);
+    REPORTER_ASSERT(reporter, transform.hasPerspective());
+
+    transform.reset();
+    transform.set(3, 2, -0.3);
+    REPORTER_ASSERT(reporter, transform.hasPerspective());
+
+    transform.reset();
+    transform.set(3, 3, 0.5);
+    REPORTER_ASSERT(reporter, transform.hasPerspective());
+ 
+    transform.reset();
+    transform.set(3, 3, 0.0);
+    REPORTER_ASSERT(reporter, transform.hasPerspective());
+}
+
 DEF_TEST(Matrix44, reporter) {
     SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
     SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
@@ -626,4 +655,5 @@
     test_scale(reporter);
     test_map2(reporter);
     test_3x3_conversion(reporter);
+    test_has_perspective(reporter);
 }
diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp
index 9c7a520..fc7ac42 100644
--- a/tests/MatrixTest.cpp
+++ b/tests/MatrixTest.cpp
@@ -245,82 +245,96 @@
     }
 }
 
-static void test_matrix_is_similarity(skiatest::Reporter* reporter) {
+static void test_matrix_preserve_shape(skiatest::Reporter* reporter) {
     SkMatrix mat;
 
     // identity
     mat.setIdentity();
     REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // translation only
     mat.reset();
     mat.setTranslate(SkIntToScalar(100), SkIntToScalar(100));
     REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // scale with same size
     mat.reset();
     mat.setScale(SkIntToScalar(15), SkIntToScalar(15));
     REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // scale with one negative
     mat.reset();
     mat.setScale(SkIntToScalar(-15), SkIntToScalar(15));
     REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // scale with different size
     mat.reset();
     mat.setScale(SkIntToScalar(15), SkIntToScalar(20));
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // scale with same size at a pivot point
     mat.reset();
     mat.setScale(SkIntToScalar(15), SkIntToScalar(15),
                  SkIntToScalar(2), SkIntToScalar(2));
     REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // scale with different size at a pivot point
     mat.reset();
     mat.setScale(SkIntToScalar(15), SkIntToScalar(20),
                  SkIntToScalar(2), SkIntToScalar(2));
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // skew with same size
     mat.reset();
     mat.setSkew(SkIntToScalar(15), SkIntToScalar(15));
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, !mat.preservesRightAngles());
 
     // skew with different size
     mat.reset();
     mat.setSkew(SkIntToScalar(15), SkIntToScalar(20));
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, !mat.preservesRightAngles());
 
     // skew with same size at a pivot point
     mat.reset();
     mat.setSkew(SkIntToScalar(15), SkIntToScalar(15),
                 SkIntToScalar(2), SkIntToScalar(2));
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, !mat.preservesRightAngles());
 
     // skew with different size at a pivot point
     mat.reset();
     mat.setSkew(SkIntToScalar(15), SkIntToScalar(20),
                 SkIntToScalar(2), SkIntToScalar(2));
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, !mat.preservesRightAngles());
 
     // perspective x
     mat.reset();
     mat.setPerspX(SkScalarToPersp(SK_Scalar1 / 2));
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, !mat.preservesRightAngles());
 
     // perspective y
     mat.reset();
     mat.setPerspY(SkScalarToPersp(SK_Scalar1 / 2));
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, !mat.preservesRightAngles());
 
     // rotate
     for (int angle = 0; angle < 360; ++angle) {
         mat.reset();
         mat.setRotate(SkIntToScalar(angle));
         REPORTER_ASSERT(reporter, mat.isSimilarity());
+        REPORTER_ASSERT(reporter, mat.preservesRightAngles());
     }
 
     // see if there are any accumulated precision issues
@@ -329,38 +343,60 @@
         mat.postRotate(SkIntToScalar(1));
     }
     REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // rotate + translate
     mat.reset();
     mat.setRotate(SkIntToScalar(30));
     mat.postTranslate(SkIntToScalar(10), SkIntToScalar(20));
     REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // rotate + uniform scale
     mat.reset();
     mat.setRotate(SkIntToScalar(30));
     mat.postScale(SkIntToScalar(2), SkIntToScalar(2));
     REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // rotate + non-uniform scale
     mat.reset();
     mat.setRotate(SkIntToScalar(30));
     mat.postScale(SkIntToScalar(3), SkIntToScalar(2));
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, !mat.preservesRightAngles());
+
+    // non-uniform scale + rotate
+    mat.reset();
+    mat.setScale(SkIntToScalar(3), SkIntToScalar(2));
+    mat.postRotate(SkIntToScalar(30));
+    REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 
     // all zero
     mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0);
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, !mat.preservesRightAngles());
 
     // all zero except perspective
+    mat.reset();
     mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1);
     REPORTER_ASSERT(reporter, !mat.isSimilarity());
+    REPORTER_ASSERT(reporter, !mat.preservesRightAngles());
 
-    // scales zero, only skews
+    // scales zero, only skews (rotation)
+    mat.setAll(0, SK_Scalar1, 0,
+               -SK_Scalar1, 0, 0,
+               0, 0, SkMatrix::I()[8]);
+    REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
+
+    // scales zero, only skews (reflection)
     mat.setAll(0, SK_Scalar1, 0,
                SK_Scalar1, 0, 0,
                0, 0, SkMatrix::I()[8]);
     REPORTER_ASSERT(reporter, mat.isSimilarity());
+    REPORTER_ASSERT(reporter, mat.preservesRightAngles());
 }
 
 // For test_matrix_decomposition, below.
@@ -809,7 +845,7 @@
     REPORTER_ASSERT(reporter, !are_equal(reporter, mat, mat2));
 
     test_matrix_min_max_scale(reporter);
-    test_matrix_is_similarity(reporter);
+    test_matrix_preserve_shape(reporter);
     test_matrix_recttorect(reporter);
     test_matrix_decomposition(reporter);
     test_matrix_homogeneous(reporter);
diff --git a/tests/MiniDataTest.cpp b/tests/MiniDataTest.cpp
new file mode 100644
index 0000000..cb656b3
--- /dev/null
+++ b/tests/MiniDataTest.cpp
@@ -0,0 +1,16 @@
+#include "SkMiniData.h"
+#include "Test.h"
+
+DEF_TEST(MiniData, r) {
+    static const char* s = "abcdefghijklmnopqrstuvwxyz";
+
+    for (size_t len = 0; len <= 26; len++) {
+        SkMiniData md(s, len);
+        REPORTER_ASSERT(r, md.len() == len);
+        REPORTER_ASSERT(r, 0 == memcmp(md.data(), s, len));
+
+        SkMiniData copy(md);
+        REPORTER_ASSERT(r, copy.len() == len);
+        REPORTER_ASSERT(r, 0 == memcmp(copy.data(), s, len));
+    }
+}
diff --git a/tests/OSPathTest.cpp b/tests/OSPathTest.cpp
index d36b7cb..facc6ad 100644
--- a/tests/OSPathTest.cpp
+++ b/tests/OSPathTest.cpp
@@ -10,9 +10,9 @@
 #include "Test.h"
 
 /**
- *  Test SkPathJoin and SkBasename.
- *  Will use SkPathJoin to append filename to dir, test that it works correctly,
- *  and tests using SkBasename on the result.
+ *  Test SkOSPath::Join, SkOSPath::Basename, and SkOSPath::Dirname.
+ *  Will use SkOSPath::Join to append filename to dir, test that it works correctly,
+ *  and tests using SkOSPath::Basename on the result.
  *  @param reporter Reporter for test conditions.
  *  @param dir String representing the path to a folder. May or may not
  *      end with SkPATH_SEPARATOR.
@@ -24,29 +24,41 @@
     // If filename contains SkPATH_SEPARATOR, the tests will fail.
     SkASSERT(!filename.contains(SkPATH_SEPARATOR));
 
-    // Tests for SkOSPath::SkPathJoin and SkOSPath::SkBasename
+    // Tests for SkOSPath::Join and SkOSPath::Basename
 
     // fullName should be "dir<SkPATH_SEPARATOR>file"
-    SkString fullName = SkOSPath::SkPathJoin(dir.c_str(), filename.c_str());
+    SkString fullName = SkOSPath::Join(dir.c_str(), filename.c_str());
 
     // fullName should be the combined size of dir and file, plus one if
     // dir did not include the final path separator.
     size_t expectedSize = dir.size() + filename.size();
-    if (!dir.endsWith(SkPATH_SEPARATOR)) {
+    if (!dir.endsWith(SkPATH_SEPARATOR) && !dir.isEmpty()) {
         expectedSize++;
     }
     REPORTER_ASSERT(reporter, fullName.size() == expectedSize);
 
-    SkString basename = SkOSPath::SkBasename(fullName.c_str());
+    SkString basename = SkOSPath::Basename(fullName.c_str());
+    SkString dirname = SkOSPath::Dirname(fullName.c_str());
 
     // basename should be the same as filename
     REPORTER_ASSERT(reporter, basename.equals(filename));
 
+    // dirname should be the same as dir with any trailing seperators removed.
+    // Except when the the string is just "/".
+    SkString strippedDir = dir;
+    while (strippedDir.size() > 2 && strippedDir[strippedDir.size() - 1] == SkPATH_SEPARATOR) {
+        strippedDir.remove(strippedDir.size() - 1, 1);
+    }
+    if (!dirname.equals(strippedDir)) {
+        SkDebugf("OOUCH %s %s %s\n", dir.c_str(), strippedDir.c_str(), dirname.c_str());
+    }
+    REPORTER_ASSERT(reporter, dirname.equals(strippedDir));
+
     // basename will not contain a path separator
     REPORTER_ASSERT(reporter, !basename.contains(SkPATH_SEPARATOR));
 
     // Now take the basename of filename, which should be the same as filename.
-    basename = SkOSPath::SkBasename(filename.c_str());
+    basename = SkOSPath::Basename(filename.c_str());
     REPORTER_ASSERT(reporter, basename.equals(filename));
 }
 
@@ -71,15 +83,23 @@
 
     // Basename of a directory with a path separator at the end is empty.
     dir.appendUnichar(SkPATH_SEPARATOR);
-    SkString baseOfDir = SkOSPath::SkBasename(dir.c_str());
+    SkString baseOfDir = SkOSPath::Basename(dir.c_str());
     REPORTER_ASSERT(reporter, baseOfDir.size() == 0);
 
     // Basename of NULL is an empty string.
-    SkString empty = SkOSPath::SkBasename(NULL);
+    SkString empty = SkOSPath::Basename(NULL);
     REPORTER_ASSERT(reporter, empty.size() == 0);
 
+    // File in root dir
+    dir.printf("%c", SkPATH_SEPARATOR);
+    filename.set("file");
+    test_dir_with_file(reporter, dir, filename);
+
+    // Just the root dir
+    filename.reset();
+    test_dir_with_file(reporter, dir, filename);
+
     // Test that NULL can be used for the directory and filename.
-    SkString emptyPath = SkOSPath::SkPathJoin(NULL, NULL);
-    REPORTER_ASSERT(reporter, emptyPath.size() == 1);
-    REPORTER_ASSERT(reporter, emptyPath.contains(SkPATH_SEPARATOR));
+    SkString emptyPath = SkOSPath::Join(NULL, NULL);
+    REPORTER_ASSERT(reporter, emptyPath.isEmpty());
 }
diff --git a/tests/OnceTest.cpp b/tests/OnceTest.cpp
index 389d257..192abaa 100644
--- a/tests/OnceTest.cpp
+++ b/tests/OnceTest.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "SkOnce.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
 #include "Test.h"
 
 static void add_five(int* x) {
@@ -42,7 +42,7 @@
 };
 
 DEF_TEST(SkOnce_Multithreaded, r) {
-    const int kTasks = 16, kThreads = 4;
+    const int kTasks = 16;
 
     // Make a bunch of tasks that will race to be the first to add six to x.
     Racer racers[kTasks];
@@ -54,11 +54,11 @@
     }
 
     // Let them race.
-    SkThreadPool pool(kThreads);
+    SkTaskGroup tg;
     for (int i = 0; i < kTasks; i++) {
-        pool.add(&racers[i]);
+        tg.add(&racers[i]);
     }
-    pool.wait();
+    tg.wait();
 
     // Only one should have done the +=.
     REPORTER_ASSERT(r, 6 == x);
diff --git a/tests/PDFJpegEmbedTest.cpp b/tests/PDFJpegEmbedTest.cpp
new file mode 100644
index 0000000..c1d0ea8
--- /dev/null
+++ b/tests/PDFJpegEmbedTest.cpp
@@ -0,0 +1,101 @@
+/*
+ * 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 "SkDocument.h"
+#include "SkCanvas.h"
+#include "SkImageGenerator.h"
+#include "SkData.h"
+#include "SkStream.h"
+#include "SkDecodingImageGenerator.h"
+
+#include "Resources.h"
+#include "Test.h"
+
+// Returned bitmap is lazy.  Only lazy bitmaps hold onto the original data.
+static SkBitmap bitmap_from_data(SkData* data) {
+    SkASSERT(data);
+    SkBitmap bm;
+    SkInstallDiscardablePixelRef(
+            SkDecodingImageGenerator::Create(
+                    data, SkDecodingImageGenerator::Options()), &bm);
+    return bm;
+}
+
+static bool is_subset_of(SkData* smaller, SkData* larger) {
+    SkASSERT(smaller && larger);
+    if (smaller->size() > larger->size()) {
+        return false;
+    }
+    size_t size = smaller->size();
+    size_t size_diff = larger->size() - size;
+    for (size_t i = 0; i <= size_diff; ++i) {
+        if (0 == memcmp(larger->bytes() + i, smaller->bytes(), size)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+static SkData* load_resource(
+        skiatest::Reporter* r, const char* test, const char* filename) {
+    SkString path(GetResourcePath(filename));
+    SkData* data = SkData::NewFromFileName(path.c_str());
+    if (!data && r->verbose()) {
+        SkDebugf("\n%s: Resource '%s' can not be found.\n",
+                 test, filename);
+    }
+    return data;  // May return NULL.
+}
+
+/**
+ *  Test that for Jpeg files that use the JFIF colorspace, they are
+ *  directly embedded into the PDF (without re-encoding) when that
+ *  makes sense.
+ */
+DEF_TEST(PDFJpegEmbedTest, r) {
+    const char test[] = "PDFJpegEmbedTest";
+    SkAutoTUnref<SkData> mandrillData(
+            load_resource(r, test, "mandrill_512_q075.jpg"));
+    SkAutoTUnref<SkData> cmykData(load_resource(r, test, "CMYK.jpg"));
+    if (!mandrillData || !cmykData) {
+        return;
+    }
+
+    SkDynamicMemoryWStream pdf;
+    SkAutoTUnref<SkDocument> document(SkDocument::CreatePDF(&pdf));
+    SkCanvas* canvas = document->beginPage(642, 1028);
+
+    canvas->clear(SK_ColorLTGRAY);
+
+    SkBitmap bm1(bitmap_from_data(mandrillData));
+    canvas->drawBitmap(bm1, 65.0, 0.0, NULL);
+    SkBitmap bm2(bitmap_from_data(cmykData));
+    canvas->drawBitmap(bm2, 0.0, 512.0, NULL);
+
+    canvas->flush();
+    document->endPage();
+    document->close();
+    SkAutoTUnref<SkData> pdfData(pdf.copyToData());
+    SkASSERT(pdfData);
+    pdf.reset();
+
+    REPORTER_ASSERT(r, is_subset_of(mandrillData, pdfData));
+
+    // This JPEG uses a nonstandard colorspace - it can not be
+    // embedded into the PDF directly.
+    REPORTER_ASSERT(r, !is_subset_of(cmykData, pdfData));
+
+    // The following is for debugging purposes only.
+    const char* outputPath = getenv("SKIA_TESTS_PDF_JPEG_EMBED_OUTPUT_PATH");
+    if (outputPath) {
+        SkFILEWStream output(outputPath);
+        if (output.isValid()) {
+            output.write(pdfData->data(), pdfData->size());
+        }
+    }
+}
diff --git a/tests/PDFPrimitivesTest.cpp b/tests/PDFPrimitivesTest.cpp
index b1d482f..05677cd 100644
--- a/tests/PDFPrimitivesTest.cpp
+++ b/tests/PDFPrimitivesTest.cpp
@@ -15,6 +15,7 @@
 #include "SkPDFDevice.h"
 #include "SkPDFStream.h"
 #include "SkPDFTypes.h"
+#include "SkReadBuffer.h"
 #include "SkScalar.h"
 #include "SkStream.h"
 #include "SkTypes.h"
@@ -428,3 +429,54 @@
 
     TestImages(reporter);
 }
+
+namespace {
+
+class DummyImageFilter : public SkImageFilter {
+public:
+    DummyImageFilter(bool visited = false) : SkImageFilter(0, NULL), fVisited(visited) {}
+    virtual ~DummyImageFilter() SK_OVERRIDE {}
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+                               SkBitmap* result, SkIPoint* offset) const {
+        fVisited = true;
+        offset->fX = offset->fY = 0;
+        *result = src;
+        return true;
+    }
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DummyImageFilter)
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    explicit DummyImageFilter(SkReadBuffer& buffer) : SkImageFilter(0, NULL) {
+        fVisited = buffer.readBool();
+    }
+#endif
+    bool visited() const { return fVisited; }
+
+private:
+    mutable bool fVisited;
+};
+
+SkFlattenable* DummyImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
+    bool visited = buffer.readBool();
+    return SkNEW_ARGS(DummyImageFilter, (visited));
+}
+
+};
+
+// Check that PDF rendering of image filters successfully falls back to
+// CPU rasterization.
+DEF_TEST(PDFImageFilter, reporter) {
+    SkISize pageSize = SkISize::Make(100, 100);
+    SkAutoTUnref<SkPDFDevice> device(new SkPDFDevice(pageSize, pageSize, SkMatrix::I()));
+    SkCanvas canvas(device.get());
+    SkAutoTUnref<DummyImageFilter> filter(new DummyImageFilter());
+
+    // Filter just created; should be unvisited.
+    REPORTER_ASSERT(reporter, !filter->visited());
+    SkPaint paint;
+    paint.setImageFilter(filter.get());
+    canvas.drawRect(SkRect::MakeWH(100, 100), paint);
+
+    // Filter was used in rendering; should be visited.
+    REPORTER_ASSERT(reporter, filter->visited());
+}
diff --git a/tests/PaintTest.cpp b/tests/PaintTest.cpp
index dbe7016..57d0283 100644
--- a/tests/PaintTest.cpp
+++ b/tests/PaintTest.cpp
@@ -309,7 +309,7 @@
     r.setLTRB(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN);
 
     // test that the rect was reset
-    paint.measureText("", 0, &r, 1.0f);
+    paint.measureText("", 0, &r);
     REPORTER_ASSERT(reporter, r.isEmpty());
 }
 
@@ -318,19 +318,22 @@
 DEF_TEST(Paint_FlatteningTraits, r) {
     SkPaint paint;
     paint.setColor(0x00AABBCC);
-    paint.setTextScaleX(1.0f);  // Encoded despite being the default value.
+    paint.setTextScaleX(1.0f);  // Default value, ignored.
     paint.setTextSize(19);
     paint.setXfermode(SkXfermode::Create(SkXfermode::kModulate_Mode))->unref();
-    paint.setLooper(NULL);  // Ignored.
+    paint.setLooper(NULL);  // Default value, ignored.
 
     SkWriteBuffer writer;
     SkPaint::FlatteningTraits::Flatten(writer, paint);
-    const size_t expectedBytesWritten = sizeof(void*) == 8 ? 36 : 32;
-    ASSERT(expectedBytesWritten == writer.bytesWritten());
 
-    const uint32_t* written = writer.getWriter32()->contiguousArray();
-    SkASSERT(written != NULL);
-    ASSERT(*written == ((1<<0) | (1<<1) | (1<<2) | (1<<8)));  // Dirty bits for our 4.
+    // BEGIN white box asserts: if the impl changes, these asserts may change
+        const size_t expectedBytesWritten = sizeof(void*) == 8 ? 32 : 28;
+        ASSERT(expectedBytesWritten == writer.bytesWritten());
+
+        const uint32_t* written = writer.getWriter32()->contiguousArray();
+        SkASSERT(written != NULL);
+        ASSERT(*written == ((1<<0) | (1<<1) | (1<<8)));  // Dirty bits for our 3.
+    // END white box asserts
 
     SkReadBuffer reader(written, writer.bytesWritten());
     SkPaint other;
diff --git a/tests/PathOpsBattles.cpp b/tests/PathOpsBattles.cpp
new file mode 100644
index 0000000..15fffd5
--- /dev/null
+++ b/tests/PathOpsBattles.cpp
@@ -0,0 +1,11183 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+#include "PathOpsTestCommon.h"
+
+#define TEST(name) { name, #name }
+
+static void issue414409(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path1, path2;
+
+    // one fill 1
+    path1.moveTo(9.53595e-07f, -60);
+    path1.lineTo(5.08228e-15f, -83);
+    path1.cubicTo(32.8673f, -83, 62.6386f, -63.6055f, 75.9208f, -33.5416f);
+    path1.cubicTo(89.2029f, -3.47759f, 83.4937f, 31.5921f, 61.3615f, 55.8907f);
+    path1.lineTo(46.9383f, 68.4529f);
+    path1.lineTo(33.9313f, 49.484f);
+    path1.cubicTo(37.7451f, 46.8689f, 41.2438f, 43.8216f, 44.3577f, 40.4029f);
+    path1.lineTo(44.3577f, 40.4029f);
+    path1.cubicTo(60.3569f, 22.8376f, 64.4841f, -2.51392f, 54.8825f, -24.2469f);
+    path1.cubicTo(45.2809f, -45.9799f, 23.7595f, -60, 9.53595e-07f, -60);
+    path1.close();
+
+    //  two fill 0
+    path2.moveTo(46.9383f, 68.4529f);
+    path2.cubicTo(17.5117f, 88.6307f, -21.518f, 87.7442f, -49.9981f, 66.251f);
+    path2.cubicTo(-78.4781f, 44.7578f, -90.035f, 7.46781f, -78.7014f, -26.3644f);
+    path2.cubicTo(-67.3679f, -60.1967f, -35.6801f, -83, -1.48383e-06f, -83);
+    path2.lineTo(4.22689e-14f, -60);
+    path2.cubicTo(-25.7929f, -60, -48.6997f, -43.5157f, -56.8926f, -19.0586f);
+    path2.cubicTo(-65.0855f, 5.39842f, -56.7312f, 32.355f, -36.1432f, 47.8923f);
+    path2.cubicTo(-15.5552f, 63.4296f, 12.6591f, 64.0704f, 33.9313f, 49.484f);
+    path2.lineTo(46.9383f, 68.4529f);
+    path2.close();
+    testPathOp(reporter, path1, path2, kUnion_PathOp, filename);
+}
+
+static void issue414409b(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path1, path2;
+    // one fill=0 op=2
+path1.setFillType((SkPath::FillType) 0);
+path1.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path1.cubicTo(SkBits2Float(0x41f12edc), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4267b362), SkBits2Float(0xc2854e1f), SkBits2Float(0x42911faa), SkBits2Float(0xc2212f3b));
+path1.cubicTo(SkBits2Float(0x42ae65a2), SkBits2Float(0xc15f08de), SkBits2Float(0x42acc913), SkBits2Float(0x41923f59), SkBits2Float(0x428ce9f0), SkBits2Float(0x422f7dc4));
+path1.lineTo(SkBits2Float(0x424bbb16), SkBits2Float(0x41fdb8ed));
+path1.cubicTo(SkBits2Float(0x4279cf6e), SkBits2Float(0x41537137), SkBits2Float(0x427c23ea), SkBits2Float(0xc1213ad2), SkBits2Float(0x4251d142), SkBits2Float(0xc1e909ae));
+path1.cubicTo(SkBits2Float(0x42277e9a), SkBits2Float(0xc240baf8), SkBits2Float(0x41ae5968), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path1.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path1.close();
+
+path2.setFillType((SkPath::FillType) 1);
+path2.moveTo(SkBits2Float(0x428ce9ef), SkBits2Float(0x422f7dc6));
+path2.cubicTo(SkBits2Float(0x4286af43), SkBits2Float(0x42437fa7), SkBits2Float(0x427ed0d6), SkBits2Float(0x42561f5a), SkBits2Float(0x426e69d2), SkBits2Float(0x42670c39));
+path2.lineTo(SkBits2Float(0x422c58d6), SkBits2Float(0x422705c1));
+path2.cubicTo(SkBits2Float(0x42383446), SkBits2Float(0x421ac98f), SkBits2Float(0x4242b98a), SkBits2Float(0x420d5308), SkBits2Float(0x424bbb17), SkBits2Float(0x41fdb8ee));
+path2.lineTo(SkBits2Float(0x428ce9ef), SkBits2Float(0x422f7dc6));
+path2.close();
+// SkOpSegment.cpp:3488: failed assertion "other->fTs[min].fWindSum == oppWinding"
+    testPathOp(reporter, path1, path2, kUnion_PathOp, filename);
+}
+
+static void issue414409c(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path1, path2;
+path1.setFillType((SkPath::FillType) 1);
+path1.moveTo(SkBits2Float(0x36961ef0), SkBits2Float(0xc2700000));
+path1.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path1.cubicTo(SkBits2Float(0x3df86648), SkBits2Float(0xc2a60000), SkBits2Float(0x3e786777), SkBits2Float(0xc2a5ffdc), SkBits2Float(0x3eba4dc2), SkBits2Float(0xc2a5ff96));
+path1.lineTo(SkBits2Float(0x3eba4dc3), SkBits2Float(0xc2a5ff97));
+path1.cubicTo(SkBits2Float(0x3ec08370), SkBits2Float(0xc2a5ff8f), SkBits2Float(0x3ec6b964), SkBits2Float(0xc2a5ff88), SkBits2Float(0x3eccef58), SkBits2Float(0xc2a5ff80));
+path1.lineTo(SkBits2Float(0x3e942522), SkBits2Float(0xc26fff49));
+path1.cubicTo(SkBits2Float(0x3e8fa7da), SkBits2Float(0xc26fff56), SkBits2Float(0x3e8b2acd), SkBits2Float(0xc26fff61), SkBits2Float(0x3e86adc0), SkBits2Float(0xc26fff6b));
+path1.lineTo(SkBits2Float(0x3e86ad6a), SkBits2Float(0xc26fff69));
+path1.cubicTo(SkBits2Float(0x3e3391e9), SkBits2Float(0xc26fffce), SkBits2Float(0x3db3931e), SkBits2Float(0xc2700000), SkBits2Float(0x36961ef0), SkBits2Float(0xc2700000));
+path1.close();
+
+path2.setFillType((SkPath::FillType) 0);
+path2.moveTo(SkBits2Float(0x3eccef1a), SkBits2Float(0xc2a5ff81));
+path2.cubicTo(SkBits2Float(0x3f18c8a9), SkBits2Float(0xc2a5ff04), SkBits2Float(0x3f4b19b0), SkBits2Float(0xc2a5fe2d), SkBits2Float(0x3f7d6a37), SkBits2Float(0xc2a5fcfa));
+path2.lineTo(SkBits2Float(0x3f3730f2), SkBits2Float(0xc26ffba1));
+path2.cubicTo(SkBits2Float(0x3f12d1c8), SkBits2Float(0xc26ffd5d), SkBits2Float(0x3edce4b4), SkBits2Float(0xc26ffe95), SkBits2Float(0x3e942577), SkBits2Float(0xc26fff49));
+path2.lineTo(SkBits2Float(0x3eccef1a), SkBits2Float(0xc2a5ff81));
+path2.close();
+
+testPathOp(reporter, path1, path2, kUnion_PathOp, filename);
+}
+
+// fails to draw correctly
+static void battleOp1(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ea4d9f5), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f24d9a9), SkBits2Float(0xc2a5ff0a), SkBits2Float(0x3f774519), SkBits2Float(0xc2a5fd1f));
+path.lineTo(SkBits2Float(0x3f32bfc3), SkBits2Float(0xc26ffbd7));
+path.cubicTo(SkBits2Float(0x3eee5669), SkBits2Float(0xc26ffe9e), SkBits2Float(0x3e6e56cc), SkBits2Float(0xc2700000), SkBits2Float(0x357ffb40), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f774503), SkBits2Float(0xc2a5fd1f));
+path.cubicTo(SkBits2Float(0x3f7f82ff), SkBits2Float(0xc2a5fcee), SkBits2Float(0x3f83e06d), SkBits2Float(0xc2a5fcbb), SkBits2Float(0x3f87ff59), SkBits2Float(0xc2a5fc85));
+path.lineTo(SkBits2Float(0x3f449f80), SkBits2Float(0xc26ffaf7));
+path.cubicTo(SkBits2Float(0x3f3eaa52), SkBits2Float(0xc26ffb47), SkBits2Float(0x3f38b4f5), SkBits2Float(0xc26ffb92), SkBits2Float(0x3f32bf98), SkBits2Float(0xc26ffbd9));
+path.lineTo(SkBits2Float(0x3f774503), SkBits2Float(0xc2a5fd1f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp2(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ea4d9e6), SkBits2Float(0xc2a60000), SkBits2Float(0x3f24d99a), SkBits2Float(0xc2a5ff0a), SkBits2Float(0x3f774503), SkBits2Float(0xc2a5fd1f));
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f87ff64), SkBits2Float(0xc2a5fc85));
+path.cubicTo(SkBits2Float(0x3fcac720), SkBits2Float(0xc2a5f91a), SkBits2Float(0x4006c62a), SkBits2Float(0xc2a5f329), SkBits2Float(0x40282667), SkBits2Float(0xc2a5eab4));
+path.lineTo(SkBits2Float(0x3ff31bb9), SkBits2Float(0xc26fe136));
+path.cubicTo(SkBits2Float(0x3fc2da88), SkBits2Float(0xc26fed71), SkBits2Float(0x3f9295ff), SkBits2Float(0xc26ff607), SkBits2Float(0x3f449f66), SkBits2Float(0xc26ffaf9));
+path.lineTo(SkBits2Float(0x3f87ff64), SkBits2Float(0xc2a5fc85));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp3(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f19f03c), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f99ef95), SkBits2Float(0xc2a5fca7), SkBits2Float(0x3fe6e2fa), SkBits2Float(0xc2a5f5f7));
+path.lineTo(SkBits2Float(0x3fa6e80c), SkBits2Float(0xc26ff17d));
+path.cubicTo(SkBits2Float(0x3f5e8ed4), SkBits2Float(0xc26ffb2a), SkBits2Float(0x3ede8fc6), SkBits2Float(0xc2700000), SkBits2Float(0x35d9fd64), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fe6e322), SkBits2Float(0xc2a5f5f7));
+path.cubicTo(SkBits2Float(0x3fee94fb), SkBits2Float(0xc2a5f54c), SkBits2Float(0x3ff646db), SkBits2Float(0xc2a5f497), SkBits2Float(0x3ffdf8ad), SkBits2Float(0xc2a5f3db));
+path.lineTo(SkBits2Float(0x3fb79813), SkBits2Float(0xc26fee71));
+path.cubicTo(SkBits2Float(0x3fb20800), SkBits2Float(0xc26fef82), SkBits2Float(0x3fac77ff), SkBits2Float(0xc26ff085), SkBits2Float(0x3fa6e7f4), SkBits2Float(0xc26ff17d));
+path.lineTo(SkBits2Float(0x3fe6e322), SkBits2Float(0xc2a5f5f7));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp4(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f19f03c), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f99ef95), SkBits2Float(0xc2a5fca7), SkBits2Float(0x3fe6e322), SkBits2Float(0xc2a5f5f7));
+path.cubicTo(SkBits2Float(0x3fee94fb), SkBits2Float(0xc2a5f54c), SkBits2Float(0x3ff646db), SkBits2Float(0xc2a5f497), SkBits2Float(0x3ffdf8ad), SkBits2Float(0xc2a5f3db));
+path.lineTo(SkBits2Float(0x3fb79813), SkBits2Float(0xc26fee71));
+path.cubicTo(SkBits2Float(0x3fb20808), SkBits2Float(0xc26fef82), SkBits2Float(0x3fac780f), SkBits2Float(0xc26ff085), SkBits2Float(0x3fa6e80c), SkBits2Float(0xc26ff17d));
+path.lineTo(SkBits2Float(0x3fa6e7f4), SkBits2Float(0xc26ff17d));
+path.cubicTo(SkBits2Float(0x3f5e8eb4), SkBits2Float(0xc26ffb2a), SkBits2Float(0x3ede8fa6), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ffdf8c6), SkBits2Float(0xc2a5f3db));
+path.cubicTo(SkBits2Float(0x403d5556), SkBits2Float(0xc2a5e7ed), SkBits2Float(0x407ba65a), SkBits2Float(0xc2a5d338), SkBits2Float(0x409cf3fe), SkBits2Float(0xc2a5b5bc));
+path.lineTo(SkBits2Float(0x4062eb8a), SkBits2Float(0xc26f94a1));
+path.cubicTo(SkBits2Float(0x4035ea63), SkBits2Float(0xc26fbf44), SkBits2Float(0x4008de16), SkBits2Float(0xc26fdd35), SkBits2Float(0x3fb79810), SkBits2Float(0xc26fee74));
+path.lineTo(SkBits2Float(0x3ffdf8c6), SkBits2Float(0xc2a5f3db));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp5(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3fe06a9b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40606368), SkBits2Float(0xc2a5e38e), SkBits2Float(0x40a82f8a), SkBits2Float(0xc2a5aab6));
+path.lineTo(SkBits2Float(0x40732902), SkBits2Float(0xc26f84b2));
+path.cubicTo(SkBits2Float(0x4022355b), SkBits2Float(0xc26fd6e1), SkBits2Float(0x3fa23a8f), SkBits2Float(0xc2700000), SkBits2Float(0xb5600574), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40a82f91), SkBits2Float(0xc2a5aab7));
+path.cubicTo(SkBits2Float(0x40adc8dc), SkBits2Float(0xc2a5a508), SkBits2Float(0x40b361d8), SkBits2Float(0xc2a59f10), SkBits2Float(0x40b8fa82), SkBits2Float(0xc2a598d0));
+path.lineTo(SkBits2Float(0x4085b825), SkBits2Float(0xc26f6ad0));
+path.cubicTo(SkBits2Float(0x4081ac7b), SkBits2Float(0xc26f73dc), SkBits2Float(0x407b412c), SkBits2Float(0xc26f7c7c), SkBits2Float(0x407328f8), SkBits2Float(0xc26f84b3));
+path.lineTo(SkBits2Float(0x40a82f91), SkBits2Float(0xc2a5aab7));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp6(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3fe06a9b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40606368), SkBits2Float(0xc2a5e38e), SkBits2Float(0x40a82f91), SkBits2Float(0xc2a5aab7));
+path.cubicTo(SkBits2Float(0x40adc8dc), SkBits2Float(0xc2a5a508), SkBits2Float(0x40b361d8), SkBits2Float(0xc2a59f10), SkBits2Float(0x40b8fa82), SkBits2Float(0xc2a598d0));
+path.lineTo(SkBits2Float(0x4085b825), SkBits2Float(0xc26f6ad0));
+path.cubicTo(SkBits2Float(0x4081ac7d), SkBits2Float(0xc26f73dc), SkBits2Float(0x407b4133), SkBits2Float(0xc26f7c7c), SkBits2Float(0x40732902), SkBits2Float(0xc26f84b2));
+path.cubicTo(SkBits2Float(0x4022355b), SkBits2Float(0xc26fd6e1), SkBits2Float(0x3fa23a8f), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+path.moveTo(SkBits2Float(0x408fea52), SkBits2Float(0xc28dc28a));
+path.lineTo(SkBits2Float(0x407328f8), SkBits2Float(0xc26f84b3));
+path.lineTo(SkBits2Float(0x40732903), SkBits2Float(0xc26f84b3));
+path.lineTo(SkBits2Float(0x408fea52), SkBits2Float(0xc28dc28a));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40b8fa77), SkBits2Float(0xc2a598d0));
+path.cubicTo(SkBits2Float(0x4109d7e9), SkBits2Float(0xc2a5337c), SkBits2Float(0x4137014a), SkBits2Float(0xc2a483b2), SkBits2Float(0x4163cbb6), SkBits2Float(0xc2a38a24));
+path.lineTo(SkBits2Float(0x4124abf0), SkBits2Float(0xc26c715c));
+path.cubicTo(SkBits2Float(0x41044af8), SkBits2Float(0xc26dda2b), SkBits2Float(0x40c74ab0), SkBits2Float(0xc26ed852), SkBits2Float(0x4085b82e), SkBits2Float(0xc26f6ad1));
+path.lineTo(SkBits2Float(0x40b8fa77), SkBits2Float(0xc2a598d0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp7(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3de5c884), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e65c882), SkBits2Float(0xc2a5ffe2), SkBits2Float(0x3eac5645), SkBits2Float(0xc2a5ffa7));
+path.lineTo(SkBits2Float(0x3e79297e), SkBits2Float(0xc26fff7f));
+path.cubicTo(SkBits2Float(0x3e261bbd), SkBits2Float(0xc26fffd7), SkBits2Float(0x3da61bbf), SkBits2Float(0xc2700000), SkBits2Float(0xb3244c00), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3eac564d), SkBits2Float(0xc2a5ffa7));
+path.cubicTo(SkBits2Float(0x3eb21458), SkBits2Float(0xc2a5ffa1), SkBits2Float(0x3eb7d2fc), SkBits2Float(0xc2a5ff9b), SkBits2Float(0x3ebd91a0), SkBits2Float(0xc2a5ff94));
+path.lineTo(SkBits2Float(0x3e8909ff), SkBits2Float(0xc26fff64));
+path.cubicTo(SkBits2Float(0x3e84e2cf), SkBits2Float(0xc26fff6d), SkBits2Float(0x3e80bc02), SkBits2Float(0xc26fff76), SkBits2Float(0x3e792a69), SkBits2Float(0xc26fff7f));
+path.lineTo(SkBits2Float(0x3eac564d), SkBits2Float(0xc2a5ffa7));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp8(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3de5c884), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e65c882), SkBits2Float(0xc2a5ffe2), SkBits2Float(0x3eac564d), SkBits2Float(0xc2a5ffa7));
+path.cubicTo(SkBits2Float(0x3eb21458), SkBits2Float(0xc2a5ffa1), SkBits2Float(0x3eb7d2fc), SkBits2Float(0xc2a5ff9b), SkBits2Float(0x3ebd91a0), SkBits2Float(0xc2a5ff94));
+path.lineTo(SkBits2Float(0x3e8909ff), SkBits2Float(0xc26fff64));
+path.lineTo(SkBits2Float(0x3e792a69), SkBits2Float(0xc26fff7f));
+path.cubicTo(SkBits2Float(0x3e261bbd), SkBits2Float(0xc26fffd7), SkBits2Float(0x3da61bbf), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ebd921a), SkBits2Float(0xc2a5ff94));
+path.cubicTo(SkBits2Float(0x3f0d545f), SkBits2Float(0xc2a5ff29), SkBits2Float(0x3f3bdfbd), SkBits2Float(0xc2a5fe71), SkBits2Float(0x3f6a6ab6), SkBits2Float(0xc2a5fd69));
+path.lineTo(SkBits2Float(0x3f297558), SkBits2Float(0xc26ffc43));
+path.cubicTo(SkBits2Float(0x3f07d00d), SkBits2Float(0xc26ffdc0), SkBits2Float(0x3ecc550f), SkBits2Float(0xc26ffecc), SkBits2Float(0x3e8909b7), SkBits2Float(0xc26fff65));
+path.lineTo(SkBits2Float(0x3ebd921a), SkBits2Float(0xc2a5ff94));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp9(skiatest::Reporter* reporter, const char* filename) { // crashes
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ecc43bf), SkBits2Float(0xc2a60000), SkBits2Float(0x3f4c4385), SkBits2Float(0xc2a5fe87), SkBits2Float(0x3f993163), SkBits2Float(0xc2a5fb95));
+path.lineTo(SkBits2Float(0x3f5d7bc4), SkBits2Float(0xc26ff99d));
+path.cubicTo(SkBits2Float(0x3f13a919), SkBits2Float(0xc26ffdde), SkBits2Float(0x3e93a998), SkBits2Float(0xc26fffff), SkBits2Float(0x367b7ed0), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f993156), SkBits2Float(0xc2a5fb95));
+path.cubicTo(SkBits2Float(0x3f9e4c7a), SkBits2Float(0xc2a5fb49), SkBits2Float(0x3fa36794), SkBits2Float(0xc2a5fafa), SkBits2Float(0x3fa882aa), SkBits2Float(0xc2a5faa7));
+path.lineTo(SkBits2Float(0x3f73a149), SkBits2Float(0xc26ff845));
+path.cubicTo(SkBits2Float(0x3f6c3f64), SkBits2Float(0xc26ff8bf), SkBits2Float(0x3f64dd9d), SkBits2Float(0xc26ff931), SkBits2Float(0x3f5d7bcf), SkBits2Float(0xc26ff99f));
+path.lineTo(SkBits2Float(0x3f993156), SkBits2Float(0xc2a5fb95));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp10(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ddcd524), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e5cd462), SkBits2Float(0xc2a5ffe3), SkBits2Float(0x3ea59eff), SkBits2Float(0xc2a5ffac));
+path.lineTo(SkBits2Float(0x3e6f74a3), SkBits2Float(0xc26fff89));
+path.cubicTo(SkBits2Float(0x3e1fa33e), SkBits2Float(0xc26fffd9), SkBits2Float(0x3d9fa303), SkBits2Float(0xc2700000), SkBits2Float(0xb580e440), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ea59f9c), SkBits2Float(0xc2a5ffad));
+path.cubicTo(SkBits2Float(0x3eab24c0), SkBits2Float(0xc2a5ffa7), SkBits2Float(0x3eb0aa54), SkBits2Float(0xc2a5ffa1), SkBits2Float(0x3eb62fe9), SkBits2Float(0xc2a5ff9b));
+path.lineTo(SkBits2Float(0x3e83b355), SkBits2Float(0xc26fff6f));
+path.cubicTo(SkBits2Float(0x3e7f6bdb), SkBits2Float(0xc26fff79), SkBits2Float(0x3e777021), SkBits2Float(0xc26fff81), SkBits2Float(0x3e6f7465), SkBits2Float(0xc26fff8a));
+path.lineTo(SkBits2Float(0x3ea59f9c), SkBits2Float(0xc2a5ffad));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp11(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ddcd524), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e5cd462), SkBits2Float(0xc2a5ffe3), SkBits2Float(0x3ea59f9c), SkBits2Float(0xc2a5ffad));
+path.lineTo(SkBits2Float(0x3eb62fe9), SkBits2Float(0xc2a5ff9b));
+path.lineTo(SkBits2Float(0x3e83b355), SkBits2Float(0xc26fff6f));
+path.cubicTo(SkBits2Float(0x3e7f6bf0), SkBits2Float(0xc26fff79), SkBits2Float(0x3e77704b), SkBits2Float(0xc26fff81), SkBits2Float(0x3e6f74a3), SkBits2Float(0xc26fff89));
+path.cubicTo(SkBits2Float(0x3e1fa33e), SkBits2Float(0xc26fffd9), SkBits2Float(0x3d9fa303), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+path.moveTo(SkBits2Float(0x3e7ee007), SkBits2Float(0xc27f7413));
+path.lineTo(SkBits2Float(0x3e6f7465), SkBits2Float(0xc26fff8a));
+path.lineTo(SkBits2Float(0x3e6f74a4), SkBits2Float(0xc26fff8a));
+path.lineTo(SkBits2Float(0x3e7ee007), SkBits2Float(0xc27f7413));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3eb62f8c), SkBits2Float(0xc2a5ff9c));
+path.cubicTo(SkBits2Float(0x3f07d31d), SkBits2Float(0xc2a5ff3a), SkBits2Float(0x3f348e3e), SkBits2Float(0xc2a5fe8f), SkBits2Float(0x3f614904), SkBits2Float(0xc2a5fd9c));
+path.lineTo(SkBits2Float(0x3f22db6c), SkBits2Float(0xc26ffc8c));
+path.cubicTo(SkBits2Float(0x3f0285bf), SkBits2Float(0xc26ffdeb), SkBits2Float(0x3ec45fa5), SkBits2Float(0xc26ffee1), SkBits2Float(0x3e83b387), SkBits2Float(0xc26fff6f));
+path.lineTo(SkBits2Float(0x3eb62f8c), SkBits2Float(0xc2a5ff9c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp12(skiatest::Reporter* reporter, const char* filename) {  // crashed
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ecc43bf), SkBits2Float(0xc2a60000), SkBits2Float(0x3f4c4385), SkBits2Float(0xc2a5fe87), SkBits2Float(0x3f993163), SkBits2Float(0xc2a5fb95));
+path.lineTo(SkBits2Float(0x3f5d7bc4), SkBits2Float(0xc26ff99d));
+path.cubicTo(SkBits2Float(0x3f13a919), SkBits2Float(0xc26ffdde), SkBits2Float(0x3e93a998), SkBits2Float(0xc26fffff), SkBits2Float(0x367b7ed0), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f993156), SkBits2Float(0xc2a5fb95));
+path.cubicTo(SkBits2Float(0x3f9e4c7a), SkBits2Float(0xc2a5fb49), SkBits2Float(0x3fa36794), SkBits2Float(0xc2a5fafa), SkBits2Float(0x3fa882aa), SkBits2Float(0xc2a5faa7));
+path.lineTo(SkBits2Float(0x3f73a149), SkBits2Float(0xc26ff845));
+path.cubicTo(SkBits2Float(0x3f6c3f64), SkBits2Float(0xc26ff8bf), SkBits2Float(0x3f64dd9d), SkBits2Float(0xc26ff931), SkBits2Float(0x3f5d7bcf), SkBits2Float(0xc26ff99f));
+path.lineTo(SkBits2Float(0x3f993156), SkBits2Float(0xc2a5fb95));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// ../../third_party/tcmalloc/chromium/src/free_list.h:118] Memory corruption detected. 
+
+static void battleOp13(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ddcd524), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e5cd462), SkBits2Float(0xc2a5ffe3), SkBits2Float(0x3ea59eff), SkBits2Float(0xc2a5ffac));
+path.lineTo(SkBits2Float(0x3e6f74a3), SkBits2Float(0xc26fff89));
+path.cubicTo(SkBits2Float(0x3e1fa33e), SkBits2Float(0xc26fffd9), SkBits2Float(0x3d9fa303), SkBits2Float(0xc2700000), SkBits2Float(0xb580e440), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ea59f9c), SkBits2Float(0xc2a5ffad));
+path.cubicTo(SkBits2Float(0x3eab24c0), SkBits2Float(0xc2a5ffa7), SkBits2Float(0x3eb0aa54), SkBits2Float(0xc2a5ffa1), SkBits2Float(0x3eb62fe9), SkBits2Float(0xc2a5ff9b));
+path.lineTo(SkBits2Float(0x3e83b355), SkBits2Float(0xc26fff6f));
+path.cubicTo(SkBits2Float(0x3e7f6bdb), SkBits2Float(0xc26fff79), SkBits2Float(0x3e777021), SkBits2Float(0xc26fff81), SkBits2Float(0x3e6f7465), SkBits2Float(0xc26fff8a));
+path.lineTo(SkBits2Float(0x3ea59f9c), SkBits2Float(0xc2a5ffad));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp14(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ddcd524), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e5cd462), SkBits2Float(0xc2a5ffe3), SkBits2Float(0x3ea59f9c), SkBits2Float(0xc2a5ffad));
+path.lineTo(SkBits2Float(0x3eb62fe9), SkBits2Float(0xc2a5ff9b));
+path.lineTo(SkBits2Float(0x3e83b355), SkBits2Float(0xc26fff6f));
+path.cubicTo(SkBits2Float(0x3e7f6bf0), SkBits2Float(0xc26fff79), SkBits2Float(0x3e77704b), SkBits2Float(0xc26fff81), SkBits2Float(0x3e6f74a3), SkBits2Float(0xc26fff89));
+path.cubicTo(SkBits2Float(0x3e1fa33e), SkBits2Float(0xc26fffd9), SkBits2Float(0x3d9fa303), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+path.moveTo(SkBits2Float(0x3e7ee007), SkBits2Float(0xc27f7413));
+path.lineTo(SkBits2Float(0x3e6f7465), SkBits2Float(0xc26fff8a));
+path.lineTo(SkBits2Float(0x3e6f74a4), SkBits2Float(0xc26fff8a));
+path.lineTo(SkBits2Float(0x3e7ee007), SkBits2Float(0xc27f7413));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3eb62f8c), SkBits2Float(0xc2a5ff9c));
+path.cubicTo(SkBits2Float(0x3f07d31d), SkBits2Float(0xc2a5ff3a), SkBits2Float(0x3f348e3e), SkBits2Float(0xc2a5fe8f), SkBits2Float(0x3f614904), SkBits2Float(0xc2a5fd9c));
+path.lineTo(SkBits2Float(0x3f22db6c), SkBits2Float(0xc26ffc8c));
+path.cubicTo(SkBits2Float(0x3f0285bf), SkBits2Float(0xc26ffdeb), SkBits2Float(0x3ec45fa5), SkBits2Float(0xc26ffee1), SkBits2Float(0x3e83b387), SkBits2Float(0xc26fff6f));
+path.lineTo(SkBits2Float(0x3eb62f8c), SkBits2Float(0xc2a5ff9c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp15(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f19f03c), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f99ef95), SkBits2Float(0xc2a5fca7), SkBits2Float(0x3fe6e2fa), SkBits2Float(0xc2a5f5f7));
+path.lineTo(SkBits2Float(0x3fa6e80c), SkBits2Float(0xc26ff17d));
+path.cubicTo(SkBits2Float(0x3f5e8ed4), SkBits2Float(0xc26ffb2a), SkBits2Float(0x3ede8fc6), SkBits2Float(0xc2700000), SkBits2Float(0x35d9fd64), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fe6e322), SkBits2Float(0xc2a5f5f7));
+path.cubicTo(SkBits2Float(0x3fee94fb), SkBits2Float(0xc2a5f54c), SkBits2Float(0x3ff646db), SkBits2Float(0xc2a5f497), SkBits2Float(0x3ffdf8ad), SkBits2Float(0xc2a5f3db));
+path.lineTo(SkBits2Float(0x3fb79813), SkBits2Float(0xc26fee71));
+path.cubicTo(SkBits2Float(0x3fb20800), SkBits2Float(0xc26fef82), SkBits2Float(0x3fac77ff), SkBits2Float(0xc26ff085), SkBits2Float(0x3fa6e7f4), SkBits2Float(0xc26ff17d));
+path.lineTo(SkBits2Float(0x3fe6e322), SkBits2Float(0xc2a5f5f7));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp16(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f19f03c), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f99ef95), SkBits2Float(0xc2a5fca7), SkBits2Float(0x3fe6e322), SkBits2Float(0xc2a5f5f7));
+path.cubicTo(SkBits2Float(0x3fee94fb), SkBits2Float(0xc2a5f54c), SkBits2Float(0x3ff646db), SkBits2Float(0xc2a5f497), SkBits2Float(0x3ffdf8ad), SkBits2Float(0xc2a5f3db));
+path.lineTo(SkBits2Float(0x3fb79813), SkBits2Float(0xc26fee71));
+path.cubicTo(SkBits2Float(0x3fb20808), SkBits2Float(0xc26fef82), SkBits2Float(0x3fac780f), SkBits2Float(0xc26ff085), SkBits2Float(0x3fa6e80c), SkBits2Float(0xc26ff17d));
+path.lineTo(SkBits2Float(0x3fa6e7f4), SkBits2Float(0xc26ff17d));
+path.cubicTo(SkBits2Float(0x3f5e8eb4), SkBits2Float(0xc26ffb2a), SkBits2Float(0x3ede8fa6), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ffdf8c6), SkBits2Float(0xc2a5f3db));
+path.cubicTo(SkBits2Float(0x403d5556), SkBits2Float(0xc2a5e7ed), SkBits2Float(0x407ba65a), SkBits2Float(0xc2a5d338), SkBits2Float(0x409cf3fe), SkBits2Float(0xc2a5b5bc));
+path.lineTo(SkBits2Float(0x4062eb8a), SkBits2Float(0xc26f94a1));
+path.cubicTo(SkBits2Float(0x4035ea63), SkBits2Float(0xc26fbf44), SkBits2Float(0x4008de16), SkBits2Float(0xc26fdd35), SkBits2Float(0x3fb79810), SkBits2Float(0xc26fee74));
+path.lineTo(SkBits2Float(0x3ffdf8c6), SkBits2Float(0xc2a5f3db));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp17(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f9860dc), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40185ea2), SkBits2Float(0xc2a5f2e2), SkBits2Float(0x40647d09), SkBits2Float(0xc2a5d8aa));
+path.lineTo(SkBits2Float(0x40252c2a), SkBits2Float(0xc26fc723));
+path.cubicTo(SkBits2Float(0x3fdc4b47), SkBits2Float(0xc26fed09), SkBits2Float(0x3f5c4ea6), SkBits2Float(0xc26ffffe), SkBits2Float(0x3664fea3), SkBits2Float(0xc26ffffe));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40647d17), SkBits2Float(0xc2a5d8ab));
+path.cubicTo(SkBits2Float(0x406c19ae), SkBits2Float(0xc2a5d60b), SkBits2Float(0x4073b608), SkBits2Float(0xc2a5d34a), SkBits2Float(0x407b5230), SkBits2Float(0xc2a5d069));
+path.lineTo(SkBits2Float(0x4035ad90), SkBits2Float(0xc26fbb32));
+path.cubicTo(SkBits2Float(0x40302d3b), SkBits2Float(0xc26fbf5d), SkBits2Float(0x402aacbf), SkBits2Float(0xc26fc358), SkBits2Float(0x40252c21), SkBits2Float(0xc26fc722));
+path.lineTo(SkBits2Float(0x40647d17), SkBits2Float(0xc2a5d8ab));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp18(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3664fea3), SkBits2Float(0xc26ffffe));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f9860dc), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40185ea2), SkBits2Float(0xc2a5f2e2), SkBits2Float(0x40647d17), SkBits2Float(0xc2a5d8ab));
+path.cubicTo(SkBits2Float(0x406c19ae), SkBits2Float(0xc2a5d60b), SkBits2Float(0x4073b608), SkBits2Float(0xc2a5d34a), SkBits2Float(0x407b5230), SkBits2Float(0xc2a5d069));
+path.lineTo(SkBits2Float(0x4035ad90), SkBits2Float(0xc26fbb32));
+path.cubicTo(SkBits2Float(0x40302d3b), SkBits2Float(0xc26fbf5d), SkBits2Float(0x402aacbf), SkBits2Float(0xc26fc358), SkBits2Float(0x40252c2a), SkBits2Float(0xc26fc723));
+path.cubicTo(SkBits2Float(0x3fdc4b47), SkBits2Float(0xc26fed09), SkBits2Float(0x3f5c4ea6), SkBits2Float(0xc26ffffe), SkBits2Float(0x3664fea3), SkBits2Float(0xc26ffffe));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x407b523a), SkBits2Float(0xc2a5d069));
+path.cubicTo(SkBits2Float(0x40bb53e8), SkBits2Float(0xc2a5a1ad), SkBits2Float(0x40f8dfd1), SkBits2Float(0xc2a5508e), SkBits2Float(0x411b1813), SkBits2Float(0xc2a4dd32));
+path.lineTo(SkBits2Float(0x40e03b7c), SkBits2Float(0xc26e5b8f));
+path.cubicTo(SkBits2Float(0x40b3e8bb), SkBits2Float(0xc26f0259), SkBits2Float(0x40876aeb), SkBits2Float(0xc26f77a1), SkBits2Float(0x4035ad92), SkBits2Float(0xc26fbb33));
+path.lineTo(SkBits2Float(0x407b523a), SkBits2Float(0xc2a5d069));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp19(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40272e66), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40a7227d), SkBits2Float(0xc2a5c0db), SkBits2Float(0x40fa5a70), SkBits2Float(0xc2a542ca));
+path.lineTo(SkBits2Float(0x40b4fa6e), SkBits2Float(0xc26eee73));
+path.cubicTo(SkBits2Float(0x4071a3f5), SkBits2Float(0xc26fa4b8), SkBits2Float(0x3ff1b53c), SkBits2Float(0xc2700000), SkBits2Float(0x359dfd46), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40fa5a6d), SkBits2Float(0xc2a542cb));
+path.cubicTo(SkBits2Float(0x4101563b), SkBits2Float(0xc2a5362f), SkBits2Float(0x41057ec0), SkBits2Float(0xc2a528f4), SkBits2Float(0x4109a6c0), SkBits2Float(0xc2a51b18));
+path.lineTo(SkBits2Float(0x40c70391), SkBits2Float(0xc26eb50e));
+path.cubicTo(SkBits2Float(0x40c10142), SkBits2Float(0xc26ec918), SkBits2Float(0x40bafe32), SkBits2Float(0xc26edc3a), SkBits2Float(0x40b4fa70), SkBits2Float(0xc26eee73));
+path.lineTo(SkBits2Float(0x40fa5a6d), SkBits2Float(0xc2a542cb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp20(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40272e63), SkBits2Float(0xc2a60000), SkBits2Float(0x40a7227a), SkBits2Float(0xc2a5c0db), SkBits2Float(0x40fa5a6c), SkBits2Float(0xc2a542ca));
+path.lineTo(SkBits2Float(0x40fa5a6d), SkBits2Float(0xc2a542cb));
+path.cubicTo(SkBits2Float(0x4101563b), SkBits2Float(0xc2a5362f), SkBits2Float(0x41057ec0), SkBits2Float(0xc2a528f4), SkBits2Float(0x4109a6c0), SkBits2Float(0xc2a51b18));
+path.lineTo(SkBits2Float(0x40c70391), SkBits2Float(0xc26eb50e));
+path.cubicTo(SkBits2Float(0x40c10142), SkBits2Float(0xc26ec918), SkBits2Float(0x40bafe32), SkBits2Float(0xc26edc3a), SkBits2Float(0x40b4fa6e), SkBits2Float(0xc26eee73));
+path.cubicTo(SkBits2Float(0x4071a3f5), SkBits2Float(0xc26fa4b8), SkBits2Float(0x3ff1b53c), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4109a6bc), SkBits2Float(0xc2a51b19));
+path.cubicTo(SkBits2Float(0x414d093d), SkBits2Float(0xc2a43a61), SkBits2Float(0x4187e474), SkBits2Float(0xc2a2b4fa), SkBits2Float(0x41a8a805), SkBits2Float(0xc2a08e4d));
+path.lineTo(SkBits2Float(0x4173d72c), SkBits2Float(0xc2682105));
+path.cubicTo(SkBits2Float(0x41447890), SkBits2Float(0xc26b3d2d), SkBits2Float(0x4114380c), SkBits2Float(0xc26d702b), SkBits2Float(0x40c70392), SkBits2Float(0xc26eb510));
+path.lineTo(SkBits2Float(0x4109a6bc), SkBits2Float(0xc2a51b19));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp21(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x404ef9c5), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40cee321), SkBits2Float(0xc2a59f3a), SkBits2Float(0x411ad5ab), SkBits2Float(0xc2a4de2c));
+path.lineTo(SkBits2Float(0x40dfdb77), SkBits2Float(0xc26e5cf8));
+path.cubicTo(SkBits2Float(0x40958e99), SkBits2Float(0xc26f7414), SkBits2Float(0x40159f04), SkBits2Float(0xc26ffffe), SkBits2Float(0x36ae7f52), SkBits2Float(0xc26ffffe));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x411ad5aa), SkBits2Float(0xc2a4de2c));
+path.cubicTo(SkBits2Float(0x411ff8ea), SkBits2Float(0xc2a4cadf), SkBits2Float(0x41251b3e), SkBits2Float(0xc2a4b69c), SkBits2Float(0x412a3c98), SkBits2Float(0xc2a4a163));
+path.lineTo(SkBits2Float(0x40f6200f), SkBits2Float(0xc26e0518));
+path.cubicTo(SkBits2Float(0x40eeb53e), SkBits2Float(0xc26e23c6), SkBits2Float(0x40e74902), SkBits2Float(0xc26e4112), SkBits2Float(0x40dfdb73), SkBits2Float(0xc26e5cf8));
+path.lineTo(SkBits2Float(0x411ad5aa), SkBits2Float(0xc2a4de2c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end fail 1
+
+static void battleOp22(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x407fb41a), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40ff895b), SkBits2Float(0xc2a56c4b), SkBits2Float(0x413f077c), SkBits2Float(0xc2a44609));
+path.lineTo(SkBits2Float(0x410a17ee), SkBits2Float(0xc26d8104));
+path.cubicTo(SkBits2Float(0x40b8b9ab), SkBits2Float(0xc26f2a74), SkBits2Float(0x4038d88b), SkBits2Float(0xc2700000), SkBits2Float(0x337fa8c0), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x413f0780), SkBits2Float(0xc2a44609));
+path.cubicTo(SkBits2Float(0x41455a4a), SkBits2Float(0xc2a4289f), SkBits2Float(0x414bab5a), SkBits2Float(0xc2a409bf), SkBits2Float(0x4151fa92), SkBits2Float(0xc2a3e96b));
+path.lineTo(SkBits2Float(0x4117cabb), SkBits2Float(0xc26cfb1d));
+path.cubicTo(SkBits2Float(0x41133b1d), SkBits2Float(0xc26d29dc), SkBits2Float(0x410eaa27), SkBits2Float(0xc26d567f), SkBits2Float(0x410a17f1), SkBits2Float(0xc26d8105));
+path.lineTo(SkBits2Float(0x413f0780), SkBits2Float(0xc2a44609));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp23(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x407fb41a), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40ff895b), SkBits2Float(0xc2a56c4b), SkBits2Float(0x413f0780), SkBits2Float(0xc2a44609));
+path.cubicTo(SkBits2Float(0x41455a4a), SkBits2Float(0xc2a4289f), SkBits2Float(0x414bab5a), SkBits2Float(0xc2a409bf), SkBits2Float(0x4151fa92), SkBits2Float(0xc2a3e96b));
+path.lineTo(SkBits2Float(0x4117cabb), SkBits2Float(0xc26cfb1d));
+path.cubicTo(SkBits2Float(0x41133b1d), SkBits2Float(0xc26d29dc), SkBits2Float(0x410eaa27), SkBits2Float(0xc26d567f), SkBits2Float(0x410a17ee), SkBits2Float(0xc26d8104));
+path.cubicTo(SkBits2Float(0x40b8b9ab), SkBits2Float(0xc26f2a74), SkBits2Float(0x4038d88b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4151fa93), SkBits2Float(0xc2a3e96b));
+path.cubicTo(SkBits2Float(0x419c2b7d), SkBits2Float(0xc2a1dce5), SkBits2Float(0x41ce36f8), SkBits2Float(0xc29e52a6), SkBits2Float(0x41fe1a0a), SkBits2Float(0xc2995d2e));
+path.lineTo(SkBits2Float(0x41b7b024), SkBits2Float(0xc25dbb29));
+path.cubicTo(SkBits2Float(0x41951228), SkBits2Float(0xc264e68b), SkBits2Float(0x4161c9b2), SkBits2Float(0xc26a04c8), SkBits2Float(0x4117cabf), SkBits2Float(0xc26cfb1e));
+path.lineTo(SkBits2Float(0x4151fa93), SkBits2Float(0xc2a3e96b));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp24(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x409bc7b0), SkBits2Float(0xc2a5ffff), SkBits2Float(0x411ba103), SkBits2Float(0xc2a524b6), SkBits2Float(0x4168515c), SkBits2Float(0xc2a370af));
+path.lineTo(SkBits2Float(0x4127f0cc), SkBits2Float(0xc26c4c8f));
+path.cubicTo(SkBits2Float(0x40e1017a), SkBits2Float(0xc26ec2f6), SkBits2Float(0x40613965), SkBits2Float(0xc26fffff), SkBits2Float(0x3655fea5), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4168515e), SkBits2Float(0xc2a370b0));
+path.cubicTo(SkBits2Float(0x416ffb5b), SkBits2Float(0xc2a3451c), SkBits2Float(0x4177a23d), SkBits2Float(0xc2a31761), SkBits2Float(0x417f45ca), SkBits2Float(0xc2a2e77f));
+path.lineTo(SkBits2Float(0x413888ce), SkBits2Float(0xc26b8638));
+path.cubicTo(SkBits2Float(0x41330328), SkBits2Float(0xc26bcb72), SkBits2Float(0x412d7b1a), SkBits2Float(0xc26c0d90), SkBits2Float(0x4127f0cb), SkBits2Float(0xc26c4c90));
+path.lineTo(SkBits2Float(0x4168515e), SkBits2Float(0xc2a370b0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp25(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3655fea5), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x409bc7b0), SkBits2Float(0xc2a5ffff), SkBits2Float(0x411ba103), SkBits2Float(0xc2a524b6), SkBits2Float(0x4168515e), SkBits2Float(0xc2a370b0));
+path.cubicTo(SkBits2Float(0x416ffb5b), SkBits2Float(0xc2a3451c), SkBits2Float(0x4177a23d), SkBits2Float(0xc2a31761), SkBits2Float(0x417f45ca), SkBits2Float(0xc2a2e77f));
+path.lineTo(SkBits2Float(0x413888ce), SkBits2Float(0xc26b8638));
+path.cubicTo(SkBits2Float(0x41330328), SkBits2Float(0xc26bcb72), SkBits2Float(0x412d7b1a), SkBits2Float(0xc26c0d90), SkBits2Float(0x4127f0cc), SkBits2Float(0xc26c4c8f));
+path.cubicTo(SkBits2Float(0x40e1017a), SkBits2Float(0xc26ec2f6), SkBits2Float(0x40613965), SkBits2Float(0xc26fffff), SkBits2Float(0x3655fea5), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x417f45c8), SkBits2Float(0xc2a2e780));
+path.cubicTo(SkBits2Float(0x41bda27d), SkBits2Float(0xc29fde49), SkBits2Float(0x41f99531), SkBits2Float(0xc29aa2c4), SkBits2Float(0x4218d569), SkBits2Float(0xc2935d77));
+path.lineTo(SkBits2Float(0x41dcf6db), SkBits2Float(0xc2550ed7));
+path.cubicTo(SkBits2Float(0x41b46bda), SkBits2Float(0xc25f91e2), SkBits2Float(0x418915db), SkBits2Float(0xc2672288), SkBits2Float(0x413888d2), SkBits2Float(0xc26b8639));
+path.lineTo(SkBits2Float(0x417f45c8), SkBits2Float(0xc2a2e780));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp26(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40b98c15), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41394aaf), SkBits2Float(0xc2a4c8e8), SkBits2Float(0x418a04fa), SkBits2Float(0xc2a25fd2));
+path.lineTo(SkBits2Float(0x41478bd6), SkBits2Float(0xc26ac20e));
+path.cubicTo(SkBits2Float(0x4105f224), SkBits2Float(0xc26e3e3c), SkBits2Float(0x40862167), SkBits2Float(0xc2700000), SkBits2Float(0xb4d00ae8), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x418a04fd), SkBits2Float(0xc2a25fd2));
+path.cubicTo(SkBits2Float(0x418e8d81), SkBits2Float(0xc2a2222a), SkBits2Float(0x41931368), SkBits2Float(0xc2a1e17a), SkBits2Float(0x41979681), SkBits2Float(0xc2a19dc3));
+path.lineTo(SkBits2Float(0x415b29c8), SkBits2Float(0xc269a97e));
+path.cubicTo(SkBits2Float(0x4154a3c3), SkBits2Float(0xc26a0b66), SkBits2Float(0x414e19b0), SkBits2Float(0xc26a68ed), SkBits2Float(0x41478bd5), SkBits2Float(0xc26ac20f));
+path.lineTo(SkBits2Float(0x418a04fd), SkBits2Float(0xc2a25fd2));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp27(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40b98c15), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41394aaf), SkBits2Float(0xc2a4c8e8), SkBits2Float(0x418a04fd), SkBits2Float(0xc2a25fd2));
+path.cubicTo(SkBits2Float(0x418e8d81), SkBits2Float(0xc2a2222a), SkBits2Float(0x41931368), SkBits2Float(0xc2a1e17a), SkBits2Float(0x41979681), SkBits2Float(0xc2a19dc3));
+path.lineTo(SkBits2Float(0x415b29c8), SkBits2Float(0xc269a97e));
+path.cubicTo(SkBits2Float(0x4154a3c3), SkBits2Float(0xc26a0b66), SkBits2Float(0x414e19b0), SkBits2Float(0xc26a68ed), SkBits2Float(0x41478bd6), SkBits2Float(0xc26ac20e));
+path.cubicTo(SkBits2Float(0x4105f224), SkBits2Float(0xc26e3e3c), SkBits2Float(0x40862167), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41979680), SkBits2Float(0xc2a19dc4));
+path.cubicTo(SkBits2Float(0x41e0e1b2), SkBits2Float(0xc29d51d4), SkBits2Float(0x42135c08), SkBits2Float(0xc295f036), SkBits2Float(0x42330e86), SkBits2Float(0xc28bc9b7));
+path.lineTo(SkBits2Float(0x42017048), SkBits2Float(0xc24a1a63));
+path.cubicTo(SkBits2Float(0x41d50cc4), SkBits2Float(0xc258c742), SkBits2Float(0x41a290a5), SkBits2Float(0xc263733c), SkBits2Float(0x415b29c7), SkBits2Float(0xc269a980));
+path.lineTo(SkBits2Float(0x41979680), SkBits2Float(0xc2a19dc4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp28(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40dd1e63), SkBits2Float(0xc2a5ffff), SkBits2Float(0x415caf98), SkBits2Float(0xc2a44632), SkBits2Float(0x41a3e96c), SkBits2Float(0xc2a0dcda));
+path.lineTo(SkBits2Float(0x416cfb1c), SkBits2Float(0xc2689294));
+path.cubicTo(SkBits2Float(0x411f8831), SkBits2Float(0xc26d8140), SkBits2Float(0x409fd849), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41a3e96b), SkBits2Float(0xc2a0dcda));
+path.cubicTo(SkBits2Float(0x41a94306), SkBits2Float(0xc2a085a1), SkBits2Float(0x41ae9839), SkBits2Float(0xc2a02a23), SkBits2Float(0x41b3e8b2), SkBits2Float(0xc29fca67));
+path.lineTo(SkBits2Float(0x41820dff), SkBits2Float(0xc26705ca));
+path.cubicTo(SkBits2Float(0x417c6d0a), SkBits2Float(0xc2679035), SkBits2Float(0x4174b742), SkBits2Float(0xc268147b), SkBits2Float(0x416cfb1d), SkBits2Float(0xc2689296));
+path.lineTo(SkBits2Float(0x41a3e96b), SkBits2Float(0xc2a0dcda));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp29(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40dd1e62), SkBits2Float(0xc2a60000), SkBits2Float(0x415caf97), SkBits2Float(0xc2a44632), SkBits2Float(0x41a3e96b), SkBits2Float(0xc2a0dcda));
+path.lineTo(SkBits2Float(0x416cfb1d), SkBits2Float(0xc2689296));
+path.cubicTo(SkBits2Float(0x4174b742), SkBits2Float(0xc268147b), SkBits2Float(0x417c6d0a), SkBits2Float(0xc2679035), SkBits2Float(0x41820dff), SkBits2Float(0xc26705ca));
+path.lineTo(SkBits2Float(0x41b3e8b2), SkBits2Float(0xc29fca67));
+path.cubicTo(SkBits2Float(0x41ae9839), SkBits2Float(0xc2a02a23), SkBits2Float(0x41a94307), SkBits2Float(0xc2a085a1), SkBits2Float(0x41a3e96c), SkBits2Float(0xc2a0dcda));
+path.lineTo(SkBits2Float(0x416cfb1c), SkBits2Float(0xc2689294));
+path.cubicTo(SkBits2Float(0x411f8831), SkBits2Float(0xc26d8140), SkBits2Float(0x409fd849), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41b3e8b1), SkBits2Float(0xc29fca67));
+path.cubicTo(SkBits2Float(0x4205291f), SkBits2Float(0xc299b5bb), SkBits2Float(0x422d73c0), SkBits2Float(0xc28f4fcf), SkBits2Float(0x425064bf), SkBits2Float(0xc2813989));
+path.lineTo(SkBits2Float(0x4216a55b), SkBits2Float(0xc23ad4b9));
+path.cubicTo(SkBits2Float(0x41fac62f), SkBits2Float(0xc24f329e), SkBits2Float(0x41c0857c), SkBits2Float(0xc25e3b2e), SkBits2Float(0x41820dfe), SkBits2Float(0xc26705cb));
+path.lineTo(SkBits2Float(0x41b3e8b1), SkBits2Float(0xc29fca67));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp30(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41028186), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4182264a), SkBits2Float(0xc2a39869), SkBits2Float(0x41c098e8), SkBits2Float(0xc29edd15));
+path.lineTo(SkBits2Float(0x418b3a1a), SkBits2Float(0xc265aeac));
+path.cubicTo(SkBits2Float(0x413c2b06), SkBits2Float(0xc26c85fe), SkBits2Float(0x40bcaeed), SkBits2Float(0xc2700000), SkBits2Float(0x337fa8c0), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41c098e9), SkBits2Float(0xc29edd15));
+path.cubicTo(SkBits2Float(0x41c6d4b6), SkBits2Float(0xc29e642a), SkBits2Float(0x41cd0950), SkBits2Float(0xc29de562), SkBits2Float(0x41d33633), SkBits2Float(0xc29d60c8));
+path.lineTo(SkBits2Float(0x4198aee4), SkBits2Float(0xc26388d7));
+path.cubicTo(SkBits2Float(0x41943815), SkBits2Float(0xc264488f), SkBits2Float(0x418fbbb2), SkBits2Float(0xc264ffdc), SkBits2Float(0x418b3a19), SkBits2Float(0xc265aeae));
+path.lineTo(SkBits2Float(0x41c098e9), SkBits2Float(0xc29edd15));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp31(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41028186), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4182264a), SkBits2Float(0xc2a39869), SkBits2Float(0x41c098e9), SkBits2Float(0xc29edd15));
+path.cubicTo(SkBits2Float(0x41c6d4b6), SkBits2Float(0xc29e642a), SkBits2Float(0x41cd0950), SkBits2Float(0xc29de562), SkBits2Float(0x41d33633), SkBits2Float(0xc29d60c8));
+path.lineTo(SkBits2Float(0x4198aee4), SkBits2Float(0xc26388d7));
+path.cubicTo(SkBits2Float(0x41943816), SkBits2Float(0xc264488f), SkBits2Float(0x418fbbb2), SkBits2Float(0xc264ffda), SkBits2Float(0x418b3a1a), SkBits2Float(0xc265aeac));
+path.cubicTo(SkBits2Float(0x413c2b06), SkBits2Float(0xc26c85fe), SkBits2Float(0x40bcaeed), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41d33633), SkBits2Float(0xc29d60c8));
+path.cubicTo(SkBits2Float(0x421be102), SkBits2Float(0xc294f1be), SkBits2Float(0x4249615f), SkBits2Float(0xc2869cbc), SkBits2Float(0x426e4d45), SkBits2Float(0xc26729aa));
+path.lineTo(SkBits2Float(0x422c4432), SkBits2Float(0xc2271b0a));
+path.cubicTo(SkBits2Float(0x42119380), SkBits2Float(0xc2429ec2), SkBits2Float(0x41e15dfd), SkBits2Float(0xc257575a), SkBits2Float(0x4198aee4), SkBits2Float(0xc26388d8));
+path.lineTo(SkBits2Float(0x41d33633), SkBits2Float(0xc29d60c8));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp32(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4118c001), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41982d6e), SkBits2Float(0xc2a2b4b2), SkBits2Float(0x41e01284), SkBits2Float(0xc29c4333));
+path.lineTo(SkBits2Float(0x41a1fae3), SkBits2Float(0xc261ebf5));
+path.cubicTo(SkBits2Float(0x415c0406), SkBits2Float(0xc26b3cc7), SkBits2Float(0x40dcd7ee), SkBits2Float(0xc2700000), SkBits2Float(0x35f7fd46), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41e01286), SkBits2Float(0xc29c4334));
+path.cubicTo(SkBits2Float(0x41e73e86), SkBits2Float(0xc29b9ea8), SkBits2Float(0x41ee5f11), SkBits2Float(0xc29af239), SkBits2Float(0x41f57356), SkBits2Float(0xc29a3dfa));
+path.lineTo(SkBits2Float(0x41b16f25), SkBits2Float(0xc25f0029));
+path.cubicTo(SkBits2Float(0x41ac5112), SkBits2Float(0xc26004c3), SkBits2Float(0x41a72a20), SkBits2Float(0xc260fe11), SkBits2Float(0x41a1fae3), SkBits2Float(0xc261ebf7));
+path.lineTo(SkBits2Float(0x41e01286), SkBits2Float(0xc29c4334));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp33(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4118c001), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41982d6e), SkBits2Float(0xc2a2b4b2), SkBits2Float(0x41e01286), SkBits2Float(0xc29c4334));
+path.cubicTo(SkBits2Float(0x41e73e86), SkBits2Float(0xc29b9ea8), SkBits2Float(0x41ee5f11), SkBits2Float(0xc29af239), SkBits2Float(0x41f57356), SkBits2Float(0xc29a3dfa));
+path.lineTo(SkBits2Float(0x41b16f25), SkBits2Float(0xc25f0029));
+path.cubicTo(SkBits2Float(0x41ac5112), SkBits2Float(0xc26004c3), SkBits2Float(0x41a72a20), SkBits2Float(0xc260fe11), SkBits2Float(0x41a1fae3), SkBits2Float(0xc261ebf7));
+path.lineTo(SkBits2Float(0x41a1fae3), SkBits2Float(0xc261ebf5));
+path.cubicTo(SkBits2Float(0x415c0406), SkBits2Float(0xc26b3cc7), SkBits2Float(0x40dcd7ee), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41f57359), SkBits2Float(0xc29a3dfa));
+path.cubicTo(SkBits2Float(0x42347528), SkBits2Float(0xc28ec218), SkBits2Float(0x42669614), SkBits2Float(0xc276cf04), SkBits2Float(0x4285b481), SkBits2Float(0xc244c364));
+path.lineTo(SkBits2Float(0x42414f00), SkBits2Float(0xc20e3d0e));
+path.cubicTo(SkBits2Float(0x4226b05a), SkBits2Float(0xc2326a79), SkBits2Float(0x4202738a), SkBits2Float(0xc24e65b9), SkBits2Float(0x41b16f25), SkBits2Float(0xc25f0028));
+path.lineTo(SkBits2Float(0x41f57359), SkBits2Float(0xc29a3dfa));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp34(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41360dec), SkBits2Float(0xc2a60000), SkBits2Float(0x41b5150e), SkBits2Float(0xc2a1522b), SkBits2Float(0x42044925), SkBits2Float(0xc29840e5));
+path.lineTo(SkBits2Float(0x41bf41a8), SkBits2Float(0xc25c2022));
+path.cubicTo(SkBits2Float(0x4182e721), SkBits2Float(0xc2693c30), SkBits2Float(0x41039b08), SkBits2Float(0xc2700000), SkBits2Float(0x3673fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42044925), SkBits2Float(0xc29840e4));
+path.cubicTo(SkBits2Float(0x4208721a), SkBits2Float(0xc2975992), SkBits2Float(0x420c9178), SkBits2Float(0xc296675c), SkBits2Float(0x4210a695), SkBits2Float(0xc2956a6a));
+path.lineTo(SkBits2Float(0x41d1222e), SkBits2Float(0xc25805ce));
+path.cubicTo(SkBits2Float(0x41cb3b2f), SkBits2Float(0xc2597382), SkBits2Float(0x41c5455b), SkBits2Float(0xc25ad1b2), SkBits2Float(0x41bf41a9), SkBits2Float(0xc25c2023));
+path.lineTo(SkBits2Float(0x42044925), SkBits2Float(0xc29840e4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp35(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3673fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41360dec), SkBits2Float(0xc2a60000), SkBits2Float(0x41b5150e), SkBits2Float(0xc2a1522b), SkBits2Float(0x42044925), SkBits2Float(0xc29840e5));
+path.lineTo(SkBits2Float(0x4210a695), SkBits2Float(0xc2956a6a));
+path.lineTo(SkBits2Float(0x41d1222e), SkBits2Float(0xc25805ce));
+path.cubicTo(SkBits2Float(0x41cb3b2f), SkBits2Float(0xc2597382), SkBits2Float(0x41c5455b), SkBits2Float(0xc25ad1b2), SkBits2Float(0x41bf41a9), SkBits2Float(0xc25c2023));
+path.lineTo(SkBits2Float(0x41bf41a8), SkBits2Float(0xc25c2022));
+path.cubicTo(SkBits2Float(0x4182e721), SkBits2Float(0xc2693c30), SkBits2Float(0x41039b08), SkBits2Float(0xc2700000), SkBits2Float(0x3673fea3), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4210a693), SkBits2Float(0xc2956a6a));
+path.cubicTo(SkBits2Float(0x42536b4d), SkBits2Float(0xc2854182), SkBits2Float(0x4284b863), SkBits2Float(0xc254c33a), SkBits2Float(0x42950c68), SkBits2Float(0xc2122882));
+path.lineTo(SkBits2Float(0x42577de3), SkBits2Float(0xc1d35027));
+path.cubicTo(SkBits2Float(0x423fe27d), SkBits2Float(0xc219cde7), SkBits2Float(0x4218d548), SkBits2Float(0xc240a8bd), SkBits2Float(0x41d1222f), SkBits2Float(0xc25805ce));
+path.lineTo(SkBits2Float(0x4210a693), SkBits2Float(0xc2956a6a));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp36(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x414e6589), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41ccf9e5), SkBits2Float(0xc29ffc89), SkBits2Float(0x4214a0bb), SkBits2Float(0xc2946fc8));
+path.lineTo(SkBits2Float(0x41d6e236), SkBits2Float(0xc2569b72));
+path.cubicTo(SkBits2Float(0x41942cf0), SkBits2Float(0xc2674e45), SkBits2Float(0x411533d1), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4214a0bb), SkBits2Float(0xc2946fc9));
+path.cubicTo(SkBits2Float(0x421938a6), SkBits2Float(0xc293496b), SkBits2Float(0x421dc2c1), SkBits2Float(0xc2921574), SkBits2Float(0x42223e19), SkBits2Float(0xc290d421));
+path.lineTo(SkBits2Float(0x41ea914d), SkBits2Float(0xc251640c));
+path.cubicTo(SkBits2Float(0x41e4167f), SkBits2Float(0xc253349e), SkBits2Float(0x41dd8659), SkBits2Float(0xc254f1de), SkBits2Float(0x41d6e239), SkBits2Float(0xc2569b73));
+path.lineTo(SkBits2Float(0x4214a0bb), SkBits2Float(0xc2946fc9));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp37(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x414e6589), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41ccf9e5), SkBits2Float(0xc29ffc89), SkBits2Float(0x4214a0bb), SkBits2Float(0xc2946fc9));
+path.cubicTo(SkBits2Float(0x421938a6), SkBits2Float(0xc293496b), SkBits2Float(0x421dc2c1), SkBits2Float(0xc2921574), SkBits2Float(0x42223e19), SkBits2Float(0xc290d421));
+path.lineTo(SkBits2Float(0x41ea914d), SkBits2Float(0xc251640c));
+path.cubicTo(SkBits2Float(0x41e4167f), SkBits2Float(0xc253349e), SkBits2Float(0x41dd8659), SkBits2Float(0xc254f1de), SkBits2Float(0x41d6e239), SkBits2Float(0xc2569b73));
+path.lineTo(SkBits2Float(0x41d6e236), SkBits2Float(0xc2569b72));
+path.cubicTo(SkBits2Float(0x41942cf0), SkBits2Float(0xc2674e45), SkBits2Float(0x411533d1), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42223e19), SkBits2Float(0xc290d422));
+path.cubicTo(SkBits2Float(0x426bbc38), SkBits2Float(0xc2787e1d), SkBits2Float(0x42916a94), SkBits2Float(0xc234ee59), SkBits2Float(0x429e2fac), SkBits2Float(0xc1c951fc));
+path.lineTo(SkBits2Float(0x4264b3f7), SkBits2Float(0xc191885f));
+path.cubicTo(SkBits2Float(0x42523d91), SkBits2Float(0xc202cb25), SkBits2Float(0x422a6939), SkBits2Float(0xc233a21b), SkBits2Float(0x41ea914d), SkBits2Float(0xc251640d));
+path.lineTo(SkBits2Float(0x42223e19), SkBits2Float(0xc290d422));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp38(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x416c96cf), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41ea70fe), SkBits2Float(0xc29e1973), SkBits2Float(0x422836c6), SkBits2Float(0xc28f1d8a));
+path.lineTo(SkBits2Float(0x41f3336d), SkBits2Float(0xc24ee9f1));
+path.cubicTo(SkBits2Float(0x41a979c6), SkBits2Float(0xc26493d6), SkBits2Float(0x412b073c), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x422836c5), SkBits2Float(0xc28f1d8b));
+path.cubicTo(SkBits2Float(0x422d4896), SkBits2Float(0xc28da02f), SkBits2Float(0x423245ea), SkBits2Float(0xc28c11a8), SkBits2Float(0x42372d65), SkBits2Float(0xc28a7261));
+path.lineTo(SkBits2Float(0x42046ad7), SkBits2Float(0xc24829ff));
+path.cubicTo(SkBits2Float(0x4200df44), SkBits2Float(0xc24a8267), SkBits2Float(0x41fa87ca), SkBits2Float(0xc24cc296), SkBits2Float(0x41f3336d), SkBits2Float(0xc24ee9f1));
+path.lineTo(SkBits2Float(0x422836c5), SkBits2Float(0xc28f1d8b));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp39(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x416c96cf), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41ea70fe), SkBits2Float(0xc29e1973), SkBits2Float(0x422836c5), SkBits2Float(0xc28f1d8b));
+path.cubicTo(SkBits2Float(0x422d4896), SkBits2Float(0xc28da02f), SkBits2Float(0x423245ea), SkBits2Float(0xc28c11a8), SkBits2Float(0x42372d65), SkBits2Float(0xc28a7261));
+path.lineTo(SkBits2Float(0x42046ad7), SkBits2Float(0xc24829ff));
+path.cubicTo(SkBits2Float(0x4200df44), SkBits2Float(0xc24a8267), SkBits2Float(0x41fa87ca), SkBits2Float(0xc24cc296), SkBits2Float(0x41f3336d), SkBits2Float(0xc24ee9f1));
+path.cubicTo(SkBits2Float(0x41a979c6), SkBits2Float(0xc26493d6), SkBits2Float(0x412b073c), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42372d65), SkBits2Float(0xc28a7262));
+path.cubicTo(SkBits2Float(0x4283f2b3), SkBits2Float(0xc25f7e9c), SkBits2Float(0x429ea5c2), SkBits2Float(0xc2098801), SkBits2Float(0x42a4b292), SkBits2Float(0xc12607b1));
+path.lineTo(SkBits2Float(0x426e1def), SkBits2Float(0xc0f00b21));
+path.cubicTo(SkBits2Float(0x42655eb1), SkBits2Float(0xc1c6d725), SkBits2Float(0x423ec4ad), SkBits2Float(0xc2218ff6), SkBits2Float(0x42046ad7), SkBits2Float(0xc2482a00));
+path.lineTo(SkBits2Float(0x42372d65), SkBits2Float(0xc28a7262));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp40(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4184d4a8), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42034ddf), SkBits2Float(0xc29c0a4c), SkBits2Float(0x423a47b2), SkBits2Float(0xc289686d));
+path.lineTo(SkBits2Float(0x4206a908), SkBits2Float(0xc246a97c));
+path.cubicTo(SkBits2Float(0x41bdd65f), SkBits2Float(0xc26199af), SkBits2Float(0x41400b5c), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423a47b2), SkBits2Float(0xc289686d));
+path.cubicTo(SkBits2Float(0x423fbcc3), SkBits2Float(0xc2878eef), SkBits2Float(0x4245154e), SkBits2Float(0xc285a0be), SkBits2Float(0x424a4f85), SkBits2Float(0xc2839e81));
+path.lineTo(SkBits2Float(0x42123fa7), SkBits2Float(0xc23e4af2));
+path.cubicTo(SkBits2Float(0x420e7846), SkBits2Float(0xc241326c), SkBits2Float(0x420a9af5), SkBits2Float(0xc243fcec), SkBits2Float(0x4206a907), SkBits2Float(0xc246a97c));
+path.lineTo(SkBits2Float(0x423a47b2), SkBits2Float(0xc289686d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end fail 1
+
+static void battleOp41(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4196c4f9), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42148669), SkBits2Float(0xc2992c23), SkBits2Float(0x424f6452), SkBits2Float(0xc281a081));
+path.lineTo(SkBits2Float(0x4215ebfd), SkBits2Float(0xc23b6999));
+path.cubicTo(SkBits2Float(0x41d6bc2a), SkBits2Float(0xc25d7441), SkBits2Float(0x4159fada), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x424f6452), SkBits2Float(0xc281a081));
+path.cubicTo(SkBits2Float(0x42553921), SkBits2Float(0xc27e96d1), SkBits2Float(0x425ae53b), SkBits2Float(0xc279ba9d), SkBits2Float(0x42606622), SkBits2Float(0xc274ae80));
+path.lineTo(SkBits2Float(0x42223753), SkBits2Float(0xc230e0d8));
+path.cubicTo(SkBits2Float(0x421e3cd8), SkBits2Float(0xc23486e8), SkBits2Float(0x421a2322), SkBits2Float(0xc2380a55), SkBits2Float(0x4215ebfe), SkBits2Float(0xc23b6999));
+path.lineTo(SkBits2Float(0x424f6452), SkBits2Float(0xc281a081));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp42(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4196c4f9), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42148669), SkBits2Float(0xc2992c23), SkBits2Float(0x424f6452), SkBits2Float(0xc281a081));
+path.cubicTo(SkBits2Float(0x42553921), SkBits2Float(0xc27e96d1), SkBits2Float(0x425ae53b), SkBits2Float(0xc279ba9d), SkBits2Float(0x42606622), SkBits2Float(0xc274ae80));
+path.lineTo(SkBits2Float(0x42223753), SkBits2Float(0xc230e0d8));
+path.cubicTo(SkBits2Float(0x421e3cd8), SkBits2Float(0xc23486e8), SkBits2Float(0x421a2322), SkBits2Float(0xc2380a55), SkBits2Float(0x4215ebfd), SkBits2Float(0xc23b6999));
+path.cubicTo(SkBits2Float(0x41d6bc2a), SkBits2Float(0xc25d7441), SkBits2Float(0x4159fada), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42606622), SkBits2Float(0xc274ae80));
+path.cubicTo(SkBits2Float(0x429deeac), SkBits2Float(0xc220cc44), SkBits2Float(0x42b0742c), SkBits2Float(0xc1039d5c), SkBits2Float(0x42a03731), SkBits2Float(0x41adc1b3));
+path.lineTo(SkBits2Float(0x4267a314), SkBits2Float(0x417b36e3));
+path.cubicTo(SkBits2Float(0x427f1d2c), SkBits2Float(0xc0be4950), SkBits2Float(0x426455fc), SkBits2Float(0xc1e87a9a), SkBits2Float(0x42223754), SkBits2Float(0xc230e0d7));
+path.lineTo(SkBits2Float(0x42606622), SkBits2Float(0xc274ae80));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp43(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41aa5d9e), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42271b56), SkBits2Float(0xc295a109), SkBits2Float(0x4264d340), SkBits2Float(0xc2708c1d));
+path.lineTo(SkBits2Float(0x42256a74), SkBits2Float(0xc22de3bf));
+path.cubicTo(SkBits2Float(0x41f199ac), SkBits2Float(0xc25854c9), SkBits2Float(0x41764fdb), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4264d342), SkBits2Float(0xc2708c1d));
+path.cubicTo(SkBits2Float(0x426aec59), SkBits2Float(0xc26abf16), SkBits2Float(0x4270cc6c), SkBits2Float(0xc264b73d), SkBits2Float(0x42767031), SkBits2Float(0xc25e77e8));
+path.lineTo(SkBits2Float(0x423225ec), SkBits2Float(0xc220d20e));
+path.cubicTo(SkBits2Float(0x422e123c), SkBits2Float(0xc2255633), SkBits2Float(0x4229d2f5), SkBits2Float(0xc229b23c), SkBits2Float(0x42256a74), SkBits2Float(0xc22de3c0));
+path.lineTo(SkBits2Float(0x4264d342), SkBits2Float(0xc2708c1d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp44(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41aa5d9e), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42271b56), SkBits2Float(0xc295a109), SkBits2Float(0x4264d340), SkBits2Float(0xc2708c1d));
+path.lineTo(SkBits2Float(0x4264d342), SkBits2Float(0xc2708c1d));
+path.cubicTo(SkBits2Float(0x426aec59), SkBits2Float(0xc26abf16), SkBits2Float(0x4270cc6c), SkBits2Float(0xc264b73d), SkBits2Float(0x42767031), SkBits2Float(0xc25e77e8));
+path.lineTo(SkBits2Float(0x423225ec), SkBits2Float(0xc220d20e));
+path.cubicTo(SkBits2Float(0x422e123c), SkBits2Float(0xc2255633), SkBits2Float(0x4229d2f5), SkBits2Float(0xc229b23c), SkBits2Float(0x42256a74), SkBits2Float(0xc22de3c0));
+path.lineTo(SkBits2Float(0x42256a74), SkBits2Float(0xc22de3bf));
+path.cubicTo(SkBits2Float(0x41f199ac), SkBits2Float(0xc25854c9), SkBits2Float(0x41764fdb), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42767032), SkBits2Float(0xc25e77e8));
+path.cubicTo(SkBits2Float(0x42aa697a), SkBits2Float(0xc1ebd370), SkBits2Float(0x42b37ad4), SkBits2Float(0x410b48c2), SkBits2Float(0x4291d766), SkBits2Float(0x421e927b));
+path.lineTo(SkBits2Float(0x4252dae4), SkBits2Float(0x41e542d2));
+path.cubicTo(SkBits2Float(0x4281be95), SkBits2Float(0x40c95ff9), SkBits2Float(0x427660fe), SkBits2Float(0xc1aa7a03), SkBits2Float(0x423225ed), SkBits2Float(0xc220d20e));
+path.lineTo(SkBits2Float(0x42767032), SkBits2Float(0xc25e77e8));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp45(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41bfbd07), SkBits2Float(0xc2a5ffff), SkBits2Float(0x423b0ef1), SkBits2Float(0xc2914772), SkBits2Float(0x427a1b1d), SkBits2Float(0xc25a5641));
+path.lineTo(SkBits2Float(0x4234ccaa), SkBits2Float(0xc21dd57d));
+path.cubicTo(SkBits2Float(0x42073912), SkBits2Float(0xc2520ac5), SkBits2Float(0x418a9b2a), SkBits2Float(0xc26fffff), SkBits2Float(0x3697ff52), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427a1b1e), SkBits2Float(0xc25a5642));
+path.cubicTo(SkBits2Float(0x4280286a), SkBits2Float(0xc253393c), SkBits2Float(0x42831c11), SkBits2Float(0xc24bd939), SkBits2Float(0x4285e673), SkBits2Float(0xc2443b5f));
+path.lineTo(SkBits2Float(0x42419733), SkBits2Float(0xc20ddaba));
+path.cubicTo(SkBits2Float(0x423d8e5d), SkBits2Float(0xc2135c44), SkBits2Float(0x423949dc), SkBits2Float(0xc218b118), SkBits2Float(0x4234ccac), SkBits2Float(0xc21dd57e));
+path.lineTo(SkBits2Float(0x427a1b1e), SkBits2Float(0xc25a5642));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp46(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41bfbd07), SkBits2Float(0xc2a5ffff), SkBits2Float(0x423b0ef1), SkBits2Float(0xc2914772), SkBits2Float(0x427a1b1e), SkBits2Float(0xc25a5642));
+path.cubicTo(SkBits2Float(0x4280286a), SkBits2Float(0xc253393c), SkBits2Float(0x42831c11), SkBits2Float(0xc24bd939), SkBits2Float(0x4285e673), SkBits2Float(0xc2443b5f));
+path.lineTo(SkBits2Float(0x42419733), SkBits2Float(0xc20ddaba));
+path.cubicTo(SkBits2Float(0x423d8e5d), SkBits2Float(0xc2135c44), SkBits2Float(0x423949dc), SkBits2Float(0xc218b118), SkBits2Float(0x4234ccac), SkBits2Float(0xc21dd57e));
+path.lineTo(SkBits2Float(0x4234ccaa), SkBits2Float(0xc21dd57d));
+path.cubicTo(SkBits2Float(0x42073912), SkBits2Float(0xc2520ac5), SkBits2Float(0x418a9b2a), SkBits2Float(0xc26fffff), SkBits2Float(0x3697ff52), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4285e672), SkBits2Float(0xc2443b5f));
+path.cubicTo(SkBits2Float(0x42b50145), SkBits2Float(0xc1875361), SkBits2Float(0x42afc74e), SkBits2Float(0x41db6d5e), SkBits2Float(0x4272e616), SkBits2Float(0x426253de));
+path.lineTo(SkBits2Float(0x422f96e8), SkBits2Float(0x42239c3e));
+path.cubicTo(SkBits2Float(0x427e233c), SkBits2Float(0x419e9f42), SkBits2Float(0x4282d8d3), SkBits2Float(0xc143a6d1), SkBits2Float(0x42419734), SkBits2Float(0xc20ddabb));
+path.lineTo(SkBits2Float(0x4285e672), SkBits2Float(0xc2443b5f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp47(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d59904), SkBits2Float(0xc2a5ffff), SkBits2Float(0x424f13ae), SkBits2Float(0xc28c4fb7), SkBits2Float(0x4286bb70), SkBits2Float(0xc241f0ca));
+path.lineTo(SkBits2Float(0x4242cb24), SkBits2Float(0xc20c32b1));
+path.cubicTo(SkBits2Float(0x4215b1b4), SkBits2Float(0xc24adc20), SkBits2Float(0x419a6875), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4286bb71), SkBits2Float(0xc241f0ca));
+path.cubicTo(SkBits2Float(0x4289cb2b), SkBits2Float(0xc2396eee), SkBits2Float(0x428ca6e5), SkBits2Float(0xc230a410), SkBits2Float(0x428f4c27), SkBits2Float(0xc22797c0));
+path.lineTo(SkBits2Float(0x424f2d54), SkBits2Float(0xc1f24d85));
+path.cubicTo(SkBits2Float(0x424b5a2a), SkBits2Float(0xc1ff6268), SkBits2Float(0x42473840), SkBits2Float(0xc2060c56), SkBits2Float(0x4242cb25), SkBits2Float(0xc20c32b2));
+path.lineTo(SkBits2Float(0x4286bb71), SkBits2Float(0xc241f0ca));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp48(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d59904), SkBits2Float(0xc2a5ffff), SkBits2Float(0x424f13ae), SkBits2Float(0xc28c4fb7), SkBits2Float(0x4286bb71), SkBits2Float(0xc241f0ca));
+path.cubicTo(SkBits2Float(0x4289cb2b), SkBits2Float(0xc2396eee), SkBits2Float(0x428ca6e5), SkBits2Float(0xc230a410), SkBits2Float(0x428f4c27), SkBits2Float(0xc22797c0));
+path.lineTo(SkBits2Float(0x424f2d54), SkBits2Float(0xc1f24d85));
+path.cubicTo(SkBits2Float(0x424b5a2a), SkBits2Float(0xc1ff6268), SkBits2Float(0x42473840), SkBits2Float(0xc2060c56), SkBits2Float(0x4242cb24), SkBits2Float(0xc20c32b1));
+path.cubicTo(SkBits2Float(0x4215b1b4), SkBits2Float(0xc24adc20), SkBits2Float(0x419a6875), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x428f4c27), SkBits2Float(0xc22797c0));
+path.cubicTo(SkBits2Float(0x42bc6513), SkBits2Float(0xc055a915), SkBits2Float(0x42a45eb2), SkBits2Float(0x42389acf), SkBits2Float(0x4231df29), SkBits2Float(0x428c2a69));
+path.lineTo(SkBits2Float(0x420094fc), SkBits2Float(0x424aa62f));
+path.cubicTo(SkBits2Float(0x426da4ad), SkBits2Float(0x42057300), SkBits2Float(0x42883065), SkBits2Float(0xc01a7416), SkBits2Float(0x424f2d56), SkBits2Float(0xc1f24d87));
+path.lineTo(SkBits2Float(0x428f4c27), SkBits2Float(0xc22797c0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp49(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41eed329), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4265a038), SkBits2Float(0xc285ef96), SkBits2Float(0x42905111), SkBits2Float(0xc2240eac));
+path.lineTo(SkBits2Float(0x4250a68d), SkBits2Float(0xc1ed30fa));
+path.cubicTo(SkBits2Float(0x4225fe9e), SkBits2Float(0xc241a46c), SkBits2Float(0x41aca4fc), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42905111), SkBits2Float(0xc2240ead));
+path.cubicTo(SkBits2Float(0x429332f8), SkBits2Float(0xc219ea36), SkBits2Float(0x4295cfef), SkBits2Float(0xc20f79c4), SkBits2Float(0x4298252c), SkBits2Float(0xc204c875));
+path.lineTo(SkBits2Float(0x425bf80f), SkBits2Float(0xc1bff9b9));
+path.cubicTo(SkBits2Float(0x42589896), SkBits2Float(0xc1cf6f48), SkBits2Float(0x4254d168), SkBits2Float(0xc1de8710), SkBits2Float(0x4250a68e), SkBits2Float(0xc1ed30fc));
+path.lineTo(SkBits2Float(0x42905111), SkBits2Float(0xc2240ead));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp50(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41eed328), SkBits2Float(0xc2a60000), SkBits2Float(0x4265a038), SkBits2Float(0xc285ef96), SkBits2Float(0x42905111), SkBits2Float(0xc2240ead));
+path.lineTo(SkBits2Float(0x42905111), SkBits2Float(0xc2240eac));
+path.cubicTo(SkBits2Float(0x429332f8), SkBits2Float(0xc219ea35), SkBits2Float(0x4295cfef), SkBits2Float(0xc20f79c4), SkBits2Float(0x4298252c), SkBits2Float(0xc204c875));
+path.lineTo(SkBits2Float(0x425bf80f), SkBits2Float(0xc1bff9b9));
+path.cubicTo(SkBits2Float(0x42589896), SkBits2Float(0xc1cf6f48), SkBits2Float(0x4254d168), SkBits2Float(0xc1de8710), SkBits2Float(0x4250a68d), SkBits2Float(0xc1ed30fa));
+path.cubicTo(SkBits2Float(0x4225fe9e), SkBits2Float(0xc241a46c), SkBits2Float(0x41aca4fc), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4298252d), SkBits2Float(0xc204c875));
+path.cubicTo(SkBits2Float(0x42ab560c), SkBits2Float(0xc1334da0), SkBits2Float(0x42aa8ee6), SkBits2Float(0x415dbf57), SkBits2Float(0x4296030d), SkBits2Float(0x420e292a));
+path.cubicTo(SkBits2Float(0x42817734), SkBits2Float(0x4264e27f), SkBits2Float(0x42365290), SkBits2Float(0x4292cae0), SkBits2Float(0x41b3e39e), SkBits2Float(0x429fcac3));
+path.lineTo(SkBits2Float(0x41820a52), SkBits2Float(0x4267064e));
+path.cubicTo(SkBits2Float(0x4203cca7), SkBits2Float(0x42543ae9), SkBits2Float(0x423b2de4), SkBits2Float(0x42257578), SkBits2Float(0x4258e27d), SkBits2Float(0x41cd88a1));
+path.cubicTo(SkBits2Float(0x42769717), SkBits2Float(0x41204ca2), SkBits2Float(0x4277b705), SkBits2Float(0xc1019de9), SkBits2Float(0x425bf810), SkBits2Float(0xc1bff9bb));
+path.lineTo(SkBits2Float(0x4298252d), SkBits2Float(0xc204c875));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp51(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42044d64), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427bf9ef), SkBits2Float(0xc27d72ab), SkBits2Float(0x42984d42), SkBits2Float(0xc2041029));
+path.lineTo(SkBits2Float(0x425c3202), SkBits2Float(0xc1beef44));
+path.cubicTo(SkBits2Float(0x423626cb), SkBits2Float(0xc2373722), SkBits2Float(0x41bf47cb), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42984d42), SkBits2Float(0xc2041029));
+path.cubicTo(SkBits2Float(0x429adc06), SkBits2Float(0xc1f08771), SkBits2Float(0x429d127e), SkBits2Float(0xc1d85b80), SkBits2Float(0x429eedcc), SkBits2Float(0xc1bfbbc5));
+path.lineTo(SkBits2Float(0x4265c6d6), SkBits2Float(0xc18a9a3f));
+path.cubicTo(SkBits2Float(0x426317a7), SkBits2Float(0xc19c6729), SkBits2Float(0x425fe4aa), SkBits2Float(0xc1ade05f), SkBits2Float(0x425c3203), SkBits2Float(0xc1beef45));
+path.lineTo(SkBits2Float(0x42984d42), SkBits2Float(0xc2041029));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp52(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42044d64), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427bf9ef), SkBits2Float(0xc27d72ab), SkBits2Float(0x42984d42), SkBits2Float(0xc2041029));
+path.cubicTo(SkBits2Float(0x429adc06), SkBits2Float(0xc1f08771), SkBits2Float(0x429d127e), SkBits2Float(0xc1d85b80), SkBits2Float(0x429eedcc), SkBits2Float(0xc1bfbbc5));
+path.lineTo(SkBits2Float(0x4265c6d6), SkBits2Float(0xc18a9a3f));
+path.cubicTo(SkBits2Float(0x426317a7), SkBits2Float(0xc19c6729), SkBits2Float(0x425fe4aa), SkBits2Float(0xc1ade05f), SkBits2Float(0x425c3202), SkBits2Float(0xc1beef44));
+path.cubicTo(SkBits2Float(0x423626cb), SkBits2Float(0xc2373722), SkBits2Float(0x41bf47cb), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429eedcc), SkBits2Float(0xc1bfbbc6));
+path.cubicTo(SkBits2Float(0x42ae408c), SkBits2Float(0x3fb7daeb), SkBits2Float(0x42a45c89), SkBits2Float(0x41e7c57e), SkBits2Float(0x42845101), SkBits2Float(0x42487bac));
+path.cubicTo(SkBits2Float(0x42488af1), SkBits2Float(0x428e8a4c), SkBits2Float(0x41c7bd0e), SkBits2Float(0x42a6f806), SkBits2Float(0xbfc7d871), SkBits2Float(0x42a5f87b));
+path.lineTo(SkBits2Float(0xbf90777c), SkBits2Float(0x426ff521));
+path.cubicTo(SkBits2Float(0x419063a9), SkBits2Float(0x42716698), SkBits2Float(0x4210f87e), SkBits2Float(0x424e1511), SkBits2Float(0x423f4d05), SkBits2Float(0x4210ed75));
+path.cubicTo(SkBits2Float(0x426da18c), SkBits2Float(0x41a78bb1), SkBits2Float(0x427bee4d), SkBits2Float(0x3f84e856), SkBits2Float(0x4265c6d8), SkBits2Float(0xc18a9a40));
+path.lineTo(SkBits2Float(0x429eedcc), SkBits2Float(0xc1bfbbc6));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp53(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x421216db), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4289817d), SkBits2Float(0xc26c814f), SkBits2Float(0x429ecb3a), SkBits2Float(0xc1c183ed));
+path.lineTo(SkBits2Float(0x426594dc), SkBits2Float(0xc18be3fc));
+path.cubicTo(SkBits2Float(0x4246cdba), SkBits2Float(0xc22af7b1), SkBits2Float(0x41d336a3), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429ecb3a), SkBits2Float(0xc1c183e9));
+path.cubicTo(SkBits2Float(0x42a0d9cb), SkBits2Float(0xc1a68281), SkBits2Float(0x42a27999), SkBits2Float(0xc18b01ce), SkBits2Float(0x42a3a81d), SkBits2Float(0xc15e595d));
+path.lineTo(SkBits2Float(0x426c9cb2), SkBits2Float(0xc120bbfa));
+path.cubicTo(SkBits2Float(0x426ae754), SkBits2Float(0xc148f95c), SkBits2Float(0x42688e2a), SkBits2Float(0xc170bcb0), SkBits2Float(0x426594dd), SkBits2Float(0xc18be3fd));
+path.lineTo(SkBits2Float(0x429ecb3a), SkBits2Float(0xc1c183e9));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp54(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x421216db), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4289817d), SkBits2Float(0xc26c814f), SkBits2Float(0x429ecb3a), SkBits2Float(0xc1c183ed));
+path.lineTo(SkBits2Float(0x42a3a81d), SkBits2Float(0xc15e595d));
+path.lineTo(SkBits2Float(0x426c9cb2), SkBits2Float(0xc120bbfa));
+path.cubicTo(SkBits2Float(0x426ae754), SkBits2Float(0xc148f95c), SkBits2Float(0x42688e2a), SkBits2Float(0xc170bcb0), SkBits2Float(0x426594dd), SkBits2Float(0xc18be3fd));
+path.lineTo(SkBits2Float(0x426594dc), SkBits2Float(0xc18be3fc));
+path.cubicTo(SkBits2Float(0x4246cdba), SkBits2Float(0xc22af7b1), SkBits2Float(0x41d336a3), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a3a81d), SkBits2Float(0xc15e595e));
+path.cubicTo(SkBits2Float(0x42ad725e), SkBits2Float(0x416ed313), SkBits2Float(0x42982fa2), SkBits2Float(0x4230cc44), SkBits2Float(0x42575fca), SkBits2Float(0x427ca963));
+path.cubicTo(SkBits2Float(0x41fcc0a1), SkBits2Float(0x42a44341), SkBits2Float(0x3f80ed4e), SkBits2Float(0x42affc4e), SkBits2Float(0xc1d56b7f), SkBits2Float(0x429d3115));
+path.lineTo(SkBits2Float(0xc19a478e), SkBits2Float(0x426343e2));
+path.cubicTo(SkBits2Float(0x3f3a6666), SkBits2Float(0x427e6fe0), SkBits2Float(0x41b6b66f), SkBits2Float(0x426d7d04), SkBits2Float(0x421bb135), SkBits2Float(0x4236a5a5));
+path.cubicTo(SkBits2Float(0x425c0733), SkBits2Float(0x41ff9c8c), SkBits2Float(0x427ac435), SkBits2Float(0x412ca4f2), SkBits2Float(0x426c9cb3), SkBits2Float(0xc120bbf8));
+path.lineTo(SkBits2Float(0x42a3a81d), SkBits2Float(0xc15e595e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp55(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4220aa02), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42952310), SkBits2Float(0xc258f48d), SkBits2Float(0x42a35f68), SkBits2Float(0xc16b5614));
+path.lineTo(SkBits2Float(0x426c3395), SkBits2Float(0xc12a1f61));
+path.cubicTo(SkBits2Float(0x42579ea8), SkBits2Float(0xc21cd5ce), SkBits2Float(0x41e84916), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a35f69), SkBits2Float(0xc16b5613));
+path.cubicTo(SkBits2Float(0x42a4bd24), SkBits2Float(0xc12ea3c2), SkBits2Float(0x42a59325), SkBits2Float(0xc0e282d6), SkBits2Float(0x42a5dfdf), SkBits2Float(0xc04e84a0));
+path.lineTo(SkBits2Float(0x426fd18d), SkBits2Float(0xc0154a48));
+path.cubicTo(SkBits2Float(0x426f62a1), SkBits2Float(0xc0a3be33), SkBits2Float(0x426e2d39), SkBits2Float(0xc0fc7dbb), SkBits2Float(0x426c3397), SkBits2Float(0xc12a1f63));
+path.lineTo(SkBits2Float(0x42a35f69), SkBits2Float(0xc16b5613));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp56(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4220aa02), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42952310), SkBits2Float(0xc258f48d), SkBits2Float(0x42a35f69), SkBits2Float(0xc16b5613));
+path.cubicTo(SkBits2Float(0x42a4bd24), SkBits2Float(0xc12ea3c2), SkBits2Float(0x42a59325), SkBits2Float(0xc0e282d6), SkBits2Float(0x42a5dfdf), SkBits2Float(0xc04e84a0));
+path.lineTo(SkBits2Float(0x426fd18d), SkBits2Float(0xc0154a48));
+path.cubicTo(SkBits2Float(0x426f62a1), SkBits2Float(0xc0a3be33), SkBits2Float(0x426e2d39), SkBits2Float(0xc0fc7dbb), SkBits2Float(0x426c3397), SkBits2Float(0xc12a1f63));
+path.lineTo(SkBits2Float(0x426c3395), SkBits2Float(0xc12a1f61));
+path.cubicTo(SkBits2Float(0x42579ea8), SkBits2Float(0xc21cd5ce), SkBits2Float(0x41e84916), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a5dfdf), SkBits2Float(0xc04e84a0));
+path.cubicTo(SkBits2Float(0x42a85e4f), SkBits2Float(0x41e6959e), SkBits2Float(0x4285b4e3), SkBits2Float(0x426ae44f), SkBits2Float(0x4219b105), SkBits2Float(0x42932450));
+path.cubicTo(SkBits2Float(0x411fe111), SkBits2Float(0x42b0d679), SkBits2Float(0xc1c3966b), SkBits2Float(0x42ab1d42), SkBits2Float(0xc2482755), SkBits2Float(0x428470e8));
+path.lineTo(SkBits2Float(0xc210b07c), SkBits2Float(0x423f7b24));
+path.cubicTo(SkBits2Float(0xc18d6382), SkBits2Float(0x427764e8), SkBits2Float(0x40e72680), SkBits2Float(0x427fab4e), SkBits2Float(0x41de345e), SkBits2Float(0x4254bc3b));
+path.cubicTo(SkBits2Float(0x42414f8e), SkBits2Float(0x4229cd28), SkBits2Float(0x42736c9d), SkBits2Float(0x41a6b008), SkBits2Float(0x426fd18e), SkBits2Float(0xc0154a3f));
+path.lineTo(SkBits2Float(0x42a5dfdf), SkBits2Float(0xc04e84a0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp57(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x422b8e0b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x429d6dbc), SkBits2Float(0xc2494bad), SkBits2Float(0x42a54cb6), SkBits2Float(0xc0f3b760));
+path.lineTo(SkBits2Float(0x426efcca), SkBits2Float(0xc0b02e2c));
+path.cubicTo(SkBits2Float(0x42639b94), SkBits2Float(0xc21183d2), SkBits2Float(0x41f807f9), SkBits2Float(0xc2700000), SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a54cb7), SkBits2Float(0xc0f3b757));
+path.cubicTo(SkBits2Float(0x42a60d08), SkBits2Float(0xc0628d9e), SkBits2Float(0x42a632b1), SkBits2Float(0x3f0efcd8), SkBits2Float(0x42a5bd61), SkBits2Float(0x4094a90a));
+path.lineTo(SkBits2Float(0x426f9faf), SkBits2Float(0x4056ee3d));
+path.cubicTo(SkBits2Float(0x42704949), SkBits2Float(0x3ecebaba), SkBits2Float(0x427012d8), SkBits2Float(0xc023c5fe), SkBits2Float(0x426efccb), SkBits2Float(0xc0b02e2d));
+path.lineTo(SkBits2Float(0x42a54cb7), SkBits2Float(0xc0f3b757));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp58(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x422b8e0b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x429d6dbc), SkBits2Float(0xc2494bad), SkBits2Float(0x42a54cb7), SkBits2Float(0xc0f3b757));
+path.cubicTo(SkBits2Float(0x42a60d08), SkBits2Float(0xc0628d9e), SkBits2Float(0x42a632b1), SkBits2Float(0x3f0efcd8), SkBits2Float(0x42a5bd61), SkBits2Float(0x4094a90a));
+path.lineTo(SkBits2Float(0x426f9faf), SkBits2Float(0x4056ee3d));
+path.cubicTo(SkBits2Float(0x42704949), SkBits2Float(0x3ecebaba), SkBits2Float(0x427012d8), SkBits2Float(0xc023c5fe), SkBits2Float(0x426efcca), SkBits2Float(0xc0b02e2c));
+path.cubicTo(SkBits2Float(0x42639b94), SkBits2Float(0xc21183d2), SkBits2Float(0x41f807f9), SkBits2Float(0xc2700000), SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a5bd62), SkBits2Float(0x4094a90c));
+path.cubicTo(SkBits2Float(0x42a1e9d4), SkBits2Float(0x421b17cd), SkBits2Float(0x426944f3), SkBits2Float(0x428879ea), SkBits2Float(0x41ceac14), SkBits2Float(0x429dc116));
+path.cubicTo(SkBits2Float(0xc0d4c6f5), SkBits2Float(0x42b30843), SkBits2Float(0xc2295516), SkBits2Float(0x429e4e8b), SkBits2Float(0xc2802142), SkBits2Float(0x4253148e));
+path.lineTo(SkBits2Float(0xc2393f81), SkBits2Float(0x42189693));
+path.cubicTo(SkBits2Float(0xc1f4d162), SkBits2Float(0x4264e09b), SkBits2Float(0xc099d099), SkBits2Float(0x42816bc3), SkBits2Float(0x419566d0), SkBits2Float(0x42641418));
+path.cubicTo(SkBits2Float(0x4228a0e3), SkBits2Float(0x424550a9), SkBits2Float(0x426a177b), SkBits2Float(0x41e03b19), SkBits2Float(0x426f9fb0), SkBits2Float(0x4056ee3a));
+path.lineTo(SkBits2Float(0x42a5bd62), SkBits2Float(0x4094a90c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp59(skiatest::Reporter* reporter, const char* filename) {  // hung
+    if (!FLAGS_runFail) {
+        return;
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x423693bc), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42a57249), SkBits2Float(0xc2389374), SkBits2Float(0x42a5ff3a), SkBits2Float(0xbf002494));
+path.lineTo(SkBits2Float(0x426ffee2), SkBits2Float(0xbeb944c3));
+path.cubicTo(SkBits2Float(0x426f331d), SkBits2Float(0xc2056daf), SkBits2Float(0x4203fbc4), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a5ff3a), SkBits2Float(0xbf0024e6));
+path.cubicTo(SkBits2Float(0x42a60c9b), SkBits2Float(0x40752b0d), SkBits2Float(0x42a56c5d), SkBits2Float(0x410284fd), SkBits2Float(0x42a41ffb), SkBits2Float(0x414709fb));
+path.lineTo(SkBits2Float(0x426d49ff), SkBits2Float(0x410fe233));
+path.cubicTo(SkBits2Float(0x426f2a8e), SkBits2Float(0x40bcb3f0), SkBits2Float(0x42701239), SkBits2Float(0x40313ae3), SkBits2Float(0x426ffee3), SkBits2Float(0xbeb944c6));
+path.lineTo(SkBits2Float(0x42a5ff3a), SkBits2Float(0xbf0024e6));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp60(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e9334c2), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f13342a), SkBits2Float(0xc2a5ff3c), SkBits2Float(0x3f5ccd0d), SkBits2Float(0xc2a5fdb4));
+path.lineTo(SkBits2Float(0x3f1f9d85), SkBits2Float(0xc26ffcaf));
+path.cubicTo(SkBits2Float(0x3ed4d324), SkBits2Float(0xc26ffee7), SkBits2Float(0x3e54d404), SkBits2Float(0xc2700000), SkBits2Float(0x36b23f68), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f5ccd1a), SkBits2Float(0xc2a5fdb5));
+path.cubicTo(SkBits2Float(0x3f642956), SkBits2Float(0xc2a5fd8c), SkBits2Float(0x3f6b855d), SkBits2Float(0xc2a5fd63), SkBits2Float(0x3f72e163), SkBits2Float(0xc2a5fd38));
+path.lineTo(SkBits2Float(0x3f2f9381), SkBits2Float(0xc26ffbfc));
+path.cubicTo(SkBits2Float(0x3f2a4188), SkBits2Float(0xc26ffc3b), SkBits2Float(0x3f24ef95), SkBits2Float(0xc26ffc76), SkBits2Float(0x3f1f9da0), SkBits2Float(0xc26ffcb0));
+path.lineTo(SkBits2Float(0x3f5ccd1a), SkBits2Float(0xc2a5fdb5));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp61(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36b23f68), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e9334c2), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f13342a), SkBits2Float(0xc2a5ff3c), SkBits2Float(0x3f5ccd1a), SkBits2Float(0xc2a5fdb5));
+path.cubicTo(SkBits2Float(0x3f642956), SkBits2Float(0xc2a5fd8c), SkBits2Float(0x3f6b855d), SkBits2Float(0xc2a5fd63), SkBits2Float(0x3f72e163), SkBits2Float(0xc2a5fd38));
+path.lineTo(SkBits2Float(0x3f2f9381), SkBits2Float(0xc26ffbfc));
+path.cubicTo(SkBits2Float(0x3f2a4188), SkBits2Float(0xc26ffc3b), SkBits2Float(0x3f24ef95), SkBits2Float(0xc26ffc76), SkBits2Float(0x3f1f9d85), SkBits2Float(0xc26ffcaf));
+path.cubicTo(SkBits2Float(0x3ed4d324), SkBits2Float(0xc26ffee7), SkBits2Float(0x3e54d404), SkBits2Float(0xc2700000), SkBits2Float(0x36b23f68), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f72e162), SkBits2Float(0xc2a5fd39));
+path.cubicTo(SkBits2Float(0x3fb51288), SkBits2Float(0xc2a5fa80), SkBits2Float(0x3ff0b297), SkBits2Float(0xc2a5f5c4), SkBits2Float(0x401627a5), SkBits2Float(0xc2a5ef06));
+path.lineTo(SkBits2Float(0x3fd9177b), SkBits2Float(0xc26fe773));
+path.cubicTo(SkBits2Float(0x3fadff90), SkBits2Float(0xc26ff134), SkBits2Float(0x3f82e54e), SkBits2Float(0xc26ff80c), SkBits2Float(0x3f2f9393), SkBits2Float(0xc26ffbfc));
+path.lineTo(SkBits2Float(0x3f72e162), SkBits2Float(0xc2a5fd39));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp62(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f614848), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3fe14683), SkBits2Float(0xc2a5f8d5), SkBits2Float(0x4028ee0f), SkBits2Float(0xc2a5ea81));
+path.lineTo(SkBits2Float(0x3ff43c76), SkBits2Float(0xc26fe0ec));
+path.cubicTo(SkBits2Float(0x3fa2d98a), SkBits2Float(0xc26ff5a4), SkBits2Float(0x3f22dad5), SkBits2Float(0xc2700000), SkBits2Float(0xb5420574), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4028ee15), SkBits2Float(0xc2a5ea81));
+path.cubicTo(SkBits2Float(0x402e8f25), SkBits2Float(0xc2a5e912), SkBits2Float(0x40343026), SkBits2Float(0xc2a5e791), SkBits2Float(0x4039d111), SkBits2Float(0xc2a5e5fd));
+path.lineTo(SkBits2Float(0x4006533c), SkBits2Float(0xc26fda66));
+path.cubicTo(SkBits2Float(0x4002419e), SkBits2Float(0xc26fdcaf), SkBits2Float(0x3ffc5fdb), SkBits2Float(0xc26fdedc), SkBits2Float(0x3ff43c61), SkBits2Float(0xc26fe0ed));
+path.lineTo(SkBits2Float(0x4028ee15), SkBits2Float(0xc2a5ea81));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp63(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f614848), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3fe14683), SkBits2Float(0xc2a5f8d5), SkBits2Float(0x4028ee15), SkBits2Float(0xc2a5ea81));
+path.cubicTo(SkBits2Float(0x402e8f25), SkBits2Float(0xc2a5e912), SkBits2Float(0x40343026), SkBits2Float(0xc2a5e791), SkBits2Float(0x4039d111), SkBits2Float(0xc2a5e5fd));
+path.lineTo(SkBits2Float(0x4006533c), SkBits2Float(0xc26fda66));
+path.cubicTo(SkBits2Float(0x400241a2), SkBits2Float(0xc26fdcaf), SkBits2Float(0x3ffc5fea), SkBits2Float(0xc26fdedc), SkBits2Float(0x3ff43c76), SkBits2Float(0xc26fe0ec));
+path.cubicTo(SkBits2Float(0x3fa2d98a), SkBits2Float(0xc26ff5a4), SkBits2Float(0x3f22dad5), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+path.moveTo(SkBits2Float(0x40186abb), SkBits2Float(0xc295b297));
+path.lineTo(SkBits2Float(0x3ff43c61), SkBits2Float(0xc26fe0ed));
+path.lineTo(SkBits2Float(0x3ff43c77), SkBits2Float(0xc26fe0ed));
+path.lineTo(SkBits2Float(0x40186abb), SkBits2Float(0xc295b297));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4039d102), SkBits2Float(0xc2a5e5fe));
+path.cubicTo(SkBits2Float(0x408a83ff), SkBits2Float(0xc2a5cc72), SkBits2Float(0x40b8130f), SkBits2Float(0xc2a5a01a), SkBits2Float(0x40e58a06), SkBits2Float(0xc2a56100));
+path.lineTo(SkBits2Float(0x40a5ee90), SkBits2Float(0xc26f1a20));
+path.cubicTo(SkBits2Float(0x408510de), SkBits2Float(0xc26f755e), SkBits2Float(0x40484386), SkBits2Float(0xc26fb57a), SkBits2Float(0x40065347), SkBits2Float(0xc26fda68));
+path.lineTo(SkBits2Float(0x4039d102), SkBits2Float(0xc2a5e5fe));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp64(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3faf587e), SkBits2Float(0xc2a5ffff), SkBits2Float(0x402f5505), SkBits2Float(0xc2a5eea1), SkBits2Float(0x408372de), SkBits2Float(0xc2a5cbeb));
+path.lineTo(SkBits2Float(0x403e0bd0), SkBits2Float(0xc26fb4b6));
+path.cubicTo(SkBits2Float(0x3ffd7de6), SkBits2Float(0xc26fe6e6), SkBits2Float(0x3f7d82fb), SkBits2Float(0xc2700000), SkBits2Float(0x363f7eb2), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x408372d6), SkBits2Float(0xc2a5cbec));
+path.cubicTo(SkBits2Float(0x4087d39d), SkBits2Float(0xc2a5c874), SkBits2Float(0x408c3440), SkBits2Float(0xc2a5c4cf), SkBits2Float(0x409094bd), SkBits2Float(0xc2a5c0fe));
+path.lineTo(SkBits2Float(0x40510866), SkBits2Float(0xc26fa4e7));
+path.cubicTo(SkBits2Float(0x404ab468), SkBits2Float(0xc26faa6c), SkBits2Float(0x40446037), SkBits2Float(0xc26fafb2), SkBits2Float(0x403e0bd2), SkBits2Float(0xc26fb4b7));
+path.lineTo(SkBits2Float(0x408372d6), SkBits2Float(0xc2a5cbec));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp65(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x363f7eb2), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3faf5872), SkBits2Float(0xc2a60000), SkBits2Float(0x402f54f9), SkBits2Float(0xc2a5eea1), SkBits2Float(0x408372d5), SkBits2Float(0xc2a5cbeb));
+path.lineTo(SkBits2Float(0x408372d6), SkBits2Float(0xc2a5cbec));
+path.cubicTo(SkBits2Float(0x4087d39d), SkBits2Float(0xc2a5c874), SkBits2Float(0x408c3440), SkBits2Float(0xc2a5c4cf), SkBits2Float(0x409094bd), SkBits2Float(0xc2a5c0fe));
+path.lineTo(SkBits2Float(0x40510866), SkBits2Float(0xc26fa4e7));
+path.cubicTo(SkBits2Float(0x404ab468), SkBits2Float(0xc26faa6c), SkBits2Float(0x40446037), SkBits2Float(0xc26fafb2), SkBits2Float(0x403e0bd0), SkBits2Float(0xc26fb4b6));
+path.cubicTo(SkBits2Float(0x3ffd7de6), SkBits2Float(0xc26fe6e6), SkBits2Float(0x3f7d82fb), SkBits2Float(0xc2700000), SkBits2Float(0x363f7eb2), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x409094be), SkBits2Float(0xc2a5c0fe));
+path.cubicTo(SkBits2Float(0x40d784bb), SkBits2Float(0xc2a5831d), SkBits2Float(0x410f22d3), SkBits2Float(0xc2a517ba), SkBits2Float(0x413255ec), SkBits2Float(0xc2a47f15));
+path.lineTo(SkBits2Float(0x4100ead4), SkBits2Float(0xc26dd37e));
+path.cubicTo(SkBits2Float(0x40cef193), SkBits2Float(0xc26eb02f), SkBits2Float(0x409bcbdf), SkBits2Float(0xc26f4b72), SkBits2Float(0x40510859), SkBits2Float(0xc26fa4e8));
+path.lineTo(SkBits2Float(0x409094be), SkBits2Float(0xc2a5c0fe));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp66(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4037e518), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40b7d534), SkBits2Float(0xc2a5b39a), SkBits2Float(0x4109a47d), SkBits2Float(0xc2a51b1f));
+path.lineTo(SkBits2Float(0x40c70051), SkBits2Float(0xc26eb519));
+path.cubicTo(SkBits2Float(0x4084e427), SkBits2Float(0xc26f918c), SkBits2Float(0x4004efa4), SkBits2Float(0xc26fffff), SkBits2Float(0x3543fa8c), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4109a47c), SkBits2Float(0xc2a51b20));
+path.cubicTo(SkBits2Float(0x410e36d1), SkBits2Float(0xc2a50be2), SkBits2Float(0x4112c883), SkBits2Float(0xc2a4fbe1), SkBits2Float(0x41175985), SkBits2Float(0xc2a4eb1d));
+path.lineTo(SkBits2Float(0x40dad196), SkBits2Float(0xc26e6faf));
+path.cubicTo(SkBits2Float(0x40d4377d), SkBits2Float(0xc26e87ed), SkBits2Float(0x40cd9c5c), SkBits2Float(0xc26e9f10), SkBits2Float(0x40c7004e), SkBits2Float(0xc26eb51a));
+path.lineTo(SkBits2Float(0x4109a47c), SkBits2Float(0xc2a51b20));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp67(skiatest::Reporter* reporter, const char* filename) { // crashed
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4037e518), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40b7d534), SkBits2Float(0xc2a5b39a), SkBits2Float(0x4109a47c), SkBits2Float(0xc2a51b20));
+path.cubicTo(SkBits2Float(0x410e36d1), SkBits2Float(0xc2a50be2), SkBits2Float(0x4112c883), SkBits2Float(0xc2a4fbe1), SkBits2Float(0x41175985), SkBits2Float(0xc2a4eb1d));
+path.lineTo(SkBits2Float(0x40dad196), SkBits2Float(0xc26e6faf));
+path.cubicTo(SkBits2Float(0x40d4377e), SkBits2Float(0xc26e87ed), SkBits2Float(0x40cd9c5f), SkBits2Float(0xc26e9f10), SkBits2Float(0x40c70052), SkBits2Float(0xc26eb51a));
+path.lineTo(SkBits2Float(0x40c70051), SkBits2Float(0xc26eb519));
+path.cubicTo(SkBits2Float(0x4084e427), SkBits2Float(0xc26f918c), SkBits2Float(0x4004efa4), SkBits2Float(0xc26fffff), SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4117597f), SkBits2Float(0xc2a4eb1d));
+path.cubicTo(SkBits2Float(0x41616445), SkBits2Float(0xc2a3db51), SkBits2Float(0x41954b2d), SkBits2Float(0xc2a2048b), SkBits2Float(0x41b914a4), SkBits2Float(0xc29f6bcb));
+path.lineTo(SkBits2Float(0x4185cb10), SkBits2Float(0xc2667d00));
+path.cubicTo(SkBits2Float(0x4157d8a2), SkBits2Float(0xc26a3e17), SkBits2Float(0x4122ef07), SkBits2Float(0xc26ce6b9), SkBits2Float(0x40dad195), SkBits2Float(0xc26e6faf));
+path.lineTo(SkBits2Float(0x4117597f), SkBits2Float(0xc2a4eb1d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp68(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e1b2207), SkBits2Float(0xc2a60000), SkBits2Float(0x3e9b2105), SkBits2Float(0xc2a5ffca), SkBits2Float(0x3ee8b0c0), SkBits2Float(0xc2a5ff5d));
+path.lineTo(SkBits2Float(0x3ea83563), SkBits2Float(0xc26fff14));
+path.cubicTo(SkBits2Float(0x3e60486a), SkBits2Float(0xc26fffb2), SkBits2Float(0x3de049e3), SkBits2Float(0xc2700000), SkBits2Float(0x36b67768), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ee8b040), SkBits2Float(0xc2a5ff5d));
+path.cubicTo(SkBits2Float(0x3ef0720a), SkBits2Float(0xc2a5ff52), SkBits2Float(0x3ef83386), SkBits2Float(0xc2a5ff47), SkBits2Float(0x3efff501), SkBits2Float(0xc2a5ff3b));
+path.lineTo(SkBits2Float(0x3eb90778), SkBits2Float(0xc26ffee3));
+path.cubicTo(SkBits2Float(0x3eb36c27), SkBits2Float(0xc26ffef6), SkBits2Float(0x3eadd0dd), SkBits2Float(0xc26fff07), SkBits2Float(0x3ea83592), SkBits2Float(0xc26fff16));
+path.lineTo(SkBits2Float(0x3ee8b040), SkBits2Float(0xc2a5ff5d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp69(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36b67768), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e1b21b2), SkBits2Float(0xc2a60000), SkBits2Float(0x3e9b20b0), SkBits2Float(0xc2a5ffca), SkBits2Float(0x3ee8b040), SkBits2Float(0xc2a5ff5d));
+path.cubicTo(SkBits2Float(0x3ef0720a), SkBits2Float(0xc2a5ff52), SkBits2Float(0x3ef83386), SkBits2Float(0xc2a5ff47), SkBits2Float(0x3efff501), SkBits2Float(0xc2a5ff3b));
+path.lineTo(SkBits2Float(0x3eb90778), SkBits2Float(0xc26ffee3));
+path.lineTo(SkBits2Float(0x3ea83592), SkBits2Float(0xc26fff16));
+path.lineTo(SkBits2Float(0x3ea83563), SkBits2Float(0xc26fff14));
+path.cubicTo(SkBits2Float(0x3e60486a), SkBits2Float(0xc26fffb2), SkBits2Float(0x3de049e3), SkBits2Float(0xc2700000), SkBits2Float(0x36b67768), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3efff501), SkBits2Float(0xc2a5ff3b));
+path.cubicTo(SkBits2Float(0x3f3ed289), SkBits2Float(0xc2a5fe79), SkBits2Float(0x3f7daa5c), SkBits2Float(0xc2a5fd28), SkBits2Float(0x3f9e4099), SkBits2Float(0xc2a5fb49));
+path.lineTo(SkBits2Float(0x3f64cc5f), SkBits2Float(0xc26ff92f));
+path.cubicTo(SkBits2Float(0x3f375f8f), SkBits2Float(0xc26ffbe5), SkBits2Float(0x3f09f1cf), SkBits2Float(0xc26ffdcc), SkBits2Float(0x3eb9075f), SkBits2Float(0xc26ffee4));
+path.lineTo(SkBits2Float(0x3efff501), SkBits2Float(0xc2a5ff3b));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp70(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f0938d2), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f893841), SkBits2Float(0xc2a5fd56), SkBits2Float(0x3fcdd137), SkBits2Float(0xc2a5f805));
+path.lineTo(SkBits2Float(0x3f94c89b), SkBits2Float(0xc26ff478));
+path.cubicTo(SkBits2Float(0x3f4663c1), SkBits2Float(0xc26ffc29), SkBits2Float(0x3ec6647d), SkBits2Float(0xc2700000), SkBits2Float(0x360ebeb2), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fcdd13c), SkBits2Float(0xc2a5f806));
+path.cubicTo(SkBits2Float(0x3fd4ad55), SkBits2Float(0xc2a5f77d), SkBits2Float(0x3fdb895f), SkBits2Float(0xc2a5f6ef), SkBits2Float(0x3fe26560), SkBits2Float(0xc2a5f659));
+path.lineTo(SkBits2Float(0x3fa3a8ea), SkBits2Float(0xc26ff20c));
+path.cubicTo(SkBits2Float(0x3f9eb37e), SkBits2Float(0xc26ff2e6), SkBits2Float(0x3f99be11), SkBits2Float(0xc26ff3b4), SkBits2Float(0x3f94c89e), SkBits2Float(0xc26ff479));
+path.lineTo(SkBits2Float(0x3fcdd13c), SkBits2Float(0xc2a5f806));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp71(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x360ebeb2), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f0938d2), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f893841), SkBits2Float(0xc2a5fd56), SkBits2Float(0x3fcdd13c), SkBits2Float(0xc2a5f806));
+path.cubicTo(SkBits2Float(0x3fd4ad55), SkBits2Float(0xc2a5f77d), SkBits2Float(0x3fdb895f), SkBits2Float(0xc2a5f6ef), SkBits2Float(0x3fe26560), SkBits2Float(0xc2a5f659));
+path.lineTo(SkBits2Float(0x3fa3a8ea), SkBits2Float(0xc26ff20c));
+path.cubicTo(SkBits2Float(0x3f9eb37e), SkBits2Float(0xc26ff2e6), SkBits2Float(0x3f99be11), SkBits2Float(0xc26ff3b4), SkBits2Float(0x3f94c89b), SkBits2Float(0xc26ff478));
+path.cubicTo(SkBits2Float(0x3f4663c1), SkBits2Float(0xc26ffc29), SkBits2Float(0x3ec6647d), SkBits2Float(0xc2700000), SkBits2Float(0x360ebeb2), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fe26566), SkBits2Float(0xc2a5f65a));
+path.cubicTo(SkBits2Float(0x4028c729), SkBits2Float(0xc2a5ecdf), SkBits2Float(0x406055f2), SkBits2Float(0xc2a5dc6a), SkBits2Float(0x408beceb), SkBits2Float(0xc2a5c4fb));
+path.lineTo(SkBits2Float(0x404a4d47), SkBits2Float(0xc26faaae));
+path.cubicTo(SkBits2Float(0x40222b9c), SkBits2Float(0xc26fcc90), SkBits2Float(0x3ff40427), SkBits2Float(0xc26fe45b), SkBits2Float(0x3fa3a8ee), SkBits2Float(0xc26ff20e));
+path.lineTo(SkBits2Float(0x3fe26566), SkBits2Float(0xc2a5f65a));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp72(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f73aa4a), SkBits2Float(0xc2a60000), SkBits2Float(0x3ff3a7f0), SkBits2Float(0xc2a5f79e), SkBits2Float(0x4036b54b), SkBits2Float(0xc2a5e6db));
+path.lineTo(SkBits2Float(0x40041412), SkBits2Float(0xc26fdba5));
+path.cubicTo(SkBits2Float(0x3fb0230c), SkBits2Float(0xc26ff3e0), SkBits2Float(0x3f3024c1), SkBits2Float(0xc26fffff), SkBits2Float(0x359dfd4a), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4036b55d), SkBits2Float(0xc2a5e6db));
+path.cubicTo(SkBits2Float(0x403ccbdf), SkBits2Float(0xc2a5e52d), SkBits2Float(0x4042e24c), SkBits2Float(0xc2a5e36a), SkBits2Float(0x4048f89e), SkBits2Float(0xc2a5e192));
+path.lineTo(SkBits2Float(0x401147bc), SkBits2Float(0xc26fd403));
+path.cubicTo(SkBits2Float(0x400ce144), SkBits2Float(0xc26fd6ae), SkBits2Float(0x40087ab2), SkBits2Float(0xc26fd939), SkBits2Float(0x4004140f), SkBits2Float(0xc26fdba5));
+path.lineTo(SkBits2Float(0x4036b55d), SkBits2Float(0xc2a5e6db));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end fail 1
+
+static void battleOp73(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40447e19), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40c46ab2), SkBits2Float(0xc2a5a8c7), SkBits2Float(0x4113078c), SkBits2Float(0xc2a4fabe));
+path.lineTo(SkBits2Float(0x40d4929e), SkBits2Float(0xc26e8647));
+path.cubicTo(SkBits2Float(0x408dfcf1), SkBits2Float(0xc26f81e6), SkBits2Float(0x400e0af8), SkBits2Float(0xc2700000), SkBits2Float(0x3655fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4113078b), SkBits2Float(0xc2a4fabe));
+path.cubicTo(SkBits2Float(0x4117e908), SkBits2Float(0xc2a4e957), SkBits2Float(0x411cc9c0), SkBits2Float(0xc2a4d714), SkBits2Float(0x4121a9a1), SkBits2Float(0xc2a4c3f3));
+path.lineTo(SkBits2Float(0x40e9baad), SkBits2Float(0xc26e370e));
+path.cubicTo(SkBits2Float(0x40e2ae85), SkBits2Float(0xc26e52b6), SkBits2Float(0x40dba120), SkBits2Float(0xc26e6d20), SkBits2Float(0x40d4929a), SkBits2Float(0xc26e8647));
+path.lineTo(SkBits2Float(0x4113078b), SkBits2Float(0xc2a4fabe));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end fail 1
+
+static void battleOp74(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x406db78d), SkBits2Float(0xc2a60000), SkBits2Float(0x40ed953d), SkBits2Float(0xc2a58058), SkBits2Float(0x4131afb7), SkBits2Float(0xc2a481e4));
+path.lineTo(SkBits2Float(0x410072b2), SkBits2Float(0xc26dd78e));
+path.cubicTo(SkBits2Float(0x40abbf2e), SkBits2Float(0xc26f4770), SkBits2Float(0x402bd807), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4131afba), SkBits2Float(0xc2a481e4));
+path.cubicTo(SkBits2Float(0x413792dd), SkBits2Float(0xc2a46874), SkBits2Float(0x413d74a2), SkBits2Float(0xc2a44dc1), SkBits2Float(0x414354e9), SkBits2Float(0xc2a431ca));
+path.lineTo(SkBits2Float(0x410d3424), SkBits2Float(0xc26d63c0));
+path.cubicTo(SkBits2Float(0x4108f4b6), SkBits2Float(0xc26d8c2e), SkBits2Float(0x4104b435), SkBits2Float(0xc26db2c8), SkBits2Float(0x410072b4), SkBits2Float(0xc26dd78e));
+path.lineTo(SkBits2Float(0x4131afba), SkBits2Float(0xc2a481e4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp75(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x406db78d), SkBits2Float(0xc2a60000), SkBits2Float(0x40ed953d), SkBits2Float(0xc2a58058), SkBits2Float(0x4131afba), SkBits2Float(0xc2a481e4));
+path.cubicTo(SkBits2Float(0x413792dd), SkBits2Float(0xc2a46874), SkBits2Float(0x413d74a2), SkBits2Float(0xc2a44dc1), SkBits2Float(0x414354e9), SkBits2Float(0xc2a431ca));
+path.lineTo(SkBits2Float(0x410d3424), SkBits2Float(0xc26d63c0));
+path.cubicTo(SkBits2Float(0x4108f4b6), SkBits2Float(0xc26d8c2e), SkBits2Float(0x4104b435), SkBits2Float(0xc26db2c8), SkBits2Float(0x410072b2), SkBits2Float(0xc26dd78e));
+path.cubicTo(SkBits2Float(0x40abbf2e), SkBits2Float(0xc26f4770), SkBits2Float(0x402bd807), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x414354ed), SkBits2Float(0xc2a431cb));
+path.cubicTo(SkBits2Float(0x419152e5), SkBits2Float(0xc2a26c3a), SkBits2Float(0x41c0119b), SkBits2Float(0xc29f5c06), SkBits2Float(0x41ed1335), SkBits2Float(0xc29b0f0a));
+path.lineTo(SkBits2Float(0x41ab612b), SkBits2Float(0xc2602e6b));
+path.cubicTo(SkBits2Float(0x418ad84d), SkBits2Float(0xc2666635), SkBits2Float(0x41521b54), SkBits2Float(0xc26ad3fe), SkBits2Float(0x410d3426), SkBits2Float(0xc26d63c0));
+path.lineTo(SkBits2Float(0x414354ed), SkBits2Float(0xc2a431cb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp76(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40932e58), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41130dbc), SkBits2Float(0xc2a53c41), SkBits2Float(0x415ba178), SkBits2Float(0xc2a3b6ca));
+path.lineTo(SkBits2Float(0x411ec4eb), SkBits2Float(0xc26cb1eb));
+path.cubicTo(SkBits2Float(0x40d49b93), SkBits2Float(0xc26ee4ff), SkBits2Float(0x4054cab9), SkBits2Float(0xc26fffff), SkBits2Float(0x35f7fd46), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x415ba178), SkBits2Float(0xc2a3b6cb));
+path.cubicTo(SkBits2Float(0x4162e261), SkBits2Float(0xc2a38fde), SkBits2Float(0x416a20aa), SkBits2Float(0xc2a36704), SkBits2Float(0x41715c23), SkBits2Float(0xc2a33c3e));
+path.lineTo(SkBits2Float(0x412e7a25), SkBits2Float(0xc26c00bd));
+path.cubicTo(SkBits2Float(0x41293fb6), SkBits2Float(0xc26c3e94), SkBits2Float(0x41240342), SkBits2Float(0xc26c79a4), SkBits2Float(0x411ec4e8), SkBits2Float(0xc26cb1eb));
+path.lineTo(SkBits2Float(0x415ba178), SkBits2Float(0xc2a3b6cb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end fail 1
+
+static void battleOp77(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40d0158a), SkBits2Float(0xc2a60000), SkBits2Float(0x414fb944), SkBits2Float(0xc2a478c0), SkBits2Float(0x419a74b5), SkBits2Float(0xc2a1724b));
+path.lineTo(SkBits2Float(0x415f4f4c), SkBits2Float(0xc2696aa5));
+path.cubicTo(SkBits2Float(0x41162967), SkBits2Float(0xc26dca57), SkBits2Float(0x40966c1f), SkBits2Float(0xc2700000), SkBits2Float(0x3655fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x419a74b6), SkBits2Float(0xc2a1724b));
+path.cubicTo(SkBits2Float(0x419f8274), SkBits2Float(0xc2a124ef), SkBits2Float(0x41a48c82), SkBits2Float(0xc2a0d3c9), SkBits2Float(0x41a9929f), SkBits2Float(0xc2a07edb));
+path.lineTo(SkBits2Float(0x41752a58), SkBits2Float(0xc2680ab0));
+path.cubicTo(SkBits2Float(0x416de6e6), SkBits2Float(0xc268857b), SkBits2Float(0x41669dc0), SkBits2Float(0xc268facf), SkBits2Float(0x415f4f4b), SkBits2Float(0xc2696aa6));
+path.lineTo(SkBits2Float(0x419a74b6), SkBits2Float(0xc2a1724b));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp78(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3655fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40d0158a), SkBits2Float(0xc2a60000), SkBits2Float(0x414fb944), SkBits2Float(0xc2a478c0), SkBits2Float(0x419a74b6), SkBits2Float(0xc2a1724b));
+path.cubicTo(SkBits2Float(0x419f8274), SkBits2Float(0xc2a124ef), SkBits2Float(0x41a48c82), SkBits2Float(0xc2a0d3c9), SkBits2Float(0x41a9929f), SkBits2Float(0xc2a07edb));
+path.lineTo(SkBits2Float(0x41752a58), SkBits2Float(0xc2680ab0));
+path.cubicTo(SkBits2Float(0x416de6e6), SkBits2Float(0xc268857b), SkBits2Float(0x41669dc0), SkBits2Float(0xc268facf), SkBits2Float(0x415f4f4c), SkBits2Float(0xc2696aa5));
+path.cubicTo(SkBits2Float(0x41162967), SkBits2Float(0xc26dca57), SkBits2Float(0x40966c1f), SkBits2Float(0xc2700000), SkBits2Float(0x3655fea3), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41a9929f), SkBits2Float(0xc2a07edc));
+path.cubicTo(SkBits2Float(0x41fb3aee), SkBits2Float(0xc29b1a71), SkBits2Float(0x422402f4), SkBits2Float(0xc291ddaf), SkBits2Float(0x4245eaa6), SkBits2Float(0xc2854763));
+path.lineTo(SkBits2Float(0x420f1280), SkBits2Float(0xc240b13c));
+path.cubicTo(SkBits2Float(0x41ed200b), SkBits2Float(0xc252e3f9), SkBits2Float(0x41b59cbb), SkBits2Float(0xc2603ee8), SkBits2Float(0x41752a58), SkBits2Float(0xc2680aaf));
+path.lineTo(SkBits2Float(0x41a9929f), SkBits2Float(0xc2a07edc));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp79(skiatest::Reporter* reporter, const char* filename) {  //crashed
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4110a0cc), SkBits2Float(0xc2a60000), SkBits2Float(0x4190247a), SkBits2Float(0xc2a30bfe), SkBits2Float(0x41d4a5dc), SkBits2Float(0xc29d41d4));
+path.lineTo(SkBits2Float(0x4199b8a9), SkBits2Float(0xc2635c16));
+path.cubicTo(SkBits2Float(0x4150660f), SkBits2Float(0xc26bbaf8), SkBits2Float(0x40d119d0), SkBits2Float(0xc2700000), SkBits2Float(0x3673fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41d4a5d9), SkBits2Float(0xc29d41d4));
+path.cubicTo(SkBits2Float(0x41db7bbd), SkBits2Float(0xc29cadef), SkBits2Float(0x41e247df), SkBits2Float(0xc29c12ec), SkBits2Float(0x41e9098d), SkBits2Float(0xc29b70d9));
+path.lineTo(SkBits2Float(0x41a875f1), SkBits2Float(0xc260bbd5));
+path.cubicTo(SkBits2Float(0x41a39393), SkBits2Float(0xc261a627), SkBits2Float(0x419ea9a6), SkBits2Float(0xc2628645), SkBits2Float(0x4199b8ab), SkBits2Float(0xc2635c17));
+path.lineTo(SkBits2Float(0x41d4a5d9), SkBits2Float(0xc29d41d4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp80(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e15a675), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e95a67a), SkBits2Float(0xc2a5ffcd), SkBits2Float(0x3ee07980), SkBits2Float(0xc2a5ff68));
+path.lineTo(SkBits2Float(0x3ea245bb), SkBits2Float(0xc26fff25));
+path.cubicTo(SkBits2Float(0x3e585de0), SkBits2Float(0xc26fffb9), SkBits2Float(0x3dd85f11), SkBits2Float(0xc2700000), SkBits2Float(0x3691e768), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ee07a10), SkBits2Float(0xc2a5ff68));
+path.cubicTo(SkBits2Float(0x3ee7f565), SkBits2Float(0xc2a5ff5d), SkBits2Float(0x3eef70d9), SkBits2Float(0xc2a5ff52), SkBits2Float(0x3ef6ec4d), SkBits2Float(0xc2a5ff47));
+path.lineTo(SkBits2Float(0x3eb27fdb), SkBits2Float(0xc26ffef6));
+path.cubicTo(SkBits2Float(0x3ead1768), SkBits2Float(0xc26fff07), SkBits2Float(0x3ea7aebe), SkBits2Float(0xc26fff17), SkBits2Float(0x3ea24612), SkBits2Float(0xc26fff26));
+path.lineTo(SkBits2Float(0x3ee07a10), SkBits2Float(0xc2a5ff68));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp81(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3691e768), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e15a675), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e95a67a), SkBits2Float(0xc2a5ffcd), SkBits2Float(0x3ee07a10), SkBits2Float(0xc2a5ff68));
+path.lineTo(SkBits2Float(0x3ef6ec4d), SkBits2Float(0xc2a5ff47));
+path.lineTo(SkBits2Float(0x3eb27fdb), SkBits2Float(0xc26ffef6));
+path.cubicTo(SkBits2Float(0x3ead1768), SkBits2Float(0xc26fff07), SkBits2Float(0x3ea7aebe), SkBits2Float(0xc26fff17), SkBits2Float(0x3ea245bb), SkBits2Float(0xc26fff25));
+path.cubicTo(SkBits2Float(0x3e585de0), SkBits2Float(0xc26fffb9), SkBits2Float(0x3dd85f11), SkBits2Float(0xc2700000), SkBits2Float(0x3691e768), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ef6ec9b), SkBits2Float(0xc2a5ff48));
+path.cubicTo(SkBits2Float(0x3f3816c9), SkBits2Float(0xc2a5fe94), SkBits2Float(0x3f74b6e1), SkBits2Float(0xc2a5fd5b), SkBits2Float(0x3f98ab0b), SkBits2Float(0xc2a5fb9d));
+path.lineTo(SkBits2Float(0x3f5cb973), SkBits2Float(0xc26ff9a8));
+path.cubicTo(SkBits2Float(0x3f30e6e7), SkBits2Float(0xc26ffc2e), SkBits2Float(0x3f05138e), SkBits2Float(0xc26ffdf2), SkBits2Float(0x3eb27fc6), SkBits2Float(0xc26ffef7));
+path.lineTo(SkBits2Float(0x3ef6ec9b), SkBits2Float(0xc2a5ff48));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp82(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3eff98a5), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f7f97b3), SkBits2Float(0xc2a5fdb1), SkBits2Float(0x3fbfaf38), SkBits2Float(0xc2a5f914));
+path.lineTo(SkBits2Float(0x3f8a9112), SkBits2Float(0xc26ff600));
+path.cubicTo(SkBits2Float(0x3f38c3e7), SkBits2Float(0xc26ffcab), SkBits2Float(0x3eb8c475), SkBits2Float(0xc2700000), SkBits2Float(0x35877d28), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fbfaf15), SkBits2Float(0xc2a5f915));
+path.cubicTo(SkBits2Float(0x3fc612b4), SkBits2Float(0xc2a5f8a0), SkBits2Float(0x3fcc7634), SkBits2Float(0xc2a5f824), SkBits2Float(0x3fd2d9ad), SkBits2Float(0xc2a5f7a2));
+path.lineTo(SkBits2Float(0x3f986bef), SkBits2Float(0xc26ff3e6));
+path.cubicTo(SkBits2Float(0x3f93cdb9), SkBits2Float(0xc26ff4a2), SkBits2Float(0x3f8f2f70), SkBits2Float(0xc26ff556), SkBits2Float(0x3f8a9121), SkBits2Float(0xc26ff601));
+path.lineTo(SkBits2Float(0x3fbfaf15), SkBits2Float(0xc2a5f915));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp83(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3eff9875), SkBits2Float(0xc2a60000), SkBits2Float(0x3f7f9783), SkBits2Float(0xc2a5fdb1), SkBits2Float(0x3fbfaf14), SkBits2Float(0xc2a5f914));
+path.lineTo(SkBits2Float(0x3fbfaf15), SkBits2Float(0xc2a5f915));
+path.cubicTo(SkBits2Float(0x3fc612b4), SkBits2Float(0xc2a5f8a0), SkBits2Float(0x3fcc7634), SkBits2Float(0xc2a5f824), SkBits2Float(0x3fd2d9ad), SkBits2Float(0xc2a5f7a2));
+path.lineTo(SkBits2Float(0x3f986bef), SkBits2Float(0xc26ff3e6));
+path.cubicTo(SkBits2Float(0x3f93cdb9), SkBits2Float(0xc26ff4a2), SkBits2Float(0x3f8f2f70), SkBits2Float(0xc26ff556), SkBits2Float(0x3f8a9112), SkBits2Float(0xc26ff600));
+path.cubicTo(SkBits2Float(0x3f38c3e7), SkBits2Float(0xc26ffcab), SkBits2Float(0x3eb8c475), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fd2d994), SkBits2Float(0xc2a5f7a1));
+path.cubicTo(SkBits2Float(0x401d305c), SkBits2Float(0xc2a5ef69), SkBits2Float(0x4050ef71), SkBits2Float(0xc2a5e123), SkBits2Float(0x408252dc), SkBits2Float(0xc2a5ccd0));
+path.lineTo(SkBits2Float(0x403c6b7d), SkBits2Float(0xc26fb5fe));
+path.cubicTo(SkBits2Float(0x401709a2), SkBits2Float(0xc26fd362), SkBits2Float(0x3fe342dd), SkBits2Float(0xc26fe805), SkBits2Float(0x3f986be0), SkBits2Float(0xc26ff3e7));
+path.lineTo(SkBits2Float(0x3fd2d994), SkBits2Float(0xc2a5f7a1));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp84(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f541e8b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3fd41d19), SkBits2Float(0xc2a5f9a6), SkBits2Float(0x401f1022), SkBits2Float(0xc2a5ecf2));
+path.lineTo(SkBits2Float(0x3fe5f882), SkBits2Float(0xc26fe473));
+path.cubicTo(SkBits2Float(0x3f9955cf), SkBits2Float(0xc26ff6d2), SkBits2Float(0x3f1956dc), SkBits2Float(0xc2700000), SkBits2Float(0xb5bb02d8), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x401f1027), SkBits2Float(0xc2a5ecf2));
+path.cubicTo(SkBits2Float(0x40245d21), SkBits2Float(0xc2a5ebac), SkBits2Float(0x4029aa04), SkBits2Float(0xc2a5ea57), SkBits2Float(0x402ef6d6), SkBits2Float(0xc2a5e8f1));
+path.lineTo(SkBits2Float(0x3ffcf5ba), SkBits2Float(0xc26fdeaa));
+path.cubicTo(SkBits2Float(0x3ff54c2d), SkBits2Float(0xc26fe0b0), SkBits2Float(0x3feda268), SkBits2Float(0xc26fe29e), SkBits2Float(0x3fe5f88e), SkBits2Float(0xc26fe474));
+path.lineTo(SkBits2Float(0x401f1027), SkBits2Float(0xc2a5ecf2));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp85(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f541e8b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3fd41d19), SkBits2Float(0xc2a5f9a6), SkBits2Float(0x401f1027), SkBits2Float(0xc2a5ecf2));
+path.cubicTo(SkBits2Float(0x40245d21), SkBits2Float(0xc2a5ebac), SkBits2Float(0x4029aa04), SkBits2Float(0xc2a5ea57), SkBits2Float(0x402ef6d6), SkBits2Float(0xc2a5e8f1));
+path.lineTo(SkBits2Float(0x3ffcf5ba), SkBits2Float(0xc26fdeaa));
+path.cubicTo(SkBits2Float(0x3ff54c2d), SkBits2Float(0xc26fe0b0), SkBits2Float(0x3feda268), SkBits2Float(0xc26fe29e), SkBits2Float(0x3fe5f882), SkBits2Float(0xc26fe473));
+path.cubicTo(SkBits2Float(0x3f9955cf), SkBits2Float(0xc26ff6d2), SkBits2Float(0x3f1956dc), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x402ef6c3), SkBits2Float(0xc2a5e8f1));
+path.cubicTo(SkBits2Float(0x40826d68), SkBits2Float(0xc2a5d24c), SkBits2Float(0x40ad550a), SkBits2Float(0xc2a5aafb), SkBits2Float(0x40d82890), SkBits2Float(0xc2a57308));
+path.lineTo(SkBits2Float(0x409c425c), SkBits2Float(0xc26f3430));
+path.cubicTo(SkBits2Float(0x407a99d8), SkBits2Float(0xc26f8515), SkBits2Float(0x403c91e6), SkBits2Float(0xc26fbded), SkBits2Float(0x3ffcf5ca), SkBits2Float(0xc26fdeaa));
+path.lineTo(SkBits2Float(0x402ef6c3), SkBits2Float(0xc2a5e8f1));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp86(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40155bee), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40955364), SkBits2Float(0xc2a5cd99), SkBits2Float(0x40dfbd5f), SkBits2Float(0xc2a568f2));
+path.lineTo(SkBits2Float(0x40a1bd53), SkBits2Float(0xc26f259d));
+path.cubicTo(SkBits2Float(0x4057e483), SkBits2Float(0xc26fb724), SkBits2Float(0x3fd7f0d9), SkBits2Float(0xc2700000), SkBits2Float(0x3619fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40dfbd5e), SkBits2Float(0xc2a568f3));
+path.cubicTo(SkBits2Float(0x40e72e1b), SkBits2Float(0xc2a55ee2), SkBits2Float(0x40ee9e1c), SkBits2Float(0xc2a55452), SkBits2Float(0x40f60d62), SkBits2Float(0xc2a54941));
+path.lineTo(SkBits2Float(0x40b1de84), SkBits2Float(0xc26ef7c9));
+path.cubicTo(SkBits2Float(0x40ac7ea0), SkBits2Float(0xc26f07cb), SkBits2Float(0x40a71e37), SkBits2Float(0xc26f1712), SkBits2Float(0x40a1bd4f), SkBits2Float(0xc26f259f));
+path.lineTo(SkBits2Float(0x40dfbd5e), SkBits2Float(0xc2a568f3));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp87(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3619fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40155bee), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40955364), SkBits2Float(0xc2a5cd99), SkBits2Float(0x40dfbd5e), SkBits2Float(0xc2a568f3));
+path.cubicTo(SkBits2Float(0x40e72e1b), SkBits2Float(0xc2a55ee2), SkBits2Float(0x40ee9e1c), SkBits2Float(0xc2a55452), SkBits2Float(0x40f60d62), SkBits2Float(0xc2a54941));
+path.lineTo(SkBits2Float(0x40b1de84), SkBits2Float(0xc26ef7c9));
+path.cubicTo(SkBits2Float(0x40ac7ea2), SkBits2Float(0xc26f07cb), SkBits2Float(0x40a71e3a), SkBits2Float(0xc26f1712), SkBits2Float(0x40a1bd54), SkBits2Float(0xc26f259f));
+path.lineTo(SkBits2Float(0x40a1bd53), SkBits2Float(0xc26f259d));
+path.cubicTo(SkBits2Float(0x4057e483), SkBits2Float(0xc26fb724), SkBits2Float(0x3fd7f0d9), SkBits2Float(0xc2700000), SkBits2Float(0x3619fea3), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40f60d69), SkBits2Float(0xc2a54941));
+path.cubicTo(SkBits2Float(0x41374a21), SkBits2Float(0xc2a495d5), SkBits2Float(0x41731962), SkBits2Float(0xc2a35eca), SkBits2Float(0x419704b1), SkBits2Float(0xc2a1a64c));
+path.lineTo(SkBits2Float(0x415a56f5), SkBits2Float(0xc269b5d4));
+path.cubicTo(SkBits2Float(0x412fbbfb), SkBits2Float(0xc26c32af), SkBits2Float(0x41047f9a), SkBits2Float(0xc26df463), SkBits2Float(0x40b1de7e), SkBits2Float(0xc26ef7cb));
+path.lineTo(SkBits2Float(0x40f60d69), SkBits2Float(0xc2a54941));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp88(skiatest::Reporter* reporter, const char* filename) {  // crashed
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4059d383), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40d9b918), SkBits2Float(0xc2a594d0), SkBits2Float(0x4122e820), SkBits2Float(0xc2a4bf0c));
+path.lineTo(SkBits2Float(0x40eb871c), SkBits2Float(0xc26e2ff8));
+path.cubicTo(SkBits2Float(0x409d63e0), SkBits2Float(0xc26f6508), SkBits2Float(0x401d76fa), SkBits2Float(0xc2700000), SkBits2Float(0x35f7fd4a), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4122e81e), SkBits2Float(0xc2a4bf0c));
+path.cubicTo(SkBits2Float(0x41284f3c), SkBits2Float(0xc2a4a9ac), SkBits2Float(0x412db549), SkBits2Float(0xc2a4933e), SkBits2Float(0x41331a33), SkBits2Float(0xc2a47bbf));
+path.lineTo(SkBits2Float(0x410178be), SkBits2Float(0xc26dceac));
+path.cubicTo(SkBits2Float(0x40fb24f7), SkBits2Float(0xc26df0a4), SkBits2Float(0x40f356d1), SkBits2Float(0xc26e1114), SkBits2Float(0x40eb871f), SkBits2Float(0xc26e2ff8));
+path.lineTo(SkBits2Float(0x4122e81e), SkBits2Float(0xc2a4bf0c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp89(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3dd41fb8), SkBits2Float(0xc2a5fffe), SkBits2Float(0x3e541e5b), SkBits2Float(0xc2a5ffe5), SkBits2Float(0x3e9f1657), SkBits2Float(0xc2a5ffb2));
+path.lineTo(SkBits2Float(0x3e66012b), SkBits2Float(0xc26fff92));
+path.cubicTo(SkBits2Float(0x3e1955e2), SkBits2Float(0xc26fffdc), SkBits2Float(0x3d99560b), SkBits2Float(0xc2700000), SkBits2Float(0x350f7780), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3e9f1626), SkBits2Float(0xc2a5ffb4));
+path.cubicTo(SkBits2Float(0x3ea463a8), SkBits2Float(0xc2a5ffae), SkBits2Float(0x3ea9b10b), SkBits2Float(0xc2a5ffa8), SkBits2Float(0x3eaefe6d), SkBits2Float(0xc2a5ffa3));
+path.lineTo(SkBits2Float(0x3e7d0144), SkBits2Float(0xc26fff7b));
+path.cubicTo(SkBits2Float(0x3e75568f), SkBits2Float(0xc26fff84), SkBits2Float(0x3e6dac12), SkBits2Float(0xc26fff8c), SkBits2Float(0x3e660197), SkBits2Float(0xc26fff93));
+path.lineTo(SkBits2Float(0x3e9f1626), SkBits2Float(0xc2a5ffb4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp90(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3dd41f74), SkBits2Float(0xc2a5fffe), SkBits2Float(0x3e541e17), SkBits2Float(0xc2a5ffe5), SkBits2Float(0x3e9f1624), SkBits2Float(0xc2a5ffb2));
+path.lineTo(SkBits2Float(0x3e9f1626), SkBits2Float(0xc2a5ffb4));
+path.cubicTo(SkBits2Float(0x3ea463a8), SkBits2Float(0xc2a5ffae), SkBits2Float(0x3ea9b10b), SkBits2Float(0xc2a5ffa8), SkBits2Float(0x3eaefe6d), SkBits2Float(0xc2a5ffa3));
+path.lineTo(SkBits2Float(0x3e7d0144), SkBits2Float(0xc26fff7b));
+path.cubicTo(SkBits2Float(0x3e75568f), SkBits2Float(0xc26fff84), SkBits2Float(0x3e6dac12), SkBits2Float(0xc26fff8c), SkBits2Float(0x3e66012b), SkBits2Float(0xc26fff92));
+path.cubicTo(SkBits2Float(0x3e1955e2), SkBits2Float(0xc26fffdc), SkBits2Float(0x3d99560b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3eaefebc), SkBits2Float(0xc2a5ffa4));
+path.cubicTo(SkBits2Float(0x3f0276b7), SkBits2Float(0xc2a5ff4a), SkBits2Float(0x3f2d6dea), SkBits2Float(0xc2a5feac), SkBits2Float(0x3f5864cc), SkBits2Float(0xc2a5fdcd));
+path.lineTo(SkBits2Float(0x3f1c6df6), SkBits2Float(0xc26ffcd0));
+path.cubicTo(SkBits2Float(0x3efabdec), SkBits2Float(0xc26ffe15), SkBits2Float(0x3ebc9f78), SkBits2Float(0xc26ffef9), SkBits2Float(0x3e7d0190), SkBits2Float(0xc26fff7c));
+path.lineTo(SkBits2Float(0x3eaefebc), SkBits2Float(0xc2a5ffa4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp91(skiatest::Reporter* reporter, const char* filename) {  // crashed
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ec1e1ad), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f41e136), SkBits2Float(0xc2a5feac), SkBits2Float(0x3f9167c6), SkBits2Float(0xc2a5fc05));
+path.lineTo(SkBits2Float(0x3f523979), SkBits2Float(0xc26ffa3f));
+path.cubicTo(SkBits2Float(0x3f0c2737), SkBits2Float(0xc26ffe17), SkBits2Float(0x3e8c2756), SkBits2Float(0xc2700000), SkBits2Float(0xb5b74260), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f9167c1), SkBits2Float(0xc2a5fc05));
+path.cubicTo(SkBits2Float(0x3f96406f), SkBits2Float(0xc2a5fbc1), SkBits2Float(0x3f9b1917), SkBits2Float(0xc2a5fb79), SkBits2Float(0x3f9ff1bc), SkBits2Float(0xc2a5fb2f));
+path.lineTo(SkBits2Float(0x3f673ed7), SkBits2Float(0xc26ff909));
+path.cubicTo(SkBits2Float(0x3f603cf4), SkBits2Float(0xc26ff977), SkBits2Float(0x3f593b3c), SkBits2Float(0xc26ff9dd), SkBits2Float(0x3f52397f), SkBits2Float(0xc26ffa3f));
+path.lineTo(SkBits2Float(0x3f9167c1), SkBits2Float(0xc2a5fc05));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp92(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e2c5962), SkBits2Float(0xc2a60000), SkBits2Float(0x3eac58ef), SkBits2Float(0xc2a5ffbd), SkBits2Float(0x3f014269), SkBits2Float(0xc2a5ff37));
+path.lineTo(SkBits2Float(0x3ebae1ca), SkBits2Float(0xc26ffedd));
+path.cubicTo(SkBits2Float(0x3e792d51), SkBits2Float(0xc26fff9f), SkBits2Float(0x3df92dfa), SkBits2Float(0xc2700000), SkBits2Float(0x36163ed0), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f014292), SkBits2Float(0xc2a5ff37));
+path.cubicTo(SkBits2Float(0x3f0591a2), SkBits2Float(0xc2a5ff28), SkBits2Float(0x3f09e09b), SkBits2Float(0xc2a5ff1a), SkBits2Float(0x3f0e2f92), SkBits2Float(0xc2a5ff0b));
+path.lineTo(SkBits2Float(0x3ecd91e5), SkBits2Float(0xc26ffea0));
+path.cubicTo(SkBits2Float(0x3ec75718), SkBits2Float(0xc26ffeb6), SkBits2Float(0x3ec11c70), SkBits2Float(0xc26ffeca), SkBits2Float(0x3ebae1c7), SkBits2Float(0xc26ffedd));
+path.lineTo(SkBits2Float(0x3f014292), SkBits2Float(0xc2a5ff37));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp93(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36163ed0), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.quadTo(SkBits2Float(0x3e81430a), SkBits2Float(0xc2a60000), SkBits2Float(0x3f014292), SkBits2Float(0xc2a5ff37));
+path.cubicTo(SkBits2Float(0x3f0591a2), SkBits2Float(0xc2a5ff28), SkBits2Float(0x3f09e09b), SkBits2Float(0xc2a5ff1a), SkBits2Float(0x3f0e2f92), SkBits2Float(0xc2a5ff0b));
+path.lineTo(SkBits2Float(0x3ecd91e5), SkBits2Float(0xc26ffea0));
+path.cubicTo(SkBits2Float(0x3ec75719), SkBits2Float(0xc26ffeb6), SkBits2Float(0x3ec11c72), SkBits2Float(0xc26ffeca), SkBits2Float(0x3ebae1ca), SkBits2Float(0xc26ffedd));
+path.quadTo(SkBits2Float(0x3e3ae230), SkBits2Float(0xc2700000), SkBits2Float(0x36163ed0), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f0e2f94), SkBits2Float(0xc2a5ff0c));
+path.cubicTo(SkBits2Float(0x3f5401b9), SkBits2Float(0xc2a5fe1c), SkBits2Float(0x3f8ce9a3), SkBits2Float(0xc2a5fc7d), SkBits2Float(0x3fafd1bd), SkBits2Float(0xc2a5fa2d));
+path.lineTo(SkBits2Float(0x3f7e3238), SkBits2Float(0xc26ff796));
+path.cubicTo(SkBits2Float(0x3f4bbaca), SkBits2Float(0xc26ffaee), SkBits2Float(0x3f194226), SkBits2Float(0xc26ffd46), SkBits2Float(0x3ecd9202), SkBits2Float(0xc26ffea0));
+path.lineTo(SkBits2Float(0x3f0e2f94), SkBits2Float(0xc2a5ff0c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp94(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f167e4a), SkBits2Float(0xc2a60000), SkBits2Float(0x3f967d97), SkBits2Float(0xc2a5fcce), SkBits2Float(0x3fe1b83b), SkBits2Float(0xc2a5f668));
+path.lineTo(SkBits2Float(0x3fa32ba2), SkBits2Float(0xc26ff222));
+path.cubicTo(SkBits2Float(0x3f599370), SkBits2Float(0xc26ffb61), SkBits2Float(0x3ed9943c), SkBits2Float(0xc2700000), SkBits2Float(0x3437e940), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fe1b817), SkBits2Float(0xc2a5f668));
+path.cubicTo(SkBits2Float(0x3fe93dd6), SkBits2Float(0xc2a5f5c4), SkBits2Float(0x3ff0c3a7), SkBits2Float(0xc2a5f518), SkBits2Float(0x3ff8496b), SkBits2Float(0xc2a5f464));
+path.lineTo(SkBits2Float(0x3fb37c11), SkBits2Float(0xc26fef38));
+path.cubicTo(SkBits2Float(0x3fae0bf9), SkBits2Float(0xc26ff03c), SkBits2Float(0x3fa89bd2), SkBits2Float(0xc26ff134), SkBits2Float(0x3fa32ba2), SkBits2Float(0xc26ff222));
+path.lineTo(SkBits2Float(0x3fe1b817), SkBits2Float(0xc2a5f668));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp95(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f167e32), SkBits2Float(0xc2a60000), SkBits2Float(0x3f967d7f), SkBits2Float(0xc2a5fcce), SkBits2Float(0x3fe1b817), SkBits2Float(0xc2a5f668));
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ff8497f), SkBits2Float(0xc2a5f465));
+path.cubicTo(SkBits2Float(0x40391895), SkBits2Float(0xc2a5e8fe), SkBits2Float(0x407604f1), SkBits2Float(0xc2a5d533), SkBits2Float(0x40997177), SkBits2Float(0xc2a5b905));
+path.lineTo(SkBits2Float(0x405dd87f), SkBits2Float(0xc26f9962));
+path.cubicTo(SkBits2Float(0x4031d867), SkBits2Float(0xc26fc221), SkBits2Float(0x4005cdec), SkBits2Float(0xc26fdebf), SkBits2Float(0x3fb37c22), SkBits2Float(0xc26fef39));
+path.lineTo(SkBits2Float(0x3ff8497f), SkBits2Float(0xc2a5f465));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp96(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3fa966bb), SkBits2Float(0xc2a5ffff), SkBits2Float(0x402963a4), SkBits2Float(0xc2a5efcb), SkBits2Float(0x407dfe39), SkBits2Float(0xc2a5cf64));
+path.lineTo(SkBits2Float(0x40379c05), SkBits2Float(0xc26fb9ba));
+path.cubicTo(SkBits2Float(0x3ff4e689), SkBits2Float(0xc26fe893), SkBits2Float(0x3f74eb1f), SkBits2Float(0xc2700000), SkBits2Float(0x363f7e94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x407dfe3a), SkBits2Float(0xc2a5cf65));
+path.cubicTo(SkBits2Float(0x40833a01), SkBits2Float(0xc2a5cc27), SkBits2Float(0x408774bf), SkBits2Float(0xc2a5c8c0), SkBits2Float(0x408baf5a), SkBits2Float(0xc2a5c52f));
+path.lineTo(SkBits2Float(0x4049f448), SkBits2Float(0xc26faaf9));
+path.cubicTo(SkBits2Float(0x4043d713), SkBits2Float(0xc26fb022), SkBits2Float(0x403db99f), SkBits2Float(0xc26fb50d), SkBits2Float(0x40379bfe), SkBits2Float(0xc26fb9bc));
+path.lineTo(SkBits2Float(0x407dfe3a), SkBits2Float(0xc2a5cf65));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp97(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x363f7e94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3fa966bb), SkBits2Float(0xc2a5ffff), SkBits2Float(0x402963a4), SkBits2Float(0xc2a5efcb), SkBits2Float(0x407dfe3a), SkBits2Float(0xc2a5cf65));
+path.cubicTo(SkBits2Float(0x40833a01), SkBits2Float(0xc2a5cc27), SkBits2Float(0x408774bf), SkBits2Float(0xc2a5c8c0), SkBits2Float(0x408baf5a), SkBits2Float(0xc2a5c52f));
+path.lineTo(SkBits2Float(0x4049f448), SkBits2Float(0xc26faaf9));
+path.cubicTo(SkBits2Float(0x4043d716), SkBits2Float(0xc26fb022), SkBits2Float(0x403db9a5), SkBits2Float(0xc26fb50d), SkBits2Float(0x40379c07), SkBits2Float(0xc26fb9bc));
+path.lineTo(SkBits2Float(0x40379c05), SkBits2Float(0xc26fb9ba));
+path.cubicTo(SkBits2Float(0x3ff4e689), SkBits2Float(0xc26fe893), SkBits2Float(0x3f74eb1f), SkBits2Float(0xc2700000), SkBits2Float(0x363f7e94), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x408baf5c), SkBits2Float(0xc2a5c530));
+path.cubicTo(SkBits2Float(0x40d03963), SkBits2Float(0xc2a58b6e), SkBits2Float(0x410a4c7d), SkBits2Float(0xc2a52732), SkBits2Float(0x412c535f), SkBits2Float(0xc2a498b2));
+path.lineTo(SkBits2Float(0x40f9253d), SkBits2Float(0xc26df886));
+path.cubicTo(SkBits2Float(0x40c7f32d), SkBits2Float(0xc26ec68d), SkBits2Float(0x409685fb), SkBits2Float(0xc26f577a), SkBits2Float(0x4049f441), SkBits2Float(0xc26faafa));
+path.lineTo(SkBits2Float(0x408baf5c), SkBits2Float(0xc2a5c530));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp98(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40155bee), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40955364), SkBits2Float(0xc2a5cd99), SkBits2Float(0x40dfbd5f), SkBits2Float(0xc2a568f2));
+path.lineTo(SkBits2Float(0x40a1bd53), SkBits2Float(0xc26f259d));
+path.cubicTo(SkBits2Float(0x4057e483), SkBits2Float(0xc26fb724), SkBits2Float(0x3fd7f0d9), SkBits2Float(0xc2700000), SkBits2Float(0x3619fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40dfbd5e), SkBits2Float(0xc2a568f3));
+path.cubicTo(SkBits2Float(0x40e72e1b), SkBits2Float(0xc2a55ee2), SkBits2Float(0x40ee9e1c), SkBits2Float(0xc2a55452), SkBits2Float(0x40f60d62), SkBits2Float(0xc2a54941));
+path.lineTo(SkBits2Float(0x40b1de84), SkBits2Float(0xc26ef7c9));
+path.cubicTo(SkBits2Float(0x40ac7ea0), SkBits2Float(0xc26f07cb), SkBits2Float(0x40a71e37), SkBits2Float(0xc26f1712), SkBits2Float(0x40a1bd4f), SkBits2Float(0xc26f259f));
+path.lineTo(SkBits2Float(0x40dfbd5e), SkBits2Float(0xc2a568f3));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp99(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3619fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40155bee), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40955364), SkBits2Float(0xc2a5cd99), SkBits2Float(0x40dfbd5e), SkBits2Float(0xc2a568f3));
+path.cubicTo(SkBits2Float(0x40e72e1b), SkBits2Float(0xc2a55ee2), SkBits2Float(0x40ee9e1c), SkBits2Float(0xc2a55452), SkBits2Float(0x40f60d62), SkBits2Float(0xc2a54941));
+path.lineTo(SkBits2Float(0x40b1de84), SkBits2Float(0xc26ef7c9));
+path.cubicTo(SkBits2Float(0x40ac7ea2), SkBits2Float(0xc26f07cb), SkBits2Float(0x40a71e3a), SkBits2Float(0xc26f1712), SkBits2Float(0x40a1bd54), SkBits2Float(0xc26f259f));
+path.lineTo(SkBits2Float(0x40a1bd53), SkBits2Float(0xc26f259d));
+path.cubicTo(SkBits2Float(0x4057e483), SkBits2Float(0xc26fb724), SkBits2Float(0x3fd7f0d9), SkBits2Float(0xc2700000), SkBits2Float(0x3619fea3), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40f60d69), SkBits2Float(0xc2a54941));
+path.cubicTo(SkBits2Float(0x41374a21), SkBits2Float(0xc2a495d5), SkBits2Float(0x41731962), SkBits2Float(0xc2a35eca), SkBits2Float(0x419704b1), SkBits2Float(0xc2a1a64c));
+path.lineTo(SkBits2Float(0x415a56f5), SkBits2Float(0xc269b5d4));
+path.cubicTo(SkBits2Float(0x412fbbfb), SkBits2Float(0xc26c32af), SkBits2Float(0x41047f9a), SkBits2Float(0xc26df463), SkBits2Float(0x40b1de7e), SkBits2Float(0xc26ef7cb));
+path.lineTo(SkBits2Float(0x40f60d69), SkBits2Float(0xc2a54941));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp100(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x403cde0b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40bcccc9), SkBits2Float(0xc2a5af6a), SkBits2Float(0x410d5936), SkBits2Float(0xc2a50e98));
+path.lineTo(SkBits2Float(0x40cc5bf6), SkBits2Float(0xc26ea2fc));
+path.cubicTo(SkBits2Float(0x40887b5e), SkBits2Float(0xc26f8b7f), SkBits2Float(0x400887d8), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x410d5935), SkBits2Float(0xc2a50e99));
+path.cubicTo(SkBits2Float(0x41120ace), SkBits2Float(0xc2a4fe85), SkBits2Float(0x4116bbb5), SkBits2Float(0xc2a4eda4), SkBits2Float(0x411b6bdd), SkBits2Float(0xc2a4dbf6));
+path.lineTo(SkBits2Float(0x40e0b4a3), SkBits2Float(0xc26e59c7));
+path.cubicTo(SkBits2Float(0x40d9ed7a), SkBits2Float(0xc26e7357), SkBits2Float(0x40d32536), SkBits2Float(0xc26e8bbe), SkBits2Float(0x40cc5bf1), SkBits2Float(0xc26ea2fc));
+path.lineTo(SkBits2Float(0x410d5935), SkBits2Float(0xc2a50e99));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end fail 1
+
+static void battleOp101(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x406db78d), SkBits2Float(0xc2a60000), SkBits2Float(0x40ed953d), SkBits2Float(0xc2a58058), SkBits2Float(0x4131afb7), SkBits2Float(0xc2a481e4));
+path.lineTo(SkBits2Float(0x410072b2), SkBits2Float(0xc26dd78e));
+path.cubicTo(SkBits2Float(0x40abbf2e), SkBits2Float(0xc26f4770), SkBits2Float(0x402bd807), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4131afba), SkBits2Float(0xc2a481e4));
+path.cubicTo(SkBits2Float(0x413792dd), SkBits2Float(0xc2a46874), SkBits2Float(0x413d74a2), SkBits2Float(0xc2a44dc1), SkBits2Float(0x414354e9), SkBits2Float(0xc2a431ca));
+path.lineTo(SkBits2Float(0x410d3424), SkBits2Float(0xc26d63c0));
+path.cubicTo(SkBits2Float(0x4108f4b6), SkBits2Float(0xc26d8c2e), SkBits2Float(0x4104b435), SkBits2Float(0xc26db2c8), SkBits2Float(0x410072b4), SkBits2Float(0xc26dd78e));
+path.lineTo(SkBits2Float(0x4131afba), SkBits2Float(0xc2a481e4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp102(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x406db78d), SkBits2Float(0xc2a60000), SkBits2Float(0x40ed953d), SkBits2Float(0xc2a58058), SkBits2Float(0x4131afba), SkBits2Float(0xc2a481e4));
+path.cubicTo(SkBits2Float(0x413792dd), SkBits2Float(0xc2a46874), SkBits2Float(0x413d74a2), SkBits2Float(0xc2a44dc1), SkBits2Float(0x414354e9), SkBits2Float(0xc2a431ca));
+path.lineTo(SkBits2Float(0x410d3424), SkBits2Float(0xc26d63c0));
+path.cubicTo(SkBits2Float(0x4108f4b6), SkBits2Float(0xc26d8c2e), SkBits2Float(0x4104b435), SkBits2Float(0xc26db2c8), SkBits2Float(0x410072b2), SkBits2Float(0xc26dd78e));
+path.cubicTo(SkBits2Float(0x40abbf2e), SkBits2Float(0xc26f4770), SkBits2Float(0x402bd807), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x414354ed), SkBits2Float(0xc2a431cb));
+path.cubicTo(SkBits2Float(0x419152e5), SkBits2Float(0xc2a26c3a), SkBits2Float(0x41c0119b), SkBits2Float(0xc29f5c06), SkBits2Float(0x41ed1335), SkBits2Float(0xc29b0f0a));
+path.lineTo(SkBits2Float(0x41ab612b), SkBits2Float(0xc2602e6b));
+path.cubicTo(SkBits2Float(0x418ad84d), SkBits2Float(0xc2666635), SkBits2Float(0x41521b54), SkBits2Float(0xc26ad3fe), SkBits2Float(0x410d3426), SkBits2Float(0xc26d63c0));
+path.lineTo(SkBits2Float(0x414354ed), SkBits2Float(0xc2a431cb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp103(skiatest::Reporter* reporter, const char* filename) {  //crash
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x408e2d73), SkBits2Float(0xc2a5ffff), SkBits2Float(0x410e100a), SkBits2Float(0xc2a54957), SkBits2Float(0x41543cd2), SkBits2Float(0xc2a3ddc8));
+path.lineTo(SkBits2Float(0x41196cba), SkBits2Float(0xc26cea49));
+path.cubicTo(SkBits2Float(0x40cd643f), SkBits2Float(0xc26ef7e9), SkBits2Float(0x404d8eb8), SkBits2Float(0xc26fffff), SkBits2Float(0xb5ac02ba), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41543cce), SkBits2Float(0xc2a3ddc8));
+path.cubicTo(SkBits2Float(0x415b4057), SkBits2Float(0xc2a3b973), SkBits2Float(0x41624181), SkBits2Float(0xc2a39350), SkBits2Float(0x41694022), SkBits2Float(0xc2a36b60));
+path.lineTo(SkBits2Float(0x41289d63), SkBits2Float(0xc26c44e1));
+path.cubicTo(SkBits2Float(0x41238ef8), SkBits2Float(0xc26c7e9e), SkBits2Float(0x411e7eb5), SkBits2Float(0xc26cb5c1), SkBits2Float(0x41196cbd), SkBits2Float(0xc26cea4a));
+path.lineTo(SkBits2Float(0x41543cce), SkBits2Float(0xc2a3ddc8));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp104(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3dd41fb8), SkBits2Float(0xc2a5fffe), SkBits2Float(0x3e541e5b), SkBits2Float(0xc2a5ffe5), SkBits2Float(0x3e9f1657), SkBits2Float(0xc2a5ffb2));
+path.lineTo(SkBits2Float(0x3e66012b), SkBits2Float(0xc26fff92));
+path.cubicTo(SkBits2Float(0x3e1955e2), SkBits2Float(0xc26fffdc), SkBits2Float(0x3d99560b), SkBits2Float(0xc2700000), SkBits2Float(0x350f7780), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3e9f1626), SkBits2Float(0xc2a5ffb4));
+path.cubicTo(SkBits2Float(0x3ea463a8), SkBits2Float(0xc2a5ffae), SkBits2Float(0x3ea9b10b), SkBits2Float(0xc2a5ffa8), SkBits2Float(0x3eaefe6d), SkBits2Float(0xc2a5ffa3));
+path.lineTo(SkBits2Float(0x3e7d0144), SkBits2Float(0xc26fff7b));
+path.cubicTo(SkBits2Float(0x3e75568f), SkBits2Float(0xc26fff84), SkBits2Float(0x3e6dac12), SkBits2Float(0xc26fff8c), SkBits2Float(0x3e660197), SkBits2Float(0xc26fff93));
+path.lineTo(SkBits2Float(0x3e9f1626), SkBits2Float(0xc2a5ffb4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp105(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3dd41f74), SkBits2Float(0xc2a5fffe), SkBits2Float(0x3e541e17), SkBits2Float(0xc2a5ffe5), SkBits2Float(0x3e9f1624), SkBits2Float(0xc2a5ffb2));
+path.lineTo(SkBits2Float(0x3e9f1626), SkBits2Float(0xc2a5ffb4));
+path.cubicTo(SkBits2Float(0x3ea463a8), SkBits2Float(0xc2a5ffae), SkBits2Float(0x3ea9b10b), SkBits2Float(0xc2a5ffa8), SkBits2Float(0x3eaefe6d), SkBits2Float(0xc2a5ffa3));
+path.lineTo(SkBits2Float(0x3e7d0144), SkBits2Float(0xc26fff7b));
+path.cubicTo(SkBits2Float(0x3e75568f), SkBits2Float(0xc26fff84), SkBits2Float(0x3e6dac12), SkBits2Float(0xc26fff8c), SkBits2Float(0x3e66012b), SkBits2Float(0xc26fff92));
+path.cubicTo(SkBits2Float(0x3e1955e2), SkBits2Float(0xc26fffdc), SkBits2Float(0x3d99560b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3eaefebc), SkBits2Float(0xc2a5ffa4));
+path.cubicTo(SkBits2Float(0x3f0276b7), SkBits2Float(0xc2a5ff4a), SkBits2Float(0x3f2d6dea), SkBits2Float(0xc2a5feac), SkBits2Float(0x3f5864cc), SkBits2Float(0xc2a5fdcd));
+path.lineTo(SkBits2Float(0x3f1c6df6), SkBits2Float(0xc26ffcd0));
+path.cubicTo(SkBits2Float(0x3efabdec), SkBits2Float(0xc26ffe15), SkBits2Float(0x3ebc9f78), SkBits2Float(0xc26ffef9), SkBits2Float(0x3e7d0190), SkBits2Float(0xc26fff7c));
+path.lineTo(SkBits2Float(0x3eaefebc), SkBits2Float(0xc2a5ffa4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp106(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ee221f0), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f622166), SkBits2Float(0xc2a5fe31), SkBits2Float(0x3fa9974d), SkBits2Float(0xc2a5fa95));
+path.lineTo(SkBits2Float(0x3f753159), SkBits2Float(0xc26ff82c));
+path.cubicTo(SkBits2Float(0x3f237814), SkBits2Float(0xc26ffd64), SkBits2Float(0x3ea3787a), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa50), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fa99777), SkBits2Float(0xc2a5fa96));
+path.cubicTo(SkBits2Float(0x3faf3e7a), SkBits2Float(0xc2a5fa39), SkBits2Float(0x3fb4e596), SkBits2Float(0xc2a5f9d8), SkBits2Float(0x3fba8cad), SkBits2Float(0xc2a5f972));
+path.lineTo(SkBits2Float(0x3f86dad5), SkBits2Float(0xc26ff687));
+path.cubicTo(SkBits2Float(0x3f82c4d9), SkBits2Float(0xc26ff71a), SkBits2Float(0x3f7d5da4), SkBits2Float(0xc26ff7a6), SkBits2Float(0x3f753191), SkBits2Float(0xc26ff82c));
+path.lineTo(SkBits2Float(0x3fa99777), SkBits2Float(0xc2a5fa96));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp107(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ee221f0), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f622166), SkBits2Float(0xc2a5fe31), SkBits2Float(0x3fa99777), SkBits2Float(0xc2a5fa96));
+path.cubicTo(SkBits2Float(0x3faf3e7a), SkBits2Float(0xc2a5fa39), SkBits2Float(0x3fb4e596), SkBits2Float(0xc2a5f9d8), SkBits2Float(0x3fba8cad), SkBits2Float(0xc2a5f972));
+path.lineTo(SkBits2Float(0x3f86dad5), SkBits2Float(0xc26ff687));
+path.cubicTo(SkBits2Float(0x3f82c4d9), SkBits2Float(0xc26ff71a), SkBits2Float(0x3f7d5da4), SkBits2Float(0xc26ff7a6), SkBits2Float(0x3f753159), SkBits2Float(0xc26ff82c));
+path.cubicTo(SkBits2Float(0x3f237814), SkBits2Float(0xc26ffd64), SkBits2Float(0x3ea3787a), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fba8c96), SkBits2Float(0xc2a5f973));
+path.cubicTo(SkBits2Float(0x400b1301), SkBits2Float(0xc2a5f303), SkBits2Float(0x4038dc7e), SkBits2Float(0xc2a5e7d6), SkBits2Float(0x40669fe4), SkBits2Float(0xc2a5d7ed));
+path.lineTo(SkBits2Float(0x4026b765), SkBits2Float(0xc26fc611));
+path.cubicTo(SkBits2Float(0x4005a27d), SkBits2Float(0xc26fdd13), SkBits2Float(0x3fc9123c), SkBits2Float(0xc26fed3b), SkBits2Float(0x3f86daf1), SkBits2Float(0xc26ff689));
+path.lineTo(SkBits2Float(0x3fba8c96), SkBits2Float(0xc2a5f973));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp108(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f587304), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3fd8713e), SkBits2Float(0xc2a5f962), SkBits2Float(0x40224ed5), SkBits2Float(0xc2a5ec27));
+path.lineTo(SkBits2Float(0x3feaa996), SkBits2Float(0xc26fe350));
+path.cubicTo(SkBits2Float(0x3f9c76e4), SkBits2Float(0xc26ff671), SkBits2Float(0x3f1c780b), SkBits2Float(0xc2700000), SkBits2Float(0xb5510538), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40224ee4), SkBits2Float(0xc2a5ec28));
+path.cubicTo(SkBits2Float(0x4027b77a), SkBits2Float(0xc2a5ead6), SkBits2Float(0x402d1ffd), SkBits2Float(0xc2a5e972), SkBits2Float(0x4032886f), SkBits2Float(0xc2a5e7fe));
+path.lineTo(SkBits2Float(0x40010f64), SkBits2Float(0xc26fdd4a));
+path.cubicTo(SkBits2Float(0x3ffa4d23), SkBits2Float(0xc26fdf64), SkBits2Float(0x3ff27b6d), SkBits2Float(0xc26fe166), SkBits2Float(0x3feaa9a1), SkBits2Float(0xc26fe350));
+path.lineTo(SkBits2Float(0x40224ee4), SkBits2Float(0xc2a5ec28));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp109(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f587304), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3fd8713e), SkBits2Float(0xc2a5f962), SkBits2Float(0x40224ee4), SkBits2Float(0xc2a5ec28));
+path.cubicTo(SkBits2Float(0x4027b77a), SkBits2Float(0xc2a5ead6), SkBits2Float(0x402d1ffd), SkBits2Float(0xc2a5e972), SkBits2Float(0x4032886f), SkBits2Float(0xc2a5e7fe));
+path.lineTo(SkBits2Float(0x40010f64), SkBits2Float(0xc26fdd4a));
+path.cubicTo(SkBits2Float(0x3ffa4d23), SkBits2Float(0xc26fdf64), SkBits2Float(0x3ff27b6d), SkBits2Float(0xc26fe166), SkBits2Float(0x3feaa996), SkBits2Float(0xc26fe350));
+path.cubicTo(SkBits2Float(0x3f9c76e4), SkBits2Float(0xc26ff671), SkBits2Float(0x3f1c780b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4032887d), SkBits2Float(0xc2a5e7fe));
+path.cubicTo(SkBits2Float(0x4085166b), SkBits2Float(0xc2a5d069), SkBits2Float(0x40b0dd8e), SkBits2Float(0xc2a5a77a), SkBits2Float(0x40dc8f53), SkBits2Float(0xc2a56d38));
+path.lineTo(SkBits2Float(0x409f70d9), SkBits2Float(0xc26f2bca));
+path.cubicTo(SkBits2Float(0x407fb58c), SkBits2Float(0xc26f8005), SkBits2Float(0x40406a74), SkBits2Float(0xc26fbb35), SkBits2Float(0x40010f5f), SkBits2Float(0xc26fdd4b));
+path.lineTo(SkBits2Float(0x4032887d), SkBits2Float(0xc2a5e7fe));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp110(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x400cf1ae), SkBits2Float(0xc2a5ffff), SkBits2Float(0x408cea87), SkBits2Float(0xc2a5d31f), SkBits2Float(0x40d32a40), SkBits2Float(0xc2a57979));
+path.lineTo(SkBits2Float(0x4098a645), SkBits2Float(0xc26f3d83));
+path.cubicTo(SkBits2Float(0x404bbc01), SkBits2Float(0xc26fbf1e), SkBits2Float(0x3fcbc669), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff59), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40d32a46), SkBits2Float(0xc2a5797a));
+path.cubicTo(SkBits2Float(0x40da306e), SkBits2Float(0xc2a57083), SkBits2Float(0x40e135fe), SkBits2Float(0xc2a5671a), SkBits2Float(0x40e83aef), SkBits2Float(0xc2a55d3f));
+path.lineTo(SkBits2Float(0x40a7e090), SkBits2Float(0xc26f14b1));
+path.cubicTo(SkBits2Float(0x40a2cd8d), SkBits2Float(0xc26f22f4), SkBits2Float(0x409dba1d), SkBits2Float(0xc26f308e), SkBits2Float(0x4098a641), SkBits2Float(0xc26f3d84));
+path.lineTo(SkBits2Float(0x40d32a46), SkBits2Float(0xc2a5797a));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp111(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff59), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x400cf1ae), SkBits2Float(0xc2a5ffff), SkBits2Float(0x408cea87), SkBits2Float(0xc2a5d31f), SkBits2Float(0x40d32a46), SkBits2Float(0xc2a5797a));
+path.cubicTo(SkBits2Float(0x40da306e), SkBits2Float(0xc2a57083), SkBits2Float(0x40e135fe), SkBits2Float(0xc2a5671a), SkBits2Float(0x40e83aef), SkBits2Float(0xc2a55d3f));
+path.lineTo(SkBits2Float(0x40a7e090), SkBits2Float(0xc26f14b1));
+path.cubicTo(SkBits2Float(0x40a2cd8f), SkBits2Float(0xc26f22f4), SkBits2Float(0x409dba20), SkBits2Float(0xc26f308e), SkBits2Float(0x4098a645), SkBits2Float(0xc26f3d83));
+path.cubicTo(SkBits2Float(0x404bbc01), SkBits2Float(0xc26fbf1e), SkBits2Float(0x3fcbc669), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff59), SkBits2Float(0xc26fffff));
+path.close();
+path.moveTo(SkBits2Float(0x40b5a39a), SkBits2Float(0xc28e5650));
+path.lineTo(SkBits2Float(0x4098a641), SkBits2Float(0xc26f3d84));
+path.lineTo(SkBits2Float(0x4098a646), SkBits2Float(0xc26f3d84));
+path.lineTo(SkBits2Float(0x40b5a39a), SkBits2Float(0xc28e5650));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40e83ae9), SkBits2Float(0xc2a55d3f));
+path.cubicTo(SkBits2Float(0x412d0232), SkBits2Float(0xc2a4bd73), SkBits2Float(0x4165854a), SkBits2Float(0xc2a3a860), SkBits2Float(0x418ea651), SkBits2Float(0xc2a21fbf));
+path.lineTo(SkBits2Float(0x414e3d91), SkBits2Float(0xc26a656a));
+path.cubicTo(SkBits2Float(0x4125eb27), SkBits2Float(0xc26c9d13), SkBits2Float(0x40fa2207), SkBits2Float(0xc26e2daa), SkBits2Float(0x40a7e094), SkBits2Float(0xc26f14b2));
+path.lineTo(SkBits2Float(0x40e83ae9), SkBits2Float(0xc2a55d3f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp112(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4035711d), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40b561d9), SkBits2Float(0xc2a5b5a1), SkBits2Float(0x4107d050), SkBits2Float(0xc2a5212f));
+path.lineTo(SkBits2Float(0x40c45b76), SkBits2Float(0xc26ebddb));
+path.cubicTo(SkBits2Float(0x40831ea4), SkBits2Float(0xc26f947a), SkBits2Float(0x400329ad), SkBits2Float(0xc26fffff), SkBits2Float(0x35bbfd46), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4107d054), SkBits2Float(0xc2a5212f));
+path.cubicTo(SkBits2Float(0x410c5332), SkBits2Float(0xc2a51258), SkBits2Float(0x4110d578), SkBits2Float(0xc2a502c3), SkBits2Float(0x41155714), SkBits2Float(0xc2a4f271));
+path.lineTo(SkBits2Float(0x40d7e9e2), SkBits2Float(0xc26e7a46));
+path.cubicTo(SkBits2Float(0x40d16605), SkBits2Float(0xc26e91e0), SkBits2Float(0x40cae131), SkBits2Float(0xc26ea866), SkBits2Float(0x40c45b7a), SkBits2Float(0xc26ebddc));
+path.lineTo(SkBits2Float(0x4107d054), SkBits2Float(0xc2a5212f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp113(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4035711d), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40b561d9), SkBits2Float(0xc2a5b5a1), SkBits2Float(0x4107d054), SkBits2Float(0xc2a5212f));
+path.cubicTo(SkBits2Float(0x410c5332), SkBits2Float(0xc2a51258), SkBits2Float(0x4110d578), SkBits2Float(0xc2a502c3), SkBits2Float(0x41155714), SkBits2Float(0xc2a4f271));
+path.lineTo(SkBits2Float(0x40d7e9e2), SkBits2Float(0xc26e7a46));
+path.cubicTo(SkBits2Float(0x40d16605), SkBits2Float(0xc26e91e0), SkBits2Float(0x40cae131), SkBits2Float(0xc26ea866), SkBits2Float(0x40c45b76), SkBits2Float(0xc26ebddb));
+path.cubicTo(SkBits2Float(0x40831ea4), SkBits2Float(0xc26f947a), SkBits2Float(0x400329ad), SkBits2Float(0xc26fffff), SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4115571a), SkBits2Float(0xc2a4f271));
+path.cubicTo(SkBits2Float(0x415e6818), SkBits2Float(0xc2a3e9d4), SkBits2Float(0x41935478), SkBits2Float(0xc2a21f7a), SkBits2Float(0x41b6ad74), SkBits2Float(0xc29f981d));
+path.lineTo(SkBits2Float(0x41840e5b), SkBits2Float(0xc266bd14));
+path.cubicTo(SkBits2Float(0x415501d6), SkBits2Float(0xc26a6507), SkBits2Float(0x4120c6a0), SkBits2Float(0xc26cfbb4), SkBits2Float(0x40d7e9e6), SkBits2Float(0xc26e7a47));
+path.lineTo(SkBits2Float(0x4115571a), SkBits2Float(0xc2a4f271));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp114(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x405f6414), SkBits2Float(0xc2a60000), SkBits2Float(0x40df4798), SkBits2Float(0xc2a58f44), SkBits2Float(0x41270b42), SkBits2Float(0xc2a4ae78));
+path.lineTo(SkBits2Float(0x40f1826b), SkBits2Float(0xc26e1801));
+path.cubicTo(SkBits2Float(0x40a16831), SkBits2Float(0xc26f5d03), SkBits2Float(0x40217cc8), SkBits2Float(0xc2700000), SkBits2Float(0x3507fa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41270b46), SkBits2Float(0xc2a4ae78));
+path.cubicTo(SkBits2Float(0x412c952a), SkBits2Float(0xc2a497ff), SkBits2Float(0x41321de3), SkBits2Float(0xc2a48068), SkBits2Float(0x4137a563), SkBits2Float(0xc2a467b4));
+path.lineTo(SkBits2Float(0x4104c195), SkBits2Float(0xc26db1b1));
+path.cubicTo(SkBits2Float(0x4100c256), SkBits2Float(0xc26dd569), SkBits2Float(0x40f98465), SkBits2Float(0xc26df784), SkBits2Float(0x40f18273), SkBits2Float(0xc26e1801));
+path.lineTo(SkBits2Float(0x41270b46), SkBits2Float(0xc2a4ae78));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp115(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x405f6414), SkBits2Float(0xc2a60000), SkBits2Float(0x40df4798), SkBits2Float(0xc2a58f44), SkBits2Float(0x41270b46), SkBits2Float(0xc2a4ae78));
+path.cubicTo(SkBits2Float(0x412c952a), SkBits2Float(0xc2a497ff), SkBits2Float(0x41321de3), SkBits2Float(0xc2a48068), SkBits2Float(0x4137a563), SkBits2Float(0xc2a467b4));
+path.lineTo(SkBits2Float(0x4104c195), SkBits2Float(0xc26db1b1));
+path.cubicTo(SkBits2Float(0x4100c256), SkBits2Float(0xc26dd569), SkBits2Float(0x40f98465), SkBits2Float(0xc26df784), SkBits2Float(0x40f1826b), SkBits2Float(0xc26e1801));
+path.cubicTo(SkBits2Float(0x40a16831), SkBits2Float(0xc26f5d03), SkBits2Float(0x40217cc8), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4137a563), SkBits2Float(0xc2a467b4));
+path.cubicTo(SkBits2Float(0x4188a9bf), SkBits2Float(0xc2a2d700), SkBits2Float(0x41b4bec4), SkBits2Float(0xc2a021d5), SkBits2Float(0x41df619b), SkBits2Float(0xc29c5308));
+path.lineTo(SkBits2Float(0x41a17afe), SkBits2Float(0xc26202d7));
+path.cubicTo(SkBits2Float(0x4182a8c1), SkBits2Float(0xc2678433), SkBits2Float(0x414595cf), SkBits2Float(0xc26b6e5e), SkBits2Float(0x4104c197), SkBits2Float(0xc26db1b2));
+path.lineTo(SkBits2Float(0x4137a563), SkBits2Float(0xc2a467b4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp116(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40894a00), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41092f84), SkBits2Float(0xc2a555af), SkBits2Float(0x414d01d5), SkBits2Float(0xc2a40295));
+path.lineTo(SkBits2Float(0x411432a9), SkBits2Float(0xc26d1f80));
+path.cubicTo(SkBits2Float(0x40c65728), SkBits2Float(0xc26f09c3), SkBits2Float(0x40467d64), SkBits2Float(0xc2700000), SkBits2Float(0xb5600574), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x414d01d1), SkBits2Float(0xc2a40296));
+path.cubicTo(SkBits2Float(0x4153c92e), SkBits2Float(0xc2a3e0b1), SkBits2Float(0x415a8e6d), SkBits2Float(0xc2a3bd1e), SkBits2Float(0x41615162), SkBits2Float(0xc2a397de));
+path.lineTo(SkBits2Float(0x4122e164), SkBits2Float(0xc26c8535));
+path.cubicTo(SkBits2Float(0x411dfe19), SkBits2Float(0xc26cbb11), SkBits2Float(0x41191928), SkBits2Float(0xc26cee7f), SkBits2Float(0x411432ab), SkBits2Float(0xc26d1f80));
+path.lineTo(SkBits2Float(0x414d01d1), SkBits2Float(0xc2a40296));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp117(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x408949fd), SkBits2Float(0xc2a60000), SkBits2Float(0x41092f81), SkBits2Float(0xc2a555af), SkBits2Float(0x414d01d0), SkBits2Float(0xc2a40295));
+path.lineTo(SkBits2Float(0x414d01d1), SkBits2Float(0xc2a40296));
+path.cubicTo(SkBits2Float(0x4153c92e), SkBits2Float(0xc2a3e0b1), SkBits2Float(0x415a8e6d), SkBits2Float(0xc2a3bd1e), SkBits2Float(0x41615162), SkBits2Float(0xc2a397de));
+path.lineTo(SkBits2Float(0x4122e164), SkBits2Float(0xc26c8535));
+path.cubicTo(SkBits2Float(0x411dfe19), SkBits2Float(0xc26cbb11), SkBits2Float(0x41191928), SkBits2Float(0xc26cee7f), SkBits2Float(0x411432a9), SkBits2Float(0xc26d1f80));
+path.cubicTo(SkBits2Float(0x40c65728), SkBits2Float(0xc26f09c3), SkBits2Float(0x40467d64), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41615164), SkBits2Float(0xc2a397de));
+path.cubicTo(SkBits2Float(0x41a78432), SkBits2Float(0xc2a13b6d), SkBits2Float(0x41dcf7f2), SkBits2Float(0xc29d27e8), SkBits2Float(0x4207e0f5), SkBits2Float(0xc29775db));
+path.lineTo(SkBits2Float(0x41c47380), SkBits2Float(0xc25afa96));
+path.cubicTo(SkBits2Float(0x419fbc7e), SkBits2Float(0xc263369d), SkBits2Float(0x41723143), SkBits2Float(0xc2691b52), SkBits2Float(0x4122e168), SkBits2Float(0xc26c8537));
+path.lineTo(SkBits2Float(0x41615164), SkBits2Float(0xc2a397de));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp118(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40a2e582), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4122b94f), SkBits2Float(0xc2a51039), SkBits2Float(0x4172cca0), SkBits2Float(0xc2a333b4));
+path.lineTo(SkBits2Float(0x412f847d), SkBits2Float(0xc26bf464));
+path.cubicTo(SkBits2Float(0x40eb4376), SkBits2Float(0xc26ea556), SkBits2Float(0x406b836d), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4172cc9b), SkBits2Float(0xc2a333b4));
+path.cubicTo(SkBits2Float(0x417acd1a), SkBits2Float(0xc2a30415), SkBits2Float(0x41816508), SkBits2Float(0xc2a2d21d), SkBits2Float(0x4185619b), SkBits2Float(0xc2a29dcb));
+path.lineTo(SkBits2Float(0x4140d724), SkBits2Float(0xc26b1ba8));
+path.cubicTo(SkBits2Float(0x413b139d), SkBits2Float(0xc26b674c), SkBits2Float(0x41354d54), SkBits2Float(0xc26baf8b), SkBits2Float(0x412f847c), SkBits2Float(0xc26bf463));
+path.lineTo(SkBits2Float(0x4172cc9b), SkBits2Float(0xc2a333b4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp119(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40a2e57f), SkBits2Float(0xc2a60000), SkBits2Float(0x4122b94c), SkBits2Float(0xc2a51039), SkBits2Float(0x4172cc9b), SkBits2Float(0xc2a333b4));
+path.lineTo(SkBits2Float(0x4172cca0), SkBits2Float(0xc2a333b4));
+path.cubicTo(SkBits2Float(0x417acd1d), SkBits2Float(0xc2a30415), SkBits2Float(0x41816509), SkBits2Float(0xc2a2d21d), SkBits2Float(0x4185619b), SkBits2Float(0xc2a29dcb));
+path.lineTo(SkBits2Float(0x4140d724), SkBits2Float(0xc26b1ba8));
+path.cubicTo(SkBits2Float(0x413b139d), SkBits2Float(0xc26b674c), SkBits2Float(0x41354d54), SkBits2Float(0xc26baf8b), SkBits2Float(0x412f847c), SkBits2Float(0xc26bf463));
+path.lineTo(SkBits2Float(0x412f847d), SkBits2Float(0xc26bf464));
+path.cubicTo(SkBits2Float(0x40eb4376), SkBits2Float(0xc26ea556), SkBits2Float(0x406b836d), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4185619b), SkBits2Float(0xc2a29dcc));
+path.cubicTo(SkBits2Float(0x41c61a92), SkBits2Float(0xc29f4c69), SkBits2Float(0x42023dd6), SkBits2Float(0xc299958f), SkBits2Float(0x421f3a98), SkBits2Float(0xc291a994));
+path.lineTo(SkBits2Float(0x41e635e1), SkBits2Float(0xc25298a5));
+path.cubicTo(SkBits2Float(0x41bc4d11), SkBits2Float(0xc25e0caa), SkBits2Float(0x418f3524), SkBits2Float(0xc2664fa2), SkBits2Float(0x4140d729), SkBits2Float(0xc26b1ba9));
+path.lineTo(SkBits2Float(0x4185619b), SkBits2Float(0xc2a29dcc));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp120(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40c39389), SkBits2Float(0xc2a60000), SkBits2Float(0x414346f4), SkBits2Float(0xc2a4a65f), SkBits2Float(0x419158cf), SkBits2Float(0xc2a1f965));
+path.lineTo(SkBits2Float(0x415223e0), SkBits2Float(0xc26a2df8));
+path.cubicTo(SkBits2Float(0x410d2a0c), SkBits2Float(0xc26e0c4b), SkBits2Float(0x408d616c), SkBits2Float(0xc2700000), SkBits2Float(0x35bbfd46), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x419158d0), SkBits2Float(0xc2a1f965));
+path.cubicTo(SkBits2Float(0x41961cea), SkBits2Float(0xc2a1b4f6), SkBits2Float(0x419addf6), SkBits2Float(0xc2a16d2c), SkBits2Float(0x419f9bbb), SkBits2Float(0xc2a12207));
+path.lineTo(SkBits2Float(0x4166c251), SkBits2Float(0xc268f69a));
+path.cubicTo(SkBits2Float(0x415fe778), SkBits2Float(0xc269633e), SkBits2Float(0x415907e2), SkBits2Float(0xc269cb09), SkBits2Float(0x415223e0), SkBits2Float(0xc26a2df8));
+path.lineTo(SkBits2Float(0x419158d0), SkBits2Float(0xc2a1f965));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp121(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40c39389), SkBits2Float(0xc2a60000), SkBits2Float(0x414346f4), SkBits2Float(0xc2a4a65f), SkBits2Float(0x419158d0), SkBits2Float(0xc2a1f965));
+path.cubicTo(SkBits2Float(0x41961cea), SkBits2Float(0xc2a1b4f6), SkBits2Float(0x419addf6), SkBits2Float(0xc2a16d2c), SkBits2Float(0x419f9bbb), SkBits2Float(0xc2a12207));
+path.lineTo(SkBits2Float(0x4166c251), SkBits2Float(0xc268f69a));
+path.cubicTo(SkBits2Float(0x415fe778), SkBits2Float(0xc269633e), SkBits2Float(0x415907e2), SkBits2Float(0xc269cb09), SkBits2Float(0x415223e0), SkBits2Float(0xc26a2df8));
+path.cubicTo(SkBits2Float(0x410d2a0c), SkBits2Float(0xc26e0c4b), SkBits2Float(0x408d616c), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x419f9bbc), SkBits2Float(0xc2a12208));
+path.cubicTo(SkBits2Float(0x41eca53e), SkBits2Float(0xc29c5d1a), SkBits2Float(0x421ad1be), SkBits2Float(0xc2942e2b), SkBits2Float(0x423b8fe1), SkBits2Float(0xc288f8a3));
+path.lineTo(SkBits2Float(0x42079647), SkBits2Float(0xc24607dc));
+path.cubicTo(SkBits2Float(0x41dfd5cc), SkBits2Float(0xc2563c94), SkBits2Float(0x41ab11aa), SkBits2Float(0xc2621167), SkBits2Float(0x4166c24e), SkBits2Float(0xc268f69b));
+path.lineTo(SkBits2Float(0x419f9bbc), SkBits2Float(0xc2a12208));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp122(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x410a1653), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4189aa2f), SkBits2Float(0xc2a34ed0), SkBits2Float(0x41cb63be), SkBits2Float(0xc29e054b));
+path.lineTo(SkBits2Float(0x41930758), SkBits2Float(0xc26476b2));
+path.cubicTo(SkBits2Float(0x41470896), SkBits2Float(0xc26c1b98), SkBits2Float(0x40c7a4f2), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41cb63c3), SkBits2Float(0xc29e054c));
+path.cubicTo(SkBits2Float(0x41d1f2f3), SkBits2Float(0xc29d7e37), SkBits2Float(0x41d879a0), SkBits2Float(0xc29cf09c), SkBits2Float(0x41def72d), SkBits2Float(0xc29c5c87));
+path.lineTo(SkBits2Float(0x41a12e10), SkBits2Float(0xc2621091));
+path.cubicTo(SkBits2Float(0x419c7cee), SkBits2Float(0xc262e6aa), SkBits2Float(0x4197c536), SkBits2Float(0xc263b366), SkBits2Float(0x41930757), SkBits2Float(0xc26476b3));
+path.lineTo(SkBits2Float(0x41cb63c3), SkBits2Float(0xc29e054c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp123(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x410a1653), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4189aa2f), SkBits2Float(0xc2a34ed0), SkBits2Float(0x41cb63be), SkBits2Float(0xc29e054b));
+path.lineTo(SkBits2Float(0x41cb63c3), SkBits2Float(0xc29e054c));
+path.cubicTo(SkBits2Float(0x41d1f2f3), SkBits2Float(0xc29d7e37), SkBits2Float(0x41d879a0), SkBits2Float(0xc29cf09c), SkBits2Float(0x41def72d), SkBits2Float(0xc29c5c87));
+path.lineTo(SkBits2Float(0x41a12e10), SkBits2Float(0xc2621091));
+path.cubicTo(SkBits2Float(0x419c7cee), SkBits2Float(0xc262e6aa), SkBits2Float(0x4197c536), SkBits2Float(0xc263b366), SkBits2Float(0x41930757), SkBits2Float(0xc26476b3));
+path.lineTo(SkBits2Float(0x41930758), SkBits2Float(0xc26476b2));
+path.cubicTo(SkBits2Float(0x41470896), SkBits2Float(0xc26c1b98), SkBits2Float(0x40c7a4f2), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea3), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41def730), SkBits2Float(0xc29c5c87));
+path.cubicTo(SkBits2Float(0x422459f2), SkBits2Float(0xc292f017), SkBits2Float(0x42539427), SkBits2Float(0xc282f764), SkBits2Float(0x4278c050), SkBits2Float(0xc25be110));
+path.lineTo(SkBits2Float(0x4233d1f5), SkBits2Float(0xc21ef2e3));
+path.cubicTo(SkBits2Float(0x4218f2cf), SkBits2Float(0xc23d5956), SkBits2Float(0x41ed9dce), SkBits2Float(0xc25470b6), SkBits2Float(0x41a12e11), SkBits2Float(0xc2621092));
+path.lineTo(SkBits2Float(0x41def730), SkBits2Float(0xc29c5c87));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp124(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x411fc00b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x419f1845), SkBits2Float(0xc2a265a5), SkBits2Float(0x41e9da2b), SkBits2Float(0xc29b5d43));
+path.lineTo(SkBits2Float(0x41a90cc1), SkBits2Float(0xc2609f84));
+path.cubicTo(SkBits2Float(0x41660440), SkBits2Float(0xc26aca7c), SkBits2Float(0x40e6f6cd), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa8c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41e9da2e), SkBits2Float(0xc29b5d44));
+path.cubicTo(SkBits2Float(0x41f14eda), SkBits2Float(0xc29aa9b5), SkBits2Float(0x41f8b671), SkBits2Float(0xc299ed94), SkBits2Float(0x42000805), SkBits2Float(0xc29928f7));
+path.lineTo(SkBits2Float(0x41b91b05), SkBits2Float(0xc25d6faa));
+path.cubicTo(SkBits2Float(0x41b3cad4), SkBits2Float(0xc25e8bec), SkBits2Float(0x41ae7086), SkBits2Float(0xc25f9beb), SkBits2Float(0x41a90cc3), SkBits2Float(0xc2609f85));
+path.lineTo(SkBits2Float(0x41e9da2e), SkBits2Float(0xc29b5d44));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp125(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x411fc00b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x419f1845), SkBits2Float(0xc2a265a5), SkBits2Float(0x41e9da2e), SkBits2Float(0xc29b5d44));
+path.cubicTo(SkBits2Float(0x41f14eda), SkBits2Float(0xc29aa9b5), SkBits2Float(0x41f8b671), SkBits2Float(0xc299ed94), SkBits2Float(0x42000805), SkBits2Float(0xc29928f7));
+path.lineTo(SkBits2Float(0x41b91b05), SkBits2Float(0xc25d6faa));
+path.cubicTo(SkBits2Float(0x41b3cad4), SkBits2Float(0xc25e8bec), SkBits2Float(0x41ae7086), SkBits2Float(0xc25f9beb), SkBits2Float(0x41a90cc1), SkBits2Float(0xc2609f84));
+path.cubicTo(SkBits2Float(0x41660440), SkBits2Float(0xc26aca7c), SkBits2Float(0x40e6f6cd), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42000806), SkBits2Float(0xc29928f8));
+path.cubicTo(SkBits2Float(0x423c0231), SkBits2Float(0xc28ca034), SkBits2Float(0x426f4e95), SkBits2Float(0xc26f2095), SkBits2Float(0x4289c821), SkBits2Float(0xc2392c12));
+path.lineTo(SkBits2Float(0x424733db), SkBits2Float(0xc205dc02));
+path.cubicTo(SkBits2Float(0x422cfe35), SkBits2Float(0xc22cdcf5), SkBits2Float(0x4207e8ea), SkBits2Float(0xc24b507f), SkBits2Float(0x41b91b06), SkBits2Float(0xc25d6faa));
+path.lineTo(SkBits2Float(0x42000806), SkBits2Float(0xc29928f8));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp126(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41379cd4), SkBits2Float(0xc2a60000), SkBits2Float(0x41b69d77), SkBits2Float(0xc2a13d93), SkBits2Float(0x42055871), SkBits2Float(0xc29805ae));
+path.lineTo(SkBits2Float(0x41c0c9e6), SkBits2Float(0xc25bca86));
+path.cubicTo(SkBits2Float(0x418402cc), SkBits2Float(0xc2691e6b), SkBits2Float(0x4104bb66), SkBits2Float(0xc26fffff), SkBits2Float(0x3673fea5), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42055872), SkBits2Float(0xc29805ae));
+path.cubicTo(SkBits2Float(0x420988d2), SkBits2Float(0xc2971a85), SkBits2Float(0x420daf5c), SkBits2Float(0xc296244f), SkBits2Float(0x4211cb64), SkBits2Float(0xc2952332));
+path.lineTo(SkBits2Float(0x41d2c988), SkBits2Float(0xc2579ed7));
+path.cubicTo(SkBits2Float(0x41ccd887), SkBits2Float(0xc2591291), SkBits2Float(0x41c6d852), SkBits2Float(0xc25a7689), SkBits2Float(0x41c0c9e6), SkBits2Float(0xc25bca86));
+path.lineTo(SkBits2Float(0x42055872), SkBits2Float(0xc29805ae));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp127(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3673fea5), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41379cd4), SkBits2Float(0xc2a60000), SkBits2Float(0x41b69d77), SkBits2Float(0xc2a13d93), SkBits2Float(0x42055872), SkBits2Float(0xc29805ae));
+path.cubicTo(SkBits2Float(0x420988d2), SkBits2Float(0xc2971a85), SkBits2Float(0x420daf5c), SkBits2Float(0xc296244f), SkBits2Float(0x4211cb64), SkBits2Float(0xc2952332));
+path.lineTo(SkBits2Float(0x41d2c988), SkBits2Float(0xc2579ed7));
+path.cubicTo(SkBits2Float(0x41ccd887), SkBits2Float(0xc2591291), SkBits2Float(0x41c6d852), SkBits2Float(0xc25a7689), SkBits2Float(0x41c0c9e6), SkBits2Float(0xc25bca86));
+path.cubicTo(SkBits2Float(0x418402cc), SkBits2Float(0xc2691e6b), SkBits2Float(0x4104bb66), SkBits2Float(0xc26fffff), SkBits2Float(0x3673fea5), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4211cb65), SkBits2Float(0xc2952332));
+path.cubicTo(SkBits2Float(0x42550406), SkBits2Float(0xc284b578), SkBits2Float(0x42859569), SkBits2Float(0xc252d13a), SkBits2Float(0x4295bbf4), SkBits2Float(0xc20f53bf));
+path.lineTo(SkBits2Float(0x42587bb2), SkBits2Float(0xc1cf3850));
+path.cubicTo(SkBits2Float(0x4241220a), SkBits2Float(0xc21865e8), SkBits2Float(0x4219fcbd), SkBits2Float(0xc23fde48), SkBits2Float(0x41d2c988), SkBits2Float(0xc2579ed8));
+path.lineTo(SkBits2Float(0x4211cb65), SkBits2Float(0xc2952332));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp128(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4151cd59), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41d04f3f), SkBits2Float(0xc29fc954), SkBits2Float(0x4216e058), SkBits2Float(0xc293de54));
+path.lineTo(SkBits2Float(0x41da226b), SkBits2Float(0xc255c926));
+path.cubicTo(SkBits2Float(0x419695d1), SkBits2Float(0xc267043d), SkBits2Float(0x4117aa0a), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4216e057), SkBits2Float(0xc293de54));
+path.cubicTo(SkBits2Float(0x421b86ea), SkBits2Float(0xc292aea0), SkBits2Float(0x42201eff), SkBits2Float(0xc29170ed), SkBits2Float(0x4224a79b), SkBits2Float(0xc290257e));
+path.lineTo(SkBits2Float(0x41ee0e15), SkBits2Float(0xc2506790));
+path.cubicTo(SkBits2Float(0x41e78019), SkBits2Float(0xc25246bf), SkBits2Float(0x41e0dbbc), SkBits2Float(0xc2541212), SkBits2Float(0x41da226b), SkBits2Float(0xc255c927));
+path.lineTo(SkBits2Float(0x4216e057), SkBits2Float(0xc293de54));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp129(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4151cd58), SkBits2Float(0xc2a60000), SkBits2Float(0x41d04f3d), SkBits2Float(0xc29fc954), SkBits2Float(0x4216e057), SkBits2Float(0xc293de54));
+path.lineTo(SkBits2Float(0x4216e058), SkBits2Float(0xc293de54));
+path.cubicTo(SkBits2Float(0x421b86eb), SkBits2Float(0xc292aea0), SkBits2Float(0x42201eff), SkBits2Float(0xc29170ed), SkBits2Float(0x4224a79b), SkBits2Float(0xc290257e));
+path.lineTo(SkBits2Float(0x41ee0e15), SkBits2Float(0xc2506790));
+path.cubicTo(SkBits2Float(0x41e78019), SkBits2Float(0xc25246bf), SkBits2Float(0x41e0dbbc), SkBits2Float(0xc2541212), SkBits2Float(0x41da226b), SkBits2Float(0xc255c927));
+path.lineTo(SkBits2Float(0x41da226b), SkBits2Float(0xc255c926));
+path.cubicTo(SkBits2Float(0x419695d1), SkBits2Float(0xc267043d), SkBits2Float(0x4117aa0a), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4224a79b), SkBits2Float(0xc290257f));
+path.cubicTo(SkBits2Float(0x426f06c3), SkBits2Float(0xc275d105), SkBits2Float(0x42930d85), SkBits2Float(0xc2303df6), SkBits2Float(0x429f3103), SkBits2Float(0xc1bc373f));
+path.lineTo(SkBits2Float(0x42662806), SkBits2Float(0xc1880f44));
+path.cubicTo(SkBits2Float(0x42549b44), SkBits2Float(0xc1fececc), SkBits2Float(0x422cca4c), SkBits2Float(0xc231b2de), SkBits2Float(0x41ee0e18), SkBits2Float(0xc2506792));
+path.lineTo(SkBits2Float(0x4224a79b), SkBits2Float(0xc290257f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp130(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x417054a2), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41ee1405), SkBits2Float(0xc29dd904), SkBits2Float(0x422a9595), SkBits2Float(0xc28e6989));
+path.lineTo(SkBits2Float(0x41f6a0c0), SkBits2Float(0xc24de5b0));
+path.cubicTo(SkBits2Float(0x41ac1ad0), SkBits2Float(0xc26436ad), SkBits2Float(0x412dbba0), SkBits2Float(0xc2700000), SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x422a9596), SkBits2Float(0xc28e6989));
+path.cubicTo(SkBits2Float(0x422fb535), SkBits2Float(0xc28ce0c4), SkBits2Float(0x4234bf65), SkBits2Float(0xc28b465e), SkBits2Float(0x4239b2bc), SkBits2Float(0xc2899acc));
+path.lineTo(SkBits2Float(0x42063d5a), SkBits2Float(0xc246f24e));
+path.cubicTo(SkBits2Float(0x4202a934), SkBits2Float(0xc2495c7c), SkBits2Float(0x41fe0912), SkBits2Float(0xc24badd5), SkBits2Float(0x41f6a0c0), SkBits2Float(0xc24de5b1));
+path.lineTo(SkBits2Float(0x422a9596), SkBits2Float(0xc28e6989));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp131(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x417054a2), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41ee1405), SkBits2Float(0xc29dd904), SkBits2Float(0x422a9596), SkBits2Float(0xc28e6989));
+path.cubicTo(SkBits2Float(0x422fb535), SkBits2Float(0xc28ce0c4), SkBits2Float(0x4234bf65), SkBits2Float(0xc28b465e), SkBits2Float(0x4239b2bc), SkBits2Float(0xc2899acc));
+path.lineTo(SkBits2Float(0x42063d5a), SkBits2Float(0xc246f24e));
+path.cubicTo(SkBits2Float(0x4202a934), SkBits2Float(0xc2495c7c), SkBits2Float(0x41fe0912), SkBits2Float(0xc24badd5), SkBits2Float(0x41f6a0c0), SkBits2Float(0xc24de5b0));
+path.cubicTo(SkBits2Float(0x41ac1ad0), SkBits2Float(0xc26436ad), SkBits2Float(0x412dbba0), SkBits2Float(0xc2700000), SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4239b2bd), SkBits2Float(0xc2899acc));
+path.cubicTo(SkBits2Float(0x42859c2b), SkBits2Float(0xc25c33ca), SkBits2Float(0x42a01474), SkBits2Float(0xc203e23a), SkBits2Float(0x42a51fce), SkBits2Float(0xc1083bae));
+path.lineTo(SkBits2Float(0x426ebbdb), SkBits2Float(0xc0c4f6ab));
+path.cubicTo(SkBits2Float(0x426770d9), SkBits2Float(0xc1beacda), SkBits2Float(0x42412bce), SkBits2Float(0xc21f2eb0), SkBits2Float(0x42063d5a), SkBits2Float(0xc246f24e));
+path.lineTo(SkBits2Float(0x4239b2bd), SkBits2Float(0xc2899acc));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp132(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4187e175), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42063ec3), SkBits2Float(0xc29b93fb), SkBits2Float(0x423df6fd), SkBits2Float(0xc2882410));
+path.lineTo(SkBits2Float(0x420952ef), SkBits2Float(0xc244d488));
+path.cubicTo(SkBits2Float(0x41c216e4), SkBits2Float(0xc260eea0), SkBits2Float(0x4144743c), SkBits2Float(0xc26fffff), SkBits2Float(0x357ffa94), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423df6fe), SkBits2Float(0xc2882411));
+path.cubicTo(SkBits2Float(0x42437e7a), SkBits2Float(0xc286364a), SkBits2Float(0x4248e78f), SkBits2Float(0xc2843312), SkBits2Float(0x424e304d), SkBits2Float(0xc2821b20));
+path.lineTo(SkBits2Float(0x42150d53), SkBits2Float(0xc23c1ae0));
+path.cubicTo(SkBits2Float(0x42113b72), SkBits2Float(0xc23f21be), SkBits2Float(0x420d522e), SkBits2Float(0xc2420aa4), SkBits2Float(0x420952ef), SkBits2Float(0xc244d48a));
+path.lineTo(SkBits2Float(0x423df6fe), SkBits2Float(0xc2882411));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp133(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4187e175), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42063ec3), SkBits2Float(0xc29b93fb), SkBits2Float(0x423df6fe), SkBits2Float(0xc2882411));
+path.cubicTo(SkBits2Float(0x42437e7a), SkBits2Float(0xc286364a), SkBits2Float(0x4248e78f), SkBits2Float(0xc2843312), SkBits2Float(0x424e304d), SkBits2Float(0xc2821b20));
+path.lineTo(SkBits2Float(0x42150d53), SkBits2Float(0xc23c1ae0));
+path.cubicTo(SkBits2Float(0x42113b72), SkBits2Float(0xc23f21be), SkBits2Float(0x420d522e), SkBits2Float(0xc2420aa4), SkBits2Float(0x420952ef), SkBits2Float(0xc244d48a));
+path.lineTo(SkBits2Float(0x420952ef), SkBits2Float(0xc244d488));
+path.cubicTo(SkBits2Float(0x41c216e4), SkBits2Float(0xc260eea0), SkBits2Float(0x4144743c), SkBits2Float(0xc26fffff), SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x424e304d), SkBits2Float(0xc2821b20));
+path.cubicTo(SkBits2Float(0x4292cbf1), SkBits2Float(0xc23ef41d), SkBits2Float(0x42aa31a6), SkBits2Float(0xc1a4e14c), SkBits2Float(0x42a56158), SkBits2Float(0x40e54b3a));
+path.lineTo(SkBits2Float(0x426f1a9e), SkBits2Float(0x40a5c12f));
+path.cubicTo(SkBits2Float(0x42761044), SkBits2Float(0xc16e617c), SkBits2Float(0x42543c73), SkBits2Float(0xc20a09ea), SkBits2Float(0x42150d54), SkBits2Float(0xc23c1ae1));
+path.lineTo(SkBits2Float(0x424e304d), SkBits2Float(0xc2821b20));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp134(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x419c5b1f), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4219d929), SkBits2Float(0xc29834b3), SkBits2Float(0x4255ae76), SkBits2Float(0xc27e184c));
+path.lineTo(SkBits2Float(0x421a77f2), SkBits2Float(0xc237aede));
+path.cubicTo(SkBits2Float(0x41de6e66), SkBits2Float(0xc25c0e82), SkBits2Float(0x41620e8a), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4255ae76), SkBits2Float(0xc27e184c));
+path.cubicTo(SkBits2Float(0x425b9ab5), SkBits2Float(0xc2791d33), SkBits2Float(0x426159ea), SkBits2Float(0xc273ed7b), SkBits2Float(0x4266e960), SkBits2Float(0xc26e8b92));
+path.lineTo(SkBits2Float(0x4226ec90), SkBits2Float(0xc22c713c));
+path.cubicTo(SkBits2Float(0x4222e78d), SkBits2Float(0xc2305550), SkBits2Float(0x421ec008), SkBits2Float(0xc234151d), SkBits2Float(0x421a77f3), SkBits2Float(0xc237aedd));
+path.lineTo(SkBits2Float(0x4255ae76), SkBits2Float(0xc27e184c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp135(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x419c5b1f), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4219d929), SkBits2Float(0xc29834b3), SkBits2Float(0x4255ae76), SkBits2Float(0xc27e184c));
+path.cubicTo(SkBits2Float(0x425b9ab5), SkBits2Float(0xc2791d33), SkBits2Float(0x426159ea), SkBits2Float(0xc273ed7b), SkBits2Float(0x4266e960), SkBits2Float(0xc26e8b92));
+path.lineTo(SkBits2Float(0x4226ec90), SkBits2Float(0xc22c713c));
+path.cubicTo(SkBits2Float(0x4222e78d), SkBits2Float(0xc2305550), SkBits2Float(0x421ec008), SkBits2Float(0xc234151d), SkBits2Float(0x421a77f2), SkBits2Float(0xc237aede));
+path.cubicTo(SkBits2Float(0x41de6e66), SkBits2Float(0xc25c0e82), SkBits2Float(0x41620e8a), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4266e961), SkBits2Float(0xc26e8b93));
+path.cubicTo(SkBits2Float(0x42a1bfce), SkBits2Float(0xc214ebcf), SkBits2Float(0x42b1ee5a), SkBits2Float(0xc05d1412), SkBits2Float(0x429cf75a), SkBits2Float(0x41d80f2c));
+path.lineTo(SkBits2Float(0x4262f06b), SkBits2Float(0x419c2ffb));
+path.cubicTo(SkBits2Float(0x42809ff9), SkBits2Float(0xc01fd0e5), SkBits2Float(0x4269dab8), SkBits2Float(0xc1d74ec6), SkBits2Float(0x4226ec91), SkBits2Float(0xc22c713d));
+path.lineTo(SkBits2Float(0x4266e961), SkBits2Float(0xc26e8b93));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp136(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ae0130), SkBits2Float(0xc2a5ffff), SkBits2Float(0x422a8737), SkBits2Float(0xc294ec91), SkBits2Float(0x42689b67), SkBits2Float(0xc26ce46c));
+path.lineTo(SkBits2Float(0x42282651), SkBits2Float(0xc22b3f58));
+path.cubicTo(SkBits2Float(0x41f68bfb), SkBits2Float(0xc2574fdc), SkBits2Float(0x417b92b3), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42689b68), SkBits2Float(0xc26ce46d));
+path.cubicTo(SkBits2Float(0x426ebcd2), SkBits2Float(0xc266df67), SkBits2Float(0x4274a1d2), SkBits2Float(0xc2609e09), SkBits2Float(0x427a4701), SkBits2Float(0xc25a23f2));
+path.lineTo(SkBits2Float(0x4234ec64), SkBits2Float(0xc21db11e));
+path.cubicTo(SkBits2Float(0x4230d7ae), SkBits2Float(0xc2225fbc), SkBits2Float(0x422c94d6), SkBits2Float(0xc226e55a), SkBits2Float(0x42282652), SkBits2Float(0xc22b3f58));
+path.lineTo(SkBits2Float(0x42689b68), SkBits2Float(0xc26ce46d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp137(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ae0130), SkBits2Float(0xc2a5ffff), SkBits2Float(0x422a8737), SkBits2Float(0xc294ec91), SkBits2Float(0x42689b68), SkBits2Float(0xc26ce46d));
+path.cubicTo(SkBits2Float(0x426ebcd2), SkBits2Float(0xc266df67), SkBits2Float(0x4274a1d2), SkBits2Float(0xc2609e09), SkBits2Float(0x427a4701), SkBits2Float(0xc25a23f2));
+path.lineTo(SkBits2Float(0x4234ec64), SkBits2Float(0xc21db11e));
+path.cubicTo(SkBits2Float(0x4230d7ae), SkBits2Float(0xc2225fbc), SkBits2Float(0x422c94d6), SkBits2Float(0xc226e55a), SkBits2Float(0x42282651), SkBits2Float(0xc22b3f58));
+path.cubicTo(SkBits2Float(0x41f68bfb), SkBits2Float(0xc2574fdc), SkBits2Float(0x417b92b3), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427a4702), SkBits2Float(0xc25a23f2));
+path.cubicTo(SkBits2Float(0x42ac7185), SkBits2Float(0xc1db2f83), SkBits2Float(0x42b35ed0), SkBits2Float(0x413e447a), SkBits2Float(0x428e4a3d), SkBits2Float(0x422afde8));
+path.lineTo(SkBits2Float(0x424db871), SkBits2Float(0x41f73799));
+path.cubicTo(SkBits2Float(0x4281aa54), SkBits2Float(0x41098afa), SkBits2Float(0x427950da), SkBits2Float(0xc19e728d), SkBits2Float(0x4234ec66), SkBits2Float(0xc21db120));
+path.lineTo(SkBits2Float(0x427a4702), SkBits2Float(0xc25a23f2));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp138(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41c2602d), SkBits2Float(0xc2a5ffff), SkBits2Float(0x423d7ece), SkBits2Float(0xc290b51a), SkBits2Float(0x427c92bc), SkBits2Float(0xc2577a5f));
+path.lineTo(SkBits2Float(0x42369543), SkBits2Float(0xc21bc469));
+path.cubicTo(SkBits2Float(0x4208fc10), SkBits2Float(0xc2513731), SkBits2Float(0x418c8338), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427c92be), SkBits2Float(0xc2577a5f));
+path.cubicTo(SkBits2Float(0x42816448), SkBits2Float(0xc25032db), SkBits2Float(0x42845689), SkBits2Float(0xc248a77c), SkBits2Float(0x42871e08), SkBits2Float(0xc240ddaa));
+path.lineTo(SkBits2Float(0x424359af), SkBits2Float(0xc20b6bce));
+path.cubicTo(SkBits2Float(0x423f5505), SkBits2Float(0xc2110d1f), SkBits2Float(0x423b1287), SkBits2Float(0xc216814b), SkBits2Float(0x42369543), SkBits2Float(0xc21bc46a));
+path.lineTo(SkBits2Float(0x427c92be), SkBits2Float(0xc2577a5f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp139(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41c2602d), SkBits2Float(0xc2a5ffff), SkBits2Float(0x423d7ece), SkBits2Float(0xc290b51a), SkBits2Float(0x427c92bc), SkBits2Float(0xc2577a5f));
+path.lineTo(SkBits2Float(0x427c92be), SkBits2Float(0xc2577a5f));
+path.cubicTo(SkBits2Float(0x42816448), SkBits2Float(0xc25032db), SkBits2Float(0x42845689), SkBits2Float(0xc248a77c), SkBits2Float(0x42871e08), SkBits2Float(0xc240ddaa));
+path.lineTo(SkBits2Float(0x424359af), SkBits2Float(0xc20b6bce));
+path.cubicTo(SkBits2Float(0x423f5505), SkBits2Float(0xc2110d1f), SkBits2Float(0x423b1287), SkBits2Float(0xc216814a), SkBits2Float(0x42369543), SkBits2Float(0xc21bc469));
+path.lineTo(SkBits2Float(0x42369543), SkBits2Float(0xc21bc46a));
+path.cubicTo(SkBits2Float(0x4208fc10), SkBits2Float(0xc2513732), SkBits2Float(0x418c8337), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42871e08), SkBits2Float(0xc240ddaa));
+path.cubicTo(SkBits2Float(0x42b615a2), SkBits2Float(0xc174ff4e), SkBits2Float(0x42aecf41), SkBits2Float(0x41edcc49), SkBits2Float(0x426bc7a7), SkBits2Float(0x4269bc09));
+path.lineTo(SkBits2Float(0x422a717e), SkBits2Float(0x4228f6f7));
+path.cubicTo(SkBits2Float(0x427cbca0), SkBits2Float(0x41abe6f4), SkBits2Float(0x4283a09b), SkBits2Float(0xc1311b44), SkBits2Float(0x424359af), SkBits2Float(0xc20b6bcd));
+path.lineTo(SkBits2Float(0x42871e08), SkBits2Float(0xc240ddaa));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp140(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d9e52a), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4252f644), SkBits2Float(0xc28b460f), SkBits2Float(0x42887c98), SkBits2Float(0xc23cf83b));
+path.lineTo(SkBits2Float(0x42455485), SkBits2Float(0xc2089ac5));
+path.cubicTo(SkBits2Float(0x421880ae), SkBits2Float(0xc2495c0a), SkBits2Float(0x419d83bb), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42887c98), SkBits2Float(0xc23cf83b));
+path.cubicTo(SkBits2Float(0x428b8706), SkBits2Float(0xc2342f4a), SkBits2Float(0x428e5ab7), SkBits2Float(0xc22b1c84), SkBits2Float(0x4290f525), SkBits2Float(0xc221c800));
+path.lineTo(SkBits2Float(0x425193c7), SkBits2Float(0xc1e9e68d));
+path.cubicTo(SkBits2Float(0x424dd044), SkBits2Float(0xc1f763d3), SkBits2Float(0x4249b9f6), SkBits2Float(0xc2024108), SkBits2Float(0x42455485), SkBits2Float(0xc2089ac6));
+path.lineTo(SkBits2Float(0x42887c98), SkBits2Float(0xc23cf83b));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp141(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d9e52a), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4252f644), SkBits2Float(0xc28b460f), SkBits2Float(0x42887c98), SkBits2Float(0xc23cf83b));
+path.cubicTo(SkBits2Float(0x428b8706), SkBits2Float(0xc2342f4a), SkBits2Float(0x428e5ab7), SkBits2Float(0xc22b1c84), SkBits2Float(0x4290f525), SkBits2Float(0xc221c800));
+path.lineTo(SkBits2Float(0x425193c7), SkBits2Float(0xc1e9e68d));
+path.cubicTo(SkBits2Float(0x424dd044), SkBits2Float(0xc1f763d3), SkBits2Float(0x4249b9f6), SkBits2Float(0xc2024107), SkBits2Float(0x42455485), SkBits2Float(0xc2089ac5));
+path.lineTo(SkBits2Float(0x42455485), SkBits2Float(0xc2089ac6));
+path.cubicTo(SkBits2Float(0x421880ae), SkBits2Float(0xc2495c0b), SkBits2Float(0x419d83ba), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4290f526), SkBits2Float(0xc221c800));
+path.cubicTo(SkBits2Float(0x42bd6cdd), SkBits2Float(0xbf1a1474), SkBits2Float(0x42a13baa), SkBits2Float(0x4246de93), SkBits2Float(0x4223add7), SkBits2Float(0x42906c8a));
+path.lineTo(SkBits2Float(0x41eca4f8), SkBits2Float(0x4250ce48));
+path.cubicTo(SkBits2Float(0x42691bac), SkBits2Float(0x420fc2d7), SkBits2Float(0x4288ef16), SkBits2Float(0xbedec420), SkBits2Float(0x425193c9), SkBits2Float(0xc1e9e690));
+path.lineTo(SkBits2Float(0x4290f526), SkBits2Float(0xc221c800));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp142(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f6a97d), SkBits2Float(0xc2a60000), SkBits2Float(0x426c7f9e), SkBits2Float(0xc283d12f), SkBits2Float(0x4292f07c), SkBits2Float(0xc21a76e5));
+path.lineTo(SkBits2Float(0x42547147), SkBits2Float(0xc1df5274));
+path.cubicTo(SkBits2Float(0x422af677), SkBits2Float(0xc23e9438), SkBits2Float(0x41b24f58), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4292f07c), SkBits2Float(0xc21a76e5));
+path.cubicTo(SkBits2Float(0x4295bcf6), SkBits2Float(0xc20fd099), SkBits2Float(0x42983ed1), SkBits2Float(0xc204de6d), SkBits2Float(0x429a7333), SkBits2Float(0xc1f3598c));
+path.lineTo(SkBits2Float(0x425f4d1c), SkBits2Float(0xc1afea60));
+path.cubicTo(SkBits2Float(0x425c1d22), SkBits2Float(0xc1c0197b), SkBits2Float(0x42587d28), SkBits2Float(0xc1cfecd2), SkBits2Float(0x42547148), SkBits2Float(0xc1df5275));
+path.lineTo(SkBits2Float(0x4292f07c), SkBits2Float(0xc21a76e5));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp143(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f6a97d), SkBits2Float(0xc2a60000), SkBits2Float(0x426c7f9e), SkBits2Float(0xc283d12f), SkBits2Float(0x4292f07c), SkBits2Float(0xc21a76e5));
+path.cubicTo(SkBits2Float(0x4295bcf6), SkBits2Float(0xc20fd099), SkBits2Float(0x42983ed1), SkBits2Float(0xc204de6d), SkBits2Float(0x429a7333), SkBits2Float(0xc1f3598c));
+path.lineTo(SkBits2Float(0x425f4d1c), SkBits2Float(0xc1afea60));
+path.cubicTo(SkBits2Float(0x425c1d22), SkBits2Float(0xc1c0197b), SkBits2Float(0x42587d28), SkBits2Float(0xc1cfecd2), SkBits2Float(0x42547147), SkBits2Float(0xc1df5274));
+path.cubicTo(SkBits2Float(0x422af677), SkBits2Float(0xc23e9438), SkBits2Float(0x41b24f58), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429a7334), SkBits2Float(0xc1f3598d));
+path.cubicTo(SkBits2Float(0x42ac9a56), SkBits2Float(0xc0ec08d5), SkBits2Float(0x42a93a4b), SkBits2Float(0x4194209c), SkBits2Float(0x42913f11), SkBits2Float(0x4220bdeb));
+path.cubicTo(SkBits2Float(0x427287b0), SkBits2Float(0x42776b87), SkBits2Float(0x421e5dc6), SkBits2Float(0x429a1372), SkBits2Float(0x4173f4a4), SkBits2Float(0x42a32ccd));
+path.lineTo(SkBits2Float(0x41305a7f), SkBits2Float(0x426bea6b));
+path.cubicTo(SkBits2Float(0x41e4f69e), SkBits2Float(0x425ec2af), SkBits2Float(0x422f52ad), SkBits2Float(0x4232db9e), SkBits2Float(0x4251feaa), SkBits2Float(0x41e865df));
+path.cubicTo(SkBits2Float(0x4274aaa7), SkBits2Float(0x41562902), SkBits2Float(0x42798bdd), SkBits2Float(0xc0aaa09a), SkBits2Float(0x425f4d1d), SkBits2Float(0xc1afea60));
+path.lineTo(SkBits2Float(0x429a7334), SkBits2Float(0xc1f3598d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp144(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42079c39), SkBits2Float(0xc2a60000), SkBits2Float(0x4280cb64), SkBits2Float(0xc279860f), SkBits2Float(0x429a0d79), SkBits2Float(0xc1f758df));
+path.lineTo(SkBits2Float(0x425eba08), SkBits2Float(0xc1b2ce1f));
+path.cubicTo(SkBits2Float(0x423a357b), SkBits2Float(0xc23460ea), SkBits2Float(0x41c41023), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429a0d79), SkBits2Float(0xc1f758de));
+path.cubicTo(SkBits2Float(0x429c811b), SkBits2Float(0xc1deea6e), SkBits2Float(0x429e9731), SkBits2Float(0xc1c5ec3a), SkBits2Float(0x42a04ce7), SkBits2Float(0xc1ac8024));
+path.lineTo(SkBits2Float(0x4267c277), SkBits2Float(0xc17965fc));
+path.cubicTo(SkBits2Float(0x426549a1), SkBits2Float(0xc18f13a3), SkBits2Float(0x42624575), SkBits2Float(0xc1a124d8), SkBits2Float(0x425eba09), SkBits2Float(0xc1b2ce1e));
+path.lineTo(SkBits2Float(0x429a0d79), SkBits2Float(0xc1f758de));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp145(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42079c39), SkBits2Float(0xc2a60000), SkBits2Float(0x4280cb64), SkBits2Float(0xc279860f), SkBits2Float(0x429a0d79), SkBits2Float(0xc1f758df));
+path.lineTo(SkBits2Float(0x42a04ce7), SkBits2Float(0xc1ac8024));
+path.lineTo(SkBits2Float(0x4267c277), SkBits2Float(0xc17965fc));
+path.cubicTo(SkBits2Float(0x426549a1), SkBits2Float(0xc18f13a3), SkBits2Float(0x42624575), SkBits2Float(0xc1a124d8), SkBits2Float(0x425eba09), SkBits2Float(0xc1b2ce1e));
+path.lineTo(SkBits2Float(0x425eba08), SkBits2Float(0xc1b2ce1f));
+path.cubicTo(SkBits2Float(0x423a357b), SkBits2Float(0xc23460ea), SkBits2Float(0x41c41023), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a04ce8), SkBits2Float(0xc1ac8024));
+path.cubicTo(SkBits2Float(0x42ae6ca1), SkBits2Float(0x4095ff41), SkBits2Float(0x42a1f1fa), SkBits2Float(0x4202ed54), SkBits2Float(0x427dc9de), SkBits2Float(0x42560b98));
+path.cubicTo(SkBits2Float(0x4237afc7), SkBits2Float(0x429494ee), SkBits2Float(0x419aa752), SkBits2Float(0x42aa57e8), SkBits2Float(0xc0f777b3), SkBits2Float(0x42a54724));
+path.lineTo(SkBits2Float(0xc0b2e472), SkBits2Float(0x426ef4bb));
+path.cubicTo(SkBits2Float(0x415f9870), SkBits2Float(0x42764794), SkBits2Float(0x4204c916), SkBits2Float(0x4256d126), SkBits2Float(0x4237762a), SkBits2Float(0x421abb46));
+path.cubicTo(SkBits2Float(0x426a233f), SkBits2Float(0x41bd4acb), SkBits2Float(0x427c2e04), SkBits2Float(0x4058dcfe), SkBits2Float(0x4267c279), SkBits2Float(0xc17965fc));
+path.lineTo(SkBits2Float(0x42a04ce8), SkBits2Float(0xc1ac8024));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp146(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x421472e7), SkBits2Float(0xc2a5ffff), SkBits2Float(0x428b6da4), SkBits2Float(0xc26973d7), SkBits2Float(0x429fb179), SkBits2Float(0xc1b54986));
+path.lineTo(SkBits2Float(0x4266e1be), SkBits2Float(0xc1830d0f));
+path.cubicTo(SkBits2Float(0x42499544), SkBits2Float(0xc228c2c8), SkBits2Float(0x41d69ff6), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429fb179), SkBits2Float(0xc1b54988));
+path.cubicTo(SkBits2Float(0x42a1a632), SkBits2Float(0xc199b837), SkBits2Float(0x42a3282f), SkBits2Float(0xc17b594e), SkBits2Float(0x42a43501), SkBits2Float(0xc142a7ba));
+path.lineTo(SkBits2Float(0x426d6865), SkBits2Float(0xc10cb6f0));
+path.cubicTo(SkBits2Float(0x426be3bc), SkBits2Float(0xc135b2ae), SkBits2Float(0x4269b5af), SkBits2Float(0xc15e3ec8), SkBits2Float(0x4266e1be), SkBits2Float(0xc1830d0f));
+path.lineTo(SkBits2Float(0x429fb179), SkBits2Float(0xc1b54988));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp147(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x421472e7), SkBits2Float(0xc2a60000), SkBits2Float(0x428b6da4), SkBits2Float(0xc26973d8), SkBits2Float(0x429fb179), SkBits2Float(0xc1b54988));
+path.lineTo(SkBits2Float(0x429fb179), SkBits2Float(0xc1b54986));
+path.cubicTo(SkBits2Float(0x42a1a632), SkBits2Float(0xc199b836), SkBits2Float(0x42a3282f), SkBits2Float(0xc17b594d), SkBits2Float(0x42a43501), SkBits2Float(0xc142a7ba));
+path.lineTo(SkBits2Float(0x426d6865), SkBits2Float(0xc10cb6f0));
+path.cubicTo(SkBits2Float(0x426be3bc), SkBits2Float(0xc135b2ae), SkBits2Float(0x4269b5af), SkBits2Float(0xc15e3ec8), SkBits2Float(0x4266e1be), SkBits2Float(0xc1830d0f));
+path.cubicTo(SkBits2Float(0x42499544), SkBits2Float(0xc228c2c8), SkBits2Float(0x41d69ff6), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a43502), SkBits2Float(0xc142a7bb));
+path.cubicTo(SkBits2Float(0x42ace9b0), SkBits2Float(0x4189ae79), SkBits2Float(0x429590d6), SkBits2Float(0x423ab1c1), SkBits2Float(0x424df762), SkBits2Float(0x428231a6));
+path.cubicTo(SkBits2Float(0x41e19a31), SkBits2Float(0x42a70a69), SkBits2Float(0xc04a3289), SkBits2Float(0x42b03133), SkBits2Float(0xc1f5f36e), SkBits2Float(0x429a3139));
+path.lineTo(SkBits2Float(0xc1b1cbb9), SkBits2Float(0x425eedb9));
+path.cubicTo(SkBits2Float(0xc0122aac), SkBits2Float(0x427ebc5a), SkBits2Float(0x41a31606), SkBits2Float(0x42718130), SkBits2Float(0x4214e430), SkBits2Float(0x423c3b73));
+path.cubicTo(SkBits2Float(0x42583d5c), SkBits2Float(0x4206f5b6), SkBits2Float(0x4279fe97), SkBits2Float(0x41470ec8), SkBits2Float(0x426d6866), SkBits2Float(0xc10cb6eb));
+path.lineTo(SkBits2Float(0x42a43502), SkBits2Float(0xc142a7bb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp148(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42216831), SkBits2Float(0xc2a60000), SkBits2Float(0x4295b6bc), SkBits2Float(0xc257ea44), SkBits2Float(0x42a38b53), SkBits2Float(0xc1639572));
+path.lineTo(SkBits2Float(0x426c7311), SkBits2Float(0xc12484b9));
+path.cubicTo(SkBits2Float(0x42587424), SkBits2Float(0xc21c154e), SkBits2Float(0x41e95c08), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a38b52), SkBits2Float(0xc1639578));
+path.cubicTo(SkBits2Float(0x42a4def8), SkBits2Float(0xc1269090), SkBits2Float(0x42a5a99a), SkBits2Float(0xc0d1c16f), SkBits2Float(0x42a5e9be), SkBits2Float(0xc02be63c));
+path.lineTo(SkBits2Float(0x426fdfd2), SkBits2Float(0xbff8877d));
+path.cubicTo(SkBits2Float(0x426f8319), SkBits2Float(0xc097a16e), SkBits2Float(0x426e5e22), SkBits2Float(0xc0f0d105), SkBits2Float(0x426c7311), SkBits2Float(0xc12484ba));
+path.lineTo(SkBits2Float(0x42a38b52), SkBits2Float(0xc1639578));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp149(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42216831), SkBits2Float(0xc2a60000), SkBits2Float(0x4295b6bc), SkBits2Float(0xc257ea44), SkBits2Float(0x42a38b52), SkBits2Float(0xc1639578));
+path.lineTo(SkBits2Float(0x426c7311), SkBits2Float(0xc12484ba));
+path.cubicTo(SkBits2Float(0x42587424), SkBits2Float(0xc21c154e), SkBits2Float(0x41e95c08), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a5e9be), SkBits2Float(0xc02be63f));
+path.cubicTo(SkBits2Float(0x42a7ff8e), SkBits2Float(0x41ec1faa), SkBits2Float(0x42849fff), SkBits2Float(0x426da4e1), SkBits2Float(0x4216595b), SkBits2Float(0x429400af));
+path.cubicTo(SkBits2Float(0x410dcade), SkBits2Float(0x42b12eec), SkBits2Float(0xc1cdb135), SkBits2Float(0x42aa7b1c), SkBits2Float(0xc24c6646), SkBits2Float(0x4282cf52));
+path.lineTo(SkBits2Float(0xc213c238), SkBits2Float(0x423d1f66));
+path.cubicTo(SkBits2Float(0xc194b176), SkBits2Float(0x42767a79), SkBits2Float(0x40cd0045), SkBits2Float(0x42801597), SkBits2Float(0x41d95f44), SkBits2Float(0x4255fad4));
+path.cubicTo(SkBits2Float(0x423fbf3c), SkBits2Float(0x422bca7a), SkBits2Float(0x4272e39a), SkBits2Float(0x41aab11f), SkBits2Float(0x426fdfd3), SkBits2Float(0xbff88758));
+path.lineTo(SkBits2Float(0x42a5e9be), SkBits2Float(0xc02be63f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp150(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x422dab0f), SkBits2Float(0xc2a5ffff), SkBits2Float(0x429efeec), SkBits2Float(0xc2462810), SkBits2Float(0x42a58789), SkBits2Float(0xc0c7d837));
+path.lineTo(SkBits2Float(0x426f51d5), SkBits2Float(0xc0907750));
+path.cubicTo(SkBits2Float(0x4265df9a), SkBits2Float(0xc20f3ee4), SkBits2Float(0x41fb162c), SkBits2Float(0xc26ffffe), SkBits2Float(0x3637fea5), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a58789), SkBits2Float(0xc0c7d840));
+path.cubicTo(SkBits2Float(0x42a626ff), SkBits2Float(0xc0078454), SkBits2Float(0x42a62824), SkBits2Float(0x4001c6d5), SkBits2Float(0x42a58af5), SkBits2Float(0x40c4fc3c));
+path.lineTo(SkBits2Float(0x426f56ca), SkBits2Float(0x408e6626));
+path.cubicTo(SkBits2Float(0x42703a0b), SkBits2Float(0x3fbba106), SkBits2Float(0x42703864), SkBits2Float(0xbfc3ed93), SkBits2Float(0x426f51d4), SkBits2Float(0xc090774f));
+path.lineTo(SkBits2Float(0x42a58789), SkBits2Float(0xc0c7d840));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp151(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x422dab0f), SkBits2Float(0xc2a60000), SkBits2Float(0x429efeec), SkBits2Float(0xc2462811), SkBits2Float(0x42a58789), SkBits2Float(0xc0c7d840));
+path.lineTo(SkBits2Float(0x42a58789), SkBits2Float(0xc0c7d837));
+path.cubicTo(SkBits2Float(0x42a626ff), SkBits2Float(0xc0078448), SkBits2Float(0x42a62824), SkBits2Float(0x4001c6db), SkBits2Float(0x42a58af5), SkBits2Float(0x40c4fc3c));
+path.lineTo(SkBits2Float(0x426f56ca), SkBits2Float(0x408e6626));
+path.cubicTo(SkBits2Float(0x42703a0b), SkBits2Float(0x3fbba106), SkBits2Float(0x42703864), SkBits2Float(0xbfc3ed93), SkBits2Float(0x426f51d4), SkBits2Float(0xc090774f));
+path.lineTo(SkBits2Float(0x426f51d5), SkBits2Float(0xc0907750));
+path.cubicTo(SkBits2Float(0x4265df9a), SkBits2Float(0xc20f3ee4), SkBits2Float(0x41fb162c), SkBits2Float(0xc26ffffe), SkBits2Float(0x3637fea5), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a58af6), SkBits2Float(0x40c4fc3d));
+path.cubicTo(SkBits2Float(0x42a06986), SkBits2Float(0x422298c3), SkBits2Float(0x42621341), SkBits2Float(0x428bdf10), SkBits2Float(0x41ba9762), SkBits2Float(0x429f4f99));
+path.cubicTo(SkBits2Float(0xc11def80), SkBits2Float(0x42b2c022), SkBits2Float(0xc236745f), SkBits2Float(0x429afb1c), SkBits2Float(0xc284c1e2), SkBits2Float(0x4247504a));
+path.lineTo(SkBits2Float(0xc23ff038), SkBits2Float(0x42101509));
+path.cubicTo(SkBits2Float(0xc203e517), SkBits2Float(0x4260119e), SkBits2Float(0xc0e45731), SkBits2Float(0x428137a0), SkBits2Float(0x4186e2a5), SkBits2Float(0x42665443));
+path.cubicTo(SkBits2Float(0x42236d8c), SkBits2Float(0x424a3945), SkBits2Float(0x4267ebda), SkBits2Float(0x41eb1462), SkBits2Float(0x426f56cb), SkBits2Float(0x408e661a));
+path.lineTo(SkBits2Float(0x42a58af6), SkBits2Float(0x40c4fc3d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp152(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41b12ed4), SkBits2Float(0xc2a60000), SkBits2Float(0x422d822c), SkBits2Float(0xc2944bde), SkBits2Float(0x426bdb91), SkBits2Float(0xc269a7f3));
+path.cubicTo(SkBits2Float(0x42951a7b), SkBits2Float(0xc22ab829), SkBits2Float(0x42a66879), SkBits2Float(0xc1aaf2b1), SkBits2Float(0x42a5fe21), SkBits2Float(0x3f4744a4));
+path.lineTo(SkBits2Float(0x426ffd4c), SkBits2Float(0x3f100c99));
+path.cubicTo(SkBits2Float(0x4270970c), SkBits2Float(0xc177275d), SkBits2Float(0x4257923d), SkBits2Float(0xc1f6d2bd), SkBits2Float(0x422a7fe2), SkBits2Float(0xc228e872));
+path.cubicTo(SkBits2Float(0x41fadb0b), SkBits2Float(0xc2566785), SkBits2Float(0x41801584), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a5fe22), SkBits2Float(0x3f4744a1));
+path.cubicTo(SkBits2Float(0x42a5e921), SkBits2Float(0x40a4df91), SkBits2Float(0x42a52322), SkBits2Float(0x411841f7), SkBits2Float(0x42a3adfe), SkBits2Float(0x415d43d0));
+path.lineTo(SkBits2Float(0x426ca531), SkBits2Float(0x411ff355));
+path.cubicTo(SkBits2Float(0x426ec0ad), SkBits2Float(0x40dc21ae), SkBits2Float(0x426fdeef), SkBits2Float(0x406e5efe), SkBits2Float(0x426ffd4d), SkBits2Float(0x3f100c9b));
+path.lineTo(SkBits2Float(0x42a5fe22), SkBits2Float(0x3f4744a1));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp153(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41b12ed4), SkBits2Float(0xc2a60000), SkBits2Float(0x422d822c), SkBits2Float(0xc2944bde), SkBits2Float(0x426bdb91), SkBits2Float(0xc269a7f3));
+path.cubicTo(SkBits2Float(0x42951a7b), SkBits2Float(0xc22ab829), SkBits2Float(0x42a66879), SkBits2Float(0xc1aaf2b1), SkBits2Float(0x42a5fe21), SkBits2Float(0x3f4744a0));
+path.lineTo(SkBits2Float(0x426ffd4c), SkBits2Float(0x3f100c99));
+path.cubicTo(SkBits2Float(0x4270970c), SkBits2Float(0xc177275d), SkBits2Float(0x4257923d), SkBits2Float(0xc1f6d2bd), SkBits2Float(0x422a7fe2), SkBits2Float(0xc228e872));
+path.cubicTo(SkBits2Float(0x41fadb0b), SkBits2Float(0xc2566785), SkBits2Float(0x41801584), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a3adfe), SkBits2Float(0x415d43d0));
+path.cubicTo(SkBits2Float(0x42977493), SkBits2Float(0x42480062), SkBits2Float(0x423a617c), SkBits2Float(0x429bbd03), SkBits2Float(0x4123044a), SkBits2Float(0x42a4be9a));
+path.cubicTo(SkBits2Float(0xc1d1beaf), SkBits2Float(0x42adc030), SkBits2Float(0xc2750d30), SkBits2Float(0x4285e3a3), SkBits2Float(0xc2980208), SkBits2Float(0x42056911));
+path.lineTo(SkBits2Float(0xc25bc541), SkBits2Float(0x41c0e1ed));
+path.cubicTo(SkBits2Float(0xc231254e), SkBits2Float(0x42419328), SkBits2Float(0xc1979f72), SkBits2Float(0x427b34be), SkBits2Float(0x40ebafde), SkBits2Float(0x426e2f5c));
+path.cubicTo(SkBits2Float(0x4206bbb1), SkBits2Float(0x426129fa), SkBits2Float(0x425af8c2), SkBits2Float(0x42109457), SkBits2Float(0x426ca533), SkBits2Float(0x411ff35b));
+path.lineTo(SkBits2Float(0x42a3adfe), SkBits2Float(0x415d43d0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp154(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41bb5603), SkBits2Float(0xc2a60000), SkBits2Float(0x4236fa4e), SkBits2Float(0xc2923760), SkBits2Float(0x4275e892), SkBits2Float(0xc25f0dc8));
+path.cubicTo(SkBits2Float(0x429a6b6b), SkBits2Float(0xc219acd0), SkBits2Float(0x42a9c473), SkBits2Float(0xc173c3a6), SkBits2Float(0x42a5369d), SkBits2Float(0x410121d8));
+path.lineTo(SkBits2Float(0x426edcd8), SkBits2Float(0x40bab276));
+path.cubicTo(SkBits2Float(0x42757264), SkBits2Float(0xc1303715), SkBits2Float(0x425f41dd), SkBits2Float(0xc1de2e4a), SkBits2Float(0x4231c3e2), SkBits2Float(0xc2213e66));
+path.cubicTo(SkBits2Float(0x420445e8), SkBits2Float(0xc25365a8), SkBits2Float(0x41876c72), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a5369e), SkBits2Float(0x410121d6));
+path.cubicTo(SkBits2Float(0x42a450b5), SkBits2Float(0x414aab85), SkBits2Float(0x42a2a6cd), SkBits2Float(0x4189bd6e), SkBits2Float(0x42a03d57), SkBits2Float(0x41ad66e6));
+path.lineTo(SkBits2Float(0x4267abf7), SkBits2Float(0x417ab39f));
+path.cubicTo(SkBits2Float(0x426b28ae), SkBits2Float(0x41472463), SkBits2Float(0x426d9071), SkBits2Float(0x41128229), SkBits2Float(0x426edcd8), SkBits2Float(0x40bab277));
+path.lineTo(SkBits2Float(0x42a5369e), SkBits2Float(0x410121d6));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp155(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41bb5603), SkBits2Float(0xc2a60000), SkBits2Float(0x4236fa4e), SkBits2Float(0xc2923760), SkBits2Float(0x4275e892), SkBits2Float(0xc25f0dc8));
+path.cubicTo(SkBits2Float(0x429a6b6b), SkBits2Float(0xc219acd0), SkBits2Float(0x42a9c473), SkBits2Float(0xc173c3a8), SkBits2Float(0x42a5369d), SkBits2Float(0x410121d5));
+path.lineTo(SkBits2Float(0x42a5369e), SkBits2Float(0x410121d6));
+path.cubicTo(SkBits2Float(0x42a450b5), SkBits2Float(0x414aab85), SkBits2Float(0x42a2a6cd), SkBits2Float(0x4189bd6e), SkBits2Float(0x42a03d57), SkBits2Float(0x41ad66e6));
+path.lineTo(SkBits2Float(0x4267abf7), SkBits2Float(0x417ab39f));
+path.cubicTo(SkBits2Float(0x426b28ae), SkBits2Float(0x41472463), SkBits2Float(0x426d9071), SkBits2Float(0x41128229), SkBits2Float(0x426edcd8), SkBits2Float(0x40bab276));
+path.cubicTo(SkBits2Float(0x42757264), SkBits2Float(0xc1303715), SkBits2Float(0x425f41dd), SkBits2Float(0xc1de2e4a), SkBits2Float(0x4231c3e2), SkBits2Float(0xc2213e66));
+path.cubicTo(SkBits2Float(0x420445e8), SkBits2Float(0xc25365a8), SkBits2Float(0x41876c72), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a03d58), SkBits2Float(0x41ad66e7));
+path.cubicTo(SkBits2Float(0x428bedd4), SkBits2Float(0x426cda0a), SkBits2Float(0x420c6f35), SkBits2Float(0x42a955c4), SkBits2Float(0xc06f4c79), SkBits2Float(0x42a5d4d6));
+path.cubicTo(SkBits2Float(0xc22a58c2), SkBits2Float(0x42a253e8), SkBits2Float(0xc2960525), SkBits2Float(0x4252b394), SkBits2Float(0xc2a37db3), SkBits2Float(0x41660422));
+path.lineTo(SkBits2Float(0xc26c5f63), SkBits2Float(0x412646cf));
+path.cubicTo(SkBits2Float(0xc258e58a), SkBits2Float(0x4218507a), SkBits2Float(0xc1f648da), SkBits2Float(0x426ab0dc), SkBits2Float(0xc02cfcc3), SkBits2Float(0x426fc1a0));
+path.cubicTo(SkBits2Float(0x41cb09aa), SkBits2Float(0x4274d265), SkBits2Float(0x424a4e9e), SkBits2Float(0x422b37da), SkBits2Float(0x4267abf8), SkBits2Float(0x417ab398));
+path.lineTo(SkBits2Float(0x42a03d58), SkBits2Float(0x41ad66e7));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp156(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41c3ae1a), SkBits2Float(0xc2a60000), SkBits2Float(0x423eb2d3), SkBits2Float(0xc2906c00), SkBits2Float(0x427dc7c2), SkBits2Float(0xc2560e13));
+path.cubicTo(SkBits2Float(0x429e6e58), SkBits2Float(0xc20b4426), SkBits2Float(0x42abdf2b), SkBits2Float(0xc121d7a7), SkBits2Float(0x42a39f93), SkBits2Float(0x415fea21));
+path.lineTo(SkBits2Float(0x426c905a), SkBits2Float(0x4121ddae));
+path.cubicTo(SkBits2Float(0x42787d42), SkBits2Float(0xc0e9fd34), SkBits2Float(0x42650e94), SkBits2Float(0xc1c95949), SkBits2Float(0x423774a6), SkBits2Float(0xc21abd13));
+path.cubicTo(SkBits2Float(0x4209dab9), SkBits2Float(0xc250cd81), SkBits2Float(0x418d749b), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a39f93), SkBits2Float(0x415fea20));
+path.cubicTo(SkBits2Float(0x42a1ffad), SkBits2Float(0x4195f252), SkBits2Float(0x429f8ce1), SkBits2Float(0x41bb4c45), SkBits2Float(0x429c4e4c), SkBits2Float(0x41df969a));
+path.lineTo(SkBits2Float(0x4261fbff), SkBits2Float(0x41a1a14e));
+path.cubicTo(SkBits2Float(0x4266acd9), SkBits2Float(0x41876566), SkBits2Float(0x426a370e), SkBits2Float(0x4158ca4c), SkBits2Float(0x426c905b), SkBits2Float(0x4121ddaf));
+path.lineTo(SkBits2Float(0x42a39f93), SkBits2Float(0x415fea20));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp157(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41c3ae1a), SkBits2Float(0xc2a60000), SkBits2Float(0x423eb2d3), SkBits2Float(0xc2906c00), SkBits2Float(0x427dc7c2), SkBits2Float(0xc2560e13));
+path.cubicTo(SkBits2Float(0x429e6e58), SkBits2Float(0xc20b4426), SkBits2Float(0x42abdf2b), SkBits2Float(0xc121d7a8), SkBits2Float(0x42a39f93), SkBits2Float(0x415fea20));
+path.lineTo(SkBits2Float(0x42a39f93), SkBits2Float(0x415fea21));
+path.cubicTo(SkBits2Float(0x42a1ffad), SkBits2Float(0x4195f252), SkBits2Float(0x429f8ce1), SkBits2Float(0x41bb4c45), SkBits2Float(0x429c4e4c), SkBits2Float(0x41df969a));
+path.lineTo(SkBits2Float(0x4261fbff), SkBits2Float(0x41a1a14e));
+path.cubicTo(SkBits2Float(0x4266acd9), SkBits2Float(0x41876566), SkBits2Float(0x426a370e), SkBits2Float(0x4158ca4c), SkBits2Float(0x426c905b), SkBits2Float(0x4121ddaf));
+path.lineTo(SkBits2Float(0x426c905a), SkBits2Float(0x4121ddae));
+path.cubicTo(SkBits2Float(0x42787d42), SkBits2Float(0xc0e9fd34), SkBits2Float(0x42650e94), SkBits2Float(0xc1c95949), SkBits2Float(0x423774a6), SkBits2Float(0xc21abd13));
+path.cubicTo(SkBits2Float(0x4209dab9), SkBits2Float(0xc250cd81), SkBits2Float(0x418d749b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429c4e4c), SkBits2Float(0x41df969b));
+path.cubicTo(SkBits2Float(0x4280e391), SkBits2Float(0x4284903f), SkBits2Float(0x41c7a851), SkBits2Float(0x42b2072e), SkBits2Float(0xc1713833), SkBits2Float(0x42a33d14));
+path.cubicTo(SkBits2Float(0xc25c7040), SkBits2Float(0x429472fb), SkBits2Float(0xc2a7bda2), SkBits2Float(0x421b8b2e), SkBits2Float(0xc2a5f5d6), SkBits2Float(0xbfe85110));
+path.lineTo(SkBits2Float(0xc26ff14f), SkBits2Float(0xbfa7f00b));
+path.cubicTo(SkBits2Float(0xc272844c), SkBits2Float(0x41e0e1f3), SkBits2Float(0xc21f5a65), SkBits2Float(0x4256a019), SkBits2Float(0xc12e6015), SkBits2Float(0x426c01f9));
+path.cubicTo(SkBits2Float(0x419054b7), SkBits2Float(0x4280b1ec), SkBits2Float(0x423a5877), SkBits2Float(0x423fa872), SkBits2Float(0x4261fc02), SkBits2Float(0x41a1a142));
+path.lineTo(SkBits2Float(0x429c4e4c), SkBits2Float(0x41df969b));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp158(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41cb677f), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4245cb36), SkBits2Float(0xc28eb15b), SkBits2Float(0x42825fc2), SkBits2Float(0xc24d8299));
+path.cubicTo(SkBits2Float(0x42a1d9e8), SkBits2Float(0xc1fb44f8), SkBits2Float(0x42ad4967), SkBits2Float(0xc0aa7cf8), SkBits2Float(0x42a1679f), SkBits2Float(0x419b26cf));
+path.lineTo(SkBits2Float(0x42695b36), SkBits2Float(0x416050ca));
+path.cubicTo(SkBits2Float(0x427a88f8), SkBits2Float(0xc0767d2a), SkBits2Float(0x426a0074), SkBits2Float(0xc1b5a3f9), SkBits2Float(0x423c7e1d), SkBits2Float(0xc2148fc2));
+path.cubicTo(SkBits2Float(0x420efbc6), SkBits2Float(0xc24e4d87), SkBits2Float(0x41930a0e), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a1679f), SkBits2Float(0x419b26d0));
+path.cubicTo(SkBits2Float(0x429f113c), SkBits2Float(0x41c20ede), SkBits2Float(0x429bdafe), SkBits2Float(0x41e80a2e), SkBits2Float(0x4297ceee), SkBits2Float(0x42065107));
+path.lineTo(SkBits2Float(0x425b7b5f), SkBits2Float(0x41c2314a));
+path.cubicTo(SkBits2Float(0x4261554b), SkBits2Float(0x41a7bd56), SkBits2Float(0x4265fa14), SkBits2Float(0x418c4870), SkBits2Float(0x42695b37), SkBits2Float(0x416050cb));
+path.lineTo(SkBits2Float(0x42a1679f), SkBits2Float(0x419b26d0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp159(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41cb677f), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4245cb36), SkBits2Float(0xc28eb15b), SkBits2Float(0x42825fc2), SkBits2Float(0xc24d8299));
+path.cubicTo(SkBits2Float(0x42a1d9e8), SkBits2Float(0xc1fb44f8), SkBits2Float(0x42ad4967), SkBits2Float(0xc0aa7cf8), SkBits2Float(0x42a1679f), SkBits2Float(0x419b26d0));
+path.cubicTo(SkBits2Float(0x429f113c), SkBits2Float(0x41c20ede), SkBits2Float(0x429bdafe), SkBits2Float(0x41e80a2e), SkBits2Float(0x4297ceee), SkBits2Float(0x42065107));
+path.lineTo(SkBits2Float(0x425b7b5f), SkBits2Float(0x41c2314a));
+path.cubicTo(SkBits2Float(0x4261554b), SkBits2Float(0x41a7bd56), SkBits2Float(0x4265fa14), SkBits2Float(0x418c4870), SkBits2Float(0x42695b36), SkBits2Float(0x416050ca));
+path.cubicTo(SkBits2Float(0x427a88f8), SkBits2Float(0xc0767d2a), SkBits2Float(0x426a0074), SkBits2Float(0xc1b5a3f9), SkBits2Float(0x423c7e1d), SkBits2Float(0xc2148fc2));
+path.cubicTo(SkBits2Float(0x420efbc6), SkBits2Float(0xc24e4d87), SkBits2Float(0x41930a0e), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4297ceef), SkBits2Float(0x42065107));
+path.cubicTo(SkBits2Float(0x426afc81), SkBits2Float(0x4290b9e3), SkBits2Float(0x4171c53f), SkBits2Float(0x42b7f2c1), SkBits2Float(0xc1ca446b), SkBits2Float(0x429e1c54));
+path.cubicTo(SkBits2Float(0xc2835add), SkBits2Float(0x428445e8), SkBits2Float(0xc2b3ab9e), SkBits2Float(0x41c6c009), SkBits2Float(0xc2a29b10), SkBits2Float(0xc18596e4));
+path.lineTo(SkBits2Float(0xc26b17b4), SkBits2Float(0xc141242b));
+path.cubicTo(SkBits2Float(0xc281e1de), SkBits2Float(0x418faccb), SkBits2Float(0xc23de932), SkBits2Float(0x423f3d09), SkBits2Float(0xc19237aa), SkBits2Float(0x42649810));
+path.cubicTo(SkBits2Float(0x412ec628), SkBits2Float(0x4284f98c), SkBits2Float(0x4229deab), SkBits2Float(0x42513e23), SkBits2Float(0x425b7b62), SkBits2Float(0x41c23147));
+path.lineTo(SkBits2Float(0x4297ceef), SkBits2Float(0x42065107));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp160(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d3ccce), SkBits2Float(0xc2a5ffff), SkBits2Float(0x424d7252), SkBits2Float(0xc28cbd55), SkBits2Float(0x4285fbcc), SkBits2Float(0xc244010c));
+path.cubicTo(SkBits2Float(0x42a53e6e), SkBits2Float(0xc1dd0edd), SkBits2Float(0x42ae3d82), SkBits2Float(0xbdb630d0), SkBits2Float(0x429e3366), SkBits2Float(0x41c92323));
+path.lineTo(SkBits2Float(0x4264b95a), SkBits2Float(0x41916681));
+path.cubicTo(SkBits2Float(0x427be9e4), SkBits2Float(0xbd83b620), SkBits2Float(0x426ee823), SkBits2Float(0xc19fcd11), SkBits2Float(0x4241b610), SkBits2Float(0xc20db091));
+path.cubicTo(SkBits2Float(0x421483fd), SkBits2Float(0xc24b7a9a), SkBits2Float(0x41991bc1), SkBits2Float(0xc26fffff), SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429e3367), SkBits2Float(0x41c92322));
+path.cubicTo(SkBits2Float(0x429b0cbc), SkBits2Float(0x41f0ca9b), SkBits2Float(0x4296f94f), SkBits2Float(0x420b9629), SkBits2Float(0x429206e2), SkBits2Float(0x421de34f));
+path.lineTo(SkBits2Float(0x42531f8a), SkBits2Float(0x41e4458f));
+path.cubicTo(SkBits2Float(0x425a4685), SkBits2Float(0x41c9cfd9), SkBits2Float(0x42602b18), SkBits2Float(0x41ae10ed), SkBits2Float(0x4264b95a), SkBits2Float(0x41916682));
+path.lineTo(SkBits2Float(0x429e3367), SkBits2Float(0x41c92322));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp161(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d3ccce), SkBits2Float(0xc2a5ffff), SkBits2Float(0x424d7252), SkBits2Float(0xc28cbd55), SkBits2Float(0x4285fbcc), SkBits2Float(0xc244010c));
+path.cubicTo(SkBits2Float(0x42a53e6e), SkBits2Float(0xc1dd0edd), SkBits2Float(0x42ae3d82), SkBits2Float(0xbdb630d0), SkBits2Float(0x429e3367), SkBits2Float(0x41c92322));
+path.cubicTo(SkBits2Float(0x429b0cbc), SkBits2Float(0x41f0ca9b), SkBits2Float(0x4296f94f), SkBits2Float(0x420b9629), SkBits2Float(0x429206e2), SkBits2Float(0x421de34f));
+path.lineTo(SkBits2Float(0x42531f8a), SkBits2Float(0x41e4458f));
+path.cubicTo(SkBits2Float(0x425a4685), SkBits2Float(0x41c9cfd9), SkBits2Float(0x42602b18), SkBits2Float(0x41ae10ed), SkBits2Float(0x4264b95a), SkBits2Float(0x41916681));
+path.cubicTo(SkBits2Float(0x427be9e4), SkBits2Float(0xbd83b620), SkBits2Float(0x426ee823), SkBits2Float(0xc19fcd11), SkBits2Float(0x4241b610), SkBits2Float(0xc20db091));
+path.cubicTo(SkBits2Float(0x421483fd), SkBits2Float(0xc24b7a9a), SkBits2Float(0x41991bc1), SkBits2Float(0xc26fffff), SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429206e2), SkBits2Float(0x421de34f));
+path.cubicTo(SkBits2Float(0x424fd7be), SkBits2Float(0x429cd433), SkBits2Float(0x40819da9), SkBits2Float(0x42bbf605), SkBits2Float(0xc20f7b98), SkBits2Float(0x4295b271));
+path.cubicTo(SkBits2Float(0xc2979573), SkBits2Float(0x425eddba), SkBits2Float(0xc2bb57fe), SkBits2Float(0x4109ef62), SkBits2Float(0xc2990315), SkBits2Float(0xc200bcbb));
+path.lineTo(SkBits2Float(0xc25d38e3), SkBits2Float(0xc1ba2048));
+path.cubicTo(SkBits2Float(0xc2876de1), SkBits2Float(0x40c76c9c), SkBits2Float(0xc25b2842), SkBits2Float(0x42211baa), SkBits2Float(0xc1cf71e5), SkBits2Float(0x42586df1));
+path.cubicTo(SkBits2Float(0x403b65b7), SkBits2Float(0x4287e01c), SkBits2Float(0x42163f6f), SkBits2Float(0x4262bd95), SkBits2Float(0x42531f8c), SkBits2Float(0x41e4458b));
+path.lineTo(SkBits2Float(0x429206e2), SkBits2Float(0x421de34f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp162(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41da3d7f), SkBits2Float(0xc2a60000), SkBits2Float(0x425345ee), SkBits2Float(0xc28b3082), SkBits2Float(0x4288a01b), SkBits2Float(0xc23c9177));
+path.cubicTo(SkBits2Float(0x42a79d3f), SkBits2Float(0xc1c583d9), SkBits2Float(0x42ae8eeb), SkBits2Float(0x407c6461), SkBits2Float(0x429b333a), SkBits2Float(0x41eb9731));
+path.lineTo(SkBits2Float(0x426062bb), SkBits2Float(0x41aa4e75));
+path.cubicTo(SkBits2Float(0x427c5f9a), SkBits2Float(0x403673d5), SkBits2Float(0x4272557b), SkBits2Float(0xc18ec82c), SkBits2Float(0x424587e0), SkBits2Float(0xc208507b));
+path.cubicTo(SkBits2Float(0x4218ba46), SkBits2Float(0xc2493ce1), SkBits2Float(0x419dc399), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429b3339), SkBits2Float(0x41eb9733));
+path.cubicTo(SkBits2Float(0x429766b3), SkBits2Float(0x4209d0f3), SkBits2Float(0x4292a485), SkBits2Float(0x421d0e17), SkBits2Float(0x428cfdb5), SkBits2Float(0x422f3e33));
+path.lineTo(SkBits2Float(0x424bd7ac), SkBits2Float(0x41fd5d06));
+path.cubicTo(SkBits2Float(0x42540374), SkBits2Float(0x41e3114e), SkBits2Float(0x425ae4ae), SkBits2Float(0x41c7409b), SkBits2Float(0x426062bc), SkBits2Float(0x41aa4e76));
+path.lineTo(SkBits2Float(0x429b3339), SkBits2Float(0x41eb9733));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp163(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41da3d7f), SkBits2Float(0xc2a60000), SkBits2Float(0x425345ee), SkBits2Float(0xc28b3082), SkBits2Float(0x4288a01b), SkBits2Float(0xc23c9177));
+path.cubicTo(SkBits2Float(0x42a79d3f), SkBits2Float(0xc1c583d9), SkBits2Float(0x42ae8eeb), SkBits2Float(0x407c6461), SkBits2Float(0x429b3339), SkBits2Float(0x41eb9733));
+path.cubicTo(SkBits2Float(0x429766b3), SkBits2Float(0x4209d0f3), SkBits2Float(0x4292a485), SkBits2Float(0x421d0e17), SkBits2Float(0x428cfdb5), SkBits2Float(0x422f3e33));
+path.lineTo(SkBits2Float(0x424bd7ac), SkBits2Float(0x41fd5d06));
+path.cubicTo(SkBits2Float(0x42540374), SkBits2Float(0x41e3114e), SkBits2Float(0x425ae4ae), SkBits2Float(0x41c7409b), SkBits2Float(0x426062bb), SkBits2Float(0x41aa4e75));
+path.cubicTo(SkBits2Float(0x427c5f9a), SkBits2Float(0x403673d5), SkBits2Float(0x4272557b), SkBits2Float(0xc18ec82c), SkBits2Float(0x424587e0), SkBits2Float(0xc208507b));
+path.cubicTo(SkBits2Float(0x4218ba46), SkBits2Float(0xc2493ce1), SkBits2Float(0x419dc399), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x428cfdb5), SkBits2Float(0x422f3e36));
+path.cubicTo(SkBits2Float(0x42397b9c), SkBits2Float(0x42a54202), SkBits2Float(0xc0931849), SkBits2Float(0x42bd474f), SkBits2Float(0xc22e0fe8), SkBits2Float(0x428d5ab7));
+path.cubicTo(SkBits2Float(0xc2a4de63), SkBits2Float(0x423adc3f), SkBits2Float(0xc2bd50df), SkBits2Float(0xc08673c0), SkBits2Float(0xc28db7cd), SkBits2Float(0xc22ce1b4));
+path.lineTo(SkBits2Float(0xc24ce4bb), SkBits2Float(0xc1f9f306));
+path.cubicTo(SkBits2Float(0xc288db72), SkBits2Float(0xc0426216), SkBits2Float(0xc26e5ec8), SkBits2Float(0x42071590), SkBits2Float(0xc1fba9c9), SkBits2Float(0x424c5fa5));
+path.cubicTo(SkBits2Float(0xc054b001), SkBits2Float(0x4288d4dc), SkBits2Float(0x420615fc), SkBits2Float(0x426eee67), SkBits2Float(0x424bd7af), SkBits2Float(0x41fd5d01));
+path.lineTo(SkBits2Float(0x428cfdb5), SkBits2Float(0x422f3e36));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp164(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41e183ec), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4259cec4), SkBits2Float(0xc2896274), SkBits2Float(0x428b79bc), SkBits2Float(0xc2340753));
+path.cubicTo(SkBits2Float(0x42aa0c16), SkBits2Float(0xc1aa937d), SkBits2Float(0x42ae7c71), SkBits2Float(0x41080a55), SkBits2Float(0x42974339), SkBits2Float(0x4208c1d5));
+path.lineTo(SkBits2Float(0x425ab161), SkBits2Float(0x41c5b8a2));
+path.cubicTo(SkBits2Float(0x427c44e4), SkBits2Float(0x40c4af5a), SkBits2Float(0x4275d9f7), SkBits2Float(0xc1769dba), SkBits2Float(0x4249a6c2), SkBits2Float(0xc2022424));
+path.cubicTo(SkBits2Float(0x421d738b), SkBits2Float(0xc246a0db), SkBits2Float(0x41a305f1), SkBits2Float(0xc2700000), SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42974339), SkBits2Float(0x4208c1d6));
+path.cubicTo(SkBits2Float(0x4292b5f8), SkBits2Float(0x421ce537), SkBits2Float(0x428d2a3f), SkBits2Float(0x42301305), SkBits2Float(0x4286b52e), SkBits2Float(0x4242022c));
+path.lineTo(SkBits2Float(0x4242c218), SkBits2Float(0x420c3f43));
+path.cubicTo(SkBits2Float(0x424c1813), SkBits2Float(0x41fe90b7), SkBits2Float(0x42541cae), SkBits2Float(0x41e2d634), SkBits2Float(0x425ab162), SkBits2Float(0x41c5b8a3));
+path.lineTo(SkBits2Float(0x42974339), SkBits2Float(0x4208c1d6));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp165(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41e183ec), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4259cec4), SkBits2Float(0xc2896274), SkBits2Float(0x428b79bc), SkBits2Float(0xc2340753));
+path.cubicTo(SkBits2Float(0x42aa0c16), SkBits2Float(0xc1aa937d), SkBits2Float(0x42ae7c71), SkBits2Float(0x41080a55), SkBits2Float(0x42974339), SkBits2Float(0x4208c1d6));
+path.cubicTo(SkBits2Float(0x4292b5f8), SkBits2Float(0x421ce537), SkBits2Float(0x428d2a3f), SkBits2Float(0x42301305), SkBits2Float(0x4286b52e), SkBits2Float(0x4242022c));
+path.lineTo(SkBits2Float(0x4242c218), SkBits2Float(0x420c3f43));
+path.cubicTo(SkBits2Float(0x424c1813), SkBits2Float(0x41fe90b7), SkBits2Float(0x42541cae), SkBits2Float(0x41e2d634), SkBits2Float(0x425ab161), SkBits2Float(0x41c5b8a2));
+path.cubicTo(SkBits2Float(0x427c44e4), SkBits2Float(0x40c4af5a), SkBits2Float(0x4275d9f7), SkBits2Float(0xc1769dba), SkBits2Float(0x4249a6c2), SkBits2Float(0xc2022424));
+path.cubicTo(SkBits2Float(0x421d738b), SkBits2Float(0xc246a0db), SkBits2Float(0x41a305f1), SkBits2Float(0xc2700000), SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4286b52e), SkBits2Float(0x4242022d));
+path.cubicTo(SkBits2Float(0x4245f9c6), SkBits2Float(0x42929b97), SkBits2Float(0x419b96e9), SkBits2Float(0x42ac9135), SkBits2Float(0xc12da222), SkBits2Float(0x42a4933a));
+path.cubicTo(SkBits2Float(0xc2249c85), SkBits2Float(0x429c9540), SkBits2Float(0xc2859c99), SkBits2Float(0x4267dd85), SkBits2Float(0xc29b4028), SkBits2Float(0x41eb0f05));
+path.cubicTo(SkBits2Float(0xc2b0e3b8), SkBits2Float(0x3f4c608a), SkBits2Float(0xc2a55c16), SkBits2Float(0xc1fb5a07), SkBits2Float(0xc27a7a78), SkBits2Float(0xc259e8d8));
+path.lineTo(SkBits2Float(0xc2351199), SkBits2Float(0xc21d8664));
+path.cubicTo(SkBits2Float(0xc26f12eb), SkBits2Float(0xc1b5b32d), SkBits2Float(0xc27fbe43), SkBits2Float(0x3f13bb74), SkBits2Float(0xc2607541), SkBits2Float(0x41a9ebcd));
+path.cubicTo(SkBits2Float(0xc2412c3e), SkBits2Float(0x42279ce1), SkBits2Float(0xc1edfdc7), SkBits2Float(0x4262625e), SkBits2Float(0xc0fb089d), SkBits2Float(0x426df06d));
+path.cubicTo(SkBits2Float(0x4160f2f1), SkBits2Float(0x42797e7c), SkBits2Float(0x420f1d6a), SkBits2Float(0x4253f671), SkBits2Float(0x4242c21c), SkBits2Float(0x420c3f41));
+path.lineTo(SkBits2Float(0x4286b52e), SkBits2Float(0x4242022d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp166(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41e5cd16), SkBits2Float(0xc2a60000), SkBits2Float(0x425da203), SkBits2Float(0xc2884b73), SkBits2Float(0x428d165b), SkBits2Float(0xc22eeec9));
+path.cubicTo(SkBits2Float(0x42ab5bb4), SkBits2Float(0xc19a8d5b), SkBits2Float(0x42ae3add), SkBits2Float(0x4132f7c2), SkBits2Float(0x4294adf4), SkBits2Float(0x4213a75b));
+path.lineTo(SkBits2Float(0x4256f554), SkBits2Float(0x41d579ab));
+path.cubicTo(SkBits2Float(0x427be612), SkBits2Float(0x41015fcf), SkBits2Float(0x4277bf2e), SkBits2Float(0xc15f72f6), SkBits2Float(0x424bfb4d), SkBits2Float(0xc1fcea38));
+path.cubicTo(SkBits2Float(0x4220376c), SkBits2Float(0xc2450d7a), SkBits2Float(0x41a61f08), SkBits2Float(0xc2700000), SkBits2Float(0xb7060057), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4294adf4), SkBits2Float(0x4213a75b));
+path.cubicTo(SkBits2Float(0x428facea), SkBits2Float(0x4227cf1b), SkBits2Float(0x4289a8e5), SkBits2Float(0x423ae500), SkBits2Float(0x4282b9a7), SkBits2Float(0x424c9dab));
+path.lineTo(SkBits2Float(0x423d0015), SkBits2Float(0x4213ea45));
+path.cubicTo(SkBits2Float(0x424706b3), SkBits2Float(0x42071ac0), SkBits2Float(0x424fb93a), SkBits2Float(0x41f29d8f), SkBits2Float(0x4256f555), SkBits2Float(0x41d579ac));
+path.lineTo(SkBits2Float(0x4294adf4), SkBits2Float(0x4213a75b));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp167(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb7060057), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41e5cd16), SkBits2Float(0xc2a60000), SkBits2Float(0x425da203), SkBits2Float(0xc2884b73), SkBits2Float(0x428d165b), SkBits2Float(0xc22eeec9));
+path.cubicTo(SkBits2Float(0x42ab5bb4), SkBits2Float(0xc19a8d5b), SkBits2Float(0x42ae3add), SkBits2Float(0x4132f7c2), SkBits2Float(0x4294adf4), SkBits2Float(0x4213a75b));
+path.cubicTo(SkBits2Float(0x428facea), SkBits2Float(0x4227cf1b), SkBits2Float(0x4289a8e5), SkBits2Float(0x423ae500), SkBits2Float(0x4282b9a7), SkBits2Float(0x424c9dab));
+path.lineTo(SkBits2Float(0x423d0015), SkBits2Float(0x4213ea45));
+path.cubicTo(SkBits2Float(0x424706b3), SkBits2Float(0x42071ac0), SkBits2Float(0x424fb93a), SkBits2Float(0x41f29d8f), SkBits2Float(0x4256f554), SkBits2Float(0x41d579ab));
+path.cubicTo(SkBits2Float(0x427be612), SkBits2Float(0x41015fcf), SkBits2Float(0x4277bf2e), SkBits2Float(0xc15f72f6), SkBits2Float(0x424bfb4d), SkBits2Float(0xc1fcea38));
+path.cubicTo(SkBits2Float(0x4220376c), SkBits2Float(0xc2450d7a), SkBits2Float(0x41a61f08), SkBits2Float(0xc2700000), SkBits2Float(0xb7060057), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4282b9a8), SkBits2Float(0x424c9dac));
+path.cubicTo(SkBits2Float(0x4238a98e), SkBits2Float(0x42975dcd), SkBits2Float(0x416d9db4), SkBits2Float(0x42aecc7f), SkBits2Float(0xc17bb856), SkBits2Float(0x42a2fd9a));
+path.cubicTo(SkBits2Float(0xc2394396), SkBits2Float(0x42972eb6), SkBits2Float(0xc28e09e8), SkBits2Float(0x42543e5a), SkBits2Float(0xc29f69c3), SkBits2Float(0x41b9307a));
+path.cubicTo(SkBits2Float(0xc2b0c99f), SkBits2Float(0xc0d86efe), SkBits2Float(0xc29f345f), SkBits2Float(0xc21c161b), SkBits2Float(0xc263c1d4), SkBits2Float(0xc2718f13));
+path.lineTo(SkBits2Float(0xc224a4cd), SkBits2Float(0xc22e9eef));
+path.cubicTo(SkBits2Float(0xc2662cd7), SkBits2Float(0xc1e1aab7), SkBits2Float(0xc27f98a3), SkBits2Float(0xc09c754c), SkBits2Float(0xc26679fe), SkBits2Float(0x4185df20));
+path.cubicTo(SkBits2Float(0xc24d5b58), SkBits2Float(0x42196dcb), SkBits2Float(0xc205ecef), SkBits2Float(0x425a93a6), SkBits2Float(0xc135f72f), SkBits2Float(0x426ba619));
+path.cubicTo(SkBits2Float(0x412bc560), SkBits2Float(0x427cb88a), SkBits2Float(0x42057da8), SkBits2Float(0x425ad7c5), SkBits2Float(0x423d0018), SkBits2Float(0x4213ea45));
+path.lineTo(SkBits2Float(0x4282b9a8), SkBits2Float(0x424c9dac));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp168(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ea54b9), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4261a7de), SkBits2Float(0xc2871f16), SkBits2Float(0x428ebc81), SkBits2Float(0xc2297f4d));
+path.cubicTo(SkBits2Float(0x42aca513), SkBits2Float(0xc18980da), SkBits2Float(0x42adc9a4), SkBits2Float(0x41604127), SkBits2Float(0x4291be57), SkBits2Float(0x421eee87));
+path.lineTo(SkBits2Float(0x4252b6a9), SkBits2Float(0x41e5c7e9));
+path.cubicTo(SkBits2Float(0x427b4260), SkBits2Float(0x41221c9f), SkBits2Float(0x42799b62), SkBits2Float(0xc146ccc2), SkBits2Float(0x424e5da6), SkBits2Float(0xc1f50e65));
+path.cubicTo(SkBits2Float(0x42231fea), SkBits2Float(0xc2435b34), SkBits2Float(0x41a9655c), SkBits2Float(0xc26ffffe), SkBits2Float(0x3725ffa9), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4291be57), SkBits2Float(0x421eee8a));
+path.cubicTo(SkBits2Float(0x428c4169), SkBits2Float(0x42330feb), SkBits2Float(0x4285bd57), SkBits2Float(0x4246005c), SkBits2Float(0x427c99ac), SkBits2Float(0x4257723d));
+path.lineTo(SkBits2Float(0x42369a46), SkBits2Float(0x421bbe89));
+path.cubicTo(SkBits2Float(0x42415bc7), SkBits2Float(0x420f2230), SkBits2Float(0x424ac771), SkBits2Float(0x4201714b), SkBits2Float(0x4252b6a9), SkBits2Float(0x41e5c7e9));
+path.lineTo(SkBits2Float(0x4291be57), SkBits2Float(0x421eee8a));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp169(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3725ffa9), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ea54b9), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4261a7de), SkBits2Float(0xc2871f16), SkBits2Float(0x428ebc81), SkBits2Float(0xc2297f4d));
+path.cubicTo(SkBits2Float(0x42aca513), SkBits2Float(0xc18980da), SkBits2Float(0x42adc9a4), SkBits2Float(0x41604127), SkBits2Float(0x4291be57), SkBits2Float(0x421eee8a));
+path.cubicTo(SkBits2Float(0x428c4169), SkBits2Float(0x42330feb), SkBits2Float(0x4285bd57), SkBits2Float(0x4246005c), SkBits2Float(0x427c99ac), SkBits2Float(0x4257723d));
+path.lineTo(SkBits2Float(0x42369a46), SkBits2Float(0x421bbe89));
+path.cubicTo(SkBits2Float(0x42415bc7), SkBits2Float(0x420f2230), SkBits2Float(0x424ac771), SkBits2Float(0x4201714b), SkBits2Float(0x4252b6a9), SkBits2Float(0x41e5c7e9));
+path.cubicTo(SkBits2Float(0x427b4260), SkBits2Float(0x41221c9f), SkBits2Float(0x42799b62), SkBits2Float(0xc146ccc2), SkBits2Float(0x424e5da6), SkBits2Float(0xc1f50e65));
+path.cubicTo(SkBits2Float(0x42231fea), SkBits2Float(0xc2435b34), SkBits2Float(0x41a9655c), SkBits2Float(0xc26ffffe), SkBits2Float(0x3725ffa9), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427c99ad), SkBits2Float(0x4257723e));
+path.cubicTo(SkBits2Float(0x422a2459), SkBits2Float(0x429c0ff6), SkBits2Float(0x411ef0c1), SkBits2Float(0x42b0a109), SkBits2Float(0xc1a68a7f), SkBits2Float(0x42a0b1a2));
+path.cubicTo(SkBits2Float(0xc24e46af), SkBits2Float(0x4290c23b), SkBits2Float(0xc296269a), SkBits2Float(0x423e3c04), SkBits2Float(0xc2a2b82b), SkBits2Float(0x41835b51));
+path.cubicTo(SkBits2Float(0xc2af49bc), SkBits2Float(0xc16b82d9), SkBits2Float(0xc2973524), SkBits2Float(0xc23adb29), SkBits2Float(0xc24965c6), SkBits2Float(0xc283f801));
+path.lineTo(SkBits2Float(0xc21196ae), SkBits2Float(0xc23ecc58));
+path.cubicTo(SkBits2Float(0xc25a9cfe), SkBits2Float(0xc20713a1), SkBits2Float(0xc27d6da1), SkBits2Float(0xc12a3fcc), SkBits2Float(0xc26b41bb), SkBits2Float(0x413de9a9));
+path.cubicTo(SkBits2Float(0xc25915d3), SkBits2Float(0x420984c8), SkBits2Float(0xc2151d75), SkBits2Float(0x42514a1b), SkBits2Float(0xc170c819), SkBits2Float(0x4268540a));
+path.cubicTo(SkBits2Float(0x40e5cb46), SkBits2Float(0x427f5dfa), SkBits2Float(0x41f5fd0c), SkBits2Float(0x4261a1d8), SkBits2Float(0x42369a4a), SkBits2Float(0x421bbe87));
+path.lineTo(SkBits2Float(0x427c99ad), SkBits2Float(0x4257723e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp170(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ef3488), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4265f5fc), SkBits2Float(0xc285d5a4), SkBits2Float(0x429072a6), SkBits2Float(0xc2239841));
+path.cubicTo(SkBits2Float(0x42adea4e), SkBits2Float(0xc16e14e5), SkBits2Float(0x42ad1da2), SkBits2Float(0x41886b20), SkBits2Float(0x428e5adb), SkBits2Float(0x422ac68e));
+path.lineTo(SkBits2Float(0x424dd078), SkBits2Float(0x41f6e790));
+path.cubicTo(SkBits2Float(0x427a49b4), SkBits2Float(0x41453b4b), SkBits2Float(0x427b719d), SkBits2Float(0xc12c1b6e), SkBits2Float(0x4250d71f), SkBits2Float(0xc1ec85c5));
+path.cubicTo(SkBits2Float(0x42263ca0), SkBits2Float(0xc2417eea), SkBits2Float(0x41aceb63), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x428e5adb), SkBits2Float(0x422ac690));
+path.cubicTo(SkBits2Float(0x42885732), SkBits2Float(0x423ed443), SkBits2Float(0x428148a8), SkBits2Float(0x42518e43), SkBits2Float(0x42729aa0), SkBits2Float(0x4262a4bd));
+path.lineTo(SkBits2Float(0x422f605c), SkBits2Float(0x4223d6b5));
+path.cubicTo(SkBits2Float(0x423aea98), SkBits2Float(0x42177c70), SkBits2Float(0x42451e76), SkBits2Float(0x4209f2e4), SkBits2Float(0x424dd078), SkBits2Float(0x41f6e792));
+path.lineTo(SkBits2Float(0x428e5adb), SkBits2Float(0x422ac690));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp171(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ef3488), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4265f5fc), SkBits2Float(0xc285d5a4), SkBits2Float(0x429072a6), SkBits2Float(0xc2239841));
+path.cubicTo(SkBits2Float(0x42adea4e), SkBits2Float(0xc16e14e5), SkBits2Float(0x42ad1da2), SkBits2Float(0x41886b20), SkBits2Float(0x428e5adb), SkBits2Float(0x422ac690));
+path.cubicTo(SkBits2Float(0x42885732), SkBits2Float(0x423ed443), SkBits2Float(0x428148a8), SkBits2Float(0x42518e43), SkBits2Float(0x42729aa0), SkBits2Float(0x4262a4bd));
+path.lineTo(SkBits2Float(0x422f605c), SkBits2Float(0x4223d6b5));
+path.cubicTo(SkBits2Float(0x423aea98), SkBits2Float(0x42177c70), SkBits2Float(0x42451e76), SkBits2Float(0x4209f2e4), SkBits2Float(0x424dd078), SkBits2Float(0x41f6e790));
+path.cubicTo(SkBits2Float(0x427a49b4), SkBits2Float(0x41453b4b), SkBits2Float(0x427b719d), SkBits2Float(0xc12c1b6e), SkBits2Float(0x4250d71f), SkBits2Float(0xc1ec85c5));
+path.cubicTo(SkBits2Float(0x42263ca0), SkBits2Float(0xc2417eea), SkBits2Float(0x41aceb63), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42729aa1), SkBits2Float(0x4262a4be));
+path.cubicTo(SkBits2Float(0x421a0aa1), SkBits2Float(0x42a0b8ab), SkBits2Float(0x4092ff14), SkBits2Float(0x42b1fc82), SkBits2Float(0xc1d17709), SkBits2Float(0x429d861f));
+path.cubicTo(SkBits2Float(0xc263d6eb), SkBits2Float(0x42890fbc), SkBits2Float(0xc29dea71), SkBits2Float(0x42253dbf), SkBits2Float(0xc2a5016a), SkBits2Float(0x4111261a));
+path.cubicTo(SkBits2Float(0xc2ac1862), SkBits2Float(0xc1b95567), SkBits2Float(0xc28cface), SkBits2Float(0xc25a1117), SkBits2Float(0xc22aafa6), SkBits2Float(0xc28e61ba));
+path.lineTo(SkBits2Float(0xc1f6c679), SkBits2Float(0xc24dda63));
+path.cubicTo(SkBits2Float(0xc24bd376), SkBits2Float(0xc21da377), SkBits2Float(0xc278cff1), SkBits2Float(0xc185f9db), SkBits2Float(0xc26e8fe1), SkBits2Float(0x40d1da84));
+path.cubicTo(SkBits2Float(0xc2644fd1), SkBits2Float(0x41eee71d), SkBits2Float(0xc224b3fc), SkBits2Float(0x4246293b), SkBits2Float(0xc1976b90), SkBits2Float(0x4263becd));
+path.cubicTo(SkBits2Float(0x405486c0), SkBits2Float(0x4280aa2f), SkBits2Float(0x41deb5f2), SkBits2Float(0x42685e3e), SkBits2Float(0x422f605e), SkBits2Float(0x4223d6b6));
+path.lineTo(SkBits2Float(0x42729aa1), SkBits2Float(0x4262a4be));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp172(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f30c96), SkBits2Float(0xc2a60000), SkBits2Float(0x426956a5), SkBits2Float(0xc284cd4a), SkBits2Float(0x4291c05e), SkBits2Float(0xc21ee718));
+path.cubicTo(SkBits2Float(0x42aed56a), SkBits2Float(0xc150ce71), SkBits2Float(0x42ac7181), SkBits2Float(0x419b8107), SkBits2Float(0x428b8516), SkBits2Float(0x4233e422));
+path.lineTo(SkBits2Float(0x4249b729), SkBits2Float(0x42020ab3));
+path.cubicTo(SkBits2Float(0x427950d3), SkBits2Float(0x4160d339), SkBits2Float(0x427cc584), SkBits2Float(0xc116f1c4), SkBits2Float(0x4252b998), SkBits2Float(0xc1e5bd26));
+path.cubicTo(SkBits2Float(0x4228adad), SkBits2Float(0xc24000b5), SkBits2Float(0x41afb2be), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x428b8516), SkBits2Float(0x4233e422));
+path.cubicTo(SkBits2Float(0x4285165c), SkBits2Float(0x4247d8d0), SkBits2Float(0x427b34bd), SkBits2Float(0x425a5d74), SkBits2Float(0x426a6401), SkBits2Float(0x426b20b1));
+path.lineTo(SkBits2Float(0x42297063), SkBits2Float(0x4229f8c9));
+path.cubicTo(SkBits2Float(0x42359840), SkBits2Float(0x421ddab1), SkBits2Float(0x42406a5a), SkBits2Float(0x421077b9), SkBits2Float(0x4249b72b), SkBits2Float(0x42020ab4));
+path.lineTo(SkBits2Float(0x428b8516), SkBits2Float(0x4233e422));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp173(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f30c96), SkBits2Float(0xc2a60000), SkBits2Float(0x426956a5), SkBits2Float(0xc284cd4a), SkBits2Float(0x4291c05e), SkBits2Float(0xc21ee718));
+path.cubicTo(SkBits2Float(0x42aed56a), SkBits2Float(0xc150ce71), SkBits2Float(0x42ac7181), SkBits2Float(0x419b8107), SkBits2Float(0x428b8516), SkBits2Float(0x4233e422));
+path.cubicTo(SkBits2Float(0x4285165c), SkBits2Float(0x4247d8d0), SkBits2Float(0x427b34bd), SkBits2Float(0x425a5d74), SkBits2Float(0x426a6401), SkBits2Float(0x426b20b1));
+path.lineTo(SkBits2Float(0x42297063), SkBits2Float(0x4229f8c9));
+path.cubicTo(SkBits2Float(0x42359840), SkBits2Float(0x421ddab1), SkBits2Float(0x42406a5a), SkBits2Float(0x421077b9), SkBits2Float(0x4249b72b), SkBits2Float(0x42020ab4));
+path.lineTo(SkBits2Float(0x4249b729), SkBits2Float(0x42020ab3));
+path.cubicTo(SkBits2Float(0x427950d3), SkBits2Float(0x4160d339), SkBits2Float(0x427cc584), SkBits2Float(0xc116f1c4), SkBits2Float(0x4252b998), SkBits2Float(0xc1e5bd26));
+path.cubicTo(SkBits2Float(0x4228adad), SkBits2Float(0xc24000b5), SkBits2Float(0x41afb2be), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x426a6401), SkBits2Float(0x426b20b0));
+path.cubicTo(SkBits2Float(0x420d0644), SkBits2Float(0x42a419c2), SkBits2Float(0x3eb79d8f), SkBits2Float(0x42b29b69), SkBits2Float(0xc1f292a7), SkBits2Float(0x429a86c6));
+path.cubicTo(SkBits2Float(0xc27401e4), SkBits2Float(0x42827223), SkBits2Float(0xc2a34d81), SkBits2Float(0x4210aea0), SkBits2Float(0xc2a5dfaf), SkBits2Float(0x404f3106));
+path.cubicTo(SkBits2Float(0xc2a871dd), SkBits2Float(0xc1ed90fa), SkBits2Float(0xc283ccf3), SkBits2Float(0xc27113da), SkBits2Float(0xc21101fe), SkBits2Float(0xc2955440));
+path.lineTo(SkBits2Float(0xc1d1a65c), SkBits2Float(0xc257e5c3));
+path.cubicTo(SkBits2Float(0xc23e8e16), SkBits2Float(0xc22e45d9), SkBits2Float(0xc27388d2), SkBits2Float(0xc1abbc0d), SkBits2Float(0xc26fd138), SkBits2Float(0x4015c6fe));
+path.cubicTo(SkBits2Float(0xc26c199f), SkBits2Float(0x41d12dcc), SkBits2Float(0xc2306400), SkBits2Float(0x423c98a5), SkBits2Float(0xc1af5a7e), SkBits2Float(0x425f695f));
+path.cubicTo(SkBits2Float(0x3e84bf70), SkBits2Float(0x42811d0c), SkBits2Float(0x41cbe40c), SkBits2Float(0x426d40fa), SkBits2Float(0x42297064), SkBits2Float(0x4229f8cc));
+path.lineTo(SkBits2Float(0x426a6401), SkBits2Float(0x426b20b0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp174(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f67553), SkBits2Float(0xc2a5ffff), SkBits2Float(0x426c5214), SkBits2Float(0xc283df7d), SkBits2Float(0x4292df93), SkBits2Float(0xc21ab724));
+path.cubicTo(SkBits2Float(0x42af961c), SkBits2Float(0xc136bd38), SkBits2Float(0x42abbe10), SkBits2Float(0x41ac5dd5), SkBits2Float(0x4288e395), SkBits2Float(0x423bcd53));
+path.lineTo(SkBits2Float(0x4245e96c), SkBits2Float(0x4207c2b1));
+path.cubicTo(SkBits2Float(0x42784d66), SkBits2Float(0x41793464), SkBits2Float(0x427ddc1f), SkBits2Float(0xc10419c2), SkBits2Float(0x425458d8), SkBits2Float(0xc1dfaf58));
+path.cubicTo(SkBits2Float(0x422ad590), SkBits2Float(0xc23ea8e8), SkBits2Float(0x41b229a4), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4288e396), SkBits2Float(0x423bcd52));
+path.cubicTo(SkBits2Float(0x42821571), SkBits2Float(0x424fa4b8), SkBits2Float(0x427470be), SkBits2Float(0x4261f24c), SkBits2Float(0x4262dfb6), SkBits2Float(0x4272637b));
+path.lineTo(SkBits2Float(0x42240156), SkBits2Float(0x422f387f));
+path.cubicTo(SkBits2Float(0x4230b436), SkBits2Float(0x422355b8), SkBits2Float(0x423c12ab), SkBits2Float(0x42161a8d), SkBits2Float(0x4245e96e), SkBits2Float(0x4207c2b2));
+path.lineTo(SkBits2Float(0x4288e396), SkBits2Float(0x423bcd52));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp175(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f67553), SkBits2Float(0xc2a5ffff), SkBits2Float(0x426c5214), SkBits2Float(0xc283df7d), SkBits2Float(0x4292df93), SkBits2Float(0xc21ab724));
+path.cubicTo(SkBits2Float(0x42af961c), SkBits2Float(0xc136bd38), SkBits2Float(0x42abbe10), SkBits2Float(0x41ac5dd5), SkBits2Float(0x4288e396), SkBits2Float(0x423bcd52));
+path.cubicTo(SkBits2Float(0x42821571), SkBits2Float(0x424fa4b8), SkBits2Float(0x427470be), SkBits2Float(0x4261f24c), SkBits2Float(0x4262dfb6), SkBits2Float(0x4272637b));
+path.lineTo(SkBits2Float(0x42240156), SkBits2Float(0x422f387f));
+path.cubicTo(SkBits2Float(0x4230b436), SkBits2Float(0x422355b8), SkBits2Float(0x423c12ab), SkBits2Float(0x42161a8d), SkBits2Float(0x4245e96e), SkBits2Float(0x4207c2b2));
+path.lineTo(SkBits2Float(0x4245e96c), SkBits2Float(0x4207c2b1));
+path.cubicTo(SkBits2Float(0x42784d66), SkBits2Float(0x41793464), SkBits2Float(0x427ddc1f), SkBits2Float(0xc10419c2), SkBits2Float(0x425458d8), SkBits2Float(0xc1dfaf58));
+path.cubicTo(SkBits2Float(0x422ad590), SkBits2Float(0xc23ea8e8), SkBits2Float(0x41b229a4), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4262dfb7), SkBits2Float(0x4272637c));
+path.cubicTo(SkBits2Float(0x4201435c), SkBits2Float(0x42a6e035), SkBits2Float(0xc05a052a), SkBits2Float(0x42b2d330), SkBits2Float(0xc207a774), SkBits2Float(0x429782c3));
+path.cubicTo(SkBits2Float(0xc280d74a), SkBits2Float(0x427864aa), SkBits2Float(0xc2a78489), SkBits2Float(0x41fbcc10), SkBits2Float(0xc2a5f467), SkBits2Float(0xbff86670));
+path.cubicTo(SkBits2Float(0xc2a46445), SkBits2Float(0xc20d6c6d), SkBits2Float(0xc275c9b5), SkBits2Float(0xc2821580), SkBits2Float(0xc1f2ade6), SkBits2Float(0xc29a8413));
+path.lineTo(SkBits2Float(0xc1af6e4e), SkBits2Float(0xc25f6582));
+path.cubicTo(SkBits2Float(0xc231ad90), SkBits2Float(0xc23c12bd), SkBits2Float(0xc26dacb3), SkBits2Float(0xc1cc77b7), SkBits2Float(0xc26fef30), SkBits2Float(0xbfb390a5));
+path.cubicTo(SkBits2Float(0xc27231ae), SkBits2Float(0x41b605a0), SkBits2Float(0xc23a46a0), SkBits2Float(0x42338faf), SkBits2Float(0xc1c42047), SkBits2Float(0x425b0d36));
+path.cubicTo(SkBits2Float(0xc01d9a6d), SkBits2Float(0x4281455e), SkBits2Float(0x41bae2f1), SkBits2Float(0x42714420), SkBits2Float(0x42240157), SkBits2Float(0x422f387f));
+path.lineTo(SkBits2Float(0x4262dfb7), SkBits2Float(0x4272637c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp176(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f9cdf3), SkBits2Float(0xc2a5ffff), SkBits2Float(0x426f3c43), SkBits2Float(0xc282f30b), SkBits2Float(0x4293f176), SkBits2Float(0xc2169536));
+path.cubicTo(SkBits2Float(0x42b044ca), SkBits2Float(0xc11d115b), SkBits2Float(0x42aaf59e), SkBits2Float(0x41bcd986), SkBits2Float(0x428633ff), SkBits2Float(0x42436703));
+path.lineTo(SkBits2Float(0x42420751), SkBits2Float(0x420d4138));
+path.cubicTo(SkBits2Float(0x42772b98), SkBits2Float(0x41888496), SkBits2Float(0x427ed8af), SkBits2Float(0xc0e315f7), SkBits2Float(0x4255e4d4), SkBits2Float(0xc1d9b5cc));
+path.cubicTo(SkBits2Float(0x422cf0fb), SkBits2Float(0xc23d530d), SkBits2Float(0x41b494e9), SkBits2Float(0xc2700000), SkBits2Float(0x3743ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x428633ff), SkBits2Float(0x42436705));
+path.cubicTo(SkBits2Float(0x427e0fd0), SkBits2Float(0x42571b29), SkBits2Float(0x426d975d), SkBits2Float(0x42692b9b), SkBits2Float(0x425b4ae0), SkBits2Float(0x427944c1));
+path.lineTo(SkBits2Float(0x421e8652), SkBits2Float(0x423431b3));
+path.cubicTo(SkBits2Float(0x422bc0b3), SkBits2Float(0x42288e8e), SkBits2Float(0x4237a8bb), SkBits2Float(0x421b7f95), SkBits2Float(0x42420752), SkBits2Float(0x420d4138));
+path.lineTo(SkBits2Float(0x428633ff), SkBits2Float(0x42436705));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp177(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3743ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f9cdf3), SkBits2Float(0xc2a5ffff), SkBits2Float(0x426f3c43), SkBits2Float(0xc282f30b), SkBits2Float(0x4293f176), SkBits2Float(0xc2169536));
+path.cubicTo(SkBits2Float(0x42b044ca), SkBits2Float(0xc11d115b), SkBits2Float(0x42aaf59e), SkBits2Float(0x41bcd986), SkBits2Float(0x428633ff), SkBits2Float(0x42436705));
+path.cubicTo(SkBits2Float(0x427e0fd0), SkBits2Float(0x42571b29), SkBits2Float(0x426d975d), SkBits2Float(0x42692b9b), SkBits2Float(0x425b4ae0), SkBits2Float(0x427944c1));
+path.lineTo(SkBits2Float(0x421e8652), SkBits2Float(0x423431b3));
+path.cubicTo(SkBits2Float(0x422bc0b3), SkBits2Float(0x42288e8e), SkBits2Float(0x4237a8bb), SkBits2Float(0x421b7f95), SkBits2Float(0x42420751), SkBits2Float(0x420d4138));
+path.cubicTo(SkBits2Float(0x42772b98), SkBits2Float(0x41888496), SkBits2Float(0x427ed8af), SkBits2Float(0xc0e315f7), SkBits2Float(0x4255e4d4), SkBits2Float(0xc1d9b5cc));
+path.cubicTo(SkBits2Float(0x422cf0fb), SkBits2Float(0xc23d530d), SkBits2Float(0x41b494e9), SkBits2Float(0xc2700000), SkBits2Float(0x3743ffa9), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x425b4ae0), SkBits2Float(0x427944c0));
+path.cubicTo(SkBits2Float(0x41eb12b8), SkBits2Float(0x42a964d5), SkBits2Float(0xc0e3546a), SkBits2Float(0x42b2bc1c), SkBits2Float(0xc2157060), SkBits2Float(0x42943ba4));
+path.cubicTo(SkBits2Float(0xc2873b19), SkBits2Float(0x426b7658), SkBits2Float(0xc2ab209f), SkBits2Float(0x41d60b1d), SkBits2Float(0xc2a5685b), SkBits2Float(0xc0e02f3c));
+path.cubicTo(SkBits2Float(0xc29fb018), SkBits2Float(0xc223115c), SkBits2Float(0xc263001e), SkBits2Float(0xc28acd07), SkBits2Float(0xc1c2e1a0), SkBits2Float(0xc29eb07c));
+path.lineTo(SkBits2Float(0xc18ce0d1), SkBits2Float(0xc2656e32));
+path.cubicTo(SkBits2Float(0xc22418c2), SkBits2Float(0xc248ad0a), SkBits2Float(0xc266dfbc), SkBits2Float(0xc1ebc2b6), SkBits2Float(0xc26f24bb), SkBits2Float(0xc0a20f94));
+path.cubicTo(SkBits2Float(0xc27769ba), SkBits2Float(0x419abaee), SkBits2Float(0xc24383ac), SkBits2Float(0x422a36b0), SkBits2Float(0xc1d80e5c), SkBits2Float(0x4256500a));
+path.cubicTo(SkBits2Float(0xc0a45587), SkBits2Float(0x428134b2), SkBits2Float(0x41a9eeb8), SkBits2Float(0x4274e820), SkBits2Float(0x421e8655), SkBits2Float(0x423431b1));
+path.lineTo(SkBits2Float(0x425b4ae0), SkBits2Float(0x427944c0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp178(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41fc5f30), SkBits2Float(0xc2a5fffe), SkBits2Float(0x427176a0), SkBits2Float(0xc2823b95), SkBits2Float(0x4294be35), SkBits2Float(0xc21365c9));
+path.cubicTo(SkBits2Float(0x42b0c118), SkBits2Float(0xc1095198), SkBits2Float(0x42aa4b8f), SkBits2Float(0x41c9721a), SkBits2Float(0x42841312), SkBits2Float(0x42491ec0));
+path.lineTo(SkBits2Float(0x423ef37b), SkBits2Float(0x42116356));
+path.cubicTo(SkBits2Float(0x427635bc), SkBits2Float(0x41919f96), SkBits2Float(0x427f8c66), SkBits2Float(0xc0c68887), SkBits2Float(0x42570cd6), SkBits2Float(0xc1d51ae4));
+path.cubicTo(SkBits2Float(0x422e8d45), SkBits2Float(0xc23c49d3), SkBits2Float(0x41b66ffd), SkBits2Float(0xc2700000), SkBits2Float(0xb7060057), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42841313), SkBits2Float(0x42491ebf));
+path.cubicTo(SkBits2Float(0x42793d8e), SkBits2Float(0x425cb36e), SkBits2Float(0x4268336d), SkBits2Float(0x426e9032), SkBits2Float(0x4255582b), SkBits2Float(0x427e60c5));
+path.lineTo(SkBits2Float(0x421a3990), SkBits2Float(0x4237e342));
+path.cubicTo(SkBits2Float(0x4227db27), SkBits2Float(0x422c7494), SkBits2Float(0x42342c7f), SkBits2Float(0x421f8af7), SkBits2Float(0x423ef37c), SkBits2Float(0x42116357));
+path.lineTo(SkBits2Float(0x42841313), SkBits2Float(0x42491ebf));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp179(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb7060057), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41fc5f30), SkBits2Float(0xc2a5fffe), SkBits2Float(0x427176a0), SkBits2Float(0xc2823b95), SkBits2Float(0x4294be35), SkBits2Float(0xc21365c9));
+path.cubicTo(SkBits2Float(0x42b0c118), SkBits2Float(0xc1095198), SkBits2Float(0x42aa4b8f), SkBits2Float(0x41c9721a), SkBits2Float(0x42841313), SkBits2Float(0x42491ebf));
+path.cubicTo(SkBits2Float(0x42793d8e), SkBits2Float(0x425cb36e), SkBits2Float(0x4268336d), SkBits2Float(0x426e9032), SkBits2Float(0x4255582b), SkBits2Float(0x427e60c5));
+path.lineTo(SkBits2Float(0x421a3990), SkBits2Float(0x4237e342));
+path.cubicTo(SkBits2Float(0x4227db27), SkBits2Float(0x422c7494), SkBits2Float(0x42342c7f), SkBits2Float(0x421f8af7), SkBits2Float(0x423ef37b), SkBits2Float(0x42116356));
+path.cubicTo(SkBits2Float(0x427635bc), SkBits2Float(0x41919f96), SkBits2Float(0x427f8c66), SkBits2Float(0xc0c68887), SkBits2Float(0x42570cd6), SkBits2Float(0xc1d51ae4));
+path.cubicTo(SkBits2Float(0x422e8d45), SkBits2Float(0xc23c49d3), SkBits2Float(0x41b66ffd), SkBits2Float(0xc2700000), SkBits2Float(0xb7060057), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4255582a), SkBits2Float(0x427e60c6));
+path.cubicTo(SkBits2Float(0x41d8da26), SkBits2Float(0x42ab2f9f), SkBits2Float(0xc11f0392), SkBits2Float(0x42b2763a), SkBits2Float(0xc21fc8f1), SkBits2Float(0x4291829a));
+path.cubicTo(SkBits2Float(0xc28be87e), SkBits2Float(0x42611df4), SkBits2Float(0xc2ad8941), SkBits2Float(0x41b88f93), SkBits2Float(0xc2a49219), SkBits2Float(0xc12de56c));
+path.cubicTo(SkBits2Float(0xc29b9af2), SkBits2Float(0xc2333a80), SkBits2Float(0xc253c58e), SkBits2Float(0xc2910614), SkBits2Float(0xc19d7dc6), SkBits2Float(0xc2a14359));
+path.lineTo(SkBits2Float(0xc163b2c9), SkBits2Float(0xc26926c4));
+path.cubicTo(SkBits2Float(0xc2191685), SkBits2Float(0xc251ac40), SkBits2Float(0xc260f8ae), SkBits2Float(0xc201900e), SkBits2Float(0xc26deef7), SkBits2Float(0xc0fb6a70));
+path.cubicTo(SkBits2Float(0xc27ae541), SkBits2Float(0x41856ae3), SkBits2Float(0xc24a46d8), SkBits2Float(0x4222bc35), SkBits2Float(0xc1e7039a), SkBits2Float(0x42526049));
+path.cubicTo(SkBits2Float(0xc0e5e60c), SkBits2Float(0x4281022e), SkBits2Float(0x419cc2c4), SkBits2Float(0x42777f70), SkBits2Float(0x421a3996), SkBits2Float(0x4237e33e));
+path.lineTo(SkBits2Float(0x4255582a), SkBits2Float(0x427e60c6));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp180(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41fed5d1), SkBits2Float(0xc2a60000), SkBits2Float(0x4273981d), SkBits2Float(0xc28189e8), SkBits2Float(0x42957e40), SkBits2Float(0xc210547e));
+path.cubicTo(SkBits2Float(0x42b13073), SkBits2Float(0xc0eca961), SkBits2Float(0x42a99b35), SkBits2Float(0x41d57c6c), SkBits2Float(0x4281fa62), SkBits2Float(0x424e82d3));
+path.lineTo(SkBits2Float(0x423beb8b), SkBits2Float(0x421548fc));
+path.cubicTo(SkBits2Float(0x427536c2), SkBits2Float(0x419a53c7), SkBits2Float(0x428016af), SkBits2Float(0xc0ab14a9), SkBits2Float(0x4258227d), SkBits2Float(0xc1d0ab83));
+path.cubicTo(SkBits2Float(0x4230179a), SkBits2Float(0xc23b48ee), SkBits2Float(0x41b837da), SkBits2Float(0xc2700002), SkBits2Float(0xb7060057), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4281fa62), SkBits2Float(0x424e82d5));
+path.cubicTo(SkBits2Float(0x4274817d), SkBits2Float(0x4261f5b7), SkBits2Float(0x4262ebfa), SkBits2Float(0x42739d02), SkBits2Float(0x424f88b8), SkBits2Float(0x428191ef));
+path.lineTo(SkBits2Float(0x4216064f), SkBits2Float(0x423b5489));
+path.cubicTo(SkBits2Float(0x42240a35), SkBits2Float(0x42301b25), SkBits2Float(0x4230c051), SkBits2Float(0x4223582f), SkBits2Float(0x423beb8c), SkBits2Float(0x421548fc));
+path.lineTo(SkBits2Float(0x4281fa62), SkBits2Float(0x424e82d5));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp181(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb7060057), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41fed5d1), SkBits2Float(0xc2a60000), SkBits2Float(0x4273981d), SkBits2Float(0xc28189e8), SkBits2Float(0x42957e40), SkBits2Float(0xc210547e));
+path.cubicTo(SkBits2Float(0x42b13073), SkBits2Float(0xc0eca961), SkBits2Float(0x42a99b35), SkBits2Float(0x41d57c6c), SkBits2Float(0x4281fa62), SkBits2Float(0x424e82d5));
+path.cubicTo(SkBits2Float(0x4274817d), SkBits2Float(0x4261f5b7), SkBits2Float(0x4262ebfa), SkBits2Float(0x42739d02), SkBits2Float(0x424f88b8), SkBits2Float(0x428191ef));
+path.lineTo(SkBits2Float(0x4216064f), SkBits2Float(0x423b5489));
+path.cubicTo(SkBits2Float(0x42240a35), SkBits2Float(0x42301b25), SkBits2Float(0x4230c051), SkBits2Float(0x4223582f), SkBits2Float(0x423beb8b), SkBits2Float(0x421548fc));
+path.cubicTo(SkBits2Float(0x427536c2), SkBits2Float(0x419a53c7), SkBits2Float(0x428016af), SkBits2Float(0xc0ab14a9), SkBits2Float(0x4258227d), SkBits2Float(0xc1d0ab83));
+path.cubicTo(SkBits2Float(0x4230179a), SkBits2Float(0xc23b48ee), SkBits2Float(0x41b837da), SkBits2Float(0xc2700002), SkBits2Float(0xb7060057), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x424f88ba), SkBits2Float(0x428191f0));
+path.cubicTo(SkBits2Float(0x41c732b7), SkBits2Float(0x42acca52), SkBits2Float(0xc14a7268), SkBits2Float(0x42b208b4), SkBits2Float(0xc22982dc), SkBits2Float(0x428ebb75));
+path.cubicTo(SkBits2Float(0xc2903490), SkBits2Float(0x4256dc6c), SkBits2Float(0xc2af8c6f), SkBits2Float(0x419be833), SkBits2Float(0xc2a36e37), SkBits2Float(0xc168c0a6));
+path.cubicTo(SkBits2Float(0xc2974fff), SkBits2Float(0xc242546a), SkBits2Float(0xc2448acf), SkBits2Float(0xc29698ac), SkBits2Float(0xc17253d7), SkBits2Float(0xc2a33682));
+path.lineTo(SkBits2Float(0xc12f2d38), SkBits2Float(0xc26bf872));
+path.cubicTo(SkBits2Float(0xc20e1427), SkBits2Float(0xc259bacc), SkBits2Float(0xc25ac3d7), SkBits2Float(0xc20c7ab2), SkBits2Float(0xc26c48f7), SkBits2Float(0xc1284130));
+path.cubicTo(SkBits2Float(0xc27dce17), SkBits2Float(0x41616864), SkBits2Float(0xc2507d50), SkBits2Float(0x421b5239), SkBits2Float(0xc1f51386), SkBits2Float(0x424e5c1e));
+path.cubicTo(SkBits2Float(0xc11258cd), SkBits2Float(0x4280b301), SkBits2Float(0x418fffac), SkBits2Float(0x4279d13a), SkBits2Float(0x42160652), SkBits2Float(0x423b5488));
+path.lineTo(SkBits2Float(0x424f88ba), SkBits2Float(0x428191f0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp182(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x420048ef), SkBits2Float(0xc2a60000), SkBits2Float(0x4275172d), SkBits2Float(0xc2810bd2), SkBits2Float(0x429602e3), SkBits2Float(0xc20e29dc));
+path.cubicTo(SkBits2Float(0x42b17a30), SkBits2Float(0xc0d1e0a1), SkBits2Float(0x42a9174e), SkBits2Float(0x41ddef9e), SkBits2Float(0x4280787d), SkBits2Float(0x4252400e));
+path.lineTo(SkBits2Float(0x4239bd9f), SkBits2Float(0x4217fcf6));
+path.cubicTo(SkBits2Float(0x4274780f), SkBits2Float(0x41a06f8c), SkBits2Float(0x42804bfe), SkBits2Float(0xc097b7f0), SkBits2Float(0x4258e240), SkBits2Float(0xc1cd899e));
+path.cubicTo(SkBits2Float(0x42312c84), SkBits2Float(0xc23a929f), SkBits2Float(0x41b978e3), SkBits2Float(0xc2700000), SkBits2Float(0x36d3ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4280787d), SkBits2Float(0x42524010));
+path.cubicTo(SkBits2Float(0x42711c0e), SkBits2Float(0x42659909), SkBits2Float(0x425f24ad), SkBits2Float(0x42771864), SkBits2Float(0x424b624a), SkBits2Float(0x4283347a));
+path.lineTo(SkBits2Float(0x42130648), SkBits2Float(0x423db1a5));
+path.cubicTo(SkBits2Float(0x42214ef3), SkBits2Float(0x42329f82), SkBits2Float(0x422e4bcd), SkBits2Float(0x4225f96c), SkBits2Float(0x4239bd9f), SkBits2Float(0x4217fcf7));
+path.lineTo(SkBits2Float(0x4280787d), SkBits2Float(0x42524010));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp183(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36d3ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x420048ef), SkBits2Float(0xc2a60000), SkBits2Float(0x4275172d), SkBits2Float(0xc2810bd2), SkBits2Float(0x429602e3), SkBits2Float(0xc20e29dc));
+path.cubicTo(SkBits2Float(0x42b17a30), SkBits2Float(0xc0d1e0a1), SkBits2Float(0x42a9174e), SkBits2Float(0x41ddef9e), SkBits2Float(0x4280787d), SkBits2Float(0x42524010));
+path.cubicTo(SkBits2Float(0x42711c0e), SkBits2Float(0x42659909), SkBits2Float(0x425f24ad), SkBits2Float(0x42771864), SkBits2Float(0x424b624a), SkBits2Float(0x4283347a));
+path.lineTo(SkBits2Float(0x42130648), SkBits2Float(0x423db1a5));
+path.cubicTo(SkBits2Float(0x42214ef3), SkBits2Float(0x42329f82), SkBits2Float(0x422e4bcd), SkBits2Float(0x4225f96c), SkBits2Float(0x4239bd9f), SkBits2Float(0x4217fcf6));
+path.cubicTo(SkBits2Float(0x4274780f), SkBits2Float(0x41a06f8c), SkBits2Float(0x42804bfe), SkBits2Float(0xc097b7f0), SkBits2Float(0x4258e240), SkBits2Float(0xc1cd899e));
+path.cubicTo(SkBits2Float(0x42312c84), SkBits2Float(0xc23a929f), SkBits2Float(0x41b978e3), SkBits2Float(0xc2700000), SkBits2Float(0x36d3ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x424b624a), SkBits2Float(0x42833479));
+path.cubicTo(SkBits2Float(0x41baac2f), SkBits2Float(0x42adda12), SkBits2Float(0xc168f6a7), SkBits2Float(0x42b1a2b3), SkBits2Float(0xc2303c92), SkBits2Float(0x428cae5c));
+path.cubicTo(SkBits2Float(0xc2931dbe), SkBits2Float(0x424f7409), SkBits2Float(0xc2b0c9d8), SkBits2Float(0x41878abe), SkBits2Float(0xc2a26e7f), SkBits2Float(0xc188ef9a));
+path.cubicTo(SkBits2Float(0xc2941327), SkBits2Float(0xc24cb4f5), SkBits2Float(0xc2397a7c), SkBits2Float(0xc29a4742), SkBits2Float(0xc13ec328), SkBits2Float(0xc2a44746));
+path.lineTo(SkBits2Float(0xc109e67a), SkBits2Float(0xc26d82d0));
+path.cubicTo(SkBits2Float(0xc20614b0), SkBits2Float(0xc25f0d94), SkBits2Float(0xc2561585), SkBits2Float(0xc213fb18), SkBits2Float(0xc26ad744), SkBits2Float(0xc145fabb));
+path.cubicTo(SkBits2Float(0xc27f9901), SkBits2Float(0x4143f6e8), SkBits2Float(0xc254b2af), SkBits2Float(0x4215f75b), SkBits2Float(0xc1feccbb), SkBits2Float(0x424b64f3));
+path.cubicTo(SkBits2Float(0xc128682f), SkBits2Float(0x42806945), SkBits2Float(0x4186f1ba), SkBits2Float(0x427b5a1e), SkBits2Float(0x4213064f), SkBits2Float(0x423db1a2));
+path.lineTo(SkBits2Float(0x424b624a), SkBits2Float(0x42833479));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp184(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42011b87), SkBits2Float(0xc2a5fffe), SkBits2Float(0x427681ab), SkBits2Float(0xc280937a), SkBits2Float(0x42967eb3), SkBits2Float(0xc20c1a94));
+path.cubicTo(SkBits2Float(0x42b1bc91), SkBits2Float(0xc0b87191), SkBits2Float(0x42a89454), SkBits2Float(0x41e5ed6f), SkBits2Float(0x427e0902), SkBits2Float(0x4255c0a2));
+path.lineTo(SkBits2Float(0x4237a3d0), SkBits2Float(0x421a8517));
+path.cubicTo(SkBits2Float(0x4273bab4), SkBits2Float(0x41a63674), SkBits2Float(0x42807bfc), SkBits2Float(0xc0855530), SkBits2Float(0x42599545), SkBits2Float(0xc1ca8f4f));
+path.cubicTo(SkBits2Float(0x42323293), SkBits2Float(0xc239e4a8), SkBits2Float(0x41baa959), SkBits2Float(0xc2700002), SkBits2Float(0xb5600574), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427e0901), SkBits2Float(0x4255c0a4));
+path.cubicTo(SkBits2Float(0x426dd77c), SkBits2Float(0x4268ff65), SkBits2Float(0x425b838b), SkBits2Float(0x427a571f), SkBits2Float(0x42476779), SkBits2Float(0x4284b92f));
+path.lineTo(SkBits2Float(0x421025c9), SkBits2Float(0x423fe3a3));
+path.cubicTo(SkBits2Float(0x421eaf4b), SkBits2Float(0x4234f80b), SkBits2Float(0x422bef10), SkBits2Float(0x42286e9a), SkBits2Float(0x4237a3d2), SkBits2Float(0x421a8517));
+path.lineTo(SkBits2Float(0x427e0901), SkBits2Float(0x4255c0a4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp185(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42011b87), SkBits2Float(0xc2a5fffe), SkBits2Float(0x427681ab), SkBits2Float(0xc280937a), SkBits2Float(0x42967eb3), SkBits2Float(0xc20c1a94));
+path.cubicTo(SkBits2Float(0x42b1bc91), SkBits2Float(0xc0b87191), SkBits2Float(0x42a89454), SkBits2Float(0x41e5ed6f), SkBits2Float(0x427e0902), SkBits2Float(0x4255c0a2));
+path.lineTo(SkBits2Float(0x427e0901), SkBits2Float(0x4255c0a4));
+path.cubicTo(SkBits2Float(0x426dd77c), SkBits2Float(0x4268ff65), SkBits2Float(0x425b838b), SkBits2Float(0x427a571f), SkBits2Float(0x42476779), SkBits2Float(0x4284b92f));
+path.lineTo(SkBits2Float(0x421025c9), SkBits2Float(0x423fe3a3));
+path.cubicTo(SkBits2Float(0x421eaf4b), SkBits2Float(0x4234f80b), SkBits2Float(0x422bef10), SkBits2Float(0x42286e9a), SkBits2Float(0x4237a3d2), SkBits2Float(0x421a8517));
+path.lineTo(SkBits2Float(0x4237a3d0), SkBits2Float(0x421a8517));
+path.cubicTo(SkBits2Float(0x4273bab4), SkBits2Float(0x41a63674), SkBits2Float(0x42807bfc), SkBits2Float(0xc0855530), SkBits2Float(0x42599545), SkBits2Float(0xc1ca8f4f));
+path.cubicTo(SkBits2Float(0x42323293), SkBits2Float(0xc239e4a8), SkBits2Float(0x41baa959), SkBits2Float(0xc2700002), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42476779), SkBits2Float(0x4284b92f));
+path.cubicTo(SkBits2Float(0x41aeb99d), SkBits2Float(0x42aece6d), SkBits2Float(0xc182ebc7), SkBits2Float(0x42b12f04), SkBits2Float(0xc236847b), SkBits2Float(0x428aaa1d));
+path.cubicTo(SkBits2Float(0xc295c989), SkBits2Float(0x42484a6d), SkBits2Float(0xc2b1d401), SkBits2Float(0x41683386), SkBits2Float(0xc2a15607), SkBits2Float(0xc19c4a77));
+path.cubicTo(SkBits2Float(0xc290d80f), SkBits2Float(0xc2565754), SkBits2Float(0xc22ebdc1), SkBits2Float(0xc29d94aa), SkBits2Float(0xc10da15c), SkBits2Float(0xc2a50da2));
+path.lineTo(SkBits2Float(0xc0ccc448), SkBits2Float(0xc26ea197));
+path.cubicTo(SkBits2Float(0xc1fca350), SkBits2Float(0xc263d3da), SkBits2Float(0xc25169ba), SkBits2Float(0xc21af203), SkBits2Float(0xc26941c7), SkBits2Float(0xc161f664));
+path.cubicTo(SkBits2Float(0xc2808cea), SkBits2Float(0x4127db45), SkBits2Float(0xc2588f4e), SkBits2Float(0x4210c9da), SkBits2Float(0xc203f0b6), SkBits2Float(0x42487a91));
+path.cubicTo(SkBits2Float(0xc13d487f), SkBits2Float(0x428015a4), SkBits2Float(0x417c9d5c), SkBits2Float(0x427cbb65), SkBits2Float(0x421025ca), SkBits2Float(0x423fe3a2));
+path.lineTo(SkBits2Float(0x42476779), SkBits2Float(0x4284b92f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp186(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4201bd60), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427797bb), SkBits2Float(0xc2803682), SkBits2Float(0x4296dc8c), SkBits2Float(0xc20a848f));
+path.cubicTo(SkBits2Float(0x42b1ed3b), SkBits2Float(0xc0a4e0c3), SkBits2Float(0x42a82bcd), SkBits2Float(0x41ec0db8), SkBits2Float(0x427bc56e), SkBits2Float(0x42586a20));
+path.lineTo(SkBits2Float(0x423600d6), SkBits2Float(0x421c71bc));
+path.cubicTo(SkBits2Float(0x42732394), SkBits2Float(0x41aaa425), SkBits2Float(0x42809f29), SkBits2Float(0xc06e60a8), SkBits2Float(0x425a1cf3), SkBits2Float(0xc1c84447));
+path.cubicTo(SkBits2Float(0x4232fb94), SkBits2Float(0xc2395e3c), SkBits2Float(0x41bb9357), SkBits2Float(0xc2700002), SkBits2Float(0xb69400ae), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427bc56c), SkBits2Float(0x42586a22));
+path.cubicTo(SkBits2Float(0x426b4cc6), SkBits2Float(0x426b93ad), SkBits2Float(0x4258b1e1), SkBits2Float(0x427ccbca), SkBits2Float(0x42445140), SkBits2Float(0x4285de6e));
+path.lineTo(SkBits2Float(0x420dea8b), SkBits2Float(0x42418b9b));
+path.cubicTo(SkBits2Float(0x421ca599), SkBits2Float(0x4236be7f), SkBits2Float(0x422a18a8), SkBits2Float(0x422a4be8), SkBits2Float(0x423600d6), SkBits2Float(0x421c71bc));
+path.lineTo(SkBits2Float(0x427bc56c), SkBits2Float(0x42586a22));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp187(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb69400ae), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4201bd60), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427797bb), SkBits2Float(0xc2803682), SkBits2Float(0x4296dc8c), SkBits2Float(0xc20a848f));
+path.cubicTo(SkBits2Float(0x42b1ed3b), SkBits2Float(0xc0a4e0c3), SkBits2Float(0x42a82bcd), SkBits2Float(0x41ec0db8), SkBits2Float(0x427bc56e), SkBits2Float(0x42586a20));
+path.lineTo(SkBits2Float(0x423600d6), SkBits2Float(0x421c71bc));
+path.cubicTo(SkBits2Float(0x42732394), SkBits2Float(0x41aaa425), SkBits2Float(0x42809f29), SkBits2Float(0xc06e60a8), SkBits2Float(0x425a1cf3), SkBits2Float(0xc1c84447));
+path.cubicTo(SkBits2Float(0x4232fb94), SkBits2Float(0xc2395e3c), SkBits2Float(0x41bb9357), SkBits2Float(0xc2700002), SkBits2Float(0xb69400ae), SkBits2Float(0xc2700000));
+path.close();
+path.moveTo(SkBits2Float(0x423600d6), SkBits2Float(0x421c71bc));
+path.lineTo(SkBits2Float(0x427bc56c), SkBits2Float(0x42586a22));
+path.cubicTo(SkBits2Float(0x426b4cc6), SkBits2Float(0x426b93ad), SkBits2Float(0x4258b1e1), SkBits2Float(0x427ccbca), SkBits2Float(0x42445140), SkBits2Float(0x4285de6e));
+path.lineTo(SkBits2Float(0x420dea8b), SkBits2Float(0x42418b9b));
+path.cubicTo(SkBits2Float(0x421ca599), SkBits2Float(0x4236be7f), SkBits2Float(0x422a18a8), SkBits2Float(0x422a4be8), SkBits2Float(0x423600d6), SkBits2Float(0x421c71bc));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42445140), SkBits2Float(0x4285de6e));
+path.cubicTo(SkBits2Float(0x41a5801a), SkBits2Float(0x42af8153), SkBits2Float(0xc18dfe3b), SkBits2Float(0x42b0c99d), SkBits2Float(0xc23b472e), SkBits2Float(0x42891183));
+path.cubicTo(SkBits2Float(0xc297c79f), SkBits2Float(0x4242b2d1), SkBits2Float(0xc2b28961), SkBits2Float(0x414a2ba6), SkBits2Float(0xc2a0659f), SkBits2Float(0xc1ab0f22));
+path.cubicTo(SkBits2Float(0xc28e41db), SkBits2Float(0xc25d9a0f), SkBits2Float(0xc2265613), SkBits2Float(0xc29ffd9f), SkBits2Float(0xc0cf8787), SkBits2Float(0xc2a57e12));
+path.lineTo(SkBits2Float(0xc09605ca), SkBits2Float(0xc26f4428));
+path.cubicTo(SkBits2Float(0xc1f07c7d), SkBits2Float(0xc2674fd1), SkBits2Float(0xc24dac50), SkBits2Float(0xc22031a9), SkBits2Float(0xc267e62b), SkBits2Float(0xc1775074));
+path.cubicTo(SkBits2Float(0xc2811003), SkBits2Float(0x411225be), SkBits2Float(0xc25b70c1), SkBits2Float(0x420cbef2), SkBits2Float(0xc20761ad), SkBits2Float(0x42462bd0));
+path.cubicTo(SkBits2Float(0xc14d4a68), SkBits2Float(0x427f98ac), SkBits2Float(0x416f472e), SkBits2Float(0x427dbe0b), SkBits2Float(0x420dea8f), SkBits2Float(0x42418b9b));
+path.lineTo(SkBits2Float(0x42445140), SkBits2Float(0x4285de6e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp188(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42025498), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42789b1b), SkBits2Float(0xc27fbe84), SkBits2Float(0x42973334), SkBits2Float(0xc2090897));
+path.cubicTo(SkBits2Float(0x42b218da), SkBits2Float(0xc092954a), SkBits2Float(0x42a7c71a), SkBits2Float(0x41f1c3b5), SkBits2Float(0x4279a1de), SkBits2Float(0x425ae0d9));
+path.lineTo(SkBits2Float(0x42347503), SkBits2Float(0x421e39ac));
+path.cubicTo(SkBits2Float(0x427291fe), SkBits2Float(0x41aec4fe), SkBits2Float(0x4280beb1), SkBits2Float(0xc053ed89), SkBits2Float(0x425a9a3a), SkBits2Float(0xc1c61ef1));
+path.cubicTo(SkBits2Float(0x4233b713), SkBits2Float(0xc238e018), SkBits2Float(0x41bc6df5), SkBits2Float(0xc2700002), SkBits2Float(0xb7240057), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4279a1de), SkBits2Float(0x425ae0d9));
+path.cubicTo(SkBits2Float(0x4268e6ce), SkBits2Float(0x426df5b7), SkBits2Float(0x425609c8), SkBits2Float(0x427f0f64), SkBits2Float(0x42416967), SkBits2Float(0x4286ec0f));
+path.lineTo(SkBits2Float(0x420bd0d2), SkBits2Float(0x42431170));
+path.cubicTo(SkBits2Float(0x421ab9f8), SkBits2Float(0x4238617e), SkBits2Float(0x42285cd4), SkBits2Float(0x422c04e7), SkBits2Float(0x42347505), SkBits2Float(0x421e39ac));
+path.lineTo(SkBits2Float(0x4279a1de), SkBits2Float(0x425ae0d9));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp189(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb7240057), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42025498), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42789b1b), SkBits2Float(0xc27fbe84), SkBits2Float(0x42973334), SkBits2Float(0xc2090897));
+path.cubicTo(SkBits2Float(0x42b218da), SkBits2Float(0xc092954a), SkBits2Float(0x42a7c71a), SkBits2Float(0x41f1c3b5), SkBits2Float(0x4279a1de), SkBits2Float(0x425ae0d9));
+path.cubicTo(SkBits2Float(0x4268e6ce), SkBits2Float(0x426df5b7), SkBits2Float(0x425609c8), SkBits2Float(0x427f0f64), SkBits2Float(0x42416967), SkBits2Float(0x4286ec0f));
+path.lineTo(SkBits2Float(0x420bd0d2), SkBits2Float(0x42431170));
+path.cubicTo(SkBits2Float(0x421ab9f8), SkBits2Float(0x4238617e), SkBits2Float(0x42285cd4), SkBits2Float(0x422c04e7), SkBits2Float(0x42347505), SkBits2Float(0x421e39ac));
+path.lineTo(SkBits2Float(0x42347503), SkBits2Float(0x421e39ac));
+path.cubicTo(SkBits2Float(0x427291fe), SkBits2Float(0x41aec4fe), SkBits2Float(0x4280beb1), SkBits2Float(0xc053ed89), SkBits2Float(0x425a9a3a), SkBits2Float(0xc1c61ef1));
+path.cubicTo(SkBits2Float(0x4233b713), SkBits2Float(0xc238e018), SkBits2Float(0x41bc6df5), SkBits2Float(0xc2700002), SkBits2Float(0xb7240057), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42416967), SkBits2Float(0x4286ec0f));
+path.cubicTo(SkBits2Float(0x419cd99a), SkBits2Float(0x42b02173), SkBits2Float(0xc19850b8), SkBits2Float(0x42b06117), SkBits2Float(0xc23fac11), SkBits2Float(0x42878a96));
+path.cubicTo(SkBits2Float(0xc29997e3), SkBits2Float(0x423d682a), SkBits2Float(0xc2b3208c), SkBits2Float(0x412e025f), SkBits2Float(0xc29f71a3), SkBits2Float(0xc1b8c415));
+path.cubicTo(SkBits2Float(0xc28bc2ba), SkBits2Float(0xc26444ae), SkBits2Float(0xc21e5e96), SkBits2Float(0xc2a223df), SkBits2Float(0xc088ac52), SkBits2Float(0xc2a5c7b3));
+path.lineTo(SkBits2Float(0xc0459a01), SkBits2Float(0xc26fae99));
+path.cubicTo(SkBits2Float(0xc1e4f7d0), SkBits2Float(0xc26a6b5c), SkBits2Float(0xc24a1045), SkBits2Float(0xc225035c), SkBits2Float(0xc266856e), SkBits2Float(0xc18590cd));
+path.cubicTo(SkBits2Float(0xc2817d4a), SkBits2Float(0x40fb9475), SkBits2Float(0xc25e0ffd), SkBits2Float(0x4208ebae), SkBits2Float(0xc20a8edd), SkBits2Float(0x4243f69e));
+path.cubicTo(SkBits2Float(0xc15c36ee), SkBits2Float(0x427f018f), SkBits2Float(0x4162c57c), SkBits2Float(0x427ea58e), SkBits2Float(0x420bd0d7), SkBits2Float(0x4243116e));
+path.lineTo(SkBits2Float(0x42416967), SkBits2Float(0x4286ec0f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp190(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4202b56e), SkBits2Float(0xc2a60000), SkBits2Float(0x427940ff), SkBits2Float(0xc27f4e67), SkBits2Float(0x42976a2d), SkBits2Float(0xc20814ff));
+path.cubicTo(SkBits2Float(0x42b233da), SkBits2Float(0xc086dcb5), SkBits2Float(0x42a78518), SkBits2Float(0x41f56a27), SkBits2Float(0x42784037), SkBits2Float(0x425c71a4));
+path.lineTo(SkBits2Float(0x4233755d), SkBits2Float(0x421f5b67));
+path.cubicTo(SkBits2Float(0x4272328d), SkBits2Float(0x41b16880), SkBits2Float(0x4280d235), SkBits2Float(0xc042fb32), SkBits2Float(0x425ae9b3), SkBits2Float(0xc1c4bebc));
+path.cubicTo(SkBits2Float(0x42342efc), SkBits2Float(0xc2388f09), SkBits2Float(0x41bcf9fa), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42784038), SkBits2Float(0x425c71a4));
+path.cubicTo(SkBits2Float(0x42675aa4), SkBits2Float(0x426f78d5), SkBits2Float(0x4254535c), SkBits2Float(0x42803f48), SkBits2Float(0x423f8a54), SkBits2Float(0x4287967e));
+path.lineTo(SkBits2Float(0x420a7682), SkBits2Float(0x424407da));
+path.cubicTo(SkBits2Float(0x42197d0c), SkBits2Float(0x42396aed), SkBits2Float(0x42273e74), SkBits2Float(0x422d1cc3), SkBits2Float(0x4233755f), SkBits2Float(0x421f5b68));
+path.lineTo(SkBits2Float(0x42784038), SkBits2Float(0x425c71a4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp191(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4202b56e), SkBits2Float(0xc2a60000), SkBits2Float(0x427940ff), SkBits2Float(0xc27f4e67), SkBits2Float(0x42976a2d), SkBits2Float(0xc20814ff));
+path.cubicTo(SkBits2Float(0x42b233da), SkBits2Float(0xc086dcb5), SkBits2Float(0x42a78518), SkBits2Float(0x41f56a27), SkBits2Float(0x42784038), SkBits2Float(0x425c71a4));
+path.cubicTo(SkBits2Float(0x42675aa4), SkBits2Float(0x426f78d5), SkBits2Float(0x4254535c), SkBits2Float(0x42803f48), SkBits2Float(0x423f8a54), SkBits2Float(0x4287967e));
+path.lineTo(SkBits2Float(0x420a7682), SkBits2Float(0x424407da));
+path.cubicTo(SkBits2Float(0x42197d0c), SkBits2Float(0x42396aed), SkBits2Float(0x42273e74), SkBits2Float(0x422d1cc3), SkBits2Float(0x4233755f), SkBits2Float(0x421f5b68));
+path.lineTo(SkBits2Float(0x4233755d), SkBits2Float(0x421f5b67));
+path.cubicTo(SkBits2Float(0x4272328d), SkBits2Float(0x41b16880), SkBits2Float(0x4280d235), SkBits2Float(0xc042fb32), SkBits2Float(0x425ae9b3), SkBits2Float(0xc1c4bebc));
+path.cubicTo(SkBits2Float(0x42342efc), SkBits2Float(0xc2388f09), SkBits2Float(0x41bcf9fa), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423f8a55), SkBits2Float(0x4287967f));
+path.cubicTo(SkBits2Float(0x41974ba2), SkBits2Float(0x42b0846d), SkBits2Float(0xc19ee9a3), SkBits2Float(0x42b01937), SkBits2Float(0xc2427547), SkBits2Float(0x42868bae));
+path.cubicTo(SkBits2Float(0xc29abade), SkBits2Float(0x4239fc4c), SkBits2Float(0xc2b3780d), SkBits2Float(0x411bee16), SkBits2Float(0xc29ecbab), SkBits2Float(0xc1c17e4f));
+path.cubicTo(SkBits2Float(0xc28a1f48), SkBits2Float(0xc26879d6), SkBits2Float(0xc2193674), SkBits2Float(0xc2a376c5), SkBits2Float(0xc0368c8c), SkBits2Float(0xc2a5e6e5));
+path.lineTo(SkBits2Float(0xc003f6b5), SkBits2Float(0xc26fdbb6));
+path.cubicTo(SkBits2Float(0xc1dd8323), SkBits2Float(0xc26c555a), SkBits2Float(0xc247b1d3), SkBits2Float(0xc2280e0b), SkBits2Float(0xc2659575), SkBits2Float(0xc18bdff2));
+path.cubicTo(SkBits2Float(0xc281bc8c), SkBits2Float(0x40e170d0), SkBits2Float(0xc25fb4ae), SkBits2Float(0x42067283), SkBits2Float(0xc20c926e), SkBits2Float(0x42428613));
+path.cubicTo(SkBits2Float(0xc165c0b5), SkBits2Float(0x427e99a3), SkBits2Float(0x415abda1), SkBits2Float(0x427f34a6), SkBits2Float(0x420a7686), SkBits2Float(0x424407d8));
+path.lineTo(SkBits2Float(0x423f8a55), SkBits2Float(0x4287967f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp192(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4202fa25), SkBits2Float(0xc2a60000), SkBits2Float(0x4279b699), SkBits2Float(0xc27efea4), SkBits2Float(0x429790ee), SkBits2Float(0xc20767f9));
+path.cubicTo(SkBits2Float(0x42b24690), SkBits2Float(0xc07d14fa), SkBits2Float(0x42a75587), SkBits2Float(0x41f80076), SkBits2Float(0x427743d2), SkBits2Float(0x425d8c9b));
+path.lineTo(SkBits2Float(0x4232bee9), SkBits2Float(0x422027f2));
+path.cubicTo(SkBits2Float(0x4271edc7), SkBits2Float(0x41b34741), SkBits2Float(0x4280dfbb), SkBits2Float(0xc036f37a), SkBits2Float(0x425b21bb), SkBits2Float(0xc1c3c49a));
+path.cubicTo(SkBits2Float(0x423483ff), SkBits2Float(0xc2385562), SkBits2Float(0x41bd5d54), SkBits2Float(0xc2700000), SkBits2Float(0x36d3ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427743d4), SkBits2Float(0x425d8c98));
+path.cubicTo(SkBits2Float(0x4266401a), SkBits2Float(0x427089e5), SkBits2Float(0x42531ae2), SkBits2Float(0x4280c0a0), SkBits2Float(0x423e3514), SkBits2Float(0x42880e64));
+path.lineTo(SkBits2Float(0x42097fd1), SkBits2Float(0x4244b531));
+path.cubicTo(SkBits2Float(0x42189b26), SkBits2Float(0x423a25ea), SkBits2Float(0x42267233), SkBits2Float(0x422de224), SkBits2Float(0x4232beea), SkBits2Float(0x422027f3));
+path.lineTo(SkBits2Float(0x427743d4), SkBits2Float(0x425d8c98));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp193(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e15a675), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e95a67a), SkBits2Float(0xc2a5ffcd), SkBits2Float(0x3ee07980), SkBits2Float(0xc2a5ff68));
+path.lineTo(SkBits2Float(0x3ea245bb), SkBits2Float(0xc26fff25));
+path.cubicTo(SkBits2Float(0x3e585de0), SkBits2Float(0xc26fffb9), SkBits2Float(0x3dd85f11), SkBits2Float(0xc2700000), SkBits2Float(0x3691e768), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ee07a10), SkBits2Float(0xc2a5ff68));
+path.cubicTo(SkBits2Float(0x3ee7f565), SkBits2Float(0xc2a5ff5d), SkBits2Float(0x3eef70d9), SkBits2Float(0xc2a5ff52), SkBits2Float(0x3ef6ec4d), SkBits2Float(0xc2a5ff47));
+path.lineTo(SkBits2Float(0x3eb27fdb), SkBits2Float(0xc26ffef6));
+path.cubicTo(SkBits2Float(0x3ead1768), SkBits2Float(0xc26fff07), SkBits2Float(0x3ea7aebe), SkBits2Float(0xc26fff17), SkBits2Float(0x3ea24612), SkBits2Float(0xc26fff26));
+path.lineTo(SkBits2Float(0x3ee07a10), SkBits2Float(0xc2a5ff68));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp194(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3691e768), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e15a675), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e95a67a), SkBits2Float(0xc2a5ffcd), SkBits2Float(0x3ee07a10), SkBits2Float(0xc2a5ff68));
+path.lineTo(SkBits2Float(0x3ef6ec4d), SkBits2Float(0xc2a5ff47));
+path.lineTo(SkBits2Float(0x3eb27fdb), SkBits2Float(0xc26ffef6));
+path.cubicTo(SkBits2Float(0x3ead1768), SkBits2Float(0xc26fff07), SkBits2Float(0x3ea7aebe), SkBits2Float(0xc26fff17), SkBits2Float(0x3ea245bb), SkBits2Float(0xc26fff25));
+path.cubicTo(SkBits2Float(0x3e585de0), SkBits2Float(0xc26fffb9), SkBits2Float(0x3dd85f11), SkBits2Float(0xc2700000), SkBits2Float(0x3691e768), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ef6ec9b), SkBits2Float(0xc2a5ff48));
+path.cubicTo(SkBits2Float(0x3f3816c9), SkBits2Float(0xc2a5fe94), SkBits2Float(0x3f74b6e1), SkBits2Float(0xc2a5fd5b), SkBits2Float(0x3f98ab0b), SkBits2Float(0xc2a5fb9d));
+path.lineTo(SkBits2Float(0x3f5cb973), SkBits2Float(0xc26ff9a8));
+path.cubicTo(SkBits2Float(0x3f30e6e7), SkBits2Float(0xc26ffc2e), SkBits2Float(0x3f05138e), SkBits2Float(0xc26ffdf2), SkBits2Float(0x3eb27fc6), SkBits2Float(0xc26ffef7));
+path.lineTo(SkBits2Float(0x3ef6ec9b), SkBits2Float(0xc2a5ff48));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp195(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f0607d9), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3f860760), SkBits2Float(0xc2a5fd76), SkBits2Float(0x3fc90825), SkBits2Float(0xc2a5f863));
+path.lineTo(SkBits2Float(0x3f9152f7), SkBits2Float(0xc26ff500));
+path.cubicTo(SkBits2Float(0x3f41c6b2), SkBits2Float(0xc26ffc55), SkBits2Float(0x3ec1c794), SkBits2Float(0xc26fffff), SkBits2Float(0x36a51f4a), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fc9081a), SkBits2Float(0xc2a5f864));
+path.cubicTo(SkBits2Float(0x3fcfbb75), SkBits2Float(0xc2a5f7e2), SkBits2Float(0x3fd66eab), SkBits2Float(0xc2a5f75a), SkBits2Float(0x3fdd21d8), SkBits2Float(0xc2a5f6cb));
+path.lineTo(SkBits2Float(0x3f9fdac0), SkBits2Float(0xc26ff2b1));
+path.cubicTo(SkBits2Float(0x3f9b02da), SkBits2Float(0xc26ff37f), SkBits2Float(0x3f962add), SkBits2Float(0xc26ff444), SkBits2Float(0x3f9152da), SkBits2Float(0xc26ff500));
+path.lineTo(SkBits2Float(0x3fc9081a), SkBits2Float(0xc2a5f864));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp196(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36a51f4a), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3f0607d1), SkBits2Float(0xc2a60000), SkBits2Float(0x3f860758), SkBits2Float(0xc2a5fd76), SkBits2Float(0x3fc9081a), SkBits2Float(0xc2a5f864));
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3fdd21ce), SkBits2Float(0xc2a5f6cb));
+path.cubicTo(SkBits2Float(0x4024daa1), SkBits2Float(0xc2a5edc0), SkBits2Float(0x405b1f05), SkBits2Float(0xc2a5de0d), SkBits2Float(0x4088aca3), SkBits2Float(0xc2a5c7b3));
+path.lineTo(SkBits2Float(0x40459a01), SkBits2Float(0xc26fae99));
+path.cubicTo(SkBits2Float(0x401e66a3), SkBits2Float(0xc26fceed), SkBits2Float(0x3fee57cd), SkBits2Float(0xc26fe5a0), SkBits2Float(0x3f9fdaba), SkBits2Float(0xc26ff2b3));
+path.lineTo(SkBits2Float(0x3fdd21ce), SkBits2Float(0xc2a5f6cb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp197(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3fa0bd52), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4020babd), SkBits2Float(0xc2a5f168), SkBits2Float(0x40710446), SkBits2Float(0xc2a5d43c));
+path.lineTo(SkBits2Float(0x402e3a94), SkBits2Float(0xc26fc0ba));
+path.cubicTo(SkBits2Float(0x3fe86158), SkBits2Float(0xc26feae9), SkBits2Float(0x3f686554), SkBits2Float(0xc2700000), SkBits2Float(0x369bbf59), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4071043c), SkBits2Float(0xc2a5d43c));
+path.cubicTo(SkBits2Float(0x40790b78), SkBits2Float(0xc2a5d151), SkBits2Float(0x40808943), SkBits2Float(0xc2a5ce41), SkBits2Float(0x40848cac), SkBits2Float(0xc2a5cb0c));
+path.lineTo(SkBits2Float(0x403fa34c), SkBits2Float(0xc26fb371));
+path.cubicTo(SkBits2Float(0x4039d5dd), SkBits2Float(0xc26fb815), SkBits2Float(0x40340849), SkBits2Float(0xc26fbc83), SkBits2Float(0x402e3a8d), SkBits2Float(0xc26fc0bb));
+path.lineTo(SkBits2Float(0x4071043c), SkBits2Float(0xc2a5d43c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp198(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x369bbf59), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3fa0bd4b), SkBits2Float(0xc2a60000), SkBits2Float(0x4020bab6), SkBits2Float(0xc2a5f168), SkBits2Float(0x4071043c), SkBits2Float(0xc2a5d43c));
+path.lineTo(SkBits2Float(0x40710446), SkBits2Float(0xc2a5d43c));
+path.cubicTo(SkBits2Float(0x40790b7f), SkBits2Float(0xc2a5d151), SkBits2Float(0x40808945), SkBits2Float(0xc2a5ce41), SkBits2Float(0x40848cac), SkBits2Float(0xc2a5cb0c));
+path.lineTo(SkBits2Float(0x403fa34c), SkBits2Float(0xc26fb371));
+path.quadTo(SkBits2Float(0x4036ef2a), SkBits2Float(0xc26fba67), SkBits2Float(0x402e3a95), SkBits2Float(0xc26fc0bb));
+path.lineTo(SkBits2Float(0x402e3a94), SkBits2Float(0xc26fc0ba));
+path.cubicTo(SkBits2Float(0x3fe86158), SkBits2Float(0xc26feae9), SkBits2Float(0x3f686554), SkBits2Float(0xc2700000), SkBits2Float(0x369bbf59), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40848cae), SkBits2Float(0xc2a5cb0c));
+path.cubicTo(SkBits2Float(0x40c597bc), SkBits2Float(0xc2a5970c), SkBits2Float(0x41033f43), SkBits2Float(0xc2a53cca), SkBits2Float(0x41238fb3), SkBits2Float(0xc2a4bc74));
+path.lineTo(SkBits2Float(0x40ec7963), SkBits2Float(0xc26e2c38));
+path.cubicTo(SkBits2Float(0x40bdc13f), SkBits2Float(0xc26ee5c4), SkBits2Float(0x408ed689), SkBits2Float(0xc26f6843), SkBits2Float(0x403fa341), SkBits2Float(0xc26fb372));
+path.lineTo(SkBits2Float(0x40848cae), SkBits2Float(0xc2a5cb0c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp199(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ffdfad4), SkBits2Float(0xc2a60000), SkBits2Float(0x407df074), SkBits2Float(0xc2a5db92), SkBits2Float(0x40be4d32), SkBits2Float(0xc2a592c7));
+path.lineTo(SkBits2Float(0x40899143), SkBits2Float(0xc26f6217));
+path.cubicTo(SkBits2Float(0x40379219), SkBits2Float(0xc26fcb54), SkBits2Float(0x3fb799b8), SkBits2Float(0xc26fffff), SkBits2Float(0x3673fea3), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40be4d37), SkBits2Float(0xc2a592c7));
+path.cubicTo(SkBits2Float(0x40c4a257), SkBits2Float(0xc2a58b80), SkBits2Float(0x40caf70c), SkBits2Float(0xc2a583db), SkBits2Float(0x40d14b4e), SkBits2Float(0xc2a57bda));
+path.lineTo(SkBits2Float(0x40974c04), SkBits2Float(0xc26f40f2));
+path.cubicTo(SkBits2Float(0x4092b8c1), SkBits2Float(0xc26f4c86), SkBits2Float(0x408e252c), SkBits2Float(0xc26f5792), SkBits2Float(0x4089914a), SkBits2Float(0xc26f6219));
+path.lineTo(SkBits2Float(0x40be4d37), SkBits2Float(0xc2a592c7));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp200(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3673fea3), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3ffdfad4), SkBits2Float(0xc2a60000), SkBits2Float(0x407df074), SkBits2Float(0xc2a5db92), SkBits2Float(0x40be4d37), SkBits2Float(0xc2a592c7));
+path.cubicTo(SkBits2Float(0x40c4a257), SkBits2Float(0xc2a58b80), SkBits2Float(0x40caf70c), SkBits2Float(0xc2a583db), SkBits2Float(0x40d14b4e), SkBits2Float(0xc2a57bda));
+path.lineTo(SkBits2Float(0x40974c04), SkBits2Float(0xc26f40f2));
+path.cubicTo(SkBits2Float(0x4092b8c1), SkBits2Float(0xc26f4c86), SkBits2Float(0x408e252c), SkBits2Float(0xc26f5792), SkBits2Float(0x4089914a), SkBits2Float(0xc26f6219));
+path.lineTo(SkBits2Float(0x40899143), SkBits2Float(0xc26f6217));
+path.cubicTo(SkBits2Float(0x40379219), SkBits2Float(0xc26fcb54), SkBits2Float(0x3fb799b8), SkBits2Float(0xc26fffff), SkBits2Float(0x3673fea3), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x40d14b4a), SkBits2Float(0xc2a57bdb));
+path.cubicTo(SkBits2Float(0x411bf161), SkBits2Float(0xc2a4fa1a), SkBits2Float(0x414ef5ad), SkBits2Float(0xc2a4190e), SkBits2Float(0x4180b83e), SkBits2Float(0xc2a2d9dc));
+path.lineTo(SkBits2Float(0x413a19cf), SkBits2Float(0xc26b727f));
+path.cubicTo(SkBits2Float(0x41159c04), SkBits2Float(0xc26d3fff), SkBits2Float(0x40e175a8), SkBits2Float(0xc26e855c), SkBits2Float(0x40974c02), SkBits2Float(0xc26f40f4));
+path.lineTo(SkBits2Float(0x40d14b4a), SkBits2Float(0xc2a57bdb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp201(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4059d383), SkBits2Float(0xc2a5ffff), SkBits2Float(0x40d9b918), SkBits2Float(0xc2a594d0), SkBits2Float(0x4122e820), SkBits2Float(0xc2a4bf0c));
+path.lineTo(SkBits2Float(0x40eb871c), SkBits2Float(0xc26e2ff8));
+path.cubicTo(SkBits2Float(0x409d63e0), SkBits2Float(0xc26f6508), SkBits2Float(0x401d76fa), SkBits2Float(0xc2700000), SkBits2Float(0x35f7fd4a), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4122e81e), SkBits2Float(0xc2a4bf0c));
+path.cubicTo(SkBits2Float(0x41284f3c), SkBits2Float(0xc2a4a9ac), SkBits2Float(0x412db549), SkBits2Float(0xc2a4933e), SkBits2Float(0x41331a33), SkBits2Float(0xc2a47bbf));
+path.lineTo(SkBits2Float(0x410178be), SkBits2Float(0xc26dceac));
+path.cubicTo(SkBits2Float(0x40fb24f7), SkBits2Float(0xc26df0a4), SkBits2Float(0x40f356d1), SkBits2Float(0xc26e1114), SkBits2Float(0x40eb871f), SkBits2Float(0xc26e2ff8));
+path.lineTo(SkBits2Float(0x4122e81e), SkBits2Float(0xc2a4bf0c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp202(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4059d380), SkBits2Float(0xc2a60000), SkBits2Float(0x40d9b915), SkBits2Float(0xc2a594d0), SkBits2Float(0x4122e81e), SkBits2Float(0xc2a4bf0c));
+path.lineTo(SkBits2Float(0x4122e820), SkBits2Float(0xc2a4bf0c));
+path.cubicTo(SkBits2Float(0x41284f3d), SkBits2Float(0xc2a4a9ac), SkBits2Float(0x412db54a), SkBits2Float(0xc2a4933e), SkBits2Float(0x41331a33), SkBits2Float(0xc2a47bbf));
+path.lineTo(SkBits2Float(0x410178be), SkBits2Float(0xc26dceac));
+path.cubicTo(SkBits2Float(0x40fb24f7), SkBits2Float(0xc26df0a4), SkBits2Float(0x40f356d1), SkBits2Float(0xc26e1114), SkBits2Float(0x40eb871f), SkBits2Float(0xc26e2ff8));
+path.lineTo(SkBits2Float(0x40eb871c), SkBits2Float(0xc26e2ff8));
+path.cubicTo(SkBits2Float(0x409d63e0), SkBits2Float(0xc26f6508), SkBits2Float(0x401d76fa), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41331a39), SkBits2Float(0xc2a47bc0));
+path.cubicTo(SkBits2Float(0x41854b40), SkBits2Float(0xc2a2feb5), SkBits2Float(0x41b05576), SkBits2Float(0xc2a06b6c), SkBits2Float(0x41da0834), SkBits2Float(0xc29ccbb1));
+path.lineTo(SkBits2Float(0x419d9d10), SkBits2Float(0xc262b148));
+path.cubicTo(SkBits2Float(0x417ef0c0), SkBits2Float(0xc267ee96), SkBits2Float(0x4140b6cf), SkBits2Float(0xc26ba7c4), SkBits2Float(0x410178c0), SkBits2Float(0xc26dcead));
+path.lineTo(SkBits2Float(0x41331a39), SkBits2Float(0xc2a47bc0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp203(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4087af55), SkBits2Float(0xc2a5ffff), SkBits2Float(0x410795c5), SkBits2Float(0xc2a559a4), SkBits2Float(0x414aa20a), SkBits2Float(0xc2a40e63));
+path.lineTo(SkBits2Float(0x41127b4b), SkBits2Float(0xc26d308f));
+path.cubicTo(SkBits2Float(0x40c406cd), SkBits2Float(0xc26f0f7b), SkBits2Float(0x40442bc2), SkBits2Float(0xc26fffff), SkBits2Float(0x36b5ff52), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x414aa206), SkBits2Float(0xc2a40e63));
+path.cubicTo(SkBits2Float(0x4151559c), SkBits2Float(0xc2a3ed46), SkBits2Float(0x41580726), SkBits2Float(0xc2a3ca86), SkBits2Float(0x415eb67b), SkBits2Float(0xc2a3a622));
+path.lineTo(SkBits2Float(0x4120ff4d), SkBits2Float(0xc26c99d6));
+path.cubicTo(SkBits2Float(0x411c2a2f), SkBits2Float(0xc26cce74), SkBits2Float(0x41175378), SkBits2Float(0xc26d00b1), SkBits2Float(0x41127b46), SkBits2Float(0xc26d308f));
+path.lineTo(SkBits2Float(0x414aa206), SkBits2Float(0xc2a40e63));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp204(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36b5ff52), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4087af52), SkBits2Float(0xc2a60000), SkBits2Float(0x410795c2), SkBits2Float(0xc2a559a4), SkBits2Float(0x414aa206), SkBits2Float(0xc2a40e63));
+path.lineTo(SkBits2Float(0x414aa20a), SkBits2Float(0xc2a40e63));
+path.cubicTo(SkBits2Float(0x4151559f), SkBits2Float(0xc2a3ed46), SkBits2Float(0x41580727), SkBits2Float(0xc2a3ca86), SkBits2Float(0x415eb67b), SkBits2Float(0xc2a3a622));
+path.lineTo(SkBits2Float(0x4120ff4d), SkBits2Float(0xc26c99d6));
+path.cubicTo(SkBits2Float(0x411c2a31), SkBits2Float(0xc26cce74), SkBits2Float(0x4117537b), SkBits2Float(0xc26d00b1), SkBits2Float(0x41127b4b), SkBits2Float(0xc26d308f));
+path.lineTo(SkBits2Float(0x41127b46), SkBits2Float(0xc26d308f));
+path.cubicTo(SkBits2Float(0x40c406c6), SkBits2Float(0xc26f0f7b), SkBits2Float(0x40442bbb), SkBits2Float(0xc26fffff), SkBits2Float(0x36b5ff52), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x415eb680), SkBits2Float(0xc2a3a623));
+path.cubicTo(SkBits2Float(0x41a59721), SkBits2Float(0xc2a157ad), SkBits2Float(0x41da77ab), SkBits2Float(0xc29d5c25), SkBits2Float(0x420662d7), SkBits2Float(0xc297cafd));
+path.lineTo(SkBits2Float(0x41c24b0d), SkBits2Float(0xc25b75ac));
+path.cubicTo(SkBits2Float(0x419deda5), SkBits2Float(0xc2638226), SkBits2Float(0x416f6860), SkBits2Float(0xc269442a), SkBits2Float(0x4120ff4a), SkBits2Float(0xc26c99d9));
+path.lineTo(SkBits2Float(0x415eb680), SkBits2Float(0xc2a3a623));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp205(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40a2e582), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4122b94f), SkBits2Float(0xc2a51039), SkBits2Float(0x4172cca0), SkBits2Float(0xc2a333b4));
+path.lineTo(SkBits2Float(0x412f847d), SkBits2Float(0xc26bf464));
+path.cubicTo(SkBits2Float(0x40eb4376), SkBits2Float(0xc26ea556), SkBits2Float(0x406b836d), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4172cc9b), SkBits2Float(0xc2a333b4));
+path.cubicTo(SkBits2Float(0x417acd1a), SkBits2Float(0xc2a30415), SkBits2Float(0x41816508), SkBits2Float(0xc2a2d21d), SkBits2Float(0x4185619b), SkBits2Float(0xc2a29dcb));
+path.lineTo(SkBits2Float(0x4140d724), SkBits2Float(0xc26b1ba8));
+path.cubicTo(SkBits2Float(0x413b139d), SkBits2Float(0xc26b674c), SkBits2Float(0x41354d54), SkBits2Float(0xc26baf8b), SkBits2Float(0x412f847c), SkBits2Float(0xc26bf463));
+path.lineTo(SkBits2Float(0x4172cc9b), SkBits2Float(0xc2a333b4));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp206(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40a2e57f), SkBits2Float(0xc2a60000), SkBits2Float(0x4122b94c), SkBits2Float(0xc2a51039), SkBits2Float(0x4172cc9b), SkBits2Float(0xc2a333b4));
+path.lineTo(SkBits2Float(0x4172cca0), SkBits2Float(0xc2a333b4));
+path.cubicTo(SkBits2Float(0x417acd1d), SkBits2Float(0xc2a30415), SkBits2Float(0x41816509), SkBits2Float(0xc2a2d21d), SkBits2Float(0x4185619b), SkBits2Float(0xc2a29dcb));
+path.lineTo(SkBits2Float(0x4140d724), SkBits2Float(0xc26b1ba8));
+path.cubicTo(SkBits2Float(0x413b139d), SkBits2Float(0xc26b674c), SkBits2Float(0x41354d54), SkBits2Float(0xc26baf8b), SkBits2Float(0x412f847c), SkBits2Float(0xc26bf463));
+path.lineTo(SkBits2Float(0x412f847d), SkBits2Float(0xc26bf464));
+path.cubicTo(SkBits2Float(0x40eb4376), SkBits2Float(0xc26ea556), SkBits2Float(0x406b836d), SkBits2Float(0xc2700000), SkBits2Float(0x36b5ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4185619b), SkBits2Float(0xc2a29dcc));
+path.cubicTo(SkBits2Float(0x41c61a92), SkBits2Float(0xc29f4c69), SkBits2Float(0x42023dd6), SkBits2Float(0xc299958f), SkBits2Float(0x421f3a98), SkBits2Float(0xc291a994));
+path.lineTo(SkBits2Float(0x41e635e1), SkBits2Float(0xc25298a5));
+path.cubicTo(SkBits2Float(0x41bc4d11), SkBits2Float(0xc25e0caa), SkBits2Float(0x418f3524), SkBits2Float(0xc2664fa2), SkBits2Float(0x4140d729), SkBits2Float(0xc26b1ba9));
+path.lineTo(SkBits2Float(0x4185619b), SkBits2Float(0xc2a29dcc));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp207(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40c39389), SkBits2Float(0xc2a60000), SkBits2Float(0x414346f4), SkBits2Float(0xc2a4a65f), SkBits2Float(0x419158cf), SkBits2Float(0xc2a1f965));
+path.lineTo(SkBits2Float(0x415223e0), SkBits2Float(0xc26a2df8));
+path.cubicTo(SkBits2Float(0x410d2a0c), SkBits2Float(0xc26e0c4b), SkBits2Float(0x408d616c), SkBits2Float(0xc2700000), SkBits2Float(0x35bbfd46), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x419158d0), SkBits2Float(0xc2a1f965));
+path.cubicTo(SkBits2Float(0x41961cea), SkBits2Float(0xc2a1b4f6), SkBits2Float(0x419addf6), SkBits2Float(0xc2a16d2c), SkBits2Float(0x419f9bbb), SkBits2Float(0xc2a12207));
+path.lineTo(SkBits2Float(0x4166c251), SkBits2Float(0xc268f69a));
+path.cubicTo(SkBits2Float(0x415fe778), SkBits2Float(0xc269633e), SkBits2Float(0x415907e2), SkBits2Float(0xc269cb09), SkBits2Float(0x415223e0), SkBits2Float(0xc26a2df8));
+path.lineTo(SkBits2Float(0x419158d0), SkBits2Float(0xc2a1f965));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp208(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40c39389), SkBits2Float(0xc2a60000), SkBits2Float(0x414346f4), SkBits2Float(0xc2a4a65f), SkBits2Float(0x419158d0), SkBits2Float(0xc2a1f965));
+path.cubicTo(SkBits2Float(0x41961cea), SkBits2Float(0xc2a1b4f6), SkBits2Float(0x419addf6), SkBits2Float(0xc2a16d2c), SkBits2Float(0x419f9bbb), SkBits2Float(0xc2a12207));
+path.lineTo(SkBits2Float(0x4166c251), SkBits2Float(0xc268f69a));
+path.cubicTo(SkBits2Float(0x415fe778), SkBits2Float(0xc269633e), SkBits2Float(0x415907e2), SkBits2Float(0xc269cb09), SkBits2Float(0x415223e0), SkBits2Float(0xc26a2df8));
+path.cubicTo(SkBits2Float(0x410d2a0c), SkBits2Float(0xc26e0c4b), SkBits2Float(0x408d616c), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x419f9bbc), SkBits2Float(0xc2a12208));
+path.cubicTo(SkBits2Float(0x41eca53e), SkBits2Float(0xc29c5d1a), SkBits2Float(0x421ad1be), SkBits2Float(0xc2942e2b), SkBits2Float(0x423b8fe1), SkBits2Float(0xc288f8a3));
+path.lineTo(SkBits2Float(0x42079647), SkBits2Float(0xc24607dc));
+path.cubicTo(SkBits2Float(0x41dfd5cc), SkBits2Float(0xc2563c94), SkBits2Float(0x41ab11aa), SkBits2Float(0xc2621167), SkBits2Float(0x4166c24e), SkBits2Float(0xc268f69b));
+path.lineTo(SkBits2Float(0x419f9bbc), SkBits2Float(0xc2a12208));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp209(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40e86425), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4167e385), SkBits2Float(0xc2a41801), SkBits2Float(0x41ac0ecd), SkBits2Float(0xc2a05484));
+path.lineTo(SkBits2Float(0x4178c21d), SkBits2Float(0xc267cd79));
+path.cubicTo(SkBits2Float(0x4127a168), SkBits2Float(0xc26d3e79), SkBits2Float(0x40a7fe68), SkBits2Float(0xc2700000), SkBits2Float(0x3673fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41ac0ecb), SkBits2Float(0xc2a05485));
+path.cubicTo(SkBits2Float(0x41b1a941), SkBits2Float(0xc29ff44e), SkBits2Float(0x41b73ea0), SkBits2Float(0xc29f8f65), SkBits2Float(0x41bcce84), SkBits2Float(0xc29f25d1));
+path.lineTo(SkBits2Float(0x41887c9d), SkBits2Float(0xc26617d6));
+path.cubicTo(SkBits2Float(0x4184774a), SkBits2Float(0xc266b07c), SkBits2Float(0x41806e06), SkBits2Float(0xc2674260), SkBits2Float(0x4178c21e), SkBits2Float(0xc267cd7a));
+path.lineTo(SkBits2Float(0x41ac0ecb), SkBits2Float(0xc2a05485));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp210(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3673fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x40e86421), SkBits2Float(0xc2a60000), SkBits2Float(0x4167e381), SkBits2Float(0xc2a41801), SkBits2Float(0x41ac0eca), SkBits2Float(0xc2a05484));
+path.lineTo(SkBits2Float(0x41ac0ecd), SkBits2Float(0xc2a05484));
+path.lineTo(SkBits2Float(0x4178c21e), SkBits2Float(0xc267cd7a));
+path.lineTo(SkBits2Float(0x41ac0ecb), SkBits2Float(0xc2a05485));
+path.cubicTo(SkBits2Float(0x41b1a941), SkBits2Float(0xc29ff44e), SkBits2Float(0x41b73ea0), SkBits2Float(0xc29f8f65), SkBits2Float(0x41bcce84), SkBits2Float(0xc29f25d1));
+path.lineTo(SkBits2Float(0x41887c9d), SkBits2Float(0xc26617d6));
+path.cubicTo(SkBits2Float(0x4184774a), SkBits2Float(0xc266b07c), SkBits2Float(0x41806e06), SkBits2Float(0xc2674260), SkBits2Float(0x4178c21d), SkBits2Float(0xc267cd79));
+path.cubicTo(SkBits2Float(0x4127a168), SkBits2Float(0xc26d3e79), SkBits2Float(0x40a7fe68), SkBits2Float(0xc2700000), SkBits2Float(0x3673fea3), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41bcce83), SkBits2Float(0xc29f25d2));
+path.cubicTo(SkBits2Float(0x420ba3b4), SkBits2Float(0xc2987080), SkBits2Float(0x42357f09), SkBits2Float(0xc28cfcb1), SkBits2Float(0x42592f07), SkBits2Float(0xc27b1ba7));
+path.lineTo(SkBits2Float(0x421d0012), SkBits2Float(0xc235861c));
+path.cubicTo(SkBits2Float(0x420333bc), SkBits2Float(0xc24bd636), SkBits2Float(0x41c9e36e), SkBits2Float(0xc25c64f6), SkBits2Float(0x41887c9c), SkBits2Float(0xc26617d7));
+path.lineTo(SkBits2Float(0x41bcce83), SkBits2Float(0xc29f25d2));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp211(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x411e5541), SkBits2Float(0xc2a5ffff), SkBits2Float(0x419db1ee), SkBits2Float(0xc2a275ef), SkBits2Float(0x41e7e0a3), SkBits2Float(0xc29b8c98));
+path.lineTo(SkBits2Float(0x41a79f51), SkBits2Float(0xc260e3f1));
+path.cubicTo(SkBits2Float(0x4163fe32), SkBits2Float(0xc26ae208), SkBits2Float(0x40e4ea54), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41e7e0a8), SkBits2Float(0xc29b8c98));
+path.cubicTo(SkBits2Float(0x41ef46bb), SkBits2Float(0xc29adc20), SkBits2Float(0x41f6a013), SkBits2Float(0xc29a2338), SkBits2Float(0x41fdebc8), SkBits2Float(0xc29961f8));
+path.lineTo(SkBits2Float(0x41b78eb0), SkBits2Float(0xc25dc215));
+path.cubicTo(SkBits2Float(0x41b2488a), SkBits2Float(0xc25ed97a), SkBits2Float(0x41acf889), SkBits2Float(0xc25fe4cd), SkBits2Float(0x41a79f51), SkBits2Float(0xc260e3f1));
+path.lineTo(SkBits2Float(0x41e7e0a8), SkBits2Float(0xc29b8c98));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp212(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea3), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x411e5541), SkBits2Float(0xc2a5ffff), SkBits2Float(0x419db1ee), SkBits2Float(0xc2a275ef), SkBits2Float(0x41e7e0a8), SkBits2Float(0xc29b8c98));
+path.cubicTo(SkBits2Float(0x41ef46bb), SkBits2Float(0xc29adc20), SkBits2Float(0x41f6a013), SkBits2Float(0xc29a2338), SkBits2Float(0x41fdebc8), SkBits2Float(0xc29961f8));
+path.lineTo(SkBits2Float(0x41b78eb0), SkBits2Float(0xc25dc215));
+path.cubicTo(SkBits2Float(0x41b2488a), SkBits2Float(0xc25ed97a), SkBits2Float(0x41acf889), SkBits2Float(0xc25fe4cd), SkBits2Float(0x41a79f51), SkBits2Float(0xc260e3f1));
+path.cubicTo(SkBits2Float(0x4163fe32), SkBits2Float(0xc26ae208), SkBits2Float(0x40e4ea54), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea3), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x41fdebc9), SkBits2Float(0xc29961f9));
+path.cubicTo(SkBits2Float(0x423a7ccd), SkBits2Float(0xc28d1085), SkBits2Float(0x426d8f8d), SkBits2Float(0xc270b4b0), SkBits2Float(0x4288fa0c), SkBits2Float(0xc23b8bbf));
+path.lineTo(SkBits2Float(0x424609e8), SkBits2Float(0xc207934a));
+path.cubicTo(SkBits2Float(0x422bbb0d), SkBits2Float(0xc22e0114), SkBits2Float(0x4206cf6b), SkBits2Float(0xc24bf2e1), SkBits2Float(0x41b78eaf), SkBits2Float(0xc25dc216));
+path.lineTo(SkBits2Float(0x41fdebc9), SkBits2Float(0xc29961f9));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp213(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4151cd59), SkBits2Float(0xc2a5ffff), SkBits2Float(0x41d04f3f), SkBits2Float(0xc29fc954), SkBits2Float(0x4216e058), SkBits2Float(0xc293de54));
+path.lineTo(SkBits2Float(0x41da226b), SkBits2Float(0xc255c926));
+path.cubicTo(SkBits2Float(0x419695d1), SkBits2Float(0xc267043d), SkBits2Float(0x4117aa0a), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4216e057), SkBits2Float(0xc293de54));
+path.cubicTo(SkBits2Float(0x421b86ea), SkBits2Float(0xc292aea0), SkBits2Float(0x42201eff), SkBits2Float(0xc29170ed), SkBits2Float(0x4224a79b), SkBits2Float(0xc290257e));
+path.lineTo(SkBits2Float(0x41ee0e15), SkBits2Float(0xc2506790));
+path.cubicTo(SkBits2Float(0x41e78019), SkBits2Float(0xc25246bf), SkBits2Float(0x41e0dbbc), SkBits2Float(0xc2541212), SkBits2Float(0x41da226b), SkBits2Float(0xc255c927));
+path.lineTo(SkBits2Float(0x4216e057), SkBits2Float(0xc293de54));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp214(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4151cd58), SkBits2Float(0xc2a60000), SkBits2Float(0x41d04f3d), SkBits2Float(0xc29fc954), SkBits2Float(0x4216e057), SkBits2Float(0xc293de54));
+path.lineTo(SkBits2Float(0x4216e058), SkBits2Float(0xc293de54));
+path.cubicTo(SkBits2Float(0x421b86eb), SkBits2Float(0xc292aea0), SkBits2Float(0x42201eff), SkBits2Float(0xc29170ed), SkBits2Float(0x4224a79b), SkBits2Float(0xc290257e));
+path.lineTo(SkBits2Float(0x41ee0e15), SkBits2Float(0xc2506790));
+path.cubicTo(SkBits2Float(0x41e78019), SkBits2Float(0xc25246bf), SkBits2Float(0x41e0dbbc), SkBits2Float(0xc2541212), SkBits2Float(0x41da226b), SkBits2Float(0xc255c927));
+path.lineTo(SkBits2Float(0x41da226b), SkBits2Float(0xc255c926));
+path.cubicTo(SkBits2Float(0x419695d1), SkBits2Float(0xc267043d), SkBits2Float(0x4117aa0a), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4224a79b), SkBits2Float(0xc290257f));
+path.cubicTo(SkBits2Float(0x426f06c3), SkBits2Float(0xc275d105), SkBits2Float(0x42930d85), SkBits2Float(0xc2303df6), SkBits2Float(0x429f3103), SkBits2Float(0xc1bc373f));
+path.lineTo(SkBits2Float(0x42662806), SkBits2Float(0xc1880f44));
+path.cubicTo(SkBits2Float(0x42549b44), SkBits2Float(0xc1fececc), SkBits2Float(0x422cca4c), SkBits2Float(0xc231b2de), SkBits2Float(0x41ee0e18), SkBits2Float(0xc2506792));
+path.lineTo(SkBits2Float(0x4224a79b), SkBits2Float(0xc290257f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp215(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41741cf0), SkBits2Float(0xc2a60000), SkBits2Float(0x41f1c060), SkBits2Float(0xc29d96da), SkBits2Float(0x422cf7a2), SkBits2Float(0xc28db11c));
+path.lineTo(SkBits2Float(0x41fa12be), SkBits2Float(0xc24cdb0d));
+path.cubicTo(SkBits2Float(0x41aec295), SkBits2Float(0xc263d704), SkBits2Float(0x413077a0), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x422cf7a1), SkBits2Float(0xc28db11c));
+path.cubicTo(SkBits2Float(0x423224e7), SkBits2Float(0xc28c1ca8), SkBits2Float(0x42373bc3), SkBits2Float(0xc28a7620), SkBits2Float(0x423c3abd), SkBits2Float(0xc288bdfd));
+path.lineTo(SkBits2Float(0x420811ca), SkBits2Float(0xc245b313));
+path.cubicTo(SkBits2Float(0x4204753a), SkBits2Float(0xc2482f6b), SkBits2Float(0x4200c767), SkBits2Float(0xc24a924f), SkBits2Float(0x41fa12c1), SkBits2Float(0xc24cdb0e));
+path.lineTo(SkBits2Float(0x422cf7a1), SkBits2Float(0xc28db11c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp216(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41741cef), SkBits2Float(0xc2a60000), SkBits2Float(0x41f1c05e), SkBits2Float(0xc29d96da), SkBits2Float(0x422cf7a1), SkBits2Float(0xc28db11c));
+path.lineTo(SkBits2Float(0x422cf7a2), SkBits2Float(0xc28db11c));
+path.cubicTo(SkBits2Float(0x423224e8), SkBits2Float(0xc28c1ca8), SkBits2Float(0x42373bc3), SkBits2Float(0xc28a7620), SkBits2Float(0x423c3abd), SkBits2Float(0xc288bdfd));
+path.lineTo(SkBits2Float(0x420811ca), SkBits2Float(0xc245b313));
+path.cubicTo(SkBits2Float(0x4204753a), SkBits2Float(0xc2482f6b), SkBits2Float(0x4200c767), SkBits2Float(0xc24a924f), SkBits2Float(0x41fa12c1), SkBits2Float(0xc24cdb0e));
+path.lineTo(SkBits2Float(0x41fa12be), SkBits2Float(0xc24cdb0d));
+path.cubicTo(SkBits2Float(0x41aec295), SkBits2Float(0xc263d704), SkBits2Float(0x413077a0), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423c3abe), SkBits2Float(0xc288bdfe));
+path.cubicTo(SkBits2Float(0x42874551), SkBits2Float(0xc258d4f5), SkBits2Float(0x42a17ace), SkBits2Float(0xc1fc3ce7), SkBits2Float(0x42a57844), SkBits2Float(0xc0d41d22));
+path.lineTo(SkBits2Float(0x426f3bc1), SkBits2Float(0xc09955d3));
+path.cubicTo(SkBits2Float(0x426976f3), SkBits2Float(0xc1b65735), SkBits2Float(0x4243927c), SkBits2Float(0xc21cbef5), SkBits2Float(0x420811ca), SkBits2Float(0xc245b314));
+path.lineTo(SkBits2Float(0x423c3abe), SkBits2Float(0xc288bdfe));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp217(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4188e880), SkBits2Float(0xc2a60000), SkBits2Float(0x42073c1a), SkBits2Float(0xc29b6b86), SkBits2Float(0x423f3295), SkBits2Float(0xc287b573));
+path.lineTo(SkBits2Float(0x420a3712), SkBits2Float(0xc2443499));
+path.cubicTo(SkBits2Float(0x41c3852b), SkBits2Float(0xc260b421), SkBits2Float(0x4145f08c), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423f3294), SkBits2Float(0xc287b572));
+path.cubicTo(SkBits2Float(0x4244c015), SkBits2Float(0xc285c0c3), SkBits2Float(0x424a2e84), SkBits2Float(0xc283b664), SkBits2Float(0x424f7bec), SkBits2Float(0xc281970f));
+path.lineTo(SkBits2Float(0x4215fd0e), SkBits2Float(0xc23b5bf1));
+path.cubicTo(SkBits2Float(0x421227cb), SkBits2Float(0xc23e6d7a), SkBits2Float(0x420e3aa9), SkBits2Float(0xc24160b8), SkBits2Float(0x420a3713), SkBits2Float(0xc2443498));
+path.lineTo(SkBits2Float(0x423f3294), SkBits2Float(0xc287b572));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp218(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4188e880), SkBits2Float(0xc2a60000), SkBits2Float(0x42073c1a), SkBits2Float(0xc29b6b86), SkBits2Float(0x423f3295), SkBits2Float(0xc287b573));
+path.lineTo(SkBits2Float(0x424f7bec), SkBits2Float(0xc281970f));
+path.lineTo(SkBits2Float(0x4215fd0e), SkBits2Float(0xc23b5bf1));
+path.cubicTo(SkBits2Float(0x421227cb), SkBits2Float(0xc23e6d7a), SkBits2Float(0x420e3aa9), SkBits2Float(0xc24160b8), SkBits2Float(0x420a3713), SkBits2Float(0xc2443498));
+path.lineTo(SkBits2Float(0x420a3712), SkBits2Float(0xc2443499));
+path.cubicTo(SkBits2Float(0x41c3852b), SkBits2Float(0xc260b421), SkBits2Float(0x4145f08c), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x424f7bed), SkBits2Float(0xc281970f));
+path.cubicTo(SkBits2Float(0x42939bdb), SkBits2Float(0xc23cf22a), SkBits2Float(0x42aabb70), SkBits2Float(0xc19e30f8), SkBits2Float(0x42a530dd), SkBits2Float(0x4102f5b1));
+path.lineTo(SkBits2Float(0x426ed486), SkBits2Float(0x40bd56e4));
+path.cubicTo(SkBits2Float(0x4276d778), SkBits2Float(0xc164b5d6), SkBits2Float(0x4255690c), SkBits2Float(0xc2089663), SkBits2Float(0x4215fd0d), SkBits2Float(0xc23b5bf2));
+path.lineTo(SkBits2Float(0x424f7bed), SkBits2Float(0xc281970f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp219(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4198fc97), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4216a3e3), SkBits2Float(0xc298caff), SkBits2Float(0x4251e7a7), SkBits2Float(0xc2809c9b));
+path.lineTo(SkBits2Float(0x4217bd0d), SkBits2Float(0xc239f1d8));
+path.cubicTo(SkBits2Float(0x41d9cb04), SkBits2Float(0xc25ce7ce), SkBits2Float(0x415d2f7f), SkBits2Float(0xc26fffff), SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4251e7a7), SkBits2Float(0xc2809c9c));
+path.cubicTo(SkBits2Float(0x4257c623), SkBits2Float(0xc27c6f1e), SkBits2Float(0x425d7a38), SkBits2Float(0xc27771f7), SkBits2Float(0x42630157), SkBits2Float(0xc27243fd));
+path.lineTo(SkBits2Float(0x422419a4), SkBits2Float(0xc22f21bb));
+path.cubicTo(SkBits2Float(0x42201aab), SkBits2Float(0xc232e046), SkBits2Float(0x421bfb30), SkBits2Float(0xc2367b84), SkBits2Float(0x4217bd0d), SkBits2Float(0xc239f1d8));
+path.lineTo(SkBits2Float(0x4251e7a7), SkBits2Float(0xc2809c9c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp220(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4198fc97), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4216a3e3), SkBits2Float(0xc298caff), SkBits2Float(0x4251e7a7), SkBits2Float(0xc2809c9c));
+path.cubicTo(SkBits2Float(0x4257c623), SkBits2Float(0xc27c6f1e), SkBits2Float(0x425d7a38), SkBits2Float(0xc27771f7), SkBits2Float(0x42630157), SkBits2Float(0xc27243fd));
+path.lineTo(SkBits2Float(0x422419a4), SkBits2Float(0xc22f21bb));
+path.cubicTo(SkBits2Float(0x42201aab), SkBits2Float(0xc232e046), SkBits2Float(0x421bfb30), SkBits2Float(0xc2367b84), SkBits2Float(0x4217bd0d), SkBits2Float(0xc239f1d8));
+path.cubicTo(SkBits2Float(0x41d9cb04), SkBits2Float(0xc25ce7ce), SkBits2Float(0x415d2f7f), SkBits2Float(0xc26fffff), SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42630157), SkBits2Float(0xc27243ff));
+path.cubicTo(SkBits2Float(0x429f78af), SkBits2Float(0xc21c1e80), SkBits2Float(0x42b11918), SkBits2Float(0xc0cad7ee), SkBits2Float(0x429f0274), SkBits2Float(0x41bea8f4));
+path.lineTo(SkBits2Float(0x4265e4b4), SkBits2Float(0x4189d394));
+path.cubicTo(SkBits2Float(0x428005cc), SkBits2Float(0xc092a249), SkBits2Float(0x42668fa3), SkBits2Float(0xc1e1b6e5), SkBits2Float(0x422419a4), SkBits2Float(0xc22f21bb));
+path.lineTo(SkBits2Float(0x42630157), SkBits2Float(0xc27243ff));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp221(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ae0130), SkBits2Float(0xc2a5ffff), SkBits2Float(0x422a8737), SkBits2Float(0xc294ec91), SkBits2Float(0x42689b67), SkBits2Float(0xc26ce46c));
+path.lineTo(SkBits2Float(0x42282651), SkBits2Float(0xc22b3f58));
+path.cubicTo(SkBits2Float(0x41f68bfb), SkBits2Float(0xc2574fdc), SkBits2Float(0x417b92b3), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42689b68), SkBits2Float(0xc26ce46d));
+path.cubicTo(SkBits2Float(0x426ebcd2), SkBits2Float(0xc266df67), SkBits2Float(0x4274a1d2), SkBits2Float(0xc2609e09), SkBits2Float(0x427a4701), SkBits2Float(0xc25a23f2));
+path.lineTo(SkBits2Float(0x4234ec64), SkBits2Float(0xc21db11e));
+path.cubicTo(SkBits2Float(0x4230d7ae), SkBits2Float(0xc2225fbc), SkBits2Float(0x422c94d6), SkBits2Float(0xc226e55a), SkBits2Float(0x42282652), SkBits2Float(0xc22b3f58));
+path.lineTo(SkBits2Float(0x42689b68), SkBits2Float(0xc26ce46d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp222(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ae0130), SkBits2Float(0xc2a5ffff), SkBits2Float(0x422a8737), SkBits2Float(0xc294ec91), SkBits2Float(0x42689b68), SkBits2Float(0xc26ce46d));
+path.cubicTo(SkBits2Float(0x426ebcd2), SkBits2Float(0xc266df67), SkBits2Float(0x4274a1d2), SkBits2Float(0xc2609e09), SkBits2Float(0x427a4701), SkBits2Float(0xc25a23f2));
+path.lineTo(SkBits2Float(0x4234ec64), SkBits2Float(0xc21db11e));
+path.cubicTo(SkBits2Float(0x4230d7ae), SkBits2Float(0xc2225fbc), SkBits2Float(0x422c94d6), SkBits2Float(0xc226e55a), SkBits2Float(0x42282651), SkBits2Float(0xc22b3f58));
+path.cubicTo(SkBits2Float(0x41f68bfb), SkBits2Float(0xc2574fdc), SkBits2Float(0x417b92b3), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427a4702), SkBits2Float(0xc25a23f2));
+path.cubicTo(SkBits2Float(0x42ac7185), SkBits2Float(0xc1db2f83), SkBits2Float(0x42b35ed0), SkBits2Float(0x413e447a), SkBits2Float(0x428e4a3d), SkBits2Float(0x422afde8));
+path.lineTo(SkBits2Float(0x424db871), SkBits2Float(0x41f73799));
+path.cubicTo(SkBits2Float(0x4281aa54), SkBits2Float(0x41098afa), SkBits2Float(0x427950da), SkBits2Float(0xc19e728d), SkBits2Float(0x4234ec66), SkBits2Float(0xc21db120));
+path.lineTo(SkBits2Float(0x427a4702), SkBits2Float(0xc25a23f2));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp223(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41c50a2c), SkBits2Float(0xc2a60000), SkBits2Float(0x423ff37f), SkBits2Float(0xc2901f4e), SkBits2Float(0x427f077c), SkBits2Float(0xc25490c6));
+path.lineTo(SkBits2Float(0x42385bc5), SkBits2Float(0xc219a96d));
+path.cubicTo(SkBits2Float(0x420ac287), SkBits2Float(0xc2505e9c), SkBits2Float(0x418e7039), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427f077b), SkBits2Float(0xc25490c6));
+path.cubicTo(SkBits2Float(0x42829e52), SkBits2Float(0xc24d1e28), SkBits2Float(0x42858ec1), SkBits2Float(0xc24566d6), SkBits2Float(0x428852e3), SkBits2Float(0xc23d7081));
+path.lineTo(SkBits2Float(0x42451839), SkBits2Float(0xc208f1b7));
+path.cubicTo(SkBits2Float(0x4241186a), SkBits2Float(0xc20eb335), SkBits2Float(0x423cd88e), SkBits2Float(0xc2144725), SkBits2Float(0x42385bc4), SkBits2Float(0xc219a96c));
+path.lineTo(SkBits2Float(0x427f077b), SkBits2Float(0xc25490c6));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp224(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41c50a2c), SkBits2Float(0xc2a60000), SkBits2Float(0x423ff37f), SkBits2Float(0xc2901f4e), SkBits2Float(0x427f077c), SkBits2Float(0xc25490c6));
+path.lineTo(SkBits2Float(0x428852e3), SkBits2Float(0xc23d7081));
+path.lineTo(SkBits2Float(0x42451839), SkBits2Float(0xc208f1b7));
+path.cubicTo(SkBits2Float(0x4241186a), SkBits2Float(0xc20eb335), SkBits2Float(0x423cd88e), SkBits2Float(0xc2144725), SkBits2Float(0x42385bc4), SkBits2Float(0xc219a96c));
+path.lineTo(SkBits2Float(0x42385bc5), SkBits2Float(0xc219a96d));
+path.cubicTo(SkBits2Float(0x420ac287), SkBits2Float(0xc2505e9c), SkBits2Float(0x418e7039), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x428852e3), SkBits2Float(0xc23d7081));
+path.cubicTo(SkBits2Float(0x42b71f8a), SkBits2Float(0xc15aea65), SkBits2Float(0x42adb77f), SkBits2Float(0x42002593), SkBits2Float(0x42645e8b), SkBits2Float(0x4270faee));
+path.lineTo(SkBits2Float(0x42251616), SkBits2Float(0x422e33d9));
+path.cubicTo(SkBits2Float(0x427b2825), SkBits2Float(0x41b945be), SkBits2Float(0x428460d4), SkBits2Float(0xc11e4099), SkBits2Float(0x4245183a), SkBits2Float(0xc208f1b8));
+path.lineTo(SkBits2Float(0x428852e3), SkBits2Float(0xc23d7081));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp225(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d8749b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4251a993), SkBits2Float(0xc28b9f9f), SkBits2Float(0x4287e789), SkBits2Float(0xc23ea40d));
+path.lineTo(SkBits2Float(0x42447d05), SkBits2Float(0xc209d00a));
+path.cubicTo(SkBits2Float(0x4217902d), SkBits2Float(0xc249dd89), SkBits2Float(0x419c7951), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4287e78a), SkBits2Float(0xc23ea40e));
+path.cubicTo(SkBits2Float(0x428af3dc), SkBits2Float(0xc235f2f3), SkBits2Float(0x428dca5e), SkBits2Float(0xc22cf844), SkBits2Float(0x4290688d), SkBits2Float(0xc223bbef));
+path.lineTo(SkBits2Float(0x4250c881), SkBits2Float(0xc1ecb95a));
+path.cubicTo(SkBits2Float(0x424cff91), SkBits2Float(0xc1fa13ac), SkBits2Float(0x4248e532), SkBits2Float(0xc2038788), SkBits2Float(0x42447d06), SkBits2Float(0xc209d00a));
+path.lineTo(SkBits2Float(0x4287e78a), SkBits2Float(0xc23ea40e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp226(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d8749b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4251a993), SkBits2Float(0xc28b9f9f), SkBits2Float(0x4287e78a), SkBits2Float(0xc23ea40e));
+path.cubicTo(SkBits2Float(0x428af3dc), SkBits2Float(0xc235f2f3), SkBits2Float(0x428dca5e), SkBits2Float(0xc22cf844), SkBits2Float(0x4290688d), SkBits2Float(0xc223bbef));
+path.lineTo(SkBits2Float(0x4250c881), SkBits2Float(0xc1ecb95a));
+path.cubicTo(SkBits2Float(0x424cff91), SkBits2Float(0xc1fa13ac), SkBits2Float(0x4248e532), SkBits2Float(0xc2038788), SkBits2Float(0x42447d05), SkBits2Float(0xc209d00a));
+path.cubicTo(SkBits2Float(0x4217902d), SkBits2Float(0xc249dd89), SkBits2Float(0x419c7951), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4290688d), SkBits2Float(0xc223bbef));
+path.cubicTo(SkBits2Float(0x42bd187d), SkBits2Float(0xbfc2a74a), SkBits2Float(0x42a250ed), SkBits2Float(0x42421cbf), SkBits2Float(0x42287a28), SkBits2Float(0x428f09b7));
+path.lineTo(SkBits2Float(0x41f394da), SkBits2Float(0x424ecd48));
+path.cubicTo(SkBits2Float(0x426aac8a), SkBits2Float(0x420c527b), SkBits2Float(0x4288b219), SkBits2Float(0xbf8cb68f), SkBits2Float(0x4250c882), SkBits2Float(0xc1ecb95c));
+path.lineTo(SkBits2Float(0x4290688d), SkBits2Float(0xc223bbef));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp227(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f1efaa), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42685cb5), SkBits2Float(0xc2851a3e), SkBits2Float(0x429160d2), SkBits2Float(0xc22043b6));
+path.lineTo(SkBits2Float(0x42522f73), SkBits2Float(0xc1e7b52d));
+path.cubicTo(SkBits2Float(0x4227f8ff), SkBits2Float(0xc2406ff8), SkBits2Float(0x41aee4c7), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429160d2), SkBits2Float(0xc22043b7));
+path.cubicTo(SkBits2Float(0x42943aa0), SkBits2Float(0xc215eba6), SkBits2Float(0x4296cd42), SkBits2Float(0xc20b4794), SkBits2Float(0x429915e6), SkBits2Float(0xc200631e));
+path.lineTo(SkBits2Float(0x425d5418), SkBits2Float(0xc1b99eb9));
+path.cubicTo(SkBits2Float(0x425a06d4), SkBits2Float(0xc1c95e3a), SkBits2Float(0x42564e98), SkBits2Float(0xc1d8c0a6), SkBits2Float(0x42522f74), SkBits2Float(0xc1e7b52e));
+path.lineTo(SkBits2Float(0x429160d2), SkBits2Float(0xc22043b7));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp228(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f1efa9), SkBits2Float(0xc2a60000), SkBits2Float(0x42685cb5), SkBits2Float(0xc2851a3e), SkBits2Float(0x429160d2), SkBits2Float(0xc22043b7));
+path.lineTo(SkBits2Float(0x429160d2), SkBits2Float(0xc22043b6));
+path.cubicTo(SkBits2Float(0x42943aa0), SkBits2Float(0xc215eba5), SkBits2Float(0x4296cd42), SkBits2Float(0xc20b4794), SkBits2Float(0x429915e6), SkBits2Float(0xc200631e));
+path.lineTo(SkBits2Float(0x425d5418), SkBits2Float(0xc1b99eb9));
+path.cubicTo(SkBits2Float(0x425a06d4), SkBits2Float(0xc1c95e3a), SkBits2Float(0x42564e98), SkBits2Float(0xc1d8c0a6), SkBits2Float(0x42522f74), SkBits2Float(0xc1e7b52e));
+path.lineTo(SkBits2Float(0x42522f73), SkBits2Float(0xc1e7b52d));
+path.cubicTo(SkBits2Float(0x4227f8ff), SkBits2Float(0xc2406ff8), SkBits2Float(0x41aee4c7), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429915e6), SkBits2Float(0xc200631e));
+path.cubicTo(SkBits2Float(0x42abe101), SkBits2Float(0xc11b0235), SkBits2Float(0x42aa16bb), SkBits2Float(0x417b685c), SkBits2Float(0x42942fff), SkBits2Float(0x42159e77));
+path.cubicTo(SkBits2Float(0x427c9284), SkBits2Float(0x426c62d8), SkBits2Float(0x422cf27d), SkBits2Float(0x4295ccdb), SkBits2Float(0x419d039e), SkBits2Float(0x42a14aca));
+path.lineTo(SkBits2Float(0x4163022c), SkBits2Float(0x42693188));
+path.cubicTo(SkBits2Float(0x41fa0b56), SkBits2Float(0x42589424), SkBits2Float(0x4236951c), SkBits2Float(0x422ae1ad), SkBits2Float(0x42563f3c), SkBits2Float(0x41d85112));
+path.cubicTo(SkBits2Float(0x4275e95c), SkBits2Float(0x4135bd94), SkBits2Float(0x42787fea), SkBits2Float(0xc0e01be1), SkBits2Float(0x425d5419), SkBits2Float(0xc1b99eba));
+path.lineTo(SkBits2Float(0x429915e6), SkBits2Float(0xc200631e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp229(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4206c976), SkBits2Float(0xc2a60000), SkBits2Float(0x42801937), SkBits2Float(0xc27a823c), SkBits2Float(0x4299a0d7), SkBits2Float(0xc1fb88d1));
+path.lineTo(SkBits2Float(0x425e1cfa), SkBits2Float(0xc1b5d505));
+path.cubicTo(SkBits2Float(0x423933e1), SkBits2Float(0xc2351735), SkBits2Float(0x41c2df6b), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4299a0d8), SkBits2Float(0xc1fb88d0));
+path.cubicTo(SkBits2Float(0x429c1b73), SkBits2Float(0xc1e34f53), SkBits2Float(0x429e39d2), SkBits2Float(0xc1ca8528), SkBits2Float(0x429ff920), SkBits2Float(0xc1b14b8c));
+path.lineTo(SkBits2Float(0x42674955), SkBits2Float(0xc1802a45));
+path.cubicTo(SkBits2Float(0x4264c2a3), SkBits2Float(0xc192666d), SkBits2Float(0x4261b27b), SkBits2Float(0xc1a45204), SkBits2Float(0x425e1cfb), SkBits2Float(0xc1b5d506));
+path.lineTo(SkBits2Float(0x4299a0d8), SkBits2Float(0xc1fb88d0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp230(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4206c976), SkBits2Float(0xc2a60000), SkBits2Float(0x42801937), SkBits2Float(0xc27a823c), SkBits2Float(0x4299a0d8), SkBits2Float(0xc1fb88d0));
+path.cubicTo(SkBits2Float(0x429c1b73), SkBits2Float(0xc1e34f53), SkBits2Float(0x429e39d2), SkBits2Float(0xc1ca8528), SkBits2Float(0x429ff920), SkBits2Float(0xc1b14b8c));
+path.lineTo(SkBits2Float(0x42674955), SkBits2Float(0xc1802a45));
+path.cubicTo(SkBits2Float(0x4264c2a3), SkBits2Float(0xc192666d), SkBits2Float(0x4261b27b), SkBits2Float(0xc1a45204), SkBits2Float(0x425e1cfa), SkBits2Float(0xc1b5d505));
+path.cubicTo(SkBits2Float(0x423933e1), SkBits2Float(0xc2351735), SkBits2Float(0x41c2df6b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429ff91f), SkBits2Float(0xc1b14b8a));
+path.cubicTo(SkBits2Float(0x42ae673b), SkBits2Float(0x40783c41), SkBits2Float(0x42a293c2), SkBits2Float(0x41fe6960), SkBits2Float(0x4280464e), SkBits2Float(0x4252ba7b));
+path.cubicTo(SkBits2Float(0x423bf1b3), SkBits2Float(0x42932023), SkBits2Float(0x41a5f32c), SkBits2Float(0x42a99309), SkBits2Float(0xc0c67989), SkBits2Float(0x42a5892f));
+path.lineTo(SkBits2Float(0xc08f79c7), SkBits2Float(0x426f5437));
+path.cubicTo(SkBits2Float(0x416fed74), SkBits2Float(0x42752af2), SkBits2Float(0x4207dcfc), SkBits2Float(0x4254b62d), SkBits2Float(0x42397512), SkBits2Float(0x42185575));
+path.cubicTo(SkBits2Float(0x426b0d26), SkBits2Float(0x41b7e97d), SkBits2Float(0x427c2639), SkBits2Float(0x40337286), SkBits2Float(0x42674956), SkBits2Float(0xc1802a46));
+path.lineTo(SkBits2Float(0x429ff91f), SkBits2Float(0xc1b14b8a));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp231(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x421472e7), SkBits2Float(0xc2a5ffff), SkBits2Float(0x428b6da4), SkBits2Float(0xc26973d7), SkBits2Float(0x429fb179), SkBits2Float(0xc1b54986));
+path.lineTo(SkBits2Float(0x4266e1be), SkBits2Float(0xc1830d0f));
+path.cubicTo(SkBits2Float(0x42499544), SkBits2Float(0xc228c2c8), SkBits2Float(0x41d69ff6), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429fb179), SkBits2Float(0xc1b54988));
+path.cubicTo(SkBits2Float(0x42a1a632), SkBits2Float(0xc199b837), SkBits2Float(0x42a3282f), SkBits2Float(0xc17b594e), SkBits2Float(0x42a43501), SkBits2Float(0xc142a7ba));
+path.lineTo(SkBits2Float(0x426d6865), SkBits2Float(0xc10cb6f0));
+path.cubicTo(SkBits2Float(0x426be3bc), SkBits2Float(0xc135b2ae), SkBits2Float(0x4269b5af), SkBits2Float(0xc15e3ec8), SkBits2Float(0x4266e1be), SkBits2Float(0xc1830d0f));
+path.lineTo(SkBits2Float(0x429fb179), SkBits2Float(0xc1b54988));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp232(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x421472e7), SkBits2Float(0xc2a60000), SkBits2Float(0x428b6da4), SkBits2Float(0xc26973d8), SkBits2Float(0x429fb179), SkBits2Float(0xc1b54988));
+path.lineTo(SkBits2Float(0x429fb179), SkBits2Float(0xc1b54986));
+path.cubicTo(SkBits2Float(0x42a1a632), SkBits2Float(0xc199b836), SkBits2Float(0x42a3282f), SkBits2Float(0xc17b594d), SkBits2Float(0x42a43501), SkBits2Float(0xc142a7ba));
+path.lineTo(SkBits2Float(0x426d6865), SkBits2Float(0xc10cb6f0));
+path.cubicTo(SkBits2Float(0x426be3bc), SkBits2Float(0xc135b2ae), SkBits2Float(0x4269b5af), SkBits2Float(0xc15e3ec8), SkBits2Float(0x4266e1be), SkBits2Float(0xc1830d0f));
+path.cubicTo(SkBits2Float(0x42499544), SkBits2Float(0xc228c2c8), SkBits2Float(0x41d69ff6), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a43502), SkBits2Float(0xc142a7bb));
+path.cubicTo(SkBits2Float(0x42ace9b0), SkBits2Float(0x4189ae79), SkBits2Float(0x429590d6), SkBits2Float(0x423ab1c1), SkBits2Float(0x424df762), SkBits2Float(0x428231a6));
+path.cubicTo(SkBits2Float(0x41e19a31), SkBits2Float(0x42a70a69), SkBits2Float(0xc04a3289), SkBits2Float(0x42b03133), SkBits2Float(0xc1f5f36e), SkBits2Float(0x429a3139));
+path.lineTo(SkBits2Float(0xc1b1cbb9), SkBits2Float(0x425eedb9));
+path.cubicTo(SkBits2Float(0xc0122aac), SkBits2Float(0x427ebc5a), SkBits2Float(0x41a31606), SkBits2Float(0x42718130), SkBits2Float(0x4214e430), SkBits2Float(0x423c3b73));
+path.cubicTo(SkBits2Float(0x42583d5c), SkBits2Float(0x4206f5b6), SkBits2Float(0x4279fe97), SkBits2Float(0x41470ec8), SkBits2Float(0x426d6866), SkBits2Float(0xc10cb6eb));
+path.lineTo(SkBits2Float(0x42a43502), SkBits2Float(0xc142a7bb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp233(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4220aa02), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42952310), SkBits2Float(0xc258f48d), SkBits2Float(0x42a35f68), SkBits2Float(0xc16b5614));
+path.lineTo(SkBits2Float(0x426c3395), SkBits2Float(0xc12a1f61));
+path.cubicTo(SkBits2Float(0x42579ea8), SkBits2Float(0xc21cd5ce), SkBits2Float(0x41e84916), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a35f69), SkBits2Float(0xc16b5613));
+path.cubicTo(SkBits2Float(0x42a4bd24), SkBits2Float(0xc12ea3c2), SkBits2Float(0x42a59325), SkBits2Float(0xc0e282d6), SkBits2Float(0x42a5dfdf), SkBits2Float(0xc04e84a0));
+path.lineTo(SkBits2Float(0x426fd18d), SkBits2Float(0xc0154a48));
+path.cubicTo(SkBits2Float(0x426f62a1), SkBits2Float(0xc0a3be33), SkBits2Float(0x426e2d39), SkBits2Float(0xc0fc7dbb), SkBits2Float(0x426c3397), SkBits2Float(0xc12a1f63));
+path.lineTo(SkBits2Float(0x42a35f69), SkBits2Float(0xc16b5613));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp234(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4220aa02), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42952310), SkBits2Float(0xc258f48d), SkBits2Float(0x42a35f69), SkBits2Float(0xc16b5613));
+path.cubicTo(SkBits2Float(0x42a4bd24), SkBits2Float(0xc12ea3c2), SkBits2Float(0x42a59325), SkBits2Float(0xc0e282d6), SkBits2Float(0x42a5dfdf), SkBits2Float(0xc04e84a0));
+path.lineTo(SkBits2Float(0x426fd18d), SkBits2Float(0xc0154a48));
+path.cubicTo(SkBits2Float(0x426f62a1), SkBits2Float(0xc0a3be33), SkBits2Float(0x426e2d39), SkBits2Float(0xc0fc7dbb), SkBits2Float(0x426c3397), SkBits2Float(0xc12a1f63));
+path.lineTo(SkBits2Float(0x426c3395), SkBits2Float(0xc12a1f61));
+path.cubicTo(SkBits2Float(0x42579ea8), SkBits2Float(0xc21cd5ce), SkBits2Float(0x41e84916), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a5dfdf), SkBits2Float(0xc04e84a0));
+path.cubicTo(SkBits2Float(0x42a85e4f), SkBits2Float(0x41e6959e), SkBits2Float(0x4285b4e3), SkBits2Float(0x426ae44f), SkBits2Float(0x4219b105), SkBits2Float(0x42932450));
+path.cubicTo(SkBits2Float(0x411fe111), SkBits2Float(0x42b0d679), SkBits2Float(0xc1c3966b), SkBits2Float(0x42ab1d42), SkBits2Float(0xc2482755), SkBits2Float(0x428470e8));
+path.lineTo(SkBits2Float(0xc210b07c), SkBits2Float(0x423f7b24));
+path.cubicTo(SkBits2Float(0xc18d6382), SkBits2Float(0x427764e8), SkBits2Float(0x40e72680), SkBits2Float(0x427fab4e), SkBits2Float(0x41de345e), SkBits2Float(0x4254bc3b));
+path.cubicTo(SkBits2Float(0x42414f8e), SkBits2Float(0x4229cd28), SkBits2Float(0x42736c9d), SkBits2Float(0x41a6b008), SkBits2Float(0x426fd18e), SkBits2Float(0xc0154a3f));
+path.lineTo(SkBits2Float(0x42a5dfdf), SkBits2Float(0xc04e84a0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp235(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x422e5e2d), SkBits2Float(0xc2a5ffff), SkBits2Float(0x429f82f2), SkBits2Float(0xc2451c35), SkBits2Float(0x42a59867), SkBits2Float(0xc0b956c5));
+path.lineTo(SkBits2Float(0x426f6a3b), SkBits2Float(0xc085fae3));
+path.cubicTo(SkBits2Float(0x42669e7e), SkBits2Float(0xc20e7d42), SkBits2Float(0x41fc1920), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a59868), SkBits2Float(0xc0b956ca));
+path.cubicTo(SkBits2Float(0x42a62cd8), SkBits2Float(0xbfd2dd07), SkBits2Float(0x42a621be), SkBits2Float(0x4020d557), SkBits2Float(0x42a57734), SkBits2Float(0x40d4ef9c));
+path.lineTo(SkBits2Float(0x426f3a3b), SkBits2Float(0x4099edfc));
+path.cubicTo(SkBits2Float(0x427030cb), SkBits2Float(0x3fe887ba), SkBits2Float(0x427040d6), SkBits2Float(0xbf986e77), SkBits2Float(0x426f6a3b), SkBits2Float(0xc085fae4));
+path.lineTo(SkBits2Float(0x42a59868), SkBits2Float(0xc0b956ca));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp236(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x422e5e2d), SkBits2Float(0xc2a5ffff), SkBits2Float(0x429f82f2), SkBits2Float(0xc2451c35), SkBits2Float(0x42a59868), SkBits2Float(0xc0b956ca));
+path.cubicTo(SkBits2Float(0x42a62cd8), SkBits2Float(0xbfd2dd07), SkBits2Float(0x42a621be), SkBits2Float(0x4020d557), SkBits2Float(0x42a57734), SkBits2Float(0x40d4ef9c));
+path.lineTo(SkBits2Float(0x426f3a3b), SkBits2Float(0x4099edfc));
+path.cubicTo(SkBits2Float(0x427030cb), SkBits2Float(0x3fe887bb), SkBits2Float(0x427040d6), SkBits2Float(0xbf986e74), SkBits2Float(0x426f6a3b), SkBits2Float(0xc085fae3));
+path.lineTo(SkBits2Float(0x426f6a3b), SkBits2Float(0xc085fae4));
+path.cubicTo(SkBits2Float(0x42669e7e), SkBits2Float(0xc20e7d42), SkBits2Float(0x41fc1920), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a57735), SkBits2Float(0x40d4ef9d));
+path.cubicTo(SkBits2Float(0x429fe5e1), SkBits2Float(0x4225104d), SkBits2Float(0x425fa7d9), SkBits2Float(0x428cf91a), SkBits2Float(0x41b3ea58), SkBits2Float(0x429fca49));
+path.cubicTo(SkBits2Float(0xc12ef606), SkBits2Float(0x42b29b77), SkBits2Float(0xc23abc07), SkBits2Float(0x4299d29d), SkBits2Float(0xc2863a28), SkBits2Float(0x42435615));
+path.lineTo(SkBits2Float(0xc242103b), SkBits2Float(0x420d34fa));
+path.cubicTo(SkBits2Float(0xc206fd22), SkBits2Float(0x425e64f1), SkBits2Float(0xc0fcf4a4), SkBits2Float(0x42811d1e), SkBits2Float(0x41820f34), SkBits2Float(0x426705a2));
+path.cubicTo(SkBits2Float(0x4221adc8), SkBits2Float(0x424bd107), SkBits2Float(0x42672d88), SkBits2Float(0x41eea576), SkBits2Float(0x426f3a3c), SkBits2Float(0x4099edfe));
+path.lineTo(SkBits2Float(0x42a57735), SkBits2Float(0x40d4ef9d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp237(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41b25a1b), SkBits2Float(0xc2a60000), SkBits2Float(0x422e9a51), SkBits2Float(0xc294100b), SkBits2Float(0x426d0a79), SkBits2Float(0xc26874a1));
+path.cubicTo(SkBits2Float(0x4295bd51), SkBits2Float(0xc228c92e), SkBits2Float(0x42a6d6d5), SkBits2Float(0xc1a5596e), SkBits2Float(0x42a5f7e5), SkBits2Float(0x3fcf7f4c));
+path.lineTo(SkBits2Float(0x426ff448), SkBits2Float(0x3f95ff69));
+path.cubicTo(SkBits2Float(0x4271369b), SkBits2Float(0xc16f0f30), SkBits2Float(0x42587daa), SkBits2Float(0xc1f4071e), SkBits2Float(0x422b5ada), SkBits2Float(0xc2280a4b));
+path.cubicTo(SkBits2Float(0x41fc7014), SkBits2Float(0xc2561107), SkBits2Float(0x4180eddd), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a5f7e5), SkBits2Float(0x3fcf7f2e));
+path.cubicTo(SkBits2Float(0x42a5cbdf), SkBits2Float(0x40c0b7f8), SkBits2Float(0x42a4eca2), SkBits2Float(0x41268f7d), SkBits2Float(0x42a35c4c), SkBits2Float(0x416be04e));
+path.lineTo(SkBits2Float(0x426c2f14), SkBits2Float(0x412a834e));
+path.cubicTo(SkBits2Float(0x426e71e2), SkBits2Float(0x40f0cf74), SkBits2Float(0x426fb4a3), SkBits2Float(0x408b5090), SkBits2Float(0x426ff449), SkBits2Float(0x3f95ff6b));
+path.lineTo(SkBits2Float(0x42a5f7e5), SkBits2Float(0x3fcf7f2e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp238(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41b25a1b), SkBits2Float(0xc2a60000), SkBits2Float(0x422e9a51), SkBits2Float(0xc294100b), SkBits2Float(0x426d0a79), SkBits2Float(0xc26874a1));
+path.cubicTo(SkBits2Float(0x4295bd51), SkBits2Float(0xc228c92e), SkBits2Float(0x42a6d6d5), SkBits2Float(0xc1a5596f), SkBits2Float(0x42a5f7e5), SkBits2Float(0x3fcf7f2e));
+path.lineTo(SkBits2Float(0x426c2f14), SkBits2Float(0x412a834e));
+path.cubicTo(SkBits2Float(0x426e71e2), SkBits2Float(0x40f0cf74), SkBits2Float(0x426fb4a3), SkBits2Float(0x408b5090), SkBits2Float(0x426ff449), SkBits2Float(0x3f95ff6b));
+path.lineTo(SkBits2Float(0x426ff448), SkBits2Float(0x3f95ff69));
+path.cubicTo(SkBits2Float(0x4271369b), SkBits2Float(0xc16f0f30), SkBits2Float(0x42587daa), SkBits2Float(0xc1f4071e), SkBits2Float(0x422b5ada), SkBits2Float(0xc2280a4b));
+path.cubicTo(SkBits2Float(0x41fc7014), SkBits2Float(0xc2561107), SkBits2Float(0x4180eddd), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a35c4c), SkBits2Float(0x416be04e));
+path.cubicTo(SkBits2Float(0x42963d3f), SkBits2Float(0x424c5e0d), SkBits2Float(0x42354f77), SkBits2Float(0x429d76d6), SkBits2Float(0x41096c90), SkBits2Float(0x42a51bdb));
+path.cubicTo(SkBits2Float(0xc1e1325f), SkBits2Float(0x42acc0e0), SkBits2Float(0xc27bf938), SkBits2Float(0x4282ec23), SkBits2Float(0xc299cad8), SkBits2Float(0x41f9ecd8));
+path.lineTo(SkBits2Float(0xc25e59b3), SkBits2Float(0x41b4ab36));
+path.cubicTo(SkBits2Float(0xc2362649), SkBits2Float(0x423d4911), SkBits2Float(0xc1a2caf7), SkBits2Float(0x4279c398), SkBits2Float(0x40c6af7d), SkBits2Float(0x426eb62b));
+path.cubicTo(SkBits2Float(0x4203115b), SkBits2Float(0x4263a8be), SkBits2Float(0x425936a2), SkBits2Float(0x4213bc4a), SkBits2Float(0x426c2f16), SkBits2Float(0x412a8350));
+path.lineTo(SkBits2Float(0x42a35c4c), SkBits2Float(0x416be04e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp239(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ba3f99), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4235f79d), SkBits2Float(0xc29271cf), SkBits2Float(0x4274db3f), SkBits2Float(0xc260354d));
+path.cubicTo(SkBits2Float(0x4299df70), SkBits2Float(0xc21b86fd), SkBits2Float(0x42a97305), SkBits2Float(0xc17e5d7a), SkBits2Float(0x42a55ba0), SkBits2Float(0x40e961b4));
+path.lineTo(SkBits2Float(0x426f1259), SkBits2Float(0x40a8b5ae));
+path.cubicTo(SkBits2Float(0x4274fca8), SkBits2Float(0xc137e0e1), SkBits2Float(0x425e777b), SkBits2Float(0xc1e0dbdb), SkBits2Float(0x42310131), SkBits2Float(0xc2221408));
+path.cubicTo(SkBits2Float(0x42038ae6), SkBits2Float(0xc253ba22), SkBits2Float(0x4186a32c), SkBits2Float(0xc2700000), SkBits2Float(0xb560056c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a55ba0), SkBits2Float(0x40e961b9));
+path.cubicTo(SkBits2Float(0x42a48d09), SkBits2Float(0x413de0a1), SkBits2Float(0x42a2fc74), SkBits2Float(0x41833376), SkBits2Float(0x42a0adff), SkBits2Float(0x41a6c250));
+path.lineTo(SkBits2Float(0x42684ed9), SkBits2Float(0x417118ef));
+path.cubicTo(SkBits2Float(0x426ba483), SkBits2Float(0x413db02f), SkBits2Float(0x426de7aa), SkBits2Float(0x410942c3), SkBits2Float(0x426f1258), SkBits2Float(0x40a8b5ad));
+path.lineTo(SkBits2Float(0x42a55ba0), SkBits2Float(0x40e961b9));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp240(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ba3f99), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4235f79d), SkBits2Float(0xc29271cf), SkBits2Float(0x4274db3f), SkBits2Float(0xc260354d));
+path.cubicTo(SkBits2Float(0x4299df70), SkBits2Float(0xc21b86fd), SkBits2Float(0x42a97305), SkBits2Float(0xc17e5d7a), SkBits2Float(0x42a55ba0), SkBits2Float(0x40e961b9));
+path.cubicTo(SkBits2Float(0x42a48d09), SkBits2Float(0x413de0a1), SkBits2Float(0x42a2fc74), SkBits2Float(0x41833376), SkBits2Float(0x42a0adff), SkBits2Float(0x41a6c250));
+path.lineTo(SkBits2Float(0x42684ed9), SkBits2Float(0x417118ef));
+path.cubicTo(SkBits2Float(0x426ba483), SkBits2Float(0x413db02f), SkBits2Float(0x426de7aa), SkBits2Float(0x410942c3), SkBits2Float(0x426f1259), SkBits2Float(0x40a8b5ae));
+path.cubicTo(SkBits2Float(0x4274fca8), SkBits2Float(0xc137e0e1), SkBits2Float(0x425e777b), SkBits2Float(0xc1e0dbdb), SkBits2Float(0x42310131), SkBits2Float(0xc2221408));
+path.cubicTo(SkBits2Float(0x42038ae6), SkBits2Float(0xc253ba22), SkBits2Float(0x4186a32c), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a0ae00), SkBits2Float(0x41a6c250));
+path.cubicTo(SkBits2Float(0x428d4422), SkBits2Float(0x4269069e), SkBits2Float(0x42118d33), SkBits2Float(0x42a8086f), SkBits2Float(0xc00fe376), SkBits2Float(0x42a5f066));
+path.cubicTo(SkBits2Float(0xc22389a2), SkBits2Float(0x42a3d85e), SkBits2Float(0xc2935e5d), SkBits2Float(0x42596224), SkBits2Float(0xc2a2b39d), SkBits2Float(0x4183b53a));
+path.lineTo(SkBits2Float(0xc26b3b33), SkBits2Float(0x413e6bca));
+path.cubicTo(SkBits2Float(0xc2551027), SkBits2Float(0x421d2508), SkBits2Float(0xc1ec70a3), SkBits2Float(0x426ce27d), SkBits2Float(0xbfd007ff), SkBits2Float(0x426fe979));
+path.cubicTo(SkBits2Float(0x41d26fa4), SkBits2Float(0x4272f076), SkBits2Float(0x424c3d84), SkBits2Float(0x422873d5), SkBits2Float(0x42684eda), SkBits2Float(0x417118ee));
+path.lineTo(SkBits2Float(0x42a0ae00), SkBits2Float(0x41a6c250));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp241(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41c2abe0), SkBits2Float(0xc2a5ffff), SkBits2Float(0x423dc4ab), SkBits2Float(0xc290a493), SkBits2Float(0x427cd8fd), SkBits2Float(0xc25727eb));
+path.cubicTo(SkBits2Float(0x429df6a6), SkBits2Float(0xc20d06b1), SkBits2Float(0x42aba628), SkBits2Float(0xc12bcbe5), SkBits2Float(0x42a3dc46), SkBits2Float(0x4154872f));
+path.lineTo(SkBits2Float(0x426ce81c), SkBits2Float(0x4119a283));
+path.cubicTo(SkBits2Float(0x42782ad8), SkBits2Float(0xc0f86165), SkBits2Float(0x42646188), SkBits2Float(0xc1cbe4ab), SkBits2Float(0x4236c80c), SkBits2Float(0xc21b88d1));
+path.cubicTo(SkBits2Float(0x42092e8f), SkBits2Float(0xc2511f4c), SkBits2Float(0x418cb9f2), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a3dc46), SkBits2Float(0x41548735));
+path.cubicTo(SkBits2Float(0x42a2537f), SkBits2Float(0x41901e3f), SkBits2Float(0x429ff996), SkBits2Float(0x41b55e92), SkBits2Float(0x429cd549), SkBits2Float(0x41d999a0));
+path.lineTo(SkBits2Float(0x4262bf29), SkBits2Float(0x419d4d21));
+path.cubicTo(SkBits2Float(0x42674a02), SkBits2Float(0x41831c46), SkBits2Float(0x426ab03e), SkBits2Float(0x41505d16), SkBits2Float(0x426ce81d), SkBits2Float(0x4119a283));
+path.lineTo(SkBits2Float(0x42a3dc46), SkBits2Float(0x41548735));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp242(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41c2abe0), SkBits2Float(0xc2a5ffff), SkBits2Float(0x423dc4ab), SkBits2Float(0xc290a493), SkBits2Float(0x427cd8fd), SkBits2Float(0xc25727eb));
+path.cubicTo(SkBits2Float(0x429df6a6), SkBits2Float(0xc20d06b1), SkBits2Float(0x42aba628), SkBits2Float(0xc12bcbe5), SkBits2Float(0x42a3dc46), SkBits2Float(0x41548735));
+path.cubicTo(SkBits2Float(0x42a2537f), SkBits2Float(0x41901e3f), SkBits2Float(0x429ff996), SkBits2Float(0x41b55e92), SkBits2Float(0x429cd549), SkBits2Float(0x41d999a0));
+path.lineTo(SkBits2Float(0x4262bf29), SkBits2Float(0x419d4d21));
+path.cubicTo(SkBits2Float(0x42674a02), SkBits2Float(0x41831c46), SkBits2Float(0x426ab03e), SkBits2Float(0x41505d16), SkBits2Float(0x426ce81c), SkBits2Float(0x4119a283));
+path.cubicTo(SkBits2Float(0x42782ad8), SkBits2Float(0xc0f86165), SkBits2Float(0x42646188), SkBits2Float(0xc1cbe4ab), SkBits2Float(0x4236c80c), SkBits2Float(0xc21b88d1));
+path.cubicTo(SkBits2Float(0x42092e8f), SkBits2Float(0xc2511f4c), SkBits2Float(0x418cb9f2), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429cd549), SkBits2Float(0x41d999a0));
+path.cubicTo(SkBits2Float(0x42824b9e), SkBits2Float(0x4282e841), SkBits2Float(0x41d1b597), SkBits2Float(0x42b119ff), SkBits2Float(0xc15b80c3), SkBits2Float(0x42a3b776));
+path.cubicTo(SkBits2Float(0xc2569b2d), SkBits2Float(0x429654ee), SkBits2Float(0xc2a5db0b), SkBits2Float(0x42228c64), SkBits2Float(0xc2a5ffee), SkBits2Float(0x3e172efd));
+path.lineTo(SkBits2Float(0xc26fffe7), SkBits2Float(0x3dda91a4));
+path.cubicTo(SkBits2Float(0xc26fca99), SkBits2Float(0x41eb0285), SkBits2Float(0xc21b2317), SkBits2Float(0x425958e5), SkBits2Float(0xc11ead4d), SkBits2Float(0x426cb2ed));
+path.cubicTo(SkBits2Float(0x419798e1), SkBits2Float(0x4280067a), SkBits2Float(0x423c6102), SkBits2Float(0x423d4379), SkBits2Float(0x4262bf29), SkBits2Float(0x419d4d1f));
+path.lineTo(SkBits2Float(0x429cd549), SkBits2Float(0x41d999a0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp243(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41caf078), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42455e40), SkBits2Float(0xc28ecc78), SkBits2Float(0x42822b31), SkBits2Float(0xc24e07b4));
+path.cubicTo(SkBits2Float(0x42a1a743), SkBits2Float(0xc1fcecee), SkBits2Float(0x42ad3753), SkBits2Float(0xc0b3be45), SkBits2Float(0x42a18eed), SkBits2Float(0x419892cb));
+path.lineTo(SkBits2Float(0x42699409), SkBits2Float(0x415c9689));
+path.cubicTo(SkBits2Float(0x427a6ed6), SkBits2Float(0xc081ef5b), SkBits2Float(0x4269b739), SkBits2Float(0xc1b6d67a), SkBits2Float(0x423c321c), SkBits2Float(0xc214effc));
+path.cubicTo(SkBits2Float(0x420eacff), SkBits2Float(0xc24e74bc), SkBits2Float(0x4192b3ff), SkBits2Float(0xc2700000), SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42a18eed), SkBits2Float(0x419892ca));
+path.cubicTo(SkBits2Float(0x429f43c9), SkBits2Float(0x41bf6e44), SkBits2Float(0x429c198b), SkBits2Float(0x41e561a5), SkBits2Float(0x42981a0b), SkBits2Float(0x4204fb6e));
+path.lineTo(SkBits2Float(0x425be7f8), SkBits2Float(0x41c0436a));
+path.cubicTo(SkBits2Float(0x4261afba), SkBits2Float(0x41a5d162), SkBits2Float(0x42664329), SkBits2Float(0x418a6237), SkBits2Float(0x4269940a), SkBits2Float(0x415c968a));
+path.lineTo(SkBits2Float(0x42a18eed), SkBits2Float(0x419892ca));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp244(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41caf078), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42455e40), SkBits2Float(0xc28ecc78), SkBits2Float(0x42822b31), SkBits2Float(0xc24e07b4));
+path.cubicTo(SkBits2Float(0x42a1a743), SkBits2Float(0xc1fcecee), SkBits2Float(0x42ad3753), SkBits2Float(0xc0b3be48), SkBits2Float(0x42a18eed), SkBits2Float(0x419892ca));
+path.lineTo(SkBits2Float(0x42a18eed), SkBits2Float(0x419892cb));
+path.cubicTo(SkBits2Float(0x429f43c9), SkBits2Float(0x41bf6e45), SkBits2Float(0x429c198b), SkBits2Float(0x41e561a5), SkBits2Float(0x42981a0b), SkBits2Float(0x4204fb6e));
+path.lineTo(SkBits2Float(0x425be7f8), SkBits2Float(0x41c0436a));
+path.cubicTo(SkBits2Float(0x4261afba), SkBits2Float(0x41a5d162), SkBits2Float(0x42664329), SkBits2Float(0x418a6237), SkBits2Float(0x4269940a), SkBits2Float(0x415c968a));
+path.lineTo(SkBits2Float(0x42699409), SkBits2Float(0x415c9689));
+path.cubicTo(SkBits2Float(0x427a6ed6), SkBits2Float(0xc081ef5b), SkBits2Float(0x4269b739), SkBits2Float(0xc1b6d67a), SkBits2Float(0x423c321c), SkBits2Float(0xc214effc));
+path.cubicTo(SkBits2Float(0x420eacff), SkBits2Float(0xc24e74bc), SkBits2Float(0x4192b3ff), SkBits2Float(0xc2700000), SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42981a0b), SkBits2Float(0x4204fb6e));
+path.cubicTo(SkBits2Float(0x426c6b55), SkBits2Float(0x42900555), SkBits2Float(0x417b6a9f), SkBits2Float(0x42b7a6c3), SkBits2Float(0xc1c57072), SkBits2Float(0x429e7dd7));
+path.cubicTo(SkBits2Float(0xc282258c), SkBits2Float(0x428554eb), SkBits2Float(0xc2b314c4), SkBits2Float(0x41cdbc89), SkBits2Float(0xc2a2f571), SkBits2Float(0xc17d09b6));
+path.lineTo(SkBits2Float(0xc26b9a61), SkBits2Float(0xc136eb32));
+path.cubicTo(SkBits2Float(0xc28174d0), SkBits2Float(0x4194b9b3), SkBits2Float(0xc23c29fc), SkBits2Float(0x4240c4dc), SkBits2Float(0xc18eba2f), SkBits2Float(0x4265250a));
+path.cubicTo(SkBits2Float(0x4135bf41), SkBits2Float(0x4284c29d), SkBits2Float(0x422ae7d8), SkBits2Float(0x42503918), SkBits2Float(0x425be7f9), SkBits2Float(0x41c04367));
+path.lineTo(SkBits2Float(0x42981a0b), SkBits2Float(0x4204fb6e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp245(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d28773), SkBits2Float(0xc2a5ffff), SkBits2Float(0x424c4acf), SkBits2Float(0xc28d0a47), SkBits2Float(0x428572fc), SkBits2Float(0xc24574fc));
+path.cubicTo(SkBits2Float(0x42a4c090), SkBits2Float(0xc1e1aad9), SkBits2Float(0x42ae2294), SkBits2Float(0xbf62367e), SkBits2Float(0x429ebce0), SkBits2Float(0x41c23fec));
+path.lineTo(SkBits2Float(0x4265801d), SkBits2Float(0x418c6be6));
+path.cubicTo(SkBits2Float(0x427bc2fb), SkBits2Float(0xbf238720), SkBits2Float(0x426e322e), SkBits2Float(0xc1a32211), SkBits2Float(0x4240f046), SkBits2Float(0xc20ebd71));
+path.cubicTo(SkBits2Float(0x4213ae61), SkBits2Float(0xc24be9da), SkBits2Float(0x41983095), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429ebce1), SkBits2Float(0x41c23fee));
+path.cubicTo(SkBits2Float(0x429bb658), SkBits2Float(0x41e9cedc), SkBits2Float(0x4297c4ea), SkBits2Float(0x4208130e), SkBits2Float(0x4292f5c0), SkBits2Float(0x421a62d5));
+path.lineTo(SkBits2Float(0x425478e6), SkBits2Float(0x41df3573));
+path.cubicTo(SkBits2Float(0x425b6ce6), SkBits2Float(0x41c4bbf1), SkBits2Float(0x42612050), SkBits2Float(0x41a90494), SkBits2Float(0x4265801e), SkBits2Float(0x418c6be6));
+path.lineTo(SkBits2Float(0x429ebce1), SkBits2Float(0x41c23fee));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp246(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d28773), SkBits2Float(0xc2a5ffff), SkBits2Float(0x424c4acf), SkBits2Float(0xc28d0a47), SkBits2Float(0x428572fc), SkBits2Float(0xc24574fc));
+path.cubicTo(SkBits2Float(0x42a4c090), SkBits2Float(0xc1e1aad9), SkBits2Float(0x42ae2294), SkBits2Float(0xbf62367e), SkBits2Float(0x429ebce1), SkBits2Float(0x41c23fee));
+path.cubicTo(SkBits2Float(0x429bb658), SkBits2Float(0x41e9cedc), SkBits2Float(0x4297c4ea), SkBits2Float(0x4208130e), SkBits2Float(0x4292f5c0), SkBits2Float(0x421a62d5));
+path.lineTo(SkBits2Float(0x425478e6), SkBits2Float(0x41df3573));
+path.cubicTo(SkBits2Float(0x425b6ce6), SkBits2Float(0x41c4bbf1), SkBits2Float(0x42612050), SkBits2Float(0x41a90494), SkBits2Float(0x4265801d), SkBits2Float(0x418c6be6));
+path.cubicTo(SkBits2Float(0x427bc2fb), SkBits2Float(0xbf238720), SkBits2Float(0x426e322e), SkBits2Float(0xc1a32211), SkBits2Float(0x4240f046), SkBits2Float(0xc20ebd71));
+path.cubicTo(SkBits2Float(0x4213ae61), SkBits2Float(0xc24be9da), SkBits2Float(0x41983095), SkBits2Float(0xc2700000), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4292f5c1), SkBits2Float(0x421a62d6));
+path.cubicTo(SkBits2Float(0x42541a09), SkBits2Float(0x429b1363), SkBits2Float(0x40b7c75d), SkBits2Float(0x42bb84d6), SkBits2Float(0xc2093cef), SkBits2Float(0x42972755));
+path.cubicTo(SkBits2Float(0xc294b966), SkBits2Float(0x426593a9), SkBits2Float(0xc2ba8c7c), SkBits2Float(0x4131f51c), SkBits2Float(0xc29ad8fe), SkBits2Float(0xc1ef45cd));
+path.lineTo(SkBits2Float(0xc25fe048), SkBits2Float(0xc1acf7d7));
+path.cubicTo(SkBits2Float(0xc286dac7), SkBits2Float(0x4100a4f0), SkBits2Float(0xc25705ec), SkBits2Float(0x4225f597), SkBits2Float(0xc1c66aa8), SkBits2Float(0x425a891e));
+path.cubicTo(SkBits2Float(0x4084da24), SkBits2Float(0x42878e54), SkBits2Float(0x4219539e), SkBits2Float(0x426034bf), SkBits2Float(0x425478e7), SkBits2Float(0x41df3571));
+path.lineTo(SkBits2Float(0x4292f5c1), SkBits2Float(0x421a62d6));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp247(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d91350), SkBits2Float(0xc2a5ffff), SkBits2Float(0x425238e3), SkBits2Float(0xc28b791f), SkBits2Float(0x428827e4), SkBits2Float(0xc23dec02));
+path.cubicTo(SkBits2Float(0x42a73357), SkBits2Float(0xc1c9cb8b), SkBits2Float(0x42ae86ff), SkBits2Float(0x404daf5b), SkBits2Float(0x429bc6e8), SkBits2Float(0x41e56ae9));
+path.lineTo(SkBits2Float(0x42613841), SkBits2Float(0x41a5d816));
+path.cubicTo(SkBits2Float(0x427c5425), SkBits2Float(0x4014b024), SkBits2Float(0x4271bc5c), SkBits2Float(0xc191e03e), SkBits2Float(0x4244da12), SkBits2Float(0xc2094aff));
+path.cubicTo(SkBits2Float(0x4217f7c8), SkBits2Float(0xc249a5df), SkBits2Float(0x419cec09), SkBits2Float(0xc2700000), SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x429bc6e9), SkBits2Float(0x41e56aeb));
+path.cubicTo(SkBits2Float(0x429818bd), SkBits2Float(0x4206b36a), SkBits2Float(0x42937671), SkBits2Float(0x4219f01e), SkBits2Float(0x428df070), SkBits2Float(0x422c2771));
+path.lineTo(SkBits2Float(0x424d369d), SkBits2Float(0x41f8e5bf));
+path.cubicTo(SkBits2Float(0x425532f6), SkBits2Float(0x41de8f99), SkBits2Float(0x425be616), SkBits2Float(0x41c2bf8b), SkBits2Float(0x42613843), SkBits2Float(0x41a5d816));
+path.lineTo(SkBits2Float(0x429bc6e9), SkBits2Float(0x41e56aeb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp248(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41d91350), SkBits2Float(0xc2a5ffff), SkBits2Float(0x425238e3), SkBits2Float(0xc28b791f), SkBits2Float(0x428827e4), SkBits2Float(0xc23dec02));
+path.cubicTo(SkBits2Float(0x42a73357), SkBits2Float(0xc1c9cb8b), SkBits2Float(0x42ae86ff), SkBits2Float(0x404daf5b), SkBits2Float(0x429bc6e9), SkBits2Float(0x41e56aeb));
+path.cubicTo(SkBits2Float(0x429818bd), SkBits2Float(0x4206b36a), SkBits2Float(0x42937671), SkBits2Float(0x4219f01e), SkBits2Float(0x428df070), SkBits2Float(0x422c2771));
+path.lineTo(SkBits2Float(0x424d369d), SkBits2Float(0x41f8e5bf));
+path.cubicTo(SkBits2Float(0x425532f6), SkBits2Float(0x41de8f99), SkBits2Float(0x425be616), SkBits2Float(0x41c2bf8b), SkBits2Float(0x42613843), SkBits2Float(0x41a5d816));
+path.lineTo(SkBits2Float(0x42613841), SkBits2Float(0x41a5d816));
+path.cubicTo(SkBits2Float(0x427c5425), SkBits2Float(0x4014b024), SkBits2Float(0x4271bc5c), SkBits2Float(0xc191e03e), SkBits2Float(0x4244da12), SkBits2Float(0xc2094aff));
+path.cubicTo(SkBits2Float(0x4217f7c8), SkBits2Float(0xc249a5df), SkBits2Float(0x419cec09), SkBits2Float(0xc2700000), SkBits2Float(0xb630015b), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x428df071), SkBits2Float(0x422c2771));
+path.cubicTo(SkBits2Float(0x423d9ebb), SkBits2Float(0x42a3ca6a), SkBits2Float(0xc041a78f), SkBits2Float(0x42bd279e), SkBits2Float(0xc228abe7), SkBits2Float(0x428efaad));
+path.cubicTo(SkBits2Float(0xc2a29eac), SkBits2Float(0x42419b78), SkBits2Float(0xc2bd3710), SkBits2Float(0xbfef63d4), SkBits2Float(0xc2900003), SkBits2Float(0xc2252a98));
+path.lineTo(SkBits2Float(0xc250315d), SkBits2Float(0xc1eecb7c));
+path.cubicTo(SkBits2Float(0xc288c864), SkBits2Float(0xbfad0c79), SkBits2Float(0xc26b1d6b), SkBits2Float(0x420bf56b), SkBits2Float(0xc1f3dd5d), SkBits2Float(0x424eb80d));
+path.cubicTo(SkBits2Float(0xc00bff34), SkBits2Float(0x4288bd57), SkBits2Float(0x4209134e), SkBits2Float(0x426ccea7), SkBits2Float(0x424d369e), SkBits2Float(0x41f8e5bd));
+path.lineTo(SkBits2Float(0x428df071), SkBits2Float(0x422c2771));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp249(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41df6bc7), SkBits2Float(0xc2a60000), SkBits2Float(0x4257ee8b), SkBits2Float(0xc289e8f6), SkBits2Float(0x428aab73), SkBits2Float(0xc2368066));
+path.cubicTo(SkBits2Float(0x42a95fa1), SkBits2Float(0xc1b25dc1), SkBits2Float(0x42ae8dc1), SkBits2Float(0x40e61789), SkBits2Float(0x42987459), SkBits2Float(0x42035b41));
+path.lineTo(SkBits2Float(0x425c6a87), SkBits2Float(0x41bde9b7));
+path.cubicTo(SkBits2Float(0x427c5dea), SkBits2Float(0x40a654db), SkBits2Float(0x4274e0a0), SkBits2Float(0xc180f082), SkBits2Float(0x42487c82), SkBits2Float(0xc203edca));
+path.cubicTo(SkBits2Float(0x421c1865), SkBits2Float(0xc2476353), SkBits2Float(0x41a18256), SkBits2Float(0xc2700000), SkBits2Float(0xb69400ae), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42987459), SkBits2Float(0x42035b41));
+path.cubicTo(SkBits2Float(0x42941f1a), SkBits2Float(0x421778e1), SkBits2Float(0x428ecdc9), SkBits2Float(0x422aae55), SkBits2Float(0x42889449), SkBits2Float(0x423cb3b9));
+path.lineTo(SkBits2Float(0x424576c5), SkBits2Float(0x4208693e));
+path.cubicTo(SkBits2Float(0x424e76a2), SkBits2Float(0x41f6c488), SkBits2Float(0x425626ce), SkBits2Float(0x41dafef6), SkBits2Float(0x425c6a88), SkBits2Float(0x41bde9b8));
+path.lineTo(SkBits2Float(0x42987459), SkBits2Float(0x42035b41));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp250(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb69400ae), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41df6bc7), SkBits2Float(0xc2a60000), SkBits2Float(0x4257ee8b), SkBits2Float(0xc289e8f6), SkBits2Float(0x428aab73), SkBits2Float(0xc2368066));
+path.cubicTo(SkBits2Float(0x42a95fa1), SkBits2Float(0xc1b25dc1), SkBits2Float(0x42ae8dc1), SkBits2Float(0x40e61789), SkBits2Float(0x42987459), SkBits2Float(0x42035b41));
+path.cubicTo(SkBits2Float(0x42941f1a), SkBits2Float(0x421778e1), SkBits2Float(0x428ecdc9), SkBits2Float(0x422aae55), SkBits2Float(0x42889449), SkBits2Float(0x423cb3b9));
+path.lineTo(SkBits2Float(0x424576c5), SkBits2Float(0x4208693e));
+path.cubicTo(SkBits2Float(0x424e76a2), SkBits2Float(0x41f6c488), SkBits2Float(0x425626ce), SkBits2Float(0x41dafef6), SkBits2Float(0x425c6a87), SkBits2Float(0x41bde9b7));
+path.cubicTo(SkBits2Float(0x427c5dea), SkBits2Float(0x40a654db), SkBits2Float(0x4274e0a0), SkBits2Float(0xc180f082), SkBits2Float(0x42487c82), SkBits2Float(0xc203edca));
+path.cubicTo(SkBits2Float(0x421c1865), SkBits2Float(0xc2476353), SkBits2Float(0x41a18256), SkBits2Float(0xc2700000), SkBits2Float(0xb69400ae), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42889449), SkBits2Float(0x423cb3b8));
+path.cubicTo(SkBits2Float(0x424c5291), SkBits2Float(0x42902c61), SkBits2Float(0x41ad609d), SkBits2Float(0x42ab4d26), SkBits2Float(0xc1072a9c), SkBits2Float(0x42a52356));
+path.cubicTo(SkBits2Float(0xc21a459c), SkBits2Float(0x429ef985), SkBits2Float(0xc2813d9b), SkBits2Float(0x4270fef6), SkBits2Float(0xc298db30), SkBits2Float(0x420179e4));
+path.cubicTo(SkBits2Float(0xc2b078c6), SkBits2Float(0x408fa686), SkBits2Float(0xc2a7d9d7), SkBits2Float(0xc1dcde62), SkBits2Float(0xc2825c7e), SkBits2Float(0xc24d8ae0));
+path.lineTo(SkBits2Float(0xc23c7965), SkBits2Float(0xc21495bd));
+path.cubicTo(SkBits2Float(0xc272ad07), SkBits2Float(0xc19fa9fe), SkBits2Float(0xc27f23bc), SkBits2Float(0x404faf9e), SkBits2Float(0xc25cff22), SkBits2Float(0x41bb31a8));
+path.cubicTo(SkBits2Float(0xc23ada86), SkBits2Float(0x422e36b1), SkBits2Float(0xc1df0b0c), SkBits2Float(0x4265d7b2), SkBits2Float(0xc0c36b6f), SkBits2Float(0x426ec0e0));
+path.cubicTo(SkBits2Float(0x417aaa9e), SkBits2Float(0x4277aa0e), SkBits2Float(0x4213b3f9), SkBits2Float(0x42507175), SkBits2Float(0x424576c8), SkBits2Float(0x4208693c));
+path.lineTo(SkBits2Float(0x42889449), SkBits2Float(0x423cb3b8));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp251(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41e529f0), SkBits2Float(0xc2a5ffff), SkBits2Float(0x425d10b2), SkBits2Float(0xc2887541), SkBits2Float(0x428cd9cf), SkBits2Float(0xc22fb184));
+path.cubicTo(SkBits2Float(0x42ab2b45), SkBits2Float(0xc19cf10c), SkBits2Float(0x42ae472d), SkBits2Float(0x412c96c0), SkBits2Float(0x42951360), SkBits2Float(0x42120c0d));
+path.lineTo(SkBits2Float(0x425787f7), SkBits2Float(0x41d32707));
+path.cubicTo(SkBits2Float(0x427bf7e0), SkBits2Float(0x40f986c2), SkBits2Float(0x4277792b), SkBits2Float(0xc162e746), SkBits2Float(0x424ba3c8), SkBits2Float(0xc1fe03ba));
+path.cubicTo(SkBits2Float(0x421fce66), SkBits2Float(0xc24549e8), SkBits2Float(0x41a5a922), SkBits2Float(0xc2700000), SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42951360), SkBits2Float(0x42120c0f));
+path.cubicTo(SkBits2Float(0x429023a5), SkBits2Float(0x422633cd), SkBits2Float(0x428a3193), SkBits2Float(0x42394df4), SkBits2Float(0x42835484), SkBits2Float(0x424b0f7e));
+path.lineTo(SkBits2Float(0x423ddffa), SkBits2Float(0x4212ca6e));
+path.cubicTo(SkBits2Float(0x4247cc4f), SkBits2Float(0x4205f480), SkBits2Float(0x425064e4), SkBits2Float(0x41f04ae6), SkBits2Float(0x425787f8), SkBits2Float(0x41d32708));
+path.lineTo(SkBits2Float(0x42951360), SkBits2Float(0x42120c0f));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp252(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41e529f0), SkBits2Float(0xc2a5ffff), SkBits2Float(0x425d10b2), SkBits2Float(0xc2887541), SkBits2Float(0x428cd9cf), SkBits2Float(0xc22fb184));
+path.cubicTo(SkBits2Float(0x42ab2b45), SkBits2Float(0xc19cf10c), SkBits2Float(0x42ae472d), SkBits2Float(0x412c96c0), SkBits2Float(0x42951360), SkBits2Float(0x42120c0f));
+path.cubicTo(SkBits2Float(0x429023a5), SkBits2Float(0x422633cd), SkBits2Float(0x428a3193), SkBits2Float(0x42394df4), SkBits2Float(0x42835484), SkBits2Float(0x424b0f7e));
+path.lineTo(SkBits2Float(0x423ddffa), SkBits2Float(0x4212ca6e));
+path.cubicTo(SkBits2Float(0x4247cc4f), SkBits2Float(0x4205f480), SkBits2Float(0x425064e4), SkBits2Float(0x41f04ae6), SkBits2Float(0x425787f7), SkBits2Float(0x41d32707));
+path.cubicTo(SkBits2Float(0x427bf7e0), SkBits2Float(0x40f986c2), SkBits2Float(0x4277792b), SkBits2Float(0xc162e746), SkBits2Float(0x424ba3c8), SkBits2Float(0xc1fe03ba));
+path.cubicTo(SkBits2Float(0x421fce66), SkBits2Float(0xc24549e8), SkBits2Float(0x41a5a922), SkBits2Float(0xc2700000), SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42835484), SkBits2Float(0x424b0f7e));
+path.cubicTo(SkBits2Float(0x423aab34), SkBits2Float(0x4296ad9b), SkBits2Float(0x41789cf4), SkBits2Float(0x42ae7f70), SkBits2Float(0xc1702bd2), SkBits2Float(0x42a3434e));
+path.cubicTo(SkBits2Float(0xc2363d27), SkBits2Float(0x4298072c), SkBits2Float(0xc28cd4c4), SkBits2Float(0x42573cf7), SkBits2Float(0xc29edb8e), SkBits2Float(0x41c0adb0));
+path.cubicTo(SkBits2Float(0xc2b0e257), SkBits2Float(0xc0b47a14), SkBits2Float(0xc2a03550), SkBits2Float(0xc217a35b), SkBits2Float(0xc2674746), SkBits2Float(0xc26e3089));
+path.lineTo(SkBits2Float(0xc2273070), SkBits2Float(0xc22c2f6e));
+path.cubicTo(SkBits2Float(0xc267a050), SkBits2Float(0xc1db3c5e), SkBits2Float(0xc27fbc5f), SkBits2Float(0xc0827737), SkBits2Float(0xc265ac62), SkBits2Float(0x418b490c));
+path.cubicTo(SkBits2Float(0xc24b9c64), SkBits2Float(0x421b97f2), SkBits2Float(0xc203bd1c), SkBits2Float(0x425bcc95), SkBits2Float(0xc12d9e08), SkBits2Float(0x426c0adc));
+path.cubicTo(SkBits2Float(0x4133b85e), SkBits2Float(0x427c4921), SkBits2Float(0x4206f0f2), SkBits2Float(0x4259d90a), SkBits2Float(0x423ddff7), SkBits2Float(0x4212ca73));
+path.lineTo(SkBits2Float(0x42835484), SkBits2Float(0x424b0f7e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp253(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ea9e19), SkBits2Float(0xc2a60000), SkBits2Float(0x4261e8db), SkBits2Float(0xc2870be6), SkBits2Float(0x428ed6bc), SkBits2Float(0xc22926d7));
+path.cubicTo(SkBits2Float(0x42acb90a), SkBits2Float(0xc1886bc1), SkBits2Float(0x42adc0f7), SkBits2Float(0x41631db6), SkBits2Float(0x42918cff), SkBits2Float(0x421fa302));
+path.lineTo(SkBits2Float(0x42526f53), SkBits2Float(0x41e6ccd4));
+path.cubicTo(SkBits2Float(0x427b35d6), SkBits2Float(0x41242e26), SkBits2Float(0x4279b842), SkBits2Float(0xc1453c2f), SkBits2Float(0x424e8393), SkBits2Float(0xc1f48e84));
+path.cubicTo(SkBits2Float(0x42234ee4), SkBits2Float(0xc2433f78), SkBits2Float(0x41a99a66), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42918d00), SkBits2Float(0x421fa301));
+path.cubicTo(SkBits2Float(0x428c0830), SkBits2Float(0x4233c399), SkBits2Float(0x42857bfe), SkBits2Float(0x4246b13f), SkBits2Float(0x427c06a0), SkBits2Float(0x42581e30));
+path.lineTo(SkBits2Float(0x42362ff8), SkBits2Float(0x421c3ad6));
+path.cubicTo(SkBits2Float(0x4240fd4a), SkBits2Float(0x420fa210), SkBits2Float(0x424a74b5), SkBits2Float(0x4201f32f), SkBits2Float(0x42526f54), SkBits2Float(0x41e6ccd5));
+path.lineTo(SkBits2Float(0x42918d00), SkBits2Float(0x421fa301));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp254(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41ea9e19), SkBits2Float(0xc2a60000), SkBits2Float(0x4261e8db), SkBits2Float(0xc2870be6), SkBits2Float(0x428ed6bc), SkBits2Float(0xc22926d7));
+path.cubicTo(SkBits2Float(0x42acb90a), SkBits2Float(0xc1886bc1), SkBits2Float(0x42adc0f7), SkBits2Float(0x41631db6), SkBits2Float(0x42918d00), SkBits2Float(0x421fa301));
+path.cubicTo(SkBits2Float(0x428c0830), SkBits2Float(0x4233c399), SkBits2Float(0x42857bfe), SkBits2Float(0x4246b13f), SkBits2Float(0x427c06a0), SkBits2Float(0x42581e30));
+path.lineTo(SkBits2Float(0x42362ff8), SkBits2Float(0x421c3ad6));
+path.cubicTo(SkBits2Float(0x4240fd4a), SkBits2Float(0x420fa210), SkBits2Float(0x424a74b5), SkBits2Float(0x4201f32f), SkBits2Float(0x42526f53), SkBits2Float(0x41e6ccd4));
+path.cubicTo(SkBits2Float(0x427b35d6), SkBits2Float(0x41242e26), SkBits2Float(0x4279b842), SkBits2Float(0xc1453c2f), SkBits2Float(0x424e8393), SkBits2Float(0xc1f48e84));
+path.cubicTo(SkBits2Float(0x42234ee4), SkBits2Float(0xc2433f78), SkBits2Float(0x41a99a66), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427c069f), SkBits2Float(0x42581e31));
+path.cubicTo(SkBits2Float(0x4229355f), SkBits2Float(0x429c5901), SkBits2Float(0x4119ef9b), SkBits2Float(0x42b0b9f6), SkBits2Float(0xc1a91754), SkBits2Float(0x42a086fc));
+path.cubicTo(SkBits2Float(0xc24f933a), SkBits2Float(0x42905402), SkBits2Float(0xc296a2af), SkBits2Float(0x423cccf9), SkBits2Float(0xc2a2e3f0), SkBits2Float(0x417fd713));
+path.cubicTo(SkBits2Float(0xc2af2532), SkBits2Float(0xc17385be), SkBits2Float(0xc296a6d5), SkBits2Float(0xc23cbfbd), SkBits2Float(0xc247a7c9), SkBits2Float(0xc284a101));
+path.lineTo(SkBits2Float(0xc210544b), SkBits2Float(0xc23fc0ab));
+path.cubicTo(SkBits2Float(0xc259cf4c), SkBits2Float(0xc20871e9), SkBits2Float(0xc27d38da), SkBits2Float(0xc1300a36), SkBits2Float(0xc26b810f), SkBits2Float(0x4138f1f1));
+path.cubicTo(SkBits2Float(0xc259c944), SkBits2Float(0x42087b85), SkBits2Float(0xc2160de3), SkBits2Float(0x4250aad1), SkBits2Float(0xc174780b), SkBits2Float(0x42681670));
+path.cubicTo(SkBits2Float(0x40de8efd), SkBits2Float(0x427f820e), SkBits2Float(0x41f4a392), SkBits2Float(0x42620b79), SkBits2Float(0x42362ffc), SkBits2Float(0x421c3ad2));
+path.lineTo(SkBits2Float(0x427c069f), SkBits2Float(0x42581e31));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp255(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41eeb164), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42658277), SkBits2Float(0xc285f892), SkBits2Float(0x42904565), SkBits2Float(0xc22437b5));
+path.cubicTo(SkBits2Float(0x42adc98d), SkBits2Float(0xc171f916), SkBits2Float(0x42ad3226), SkBits2Float(0x4185deb6), SkBits2Float(0x428eb8d5), SkBits2Float(0x42298bae));
+path.lineTo(SkBits2Float(0x424e5857), SkBits2Float(0x41f5204e));
+path.cubicTo(SkBits2Float(0x427a675d), SkBits2Float(0x41418c03), SkBits2Float(0x427b4242), SkBits2Float(0xc12eeb9a), SkBits2Float(0x425095b0), SkBits2Float(0xc1ed6c50));
+path.cubicTo(SkBits2Float(0x4225e91e), SkBits2Float(0xc241b169), SkBits2Float(0x41ac8c92), SkBits2Float(0xc2700000), SkBits2Float(0xb69400ae), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x428eb8d5), SkBits2Float(0x42298bad));
+path.cubicTo(SkBits2Float(0x4288c365), SkBits2Float(0x423d9c15), SkBits2Float(0x4281c36f), SkBits2Float(0x42505c7e), SkBits2Float(0x4273ad50), SkBits2Float(0x42617d52));
+path.lineTo(SkBits2Float(0x423026ec), SkBits2Float(0x42230126));
+path.cubicTo(SkBits2Float(0x423b9c18), SkBits2Float(0x42169f65), SkBits2Float(0x4245bae4), SkBits2Float(0x42091136), SkBits2Float(0x424e5858), SkBits2Float(0x41f5204d));
+path.lineTo(SkBits2Float(0x428eb8d5), SkBits2Float(0x42298bad));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp256(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb69400ae), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41eeb164), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42658277), SkBits2Float(0xc285f892), SkBits2Float(0x42904565), SkBits2Float(0xc22437b5));
+path.cubicTo(SkBits2Float(0x42adc98d), SkBits2Float(0xc171f917), SkBits2Float(0x42ad3226), SkBits2Float(0x4185deb4), SkBits2Float(0x428eb8d5), SkBits2Float(0x42298bad));
+path.lineTo(SkBits2Float(0x428eb8d5), SkBits2Float(0x42298bae));
+path.cubicTo(SkBits2Float(0x4288c365), SkBits2Float(0x423d9c16), SkBits2Float(0x4281c36f), SkBits2Float(0x42505c7e), SkBits2Float(0x4273ad50), SkBits2Float(0x42617d52));
+path.lineTo(SkBits2Float(0x423026ec), SkBits2Float(0x42230126));
+path.cubicTo(SkBits2Float(0x423b9c18), SkBits2Float(0x42169f65), SkBits2Float(0x4245bae4), SkBits2Float(0x42091136), SkBits2Float(0x424e5858), SkBits2Float(0x41f5204d));
+path.cubicTo(SkBits2Float(0x427a675e), SkBits2Float(0x41418c02), SkBits2Float(0x427b4242), SkBits2Float(0xc12eeb9b), SkBits2Float(0x425095b0), SkBits2Float(0xc1ed6c50));
+path.cubicTo(SkBits2Float(0x4225e91e), SkBits2Float(0xc241b169), SkBits2Float(0x41ac8c92), SkBits2Float(0xc2700000), SkBits2Float(0xb69400ae), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4273ad4f), SkBits2Float(0x42617d52));
+path.cubicTo(SkBits2Float(0x421bc173), SkBits2Float(0x42a0404f), SkBits2Float(0x40a50405), SkBits2Float(0x42b1dfaa), SkBits2Float(0xc1cd0022), SkBits2Float(0x429de3fd));
+path.cubicTo(SkBits2Float(0xc261a0a2), SkBits2Float(0x4289e850), SkBits2Float(0xc29d25ee), SkBits2Float(0x4227ed4e), SkBits2Float(0xc2a4d3d8), SkBits2Float(0x411d8f80));
+path.cubicTo(SkBits2Float(0xc2ac81c3), SkBits2Float(0xc1b24b1c), SkBits2Float(0xc28e216c), SkBits2Float(0xc256e38c), SkBits2Float(0xc22e0453), SkBits2Float(0xc28d5ec3));
+path.lineTo(SkBits2Float(0xc1fb9743), SkBits2Float(0xc24c63fd));
+path.cubicTo(SkBits2Float(0xc24d7d6b), SkBits2Float(0xc21b575f), SkBits2Float(0xc279684a), SkBits2Float(0xc180e302), SkBits2Float(0xc26e4dff), SkBits2Float(0x40e3cc4e));
+path.cubicTo(SkBits2Float(0xc26333b4), SkBits2Float(0x41f2c929), SkBits2Float(0xc2231aa4), SkBits2Float(0x42476256), SkBits2Float(0xc1943166), SkBits2Float(0x4264467e));
+path.cubicTo(SkBits2Float(0x406e93d1), SkBits2Float(0x42809553), SkBits2Float(0x41e1305a), SkBits2Float(0x4267b03c), SkBits2Float(0x423026ed), SkBits2Float(0x42230127));
+path.lineTo(SkBits2Float(0x4273ad4f), SkBits2Float(0x42617d52));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp257(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f2d268), SkBits2Float(0xc2a5ffff), SkBits2Float(0x426923a2), SkBits2Float(0xc284dd06), SkBits2Float(0x4291aced), SkBits2Float(0xc21f2e53));
+path.cubicTo(SkBits2Float(0x42aec809), SkBits2Float(0xc1528a66), SkBits2Float(0x42ac7c90), SkBits2Float(0x419a60b1), SkBits2Float(0x428bb0fe), SkBits2Float(0x42335ba0));
+path.lineTo(SkBits2Float(0x4249f6a4), SkBits2Float(0x4201a806));
+path.cubicTo(SkBits2Float(0x427960d2), SkBits2Float(0x415f325f), SkBits2Float(0x427cb22e), SkBits2Float(0xc11832b1), SkBits2Float(0x42529d7e), SkBits2Float(0xc1e62422));
+path.cubicTo(SkBits2Float(0x422888ce), SkBits2Float(0xc2401775), SkBits2Float(0x41af88b3), SkBits2Float(0xc2700000), SkBits2Float(0x36d3ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x428bb0ff), SkBits2Float(0x42335ba2));
+path.cubicTo(SkBits2Float(0x4285489d), SkBits2Float(0x42475206), SkBits2Float(0x427ba631), SkBits2Float(0x4259da14), SkBits2Float(0x426ae250), SkBits2Float(0x426aa282));
+path.lineTo(SkBits2Float(0x4229cbb3), SkBits2Float(0x42299d92));
+path.cubicTo(SkBits2Float(0x4235ea43), SkBits2Float(0x421d7bb7), SkBits2Float(0x4240b302), SkBits2Float(0x42101649), SkBits2Float(0x4249f6a5), SkBits2Float(0x4201a807));
+path.lineTo(SkBits2Float(0x428bb0ff), SkBits2Float(0x42335ba2));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp258(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36d3ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f2d268), SkBits2Float(0xc2a5ffff), SkBits2Float(0x426923a2), SkBits2Float(0xc284dd06), SkBits2Float(0x4291aced), SkBits2Float(0xc21f2e53));
+path.cubicTo(SkBits2Float(0x42aec809), SkBits2Float(0xc1528a66), SkBits2Float(0x42ac7c90), SkBits2Float(0x419a60b1), SkBits2Float(0x428bb0ff), SkBits2Float(0x42335ba2));
+path.cubicTo(SkBits2Float(0x4285489d), SkBits2Float(0x42475206), SkBits2Float(0x427ba631), SkBits2Float(0x4259da14), SkBits2Float(0x426ae250), SkBits2Float(0x426aa282));
+path.lineTo(SkBits2Float(0x4229cbb3), SkBits2Float(0x42299d92));
+path.cubicTo(SkBits2Float(0x4235ea43), SkBits2Float(0x421d7bb7), SkBits2Float(0x4240b302), SkBits2Float(0x42101649), SkBits2Float(0x4249f6a4), SkBits2Float(0x4201a806));
+path.cubicTo(SkBits2Float(0x427960d2), SkBits2Float(0x415f325f), SkBits2Float(0x427cb22e), SkBits2Float(0xc11832b1), SkBits2Float(0x42529d7e), SkBits2Float(0xc1e62422));
+path.cubicTo(SkBits2Float(0x422888ce), SkBits2Float(0xc2401775), SkBits2Float(0x41af88b3), SkBits2Float(0xc2700000), SkBits2Float(0x36d3ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x426ae251), SkBits2Float(0x426aa281));
+path.cubicTo(SkBits2Float(0x420dcd2c), SkBits2Float(0x42a3e87c), SkBits2Float(0x3f1c0197), SkBits2Float(0x42b294d6), SkBits2Float(0xc1f0a2ab), SkBits2Float(0x429ab731));
+path.cubicTo(SkBits2Float(0xc27312b1), SkBits2Float(0x4282d98e), SkBits2Float(0xc2a300b1), SkBits2Float(0x4211eaa7), SkBits2Float(0xc2a5d865), SkBits2Float(0x40654aaf));
+path.cubicTo(SkBits2Float(0xc2a8b018), SkBits2Float(0xc1ea82a2), SkBits2Float(0xc2845e8a), SkBits2Float(0xc26fc272), SkBits2Float(0xc2128ebb), SkBits2Float(0xc294f34d));
+path.lineTo(SkBits2Float(0xc1d3e3ef), SkBits2Float(0xc2575999));
+path.cubicTo(SkBits2Float(0xc23f6093), SkBits2Float(0xc22d51f6), SkBits2Float(0xc273e2d0), SkBits2Float(0xc1a9868a), SkBits2Float(0xc26fc6b5), SkBits2Float(0x4025c090));
+path.cubicTo(SkBits2Float(0xc26baa9a), SkBits2Float(0x41d2f6ae), SkBits2Float(0xc22fb71e), SkBits2Float(0x423d2e2a), SkBits2Float(0xc1adf403), SkBits2Float(0x425faf61));
+path.cubicTo(SkBits2Float(0x3ee18e9e), SkBits2Float(0x4281184d), SkBits2Float(0x41cd03a3), SkBits2Float(0x426cf9bf), SkBits2Float(0x4229cbb7), SkBits2Float(0x42299d90));
+path.lineTo(SkBits2Float(0x426ae251), SkBits2Float(0x426aa281));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp259(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f70d18), SkBits2Float(0xc2a60000), SkBits2Float(0x426cd682), SkBits2Float(0xc283b5d2), SkBits2Float(0x429310ae), SkBits2Float(0xc219fc22));
+path.cubicTo(SkBits2Float(0x42afb61c), SkBits2Float(0xc132327f), SkBits2Float(0x42ab9c4e), SkBits2Float(0x41af4ab2), SkBits2Float(0x42886baa), SkBits2Float(0x423d2918));
+path.lineTo(SkBits2Float(0x42453c0d), SkBits2Float(0x4208be17));
+path.cubicTo(SkBits2Float(0x42781c98), SkBits2Float(0x417d6f0f), SkBits2Float(0x427e0a5e), SkBits2Float(0xc100d142), SkBits2Float(0x42549fd3), SkBits2Float(0xc1dea0fa));
+path.cubicTo(SkBits2Float(0x422b3547), SkBits2Float(0xc23e6ca9), SkBits2Float(0x41b29756), SkBits2Float(0xc26fffff), SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42886bab), SkBits2Float(0x423d2917));
+path.cubicTo(SkBits2Float(0x42818ce6), SkBits2Float(0x4250fab6), SkBits2Float(0x42733ded), SkBits2Float(0x42633df9), SkBits2Float(0x42618b96), SkBits2Float(0x4273a01b));
+path.lineTo(SkBits2Float(0x42230b75), SkBits2Float(0x42301d61));
+path.cubicTo(SkBits2Float(0x422fd668), SkBits2Float(0x4224457a), SkBits2Float(0x423b4d41), SkBits2Float(0x421711c6), SkBits2Float(0x42453c0e), SkBits2Float(0x4208be17));
+path.lineTo(SkBits2Float(0x42886bab), SkBits2Float(0x423d2917));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp260(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f70d18), SkBits2Float(0xc2a60000), SkBits2Float(0x426cd682), SkBits2Float(0xc283b5d2), SkBits2Float(0x429310ae), SkBits2Float(0xc219fc22));
+path.cubicTo(SkBits2Float(0x42afb61c), SkBits2Float(0xc132327f), SkBits2Float(0x42ab9c4e), SkBits2Float(0x41af4ab2), SkBits2Float(0x42886bab), SkBits2Float(0x423d2917));
+path.cubicTo(SkBits2Float(0x42818ce6), SkBits2Float(0x4250fab6), SkBits2Float(0x42733ded), SkBits2Float(0x42633df9), SkBits2Float(0x42618b96), SkBits2Float(0x4273a01b));
+path.lineTo(SkBits2Float(0x42230b75), SkBits2Float(0x42301d61));
+path.cubicTo(SkBits2Float(0x422fd668), SkBits2Float(0x4224457a), SkBits2Float(0x423b4d41), SkBits2Float(0x421711c6), SkBits2Float(0x42453c0d), SkBits2Float(0x4208be17));
+path.cubicTo(SkBits2Float(0x42781c98), SkBits2Float(0x417d6f0f), SkBits2Float(0x427e0a5e), SkBits2Float(0xc100d142), SkBits2Float(0x42549fd3), SkBits2Float(0xc1dea0fa));
+path.cubicTo(SkBits2Float(0x422b3547), SkBits2Float(0xc23e6ca9), SkBits2Float(0x41b29756), SkBits2Float(0xc26fffff), SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42618b95), SkBits2Float(0x4273a01c));
+path.cubicTo(SkBits2Float(0x41fe659e), SkBits2Float(0x42a75638), SkBits2Float(0xc081f8cf), SkBits2Float(0x42b2d4b3), SkBits2Float(0xc20a1eaa), SkBits2Float(0x4296f3e7));
+path.cubicTo(SkBits2Float(0xc281ff1e), SkBits2Float(0x42762634), SkBits2Float(0xc2a8320c), SkBits2Float(0x41f52b39), SkBits2Float(0xc2a5e71e), SkBits2Float(0xc035be80));
+path.cubicTo(SkBits2Float(0xc2a39c30), SkBits2Float(0xc2114d6a), SkBits2Float(0xc2728d06), SkBits2Float(0xc283ad37), SkBits2Float(0xc1ea4cbe), SkBits2Float(0xc29b5279));
+path.lineTo(SkBits2Float(0xc1a95f99), SkBits2Float(0xc2608fe9));
+path.cubicTo(SkBits2Float(0xc22f5688), SkBits2Float(0xc23e6034), SkBits2Float(0xc26c8b72), SkBits2Float(0xc1d2135a), SkBits2Float(0xc26fdc03), SkBits2Float(0xc003615b));
+path.cubicTo(SkBits2Float(0xc2732c96), SkBits2Float(0x41b13b02), SkBits2Float(0xc23bf25c), SkBits2Float(0x4231f06e), SkBits2Float(0xc1c7b0f0), SkBits2Float(0x425a3eb1));
+path.cubicTo(SkBits2Float(0xc03be91a), SkBits2Float(0x4281467b), SkBits2Float(0x41b7e6c5), SkBits2Float(0x4271eec4), SkBits2Float(0x42230b77), SkBits2Float(0x42301d61));
+path.lineTo(SkBits2Float(0x42618b95), SkBits2Float(0x4273a01c));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp261(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f9750b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x426eeefa), SkBits2Float(0xc2830bb8), SkBits2Float(0x4293d569), SkBits2Float(0xc2170343));
+path.cubicTo(SkBits2Float(0x42b03354), SkBits2Float(0xc11fbc55), SkBits2Float(0x42ab0b89), SkBits2Float(0x41bb247a), SkBits2Float(0x42867c8e), SkBits2Float(0x42429f12));
+path.lineTo(SkBits2Float(0x42427039), SkBits2Float(0x420cb0ae));
+path.cubicTo(SkBits2Float(0x42774b4a), SkBits2Float(0x418748a6), SkBits2Float(0x427ebf70), SkBits2Float(0xc0e6f16a), SkBits2Float(0x4255bc46), SkBits2Float(0xc1da54e8));
+path.cubicTo(SkBits2Float(0x422cb91b), SkBits2Float(0xc23d76ba), SkBits2Float(0x41b454a4), SkBits2Float(0xc2700000), SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42867c8e), SkBits2Float(0x42429f13));
+path.cubicTo(SkBits2Float(0x427eb473), SkBits2Float(0x4256572c), SkBits2Float(0x426e4fbb), SkBits2Float(0x42686e49), SkBits2Float(0x425c16a2), SkBits2Float(0x427890ea));
+path.lineTo(SkBits2Float(0x421f199c), SkBits2Float(0x4233afb3));
+path.cubicTo(SkBits2Float(0x422c45f9), SkBits2Float(0x422805b5), SkBits2Float(0x42381fbf), SkBits2Float(0x421af1ea), SkBits2Float(0x4242703a), SkBits2Float(0x420cb0af));
+path.lineTo(SkBits2Float(0x42867c8e), SkBits2Float(0x42429f13));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp262(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41f9750b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x426eeefa), SkBits2Float(0xc2830bb8), SkBits2Float(0x4293d569), SkBits2Float(0xc2170343));
+path.cubicTo(SkBits2Float(0x42b03354), SkBits2Float(0xc11fbc55), SkBits2Float(0x42ab0b89), SkBits2Float(0x41bb247a), SkBits2Float(0x42867c8e), SkBits2Float(0x42429f13));
+path.cubicTo(SkBits2Float(0x427eb473), SkBits2Float(0x4256572c), SkBits2Float(0x426e4fbb), SkBits2Float(0x42686e49), SkBits2Float(0x425c16a2), SkBits2Float(0x427890ea));
+path.lineTo(SkBits2Float(0x421f199c), SkBits2Float(0x4233afb3));
+path.cubicTo(SkBits2Float(0x422c45f9), SkBits2Float(0x422805b5), SkBits2Float(0x42381fbf), SkBits2Float(0x421af1ea), SkBits2Float(0x42427039), SkBits2Float(0x420cb0ae));
+path.cubicTo(SkBits2Float(0x42774b4a), SkBits2Float(0x418748a6), SkBits2Float(0x427ebf70), SkBits2Float(0xc0e6f16a), SkBits2Float(0x4255bc46), SkBits2Float(0xc1da54e8));
+path.cubicTo(SkBits2Float(0x422cb91b), SkBits2Float(0xc23d76ba), SkBits2Float(0x41b454a4), SkBits2Float(0xc2700000), SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x425c16a1), SkBits2Float(0x427890eb));
+path.cubicTo(SkBits2Float(0x41ed85e5), SkBits2Float(0x42a9245e), SkBits2Float(0xc0d70d9a), SkBits2Float(0x42b2c211), SkBits2Float(0xc2140612), SkBits2Float(0x42949665));
+path.cubicTo(SkBits2Float(0xc2869539), SkBits2Float(0x426cd56f), SkBits2Float(0xc2aac701), SkBits2Float(0x41d9ff9c), SkBits2Float(0xc2a57e3b), SkBits2Float(0xc0cf6824));
+path.cubicTo(SkBits2Float(0xc2a03574), SkBits2Float(0xc220d9d7), SkBits2Float(0xc26501e3), SkBits2Float(0xc289ed78), SkBits2Float(0xc1c7e516), SkBits2Float(0xc29e4c97));
+path.lineTo(SkBits2Float(0xc190809e), SkBits2Float(0xc264ddc3));
+path.cubicTo(SkBits2Float(0xc2258c2b), SkBits2Float(0xc24769d4), SkBits2Float(0xc267a08f), SkBits2Float(0xc1e88e39), SkBits2Float(0xc26f4461), SkBits2Float(0xc095eec9));
+path.cubicTo(SkBits2Float(0xc276e835), SkBits2Float(0x419d96da), SkBits2Float(0xc24293e3), SkBits2Float(0x422b3483), SkBits2Float(0xc1d60298), SkBits2Float(0x4256d347));
+path.cubicTo(SkBits2Float(0xc09b75b0), SkBits2Float(0x42813905), SkBits2Float(0x41abb417), SkBits2Float(0x42748af0), SkBits2Float(0x421f199e), SkBits2Float(0x4233afb2));
+path.lineTo(SkBits2Float(0x425c16a1), SkBits2Float(0x427890eb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp263(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41fc38da), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4271556b), SkBits2Float(0xc2824656), SkBits2Float(0x4294b266), SkBits2Float(0xc213956f));
+path.cubicTo(SkBits2Float(0x42b0ba15), SkBits2Float(0xc10a78c9), SkBits2Float(0x42aa55de), SkBits2Float(0x41c8b65d), SkBits2Float(0x42843343), SkBits2Float(0x4248ca15));
+path.lineTo(SkBits2Float(0x423f2206), SkBits2Float(0x42112621));
+path.cubicTo(SkBits2Float(0x427644a6), SkBits2Float(0x419117e2), SkBits2Float(0x427f8241), SkBits2Float(0xc0c83353), SkBits2Float(0x4256fbc4), SkBits2Float(0xc1d55fc8));
+path.cubicTo(SkBits2Float(0x422e7546), SkBits2Float(0xc23c595d), SkBits2Float(0x41b6544b), SkBits2Float(0xc2700002), SkBits2Float(0x357ffa8c), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42843344), SkBits2Float(0x4248ca14));
+path.cubicTo(SkBits2Float(0x4279865a), SkBits2Float(0x425c60b2), SkBits2Float(0x426884b7), SkBits2Float(0x426e4097), SkBits2Float(0x4255b1c1), SkBits2Float(0x427e1584));
+path.lineTo(SkBits2Float(0x421a7a55), SkBits2Float(0x4237acdc));
+path.cubicTo(SkBits2Float(0x422815ec), SkBits2Float(0x422c3b08), SkBits2Float(0x42346121), SkBits2Float(0x421f4f28), SkBits2Float(0x423f2207), SkBits2Float(0x42112621));
+path.lineTo(SkBits2Float(0x42843344), SkBits2Float(0x4248ca14));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp264(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41fc38da), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4271556b), SkBits2Float(0xc2824656), SkBits2Float(0x4294b266), SkBits2Float(0xc213956f));
+path.cubicTo(SkBits2Float(0x42b0ba15), SkBits2Float(0xc10a78c9), SkBits2Float(0x42aa55de), SkBits2Float(0x41c8b65d), SkBits2Float(0x42843344), SkBits2Float(0x4248ca14));
+path.cubicTo(SkBits2Float(0x4279865a), SkBits2Float(0x425c60b2), SkBits2Float(0x426884b7), SkBits2Float(0x426e4097), SkBits2Float(0x4255b1c1), SkBits2Float(0x427e1584));
+path.lineTo(SkBits2Float(0x421a7a55), SkBits2Float(0x4237acdc));
+path.cubicTo(SkBits2Float(0x422815ec), SkBits2Float(0x422c3b08), SkBits2Float(0x42346121), SkBits2Float(0x421f4f28), SkBits2Float(0x423f2206), SkBits2Float(0x42112621));
+path.cubicTo(SkBits2Float(0x427644a6), SkBits2Float(0x419117e2), SkBits2Float(0x427f8241), SkBits2Float(0xc0c83353), SkBits2Float(0x4256fbc4), SkBits2Float(0xc1d55fc8));
+path.cubicTo(SkBits2Float(0x422e7546), SkBits2Float(0xc23c595d), SkBits2Float(0x41b6544b), SkBits2Float(0xc2700002), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4255b1c2), SkBits2Float(0x427e1586));
+path.cubicTo(SkBits2Float(0x41d9eb88), SkBits2Float(0x42ab15b8), SkBits2Float(0xc11c5ee2), SkBits2Float(0x42b27b8c), SkBits2Float(0xc21f2fec), SkBits2Float(0x4291ac82));
+path.cubicTo(SkBits2Float(0xc28ba40f), SkBits2Float(0x4261baf0), SkBits2Float(0xc2ad6782), SkBits2Float(0x41ba4aab), SkBits2Float(0xc2a4a120), SkBits2Float(0xc12a4d95));
+path.cubicTo(SkBits2Float(0xc29bdabd), SkBits2Float(0xc2324c20), SkBits2Float(0xc254adab), SkBits2Float(0xc290ac19), SkBits2Float(0xc19fafc0), SkBits2Float(0xc2a120ca));
+path.lineTo(SkBits2Float(0xc166df50), SkBits2Float(0xc268f4ce));
+path.cubicTo(SkBits2Float(0xc219be54), SkBits2Float(0xc2512a28), SkBits2Float(0xc26154eb), SkBits2Float(0xc200e3bb), SkBits2Float(0xc26e04b2), SkBits2Float(0xc0f6387e));
+path.cubicTo(SkBits2Float(0xc27ab479), SkBits2Float(0x4186ab35), SkBits2Float(0xc249e3ea), SkBits2Float(0x42232db1), SkBits2Float(0xc1e62664), SkBits2Float(0x42529ce0));
+path.cubicTo(SkBits2Float(0xc0e213c9), SkBits2Float(0x42810608), SkBits2Float(0x419d8860), SkBits2Float(0x427759fd), SkBits2Float(0x421a7a58), SkBits2Float(0x4237acda));
+path.lineTo(SkBits2Float(0x4255b1c2), SkBits2Float(0x427e1586));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp265(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41fe7454), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427343e8), SkBits2Float(0xc281a57b), SkBits2Float(0x429560d9), SkBits2Float(0xc210ce12));
+path.cubicTo(SkBits2Float(0x42b11fbd), SkBits2Float(0xc0f2896e), SkBits2Float(0x42a9b750), SkBits2Float(0x41d3a0ba), SkBits2Float(0x42824e39), SkBits2Float(0x424daf12));
+path.lineTo(SkBits2Float(0x423c64bf), SkBits2Float(0x4214afea));
+path.cubicTo(SkBits2Float(0x42755f66), SkBits2Float(0x4198fbec), SkBits2Float(0x42800a9d), SkBits2Float(0xc0af53e2), SkBits2Float(0x4257f7fc), SkBits2Float(0xc1d15b49));
+path.cubicTo(SkBits2Float(0x422fdabc), SkBits2Float(0xc23b70cc), SkBits2Float(0x41b7f168), SkBits2Float(0xc2700002), SkBits2Float(0xb5600574), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42824e38), SkBits2Float(0x424daf15));
+path.cubicTo(SkBits2Float(0x42753e9a), SkBits2Float(0x4261276c), SkBits2Float(0x4263be9a), SkBits2Float(0x4272d73c), SkBits2Float(0x4250704b), SkBits2Float(0x428134df));
+path.lineTo(SkBits2Float(0x4216adb6), SkBits2Float(0x423acdfc));
+path.cubicTo(SkBits2Float(0x4224a276), SkBits2Float(0x422f8c2c), SkBits2Float(0x42314905), SkBits2Float(0x4222c30f), SkBits2Float(0x423c64c0), SkBits2Float(0x4214afec));
+path.lineTo(SkBits2Float(0x42824e38), SkBits2Float(0x424daf15));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp266(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x41fe7454), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427343e8), SkBits2Float(0xc281a57b), SkBits2Float(0x429560d9), SkBits2Float(0xc210ce12));
+path.cubicTo(SkBits2Float(0x42b11fbd), SkBits2Float(0xc0f2896e), SkBits2Float(0x42a9b750), SkBits2Float(0x41d3a0ba), SkBits2Float(0x42824e39), SkBits2Float(0x424daf12));
+path.lineTo(SkBits2Float(0x42824e38), SkBits2Float(0x424daf15));
+path.cubicTo(SkBits2Float(0x42753e9a), SkBits2Float(0x4261276c), SkBits2Float(0x4263be9a), SkBits2Float(0x4272d73c), SkBits2Float(0x4250704b), SkBits2Float(0x428134df));
+path.lineTo(SkBits2Float(0x4216adb6), SkBits2Float(0x423acdfc));
+path.cubicTo(SkBits2Float(0x4224a276), SkBits2Float(0x422f8c2c), SkBits2Float(0x42314905), SkBits2Float(0x4222c30f), SkBits2Float(0x423c64c0), SkBits2Float(0x4214afec));
+path.lineTo(SkBits2Float(0x423c64bf), SkBits2Float(0x4214afea));
+path.cubicTo(SkBits2Float(0x42755f66), SkBits2Float(0x4198fbec), SkBits2Float(0x42800a9d), SkBits2Float(0xc0af53e2), SkBits2Float(0x4257f7fc), SkBits2Float(0xc1d15b49));
+path.cubicTo(SkBits2Float(0x422fdabc), SkBits2Float(0xc23b70cc), SkBits2Float(0x41b7f168), SkBits2Float(0xc2700002), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4250704d), SkBits2Float(0x428134e0));
+path.cubicTo(SkBits2Float(0x41c9effb), SkBits2Float(0x42ac8cba), SkBits2Float(0xc143bd6b), SkBits2Float(0x42b21c58), SkBits2Float(0xc2280561), SkBits2Float(0x428f2c0c));
+path.cubicTo(SkBits2Float(0xc28f8db2), SkBits2Float(0x42587782), SkBits2Float(0xc2af41ba), SkBits2Float(0x41a05b8a), SkBits2Float(0xc2a3a0d2), SkBits2Float(0xc15fb01a));
+path.cubicTo(SkBits2Float(0xc297ffea), SkBits2Float(0xc24005d3), SkBits2Float(0xc246ef26), SkBits2Float(0xc295c2d5), SkBits2Float(0xc17d9b57), SkBits2Float(0xc2a2f1e8));
+path.lineTo(SkBits2Float(0xc1375488), SkBits2Float(0xc26b9543));
+path.cubicTo(SkBits2Float(0xc20fcecd), SkBits2Float(0xc25885a3), SkBits2Float(0xc25bc22e), SkBits2Float(0xc20acfc5), SkBits2Float(0xc26c9222), SkBits2Float(0xc121b3b7));
+path.cubicTo(SkBits2Float(0xc27d6216), SkBits2Float(0x4167d7a5), SkBits2Float(0xc24f8c13), SkBits2Float(0x421c7b68), SkBits2Float(0xc1f2ebf9), SkBits2Float(0x424efee8));
+path.cubicTo(SkBits2Float(0xc10d7f99), SkBits2Float(0x4280c134), SkBits2Float(0x4191fa9e), SkBits2Float(0x4279782f), SkBits2Float(0x4216adb8), SkBits2Float(0x423acdfc));
+path.lineTo(SkBits2Float(0x4250704d), SkBits2Float(0x428134e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp267(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42003b3a), SkBits2Float(0xc2a60000), SkBits2Float(0x4274ff8d), SkBits2Float(0xc28113a0), SkBits2Float(0x4295fac2), SkBits2Float(0xc20e4c24));
+path.cubicTo(SkBits2Float(0x42b175be), SkBits2Float(0xc0d38840), SkBits2Float(0x42a91fa3), SkBits2Float(0x41dd6a3d), SkBits2Float(0x42809081), SkBits2Float(0x4252054f));
+path.lineTo(SkBits2Float(0x4239e059), SkBits2Float(0x4217d27c));
+path.cubicTo(SkBits2Float(0x4274841b), SkBits2Float(0x41a00f1c), SkBits2Float(0x428048c8), SkBits2Float(0xc098ea38), SkBits2Float(0x4258d681), SkBits2Float(0xc1cdbb32));
+path.cubicTo(SkBits2Float(0x42311b71), SkBits2Float(0xc23a9deb), SkBits2Float(0x41b96511), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42809082), SkBits2Float(0x4252054e));
+path.cubicTo(SkBits2Float(0x4271521d), SkBits2Float(0x42655feb), SkBits2Float(0x425f60c7), SkBits2Float(0x4276e1ca), SkBits2Float(0x424ba43f), SkBits2Float(0x42831ae1));
+path.lineTo(SkBits2Float(0x421335f7), SkBits2Float(0x423d8ca7));
+path.cubicTo(SkBits2Float(0x42217a65), SkBits2Float(0x4232780c), SkBits2Float(0x422e72e3), SkBits2Float(0x4225d023), SkBits2Float(0x4239e05a), SkBits2Float(0x4217d27c));
+path.lineTo(SkBits2Float(0x42809082), SkBits2Float(0x4252054e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp268(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42003b3a), SkBits2Float(0xc2a60000), SkBits2Float(0x4274ff8d), SkBits2Float(0xc28113a0), SkBits2Float(0x4295fac2), SkBits2Float(0xc20e4c24));
+path.cubicTo(SkBits2Float(0x42b175be), SkBits2Float(0xc0d38840), SkBits2Float(0x42a91fa3), SkBits2Float(0x41dd6a3d), SkBits2Float(0x42809082), SkBits2Float(0x4252054e));
+path.cubicTo(SkBits2Float(0x4271521d), SkBits2Float(0x42655feb), SkBits2Float(0x425f60c7), SkBits2Float(0x4276e1ca), SkBits2Float(0x424ba43f), SkBits2Float(0x42831ae1));
+path.lineTo(SkBits2Float(0x421335f7), SkBits2Float(0x423d8ca7));
+path.cubicTo(SkBits2Float(0x42217a65), SkBits2Float(0x4232780c), SkBits2Float(0x422e72e3), SkBits2Float(0x4225d023), SkBits2Float(0x4239e059), SkBits2Float(0x4217d27c));
+path.cubicTo(SkBits2Float(0x4274841b), SkBits2Float(0x41a00f1c), SkBits2Float(0x428048c8), SkBits2Float(0xc098ea38), SkBits2Float(0x4258d681), SkBits2Float(0xc1cdbb32));
+path.cubicTo(SkBits2Float(0x42311b71), SkBits2Float(0xc23a9deb), SkBits2Float(0x41b96511), SkBits2Float(0xc2700000), SkBits2Float(0x3697ff52), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x424ba440), SkBits2Float(0x42831ae2));
+path.cubicTo(SkBits2Float(0x41bb72ba), SkBits2Float(0x42adc9b8), SkBits2Float(0xc16714ca), SkBits2Float(0x42b1a998), SkBits2Float(0xc22fd30d), SkBits2Float(0x428ccf5c));
+path.cubicTo(SkBits2Float(0xc292f074), SkBits2Float(0x424fea41), SkBits2Float(0xc2b0b757), SkBits2Float(0x4188cdbd), SkBits2Float(0xc2a27f7d), SkBits2Float(0xc187abb1));
+path.cubicTo(SkBits2Float(0xc29447a3), SkBits2Float(0xc24c1290), SkBits2Float(0xc23a2b5e), SkBits2Float(0xc29a0e93), SkBits2Float(0xc141f42b), SkBits2Float(0xc2a43853));
+path.lineTo(SkBits2Float(0xc10c3538), SkBits2Float(0xc26d6d31));
+path.cubicTo(SkBits2Float(0xc2069491), SkBits2Float(0xc25ebb9d), SkBits2Float(0xc2566164), SkBits2Float(0xc21385b2), SkBits2Float(0xc26aefd1), SkBits2Float(0xc1442672));
+path.cubicTo(SkBits2Float(0xc27f7e3e), SkBits2Float(0x4145c9dc), SkBits2Float(0xc2547130), SkBits2Float(0x42164ccc), SkBits2Float(0xc1fe3427), SkBits2Float(0x424b94a6));
+path.cubicTo(SkBits2Float(0xc1270bd9), SkBits2Float(0x42806e40), SkBits2Float(0x41878138), SkBits2Float(0x427b4278), SkBits2Float(0x421335f8), SkBits2Float(0x423d8ca8));
+path.lineTo(SkBits2Float(0x424ba440), SkBits2Float(0x42831ae2));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp269(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42011047), SkBits2Float(0xc2a60000), SkBits2Float(0x42766e56), SkBits2Float(0xc28099ef), SkBits2Float(0x42967824), SkBits2Float(0xc20c36c8));
+path.cubicTo(SkBits2Float(0x42b1b91c), SkBits2Float(0xc0b9cd9b), SkBits2Float(0x42a89b7a), SkBits2Float(0x41e5804f), SkBits2Float(0x427e310b), SkBits2Float(0x42559106));
+path.lineTo(SkBits2Float(0x4237c0bf), SkBits2Float(0x421a62ac));
+path.cubicTo(SkBits2Float(0x4273c506), SkBits2Float(0x41a5e791), SkBits2Float(0x4280797a), SkBits2Float(0xc08650bf), SkBits2Float(0x42598bc5), SkBits2Float(0xc1cab811));
+path.cubicTo(SkBits2Float(0x42322494), SkBits2Float(0xc239edfa), SkBits2Float(0x41ba9913), SkBits2Float(0xc2700002), SkBits2Float(0xb7060057), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427e3109), SkBits2Float(0x42559108));
+path.cubicTo(SkBits2Float(0x426e0477), SkBits2Float(0x4268d13b), SkBits2Float(0x425bb575), SkBits2Float(0x427a2b1d), SkBits2Float(0x42479e2a), SkBits2Float(0x4284a4a0));
+path.lineTo(SkBits2Float(0x42104d52), SkBits2Float(0x423fc5ea));
+path.cubicTo(SkBits2Float(0x421ed35e), SkBits2Float(0x4234d83a), SkBits2Float(0x422c0f91), SkBits2Float(0x42284d3a), SkBits2Float(0x4237c0bf), SkBits2Float(0x421a62ad));
+path.lineTo(SkBits2Float(0x427e3109), SkBits2Float(0x42559108));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp270(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb7060057), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42011047), SkBits2Float(0xc2a60000), SkBits2Float(0x42766e56), SkBits2Float(0xc28099ef), SkBits2Float(0x42967824), SkBits2Float(0xc20c36c8));
+path.cubicTo(SkBits2Float(0x42b1b91c), SkBits2Float(0xc0b9cd9b), SkBits2Float(0x42a89b7a), SkBits2Float(0x41e5804f), SkBits2Float(0x427e310b), SkBits2Float(0x42559106));
+path.lineTo(SkBits2Float(0x4237c0bf), SkBits2Float(0x421a62ad));
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42479e29), SkBits2Float(0x4284a4a0));
+path.cubicTo(SkBits2Float(0x41af5d68), SkBits2Float(0x42aec1b4), SkBits2Float(0xc1822698), SkBits2Float(0x42b135a9), SkBits2Float(0xc2362f3e), SkBits2Float(0x428ac623));
+path.cubicTo(SkBits2Float(0xc295a599), SkBits2Float(0x4248ad36), SkBits2Float(0xc2b1c6ab), SkBits2Float(0x416a48a9), SkBits2Float(0xc2a165f3), SkBits2Float(0xc19b42cf));
+path.cubicTo(SkBits2Float(0xc291053c), SkBits2Float(0xc255d4f6), SkBits2Float(0xc22f520a), SkBits2Float(0xc29d68ba), SkBits2Float(0xc110422a), SkBits2Float(0xc2a50486));
+path.lineTo(SkBits2Float(0xc0d09136), SkBits2Float(0xc26e946c));
+path.cubicTo(SkBits2Float(0xc1fd79b9), SkBits2Float(0xc2639452), SkBits2Float(0xc251ab0b), SkBits2Float(0xc21a93c1), SkBits2Float(0xc26958c8), SkBits2Float(0xc1607927));
+path.cubicTo(SkBits2Float(0xc2808342), SkBits2Float(0x41295cae), SkBits2Float(0xc2585b55), SkBits2Float(0x42111142), SkBits2Float(0xc203b318), SkBits2Float(0x4248a313));
+path.cubicTo(SkBits2Float(0xc13c2b63), SkBits2Float(0x42801a73), SkBits2Float(0x417d8a30), SkBits2Float(0x427ca903), SkBits2Float(0x42104d56), SkBits2Float(0x423fc5e8));
+path.lineTo(SkBits2Float(0x42479e29), SkBits2Float(0x4284a4a0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp271(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4201b43a), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4277880a), SkBits2Float(0xc2803bc7), SkBits2Float(0x4296d747), SkBits2Float(0xc20a9b85));
+path.cubicTo(SkBits2Float(0x42b1ea89), SkBits2Float(0xc0a5fbe3), SkBits2Float(0x42a831cc), SkBits2Float(0x41ebb52f), SkBits2Float(0x427be65b), SkBits2Float(0x425843c9));
+path.lineTo(SkBits2Float(0x423618a6), SkBits2Float(0x421c5604));
+path.cubicTo(SkBits2Float(0x42732c40), SkBits2Float(0x41aa6424), SkBits2Float(0x42809d37), SkBits2Float(0xc06ffa1c), SkBits2Float(0x425a1555), SkBits2Float(0xc1c8657d));
+path.cubicTo(SkBits2Float(0x4232f03c), SkBits2Float(0xc23965db), SkBits2Float(0x41bb8620), SkBits2Float(0xc2700002), SkBits2Float(0xb5600574), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x427be65e), SkBits2Float(0x425843c9));
+path.cubicTo(SkBits2Float(0x426b71bd), SkBits2Float(0x426b6e8c), SkBits2Float(0x4258dad9), SkBits2Float(0x427ca87a), SkBits2Float(0x42447e14), SkBits2Float(0x4285cdfb));
+path.lineTo(SkBits2Float(0x420e0af4), SkBits2Float(0x424173d3));
+path.cubicTo(SkBits2Float(0x421cc338), SkBits2Float(0x4236a4f9), SkBits2Float(0x422a3361), SkBits2Float(0x422a3113), SkBits2Float(0x423618a6), SkBits2Float(0x421c5605));
+path.lineTo(SkBits2Float(0x427be65e), SkBits2Float(0x425843c9));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp272(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4201b43a), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4277880a), SkBits2Float(0xc2803bc7), SkBits2Float(0x4296d747), SkBits2Float(0xc20a9b85));
+path.cubicTo(SkBits2Float(0x42b1ea89), SkBits2Float(0xc0a5fbe3), SkBits2Float(0x42a831cc), SkBits2Float(0x41ebb52f), SkBits2Float(0x427be65b), SkBits2Float(0x425843c9));
+path.lineTo(SkBits2Float(0x427be65e), SkBits2Float(0x425843c9));
+path.cubicTo(SkBits2Float(0x426b71bd), SkBits2Float(0x426b6e8c), SkBits2Float(0x4258dad9), SkBits2Float(0x427ca87a), SkBits2Float(0x42447e14), SkBits2Float(0x4285cdfb));
+path.lineTo(SkBits2Float(0x420e0af4), SkBits2Float(0x424173d3));
+path.cubicTo(SkBits2Float(0x421cc338), SkBits2Float(0x4236a4f9), SkBits2Float(0x422a3361), SkBits2Float(0x422a3113), SkBits2Float(0x423618a6), SkBits2Float(0x421c5605));
+path.lineTo(SkBits2Float(0x423618a6), SkBits2Float(0x421c5604));
+path.cubicTo(SkBits2Float(0x42732c40), SkBits2Float(0x41aa6424), SkBits2Float(0x42809d37), SkBits2Float(0xc06ffa1c), SkBits2Float(0x425a1555), SkBits2Float(0xc1c8657d));
+path.cubicTo(SkBits2Float(0x4232f03c), SkBits2Float(0xc23965db), SkBits2Float(0x41bb8620), SkBits2Float(0xc2700002), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42447e16), SkBits2Float(0x4285cdfb));
+path.cubicTo(SkBits2Float(0x41a605d7), SkBits2Float(0x42af776a), SkBits2Float(0xc18d5e26), SkBits2Float(0x42b0cfa2), SkBits2Float(0xc23b02ad), SkBits2Float(0x428928e1));
+path.cubicTo(SkBits2Float(0xc297ab24), SkBits2Float(0x42430442), SkBits2Float(0xc2b27fa9), SkBits2Float(0x414bdf0d), SkBits2Float(0xc2a073c8), SkBits2Float(0xc1aa3a13));
+path.cubicTo(SkBits2Float(0xc28e67e7), SkBits2Float(0xc25d31d4), SkBits2Float(0xc226d0a4), SkBits2Float(0xc29fdb7e), SkBits2Float(0xc0d3d11a), SkBits2Float(0xc2a578a5));
+path.lineTo(SkBits2Float(0xc0991eb2), SkBits2Float(0xc26f3c4f));
+path.cubicTo(SkBits2Float(0xc1f12d9c), SkBits2Float(0xc2671e82), SkBits2Float(0xc24de350), SkBits2Float(0xc21fe656), SkBits2Float(0xc267faa7), SkBits2Float(0xc1761c74));
+path.cubicTo(SkBits2Float(0xc28108ff), SkBits2Float(0x4113607a), SkBits2Float(0xc25b4798), SkBits2Float(0x420cf9d1), SkBits2Float(0xc207302c), SkBits2Float(0x42464d9a));
+path.cubicTo(SkBits2Float(0xc14c6303), SkBits2Float(0x427fa162), SkBits2Float(0x4170087f), SkBits2Float(0x427dafb7), SkBits2Float(0x420e0af6), SkBits2Float(0x424173d2));
+path.lineTo(SkBits2Float(0x42447e16), SkBits2Float(0x4285cdfb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp273(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42023f77), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427876e4), SkBits2Float(0xc27fd6f4), SkBits2Float(0x42972728), SkBits2Float(0xc2093dbb));
+path.cubicTo(SkBits2Float(0x42b212de), SkBits2Float(0xc0952410), SkBits2Float(0x42a7d55b), SkBits2Float(0x41f0f791), SkBits2Float(0x4279eebf), SkBits2Float(0x425a890b));
+path.lineTo(SkBits2Float(0x4234ac95), SkBits2Float(0x421dfa35));
+path.cubicTo(SkBits2Float(0x4272a697), SkBits2Float(0x41ae3171), SkBits2Float(0x4280ba5e), SkBits2Float(0xc057a00f), SkBits2Float(0x425a88d0), SkBits2Float(0xc1c66bc2));
+path.cubicTo(SkBits2Float(0x42339ce5), SkBits2Float(0xc238f1c1), SkBits2Float(0x41bc4f6b), SkBits2Float(0xc2700002), SkBits2Float(0xb630015d), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4279eebd), SkBits2Float(0x425a890e));
+path.cubicTo(SkBits2Float(0x42693cf3), SkBits2Float(0x426da0dc), SkBits2Float(0x42566929), SkBits2Float(0x427ebed8), SkBits2Float(0x4241d1ac), SkBits2Float(0x4286c6a2));
+path.lineTo(SkBits2Float(0x420c1c33), SkBits2Float(0x4242db53));
+path.cubicTo(SkBits2Float(0x421afee9), SkBits2Float(0x42382742), SkBits2Float(0x42289b18), SkBits2Float(0x422bc78f), SkBits2Float(0x4234ac94), SkBits2Float(0x421dfa34));
+path.lineTo(SkBits2Float(0x4279eebd), SkBits2Float(0x425a890e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp274(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb630015d), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42023f77), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427876e4), SkBits2Float(0xc27fd6f4), SkBits2Float(0x42972728), SkBits2Float(0xc2093dbb));
+path.cubicTo(SkBits2Float(0x42b212de), SkBits2Float(0xc0952410), SkBits2Float(0x42a7d55b), SkBits2Float(0x41f0f791), SkBits2Float(0x4279eebf), SkBits2Float(0x425a890b));
+path.lineTo(SkBits2Float(0x4234ac95), SkBits2Float(0x421dfa35));
+path.cubicTo(SkBits2Float(0x4272a697), SkBits2Float(0x41ae3171), SkBits2Float(0x4280ba5e), SkBits2Float(0xc057a00f), SkBits2Float(0x425a88d0), SkBits2Float(0xc1c66bc2));
+path.cubicTo(SkBits2Float(0x42339ce5), SkBits2Float(0xc238f1c1), SkBits2Float(0x41bc4f6b), SkBits2Float(0xc2700002), SkBits2Float(0xb630015d), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4241d1ad), SkBits2Float(0x4286c6a2));
+path.cubicTo(SkBits2Float(0x419e0f8e), SkBits2Float(0x42b00b7b), SkBits2Float(0xc196dfc4), SkBits2Float(0x42b07042), SkBits2Float(0xc23f0fa7), SkBits2Float(0x4287c1be));
+path.cubicTo(SkBits2Float(0xc29957b6), SkBits2Float(0x423e2672), SkBits2Float(0xc2b30c7a), SkBits2Float(0x4131f351), SkBits2Float(0xc29f94d8), SkBits2Float(0xc1b6db1d));
+path.cubicTo(SkBits2Float(0xc28c1d38), SkBits2Float(0xc26357ee), SkBits2Float(0xc21f7d48), SkBits2Float(0xc2a1d87d), SkBits2Float(0xc09294c7), SkBits2Float(0xc2a5bf3c));
+path.lineTo(SkBits2Float(0xc053ec94), SkBits2Float(0xc26fa25d));
+path.cubicTo(SkBits2Float(0xc1e69644), SkBits2Float(0xc269fe64), SkBits2Float(0xc24a931a), SkBits2Float(0xc224583b), SkBits2Float(0xc266b858), SkBits2Float(0xc1842f59));
+path.cubicTo(SkBits2Float(0xc2816ecb), SkBits2Float(0x4100a388), SkBits2Float(0xc25db33b), SkBits2Float(0x42097539), SkBits2Float(0xc20a1dd2), SkBits2Float(0x4244465c));
+path.cubicTo(SkBits2Float(0xc15a2194), SkBits2Float(0x427f177f), SkBits2Float(0x41648588), SkBits2Float(0x427e85cc), SkBits2Float(0x420c1c35), SkBits2Float(0x4242db52));
+path.lineTo(SkBits2Float(0x4241d1ad), SkBits2Float(0x4286c6a2));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp275(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4202aab9), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42792ea4), SkBits2Float(0xc27f5acc), SkBits2Float(0x4297641b), SkBits2Float(0xc2082fee));
+path.cubicTo(SkBits2Float(0x42b230e5), SkBits2Float(0xc0882884), SkBits2Float(0x42a78c73), SkBits2Float(0x41f502e3), SkBits2Float(0x4278676f), SkBits2Float(0x425c4571));
+path.lineTo(SkBits2Float(0x423391b8), SkBits2Float(0x421f3b73));
+path.cubicTo(SkBits2Float(0x42723d33), SkBits2Float(0x41b11ddb), SkBits2Float(0x4280d014), SkBits2Float(0xc044db05), SkBits2Float(0x425ae0f2), SkBits2Float(0xc1c4e5b3));
+path.cubicTo(SkBits2Float(0x423421be), SkBits2Float(0xc2389802), SkBits2Float(0x41bcea83), SkBits2Float(0xc2700000), SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42786771), SkBits2Float(0x425c4570));
+path.cubicTo(SkBits2Float(0x42678692), SkBits2Float(0x426f4e2b), SkBits2Float(0x425483f6), SkBits2Float(0x42802b0f), SkBits2Float(0x423fbf6b), SkBits2Float(0x428783bc));
+path.lineTo(SkBits2Float(0x420a9ce1), SkBits2Float(0x4243ecb9));
+path.cubicTo(SkBits2Float(0x4219a02a), SkBits2Float(0x42394dac), SkBits2Float(0x42275e32), SkBits2Float(0x422cfde6), SkBits2Float(0x423391b8), SkBits2Float(0x421f3b72));
+path.lineTo(SkBits2Float(0x42786771), SkBits2Float(0x425c4570));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp276(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4202aab9), SkBits2Float(0xc2a5ffff), SkBits2Float(0x42792ea4), SkBits2Float(0xc27f5acc), SkBits2Float(0x4297641b), SkBits2Float(0xc2082fee));
+path.cubicTo(SkBits2Float(0x42b230e5), SkBits2Float(0xc0882884), SkBits2Float(0x42a78c73), SkBits2Float(0x41f502e3), SkBits2Float(0x4278676f), SkBits2Float(0x425c4571));
+path.cubicTo(SkBits2Float(0x42678690), SkBits2Float(0x426f4e2b), SkBits2Float(0x425483f5), SkBits2Float(0x42802b0f), SkBits2Float(0x423fbf6b), SkBits2Float(0x428783bc));
+path.lineTo(SkBits2Float(0x420a9ce1), SkBits2Float(0x4243ecb9));
+path.cubicTo(SkBits2Float(0x4219a02a), SkBits2Float(0x42394dac), SkBits2Float(0x42275e32), SkBits2Float(0x422cfde7), SkBits2Float(0x423391b8), SkBits2Float(0x421f3b73));
+path.lineTo(SkBits2Float(0x423391b8), SkBits2Float(0x421f3b72));
+path.cubicTo(SkBits2Float(0x42723d33), SkBits2Float(0x41b11dd9), SkBits2Float(0x4280d014), SkBits2Float(0xc044db09), SkBits2Float(0x425ae0f2), SkBits2Float(0xc1c4e5b3));
+path.cubicTo(SkBits2Float(0x423421be), SkBits2Float(0xc2389802), SkBits2Float(0x41bcea83), SkBits2Float(0xc2700000), SkBits2Float(0x3725ffa9), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423fbf6b), SkBits2Float(0x428783bc));
+path.cubicTo(SkBits2Float(0x4197e908), SkBits2Float(0x42b0799e), SkBits2Float(0xc19e2f01), SkBits2Float(0x42b0215b), SkBits2Float(0xc24226b0), SkBits2Float(0x4286a80b));
+path.cubicTo(SkBits2Float(0xc29a9aef), SkBits2Float(0x423a5d79), SkBits2Float(0xc2b36ebb), SkBits2Float(0x411dee4a), SkBits2Float(0xc29ede64), SkBits2Float(0xc1c087c1));
+path.cubicTo(SkBits2Float(0xc28a4e0d), SkBits2Float(0xc2680353), SkBits2Float(0xc219c8f7), SkBits2Float(0xc2a351d0), SkBits2Float(0xc0409740), SkBits2Float(0xc2a5e40e));
+path.lineTo(SkBits2Float(0xc00b391c), SkBits2Float(0xc26fd79b));
+path.cubicTo(SkBits2Float(0xc1de5701), SkBits2Float(0xc26c1feb), SkBits2Float(0xc247f576), SkBits2Float(0xc227b85e), SkBits2Float(0xc265b08d), SkBits2Float(0xc18b2dac));
+path.cubicTo(SkBits2Float(0xc281b5d1), SkBits2Float(0x40e45588), SkBits2Float(0xc25f8687), SkBits2Float(0x4206b8c8), SkBits2Float(0xc20c59a1), SkBits2Float(0x4242af19));
+path.cubicTo(SkBits2Float(0xc164b2eb), SkBits2Float(0x427ea56a), SkBits2Float(0x415ba119), SkBits2Float(0x427f2508), SkBits2Float(0x420a9ce0), SkBits2Float(0x4243ecba));
+path.lineTo(SkBits2Float(0x423fbf6b), SkBits2Float(0x428783bc));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp277(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4202f62b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4279afc7), SkBits2Float(0xc27f0340), SkBits2Float(0x42978eaf), SkBits2Float(0xc20771fd));
+path.cubicTo(SkBits2Float(0x42b2457b), SkBits2Float(0xc07e0b91), SkBits2Float(0x42a7584a), SkBits2Float(0x41f7da1e), SkBits2Float(0x42775276), SkBits2Float(0x425d7c3f));
+path.lineTo(SkBits2Float(0x4232c97e), SkBits2Float(0x42201c22));
+path.cubicTo(SkBits2Float(0x4271f1c7), SkBits2Float(0x41b32b8d), SkBits2Float(0x4280def3), SkBits2Float(0xc037a5cf), SkBits2Float(0x425b1e7c), SkBits2Float(0xc1c3d316));
+path.cubicTo(SkBits2Float(0x42347f10), SkBits2Float(0xc23858b9), SkBits2Float(0x41bd578b), SkBits2Float(0xc26fffff), SkBits2Float(0xb7240057), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42775277), SkBits2Float(0x425d7c41));
+path.cubicTo(SkBits2Float(0x4266507b), SkBits2Float(0x42707a20), SkBits2Float(0x42532cff), SkBits2Float(0x4280b928), SkBits2Float(0x423e48db), SkBits2Float(0x42880779));
+path.lineTo(SkBits2Float(0x42098e1c), SkBits2Float(0x4244ab32));
+path.cubicTo(SkBits2Float(0x4218a83e), SkBits2Float(0x423a1b21), SkBits2Float(0x42267e0b), SkBits2Float(0x422dd6be), SkBits2Float(0x4232c97e), SkBits2Float(0x42201c22));
+path.lineTo(SkBits2Float(0x42775277), SkBits2Float(0x425d7c41));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp278(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb7240057), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x4202f62b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x4279afc7), SkBits2Float(0xc27f0340), SkBits2Float(0x42978eaf), SkBits2Float(0xc20771fd));
+path.cubicTo(SkBits2Float(0x42b2457b), SkBits2Float(0xc07e0b91), SkBits2Float(0x42a7584a), SkBits2Float(0x41f7da1e), SkBits2Float(0x42775276), SkBits2Float(0x425d7c3f));
+path.lineTo(SkBits2Float(0x42775277), SkBits2Float(0x425d7c41));
+path.cubicTo(SkBits2Float(0x4266507b), SkBits2Float(0x42707a20), SkBits2Float(0x42532cff), SkBits2Float(0x4280b928), SkBits2Float(0x423e48db), SkBits2Float(0x42880779));
+path.lineTo(SkBits2Float(0x42098e1c), SkBits2Float(0x4244ab32));
+path.cubicTo(SkBits2Float(0x4218a83e), SkBits2Float(0x423a1b21), SkBits2Float(0x42267e0b), SkBits2Float(0x422dd6be), SkBits2Float(0x4232c97e), SkBits2Float(0x42201c22));
+path.cubicTo(SkBits2Float(0x4271f1c7), SkBits2Float(0x41b32b8d), SkBits2Float(0x4280def3), SkBits2Float(0xc037a5cf), SkBits2Float(0x425b1e7c), SkBits2Float(0xc1c3d316));
+path.cubicTo(SkBits2Float(0x42347f10), SkBits2Float(0xc23858b9), SkBits2Float(0x41bd578b), SkBits2Float(0xc26fffff), SkBits2Float(0xb7240057), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423e48db), SkBits2Float(0x4288077a));
+path.cubicTo(SkBits2Float(0x41939344), SkBits2Float(0x42b0c509), SkBits2Float(0xc1a3515b), SkBits2Float(0x42afe6ff), SkBits2Float(0xc2444efb), SkBits2Float(0x4285df44));
+path.cubicTo(SkBits2Float(0xc29b7aa2), SkBits2Float(0x4237af14), SkBits2Float(0xc2b3ae7d), SkBits2Float(0x410fd2d1), SkBits2Float(0xc29e5879), SkBits2Float(0xc1c74e5b));
+path.cubicTo(SkBits2Float(0xc2890275), SkBits2Float(0xc26b4310), SkBits2Float(0xc215bdd9), SkBits2Float(0xc2a45375), SkBits2Float(0xbff3abc7), SkBits2Float(0xc2a5f4d2));
+path.lineTo(SkBits2Float(0xbfb025f0), SkBits2Float(0xc26fefd6));
+path.cubicTo(SkBits2Float(0xc1d87e6f), SkBits2Float(0xc26d946b), SkBits2Float(0xc246160c), SkBits2Float(0xc22a11a0), SkBits2Float(0xc264eef0), SkBits2Float(0xc190139e));
+path.cubicTo(SkBits2Float(0xc281e3ea), SkBits2Float(0x40cff015), SkBits2Float(0xc260c9f8), SkBits2Float(0x4204c898), SkBits2Float(0xc20de8e2), SkBits2Float(0x42418cd3));
+path.cubicTo(SkBits2Float(0xc16c1f36), SkBits2Float(0x427e510e), SkBits2Float(0x41555c9e), SkBits2Float(0x427f9213), SkBits2Float(0x42098e1b), SkBits2Float(0x4244ab33));
+path.lineTo(SkBits2Float(0x423e48db), SkBits2Float(0x4288077a));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp279(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x420331e6), SkBits2Float(0xc2a60000), SkBits2Float(0x427a15f4), SkBits2Float(0xc27ebdd3), SkBits2Float(0x4297b03a), SkBits2Float(0xc206db86));
+path.cubicTo(SkBits2Float(0x42b2557a), SkBits2Float(0xc06f9378), SkBits2Float(0x42a72e7e), SkBits2Float(0x41fa194a), SkBits2Float(0x4276762d), SkBits2Float(0x425e7148));
+path.lineTo(SkBits2Float(0x42322a40), SkBits2Float(0x4220cd43));
+path.cubicTo(SkBits2Float(0x4271b558), SkBits2Float(0x41b4cb56), SkBits2Float(0x4280ea83), SkBits2Float(0xc02d3004), SkBits2Float(0x425b4efa), SkBits2Float(0xc1c2f986));
+path.cubicTo(SkBits2Float(0x4234c8ee), SkBits2Float(0xc2382686), SkBits2Float(0x41bdadf1), SkBits2Float(0xc26fffff), SkBits2Float(0x3707ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4276762e), SkBits2Float(0x425e7147));
+path.cubicTo(SkBits2Float(0x42655a01), SkBits2Float(0x42716669), SkBits2Float(0x42521c84), SkBits2Float(0x428128fd), SkBits2Float(0x423d1f69), SkBits2Float(0x42886f05));
+path.lineTo(SkBits2Float(0x4208b718), SkBits2Float(0x424540e7));
+path.cubicTo(SkBits2Float(0x4217e344), SkBits2Float(0x423abccf), SkBits2Float(0x4225cbdd), SkBits2Float(0x422e818f), SkBits2Float(0x42322a41), SkBits2Float(0x4220cd43));
+path.lineTo(SkBits2Float(0x4276762e), SkBits2Float(0x425e7147));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp280(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3707ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x420331e6), SkBits2Float(0xc2a60000), SkBits2Float(0x427a15f4), SkBits2Float(0xc27ebdd3), SkBits2Float(0x4297b03a), SkBits2Float(0xc206db86));
+path.cubicTo(SkBits2Float(0x42b2557a), SkBits2Float(0xc06f937f), SkBits2Float(0x42a72e7e), SkBits2Float(0x41fa1948), SkBits2Float(0x4276762e), SkBits2Float(0x425e7147));
+path.lineTo(SkBits2Float(0x4276762d), SkBits2Float(0x425e7148));
+path.cubicTo(SkBits2Float(0x42655a00), SkBits2Float(0x4271666a), SkBits2Float(0x42521c84), SkBits2Float(0x428128fd), SkBits2Float(0x423d1f69), SkBits2Float(0x42886f05));
+path.lineTo(SkBits2Float(0x4208b718), SkBits2Float(0x424540e7));
+path.cubicTo(SkBits2Float(0x4217e344), SkBits2Float(0x423abccf), SkBits2Float(0x4225cbdd), SkBits2Float(0x422e818f), SkBits2Float(0x42322a41), SkBits2Float(0x4220cd43));
+path.lineTo(SkBits2Float(0x42322a40), SkBits2Float(0x4220cd43));
+path.cubicTo(SkBits2Float(0x4271b558), SkBits2Float(0x41b4cb56), SkBits2Float(0x4280ea83), SkBits2Float(0xc02d3004), SkBits2Float(0x425b4efa), SkBits2Float(0xc1c2f986));
+path.cubicTo(SkBits2Float(0x4234c8ee), SkBits2Float(0xc2382686), SkBits2Float(0x41bdadf1), SkBits2Float(0xc26fffff), SkBits2Float(0x3707ffa9), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423d1f69), SkBits2Float(0x42886f06));
+path.cubicTo(SkBits2Float(0x4190236c), SkBits2Float(0x42b0ff8c), SkBits2Float(0xc1a760b7), SkBits2Float(0x42afb726), SkBits2Float(0xc24601c7), SkBits2Float(0x42853ece));
+path.cubicTo(SkBits2Float(0xc29c2998), SkBits2Float(0x42358ced), SkBits2Float(0xc2b3ddd5), SkBits2Float(0x4104a433), SkBits2Float(0xc29deb35), SkBits2Float(0xc1cca70e));
+path.cubicTo(SkBits2Float(0xc287f895), SkBits2Float(0xc26dd020), SkBits2Float(0xc21285d2), SkBits2Float(0xc2a51ade), SkBits2Float(0xbf83a2cf), SkBits2Float(0xc2a5fcbd));
+path.lineTo(SkBits2Float(0xbf3e53cf), SkBits2Float(0xc26ffb48));
+path.cubicTo(SkBits2Float(0xc1d3d71b), SkBits2Float(0xc26eb4b2), SkBits2Float(0xc24495a7), SkBits2Float(0xc22be9b4), SkBits2Float(0xc26450f5), SkBits2Float(0xc193f109));
+path.cubicTo(SkBits2Float(0xc2820621), SkBits2Float(0x40bfc558), SkBits2Float(0xc261c6ea), SkBits2Float(0x42033dc6), SkBits2Float(0xc20f2333), SkBits2Float(0x4240a4d2));
+path.cubicTo(SkBits2Float(0xc171fde8), SkBits2Float(0x427e0bde), SkBits2Float(0x4150649d), SkBits2Float(0x427fe6ab), SkBits2Float(0x4208b71a), SkBits2Float(0x424540e8));
+path.lineTo(SkBits2Float(0x423d1f69), SkBits2Float(0x42886f06));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp281(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42035955), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427a595d), SkBits2Float(0xc27e8fe6), SkBits2Float(0x4297c647), SkBits2Float(0xc206781b));
+path.cubicTo(SkBits2Float(0x42b25fdf), SkBits2Float(0xc0660504), SkBits2Float(0x42a712a2), SkBits2Float(0x41fb94c7), SkBits2Float(0x4275e43b), SkBits2Float(0x425f1290));
+path.lineTo(SkBits2Float(0x4231c0be), SkBits2Float(0x422141dc));
+path.cubicTo(SkBits2Float(0x42718d10), SkBits2Float(0x41b5ddaf), SkBits2Float(0x4280f208), SkBits2Float(0xc026476c), SkBits2Float(0x425b6edc), SkBits2Float(0xc1c269cb));
+path.cubicTo(SkBits2Float(0x4234f9ab), SkBits2Float(0xc2380553), SkBits2Float(0x41bde6f3), SkBits2Float(0xc26fffff), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x4275e43b), SkBits2Float(0x425f1292));
+path.cubicTo(SkBits2Float(0x4264b6c3), SkBits2Float(0x427201df), SkBits2Float(0x4251681e), SkBits2Float(0x42817283), SkBits2Float(0x423c5a8f), SkBits2Float(0x4288b309));
+path.lineTo(SkBits2Float(0x420828ca), SkBits2Float(0x4245a33c));
+path.cubicTo(SkBits2Float(0x421760db), SkBits2Float(0x423b2719), SkBits2Float(0x422555d9), SkBits2Float(0x422ef1ee), SkBits2Float(0x4231c0be), SkBits2Float(0x422141da));
+path.lineTo(SkBits2Float(0x4275e43b), SkBits2Float(0x425f1292));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp282(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42035955), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427a595d), SkBits2Float(0xc27e8fe6), SkBits2Float(0x4297c647), SkBits2Float(0xc206781b));
+path.cubicTo(SkBits2Float(0x42b25fdf), SkBits2Float(0xc0660504), SkBits2Float(0x42a712a2), SkBits2Float(0x41fb94c7), SkBits2Float(0x4275e43b), SkBits2Float(0x425f1290));
+path.lineTo(SkBits2Float(0x4275e43b), SkBits2Float(0x425f1292));
+path.cubicTo(SkBits2Float(0x4264b6c3), SkBits2Float(0x427201df), SkBits2Float(0x4251681e), SkBits2Float(0x42817283), SkBits2Float(0x423c5a8f), SkBits2Float(0x4288b309));
+path.lineTo(SkBits2Float(0x420828ca), SkBits2Float(0x4245a33c));
+path.cubicTo(SkBits2Float(0x421760db), SkBits2Float(0x423b2719), SkBits2Float(0x422555d9), SkBits2Float(0x422ef1f0), SkBits2Float(0x4231c0be), SkBits2Float(0x422141dc));
+path.cubicTo(SkBits2Float(0x42718d10), SkBits2Float(0x41b5ddaf), SkBits2Float(0x4280f208), SkBits2Float(0xc026476c), SkBits2Float(0x425b6edc), SkBits2Float(0xc1c269cb));
+path.cubicTo(SkBits2Float(0x4234f9ab), SkBits2Float(0xc2380553), SkBits2Float(0x41bde6f3), SkBits2Float(0xc26fffff), SkBits2Float(0x3637fea5), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423c5a8f), SkBits2Float(0x4288b30a));
+path.cubicTo(SkBits2Float(0x418dddd4), SkBits2Float(0x42b12599), SkBits2Float(0xc1aa0e7c), SkBits2Float(0x42af96c0), SkBits2Float(0xc2471fb7), SkBits2Float(0x4284d41e));
+path.cubicTo(SkBits2Float(0xc29c9c18), SkBits2Float(0x423422f8), SkBits2Float(0xc2b3fb95), SkBits2Float(0x40fa8096), SkBits2Float(0xc29da17e), SkBits2Float(0xc1d02ca0));
+path.cubicTo(SkBits2Float(0xc2874768), SkBits2Float(0xc26f7cb1), SkBits2Float(0xc2106396), SkBits2Float(0xc2a59c4c), SkBits2Float(0xbee6b152), SkBits2Float(0xc2a5ff5f));
+path.lineTo(SkBits2Float(0xbea6c49b), SkBits2Float(0xc26fff18));
+path.cubicTo(SkBits2Float(0xc1d0c156), SkBits2Float(0xc26f6fd8), SkBits2Float(0xc2439580), SkBits2Float(0xc22d1f86), SkBits2Float(0xc263e663), SkBits2Float(0xc1967cc0));
+path.cubicTo(SkBits2Float(0xc2821ba4), SkBits2Float(0x40b51622), SkBits2Float(0xc2626c73), SkBits2Float(0x4202381f), SkBits2Float(0xc20ff1e5), SkBits2Float(0x42400a93));
+path.cubicTo(SkBits2Float(0xc175dd55), SkBits2Float(0x427ddd08), SkBits2Float(0x414d1bd1), SkBits2Float(0x42800ed7), SkBits2Float(0x420828d0), SkBits2Float(0x4245a338));
+path.lineTo(SkBits2Float(0x423c5a8f), SkBits2Float(0x4288b30a));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp283(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;  // draws wrong
+    }
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42036bf7), SkBits2Float(0xc2a60000), SkBits2Float(0x427a7934), SkBits2Float(0xc27e7a35), SkBits2Float(0x4297d0ad), SkBits2Float(0xc2064926));
+path.cubicTo(SkBits2Float(0x42b264c0), SkBits2Float(0xc061818a), SkBits2Float(0x42a70569), SkBits2Float(0x41fc47ee), SkBits2Float(0x42759f2d), SkBits2Float(0x425f5e99));
+path.lineTo(SkBits2Float(0x42318ed2), SkBits2Float(0x422178d2));
+path.cubicTo(SkBits2Float(0x427179f2), SkBits2Float(0x41b65f2f), SkBits2Float(0x4280f58f), SkBits2Float(0xc0230424), SkBits2Float(0x425b7de6), SkBits2Float(0xc1c225e6));
+path.cubicTo(SkBits2Float(0x423510af), SkBits2Float(0xc237f5a4), SkBits2Float(0x41be01e5), SkBits2Float(0xc26fffff), SkBits2Float(0x3707ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42759f2b), SkBits2Float(0x425f5e9b));
+path.cubicTo(SkBits2Float(0x42646988), SkBits2Float(0x42724b20), SkBits2Float(0x425112cb), SkBits2Float(0x42819524), SkBits2Float(0x423bfd7a), SkBits2Float(0x4288d30e));
+path.lineTo(SkBits2Float(0x4207e580), SkBits2Float(0x4245d187));
+path.cubicTo(SkBits2Float(0x4217232e), SkBits2Float(0x423b592c), SkBits2Float(0x42251e07), SkBits2Float(0x422f26e4), SkBits2Float(0x42318ed3), SkBits2Float(0x422178d2));
+path.lineTo(SkBits2Float(0x42759f2b), SkBits2Float(0x425f5e9b));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp284(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3707ffa9), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42036bf7), SkBits2Float(0xc2a60000), SkBits2Float(0x427a7934), SkBits2Float(0xc27e7a35), SkBits2Float(0x4297d0ad), SkBits2Float(0xc2064926));
+path.cubicTo(SkBits2Float(0x42b264c0), SkBits2Float(0xc061818a), SkBits2Float(0x42a70569), SkBits2Float(0x41fc47ee), SkBits2Float(0x42759f2d), SkBits2Float(0x425f5e99));
+path.lineTo(SkBits2Float(0x42318ed3), SkBits2Float(0x422178d2));
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bfd7a), SkBits2Float(0x4288d30e));
+path.cubicTo(SkBits2Float(0x418ccafd), SkBits2Float(0x42b13768), SkBits2Float(0xc1ab522b), SkBits2Float(0x42af873b), SkBits2Float(0xc247a66c), SkBits2Float(0x4284a188));
+path.cubicTo(SkBits2Float(0xc29cd1e0), SkBits2Float(0x423377ac), SkBits2Float(0xc2b40936), SkBits2Float(0x40f384e7), SkBits2Float(0xc29d7e41), SkBits2Float(0xc1d1d5b9));
+path.cubicTo(SkBits2Float(0xc286f34a), SkBits2Float(0xc2704657), SkBits2Float(0xc20f6108), SkBits2Float(0xc2a5d8cf), SkBits2Float(0xbe35f437), SkBits2Float(0xc2a5ffe6));
+path.lineTo(SkBits2Float(0xbe038989), SkBits2Float(0xc26fffdc));
+path.cubicTo(SkBits2Float(0xc1cf4b80), SkBits2Float(0xc26fc755), SkBits2Float(0xc2431bdf), SkBits2Float(0xc22db14d), SkBits2Float(0xc263b36c), SkBits2Float(0xc197b016));
+path.cubicTo(SkBits2Float(0xc282257d), SkBits2Float(0x40b009af), SkBits2Float(0xc262ba31), SkBits2Float(0x4201bc49), SkBits2Float(0xc2105343), SkBits2Float(0x423fc16f));
+path.cubicTo(SkBits2Float(0xc177b158), SkBits2Float(0x427dc695), SkBits2Float(0x414b8e67), SkBits2Float(0x42801bb6), SkBits2Float(0x4207e581), SkBits2Float(0x4245d188));
+path.lineTo(SkBits2Float(0x423bfd7a), SkBits2Float(0x4288d30e));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp285(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x420374f9), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427a8897), SkBits2Float(0xc27e6fb3), SkBits2Float(0x4297d5b1), SkBits2Float(0xc2063270));
+path.cubicTo(SkBits2Float(0x42b26718), SkBits2Float(0xc05f52ba), SkBits2Float(0x42a6ff00), SkBits2Float(0x41fc9e87), SkBits2Float(0x42757dbf), SkBits2Float(0x425f8353));
+path.lineTo(SkBits2Float(0x423176ab), SkBits2Float(0x4221935e));
+path.cubicTo(SkBits2Float(0x427170b0), SkBits2Float(0x41b69dc5), SkBits2Float(0x4280f73f), SkBits2Float(0xc0217057), SkBits2Float(0x425b8525), SkBits2Float(0xc1c20512));
+path.cubicTo(SkBits2Float(0x42351bcc), SkBits2Float(0xc237ee0d), SkBits2Float(0x41be0ee4), SkBits2Float(0xc26fffff), SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757dc1), SkBits2Float(0x425f8353));
+path.cubicTo(SkBits2Float(0x4264442b), SkBits2Float(0x42726e80), SkBits2Float(0x4250e985), SkBits2Float(0x4281a5dc), SkBits2Float(0x423bd072), SkBits2Float(0x4288e283));
+path.lineTo(SkBits2Float(0x4207c4f4), SkBits2Float(0x4245e7df));
+path.cubicTo(SkBits2Float(0x42170559), SkBits2Float(0x423b7158), SkBits2Float(0x42250305), SkBits2Float(0x422f4076), SkBits2Float(0x423176ac), SkBits2Float(0x4221935e));
+path.lineTo(SkBits2Float(0x42757dc1), SkBits2Float(0x425f8353));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp286(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x420374f9), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427a8897), SkBits2Float(0xc27e6fb3), SkBits2Float(0x4297d5b1), SkBits2Float(0xc2063270));
+path.cubicTo(SkBits2Float(0x42b26718), SkBits2Float(0xc05f52c1), SkBits2Float(0x42a6ff01), SkBits2Float(0x41fc9e87), SkBits2Float(0x42757dc1), SkBits2Float(0x425f8353));
+path.cubicTo(SkBits2Float(0x4264442b), SkBits2Float(0x42726e80), SkBits2Float(0x4250e985), SkBits2Float(0x4281a5dc), SkBits2Float(0x423bd072), SkBits2Float(0x4288e283));
+path.lineTo(SkBits2Float(0x4207c4f4), SkBits2Float(0x4245e7df));
+path.cubicTo(SkBits2Float(0x42170559), SkBits2Float(0x423b7158), SkBits2Float(0x42250305), SkBits2Float(0x422f4076), SkBits2Float(0x423176ab), SkBits2Float(0x4221935e));
+path.cubicTo(SkBits2Float(0x427170b0), SkBits2Float(0x41b69dc5), SkBits2Float(0x4280f73f), SkBits2Float(0xc0217057), SkBits2Float(0x425b8525), SkBits2Float(0xc1c20512));
+path.cubicTo(SkBits2Float(0x42351bcc), SkBits2Float(0xc237ee0d), SkBits2Float(0x41be0ee4), SkBits2Float(0xc26fffff), SkBits2Float(0xb630015b), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bd073), SkBits2Float(0x4288e283));
+path.cubicTo(SkBits2Float(0x418c461b), SkBits2Float(0x42b13ffc), SkBits2Float(0xc1abee9c), SkBits2Float(0x42af7fac), SkBits2Float(0xc247e775), SkBits2Float(0x42848907));
+path.cubicTo(SkBits2Float(0xc29cebcd), SkBits2Float(0x423324c4), SkBits2Float(0xc2b40fb2), SkBits2Float(0x40f02474), SkBits2Float(0xc29d6d1c), SkBits2Float(0xc1d2a316));
+path.cubicTo(SkBits2Float(0xc286ca87), SkBits2Float(0xc270a7a6), SkBits2Float(0xc20ee3ea), SkBits2Float(0xc2a5f5e9), SkBits2Float(0xbd3ba09e), SkBits2Float(0xc2a5fffd));
+path.lineTo(SkBits2Float(0xbd0796d7), SkBits2Float(0xc26ffffe));
+path.cubicTo(SkBits2Float(0xc1ce9695), SkBits2Float(0xc26ff16b), SkBits2Float(0xc242e0ee), SkBits2Float(0xc22df7a5), SkBits2Float(0xc2639aa3), SkBits2Float(0xc198448c));
+path.cubicTo(SkBits2Float(0xc2822a2c), SkBits2Float(0x40ad98d0), SkBits2Float(0xc262dfac), SkBits2Float(0x4201805e), SkBits2Float(0xc2108243), SkBits2Float(0x423f9e03));
+path.cubicTo(SkBits2Float(0xc178936c), SkBits2Float(0x427dbba8), SkBits2Float(0x414ace5d), SkBits2Float(0x428021e8), SkBits2Float(0x4207c4fa), SkBits2Float(0x4245e7dc));
+path.lineTo(SkBits2Float(0x423bd073), SkBits2Float(0x4288e283));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp287(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x420377c9), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8d67), SkBits2Float(0xc27e6c6d), SkBits2Float(0x4297d744), SkBits2Float(0xc2062b59));
+path.cubicTo(SkBits2Float(0x42b267d3), SkBits2Float(0xc05ea43d), SkBits2Float(0x42a6fd01), SkBits2Float(0x41fcb991), SkBits2Float(0x42757351), SkBits2Float(0x425f8ecb));
+path.lineTo(SkBits2Float(0x42316f1e), SkBits2Float(0x42219ba8));
+path.cubicTo(SkBits2Float(0x42716dc9), SkBits2Float(0x41b6b154), SkBits2Float(0x4280f7c8), SkBits2Float(0xc020f212), SkBits2Float(0x425b876b), SkBits2Float(0xc1c1fad0));
+path.cubicTo(SkBits2Float(0x42351f48), SkBits2Float(0xc237ebae), SkBits2Float(0x41be12f9), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757350), SkBits2Float(0x425f8ecb));
+path.cubicTo(SkBits2Float(0x42643881), SkBits2Float(0x4272798e), SkBits2Float(0x4250dca0), SkBits2Float(0x4281ab15), SkBits2Float(0x423bc262), SkBits2Float(0x4288e756));
+path.lineTo(SkBits2Float(0x4207bac8), SkBits2Float(0x4245eed9));
+path.cubicTo(SkBits2Float(0x4216fc05), SkBits2Float(0x423b78e5), SkBits2Float(0x4224fa94), SkBits2Float(0x422f4874), SkBits2Float(0x42316f1f), SkBits2Float(0x42219baa));
+path.lineTo(SkBits2Float(0x42757350), SkBits2Float(0x425f8ecb));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp288(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x420377c9), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8d67), SkBits2Float(0xc27e6c6d), SkBits2Float(0x4297d744), SkBits2Float(0xc2062b59));
+path.cubicTo(SkBits2Float(0x42b267d3), SkBits2Float(0xc05ea43d), SkBits2Float(0x42a6fd01), SkBits2Float(0x41fcb991), SkBits2Float(0x42757351), SkBits2Float(0x425f8ecb));
+path.lineTo(SkBits2Float(0x423bc262), SkBits2Float(0x4288e756));
+path.lineTo(SkBits2Float(0x4207bac8), SkBits2Float(0x4245eed9));
+path.cubicTo(SkBits2Float(0x4216fc05), SkBits2Float(0x423b78e5), SkBits2Float(0x4224fa94), SkBits2Float(0x422f4874), SkBits2Float(0x42316f1f), SkBits2Float(0x42219baa));
+path.lineTo(SkBits2Float(0x42316f1e), SkBits2Float(0x42219ba8));
+path.cubicTo(SkBits2Float(0x42716dc9), SkBits2Float(0x41b6b154), SkBits2Float(0x4280f7c8), SkBits2Float(0xc020f212), SkBits2Float(0x425b876b), SkBits2Float(0xc1c1fad0));
+path.cubicTo(SkBits2Float(0x42351f48), SkBits2Float(0xc237ebae), SkBits2Float(0x41be12f9), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc261), SkBits2Float(0x4288e756));
+path.cubicTo(SkBits2Float(0x418c1c95), SkBits2Float(0x42b142a6), SkBits2Float(0xc1ac1f7e), SkBits2Float(0x42af7d4d), SkBits2Float(0xc247fbc6), SkBits2Float(0x4284815d));
+path.cubicTo(SkBits2Float(0xc29cf3e6), SkBits2Float(0x42330ad8), SkBits2Float(0xc2b411b5), SkBits2Float(0x40ef163d), SkBits2Float(0xc29d67bc), SkBits2Float(0xc1d2e345));
+path.cubicTo(SkBits2Float(0xc286bdc4), SkBits2Float(0xc270c60d), SkBits2Float(0xc20ebcc7), SkBits2Float(0xc2a5feff), SkBits2Float(0xbb958372), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0xbb591ee2), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce5e0c), SkBits2Float(0xc26ffe8b), SkBits2Float(0xc242ce80), SkBits2Float(0xc22e0d9d), SkBits2Float(0xc26392e3), SkBits2Float(0xc19872ed));
+path.cubicTo(SkBits2Float(0xc2822ba3), SkBits2Float(0x40acd588), SkBits2Float(0xc262eb66), SkBits2Float(0x42016da1), SkBits2Float(0xc21090f8), SkBits2Float(0x423f92f0));
+path.cubicTo(SkBits2Float(0xc178da2a), SkBits2Float(0x427db83e), SkBits2Float(0x414a923f), SkBits2Float(0x428023d8), SkBits2Float(0x4207baca), SkBits2Float(0x4245eed8));
+path.lineTo(SkBits2Float(0x423bc261), SkBits2Float(0x4288e756));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp289(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp290(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp291(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp292(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp293(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp294(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp295(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp296(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp297(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp298(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp299(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp300(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp301(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp302(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp303(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp304(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp305(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp306(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp307(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp308(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp309(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp310(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp311(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp312(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp313(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp314(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp315(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp316(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp317(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp318(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp319(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp320(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp321(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp322(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp323(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp324(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp325(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp326(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp327(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp328(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp329(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp330(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp331(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp332(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp333(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp334(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp335(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp336(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp337(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp338(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp339(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp340(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp341(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp342(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp343(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp344(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp345(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp346(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp347(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3d570205), SkBits2Float(0xc2a60000), SkBits2Float(0x3dd7026d), SkBits2Float(0xc2a5fffa), SkBits2Float(0x3e2141e6), SkBits2Float(0xc2a5ffed));
+path.lineTo(SkBits2Float(0x3de92565), SkBits2Float(0xc26fffe4));
+path.cubicTo(SkBits2Float(0x3d9b6fac), SkBits2Float(0xc26ffff9), SkBits2Float(0x3d1b715b), SkBits2Float(0xc2700002), SkBits2Float(0x365677c0), SkBits2Float(0xc2700002));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3e214267), SkBits2Float(0xc2a5ffec));
+path.cubicTo(SkBits2Float(0x3e26a1f2), SkBits2Float(0xc2a5ffeb), SkBits2Float(0x3e2c025b), SkBits2Float(0xc2a5ffe9), SkBits2Float(0x3e3162c6), SkBits2Float(0xc2a5ffe7));
+path.lineTo(SkBits2Float(0x3e003af5), SkBits2Float(0xc26fffde));
+path.cubicTo(SkBits2Float(0x3df8b0d2), SkBits2Float(0xc26fffe0), SkBits2Float(0x3df0ead2), SkBits2Float(0xc26fffe2), SkBits2Float(0x3de924d4), SkBits2Float(0xc26fffe4));
+path.lineTo(SkBits2Float(0x3e214267), SkBits2Float(0xc2a5ffec));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp348(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x365677c0), SkBits2Float(0xc2700002));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3d570205), SkBits2Float(0xc2a60000), SkBits2Float(0x3dd7026d), SkBits2Float(0xc2a5fffa), SkBits2Float(0x3e2141e6), SkBits2Float(0xc2a5ffed));
+path.lineTo(SkBits2Float(0x3e0492ca), SkBits2Float(0xc28878a2));
+path.lineTo(SkBits2Float(0x3e214267), SkBits2Float(0xc2a5ffec));
+path.cubicTo(SkBits2Float(0x3e26a1f2), SkBits2Float(0xc2a5ffeb), SkBits2Float(0x3e2c025b), SkBits2Float(0xc2a5ffe9), SkBits2Float(0x3e3162c6), SkBits2Float(0xc2a5ffe7));
+path.lineTo(SkBits2Float(0x3e003af5), SkBits2Float(0xc26fffde));
+path.lineTo(SkBits2Float(0x3de92565), SkBits2Float(0xc26fffe4));
+path.lineTo(SkBits2Float(0x3de924d4), SkBits2Float(0xc26fffe4));
+path.cubicTo(SkBits2Float(0x3d9b6f4b), SkBits2Float(0xc26ffff9), SkBits2Float(0x3d1b70fa), SkBits2Float(0xc2700002), SkBits2Float(0x365677c0), SkBits2Float(0xc2700002));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3e3162a4), SkBits2Float(0xc2a5ffe8));
+path.cubicTo(SkBits2Float(0x3e843f51), SkBits2Float(0xc2a5ffd1), SkBits2Float(0x3eafcce9), SkBits2Float(0xc2a5ffa8), SkBits2Float(0x3edb5a6f), SkBits2Float(0xc2a5ff6f));
+path.lineTo(SkBits2Float(0x3e9e9160), SkBits2Float(0xc26fff2e));
+path.cubicTo(SkBits2Float(0x3e7e2aec), SkBits2Float(0xc26fff82), SkBits2Float(0x3e3f3306), SkBits2Float(0xc26fffbd), SkBits2Float(0x3e003b0e), SkBits2Float(0xc26fffdf));
+path.lineTo(SkBits2Float(0x3e3162a4), SkBits2Float(0xc2a5ffe8));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp349(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e678fda), SkBits2Float(0xc2a60000), SkBits2Float(0x3ee78f7d), SkBits2Float(0xc2a5ff87), SkBits2Float(0x3f2dab18), SkBits2Float(0xc2a5fe96));
+path.lineTo(SkBits2Float(0x3efb15d4), SkBits2Float(0xc26ffdf3));
+path.cubicTo(SkBits2Float(0x3ea764ab), SkBits2Float(0xc26fff52), SkBits2Float(0x3e2764f3), SkBits2Float(0xc2700000), SkBits2Float(0x35c73da0), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f2daad3), SkBits2Float(0xc2a5fe95));
+path.cubicTo(SkBits2Float(0x3f3374d8), SkBits2Float(0xc2a5fe7b), SkBits2Float(0x3f393eae), SkBits2Float(0xc2a5fe62), SkBits2Float(0x3f3f0885), SkBits2Float(0xc2a5fe46));
+path.lineTo(SkBits2Float(0x3f0a18b8), SkBits2Float(0xc26ffd84));
+path.cubicTo(SkBits2Float(0x3f05e964), SkBits2Float(0xc26ffdad), SkBits2Float(0x3f01ba2f), SkBits2Float(0xc26ffdd1), SkBits2Float(0x3efb15f0), SkBits2Float(0xc26ffdf5));
+path.lineTo(SkBits2Float(0x3f2daad3), SkBits2Float(0xc2a5fe95));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp350(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e678fda), SkBits2Float(0xc2a60000), SkBits2Float(0x3ee78f7d), SkBits2Float(0xc2a5ff87), SkBits2Float(0x3f2dab18), SkBits2Float(0xc2a5fe96));
+path.cubicTo(SkBits2Float(0x3f3374d8), SkBits2Float(0xc2a5fe7b), SkBits2Float(0x3f393eae), SkBits2Float(0xc2a5fe62), SkBits2Float(0x3f3f0885), SkBits2Float(0xc2a5fe46));
+path.lineTo(SkBits2Float(0x3f0a18b8), SkBits2Float(0xc26ffd84));
+path.cubicTo(SkBits2Float(0x3f05e964), SkBits2Float(0xc26ffdad), SkBits2Float(0x3f01ba2f), SkBits2Float(0xc26ffdd1), SkBits2Float(0x3efb15f0), SkBits2Float(0xc26ffdf5));
+path.lineTo(SkBits2Float(0x3efb15d4), SkBits2Float(0xc26ffdf3));
+path.cubicTo(SkBits2Float(0x3ea764ab), SkBits2Float(0xc26fff52), SkBits2Float(0x3e2764f3), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f3f0899), SkBits2Float(0xc2a5fe48));
+path.cubicTo(SkBits2Float(0x3f8e6b81), SkBits2Float(0xc2a5fc98), SkBits2Float(0x3fbd51fb), SkBits2Float(0xc2a5f9aa), SkBits2Float(0x3fec36d3), SkBits2Float(0xc2a5f57e));
+path.lineTo(SkBits2Float(0x3faac1d7), SkBits2Float(0xc26ff0d0));
+path.cubicTo(SkBits2Float(0x3f88dbac), SkBits2Float(0xc26ff6d7), SkBits2Float(0x3f4de8bb), SkBits2Float(0xc26ffb13), SkBits2Float(0x3f0a18e7), SkBits2Float(0xc26ffd83));
+path.lineTo(SkBits2Float(0x3f3f0899), SkBits2Float(0xc2a5fe48));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp351(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x403f62fc), SkBits2Float(0xc2a60000), SkBits2Float(0x40bf510b), SkBits2Float(0xc2a5ad41), SkBits2Float(0x410f39cc), SkBits2Float(0xc2a50821));
+path.lineTo(SkBits2Float(0x40cf12cc), SkBits2Float(0xc26e99a0));
+path.cubicTo(SkBits2Float(0x408a4d18), SkBits2Float(0xc26f885f), SkBits2Float(0x400a5a13), SkBits2Float(0xc2700000), SkBits2Float(0x36a6ff52), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x410f39cd), SkBits2Float(0xc2a50820));
+path.cubicTo(SkBits2Float(0x4113fb3b), SkBits2Float(0xc2a4f79d), SkBits2Float(0x4118bbf1), SkBits2Float(0xc2a4e648), SkBits2Float(0x411d7be1), SkBits2Float(0xc2a4d421));
+path.lineTo(SkBits2Float(0x40e3b008), SkBits2Float(0xc26e4e75));
+path.cubicTo(SkBits2Float(0x40dcd206), SkBits2Float(0xc26e68b4), SkBits2Float(0x40d5f2eb), SkBits2Float(0xc26e81c3), SkBits2Float(0x40cf12c6), SkBits2Float(0xc26e99a1));
+path.lineTo(SkBits2Float(0x410f39cd), SkBits2Float(0xc2a50820));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp352(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e0b17a8), SkBits2Float(0xc2a60000), SkBits2Float(0x3e8b179e), SkBits2Float(0xc2a5ffd4), SkBits2Float(0x3ed0a337), SkBits2Float(0xc2a5ff7c));
+path.lineTo(SkBits2Float(0x3ed0a338), SkBits2Float(0xc2a5ff7d));
+path.cubicTo(SkBits2Float(0x3ed797a0), SkBits2Float(0xc2a5ff73), SkBits2Float(0x3ede8c36), SkBits2Float(0xc2a5ff6a), SkBits2Float(0x3ee580cb), SkBits2Float(0xc2a5ff60));
+path.lineTo(SkBits2Float(0x3ea5e78a), SkBits2Float(0xc26fff1b));
+path.cubicTo(SkBits2Float(0x3ea0e0bb), SkBits2Float(0xc26fff29), SkBits2Float(0x3e9bd9a1), SkBits2Float(0xc26fff36), SkBits2Float(0x3e96d286), SkBits2Float(0xc26fff43));
+path.lineTo(SkBits2Float(0x3e96d285), SkBits2Float(0xc26fff42));
+path.cubicTo(SkBits2Float(0x3e491945), SkBits2Float(0xc26fffc2), SkBits2Float(0x3dc91958), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ee58048), SkBits2Float(0xc2a5ff61));
+path.cubicTo(SkBits2Float(0x3f2b1987), SkBits2Float(0xc2a5fec4), SkBits2Float(0x3f637253), SkBits2Float(0xc2a5fdb6), SkBits2Float(0x3f8de535), SkBits2Float(0xc2a5fc35));
+path.lineTo(SkBits2Float(0x3f4d269a), SkBits2Float(0xc26ffa85));
+path.cubicTo(SkBits2Float(0x3f246b51), SkBits2Float(0xc26ffcb3), SkBits2Float(0x3ef75f30), SkBits2Float(0xc26ffe3a), SkBits2Float(0x3ea5e737), SkBits2Float(0xc26fff1c));
+path.lineTo(SkBits2Float(0x3ee58048), SkBits2Float(0xc2a5ff61));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp1390(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0xb7240057), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x420377ff), SkBits2Float(0xc2a5ffff), SkBits2Float(0x427a8dc0), SkBits2Float(0xc27e6c2f), SkBits2Float(0x4297d760), SkBits2Float(0xc2062ad2));
+path.cubicTo(SkBits2Float(0x42b267e1), SkBits2Float(0xc05e974f), SkBits2Float(0x42a6fcda), SkBits2Float(0x41fcbb92), SkBits2Float(0x42757289), SkBits2Float(0x425f8fa5));
+path.cubicTo(SkBits2Float(0x426437a0), SkBits2Float(0x42727a5f), SkBits2Float(0x4250dbaa), SkBits2Float(0x4281ab79), SkBits2Float(0x423bc155), SkBits2Float(0x4288e7b2));
+path.lineTo(SkBits2Float(0x4207ba06), SkBits2Float(0x4245ef5e));
+path.cubicTo(SkBits2Float(0x4216fb52), SkBits2Float(0x423b7973), SkBits2Float(0x4224f9f2), SkBits2Float(0x422f490a), SkBits2Float(0x42316e8e), SkBits2Float(0x42219c46));
+path.cubicTo(SkBits2Float(0x42716d91), SkBits2Float(0x41b6b2c9), SkBits2Float(0x4280f7d1), SkBits2Float(0xc020e8c8), SkBits2Float(0x425b8794), SkBits2Float(0xc1c1fa0e));
+path.cubicTo(SkBits2Float(0x42351f87), SkBits2Float(0xc237eb83), SkBits2Float(0x41be1342), SkBits2Float(0xc2700002), SkBits2Float(0xb7240057), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc156), SkBits2Float(0x4288e7b2));
+path.cubicTo(SkBits2Float(0x418c1984), SkBits2Float(0x42b142da), SkBits2Float(0xc1ac2314), SkBits2Float(0x42af7d21), SkBits2Float(0xc247fd43), SkBits2Float(0x428480ce));
+path.cubicTo(SkBits2Float(0xc29cf47f), SkBits2Float(0x423308f3), SkBits2Float(0xc2b411dd), SkBits2Float(0x40ef0242), SkBits2Float(0xc29d6757), SkBits2Float(0xc1d2e807));
+path.cubicTo(SkBits2Float(0xc286bcd2), SkBits2Float(0xc270c84c), SkBits2Float(0xc20eb9e2), SkBits2Float(0xc2a5ffaa), SkBits2Float(0xbac6f0ca), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0xba901698), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce59d7), SkBits2Float(0xc26fff83), SkBits2Float(0xc242cd21), SkBits2Float(0xc22e0f3f), SkBits2Float(0xc263924f), SkBits2Float(0xc1987661));
+path.cubicTo(SkBits2Float(0xc2822bbf), SkBits2Float(0x40acc6fd), SkBits2Float(0xc262ec43), SkBits2Float(0x42016c3b), SkBits2Float(0xc2109210), SkBits2Float(0x423f921c));
+path.cubicTo(SkBits2Float(0xc178df72), SkBits2Float(0x427db7fc), SkBits2Float(0x414a8dba), SkBits2Float(0x428023fd), SkBits2Float(0x4207ba05), SkBits2Float(0x4245ef60));
+path.lineTo(SkBits2Float(0x423bc156), SkBits2Float(0x4288e7b2));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp1391(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp1392(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp1393(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3c436965), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3cc36072), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d128619), SkBits2Float(0xc2a5fffe));
+path.lineTo(SkBits2Float(0x3cd3db06), SkBits2Float(0xc26fffff));
+path.cubicTo(SkBits2Float(0x3c8d3d03), SkBits2Float(0xc2700000), SkBits2Float(0x3c0d4407), SkBits2Float(0xc2700000), SkBits2Float(0x36606a00), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3d12888d), SkBits2Float(0xc2a5ffff));
+path.cubicTo(SkBits2Float(0x3d176d55), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d1c4dcb), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d212e40), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x3ce90a84), SkBits2Float(0xc26ffffe));
+path.cubicTo(SkBits2Float(0x3ce1ffb6), SkBits2Float(0xc26ffffe), SkBits2Float(0x3cdaedb6), SkBits2Float(0xc26fffff), SkBits2Float(0x3cd3dbb7), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x3d12888d), SkBits2Float(0xc2a5ffff));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp1394(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x36606a00), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3c436965), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3cc36072), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d128619), SkBits2Float(0xc2a5fffe));
+path.lineTo(SkBits2Float(0x3d12888d), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x3d212e40), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x3ce90a84), SkBits2Float(0xc26ffffe));
+path.cubicTo(SkBits2Float(0x3ce1ffb6), SkBits2Float(0xc26ffffe), SkBits2Float(0x3cdaedb6), SkBits2Float(0xc26fffff), SkBits2Float(0x3cd3db06), SkBits2Float(0xc26fffff));
+path.cubicTo(SkBits2Float(0x3c8d3d03), SkBits2Float(0xc2700000), SkBits2Float(0x3c0d4407), SkBits2Float(0xc2700000), SkBits2Float(0x36606a00), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3d212fd0), SkBits2Float(0xc2a5ffff));
+path.cubicTo(SkBits2Float(0x3d705530), SkBits2Float(0xc2a5fffe), SkBits2Float(0x3d9fbf82), SkBits2Float(0xc2a5fffc), SkBits2Float(0x3dc7546b), SkBits2Float(0xc2a5fffa));
+path.lineTo(SkBits2Float(0x3d901696), SkBits2Float(0xc26ffff5));
+path.cubicTo(SkBits2Float(0x3d66f230), SkBits2Float(0xc26ffff9), SkBits2Float(0x3d2dbab1), SkBits2Float(0xc26ffffc), SkBits2Float(0x3ce90664), SkBits2Float(0xc26ffffe));
+path.lineTo(SkBits2Float(0x3d212fd0), SkBits2Float(0xc2a5ffff));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp1395(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e06023f), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e860192), SkBits2Float(0xc2a5ffd6), SkBits2Float(0x3ec901db), SkBits2Float(0xc2a5ff85));
+path.lineTo(SkBits2Float(0x3e914e16), SkBits2Float(0xc26fff50));
+path.cubicTo(SkBits2Float(0x3e41bddf), SkBits2Float(0xc26fffc5), SkBits2Float(0x3dc1be4c), SkBits2Float(0xc26fffff), SkBits2Float(0x35c55da0), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ec9015b), SkBits2Float(0xc2a5ff86));
+path.cubicTo(SkBits2Float(0x3ecfb4f0), SkBits2Float(0xc2a5ff7d), SkBits2Float(0x3ed66842), SkBits2Float(0xc2a5ff75), SkBits2Float(0x3edd1b92), SkBits2Float(0xc2a5ff6c));
+path.lineTo(SkBits2Float(0x3e9fd5de), SkBits2Float(0xc26fff2b));
+path.cubicTo(SkBits2Float(0x3e9afe3a), SkBits2Float(0xc26fff39), SkBits2Float(0x3e96263d), SkBits2Float(0xc26fff45), SkBits2Float(0x3e914e41), SkBits2Float(0xc26fff51));
+path.lineTo(SkBits2Float(0x3ec9015b), SkBits2Float(0xc2a5ff86));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp1396(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e0601e9), SkBits2Float(0xc2a60000), SkBits2Float(0x3e86013c), SkBits2Float(0xc2a5ffd6), SkBits2Float(0x3ec9015a), SkBits2Float(0xc2a5ff85));
+path.lineTo(SkBits2Float(0x3ec9015b), SkBits2Float(0xc2a5ff86));
+path.cubicTo(SkBits2Float(0x3ecfb4f0), SkBits2Float(0xc2a5ff7d), SkBits2Float(0x3ed66842), SkBits2Float(0xc2a5ff75), SkBits2Float(0x3edd1b92), SkBits2Float(0xc2a5ff6c));
+path.lineTo(SkBits2Float(0x3e9fd5de), SkBits2Float(0xc26fff2b));
+path.cubicTo(SkBits2Float(0x3e9afe3a), SkBits2Float(0xc26fff39), SkBits2Float(0x3e96263d), SkBits2Float(0xc26fff45), SkBits2Float(0x3e914e16), SkBits2Float(0xc26fff50));
+path.cubicTo(SkBits2Float(0x3e41bddf), SkBits2Float(0xc26fffc5), SkBits2Float(0x3dc1be4c), SkBits2Float(0xc26fffff), SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3edd1b0d), SkBits2Float(0xc2a5ff6d));
+path.cubicTo(SkBits2Float(0x3f24d70e), SkBits2Float(0xc2a5fedc), SkBits2Float(0x3f5b204e), SkBits2Float(0xc2a5fde1), SkBits2Float(0x3f88b475), SkBits2Float(0xc2a5fc7b));
+path.lineTo(SkBits2Float(0x3f45a57e), SkBits2Float(0xc26ffaea));
+path.cubicTo(SkBits2Float(0x3f1e67a6), SkBits2Float(0xc26ffcf1), SkBits2Float(0x3eee52e7), SkBits2Float(0xc26ffe5c), SkBits2Float(0x3e9fd606), SkBits2Float(0xc26fff2d));
+path.lineTo(SkBits2Float(0x3edd1b0d), SkBits2Float(0xc2a5ff6d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp2193(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e3881bc), SkBits2Float(0xc2a60000), SkBits2Float(0x3eb88238), SkBits2Float(0xc2a5ffb3), SkBits2Float(0x3f0a6190), SkBits2Float(0xc2a5ff19));
+path.lineTo(SkBits2Float(0x3ec8119b), SkBits2Float(0xc26ffeb2));
+path.cubicTo(SkBits2Float(0x3e856151), SkBits2Float(0xc26fff91), SkBits2Float(0x3e0561b2), SkBits2Float(0xc2700000), SkBits2Float(0x3629eed0), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f0a6183), SkBits2Float(0xc2a5ff19));
+path.cubicTo(SkBits2Float(0x3f0efe46), SkBits2Float(0xc2a5ff0a), SkBits2Float(0x3f139b44), SkBits2Float(0xc2a5fef9), SkBits2Float(0x3f183842), SkBits2Float(0xc2a5fee9));
+path.lineTo(SkBits2Float(0x3edc1349), SkBits2Float(0xc26ffe6c));
+path.cubicTo(SkBits2Float(0x3ed567f5), SkBits2Float(0xc26ffe84), SkBits2Float(0x3ecebccf), SkBits2Float(0xc26ffe9c), SkBits2Float(0x3ec811a8), SkBits2Float(0xc26ffeb2));
+path.lineTo(SkBits2Float(0x3f0a6183), SkBits2Float(0xc2a5ff19));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp2194(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3629eed0), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e3881ab), SkBits2Float(0xc2a60000), SkBits2Float(0x3eb88227), SkBits2Float(0xc2a5ffb3), SkBits2Float(0x3f0a6183), SkBits2Float(0xc2a5ff19));
+path.lineTo(SkBits2Float(0x3f0a6190), SkBits2Float(0xc2a5ff19));
+path.cubicTo(SkBits2Float(0x3f0efe4f), SkBits2Float(0xc2a5ff0a), SkBits2Float(0x3f139b48), SkBits2Float(0xc2a5fef9), SkBits2Float(0x3f183842), SkBits2Float(0xc2a5fee9));
+path.lineTo(SkBits2Float(0x3edc1349), SkBits2Float(0xc26ffe6c));
+path.cubicTo(SkBits2Float(0x3ed567f5), SkBits2Float(0xc26ffe84), SkBits2Float(0x3ecebccf), SkBits2Float(0xc26ffe9c), SkBits2Float(0x3ec811a8), SkBits2Float(0xc26ffeb2));
+path.lineTo(SkBits2Float(0x3ec8119b), SkBits2Float(0xc26ffeb2));
+path.cubicTo(SkBits2Float(0x3e856151), SkBits2Float(0xc26fff91), SkBits2Float(0x3e0561b2), SkBits2Float(0xc2700000), SkBits2Float(0x3629eed0), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f183800), SkBits2Float(0xc2a5fee9));
+path.cubicTo(SkBits2Float(0x3f62f7a2), SkBits2Float(0xc2a5fdd7), SkBits2Float(0x3f96db12), SkBits2Float(0xc2a5fbfa), SkBits2Float(0x3fbc3981), SkBits2Float(0xc2a5f954));
+path.lineTo(SkBits2Float(0x3f8810cc), SkBits2Float(0xc26ff65b));
+path.cubicTo(SkBits2Float(0x3f5a1a86), SkBits2Float(0xc26ffa2f), SkBits2Float(0x3f241256), SkBits2Float(0xc26ffcdf), SkBits2Float(0x3edc1312), SkBits2Float(0xc26ffe6c));
+path.lineTo(SkBits2Float(0x3f183800), SkBits2Float(0xc2a5fee9));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp3368(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp3369(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp3370(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp3371(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3c85f8a2), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d05fda5), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d48fefa), SkBits2Float(0xc2a5fffd));
+path.lineTo(SkBits2Float(0x3d114e3a), SkBits2Float(0xc26ffffd));
+path.cubicTo(SkBits2Float(0x3cc1c2c0), SkBits2Float(0xc26fffff), SkBits2Float(0x3c41c57e), SkBits2Float(0xc26fffff), SkBits2Float(0x35afaa00), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3d49018c), SkBits2Float(0xc2a5fffe));
+path.cubicTo(SkBits2Float(0x3d4fb7df), SkBits2Float(0xc2a5fffd), SkBits2Float(0x3d5667bf), SkBits2Float(0xc2a5fffd), SkBits2Float(0x3d5d179f), SkBits2Float(0xc2a5fffd));
+path.lineTo(SkBits2Float(0x3d1fd60d), SkBits2Float(0xc26ffffd));
+path.cubicTo(SkBits2Float(0x3d1afde4), SkBits2Float(0xc26fffff), SkBits2Float(0x3d162864), SkBits2Float(0xc26fffff), SkBits2Float(0x3d1152e4), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x3d49018c), SkBits2Float(0xc2a5fffe));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp3372(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3c85f8a2), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d05fda5), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d48fefa), SkBits2Float(0xc2a5fffd));
+path.lineTo(SkBits2Float(0x3d49018c), SkBits2Float(0xc2a5fffe));
+path.cubicTo(SkBits2Float(0x3d4fb7df), SkBits2Float(0xc2a5fffd), SkBits2Float(0x3d5667bf), SkBits2Float(0xc2a5fffd), SkBits2Float(0x3d5d179f), SkBits2Float(0xc2a5fffd));
+path.lineTo(SkBits2Float(0x3d1fd60d), SkBits2Float(0xc26ffffd));
+path.cubicTo(SkBits2Float(0x3d1afde4), SkBits2Float(0xc26fffff), SkBits2Float(0x3d162864), SkBits2Float(0xc26fffff), SkBits2Float(0x3d1152e4), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x3d114e3a), SkBits2Float(0xc26ffffd));
+path.cubicTo(SkBits2Float(0x3cc1c2c0), SkBits2Float(0xc26fffff), SkBits2Float(0x3c41c57e), SkBits2Float(0xc26fffff), SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3d5d1b4e), SkBits2Float(0xc2a5fffe));
+path.cubicTo(SkBits2Float(0x3da4d661), SkBits2Float(0xc2a5fffc), SkBits2Float(0x3ddb1fb1), SkBits2Float(0xc2a5fff8), SkBits2Float(0x3e08b47e), SkBits2Float(0xc2a5fff2));
+path.lineTo(SkBits2Float(0x3dc5a6e0), SkBits2Float(0xc26fffec));
+path.cubicTo(SkBits2Float(0x3d9e671d), SkBits2Float(0xc26ffff6), SkBits2Float(0x3d6e51bc), SkBits2Float(0xc26ffffb), SkBits2Float(0x3d1fd53d), SkBits2Float(0xc26ffffe));
+path.lineTo(SkBits2Float(0x3d5d1b4e), SkBits2Float(0xc2a5fffe));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp4290(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp4291(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp4292(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp4293(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x357ffa94), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.cubicTo(SkBits2Float(0x42643732), SkBits2Float(0x42727ac8), SkBits2Float(0x4250db30), SkBits2Float(0x4281abaa), SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42757226), SkBits2Float(0x425f9012));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp4294(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x42037818), SkBits2Float(0xc2a60000), SkBits2Float(0x427a8dee), SkBits2Float(0xc27e6c10), SkBits2Float(0x4297d76f), SkBits2Float(0xc2062a8f));
+path.cubicTo(SkBits2Float(0x42b267e8), SkBits2Float(0xc05e90e8), SkBits2Float(0x42a6fcc7), SkBits2Float(0x41fcbc94), SkBits2Float(0x42757227), SkBits2Float(0x425f9011));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.lineTo(SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.cubicTo(SkBits2Float(0x4216fafb), SkBits2Float(0x423b79ba), SkBits2Float(0x4224f9a4), SkBits2Float(0x422f4956), SkBits2Float(0x42316e48), SkBits2Float(0x42219c94));
+path.lineTo(SkBits2Float(0x42316e47), SkBits2Float(0x42219c94));
+path.cubicTo(SkBits2Float(0x42716d77), SkBits2Float(0x41b6b381), SkBits2Float(0x4280f7d6), SkBits2Float(0xc020e418), SkBits2Float(0x425b87ab), SkBits2Float(0xc1c1f9ac));
+path.cubicTo(SkBits2Float(0x42351faa), SkBits2Float(0xc237eb6b), SkBits2Float(0x41be136b), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.cubicTo(SkBits2Float(0x418c17fd), SkBits2Float(0x42b142f1), SkBits2Float(0xc1ac24e4), SkBits2Float(0x42af7d09), SkBits2Float(0xc247fe03), SkBits2Float(0x42848083));
+path.cubicTo(SkBits2Float(0xc29cf4c9), SkBits2Float(0x423307fa), SkBits2Float(0xc2b411ee), SkBits2Float(0x40eef84a), SkBits2Float(0xc29d6723), SkBits2Float(0xc1d2ea61));
+path.cubicTo(SkBits2Float(0xc286bc59), SkBits2Float(0xc270c968), SkBits2Float(0xc20eb871), SkBits2Float(0xc2a5ffff), SkBits2Float(0xb5c727ee), SkBits2Float(0xc2a5ffff));
+path.lineTo(SkBits2Float(0x293e5cb4), SkBits2Float(0xc2700000));
+path.cubicTo(SkBits2Float(0xc1ce57c4), SkBits2Float(0xc2700000), SkBits2Float(0xc242cc76), SkBits2Float(0xc22e100c), SkBits2Float(0xc2639208), SkBits2Float(0xc1987810));
+path.cubicTo(SkBits2Float(0xc2822bcd), SkBits2Float(0x40acbfe2), SkBits2Float(0xc262ecb3), SkBits2Float(0x42016b8c), SkBits2Float(0xc210929c), SkBits2Float(0x423f91b4));
+path.cubicTo(SkBits2Float(0xc178e211), SkBits2Float(0x427db7dc), SkBits2Float(0x414a8b85), SkBits2Float(0x4280240f), SkBits2Float(0x4207b9a6), SkBits2Float(0x4245efa0));
+path.lineTo(SkBits2Float(0x423bc0d1), SkBits2Float(0x4288e7e0));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp4295(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e3881bc), SkBits2Float(0xc2a60000), SkBits2Float(0x3eb88238), SkBits2Float(0xc2a5ffb3), SkBits2Float(0x3f0a6190), SkBits2Float(0xc2a5ff19));
+path.lineTo(SkBits2Float(0x3ec8119b), SkBits2Float(0xc26ffeb2));
+path.cubicTo(SkBits2Float(0x3e856151), SkBits2Float(0xc26fff91), SkBits2Float(0x3e0561b2), SkBits2Float(0xc2700000), SkBits2Float(0x3629eed0), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f0a6183), SkBits2Float(0xc2a5ff19));
+path.cubicTo(SkBits2Float(0x3f0efe46), SkBits2Float(0xc2a5ff0a), SkBits2Float(0x3f139b44), SkBits2Float(0xc2a5fef9), SkBits2Float(0x3f183842), SkBits2Float(0xc2a5fee9));
+path.lineTo(SkBits2Float(0x3edc1349), SkBits2Float(0xc26ffe6c));
+path.cubicTo(SkBits2Float(0x3ed567f5), SkBits2Float(0xc26ffe84), SkBits2Float(0x3ecebccf), SkBits2Float(0xc26ffe9c), SkBits2Float(0x3ec811a8), SkBits2Float(0xc26ffeb2));
+path.lineTo(SkBits2Float(0x3f0a6183), SkBits2Float(0xc2a5ff19));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp4296(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x3629eed0), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e3881ab), SkBits2Float(0xc2a60000), SkBits2Float(0x3eb88227), SkBits2Float(0xc2a5ffb3), SkBits2Float(0x3f0a6183), SkBits2Float(0xc2a5ff19));
+path.lineTo(SkBits2Float(0x3f0a6190), SkBits2Float(0xc2a5ff19));
+path.cubicTo(SkBits2Float(0x3f0efe4f), SkBits2Float(0xc2a5ff0a), SkBits2Float(0x3f139b48), SkBits2Float(0xc2a5fef9), SkBits2Float(0x3f183842), SkBits2Float(0xc2a5fee9));
+path.lineTo(SkBits2Float(0x3edc1349), SkBits2Float(0xc26ffe6c));
+path.cubicTo(SkBits2Float(0x3ed567f5), SkBits2Float(0xc26ffe84), SkBits2Float(0x3ecebccf), SkBits2Float(0xc26ffe9c), SkBits2Float(0x3ec811a8), SkBits2Float(0xc26ffeb2));
+path.lineTo(SkBits2Float(0x3ec8119b), SkBits2Float(0xc26ffeb2));
+path.cubicTo(SkBits2Float(0x3e856151), SkBits2Float(0xc26fff91), SkBits2Float(0x3e0561b2), SkBits2Float(0xc2700000), SkBits2Float(0x3629eed0), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3f183800), SkBits2Float(0xc2a5fee9));
+path.cubicTo(SkBits2Float(0x3f62f7a2), SkBits2Float(0xc2a5fdd7), SkBits2Float(0x3f96db12), SkBits2Float(0xc2a5fbfa), SkBits2Float(0x3fbc3981), SkBits2Float(0xc2a5f954));
+path.lineTo(SkBits2Float(0x3f8810cc), SkBits2Float(0xc26ff65b));
+path.cubicTo(SkBits2Float(0x3f5a1a86), SkBits2Float(0xc26ffa2f), SkBits2Float(0x3f241256), SkBits2Float(0xc26ffcdf), SkBits2Float(0x3edc1312), SkBits2Float(0xc26ffe6c));
+path.lineTo(SkBits2Float(0x3f183800), SkBits2Float(0xc2a5fee9));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp5193(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e0b17ea), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3e8b17df), SkBits2Float(0xc2a5ffd4), SkBits2Float(0x3ed0a399), SkBits2Float(0xc2a5ff7c));
+path.lineTo(SkBits2Float(0x3e96d285), SkBits2Float(0xc26fff42));
+path.cubicTo(SkBits2Float(0x3e491945), SkBits2Float(0xc26fffc2), SkBits2Float(0x3dc91958), SkBits2Float(0xc2700000), SkBits2Float(0x340ae940), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ed0a338), SkBits2Float(0xc2a5ff7d));
+path.cubicTo(SkBits2Float(0x3ed797a0), SkBits2Float(0xc2a5ff73), SkBits2Float(0x3ede8c36), SkBits2Float(0xc2a5ff6a), SkBits2Float(0x3ee580cb), SkBits2Float(0xc2a5ff60));
+path.lineTo(SkBits2Float(0x3ea5e78a), SkBits2Float(0xc26fff1b));
+path.cubicTo(SkBits2Float(0x3ea0e0aa), SkBits2Float(0xc26fff29), SkBits2Float(0x3e9bd97e), SkBits2Float(0xc26fff36), SkBits2Float(0x3e96d252), SkBits2Float(0xc26fff43));
+path.lineTo(SkBits2Float(0x3ed0a338), SkBits2Float(0xc2a5ff7d));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+// op end success 1
+
+static void battleOp5194(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e0b17a8), SkBits2Float(0xc2a60000), SkBits2Float(0x3e8b179e), SkBits2Float(0xc2a5ffd4), SkBits2Float(0x3ed0a337), SkBits2Float(0xc2a5ff7c));
+path.lineTo(SkBits2Float(0x3ed0a338), SkBits2Float(0xc2a5ff7d));
+path.cubicTo(SkBits2Float(0x3ed797a0), SkBits2Float(0xc2a5ff73), SkBits2Float(0x3ede8c36), SkBits2Float(0xc2a5ff6a), SkBits2Float(0x3ee580cb), SkBits2Float(0xc2a5ff60));
+path.lineTo(SkBits2Float(0x3ea5e78a), SkBits2Float(0xc26fff1b));
+path.cubicTo(SkBits2Float(0x3ea0e0bb), SkBits2Float(0xc26fff29), SkBits2Float(0x3e9bd9a1), SkBits2Float(0xc26fff36), SkBits2Float(0x3e96d286), SkBits2Float(0xc26fff43));
+path.lineTo(SkBits2Float(0x3e96d285), SkBits2Float(0xc26fff42));
+path.cubicTo(SkBits2Float(0x3e491945), SkBits2Float(0xc26fffc2), SkBits2Float(0x3dc91958), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ee58048), SkBits2Float(0xc2a5ff61));
+path.cubicTo(SkBits2Float(0x3f2b1987), SkBits2Float(0xc2a5fec4), SkBits2Float(0x3f637253), SkBits2Float(0xc2a5fdb6), SkBits2Float(0x3f8de535), SkBits2Float(0xc2a5fc35));
+path.lineTo(SkBits2Float(0x3f4d269a), SkBits2Float(0xc26ffa85));
+path.cubicTo(SkBits2Float(0x3f246b51), SkBits2Float(0xc26ffcb3), SkBits2Float(0x3ef75f30), SkBits2Float(0xc26ffe3a), SkBits2Float(0x3ea5e737), SkBits2Float(0xc26fff1c));
+path.lineTo(SkBits2Float(0x3ee58048), SkBits2Float(0xc2a5ff61));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp402(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3e0b17a8), SkBits2Float(0xc2a60000), SkBits2Float(0x3e8b179e), SkBits2Float(0xc2a5ffd4), SkBits2Float(0x3ed0a337), SkBits2Float(0xc2a5ff7c));
+path.lineTo(SkBits2Float(0x3ed0a338), SkBits2Float(0xc2a5ff7d));
+path.cubicTo(SkBits2Float(0x3ed797a0), SkBits2Float(0xc2a5ff73), SkBits2Float(0x3ede8c36), SkBits2Float(0xc2a5ff6a), SkBits2Float(0x3ee580cb), SkBits2Float(0xc2a5ff60));
+path.lineTo(SkBits2Float(0x3ea5e78a), SkBits2Float(0xc26fff1b));
+path.cubicTo(SkBits2Float(0x3ea0e0bb), SkBits2Float(0xc26fff29), SkBits2Float(0x3e9bd9a1), SkBits2Float(0xc26fff36), SkBits2Float(0x3e96d286), SkBits2Float(0xc26fff43));
+path.lineTo(SkBits2Float(0x3e96d285), SkBits2Float(0xc26fff42));
+path.cubicTo(SkBits2Float(0x3e491945), SkBits2Float(0xc26fffc2), SkBits2Float(0x3dc91958), SkBits2Float(0xc2700000), SkBits2Float(0x00000000), SkBits2Float(0xc2700000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3ee58048), SkBits2Float(0xc2a5ff61));
+path.cubicTo(SkBits2Float(0x3f2b1987), SkBits2Float(0xc2a5fec4), SkBits2Float(0x3f637253), SkBits2Float(0xc2a5fdb6), SkBits2Float(0x3f8de535), SkBits2Float(0xc2a5fc35));
+path.lineTo(SkBits2Float(0x3f4d269a), SkBits2Float(0xc26ffa85));
+path.cubicTo(SkBits2Float(0x3f246b51), SkBits2Float(0xc26ffcb3), SkBits2Float(0x3ef75f30), SkBits2Float(0xc26ffe3a), SkBits2Float(0x3ea5e737), SkBits2Float(0xc26fff1c));
+path.lineTo(SkBits2Float(0x3ee58048), SkBits2Float(0xc2a5ff61));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp6000(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3c9b2383), SkBits2Float(0xc2a60000), SkBits2Float(0x3d1b200b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d68ae54), SkBits2Float(0xc2a5fffd));
+path.lineTo(SkBits2Float(0x3d283599), SkBits2Float(0xc26ffffc));
+path.cubicTo(SkBits2Float(0x3ce049ca), SkBits2Float(0xc26ffffe), SkBits2Float(0x3c604794), SkBits2Float(0xc26fffff), SkBits2Float(0xb58d9000), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x27b71bcd), SkBits2Float(0xc2a60000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3d68b08b), SkBits2Float(0xc2a5fffd));
+path.cubicTo(SkBits2Float(0x3d707589), SkBits2Float(0xc2a5fffd), SkBits2Float(0x3d783329), SkBits2Float(0xc2a5fffd), SkBits2Float(0x3d7ff0c9), SkBits2Float(0xc2a5fffd));
+path.lineTo(SkBits2Float(0x3d3907c2), SkBits2Float(0xc26ffffc));
+path.cubicTo(SkBits2Float(0x3d336bee), SkBits2Float(0xc26ffffd), SkBits2Float(0x3d2dd36e), SkBits2Float(0xc26ffffd), SkBits2Float(0x3d283aee), SkBits2Float(0xc26ffffd));
+path.lineTo(SkBits2Float(0x3d68b08b), SkBits2Float(0xc2a5fffd));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void battleOp6001(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0xc2a60000));
+path.cubicTo(SkBits2Float(0x3c9b2383), SkBits2Float(0xc2a60000), SkBits2Float(0x3d1b200b), SkBits2Float(0xc2a5ffff), SkBits2Float(0x3d68ae54), SkBits2Float(0xc2a5fffd));
+path.lineTo(SkBits2Float(0x3d7ff0c9), SkBits2Float(0xc2a5fffd));
+path.lineTo(SkBits2Float(0x3d3907c2), SkBits2Float(0xc26ffffc));
+path.cubicTo(SkBits2Float(0x3d336bee), SkBits2Float(0xc26ffffd), SkBits2Float(0x3d2dd36e), SkBits2Float(0xc26ffffd), SkBits2Float(0x3d283aee), SkBits2Float(0xc26ffffd));
+path.lineTo(SkBits2Float(0x3d283599), SkBits2Float(0xc26ffffc));
+path.cubicTo(SkBits2Float(0x3ce049ca), SkBits2Float(0xc26ffffe), SkBits2Float(0x3c604794), SkBits2Float(0xc26fffff), SkBits2Float(0x00000000), SkBits2Float(0xc26fffff));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x3d7ff566), SkBits2Float(0xc2a5fffd));
+path.cubicTo(SkBits2Float(0x3dbed1a5), SkBits2Float(0xc2a5fffa), SkBits2Float(0x3dfda9cc), SkBits2Float(0xc2a5fff4), SkBits2Float(0x3e1e40f8), SkBits2Float(0xc2a5ffed));
+path.lineTo(SkBits2Float(0x3de4ce81), SkBits2Float(0xc26fffe5));
+path.cubicTo(SkBits2Float(0x3db75eff), SkBits2Float(0xc26ffff0), SkBits2Float(0x3d89f101), SkBits2Float(0xc26ffff8), SkBits2Float(0x3d390604), SkBits2Float(0xc26ffffc));
+path.lineTo(SkBits2Float(0x3d7ff566), SkBits2Float(0xc2a5fffd));
+path.close();
+
+    SkPath path2(path);
+    testPathOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void (*firstTest)(skiatest::Reporter* , const char* filename) = battleOp6001;
+static void (*stopTest)(skiatest::Reporter* , const char* filename) = 0;
+
+static struct TestDesc tests[] = {
+    TEST(battleOp1),
+    TEST(battleOp2),
+    TEST(battleOp3),
+    TEST(battleOp4),
+    TEST(battleOp5),
+    TEST(battleOp6),
+    TEST(battleOp7),
+    TEST(battleOp8),
+    TEST(battleOp9),
+    TEST(battleOp10),
+
+    TEST(battleOp11),
+    TEST(battleOp12),
+    TEST(battleOp13),
+    TEST(battleOp14),
+    TEST(battleOp15),
+    TEST(battleOp16),
+    TEST(battleOp17),
+    TEST(battleOp18),
+    TEST(battleOp19),
+    TEST(battleOp20),
+
+    TEST(battleOp21),
+    TEST(battleOp22),
+    TEST(battleOp23),
+    TEST(battleOp24),
+    TEST(battleOp25),
+    TEST(battleOp26),
+    TEST(battleOp27),
+    TEST(battleOp28),
+    TEST(battleOp29),
+    TEST(battleOp30),
+
+    TEST(battleOp31),
+    TEST(battleOp32),
+    TEST(battleOp33),
+    TEST(battleOp34),
+    TEST(battleOp35),
+    TEST(battleOp36),
+    TEST(battleOp37),
+    TEST(battleOp38),
+    TEST(battleOp39),
+    TEST(battleOp40),
+
+    TEST(battleOp41),
+    TEST(battleOp42),
+    TEST(battleOp43),
+    TEST(battleOp44),
+    TEST(battleOp45),
+    TEST(battleOp46),  // draws wrong : dropped an outer cubic incorrectly
+    // if assembly rewrite was done, the error would be hidden
+    TEST(battleOp47),
+    TEST(battleOp48),
+    TEST(battleOp49),
+    TEST(battleOp50),
+
+    TEST(battleOp51),
+    TEST(battleOp52),
+    TEST(battleOp53),
+    TEST(battleOp54),  // draws wrong
+    TEST(battleOp55),
+    TEST(battleOp56),
+    TEST(battleOp57),
+    TEST(battleOp58),
+    TEST(battleOp59),  // draws wrong
+    TEST(battleOp60),
+
+    TEST(battleOp61),
+    TEST(battleOp62),
+    TEST(battleOp63),  // draws wrong
+    TEST(battleOp64),
+    TEST(battleOp65),
+    TEST(battleOp66),
+    TEST(battleOp67),
+    TEST(battleOp68),
+    TEST(battleOp69),
+    TEST(battleOp70),
+
+    TEST(battleOp71),
+    TEST(battleOp72),
+    TEST(battleOp73),
+    TEST(battleOp74),
+    TEST(battleOp75),
+    TEST(battleOp76),
+    TEST(battleOp77),
+    TEST(battleOp78),
+    TEST(battleOp79),
+    TEST(battleOp80),
+
+    TEST(battleOp81),
+    TEST(battleOp82),
+    TEST(battleOp83),
+    TEST(battleOp84),
+    TEST(battleOp85),  // draws wrong
+    TEST(battleOp86),
+    TEST(battleOp87),
+    TEST(battleOp88),
+    TEST(battleOp89),
+    TEST(battleOp90),
+
+    TEST(battleOp91),
+    TEST(battleOp92),
+    TEST(battleOp93),
+    TEST(battleOp94),
+    TEST(battleOp95),
+    TEST(battleOp96),
+    TEST(battleOp97),
+    TEST(battleOp98),
+    TEST(battleOp99),
+    TEST(battleOp100),
+
+    TEST(battleOp101),
+    TEST(battleOp102),
+    TEST(battleOp103),
+    TEST(battleOp104),
+    TEST(battleOp105),
+    TEST(battleOp106),
+    TEST(battleOp107),
+    TEST(battleOp108),
+    TEST(battleOp109),
+    TEST(battleOp110),
+
+    TEST(battleOp111),
+    TEST(battleOp112),
+    TEST(battleOp113),
+    TEST(battleOp114),
+    TEST(battleOp115),
+    TEST(battleOp116),
+    TEST(battleOp117),
+    TEST(battleOp118),
+    TEST(battleOp119),
+    TEST(battleOp120),
+
+    TEST(battleOp121),
+    TEST(battleOp122),
+    TEST(battleOp123),
+    TEST(battleOp124),
+    TEST(battleOp125),
+    TEST(battleOp126),
+    TEST(battleOp127),
+    TEST(battleOp128),
+    TEST(battleOp129),
+    TEST(battleOp130),
+
+    TEST(battleOp131),
+    TEST(battleOp132),
+    TEST(battleOp133),
+    TEST(battleOp134),
+    TEST(battleOp135),
+    TEST(battleOp136),
+    TEST(battleOp137),
+    TEST(battleOp138),
+    TEST(battleOp139),
+    TEST(battleOp140),
+
+    TEST(battleOp141),
+    TEST(battleOp142),
+    TEST(battleOp143),
+    TEST(battleOp144),
+    TEST(battleOp145),
+    TEST(battleOp146),
+    TEST(battleOp147),
+    TEST(battleOp148),  // draws wrong
+    TEST(battleOp149),
+    TEST(battleOp150),
+
+    TEST(battleOp151),
+    TEST(battleOp152),
+    TEST(battleOp153),
+    TEST(battleOp154),
+    TEST(battleOp155),
+    TEST(battleOp156),
+    TEST(battleOp157),
+    TEST(battleOp158),
+    TEST(battleOp159),
+    TEST(battleOp160),
+
+    TEST(battleOp161),
+    TEST(battleOp162),
+    TEST(battleOp163),
+    TEST(battleOp164),
+    TEST(battleOp165),
+    TEST(battleOp166),
+    TEST(battleOp167),
+    TEST(battleOp168),
+    TEST(battleOp169),
+    TEST(battleOp170),
+
+    TEST(battleOp171),
+    TEST(battleOp172),
+    TEST(battleOp173),
+    TEST(battleOp174),
+    TEST(battleOp175),
+    TEST(battleOp176),
+    TEST(battleOp177),
+    TEST(battleOp178),
+    TEST(battleOp179),
+    TEST(battleOp180),
+
+    TEST(battleOp181),
+    TEST(battleOp182),
+    TEST(battleOp183),
+    TEST(battleOp184),
+    TEST(battleOp185),
+    TEST(battleOp186),
+    TEST(battleOp187),
+    TEST(battleOp188),
+    TEST(battleOp189),
+    TEST(battleOp190),
+
+    TEST(battleOp191),
+    TEST(battleOp192),
+    TEST(battleOp193),
+    TEST(battleOp194),
+    TEST(battleOp195),
+    TEST(battleOp196),
+    TEST(battleOp197),
+    TEST(battleOp198),
+    TEST(battleOp199),
+    TEST(battleOp200),
+
+    TEST(battleOp201),
+    TEST(battleOp202),
+    TEST(battleOp203),
+    TEST(battleOp204),
+    TEST(battleOp205),
+    TEST(battleOp206),
+    TEST(battleOp207),
+    TEST(battleOp208),
+    TEST(battleOp209),
+    TEST(battleOp210),
+
+    TEST(battleOp211),
+    TEST(battleOp212),
+    TEST(battleOp213),
+    TEST(battleOp214),
+    TEST(battleOp215),
+    TEST(battleOp216),
+    TEST(battleOp217),
+    TEST(battleOp218),
+    TEST(battleOp219),
+    TEST(battleOp220),
+
+    TEST(battleOp221),
+    TEST(battleOp222),
+    TEST(battleOp223),
+    TEST(battleOp224),
+    TEST(battleOp225),
+    TEST(battleOp226),
+    TEST(battleOp227),
+    TEST(battleOp228),
+    TEST(battleOp229),
+    TEST(battleOp230),
+
+    TEST(battleOp231),
+    TEST(battleOp232),
+    TEST(battleOp233),
+    TEST(battleOp234),
+    TEST(battleOp235),
+    TEST(battleOp236),
+    TEST(battleOp237),
+    TEST(battleOp238),
+    TEST(battleOp239),
+    TEST(battleOp240),
+
+    TEST(battleOp241),
+    TEST(battleOp242),
+    TEST(battleOp243),
+    TEST(battleOp244),
+    TEST(battleOp245),
+    TEST(battleOp246),
+    TEST(battleOp247),
+    TEST(battleOp248),
+    TEST(battleOp249),
+    TEST(battleOp250),
+
+    TEST(battleOp251),
+    TEST(battleOp252),
+    TEST(battleOp253),
+    TEST(battleOp254),
+    TEST(battleOp255),
+    TEST(battleOp256),
+    TEST(battleOp257),
+    TEST(battleOp258),
+    TEST(battleOp259),
+    TEST(battleOp260),
+
+    TEST(battleOp261),
+    TEST(battleOp262),
+    TEST(battleOp263),
+    TEST(battleOp264),
+    TEST(battleOp265),
+    TEST(battleOp266),
+    TEST(battleOp267),
+    TEST(battleOp268),
+    TEST(battleOp269),
+    TEST(battleOp270),
+
+    TEST(battleOp271),
+    TEST(battleOp272),
+    TEST(battleOp273),
+    TEST(battleOp274),
+    TEST(battleOp275),
+    TEST(battleOp276),
+    TEST(battleOp277),
+    TEST(battleOp278),
+    TEST(battleOp279),
+    TEST(battleOp280),
+
+    TEST(battleOp281),
+    TEST(battleOp282),
+    TEST(battleOp283),
+    TEST(battleOp284),
+    TEST(battleOp285),
+    TEST(battleOp286),
+    TEST(battleOp287),
+    TEST(battleOp288),
+    TEST(battleOp289),
+    TEST(battleOp290),
+
+    TEST(battleOp291),
+    TEST(battleOp292),
+    TEST(battleOp293),
+    TEST(battleOp294),
+    TEST(battleOp295),
+    TEST(battleOp296),
+    TEST(battleOp297),
+    TEST(battleOp298),
+    TEST(battleOp299),
+    TEST(battleOp300),
+
+    TEST(battleOp301),
+    TEST(battleOp302),
+    TEST(battleOp303),
+    TEST(battleOp304),
+    TEST(battleOp305),
+    TEST(battleOp306),
+    TEST(battleOp307),
+    TEST(battleOp308),
+    TEST(battleOp309),
+    TEST(battleOp310),
+
+    TEST(battleOp311),
+    TEST(battleOp312),
+    TEST(battleOp313),
+    TEST(battleOp314),
+    TEST(battleOp315),
+    TEST(battleOp316),
+    TEST(battleOp317),
+    TEST(battleOp318),
+    TEST(battleOp319),
+    TEST(battleOp320),
+
+    TEST(battleOp321),
+    TEST(battleOp322),
+    TEST(battleOp323),
+    TEST(battleOp324),
+    TEST(battleOp325),
+    TEST(battleOp326),
+    TEST(battleOp327),
+    TEST(battleOp328),
+    TEST(battleOp329),
+    TEST(battleOp330),
+
+    TEST(battleOp331),
+    TEST(battleOp332),
+    TEST(battleOp333),
+    TEST(battleOp334),
+    TEST(battleOp335),
+    TEST(battleOp336),
+    TEST(battleOp337),
+    TEST(battleOp338),
+    TEST(battleOp339),
+    TEST(battleOp340),
+
+    TEST(battleOp341),
+    TEST(battleOp342),
+    TEST(battleOp343),
+    TEST(battleOp344),
+    TEST(battleOp345),
+    TEST(battleOp346),
+    TEST(battleOp347),
+    TEST(battleOp348),
+    TEST(battleOp349),
+    TEST(battleOp350),
+
+    TEST(battleOp351),
+    TEST(battleOp352),
+
+    TEST(battleOp402),
+
+    TEST(battleOp1390),
+    TEST(battleOp1391),
+    TEST(battleOp1392),
+    TEST(battleOp1393),
+    TEST(battleOp1394),
+    TEST(battleOp1395),
+    TEST(battleOp1396),
+
+    TEST(battleOp2193),
+    TEST(battleOp2194),
+
+    TEST(battleOp3368),
+    TEST(battleOp3369),
+    TEST(battleOp3370),
+    TEST(battleOp3371),
+    TEST(battleOp3372),
+
+    TEST(battleOp4290),
+    TEST(battleOp4291),
+    TEST(battleOp4292),
+    TEST(battleOp4293),
+    TEST(battleOp4294),
+    TEST(battleOp4295),
+    TEST(battleOp4296),
+
+    TEST(battleOp5193),
+    TEST(battleOp5194),
+
+    TEST(battleOp6000),
+    TEST(battleOp6001),
+
+    TEST(issue414409c),
+    TEST(issue414409b),
+    TEST(issue414409),
+};
+
+
+static const size_t testCount = SK_ARRAY_COUNT(tests);
+
+static bool runReverse = false;
+
+DEF_TEST(PathOpsBattle, reporter) {
+#if DEBUG_SHOW_TEST_NAME
+    strncpy(DEBUG_FILENAME_STRING, "", DEBUG_FILENAME_STRING_LENGTH);
+#endif
+    RunTestSet(reporter, tests, testCount, firstTest, stopTest, runReverse);
+}
diff --git a/tests/PathOpsDebug.cpp b/tests/PathOpsDebug.cpp
index af60318..8ac38aa 100755
--- a/tests/PathOpsDebug.cpp
+++ b/tests/PathOpsDebug.cpp
@@ -1,6 +1,7 @@
 #include "SkOpContour.h"
 #include "SkIntersectionHelper.h"
 #include "SkOpSegment.h"
+#include "SkString.h"
 
 inline void DebugDumpDouble(double x) {
     if (x == floor(x)) {
@@ -18,6 +19,137 @@
     }
 }
 
+
+#if DEBUG_SHOW_TEST_NAME
+
+static void output_scalar(SkScalar num) {
+    if (num == (int) num) {
+        SkDebugf("%d", (int) num);
+    } else {
+        SkString str;
+        str.printf("%1.9g", num);
+        int width = (int) str.size();
+        const char* cStr = str.c_str();
+        while (cStr[width - 1] == '0') {
+            --width;
+        }
+        str.resize(width);
+        SkDebugf("%sf", str.c_str());
+    }
+}
+
+static void output_points(const SkPoint* pts, int count) {
+    for (int index = 0; index < count; ++index) {
+        output_scalar(pts[index].fX);
+        SkDebugf(", ");
+        output_scalar(pts[index].fY);
+        if (index + 1 < count) {
+            SkDebugf(", ");
+        }
+    }
+    SkDebugf(");\n");
+}
+
+static void showPathContours(SkPath::RawIter& iter, const char* pathName) {
+    uint8_t verb;
+    SkPoint pts[4];
+    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+        switch (verb) {
+            case SkPath::kMove_Verb:
+                SkDebugf("    %s.moveTo(", pathName);
+                output_points(&pts[0], 1);
+                continue;
+            case SkPath::kLine_Verb:
+                SkDebugf("    %s.lineTo(", pathName);
+                output_points(&pts[1], 1);
+                break;
+            case SkPath::kQuad_Verb:
+                SkDebugf("    %s.quadTo(", pathName);
+                output_points(&pts[1], 2);
+                break;
+            case SkPath::kCubic_Verb:
+                SkDebugf("    %s.cubicTo(", pathName);
+                output_points(&pts[1], 3);
+                break;
+            case SkPath::kClose_Verb:
+                SkDebugf("    %s.close();\n", pathName);
+                break;
+            default:
+                SkDEBUGFAIL("bad verb");
+                return;
+        }
+    }
+}
+
+static const char* gFillTypeStr[] = {
+    "kWinding_FillType",
+    "kEvenOdd_FillType",
+    "kInverseWinding_FillType",
+    "kInverseEvenOdd_FillType"
+};
+
+void SkPathOpsDebug::ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration) {
+    SkPath::RawIter iter(path);
+#define SUPPORT_RECT_CONTOUR_DETECTION 0
+#if SUPPORT_RECT_CONTOUR_DETECTION
+    int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0;
+    if (rectCount > 0) {
+        SkTDArray<SkRect> rects;
+        SkTDArray<SkPath::Direction> directions;
+        rects.setCount(rectCount);
+        directions.setCount(rectCount);
+        path.rectContours(rects.begin(), directions.begin());
+        for (int contour = 0; contour < rectCount; ++contour) {
+            const SkRect& rect = rects[contour];
+            SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop,
+                    rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction
+                    ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
+        }
+        return;
+    }
+#endif
+    SkPath::FillType fillType = path.getFillType();
+    SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInverseEvenOdd_FillType);
+    if (includeDeclaration) {
+        SkDebugf("    SkPath %s;\n", name);
+    }
+    SkDebugf("    %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]);
+    iter.setPath(path);
+    showPathContours(iter, name);
+}
+
+static void show_function_header(const char* functionName) {
+    SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filename) {\n", functionName);
+    if (strcmp("skphealth_com76", functionName) == 0) {
+        SkDebugf("found it\n");
+    }
+}
+
+static const char* gOpStrs[] = {
+    "kDifference_PathOp",
+    "kIntersect_PathOp",
+    "kUnion_PathOp",
+    "kXor_PathOp",
+    "kReverseDifference_PathOp",
+};
+
+static void show_op(SkPathOp op, const char* pathOne, const char* pathTwo) {
+    SkDebugf("    testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathTwo, gOpStrs[op]);
+    SkDebugf("}\n");
+}
+
+SK_DECLARE_STATIC_MUTEX(gTestMutex);
+
+void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp,
+        const char* testName) {
+    SkAutoMutexAcquire ac(gTestMutex);
+    show_function_header(testName);
+    ShowOnePath(a, "path", true);
+    ShowOnePath(b, "pathB", true);
+    show_op(shapeOp, "path", "pathB");
+}
+#endif
+
 // if not defined by PathOpsDebug.cpp ...
 #if !defined SK_DEBUG && FORCE_RELEASE
 bool SkPathOpsDebug::ValidWind(int wind) {
diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp
index fe3d24d..d808ed7 100644
--- a/tests/PathOpsExtendedTest.cpp
+++ b/tests/PathOpsExtendedTest.cpp
@@ -14,8 +14,8 @@
 #include "SkPaint.h"
 #include "SkRTConf.h"
 #include "SkStream.h"
+#include "SkTaskGroup.h"
 #include "SkThread.h"
-#include "SkThreadPool.h"
 
 #ifdef SK_BUILD_FOR_MAC
 #include <sys/sysctl.h>
@@ -23,6 +23,8 @@
 
 __SK_FORCE_IMAGE_DECODER_LINKING;
 
+DEFINE_bool2(runFail, f, false, "run tests known to fail.");
+
 static const char marker[] =
     "</div>\n"
     "\n"
@@ -49,102 +51,6 @@
 static bool gComparePathsAssert = true;
 static bool gPathStrAssert = true;
 
-static const char* gFillTypeStr[] = {
-    "kWinding_FillType",
-    "kEvenOdd_FillType",
-    "kInverseWinding_FillType",
-    "kInverseEvenOdd_FillType"
-};
-
-static void output_scalar(SkScalar num) {
-    if (num == (int) num) {
-        SkDebugf("%d", (int) num);
-    } else {
-        SkString str;
-        str.printf("%1.9g", num);
-        int width = (int) str.size();
-        const char* cStr = str.c_str();
-        while (cStr[width - 1] == '0') {
-            --width;
-        }
-        str.resize(width);
-        SkDebugf("%sf", str.c_str());
-    }
-}
-
-static void output_points(const SkPoint* pts, int count) {
-    for (int index = 0; index < count; ++index) {
-        output_scalar(pts[index].fX);
-        SkDebugf(", ");
-        output_scalar(pts[index].fY);
-        if (index + 1 < count) {
-            SkDebugf(", ");
-        }
-    }
-    SkDebugf(");\n");
-}
-
-static void showPathContours(SkPath::RawIter& iter, const char* pathName) {
-    uint8_t verb;
-    SkPoint pts[4];
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        switch (verb) {
-            case SkPath::kMove_Verb:
-                SkDebugf("    %s.moveTo(", pathName);
-                output_points(&pts[0], 1);
-                continue;
-            case SkPath::kLine_Verb:
-                SkDebugf("    %s.lineTo(", pathName);
-                output_points(&pts[1], 1);
-                break;
-            case SkPath::kQuad_Verb:
-                SkDebugf("    %s.quadTo(", pathName);
-                output_points(&pts[1], 2);
-                break;
-            case SkPath::kCubic_Verb:
-                SkDebugf("    %s.cubicTo(", pathName);
-                output_points(&pts[1], 3);
-                break;
-            case SkPath::kClose_Verb:
-                SkDebugf("    %s.close();\n", pathName);
-                break;
-            default:
-                SkDEBUGFAIL("bad verb");
-                return;
-        }
-    }
-}
-
-static void showPath(const SkPath& path, const char* pathName, bool includeDeclaration) {
-    SkPath::RawIter iter(path);
-#define SUPPORT_RECT_CONTOUR_DETECTION 0
-#if SUPPORT_RECT_CONTOUR_DETECTION
-    int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0;
-    if (rectCount > 0) {
-        SkTDArray<SkRect> rects;
-        SkTDArray<SkPath::Direction> directions;
-        rects.setCount(rectCount);
-        directions.setCount(rectCount);
-        path.rectContours(rects.begin(), directions.begin());
-        for (int contour = 0; contour < rectCount; ++contour) {
-            const SkRect& rect = rects[contour];
-            SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop,
-                    rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction
-                    ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
-        }
-        return;
-    }
-#endif
-    SkPath::FillType fillType = path.getFillType();
-    SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInverseEvenOdd_FillType);
-    if (includeDeclaration) {
-        SkDebugf("    SkPath %s;\n", pathName);
-    }
-    SkDebugf("    %s.setFillType(SkPath::%s);\n", pathName, gFillTypeStr[fillType]);
-    iter.setPath(path);
-    showPathContours(iter, pathName);
-}
-
 #if DEBUG_SHOW_TEST_NAME
 static void showPathData(const SkPath& path) {
     SkPath::RawIter iter(path);
@@ -225,29 +131,6 @@
 }
 
 #if DEBUG_SHOW_TEST_NAME
-
-void ShowFunctionHeader(const char* functionName) {
-    SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filename) {\n", functionName);
-    if (strcmp("skphealth_com76", functionName) == 0) {
-        SkDebugf("found it\n");
-    }
-}
-
-static const char* gOpStrs[] = {
-    "kDifference_PathOp",
-    "kIntersect_PathOp",
-    "kUnion_PathOp",
-    "kXor_PathOp",
-    "kReverseDifference_PathOp",
-};
-
-void ShowOp(SkPathOp op, const char* pathOne, const char* pathTwo) {
-    SkDebugf("    testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathTwo, gOpStrs[op]);
-    SkDebugf("}\n");
-}
-#endif
-
-#if DEBUG_SHOW_TEST_NAME
 static char hexorator(int x) {
     if (x < 10) {
         return x + '0';
@@ -420,8 +303,10 @@
     *gTestOp.append() = shapeOp;
     ++gTestNo;
     SkDebugf("    SkPath path, pathB;\n");
-    showPath(a, "path", false);
-    showPath(b, "pathB", false);
+#if DEBUG_SHOW_TEST_NAME
+    SkPathOpsDebug::ShowOnePath(a, "path", false);
+    SkPathOpsDebug::ShowOnePath(b, "pathB", false);
+#endif
     SkDebugf("    testPathOp(reporter, path, pathB, %s, filename);\n", opStrs[shapeOp]);
     SkDebugf("}\n");
     drawAsciiPaths(scaledOne, scaledTwo, true);
@@ -433,6 +318,8 @@
     }
 }
 
+SK_DECLARE_STATIC_MUTEX(compareDebugOut3);
+SK_DECLARE_STATIC_MUTEX(compareDebugOut4);
 static int comparePaths(skiatest::Reporter* reporter, const char* testName, const SkPath& one,
         const SkPath& scaledOne, const SkPath& two, const SkPath& scaledTwo, SkBitmap& bitmap,
         const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const SkMatrix& scale) {
@@ -446,13 +333,11 @@
     }
     const int MAX_ERRORS = 8;
     if (errors2x2 > MAX_ERRORS && gComparePathsAssert) {
-        SK_DECLARE_STATIC_MUTEX(compareDebugOut3);
         SkAutoMutexAcquire autoM(compareDebugOut3);
         SkDebugf("\n*** this test fails ***\n");
         showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
         REPORTER_ASSERT(reporter, 0);
     } else if (gShowPath || errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) {
-        SK_DECLARE_STATIC_MUTEX(compareDebugOut4);
         SkAutoMutexAcquire autoM(compareDebugOut4);
         showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
     }
@@ -519,13 +404,16 @@
     outFile.flush();
 }
 
+SK_DECLARE_STATIC_MUTEX(simplifyDebugOut);
 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state,
                   const char* pathStr) {
     SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
     path.setFillType(fillType);
+#if DEBUG_SHOW_TEST_NAME
     if (gShowPath) {
-        showPath(path, "path", false);
+        SkPathOpsDebug::ShowOnePath(path, "path", false);
     }
+#endif
     if (!Simplify(path, &out)) {
         SkDebugf("%s did not expect failure\n", __FUNCTION__);
         REPORTER_ASSERT(state.fReporter, 0);
@@ -536,7 +424,6 @@
     }
     int result = comparePaths(state.fReporter, NULL, path, out, *state.fBitmap);
     if (result && gPathStrAssert) {
-        SK_DECLARE_STATIC_MUTEX(simplifyDebugOut);
         SkAutoMutexAcquire autoM(simplifyDebugOut);
         char temp[8192];
         sk_bzero(temp, sizeof(temp));
@@ -576,20 +463,6 @@
 }
 
 #if DEBUG_SHOW_TEST_NAME
-
-SK_DECLARE_STATIC_MUTEX(gTestMutex);
-
-void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp,
-        const char* testName) {
-    SkAutoMutexAcquire ac(gTestMutex);
-    ShowFunctionHeader(testName);
-    showPath(a, "path", true);
-    showPath(b, "pathB", true);
-    ShowOp(shapeOp, "path", "pathB");
-}
-#endif
-
-#if DEBUG_SHOW_TEST_NAME
 static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) {
     SkDebugf("\n");
     showPathData(a);
@@ -671,7 +544,7 @@
 
 SK_DECLARE_STATIC_MUTEX(gMutex);
 
-int initializeTests(skiatest::Reporter* reporter, const char* test) {
+void initializeTests(skiatest::Reporter* reporter, const char* test) {
 #if 0  // doesn't work yet
     SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true);
     SK_CONF_SET("images.png.suppressDecoderWarnings", true);
@@ -695,7 +568,6 @@
             }
         }
     }
-    return reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1;
 }
 
 void outputProgress(char* ramStr, const char* pathStr, SkPath::FillType pathFillType) {
diff --git a/tests/PathOpsExtendedTest.h b/tests/PathOpsExtendedTest.h
index 5f3413c..49ac804 100644
--- a/tests/PathOpsExtendedTest.h
+++ b/tests/PathOpsExtendedTest.h
@@ -8,6 +8,7 @@
 #define PathOpsExtendedTest_DEFINED
 
 #include "SkBitmap.h"
+#include "SkCommandLineFlags.h"
 #include "SkPath.h"
 #include "SkPathOpsTypes.h"
 #include "SkStream.h"
@@ -15,6 +16,8 @@
 #include "SkThreadUtils.h"
 #include "Test.h"
 
+DECLARE_bool(runFail);
+
 struct PathOpsThreadState;
 
 struct TestDesc {
@@ -36,7 +39,7 @@
                          const char* pathStr);
 extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename);
 
-int initializeTests(skiatest::Reporter* reporter, const char* testName);
+void initializeTests(skiatest::Reporter* reporter, const char* testName);
 void outputProgress(char* ramStr, const char* pathStr, SkPath::FillType );
 void outputProgress(char* ramStr, const char* pathStr, SkPathOp op);
 
diff --git a/tests/PathOpsLineIntersectionTest.cpp b/tests/PathOpsLineIntersectionTest.cpp
index 379c2f1..105187b 100644
--- a/tests/PathOpsLineIntersectionTest.cpp
+++ b/tests/PathOpsLineIntersectionTest.cpp
@@ -11,6 +11,10 @@
 
 // FIXME: add tests for intersecting, non-intersecting, degenerate, coincident
 static const SkDLine tests[][2] = {
+#if 0
+    // these do intersect at a pair of points, but not close enough for check results liking
+    {{{{365.848175,5081.15186}, {368,5103}}}, {{{367.967712,5102.61084}, {368.278717,5105.71045}}}},
+#endif
     {{{{30,20}, {30,50}}}, {{{24,30}, {36,30}}}},
     {{{{323,193}, {-317,193}}}, {{{0,994}, {0,0}}}},
     {{{{90,230}, {160,60}}}, {{{60,120}, {260,120}}}},
@@ -50,6 +54,9 @@
 static const size_t noIntersect_count = SK_ARRAY_COUNT(noIntersect);
 
 static const SkDLine coincidentTests[][2] = {
+   {{{ {-1.48383003e-006,-83}, {4.2268899e-014,-60} }},
+    {{ {9.5359502e-007,-60}, {5.08227985e-015,-83} }}},
+
    {{{ { 10105, 2510 }, { 10123, 2509.98999f } }},
     {{{10105, 2509.98999f}, { 10123, 2510 } }}},
 
diff --git a/tests/PathOpsOpCubicThreadedTest.cpp b/tests/PathOpsOpCubicThreadedTest.cpp
index 889ade0..751ccc5 100644
--- a/tests/PathOpsOpCubicThreadedTest.cpp
+++ b/tests/PathOpsOpCubicThreadedTest.cpp
@@ -67,8 +67,8 @@
 }
 
 DEF_TEST(PathOpsOpCubicsThreaded, reporter) {
-    int threadCount = initializeTests(reporter, "cubicOp");
-    PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+    initializeTests(reporter, "cubicOp");
+    PathOpsThreadedTestRunner testRunner(reporter);
     for (int a = 0; a < 6; ++a) {  // outermost
         for (int b = a + 1; b < 7; ++b) {
             for (int c = 0 ; c < 6; ++c) {
diff --git a/tests/PathOpsOpLoopThreadedTest.cpp b/tests/PathOpsOpLoopThreadedTest.cpp
index 71efff3..c50e23b 100755
--- a/tests/PathOpsOpLoopThreadedTest.cpp
+++ b/tests/PathOpsOpLoopThreadedTest.cpp
@@ -62,8 +62,11 @@
 }
 
 DEF_TEST(PathOpsOpLoopsThreaded, reporter) {
-    int threadCount = initializeTests(reporter, "cubicOp");
-    PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+    if (!FLAGS_runFail) {
+        return;
+    }
+    initializeTests(reporter, "cubicOp");
+    PathOpsThreadedTestRunner testRunner(reporter);
     for (int a = 0; a < 6; ++a) {  // outermost
         for (int b = a + 1; b < 7; ++b) {
             for (int c = 0 ; c < 6; ++c) {
@@ -81,7 +84,10 @@
 }
 
 DEF_TEST(PathOpsOpLoops, reporter) {
-    (void) initializeTests(reporter, "cubicOp");
+    if (!FLAGS_runFail) {
+        return;
+    }
+    initializeTests(reporter, "cubicOp");
     PathOpsThreadState state;
     state.fReporter = reporter;
     SkBitmap bitmap;
diff --git a/tests/PathOpsOpRectThreadedTest.cpp b/tests/PathOpsOpRectThreadedTest.cpp
index 3d07d74..1b6e4e8 100644
--- a/tests/PathOpsOpRectThreadedTest.cpp
+++ b/tests/PathOpsOpRectThreadedTest.cpp
@@ -74,8 +74,8 @@
 }
 
 DEF_TEST(PathOpsRectsThreaded, reporter) {
-    int threadCount = initializeTests(reporter, "testOp");
-    PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+    initializeTests(reporter, "testOp");
+    PathOpsThreadedTestRunner testRunner(reporter);
     for (int a = 0; a < 6; ++a) {  // outermost
         for (int b = a + 1; b < 7; ++b) {
             for (int c = 0 ; c < 6; ++c) {
diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp
index 1d63bd7..4977b28 100644
--- a/tests/PathOpsOpTest.cpp
+++ b/tests/PathOpsOpTest.cpp
@@ -2731,10 +2731,11 @@
     testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
 }
 
-#define QUAD_CUBIC_FAILS_TO_FIND_INTERSECTION 0
-#if QUAD_CUBIC_FAILS_TO_FIND_INTERSECTION
 // this fails because cubic/quad misses an intersection (failure is isolated in c/q int test)
 static void skpcarrot_is24(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;
+    }
     SkPath path;
     path.setFillType(SkPath::kEvenOdd_FillType);
     path.moveTo(945, 597);
@@ -2760,8 +2761,6 @@
     testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
 }
 
-#endif
-
 static void skpbangalorenest_com4(skiatest::Reporter* reporter, const char* filename) {
     SkPath path;
     path.setFillType(SkPath::kEvenOdd_FillType);
@@ -3283,9 +3282,10 @@
     testPathOp(reporter, path, pathB, kDifference_PathOp, filename);
 }
 
-#define CUBIC_OP_114 0
-#if CUBIC_OP_114
 static void cubicOp114(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;
+    }
     SkPath path, pathB;
     path.setFillType(SkPath::kWinding_FillType);
     path.moveTo(0, 1);
@@ -3297,7 +3297,6 @@
     pathB.close();
     testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
 }
-#endif
 
 static void cubicOp114asQuad(skiatest::Reporter* reporter, const char* filename) {
     SkPath path, pathB;
@@ -3461,13 +3460,64 @@
     testPathOp(reporter, path, pathB, kDifference_PathOp, filename);
 }
 
+static void issue2753(skiatest::Reporter* reporter, const char* filename) {
+    if (!FLAGS_runFail) {
+        return;
+    }
+    SkPath path1;
+    path1.moveTo(142.701f, 110.568f);
+    path1.lineTo(142.957f, 100);
+    path1.lineTo(153.835f, 100);
+    path1.lineTo(154.592f, 108.188f);
+    path1.cubicTo(154.592f, 108.188f, 153.173f, 108.483f, 152.83f, 109.412f);
+    path1.cubicTo(152.83f, 109.412f, 142.701f, 110.568f, 142.701f, 110.568f);
+    path1.close();
+
+    SkPath path2;
+    path2.moveTo(39, 124.001f);
+    path2.cubicTo(39, 124.001f, 50.6f, 117.001f, 50.6f, 117.001f);
+    path2.cubicTo(50.6f, 117.001f, 164.601f, 85.2f, 188.201f, 117.601f);
+    path2.cubicTo(188.201f, 117.601f, 174.801f, 93, 39, 124.001f);
+    path2.close();
+
+    testPathOp(reporter, path1, path2, kUnion_PathOp, filename);
+}
+
+static void issue2808(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path1, path2;
+
+	path1.moveTo(509.20300293f, 385.601989746f);
+	path1.quadTo(509.20300293f, 415.68838501f, 487.928710938f, 436.96270752f);
+	path1.quadTo(466.654388428f, 458.236999512f, 436.567993164f, 458.236999512f);
+	path1.quadTo(406.4815979f, 458.236999512f, 385.207275391f, 436.96270752f);
+	path1.quadTo(363.932983398f, 415.68838501f, 363.932983398f, 385.601989746f);
+	path1.quadTo(363.932983398f, 355.515594482f, 385.207275391f, 334.241271973f);
+	path1.quadTo(406.4815979f, 312.96697998f, 436.567993164f, 312.96697998f);
+	path1.quadTo(466.654388428f, 312.96697998f, 487.928710938f, 334.241271973f);
+	path1.quadTo(509.20300293f, 355.515594482f, 509.20300293f, 385.601989746f);
+	path1.close();
+
+	path2.moveTo(449.033996582f, 290.87298584f);
+	path2.quadTo(449.033996582f, 301.028259277f, 441.853149414f, 308.209106445f);
+	path2.quadTo(434.672271729f, 315.389984131f, 424.516998291f, 315.389984131f);
+	path2.quadTo(414.361724854f, 315.389984131f, 407.180847168f, 308.209106445f);
+	path2.quadTo(400, 301.028259277f, 400, 290.87298584f);
+	path2.quadTo(400, 280.717712402f, 407.180847168f, 273.536865234f);
+	path2.quadTo(414.361724854f, 266.355987549f, 424.516998291f, 266.355987549f);
+	path2.quadTo(434.672271729f, 266.355987549f, 441.853149414f, 273.536865234f);
+	path2.quadTo(449.033996582f, 280.717712402f, 449.033996582f, 290.87298584f);
+	path2.close();
+
+    testPathOp(reporter, path1, path2, kUnion_PathOp, filename);
+}
+
 static void (*firstTest)(skiatest::Reporter* , const char* filename) = 0;
 static void (*stopTest)(skiatest::Reporter* , const char* filename) = 0;
 
 static struct TestDesc tests[] = {
-#if CUBIC_OP_114  // FIXME: curve with inflection is ordered the wrong way
-    TEST(cubicOp114),
-#endif
+    TEST(issue2753),  // FIXME: pair of cubics miss intersection
+    TEST(cubicOp114),  // FIXME: curve with inflection is ordered the wrong way
+    TEST(issue2808),
     TEST(cubicOp114asQuad),
     TEST(rects4),
     TEST(rects3),
@@ -3478,11 +3528,9 @@
     TEST(kari1),
     TEST(quadOp10i),
     TEST(cubicOp113),
-#if QUAD_CUBIC_FAILS_TO_FIND_INTERSECTION
     // fails because a cubic/quadratic intersection is missed
     // the internal quad/quad is far enough away from the real cubic/quad that it is rejected
     TEST(skpcarrot_is24),
-#endif
     TEST(issue1417),
     TEST(cubicOp112),
     TEST(skpadspert_net23),
@@ -3716,7 +3764,146 @@
     testPathFailOp(reporter, path, pathB, kUnion_PathOp, filename);
 }
 
+// m 100,0 60,170 -160,-110 200,0 -170,11000000000 z
+static void fuzz433(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path1, path2;
+    path1.moveTo(100,0);
+    path1.lineTo(60,170);
+    path1.lineTo(-160,-110);
+    path1.lineTo(200,0);
+    path1.lineTo(-170,11000000000.0f);
+    path1.close();
+
+    path2.moveTo(100 + 20,0 + 20);
+    path2.lineTo(60 + 20,170 + 20);
+    path2.lineTo(-160 + 20,-110 + 20);
+    path2.lineTo(200 + 20,0 + 20);
+    path2.lineTo(-170 + 20,11000000000.0f + 20);
+    path2.close();
+
+    testPathFailOp(reporter, path1, path2, kIntersect_PathOp, filename);
+}
+
+static void fuzz433b(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path1, path2;
+    path1.setFillType(SkPath::kEvenOdd_FillType);
+    path1.moveTo(140, 40);
+    path1.lineTo(200, 210);
+    path1.lineTo(40, 100);
+    path1.lineTo(240, 100);
+    path1.lineTo(70, 1.1e+10f);
+    path1.lineTo(140, 40);
+    path1.close();
+
+    path1.setFillType(SkPath::kWinding_FillType);
+    path2.moveTo(190, 60);
+    path2.lineTo(250, 230);
+    path2.lineTo(90, 120);
+    path2.lineTo(290, 120);
+    path2.lineTo(120, 1.1e+10f);
+    path2.lineTo(190, 60);
+    path2.close();
+
+    testPathFailOp(reporter, path1, path2, kUnion_PathOp, filename);
+}
+
+static void fuzz487a(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4309999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4309999a), SkBits2Float(0x429a6666), SkBits2Float(0x42f9999a), SkBits2Float(0x4275999a), SkBits2Float(0x42d70001), SkBits2Float(0x42633333));
+path.lineTo(SkBits2Float(0x42e90001), SkBits2Float(0x41b8cccc));
+path.cubicTo(SkBits2Float(0x42dc6667), SkBits2Float(0x41ab3332), SkBits2Float(0x42cf3334), SkBits2Float(0x41a3ffff), SkBits2Float(0x42c20001), SkBits2Float(0x41a3ffff));
+path.lineTo(SkBits2Float(0x42c20001), SkBits2Float(0x425d999a));
+path.lineTo(SkBits2Float(0x42c20001), SkBits2Float(0x425d999a));
+path.cubicTo(SkBits2Float(0x429c6668), SkBits2Float(0x425d999a), SkBits2Float(0x4279999c), SkBits2Float(0x42886667), SkBits2Float(0x42673335), SkBits2Float(0x42ab0000));
+path.lineTo(SkBits2Float(0x41c0ccd0), SkBits2Float(0x42990000));
+path.cubicTo(SkBits2Float(0x41b33336), SkBits2Float(0x42a5999a), SkBits2Float(0x41ac0003), SkBits2Float(0x42b2cccd), SkBits2Float(0x41ac0003), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999c), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999c), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4261999c), SkBits2Float(0x434d3333), SkBits2Float(0x4364e667), SkBits2Float(0x4346b333), SkBits2Float(0x4364e667), SkBits2Float(0x43400000));
+path.lineTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4309999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4309999a), SkBits2Float(0x42a20000), SkBits2Float(0x43016667), SkBits2Float(0x4287cccd), SkBits2Float(0x42ea999a), SkBits2Float(0x4273999a));
+path.lineTo(SkBits2Float(0x4306cccd), SkBits2Float(0x41f5999a));
+path.cubicTo(SkBits2Float(0x42f76667), SkBits2Float(0x41c26667), SkBits2Float(0x42dd999a), SkBits2Float(0x41a4cccd), SkBits2Float(0x42c23334), SkBits2Float(0x41a4cccd));
+path.lineTo(SkBits2Float(0x42c23334), SkBits2Float(0x425e0000));
+path.cubicTo(SkBits2Float(0x42a43334), SkBits2Float(0x425e0000), SkBits2Float(0x428a0001), SkBits2Float(0x427ecccd), SkBits2Float(0x42780002), SkBits2Float(0x4297999a));
+path.lineTo(SkBits2Float(0x41fccccd), SkBits2Float(0x42693333));
+path.cubicTo(SkBits2Float(0x41c9999a), SkBits2Float(0x428acccd), SkBits2Float(0x41ac0000), SkBits2Float(0x42a4999a), SkBits2Float(0x41ac0000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4261999a), SkBits2Float(0x42de0000), SkBits2Float(0x42813333), SkBits2Float(0x42f83333), SkBits2Float(0x42996666), SkBits2Float(0x4303199a));
+path.cubicTo(SkBits2Float(0x4272cccc), SkBits2Float(0x4303199a), SkBits2Float(0x423d3332), SkBits2Float(0x430de667), SkBits2Float(0x422d9999), SkBits2Float(0x431cb334));
+path.lineTo(SkBits2Float(0x7086a1dc), SkBits2Float(0x42eecccd));
+path.lineTo(SkBits2Float(0x41eb3333), SkBits2Float(0xc12ccccd));
+path.lineTo(SkBits2Float(0x42053333), SkBits2Float(0xc1cccccd));
+path.lineTo(SkBits2Float(0x42780000), SkBits2Float(0xc18f3334));
+path.cubicTo(SkBits2Float(0x43206666), SkBits2Float(0x43134ccd), SkBits2Float(0x43213333), SkBits2Float(0x430db333), SkBits2Float(0x43213333), SkBits2Float(0x43080000));
+path.lineTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.close();
+
+    SkPath path2(path);
+    testPathFailOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void fuzz487b(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4309999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4309999a), SkBits2Float(0x429a6666), SkBits2Float(0x42f9999a), SkBits2Float(0x4275999a), SkBits2Float(0x42d70001), SkBits2Float(0x42633333));
+path.lineTo(SkBits2Float(0x42e90001), SkBits2Float(0x41b8cccc));
+path.cubicTo(SkBits2Float(0x42dc6667), SkBits2Float(0x41ab3332), SkBits2Float(0x42cf3334), SkBits2Float(0x41a3ffff), SkBits2Float(0x42c20001), SkBits2Float(0x41a3ffff));
+path.lineTo(SkBits2Float(0x42c20001), SkBits2Float(0x425d999a));
+path.lineTo(SkBits2Float(0x42c20001), SkBits2Float(0x425d999a));
+path.cubicTo(SkBits2Float(0x429c6668), SkBits2Float(0x425d999a), SkBits2Float(0x4279999c), SkBits2Float(0x42886667), SkBits2Float(0x42673335), SkBits2Float(0x42ab0000));
+path.lineTo(SkBits2Float(0x41c0ccd0), SkBits2Float(0x42990000));
+path.cubicTo(SkBits2Float(0x41b33336), SkBits2Float(0x42a5999a), SkBits2Float(0x41ac0003), SkBits2Float(0x42b2cccd), SkBits2Float(0x41ac0003), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999c), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999c), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4261999c), SkBits2Float(0x434d3333), SkBits2Float(0x4364e667), SkBits2Float(0x4346b333), SkBits2Float(0x4364e667), SkBits2Float(0x43400000));
+path.lineTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.close();
+
+    SkPath path1(path);
+    path.reset();
+    path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4309999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4309999a), SkBits2Float(0x42a20000), SkBits2Float(0x43016667), SkBits2Float(0x4287cccd), SkBits2Float(0x42ea999a), SkBits2Float(0x4273999a));
+path.lineTo(SkBits2Float(0x4306cccd), SkBits2Float(0x41f5999a));
+path.cubicTo(SkBits2Float(0x42f76667), SkBits2Float(0x41c26667), SkBits2Float(0x42dd999a), SkBits2Float(0x41a4cccd), SkBits2Float(0x42c23334), SkBits2Float(0x41a4cccd));
+path.lineTo(SkBits2Float(0x42c23334), SkBits2Float(0x425e0000));
+path.cubicTo(SkBits2Float(0x42a43334), SkBits2Float(0x425e0000), SkBits2Float(0x428a0001), SkBits2Float(0x427ecccd), SkBits2Float(0x42780002), SkBits2Float(0x4297999a));
+path.lineTo(SkBits2Float(0x41fccccd), SkBits2Float(0x42693333));
+path.cubicTo(SkBits2Float(0x41c9999a), SkBits2Float(0x428acccd), SkBits2Float(0x41ac0000), SkBits2Float(0x42a4999a), SkBits2Float(0x41ac0000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4261999a), SkBits2Float(0x42de0000), SkBits2Float(0x42813333), SkBits2Float(0x42f83333), SkBits2Float(0x42996666), SkBits2Float(0x4303199a));
+path.cubicTo(SkBits2Float(0x4272cccc), SkBits2Float(0x4303199a), SkBits2Float(0x423d3332), SkBits2Float(0x430de667), SkBits2Float(0x422d9999), SkBits2Float(0x431cb334));
+path.lineTo(SkBits2Float(0x7086a1dc), SkBits2Float(0x42eecccd));
+path.lineTo(SkBits2Float(0x41eb3333), SkBits2Float(0xc12ccccd));
+path.lineTo(SkBits2Float(0x42053333), SkBits2Float(0xc1cccccd));
+path.lineTo(SkBits2Float(0x42780000), SkBits2Float(0xc18f3334));
+path.cubicTo(SkBits2Float(0x43206666), SkBits2Float(0x43134ccd), SkBits2Float(0x43213333), SkBits2Float(0x430db333), SkBits2Float(0x43213333), SkBits2Float(0x43080000));
+path.lineTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.close();
+
+    SkPath path2(path);
+    testPathFailOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
 static struct TestDesc failTests[] = {
+    TEST(fuzz487a),
+    TEST(fuzz487b),
+    TEST(fuzz433b),
+    TEST(fuzz433),
     TEST(bufferOverflow),
 };
 
diff --git a/tests/PathOpsQuadIntersectionTest.cpp b/tests/PathOpsQuadIntersectionTest.cpp
index ffa00ed..1ddbbcc 100644
--- a/tests/PathOpsQuadIntersectionTest.cpp
+++ b/tests/PathOpsQuadIntersectionTest.cpp
@@ -53,6 +53,9 @@
 }
 
 static const SkDQuad testSet[] = {
+{{{441.853149, 308.209106}, {434.672272, 315.389984}, {424.516998, 315.389984}}},
+{{{385.207275, 334.241272}, {406.481598, 312.96698}, {436.567993, 312.96698}}},
+
 {{{-708.00779269310044, -154.36998607290101}, {-707.90560262312511, -154.36998607290101}, {-707.8333433370193, -154.44224536635932}}},
 {{{-708.00779269310044, -154.61669472244046}, {-701.04513225634582, -128.85970734043804}, {505.58447265625, -504.9130859375}}},
 
diff --git a/tests/PathOpsQuadLineIntersectionThreadedTest.cpp b/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
index fd7581f..7e33b7b 100644
--- a/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
+++ b/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
@@ -111,8 +111,8 @@
 }
 
 DEF_TEST(PathOpsQuadLineIntersectionThreaded, reporter) {
-    int threadCount = initializeTests(reporter, "testQuadLineIntersect");
-    PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+    initializeTests(reporter, "testQuadLineIntersect");
+    PathOpsThreadedTestRunner testRunner(reporter);
     for (int a = 0; a < 16; ++a) {
         for (int b = 0 ; b < 16; ++b) {
             for (int c = 0 ; c < 16; ++c) {
diff --git a/tests/PathOpsSimplifyDegenerateThreadedTest.cpp b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
index 5cd3c35..8e8c58b 100755
--- a/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
+++ b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
@@ -68,8 +68,8 @@
 }
 
 DEF_TEST(PathOpsSimplifyDegeneratesThreaded, reporter) {
-    int threadCount = initializeTests(reporter, "testDegenerates");
-    PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+    initializeTests(reporter, "testDegenerates");
+    PathOpsThreadedTestRunner testRunner(reporter);
     for (int a = 0; a < 16; ++a) {
         int ax = a & 0x03;
         int ay = a >> 2;
diff --git a/tests/PathOpsSimplifyQuadThreadedTest.cpp b/tests/PathOpsSimplifyQuadThreadedTest.cpp
index dbbec3e..3c92cca 100644
--- a/tests/PathOpsSimplifyQuadThreadedTest.cpp
+++ b/tests/PathOpsSimplifyQuadThreadedTest.cpp
@@ -74,8 +74,8 @@
 }
 
 DEF_TEST(PathOpsSimplifyQuadsThreaded, reporter) {
-    int threadCount = initializeTests(reporter, "testQuads");
-    PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+    initializeTests(reporter, "testQuads");
+    PathOpsThreadedTestRunner testRunner(reporter);
     int a = 0;
     for (; a < 16; ++a) {
         for (int b = a ; b < 16; ++b) {
diff --git a/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
index afa9200..f8e9a6e 100755
--- a/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
+++ b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
@@ -76,8 +76,8 @@
 }
 
 DEF_TEST(PathOpsSimplifyQuadralateralsThreaded, reporter) {
-    int threadCount = initializeTests(reporter, "testQuadralaterals");
-    PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+    initializeTests(reporter, "testQuadralaterals");
+    PathOpsThreadedTestRunner testRunner(reporter);
     for (int a = 0; a < 16; ++a) {
         for (int b = a ; b < 16; ++b) {
             for (int c = b ; c < 16; ++c) {
diff --git a/tests/PathOpsSimplifyRectThreadedTest.cpp b/tests/PathOpsSimplifyRectThreadedTest.cpp
index 9e6a5ea..52a78ec 100644
--- a/tests/PathOpsSimplifyRectThreadedTest.cpp
+++ b/tests/PathOpsSimplifyRectThreadedTest.cpp
@@ -187,8 +187,8 @@
 }
 
 DEF_TEST(PathOpsSimplifyRectsThreaded, reporter) {
-    int threadCount = initializeTests(reporter, "testLine");
-    PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+    initializeTests(reporter, "testLine");
+    PathOpsThreadedTestRunner testRunner(reporter);
     for (int a = 0; a < 8; ++a) {  // outermost
         for (int b = a ; b < 8; ++b) {
             for (int c = b ; c < 8; ++c) {
diff --git a/tests/PathOpsSimplifyTest.cpp b/tests/PathOpsSimplifyTest.cpp
index 4bfab14..88547a0 100644
--- a/tests/PathOpsSimplifyTest.cpp
+++ b/tests/PathOpsSimplifyTest.cpp
@@ -4669,9 +4669,20 @@
     testSimplify(reporter, path, filename);
 }
 
+static void testRect3(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, SkPath::kCCW_Direction);
+    path.addRect(10, 30, 40, 30, SkPath::kCCW_Direction);
+    path.addRect(24, 6, 36, 36, SkPath::kCCW_Direction);
+    path.addRect(32, 6, 36, 41, SkPath::kCCW_Direction);
+    testSimplify(reporter, path, filename);
+}
+
 static void (*firstTest)(skiatest::Reporter* , const char* filename) = 0;
 
 static TestDesc tests[] = {
+    TEST(testRect3),
     TEST(testQuadralateral10),
     TEST(testQuads61),
     TEST(testQuads60),
diff --git a/tests/PathOpsSimplifyTrianglesThreadedTest.cpp b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
index b5d6508..ee0ca2b 100755
--- a/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
+++ b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
@@ -73,8 +73,8 @@
 }
 
 DEF_TEST(PathOpsSimplifyTrianglesThreaded, reporter) {
-    int threadCount = initializeTests(reporter, "testTriangles");
-    PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+    initializeTests(reporter, "testTriangles");
+    PathOpsThreadedTestRunner testRunner(reporter);
     for (int a = 0; a < 15; ++a) {
         int ax = a & 0x03;
         int ay = a >> 2;
diff --git a/tests/PathOpsSkpClipTest.cpp b/tests/PathOpsSkpClipTest.cpp
index da50545..b8142cd 100755
--- a/tests/PathOpsSkpClipTest.cpp
+++ b/tests/PathOpsSkpClipTest.cpp
@@ -1,9 +1,13 @@
-
+#include "CrashHandler.h"
+// #include "OverwriteLine.h"
+#include "Resources.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkColor.h"
 #include "SkColorPriv.h"
+#include "SkCommandLineFlags.h"
 #include "SkDevice.h"
+#include "SkForceLinking.h"
 #include "SkGraphics.h"
 #include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
@@ -16,209 +20,133 @@
 #include "SkString.h"
 #include "SkTArray.h"
 #include "SkTDArray.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
+#include "SkTemplates.h"
 #include "SkTime.h"
-#include "Test.h"
 
-#ifdef SK_BUILD_FOR_WIN
-    #define PATH_SLASH "\\"
-    #define IN_DIR "D:\\skp\\slave"
-    #define OUT_DIR "D:\\skpOut\\1\\"
-#else
-    #define PATH_SLASH "/"
-    #define IN_DIR "/skp/2311328-7fc2228/slave"
-    #define OUT_DIR "/skpOut/4/"
-#endif
+__SK_FORCE_IMAGE_DECODER_LINKING;
 
-const struct {
+/* add local exceptions here */
+/* TODO : add command flag interface */
+const struct SkipOverTest {
     int directory;
     const char* filename;
-} skipOverSept[] = {
-    { 3, "http___www_americascup_com_.skp"},  // !simple->closed()
-    {18, "http___www_argus_presse_fr_.skp"},  // can't find winding of remaining vertical edge
-    {31, "http___www_narayana_verlag_de_.skp"},  // !simple->closed()
-    {36, "http___www_educationalcraft_com_.skp"},  // cubic / cubic near end / assert in SkIntersections::insert
-    {44, "http___www_cooksnaps_com_.skp"},  // !simple->isClosed()
-    {48, "http___www_narayana_publishers_com_.skp"},  // !simple->isClosed()
-    {51, "http___www_freedominthe50states_org_.skp"},  // corrupt dash data
-    {52, "http___www_aceinfographics_com_.skp"},  // right angle winding assert
-    {53, "http___www_lojaanabotafogo_com_br_.skp"},  // rrect validate assert
-    {57, "http___www_vantageproduction_com_.skp"},  // !isClosed()
-    {64, "http___www_etiqadd_com_.skp"},  // !simple->closed()
-    {84, "http___www_swapspacesystems_com_.skp"},  // !simple->closed()
-    {90, "http___www_tcmevents_org_.skp"},  // !simple->closed()
-    {96, "http___www_paseoitaigara_com_br_.skp"},  // !simple->closed()
-    {98, "http___www_mortgagemarketguide_com_.skp"},  // !simple->closed()
-    {99, "http___www_kitcheninspirations_wordpress_com_.skp"},  // checkSmall / bumpSpan
+    bool blamePathOps;
+} skipOver[] = {
+    { 2, "http___www_groupon_sg_.skp", false},  // SkAAClip::Builder::addRun SkASSERT(fBounds.contains(x, y));
+    { 6, "http___www_googleventures_com_.skp", true},  // addTCoincident SkASSERT(test->fT < 1);
+    { 7, "http___www_foxsports_nl_.skp", true},  // (no repro on mac) addT SkASSERT(this != other || fVerb == SkPath::kCubic_Verb)
+    {13, "http___www_modernqigong_com_.skp", false},  // SkAAClip::Builder::addRun SkASSERT(fBounds.contains(x, y));
+    {14, "http___www_devbridge_com_.skp", true},  // checkSmallCoincidence SkASSERT(!next->fSmall || checkMultiple);
+    {16, "http___www_1023world_net_.skp", false},  // bitmap decode assert (corrupt skp?)
+    {19, "http___www_alamdi_com_.skp", true},  // cubic/quad intersection
+    {26, "http___www_liveencounters_net_.skp", true},  // (no repro on mac) checkSmall addT:549 (line, expects cubic)
+    {28, "http___www_encros_fr_.skp", false},  // SkAAClip::Builder::addRun SkASSERT(fBounds.contains(x, y));
+    {37, "http___www_familysurvivalprotocol_wordpress_com_.skp", true},  // bumpSpan SkASSERT(span->fOppValue >= 0);
+    {39, "http___sufeinet_com_.skp", false}, // bitmap decode assert (corrupt skp?)
+    {41, "http___www_rano360_com_.skp", true}, // checkSmallCoincidence SkASSERT(!next->fSmall || checkMultiple);
+    {44, "http___www_firstunitedbank_com_.skp", true},  // addTCancel SkASSERT(oIndex > 0);
+    {46, "http___www_shinydemos_com_.skp", true},  // addSimpleAngle SkASSERT(index == count() - 2);
+    {48, "http___www_familysurvivalprotocol_com_.skp", true},  // bumpSpan SkASSERT "span->fOppValue >= 0"
+    {57, "http___www_lptemp_com_.skp", true}, // addTCoincident oPeek = &other->fTs[++oPeekIndex];
+    {71, "http___www_1milyonkahraman_org_.skp", true},  // addTCoincident SkASSERT(test->fT < 1);
+    {88, "http___www_apuntesdelechuza_wordpress_com_.skp", true},  // bumpSpan SkASSERT "span->fOppValue >= 0"
+    {89, "http___www_mobilizedconsulting_com_.skp", true}, // addTCancel SkASSERT(oIndex > 0);
+    {93, "http___www_simple_living_in_suffolk_co_uk_.skp", true},  // bumpSpan SkASSERT "span->fOppValue >= 0"
 };
 
-/* stats
-97 http___www_brandyandvinca_com_.skp pixelError=3
-95 http___www_into_asia_com_.skp pixelError=12
-93 http___www_lunarplanner_com_.skp pixelError=14
-98 http___www_lovelyitalia_com_.skp pixelError=17
-90 http___www_inter_partner_blogspot_com_.skp pixelError=18
-99 http___www_maxarea_com_.skp pixelError=26
-98 http___www_maroonsnet_org_.skp pixelError=33
-92 http___www_belinaart_ru_.skp pixelError=50
-100 http___www_chroot_ro_.skp pixelError=62
-99 http___www_hsbrands_com_.skp pixelError=98
-95 http___www_tournamentindicator_com_.skp pixelError=122
-93 http___www_businesses_com_au_.skp pixelError=162
-90 http___www_regenesys_net_.skp pixelError=182
-88 http___www_1863544208148625103_c18eac63985503fa85b06358959c1ba27fc36f82_blogspot_com_.skp pixelError=186
-97 http___www_pregacoesevangelica_com_br_.skp pixelError=240
-77 http___www_zhenggang_org_.skp pixelError=284
-96 http___slidesharemailer_com_.skp pixelError=522
-94 http___www_gensteel_com_.skp pixelError=555
-68 http___www_jf_eti_br_.skp pixelError=610
-83 http___www_swishiat_com_.skp pixelError=706
-96 http___www_matusikmissive_com_au_.skp pixelError=2580
-95 http___www_momentumnation_com_.skp pixelError=3938
-92 http___www_rssowl_com_.skp pixelError=5113
-96 http___www_sexxygirl_tv_.skp pixelError=7605
-99 http___www_georgevalah_wordpress_com_.skp pixelError=8386
-78 http___www_furbo_org_.skp pixelError=8656
-78 http___www_djxhemary_wordpress_com_.skp pixelError=8976
-100 http___www_mindcontrolblackassassins_com_.skp pixelError=31950
-98 http___bababillgates_free_fr_.skp pixelError=40237
-98 http___hepatite_ro_.skp pixelError=44370
-86 http___www_somethingwagging_com_.skp pixelError=47794
-84 http___www_beverageuniverse_com_.skp pixelError=65450
-50 http___www_aveksa_com_.skp pixelError=68194
-10 http___www_publiker_pl_.skp pixelError=89997
-61 http___www_dominos_co_id_.skp pixelError=476868
-87 http___www_du_edu_om_.skp time=46
-87 http___www_bigload_de_.skp time=46
-100 http___www_home_forum_com_.skp time=48
-97 http___www_hotamateurchat_com_.skp time=48
-97 http___www_myrsky_com_cn_.skp time=48
-98 http___www_techiegeex_com_.skp time=49
-82 http___www_fashionoutletsofchicago_com_.skp time=50
-77 http___www_dynamischbureau_nl_.skp time=50
-82 http___www_mayihelpu_co_in_.skp time=50
-84 http___www_vbox7_com_user_history_viewers_.skp time=50
-85 http___www_ktokogda_com_.skp time=50
-85 http___www_propertyturkeysale_com_.skp time=50
-85 http___www_51play_com_.skp time=50
-86 http___www_bayalarm_com_.skp time=50
-87 http___www_eaglepictures_com_.skp time=50
-88 http___www_atlasakvaryum_com_.skp time=50
-91 http___www_pioneerchryslerjeep_com_.skp time=50
-94 http___www_thepulsemag_com_.skp time=50
-95 http___www_dcshoes_com_ph_.skp time=50
-96 http___www_montrealmassage_ca_.skp time=50
-96 http___www_jkshahclasses_com_.skp time=50
-96 http___www_webcamconsult_com_.skp time=51
-100 http___www_bsoscblog_com_.skp time=52
-95 http___www_flaktwoods_com_.skp time=53
-91 http___www_qivivo_com_.skp time=54
-90 http___www_unitender_com_.skp time=56
-97 http___www_casinogaming_com_.skp time=56
-97 http___www_rootdownload_com_.skp time=56
-94 http___www_aspa_ev_de_.skp time=57
-98 http___www_tenpieknyswiat_pl_.skp time=57
-93 http___www_transocean_de_.skp time=58
-94 http___www_vdo2_blogspot_com_.skp time=58
-94 http___www_asmaissexy_com_br_.skp time=58
-100 http___www_prefeiturasjm_com_br_.skp time=60
-100 http___www_eduinsuranceclick_blogspot_com_.skp time=60
-96 http___www_bobdunsire_com_.skp time=61
-96 http___www_omgkettlecorn_com_.skp time=61
-85 http___www_fbbsessions_com_.skp time=62
-86 http___www_hector_ru_.skp time=62
-87 http___www_wereldsupporter_nl_.skp time=62
-90 http___www_arello_com_.skp time=62
-93 http___www_bayerplastics_com_.skp time=62
-93 http___www_superandolamovida_com_ar_.skp time=62
-96 http___www_med_rbf_ru_.skp time=62
-81 http___www_carnegiescience_edu_.skp time=65
-87 http___www_asanewengland_com_.skp time=65
-92 http___www_turkce_karakter_appspot_com_.skp time=65
-94 http___www_k3a_org_.skp time=65
-96 http___www_powermaccenter_com_.skp time=65
-98 http___www_avto49_ru_.skp time=67
-100 http___www_hetoldeambaecht_nl_.skp time=68
-95 http___www_marine_ie_.skp time=69
-96 http___www_quebecvapeboutique_com_.skp time=69
-95 http___www_brays_ingles_com_.skp time=70
-100 http___www_lacondesa_com_.skp time=72
-95 http___www_timbarrathai_com_au_.skp time=76
-95 http___www_cuissedegrenouille_com_.skp time=76
-95 http___www_iwama51_ru_.skp time=76
-99 http___www_fotoantologia_it_.skp time=76
-92 http___www_indian_architects_com_.skp time=78
-92 http___www_totalwomanspa_com_.skp time=78
-100 http___www_fachverband_spielhallen_de_.skp time=83
-93 http___www_golshanemehr_ir_.skp time=84
-95 http___www_maryesses_com_.skp time=84
-99 http___www_ddcorp_ca_.skp time=89
-90 http___www_brontops_com_.skp time=89
-94 http___www_robgolding_com_.skp time=89
-91 http___www_tecban_com_br_.skp time=91
-98 http___www_costamesakarate_com_.skp time=100
-95 http___www_monsexyblog_com_.skp time=103
-97 http___www_stornowaygazette_co_uk_.skp time=103
-93 http___www_fitforaframe_com_.skp time=104
-98 http___www_intentionoftheday_com_.skp time=113
-100 http___www_tailgateclothing_com_.skp time=117
-95 http___www_senbros_com_.skp time=118
-93 http___www_lettoblog_com_.skp time=121
-94 http___www_maxineschallenge_com_au_.skp time=125
-95 http___www_savvycard_net_.skp time=127
-95 http___www_open_ac_mu_.skp time=129
-96 http___www_avgindia_in_.skp time=135
-97 http___www_stocktonseaview_com_.skp time=135
-96 http___www_distroller_com_.skp time=142
-94 http___www_travoggalop_dk_.skp time=144
-100 http___www_history_im_.skp time=144
-94 http___www_playradio_sk_.skp time=145
-92 http___www_linglongglass_com_.skp time=151
-97 http___www_bizzna_com_.skp time=151
-96 http___www_spiros_ws_.skp time=154
-91 http___www_rosen_meents_co_il_.skp time=156
-81 http___www_hoteldeluxeportland_com_.skp time=158
-92 http___www_freetennis_org_.skp time=161
-93 http___www_aircharternetwork_com_au_.skp time=161
-94 http___www_austinparks_org_.skp time=165
-89 http___www_bevvy_co_.skp time=168
-91 http___www_sosyalhile_net_.skp time=168
-98 http___www_minvih_gob_ve_.skp time=171
-89 http___www_streetfoodmtl_com_.skp time=172
-92 http___www_loveslatinas_tumblr_com_.skp time=178
-93 http___www_madbites_co_in_.skp time=180
-94 http___www_rocktarah_ir_.skp time=185
-97 http___www_penthouselife_com_.skp time=185
-96 http___www_appymonkey_com_.skp time=196
-92 http___www_pasargadhotels_com_.skp time=203
-99 http___www_marina_mil_pe_.skp time=203
-89 http___www_kays_co_uk_.skp time=205
-77 http___www_334588_com_.skp time=211
-83 http___www_trendbad24_de_.skp time=211
-81 http___www_cdnetworks_co_kr_.skp time=216
-94 http___www_schellgames_com_.skp time=223
-95 http___www_juliaweddingnews_cn_.skp time=230
-92 http___www_xcrafters_pl_.skp time=253
-93 http___www_pondoo_com_.skp time=253
-96 http___www_helsinkicapitalpartners_fi_.skp time=255
-88 http___www_nadtexican_com_.skp time=259
-85 http___www_canstockphoto_hu_.skp time=266
-78 http___www_ecovacs_com_cn_.skp time=271
-93 http___www_brookfieldplaceny_com_.skp time=334
-93 http___www_fmastrengthtraining_com_.skp time=337
-94 http___www_turtleonthebeach_com_.skp time=394
-90 http___www_temptationthemovie_com_.skp time=413
-95 http___www_patongsawaddi_com_.skp time=491
-91 http___www_online_radio_appspot_com_.skp time=511
-68 http___www_richardmiller_co_uk_.skp time=528
-63 http___www_eschrade_com_.skp time=543
-55 http___www_interaction_inf_br_.skp time=625
-38 http___www_huskyliners_com_.skp time=632
-86 http___granda_net_.skp time=1067
-24 http___www_cocacolafm_com_br_.skp time=1081
-*/
+size_t skipOverCount = sizeof(skipOver) / sizeof(skipOver[0]);
 
-size_t skipOverSeptCount = sizeof(skipOverSept) / sizeof(skipOverSept[0]);
+
+/* customize file in/out here */
+/* TODO : add command flag interface */
+#define CHROME_VERSION "1e5dfa4-4a995df"
+#define SUMMARY_RUN 1
+
+#ifdef SK_BUILD_FOR_WIN
+    #define DRIVE_SPEC "D:"
+    #define PATH_SLASH "\\"
+#else
+    #define DRIVE_SPEC ""
+    #define PATH_SLASH "/"
+#endif
+
+#define IN_DIR_PRE  DRIVE_SPEC PATH_SLASH "skps"   PATH_SLASH "slave"
+#define OUT_DIR_PRE DRIVE_SPEC PATH_SLASH "skpOut" PATH_SLASH "slave"
+#define OUT_DIR_SUM DRIVE_SPEC PATH_SLASH "skpOut" PATH_SLASH "summary"
+#define DIR_POST               PATH_SLASH "All"    PATH_SLASH CHROME_VERSION
+
+static const char outOpDir[]     = "opClip";
+static const char outOldDir[]    = "oldClip";
+static const char outStatusDir[] = "statusTest";
+
+static SkString get_in_path(int dirNo, const char* filename) {
+    SkString path;
+    SkASSERT(dirNo);
+    path.appendf("%s%d%s", IN_DIR_PRE, dirNo, DIR_POST);
+    if (!sk_exists(path.c_str())) {
+        SkDebugf("could not read %s\n", path.c_str());
+        return SkString();
+    }
+    if (filename) {
+        path.appendf("%s%s", PATH_SLASH, filename);
+        if (!sk_exists(path.c_str())) {
+            SkDebugf("could not read %s\n", path.c_str());
+            return SkString();
+        }
+    }
+    return path;
+}
+
+static void make_recursive_dir(const SkString& path) {
+    if (sk_exists(path.c_str())) {
+        return;
+    }
+    const char* pathStr = path.c_str();
+    int last = (int) path.size();
+    do {
+        while (last > 0 && pathStr[--last] != PATH_SLASH[0])
+            ;
+        SkASSERT(last > 0);
+        SkString shorter(pathStr, last);
+        if (sk_mkdir(shorter.c_str())) {
+            break;
+        }
+    } while (true);
+    do {
+        while (last < (int) path.size() && pathStr[++last] != PATH_SLASH[0])
+            ;
+        SkString shorter(pathStr, last);
+        SkAssertResult(sk_mkdir(shorter.c_str()));
+    } while (last < (int) path.size());
+}
+
+static SkString get_out_path(int dirNo, const char* dirName) {
+    SkString path;
+    SkASSERT(dirNo);
+    SkASSERT(dirName);
+    path.appendf("%s%d%s%s%s", OUT_DIR_PRE, dirNo, DIR_POST, PATH_SLASH, dirName);
+    make_recursive_dir(path);
+    return path;
+}
+
+static SkString get_sum_path(const char* dirName) {
+    SkString path;
+    SkASSERT(dirName);
+    path.appendf("%s%d%s%s", OUT_DIR_SUM, SUMMARY_RUN, PATH_SLASH, dirName);
+    SkDebugf("%s\n", path.c_str());
+    make_recursive_dir(path);
+    return path;
+}
+
+static SkString make_png_name(const char* filename) {
+    SkString pngName = SkString(filename);
+    pngName.remove(pngName.size() - 3, 3);
+    pngName.append("png");
+    return pngName;
+}
+
+////////////////////////////////////////////////////////
 
 enum TestStep {
     kCompareBits,
@@ -239,6 +167,13 @@
         fScale = 1;
     }
 
+    void init(int dirNo, const SkString& filename) {
+        fDirNo = dirNo;
+        strcpy(fFilename, filename.c_str());
+        fTestStep = kCompareBits;
+        fScale = 1;
+    }
+
     SkString status() {
         SkString outStr;
         outStr.printf("%s %d %d\n", fFilename, fPixelError, fTime);
@@ -262,14 +197,6 @@
 
     }
 
-    static void Test(int dirNo, const char* filename, TestStep testStep) {
-        TestResult test;
-        test.init(dirNo);
-        test.fTestStep = testStep;
-        strcpy(test.fFilename, filename);
-        test.testOne();
-    }
-
     void test(int dirNo, const SkString& filename) {
         init(dirNo);
         strcpy(fFilename, filename.c_str());
@@ -308,28 +235,19 @@
 };
 
 struct TestState {
-    void init(int dirNo, skiatest::Reporter* reporter) {
-        fReporter = reporter;
+    void init(int dirNo) {
         fResult.init(dirNo);
     }
 
     SkTDArray<SortByPixel> fPixelWorst;
     SkTDArray<SortByTime> fSlowest;
-    skiatest::Reporter* fReporter;
     TestResult fResult;
 };
 
 struct TestRunner {
-    TestRunner(skiatest::Reporter* reporter, int threadCount)
-        : fNumThreads(threadCount)
-        , fReporter(reporter) {
-    }
-
     ~TestRunner();
     void render();
-    int fNumThreads;
     SkTDArray<class TestRunnable*> fRunnables;
-    skiatest::Reporter* fReporter;
 };
 
 class TestRunnable : public SkRunnable {
@@ -347,7 +265,7 @@
 class TestRunnableDir : public TestRunnable {
 public:
     TestRunnableDir(void (*testFun)(TestState*), int dirNo, TestRunner* runner) {
-        fState.init(dirNo, runner->fReporter);
+        fState.init(dirNo);
         fTestFun = testFun;
     }
 
@@ -356,7 +274,7 @@
 class TestRunnableFile : public TestRunnable {
 public:
     TestRunnableFile(void (*testFun)(TestState*), int dirNo, const char* name, TestRunner* runner) {
-        fState.init(dirNo, runner->fReporter);
+        fState.init(dirNo);
         strcpy(fState.fResult.fFilename, name);
         fTestFun = testFun;
     }
@@ -377,82 +295,14 @@
 }
 
 void TestRunner::render() {
-    SkThreadPool pool(fNumThreads);
+    SkTaskGroup tg;
     for (int index = 0; index < fRunnables.count(); ++ index) {
-        pool.add(fRunnables[index]);
+        tg.add(fRunnables[index]);
     }
 }
 
 ////////////////////////////////////////////////
 
-static const char outOpDir[] = OUT_DIR "opClip";
-static const char outOldDir[] = OUT_DIR "oldClip";
-static const char outSkpDir[] = OUT_DIR "skpTest";
-static const char outDiffDir[] = OUT_DIR "outTest";
-static const char outStatusDir[] = OUT_DIR "statusTest";
-
-static SkString make_filepath(int dirNo, const char* dir, const char* name) {
-    SkString path(dir);
-    if (dirNo) {
-        path.appendf("%d", dirNo);
-    }
-    path.append(PATH_SLASH);
-    path.append(name);
-    return path;
-}
-
-static SkString make_in_dir_name(int dirNo) {
-    SkString dirName(IN_DIR);
-    dirName.appendf("%d", dirNo);
-    if (!sk_exists(dirName.c_str())) {
-        SkDebugf("could not read dir %s\n", dirName.c_str());
-        return SkString();
-    }
-    return dirName;
-}
-
-static SkString make_stat_dir_name(int dirNo) {
-    SkString dirName(outStatusDir);
-    dirName.appendf("%d", dirNo);
-    if (!sk_exists(dirName.c_str())) {
-        SkDebugf("could not read dir %s\n", dirName.c_str());
-        return SkString();
-    }
-    return dirName;
-}
-
-static bool make_one_out_dir(const char* outDirStr) {
-    SkString outDir = make_filepath(0, outDirStr, "");
-    if (!sk_exists(outDir.c_str())) {
-        if (!sk_mkdir(outDir.c_str())) {
-            SkDebugf("could not create dir %s\n", outDir.c_str());
-            return false;
-        }
-    }
-    return true;
-}
-
-static bool make_out_dirs() {
-    SkString outDir = make_filepath(0, OUT_DIR, "");
-    if (!sk_exists(outDir.c_str())) {
-        if (!sk_mkdir(outDir.c_str())) {
-            SkDebugf("could not create dir %s\n", outDir.c_str());
-            return false;
-        }
-    }
-    return make_one_out_dir(outOldDir)
-            && make_one_out_dir(outOpDir)
-            && make_one_out_dir(outSkpDir)
-            && make_one_out_dir(outDiffDir)
-            && make_one_out_dir(outStatusDir);
-}
-
-static SkString make_png_name(const char* filename) {
-    SkString pngName = SkString(filename);
-    pngName.remove(pngName.size() - 3, 3);
-    pngName.append("png");
-    return pngName;
-}
 
 static int similarBits(const SkBitmap& gr, const SkBitmap& sk) {
     const int kRowCount = 3;
@@ -539,22 +389,21 @@
 
 static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) {
     canvas->save();
-    int pWidth = pic->width();
-    int pHeight = pic->height();
-    const int maxDimension = 1000;
+    SkScalar pWidth = pic->cullRect().width();
+    SkScalar pHeight = pic->cullRect().height();
+    const SkScalar maxDimension = 1000.0f;
     const int slices = 3;
-    int xInterval = SkTMax(pWidth - maxDimension, 0) / (slices - 1);
-    int yInterval = SkTMax(pHeight - maxDimension, 0) / (slices - 1);
-    SkRect rect = {0, 0, SkIntToScalar(SkTMin(maxDimension, pWidth)),
-            SkIntToScalar(SkTMin(maxDimension, pHeight))};
+    SkScalar xInterval = SkTMax(pWidth - maxDimension, 0.0f) / (slices - 1);
+    SkScalar yInterval = SkTMax(pHeight - maxDimension, 0.0f) / (slices - 1);
+    SkRect rect = {0, 0, SkTMin(maxDimension, pWidth), SkTMin(maxDimension, pHeight) };
     canvas->clipRect(rect);
     SkMSec start = SkTime::GetMSecs();
     for (int x = 0; x < slices; ++x) {
         for (int y = 0; y < slices; ++y) {
-            pic->draw(canvas);
-            canvas->translate(0, SkIntToScalar(yInterval));
+            pic->playback(canvas);
+            canvas->translate(0, yInterval);
         }
-        canvas->translate(SkIntToScalar(xInterval), SkIntToScalar(-yInterval * slices));
+        canvas->translate(xInterval, -yInterval * slices);
     }
     SkMSec end = SkTime::GetMSecs();
     canvas->restore();
@@ -567,16 +416,16 @@
         canvas->save();
         canvas->scale(1.0f / scale, 1.0f / scale);
     }
-    pic->draw(canvas);
+    pic->playback(canvas);
     if (scale != 1) {
         canvas->restore();
     }
 }
 
 static void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) {
-    SkString outFile = make_filepath(0, outDir, pngName);
-    if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap,
-            SkImageEncoder::kPNG_Type, 100)) {
+    SkString outFile = get_sum_path(outDir);
+    outFile.appendf("%s%s", PATH_SLASH, pngName);
+    if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100)) {
         SkDebugf("unable to encode gr %s (width=%d height=%d)\n", pngName,
                     bitmap.width(), bitmap.height());
     }
@@ -607,7 +456,7 @@
             strncpy(DEBUG_FILENAME_STRING, "", DEBUG_FILENAME_STRING_LENGTH);
         }
     #endif
-        SkString path = make_filepath(fDirNo, IN_DIR, fFilename);
+        SkString path = get_in_path(fDirNo, fFilename);
         SkFILEStream stream(path.c_str());
         if (!stream.isValid()) {
             SkDebugf("invalid stream %s\n", path.c_str());
@@ -618,24 +467,23 @@
             SkDebugf("unable to decode %s\n", fFilename);
             goto finish;
         }
-        int width = pic->width();
-        int height = pic->height();
+        SkScalar width = pic->cullRect().width();
+        SkScalar height = pic->cullRect().height();
         SkBitmap oldBitmap, opBitmap;
         fScale = 1;
         while (width / fScale > 32767 || height / fScale > 32767) {
             ++fScale;
         }
         do {
-            int dimX = (width + fScale - 1) / fScale;
-            int dimY = (height + fScale - 1) / fScale;
-            if (oldBitmap.allocN32Pixels(dimX, dimY) &&
-                opBitmap.allocN32Pixels(dimX, dimY)) {
+            int dimX = SkScalarCeilToInt(width / fScale);
+            int dimY = SkScalarCeilToInt(height / fScale);
+            if (oldBitmap.tryAllocN32Pixels(dimX, dimY) && opBitmap.tryAllocN32Pixels(dimX, dimY)) {
                 break;
             }
             SkDebugf("-%d-", fScale);
         } while (++fScale < 256);
         if (fScale >= 256) {
-            SkDebugf("unable to allocate bitmap for %s (w=%d h=%d)\n", fFilename,
+            SkDebugf("unable to allocate bitmap for %s (w=%f h=%f)\n", fFilename,
                     width, height);
             goto finish;
         }
@@ -665,189 +513,249 @@
     }
 }
 
-static SkString makeStatusString(int dirNo) {
-    SkString statName;
-    statName.printf("stats%d.txt", dirNo);
-    SkString statusFile = make_filepath(0, outStatusDir, statName.c_str());
-    return statusFile;
+DEFINE_string2(match, m, "PathOpsSkpClipThreaded",
+        "[~][^]substring[$] [...] of test name to run.\n"
+        "Multiple matches may be separated by spaces.\n"
+        "~ causes a matching test to always be skipped\n"
+        "^ requires the start of the test to match\n"
+        "$ requires the end of the test to match\n"
+        "^ and $ requires an exact match\n"
+        "If a test does not match any list entry,\n"
+        "it is skipped unless some list entry starts with ~");
+DEFINE_string2(dir, d, NULL, "range of directories (e.g., 1-100)");
+DEFINE_string2(skp, s, NULL, "skp to test");
+DEFINE_bool2(single, z, false, "run tests on a single thread internally.");
+DEFINE_int32(testIndex, 0, "override local test index (PathOpsSkpClipOneOff only).");
+DEFINE_bool2(verbose, v, false, "enable verbose output.");
+
+static bool verbose() {
+    return FLAGS_verbose;
 }
 
-class PreParser {
+class Dirs {
 public:
-    PreParser(int dirNo, bool threaded)
-        : fDirNo(dirNo)
-        , fIndex(0)
-        , fThreaded(threaded) {
-        SkString statusPath = makeStatusString(dirNo);
-        if (!sk_exists(statusPath.c_str())) {
-            return;
+    Dirs() {
+        reset();
+        sk_bzero(fRun, sizeof(fRun));
+        fSet = false;
+    }
+
+    int first() const {
+        int index = 0;
+        while (++index < kMaxDir) {
+            if (fRun[index]) {
+                return index;
+            }
         }
-        SkFILEStream reader;
-        reader.setPath(statusPath.c_str());
-        while (fetch(reader, &fResults.push_back()))
+        SkASSERT(0);
+        return -1;
+    }
+
+    int last() const {
+        int index = kMaxDir;
+        while (--index > 0 && !fRun[index])
             ;
-        fResults.pop_back();
+        return index;
     }
 
-    bool fetch(SkFILEStream& reader, TestResult* result) {
-        char c;
-        int i = 0;
-        result->init(fDirNo);
-        result->fPixelError = 0;
-        result->fTime = 0;
-        do {
-            bool readOne = reader.read(&c, 1) != 0;
-            if (!readOne) {
-//                SkASSERT(i == 0);   // the current text may be incomplete -- if so, ignore it
-                return false;
+    int next() {
+        while (++fIndex < kMaxDir) {
+            if (fRun[fIndex]) {
+                return fIndex;
             }
-            if (c == ' ') {
-                result->fFilename[i++] = '\0';
-                break;
-            }
-            result->fFilename[i++] = c;
-            SkASSERT(i < kMaxLength);
-        } while (true);
-        do {
-            if (!reader.read(&c, 1)) {
-                return false;
-            }
-            if (c == ' ') {
-                break;
-            }
-            SkASSERT(c >= '0' && c <= '9');
-            result->fPixelError = result->fPixelError * 10 + (c - '0');
-        } while (true);
-        bool minus = false;
-        do {
-            if (!reader.read(&c, 1)) {
-                return false;
-            }
-            if (c == '\n') {
-                break;
-            }
-            if (c == '-') {
-                minus = true;
-                continue;
-            }
-            SkASSERT(c >= '0' && c <= '9');
-            result->fTime = result->fTime * 10 + (c - '0');
-        } while (true);
-        if (minus) {
-            result->fTime = -result->fTime;
         }
-        return true;
+        return -1;
     }
 
-    bool match(const SkString& filename, SkFILEWStream* stream, TestResult* result) {
-        if (fThreaded) {
-            for (int index = 0; index < fResults.count(); ++index) {
-                const TestResult& test = fResults[index];
-                if (filename.equals(test.fFilename)) {
-                    *result = test;
-                    SkString outStr(result->status());
-                    stream->write(outStr.c_str(), outStr.size());
-                    return true;
-                }
-            }
-        } else if (fIndex < fResults.count()) {
-            *result = fResults[fIndex++];
-            SkASSERT(filename.equals(result->fFilename));
-            SkString outStr(result->status());
-            stream->write(outStr.c_str(), outStr.size());
-            return true;
+    void reset() {
+        fIndex = -1;
+    }
+
+    void set(int start, int end) {
+        while (start < end) {
+            fRun[start++] = 1;
         }
-        return false;
+        fSet = true;
+    }
+
+    void setDefault() {
+        if (!fSet) {
+            set(1, 100);
+        }
     }
 
 private:
-    int fDirNo;
+    enum {
+         kMaxDir = 101
+    };
+    char fRun[kMaxDir];
     int fIndex;
-    SkTArray<TestResult, true> fResults;
-    bool fThreaded;
-};
+    bool fSet;
+} gDirs;
 
-static bool doOneDir(TestState* state, bool threaded) {
-    int dirNo = state->fResult.fDirNo;
-    skiatest::Reporter* reporter = state->fReporter;
-    SkString dirName = make_in_dir_name(dirNo);
+class Filenames {
+public:
+    Filenames()
+        : fIndex(-1) {
+    }
+
+    const char* next() {
+        while (fNames && ++fIndex < fNames->count()) {
+            return (*fNames)[fIndex];
+        }
+        return NULL;
+    }
+
+    void set(const SkCommandLineFlags::StringArray& names) {
+        fNames = &names;
+    }
+
+private:
+    int fIndex;
+    const SkCommandLineFlags::StringArray* fNames;
+} gNames;
+
+static bool buildTestDir(int dirNo, int firstDirNo,
+        SkTDArray<TestResult>* tests, SkTDArray<SortByName*>* sorted) {
+    SkString dirName = get_out_path(dirNo, outStatusDir);
     if (!dirName.size()) {
         return false;
     }
     SkOSFile::Iter iter(dirName.c_str(), "skp");
     SkString filename;
-    int testCount = 0;
-    PreParser preParser(dirNo, threaded);
-    SkFILEWStream statusStream(makeStatusString(dirNo).c_str());
     while (iter.next(&filename)) {
-        for (size_t index = 0; index < skipOverSeptCount; ++index) {
-            if (skipOverSept[index].directory == dirNo
-                    && strcmp(filename.c_str(), skipOverSept[index].filename) == 0) {
-                goto checkEarlyExit;
+        TestResult test;
+        test.init(dirNo);
+        SkString spaceFile(filename);
+        char* spaces = spaceFile.writable_str();
+        int spaceSize = (int) spaceFile.size();
+        for (int index = 0; index < spaceSize; ++index) {
+            if (spaces[index] == '.') {
+                spaces[index] = ' ';
             }
         }
-        if (preParser.match(filename, &statusStream, &state->fResult)) {
-            (void) addError(state, state->fResult);
-            ++testCount;
-            goto checkEarlyExit;
+        int success = sscanf(spaces, "%s %d %d skp", test.fFilename,
+                &test.fPixelError, &test.fTime);
+        if (success < 3) {
+            SkDebugf("failed to scan %s matched=%d\n", filename.c_str(), success);
+            return false;
         }
-        {
-            TestResult& result = state->fResult;
-            result.test(dirNo, filename);
-            SkString outStr(result.status());
-            statusStream.write(outStr.c_str(), outStr.size());
-            statusStream.flush();
-            if (addError(state, result)) {
-                SkDebugf("%s", result.progress().c_str());
-            }
-        }
-        ++testCount;
-        if (reporter->verbose()) {
-            SkDebugf(".");
-            if (++testCount % 100 == 0) {
-                SkDebugf("%d\n", testCount);
-            }
-        }
-checkEarlyExit:
-        if (0 && testCount >= 1) {
-            return true;
+        *tests[dirNo - firstDirNo].append() = test;
+    }
+    if (!sorted) {
+        return true;
+    }
+    SkTDArray<TestResult>& testSet = tests[dirNo - firstDirNo];
+    int count = testSet.count();
+    for (int index = 0; index < count; ++index) {
+        *sorted[dirNo - firstDirNo].append() = (SortByName*) &testSet[index];
+    }
+    if (sorted[dirNo - firstDirNo].count()) {
+        SkTQSort<SortByName>(sorted[dirNo - firstDirNo].begin(),
+                sorted[dirNo - firstDirNo].end() - 1);
+        if (verbose()) {
+            SkDebugf("+");
         }
     }
     return true;
 }
 
-static bool initTest() {
+static void testSkpClip(TestState* data) {
+    data->fResult.testOne();
+    SkString statName(data->fResult.fFilename);
+    SkASSERT(statName.endsWith(".skp"));
+    statName.remove(statName.size() - 4, 4);
+    statName.appendf(".%d.%d.skp", data->fResult.fPixelError, data->fResult.fTime);
+    SkString statusFile = get_out_path(data->fResult.fDirNo, outStatusDir);
+    if (!statusFile.size()) {
+        SkDebugf("failed to create %s", statusFile.c_str());
+        return;
+    }
+    statusFile.appendf("%s%s", PATH_SLASH, statName.c_str());
+    SkFILE* file = sk_fopen(statusFile.c_str(), kWrite_SkFILE_Flag);
+    if (!file) {
+            SkDebugf("failed to create %s", statusFile.c_str());
+            return;
+    }
+    sk_fclose(file);
+    if (verbose()) {
+        if (data->fResult.fPixelError || data->fResult.fTime) {
+            SkDebugf("%s", data->fResult.progress().c_str());
+        } else {
+            SkDebugf(".");
+        }
+    }
+}
+
+bool Less(const SortByName& a, const SortByName& b);
+bool Less(const SortByName& a, const SortByName& b) {
+    return a < b;
+}
+
+static bool doOneDir(TestState* state, bool threaded) {
+    int dirNo = state->fResult.fDirNo;
+    SkString dirName = get_in_path(dirNo, NULL);
+    if (!dirName.size()) {
+        return false;
+    }
+    SkTDArray<TestResult> tests[1];
+    SkTDArray<SortByName*> sorted[1];
+    if (!buildTestDir(dirNo, dirNo, tests, sorted)) {
+        return false;
+    }
+    SkOSFile::Iter iter(dirName.c_str(), "skp");
+    SkString filename;
+    while (iter.next(&filename)) {
+        for (size_t index = 0; index < skipOverCount; ++index) {
+            if (skipOver[index].directory == dirNo
+                    && strcmp(filename.c_str(), skipOver[index].filename) == 0) {
+                goto checkEarlyExit;
+            }
+        }
+        {
+            SortByName name;
+            name.init(dirNo);
+            strncpy(name.fFilename, filename.c_str(), filename.size() - 4);  // drop .skp
+            int count = sorted[0].count();
+            int idx = SkTSearch<SortByName, Less>(sorted[0].begin(), count, &name, sizeof(&name));
+            if (idx >= 0) {
+                SortByName* found = sorted[0][idx];
+                (void) addError(state, *found);
+                continue;
+            }
+            TestResult test;
+            test.init(dirNo, filename);
+            state->fResult = test;
+            testSkpClip(state);
+#if 0 // artificially limit to a few while debugging code
+            static int debugLimit = 0;
+            if (++debugLimit == 5) {
+                return true;
+            }
+#endif
+        }
+checkEarlyExit:
+        ;
+    }
+    return true;
+}
+
+static void initTest() {
 #if !defined SK_BUILD_FOR_WIN && !defined SK_BUILD_FOR_MAC
     SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true);
     SK_CONF_SET("images.png.suppressDecoderWarnings", true);
 #endif
-    return make_out_dirs();
 }
 
-static bool initUberTest(int firstDirNo, int lastDirNo) {
-    if (!initTest()) {
-        return false;
-    }
-    for (int index = firstDirNo; index <= lastDirNo; ++index) {
-        SkString statusDir(outStatusDir);
-        statusDir.appendf("%d", index);
-        if (!make_one_out_dir(statusDir.c_str())) {
-            return false;
-        }
-    }
-    return true;
-}
-
-
 static void testSkpClipEncode(TestState* data) {
     data->fResult.testOne();
-    if (data->fReporter->verbose()) {
-       SkDebugf("+");
+    if (verbose()) {
+        SkDebugf("+");
     }
 }
 
-static void encodeFound(skiatest::Reporter* reporter, TestState& state) {
-    if (reporter->verbose()) {
+static void encodeFound(TestState& state) {
+    if (verbose()) {
         if (state.fPixelWorst.count()) {
             SkTDArray<SortByPixel*> worst;
             for (int index = 0; index < state.fPixelWorst.count(); ++index) {
@@ -873,9 +781,7 @@
             }
         }
     }
-
-    int threadCount = reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1;
-    TestRunner testRunner(reporter, threadCount);
+    TestRunner testRunner;
     for (int index = 0; index < state.fPixelWorst.count(); ++index) {
         const TestResult& result = state.fPixelWorst[index];
         SkString filename(result.fFilename);
@@ -886,28 +792,50 @@
                 (&testSkpClipEncode, result.fDirNo, filename.c_str(), &testRunner));
     }
     testRunner.render();
-#if 0
-    for (int index = 0; index < state.fPixelWorst.count(); ++index) {
-        const TestResult& result = state.fPixelWorst[index];
-        SkString filename(result.fFilename);
-        if (!filename.endsWith(".skp")) {
-            filename.append(".skp");
-        }
-        TestResult::Test(result.fDirNo, filename.c_str(), kEncodeFiles);
-        if (reporter->verbose()) SkDebugf("+");
-    }
-#endif
 }
 
-DEF_TEST(PathOpsSkpClip, reporter) {
-    if (!initTest()) {
-        return;
-    }
+class Test {
+public:
+    Test() {}
+    virtual ~Test() {}
+
+    const char* getName() { onGetName(&fName); return fName.c_str(); }
+    void run() { onRun(); }
+
+protected:
+    virtual void onGetName(SkString*) = 0;
+    virtual void onRun() = 0;
+
+private:
+    SkString    fName;
+};
+
+typedef SkTRegistry<Test*(*)(void*)> TestRegistry;
+
+#define DEF_TEST(name)                                        \
+    static void test_##name();                       \
+    class name##Class : public Test {                                   \
+    public:                                                             \
+        static Test* Factory(void*) { return SkNEW(name##Class); }      \
+    protected:                                                          \
+        virtual void onGetName(SkString* name) SK_OVERRIDE {            \
+            name->set(#name);                                           \
+        }                                                               \
+        virtual void onRun() SK_OVERRIDE { test_##name(); } \
+    };                                                                  \
+    static TestRegistry gReg_##name##Class(name##Class::Factory);       \
+    static void test_##name()
+
+DEF_TEST(PathOpsSkpClip) {
+    gDirs.setDefault();
+    initTest();
     SkTArray<TestResult, true> errors;
     TestState state;
-    state.init(0, reporter);
-    for (int dirNo = 1; dirNo <= 100; ++dirNo) {
-        if (reporter->verbose()) {
+    state.init(0);
+    int dirNo;
+    gDirs.reset();
+    while ((dirNo = gDirs.next()) > 0) {
+        if (verbose()) {
             SkDebugf("dirNo=%d\n", dirNo);
         }
         state.fResult.fDirNo = dirNo;
@@ -915,28 +843,28 @@
             break;
         }
     }
-    encodeFound(reporter, state);
+    encodeFound(state);
 }
 
 static void testSkpClipMain(TestState* data) {
         (void) doOneDir(data, true);
 }
 
-DEF_TEST(PathOpsSkpClipThreaded, reporter) {
-    if (!initTest()) {
-        return;
-    }
-    int threadCount = reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1;
-    TestRunner testRunner(reporter, threadCount);
-    const int firstDirNo = 1;
-    for (int dirNo = firstDirNo; dirNo <= 100; ++dirNo) {
+DEF_TEST(PathOpsSkpClipThreaded) {
+    gDirs.setDefault();
+    initTest();
+    TestRunner testRunner;
+    int dirNo;
+    gDirs.reset();
+    while ((dirNo = gDirs.next()) > 0) {
         *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnableDir,
                 (&testSkpClipMain, dirNo, &testRunner));
     }
     testRunner.render();
     TestState state;
-    state.init(0, reporter);
-    for (int dirNo = firstDirNo; dirNo <= 100; ++dirNo) {
+    state.init(0);
+    gDirs.reset();
+    while ((dirNo = gDirs.next()) > 0) {
         TestState& testState = testRunner.fRunnables[dirNo - 1]->fState;
         SkASSERT(testState.fResult.fDirNo == dirNo);
         for (int inner = 0; inner < testState.fPixelWorst.count(); ++inner) {
@@ -946,124 +874,58 @@
             addError(&state, testState.fSlowest[inner]);
         }
     }
-    encodeFound(reporter, state);
+    encodeFound(state);
 }
 
-static void testSkpClipUber(TestState* data) {
-    data->fResult.testOne();
-    SkString dirName = make_stat_dir_name(data->fResult.fDirNo);
-    if (!dirName.size()) {
-        return;
-    }
-    SkString statName(data->fResult.fFilename);
-    SkASSERT(statName.endsWith(".skp"));
-    statName.remove(statName.size() - 4, 4);
-    statName.appendf(".%d.%d.skp", data->fResult.fPixelError, data->fResult.fTime);
-    SkString statusFile = make_filepath(data->fResult.fDirNo, outStatusDir, statName.c_str());
-    SkFILE* file = sk_fopen(statusFile.c_str(), kWrite_SkFILE_Flag);
-    if (!file) {
-            SkDebugf("failed to create %s", statusFile.c_str());
-            return;
-    }
-    sk_fclose(file);
-    if (data->fReporter->verbose()) {
-        if (data->fResult.fPixelError || data->fResult.fTime) {
-            SkDebugf("%s", data->fResult.progress().c_str());
-        } else {
-            SkDebugf(".");
-        }
-    }
-}
-
-static bool buildTests(skiatest::Reporter* reporter, int firstDirNo, int lastDirNo, SkTDArray<TestResult>* tests,
-        SkTDArray<SortByName*>* sorted) {
-    for (int dirNo = firstDirNo; dirNo <= lastDirNo; ++dirNo) {
-        SkString dirName = make_stat_dir_name(dirNo);
-        if (!dirName.size()) {
+static bool buildTests(SkTDArray<TestResult>* tests, SkTDArray<SortByName*>* sorted) {
+    int firstDirNo = gDirs.first();
+    int dirNo;
+    while ((dirNo = gDirs.next()) > 0) {
+        if (!buildTestDir(dirNo, firstDirNo, tests, sorted)) {
             return false;
         }
-        SkOSFile::Iter iter(dirName.c_str(), "skp");
-        SkString filename;
-        while (iter.next(&filename)) {
-            TestResult test;
-            test.init(dirNo);
-            SkString spaceFile(filename);
-            char* spaces = spaceFile.writable_str();
-            int spaceSize = (int) spaceFile.size();
-            for (int index = 0; index < spaceSize; ++index) {
-                if (spaces[index] == '.') {
-                    spaces[index] = ' ';
-                }
-            }
-            int success = sscanf(spaces, "%s %d %d skp", test.fFilename,
-                    &test.fPixelError, &test.fTime);
-            if (success < 3) {
-                SkDebugf("failed to scan %s matched=%d\n", filename.c_str(), success);
-                return false;
-            }
-            *tests[dirNo - firstDirNo].append() = test;
-        }
-        if (!sorted) {
-            continue;
-        }
-        SkTDArray<TestResult>& testSet = tests[dirNo - firstDirNo];
-        int count = testSet.count();
-        for (int index = 0; index < count; ++index) {
-            *sorted[dirNo - firstDirNo].append() = (SortByName*) &testSet[index];
-        }
-        if (sorted[dirNo - firstDirNo].count()) {
-            SkTQSort<SortByName>(sorted[dirNo - firstDirNo].begin(),
-                    sorted[dirNo - firstDirNo].end() - 1);
-            if (reporter->verbose()) {
-                SkDebugf("+");
-            }
-       }
     }
     return true;
 }
 
-bool Less(const SortByName& a, const SortByName& b);
-bool Less(const SortByName& a, const SortByName& b) {
-    return a < b;
-}
-
-DEF_TEST(PathOpsSkpClipUberThreaded, reporter) {
-    const int firstDirNo = 1;
-    const int lastDirNo = 100;
-    if (!initUberTest(firstDirNo, lastDirNo)) {
+DEF_TEST(PathOpsSkpClipUberThreaded) {
+    gDirs.setDefault();
+    const int firstDirNo = gDirs.next();
+    const int lastDirNo = gDirs.last();
+    initTest();
+    int dirCount = lastDirNo - firstDirNo + 1;
+    SkAutoTDeleteArray<SkTDArray<TestResult> > tests(new SkTDArray<TestResult>[dirCount]);
+    SkAutoTDeleteArray<SkTDArray<SortByName*> > sorted(new SkTDArray<SortByName*>[dirCount]);
+    if (!buildTests(tests.get(), sorted.get())) {
         return;
     }
-    const int dirCount = lastDirNo - firstDirNo + 1;
-    SkTDArray<TestResult> tests[dirCount];
-    SkTDArray<SortByName*> sorted[dirCount];
-    if (!buildTests(reporter, firstDirNo, lastDirNo, tests, sorted)) {
-        return;
-    }
-    int threadCount = reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1;
-    TestRunner testRunner(reporter, threadCount);
-    for (int dirNo = firstDirNo; dirNo <= lastDirNo; ++dirNo) {
-        SkString dirName = make_in_dir_name(dirNo);
+    TestRunner testRunner;
+    int dirNo;
+    gDirs.reset();
+    while ((dirNo = gDirs.next()) > 0) {
+        SkString dirName = get_in_path(dirNo, NULL);
         if (!dirName.size()) {
             continue;
         }
         SkOSFile::Iter iter(dirName.c_str(), "skp");
         SkString filename;
         while (iter.next(&filename)) {
-            int count;
-            SortByName name;
-            for (size_t index = 0; index < skipOverSeptCount; ++index) {
-                if (skipOverSept[index].directory == dirNo
-                        && strcmp(filename.c_str(), skipOverSept[index].filename) == 0) {
+            for (size_t index = 0; index < skipOverCount; ++index) {
+                if (skipOver[index].directory == dirNo
+                        && strcmp(filename.c_str(), skipOver[index].filename) == 0) {
                     goto checkEarlyExit;
                 }
             }
-            name.init(dirNo);
-            strncpy(name.fFilename, filename.c_str(), filename.size() - 4);  // drop .skp
-            count = sorted[dirNo - firstDirNo].count();
-            if (SkTSearch<SortByName, Less>(sorted[dirNo - firstDirNo].begin(),
-                    count, &name, sizeof(&name)) < 0) {
-                *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnableFile,
-                        (&testSkpClipUber, dirNo, filename.c_str(), &testRunner));
+            {
+                SortByName name;
+                name.init(dirNo);
+                strncpy(name.fFilename, filename.c_str(), filename.size() - 4);  // drop .skp
+                int count = sorted.get()[dirNo - firstDirNo].count();
+                if (SkTSearch<SortByName, Less>(sorted.get()[dirNo - firstDirNo].begin(),
+                        count, &name, sizeof(&name)) < 0) {
+                    *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnableFile,
+                            (&testSkpClip, dirNo, filename.c_str(), &testRunner));
+                }
             }
     checkEarlyExit:
             ;
@@ -1071,13 +933,13 @@
 
     }
     testRunner.render();
-    SkTDArray<TestResult> results[dirCount];
-    if (!buildTests(reporter, firstDirNo, lastDirNo, results, NULL)) {
+    SkAutoTDeleteArray<SkTDArray<TestResult> > results(new SkTDArray<TestResult>[dirCount]);
+    if (!buildTests(results.get(), NULL)) {
         return;
     }
     SkTDArray<TestResult> allResults;
     for (int dirNo = firstDirNo; dirNo <= lastDirNo; ++dirNo) {
-        SkTDArray<TestResult>& array = results[dirNo - firstDirNo];
+        SkTDArray<TestResult>& array = results.get()[dirNo - firstDirNo];
         allResults.append(array.count(), array.begin());
     }
     int allCount = allResults.count();
@@ -1100,22 +962,144 @@
             *state.fSlowest.append() = *times[allCount - inner - 1];
         }
     }
-    encodeFound(reporter, state);
+    encodeFound(state);
 }
 
-DEF_TEST(PathOpsSkpClipOneOff, reporter) {
-    if (!initTest()) {
-        return;
+DEF_TEST(PathOpsSkpClipOneOff) {
+    const int testIndex = FLAGS_testIndex;
+    int dirNo = gDirs.next();
+    if (dirNo < 0) {
+        dirNo = skipOver[testIndex].directory;
     }
-    const int testIndex = 43 - 37;
-    int dirNo = skipOverSept[testIndex].directory;
-    SkAssertResult(make_in_dir_name(dirNo).size());
-    SkString filename(skipOverSept[testIndex].filename);
+    const char* skp = gNames.next();
+    if (!skp) {
+        skp = skipOver[testIndex].filename;
+    }
+    initTest();
+    SkAssertResult(get_in_path(dirNo, skp).size());
+    SkString filename(skp);
     TestResult state;
     state.test(dirNo, filename);
-    if (reporter->verbose()) {
+    if (verbose()) {
         SkDebugf("%s", state.status().c_str());
     }
     state.fTestStep = kEncodeFiles;
     state.testOne();
 }
+
+DEF_TEST(PathOpsTestSkipped) {
+    for (size_t index = 0; index < skipOverCount; ++index) {
+        const SkipOverTest& skip = skipOver[index];
+        if (!skip.blamePathOps) {
+            continue;
+        }
+        int dirNo = skip.directory;
+        const char* skp = skip.filename;
+        initTest();
+        SkAssertResult(get_in_path(dirNo, skp).size());
+        SkString filename(skp);
+        TestResult state;
+        state.test(dirNo, filename);
+        if (verbose()) {
+            SkDebugf("%s", state.status().c_str());
+        }
+        state.fTestStep = kEncodeFiles;
+        state.testOne();
+    }
+}
+
+DEF_TEST(PathOpsCopyFails) {
+    FLAGS_verbose = true;
+    for (size_t index = 0; index < skipOverCount; ++index) {
+        int dirNo = skipOver[index].directory;
+        SkDebugf("mkdir -p " IN_DIR_PRE "%d" DIR_POST "\n", dirNo);
+    }
+    for (size_t index = 0; index < skipOverCount; ++index) {
+        int dirNo = skipOver[index].directory;
+        const char* filename = skipOver[index].filename;
+        SkDebugf("rsync -av cary-linux.cnc:/tera" PATH_SLASH "skps" PATH_SLASH "slave"
+            "%d" DIR_POST "/%s " IN_DIR_PRE "%d" DIR_POST "\n", dirNo, filename, dirNo);
+    }
+}
+
+template TestRegistry* TestRegistry::gHead;
+
+class Iter {
+public:
+    Iter() { this->reset(); }
+    void reset() { fReg = TestRegistry::Head(); }
+
+    Test* next() {
+        if (fReg) {
+            TestRegistry::Factory fact = fReg->factory();
+            fReg = fReg->next();
+            Test* test = fact(NULL);
+            return test;
+        }
+        return NULL;
+    }
+
+private:
+    const TestRegistry* fReg;
+};
+
+int tool_main(int argc, char** argv);
+int tool_main(int argc, char** argv) {
+    SetupCrashHandler();
+    SkCommandLineFlags::SetUsage("");
+    SkCommandLineFlags::Parse(argc, argv);
+    SkGraphics::Init();
+    SkString header("PathOps SkpClip:");
+    if (!FLAGS_match.isEmpty()) {
+        header.appendf(" --match");
+        for (int index = 0; index < FLAGS_match.count(); ++index) {
+            header.appendf(" %s", FLAGS_match[index]);
+        }
+    }
+    if (!FLAGS_dir.isEmpty()) {
+        int count = FLAGS_dir.count();
+        for (int i = 0; i < count; ++i) {
+            const char* range = FLAGS_dir[i];
+            const char* dash = strchr(range, '-');
+            if (!dash) {
+                dash = strchr(range, ',');
+            }
+            int first = atoi(range);
+            int last = dash ? atoi(dash + 1) : first;
+            if (!first || !last) {
+                SkDebugf("couldn't parse --dir %s\n", range);
+                return 1;
+            }
+            gDirs.set(first, last);
+        }
+    }
+    if (!FLAGS_skp.isEmpty()) {
+        gNames.set(FLAGS_skp);
+    }
+#ifdef SK_DEBUG
+    header.append(" SK_DEBUG");
+#else
+    header.append(" SK_RELEASE");
+#endif
+    header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8);
+    if (FLAGS_verbose) {
+        header.appendf("\n");
+    }
+    SkDebugf(header.c_str());
+    Iter iter;
+    Test* test;
+    while ((test = iter.next()) != NULL) {
+        SkAutoTDelete<Test> owned(test);
+        if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) {
+            test->run();
+        }
+    }
+    SkGraphics::Term();
+    return 0;
+}
+
+#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
+int main(int argc, char * const argv[]) {
+    return tool_main(argc, (char**) argv);
+}
+#endif
diff --git a/tests/PathOpsSkpTest.cpp b/tests/PathOpsSkpTest.cpp
index d62e326..32ddf61 100755
--- a/tests/PathOpsSkpTest.cpp
+++ b/tests/PathOpsSkpTest.cpp
@@ -8,6 +8,8 @@
 
 #define TEST(name) { name, #name }
 
+#define TEST_NEW_FAILURES 0
+
 static void skpcheeseandburger_com225(skiatest::Reporter* reporter, const char* filename) {
     SkPath path;
     path.setFillType(SkPath::kEvenOdd_FillType);
@@ -3547,9 +3549,290 @@
     testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
 }
 
+static void skpwww_9to5mac_com_64(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(365, 5101);
+    path.lineTo(365, 5082);
+    path.lineTo(366, 5083);
+    path.lineTo(367, 5092.96631f);
+    path.lineTo(367, 5100);
+    path.quadTo(367, 5101.50537f, 367.967712f, 5102.61084f);
+    path.lineTo(368.278717f, 5105.71045f);
+    path.quadTo(367.277618f, 5105.34863f, 366.464478f, 5104.53564f);
+    path.quadTo(365, 5103.07129f, 365, 5101);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kWinding_FillType);
+    pathB.moveTo(365, 5082);
+    pathB.lineTo(365.848175f, 5081.15186f);
+    pathB.lineTo(368, 5103);
+    pathB.lineTo(365, 5106);
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+
+static void skpwww_googleventures_com_32(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(725.911682f, 898.767456f);
+    path.lineTo(741.232544f, 885.911682f);
+    path.lineTo(754.088318f, 901.232544f);
+    path.lineTo(738.767456f, 914.088318f);
+    path.lineTo(725.911682f, 898.767456f);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kWinding_FillType);
+    pathB.moveTo(728.37677f, 870.59082f);
+    pathB.lineTo(754.088257f, 901.232605f);
+    pathB.lineTo(738.767395f, 914.088379f);
+    pathB.lineTo(713.055908f, 883.446594f);
+    pathB.close();
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+
+#if TEST_NEW_FAILURES
+static void skpwww_devbridge_com_22(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(4915, 1523);
+    path.quadTo(4887.24756f, 1523, 4867.62402f, 1542.6239f);
+    path.quadTo(4848, 1562.24768f, 4848, 1590);
+    path.quadTo(4848, 1617.75232f, 4867.62402f, 1637.3761f);
+    path.quadTo(4887.24756f, 1657, 4915, 1657);
+    path.quadTo(4942.75244f, 1657, 4962.37598f, 1637.3761f);
+    path.quadTo(4982, 1617.75232f, 4982, 1590);
+    path.quadTo(4982, 1562.24768f, 4962.37598f, 1542.6239f);
+    path.quadTo(4942.75244f, 1523, 4915, 1523);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kWinding_FillType);
+    pathB.moveTo(4981.99902f, 1590);
+    pathB.quadTo(4981.99902f, 1617.75232f, 4962.375f, 1637.3761f);
+    pathB.quadTo(4942.75146f, 1657, 4914.99902f, 1657);
+    pathB.quadTo(4887.24658f, 1657, 4867.62305f, 1637.3761f);
+    pathB.quadTo(4847.99902f, 1617.75232f, 4847.99902f, 1590);
+    pathB.quadTo(4847.99902f, 1562.24768f, 4867.62305f, 1542.6239f);
+    pathB.quadTo(4887.24658f, 1523, 4914.99902f, 1523);
+    pathB.quadTo(4942.75146f, 1523, 4962.375f, 1542.6239f);
+    pathB.quadTo(4981.99902f, 1562.24768f, 4981.99902f, 1590);
+    pathB.close();
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+
+// cubic/quad intersection
+static void skpwww_alamdi_com_3(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(10210.8789f, 5315.87891f);
+    path.quadTo(10211.7578f, 5315, 10213, 5315);
+    path.lineTo(10230, 5315);
+    path.quadTo(10231.2422f, 5315, 10232.1211f, 5315.87891f);
+    path.quadTo(10233, 5316.75732f, 10233, 5318);
+    path.lineTo(10233, 5338);
+    path.quadTo(10233, 5339.24268f, 10232.1211f, 5340.12109f);
+    path.quadTo(10231.2422f, 5341, 10230, 5341);
+    path.lineTo(10213, 5341);
+    path.quadTo(10211.7578f, 5341, 10210.8789f, 5340.12109f);
+    path.quadTo(10210, 5339.24268f, 10210, 5338);
+    path.lineTo(10210, 5318);
+    path.quadTo(10210, 5316.75732f, 10210.8789f, 5315.87891f);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kEvenOdd_FillType);
+    pathB.moveTo(10213, 5315);
+    pathB.lineTo(10230, 5315);
+    pathB.cubicTo(10231.6572f, 5315, 10233, 5316.34326f, 10233, 5318);
+    pathB.lineTo(10233, 5338);
+    pathB.cubicTo(10233, 5339.10449f, 10231.6572f, 5340, 10230, 5340);
+    pathB.lineTo(10213, 5340);
+    pathB.cubicTo(10211.3428f, 5340, 10210, 5339.10449f, 10210, 5338);
+    pathB.lineTo(10210, 5318);
+    pathB.cubicTo(10210, 5316.34326f, 10211.3428f, 5315, 10213, 5315);
+    pathB.close();
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+
+// bumpSpan failed assertion "span->fOppValue >= 0"
+static void skpwww_familysurvivalprotocol_wordpress_com_61(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(143, 14557);
+    path.lineTo(165, 14557);
+    path.lineTo(165, 14555.9902f);
+    path.lineTo(143, 14556);
+    path.lineTo(143, 14557);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kWinding_FillType);
+    pathB.moveTo(143, 14557);
+    pathB.lineTo(143, 14555.9902f);
+    pathB.lineTo(165, 14556);
+    pathB.lineTo(165, 14557);
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+#endif
+
+static void skpwww_firstunitedbank_com_19(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(808.585815f, 11673.5859f);
+    path.quadTo(809.17157f, 11673, 810, 11673);
+    path.lineTo(1032, 11673);
+    path.quadTo(1038.21326f, 11673, 1042.60657f, 11677.3936f);
+    path.quadTo(1047, 11681.7871f, 1047, 11688);
+    path.quadTo(1047, 11682.2012f, 1042.60657f, 11678.1006f);
+    path.quadTo(1038.21326f, 11674, 1032, 11674);
+    path.lineTo(810, 11674);
+    path.quadTo(809.585815f, 11674, 809.292908f, 11674.293f);
+    path.quadTo(809, 11674.5859f, 809, 11675);
+    path.lineTo(809, 11701);
+    path.quadTo(809, 11701.4141f, 809.292908f, 11701.707f);
+    path.quadTo(809.585815f, 11702, 810, 11702);
+    path.lineTo(1032, 11702);
+    path.quadTo(1038.21326f, 11702, 1042.60657f, 11697.8994f);
+    path.quadTo(1047, 11693.7988f, 1047, 11688);
+    path.quadTo(1047, 11694.2129f, 1042.60657f, 11698.6064f);
+    path.quadTo(1038.21326f, 11703, 1032, 11703);
+    path.lineTo(810, 11703);
+    path.quadTo(809.17157f, 11703, 808.585815f, 11702.4141f);
+    path.quadTo(808, 11701.8281f, 808, 11701);
+    path.lineTo(808, 11675);
+    path.quadTo(808, 11674.1719f, 808.585815f, 11673.5859f);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kWinding_FillType);
+    pathB.moveTo(808, 11703);
+    pathB.lineTo(809.5f, 11701.5f);
+    pathB.lineTo(1062.91907f, 11687.0811f);
+    pathB.lineTo(1047, 11703);
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+
+// addSimpleAngle: failed assertion "index == count() - 2"
+static void skpwww_shinydemos_com_5(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(205.884888f, 648.203857f);
+    path.lineTo(771.570374f, 82.5183716f);
+    path.lineTo(1110.98169f, 421.929626f);
+    path.lineTo(545.296143f, 987.615112f);
+    path.lineTo(205.884888f, 648.203857f);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kWinding_FillType);
+    pathB.moveTo(771.570374f, 82.5183716f);
+    pathB.lineTo(1110.98169f, 421.929626f);
+    pathB.lineTo(545.296204f, 987.615051f);
+    pathB.lineTo(205.884949f, 648.203796f);
+    pathB.close();
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+
+// addTCoincident oPeek = &other->fTs[++oPeekIndex];
+static void skpwww_lptemp_com_3(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(78.6429825f, 1394.30969f);
+    path.quadTo(79.6192932f, 1393.33337f, 81.0000076f, 1393.33337f);
+    path.lineTo(341, 1393.33337f);
+    path.quadTo(342.380707f, 1393.33337f, 343.357025f, 1394.30969f);
+    path.quadTo(344.333344f, 1395.28601f, 344.333344f, 1396.66675f);
+    path.lineTo(344.333344f, 1465.66663f);
+    path.quadTo(344.333344f, 1467.04736f, 343.357025f, 1468.02368f);
+    path.quadTo(342.380707f, 1469, 341, 1469);
+    path.lineTo(81.0000076f, 1469);
+    path.quadTo(79.6192932f, 1469, 78.6429825f, 1468.02368f);
+    path.quadTo(77.6666718f, 1467.04736f, 77.6666718f, 1465.66663f);
+    path.lineTo(77.6666718f, 1396.66675f);
+    path.quadTo(77.6666718f, 1395.28601f, 78.6429825f, 1394.30969f);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kEvenOdd_FillType);
+    pathB.moveTo(81, 1393.33337f);
+    pathB.lineTo(341, 1393.33337f);
+    pathB.cubicTo(342.840942f, 1393.33337f, 344.333344f, 1394.82568f, 344.333344f, 1396.66675f);
+    pathB.lineTo(344.333344f, 1465.66675f);
+    pathB.cubicTo(344.333344f, 1467.32361f, 342.840942f, 1468.66675f, 341, 1468.66675f);
+    pathB.lineTo(81, 1468.66675f);
+    pathB.cubicTo(79.15905f, 1468.66675f, 77.6666718f, 1467.32361f, 77.6666718f, 1465.66675f);
+    pathB.lineTo(77.6666718f, 1396.66675f);
+    pathB.cubicTo(77.6666718f, 1394.82568f, 79.15905f, 1393.33337f, 81, 1393.33337f);
+    pathB.close();
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+
+#if TEST_NEW_FAILURES
+// SkOpSegment.cpp:3915: failed assertion "otherEnd >= 0"
+static void skpwww_shinydemos_com_15(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(1000, 310.947968f);
+    path.lineTo(771.570374f, 82.5183716f);
+    path.lineTo(205.884888f, 648.203857f);
+    path.lineTo(448.68103f, 891);
+    path.lineTo(641.911255f, 891);
+    path.lineTo(1000, 532.911316f);
+    path.lineTo(1000, 310.947968f);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kWinding_FillType);
+    pathB.moveTo(771.570374f, 82.5183716f);
+    pathB.lineTo(1110.98169f, 421.929626f);
+    pathB.lineTo(545.296204f, 987.615051f);
+    pathB.lineTo(205.884949f, 648.203796f);
+    pathB.close();
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+
+// SkOpSegment.cpp:4398: failed assertion "!span->fDone"
+static void skpwww_lptemp_com_5(skiatest::Reporter* reporter, const char* filename) {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(78.6429825f, 3150.97632f);
+    path.quadTo(79.6192932f, 3150, 81.0000076f, 3150);
+    path.lineTo(341, 3150);
+    path.quadTo(342.380707f, 3150, 343.357025f, 3150.97632f);
+    path.quadTo(344.333344f, 3151.95264f, 344.333344f, 3153.33325f);
+    path.lineTo(344.333344f, 5205.3335f);
+    path.quadTo(344.333344f, 5206.71436f, 343.357025f, 5207.69092f);
+    path.quadTo(342.380707f, 5208.66699f, 341, 5208.66699f);
+    path.lineTo(81.0000076f, 5208.66699f);
+    path.quadTo(79.6192932f, 5208.66699f, 78.6429825f, 5207.69092f);
+    path.quadTo(77.6666718f, 5206.71436f, 77.6666718f, 5205.3335f);
+    path.lineTo(77.6666718f, 3153.33325f);
+    path.quadTo(77.6666718f, 3151.95264f, 78.6429825f, 3150.97632f);
+    path.close();
+    SkPath pathB;
+    pathB.setFillType(SkPath::kEvenOdd_FillType);
+    pathB.moveTo(81, 3150);
+    pathB.lineTo(341, 3150);
+    pathB.cubicTo(342.840942f, 3150, 344.333344f, 3151.49268f, 344.333344f, 3153.3335f);
+    pathB.lineTo(344.333344f, 5205.3335f);
+    pathB.cubicTo(344.333344f, 5206.99023f, 342.840942f, 5208.3335f, 341, 5208.3335f);
+    pathB.lineTo(81, 5208.3335f);
+    pathB.cubicTo(79.15905f, 5208.3335f, 77.6666718f, 5206.99023f, 77.6666718f, 5205.3335f);
+    pathB.lineTo(77.6666718f, 3153.3335f);
+    pathB.cubicTo(77.6666718f, 3151.49268f, 79.15905f, 3150, 81, 3150);
+    pathB.close();
+    testPathOp(reporter, path, pathB, kIntersect_PathOp, filename);
+}
+#endif
+
 static void (*firstTest)(skiatest::Reporter* , const char* filename) = 0;
 
 static struct TestDesc tests[] = {
+    TEST(skpwww_lptemp_com_3),
+    TEST(skpwww_shinydemos_com_5),
+#if TEST_NEW_FAILURES
+    TEST(skpwww_lptemp_com_5),
+    TEST(skpwww_shinydemos_com_15),
+    TEST(skpwww_familysurvivalprotocol_wordpress_com_61),
+    TEST(skpwww_alamdi_com_3),
+    TEST(skpwww_devbridge_com_22),
+#endif
+    TEST(skpwww_firstunitedbank_com_19),
+    TEST(skpwww_googleventures_com_32),
+    TEST(skpwww_9to5mac_com_64),
     TEST(skpwww_wartepop_blogspot_com_br_6),
     TEST(skpwww_wartepop_blogspot_com_br_6a),
     TEST(skpwww_cooksnaps_com_32a),
diff --git a/tests/PathOpsThreadedCommon.cpp b/tests/PathOpsThreadedCommon.cpp
index ac4cd6b..0adde91 100644
--- a/tests/PathOpsThreadedCommon.cpp
+++ b/tests/PathOpsThreadedCommon.cpp
@@ -7,7 +7,7 @@
 
 #include "PathOpsExtendedTest.h"
 #include "PathOpsThreadedCommon.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
 
 PathOpsThreadedTestRunner::~PathOpsThreadedTestRunner() {
     for (int index = 0; index < fRunnables.count(); index++) {
@@ -16,8 +16,8 @@
 }
 
 void PathOpsThreadedTestRunner::render() {
-    SkThreadPool pool(fNumThreads);
+    SkTaskGroup tg;
     for (int index = 0; index < fRunnables.count(); ++ index) {
-        pool.add(fRunnables[index]);
+        tg.add(fRunnables[index]);
     }
 }
diff --git a/tests/PathOpsThreadedCommon.h b/tests/PathOpsThreadedCommon.h
index a638cd2..124921e 100644
--- a/tests/PathOpsThreadedCommon.h
+++ b/tests/PathOpsThreadedCommon.h
@@ -33,17 +33,13 @@
 
 class PathOpsThreadedTestRunner {
 public:
-    PathOpsThreadedTestRunner(skiatest::Reporter* reporter, int threadCount)
-        : fNumThreads(threadCount)
-        , fReporter(reporter) {
-    }
+    PathOpsThreadedTestRunner(skiatest::Reporter* reporter) : fReporter(reporter) {}
 
     ~PathOpsThreadedTestRunner();
 
     void render();
 
 public:
-    int fNumThreads;
     SkTDArray<PathOpsThreadedRunnable*> fRunnables;
     skiatest::Reporter* fReporter;
 };
diff --git a/tests/PathOpsTightBoundsTest.cpp b/tests/PathOpsTightBoundsTest.cpp
new file mode 100644
index 0000000..cea3752
--- /dev/null
+++ b/tests/PathOpsTightBoundsTest.cpp
@@ -0,0 +1,123 @@
+/*
+ * 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 "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
+#include "SkCanvas.h"
+#include "SkRandom.h"
+#include "SkTArray.h"
+#include "SkTSort.h"
+#include "Test.h"
+
+static void testTightBoundsLines(PathOpsThreadState* data) {
+    SkRandom ran;
+    for (int index = 0; index < 1000; ++index) {
+        SkPath path;
+        int contourCount = ran.nextRangeU(1, 10);
+        for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+            int lineCount = ran.nextRangeU(1, 10);
+            path.moveTo(ran.nextRangeF(-1000, 1000), ran.nextRangeF(-1000, 1000));
+            for (int lIndex = 0; lIndex < lineCount; ++lIndex) {
+                path.lineTo(ran.nextRangeF(-1000, 1000), ran.nextRangeF(-1000, 1000));
+            }
+            if (ran.nextBool()) {
+                path.close();
+            }
+        }
+        SkRect classicBounds = path.getBounds();
+        SkRect tightBounds;
+        REPORTER_ASSERT(data->fReporter, TightBounds(path, &tightBounds));
+        REPORTER_ASSERT(data->fReporter, classicBounds == tightBounds);
+    }
+}
+
+DEF_TEST(PathOpsTightBoundsLines, reporter) {
+    initializeTests(reporter, "tightBoundsLines");
+    PathOpsThreadedTestRunner testRunner(reporter);
+    int outerCount = reporter->allowExtendedTest() ? 100 : 1;
+    for (int index = 0; index < outerCount; ++index) {
+        for (int idx2 = 0; idx2 < 10; ++idx2) {
+            *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+                    (&testTightBoundsLines, 0, 0, 0, 0, &testRunner));
+        }
+    }
+    testRunner.render();
+}
+
+static void testTightBoundsQuads(PathOpsThreadState* data) {
+    SkRandom ran;
+    const int bitWidth = 32;
+    const int bitHeight = 32;
+    const float pathMin = 1;
+    const float pathMax = (float) (bitHeight - 2);
+    SkBitmap& bits = *data->fBitmap;
+    if (bits.width() == 0) {
+        bits.allocN32Pixels(bitWidth, bitHeight);
+    }
+    SkCanvas canvas(bits);
+    SkPaint paint;
+    for (int index = 0; index < 100; ++index) {
+        SkPath path;
+        int contourCount = ran.nextRangeU(1, 10);
+        for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+            int lineCount = ran.nextRangeU(1, 10);
+            path.moveTo(ran.nextRangeF(1, pathMax), ran.nextRangeF(pathMin, pathMax));
+            for (int lIndex = 0; lIndex < lineCount; ++lIndex) {
+                if (ran.nextBool()) {
+                    path.lineTo(ran.nextRangeF(pathMin, pathMax), ran.nextRangeF(pathMin, pathMax));
+                } else {
+                    path.quadTo(ran.nextRangeF(pathMin, pathMax), ran.nextRangeF(pathMin, pathMax),
+                            ran.nextRangeF(pathMin, pathMax), ran.nextRangeF(pathMin, pathMax));
+                }
+            }
+            if (ran.nextBool()) {
+                path.close();
+            }
+        }
+        SkRect classicBounds = path.getBounds();
+        SkRect tightBounds;
+        REPORTER_ASSERT(data->fReporter, TightBounds(path, &tightBounds));
+        REPORTER_ASSERT(data->fReporter, classicBounds.contains(tightBounds));
+        canvas.drawColor(SK_ColorWHITE);
+        canvas.drawPath(path, paint);
+        SkIRect bitsWritten = {31, 31, 0, 0};
+        for (int y = 0; y < bitHeight; ++y) {
+            uint32_t* addr1 = data->fBitmap->getAddr32(0, y);
+            bool lineWritten = false;
+            for (int x = 0; x < bitWidth; ++x) {
+                if (addr1[x] == (uint32_t) -1) {
+                    continue;
+                }
+                lineWritten = true;
+                bitsWritten.fLeft = SkTMin(bitsWritten.fLeft, x);
+                bitsWritten.fRight = SkTMax(bitsWritten.fRight, x);
+            }
+            if (!lineWritten) {
+                continue;
+            }
+            bitsWritten.fTop = SkTMin(bitsWritten.fTop, y);
+            bitsWritten.fBottom = SkTMax(bitsWritten.fBottom, y);
+        }
+        if (!bitsWritten.isEmpty()) {
+            SkIRect tightOut;
+            tightBounds.roundOut(&tightOut);
+            REPORTER_ASSERT(data->fReporter, tightOut.contains(bitsWritten));
+        }
+    }
+}
+
+DEF_TEST(PathOpsTightBoundsQuads, reporter) {
+    initializeTests(reporter, "tightBoundsQuads");
+    PathOpsThreadedTestRunner testRunner(reporter);
+    int outerCount = reporter->allowExtendedTest() ? 100 : 1;
+    for (int index = 0; index < outerCount; ++index) {
+        for (int idx2 = 0; idx2 < 10; ++idx2) {
+            *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+                    (&testTightBoundsQuads, 0, 0, 0, 0, &testRunner));
+        }
+    }
+    testRunner.render();
+}
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index e265d31..1f0422d 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -15,6 +15,7 @@
 #include "SkRandom.h"
 #include "SkReader32.h"
 #include "SkSize.h"
+#include "SkStream.h"
 #include "SkSurface.h"
 #include "SkTypes.h"
 #include "SkWriter32.h"
@@ -63,6 +64,32 @@
     canvas->drawPath(path, paint);
 }
 
+/**
+ * In debug mode, this path was causing an assertion to fail in
+ * SkPathStroker::preJoinTo() and, in Release, the use of an unitialized value.
+ */
+static void make_path_crbugskia2820(SkPath* path, skiatest::Reporter* reporter) {
+    SkPoint orig, p1, p2, p3;
+    orig = SkPoint::Make(1.f, 1.f);
+    p1 = SkPoint::Make(1.f - SK_ScalarNearlyZero, 1.f);
+    p2 = SkPoint::Make(1.f, 1.f + SK_ScalarNearlyZero);
+    p3 = SkPoint::Make(2.f, 2.f);
+
+    path->reset();
+    path->moveTo(orig);
+    path->cubicTo(p1, p2, p3);
+    path->close();
+}
+
+static void test_path_crbugskia2820(skiatest::Reporter* reporter) {//GrContext* context) {
+    SkPath path;
+    make_path_crbugskia2820(&path, reporter);
+
+    SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
+    stroke.setStrokeStyle(2 * SK_Scalar1);
+    stroke.applyToPath(&path, path);
+}
+
 static void make_path0(SkPath* path) {
     // from  *  https://code.google.com/p/skia/issues/detail?id=1706
 
@@ -1168,6 +1195,17 @@
     stroke.applyToPath(&strokedSin, strokedSin);
     check_convexity(reporter, strokedSin, SkPath::kConcave_Convexity);
     check_direction(reporter, strokedSin, kDontCheckDir);
+
+    // http://crbug.com/412640
+    SkPath degenerateConcave;
+    degenerateConcave.moveTo(148.67912f, 191.875f);
+    degenerateConcave.lineTo(470.37695f, 7.5f);
+    degenerateConcave.lineTo(148.67912f, 191.875f);
+    degenerateConcave.lineTo(41.446522f, 376.25f);
+    degenerateConcave.lineTo(-55.971577f, 460.0f);
+    degenerateConcave.lineTo(41.446522f, 376.25f);
+    check_convexity(reporter, degenerateConcave, SkPath::kConcave_Convexity);
+    check_direction(reporter, degenerateConcave, SkPath::kUnknown_Direction);
 }
 
 static void check_convex_bounds(skiatest::Reporter* reporter, const SkPath& p,
@@ -1477,7 +1515,19 @@
                                                                                 SkIntToScalar(20),
                                                                                 SkIntToScalar(5))));
 
-    // same as above path and first test but with an extra moveTo.
+
+    // Test that multiple move commands do not cause asserts.
+
+    // At the time of writing, this would not modify cached convexity. This caused an assert while
+    // checking conservative containment again. http://skbug.com/1460
+    path.moveTo(SkIntToScalar(100), SkIntToScalar(100));
+#if 0
+    REPORTER_ASSERT(reporter, path.conservativelyContainsRect(SkRect::MakeXYWH(SkIntToScalar(50), 0,
+                                                                               SkIntToScalar(10),
+                                                                               SkIntToScalar(10))));
+#endif
+
+    // Same as above path and first test but with an extra moveTo.
     path.reset();
     path.moveTo(100, 100);
     path.moveTo(0, 0);
@@ -1488,6 +1538,21 @@
                                                                                SkIntToScalar(10),
                                                                                SkIntToScalar(10))));
 
+    // Test that multiple move commands do not cause asserts and that the function
+    // is not confused by the multiple moves.
+    path.reset();
+    path.moveTo(0, 0);
+    path.lineTo(SkIntToScalar(100), 0);
+    path.lineTo(0, SkIntToScalar(100));
+    path.moveTo(0, SkIntToScalar(200));
+    path.lineTo(SkIntToScalar(100), SkIntToScalar(200));
+    path.lineTo(0, SkIntToScalar(300));
+
+    REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(
+                                                            SkRect::MakeXYWH(SkIntToScalar(50), 0,
+                                                                             SkIntToScalar(10),
+                                                                             SkIntToScalar(10))));
+
     path.reset();
     path.lineTo(100, 100);
     REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeXYWH(0, 0, 1, 1)));
@@ -3323,7 +3388,7 @@
             REPORTER_ASSERT(reporter, 2*kRepeatCnt == pathRef->countPoints());
             REPORTER_ASSERT(reporter, kRepeatCnt == pathRef->countWeights());
             REPORTER_ASSERT(reporter, SkPath::kConic_SegmentMask == pathRef->getSegmentMasks());
-            REPORTER_ASSERT(reporter, NULL != weights);
+            REPORTER_ASSERT(reporter, weights);
             for (int i = 0; i < kRepeatCnt; ++i) {
                 REPORTER_ASSERT(reporter, SkPath::kConic_Verb == pathRef->atVerb(i));
             }
@@ -3364,6 +3429,54 @@
     REPORTER_ASSERT(reporter, a == b);
 }
 
+static void compare_dump(skiatest::Reporter* reporter, const SkPath& path, bool force,
+        bool dumpAsHex, const char* str) {
+    SkDynamicMemoryWStream wStream;
+    path.dump(&wStream, force, dumpAsHex);
+    SkAutoDataUnref data(wStream.copyToData());
+    REPORTER_ASSERT(reporter, data->size() == strlen(str));
+    REPORTER_ASSERT(reporter, !memcmp(data->data(), str, strlen(str)));
+}
+
+static void test_dump(skiatest::Reporter* reporter) {
+    SkPath p;
+    compare_dump(reporter, p, false, false, "");
+    compare_dump(reporter, p, true, false, "");
+    p.moveTo(1, 2);
+    p.lineTo(3, 4);
+    compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
+                                            "path.lineTo(3, 4);\n");
+    compare_dump(reporter, p, true, false,  "path.moveTo(1, 2);\n"
+                                            "path.lineTo(3, 4);\n"
+                                            "path.lineTo(1, 2);\n"
+                                            "path.close();\n");
+    p.reset();
+    p.moveTo(1, 2);
+    p.quadTo(3, 4, 5, 6);
+    compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
+                                            "path.quadTo(3, 4, 5, 6);\n");
+    p.reset();
+    p.moveTo(1, 2);
+    p.conicTo(3, 4, 5, 6, 0.5f);
+    compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
+                                            "path.conicTo(3, 4, 5, 6, 0.5f);\n");
+    p.reset();
+    p.moveTo(1, 2);
+    p.cubicTo(3, 4, 5, 6, 7, 8);
+    compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
+                                            "path.cubicTo(3, 4, 5, 6, 7, 8);\n");
+    p.reset();
+    p.moveTo(1, 2);
+    p.lineTo(3, 4);
+    compare_dump(reporter, p, false, true,  "path.moveTo(SkBits2Float(0x3f800000), SkBits2Float(0x40000000));\n"
+                                            "path.lineTo(SkBits2Float(0x40400000), SkBits2Float(0x40800000));\n");
+    p.reset();
+    p.moveTo(SkBits2Float(0x3f800000), SkBits2Float(0x40000000));
+    p.lineTo(SkBits2Float(0x40400000), SkBits2Float(0x40800000));
+    compare_dump(reporter, p, false, false, "path.moveTo(1, 2);\n"
+                                            "path.lineTo(3, 4);\n");
+}
+
 class PathTest_Private {
 public:
     static void TestPathTo(skiatest::Reporter* reporter) {
@@ -3513,4 +3626,6 @@
     test_contains(reporter);
     PathTest_Private::TestPathTo(reporter);
     PathRefTest_Private::TestPathRef(reporter);
+    test_dump(reporter);
+    test_path_crbugskia2820(reporter);
 }
diff --git a/tests/PictureShaderTest.cpp b/tests/PictureShaderTest.cpp
index 17ef5b5..8d933db 100644
--- a/tests/PictureShaderTest.cpp
+++ b/tests/PictureShaderTest.cpp
@@ -14,13 +14,13 @@
 // empty picture returns NULL.
 DEF_TEST(PictureShader_empty, reporter) {
     SkShader* shader = SkShader::CreatePictureShader(NULL,
-            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, NULL, NULL);
     REPORTER_ASSERT(reporter, NULL == shader);
 
     SkPictureRecorder factory;
     factory.beginRecording(0, 0, NULL, 0);
     SkAutoTUnref<SkPicture> picture(factory.endRecording());
     shader = SkShader::CreatePictureShader(picture.get(),
-            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, NULL, NULL);
     REPORTER_ASSERT(reporter, NULL == shader);
 }
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index 6969524..9cd63df 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SkBitmapDevice.h"
+#include "SkBBoxHierarchy.h"
 #include "SkBlurImageFilter.h"
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
@@ -13,15 +13,13 @@
 #include "SkData.h"
 #include "SkDecodingImageGenerator.h"
 #include "SkError.h"
-#if SK_SUPPORT_GPU
-#include "SkGpuDevice.h"
-#endif
 #include "SkImageEncoder.h"
 #include "SkImageGenerator.h"
 #include "SkPaint.h"
 #include "SkPicture.h"
 #include "SkPictureRecorder.h"
 #include "SkPictureUtils.h"
+#include "SkPixelRef.h"
 #include "SkRRect.h"
 #include "SkRandom.h"
 #include "SkShader.h"
@@ -581,6 +579,43 @@
     }
 }
 
+#define GENERATE_CANVAS(recorder, x) \
+    (x) ? recorder.EXPERIMENTAL_beginRecording(100, 100) \
+        : recorder.  DEPRECATED_beginRecording(100,100);
+
+/* Hit a few SkPicture::Analysis cases not handled elsewhere. */
+static void test_analysis(skiatest::Reporter* reporter, bool useNewPath) {
+    SkPictureRecorder recorder;
+
+    SkCanvas* canvas = GENERATE_CANVAS(recorder, useNewPath);
+    {
+        canvas->drawRect(SkRect::MakeWH(10, 10), SkPaint ());
+    }
+    SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+    REPORTER_ASSERT(reporter, !picture->willPlayBackBitmaps());
+
+    canvas = GENERATE_CANVAS(recorder, useNewPath);
+    {
+        SkPaint paint;
+        // CreateBitmapShader is too smart for us; an empty (or 1x1) bitmap shader
+        // gets optimized into a non-bitmap form, so we create a 2x2 bitmap here.
+        SkBitmap bitmap;
+        bitmap.allocPixels(SkImageInfo::MakeN32Premul(2, 2));
+        bitmap.eraseColor(SK_ColorBLUE);
+        *(bitmap.getAddr32(0, 0)) = SK_ColorGREEN;
+        SkShader* shader = SkShader::CreateBitmapShader(bitmap, SkShader::kClamp_TileMode,
+                                                        SkShader::kClamp_TileMode);
+        paint.setShader(shader)->unref();
+        REPORTER_ASSERT(reporter,
+                        shader->asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType);
+
+        canvas->drawRect(SkRect::MakeWH(10, 10), paint);
+    }
+    picture.reset(recorder.endRecording());
+    REPORTER_ASSERT(reporter, picture->willPlayBackBitmaps());
+}
+
+
 static void test_gatherpixelrefsandrects(skiatest::Reporter* reporter) {
     const int IW = 32;
     const int IH = IW;
@@ -666,15 +701,15 @@
 }
 
 #ifdef SK_DEBUG
-// Ensure that deleting SkPicturePlayback does not assert. Asserts only fire in debug mode, so only
-// run in debug mode.
-static void test_deleting_empty_playback() {
+// Ensure that deleting an empty SkPicture does not assert. Asserts only fire
+// in debug mode, so only run in debug mode.
+static void test_deleting_empty_picture() {
     SkPictureRecorder recorder;
     // Creates an SkPictureRecord
     recorder.beginRecording(0, 0);
-    // Turns that into an SkPicturePlayback
+    // Turns that into an SkPicture
     SkAutoTUnref<SkPicture> picture(recorder.endRecording());
-    // Deletes the old SkPicturePlayback, and creates a new SkPictureRecord
+    // Ceates a new SkPictureRecord
     recorder.beginRecording(0, 0);
 }
 
@@ -709,11 +744,13 @@
 }
 
 #if SK_SUPPORT_GPU
-static void test_gpu_veto(skiatest::Reporter* reporter) {
+
+static void test_gpu_veto(skiatest::Reporter* reporter,
+                          bool useNewPath) {
 
     SkPictureRecorder recorder;
 
-    SkCanvas* canvas = recorder.beginRecording(100, 100);
+    SkCanvas* canvas = GENERATE_CANVAS(recorder, useNewPath);
     {
         SkPath path;
         path.moveTo(0, 0);
@@ -733,9 +770,9 @@
 
     const char *reason = NULL;
     REPORTER_ASSERT(reporter, !picture->suitableForGpuRasterization(NULL, &reason));
-    REPORTER_ASSERT(reporter, NULL != reason);
+    REPORTER_ASSERT(reporter, reason);
 
-    canvas = recorder.beginRecording(100, 100);
+    canvas = GENERATE_CANVAS(recorder, useNewPath);
     {
         SkPath path;
 
@@ -757,7 +794,7 @@
     // A lot of AA concave paths currently render an SkPicture undesireable for GPU rendering
     REPORTER_ASSERT(reporter, !picture->suitableForGpuRasterization(NULL));
 
-    canvas = recorder.beginRecording(100, 100);
+    canvas = GENERATE_CANVAS(recorder, useNewPath);
     {
         SkPath path;
 
@@ -780,138 +817,330 @@
     picture.reset(recorder.endRecording());
     // hairline stroked AA concave paths are fine for GPU rendering
     REPORTER_ASSERT(reporter, picture->suitableForGpuRasterization(NULL));
+
+    canvas = GENERATE_CANVAS(recorder, useNewPath);
+    {
+        SkPaint paint;
+        SkScalar intervals [] = { 10, 20 };
+        SkPathEffect* pe = SkDashPathEffect::Create(intervals, 2, 25);
+        paint.setPathEffect(pe)->unref();
+
+        SkPoint points [2] = { { 0, 0 }, { 100, 0 } };
+        canvas->drawPoints(SkCanvas::kLines_PointMode, 2, points, paint);
+    }
+    picture.reset(recorder.endRecording());
+    // fast-path dashed effects are fine for GPU rendering ...
+    REPORTER_ASSERT(reporter, picture->suitableForGpuRasterization(NULL));
+
+    canvas = GENERATE_CANVAS(recorder, useNewPath);
+    {
+        SkPaint paint;
+        SkScalar intervals [] = { 10, 20 };
+        SkPathEffect* pe = SkDashPathEffect::Create(intervals, 2, 25);
+        paint.setPathEffect(pe)->unref();
+
+        canvas->drawRect(SkRect::MakeWH(10, 10), paint);
+    }
+    picture.reset(recorder.endRecording());
+    // ... but only when applied to drawPoint() calls
+    REPORTER_ASSERT(reporter, !picture->suitableForGpuRasterization(NULL));
+
+    // Nest the previous picture inside a new one.
+    // This doesn't work in the old backend.
+    if (useNewPath) {
+        canvas = GENERATE_CANVAS(recorder, useNewPath);
+        {
+            canvas->drawPicture(picture.get());
+        }
+        picture.reset(recorder.endRecording());
+        REPORTER_ASSERT(reporter, !picture->suitableForGpuRasterization(NULL));
+    }
 }
 
+#undef GENERATE_CANVAS
+
 static void test_gpu_picture_optimization(skiatest::Reporter* reporter,
                                           GrContextFactory* factory) {
+    for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
+        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
 
-    GrContext* context = factory->get(GrContextFactory::kNative_GLContextType);
+        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
+            continue;
+        }
 
-    static const int kWidth = 100;
-    static const int kHeight = 100;
+        GrContext* context = factory->get(glCtxType);
 
-    SkAutoTUnref<SkPicture> pict;
+        if (NULL == context) {
+            continue;
+        }
 
-    // create a picture with the structure:
-    // 1)
-    //      SaveLayer
-    //      Restore
-    // 2)
-    //      SaveLayer
-    //          Translate
-    //          SaveLayer w/ bound
-    //          Restore
-    //      Restore
-    // 3)
-    //      SaveLayer w/ copyable paint
-    //      Restore
-    // 4)
-    //      SaveLayer w/ non-copyable paint
-    //      Restore
-    {
-        SkPictureRecorder recorder;
+        static const int kWidth = 100;
+        static const int kHeight = 100;
 
-        SkCanvas* c = recorder.beginRecording(kWidth, kHeight);
+        SkAutoTUnref<SkPicture> pict, child;
+
+        {
+            SkPictureRecorder recorder;
+
+            SkCanvas* c = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
+
+            c->saveLayer(NULL, NULL);
+            c->restore();
+
+            child.reset(recorder.endRecording());
+        }
+
+        // create a picture with the structure:
         // 1)
-        c->saveLayer(NULL, NULL);
-        c->restore();
-
+        //      SaveLayer
+        //      Restore
         // 2)
-        c->saveLayer(NULL, NULL);
-            c->translate(kWidth/2, kHeight/2);
-            SkRect r = SkRect::MakeXYWH(0, 0, kWidth/2, kHeight/2);
-            c->saveLayer(&r, NULL);
-            c->restore();
-        c->restore();
-
+        //      SaveLayer
+        //          Translate
+        //          SaveLayer w/ bound
+        //          Restore
+        //      Restore
         // 3)
-        {
-            SkPaint p;
-            p.setColor(SK_ColorRED);
-            c->saveLayer(NULL, &p);
-            c->restore();
-        }
+        //      SaveLayer w/ copyable paint
+        //      Restore
         // 4)
-        // TODO: this case will need to be removed once the paint's are immutable
+        //      SaveLayer
+        //          DrawPicture (which has a SaveLayer/Restore pair)
+        //      Restore
+        // 5)
+        //      SaveLayer
+        //          DrawPicture with Matrix & Paint (with SaveLayer/Restore pair)
+        //      Restore
         {
-            SkPaint p;
-            SkAutoTUnref<SkColorFilter> cf(SkLumaColorFilter::Create());
-            p.setImageFilter(SkColorFilterImageFilter::Create(cf.get()))->unref();
-            c->saveLayer(NULL, &p);
+            SkPictureRecorder recorder;
+
+            SkCanvas* c = recorder.beginRecording(SkIntToScalar(kWidth),
+                                                  SkIntToScalar(kHeight));
+            // 1)
+            c->saveLayer(NULL, NULL); // layer #0
             c->restore();
+
+            // 2)
+            c->saveLayer(NULL, NULL); // layer #1
+                c->translate(kWidth/2.0f, kHeight/2.0f);
+                SkRect r = SkRect::MakeXYWH(0, 0, kWidth/2, kHeight/2);
+                c->saveLayer(&r, NULL); // layer #2
+                c->restore();
+            c->restore();
+
+            // 3)
+            {
+                SkPaint p;
+                p.setColor(SK_ColorRED);
+                c->saveLayer(NULL, &p); // layer #3
+                c->restore();
+            }
+
+            SkPaint layerPaint;
+            layerPaint.setColor(SK_ColorRED);  // Non-alpha only to avoid SaveLayerDrawRestoreNooper
+            // 4)
+            {
+                c->saveLayer(NULL, &layerPaint);  // layer #4
+                    c->drawPicture(child);  // layer #5 inside picture
+                c->restore();
+            }
+            // 5
+            {
+                SkPaint picturePaint;
+                SkMatrix trans;
+                trans.setTranslate(10, 10);
+
+                c->saveLayer(NULL, &layerPaint);  // layer #6
+                    c->drawPicture(child, &trans, &picturePaint); // layer #7 inside picture
+                c->restore();
+            }
+
+            pict.reset(recorder.endRecording());
         }
 
-        pict.reset(recorder.endRecording());
-    }
+        // Now test out the SaveLayer extraction
+        {
+            SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
 
-    // Now test out the SaveLayer extraction
-    {
-        SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
+            SkAutoTUnref<SkSurface> surface(SkSurface::NewScratchRenderTarget(context, info));
 
-        SkAutoTUnref<SkSurface> surface(SkSurface::NewScratchRenderTarget(context, info));
+            SkCanvas* canvas = surface->getCanvas();
 
-        SkCanvas* canvas = surface->getCanvas();
+            canvas->EXPERIMENTAL_optimize(pict);
 
-        canvas->EXPERIMENTAL_optimize(pict);
+            SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey();
 
-        SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey();
+            const SkPicture::AccelData* data = pict->EXPERIMENTAL_getAccelData(key);
+            REPORTER_ASSERT(reporter, data);
 
-        const SkPicture::AccelData* data = pict->EXPERIMENTAL_getAccelData(key);
-        REPORTER_ASSERT(reporter, NULL != data);
+            const GrAccelData *gpuData = static_cast<const GrAccelData*>(data);
+            REPORTER_ASSERT(reporter, 8 == gpuData->numSaveLayers());
 
-        const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data);
-        REPORTER_ASSERT(reporter, 5 == gpuData->numSaveLayers());
+            const GrAccelData::SaveLayerInfo& info0 = gpuData->saveLayerInfo(0);
+            // The parent/child layers appear in reverse order
+            const GrAccelData::SaveLayerInfo& info1 = gpuData->saveLayerInfo(2);
+            const GrAccelData::SaveLayerInfo& info2 = gpuData->saveLayerInfo(1);
 
-        const GPUAccelData::SaveLayerInfo& info0 = gpuData->saveLayerInfo(0);
-        // The parent/child layer appear in reverse order
-        const GPUAccelData::SaveLayerInfo& info1 = gpuData->saveLayerInfo(2);
-        const GPUAccelData::SaveLayerInfo& info2 = gpuData->saveLayerInfo(1);
-        const GPUAccelData::SaveLayerInfo& info3 = gpuData->saveLayerInfo(3);
-//        const GPUAccelData::SaveLayerInfo& info4 = gpuData->saveLayerInfo(4);
+            const GrAccelData::SaveLayerInfo& info3 = gpuData->saveLayerInfo(3);
 
-        REPORTER_ASSERT(reporter, info0.fValid);
-        REPORTER_ASSERT(reporter, kWidth == info0.fSize.fWidth && kHeight == info0.fSize.fHeight);
-        REPORTER_ASSERT(reporter, info0.fCTM.isIdentity());
-        REPORTER_ASSERT(reporter, 0 == info0.fOffset.fX && 0 == info0.fOffset.fY);
-        REPORTER_ASSERT(reporter, NULL != info0.fPaint);
-        REPORTER_ASSERT(reporter, !info0.fIsNested && !info0.fHasNestedLayers);
+            // The parent/child layers appear in reverse order
+            const GrAccelData::SaveLayerInfo& info4 = gpuData->saveLayerInfo(5);
+            const GrAccelData::SaveLayerInfo& info5 = gpuData->saveLayerInfo(4);
 
-        REPORTER_ASSERT(reporter, info1.fValid);
-        REPORTER_ASSERT(reporter, kWidth == info1.fSize.fWidth && kHeight == info1.fSize.fHeight);
-        REPORTER_ASSERT(reporter, info1.fCTM.isIdentity());
-        REPORTER_ASSERT(reporter, 0 == info1.fOffset.fX && 0 == info1.fOffset.fY);
-        REPORTER_ASSERT(reporter, NULL != info1.fPaint);
-        REPORTER_ASSERT(reporter, !info1.fIsNested && info1.fHasNestedLayers); // has a nested SL
+            // The parent/child layers appear in reverse order
+            const GrAccelData::SaveLayerInfo& info6 = gpuData->saveLayerInfo(7);
+            const GrAccelData::SaveLayerInfo& info7 = gpuData->saveLayerInfo(6);
 
-        REPORTER_ASSERT(reporter, info2.fValid);
-        REPORTER_ASSERT(reporter, kWidth/2 == info2.fSize.fWidth &&
-                                  kHeight/2 == info2.fSize.fHeight); // bound reduces size
-        REPORTER_ASSERT(reporter, info2.fCTM.isIdentity());         // translated
-        REPORTER_ASSERT(reporter, kWidth/2 == info2.fOffset.fX &&
-                                  kHeight/2 == info2.fOffset.fY);
-        REPORTER_ASSERT(reporter, NULL != info1.fPaint);
-        REPORTER_ASSERT(reporter, info2.fIsNested && !info2.fHasNestedLayers); // is nested
+            REPORTER_ASSERT(reporter, info0.fValid);
+            REPORTER_ASSERT(reporter, NULL == info0.fPicture);
+            REPORTER_ASSERT(reporter, kWidth == info0.fSize.fWidth &&
+                                      kHeight == info0.fSize.fHeight);
+            REPORTER_ASSERT(reporter, info0.fOriginXform.isIdentity());
+            REPORTER_ASSERT(reporter, 0 == info0.fOffset.fX && 0 == info0.fOffset.fY);
+            REPORTER_ASSERT(reporter, NULL == info0.fPaint);
+            REPORTER_ASSERT(reporter, !info0.fIsNested && !info0.fHasNestedLayers);
 
-        REPORTER_ASSERT(reporter, info3.fValid);
-        REPORTER_ASSERT(reporter, kWidth == info3.fSize.fWidth && kHeight == info3.fSize.fHeight);
-        REPORTER_ASSERT(reporter, info3.fCTM.isIdentity());
-        REPORTER_ASSERT(reporter, 0 == info3.fOffset.fX && 0 == info3.fOffset.fY);
-        REPORTER_ASSERT(reporter, NULL != info3.fPaint);
-        REPORTER_ASSERT(reporter, !info3.fIsNested && !info3.fHasNestedLayers);
+            REPORTER_ASSERT(reporter, info1.fValid);
+            REPORTER_ASSERT(reporter, NULL == info1.fPicture);
+            REPORTER_ASSERT(reporter, kWidth == info1.fSize.fWidth &&
+                                      kHeight == info1.fSize.fHeight);
+            REPORTER_ASSERT(reporter, info1.fOriginXform.isIdentity());
+            REPORTER_ASSERT(reporter, 0 == info1.fOffset.fX && 0 == info1.fOffset.fY);
+            REPORTER_ASSERT(reporter, NULL == info1.fPaint);
+            REPORTER_ASSERT(reporter, !info1.fIsNested &&
+                                      info1.fHasNestedLayers); // has a nested SL
 
-#if 0 // needs more though for GrGatherCanvas
-        REPORTER_ASSERT(reporter, !info4.fValid);                 // paint is/was uncopyable
-        REPORTER_ASSERT(reporter, kWidth == info4.fSize.fWidth && kHeight == info4.fSize.fHeight);
-        REPORTER_ASSERT(reporter, 0 == info4.fOffset.fX && 0 == info4.fOffset.fY);
-        REPORTER_ASSERT(reporter, info4.fCTM.isIdentity());
-        REPORTER_ASSERT(reporter, NULL == info4.fPaint);     // paint is/was uncopyable
-        REPORTER_ASSERT(reporter, !info4.fIsNested && !info4.fHasNestedLayers);
-#endif
+            REPORTER_ASSERT(reporter, info2.fValid);
+            REPORTER_ASSERT(reporter, NULL == info2.fPicture);
+            REPORTER_ASSERT(reporter, kWidth / 2 == info2.fSize.fWidth &&
+                                      kHeight/2 == info2.fSize.fHeight); // bound reduces size
+            REPORTER_ASSERT(reporter, !info2.fOriginXform.isIdentity());
+            REPORTER_ASSERT(reporter, kWidth/2 == info2.fOffset.fX &&   // translated
+                                      kHeight/2 == info2.fOffset.fY);
+            REPORTER_ASSERT(reporter, NULL == info1.fPaint);
+            REPORTER_ASSERT(reporter, info2.fIsNested && !info2.fHasNestedLayers); // is nested
+
+            REPORTER_ASSERT(reporter, info3.fValid);
+            REPORTER_ASSERT(reporter, NULL == info3.fPicture);
+            REPORTER_ASSERT(reporter, kWidth == info3.fSize.fWidth &&
+                                      kHeight == info3.fSize.fHeight);
+            REPORTER_ASSERT(reporter, info3.fOriginXform.isIdentity());
+            REPORTER_ASSERT(reporter, 0 == info3.fOffset.fX && 0 == info3.fOffset.fY);
+            REPORTER_ASSERT(reporter, info3.fPaint);
+            REPORTER_ASSERT(reporter, !info3.fIsNested && !info3.fHasNestedLayers);
+
+            REPORTER_ASSERT(reporter, info4.fValid);
+            REPORTER_ASSERT(reporter, NULL == info4.fPicture);
+            REPORTER_ASSERT(reporter, kWidth == info4.fSize.fWidth &&
+                                      kHeight == info4.fSize.fHeight);
+            REPORTER_ASSERT(reporter, 0 == info4.fOffset.fX && 0 == info4.fOffset.fY);
+            REPORTER_ASSERT(reporter, info4.fOriginXform.isIdentity());
+            REPORTER_ASSERT(reporter, info4.fPaint);
+            REPORTER_ASSERT(reporter, !info4.fIsNested &&
+                                      info4.fHasNestedLayers); // has a nested SL
+
+            REPORTER_ASSERT(reporter, info5.fValid);
+            REPORTER_ASSERT(reporter, child == info5.fPicture); // in a child picture
+            REPORTER_ASSERT(reporter, kWidth == info5.fSize.fWidth &&
+                                      kHeight == info5.fSize.fHeight);
+            REPORTER_ASSERT(reporter, 0 == info5.fOffset.fX && 0 == info5.fOffset.fY);
+            REPORTER_ASSERT(reporter, info5.fOriginXform.isIdentity());
+            REPORTER_ASSERT(reporter, NULL == info5.fPaint);
+            REPORTER_ASSERT(reporter, info5.fIsNested && !info5.fHasNestedLayers); // is nested
+
+            REPORTER_ASSERT(reporter, info6.fValid);
+            REPORTER_ASSERT(reporter, NULL == info6.fPicture);
+            REPORTER_ASSERT(reporter, kWidth == info6.fSize.fWidth &&
+                                      kHeight == info6.fSize.fHeight);
+            REPORTER_ASSERT(reporter, 0 == info6.fOffset.fX && 0 == info6.fOffset.fY);
+            REPORTER_ASSERT(reporter, info6.fOriginXform.isIdentity());
+            REPORTER_ASSERT(reporter, info6.fPaint);
+            REPORTER_ASSERT(reporter, !info6.fIsNested &&
+                                      info6.fHasNestedLayers); // has a nested SL
+
+            REPORTER_ASSERT(reporter, info7.fValid);
+            REPORTER_ASSERT(reporter, child == info7.fPicture); // in a child picture
+            REPORTER_ASSERT(reporter, kWidth == info7.fSize.fWidth &&
+                                      kHeight == info7.fSize.fHeight);
+            REPORTER_ASSERT(reporter, 0 == info7.fOffset.fX && 0 == info7.fOffset.fY);
+            REPORTER_ASSERT(reporter, info7.fOriginXform.isIdentity());
+            REPORTER_ASSERT(reporter, NULL == info7.fPaint);
+            REPORTER_ASSERT(reporter, info7.fIsNested && !info7.fHasNestedLayers); // is nested
+        }
     }
 }
 
 #endif
 
+static void test_has_text(skiatest::Reporter* reporter, bool useNewPath) {
+    SkPictureRecorder recorder;
+#define BEGIN_RECORDING useNewPath ? recorder.EXPERIMENTAL_beginRecording(100, 100) \
+                                   : recorder.  DEPRECATED_beginRecording(100, 100)
+
+    SkCanvas* canvas = BEGIN_RECORDING;
+    {
+        canvas->drawRect(SkRect::MakeWH(20, 20), SkPaint());
+    }
+    SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+    REPORTER_ASSERT(reporter, !picture->hasText());
+
+    SkPoint point = SkPoint::Make(10, 10);
+    canvas = BEGIN_RECORDING;
+    {
+        canvas->drawText("Q", 1, point.fX, point.fY, SkPaint());
+    }
+    picture.reset(recorder.endRecording());
+    REPORTER_ASSERT(reporter, picture->hasText());
+
+    canvas = BEGIN_RECORDING;
+    {
+        canvas->drawPosText("Q", 1, &point, SkPaint());
+    }
+    picture.reset(recorder.endRecording());
+    REPORTER_ASSERT(reporter, picture->hasText());
+
+    canvas = BEGIN_RECORDING;
+    {
+        canvas->drawPosTextH("Q", 1, &point.fX, point.fY, SkPaint());
+    }
+    picture.reset(recorder.endRecording());
+    REPORTER_ASSERT(reporter, picture->hasText());
+
+    canvas = BEGIN_RECORDING;
+    {
+        SkPath path;
+        path.moveTo(0, 0);
+        path.lineTo(50, 50);
+
+        canvas->drawTextOnPathHV("Q", 1, path, point.fX, point.fY, SkPaint());
+    }
+    picture.reset(recorder.endRecording());
+    REPORTER_ASSERT(reporter, picture->hasText());
+
+    canvas = BEGIN_RECORDING;
+    {
+        SkPath path;
+        path.moveTo(0, 0);
+        path.lineTo(50, 50);
+
+        canvas->drawTextOnPath("Q", 1, path, NULL, SkPaint());
+    }
+    picture.reset(recorder.endRecording());
+    REPORTER_ASSERT(reporter, picture->hasText());
+
+    // Nest the previous picture inside a new one.
+    // This doesn't work in the old backend.
+    if (useNewPath) {
+        canvas = BEGIN_RECORDING;
+        {
+            canvas->drawPicture(picture.get());
+        }
+        picture.reset(recorder.endRecording());
+        REPORTER_ASSERT(reporter, picture->hasText());
+    }
+#undef BEGIN_RECORDING
+}
+
 static void set_canvas_to_save_count_4(SkCanvas* canvas) {
     canvas->restoreToCount(1);
     canvas->save();
@@ -937,9 +1166,9 @@
         return this->INHERITED::willSaveLayer(bounds, paint, flags);
     }
 
-    virtual void willSave(SaveFlags flags) SK_OVERRIDE {
+    virtual void willSave() SK_OVERRIDE {
         ++fSaveCount;
-        this->INHERITED::willSave(flags);
+        this->INHERITED::willSave();
     }
 
     virtual void willRestore() SK_OVERRIDE {
@@ -962,13 +1191,16 @@
 void check_save_state(skiatest::Reporter* reporter, SkPicture* picture,
                       unsigned int numSaves, unsigned int numSaveLayers,
                       unsigned int numRestores) {
-    SaveCountingCanvas canvas(picture->width(), picture->height());
+    SaveCountingCanvas canvas(SkScalarCeilToInt(picture->cullRect().width()),
+                              SkScalarCeilToInt(picture->cullRect().height()));
 
-    picture->draw(&canvas);
+    picture->playback(&canvas);
 
-    REPORTER_ASSERT(reporter, numSaves == canvas.getSaveCount());
-    REPORTER_ASSERT(reporter, numSaveLayers == canvas.getSaveLayerCount());
-    REPORTER_ASSERT(reporter, numRestores == canvas.getRestoreCount());
+    // Optimizations may have removed these,
+    // so expect to have seen no more than num{Saves,SaveLayers,Restores}.
+    REPORTER_ASSERT(reporter, numSaves >= canvas.getSaveCount());
+    REPORTER_ASSERT(reporter, numSaveLayers >= canvas.getSaveLayerCount());
+    REPORTER_ASSERT(reporter, numRestores >= canvas.getRestoreCount());
 }
 
 // This class exists so SkPicture can friend it and give it access to
@@ -1218,7 +1450,8 @@
 
 static SkData* serialized_picture_from_bitmap(const SkBitmap& bitmap) {
     SkPictureRecorder recorder;
-    SkCanvas* canvas = recorder.beginRecording(bitmap.width(), bitmap.height());
+    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(bitmap.width()),
+                                               SkIntToScalar(bitmap.height()));
     canvas->drawBitmap(bitmap, 0, 0);
     SkAutoTUnref<SkPicture> picture(recorder.endRecording());
 
@@ -1278,19 +1511,6 @@
     SkSetErrorCallback(NULL, NULL);
 }
 
-static void test_clone_empty(skiatest::Reporter* reporter) {
-    // This is a regression test for crbug.com/172062
-    // Before the fix, we used to crash accessing a null pointer when we
-    // had a picture with no paints. This test passes by not crashing.
-    {
-        SkPictureRecorder recorder;
-        recorder.beginRecording(1, 1);
-        SkAutoTUnref<SkPicture> picture(recorder.endRecording());
-        SkAutoTUnref<SkPicture> destPicture(picture->clone());
-        REPORTER_ASSERT(reporter, NULL != destPicture);
-    }
-}
-
 static void test_draw_empty(skiatest::Reporter* reporter) {
     SkBitmap result;
     make_bm(&result, 2, 2, SK_ColorBLACK, false);
@@ -1330,16 +1550,6 @@
 
         canvas.drawPicture(picture);
     }
-
-    {
-        // quad tree
-        SkQuadTreeFactory factory;
-        SkPictureRecorder recorder;
-        recorder.beginRecording(1, 1, &factory);
-        SkAutoTUnref<SkPicture> picture(recorder.endRecording());
-
-        canvas.drawPicture(picture);
-    }
 }
 
 static void test_clip_bound_opt(skiatest::Reporter* reporter) {
@@ -1360,8 +1570,8 @@
     path2.addOval(rect3);
     SkIRect clipBounds;
     SkPictureRecorder recorder;
-    // Minimalist test set for 100% code coverage of
-    // SkPictureRecord::updateClipConservativelyUsingBounds
+
+    // Testing conservative-raster-clip that is enabled by PictureRecord
     {
         SkCanvas* canvas = recorder.beginRecording(10, 10);
         canvas->clipPath(invPath, SkRegion::kIntersect_Op);
@@ -1488,7 +1698,7 @@
     SkAutoTUnref<SkPicture> picture(recorder.endRecording());
 
     ClipCountingCanvas testCanvas(10, 10);
-    picture->draw(&testCanvas);
+    picture->playback(&testCanvas);
 
     // Both clips should be present on playback.
     REPORTER_ASSERT(reporter, testCanvas.getClipCount() == 2);
@@ -1538,12 +1748,12 @@
 
 static void test_gen_id(skiatest::Reporter* reporter) {
 
-    SkPicture empty;
+    SkPictureRecorder recorder;
+    recorder.beginRecording(0, 0);
+    SkAutoTUnref<SkPicture> empty(recorder.endRecording());
 
     // Empty pictures should still have a valid ID
-    REPORTER_ASSERT(reporter, empty.uniqueID() != SK_InvalidGenID);
-
-    SkPictureRecorder recorder;
+    REPORTER_ASSERT(reporter, empty->uniqueID() != SK_InvalidGenID);
 
     SkCanvas* canvas = recorder.beginRecording(1, 1);
     canvas->drawARGB(255, 255, 255, 255);
@@ -1552,38 +1762,12 @@
     REPORTER_ASSERT(reporter, hasData->uniqueID() != SK_InvalidGenID);
 
     // both pictures should have different ids
-    REPORTER_ASSERT(reporter, hasData->uniqueID() != empty.uniqueID());
-
-    // test out copy constructor
-    SkPicture copyWithData(*hasData);
-    REPORTER_ASSERT(reporter, hasData->uniqueID() == copyWithData.uniqueID());
-
-    SkPicture emptyCopy(empty);
-    REPORTER_ASSERT(reporter, empty.uniqueID() != emptyCopy.uniqueID());
-
-    // test out swap
-    {
-        SkPicture swapWithData;
-        uint32_t beforeID1 = swapWithData.uniqueID();
-        uint32_t beforeID2 = copyWithData.uniqueID();
-        swapWithData.swap(copyWithData);
-        REPORTER_ASSERT(reporter, copyWithData.uniqueID() == beforeID1);
-        REPORTER_ASSERT(reporter, swapWithData.uniqueID() == beforeID2);
-    }
-
-    // test out clone
-    {
-        SkAutoTUnref<SkPicture> cloneWithData(hasData->clone());
-        REPORTER_ASSERT(reporter, hasData->uniqueID() == cloneWithData->uniqueID());
-
-        SkAutoTUnref<SkPicture> emptyClone(empty.clone());
-        REPORTER_ASSERT(reporter, empty.uniqueID() != emptyClone->uniqueID());
-    }
+    REPORTER_ASSERT(reporter, hasData->uniqueID() != empty->uniqueID());
 }
 
 DEF_TEST(Picture, reporter) {
 #ifdef SK_DEBUG
-    test_deleting_empty_playback();
+    test_deleting_empty_picture();
     test_serializing_empty_picture();
 #else
     test_bad_bitmap();
@@ -1591,12 +1775,16 @@
     test_unbalanced_save_restores(reporter);
     test_peephole();
 #if SK_SUPPORT_GPU
-    test_gpu_veto(reporter);
+    test_gpu_veto(reporter, false);
+    test_gpu_veto(reporter, true);
 #endif
+    test_has_text(reporter, false);
+    test_has_text(reporter, true);
+    test_analysis(reporter, false);
+    test_analysis(reporter, true);
     test_gatherpixelrefs(reporter);
     test_gatherpixelrefsandrects(reporter);
     test_bitmap_with_encoded_data(reporter);
-    test_clone_empty(reporter);
     test_draw_empty(reporter);
     test_clip_bound_opt(reporter);
     test_clip_expansion(reporter);
@@ -1643,3 +1831,125 @@
 
     test_draw_bitmaps(&canvas);
 }
+
+DEF_TEST(DontOptimizeSaveLayerDrawDrawRestore, reporter) {
+    // This test is from crbug.com/344987.
+    // The commands are:
+    //   saveLayer with paint that modifies alpha
+    //     drawBitmapRectToRect
+    //     drawBitmapRectToRect
+    //   restore
+    // The bug was that this structure was modified so that:
+    //  - The saveLayer and restore were eliminated
+    //  - The alpha was only applied to the first drawBitmapRectToRect
+
+    // This test draws blue and red squares inside a 50% transparent
+    // layer.  Both colours should show up muted.
+    // When the bug is present, the red square (the second bitmap)
+    // shows upwith full opacity.
+
+    SkBitmap blueBM;
+    make_bm(&blueBM, 100, 100, SkColorSetARGB(255, 0, 0, 255), true);
+    SkBitmap redBM;
+    make_bm(&redBM, 100, 100, SkColorSetARGB(255, 255, 0, 0), true);
+    SkPaint semiTransparent;
+    semiTransparent.setAlpha(0x80);
+
+    SkPictureRecorder recorder;
+    SkCanvas* canvas = recorder.beginRecording(100, 100);
+    canvas->drawARGB(0, 0, 0, 0);
+
+    canvas->saveLayer(0, &semiTransparent);
+    canvas->drawBitmap(blueBM, 25, 25);
+    canvas->drawBitmap(redBM, 50, 50);
+    canvas->restore();
+
+    SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+
+    // Now replay the picture back on another canvas
+    // and check a couple of its pixels.
+    SkBitmap replayBM;
+    make_bm(&replayBM, 100, 100, SK_ColorBLACK, false);
+    SkCanvas replayCanvas(replayBM);
+    picture->playback(&replayCanvas);
+    replayCanvas.flush();
+
+    // With the bug present, at (55, 55) we would get a fully opaque red
+    // intead of a dark red.
+    REPORTER_ASSERT(reporter, replayBM.getColor(30, 30) == 0xff000080);
+    REPORTER_ASSERT(reporter, replayBM.getColor(55, 55) == 0xff800000);
+}
+
+struct CountingBBH : public SkBBoxHierarchy {
+    mutable int searchCalls;
+
+    CountingBBH() : searchCalls(0) {}
+
+    virtual void search(const SkRect& query, SkTDArray<void*>* results) const {
+        this->searchCalls++;
+    }
+
+    // All other methods unimplemented.
+    virtual void insert(void* data, const SkRect& bounds, bool defer) {}
+    virtual void flushDeferredInserts() {}
+    virtual void clear() {}
+    virtual int getCount() const { return 0; }
+    virtual int getDepth() const { return 0; }
+    virtual void rewindInserts() {}
+};
+
+class SpoonFedBBHFactory : public SkBBHFactory {
+public:
+    explicit SpoonFedBBHFactory(SkBBoxHierarchy* bbh) : fBBH(bbh) {}
+    virtual SkBBoxHierarchy* operator()(int width, int height) const {
+        return SkRef(fBBH);
+    }
+private:
+    SkBBoxHierarchy* fBBH;
+};
+
+// When the canvas clip covers the full picture, we don't need to call the BBH.
+DEF_TEST(Picture_SkipBBH, r) {
+    CountingBBH bbh;
+    SpoonFedBBHFactory factory(&bbh);
+
+    SkPictureRecorder recorder;
+    recorder.beginRecording(320, 240, &factory);
+    SkAutoTUnref<const SkPicture> picture(recorder.endRecording());
+
+    SkCanvas big(640, 480), small(300, 200);
+
+    picture->playback(&big);
+    REPORTER_ASSERT(r, bbh.searchCalls == 0);
+
+    picture->playback(&small);
+    REPORTER_ASSERT(r, bbh.searchCalls == 1);
+}
+
+DEF_TEST(Picture_BitmapLeak, r) {
+    SkBitmap mut, immut;
+    mut.allocN32Pixels(300, 200);
+    immut.allocN32Pixels(300, 200);
+    immut.setImmutable();
+    SkASSERT(!mut.isImmutable());
+    SkASSERT(immut.isImmutable());
+
+    // No one can hold a ref on our pixels yet.
+    REPORTER_ASSERT(r, mut.pixelRef()->unique());
+    REPORTER_ASSERT(r, immut.pixelRef()->unique());
+
+    SkPictureRecorder rec;
+    SkCanvas* canvas = rec.beginRecording(1920, 1200);
+        canvas->drawBitmap(mut, 0, 0);
+        canvas->drawBitmap(immut, 800, 600);
+    SkAutoTDelete<const SkPicture> pic(rec.endRecording());
+
+    // The picture shares the immutable pixels but copies the mutable ones.
+    REPORTER_ASSERT(r, mut.pixelRef()->unique());
+    REPORTER_ASSERT(r, !immut.pixelRef()->unique());
+
+    // When the picture goes away, it's just our bitmaps holding the refs.
+    pic.reset(NULL);
+    REPORTER_ASSERT(r, mut.pixelRef()->unique());
+    REPORTER_ASSERT(r, immut.pixelRef()->unique());
+}
diff --git a/tests/PremulAlphaRoundTripTest.cpp b/tests/PremulAlphaRoundTripTest.cpp
index af041ce..ce45f16 100644
--- a/tests/PremulAlphaRoundTripTest.cpp
+++ b/tests/PremulAlphaRoundTripTest.cpp
@@ -58,16 +58,14 @@
         }
     }
 
-    SkImageInfo info = bmp.info();
-    info.fColorType = colorType;
-    info.fAlphaType = kUnpremul_SkAlphaType;
+    const SkImageInfo info = SkImageInfo::Make(bmp.width(), bmp.height(),
+                                               colorType, kUnpremul_SkAlphaType);
     canvas->writePixels(info, bmp.getPixels(), bmp.rowBytes(), 0, 0);
 }
 
 DEF_GPUTEST(PremulAlphaRoundTrip, reporter, factory) {
     const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
 
-    SkAutoTUnref<SkBaseDevice> device;
     for (int dtype = 0; dtype < 2; ++dtype) {
 
         int glCtxTypeCnt = 1;
@@ -77,6 +75,7 @@
         }
 #endif
         for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) {
+            SkAutoTUnref<SkBaseDevice> device;
             if (0 == dtype) {
                 device.reset(SkBitmapDevice::Create(info));
             } else {
@@ -91,7 +90,8 @@
                     continue;
                 }
 
-                device.reset(SkGpuDevice::Create(context, info, 0));
+                device.reset(SkGpuDevice::Create(context, info,
+                                     SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType), 0));
 #else
                 continue;
 #endif
@@ -121,6 +121,10 @@
                     const uint32_t* pixels1 = readBmp1.getAddr32(0, y);
                     const uint32_t* pixels2 = readBmp2.getAddr32(0, y);
                     for (int x = 0; x < 256 && success; ++x) {
+                        // We see sporadic failures here. May help to see where it goes wrong.
+                        if (pixels1[x] != pixels2[x]) {
+                            SkDebugf("%x != %x, x = %d, y = %d\n", pixels1[x], pixels2[x], x, y);
+                        }
                         REPORTER_ASSERT(reporter, success = pixels1[x] == pixels2[x]);
                     }
                 }
diff --git a/tests/RTConfRegistryTest.cpp b/tests/RTConfRegistryTest.cpp
new file mode 100644
index 0000000..59fb3e9
--- /dev/null
+++ b/tests/RTConfRegistryTest.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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 "SkRTConf.h"
+#include "Test.h"
+
+// Friended proxy for SkRTConfRegistry::parse()
+template <typename T>
+bool test_rt_conf_parse(SkRTConfRegistry* reg, const char* key, T* value) {
+    return reg->parse(key, value);
+}
+
+static void portable_setenv(const char* key, const char* value) {
+#ifdef SK_BUILD_FOR_WIN32
+    _putenv_s(key, value);
+#else
+    setenv(key, value, 1);
+#endif
+}
+
+DEF_TEST(SkRTConfRegistry, reporter) {
+    SkRTConfRegistry reg;
+
+    portable_setenv("skia_nonexistent_item", "132");
+    int result = 0;
+    test_rt_conf_parse(&reg, "nonexistent.item", &result);
+    REPORTER_ASSERT(reporter, result == 132);
+}
diff --git a/tests/RTreeTest.cpp b/tests/RTreeTest.cpp
index ae8c005..40af5fe 100644
--- a/tests/RTreeTest.cpp
+++ b/tests/RTreeTest.cpp
@@ -18,17 +18,17 @@
 static const size_t NUM_QUERIES = 50;
 
 struct DataRect {
-    SkIRect rect;
+    SkRect rect;
     void* data;
 };
 
-static SkIRect random_rect(SkRandom& rand) {
-    SkIRect rect = {0,0,0,0};
+static SkRect random_rect(SkRandom& rand) {
+    SkRect rect = {0,0,0,0};
     while (rect.isEmpty()) {
-        rect.fLeft   = rand.nextS() % 1000;
-        rect.fRight  = rand.nextS() % 1000;
-        rect.fTop    = rand.nextS() % 1000;
-        rect.fBottom = rand.nextS() % 1000;
+        rect.fLeft   = rand.nextRangeF(0, 1000);
+        rect.fRight  = rand.nextRangeF(0, 1000);
+        rect.fTop    = rand.nextRangeF(0, 1000);
+        rect.fBottom = rand.nextRangeF(0, 1000);
         rect.sort();
     }
     return rect;
@@ -41,12 +41,16 @@
     }
 }
 
-static bool verify_query(SkIRect query, DataRect rects[],
+static bool verify_query(SkRect query, DataRect rects[],
                          SkTDArray<void*>& found) {
+    // TODO(mtklein): no need to do this after everything's SkRects
+    query.roundOut();
+
     SkTDArray<void*> expected;
+
     // manually intersect with every rectangle
     for (int i = 0; i < NUM_RECTS; ++i) {
-        if (SkIRect::IntersectsNoEmptyCheck(query, rects[i].rect)) {
+        if (SkRect::Intersects(query, rects[i].rect)) {
             expected.push(rects[i].data);
         }
     }
@@ -71,7 +75,7 @@
                        SkRTree& tree) {
     for (size_t i = 0; i < NUM_QUERIES; ++i) {
         SkTDArray<void*> hits;
-        SkIRect query = random_rect(rand);
+        SkRect query = random_rect(rand);
         tree.search(query, &hits);
         REPORTER_ASSERT(reporter, verify_query(query, rects, hits));
     }
@@ -80,7 +84,7 @@
 static void rtree_test_main(SkRTree* rtree, skiatest::Reporter* reporter) {
     DataRect rects[NUM_RECTS];
     SkRandom rand;
-    REPORTER_ASSERT(reporter, NULL != rtree);
+    REPORTER_ASSERT(reporter, rtree);
 
     int expectedDepthMin = -1;
     int expectedDepthMax = -1;
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index 3e22f7c..77aac1f 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -10,6 +10,7 @@
 #include "SkColorPriv.h"
 #include "SkMathPriv.h"
 #include "SkRegion.h"
+#include "SkSurface.h"
 #include "Test.h"
 
 #if SK_SUPPORT_GPU
@@ -95,9 +96,7 @@
 static void fillCanvas(SkCanvas* canvas) {
     static SkBitmap bmp;
     if (bmp.isNull()) {
-        SkDEBUGCODE(bool alloc =) bmp.allocN32Pixels(DEV_W, DEV_H);
-        SkASSERT(alloc);
-        SkAutoLockPixels alp(bmp);
+        bmp.allocN32Pixels(DEV_W, DEV_H);
         intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels());
         for (int y = 0; y < DEV_H; ++y) {
             for (int x = 0; x < DEV_W; ++x) {
@@ -297,11 +296,11 @@
             glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt;
         }
 #endif
+        const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
         for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) {
-            SkAutoTUnref<SkBaseDevice> device;
+            SkAutoTUnref<SkSurface> surface;
             if (0 == dtype) {
-                SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
-                device.reset(SkBitmapDevice::Create(info));
+                surface.reset(SkSurface::NewRaster(info));
             } else {
 #if SK_SUPPORT_GPU
                 GrContextFactory::GLContextType type =
@@ -318,16 +317,15 @@
                 desc.fWidth = DEV_W;
                 desc.fHeight = DEV_H;
                 desc.fConfig = kSkia8888_GrPixelConfig;
-                desc.fOrigin = 1 == dtype ? kBottomLeft_GrSurfaceOrigin
-                                          : kTopLeft_GrSurfaceOrigin;
+                desc.fOrigin = 1 == dtype ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
                 GrAutoScratchTexture ast(context, desc, GrContext::kExact_ScratchTexMatch);
                 SkAutoTUnref<GrTexture> tex(ast.detach());
-                device.reset(new SkGpuDevice(context, tex));
+                surface.reset(SkSurface::NewRenderTargetDirect(tex->asRenderTarget()));
 #else
                 continue;
 #endif
             }
-            SkCanvas canvas(device);
+            SkCanvas& canvas = *surface->getCanvas();
             fillCanvas(&canvas);
 
             static const struct {
@@ -353,9 +351,9 @@
                         if (startsWithPixels) {
                             fillBitmap(&bmp);
                         }
-                        uint32_t idBefore = canvas.getDevice()->accessBitmap(false).getGenerationID();
+                        uint32_t idBefore = surface->generationID();
                         bool success = canvas.readPixels(&bmp, srcRect.fLeft, srcRect.fTop);
-                        uint32_t idAfter = canvas.getDevice()->accessBitmap(false).getGenerationID();
+                        uint32_t idAfter = surface->generationID();
 
                         // we expect to succeed when the read isn't fully clipped
                         // out.
diff --git a/tests/ReadWriteAlphaTest.cpp b/tests/ReadWriteAlphaTest.cpp
index 5df1ab3..385a17e 100644
--- a/tests/ReadWriteAlphaTest.cpp
+++ b/tests/ReadWriteAlphaTest.cpp
@@ -45,7 +45,7 @@
             return;
         }
 
-        SkAutoUnref au(texture);
+        SkAutoTUnref<GrTexture> au(texture);
 
         // create a distinctive texture
         for (int y = 0; y < Y_SIZE; ++y) {
@@ -81,7 +81,8 @@
         REPORTER_ASSERT(reporter, match);
 
         // Now try writing on the single channel texture
-        SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(context, texture->asRenderTarget()));
+        SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(),
+                                      SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType)));
         SkCanvas canvas(device);
 
         SkPaint paint;
diff --git a/tests/RecordDrawTest.cpp b/tests/RecordDrawTest.cpp
index b13b3a1..33efbd8 100644
--- a/tests/RecordDrawTest.cpp
+++ b/tests/RecordDrawTest.cpp
@@ -9,70 +9,58 @@
 #include "RecordTestUtils.h"
 
 #include "SkDebugCanvas.h"
+#include "SkDrawPictureCallback.h"
+#include "SkDropShadowImageFilter.h"
 #include "SkRecord.h"
-#include "SkRecordOpts.h"
 #include "SkRecordDraw.h"
+#include "SkRecordOpts.h"
 #include "SkRecorder.h"
 #include "SkRecords.h"
 
 static const int W = 1920, H = 1080;
 
-static void draw_pos_text_h(SkCanvas* canvas, const char* text, SkScalar y) {
-    const size_t len = strlen(text);
-    SkAutoTMalloc<SkScalar> xpos(len);
-    for (size_t i = 0; i < len; i++) {
-        xpos[i] = (SkScalar)i;
-    }
-    canvas->drawPosTextH(text, len, xpos, y, SkPaint());
-}
+class JustOneDraw : public SkDrawPictureCallback {
+public:
+    JustOneDraw() : fCalls(0) {}
 
-// Rerecord into another SkRecord using full SkCanvas semantics,
-// tracking clips and allowing SkRecordDraw's quickReject() calls to work.
-static void record_clipped(const SkRecord& record, SkRect clip, SkRecord* clipped) {
-    SkRecorder recorder(clipped, W, H);
-    recorder.clipRect(clip);
-    SkRecordDraw(record, &recorder);
-}
+    virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
+private:
+    int fCalls;
+};
 
-DEF_TEST(RecordDraw_PosTextHQuickReject, r) {
+DEF_TEST(RecordDraw_Abort, r) {
+    // Record two commands.
     SkRecord record;
     SkRecorder recorder(&record, W, H);
+    recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint());
+    recorder.clipRect(SkRect::MakeWH(100, 200));
 
-    draw_pos_text_h(&recorder, "This will draw.", 20);
-    draw_pos_text_h(&recorder, "This won't.", 5000);
+    SkRecord rerecord;
+    SkRecorder canvas(&rerecord, W, H);
 
-    SkRecordBoundDrawPosTextH(&record);
+    JustOneDraw callback;
+    SkRecordDraw(record, &canvas, NULL/*bbh*/, &callback);
 
-    SkRecord clipped;
-    record_clipped(record, SkRect::MakeLTRB(20, 20, 200, 200), &clipped);
-
-    // clipRect and the first drawPosTextH.
-    REPORTER_ASSERT(r, 2 == clipped.count());
+    REPORTER_ASSERT(r, 3 == rerecord.count());
+    assert_type<SkRecords::Save>    (r, rerecord, 0);
+    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
+    assert_type<SkRecords::Restore> (r, rerecord, 2);
 }
 
-DEF_TEST(RecordDraw_Culling, r) {
-    // Record these 7 drawing commands verbatim.
+DEF_TEST(RecordDraw_Unbalanced, r) {
     SkRecord record;
     SkRecorder recorder(&record, W, H);
+    recorder.save();  // We won't balance this, but SkRecordDraw will for us.
 
-    recorder.pushCull(SkRect::MakeWH(100, 100));
-        recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint());
-        recorder.drawRect(SkRect::MakeWH(30, 30), SkPaint());
-        recorder.pushCull(SkRect::MakeWH(5, 5));
-            recorder.drawRect(SkRect::MakeWH(1, 1), SkPaint());
-        recorder.popCull();
-    recorder.popCull();
+    SkRecord rerecord;
+    SkRecorder canvas(&rerecord, W, H);
+    SkRecordDraw(record, &canvas, NULL/*bbh*/, NULL/*callback*/);
 
-    // Take a pass over to match up pushCulls and popCulls.
-    SkRecordAnnotateCullingPairs(&record);
-
-    // This clip intersects the outer cull, but allows us to quick reject the inner one.
-    SkRecord clipped;
-    record_clipped(record, SkRect::MakeLTRB(20, 20, 200, 200), &clipped);
-
-    // We'll keep the clipRect call from above, and the outer two drawRects, and the push/pop pair.
-    // If culling weren't working, we'd see 8 commands recorded here.
-    REPORTER_ASSERT(r, 5 == clipped.count());
+    REPORTER_ASSERT(r, 4 == rerecord.count());
+    assert_type<SkRecords::Save>    (r, rerecord, 0);
+    assert_type<SkRecords::Save>    (r, rerecord, 1);
+    assert_type<SkRecords::Restore> (r, rerecord, 2);
+    assert_type<SkRecords::Restore> (r, rerecord, 3);
 }
 
 DEF_TEST(RecordDraw_SetMatrixClobber, r) {
@@ -90,7 +78,12 @@
     translate.setTranslate(20, 20);
     translateCanvas.setMatrix(translate);
 
-    SkRecordDraw(scaleRecord, &translateCanvas);
+    SkRecordDraw(scaleRecord, &translateCanvas, NULL/*bbh*/, NULL/*callback*/);
+    REPORTER_ASSERT(r, 4 == translateRecord.count());
+    assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
+    assert_type<SkRecords::Save>     (r, translateRecord, 1);
+    assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
+    assert_type<SkRecords::Restore>  (r, translateRecord, 3);
 
     // When we look at translateRecord now, it should have its first +20,+20 translate,
     // then a 2x,3x scale that's been concatted with that +20,+20 translate.
@@ -98,8 +91,170 @@
     setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
     REPORTER_ASSERT(r, setMatrix->matrix == translate);
 
-    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 1);
+    setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
     SkMatrix expected = scale;
     expected.postConcat(translate);
     REPORTER_ASSERT(r, setMatrix->matrix == expected);
 }
+
+struct TestBBH : public SkBBoxHierarchy {
+    virtual void insert(void* data, const SkRect& bounds, bool defer) SK_OVERRIDE {
+        Entry e = { (uintptr_t)data, bounds };
+        entries.push(e);
+    }
+    virtual int getCount() const SK_OVERRIDE { return entries.count(); }
+
+    virtual void flushDeferredInserts() SK_OVERRIDE {}
+
+    virtual void search(const SkRect& query, SkTDArray<void*>* results) const SK_OVERRIDE {}
+    virtual void clear() SK_OVERRIDE {}
+    virtual void rewindInserts() SK_OVERRIDE {}
+    virtual int getDepth() const SK_OVERRIDE { return -1; }
+
+    struct Entry {
+        uintptr_t data;
+        SkRect bounds;
+    };
+    SkTDArray<Entry> entries;
+};
+
+// Like a==b, with a little slop recognizing that float equality can be weird.
+static bool sloppy_rect_eq(SkRect a, SkRect b) {
+    SkRect inset(a), outset(a);
+    inset.inset(1, 1);
+    outset.outset(1, 1);
+    return outset.contains(b) && !inset.contains(b);
+}
+
+// This test is not meant to make total sense yet.  It's testing the status quo
+// of SkRecordFillBounds(), which itself doesn't make total sense yet.
+DEF_TEST(RecordDraw_BBH, r) {
+    SkRecord record;
+    SkRecorder recorder(&record, W, H);
+    recorder.save();
+        recorder.clipRect(SkRect::MakeWH(400, 500));
+        recorder.scale(2, 2);
+        recorder.drawRect(SkRect::MakeWH(320, 240), SkPaint());
+    recorder.restore();
+
+    TestBBH bbh;
+    SkRecordFillBounds(record, &bbh);
+
+    REPORTER_ASSERT(r, bbh.entries.count() == 5);
+    for (int i = 0; i < bbh.entries.count(); i++) {
+        REPORTER_ASSERT(r, bbh.entries[i].data == (uintptr_t)i);
+
+        REPORTER_ASSERT(r, sloppy_rect_eq(SkRect::MakeWH(400, 480), bbh.entries[i].bounds));
+    }
+}
+
+// A regression test for crbug.com/409110.
+DEF_TEST(RecordDraw_TextBounds, r) {
+    SkRecord record;
+    SkRecorder recorder(&record, W, H);
+
+    // Two Chinese characters in UTF-8.
+    const char text[] = { '\xe6', '\xbc', '\xa2', '\xe5', '\xad', '\x97' };
+    const size_t bytes = SK_ARRAY_COUNT(text);
+
+    const SkScalar xpos[] = { 10, 20 };
+    recorder.drawPosTextH(text, bytes, xpos, 30, SkPaint());
+
+    const SkPoint pos[] = { {40, 50}, {60, 70} };
+    recorder.drawPosText(text, bytes, pos, SkPaint());
+
+    TestBBH bbh;
+    SkRecordFillBounds(record, &bbh);
+    REPORTER_ASSERT(r, bbh.entries.count() == 2);
+
+    // We can make these next assertions confidently because SkRecordFillBounds
+    // builds its bounds by overestimating font metrics in a platform-independent way.
+    // If that changes, these tests will need to be more flexible.
+    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[0].bounds, SkRect::MakeLTRB(-86,  6, 116, 54)));
+    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[1].bounds, SkRect::MakeLTRB(-56, 26, 156, 94)));
+}
+
+// Base test to ensure start/stop range is respected
+DEF_TEST(RecordDraw_PartialStartStop, r) {
+    static const int kWidth = 10, kHeight = 10;
+
+    SkRect r1 = { 0, 0, kWidth,   kHeight };
+    SkRect r2 = { 0, 0, kWidth,   kHeight/2 };
+    SkRect r3 = { 0, 0, kWidth/2, kHeight };
+    SkPaint p;
+
+    SkRecord record;
+    SkRecorder recorder(&record, kWidth, kHeight);
+    recorder.drawRect(r1, p);
+    recorder.drawRect(r2, p);
+    recorder.drawRect(r3, p);
+
+    SkRecord rerecord;
+    SkRecorder canvas(&rerecord, kWidth, kHeight);
+    SkRecordPartialDraw(record, &canvas, r1, 1, 2, SkMatrix::I()); // replay just drawRect of r2
+
+    REPORTER_ASSERT(r, 3 == rerecord.count());
+    assert_type<SkRecords::Save>     (r, rerecord, 0);
+    assert_type<SkRecords::DrawRect> (r, rerecord, 1);
+    assert_type<SkRecords::Restore>  (r, rerecord, 2);
+
+    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1);
+    REPORTER_ASSERT(r, drawRect->rect == r2);
+}
+
+// Check that clears are converted to drawRects
+DEF_TEST(RecordDraw_PartialClear, r) {
+    static const int kWidth = 10, kHeight = 10;
+
+    SkRect rect = { 0, 0, kWidth, kHeight };
+
+    SkRecord record;
+    SkRecorder recorder(&record, kWidth, kHeight);
+    recorder.clear(SK_ColorRED);
+
+    SkRecord rerecord;
+    SkRecorder canvas(&rerecord, kWidth, kHeight);
+    SkRecordPartialDraw(record, &canvas, rect, 0, 1, SkMatrix::I()); // replay just the clear
+
+    REPORTER_ASSERT(r, 3 == rerecord.count());
+    assert_type<SkRecords::Save>    (r, rerecord, 0);
+    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
+    assert_type<SkRecords::Restore> (r, rerecord, 2);
+
+    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1);
+    REPORTER_ASSERT(r, drawRect->rect == rect);
+    REPORTER_ASSERT(r, drawRect->paint.getColor() == SK_ColorRED);
+}
+
+// A regression test for crbug.com/415468 and skbug.com/2957.
+//
+// This also now serves as a regression test for crbug.com/418417.  We used to adjust the
+// bounds for the saveLayer, clip, and restore to be greater than the bounds of the picture.
+// (We were applying the saveLayer paint to the bounds after restore, which makes no sense.)
+DEF_TEST(RecordDraw_SaveLayerAffectsClipBounds, r) {
+    SkRecord record;
+    SkRecorder recorder(&record, 50, 50);
+
+    // We draw a rectangle with a long drop shadow.  We used to not update the clip
+    // bounds based on SaveLayer paints, so the drop shadow could be cut off.
+    SkPaint paint;
+    paint.setImageFilter(SkDropShadowImageFilter::Create(20, 0, 0, 0, SK_ColorBLACK))->unref();
+
+    recorder.saveLayer(NULL, &paint);
+        recorder.clipRect(SkRect::MakeWH(20, 40));
+        recorder.drawRect(SkRect::MakeWH(20, 40), SkPaint());
+    recorder.restore();
+
+    // Under the original bug, the right edge value of the drawRect would be 20 less than asserted
+    // here because we intersected it with a clip that had not been adjusted for the drop shadow.
+    //
+    // The second bug showed up as adjusting the picture bounds (0,0,50,50) by the drop shadow too.
+    // The saveLayer, clipRect, and restore bounds were incorrectly (0,0,70,50).
+    TestBBH bbh;
+    SkRecordFillBounds(record, &bbh);
+    REPORTER_ASSERT(r, bbh.entries.count() == 4);
+    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[0].bounds, SkRect::MakeLTRB(0, 0, 50, 50)));
+    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[1].bounds, SkRect::MakeLTRB(0, 0, 50, 50)));
+    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[2].bounds, SkRect::MakeLTRB(0, 0, 40, 40)));
+    REPORTER_ASSERT(r, sloppy_rect_eq(bbh.entries[3].bounds, SkRect::MakeLTRB(0, 0, 50, 50)));
+}
diff --git a/tests/RecordOptsTest.cpp b/tests/RecordOptsTest.cpp
index 6a9f08a..c5c4471 100644
--- a/tests/RecordOptsTest.cpp
+++ b/tests/RecordOptsTest.cpp
@@ -16,102 +16,6 @@
 
 static const int W = 1920, H = 1080;
 
-DEF_TEST(RecordOpts_Culling, r) {
-    SkRecord record;
-    SkRecorder recorder(&record, W, H);
-
-    recorder.drawRect(SkRect::MakeWH(1000, 10000), SkPaint());
-
-    recorder.pushCull(SkRect::MakeWH(100, 100));
-        recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint());
-        recorder.drawRect(SkRect::MakeWH(30, 30), SkPaint());
-        recorder.pushCull(SkRect::MakeWH(5, 5));
-            recorder.drawRect(SkRect::MakeWH(1, 1), SkPaint());
-        recorder.popCull();
-    recorder.popCull();
-
-    SkRecordAnnotateCullingPairs(&record);
-
-    REPORTER_ASSERT(r, 6 == assert_type<SkRecords::PairedPushCull>(r, record, 1)->skip);
-    REPORTER_ASSERT(r, 2 == assert_type<SkRecords::PairedPushCull>(r, record, 4)->skip);
-}
-
-DEF_TEST(RecordOpts_NoopCulls, r) {
-    SkRecord record;
-    SkRecorder recorder(&record, W, H);
-
-    // All should be nooped.
-    recorder.pushCull(SkRect::MakeWH(200, 200));
-        recorder.pushCull(SkRect::MakeWH(100, 100));
-        recorder.popCull();
-    recorder.popCull();
-
-    // Kept for now.  We could peel off a layer of culling.
-    recorder.pushCull(SkRect::MakeWH(5, 5));
-        recorder.pushCull(SkRect::MakeWH(5, 5));
-            recorder.drawRect(SkRect::MakeWH(1, 1), SkPaint());
-        recorder.popCull();
-    recorder.popCull();
-
-    SkRecordNoopCulls(&record);
-
-    for (unsigned i = 0; i < 4; i++) {
-        assert_type<SkRecords::NoOp>(r, record, i);
-    }
-    assert_type<SkRecords::PushCull>(r, record, 4);
-    assert_type<SkRecords::PushCull>(r, record, 5);
-    assert_type<SkRecords::DrawRect>(r, record, 6);
-    assert_type<SkRecords::PopCull>(r, record, 7);
-    assert_type<SkRecords::PopCull>(r, record, 8);
-}
-
-static void draw_pos_text(SkCanvas* canvas, const char* text, bool constantY) {
-    const size_t len = strlen(text);
-    SkAutoTMalloc<SkPoint> pos(len);
-    for (size_t i = 0; i < len; i++) {
-        pos[i].fX = (SkScalar)i;
-        pos[i].fY = constantY ? SK_Scalar1 : (SkScalar)i;
-    }
-    canvas->drawPosText(text, len, pos, SkPaint());
-}
-
-DEF_TEST(RecordOpts_StrengthReduction, r) {
-    SkRecord record;
-    SkRecorder recorder(&record, W, H);
-
-    // We can convert a drawPosText into a drawPosTextH when all the Ys are the same.
-    draw_pos_text(&recorder, "This will be reduced to drawPosTextH.", true);
-    draw_pos_text(&recorder, "This cannot be reduced to drawPosTextH.", false);
-
-    SkRecordReduceDrawPosTextStrength(&record);
-
-    assert_type<SkRecords::DrawPosTextH>(r, record, 0);
-    assert_type<SkRecords::DrawPosText>(r, record, 1);
-}
-
-DEF_TEST(RecordOpts_TextBounding, r) {
-    SkRecord record;
-    SkRecorder recorder(&record, W, H);
-
-    // First, get a drawPosTextH.  Here's a handy way.  Its text size will be the default (12).
-    draw_pos_text(&recorder, "This will be reduced to drawPosTextH.", true);
-    SkRecordReduceDrawPosTextStrength(&record);
-
-    const SkRecords::DrawPosTextH* original =
-        assert_type<SkRecords::DrawPosTextH>(r, record, 0);
-
-    // This should wrap the original DrawPosTextH with minY and maxY.
-    SkRecordBoundDrawPosTextH(&record);
-
-    const SkRecords::BoundedDrawPosTextH* bounded =
-        assert_type<SkRecords::BoundedDrawPosTextH>(r, record, 0);
-
-    const SkPaint defaults;
-    REPORTER_ASSERT(r, bounded->base == original);
-    REPORTER_ASSERT(r, bounded->minY <= SK_Scalar1 - defaults.getTextSize());
-    REPORTER_ASSERT(r, bounded->maxY >= SK_Scalar1 + defaults.getTextSize());
-}
-
 DEF_TEST(RecordOpts_NoopDrawSaveRestore, r) {
     SkRecord record;
     SkRecorder recorder(&record, W, H);
@@ -171,6 +75,23 @@
     }
 }
 
+DEF_TEST(RecordOpts_SaveSaveLayerRestoreRestore, r) {
+    SkRecord record;
+    SkRecorder recorder(&record, W, H);
+
+    // A previous bug NoOp'd away the first 3 commands.
+    recorder.save();
+        recorder.saveLayer(NULL, NULL);
+        recorder.restore();
+    recorder.restore();
+
+    SkRecordNoopSaveRestores(&record);
+    assert_type<SkRecords::Save>     (r, record, 0);
+    assert_type<SkRecords::SaveLayer>(r, record, 1);
+    assert_type<SkRecords::Restore>  (r, record, 2);
+    assert_type<SkRecords::Restore>  (r, record, 3);
+}
+
 static void assert_savelayer_restore(skiatest::Reporter* r,
                                      SkRecord* record,
                                      unsigned i,
diff --git a/tests/RecordReplaceDrawTest.cpp b/tests/RecordReplaceDrawTest.cpp
new file mode 100644
index 0000000..618be72
--- /dev/null
+++ b/tests/RecordReplaceDrawTest.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#if SK_SUPPORT_GPU
+
+#include "Test.h"
+#include "RecordTestUtils.h"
+
+#include "SkBBHFactory.h"
+#include "SkRecordDraw.h"
+#include "SkRecorder.h"
+#include "SkUtils.h"
+#include "GrRecordReplaceDraw.h"
+
+static const int kWidth = 100;
+static const int kHeight = 100;
+
+class JustOneDraw : public SkDrawPictureCallback {
+public:
+    JustOneDraw() : fCalls(0) {}
+
+    virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
+private:
+    int fCalls;
+};
+
+// Make sure the abort callback works
+DEF_TEST(RecordReplaceDraw_Abort, r) {
+    // Record two commands.
+    SkRecord record;
+    SkRecorder recorder(&record, kWidth, kHeight);
+    recorder.drawRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)), SkPaint());
+    recorder.clipRect(SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)));
+
+    SkRecord rerecord;
+    SkRecorder canvas(&rerecord, kWidth, kHeight);
+
+    GrReplacements replacements;
+    JustOneDraw callback;
+    GrRecordReplaceDraw(record, &canvas, NULL/*bbh*/, &replacements, &callback);
+
+    REPORTER_ASSERT(r, 3 == rerecord.count());
+    assert_type<SkRecords::Save>(r, rerecord, 0);
+    assert_type<SkRecords::DrawRect>(r, rerecord, 1);
+    assert_type<SkRecords::Restore>(r, rerecord, 2);
+}
+
+// Make sure GrRecordReplaceDraw balances unbalanced saves
+DEF_TEST(RecordReplaceDraw_Unbalanced, r) {
+    SkRecord record;
+    SkRecorder recorder(&record, kWidth, kHeight);
+    recorder.save();  // We won't balance this, but GrRecordReplaceDraw will for us.
+
+    SkRecord rerecord;
+    SkRecorder canvas(&rerecord, kWidth, kHeight);
+
+    GrReplacements replacements;
+    GrRecordReplaceDraw(record, &canvas, NULL/*bbh*/, &replacements, NULL/*callback*/);
+
+    REPORTER_ASSERT(r, 4 == rerecord.count());
+    assert_type<SkRecords::Save>(r, rerecord, 0);
+    assert_type<SkRecords::Save>(r, rerecord, 1);
+    assert_type<SkRecords::Restore>(r, rerecord, 2);
+    assert_type<SkRecords::Restore>(r, rerecord, 3);
+}
+
+static SkImage* make_image(SkColor color) {
+    const SkPMColor pmcolor = SkPreMultiplyColor(color);
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
+    const size_t rowBytes = info.minRowBytes();
+    const size_t size = rowBytes * info.height();
+
+    SkAutoMalloc addr(size);
+    sk_memset32((SkPMColor*)addr.get(), pmcolor, SkToInt(size >> 2));
+
+    return SkImage::NewRasterCopy(info, addr.get(), rowBytes);
+}
+
+// Test out the layer replacement functionality with and w/o a BBH
+void test_replacements(skiatest::Reporter* r, bool useBBH) {
+    SkRecord record;
+    SkRecorder recorder(&record, kWidth, kHeight);
+    SkAutoTDelete<SkPaint> paint(SkNEW(SkPaint));
+    recorder.saveLayer(NULL, paint);
+    recorder.clear(SK_ColorRED);
+    recorder.restore();
+    recorder.drawRect(SkRect::MakeWH(SkIntToScalar(kWidth/2), SkIntToScalar(kHeight/2)), 
+                      SkPaint());
+
+    GrReplacements replacements;
+    GrReplacements::ReplacementInfo* ri = replacements.push();
+    ri->fStart = 0;
+    ri->fStop = 2;
+    ri->fPos.set(0, 0);
+    ri->fImage = make_image(SK_ColorRED);
+    ri->fPaint = SkNEW(SkPaint);
+    ri->fSrcRect = SkIRect::MakeWH(kWidth, kHeight);
+
+    SkAutoTUnref<SkBBoxHierarchy> bbh;
+
+    if (useBBH) {
+        SkRTreeFactory factory;
+        bbh.reset((factory)(kWidth, kHeight));
+        SkRecordFillBounds(record, bbh);
+    }
+
+    SkRecord rerecord;
+    SkRecorder canvas(&rerecord, kWidth, kHeight);
+    GrRecordReplaceDraw(record, &canvas, bbh, &replacements, NULL/*callback*/);
+
+    REPORTER_ASSERT(r, 7 == rerecord.count());
+    assert_type<SkRecords::Save>(r, rerecord, 0);
+    assert_type<SkRecords::Save>(r, rerecord, 1);
+    assert_type<SkRecords::SetMatrix>(r, rerecord, 2);
+    assert_type<SkRecords::DrawBitmapRectToRect>(r, rerecord, 3);
+    assert_type<SkRecords::Restore>(r, rerecord, 4);
+    assert_type<SkRecords::DrawRect>(r, rerecord, 5);
+    assert_type<SkRecords::Restore>(r, rerecord, 6);
+}
+
+DEF_TEST(RecordReplaceDraw_Replace, r)        { test_replacements(r, false); }
+DEF_TEST(RecordReplaceDraw_ReplaceWithBBH, r) { test_replacements(r, true); }
+
+#endif
diff --git a/tests/RecordTest.cpp b/tests/RecordTest.cpp
index 96f3ad4..2a0e615 100644
--- a/tests/RecordTest.cpp
+++ b/tests/RecordTest.cpp
@@ -7,6 +7,9 @@
 
 #include "Test.h"
 
+#include "SkBitmap.h"
+#include "SkImageInfo.h"
+#include "SkShader.h"
 #include "SkRecord.h"
 #include "SkRecords.h"
 
@@ -48,6 +51,8 @@
     }
 };
 
+#define APPEND(record, type, ...) SkNEW_PLACEMENT_ARGS(record.append<type>(), type, (__VA_ARGS__))
+
 // Basic tests for the low-level SkRecord code.
 DEF_TEST(Record, r) {
     SkRecord record;
@@ -55,7 +60,7 @@
     // Add a simple DrawRect command.
     SkRect rect = SkRect::MakeWH(10, 10);
     SkPaint paint;
-    SkNEW_PLACEMENT_ARGS(record.append<SkRecords::DrawRect>(), SkRecords::DrawRect, (paint, rect));
+    APPEND(record, SkRecords::DrawRect, paint, rect);
 
     // Its area should be 100.
     AreaSummer summer;
@@ -70,3 +75,31 @@
     summer.apply(record);
     REPORTER_ASSERT(r, summer.area() == 500);
 }
+
+#undef APPEND
+
+template <typename T>
+static bool is_aligned(const T* p) {
+    return (((uintptr_t)p) & (sizeof(T) - 1)) == 0;
+}
+
+DEF_TEST(Record_Alignment, r) {
+    SkRecord record;
+
+    // Of course a byte's always aligned.
+    REPORTER_ASSERT(r, is_aligned(record.alloc<uint8_t>()));
+
+    // (If packed tightly, the rest below here would be off by one.)
+
+    // It happens that the first implementation always aligned to 4 bytes,
+    // so these two were always correct.
+    REPORTER_ASSERT(r, is_aligned(record.alloc<uint16_t>()));
+    REPORTER_ASSERT(r, is_aligned(record.alloc<uint32_t>()));
+
+    // These two are regression tests (void* only on 64-bit machines).
+    REPORTER_ASSERT(r, is_aligned(record.alloc<uint64_t>()));
+    REPORTER_ASSERT(r, is_aligned(record.alloc<void*>()));
+
+    // We're not testing beyond sizeof(void*), which is where the current implementation will break.
+}
+
diff --git a/tests/RecordTestUtils.h b/tests/RecordTestUtils.h
index db3f02d..0575b83 100644
--- a/tests/RecordTestUtils.h
+++ b/tests/RecordTestUtils.h
@@ -24,7 +24,7 @@
     ReadAs<T> reader;
     record.visit<void>(index, reader);
     REPORTER_ASSERT(r, T::kType == reader.type);
-    REPORTER_ASSERT(r, NULL != reader.ptr);
+    REPORTER_ASSERT(r, SkToBool(reader.ptr));
     return reader.ptr;
 }
 
diff --git a/tests/RecorderTest.cpp b/tests/RecorderTest.cpp
index c1d9638..aced54f 100644
--- a/tests/RecorderTest.cpp
+++ b/tests/RecorderTest.cpp
@@ -7,11 +7,11 @@
 
 #include "Test.h"
 
+#include "SkPictureRecorder.h"
 #include "SkRecord.h"
 #include "SkRecorder.h"
 #include "SkRecords.h"
-
-#include "SkEmptyShader.h"
+#include "SkShader.h"
 
 #define COUNT(T) + 1
 static const int kRecordTypes = SK_RECORD_TYPES(COUNT);
@@ -49,6 +49,39 @@
     REPORTER_ASSERT(r, 1 == tally.count<SkRecords::DrawRect>());
 }
 
+// All of Skia will work fine without support for comment groups, but
+// Chrome's inspector can break.  This serves as a simple regression test.
+DEF_TEST(Recorder_CommentGroups, r) {
+    SkRecord record;
+    SkRecorder recorder(&record, 1920, 1080);
+
+    recorder.beginCommentGroup("test");
+        recorder.addComment("foo", "bar");
+        recorder.addComment("baz", "quux");
+    recorder.endCommentGroup();
+
+    Tally tally;
+    tally.apply(record);
+
+    REPORTER_ASSERT(r, 1 == tally.count<SkRecords::BeginCommentGroup>());
+    REPORTER_ASSERT(r, 2 == tally.count<SkRecords::AddComment>());
+    REPORTER_ASSERT(r, 1 == tally.count<SkRecords::EndCommentGroup>());
+}
+
+// DrawData is similar to comment groups.  It doesn't affect drawing, but
+// it's a pass-through we provide to the client.  Again, a simple reg. test.
+DEF_TEST(Recorder_DrawData, r) {
+    SkRecord record;
+    SkRecorder recorder(&record, 100, 100);
+
+    const char* data = "This sure is some data, eh?";
+    recorder.drawData(data, strlen(data));
+
+    Tally tally;
+    tally.apply(record);
+    REPORTER_ASSERT(r, 1 == tally.count<SkRecords::DrawData>());
+}
+
 // Regression test for leaking refs held by optional arguments.
 DEF_TEST(Recorder_RefLeaking, r) {
     // We use SaveLayer to test:
@@ -57,7 +90,7 @@
 
     SkRect bounds = SkRect::MakeWH(320, 240);
     SkPaint paint;
-    paint.setShader(SkNEW(SkEmptyShader))->unref();
+    paint.setShader(SkShader::CreateEmptyShader())->unref();
 
     REPORTER_ASSERT(r, paint.getShader()->unique());
     {
@@ -68,3 +101,52 @@
     }
     REPORTER_ASSERT(r, paint.getShader()->unique());
 }
+
+DEF_TEST(Recorder_RefPictures, r) {
+    SkAutoTUnref<SkPicture> pic;
+
+    {
+        SkPictureRecorder pr;
+        SkCanvas* canvas = pr.beginRecording(100, 100);
+        canvas->drawColor(SK_ColorRED);
+        pic.reset(pr.endRecording());
+    }
+    REPORTER_ASSERT(r, pic->unique());
+
+    {
+        SkRecord record;
+        SkRecorder recorder(&record, 100, 100);
+        recorder.drawPicture(pic);
+        // the recorder should now also be an owner
+        REPORTER_ASSERT(r, !pic->unique());
+    }
+    // the recorder destructor should have released us (back to unique)
+    REPORTER_ASSERT(r, pic->unique());
+}
+
+DEF_TEST(Recorder_IsDrawingToLayer, r) {
+    SkRecord record;
+    SkRecorder recorder(&record, 100, 100);
+
+    // We'll save, saveLayer, save, and saveLayer, then restore them all,
+    // checking that isDrawingToLayer() is correct at each step.
+
+    REPORTER_ASSERT(r, !recorder.isDrawingToLayer());
+    recorder.save();
+        REPORTER_ASSERT(r, !recorder.isDrawingToLayer());
+        recorder.saveLayer(NULL, NULL);
+            REPORTER_ASSERT(r, recorder.isDrawingToLayer());
+            recorder.save();
+                REPORTER_ASSERT(r, recorder.isDrawingToLayer());
+                recorder.saveLayer(NULL, NULL);
+                    REPORTER_ASSERT(r, recorder.isDrawingToLayer());
+                recorder.restore();
+                REPORTER_ASSERT(r, recorder.isDrawingToLayer());
+            recorder.restore();
+            REPORTER_ASSERT(r, recorder.isDrawingToLayer());
+        recorder.restore();
+        REPORTER_ASSERT(r, !recorder.isDrawingToLayer());
+    recorder.restore();
+    REPORTER_ASSERT(r, !recorder.isDrawingToLayer());
+}
+
diff --git a/tests/RecordingTest.cpp b/tests/RecordingTest.cpp
index 8de52da..0066556 100644
--- a/tests/RecordingTest.cpp
+++ b/tests/RecordingTest.cpp
@@ -11,7 +11,7 @@
 
 // Minimally exercise the public SkRecording API.
 
-DEF_TEST(RecordingTest, r) {
+DEF_TEST(SkRecording, r) {
     EXPERIMENTAL::SkRecording recording(1920, 1080);
 
     // Some very exciting commands here.
diff --git a/tests/RecordingXfermodeTest.cpp b/tests/RecordingXfermodeTest.cpp
new file mode 100644
index 0000000..8da81b3
--- /dev/null
+++ b/tests/RecordingXfermodeTest.cpp
@@ -0,0 +1,240 @@
+/*
+ * 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 "Test.h"
+
+#include "../include/core/SkCanvas.h"
+#include "../include/core/SkPicture.h"
+#include "../include/core/SkStream.h"
+#include "../include/core/SkString.h"
+#include "../include/record/SkRecording.h"
+#include "../include/core/SkPictureRecorder.h"
+#include <cstring>
+
+// Verify that replay of a recording into a clipped canvas
+// produces the correct bitmap.
+// This arose from http://crbug.com/401593 which has
+// https://code.google.com/p/skia/issues/detail?id=1291 as its root cause.
+
+
+namespace {
+
+class Drawer {
+ public:
+    explicit Drawer()
+            : fImageInfo(SkImageInfo::MakeN32Premul(200,100))
+    {
+        fCircleBM.allocPixels( SkImageInfo::MakeN32Premul(100,100) );
+        SkCanvas canvas(fCircleBM);
+        canvas.clear(0xffffffff);
+        SkPaint circlePaint;
+        circlePaint.setColor(0xff000000);
+        canvas.drawCircle(50,50,50,circlePaint);
+    }
+
+    const SkImageInfo& imageInfo() const { return fImageInfo; }
+
+    void draw(SkCanvas* canvas, const SkRect& clipRect, SkXfermode::Mode mode) const {
+        SkPaint greenPaint;
+        greenPaint.setColor(0xff008000);
+        SkPaint blackPaint;
+        blackPaint.setColor(0xff000000);
+        SkPaint whitePaint;
+        whitePaint.setColor(0xffffffff);
+        SkPaint layerPaint;
+        layerPaint.setColor(0xff000000);
+        layerPaint.setXfermodeMode(mode);
+        SkRect canvasRect(SkRect::MakeWH(SkIntToScalar(fImageInfo.width()),SkIntToScalar(fImageInfo.height())));
+
+        canvas->clipRect(clipRect);
+        canvas->clear(0xff000000);
+
+        canvas->saveLayer(NULL,&blackPaint);
+            canvas->drawRect(canvasRect,greenPaint);
+            canvas->saveLayer(NULL,&layerPaint);
+                canvas->drawBitmapRect(fCircleBM,SkRect::MakeXYWH(20,20,60,60),&blackPaint);
+            canvas->restore();
+        canvas->restore();
+    }
+
+ private:
+    const SkImageInfo fImageInfo;
+    SkBitmap fCircleBM;
+};
+
+class RecordingStrategy {
+ public:
+    virtual ~RecordingStrategy() {}
+    virtual void init(const SkImageInfo&) = 0;
+    virtual const SkBitmap& recordAndReplay(const Drawer& drawer,
+                                            const SkRect& intoClip,
+                                            SkXfermode::Mode) = 0;
+};
+
+class BitmapBackedCanvasStrategy : public RecordingStrategy {
+    // This version just draws into a bitmap-backed canvas.
+ public:
+    BitmapBackedCanvasStrategy() {}
+
+    virtual void init(const SkImageInfo& imageInfo) {
+        fBitmap.allocPixels(imageInfo);
+    }
+
+    virtual const SkBitmap& recordAndReplay(const Drawer& drawer,
+                                            const SkRect& intoClip,
+                                            SkXfermode::Mode mode) {
+        SkCanvas canvas(fBitmap);
+        canvas.clear(0xffffffff);
+        // Note that the scene is drawn just into the clipped region!
+        canvas.clipRect(intoClip);
+        drawer.draw(&canvas, intoClip, mode); // Shouild be canvas-wide...
+        return fBitmap;
+    }
+
+ private:
+    SkBitmap fBitmap;
+};
+
+class DeprecatedRecorderStrategy : public RecordingStrategy {
+    // This version draws the entire scene into an SkPictureRecorder,
+    // using the deprecated recording backend.
+    // Then it then replays the scene through a clip rectangle.
+    // This backend proved to be buggy.
+ public:
+    DeprecatedRecorderStrategy() {}
+
+    virtual void init(const SkImageInfo& imageInfo) {
+        fBitmap.allocPixels(imageInfo);
+        fWidth = imageInfo.width();
+        fHeight= imageInfo.height();
+    }
+
+    virtual const SkBitmap& recordAndReplay(const Drawer& drawer,
+                                            const SkRect& intoClip,
+                                            SkXfermode::Mode mode) {
+        SkTileGridFactory::TileGridInfo tileGridInfo = { {100,100}, {0,0}, {0,0} };
+        SkTileGridFactory factory(tileGridInfo);
+        SkPictureRecorder recorder;
+        SkRect canvasRect(SkRect::MakeWH(SkIntToScalar(fWidth),SkIntToScalar(fHeight)));
+        SkCanvas* canvas = recorder.DEPRECATED_beginRecording( SkIntToScalar(fWidth), SkIntToScalar(fHeight), &factory);
+        drawer.draw(canvas, canvasRect, mode);
+        SkAutoTDelete<SkPicture> picture(recorder.endRecording());
+
+        SkCanvas replayCanvas(fBitmap);
+        replayCanvas.clear(0xffffffff);
+        replayCanvas.clipRect(intoClip);
+        picture->playback(&replayCanvas);
+
+        return fBitmap;
+    }
+
+ private:
+    SkBitmap fBitmap;
+    int fWidth;
+    int fHeight;
+};
+
+class NewRecordingStrategy : public RecordingStrategy {
+    // This version draws the entire scene into an SkPictureRecorder,
+    // using the new recording backend.
+    // Then it then replays the scene through a clip rectangle.
+    // This backend proved to be buggy.
+ public:
+    NewRecordingStrategy() {}
+
+    virtual void init(const SkImageInfo& imageInfo) {
+        fBitmap.allocPixels(imageInfo);
+        fWidth = imageInfo.width();
+        fHeight= imageInfo.height();
+    }
+
+    virtual const SkBitmap& recordAndReplay(const Drawer& drawer,
+                                            const SkRect& intoClip,
+                                            SkXfermode::Mode mode) {
+        SkTileGridFactory::TileGridInfo tileGridInfo = { {100,100}, {0,0}, {0,0} };
+        SkTileGridFactory factory(tileGridInfo);
+        SkPictureRecorder recorder;
+        SkRect canvasRect(SkRect::MakeWH(SkIntToScalar(fWidth),SkIntToScalar(fHeight)));
+        SkCanvas* canvas = recorder.EXPERIMENTAL_beginRecording( SkIntToScalar(fWidth), SkIntToScalar(fHeight), &factory);
+
+        drawer.draw(canvas, canvasRect, mode);
+        SkAutoTDelete<SkPicture> picture(recorder.endRecording());
+
+        SkCanvas replayCanvas(fBitmap);
+        replayCanvas.clear(0xffffffff);
+        replayCanvas.clipRect(intoClip);
+        picture->playback(&replayCanvas);
+        return fBitmap;
+    }
+
+ private:
+    SkBitmap fBitmap;
+    int fWidth;
+    int fHeight;
+};
+
+}
+
+
+
+DEF_TEST(SkRecordingAccuracyXfermode, reporter) {
+#define FINEGRAIN 0
+
+    const Drawer drawer;
+
+    BitmapBackedCanvasStrategy golden; // This is the expected result.
+    DeprecatedRecorderStrategy deprecatedRecording;
+    NewRecordingStrategy newRecording;
+
+    golden.init(drawer.imageInfo());
+    deprecatedRecording.init(drawer.imageInfo());
+    newRecording.init(drawer.imageInfo());
+
+#if !FINEGRAIN
+    unsigned numErrors = 0;
+    SkString errors;
+#endif
+
+    for (int iMode = 0; iMode < int(SkXfermode::kLastMode) ; iMode++ ) {
+        const SkRect& clip = SkRect::MakeXYWH(100,0,100,100);
+        SkXfermode::Mode mode = SkXfermode::Mode(iMode);
+
+        const SkBitmap& goldenBM = golden.recordAndReplay(drawer, clip, mode);
+        const SkBitmap& deprecatedBM = deprecatedRecording.recordAndReplay(drawer, clip, mode);
+        const SkBitmap& newRecordingBM = newRecording.recordAndReplay(drawer, clip, mode);
+
+        size_t pixelsSize = goldenBM.getSize();
+        REPORTER_ASSERT( reporter, pixelsSize == deprecatedBM.getSize() );
+        REPORTER_ASSERT( reporter, pixelsSize == newRecordingBM.getSize() );
+
+        // The pixel arrays should match.
+#if FINEGRAIN
+        REPORTER_ASSERT_MESSAGE( reporter,
+                                 0==memcmp( goldenBM.getPixels(), deprecatedBM.getPixels(), pixelsSize ),
+                                 "Tiled bitmap is wrong");
+        REPORTER_ASSERT_MESSAGE( reporter,
+                                 0==memcmp( goldenBM.getPixels(), recordingBM.getPixels(), pixelsSize ),
+                                 "SkRecorder bitmap is wrong");
+#else
+        if ( memcmp( goldenBM.getPixels(), deprecatedBM.getPixels(), pixelsSize ) ) {
+            numErrors++;
+            SkString str;
+            str.printf("For SkXfermode %d %s:    Deprecated recorder bitmap is wrong\n", iMode, SkXfermode::ModeName(mode));
+            errors.append(str);
+        }
+        if ( memcmp( goldenBM.getPixels(), newRecordingBM.getPixels(), pixelsSize ) ) {
+            numErrors++;
+            SkString str;
+            str.printf("For SkXfermode %d %s:    SkPictureRecorder bitmap is wrong\n", iMode, SkXfermode::ModeName(mode));
+            errors.append(str);
+        }
+#endif
+    }
+#if !FINEGRAIN
+    REPORTER_ASSERT_MESSAGE( reporter, 0==numErrors, errors.c_str() );
+#endif
+}
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 78c1124..f9f94d1 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -7,9 +7,10 @@
 
 #if SK_SUPPORT_GPU
 
+#include "SkCanvas.h"
 #include "GrContextFactory.h"
 #include "GrResourceCache.h"
-#include "SkGpuDevice.h"
+#include "SkSurface.h"
 #include "Test.h"
 
 static const int gWidth = 640;
@@ -58,25 +59,28 @@
     context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
 }
 
-class TestResource : public GrCacheable {
+class TestResource : public GrGpuResource {
     static const size_t kDefaultSize = 100;
 
 public:
     SK_DECLARE_INST_COUNT(TestResource);
-    TestResource(size_t size = kDefaultSize)
-        : fCache(NULL)
+    TestResource(GrGpu* gpu, size_t size = kDefaultSize)
+        : INHERITED(gpu, false)
+        , fCache(NULL)
         , fToDelete(NULL)
         , fSize(size) {
         ++fAlive;
+        this->registerWithCache();
     }
 
     ~TestResource() {
         --fAlive;
-        if (NULL != fToDelete) {
+        if (fToDelete) {
             // Breaks our little 2-element cycle below.
             fToDelete->setDeleteWhenDestroyed(NULL, NULL);
             fCache->deleteResource(fToDelete->getCacheEntry());
         }
+        this->release();
     }
 
     void setSize(size_t size) {
@@ -86,8 +90,6 @@
 
     size_t gpuMemorySize() const SK_OVERRIDE { return fSize; }
 
-    bool isValidOnGpu() const SK_OVERRIDE { return true; }
-
     static int alive() { return fAlive; }
 
     void setDeleteWhenDestroyed(GrResourceCache* cache, TestResource* resource) {
@@ -101,7 +103,7 @@
     size_t fSize;
     static int fAlive;
 
-    typedef GrCacheable INHERITED;
+    typedef GrGpuResource INHERITED;
 };
 int TestResource::fAlive = 0;
 
@@ -116,8 +118,8 @@
     GrResourceCache cache(5, 30000);
 
     // Add two resources with the same key that delete each other from the cache when destroyed.
-    TestResource* a = new TestResource();
-    TestResource* b = new TestResource();
+    TestResource* a = new TestResource(context->getGpu());
+    TestResource* b = new TestResource(context->getGpu());
     cache.addResource(key, a);
     cache.addResource(key, b);
     // Circle back.
@@ -127,7 +129,7 @@
     b->unref();
 
     // Add a third independent resource also with the same key.
-    GrCacheable* r = new TestResource();
+    GrGpuResource* r = new TestResource(context->getGpu());
     cache.addResource(key, r);
     r->unref();
 
@@ -152,8 +154,8 @@
     {
         {
             GrResourceCache cache(3, 30000);
-            TestResource* a = new TestResource();
-            TestResource* b = new TestResource();
+            TestResource* a = new TestResource(context->getGpu());
+            TestResource* b = new TestResource(context->getGpu());
             cache.addResource(key, a);
             cache.addResource(key, b);
 
@@ -168,8 +170,8 @@
     }
     {
         GrResourceCache cache(3, 30000);
-        TestResource* a = new TestResource();
-        TestResource* b = new TestResource();
+        TestResource* a = new TestResource(context->getGpu());
+        TestResource* b = new TestResource(context->getGpu());
         cache.addResource(key, a);
         cache.addResource(key, b);
 
@@ -204,12 +206,12 @@
     {
         GrResourceCache cache(2, 300);
 
-        TestResource* a = new TestResource(0);
+        TestResource* a = new TestResource(context->getGpu());
         a->setSize(100); // Test didChangeGpuMemorySize() when not in the cache.
         cache.addResource(key1, a);
         a->unref();
 
-        TestResource* b = new TestResource(0);
+        TestResource* b = new TestResource(context->getGpu());
         b->setSize(100);
         cache.addResource(key2, b);
         b->unref();
@@ -228,11 +230,11 @@
     {
         GrResourceCache cache(2, 300);
 
-        TestResource* a = new TestResource(100);
+        TestResource* a = new TestResource(context->getGpu(), 100);
         cache.addResource(key1, a);
         a->unref();
 
-        TestResource* b = new TestResource(100);
+        TestResource* b = new TestResource(context->getGpu(), 100);
         cache.addResource(key2, b);
         b->unref();
 
@@ -250,11 +252,11 @@
     {
         GrResourceCache cache(2, 300);
 
-        TestResource* a = new TestResource(100);
+        TestResource* a = new TestResource(context->getGpu(), 100);
         cache.addResource(key1, a);
         cache.makeExclusive(a->getCacheEntry());
 
-        TestResource* b = new TestResource(100);
+        TestResource* b = new TestResource(context->getGpu(), 100);
         cache.addResource(key2, b);
         b->unref();
 
@@ -273,7 +275,7 @@
 
         REPORTER_ASSERT(reporter, 300 == cache.getCachedResourceBytes());
         REPORTER_ASSERT(reporter, 2 == cache.getCachedResourceCount());
-        REPORTER_ASSERT(reporter, NULL != cache.find(key1));
+        REPORTER_ASSERT(reporter, cache.find(key1));
         // Internal resource cache validation will test the detached size (debug mode only).
     }
 }
@@ -295,12 +297,10 @@
         desc.fFlags = kRenderTarget_GrTextureFlagBit;
         desc.fWidth = gWidth;
         desc.fHeight = gHeight;
+        SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, info));
 
-        SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
-        SkAutoTUnref<SkGpuDevice> device(SkNEW_ARGS(SkGpuDevice, (context, texture.get())));
-        SkCanvas canvas(device.get());
-
-        test_cache(reporter, context, &canvas);
+        test_cache(reporter, context, surface->getCanvas());
         test_purge_invalidated(reporter, context);
         test_cache_delete_on_destruction(reporter, context);
         test_resource_size_changed(reporter, context);
diff --git a/tests/RoundRectTest.cpp b/tests/RoundRectTest.cpp
index 0a528a6..261ec67 100644
--- a/tests/RoundRectTest.cpp
+++ b/tests/RoundRectTest.cpp
@@ -582,6 +582,35 @@
     }
 }
 
+// Test out the case where an oval already off in space is translated/scaled 
+// further off into space - yielding numerical issues when the rect & radii
+// are transformed separatly
+// BUG=skia:2696
+static void test_issue_2696(skiatest::Reporter* reporter) {
+    SkRRect rrect;
+    SkRect r = { 28443.8594f, 53.1428604f, 28446.7148f, 56.0000038f };
+    rrect.setOval(r);
+
+    SkMatrix xform;
+    xform.setAll(2.44f,  0.0f, 485411.7f,
+                 0.0f,  2.44f,   -438.7f,
+                 0.0f,   0.0f,      1.0f);
+    SkRRect dst;
+
+    bool success = rrect.transform(xform, &dst);
+    REPORTER_ASSERT(reporter, success);
+
+    SkScalar halfWidth = SkScalarHalf(dst.width());
+    SkScalar halfHeight = SkScalarHalf(dst.height());
+
+    for (int i = 0; i < 4; ++i) {
+        REPORTER_ASSERT(reporter, 
+                        SkScalarNearlyEqual(dst.radii((SkRRect::Corner)i).fX, halfWidth));
+        REPORTER_ASSERT(reporter, 
+                        SkScalarNearlyEqual(dst.radii((SkRRect::Corner)i).fY, halfHeight));
+    }
+}
+
 DEF_TEST(RoundRect, reporter) {
     test_round_rect_basic(reporter);
     test_round_rect_rects(reporter);
@@ -591,4 +620,5 @@
     test_inset(reporter);
     test_round_rect_contains_rect(reporter);
     test_round_rect_transform(reporter);
+    test_issue_2696(reporter);
 }
diff --git a/tests/SListTest.cpp b/tests/SListTest.cpp
index 72a8281..78fcc65 100644
--- a/tests/SListTest.cpp
+++ b/tests/SListTest.cpp
@@ -27,7 +27,7 @@
         ERRORF(reporter, "%s - List count is not zero, %d instead", stage, list.getCount());
         return false;
     }
-    if (NULL != list.head()) {
+    if (list.head()) {
         ERRORF(reporter, "%s - List has elements when empty", stage);
         return false;
     }
@@ -55,7 +55,7 @@
         }
         next = next->next();
     }
-    if (NULL != next) {
+    if (next) {
         ERRORF(reporter, "%s - List too long, should be %d", stage, count);
         return false;
     }
diff --git a/tests/ScaledImageCache.cpp b/tests/ScaledImageCache.cpp
deleted file mode 100644
index 2040afe..0000000
--- a/tests/ScaledImageCache.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 "Test.h"
-#include "SkGraphics.h"
-#include "SkCanvas.h"
-
-static const int kCanvasSize = 1;
-static const int kBitmapSize = 16;
-static const int kScale = 8;
-
-static size_t test_scaled_image_cache_useage() {
-    SkAutoTUnref<SkCanvas> canvas(
-            SkCanvas::NewRasterN32(kCanvasSize, kCanvasSize));
-    SkBitmap bitmap;
-    SkAssertResult(bitmap.allocN32Pixels(kBitmapSize, kBitmapSize));
-    SkScalar scaledSize = SkIntToScalar(kScale * kBitmapSize);
-    canvas->clipRect(SkRect::MakeLTRB(0, 0, scaledSize, scaledSize));
-    SkPaint paint;
-    paint.setFilterLevel(SkPaint::kHigh_FilterLevel);
-    size_t bytesUsed = SkGraphics::GetImageCacheBytesUsed();
-    canvas->drawBitmapRect(bitmap,
-                           SkRect::MakeLTRB(0, 0, scaledSize, scaledSize),
-                           &paint);
-    return SkGraphics::GetImageCacheBytesUsed() - bytesUsed;
-}
-
-// http://crbug.com/389439
-DEF_TEST(ScaledImageCache_SingleAllocationByteLimit, reporter) {
-    size_t originalByteLimit = SkGraphics::GetImageCacheByteLimit();
-    size_t originalAllocationLimit =
-        SkGraphics::GetImageCacheSingleAllocationByteLimit();
-
-    size_t size = kBitmapSize * kScale * kBitmapSize * kScale
-        * SkColorTypeBytesPerPixel(kN32_SkColorType);
-
-    SkGraphics::SetImageCacheByteLimit(0); // clear cache
-    SkGraphics::SetImageCacheByteLimit(2 * size);
-    SkGraphics::SetImageCacheSingleAllocationByteLimit(0);
-
-    REPORTER_ASSERT(reporter, size == test_scaled_image_cache_useage());
-
-    SkGraphics::SetImageCacheByteLimit(0); // clear cache
-    SkGraphics::SetImageCacheByteLimit(2 * size);
-    SkGraphics::SetImageCacheSingleAllocationByteLimit(size * 2);
-
-    REPORTER_ASSERT(reporter, size == test_scaled_image_cache_useage());
-
-    SkGraphics::SetImageCacheByteLimit(0); // clear cache
-    SkGraphics::SetImageCacheByteLimit(2 * size);
-    SkGraphics::SetImageCacheSingleAllocationByteLimit(size / 2);
-
-    REPORTER_ASSERT(reporter, 0 == test_scaled_image_cache_useage());
-
-    SkGraphics::SetImageCacheSingleAllocationByteLimit(originalAllocationLimit);
-    SkGraphics::SetImageCacheByteLimit(originalByteLimit);
-}
diff --git a/tests/SerializationTest.cpp b/tests/SerializationTest.cpp
index ce91490..dd9b938 100644
--- a/tests/SerializationTest.cpp
+++ b/tests/SerializationTest.cpp
@@ -5,12 +5,15 @@
  * found in the LICENSE file.
  */
 
-#include "SkBitmapDevice.h"
+#include "Resources.h"
 #include "SkBitmapSource.h"
 #include "SkCanvas.h"
 #include "SkMallocPixelRef.h"
+#include "SkOSFile.h"
 #include "SkPictureRecorder.h"
+#include "SkTableColorFilter.h"
 #include "SkTemplates.h"
+#include "SkTypeface.h"
 #include "SkWriteBuffer.h"
 #include "SkValidatingReadBuffer.h"
 #include "SkXfermodeImageFilter.h"
@@ -175,7 +178,7 @@
     size_t bytesWritten = writer.bytesWritten();
     REPORTER_ASSERT(reporter, SkAlign4(bytesWritten) == bytesWritten);
 
-    unsigned char dataWritten[1024];
+    unsigned char dataWritten[4096];
     SkASSERT(bytesWritten <= sizeof(dataWritten));
     writer.writeToMemory(dataWritten);
 
@@ -196,7 +199,7 @@
         // This should have succeeded, since there are enough bytes to read this
         REPORTER_ASSERT(reporter, buffer2.isValid());
         REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == bytesWritten);
-        REPORTER_ASSERT(reporter, NULL != obj2);
+        REPORTER_ASSERT(reporter, obj2);
     } else {
         // If the deserialization was supposed to fail, make sure it did
         REPORTER_ASSERT(reporter, !buffer.isValid());
@@ -259,14 +262,109 @@
     }
 }
 
-static bool setup_bitmap_for_canvas(SkBitmap* bitmap) {
-    SkImageInfo info = SkImageInfo::Make(
-        kBitmapSize, kBitmapSize, kN32_SkColorType, kPremul_SkAlphaType);
-    return bitmap->allocPixels(info);
+static void TestXfermodeSerialization(skiatest::Reporter* reporter) {
+    for (size_t i = 0; i <= SkXfermode::kLastMode; ++i) {
+        if (i == SkXfermode::kSrcOver_Mode) {
+            // skip SrcOver, as it is allowed to return NULL from Create()
+            continue;
+        }
+        SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(static_cast<SkXfermode::Mode>(i)));
+        REPORTER_ASSERT(reporter, mode.get());
+        SkAutoTUnref<SkXfermode> copy(
+            TestFlattenableSerialization<SkXfermode>(mode.get(), true, reporter));
+    }
 }
 
-static bool make_checkerboard_bitmap(SkBitmap& bitmap) {
-    bool success = setup_bitmap_for_canvas(&bitmap);
+static void TestColorFilterSerialization(skiatest::Reporter* reporter) {
+    uint8_t table[256];
+    for (int i = 0; i < 256; ++i) {
+        table[i] = (i * 41) % 256;
+    }
+    SkAutoTUnref<SkColorFilter> colorFilter(SkTableColorFilter::Create(table));
+    SkAutoTUnref<SkColorFilter> copy(
+        TestFlattenableSerialization<SkColorFilter>(colorFilter.get(), true, reporter));
+}
+
+static SkBitmap draw_picture(SkPicture& picture) {
+     SkBitmap bitmap;
+     bitmap.allocN32Pixels(SkScalarCeilToInt(picture.cullRect().width()), 
+                           SkScalarCeilToInt(picture.cullRect().height()));
+     SkCanvas canvas(bitmap);
+     picture.playback(&canvas);
+     return bitmap;
+}
+
+static void compare_bitmaps(skiatest::Reporter* reporter,
+                            const SkBitmap& b1, const SkBitmap& b2) {
+    REPORTER_ASSERT(reporter, b1.width() == b2.width());
+    REPORTER_ASSERT(reporter, b1.height() == b2.height());
+    SkAutoLockPixels autoLockPixels1(b1);
+    SkAutoLockPixels autoLockPixels2(b2);
+
+    if ((b1.width() != b2.width()) ||
+        (b1.height() != b2.height())) {
+        return;
+    }
+
+    int pixelErrors = 0;
+    for (int y = 0; y < b2.height(); ++y) {
+        for (int x = 0; x < b2.width(); ++x) {
+            if (b1.getColor(x, y) != b2.getColor(x, y))
+                ++pixelErrors;
+        }
+    }
+    REPORTER_ASSERT(reporter, 0 == pixelErrors);
+}
+
+static void TestPictureTypefaceSerialization(skiatest::Reporter* reporter) {
+    // Load typeface form file.
+    // This test cannot run if there is no resource path.
+    SkString resourcePath = GetResourcePath();
+    if (resourcePath.isEmpty()) {
+        SkDebugf("Could not run fontstream test because resourcePath not specified.");
+        return;
+    }
+    SkString filename = SkOSPath::Join(resourcePath.c_str(), "test.ttc");
+    SkTypeface* typeface = SkTypeface::CreateFromFile(filename.c_str(), 1);
+    if (!typeface) {
+        SkDebugf("Could not run fontstream test because test.ttc not found.");
+        return;
+    }
+
+    // Create a paint with the typeface we loaded.
+    SkPaint paint;
+    paint.setColor(SK_ColorGRAY);
+    paint.setTextSize(SkIntToScalar(30));
+    SkSafeUnref(paint.setTypeface(typeface));
+
+    // Paint some text.
+    SkPictureRecorder recorder;
+    SkIRect canvasRect = SkIRect::MakeWH(kBitmapSize, kBitmapSize);
+    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(canvasRect.width()), 
+                                               SkIntToScalar(canvasRect.height()), 
+                                               NULL, 0);
+    canvas->drawColor(SK_ColorWHITE);
+    canvas->drawText("A!", 2, 24, 32, paint);
+    SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+
+    // Serlialize picture and create its clone from stream.
+    SkDynamicMemoryWStream stream;
+    picture->serialize(&stream);
+    SkAutoTUnref<SkStream> inputStream(stream.detachAsStream());
+    SkAutoTUnref<SkPicture> loadedPicture(SkPicture::CreateFromStream(inputStream.get()));
+
+    // Draw both original and clone picture and compare bitmaps -- they should be identical.
+    SkBitmap origBitmap = draw_picture(*picture);
+    SkBitmap destBitmap = draw_picture(*loadedPicture);
+    compare_bitmaps(reporter, origBitmap, destBitmap);
+}
+
+static void setup_bitmap_for_canvas(SkBitmap* bitmap) {
+    bitmap->allocN32Pixels(kBitmapSize, kBitmapSize);
+}
+
+static void make_checkerboard_bitmap(SkBitmap& bitmap) {
+    setup_bitmap_for_canvas(&bitmap);
 
     SkCanvas canvas(bitmap);
     canvas.clear(0x00000000);
@@ -287,14 +385,12 @@
             canvas.restore();
         }
     }
-
-    return success;
 }
 
-static bool drawSomething(SkCanvas* canvas) {
+static void draw_something(SkCanvas* canvas) {
     SkPaint paint;
     SkBitmap bitmap;
-    bool success = make_checkerboard_bitmap(bitmap);
+    make_checkerboard_bitmap(bitmap);
 
     canvas->save();
     canvas->scale(0.5f, 0.5f);
@@ -313,8 +409,6 @@
     paint.setColor(SK_ColorBLACK);
     paint.setTextSize(SkIntToScalar(kBitmapSize/3));
     canvas->drawText("Picture", 7, SkIntToScalar(kBitmapSize/2), SkIntToScalar(kBitmapSize/4), paint);
-
-    return success;
 }
 
 DEF_TEST(Serialization, reporter) {
@@ -322,7 +416,7 @@
     {
         SkMatrix matrix = SkMatrix::I();
         TestObjectSerialization(&matrix, reporter);
-     }
+    }
 
     // Test path serialization
     {
@@ -336,6 +430,16 @@
         TestObjectSerialization(&region, reporter);
     }
 
+    // Test xfermode serialization
+    {
+        TestXfermodeSerialization(reporter);
+    }
+
+    // Test color filter serialization
+    {
+        TestColorFilterSerialization(reporter);
+    }
+
     // Test string serialization
     {
         SkString string("string");
@@ -393,9 +497,8 @@
         validBitmap.setInfo(info);
 
         // Create a bitmap with a really large height
-        info.fHeight = 1000000000;
         SkBitmap invalidBitmap;
-        invalidBitmap.setInfo(info);
+        invalidBitmap.setInfo(info.makeWH(info.width(), 1000000000));
 
         // The deserialization should succeed, and the rendering shouldn't crash,
         // even when the device fails to initialize, due to its size
@@ -405,8 +508,9 @@
     // Test simple SkPicture serialization
     {
         SkPictureRecorder recorder;
-        bool didDraw = drawSomething(recorder.beginRecording(kBitmapSize, kBitmapSize, NULL, 0));
-        REPORTER_ASSERT(reporter, didDraw);
+        draw_something(recorder.beginRecording(SkIntToScalar(kBitmapSize),
+                                               SkIntToScalar(kBitmapSize),
+                                               NULL, 0));
         SkAutoTUnref<SkPicture> pict(recorder.endRecording());
 
         // Serialize picture
@@ -420,6 +524,8 @@
         SkValidatingReadBuffer reader(static_cast<void*>(data.get()), size);
         SkAutoTUnref<SkPicture> readPict(
             SkPicture::CreateFromBuffer(reader));
-        REPORTER_ASSERT(reporter, NULL != readPict.get());
+        REPORTER_ASSERT(reporter, readPict.get());
     }
+
+    TestPictureTypefaceSerialization(reporter);
 }
diff --git a/tests/TestSize.cpp b/tests/SizeTest.cpp
similarity index 94%
rename from tests/TestSize.cpp
rename to tests/SizeTest.cpp
index 466a628..9800aa2 100644
--- a/tests/TestSize.cpp
+++ b/tests/SizeTest.cpp
@@ -6,9 +6,10 @@
  */
 
 #include "SkSize.h"
+
 #include "Test.h"
 
-static void TestISize(skiatest::Reporter* reporter) {
+DEF_TEST(ISize, reporter) {
     SkISize  a, b;
 
     a.set(0, 0);
@@ -31,8 +32,6 @@
 }
 
 DEF_TEST(Size, reporter) {
-    TestISize(reporter);
-
     SkSize a, b;
     int ix = 5;
     int iy = 3;
diff --git a/tests/SkBase64Test.cpp b/tests/SkBase64Test.cpp
index 217e2ca..14ff1f7 100644
--- a/tests/SkBase64Test.cpp
+++ b/tests/SkBase64Test.cpp
@@ -9,7 +9,7 @@
 
 #include "Test.h"
 
-DEF_TEST(SkBase64Test, reporter) {
+DEF_TEST(SkBase64, reporter) {
     char all[256];
     for (int index = 0; index < 256; ++index) {
         all[index] = (signed char) (index + 1);
diff --git a/tests/SkResourceCacheTest.cpp b/tests/SkResourceCacheTest.cpp
new file mode 100644
index 0000000..f13476a
--- /dev/null
+++ b/tests/SkResourceCacheTest.cpp
@@ -0,0 +1,168 @@
+/*
+ * 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 "Test.h"
+#include "SkBitmapCache.h"
+#include "SkCanvas.h"
+#include "SkDiscardableMemoryPool.h"
+#include "SkGraphics.h"
+#include "SkResourceCache.h"
+
+static const int kCanvasSize = 1;
+static const int kBitmapSize = 16;
+static const int kScale = 8;
+
+static bool is_in_scaled_image_cache(const SkBitmap& orig,
+                                     SkScalar xScale,
+                                     SkScalar yScale) {
+    SkBitmap scaled;
+    float roundedImageWidth = SkScalarRoundToScalar(orig.width() * xScale);
+    float roundedImageHeight = SkScalarRoundToScalar(orig.height() * xScale);
+    return SkBitmapCache::Find(orig, roundedImageWidth, roundedImageHeight, &scaled);
+}
+
+// Draw a scaled bitmap, then return true iff it has been cached.
+static bool test_scaled_image_cache_useage() {
+    SkAutoTUnref<SkCanvas> canvas(
+            SkCanvas::NewRasterN32(kCanvasSize, kCanvasSize));
+    SkBitmap bitmap;
+    bitmap.allocN32Pixels(kBitmapSize, kBitmapSize);
+    bitmap.eraseColor(0xFFFFFFFF);
+    SkScalar scale = SkIntToScalar(kScale);
+    SkScalar scaledSize = SkIntToScalar(kBitmapSize) * scale;
+    canvas->clipRect(SkRect::MakeLTRB(0, 0, scaledSize, scaledSize));
+    SkPaint paint;
+    paint.setFilterLevel(SkPaint::kHigh_FilterLevel);
+
+    canvas->drawBitmapRect(bitmap,
+                           SkRect::MakeLTRB(0, 0, scaledSize, scaledSize),
+                           &paint);
+
+    return is_in_scaled_image_cache(bitmap, scale, scale);
+}
+
+// http://crbug.com/389439
+DEF_TEST(ResourceCache_SingleAllocationByteLimit, reporter) {
+    size_t originalByteLimit = SkGraphics::GetResourceCacheTotalByteLimit();
+    size_t originalAllocationLimit =
+        SkGraphics::GetResourceCacheSingleAllocationByteLimit();
+
+    size_t size = kBitmapSize * kScale * kBitmapSize * kScale
+        * SkColorTypeBytesPerPixel(kN32_SkColorType);
+
+    SkGraphics::SetResourceCacheTotalByteLimit(0);  // clear cache
+    SkGraphics::SetResourceCacheTotalByteLimit(2 * size);
+    SkGraphics::SetResourceCacheSingleAllocationByteLimit(0);  // No limit
+
+    REPORTER_ASSERT(reporter, test_scaled_image_cache_useage());
+
+    SkGraphics::SetResourceCacheTotalByteLimit(0);  // clear cache
+    SkGraphics::SetResourceCacheTotalByteLimit(2 * size);
+    SkGraphics::SetResourceCacheSingleAllocationByteLimit(size * 2);  // big enough
+
+    REPORTER_ASSERT(reporter, test_scaled_image_cache_useage());
+
+    SkGraphics::SetResourceCacheTotalByteLimit(0);  // clear cache
+    SkGraphics::SetResourceCacheTotalByteLimit(2 * size);
+    SkGraphics::SetResourceCacheSingleAllocationByteLimit(size / 2);  // too small
+
+    REPORTER_ASSERT(reporter, !test_scaled_image_cache_useage());
+
+    SkGraphics::SetResourceCacheSingleAllocationByteLimit(originalAllocationLimit);
+    SkGraphics::SetResourceCacheTotalByteLimit(originalByteLimit);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+static void make_bitmap(SkBitmap* bitmap, const SkImageInfo& info, SkBitmap::Allocator* allocator) {
+    if (allocator) {
+        bitmap->setInfo(info);
+        allocator->allocPixelRef(bitmap, 0);
+    } else {
+        bitmap->allocPixels(info);
+    }
+}
+
+// http://skbug.com/2894
+DEF_TEST(BitmapCache_add_rect, reporter) {
+    SkResourceCache::DiscardableFactory factory = SkResourceCache::GetDiscardableFactory();
+    SkBitmap::Allocator* allocator = SkBitmapCache::GetAllocator();
+
+    SkAutoTDelete<SkResourceCache> cache;
+    if (factory) {
+        cache.reset(SkNEW_ARGS(SkResourceCache, (factory)));
+    } else {
+        const size_t byteLimit = 100 * 1024;
+        cache.reset(SkNEW_ARGS(SkResourceCache, (byteLimit)));
+    }
+    SkBitmap cachedBitmap;
+    make_bitmap(&cachedBitmap, SkImageInfo::MakeN32Premul(5, 5), allocator);
+    cachedBitmap.setImmutable();
+
+    SkBitmap bm;
+    SkIRect rect = SkIRect::MakeWH(5, 5);
+
+    // Wrong subset size
+    REPORTER_ASSERT(reporter, !SkBitmapCache::Add(cachedBitmap.getGenerationID(), SkIRect::MakeWH(4, 6), cachedBitmap, cache));
+    REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
+    // Wrong offset value
+    REPORTER_ASSERT(reporter, !SkBitmapCache::Add(cachedBitmap.getGenerationID(), SkIRect::MakeXYWH(-1, 0, 5, 5), cachedBitmap, cache));
+    REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
+
+    // Should not be in the cache
+    REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
+
+    REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.getGenerationID(), rect, cachedBitmap, cache));
+    // Should be in the cache, we just added it
+    REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
+}
+
+DEF_TEST(BitmapCache_discarded_bitmap, reporter) {
+    SkResourceCache::DiscardableFactory factory = SkResourceCache::GetDiscardableFactory();
+    SkBitmap::Allocator* allocator = SkBitmapCache::GetAllocator();
+    
+    SkAutoTDelete<SkResourceCache> cache;
+    if (factory) {
+        cache.reset(SkNEW_ARGS(SkResourceCache, (factory)));
+    } else {
+        const size_t byteLimit = 100 * 1024;
+        cache.reset(SkNEW_ARGS(SkResourceCache, (byteLimit)));
+    }
+    SkBitmap cachedBitmap;
+    make_bitmap(&cachedBitmap, SkImageInfo::MakeN32Premul(5, 5), allocator);
+    cachedBitmap.setImmutable();
+    cachedBitmap.unlockPixels();
+
+    SkBitmap bm;
+    SkIRect rect = SkIRect::MakeWH(5, 5);
+
+    // Add a bitmap to the cache.
+    REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.getGenerationID(), rect, cachedBitmap, cache));
+    REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
+
+    // Finding more than once works fine.
+    REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
+    bm.unlockPixels();
+
+    // Drop the pixels in the bitmap.
+    if (factory) {
+        REPORTER_ASSERT(reporter, SkGetGlobalDiscardableMemoryPool()->getRAMUsed() > 0);
+        SkGetGlobalDiscardableMemoryPool()->dumpPool();
+        REPORTER_ASSERT(reporter, SkGetGlobalDiscardableMemoryPool()->getRAMUsed() == 0);
+
+        // The bitmap is not in the cache since it has been dropped.
+        REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
+    }
+
+    make_bitmap(&cachedBitmap, SkImageInfo::MakeN32Premul(5, 5), allocator);
+    cachedBitmap.setImmutable();
+    cachedBitmap.unlockPixels();
+
+    // We can add the bitmap back to the cache and find it again.
+    REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.getGenerationID(), rect, cachedBitmap, cache));
+    REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
+}
diff --git a/tests/SkpSkGrTest.cpp b/tests/SkpSkGrTest.cpp
index c1883a9..c882654 100644
--- a/tests/SkpSkGrTest.cpp
+++ b/tests/SkpSkGrTest.cpp
@@ -23,7 +23,7 @@
 #include "SkString.h"
 #include "SkTArray.h"
 #include "SkTDArray.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
 #include "SkTime.h"
 #include "Test.h"
 
@@ -125,14 +125,12 @@
 };
 
 struct SkpSkGrThreadedTestRunner {
-    SkpSkGrThreadedTestRunner(skiatest::Reporter* reporter, int threadCount)
-        : fNumThreads(threadCount)
-        , fReporter(reporter) {
+    SkpSkGrThreadedTestRunner(skiatest::Reporter* reporter)
+        : fReporter(reporter) {
     }
 
     ~SkpSkGrThreadedTestRunner();
     void render();
-    int fNumThreads;
     SkTDArray<SkpSkGrThreadedRunnable*> fRunnables;
     skiatest::Reporter* fReporter;
 };
@@ -164,9 +162,9 @@
 }
 
 void SkpSkGrThreadedTestRunner::render() {
-    SkThreadPool pool(fNumThreads);
+    SkTaskGroup tg;
     for (int index = 0; index < fRunnables.count(); ++ index) {
-        pool.add(fRunnables[index]);
+        tg.add(fRunnables[index]);
     }
 }
 
@@ -676,8 +674,7 @@
     if (!initTest()) {
         return;
     }
-    int threadCount = reporter->allowThreaded() ? 3 : 1;
-    SkpSkGrThreadedTestRunner testRunner(reporter, threadCount);
+    SkpSkGrThreadedTestRunner testRunner(reporter);
     for (int dirIndex = 1; dirIndex <= 100; ++dirIndex) {
         SkString pictDir = make_in_dir_name(dirIndex);
         if (pictDir.size() == 0) {
diff --git a/tests/StreamTest.cpp b/tests/StreamTest.cpp
index 7cf3126..ce391a3 100644
--- a/tests/StreamTest.cpp
+++ b/tests/StreamTest.cpp
@@ -37,7 +37,7 @@
 }
 
 static void test_filestreams(skiatest::Reporter* reporter, const char* tmpDir) {
-    SkString path = SkOSPath::SkPathJoin(tmpDir, "wstream_test");
+    SkString path = SkOSPath::Join(tmpDir, "wstream_test");
 
     const char s[] = "abcdefghijklmnopqrstuvwxyz";
 
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 3f61f89..69c8b84 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -7,6 +7,7 @@
 
 #include "SkCanvas.h"
 #include "SkData.h"
+#include "SkDecodingImageGenerator.h"
 #include "SkImageEncoder.h"
 #include "SkRRect.h"
 #include "SkSurface.h"
@@ -27,13 +28,14 @@
     kGpuScratch_SurfaceType,
 };
 
-static const int gSurfaceSize = 10;
-static SkPMColor gSurfaceStorage[gSurfaceSize * gSurfaceSize];
+static void release_storage(void* pixels, void* context) {
+    SkASSERT(pixels == context);
+    sk_free(pixels);
+}
 
 static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context,
                                 SkImageInfo* requestedInfo = NULL) {
-    static const SkImageInfo info = SkImageInfo::MakeN32Premul(gSurfaceSize,
-                                                               gSurfaceSize);
+    static const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
 
     if (requestedInfo) {
         *requestedInfo = info;
@@ -42,12 +44,15 @@
     switch (surfaceType) {
         case kRaster_SurfaceType:
             return SkSurface::NewRaster(info);
-        case kRasterDirect_SurfaceType:
-            return SkSurface::NewRasterDirect(info, gSurfaceStorage,
-                                              info.minRowBytes());
+        case kRasterDirect_SurfaceType: {
+            const size_t rowBytes = info.minRowBytes();
+            void* storage = sk_malloc_throw(info.getSafeSize(rowBytes));
+            return SkSurface::NewRasterDirectReleaseProc(info, storage, rowBytes,
+                                                         release_storage, storage);
+        }
         case kGpu_SurfaceType:
 #if SK_SUPPORT_GPU
-            return context ? SkSurface::NewRenderTarget(context, info) : NULL;
+            return context ? SkSurface::NewRenderTarget(context, info, 0, NULL) : NULL;
 #endif
             break;
         case kGpuScratch_SurfaceType:
@@ -70,8 +75,7 @@
     SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
     size_t rowBytes = info.minRowBytes();
     size_t size = info.getSafeSize(rowBytes);
-    void* addr = sk_malloc_throw(size);
-    SkData* data = SkData::NewFromMalloc(addr, size);
+    SkData* data = SkData::NewUninitialized(size);
 
     REPORTER_ASSERT(reporter, 1 == data->getRefCnt());
     SkImage* image = SkImage::NewRasterData(info, data, rowBytes);
@@ -86,11 +90,11 @@
     const SkPMColor pmcolor = SkPreMultiplyColor(color);
     const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
     const size_t rowBytes = info.minRowBytes();
-    const size_t size = rowBytes * info.fHeight;
+    const size_t size = rowBytes * info.height();
 
-    void* addr = sk_malloc_throw(size);
+    SkAutoTUnref<SkData> data(SkData::NewUninitialized(size));
+    void* addr = data->writable_data();
     sk_memset32((SkPMColor*)addr, pmcolor, SkToInt(size >> 2));
-    SkAutoTUnref<SkData> data(SkData::NewFromMalloc(addr, size));
 
     switch (imageType) {
         case kRasterCopy_ImageType:
@@ -105,7 +109,8 @@
             SkAutoTUnref<SkData> src(
                  SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type,
                                             100));
-            return SkImage::NewEncodedData(src);
+            return SkImage::NewFromGenerator(
+                SkDecodingImageGenerator::Create(data, SkDecodingImageGenerator::Options()));
         }
     }
     SkASSERT(false);
@@ -135,14 +140,14 @@
             continue;   // gpu may not be enabled
         }
         const void* addr = image->peekPixels(&info, &rowBytes);
-        bool success = (NULL != addr);
+        bool success = SkToBool(addr);
         REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
         if (success) {
-            REPORTER_ASSERT(reporter, 10 == info.fWidth);
-            REPORTER_ASSERT(reporter, 10 == info.fHeight);
-            REPORTER_ASSERT(reporter, kN32_SkColorType == info.fColorType);
-            REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.fAlphaType ||
-                            kOpaque_SkAlphaType == info.fAlphaType);
+            REPORTER_ASSERT(reporter, 10 == info.width());
+            REPORTER_ASSERT(reporter, 10 == info.height());
+            REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType());
+            REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() ||
+                            kOpaque_SkAlphaType == info.alphaType());
             REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes);
             REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
         }
@@ -166,37 +171,53 @@
     const SkColor color = SK_ColorRED;
     const SkPMColor pmcolor = SkPreMultiplyColor(color);
 
-    GrContext* context = NULL;
+    int cnt;
 #if SK_SUPPORT_GPU
-    context = factory->get(GrContextFactory::kNative_GLContextType);
+    cnt = GrContextFactory::kGLContextTypeCnt;
+#else
+    cnt = 1;
 #endif
 
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
-        SkImageInfo info, requestInfo;
-        size_t rowBytes;
+    for (int i= 0; i < cnt; ++i) {
+        GrContext* context = NULL;
+#if SK_SUPPORT_GPU
+        GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+        if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
+            continue;
+        }
+        context = factory->get(glCtxType);
 
-        SkAutoTUnref<SkSurface> surface(createSurface(gRec[i].fType, context,
-                                                      &requestInfo));
-        surface->getCanvas()->clear(color);
+        if (NULL == context) {
+            continue;
+        }
+#endif
+        for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
+            SkImageInfo info, requestInfo;
+            size_t rowBytes;
 
-        const void* addr = surface->getCanvas()->peekPixels(&info, &rowBytes);
-        bool success = (NULL != addr);
-        REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
+            SkAutoTUnref<SkSurface> surface(createSurface(gRec[i].fType, context,
+                                                          &requestInfo));
+            surface->getCanvas()->clear(color);
 
-        SkImageInfo info2;
-        size_t rb2;
-        const void* addr2 = surface->peekPixels(&info2, &rb2);
+            const void* addr = surface->getCanvas()->peekPixels(&info, &rowBytes);
+            bool success = SkToBool(addr);
+            REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
 
-        if (success) {
-            REPORTER_ASSERT(reporter, requestInfo == info);
-            REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= rowBytes);
-            REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
+            SkImageInfo info2;
+            size_t rb2;
+            const void* addr2 = surface->peekPixels(&info2, &rb2);
 
-            REPORTER_ASSERT(reporter, addr2 == addr);
-            REPORTER_ASSERT(reporter, info2 == info);
-            REPORTER_ASSERT(reporter, rb2 == rowBytes);
-        } else {
-            REPORTER_ASSERT(reporter, NULL == addr2);
+            if (success) {
+                REPORTER_ASSERT(reporter, requestInfo == info);
+                REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= rowBytes);
+                REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
+
+                REPORTER_ASSERT(reporter, addr2 == addr);
+                REPORTER_ASSERT(reporter, info2 == info);
+                REPORTER_ASSERT(reporter, rb2 == rowBytes);
+            } else {
+                REPORTER_ASSERT(reporter, NULL == addr2);
+            }
         }
     }
 }
@@ -369,7 +390,7 @@
     SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
     GrTexture* texture = image->getTexture();
     if (surfaceType == kGpu_SurfaceType || surfaceType == kGpuScratch_SurfaceType) {
-        REPORTER_ASSERT(reporter, NULL != texture);
+        REPORTER_ASSERT(reporter, texture);
         REPORTER_ASSERT(reporter, 0 != texture->getTextureHandle());
     } else {
         REPORTER_ASSERT(reporter, NULL == texture);
@@ -424,23 +445,29 @@
 
 #if SK_SUPPORT_GPU
     TestGetTexture(reporter, kRaster_SurfaceType, NULL);
-    if (NULL != factory) {
-        GrContext* context = factory->get(GrContextFactory::kNative_GLContextType);
-        if (NULL != context) {
-            TestSurfaceInCache(reporter, kGpu_SurfaceType, context);
-            TestSurfaceInCache(reporter, kGpuScratch_SurfaceType, context);
-            Test_crbug263329(reporter, kGpu_SurfaceType, context);
-            Test_crbug263329(reporter, kGpuScratch_SurfaceType, context);
-            TestSurfaceCopyOnWrite(reporter, kGpu_SurfaceType, context);
-            TestSurfaceCopyOnWrite(reporter, kGpuScratch_SurfaceType, context);
-            TestSurfaceWritableAfterSnapshotRelease(reporter, kGpu_SurfaceType, context);
-            TestSurfaceWritableAfterSnapshotRelease(reporter, kGpuScratch_SurfaceType, context);
-            TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
-            TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
-            TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
-            TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
-            TestGetTexture(reporter, kGpu_SurfaceType, context);
-            TestGetTexture(reporter, kGpuScratch_SurfaceType, context);
+    if (factory) {
+        for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
+            GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+            if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
+                continue;
+            }
+            GrContext* context = factory->get(glCtxType);
+            if (context) {
+                TestSurfaceInCache(reporter, kGpu_SurfaceType, context);
+                TestSurfaceInCache(reporter, kGpuScratch_SurfaceType, context);
+                Test_crbug263329(reporter, kGpu_SurfaceType, context);
+                Test_crbug263329(reporter, kGpuScratch_SurfaceType, context);
+                TestSurfaceCopyOnWrite(reporter, kGpu_SurfaceType, context);
+                TestSurfaceCopyOnWrite(reporter, kGpuScratch_SurfaceType, context);
+                TestSurfaceWritableAfterSnapshotRelease(reporter, kGpu_SurfaceType, context);
+                TestSurfaceWritableAfterSnapshotRelease(reporter, kGpuScratch_SurfaceType, context);
+                TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
+                TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
+                TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
+                TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
+                TestGetTexture(reporter, kGpu_SurfaceType, context);
+                TestGetTexture(reporter, kGpuScratch_SurfaceType, context);
+            }
         }
     }
 #endif
diff --git a/tests/Test.cpp b/tests/Test.cpp
index 20afd45..d0147e1 100644
--- a/tests/Test.cpp
+++ b/tests/Test.cpp
@@ -75,10 +75,6 @@
         return fReporter->allowExtendedTest();
     }
 
-    virtual bool allowThreaded() const SK_OVERRIDE {
-        return fReporter->allowThreaded();
-    }
-
     virtual void bumpTestCount() SK_OVERRIDE {
         fReporter->bumpTestCount();
     }
diff --git a/tests/Test.h b/tests/Test.h
index fc18900..6c85b32 100644
--- a/tests/Test.h
+++ b/tests/Test.h
@@ -32,7 +32,6 @@
         void endTest(Test*);
 
         virtual bool allowExtendedTest() const { return false; }
-        virtual bool allowThreaded() const { return false; }
         virtual bool verbose() const { return false; }
         virtual void bumpTestCount() { sk_atomic_inc(&fTestCount); }
 
@@ -138,38 +137,38 @@
         (reporter)->reportFailed(desc);             \
     } while(0)
 
-#define DEF_TEST(name, reporter)                                   \
-    static void name(skiatest::Reporter*);                         \
-    namespace skiatest {                                           \
-    class name##Class : public Test {                              \
-    public:                                                        \
-        static Test* Factory(void*) { return SkNEW(name##Class); } \
-    protected:                                                     \
-        virtual void onGetName(SkString* name) SK_OVERRIDE {       \
-            name->set(#name);                                      \
-        }                                                          \
-        virtual void onRun(Reporter* r) SK_OVERRIDE { name(r); }   \
-    };                                                             \
-    static TestRegistry gReg_##name##Class(name##Class::Factory);  \
-    }                                                              \
-    static void name(skiatest::Reporter* reporter)
+#define DEF_TEST(name, reporter)                                        \
+    static void test_##name(skiatest::Reporter*);                       \
+    namespace skiatest {                                                \
+    class name##Class : public Test {                                   \
+    public:                                                             \
+        static Test* Factory(void*) { return SkNEW(name##Class); }      \
+    protected:                                                          \
+        virtual void onGetName(SkString* name) SK_OVERRIDE {            \
+            name->set(#name);                                           \
+        }                                                               \
+        virtual void onRun(Reporter* r) SK_OVERRIDE { test_##name(r); } \
+    };                                                                  \
+    static TestRegistry gReg_##name##Class(name##Class::Factory);       \
+    }                                                                   \
+    static void test_##name(skiatest::Reporter* reporter)
 
-#define DEF_GPUTEST(name, reporter, factory)                       \
-    static void name(skiatest::Reporter*, GrContextFactory*);      \
-    namespace skiatest {                                           \
-    class name##Class : public GpuTest {                           \
-    public:                                                        \
-        static Test* Factory(void*) { return SkNEW(name##Class); } \
-    protected:                                                     \
-        virtual void onGetName(SkString* name) SK_OVERRIDE {       \
-            name->set(#name);                                      \
-        }                                                          \
-        virtual void onRun(Reporter* r) SK_OVERRIDE {              \
-            name(r, fGrContextFactory);                            \
-        }                                                          \
-    };                                                             \
-    static TestRegistry gReg_##name##Class(name##Class::Factory);  \
-    }                                                              \
-    static void name(skiatest::Reporter* reporter, GrContextFactory* factory)
+#define DEF_GPUTEST(name, reporter, factory)                          \
+    static void test_##name(skiatest::Reporter*, GrContextFactory*);  \
+    namespace skiatest {                                              \
+    class name##Class : public GpuTest {                              \
+    public:                                                           \
+        static Test* Factory(void*) { return SkNEW(name##Class); }    \
+    protected:                                                        \
+        virtual void onGetName(SkString* name) SK_OVERRIDE {          \
+            name->set(#name);                                         \
+        }                                                             \
+        virtual void onRun(Reporter* r) SK_OVERRIDE {                 \
+            test_##name(r, fGrContextFactory);                        \
+        }                                                             \
+    };                                                                \
+    static TestRegistry gReg_##name##Class(name##Class::Factory);     \
+    }                                                                 \
+    static void test_##name(skiatest::Reporter* reporter, GrContextFactory* factory)
 
 #endif
diff --git a/tests/TestXCode/Tests.xcodeproj/project.pbxproj b/tests/TestXCode/Tests.xcodeproj/project.pbxproj
deleted file mode 100644
index af9dfd7..0000000
--- a/tests/TestXCode/Tests.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,371 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 44;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		00857F860F56F8EE0078BE26 /* libcore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00857F730F56F71B0078BE26 /* libcore.a */; };
-		00857F920F56F9170078BE26 /* libmaccore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00857F910F56F9150078BE26 /* libmaccore.a */; };
-		00857FAA0F56F9620078BE26 /* Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00857FA80F56F9620078BE26 /* Test.cpp */; };
-		00857FAB0F56F9620078BE26 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00857FA90F56F9620078BE26 /* main.cpp */; };
-		00857FB70F56FD340078BE26 /* MathTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00857FB60F56FD340078BE26 /* MathTest.cpp */; };
-		008634DC0F579B7A0044DA64 /* PackBitsTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 008634DB0F579B7A0044DA64 /* PackBitsTest.cpp */; };
-		008634F10F579E410044DA64 /* MatrixTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 008634F00F579E410044DA64 /* MatrixTest.cpp */; };
-		0086350F0F57A3140044DA64 /* UtilsTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0086350E0F57A3140044DA64 /* UtilsTest.cpp */; };
-		009CC7840F5DAE2B002185BE /* SrcOverTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009CC7830F5DAE2B002185BE /* SrcOverTest.cpp */; };
-		009CC7880F5DAF16002185BE /* ClipCubicTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009CC7870F5DAF16002185BE /* ClipCubicTest.cpp */; };
-		00A9BF860F584CF30091AD2D /* Sk64Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A9BF850F584CF30091AD2D /* Sk64Test.cpp */; };
-		00A9BFA30F584E150091AD2D /* StringTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A9BFA20F584E150091AD2D /* StringTest.cpp */; };
-		00A9BFBC0F5851570091AD2D /* GeometryTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A9BFBB0F5851570091AD2D /* GeometryTest.cpp */; };
-		276D93080F5B9FEA0081B3B9 /* PathTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 276D93070F5B9FEA0081B3B9 /* PathTest.cpp */; };
-		27C9A9C70F6222EE00E9C93D /* PathMeasureTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C9A9C40F6222EE00E9C93D /* PathMeasureTest.cpp */; };
-		27C9A9C80F6222EE00E9C93D /* SortTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C9A9C50F6222EE00E9C93D /* SortTest.cpp */; };
-		27C9A9C90F6222EE00E9C93D /* StreamTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C9A9C60F6222EE00E9C93D /* StreamTest.cpp */; };
-		8DD76F6A0486A84900D96B5E /* Tests.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859E8B029090EE04C91782 /* Tests.1 */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXContainerItemProxy section */
-		00857F720F56F71B0078BE26 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00857F6B0F56F71B0078BE26 /* core.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = core;
-		};
-		00857F900F56F9150078BE26 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00857F890F56F9150078BE26 /* maccore.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = D2AAC046055464E500DB518D;
-			remoteInfo = maccore;
-		};
-		0086351C0F57A51A0044DA64 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00857F6B0F56F71B0078BE26 /* core.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = core;
-		};
-		0086351E0F57A5200044DA64 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 00857F890F56F9150078BE26 /* maccore.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = D2AAC045055464E500DB518D;
-			remoteInfo = maccore;
-		};
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXCopyFilesBuildPhase section */
-		8DD76F690486A84900D96B5E /* CopyFiles */ = {
-			isa = PBXCopyFilesBuildPhase;
-			buildActionMask = 8;
-			dstPath = /usr/share/man/man1/;
-			dstSubfolderSpec = 0;
-			files = (
-				8DD76F6A0486A84900D96B5E /* Tests.1 in CopyFiles */,
-			);
-			runOnlyForDeploymentPostprocessing = 1;
-		};
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
-		00857F630F56F4220078BE26 /* Test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Test.h; path = ../Test.h; sourceTree = SOURCE_ROOT; };
-		00857F6B0F56F71B0078BE26 /* core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = core.xcodeproj; path = ../../xcode/core/core.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00857F890F56F9150078BE26 /* maccore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = maccore.xcodeproj; path = ../../xcode/maccore/maccore.xcodeproj; sourceTree = SOURCE_ROOT; };
-		00857FA80F56F9620078BE26 /* Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Test.cpp; path = ../Test.cpp; sourceTree = SOURCE_ROOT; };
-		00857FA90F56F9620078BE26 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../main.cpp; sourceTree = SOURCE_ROOT; };
-		00857FB60F56FD340078BE26 /* MathTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MathTest.cpp; path = ../MathTest.cpp; sourceTree = SOURCE_ROOT; };
-		008634DB0F579B7A0044DA64 /* PackBitsTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PackBitsTest.cpp; path = ../PackBitsTest.cpp; sourceTree = SOURCE_ROOT; };
-		008634F00F579E410044DA64 /* MatrixTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MatrixTest.cpp; path = ../MatrixTest.cpp; sourceTree = SOURCE_ROOT; };
-		0086350E0F57A3140044DA64 /* UtilsTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UtilsTest.cpp; path = ../UtilsTest.cpp; sourceTree = SOURCE_ROOT; };
-		009CC7830F5DAE2B002185BE /* SrcOverTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SrcOverTest.cpp; path = ../SrcOverTest.cpp; sourceTree = SOURCE_ROOT; };
-		009CC7870F5DAF16002185BE /* ClipCubicTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClipCubicTest.cpp; path = ../ClipCubicTest.cpp; sourceTree = SOURCE_ROOT; };
-		00A9BF850F584CF30091AD2D /* Sk64Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sk64Test.cpp; path = ../Sk64Test.cpp; sourceTree = SOURCE_ROOT; };
-		00A9BFA20F584E150091AD2D /* StringTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringTest.cpp; path = ../StringTest.cpp; sourceTree = SOURCE_ROOT; };
-		00A9BFA60F584F200091AD2D /* TestClassDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestClassDef.h; path = ../TestClassDef.h; sourceTree = SOURCE_ROOT; };
-		00A9BFBB0F5851570091AD2D /* GeometryTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GeometryTest.cpp; path = ../GeometryTest.cpp; sourceTree = SOURCE_ROOT; };
-		276D93070F5B9FEA0081B3B9 /* PathTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PathTest.cpp; path = ../PathTest.cpp; sourceTree = SOURCE_ROOT; };
-		27C9A9C40F6222EE00E9C93D /* PathMeasureTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PathMeasureTest.cpp; path = ../PathMeasureTest.cpp; sourceTree = SOURCE_ROOT; };
-		27C9A9C50F6222EE00E9C93D /* SortTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SortTest.cpp; path = ../SortTest.cpp; sourceTree = SOURCE_ROOT; };
-		27C9A9C60F6222EE00E9C93D /* StreamTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StreamTest.cpp; path = ../StreamTest.cpp; sourceTree = SOURCE_ROOT; };
-		8DD76F6C0486A84900D96B5E /* Tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Tests; sourceTree = BUILT_PRODUCTS_DIR; };
-		C6859E8B029090EE04C91782 /* Tests.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = Tests.1; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		8DD76F660486A84900D96B5E /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00857F860F56F8EE0078BE26 /* libcore.a in Frameworks */,
-				00857F920F56F9170078BE26 /* libmaccore.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		00857F6C0F56F71B0078BE26 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00857F730F56F71B0078BE26 /* libcore.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		00857F8A0F56F9150078BE26 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				00857F910F56F9150078BE26 /* libmaccore.a */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		08FB7794FE84155DC02AAC07 /* Tests */ = {
-			isa = PBXGroup;
-			children = (
-				00857F890F56F9150078BE26 /* maccore.xcodeproj */,
-				00857F6B0F56F71B0078BE26 /* core.xcodeproj */,
-				08FB7795FE84155DC02AAC07 /* Source */,
-				C6859E8C029090F304C91782 /* Documentation */,
-				1AB674ADFE9D54B511CA2CBB /* Products */,
-			);
-			name = Tests;
-			sourceTree = "<group>";
-		};
-		08FB7795FE84155DC02AAC07 /* Source */ = {
-			isa = PBXGroup;
-			children = (
-				27C9A9C40F6222EE00E9C93D /* PathMeasureTest.cpp */,
-				27C9A9C50F6222EE00E9C93D /* SortTest.cpp */,
-				27C9A9C60F6222EE00E9C93D /* StreamTest.cpp */,
-				009CC7870F5DAF16002185BE /* ClipCubicTest.cpp */,
-				276D93070F5B9FEA0081B3B9 /* PathTest.cpp */,
-				00A9BF850F584CF30091AD2D /* Sk64Test.cpp */,
-				00A9BFBB0F5851570091AD2D /* GeometryTest.cpp */,
-				00A9BFA20F584E150091AD2D /* StringTest.cpp */,
-				00857FA80F56F9620078BE26 /* Test.cpp */,
-				00857FA90F56F9620078BE26 /* main.cpp */,
-				00857F630F56F4220078BE26 /* Test.h */,
-				00857FB60F56FD340078BE26 /* MathTest.cpp */,
-				0086350E0F57A3140044DA64 /* UtilsTest.cpp */,
-				008634F00F579E410044DA64 /* MatrixTest.cpp */,
-				00A9BFA60F584F200091AD2D /* TestClassDef.h */,
-				008634DB0F579B7A0044DA64 /* PackBitsTest.cpp */,
-				009CC7830F5DAE2B002185BE /* SrcOverTest.cpp */,
-			);
-			name = Source;
-			sourceTree = "<group>";
-		};
-		1AB674ADFE9D54B511CA2CBB /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				8DD76F6C0486A84900D96B5E /* Tests */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		C6859E8C029090F304C91782 /* Documentation */ = {
-			isa = PBXGroup;
-			children = (
-				C6859E8B029090EE04C91782 /* Tests.1 */,
-			);
-			name = Documentation;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
-		8DD76F620486A84900D96B5E /* Tests */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Tests" */;
-			buildPhases = (
-				8DD76F640486A84900D96B5E /* Sources */,
-				8DD76F660486A84900D96B5E /* Frameworks */,
-				8DD76F690486A84900D96B5E /* CopyFiles */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				0086351D0F57A51A0044DA64 /* PBXTargetDependency */,
-				0086351F0F57A5200044DA64 /* PBXTargetDependency */,
-			);
-			name = Tests;
-			productInstallPath = "$(HOME)/bin";
-			productName = Tests;
-			productReference = 8DD76F6C0486A84900D96B5E /* Tests */;
-			productType = "com.apple.product-type.tool";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		08FB7793FE84155DC02AAC07 /* Project object */ = {
-			isa = PBXProject;
-			buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "Tests" */;
-			compatibilityVersion = "Xcode 3.0";
-			hasScannedForEncodings = 1;
-			mainGroup = 08FB7794FE84155DC02AAC07 /* Tests */;
-			projectDirPath = "";
-			projectReferences = (
-				{
-					ProductGroup = 00857F6C0F56F71B0078BE26 /* Products */;
-					ProjectRef = 00857F6B0F56F71B0078BE26 /* core.xcodeproj */;
-				},
-				{
-					ProductGroup = 00857F8A0F56F9150078BE26 /* Products */;
-					ProjectRef = 00857F890F56F9150078BE26 /* maccore.xcodeproj */;
-				},
-			);
-			projectRoot = "";
-			targets = (
-				8DD76F620486A84900D96B5E /* Tests */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXReferenceProxy section */
-		00857F730F56F71B0078BE26 /* libcore.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libcore.a;
-			remoteRef = 00857F720F56F71B0078BE26 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		00857F910F56F9150078BE26 /* libmaccore.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libmaccore.a;
-			remoteRef = 00857F900F56F9150078BE26 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-/* End PBXReferenceProxy section */
-
-/* Begin PBXSourcesBuildPhase section */
-		8DD76F640486A84900D96B5E /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				00857FAA0F56F9620078BE26 /* Test.cpp in Sources */,
-				00857FAB0F56F9620078BE26 /* main.cpp in Sources */,
-				00857FB70F56FD340078BE26 /* MathTest.cpp in Sources */,
-				008634DC0F579B7A0044DA64 /* PackBitsTest.cpp in Sources */,
-				008634F10F579E410044DA64 /* MatrixTest.cpp in Sources */,
-				0086350F0F57A3140044DA64 /* UtilsTest.cpp in Sources */,
-				00A9BF860F584CF30091AD2D /* Sk64Test.cpp in Sources */,
-				00A9BFA30F584E150091AD2D /* StringTest.cpp in Sources */,
-				00A9BFBC0F5851570091AD2D /* GeometryTest.cpp in Sources */,
-				276D93080F5B9FEA0081B3B9 /* PathTest.cpp in Sources */,
-				009CC7840F5DAE2B002185BE /* SrcOverTest.cpp in Sources */,
-				009CC7880F5DAF16002185BE /* ClipCubicTest.cpp in Sources */,
-				27C9A9C70F6222EE00E9C93D /* PathMeasureTest.cpp in Sources */,
-				27C9A9C80F6222EE00E9C93D /* SortTest.cpp in Sources */,
-				27C9A9C90F6222EE00E9C93D /* StreamTest.cpp in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
-		0086351D0F57A51A0044DA64 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = core;
-			targetProxy = 0086351C0F57A51A0044DA64 /* PBXContainerItemProxy */;
-		};
-		0086351F0F57A5200044DA64 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = maccore;
-			targetProxy = 0086351E0F57A5200044DA64 /* PBXContainerItemProxy */;
-		};
-/* End PBXTargetDependency section */
-
-/* Begin XCBuildConfiguration section */
-		1DEB923208733DC60010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				COPY_PHASE_STRIP = NO;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_ENABLE_FIX_AND_CONTINUE = YES;
-				GCC_MODEL_TUNING = G5;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"_GLIBCXX_DEBUG=1",
-					"_GLIBCXX_DEBUG_PEDANTIC=1",
-				);
-				INSTALL_PATH = /usr/local/bin;
-				PRODUCT_NAME = Tests;
-			};
-			name = Debug;
-		};
-		1DEB923308733DC60010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				GCC_MODEL_TUNING = G5;
-				INSTALL_PATH = /usr/local/bin;
-				PRODUCT_NAME = Tests;
-			};
-			name = Release;
-		};
-		1DEB923608733DC60010E9CD /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				GCC_C_LANGUAGE_STANDARD = c99;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "../../../**";
-				ONLY_ACTIVE_ARCH = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
-				VALID_ARCHS = "i386 x86_64";
-			};
-			name = Debug;
-		};
-		1DEB923708733DC60010E9CD /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH)";
-				GCC_C_LANGUAGE_STANDARD = c99;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				HEADER_SEARCH_PATHS = "../../../**";
-				ONLY_ACTIVE_ARCH = NO;
-				PREBINDING = NO;
-				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
-				VALID_ARCHS = "i386 x86_64";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Tests" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB923208733DC60010E9CD /* Debug */,
-				1DEB923308733DC60010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "Tests" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				1DEB923608733DC60010E9CD /* Debug */,
-				1DEB923708733DC60010E9CD /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/tests/TextBlobTest.cpp b/tests/TextBlobTest.cpp
new file mode 100644
index 0000000..5d08b01
--- /dev/null
+++ b/tests/TextBlobTest.cpp
@@ -0,0 +1,243 @@
+/*
+ * 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 "SkPaint.h"
+#include "SkPoint.h"
+#include "SkTextBlob.h"
+
+#include "Test.h"
+
+
+class TextBlobTester {
+public:
+    // This unit test feeds an SkTextBlobBuilder various runs then checks to see if
+    // the result contains the provided data and merges runs when appropriate.
+    static void TestBuilder(skiatest::Reporter* reporter) {
+        SkTextBlobBuilder builder;
+
+        // empty run set
+        RunBuilderTest(reporter, builder, NULL, 0, NULL, 0);
+
+        RunDef set1[] = {
+            { 128, SkTextBlob::kDefault_Positioning, 100, 100 },
+        };
+        RunBuilderTest(reporter, builder, set1, SK_ARRAY_COUNT(set1), set1, SK_ARRAY_COUNT(set1));
+
+        RunDef set2[] = {
+            { 128, SkTextBlob::kHorizontal_Positioning, 100, 100 },
+        };
+        RunBuilderTest(reporter, builder, set2, SK_ARRAY_COUNT(set2), set2, SK_ARRAY_COUNT(set2));
+
+        RunDef set3[] = {
+            { 128, SkTextBlob::kFull_Positioning, 100, 100 },
+        };
+        RunBuilderTest(reporter, builder, set3, SK_ARRAY_COUNT(set3), set3, SK_ARRAY_COUNT(set3));
+
+        RunDef set4[] = {
+            { 128, SkTextBlob::kDefault_Positioning, 100, 150 },
+            { 128, SkTextBlob::kDefault_Positioning, 100, 150 },
+            { 128, SkTextBlob::kDefault_Positioning, 100, 150 },
+        };
+        RunBuilderTest(reporter, builder, set4, SK_ARRAY_COUNT(set4), set4, SK_ARRAY_COUNT(set4));
+
+        RunDef set5[] = {
+            { 128, SkTextBlob::kHorizontal_Positioning, 100, 150 },
+            { 128, SkTextBlob::kHorizontal_Positioning, 200, 150 },
+            { 128, SkTextBlob::kHorizontal_Positioning, 300, 250 },
+        };
+        RunDef mergedSet5[] = {
+            { 256, SkTextBlob::kHorizontal_Positioning, 0, 150 },
+            { 128, SkTextBlob::kHorizontal_Positioning, 0, 250 },
+        };
+        RunBuilderTest(reporter, builder, set5, SK_ARRAY_COUNT(set5), mergedSet5,
+                       SK_ARRAY_COUNT(mergedSet5));
+
+        RunDef set6[] = {
+            { 128, SkTextBlob::kFull_Positioning, 100, 100 },
+            { 128, SkTextBlob::kFull_Positioning, 200, 200 },
+            { 128, SkTextBlob::kFull_Positioning, 300, 300 },
+        };
+        RunDef mergedSet6[] = {
+            { 384, SkTextBlob::kFull_Positioning, 0, 0 },
+        };
+        RunBuilderTest(reporter, builder, set6, SK_ARRAY_COUNT(set6), mergedSet6,
+                       SK_ARRAY_COUNT(mergedSet6));
+
+        RunDef set7[] = {
+            { 128, SkTextBlob::kDefault_Positioning, 100, 150 },
+            { 128, SkTextBlob::kDefault_Positioning, 100, 150 },
+            { 128, SkTextBlob::kHorizontal_Positioning, 100, 150 },
+            { 128, SkTextBlob::kHorizontal_Positioning, 200, 150 },
+            { 128, SkTextBlob::kFull_Positioning, 400, 350 },
+            { 128, SkTextBlob::kFull_Positioning, 400, 350 },
+            { 128, SkTextBlob::kDefault_Positioning, 100, 450 },
+            { 128, SkTextBlob::kDefault_Positioning, 100, 450 },
+            { 128, SkTextBlob::kHorizontal_Positioning, 100, 550 },
+            { 128, SkTextBlob::kHorizontal_Positioning, 200, 650 },
+            { 128, SkTextBlob::kFull_Positioning, 400, 750 },
+            { 128, SkTextBlob::kFull_Positioning, 400, 850 },
+        };
+        RunDef mergedSet7[] = {
+            { 128, SkTextBlob::kDefault_Positioning, 100, 150 },
+            { 128, SkTextBlob::kDefault_Positioning, 100, 150 },
+            { 256, SkTextBlob::kHorizontal_Positioning, 0, 150 },
+            { 256, SkTextBlob::kFull_Positioning, 0, 0 },
+            { 128, SkTextBlob::kDefault_Positioning, 100, 450 },
+            { 128, SkTextBlob::kDefault_Positioning, 100, 450 },
+            { 128, SkTextBlob::kHorizontal_Positioning, 0, 550 },
+            { 128, SkTextBlob::kHorizontal_Positioning, 0, 650 },
+            { 256, SkTextBlob::kFull_Positioning, 0, 0 },
+        };
+        RunBuilderTest(reporter, builder, set7, SK_ARRAY_COUNT(set7), mergedSet7,
+                       SK_ARRAY_COUNT(mergedSet7));
+    }
+
+    // This unit test verifies blob bounds computation.
+    static void TestBounds(skiatest::Reporter* reporter) {
+        SkTextBlobBuilder builder;
+        SkPaint font;
+        font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+
+        // Explicit bounds.
+        {
+            SkAutoTUnref<const SkTextBlob> blob(builder.build());
+            REPORTER_ASSERT(reporter, blob->bounds().isEmpty());
+        }
+
+        {
+            SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20);
+            builder.allocRun(font, 16, 0, 0, &r1);
+            SkAutoTUnref<const SkTextBlob> blob(builder.build());
+            REPORTER_ASSERT(reporter, blob->bounds() == r1);
+        }
+
+        {
+            SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20);
+            builder.allocRunPosH(font, 16, 0, &r1);
+            SkAutoTUnref<const SkTextBlob> blob(builder.build());
+            REPORTER_ASSERT(reporter, blob->bounds() == r1);
+        }
+
+        {
+            SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20);
+            builder.allocRunPos(font, 16, &r1);
+            SkAutoTUnref<const SkTextBlob> blob(builder.build());
+            REPORTER_ASSERT(reporter, blob->bounds() == r1);
+        }
+
+        {
+            SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20);
+            SkRect r2 = SkRect::MakeXYWH(15, 20, 50, 50);
+            SkRect r3 = SkRect::MakeXYWH(0, 5, 10, 5);
+
+            builder.allocRun(font, 16, 0, 0, &r1);
+            builder.allocRunPosH(font, 16, 0, &r2);
+            builder.allocRunPos(font, 16, &r3);
+
+            SkAutoTUnref<const SkTextBlob> blob(builder.build());
+            REPORTER_ASSERT(reporter, blob->bounds() == SkRect::MakeXYWH(0, 5, 65, 65));
+        }
+
+        {
+            // Verify empty blob bounds after building some non-empty blobs.
+            SkAutoTUnref<const SkTextBlob> blob(builder.build());
+            REPORTER_ASSERT(reporter, blob->bounds().isEmpty());
+        }
+
+        // Implicit bounds
+        // FIXME: not supported yet.
+    }
+
+private:
+    struct RunDef {
+        unsigned                     count;
+        SkTextBlob::GlyphPositioning pos;
+        SkScalar                     x, y;
+    };
+
+    static void RunBuilderTest(skiatest::Reporter* reporter, SkTextBlobBuilder& builder,
+                               const RunDef in[], unsigned inCount,
+                               const RunDef out[], unsigned outCount) {
+        SkPaint font;
+        font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+
+        unsigned glyphCount = 0;
+        unsigned posCount = 0;
+
+        for (unsigned i = 0; i < inCount; ++i) {
+            AddRun(font, in[i].count, in[i].pos, SkPoint::Make(in[i].x, in[i].y), builder);
+            glyphCount += in[i].count;
+            posCount += in[i].count * in[i].pos;
+        }
+
+        SkAutoTUnref<const SkTextBlob> blob(builder.build());
+
+        SkTextBlob::RunIterator it(blob);
+        for (unsigned i = 0; i < outCount; ++i) {
+            REPORTER_ASSERT(reporter, !it.done());
+            REPORTER_ASSERT(reporter, out[i].pos == it.positioning());
+            REPORTER_ASSERT(reporter, out[i].count == it.glyphCount());
+            if (SkTextBlob::kDefault_Positioning == out[i].pos) {
+                REPORTER_ASSERT(reporter, out[i].x == it.offset().x());
+                REPORTER_ASSERT(reporter, out[i].y == it.offset().y());
+            } else if (SkTextBlob::kHorizontal_Positioning == out[i].pos) {
+                REPORTER_ASSERT(reporter, out[i].y == it.offset().y());
+            }
+
+            for (unsigned k = 0; k < it.glyphCount(); ++k) {
+                REPORTER_ASSERT(reporter, k % 128 == it.glyphs()[k]);
+                if (SkTextBlob::kHorizontal_Positioning == it.positioning()) {
+                    REPORTER_ASSERT(reporter, SkIntToScalar(k % 128) == it.pos()[k]);
+                } else if (SkTextBlob::kFull_Positioning == it.positioning()) {
+                    REPORTER_ASSERT(reporter, SkIntToScalar(k % 128) == it.pos()[k * 2]);
+                    REPORTER_ASSERT(reporter, -SkIntToScalar(k % 128) == it.pos()[k * 2 + 1]);
+                }
+            }
+
+            it.next();
+        }
+
+        REPORTER_ASSERT(reporter, it.done());
+    }
+
+    static void AddRun(const SkPaint& font, int count, SkTextBlob::GlyphPositioning pos,
+                       const SkPoint& offset, SkTextBlobBuilder& builder,
+                       const SkRect* bounds = NULL) {
+        switch (pos) {
+        case SkTextBlob::kDefault_Positioning: {
+            const SkTextBlobBuilder::RunBuffer& rb = builder.allocRun(font, count, offset.x(),
+                                                                      offset.y(), bounds);
+            for (int i = 0; i < count; ++i) {
+                rb.glyphs[i] = i;
+            }
+        } break;
+        case SkTextBlob::kHorizontal_Positioning: {
+            const SkTextBlobBuilder::RunBuffer& rb = builder.allocRunPosH(font, count, offset.y(),
+                                                                          bounds);
+            for (int i = 0; i < count; ++i) {
+                rb.glyphs[i] = i;
+                rb.pos[i] = SkIntToScalar(i);
+            }
+        } break;
+        case SkTextBlob::kFull_Positioning: {
+            const SkTextBlobBuilder::RunBuffer& rb = builder.allocRunPos(font, count, bounds);
+            for (int i = 0; i < count; ++i) {
+                rb.glyphs[i] = i;
+                rb.pos[i * 2] = SkIntToScalar(i);
+                rb.pos[i * 2 + 1] = -SkIntToScalar(i);
+            }
+        } break;
+        default:
+            SkFAIL("unhandled positioning value");
+        }
+    }
+};
+
+DEF_TEST(TextBlob_builder, reporter) {
+    TextBlobTester::TestBuilder(reporter);
+    TextBlobTester::TestBounds(reporter);
+}
diff --git a/tests/TextureCompressionTest.cpp b/tests/TextureCompressionTest.cpp
index 2079fa3..7dd285d 100644
--- a/tests/TextureCompressionTest.cpp
+++ b/tests/TextureCompressionTest.cpp
@@ -12,60 +12,198 @@
 #include "SkTextureCompressor.h"
 #include "Test.h"
 
-static const int kLATCBlockDimension = 4;
-static const int kLATCEncodedBlockSize = 8;
+// TODO: Create separate tests for RGB and RGBA data once
+// ASTC and ETC1 decompression is implemented.
+
+static bool decompresses_a8(SkTextureCompressor::Format fmt) {
+    switch (fmt) {
+        case SkTextureCompressor::kLATC_Format:
+        case SkTextureCompressor::kR11_EAC_Format:
+            return true;
+
+        default:
+            return false;
+    }
+}
+
+static bool compresses_a8(SkTextureCompressor::Format fmt) {
+    switch (fmt) {
+        case SkTextureCompressor::kLATC_Format:
+        case SkTextureCompressor::kR11_EAC_Format:
+        case SkTextureCompressor::kASTC_12x12_Format:
+            return true;
+
+        default:
+            return false;
+    }
+}
 
 /**
  * Make sure that we properly fail when we don't have multiple of four image dimensions.
  */
-DEF_TEST(CompressLATCFailDimensions, reporter) {
+DEF_TEST(CompressAlphaFailDimensions, reporter) {
     SkBitmap bitmap;
-    static const int kWidth = 63;
-    static const int kHeight = 63;
+    static const int kWidth = 17;
+    static const int kHeight = 17;
     SkImageInfo info = SkImageInfo::MakeA8(kWidth, kHeight);
-    REPORTER_ASSERT(reporter, kWidth % kLATCBlockDimension != 0);
-    REPORTER_ASSERT(reporter, kHeight % kLATCBlockDimension != 0);
+
+    // R11_EAC and LATC are both dimensions of 4, so we need to make sure that we
+    // are violating those assumptions. And if we are, then we're also violating the
+    // assumptions of ASTC, which is 12x12 since any number not divisible by 4 is
+    // also not divisible by 12. Our dimensions are prime, so any block dimension
+    // larger than 1 should fail.
+    REPORTER_ASSERT(reporter, kWidth % 4 != 0);
+    REPORTER_ASSERT(reporter, kHeight % 4 != 0);
 
     bool setInfoSuccess = bitmap.setInfo(info);
     REPORTER_ASSERT(reporter, setInfoSuccess);
 
-    bool allocPixelsSuccess = bitmap.allocPixels(info);
-    REPORTER_ASSERT(reporter, allocPixelsSuccess);
+    bitmap.allocPixels(info);
     bitmap.unlockPixels();
-
-    const SkTextureCompressor::Format kLATCFormat = SkTextureCompressor::kLATC_Format;
-    SkAutoDataUnref latcData(SkTextureCompressor::CompressBitmapToFormat(bitmap, kLATCFormat));
-    REPORTER_ASSERT(reporter, NULL == latcData);
+    
+    for (int i = 0; i < SkTextureCompressor::kFormatCnt; ++i) {
+        const SkTextureCompressor::Format fmt = static_cast<SkTextureCompressor::Format>(i);
+        if (!compresses_a8(fmt)) {
+            continue;
+        }
+        SkAutoDataUnref data(SkTextureCompressor::CompressBitmapToFormat(bitmap, fmt));
+        REPORTER_ASSERT(reporter, NULL == data);
+    }
 }
 
 /**
  * Make sure that we properly fail when we don't have the correct bitmap type.
- * LATC compressed textures can only be created from A8 bitmaps.
+ * compressed textures can (currently) only be created from A8 bitmaps.
  */
-DEF_TEST(CompressLATCFailColorType, reporter) {
+DEF_TEST(CompressAlphaFailColorType, reporter) {
     SkBitmap bitmap;
-    static const int kWidth = 64;
-    static const int kHeight = 64;
+    static const int kWidth = 12;
+    static const int kHeight = 12;
     SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
-    REPORTER_ASSERT(reporter, kWidth % kLATCBlockDimension == 0);
-    REPORTER_ASSERT(reporter, kHeight % kLATCBlockDimension == 0);
+
+    // ASTC is at most 12x12, and any dimension divisible by 12 is also divisible
+    // by 4, which is the dimensions of R11_EAC and LATC. In the future, we might
+    // support additional variants of ASTC, such as 5x6 and 8x8, in which case this would
+    // need to be updated.
+    REPORTER_ASSERT(reporter, kWidth % 12 == 0);
+    REPORTER_ASSERT(reporter, kHeight % 12 == 0);
 
     bool setInfoSuccess = bitmap.setInfo(info);
     REPORTER_ASSERT(reporter, setInfoSuccess);
 
-    bool allocPixelsSuccess = bitmap.allocPixels(info);
-    REPORTER_ASSERT(reporter, allocPixelsSuccess);
+    bitmap.allocPixels(info);
     bitmap.unlockPixels();
 
-    const SkTextureCompressor::Format kLATCFormat = SkTextureCompressor::kLATC_Format;
-    SkAutoDataUnref latcData(SkTextureCompressor::CompressBitmapToFormat(bitmap, kLATCFormat));
-    REPORTER_ASSERT(reporter, NULL == latcData);
+    for (int i = 0; i < SkTextureCompressor::kFormatCnt; ++i) {
+        const SkTextureCompressor::Format fmt = static_cast<SkTextureCompressor::Format>(i);
+        if (!compresses_a8(fmt)) {
+            continue;
+        }
+        SkAutoDataUnref data(SkTextureCompressor::CompressBitmapToFormat(bitmap, fmt));
+        REPORTER_ASSERT(reporter, NULL == data);
+    }
+}
+
+/**
+ * Make sure that if you compress a texture with alternating black/white pixels, and
+ * then decompress it, you get what you started with.
+ */
+DEF_TEST(CompressCheckerboard, reporter) {
+    SkBitmap bitmap;
+    static const int kWidth = 48;  // We need the number to be divisible by both
+    static const int kHeight = 48; // 12 (ASTC) and 16 (ARM NEON R11 EAC).
+    SkImageInfo info = SkImageInfo::MakeA8(kWidth, kHeight);
+
+    // ASTC is at most 12x12, and any dimension divisible by 12 is also divisible
+    // by 4, which is the dimensions of R11_EAC and LATC. In the future, we might
+    // support additional variants of ASTC, such as 5x6 and 8x8, in which case this would
+    // need to be updated. Additionally, ARM NEON and SSE code paths support up to
+    // four blocks of R11 EAC at once, so they operate on 16-wide blocks. Hence, the
+    // valid width and height is going to be the LCM of 12 and 16 which is 4*4*3 = 48
+    REPORTER_ASSERT(reporter, kWidth % 48 == 0);
+    REPORTER_ASSERT(reporter, kHeight % 48 == 0);
+
+    bool setInfoSuccess = bitmap.setInfo(info);
+    REPORTER_ASSERT(reporter, setInfoSuccess);
+
+    bitmap.allocPixels(info);
+    bitmap.unlockPixels();
+
+    // Populate bitmap
+    {
+        SkAutoLockPixels alp(bitmap);
+
+        uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels());
+        REPORTER_ASSERT(reporter, pixels);
+        if (NULL == pixels) {
+            return;
+        }
+
+        for (int y = 0; y < kHeight; ++y) {
+            for (int x = 0; x < kWidth; ++x) {
+                if ((x ^ y) & 1) {
+                    pixels[x] = 0xFF;
+                } else {
+                    pixels[x] = 0;
+                }
+            }
+            pixels += bitmap.rowBytes();
+        }
+    }
+
+    SkAutoMalloc decompMemory(kWidth*kHeight);
+    uint8_t* decompBuffer = reinterpret_cast<uint8_t*>(decompMemory.get());
+    REPORTER_ASSERT(reporter, decompBuffer);
+    if (NULL == decompBuffer) {
+        return;
+    }
+
+    for (int i = 0; i < SkTextureCompressor::kFormatCnt; ++i) {
+        const SkTextureCompressor::Format fmt = static_cast<SkTextureCompressor::Format>(i);
+
+        // Ignore formats for RGBA data, since the decompressed buffer
+        // won't match the size and contents of the original.
+        if (!decompresses_a8(fmt) || !compresses_a8(fmt)) {
+            continue;
+        }
+
+        SkAutoDataUnref data(SkTextureCompressor::CompressBitmapToFormat(bitmap, fmt));
+        REPORTER_ASSERT(reporter, data);
+        if (NULL == data) {
+            continue;
+        }
+
+        bool decompResult =
+            SkTextureCompressor::DecompressBufferFromFormat(
+                decompBuffer, kWidth,
+                data->bytes(),
+                kWidth, kHeight, fmt);
+        REPORTER_ASSERT(reporter, decompResult);
+
+        SkAutoLockPixels alp(bitmap);
+        uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels());
+        REPORTER_ASSERT(reporter, pixels);
+        if (NULL == pixels) {
+            continue;
+        }
+
+        for (int y = 0; y < kHeight; ++y) {
+            for (int x = 0; x < kWidth; ++x) {
+                bool ok = pixels[y*bitmap.rowBytes() + x] == decompBuffer[y*kWidth + x];
+                REPORTER_ASSERT(reporter, ok);
+            }
+        }
+    }
 }
 
 /**
  * Make sure that if we pass in a solid color bitmap that we get the appropriate results
  */
 DEF_TEST(CompressLATC, reporter) {
+
+    const SkTextureCompressor::Format kLATCFormat = SkTextureCompressor::kLATC_Format;
+    static const int kLATCEncodedBlockSize = 8;
+
     SkBitmap bitmap;
     static const int kWidth = 8;
     static const int kHeight = 8;
@@ -74,40 +212,60 @@
     bool setInfoSuccess = bitmap.setInfo(info);
     REPORTER_ASSERT(reporter, setInfoSuccess);
 
-    bool allocPixelsSuccess = bitmap.allocPixels(info);
-    REPORTER_ASSERT(reporter, allocPixelsSuccess);
+    bitmap.allocPixels(info);
     bitmap.unlockPixels();
 
-    REPORTER_ASSERT(reporter, kWidth % kLATCBlockDimension == 0);
-    REPORTER_ASSERT(reporter, kHeight % kLATCBlockDimension == 0);
-    const int numBlocks = (kWidth / kLATCBlockDimension) * (kHeight / kLATCBlockDimension);
-    const size_t kSizeToBe = static_cast<size_t>(kLATCEncodedBlockSize * numBlocks);
+    int latcDimX, latcDimY;
+    SkTextureCompressor::GetBlockDimensions(kLATCFormat, &latcDimX, &latcDimY);
+
+    REPORTER_ASSERT(reporter, kWidth % latcDimX == 0);
+    REPORTER_ASSERT(reporter, kHeight % latcDimY == 0);
+    const size_t kSizeToBe =
+        SkTextureCompressor::GetCompressedDataSize(kLATCFormat, kWidth, kHeight);
+    REPORTER_ASSERT(reporter, kSizeToBe == ((kWidth*kHeight*kLATCEncodedBlockSize)/16));
+    REPORTER_ASSERT(reporter, (kSizeToBe % kLATCEncodedBlockSize) == 0);
 
     for (int lum = 0; lum < 256; ++lum) {
         bitmap.lockPixels();
         uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels());
-        REPORTER_ASSERT(reporter, NULL != pixels);
+        REPORTER_ASSERT(reporter, pixels);
+        if (NULL == pixels) {
+            bitmap.unlockPixels();
+            continue;
+        }
 
         for (int i = 0; i < kWidth*kHeight; ++i) {
             pixels[i] = lum;
         }
         bitmap.unlockPixels();
 
-        const SkTextureCompressor::Format kLATCFormat = SkTextureCompressor::kLATC_Format;
         SkAutoDataUnref latcData(
             SkTextureCompressor::CompressBitmapToFormat(bitmap, kLATCFormat));
-        REPORTER_ASSERT(reporter, NULL != latcData);
+        REPORTER_ASSERT(reporter, latcData);
+        if (NULL == latcData) {
+            continue;
+        }
+
         REPORTER_ASSERT(reporter, kSizeToBe == latcData->size());
 
-        // Make sure that it all matches a given block encoding. If the entire bitmap
-        // is a single value, then the lower two bytes of the encoded data should be that
-        // value. The remaining indices can be any value, and since we try to match the pixels
-        // in the chosen palette in increasing index order, each one should be zero. Hence,
-        // the correct encoding should be just the two luminance values in the bottom two
-        // bytes of the block encoding.
-        const uint64_t kConstColorEncoding = SkEndian_SwapLE64(lum | (lum << 8));
+        // Make sure that it all matches a given block encoding. Since we have
+        // COMPRESS_LATC_FAST defined in SkTextureCompressor_LATC.cpp, we are using
+        // an approximation scheme that optimizes for speed against coverage maps.
+        // That means that each palette in the encoded block is exactly the same,
+        // and that the three bits saved per pixel are computed from the top three
+        // bits of the luminance value.
+        const uint64_t kIndexEncodingMap[8] = { 1, 7, 6, 5, 4, 3, 2, 0 };
+        const uint64_t kIndex = kIndexEncodingMap[lum >> 5];
+        const uint64_t kConstColorEncoding =
+            SkEndian_SwapLE64(
+                255 |
+                (kIndex << 16) | (kIndex << 19) | (kIndex << 22) | (kIndex << 25) |
+                (kIndex << 28) | (kIndex << 31) | (kIndex << 34) | (kIndex << 37) |
+                (kIndex << 40) | (kIndex << 43) | (kIndex << 46) | (kIndex << 49) |
+                (kIndex << 52) | (kIndex << 55) | (kIndex << 58) | (kIndex << 61));
+
         const uint64_t* blockPtr = reinterpret_cast<const uint64_t*>(latcData->data());
-        for (int i = 0; i < numBlocks; ++i) {
+        for (size_t i = 0; i < (kSizeToBe/8); ++i) {
             REPORTER_ASSERT(reporter, blockPtr[i] == kConstColorEncoding);
         }
     }
diff --git a/tests/TileGridTest.cpp b/tests/TileGridTest.cpp
index da228a0..16434ab 100644
--- a/tests/TileGridTest.cpp
+++ b/tests/TileGridTest.cpp
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkBitmapDevice.h"
 #include "SkCanvas.h"
 #include "SkPictureRecorder.h"
 #include "SkTileGrid.h"
@@ -32,13 +31,13 @@
     SkTDArray<SkRect> fRects;
 };
 
-static void verifyTileHits(skiatest::Reporter* reporter, SkIRect rect,
+static void verifyTileHits(skiatest::Reporter* reporter, SkRect rect,
                            uint32_t tileMask, int borderPixels = 0) {
     SkTileGridFactory::TileGridInfo info;
     info.fMargin.set(borderPixels, borderPixels);
     info.fOffset.setZero();
     info.fTileInterval.set(10 - 2 * borderPixels, 10 - 2 * borderPixels);
-    SkTileGrid grid(2, 2, info, NULL);
+    SkTileGrid grid(2, 2, info);
     grid.insert(NULL, rect, false);
     REPORTER_ASSERT(reporter, grid.tileCount(0, 0) ==
                     ((tileMask & kTopLeft_Tile)? 1 : 0));
@@ -74,14 +73,14 @@
     // Test parts of top-left tile
     {
         MockCanvas mockCanvas(store);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
     }
     {
         MockCanvas mockCanvas(store);
         mockCanvas.translate(-7.99f, -7.99f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
     }
@@ -89,7 +88,7 @@
     {
         MockCanvas mockCanvas(store);
         mockCanvas.translate(-9.5f, -9.5f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 2 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
         REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[1]);
@@ -98,7 +97,7 @@
     {
         MockCanvas mockCanvas(store);
         mockCanvas.translate(-16.0f, -16.0f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[0]);
     }
@@ -106,28 +105,28 @@
     {
         MockCanvas mockCanvas(store);
         mockCanvas.translate(2.0f, 0.0f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
     }
     {
         MockCanvas mockCanvas(store);
         mockCanvas.translate(0.0f, 2.0f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
     }
     {
         MockCanvas mockCanvas(store);
         mockCanvas.translate(-22.0f, -16.0f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[0]);
     }
     {
         MockCanvas mockCanvas(store);
         mockCanvas.translate(-16.0f, -22.0f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[0]);
     }
@@ -169,14 +168,14 @@
         // The offset should cancel the top and left borders of the top left tile
         // So a look-up at interval 0-10 should be grid aligned,
         MockCanvas mockCanvas(tileBitmap);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
     }
     {
         // Encroaching border by one pixel
         MockCanvas mockCanvas(moreThanATileBitmap);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 2 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
         REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[1]);
@@ -187,14 +186,14 @@
         // with middle tile.
         MockCanvas mockCanvas(tileBitmap);
         mockCanvas.translate(SkIntToScalar(-8), SkIntToScalar(-8));
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[0]);
     }
     {
         MockCanvas mockCanvas(tileBitmap);
         mockCanvas.translate(-7.9f, -7.9f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 2 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
         REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[1]);
@@ -202,7 +201,7 @@
     {
         MockCanvas mockCanvas(tileBitmap);
         mockCanvas.translate(-8.1f, -8.1f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         REPORTER_ASSERT(reporter, 2 == mockCanvas.fRects.count());
         REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[0]);
         REPORTER_ASSERT(reporter, rect3 == mockCanvas.fRects[1]);
@@ -213,7 +212,7 @@
         // adjusted region, sitting right on top of the tile boundary.
         MockCanvas mockCanvas(tinyBitmap);
         mockCanvas.translate(-8.0f, -8.0f);
-        picture->draw(&mockCanvas);
+        picture->playback(&mockCanvas);
         // This test passes by not asserting. We do not validate the rects recorded
         // because the result is numerically unstable (floating point equality).
         // The content of any one of the four tiles of the tilegrid would be a valid
@@ -224,29 +223,29 @@
 
 DEF_TEST(TileGrid, reporter) {
     // Out of bounds
-    verifyTileHits(reporter, SkIRect::MakeXYWH(30, 0, 1, 1),  0);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(0, 30, 1, 1),  0);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(-10, 0, 1, 1),  0);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(0, -10, 1, 1),  0);
+    verifyTileHits(reporter, SkRect::MakeXYWH(30, 0, 1, 1),  0);
+    verifyTileHits(reporter, SkRect::MakeXYWH(0, 30, 1, 1),  0);
+    verifyTileHits(reporter, SkRect::MakeXYWH(-10, 0, 1, 1),  0);
+    verifyTileHits(reporter, SkRect::MakeXYWH(0, -10, 1, 1),  0);
 
     // Dilation for AA consideration
-    verifyTileHits(reporter, SkIRect::MakeXYWH(0, 0, 9, 9),  kTopLeft_Tile);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(0, 0, 10, 10),  kAll_Tile);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(9, 9, 1, 1),  kAll_Tile);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(10, 10, 1, 1),  kAll_Tile);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(11, 11, 1, 1),  kBottomRight_Tile);
+    verifyTileHits(reporter, SkRect::MakeXYWH(0, 0, 9, 9),  kTopLeft_Tile);
+    verifyTileHits(reporter, SkRect::MakeXYWH(0, 0, 10, 10),  kAll_Tile);
+    verifyTileHits(reporter, SkRect::MakeXYWH(9, 9, 1, 1),  kAll_Tile);
+    verifyTileHits(reporter, SkRect::MakeXYWH(10, 10, 1, 1),  kAll_Tile);
+    verifyTileHits(reporter, SkRect::MakeXYWH(11, 11, 1, 1),  kBottomRight_Tile);
 
     // BorderPixels
-    verifyTileHits(reporter, SkIRect::MakeXYWH(0, 0, 6, 6),  kTopLeft_Tile, 1);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(0, 0, 7, 7),  kAll_Tile, 1);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(9, 9, 1, 1),  kAll_Tile, 1);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(10, 10, 1, 1),  kBottomRight_Tile, 1);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(17, 17, 1, 1),  kBottomRight_Tile, 1);
+    verifyTileHits(reporter, SkRect::MakeXYWH(0, 0, 6, 6),  kTopLeft_Tile, 1);
+    verifyTileHits(reporter, SkRect::MakeXYWH(0, 0, 7, 7),  kAll_Tile, 1);
+    verifyTileHits(reporter, SkRect::MakeXYWH(9, 9, 1, 1),  kAll_Tile, 1);
+    verifyTileHits(reporter, SkRect::MakeXYWH(10, 10, 1, 1),  kBottomRight_Tile, 1);
+    verifyTileHits(reporter, SkRect::MakeXYWH(17, 17, 1, 1),  kBottomRight_Tile, 1);
 
     // BBoxes that overlap tiles
-    verifyTileHits(reporter, SkIRect::MakeXYWH(5, 5, 10, 1),  kTopLeft_Tile | kTopRight_Tile);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(5, 5, 1, 10),  kTopLeft_Tile |
+    verifyTileHits(reporter, SkRect::MakeXYWH(5, 5, 10, 1),  kTopLeft_Tile | kTopRight_Tile);
+    verifyTileHits(reporter, SkRect::MakeXYWH(5, 5, 1, 10),  kTopLeft_Tile |
                    kBottomLeft_Tile);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(5, 5, 10, 10),  kAll_Tile);
-    verifyTileHits(reporter, SkIRect::MakeXYWH(-10, -10, 40, 40),  kAll_Tile);
+    verifyTileHits(reporter, SkRect::MakeXYWH(5, 5, 10, 10),  kAll_Tile);
+    verifyTileHits(reporter, SkRect::MakeXYWH(-10, -10, 40, 40),  kAll_Tile);
 }
diff --git a/tests/UnitTestTest.cpp b/tests/UnitTestTest.cpp
deleted file mode 100644
index 35432cd..0000000
--- a/tests/UnitTestTest.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * 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 "SkRTConf.h"
-#include "Test.h"
-
-DEF_TEST(UnitTest, reporter) {
-#ifdef SK_SUPPORT_UNITTEST
-    SkRTConfRegistry::UnitTest();
-#endif
-}
diff --git a/tests/UtilsTest.cpp b/tests/UtilsTest.cpp
index 438a5cc..2c84c95 100644
--- a/tests/UtilsTest.cpp
+++ b/tests/UtilsTest.cpp
@@ -53,14 +53,14 @@
     REPORTER_ASSERT(reporter, 1 == obj1.getRefCnt());
 
     {
-        SkAutoSTArray<2, SkRefPtr<RefClass> > tmp;
+        SkAutoSTArray<2, SkAutoTUnref<RefClass> > tmp;
         REPORTER_ASSERT(reporter, 0 == tmp.count());
 
         tmp.reset(0);   // test out reset(0) when already at 0
         tmp.reset(4);   // this should force a new allocation
         REPORTER_ASSERT(reporter, 4 == tmp.count());
-        tmp[0] = &obj0;
-        tmp[1] = &obj1;
+        tmp[0].reset(SkRef(&obj0));
+        tmp[1].reset(SkRef(&obj1));
         REPORTER_ASSERT(reporter, 2 == obj0.getRefCnt());
         REPORTER_ASSERT(reporter, 2 == obj1.getRefCnt());
 
@@ -72,8 +72,8 @@
 
         tmp.reset(2);   // this should use the preexisting allocation
         REPORTER_ASSERT(reporter, 2 == tmp.count());
-        tmp[0] = &obj0;
-        tmp[1] = &obj1;
+        tmp[0].reset(SkRef(&obj0));
+        tmp[1].reset(SkRef(&obj1));
     }
 
     // test out destructor with data in the array (and using existing allocation)
@@ -82,11 +82,11 @@
 
     {
         // test out allocating ctor (this should allocate new memory)
-        SkAutoSTArray<2, SkRefPtr<RefClass> > tmp(4);
+        SkAutoSTArray<2, SkAutoTUnref<RefClass> > tmp(4);
         REPORTER_ASSERT(reporter, 4 == tmp.count());
 
-        tmp[0] = &obj0;
-        tmp[1] = &obj1;
+        tmp[0].reset(SkRef(&obj0));
+        tmp[1].reset(SkRef(&obj1));
         REPORTER_ASSERT(reporter, 2 == obj0.getRefCnt());
         REPORTER_ASSERT(reporter, 2 == obj1.getRefCnt());
 
@@ -96,8 +96,8 @@
         REPORTER_ASSERT(reporter, 1 == obj1.getRefCnt());
 
         tmp.reset(2);   // this should use the preexisting storage
-        tmp[0] = &obj0;
-        tmp[1] = &obj1;
+        tmp[0].reset(SkRef(&obj0));
+        tmp[1].reset(SkRef(&obj1));
         REPORTER_ASSERT(reporter, 2 == obj0.getRefCnt());
         REPORTER_ASSERT(reporter, 2 == obj1.getRefCnt());
 
@@ -105,8 +105,8 @@
         REPORTER_ASSERT(reporter, 1 == obj0.getRefCnt());
         REPORTER_ASSERT(reporter, 1 == obj1.getRefCnt());
 
-        tmp[0] = &obj0;
-        tmp[1] = &obj1;
+        tmp[0].reset(SkRef(&obj0));
+        tmp[1].reset(SkRef(&obj1));
         REPORTER_ASSERT(reporter, 2 == obj0.getRefCnt());
         REPORTER_ASSERT(reporter, 2 == obj1.getRefCnt());
     }
diff --git a/tests/WArrayTest.cpp b/tests/WArrayTest.cpp
index 11d5ca5..7f03e5b 100644
--- a/tests/WArrayTest.cpp
+++ b/tests/WArrayTest.cpp
@@ -164,7 +164,7 @@
         SkAutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t> > result;
         result.reset(getAdvanceData((void*)this, fAdvancesLen, fSubset, fSubsetLen, getAdvance));
 
-        SkString stringResult = stringify_advance_data(result.get());
+        SkString stringResult = stringify_advance_data(result);
         if (!stringResult.equals(fExpected)) {
             SkDebugf("Expected: %s\n  Result: %s\n", fExpected, stringResult.c_str());
             return false;
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index 1a52793..f47c67b 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -10,6 +10,7 @@
 #include "SkColorPriv.h"
 #include "SkMathPriv.h"
 #include "SkRegion.h"
+#include "SkSurface.h"
 #include "Test.h"
 #include "sk_tool_utils.h"
 
@@ -114,8 +115,7 @@
 static void fillCanvas(SkCanvas* canvas) {
     SkBitmap bmp;
     if (bmp.isNull()) {
-        SkDEBUGCODE(bool alloc = ) bmp.allocN32Pixels(DEV_W, DEV_H);
-        SkASSERT(alloc);
+        bmp.allocN32Pixels(DEV_W, DEV_H);
         for (int y = 0; y < DEV_H; ++y) {
             for (int x = 0; x < DEV_W; ++x) {
                 *bmp.getAddr32(x, y) = getCanvasColor(x, y);
@@ -185,9 +185,9 @@
            SkAbs32(aB - bB) <= 1;
 }
 
-static bool checkWrite(skiatest::Reporter* reporter, SkCanvas* canvas, const SkBitmap& bitmap,
+static bool check_write(skiatest::Reporter* reporter, SkCanvas* canvas, const SkBitmap& bitmap,
                        int writeX, int writeY) {
-    SkImageInfo canvasInfo;
+    const SkImageInfo canvasInfo = canvas->imageInfo();
     size_t canvasRowBytes;
     const uint32_t* canvasPixels;
 
@@ -195,15 +195,9 @@
     // At some point this will be unsupported, as we won't allow accessBitmap() to magically call
     // readPixels for the client.
     SkBitmap secretDevBitmap;
-    {
-        SkBaseDevice* dev = canvas->getDevice();
-        if (!dev) {
-            return false;
-        }
-        secretDevBitmap = dev->accessBitmap(false);
-    }
+    canvas->readPixels(SkIRect::MakeWH(canvasInfo.width(), canvasInfo.height()), &secretDevBitmap);
+
     SkAutoLockPixels alp(secretDevBitmap);
-    canvasInfo = secretDevBitmap.info();
     canvasRowBytes = secretDevBitmap.rowBytes();
     canvasPixels = static_cast<const uint32_t*>(secretDevBitmap.getPixels());
 
@@ -298,25 +292,22 @@
     return true;
 }
 
-static SkBaseDevice* createDevice(const CanvasConfig& c, GrContext* grCtx) {
+static void free_pixels(void* pixels, void* ctx) {
+    sk_free(pixels);
+}
+
+static SkSurface* create_surface(const CanvasConfig& c, GrContext* grCtx) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
     switch (c.fDevType) {
         case kRaster_DevType: {
-            SkBitmap bmp;
-            size_t rowBytes = c.fTightRowBytes ? 0 : 4 * DEV_W + 100;
-            SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
-            if (!allocRowBytes(&bmp, info, rowBytes)) {
-                sk_throw();
-                return NULL;
-            }
+            const size_t rowBytes = c.fTightRowBytes ? info.minRowBytes() : 4 * DEV_W + 100;
+            const size_t size = info.getSafeSize(rowBytes);
+            void* pixels = sk_malloc_throw(size);
             // if rowBytes isn't tight then set the padding to a known value
-            if (rowBytes) {
-                SkAutoLockPixels alp(bmp);
-                // We'd just use memset here but GCC 4.8.1 throws up a bogus warning when we do.
-                for (size_t i = 0; i < bmp.getSafeSize(); i++) {
-                    ((uint8_t*)bmp.getPixels())[i] = DEV_PAD;
-                }
+            if (!c.fTightRowBytes) {
+                memset(pixels, DEV_PAD, size);
             }
-            return new SkBitmapDevice(bmp);
+            return SkSurface::NewRasterDirectReleaseProc(info, pixels, rowBytes, free_pixels, NULL);
         }
 #if SK_SUPPORT_GPU
         case kGpu_BottomLeft_DevType:
@@ -330,13 +321,13 @@
                 kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
             GrAutoScratchTexture ast(grCtx, desc, GrContext::kExact_ScratchTexMatch);
             SkAutoTUnref<GrTexture> tex(ast.detach());
-            return new SkGpuDevice(grCtx, tex);
+            return SkSurface::NewRenderTargetDirect(tex->asRenderTarget());
 #endif
     }
     return NULL;
 }
 
-static bool setupBitmap(SkBitmap* bm, SkColorType ct, SkAlphaType at, int w, int h, int tightRB) {
+static bool setup_bitmap(SkBitmap* bm, SkColorType ct, SkAlphaType at, int w, int h, int tightRB) {
     size_t rowBytes = tightRB ? 0 : 4 * w + 60;
     SkImageInfo info = SkImageInfo::Make(w, h, ct, at);
     if (!allocRowBytes(bm, info, rowBytes)) {
@@ -351,7 +342,24 @@
     return true;
 }
 
+static void call_writepixels(SkCanvas* canvas) {
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
+    SkPMColor pixel = 0;
+    canvas->writePixels(info, &pixel, sizeof(SkPMColor), 0, 0);
+}
+
+static void test_surface_genid(skiatest::Reporter* reporter) {
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
+    SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
+    uint32_t genID1 = surface->generationID();
+    call_writepixels(surface->getCanvas());
+    uint32_t genID2 = surface->generationID();
+    REPORTER_ASSERT(reporter, genID1 != genID2);
+}
+
 DEF_GPUTEST(WritePixels, reporter, factory) {
+    test_surface_genid(reporter);
+
     SkCanvas canvas;
 
     const SkIRect testRects[] = {
@@ -426,8 +434,8 @@
             }
 #endif
 
-            SkAutoTUnref<SkBaseDevice> device(createDevice(gCanvasConfigs[i], context));
-            SkCanvas canvas(device);
+            SkAutoTUnref<SkSurface> surface(create_surface(gCanvasConfigs[i], context));
+            SkCanvas& canvas = *surface->getCanvas();
 
             static const struct {
                 SkColorType fColorType;
@@ -447,15 +455,16 @@
 
                         fillCanvas(&canvas);
                         SkBitmap bmp;
-                        REPORTER_ASSERT(reporter, setupBitmap(&bmp, ct, at, rect.width(),
-                                                              rect.height(), SkToBool(tightBmp)));
-                        uint32_t idBefore = canvas.getDevice()->accessBitmap(false).getGenerationID();
+                        REPORTER_ASSERT(reporter, setup_bitmap(&bmp, ct, at, rect.width(),
+                                                               rect.height(), SkToBool(tightBmp)));
+                        uint32_t idBefore = surface->generationID();
 
                        // sk_tool_utils::write_pixels(&canvas, bmp, rect.fLeft, rect.fTop, ct, at);
                         canvas.writePixels(bmp, rect.fLeft, rect.fTop);
 
-                        uint32_t idAfter = canvas.getDevice()->accessBitmap(false).getGenerationID();
-                        REPORTER_ASSERT(reporter, checkWrite(reporter, &canvas, bmp, rect.fLeft, rect.fTop));
+                        uint32_t idAfter = surface->generationID();
+                        REPORTER_ASSERT(reporter, check_write(reporter, &canvas, bmp,
+                                                              rect.fLeft, rect.fTop));
 
                         // we should change the genID iff pixels were actually written.
                         SkIRect canvasRect = SkIRect::MakeSize(canvas.getDeviceSize());
diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp
index f4b67c9..0058215 100644
--- a/tests/skia_test.cpp
+++ b/tests/skia_test.cpp
@@ -8,12 +8,12 @@
 #include "CrashHandler.h"
 #include "OverwriteLine.h"
 #include "Resources.h"
-#include "SkCommandLineFlags.h"
+#include "SkCommonFlags.h"
 #include "SkGraphics.h"
 #include "SkOSFile.h"
 #include "SkTArray.h"
+#include "SkTaskGroup.h"
 #include "SkTemplates.h"
-#include "SkThreadPool.h"
 #include "SkTime.h"
 #include "Test.h"
 
@@ -24,23 +24,7 @@
 
 using namespace skiatest;
 
-DEFINE_string2(match, m, NULL, "[~][^]substring[$] [...] of test name to run.\n" \
-                               "Multiple matches may be separated by spaces.\n" \
-                               "~ causes a matching test to always be skipped\n" \
-                               "^ requires the start of the test to match\n" \
-                               "$ requires the end of the test to match\n" \
-                               "^ and $ requires an exact match\n" \
-                               "If a test does not match any list entry,\n" \
-                               "it is skipped unless some list entry starts with ~");
 DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps.");
-DEFINE_bool2(leaks, l, false, "show leaked ref cnt'd objects.");
-DEFINE_bool2(single, z, false, "run tests on a single thread internally.");
-DEFINE_bool2(verbose, v, false, "enable verbose output from the test driver.");
-DEFINE_bool2(veryVerbose, V, false, "tell individual tests to be verbose.");
-DEFINE_bool(cpu, true, "whether or not to run CPU tests.");
-DEFINE_bool(gpu, true, "whether or not to run GPU tests.");
-DEFINE_int32(threads, SkThreadPool::kThreadPerCore,
-             "Run threadsafe tests on a threadpool with this many threads.");
 
 // need to explicitly declare this, or we get some weird infinite loop llist
 template TestRegistry* TestRegistry::gHead;
@@ -70,7 +54,6 @@
     explicit DebugfReporter(int total) : fDone(0), fTotal(total) {}
 
     virtual bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_extendedTest; }
-    virtual bool allowThreaded()     const SK_OVERRIDE { return !FLAGS_single; }
     virtual bool verbose()           const SK_OVERRIDE { return FLAGS_veryVerbose; }
 
 protected:
@@ -131,11 +114,9 @@
     return true;
 }
 
-int tool_main(int argc, char** argv);
-int tool_main(int argc, char** argv) {
+int test_main();
+int test_main() {
     SetupCrashHandler();
-    SkCommandLineFlags::SetUsage("");
-    SkCommandLineFlags::Parse(argc, argv);
 
 #if SK_ENABLE_INST_COUNT
     if (FLAGS_leaks) {
@@ -193,7 +174,8 @@
     int32_t failCount = 0;
     int skipCount = 0;
 
-    SkThreadPool threadpool(FLAGS_threads);
+    SkTaskGroup::Enabler enabled(FLAGS_threads);
+    SkTaskGroup cpuTests;
     SkTArray<Test*> gpuTests;  // Always passes ownership to an SkTestRunnable
 
     DebugfReporter reporter(toRun);
@@ -204,7 +186,7 @@
         } else if (test->isGPUTest()) {
             gpuTests.push_back() = test.detach();
         } else {
-            threadpool.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount)));
+            cpuTests.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount)));
         }
     }
 
@@ -222,7 +204,7 @@
     }
 
     // Block until threaded tests finish.
-    threadpool.wait();
+    cpuTests.wait();
 
     if (FLAGS_verbose) {
         SkDebugf("\nFinished %d tests, %d failures, %d skipped. (%d internal tests)",
@@ -235,7 +217,8 @@
 }
 
 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
-int main(int argc, char * const argv[]) {
-    return tool_main(argc, (char**) argv);
+int main(int argc, char** argv) {
+    SkCommandLineFlags::Parse(argc, argv);
+    return test_main();
 }
 #endif
diff --git a/third_party/harfbuzz/.gitignore b/third_party/harfbuzz/.gitignore
deleted file mode 100644
index 572243f..0000000
--- a/third_party/harfbuzz/.gitignore
+++ /dev/null
@@ -1,20 +0,0 @@
-INSTALL
-Makefile.in
-aclocal.m4
-autom4te.cache
-config.guess
-config.h.in
-config.sub
-config.h
-configure
-depcomp
-install-sh
-ltmain.sh
-missing
-Makefile
-config.status
-config.log
-libtool
-stamp-h1
-compile
-build
diff --git a/third_party/harfbuzz/AUTHORS b/third_party/harfbuzz/AUTHORS
deleted file mode 100644
index 023488a..0000000
--- a/third_party/harfbuzz/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-David Turner
-Werner Lemberg
-Owen Taylor
-Behdad Esfahbod
-Lars Knoll
-Simon Hausmann
diff --git a/third_party/harfbuzz/COPYING b/third_party/harfbuzz/COPYING
deleted file mode 100644
index 820a9e6..0000000
--- a/third_party/harfbuzz/COPYING
+++ /dev/null
@@ -1,24 +0,0 @@
-HarfBuzz was previously licensed under different licenses.  This was
-changed in January 2008.  If you need to relicense your old copies,
-consult the announcement of the license change on the internet.
-Other than that, each copy of HarfBuzz is licensed under the COPYING
-file included with it.  The actual license follows:
-
-
-Permission is hereby granted, without written agreement and without
-license or royalty fees, to use, copy, modify, and distribute this
-software and its documentation for any purpose, provided that the
-above copyright notice and the following two paragraphs appear in
-all copies of this software.
-
-IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
-DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
-IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
-
-THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
-ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
-PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
diff --git a/third_party/harfbuzz/Makefile.am b/third_party/harfbuzz/Makefile.am
deleted file mode 100644
index 776b947..0000000
--- a/third_party/harfbuzz/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-
-SUBDIRS = src tests
diff --git a/third_party/harfbuzz/NEWS b/third_party/harfbuzz/NEWS
deleted file mode 100644
index e69de29..0000000
--- a/third_party/harfbuzz/NEWS
+++ /dev/null
diff --git a/third_party/harfbuzz/README b/third_party/harfbuzz/README
deleted file mode 100644
index ca2546a..0000000
--- a/third_party/harfbuzz/README
+++ /dev/null
@@ -1,7 +0,0 @@
-This is HarfBuzz, an OpenType Layout engine library.
-
-To report bugs or post to discussion mailing list, see:
-
-	http://freedesktop.org/wiki/Software/HarfBuzz
-
-For license information, see the file COPYING. 
diff --git a/third_party/harfbuzz/README.google b/third_party/harfbuzz/README.google
deleted file mode 100644
index 74eeb2e..0000000
--- a/third_party/harfbuzz/README.google
+++ /dev/null
@@ -1,9 +0,0 @@
-Harfbuzz
-
-http://freedesktop.org/wiki/Software/HarfBuzz
-
-This code was taken from b0d396aa88b3cdf8cea896bfeeba197656e1cdb1
-(git://anongit.freedesktop.org/harfbuzz)
-
-The patch in chromium.patch was applied on top of this; I will talk with
-upstream about it.
diff --git a/third_party/harfbuzz/autogen.sh b/third_party/harfbuzz/autogen.sh
deleted file mode 100755
index 7fa1c3d..0000000
--- a/third_party/harfbuzz/autogen.sh
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/bin/sh
-# Run this to generate all the initial makefiles, etc.
-
-set -e
-
-srcdir=`dirname $0`
-test -z "$srcdir" && srcdir=.
-
-ORIGDIR=`pwd`
-cd $srcdir
-PROJECT=harfbuzz
-TEST_TYPE=-f
-FILE=src/harfbuzz.h
-ACLOCAL=${ACLOCAL-aclocal}
-LIBTOOLIZE=${LIBTOOLIZE-libtoolize}
-AUTOMAKE=${AUTOMAKE-automake}
-AUTOHEADER=${AUTOHEADER-autoheader}
-AUTOCONF=${AUTOCONF-autoconf}
-LIBTOOLIZE_FLAGS="--copy --force"
-
-DIE=0
-
-have_libtool=false
-if $LIBTOOLIZE --version < /dev/null > /dev/null 2>&1 ; then
-	libtool_version=`$LIBTOOLIZE --version | sed 's/^[^0-9]*\([0-9].[0-9.]*\).*/\1/'`
-	case $libtool_version in
-	    1.4*|1.5*|1.6*|1.7*|2*)
-		have_libtool=true
-		;;
-	esac
-fi
-if $have_libtool ; then : ; else
-	echo
-	echo "You must have libtool 1.4 installed to compile $PROJECT."
-	echo "Install the appropriate package for your distribution,"
-	echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
-	DIE=1
-fi
-
-($AUTOCONF --version) < /dev/null > /dev/null 2>&1 || {
-	echo
-	echo "You must have autoconf installed to compile $PROJECT."
-	echo "libtool the appropriate package for your distribution,"
-	echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
-	DIE=1
-}
-
-have_automake=false
-need_libtoolize=true
-if $AUTOMAKE --version < /dev/null > /dev/null 2>&1 ; then
-	automake_version=`$AUTOMAKE --version | grep 'automake (GNU automake)' | sed 's/^[^0-9]*\(.*\)/\1/'`
-	case $automake_version in
-	   1.2*|1.3*|1.4) 
-		;;
-	   1.4*)
-	   	have_automake=true
-	        need_libtoolize=false
-		;;
-	   *)
-		have_automake=true
-		;;
-	esac
-fi
-if $have_automake ; then : ; else
-	echo
-	echo "You must have automake 1.4-p1 installed to compile $PROJECT."
-	echo "Get ftp://ftp.gnu.org/pub/gnu/automake/automake-1.4-p1.tar.gz"
-	echo "(or a newer version if it is available)"
-	DIE=1
-fi
-
-if test "$DIE" -eq 1; then
-	exit 1
-fi
-
-test $TEST_TYPE $FILE || {
-	echo "You must run this script in the top-level $PROJECT directory"
-	exit 1
-}
-
-if test -z "$AUTOGEN_SUBDIR_MODE"; then
-        if test -z "$*"; then
-                echo "I am going to run ./configure with no arguments - if you wish "
-                echo "to pass any to it, please specify them on the $0 command line."
-        fi
-fi
-
-echo Running $ACLOCAL $ACLOCAL_FLAGS
-$ACLOCAL $ACLOCAL_FLAGS
-
-# optionally run autoheader
-if $AUTOHEADER --version  < /dev/null > /dev/null 2>&1; then
-	echo Running $AUTOHEADER
-	$AUTOHEADER
-fi
-
-case $need_libtoolize in
-   true)
-   	echo Running $LIBTOOLIZE $LIBTOOLIZE_FLAGS
-   	$LIBTOOLIZE $LIBTOOLIZE_FLAGS
-	;;
-esac
-
-echo Running $AUTOMAKE -a $am_opt
-$AUTOMAKE -a $am_opt
-echo Running $AUTOCONF
-$AUTOCONF
-cd $ORIGDIR
-
-if test -z "$AUTOGEN_SUBDIR_MODE"; then
-	echo Running $srcdir/configure "$@"
-        $srcdir/configure "$@"
-
-        echo 
-        echo "Now type 'make' to compile $PROJECT."
-fi
diff --git a/third_party/harfbuzz/chromium.patch b/third_party/harfbuzz/chromium.patch
deleted file mode 100644
index 0f20dfd..0000000
--- a/third_party/harfbuzz/chromium.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-diff --git a/contrib/harfbuzz-unicode.c b/contrib/harfbuzz-unicode.c
-index 51dd4ea..cb7a85b 100644
---- a/contrib/harfbuzz-unicode.c
-+++ b/contrib/harfbuzz-unicode.c
-@@ -171,7 +171,10 @@ hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output,
-         current_script = script;
-         continue;
-       } else if (script == HB_Script_Inherited) {
--        current_script = script;
-+        // Just assume that whatever follows this combining character is within
-+        // the same script.  This is incorrect if you had language1 + combining
-+        // char + language 2, but that is rare and this code is suspicious
-+        // anyway.
-         continue;
-       } else {
-         *iter = prev_iter;
-diff --git a/src/harfbuzz-shaper.cpp b/src/harfbuzz-shaper.cpp
-index f3ec8e1..2b0dfde 100644
---- a/src/harfbuzz-shaper.cpp
-+++ b/src/harfbuzz-shaper.cpp
-@@ -433,7 +433,7 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item)
- 
-     // ### zeroWidth and justification are missing here!!!!!
- 
--    assert(item->num_glyphs <= length);
-+    assert(length <= item->num_glyphs);
- 
- //     qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs);
-     HB_GlyphAttributes *attributes = item->attributes;
-@@ -451,7 +451,6 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item)
-         }
-         ++glyph_pos;
-     }
--    assert(glyph_pos == item->num_glyphs);
- 
-     // first char in a run is never (treated as) a mark
-     int cStart = 0;
diff --git a/third_party/harfbuzz/config.h b/third_party/harfbuzz/config.h
deleted file mode 100644
index 2e856ee..0000000
--- a/third_party/harfbuzz/config.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* config.h.  Generated from config.h.in by configure.  */
-/* config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "harfbuzz"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "0.1"
diff --git a/third_party/harfbuzz/configure.ac b/third_party/harfbuzz/configure.ac
deleted file mode 100644
index 8519279..0000000
--- a/third_party/harfbuzz/configure.ac
+++ /dev/null
@@ -1,54 +0,0 @@
-AC_INIT(README)
-AM_INIT_AUTOMAKE(harfbuzz, 0.1)
-AC_PROG_CC
-AC_PROG_CXX
-AM_PROG_LIBTOOL
-PKG_PROG_PKG_CONFIG
-AM_CONFIG_HEADER(config.h)
-
-if test "x$ac_compiler_gnu" = xyes; then
-    CFLAGS="$CFLAGS -Wall -W -pedantic -ansi"
-    CXXFLAGS="$CXXFLAGS -Wall -W"
-fi
-
-AC_PATH_PROG(ft_config,freetype-config,no)
-if test "$ft_config" = "no"; then
-    AC_MSG_ERROR([You must have freetype installed; see http://www.freetype.org/])
-fi
-
-FREETYPE_CFLAGS="`$ft_config --cflags`"
-FREETYPE_LIBS="`$ft_config --libs`"
-
-AC_SUBST(FREETYPE_LIBS)
-AC_SUBST(FREETYPE_CFLAGS)
-
-AC_ARG_ENABLE(qt, AS_HELP_STRING([--disable-qt], [Build Qt support (default: auto)]), [QT=$enableval], [QT=auto])
-
-if test "x$QT" = xauto; then
-    PKG_CHECK_MODULES(QT, [QtGui >= 4.3], [QT=yes], [QT=no])
-fi
-if test "x$QT" = xyes; then
-    PKG_CHECK_MODULES(QT_GUI, [QtGui >= 4.3])
-    PKG_CHECK_MODULES(QT_QTEST, [QtTest >= 4.3])
-
-    _PKG_CONFIG(QT_INCDIR, [variable=includedir], [QtGui >= 4.3])
-    QT_GUI_CFLAGS="$QT_GUI_CFLAGS -I$pkg_cv_QT_INCDIR/../Qt"
-
-    AC_SUBST(QT_GUI_CFLAGS)
-    AC_SUBST(QT_GUI_LIBS)
-    AC_SUBST(QT_QTEST_CFLAGS)
-    AC_SUBST(QT_QTEST_LIBS)
-
-    _PKG_CONFIG(QT_MOC, [variable=moc_location], [QtGui >= 4.3])
-    QT_MOC=$pkg_cv_QT_MOC
-    AC_SUBST(QT_MOC)
-fi
-AM_CONDITIONAL(QT, [test "x$QT" = xyes])
-
-AC_OUTPUT([
-Makefile
-src/Makefile
-tests/Makefile
-tests/linebreaking/Makefile
-tests/shaping/Makefile
-])
diff --git a/third_party/harfbuzz/contrib/README b/third_party/harfbuzz/contrib/README
deleted file mode 100644
index 074cc52..0000000
--- a/third_party/harfbuzz/contrib/README
+++ /dev/null
@@ -1,9 +0,0 @@
-Harfbuzz requires several functions to be defined in order to work with the
-platform's Unicode tables etc.
-
-If you are building on top of Qt4 you should look at the code in the tests/
-directory for examples of how to hook up Qt4 functions to Harfbuzz.
-
-Otherwise, this directory contains examples of using downloaded Unicode tables
-and/or glib to host Harfbuzz. You should read the README file in tables/ for how
-to build the header files for some of the Unicode tables.
diff --git a/third_party/harfbuzz/contrib/harfbuzz-freetype.c b/third_party/harfbuzz/contrib/harfbuzz-freetype.c
deleted file mode 100644
index a2962df..0000000
--- a/third_party/harfbuzz/contrib/harfbuzz-freetype.c
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <stdint.h>
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TRUETYPE_TABLES_H
-
-#if 0
-#include <freetype/freetype.h>
-#include <freetype/tttables.h>
-#endif
-
-#include <harfbuzz-shaper.h>
-#include "harfbuzz-unicode.h"
-
-static HB_Bool
-hb_freetype_string_to_glyphs(HB_Font font,
-                             const HB_UChar16 *chars, hb_uint32 len,
-                             HB_Glyph *glyphs, hb_uint32 *numGlyphs,
-                             HB_Bool is_rtl) {
-  FT_Face face = (FT_Face) font->userData;
-  if (len > *numGlyphs)
-    return 0;
-
-  size_t i = 0, j = 0;
-  while (i < len) {
-    const uint32_t cp = utf16_to_code_point(chars, len, &i);
-    glyphs[j++] = FT_Get_Char_Index(face, cp);
-  }
-
-  *numGlyphs = j;
-
-  return 1;
-}
-
-static void
-hb_freetype_advances_get(HB_Font font, const HB_Glyph *glyphs, hb_uint32 len,
-                         HB_Fixed *advances, int flags) {
-  FT_Face face = (FT_Face) font->userData;
-
-  hb_uint32 i;
-  for (i = 0; i < len; ++i) {
-    const FT_Error error = FT_Load_Glyph(face, glyphs[i], FT_LOAD_DEFAULT);
-    if (error) {
-      advances[i] = 0;
-      continue;
-    }
-
-    advances[i] = face->glyph->advance.x;
-  }
-}
-
-static HB_Bool
-hb_freetype_can_render(HB_Font font, const HB_UChar16 *chars, hb_uint32 len) {
-  FT_Face face = (FT_Face)font->userData;
-
-  size_t i = 0;
-  while (i < len) {
-    const uint32_t cp = utf16_to_code_point(chars, len, &i);
-    if (FT_Get_Char_Index(face, cp) == 0)
-      return 0;
-  }
-
-  return 1;
-}
-
-static HB_Error
-hb_freetype_outline_point_get(HB_Font font, HB_Glyph glyph, int flags,
-                              hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos,
-                              hb_uint32 *n_points) {
-  HB_Error error = HB_Err_Ok;
-  FT_Face face = (FT_Face) font->userData;
-
-  int load_flags = (flags & HB_ShaperFlag_UseDesignMetrics) ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT;
-
-  if ((error = (HB_Error) FT_Load_Glyph(face, glyph, load_flags)))
-    return error;
-
-  if (face->glyph->format != ft_glyph_format_outline)
-    return (HB_Error)HB_Err_Invalid_SubTable;
-
-  *n_points = face->glyph->outline.n_points;
-  if (!(*n_points))
-    return HB_Err_Ok;
-
-  if (point > *n_points)
-    return (HB_Error)HB_Err_Invalid_SubTable;
-
-  *xpos = face->glyph->outline.points[point].x;
-  *ypos = face->glyph->outline.points[point].y;
-
-  return HB_Err_Ok;
-}
-
-static void
-hb_freetype_glyph_metrics_get(HB_Font font, HB_Glyph glyph,
-                              HB_GlyphMetrics *metrics) {
-  FT_Face face = (FT_Face) font->userData;
-
-  const FT_Error error = FT_Load_Glyph(face, glyph, FT_LOAD_DEFAULT);
-  if (error) {
-    metrics->x = metrics->y = metrics->width = metrics->height = 0;
-    metrics->xOffset = metrics->yOffset = 0;
-    return;
-  }
-
-  const FT_Glyph_Metrics *ftmetrics = &face->glyph->metrics;
-  metrics->width = ftmetrics->width;
-  metrics->height = ftmetrics->height;
-  metrics->x = ftmetrics->horiAdvance;
-  metrics->y = 0;  // unclear what this is
-  metrics->xOffset = ftmetrics->horiBearingX;
-  metrics->yOffset = ftmetrics->horiBearingY;
-}
-
-static HB_Fixed
-hb_freetype_font_metric_get(HB_Font font, HB_FontMetric metric) {
-  FT_Face face = (FT_Face) font->userData;
-
-  switch (metric) {
-  case HB_FontAscent:
-    // Note that we aren't scanning the VDMX table which we probably would in
-    // an ideal world.
-    return face->ascender;
-  default:
-    return 0;
-  }
-}
-
-const HB_FontClass hb_freetype_class = {
-  hb_freetype_string_to_glyphs,
-  hb_freetype_advances_get,
-  hb_freetype_can_render,
-  hb_freetype_outline_point_get,
-  hb_freetype_glyph_metrics_get,
-  hb_freetype_font_metric_get,
-};
-
-HB_Error
-hb_freetype_table_sfnt_get(void *voidface, const HB_Tag tag, HB_Byte *buffer, HB_UInt *len) {
-  FT_Face face = (FT_Face) voidface;
-  FT_ULong ftlen = *len;
-
-  if (!FT_IS_SFNT(face))
-    return HB_Err_Invalid_Argument;
-
-  const FT_Error error = FT_Load_Sfnt_Table(face, tag, 0, buffer, &ftlen);
-  *len = ftlen;
-  return (HB_Error) error;
-}
diff --git a/third_party/harfbuzz/contrib/harfbuzz-freetype.h b/third_party/harfbuzz/contrib/harfbuzz-freetype.h
deleted file mode 100644
index 628be16..0000000
--- a/third_party/harfbuzz/contrib/harfbuzz-freetype.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef HB_FREETYPE_H_
-#define HB_FREETYPE_H_
-
-extern const HB_FontClass hb_freetype_class;
-
-HB_Error hb_freetype_table_sfnt_get(void *voidface, const HB_Tag tag,
-                                    HB_Byte *buffer, HB_UInt *len);
-
-#endif  // HB_FREETYPE_H_
diff --git a/third_party/harfbuzz/contrib/harfbuzz-unicode-glib.c b/third_party/harfbuzz/contrib/harfbuzz-unicode-glib.c
deleted file mode 100644
index 6a13433..0000000
--- a/third_party/harfbuzz/contrib/harfbuzz-unicode-glib.c
+++ /dev/null
@@ -1,169 +0,0 @@
-#include "harfbuzz-external.h"
-
-#include <glib.h>
-
-static int
-hb_category_for_char(HB_UChar32 ch) {
-  switch (g_unichar_type(ch)) {
-    case G_UNICODE_CONTROL:
-      return HB_Other_Control;
-    case G_UNICODE_FORMAT:
-      return HB_Other_Format;
-    case G_UNICODE_UNASSIGNED:
-      return HB_Other_NotAssigned;
-    case G_UNICODE_PRIVATE_USE:
-      return HB_Other_PrivateUse;
-    case G_UNICODE_SURROGATE:
-      return HB_Other_Surrogate;
-    case G_UNICODE_LOWERCASE_LETTER:
-      return HB_Letter_Lowercase;
-    case G_UNICODE_MODIFIER_LETTER:
-      return HB_Letter_Modifier;
-    case G_UNICODE_OTHER_LETTER:
-      return HB_Letter_Other;
-    case G_UNICODE_TITLECASE_LETTER:
-      return HB_Letter_Titlecase;
-    case G_UNICODE_UPPERCASE_LETTER:
-      return HB_Letter_Uppercase;
-    case G_UNICODE_COMBINING_MARK:
-      return HB_Mark_SpacingCombining;
-    case G_UNICODE_ENCLOSING_MARK:
-      return HB_Mark_Enclosing;
-    case G_UNICODE_NON_SPACING_MARK:
-      return HB_Mark_NonSpacing;
-    case G_UNICODE_DECIMAL_NUMBER:
-      return HB_Number_DecimalDigit;
-    case G_UNICODE_LETTER_NUMBER:
-      return HB_Number_Letter;
-    case G_UNICODE_OTHER_NUMBER:
-      return HB_Number_Other;
-    case G_UNICODE_CONNECT_PUNCTUATION:
-      return HB_Punctuation_Connector;
-    case G_UNICODE_DASH_PUNCTUATION:
-      return HB_Punctuation_Dash;
-    case G_UNICODE_CLOSE_PUNCTUATION:
-      return HB_Punctuation_Close;
-    case G_UNICODE_FINAL_PUNCTUATION:
-      return HB_Punctuation_FinalQuote;
-    case G_UNICODE_INITIAL_PUNCTUATION:
-      return HB_Punctuation_InitialQuote;
-    case G_UNICODE_OTHER_PUNCTUATION:
-      return HB_Punctuation_Other;
-    case G_UNICODE_OPEN_PUNCTUATION:
-      return HB_Punctuation_Open;
-    case G_UNICODE_CURRENCY_SYMBOL:
-      return HB_Symbol_Currency;
-    case G_UNICODE_MODIFIER_SYMBOL:
-      return HB_Symbol_Modifier;
-    case G_UNICODE_MATH_SYMBOL:
-      return HB_Symbol_Math;
-    case G_UNICODE_OTHER_SYMBOL:
-      return HB_Symbol_Other;
-    case G_UNICODE_LINE_SEPARATOR:
-      return HB_Separator_Line;
-    case G_UNICODE_PARAGRAPH_SEPARATOR:
-      return HB_Separator_Paragraph;
-    case G_UNICODE_SPACE_SEPARATOR:
-      return HB_Separator_Space;
-    default:
-      return HB_Symbol_Other;
-  }
-}
-
-HB_LineBreakClass
-HB_GetLineBreakClass(HB_UChar32 ch) {
-  switch (g_unichar_break_type(ch)) {
-    case G_UNICODE_BREAK_MANDATORY:
-      return HB_LineBreak_BK;
-    case G_UNICODE_BREAK_CARRIAGE_RETURN:
-      return HB_LineBreak_CR;
-    case G_UNICODE_BREAK_LINE_FEED:
-      return HB_LineBreak_LF;
-    case G_UNICODE_BREAK_COMBINING_MARK:
-      return HB_LineBreak_CM;
-    case G_UNICODE_BREAK_SURROGATE:
-      return HB_LineBreak_SG;
-    case G_UNICODE_BREAK_ZERO_WIDTH_SPACE:
-      return HB_LineBreak_ZW;
-    case G_UNICODE_BREAK_INSEPARABLE:
-      return HB_LineBreak_IN;
-    case G_UNICODE_BREAK_NON_BREAKING_GLUE:
-      return HB_LineBreak_GL;
-    case G_UNICODE_BREAK_CONTINGENT:
-      return HB_LineBreak_AL;
-    case G_UNICODE_BREAK_SPACE:
-      return HB_LineBreak_SP;
-    case G_UNICODE_BREAK_AFTER:
-      return HB_LineBreak_BA;
-    case G_UNICODE_BREAK_BEFORE:
-      return HB_LineBreak_BB;
-    case G_UNICODE_BREAK_BEFORE_AND_AFTER:
-      return HB_LineBreak_B2;
-    case G_UNICODE_BREAK_HYPHEN:
-      return HB_LineBreak_HY;
-    case G_UNICODE_BREAK_NON_STARTER:
-      return HB_LineBreak_NS;
-    case G_UNICODE_BREAK_OPEN_PUNCTUATION:
-      return HB_LineBreak_OP;
-    case G_UNICODE_BREAK_CLOSE_PUNCTUATION:
-      return HB_LineBreak_CL;
-    case G_UNICODE_BREAK_QUOTATION:
-      return HB_LineBreak_QU;
-    case G_UNICODE_BREAK_EXCLAMATION:
-      return HB_LineBreak_EX;
-    case G_UNICODE_BREAK_IDEOGRAPHIC:
-      return HB_LineBreak_ID;
-    case G_UNICODE_BREAK_NUMERIC:
-      return HB_LineBreak_NU;
-    case G_UNICODE_BREAK_INFIX_SEPARATOR:
-      return HB_LineBreak_IS;
-    case G_UNICODE_BREAK_SYMBOL:
-      return HB_LineBreak_SY;
-    case G_UNICODE_BREAK_ALPHABETIC:
-      return HB_LineBreak_AL;
-    case G_UNICODE_BREAK_PREFIX:
-      return HB_LineBreak_PR;
-    case G_UNICODE_BREAK_POSTFIX:
-      return HB_LineBreak_PO;
-    case G_UNICODE_BREAK_COMPLEX_CONTEXT:
-      return HB_LineBreak_SA;
-    case G_UNICODE_BREAK_AMBIGUOUS:
-      return HB_LineBreak_AL;
-    case G_UNICODE_BREAK_UNKNOWN:
-      return HB_LineBreak_AL;
-    case G_UNICODE_BREAK_NEXT_LINE:
-      return HB_LineBreak_AL;
-    case G_UNICODE_BREAK_WORD_JOINER:
-      return HB_LineBreak_WJ;
-    case G_UNICODE_BREAK_HANGUL_L_JAMO:
-      return HB_LineBreak_JL;
-    case G_UNICODE_BREAK_HANGUL_V_JAMO:
-      return HB_LineBreak_JV;
-    case G_UNICODE_BREAK_HANGUL_T_JAMO:
-      return HB_LineBreak_JT;
-    case G_UNICODE_BREAK_HANGUL_LV_SYLLABLE:
-      return HB_LineBreak_H2;
-    case G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE:
-      return HB_LineBreak_H3;
-    default:
-      return HB_LineBreak_AL;
-  }
-}
-
-int
-HB_GetUnicodeCharCombiningClass(HB_UChar32 ch) {
-  return g_unichar_combining_class(ch);
-}
-
-void
-HB_GetUnicodeCharProperties(HB_UChar32 ch,
-                            HB_CharCategory *category,
-                            int *combiningClass) {
-  *category = hb_category_for_char(ch);
-  *combiningClass = g_unichar_combining_class(ch);
-}
-
-HB_CharCategory
-HB_GetUnicodeCharCategory(HB_UChar32 ch) {
-  return hb_category_for_char(ch);
-}
diff --git a/third_party/harfbuzz/contrib/harfbuzz-unicode-tables.c b/third_party/harfbuzz/contrib/harfbuzz-unicode-tables.c
deleted file mode 100644
index 3c3fead..0000000
--- a/third_party/harfbuzz/contrib/harfbuzz-unicode-tables.c
+++ /dev/null
@@ -1,84 +0,0 @@
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <harfbuzz-external.h>
-
-#include "tables/category-properties.h"
-#include "tables/combining-properties.h"
-
-HB_LineBreakClass
-HB_GetLineBreakClass(HB_UChar32 ch) {
-  abort();
-  return 0;
-}
-
-static int
-combining_property_cmp(const void *vkey, const void *vcandidate) {
-  const uint32_t key = (uint32_t) (intptr_t) vkey;
-  const struct combining_property *candidate = vcandidate;
-
-  if (key < candidate->range_start) {
-    return -1;
-  } else if (key > candidate->range_end) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-static int
-code_point_to_combining_class(HB_UChar32 cp) {
-  const void *vprop = bsearch((void *) (intptr_t) cp, combining_properties,
-                              combining_properties_count,
-                              sizeof(struct combining_property),
-                              combining_property_cmp);
-  if (!vprop)
-    return 0;
-
-  return ((const struct combining_property *) vprop)->klass;
-}
-
-int
-HB_GetUnicodeCharCombiningClass(HB_UChar32 ch) {
-  return code_point_to_combining_class(ch);
-  return 0;
-}
-
-static int
-category_property_cmp(const void *vkey, const void *vcandidate) {
-  const uint32_t key = (uint32_t) (intptr_t) vkey;
-  const struct category_property *candidate = vcandidate;
-
-  if (key < candidate->range_start) {
-    return -1;
-  } else if (key > candidate->range_end) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-static HB_CharCategory
-code_point_to_category(HB_UChar32 cp) {
-  const void *vprop = bsearch((void *) (intptr_t) cp, category_properties,
-                              category_properties_count,
-                              sizeof(struct category_property),
-                              category_property_cmp);
-  if (!vprop)
-    return HB_NoCategory;
-
-  return ((const struct category_property *) vprop)->category;
-}
-
-void
-HB_GetUnicodeCharProperties(HB_UChar32 ch,
-                            HB_CharCategory *category,
-                            int *combiningClass) {
-  *category = code_point_to_category(ch);
-  *combiningClass = code_point_to_combining_class(ch);
-}
-
-HB_CharCategory
-HB_GetUnicodeCharCategory(HB_UChar32 ch) {
-  return code_point_to_category(ch);
-}
diff --git a/third_party/harfbuzz/contrib/harfbuzz-unicode.c b/third_party/harfbuzz/contrib/harfbuzz-unicode.c
deleted file mode 100644
index f2185dc..0000000
--- a/third_party/harfbuzz/contrib/harfbuzz-unicode.c
+++ /dev/null
@@ -1,287 +0,0 @@
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <harfbuzz-external.h>
-#include <harfbuzz-impl.h>
-#include <harfbuzz-shaper.h>
-#include "harfbuzz-unicode.h"
-
-#include "tables/grapheme-break-properties.h"
-#include "tables/mirroring-properties.h"
-#include "tables/script-properties.h"
-
-uint32_t
-utf16_to_code_point(const uint16_t *chars, size_t len, ssize_t *iter) {
-  const uint16_t v = chars[(*iter)++];
-  if (HB_IsHighSurrogate(v)) {
-    // surrogate pair
-    if (*iter >= len) {
-      // the surrogate is incomplete.
-      return HB_InvalidCodePoint;
-    }
-    const uint16_t v2 = chars[(*iter)++];
-    if (!HB_IsLowSurrogate(v2)) {
-      // invalidate surrogate pair.
-      return HB_InvalidCodePoint;
-    }
-
-    return HB_SurrogateToUcs4(v, v2);
-  }
-
-  if (HB_IsLowSurrogate(v)) {
-    // this isn't a valid code point
-    return HB_InvalidCodePoint;
-  }
-
-  return v;
-}
-
-uint32_t
-utf16_to_code_point_prev(const uint16_t *chars, size_t len, ssize_t *iter) {
-  const uint16_t v = chars[(*iter)--];
-  if (HB_IsLowSurrogate(v)) {
-    // surrogate pair
-    if (*iter < 0) {
-      // the surrogate is incomplete.
-      return HB_InvalidCodePoint;
-    }
-    const uint16_t v2 = chars[(*iter)--];
-    if (!HB_IsHighSurrogate(v2)) {
-      // invalidate surrogate pair.
-      return HB_InvalidCodePoint;
-    }
-
-    return HB_SurrogateToUcs4(v2, v);
-  }
-
-  if (HB_IsHighSurrogate(v)) {
-    // this isn't a valid code point
-    return HB_InvalidCodePoint;
-  }
-
-  return v;
-}
-
-static int
-script_property_cmp(const void *vkey, const void *vcandidate) {
-  const uint32_t key = (uint32_t) (intptr_t) vkey;
-  const struct script_property *candidate = vcandidate;
-
-  if (key < candidate->range_start) {
-    return -1;
-  } else if (key > candidate->range_end) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-HB_Script
-code_point_to_script(uint32_t cp) {
-  const void *vprop = bsearch((void *) (intptr_t) cp, script_properties,
-                              script_properties_count,
-                              sizeof(struct script_property),
-                              script_property_cmp);
-  if (!vprop)
-    return HB_Script_Common;
-
-  return ((const struct script_property *) vprop)->script;
-}
-
-char
-hb_utf16_script_run_next(unsigned *num_code_points, HB_ScriptItem *output,
-                         const uint16_t *chars, size_t len, ssize_t *iter) {
-  if (*iter == len)
-    return 0;
-
-  output->pos = *iter;
-  const uint32_t init_cp = utf16_to_code_point(chars, len, iter);
-  unsigned cps = 1;
-  if (init_cp == HB_InvalidCodePoint)
-    return 0;
-  const HB_Script init_script = code_point_to_script(init_cp);
-  HB_Script current_script = init_script;
-  output->script = init_script;
-
-  for (;;) {
-    if (*iter == len)
-      break;
-    const ssize_t prev_iter = *iter;
-    const uint32_t cp = utf16_to_code_point(chars, len, iter);
-    if (cp == HB_InvalidCodePoint)
-      return 0;
-    cps++;
-    const HB_Script script = code_point_to_script(cp);
-
-    if (script != current_script) {
-      if (current_script == init_script == HB_Script_Inherited) {
-        // If we started off as inherited, we take whatever we can find.
-        output->script = script;
-        current_script = script;
-        continue;
-      } else if (script == HB_Script_Inherited) {
-        continue;
-      } else {
-        *iter = prev_iter;
-        cps--;
-        break;
-      }
-    }
-  }
-
-  if (output->script == HB_Script_Inherited)
-    output->script = HB_Script_Common;
-
-  output->length = *iter - output->pos;
-  if (num_code_points)
-    *num_code_points = cps;
-  return 1;
-}
-
-char
-hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output,
-                         const uint16_t *chars, size_t len, ssize_t *iter) {
-  if (*iter == (size_t) -1)
-    return 0;
-
-  const size_t ending_index = *iter;
-  const uint32_t init_cp = utf16_to_code_point_prev(chars, len, iter);
-  unsigned cps = 1;
-  if (init_cp == HB_InvalidCodePoint)
-    return 0;
-  const HB_Script init_script = code_point_to_script(init_cp);
-  HB_Script current_script = init_script;
-  output->script = init_script;
-
-  for (;;) {
-    if (*iter < 0)
-      break;
-    const ssize_t prev_iter = *iter;
-    const uint32_t cp = utf16_to_code_point_prev(chars, len, iter);
-    if (cp == HB_InvalidCodePoint)
-      return 0;
-    cps++;
-    const HB_Script script = code_point_to_script(cp);
-
-    if (script != current_script) {
-      if (current_script == init_script == HB_Script_Inherited) {
-        // If we started off as inherited, we take whatever we can find.
-        output->script = script;
-        current_script = script;
-        continue;
-      } else if (script == HB_Script_Inherited) {
-        // Just assume that whatever follows this combining character is within
-        // the same script.  This is incorrect if you had language1 + combining
-        // char + language 2, but that is rare and this code is suspicious
-        // anyway.
-        continue;
-      } else {
-        *iter = prev_iter;
-        cps--;
-        break;
-      }
-    }
-  }
-
-  if (output->script == HB_Script_Inherited)
-    output->script = HB_Script_Common;
-
-  output->pos = *iter + 1;
-  output->length = ending_index - *iter;
-  if (num_code_points)
-    *num_code_points = cps;
-  return 1;
-}
-
-static int
-grapheme_break_property_cmp(const void *vkey, const void *vcandidate) {
-  const uint32_t key = (uint32_t) (intptr_t) vkey;
-  const struct grapheme_break_property *candidate = vcandidate;
-
-  if (key < candidate->range_start) {
-    return -1;
-  } else if (key > candidate->range_end) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-HB_GraphemeClass
-HB_GetGraphemeClass(HB_UChar32 ch) {
-  const void *vprop = bsearch((void *) (intptr_t) ch, grapheme_break_properties,
-                              grapheme_break_properties_count,
-                              sizeof(struct grapheme_break_property),
-                              grapheme_break_property_cmp);
-  if (!vprop)
-    return HB_Grapheme_Other;
-
-  return ((const struct grapheme_break_property *) vprop)->klass;
-}
-
-HB_WordClass
-HB_GetWordClass(HB_UChar32 ch) {
-  abort();
-  return 0;
-}
-
-HB_SentenceClass
-HB_GetSentenceClass(HB_UChar32 ch) {
-  abort();
-  return 0;
-}
-
-void
-HB_GetGraphemeAndLineBreakClass(HB_UChar32 ch, HB_GraphemeClass *gclass, HB_LineBreakClass *breakclass) {
-  *gclass = HB_GetGraphemeClass(ch);
-  *breakclass = HB_GetLineBreakClass(ch);
-}
-
-static int
-mirroring_property_cmp(const void *vkey, const void *vcandidate) {
-  const uint32_t key = (uint32_t) (intptr_t) vkey;
-  const struct mirroring_property *candidate = vcandidate;
-
-  if (key < candidate->a) {
-    return -1;
-  } else if (key > candidate->a) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-HB_UChar16
-HB_GetMirroredChar(HB_UChar16 ch) {
-  const void *mprop = bsearch((void *) (intptr_t) ch, mirroring_properties,
-                              mirroring_properties_count,
-                              sizeof(struct mirroring_property),
-                              mirroring_property_cmp);
-  if (!mprop)
-    return ch;
-
-  return ((const struct mirroring_property *) mprop)->b;
-}
-
-void *
-HB_Library_Resolve(const char *library, const char *symbol) {
-  abort();
-  return NULL;
-}
-
-void *
-HB_TextCodecForMib(int mib) {
-  abort();
-  return NULL;
-}
-
-char *
-HB_TextCodec_ConvertFromUnicode(void *codec, const HB_UChar16 *unicode, hb_uint32 length, hb_uint32 *outputLength) {
-  abort();
-  return NULL;
-}
-
-void
-HB_TextCodec_FreeResult(char *v) {
-  abort();
-}
diff --git a/third_party/harfbuzz/contrib/harfbuzz-unicode.h b/third_party/harfbuzz/contrib/harfbuzz-unicode.h
deleted file mode 100644
index f28b3c3..0000000
--- a/third_party/harfbuzz/contrib/harfbuzz-unicode.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef SCRIPT_IDENTIFY_H_
-#define SCRIPT_IDENTIFY_H_
-
-#include <stdint.h>
-
-#include <harfbuzz-shaper.h>
-
-static const uint32_t HB_InvalidCodePoint = 0xffffffffu;
-
-// -----------------------------------------------------------------------------
-// Return the next Unicode code point from a UTF-16 vector
-//   chars: a pointer to @len words
-//   iter: (input/output) an index into @chars. This is updated.
-//   returns: HB_InvalidCodePoint on error and the code point otherwise.
-// -----------------------------------------------------------------------------
-uint32_t utf16_to_code_point(const uint16_t *chars, size_t len, ssize_t *iter);
-
-// -----------------------------------------------------------------------------
-// Like the above, except that the code points are traversed backwards. Thus,
-// on the first call, |iter| should be |len| - 1.
-// -----------------------------------------------------------------------------
-uint32_t utf16_to_code_point(const uint16_t *chars, size_t len, ssize_t *iter);
-
-// -----------------------------------------------------------------------------
-// Return the script of the given code point
-// -----------------------------------------------------------------------------
-HB_Script code_point_to_script(uint32_t cp);
-
-// -----------------------------------------------------------------------------
-// Find the next script run in a UTF-16 string.
-//
-// A script run is a subvector of codepoints, all of which are in the same
-// script. A run will never cut a surrogate pair in half at either end.
-//
-// num_code_points: (output, maybe NULL) the number of code points in the run
-// output: (output) the @pos, @length and @script fields are set on success
-// chars: the UTF-16 string
-// len: the length of @chars, in words
-// iter: (in/out) the current index into the string. This should be 0 for the
-//   first call and is updated on exit.
-//
-// returns: non-zero if a script run was found and returned.
-// -----------------------------------------------------------------------------
-char hb_utf16_script_run_next(unsigned *num_code_points, HB_ScriptItem *output,
-                              const uint16_t *chars, size_t len, ssize_t *iter);
-
-// -----------------------------------------------------------------------------
-// This is the same as above, except that the input is traversed backwards.
-// Thus, on the first call, |iter| should be |len| - 1.
-// -----------------------------------------------------------------------------
-char hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output,
-                              const uint16_t *chars, size_t len, ssize_t *iter);
-
-#endif
diff --git a/third_party/harfbuzz/contrib/tables/BidiMirroring.txt b/third_party/harfbuzz/contrib/tables/BidiMirroring.txt
deleted file mode 100644
index 64d29e4..0000000
--- a/third_party/harfbuzz/contrib/tables/BidiMirroring.txt
+++ /dev/null
@@ -1,588 +0,0 @@
-# BidiMirroring-5.1.0.txt
-# Date: 2008-03-28, 10:22:00 PDT [KW]
-#
-# Bidi_Mirroring_Glyph Property
-# 
-# This file is an informative contributory data file in the
-# Unicode Character Database.
-#
-# Copyright (c) 1991-2008 Unicode, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-#
-# This data file lists characters that have the mirrored property
-# where there is another Unicode character that typically has a glyph
-# that is the mirror image of the original character's glyph.
-# The repertoire covered by the file is Unicode 5.1.0.
-# 
-# The file contains a list of lines with mappings from one code point
-# to another one for character-based mirroring.
-# Note that for "real" mirroring, a rendering engine needs to select
-# appropriate alternative glyphs, and that many Unicode characters do not
-# have a mirror-image Unicode character.
-# 
-# Each mapping line contains two fields, separated by a semicolon (';').
-# Each of the two fields contains a code point represented as a
-# variable-length hexadecimal value with 4 to 6 digits.
-# A comment indicates where the characters are "BEST FIT" mirroring.
-# 
-# Code points with the "mirrored" property but no appropriate mirrors are
-# listed as comments at the end of the file.
-# 
-# For information on bidi mirroring, see UAX #9: Bidirectional Algorithm,
-# at http://www.unicode.org/unicode/reports/tr9/
-# 
-# This file was originally created by Markus Scherer.
-# Extended for Unicode 3.2, 4.0, 4.1, 5.0, and 5.1 by Ken Whistler.
-# 
-# ############################################################
-
-0028; 0029 # LEFT PARENTHESIS
-0029; 0028 # RIGHT PARENTHESIS
-003C; 003E # LESS-THAN SIGN
-003E; 003C # GREATER-THAN SIGN
-005B; 005D # LEFT SQUARE BRACKET
-005D; 005B # RIGHT SQUARE BRACKET
-007B; 007D # LEFT CURLY BRACKET
-007D; 007B # RIGHT CURLY BRACKET
-00AB; 00BB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
-00BB; 00AB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-0F3A; 0F3B # TIBETAN MARK GUG RTAGS GYON
-0F3B; 0F3A # TIBETAN MARK GUG RTAGS GYAS
-0F3C; 0F3D # TIBETAN MARK ANG KHANG GYON
-0F3D; 0F3C # TIBETAN MARK ANG KHANG GYAS
-169B; 169C # OGHAM FEATHER MARK
-169C; 169B # OGHAM REVERSED FEATHER MARK
-2039; 203A # SINGLE LEFT-POINTING ANGLE QUOTATION MARK
-203A; 2039 # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
-2045; 2046 # LEFT SQUARE BRACKET WITH QUILL
-2046; 2045 # RIGHT SQUARE BRACKET WITH QUILL
-207D; 207E # SUPERSCRIPT LEFT PARENTHESIS
-207E; 207D # SUPERSCRIPT RIGHT PARENTHESIS
-208D; 208E # SUBSCRIPT LEFT PARENTHESIS
-208E; 208D # SUBSCRIPT RIGHT PARENTHESIS
-2208; 220B # ELEMENT OF
-2209; 220C # NOT AN ELEMENT OF
-220A; 220D # SMALL ELEMENT OF
-220B; 2208 # CONTAINS AS MEMBER
-220C; 2209 # DOES NOT CONTAIN AS MEMBER
-220D; 220A # SMALL CONTAINS AS MEMBER
-2215; 29F5 # DIVISION SLASH
-223C; 223D # TILDE OPERATOR
-223D; 223C # REVERSED TILDE
-2243; 22CD # ASYMPTOTICALLY EQUAL TO
-2252; 2253 # APPROXIMATELY EQUAL TO OR THE IMAGE OF
-2253; 2252 # IMAGE OF OR APPROXIMATELY EQUAL TO
-2254; 2255 # COLON EQUALS
-2255; 2254 # EQUALS COLON
-2264; 2265 # LESS-THAN OR EQUAL TO
-2265; 2264 # GREATER-THAN OR EQUAL TO
-2266; 2267 # LESS-THAN OVER EQUAL TO
-2267; 2266 # GREATER-THAN OVER EQUAL TO
-2268; 2269 # [BEST FIT] LESS-THAN BUT NOT EQUAL TO
-2269; 2268 # [BEST FIT] GREATER-THAN BUT NOT EQUAL TO
-226A; 226B # MUCH LESS-THAN
-226B; 226A # MUCH GREATER-THAN
-226E; 226F # [BEST FIT] NOT LESS-THAN
-226F; 226E # [BEST FIT] NOT GREATER-THAN
-2270; 2271 # [BEST FIT] NEITHER LESS-THAN NOR EQUAL TO
-2271; 2270 # [BEST FIT] NEITHER GREATER-THAN NOR EQUAL TO
-2272; 2273 # [BEST FIT] LESS-THAN OR EQUIVALENT TO
-2273; 2272 # [BEST FIT] GREATER-THAN OR EQUIVALENT TO
-2274; 2275 # [BEST FIT] NEITHER LESS-THAN NOR EQUIVALENT TO
-2275; 2274 # [BEST FIT] NEITHER GREATER-THAN NOR EQUIVALENT TO
-2276; 2277 # LESS-THAN OR GREATER-THAN
-2277; 2276 # GREATER-THAN OR LESS-THAN
-2278; 2279 # [BEST FIT] NEITHER LESS-THAN NOR GREATER-THAN
-2279; 2278 # [BEST FIT] NEITHER GREATER-THAN NOR LESS-THAN
-227A; 227B # PRECEDES
-227B; 227A # SUCCEEDS
-227C; 227D # PRECEDES OR EQUAL TO
-227D; 227C # SUCCEEDS OR EQUAL TO
-227E; 227F # [BEST FIT] PRECEDES OR EQUIVALENT TO
-227F; 227E # [BEST FIT] SUCCEEDS OR EQUIVALENT TO
-2280; 2281 # [BEST FIT] DOES NOT PRECEDE
-2281; 2280 # [BEST FIT] DOES NOT SUCCEED
-2282; 2283 # SUBSET OF
-2283; 2282 # SUPERSET OF
-2284; 2285 # [BEST FIT] NOT A SUBSET OF
-2285; 2284 # [BEST FIT] NOT A SUPERSET OF
-2286; 2287 # SUBSET OF OR EQUAL TO
-2287; 2286 # SUPERSET OF OR EQUAL TO
-2288; 2289 # [BEST FIT] NEITHER A SUBSET OF NOR EQUAL TO
-2289; 2288 # [BEST FIT] NEITHER A SUPERSET OF NOR EQUAL TO
-228A; 228B # [BEST FIT] SUBSET OF WITH NOT EQUAL TO
-228B; 228A # [BEST FIT] SUPERSET OF WITH NOT EQUAL TO
-228F; 2290 # SQUARE IMAGE OF
-2290; 228F # SQUARE ORIGINAL OF
-2291; 2292 # SQUARE IMAGE OF OR EQUAL TO
-2292; 2291 # SQUARE ORIGINAL OF OR EQUAL TO
-2298; 29B8 # CIRCLED DIVISION SLASH
-22A2; 22A3 # RIGHT TACK
-22A3; 22A2 # LEFT TACK
-22A6; 2ADE # ASSERTION
-22A8; 2AE4 # TRUE
-22A9; 2AE3 # FORCES
-22AB; 2AE5 # DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
-22B0; 22B1 # PRECEDES UNDER RELATION
-22B1; 22B0 # SUCCEEDS UNDER RELATION
-22B2; 22B3 # NORMAL SUBGROUP OF
-22B3; 22B2 # CONTAINS AS NORMAL SUBGROUP
-22B4; 22B5 # NORMAL SUBGROUP OF OR EQUAL TO
-22B5; 22B4 # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO
-22B6; 22B7 # ORIGINAL OF
-22B7; 22B6 # IMAGE OF
-22C9; 22CA # LEFT NORMAL FACTOR SEMIDIRECT PRODUCT
-22CA; 22C9 # RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT
-22CB; 22CC # LEFT SEMIDIRECT PRODUCT
-22CC; 22CB # RIGHT SEMIDIRECT PRODUCT
-22CD; 2243 # REVERSED TILDE EQUALS
-22D0; 22D1 # DOUBLE SUBSET
-22D1; 22D0 # DOUBLE SUPERSET
-22D6; 22D7 # LESS-THAN WITH DOT
-22D7; 22D6 # GREATER-THAN WITH DOT
-22D8; 22D9 # VERY MUCH LESS-THAN
-22D9; 22D8 # VERY MUCH GREATER-THAN
-22DA; 22DB # LESS-THAN EQUAL TO OR GREATER-THAN
-22DB; 22DA # GREATER-THAN EQUAL TO OR LESS-THAN
-22DC; 22DD # EQUAL TO OR LESS-THAN
-22DD; 22DC # EQUAL TO OR GREATER-THAN
-22DE; 22DF # EQUAL TO OR PRECEDES
-22DF; 22DE # EQUAL TO OR SUCCEEDS
-22E0; 22E1 # [BEST FIT] DOES NOT PRECEDE OR EQUAL
-22E1; 22E0 # [BEST FIT] DOES NOT SUCCEED OR EQUAL
-22E2; 22E3 # [BEST FIT] NOT SQUARE IMAGE OF OR EQUAL TO
-22E3; 22E2 # [BEST FIT] NOT SQUARE ORIGINAL OF OR EQUAL TO
-22E4; 22E5 # [BEST FIT] SQUARE IMAGE OF OR NOT EQUAL TO
-22E5; 22E4 # [BEST FIT] SQUARE ORIGINAL OF OR NOT EQUAL TO
-22E6; 22E7 # [BEST FIT] LESS-THAN BUT NOT EQUIVALENT TO
-22E7; 22E6 # [BEST FIT] GREATER-THAN BUT NOT EQUIVALENT TO
-22E8; 22E9 # [BEST FIT] PRECEDES BUT NOT EQUIVALENT TO
-22E9; 22E8 # [BEST FIT] SUCCEEDS BUT NOT EQUIVALENT TO
-22EA; 22EB # [BEST FIT] NOT NORMAL SUBGROUP OF
-22EB; 22EA # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP
-22EC; 22ED # [BEST FIT] NOT NORMAL SUBGROUP OF OR EQUAL TO
-22ED; 22EC # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL
-22F0; 22F1 # UP RIGHT DIAGONAL ELLIPSIS
-22F1; 22F0 # DOWN RIGHT DIAGONAL ELLIPSIS
-22F2; 22FA # ELEMENT OF WITH LONG HORIZONTAL STROKE
-22F3; 22FB # ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
-22F4; 22FC # SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
-22F6; 22FD # ELEMENT OF WITH OVERBAR
-22F7; 22FE # SMALL ELEMENT OF WITH OVERBAR
-22FA; 22F2 # CONTAINS WITH LONG HORIZONTAL STROKE
-22FB; 22F3 # CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
-22FC; 22F4 # SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
-22FD; 22F6 # CONTAINS WITH OVERBAR
-22FE; 22F7 # SMALL CONTAINS WITH OVERBAR
-2308; 2309 # LEFT CEILING
-2309; 2308 # RIGHT CEILING
-230A; 230B # LEFT FLOOR
-230B; 230A # RIGHT FLOOR
-2329; 232A # LEFT-POINTING ANGLE BRACKET
-232A; 2329 # RIGHT-POINTING ANGLE BRACKET
-2768; 2769 # MEDIUM LEFT PARENTHESIS ORNAMENT
-2769; 2768 # MEDIUM RIGHT PARENTHESIS ORNAMENT
-276A; 276B # MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
-276B; 276A # MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
-276C; 276D # MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
-276D; 276C # MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
-276E; 276F # HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
-276F; 276E # HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
-2770; 2771 # HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
-2771; 2770 # HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
-2772; 2773 # LIGHT LEFT TORTOISE SHELL BRACKET
-2773; 2772 # LIGHT RIGHT TORTOISE SHELL BRACKET
-2774; 2775 # MEDIUM LEFT CURLY BRACKET ORNAMENT
-2775; 2774 # MEDIUM RIGHT CURLY BRACKET ORNAMENT
-27C3; 27C4 # OPEN SUBSET
-27C4; 27C3 # OPEN SUPERSET
-27C5; 27C6 # LEFT S-SHAPED BAG DELIMITER
-27C6; 27C5 # RIGHT S-SHAPED BAG DELIMITER
-27C8; 27C9 # REVERSE SOLIDUS PRECEDING SUBSET
-27C9; 27C8 # SUPERSET PRECEDING SOLIDUS
-27D5; 27D6 # LEFT OUTER JOIN
-27D6; 27D5 # RIGHT OUTER JOIN
-27DD; 27DE # LONG RIGHT TACK
-27DE; 27DD # LONG LEFT TACK
-27E2; 27E3 # WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK
-27E3; 27E2 # WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK
-27E4; 27E5 # WHITE SQUARE WITH LEFTWARDS TICK
-27E5; 27E4 # WHITE SQUARE WITH RIGHTWARDS TICK
-27E6; 27E7 # MATHEMATICAL LEFT WHITE SQUARE BRACKET
-27E7; 27E6 # MATHEMATICAL RIGHT WHITE SQUARE BRACKET
-27E8; 27E9 # MATHEMATICAL LEFT ANGLE BRACKET
-27E9; 27E8 # MATHEMATICAL RIGHT ANGLE BRACKET
-27EA; 27EB # MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
-27EB; 27EA # MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
-27EC; 27ED # MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
-27ED; 27EC # MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
-27EE; 27EF # MATHEMATICAL LEFT FLATTENED PARENTHESIS
-27EF; 27EE # MATHEMATICAL RIGHT FLATTENED PARENTHESIS
-2983; 2984 # LEFT WHITE CURLY BRACKET
-2984; 2983 # RIGHT WHITE CURLY BRACKET
-2985; 2986 # LEFT WHITE PARENTHESIS
-2986; 2985 # RIGHT WHITE PARENTHESIS
-2987; 2988 # Z NOTATION LEFT IMAGE BRACKET
-2988; 2987 # Z NOTATION RIGHT IMAGE BRACKET
-2989; 298A # Z NOTATION LEFT BINDING BRACKET
-298A; 2989 # Z NOTATION RIGHT BINDING BRACKET
-298B; 298C # LEFT SQUARE BRACKET WITH UNDERBAR
-298C; 298B # RIGHT SQUARE BRACKET WITH UNDERBAR
-298D; 2990 # LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
-298E; 298F # RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
-298F; 298E # LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
-2990; 298D # RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
-2991; 2992 # LEFT ANGLE BRACKET WITH DOT
-2992; 2991 # RIGHT ANGLE BRACKET WITH DOT
-2993; 2994 # LEFT ARC LESS-THAN BRACKET
-2994; 2993 # RIGHT ARC GREATER-THAN BRACKET
-2995; 2996 # DOUBLE LEFT ARC GREATER-THAN BRACKET
-2996; 2995 # DOUBLE RIGHT ARC LESS-THAN BRACKET
-2997; 2998 # LEFT BLACK TORTOISE SHELL BRACKET
-2998; 2997 # RIGHT BLACK TORTOISE SHELL BRACKET
-29B8; 2298 # CIRCLED REVERSE SOLIDUS
-29C0; 29C1 # CIRCLED LESS-THAN
-29C1; 29C0 # CIRCLED GREATER-THAN
-29C4; 29C5 # SQUARED RISING DIAGONAL SLASH
-29C5; 29C4 # SQUARED FALLING DIAGONAL SLASH
-29CF; 29D0 # LEFT TRIANGLE BESIDE VERTICAL BAR
-29D0; 29CF # VERTICAL BAR BESIDE RIGHT TRIANGLE
-29D1; 29D2 # BOWTIE WITH LEFT HALF BLACK
-29D2; 29D1 # BOWTIE WITH RIGHT HALF BLACK
-29D4; 29D5 # TIMES WITH LEFT HALF BLACK
-29D5; 29D4 # TIMES WITH RIGHT HALF BLACK
-29D8; 29D9 # LEFT WIGGLY FENCE
-29D9; 29D8 # RIGHT WIGGLY FENCE
-29DA; 29DB # LEFT DOUBLE WIGGLY FENCE
-29DB; 29DA # RIGHT DOUBLE WIGGLY FENCE
-29F5; 2215 # REVERSE SOLIDUS OPERATOR
-29F8; 29F9 # BIG SOLIDUS
-29F9; 29F8 # BIG REVERSE SOLIDUS
-29FC; 29FD # LEFT-POINTING CURVED ANGLE BRACKET
-29FD; 29FC # RIGHT-POINTING CURVED ANGLE BRACKET
-2A2B; 2A2C # MINUS SIGN WITH FALLING DOTS
-2A2C; 2A2B # MINUS SIGN WITH RISING DOTS
-2A2D; 2A2E # PLUS SIGN IN LEFT HALF CIRCLE
-2A2E; 2A2D # PLUS SIGN IN RIGHT HALF CIRCLE
-2A34; 2A35 # MULTIPLICATION SIGN IN LEFT HALF CIRCLE
-2A35; 2A34 # MULTIPLICATION SIGN IN RIGHT HALF CIRCLE
-2A3C; 2A3D # INTERIOR PRODUCT
-2A3D; 2A3C # RIGHTHAND INTERIOR PRODUCT
-2A64; 2A65 # Z NOTATION DOMAIN ANTIRESTRICTION
-2A65; 2A64 # Z NOTATION RANGE ANTIRESTRICTION
-2A79; 2A7A # LESS-THAN WITH CIRCLE INSIDE
-2A7A; 2A79 # GREATER-THAN WITH CIRCLE INSIDE
-2A7D; 2A7E # LESS-THAN OR SLANTED EQUAL TO
-2A7E; 2A7D # GREATER-THAN OR SLANTED EQUAL TO
-2A7F; 2A80 # LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
-2A80; 2A7F # GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
-2A81; 2A82 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
-2A82; 2A81 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
-2A83; 2A84 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT
-2A84; 2A83 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT
-2A8B; 2A8C # LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN
-2A8C; 2A8B # GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN
-2A91; 2A92 # LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL
-2A92; 2A91 # GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL
-2A93; 2A94 # LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL
-2A94; 2A93 # GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL
-2A95; 2A96 # SLANTED EQUAL TO OR LESS-THAN
-2A96; 2A95 # SLANTED EQUAL TO OR GREATER-THAN
-2A97; 2A98 # SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE
-2A98; 2A97 # SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE
-2A99; 2A9A # DOUBLE-LINE EQUAL TO OR LESS-THAN
-2A9A; 2A99 # DOUBLE-LINE EQUAL TO OR GREATER-THAN
-2A9B; 2A9C # DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN
-2A9C; 2A9B # DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN
-2AA1; 2AA2 # DOUBLE NESTED LESS-THAN
-2AA2; 2AA1 # DOUBLE NESTED GREATER-THAN
-2AA6; 2AA7 # LESS-THAN CLOSED BY CURVE
-2AA7; 2AA6 # GREATER-THAN CLOSED BY CURVE
-2AA8; 2AA9 # LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
-2AA9; 2AA8 # GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
-2AAA; 2AAB # SMALLER THAN
-2AAB; 2AAA # LARGER THAN
-2AAC; 2AAD # SMALLER THAN OR EQUAL TO
-2AAD; 2AAC # LARGER THAN OR EQUAL TO
-2AAF; 2AB0 # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN
-2AB0; 2AAF # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN
-2AB3; 2AB4 # PRECEDES ABOVE EQUALS SIGN
-2AB4; 2AB3 # SUCCEEDS ABOVE EQUALS SIGN
-2ABB; 2ABC # DOUBLE PRECEDES
-2ABC; 2ABB # DOUBLE SUCCEEDS
-2ABD; 2ABE # SUBSET WITH DOT
-2ABE; 2ABD # SUPERSET WITH DOT
-2ABF; 2AC0 # SUBSET WITH PLUS SIGN BELOW
-2AC0; 2ABF # SUPERSET WITH PLUS SIGN BELOW
-2AC1; 2AC2 # SUBSET WITH MULTIPLICATION SIGN BELOW
-2AC2; 2AC1 # SUPERSET WITH MULTIPLICATION SIGN BELOW
-2AC3; 2AC4 # SUBSET OF OR EQUAL TO WITH DOT ABOVE
-2AC4; 2AC3 # SUPERSET OF OR EQUAL TO WITH DOT ABOVE
-2AC5; 2AC6 # SUBSET OF ABOVE EQUALS SIGN
-2AC6; 2AC5 # SUPERSET OF ABOVE EQUALS SIGN
-2ACD; 2ACE # SQUARE LEFT OPEN BOX OPERATOR
-2ACE; 2ACD # SQUARE RIGHT OPEN BOX OPERATOR
-2ACF; 2AD0 # CLOSED SUBSET
-2AD0; 2ACF # CLOSED SUPERSET
-2AD1; 2AD2 # CLOSED SUBSET OR EQUAL TO
-2AD2; 2AD1 # CLOSED SUPERSET OR EQUAL TO
-2AD3; 2AD4 # SUBSET ABOVE SUPERSET
-2AD4; 2AD3 # SUPERSET ABOVE SUBSET
-2AD5; 2AD6 # SUBSET ABOVE SUBSET
-2AD6; 2AD5 # SUPERSET ABOVE SUPERSET
-2ADE; 22A6 # SHORT LEFT TACK
-2AE3; 22A9 # DOUBLE VERTICAL BAR LEFT TURNSTILE
-2AE4; 22A8 # VERTICAL BAR DOUBLE LEFT TURNSTILE
-2AE5; 22AB # DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE
-2AEC; 2AED # DOUBLE STROKE NOT SIGN
-2AED; 2AEC # REVERSED DOUBLE STROKE NOT SIGN
-2AF7; 2AF8 # TRIPLE NESTED LESS-THAN
-2AF8; 2AF7 # TRIPLE NESTED GREATER-THAN
-2AF9; 2AFA # DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO
-2AFA; 2AF9 # DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO
-2E02; 2E03 # LEFT SUBSTITUTION BRACKET
-2E03; 2E02 # RIGHT SUBSTITUTION BRACKET
-2E04; 2E05 # LEFT DOTTED SUBSTITUTION BRACKET
-2E05; 2E04 # RIGHT DOTTED SUBSTITUTION BRACKET
-2E09; 2E0A # LEFT TRANSPOSITION BRACKET
-2E0A; 2E09 # RIGHT TRANSPOSITION BRACKET
-2E0C; 2E0D # LEFT RAISED OMISSION BRACKET
-2E0D; 2E0C # RIGHT RAISED OMISSION BRACKET
-2E1C; 2E1D # LEFT LOW PARAPHRASE BRACKET
-2E1D; 2E1C # RIGHT LOW PARAPHRASE BRACKET
-2E20; 2E21 # LEFT VERTICAL BAR WITH QUILL
-2E21; 2E20 # RIGHT VERTICAL BAR WITH QUILL
-2E22; 2E23 # TOP LEFT HALF BRACKET
-2E23; 2E22 # TOP RIGHT HALF BRACKET
-2E24; 2E25 # BOTTOM LEFT HALF BRACKET
-2E25; 2E24 # BOTTOM RIGHT HALF BRACKET
-2E26; 2E27 # LEFT SIDEWAYS U BRACKET
-2E27; 2E26 # RIGHT SIDEWAYS U BRACKET
-2E28; 2E29 # LEFT DOUBLE PARENTHESIS
-2E29; 2E28 # RIGHT DOUBLE PARENTHESIS
-3008; 3009 # LEFT ANGLE BRACKET
-3009; 3008 # RIGHT ANGLE BRACKET
-300A; 300B # LEFT DOUBLE ANGLE BRACKET
-300B; 300A # RIGHT DOUBLE ANGLE BRACKET
-300C; 300D # [BEST FIT] LEFT CORNER BRACKET
-300D; 300C # [BEST FIT] RIGHT CORNER BRACKET
-300E; 300F # [BEST FIT] LEFT WHITE CORNER BRACKET
-300F; 300E # [BEST FIT] RIGHT WHITE CORNER BRACKET
-3010; 3011 # LEFT BLACK LENTICULAR BRACKET
-3011; 3010 # RIGHT BLACK LENTICULAR BRACKET
-3014; 3015 # LEFT TORTOISE SHELL BRACKET
-3015; 3014 # RIGHT TORTOISE SHELL BRACKET
-3016; 3017 # LEFT WHITE LENTICULAR BRACKET
-3017; 3016 # RIGHT WHITE LENTICULAR BRACKET
-3018; 3019 # LEFT WHITE TORTOISE SHELL BRACKET
-3019; 3018 # RIGHT WHITE TORTOISE SHELL BRACKET
-301A; 301B # LEFT WHITE SQUARE BRACKET
-301B; 301A # RIGHT WHITE SQUARE BRACKET
-FE59; FE5A # SMALL LEFT PARENTHESIS
-FE5A; FE59 # SMALL RIGHT PARENTHESIS
-FE5B; FE5C # SMALL LEFT CURLY BRACKET
-FE5C; FE5B # SMALL RIGHT CURLY BRACKET
-FE5D; FE5E # SMALL LEFT TORTOISE SHELL BRACKET
-FE5E; FE5D # SMALL RIGHT TORTOISE SHELL BRACKET
-FE64; FE65 # SMALL LESS-THAN SIGN
-FE65; FE64 # SMALL GREATER-THAN SIGN
-FF08; FF09 # FULLWIDTH LEFT PARENTHESIS
-FF09; FF08 # FULLWIDTH RIGHT PARENTHESIS
-FF1C; FF1E # FULLWIDTH LESS-THAN SIGN
-FF1E; FF1C # FULLWIDTH GREATER-THAN SIGN
-FF3B; FF3D # FULLWIDTH LEFT SQUARE BRACKET
-FF3D; FF3B # FULLWIDTH RIGHT SQUARE BRACKET
-FF5B; FF5D # FULLWIDTH LEFT CURLY BRACKET
-FF5D; FF5B # FULLWIDTH RIGHT CURLY BRACKET
-FF5F; FF60 # FULLWIDTH LEFT WHITE PARENTHESIS
-FF60; FF5F # FULLWIDTH RIGHT WHITE PARENTHESIS
-FF62; FF63 # [BEST FIT] HALFWIDTH LEFT CORNER BRACKET
-FF63; FF62 # [BEST FIT] HALFWIDTH RIGHT CORNER BRACKET
-
-# The following characters have no appropriate mirroring character.
-# For these characters it is up to the rendering system
-#   to provide mirrored glyphs.
-
-# 2140; DOUBLE-STRUCK N-ARY SUMMATION
-# 2201; COMPLEMENT
-# 2202; PARTIAL DIFFERENTIAL
-# 2203; THERE EXISTS
-# 2204; THERE DOES NOT EXIST
-# 2211; N-ARY SUMMATION
-# 2216; SET MINUS
-# 221A; SQUARE ROOT
-# 221B; CUBE ROOT
-# 221C; FOURTH ROOT
-# 221D; PROPORTIONAL TO
-# 221F; RIGHT ANGLE
-# 2220; ANGLE
-# 2221; MEASURED ANGLE
-# 2222; SPHERICAL ANGLE
-# 2224; DOES NOT DIVIDE
-# 2226; NOT PARALLEL TO
-# 222B; INTEGRAL
-# 222C; DOUBLE INTEGRAL
-# 222D; TRIPLE INTEGRAL
-# 222E; CONTOUR INTEGRAL
-# 222F; SURFACE INTEGRAL
-# 2230; VOLUME INTEGRAL
-# 2231; CLOCKWISE INTEGRAL
-# 2232; CLOCKWISE CONTOUR INTEGRAL
-# 2233; ANTICLOCKWISE CONTOUR INTEGRAL
-# 2239; EXCESS
-# 223B; HOMOTHETIC
-# 223E; INVERTED LAZY S
-# 223F; SINE WAVE
-# 2240; WREATH PRODUCT
-# 2241; NOT TILDE
-# 2242; MINUS TILDE
-# 2244; NOT ASYMPTOTICALLY EQUAL TO
-# 2245; APPROXIMATELY EQUAL TO
-# 2246; APPROXIMATELY BUT NOT ACTUALLY EQUAL TO
-# 2247; NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
-# 2248; ALMOST EQUAL TO
-# 2249; NOT ALMOST EQUAL TO
-# 224A; ALMOST EQUAL OR EQUAL TO
-# 224B; TRIPLE TILDE
-# 224C; ALL EQUAL TO
-# 225F; QUESTIONED EQUAL TO
-# 2260; NOT EQUAL TO
-# 2262; NOT IDENTICAL TO
-# 228C; MULTISET
-# 22A7; MODELS
-# 22AA; TRIPLE VERTICAL BAR RIGHT TURNSTILE
-# 22AC; DOES NOT PROVE
-# 22AD; NOT TRUE
-# 22AE; DOES NOT FORCE
-# 22AF; NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
-# 22B8; MULTIMAP
-# 22BE; RIGHT ANGLE WITH ARC
-# 22BF; RIGHT TRIANGLE
-# 22F5; ELEMENT OF WITH DOT ABOVE
-# 22F8; ELEMENT OF WITH UNDERBAR
-# 22F9; ELEMENT OF WITH TWO HORIZONTAL STROKES
-# 22FF; Z NOTATION BAG MEMBERSHIP
-# 2320; TOP HALF INTEGRAL
-# 2321; BOTTOM HALF INTEGRAL
-# 27CC; LONG DIVISION
-# 27C0; THREE DIMENSIONAL ANGLE
-# 27D3; LOWER RIGHT CORNER WITH DOT
-# 27D4; UPPER LEFT CORNER WITH DOT
-# 27DC; LEFT MULTIMAP
-# 299B; MEASURED ANGLE OPENING LEFT
-# 299C; RIGHT ANGLE VARIANT WITH SQUARE
-# 299D; MEASURED RIGHT ANGLE WITH DOT
-# 299E; ANGLE WITH S INSIDE
-# 299F; ACUTE ANGLE
-# 29A0; SPHERICAL ANGLE OPENING LEFT
-# 29A1; SPHERICAL ANGLE OPENING UP
-# 29A2; TURNED ANGLE
-# 29A3; REVERSED ANGLE
-# 29A4; ANGLE WITH UNDERBAR
-# 29A5; REVERSED ANGLE WITH UNDERBAR
-# 29A6; OBLIQUE ANGLE OPENING UP
-# 29A7; OBLIQUE ANGLE OPENING DOWN
-# 29A8; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT
-# 29A9; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT
-# 29AA; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT
-# 29AB; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT
-# 29AC; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP
-# 29AD; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP
-# 29AE; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN
-# 29AF; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN
-# 29C2; CIRCLE WITH SMALL CIRCLE TO THE RIGHT
-# 29C3; CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT
-# 29C9; TWO JOINED SQUARES
-# 29CE; RIGHT TRIANGLE ABOVE LEFT TRIANGLE
-# 29DC; INCOMPLETE INFINITY
-# 29E1; INCREASES AS
-# 29E3; EQUALS SIGN AND SLANTED PARALLEL
-# 29E4; EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE
-# 29E5; IDENTICAL TO AND SLANTED PARALLEL
-# 29E8; DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK
-# 29E9; DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK
-# 29F4; RULE-DELAYED
-# 29F6; SOLIDUS WITH OVERBAR
-# 29F7; REVERSE SOLIDUS WITH HORIZONTAL STROKE
-# 2A0A; MODULO TWO SUM
-# 2A0B; SUMMATION WITH INTEGRAL
-# 2A0C; QUADRUPLE INTEGRAL OPERATOR
-# 2A0D; FINITE PART INTEGRAL
-# 2A0E; INTEGRAL WITH DOUBLE STROKE
-# 2A0F; INTEGRAL AVERAGE WITH SLASH
-# 2A10; CIRCULATION FUNCTION
-# 2A11; ANTICLOCKWISE INTEGRATION
-# 2A12; LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE
-# 2A13; LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE
-# 2A14; LINE INTEGRATION NOT INCLUDING THE POLE
-# 2A15; INTEGRAL AROUND A POINT OPERATOR
-# 2A16; QUATERNION INTEGRAL OPERATOR
-# 2A17; INTEGRAL WITH LEFTWARDS ARROW WITH HOOK
-# 2A18; INTEGRAL WITH TIMES SIGN
-# 2A19; INTEGRAL WITH INTERSECTION
-# 2A1A; INTEGRAL WITH UNION
-# 2A1B; INTEGRAL WITH OVERBAR
-# 2A1C; INTEGRAL WITH UNDERBAR
-# 2A1E; LARGE LEFT TRIANGLE OPERATOR
-# 2A1F; Z NOTATION SCHEMA COMPOSITION
-# 2A20; Z NOTATION SCHEMA PIPING
-# 2A21; Z NOTATION SCHEMA PROJECTION
-# 2A24; PLUS SIGN WITH TILDE ABOVE
-# 2A26; PLUS SIGN WITH TILDE BELOW
-# 2A29; MINUS SIGN WITH COMMA ABOVE
-# 2A3E; Z NOTATION RELATIONAL COMPOSITION
-# 2A57; SLOPING LARGE OR
-# 2A58; SLOPING LARGE AND
-# 2A6A; TILDE OPERATOR WITH DOT ABOVE
-# 2A6B; TILDE OPERATOR WITH RISING DOTS
-# 2A6C; SIMILAR MINUS SIMILAR
-# 2A6D; CONGRUENT WITH DOT ABOVE
-# 2A6F; ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT
-# 2A70; APPROXIMATELY EQUAL OR EQUAL TO
-# 2A73; EQUALS SIGN ABOVE TILDE OPERATOR
-# 2A74; DOUBLE COLON EQUAL
-# 2A7B; LESS-THAN WITH QUESTION MARK ABOVE
-# 2A7C; GREATER-THAN WITH QUESTION MARK ABOVE
-# 2A85; LESS-THAN OR APPROXIMATE
-# 2A86; GREATER-THAN OR APPROXIMATE
-# 2A87; LESS-THAN AND SINGLE-LINE NOT EQUAL TO
-# 2A88; GREATER-THAN AND SINGLE-LINE NOT EQUAL TO
-# 2A89; LESS-THAN AND NOT APPROXIMATE
-# 2A8A; GREATER-THAN AND NOT APPROXIMATE
-# 2A8D; LESS-THAN ABOVE SIMILAR OR EQUAL
-# 2A8E; GREATER-THAN ABOVE SIMILAR OR EQUAL
-# 2A8F; LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN
-# 2A90; GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN
-# 2A9D; SIMILAR OR LESS-THAN
-# 2A9E; SIMILAR OR GREATER-THAN
-# 2A9F; SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN
-# 2AA0; SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN
-# 2AA3; DOUBLE NESTED LESS-THAN WITH UNDERBAR
-# 2AB1; PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO
-# 2AB2; SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO
-# 2AB5; PRECEDES ABOVE NOT EQUAL TO
-# 2AB6; SUCCEEDS ABOVE NOT EQUAL TO
-# 2AB7; PRECEDES ABOVE ALMOST EQUAL TO
-# 2AB8; SUCCEEDS ABOVE ALMOST EQUAL TO
-# 2AB9; PRECEDES ABOVE NOT ALMOST EQUAL TO
-# 2ABA; SUCCEEDS ABOVE NOT ALMOST EQUAL TO
-# 2AC7; SUBSET OF ABOVE TILDE OPERATOR
-# 2AC8; SUPERSET OF ABOVE TILDE OPERATOR
-# 2AC9; SUBSET OF ABOVE ALMOST EQUAL TO
-# 2ACA; SUPERSET OF ABOVE ALMOST EQUAL TO
-# 2ACB; SUBSET OF ABOVE NOT EQUAL TO
-# 2ACC; SUPERSET OF ABOVE NOT EQUAL TO
-# 2ADC; FORKING
-# 2AE2; VERTICAL BAR TRIPLE RIGHT TURNSTILE
-# 2AE6; LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL
-# 2AEE; DOES NOT DIVIDE WITH REVERSED NEGATION SLASH
-# 2AF3; PARALLEL WITH TILDE OPERATOR
-# 2AFB; TRIPLE SOLIDUS BINARY RELATION
-# 2AFD; DOUBLE SOLIDUS OPERATOR
-# 1D6DB; MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
-# 1D715; MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
-# 1D74F; MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
-# 1D789; MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
-# 1D7C3; MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
-
-# EOF
diff --git a/third_party/harfbuzz/contrib/tables/DerivedCombiningClass.txt b/third_party/harfbuzz/contrib/tables/DerivedCombiningClass.txt
deleted file mode 100644
index f30fb0b..0000000
--- a/third_party/harfbuzz/contrib/tables/DerivedCombiningClass.txt
+++ /dev/null
@@ -1,1881 +0,0 @@
-# DerivedCombiningClass-5.1.0.txt
-# Date: 2008-03-20, 17:54:45 GMT [MD]
-#
-# Unicode Character Database
-# Copyright (c) 1991-2008 Unicode, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-# For documentation, see UCD.html
-
-# ================================================
-
-# Combining Class (listing UnicodeData.txt, field 3: see UCD.html)
-
-#  All code points not explicitly listed for Canonical_Combining_Class
-#  have the value Not_Reordered (0).
-
-# @missing: 0000..10FFFF; Not_Reordered
-
-# ================================================
-
-# Canonical_Combining_Class=Not_Reordered
-
-0000..001F    ; 0 # Cc  [32] <control-0000>..<control-001F>
-0020          ; 0 # Zs       SPACE
-0021..0023    ; 0 # Po   [3] EXCLAMATION MARK..NUMBER SIGN
-0024          ; 0 # Sc       DOLLAR SIGN
-0025..0027    ; 0 # Po   [3] PERCENT SIGN..APOSTROPHE
-0028          ; 0 # Ps       LEFT PARENTHESIS
-0029          ; 0 # Pe       RIGHT PARENTHESIS
-002A          ; 0 # Po       ASTERISK
-002B          ; 0 # Sm       PLUS SIGN
-002C          ; 0 # Po       COMMA
-002D          ; 0 # Pd       HYPHEN-MINUS
-002E..002F    ; 0 # Po   [2] FULL STOP..SOLIDUS
-0030..0039    ; 0 # Nd  [10] DIGIT ZERO..DIGIT NINE
-003A..003B    ; 0 # Po   [2] COLON..SEMICOLON
-003C..003E    ; 0 # Sm   [3] LESS-THAN SIGN..GREATER-THAN SIGN
-003F..0040    ; 0 # Po   [2] QUESTION MARK..COMMERCIAL AT
-0041..005A    ; 0 # L&  [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z
-005B          ; 0 # Ps       LEFT SQUARE BRACKET
-005C          ; 0 # Po       REVERSE SOLIDUS
-005D          ; 0 # Pe       RIGHT SQUARE BRACKET
-005E          ; 0 # Sk       CIRCUMFLEX ACCENT
-005F          ; 0 # Pc       LOW LINE
-0060          ; 0 # Sk       GRAVE ACCENT
-0061..007A    ; 0 # L&  [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z
-007B          ; 0 # Ps       LEFT CURLY BRACKET
-007C          ; 0 # Sm       VERTICAL LINE
-007D          ; 0 # Pe       RIGHT CURLY BRACKET
-007E          ; 0 # Sm       TILDE
-007F..009F    ; 0 # Cc  [33] <control-007F>..<control-009F>
-00A0          ; 0 # Zs       NO-BREAK SPACE
-00A1          ; 0 # Po       INVERTED EXCLAMATION MARK
-00A2..00A5    ; 0 # Sc   [4] CENT SIGN..YEN SIGN
-00A6..00A7    ; 0 # So   [2] BROKEN BAR..SECTION SIGN
-00A8          ; 0 # Sk       DIAERESIS
-00A9          ; 0 # So       COPYRIGHT SIGN
-00AA          ; 0 # L&       FEMININE ORDINAL INDICATOR
-00AB          ; 0 # Pi       LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
-00AC          ; 0 # Sm       NOT SIGN
-00AD          ; 0 # Cf       SOFT HYPHEN
-00AE          ; 0 # So       REGISTERED SIGN
-00AF          ; 0 # Sk       MACRON
-00B0          ; 0 # So       DEGREE SIGN
-00B1          ; 0 # Sm       PLUS-MINUS SIGN
-00B2..00B3    ; 0 # No   [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE
-00B4          ; 0 # Sk       ACUTE ACCENT
-00B5          ; 0 # L&       MICRO SIGN
-00B6          ; 0 # So       PILCROW SIGN
-00B7          ; 0 # Po       MIDDLE DOT
-00B8          ; 0 # Sk       CEDILLA
-00B9          ; 0 # No       SUPERSCRIPT ONE
-00BA          ; 0 # L&       MASCULINE ORDINAL INDICATOR
-00BB          ; 0 # Pf       RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-00BC..00BE    ; 0 # No   [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS
-00BF          ; 0 # Po       INVERTED QUESTION MARK
-00C0..00D6    ; 0 # L&  [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS
-00D7          ; 0 # Sm       MULTIPLICATION SIGN
-00D8..00F6    ; 0 # L&  [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS
-00F7          ; 0 # Sm       DIVISION SIGN
-00F8..01BA    ; 0 # L& [195] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL
-01BB          ; 0 # Lo       LATIN LETTER TWO WITH STROKE
-01BC..01BF    ; 0 # L&   [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN
-01C0..01C3    ; 0 # Lo   [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK
-01C4..0293    ; 0 # L& [208] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER EZH WITH CURL
-0294          ; 0 # Lo       LATIN LETTER GLOTTAL STOP
-0295..02AF    ; 0 # L&  [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
-02B0..02C1    ; 0 # Lm  [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP
-02C2..02C5    ; 0 # Sk   [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD
-02C6..02D1    ; 0 # Lm  [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON
-02D2..02DF    ; 0 # Sk  [14] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER CROSS ACCENT
-02E0..02E4    ; 0 # Lm   [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
-02E5..02EB    ; 0 # Sk   [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK
-02EC          ; 0 # Lm       MODIFIER LETTER VOICING
-02ED          ; 0 # Sk       MODIFIER LETTER UNASPIRATED
-02EE          ; 0 # Lm       MODIFIER LETTER DOUBLE APOSTROPHE
-02EF..02FF    ; 0 # Sk  [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW
-034F          ; 0 # Mn       COMBINING GRAPHEME JOINER
-0370..0373    ; 0 # L&   [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI
-0374          ; 0 # Lm       GREEK NUMERAL SIGN
-0375          ; 0 # Sk       GREEK LOWER NUMERAL SIGN
-0376..0377    ; 0 # L&   [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA
-037A          ; 0 # Lm       GREEK YPOGEGRAMMENI
-037B..037D    ; 0 # L&   [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
-037E          ; 0 # Po       GREEK QUESTION MARK
-0384..0385    ; 0 # Sk   [2] GREEK TONOS..GREEK DIALYTIKA TONOS
-0386          ; 0 # L&       GREEK CAPITAL LETTER ALPHA WITH TONOS
-0387          ; 0 # Po       GREEK ANO TELEIA
-0388..038A    ; 0 # L&   [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS
-038C          ; 0 # L&       GREEK CAPITAL LETTER OMICRON WITH TONOS
-038E..03A1    ; 0 # L&  [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO
-03A3..03F5    ; 0 # L&  [83] GREEK CAPITAL LETTER SIGMA..GREEK LUNATE EPSILON SYMBOL
-03F6          ; 0 # Sm       GREEK REVERSED LUNATE EPSILON SYMBOL
-03F7..0481    ; 0 # L& [139] GREEK CAPITAL LETTER SHO..CYRILLIC SMALL LETTER KOPPA
-0482          ; 0 # So       CYRILLIC THOUSANDS SIGN
-0488..0489    ; 0 # Me   [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
-048A..0523    ; 0 # L& [154] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK
-0531..0556    ; 0 # L&  [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH
-0559          ; 0 # Lm       ARMENIAN MODIFIER LETTER LEFT HALF RING
-055A..055F    ; 0 # Po   [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK
-0561..0587    ; 0 # L&  [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN
-0589          ; 0 # Po       ARMENIAN FULL STOP
-058A          ; 0 # Pd       ARMENIAN HYPHEN
-05BE          ; 0 # Pd       HEBREW PUNCTUATION MAQAF
-05C0          ; 0 # Po       HEBREW PUNCTUATION PASEQ
-05C3          ; 0 # Po       HEBREW PUNCTUATION SOF PASUQ
-05C6          ; 0 # Po       HEBREW PUNCTUATION NUN HAFUKHA
-05D0..05EA    ; 0 # Lo  [27] HEBREW LETTER ALEF..HEBREW LETTER TAV
-05F0..05F2    ; 0 # Lo   [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD
-05F3..05F4    ; 0 # Po   [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM
-0600..0603    ; 0 # Cf   [4] ARABIC NUMBER SIGN..ARABIC SIGN SAFHA
-0606..0608    ; 0 # Sm   [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY
-0609..060A    ; 0 # Po   [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN
-060B          ; 0 # Sc       AFGHANI SIGN
-060C..060D    ; 0 # Po   [2] ARABIC COMMA..ARABIC DATE SEPARATOR
-060E..060F    ; 0 # So   [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA
-061B          ; 0 # Po       ARABIC SEMICOLON
-061E..061F    ; 0 # Po   [2] ARABIC TRIPLE DOT PUNCTUATION MARK..ARABIC QUESTION MARK
-0621..063F    ; 0 # Lo  [31] ARABIC LETTER HAMZA..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
-0640          ; 0 # Lm       ARABIC TATWEEL
-0641..064A    ; 0 # Lo  [10] ARABIC LETTER FEH..ARABIC LETTER YEH
-0660..0669    ; 0 # Nd  [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE
-066A..066D    ; 0 # Po   [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR
-066E..066F    ; 0 # Lo   [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF
-0671..06D3    ; 0 # Lo  [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
-06D4          ; 0 # Po       ARABIC FULL STOP
-06D5          ; 0 # Lo       ARABIC LETTER AE
-06DD          ; 0 # Cf       ARABIC END OF AYAH
-06DE          ; 0 # Me       ARABIC START OF RUB EL HIZB
-06E5..06E6    ; 0 # Lm   [2] ARABIC SMALL WAW..ARABIC SMALL YEH
-06E9          ; 0 # So       ARABIC PLACE OF SAJDAH
-06EE..06EF    ; 0 # Lo   [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V
-06F0..06F9    ; 0 # Nd  [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE
-06FA..06FC    ; 0 # Lo   [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW
-06FD..06FE    ; 0 # So   [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN
-06FF          ; 0 # Lo       ARABIC LETTER HEH WITH INVERTED V
-0700..070D    ; 0 # Po  [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS
-070F          ; 0 # Cf       SYRIAC ABBREVIATION MARK
-0710          ; 0 # Lo       SYRIAC LETTER ALAPH
-0712..072F    ; 0 # Lo  [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH
-074D..07A5    ; 0 # Lo  [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU
-07A6..07B0    ; 0 # Mn  [11] THAANA ABAFILI..THAANA SUKUN
-07B1          ; 0 # Lo       THAANA LETTER NAA
-07C0..07C9    ; 0 # Nd  [10] NKO DIGIT ZERO..NKO DIGIT NINE
-07CA..07EA    ; 0 # Lo  [33] NKO LETTER A..NKO LETTER JONA RA
-07F4..07F5    ; 0 # Lm   [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE
-07F6          ; 0 # So       NKO SYMBOL OO DENNEN
-07F7..07F9    ; 0 # Po   [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK
-07FA          ; 0 # Lm       NKO LAJANYALAN
-0901..0902    ; 0 # Mn   [2] DEVANAGARI SIGN CANDRABINDU..DEVANAGARI SIGN ANUSVARA
-0903          ; 0 # Mc       DEVANAGARI SIGN VISARGA
-0904..0939    ; 0 # Lo  [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA
-093D          ; 0 # Lo       DEVANAGARI SIGN AVAGRAHA
-093E..0940    ; 0 # Mc   [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
-0941..0948    ; 0 # Mn   [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
-0949..094C    ; 0 # Mc   [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
-0950          ; 0 # Lo       DEVANAGARI OM
-0958..0961    ; 0 # Lo  [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL
-0962..0963    ; 0 # Mn   [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
-0964..0965    ; 0 # Po   [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA
-0966..096F    ; 0 # Nd  [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE
-0970          ; 0 # Po       DEVANAGARI ABBREVIATION SIGN
-0971          ; 0 # Lm       DEVANAGARI SIGN HIGH SPACING DOT
-0972          ; 0 # Lo       DEVANAGARI LETTER CANDRA A
-097B..097F    ; 0 # Lo   [5] DEVANAGARI LETTER GGA..DEVANAGARI LETTER BBA
-0981          ; 0 # Mn       BENGALI SIGN CANDRABINDU
-0982..0983    ; 0 # Mc   [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
-0985..098C    ; 0 # Lo   [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L
-098F..0990    ; 0 # Lo   [2] BENGALI LETTER E..BENGALI LETTER AI
-0993..09A8    ; 0 # Lo  [22] BENGALI LETTER O..BENGALI LETTER NA
-09AA..09B0    ; 0 # Lo   [7] BENGALI LETTER PA..BENGALI LETTER RA
-09B2          ; 0 # Lo       BENGALI LETTER LA
-09B6..09B9    ; 0 # Lo   [4] BENGALI LETTER SHA..BENGALI LETTER HA
-09BD          ; 0 # Lo       BENGALI SIGN AVAGRAHA
-09BE..09C0    ; 0 # Mc   [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II
-09C1..09C4    ; 0 # Mn   [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
-09C7..09C8    ; 0 # Mc   [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
-09CB..09CC    ; 0 # Mc   [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
-09CE          ; 0 # Lo       BENGALI LETTER KHANDA TA
-09D7          ; 0 # Mc       BENGALI AU LENGTH MARK
-09DC..09DD    ; 0 # Lo   [2] BENGALI LETTER RRA..BENGALI LETTER RHA
-09DF..09E1    ; 0 # Lo   [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL
-09E2..09E3    ; 0 # Mn   [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
-09E6..09EF    ; 0 # Nd  [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE
-09F0..09F1    ; 0 # Lo   [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL
-09F2..09F3    ; 0 # Sc   [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN
-09F4..09F9    ; 0 # No   [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN
-09FA          ; 0 # So       BENGALI ISSHAR
-0A01..0A02    ; 0 # Mn   [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
-0A03          ; 0 # Mc       GURMUKHI SIGN VISARGA
-0A05..0A0A    ; 0 # Lo   [6] GURMUKHI LETTER A..GURMUKHI LETTER UU
-0A0F..0A10    ; 0 # Lo   [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI
-0A13..0A28    ; 0 # Lo  [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA
-0A2A..0A30    ; 0 # Lo   [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA
-0A32..0A33    ; 0 # Lo   [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA
-0A35..0A36    ; 0 # Lo   [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA
-0A38..0A39    ; 0 # Lo   [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA
-0A3E..0A40    ; 0 # Mc   [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
-0A41..0A42    ; 0 # Mn   [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
-0A47..0A48    ; 0 # Mn   [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
-0A4B..0A4C    ; 0 # Mn   [2] GURMUKHI VOWEL SIGN OO..GURMUKHI VOWEL SIGN AU
-0A51          ; 0 # Mn       GURMUKHI SIGN UDAAT
-0A59..0A5C    ; 0 # Lo   [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA
-0A5E          ; 0 # Lo       GURMUKHI LETTER FA
-0A66..0A6F    ; 0 # Nd  [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE
-0A70..0A71    ; 0 # Mn   [2] GURMUKHI TIPPI..GURMUKHI ADDAK
-0A72..0A74    ; 0 # Lo   [3] GURMUKHI IRI..GURMUKHI EK ONKAR
-0A75          ; 0 # Mn       GURMUKHI SIGN YAKASH
-0A81..0A82    ; 0 # Mn   [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
-0A83          ; 0 # Mc       GUJARATI SIGN VISARGA
-0A85..0A8D    ; 0 # Lo   [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E
-0A8F..0A91    ; 0 # Lo   [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O
-0A93..0AA8    ; 0 # Lo  [22] GUJARATI LETTER O..GUJARATI LETTER NA
-0AAA..0AB0    ; 0 # Lo   [7] GUJARATI LETTER PA..GUJARATI LETTER RA
-0AB2..0AB3    ; 0 # Lo   [2] GUJARATI LETTER LA..GUJARATI LETTER LLA
-0AB5..0AB9    ; 0 # Lo   [5] GUJARATI LETTER VA..GUJARATI LETTER HA
-0ABD          ; 0 # Lo       GUJARATI SIGN AVAGRAHA
-0ABE..0AC0    ; 0 # Mc   [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
-0AC1..0AC5    ; 0 # Mn   [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
-0AC7..0AC8    ; 0 # Mn   [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
-0AC9          ; 0 # Mc       GUJARATI VOWEL SIGN CANDRA O
-0ACB..0ACC    ; 0 # Mc   [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
-0AD0          ; 0 # Lo       GUJARATI OM
-0AE0..0AE1    ; 0 # Lo   [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL
-0AE2..0AE3    ; 0 # Mn   [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
-0AE6..0AEF    ; 0 # Nd  [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE
-0AF1          ; 0 # Sc       GUJARATI RUPEE SIGN
-0B01          ; 0 # Mn       ORIYA SIGN CANDRABINDU
-0B02..0B03    ; 0 # Mc   [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
-0B05..0B0C    ; 0 # Lo   [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L
-0B0F..0B10    ; 0 # Lo   [2] ORIYA LETTER E..ORIYA LETTER AI
-0B13..0B28    ; 0 # Lo  [22] ORIYA LETTER O..ORIYA LETTER NA
-0B2A..0B30    ; 0 # Lo   [7] ORIYA LETTER PA..ORIYA LETTER RA
-0B32..0B33    ; 0 # Lo   [2] ORIYA LETTER LA..ORIYA LETTER LLA
-0B35..0B39    ; 0 # Lo   [5] ORIYA LETTER VA..ORIYA LETTER HA
-0B3D          ; 0 # Lo       ORIYA SIGN AVAGRAHA
-0B3E          ; 0 # Mc       ORIYA VOWEL SIGN AA
-0B3F          ; 0 # Mn       ORIYA VOWEL SIGN I
-0B40          ; 0 # Mc       ORIYA VOWEL SIGN II
-0B41..0B44    ; 0 # Mn   [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
-0B47..0B48    ; 0 # Mc   [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
-0B4B..0B4C    ; 0 # Mc   [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
-0B56          ; 0 # Mn       ORIYA AI LENGTH MARK
-0B57          ; 0 # Mc       ORIYA AU LENGTH MARK
-0B5C..0B5D    ; 0 # Lo   [2] ORIYA LETTER RRA..ORIYA LETTER RHA
-0B5F..0B61    ; 0 # Lo   [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
-0B62..0B63    ; 0 # Mn   [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
-0B66..0B6F    ; 0 # Nd  [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE
-0B70          ; 0 # So       ORIYA ISSHAR
-0B71          ; 0 # Lo       ORIYA LETTER WA
-0B82          ; 0 # Mn       TAMIL SIGN ANUSVARA
-0B83          ; 0 # Lo       TAMIL SIGN VISARGA
-0B85..0B8A    ; 0 # Lo   [6] TAMIL LETTER A..TAMIL LETTER UU
-0B8E..0B90    ; 0 # Lo   [3] TAMIL LETTER E..TAMIL LETTER AI
-0B92..0B95    ; 0 # Lo   [4] TAMIL LETTER O..TAMIL LETTER KA
-0B99..0B9A    ; 0 # Lo   [2] TAMIL LETTER NGA..TAMIL LETTER CA
-0B9C          ; 0 # Lo       TAMIL LETTER JA
-0B9E..0B9F    ; 0 # Lo   [2] TAMIL LETTER NYA..TAMIL LETTER TTA
-0BA3..0BA4    ; 0 # Lo   [2] TAMIL LETTER NNA..TAMIL LETTER TA
-0BA8..0BAA    ; 0 # Lo   [3] TAMIL LETTER NA..TAMIL LETTER PA
-0BAE..0BB9    ; 0 # Lo  [12] TAMIL LETTER MA..TAMIL LETTER HA
-0BBE..0BBF    ; 0 # Mc   [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I
-0BC0          ; 0 # Mn       TAMIL VOWEL SIGN II
-0BC1..0BC2    ; 0 # Mc   [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
-0BC6..0BC8    ; 0 # Mc   [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
-0BCA..0BCC    ; 0 # Mc   [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
-0BD0          ; 0 # Lo       TAMIL OM
-0BD7          ; 0 # Mc       TAMIL AU LENGTH MARK
-0BE6..0BEF    ; 0 # Nd  [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE
-0BF0..0BF2    ; 0 # No   [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND
-0BF3..0BF8    ; 0 # So   [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN
-0BF9          ; 0 # Sc       TAMIL RUPEE SIGN
-0BFA          ; 0 # So       TAMIL NUMBER SIGN
-0C01..0C03    ; 0 # Mc   [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
-0C05..0C0C    ; 0 # Lo   [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L
-0C0E..0C10    ; 0 # Lo   [3] TELUGU LETTER E..TELUGU LETTER AI
-0C12..0C28    ; 0 # Lo  [23] TELUGU LETTER O..TELUGU LETTER NA
-0C2A..0C33    ; 0 # Lo  [10] TELUGU LETTER PA..TELUGU LETTER LLA
-0C35..0C39    ; 0 # Lo   [5] TELUGU LETTER VA..TELUGU LETTER HA
-0C3D          ; 0 # Lo       TELUGU SIGN AVAGRAHA
-0C3E..0C40    ; 0 # Mn   [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
-0C41..0C44    ; 0 # Mc   [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
-0C46..0C48    ; 0 # Mn   [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
-0C4A..0C4C    ; 0 # Mn   [3] TELUGU VOWEL SIGN O..TELUGU VOWEL SIGN AU
-0C58..0C59    ; 0 # Lo   [2] TELUGU LETTER TSA..TELUGU LETTER DZA
-0C60..0C61    ; 0 # Lo   [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL
-0C62..0C63    ; 0 # Mn   [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
-0C66..0C6F    ; 0 # Nd  [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE
-0C78..0C7E    ; 0 # No   [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR
-0C7F          ; 0 # So       TELUGU SIGN TUUMU
-0C82..0C83    ; 0 # Mc   [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
-0C85..0C8C    ; 0 # Lo   [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L
-0C8E..0C90    ; 0 # Lo   [3] KANNADA LETTER E..KANNADA LETTER AI
-0C92..0CA8    ; 0 # Lo  [23] KANNADA LETTER O..KANNADA LETTER NA
-0CAA..0CB3    ; 0 # Lo  [10] KANNADA LETTER PA..KANNADA LETTER LLA
-0CB5..0CB9    ; 0 # Lo   [5] KANNADA LETTER VA..KANNADA LETTER HA
-0CBD          ; 0 # Lo       KANNADA SIGN AVAGRAHA
-0CBE          ; 0 # Mc       KANNADA VOWEL SIGN AA
-0CBF          ; 0 # Mn       KANNADA VOWEL SIGN I
-0CC0..0CC4    ; 0 # Mc   [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR
-0CC6          ; 0 # Mn       KANNADA VOWEL SIGN E
-0CC7..0CC8    ; 0 # Mc   [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
-0CCA..0CCB    ; 0 # Mc   [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
-0CCC          ; 0 # Mn       KANNADA VOWEL SIGN AU
-0CD5..0CD6    ; 0 # Mc   [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
-0CDE          ; 0 # Lo       KANNADA LETTER FA
-0CE0..0CE1    ; 0 # Lo   [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
-0CE2..0CE3    ; 0 # Mn   [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
-0CE6..0CEF    ; 0 # Nd  [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
-0CF1..0CF2    ; 0 # So   [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
-0D02..0D03    ; 0 # Mc   [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
-0D05..0D0C    ; 0 # Lo   [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
-0D0E..0D10    ; 0 # Lo   [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
-0D12..0D28    ; 0 # Lo  [23] MALAYALAM LETTER O..MALAYALAM LETTER NA
-0D2A..0D39    ; 0 # Lo  [16] MALAYALAM LETTER PA..MALAYALAM LETTER HA
-0D3D          ; 0 # Lo       MALAYALAM SIGN AVAGRAHA
-0D3E..0D40    ; 0 # Mc   [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II
-0D41..0D44    ; 0 # Mn   [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
-0D46..0D48    ; 0 # Mc   [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
-0D4A..0D4C    ; 0 # Mc   [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
-0D57          ; 0 # Mc       MALAYALAM AU LENGTH MARK
-0D60..0D61    ; 0 # Lo   [2] MALAYALAM LETTER VOCALIC RR..MALAYALAM LETTER VOCALIC LL
-0D62..0D63    ; 0 # Mn   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
-0D66..0D6F    ; 0 # Nd  [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
-0D70..0D75    ; 0 # No   [6] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE QUARTERS
-0D79          ; 0 # So       MALAYALAM DATE MARK
-0D7A..0D7F    ; 0 # Lo   [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
-0D82..0D83    ; 0 # Mc   [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
-0D85..0D96    ; 0 # Lo  [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
-0D9A..0DB1    ; 0 # Lo  [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
-0DB3..0DBB    ; 0 # Lo   [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA
-0DBD          ; 0 # Lo       SINHALA LETTER DANTAJA LAYANNA
-0DC0..0DC6    ; 0 # Lo   [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA
-0DCF..0DD1    ; 0 # Mc   [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
-0DD2..0DD4    ; 0 # Mn   [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
-0DD6          ; 0 # Mn       SINHALA VOWEL SIGN DIGA PAA-PILLA
-0DD8..0DDF    ; 0 # Mc   [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
-0DF2..0DF3    ; 0 # Mc   [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
-0DF4          ; 0 # Po       SINHALA PUNCTUATION KUNDDALIYA
-0E01..0E30    ; 0 # Lo  [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A
-0E31          ; 0 # Mn       THAI CHARACTER MAI HAN-AKAT
-0E32..0E33    ; 0 # Lo   [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM
-0E34..0E37    ; 0 # Mn   [4] THAI CHARACTER SARA I..THAI CHARACTER SARA UEE
-0E3F          ; 0 # Sc       THAI CURRENCY SYMBOL BAHT
-0E40..0E45    ; 0 # Lo   [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO
-0E46          ; 0 # Lm       THAI CHARACTER MAIYAMOK
-0E47          ; 0 # Mn       THAI CHARACTER MAITAIKHU
-0E4C..0E4E    ; 0 # Mn   [3] THAI CHARACTER THANTHAKHAT..THAI CHARACTER YAMAKKAN
-0E4F          ; 0 # Po       THAI CHARACTER FONGMAN
-0E50..0E59    ; 0 # Nd  [10] THAI DIGIT ZERO..THAI DIGIT NINE
-0E5A..0E5B    ; 0 # Po   [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT
-0E81..0E82    ; 0 # Lo   [2] LAO LETTER KO..LAO LETTER KHO SUNG
-0E84          ; 0 # Lo       LAO LETTER KHO TAM
-0E87..0E88    ; 0 # Lo   [2] LAO LETTER NGO..LAO LETTER CO
-0E8A          ; 0 # Lo       LAO LETTER SO TAM
-0E8D          ; 0 # Lo       LAO LETTER NYO
-0E94..0E97    ; 0 # Lo   [4] LAO LETTER DO..LAO LETTER THO TAM
-0E99..0E9F    ; 0 # Lo   [7] LAO LETTER NO..LAO LETTER FO SUNG
-0EA1..0EA3    ; 0 # Lo   [3] LAO LETTER MO..LAO LETTER LO LING
-0EA5          ; 0 # Lo       LAO LETTER LO LOOT
-0EA7          ; 0 # Lo       LAO LETTER WO
-0EAA..0EAB    ; 0 # Lo   [2] LAO LETTER SO SUNG..LAO LETTER HO SUNG
-0EAD..0EB0    ; 0 # Lo   [4] LAO LETTER O..LAO VOWEL SIGN A
-0EB1          ; 0 # Mn       LAO VOWEL SIGN MAI KAN
-0EB2..0EB3    ; 0 # Lo   [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM
-0EB4..0EB7    ; 0 # Mn   [4] LAO VOWEL SIGN I..LAO VOWEL SIGN YY
-0EBB..0EBC    ; 0 # Mn   [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO
-0EBD          ; 0 # Lo       LAO SEMIVOWEL SIGN NYO
-0EC0..0EC4    ; 0 # Lo   [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
-0EC6          ; 0 # Lm       LAO KO LA
-0ECC..0ECD    ; 0 # Mn   [2] LAO CANCELLATION MARK..LAO NIGGAHITA
-0ED0..0ED9    ; 0 # Nd  [10] LAO DIGIT ZERO..LAO DIGIT NINE
-0EDC..0EDD    ; 0 # Lo   [2] LAO HO NO..LAO HO MO
-0F00          ; 0 # Lo       TIBETAN SYLLABLE OM
-0F01..0F03    ; 0 # So   [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA
-0F04..0F12    ; 0 # Po  [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD
-0F13..0F17    ; 0 # So   [5] TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS
-0F1A..0F1F    ; 0 # So   [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG
-0F20..0F29    ; 0 # Nd  [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE
-0F2A..0F33    ; 0 # No  [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO
-0F34          ; 0 # So       TIBETAN MARK BSDUS RTAGS
-0F36          ; 0 # So       TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN
-0F38          ; 0 # So       TIBETAN MARK CHE MGO
-0F3A          ; 0 # Ps       TIBETAN MARK GUG RTAGS GYON
-0F3B          ; 0 # Pe       TIBETAN MARK GUG RTAGS GYAS
-0F3C          ; 0 # Ps       TIBETAN MARK ANG KHANG GYON
-0F3D          ; 0 # Pe       TIBETAN MARK ANG KHANG GYAS
-0F3E..0F3F    ; 0 # Mc   [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
-0F40..0F47    ; 0 # Lo   [8] TIBETAN LETTER KA..TIBETAN LETTER JA
-0F49..0F6C    ; 0 # Lo  [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA
-0F73          ; 0 # Mn       TIBETAN VOWEL SIGN II
-0F75..0F79    ; 0 # Mn   [5] TIBETAN VOWEL SIGN UU..TIBETAN VOWEL SIGN VOCALIC LL
-0F7E          ; 0 # Mn       TIBETAN SIGN RJES SU NGA RO
-0F7F          ; 0 # Mc       TIBETAN SIGN RNAM BCAD
-0F81          ; 0 # Mn       TIBETAN VOWEL SIGN REVERSED II
-0F85          ; 0 # Po       TIBETAN MARK PALUTA
-0F88..0F8B    ; 0 # Lo   [4] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN GRU MED RGYINGS
-0F90..0F97    ; 0 # Mn   [8] TIBETAN SUBJOINED LETTER KA..TIBETAN SUBJOINED LETTER JA
-0F99..0FBC    ; 0 # Mn  [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
-0FBE..0FC5    ; 0 # So   [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE
-0FC7..0FCC    ; 0 # So   [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL
-0FCE..0FCF    ; 0 # So   [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM
-0FD0..0FD4    ; 0 # Po   [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA
-1000..102A    ; 0 # Lo  [43] MYANMAR LETTER KA..MYANMAR LETTER AU
-102B..102C    ; 0 # Mc   [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA
-102D..1030    ; 0 # Mn   [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
-1031          ; 0 # Mc       MYANMAR VOWEL SIGN E
-1032..1036    ; 0 # Mn   [5] MYANMAR VOWEL SIGN AI..MYANMAR SIGN ANUSVARA
-1038          ; 0 # Mc       MYANMAR SIGN VISARGA
-103B..103C    ; 0 # Mc   [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
-103D..103E    ; 0 # Mn   [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
-103F          ; 0 # Lo       MYANMAR LETTER GREAT SA
-1040..1049    ; 0 # Nd  [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE
-104A..104F    ; 0 # Po   [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE
-1050..1055    ; 0 # Lo   [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL
-1056..1057    ; 0 # Mc   [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
-1058..1059    ; 0 # Mn   [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
-105A..105D    ; 0 # Lo   [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE
-105E..1060    ; 0 # Mn   [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
-1061          ; 0 # Lo       MYANMAR LETTER SGAW KAREN SHA
-1062..1064    ; 0 # Mc   [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO
-1065..1066    ; 0 # Lo   [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA
-1067..106D    ; 0 # Mc   [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5
-106E..1070    ; 0 # Lo   [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA
-1071..1074    ; 0 # Mn   [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
-1075..1081    ; 0 # Lo  [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA
-1082          ; 0 # Mn       MYANMAR CONSONANT SIGN SHAN MEDIAL WA
-1083..1084    ; 0 # Mc   [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E
-1085..1086    ; 0 # Mn   [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
-1087..108C    ; 0 # Mc   [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3
-108E          ; 0 # Lo       MYANMAR LETTER RUMAI PALAUNG FA
-108F          ; 0 # Mc       MYANMAR SIGN RUMAI PALAUNG TONE-5
-1090..1099    ; 0 # Nd  [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE
-109E..109F    ; 0 # So   [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION
-10A0..10C5    ; 0 # L&  [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE
-10D0..10FA    ; 0 # Lo  [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN
-10FB          ; 0 # Po       GEORGIAN PARAGRAPH SEPARATOR
-10FC          ; 0 # Lm       MODIFIER LETTER GEORGIAN NAR
-1100..1159    ; 0 # Lo  [90] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG YEORINHIEUH
-115F..11A2    ; 0 # Lo  [68] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG SSANGARAEA
-11A8..11F9    ; 0 # Lo  [82] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG YEORINHIEUH
-1200..1248    ; 0 # Lo  [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA
-124A..124D    ; 0 # Lo   [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE
-1250..1256    ; 0 # Lo   [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO
-1258          ; 0 # Lo       ETHIOPIC SYLLABLE QHWA
-125A..125D    ; 0 # Lo   [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE
-1260..1288    ; 0 # Lo  [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA
-128A..128D    ; 0 # Lo   [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE
-1290..12B0    ; 0 # Lo  [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA
-12B2..12B5    ; 0 # Lo   [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE
-12B8..12BE    ; 0 # Lo   [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO
-12C0          ; 0 # Lo       ETHIOPIC SYLLABLE KXWA
-12C2..12C5    ; 0 # Lo   [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE
-12C8..12D6    ; 0 # Lo  [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O
-12D8..1310    ; 0 # Lo  [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA
-1312..1315    ; 0 # Lo   [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE
-1318..135A    ; 0 # Lo  [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA
-1360          ; 0 # So       ETHIOPIC SECTION MARK
-1361..1368    ; 0 # Po   [8] ETHIOPIC WORDSPACE..ETHIOPIC PARAGRAPH SEPARATOR
-1369..137C    ; 0 # No  [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND
-1380..138F    ; 0 # Lo  [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE
-1390..1399    ; 0 # So  [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT
-13A0..13F4    ; 0 # Lo  [85] CHEROKEE LETTER A..CHEROKEE LETTER YV
-1401..166C    ; 0 # Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA
-166D..166E    ; 0 # Po   [2] CANADIAN SYLLABICS CHI SIGN..CANADIAN SYLLABICS FULL STOP
-166F..1676    ; 0 # Lo   [8] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS NNGAA
-1680          ; 0 # Zs       OGHAM SPACE MARK
-1681..169A    ; 0 # Lo  [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH
-169B          ; 0 # Ps       OGHAM FEATHER MARK
-169C          ; 0 # Pe       OGHAM REVERSED FEATHER MARK
-16A0..16EA    ; 0 # Lo  [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X
-16EB..16ED    ; 0 # Po   [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION
-16EE..16F0    ; 0 # Nl   [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL
-1700..170C    ; 0 # Lo  [13] TAGALOG LETTER A..TAGALOG LETTER YA
-170E..1711    ; 0 # Lo   [4] TAGALOG LETTER LA..TAGALOG LETTER HA
-1712..1713    ; 0 # Mn   [2] TAGALOG VOWEL SIGN I..TAGALOG VOWEL SIGN U
-1720..1731    ; 0 # Lo  [18] HANUNOO LETTER A..HANUNOO LETTER HA
-1732..1733    ; 0 # Mn   [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U
-1735..1736    ; 0 # Po   [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION
-1740..1751    ; 0 # Lo  [18] BUHID LETTER A..BUHID LETTER HA
-1752..1753    ; 0 # Mn   [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
-1760..176C    ; 0 # Lo  [13] TAGBANWA LETTER A..TAGBANWA LETTER YA
-176E..1770    ; 0 # Lo   [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA
-1772..1773    ; 0 # Mn   [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
-1780..17B3    ; 0 # Lo  [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU
-17B4..17B5    ; 0 # Cf   [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
-17B6          ; 0 # Mc       KHMER VOWEL SIGN AA
-17B7..17BD    ; 0 # Mn   [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
-17BE..17C5    ; 0 # Mc   [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
-17C6          ; 0 # Mn       KHMER SIGN NIKAHIT
-17C7..17C8    ; 0 # Mc   [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
-17C9..17D1    ; 0 # Mn   [9] KHMER SIGN MUUSIKATOAN..KHMER SIGN VIRIAM
-17D3          ; 0 # Mn       KHMER SIGN BATHAMASAT
-17D4..17D6    ; 0 # Po   [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH
-17D7          ; 0 # Lm       KHMER SIGN LEK TOO
-17D8..17DA    ; 0 # Po   [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT
-17DB          ; 0 # Sc       KHMER CURRENCY SYMBOL RIEL
-17DC          ; 0 # Lo       KHMER SIGN AVAKRAHASANYA
-17E0..17E9    ; 0 # Nd  [10] KHMER DIGIT ZERO..KHMER DIGIT NINE
-17F0..17F9    ; 0 # No  [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON
-1800..1805    ; 0 # Po   [6] MONGOLIAN BIRGA..MONGOLIAN FOUR DOTS
-1806          ; 0 # Pd       MONGOLIAN TODO SOFT HYPHEN
-1807..180A    ; 0 # Po   [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU
-180B..180D    ; 0 # Mn   [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
-180E          ; 0 # Zs       MONGOLIAN VOWEL SEPARATOR
-1810..1819    ; 0 # Nd  [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
-1820..1842    ; 0 # Lo  [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI
-1843          ; 0 # Lm       MONGOLIAN LETTER TODO LONG VOWEL SIGN
-1844..1877    ; 0 # Lo  [52] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER MANCHU ZHA
-1880..18A8    ; 0 # Lo  [41] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER MANCHU ALI GALI BHA
-18AA          ; 0 # Lo       MONGOLIAN LETTER MANCHU ALI GALI LHA
-1900..191C    ; 0 # Lo  [29] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER HA
-1920..1922    ; 0 # Mn   [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
-1923..1926    ; 0 # Mc   [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
-1927..1928    ; 0 # Mn   [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
-1929..192B    ; 0 # Mc   [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
-1930..1931    ; 0 # Mc   [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
-1932          ; 0 # Mn       LIMBU SMALL LETTER ANUSVARA
-1933..1938    ; 0 # Mc   [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
-1940          ; 0 # So       LIMBU SIGN LOO
-1944..1945    ; 0 # Po   [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK
-1946..194F    ; 0 # Nd  [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE
-1950..196D    ; 0 # Lo  [30] TAI LE LETTER KA..TAI LE LETTER AI
-1970..1974    ; 0 # Lo   [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6
-1980..19A9    ; 0 # Lo  [42] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW XVA
-19B0..19C0    ; 0 # Mc  [17] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE VOWEL SIGN IY
-19C1..19C7    ; 0 # Lo   [7] NEW TAI LUE LETTER FINAL V..NEW TAI LUE LETTER FINAL B
-19C8..19C9    ; 0 # Mc   [2] NEW TAI LUE TONE MARK-1..NEW TAI LUE TONE MARK-2
-19D0..19D9    ; 0 # Nd  [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE
-19DE..19DF    ; 0 # Po   [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV
-19E0..19FF    ; 0 # So  [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC
-1A00..1A16    ; 0 # Lo  [23] BUGINESE LETTER KA..BUGINESE LETTER HA
-1A19..1A1B    ; 0 # Mc   [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE
-1A1E..1A1F    ; 0 # Po   [2] BUGINESE PALLAWA..BUGINESE END OF SECTION
-1B00..1B03    ; 0 # Mn   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
-1B04          ; 0 # Mc       BALINESE SIGN BISAH
-1B05..1B33    ; 0 # Lo  [47] BALINESE LETTER AKARA..BALINESE LETTER HA
-1B35          ; 0 # Mc       BALINESE VOWEL SIGN TEDUNG
-1B36..1B3A    ; 0 # Mn   [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
-1B3B          ; 0 # Mc       BALINESE VOWEL SIGN RA REPA TEDUNG
-1B3C          ; 0 # Mn       BALINESE VOWEL SIGN LA LENGA
-1B3D..1B41    ; 0 # Mc   [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
-1B42          ; 0 # Mn       BALINESE VOWEL SIGN PEPET
-1B43          ; 0 # Mc       BALINESE VOWEL SIGN PEPET TEDUNG
-1B45..1B4B    ; 0 # Lo   [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK
-1B50..1B59    ; 0 # Nd  [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE
-1B5A..1B60    ; 0 # Po   [7] BALINESE PANTI..BALINESE PAMENENG
-1B61..1B6A    ; 0 # So  [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE
-1B74..1B7C    ; 0 # So   [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING
-1B80..1B81    ; 0 # Mn   [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
-1B82          ; 0 # Mc       SUNDANESE SIGN PANGWISAD
-1B83..1BA0    ; 0 # Lo  [30] SUNDANESE LETTER A..SUNDANESE LETTER HA
-1BA1          ; 0 # Mc       SUNDANESE CONSONANT SIGN PAMINGKAL
-1BA2..1BA5    ; 0 # Mn   [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
-1BA6..1BA7    ; 0 # Mc   [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
-1BA8..1BA9    ; 0 # Mn   [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
-1BAE..1BAF    ; 0 # Lo   [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA
-1BB0..1BB9    ; 0 # Nd  [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE
-1C00..1C23    ; 0 # Lo  [36] LEPCHA LETTER KA..LEPCHA LETTER A
-1C24..1C2B    ; 0 # Mc   [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
-1C2C..1C33    ; 0 # Mn   [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
-1C34..1C35    ; 0 # Mc   [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
-1C36          ; 0 # Mn       LEPCHA SIGN RAN
-1C3B..1C3F    ; 0 # Po   [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK
-1C40..1C49    ; 0 # Nd  [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE
-1C4D..1C4F    ; 0 # Lo   [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA
-1C50..1C59    ; 0 # Nd  [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE
-1C5A..1C77    ; 0 # Lo  [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH
-1C78..1C7D    ; 0 # Lm   [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD
-1C7E..1C7F    ; 0 # Po   [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD
-1D00..1D2B    ; 0 # L&  [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL
-1D2C..1D61    ; 0 # Lm  [54] MODIFIER LETTER CAPITAL A..MODIFIER LETTER SMALL CHI
-1D62..1D77    ; 0 # L&  [22] LATIN SUBSCRIPT SMALL LETTER I..LATIN SMALL LETTER TURNED G
-1D78          ; 0 # Lm       MODIFIER LETTER CYRILLIC EN
-1D79..1D9A    ; 0 # L&  [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK
-1D9B..1DBF    ; 0 # Lm  [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA
-1E00..1F15    ; 0 # L& [278] LATIN CAPITAL LETTER A WITH RING BELOW..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
-1F18..1F1D    ; 0 # L&   [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
-1F20..1F45    ; 0 # L&  [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
-1F48..1F4D    ; 0 # L&   [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
-1F50..1F57    ; 0 # L&   [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
-1F59          ; 0 # L&       GREEK CAPITAL LETTER UPSILON WITH DASIA
-1F5B          ; 0 # L&       GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
-1F5D          ; 0 # L&       GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
-1F5F..1F7D    ; 0 # L&  [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA
-1F80..1FB4    ; 0 # L&  [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
-1FB6..1FBC    ; 0 # L&   [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
-1FBD          ; 0 # Sk       GREEK KORONIS
-1FBE          ; 0 # L&       GREEK PROSGEGRAMMENI
-1FBF..1FC1    ; 0 # Sk   [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI
-1FC2..1FC4    ; 0 # L&   [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
-1FC6..1FCC    ; 0 # L&   [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
-1FCD..1FCF    ; 0 # Sk   [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI
-1FD0..1FD3    ; 0 # L&   [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
-1FD6..1FDB    ; 0 # L&   [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA
-1FDD..1FDF    ; 0 # Sk   [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI
-1FE0..1FEC    ; 0 # L&  [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA
-1FED..1FEF    ; 0 # Sk   [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA
-1FF2..1FF4    ; 0 # L&   [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
-1FF6..1FFC    ; 0 # L&   [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
-1FFD..1FFE    ; 0 # Sk   [2] GREEK OXIA..GREEK DASIA
-2000..200A    ; 0 # Zs  [11] EN QUAD..HAIR SPACE
-200B..200F    ; 0 # Cf   [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
-2010..2015    ; 0 # Pd   [6] HYPHEN..HORIZONTAL BAR
-2016..2017    ; 0 # Po   [2] DOUBLE VERTICAL LINE..DOUBLE LOW LINE
-2018          ; 0 # Pi       LEFT SINGLE QUOTATION MARK
-2019          ; 0 # Pf       RIGHT SINGLE QUOTATION MARK
-201A          ; 0 # Ps       SINGLE LOW-9 QUOTATION MARK
-201B..201C    ; 0 # Pi   [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK
-201D          ; 0 # Pf       RIGHT DOUBLE QUOTATION MARK
-201E          ; 0 # Ps       DOUBLE LOW-9 QUOTATION MARK
-201F          ; 0 # Pi       DOUBLE HIGH-REVERSED-9 QUOTATION MARK
-2020..2027    ; 0 # Po   [8] DAGGER..HYPHENATION POINT
-2028          ; 0 # Zl       LINE SEPARATOR
-2029          ; 0 # Zp       PARAGRAPH SEPARATOR
-202A..202E    ; 0 # Cf   [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
-202F          ; 0 # Zs       NARROW NO-BREAK SPACE
-2030..2038    ; 0 # Po   [9] PER MILLE SIGN..CARET
-2039          ; 0 # Pi       SINGLE LEFT-POINTING ANGLE QUOTATION MARK
-203A          ; 0 # Pf       SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
-203B..203E    ; 0 # Po   [4] REFERENCE MARK..OVERLINE
-203F..2040    ; 0 # Pc   [2] UNDERTIE..CHARACTER TIE
-2041..2043    ; 0 # Po   [3] CARET INSERTION POINT..HYPHEN BULLET
-2044          ; 0 # Sm       FRACTION SLASH
-2045          ; 0 # Ps       LEFT SQUARE BRACKET WITH QUILL
-2046          ; 0 # Pe       RIGHT SQUARE BRACKET WITH QUILL
-2047..2051    ; 0 # Po  [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY
-2052          ; 0 # Sm       COMMERCIAL MINUS SIGN
-2053          ; 0 # Po       SWUNG DASH
-2054          ; 0 # Pc       INVERTED UNDERTIE
-2055..205E    ; 0 # Po  [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS
-205F          ; 0 # Zs       MEDIUM MATHEMATICAL SPACE
-2060..2064    ; 0 # Cf   [5] WORD JOINER..INVISIBLE PLUS
-206A..206F    ; 0 # Cf   [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
-2070          ; 0 # No       SUPERSCRIPT ZERO
-2071          ; 0 # L&       SUPERSCRIPT LATIN SMALL LETTER I
-2074..2079    ; 0 # No   [6] SUPERSCRIPT FOUR..SUPERSCRIPT NINE
-207A..207C    ; 0 # Sm   [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN
-207D          ; 0 # Ps       SUPERSCRIPT LEFT PARENTHESIS
-207E          ; 0 # Pe       SUPERSCRIPT RIGHT PARENTHESIS
-207F          ; 0 # L&       SUPERSCRIPT LATIN SMALL LETTER N
-2080..2089    ; 0 # No  [10] SUBSCRIPT ZERO..SUBSCRIPT NINE
-208A..208C    ; 0 # Sm   [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN
-208D          ; 0 # Ps       SUBSCRIPT LEFT PARENTHESIS
-208E          ; 0 # Pe       SUBSCRIPT RIGHT PARENTHESIS
-2090..2094    ; 0 # Lm   [5] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER SCHWA
-20A0..20B5    ; 0 # Sc  [22] EURO-CURRENCY SIGN..CEDI SIGN
-20DD..20E0    ; 0 # Me   [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
-20E2..20E4    ; 0 # Me   [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
-2100..2101    ; 0 # So   [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT
-2102          ; 0 # L&       DOUBLE-STRUCK CAPITAL C
-2103..2106    ; 0 # So   [4] DEGREE CELSIUS..CADA UNA
-2107          ; 0 # L&       EULER CONSTANT
-2108..2109    ; 0 # So   [2] SCRUPLE..DEGREE FAHRENHEIT
-210A..2113    ; 0 # L&  [10] SCRIPT SMALL G..SCRIPT SMALL L
-2114          ; 0 # So       L B BAR SYMBOL
-2115          ; 0 # L&       DOUBLE-STRUCK CAPITAL N
-2116..2118    ; 0 # So   [3] NUMERO SIGN..SCRIPT CAPITAL P
-2119..211D    ; 0 # L&   [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R
-211E..2123    ; 0 # So   [6] PRESCRIPTION TAKE..VERSICLE
-2124          ; 0 # L&       DOUBLE-STRUCK CAPITAL Z
-2125          ; 0 # So       OUNCE SIGN
-2126          ; 0 # L&       OHM SIGN
-2127          ; 0 # So       INVERTED OHM SIGN
-2128          ; 0 # L&       BLACK-LETTER CAPITAL Z
-2129          ; 0 # So       TURNED GREEK SMALL LETTER IOTA
-212A..212D    ; 0 # L&   [4] KELVIN SIGN..BLACK-LETTER CAPITAL C
-212E          ; 0 # So       ESTIMATED SYMBOL
-212F..2134    ; 0 # L&   [6] SCRIPT SMALL E..SCRIPT SMALL O
-2135..2138    ; 0 # Lo   [4] ALEF SYMBOL..DALET SYMBOL
-2139          ; 0 # L&       INFORMATION SOURCE
-213A..213B    ; 0 # So   [2] ROTATED CAPITAL Q..FACSIMILE SIGN
-213C..213F    ; 0 # L&   [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI
-2140..2144    ; 0 # Sm   [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y
-2145..2149    ; 0 # L&   [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J
-214A          ; 0 # So       PROPERTY LINE
-214B          ; 0 # Sm       TURNED AMPERSAND
-214C..214D    ; 0 # So   [2] PER SIGN..AKTIESELSKAB
-214E          ; 0 # L&       TURNED SMALL F
-214F          ; 0 # So       SYMBOL FOR SAMARITAN SOURCE
-2153..215F    ; 0 # No  [13] VULGAR FRACTION ONE THIRD..FRACTION NUMERATOR ONE
-2160..2182    ; 0 # Nl  [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND
-2183..2184    ; 0 # L&   [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C
-2185..2188    ; 0 # Nl   [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND
-2190..2194    ; 0 # Sm   [5] LEFTWARDS ARROW..LEFT RIGHT ARROW
-2195..2199    ; 0 # So   [5] UP DOWN ARROW..SOUTH WEST ARROW
-219A..219B    ; 0 # Sm   [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE
-219C..219F    ; 0 # So   [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW
-21A0          ; 0 # Sm       RIGHTWARDS TWO HEADED ARROW
-21A1..21A2    ; 0 # So   [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL
-21A3          ; 0 # Sm       RIGHTWARDS ARROW WITH TAIL
-21A4..21A5    ; 0 # So   [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR
-21A6          ; 0 # Sm       RIGHTWARDS ARROW FROM BAR
-21A7..21AD    ; 0 # So   [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW
-21AE          ; 0 # Sm       LEFT RIGHT ARROW WITH STROKE
-21AF..21CD    ; 0 # So  [31] DOWNWARDS ZIGZAG ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE
-21CE..21CF    ; 0 # Sm   [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE
-21D0..21D1    ; 0 # So   [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW
-21D2          ; 0 # Sm       RIGHTWARDS DOUBLE ARROW
-21D3          ; 0 # So       DOWNWARDS DOUBLE ARROW
-21D4          ; 0 # Sm       LEFT RIGHT DOUBLE ARROW
-21D5..21F3    ; 0 # So  [31] UP DOWN DOUBLE ARROW..UP DOWN WHITE ARROW
-21F4..22FF    ; 0 # Sm [268] RIGHT ARROW WITH SMALL CIRCLE..Z NOTATION BAG MEMBERSHIP
-2300..2307    ; 0 # So   [8] DIAMETER SIGN..WAVY LINE
-2308..230B    ; 0 # Sm   [4] LEFT CEILING..RIGHT FLOOR
-230C..231F    ; 0 # So  [20] BOTTOM RIGHT CROP..BOTTOM RIGHT CORNER
-2320..2321    ; 0 # Sm   [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL
-2322..2328    ; 0 # So   [7] FROWN..KEYBOARD
-2329          ; 0 # Ps       LEFT-POINTING ANGLE BRACKET
-232A          ; 0 # Pe       RIGHT-POINTING ANGLE BRACKET
-232B..237B    ; 0 # So  [81] ERASE TO THE LEFT..NOT CHECK MARK
-237C          ; 0 # Sm       RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
-237D..239A    ; 0 # So  [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL
-239B..23B3    ; 0 # Sm  [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM
-23B4..23DB    ; 0 # So  [40] TOP SQUARE BRACKET..FUSE
-23DC..23E1    ; 0 # Sm   [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET
-23E2..23E7    ; 0 # So   [6] WHITE TRAPEZIUM..ELECTRICAL INTERSECTION
-2400..2426    ; 0 # So  [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO
-2440..244A    ; 0 # So  [11] OCR HOOK..OCR DOUBLE BACKSLASH
-2460..249B    ; 0 # No  [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP
-249C..24E9    ; 0 # So  [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z
-24EA..24FF    ; 0 # No  [22] CIRCLED DIGIT ZERO..NEGATIVE CIRCLED DIGIT ZERO
-2500..25B6    ; 0 # So [183] BOX DRAWINGS LIGHT HORIZONTAL..BLACK RIGHT-POINTING TRIANGLE
-25B7          ; 0 # Sm       WHITE RIGHT-POINTING TRIANGLE
-25B8..25C0    ; 0 # So   [9] BLACK RIGHT-POINTING SMALL TRIANGLE..BLACK LEFT-POINTING TRIANGLE
-25C1          ; 0 # Sm       WHITE LEFT-POINTING TRIANGLE
-25C2..25F7    ; 0 # So  [54] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE CIRCLE WITH UPPER RIGHT QUADRANT
-25F8..25FF    ; 0 # Sm   [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE
-2600..266E    ; 0 # So [111] BLACK SUN WITH RAYS..MUSIC NATURAL SIGN
-266F          ; 0 # Sm       MUSIC SHARP SIGN
-2670..269D    ; 0 # So  [46] WEST SYRIAC CROSS..OUTLINED WHITE STAR
-26A0..26BC    ; 0 # So  [29] WARNING SIGN..SESQUIQUADRATE
-26C0..26C3    ; 0 # So   [4] WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING
-2701..2704    ; 0 # So   [4] UPPER BLADE SCISSORS..WHITE SCISSORS
-2706..2709    ; 0 # So   [4] TELEPHONE LOCATION SIGN..ENVELOPE
-270C..2727    ; 0 # So  [28] VICTORY HAND..WHITE FOUR POINTED STAR
-2729..274B    ; 0 # So  [35] STRESS OUTLINED WHITE STAR..HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
-274D          ; 0 # So       SHADOWED WHITE CIRCLE
-274F..2752    ; 0 # So   [4] LOWER RIGHT DROP-SHADOWED WHITE SQUARE..UPPER RIGHT SHADOWED WHITE SQUARE
-2756          ; 0 # So       BLACK DIAMOND MINUS WHITE X
-2758..275E    ; 0 # So   [7] LIGHT VERTICAL BAR..HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT
-2761..2767    ; 0 # So   [7] CURVED STEM PARAGRAPH SIGN ORNAMENT..ROTATED FLORAL HEART BULLET
-2768          ; 0 # Ps       MEDIUM LEFT PARENTHESIS ORNAMENT
-2769          ; 0 # Pe       MEDIUM RIGHT PARENTHESIS ORNAMENT
-276A          ; 0 # Ps       MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
-276B          ; 0 # Pe       MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
-276C          ; 0 # Ps       MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
-276D          ; 0 # Pe       MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
-276E          ; 0 # Ps       HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
-276F          ; 0 # Pe       HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
-2770          ; 0 # Ps       HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
-2771          ; 0 # Pe       HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
-2772          ; 0 # Ps       LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
-2773          ; 0 # Pe       LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
-2774          ; 0 # Ps       MEDIUM LEFT CURLY BRACKET ORNAMENT
-2775          ; 0 # Pe       MEDIUM RIGHT CURLY BRACKET ORNAMENT
-2776..2793    ; 0 # No  [30] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
-2794          ; 0 # So       HEAVY WIDE-HEADED RIGHTWARDS ARROW
-2798..27AF    ; 0 # So  [24] HEAVY SOUTH EAST ARROW..NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
-27B1..27BE    ; 0 # So  [14] NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW..OPEN-OUTLINED RIGHTWARDS ARROW
-27C0..27C4    ; 0 # Sm   [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET
-27C5          ; 0 # Ps       LEFT S-SHAPED BAG DELIMITER
-27C6          ; 0 # Pe       RIGHT S-SHAPED BAG DELIMITER
-27C7..27CA    ; 0 # Sm   [4] OR WITH DOT INSIDE..VERTICAL BAR WITH HORIZONTAL STROKE
-27CC          ; 0 # Sm       LONG DIVISION
-27D0..27E5    ; 0 # Sm  [22] WHITE DIAMOND WITH CENTRED DOT..WHITE SQUARE WITH RIGHTWARDS TICK
-27E6          ; 0 # Ps       MATHEMATICAL LEFT WHITE SQUARE BRACKET
-27E7          ; 0 # Pe       MATHEMATICAL RIGHT WHITE SQUARE BRACKET
-27E8          ; 0 # Ps       MATHEMATICAL LEFT ANGLE BRACKET
-27E9          ; 0 # Pe       MATHEMATICAL RIGHT ANGLE BRACKET
-27EA          ; 0 # Ps       MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
-27EB          ; 0 # Pe       MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
-27EC          ; 0 # Ps       MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
-27ED          ; 0 # Pe       MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
-27EE          ; 0 # Ps       MATHEMATICAL LEFT FLATTENED PARENTHESIS
-27EF          ; 0 # Pe       MATHEMATICAL RIGHT FLATTENED PARENTHESIS
-27F0..27FF    ; 0 # Sm  [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW
-2800..28FF    ; 0 # So [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678
-2900..2982    ; 0 # Sm [131] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..Z NOTATION TYPE COLON
-2983          ; 0 # Ps       LEFT WHITE CURLY BRACKET
-2984          ; 0 # Pe       RIGHT WHITE CURLY BRACKET
-2985          ; 0 # Ps       LEFT WHITE PARENTHESIS
-2986          ; 0 # Pe       RIGHT WHITE PARENTHESIS
-2987          ; 0 # Ps       Z NOTATION LEFT IMAGE BRACKET
-2988          ; 0 # Pe       Z NOTATION RIGHT IMAGE BRACKET
-2989          ; 0 # Ps       Z NOTATION LEFT BINDING BRACKET
-298A          ; 0 # Pe       Z NOTATION RIGHT BINDING BRACKET
-298B          ; 0 # Ps       LEFT SQUARE BRACKET WITH UNDERBAR
-298C          ; 0 # Pe       RIGHT SQUARE BRACKET WITH UNDERBAR
-298D          ; 0 # Ps       LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
-298E          ; 0 # Pe       RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
-298F          ; 0 # Ps       LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
-2990          ; 0 # Pe       RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
-2991          ; 0 # Ps       LEFT ANGLE BRACKET WITH DOT
-2992          ; 0 # Pe       RIGHT ANGLE BRACKET WITH DOT
-2993          ; 0 # Ps       LEFT ARC LESS-THAN BRACKET
-2994          ; 0 # Pe       RIGHT ARC GREATER-THAN BRACKET
-2995          ; 0 # Ps       DOUBLE LEFT ARC GREATER-THAN BRACKET
-2996          ; 0 # Pe       DOUBLE RIGHT ARC LESS-THAN BRACKET
-2997          ; 0 # Ps       LEFT BLACK TORTOISE SHELL BRACKET
-2998          ; 0 # Pe       RIGHT BLACK TORTOISE SHELL BRACKET
-2999..29D7    ; 0 # Sm  [63] DOTTED FENCE..BLACK HOURGLASS
-29D8          ; 0 # Ps       LEFT WIGGLY FENCE
-29D9          ; 0 # Pe       RIGHT WIGGLY FENCE
-29DA          ; 0 # Ps       LEFT DOUBLE WIGGLY FENCE
-29DB          ; 0 # Pe       RIGHT DOUBLE WIGGLY FENCE
-29DC..29FB    ; 0 # Sm  [32] INCOMPLETE INFINITY..TRIPLE PLUS
-29FC          ; 0 # Ps       LEFT-POINTING CURVED ANGLE BRACKET
-29FD          ; 0 # Pe       RIGHT-POINTING CURVED ANGLE BRACKET
-29FE..2AFF    ; 0 # Sm [258] TINY..N-ARY WHITE VERTICAL BAR
-2B00..2B2F    ; 0 # So  [48] NORTH EAST WHITE ARROW..WHITE VERTICAL ELLIPSE
-2B30..2B44    ; 0 # Sm  [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET
-2B45..2B46    ; 0 # So   [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW
-2B47..2B4C    ; 0 # Sm   [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
-2B50..2B54    ; 0 # So   [5] WHITE MEDIUM STAR..WHITE RIGHT-POINTING PENTAGON
-2C00..2C2E    ; 0 # L&  [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
-2C30..2C5E    ; 0 # L&  [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE
-2C60..2C6F    ; 0 # L&  [16] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN CAPITAL LETTER TURNED A
-2C71..2C7C    ; 0 # L&  [12] LATIN SMALL LETTER V WITH RIGHT HOOK..LATIN SUBSCRIPT SMALL LETTER J
-2C7D          ; 0 # Lm       MODIFIER LETTER CAPITAL V
-2C80..2CE4    ; 0 # L& [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI
-2CE5..2CEA    ; 0 # So   [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA
-2CF9..2CFC    ; 0 # Po   [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER
-2CFD          ; 0 # No       COPTIC FRACTION ONE HALF
-2CFE..2CFF    ; 0 # Po   [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER
-2D00..2D25    ; 0 # L&  [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE
-2D30..2D65    ; 0 # Lo  [54] TIFINAGH LETTER YA..TIFINAGH LETTER YAZZ
-2D6F          ; 0 # Lm       TIFINAGH MODIFIER LETTER LABIALIZATION MARK
-2D80..2D96    ; 0 # Lo  [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE
-2DA0..2DA6    ; 0 # Lo   [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO
-2DA8..2DAE    ; 0 # Lo   [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO
-2DB0..2DB6    ; 0 # Lo   [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO
-2DB8..2DBE    ; 0 # Lo   [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO
-2DC0..2DC6    ; 0 # Lo   [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO
-2DC8..2DCE    ; 0 # Lo   [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO
-2DD0..2DD6    ; 0 # Lo   [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO
-2DD8..2DDE    ; 0 # Lo   [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO
-2E00..2E01    ; 0 # Po   [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
-2E02          ; 0 # Pi       LEFT SUBSTITUTION BRACKET
-2E03          ; 0 # Pf       RIGHT SUBSTITUTION BRACKET
-2E04          ; 0 # Pi       LEFT DOTTED SUBSTITUTION BRACKET
-2E05          ; 0 # Pf       RIGHT DOTTED SUBSTITUTION BRACKET
-2E06..2E08    ; 0 # Po   [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER
-2E09          ; 0 # Pi       LEFT TRANSPOSITION BRACKET
-2E0A          ; 0 # Pf       RIGHT TRANSPOSITION BRACKET
-2E0B          ; 0 # Po       RAISED SQUARE
-2E0C          ; 0 # Pi       LEFT RAISED OMISSION BRACKET
-2E0D          ; 0 # Pf       RIGHT RAISED OMISSION BRACKET
-2E0E..2E16    ; 0 # Po   [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE
-2E17          ; 0 # Pd       DOUBLE OBLIQUE HYPHEN
-2E18..2E19    ; 0 # Po   [2] INVERTED INTERROBANG..PALM BRANCH
-2E1A          ; 0 # Pd       HYPHEN WITH DIAERESIS
-2E1B          ; 0 # Po       TILDE WITH RING ABOVE
-2E1C          ; 0 # Pi       LEFT LOW PARAPHRASE BRACKET
-2E1D          ; 0 # Pf       RIGHT LOW PARAPHRASE BRACKET
-2E1E..2E1F    ; 0 # Po   [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW
-2E20          ; 0 # Pi       LEFT VERTICAL BAR WITH QUILL
-2E21          ; 0 # Pf       RIGHT VERTICAL BAR WITH QUILL
-2E22          ; 0 # Ps       TOP LEFT HALF BRACKET
-2E23          ; 0 # Pe       TOP RIGHT HALF BRACKET
-2E24          ; 0 # Ps       BOTTOM LEFT HALF BRACKET
-2E25          ; 0 # Pe       BOTTOM RIGHT HALF BRACKET
-2E26          ; 0 # Ps       LEFT SIDEWAYS U BRACKET
-2E27          ; 0 # Pe       RIGHT SIDEWAYS U BRACKET
-2E28          ; 0 # Ps       LEFT DOUBLE PARENTHESIS
-2E29          ; 0 # Pe       RIGHT DOUBLE PARENTHESIS
-2E2A..2E2E    ; 0 # Po   [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK
-2E2F          ; 0 # Lm       VERTICAL TILDE
-2E30          ; 0 # Po       RING POINT
-2E80..2E99    ; 0 # So  [26] CJK RADICAL REPEAT..CJK RADICAL RAP
-2E9B..2EF3    ; 0 # So  [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE
-2F00..2FD5    ; 0 # So [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE
-2FF0..2FFB    ; 0 # So  [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
-3000          ; 0 # Zs       IDEOGRAPHIC SPACE
-3001..3003    ; 0 # Po   [3] IDEOGRAPHIC COMMA..DITTO MARK
-3004          ; 0 # So       JAPANESE INDUSTRIAL STANDARD SYMBOL
-3005          ; 0 # Lm       IDEOGRAPHIC ITERATION MARK
-3006          ; 0 # Lo       IDEOGRAPHIC CLOSING MARK
-3007          ; 0 # Nl       IDEOGRAPHIC NUMBER ZERO
-3008          ; 0 # Ps       LEFT ANGLE BRACKET
-3009          ; 0 # Pe       RIGHT ANGLE BRACKET
-300A          ; 0 # Ps       LEFT DOUBLE ANGLE BRACKET
-300B          ; 0 # Pe       RIGHT DOUBLE ANGLE BRACKET
-300C          ; 0 # Ps       LEFT CORNER BRACKET
-300D          ; 0 # Pe       RIGHT CORNER BRACKET
-300E          ; 0 # Ps       LEFT WHITE CORNER BRACKET
-300F          ; 0 # Pe       RIGHT WHITE CORNER BRACKET
-3010          ; 0 # Ps       LEFT BLACK LENTICULAR BRACKET
-3011          ; 0 # Pe       RIGHT BLACK LENTICULAR BRACKET
-3012..3013    ; 0 # So   [2] POSTAL MARK..GETA MARK
-3014          ; 0 # Ps       LEFT TORTOISE SHELL BRACKET
-3015          ; 0 # Pe       RIGHT TORTOISE SHELL BRACKET
-3016          ; 0 # Ps       LEFT WHITE LENTICULAR BRACKET
-3017          ; 0 # Pe       RIGHT WHITE LENTICULAR BRACKET
-3018          ; 0 # Ps       LEFT WHITE TORTOISE SHELL BRACKET
-3019          ; 0 # Pe       RIGHT WHITE TORTOISE SHELL BRACKET
-301A          ; 0 # Ps       LEFT WHITE SQUARE BRACKET
-301B          ; 0 # Pe       RIGHT WHITE SQUARE BRACKET
-301C          ; 0 # Pd       WAVE DASH
-301D          ; 0 # Ps       REVERSED DOUBLE PRIME QUOTATION MARK
-301E..301F    ; 0 # Pe   [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK
-3020          ; 0 # So       POSTAL MARK FACE
-3021..3029    ; 0 # Nl   [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE
-3030          ; 0 # Pd       WAVY DASH
-3031..3035    ; 0 # Lm   [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF
-3036..3037    ; 0 # So   [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL
-3038..303A    ; 0 # Nl   [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY
-303B          ; 0 # Lm       VERTICAL IDEOGRAPHIC ITERATION MARK
-303C          ; 0 # Lo       MASU MARK
-303D          ; 0 # Po       PART ALTERNATION MARK
-303E..303F    ; 0 # So   [2] IDEOGRAPHIC VARIATION INDICATOR..IDEOGRAPHIC HALF FILL SPACE
-3041..3096    ; 0 # Lo  [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE
-309B..309C    ; 0 # Sk   [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
-309D..309E    ; 0 # Lm   [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
-309F          ; 0 # Lo       HIRAGANA DIGRAPH YORI
-30A0          ; 0 # Pd       KATAKANA-HIRAGANA DOUBLE HYPHEN
-30A1..30FA    ; 0 # Lo  [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO
-30FB          ; 0 # Po       KATAKANA MIDDLE DOT
-30FC..30FE    ; 0 # Lm   [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK
-30FF          ; 0 # Lo       KATAKANA DIGRAPH KOTO
-3105..312D    ; 0 # Lo  [41] BOPOMOFO LETTER B..BOPOMOFO LETTER IH
-3131..318E    ; 0 # Lo  [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
-3190..3191    ; 0 # So   [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK
-3192..3195    ; 0 # No   [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK
-3196..319F    ; 0 # So  [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK
-31A0..31B7    ; 0 # Lo  [24] BOPOMOFO LETTER BU..BOPOMOFO FINAL LETTER H
-31C0..31E3    ; 0 # So  [36] CJK STROKE T..CJK STROKE Q
-31F0..31FF    ; 0 # Lo  [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
-3200..321E    ; 0 # So  [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU
-3220..3229    ; 0 # No  [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN
-322A..3243    ; 0 # So  [26] PARENTHESIZED IDEOGRAPH MOON..PARENTHESIZED IDEOGRAPH REACH
-3250          ; 0 # So       PARTNERSHIP SIGN
-3251..325F    ; 0 # No  [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE
-3260..327F    ; 0 # So  [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL
-3280..3289    ; 0 # No  [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN
-328A..32B0    ; 0 # So  [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT
-32B1..32BF    ; 0 # No  [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY
-32C0..32FE    ; 0 # So  [63] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..CIRCLED KATAKANA WO
-3300..33FF    ; 0 # So [256] SQUARE APAATO..SQUARE GAL
-3400..4DB5    ; 0 # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
-4DC0..4DFF    ; 0 # So  [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION
-4E00..9FC3    ; 0 # Lo [20932] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FC3
-A000..A014    ; 0 # Lo  [21] YI SYLLABLE IT..YI SYLLABLE E
-A015          ; 0 # Lm       YI SYLLABLE WU
-A016..A48C    ; 0 # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
-A490..A4C6    ; 0 # So  [55] YI RADICAL QOT..YI RADICAL KE
-A500..A60B    ; 0 # Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG
-A60C          ; 0 # Lm       VAI SYLLABLE LENGTHENER
-A60D..A60F    ; 0 # Po   [3] VAI COMMA..VAI QUESTION MARK
-A610..A61F    ; 0 # Lo  [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG
-A620..A629    ; 0 # Nd  [10] VAI DIGIT ZERO..VAI DIGIT NINE
-A62A..A62B    ; 0 # Lo   [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO
-A640..A65F    ; 0 # L&  [32] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER YN
-A662..A66D    ; 0 # L&  [12] CYRILLIC CAPITAL LETTER SOFT DE..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O
-A66E          ; 0 # Lo       CYRILLIC LETTER MULTIOCULAR O
-A670..A672    ; 0 # Me   [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
-A673          ; 0 # Po       SLAVONIC ASTERISK
-A67E          ; 0 # Po       CYRILLIC KAVYKA
-A67F          ; 0 # Lm       CYRILLIC PAYEROK
-A680..A697    ; 0 # L&  [24] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER SHWE
-A700..A716    ; 0 # Sk  [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR
-A717..A71F    ; 0 # Lm   [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK
-A720..A721    ; 0 # Sk   [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE
-A722..A76F    ; 0 # L&  [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON
-A770          ; 0 # Lm       MODIFIER LETTER US
-A771..A787    ; 0 # L&  [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T
-A788          ; 0 # Lm       MODIFIER LETTER LOW CIRCUMFLEX ACCENT
-A789..A78A    ; 0 # Sk   [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN
-A78B..A78C    ; 0 # L&   [2] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER SALTILLO
-A7FB..A801    ; 0 # Lo   [7] LATIN EPIGRAPHIC LETTER REVERSED F..SYLOTI NAGRI LETTER I
-A802          ; 0 # Mn       SYLOTI NAGRI SIGN DVISVARA
-A803..A805    ; 0 # Lo   [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O
-A807..A80A    ; 0 # Lo   [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO
-A80B          ; 0 # Mn       SYLOTI NAGRI SIGN ANUSVARA
-A80C..A822    ; 0 # Lo  [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO
-A823..A824    ; 0 # Mc   [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
-A825..A826    ; 0 # Mn   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
-A827          ; 0 # Mc       SYLOTI NAGRI VOWEL SIGN OO
-A828..A82B    ; 0 # So   [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4
-A840..A873    ; 0 # Lo  [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU
-A874..A877    ; 0 # Po   [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD
-A880..A881    ; 0 # Mc   [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
-A882..A8B3    ; 0 # Lo  [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA
-A8B4..A8C3    ; 0 # Mc  [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
-A8CE..A8CF    ; 0 # Po   [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA
-A8D0..A8D9    ; 0 # Nd  [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE
-A900..A909    ; 0 # Nd  [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE
-A90A..A925    ; 0 # Lo  [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO
-A926..A92A    ; 0 # Mn   [5] KAYAH LI VOWEL UE..KAYAH LI VOWEL O
-A92E..A92F    ; 0 # Po   [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA
-A930..A946    ; 0 # Lo  [23] REJANG LETTER KA..REJANG LETTER A
-A947..A951    ; 0 # Mn  [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
-A952          ; 0 # Mc       REJANG CONSONANT SIGN H
-A95F          ; 0 # Po       REJANG SECTION MARK
-AA00..AA28    ; 0 # Lo  [41] CHAM LETTER A..CHAM LETTER HA
-AA29..AA2E    ; 0 # Mn   [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
-AA2F..AA30    ; 0 # Mc   [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
-AA31..AA32    ; 0 # Mn   [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
-AA33..AA34    ; 0 # Mc   [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
-AA35..AA36    ; 0 # Mn   [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
-AA40..AA42    ; 0 # Lo   [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG
-AA43          ; 0 # Mn       CHAM CONSONANT SIGN FINAL NG
-AA44..AA4B    ; 0 # Lo   [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS
-AA4C          ; 0 # Mn       CHAM CONSONANT SIGN FINAL M
-AA4D          ; 0 # Mc       CHAM CONSONANT SIGN FINAL H
-AA50..AA59    ; 0 # Nd  [10] CHAM DIGIT ZERO..CHAM DIGIT NINE
-AA5C..AA5F    ; 0 # Po   [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA
-AC00..D7A3    ; 0 # Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH
-E000..F8FF    ; 0 # Co [6400] <private-use-E000>..<private-use-F8FF>
-F900..FA2D    ; 0 # Lo [302] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA2D
-FA30..FA6A    ; 0 # Lo  [59] CJK COMPATIBILITY IDEOGRAPH-FA30..CJK COMPATIBILITY IDEOGRAPH-FA6A
-FA70..FAD9    ; 0 # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
-FB00..FB06    ; 0 # L&   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
-FB13..FB17    ; 0 # L&   [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
-FB1D          ; 0 # Lo       HEBREW LETTER YOD WITH HIRIQ
-FB1F..FB28    ; 0 # Lo  [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV
-FB29          ; 0 # Sm       HEBREW LETTER ALTERNATIVE PLUS SIGN
-FB2A..FB36    ; 0 # Lo  [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH
-FB38..FB3C    ; 0 # Lo   [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH
-FB3E          ; 0 # Lo       HEBREW LETTER MEM WITH DAGESH
-FB40..FB41    ; 0 # Lo   [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH
-FB43..FB44    ; 0 # Lo   [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH
-FB46..FBB1    ; 0 # Lo [108] HEBREW LETTER TSADI WITH DAGESH..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
-FBD3..FD3D    ; 0 # Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM
-FD3E          ; 0 # Ps       ORNATE LEFT PARENTHESIS
-FD3F          ; 0 # Pe       ORNATE RIGHT PARENTHESIS
-FD50..FD8F    ; 0 # Lo  [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM
-FD92..FDC7    ; 0 # Lo  [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM
-FDF0..FDFB    ; 0 # Lo  [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU
-FDFC          ; 0 # Sc       RIAL SIGN
-FDFD          ; 0 # So       ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM
-FE00..FE0F    ; 0 # Mn  [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
-FE10..FE16    ; 0 # Po   [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK
-FE17          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
-FE18          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET
-FE19          ; 0 # Po       PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
-FE30          ; 0 # Po       PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
-FE31..FE32    ; 0 # Pd   [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH
-FE33..FE34    ; 0 # Pc   [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
-FE35          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
-FE36          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
-FE37          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
-FE38          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
-FE39          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
-FE3A          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
-FE3B          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
-FE3C          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
-FE3D          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
-FE3E          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
-FE3F          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
-FE40          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
-FE41          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
-FE42          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
-FE43          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
-FE44          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
-FE45..FE46    ; 0 # Po   [2] SESAME DOT..WHITE SESAME DOT
-FE47          ; 0 # Ps       PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
-FE48          ; 0 # Pe       PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
-FE49..FE4C    ; 0 # Po   [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE
-FE4D..FE4F    ; 0 # Pc   [3] DASHED LOW LINE..WAVY LOW LINE
-FE50..FE52    ; 0 # Po   [3] SMALL COMMA..SMALL FULL STOP
-FE54..FE57    ; 0 # Po   [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK
-FE58          ; 0 # Pd       SMALL EM DASH
-FE59          ; 0 # Ps       SMALL LEFT PARENTHESIS
-FE5A          ; 0 # Pe       SMALL RIGHT PARENTHESIS
-FE5B          ; 0 # Ps       SMALL LEFT CURLY BRACKET
-FE5C          ; 0 # Pe       SMALL RIGHT CURLY BRACKET
-FE5D          ; 0 # Ps       SMALL LEFT TORTOISE SHELL BRACKET
-FE5E          ; 0 # Pe       SMALL RIGHT TORTOISE SHELL BRACKET
-FE5F..FE61    ; 0 # Po   [3] SMALL NUMBER SIGN..SMALL ASTERISK
-FE62          ; 0 # Sm       SMALL PLUS SIGN
-FE63          ; 0 # Pd       SMALL HYPHEN-MINUS
-FE64..FE66    ; 0 # Sm   [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN
-FE68          ; 0 # Po       SMALL REVERSE SOLIDUS
-FE69          ; 0 # Sc       SMALL DOLLAR SIGN
-FE6A..FE6B    ; 0 # Po   [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT
-FE70..FE74    ; 0 # Lo   [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM
-FE76..FEFC    ; 0 # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM
-FEFF          ; 0 # Cf       ZERO WIDTH NO-BREAK SPACE
-FF01..FF03    ; 0 # Po   [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN
-FF04          ; 0 # Sc       FULLWIDTH DOLLAR SIGN
-FF05..FF07    ; 0 # Po   [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE
-FF08          ; 0 # Ps       FULLWIDTH LEFT PARENTHESIS
-FF09          ; 0 # Pe       FULLWIDTH RIGHT PARENTHESIS
-FF0A          ; 0 # Po       FULLWIDTH ASTERISK
-FF0B          ; 0 # Sm       FULLWIDTH PLUS SIGN
-FF0C          ; 0 # Po       FULLWIDTH COMMA
-FF0D          ; 0 # Pd       FULLWIDTH HYPHEN-MINUS
-FF0E..FF0F    ; 0 # Po   [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS
-FF10..FF19    ; 0 # Nd  [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE
-FF1A..FF1B    ; 0 # Po   [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON
-FF1C..FF1E    ; 0 # Sm   [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN
-FF1F..FF20    ; 0 # Po   [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT
-FF21..FF3A    ; 0 # L&  [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
-FF3B          ; 0 # Ps       FULLWIDTH LEFT SQUARE BRACKET
-FF3C          ; 0 # Po       FULLWIDTH REVERSE SOLIDUS
-FF3D          ; 0 # Pe       FULLWIDTH RIGHT SQUARE BRACKET
-FF3E          ; 0 # Sk       FULLWIDTH CIRCUMFLEX ACCENT
-FF3F          ; 0 # Pc       FULLWIDTH LOW LINE
-FF40          ; 0 # Sk       FULLWIDTH GRAVE ACCENT
-FF41..FF5A    ; 0 # L&  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z
-FF5B          ; 0 # Ps       FULLWIDTH LEFT CURLY BRACKET
-FF5C          ; 0 # Sm       FULLWIDTH VERTICAL LINE
-FF5D          ; 0 # Pe       FULLWIDTH RIGHT CURLY BRACKET
-FF5E          ; 0 # Sm       FULLWIDTH TILDE
-FF5F          ; 0 # Ps       FULLWIDTH LEFT WHITE PARENTHESIS
-FF60          ; 0 # Pe       FULLWIDTH RIGHT WHITE PARENTHESIS
-FF61          ; 0 # Po       HALFWIDTH IDEOGRAPHIC FULL STOP
-FF62          ; 0 # Ps       HALFWIDTH LEFT CORNER BRACKET
-FF63          ; 0 # Pe       HALFWIDTH RIGHT CORNER BRACKET
-FF64..FF65    ; 0 # Po   [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT
-FF66..FF6F    ; 0 # Lo  [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU
-FF70          ; 0 # Lm       HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
-FF71..FF9D    ; 0 # Lo  [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N
-FF9E..FF9F    ; 0 # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
-FFA0..FFBE    ; 0 # Lo  [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH
-FFC2..FFC7    ; 0 # Lo   [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E
-FFCA..FFCF    ; 0 # Lo   [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE
-FFD2..FFD7    ; 0 # Lo   [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU
-FFDA..FFDC    ; 0 # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I
-FFE0..FFE1    ; 0 # Sc   [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN
-FFE2          ; 0 # Sm       FULLWIDTH NOT SIGN
-FFE3          ; 0 # Sk       FULLWIDTH MACRON
-FFE4          ; 0 # So       FULLWIDTH BROKEN BAR
-FFE5..FFE6    ; 0 # Sc   [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN
-FFE8          ; 0 # So       HALFWIDTH FORMS LIGHT VERTICAL
-FFE9..FFEC    ; 0 # Sm   [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW
-FFED..FFEE    ; 0 # So   [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE
-FFF9..FFFB    ; 0 # Cf   [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
-FFFC..FFFD    ; 0 # So   [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHARACTER
-10000..1000B  ; 0 # Lo  [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE
-1000D..10026  ; 0 # Lo  [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO
-10028..1003A  ; 0 # Lo  [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO
-1003C..1003D  ; 0 # Lo   [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE
-1003F..1004D  ; 0 # Lo  [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO
-10050..1005D  ; 0 # Lo  [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089
-10080..100FA  ; 0 # Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305
-10100..10101  ; 0 # Po   [2] AEGEAN WORD SEPARATOR LINE..AEGEAN WORD SEPARATOR DOT
-10102         ; 0 # So       AEGEAN CHECK MARK
-10107..10133  ; 0 # No  [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND
-10137..1013F  ; 0 # So   [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT
-10140..10174  ; 0 # Nl  [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS
-10175..10178  ; 0 # No   [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN
-10179..10189  ; 0 # So  [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN
-1018A         ; 0 # No       GREEK ZERO SIGN
-10190..1019B  ; 0 # So  [12] ROMAN SEXTANS SIGN..ROMAN CENTURIAL SIGN
-101D0..101FC  ; 0 # So  [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND
-10280..1029C  ; 0 # Lo  [29] LYCIAN LETTER A..LYCIAN LETTER X
-102A0..102D0  ; 0 # Lo  [49] CARIAN LETTER A..CARIAN LETTER UUU3
-10300..1031E  ; 0 # Lo  [31] OLD ITALIC LETTER A..OLD ITALIC LETTER UU
-10320..10323  ; 0 # No   [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY
-10330..10340  ; 0 # Lo  [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA
-10341         ; 0 # Nl       GOTHIC LETTER NINETY
-10342..10349  ; 0 # Lo   [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL
-1034A         ; 0 # Nl       GOTHIC LETTER NINE HUNDRED
-10380..1039D  ; 0 # Lo  [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU
-1039F         ; 0 # Po       UGARITIC WORD DIVIDER
-103A0..103C3  ; 0 # Lo  [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA
-103C8..103CF  ; 0 # Lo   [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH
-103D0         ; 0 # Po       OLD PERSIAN WORD DIVIDER
-103D1..103D5  ; 0 # Nl   [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED
-10400..1044F  ; 0 # L&  [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW
-10450..1049D  ; 0 # Lo  [78] SHAVIAN LETTER PEEP..OSMANYA LETTER OO
-104A0..104A9  ; 0 # Nd  [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE
-10800..10805  ; 0 # Lo   [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA
-10808         ; 0 # Lo       CYPRIOT SYLLABLE JO
-1080A..10835  ; 0 # Lo  [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO
-10837..10838  ; 0 # Lo   [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE
-1083C         ; 0 # Lo       CYPRIOT SYLLABLE ZA
-1083F         ; 0 # Lo       CYPRIOT SYLLABLE ZO
-10900..10915  ; 0 # Lo  [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU
-10916..10919  ; 0 # No   [4] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER ONE HUNDRED
-1091F         ; 0 # Po       PHOENICIAN WORD SEPARATOR
-10920..10939  ; 0 # Lo  [26] LYDIAN LETTER A..LYDIAN LETTER C
-1093F         ; 0 # Po       LYDIAN TRIANGULAR MARK
-10A00         ; 0 # Lo       KHAROSHTHI LETTER A
-10A01..10A03  ; 0 # Mn   [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
-10A05..10A06  ; 0 # Mn   [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
-10A0C         ; 0 # Mn       KHAROSHTHI VOWEL LENGTH MARK
-10A0E         ; 0 # Mn       KHAROSHTHI SIGN ANUSVARA
-10A10..10A13  ; 0 # Lo   [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA
-10A15..10A17  ; 0 # Lo   [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA
-10A19..10A33  ; 0 # Lo  [27] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER TTTHA
-10A40..10A47  ; 0 # No   [8] KHAROSHTHI DIGIT ONE..KHAROSHTHI NUMBER ONE THOUSAND
-10A50..10A58  ; 0 # Po   [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES
-12000..1236E  ; 0 # Lo [879] CUNEIFORM SIGN A..CUNEIFORM SIGN ZUM
-12400..12462  ; 0 # Nl  [99] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER
-12470..12473  ; 0 # Po   [4] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON
-1D000..1D0F5  ; 0 # So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO
-1D100..1D126  ; 0 # So  [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2
-1D129..1D164  ; 0 # So  [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
-1D16A..1D16C  ; 0 # So   [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3
-1D173..1D17A  ; 0 # Cf   [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
-1D183..1D184  ; 0 # So   [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN
-1D18C..1D1A9  ; 0 # So  [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH
-1D1AE..1D1DD  ; 0 # So  [48] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL PES SUBPUNCTIS
-1D200..1D241  ; 0 # So  [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54
-1D245         ; 0 # So       GREEK MUSICAL LEIMMA
-1D300..1D356  ; 0 # So  [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
-1D360..1D371  ; 0 # No  [18] COUNTING ROD UNIT DIGIT ONE..COUNTING ROD TENS DIGIT NINE
-1D400..1D454  ; 0 # L&  [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G
-1D456..1D49C  ; 0 # L&  [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A
-1D49E..1D49F  ; 0 # L&   [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D
-1D4A2         ; 0 # L&       MATHEMATICAL SCRIPT CAPITAL G
-1D4A5..1D4A6  ; 0 # L&   [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K
-1D4A9..1D4AC  ; 0 # L&   [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q
-1D4AE..1D4B9  ; 0 # L&  [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D
-1D4BB         ; 0 # L&       MATHEMATICAL SCRIPT SMALL F
-1D4BD..1D4C3  ; 0 # L&   [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N
-1D4C5..1D505  ; 0 # L&  [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B
-1D507..1D50A  ; 0 # L&   [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G
-1D50D..1D514  ; 0 # L&   [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q
-1D516..1D51C  ; 0 # L&   [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y
-1D51E..1D539  ; 0 # L&  [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B
-1D53B..1D53E  ; 0 # L&   [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G
-1D540..1D544  ; 0 # L&   [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M
-1D546         ; 0 # L&       MATHEMATICAL DOUBLE-STRUCK CAPITAL O
-1D54A..1D550  ; 0 # L&   [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
-1D552..1D6A5  ; 0 # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J
-1D6A8..1D6C0  ; 0 # L&  [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA
-1D6C1         ; 0 # Sm       MATHEMATICAL BOLD NABLA
-1D6C2..1D6DA  ; 0 # L&  [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA
-1D6DB         ; 0 # Sm       MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
-1D6DC..1D6FA  ; 0 # L&  [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA
-1D6FB         ; 0 # Sm       MATHEMATICAL ITALIC NABLA
-1D6FC..1D714  ; 0 # L&  [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA
-1D715         ; 0 # Sm       MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
-1D716..1D734  ; 0 # L&  [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
-1D735         ; 0 # Sm       MATHEMATICAL BOLD ITALIC NABLA
-1D736..1D74E  ; 0 # L&  [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA
-1D74F         ; 0 # Sm       MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
-1D750..1D76E  ; 0 # L&  [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
-1D76F         ; 0 # Sm       MATHEMATICAL SANS-SERIF BOLD NABLA
-1D770..1D788  ; 0 # L&  [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
-1D789         ; 0 # Sm       MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
-1D78A..1D7A8  ; 0 # L&  [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
-1D7A9         ; 0 # Sm       MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
-1D7AA..1D7C2  ; 0 # L&  [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
-1D7C3         ; 0 # Sm       MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
-1D7C4..1D7CB  ; 0 # L&   [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA
-1D7CE..1D7FF  ; 0 # Nd  [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE
-1F000..1F02B  ; 0 # So  [44] MAHJONG TILE EAST WIND..MAHJONG TILE BACK
-1F030..1F093  ; 0 # So [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06
-20000..2A6D6  ; 0 # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
-2F800..2FA1D  ; 0 # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
-E0001         ; 0 # Cf       LANGUAGE TAG
-E0020..E007F  ; 0 # Cf  [96] TAG SPACE..CANCEL TAG
-E0100..E01EF  ; 0 # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
-F0000..FFFFD  ; 0 # Co [65534] <private-use-F0000>..<private-use-FFFFD>
-100000..10FFFD; 0 # Co [65534] <private-use-100000>..<private-use-10FFFD>
-
-# The above property value applies to 875931 code points not listed here.
-# Total code points: 1113611
-
-# ================================================
-
-# Canonical_Combining_Class=Overlay
-
-0334..0338    ; 1 # Mn   [5] COMBINING TILDE OVERLAY..COMBINING LONG SOLIDUS OVERLAY
-20D2..20D3    ; 1 # Mn   [2] COMBINING LONG VERTICAL LINE OVERLAY..COMBINING SHORT VERTICAL LINE OVERLAY
-20D8..20DA    ; 1 # Mn   [3] COMBINING RING OVERLAY..COMBINING ANTICLOCKWISE RING OVERLAY
-20E5..20E6    ; 1 # Mn   [2] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING DOUBLE VERTICAL STROKE OVERLAY
-20EA..20EB    ; 1 # Mn   [2] COMBINING LEFTWARDS ARROW OVERLAY..COMBINING LONG DOUBLE SOLIDUS OVERLAY
-10A39         ; 1 # Mn       KHAROSHTHI SIGN CAUDA
-1D167..1D169  ; 1 # Mn   [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
-
-# Total code points: 18
-
-# ================================================
-
-# Canonical_Combining_Class=Nukta
-
-093C          ; 7 # Mn       DEVANAGARI SIGN NUKTA
-09BC          ; 7 # Mn       BENGALI SIGN NUKTA
-0A3C          ; 7 # Mn       GURMUKHI SIGN NUKTA
-0ABC          ; 7 # Mn       GUJARATI SIGN NUKTA
-0B3C          ; 7 # Mn       ORIYA SIGN NUKTA
-0CBC          ; 7 # Mn       KANNADA SIGN NUKTA
-1037          ; 7 # Mn       MYANMAR SIGN DOT BELOW
-1B34          ; 7 # Mn       BALINESE SIGN REREKAN
-1C37          ; 7 # Mn       LEPCHA SIGN NUKTA
-
-# Total code points: 9
-
-# ================================================
-
-# Canonical_Combining_Class=Kana_Voicing
-
-3099..309A    ; 8 # Mn   [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
-
-# Total code points: 2
-
-# ================================================
-
-# Canonical_Combining_Class=Virama
-
-094D          ; 9 # Mn       DEVANAGARI SIGN VIRAMA
-09CD          ; 9 # Mn       BENGALI SIGN VIRAMA
-0A4D          ; 9 # Mn       GURMUKHI SIGN VIRAMA
-0ACD          ; 9 # Mn       GUJARATI SIGN VIRAMA
-0B4D          ; 9 # Mn       ORIYA SIGN VIRAMA
-0BCD          ; 9 # Mn       TAMIL SIGN VIRAMA
-0C4D          ; 9 # Mn       TELUGU SIGN VIRAMA
-0CCD          ; 9 # Mn       KANNADA SIGN VIRAMA
-0D4D          ; 9 # Mn       MALAYALAM SIGN VIRAMA
-0DCA          ; 9 # Mn       SINHALA SIGN AL-LAKUNA
-0E3A          ; 9 # Mn       THAI CHARACTER PHINTHU
-0F84          ; 9 # Mn       TIBETAN MARK HALANTA
-1039..103A    ; 9 # Mn   [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
-1714          ; 9 # Mn       TAGALOG SIGN VIRAMA
-1734          ; 9 # Mn       HANUNOO SIGN PAMUDPOD
-17D2          ; 9 # Mn       KHMER SIGN COENG
-1B44          ; 9 # Mc       BALINESE ADEG ADEG
-1BAA          ; 9 # Mc       SUNDANESE SIGN PAMAAEH
-A806          ; 9 # Mn       SYLOTI NAGRI SIGN HASANTA
-A8C4          ; 9 # Mn       SAURASHTRA SIGN VIRAMA
-A953          ; 9 # Mc       REJANG VIRAMA
-10A3F         ; 9 # Mn       KHAROSHTHI VIRAMA
-
-# Total code points: 23
-
-# ================================================
-
-# Canonical_Combining_Class=10
-
-05B0          ; 10 # Mn       HEBREW POINT SHEVA
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=11
-
-05B1          ; 11 # Mn       HEBREW POINT HATAF SEGOL
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=12
-
-05B2          ; 12 # Mn       HEBREW POINT HATAF PATAH
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=13
-
-05B3          ; 13 # Mn       HEBREW POINT HATAF QAMATS
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=14
-
-05B4          ; 14 # Mn       HEBREW POINT HIRIQ
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=15
-
-05B5          ; 15 # Mn       HEBREW POINT TSERE
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=16
-
-05B6          ; 16 # Mn       HEBREW POINT SEGOL
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=17
-
-05B7          ; 17 # Mn       HEBREW POINT PATAH
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=18
-
-05B8          ; 18 # Mn       HEBREW POINT QAMATS
-05C7          ; 18 # Mn       HEBREW POINT QAMATS QATAN
-
-# Total code points: 2
-
-# ================================================
-
-# Canonical_Combining_Class=19
-
-05B9..05BA    ; 19 # Mn   [2] HEBREW POINT HOLAM..HEBREW POINT HOLAM HASER FOR VAV
-
-# Total code points: 2
-
-# ================================================
-
-# Canonical_Combining_Class=20
-
-05BB          ; 20 # Mn       HEBREW POINT QUBUTS
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=21
-
-05BC          ; 21 # Mn       HEBREW POINT DAGESH OR MAPIQ
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=22
-
-05BD          ; 22 # Mn       HEBREW POINT METEG
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=23
-
-05BF          ; 23 # Mn       HEBREW POINT RAFE
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=24
-
-05C1          ; 24 # Mn       HEBREW POINT SHIN DOT
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=25
-
-05C2          ; 25 # Mn       HEBREW POINT SIN DOT
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=26
-
-FB1E          ; 26 # Mn       HEBREW POINT JUDEO-SPANISH VARIKA
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=27
-
-064B          ; 27 # Mn       ARABIC FATHATAN
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=28
-
-064C          ; 28 # Mn       ARABIC DAMMATAN
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=29
-
-064D          ; 29 # Mn       ARABIC KASRATAN
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=30
-
-0618          ; 30 # Mn       ARABIC SMALL FATHA
-064E          ; 30 # Mn       ARABIC FATHA
-
-# Total code points: 2
-
-# ================================================
-
-# Canonical_Combining_Class=31
-
-0619          ; 31 # Mn       ARABIC SMALL DAMMA
-064F          ; 31 # Mn       ARABIC DAMMA
-
-# Total code points: 2
-
-# ================================================
-
-# Canonical_Combining_Class=32
-
-061A          ; 32 # Mn       ARABIC SMALL KASRA
-0650          ; 32 # Mn       ARABIC KASRA
-
-# Total code points: 2
-
-# ================================================
-
-# Canonical_Combining_Class=33
-
-0651          ; 33 # Mn       ARABIC SHADDA
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=34
-
-0652          ; 34 # Mn       ARABIC SUKUN
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=35
-
-0670          ; 35 # Mn       ARABIC LETTER SUPERSCRIPT ALEF
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=36
-
-0711          ; 36 # Mn       SYRIAC LETTER SUPERSCRIPT ALAPH
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=84
-
-0C55          ; 84 # Mn       TELUGU LENGTH MARK
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=91
-
-0C56          ; 91 # Mn       TELUGU AI LENGTH MARK
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=103
-
-0E38..0E39    ; 103 # Mn   [2] THAI CHARACTER SARA U..THAI CHARACTER SARA UU
-
-# Total code points: 2
-
-# ================================================
-
-# Canonical_Combining_Class=107
-
-0E48..0E4B    ; 107 # Mn   [4] THAI CHARACTER MAI EK..THAI CHARACTER MAI CHATTAWA
-
-# Total code points: 4
-
-# ================================================
-
-# Canonical_Combining_Class=118
-
-0EB8..0EB9    ; 118 # Mn   [2] LAO VOWEL SIGN U..LAO VOWEL SIGN UU
-
-# Total code points: 2
-
-# ================================================
-
-# Canonical_Combining_Class=122
-
-0EC8..0ECB    ; 122 # Mn   [4] LAO TONE MAI EK..LAO TONE MAI CATAWA
-
-# Total code points: 4
-
-# ================================================
-
-# Canonical_Combining_Class=129
-
-0F71          ; 129 # Mn       TIBETAN VOWEL SIGN AA
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=130
-
-0F72          ; 130 # Mn       TIBETAN VOWEL SIGN I
-0F7A..0F7D    ; 130 # Mn   [4] TIBETAN VOWEL SIGN E..TIBETAN VOWEL SIGN OO
-0F80          ; 130 # Mn       TIBETAN VOWEL SIGN REVERSED I
-
-# Total code points: 6
-
-# ================================================
-
-# Canonical_Combining_Class=132
-
-0F74          ; 132 # Mn       TIBETAN VOWEL SIGN U
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=Attached_Below
-
-0321..0322    ; 202 # Mn   [2] COMBINING PALATALIZED HOOK BELOW..COMBINING RETROFLEX HOOK BELOW
-0327..0328    ; 202 # Mn   [2] COMBINING CEDILLA..COMBINING OGONEK
-1DD0          ; 202 # Mn       COMBINING IS BELOW
-
-# Total code points: 5
-
-# ================================================
-
-# Canonical_Combining_Class=214
-
-1DCE          ; 214 # Mn       COMBINING OGONEK ABOVE
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=Attached_Above_Right
-
-031B          ; 216 # Mn       COMBINING HORN
-0F39          ; 216 # Mn       TIBETAN MARK TSA -PHRU
-1D165..1D166  ; 216 # Mc   [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
-1D16E..1D172  ; 216 # Mc   [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5
-
-# Total code points: 9
-
-# ================================================
-
-# Canonical_Combining_Class=Below_Left
-
-302A          ; 218 # Mn       IDEOGRAPHIC LEVEL TONE MARK
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=Below
-
-0316..0319    ; 220 # Mn   [4] COMBINING GRAVE ACCENT BELOW..COMBINING RIGHT TACK BELOW
-031C..0320    ; 220 # Mn   [5] COMBINING LEFT HALF RING BELOW..COMBINING MINUS SIGN BELOW
-0323..0326    ; 220 # Mn   [4] COMBINING DOT BELOW..COMBINING COMMA BELOW
-0329..0333    ; 220 # Mn  [11] COMBINING VERTICAL LINE BELOW..COMBINING DOUBLE LOW LINE
-0339..033C    ; 220 # Mn   [4] COMBINING RIGHT HALF RING BELOW..COMBINING SEAGULL BELOW
-0347..0349    ; 220 # Mn   [3] COMBINING EQUALS SIGN BELOW..COMBINING LEFT ANGLE BELOW
-034D..034E    ; 220 # Mn   [2] COMBINING LEFT RIGHT ARROW BELOW..COMBINING UPWARDS ARROW BELOW
-0353..0356    ; 220 # Mn   [4] COMBINING X BELOW..COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW
-0359..035A    ; 220 # Mn   [2] COMBINING ASTERISK BELOW..COMBINING DOUBLE RING BELOW
-0591          ; 220 # Mn       HEBREW ACCENT ETNAHTA
-0596          ; 220 # Mn       HEBREW ACCENT TIPEHA
-059B          ; 220 # Mn       HEBREW ACCENT TEVIR
-05A2..05A7    ; 220 # Mn   [6] HEBREW ACCENT ATNAH HAFUKH..HEBREW ACCENT DARGA
-05AA          ; 220 # Mn       HEBREW ACCENT YERAH BEN YOMO
-05C5          ; 220 # Mn       HEBREW MARK LOWER DOT
-0655..0656    ; 220 # Mn   [2] ARABIC HAMZA BELOW..ARABIC SUBSCRIPT ALEF
-065C          ; 220 # Mn       ARABIC VOWEL SIGN DOT BELOW
-06E3          ; 220 # Mn       ARABIC SMALL LOW SEEN
-06EA          ; 220 # Mn       ARABIC EMPTY CENTRE LOW STOP
-06ED          ; 220 # Mn       ARABIC SMALL LOW MEEM
-0731          ; 220 # Mn       SYRIAC PTHAHA BELOW
-0734          ; 220 # Mn       SYRIAC ZQAPHA BELOW
-0737..0739    ; 220 # Mn   [3] SYRIAC RBASA BELOW..SYRIAC DOTTED ZLAMA ANGULAR
-073B..073C    ; 220 # Mn   [2] SYRIAC HBASA BELOW..SYRIAC HBASA-ESASA DOTTED
-073E          ; 220 # Mn       SYRIAC ESASA BELOW
-0742          ; 220 # Mn       SYRIAC RUKKAKHA
-0744          ; 220 # Mn       SYRIAC TWO VERTICAL DOTS BELOW
-0746          ; 220 # Mn       SYRIAC THREE DOTS BELOW
-0748          ; 220 # Mn       SYRIAC OBLIQUE LINE BELOW
-07F2          ; 220 # Mn       NKO COMBINING NASALIZATION MARK
-0952          ; 220 # Mn       DEVANAGARI STRESS SIGN ANUDATTA
-0F18..0F19    ; 220 # Mn   [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
-0F35          ; 220 # Mn       TIBETAN MARK NGAS BZUNG NYI ZLA
-0F37          ; 220 # Mn       TIBETAN MARK NGAS BZUNG SGOR RTAGS
-0FC6          ; 220 # Mn       TIBETAN SYMBOL PADMA GDAN
-108D          ; 220 # Mn       MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
-193B          ; 220 # Mn       LIMBU SIGN SA-I
-1A18          ; 220 # Mn       BUGINESE VOWEL SIGN U
-1B6C          ; 220 # Mn       BALINESE MUSICAL SYMBOL COMBINING ENDEP
-1DC2          ; 220 # Mn       COMBINING SNAKE BELOW
-1DCA          ; 220 # Mn       COMBINING LATIN SMALL LETTER R BELOW
-1DCF          ; 220 # Mn       COMBINING ZIGZAG BELOW
-1DFF          ; 220 # Mn       COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
-20E8          ; 220 # Mn       COMBINING TRIPLE UNDERDOT
-20EC..20EF    ; 220 # Mn   [4] COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS..COMBINING RIGHT ARROW BELOW
-A92B..A92D    ; 220 # Mn   [3] KAYAH LI TONE PLOPHU..KAYAH LI TONE CALYA PLOPHU
-101FD         ; 220 # Mn       PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
-10A0D         ; 220 # Mn       KHAROSHTHI SIGN DOUBLE RING BELOW
-10A3A         ; 220 # Mn       KHAROSHTHI SIGN DOT BELOW
-1D17B..1D182  ; 220 # Mn   [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
-1D18A..1D18B  ; 220 # Mn   [2] MUSICAL SYMBOL COMBINING DOUBLE TONGUE..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
-
-# Total code points: 104
-
-# ================================================
-
-# Canonical_Combining_Class=Below_Right
-
-059A          ; 222 # Mn       HEBREW ACCENT YETIV
-05AD          ; 222 # Mn       HEBREW ACCENT DEHI
-1939          ; 222 # Mn       LIMBU SIGN MUKPHRENG
-302D          ; 222 # Mn       IDEOGRAPHIC ENTERING TONE MARK
-
-# Total code points: 4
-
-# ================================================
-
-# Canonical_Combining_Class=Left
-
-302E..302F    ; 224 # Mn   [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK
-
-# Total code points: 2
-
-# ================================================
-
-# Canonical_Combining_Class=Right
-
-1D16D         ; 226 # Mc       MUSICAL SYMBOL COMBINING AUGMENTATION DOT
-
-# Total code points: 1
-
-# ================================================
-
-# Canonical_Combining_Class=Above_Left
-
-05AE          ; 228 # Mn       HEBREW ACCENT ZINOR
-18A9          ; 228 # Mn       MONGOLIAN LETTER ALI GALI DAGALGA
-302B          ; 228 # Mn       IDEOGRAPHIC RISING TONE MARK
-
-# Total code points: 3
-
-# ================================================
-
-# Canonical_Combining_Class=Above
-
-0300..0314    ; 230 # Mn  [21] COMBINING GRAVE ACCENT..COMBINING REVERSED COMMA ABOVE
-033D..0344    ; 230 # Mn   [8] COMBINING X ABOVE..COMBINING GREEK DIALYTIKA TONOS
-0346          ; 230 # Mn       COMBINING BRIDGE ABOVE
-034A..034C    ; 230 # Mn   [3] COMBINING NOT TILDE ABOVE..COMBINING ALMOST EQUAL TO ABOVE
-0350..0352    ; 230 # Mn   [3] COMBINING RIGHT ARROWHEAD ABOVE..COMBINING FERMATA
-0357          ; 230 # Mn       COMBINING RIGHT HALF RING ABOVE
-035B          ; 230 # Mn       COMBINING ZIGZAG ABOVE
-0363..036F    ; 230 # Mn  [13] COMBINING LATIN SMALL LETTER A..COMBINING LATIN SMALL LETTER X
-0483..0487    ; 230 # Mn   [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
-0592..0595    ; 230 # Mn   [4] HEBREW ACCENT SEGOL..HEBREW ACCENT ZAQEF GADOL
-0597..0599    ; 230 # Mn   [3] HEBREW ACCENT REVIA..HEBREW ACCENT PASHTA
-059C..05A1    ; 230 # Mn   [6] HEBREW ACCENT GERESH..HEBREW ACCENT PAZER
-05A8..05A9    ; 230 # Mn   [2] HEBREW ACCENT QADMA..HEBREW ACCENT TELISHA QETANA
-05AB..05AC    ; 230 # Mn   [2] HEBREW ACCENT OLE..HEBREW ACCENT ILUY
-05AF          ; 230 # Mn       HEBREW MARK MASORA CIRCLE
-05C4          ; 230 # Mn       HEBREW MARK UPPER DOT
-0610..0617    ; 230 # Mn   [8] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL HIGH ZAIN
-0653..0654    ; 230 # Mn   [2] ARABIC MADDAH ABOVE..ARABIC HAMZA ABOVE
-0657..065B    ; 230 # Mn   [5] ARABIC INVERTED DAMMA..ARABIC VOWEL SIGN INVERTED SMALL V ABOVE
-065D..065E    ; 230 # Mn   [2] ARABIC REVERSED DAMMA..ARABIC FATHA WITH TWO DOTS
-06D6..06DC    ; 230 # Mn   [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
-06DF..06E2    ; 230 # Mn   [4] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MEEM ISOLATED FORM
-06E4          ; 230 # Mn       ARABIC SMALL HIGH MADDA
-06E7..06E8    ; 230 # Mn   [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
-06EB..06EC    ; 230 # Mn   [2] ARABIC EMPTY CENTRE HIGH STOP..ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE
-0730          ; 230 # Mn       SYRIAC PTHAHA ABOVE
-0732..0733    ; 230 # Mn   [2] SYRIAC PTHAHA DOTTED..SYRIAC ZQAPHA ABOVE
-0735..0736    ; 230 # Mn   [2] SYRIAC ZQAPHA DOTTED..SYRIAC RBASA ABOVE
-073A          ; 230 # Mn       SYRIAC HBASA ABOVE
-073D          ; 230 # Mn       SYRIAC ESASA ABOVE
-073F..0741    ; 230 # Mn   [3] SYRIAC RWAHA..SYRIAC QUSHSHAYA
-0743          ; 230 # Mn       SYRIAC TWO VERTICAL DOTS ABOVE
-0745          ; 230 # Mn       SYRIAC THREE DOTS ABOVE
-0747          ; 230 # Mn       SYRIAC OBLIQUE LINE ABOVE
-0749..074A    ; 230 # Mn   [2] SYRIAC MUSIC..SYRIAC BARREKH
-07EB..07F1    ; 230 # Mn   [7] NKO COMBINING SHORT HIGH TONE..NKO COMBINING LONG RISING TONE
-07F3          ; 230 # Mn       NKO COMBINING DOUBLE DOT ABOVE
-0951          ; 230 # Mn       DEVANAGARI STRESS SIGN UDATTA
-0953..0954    ; 230 # Mn   [2] DEVANAGARI GRAVE ACCENT..DEVANAGARI ACUTE ACCENT
-0F82..0F83    ; 230 # Mn   [2] TIBETAN SIGN NYI ZLA NAA DA..TIBETAN SIGN SNA LDAN
-0F86..0F87    ; 230 # Mn   [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
-135F          ; 230 # Mn       ETHIOPIC COMBINING GEMINATION MARK
-17DD          ; 230 # Mn       KHMER SIGN ATTHACAN
-193A          ; 230 # Mn       LIMBU SIGN KEMPHRENG
-1A17          ; 230 # Mn       BUGINESE VOWEL SIGN I
-1B6B          ; 230 # Mn       BALINESE MUSICAL SYMBOL COMBINING TEGEH
-1B6D..1B73    ; 230 # Mn   [7] BALINESE MUSICAL SYMBOL COMBINING KEMPUL..BALINESE MUSICAL SYMBOL COMBINING GONG
-1DC0..1DC1    ; 230 # Mn   [2] COMBINING DOTTED GRAVE ACCENT..COMBINING DOTTED ACUTE ACCENT
-1DC3..1DC9    ; 230 # Mn   [7] COMBINING SUSPENSION MARK..COMBINING ACUTE-GRAVE-ACUTE
-1DCB..1DCC    ; 230 # Mn   [2] COMBINING BREVE-MACRON..COMBINING MACRON-BREVE
-1DD1..1DE6    ; 230 # Mn  [22] COMBINING UR ABOVE..COMBINING LATIN SMALL LETTER Z
-1DFE          ; 230 # Mn       COMBINING LEFT ARROWHEAD ABOVE
-20D0..20D1    ; 230 # Mn   [2] COMBINING LEFT HARPOON ABOVE..COMBINING RIGHT HARPOON ABOVE
-20D4..20D7    ; 230 # Mn   [4] COMBINING ANTICLOCKWISE ARROW ABOVE..COMBINING RIGHT ARROW ABOVE
-20DB..20DC    ; 230 # Mn   [2] COMBINING THREE DOTS ABOVE..COMBINING FOUR DOTS ABOVE
-20E1          ; 230 # Mn       COMBINING LEFT RIGHT ARROW ABOVE
-20E7          ; 230 # Mn       COMBINING ANNUITY SYMBOL
-20E9          ; 230 # Mn       COMBINING WIDE BRIDGE ABOVE
-20F0          ; 230 # Mn       COMBINING ASTERISK ABOVE
-2DE0..2DFF    ; 230 # Mn  [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
-A66F          ; 230 # Mn       COMBINING CYRILLIC VZMET
-A67C..A67D    ; 230 # Mn   [2] COMBINING CYRILLIC KAVYKA..COMBINING CYRILLIC PAYEROK
-FE20..FE26    ; 230 # Mn   [7] COMBINING LIGATURE LEFT HALF..COMBINING CONJOINING MACRON
-10A0F         ; 230 # Mn       KHAROSHTHI SIGN VISARGA
-10A38         ; 230 # Mn       KHAROSHTHI SIGN BAR ABOVE
-1D185..1D189  ; 230 # Mn   [5] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING BEND
-1D1AA..1D1AD  ; 230 # Mn   [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
-1D242..1D244  ; 230 # Mn   [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
-
-# Total code points: 252
-
-# ================================================
-
-# Canonical_Combining_Class=Above_Right
-
-0315          ; 232 # Mn       COMBINING COMMA ABOVE RIGHT
-031A          ; 232 # Mn       COMBINING LEFT ANGLE ABOVE
-0358          ; 232 # Mn       COMBINING DOT ABOVE RIGHT
-302C          ; 232 # Mn       IDEOGRAPHIC DEPARTING TONE MARK
-
-# Total code points: 4
-
-# ================================================
-
-# Canonical_Combining_Class=Double_Below
-
-035C          ; 233 # Mn       COMBINING DOUBLE BREVE BELOW
-035F          ; 233 # Mn       COMBINING DOUBLE MACRON BELOW
-0362          ; 233 # Mn       COMBINING DOUBLE RIGHTWARDS ARROW BELOW
-
-# Total code points: 3
-
-# ================================================
-
-# Canonical_Combining_Class=Double_Above
-
-035D..035E    ; 234 # Mn   [2] COMBINING DOUBLE BREVE..COMBINING DOUBLE MACRON
-0360..0361    ; 234 # Mn   [2] COMBINING DOUBLE TILDE..COMBINING DOUBLE INVERTED BREVE
-1DCD          ; 234 # Mn       COMBINING DOUBLE CIRCUMFLEX ABOVE
-
-# Total code points: 5
-
-# ================================================
-
-# Canonical_Combining_Class=Iota_Subscript
-
-0345          ; 240 # Mn       COMBINING GREEK YPOGEGRAMMENI
-
-# Total code points: 1
-
-# EOF
diff --git a/third_party/harfbuzz/contrib/tables/DerivedGeneralCategory.txt b/third_party/harfbuzz/contrib/tables/DerivedGeneralCategory.txt
deleted file mode 100644
index 8423c70..0000000
--- a/third_party/harfbuzz/contrib/tables/DerivedGeneralCategory.txt
+++ /dev/null
@@ -1,3072 +0,0 @@
-# DerivedGeneralCategory-5.1.0.txt
-# Date: 2008-03-20, 17:54:57 GMT [MD]
-#
-# Unicode Character Database
-# Copyright (c) 1991-2008 Unicode, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-# For documentation, see UCD.html
-
-# ================================================
-
-# Property:	General_Category
-
-# ================================================
-
-# General_Category=Unassigned
-
-0378..0379    ; Cn #   [2] <reserved-0378>..<reserved-0379>
-037F..0383    ; Cn #   [5] <reserved-037F>..<reserved-0383>
-038B          ; Cn #       <reserved-038B>
-038D          ; Cn #       <reserved-038D>
-03A2          ; Cn #       <reserved-03A2>
-0524..0530    ; Cn #  [13] <reserved-0524>..<reserved-0530>
-0557..0558    ; Cn #   [2] <reserved-0557>..<reserved-0558>
-0560          ; Cn #       <reserved-0560>
-0588          ; Cn #       <reserved-0588>
-058B..0590    ; Cn #   [6] <reserved-058B>..<reserved-0590>
-05C8..05CF    ; Cn #   [8] <reserved-05C8>..<reserved-05CF>
-05EB..05EF    ; Cn #   [5] <reserved-05EB>..<reserved-05EF>
-05F5..05FF    ; Cn #  [11] <reserved-05F5>..<reserved-05FF>
-0604..0605    ; Cn #   [2] <reserved-0604>..<reserved-0605>
-061C..061D    ; Cn #   [2] <reserved-061C>..<reserved-061D>
-0620          ; Cn #       <reserved-0620>
-065F          ; Cn #       <reserved-065F>
-070E          ; Cn #       <reserved-070E>
-074B..074C    ; Cn #   [2] <reserved-074B>..<reserved-074C>
-07B2..07BF    ; Cn #  [14] <reserved-07B2>..<reserved-07BF>
-07FB..0900    ; Cn # [262] <reserved-07FB>..<reserved-0900>
-093A..093B    ; Cn #   [2] <reserved-093A>..<reserved-093B>
-094E..094F    ; Cn #   [2] <reserved-094E>..<reserved-094F>
-0955..0957    ; Cn #   [3] <reserved-0955>..<reserved-0957>
-0973..097A    ; Cn #   [8] <reserved-0973>..<reserved-097A>
-0980          ; Cn #       <reserved-0980>
-0984          ; Cn #       <reserved-0984>
-098D..098E    ; Cn #   [2] <reserved-098D>..<reserved-098E>
-0991..0992    ; Cn #   [2] <reserved-0991>..<reserved-0992>
-09A9          ; Cn #       <reserved-09A9>
-09B1          ; Cn #       <reserved-09B1>
-09B3..09B5    ; Cn #   [3] <reserved-09B3>..<reserved-09B5>
-09BA..09BB    ; Cn #   [2] <reserved-09BA>..<reserved-09BB>
-09C5..09C6    ; Cn #   [2] <reserved-09C5>..<reserved-09C6>
-09C9..09CA    ; Cn #   [2] <reserved-09C9>..<reserved-09CA>
-09CF..09D6    ; Cn #   [8] <reserved-09CF>..<reserved-09D6>
-09D8..09DB    ; Cn #   [4] <reserved-09D8>..<reserved-09DB>
-09DE          ; Cn #       <reserved-09DE>
-09E4..09E5    ; Cn #   [2] <reserved-09E4>..<reserved-09E5>
-09FB..0A00    ; Cn #   [6] <reserved-09FB>..<reserved-0A00>
-0A04          ; Cn #       <reserved-0A04>
-0A0B..0A0E    ; Cn #   [4] <reserved-0A0B>..<reserved-0A0E>
-0A11..0A12    ; Cn #   [2] <reserved-0A11>..<reserved-0A12>
-0A29          ; Cn #       <reserved-0A29>
-0A31          ; Cn #       <reserved-0A31>
-0A34          ; Cn #       <reserved-0A34>
-0A37          ; Cn #       <reserved-0A37>
-0A3A..0A3B    ; Cn #   [2] <reserved-0A3A>..<reserved-0A3B>
-0A3D          ; Cn #       <reserved-0A3D>
-0A43..0A46    ; Cn #   [4] <reserved-0A43>..<reserved-0A46>
-0A49..0A4A    ; Cn #   [2] <reserved-0A49>..<reserved-0A4A>
-0A4E..0A50    ; Cn #   [3] <reserved-0A4E>..<reserved-0A50>
-0A52..0A58    ; Cn #   [7] <reserved-0A52>..<reserved-0A58>
-0A5D          ; Cn #       <reserved-0A5D>
-0A5F..0A65    ; Cn #   [7] <reserved-0A5F>..<reserved-0A65>
-0A76..0A80    ; Cn #  [11] <reserved-0A76>..<reserved-0A80>
-0A84          ; Cn #       <reserved-0A84>
-0A8E          ; Cn #       <reserved-0A8E>
-0A92          ; Cn #       <reserved-0A92>
-0AA9          ; Cn #       <reserved-0AA9>
-0AB1          ; Cn #       <reserved-0AB1>
-0AB4          ; Cn #       <reserved-0AB4>
-0ABA..0ABB    ; Cn #   [2] <reserved-0ABA>..<reserved-0ABB>
-0AC6          ; Cn #       <reserved-0AC6>
-0ACA          ; Cn #       <reserved-0ACA>
-0ACE..0ACF    ; Cn #   [2] <reserved-0ACE>..<reserved-0ACF>
-0AD1..0ADF    ; Cn #  [15] <reserved-0AD1>..<reserved-0ADF>
-0AE4..0AE5    ; Cn #   [2] <reserved-0AE4>..<reserved-0AE5>
-0AF0          ; Cn #       <reserved-0AF0>
-0AF2..0B00    ; Cn #  [15] <reserved-0AF2>..<reserved-0B00>
-0B04          ; Cn #       <reserved-0B04>
-0B0D..0B0E    ; Cn #   [2] <reserved-0B0D>..<reserved-0B0E>
-0B11..0B12    ; Cn #   [2] <reserved-0B11>..<reserved-0B12>
-0B29          ; Cn #       <reserved-0B29>
-0B31          ; Cn #       <reserved-0B31>
-0B34          ; Cn #       <reserved-0B34>
-0B3A..0B3B    ; Cn #   [2] <reserved-0B3A>..<reserved-0B3B>
-0B45..0B46    ; Cn #   [2] <reserved-0B45>..<reserved-0B46>
-0B49..0B4A    ; Cn #   [2] <reserved-0B49>..<reserved-0B4A>
-0B4E..0B55    ; Cn #   [8] <reserved-0B4E>..<reserved-0B55>
-0B58..0B5B    ; Cn #   [4] <reserved-0B58>..<reserved-0B5B>
-0B5E          ; Cn #       <reserved-0B5E>
-0B64..0B65    ; Cn #   [2] <reserved-0B64>..<reserved-0B65>
-0B72..0B81    ; Cn #  [16] <reserved-0B72>..<reserved-0B81>
-0B84          ; Cn #       <reserved-0B84>
-0B8B..0B8D    ; Cn #   [3] <reserved-0B8B>..<reserved-0B8D>
-0B91          ; Cn #       <reserved-0B91>
-0B96..0B98    ; Cn #   [3] <reserved-0B96>..<reserved-0B98>
-0B9B          ; Cn #       <reserved-0B9B>
-0B9D          ; Cn #       <reserved-0B9D>
-0BA0..0BA2    ; Cn #   [3] <reserved-0BA0>..<reserved-0BA2>
-0BA5..0BA7    ; Cn #   [3] <reserved-0BA5>..<reserved-0BA7>
-0BAB..0BAD    ; Cn #   [3] <reserved-0BAB>..<reserved-0BAD>
-0BBA..0BBD    ; Cn #   [4] <reserved-0BBA>..<reserved-0BBD>
-0BC3..0BC5    ; Cn #   [3] <reserved-0BC3>..<reserved-0BC5>
-0BC9          ; Cn #       <reserved-0BC9>
-0BCE..0BCF    ; Cn #   [2] <reserved-0BCE>..<reserved-0BCF>
-0BD1..0BD6    ; Cn #   [6] <reserved-0BD1>..<reserved-0BD6>
-0BD8..0BE5    ; Cn #  [14] <reserved-0BD8>..<reserved-0BE5>
-0BFB..0C00    ; Cn #   [6] <reserved-0BFB>..<reserved-0C00>
-0C04          ; Cn #       <reserved-0C04>
-0C0D          ; Cn #       <reserved-0C0D>
-0C11          ; Cn #       <reserved-0C11>
-0C29          ; Cn #       <reserved-0C29>
-0C34          ; Cn #       <reserved-0C34>
-0C3A..0C3C    ; Cn #   [3] <reserved-0C3A>..<reserved-0C3C>
-0C45          ; Cn #       <reserved-0C45>
-0C49          ; Cn #       <reserved-0C49>
-0C4E..0C54    ; Cn #   [7] <reserved-0C4E>..<reserved-0C54>
-0C57          ; Cn #       <reserved-0C57>
-0C5A..0C5F    ; Cn #   [6] <reserved-0C5A>..<reserved-0C5F>
-0C64..0C65    ; Cn #   [2] <reserved-0C64>..<reserved-0C65>
-0C70..0C77    ; Cn #   [8] <reserved-0C70>..<reserved-0C77>
-0C80..0C81    ; Cn #   [2] <reserved-0C80>..<reserved-0C81>
-0C84          ; Cn #       <reserved-0C84>
-0C8D          ; Cn #       <reserved-0C8D>
-0C91          ; Cn #       <reserved-0C91>
-0CA9          ; Cn #       <reserved-0CA9>
-0CB4          ; Cn #       <reserved-0CB4>
-0CBA..0CBB    ; Cn #   [2] <reserved-0CBA>..<reserved-0CBB>
-0CC5          ; Cn #       <reserved-0CC5>
-0CC9          ; Cn #       <reserved-0CC9>
-0CCE..0CD4    ; Cn #   [7] <reserved-0CCE>..<reserved-0CD4>
-0CD7..0CDD    ; Cn #   [7] <reserved-0CD7>..<reserved-0CDD>
-0CDF          ; Cn #       <reserved-0CDF>
-0CE4..0CE5    ; Cn #   [2] <reserved-0CE4>..<reserved-0CE5>
-0CF0          ; Cn #       <reserved-0CF0>
-0CF3..0D01    ; Cn #  [15] <reserved-0CF3>..<reserved-0D01>
-0D04          ; Cn #       <reserved-0D04>
-0D0D          ; Cn #       <reserved-0D0D>
-0D11          ; Cn #       <reserved-0D11>
-0D29          ; Cn #       <reserved-0D29>
-0D3A..0D3C    ; Cn #   [3] <reserved-0D3A>..<reserved-0D3C>
-0D45          ; Cn #       <reserved-0D45>
-0D49          ; Cn #       <reserved-0D49>
-0D4E..0D56    ; Cn #   [9] <reserved-0D4E>..<reserved-0D56>
-0D58..0D5F    ; Cn #   [8] <reserved-0D58>..<reserved-0D5F>
-0D64..0D65    ; Cn #   [2] <reserved-0D64>..<reserved-0D65>
-0D76..0D78    ; Cn #   [3] <reserved-0D76>..<reserved-0D78>
-0D80..0D81    ; Cn #   [2] <reserved-0D80>..<reserved-0D81>
-0D84          ; Cn #       <reserved-0D84>
-0D97..0D99    ; Cn #   [3] <reserved-0D97>..<reserved-0D99>
-0DB2          ; Cn #       <reserved-0DB2>
-0DBC          ; Cn #       <reserved-0DBC>
-0DBE..0DBF    ; Cn #   [2] <reserved-0DBE>..<reserved-0DBF>
-0DC7..0DC9    ; Cn #   [3] <reserved-0DC7>..<reserved-0DC9>
-0DCB..0DCE    ; Cn #   [4] <reserved-0DCB>..<reserved-0DCE>
-0DD5          ; Cn #       <reserved-0DD5>
-0DD7          ; Cn #       <reserved-0DD7>
-0DE0..0DF1    ; Cn #  [18] <reserved-0DE0>..<reserved-0DF1>
-0DF5..0E00    ; Cn #  [12] <reserved-0DF5>..<reserved-0E00>
-0E3B..0E3E    ; Cn #   [4] <reserved-0E3B>..<reserved-0E3E>
-0E5C..0E80    ; Cn #  [37] <reserved-0E5C>..<reserved-0E80>
-0E83          ; Cn #       <reserved-0E83>
-0E85..0E86    ; Cn #   [2] <reserved-0E85>..<reserved-0E86>
-0E89          ; Cn #       <reserved-0E89>
-0E8B..0E8C    ; Cn #   [2] <reserved-0E8B>..<reserved-0E8C>
-0E8E..0E93    ; Cn #   [6] <reserved-0E8E>..<reserved-0E93>
-0E98          ; Cn #       <reserved-0E98>
-0EA0          ; Cn #       <reserved-0EA0>
-0EA4          ; Cn #       <reserved-0EA4>
-0EA6          ; Cn #       <reserved-0EA6>
-0EA8..0EA9    ; Cn #   [2] <reserved-0EA8>..<reserved-0EA9>
-0EAC          ; Cn #       <reserved-0EAC>
-0EBA          ; Cn #       <reserved-0EBA>
-0EBE..0EBF    ; Cn #   [2] <reserved-0EBE>..<reserved-0EBF>
-0EC5          ; Cn #       <reserved-0EC5>
-0EC7          ; Cn #       <reserved-0EC7>
-0ECE..0ECF    ; Cn #   [2] <reserved-0ECE>..<reserved-0ECF>
-0EDA..0EDB    ; Cn #   [2] <reserved-0EDA>..<reserved-0EDB>
-0EDE..0EFF    ; Cn #  [34] <reserved-0EDE>..<reserved-0EFF>
-0F48          ; Cn #       <reserved-0F48>
-0F6D..0F70    ; Cn #   [4] <reserved-0F6D>..<reserved-0F70>
-0F8C..0F8F    ; Cn #   [4] <reserved-0F8C>..<reserved-0F8F>
-0F98          ; Cn #       <reserved-0F98>
-0FBD          ; Cn #       <reserved-0FBD>
-0FCD          ; Cn #       <reserved-0FCD>
-0FD5..0FFF    ; Cn #  [43] <reserved-0FD5>..<reserved-0FFF>
-109A..109D    ; Cn #   [4] <reserved-109A>..<reserved-109D>
-10C6..10CF    ; Cn #  [10] <reserved-10C6>..<reserved-10CF>
-10FD..10FF    ; Cn #   [3] <reserved-10FD>..<reserved-10FF>
-115A..115E    ; Cn #   [5] <reserved-115A>..<reserved-115E>
-11A3..11A7    ; Cn #   [5] <reserved-11A3>..<reserved-11A7>
-11FA..11FF    ; Cn #   [6] <reserved-11FA>..<reserved-11FF>
-1249          ; Cn #       <reserved-1249>
-124E..124F    ; Cn #   [2] <reserved-124E>..<reserved-124F>
-1257          ; Cn #       <reserved-1257>
-1259          ; Cn #       <reserved-1259>
-125E..125F    ; Cn #   [2] <reserved-125E>..<reserved-125F>
-1289          ; Cn #       <reserved-1289>
-128E..128F    ; Cn #   [2] <reserved-128E>..<reserved-128F>
-12B1          ; Cn #       <reserved-12B1>
-12B6..12B7    ; Cn #   [2] <reserved-12B6>..<reserved-12B7>
-12BF          ; Cn #       <reserved-12BF>
-12C1          ; Cn #       <reserved-12C1>
-12C6..12C7    ; Cn #   [2] <reserved-12C6>..<reserved-12C7>
-12D7          ; Cn #       <reserved-12D7>
-1311          ; Cn #       <reserved-1311>
-1316..1317    ; Cn #   [2] <reserved-1316>..<reserved-1317>
-135B..135E    ; Cn #   [4] <reserved-135B>..<reserved-135E>
-137D..137F    ; Cn #   [3] <reserved-137D>..<reserved-137F>
-139A..139F    ; Cn #   [6] <reserved-139A>..<reserved-139F>
-13F5..1400    ; Cn #  [12] <reserved-13F5>..<reserved-1400>
-1677..167F    ; Cn #   [9] <reserved-1677>..<reserved-167F>
-169D..169F    ; Cn #   [3] <reserved-169D>..<reserved-169F>
-16F1..16FF    ; Cn #  [15] <reserved-16F1>..<reserved-16FF>
-170D          ; Cn #       <reserved-170D>
-1715..171F    ; Cn #  [11] <reserved-1715>..<reserved-171F>
-1737..173F    ; Cn #   [9] <reserved-1737>..<reserved-173F>
-1754..175F    ; Cn #  [12] <reserved-1754>..<reserved-175F>
-176D          ; Cn #       <reserved-176D>
-1771          ; Cn #       <reserved-1771>
-1774..177F    ; Cn #  [12] <reserved-1774>..<reserved-177F>
-17DE..17DF    ; Cn #   [2] <reserved-17DE>..<reserved-17DF>
-17EA..17EF    ; Cn #   [6] <reserved-17EA>..<reserved-17EF>
-17FA..17FF    ; Cn #   [6] <reserved-17FA>..<reserved-17FF>
-180F          ; Cn #       <reserved-180F>
-181A..181F    ; Cn #   [6] <reserved-181A>..<reserved-181F>
-1878..187F    ; Cn #   [8] <reserved-1878>..<reserved-187F>
-18AB..18FF    ; Cn #  [85] <reserved-18AB>..<reserved-18FF>
-191D..191F    ; Cn #   [3] <reserved-191D>..<reserved-191F>
-192C..192F    ; Cn #   [4] <reserved-192C>..<reserved-192F>
-193C..193F    ; Cn #   [4] <reserved-193C>..<reserved-193F>
-1941..1943    ; Cn #   [3] <reserved-1941>..<reserved-1943>
-196E..196F    ; Cn #   [2] <reserved-196E>..<reserved-196F>
-1975..197F    ; Cn #  [11] <reserved-1975>..<reserved-197F>
-19AA..19AF    ; Cn #   [6] <reserved-19AA>..<reserved-19AF>
-19CA..19CF    ; Cn #   [6] <reserved-19CA>..<reserved-19CF>
-19DA..19DD    ; Cn #   [4] <reserved-19DA>..<reserved-19DD>
-1A1C..1A1D    ; Cn #   [2] <reserved-1A1C>..<reserved-1A1D>
-1A20..1AFF    ; Cn # [224] <reserved-1A20>..<reserved-1AFF>
-1B4C..1B4F    ; Cn #   [4] <reserved-1B4C>..<reserved-1B4F>
-1B7D..1B7F    ; Cn #   [3] <reserved-1B7D>..<reserved-1B7F>
-1BAB..1BAD    ; Cn #   [3] <reserved-1BAB>..<reserved-1BAD>
-1BBA..1BFF    ; Cn #  [70] <reserved-1BBA>..<reserved-1BFF>
-1C38..1C3A    ; Cn #   [3] <reserved-1C38>..<reserved-1C3A>
-1C4A..1C4C    ; Cn #   [3] <reserved-1C4A>..<reserved-1C4C>
-1C80..1CFF    ; Cn # [128] <reserved-1C80>..<reserved-1CFF>
-1DE7..1DFD    ; Cn #  [23] <reserved-1DE7>..<reserved-1DFD>
-1F16..1F17    ; Cn #   [2] <reserved-1F16>..<reserved-1F17>
-1F1E..1F1F    ; Cn #   [2] <reserved-1F1E>..<reserved-1F1F>
-1F46..1F47    ; Cn #   [2] <reserved-1F46>..<reserved-1F47>
-1F4E..1F4F    ; Cn #   [2] <reserved-1F4E>..<reserved-1F4F>
-1F58          ; Cn #       <reserved-1F58>
-1F5A          ; Cn #       <reserved-1F5A>
-1F5C          ; Cn #       <reserved-1F5C>
-1F5E          ; Cn #       <reserved-1F5E>
-1F7E..1F7F    ; Cn #   [2] <reserved-1F7E>..<reserved-1F7F>
-1FB5          ; Cn #       <reserved-1FB5>
-1FC5          ; Cn #       <reserved-1FC5>
-1FD4..1FD5    ; Cn #   [2] <reserved-1FD4>..<reserved-1FD5>
-1FDC          ; Cn #       <reserved-1FDC>
-1FF0..1FF1    ; Cn #   [2] <reserved-1FF0>..<reserved-1FF1>
-1FF5          ; Cn #       <reserved-1FF5>
-1FFF          ; Cn #       <reserved-1FFF>
-2065..2069    ; Cn #   [5] <reserved-2065>..<reserved-2069>
-2072..2073    ; Cn #   [2] <reserved-2072>..<reserved-2073>
-208F          ; Cn #       <reserved-208F>
-2095..209F    ; Cn #  [11] <reserved-2095>..<reserved-209F>
-20B6..20CF    ; Cn #  [26] <reserved-20B6>..<reserved-20CF>
-20F1..20FF    ; Cn #  [15] <reserved-20F1>..<reserved-20FF>
-2150..2152    ; Cn #   [3] <reserved-2150>..<reserved-2152>
-2189..218F    ; Cn #   [7] <reserved-2189>..<reserved-218F>
-23E8..23FF    ; Cn #  [24] <reserved-23E8>..<reserved-23FF>
-2427..243F    ; Cn #  [25] <reserved-2427>..<reserved-243F>
-244B..245F    ; Cn #  [21] <reserved-244B>..<reserved-245F>
-269E..269F    ; Cn #   [2] <reserved-269E>..<reserved-269F>
-26BD..26BF    ; Cn #   [3] <reserved-26BD>..<reserved-26BF>
-26C4..2700    ; Cn #  [61] <reserved-26C4>..<reserved-2700>
-2705          ; Cn #       <reserved-2705>
-270A..270B    ; Cn #   [2] <reserved-270A>..<reserved-270B>
-2728          ; Cn #       <reserved-2728>
-274C          ; Cn #       <reserved-274C>
-274E          ; Cn #       <reserved-274E>
-2753..2755    ; Cn #   [3] <reserved-2753>..<reserved-2755>
-2757          ; Cn #       <reserved-2757>
-275F..2760    ; Cn #   [2] <reserved-275F>..<reserved-2760>
-2795..2797    ; Cn #   [3] <reserved-2795>..<reserved-2797>
-27B0          ; Cn #       <reserved-27B0>
-27BF          ; Cn #       <reserved-27BF>
-27CB          ; Cn #       <reserved-27CB>
-27CD..27CF    ; Cn #   [3] <reserved-27CD>..<reserved-27CF>
-2B4D..2B4F    ; Cn #   [3] <reserved-2B4D>..<reserved-2B4F>
-2B55..2BFF    ; Cn # [171] <reserved-2B55>..<reserved-2BFF>
-2C2F          ; Cn #       <reserved-2C2F>
-2C5F          ; Cn #       <reserved-2C5F>
-2C70          ; Cn #       <reserved-2C70>
-2C7E..2C7F    ; Cn #   [2] <reserved-2C7E>..<reserved-2C7F>
-2CEB..2CF8    ; Cn #  [14] <reserved-2CEB>..<reserved-2CF8>
-2D26..2D2F    ; Cn #  [10] <reserved-2D26>..<reserved-2D2F>
-2D66..2D6E    ; Cn #   [9] <reserved-2D66>..<reserved-2D6E>
-2D70..2D7F    ; Cn #  [16] <reserved-2D70>..<reserved-2D7F>
-2D97..2D9F    ; Cn #   [9] <reserved-2D97>..<reserved-2D9F>
-2DA7          ; Cn #       <reserved-2DA7>
-2DAF          ; Cn #       <reserved-2DAF>
-2DB7          ; Cn #       <reserved-2DB7>
-2DBF          ; Cn #       <reserved-2DBF>
-2DC7          ; Cn #       <reserved-2DC7>
-2DCF          ; Cn #       <reserved-2DCF>
-2DD7          ; Cn #       <reserved-2DD7>
-2DDF          ; Cn #       <reserved-2DDF>
-2E31..2E7F    ; Cn #  [79] <reserved-2E31>..<reserved-2E7F>
-2E9A          ; Cn #       <reserved-2E9A>
-2EF4..2EFF    ; Cn #  [12] <reserved-2EF4>..<reserved-2EFF>
-2FD6..2FEF    ; Cn #  [26] <reserved-2FD6>..<reserved-2FEF>
-2FFC..2FFF    ; Cn #   [4] <reserved-2FFC>..<reserved-2FFF>
-3040          ; Cn #       <reserved-3040>
-3097..3098    ; Cn #   [2] <reserved-3097>..<reserved-3098>
-3100..3104    ; Cn #   [5] <reserved-3100>..<reserved-3104>
-312E..3130    ; Cn #   [3] <reserved-312E>..<reserved-3130>
-318F          ; Cn #       <reserved-318F>
-31B8..31BF    ; Cn #   [8] <reserved-31B8>..<reserved-31BF>
-31E4..31EF    ; Cn #  [12] <reserved-31E4>..<reserved-31EF>
-321F          ; Cn #       <reserved-321F>
-3244..324F    ; Cn #  [12] <reserved-3244>..<reserved-324F>
-32FF          ; Cn #       <reserved-32FF>
-4DB6..4DBF    ; Cn #  [10] <reserved-4DB6>..<reserved-4DBF>
-9FC4..9FFF    ; Cn #  [60] <reserved-9FC4>..<reserved-9FFF>
-A48D..A48F    ; Cn #   [3] <reserved-A48D>..<reserved-A48F>
-A4C7..A4FF    ; Cn #  [57] <reserved-A4C7>..<reserved-A4FF>
-A62C..A63F    ; Cn #  [20] <reserved-A62C>..<reserved-A63F>
-A660..A661    ; Cn #   [2] <reserved-A660>..<reserved-A661>
-A674..A67B    ; Cn #   [8] <reserved-A674>..<reserved-A67B>
-A698..A6FF    ; Cn # [104] <reserved-A698>..<reserved-A6FF>
-A78D..A7FA    ; Cn # [110] <reserved-A78D>..<reserved-A7FA>
-A82C..A83F    ; Cn #  [20] <reserved-A82C>..<reserved-A83F>
-A878..A87F    ; Cn #   [8] <reserved-A878>..<reserved-A87F>
-A8C5..A8CD    ; Cn #   [9] <reserved-A8C5>..<reserved-A8CD>
-A8DA..A8FF    ; Cn #  [38] <reserved-A8DA>..<reserved-A8FF>
-A954..A95E    ; Cn #  [11] <reserved-A954>..<reserved-A95E>
-A960..A9FF    ; Cn # [160] <reserved-A960>..<reserved-A9FF>
-AA37..AA3F    ; Cn #   [9] <reserved-AA37>..<reserved-AA3F>
-AA4E..AA4F    ; Cn #   [2] <reserved-AA4E>..<reserved-AA4F>
-AA5A..AA5B    ; Cn #   [2] <reserved-AA5A>..<reserved-AA5B>
-AA60..ABFF    ; Cn # [416] <reserved-AA60>..<reserved-ABFF>
-D7A4..D7FF    ; Cn #  [92] <reserved-D7A4>..<reserved-D7FF>
-FA2E..FA2F    ; Cn #   [2] <reserved-FA2E>..<reserved-FA2F>
-FA6B..FA6F    ; Cn #   [5] <reserved-FA6B>..<reserved-FA6F>
-FADA..FAFF    ; Cn #  [38] <reserved-FADA>..<reserved-FAFF>
-FB07..FB12    ; Cn #  [12] <reserved-FB07>..<reserved-FB12>
-FB18..FB1C    ; Cn #   [5] <reserved-FB18>..<reserved-FB1C>
-FB37          ; Cn #       <reserved-FB37>
-FB3D          ; Cn #       <reserved-FB3D>
-FB3F          ; Cn #       <reserved-FB3F>
-FB42          ; Cn #       <reserved-FB42>
-FB45          ; Cn #       <reserved-FB45>
-FBB2..FBD2    ; Cn #  [33] <reserved-FBB2>..<reserved-FBD2>
-FD40..FD4F    ; Cn #  [16] <reserved-FD40>..<reserved-FD4F>
-FD90..FD91    ; Cn #   [2] <reserved-FD90>..<reserved-FD91>
-FDC8..FDEF    ; Cn #  [40] <reserved-FDC8>..<noncharacter-FDEF>
-FDFE..FDFF    ; Cn #   [2] <reserved-FDFE>..<reserved-FDFF>
-FE1A..FE1F    ; Cn #   [6] <reserved-FE1A>..<reserved-FE1F>
-FE27..FE2F    ; Cn #   [9] <reserved-FE27>..<reserved-FE2F>
-FE53          ; Cn #       <reserved-FE53>
-FE67          ; Cn #       <reserved-FE67>
-FE6C..FE6F    ; Cn #   [4] <reserved-FE6C>..<reserved-FE6F>
-FE75          ; Cn #       <reserved-FE75>
-FEFD..FEFE    ; Cn #   [2] <reserved-FEFD>..<reserved-FEFE>
-FF00          ; Cn #       <reserved-FF00>
-FFBF..FFC1    ; Cn #   [3] <reserved-FFBF>..<reserved-FFC1>
-FFC8..FFC9    ; Cn #   [2] <reserved-FFC8>..<reserved-FFC9>
-FFD0..FFD1    ; Cn #   [2] <reserved-FFD0>..<reserved-FFD1>
-FFD8..FFD9    ; Cn #   [2] <reserved-FFD8>..<reserved-FFD9>
-FFDD..FFDF    ; Cn #   [3] <reserved-FFDD>..<reserved-FFDF>
-FFE7          ; Cn #       <reserved-FFE7>
-FFEF..FFF8    ; Cn #  [10] <reserved-FFEF>..<reserved-FFF8>
-FFFE..FFFF    ; Cn #   [2] <noncharacter-FFFE>..<noncharacter-FFFF>
-1000C         ; Cn #       <reserved-1000C>
-10027         ; Cn #       <reserved-10027>
-1003B         ; Cn #       <reserved-1003B>
-1003E         ; Cn #       <reserved-1003E>
-1004E..1004F  ; Cn #   [2] <reserved-1004E>..<reserved-1004F>
-1005E..1007F  ; Cn #  [34] <reserved-1005E>..<reserved-1007F>
-100FB..100FF  ; Cn #   [5] <reserved-100FB>..<reserved-100FF>
-10103..10106  ; Cn #   [4] <reserved-10103>..<reserved-10106>
-10134..10136  ; Cn #   [3] <reserved-10134>..<reserved-10136>
-1018B..1018F  ; Cn #   [5] <reserved-1018B>..<reserved-1018F>
-1019C..101CF  ; Cn #  [52] <reserved-1019C>..<reserved-101CF>
-101FE..1027F  ; Cn # [130] <reserved-101FE>..<reserved-1027F>
-1029D..1029F  ; Cn #   [3] <reserved-1029D>..<reserved-1029F>
-102D1..102FF  ; Cn #  [47] <reserved-102D1>..<reserved-102FF>
-1031F         ; Cn #       <reserved-1031F>
-10324..1032F  ; Cn #  [12] <reserved-10324>..<reserved-1032F>
-1034B..1037F  ; Cn #  [53] <reserved-1034B>..<reserved-1037F>
-1039E         ; Cn #       <reserved-1039E>
-103C4..103C7  ; Cn #   [4] <reserved-103C4>..<reserved-103C7>
-103D6..103FF  ; Cn #  [42] <reserved-103D6>..<reserved-103FF>
-1049E..1049F  ; Cn #   [2] <reserved-1049E>..<reserved-1049F>
-104AA..107FF  ; Cn # [854] <reserved-104AA>..<reserved-107FF>
-10806..10807  ; Cn #   [2] <reserved-10806>..<reserved-10807>
-10809         ; Cn #       <reserved-10809>
-10836         ; Cn #       <reserved-10836>
-10839..1083B  ; Cn #   [3] <reserved-10839>..<reserved-1083B>
-1083D..1083E  ; Cn #   [2] <reserved-1083D>..<reserved-1083E>
-10840..108FF  ; Cn # [192] <reserved-10840>..<reserved-108FF>
-1091A..1091E  ; Cn #   [5] <reserved-1091A>..<reserved-1091E>
-1093A..1093E  ; Cn #   [5] <reserved-1093A>..<reserved-1093E>
-10940..109FF  ; Cn # [192] <reserved-10940>..<reserved-109FF>
-10A04         ; Cn #       <reserved-10A04>
-10A07..10A0B  ; Cn #   [5] <reserved-10A07>..<reserved-10A0B>
-10A14         ; Cn #       <reserved-10A14>
-10A18         ; Cn #       <reserved-10A18>
-10A34..10A37  ; Cn #   [4] <reserved-10A34>..<reserved-10A37>
-10A3B..10A3E  ; Cn #   [4] <reserved-10A3B>..<reserved-10A3E>
-10A48..10A4F  ; Cn #   [8] <reserved-10A48>..<reserved-10A4F>
-10A59..11FFF  ; Cn # [5543] <reserved-10A59>..<reserved-11FFF>
-1236F..123FF  ; Cn # [145] <reserved-1236F>..<reserved-123FF>
-12463..1246F  ; Cn #  [13] <reserved-12463>..<reserved-1246F>
-12474..1CFFF  ; Cn # [43916] <reserved-12474>..<reserved-1CFFF>
-1D0F6..1D0FF  ; Cn #  [10] <reserved-1D0F6>..<reserved-1D0FF>
-1D127..1D128  ; Cn #   [2] <reserved-1D127>..<reserved-1D128>
-1D1DE..1D1FF  ; Cn #  [34] <reserved-1D1DE>..<reserved-1D1FF>
-1D246..1D2FF  ; Cn # [186] <reserved-1D246>..<reserved-1D2FF>
-1D357..1D35F  ; Cn #   [9] <reserved-1D357>..<reserved-1D35F>
-1D372..1D3FF  ; Cn # [142] <reserved-1D372>..<reserved-1D3FF>
-1D455         ; Cn #       <reserved-1D455>
-1D49D         ; Cn #       <reserved-1D49D>
-1D4A0..1D4A1  ; Cn #   [2] <reserved-1D4A0>..<reserved-1D4A1>
-1D4A3..1D4A4  ; Cn #   [2] <reserved-1D4A3>..<reserved-1D4A4>
-1D4A7..1D4A8  ; Cn #   [2] <reserved-1D4A7>..<reserved-1D4A8>
-1D4AD         ; Cn #       <reserved-1D4AD>
-1D4BA         ; Cn #       <reserved-1D4BA>
-1D4BC         ; Cn #       <reserved-1D4BC>
-1D4C4         ; Cn #       <reserved-1D4C4>
-1D506         ; Cn #       <reserved-1D506>
-1D50B..1D50C  ; Cn #   [2] <reserved-1D50B>..<reserved-1D50C>
-1D515         ; Cn #       <reserved-1D515>
-1D51D         ; Cn #       <reserved-1D51D>
-1D53A         ; Cn #       <reserved-1D53A>
-1D53F         ; Cn #       <reserved-1D53F>
-1D545         ; Cn #       <reserved-1D545>
-1D547..1D549  ; Cn #   [3] <reserved-1D547>..<reserved-1D549>
-1D551         ; Cn #       <reserved-1D551>
-1D6A6..1D6A7  ; Cn #   [2] <reserved-1D6A6>..<reserved-1D6A7>
-1D7CC..1D7CD  ; Cn #   [2] <reserved-1D7CC>..<reserved-1D7CD>
-1D800..1EFFF  ; Cn # [6144] <reserved-1D800>..<reserved-1EFFF>
-1F02C..1F02F  ; Cn #   [4] <reserved-1F02C>..<reserved-1F02F>
-1F094..1FFFF  ; Cn # [3948] <reserved-1F094>..<noncharacter-1FFFF>
-2A6D7..2F7FF  ; Cn # [20777] <reserved-2A6D7>..<reserved-2F7FF>
-2FA1E..E0000  ; Cn # [722403] <reserved-2FA1E>..<reserved-E0000>
-E0002..E001F  ; Cn #  [30] <reserved-E0002>..<reserved-E001F>
-E0080..E00FF  ; Cn # [128] <reserved-E0080>..<reserved-E00FF>
-E01F0..EFFFF  ; Cn # [65040] <reserved-E01F0>..<noncharacter-EFFFF>
-FFFFE..FFFFF  ; Cn #   [2] <noncharacter-FFFFE>..<noncharacter-FFFFF>
-10FFFE..10FFFF; Cn #   [2] <noncharacter-10FFFE>..<noncharacter-10FFFF>
-
-# Total code points: 873883
-
-# ================================================
-
-# General_Category=Uppercase_Letter
-
-0041..005A    ; Lu #  [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z
-00C0..00D6    ; Lu #  [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS
-00D8..00DE    ; Lu #   [7] LATIN CAPITAL LETTER O WITH STROKE..LATIN CAPITAL LETTER THORN
-0100          ; Lu #       LATIN CAPITAL LETTER A WITH MACRON
-0102          ; Lu #       LATIN CAPITAL LETTER A WITH BREVE
-0104          ; Lu #       LATIN CAPITAL LETTER A WITH OGONEK
-0106          ; Lu #       LATIN CAPITAL LETTER C WITH ACUTE
-0108          ; Lu #       LATIN CAPITAL LETTER C WITH CIRCUMFLEX
-010A          ; Lu #       LATIN CAPITAL LETTER C WITH DOT ABOVE
-010C          ; Lu #       LATIN CAPITAL LETTER C WITH CARON
-010E          ; Lu #       LATIN CAPITAL LETTER D WITH CARON
-0110          ; Lu #       LATIN CAPITAL LETTER D WITH STROKE
-0112          ; Lu #       LATIN CAPITAL LETTER E WITH MACRON
-0114          ; Lu #       LATIN CAPITAL LETTER E WITH BREVE
-0116          ; Lu #       LATIN CAPITAL LETTER E WITH DOT ABOVE
-0118          ; Lu #       LATIN CAPITAL LETTER E WITH OGONEK
-011A          ; Lu #       LATIN CAPITAL LETTER E WITH CARON
-011C          ; Lu #       LATIN CAPITAL LETTER G WITH CIRCUMFLEX
-011E          ; Lu #       LATIN CAPITAL LETTER G WITH BREVE
-0120          ; Lu #       LATIN CAPITAL LETTER G WITH DOT ABOVE
-0122          ; Lu #       LATIN CAPITAL LETTER G WITH CEDILLA
-0124          ; Lu #       LATIN CAPITAL LETTER H WITH CIRCUMFLEX
-0126          ; Lu #       LATIN CAPITAL LETTER H WITH STROKE
-0128          ; Lu #       LATIN CAPITAL LETTER I WITH TILDE
-012A          ; Lu #       LATIN CAPITAL LETTER I WITH MACRON
-012C          ; Lu #       LATIN CAPITAL LETTER I WITH BREVE
-012E          ; Lu #       LATIN CAPITAL LETTER I WITH OGONEK
-0130          ; Lu #       LATIN CAPITAL LETTER I WITH DOT ABOVE
-0132          ; Lu #       LATIN CAPITAL LIGATURE IJ
-0134          ; Lu #       LATIN CAPITAL LETTER J WITH CIRCUMFLEX
-0136          ; Lu #       LATIN CAPITAL LETTER K WITH CEDILLA
-0139          ; Lu #       LATIN CAPITAL LETTER L WITH ACUTE
-013B          ; Lu #       LATIN CAPITAL LETTER L WITH CEDILLA
-013D          ; Lu #       LATIN CAPITAL LETTER L WITH CARON
-013F          ; Lu #       LATIN CAPITAL LETTER L WITH MIDDLE DOT
-0141          ; Lu #       LATIN CAPITAL LETTER L WITH STROKE
-0143          ; Lu #       LATIN CAPITAL LETTER N WITH ACUTE
-0145          ; Lu #       LATIN CAPITAL LETTER N WITH CEDILLA
-0147          ; Lu #       LATIN CAPITAL LETTER N WITH CARON
-014A          ; Lu #       LATIN CAPITAL LETTER ENG
-014C          ; Lu #       LATIN CAPITAL LETTER O WITH MACRON
-014E          ; Lu #       LATIN CAPITAL LETTER O WITH BREVE
-0150          ; Lu #       LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
-0152          ; Lu #       LATIN CAPITAL LIGATURE OE
-0154          ; Lu #       LATIN CAPITAL LETTER R WITH ACUTE
-0156          ; Lu #       LATIN CAPITAL LETTER R WITH CEDILLA
-0158          ; Lu #       LATIN CAPITAL LETTER R WITH CARON
-015A          ; Lu #       LATIN CAPITAL LETTER S WITH ACUTE
-015C          ; Lu #       LATIN CAPITAL LETTER S WITH CIRCUMFLEX
-015E          ; Lu #       LATIN CAPITAL LETTER S WITH CEDILLA
-0160          ; Lu #       LATIN CAPITAL LETTER S WITH CARON
-0162          ; Lu #       LATIN CAPITAL LETTER T WITH CEDILLA
-0164          ; Lu #       LATIN CAPITAL LETTER T WITH CARON
-0166          ; Lu #       LATIN CAPITAL LETTER T WITH STROKE
-0168          ; Lu #       LATIN CAPITAL LETTER U WITH TILDE
-016A          ; Lu #       LATIN CAPITAL LETTER U WITH MACRON
-016C          ; Lu #       LATIN CAPITAL LETTER U WITH BREVE
-016E          ; Lu #       LATIN CAPITAL LETTER U WITH RING ABOVE
-0170          ; Lu #       LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
-0172          ; Lu #       LATIN CAPITAL LETTER U WITH OGONEK
-0174          ; Lu #       LATIN CAPITAL LETTER W WITH CIRCUMFLEX
-0176          ; Lu #       LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
-0178..0179    ; Lu #   [2] LATIN CAPITAL LETTER Y WITH DIAERESIS..LATIN CAPITAL LETTER Z WITH ACUTE
-017B          ; Lu #       LATIN CAPITAL LETTER Z WITH DOT ABOVE
-017D          ; Lu #       LATIN CAPITAL LETTER Z WITH CARON
-0181..0182    ; Lu #   [2] LATIN CAPITAL LETTER B WITH HOOK..LATIN CAPITAL LETTER B WITH TOPBAR
-0184          ; Lu #       LATIN CAPITAL LETTER TONE SIX
-0186..0187    ; Lu #   [2] LATIN CAPITAL LETTER OPEN O..LATIN CAPITAL LETTER C WITH HOOK
-0189..018B    ; Lu #   [3] LATIN CAPITAL LETTER AFRICAN D..LATIN CAPITAL LETTER D WITH TOPBAR
-018E..0191    ; Lu #   [4] LATIN CAPITAL LETTER REVERSED E..LATIN CAPITAL LETTER F WITH HOOK
-0193..0194    ; Lu #   [2] LATIN CAPITAL LETTER G WITH HOOK..LATIN CAPITAL LETTER GAMMA
-0196..0198    ; Lu #   [3] LATIN CAPITAL LETTER IOTA..LATIN CAPITAL LETTER K WITH HOOK
-019C..019D    ; Lu #   [2] LATIN CAPITAL LETTER TURNED M..LATIN CAPITAL LETTER N WITH LEFT HOOK
-019F..01A0    ; Lu #   [2] LATIN CAPITAL LETTER O WITH MIDDLE TILDE..LATIN CAPITAL LETTER O WITH HORN
-01A2          ; Lu #       LATIN CAPITAL LETTER OI
-01A4          ; Lu #       LATIN CAPITAL LETTER P WITH HOOK
-01A6..01A7    ; Lu #   [2] LATIN LETTER YR..LATIN CAPITAL LETTER TONE TWO
-01A9          ; Lu #       LATIN CAPITAL LETTER ESH
-01AC          ; Lu #       LATIN CAPITAL LETTER T WITH HOOK
-01AE..01AF    ; Lu #   [2] LATIN CAPITAL LETTER T WITH RETROFLEX HOOK..LATIN CAPITAL LETTER U WITH HORN
-01B1..01B3    ; Lu #   [3] LATIN CAPITAL LETTER UPSILON..LATIN CAPITAL LETTER Y WITH HOOK
-01B5          ; Lu #       LATIN CAPITAL LETTER Z WITH STROKE
-01B7..01B8    ; Lu #   [2] LATIN CAPITAL LETTER EZH..LATIN CAPITAL LETTER EZH REVERSED
-01BC          ; Lu #       LATIN CAPITAL LETTER TONE FIVE
-01C4          ; Lu #       LATIN CAPITAL LETTER DZ WITH CARON
-01C7          ; Lu #       LATIN CAPITAL LETTER LJ
-01CA          ; Lu #       LATIN CAPITAL LETTER NJ
-01CD          ; Lu #       LATIN CAPITAL LETTER A WITH CARON
-01CF          ; Lu #       LATIN CAPITAL LETTER I WITH CARON
-01D1          ; Lu #       LATIN CAPITAL LETTER O WITH CARON
-01D3          ; Lu #       LATIN CAPITAL LETTER U WITH CARON
-01D5          ; Lu #       LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
-01D7          ; Lu #       LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
-01D9          ; Lu #       LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
-01DB          ; Lu #       LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
-01DE          ; Lu #       LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
-01E0          ; Lu #       LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
-01E2          ; Lu #       LATIN CAPITAL LETTER AE WITH MACRON
-01E4          ; Lu #       LATIN CAPITAL LETTER G WITH STROKE
-01E6          ; Lu #       LATIN CAPITAL LETTER G WITH CARON
-01E8          ; Lu #       LATIN CAPITAL LETTER K WITH CARON
-01EA          ; Lu #       LATIN CAPITAL LETTER O WITH OGONEK
-01EC          ; Lu #       LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
-01EE          ; Lu #       LATIN CAPITAL LETTER EZH WITH CARON
-01F1          ; Lu #       LATIN CAPITAL LETTER DZ
-01F4          ; Lu #       LATIN CAPITAL LETTER G WITH ACUTE
-01F6..01F8    ; Lu #   [3] LATIN CAPITAL LETTER HWAIR..LATIN CAPITAL LETTER N WITH GRAVE
-01FA          ; Lu #       LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
-01FC          ; Lu #       LATIN CAPITAL LETTER AE WITH ACUTE
-01FE          ; Lu #       LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
-0200          ; Lu #       LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
-0202          ; Lu #       LATIN CAPITAL LETTER A WITH INVERTED BREVE
-0204          ; Lu #       LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
-0206          ; Lu #       LATIN CAPITAL LETTER E WITH INVERTED BREVE
-0208          ; Lu #       LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
-020A          ; Lu #       LATIN CAPITAL LETTER I WITH INVERTED BREVE
-020C          ; Lu #       LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
-020E          ; Lu #       LATIN CAPITAL LETTER O WITH INVERTED BREVE
-0210          ; Lu #       LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
-0212          ; Lu #       LATIN CAPITAL LETTER R WITH INVERTED BREVE
-0214          ; Lu #       LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
-0216          ; Lu #       LATIN CAPITAL LETTER U WITH INVERTED BREVE
-0218          ; Lu #       LATIN CAPITAL LETTER S WITH COMMA BELOW
-021A          ; Lu #       LATIN CAPITAL LETTER T WITH COMMA BELOW
-021C          ; Lu #       LATIN CAPITAL LETTER YOGH
-021E          ; Lu #       LATIN CAPITAL LETTER H WITH CARON
-0220          ; Lu #       LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
-0222          ; Lu #       LATIN CAPITAL LETTER OU
-0224          ; Lu #       LATIN CAPITAL LETTER Z WITH HOOK
-0226          ; Lu #       LATIN CAPITAL LETTER A WITH DOT ABOVE
-0228          ; Lu #       LATIN CAPITAL LETTER E WITH CEDILLA
-022A          ; Lu #       LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
-022C          ; Lu #       LATIN CAPITAL LETTER O WITH TILDE AND MACRON
-022E          ; Lu #       LATIN CAPITAL LETTER O WITH DOT ABOVE
-0230          ; Lu #       LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
-0232          ; Lu #       LATIN CAPITAL LETTER Y WITH MACRON
-023A..023B    ; Lu #   [2] LATIN CAPITAL LETTER A WITH STROKE..LATIN CAPITAL LETTER C WITH STROKE
-023D..023E    ; Lu #   [2] LATIN CAPITAL LETTER L WITH BAR..LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
-0241          ; Lu #       LATIN CAPITAL LETTER GLOTTAL STOP
-0243..0246    ; Lu #   [4] LATIN CAPITAL LETTER B WITH STROKE..LATIN CAPITAL LETTER E WITH STROKE
-0248          ; Lu #       LATIN CAPITAL LETTER J WITH STROKE
-024A          ; Lu #       LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
-024C          ; Lu #       LATIN CAPITAL LETTER R WITH STROKE
-024E          ; Lu #       LATIN CAPITAL LETTER Y WITH STROKE
-0370          ; Lu #       GREEK CAPITAL LETTER HETA
-0372          ; Lu #       GREEK CAPITAL LETTER ARCHAIC SAMPI
-0376          ; Lu #       GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA
-0386          ; Lu #       GREEK CAPITAL LETTER ALPHA WITH TONOS
-0388..038A    ; Lu #   [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS
-038C          ; Lu #       GREEK CAPITAL LETTER OMICRON WITH TONOS
-038E..038F    ; Lu #   [2] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER OMEGA WITH TONOS
-0391..03A1    ; Lu #  [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO
-03A3..03AB    ; Lu #   [9] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
-03CF          ; Lu #       GREEK CAPITAL KAI SYMBOL
-03D2..03D4    ; Lu #   [3] GREEK UPSILON WITH HOOK SYMBOL..GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL
-03D8          ; Lu #       GREEK LETTER ARCHAIC KOPPA
-03DA          ; Lu #       GREEK LETTER STIGMA
-03DC          ; Lu #       GREEK LETTER DIGAMMA
-03DE          ; Lu #       GREEK LETTER KOPPA
-03E0          ; Lu #       GREEK LETTER SAMPI
-03E2          ; Lu #       COPTIC CAPITAL LETTER SHEI
-03E4          ; Lu #       COPTIC CAPITAL LETTER FEI
-03E6          ; Lu #       COPTIC CAPITAL LETTER KHEI
-03E8          ; Lu #       COPTIC CAPITAL LETTER HORI
-03EA          ; Lu #       COPTIC CAPITAL LETTER GANGIA
-03EC          ; Lu #       COPTIC CAPITAL LETTER SHIMA
-03EE          ; Lu #       COPTIC CAPITAL LETTER DEI
-03F4          ; Lu #       GREEK CAPITAL THETA SYMBOL
-03F7          ; Lu #       GREEK CAPITAL LETTER SHO
-03F9..03FA    ; Lu #   [2] GREEK CAPITAL LUNATE SIGMA SYMBOL..GREEK CAPITAL LETTER SAN
-03FD..042F    ; Lu #  [51] GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL..CYRILLIC CAPITAL LETTER YA
-0460          ; Lu #       CYRILLIC CAPITAL LETTER OMEGA
-0462          ; Lu #       CYRILLIC CAPITAL LETTER YAT
-0464          ; Lu #       CYRILLIC CAPITAL LETTER IOTIFIED E
-0466          ; Lu #       CYRILLIC CAPITAL LETTER LITTLE YUS
-0468          ; Lu #       CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
-046A          ; Lu #       CYRILLIC CAPITAL LETTER BIG YUS
-046C          ; Lu #       CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
-046E          ; Lu #       CYRILLIC CAPITAL LETTER KSI
-0470          ; Lu #       CYRILLIC CAPITAL LETTER PSI
-0472          ; Lu #       CYRILLIC CAPITAL LETTER FITA
-0474          ; Lu #       CYRILLIC CAPITAL LETTER IZHITSA
-0476          ; Lu #       CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
-0478          ; Lu #       CYRILLIC CAPITAL LETTER UK
-047A          ; Lu #       CYRILLIC CAPITAL LETTER ROUND OMEGA
-047C          ; Lu #       CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
-047E          ; Lu #       CYRILLIC CAPITAL LETTER OT
-0480          ; Lu #       CYRILLIC CAPITAL LETTER KOPPA
-048A          ; Lu #       CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
-048C          ; Lu #       CYRILLIC CAPITAL LETTER SEMISOFT SIGN
-048E          ; Lu #       CYRILLIC CAPITAL LETTER ER WITH TICK
-0490          ; Lu #       CYRILLIC CAPITAL LETTER GHE WITH UPTURN
-0492          ; Lu #       CYRILLIC CAPITAL LETTER GHE WITH STROKE
-0494          ; Lu #       CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
-0496          ; Lu #       CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
-0498          ; Lu #       CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
-049A          ; Lu #       CYRILLIC CAPITAL LETTER KA WITH DESCENDER
-049C          ; Lu #       CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
-049E          ; Lu #       CYRILLIC CAPITAL LETTER KA WITH STROKE
-04A0          ; Lu #       CYRILLIC CAPITAL LETTER BASHKIR KA
-04A2          ; Lu #       CYRILLIC CAPITAL LETTER EN WITH DESCENDER
-04A4          ; Lu #       CYRILLIC CAPITAL LIGATURE EN GHE
-04A6          ; Lu #       CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
-04A8          ; Lu #       CYRILLIC CAPITAL LETTER ABKHASIAN HA
-04AA          ; Lu #       CYRILLIC CAPITAL LETTER ES WITH DESCENDER
-04AC          ; Lu #       CYRILLIC CAPITAL LETTER TE WITH DESCENDER
-04AE          ; Lu #       CYRILLIC CAPITAL LETTER STRAIGHT U
-04B0          ; Lu #       CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
-04B2          ; Lu #       CYRILLIC CAPITAL LETTER HA WITH DESCENDER
-04B4          ; Lu #       CYRILLIC CAPITAL LIGATURE TE TSE
-04B6          ; Lu #       CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
-04B8          ; Lu #       CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
-04BA          ; Lu #       CYRILLIC CAPITAL LETTER SHHA
-04BC          ; Lu #       CYRILLIC CAPITAL LETTER ABKHASIAN CHE
-04BE          ; Lu #       CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
-04C0..04C1    ; Lu #   [2] CYRILLIC LETTER PALOCHKA..CYRILLIC CAPITAL LETTER ZHE WITH BREVE
-04C3          ; Lu #       CYRILLIC CAPITAL LETTER KA WITH HOOK
-04C5          ; Lu #       CYRILLIC CAPITAL LETTER EL WITH TAIL
-04C7          ; Lu #       CYRILLIC CAPITAL LETTER EN WITH HOOK
-04C9          ; Lu #       CYRILLIC CAPITAL LETTER EN WITH TAIL
-04CB          ; Lu #       CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
-04CD          ; Lu #       CYRILLIC CAPITAL LETTER EM WITH TAIL
-04D0          ; Lu #       CYRILLIC CAPITAL LETTER A WITH BREVE
-04D2          ; Lu #       CYRILLIC CAPITAL LETTER A WITH DIAERESIS
-04D4          ; Lu #       CYRILLIC CAPITAL LIGATURE A IE
-04D6          ; Lu #       CYRILLIC CAPITAL LETTER IE WITH BREVE
-04D8          ; Lu #       CYRILLIC CAPITAL LETTER SCHWA
-04DA          ; Lu #       CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
-04DC          ; Lu #       CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
-04DE          ; Lu #       CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
-04E0          ; Lu #       CYRILLIC CAPITAL LETTER ABKHASIAN DZE
-04E2          ; Lu #       CYRILLIC CAPITAL LETTER I WITH MACRON
-04E4          ; Lu #       CYRILLIC CAPITAL LETTER I WITH DIAERESIS
-04E6          ; Lu #       CYRILLIC CAPITAL LETTER O WITH DIAERESIS
-04E8          ; Lu #       CYRILLIC CAPITAL LETTER BARRED O
-04EA          ; Lu #       CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
-04EC          ; Lu #       CYRILLIC CAPITAL LETTER E WITH DIAERESIS
-04EE          ; Lu #       CYRILLIC CAPITAL LETTER U WITH MACRON
-04F0          ; Lu #       CYRILLIC CAPITAL LETTER U WITH DIAERESIS
-04F2          ; Lu #       CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
-04F4          ; Lu #       CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
-04F6          ; Lu #       CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
-04F8          ; Lu #       CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
-04FA          ; Lu #       CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
-04FC          ; Lu #       CYRILLIC CAPITAL LETTER HA WITH HOOK
-04FE          ; Lu #       CYRILLIC CAPITAL LETTER HA WITH STROKE
-0500          ; Lu #       CYRILLIC CAPITAL LETTER KOMI DE
-0502          ; Lu #       CYRILLIC CAPITAL LETTER KOMI DJE
-0504          ; Lu #       CYRILLIC CAPITAL LETTER KOMI ZJE
-0506          ; Lu #       CYRILLIC CAPITAL LETTER KOMI DZJE
-0508          ; Lu #       CYRILLIC CAPITAL LETTER KOMI LJE
-050A          ; Lu #       CYRILLIC CAPITAL LETTER KOMI NJE
-050C          ; Lu #       CYRILLIC CAPITAL LETTER KOMI SJE
-050E          ; Lu #       CYRILLIC CAPITAL LETTER KOMI TJE
-0510          ; Lu #       CYRILLIC CAPITAL LETTER REVERSED ZE
-0512          ; Lu #       CYRILLIC CAPITAL LETTER EL WITH HOOK
-0514          ; Lu #       CYRILLIC CAPITAL LETTER LHA
-0516          ; Lu #       CYRILLIC CAPITAL LETTER RHA
-0518          ; Lu #       CYRILLIC CAPITAL LETTER YAE
-051A          ; Lu #       CYRILLIC CAPITAL LETTER QA
-051C          ; Lu #       CYRILLIC CAPITAL LETTER WE
-051E          ; Lu #       CYRILLIC CAPITAL LETTER ALEUT KA
-0520          ; Lu #       CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK
-0522          ; Lu #       CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK
-0531..0556    ; Lu #  [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH
-10A0..10C5    ; Lu #  [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE
-1E00          ; Lu #       LATIN CAPITAL LETTER A WITH RING BELOW
-1E02          ; Lu #       LATIN CAPITAL LETTER B WITH DOT ABOVE
-1E04          ; Lu #       LATIN CAPITAL LETTER B WITH DOT BELOW
-1E06          ; Lu #       LATIN CAPITAL LETTER B WITH LINE BELOW
-1E08          ; Lu #       LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
-1E0A          ; Lu #       LATIN CAPITAL LETTER D WITH DOT ABOVE
-1E0C          ; Lu #       LATIN CAPITAL LETTER D WITH DOT BELOW
-1E0E          ; Lu #       LATIN CAPITAL LETTER D WITH LINE BELOW
-1E10          ; Lu #       LATIN CAPITAL LETTER D WITH CEDILLA
-1E12          ; Lu #       LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
-1E14          ; Lu #       LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
-1E16          ; Lu #       LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
-1E18          ; Lu #       LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
-1E1A          ; Lu #       LATIN CAPITAL LETTER E WITH TILDE BELOW
-1E1C          ; Lu #       LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
-1E1E          ; Lu #       LATIN CAPITAL LETTER F WITH DOT ABOVE
-1E20          ; Lu #       LATIN CAPITAL LETTER G WITH MACRON
-1E22          ; Lu #       LATIN CAPITAL LETTER H WITH DOT ABOVE
-1E24          ; Lu #       LATIN CAPITAL LETTER H WITH DOT BELOW
-1E26          ; Lu #       LATIN CAPITAL LETTER H WITH DIAERESIS
-1E28          ; Lu #       LATIN CAPITAL LETTER H WITH CEDILLA
-1E2A          ; Lu #       LATIN CAPITAL LETTER H WITH BREVE BELOW
-1E2C          ; Lu #       LATIN CAPITAL LETTER I WITH TILDE BELOW
-1E2E          ; Lu #       LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
-1E30          ; Lu #       LATIN CAPITAL LETTER K WITH ACUTE
-1E32          ; Lu #       LATIN CAPITAL LETTER K WITH DOT BELOW
-1E34          ; Lu #       LATIN CAPITAL LETTER K WITH LINE BELOW
-1E36          ; Lu #       LATIN CAPITAL LETTER L WITH DOT BELOW
-1E38          ; Lu #       LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
-1E3A          ; Lu #       LATIN CAPITAL LETTER L WITH LINE BELOW
-1E3C          ; Lu #       LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
-1E3E          ; Lu #       LATIN CAPITAL LETTER M WITH ACUTE
-1E40          ; Lu #       LATIN CAPITAL LETTER M WITH DOT ABOVE
-1E42          ; Lu #       LATIN CAPITAL LETTER M WITH DOT BELOW
-1E44          ; Lu #       LATIN CAPITAL LETTER N WITH DOT ABOVE
-1E46          ; Lu #       LATIN CAPITAL LETTER N WITH DOT BELOW
-1E48          ; Lu #       LATIN CAPITAL LETTER N WITH LINE BELOW
-1E4A          ; Lu #       LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
-1E4C          ; Lu #       LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
-1E4E          ; Lu #       LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
-1E50          ; Lu #       LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
-1E52          ; Lu #       LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
-1E54          ; Lu #       LATIN CAPITAL LETTER P WITH ACUTE
-1E56          ; Lu #       LATIN CAPITAL LETTER P WITH DOT ABOVE
-1E58          ; Lu #       LATIN CAPITAL LETTER R WITH DOT ABOVE
-1E5A          ; Lu #       LATIN CAPITAL LETTER R WITH DOT BELOW
-1E5C          ; Lu #       LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
-1E5E          ; Lu #       LATIN CAPITAL LETTER R WITH LINE BELOW
-1E60          ; Lu #       LATIN CAPITAL LETTER S WITH DOT ABOVE
-1E62          ; Lu #       LATIN CAPITAL LETTER S WITH DOT BELOW
-1E64          ; Lu #       LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
-1E66          ; Lu #       LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
-1E68          ; Lu #       LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
-1E6A          ; Lu #       LATIN CAPITAL LETTER T WITH DOT ABOVE
-1E6C          ; Lu #       LATIN CAPITAL LETTER T WITH DOT BELOW
-1E6E          ; Lu #       LATIN CAPITAL LETTER T WITH LINE BELOW
-1E70          ; Lu #       LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
-1E72          ; Lu #       LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
-1E74          ; Lu #       LATIN CAPITAL LETTER U WITH TILDE BELOW
-1E76          ; Lu #       LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
-1E78          ; Lu #       LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
-1E7A          ; Lu #       LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
-1E7C          ; Lu #       LATIN CAPITAL LETTER V WITH TILDE
-1E7E          ; Lu #       LATIN CAPITAL LETTER V WITH DOT BELOW
-1E80          ; Lu #       LATIN CAPITAL LETTER W WITH GRAVE
-1E82          ; Lu #       LATIN CAPITAL LETTER W WITH ACUTE
-1E84          ; Lu #       LATIN CAPITAL LETTER W WITH DIAERESIS
-1E86          ; Lu #       LATIN CAPITAL LETTER W WITH DOT ABOVE
-1E88          ; Lu #       LATIN CAPITAL LETTER W WITH DOT BELOW
-1E8A          ; Lu #       LATIN CAPITAL LETTER X WITH DOT ABOVE
-1E8C          ; Lu #       LATIN CAPITAL LETTER X WITH DIAERESIS
-1E8E          ; Lu #       LATIN CAPITAL LETTER Y WITH DOT ABOVE
-1E90          ; Lu #       LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
-1E92          ; Lu #       LATIN CAPITAL LETTER Z WITH DOT BELOW
-1E94          ; Lu #       LATIN CAPITAL LETTER Z WITH LINE BELOW
-1E9E          ; Lu #       LATIN CAPITAL LETTER SHARP S
-1EA0          ; Lu #       LATIN CAPITAL LETTER A WITH DOT BELOW
-1EA2          ; Lu #       LATIN CAPITAL LETTER A WITH HOOK ABOVE
-1EA4          ; Lu #       LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
-1EA6          ; Lu #       LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
-1EA8          ; Lu #       LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
-1EAA          ; Lu #       LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
-1EAC          ; Lu #       LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
-1EAE          ; Lu #       LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
-1EB0          ; Lu #       LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
-1EB2          ; Lu #       LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
-1EB4          ; Lu #       LATIN CAPITAL LETTER A WITH BREVE AND TILDE
-1EB6          ; Lu #       LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
-1EB8          ; Lu #       LATIN CAPITAL LETTER E WITH DOT BELOW
-1EBA          ; Lu #       LATIN CAPITAL LETTER E WITH HOOK ABOVE
-1EBC          ; Lu #       LATIN CAPITAL LETTER E WITH TILDE
-1EBE          ; Lu #       LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
-1EC0          ; Lu #       LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
-1EC2          ; Lu #       LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
-1EC4          ; Lu #       LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
-1EC6          ; Lu #       LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
-1EC8          ; Lu #       LATIN CAPITAL LETTER I WITH HOOK ABOVE
-1ECA          ; Lu #       LATIN CAPITAL LETTER I WITH DOT BELOW
-1ECC          ; Lu #       LATIN CAPITAL LETTER O WITH DOT BELOW
-1ECE          ; Lu #       LATIN CAPITAL LETTER O WITH HOOK ABOVE
-1ED0          ; Lu #       LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
-1ED2          ; Lu #       LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
-1ED4          ; Lu #       LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
-1ED6          ; Lu #       LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
-1ED8          ; Lu #       LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
-1EDA          ; Lu #       LATIN CAPITAL LETTER O WITH HORN AND ACUTE
-1EDC          ; Lu #       LATIN CAPITAL LETTER O WITH HORN AND GRAVE
-1EDE          ; Lu #       LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
-1EE0          ; Lu #       LATIN CAPITAL LETTER O WITH HORN AND TILDE
-1EE2          ; Lu #       LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
-1EE4          ; Lu #       LATIN CAPITAL LETTER U WITH DOT BELOW
-1EE6          ; Lu #       LATIN CAPITAL LETTER U WITH HOOK ABOVE
-1EE8          ; Lu #       LATIN CAPITAL LETTER U WITH HORN AND ACUTE
-1EEA          ; Lu #       LATIN CAPITAL LETTER U WITH HORN AND GRAVE
-1EEC          ; Lu #       LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
-1EEE          ; Lu #       LATIN CAPITAL LETTER U WITH HORN AND TILDE
-1EF0          ; Lu #       LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
-1EF2          ; Lu #       LATIN CAPITAL LETTER Y WITH GRAVE
-1EF4          ; Lu #       LATIN CAPITAL LETTER Y WITH DOT BELOW
-1EF6          ; Lu #       LATIN CAPITAL LETTER Y WITH HOOK ABOVE
-1EF8          ; Lu #       LATIN CAPITAL LETTER Y WITH TILDE
-1EFA          ; Lu #       LATIN CAPITAL LETTER MIDDLE-WELSH LL
-1EFC          ; Lu #       LATIN CAPITAL LETTER MIDDLE-WELSH V
-1EFE          ; Lu #       LATIN CAPITAL LETTER Y WITH LOOP
-1F08..1F0F    ; Lu #   [8] GREEK CAPITAL LETTER ALPHA WITH PSILI..GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
-1F18..1F1D    ; Lu #   [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
-1F28..1F2F    ; Lu #   [8] GREEK CAPITAL LETTER ETA WITH PSILI..GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
-1F38..1F3F    ; Lu #   [8] GREEK CAPITAL LETTER IOTA WITH PSILI..GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
-1F48..1F4D    ; Lu #   [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
-1F59          ; Lu #       GREEK CAPITAL LETTER UPSILON WITH DASIA
-1F5B          ; Lu #       GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
-1F5D          ; Lu #       GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
-1F5F          ; Lu #       GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
-1F68..1F6F    ; Lu #   [8] GREEK CAPITAL LETTER OMEGA WITH PSILI..GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
-1FB8..1FBB    ; Lu #   [4] GREEK CAPITAL LETTER ALPHA WITH VRACHY..GREEK CAPITAL LETTER ALPHA WITH OXIA
-1FC8..1FCB    ; Lu #   [4] GREEK CAPITAL LETTER EPSILON WITH VARIA..GREEK CAPITAL LETTER ETA WITH OXIA
-1FD8..1FDB    ; Lu #   [4] GREEK CAPITAL LETTER IOTA WITH VRACHY..GREEK CAPITAL LETTER IOTA WITH OXIA
-1FE8..1FEC    ; Lu #   [5] GREEK CAPITAL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA
-1FF8..1FFB    ; Lu #   [4] GREEK CAPITAL LETTER OMICRON WITH VARIA..GREEK CAPITAL LETTER OMEGA WITH OXIA
-2102          ; Lu #       DOUBLE-STRUCK CAPITAL C
-2107          ; Lu #       EULER CONSTANT
-210B..210D    ; Lu #   [3] SCRIPT CAPITAL H..DOUBLE-STRUCK CAPITAL H
-2110..2112    ; Lu #   [3] SCRIPT CAPITAL I..SCRIPT CAPITAL L
-2115          ; Lu #       DOUBLE-STRUCK CAPITAL N
-2119..211D    ; Lu #   [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R
-2124          ; Lu #       DOUBLE-STRUCK CAPITAL Z
-2126          ; Lu #       OHM SIGN
-2128          ; Lu #       BLACK-LETTER CAPITAL Z
-212A..212D    ; Lu #   [4] KELVIN SIGN..BLACK-LETTER CAPITAL C
-2130..2133    ; Lu #   [4] SCRIPT CAPITAL E..SCRIPT CAPITAL M
-213E..213F    ; Lu #   [2] DOUBLE-STRUCK CAPITAL GAMMA..DOUBLE-STRUCK CAPITAL PI
-2145          ; Lu #       DOUBLE-STRUCK ITALIC CAPITAL D
-2183          ; Lu #       ROMAN NUMERAL REVERSED ONE HUNDRED
-2C00..2C2E    ; Lu #  [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
-2C60          ; Lu #       LATIN CAPITAL LETTER L WITH DOUBLE BAR
-2C62..2C64    ; Lu #   [3] LATIN CAPITAL LETTER L WITH MIDDLE TILDE..LATIN CAPITAL LETTER R WITH TAIL
-2C67          ; Lu #       LATIN CAPITAL LETTER H WITH DESCENDER
-2C69          ; Lu #       LATIN CAPITAL LETTER K WITH DESCENDER
-2C6B          ; Lu #       LATIN CAPITAL LETTER Z WITH DESCENDER
-2C6D..2C6F    ; Lu #   [3] LATIN CAPITAL LETTER ALPHA..LATIN CAPITAL LETTER TURNED A
-2C72          ; Lu #       LATIN CAPITAL LETTER W WITH HOOK
-2C75          ; Lu #       LATIN CAPITAL LETTER HALF H
-2C80          ; Lu #       COPTIC CAPITAL LETTER ALFA
-2C82          ; Lu #       COPTIC CAPITAL LETTER VIDA
-2C84          ; Lu #       COPTIC CAPITAL LETTER GAMMA
-2C86          ; Lu #       COPTIC CAPITAL LETTER DALDA
-2C88          ; Lu #       COPTIC CAPITAL LETTER EIE
-2C8A          ; Lu #       COPTIC CAPITAL LETTER SOU
-2C8C          ; Lu #       COPTIC CAPITAL LETTER ZATA
-2C8E          ; Lu #       COPTIC CAPITAL LETTER HATE
-2C90          ; Lu #       COPTIC CAPITAL LETTER THETHE
-2C92          ; Lu #       COPTIC CAPITAL LETTER IAUDA
-2C94          ; Lu #       COPTIC CAPITAL LETTER KAPA
-2C96          ; Lu #       COPTIC CAPITAL LETTER LAULA
-2C98          ; Lu #       COPTIC CAPITAL LETTER MI
-2C9A          ; Lu #       COPTIC CAPITAL LETTER NI
-2C9C          ; Lu #       COPTIC CAPITAL LETTER KSI
-2C9E          ; Lu #       COPTIC CAPITAL LETTER O
-2CA0          ; Lu #       COPTIC CAPITAL LETTER PI
-2CA2          ; Lu #       COPTIC CAPITAL LETTER RO
-2CA4          ; Lu #       COPTIC CAPITAL LETTER SIMA
-2CA6          ; Lu #       COPTIC CAPITAL LETTER TAU
-2CA8          ; Lu #       COPTIC CAPITAL LETTER UA
-2CAA          ; Lu #       COPTIC CAPITAL LETTER FI
-2CAC          ; Lu #       COPTIC CAPITAL LETTER KHI
-2CAE          ; Lu #       COPTIC CAPITAL LETTER PSI
-2CB0          ; Lu #       COPTIC CAPITAL LETTER OOU
-2CB2          ; Lu #       COPTIC CAPITAL LETTER DIALECT-P ALEF
-2CB4          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC AIN
-2CB6          ; Lu #       COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
-2CB8          ; Lu #       COPTIC CAPITAL LETTER DIALECT-P KAPA
-2CBA          ; Lu #       COPTIC CAPITAL LETTER DIALECT-P NI
-2CBC          ; Lu #       COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
-2CBE          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC OOU
-2CC0          ; Lu #       COPTIC CAPITAL LETTER SAMPI
-2CC2          ; Lu #       COPTIC CAPITAL LETTER CROSSED SHEI
-2CC4          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC SHEI
-2CC6          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC ESH
-2CC8          ; Lu #       COPTIC CAPITAL LETTER AKHMIMIC KHEI
-2CCA          ; Lu #       COPTIC CAPITAL LETTER DIALECT-P HORI
-2CCC          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC HORI
-2CCE          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC HA
-2CD0          ; Lu #       COPTIC CAPITAL LETTER L-SHAPED HA
-2CD2          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC HEI
-2CD4          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC HAT
-2CD6          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC GANGIA
-2CD8          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC DJA
-2CDA          ; Lu #       COPTIC CAPITAL LETTER OLD COPTIC SHIMA
-2CDC          ; Lu #       COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
-2CDE          ; Lu #       COPTIC CAPITAL LETTER OLD NUBIAN NGI
-2CE0          ; Lu #       COPTIC CAPITAL LETTER OLD NUBIAN NYI
-2CE2          ; Lu #       COPTIC CAPITAL LETTER OLD NUBIAN WAU
-A640          ; Lu #       CYRILLIC CAPITAL LETTER ZEMLYA
-A642          ; Lu #       CYRILLIC CAPITAL LETTER DZELO
-A644          ; Lu #       CYRILLIC CAPITAL LETTER REVERSED DZE
-A646          ; Lu #       CYRILLIC CAPITAL LETTER IOTA
-A648          ; Lu #       CYRILLIC CAPITAL LETTER DJERV
-A64A          ; Lu #       CYRILLIC CAPITAL LETTER MONOGRAPH UK
-A64C          ; Lu #       CYRILLIC CAPITAL LETTER BROAD OMEGA
-A64E          ; Lu #       CYRILLIC CAPITAL LETTER NEUTRAL YER
-A650          ; Lu #       CYRILLIC CAPITAL LETTER YERU WITH BACK YER
-A652          ; Lu #       CYRILLIC CAPITAL LETTER IOTIFIED YAT
-A654          ; Lu #       CYRILLIC CAPITAL LETTER REVERSED YU
-A656          ; Lu #       CYRILLIC CAPITAL LETTER IOTIFIED A
-A658          ; Lu #       CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS
-A65A          ; Lu #       CYRILLIC CAPITAL LETTER BLENDED YUS
-A65C          ; Lu #       CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS
-A65E          ; Lu #       CYRILLIC CAPITAL LETTER YN
-A662          ; Lu #       CYRILLIC CAPITAL LETTER SOFT DE
-A664          ; Lu #       CYRILLIC CAPITAL LETTER SOFT EL
-A666          ; Lu #       CYRILLIC CAPITAL LETTER SOFT EM
-A668          ; Lu #       CYRILLIC CAPITAL LETTER MONOCULAR O
-A66A          ; Lu #       CYRILLIC CAPITAL LETTER BINOCULAR O
-A66C          ; Lu #       CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O
-A680          ; Lu #       CYRILLIC CAPITAL LETTER DWE
-A682          ; Lu #       CYRILLIC CAPITAL LETTER DZWE
-A684          ; Lu #       CYRILLIC CAPITAL LETTER ZHWE
-A686          ; Lu #       CYRILLIC CAPITAL LETTER CCHE
-A688          ; Lu #       CYRILLIC CAPITAL LETTER DZZE
-A68A          ; Lu #       CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK
-A68C          ; Lu #       CYRILLIC CAPITAL LETTER TWE
-A68E          ; Lu #       CYRILLIC CAPITAL LETTER TSWE
-A690          ; Lu #       CYRILLIC CAPITAL LETTER TSSE
-A692          ; Lu #       CYRILLIC CAPITAL LETTER TCHE
-A694          ; Lu #       CYRILLIC CAPITAL LETTER HWE
-A696          ; Lu #       CYRILLIC CAPITAL LETTER SHWE
-A722          ; Lu #       LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF
-A724          ; Lu #       LATIN CAPITAL LETTER EGYPTOLOGICAL AIN
-A726          ; Lu #       LATIN CAPITAL LETTER HENG
-A728          ; Lu #       LATIN CAPITAL LETTER TZ
-A72A          ; Lu #       LATIN CAPITAL LETTER TRESILLO
-A72C          ; Lu #       LATIN CAPITAL LETTER CUATRILLO
-A72E          ; Lu #       LATIN CAPITAL LETTER CUATRILLO WITH COMMA
-A732          ; Lu #       LATIN CAPITAL LETTER AA
-A734          ; Lu #       LATIN CAPITAL LETTER AO
-A736          ; Lu #       LATIN CAPITAL LETTER AU
-A738          ; Lu #       LATIN CAPITAL LETTER AV
-A73A          ; Lu #       LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR
-A73C          ; Lu #       LATIN CAPITAL LETTER AY
-A73E          ; Lu #       LATIN CAPITAL LETTER REVERSED C WITH DOT
-A740          ; Lu #       LATIN CAPITAL LETTER K WITH STROKE
-A742          ; Lu #       LATIN CAPITAL LETTER K WITH DIAGONAL STROKE
-A744          ; Lu #       LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE
-A746          ; Lu #       LATIN CAPITAL LETTER BROKEN L
-A748          ; Lu #       LATIN CAPITAL LETTER L WITH HIGH STROKE
-A74A          ; Lu #       LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY
-A74C          ; Lu #       LATIN CAPITAL LETTER O WITH LOOP
-A74E          ; Lu #       LATIN CAPITAL LETTER OO
-A750          ; Lu #       LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER
-A752          ; Lu #       LATIN CAPITAL LETTER P WITH FLOURISH
-A754          ; Lu #       LATIN CAPITAL LETTER P WITH SQUIRREL TAIL
-A756          ; Lu #       LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER
-A758          ; Lu #       LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE
-A75A          ; Lu #       LATIN CAPITAL LETTER R ROTUNDA
-A75C          ; Lu #       LATIN CAPITAL LETTER RUM ROTUNDA
-A75E          ; Lu #       LATIN CAPITAL LETTER V WITH DIAGONAL STROKE
-A760          ; Lu #       LATIN CAPITAL LETTER VY
-A762          ; Lu #       LATIN CAPITAL LETTER VISIGOTHIC Z
-A764          ; Lu #       LATIN CAPITAL LETTER THORN WITH STROKE
-A766          ; Lu #       LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER
-A768          ; Lu #       LATIN CAPITAL LETTER VEND
-A76A          ; Lu #       LATIN CAPITAL LETTER ET
-A76C          ; Lu #       LATIN CAPITAL LETTER IS
-A76E          ; Lu #       LATIN CAPITAL LETTER CON
-A779          ; Lu #       LATIN CAPITAL LETTER INSULAR D
-A77B          ; Lu #       LATIN CAPITAL LETTER INSULAR F
-A77D..A77E    ; Lu #   [2] LATIN CAPITAL LETTER INSULAR G..LATIN CAPITAL LETTER TURNED INSULAR G
-A780          ; Lu #       LATIN CAPITAL LETTER TURNED L
-A782          ; Lu #       LATIN CAPITAL LETTER INSULAR R
-A784          ; Lu #       LATIN CAPITAL LETTER INSULAR S
-A786          ; Lu #       LATIN CAPITAL LETTER INSULAR T
-A78B          ; Lu #       LATIN CAPITAL LETTER SALTILLO
-FF21..FF3A    ; Lu #  [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
-10400..10427  ; Lu #  [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW
-1D400..1D419  ; Lu #  [26] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL BOLD CAPITAL Z
-1D434..1D44D  ; Lu #  [26] MATHEMATICAL ITALIC CAPITAL A..MATHEMATICAL ITALIC CAPITAL Z
-1D468..1D481  ; Lu #  [26] MATHEMATICAL BOLD ITALIC CAPITAL A..MATHEMATICAL BOLD ITALIC CAPITAL Z
-1D49C         ; Lu #       MATHEMATICAL SCRIPT CAPITAL A
-1D49E..1D49F  ; Lu #   [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D
-1D4A2         ; Lu #       MATHEMATICAL SCRIPT CAPITAL G
-1D4A5..1D4A6  ; Lu #   [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K
-1D4A9..1D4AC  ; Lu #   [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q
-1D4AE..1D4B5  ; Lu #   [8] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT CAPITAL Z
-1D4D0..1D4E9  ; Lu #  [26] MATHEMATICAL BOLD SCRIPT CAPITAL A..MATHEMATICAL BOLD SCRIPT CAPITAL Z
-1D504..1D505  ; Lu #   [2] MATHEMATICAL FRAKTUR CAPITAL A..MATHEMATICAL FRAKTUR CAPITAL B
-1D507..1D50A  ; Lu #   [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G
-1D50D..1D514  ; Lu #   [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q
-1D516..1D51C  ; Lu #   [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y
-1D538..1D539  ; Lu #   [2] MATHEMATICAL DOUBLE-STRUCK CAPITAL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B
-1D53B..1D53E  ; Lu #   [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G
-1D540..1D544  ; Lu #   [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M
-1D546         ; Lu #       MATHEMATICAL DOUBLE-STRUCK CAPITAL O
-1D54A..1D550  ; Lu #   [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
-1D56C..1D585  ; Lu #  [26] MATHEMATICAL BOLD FRAKTUR CAPITAL A..MATHEMATICAL BOLD FRAKTUR CAPITAL Z
-1D5A0..1D5B9  ; Lu #  [26] MATHEMATICAL SANS-SERIF CAPITAL A..MATHEMATICAL SANS-SERIF CAPITAL Z
-1D5D4..1D5ED  ; Lu #  [26] MATHEMATICAL SANS-SERIF BOLD CAPITAL A..MATHEMATICAL SANS-SERIF BOLD CAPITAL Z
-1D608..1D621  ; Lu #  [26] MATHEMATICAL SANS-SERIF ITALIC CAPITAL A..MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z
-1D63C..1D655  ; Lu #  [26] MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z
-1D670..1D689  ; Lu #  [26] MATHEMATICAL MONOSPACE CAPITAL A..MATHEMATICAL MONOSPACE CAPITAL Z
-1D6A8..1D6C0  ; Lu #  [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA
-1D6E2..1D6FA  ; Lu #  [25] MATHEMATICAL ITALIC CAPITAL ALPHA..MATHEMATICAL ITALIC CAPITAL OMEGA
-1D71C..1D734  ; Lu #  [25] MATHEMATICAL BOLD ITALIC CAPITAL ALPHA..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
-1D756..1D76E  ; Lu #  [25] MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
-1D790..1D7A8  ; Lu #  [25] MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
-1D7CA         ; Lu #       MATHEMATICAL BOLD CAPITAL DIGAMMA
-
-# Total code points: 1421
-
-# ================================================
-
-# General_Category=Lowercase_Letter
-
-0061..007A    ; Ll #  [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z
-00AA          ; Ll #       FEMININE ORDINAL INDICATOR
-00B5          ; Ll #       MICRO SIGN
-00BA          ; Ll #       MASCULINE ORDINAL INDICATOR
-00DF..00F6    ; Ll #  [24] LATIN SMALL LETTER SHARP S..LATIN SMALL LETTER O WITH DIAERESIS
-00F8..00FF    ; Ll #   [8] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS
-0101          ; Ll #       LATIN SMALL LETTER A WITH MACRON
-0103          ; Ll #       LATIN SMALL LETTER A WITH BREVE
-0105          ; Ll #       LATIN SMALL LETTER A WITH OGONEK
-0107          ; Ll #       LATIN SMALL LETTER C WITH ACUTE
-0109          ; Ll #       LATIN SMALL LETTER C WITH CIRCUMFLEX
-010B          ; Ll #       LATIN SMALL LETTER C WITH DOT ABOVE
-010D          ; Ll #       LATIN SMALL LETTER C WITH CARON
-010F          ; Ll #       LATIN SMALL LETTER D WITH CARON
-0111          ; Ll #       LATIN SMALL LETTER D WITH STROKE
-0113          ; Ll #       LATIN SMALL LETTER E WITH MACRON
-0115          ; Ll #       LATIN SMALL LETTER E WITH BREVE
-0117          ; Ll #       LATIN SMALL LETTER E WITH DOT ABOVE
-0119          ; Ll #       LATIN SMALL LETTER E WITH OGONEK
-011B          ; Ll #       LATIN SMALL LETTER E WITH CARON
-011D          ; Ll #       LATIN SMALL LETTER G WITH CIRCUMFLEX
-011F          ; Ll #       LATIN SMALL LETTER G WITH BREVE
-0121          ; Ll #       LATIN SMALL LETTER G WITH DOT ABOVE
-0123          ; Ll #       LATIN SMALL LETTER G WITH CEDILLA
-0125          ; Ll #       LATIN SMALL LETTER H WITH CIRCUMFLEX
-0127          ; Ll #       LATIN SMALL LETTER H WITH STROKE
-0129          ; Ll #       LATIN SMALL LETTER I WITH TILDE
-012B          ; Ll #       LATIN SMALL LETTER I WITH MACRON
-012D          ; Ll #       LATIN SMALL LETTER I WITH BREVE
-012F          ; Ll #       LATIN SMALL LETTER I WITH OGONEK
-0131          ; Ll #       LATIN SMALL LETTER DOTLESS I
-0133          ; Ll #       LATIN SMALL LIGATURE IJ
-0135          ; Ll #       LATIN SMALL LETTER J WITH CIRCUMFLEX
-0137..0138    ; Ll #   [2] LATIN SMALL LETTER K WITH CEDILLA..LATIN SMALL LETTER KRA
-013A          ; Ll #       LATIN SMALL LETTER L WITH ACUTE
-013C          ; Ll #       LATIN SMALL LETTER L WITH CEDILLA
-013E          ; Ll #       LATIN SMALL LETTER L WITH CARON
-0140          ; Ll #       LATIN SMALL LETTER L WITH MIDDLE DOT
-0142          ; Ll #       LATIN SMALL LETTER L WITH STROKE
-0144          ; Ll #       LATIN SMALL LETTER N WITH ACUTE
-0146          ; Ll #       LATIN SMALL LETTER N WITH CEDILLA
-0148..0149    ; Ll #   [2] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
-014B          ; Ll #       LATIN SMALL LETTER ENG
-014D          ; Ll #       LATIN SMALL LETTER O WITH MACRON
-014F          ; Ll #       LATIN SMALL LETTER O WITH BREVE
-0151          ; Ll #       LATIN SMALL LETTER O WITH DOUBLE ACUTE
-0153          ; Ll #       LATIN SMALL LIGATURE OE
-0155          ; Ll #       LATIN SMALL LETTER R WITH ACUTE
-0157          ; Ll #       LATIN SMALL LETTER R WITH CEDILLA
-0159          ; Ll #       LATIN SMALL LETTER R WITH CARON
-015B          ; Ll #       LATIN SMALL LETTER S WITH ACUTE
-015D          ; Ll #       LATIN SMALL LETTER S WITH CIRCUMFLEX
-015F          ; Ll #       LATIN SMALL LETTER S WITH CEDILLA
-0161          ; Ll #       LATIN SMALL LETTER S WITH CARON
-0163          ; Ll #       LATIN SMALL LETTER T WITH CEDILLA
-0165          ; Ll #       LATIN SMALL LETTER T WITH CARON
-0167          ; Ll #       LATIN SMALL LETTER T WITH STROKE
-0169          ; Ll #       LATIN SMALL LETTER U WITH TILDE
-016B          ; Ll #       LATIN SMALL LETTER U WITH MACRON
-016D          ; Ll #       LATIN SMALL LETTER U WITH BREVE
-016F          ; Ll #       LATIN SMALL LETTER U WITH RING ABOVE
-0171          ; Ll #       LATIN SMALL LETTER U WITH DOUBLE ACUTE
-0173          ; Ll #       LATIN SMALL LETTER U WITH OGONEK
-0175          ; Ll #       LATIN SMALL LETTER W WITH CIRCUMFLEX
-0177          ; Ll #       LATIN SMALL LETTER Y WITH CIRCUMFLEX
-017A          ; Ll #       LATIN SMALL LETTER Z WITH ACUTE
-017C          ; Ll #       LATIN SMALL LETTER Z WITH DOT ABOVE
-017E..0180    ; Ll #   [3] LATIN SMALL LETTER Z WITH CARON..LATIN SMALL LETTER B WITH STROKE
-0183          ; Ll #       LATIN SMALL LETTER B WITH TOPBAR
-0185          ; Ll #       LATIN SMALL LETTER TONE SIX
-0188          ; Ll #       LATIN SMALL LETTER C WITH HOOK
-018C..018D    ; Ll #   [2] LATIN SMALL LETTER D WITH TOPBAR..LATIN SMALL LETTER TURNED DELTA
-0192          ; Ll #       LATIN SMALL LETTER F WITH HOOK
-0195          ; Ll #       LATIN SMALL LETTER HV
-0199..019B    ; Ll #   [3] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE
-019E          ; Ll #       LATIN SMALL LETTER N WITH LONG RIGHT LEG
-01A1          ; Ll #       LATIN SMALL LETTER O WITH HORN
-01A3          ; Ll #       LATIN SMALL LETTER OI
-01A5          ; Ll #       LATIN SMALL LETTER P WITH HOOK
-01A8          ; Ll #       LATIN SMALL LETTER TONE TWO
-01AA..01AB    ; Ll #   [2] LATIN LETTER REVERSED ESH LOOP..LATIN SMALL LETTER T WITH PALATAL HOOK
-01AD          ; Ll #       LATIN SMALL LETTER T WITH HOOK
-01B0          ; Ll #       LATIN SMALL LETTER U WITH HORN
-01B4          ; Ll #       LATIN SMALL LETTER Y WITH HOOK
-01B6          ; Ll #       LATIN SMALL LETTER Z WITH STROKE
-01B9..01BA    ; Ll #   [2] LATIN SMALL LETTER EZH REVERSED..LATIN SMALL LETTER EZH WITH TAIL
-01BD..01BF    ; Ll #   [3] LATIN SMALL LETTER TONE FIVE..LATIN LETTER WYNN
-01C6          ; Ll #       LATIN SMALL LETTER DZ WITH CARON
-01C9          ; Ll #       LATIN SMALL LETTER LJ
-01CC          ; Ll #       LATIN SMALL LETTER NJ
-01CE          ; Ll #       LATIN SMALL LETTER A WITH CARON
-01D0          ; Ll #       LATIN SMALL LETTER I WITH CARON
-01D2          ; Ll #       LATIN SMALL LETTER O WITH CARON
-01D4          ; Ll #       LATIN SMALL LETTER U WITH CARON
-01D6          ; Ll #       LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
-01D8          ; Ll #       LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
-01DA          ; Ll #       LATIN SMALL LETTER U WITH DIAERESIS AND CARON
-01DC..01DD    ; Ll #   [2] LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE..LATIN SMALL LETTER TURNED E
-01DF          ; Ll #       LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
-01E1          ; Ll #       LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON
-01E3          ; Ll #       LATIN SMALL LETTER AE WITH MACRON
-01E5          ; Ll #       LATIN SMALL LETTER G WITH STROKE
-01E7          ; Ll #       LATIN SMALL LETTER G WITH CARON
-01E9          ; Ll #       LATIN SMALL LETTER K WITH CARON
-01EB          ; Ll #       LATIN SMALL LETTER O WITH OGONEK
-01ED          ; Ll #       LATIN SMALL LETTER O WITH OGONEK AND MACRON
-01EF..01F0    ; Ll #   [2] LATIN SMALL LETTER EZH WITH CARON..LATIN SMALL LETTER J WITH CARON
-01F3          ; Ll #       LATIN SMALL LETTER DZ
-01F5          ; Ll #       LATIN SMALL LETTER G WITH ACUTE
-01F9          ; Ll #       LATIN SMALL LETTER N WITH GRAVE
-01FB          ; Ll #       LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
-01FD          ; Ll #       LATIN SMALL LETTER AE WITH ACUTE
-01FF          ; Ll #       LATIN SMALL LETTER O WITH STROKE AND ACUTE
-0201          ; Ll #       LATIN SMALL LETTER A WITH DOUBLE GRAVE
-0203          ; Ll #       LATIN SMALL LETTER A WITH INVERTED BREVE
-0205          ; Ll #       LATIN SMALL LETTER E WITH DOUBLE GRAVE
-0207          ; Ll #       LATIN SMALL LETTER E WITH INVERTED BREVE
-0209          ; Ll #       LATIN SMALL LETTER I WITH DOUBLE GRAVE
-020B          ; Ll #       LATIN SMALL LETTER I WITH INVERTED BREVE
-020D          ; Ll #       LATIN SMALL LETTER O WITH DOUBLE GRAVE
-020F          ; Ll #       LATIN SMALL LETTER O WITH INVERTED BREVE
-0211          ; Ll #       LATIN SMALL LETTER R WITH DOUBLE GRAVE
-0213          ; Ll #       LATIN SMALL LETTER R WITH INVERTED BREVE
-0215          ; Ll #       LATIN SMALL LETTER U WITH DOUBLE GRAVE
-0217          ; Ll #       LATIN SMALL LETTER U WITH INVERTED BREVE
-0219          ; Ll #       LATIN SMALL LETTER S WITH COMMA BELOW
-021B          ; Ll #       LATIN SMALL LETTER T WITH COMMA BELOW
-021D          ; Ll #       LATIN SMALL LETTER YOGH
-021F          ; Ll #       LATIN SMALL LETTER H WITH CARON
-0221          ; Ll #       LATIN SMALL LETTER D WITH CURL
-0223          ; Ll #       LATIN SMALL LETTER OU
-0225          ; Ll #       LATIN SMALL LETTER Z WITH HOOK
-0227          ; Ll #       LATIN SMALL LETTER A WITH DOT ABOVE
-0229          ; Ll #       LATIN SMALL LETTER E WITH CEDILLA
-022B          ; Ll #       LATIN SMALL LETTER O WITH DIAERESIS AND MACRON
-022D          ; Ll #       LATIN SMALL LETTER O WITH TILDE AND MACRON
-022F          ; Ll #       LATIN SMALL LETTER O WITH DOT ABOVE
-0231          ; Ll #       LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON
-0233..0239    ; Ll #   [7] LATIN SMALL LETTER Y WITH MACRON..LATIN SMALL LETTER QP DIGRAPH
-023C          ; Ll #       LATIN SMALL LETTER C WITH STROKE
-023F..0240    ; Ll #   [2] LATIN SMALL LETTER S WITH SWASH TAIL..LATIN SMALL LETTER Z WITH SWASH TAIL
-0242          ; Ll #       LATIN SMALL LETTER GLOTTAL STOP
-0247          ; Ll #       LATIN SMALL LETTER E WITH STROKE
-0249          ; Ll #       LATIN SMALL LETTER J WITH STROKE
-024B          ; Ll #       LATIN SMALL LETTER Q WITH HOOK TAIL
-024D          ; Ll #       LATIN SMALL LETTER R WITH STROKE
-024F..0293    ; Ll #  [69] LATIN SMALL LETTER Y WITH STROKE..LATIN SMALL LETTER EZH WITH CURL
-0295..02AF    ; Ll #  [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
-0371          ; Ll #       GREEK SMALL LETTER HETA
-0373          ; Ll #       GREEK SMALL LETTER ARCHAIC SAMPI
-0377          ; Ll #       GREEK SMALL LETTER PAMPHYLIAN DIGAMMA
-037B..037D    ; Ll #   [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
-0390          ; Ll #       GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
-03AC..03CE    ; Ll #  [35] GREEK SMALL LETTER ALPHA WITH TONOS..GREEK SMALL LETTER OMEGA WITH TONOS
-03D0..03D1    ; Ll #   [2] GREEK BETA SYMBOL..GREEK THETA SYMBOL
-03D5..03D7    ; Ll #   [3] GREEK PHI SYMBOL..GREEK KAI SYMBOL
-03D9          ; Ll #       GREEK SMALL LETTER ARCHAIC KOPPA
-03DB          ; Ll #       GREEK SMALL LETTER STIGMA
-03DD          ; Ll #       GREEK SMALL LETTER DIGAMMA
-03DF          ; Ll #       GREEK SMALL LETTER KOPPA
-03E1          ; Ll #       GREEK SMALL LETTER SAMPI
-03E3          ; Ll #       COPTIC SMALL LETTER SHEI
-03E5          ; Ll #       COPTIC SMALL LETTER FEI
-03E7          ; Ll #       COPTIC SMALL LETTER KHEI
-03E9          ; Ll #       COPTIC SMALL LETTER HORI
-03EB          ; Ll #       COPTIC SMALL LETTER GANGIA
-03ED          ; Ll #       COPTIC SMALL LETTER SHIMA
-03EF..03F3    ; Ll #   [5] COPTIC SMALL LETTER DEI..GREEK LETTER YOT
-03F5          ; Ll #       GREEK LUNATE EPSILON SYMBOL
-03F8          ; Ll #       GREEK SMALL LETTER SHO
-03FB..03FC    ; Ll #   [2] GREEK SMALL LETTER SAN..GREEK RHO WITH STROKE SYMBOL
-0430..045F    ; Ll #  [48] CYRILLIC SMALL LETTER A..CYRILLIC SMALL LETTER DZHE
-0461          ; Ll #       CYRILLIC SMALL LETTER OMEGA
-0463          ; Ll #       CYRILLIC SMALL LETTER YAT
-0465          ; Ll #       CYRILLIC SMALL LETTER IOTIFIED E
-0467          ; Ll #       CYRILLIC SMALL LETTER LITTLE YUS
-0469          ; Ll #       CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS
-046B          ; Ll #       CYRILLIC SMALL LETTER BIG YUS
-046D          ; Ll #       CYRILLIC SMALL LETTER IOTIFIED BIG YUS
-046F          ; Ll #       CYRILLIC SMALL LETTER KSI
-0471          ; Ll #       CYRILLIC SMALL LETTER PSI
-0473          ; Ll #       CYRILLIC SMALL LETTER FITA
-0475          ; Ll #       CYRILLIC SMALL LETTER IZHITSA
-0477          ; Ll #       CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
-0479          ; Ll #       CYRILLIC SMALL LETTER UK
-047B          ; Ll #       CYRILLIC SMALL LETTER ROUND OMEGA
-047D          ; Ll #       CYRILLIC SMALL LETTER OMEGA WITH TITLO
-047F          ; Ll #       CYRILLIC SMALL LETTER OT
-0481          ; Ll #       CYRILLIC SMALL LETTER KOPPA
-048B          ; Ll #       CYRILLIC SMALL LETTER SHORT I WITH TAIL
-048D          ; Ll #       CYRILLIC SMALL LETTER SEMISOFT SIGN
-048F          ; Ll #       CYRILLIC SMALL LETTER ER WITH TICK
-0491          ; Ll #       CYRILLIC SMALL LETTER GHE WITH UPTURN
-0493          ; Ll #       CYRILLIC SMALL LETTER GHE WITH STROKE
-0495          ; Ll #       CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK
-0497          ; Ll #       CYRILLIC SMALL LETTER ZHE WITH DESCENDER
-0499          ; Ll #       CYRILLIC SMALL LETTER ZE WITH DESCENDER
-049B          ; Ll #       CYRILLIC SMALL LETTER KA WITH DESCENDER
-049D          ; Ll #       CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE
-049F          ; Ll #       CYRILLIC SMALL LETTER KA WITH STROKE
-04A1          ; Ll #       CYRILLIC SMALL LETTER BASHKIR KA
-04A3          ; Ll #       CYRILLIC SMALL LETTER EN WITH DESCENDER
-04A5          ; Ll #       CYRILLIC SMALL LIGATURE EN GHE
-04A7          ; Ll #       CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK
-04A9          ; Ll #       CYRILLIC SMALL LETTER ABKHASIAN HA
-04AB          ; Ll #       CYRILLIC SMALL LETTER ES WITH DESCENDER
-04AD          ; Ll #       CYRILLIC SMALL LETTER TE WITH DESCENDER
-04AF          ; Ll #       CYRILLIC SMALL LETTER STRAIGHT U
-04B1          ; Ll #       CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE
-04B3          ; Ll #       CYRILLIC SMALL LETTER HA WITH DESCENDER
-04B5          ; Ll #       CYRILLIC SMALL LIGATURE TE TSE
-04B7          ; Ll #       CYRILLIC SMALL LETTER CHE WITH DESCENDER
-04B9          ; Ll #       CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE
-04BB          ; Ll #       CYRILLIC SMALL LETTER SHHA
-04BD          ; Ll #       CYRILLIC SMALL LETTER ABKHASIAN CHE
-04BF          ; Ll #       CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER
-04C2          ; Ll #       CYRILLIC SMALL LETTER ZHE WITH BREVE
-04C4          ; Ll #       CYRILLIC SMALL LETTER KA WITH HOOK
-04C6          ; Ll #       CYRILLIC SMALL LETTER EL WITH TAIL
-04C8          ; Ll #       CYRILLIC SMALL LETTER EN WITH HOOK
-04CA          ; Ll #       CYRILLIC SMALL LETTER EN WITH TAIL
-04CC          ; Ll #       CYRILLIC SMALL LETTER KHAKASSIAN CHE
-04CE..04CF    ; Ll #   [2] CYRILLIC SMALL LETTER EM WITH TAIL..CYRILLIC SMALL LETTER PALOCHKA
-04D1          ; Ll #       CYRILLIC SMALL LETTER A WITH BREVE
-04D3          ; Ll #       CYRILLIC SMALL LETTER A WITH DIAERESIS
-04D5          ; Ll #       CYRILLIC SMALL LIGATURE A IE
-04D7          ; Ll #       CYRILLIC SMALL LETTER IE WITH BREVE
-04D9          ; Ll #       CYRILLIC SMALL LETTER SCHWA
-04DB          ; Ll #       CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS
-04DD          ; Ll #       CYRILLIC SMALL LETTER ZHE WITH DIAERESIS
-04DF          ; Ll #       CYRILLIC SMALL LETTER ZE WITH DIAERESIS
-04E1          ; Ll #       CYRILLIC SMALL LETTER ABKHASIAN DZE
-04E3          ; Ll #       CYRILLIC SMALL LETTER I WITH MACRON
-04E5          ; Ll #       CYRILLIC SMALL LETTER I WITH DIAERESIS
-04E7          ; Ll #       CYRILLIC SMALL LETTER O WITH DIAERESIS
-04E9          ; Ll #       CYRILLIC SMALL LETTER BARRED O
-04EB          ; Ll #       CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS
-04ED          ; Ll #       CYRILLIC SMALL LETTER E WITH DIAERESIS
-04EF          ; Ll #       CYRILLIC SMALL LETTER U WITH MACRON
-04F1          ; Ll #       CYRILLIC SMALL LETTER U WITH DIAERESIS
-04F3          ; Ll #       CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE
-04F5          ; Ll #       CYRILLIC SMALL LETTER CHE WITH DIAERESIS
-04F7          ; Ll #       CYRILLIC SMALL LETTER GHE WITH DESCENDER
-04F9          ; Ll #       CYRILLIC SMALL LETTER YERU WITH DIAERESIS
-04FB          ; Ll #       CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK
-04FD          ; Ll #       CYRILLIC SMALL LETTER HA WITH HOOK
-04FF          ; Ll #       CYRILLIC SMALL LETTER HA WITH STROKE
-0501          ; Ll #       CYRILLIC SMALL LETTER KOMI DE
-0503          ; Ll #       CYRILLIC SMALL LETTER KOMI DJE
-0505          ; Ll #       CYRILLIC SMALL LETTER KOMI ZJE
-0507          ; Ll #       CYRILLIC SMALL LETTER KOMI DZJE
-0509          ; Ll #       CYRILLIC SMALL LETTER KOMI LJE
-050B          ; Ll #       CYRILLIC SMALL LETTER KOMI NJE
-050D          ; Ll #       CYRILLIC SMALL LETTER KOMI SJE
-050F          ; Ll #       CYRILLIC SMALL LETTER KOMI TJE
-0511          ; Ll #       CYRILLIC SMALL LETTER REVERSED ZE
-0513          ; Ll #       CYRILLIC SMALL LETTER EL WITH HOOK
-0515          ; Ll #       CYRILLIC SMALL LETTER LHA
-0517          ; Ll #       CYRILLIC SMALL LETTER RHA
-0519          ; Ll #       CYRILLIC SMALL LETTER YAE
-051B          ; Ll #       CYRILLIC SMALL LETTER QA
-051D          ; Ll #       CYRILLIC SMALL LETTER WE
-051F          ; Ll #       CYRILLIC SMALL LETTER ALEUT KA
-0521          ; Ll #       CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK
-0523          ; Ll #       CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK
-0561..0587    ; Ll #  [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN
-1D00..1D2B    ; Ll #  [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL
-1D62..1D77    ; Ll #  [22] LATIN SUBSCRIPT SMALL LETTER I..LATIN SMALL LETTER TURNED G
-1D79..1D9A    ; Ll #  [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK
-1E01          ; Ll #       LATIN SMALL LETTER A WITH RING BELOW
-1E03          ; Ll #       LATIN SMALL LETTER B WITH DOT ABOVE
-1E05          ; Ll #       LATIN SMALL LETTER B WITH DOT BELOW
-1E07          ; Ll #       LATIN SMALL LETTER B WITH LINE BELOW
-1E09          ; Ll #       LATIN SMALL LETTER C WITH CEDILLA AND ACUTE
-1E0B          ; Ll #       LATIN SMALL LETTER D WITH DOT ABOVE
-1E0D          ; Ll #       LATIN SMALL LETTER D WITH DOT BELOW
-1E0F          ; Ll #       LATIN SMALL LETTER D WITH LINE BELOW
-1E11          ; Ll #       LATIN SMALL LETTER D WITH CEDILLA
-1E13          ; Ll #       LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW
-1E15          ; Ll #       LATIN SMALL LETTER E WITH MACRON AND GRAVE
-1E17          ; Ll #       LATIN SMALL LETTER E WITH MACRON AND ACUTE
-1E19          ; Ll #       LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW
-1E1B          ; Ll #       LATIN SMALL LETTER E WITH TILDE BELOW
-1E1D          ; Ll #       LATIN SMALL LETTER E WITH CEDILLA AND BREVE
-1E1F          ; Ll #       LATIN SMALL LETTER F WITH DOT ABOVE
-1E21          ; Ll #       LATIN SMALL LETTER G WITH MACRON
-1E23          ; Ll #       LATIN SMALL LETTER H WITH DOT ABOVE
-1E25          ; Ll #       LATIN SMALL LETTER H WITH DOT BELOW
-1E27          ; Ll #       LATIN SMALL LETTER H WITH DIAERESIS
-1E29          ; Ll #       LATIN SMALL LETTER H WITH CEDILLA
-1E2B          ; Ll #       LATIN SMALL LETTER H WITH BREVE BELOW
-1E2D          ; Ll #       LATIN SMALL LETTER I WITH TILDE BELOW
-1E2F          ; Ll #       LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE
-1E31          ; Ll #       LATIN SMALL LETTER K WITH ACUTE
-1E33          ; Ll #       LATIN SMALL LETTER K WITH DOT BELOW
-1E35          ; Ll #       LATIN SMALL LETTER K WITH LINE BELOW
-1E37          ; Ll #       LATIN SMALL LETTER L WITH DOT BELOW
-1E39          ; Ll #       LATIN SMALL LETTER L WITH DOT BELOW AND MACRON
-1E3B          ; Ll #       LATIN SMALL LETTER L WITH LINE BELOW
-1E3D          ; Ll #       LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW
-1E3F          ; Ll #       LATIN SMALL LETTER M WITH ACUTE
-1E41          ; Ll #       LATIN SMALL LETTER M WITH DOT ABOVE
-1E43          ; Ll #       LATIN SMALL LETTER M WITH DOT BELOW
-1E45          ; Ll #       LATIN SMALL LETTER N WITH DOT ABOVE
-1E47          ; Ll #       LATIN SMALL LETTER N WITH DOT BELOW
-1E49          ; Ll #       LATIN SMALL LETTER N WITH LINE BELOW
-1E4B          ; Ll #       LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW
-1E4D          ; Ll #       LATIN SMALL LETTER O WITH TILDE AND ACUTE
-1E4F          ; Ll #       LATIN SMALL LETTER O WITH TILDE AND DIAERESIS
-1E51          ; Ll #       LATIN SMALL LETTER O WITH MACRON AND GRAVE
-1E53          ; Ll #       LATIN SMALL LETTER O WITH MACRON AND ACUTE
-1E55          ; Ll #       LATIN SMALL LETTER P WITH ACUTE
-1E57          ; Ll #       LATIN SMALL LETTER P WITH DOT ABOVE
-1E59          ; Ll #       LATIN SMALL LETTER R WITH DOT ABOVE
-1E5B          ; Ll #       LATIN SMALL LETTER R WITH DOT BELOW
-1E5D          ; Ll #       LATIN SMALL LETTER R WITH DOT BELOW AND MACRON
-1E5F          ; Ll #       LATIN SMALL LETTER R WITH LINE BELOW
-1E61          ; Ll #       LATIN SMALL LETTER S WITH DOT ABOVE
-1E63          ; Ll #       LATIN SMALL LETTER S WITH DOT BELOW
-1E65          ; Ll #       LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE
-1E67          ; Ll #       LATIN SMALL LETTER S WITH CARON AND DOT ABOVE
-1E69          ; Ll #       LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
-1E6B          ; Ll #       LATIN SMALL LETTER T WITH DOT ABOVE
-1E6D          ; Ll #       LATIN SMALL LETTER T WITH DOT BELOW
-1E6F          ; Ll #       LATIN SMALL LETTER T WITH LINE BELOW
-1E71          ; Ll #       LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW
-1E73          ; Ll #       LATIN SMALL LETTER U WITH DIAERESIS BELOW
-1E75          ; Ll #       LATIN SMALL LETTER U WITH TILDE BELOW
-1E77          ; Ll #       LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW
-1E79          ; Ll #       LATIN SMALL LETTER U WITH TILDE AND ACUTE
-1E7B          ; Ll #       LATIN SMALL LETTER U WITH MACRON AND DIAERESIS
-1E7D          ; Ll #       LATIN SMALL LETTER V WITH TILDE
-1E7F          ; Ll #       LATIN SMALL LETTER V WITH DOT BELOW
-1E81          ; Ll #       LATIN SMALL LETTER W WITH GRAVE
-1E83          ; Ll #       LATIN SMALL LETTER W WITH ACUTE
-1E85          ; Ll #       LATIN SMALL LETTER W WITH DIAERESIS
-1E87          ; Ll #       LATIN SMALL LETTER W WITH DOT ABOVE
-1E89          ; Ll #       LATIN SMALL LETTER W WITH DOT BELOW
-1E8B          ; Ll #       LATIN SMALL LETTER X WITH DOT ABOVE
-1E8D          ; Ll #       LATIN SMALL LETTER X WITH DIAERESIS
-1E8F          ; Ll #       LATIN SMALL LETTER Y WITH DOT ABOVE
-1E91          ; Ll #       LATIN SMALL LETTER Z WITH CIRCUMFLEX
-1E93          ; Ll #       LATIN SMALL LETTER Z WITH DOT BELOW
-1E95..1E9D    ; Ll #   [9] LATIN SMALL LETTER Z WITH LINE BELOW..LATIN SMALL LETTER LONG S WITH HIGH STROKE
-1E9F          ; Ll #       LATIN SMALL LETTER DELTA
-1EA1          ; Ll #       LATIN SMALL LETTER A WITH DOT BELOW
-1EA3          ; Ll #       LATIN SMALL LETTER A WITH HOOK ABOVE
-1EA5          ; Ll #       LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
-1EA7          ; Ll #       LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE
-1EA9          ; Ll #       LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
-1EAB          ; Ll #       LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE
-1EAD          ; Ll #       LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW
-1EAF          ; Ll #       LATIN SMALL LETTER A WITH BREVE AND ACUTE
-1EB1          ; Ll #       LATIN SMALL LETTER A WITH BREVE AND GRAVE
-1EB3          ; Ll #       LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE
-1EB5          ; Ll #       LATIN SMALL LETTER A WITH BREVE AND TILDE
-1EB7          ; Ll #       LATIN SMALL LETTER A WITH BREVE AND DOT BELOW
-1EB9          ; Ll #       LATIN SMALL LETTER E WITH DOT BELOW
-1EBB          ; Ll #       LATIN SMALL LETTER E WITH HOOK ABOVE
-1EBD          ; Ll #       LATIN SMALL LETTER E WITH TILDE
-1EBF          ; Ll #       LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
-1EC1          ; Ll #       LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE
-1EC3          ; Ll #       LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
-1EC5          ; Ll #       LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
-1EC7          ; Ll #       LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
-1EC9          ; Ll #       LATIN SMALL LETTER I WITH HOOK ABOVE
-1ECB          ; Ll #       LATIN SMALL LETTER I WITH DOT BELOW
-1ECD          ; Ll #       LATIN SMALL LETTER O WITH DOT BELOW
-1ECF          ; Ll #       LATIN SMALL LETTER O WITH HOOK ABOVE
-1ED1          ; Ll #       LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE
-1ED3          ; Ll #       LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE
-1ED5          ; Ll #       LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
-1ED7          ; Ll #       LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE
-1ED9          ; Ll #       LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW
-1EDB          ; Ll #       LATIN SMALL LETTER O WITH HORN AND ACUTE
-1EDD          ; Ll #       LATIN SMALL LETTER O WITH HORN AND GRAVE
-1EDF          ; Ll #       LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE
-1EE1          ; Ll #       LATIN SMALL LETTER O WITH HORN AND TILDE
-1EE3          ; Ll #       LATIN SMALL LETTER O WITH HORN AND DOT BELOW
-1EE5          ; Ll #       LATIN SMALL LETTER U WITH DOT BELOW
-1EE7          ; Ll #       LATIN SMALL LETTER U WITH HOOK ABOVE
-1EE9          ; Ll #       LATIN SMALL LETTER U WITH HORN AND ACUTE
-1EEB          ; Ll #       LATIN SMALL LETTER U WITH HORN AND GRAVE
-1EED          ; Ll #       LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE
-1EEF          ; Ll #       LATIN SMALL LETTER U WITH HORN AND TILDE
-1EF1          ; Ll #       LATIN SMALL LETTER U WITH HORN AND DOT BELOW
-1EF3          ; Ll #       LATIN SMALL LETTER Y WITH GRAVE
-1EF5          ; Ll #       LATIN SMALL LETTER Y WITH DOT BELOW
-1EF7          ; Ll #       LATIN SMALL LETTER Y WITH HOOK ABOVE
-1EF9          ; Ll #       LATIN SMALL LETTER Y WITH TILDE
-1EFB          ; Ll #       LATIN SMALL LETTER MIDDLE-WELSH LL
-1EFD          ; Ll #       LATIN SMALL LETTER MIDDLE-WELSH V
-1EFF..1F07    ; Ll #   [9] LATIN SMALL LETTER Y WITH LOOP..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI
-1F10..1F15    ; Ll #   [6] GREEK SMALL LETTER EPSILON WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
-1F20..1F27    ; Ll #   [8] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI
-1F30..1F37    ; Ll #   [8] GREEK SMALL LETTER IOTA WITH PSILI..GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI
-1F40..1F45    ; Ll #   [6] GREEK SMALL LETTER OMICRON WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
-1F50..1F57    ; Ll #   [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
-1F60..1F67    ; Ll #   [8] GREEK SMALL LETTER OMEGA WITH PSILI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI
-1F70..1F7D    ; Ll #  [14] GREEK SMALL LETTER ALPHA WITH VARIA..GREEK SMALL LETTER OMEGA WITH OXIA
-1F80..1F87    ; Ll #   [8] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-1F90..1F97    ; Ll #   [8] GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-1FA0..1FA7    ; Ll #   [8] GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-1FB0..1FB4    ; Ll #   [5] GREEK SMALL LETTER ALPHA WITH VRACHY..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
-1FB6..1FB7    ; Ll #   [2] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
-1FBE          ; Ll #       GREEK PROSGEGRAMMENI
-1FC2..1FC4    ; Ll #   [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
-1FC6..1FC7    ; Ll #   [2] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
-1FD0..1FD3    ; Ll #   [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
-1FD6..1FD7    ; Ll #   [2] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
-1FE0..1FE7    ; Ll #   [8] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
-1FF2..1FF4    ; Ll #   [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
-1FF6..1FF7    ; Ll #   [2] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
-2071          ; Ll #       SUPERSCRIPT LATIN SMALL LETTER I
-207F          ; Ll #       SUPERSCRIPT LATIN SMALL LETTER N
-210A          ; Ll #       SCRIPT SMALL G
-210E..210F    ; Ll #   [2] PLANCK CONSTANT..PLANCK CONSTANT OVER TWO PI
-2113          ; Ll #       SCRIPT SMALL L
-212F          ; Ll #       SCRIPT SMALL E
-2134          ; Ll #       SCRIPT SMALL O
-2139          ; Ll #       INFORMATION SOURCE
-213C..213D    ; Ll #   [2] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK SMALL GAMMA
-2146..2149    ; Ll #   [4] DOUBLE-STRUCK ITALIC SMALL D..DOUBLE-STRUCK ITALIC SMALL J
-214E          ; Ll #       TURNED SMALL F
-2184          ; Ll #       LATIN SMALL LETTER REVERSED C
-2C30..2C5E    ; Ll #  [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE
-2C61          ; Ll #       LATIN SMALL LETTER L WITH DOUBLE BAR
-2C65..2C66    ; Ll #   [2] LATIN SMALL LETTER A WITH STROKE..LATIN SMALL LETTER T WITH DIAGONAL STROKE
-2C68          ; Ll #       LATIN SMALL LETTER H WITH DESCENDER
-2C6A          ; Ll #       LATIN SMALL LETTER K WITH DESCENDER
-2C6C          ; Ll #       LATIN SMALL LETTER Z WITH DESCENDER
-2C71          ; Ll #       LATIN SMALL LETTER V WITH RIGHT HOOK
-2C73..2C74    ; Ll #   [2] LATIN SMALL LETTER W WITH HOOK..LATIN SMALL LETTER V WITH CURL
-2C76..2C7C    ; Ll #   [7] LATIN SMALL LETTER HALF H..LATIN SUBSCRIPT SMALL LETTER J
-2C81          ; Ll #       COPTIC SMALL LETTER ALFA
-2C83          ; Ll #       COPTIC SMALL LETTER VIDA
-2C85          ; Ll #       COPTIC SMALL LETTER GAMMA
-2C87          ; Ll #       COPTIC SMALL LETTER DALDA
-2C89          ; Ll #       COPTIC SMALL LETTER EIE
-2C8B          ; Ll #       COPTIC SMALL LETTER SOU
-2C8D          ; Ll #       COPTIC SMALL LETTER ZATA
-2C8F          ; Ll #       COPTIC SMALL LETTER HATE
-2C91          ; Ll #       COPTIC SMALL LETTER THETHE
-2C93          ; Ll #       COPTIC SMALL LETTER IAUDA
-2C95          ; Ll #       COPTIC SMALL LETTER KAPA
-2C97          ; Ll #       COPTIC SMALL LETTER LAULA
-2C99          ; Ll #       COPTIC SMALL LETTER MI
-2C9B          ; Ll #       COPTIC SMALL LETTER NI
-2C9D          ; Ll #       COPTIC SMALL LETTER KSI
-2C9F          ; Ll #       COPTIC SMALL LETTER O
-2CA1          ; Ll #       COPTIC SMALL LETTER PI
-2CA3          ; Ll #       COPTIC SMALL LETTER RO
-2CA5          ; Ll #       COPTIC SMALL LETTER SIMA
-2CA7          ; Ll #       COPTIC SMALL LETTER TAU
-2CA9          ; Ll #       COPTIC SMALL LETTER UA
-2CAB          ; Ll #       COPTIC SMALL LETTER FI
-2CAD          ; Ll #       COPTIC SMALL LETTER KHI
-2CAF          ; Ll #       COPTIC SMALL LETTER PSI
-2CB1          ; Ll #       COPTIC SMALL LETTER OOU
-2CB3          ; Ll #       COPTIC SMALL LETTER DIALECT-P ALEF
-2CB5          ; Ll #       COPTIC SMALL LETTER OLD COPTIC AIN
-2CB7          ; Ll #       COPTIC SMALL LETTER CRYPTOGRAMMIC EIE
-2CB9          ; Ll #       COPTIC SMALL LETTER DIALECT-P KAPA
-2CBB          ; Ll #       COPTIC SMALL LETTER DIALECT-P NI
-2CBD          ; Ll #       COPTIC SMALL LETTER CRYPTOGRAMMIC NI
-2CBF          ; Ll #       COPTIC SMALL LETTER OLD COPTIC OOU
-2CC1          ; Ll #       COPTIC SMALL LETTER SAMPI
-2CC3          ; Ll #       COPTIC SMALL LETTER CROSSED SHEI
-2CC5          ; Ll #       COPTIC SMALL LETTER OLD COPTIC SHEI
-2CC7          ; Ll #       COPTIC SMALL LETTER OLD COPTIC ESH
-2CC9          ; Ll #       COPTIC SMALL LETTER AKHMIMIC KHEI
-2CCB          ; Ll #       COPTIC SMALL LETTER DIALECT-P HORI
-2CCD          ; Ll #       COPTIC SMALL LETTER OLD COPTIC HORI
-2CCF          ; Ll #       COPTIC SMALL LETTER OLD COPTIC HA
-2CD1          ; Ll #       COPTIC SMALL LETTER L-SHAPED HA
-2CD3          ; Ll #       COPTIC SMALL LETTER OLD COPTIC HEI
-2CD5          ; Ll #       COPTIC SMALL LETTER OLD COPTIC HAT
-2CD7          ; Ll #       COPTIC SMALL LETTER OLD COPTIC GANGIA
-2CD9          ; Ll #       COPTIC SMALL LETTER OLD COPTIC DJA
-2CDB          ; Ll #       COPTIC SMALL LETTER OLD COPTIC SHIMA
-2CDD          ; Ll #       COPTIC SMALL LETTER OLD NUBIAN SHIMA
-2CDF          ; Ll #       COPTIC SMALL LETTER OLD NUBIAN NGI
-2CE1          ; Ll #       COPTIC SMALL LETTER OLD NUBIAN NYI
-2CE3..2CE4    ; Ll #   [2] COPTIC SMALL LETTER OLD NUBIAN WAU..COPTIC SYMBOL KAI
-2D00..2D25    ; Ll #  [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE
-A641          ; Ll #       CYRILLIC SMALL LETTER ZEMLYA
-A643          ; Ll #       CYRILLIC SMALL LETTER DZELO
-A645          ; Ll #       CYRILLIC SMALL LETTER REVERSED DZE
-A647          ; Ll #       CYRILLIC SMALL LETTER IOTA
-A649          ; Ll #       CYRILLIC SMALL LETTER DJERV
-A64B          ; Ll #       CYRILLIC SMALL LETTER MONOGRAPH UK
-A64D          ; Ll #       CYRILLIC SMALL LETTER BROAD OMEGA
-A64F          ; Ll #       CYRILLIC SMALL LETTER NEUTRAL YER
-A651          ; Ll #       CYRILLIC SMALL LETTER YERU WITH BACK YER
-A653          ; Ll #       CYRILLIC SMALL LETTER IOTIFIED YAT
-A655          ; Ll #       CYRILLIC SMALL LETTER REVERSED YU
-A657          ; Ll #       CYRILLIC SMALL LETTER IOTIFIED A
-A659          ; Ll #       CYRILLIC SMALL LETTER CLOSED LITTLE YUS
-A65B          ; Ll #       CYRILLIC SMALL LETTER BLENDED YUS
-A65D          ; Ll #       CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS
-A65F          ; Ll #       CYRILLIC SMALL LETTER YN
-A663          ; Ll #       CYRILLIC SMALL LETTER SOFT DE
-A665          ; Ll #       CYRILLIC SMALL LETTER SOFT EL
-A667          ; Ll #       CYRILLIC SMALL LETTER SOFT EM
-A669          ; Ll #       CYRILLIC SMALL LETTER MONOCULAR O
-A66B          ; Ll #       CYRILLIC SMALL LETTER BINOCULAR O
-A66D          ; Ll #       CYRILLIC SMALL LETTER DOUBLE MONOCULAR O
-A681          ; Ll #       CYRILLIC SMALL LETTER DWE
-A683          ; Ll #       CYRILLIC SMALL LETTER DZWE
-A685          ; Ll #       CYRILLIC SMALL LETTER ZHWE
-A687          ; Ll #       CYRILLIC SMALL LETTER CCHE
-A689          ; Ll #       CYRILLIC SMALL LETTER DZZE
-A68B          ; Ll #       CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK
-A68D          ; Ll #       CYRILLIC SMALL LETTER TWE
-A68F          ; Ll #       CYRILLIC SMALL LETTER TSWE
-A691          ; Ll #       CYRILLIC SMALL LETTER TSSE
-A693          ; Ll #       CYRILLIC SMALL LETTER TCHE
-A695          ; Ll #       CYRILLIC SMALL LETTER HWE
-A697          ; Ll #       CYRILLIC SMALL LETTER SHWE
-A723          ; Ll #       LATIN SMALL LETTER EGYPTOLOGICAL ALEF
-A725          ; Ll #       LATIN SMALL LETTER EGYPTOLOGICAL AIN
-A727          ; Ll #       LATIN SMALL LETTER HENG
-A729          ; Ll #       LATIN SMALL LETTER TZ
-A72B          ; Ll #       LATIN SMALL LETTER TRESILLO
-A72D          ; Ll #       LATIN SMALL LETTER CUATRILLO
-A72F..A731    ; Ll #   [3] LATIN SMALL LETTER CUATRILLO WITH COMMA..LATIN LETTER SMALL CAPITAL S
-A733          ; Ll #       LATIN SMALL LETTER AA
-A735          ; Ll #       LATIN SMALL LETTER AO
-A737          ; Ll #       LATIN SMALL LETTER AU
-A739          ; Ll #       LATIN SMALL LETTER AV
-A73B          ; Ll #       LATIN SMALL LETTER AV WITH HORIZONTAL BAR
-A73D          ; Ll #       LATIN SMALL LETTER AY
-A73F          ; Ll #       LATIN SMALL LETTER REVERSED C WITH DOT
-A741          ; Ll #       LATIN SMALL LETTER K WITH STROKE
-A743          ; Ll #       LATIN SMALL LETTER K WITH DIAGONAL STROKE
-A745          ; Ll #       LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE
-A747          ; Ll #       LATIN SMALL LETTER BROKEN L
-A749          ; Ll #       LATIN SMALL LETTER L WITH HIGH STROKE
-A74B          ; Ll #       LATIN SMALL LETTER O WITH LONG STROKE OVERLAY
-A74D          ; Ll #       LATIN SMALL LETTER O WITH LOOP
-A74F          ; Ll #       LATIN SMALL LETTER OO
-A751          ; Ll #       LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER
-A753          ; Ll #       LATIN SMALL LETTER P WITH FLOURISH
-A755          ; Ll #       LATIN SMALL LETTER P WITH SQUIRREL TAIL
-A757          ; Ll #       LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER
-A759          ; Ll #       LATIN SMALL LETTER Q WITH DIAGONAL STROKE
-A75B          ; Ll #       LATIN SMALL LETTER R ROTUNDA
-A75D          ; Ll #       LATIN SMALL LETTER RUM ROTUNDA
-A75F          ; Ll #       LATIN SMALL LETTER V WITH DIAGONAL STROKE
-A761          ; Ll #       LATIN SMALL LETTER VY
-A763          ; Ll #       LATIN SMALL LETTER VISIGOTHIC Z
-A765          ; Ll #       LATIN SMALL LETTER THORN WITH STROKE
-A767          ; Ll #       LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER
-A769          ; Ll #       LATIN SMALL LETTER VEND
-A76B          ; Ll #       LATIN SMALL LETTER ET
-A76D          ; Ll #       LATIN SMALL LETTER IS
-A76F          ; Ll #       LATIN SMALL LETTER CON
-A771..A778    ; Ll #   [8] LATIN SMALL LETTER DUM..LATIN SMALL LETTER UM
-A77A          ; Ll #       LATIN SMALL LETTER INSULAR D
-A77C          ; Ll #       LATIN SMALL LETTER INSULAR F
-A77F          ; Ll #       LATIN SMALL LETTER TURNED INSULAR G
-A781          ; Ll #       LATIN SMALL LETTER TURNED L
-A783          ; Ll #       LATIN SMALL LETTER INSULAR R
-A785          ; Ll #       LATIN SMALL LETTER INSULAR S
-A787          ; Ll #       LATIN SMALL LETTER INSULAR T
-A78C          ; Ll #       LATIN SMALL LETTER SALTILLO
-FB00..FB06    ; Ll #   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
-FB13..FB17    ; Ll #   [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
-FF41..FF5A    ; Ll #  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z
-10428..1044F  ; Ll #  [40] DESERET SMALL LETTER LONG I..DESERET SMALL LETTER EW
-1D41A..1D433  ; Ll #  [26] MATHEMATICAL BOLD SMALL A..MATHEMATICAL BOLD SMALL Z
-1D44E..1D454  ; Ll #   [7] MATHEMATICAL ITALIC SMALL A..MATHEMATICAL ITALIC SMALL G
-1D456..1D467  ; Ll #  [18] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL ITALIC SMALL Z
-1D482..1D49B  ; Ll #  [26] MATHEMATICAL BOLD ITALIC SMALL A..MATHEMATICAL BOLD ITALIC SMALL Z
-1D4B6..1D4B9  ; Ll #   [4] MATHEMATICAL SCRIPT SMALL A..MATHEMATICAL SCRIPT SMALL D
-1D4BB         ; Ll #       MATHEMATICAL SCRIPT SMALL F
-1D4BD..1D4C3  ; Ll #   [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N
-1D4C5..1D4CF  ; Ll #  [11] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL SCRIPT SMALL Z
-1D4EA..1D503  ; Ll #  [26] MATHEMATICAL BOLD SCRIPT SMALL A..MATHEMATICAL BOLD SCRIPT SMALL Z
-1D51E..1D537  ; Ll #  [26] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL FRAKTUR SMALL Z
-1D552..1D56B  ; Ll #  [26] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL DOUBLE-STRUCK SMALL Z
-1D586..1D59F  ; Ll #  [26] MATHEMATICAL BOLD FRAKTUR SMALL A..MATHEMATICAL BOLD FRAKTUR SMALL Z
-1D5BA..1D5D3  ; Ll #  [26] MATHEMATICAL SANS-SERIF SMALL A..MATHEMATICAL SANS-SERIF SMALL Z
-1D5EE..1D607  ; Ll #  [26] MATHEMATICAL SANS-SERIF BOLD SMALL A..MATHEMATICAL SANS-SERIF BOLD SMALL Z
-1D622..1D63B  ; Ll #  [26] MATHEMATICAL SANS-SERIF ITALIC SMALL A..MATHEMATICAL SANS-SERIF ITALIC SMALL Z
-1D656..1D66F  ; Ll #  [26] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z
-1D68A..1D6A5  ; Ll #  [28] MATHEMATICAL MONOSPACE SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J
-1D6C2..1D6DA  ; Ll #  [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA
-1D6DC..1D6E1  ; Ll #   [6] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL BOLD PI SYMBOL
-1D6FC..1D714  ; Ll #  [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA
-1D716..1D71B  ; Ll #   [6] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL ITALIC PI SYMBOL
-1D736..1D74E  ; Ll #  [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA
-1D750..1D755  ; Ll #   [6] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC PI SYMBOL
-1D770..1D788  ; Ll #  [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
-1D78A..1D78F  ; Ll #   [6] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD PI SYMBOL
-1D7AA..1D7C2  ; Ll #  [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
-1D7C4..1D7C9  ; Ll #   [6] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL
-1D7CB         ; Ll #       MATHEMATICAL BOLD SMALL DIGAMMA
-
-# Total code points: 1748
-
-# ================================================
-
-# General_Category=Titlecase_Letter
-
-01C5          ; Lt #       LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
-01C8          ; Lt #       LATIN CAPITAL LETTER L WITH SMALL LETTER J
-01CB          ; Lt #       LATIN CAPITAL LETTER N WITH SMALL LETTER J
-01F2          ; Lt #       LATIN CAPITAL LETTER D WITH SMALL LETTER Z
-1F88..1F8F    ; Lt #   [8] GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-1F98..1F9F    ; Lt #   [8] GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-1FA8..1FAF    ; Lt #   [8] GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-1FBC          ; Lt #       GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
-1FCC          ; Lt #       GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
-1FFC          ; Lt #       GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
-
-# Total code points: 31
-
-# ================================================
-
-# General_Category=Modifier_Letter
-
-02B0..02C1    ; Lm #  [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP
-02C6..02D1    ; Lm #  [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON
-02E0..02E4    ; Lm #   [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
-02EC          ; Lm #       MODIFIER LETTER VOICING
-02EE          ; Lm #       MODIFIER LETTER DOUBLE APOSTROPHE
-0374          ; Lm #       GREEK NUMERAL SIGN
-037A          ; Lm #       GREEK YPOGEGRAMMENI
-0559          ; Lm #       ARMENIAN MODIFIER LETTER LEFT HALF RING
-0640          ; Lm #       ARABIC TATWEEL
-06E5..06E6    ; Lm #   [2] ARABIC SMALL WAW..ARABIC SMALL YEH
-07F4..07F5    ; Lm #   [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE
-07FA          ; Lm #       NKO LAJANYALAN
-0971          ; Lm #       DEVANAGARI SIGN HIGH SPACING DOT
-0E46          ; Lm #       THAI CHARACTER MAIYAMOK
-0EC6          ; Lm #       LAO KO LA
-10FC          ; Lm #       MODIFIER LETTER GEORGIAN NAR
-17D7          ; Lm #       KHMER SIGN LEK TOO
-1843          ; Lm #       MONGOLIAN LETTER TODO LONG VOWEL SIGN
-1C78..1C7D    ; Lm #   [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD
-1D2C..1D61    ; Lm #  [54] MODIFIER LETTER CAPITAL A..MODIFIER LETTER SMALL CHI
-1D78          ; Lm #       MODIFIER LETTER CYRILLIC EN
-1D9B..1DBF    ; Lm #  [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA
-2090..2094    ; Lm #   [5] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER SCHWA
-2C7D          ; Lm #       MODIFIER LETTER CAPITAL V
-2D6F          ; Lm #       TIFINAGH MODIFIER LETTER LABIALIZATION MARK
-2E2F          ; Lm #       VERTICAL TILDE
-3005          ; Lm #       IDEOGRAPHIC ITERATION MARK
-3031..3035    ; Lm #   [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF
-303B          ; Lm #       VERTICAL IDEOGRAPHIC ITERATION MARK
-309D..309E    ; Lm #   [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
-30FC..30FE    ; Lm #   [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK
-A015          ; Lm #       YI SYLLABLE WU
-A60C          ; Lm #       VAI SYLLABLE LENGTHENER
-A67F          ; Lm #       CYRILLIC PAYEROK
-A717..A71F    ; Lm #   [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK
-A770          ; Lm #       MODIFIER LETTER US
-A788          ; Lm #       MODIFIER LETTER LOW CIRCUMFLEX ACCENT
-FF70          ; Lm #       HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
-FF9E..FF9F    ; Lm #   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
-
-# Total code points: 187
-
-# ================================================
-
-# General_Category=Other_Letter
-
-01BB          ; Lo #       LATIN LETTER TWO WITH STROKE
-01C0..01C3    ; Lo #   [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK
-0294          ; Lo #       LATIN LETTER GLOTTAL STOP
-05D0..05EA    ; Lo #  [27] HEBREW LETTER ALEF..HEBREW LETTER TAV
-05F0..05F2    ; Lo #   [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD
-0621..063F    ; Lo #  [31] ARABIC LETTER HAMZA..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
-0641..064A    ; Lo #  [10] ARABIC LETTER FEH..ARABIC LETTER YEH
-066E..066F    ; Lo #   [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF
-0671..06D3    ; Lo #  [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
-06D5          ; Lo #       ARABIC LETTER AE
-06EE..06EF    ; Lo #   [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V
-06FA..06FC    ; Lo #   [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW
-06FF          ; Lo #       ARABIC LETTER HEH WITH INVERTED V
-0710          ; Lo #       SYRIAC LETTER ALAPH
-0712..072F    ; Lo #  [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH
-074D..07A5    ; Lo #  [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU
-07B1          ; Lo #       THAANA LETTER NAA
-07CA..07EA    ; Lo #  [33] NKO LETTER A..NKO LETTER JONA RA
-0904..0939    ; Lo #  [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA
-093D          ; Lo #       DEVANAGARI SIGN AVAGRAHA
-0950          ; Lo #       DEVANAGARI OM
-0958..0961    ; Lo #  [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL
-0972          ; Lo #       DEVANAGARI LETTER CANDRA A
-097B..097F    ; Lo #   [5] DEVANAGARI LETTER GGA..DEVANAGARI LETTER BBA
-0985..098C    ; Lo #   [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L
-098F..0990    ; Lo #   [2] BENGALI LETTER E..BENGALI LETTER AI
-0993..09A8    ; Lo #  [22] BENGALI LETTER O..BENGALI LETTER NA
-09AA..09B0    ; Lo #   [7] BENGALI LETTER PA..BENGALI LETTER RA
-09B2          ; Lo #       BENGALI LETTER LA
-09B6..09B9    ; Lo #   [4] BENGALI LETTER SHA..BENGALI LETTER HA
-09BD          ; Lo #       BENGALI SIGN AVAGRAHA
-09CE          ; Lo #       BENGALI LETTER KHANDA TA
-09DC..09DD    ; Lo #   [2] BENGALI LETTER RRA..BENGALI LETTER RHA
-09DF..09E1    ; Lo #   [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL
-09F0..09F1    ; Lo #   [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL
-0A05..0A0A    ; Lo #   [6] GURMUKHI LETTER A..GURMUKHI LETTER UU
-0A0F..0A10    ; Lo #   [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI
-0A13..0A28    ; Lo #  [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA
-0A2A..0A30    ; Lo #   [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA
-0A32..0A33    ; Lo #   [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA
-0A35..0A36    ; Lo #   [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA
-0A38..0A39    ; Lo #   [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA
-0A59..0A5C    ; Lo #   [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA
-0A5E          ; Lo #       GURMUKHI LETTER FA
-0A72..0A74    ; Lo #   [3] GURMUKHI IRI..GURMUKHI EK ONKAR
-0A85..0A8D    ; Lo #   [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E
-0A8F..0A91    ; Lo #   [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O
-0A93..0AA8    ; Lo #  [22] GUJARATI LETTER O..GUJARATI LETTER NA
-0AAA..0AB0    ; Lo #   [7] GUJARATI LETTER PA..GUJARATI LETTER RA
-0AB2..0AB3    ; Lo #   [2] GUJARATI LETTER LA..GUJARATI LETTER LLA
-0AB5..0AB9    ; Lo #   [5] GUJARATI LETTER VA..GUJARATI LETTER HA
-0ABD          ; Lo #       GUJARATI SIGN AVAGRAHA
-0AD0          ; Lo #       GUJARATI OM
-0AE0..0AE1    ; Lo #   [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL
-0B05..0B0C    ; Lo #   [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L
-0B0F..0B10    ; Lo #   [2] ORIYA LETTER E..ORIYA LETTER AI
-0B13..0B28    ; Lo #  [22] ORIYA LETTER O..ORIYA LETTER NA
-0B2A..0B30    ; Lo #   [7] ORIYA LETTER PA..ORIYA LETTER RA
-0B32..0B33    ; Lo #   [2] ORIYA LETTER LA..ORIYA LETTER LLA
-0B35..0B39    ; Lo #   [5] ORIYA LETTER VA..ORIYA LETTER HA
-0B3D          ; Lo #       ORIYA SIGN AVAGRAHA
-0B5C..0B5D    ; Lo #   [2] ORIYA LETTER RRA..ORIYA LETTER RHA
-0B5F..0B61    ; Lo #   [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
-0B71          ; Lo #       ORIYA LETTER WA
-0B83          ; Lo #       TAMIL SIGN VISARGA
-0B85..0B8A    ; Lo #   [6] TAMIL LETTER A..TAMIL LETTER UU
-0B8E..0B90    ; Lo #   [3] TAMIL LETTER E..TAMIL LETTER AI
-0B92..0B95    ; Lo #   [4] TAMIL LETTER O..TAMIL LETTER KA
-0B99..0B9A    ; Lo #   [2] TAMIL LETTER NGA..TAMIL LETTER CA
-0B9C          ; Lo #       TAMIL LETTER JA
-0B9E..0B9F    ; Lo #   [2] TAMIL LETTER NYA..TAMIL LETTER TTA
-0BA3..0BA4    ; Lo #   [2] TAMIL LETTER NNA..TAMIL LETTER TA
-0BA8..0BAA    ; Lo #   [3] TAMIL LETTER NA..TAMIL LETTER PA
-0BAE..0BB9    ; Lo #  [12] TAMIL LETTER MA..TAMIL LETTER HA
-0BD0          ; Lo #       TAMIL OM
-0C05..0C0C    ; Lo #   [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L
-0C0E..0C10    ; Lo #   [3] TELUGU LETTER E..TELUGU LETTER AI
-0C12..0C28    ; Lo #  [23] TELUGU LETTER O..TELUGU LETTER NA
-0C2A..0C33    ; Lo #  [10] TELUGU LETTER PA..TELUGU LETTER LLA
-0C35..0C39    ; Lo #   [5] TELUGU LETTER VA..TELUGU LETTER HA
-0C3D          ; Lo #       TELUGU SIGN AVAGRAHA
-0C58..0C59    ; Lo #   [2] TELUGU LETTER TSA..TELUGU LETTER DZA
-0C60..0C61    ; Lo #   [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL
-0C85..0C8C    ; Lo #   [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L
-0C8E..0C90    ; Lo #   [3] KANNADA LETTER E..KANNADA LETTER AI
-0C92..0CA8    ; Lo #  [23] KANNADA LETTER O..KANNADA LETTER NA
-0CAA..0CB3    ; Lo #  [10] KANNADA LETTER PA..KANNADA LETTER LLA
-0CB5..0CB9    ; Lo #   [5] KANNADA LETTER VA..KANNADA LETTER HA
-0CBD          ; Lo #       KANNADA SIGN AVAGRAHA
-0CDE          ; Lo #       KANNADA LETTER FA
-0CE0..0CE1    ; Lo #   [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
-0D05..0D0C    ; Lo #   [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
-0D0E..0D10    ; Lo #   [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
-0D12..0D28    ; Lo #  [23] MALAYALAM LETTER O..MALAYALAM LETTER NA
-0D2A..0D39    ; Lo #  [16] MALAYALAM LETTER PA..MALAYALAM LETTER HA
-0D3D          ; Lo #       MALAYALAM SIGN AVAGRAHA
-0D60..0D61    ; Lo #   [2] MALAYALAM LETTER VOCALIC RR..MALAYALAM LETTER VOCALIC LL
-0D7A..0D7F    ; Lo #   [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
-0D85..0D96    ; Lo #  [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
-0D9A..0DB1    ; Lo #  [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
-0DB3..0DBB    ; Lo #   [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA
-0DBD          ; Lo #       SINHALA LETTER DANTAJA LAYANNA
-0DC0..0DC6    ; Lo #   [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA
-0E01..0E30    ; Lo #  [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A
-0E32..0E33    ; Lo #   [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM
-0E40..0E45    ; Lo #   [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO
-0E81..0E82    ; Lo #   [2] LAO LETTER KO..LAO LETTER KHO SUNG
-0E84          ; Lo #       LAO LETTER KHO TAM
-0E87..0E88    ; Lo #   [2] LAO LETTER NGO..LAO LETTER CO
-0E8A          ; Lo #       LAO LETTER SO TAM
-0E8D          ; Lo #       LAO LETTER NYO
-0E94..0E97    ; Lo #   [4] LAO LETTER DO..LAO LETTER THO TAM
-0E99..0E9F    ; Lo #   [7] LAO LETTER NO..LAO LETTER FO SUNG
-0EA1..0EA3    ; Lo #   [3] LAO LETTER MO..LAO LETTER LO LING
-0EA5          ; Lo #       LAO LETTER LO LOOT
-0EA7          ; Lo #       LAO LETTER WO
-0EAA..0EAB    ; Lo #   [2] LAO LETTER SO SUNG..LAO LETTER HO SUNG
-0EAD..0EB0    ; Lo #   [4] LAO LETTER O..LAO VOWEL SIGN A
-0EB2..0EB3    ; Lo #   [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM
-0EBD          ; Lo #       LAO SEMIVOWEL SIGN NYO
-0EC0..0EC4    ; Lo #   [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
-0EDC..0EDD    ; Lo #   [2] LAO HO NO..LAO HO MO
-0F00          ; Lo #       TIBETAN SYLLABLE OM
-0F40..0F47    ; Lo #   [8] TIBETAN LETTER KA..TIBETAN LETTER JA
-0F49..0F6C    ; Lo #  [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA
-0F88..0F8B    ; Lo #   [4] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN GRU MED RGYINGS
-1000..102A    ; Lo #  [43] MYANMAR LETTER KA..MYANMAR LETTER AU
-103F          ; Lo #       MYANMAR LETTER GREAT SA
-1050..1055    ; Lo #   [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL
-105A..105D    ; Lo #   [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE
-1061          ; Lo #       MYANMAR LETTER SGAW KAREN SHA
-1065..1066    ; Lo #   [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA
-106E..1070    ; Lo #   [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA
-1075..1081    ; Lo #  [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA
-108E          ; Lo #       MYANMAR LETTER RUMAI PALAUNG FA
-10D0..10FA    ; Lo #  [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN
-1100..1159    ; Lo #  [90] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG YEORINHIEUH
-115F..11A2    ; Lo #  [68] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG SSANGARAEA
-11A8..11F9    ; Lo #  [82] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG YEORINHIEUH
-1200..1248    ; Lo #  [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA
-124A..124D    ; Lo #   [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE
-1250..1256    ; Lo #   [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO
-1258          ; Lo #       ETHIOPIC SYLLABLE QHWA
-125A..125D    ; Lo #   [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE
-1260..1288    ; Lo #  [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA
-128A..128D    ; Lo #   [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE
-1290..12B0    ; Lo #  [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA
-12B2..12B5    ; Lo #   [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE
-12B8..12BE    ; Lo #   [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO
-12C0          ; Lo #       ETHIOPIC SYLLABLE KXWA
-12C2..12C5    ; Lo #   [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE
-12C8..12D6    ; Lo #  [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O
-12D8..1310    ; Lo #  [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA
-1312..1315    ; Lo #   [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE
-1318..135A    ; Lo #  [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA
-1380..138F    ; Lo #  [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE
-13A0..13F4    ; Lo #  [85] CHEROKEE LETTER A..CHEROKEE LETTER YV
-1401..166C    ; Lo # [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA
-166F..1676    ; Lo #   [8] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS NNGAA
-1681..169A    ; Lo #  [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH
-16A0..16EA    ; Lo #  [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X
-1700..170C    ; Lo #  [13] TAGALOG LETTER A..TAGALOG LETTER YA
-170E..1711    ; Lo #   [4] TAGALOG LETTER LA..TAGALOG LETTER HA
-1720..1731    ; Lo #  [18] HANUNOO LETTER A..HANUNOO LETTER HA
-1740..1751    ; Lo #  [18] BUHID LETTER A..BUHID LETTER HA
-1760..176C    ; Lo #  [13] TAGBANWA LETTER A..TAGBANWA LETTER YA
-176E..1770    ; Lo #   [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA
-1780..17B3    ; Lo #  [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU
-17DC          ; Lo #       KHMER SIGN AVAKRAHASANYA
-1820..1842    ; Lo #  [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI
-1844..1877    ; Lo #  [52] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER MANCHU ZHA
-1880..18A8    ; Lo #  [41] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER MANCHU ALI GALI BHA
-18AA          ; Lo #       MONGOLIAN LETTER MANCHU ALI GALI LHA
-1900..191C    ; Lo #  [29] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER HA
-1950..196D    ; Lo #  [30] TAI LE LETTER KA..TAI LE LETTER AI
-1970..1974    ; Lo #   [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6
-1980..19A9    ; Lo #  [42] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW XVA
-19C1..19C7    ; Lo #   [7] NEW TAI LUE LETTER FINAL V..NEW TAI LUE LETTER FINAL B
-1A00..1A16    ; Lo #  [23] BUGINESE LETTER KA..BUGINESE LETTER HA
-1B05..1B33    ; Lo #  [47] BALINESE LETTER AKARA..BALINESE LETTER HA
-1B45..1B4B    ; Lo #   [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK
-1B83..1BA0    ; Lo #  [30] SUNDANESE LETTER A..SUNDANESE LETTER HA
-1BAE..1BAF    ; Lo #   [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA
-1C00..1C23    ; Lo #  [36] LEPCHA LETTER KA..LEPCHA LETTER A
-1C4D..1C4F    ; Lo #   [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA
-1C5A..1C77    ; Lo #  [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH
-2135..2138    ; Lo #   [4] ALEF SYMBOL..DALET SYMBOL
-2D30..2D65    ; Lo #  [54] TIFINAGH LETTER YA..TIFINAGH LETTER YAZZ
-2D80..2D96    ; Lo #  [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE
-2DA0..2DA6    ; Lo #   [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO
-2DA8..2DAE    ; Lo #   [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO
-2DB0..2DB6    ; Lo #   [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO
-2DB8..2DBE    ; Lo #   [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO
-2DC0..2DC6    ; Lo #   [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO
-2DC8..2DCE    ; Lo #   [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO
-2DD0..2DD6    ; Lo #   [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO
-2DD8..2DDE    ; Lo #   [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO
-3006          ; Lo #       IDEOGRAPHIC CLOSING MARK
-303C          ; Lo #       MASU MARK
-3041..3096    ; Lo #  [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE
-309F          ; Lo #       HIRAGANA DIGRAPH YORI
-30A1..30FA    ; Lo #  [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO
-30FF          ; Lo #       KATAKANA DIGRAPH KOTO
-3105..312D    ; Lo #  [41] BOPOMOFO LETTER B..BOPOMOFO LETTER IH
-3131..318E    ; Lo #  [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
-31A0..31B7    ; Lo #  [24] BOPOMOFO LETTER BU..BOPOMOFO FINAL LETTER H
-31F0..31FF    ; Lo #  [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
-3400..4DB5    ; Lo # [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
-4E00..9FC3    ; Lo # [20932] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FC3
-A000..A014    ; Lo #  [21] YI SYLLABLE IT..YI SYLLABLE E
-A016..A48C    ; Lo # [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
-A500..A60B    ; Lo # [268] VAI SYLLABLE EE..VAI SYLLABLE NG
-A610..A61F    ; Lo #  [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG
-A62A..A62B    ; Lo #   [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO
-A66E          ; Lo #       CYRILLIC LETTER MULTIOCULAR O
-A7FB..A801    ; Lo #   [7] LATIN EPIGRAPHIC LETTER REVERSED F..SYLOTI NAGRI LETTER I
-A803..A805    ; Lo #   [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O
-A807..A80A    ; Lo #   [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO
-A80C..A822    ; Lo #  [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO
-A840..A873    ; Lo #  [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU
-A882..A8B3    ; Lo #  [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA
-A90A..A925    ; Lo #  [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO
-A930..A946    ; Lo #  [23] REJANG LETTER KA..REJANG LETTER A
-AA00..AA28    ; Lo #  [41] CHAM LETTER A..CHAM LETTER HA
-AA40..AA42    ; Lo #   [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG
-AA44..AA4B    ; Lo #   [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS
-AC00..D7A3    ; Lo # [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH
-F900..FA2D    ; Lo # [302] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA2D
-FA30..FA6A    ; Lo #  [59] CJK COMPATIBILITY IDEOGRAPH-FA30..CJK COMPATIBILITY IDEOGRAPH-FA6A
-FA70..FAD9    ; Lo # [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
-FB1D          ; Lo #       HEBREW LETTER YOD WITH HIRIQ
-FB1F..FB28    ; Lo #  [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV
-FB2A..FB36    ; Lo #  [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH
-FB38..FB3C    ; Lo #   [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH
-FB3E          ; Lo #       HEBREW LETTER MEM WITH DAGESH
-FB40..FB41    ; Lo #   [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH
-FB43..FB44    ; Lo #   [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH
-FB46..FBB1    ; Lo # [108] HEBREW LETTER TSADI WITH DAGESH..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
-FBD3..FD3D    ; Lo # [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM
-FD50..FD8F    ; Lo #  [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM
-FD92..FDC7    ; Lo #  [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM
-FDF0..FDFB    ; Lo #  [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU
-FE70..FE74    ; Lo #   [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM
-FE76..FEFC    ; Lo # [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM
-FF66..FF6F    ; Lo #  [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU
-FF71..FF9D    ; Lo #  [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N
-FFA0..FFBE    ; Lo #  [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH
-FFC2..FFC7    ; Lo #   [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E
-FFCA..FFCF    ; Lo #   [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE
-FFD2..FFD7    ; Lo #   [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU
-FFDA..FFDC    ; Lo #   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I
-10000..1000B  ; Lo #  [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE
-1000D..10026  ; Lo #  [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO
-10028..1003A  ; Lo #  [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO
-1003C..1003D  ; Lo #   [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE
-1003F..1004D  ; Lo #  [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO
-10050..1005D  ; Lo #  [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089
-10080..100FA  ; Lo # [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305
-10280..1029C  ; Lo #  [29] LYCIAN LETTER A..LYCIAN LETTER X
-102A0..102D0  ; Lo #  [49] CARIAN LETTER A..CARIAN LETTER UUU3
-10300..1031E  ; Lo #  [31] OLD ITALIC LETTER A..OLD ITALIC LETTER UU
-10330..10340  ; Lo #  [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA
-10342..10349  ; Lo #   [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL
-10380..1039D  ; Lo #  [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU
-103A0..103C3  ; Lo #  [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA
-103C8..103CF  ; Lo #   [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH
-10450..1049D  ; Lo #  [78] SHAVIAN LETTER PEEP..OSMANYA LETTER OO
-10800..10805  ; Lo #   [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA
-10808         ; Lo #       CYPRIOT SYLLABLE JO
-1080A..10835  ; Lo #  [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO
-10837..10838  ; Lo #   [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE
-1083C         ; Lo #       CYPRIOT SYLLABLE ZA
-1083F         ; Lo #       CYPRIOT SYLLABLE ZO
-10900..10915  ; Lo #  [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU
-10920..10939  ; Lo #  [26] LYDIAN LETTER A..LYDIAN LETTER C
-10A00         ; Lo #       KHAROSHTHI LETTER A
-10A10..10A13  ; Lo #   [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA
-10A15..10A17  ; Lo #   [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA
-10A19..10A33  ; Lo #  [27] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER TTTHA
-12000..1236E  ; Lo # [879] CUNEIFORM SIGN A..CUNEIFORM SIGN ZUM
-20000..2A6D6  ; Lo # [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
-2F800..2FA1D  ; Lo # [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
-
-# Total code points: 90068
-
-# ================================================
-
-# General_Category=Nonspacing_Mark
-
-0300..036F    ; Mn # [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X
-0483..0487    ; Mn #   [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
-0591..05BD    ; Mn #  [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
-05BF          ; Mn #       HEBREW POINT RAFE
-05C1..05C2    ; Mn #   [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
-05C4..05C5    ; Mn #   [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
-05C7          ; Mn #       HEBREW POINT QAMATS QATAN
-0610..061A    ; Mn #  [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
-064B..065E    ; Mn #  [20] ARABIC FATHATAN..ARABIC FATHA WITH TWO DOTS
-0670          ; Mn #       ARABIC LETTER SUPERSCRIPT ALEF
-06D6..06DC    ; Mn #   [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
-06DF..06E4    ; Mn #   [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
-06E7..06E8    ; Mn #   [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
-06EA..06ED    ; Mn #   [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
-0711          ; Mn #       SYRIAC LETTER SUPERSCRIPT ALAPH
-0730..074A    ; Mn #  [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
-07A6..07B0    ; Mn #  [11] THAANA ABAFILI..THAANA SUKUN
-07EB..07F3    ; Mn #   [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
-0901..0902    ; Mn #   [2] DEVANAGARI SIGN CANDRABINDU..DEVANAGARI SIGN ANUSVARA
-093C          ; Mn #       DEVANAGARI SIGN NUKTA
-0941..0948    ; Mn #   [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
-094D          ; Mn #       DEVANAGARI SIGN VIRAMA
-0951..0954    ; Mn #   [4] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI ACUTE ACCENT
-0962..0963    ; Mn #   [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
-0981          ; Mn #       BENGALI SIGN CANDRABINDU
-09BC          ; Mn #       BENGALI SIGN NUKTA
-09C1..09C4    ; Mn #   [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
-09CD          ; Mn #       BENGALI SIGN VIRAMA
-09E2..09E3    ; Mn #   [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
-0A01..0A02    ; Mn #   [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
-0A3C          ; Mn #       GURMUKHI SIGN NUKTA
-0A41..0A42    ; Mn #   [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
-0A47..0A48    ; Mn #   [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
-0A4B..0A4D    ; Mn #   [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
-0A51          ; Mn #       GURMUKHI SIGN UDAAT
-0A70..0A71    ; Mn #   [2] GURMUKHI TIPPI..GURMUKHI ADDAK
-0A75          ; Mn #       GURMUKHI SIGN YAKASH
-0A81..0A82    ; Mn #   [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
-0ABC          ; Mn #       GUJARATI SIGN NUKTA
-0AC1..0AC5    ; Mn #   [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
-0AC7..0AC8    ; Mn #   [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
-0ACD          ; Mn #       GUJARATI SIGN VIRAMA
-0AE2..0AE3    ; Mn #   [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
-0B01          ; Mn #       ORIYA SIGN CANDRABINDU
-0B3C          ; Mn #       ORIYA SIGN NUKTA
-0B3F          ; Mn #       ORIYA VOWEL SIGN I
-0B41..0B44    ; Mn #   [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
-0B4D          ; Mn #       ORIYA SIGN VIRAMA
-0B56          ; Mn #       ORIYA AI LENGTH MARK
-0B62..0B63    ; Mn #   [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
-0B82          ; Mn #       TAMIL SIGN ANUSVARA
-0BC0          ; Mn #       TAMIL VOWEL SIGN II
-0BCD          ; Mn #       TAMIL SIGN VIRAMA
-0C3E..0C40    ; Mn #   [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
-0C46..0C48    ; Mn #   [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
-0C4A..0C4D    ; Mn #   [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
-0C55..0C56    ; Mn #   [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
-0C62..0C63    ; Mn #   [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
-0CBC          ; Mn #       KANNADA SIGN NUKTA
-0CBF          ; Mn #       KANNADA VOWEL SIGN I
-0CC6          ; Mn #       KANNADA VOWEL SIGN E
-0CCC..0CCD    ; Mn #   [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA
-0CE2..0CE3    ; Mn #   [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
-0D41..0D44    ; Mn #   [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
-0D4D          ; Mn #       MALAYALAM SIGN VIRAMA
-0D62..0D63    ; Mn #   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
-0DCA          ; Mn #       SINHALA SIGN AL-LAKUNA
-0DD2..0DD4    ; Mn #   [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
-0DD6          ; Mn #       SINHALA VOWEL SIGN DIGA PAA-PILLA
-0E31          ; Mn #       THAI CHARACTER MAI HAN-AKAT
-0E34..0E3A    ; Mn #   [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
-0E47..0E4E    ; Mn #   [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
-0EB1          ; Mn #       LAO VOWEL SIGN MAI KAN
-0EB4..0EB9    ; Mn #   [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU
-0EBB..0EBC    ; Mn #   [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO
-0EC8..0ECD    ; Mn #   [6] LAO TONE MAI EK..LAO NIGGAHITA
-0F18..0F19    ; Mn #   [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
-0F35          ; Mn #       TIBETAN MARK NGAS BZUNG NYI ZLA
-0F37          ; Mn #       TIBETAN MARK NGAS BZUNG SGOR RTAGS
-0F39          ; Mn #       TIBETAN MARK TSA -PHRU
-0F71..0F7E    ; Mn #  [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
-0F80..0F84    ; Mn #   [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA
-0F86..0F87    ; Mn #   [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
-0F90..0F97    ; Mn #   [8] TIBETAN SUBJOINED LETTER KA..TIBETAN SUBJOINED LETTER JA
-0F99..0FBC    ; Mn #  [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
-0FC6          ; Mn #       TIBETAN SYMBOL PADMA GDAN
-102D..1030    ; Mn #   [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
-1032..1037    ; Mn #   [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW
-1039..103A    ; Mn #   [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
-103D..103E    ; Mn #   [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
-1058..1059    ; Mn #   [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
-105E..1060    ; Mn #   [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
-1071..1074    ; Mn #   [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
-1082          ; Mn #       MYANMAR CONSONANT SIGN SHAN MEDIAL WA
-1085..1086    ; Mn #   [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
-108D          ; Mn #       MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
-135F          ; Mn #       ETHIOPIC COMBINING GEMINATION MARK
-1712..1714    ; Mn #   [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA
-1732..1734    ; Mn #   [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD
-1752..1753    ; Mn #   [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
-1772..1773    ; Mn #   [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
-17B7..17BD    ; Mn #   [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
-17C6          ; Mn #       KHMER SIGN NIKAHIT
-17C9..17D3    ; Mn #  [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
-17DD          ; Mn #       KHMER SIGN ATTHACAN
-180B..180D    ; Mn #   [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
-18A9          ; Mn #       MONGOLIAN LETTER ALI GALI DAGALGA
-1920..1922    ; Mn #   [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
-1927..1928    ; Mn #   [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
-1932          ; Mn #       LIMBU SMALL LETTER ANUSVARA
-1939..193B    ; Mn #   [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
-1A17..1A18    ; Mn #   [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
-1B00..1B03    ; Mn #   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
-1B34          ; Mn #       BALINESE SIGN REREKAN
-1B36..1B3A    ; Mn #   [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
-1B3C          ; Mn #       BALINESE VOWEL SIGN LA LENGA
-1B42          ; Mn #       BALINESE VOWEL SIGN PEPET
-1B6B..1B73    ; Mn #   [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
-1B80..1B81    ; Mn #   [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
-1BA2..1BA5    ; Mn #   [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
-1BA8..1BA9    ; Mn #   [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
-1C2C..1C33    ; Mn #   [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
-1C36..1C37    ; Mn #   [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
-1DC0..1DE6    ; Mn #  [39] COMBINING DOTTED GRAVE ACCENT..COMBINING LATIN SMALL LETTER Z
-1DFE..1DFF    ; Mn #   [2] COMBINING LEFT ARROWHEAD ABOVE..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
-20D0..20DC    ; Mn #  [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
-20E1          ; Mn #       COMBINING LEFT RIGHT ARROW ABOVE
-20E5..20F0    ; Mn #  [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE
-2DE0..2DFF    ; Mn #  [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
-302A..302F    ; Mn #   [6] IDEOGRAPHIC LEVEL TONE MARK..HANGUL DOUBLE DOT TONE MARK
-3099..309A    ; Mn #   [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
-A66F          ; Mn #       COMBINING CYRILLIC VZMET
-A67C..A67D    ; Mn #   [2] COMBINING CYRILLIC KAVYKA..COMBINING CYRILLIC PAYEROK
-A802          ; Mn #       SYLOTI NAGRI SIGN DVISVARA
-A806          ; Mn #       SYLOTI NAGRI SIGN HASANTA
-A80B          ; Mn #       SYLOTI NAGRI SIGN ANUSVARA
-A825..A826    ; Mn #   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
-A8C4          ; Mn #       SAURASHTRA SIGN VIRAMA
-A926..A92D    ; Mn #   [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU
-A947..A951    ; Mn #  [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
-AA29..AA2E    ; Mn #   [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
-AA31..AA32    ; Mn #   [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
-AA35..AA36    ; Mn #   [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
-AA43          ; Mn #       CHAM CONSONANT SIGN FINAL NG
-AA4C          ; Mn #       CHAM CONSONANT SIGN FINAL M
-FB1E          ; Mn #       HEBREW POINT JUDEO-SPANISH VARIKA
-FE00..FE0F    ; Mn #  [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
-FE20..FE26    ; Mn #   [7] COMBINING LIGATURE LEFT HALF..COMBINING CONJOINING MACRON
-101FD         ; Mn #       PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
-10A01..10A03  ; Mn #   [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
-10A05..10A06  ; Mn #   [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
-10A0C..10A0F  ; Mn #   [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
-10A38..10A3A  ; Mn #   [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW
-10A3F         ; Mn #       KHAROSHTHI VIRAMA
-1D167..1D169  ; Mn #   [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
-1D17B..1D182  ; Mn #   [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
-1D185..1D18B  ; Mn #   [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
-1D1AA..1D1AD  ; Mn #   [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
-1D242..1D244  ; Mn #   [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
-E0100..E01EF  ; Mn # [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
-
-# Total code points: 1032
-
-# ================================================
-
-# General_Category=Enclosing_Mark
-
-0488..0489    ; Me #   [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
-06DE          ; Me #       ARABIC START OF RUB EL HIZB
-20DD..20E0    ; Me #   [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
-20E2..20E4    ; Me #   [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
-A670..A672    ; Me #   [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
-
-# Total code points: 13
-
-# ================================================
-
-# General_Category=Spacing_Mark
-
-0903          ; Mc #       DEVANAGARI SIGN VISARGA
-093E..0940    ; Mc #   [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
-0949..094C    ; Mc #   [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
-0982..0983    ; Mc #   [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
-09BE..09C0    ; Mc #   [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II
-09C7..09C8    ; Mc #   [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
-09CB..09CC    ; Mc #   [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
-09D7          ; Mc #       BENGALI AU LENGTH MARK
-0A03          ; Mc #       GURMUKHI SIGN VISARGA
-0A3E..0A40    ; Mc #   [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
-0A83          ; Mc #       GUJARATI SIGN VISARGA
-0ABE..0AC0    ; Mc #   [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
-0AC9          ; Mc #       GUJARATI VOWEL SIGN CANDRA O
-0ACB..0ACC    ; Mc #   [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
-0B02..0B03    ; Mc #   [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
-0B3E          ; Mc #       ORIYA VOWEL SIGN AA
-0B40          ; Mc #       ORIYA VOWEL SIGN II
-0B47..0B48    ; Mc #   [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
-0B4B..0B4C    ; Mc #   [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
-0B57          ; Mc #       ORIYA AU LENGTH MARK
-0BBE..0BBF    ; Mc #   [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I
-0BC1..0BC2    ; Mc #   [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
-0BC6..0BC8    ; Mc #   [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
-0BCA..0BCC    ; Mc #   [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
-0BD7          ; Mc #       TAMIL AU LENGTH MARK
-0C01..0C03    ; Mc #   [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
-0C41..0C44    ; Mc #   [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
-0C82..0C83    ; Mc #   [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
-0CBE          ; Mc #       KANNADA VOWEL SIGN AA
-0CC0..0CC4    ; Mc #   [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR
-0CC7..0CC8    ; Mc #   [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
-0CCA..0CCB    ; Mc #   [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
-0CD5..0CD6    ; Mc #   [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
-0D02..0D03    ; Mc #   [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
-0D3E..0D40    ; Mc #   [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II
-0D46..0D48    ; Mc #   [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
-0D4A..0D4C    ; Mc #   [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
-0D57          ; Mc #       MALAYALAM AU LENGTH MARK
-0D82..0D83    ; Mc #   [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
-0DCF..0DD1    ; Mc #   [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
-0DD8..0DDF    ; Mc #   [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
-0DF2..0DF3    ; Mc #   [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
-0F3E..0F3F    ; Mc #   [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
-0F7F          ; Mc #       TIBETAN SIGN RNAM BCAD
-102B..102C    ; Mc #   [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA
-1031          ; Mc #       MYANMAR VOWEL SIGN E
-1038          ; Mc #       MYANMAR SIGN VISARGA
-103B..103C    ; Mc #   [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
-1056..1057    ; Mc #   [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
-1062..1064    ; Mc #   [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO
-1067..106D    ; Mc #   [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5
-1083..1084    ; Mc #   [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E
-1087..108C    ; Mc #   [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3
-108F          ; Mc #       MYANMAR SIGN RUMAI PALAUNG TONE-5
-17B6          ; Mc #       KHMER VOWEL SIGN AA
-17BE..17C5    ; Mc #   [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
-17C7..17C8    ; Mc #   [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
-1923..1926    ; Mc #   [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
-1929..192B    ; Mc #   [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
-1930..1931    ; Mc #   [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
-1933..1938    ; Mc #   [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
-19B0..19C0    ; Mc #  [17] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE VOWEL SIGN IY
-19C8..19C9    ; Mc #   [2] NEW TAI LUE TONE MARK-1..NEW TAI LUE TONE MARK-2
-1A19..1A1B    ; Mc #   [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE
-1B04          ; Mc #       BALINESE SIGN BISAH
-1B35          ; Mc #       BALINESE VOWEL SIGN TEDUNG
-1B3B          ; Mc #       BALINESE VOWEL SIGN RA REPA TEDUNG
-1B3D..1B41    ; Mc #   [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
-1B43..1B44    ; Mc #   [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG
-1B82          ; Mc #       SUNDANESE SIGN PANGWISAD
-1BA1          ; Mc #       SUNDANESE CONSONANT SIGN PAMINGKAL
-1BA6..1BA7    ; Mc #   [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
-1BAA          ; Mc #       SUNDANESE SIGN PAMAAEH
-1C24..1C2B    ; Mc #   [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
-1C34..1C35    ; Mc #   [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
-A823..A824    ; Mc #   [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
-A827          ; Mc #       SYLOTI NAGRI VOWEL SIGN OO
-A880..A881    ; Mc #   [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
-A8B4..A8C3    ; Mc #  [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
-A952..A953    ; Mc #   [2] REJANG CONSONANT SIGN H..REJANG VIRAMA
-AA2F..AA30    ; Mc #   [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
-AA33..AA34    ; Mc #   [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
-AA4D          ; Mc #       CHAM CONSONANT SIGN FINAL H
-1D165..1D166  ; Mc #   [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
-1D16D..1D172  ; Mc #   [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5
-
-# Total code points: 236
-
-# ================================================
-
-# General_Category=Decimal_Number
-
-0030..0039    ; Nd #  [10] DIGIT ZERO..DIGIT NINE
-0660..0669    ; Nd #  [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE
-06F0..06F9    ; Nd #  [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE
-07C0..07C9    ; Nd #  [10] NKO DIGIT ZERO..NKO DIGIT NINE
-0966..096F    ; Nd #  [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE
-09E6..09EF    ; Nd #  [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE
-0A66..0A6F    ; Nd #  [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE
-0AE6..0AEF    ; Nd #  [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE
-0B66..0B6F    ; Nd #  [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE
-0BE6..0BEF    ; Nd #  [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE
-0C66..0C6F    ; Nd #  [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE
-0CE6..0CEF    ; Nd #  [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
-0D66..0D6F    ; Nd #  [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
-0E50..0E59    ; Nd #  [10] THAI DIGIT ZERO..THAI DIGIT NINE
-0ED0..0ED9    ; Nd #  [10] LAO DIGIT ZERO..LAO DIGIT NINE
-0F20..0F29    ; Nd #  [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE
-1040..1049    ; Nd #  [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE
-1090..1099    ; Nd #  [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE
-17E0..17E9    ; Nd #  [10] KHMER DIGIT ZERO..KHMER DIGIT NINE
-1810..1819    ; Nd #  [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
-1946..194F    ; Nd #  [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE
-19D0..19D9    ; Nd #  [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE
-1B50..1B59    ; Nd #  [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE
-1BB0..1BB9    ; Nd #  [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE
-1C40..1C49    ; Nd #  [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE
-1C50..1C59    ; Nd #  [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE
-A620..A629    ; Nd #  [10] VAI DIGIT ZERO..VAI DIGIT NINE
-A8D0..A8D9    ; Nd #  [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE
-A900..A909    ; Nd #  [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE
-AA50..AA59    ; Nd #  [10] CHAM DIGIT ZERO..CHAM DIGIT NINE
-FF10..FF19    ; Nd #  [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE
-104A0..104A9  ; Nd #  [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE
-1D7CE..1D7FF  ; Nd #  [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE
-
-# Total code points: 370
-
-# ================================================
-
-# General_Category=Letter_Number
-
-16EE..16F0    ; Nl #   [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL
-2160..2182    ; Nl #  [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND
-2185..2188    ; Nl #   [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND
-3007          ; Nl #       IDEOGRAPHIC NUMBER ZERO
-3021..3029    ; Nl #   [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE
-3038..303A    ; Nl #   [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY
-10140..10174  ; Nl #  [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS
-10341         ; Nl #       GOTHIC LETTER NINETY
-1034A         ; Nl #       GOTHIC LETTER NINE HUNDRED
-103D1..103D5  ; Nl #   [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED
-12400..12462  ; Nl #  [99] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER
-
-# Total code points: 214
-
-# ================================================
-
-# General_Category=Other_Number
-
-00B2..00B3    ; No #   [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE
-00B9          ; No #       SUPERSCRIPT ONE
-00BC..00BE    ; No #   [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS
-09F4..09F9    ; No #   [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN
-0BF0..0BF2    ; No #   [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND
-0C78..0C7E    ; No #   [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR
-0D70..0D75    ; No #   [6] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE QUARTERS
-0F2A..0F33    ; No #  [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO
-1369..137C    ; No #  [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND
-17F0..17F9    ; No #  [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON
-2070          ; No #       SUPERSCRIPT ZERO
-2074..2079    ; No #   [6] SUPERSCRIPT FOUR..SUPERSCRIPT NINE
-2080..2089    ; No #  [10] SUBSCRIPT ZERO..SUBSCRIPT NINE
-2153..215F    ; No #  [13] VULGAR FRACTION ONE THIRD..FRACTION NUMERATOR ONE
-2460..249B    ; No #  [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP
-24EA..24FF    ; No #  [22] CIRCLED DIGIT ZERO..NEGATIVE CIRCLED DIGIT ZERO
-2776..2793    ; No #  [30] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
-2CFD          ; No #       COPTIC FRACTION ONE HALF
-3192..3195    ; No #   [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK
-3220..3229    ; No #  [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN
-3251..325F    ; No #  [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE
-3280..3289    ; No #  [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN
-32B1..32BF    ; No #  [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY
-10107..10133  ; No #  [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND
-10175..10178  ; No #   [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN
-1018A         ; No #       GREEK ZERO SIGN
-10320..10323  ; No #   [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY
-10916..10919  ; No #   [4] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER ONE HUNDRED
-10A40..10A47  ; No #   [8] KHAROSHTHI DIGIT ONE..KHAROSHTHI NUMBER ONE THOUSAND
-1D360..1D371  ; No #  [18] COUNTING ROD UNIT DIGIT ONE..COUNTING ROD TENS DIGIT NINE
-
-# Total code points: 349
-
-# ================================================
-
-# General_Category=Space_Separator
-
-0020          ; Zs #       SPACE
-00A0          ; Zs #       NO-BREAK SPACE
-1680          ; Zs #       OGHAM SPACE MARK
-180E          ; Zs #       MONGOLIAN VOWEL SEPARATOR
-2000..200A    ; Zs #  [11] EN QUAD..HAIR SPACE
-202F          ; Zs #       NARROW NO-BREAK SPACE
-205F          ; Zs #       MEDIUM MATHEMATICAL SPACE
-3000          ; Zs #       IDEOGRAPHIC SPACE
-
-# Total code points: 18
-
-# ================================================
-
-# General_Category=Line_Separator
-
-2028          ; Zl #       LINE SEPARATOR
-
-# Total code points: 1
-
-# ================================================
-
-# General_Category=Paragraph_Separator
-
-2029          ; Zp #       PARAGRAPH SEPARATOR
-
-# Total code points: 1
-
-# ================================================
-
-# General_Category=Control
-
-0000..001F    ; Cc #  [32] <control-0000>..<control-001F>
-007F..009F    ; Cc #  [33] <control-007F>..<control-009F>
-
-# Total code points: 65
-
-# ================================================
-
-# General_Category=Format
-
-00AD          ; Cf #       SOFT HYPHEN
-0600..0603    ; Cf #   [4] ARABIC NUMBER SIGN..ARABIC SIGN SAFHA
-06DD          ; Cf #       ARABIC END OF AYAH
-070F          ; Cf #       SYRIAC ABBREVIATION MARK
-17B4..17B5    ; Cf #   [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
-200B..200F    ; Cf #   [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
-202A..202E    ; Cf #   [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
-2060..2064    ; Cf #   [5] WORD JOINER..INVISIBLE PLUS
-206A..206F    ; Cf #   [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
-FEFF          ; Cf #       ZERO WIDTH NO-BREAK SPACE
-FFF9..FFFB    ; Cf #   [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
-1D173..1D17A  ; Cf #   [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
-E0001         ; Cf #       LANGUAGE TAG
-E0020..E007F  ; Cf #  [96] TAG SPACE..CANCEL TAG
-
-# Total code points: 139
-
-# ================================================
-
-# General_Category=Private_Use
-
-E000..F8FF    ; Co # [6400] <private-use-E000>..<private-use-F8FF>
-F0000..FFFFD  ; Co # [65534] <private-use-F0000>..<private-use-FFFFD>
-100000..10FFFD; Co # [65534] <private-use-100000>..<private-use-10FFFD>
-
-# Total code points: 137468
-
-# ================================================
-
-# General_Category=Surrogate
-
-D800..DFFF    ; Cs # [2048] <surrogate-D800>..<surrogate-DFFF>
-
-# Total code points: 2048
-
-# ================================================
-
-# General_Category=Dash_Punctuation
-
-002D          ; Pd #       HYPHEN-MINUS
-058A          ; Pd #       ARMENIAN HYPHEN
-05BE          ; Pd #       HEBREW PUNCTUATION MAQAF
-1806          ; Pd #       MONGOLIAN TODO SOFT HYPHEN
-2010..2015    ; Pd #   [6] HYPHEN..HORIZONTAL BAR
-2E17          ; Pd #       DOUBLE OBLIQUE HYPHEN
-2E1A          ; Pd #       HYPHEN WITH DIAERESIS
-301C          ; Pd #       WAVE DASH
-3030          ; Pd #       WAVY DASH
-30A0          ; Pd #       KATAKANA-HIRAGANA DOUBLE HYPHEN
-FE31..FE32    ; Pd #   [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH
-FE58          ; Pd #       SMALL EM DASH
-FE63          ; Pd #       SMALL HYPHEN-MINUS
-FF0D          ; Pd #       FULLWIDTH HYPHEN-MINUS
-
-# Total code points: 20
-
-# ================================================
-
-# General_Category=Open_Punctuation
-
-0028          ; Ps #       LEFT PARENTHESIS
-005B          ; Ps #       LEFT SQUARE BRACKET
-007B          ; Ps #       LEFT CURLY BRACKET
-0F3A          ; Ps #       TIBETAN MARK GUG RTAGS GYON
-0F3C          ; Ps #       TIBETAN MARK ANG KHANG GYON
-169B          ; Ps #       OGHAM FEATHER MARK
-201A          ; Ps #       SINGLE LOW-9 QUOTATION MARK
-201E          ; Ps #       DOUBLE LOW-9 QUOTATION MARK
-2045          ; Ps #       LEFT SQUARE BRACKET WITH QUILL
-207D          ; Ps #       SUPERSCRIPT LEFT PARENTHESIS
-208D          ; Ps #       SUBSCRIPT LEFT PARENTHESIS
-2329          ; Ps #       LEFT-POINTING ANGLE BRACKET
-2768          ; Ps #       MEDIUM LEFT PARENTHESIS ORNAMENT
-276A          ; Ps #       MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
-276C          ; Ps #       MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
-276E          ; Ps #       HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
-2770          ; Ps #       HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
-2772          ; Ps #       LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
-2774          ; Ps #       MEDIUM LEFT CURLY BRACKET ORNAMENT
-27C5          ; Ps #       LEFT S-SHAPED BAG DELIMITER
-27E6          ; Ps #       MATHEMATICAL LEFT WHITE SQUARE BRACKET
-27E8          ; Ps #       MATHEMATICAL LEFT ANGLE BRACKET
-27EA          ; Ps #       MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
-27EC          ; Ps #       MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
-27EE          ; Ps #       MATHEMATICAL LEFT FLATTENED PARENTHESIS
-2983          ; Ps #       LEFT WHITE CURLY BRACKET
-2985          ; Ps #       LEFT WHITE PARENTHESIS
-2987          ; Ps #       Z NOTATION LEFT IMAGE BRACKET
-2989          ; Ps #       Z NOTATION LEFT BINDING BRACKET
-298B          ; Ps #       LEFT SQUARE BRACKET WITH UNDERBAR
-298D          ; Ps #       LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
-298F          ; Ps #       LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
-2991          ; Ps #       LEFT ANGLE BRACKET WITH DOT
-2993          ; Ps #       LEFT ARC LESS-THAN BRACKET
-2995          ; Ps #       DOUBLE LEFT ARC GREATER-THAN BRACKET
-2997          ; Ps #       LEFT BLACK TORTOISE SHELL BRACKET
-29D8          ; Ps #       LEFT WIGGLY FENCE
-29DA          ; Ps #       LEFT DOUBLE WIGGLY FENCE
-29FC          ; Ps #       LEFT-POINTING CURVED ANGLE BRACKET
-2E22          ; Ps #       TOP LEFT HALF BRACKET
-2E24          ; Ps #       BOTTOM LEFT HALF BRACKET
-2E26          ; Ps #       LEFT SIDEWAYS U BRACKET
-2E28          ; Ps #       LEFT DOUBLE PARENTHESIS
-3008          ; Ps #       LEFT ANGLE BRACKET
-300A          ; Ps #       LEFT DOUBLE ANGLE BRACKET
-300C          ; Ps #       LEFT CORNER BRACKET
-300E          ; Ps #       LEFT WHITE CORNER BRACKET
-3010          ; Ps #       LEFT BLACK LENTICULAR BRACKET
-3014          ; Ps #       LEFT TORTOISE SHELL BRACKET
-3016          ; Ps #       LEFT WHITE LENTICULAR BRACKET
-3018          ; Ps #       LEFT WHITE TORTOISE SHELL BRACKET
-301A          ; Ps #       LEFT WHITE SQUARE BRACKET
-301D          ; Ps #       REVERSED DOUBLE PRIME QUOTATION MARK
-FD3E          ; Ps #       ORNATE LEFT PARENTHESIS
-FE17          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
-FE35          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
-FE37          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
-FE39          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
-FE3B          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
-FE3D          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
-FE3F          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
-FE41          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
-FE43          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
-FE47          ; Ps #       PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
-FE59          ; Ps #       SMALL LEFT PARENTHESIS
-FE5B          ; Ps #       SMALL LEFT CURLY BRACKET
-FE5D          ; Ps #       SMALL LEFT TORTOISE SHELL BRACKET
-FF08          ; Ps #       FULLWIDTH LEFT PARENTHESIS
-FF3B          ; Ps #       FULLWIDTH LEFT SQUARE BRACKET
-FF5B          ; Ps #       FULLWIDTH LEFT CURLY BRACKET
-FF5F          ; Ps #       FULLWIDTH LEFT WHITE PARENTHESIS
-FF62          ; Ps #       HALFWIDTH LEFT CORNER BRACKET
-
-# Total code points: 72
-
-# ================================================
-
-# General_Category=Close_Punctuation
-
-0029          ; Pe #       RIGHT PARENTHESIS
-005D          ; Pe #       RIGHT SQUARE BRACKET
-007D          ; Pe #       RIGHT CURLY BRACKET
-0F3B          ; Pe #       TIBETAN MARK GUG RTAGS GYAS
-0F3D          ; Pe #       TIBETAN MARK ANG KHANG GYAS
-169C          ; Pe #       OGHAM REVERSED FEATHER MARK
-2046          ; Pe #       RIGHT SQUARE BRACKET WITH QUILL
-207E          ; Pe #       SUPERSCRIPT RIGHT PARENTHESIS
-208E          ; Pe #       SUBSCRIPT RIGHT PARENTHESIS
-232A          ; Pe #       RIGHT-POINTING ANGLE BRACKET
-2769          ; Pe #       MEDIUM RIGHT PARENTHESIS ORNAMENT
-276B          ; Pe #       MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
-276D          ; Pe #       MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
-276F          ; Pe #       HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
-2771          ; Pe #       HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
-2773          ; Pe #       LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
-2775          ; Pe #       MEDIUM RIGHT CURLY BRACKET ORNAMENT
-27C6          ; Pe #       RIGHT S-SHAPED BAG DELIMITER
-27E7          ; Pe #       MATHEMATICAL RIGHT WHITE SQUARE BRACKET
-27E9          ; Pe #       MATHEMATICAL RIGHT ANGLE BRACKET
-27EB          ; Pe #       MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
-27ED          ; Pe #       MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
-27EF          ; Pe #       MATHEMATICAL RIGHT FLATTENED PARENTHESIS
-2984          ; Pe #       RIGHT WHITE CURLY BRACKET
-2986          ; Pe #       RIGHT WHITE PARENTHESIS
-2988          ; Pe #       Z NOTATION RIGHT IMAGE BRACKET
-298A          ; Pe #       Z NOTATION RIGHT BINDING BRACKET
-298C          ; Pe #       RIGHT SQUARE BRACKET WITH UNDERBAR
-298E          ; Pe #       RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
-2990          ; Pe #       RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
-2992          ; Pe #       RIGHT ANGLE BRACKET WITH DOT
-2994          ; Pe #       RIGHT ARC GREATER-THAN BRACKET
-2996          ; Pe #       DOUBLE RIGHT ARC LESS-THAN BRACKET
-2998          ; Pe #       RIGHT BLACK TORTOISE SHELL BRACKET
-29D9          ; Pe #       RIGHT WIGGLY FENCE
-29DB          ; Pe #       RIGHT DOUBLE WIGGLY FENCE
-29FD          ; Pe #       RIGHT-POINTING CURVED ANGLE BRACKET
-2E23          ; Pe #       TOP RIGHT HALF BRACKET
-2E25          ; Pe #       BOTTOM RIGHT HALF BRACKET
-2E27          ; Pe #       RIGHT SIDEWAYS U BRACKET
-2E29          ; Pe #       RIGHT DOUBLE PARENTHESIS
-3009          ; Pe #       RIGHT ANGLE BRACKET
-300B          ; Pe #       RIGHT DOUBLE ANGLE BRACKET
-300D          ; Pe #       RIGHT CORNER BRACKET
-300F          ; Pe #       RIGHT WHITE CORNER BRACKET
-3011          ; Pe #       RIGHT BLACK LENTICULAR BRACKET
-3015          ; Pe #       RIGHT TORTOISE SHELL BRACKET
-3017          ; Pe #       RIGHT WHITE LENTICULAR BRACKET
-3019          ; Pe #       RIGHT WHITE TORTOISE SHELL BRACKET
-301B          ; Pe #       RIGHT WHITE SQUARE BRACKET
-301E..301F    ; Pe #   [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK
-FD3F          ; Pe #       ORNATE RIGHT PARENTHESIS
-FE18          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET
-FE36          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
-FE38          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
-FE3A          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
-FE3C          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
-FE3E          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
-FE40          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
-FE42          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
-FE44          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
-FE48          ; Pe #       PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
-FE5A          ; Pe #       SMALL RIGHT PARENTHESIS
-FE5C          ; Pe #       SMALL RIGHT CURLY BRACKET
-FE5E          ; Pe #       SMALL RIGHT TORTOISE SHELL BRACKET
-FF09          ; Pe #       FULLWIDTH RIGHT PARENTHESIS
-FF3D          ; Pe #       FULLWIDTH RIGHT SQUARE BRACKET
-FF5D          ; Pe #       FULLWIDTH RIGHT CURLY BRACKET
-FF60          ; Pe #       FULLWIDTH RIGHT WHITE PARENTHESIS
-FF63          ; Pe #       HALFWIDTH RIGHT CORNER BRACKET
-
-# Total code points: 71
-
-# ================================================
-
-# General_Category=Connector_Punctuation
-
-005F          ; Pc #       LOW LINE
-203F..2040    ; Pc #   [2] UNDERTIE..CHARACTER TIE
-2054          ; Pc #       INVERTED UNDERTIE
-FE33..FE34    ; Pc #   [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
-FE4D..FE4F    ; Pc #   [3] DASHED LOW LINE..WAVY LOW LINE
-FF3F          ; Pc #       FULLWIDTH LOW LINE
-
-# Total code points: 10
-
-# ================================================
-
-# General_Category=Other_Punctuation
-
-0021..0023    ; Po #   [3] EXCLAMATION MARK..NUMBER SIGN
-0025..0027    ; Po #   [3] PERCENT SIGN..APOSTROPHE
-002A          ; Po #       ASTERISK
-002C          ; Po #       COMMA
-002E..002F    ; Po #   [2] FULL STOP..SOLIDUS
-003A..003B    ; Po #   [2] COLON..SEMICOLON
-003F..0040    ; Po #   [2] QUESTION MARK..COMMERCIAL AT
-005C          ; Po #       REVERSE SOLIDUS
-00A1          ; Po #       INVERTED EXCLAMATION MARK
-00B7          ; Po #       MIDDLE DOT
-00BF          ; Po #       INVERTED QUESTION MARK
-037E          ; Po #       GREEK QUESTION MARK
-0387          ; Po #       GREEK ANO TELEIA
-055A..055F    ; Po #   [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK
-0589          ; Po #       ARMENIAN FULL STOP
-05C0          ; Po #       HEBREW PUNCTUATION PASEQ
-05C3          ; Po #       HEBREW PUNCTUATION SOF PASUQ
-05C6          ; Po #       HEBREW PUNCTUATION NUN HAFUKHA
-05F3..05F4    ; Po #   [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM
-0609..060A    ; Po #   [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN
-060C..060D    ; Po #   [2] ARABIC COMMA..ARABIC DATE SEPARATOR
-061B          ; Po #       ARABIC SEMICOLON
-061E..061F    ; Po #   [2] ARABIC TRIPLE DOT PUNCTUATION MARK..ARABIC QUESTION MARK
-066A..066D    ; Po #   [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR
-06D4          ; Po #       ARABIC FULL STOP
-0700..070D    ; Po #  [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS
-07F7..07F9    ; Po #   [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK
-0964..0965    ; Po #   [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA
-0970          ; Po #       DEVANAGARI ABBREVIATION SIGN
-0DF4          ; Po #       SINHALA PUNCTUATION KUNDDALIYA
-0E4F          ; Po #       THAI CHARACTER FONGMAN
-0E5A..0E5B    ; Po #   [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT
-0F04..0F12    ; Po #  [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD
-0F85          ; Po #       TIBETAN MARK PALUTA
-0FD0..0FD4    ; Po #   [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA
-104A..104F    ; Po #   [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE
-10FB          ; Po #       GEORGIAN PARAGRAPH SEPARATOR
-1361..1368    ; Po #   [8] ETHIOPIC WORDSPACE..ETHIOPIC PARAGRAPH SEPARATOR
-166D..166E    ; Po #   [2] CANADIAN SYLLABICS CHI SIGN..CANADIAN SYLLABICS FULL STOP
-16EB..16ED    ; Po #   [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION
-1735..1736    ; Po #   [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION
-17D4..17D6    ; Po #   [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH
-17D8..17DA    ; Po #   [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT
-1800..1805    ; Po #   [6] MONGOLIAN BIRGA..MONGOLIAN FOUR DOTS
-1807..180A    ; Po #   [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU
-1944..1945    ; Po #   [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK
-19DE..19DF    ; Po #   [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV
-1A1E..1A1F    ; Po #   [2] BUGINESE PALLAWA..BUGINESE END OF SECTION
-1B5A..1B60    ; Po #   [7] BALINESE PANTI..BALINESE PAMENENG
-1C3B..1C3F    ; Po #   [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK
-1C7E..1C7F    ; Po #   [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD
-2016..2017    ; Po #   [2] DOUBLE VERTICAL LINE..DOUBLE LOW LINE
-2020..2027    ; Po #   [8] DAGGER..HYPHENATION POINT
-2030..2038    ; Po #   [9] PER MILLE SIGN..CARET
-203B..203E    ; Po #   [4] REFERENCE MARK..OVERLINE
-2041..2043    ; Po #   [3] CARET INSERTION POINT..HYPHEN BULLET
-2047..2051    ; Po #  [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY
-2053          ; Po #       SWUNG DASH
-2055..205E    ; Po #  [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS
-2CF9..2CFC    ; Po #   [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER
-2CFE..2CFF    ; Po #   [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER
-2E00..2E01    ; Po #   [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
-2E06..2E08    ; Po #   [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER
-2E0B          ; Po #       RAISED SQUARE
-2E0E..2E16    ; Po #   [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE
-2E18..2E19    ; Po #   [2] INVERTED INTERROBANG..PALM BRANCH
-2E1B          ; Po #       TILDE WITH RING ABOVE
-2E1E..2E1F    ; Po #   [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW
-2E2A..2E2E    ; Po #   [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK
-2E30          ; Po #       RING POINT
-3001..3003    ; Po #   [3] IDEOGRAPHIC COMMA..DITTO MARK
-303D          ; Po #       PART ALTERNATION MARK
-30FB          ; Po #       KATAKANA MIDDLE DOT
-A60D..A60F    ; Po #   [3] VAI COMMA..VAI QUESTION MARK
-A673          ; Po #       SLAVONIC ASTERISK
-A67E          ; Po #       CYRILLIC KAVYKA
-A874..A877    ; Po #   [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD
-A8CE..A8CF    ; Po #   [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA
-A92E..A92F    ; Po #   [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA
-A95F          ; Po #       REJANG SECTION MARK
-AA5C..AA5F    ; Po #   [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA
-FE10..FE16    ; Po #   [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK
-FE19          ; Po #       PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
-FE30          ; Po #       PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
-FE45..FE46    ; Po #   [2] SESAME DOT..WHITE SESAME DOT
-FE49..FE4C    ; Po #   [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE
-FE50..FE52    ; Po #   [3] SMALL COMMA..SMALL FULL STOP
-FE54..FE57    ; Po #   [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK
-FE5F..FE61    ; Po #   [3] SMALL NUMBER SIGN..SMALL ASTERISK
-FE68          ; Po #       SMALL REVERSE SOLIDUS
-FE6A..FE6B    ; Po #   [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT
-FF01..FF03    ; Po #   [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN
-FF05..FF07    ; Po #   [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE
-FF0A          ; Po #       FULLWIDTH ASTERISK
-FF0C          ; Po #       FULLWIDTH COMMA
-FF0E..FF0F    ; Po #   [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS
-FF1A..FF1B    ; Po #   [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON
-FF1F..FF20    ; Po #   [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT
-FF3C          ; Po #       FULLWIDTH REVERSE SOLIDUS
-FF61          ; Po #       HALFWIDTH IDEOGRAPHIC FULL STOP
-FF64..FF65    ; Po #   [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT
-10100..10101  ; Po #   [2] AEGEAN WORD SEPARATOR LINE..AEGEAN WORD SEPARATOR DOT
-1039F         ; Po #       UGARITIC WORD DIVIDER
-103D0         ; Po #       OLD PERSIAN WORD DIVIDER
-1091F         ; Po #       PHOENICIAN WORD SEPARATOR
-1093F         ; Po #       LYDIAN TRIANGULAR MARK
-10A50..10A58  ; Po #   [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES
-12470..12473  ; Po #   [4] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON
-
-# Total code points: 315
-
-# ================================================
-
-# General_Category=Math_Symbol
-
-002B          ; Sm #       PLUS SIGN
-003C..003E    ; Sm #   [3] LESS-THAN SIGN..GREATER-THAN SIGN
-007C          ; Sm #       VERTICAL LINE
-007E          ; Sm #       TILDE
-00AC          ; Sm #       NOT SIGN
-00B1          ; Sm #       PLUS-MINUS SIGN
-00D7          ; Sm #       MULTIPLICATION SIGN
-00F7          ; Sm #       DIVISION SIGN
-03F6          ; Sm #       GREEK REVERSED LUNATE EPSILON SYMBOL
-0606..0608    ; Sm #   [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY
-2044          ; Sm #       FRACTION SLASH
-2052          ; Sm #       COMMERCIAL MINUS SIGN
-207A..207C    ; Sm #   [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN
-208A..208C    ; Sm #   [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN
-2140..2144    ; Sm #   [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y
-214B          ; Sm #       TURNED AMPERSAND
-2190..2194    ; Sm #   [5] LEFTWARDS ARROW..LEFT RIGHT ARROW
-219A..219B    ; Sm #   [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE
-21A0          ; Sm #       RIGHTWARDS TWO HEADED ARROW
-21A3          ; Sm #       RIGHTWARDS ARROW WITH TAIL
-21A6          ; Sm #       RIGHTWARDS ARROW FROM BAR
-21AE          ; Sm #       LEFT RIGHT ARROW WITH STROKE
-21CE..21CF    ; Sm #   [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE
-21D2          ; Sm #       RIGHTWARDS DOUBLE ARROW
-21D4          ; Sm #       LEFT RIGHT DOUBLE ARROW
-21F4..22FF    ; Sm # [268] RIGHT ARROW WITH SMALL CIRCLE..Z NOTATION BAG MEMBERSHIP
-2308..230B    ; Sm #   [4] LEFT CEILING..RIGHT FLOOR
-2320..2321    ; Sm #   [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL
-237C          ; Sm #       RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
-239B..23B3    ; Sm #  [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM
-23DC..23E1    ; Sm #   [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET
-25B7          ; Sm #       WHITE RIGHT-POINTING TRIANGLE
-25C1          ; Sm #       WHITE LEFT-POINTING TRIANGLE
-25F8..25FF    ; Sm #   [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE
-266F          ; Sm #       MUSIC SHARP SIGN
-27C0..27C4    ; Sm #   [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET
-27C7..27CA    ; Sm #   [4] OR WITH DOT INSIDE..VERTICAL BAR WITH HORIZONTAL STROKE
-27CC          ; Sm #       LONG DIVISION
-27D0..27E5    ; Sm #  [22] WHITE DIAMOND WITH CENTRED DOT..WHITE SQUARE WITH RIGHTWARDS TICK
-27F0..27FF    ; Sm #  [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW
-2900..2982    ; Sm # [131] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..Z NOTATION TYPE COLON
-2999..29D7    ; Sm #  [63] DOTTED FENCE..BLACK HOURGLASS
-29DC..29FB    ; Sm #  [32] INCOMPLETE INFINITY..TRIPLE PLUS
-29FE..2AFF    ; Sm # [258] TINY..N-ARY WHITE VERTICAL BAR
-2B30..2B44    ; Sm #  [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET
-2B47..2B4C    ; Sm #   [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
-FB29          ; Sm #       HEBREW LETTER ALTERNATIVE PLUS SIGN
-FE62          ; Sm #       SMALL PLUS SIGN
-FE64..FE66    ; Sm #   [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN
-FF0B          ; Sm #       FULLWIDTH PLUS SIGN
-FF1C..FF1E    ; Sm #   [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN
-FF5C          ; Sm #       FULLWIDTH VERTICAL LINE
-FF5E          ; Sm #       FULLWIDTH TILDE
-FFE2          ; Sm #       FULLWIDTH NOT SIGN
-FFE9..FFEC    ; Sm #   [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW
-1D6C1         ; Sm #       MATHEMATICAL BOLD NABLA
-1D6DB         ; Sm #       MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
-1D6FB         ; Sm #       MATHEMATICAL ITALIC NABLA
-1D715         ; Sm #       MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
-1D735         ; Sm #       MATHEMATICAL BOLD ITALIC NABLA
-1D74F         ; Sm #       MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
-1D76F         ; Sm #       MATHEMATICAL SANS-SERIF BOLD NABLA
-1D789         ; Sm #       MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
-1D7A9         ; Sm #       MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
-1D7C3         ; Sm #       MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
-
-# Total code points: 945
-
-# ================================================
-
-# General_Category=Currency_Symbol
-
-0024          ; Sc #       DOLLAR SIGN
-00A2..00A5    ; Sc #   [4] CENT SIGN..YEN SIGN
-060B          ; Sc #       AFGHANI SIGN
-09F2..09F3    ; Sc #   [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN
-0AF1          ; Sc #       GUJARATI RUPEE SIGN
-0BF9          ; Sc #       TAMIL RUPEE SIGN
-0E3F          ; Sc #       THAI CURRENCY SYMBOL BAHT
-17DB          ; Sc #       KHMER CURRENCY SYMBOL RIEL
-20A0..20B5    ; Sc #  [22] EURO-CURRENCY SIGN..CEDI SIGN
-FDFC          ; Sc #       RIAL SIGN
-FE69          ; Sc #       SMALL DOLLAR SIGN
-FF04          ; Sc #       FULLWIDTH DOLLAR SIGN
-FFE0..FFE1    ; Sc #   [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN
-FFE5..FFE6    ; Sc #   [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN
-
-# Total code points: 41
-
-# ================================================
-
-# General_Category=Modifier_Symbol
-
-005E          ; Sk #       CIRCUMFLEX ACCENT
-0060          ; Sk #       GRAVE ACCENT
-00A8          ; Sk #       DIAERESIS
-00AF          ; Sk #       MACRON
-00B4          ; Sk #       ACUTE ACCENT
-00B8          ; Sk #       CEDILLA
-02C2..02C5    ; Sk #   [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD
-02D2..02DF    ; Sk #  [14] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER CROSS ACCENT
-02E5..02EB    ; Sk #   [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK
-02ED          ; Sk #       MODIFIER LETTER UNASPIRATED
-02EF..02FF    ; Sk #  [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW
-0375          ; Sk #       GREEK LOWER NUMERAL SIGN
-0384..0385    ; Sk #   [2] GREEK TONOS..GREEK DIALYTIKA TONOS
-1FBD          ; Sk #       GREEK KORONIS
-1FBF..1FC1    ; Sk #   [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI
-1FCD..1FCF    ; Sk #   [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI
-1FDD..1FDF    ; Sk #   [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI
-1FED..1FEF    ; Sk #   [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA
-1FFD..1FFE    ; Sk #   [2] GREEK OXIA..GREEK DASIA
-309B..309C    ; Sk #   [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
-A700..A716    ; Sk #  [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR
-A720..A721    ; Sk #   [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE
-A789..A78A    ; Sk #   [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN
-FF3E          ; Sk #       FULLWIDTH CIRCUMFLEX ACCENT
-FF40          ; Sk #       FULLWIDTH GRAVE ACCENT
-FFE3          ; Sk #       FULLWIDTH MACRON
-
-# Total code points: 99
-
-# ================================================
-
-# General_Category=Other_Symbol
-
-00A6..00A7    ; So #   [2] BROKEN BAR..SECTION SIGN
-00A9          ; So #       COPYRIGHT SIGN
-00AE          ; So #       REGISTERED SIGN
-00B0          ; So #       DEGREE SIGN
-00B6          ; So #       PILCROW SIGN
-0482          ; So #       CYRILLIC THOUSANDS SIGN
-060E..060F    ; So #   [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA
-06E9          ; So #       ARABIC PLACE OF SAJDAH
-06FD..06FE    ; So #   [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN
-07F6          ; So #       NKO SYMBOL OO DENNEN
-09FA          ; So #       BENGALI ISSHAR
-0B70          ; So #       ORIYA ISSHAR
-0BF3..0BF8    ; So #   [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN
-0BFA          ; So #       TAMIL NUMBER SIGN
-0C7F          ; So #       TELUGU SIGN TUUMU
-0CF1..0CF2    ; So #   [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
-0D79          ; So #       MALAYALAM DATE MARK
-0F01..0F03    ; So #   [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA
-0F13..0F17    ; So #   [5] TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS
-0F1A..0F1F    ; So #   [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG
-0F34          ; So #       TIBETAN MARK BSDUS RTAGS
-0F36          ; So #       TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN
-0F38          ; So #       TIBETAN MARK CHE MGO
-0FBE..0FC5    ; So #   [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE
-0FC7..0FCC    ; So #   [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL
-0FCE..0FCF    ; So #   [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM
-109E..109F    ; So #   [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION
-1360          ; So #       ETHIOPIC SECTION MARK
-1390..1399    ; So #  [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT
-1940          ; So #       LIMBU SIGN LOO
-19E0..19FF    ; So #  [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC
-1B61..1B6A    ; So #  [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE
-1B74..1B7C    ; So #   [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING
-2100..2101    ; So #   [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT
-2103..2106    ; So #   [4] DEGREE CELSIUS..CADA UNA
-2108..2109    ; So #   [2] SCRUPLE..DEGREE FAHRENHEIT
-2114          ; So #       L B BAR SYMBOL
-2116..2118    ; So #   [3] NUMERO SIGN..SCRIPT CAPITAL P
-211E..2123    ; So #   [6] PRESCRIPTION TAKE..VERSICLE
-2125          ; So #       OUNCE SIGN
-2127          ; So #       INVERTED OHM SIGN
-2129          ; So #       TURNED GREEK SMALL LETTER IOTA
-212E          ; So #       ESTIMATED SYMBOL
-213A..213B    ; So #   [2] ROTATED CAPITAL Q..FACSIMILE SIGN
-214A          ; So #       PROPERTY LINE
-214C..214D    ; So #   [2] PER SIGN..AKTIESELSKAB
-214F          ; So #       SYMBOL FOR SAMARITAN SOURCE
-2195..2199    ; So #   [5] UP DOWN ARROW..SOUTH WEST ARROW
-219C..219F    ; So #   [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW
-21A1..21A2    ; So #   [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL
-21A4..21A5    ; So #   [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR
-21A7..21AD    ; So #   [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW
-21AF..21CD    ; So #  [31] DOWNWARDS ZIGZAG ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE
-21D0..21D1    ; So #   [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW
-21D3          ; So #       DOWNWARDS DOUBLE ARROW
-21D5..21F3    ; So #  [31] UP DOWN DOUBLE ARROW..UP DOWN WHITE ARROW
-2300..2307    ; So #   [8] DIAMETER SIGN..WAVY LINE
-230C..231F    ; So #  [20] BOTTOM RIGHT CROP..BOTTOM RIGHT CORNER
-2322..2328    ; So #   [7] FROWN..KEYBOARD
-232B..237B    ; So #  [81] ERASE TO THE LEFT..NOT CHECK MARK
-237D..239A    ; So #  [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL
-23B4..23DB    ; So #  [40] TOP SQUARE BRACKET..FUSE
-23E2..23E7    ; So #   [6] WHITE TRAPEZIUM..ELECTRICAL INTERSECTION
-2400..2426    ; So #  [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO
-2440..244A    ; So #  [11] OCR HOOK..OCR DOUBLE BACKSLASH
-249C..24E9    ; So #  [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z
-2500..25B6    ; So # [183] BOX DRAWINGS LIGHT HORIZONTAL..BLACK RIGHT-POINTING TRIANGLE
-25B8..25C0    ; So #   [9] BLACK RIGHT-POINTING SMALL TRIANGLE..BLACK LEFT-POINTING TRIANGLE
-25C2..25F7    ; So #  [54] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE CIRCLE WITH UPPER RIGHT QUADRANT
-2600..266E    ; So # [111] BLACK SUN WITH RAYS..MUSIC NATURAL SIGN
-2670..269D    ; So #  [46] WEST SYRIAC CROSS..OUTLINED WHITE STAR
-26A0..26BC    ; So #  [29] WARNING SIGN..SESQUIQUADRATE
-26C0..26C3    ; So #   [4] WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING
-2701..2704    ; So #   [4] UPPER BLADE SCISSORS..WHITE SCISSORS
-2706..2709    ; So #   [4] TELEPHONE LOCATION SIGN..ENVELOPE
-270C..2727    ; So #  [28] VICTORY HAND..WHITE FOUR POINTED STAR
-2729..274B    ; So #  [35] STRESS OUTLINED WHITE STAR..HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
-274D          ; So #       SHADOWED WHITE CIRCLE
-274F..2752    ; So #   [4] LOWER RIGHT DROP-SHADOWED WHITE SQUARE..UPPER RIGHT SHADOWED WHITE SQUARE
-2756          ; So #       BLACK DIAMOND MINUS WHITE X
-2758..275E    ; So #   [7] LIGHT VERTICAL BAR..HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT
-2761..2767    ; So #   [7] CURVED STEM PARAGRAPH SIGN ORNAMENT..ROTATED FLORAL HEART BULLET
-2794          ; So #       HEAVY WIDE-HEADED RIGHTWARDS ARROW
-2798..27AF    ; So #  [24] HEAVY SOUTH EAST ARROW..NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
-27B1..27BE    ; So #  [14] NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW..OPEN-OUTLINED RIGHTWARDS ARROW
-2800..28FF    ; So # [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678
-2B00..2B2F    ; So #  [48] NORTH EAST WHITE ARROW..WHITE VERTICAL ELLIPSE
-2B45..2B46    ; So #   [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW
-2B50..2B54    ; So #   [5] WHITE MEDIUM STAR..WHITE RIGHT-POINTING PENTAGON
-2CE5..2CEA    ; So #   [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA
-2E80..2E99    ; So #  [26] CJK RADICAL REPEAT..CJK RADICAL RAP
-2E9B..2EF3    ; So #  [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE
-2F00..2FD5    ; So # [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE
-2FF0..2FFB    ; So #  [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
-3004          ; So #       JAPANESE INDUSTRIAL STANDARD SYMBOL
-3012..3013    ; So #   [2] POSTAL MARK..GETA MARK
-3020          ; So #       POSTAL MARK FACE
-3036..3037    ; So #   [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL
-303E..303F    ; So #   [2] IDEOGRAPHIC VARIATION INDICATOR..IDEOGRAPHIC HALF FILL SPACE
-3190..3191    ; So #   [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK
-3196..319F    ; So #  [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK
-31C0..31E3    ; So #  [36] CJK STROKE T..CJK STROKE Q
-3200..321E    ; So #  [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU
-322A..3243    ; So #  [26] PARENTHESIZED IDEOGRAPH MOON..PARENTHESIZED IDEOGRAPH REACH
-3250          ; So #       PARTNERSHIP SIGN
-3260..327F    ; So #  [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL
-328A..32B0    ; So #  [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT
-32C0..32FE    ; So #  [63] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..CIRCLED KATAKANA WO
-3300..33FF    ; So # [256] SQUARE APAATO..SQUARE GAL
-4DC0..4DFF    ; So #  [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION
-A490..A4C6    ; So #  [55] YI RADICAL QOT..YI RADICAL KE
-A828..A82B    ; So #   [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4
-FDFD          ; So #       ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM
-FFE4          ; So #       FULLWIDTH BROKEN BAR
-FFE8          ; So #       HALFWIDTH FORMS LIGHT VERTICAL
-FFED..FFEE    ; So #   [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE
-FFFC..FFFD    ; So #   [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHARACTER
-10102         ; So #       AEGEAN CHECK MARK
-10137..1013F  ; So #   [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT
-10179..10189  ; So #  [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN
-10190..1019B  ; So #  [12] ROMAN SEXTANS SIGN..ROMAN CENTURIAL SIGN
-101D0..101FC  ; So #  [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND
-1D000..1D0F5  ; So # [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO
-1D100..1D126  ; So #  [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2
-1D129..1D164  ; So #  [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
-1D16A..1D16C  ; So #   [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3
-1D183..1D184  ; So #   [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN
-1D18C..1D1A9  ; So #  [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH
-1D1AE..1D1DD  ; So #  [48] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL PES SUBPUNCTIS
-1D200..1D241  ; So #  [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54
-1D245         ; So #       GREEK MUSICAL LEIMMA
-1D300..1D356  ; So #  [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
-1F000..1F02B  ; So #  [44] MAHJONG TILE EAST WIND..MAHJONG TILE BACK
-1F030..1F093  ; So # [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06
-
-# Total code points: 3225
-
-# ================================================
-
-# General_Category=Initial_Punctuation
-
-00AB          ; Pi #       LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
-2018          ; Pi #       LEFT SINGLE QUOTATION MARK
-201B..201C    ; Pi #   [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK
-201F          ; Pi #       DOUBLE HIGH-REVERSED-9 QUOTATION MARK
-2039          ; Pi #       SINGLE LEFT-POINTING ANGLE QUOTATION MARK
-2E02          ; Pi #       LEFT SUBSTITUTION BRACKET
-2E04          ; Pi #       LEFT DOTTED SUBSTITUTION BRACKET
-2E09          ; Pi #       LEFT TRANSPOSITION BRACKET
-2E0C          ; Pi #       LEFT RAISED OMISSION BRACKET
-2E1C          ; Pi #       LEFT LOW PARAPHRASE BRACKET
-2E20          ; Pi #       LEFT VERTICAL BAR WITH QUILL
-
-# Total code points: 12
-
-# ================================================
-
-# General_Category=Final_Punctuation
-
-00BB          ; Pf #       RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-2019          ; Pf #       RIGHT SINGLE QUOTATION MARK
-201D          ; Pf #       RIGHT DOUBLE QUOTATION MARK
-203A          ; Pf #       SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
-2E03          ; Pf #       RIGHT SUBSTITUTION BRACKET
-2E05          ; Pf #       RIGHT DOTTED SUBSTITUTION BRACKET
-2E0A          ; Pf #       RIGHT TRANSPOSITION BRACKET
-2E0D          ; Pf #       RIGHT RAISED OMISSION BRACKET
-2E1D          ; Pf #       RIGHT LOW PARAPHRASE BRACKET
-2E21          ; Pf #       RIGHT VERTICAL BAR WITH QUILL
-
-# Total code points: 10
-
-# EOF
diff --git a/third_party/harfbuzz/contrib/tables/GraphemeBreakProperty.txt b/third_party/harfbuzz/contrib/tables/GraphemeBreakProperty.txt
deleted file mode 100644
index 50477a1..0000000
--- a/third_party/harfbuzz/contrib/tables/GraphemeBreakProperty.txt
+++ /dev/null
@@ -1,1166 +0,0 @@
-# GraphemeBreakProperty-5.1.0.txt
-# Date: 2008-03-03, 21:57:47 GMT [MD]
-#
-# Unicode Character Database
-# Copyright (c) 1991-2008 Unicode, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-# For documentation, see UCD.html
-
-# ================================================
-
-# Property:	Grapheme_Cluster_Break
-
-#  All code points not explicitly listed for Grapheme_Cluster_Break
-#  have the value Other (XX).
-
-# @missing: 0000..10FFFF; Other
-
-# ================================================
-
-000D          ; CR # Cc       <control-000D>
-
-# Total code points: 1
-
-# ================================================
-
-000A          ; LF # Cc       <control-000A>
-
-# Total code points: 1
-
-# ================================================
-
-0000..0009    ; Control # Cc  [10] <control-0000>..<control-0009>
-000B..000C    ; Control # Cc   [2] <control-000B>..<control-000C>
-000E..001F    ; Control # Cc  [18] <control-000E>..<control-001F>
-007F..009F    ; Control # Cc  [33] <control-007F>..<control-009F>
-00AD          ; Control # Cf       SOFT HYPHEN
-0600..0603    ; Control # Cf   [4] ARABIC NUMBER SIGN..ARABIC SIGN SAFHA
-06DD          ; Control # Cf       ARABIC END OF AYAH
-070F          ; Control # Cf       SYRIAC ABBREVIATION MARK
-17B4..17B5    ; Control # Cf   [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
-200B          ; Control # Cf       ZERO WIDTH SPACE
-200E..200F    ; Control # Cf   [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
-2028          ; Control # Zl       LINE SEPARATOR
-2029          ; Control # Zp       PARAGRAPH SEPARATOR
-202A..202E    ; Control # Cf   [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
-2060..2064    ; Control # Cf   [5] WORD JOINER..INVISIBLE PLUS
-206A..206F    ; Control # Cf   [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
-FEFF          ; Control # Cf       ZERO WIDTH NO-BREAK SPACE
-FFF9..FFFB    ; Control # Cf   [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
-1D173..1D17A  ; Control # Cf   [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
-E0001         ; Control # Cf       LANGUAGE TAG
-E0020..E007F  ; Control # Cf  [96] TAG SPACE..CANCEL TAG
-
-# Total code points: 202
-
-# ================================================
-
-0300..036F    ; Extend # Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X
-0483..0487    ; Extend # Mn   [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
-0488..0489    ; Extend # Me   [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
-0591..05BD    ; Extend # Mn  [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
-05BF          ; Extend # Mn       HEBREW POINT RAFE
-05C1..05C2    ; Extend # Mn   [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
-05C4..05C5    ; Extend # Mn   [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
-05C7          ; Extend # Mn       HEBREW POINT QAMATS QATAN
-0610..061A    ; Extend # Mn  [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
-064B..065E    ; Extend # Mn  [20] ARABIC FATHATAN..ARABIC FATHA WITH TWO DOTS
-0670          ; Extend # Mn       ARABIC LETTER SUPERSCRIPT ALEF
-06D6..06DC    ; Extend # Mn   [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
-06DE          ; Extend # Me       ARABIC START OF RUB EL HIZB
-06DF..06E4    ; Extend # Mn   [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
-06E7..06E8    ; Extend # Mn   [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
-06EA..06ED    ; Extend # Mn   [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
-0711          ; Extend # Mn       SYRIAC LETTER SUPERSCRIPT ALAPH
-0730..074A    ; Extend # Mn  [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
-07A6..07B0    ; Extend # Mn  [11] THAANA ABAFILI..THAANA SUKUN
-07EB..07F3    ; Extend # Mn   [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
-0901..0902    ; Extend # Mn   [2] DEVANAGARI SIGN CANDRABINDU..DEVANAGARI SIGN ANUSVARA
-093C          ; Extend # Mn       DEVANAGARI SIGN NUKTA
-0941..0948    ; Extend # Mn   [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
-094D          ; Extend # Mn       DEVANAGARI SIGN VIRAMA
-0951..0954    ; Extend # Mn   [4] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI ACUTE ACCENT
-0962..0963    ; Extend # Mn   [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
-0981          ; Extend # Mn       BENGALI SIGN CANDRABINDU
-09BC          ; Extend # Mn       BENGALI SIGN NUKTA
-09BE          ; Extend # Mc       BENGALI VOWEL SIGN AA
-09C1..09C4    ; Extend # Mn   [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
-09CD          ; Extend # Mn       BENGALI SIGN VIRAMA
-09D7          ; Extend # Mc       BENGALI AU LENGTH MARK
-09E2..09E3    ; Extend # Mn   [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
-0A01..0A02    ; Extend # Mn   [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
-0A3C          ; Extend # Mn       GURMUKHI SIGN NUKTA
-0A41..0A42    ; Extend # Mn   [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
-0A47..0A48    ; Extend # Mn   [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
-0A4B..0A4D    ; Extend # Mn   [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
-0A51          ; Extend # Mn       GURMUKHI SIGN UDAAT
-0A70..0A71    ; Extend # Mn   [2] GURMUKHI TIPPI..GURMUKHI ADDAK
-0A75          ; Extend # Mn       GURMUKHI SIGN YAKASH
-0A81..0A82    ; Extend # Mn   [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
-0ABC          ; Extend # Mn       GUJARATI SIGN NUKTA
-0AC1..0AC5    ; Extend # Mn   [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
-0AC7..0AC8    ; Extend # Mn   [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
-0ACD          ; Extend # Mn       GUJARATI SIGN VIRAMA
-0AE2..0AE3    ; Extend # Mn   [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
-0B01          ; Extend # Mn       ORIYA SIGN CANDRABINDU
-0B3C          ; Extend # Mn       ORIYA SIGN NUKTA
-0B3E          ; Extend # Mc       ORIYA VOWEL SIGN AA
-0B3F          ; Extend # Mn       ORIYA VOWEL SIGN I
-0B41..0B44    ; Extend # Mn   [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
-0B4D          ; Extend # Mn       ORIYA SIGN VIRAMA
-0B56          ; Extend # Mn       ORIYA AI LENGTH MARK
-0B57          ; Extend # Mc       ORIYA AU LENGTH MARK
-0B62..0B63    ; Extend # Mn   [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
-0B82          ; Extend # Mn       TAMIL SIGN ANUSVARA
-0BBE          ; Extend # Mc       TAMIL VOWEL SIGN AA
-0BC0          ; Extend # Mn       TAMIL VOWEL SIGN II
-0BCD          ; Extend # Mn       TAMIL SIGN VIRAMA
-0BD7          ; Extend # Mc       TAMIL AU LENGTH MARK
-0C3E..0C40    ; Extend # Mn   [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
-0C46..0C48    ; Extend # Mn   [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
-0C4A..0C4D    ; Extend # Mn   [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
-0C55..0C56    ; Extend # Mn   [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
-0C62..0C63    ; Extend # Mn   [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
-0CBC          ; Extend # Mn       KANNADA SIGN NUKTA
-0CBF          ; Extend # Mn       KANNADA VOWEL SIGN I
-0CC2          ; Extend # Mc       KANNADA VOWEL SIGN UU
-0CC6          ; Extend # Mn       KANNADA VOWEL SIGN E
-0CCC..0CCD    ; Extend # Mn   [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA
-0CD5..0CD6    ; Extend # Mc   [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
-0CE2..0CE3    ; Extend # Mn   [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
-0D3E          ; Extend # Mc       MALAYALAM VOWEL SIGN AA
-0D41..0D44    ; Extend # Mn   [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
-0D4D          ; Extend # Mn       MALAYALAM SIGN VIRAMA
-0D57          ; Extend # Mc       MALAYALAM AU LENGTH MARK
-0D62..0D63    ; Extend # Mn   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
-0DCA          ; Extend # Mn       SINHALA SIGN AL-LAKUNA
-0DCF          ; Extend # Mc       SINHALA VOWEL SIGN AELA-PILLA
-0DD2..0DD4    ; Extend # Mn   [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
-0DD6          ; Extend # Mn       SINHALA VOWEL SIGN DIGA PAA-PILLA
-0DDF          ; Extend # Mc       SINHALA VOWEL SIGN GAYANUKITTA
-0E30          ; Extend # Lo       THAI CHARACTER SARA A
-0E31          ; Extend # Mn       THAI CHARACTER MAI HAN-AKAT
-0E32..0E33    ; Extend # Lo   [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM
-0E34..0E3A    ; Extend # Mn   [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
-0E45          ; Extend # Lo       THAI CHARACTER LAKKHANGYAO
-0E47..0E4E    ; Extend # Mn   [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
-0EB0          ; Extend # Lo       LAO VOWEL SIGN A
-0EB1          ; Extend # Mn       LAO VOWEL SIGN MAI KAN
-0EB2..0EB3    ; Extend # Lo   [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM
-0EB4..0EB9    ; Extend # Mn   [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU
-0EBB..0EBC    ; Extend # Mn   [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO
-0EC8..0ECD    ; Extend # Mn   [6] LAO TONE MAI EK..LAO NIGGAHITA
-0F18..0F19    ; Extend # Mn   [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
-0F35          ; Extend # Mn       TIBETAN MARK NGAS BZUNG NYI ZLA
-0F37          ; Extend # Mn       TIBETAN MARK NGAS BZUNG SGOR RTAGS
-0F39          ; Extend # Mn       TIBETAN MARK TSA -PHRU
-0F71..0F7E    ; Extend # Mn  [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
-0F80..0F84    ; Extend # Mn   [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA
-0F86..0F87    ; Extend # Mn   [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
-0F90..0F97    ; Extend # Mn   [8] TIBETAN SUBJOINED LETTER KA..TIBETAN SUBJOINED LETTER JA
-0F99..0FBC    ; Extend # Mn  [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
-0FC6          ; Extend # Mn       TIBETAN SYMBOL PADMA GDAN
-102D..1030    ; Extend # Mn   [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
-1032..1037    ; Extend # Mn   [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW
-1039..103A    ; Extend # Mn   [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
-103D..103E    ; Extend # Mn   [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
-1058..1059    ; Extend # Mn   [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
-105E..1060    ; Extend # Mn   [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
-1071..1074    ; Extend # Mn   [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
-1082          ; Extend # Mn       MYANMAR CONSONANT SIGN SHAN MEDIAL WA
-1085..1086    ; Extend # Mn   [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
-108D          ; Extend # Mn       MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
-135F          ; Extend # Mn       ETHIOPIC COMBINING GEMINATION MARK
-1712..1714    ; Extend # Mn   [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA
-1732..1734    ; Extend # Mn   [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD
-1752..1753    ; Extend # Mn   [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
-1772..1773    ; Extend # Mn   [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
-17B7..17BD    ; Extend # Mn   [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
-17C6          ; Extend # Mn       KHMER SIGN NIKAHIT
-17C9..17D3    ; Extend # Mn  [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
-17DD          ; Extend # Mn       KHMER SIGN ATTHACAN
-180B..180D    ; Extend # Mn   [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
-18A9          ; Extend # Mn       MONGOLIAN LETTER ALI GALI DAGALGA
-1920..1922    ; Extend # Mn   [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
-1927..1928    ; Extend # Mn   [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
-1932          ; Extend # Mn       LIMBU SMALL LETTER ANUSVARA
-1939..193B    ; Extend # Mn   [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
-1A17..1A18    ; Extend # Mn   [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
-1B00..1B03    ; Extend # Mn   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
-1B34          ; Extend # Mn       BALINESE SIGN REREKAN
-1B36..1B3A    ; Extend # Mn   [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
-1B3C          ; Extend # Mn       BALINESE VOWEL SIGN LA LENGA
-1B42          ; Extend # Mn       BALINESE VOWEL SIGN PEPET
-1B6B..1B73    ; Extend # Mn   [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
-1B80..1B81    ; Extend # Mn   [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
-1BA2..1BA5    ; Extend # Mn   [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
-1BA8..1BA9    ; Extend # Mn   [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
-1C2C..1C33    ; Extend # Mn   [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
-1C36..1C37    ; Extend # Mn   [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
-1DC0..1DE6    ; Extend # Mn  [39] COMBINING DOTTED GRAVE ACCENT..COMBINING LATIN SMALL LETTER Z
-1DFE..1DFF    ; Extend # Mn   [2] COMBINING LEFT ARROWHEAD ABOVE..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
-200C..200D    ; Extend # Cf   [2] ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER
-20D0..20DC    ; Extend # Mn  [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
-20DD..20E0    ; Extend # Me   [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
-20E1          ; Extend # Mn       COMBINING LEFT RIGHT ARROW ABOVE
-20E2..20E4    ; Extend # Me   [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
-20E5..20F0    ; Extend # Mn  [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE
-2DE0..2DFF    ; Extend # Mn  [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
-302A..302F    ; Extend # Mn   [6] IDEOGRAPHIC LEVEL TONE MARK..HANGUL DOUBLE DOT TONE MARK
-3099..309A    ; Extend # Mn   [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
-A66F          ; Extend # Mn       COMBINING CYRILLIC VZMET
-A670..A672    ; Extend # Me   [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
-A67C..A67D    ; Extend # Mn   [2] COMBINING CYRILLIC KAVYKA..COMBINING CYRILLIC PAYEROK
-A802          ; Extend # Mn       SYLOTI NAGRI SIGN DVISVARA
-A806          ; Extend # Mn       SYLOTI NAGRI SIGN HASANTA
-A80B          ; Extend # Mn       SYLOTI NAGRI SIGN ANUSVARA
-A825..A826    ; Extend # Mn   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
-A8C4          ; Extend # Mn       SAURASHTRA SIGN VIRAMA
-A926..A92D    ; Extend # Mn   [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU
-A947..A951    ; Extend # Mn  [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
-AA29..AA2E    ; Extend # Mn   [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
-AA31..AA32    ; Extend # Mn   [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
-AA35..AA36    ; Extend # Mn   [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
-AA43          ; Extend # Mn       CHAM CONSONANT SIGN FINAL NG
-AA4C          ; Extend # Mn       CHAM CONSONANT SIGN FINAL M
-FB1E          ; Extend # Mn       HEBREW POINT JUDEO-SPANISH VARIKA
-FE00..FE0F    ; Extend # Mn  [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
-FE20..FE26    ; Extend # Mn   [7] COMBINING LIGATURE LEFT HALF..COMBINING CONJOINING MACRON
-FF9E..FF9F    ; Extend # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
-101FD         ; Extend # Mn       PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
-10A01..10A03  ; Extend # Mn   [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
-10A05..10A06  ; Extend # Mn   [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
-10A0C..10A0F  ; Extend # Mn   [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
-10A38..10A3A  ; Extend # Mn   [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW
-10A3F         ; Extend # Mn       KHAROSHTHI VIRAMA
-1D165         ; Extend # Mc       MUSICAL SYMBOL COMBINING STEM
-1D167..1D169  ; Extend # Mn   [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
-1D16E..1D172  ; Extend # Mc   [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5
-1D17B..1D182  ; Extend # Mn   [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
-1D185..1D18B  ; Extend # Mn   [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
-1D1AA..1D1AD  ; Extend # Mn   [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
-1D242..1D244  ; Extend # Mn   [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
-E0100..E01EF  ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
-
-# Total code points: 1075
-
-# ================================================
-
-0E40..0E44    ; Prepend # Lo   [5] THAI CHARACTER SARA E..THAI CHARACTER SARA AI MAIMALAI
-0EC0..0EC4    ; Prepend # Lo   [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
-
-# Total code points: 10
-
-# ================================================
-
-0903          ; SpacingMark # Mc       DEVANAGARI SIGN VISARGA
-093E..0940    ; SpacingMark # Mc   [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
-0949..094C    ; SpacingMark # Mc   [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
-0982..0983    ; SpacingMark # Mc   [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
-09BF..09C0    ; SpacingMark # Mc   [2] BENGALI VOWEL SIGN I..BENGALI VOWEL SIGN II
-09C7..09C8    ; SpacingMark # Mc   [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
-09CB..09CC    ; SpacingMark # Mc   [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
-0A03          ; SpacingMark # Mc       GURMUKHI SIGN VISARGA
-0A3E..0A40    ; SpacingMark # Mc   [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
-0A83          ; SpacingMark # Mc       GUJARATI SIGN VISARGA
-0ABE..0AC0    ; SpacingMark # Mc   [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
-0AC9          ; SpacingMark # Mc       GUJARATI VOWEL SIGN CANDRA O
-0ACB..0ACC    ; SpacingMark # Mc   [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
-0B02..0B03    ; SpacingMark # Mc   [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
-0B40          ; SpacingMark # Mc       ORIYA VOWEL SIGN II
-0B47..0B48    ; SpacingMark # Mc   [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
-0B4B..0B4C    ; SpacingMark # Mc   [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
-0BBF          ; SpacingMark # Mc       TAMIL VOWEL SIGN I
-0BC1..0BC2    ; SpacingMark # Mc   [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
-0BC6..0BC8    ; SpacingMark # Mc   [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
-0BCA..0BCC    ; SpacingMark # Mc   [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
-0C01..0C03    ; SpacingMark # Mc   [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
-0C41..0C44    ; SpacingMark # Mc   [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
-0C82..0C83    ; SpacingMark # Mc   [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
-0CBE          ; SpacingMark # Mc       KANNADA VOWEL SIGN AA
-0CC0..0CC1    ; SpacingMark # Mc   [2] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN U
-0CC3..0CC4    ; SpacingMark # Mc   [2] KANNADA VOWEL SIGN VOCALIC R..KANNADA VOWEL SIGN VOCALIC RR
-0CC7..0CC8    ; SpacingMark # Mc   [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
-0CCA..0CCB    ; SpacingMark # Mc   [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
-0D02..0D03    ; SpacingMark # Mc   [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
-0D3F..0D40    ; SpacingMark # Mc   [2] MALAYALAM VOWEL SIGN I..MALAYALAM VOWEL SIGN II
-0D46..0D48    ; SpacingMark # Mc   [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
-0D4A..0D4C    ; SpacingMark # Mc   [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
-0D82..0D83    ; SpacingMark # Mc   [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
-0DD0..0DD1    ; SpacingMark # Mc   [2] SINHALA VOWEL SIGN KETTI AEDA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
-0DD8..0DDE    ; SpacingMark # Mc   [7] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA
-0DF2..0DF3    ; SpacingMark # Mc   [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
-0F3E..0F3F    ; SpacingMark # Mc   [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
-0F7F          ; SpacingMark # Mc       TIBETAN SIGN RNAM BCAD
-102B..102C    ; SpacingMark # Mc   [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA
-1031          ; SpacingMark # Mc       MYANMAR VOWEL SIGN E
-1038          ; SpacingMark # Mc       MYANMAR SIGN VISARGA
-103B..103C    ; SpacingMark # Mc   [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
-1056..1057    ; SpacingMark # Mc   [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
-1062..1064    ; SpacingMark # Mc   [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO
-1067..106D    ; SpacingMark # Mc   [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5
-1083..1084    ; SpacingMark # Mc   [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E
-1087..108C    ; SpacingMark # Mc   [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3
-108F          ; SpacingMark # Mc       MYANMAR SIGN RUMAI PALAUNG TONE-5
-17B6          ; SpacingMark # Mc       KHMER VOWEL SIGN AA
-17BE..17C5    ; SpacingMark # Mc   [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
-17C7..17C8    ; SpacingMark # Mc   [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
-1923..1926    ; SpacingMark # Mc   [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
-1929..192B    ; SpacingMark # Mc   [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
-1930..1931    ; SpacingMark # Mc   [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
-1933..1938    ; SpacingMark # Mc   [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
-19B0..19C0    ; SpacingMark # Mc  [17] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE VOWEL SIGN IY
-19C8..19C9    ; SpacingMark # Mc   [2] NEW TAI LUE TONE MARK-1..NEW TAI LUE TONE MARK-2
-1A19..1A1B    ; SpacingMark # Mc   [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE
-1B04          ; SpacingMark # Mc       BALINESE SIGN BISAH
-1B35          ; SpacingMark # Mc       BALINESE VOWEL SIGN TEDUNG
-1B3B          ; SpacingMark # Mc       BALINESE VOWEL SIGN RA REPA TEDUNG
-1B3D..1B41    ; SpacingMark # Mc   [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
-1B43..1B44    ; SpacingMark # Mc   [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG
-1B82          ; SpacingMark # Mc       SUNDANESE SIGN PANGWISAD
-1BA1          ; SpacingMark # Mc       SUNDANESE CONSONANT SIGN PAMINGKAL
-1BA6..1BA7    ; SpacingMark # Mc   [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
-1BAA          ; SpacingMark # Mc       SUNDANESE SIGN PAMAAEH
-1C24..1C2B    ; SpacingMark # Mc   [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
-1C34..1C35    ; SpacingMark # Mc   [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
-A823..A824    ; SpacingMark # Mc   [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
-A827          ; SpacingMark # Mc       SYLOTI NAGRI VOWEL SIGN OO
-A880..A881    ; SpacingMark # Mc   [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
-A8B4..A8C3    ; SpacingMark # Mc  [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
-A952..A953    ; SpacingMark # Mc   [2] REJANG CONSONANT SIGN H..REJANG VIRAMA
-AA2F..AA30    ; SpacingMark # Mc   [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
-AA33..AA34    ; SpacingMark # Mc   [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
-AA4D          ; SpacingMark # Mc       CHAM CONSONANT SIGN FINAL H
-1D166         ; SpacingMark # Mc       MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
-1D16D         ; SpacingMark # Mc       MUSICAL SYMBOL COMBINING AUGMENTATION DOT
-
-# Total code points: 217
-
-# ================================================
-
-1100..1159    ; L # Lo  [90] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG YEORINHIEUH
-115F          ; L # Lo       HANGUL CHOSEONG FILLER
-
-# Total code points: 91
-
-# ================================================
-
-1160..11A2    ; V # Lo  [67] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG SSANGARAEA
-
-# Total code points: 67
-
-# ================================================
-
-11A8..11F9    ; T # Lo  [82] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG YEORINHIEUH
-
-# Total code points: 82
-
-# ================================================
-
-AC00          ; LV # Lo       HANGUL SYLLABLE GA
-AC1C          ; LV # Lo       HANGUL SYLLABLE GAE
-AC38          ; LV # Lo       HANGUL SYLLABLE GYA
-AC54          ; LV # Lo       HANGUL SYLLABLE GYAE
-AC70          ; LV # Lo       HANGUL SYLLABLE GEO
-AC8C          ; LV # Lo       HANGUL SYLLABLE GE
-ACA8          ; LV # Lo       HANGUL SYLLABLE GYEO
-ACC4          ; LV # Lo       HANGUL SYLLABLE GYE
-ACE0          ; LV # Lo       HANGUL SYLLABLE GO
-ACFC          ; LV # Lo       HANGUL SYLLABLE GWA
-AD18          ; LV # Lo       HANGUL SYLLABLE GWAE
-AD34          ; LV # Lo       HANGUL SYLLABLE GOE
-AD50          ; LV # Lo       HANGUL SYLLABLE GYO
-AD6C          ; LV # Lo       HANGUL SYLLABLE GU
-AD88          ; LV # Lo       HANGUL SYLLABLE GWEO
-ADA4          ; LV # Lo       HANGUL SYLLABLE GWE
-ADC0          ; LV # Lo       HANGUL SYLLABLE GWI
-ADDC          ; LV # Lo       HANGUL SYLLABLE GYU
-ADF8          ; LV # Lo       HANGUL SYLLABLE GEU
-AE14          ; LV # Lo       HANGUL SYLLABLE GYI
-AE30          ; LV # Lo       HANGUL SYLLABLE GI
-AE4C          ; LV # Lo       HANGUL SYLLABLE GGA
-AE68          ; LV # Lo       HANGUL SYLLABLE GGAE
-AE84          ; LV # Lo       HANGUL SYLLABLE GGYA
-AEA0          ; LV # Lo       HANGUL SYLLABLE GGYAE
-AEBC          ; LV # Lo       HANGUL SYLLABLE GGEO
-AED8          ; LV # Lo       HANGUL SYLLABLE GGE
-AEF4          ; LV # Lo       HANGUL SYLLABLE GGYEO
-AF10          ; LV # Lo       HANGUL SYLLABLE GGYE
-AF2C          ; LV # Lo       HANGUL SYLLABLE GGO
-AF48          ; LV # Lo       HANGUL SYLLABLE GGWA
-AF64          ; LV # Lo       HANGUL SYLLABLE GGWAE
-AF80          ; LV # Lo       HANGUL SYLLABLE GGOE
-AF9C          ; LV # Lo       HANGUL SYLLABLE GGYO
-AFB8          ; LV # Lo       HANGUL SYLLABLE GGU
-AFD4          ; LV # Lo       HANGUL SYLLABLE GGWEO
-AFF0          ; LV # Lo       HANGUL SYLLABLE GGWE
-B00C          ; LV # Lo       HANGUL SYLLABLE GGWI
-B028          ; LV # Lo       HANGUL SYLLABLE GGYU
-B044          ; LV # Lo       HANGUL SYLLABLE GGEU
-B060          ; LV # Lo       HANGUL SYLLABLE GGYI
-B07C          ; LV # Lo       HANGUL SYLLABLE GGI
-B098          ; LV # Lo       HANGUL SYLLABLE NA
-B0B4          ; LV # Lo       HANGUL SYLLABLE NAE
-B0D0          ; LV # Lo       HANGUL SYLLABLE NYA
-B0EC          ; LV # Lo       HANGUL SYLLABLE NYAE
-B108          ; LV # Lo       HANGUL SYLLABLE NEO
-B124          ; LV # Lo       HANGUL SYLLABLE NE
-B140          ; LV # Lo       HANGUL SYLLABLE NYEO
-B15C          ; LV # Lo       HANGUL SYLLABLE NYE
-B178          ; LV # Lo       HANGUL SYLLABLE NO
-B194          ; LV # Lo       HANGUL SYLLABLE NWA
-B1B0          ; LV # Lo       HANGUL SYLLABLE NWAE
-B1CC          ; LV # Lo       HANGUL SYLLABLE NOE
-B1E8          ; LV # Lo       HANGUL SYLLABLE NYO
-B204          ; LV # Lo       HANGUL SYLLABLE NU
-B220          ; LV # Lo       HANGUL SYLLABLE NWEO
-B23C          ; LV # Lo       HANGUL SYLLABLE NWE
-B258          ; LV # Lo       HANGUL SYLLABLE NWI
-B274          ; LV # Lo       HANGUL SYLLABLE NYU
-B290          ; LV # Lo       HANGUL SYLLABLE NEU
-B2AC          ; LV # Lo       HANGUL SYLLABLE NYI
-B2C8          ; LV # Lo       HANGUL SYLLABLE NI
-B2E4          ; LV # Lo       HANGUL SYLLABLE DA
-B300          ; LV # Lo       HANGUL SYLLABLE DAE
-B31C          ; LV # Lo       HANGUL SYLLABLE DYA
-B338          ; LV # Lo       HANGUL SYLLABLE DYAE
-B354          ; LV # Lo       HANGUL SYLLABLE DEO
-B370          ; LV # Lo       HANGUL SYLLABLE DE
-B38C          ; LV # Lo       HANGUL SYLLABLE DYEO
-B3A8          ; LV # Lo       HANGUL SYLLABLE DYE
-B3C4          ; LV # Lo       HANGUL SYLLABLE DO
-B3E0          ; LV # Lo       HANGUL SYLLABLE DWA
-B3FC          ; LV # Lo       HANGUL SYLLABLE DWAE
-B418          ; LV # Lo       HANGUL SYLLABLE DOE
-B434          ; LV # Lo       HANGUL SYLLABLE DYO
-B450          ; LV # Lo       HANGUL SYLLABLE DU
-B46C          ; LV # Lo       HANGUL SYLLABLE DWEO
-B488          ; LV # Lo       HANGUL SYLLABLE DWE
-B4A4          ; LV # Lo       HANGUL SYLLABLE DWI
-B4C0          ; LV # Lo       HANGUL SYLLABLE DYU
-B4DC          ; LV # Lo       HANGUL SYLLABLE DEU
-B4F8          ; LV # Lo       HANGUL SYLLABLE DYI
-B514          ; LV # Lo       HANGUL SYLLABLE DI
-B530          ; LV # Lo       HANGUL SYLLABLE DDA
-B54C          ; LV # Lo       HANGUL SYLLABLE DDAE
-B568          ; LV # Lo       HANGUL SYLLABLE DDYA
-B584          ; LV # Lo       HANGUL SYLLABLE DDYAE
-B5A0          ; LV # Lo       HANGUL SYLLABLE DDEO
-B5BC          ; LV # Lo       HANGUL SYLLABLE DDE
-B5D8          ; LV # Lo       HANGUL SYLLABLE DDYEO
-B5F4          ; LV # Lo       HANGUL SYLLABLE DDYE
-B610          ; LV # Lo       HANGUL SYLLABLE DDO
-B62C          ; LV # Lo       HANGUL SYLLABLE DDWA
-B648          ; LV # Lo       HANGUL SYLLABLE DDWAE
-B664          ; LV # Lo       HANGUL SYLLABLE DDOE
-B680          ; LV # Lo       HANGUL SYLLABLE DDYO
-B69C          ; LV # Lo       HANGUL SYLLABLE DDU
-B6B8          ; LV # Lo       HANGUL SYLLABLE DDWEO
-B6D4          ; LV # Lo       HANGUL SYLLABLE DDWE
-B6F0          ; LV # Lo       HANGUL SYLLABLE DDWI
-B70C          ; LV # Lo       HANGUL SYLLABLE DDYU
-B728          ; LV # Lo       HANGUL SYLLABLE DDEU
-B744          ; LV # Lo       HANGUL SYLLABLE DDYI
-B760          ; LV # Lo       HANGUL SYLLABLE DDI
-B77C          ; LV # Lo       HANGUL SYLLABLE RA
-B798          ; LV # Lo       HANGUL SYLLABLE RAE
-B7B4          ; LV # Lo       HANGUL SYLLABLE RYA
-B7D0          ; LV # Lo       HANGUL SYLLABLE RYAE
-B7EC          ; LV # Lo       HANGUL SYLLABLE REO
-B808          ; LV # Lo       HANGUL SYLLABLE RE
-B824          ; LV # Lo       HANGUL SYLLABLE RYEO
-B840          ; LV # Lo       HANGUL SYLLABLE RYE
-B85C          ; LV # Lo       HANGUL SYLLABLE RO
-B878          ; LV # Lo       HANGUL SYLLABLE RWA
-B894          ; LV # Lo       HANGUL SYLLABLE RWAE
-B8B0          ; LV # Lo       HANGUL SYLLABLE ROE
-B8CC          ; LV # Lo       HANGUL SYLLABLE RYO
-B8E8          ; LV # Lo       HANGUL SYLLABLE RU
-B904          ; LV # Lo       HANGUL SYLLABLE RWEO
-B920          ; LV # Lo       HANGUL SYLLABLE RWE
-B93C          ; LV # Lo       HANGUL SYLLABLE RWI
-B958          ; LV # Lo       HANGUL SYLLABLE RYU
-B974          ; LV # Lo       HANGUL SYLLABLE REU
-B990          ; LV # Lo       HANGUL SYLLABLE RYI
-B9AC          ; LV # Lo       HANGUL SYLLABLE RI
-B9C8          ; LV # Lo       HANGUL SYLLABLE MA
-B9E4          ; LV # Lo       HANGUL SYLLABLE MAE
-BA00          ; LV # Lo       HANGUL SYLLABLE MYA
-BA1C          ; LV # Lo       HANGUL SYLLABLE MYAE
-BA38          ; LV # Lo       HANGUL SYLLABLE MEO
-BA54          ; LV # Lo       HANGUL SYLLABLE ME
-BA70          ; LV # Lo       HANGUL SYLLABLE MYEO
-BA8C          ; LV # Lo       HANGUL SYLLABLE MYE
-BAA8          ; LV # Lo       HANGUL SYLLABLE MO
-BAC4          ; LV # Lo       HANGUL SYLLABLE MWA
-BAE0          ; LV # Lo       HANGUL SYLLABLE MWAE
-BAFC          ; LV # Lo       HANGUL SYLLABLE MOE
-BB18          ; LV # Lo       HANGUL SYLLABLE MYO
-BB34          ; LV # Lo       HANGUL SYLLABLE MU
-BB50          ; LV # Lo       HANGUL SYLLABLE MWEO
-BB6C          ; LV # Lo       HANGUL SYLLABLE MWE
-BB88          ; LV # Lo       HANGUL SYLLABLE MWI
-BBA4          ; LV # Lo       HANGUL SYLLABLE MYU
-BBC0          ; LV # Lo       HANGUL SYLLABLE MEU
-BBDC          ; LV # Lo       HANGUL SYLLABLE MYI
-BBF8          ; LV # Lo       HANGUL SYLLABLE MI
-BC14          ; LV # Lo       HANGUL SYLLABLE BA
-BC30          ; LV # Lo       HANGUL SYLLABLE BAE
-BC4C          ; LV # Lo       HANGUL SYLLABLE BYA
-BC68          ; LV # Lo       HANGUL SYLLABLE BYAE
-BC84          ; LV # Lo       HANGUL SYLLABLE BEO
-BCA0          ; LV # Lo       HANGUL SYLLABLE BE
-BCBC          ; LV # Lo       HANGUL SYLLABLE BYEO
-BCD8          ; LV # Lo       HANGUL SYLLABLE BYE
-BCF4          ; LV # Lo       HANGUL SYLLABLE BO
-BD10          ; LV # Lo       HANGUL SYLLABLE BWA
-BD2C          ; LV # Lo       HANGUL SYLLABLE BWAE
-BD48          ; LV # Lo       HANGUL SYLLABLE BOE
-BD64          ; LV # Lo       HANGUL SYLLABLE BYO
-BD80          ; LV # Lo       HANGUL SYLLABLE BU
-BD9C          ; LV # Lo       HANGUL SYLLABLE BWEO
-BDB8          ; LV # Lo       HANGUL SYLLABLE BWE
-BDD4          ; LV # Lo       HANGUL SYLLABLE BWI
-BDF0          ; LV # Lo       HANGUL SYLLABLE BYU
-BE0C          ; LV # Lo       HANGUL SYLLABLE BEU
-BE28          ; LV # Lo       HANGUL SYLLABLE BYI
-BE44          ; LV # Lo       HANGUL SYLLABLE BI
-BE60          ; LV # Lo       HANGUL SYLLABLE BBA
-BE7C          ; LV # Lo       HANGUL SYLLABLE BBAE
-BE98          ; LV # Lo       HANGUL SYLLABLE BBYA
-BEB4          ; LV # Lo       HANGUL SYLLABLE BBYAE
-BED0          ; LV # Lo       HANGUL SYLLABLE BBEO
-BEEC          ; LV # Lo       HANGUL SYLLABLE BBE
-BF08          ; LV # Lo       HANGUL SYLLABLE BBYEO
-BF24          ; LV # Lo       HANGUL SYLLABLE BBYE
-BF40          ; LV # Lo       HANGUL SYLLABLE BBO
-BF5C          ; LV # Lo       HANGUL SYLLABLE BBWA
-BF78          ; LV # Lo       HANGUL SYLLABLE BBWAE
-BF94          ; LV # Lo       HANGUL SYLLABLE BBOE
-BFB0          ; LV # Lo       HANGUL SYLLABLE BBYO
-BFCC          ; LV # Lo       HANGUL SYLLABLE BBU
-BFE8          ; LV # Lo       HANGUL SYLLABLE BBWEO
-C004          ; LV # Lo       HANGUL SYLLABLE BBWE
-C020          ; LV # Lo       HANGUL SYLLABLE BBWI
-C03C          ; LV # Lo       HANGUL SYLLABLE BBYU
-C058          ; LV # Lo       HANGUL SYLLABLE BBEU
-C074          ; LV # Lo       HANGUL SYLLABLE BBYI
-C090          ; LV # Lo       HANGUL SYLLABLE BBI
-C0AC          ; LV # Lo       HANGUL SYLLABLE SA
-C0C8          ; LV # Lo       HANGUL SYLLABLE SAE
-C0E4          ; LV # Lo       HANGUL SYLLABLE SYA
-C100          ; LV # Lo       HANGUL SYLLABLE SYAE
-C11C          ; LV # Lo       HANGUL SYLLABLE SEO
-C138          ; LV # Lo       HANGUL SYLLABLE SE
-C154          ; LV # Lo       HANGUL SYLLABLE SYEO
-C170          ; LV # Lo       HANGUL SYLLABLE SYE
-C18C          ; LV # Lo       HANGUL SYLLABLE SO
-C1A8          ; LV # Lo       HANGUL SYLLABLE SWA
-C1C4          ; LV # Lo       HANGUL SYLLABLE SWAE
-C1E0          ; LV # Lo       HANGUL SYLLABLE SOE
-C1FC          ; LV # Lo       HANGUL SYLLABLE SYO
-C218          ; LV # Lo       HANGUL SYLLABLE SU
-C234          ; LV # Lo       HANGUL SYLLABLE SWEO
-C250          ; LV # Lo       HANGUL SYLLABLE SWE
-C26C          ; LV # Lo       HANGUL SYLLABLE SWI
-C288          ; LV # Lo       HANGUL SYLLABLE SYU
-C2A4          ; LV # Lo       HANGUL SYLLABLE SEU
-C2C0          ; LV # Lo       HANGUL SYLLABLE SYI
-C2DC          ; LV # Lo       HANGUL SYLLABLE SI
-C2F8          ; LV # Lo       HANGUL SYLLABLE SSA
-C314          ; LV # Lo       HANGUL SYLLABLE SSAE
-C330          ; LV # Lo       HANGUL SYLLABLE SSYA
-C34C          ; LV # Lo       HANGUL SYLLABLE SSYAE
-C368          ; LV # Lo       HANGUL SYLLABLE SSEO
-C384          ; LV # Lo       HANGUL SYLLABLE SSE
-C3A0          ; LV # Lo       HANGUL SYLLABLE SSYEO
-C3BC          ; LV # Lo       HANGUL SYLLABLE SSYE
-C3D8          ; LV # Lo       HANGUL SYLLABLE SSO
-C3F4          ; LV # Lo       HANGUL SYLLABLE SSWA
-C410          ; LV # Lo       HANGUL SYLLABLE SSWAE
-C42C          ; LV # Lo       HANGUL SYLLABLE SSOE
-C448          ; LV # Lo       HANGUL SYLLABLE SSYO
-C464          ; LV # Lo       HANGUL SYLLABLE SSU
-C480          ; LV # Lo       HANGUL SYLLABLE SSWEO
-C49C          ; LV # Lo       HANGUL SYLLABLE SSWE
-C4B8          ; LV # Lo       HANGUL SYLLABLE SSWI
-C4D4          ; LV # Lo       HANGUL SYLLABLE SSYU
-C4F0          ; LV # Lo       HANGUL SYLLABLE SSEU
-C50C          ; LV # Lo       HANGUL SYLLABLE SSYI
-C528          ; LV # Lo       HANGUL SYLLABLE SSI
-C544          ; LV # Lo       HANGUL SYLLABLE A
-C560          ; LV # Lo       HANGUL SYLLABLE AE
-C57C          ; LV # Lo       HANGUL SYLLABLE YA
-C598          ; LV # Lo       HANGUL SYLLABLE YAE
-C5B4          ; LV # Lo       HANGUL SYLLABLE EO
-C5D0          ; LV # Lo       HANGUL SYLLABLE E
-C5EC          ; LV # Lo       HANGUL SYLLABLE YEO
-C608          ; LV # Lo       HANGUL SYLLABLE YE
-C624          ; LV # Lo       HANGUL SYLLABLE O
-C640          ; LV # Lo       HANGUL SYLLABLE WA
-C65C          ; LV # Lo       HANGUL SYLLABLE WAE
-C678          ; LV # Lo       HANGUL SYLLABLE OE
-C694          ; LV # Lo       HANGUL SYLLABLE YO
-C6B0          ; LV # Lo       HANGUL SYLLABLE U
-C6CC          ; LV # Lo       HANGUL SYLLABLE WEO
-C6E8          ; LV # Lo       HANGUL SYLLABLE WE
-C704          ; LV # Lo       HANGUL SYLLABLE WI
-C720          ; LV # Lo       HANGUL SYLLABLE YU
-C73C          ; LV # Lo       HANGUL SYLLABLE EU
-C758          ; LV # Lo       HANGUL SYLLABLE YI
-C774          ; LV # Lo       HANGUL SYLLABLE I
-C790          ; LV # Lo       HANGUL SYLLABLE JA
-C7AC          ; LV # Lo       HANGUL SYLLABLE JAE
-C7C8          ; LV # Lo       HANGUL SYLLABLE JYA
-C7E4          ; LV # Lo       HANGUL SYLLABLE JYAE
-C800          ; LV # Lo       HANGUL SYLLABLE JEO
-C81C          ; LV # Lo       HANGUL SYLLABLE JE
-C838          ; LV # Lo       HANGUL SYLLABLE JYEO
-C854          ; LV # Lo       HANGUL SYLLABLE JYE
-C870          ; LV # Lo       HANGUL SYLLABLE JO
-C88C          ; LV # Lo       HANGUL SYLLABLE JWA
-C8A8          ; LV # Lo       HANGUL SYLLABLE JWAE
-C8C4          ; LV # Lo       HANGUL SYLLABLE JOE
-C8E0          ; LV # Lo       HANGUL SYLLABLE JYO
-C8FC          ; LV # Lo       HANGUL SYLLABLE JU
-C918          ; LV # Lo       HANGUL SYLLABLE JWEO
-C934          ; LV # Lo       HANGUL SYLLABLE JWE
-C950          ; LV # Lo       HANGUL SYLLABLE JWI
-C96C          ; LV # Lo       HANGUL SYLLABLE JYU
-C988          ; LV # Lo       HANGUL SYLLABLE JEU
-C9A4          ; LV # Lo       HANGUL SYLLABLE JYI
-C9C0          ; LV # Lo       HANGUL SYLLABLE JI
-C9DC          ; LV # Lo       HANGUL SYLLABLE JJA
-C9F8          ; LV # Lo       HANGUL SYLLABLE JJAE
-CA14          ; LV # Lo       HANGUL SYLLABLE JJYA
-CA30          ; LV # Lo       HANGUL SYLLABLE JJYAE
-CA4C          ; LV # Lo       HANGUL SYLLABLE JJEO
-CA68          ; LV # Lo       HANGUL SYLLABLE JJE
-CA84          ; LV # Lo       HANGUL SYLLABLE JJYEO
-CAA0          ; LV # Lo       HANGUL SYLLABLE JJYE
-CABC          ; LV # Lo       HANGUL SYLLABLE JJO
-CAD8          ; LV # Lo       HANGUL SYLLABLE JJWA
-CAF4          ; LV # Lo       HANGUL SYLLABLE JJWAE
-CB10          ; LV # Lo       HANGUL SYLLABLE JJOE
-CB2C          ; LV # Lo       HANGUL SYLLABLE JJYO
-CB48          ; LV # Lo       HANGUL SYLLABLE JJU
-CB64          ; LV # Lo       HANGUL SYLLABLE JJWEO
-CB80          ; LV # Lo       HANGUL SYLLABLE JJWE
-CB9C          ; LV # Lo       HANGUL SYLLABLE JJWI
-CBB8          ; LV # Lo       HANGUL SYLLABLE JJYU
-CBD4          ; LV # Lo       HANGUL SYLLABLE JJEU
-CBF0          ; LV # Lo       HANGUL SYLLABLE JJYI
-CC0C          ; LV # Lo       HANGUL SYLLABLE JJI
-CC28          ; LV # Lo       HANGUL SYLLABLE CA
-CC44          ; LV # Lo       HANGUL SYLLABLE CAE
-CC60          ; LV # Lo       HANGUL SYLLABLE CYA
-CC7C          ; LV # Lo       HANGUL SYLLABLE CYAE
-CC98          ; LV # Lo       HANGUL SYLLABLE CEO
-CCB4          ; LV # Lo       HANGUL SYLLABLE CE
-CCD0          ; LV # Lo       HANGUL SYLLABLE CYEO
-CCEC          ; LV # Lo       HANGUL SYLLABLE CYE
-CD08          ; LV # Lo       HANGUL SYLLABLE CO
-CD24          ; LV # Lo       HANGUL SYLLABLE CWA
-CD40          ; LV # Lo       HANGUL SYLLABLE CWAE
-CD5C          ; LV # Lo       HANGUL SYLLABLE COE
-CD78          ; LV # Lo       HANGUL SYLLABLE CYO
-CD94          ; LV # Lo       HANGUL SYLLABLE CU
-CDB0          ; LV # Lo       HANGUL SYLLABLE CWEO
-CDCC          ; LV # Lo       HANGUL SYLLABLE CWE
-CDE8          ; LV # Lo       HANGUL SYLLABLE CWI
-CE04          ; LV # Lo       HANGUL SYLLABLE CYU
-CE20          ; LV # Lo       HANGUL SYLLABLE CEU
-CE3C          ; LV # Lo       HANGUL SYLLABLE CYI
-CE58          ; LV # Lo       HANGUL SYLLABLE CI
-CE74          ; LV # Lo       HANGUL SYLLABLE KA
-CE90          ; LV # Lo       HANGUL SYLLABLE KAE
-CEAC          ; LV # Lo       HANGUL SYLLABLE KYA
-CEC8          ; LV # Lo       HANGUL SYLLABLE KYAE
-CEE4          ; LV # Lo       HANGUL SYLLABLE KEO
-CF00          ; LV # Lo       HANGUL SYLLABLE KE
-CF1C          ; LV # Lo       HANGUL SYLLABLE KYEO
-CF38          ; LV # Lo       HANGUL SYLLABLE KYE
-CF54          ; LV # Lo       HANGUL SYLLABLE KO
-CF70          ; LV # Lo       HANGUL SYLLABLE KWA
-CF8C          ; LV # Lo       HANGUL SYLLABLE KWAE
-CFA8          ; LV # Lo       HANGUL SYLLABLE KOE
-CFC4          ; LV # Lo       HANGUL SYLLABLE KYO
-CFE0          ; LV # Lo       HANGUL SYLLABLE KU
-CFFC          ; LV # Lo       HANGUL SYLLABLE KWEO
-D018          ; LV # Lo       HANGUL SYLLABLE KWE
-D034          ; LV # Lo       HANGUL SYLLABLE KWI
-D050          ; LV # Lo       HANGUL SYLLABLE KYU
-D06C          ; LV # Lo       HANGUL SYLLABLE KEU
-D088          ; LV # Lo       HANGUL SYLLABLE KYI
-D0A4          ; LV # Lo       HANGUL SYLLABLE KI
-D0C0          ; LV # Lo       HANGUL SYLLABLE TA
-D0DC          ; LV # Lo       HANGUL SYLLABLE TAE
-D0F8          ; LV # Lo       HANGUL SYLLABLE TYA
-D114          ; LV # Lo       HANGUL SYLLABLE TYAE
-D130          ; LV # Lo       HANGUL SYLLABLE TEO
-D14C          ; LV # Lo       HANGUL SYLLABLE TE
-D168          ; LV # Lo       HANGUL SYLLABLE TYEO
-D184          ; LV # Lo       HANGUL SYLLABLE TYE
-D1A0          ; LV # Lo       HANGUL SYLLABLE TO
-D1BC          ; LV # Lo       HANGUL SYLLABLE TWA
-D1D8          ; LV # Lo       HANGUL SYLLABLE TWAE
-D1F4          ; LV # Lo       HANGUL SYLLABLE TOE
-D210          ; LV # Lo       HANGUL SYLLABLE TYO
-D22C          ; LV # Lo       HANGUL SYLLABLE TU
-D248          ; LV # Lo       HANGUL SYLLABLE TWEO
-D264          ; LV # Lo       HANGUL SYLLABLE TWE
-D280          ; LV # Lo       HANGUL SYLLABLE TWI
-D29C          ; LV # Lo       HANGUL SYLLABLE TYU
-D2B8          ; LV # Lo       HANGUL SYLLABLE TEU
-D2D4          ; LV # Lo       HANGUL SYLLABLE TYI
-D2F0          ; LV # Lo       HANGUL SYLLABLE TI
-D30C          ; LV # Lo       HANGUL SYLLABLE PA
-D328          ; LV # Lo       HANGUL SYLLABLE PAE
-D344          ; LV # Lo       HANGUL SYLLABLE PYA
-D360          ; LV # Lo       HANGUL SYLLABLE PYAE
-D37C          ; LV # Lo       HANGUL SYLLABLE PEO
-D398          ; LV # Lo       HANGUL SYLLABLE PE
-D3B4          ; LV # Lo       HANGUL SYLLABLE PYEO
-D3D0          ; LV # Lo       HANGUL SYLLABLE PYE
-D3EC          ; LV # Lo       HANGUL SYLLABLE PO
-D408          ; LV # Lo       HANGUL SYLLABLE PWA
-D424          ; LV # Lo       HANGUL SYLLABLE PWAE
-D440          ; LV # Lo       HANGUL SYLLABLE POE
-D45C          ; LV # Lo       HANGUL SYLLABLE PYO
-D478          ; LV # Lo       HANGUL SYLLABLE PU
-D494          ; LV # Lo       HANGUL SYLLABLE PWEO
-D4B0          ; LV # Lo       HANGUL SYLLABLE PWE
-D4CC          ; LV # Lo       HANGUL SYLLABLE PWI
-D4E8          ; LV # Lo       HANGUL SYLLABLE PYU
-D504          ; LV # Lo       HANGUL SYLLABLE PEU
-D520          ; LV # Lo       HANGUL SYLLABLE PYI
-D53C          ; LV # Lo       HANGUL SYLLABLE PI
-D558          ; LV # Lo       HANGUL SYLLABLE HA
-D574          ; LV # Lo       HANGUL SYLLABLE HAE
-D590          ; LV # Lo       HANGUL SYLLABLE HYA
-D5AC          ; LV # Lo       HANGUL SYLLABLE HYAE
-D5C8          ; LV # Lo       HANGUL SYLLABLE HEO
-D5E4          ; LV # Lo       HANGUL SYLLABLE HE
-D600          ; LV # Lo       HANGUL SYLLABLE HYEO
-D61C          ; LV # Lo       HANGUL SYLLABLE HYE
-D638          ; LV # Lo       HANGUL SYLLABLE HO
-D654          ; LV # Lo       HANGUL SYLLABLE HWA
-D670          ; LV # Lo       HANGUL SYLLABLE HWAE
-D68C          ; LV # Lo       HANGUL SYLLABLE HOE
-D6A8          ; LV # Lo       HANGUL SYLLABLE HYO
-D6C4          ; LV # Lo       HANGUL SYLLABLE HU
-D6E0          ; LV # Lo       HANGUL SYLLABLE HWEO
-D6FC          ; LV # Lo       HANGUL SYLLABLE HWE
-D718          ; LV # Lo       HANGUL SYLLABLE HWI
-D734          ; LV # Lo       HANGUL SYLLABLE HYU
-D750          ; LV # Lo       HANGUL SYLLABLE HEU
-D76C          ; LV # Lo       HANGUL SYLLABLE HYI
-D788          ; LV # Lo       HANGUL SYLLABLE HI
-
-# Total code points: 399
-
-# ================================================
-
-AC01..AC1B    ; LVT # Lo  [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH
-AC1D..AC37    ; LVT # Lo  [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH
-AC39..AC53    ; LVT # Lo  [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH
-AC55..AC6F    ; LVT # Lo  [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH
-AC71..AC8B    ; LVT # Lo  [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH
-AC8D..ACA7    ; LVT # Lo  [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH
-ACA9..ACC3    ; LVT # Lo  [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH
-ACC5..ACDF    ; LVT # Lo  [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH
-ACE1..ACFB    ; LVT # Lo  [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH
-ACFD..AD17    ; LVT # Lo  [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH
-AD19..AD33    ; LVT # Lo  [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH
-AD35..AD4F    ; LVT # Lo  [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH
-AD51..AD6B    ; LVT # Lo  [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH
-AD6D..AD87    ; LVT # Lo  [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH
-AD89..ADA3    ; LVT # Lo  [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH
-ADA5..ADBF    ; LVT # Lo  [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH
-ADC1..ADDB    ; LVT # Lo  [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH
-ADDD..ADF7    ; LVT # Lo  [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH
-ADF9..AE13    ; LVT # Lo  [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH
-AE15..AE2F    ; LVT # Lo  [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH
-AE31..AE4B    ; LVT # Lo  [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH
-AE4D..AE67    ; LVT # Lo  [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH
-AE69..AE83    ; LVT # Lo  [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH
-AE85..AE9F    ; LVT # Lo  [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH
-AEA1..AEBB    ; LVT # Lo  [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH
-AEBD..AED7    ; LVT # Lo  [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH
-AED9..AEF3    ; LVT # Lo  [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH
-AEF5..AF0F    ; LVT # Lo  [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH
-AF11..AF2B    ; LVT # Lo  [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH
-AF2D..AF47    ; LVT # Lo  [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH
-AF49..AF63    ; LVT # Lo  [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH
-AF65..AF7F    ; LVT # Lo  [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH
-AF81..AF9B    ; LVT # Lo  [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH
-AF9D..AFB7    ; LVT # Lo  [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH
-AFB9..AFD3    ; LVT # Lo  [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH
-AFD5..AFEF    ; LVT # Lo  [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH
-AFF1..B00B    ; LVT # Lo  [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH
-B00D..B027    ; LVT # Lo  [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH
-B029..B043    ; LVT # Lo  [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH
-B045..B05F    ; LVT # Lo  [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH
-B061..B07B    ; LVT # Lo  [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH
-B07D..B097    ; LVT # Lo  [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH
-B099..B0B3    ; LVT # Lo  [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH
-B0B5..B0CF    ; LVT # Lo  [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH
-B0D1..B0EB    ; LVT # Lo  [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH
-B0ED..B107    ; LVT # Lo  [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH
-B109..B123    ; LVT # Lo  [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH
-B125..B13F    ; LVT # Lo  [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH
-B141..B15B    ; LVT # Lo  [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH
-B15D..B177    ; LVT # Lo  [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH
-B179..B193    ; LVT # Lo  [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH
-B195..B1AF    ; LVT # Lo  [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH
-B1B1..B1CB    ; LVT # Lo  [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH
-B1CD..B1E7    ; LVT # Lo  [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH
-B1E9..B203    ; LVT # Lo  [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH
-B205..B21F    ; LVT # Lo  [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH
-B221..B23B    ; LVT # Lo  [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH
-B23D..B257    ; LVT # Lo  [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH
-B259..B273    ; LVT # Lo  [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH
-B275..B28F    ; LVT # Lo  [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH
-B291..B2AB    ; LVT # Lo  [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH
-B2AD..B2C7    ; LVT # Lo  [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH
-B2C9..B2E3    ; LVT # Lo  [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH
-B2E5..B2FF    ; LVT # Lo  [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH
-B301..B31B    ; LVT # Lo  [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH
-B31D..B337    ; LVT # Lo  [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH
-B339..B353    ; LVT # Lo  [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH
-B355..B36F    ; LVT # Lo  [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH
-B371..B38B    ; LVT # Lo  [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH
-B38D..B3A7    ; LVT # Lo  [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH
-B3A9..B3C3    ; LVT # Lo  [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH
-B3C5..B3DF    ; LVT # Lo  [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH
-B3E1..B3FB    ; LVT # Lo  [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH
-B3FD..B417    ; LVT # Lo  [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH
-B419..B433    ; LVT # Lo  [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH
-B435..B44F    ; LVT # Lo  [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH
-B451..B46B    ; LVT # Lo  [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH
-B46D..B487    ; LVT # Lo  [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH
-B489..B4A3    ; LVT # Lo  [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH
-B4A5..B4BF    ; LVT # Lo  [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH
-B4C1..B4DB    ; LVT # Lo  [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH
-B4DD..B4F7    ; LVT # Lo  [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH
-B4F9..B513    ; LVT # Lo  [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH
-B515..B52F    ; LVT # Lo  [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH
-B531..B54B    ; LVT # Lo  [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH
-B54D..B567    ; LVT # Lo  [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH
-B569..B583    ; LVT # Lo  [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH
-B585..B59F    ; LVT # Lo  [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH
-B5A1..B5BB    ; LVT # Lo  [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH
-B5BD..B5D7    ; LVT # Lo  [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH
-B5D9..B5F3    ; LVT # Lo  [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH
-B5F5..B60F    ; LVT # Lo  [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH
-B611..B62B    ; LVT # Lo  [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH
-B62D..B647    ; LVT # Lo  [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH
-B649..B663    ; LVT # Lo  [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH
-B665..B67F    ; LVT # Lo  [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH
-B681..B69B    ; LVT # Lo  [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH
-B69D..B6B7    ; LVT # Lo  [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH
-B6B9..B6D3    ; LVT # Lo  [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH
-B6D5..B6EF    ; LVT # Lo  [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH
-B6F1..B70B    ; LVT # Lo  [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH
-B70D..B727    ; LVT # Lo  [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH
-B729..B743    ; LVT # Lo  [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH
-B745..B75F    ; LVT # Lo  [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH
-B761..B77B    ; LVT # Lo  [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH
-B77D..B797    ; LVT # Lo  [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH
-B799..B7B3    ; LVT # Lo  [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH
-B7B5..B7CF    ; LVT # Lo  [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH
-B7D1..B7EB    ; LVT # Lo  [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH
-B7ED..B807    ; LVT # Lo  [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH
-B809..B823    ; LVT # Lo  [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH
-B825..B83F    ; LVT # Lo  [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH
-B841..B85B    ; LVT # Lo  [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH
-B85D..B877    ; LVT # Lo  [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH
-B879..B893    ; LVT # Lo  [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH
-B895..B8AF    ; LVT # Lo  [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH
-B8B1..B8CB    ; LVT # Lo  [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH
-B8CD..B8E7    ; LVT # Lo  [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH
-B8E9..B903    ; LVT # Lo  [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH
-B905..B91F    ; LVT # Lo  [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH
-B921..B93B    ; LVT # Lo  [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH
-B93D..B957    ; LVT # Lo  [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH
-B959..B973    ; LVT # Lo  [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH
-B975..B98F    ; LVT # Lo  [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH
-B991..B9AB    ; LVT # Lo  [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH
-B9AD..B9C7    ; LVT # Lo  [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH
-B9C9..B9E3    ; LVT # Lo  [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH
-B9E5..B9FF    ; LVT # Lo  [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH
-BA01..BA1B    ; LVT # Lo  [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH
-BA1D..BA37    ; LVT # Lo  [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH
-BA39..BA53    ; LVT # Lo  [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH
-BA55..BA6F    ; LVT # Lo  [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH
-BA71..BA8B    ; LVT # Lo  [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH
-BA8D..BAA7    ; LVT # Lo  [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH
-BAA9..BAC3    ; LVT # Lo  [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH
-BAC5..BADF    ; LVT # Lo  [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH
-BAE1..BAFB    ; LVT # Lo  [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH
-BAFD..BB17    ; LVT # Lo  [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH
-BB19..BB33    ; LVT # Lo  [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH
-BB35..BB4F    ; LVT # Lo  [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH
-BB51..BB6B    ; LVT # Lo  [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH
-BB6D..BB87    ; LVT # Lo  [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH
-BB89..BBA3    ; LVT # Lo  [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH
-BBA5..BBBF    ; LVT # Lo  [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH
-BBC1..BBDB    ; LVT # Lo  [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH
-BBDD..BBF7    ; LVT # Lo  [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH
-BBF9..BC13    ; LVT # Lo  [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH
-BC15..BC2F    ; LVT # Lo  [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH
-BC31..BC4B    ; LVT # Lo  [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH
-BC4D..BC67    ; LVT # Lo  [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH
-BC69..BC83    ; LVT # Lo  [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH
-BC85..BC9F    ; LVT # Lo  [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH
-BCA1..BCBB    ; LVT # Lo  [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH
-BCBD..BCD7    ; LVT # Lo  [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH
-BCD9..BCF3    ; LVT # Lo  [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH
-BCF5..BD0F    ; LVT # Lo  [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH
-BD11..BD2B    ; LVT # Lo  [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH
-BD2D..BD47    ; LVT # Lo  [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH
-BD49..BD63    ; LVT # Lo  [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH
-BD65..BD7F    ; LVT # Lo  [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH
-BD81..BD9B    ; LVT # Lo  [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH
-BD9D..BDB7    ; LVT # Lo  [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH
-BDB9..BDD3    ; LVT # Lo  [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH
-BDD5..BDEF    ; LVT # Lo  [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH
-BDF1..BE0B    ; LVT # Lo  [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH
-BE0D..BE27    ; LVT # Lo  [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH
-BE29..BE43    ; LVT # Lo  [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH
-BE45..BE5F    ; LVT # Lo  [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH
-BE61..BE7B    ; LVT # Lo  [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH
-BE7D..BE97    ; LVT # Lo  [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH
-BE99..BEB3    ; LVT # Lo  [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH
-BEB5..BECF    ; LVT # Lo  [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH
-BED1..BEEB    ; LVT # Lo  [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH
-BEED..BF07    ; LVT # Lo  [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH
-BF09..BF23    ; LVT # Lo  [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH
-BF25..BF3F    ; LVT # Lo  [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH
-BF41..BF5B    ; LVT # Lo  [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH
-BF5D..BF77    ; LVT # Lo  [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH
-BF79..BF93    ; LVT # Lo  [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH
-BF95..BFAF    ; LVT # Lo  [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH
-BFB1..BFCB    ; LVT # Lo  [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH
-BFCD..BFE7    ; LVT # Lo  [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH
-BFE9..C003    ; LVT # Lo  [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH
-C005..C01F    ; LVT # Lo  [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH
-C021..C03B    ; LVT # Lo  [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH
-C03D..C057    ; LVT # Lo  [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH
-C059..C073    ; LVT # Lo  [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH
-C075..C08F    ; LVT # Lo  [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH
-C091..C0AB    ; LVT # Lo  [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH
-C0AD..C0C7    ; LVT # Lo  [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH
-C0C9..C0E3    ; LVT # Lo  [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH
-C0E5..C0FF    ; LVT # Lo  [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH
-C101..C11B    ; LVT # Lo  [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH
-C11D..C137    ; LVT # Lo  [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH
-C139..C153    ; LVT # Lo  [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH
-C155..C16F    ; LVT # Lo  [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH
-C171..C18B    ; LVT # Lo  [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH
-C18D..C1A7    ; LVT # Lo  [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH
-C1A9..C1C3    ; LVT # Lo  [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH
-C1C5..C1DF    ; LVT # Lo  [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH
-C1E1..C1FB    ; LVT # Lo  [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH
-C1FD..C217    ; LVT # Lo  [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH
-C219..C233    ; LVT # Lo  [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH
-C235..C24F    ; LVT # Lo  [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH
-C251..C26B    ; LVT # Lo  [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH
-C26D..C287    ; LVT # Lo  [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH
-C289..C2A3    ; LVT # Lo  [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH
-C2A5..C2BF    ; LVT # Lo  [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH
-C2C1..C2DB    ; LVT # Lo  [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH
-C2DD..C2F7    ; LVT # Lo  [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH
-C2F9..C313    ; LVT # Lo  [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH
-C315..C32F    ; LVT # Lo  [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH
-C331..C34B    ; LVT # Lo  [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH
-C34D..C367    ; LVT # Lo  [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH
-C369..C383    ; LVT # Lo  [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH
-C385..C39F    ; LVT # Lo  [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH
-C3A1..C3BB    ; LVT # Lo  [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH
-C3BD..C3D7    ; LVT # Lo  [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH
-C3D9..C3F3    ; LVT # Lo  [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH
-C3F5..C40F    ; LVT # Lo  [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH
-C411..C42B    ; LVT # Lo  [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH
-C42D..C447    ; LVT # Lo  [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH
-C449..C463    ; LVT # Lo  [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH
-C465..C47F    ; LVT # Lo  [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH
-C481..C49B    ; LVT # Lo  [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH
-C49D..C4B7    ; LVT # Lo  [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH
-C4B9..C4D3    ; LVT # Lo  [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH
-C4D5..C4EF    ; LVT # Lo  [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH
-C4F1..C50B    ; LVT # Lo  [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH
-C50D..C527    ; LVT # Lo  [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH
-C529..C543    ; LVT # Lo  [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH
-C545..C55F    ; LVT # Lo  [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH
-C561..C57B    ; LVT # Lo  [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH
-C57D..C597    ; LVT # Lo  [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH
-C599..C5B3    ; LVT # Lo  [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH
-C5B5..C5CF    ; LVT # Lo  [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH
-C5D1..C5EB    ; LVT # Lo  [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH
-C5ED..C607    ; LVT # Lo  [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH
-C609..C623    ; LVT # Lo  [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH
-C625..C63F    ; LVT # Lo  [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH
-C641..C65B    ; LVT # Lo  [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH
-C65D..C677    ; LVT # Lo  [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH
-C679..C693    ; LVT # Lo  [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH
-C695..C6AF    ; LVT # Lo  [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH
-C6B1..C6CB    ; LVT # Lo  [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH
-C6CD..C6E7    ; LVT # Lo  [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH
-C6E9..C703    ; LVT # Lo  [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH
-C705..C71F    ; LVT # Lo  [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH
-C721..C73B    ; LVT # Lo  [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH
-C73D..C757    ; LVT # Lo  [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH
-C759..C773    ; LVT # Lo  [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH
-C775..C78F    ; LVT # Lo  [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH
-C791..C7AB    ; LVT # Lo  [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH
-C7AD..C7C7    ; LVT # Lo  [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH
-C7C9..C7E3    ; LVT # Lo  [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH
-C7E5..C7FF    ; LVT # Lo  [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH
-C801..C81B    ; LVT # Lo  [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH
-C81D..C837    ; LVT # Lo  [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH
-C839..C853    ; LVT # Lo  [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH
-C855..C86F    ; LVT # Lo  [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH
-C871..C88B    ; LVT # Lo  [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH
-C88D..C8A7    ; LVT # Lo  [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH
-C8A9..C8C3    ; LVT # Lo  [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH
-C8C5..C8DF    ; LVT # Lo  [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH
-C8E1..C8FB    ; LVT # Lo  [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH
-C8FD..C917    ; LVT # Lo  [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH
-C919..C933    ; LVT # Lo  [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH
-C935..C94F    ; LVT # Lo  [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH
-C951..C96B    ; LVT # Lo  [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH
-C96D..C987    ; LVT # Lo  [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH
-C989..C9A3    ; LVT # Lo  [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH
-C9A5..C9BF    ; LVT # Lo  [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH
-C9C1..C9DB    ; LVT # Lo  [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH
-C9DD..C9F7    ; LVT # Lo  [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH
-C9F9..CA13    ; LVT # Lo  [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH
-CA15..CA2F    ; LVT # Lo  [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH
-CA31..CA4B    ; LVT # Lo  [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH
-CA4D..CA67    ; LVT # Lo  [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH
-CA69..CA83    ; LVT # Lo  [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH
-CA85..CA9F    ; LVT # Lo  [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH
-CAA1..CABB    ; LVT # Lo  [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH
-CABD..CAD7    ; LVT # Lo  [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH
-CAD9..CAF3    ; LVT # Lo  [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH
-CAF5..CB0F    ; LVT # Lo  [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH
-CB11..CB2B    ; LVT # Lo  [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH
-CB2D..CB47    ; LVT # Lo  [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH
-CB49..CB63    ; LVT # Lo  [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH
-CB65..CB7F    ; LVT # Lo  [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH
-CB81..CB9B    ; LVT # Lo  [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH
-CB9D..CBB7    ; LVT # Lo  [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH
-CBB9..CBD3    ; LVT # Lo  [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH
-CBD5..CBEF    ; LVT # Lo  [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH
-CBF1..CC0B    ; LVT # Lo  [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH
-CC0D..CC27    ; LVT # Lo  [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH
-CC29..CC43    ; LVT # Lo  [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH
-CC45..CC5F    ; LVT # Lo  [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH
-CC61..CC7B    ; LVT # Lo  [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH
-CC7D..CC97    ; LVT # Lo  [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH
-CC99..CCB3    ; LVT # Lo  [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH
-CCB5..CCCF    ; LVT # Lo  [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH
-CCD1..CCEB    ; LVT # Lo  [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH
-CCED..CD07    ; LVT # Lo  [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH
-CD09..CD23    ; LVT # Lo  [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH
-CD25..CD3F    ; LVT # Lo  [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH
-CD41..CD5B    ; LVT # Lo  [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH
-CD5D..CD77    ; LVT # Lo  [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH
-CD79..CD93    ; LVT # Lo  [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH
-CD95..CDAF    ; LVT # Lo  [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH
-CDB1..CDCB    ; LVT # Lo  [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH
-CDCD..CDE7    ; LVT # Lo  [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH
-CDE9..CE03    ; LVT # Lo  [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH
-CE05..CE1F    ; LVT # Lo  [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH
-CE21..CE3B    ; LVT # Lo  [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH
-CE3D..CE57    ; LVT # Lo  [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH
-CE59..CE73    ; LVT # Lo  [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH
-CE75..CE8F    ; LVT # Lo  [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH
-CE91..CEAB    ; LVT # Lo  [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH
-CEAD..CEC7    ; LVT # Lo  [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH
-CEC9..CEE3    ; LVT # Lo  [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH
-CEE5..CEFF    ; LVT # Lo  [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH
-CF01..CF1B    ; LVT # Lo  [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH
-CF1D..CF37    ; LVT # Lo  [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH
-CF39..CF53    ; LVT # Lo  [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH
-CF55..CF6F    ; LVT # Lo  [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH
-CF71..CF8B    ; LVT # Lo  [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH
-CF8D..CFA7    ; LVT # Lo  [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH
-CFA9..CFC3    ; LVT # Lo  [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH
-CFC5..CFDF    ; LVT # Lo  [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH
-CFE1..CFFB    ; LVT # Lo  [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH
-CFFD..D017    ; LVT # Lo  [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH
-D019..D033    ; LVT # Lo  [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH
-D035..D04F    ; LVT # Lo  [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH
-D051..D06B    ; LVT # Lo  [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH
-D06D..D087    ; LVT # Lo  [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH
-D089..D0A3    ; LVT # Lo  [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH
-D0A5..D0BF    ; LVT # Lo  [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH
-D0C1..D0DB    ; LVT # Lo  [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH
-D0DD..D0F7    ; LVT # Lo  [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH
-D0F9..D113    ; LVT # Lo  [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH
-D115..D12F    ; LVT # Lo  [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH
-D131..D14B    ; LVT # Lo  [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH
-D14D..D167    ; LVT # Lo  [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH
-D169..D183    ; LVT # Lo  [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH
-D185..D19F    ; LVT # Lo  [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH
-D1A1..D1BB    ; LVT # Lo  [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH
-D1BD..D1D7    ; LVT # Lo  [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH
-D1D9..D1F3    ; LVT # Lo  [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH
-D1F5..D20F    ; LVT # Lo  [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH
-D211..D22B    ; LVT # Lo  [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH
-D22D..D247    ; LVT # Lo  [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH
-D249..D263    ; LVT # Lo  [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH
-D265..D27F    ; LVT # Lo  [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH
-D281..D29B    ; LVT # Lo  [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH
-D29D..D2B7    ; LVT # Lo  [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH
-D2B9..D2D3    ; LVT # Lo  [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH
-D2D5..D2EF    ; LVT # Lo  [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH
-D2F1..D30B    ; LVT # Lo  [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH
-D30D..D327    ; LVT # Lo  [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH
-D329..D343    ; LVT # Lo  [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH
-D345..D35F    ; LVT # Lo  [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH
-D361..D37B    ; LVT # Lo  [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH
-D37D..D397    ; LVT # Lo  [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH
-D399..D3B3    ; LVT # Lo  [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH
-D3B5..D3CF    ; LVT # Lo  [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH
-D3D1..D3EB    ; LVT # Lo  [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH
-D3ED..D407    ; LVT # Lo  [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH
-D409..D423    ; LVT # Lo  [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH
-D425..D43F    ; LVT # Lo  [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH
-D441..D45B    ; LVT # Lo  [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH
-D45D..D477    ; LVT # Lo  [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH
-D479..D493    ; LVT # Lo  [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH
-D495..D4AF    ; LVT # Lo  [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH
-D4B1..D4CB    ; LVT # Lo  [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH
-D4CD..D4E7    ; LVT # Lo  [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH
-D4E9..D503    ; LVT # Lo  [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH
-D505..D51F    ; LVT # Lo  [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH
-D521..D53B    ; LVT # Lo  [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH
-D53D..D557    ; LVT # Lo  [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH
-D559..D573    ; LVT # Lo  [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH
-D575..D58F    ; LVT # Lo  [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH
-D591..D5AB    ; LVT # Lo  [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH
-D5AD..D5C7    ; LVT # Lo  [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH
-D5C9..D5E3    ; LVT # Lo  [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH
-D5E5..D5FF    ; LVT # Lo  [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH
-D601..D61B    ; LVT # Lo  [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH
-D61D..D637    ; LVT # Lo  [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH
-D639..D653    ; LVT # Lo  [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH
-D655..D66F    ; LVT # Lo  [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH
-D671..D68B    ; LVT # Lo  [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH
-D68D..D6A7    ; LVT # Lo  [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH
-D6A9..D6C3    ; LVT # Lo  [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH
-D6C5..D6DF    ; LVT # Lo  [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH
-D6E1..D6FB    ; LVT # Lo  [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH
-D6FD..D717    ; LVT # Lo  [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH
-D719..D733    ; LVT # Lo  [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH
-D735..D74F    ; LVT # Lo  [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH
-D751..D76B    ; LVT # Lo  [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH
-D76D..D787    ; LVT # Lo  [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH
-D789..D7A3    ; LVT # Lo  [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH
-
-# Total code points: 10773
-
-# EOF
diff --git a/third_party/harfbuzz/contrib/tables/README b/third_party/harfbuzz/contrib/tables/README
deleted file mode 100644
index 605d1c0..0000000
--- a/third_party/harfbuzz/contrib/tables/README
+++ /dev/null
@@ -1,17 +0,0 @@
-This directory contains Python script to parse several of the Unicode tables
-that are downloadable from the web and generate C header files from them.
-
-These are the locations of the files which are parsed. You should download these
-files and put them in this directory.
-
-http://www.unicode.org/Public/5.1.0/ucd/extracted/DerivedGeneralCategory.txt
-http://www.unicode.org/Public/5.1.0/ucd/extracted/DerivedCombiningClass.txt
-http://www.unicode.org/Public/UNIDATA/auxiliary/GraphemeBreakProperty.txt
-http://www.unicode.org/Public/5.1.0/ucd/Scripts.txt
-
-Then you can run the following python scripts to generate the header files:
-
-python category-parse.py DerivedGeneralCategory.txt category-properties.h
-python combining-class-parse.py DerivedCombiningClass.txt combining-properties.h
-python grapheme-break-parse.py GraphemeBreakProperty.txt grapheme-break-properties.h
-python scripts-parse.py Scripts.txt script-properties.h
diff --git a/third_party/harfbuzz/contrib/tables/Scripts.txt b/third_party/harfbuzz/contrib/tables/Scripts.txt
deleted file mode 100644
index 7065486..0000000
--- a/third_party/harfbuzz/contrib/tables/Scripts.txt
+++ /dev/null
@@ -1,1747 +0,0 @@
-# Scripts-5.1.0.txt
-# Date: 2008-03-20, 17:55:33 GMT [MD]
-#
-# Unicode Character Database
-# Copyright (c) 1991-2008 Unicode, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-# For documentation, see UCD.html
-
-# ================================================
-
-# Property:	Script
-
-#  All code points not explicitly listed for Script
-#  have the value Unknown (Zzzz).
-
-# @missing: 0000..10FFFF; Unknown
-
-# ================================================
-
-0000..001F    ; Common # Cc  [32] <control-0000>..<control-001F>
-0020          ; Common # Zs       SPACE
-0021..0023    ; Common # Po   [3] EXCLAMATION MARK..NUMBER SIGN
-0024          ; Common # Sc       DOLLAR SIGN
-0025..0027    ; Common # Po   [3] PERCENT SIGN..APOSTROPHE
-0028          ; Common # Ps       LEFT PARENTHESIS
-0029          ; Common # Pe       RIGHT PARENTHESIS
-002A          ; Common # Po       ASTERISK
-002B          ; Common # Sm       PLUS SIGN
-002C          ; Common # Po       COMMA
-002D          ; Common # Pd       HYPHEN-MINUS
-002E..002F    ; Common # Po   [2] FULL STOP..SOLIDUS
-0030..0039    ; Common # Nd  [10] DIGIT ZERO..DIGIT NINE
-003A..003B    ; Common # Po   [2] COLON..SEMICOLON
-003C..003E    ; Common # Sm   [3] LESS-THAN SIGN..GREATER-THAN SIGN
-003F..0040    ; Common # Po   [2] QUESTION MARK..COMMERCIAL AT
-005B          ; Common # Ps       LEFT SQUARE BRACKET
-005C          ; Common # Po       REVERSE SOLIDUS
-005D          ; Common # Pe       RIGHT SQUARE BRACKET
-005E          ; Common # Sk       CIRCUMFLEX ACCENT
-005F          ; Common # Pc       LOW LINE
-0060          ; Common # Sk       GRAVE ACCENT
-007B          ; Common # Ps       LEFT CURLY BRACKET
-007C          ; Common # Sm       VERTICAL LINE
-007D          ; Common # Pe       RIGHT CURLY BRACKET
-007E          ; Common # Sm       TILDE
-007F..009F    ; Common # Cc  [33] <control-007F>..<control-009F>
-00A0          ; Common # Zs       NO-BREAK SPACE
-00A1          ; Common # Po       INVERTED EXCLAMATION MARK
-00A2..00A5    ; Common # Sc   [4] CENT SIGN..YEN SIGN
-00A6..00A7    ; Common # So   [2] BROKEN BAR..SECTION SIGN
-00A8          ; Common # Sk       DIAERESIS
-00A9          ; Common # So       COPYRIGHT SIGN
-00AB          ; Common # Pi       LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
-00AC          ; Common # Sm       NOT SIGN
-00AD          ; Common # Cf       SOFT HYPHEN
-00AE          ; Common # So       REGISTERED SIGN
-00AF          ; Common # Sk       MACRON
-00B0          ; Common # So       DEGREE SIGN
-00B1          ; Common # Sm       PLUS-MINUS SIGN
-00B2..00B3    ; Common # No   [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE
-00B4          ; Common # Sk       ACUTE ACCENT
-00B5          ; Common # L&       MICRO SIGN
-00B6          ; Common # So       PILCROW SIGN
-00B7          ; Common # Po       MIDDLE DOT
-00B8          ; Common # Sk       CEDILLA
-00B9          ; Common # No       SUPERSCRIPT ONE
-00BB          ; Common # Pf       RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-00BC..00BE    ; Common # No   [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS
-00BF          ; Common # Po       INVERTED QUESTION MARK
-00D7          ; Common # Sm       MULTIPLICATION SIGN
-00F7          ; Common # Sm       DIVISION SIGN
-02B9..02C1    ; Common # Lm   [9] MODIFIER LETTER PRIME..MODIFIER LETTER REVERSED GLOTTAL STOP
-02C2..02C5    ; Common # Sk   [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD
-02C6..02D1    ; Common # Lm  [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON
-02D2..02DF    ; Common # Sk  [14] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER CROSS ACCENT
-02E5..02EB    ; Common # Sk   [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK
-02EC          ; Common # Lm       MODIFIER LETTER VOICING
-02ED          ; Common # Sk       MODIFIER LETTER UNASPIRATED
-02EE          ; Common # Lm       MODIFIER LETTER DOUBLE APOSTROPHE
-02EF..02FF    ; Common # Sk  [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW
-0374          ; Common # Lm       GREEK NUMERAL SIGN
-037E          ; Common # Po       GREEK QUESTION MARK
-0385          ; Common # Sk       GREEK DIALYTIKA TONOS
-0387          ; Common # Po       GREEK ANO TELEIA
-0589          ; Common # Po       ARMENIAN FULL STOP
-0600..0603    ; Common # Cf   [4] ARABIC NUMBER SIGN..ARABIC SIGN SAFHA
-060C          ; Common # Po       ARABIC COMMA
-061B          ; Common # Po       ARABIC SEMICOLON
-061F          ; Common # Po       ARABIC QUESTION MARK
-0640          ; Common # Lm       ARABIC TATWEEL
-0660..0669    ; Common # Nd  [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE
-06DD          ; Common # Cf       ARABIC END OF AYAH
-0964..0965    ; Common # Po   [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA
-0970          ; Common # Po       DEVANAGARI ABBREVIATION SIGN
-0CF1..0CF2    ; Common # So   [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
-0E3F          ; Common # Sc       THAI CURRENCY SYMBOL BAHT
-10FB          ; Common # Po       GEORGIAN PARAGRAPH SEPARATOR
-16EB..16ED    ; Common # Po   [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION
-1735..1736    ; Common # Po   [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION
-1802..1803    ; Common # Po   [2] MONGOLIAN COMMA..MONGOLIAN FULL STOP
-1805          ; Common # Po       MONGOLIAN FOUR DOTS
-2000..200A    ; Common # Zs  [11] EN QUAD..HAIR SPACE
-200B          ; Common # Cf       ZERO WIDTH SPACE
-200E..200F    ; Common # Cf   [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
-2010..2015    ; Common # Pd   [6] HYPHEN..HORIZONTAL BAR
-2016..2017    ; Common # Po   [2] DOUBLE VERTICAL LINE..DOUBLE LOW LINE
-2018          ; Common # Pi       LEFT SINGLE QUOTATION MARK
-2019          ; Common # Pf       RIGHT SINGLE QUOTATION MARK
-201A          ; Common # Ps       SINGLE LOW-9 QUOTATION MARK
-201B..201C    ; Common # Pi   [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK
-201D          ; Common # Pf       RIGHT DOUBLE QUOTATION MARK
-201E          ; Common # Ps       DOUBLE LOW-9 QUOTATION MARK
-201F          ; Common # Pi       DOUBLE HIGH-REVERSED-9 QUOTATION MARK
-2020..2027    ; Common # Po   [8] DAGGER..HYPHENATION POINT
-2028          ; Common # Zl       LINE SEPARATOR
-2029          ; Common # Zp       PARAGRAPH SEPARATOR
-202A..202E    ; Common # Cf   [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
-202F          ; Common # Zs       NARROW NO-BREAK SPACE
-2030..2038    ; Common # Po   [9] PER MILLE SIGN..CARET
-2039          ; Common # Pi       SINGLE LEFT-POINTING ANGLE QUOTATION MARK
-203A          ; Common # Pf       SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
-203B..203E    ; Common # Po   [4] REFERENCE MARK..OVERLINE
-203F..2040    ; Common # Pc   [2] UNDERTIE..CHARACTER TIE
-2041..2043    ; Common # Po   [3] CARET INSERTION POINT..HYPHEN BULLET
-2044          ; Common # Sm       FRACTION SLASH
-2045          ; Common # Ps       LEFT SQUARE BRACKET WITH QUILL
-2046          ; Common # Pe       RIGHT SQUARE BRACKET WITH QUILL
-2047..2051    ; Common # Po  [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY
-2052          ; Common # Sm       COMMERCIAL MINUS SIGN
-2053          ; Common # Po       SWUNG DASH
-2054          ; Common # Pc       INVERTED UNDERTIE
-2055..205E    ; Common # Po  [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS
-205F          ; Common # Zs       MEDIUM MATHEMATICAL SPACE
-2060..2064    ; Common # Cf   [5] WORD JOINER..INVISIBLE PLUS
-206A..206F    ; Common # Cf   [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
-2070          ; Common # No       SUPERSCRIPT ZERO
-2074..2079    ; Common # No   [6] SUPERSCRIPT FOUR..SUPERSCRIPT NINE
-207A..207C    ; Common # Sm   [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN
-207D          ; Common # Ps       SUPERSCRIPT LEFT PARENTHESIS
-207E          ; Common # Pe       SUPERSCRIPT RIGHT PARENTHESIS
-2080..2089    ; Common # No  [10] SUBSCRIPT ZERO..SUBSCRIPT NINE
-208A..208C    ; Common # Sm   [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN
-208D          ; Common # Ps       SUBSCRIPT LEFT PARENTHESIS
-208E          ; Common # Pe       SUBSCRIPT RIGHT PARENTHESIS
-20A0..20B5    ; Common # Sc  [22] EURO-CURRENCY SIGN..CEDI SIGN
-2100..2101    ; Common # So   [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT
-2102          ; Common # L&       DOUBLE-STRUCK CAPITAL C
-2103..2106    ; Common # So   [4] DEGREE CELSIUS..CADA UNA
-2107          ; Common # L&       EULER CONSTANT
-2108..2109    ; Common # So   [2] SCRUPLE..DEGREE FAHRENHEIT
-210A..2113    ; Common # L&  [10] SCRIPT SMALL G..SCRIPT SMALL L
-2114          ; Common # So       L B BAR SYMBOL
-2115          ; Common # L&       DOUBLE-STRUCK CAPITAL N
-2116..2118    ; Common # So   [3] NUMERO SIGN..SCRIPT CAPITAL P
-2119..211D    ; Common # L&   [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R
-211E..2123    ; Common # So   [6] PRESCRIPTION TAKE..VERSICLE
-2124          ; Common # L&       DOUBLE-STRUCK CAPITAL Z
-2125          ; Common # So       OUNCE SIGN
-2127          ; Common # So       INVERTED OHM SIGN
-2128          ; Common # L&       BLACK-LETTER CAPITAL Z
-2129          ; Common # So       TURNED GREEK SMALL LETTER IOTA
-212C..212D    ; Common # L&   [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C
-212E          ; Common # So       ESTIMATED SYMBOL
-212F..2131    ; Common # L&   [3] SCRIPT SMALL E..SCRIPT CAPITAL F
-2133..2134    ; Common # L&   [2] SCRIPT CAPITAL M..SCRIPT SMALL O
-2135..2138    ; Common # Lo   [4] ALEF SYMBOL..DALET SYMBOL
-2139          ; Common # L&       INFORMATION SOURCE
-213A..213B    ; Common # So   [2] ROTATED CAPITAL Q..FACSIMILE SIGN
-213C..213F    ; Common # L&   [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI
-2140..2144    ; Common # Sm   [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y
-2145..2149    ; Common # L&   [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J
-214A          ; Common # So       PROPERTY LINE
-214B          ; Common # Sm       TURNED AMPERSAND
-214C..214D    ; Common # So   [2] PER SIGN..AKTIESELSKAB
-214F          ; Common # So       SYMBOL FOR SAMARITAN SOURCE
-2153..215F    ; Common # No  [13] VULGAR FRACTION ONE THIRD..FRACTION NUMERATOR ONE
-2190..2194    ; Common # Sm   [5] LEFTWARDS ARROW..LEFT RIGHT ARROW
-2195..2199    ; Common # So   [5] UP DOWN ARROW..SOUTH WEST ARROW
-219A..219B    ; Common # Sm   [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE
-219C..219F    ; Common # So   [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW
-21A0          ; Common # Sm       RIGHTWARDS TWO HEADED ARROW
-21A1..21A2    ; Common # So   [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL
-21A3          ; Common # Sm       RIGHTWARDS ARROW WITH TAIL
-21A4..21A5    ; Common # So   [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR
-21A6          ; Common # Sm       RIGHTWARDS ARROW FROM BAR
-21A7..21AD    ; Common # So   [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW
-21AE          ; Common # Sm       LEFT RIGHT ARROW WITH STROKE
-21AF..21CD    ; Common # So  [31] DOWNWARDS ZIGZAG ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE
-21CE..21CF    ; Common # Sm   [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE
-21D0..21D1    ; Common # So   [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW
-21D2          ; Common # Sm       RIGHTWARDS DOUBLE ARROW
-21D3          ; Common # So       DOWNWARDS DOUBLE ARROW
-21D4          ; Common # Sm       LEFT RIGHT DOUBLE ARROW
-21D5..21F3    ; Common # So  [31] UP DOWN DOUBLE ARROW..UP DOWN WHITE ARROW
-21F4..22FF    ; Common # Sm [268] RIGHT ARROW WITH SMALL CIRCLE..Z NOTATION BAG MEMBERSHIP
-2300..2307    ; Common # So   [8] DIAMETER SIGN..WAVY LINE
-2308..230B    ; Common # Sm   [4] LEFT CEILING..RIGHT FLOOR
-230C..231F    ; Common # So  [20] BOTTOM RIGHT CROP..BOTTOM RIGHT CORNER
-2320..2321    ; Common # Sm   [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL
-2322..2328    ; Common # So   [7] FROWN..KEYBOARD
-2329          ; Common # Ps       LEFT-POINTING ANGLE BRACKET
-232A          ; Common # Pe       RIGHT-POINTING ANGLE BRACKET
-232B..237B    ; Common # So  [81] ERASE TO THE LEFT..NOT CHECK MARK
-237C          ; Common # Sm       RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
-237D..239A    ; Common # So  [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL
-239B..23B3    ; Common # Sm  [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM
-23B4..23DB    ; Common # So  [40] TOP SQUARE BRACKET..FUSE
-23DC..23E1    ; Common # Sm   [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET
-23E2..23E7    ; Common # So   [6] WHITE TRAPEZIUM..ELECTRICAL INTERSECTION
-2400..2426    ; Common # So  [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO
-2440..244A    ; Common # So  [11] OCR HOOK..OCR DOUBLE BACKSLASH
-2460..249B    ; Common # No  [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP
-249C..24E9    ; Common # So  [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z
-24EA..24FF    ; Common # No  [22] CIRCLED DIGIT ZERO..NEGATIVE CIRCLED DIGIT ZERO
-2500..25B6    ; Common # So [183] BOX DRAWINGS LIGHT HORIZONTAL..BLACK RIGHT-POINTING TRIANGLE
-25B7          ; Common # Sm       WHITE RIGHT-POINTING TRIANGLE
-25B8..25C0    ; Common # So   [9] BLACK RIGHT-POINTING SMALL TRIANGLE..BLACK LEFT-POINTING TRIANGLE
-25C1          ; Common # Sm       WHITE LEFT-POINTING TRIANGLE
-25C2..25F7    ; Common # So  [54] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE CIRCLE WITH UPPER RIGHT QUADRANT
-25F8..25FF    ; Common # Sm   [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE
-2600..266E    ; Common # So [111] BLACK SUN WITH RAYS..MUSIC NATURAL SIGN
-266F          ; Common # Sm       MUSIC SHARP SIGN
-2670..269D    ; Common # So  [46] WEST SYRIAC CROSS..OUTLINED WHITE STAR
-26A0..26BC    ; Common # So  [29] WARNING SIGN..SESQUIQUADRATE
-26C0..26C3    ; Common # So   [4] WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING
-2701..2704    ; Common # So   [4] UPPER BLADE SCISSORS..WHITE SCISSORS
-2706..2709    ; Common # So   [4] TELEPHONE LOCATION SIGN..ENVELOPE
-270C..2727    ; Common # So  [28] VICTORY HAND..WHITE FOUR POINTED STAR
-2729..274B    ; Common # So  [35] STRESS OUTLINED WHITE STAR..HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
-274D          ; Common # So       SHADOWED WHITE CIRCLE
-274F..2752    ; Common # So   [4] LOWER RIGHT DROP-SHADOWED WHITE SQUARE..UPPER RIGHT SHADOWED WHITE SQUARE
-2756          ; Common # So       BLACK DIAMOND MINUS WHITE X
-2758..275E    ; Common # So   [7] LIGHT VERTICAL BAR..HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT
-2761..2767    ; Common # So   [7] CURVED STEM PARAGRAPH SIGN ORNAMENT..ROTATED FLORAL HEART BULLET
-2768          ; Common # Ps       MEDIUM LEFT PARENTHESIS ORNAMENT
-2769          ; Common # Pe       MEDIUM RIGHT PARENTHESIS ORNAMENT
-276A          ; Common # Ps       MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
-276B          ; Common # Pe       MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
-276C          ; Common # Ps       MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
-276D          ; Common # Pe       MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
-276E          ; Common # Ps       HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
-276F          ; Common # Pe       HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
-2770          ; Common # Ps       HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
-2771          ; Common # Pe       HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
-2772          ; Common # Ps       LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
-2773          ; Common # Pe       LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
-2774          ; Common # Ps       MEDIUM LEFT CURLY BRACKET ORNAMENT
-2775          ; Common # Pe       MEDIUM RIGHT CURLY BRACKET ORNAMENT
-2776..2793    ; Common # No  [30] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
-2794          ; Common # So       HEAVY WIDE-HEADED RIGHTWARDS ARROW
-2798..27AF    ; Common # So  [24] HEAVY SOUTH EAST ARROW..NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
-27B1..27BE    ; Common # So  [14] NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW..OPEN-OUTLINED RIGHTWARDS ARROW
-27C0..27C4    ; Common # Sm   [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET
-27C5          ; Common # Ps       LEFT S-SHAPED BAG DELIMITER
-27C6          ; Common # Pe       RIGHT S-SHAPED BAG DELIMITER
-27C7..27CA    ; Common # Sm   [4] OR WITH DOT INSIDE..VERTICAL BAR WITH HORIZONTAL STROKE
-27CC          ; Common # Sm       LONG DIVISION
-27D0..27E5    ; Common # Sm  [22] WHITE DIAMOND WITH CENTRED DOT..WHITE SQUARE WITH RIGHTWARDS TICK
-27E6          ; Common # Ps       MATHEMATICAL LEFT WHITE SQUARE BRACKET
-27E7          ; Common # Pe       MATHEMATICAL RIGHT WHITE SQUARE BRACKET
-27E8          ; Common # Ps       MATHEMATICAL LEFT ANGLE BRACKET
-27E9          ; Common # Pe       MATHEMATICAL RIGHT ANGLE BRACKET
-27EA          ; Common # Ps       MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
-27EB          ; Common # Pe       MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
-27EC          ; Common # Ps       MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
-27ED          ; Common # Pe       MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
-27EE          ; Common # Ps       MATHEMATICAL LEFT FLATTENED PARENTHESIS
-27EF          ; Common # Pe       MATHEMATICAL RIGHT FLATTENED PARENTHESIS
-27F0..27FF    ; Common # Sm  [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW
-2900..2982    ; Common # Sm [131] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..Z NOTATION TYPE COLON
-2983          ; Common # Ps       LEFT WHITE CURLY BRACKET
-2984          ; Common # Pe       RIGHT WHITE CURLY BRACKET
-2985          ; Common # Ps       LEFT WHITE PARENTHESIS
-2986          ; Common # Pe       RIGHT WHITE PARENTHESIS
-2987          ; Common # Ps       Z NOTATION LEFT IMAGE BRACKET
-2988          ; Common # Pe       Z NOTATION RIGHT IMAGE BRACKET
-2989          ; Common # Ps       Z NOTATION LEFT BINDING BRACKET
-298A          ; Common # Pe       Z NOTATION RIGHT BINDING BRACKET
-298B          ; Common # Ps       LEFT SQUARE BRACKET WITH UNDERBAR
-298C          ; Common # Pe       RIGHT SQUARE BRACKET WITH UNDERBAR
-298D          ; Common # Ps       LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
-298E          ; Common # Pe       RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
-298F          ; Common # Ps       LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
-2990          ; Common # Pe       RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
-2991          ; Common # Ps       LEFT ANGLE BRACKET WITH DOT
-2992          ; Common # Pe       RIGHT ANGLE BRACKET WITH DOT
-2993          ; Common # Ps       LEFT ARC LESS-THAN BRACKET
-2994          ; Common # Pe       RIGHT ARC GREATER-THAN BRACKET
-2995          ; Common # Ps       DOUBLE LEFT ARC GREATER-THAN BRACKET
-2996          ; Common # Pe       DOUBLE RIGHT ARC LESS-THAN BRACKET
-2997          ; Common # Ps       LEFT BLACK TORTOISE SHELL BRACKET
-2998          ; Common # Pe       RIGHT BLACK TORTOISE SHELL BRACKET
-2999..29D7    ; Common # Sm  [63] DOTTED FENCE..BLACK HOURGLASS
-29D8          ; Common # Ps       LEFT WIGGLY FENCE
-29D9          ; Common # Pe       RIGHT WIGGLY FENCE
-29DA          ; Common # Ps       LEFT DOUBLE WIGGLY FENCE
-29DB          ; Common # Pe       RIGHT DOUBLE WIGGLY FENCE
-29DC..29FB    ; Common # Sm  [32] INCOMPLETE INFINITY..TRIPLE PLUS
-29FC          ; Common # Ps       LEFT-POINTING CURVED ANGLE BRACKET
-29FD          ; Common # Pe       RIGHT-POINTING CURVED ANGLE BRACKET
-29FE..2AFF    ; Common # Sm [258] TINY..N-ARY WHITE VERTICAL BAR
-2B00..2B2F    ; Common # So  [48] NORTH EAST WHITE ARROW..WHITE VERTICAL ELLIPSE
-2B30..2B44    ; Common # Sm  [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET
-2B45..2B46    ; Common # So   [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW
-2B47..2B4C    ; Common # Sm   [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
-2B50..2B54    ; Common # So   [5] WHITE MEDIUM STAR..WHITE RIGHT-POINTING PENTAGON
-2E00..2E01    ; Common # Po   [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
-2E02          ; Common # Pi       LEFT SUBSTITUTION BRACKET
-2E03          ; Common # Pf       RIGHT SUBSTITUTION BRACKET
-2E04          ; Common # Pi       LEFT DOTTED SUBSTITUTION BRACKET
-2E05          ; Common # Pf       RIGHT DOTTED SUBSTITUTION BRACKET
-2E06..2E08    ; Common # Po   [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER
-2E09          ; Common # Pi       LEFT TRANSPOSITION BRACKET
-2E0A          ; Common # Pf       RIGHT TRANSPOSITION BRACKET
-2E0B          ; Common # Po       RAISED SQUARE
-2E0C          ; Common # Pi       LEFT RAISED OMISSION BRACKET
-2E0D          ; Common # Pf       RIGHT RAISED OMISSION BRACKET
-2E0E..2E16    ; Common # Po   [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE
-2E17          ; Common # Pd       DOUBLE OBLIQUE HYPHEN
-2E18..2E19    ; Common # Po   [2] INVERTED INTERROBANG..PALM BRANCH
-2E1A          ; Common # Pd       HYPHEN WITH DIAERESIS
-2E1B          ; Common # Po       TILDE WITH RING ABOVE
-2E1C          ; Common # Pi       LEFT LOW PARAPHRASE BRACKET
-2E1D          ; Common # Pf       RIGHT LOW PARAPHRASE BRACKET
-2E1E..2E1F    ; Common # Po   [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW
-2E20          ; Common # Pi       LEFT VERTICAL BAR WITH QUILL
-2E21          ; Common # Pf       RIGHT VERTICAL BAR WITH QUILL
-2E22          ; Common # Ps       TOP LEFT HALF BRACKET
-2E23          ; Common # Pe       TOP RIGHT HALF BRACKET
-2E24          ; Common # Ps       BOTTOM LEFT HALF BRACKET
-2E25          ; Common # Pe       BOTTOM RIGHT HALF BRACKET
-2E26          ; Common # Ps       LEFT SIDEWAYS U BRACKET
-2E27          ; Common # Pe       RIGHT SIDEWAYS U BRACKET
-2E28          ; Common # Ps       LEFT DOUBLE PARENTHESIS
-2E29          ; Common # Pe       RIGHT DOUBLE PARENTHESIS
-2E2A..2E2E    ; Common # Po   [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK
-2E2F          ; Common # Lm       VERTICAL TILDE
-2E30          ; Common # Po       RING POINT
-2FF0..2FFB    ; Common # So  [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
-3000          ; Common # Zs       IDEOGRAPHIC SPACE
-3001..3003    ; Common # Po   [3] IDEOGRAPHIC COMMA..DITTO MARK
-3004          ; Common # So       JAPANESE INDUSTRIAL STANDARD SYMBOL
-3006          ; Common # Lo       IDEOGRAPHIC CLOSING MARK
-3008          ; Common # Ps       LEFT ANGLE BRACKET
-3009          ; Common # Pe       RIGHT ANGLE BRACKET
-300A          ; Common # Ps       LEFT DOUBLE ANGLE BRACKET
-300B          ; Common # Pe       RIGHT DOUBLE ANGLE BRACKET
-300C          ; Common # Ps       LEFT CORNER BRACKET
-300D          ; Common # Pe       RIGHT CORNER BRACKET
-300E          ; Common # Ps       LEFT WHITE CORNER BRACKET
-300F          ; Common # Pe       RIGHT WHITE CORNER BRACKET
-3010          ; Common # Ps       LEFT BLACK LENTICULAR BRACKET
-3011          ; Common # Pe       RIGHT BLACK LENTICULAR BRACKET
-3012..3013    ; Common # So   [2] POSTAL MARK..GETA MARK
-3014          ; Common # Ps       LEFT TORTOISE SHELL BRACKET
-3015          ; Common # Pe       RIGHT TORTOISE SHELL BRACKET
-3016          ; Common # Ps       LEFT WHITE LENTICULAR BRACKET
-3017          ; Common # Pe       RIGHT WHITE LENTICULAR BRACKET
-3018          ; Common # Ps       LEFT WHITE TORTOISE SHELL BRACKET
-3019          ; Common # Pe       RIGHT WHITE TORTOISE SHELL BRACKET
-301A          ; Common # Ps       LEFT WHITE SQUARE BRACKET
-301B          ; Common # Pe       RIGHT WHITE SQUARE BRACKET
-301C          ; Common # Pd       WAVE DASH
-301D          ; Common # Ps       REVERSED DOUBLE PRIME QUOTATION MARK
-301E..301F    ; Common # Pe   [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK
-3020          ; Common # So       POSTAL MARK FACE
-3030          ; Common # Pd       WAVY DASH
-3031..3035    ; Common # Lm   [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF
-3036..3037    ; Common # So   [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL
-303C          ; Common # Lo       MASU MARK
-303D          ; Common # Po       PART ALTERNATION MARK
-303E..303F    ; Common # So   [2] IDEOGRAPHIC VARIATION INDICATOR..IDEOGRAPHIC HALF FILL SPACE
-309B..309C    ; Common # Sk   [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
-30A0          ; Common # Pd       KATAKANA-HIRAGANA DOUBLE HYPHEN
-30FB          ; Common # Po       KATAKANA MIDDLE DOT
-30FC          ; Common # Lm       KATAKANA-HIRAGANA PROLONGED SOUND MARK
-3190..3191    ; Common # So   [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK
-3192..3195    ; Common # No   [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK
-3196..319F    ; Common # So  [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK
-31C0..31E3    ; Common # So  [36] CJK STROKE T..CJK STROKE Q
-3220..3229    ; Common # No  [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN
-322A..3243    ; Common # So  [26] PARENTHESIZED IDEOGRAPH MOON..PARENTHESIZED IDEOGRAPH REACH
-3250          ; Common # So       PARTNERSHIP SIGN
-3251..325F    ; Common # No  [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE
-327F          ; Common # So       KOREAN STANDARD SYMBOL
-3280..3289    ; Common # No  [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN
-328A..32B0    ; Common # So  [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT
-32B1..32BF    ; Common # No  [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY
-32C0..32CF    ; Common # So  [16] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..LIMITED LIABILITY SIGN
-3358..33FF    ; Common # So [168] IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO..SQUARE GAL
-4DC0..4DFF    ; Common # So  [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION
-A700..A716    ; Common # Sk  [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR
-A717..A71F    ; Common # Lm   [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK
-A720..A721    ; Common # Sk   [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE
-A788          ; Common # Lm       MODIFIER LETTER LOW CIRCUMFLEX ACCENT
-A789..A78A    ; Common # Sk   [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN
-FD3E          ; Common # Ps       ORNATE LEFT PARENTHESIS
-FD3F          ; Common # Pe       ORNATE RIGHT PARENTHESIS
-FDFD          ; Common # So       ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM
-FE10..FE16    ; Common # Po   [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK
-FE17          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
-FE18          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET
-FE19          ; Common # Po       PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
-FE30          ; Common # Po       PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
-FE31..FE32    ; Common # Pd   [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH
-FE33..FE34    ; Common # Pc   [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
-FE35          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
-FE36          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
-FE37          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
-FE38          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
-FE39          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
-FE3A          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
-FE3B          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
-FE3C          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
-FE3D          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
-FE3E          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
-FE3F          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
-FE40          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
-FE41          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
-FE42          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
-FE43          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
-FE44          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
-FE45..FE46    ; Common # Po   [2] SESAME DOT..WHITE SESAME DOT
-FE47          ; Common # Ps       PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
-FE48          ; Common # Pe       PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
-FE49..FE4C    ; Common # Po   [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE
-FE4D..FE4F    ; Common # Pc   [3] DASHED LOW LINE..WAVY LOW LINE
-FE50..FE52    ; Common # Po   [3] SMALL COMMA..SMALL FULL STOP
-FE54..FE57    ; Common # Po   [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK
-FE58          ; Common # Pd       SMALL EM DASH
-FE59          ; Common # Ps       SMALL LEFT PARENTHESIS
-FE5A          ; Common # Pe       SMALL RIGHT PARENTHESIS
-FE5B          ; Common # Ps       SMALL LEFT CURLY BRACKET
-FE5C          ; Common # Pe       SMALL RIGHT CURLY BRACKET
-FE5D          ; Common # Ps       SMALL LEFT TORTOISE SHELL BRACKET
-FE5E          ; Common # Pe       SMALL RIGHT TORTOISE SHELL BRACKET
-FE5F..FE61    ; Common # Po   [3] SMALL NUMBER SIGN..SMALL ASTERISK
-FE62          ; Common # Sm       SMALL PLUS SIGN
-FE63          ; Common # Pd       SMALL HYPHEN-MINUS
-FE64..FE66    ; Common # Sm   [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN
-FE68          ; Common # Po       SMALL REVERSE SOLIDUS
-FE69          ; Common # Sc       SMALL DOLLAR SIGN
-FE6A..FE6B    ; Common # Po   [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT
-FEFF          ; Common # Cf       ZERO WIDTH NO-BREAK SPACE
-FF01..FF03    ; Common # Po   [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN
-FF04          ; Common # Sc       FULLWIDTH DOLLAR SIGN
-FF05..FF07    ; Common # Po   [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE
-FF08          ; Common # Ps       FULLWIDTH LEFT PARENTHESIS
-FF09          ; Common # Pe       FULLWIDTH RIGHT PARENTHESIS
-FF0A          ; Common # Po       FULLWIDTH ASTERISK
-FF0B          ; Common # Sm       FULLWIDTH PLUS SIGN
-FF0C          ; Common # Po       FULLWIDTH COMMA
-FF0D          ; Common # Pd       FULLWIDTH HYPHEN-MINUS
-FF0E..FF0F    ; Common # Po   [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS
-FF10..FF19    ; Common # Nd  [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE
-FF1A..FF1B    ; Common # Po   [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON
-FF1C..FF1E    ; Common # Sm   [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN
-FF1F..FF20    ; Common # Po   [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT
-FF3B          ; Common # Ps       FULLWIDTH LEFT SQUARE BRACKET
-FF3C          ; Common # Po       FULLWIDTH REVERSE SOLIDUS
-FF3D          ; Common # Pe       FULLWIDTH RIGHT SQUARE BRACKET
-FF3E          ; Common # Sk       FULLWIDTH CIRCUMFLEX ACCENT
-FF3F          ; Common # Pc       FULLWIDTH LOW LINE
-FF40          ; Common # Sk       FULLWIDTH GRAVE ACCENT
-FF5B          ; Common # Ps       FULLWIDTH LEFT CURLY BRACKET
-FF5C          ; Common # Sm       FULLWIDTH VERTICAL LINE
-FF5D          ; Common # Pe       FULLWIDTH RIGHT CURLY BRACKET
-FF5E          ; Common # Sm       FULLWIDTH TILDE
-FF5F          ; Common # Ps       FULLWIDTH LEFT WHITE PARENTHESIS
-FF60          ; Common # Pe       FULLWIDTH RIGHT WHITE PARENTHESIS
-FF61          ; Common # Po       HALFWIDTH IDEOGRAPHIC FULL STOP
-FF62          ; Common # Ps       HALFWIDTH LEFT CORNER BRACKET
-FF63          ; Common # Pe       HALFWIDTH RIGHT CORNER BRACKET
-FF64..FF65    ; Common # Po   [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT
-FF70          ; Common # Lm       HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
-FF9E..FF9F    ; Common # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
-FFE0..FFE1    ; Common # Sc   [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN
-FFE2          ; Common # Sm       FULLWIDTH NOT SIGN
-FFE3          ; Common # Sk       FULLWIDTH MACRON
-FFE4          ; Common # So       FULLWIDTH BROKEN BAR
-FFE5..FFE6    ; Common # Sc   [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN
-FFE8          ; Common # So       HALFWIDTH FORMS LIGHT VERTICAL
-FFE9..FFEC    ; Common # Sm   [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW
-FFED..FFEE    ; Common # So   [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE
-FFF9..FFFB    ; Common # Cf   [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
-FFFC..FFFD    ; Common # So   [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHARACTER
-10100..10101  ; Common # Po   [2] AEGEAN WORD SEPARATOR LINE..AEGEAN WORD SEPARATOR DOT
-10102         ; Common # So       AEGEAN CHECK MARK
-10107..10133  ; Common # No  [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND
-10137..1013F  ; Common # So   [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT
-10190..1019B  ; Common # So  [12] ROMAN SEXTANS SIGN..ROMAN CENTURIAL SIGN
-101D0..101FC  ; Common # So  [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND
-1D000..1D0F5  ; Common # So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO
-1D100..1D126  ; Common # So  [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2
-1D129..1D164  ; Common # So  [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
-1D165..1D166  ; Common # Mc   [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
-1D16A..1D16C  ; Common # So   [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3
-1D16D..1D172  ; Common # Mc   [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5
-1D173..1D17A  ; Common # Cf   [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
-1D183..1D184  ; Common # So   [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN
-1D18C..1D1A9  ; Common # So  [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH
-1D1AE..1D1DD  ; Common # So  [48] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL PES SUBPUNCTIS
-1D300..1D356  ; Common # So  [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
-1D360..1D371  ; Common # No  [18] COUNTING ROD UNIT DIGIT ONE..COUNTING ROD TENS DIGIT NINE
-1D400..1D454  ; Common # L&  [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G
-1D456..1D49C  ; Common # L&  [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A
-1D49E..1D49F  ; Common # L&   [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D
-1D4A2         ; Common # L&       MATHEMATICAL SCRIPT CAPITAL G
-1D4A5..1D4A6  ; Common # L&   [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K
-1D4A9..1D4AC  ; Common # L&   [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q
-1D4AE..1D4B9  ; Common # L&  [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D
-1D4BB         ; Common # L&       MATHEMATICAL SCRIPT SMALL F
-1D4BD..1D4C3  ; Common # L&   [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N
-1D4C5..1D505  ; Common # L&  [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B
-1D507..1D50A  ; Common # L&   [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G
-1D50D..1D514  ; Common # L&   [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q
-1D516..1D51C  ; Common # L&   [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y
-1D51E..1D539  ; Common # L&  [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B
-1D53B..1D53E  ; Common # L&   [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G
-1D540..1D544  ; Common # L&   [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M
-1D546         ; Common # L&       MATHEMATICAL DOUBLE-STRUCK CAPITAL O
-1D54A..1D550  ; Common # L&   [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
-1D552..1D6A5  ; Common # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J
-1D6A8..1D6C0  ; Common # L&  [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA
-1D6C1         ; Common # Sm       MATHEMATICAL BOLD NABLA
-1D6C2..1D6DA  ; Common # L&  [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA
-1D6DB         ; Common # Sm       MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
-1D6DC..1D6FA  ; Common # L&  [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA
-1D6FB         ; Common # Sm       MATHEMATICAL ITALIC NABLA
-1D6FC..1D714  ; Common # L&  [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA
-1D715         ; Common # Sm       MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
-1D716..1D734  ; Common # L&  [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
-1D735         ; Common # Sm       MATHEMATICAL BOLD ITALIC NABLA
-1D736..1D74E  ; Common # L&  [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA
-1D74F         ; Common # Sm       MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
-1D750..1D76E  ; Common # L&  [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
-1D76F         ; Common # Sm       MATHEMATICAL SANS-SERIF BOLD NABLA
-1D770..1D788  ; Common # L&  [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
-1D789         ; Common # Sm       MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
-1D78A..1D7A8  ; Common # L&  [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
-1D7A9         ; Common # Sm       MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
-1D7AA..1D7C2  ; Common # L&  [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
-1D7C3         ; Common # Sm       MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
-1D7C4..1D7CB  ; Common # L&   [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA
-1D7CE..1D7FF  ; Common # Nd  [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE
-1F000..1F02B  ; Common # So  [44] MAHJONG TILE EAST WIND..MAHJONG TILE BACK
-1F030..1F093  ; Common # So [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06
-E0001         ; Common # Cf       LANGUAGE TAG
-E0020..E007F  ; Common # Cf  [96] TAG SPACE..CANCEL TAG
-
-# Total code points: 5178
-
-# ================================================
-
-0041..005A    ; Latin # L&  [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z
-0061..007A    ; Latin # L&  [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z
-00AA          ; Latin # L&       FEMININE ORDINAL INDICATOR
-00BA          ; Latin # L&       MASCULINE ORDINAL INDICATOR
-00C0..00D6    ; Latin # L&  [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS
-00D8..00F6    ; Latin # L&  [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS
-00F8..01BA    ; Latin # L& [195] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL
-01BB          ; Latin # Lo       LATIN LETTER TWO WITH STROKE
-01BC..01BF    ; Latin # L&   [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN
-01C0..01C3    ; Latin # Lo   [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK
-01C4..0293    ; Latin # L& [208] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER EZH WITH CURL
-0294          ; Latin # Lo       LATIN LETTER GLOTTAL STOP
-0295..02AF    ; Latin # L&  [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
-02B0..02B8    ; Latin # Lm   [9] MODIFIER LETTER SMALL H..MODIFIER LETTER SMALL Y
-02E0..02E4    ; Latin # Lm   [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
-1D00..1D25    ; Latin # L&  [38] LATIN LETTER SMALL CAPITAL A..LATIN LETTER AIN
-1D2C..1D5C    ; Latin # Lm  [49] MODIFIER LETTER CAPITAL A..MODIFIER LETTER SMALL AIN
-1D62..1D65    ; Latin # L&   [4] LATIN SUBSCRIPT SMALL LETTER I..LATIN SUBSCRIPT SMALL LETTER V
-1D6B..1D77    ; Latin # L&  [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G
-1D79..1D9A    ; Latin # L&  [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK
-1D9B..1DBE    ; Latin # Lm  [36] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL EZH
-1E00..1EFF    ; Latin # L& [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP
-2071          ; Latin # L&       SUPERSCRIPT LATIN SMALL LETTER I
-207F          ; Latin # L&       SUPERSCRIPT LATIN SMALL LETTER N
-2090..2094    ; Latin # Lm   [5] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER SCHWA
-212A..212B    ; Latin # L&   [2] KELVIN SIGN..ANGSTROM SIGN
-2132          ; Latin # L&       TURNED CAPITAL F
-214E          ; Latin # L&       TURNED SMALL F
-2160..2182    ; Latin # Nl  [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND
-2183..2184    ; Latin # L&   [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C
-2185..2188    ; Latin # Nl   [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND
-2C60..2C6F    ; Latin # L&  [16] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN CAPITAL LETTER TURNED A
-2C71..2C7C    ; Latin # L&  [12] LATIN SMALL LETTER V WITH RIGHT HOOK..LATIN SUBSCRIPT SMALL LETTER J
-2C7D          ; Latin # Lm       MODIFIER LETTER CAPITAL V
-A722..A76F    ; Latin # L&  [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON
-A770          ; Latin # Lm       MODIFIER LETTER US
-A771..A787    ; Latin # L&  [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T
-A78B..A78C    ; Latin # L&   [2] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER SALTILLO
-A7FB..A7FF    ; Latin # Lo   [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M
-FB00..FB06    ; Latin # L&   [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
-FF21..FF3A    ; Latin # L&  [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
-FF41..FF5A    ; Latin # L&  [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z
-
-# Total code points: 1241
-
-# ================================================
-
-0370..0373    ; Greek # L&   [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI
-0375          ; Greek # Sk       GREEK LOWER NUMERAL SIGN
-0376..0377    ; Greek # L&   [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA
-037A          ; Greek # Lm       GREEK YPOGEGRAMMENI
-037B..037D    ; Greek # L&   [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
-0384          ; Greek # Sk       GREEK TONOS
-0386          ; Greek # L&       GREEK CAPITAL LETTER ALPHA WITH TONOS
-0388..038A    ; Greek # L&   [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS
-038C          ; Greek # L&       GREEK CAPITAL LETTER OMICRON WITH TONOS
-038E..03A1    ; Greek # L&  [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO
-03A3..03E1    ; Greek # L&  [63] GREEK CAPITAL LETTER SIGMA..GREEK SMALL LETTER SAMPI
-03F0..03F5    ; Greek # L&   [6] GREEK KAPPA SYMBOL..GREEK LUNATE EPSILON SYMBOL
-03F6          ; Greek # Sm       GREEK REVERSED LUNATE EPSILON SYMBOL
-03F7..03FF    ; Greek # L&   [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
-1D26..1D2A    ; Greek # L&   [5] GREEK LETTER SMALL CAPITAL GAMMA..GREEK LETTER SMALL CAPITAL PSI
-1D5D..1D61    ; Greek # Lm   [5] MODIFIER LETTER SMALL BETA..MODIFIER LETTER SMALL CHI
-1D66..1D6A    ; Greek # L&   [5] GREEK SUBSCRIPT SMALL LETTER BETA..GREEK SUBSCRIPT SMALL LETTER CHI
-1DBF          ; Greek # Lm       MODIFIER LETTER SMALL THETA
-1F00..1F15    ; Greek # L&  [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
-1F18..1F1D    ; Greek # L&   [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
-1F20..1F45    ; Greek # L&  [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
-1F48..1F4D    ; Greek # L&   [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
-1F50..1F57    ; Greek # L&   [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
-1F59          ; Greek # L&       GREEK CAPITAL LETTER UPSILON WITH DASIA
-1F5B          ; Greek # L&       GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
-1F5D          ; Greek # L&       GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
-1F5F..1F7D    ; Greek # L&  [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA
-1F80..1FB4    ; Greek # L&  [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
-1FB6..1FBC    ; Greek # L&   [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
-1FBD          ; Greek # Sk       GREEK KORONIS
-1FBE          ; Greek # L&       GREEK PROSGEGRAMMENI
-1FBF..1FC1    ; Greek # Sk   [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI
-1FC2..1FC4    ; Greek # L&   [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
-1FC6..1FCC    ; Greek # L&   [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
-1FCD..1FCF    ; Greek # Sk   [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI
-1FD0..1FD3    ; Greek # L&   [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
-1FD6..1FDB    ; Greek # L&   [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA
-1FDD..1FDF    ; Greek # Sk   [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI
-1FE0..1FEC    ; Greek # L&  [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA
-1FED..1FEF    ; Greek # Sk   [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA
-1FF2..1FF4    ; Greek # L&   [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
-1FF6..1FFC    ; Greek # L&   [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
-1FFD..1FFE    ; Greek # Sk   [2] GREEK OXIA..GREEK DASIA
-2126          ; Greek # L&       OHM SIGN
-10140..10174  ; Greek # Nl  [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS
-10175..10178  ; Greek # No   [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN
-10179..10189  ; Greek # So  [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN
-1018A         ; Greek # No       GREEK ZERO SIGN
-1D200..1D241  ; Greek # So  [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54
-1D242..1D244  ; Greek # Mn   [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
-1D245         ; Greek # So       GREEK MUSICAL LEIMMA
-
-# Total code points: 511
-
-# ================================================
-
-0400..0481    ; Cyrillic # L& [130] CYRILLIC CAPITAL LETTER IE WITH GRAVE..CYRILLIC SMALL LETTER KOPPA
-0482          ; Cyrillic # So       CYRILLIC THOUSANDS SIGN
-0483..0487    ; Cyrillic # Mn   [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
-0488..0489    ; Cyrillic # Me   [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
-048A..0523    ; Cyrillic # L& [154] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK
-1D2B          ; Cyrillic # L&       CYRILLIC LETTER SMALL CAPITAL EL
-1D78          ; Cyrillic # Lm       MODIFIER LETTER CYRILLIC EN
-2DE0..2DFF    ; Cyrillic # Mn  [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
-A640..A65F    ; Cyrillic # L&  [32] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER YN
-A662..A66D    ; Cyrillic # L&  [12] CYRILLIC CAPITAL LETTER SOFT DE..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O
-A66E          ; Cyrillic # Lo       CYRILLIC LETTER MULTIOCULAR O
-A66F          ; Cyrillic # Mn       COMBINING CYRILLIC VZMET
-A670..A672    ; Cyrillic # Me   [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
-A673          ; Cyrillic # Po       SLAVONIC ASTERISK
-A67C..A67D    ; Cyrillic # Mn   [2] COMBINING CYRILLIC KAVYKA..COMBINING CYRILLIC PAYEROK
-A67E          ; Cyrillic # Po       CYRILLIC KAVYKA
-A67F          ; Cyrillic # Lm       CYRILLIC PAYEROK
-A680..A697    ; Cyrillic # L&  [24] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER SHWE
-
-# Total code points: 404
-
-# ================================================
-
-0531..0556    ; Armenian # L&  [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH
-0559          ; Armenian # Lm       ARMENIAN MODIFIER LETTER LEFT HALF RING
-055A..055F    ; Armenian # Po   [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK
-0561..0587    ; Armenian # L&  [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN
-058A          ; Armenian # Pd       ARMENIAN HYPHEN
-FB13..FB17    ; Armenian # L&   [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
-
-# Total code points: 90
-
-# ================================================
-
-0591..05BD    ; Hebrew # Mn  [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
-05BE          ; Hebrew # Pd       HEBREW PUNCTUATION MAQAF
-05BF          ; Hebrew # Mn       HEBREW POINT RAFE
-05C0          ; Hebrew # Po       HEBREW PUNCTUATION PASEQ
-05C1..05C2    ; Hebrew # Mn   [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
-05C3          ; Hebrew # Po       HEBREW PUNCTUATION SOF PASUQ
-05C4..05C5    ; Hebrew # Mn   [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
-05C6          ; Hebrew # Po       HEBREW PUNCTUATION NUN HAFUKHA
-05C7          ; Hebrew # Mn       HEBREW POINT QAMATS QATAN
-05D0..05EA    ; Hebrew # Lo  [27] HEBREW LETTER ALEF..HEBREW LETTER TAV
-05F0..05F2    ; Hebrew # Lo   [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD
-05F3..05F4    ; Hebrew # Po   [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM
-FB1D          ; Hebrew # Lo       HEBREW LETTER YOD WITH HIRIQ
-FB1E          ; Hebrew # Mn       HEBREW POINT JUDEO-SPANISH VARIKA
-FB1F..FB28    ; Hebrew # Lo  [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV
-FB29          ; Hebrew # Sm       HEBREW LETTER ALTERNATIVE PLUS SIGN
-FB2A..FB36    ; Hebrew # Lo  [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH
-FB38..FB3C    ; Hebrew # Lo   [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH
-FB3E          ; Hebrew # Lo       HEBREW LETTER MEM WITH DAGESH
-FB40..FB41    ; Hebrew # Lo   [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH
-FB43..FB44    ; Hebrew # Lo   [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH
-FB46..FB4F    ; Hebrew # Lo  [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED
-
-# Total code points: 133
-
-# ================================================
-
-0606..0608    ; Arabic # Sm   [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY
-0609..060A    ; Arabic # Po   [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN
-060B          ; Arabic # Sc       AFGHANI SIGN
-060D          ; Arabic # Po       ARABIC DATE SEPARATOR
-060E..060F    ; Arabic # So   [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA
-0610..061A    ; Arabic # Mn  [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
-061E          ; Arabic # Po       ARABIC TRIPLE DOT PUNCTUATION MARK
-0621..063F    ; Arabic # Lo  [31] ARABIC LETTER HAMZA..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
-0641..064A    ; Arabic # Lo  [10] ARABIC LETTER FEH..ARABIC LETTER YEH
-0656..065E    ; Arabic # Mn   [9] ARABIC SUBSCRIPT ALEF..ARABIC FATHA WITH TWO DOTS
-066A..066D    ; Arabic # Po   [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR
-066E..066F    ; Arabic # Lo   [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF
-0671..06D3    ; Arabic # Lo  [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
-06D4          ; Arabic # Po       ARABIC FULL STOP
-06D5          ; Arabic # Lo       ARABIC LETTER AE
-06D6..06DC    ; Arabic # Mn   [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
-06DE          ; Arabic # Me       ARABIC START OF RUB EL HIZB
-06DF..06E4    ; Arabic # Mn   [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
-06E5..06E6    ; Arabic # Lm   [2] ARABIC SMALL WAW..ARABIC SMALL YEH
-06E7..06E8    ; Arabic # Mn   [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
-06E9          ; Arabic # So       ARABIC PLACE OF SAJDAH
-06EA..06ED    ; Arabic # Mn   [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
-06EE..06EF    ; Arabic # Lo   [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V
-06F0..06F9    ; Arabic # Nd  [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE
-06FA..06FC    ; Arabic # Lo   [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW
-06FD..06FE    ; Arabic # So   [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN
-06FF          ; Arabic # Lo       ARABIC LETTER HEH WITH INVERTED V
-0750..077F    ; Arabic # Lo  [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE
-FB50..FBB1    ; Arabic # Lo  [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
-FBD3..FD3D    ; Arabic # Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM
-FD50..FD8F    ; Arabic # Lo  [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM
-FD92..FDC7    ; Arabic # Lo  [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM
-FDF0..FDFB    ; Arabic # Lo  [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU
-FDFC          ; Arabic # Sc       RIAL SIGN
-FE70..FE74    ; Arabic # Lo   [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM
-FE76..FEFC    ; Arabic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM
-
-# Total code points: 999
-
-# ================================================
-
-0700..070D    ; Syriac # Po  [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS
-070F          ; Syriac # Cf       SYRIAC ABBREVIATION MARK
-0710          ; Syriac # Lo       SYRIAC LETTER ALAPH
-0711          ; Syriac # Mn       SYRIAC LETTER SUPERSCRIPT ALAPH
-0712..072F    ; Syriac # Lo  [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH
-0730..074A    ; Syriac # Mn  [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
-074D..074F    ; Syriac # Lo   [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE
-
-# Total code points: 77
-
-# ================================================
-
-0780..07A5    ; Thaana # Lo  [38] THAANA LETTER HAA..THAANA LETTER WAAVU
-07A6..07B0    ; Thaana # Mn  [11] THAANA ABAFILI..THAANA SUKUN
-07B1          ; Thaana # Lo       THAANA LETTER NAA
-
-# Total code points: 50
-
-# ================================================
-
-0901..0902    ; Devanagari # Mn   [2] DEVANAGARI SIGN CANDRABINDU..DEVANAGARI SIGN ANUSVARA
-0903          ; Devanagari # Mc       DEVANAGARI SIGN VISARGA
-0904..0939    ; Devanagari # Lo  [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA
-093C          ; Devanagari # Mn       DEVANAGARI SIGN NUKTA
-093D          ; Devanagari # Lo       DEVANAGARI SIGN AVAGRAHA
-093E..0940    ; Devanagari # Mc   [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
-0941..0948    ; Devanagari # Mn   [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
-0949..094C    ; Devanagari # Mc   [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
-094D          ; Devanagari # Mn       DEVANAGARI SIGN VIRAMA
-0950          ; Devanagari # Lo       DEVANAGARI OM
-0953..0954    ; Devanagari # Mn   [2] DEVANAGARI GRAVE ACCENT..DEVANAGARI ACUTE ACCENT
-0958..0961    ; Devanagari # Lo  [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL
-0962..0963    ; Devanagari # Mn   [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
-0966..096F    ; Devanagari # Nd  [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE
-0971          ; Devanagari # Lm       DEVANAGARI SIGN HIGH SPACING DOT
-0972          ; Devanagari # Lo       DEVANAGARI LETTER CANDRA A
-097B..097F    ; Devanagari # Lo   [5] DEVANAGARI LETTER GGA..DEVANAGARI LETTER BBA
-
-# Total code points: 107
-
-# ================================================
-
-0981          ; Bengali # Mn       BENGALI SIGN CANDRABINDU
-0982..0983    ; Bengali # Mc   [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
-0985..098C    ; Bengali # Lo   [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L
-098F..0990    ; Bengali # Lo   [2] BENGALI LETTER E..BENGALI LETTER AI
-0993..09A8    ; Bengali # Lo  [22] BENGALI LETTER O..BENGALI LETTER NA
-09AA..09B0    ; Bengali # Lo   [7] BENGALI LETTER PA..BENGALI LETTER RA
-09B2          ; Bengali # Lo       BENGALI LETTER LA
-09B6..09B9    ; Bengali # Lo   [4] BENGALI LETTER SHA..BENGALI LETTER HA
-09BC          ; Bengali # Mn       BENGALI SIGN NUKTA
-09BD          ; Bengali # Lo       BENGALI SIGN AVAGRAHA
-09BE..09C0    ; Bengali # Mc   [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II
-09C1..09C4    ; Bengali # Mn   [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
-09C7..09C8    ; Bengali # Mc   [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
-09CB..09CC    ; Bengali # Mc   [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
-09CD          ; Bengali # Mn       BENGALI SIGN VIRAMA
-09CE          ; Bengali # Lo       BENGALI LETTER KHANDA TA
-09D7          ; Bengali # Mc       BENGALI AU LENGTH MARK
-09DC..09DD    ; Bengali # Lo   [2] BENGALI LETTER RRA..BENGALI LETTER RHA
-09DF..09E1    ; Bengali # Lo   [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL
-09E2..09E3    ; Bengali # Mn   [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
-09E6..09EF    ; Bengali # Nd  [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE
-09F0..09F1    ; Bengali # Lo   [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL
-09F2..09F3    ; Bengali # Sc   [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN
-09F4..09F9    ; Bengali # No   [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN
-09FA          ; Bengali # So       BENGALI ISSHAR
-
-# Total code points: 91
-
-# ================================================
-
-0A01..0A02    ; Gurmukhi # Mn   [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
-0A03          ; Gurmukhi # Mc       GURMUKHI SIGN VISARGA
-0A05..0A0A    ; Gurmukhi # Lo   [6] GURMUKHI LETTER A..GURMUKHI LETTER UU
-0A0F..0A10    ; Gurmukhi # Lo   [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI
-0A13..0A28    ; Gurmukhi # Lo  [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA
-0A2A..0A30    ; Gurmukhi # Lo   [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA
-0A32..0A33    ; Gurmukhi # Lo   [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA
-0A35..0A36    ; Gurmukhi # Lo   [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA
-0A38..0A39    ; Gurmukhi # Lo   [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA
-0A3C          ; Gurmukhi # Mn       GURMUKHI SIGN NUKTA
-0A3E..0A40    ; Gurmukhi # Mc   [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
-0A41..0A42    ; Gurmukhi # Mn   [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
-0A47..0A48    ; Gurmukhi # Mn   [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
-0A4B..0A4D    ; Gurmukhi # Mn   [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
-0A51          ; Gurmukhi # Mn       GURMUKHI SIGN UDAAT
-0A59..0A5C    ; Gurmukhi # Lo   [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA
-0A5E          ; Gurmukhi # Lo       GURMUKHI LETTER FA
-0A66..0A6F    ; Gurmukhi # Nd  [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE
-0A70..0A71    ; Gurmukhi # Mn   [2] GURMUKHI TIPPI..GURMUKHI ADDAK
-0A72..0A74    ; Gurmukhi # Lo   [3] GURMUKHI IRI..GURMUKHI EK ONKAR
-0A75          ; Gurmukhi # Mn       GURMUKHI SIGN YAKASH
-
-# Total code points: 79
-
-# ================================================
-
-0A81..0A82    ; Gujarati # Mn   [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
-0A83          ; Gujarati # Mc       GUJARATI SIGN VISARGA
-0A85..0A8D    ; Gujarati # Lo   [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E
-0A8F..0A91    ; Gujarati # Lo   [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O
-0A93..0AA8    ; Gujarati # Lo  [22] GUJARATI LETTER O..GUJARATI LETTER NA
-0AAA..0AB0    ; Gujarati # Lo   [7] GUJARATI LETTER PA..GUJARATI LETTER RA
-0AB2..0AB3    ; Gujarati # Lo   [2] GUJARATI LETTER LA..GUJARATI LETTER LLA
-0AB5..0AB9    ; Gujarati # Lo   [5] GUJARATI LETTER VA..GUJARATI LETTER HA
-0ABC          ; Gujarati # Mn       GUJARATI SIGN NUKTA
-0ABD          ; Gujarati # Lo       GUJARATI SIGN AVAGRAHA
-0ABE..0AC0    ; Gujarati # Mc   [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
-0AC1..0AC5    ; Gujarati # Mn   [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
-0AC7..0AC8    ; Gujarati # Mn   [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
-0AC9          ; Gujarati # Mc       GUJARATI VOWEL SIGN CANDRA O
-0ACB..0ACC    ; Gujarati # Mc   [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
-0ACD          ; Gujarati # Mn       GUJARATI SIGN VIRAMA
-0AD0          ; Gujarati # Lo       GUJARATI OM
-0AE0..0AE1    ; Gujarati # Lo   [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL
-0AE2..0AE3    ; Gujarati # Mn   [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
-0AE6..0AEF    ; Gujarati # Nd  [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE
-0AF1          ; Gujarati # Sc       GUJARATI RUPEE SIGN
-
-# Total code points: 83
-
-# ================================================
-
-0B01          ; Oriya # Mn       ORIYA SIGN CANDRABINDU
-0B02..0B03    ; Oriya # Mc   [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
-0B05..0B0C    ; Oriya # Lo   [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L
-0B0F..0B10    ; Oriya # Lo   [2] ORIYA LETTER E..ORIYA LETTER AI
-0B13..0B28    ; Oriya # Lo  [22] ORIYA LETTER O..ORIYA LETTER NA
-0B2A..0B30    ; Oriya # Lo   [7] ORIYA LETTER PA..ORIYA LETTER RA
-0B32..0B33    ; Oriya # Lo   [2] ORIYA LETTER LA..ORIYA LETTER LLA
-0B35..0B39    ; Oriya # Lo   [5] ORIYA LETTER VA..ORIYA LETTER HA
-0B3C          ; Oriya # Mn       ORIYA SIGN NUKTA
-0B3D          ; Oriya # Lo       ORIYA SIGN AVAGRAHA
-0B3E          ; Oriya # Mc       ORIYA VOWEL SIGN AA
-0B3F          ; Oriya # Mn       ORIYA VOWEL SIGN I
-0B40          ; Oriya # Mc       ORIYA VOWEL SIGN II
-0B41..0B44    ; Oriya # Mn   [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
-0B47..0B48    ; Oriya # Mc   [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
-0B4B..0B4C    ; Oriya # Mc   [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
-0B4D          ; Oriya # Mn       ORIYA SIGN VIRAMA
-0B56          ; Oriya # Mn       ORIYA AI LENGTH MARK
-0B57          ; Oriya # Mc       ORIYA AU LENGTH MARK
-0B5C..0B5D    ; Oriya # Lo   [2] ORIYA LETTER RRA..ORIYA LETTER RHA
-0B5F..0B61    ; Oriya # Lo   [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
-0B62..0B63    ; Oriya # Mn   [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
-0B66..0B6F    ; Oriya # Nd  [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE
-0B70          ; Oriya # So       ORIYA ISSHAR
-0B71          ; Oriya # Lo       ORIYA LETTER WA
-
-# Total code points: 84
-
-# ================================================
-
-0B82          ; Tamil # Mn       TAMIL SIGN ANUSVARA
-0B83          ; Tamil # Lo       TAMIL SIGN VISARGA
-0B85..0B8A    ; Tamil # Lo   [6] TAMIL LETTER A..TAMIL LETTER UU
-0B8E..0B90    ; Tamil # Lo   [3] TAMIL LETTER E..TAMIL LETTER AI
-0B92..0B95    ; Tamil # Lo   [4] TAMIL LETTER O..TAMIL LETTER KA
-0B99..0B9A    ; Tamil # Lo   [2] TAMIL LETTER NGA..TAMIL LETTER CA
-0B9C          ; Tamil # Lo       TAMIL LETTER JA
-0B9E..0B9F    ; Tamil # Lo   [2] TAMIL LETTER NYA..TAMIL LETTER TTA
-0BA3..0BA4    ; Tamil # Lo   [2] TAMIL LETTER NNA..TAMIL LETTER TA
-0BA8..0BAA    ; Tamil # Lo   [3] TAMIL LETTER NA..TAMIL LETTER PA
-0BAE..0BB9    ; Tamil # Lo  [12] TAMIL LETTER MA..TAMIL LETTER HA
-0BBE..0BBF    ; Tamil # Mc   [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I
-0BC0          ; Tamil # Mn       TAMIL VOWEL SIGN II
-0BC1..0BC2    ; Tamil # Mc   [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
-0BC6..0BC8    ; Tamil # Mc   [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
-0BCA..0BCC    ; Tamil # Mc   [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
-0BCD          ; Tamil # Mn       TAMIL SIGN VIRAMA
-0BD0          ; Tamil # Lo       TAMIL OM
-0BD7          ; Tamil # Mc       TAMIL AU LENGTH MARK
-0BE6..0BEF    ; Tamil # Nd  [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE
-0BF0..0BF2    ; Tamil # No   [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND
-0BF3..0BF8    ; Tamil # So   [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN
-0BF9          ; Tamil # Sc       TAMIL RUPEE SIGN
-0BFA          ; Tamil # So       TAMIL NUMBER SIGN
-
-# Total code points: 72
-
-# ================================================
-
-0C01..0C03    ; Telugu # Mc   [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
-0C05..0C0C    ; Telugu # Lo   [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L
-0C0E..0C10    ; Telugu # Lo   [3] TELUGU LETTER E..TELUGU LETTER AI
-0C12..0C28    ; Telugu # Lo  [23] TELUGU LETTER O..TELUGU LETTER NA
-0C2A..0C33    ; Telugu # Lo  [10] TELUGU LETTER PA..TELUGU LETTER LLA
-0C35..0C39    ; Telugu # Lo   [5] TELUGU LETTER VA..TELUGU LETTER HA
-0C3D          ; Telugu # Lo       TELUGU SIGN AVAGRAHA
-0C3E..0C40    ; Telugu # Mn   [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
-0C41..0C44    ; Telugu # Mc   [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
-0C46..0C48    ; Telugu # Mn   [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
-0C4A..0C4D    ; Telugu # Mn   [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
-0C55..0C56    ; Telugu # Mn   [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
-0C58..0C59    ; Telugu # Lo   [2] TELUGU LETTER TSA..TELUGU LETTER DZA
-0C60..0C61    ; Telugu # Lo   [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL
-0C62..0C63    ; Telugu # Mn   [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
-0C66..0C6F    ; Telugu # Nd  [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE
-0C78..0C7E    ; Telugu # No   [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR
-0C7F          ; Telugu # So       TELUGU SIGN TUUMU
-
-# Total code points: 93
-
-# ================================================
-
-0C82..0C83    ; Kannada # Mc   [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
-0C85..0C8C    ; Kannada # Lo   [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L
-0C8E..0C90    ; Kannada # Lo   [3] KANNADA LETTER E..KANNADA LETTER AI
-0C92..0CA8    ; Kannada # Lo  [23] KANNADA LETTER O..KANNADA LETTER NA
-0CAA..0CB3    ; Kannada # Lo  [10] KANNADA LETTER PA..KANNADA LETTER LLA
-0CB5..0CB9    ; Kannada # Lo   [5] KANNADA LETTER VA..KANNADA LETTER HA
-0CBC          ; Kannada # Mn       KANNADA SIGN NUKTA
-0CBD          ; Kannada # Lo       KANNADA SIGN AVAGRAHA
-0CBE          ; Kannada # Mc       KANNADA VOWEL SIGN AA
-0CBF          ; Kannada # Mn       KANNADA VOWEL SIGN I
-0CC0..0CC4    ; Kannada # Mc   [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR
-0CC6          ; Kannada # Mn       KANNADA VOWEL SIGN E
-0CC7..0CC8    ; Kannada # Mc   [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
-0CCA..0CCB    ; Kannada # Mc   [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
-0CCC..0CCD    ; Kannada # Mn   [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA
-0CD5..0CD6    ; Kannada # Mc   [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
-0CDE          ; Kannada # Lo       KANNADA LETTER FA
-0CE0..0CE1    ; Kannada # Lo   [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
-0CE2..0CE3    ; Kannada # Mn   [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
-0CE6..0CEF    ; Kannada # Nd  [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
-
-# Total code points: 84
-
-# ================================================
-
-0D02..0D03    ; Malayalam # Mc   [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
-0D05..0D0C    ; Malayalam # Lo   [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
-0D0E..0D10    ; Malayalam # Lo   [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
-0D12..0D28    ; Malayalam # Lo  [23] MALAYALAM LETTER O..MALAYALAM LETTER NA
-0D2A..0D39    ; Malayalam # Lo  [16] MALAYALAM LETTER PA..MALAYALAM LETTER HA
-0D3D          ; Malayalam # Lo       MALAYALAM SIGN AVAGRAHA
-0D3E..0D40    ; Malayalam # Mc   [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II
-0D41..0D44    ; Malayalam # Mn   [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
-0D46..0D48    ; Malayalam # Mc   [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
-0D4A..0D4C    ; Malayalam # Mc   [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
-0D4D          ; Malayalam # Mn       MALAYALAM SIGN VIRAMA
-0D57          ; Malayalam # Mc       MALAYALAM AU LENGTH MARK
-0D60..0D61    ; Malayalam # Lo   [2] MALAYALAM LETTER VOCALIC RR..MALAYALAM LETTER VOCALIC LL
-0D62..0D63    ; Malayalam # Mn   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
-0D66..0D6F    ; Malayalam # Nd  [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
-0D70..0D75    ; Malayalam # No   [6] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE QUARTERS
-0D79          ; Malayalam # So       MALAYALAM DATE MARK
-0D7A..0D7F    ; Malayalam # Lo   [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
-
-# Total code points: 95
-
-# ================================================
-
-0D82..0D83    ; Sinhala # Mc   [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
-0D85..0D96    ; Sinhala # Lo  [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
-0D9A..0DB1    ; Sinhala # Lo  [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
-0DB3..0DBB    ; Sinhala # Lo   [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA
-0DBD          ; Sinhala # Lo       SINHALA LETTER DANTAJA LAYANNA
-0DC0..0DC6    ; Sinhala # Lo   [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA
-0DCA          ; Sinhala # Mn       SINHALA SIGN AL-LAKUNA
-0DCF..0DD1    ; Sinhala # Mc   [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
-0DD2..0DD4    ; Sinhala # Mn   [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
-0DD6          ; Sinhala # Mn       SINHALA VOWEL SIGN DIGA PAA-PILLA
-0DD8..0DDF    ; Sinhala # Mc   [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
-0DF2..0DF3    ; Sinhala # Mc   [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
-0DF4          ; Sinhala # Po       SINHALA PUNCTUATION KUNDDALIYA
-
-# Total code points: 80
-
-# ================================================
-
-0E01..0E30    ; Thai # Lo  [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A
-0E31          ; Thai # Mn       THAI CHARACTER MAI HAN-AKAT
-0E32..0E33    ; Thai # Lo   [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM
-0E34..0E3A    ; Thai # Mn   [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
-0E40..0E45    ; Thai # Lo   [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO
-0E46          ; Thai # Lm       THAI CHARACTER MAIYAMOK
-0E47..0E4E    ; Thai # Mn   [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
-0E4F          ; Thai # Po       THAI CHARACTER FONGMAN
-0E50..0E59    ; Thai # Nd  [10] THAI DIGIT ZERO..THAI DIGIT NINE
-0E5A..0E5B    ; Thai # Po   [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT
-
-# Total code points: 86
-
-# ================================================
-
-0E81..0E82    ; Lao # Lo   [2] LAO LETTER KO..LAO LETTER KHO SUNG
-0E84          ; Lao # Lo       LAO LETTER KHO TAM
-0E87..0E88    ; Lao # Lo   [2] LAO LETTER NGO..LAO LETTER CO
-0E8A          ; Lao # Lo       LAO LETTER SO TAM
-0E8D          ; Lao # Lo       LAO LETTER NYO
-0E94..0E97    ; Lao # Lo   [4] LAO LETTER DO..LAO LETTER THO TAM
-0E99..0E9F    ; Lao # Lo   [7] LAO LETTER NO..LAO LETTER FO SUNG
-0EA1..0EA3    ; Lao # Lo   [3] LAO LETTER MO..LAO LETTER LO LING
-0EA5          ; Lao # Lo       LAO LETTER LO LOOT
-0EA7          ; Lao # Lo       LAO LETTER WO
-0EAA..0EAB    ; Lao # Lo   [2] LAO LETTER SO SUNG..LAO LETTER HO SUNG
-0EAD..0EB0    ; Lao # Lo   [4] LAO LETTER O..LAO VOWEL SIGN A
-0EB1          ; Lao # Mn       LAO VOWEL SIGN MAI KAN
-0EB2..0EB3    ; Lao # Lo   [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM
-0EB4..0EB9    ; Lao # Mn   [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU
-0EBB..0EBC    ; Lao # Mn   [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO
-0EBD          ; Lao # Lo       LAO SEMIVOWEL SIGN NYO
-0EC0..0EC4    ; Lao # Lo   [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
-0EC6          ; Lao # Lm       LAO KO LA
-0EC8..0ECD    ; Lao # Mn   [6] LAO TONE MAI EK..LAO NIGGAHITA
-0ED0..0ED9    ; Lao # Nd  [10] LAO DIGIT ZERO..LAO DIGIT NINE
-0EDC..0EDD    ; Lao # Lo   [2] LAO HO NO..LAO HO MO
-
-# Total code points: 65
-
-# ================================================
-
-0F00          ; Tibetan # Lo       TIBETAN SYLLABLE OM
-0F01..0F03    ; Tibetan # So   [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA
-0F04..0F12    ; Tibetan # Po  [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD
-0F13..0F17    ; Tibetan # So   [5] TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS
-0F18..0F19    ; Tibetan # Mn   [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
-0F1A..0F1F    ; Tibetan # So   [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG
-0F20..0F29    ; Tibetan # Nd  [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE
-0F2A..0F33    ; Tibetan # No  [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO
-0F34          ; Tibetan # So       TIBETAN MARK BSDUS RTAGS
-0F35          ; Tibetan # Mn       TIBETAN MARK NGAS BZUNG NYI ZLA
-0F36          ; Tibetan # So       TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN
-0F37          ; Tibetan # Mn       TIBETAN MARK NGAS BZUNG SGOR RTAGS
-0F38          ; Tibetan # So       TIBETAN MARK CHE MGO
-0F39          ; Tibetan # Mn       TIBETAN MARK TSA -PHRU
-0F3A          ; Tibetan # Ps       TIBETAN MARK GUG RTAGS GYON
-0F3B          ; Tibetan # Pe       TIBETAN MARK GUG RTAGS GYAS
-0F3C          ; Tibetan # Ps       TIBETAN MARK ANG KHANG GYON
-0F3D          ; Tibetan # Pe       TIBETAN MARK ANG KHANG GYAS
-0F3E..0F3F    ; Tibetan # Mc   [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
-0F40..0F47    ; Tibetan # Lo   [8] TIBETAN LETTER KA..TIBETAN LETTER JA
-0F49..0F6C    ; Tibetan # Lo  [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA
-0F71..0F7E    ; Tibetan # Mn  [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
-0F7F          ; Tibetan # Mc       TIBETAN SIGN RNAM BCAD
-0F80..0F84    ; Tibetan # Mn   [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA
-0F85          ; Tibetan # Po       TIBETAN MARK PALUTA
-0F86..0F87    ; Tibetan # Mn   [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
-0F88..0F8B    ; Tibetan # Lo   [4] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN GRU MED RGYINGS
-0F90..0F97    ; Tibetan # Mn   [8] TIBETAN SUBJOINED LETTER KA..TIBETAN SUBJOINED LETTER JA
-0F99..0FBC    ; Tibetan # Mn  [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
-0FBE..0FC5    ; Tibetan # So   [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE
-0FC6          ; Tibetan # Mn       TIBETAN SYMBOL PADMA GDAN
-0FC7..0FCC    ; Tibetan # So   [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL
-0FCE..0FCF    ; Tibetan # So   [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM
-0FD0..0FD4    ; Tibetan # Po   [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA
-
-# Total code points: 201
-
-# ================================================
-
-1000..102A    ; Myanmar # Lo  [43] MYANMAR LETTER KA..MYANMAR LETTER AU
-102B..102C    ; Myanmar # Mc   [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA
-102D..1030    ; Myanmar # Mn   [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
-1031          ; Myanmar # Mc       MYANMAR VOWEL SIGN E
-1032..1037    ; Myanmar # Mn   [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW
-1038          ; Myanmar # Mc       MYANMAR SIGN VISARGA
-1039..103A    ; Myanmar # Mn   [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
-103B..103C    ; Myanmar # Mc   [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
-103D..103E    ; Myanmar # Mn   [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
-103F          ; Myanmar # Lo       MYANMAR LETTER GREAT SA
-1040..1049    ; Myanmar # Nd  [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE
-104A..104F    ; Myanmar # Po   [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE
-1050..1055    ; Myanmar # Lo   [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL
-1056..1057    ; Myanmar # Mc   [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
-1058..1059    ; Myanmar # Mn   [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
-105A..105D    ; Myanmar # Lo   [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE
-105E..1060    ; Myanmar # Mn   [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
-1061          ; Myanmar # Lo       MYANMAR LETTER SGAW KAREN SHA
-1062..1064    ; Myanmar # Mc   [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO
-1065..1066    ; Myanmar # Lo   [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA
-1067..106D    ; Myanmar # Mc   [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5
-106E..1070    ; Myanmar # Lo   [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA
-1071..1074    ; Myanmar # Mn   [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
-1075..1081    ; Myanmar # Lo  [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA
-1082          ; Myanmar # Mn       MYANMAR CONSONANT SIGN SHAN MEDIAL WA
-1083..1084    ; Myanmar # Mc   [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E
-1085..1086    ; Myanmar # Mn   [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
-1087..108C    ; Myanmar # Mc   [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3
-108D          ; Myanmar # Mn       MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
-108E          ; Myanmar # Lo       MYANMAR LETTER RUMAI PALAUNG FA
-108F          ; Myanmar # Mc       MYANMAR SIGN RUMAI PALAUNG TONE-5
-1090..1099    ; Myanmar # Nd  [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE
-109E..109F    ; Myanmar # So   [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION
-
-# Total code points: 156
-
-# ================================================
-
-10A0..10C5    ; Georgian # L&  [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE
-10D0..10FA    ; Georgian # Lo  [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN
-10FC          ; Georgian # Lm       MODIFIER LETTER GEORGIAN NAR
-2D00..2D25    ; Georgian # L&  [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE
-
-# Total code points: 120
-
-# ================================================
-
-1100..1159    ; Hangul # Lo  [90] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG YEORINHIEUH
-115F..11A2    ; Hangul # Lo  [68] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG SSANGARAEA
-11A8..11F9    ; Hangul # Lo  [82] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG YEORINHIEUH
-3131..318E    ; Hangul # Lo  [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
-3200..321E    ; Hangul # So  [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU
-3260..327E    ; Hangul # So  [31] CIRCLED HANGUL KIYEOK..CIRCLED HANGUL IEUNG U
-AC00..D7A3    ; Hangul # Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH
-FFA0..FFBE    ; Hangul # Lo  [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH
-FFC2..FFC7    ; Hangul # Lo   [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E
-FFCA..FFCF    ; Hangul # Lo   [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE
-FFD2..FFD7    ; Hangul # Lo   [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU
-FFDA..FFDC    ; Hangul # Lo   [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I
-
-# Total code points: 11620
-
-# ================================================
-
-1200..1248    ; Ethiopic # Lo  [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA
-124A..124D    ; Ethiopic # Lo   [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE
-1250..1256    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO
-1258          ; Ethiopic # Lo       ETHIOPIC SYLLABLE QHWA
-125A..125D    ; Ethiopic # Lo   [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE
-1260..1288    ; Ethiopic # Lo  [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA
-128A..128D    ; Ethiopic # Lo   [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE
-1290..12B0    ; Ethiopic # Lo  [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA
-12B2..12B5    ; Ethiopic # Lo   [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE
-12B8..12BE    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO
-12C0          ; Ethiopic # Lo       ETHIOPIC SYLLABLE KXWA
-12C2..12C5    ; Ethiopic # Lo   [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE
-12C8..12D6    ; Ethiopic # Lo  [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O
-12D8..1310    ; Ethiopic # Lo  [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA
-1312..1315    ; Ethiopic # Lo   [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE
-1318..135A    ; Ethiopic # Lo  [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA
-135F          ; Ethiopic # Mn       ETHIOPIC COMBINING GEMINATION MARK
-1360          ; Ethiopic # So       ETHIOPIC SECTION MARK
-1361..1368    ; Ethiopic # Po   [8] ETHIOPIC WORDSPACE..ETHIOPIC PARAGRAPH SEPARATOR
-1369..137C    ; Ethiopic # No  [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND
-1380..138F    ; Ethiopic # Lo  [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE
-1390..1399    ; Ethiopic # So  [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT
-2D80..2D96    ; Ethiopic # Lo  [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE
-2DA0..2DA6    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO
-2DA8..2DAE    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO
-2DB0..2DB6    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO
-2DB8..2DBE    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO
-2DC0..2DC6    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO
-2DC8..2DCE    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO
-2DD0..2DD6    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO
-2DD8..2DDE    ; Ethiopic # Lo   [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO
-
-# Total code points: 461
-
-# ================================================
-
-13A0..13F4    ; Cherokee # Lo  [85] CHEROKEE LETTER A..CHEROKEE LETTER YV
-
-# Total code points: 85
-
-# ================================================
-
-1401..166C    ; Canadian_Aboriginal # Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA
-166D..166E    ; Canadian_Aboriginal # Po   [2] CANADIAN SYLLABICS CHI SIGN..CANADIAN SYLLABICS FULL STOP
-166F..1676    ; Canadian_Aboriginal # Lo   [8] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS NNGAA
-
-# Total code points: 630
-
-# ================================================
-
-1680          ; Ogham # Zs       OGHAM SPACE MARK
-1681..169A    ; Ogham # Lo  [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH
-169B          ; Ogham # Ps       OGHAM FEATHER MARK
-169C          ; Ogham # Pe       OGHAM REVERSED FEATHER MARK
-
-# Total code points: 29
-
-# ================================================
-
-16A0..16EA    ; Runic # Lo  [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X
-16EE..16F0    ; Runic # Nl   [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL
-
-# Total code points: 78
-
-# ================================================
-
-1780..17B3    ; Khmer # Lo  [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU
-17B4..17B5    ; Khmer # Cf   [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
-17B6          ; Khmer # Mc       KHMER VOWEL SIGN AA
-17B7..17BD    ; Khmer # Mn   [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
-17BE..17C5    ; Khmer # Mc   [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
-17C6          ; Khmer # Mn       KHMER SIGN NIKAHIT
-17C7..17C8    ; Khmer # Mc   [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
-17C9..17D3    ; Khmer # Mn  [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
-17D4..17D6    ; Khmer # Po   [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH
-17D7          ; Khmer # Lm       KHMER SIGN LEK TOO
-17D8..17DA    ; Khmer # Po   [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT
-17DB          ; Khmer # Sc       KHMER CURRENCY SYMBOL RIEL
-17DC          ; Khmer # Lo       KHMER SIGN AVAKRAHASANYA
-17DD          ; Khmer # Mn       KHMER SIGN ATTHACAN
-17E0..17E9    ; Khmer # Nd  [10] KHMER DIGIT ZERO..KHMER DIGIT NINE
-17F0..17F9    ; Khmer # No  [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON
-19E0..19FF    ; Khmer # So  [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC
-
-# Total code points: 146
-
-# ================================================
-
-1800..1801    ; Mongolian # Po   [2] MONGOLIAN BIRGA..MONGOLIAN ELLIPSIS
-1804          ; Mongolian # Po       MONGOLIAN COLON
-1806          ; Mongolian # Pd       MONGOLIAN TODO SOFT HYPHEN
-1807..180A    ; Mongolian # Po   [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU
-180B..180D    ; Mongolian # Mn   [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
-180E          ; Mongolian # Zs       MONGOLIAN VOWEL SEPARATOR
-1810..1819    ; Mongolian # Nd  [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
-1820..1842    ; Mongolian # Lo  [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI
-1843          ; Mongolian # Lm       MONGOLIAN LETTER TODO LONG VOWEL SIGN
-1844..1877    ; Mongolian # Lo  [52] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER MANCHU ZHA
-1880..18A8    ; Mongolian # Lo  [41] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER MANCHU ALI GALI BHA
-18A9          ; Mongolian # Mn       MONGOLIAN LETTER ALI GALI DAGALGA
-18AA          ; Mongolian # Lo       MONGOLIAN LETTER MANCHU ALI GALI LHA
-
-# Total code points: 153
-
-# ================================================
-
-3041..3096    ; Hiragana # Lo  [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE
-309D..309E    ; Hiragana # Lm   [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
-309F          ; Hiragana # Lo       HIRAGANA DIGRAPH YORI
-
-# Total code points: 89
-
-# ================================================
-
-30A1..30FA    ; Katakana # Lo  [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO
-30FD..30FE    ; Katakana # Lm   [2] KATAKANA ITERATION MARK..KATAKANA VOICED ITERATION MARK
-30FF          ; Katakana # Lo       KATAKANA DIGRAPH KOTO
-31F0..31FF    ; Katakana # Lo  [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
-32D0..32FE    ; Katakana # So  [47] CIRCLED KATAKANA A..CIRCLED KATAKANA WO
-3300..3357    ; Katakana # So  [88] SQUARE APAATO..SQUARE WATTO
-FF66..FF6F    ; Katakana # Lo  [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU
-FF71..FF9D    ; Katakana # Lo  [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N
-
-# Total code points: 299
-
-# ================================================
-
-3105..312D    ; Bopomofo # Lo  [41] BOPOMOFO LETTER B..BOPOMOFO LETTER IH
-31A0..31B7    ; Bopomofo # Lo  [24] BOPOMOFO LETTER BU..BOPOMOFO FINAL LETTER H
-
-# Total code points: 65
-
-# ================================================
-
-2E80..2E99    ; Han # So  [26] CJK RADICAL REPEAT..CJK RADICAL RAP
-2E9B..2EF3    ; Han # So  [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE
-2F00..2FD5    ; Han # So [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE
-3005          ; Han # Lm       IDEOGRAPHIC ITERATION MARK
-3007          ; Han # Nl       IDEOGRAPHIC NUMBER ZERO
-3021..3029    ; Han # Nl   [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE
-3038..303A    ; Han # Nl   [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY
-303B          ; Han # Lm       VERTICAL IDEOGRAPHIC ITERATION MARK
-3400..4DB5    ; Han # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
-4E00..9FC3    ; Han # Lo [20932] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FC3
-F900..FA2D    ; Han # Lo [302] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA2D
-FA30..FA6A    ; Han # Lo  [59] CJK COMPATIBILITY IDEOGRAPH-FA30..CJK COMPATIBILITY IDEOGRAPH-FA6A
-FA70..FAD9    ; Han # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
-20000..2A6D6  ; Han # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
-2F800..2FA1D  ; Han # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
-
-# Total code points: 71578
-
-# ================================================
-
-A000..A014    ; Yi # Lo  [21] YI SYLLABLE IT..YI SYLLABLE E
-A015          ; Yi # Lm       YI SYLLABLE WU
-A016..A48C    ; Yi # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
-A490..A4C6    ; Yi # So  [55] YI RADICAL QOT..YI RADICAL KE
-
-# Total code points: 1220
-
-# ================================================
-
-10300..1031E  ; Old_Italic # Lo  [31] OLD ITALIC LETTER A..OLD ITALIC LETTER UU
-10320..10323  ; Old_Italic # No   [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY
-
-# Total code points: 35
-
-# ================================================
-
-10330..10340  ; Gothic # Lo  [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA
-10341         ; Gothic # Nl       GOTHIC LETTER NINETY
-10342..10349  ; Gothic # Lo   [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL
-1034A         ; Gothic # Nl       GOTHIC LETTER NINE HUNDRED
-
-# Total code points: 27
-
-# ================================================
-
-10400..1044F  ; Deseret # L&  [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW
-
-# Total code points: 80
-
-# ================================================
-
-0300..036F    ; Inherited # Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X
-064B..0655    ; Inherited # Mn  [11] ARABIC FATHATAN..ARABIC HAMZA BELOW
-0670          ; Inherited # Mn       ARABIC LETTER SUPERSCRIPT ALEF
-0951..0952    ; Inherited # Mn   [2] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI STRESS SIGN ANUDATTA
-1DC0..1DE6    ; Inherited # Mn  [39] COMBINING DOTTED GRAVE ACCENT..COMBINING LATIN SMALL LETTER Z
-1DFE..1DFF    ; Inherited # Mn   [2] COMBINING LEFT ARROWHEAD ABOVE..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
-200C..200D    ; Inherited # Cf   [2] ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER
-20D0..20DC    ; Inherited # Mn  [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
-20DD..20E0    ; Inherited # Me   [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
-20E1          ; Inherited # Mn       COMBINING LEFT RIGHT ARROW ABOVE
-20E2..20E4    ; Inherited # Me   [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
-20E5..20F0    ; Inherited # Mn  [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE
-302A..302F    ; Inherited # Mn   [6] IDEOGRAPHIC LEVEL TONE MARK..HANGUL DOUBLE DOT TONE MARK
-3099..309A    ; Inherited # Mn   [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
-FE00..FE0F    ; Inherited # Mn  [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
-FE20..FE26    ; Inherited # Mn   [7] COMBINING LIGATURE LEFT HALF..COMBINING CONJOINING MACRON
-101FD         ; Inherited # Mn       PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
-1D167..1D169  ; Inherited # Mn   [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
-1D17B..1D182  ; Inherited # Mn   [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
-1D185..1D18B  ; Inherited # Mn   [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
-1D1AA..1D1AD  ; Inherited # Mn   [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
-E0100..E01EF  ; Inherited # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
-
-# Total code points: 496
-
-# ================================================
-
-1700..170C    ; Tagalog # Lo  [13] TAGALOG LETTER A..TAGALOG LETTER YA
-170E..1711    ; Tagalog # Lo   [4] TAGALOG LETTER LA..TAGALOG LETTER HA
-1712..1714    ; Tagalog # Mn   [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA
-
-# Total code points: 20
-
-# ================================================
-
-1720..1731    ; Hanunoo # Lo  [18] HANUNOO LETTER A..HANUNOO LETTER HA
-1732..1734    ; Hanunoo # Mn   [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD
-
-# Total code points: 21
-
-# ================================================
-
-1740..1751    ; Buhid # Lo  [18] BUHID LETTER A..BUHID LETTER HA
-1752..1753    ; Buhid # Mn   [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
-
-# Total code points: 20
-
-# ================================================
-
-1760..176C    ; Tagbanwa # Lo  [13] TAGBANWA LETTER A..TAGBANWA LETTER YA
-176E..1770    ; Tagbanwa # Lo   [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA
-1772..1773    ; Tagbanwa # Mn   [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
-
-# Total code points: 18
-
-# ================================================
-
-1900..191C    ; Limbu # Lo  [29] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER HA
-1920..1922    ; Limbu # Mn   [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
-1923..1926    ; Limbu # Mc   [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
-1927..1928    ; Limbu # Mn   [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
-1929..192B    ; Limbu # Mc   [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
-1930..1931    ; Limbu # Mc   [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
-1932          ; Limbu # Mn       LIMBU SMALL LETTER ANUSVARA
-1933..1938    ; Limbu # Mc   [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
-1939..193B    ; Limbu # Mn   [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
-1940          ; Limbu # So       LIMBU SIGN LOO
-1944..1945    ; Limbu # Po   [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK
-1946..194F    ; Limbu # Nd  [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE
-
-# Total code points: 66
-
-# ================================================
-
-1950..196D    ; Tai_Le # Lo  [30] TAI LE LETTER KA..TAI LE LETTER AI
-1970..1974    ; Tai_Le # Lo   [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6
-
-# Total code points: 35
-
-# ================================================
-
-10000..1000B  ; Linear_B # Lo  [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE
-1000D..10026  ; Linear_B # Lo  [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO
-10028..1003A  ; Linear_B # Lo  [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO
-1003C..1003D  ; Linear_B # Lo   [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE
-1003F..1004D  ; Linear_B # Lo  [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO
-10050..1005D  ; Linear_B # Lo  [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089
-10080..100FA  ; Linear_B # Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305
-
-# Total code points: 211
-
-# ================================================
-
-10380..1039D  ; Ugaritic # Lo  [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU
-1039F         ; Ugaritic # Po       UGARITIC WORD DIVIDER
-
-# Total code points: 31
-
-# ================================================
-
-10450..1047F  ; Shavian # Lo  [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW
-
-# Total code points: 48
-
-# ================================================
-
-10480..1049D  ; Osmanya # Lo  [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO
-104A0..104A9  ; Osmanya # Nd  [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE
-
-# Total code points: 40
-
-# ================================================
-
-10800..10805  ; Cypriot # Lo   [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA
-10808         ; Cypriot # Lo       CYPRIOT SYLLABLE JO
-1080A..10835  ; Cypriot # Lo  [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO
-10837..10838  ; Cypriot # Lo   [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE
-1083C         ; Cypriot # Lo       CYPRIOT SYLLABLE ZA
-1083F         ; Cypriot # Lo       CYPRIOT SYLLABLE ZO
-
-# Total code points: 55
-
-# ================================================
-
-2800..28FF    ; Braille # So [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678
-
-# Total code points: 256
-
-# ================================================
-
-1A00..1A16    ; Buginese # Lo  [23] BUGINESE LETTER KA..BUGINESE LETTER HA
-1A17..1A18    ; Buginese # Mn   [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
-1A19..1A1B    ; Buginese # Mc   [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE
-1A1E..1A1F    ; Buginese # Po   [2] BUGINESE PALLAWA..BUGINESE END OF SECTION
-
-# Total code points: 30
-
-# ================================================
-
-03E2..03EF    ; Coptic # L&  [14] COPTIC CAPITAL LETTER SHEI..COPTIC SMALL LETTER DEI
-2C80..2CE4    ; Coptic # L& [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI
-2CE5..2CEA    ; Coptic # So   [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA
-2CF9..2CFC    ; Coptic # Po   [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER
-2CFD          ; Coptic # No       COPTIC FRACTION ONE HALF
-2CFE..2CFF    ; Coptic # Po   [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER
-
-# Total code points: 128
-
-# ================================================
-
-1980..19A9    ; New_Tai_Lue # Lo  [42] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW XVA
-19B0..19C0    ; New_Tai_Lue # Mc  [17] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE VOWEL SIGN IY
-19C1..19C7    ; New_Tai_Lue # Lo   [7] NEW TAI LUE LETTER FINAL V..NEW TAI LUE LETTER FINAL B
-19C8..19C9    ; New_Tai_Lue # Mc   [2] NEW TAI LUE TONE MARK-1..NEW TAI LUE TONE MARK-2
-19D0..19D9    ; New_Tai_Lue # Nd  [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE
-19DE..19DF    ; New_Tai_Lue # Po   [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV
-
-# Total code points: 80
-
-# ================================================
-
-2C00..2C2E    ; Glagolitic # L&  [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
-2C30..2C5E    ; Glagolitic # L&  [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE
-
-# Total code points: 94
-
-# ================================================
-
-2D30..2D65    ; Tifinagh # Lo  [54] TIFINAGH LETTER YA..TIFINAGH LETTER YAZZ
-2D6F          ; Tifinagh # Lm       TIFINAGH MODIFIER LETTER LABIALIZATION MARK
-
-# Total code points: 55
-
-# ================================================
-
-A800..A801    ; Syloti_Nagri # Lo   [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I
-A802          ; Syloti_Nagri # Mn       SYLOTI NAGRI SIGN DVISVARA
-A803..A805    ; Syloti_Nagri # Lo   [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O
-A806          ; Syloti_Nagri # Mn       SYLOTI NAGRI SIGN HASANTA
-A807..A80A    ; Syloti_Nagri # Lo   [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO
-A80B          ; Syloti_Nagri # Mn       SYLOTI NAGRI SIGN ANUSVARA
-A80C..A822    ; Syloti_Nagri # Lo  [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO
-A823..A824    ; Syloti_Nagri # Mc   [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
-A825..A826    ; Syloti_Nagri # Mn   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
-A827          ; Syloti_Nagri # Mc       SYLOTI NAGRI VOWEL SIGN OO
-A828..A82B    ; Syloti_Nagri # So   [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4
-
-# Total code points: 44
-
-# ================================================
-
-103A0..103C3  ; Old_Persian # Lo  [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA
-103C8..103CF  ; Old_Persian # Lo   [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH
-103D0         ; Old_Persian # Po       OLD PERSIAN WORD DIVIDER
-103D1..103D5  ; Old_Persian # Nl   [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED
-
-# Total code points: 50
-
-# ================================================
-
-10A00         ; Kharoshthi # Lo       KHAROSHTHI LETTER A
-10A01..10A03  ; Kharoshthi # Mn   [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
-10A05..10A06  ; Kharoshthi # Mn   [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
-10A0C..10A0F  ; Kharoshthi # Mn   [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
-10A10..10A13  ; Kharoshthi # Lo   [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA
-10A15..10A17  ; Kharoshthi # Lo   [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA
-10A19..10A33  ; Kharoshthi # Lo  [27] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER TTTHA
-10A38..10A3A  ; Kharoshthi # Mn   [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW
-10A3F         ; Kharoshthi # Mn       KHAROSHTHI VIRAMA
-10A40..10A47  ; Kharoshthi # No   [8] KHAROSHTHI DIGIT ONE..KHAROSHTHI NUMBER ONE THOUSAND
-10A50..10A58  ; Kharoshthi # Po   [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES
-
-# Total code points: 65
-
-# ================================================
-
-1B00..1B03    ; Balinese # Mn   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
-1B04          ; Balinese # Mc       BALINESE SIGN BISAH
-1B05..1B33    ; Balinese # Lo  [47] BALINESE LETTER AKARA..BALINESE LETTER HA
-1B34          ; Balinese # Mn       BALINESE SIGN REREKAN
-1B35          ; Balinese # Mc       BALINESE VOWEL SIGN TEDUNG
-1B36..1B3A    ; Balinese # Mn   [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
-1B3B          ; Balinese # Mc       BALINESE VOWEL SIGN RA REPA TEDUNG
-1B3C          ; Balinese # Mn       BALINESE VOWEL SIGN LA LENGA
-1B3D..1B41    ; Balinese # Mc   [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
-1B42          ; Balinese # Mn       BALINESE VOWEL SIGN PEPET
-1B43..1B44    ; Balinese # Mc   [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG
-1B45..1B4B    ; Balinese # Lo   [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK
-1B50..1B59    ; Balinese # Nd  [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE
-1B5A..1B60    ; Balinese # Po   [7] BALINESE PANTI..BALINESE PAMENENG
-1B61..1B6A    ; Balinese # So  [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE
-1B6B..1B73    ; Balinese # Mn   [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
-1B74..1B7C    ; Balinese # So   [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING
-
-# Total code points: 121
-
-# ================================================
-
-12000..1236E  ; Cuneiform # Lo [879] CUNEIFORM SIGN A..CUNEIFORM SIGN ZUM
-12400..12462  ; Cuneiform # Nl  [99] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER
-12470..12473  ; Cuneiform # Po   [4] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON
-
-# Total code points: 982
-
-# ================================================
-
-10900..10915  ; Phoenician # Lo  [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU
-10916..10919  ; Phoenician # No   [4] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER ONE HUNDRED
-1091F         ; Phoenician # Po       PHOENICIAN WORD SEPARATOR
-
-# Total code points: 27
-
-# ================================================
-
-A840..A873    ; Phags_Pa # Lo  [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU
-A874..A877    ; Phags_Pa # Po   [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD
-
-# Total code points: 56
-
-# ================================================
-
-07C0..07C9    ; Nko # Nd  [10] NKO DIGIT ZERO..NKO DIGIT NINE
-07CA..07EA    ; Nko # Lo  [33] NKO LETTER A..NKO LETTER JONA RA
-07EB..07F3    ; Nko # Mn   [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
-07F4..07F5    ; Nko # Lm   [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE
-07F6          ; Nko # So       NKO SYMBOL OO DENNEN
-07F7..07F9    ; Nko # Po   [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK
-07FA          ; Nko # Lm       NKO LAJANYALAN
-
-# Total code points: 59
-
-# ================================================
-
-1B80..1B81    ; Sundanese # Mn   [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
-1B82          ; Sundanese # Mc       SUNDANESE SIGN PANGWISAD
-1B83..1BA0    ; Sundanese # Lo  [30] SUNDANESE LETTER A..SUNDANESE LETTER HA
-1BA1          ; Sundanese # Mc       SUNDANESE CONSONANT SIGN PAMINGKAL
-1BA2..1BA5    ; Sundanese # Mn   [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
-1BA6..1BA7    ; Sundanese # Mc   [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
-1BA8..1BA9    ; Sundanese # Mn   [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
-1BAA          ; Sundanese # Mc       SUNDANESE SIGN PAMAAEH
-1BAE..1BAF    ; Sundanese # Lo   [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA
-1BB0..1BB9    ; Sundanese # Nd  [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE
-
-# Total code points: 55
-
-# ================================================
-
-1C00..1C23    ; Lepcha # Lo  [36] LEPCHA LETTER KA..LEPCHA LETTER A
-1C24..1C2B    ; Lepcha # Mc   [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
-1C2C..1C33    ; Lepcha # Mn   [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
-1C34..1C35    ; Lepcha # Mc   [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
-1C36..1C37    ; Lepcha # Mn   [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
-1C3B..1C3F    ; Lepcha # Po   [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK
-1C40..1C49    ; Lepcha # Nd  [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE
-1C4D..1C4F    ; Lepcha # Lo   [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA
-
-# Total code points: 74
-
-# ================================================
-
-1C50..1C59    ; Ol_Chiki # Nd  [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE
-1C5A..1C77    ; Ol_Chiki # Lo  [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH
-1C78..1C7D    ; Ol_Chiki # Lm   [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD
-1C7E..1C7F    ; Ol_Chiki # Po   [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD
-
-# Total code points: 48
-
-# ================================================
-
-A500..A60B    ; Vai # Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG
-A60C          ; Vai # Lm       VAI SYLLABLE LENGTHENER
-A60D..A60F    ; Vai # Po   [3] VAI COMMA..VAI QUESTION MARK
-A610..A61F    ; Vai # Lo  [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG
-A620..A629    ; Vai # Nd  [10] VAI DIGIT ZERO..VAI DIGIT NINE
-A62A..A62B    ; Vai # Lo   [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO
-
-# Total code points: 300
-
-# ================================================
-
-A880..A881    ; Saurashtra # Mc   [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
-A882..A8B3    ; Saurashtra # Lo  [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA
-A8B4..A8C3    ; Saurashtra # Mc  [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
-A8C4          ; Saurashtra # Mn       SAURASHTRA SIGN VIRAMA
-A8CE..A8CF    ; Saurashtra # Po   [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA
-A8D0..A8D9    ; Saurashtra # Nd  [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE
-
-# Total code points: 81
-
-# ================================================
-
-A900..A909    ; Kayah_Li # Nd  [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE
-A90A..A925    ; Kayah_Li # Lo  [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO
-A926..A92D    ; Kayah_Li # Mn   [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU
-A92E..A92F    ; Kayah_Li # Po   [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA
-
-# Total code points: 48
-
-# ================================================
-
-A930..A946    ; Rejang # Lo  [23] REJANG LETTER KA..REJANG LETTER A
-A947..A951    ; Rejang # Mn  [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
-A952..A953    ; Rejang # Mc   [2] REJANG CONSONANT SIGN H..REJANG VIRAMA
-A95F          ; Rejang # Po       REJANG SECTION MARK
-
-# Total code points: 37
-
-# ================================================
-
-10280..1029C  ; Lycian # Lo  [29] LYCIAN LETTER A..LYCIAN LETTER X
-
-# Total code points: 29
-
-# ================================================
-
-102A0..102D0  ; Carian # Lo  [49] CARIAN LETTER A..CARIAN LETTER UUU3
-
-# Total code points: 49
-
-# ================================================
-
-10920..10939  ; Lydian # Lo  [26] LYDIAN LETTER A..LYDIAN LETTER C
-1093F         ; Lydian # Po       LYDIAN TRIANGULAR MARK
-
-# Total code points: 27
-
-# ================================================
-
-AA00..AA28    ; Cham # Lo  [41] CHAM LETTER A..CHAM LETTER HA
-AA29..AA2E    ; Cham # Mn   [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
-AA2F..AA30    ; Cham # Mc   [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
-AA31..AA32    ; Cham # Mn   [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
-AA33..AA34    ; Cham # Mc   [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
-AA35..AA36    ; Cham # Mn   [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
-AA40..AA42    ; Cham # Lo   [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG
-AA43          ; Cham # Mn       CHAM CONSONANT SIGN FINAL NG
-AA44..AA4B    ; Cham # Lo   [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS
-AA4C          ; Cham # Mn       CHAM CONSONANT SIGN FINAL M
-AA4D          ; Cham # Mc       CHAM CONSONANT SIGN FINAL H
-AA50..AA59    ; Cham # Nd  [10] CHAM DIGIT ZERO..CHAM DIGIT NINE
-AA5C..AA5F    ; Cham # Po   [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA
-
-# Total code points: 83
-
-# EOF
diff --git a/third_party/harfbuzz/contrib/tables/category-parse.py b/third_party/harfbuzz/contrib/tables/category-parse.py
deleted file mode 100644
index 6818c1d..0000000
--- a/third_party/harfbuzz/contrib/tables/category-parse.py
+++ /dev/null
@@ -1,70 +0,0 @@
-import sys
-from unicode_parse_common import *
-
-# http://www.unicode.org/Public/5.1.0/ucd/extracted/DerivedGeneralCategory.txt
-
-category_to_harfbuzz = {
-  'Mn': 'HB_Mark_NonSpacing',
-  'Mc': 'HB_Mark_SpacingCombining',
-  'Me': 'HB_Mark_Enclosing',
-
-  'Nd': 'HB_Number_DecimalDigit',
-  'Nl': 'HB_Number_Letter',
-  'No': 'HB_Number_Other',
-
-  'Zs': 'HB_Separator_Space',
-  'Zl': 'HB_Separator_Line',
-  'Zp': 'HB_Separator_Paragraph',
-
-  'Cc': 'HB_Other_Control',
-  'Cf': 'HB_Other_Format',
-  'Cs': 'HB_Other_Surrogate',
-  'Co': 'HB_Other_PrivateUse',
-  'Cn': 'HB_Other_NotAssigned',
-
-  'Lu': 'HB_Letter_Uppercase',
-  'Ll': 'HB_Letter_Lowercase',
-  'Lt': 'HB_Letter_Titlecase',
-  'Lm': 'HB_Letter_Modifier',
-  'Lo': 'HB_Letter_Other',
-
-  'Pc': 'HB_Punctuation_Connector',
-  'Pd': 'HB_Punctuation_Dash',
-  'Ps': 'HB_Punctuation_Open',
-  'Pe': 'HB_Punctuation_Close',
-  'Pi': 'HB_Punctuation_InitialQuote',
-  'Pf': 'HB_Punctuation_FinalQuote',
-  'Po': 'HB_Punctuation_Other',
-
-  'Sm': 'HB_Symbol_Math',
-  'Sc': 'HB_Symbol_Currency',
-  'Sk': 'HB_Symbol_Modifier',
-  'So': 'HB_Symbol_Other',
-}
-
-def main(infile, outfile):
-  ranges = unicode_file_parse(infile, category_to_harfbuzz)
-  ranges = sort_and_merge(ranges)
-
-  print >>outfile, '// Generated from Unicode script tables\n'
-  print >>outfile, '#ifndef CATEGORY_PROPERTIES_H_'
-  print >>outfile, '#define CATEGORY_PROPERTIES_H_\n'
-  print >>outfile, '#include <stdint.h>'
-  print >>outfile, '#include "harfbuzz-external.h"\n'
-  print >>outfile, 'struct category_property {'
-  print >>outfile, '  uint32_t range_start;'
-  print >>outfile, '  uint32_t range_end;'
-  print >>outfile, '  HB_CharCategory category;'
-  print >>outfile, '};\n'
-  print >>outfile, 'static const struct category_property category_properties[] = {'
-  for (start, end, value) in ranges:
-    print >>outfile, '  {0x%x, 0x%x, %s},' % (start, end, value)
-  print >>outfile, '};\n'
-  print >>outfile, 'static const unsigned category_properties_count = %d;\n' % len(ranges)
-  print >>outfile, '#endif  // CATEGORY_PROPERTIES_H_'
-
-if __name__ == '__main__':
-  if len(sys.argv) != 3:
-    print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
-  else:
-    main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))
diff --git a/third_party/harfbuzz/contrib/tables/category-properties.h b/third_party/harfbuzz/contrib/tables/category-properties.h
deleted file mode 100644
index 3b7c7ca..0000000
--- a/third_party/harfbuzz/contrib/tables/category-properties.h
+++ /dev/null
@@ -1,2869 +0,0 @@
-// Generated from Unicode script tables
-
-#ifndef CATEGORY_PROPERTIES_H_
-#define CATEGORY_PROPERTIES_H_
-
-#include <stdint.h>
-#include "harfbuzz-external.h"
-
-struct category_property {
-  uint32_t range_start;
-  uint32_t range_end;
-  HB_CharCategory category;
-};
-
-static const struct category_property category_properties[] = {
-  {0x0, 0x1f, HB_Other_Control},
-  {0x20, 0x20, HB_Separator_Space},
-  {0x21, 0x23, HB_Punctuation_Other},
-  {0x24, 0x24, HB_Symbol_Currency},
-  {0x25, 0x27, HB_Punctuation_Other},
-  {0x28, 0x28, HB_Punctuation_Open},
-  {0x29, 0x29, HB_Punctuation_Close},
-  {0x2a, 0x2a, HB_Punctuation_Other},
-  {0x2b, 0x2b, HB_Symbol_Math},
-  {0x2c, 0x2c, HB_Punctuation_Other},
-  {0x2d, 0x2d, HB_Punctuation_Dash},
-  {0x2e, 0x2f, HB_Punctuation_Other},
-  {0x30, 0x39, HB_Number_DecimalDigit},
-  {0x3a, 0x3b, HB_Punctuation_Other},
-  {0x3c, 0x3e, HB_Symbol_Math},
-  {0x3f, 0x40, HB_Punctuation_Other},
-  {0x41, 0x5a, HB_Letter_Uppercase},
-  {0x5b, 0x5b, HB_Punctuation_Open},
-  {0x5c, 0x5c, HB_Punctuation_Other},
-  {0x5d, 0x5d, HB_Punctuation_Close},
-  {0x5e, 0x5e, HB_Symbol_Modifier},
-  {0x5f, 0x5f, HB_Punctuation_Connector},
-  {0x60, 0x60, HB_Symbol_Modifier},
-  {0x61, 0x7a, HB_Letter_Lowercase},
-  {0x7b, 0x7b, HB_Punctuation_Open},
-  {0x7c, 0x7c, HB_Symbol_Math},
-  {0x7d, 0x7d, HB_Punctuation_Close},
-  {0x7e, 0x7e, HB_Symbol_Math},
-  {0x7f, 0x9f, HB_Other_Control},
-  {0xa0, 0xa0, HB_Separator_Space},
-  {0xa1, 0xa1, HB_Punctuation_Other},
-  {0xa2, 0xa5, HB_Symbol_Currency},
-  {0xa6, 0xa7, HB_Symbol_Other},
-  {0xa8, 0xa8, HB_Symbol_Modifier},
-  {0xa9, 0xa9, HB_Symbol_Other},
-  {0xaa, 0xaa, HB_Letter_Lowercase},
-  {0xab, 0xab, HB_Punctuation_InitialQuote},
-  {0xac, 0xac, HB_Symbol_Math},
-  {0xad, 0xad, HB_Other_Format},
-  {0xae, 0xae, HB_Symbol_Other},
-  {0xaf, 0xaf, HB_Symbol_Modifier},
-  {0xb0, 0xb0, HB_Symbol_Other},
-  {0xb1, 0xb1, HB_Symbol_Math},
-  {0xb2, 0xb3, HB_Number_Other},
-  {0xb4, 0xb4, HB_Symbol_Modifier},
-  {0xb5, 0xb5, HB_Letter_Lowercase},
-  {0xb6, 0xb6, HB_Symbol_Other},
-  {0xb7, 0xb7, HB_Punctuation_Other},
-  {0xb8, 0xb8, HB_Symbol_Modifier},
-  {0xb9, 0xb9, HB_Number_Other},
-  {0xba, 0xba, HB_Letter_Lowercase},
-  {0xbb, 0xbb, HB_Punctuation_FinalQuote},
-  {0xbc, 0xbe, HB_Number_Other},
-  {0xbf, 0xbf, HB_Punctuation_Other},
-  {0xc0, 0xd6, HB_Letter_Uppercase},
-  {0xd7, 0xd7, HB_Symbol_Math},
-  {0xd8, 0xde, HB_Letter_Uppercase},
-  {0xdf, 0xf6, HB_Letter_Lowercase},
-  {0xf7, 0xf7, HB_Symbol_Math},
-  {0xf8, 0xff, HB_Letter_Lowercase},
-  {0x100, 0x100, HB_Letter_Uppercase},
-  {0x101, 0x101, HB_Letter_Lowercase},
-  {0x102, 0x102, HB_Letter_Uppercase},
-  {0x103, 0x103, HB_Letter_Lowercase},
-  {0x104, 0x104, HB_Letter_Uppercase},
-  {0x105, 0x105, HB_Letter_Lowercase},
-  {0x106, 0x106, HB_Letter_Uppercase},
-  {0x107, 0x107, HB_Letter_Lowercase},
-  {0x108, 0x108, HB_Letter_Uppercase},
-  {0x109, 0x109, HB_Letter_Lowercase},
-  {0x10a, 0x10a, HB_Letter_Uppercase},
-  {0x10b, 0x10b, HB_Letter_Lowercase},
-  {0x10c, 0x10c, HB_Letter_Uppercase},
-  {0x10d, 0x10d, HB_Letter_Lowercase},
-  {0x10e, 0x10e, HB_Letter_Uppercase},
-  {0x10f, 0x10f, HB_Letter_Lowercase},
-  {0x110, 0x110, HB_Letter_Uppercase},
-  {0x111, 0x111, HB_Letter_Lowercase},
-  {0x112, 0x112, HB_Letter_Uppercase},
-  {0x113, 0x113, HB_Letter_Lowercase},
-  {0x114, 0x114, HB_Letter_Uppercase},
-  {0x115, 0x115, HB_Letter_Lowercase},
-  {0x116, 0x116, HB_Letter_Uppercase},
-  {0x117, 0x117, HB_Letter_Lowercase},
-  {0x118, 0x118, HB_Letter_Uppercase},
-  {0x119, 0x119, HB_Letter_Lowercase},
-  {0x11a, 0x11a, HB_Letter_Uppercase},
-  {0x11b, 0x11b, HB_Letter_Lowercase},
-  {0x11c, 0x11c, HB_Letter_Uppercase},
-  {0x11d, 0x11d, HB_Letter_Lowercase},
-  {0x11e, 0x11e, HB_Letter_Uppercase},
-  {0x11f, 0x11f, HB_Letter_Lowercase},
-  {0x120, 0x120, HB_Letter_Uppercase},
-  {0x121, 0x121, HB_Letter_Lowercase},
-  {0x122, 0x122, HB_Letter_Uppercase},
-  {0x123, 0x123, HB_Letter_Lowercase},
-  {0x124, 0x124, HB_Letter_Uppercase},
-  {0x125, 0x125, HB_Letter_Lowercase},
-  {0x126, 0x126, HB_Letter_Uppercase},
-  {0x127, 0x127, HB_Letter_Lowercase},
-  {0x128, 0x128, HB_Letter_Uppercase},
-  {0x129, 0x129, HB_Letter_Lowercase},
-  {0x12a, 0x12a, HB_Letter_Uppercase},
-  {0x12b, 0x12b, HB_Letter_Lowercase},
-  {0x12c, 0x12c, HB_Letter_Uppercase},
-  {0x12d, 0x12d, HB_Letter_Lowercase},
-  {0x12e, 0x12e, HB_Letter_Uppercase},
-  {0x12f, 0x12f, HB_Letter_Lowercase},
-  {0x130, 0x130, HB_Letter_Uppercase},
-  {0x131, 0x131, HB_Letter_Lowercase},
-  {0x132, 0x132, HB_Letter_Uppercase},
-  {0x133, 0x133, HB_Letter_Lowercase},
-  {0x134, 0x134, HB_Letter_Uppercase},
-  {0x135, 0x135, HB_Letter_Lowercase},
-  {0x136, 0x136, HB_Letter_Uppercase},
-  {0x137, 0x138, HB_Letter_Lowercase},
-  {0x139, 0x139, HB_Letter_Uppercase},
-  {0x13a, 0x13a, HB_Letter_Lowercase},
-  {0x13b, 0x13b, HB_Letter_Uppercase},
-  {0x13c, 0x13c, HB_Letter_Lowercase},
-  {0x13d, 0x13d, HB_Letter_Uppercase},
-  {0x13e, 0x13e, HB_Letter_Lowercase},
-  {0x13f, 0x13f, HB_Letter_Uppercase},
-  {0x140, 0x140, HB_Letter_Lowercase},
-  {0x141, 0x141, HB_Letter_Uppercase},
-  {0x142, 0x142, HB_Letter_Lowercase},
-  {0x143, 0x143, HB_Letter_Uppercase},
-  {0x144, 0x144, HB_Letter_Lowercase},
-  {0x145, 0x145, HB_Letter_Uppercase},
-  {0x146, 0x146, HB_Letter_Lowercase},
-  {0x147, 0x147, HB_Letter_Uppercase},
-  {0x148, 0x149, HB_Letter_Lowercase},
-  {0x14a, 0x14a, HB_Letter_Uppercase},
-  {0x14b, 0x14b, HB_Letter_Lowercase},
-  {0x14c, 0x14c, HB_Letter_Uppercase},
-  {0x14d, 0x14d, HB_Letter_Lowercase},
-  {0x14e, 0x14e, HB_Letter_Uppercase},
-  {0x14f, 0x14f, HB_Letter_Lowercase},
-  {0x150, 0x150, HB_Letter_Uppercase},
-  {0x151, 0x151, HB_Letter_Lowercase},
-  {0x152, 0x152, HB_Letter_Uppercase},
-  {0x153, 0x153, HB_Letter_Lowercase},
-  {0x154, 0x154, HB_Letter_Uppercase},
-  {0x155, 0x155, HB_Letter_Lowercase},
-  {0x156, 0x156, HB_Letter_Uppercase},
-  {0x157, 0x157, HB_Letter_Lowercase},
-  {0x158, 0x158, HB_Letter_Uppercase},
-  {0x159, 0x159, HB_Letter_Lowercase},
-  {0x15a, 0x15a, HB_Letter_Uppercase},
-  {0x15b, 0x15b, HB_Letter_Lowercase},
-  {0x15c, 0x15c, HB_Letter_Uppercase},
-  {0x15d, 0x15d, HB_Letter_Lowercase},
-  {0x15e, 0x15e, HB_Letter_Uppercase},
-  {0x15f, 0x15f, HB_Letter_Lowercase},
-  {0x160, 0x160, HB_Letter_Uppercase},
-  {0x161, 0x161, HB_Letter_Lowercase},
-  {0x162, 0x162, HB_Letter_Uppercase},
-  {0x163, 0x163, HB_Letter_Lowercase},
-  {0x164, 0x164, HB_Letter_Uppercase},
-  {0x165, 0x165, HB_Letter_Lowercase},
-  {0x166, 0x166, HB_Letter_Uppercase},
-  {0x167, 0x167, HB_Letter_Lowercase},
-  {0x168, 0x168, HB_Letter_Uppercase},
-  {0x169, 0x169, HB_Letter_Lowercase},
-  {0x16a, 0x16a, HB_Letter_Uppercase},
-  {0x16b, 0x16b, HB_Letter_Lowercase},
-  {0x16c, 0x16c, HB_Letter_Uppercase},
-  {0x16d, 0x16d, HB_Letter_Lowercase},
-  {0x16e, 0x16e, HB_Letter_Uppercase},
-  {0x16f, 0x16f, HB_Letter_Lowercase},
-  {0x170, 0x170, HB_Letter_Uppercase},
-  {0x171, 0x171, HB_Letter_Lowercase},
-  {0x172, 0x172, HB_Letter_Uppercase},
-  {0x173, 0x173, HB_Letter_Lowercase},
-  {0x174, 0x174, HB_Letter_Uppercase},
-  {0x175, 0x175, HB_Letter_Lowercase},
-  {0x176, 0x176, HB_Letter_Uppercase},
-  {0x177, 0x177, HB_Letter_Lowercase},
-  {0x178, 0x179, HB_Letter_Uppercase},
-  {0x17a, 0x17a, HB_Letter_Lowercase},
-  {0x17b, 0x17b, HB_Letter_Uppercase},
-  {0x17c, 0x17c, HB_Letter_Lowercase},
-  {0x17d, 0x17d, HB_Letter_Uppercase},
-  {0x17e, 0x180, HB_Letter_Lowercase},
-  {0x181, 0x182, HB_Letter_Uppercase},
-  {0x183, 0x183, HB_Letter_Lowercase},
-  {0x184, 0x184, HB_Letter_Uppercase},
-  {0x185, 0x185, HB_Letter_Lowercase},
-  {0x186, 0x187, HB_Letter_Uppercase},
-  {0x188, 0x188, HB_Letter_Lowercase},
-  {0x189, 0x18b, HB_Letter_Uppercase},
-  {0x18c, 0x18d, HB_Letter_Lowercase},
-  {0x18e, 0x191, HB_Letter_Uppercase},
-  {0x192, 0x192, HB_Letter_Lowercase},
-  {0x193, 0x194, HB_Letter_Uppercase},
-  {0x195, 0x195, HB_Letter_Lowercase},
-  {0x196, 0x198, HB_Letter_Uppercase},
-  {0x199, 0x19b, HB_Letter_Lowercase},
-  {0x19c, 0x19d, HB_Letter_Uppercase},
-  {0x19e, 0x19e, HB_Letter_Lowercase},
-  {0x19f, 0x1a0, HB_Letter_Uppercase},
-  {0x1a1, 0x1a1, HB_Letter_Lowercase},
-  {0x1a2, 0x1a2, HB_Letter_Uppercase},
-  {0x1a3, 0x1a3, HB_Letter_Lowercase},
-  {0x1a4, 0x1a4, HB_Letter_Uppercase},
-  {0x1a5, 0x1a5, HB_Letter_Lowercase},
-  {0x1a6, 0x1a7, HB_Letter_Uppercase},
-  {0x1a8, 0x1a8, HB_Letter_Lowercase},
-  {0x1a9, 0x1a9, HB_Letter_Uppercase},
-  {0x1aa, 0x1ab, HB_Letter_Lowercase},
-  {0x1ac, 0x1ac, HB_Letter_Uppercase},
-  {0x1ad, 0x1ad, HB_Letter_Lowercase},
-  {0x1ae, 0x1af, HB_Letter_Uppercase},
-  {0x1b0, 0x1b0, HB_Letter_Lowercase},
-  {0x1b1, 0x1b3, HB_Letter_Uppercase},
-  {0x1b4, 0x1b4, HB_Letter_Lowercase},
-  {0x1b5, 0x1b5, HB_Letter_Uppercase},
-  {0x1b6, 0x1b6, HB_Letter_Lowercase},
-  {0x1b7, 0x1b8, HB_Letter_Uppercase},
-  {0x1b9, 0x1ba, HB_Letter_Lowercase},
-  {0x1bb, 0x1bb, HB_Letter_Other},
-  {0x1bc, 0x1bc, HB_Letter_Uppercase},
-  {0x1bd, 0x1bf, HB_Letter_Lowercase},
-  {0x1c0, 0x1c3, HB_Letter_Other},
-  {0x1c4, 0x1c4, HB_Letter_Uppercase},
-  {0x1c5, 0x1c5, HB_Letter_Titlecase},
-  {0x1c6, 0x1c6, HB_Letter_Lowercase},
-  {0x1c7, 0x1c7, HB_Letter_Uppercase},
-  {0x1c8, 0x1c8, HB_Letter_Titlecase},
-  {0x1c9, 0x1c9, HB_Letter_Lowercase},
-  {0x1ca, 0x1ca, HB_Letter_Uppercase},
-  {0x1cb, 0x1cb, HB_Letter_Titlecase},
-  {0x1cc, 0x1cc, HB_Letter_Lowercase},
-  {0x1cd, 0x1cd, HB_Letter_Uppercase},
-  {0x1ce, 0x1ce, HB_Letter_Lowercase},
-  {0x1cf, 0x1cf, HB_Letter_Uppercase},
-  {0x1d0, 0x1d0, HB_Letter_Lowercase},
-  {0x1d1, 0x1d1, HB_Letter_Uppercase},
-  {0x1d2, 0x1d2, HB_Letter_Lowercase},
-  {0x1d3, 0x1d3, HB_Letter_Uppercase},
-  {0x1d4, 0x1d4, HB_Letter_Lowercase},
-  {0x1d5, 0x1d5, HB_Letter_Uppercase},
-  {0x1d6, 0x1d6, HB_Letter_Lowercase},
-  {0x1d7, 0x1d7, HB_Letter_Uppercase},
-  {0x1d8, 0x1d8, HB_Letter_Lowercase},
-  {0x1d9, 0x1d9, HB_Letter_Uppercase},
-  {0x1da, 0x1da, HB_Letter_Lowercase},
-  {0x1db, 0x1db, HB_Letter_Uppercase},
-  {0x1dc, 0x1dd, HB_Letter_Lowercase},
-  {0x1de, 0x1de, HB_Letter_Uppercase},
-  {0x1df, 0x1df, HB_Letter_Lowercase},
-  {0x1e0, 0x1e0, HB_Letter_Uppercase},
-  {0x1e1, 0x1e1, HB_Letter_Lowercase},
-  {0x1e2, 0x1e2, HB_Letter_Uppercase},
-  {0x1e3, 0x1e3, HB_Letter_Lowercase},
-  {0x1e4, 0x1e4, HB_Letter_Uppercase},
-  {0x1e5, 0x1e5, HB_Letter_Lowercase},
-  {0x1e6, 0x1e6, HB_Letter_Uppercase},
-  {0x1e7, 0x1e7, HB_Letter_Lowercase},
-  {0x1e8, 0x1e8, HB_Letter_Uppercase},
-  {0x1e9, 0x1e9, HB_Letter_Lowercase},
-  {0x1ea, 0x1ea, HB_Letter_Uppercase},
-  {0x1eb, 0x1eb, HB_Letter_Lowercase},
-  {0x1ec, 0x1ec, HB_Letter_Uppercase},
-  {0x1ed, 0x1ed, HB_Letter_Lowercase},
-  {0x1ee, 0x1ee, HB_Letter_Uppercase},
-  {0x1ef, 0x1f0, HB_Letter_Lowercase},
-  {0x1f1, 0x1f1, HB_Letter_Uppercase},
-  {0x1f2, 0x1f2, HB_Letter_Titlecase},
-  {0x1f3, 0x1f3, HB_Letter_Lowercase},
-  {0x1f4, 0x1f4, HB_Letter_Uppercase},
-  {0x1f5, 0x1f5, HB_Letter_Lowercase},
-  {0x1f6, 0x1f8, HB_Letter_Uppercase},
-  {0x1f9, 0x1f9, HB_Letter_Lowercase},
-  {0x1fa, 0x1fa, HB_Letter_Uppercase},
-  {0x1fb, 0x1fb, HB_Letter_Lowercase},
-  {0x1fc, 0x1fc, HB_Letter_Uppercase},
-  {0x1fd, 0x1fd, HB_Letter_Lowercase},
-  {0x1fe, 0x1fe, HB_Letter_Uppercase},
-  {0x1ff, 0x1ff, HB_Letter_Lowercase},
-  {0x200, 0x200, HB_Letter_Uppercase},
-  {0x201, 0x201, HB_Letter_Lowercase},
-  {0x202, 0x202, HB_Letter_Uppercase},
-  {0x203, 0x203, HB_Letter_Lowercase},
-  {0x204, 0x204, HB_Letter_Uppercase},
-  {0x205, 0x205, HB_Letter_Lowercase},
-  {0x206, 0x206, HB_Letter_Uppercase},
-  {0x207, 0x207, HB_Letter_Lowercase},
-  {0x208, 0x208, HB_Letter_Uppercase},
-  {0x209, 0x209, HB_Letter_Lowercase},
-  {0x20a, 0x20a, HB_Letter_Uppercase},
-  {0x20b, 0x20b, HB_Letter_Lowercase},
-  {0x20c, 0x20c, HB_Letter_Uppercase},
-  {0x20d, 0x20d, HB_Letter_Lowercase},
-  {0x20e, 0x20e, HB_Letter_Uppercase},
-  {0x20f, 0x20f, HB_Letter_Lowercase},
-  {0x210, 0x210, HB_Letter_Uppercase},
-  {0x211, 0x211, HB_Letter_Lowercase},
-  {0x212, 0x212, HB_Letter_Uppercase},
-  {0x213, 0x213, HB_Letter_Lowercase},
-  {0x214, 0x214, HB_Letter_Uppercase},
-  {0x215, 0x215, HB_Letter_Lowercase},
-  {0x216, 0x216, HB_Letter_Uppercase},
-  {0x217, 0x217, HB_Letter_Lowercase},
-  {0x218, 0x218, HB_Letter_Uppercase},
-  {0x219, 0x219, HB_Letter_Lowercase},
-  {0x21a, 0x21a, HB_Letter_Uppercase},
-  {0x21b, 0x21b, HB_Letter_Lowercase},
-  {0x21c, 0x21c, HB_Letter_Uppercase},
-  {0x21d, 0x21d, HB_Letter_Lowercase},
-  {0x21e, 0x21e, HB_Letter_Uppercase},
-  {0x21f, 0x21f, HB_Letter_Lowercase},
-  {0x220, 0x220, HB_Letter_Uppercase},
-  {0x221, 0x221, HB_Letter_Lowercase},
-  {0x222, 0x222, HB_Letter_Uppercase},
-  {0x223, 0x223, HB_Letter_Lowercase},
-  {0x224, 0x224, HB_Letter_Uppercase},
-  {0x225, 0x225, HB_Letter_Lowercase},
-  {0x226, 0x226, HB_Letter_Uppercase},
-  {0x227, 0x227, HB_Letter_Lowercase},
-  {0x228, 0x228, HB_Letter_Uppercase},
-  {0x229, 0x229, HB_Letter_Lowercase},
-  {0x22a, 0x22a, HB_Letter_Uppercase},
-  {0x22b, 0x22b, HB_Letter_Lowercase},
-  {0x22c, 0x22c, HB_Letter_Uppercase},
-  {0x22d, 0x22d, HB_Letter_Lowercase},
-  {0x22e, 0x22e, HB_Letter_Uppercase},
-  {0x22f, 0x22f, HB_Letter_Lowercase},
-  {0x230, 0x230, HB_Letter_Uppercase},
-  {0x231, 0x231, HB_Letter_Lowercase},
-  {0x232, 0x232, HB_Letter_Uppercase},
-  {0x233, 0x239, HB_Letter_Lowercase},
-  {0x23a, 0x23b, HB_Letter_Uppercase},
-  {0x23c, 0x23c, HB_Letter_Lowercase},
-  {0x23d, 0x23e, HB_Letter_Uppercase},
-  {0x23f, 0x240, HB_Letter_Lowercase},
-  {0x241, 0x241, HB_Letter_Uppercase},
-  {0x242, 0x242, HB_Letter_Lowercase},
-  {0x243, 0x246, HB_Letter_Uppercase},
-  {0x247, 0x247, HB_Letter_Lowercase},
-  {0x248, 0x248, HB_Letter_Uppercase},
-  {0x249, 0x249, HB_Letter_Lowercase},
-  {0x24a, 0x24a, HB_Letter_Uppercase},
-  {0x24b, 0x24b, HB_Letter_Lowercase},
-  {0x24c, 0x24c, HB_Letter_Uppercase},
-  {0x24d, 0x24d, HB_Letter_Lowercase},
-  {0x24e, 0x24e, HB_Letter_Uppercase},
-  {0x24f, 0x293, HB_Letter_Lowercase},
-  {0x294, 0x294, HB_Letter_Other},
-  {0x295, 0x2af, HB_Letter_Lowercase},
-  {0x2b0, 0x2c1, HB_Letter_Modifier},
-  {0x2c2, 0x2c5, HB_Symbol_Modifier},
-  {0x2c6, 0x2d1, HB_Letter_Modifier},
-  {0x2d2, 0x2df, HB_Symbol_Modifier},
-  {0x2e0, 0x2e4, HB_Letter_Modifier},
-  {0x2e5, 0x2eb, HB_Symbol_Modifier},
-  {0x2ec, 0x2ec, HB_Letter_Modifier},
-  {0x2ed, 0x2ed, HB_Symbol_Modifier},
-  {0x2ee, 0x2ee, HB_Letter_Modifier},
-  {0x2ef, 0x2ff, HB_Symbol_Modifier},
-  {0x300, 0x36f, HB_Mark_NonSpacing},
-  {0x370, 0x370, HB_Letter_Uppercase},
-  {0x371, 0x371, HB_Letter_Lowercase},
-  {0x372, 0x372, HB_Letter_Uppercase},
-  {0x373, 0x373, HB_Letter_Lowercase},
-  {0x374, 0x374, HB_Letter_Modifier},
-  {0x375, 0x375, HB_Symbol_Modifier},
-  {0x376, 0x376, HB_Letter_Uppercase},
-  {0x377, 0x377, HB_Letter_Lowercase},
-  {0x378, 0x379, HB_Other_NotAssigned},
-  {0x37a, 0x37a, HB_Letter_Modifier},
-  {0x37b, 0x37d, HB_Letter_Lowercase},
-  {0x37e, 0x37e, HB_Punctuation_Other},
-  {0x37f, 0x383, HB_Other_NotAssigned},
-  {0x384, 0x385, HB_Symbol_Modifier},
-  {0x386, 0x386, HB_Letter_Uppercase},
-  {0x387, 0x387, HB_Punctuation_Other},
-  {0x388, 0x38a, HB_Letter_Uppercase},
-  {0x38b, 0x38b, HB_Other_NotAssigned},
-  {0x38c, 0x38c, HB_Letter_Uppercase},
-  {0x38d, 0x38d, HB_Other_NotAssigned},
-  {0x38e, 0x38f, HB_Letter_Uppercase},
-  {0x390, 0x390, HB_Letter_Lowercase},
-  {0x391, 0x3a1, HB_Letter_Uppercase},
-  {0x3a2, 0x3a2, HB_Other_NotAssigned},
-  {0x3a3, 0x3ab, HB_Letter_Uppercase},
-  {0x3ac, 0x3ce, HB_Letter_Lowercase},
-  {0x3cf, 0x3cf, HB_Letter_Uppercase},
-  {0x3d0, 0x3d1, HB_Letter_Lowercase},
-  {0x3d2, 0x3d4, HB_Letter_Uppercase},
-  {0x3d5, 0x3d7, HB_Letter_Lowercase},
-  {0x3d8, 0x3d8, HB_Letter_Uppercase},
-  {0x3d9, 0x3d9, HB_Letter_Lowercase},
-  {0x3da, 0x3da, HB_Letter_Uppercase},
-  {0x3db, 0x3db, HB_Letter_Lowercase},
-  {0x3dc, 0x3dc, HB_Letter_Uppercase},
-  {0x3dd, 0x3dd, HB_Letter_Lowercase},
-  {0x3de, 0x3de, HB_Letter_Uppercase},
-  {0x3df, 0x3df, HB_Letter_Lowercase},
-  {0x3e0, 0x3e0, HB_Letter_Uppercase},
-  {0x3e1, 0x3e1, HB_Letter_Lowercase},
-  {0x3e2, 0x3e2, HB_Letter_Uppercase},
-  {0x3e3, 0x3e3, HB_Letter_Lowercase},
-  {0x3e4, 0x3e4, HB_Letter_Uppercase},
-  {0x3e5, 0x3e5, HB_Letter_Lowercase},
-  {0x3e6, 0x3e6, HB_Letter_Uppercase},
-  {0x3e7, 0x3e7, HB_Letter_Lowercase},
-  {0x3e8, 0x3e8, HB_Letter_Uppercase},
-  {0x3e9, 0x3e9, HB_Letter_Lowercase},
-  {0x3ea, 0x3ea, HB_Letter_Uppercase},
-  {0x3eb, 0x3eb, HB_Letter_Lowercase},
-  {0x3ec, 0x3ec, HB_Letter_Uppercase},
-  {0x3ed, 0x3ed, HB_Letter_Lowercase},
-  {0x3ee, 0x3ee, HB_Letter_Uppercase},
-  {0x3ef, 0x3f3, HB_Letter_Lowercase},
-  {0x3f4, 0x3f4, HB_Letter_Uppercase},
-  {0x3f5, 0x3f5, HB_Letter_Lowercase},
-  {0x3f6, 0x3f6, HB_Symbol_Math},
-  {0x3f7, 0x3f7, HB_Letter_Uppercase},
-  {0x3f8, 0x3f8, HB_Letter_Lowercase},
-  {0x3f9, 0x3fa, HB_Letter_Uppercase},
-  {0x3fb, 0x3fc, HB_Letter_Lowercase},
-  {0x3fd, 0x42f, HB_Letter_Uppercase},
-  {0x430, 0x45f, HB_Letter_Lowercase},
-  {0x460, 0x460, HB_Letter_Uppercase},
-  {0x461, 0x461, HB_Letter_Lowercase},
-  {0x462, 0x462, HB_Letter_Uppercase},
-  {0x463, 0x463, HB_Letter_Lowercase},
-  {0x464, 0x464, HB_Letter_Uppercase},
-  {0x465, 0x465, HB_Letter_Lowercase},
-  {0x466, 0x466, HB_Letter_Uppercase},
-  {0x467, 0x467, HB_Letter_Lowercase},
-  {0x468, 0x468, HB_Letter_Uppercase},
-  {0x469, 0x469, HB_Letter_Lowercase},
-  {0x46a, 0x46a, HB_Letter_Uppercase},
-  {0x46b, 0x46b, HB_Letter_Lowercase},
-  {0x46c, 0x46c, HB_Letter_Uppercase},
-  {0x46d, 0x46d, HB_Letter_Lowercase},
-  {0x46e, 0x46e, HB_Letter_Uppercase},
-  {0x46f, 0x46f, HB_Letter_Lowercase},
-  {0x470, 0x470, HB_Letter_Uppercase},
-  {0x471, 0x471, HB_Letter_Lowercase},
-  {0x472, 0x472, HB_Letter_Uppercase},
-  {0x473, 0x473, HB_Letter_Lowercase},
-  {0x474, 0x474, HB_Letter_Uppercase},
-  {0x475, 0x475, HB_Letter_Lowercase},
-  {0x476, 0x476, HB_Letter_Uppercase},
-  {0x477, 0x477, HB_Letter_Lowercase},
-  {0x478, 0x478, HB_Letter_Uppercase},
-  {0x479, 0x479, HB_Letter_Lowercase},
-  {0x47a, 0x47a, HB_Letter_Uppercase},
-  {0x47b, 0x47b, HB_Letter_Lowercase},
-  {0x47c, 0x47c, HB_Letter_Uppercase},
-  {0x47d, 0x47d, HB_Letter_Lowercase},
-  {0x47e, 0x47e, HB_Letter_Uppercase},
-  {0x47f, 0x47f, HB_Letter_Lowercase},
-  {0x480, 0x480, HB_Letter_Uppercase},
-  {0x481, 0x481, HB_Letter_Lowercase},
-  {0x482, 0x482, HB_Symbol_Other},
-  {0x483, 0x487, HB_Mark_NonSpacing},
-  {0x488, 0x489, HB_Mark_Enclosing},
-  {0x48a, 0x48a, HB_Letter_Uppercase},
-  {0x48b, 0x48b, HB_Letter_Lowercase},
-  {0x48c, 0x48c, HB_Letter_Uppercase},
-  {0x48d, 0x48d, HB_Letter_Lowercase},
-  {0x48e, 0x48e, HB_Letter_Uppercase},
-  {0x48f, 0x48f, HB_Letter_Lowercase},
-  {0x490, 0x490, HB_Letter_Uppercase},
-  {0x491, 0x491, HB_Letter_Lowercase},
-  {0x492, 0x492, HB_Letter_Uppercase},
-  {0x493, 0x493, HB_Letter_Lowercase},
-  {0x494, 0x494, HB_Letter_Uppercase},
-  {0x495, 0x495, HB_Letter_Lowercase},
-  {0x496, 0x496, HB_Letter_Uppercase},
-  {0x497, 0x497, HB_Letter_Lowercase},
-  {0x498, 0x498, HB_Letter_Uppercase},
-  {0x499, 0x499, HB_Letter_Lowercase},
-  {0x49a, 0x49a, HB_Letter_Uppercase},
-  {0x49b, 0x49b, HB_Letter_Lowercase},
-  {0x49c, 0x49c, HB_Letter_Uppercase},
-  {0x49d, 0x49d, HB_Letter_Lowercase},
-  {0x49e, 0x49e, HB_Letter_Uppercase},
-  {0x49f, 0x49f, HB_Letter_Lowercase},
-  {0x4a0, 0x4a0, HB_Letter_Uppercase},
-  {0x4a1, 0x4a1, HB_Letter_Lowercase},
-  {0x4a2, 0x4a2, HB_Letter_Uppercase},
-  {0x4a3, 0x4a3, HB_Letter_Lowercase},
-  {0x4a4, 0x4a4, HB_Letter_Uppercase},
-  {0x4a5, 0x4a5, HB_Letter_Lowercase},
-  {0x4a6, 0x4a6, HB_Letter_Uppercase},
-  {0x4a7, 0x4a7, HB_Letter_Lowercase},
-  {0x4a8, 0x4a8, HB_Letter_Uppercase},
-  {0x4a9, 0x4a9, HB_Letter_Lowercase},
-  {0x4aa, 0x4aa, HB_Letter_Uppercase},
-  {0x4ab, 0x4ab, HB_Letter_Lowercase},
-  {0x4ac, 0x4ac, HB_Letter_Uppercase},
-  {0x4ad, 0x4ad, HB_Letter_Lowercase},
-  {0x4ae, 0x4ae, HB_Letter_Uppercase},
-  {0x4af, 0x4af, HB_Letter_Lowercase},
-  {0x4b0, 0x4b0, HB_Letter_Uppercase},
-  {0x4b1, 0x4b1, HB_Letter_Lowercase},
-  {0x4b2, 0x4b2, HB_Letter_Uppercase},
-  {0x4b3, 0x4b3, HB_Letter_Lowercase},
-  {0x4b4, 0x4b4, HB_Letter_Uppercase},
-  {0x4b5, 0x4b5, HB_Letter_Lowercase},
-  {0x4b6, 0x4b6, HB_Letter_Uppercase},
-  {0x4b7, 0x4b7, HB_Letter_Lowercase},
-  {0x4b8, 0x4b8, HB_Letter_Uppercase},
-  {0x4b9, 0x4b9, HB_Letter_Lowercase},
-  {0x4ba, 0x4ba, HB_Letter_Uppercase},
-  {0x4bb, 0x4bb, HB_Letter_Lowercase},
-  {0x4bc, 0x4bc, HB_Letter_Uppercase},
-  {0x4bd, 0x4bd, HB_Letter_Lowercase},
-  {0x4be, 0x4be, HB_Letter_Uppercase},
-  {0x4bf, 0x4bf, HB_Letter_Lowercase},
-  {0x4c0, 0x4c1, HB_Letter_Uppercase},
-  {0x4c2, 0x4c2, HB_Letter_Lowercase},
-  {0x4c3, 0x4c3, HB_Letter_Uppercase},
-  {0x4c4, 0x4c4, HB_Letter_Lowercase},
-  {0x4c5, 0x4c5, HB_Letter_Uppercase},
-  {0x4c6, 0x4c6, HB_Letter_Lowercase},
-  {0x4c7, 0x4c7, HB_Letter_Uppercase},
-  {0x4c8, 0x4c8, HB_Letter_Lowercase},
-  {0x4c9, 0x4c9, HB_Letter_Uppercase},
-  {0x4ca, 0x4ca, HB_Letter_Lowercase},
-  {0x4cb, 0x4cb, HB_Letter_Uppercase},
-  {0x4cc, 0x4cc, HB_Letter_Lowercase},
-  {0x4cd, 0x4cd, HB_Letter_Uppercase},
-  {0x4ce, 0x4cf, HB_Letter_Lowercase},
-  {0x4d0, 0x4d0, HB_Letter_Uppercase},
-  {0x4d1, 0x4d1, HB_Letter_Lowercase},
-  {0x4d2, 0x4d2, HB_Letter_Uppercase},
-  {0x4d3, 0x4d3, HB_Letter_Lowercase},
-  {0x4d4, 0x4d4, HB_Letter_Uppercase},
-  {0x4d5, 0x4d5, HB_Letter_Lowercase},
-  {0x4d6, 0x4d6, HB_Letter_Uppercase},
-  {0x4d7, 0x4d7, HB_Letter_Lowercase},
-  {0x4d8, 0x4d8, HB_Letter_Uppercase},
-  {0x4d9, 0x4d9, HB_Letter_Lowercase},
-  {0x4da, 0x4da, HB_Letter_Uppercase},
-  {0x4db, 0x4db, HB_Letter_Lowercase},
-  {0x4dc, 0x4dc, HB_Letter_Uppercase},
-  {0x4dd, 0x4dd, HB_Letter_Lowercase},
-  {0x4de, 0x4de, HB_Letter_Uppercase},
-  {0x4df, 0x4df, HB_Letter_Lowercase},
-  {0x4e0, 0x4e0, HB_Letter_Uppercase},
-  {0x4e1, 0x4e1, HB_Letter_Lowercase},
-  {0x4e2, 0x4e2, HB_Letter_Uppercase},
-  {0x4e3, 0x4e3, HB_Letter_Lowercase},
-  {0x4e4, 0x4e4, HB_Letter_Uppercase},
-  {0x4e5, 0x4e5, HB_Letter_Lowercase},
-  {0x4e6, 0x4e6, HB_Letter_Uppercase},
-  {0x4e7, 0x4e7, HB_Letter_Lowercase},
-  {0x4e8, 0x4e8, HB_Letter_Uppercase},
-  {0x4e9, 0x4e9, HB_Letter_Lowercase},
-  {0x4ea, 0x4ea, HB_Letter_Uppercase},
-  {0x4eb, 0x4eb, HB_Letter_Lowercase},
-  {0x4ec, 0x4ec, HB_Letter_Uppercase},
-  {0x4ed, 0x4ed, HB_Letter_Lowercase},
-  {0x4ee, 0x4ee, HB_Letter_Uppercase},
-  {0x4ef, 0x4ef, HB_Letter_Lowercase},
-  {0x4f0, 0x4f0, HB_Letter_Uppercase},
-  {0x4f1, 0x4f1, HB_Letter_Lowercase},
-  {0x4f2, 0x4f2, HB_Letter_Uppercase},
-  {0x4f3, 0x4f3, HB_Letter_Lowercase},
-  {0x4f4, 0x4f4, HB_Letter_Uppercase},
-  {0x4f5, 0x4f5, HB_Letter_Lowercase},
-  {0x4f6, 0x4f6, HB_Letter_Uppercase},
-  {0x4f7, 0x4f7, HB_Letter_Lowercase},
-  {0x4f8, 0x4f8, HB_Letter_Uppercase},
-  {0x4f9, 0x4f9, HB_Letter_Lowercase},
-  {0x4fa, 0x4fa, HB_Letter_Uppercase},
-  {0x4fb, 0x4fb, HB_Letter_Lowercase},
-  {0x4fc, 0x4fc, HB_Letter_Uppercase},
-  {0x4fd, 0x4fd, HB_Letter_Lowercase},
-  {0x4fe, 0x4fe, HB_Letter_Uppercase},
-  {0x4ff, 0x4ff, HB_Letter_Lowercase},
-  {0x500, 0x500, HB_Letter_Uppercase},
-  {0x501, 0x501, HB_Letter_Lowercase},
-  {0x502, 0x502, HB_Letter_Uppercase},
-  {0x503, 0x503, HB_Letter_Lowercase},
-  {0x504, 0x504, HB_Letter_Uppercase},
-  {0x505, 0x505, HB_Letter_Lowercase},
-  {0x506, 0x506, HB_Letter_Uppercase},
-  {0x507, 0x507, HB_Letter_Lowercase},
-  {0x508, 0x508, HB_Letter_Uppercase},
-  {0x509, 0x509, HB_Letter_Lowercase},
-  {0x50a, 0x50a, HB_Letter_Uppercase},
-  {0x50b, 0x50b, HB_Letter_Lowercase},
-  {0x50c, 0x50c, HB_Letter_Uppercase},
-  {0x50d, 0x50d, HB_Letter_Lowercase},
-  {0x50e, 0x50e, HB_Letter_Uppercase},
-  {0x50f, 0x50f, HB_Letter_Lowercase},
-  {0x510, 0x510, HB_Letter_Uppercase},
-  {0x511, 0x511, HB_Letter_Lowercase},
-  {0x512, 0x512, HB_Letter_Uppercase},
-  {0x513, 0x513, HB_Letter_Lowercase},
-  {0x514, 0x514, HB_Letter_Uppercase},
-  {0x515, 0x515, HB_Letter_Lowercase},
-  {0x516, 0x516, HB_Letter_Uppercase},
-  {0x517, 0x517, HB_Letter_Lowercase},
-  {0x518, 0x518, HB_Letter_Uppercase},
-  {0x519, 0x519, HB_Letter_Lowercase},
-  {0x51a, 0x51a, HB_Letter_Uppercase},
-  {0x51b, 0x51b, HB_Letter_Lowercase},
-  {0x51c, 0x51c, HB_Letter_Uppercase},
-  {0x51d, 0x51d, HB_Letter_Lowercase},
-  {0x51e, 0x51e, HB_Letter_Uppercase},
-  {0x51f, 0x51f, HB_Letter_Lowercase},
-  {0x520, 0x520, HB_Letter_Uppercase},
-  {0x521, 0x521, HB_Letter_Lowercase},
-  {0x522, 0x522, HB_Letter_Uppercase},
-  {0x523, 0x523, HB_Letter_Lowercase},
-  {0x524, 0x530, HB_Other_NotAssigned},
-  {0x531, 0x556, HB_Letter_Uppercase},
-  {0x557, 0x558, HB_Other_NotAssigned},
-  {0x559, 0x559, HB_Letter_Modifier},
-  {0x55a, 0x55f, HB_Punctuation_Other},
-  {0x560, 0x560, HB_Other_NotAssigned},
-  {0x561, 0x587, HB_Letter_Lowercase},
-  {0x588, 0x588, HB_Other_NotAssigned},
-  {0x589, 0x589, HB_Punctuation_Other},
-  {0x58a, 0x58a, HB_Punctuation_Dash},
-  {0x58b, 0x590, HB_Other_NotAssigned},
-  {0x591, 0x5bd, HB_Mark_NonSpacing},
-  {0x5be, 0x5be, HB_Punctuation_Dash},
-  {0x5bf, 0x5bf, HB_Mark_NonSpacing},
-  {0x5c0, 0x5c0, HB_Punctuation_Other},
-  {0x5c1, 0x5c2, HB_Mark_NonSpacing},
-  {0x5c3, 0x5c3, HB_Punctuation_Other},
-  {0x5c4, 0x5c5, HB_Mark_NonSpacing},
-  {0x5c6, 0x5c6, HB_Punctuation_Other},
-  {0x5c7, 0x5c7, HB_Mark_NonSpacing},
-  {0x5c8, 0x5cf, HB_Other_NotAssigned},
-  {0x5d0, 0x5ea, HB_Letter_Other},
-  {0x5eb, 0x5ef, HB_Other_NotAssigned},
-  {0x5f0, 0x5f2, HB_Letter_Other},
-  {0x5f3, 0x5f4, HB_Punctuation_Other},
-  {0x5f5, 0x5ff, HB_Other_NotAssigned},
-  {0x600, 0x603, HB_Other_Format},
-  {0x604, 0x605, HB_Other_NotAssigned},
-  {0x606, 0x608, HB_Symbol_Math},
-  {0x609, 0x60a, HB_Punctuation_Other},
-  {0x60b, 0x60b, HB_Symbol_Currency},
-  {0x60c, 0x60d, HB_Punctuation_Other},
-  {0x60e, 0x60f, HB_Symbol_Other},
-  {0x610, 0x61a, HB_Mark_NonSpacing},
-  {0x61b, 0x61b, HB_Punctuation_Other},
-  {0x61c, 0x61d, HB_Other_NotAssigned},
-  {0x61e, 0x61f, HB_Punctuation_Other},
-  {0x620, 0x620, HB_Other_NotAssigned},
-  {0x621, 0x63f, HB_Letter_Other},
-  {0x640, 0x640, HB_Letter_Modifier},
-  {0x641, 0x64a, HB_Letter_Other},
-  {0x64b, 0x65e, HB_Mark_NonSpacing},
-  {0x65f, 0x65f, HB_Other_NotAssigned},
-  {0x660, 0x669, HB_Number_DecimalDigit},
-  {0x66a, 0x66d, HB_Punctuation_Other},
-  {0x66e, 0x66f, HB_Letter_Other},
-  {0x670, 0x670, HB_Mark_NonSpacing},
-  {0x671, 0x6d3, HB_Letter_Other},
-  {0x6d4, 0x6d4, HB_Punctuation_Other},
-  {0x6d5, 0x6d5, HB_Letter_Other},
-  {0x6d6, 0x6dc, HB_Mark_NonSpacing},
-  {0x6dd, 0x6dd, HB_Other_Format},
-  {0x6de, 0x6de, HB_Mark_Enclosing},
-  {0x6df, 0x6e4, HB_Mark_NonSpacing},
-  {0x6e5, 0x6e6, HB_Letter_Modifier},
-  {0x6e7, 0x6e8, HB_Mark_NonSpacing},
-  {0x6e9, 0x6e9, HB_Symbol_Other},
-  {0x6ea, 0x6ed, HB_Mark_NonSpacing},
-  {0x6ee, 0x6ef, HB_Letter_Other},
-  {0x6f0, 0x6f9, HB_Number_DecimalDigit},
-  {0x6fa, 0x6fc, HB_Letter_Other},
-  {0x6fd, 0x6fe, HB_Symbol_Other},
-  {0x6ff, 0x6ff, HB_Letter_Other},
-  {0x700, 0x70d, HB_Punctuation_Other},
-  {0x70e, 0x70e, HB_Other_NotAssigned},
-  {0x70f, 0x70f, HB_Other_Format},
-  {0x710, 0x710, HB_Letter_Other},
-  {0x711, 0x711, HB_Mark_NonSpacing},
-  {0x712, 0x72f, HB_Letter_Other},
-  {0x730, 0x74a, HB_Mark_NonSpacing},
-  {0x74b, 0x74c, HB_Other_NotAssigned},
-  {0x74d, 0x7a5, HB_Letter_Other},
-  {0x7a6, 0x7b0, HB_Mark_NonSpacing},
-  {0x7b1, 0x7b1, HB_Letter_Other},
-  {0x7b2, 0x7bf, HB_Other_NotAssigned},
-  {0x7c0, 0x7c9, HB_Number_DecimalDigit},
-  {0x7ca, 0x7ea, HB_Letter_Other},
-  {0x7eb, 0x7f3, HB_Mark_NonSpacing},
-  {0x7f4, 0x7f5, HB_Letter_Modifier},
-  {0x7f6, 0x7f6, HB_Symbol_Other},
-  {0x7f7, 0x7f9, HB_Punctuation_Other},
-  {0x7fa, 0x7fa, HB_Letter_Modifier},
-  {0x7fb, 0x900, HB_Other_NotAssigned},
-  {0x901, 0x902, HB_Mark_NonSpacing},
-  {0x903, 0x903, HB_Mark_SpacingCombining},
-  {0x904, 0x939, HB_Letter_Other},
-  {0x93a, 0x93b, HB_Other_NotAssigned},
-  {0x93c, 0x93c, HB_Mark_NonSpacing},
-  {0x93d, 0x93d, HB_Letter_Other},
-  {0x93e, 0x940, HB_Mark_SpacingCombining},
-  {0x941, 0x948, HB_Mark_NonSpacing},
-  {0x949, 0x94c, HB_Mark_SpacingCombining},
-  {0x94d, 0x94d, HB_Mark_NonSpacing},
-  {0x94e, 0x94f, HB_Other_NotAssigned},
-  {0x950, 0x950, HB_Letter_Other},
-  {0x951, 0x954, HB_Mark_NonSpacing},
-  {0x955, 0x957, HB_Other_NotAssigned},
-  {0x958, 0x961, HB_Letter_Other},
-  {0x962, 0x963, HB_Mark_NonSpacing},
-  {0x964, 0x965, HB_Punctuation_Other},
-  {0x966, 0x96f, HB_Number_DecimalDigit},
-  {0x970, 0x970, HB_Punctuation_Other},
-  {0x971, 0x971, HB_Letter_Modifier},
-  {0x972, 0x972, HB_Letter_Other},
-  {0x973, 0x97a, HB_Other_NotAssigned},
-  {0x97b, 0x97f, HB_Letter_Other},
-  {0x980, 0x980, HB_Other_NotAssigned},
-  {0x981, 0x981, HB_Mark_NonSpacing},
-  {0x982, 0x983, HB_Mark_SpacingCombining},
-  {0x984, 0x984, HB_Other_NotAssigned},
-  {0x985, 0x98c, HB_Letter_Other},
-  {0x98d, 0x98e, HB_Other_NotAssigned},
-  {0x98f, 0x990, HB_Letter_Other},
-  {0x991, 0x992, HB_Other_NotAssigned},
-  {0x993, 0x9a8, HB_Letter_Other},
-  {0x9a9, 0x9a9, HB_Other_NotAssigned},
-  {0x9aa, 0x9b0, HB_Letter_Other},
-  {0x9b1, 0x9b1, HB_Other_NotAssigned},
-  {0x9b2, 0x9b2, HB_Letter_Other},
-  {0x9b3, 0x9b5, HB_Other_NotAssigned},
-  {0x9b6, 0x9b9, HB_Letter_Other},
-  {0x9ba, 0x9bb, HB_Other_NotAssigned},
-  {0x9bc, 0x9bc, HB_Mark_NonSpacing},
-  {0x9bd, 0x9bd, HB_Letter_Other},
-  {0x9be, 0x9c0, HB_Mark_SpacingCombining},
-  {0x9c1, 0x9c4, HB_Mark_NonSpacing},
-  {0x9c5, 0x9c6, HB_Other_NotAssigned},
-  {0x9c7, 0x9c8, HB_Mark_SpacingCombining},
-  {0x9c9, 0x9ca, HB_Other_NotAssigned},
-  {0x9cb, 0x9cc, HB_Mark_SpacingCombining},
-  {0x9cd, 0x9cd, HB_Mark_NonSpacing},
-  {0x9ce, 0x9ce, HB_Letter_Other},
-  {0x9cf, 0x9d6, HB_Other_NotAssigned},
-  {0x9d7, 0x9d7, HB_Mark_SpacingCombining},
-  {0x9d8, 0x9db, HB_Other_NotAssigned},
-  {0x9dc, 0x9dd, HB_Letter_Other},
-  {0x9de, 0x9de, HB_Other_NotAssigned},
-  {0x9df, 0x9e1, HB_Letter_Other},
-  {0x9e2, 0x9e3, HB_Mark_NonSpacing},
-  {0x9e4, 0x9e5, HB_Other_NotAssigned},
-  {0x9e6, 0x9ef, HB_Number_DecimalDigit},
-  {0x9f0, 0x9f1, HB_Letter_Other},
-  {0x9f2, 0x9f3, HB_Symbol_Currency},
-  {0x9f4, 0x9f9, HB_Number_Other},
-  {0x9fa, 0x9fa, HB_Symbol_Other},
-  {0x9fb, 0xa00, HB_Other_NotAssigned},
-  {0xa01, 0xa02, HB_Mark_NonSpacing},
-  {0xa03, 0xa03, HB_Mark_SpacingCombining},
-  {0xa04, 0xa04, HB_Other_NotAssigned},
-  {0xa05, 0xa0a, HB_Letter_Other},
-  {0xa0b, 0xa0e, HB_Other_NotAssigned},
-  {0xa0f, 0xa10, HB_Letter_Other},
-  {0xa11, 0xa12, HB_Other_NotAssigned},
-  {0xa13, 0xa28, HB_Letter_Other},
-  {0xa29, 0xa29, HB_Other_NotAssigned},
-  {0xa2a, 0xa30, HB_Letter_Other},
-  {0xa31, 0xa31, HB_Other_NotAssigned},
-  {0xa32, 0xa33, HB_Letter_Other},
-  {0xa34, 0xa34, HB_Other_NotAssigned},
-  {0xa35, 0xa36, HB_Letter_Other},
-  {0xa37, 0xa37, HB_Other_NotAssigned},
-  {0xa38, 0xa39, HB_Letter_Other},
-  {0xa3a, 0xa3b, HB_Other_NotAssigned},
-  {0xa3c, 0xa3c, HB_Mark_NonSpacing},
-  {0xa3d, 0xa3d, HB_Other_NotAssigned},
-  {0xa3e, 0xa40, HB_Mark_SpacingCombining},
-  {0xa41, 0xa42, HB_Mark_NonSpacing},
-  {0xa43, 0xa46, HB_Other_NotAssigned},
-  {0xa47, 0xa48, HB_Mark_NonSpacing},
-  {0xa49, 0xa4a, HB_Other_NotAssigned},
-  {0xa4b, 0xa4d, HB_Mark_NonSpacing},
-  {0xa4e, 0xa50, HB_Other_NotAssigned},
-  {0xa51, 0xa51, HB_Mark_NonSpacing},
-  {0xa52, 0xa58, HB_Other_NotAssigned},
-  {0xa59, 0xa5c, HB_Letter_Other},
-  {0xa5d, 0xa5d, HB_Other_NotAssigned},
-  {0xa5e, 0xa5e, HB_Letter_Other},
-  {0xa5f, 0xa65, HB_Other_NotAssigned},
-  {0xa66, 0xa6f, HB_Number_DecimalDigit},
-  {0xa70, 0xa71, HB_Mark_NonSpacing},
-  {0xa72, 0xa74, HB_Letter_Other},
-  {0xa75, 0xa75, HB_Mark_NonSpacing},
-  {0xa76, 0xa80, HB_Other_NotAssigned},
-  {0xa81, 0xa82, HB_Mark_NonSpacing},
-  {0xa83, 0xa83, HB_Mark_SpacingCombining},
-  {0xa84, 0xa84, HB_Other_NotAssigned},
-  {0xa85, 0xa8d, HB_Letter_Other},
-  {0xa8e, 0xa8e, HB_Other_NotAssigned},
-  {0xa8f, 0xa91, HB_Letter_Other},
-  {0xa92, 0xa92, HB_Other_NotAssigned},
-  {0xa93, 0xaa8, HB_Letter_Other},
-  {0xaa9, 0xaa9, HB_Other_NotAssigned},
-  {0xaaa, 0xab0, HB_Letter_Other},
-  {0xab1, 0xab1, HB_Other_NotAssigned},
-  {0xab2, 0xab3, HB_Letter_Other},
-  {0xab4, 0xab4, HB_Other_NotAssigned},
-  {0xab5, 0xab9, HB_Letter_Other},
-  {0xaba, 0xabb, HB_Other_NotAssigned},
-  {0xabc, 0xabc, HB_Mark_NonSpacing},
-  {0xabd, 0xabd, HB_Letter_Other},
-  {0xabe, 0xac0, HB_Mark_SpacingCombining},
-  {0xac1, 0xac5, HB_Mark_NonSpacing},
-  {0xac6, 0xac6, HB_Other_NotAssigned},
-  {0xac7, 0xac8, HB_Mark_NonSpacing},
-  {0xac9, 0xac9, HB_Mark_SpacingCombining},
-  {0xaca, 0xaca, HB_Other_NotAssigned},
-  {0xacb, 0xacc, HB_Mark_SpacingCombining},
-  {0xacd, 0xacd, HB_Mark_NonSpacing},
-  {0xace, 0xacf, HB_Other_NotAssigned},
-  {0xad0, 0xad0, HB_Letter_Other},
-  {0xad1, 0xadf, HB_Other_NotAssigned},
-  {0xae0, 0xae1, HB_Letter_Other},
-  {0xae2, 0xae3, HB_Mark_NonSpacing},
-  {0xae4, 0xae5, HB_Other_NotAssigned},
-  {0xae6, 0xaef, HB_Number_DecimalDigit},
-  {0xaf0, 0xaf0, HB_Other_NotAssigned},
-  {0xaf1, 0xaf1, HB_Symbol_Currency},
-  {0xaf2, 0xb00, HB_Other_NotAssigned},
-  {0xb01, 0xb01, HB_Mark_NonSpacing},
-  {0xb02, 0xb03, HB_Mark_SpacingCombining},
-  {0xb04, 0xb04, HB_Other_NotAssigned},
-  {0xb05, 0xb0c, HB_Letter_Other},
-  {0xb0d, 0xb0e, HB_Other_NotAssigned},
-  {0xb0f, 0xb10, HB_Letter_Other},
-  {0xb11, 0xb12, HB_Other_NotAssigned},
-  {0xb13, 0xb28, HB_Letter_Other},
-  {0xb29, 0xb29, HB_Other_NotAssigned},
-  {0xb2a, 0xb30, HB_Letter_Other},
-  {0xb31, 0xb31, HB_Other_NotAssigned},
-  {0xb32, 0xb33, HB_Letter_Other},
-  {0xb34, 0xb34, HB_Other_NotAssigned},
-  {0xb35, 0xb39, HB_Letter_Other},
-  {0xb3a, 0xb3b, HB_Other_NotAssigned},
-  {0xb3c, 0xb3c, HB_Mark_NonSpacing},
-  {0xb3d, 0xb3d, HB_Letter_Other},
-  {0xb3e, 0xb3e, HB_Mark_SpacingCombining},
-  {0xb3f, 0xb3f, HB_Mark_NonSpacing},
-  {0xb40, 0xb40, HB_Mark_SpacingCombining},
-  {0xb41, 0xb44, HB_Mark_NonSpacing},
-  {0xb45, 0xb46, HB_Other_NotAssigned},
-  {0xb47, 0xb48, HB_Mark_SpacingCombining},
-  {0xb49, 0xb4a, HB_Other_NotAssigned},
-  {0xb4b, 0xb4c, HB_Mark_SpacingCombining},
-  {0xb4d, 0xb4d, HB_Mark_NonSpacing},
-  {0xb4e, 0xb55, HB_Other_NotAssigned},
-  {0xb56, 0xb56, HB_Mark_NonSpacing},
-  {0xb57, 0xb57, HB_Mark_SpacingCombining},
-  {0xb58, 0xb5b, HB_Other_NotAssigned},
-  {0xb5c, 0xb5d, HB_Letter_Other},
-  {0xb5e, 0xb5e, HB_Other_NotAssigned},
-  {0xb5f, 0xb61, HB_Letter_Other},
-  {0xb62, 0xb63, HB_Mark_NonSpacing},
-  {0xb64, 0xb65, HB_Other_NotAssigned},
-  {0xb66, 0xb6f, HB_Number_DecimalDigit},
-  {0xb70, 0xb70, HB_Symbol_Other},
-  {0xb71, 0xb71, HB_Letter_Other},
-  {0xb72, 0xb81, HB_Other_NotAssigned},
-  {0xb82, 0xb82, HB_Mark_NonSpacing},
-  {0xb83, 0xb83, HB_Letter_Other},
-  {0xb84, 0xb84, HB_Other_NotAssigned},
-  {0xb85, 0xb8a, HB_Letter_Other},
-  {0xb8b, 0xb8d, HB_Other_NotAssigned},
-  {0xb8e, 0xb90, HB_Letter_Other},
-  {0xb91, 0xb91, HB_Other_NotAssigned},
-  {0xb92, 0xb95, HB_Letter_Other},
-  {0xb96, 0xb98, HB_Other_NotAssigned},
-  {0xb99, 0xb9a, HB_Letter_Other},
-  {0xb9b, 0xb9b, HB_Other_NotAssigned},
-  {0xb9c, 0xb9c, HB_Letter_Other},
-  {0xb9d, 0xb9d, HB_Other_NotAssigned},
-  {0xb9e, 0xb9f, HB_Letter_Other},
-  {0xba0, 0xba2, HB_Other_NotAssigned},
-  {0xba3, 0xba4, HB_Letter_Other},
-  {0xba5, 0xba7, HB_Other_NotAssigned},
-  {0xba8, 0xbaa, HB_Letter_Other},
-  {0xbab, 0xbad, HB_Other_NotAssigned},
-  {0xbae, 0xbb9, HB_Letter_Other},
-  {0xbba, 0xbbd, HB_Other_NotAssigned},
-  {0xbbe, 0xbbf, HB_Mark_SpacingCombining},
-  {0xbc0, 0xbc0, HB_Mark_NonSpacing},
-  {0xbc1, 0xbc2, HB_Mark_SpacingCombining},
-  {0xbc3, 0xbc5, HB_Other_NotAssigned},
-  {0xbc6, 0xbc8, HB_Mark_SpacingCombining},
-  {0xbc9, 0xbc9, HB_Other_NotAssigned},
-  {0xbca, 0xbcc, HB_Mark_SpacingCombining},
-  {0xbcd, 0xbcd, HB_Mark_NonSpacing},
-  {0xbce, 0xbcf, HB_Other_NotAssigned},
-  {0xbd0, 0xbd0, HB_Letter_Other},
-  {0xbd1, 0xbd6, HB_Other_NotAssigned},
-  {0xbd7, 0xbd7, HB_Mark_SpacingCombining},
-  {0xbd8, 0xbe5, HB_Other_NotAssigned},
-  {0xbe6, 0xbef, HB_Number_DecimalDigit},
-  {0xbf0, 0xbf2, HB_Number_Other},
-  {0xbf3, 0xbf8, HB_Symbol_Other},
-  {0xbf9, 0xbf9, HB_Symbol_Currency},
-  {0xbfa, 0xbfa, HB_Symbol_Other},
-  {0xbfb, 0xc00, HB_Other_NotAssigned},
-  {0xc01, 0xc03, HB_Mark_SpacingCombining},
-  {0xc04, 0xc04, HB_Other_NotAssigned},
-  {0xc05, 0xc0c, HB_Letter_Other},
-  {0xc0d, 0xc0d, HB_Other_NotAssigned},
-  {0xc0e, 0xc10, HB_Letter_Other},
-  {0xc11, 0xc11, HB_Other_NotAssigned},
-  {0xc12, 0xc28, HB_Letter_Other},
-  {0xc29, 0xc29, HB_Other_NotAssigned},
-  {0xc2a, 0xc33, HB_Letter_Other},
-  {0xc34, 0xc34, HB_Other_NotAssigned},
-  {0xc35, 0xc39, HB_Letter_Other},
-  {0xc3a, 0xc3c, HB_Other_NotAssigned},
-  {0xc3d, 0xc3d, HB_Letter_Other},
-  {0xc3e, 0xc40, HB_Mark_NonSpacing},
-  {0xc41, 0xc44, HB_Mark_SpacingCombining},
-  {0xc45, 0xc45, HB_Other_NotAssigned},
-  {0xc46, 0xc48, HB_Mark_NonSpacing},
-  {0xc49, 0xc49, HB_Other_NotAssigned},
-  {0xc4a, 0xc4d, HB_Mark_NonSpacing},
-  {0xc4e, 0xc54, HB_Other_NotAssigned},
-  {0xc55, 0xc56, HB_Mark_NonSpacing},
-  {0xc57, 0xc57, HB_Other_NotAssigned},
-  {0xc58, 0xc59, HB_Letter_Other},
-  {0xc5a, 0xc5f, HB_Other_NotAssigned},
-  {0xc60, 0xc61, HB_Letter_Other},
-  {0xc62, 0xc63, HB_Mark_NonSpacing},
-  {0xc64, 0xc65, HB_Other_NotAssigned},
-  {0xc66, 0xc6f, HB_Number_DecimalDigit},
-  {0xc70, 0xc77, HB_Other_NotAssigned},
-  {0xc78, 0xc7e, HB_Number_Other},
-  {0xc7f, 0xc7f, HB_Symbol_Other},
-  {0xc80, 0xc81, HB_Other_NotAssigned},
-  {0xc82, 0xc83, HB_Mark_SpacingCombining},
-  {0xc84, 0xc84, HB_Other_NotAssigned},
-  {0xc85, 0xc8c, HB_Letter_Other},
-  {0xc8d, 0xc8d, HB_Other_NotAssigned},
-  {0xc8e, 0xc90, HB_Letter_Other},
-  {0xc91, 0xc91, HB_Other_NotAssigned},
-  {0xc92, 0xca8, HB_Letter_Other},
-  {0xca9, 0xca9, HB_Other_NotAssigned},
-  {0xcaa, 0xcb3, HB_Letter_Other},
-  {0xcb4, 0xcb4, HB_Other_NotAssigned},
-  {0xcb5, 0xcb9, HB_Letter_Other},
-  {0xcba, 0xcbb, HB_Other_NotAssigned},
-  {0xcbc, 0xcbc, HB_Mark_NonSpacing},
-  {0xcbd, 0xcbd, HB_Letter_Other},
-  {0xcbe, 0xcbe, HB_Mark_SpacingCombining},
-  {0xcbf, 0xcbf, HB_Mark_NonSpacing},
-  {0xcc0, 0xcc4, HB_Mark_SpacingCombining},
-  {0xcc5, 0xcc5, HB_Other_NotAssigned},
-  {0xcc6, 0xcc6, HB_Mark_NonSpacing},
-  {0xcc7, 0xcc8, HB_Mark_SpacingCombining},
-  {0xcc9, 0xcc9, HB_Other_NotAssigned},
-  {0xcca, 0xccb, HB_Mark_SpacingCombining},
-  {0xccc, 0xccd, HB_Mark_NonSpacing},
-  {0xcce, 0xcd4, HB_Other_NotAssigned},
-  {0xcd5, 0xcd6, HB_Mark_SpacingCombining},
-  {0xcd7, 0xcdd, HB_Other_NotAssigned},
-  {0xcde, 0xcde, HB_Letter_Other},
-  {0xcdf, 0xcdf, HB_Other_NotAssigned},
-  {0xce0, 0xce1, HB_Letter_Other},
-  {0xce2, 0xce3, HB_Mark_NonSpacing},
-  {0xce4, 0xce5, HB_Other_NotAssigned},
-  {0xce6, 0xcef, HB_Number_DecimalDigit},
-  {0xcf0, 0xcf0, HB_Other_NotAssigned},
-  {0xcf1, 0xcf2, HB_Symbol_Other},
-  {0xcf3, 0xd01, HB_Other_NotAssigned},
-  {0xd02, 0xd03, HB_Mark_SpacingCombining},
-  {0xd04, 0xd04, HB_Other_NotAssigned},
-  {0xd05, 0xd0c, HB_Letter_Other},
-  {0xd0d, 0xd0d, HB_Other_NotAssigned},
-  {0xd0e, 0xd10, HB_Letter_Other},
-  {0xd11, 0xd11, HB_Other_NotAssigned},
-  {0xd12, 0xd28, HB_Letter_Other},
-  {0xd29, 0xd29, HB_Other_NotAssigned},
-  {0xd2a, 0xd39, HB_Letter_Other},
-  {0xd3a, 0xd3c, HB_Other_NotAssigned},
-  {0xd3d, 0xd3d, HB_Letter_Other},
-  {0xd3e, 0xd40, HB_Mark_SpacingCombining},
-  {0xd41, 0xd44, HB_Mark_NonSpacing},
-  {0xd45, 0xd45, HB_Other_NotAssigned},
-  {0xd46, 0xd48, HB_Mark_SpacingCombining},
-  {0xd49, 0xd49, HB_Other_NotAssigned},
-  {0xd4a, 0xd4c, HB_Mark_SpacingCombining},
-  {0xd4d, 0xd4d, HB_Mark_NonSpacing},
-  {0xd4e, 0xd56, HB_Other_NotAssigned},
-  {0xd57, 0xd57, HB_Mark_SpacingCombining},
-  {0xd58, 0xd5f, HB_Other_NotAssigned},
-  {0xd60, 0xd61, HB_Letter_Other},
-  {0xd62, 0xd63, HB_Mark_NonSpacing},
-  {0xd64, 0xd65, HB_Other_NotAssigned},
-  {0xd66, 0xd6f, HB_Number_DecimalDigit},
-  {0xd70, 0xd75, HB_Number_Other},
-  {0xd76, 0xd78, HB_Other_NotAssigned},
-  {0xd79, 0xd79, HB_Symbol_Other},
-  {0xd7a, 0xd7f, HB_Letter_Other},
-  {0xd80, 0xd81, HB_Other_NotAssigned},
-  {0xd82, 0xd83, HB_Mark_SpacingCombining},
-  {0xd84, 0xd84, HB_Other_NotAssigned},
-  {0xd85, 0xd96, HB_Letter_Other},
-  {0xd97, 0xd99, HB_Other_NotAssigned},
-  {0xd9a, 0xdb1, HB_Letter_Other},
-  {0xdb2, 0xdb2, HB_Other_NotAssigned},
-  {0xdb3, 0xdbb, HB_Letter_Other},
-  {0xdbc, 0xdbc, HB_Other_NotAssigned},
-  {0xdbd, 0xdbd, HB_Letter_Other},
-  {0xdbe, 0xdbf, HB_Other_NotAssigned},
-  {0xdc0, 0xdc6, HB_Letter_Other},
-  {0xdc7, 0xdc9, HB_Other_NotAssigned},
-  {0xdca, 0xdca, HB_Mark_NonSpacing},
-  {0xdcb, 0xdce, HB_Other_NotAssigned},
-  {0xdcf, 0xdd1, HB_Mark_SpacingCombining},
-  {0xdd2, 0xdd4, HB_Mark_NonSpacing},
-  {0xdd5, 0xdd5, HB_Other_NotAssigned},
-  {0xdd6, 0xdd6, HB_Mark_NonSpacing},
-  {0xdd7, 0xdd7, HB_Other_NotAssigned},
-  {0xdd8, 0xddf, HB_Mark_SpacingCombining},
-  {0xde0, 0xdf1, HB_Other_NotAssigned},
-  {0xdf2, 0xdf3, HB_Mark_SpacingCombining},
-  {0xdf4, 0xdf4, HB_Punctuation_Other},
-  {0xdf5, 0xe00, HB_Other_NotAssigned},
-  {0xe01, 0xe30, HB_Letter_Other},
-  {0xe31, 0xe31, HB_Mark_NonSpacing},
-  {0xe32, 0xe33, HB_Letter_Other},
-  {0xe34, 0xe3a, HB_Mark_NonSpacing},
-  {0xe3b, 0xe3e, HB_Other_NotAssigned},
-  {0xe3f, 0xe3f, HB_Symbol_Currency},
-  {0xe40, 0xe45, HB_Letter_Other},
-  {0xe46, 0xe46, HB_Letter_Modifier},
-  {0xe47, 0xe4e, HB_Mark_NonSpacing},
-  {0xe4f, 0xe4f, HB_Punctuation_Other},
-  {0xe50, 0xe59, HB_Number_DecimalDigit},
-  {0xe5a, 0xe5b, HB_Punctuation_Other},
-  {0xe5c, 0xe80, HB_Other_NotAssigned},
-  {0xe81, 0xe82, HB_Letter_Other},
-  {0xe83, 0xe83, HB_Other_NotAssigned},
-  {0xe84, 0xe84, HB_Letter_Other},
-  {0xe85, 0xe86, HB_Other_NotAssigned},
-  {0xe87, 0xe88, HB_Letter_Other},
-  {0xe89, 0xe89, HB_Other_NotAssigned},
-  {0xe8a, 0xe8a, HB_Letter_Other},
-  {0xe8b, 0xe8c, HB_Other_NotAssigned},
-  {0xe8d, 0xe8d, HB_Letter_Other},
-  {0xe8e, 0xe93, HB_Other_NotAssigned},
-  {0xe94, 0xe97, HB_Letter_Other},
-  {0xe98, 0xe98, HB_Other_NotAssigned},
-  {0xe99, 0xe9f, HB_Letter_Other},
-  {0xea0, 0xea0, HB_Other_NotAssigned},
-  {0xea1, 0xea3, HB_Letter_Other},
-  {0xea4, 0xea4, HB_Other_NotAssigned},
-  {0xea5, 0xea5, HB_Letter_Other},
-  {0xea6, 0xea6, HB_Other_NotAssigned},
-  {0xea7, 0xea7, HB_Letter_Other},
-  {0xea8, 0xea9, HB_Other_NotAssigned},
-  {0xeaa, 0xeab, HB_Letter_Other},
-  {0xeac, 0xeac, HB_Other_NotAssigned},
-  {0xead, 0xeb0, HB_Letter_Other},
-  {0xeb1, 0xeb1, HB_Mark_NonSpacing},
-  {0xeb2, 0xeb3, HB_Letter_Other},
-  {0xeb4, 0xeb9, HB_Mark_NonSpacing},
-  {0xeba, 0xeba, HB_Other_NotAssigned},
-  {0xebb, 0xebc, HB_Mark_NonSpacing},
-  {0xebd, 0xebd, HB_Letter_Other},
-  {0xebe, 0xebf, HB_Other_NotAssigned},
-  {0xec0, 0xec4, HB_Letter_Other},
-  {0xec5, 0xec5, HB_Other_NotAssigned},
-  {0xec6, 0xec6, HB_Letter_Modifier},
-  {0xec7, 0xec7, HB_Other_NotAssigned},
-  {0xec8, 0xecd, HB_Mark_NonSpacing},
-  {0xece, 0xecf, HB_Other_NotAssigned},
-  {0xed0, 0xed9, HB_Number_DecimalDigit},
-  {0xeda, 0xedb, HB_Other_NotAssigned},
-  {0xedc, 0xedd, HB_Letter_Other},
-  {0xede, 0xeff, HB_Other_NotAssigned},
-  {0xf00, 0xf00, HB_Letter_Other},
-  {0xf01, 0xf03, HB_Symbol_Other},
-  {0xf04, 0xf12, HB_Punctuation_Other},
-  {0xf13, 0xf17, HB_Symbol_Other},
-  {0xf18, 0xf19, HB_Mark_NonSpacing},
-  {0xf1a, 0xf1f, HB_Symbol_Other},
-  {0xf20, 0xf29, HB_Number_DecimalDigit},
-  {0xf2a, 0xf33, HB_Number_Other},
-  {0xf34, 0xf34, HB_Symbol_Other},
-  {0xf35, 0xf35, HB_Mark_NonSpacing},
-  {0xf36, 0xf36, HB_Symbol_Other},
-  {0xf37, 0xf37, HB_Mark_NonSpacing},
-  {0xf38, 0xf38, HB_Symbol_Other},
-  {0xf39, 0xf39, HB_Mark_NonSpacing},
-  {0xf3a, 0xf3a, HB_Punctuation_Open},
-  {0xf3b, 0xf3b, HB_Punctuation_Close},
-  {0xf3c, 0xf3c, HB_Punctuation_Open},
-  {0xf3d, 0xf3d, HB_Punctuation_Close},
-  {0xf3e, 0xf3f, HB_Mark_SpacingCombining},
-  {0xf40, 0xf47, HB_Letter_Other},
-  {0xf48, 0xf48, HB_Other_NotAssigned},
-  {0xf49, 0xf6c, HB_Letter_Other},
-  {0xf6d, 0xf70, HB_Other_NotAssigned},
-  {0xf71, 0xf7e, HB_Mark_NonSpacing},
-  {0xf7f, 0xf7f, HB_Mark_SpacingCombining},
-  {0xf80, 0xf84, HB_Mark_NonSpacing},
-  {0xf85, 0xf85, HB_Punctuation_Other},
-  {0xf86, 0xf87, HB_Mark_NonSpacing},
-  {0xf88, 0xf8b, HB_Letter_Other},
-  {0xf8c, 0xf8f, HB_Other_NotAssigned},
-  {0xf90, 0xf97, HB_Mark_NonSpacing},
-  {0xf98, 0xf98, HB_Other_NotAssigned},
-  {0xf99, 0xfbc, HB_Mark_NonSpacing},
-  {0xfbd, 0xfbd, HB_Other_NotAssigned},
-  {0xfbe, 0xfc5, HB_Symbol_Other},
-  {0xfc6, 0xfc6, HB_Mark_NonSpacing},
-  {0xfc7, 0xfcc, HB_Symbol_Other},
-  {0xfcd, 0xfcd, HB_Other_NotAssigned},
-  {0xfce, 0xfcf, HB_Symbol_Other},
-  {0xfd0, 0xfd4, HB_Punctuation_Other},
-  {0xfd5, 0xfff, HB_Other_NotAssigned},
-  {0x1000, 0x102a, HB_Letter_Other},
-  {0x102b, 0x102c, HB_Mark_SpacingCombining},
-  {0x102d, 0x1030, HB_Mark_NonSpacing},
-  {0x1031, 0x1031, HB_Mark_SpacingCombining},
-  {0x1032, 0x1037, HB_Mark_NonSpacing},
-  {0x1038, 0x1038, HB_Mark_SpacingCombining},
-  {0x1039, 0x103a, HB_Mark_NonSpacing},
-  {0x103b, 0x103c, HB_Mark_SpacingCombining},
-  {0x103d, 0x103e, HB_Mark_NonSpacing},
-  {0x103f, 0x103f, HB_Letter_Other},
-  {0x1040, 0x1049, HB_Number_DecimalDigit},
-  {0x104a, 0x104f, HB_Punctuation_Other},
-  {0x1050, 0x1055, HB_Letter_Other},
-  {0x1056, 0x1057, HB_Mark_SpacingCombining},
-  {0x1058, 0x1059, HB_Mark_NonSpacing},
-  {0x105a, 0x105d, HB_Letter_Other},
-  {0x105e, 0x1060, HB_Mark_NonSpacing},
-  {0x1061, 0x1061, HB_Letter_Other},
-  {0x1062, 0x1064, HB_Mark_SpacingCombining},
-  {0x1065, 0x1066, HB_Letter_Other},
-  {0x1067, 0x106d, HB_Mark_SpacingCombining},
-  {0x106e, 0x1070, HB_Letter_Other},
-  {0x1071, 0x1074, HB_Mark_NonSpacing},
-  {0x1075, 0x1081, HB_Letter_Other},
-  {0x1082, 0x1082, HB_Mark_NonSpacing},
-  {0x1083, 0x1084, HB_Mark_SpacingCombining},
-  {0x1085, 0x1086, HB_Mark_NonSpacing},
-  {0x1087, 0x108c, HB_Mark_SpacingCombining},
-  {0x108d, 0x108d, HB_Mark_NonSpacing},
-  {0x108e, 0x108e, HB_Letter_Other},
-  {0x108f, 0x108f, HB_Mark_SpacingCombining},
-  {0x1090, 0x1099, HB_Number_DecimalDigit},
-  {0x109a, 0x109d, HB_Other_NotAssigned},
-  {0x109e, 0x109f, HB_Symbol_Other},
-  {0x10a0, 0x10c5, HB_Letter_Uppercase},
-  {0x10c6, 0x10cf, HB_Other_NotAssigned},
-  {0x10d0, 0x10fa, HB_Letter_Other},
-  {0x10fb, 0x10fb, HB_Punctuation_Other},
-  {0x10fc, 0x10fc, HB_Letter_Modifier},
-  {0x10fd, 0x10ff, HB_Other_NotAssigned},
-  {0x1100, 0x1159, HB_Letter_Other},
-  {0x115a, 0x115e, HB_Other_NotAssigned},
-  {0x115f, 0x11a2, HB_Letter_Other},
-  {0x11a3, 0x11a7, HB_Other_NotAssigned},
-  {0x11a8, 0x11f9, HB_Letter_Other},
-  {0x11fa, 0x11ff, HB_Other_NotAssigned},
-  {0x1200, 0x1248, HB_Letter_Other},
-  {0x1249, 0x1249, HB_Other_NotAssigned},
-  {0x124a, 0x124d, HB_Letter_Other},
-  {0x124e, 0x124f, HB_Other_NotAssigned},
-  {0x1250, 0x1256, HB_Letter_Other},
-  {0x1257, 0x1257, HB_Other_NotAssigned},
-  {0x1258, 0x1258, HB_Letter_Other},
-  {0x1259, 0x1259, HB_Other_NotAssigned},
-  {0x125a, 0x125d, HB_Letter_Other},
-  {0x125e, 0x125f, HB_Other_NotAssigned},
-  {0x1260, 0x1288, HB_Letter_Other},
-  {0x1289, 0x1289, HB_Other_NotAssigned},
-  {0x128a, 0x128d, HB_Letter_Other},
-  {0x128e, 0x128f, HB_Other_NotAssigned},
-  {0x1290, 0x12b0, HB_Letter_Other},
-  {0x12b1, 0x12b1, HB_Other_NotAssigned},
-  {0x12b2, 0x12b5, HB_Letter_Other},
-  {0x12b6, 0x12b7, HB_Other_NotAssigned},
-  {0x12b8, 0x12be, HB_Letter_Other},
-  {0x12bf, 0x12bf, HB_Other_NotAssigned},
-  {0x12c0, 0x12c0, HB_Letter_Other},
-  {0x12c1, 0x12c1, HB_Other_NotAssigned},
-  {0x12c2, 0x12c5, HB_Letter_Other},
-  {0x12c6, 0x12c7, HB_Other_NotAssigned},
-  {0x12c8, 0x12d6, HB_Letter_Other},
-  {0x12d7, 0x12d7, HB_Other_NotAssigned},
-  {0x12d8, 0x1310, HB_Letter_Other},
-  {0x1311, 0x1311, HB_Other_NotAssigned},
-  {0x1312, 0x1315, HB_Letter_Other},
-  {0x1316, 0x1317, HB_Other_NotAssigned},
-  {0x1318, 0x135a, HB_Letter_Other},
-  {0x135b, 0x135e, HB_Other_NotAssigned},
-  {0x135f, 0x135f, HB_Mark_NonSpacing},
-  {0x1360, 0x1360, HB_Symbol_Other},
-  {0x1361, 0x1368, HB_Punctuation_Other},
-  {0x1369, 0x137c, HB_Number_Other},
-  {0x137d, 0x137f, HB_Other_NotAssigned},
-  {0x1380, 0x138f, HB_Letter_Other},
-  {0x1390, 0x1399, HB_Symbol_Other},
-  {0x139a, 0x139f, HB_Other_NotAssigned},
-  {0x13a0, 0x13f4, HB_Letter_Other},
-  {0x13f5, 0x1400, HB_Other_NotAssigned},
-  {0x1401, 0x166c, HB_Letter_Other},
-  {0x166d, 0x166e, HB_Punctuation_Other},
-  {0x166f, 0x1676, HB_Letter_Other},
-  {0x1677, 0x167f, HB_Other_NotAssigned},
-  {0x1680, 0x1680, HB_Separator_Space},
-  {0x1681, 0x169a, HB_Letter_Other},
-  {0x169b, 0x169b, HB_Punctuation_Open},
-  {0x169c, 0x169c, HB_Punctuation_Close},
-  {0x169d, 0x169f, HB_Other_NotAssigned},
-  {0x16a0, 0x16ea, HB_Letter_Other},
-  {0x16eb, 0x16ed, HB_Punctuation_Other},
-  {0x16ee, 0x16f0, HB_Number_Letter},
-  {0x16f1, 0x16ff, HB_Other_NotAssigned},
-  {0x1700, 0x170c, HB_Letter_Other},
-  {0x170d, 0x170d, HB_Other_NotAssigned},
-  {0x170e, 0x1711, HB_Letter_Other},
-  {0x1712, 0x1714, HB_Mark_NonSpacing},
-  {0x1715, 0x171f, HB_Other_NotAssigned},
-  {0x1720, 0x1731, HB_Letter_Other},
-  {0x1732, 0x1734, HB_Mark_NonSpacing},
-  {0x1735, 0x1736, HB_Punctuation_Other},
-  {0x1737, 0x173f, HB_Other_NotAssigned},
-  {0x1740, 0x1751, HB_Letter_Other},
-  {0x1752, 0x1753, HB_Mark_NonSpacing},
-  {0x1754, 0x175f, HB_Other_NotAssigned},
-  {0x1760, 0x176c, HB_Letter_Other},
-  {0x176d, 0x176d, HB_Other_NotAssigned},
-  {0x176e, 0x1770, HB_Letter_Other},
-  {0x1771, 0x1771, HB_Other_NotAssigned},
-  {0x1772, 0x1773, HB_Mark_NonSpacing},
-  {0x1774, 0x177f, HB_Other_NotAssigned},
-  {0x1780, 0x17b3, HB_Letter_Other},
-  {0x17b4, 0x17b5, HB_Other_Format},
-  {0x17b6, 0x17b6, HB_Mark_SpacingCombining},
-  {0x17b7, 0x17bd, HB_Mark_NonSpacing},
-  {0x17be, 0x17c5, HB_Mark_SpacingCombining},
-  {0x17c6, 0x17c6, HB_Mark_NonSpacing},
-  {0x17c7, 0x17c8, HB_Mark_SpacingCombining},
-  {0x17c9, 0x17d3, HB_Mark_NonSpacing},
-  {0x17d4, 0x17d6, HB_Punctuation_Other},
-  {0x17d7, 0x17d7, HB_Letter_Modifier},
-  {0x17d8, 0x17da, HB_Punctuation_Other},
-  {0x17db, 0x17db, HB_Symbol_Currency},
-  {0x17dc, 0x17dc, HB_Letter_Other},
-  {0x17dd, 0x17dd, HB_Mark_NonSpacing},
-  {0x17de, 0x17df, HB_Other_NotAssigned},
-  {0x17e0, 0x17e9, HB_Number_DecimalDigit},
-  {0x17ea, 0x17ef, HB_Other_NotAssigned},
-  {0x17f0, 0x17f9, HB_Number_Other},
-  {0x17fa, 0x17ff, HB_Other_NotAssigned},
-  {0x1800, 0x1805, HB_Punctuation_Other},
-  {0x1806, 0x1806, HB_Punctuation_Dash},
-  {0x1807, 0x180a, HB_Punctuation_Other},
-  {0x180b, 0x180d, HB_Mark_NonSpacing},
-  {0x180e, 0x180e, HB_Separator_Space},
-  {0x180f, 0x180f, HB_Other_NotAssigned},
-  {0x1810, 0x1819, HB_Number_DecimalDigit},
-  {0x181a, 0x181f, HB_Other_NotAssigned},
-  {0x1820, 0x1842, HB_Letter_Other},
-  {0x1843, 0x1843, HB_Letter_Modifier},
-  {0x1844, 0x1877, HB_Letter_Other},
-  {0x1878, 0x187f, HB_Other_NotAssigned},
-  {0x1880, 0x18a8, HB_Letter_Other},
-  {0x18a9, 0x18a9, HB_Mark_NonSpacing},
-  {0x18aa, 0x18aa, HB_Letter_Other},
-  {0x18ab, 0x18ff, HB_Other_NotAssigned},
-  {0x1900, 0x191c, HB_Letter_Other},
-  {0x191d, 0x191f, HB_Other_NotAssigned},
-  {0x1920, 0x1922, HB_Mark_NonSpacing},
-  {0x1923, 0x1926, HB_Mark_SpacingCombining},
-  {0x1927, 0x1928, HB_Mark_NonSpacing},
-  {0x1929, 0x192b, HB_Mark_SpacingCombining},
-  {0x192c, 0x192f, HB_Other_NotAssigned},
-  {0x1930, 0x1931, HB_Mark_SpacingCombining},
-  {0x1932, 0x1932, HB_Mark_NonSpacing},
-  {0x1933, 0x1938, HB_Mark_SpacingCombining},
-  {0x1939, 0x193b, HB_Mark_NonSpacing},
-  {0x193c, 0x193f, HB_Other_NotAssigned},
-  {0x1940, 0x1940, HB_Symbol_Other},
-  {0x1941, 0x1943, HB_Other_NotAssigned},
-  {0x1944, 0x1945, HB_Punctuation_Other},
-  {0x1946, 0x194f, HB_Number_DecimalDigit},
-  {0x1950, 0x196d, HB_Letter_Other},
-  {0x196e, 0x196f, HB_Other_NotAssigned},
-  {0x1970, 0x1974, HB_Letter_Other},
-  {0x1975, 0x197f, HB_Other_NotAssigned},
-  {0x1980, 0x19a9, HB_Letter_Other},
-  {0x19aa, 0x19af, HB_Other_NotAssigned},
-  {0x19b0, 0x19c0, HB_Mark_SpacingCombining},
-  {0x19c1, 0x19c7, HB_Letter_Other},
-  {0x19c8, 0x19c9, HB_Mark_SpacingCombining},
-  {0x19ca, 0x19cf, HB_Other_NotAssigned},
-  {0x19d0, 0x19d9, HB_Number_DecimalDigit},
-  {0x19da, 0x19dd, HB_Other_NotAssigned},
-  {0x19de, 0x19df, HB_Punctuation_Other},
-  {0x19e0, 0x19ff, HB_Symbol_Other},
-  {0x1a00, 0x1a16, HB_Letter_Other},
-  {0x1a17, 0x1a18, HB_Mark_NonSpacing},
-  {0x1a19, 0x1a1b, HB_Mark_SpacingCombining},
-  {0x1a1c, 0x1a1d, HB_Other_NotAssigned},
-  {0x1a1e, 0x1a1f, HB_Punctuation_Other},
-  {0x1a20, 0x1aff, HB_Other_NotAssigned},
-  {0x1b00, 0x1b03, HB_Mark_NonSpacing},
-  {0x1b04, 0x1b04, HB_Mark_SpacingCombining},
-  {0x1b05, 0x1b33, HB_Letter_Other},
-  {0x1b34, 0x1b34, HB_Mark_NonSpacing},
-  {0x1b35, 0x1b35, HB_Mark_SpacingCombining},
-  {0x1b36, 0x1b3a, HB_Mark_NonSpacing},
-  {0x1b3b, 0x1b3b, HB_Mark_SpacingCombining},
-  {0x1b3c, 0x1b3c, HB_Mark_NonSpacing},
-  {0x1b3d, 0x1b41, HB_Mark_SpacingCombining},
-  {0x1b42, 0x1b42, HB_Mark_NonSpacing},
-  {0x1b43, 0x1b44, HB_Mark_SpacingCombining},
-  {0x1b45, 0x1b4b, HB_Letter_Other},
-  {0x1b4c, 0x1b4f, HB_Other_NotAssigned},
-  {0x1b50, 0x1b59, HB_Number_DecimalDigit},
-  {0x1b5a, 0x1b60, HB_Punctuation_Other},
-  {0x1b61, 0x1b6a, HB_Symbol_Other},
-  {0x1b6b, 0x1b73, HB_Mark_NonSpacing},
-  {0x1b74, 0x1b7c, HB_Symbol_Other},
-  {0x1b7d, 0x1b7f, HB_Other_NotAssigned},
-  {0x1b80, 0x1b81, HB_Mark_NonSpacing},
-  {0x1b82, 0x1b82, HB_Mark_SpacingCombining},
-  {0x1b83, 0x1ba0, HB_Letter_Other},
-  {0x1ba1, 0x1ba1, HB_Mark_SpacingCombining},
-  {0x1ba2, 0x1ba5, HB_Mark_NonSpacing},
-  {0x1ba6, 0x1ba7, HB_Mark_SpacingCombining},
-  {0x1ba8, 0x1ba9, HB_Mark_NonSpacing},
-  {0x1baa, 0x1baa, HB_Mark_SpacingCombining},
-  {0x1bab, 0x1bad, HB_Other_NotAssigned},
-  {0x1bae, 0x1baf, HB_Letter_Other},
-  {0x1bb0, 0x1bb9, HB_Number_DecimalDigit},
-  {0x1bba, 0x1bff, HB_Other_NotAssigned},
-  {0x1c00, 0x1c23, HB_Letter_Other},
-  {0x1c24, 0x1c2b, HB_Mark_SpacingCombining},
-  {0x1c2c, 0x1c33, HB_Mark_NonSpacing},
-  {0x1c34, 0x1c35, HB_Mark_SpacingCombining},
-  {0x1c36, 0x1c37, HB_Mark_NonSpacing},
-  {0x1c38, 0x1c3a, HB_Other_NotAssigned},
-  {0x1c3b, 0x1c3f, HB_Punctuation_Other},
-  {0x1c40, 0x1c49, HB_Number_DecimalDigit},
-  {0x1c4a, 0x1c4c, HB_Other_NotAssigned},
-  {0x1c4d, 0x1c4f, HB_Letter_Other},
-  {0x1c50, 0x1c59, HB_Number_DecimalDigit},
-  {0x1c5a, 0x1c77, HB_Letter_Other},
-  {0x1c78, 0x1c7d, HB_Letter_Modifier},
-  {0x1c7e, 0x1c7f, HB_Punctuation_Other},
-  {0x1c80, 0x1cff, HB_Other_NotAssigned},
-  {0x1d00, 0x1d2b, HB_Letter_Lowercase},
-  {0x1d2c, 0x1d61, HB_Letter_Modifier},
-  {0x1d62, 0x1d77, HB_Letter_Lowercase},
-  {0x1d78, 0x1d78, HB_Letter_Modifier},
-  {0x1d79, 0x1d9a, HB_Letter_Lowercase},
-  {0x1d9b, 0x1dbf, HB_Letter_Modifier},
-  {0x1dc0, 0x1de6, HB_Mark_NonSpacing},
-  {0x1de7, 0x1dfd, HB_Other_NotAssigned},
-  {0x1dfe, 0x1dff, HB_Mark_NonSpacing},
-  {0x1e00, 0x1e00, HB_Letter_Uppercase},
-  {0x1e01, 0x1e01, HB_Letter_Lowercase},
-  {0x1e02, 0x1e02, HB_Letter_Uppercase},
-  {0x1e03, 0x1e03, HB_Letter_Lowercase},
-  {0x1e04, 0x1e04, HB_Letter_Uppercase},
-  {0x1e05, 0x1e05, HB_Letter_Lowercase},
-  {0x1e06, 0x1e06, HB_Letter_Uppercase},
-  {0x1e07, 0x1e07, HB_Letter_Lowercase},
-  {0x1e08, 0x1e08, HB_Letter_Uppercase},
-  {0x1e09, 0x1e09, HB_Letter_Lowercase},
-  {0x1e0a, 0x1e0a, HB_Letter_Uppercase},
-  {0x1e0b, 0x1e0b, HB_Letter_Lowercase},
-  {0x1e0c, 0x1e0c, HB_Letter_Uppercase},
-  {0x1e0d, 0x1e0d, HB_Letter_Lowercase},
-  {0x1e0e, 0x1e0e, HB_Letter_Uppercase},
-  {0x1e0f, 0x1e0f, HB_Letter_Lowercase},
-  {0x1e10, 0x1e10, HB_Letter_Uppercase},
-  {0x1e11, 0x1e11, HB_Letter_Lowercase},
-  {0x1e12, 0x1e12, HB_Letter_Uppercase},
-  {0x1e13, 0x1e13, HB_Letter_Lowercase},
-  {0x1e14, 0x1e14, HB_Letter_Uppercase},
-  {0x1e15, 0x1e15, HB_Letter_Lowercase},
-  {0x1e16, 0x1e16, HB_Letter_Uppercase},
-  {0x1e17, 0x1e17, HB_Letter_Lowercase},
-  {0x1e18, 0x1e18, HB_Letter_Uppercase},
-  {0x1e19, 0x1e19, HB_Letter_Lowercase},
-  {0x1e1a, 0x1e1a, HB_Letter_Uppercase},
-  {0x1e1b, 0x1e1b, HB_Letter_Lowercase},
-  {0x1e1c, 0x1e1c, HB_Letter_Uppercase},
-  {0x1e1d, 0x1e1d, HB_Letter_Lowercase},
-  {0x1e1e, 0x1e1e, HB_Letter_Uppercase},
-  {0x1e1f, 0x1e1f, HB_Letter_Lowercase},
-  {0x1e20, 0x1e20, HB_Letter_Uppercase},
-  {0x1e21, 0x1e21, HB_Letter_Lowercase},
-  {0x1e22, 0x1e22, HB_Letter_Uppercase},
-  {0x1e23, 0x1e23, HB_Letter_Lowercase},
-  {0x1e24, 0x1e24, HB_Letter_Uppercase},
-  {0x1e25, 0x1e25, HB_Letter_Lowercase},
-  {0x1e26, 0x1e26, HB_Letter_Uppercase},
-  {0x1e27, 0x1e27, HB_Letter_Lowercase},
-  {0x1e28, 0x1e28, HB_Letter_Uppercase},
-  {0x1e29, 0x1e29, HB_Letter_Lowercase},
-  {0x1e2a, 0x1e2a, HB_Letter_Uppercase},
-  {0x1e2b, 0x1e2b, HB_Letter_Lowercase},
-  {0x1e2c, 0x1e2c, HB_Letter_Uppercase},
-  {0x1e2d, 0x1e2d, HB_Letter_Lowercase},
-  {0x1e2e, 0x1e2e, HB_Letter_Uppercase},
-  {0x1e2f, 0x1e2f, HB_Letter_Lowercase},
-  {0x1e30, 0x1e30, HB_Letter_Uppercase},
-  {0x1e31, 0x1e31, HB_Letter_Lowercase},
-  {0x1e32, 0x1e32, HB_Letter_Uppercase},
-  {0x1e33, 0x1e33, HB_Letter_Lowercase},
-  {0x1e34, 0x1e34, HB_Letter_Uppercase},
-  {0x1e35, 0x1e35, HB_Letter_Lowercase},
-  {0x1e36, 0x1e36, HB_Letter_Uppercase},
-  {0x1e37, 0x1e37, HB_Letter_Lowercase},
-  {0x1e38, 0x1e38, HB_Letter_Uppercase},
-  {0x1e39, 0x1e39, HB_Letter_Lowercase},
-  {0x1e3a, 0x1e3a, HB_Letter_Uppercase},
-  {0x1e3b, 0x1e3b, HB_Letter_Lowercase},
-  {0x1e3c, 0x1e3c, HB_Letter_Uppercase},
-  {0x1e3d, 0x1e3d, HB_Letter_Lowercase},
-  {0x1e3e, 0x1e3e, HB_Letter_Uppercase},
-  {0x1e3f, 0x1e3f, HB_Letter_Lowercase},
-  {0x1e40, 0x1e40, HB_Letter_Uppercase},
-  {0x1e41, 0x1e41, HB_Letter_Lowercase},
-  {0x1e42, 0x1e42, HB_Letter_Uppercase},
-  {0x1e43, 0x1e43, HB_Letter_Lowercase},
-  {0x1e44, 0x1e44, HB_Letter_Uppercase},
-  {0x1e45, 0x1e45, HB_Letter_Lowercase},
-  {0x1e46, 0x1e46, HB_Letter_Uppercase},
-  {0x1e47, 0x1e47, HB_Letter_Lowercase},
-  {0x1e48, 0x1e48, HB_Letter_Uppercase},
-  {0x1e49, 0x1e49, HB_Letter_Lowercase},
-  {0x1e4a, 0x1e4a, HB_Letter_Uppercase},
-  {0x1e4b, 0x1e4b, HB_Letter_Lowercase},
-  {0x1e4c, 0x1e4c, HB_Letter_Uppercase},
-  {0x1e4d, 0x1e4d, HB_Letter_Lowercase},
-  {0x1e4e, 0x1e4e, HB_Letter_Uppercase},
-  {0x1e4f, 0x1e4f, HB_Letter_Lowercase},
-  {0x1e50, 0x1e50, HB_Letter_Uppercase},
-  {0x1e51, 0x1e51, HB_Letter_Lowercase},
-  {0x1e52, 0x1e52, HB_Letter_Uppercase},
-  {0x1e53, 0x1e53, HB_Letter_Lowercase},
-  {0x1e54, 0x1e54, HB_Letter_Uppercase},
-  {0x1e55, 0x1e55, HB_Letter_Lowercase},
-  {0x1e56, 0x1e56, HB_Letter_Uppercase},
-  {0x1e57, 0x1e57, HB_Letter_Lowercase},
-  {0x1e58, 0x1e58, HB_Letter_Uppercase},
-  {0x1e59, 0x1e59, HB_Letter_Lowercase},
-  {0x1e5a, 0x1e5a, HB_Letter_Uppercase},
-  {0x1e5b, 0x1e5b, HB_Letter_Lowercase},
-  {0x1e5c, 0x1e5c, HB_Letter_Uppercase},
-  {0x1e5d, 0x1e5d, HB_Letter_Lowercase},
-  {0x1e5e, 0x1e5e, HB_Letter_Uppercase},
-  {0x1e5f, 0x1e5f, HB_Letter_Lowercase},
-  {0x1e60, 0x1e60, HB_Letter_Uppercase},
-  {0x1e61, 0x1e61, HB_Letter_Lowercase},
-  {0x1e62, 0x1e62, HB_Letter_Uppercase},
-  {0x1e63, 0x1e63, HB_Letter_Lowercase},
-  {0x1e64, 0x1e64, HB_Letter_Uppercase},
-  {0x1e65, 0x1e65, HB_Letter_Lowercase},
-  {0x1e66, 0x1e66, HB_Letter_Uppercase},
-  {0x1e67, 0x1e67, HB_Letter_Lowercase},
-  {0x1e68, 0x1e68, HB_Letter_Uppercase},
-  {0x1e69, 0x1e69, HB_Letter_Lowercase},
-  {0x1e6a, 0x1e6a, HB_Letter_Uppercase},
-  {0x1e6b, 0x1e6b, HB_Letter_Lowercase},
-  {0x1e6c, 0x1e6c, HB_Letter_Uppercase},
-  {0x1e6d, 0x1e6d, HB_Letter_Lowercase},
-  {0x1e6e, 0x1e6e, HB_Letter_Uppercase},
-  {0x1e6f, 0x1e6f, HB_Letter_Lowercase},
-  {0x1e70, 0x1e70, HB_Letter_Uppercase},
-  {0x1e71, 0x1e71, HB_Letter_Lowercase},
-  {0x1e72, 0x1e72, HB_Letter_Uppercase},
-  {0x1e73, 0x1e73, HB_Letter_Lowercase},
-  {0x1e74, 0x1e74, HB_Letter_Uppercase},
-  {0x1e75, 0x1e75, HB_Letter_Lowercase},
-  {0x1e76, 0x1e76, HB_Letter_Uppercase},
-  {0x1e77, 0x1e77, HB_Letter_Lowercase},
-  {0x1e78, 0x1e78, HB_Letter_Uppercase},
-  {0x1e79, 0x1e79, HB_Letter_Lowercase},
-  {0x1e7a, 0x1e7a, HB_Letter_Uppercase},
-  {0x1e7b, 0x1e7b, HB_Letter_Lowercase},
-  {0x1e7c, 0x1e7c, HB_Letter_Uppercase},
-  {0x1e7d, 0x1e7d, HB_Letter_Lowercase},
-  {0x1e7e, 0x1e7e, HB_Letter_Uppercase},
-  {0x1e7f, 0x1e7f, HB_Letter_Lowercase},
-  {0x1e80, 0x1e80, HB_Letter_Uppercase},
-  {0x1e81, 0x1e81, HB_Letter_Lowercase},
-  {0x1e82, 0x1e82, HB_Letter_Uppercase},
-  {0x1e83, 0x1e83, HB_Letter_Lowercase},
-  {0x1e84, 0x1e84, HB_Letter_Uppercase},
-  {0x1e85, 0x1e85, HB_Letter_Lowercase},
-  {0x1e86, 0x1e86, HB_Letter_Uppercase},
-  {0x1e87, 0x1e87, HB_Letter_Lowercase},
-  {0x1e88, 0x1e88, HB_Letter_Uppercase},
-  {0x1e89, 0x1e89, HB_Letter_Lowercase},
-  {0x1e8a, 0x1e8a, HB_Letter_Uppercase},
-  {0x1e8b, 0x1e8b, HB_Letter_Lowercase},
-  {0x1e8c, 0x1e8c, HB_Letter_Uppercase},
-  {0x1e8d, 0x1e8d, HB_Letter_Lowercase},
-  {0x1e8e, 0x1e8e, HB_Letter_Uppercase},
-  {0x1e8f, 0x1e8f, HB_Letter_Lowercase},
-  {0x1e90, 0x1e90, HB_Letter_Uppercase},
-  {0x1e91, 0x1e91, HB_Letter_Lowercase},
-  {0x1e92, 0x1e92, HB_Letter_Uppercase},
-  {0x1e93, 0x1e93, HB_Letter_Lowercase},
-  {0x1e94, 0x1e94, HB_Letter_Uppercase},
-  {0x1e95, 0x1e9d, HB_Letter_Lowercase},
-  {0x1e9e, 0x1e9e, HB_Letter_Uppercase},
-  {0x1e9f, 0x1e9f, HB_Letter_Lowercase},
-  {0x1ea0, 0x1ea0, HB_Letter_Uppercase},
-  {0x1ea1, 0x1ea1, HB_Letter_Lowercase},
-  {0x1ea2, 0x1ea2, HB_Letter_Uppercase},
-  {0x1ea3, 0x1ea3, HB_Letter_Lowercase},
-  {0x1ea4, 0x1ea4, HB_Letter_Uppercase},
-  {0x1ea5, 0x1ea5, HB_Letter_Lowercase},
-  {0x1ea6, 0x1ea6, HB_Letter_Uppercase},
-  {0x1ea7, 0x1ea7, HB_Letter_Lowercase},
-  {0x1ea8, 0x1ea8, HB_Letter_Uppercase},
-  {0x1ea9, 0x1ea9, HB_Letter_Lowercase},
-  {0x1eaa, 0x1eaa, HB_Letter_Uppercase},
-  {0x1eab, 0x1eab, HB_Letter_Lowercase},
-  {0x1eac, 0x1eac, HB_Letter_Uppercase},
-  {0x1ead, 0x1ead, HB_Letter_Lowercase},
-  {0x1eae, 0x1eae, HB_Letter_Uppercase},
-  {0x1eaf, 0x1eaf, HB_Letter_Lowercase},
-  {0x1eb0, 0x1eb0, HB_Letter_Uppercase},
-  {0x1eb1, 0x1eb1, HB_Letter_Lowercase},
-  {0x1eb2, 0x1eb2, HB_Letter_Uppercase},
-  {0x1eb3, 0x1eb3, HB_Letter_Lowercase},
-  {0x1eb4, 0x1eb4, HB_Letter_Uppercase},
-  {0x1eb5, 0x1eb5, HB_Letter_Lowercase},
-  {0x1eb6, 0x1eb6, HB_Letter_Uppercase},
-  {0x1eb7, 0x1eb7, HB_Letter_Lowercase},
-  {0x1eb8, 0x1eb8, HB_Letter_Uppercase},
-  {0x1eb9, 0x1eb9, HB_Letter_Lowercase},
-  {0x1eba, 0x1eba, HB_Letter_Uppercase},
-  {0x1ebb, 0x1ebb, HB_Letter_Lowercase},
-  {0x1ebc, 0x1ebc, HB_Letter_Uppercase},
-  {0x1ebd, 0x1ebd, HB_Letter_Lowercase},
-  {0x1ebe, 0x1ebe, HB_Letter_Uppercase},
-  {0x1ebf, 0x1ebf, HB_Letter_Lowercase},
-  {0x1ec0, 0x1ec0, HB_Letter_Uppercase},
-  {0x1ec1, 0x1ec1, HB_Letter_Lowercase},
-  {0x1ec2, 0x1ec2, HB_Letter_Uppercase},
-  {0x1ec3, 0x1ec3, HB_Letter_Lowercase},
-  {0x1ec4, 0x1ec4, HB_Letter_Uppercase},
-  {0x1ec5, 0x1ec5, HB_Letter_Lowercase},
-  {0x1ec6, 0x1ec6, HB_Letter_Uppercase},
-  {0x1ec7, 0x1ec7, HB_Letter_Lowercase},
-  {0x1ec8, 0x1ec8, HB_Letter_Uppercase},
-  {0x1ec9, 0x1ec9, HB_Letter_Lowercase},
-  {0x1eca, 0x1eca, HB_Letter_Uppercase},
-  {0x1ecb, 0x1ecb, HB_Letter_Lowercase},
-  {0x1ecc, 0x1ecc, HB_Letter_Uppercase},
-  {0x1ecd, 0x1ecd, HB_Letter_Lowercase},
-  {0x1ece, 0x1ece, HB_Letter_Uppercase},
-  {0x1ecf, 0x1ecf, HB_Letter_Lowercase},
-  {0x1ed0, 0x1ed0, HB_Letter_Uppercase},
-  {0x1ed1, 0x1ed1, HB_Letter_Lowercase},
-  {0x1ed2, 0x1ed2, HB_Letter_Uppercase},
-  {0x1ed3, 0x1ed3, HB_Letter_Lowercase},
-  {0x1ed4, 0x1ed4, HB_Letter_Uppercase},
-  {0x1ed5, 0x1ed5, HB_Letter_Lowercase},
-  {0x1ed6, 0x1ed6, HB_Letter_Uppercase},
-  {0x1ed7, 0x1ed7, HB_Letter_Lowercase},
-  {0x1ed8, 0x1ed8, HB_Letter_Uppercase},
-  {0x1ed9, 0x1ed9, HB_Letter_Lowercase},
-  {0x1eda, 0x1eda, HB_Letter_Uppercase},
-  {0x1edb, 0x1edb, HB_Letter_Lowercase},
-  {0x1edc, 0x1edc, HB_Letter_Uppercase},
-  {0x1edd, 0x1edd, HB_Letter_Lowercase},
-  {0x1ede, 0x1ede, HB_Letter_Uppercase},
-  {0x1edf, 0x1edf, HB_Letter_Lowercase},
-  {0x1ee0, 0x1ee0, HB_Letter_Uppercase},
-  {0x1ee1, 0x1ee1, HB_Letter_Lowercase},
-  {0x1ee2, 0x1ee2, HB_Letter_Uppercase},
-  {0x1ee3, 0x1ee3, HB_Letter_Lowercase},
-  {0x1ee4, 0x1ee4, HB_Letter_Uppercase},
-  {0x1ee5, 0x1ee5, HB_Letter_Lowercase},
-  {0x1ee6, 0x1ee6, HB_Letter_Uppercase},
-  {0x1ee7, 0x1ee7, HB_Letter_Lowercase},
-  {0x1ee8, 0x1ee8, HB_Letter_Uppercase},
-  {0x1ee9, 0x1ee9, HB_Letter_Lowercase},
-  {0x1eea, 0x1eea, HB_Letter_Uppercase},
-  {0x1eeb, 0x1eeb, HB_Letter_Lowercase},
-  {0x1eec, 0x1eec, HB_Letter_Uppercase},
-  {0x1eed, 0x1eed, HB_Letter_Lowercase},
-  {0x1eee, 0x1eee, HB_Letter_Uppercase},
-  {0x1eef, 0x1eef, HB_Letter_Lowercase},
-  {0x1ef0, 0x1ef0, HB_Letter_Uppercase},
-  {0x1ef1, 0x1ef1, HB_Letter_Lowercase},
-  {0x1ef2, 0x1ef2, HB_Letter_Uppercase},
-  {0x1ef3, 0x1ef3, HB_Letter_Lowercase},
-  {0x1ef4, 0x1ef4, HB_Letter_Uppercase},
-  {0x1ef5, 0x1ef5, HB_Letter_Lowercase},
-  {0x1ef6, 0x1ef6, HB_Letter_Uppercase},
-  {0x1ef7, 0x1ef7, HB_Letter_Lowercase},
-  {0x1ef8, 0x1ef8, HB_Letter_Uppercase},
-  {0x1ef9, 0x1ef9, HB_Letter_Lowercase},
-  {0x1efa, 0x1efa, HB_Letter_Uppercase},
-  {0x1efb, 0x1efb, HB_Letter_Lowercase},
-  {0x1efc, 0x1efc, HB_Letter_Uppercase},
-  {0x1efd, 0x1efd, HB_Letter_Lowercase},
-  {0x1efe, 0x1efe, HB_Letter_Uppercase},
-  {0x1eff, 0x1f07, HB_Letter_Lowercase},
-  {0x1f08, 0x1f0f, HB_Letter_Uppercase},
-  {0x1f10, 0x1f15, HB_Letter_Lowercase},
-  {0x1f16, 0x1f17, HB_Other_NotAssigned},
-  {0x1f18, 0x1f1d, HB_Letter_Uppercase},
-  {0x1f1e, 0x1f1f, HB_Other_NotAssigned},
-  {0x1f20, 0x1f27, HB_Letter_Lowercase},
-  {0x1f28, 0x1f2f, HB_Letter_Uppercase},
-  {0x1f30, 0x1f37, HB_Letter_Lowercase},
-  {0x1f38, 0x1f3f, HB_Letter_Uppercase},
-  {0x1f40, 0x1f45, HB_Letter_Lowercase},
-  {0x1f46, 0x1f47, HB_Other_NotAssigned},
-  {0x1f48, 0x1f4d, HB_Letter_Uppercase},
-  {0x1f4e, 0x1f4f, HB_Other_NotAssigned},
-  {0x1f50, 0x1f57, HB_Letter_Lowercase},
-  {0x1f58, 0x1f58, HB_Other_NotAssigned},
-  {0x1f59, 0x1f59, HB_Letter_Uppercase},
-  {0x1f5a, 0x1f5a, HB_Other_NotAssigned},
-  {0x1f5b, 0x1f5b, HB_Letter_Uppercase},
-  {0x1f5c, 0x1f5c, HB_Other_NotAssigned},
-  {0x1f5d, 0x1f5d, HB_Letter_Uppercase},
-  {0x1f5e, 0x1f5e, HB_Other_NotAssigned},
-  {0x1f5f, 0x1f5f, HB_Letter_Uppercase},
-  {0x1f60, 0x1f67, HB_Letter_Lowercase},
-  {0x1f68, 0x1f6f, HB_Letter_Uppercase},
-  {0x1f70, 0x1f7d, HB_Letter_Lowercase},
-  {0x1f7e, 0x1f7f, HB_Other_NotAssigned},
-  {0x1f80, 0x1f87, HB_Letter_Lowercase},
-  {0x1f88, 0x1f8f, HB_Letter_Titlecase},
-  {0x1f90, 0x1f97, HB_Letter_Lowercase},
-  {0x1f98, 0x1f9f, HB_Letter_Titlecase},
-  {0x1fa0, 0x1fa7, HB_Letter_Lowercase},
-  {0x1fa8, 0x1faf, HB_Letter_Titlecase},
-  {0x1fb0, 0x1fb4, HB_Letter_Lowercase},
-  {0x1fb5, 0x1fb5, HB_Other_NotAssigned},
-  {0x1fb6, 0x1fb7, HB_Letter_Lowercase},
-  {0x1fb8, 0x1fbb, HB_Letter_Uppercase},
-  {0x1fbc, 0x1fbc, HB_Letter_Titlecase},
-  {0x1fbd, 0x1fbd, HB_Symbol_Modifier},
-  {0x1fbe, 0x1fbe, HB_Letter_Lowercase},
-  {0x1fbf, 0x1fc1, HB_Symbol_Modifier},
-  {0x1fc2, 0x1fc4, HB_Letter_Lowercase},
-  {0x1fc5, 0x1fc5, HB_Other_NotAssigned},
-  {0x1fc6, 0x1fc7, HB_Letter_Lowercase},
-  {0x1fc8, 0x1fcb, HB_Letter_Uppercase},
-  {0x1fcc, 0x1fcc, HB_Letter_Titlecase},
-  {0x1fcd, 0x1fcf, HB_Symbol_Modifier},
-  {0x1fd0, 0x1fd3, HB_Letter_Lowercase},
-  {0x1fd4, 0x1fd5, HB_Other_NotAssigned},
-  {0x1fd6, 0x1fd7, HB_Letter_Lowercase},
-  {0x1fd8, 0x1fdb, HB_Letter_Uppercase},
-  {0x1fdc, 0x1fdc, HB_Other_NotAssigned},
-  {0x1fdd, 0x1fdf, HB_Symbol_Modifier},
-  {0x1fe0, 0x1fe7, HB_Letter_Lowercase},
-  {0x1fe8, 0x1fec, HB_Letter_Uppercase},
-  {0x1fed, 0x1fef, HB_Symbol_Modifier},
-  {0x1ff0, 0x1ff1, HB_Other_NotAssigned},
-  {0x1ff2, 0x1ff4, HB_Letter_Lowercase},
-  {0x1ff5, 0x1ff5, HB_Other_NotAssigned},
-  {0x1ff6, 0x1ff7, HB_Letter_Lowercase},
-  {0x1ff8, 0x1ffb, HB_Letter_Uppercase},
-  {0x1ffc, 0x1ffc, HB_Letter_Titlecase},
-  {0x1ffd, 0x1ffe, HB_Symbol_Modifier},
-  {0x1fff, 0x1fff, HB_Other_NotAssigned},
-  {0x2000, 0x200a, HB_Separator_Space},
-  {0x200b, 0x200f, HB_Other_Format},
-  {0x2010, 0x2015, HB_Punctuation_Dash},
-  {0x2016, 0x2017, HB_Punctuation_Other},
-  {0x2018, 0x2018, HB_Punctuation_InitialQuote},
-  {0x2019, 0x2019, HB_Punctuation_FinalQuote},
-  {0x201a, 0x201a, HB_Punctuation_Open},
-  {0x201b, 0x201c, HB_Punctuation_InitialQuote},
-  {0x201d, 0x201d, HB_Punctuation_FinalQuote},
-  {0x201e, 0x201e, HB_Punctuation_Open},
-  {0x201f, 0x201f, HB_Punctuation_InitialQuote},
-  {0x2020, 0x2027, HB_Punctuation_Other},
-  {0x2028, 0x2028, HB_Separator_Line},
-  {0x2029, 0x2029, HB_Separator_Paragraph},
-  {0x202a, 0x202e, HB_Other_Format},
-  {0x202f, 0x202f, HB_Separator_Space},
-  {0x2030, 0x2038, HB_Punctuation_Other},
-  {0x2039, 0x2039, HB_Punctuation_InitialQuote},
-  {0x203a, 0x203a, HB_Punctuation_FinalQuote},
-  {0x203b, 0x203e, HB_Punctuation_Other},
-  {0x203f, 0x2040, HB_Punctuation_Connector},
-  {0x2041, 0x2043, HB_Punctuation_Other},
-  {0x2044, 0x2044, HB_Symbol_Math},
-  {0x2045, 0x2045, HB_Punctuation_Open},
-  {0x2046, 0x2046, HB_Punctuation_Close},
-  {0x2047, 0x2051, HB_Punctuation_Other},
-  {0x2052, 0x2052, HB_Symbol_Math},
-  {0x2053, 0x2053, HB_Punctuation_Other},
-  {0x2054, 0x2054, HB_Punctuation_Connector},
-  {0x2055, 0x205e, HB_Punctuation_Other},
-  {0x205f, 0x205f, HB_Separator_Space},
-  {0x2060, 0x2064, HB_Other_Format},
-  {0x2065, 0x2069, HB_Other_NotAssigned},
-  {0x206a, 0x206f, HB_Other_Format},
-  {0x2070, 0x2070, HB_Number_Other},
-  {0x2071, 0x2071, HB_Letter_Lowercase},
-  {0x2072, 0x2073, HB_Other_NotAssigned},
-  {0x2074, 0x2079, HB_Number_Other},
-  {0x207a, 0x207c, HB_Symbol_Math},
-  {0x207d, 0x207d, HB_Punctuation_Open},
-  {0x207e, 0x207e, HB_Punctuation_Close},
-  {0x207f, 0x207f, HB_Letter_Lowercase},
-  {0x2080, 0x2089, HB_Number_Other},
-  {0x208a, 0x208c, HB_Symbol_Math},
-  {0x208d, 0x208d, HB_Punctuation_Open},
-  {0x208e, 0x208e, HB_Punctuation_Close},
-  {0x208f, 0x208f, HB_Other_NotAssigned},
-  {0x2090, 0x2094, HB_Letter_Modifier},
-  {0x2095, 0x209f, HB_Other_NotAssigned},
-  {0x20a0, 0x20b5, HB_Symbol_Currency},
-  {0x20b6, 0x20cf, HB_Other_NotAssigned},
-  {0x20d0, 0x20dc, HB_Mark_NonSpacing},
-  {0x20dd, 0x20e0, HB_Mark_Enclosing},
-  {0x20e1, 0x20e1, HB_Mark_NonSpacing},
-  {0x20e2, 0x20e4, HB_Mark_Enclosing},
-  {0x20e5, 0x20f0, HB_Mark_NonSpacing},
-  {0x20f1, 0x20ff, HB_Other_NotAssigned},
-  {0x2100, 0x2101, HB_Symbol_Other},
-  {0x2102, 0x2102, HB_Letter_Uppercase},
-  {0x2103, 0x2106, HB_Symbol_Other},
-  {0x2107, 0x2107, HB_Letter_Uppercase},
-  {0x2108, 0x2109, HB_Symbol_Other},
-  {0x210a, 0x210a, HB_Letter_Lowercase},
-  {0x210b, 0x210d, HB_Letter_Uppercase},
-  {0x210e, 0x210f, HB_Letter_Lowercase},
-  {0x2110, 0x2112, HB_Letter_Uppercase},
-  {0x2113, 0x2113, HB_Letter_Lowercase},
-  {0x2114, 0x2114, HB_Symbol_Other},
-  {0x2115, 0x2115, HB_Letter_Uppercase},
-  {0x2116, 0x2118, HB_Symbol_Other},
-  {0x2119, 0x211d, HB_Letter_Uppercase},
-  {0x211e, 0x2123, HB_Symbol_Other},
-  {0x2124, 0x2124, HB_Letter_Uppercase},
-  {0x2125, 0x2125, HB_Symbol_Other},
-  {0x2126, 0x2126, HB_Letter_Uppercase},
-  {0x2127, 0x2127, HB_Symbol_Other},
-  {0x2128, 0x2128, HB_Letter_Uppercase},
-  {0x2129, 0x2129, HB_Symbol_Other},
-  {0x212a, 0x212d, HB_Letter_Uppercase},
-  {0x212e, 0x212e, HB_Symbol_Other},
-  {0x212f, 0x212f, HB_Letter_Lowercase},
-  {0x2130, 0x2133, HB_Letter_Uppercase},
-  {0x2134, 0x2134, HB_Letter_Lowercase},
-  {0x2135, 0x2138, HB_Letter_Other},
-  {0x2139, 0x2139, HB_Letter_Lowercase},
-  {0x213a, 0x213b, HB_Symbol_Other},
-  {0x213c, 0x213d, HB_Letter_Lowercase},
-  {0x213e, 0x213f, HB_Letter_Uppercase},
-  {0x2140, 0x2144, HB_Symbol_Math},
-  {0x2145, 0x2145, HB_Letter_Uppercase},
-  {0x2146, 0x2149, HB_Letter_Lowercase},
-  {0x214a, 0x214a, HB_Symbol_Other},
-  {0x214b, 0x214b, HB_Symbol_Math},
-  {0x214c, 0x214d, HB_Symbol_Other},
-  {0x214e, 0x214e, HB_Letter_Lowercase},
-  {0x214f, 0x214f, HB_Symbol_Other},
-  {0x2150, 0x2152, HB_Other_NotAssigned},
-  {0x2153, 0x215f, HB_Number_Other},
-  {0x2160, 0x2182, HB_Number_Letter},
-  {0x2183, 0x2183, HB_Letter_Uppercase},
-  {0x2184, 0x2184, HB_Letter_Lowercase},
-  {0x2185, 0x2188, HB_Number_Letter},
-  {0x2189, 0x218f, HB_Other_NotAssigned},
-  {0x2190, 0x2194, HB_Symbol_Math},
-  {0x2195, 0x2199, HB_Symbol_Other},
-  {0x219a, 0x219b, HB_Symbol_Math},
-  {0x219c, 0x219f, HB_Symbol_Other},
-  {0x21a0, 0x21a0, HB_Symbol_Math},
-  {0x21a1, 0x21a2, HB_Symbol_Other},
-  {0x21a3, 0x21a3, HB_Symbol_Math},
-  {0x21a4, 0x21a5, HB_Symbol_Other},
-  {0x21a6, 0x21a6, HB_Symbol_Math},
-  {0x21a7, 0x21ad, HB_Symbol_Other},
-  {0x21ae, 0x21ae, HB_Symbol_Math},
-  {0x21af, 0x21cd, HB_Symbol_Other},
-  {0x21ce, 0x21cf, HB_Symbol_Math},
-  {0x21d0, 0x21d1, HB_Symbol_Other},
-  {0x21d2, 0x21d2, HB_Symbol_Math},
-  {0x21d3, 0x21d3, HB_Symbol_Other},
-  {0x21d4, 0x21d4, HB_Symbol_Math},
-  {0x21d5, 0x21f3, HB_Symbol_Other},
-  {0x21f4, 0x22ff, HB_Symbol_Math},
-  {0x2300, 0x2307, HB_Symbol_Other},
-  {0x2308, 0x230b, HB_Symbol_Math},
-  {0x230c, 0x231f, HB_Symbol_Other},
-  {0x2320, 0x2321, HB_Symbol_Math},
-  {0x2322, 0x2328, HB_Symbol_Other},
-  {0x2329, 0x2329, HB_Punctuation_Open},
-  {0x232a, 0x232a, HB_Punctuation_Close},
-  {0x232b, 0x237b, HB_Symbol_Other},
-  {0x237c, 0x237c, HB_Symbol_Math},
-  {0x237d, 0x239a, HB_Symbol_Other},
-  {0x239b, 0x23b3, HB_Symbol_Math},
-  {0x23b4, 0x23db, HB_Symbol_Other},
-  {0x23dc, 0x23e1, HB_Symbol_Math},
-  {0x23e2, 0x23e7, HB_Symbol_Other},
-  {0x23e8, 0x23ff, HB_Other_NotAssigned},
-  {0x2400, 0x2426, HB_Symbol_Other},
-  {0x2427, 0x243f, HB_Other_NotAssigned},
-  {0x2440, 0x244a, HB_Symbol_Other},
-  {0x244b, 0x245f, HB_Other_NotAssigned},
-  {0x2460, 0x249b, HB_Number_Other},
-  {0x249c, 0x24e9, HB_Symbol_Other},
-  {0x24ea, 0x24ff, HB_Number_Other},
-  {0x2500, 0x25b6, HB_Symbol_Other},
-  {0x25b7, 0x25b7, HB_Symbol_Math},
-  {0x25b8, 0x25c0, HB_Symbol_Other},
-  {0x25c1, 0x25c1, HB_Symbol_Math},
-  {0x25c2, 0x25f7, HB_Symbol_Other},
-  {0x25f8, 0x25ff, HB_Symbol_Math},
-  {0x2600, 0x266e, HB_Symbol_Other},
-  {0x266f, 0x266f, HB_Symbol_Math},
-  {0x2670, 0x269d, HB_Symbol_Other},
-  {0x269e, 0x269f, HB_Other_NotAssigned},
-  {0x26a0, 0x26bc, HB_Symbol_Other},
-  {0x26bd, 0x26bf, HB_Other_NotAssigned},
-  {0x26c0, 0x26c3, HB_Symbol_Other},
-  {0x26c4, 0x2700, HB_Other_NotAssigned},
-  {0x2701, 0x2704, HB_Symbol_Other},
-  {0x2705, 0x2705, HB_Other_NotAssigned},
-  {0x2706, 0x2709, HB_Symbol_Other},
-  {0x270a, 0x270b, HB_Other_NotAssigned},
-  {0x270c, 0x2727, HB_Symbol_Other},
-  {0x2728, 0x2728, HB_Other_NotAssigned},
-  {0x2729, 0x274b, HB_Symbol_Other},
-  {0x274c, 0x274c, HB_Other_NotAssigned},
-  {0x274d, 0x274d, HB_Symbol_Other},
-  {0x274e, 0x274e, HB_Other_NotAssigned},
-  {0x274f, 0x2752, HB_Symbol_Other},
-  {0x2753, 0x2755, HB_Other_NotAssigned},
-  {0x2756, 0x2756, HB_Symbol_Other},
-  {0x2757, 0x2757, HB_Other_NotAssigned},
-  {0x2758, 0x275e, HB_Symbol_Other},
-  {0x275f, 0x2760, HB_Other_NotAssigned},
-  {0x2761, 0x2767, HB_Symbol_Other},
-  {0x2768, 0x2768, HB_Punctuation_Open},
-  {0x2769, 0x2769, HB_Punctuation_Close},
-  {0x276a, 0x276a, HB_Punctuation_Open},
-  {0x276b, 0x276b, HB_Punctuation_Close},
-  {0x276c, 0x276c, HB_Punctuation_Open},
-  {0x276d, 0x276d, HB_Punctuation_Close},
-  {0x276e, 0x276e, HB_Punctuation_Open},
-  {0x276f, 0x276f, HB_Punctuation_Close},
-  {0x2770, 0x2770, HB_Punctuation_Open},
-  {0x2771, 0x2771, HB_Punctuation_Close},
-  {0x2772, 0x2772, HB_Punctuation_Open},
-  {0x2773, 0x2773, HB_Punctuation_Close},
-  {0x2774, 0x2774, HB_Punctuation_Open},
-  {0x2775, 0x2775, HB_Punctuation_Close},
-  {0x2776, 0x2793, HB_Number_Other},
-  {0x2794, 0x2794, HB_Symbol_Other},
-  {0x2795, 0x2797, HB_Other_NotAssigned},
-  {0x2798, 0x27af, HB_Symbol_Other},
-  {0x27b0, 0x27b0, HB_Other_NotAssigned},
-  {0x27b1, 0x27be, HB_Symbol_Other},
-  {0x27bf, 0x27bf, HB_Other_NotAssigned},
-  {0x27c0, 0x27c4, HB_Symbol_Math},
-  {0x27c5, 0x27c5, HB_Punctuation_Open},
-  {0x27c6, 0x27c6, HB_Punctuation_Close},
-  {0x27c7, 0x27ca, HB_Symbol_Math},
-  {0x27cb, 0x27cb, HB_Other_NotAssigned},
-  {0x27cc, 0x27cc, HB_Symbol_Math},
-  {0x27cd, 0x27cf, HB_Other_NotAssigned},
-  {0x27d0, 0x27e5, HB_Symbol_Math},
-  {0x27e6, 0x27e6, HB_Punctuation_Open},
-  {0x27e7, 0x27e7, HB_Punctuation_Close},
-  {0x27e8, 0x27e8, HB_Punctuation_Open},
-  {0x27e9, 0x27e9, HB_Punctuation_Close},
-  {0x27ea, 0x27ea, HB_Punctuation_Open},
-  {0x27eb, 0x27eb, HB_Punctuation_Close},
-  {0x27ec, 0x27ec, HB_Punctuation_Open},
-  {0x27ed, 0x27ed, HB_Punctuation_Close},
-  {0x27ee, 0x27ee, HB_Punctuation_Open},
-  {0x27ef, 0x27ef, HB_Punctuation_Close},
-  {0x27f0, 0x27ff, HB_Symbol_Math},
-  {0x2800, 0x28ff, HB_Symbol_Other},
-  {0x2900, 0x2982, HB_Symbol_Math},
-  {0x2983, 0x2983, HB_Punctuation_Open},
-  {0x2984, 0x2984, HB_Punctuation_Close},
-  {0x2985, 0x2985, HB_Punctuation_Open},
-  {0x2986, 0x2986, HB_Punctuation_Close},
-  {0x2987, 0x2987, HB_Punctuation_Open},
-  {0x2988, 0x2988, HB_Punctuation_Close},
-  {0x2989, 0x2989, HB_Punctuation_Open},
-  {0x298a, 0x298a, HB_Punctuation_Close},
-  {0x298b, 0x298b, HB_Punctuation_Open},
-  {0x298c, 0x298c, HB_Punctuation_Close},
-  {0x298d, 0x298d, HB_Punctuation_Open},
-  {0x298e, 0x298e, HB_Punctuation_Close},
-  {0x298f, 0x298f, HB_Punctuation_Open},
-  {0x2990, 0x2990, HB_Punctuation_Close},
-  {0x2991, 0x2991, HB_Punctuation_Open},
-  {0x2992, 0x2992, HB_Punctuation_Close},
-  {0x2993, 0x2993, HB_Punctuation_Open},
-  {0x2994, 0x2994, HB_Punctuation_Close},
-  {0x2995, 0x2995, HB_Punctuation_Open},
-  {0x2996, 0x2996, HB_Punctuation_Close},
-  {0x2997, 0x2997, HB_Punctuation_Open},
-  {0x2998, 0x2998, HB_Punctuation_Close},
-  {0x2999, 0x29d7, HB_Symbol_Math},
-  {0x29d8, 0x29d8, HB_Punctuation_Open},
-  {0x29d9, 0x29d9, HB_Punctuation_Close},
-  {0x29da, 0x29da, HB_Punctuation_Open},
-  {0x29db, 0x29db, HB_Punctuation_Close},
-  {0x29dc, 0x29fb, HB_Symbol_Math},
-  {0x29fc, 0x29fc, HB_Punctuation_Open},
-  {0x29fd, 0x29fd, HB_Punctuation_Close},
-  {0x29fe, 0x2aff, HB_Symbol_Math},
-  {0x2b00, 0x2b2f, HB_Symbol_Other},
-  {0x2b30, 0x2b44, HB_Symbol_Math},
-  {0x2b45, 0x2b46, HB_Symbol_Other},
-  {0x2b47, 0x2b4c, HB_Symbol_Math},
-  {0x2b4d, 0x2b4f, HB_Other_NotAssigned},
-  {0x2b50, 0x2b54, HB_Symbol_Other},
-  {0x2b55, 0x2bff, HB_Other_NotAssigned},
-  {0x2c00, 0x2c2e, HB_Letter_Uppercase},
-  {0x2c2f, 0x2c2f, HB_Other_NotAssigned},
-  {0x2c30, 0x2c5e, HB_Letter_Lowercase},
-  {0x2c5f, 0x2c5f, HB_Other_NotAssigned},
-  {0x2c60, 0x2c60, HB_Letter_Uppercase},
-  {0x2c61, 0x2c61, HB_Letter_Lowercase},
-  {0x2c62, 0x2c64, HB_Letter_Uppercase},
-  {0x2c65, 0x2c66, HB_Letter_Lowercase},
-  {0x2c67, 0x2c67, HB_Letter_Uppercase},
-  {0x2c68, 0x2c68, HB_Letter_Lowercase},
-  {0x2c69, 0x2c69, HB_Letter_Uppercase},
-  {0x2c6a, 0x2c6a, HB_Letter_Lowercase},
-  {0x2c6b, 0x2c6b, HB_Letter_Uppercase},
-  {0x2c6c, 0x2c6c, HB_Letter_Lowercase},
-  {0x2c6d, 0x2c6f, HB_Letter_Uppercase},
-  {0x2c70, 0x2c70, HB_Other_NotAssigned},
-  {0x2c71, 0x2c71, HB_Letter_Lowercase},
-  {0x2c72, 0x2c72, HB_Letter_Uppercase},
-  {0x2c73, 0x2c74, HB_Letter_Lowercase},
-  {0x2c75, 0x2c75, HB_Letter_Uppercase},
-  {0x2c76, 0x2c7c, HB_Letter_Lowercase},
-  {0x2c7d, 0x2c7d, HB_Letter_Modifier},
-  {0x2c7e, 0x2c7f, HB_Other_NotAssigned},
-  {0x2c80, 0x2c80, HB_Letter_Uppercase},
-  {0x2c81, 0x2c81, HB_Letter_Lowercase},
-  {0x2c82, 0x2c82, HB_Letter_Uppercase},
-  {0x2c83, 0x2c83, HB_Letter_Lowercase},
-  {0x2c84, 0x2c84, HB_Letter_Uppercase},
-  {0x2c85, 0x2c85, HB_Letter_Lowercase},
-  {0x2c86, 0x2c86, HB_Letter_Uppercase},
-  {0x2c87, 0x2c87, HB_Letter_Lowercase},
-  {0x2c88, 0x2c88, HB_Letter_Uppercase},
-  {0x2c89, 0x2c89, HB_Letter_Lowercase},
-  {0x2c8a, 0x2c8a, HB_Letter_Uppercase},
-  {0x2c8b, 0x2c8b, HB_Letter_Lowercase},
-  {0x2c8c, 0x2c8c, HB_Letter_Uppercase},
-  {0x2c8d, 0x2c8d, HB_Letter_Lowercase},
-  {0x2c8e, 0x2c8e, HB_Letter_Uppercase},
-  {0x2c8f, 0x2c8f, HB_Letter_Lowercase},
-  {0x2c90, 0x2c90, HB_Letter_Uppercase},
-  {0x2c91, 0x2c91, HB_Letter_Lowercase},
-  {0x2c92, 0x2c92, HB_Letter_Uppercase},
-  {0x2c93, 0x2c93, HB_Letter_Lowercase},
-  {0x2c94, 0x2c94, HB_Letter_Uppercase},
-  {0x2c95, 0x2c95, HB_Letter_Lowercase},
-  {0x2c96, 0x2c96, HB_Letter_Uppercase},
-  {0x2c97, 0x2c97, HB_Letter_Lowercase},
-  {0x2c98, 0x2c98, HB_Letter_Uppercase},
-  {0x2c99, 0x2c99, HB_Letter_Lowercase},
-  {0x2c9a, 0x2c9a, HB_Letter_Uppercase},
-  {0x2c9b, 0x2c9b, HB_Letter_Lowercase},
-  {0x2c9c, 0x2c9c, HB_Letter_Uppercase},
-  {0x2c9d, 0x2c9d, HB_Letter_Lowercase},
-  {0x2c9e, 0x2c9e, HB_Letter_Uppercase},
-  {0x2c9f, 0x2c9f, HB_Letter_Lowercase},
-  {0x2ca0, 0x2ca0, HB_Letter_Uppercase},
-  {0x2ca1, 0x2ca1, HB_Letter_Lowercase},
-  {0x2ca2, 0x2ca2, HB_Letter_Uppercase},
-  {0x2ca3, 0x2ca3, HB_Letter_Lowercase},
-  {0x2ca4, 0x2ca4, HB_Letter_Uppercase},
-  {0x2ca5, 0x2ca5, HB_Letter_Lowercase},
-  {0x2ca6, 0x2ca6, HB_Letter_Uppercase},
-  {0x2ca7, 0x2ca7, HB_Letter_Lowercase},
-  {0x2ca8, 0x2ca8, HB_Letter_Uppercase},
-  {0x2ca9, 0x2ca9, HB_Letter_Lowercase},
-  {0x2caa, 0x2caa, HB_Letter_Uppercase},
-  {0x2cab, 0x2cab, HB_Letter_Lowercase},
-  {0x2cac, 0x2cac, HB_Letter_Uppercase},
-  {0x2cad, 0x2cad, HB_Letter_Lowercase},
-  {0x2cae, 0x2cae, HB_Letter_Uppercase},
-  {0x2caf, 0x2caf, HB_Letter_Lowercase},
-  {0x2cb0, 0x2cb0, HB_Letter_Uppercase},
-  {0x2cb1, 0x2cb1, HB_Letter_Lowercase},
-  {0x2cb2, 0x2cb2, HB_Letter_Uppercase},
-  {0x2cb3, 0x2cb3, HB_Letter_Lowercase},
-  {0x2cb4, 0x2cb4, HB_Letter_Uppercase},
-  {0x2cb5, 0x2cb5, HB_Letter_Lowercase},
-  {0x2cb6, 0x2cb6, HB_Letter_Uppercase},
-  {0x2cb7, 0x2cb7, HB_Letter_Lowercase},
-  {0x2cb8, 0x2cb8, HB_Letter_Uppercase},
-  {0x2cb9, 0x2cb9, HB_Letter_Lowercase},
-  {0x2cba, 0x2cba, HB_Letter_Uppercase},
-  {0x2cbb, 0x2cbb, HB_Letter_Lowercase},
-  {0x2cbc, 0x2cbc, HB_Letter_Uppercase},
-  {0x2cbd, 0x2cbd, HB_Letter_Lowercase},
-  {0x2cbe, 0x2cbe, HB_Letter_Uppercase},
-  {0x2cbf, 0x2cbf, HB_Letter_Lowercase},
-  {0x2cc0, 0x2cc0, HB_Letter_Uppercase},
-  {0x2cc1, 0x2cc1, HB_Letter_Lowercase},
-  {0x2cc2, 0x2cc2, HB_Letter_Uppercase},
-  {0x2cc3, 0x2cc3, HB_Letter_Lowercase},
-  {0x2cc4, 0x2cc4, HB_Letter_Uppercase},
-  {0x2cc5, 0x2cc5, HB_Letter_Lowercase},
-  {0x2cc6, 0x2cc6, HB_Letter_Uppercase},
-  {0x2cc7, 0x2cc7, HB_Letter_Lowercase},
-  {0x2cc8, 0x2cc8, HB_Letter_Uppercase},
-  {0x2cc9, 0x2cc9, HB_Letter_Lowercase},
-  {0x2cca, 0x2cca, HB_Letter_Uppercase},
-  {0x2ccb, 0x2ccb, HB_Letter_Lowercase},
-  {0x2ccc, 0x2ccc, HB_Letter_Uppercase},
-  {0x2ccd, 0x2ccd, HB_Letter_Lowercase},
-  {0x2cce, 0x2cce, HB_Letter_Uppercase},
-  {0x2ccf, 0x2ccf, HB_Letter_Lowercase},
-  {0x2cd0, 0x2cd0, HB_Letter_Uppercase},
-  {0x2cd1, 0x2cd1, HB_Letter_Lowercase},
-  {0x2cd2, 0x2cd2, HB_Letter_Uppercase},
-  {0x2cd3, 0x2cd3, HB_Letter_Lowercase},
-  {0x2cd4, 0x2cd4, HB_Letter_Uppercase},
-  {0x2cd5, 0x2cd5, HB_Letter_Lowercase},
-  {0x2cd6, 0x2cd6, HB_Letter_Uppercase},
-  {0x2cd7, 0x2cd7, HB_Letter_Lowercase},
-  {0x2cd8, 0x2cd8, HB_Letter_Uppercase},
-  {0x2cd9, 0x2cd9, HB_Letter_Lowercase},
-  {0x2cda, 0x2cda, HB_Letter_Uppercase},
-  {0x2cdb, 0x2cdb, HB_Letter_Lowercase},
-  {0x2cdc, 0x2cdc, HB_Letter_Uppercase},
-  {0x2cdd, 0x2cdd, HB_Letter_Lowercase},
-  {0x2cde, 0x2cde, HB_Letter_Uppercase},
-  {0x2cdf, 0x2cdf, HB_Letter_Lowercase},
-  {0x2ce0, 0x2ce0, HB_Letter_Uppercase},
-  {0x2ce1, 0x2ce1, HB_Letter_Lowercase},
-  {0x2ce2, 0x2ce2, HB_Letter_Uppercase},
-  {0x2ce3, 0x2ce4, HB_Letter_Lowercase},
-  {0x2ce5, 0x2cea, HB_Symbol_Other},
-  {0x2ceb, 0x2cf8, HB_Other_NotAssigned},
-  {0x2cf9, 0x2cfc, HB_Punctuation_Other},
-  {0x2cfd, 0x2cfd, HB_Number_Other},
-  {0x2cfe, 0x2cff, HB_Punctuation_Other},
-  {0x2d00, 0x2d25, HB_Letter_Lowercase},
-  {0x2d26, 0x2d2f, HB_Other_NotAssigned},
-  {0x2d30, 0x2d65, HB_Letter_Other},
-  {0x2d66, 0x2d6e, HB_Other_NotAssigned},
-  {0x2d6f, 0x2d6f, HB_Letter_Modifier},
-  {0x2d70, 0x2d7f, HB_Other_NotAssigned},
-  {0x2d80, 0x2d96, HB_Letter_Other},
-  {0x2d97, 0x2d9f, HB_Other_NotAssigned},
-  {0x2da0, 0x2da6, HB_Letter_Other},
-  {0x2da7, 0x2da7, HB_Other_NotAssigned},
-  {0x2da8, 0x2dae, HB_Letter_Other},
-  {0x2daf, 0x2daf, HB_Other_NotAssigned},
-  {0x2db0, 0x2db6, HB_Letter_Other},
-  {0x2db7, 0x2db7, HB_Other_NotAssigned},
-  {0x2db8, 0x2dbe, HB_Letter_Other},
-  {0x2dbf, 0x2dbf, HB_Other_NotAssigned},
-  {0x2dc0, 0x2dc6, HB_Letter_Other},
-  {0x2dc7, 0x2dc7, HB_Other_NotAssigned},
-  {0x2dc8, 0x2dce, HB_Letter_Other},
-  {0x2dcf, 0x2dcf, HB_Other_NotAssigned},
-  {0x2dd0, 0x2dd6, HB_Letter_Other},
-  {0x2dd7, 0x2dd7, HB_Other_NotAssigned},
-  {0x2dd8, 0x2dde, HB_Letter_Other},
-  {0x2ddf, 0x2ddf, HB_Other_NotAssigned},
-  {0x2de0, 0x2dff, HB_Mark_NonSpacing},
-  {0x2e00, 0x2e01, HB_Punctuation_Other},
-  {0x2e02, 0x2e02, HB_Punctuation_InitialQuote},
-  {0x2e03, 0x2e03, HB_Punctuation_FinalQuote},
-  {0x2e04, 0x2e04, HB_Punctuation_InitialQuote},
-  {0x2e05, 0x2e05, HB_Punctuation_FinalQuote},
-  {0x2e06, 0x2e08, HB_Punctuation_Other},
-  {0x2e09, 0x2e09, HB_Punctuation_InitialQuote},
-  {0x2e0a, 0x2e0a, HB_Punctuation_FinalQuote},
-  {0x2e0b, 0x2e0b, HB_Punctuation_Other},
-  {0x2e0c, 0x2e0c, HB_Punctuation_InitialQuote},
-  {0x2e0d, 0x2e0d, HB_Punctuation_FinalQuote},
-  {0x2e0e, 0x2e16, HB_Punctuation_Other},
-  {0x2e17, 0x2e17, HB_Punctuation_Dash},
-  {0x2e18, 0x2e19, HB_Punctuation_Other},
-  {0x2e1a, 0x2e1a, HB_Punctuation_Dash},
-  {0x2e1b, 0x2e1b, HB_Punctuation_Other},
-  {0x2e1c, 0x2e1c, HB_Punctuation_InitialQuote},
-  {0x2e1d, 0x2e1d, HB_Punctuation_FinalQuote},
-  {0x2e1e, 0x2e1f, HB_Punctuation_Other},
-  {0x2e20, 0x2e20, HB_Punctuation_InitialQuote},
-  {0x2e21, 0x2e21, HB_Punctuation_FinalQuote},
-  {0x2e22, 0x2e22, HB_Punctuation_Open},
-  {0x2e23, 0x2e23, HB_Punctuation_Close},
-  {0x2e24, 0x2e24, HB_Punctuation_Open},
-  {0x2e25, 0x2e25, HB_Punctuation_Close},
-  {0x2e26, 0x2e26, HB_Punctuation_Open},
-  {0x2e27, 0x2e27, HB_Punctuation_Close},
-  {0x2e28, 0x2e28, HB_Punctuation_Open},
-  {0x2e29, 0x2e29, HB_Punctuation_Close},
-  {0x2e2a, 0x2e2e, HB_Punctuation_Other},
-  {0x2e2f, 0x2e2f, HB_Letter_Modifier},
-  {0x2e30, 0x2e30, HB_Punctuation_Other},
-  {0x2e31, 0x2e7f, HB_Other_NotAssigned},
-  {0x2e80, 0x2e99, HB_Symbol_Other},
-  {0x2e9a, 0x2e9a, HB_Other_NotAssigned},
-  {0x2e9b, 0x2ef3, HB_Symbol_Other},
-  {0x2ef4, 0x2eff, HB_Other_NotAssigned},
-  {0x2f00, 0x2fd5, HB_Symbol_Other},
-  {0x2fd6, 0x2fef, HB_Other_NotAssigned},
-  {0x2ff0, 0x2ffb, HB_Symbol_Other},
-  {0x2ffc, 0x2fff, HB_Other_NotAssigned},
-  {0x3000, 0x3000, HB_Separator_Space},
-  {0x3001, 0x3003, HB_Punctuation_Other},
-  {0x3004, 0x3004, HB_Symbol_Other},
-  {0x3005, 0x3005, HB_Letter_Modifier},
-  {0x3006, 0x3006, HB_Letter_Other},
-  {0x3007, 0x3007, HB_Number_Letter},
-  {0x3008, 0x3008, HB_Punctuation_Open},
-  {0x3009, 0x3009, HB_Punctuation_Close},
-  {0x300a, 0x300a, HB_Punctuation_Open},
-  {0x300b, 0x300b, HB_Punctuation_Close},
-  {0x300c, 0x300c, HB_Punctuation_Open},
-  {0x300d, 0x300d, HB_Punctuation_Close},
-  {0x300e, 0x300e, HB_Punctuation_Open},
-  {0x300f, 0x300f, HB_Punctuation_Close},
-  {0x3010, 0x3010, HB_Punctuation_Open},
-  {0x3011, 0x3011, HB_Punctuation_Close},
-  {0x3012, 0x3013, HB_Symbol_Other},
-  {0x3014, 0x3014, HB_Punctuation_Open},
-  {0x3015, 0x3015, HB_Punctuation_Close},
-  {0x3016, 0x3016, HB_Punctuation_Open},
-  {0x3017, 0x3017, HB_Punctuation_Close},
-  {0x3018, 0x3018, HB_Punctuation_Open},
-  {0x3019, 0x3019, HB_Punctuation_Close},
-  {0x301a, 0x301a, HB_Punctuation_Open},
-  {0x301b, 0x301b, HB_Punctuation_Close},
-  {0x301c, 0x301c, HB_Punctuation_Dash},
-  {0x301d, 0x301d, HB_Punctuation_Open},
-  {0x301e, 0x301f, HB_Punctuation_Close},
-  {0x3020, 0x3020, HB_Symbol_Other},
-  {0x3021, 0x3029, HB_Number_Letter},
-  {0x302a, 0x302f, HB_Mark_NonSpacing},
-  {0x3030, 0x3030, HB_Punctuation_Dash},
-  {0x3031, 0x3035, HB_Letter_Modifier},
-  {0x3036, 0x3037, HB_Symbol_Other},
-  {0x3038, 0x303a, HB_Number_Letter},
-  {0x303b, 0x303b, HB_Letter_Modifier},
-  {0x303c, 0x303c, HB_Letter_Other},
-  {0x303d, 0x303d, HB_Punctuation_Other},
-  {0x303e, 0x303f, HB_Symbol_Other},
-  {0x3040, 0x3040, HB_Other_NotAssigned},
-  {0x3041, 0x3096, HB_Letter_Other},
-  {0x3097, 0x3098, HB_Other_NotAssigned},
-  {0x3099, 0x309a, HB_Mark_NonSpacing},
-  {0x309b, 0x309c, HB_Symbol_Modifier},
-  {0x309d, 0x309e, HB_Letter_Modifier},
-  {0x309f, 0x309f, HB_Letter_Other},
-  {0x30a0, 0x30a0, HB_Punctuation_Dash},
-  {0x30a1, 0x30fa, HB_Letter_Other},
-  {0x30fb, 0x30fb, HB_Punctuation_Other},
-  {0x30fc, 0x30fe, HB_Letter_Modifier},
-  {0x30ff, 0x30ff, HB_Letter_Other},
-  {0x3100, 0x3104, HB_Other_NotAssigned},
-  {0x3105, 0x312d, HB_Letter_Other},
-  {0x312e, 0x3130, HB_Other_NotAssigned},
-  {0x3131, 0x318e, HB_Letter_Other},
-  {0x318f, 0x318f, HB_Other_NotAssigned},
-  {0x3190, 0x3191, HB_Symbol_Other},
-  {0x3192, 0x3195, HB_Number_Other},
-  {0x3196, 0x319f, HB_Symbol_Other},
-  {0x31a0, 0x31b7, HB_Letter_Other},
-  {0x31b8, 0x31bf, HB_Other_NotAssigned},
-  {0x31c0, 0x31e3, HB_Symbol_Other},
-  {0x31e4, 0x31ef, HB_Other_NotAssigned},
-  {0x31f0, 0x31ff, HB_Letter_Other},
-  {0x3200, 0x321e, HB_Symbol_Other},
-  {0x321f, 0x321f, HB_Other_NotAssigned},
-  {0x3220, 0x3229, HB_Number_Other},
-  {0x322a, 0x3243, HB_Symbol_Other},
-  {0x3244, 0x324f, HB_Other_NotAssigned},
-  {0x3250, 0x3250, HB_Symbol_Other},
-  {0x3251, 0x325f, HB_Number_Other},
-  {0x3260, 0x327f, HB_Symbol_Other},
-  {0x3280, 0x3289, HB_Number_Other},
-  {0x328a, 0x32b0, HB_Symbol_Other},
-  {0x32b1, 0x32bf, HB_Number_Other},
-  {0x32c0, 0x32fe, HB_Symbol_Other},
-  {0x32ff, 0x32ff, HB_Other_NotAssigned},
-  {0x3300, 0x33ff, HB_Symbol_Other},
-  {0x3400, 0x4db5, HB_Letter_Other},
-  {0x4db6, 0x4dbf, HB_Other_NotAssigned},
-  {0x4dc0, 0x4dff, HB_Symbol_Other},
-  {0x4e00, 0x9fc3, HB_Letter_Other},
-  {0x9fc4, 0x9fff, HB_Other_NotAssigned},
-  {0xa000, 0xa014, HB_Letter_Other},
-  {0xa015, 0xa015, HB_Letter_Modifier},
-  {0xa016, 0xa48c, HB_Letter_Other},
-  {0xa48d, 0xa48f, HB_Other_NotAssigned},
-  {0xa490, 0xa4c6, HB_Symbol_Other},
-  {0xa4c7, 0xa4ff, HB_Other_NotAssigned},
-  {0xa500, 0xa60b, HB_Letter_Other},
-  {0xa60c, 0xa60c, HB_Letter_Modifier},
-  {0xa60d, 0xa60f, HB_Punctuation_Other},
-  {0xa610, 0xa61f, HB_Letter_Other},
-  {0xa620, 0xa629, HB_Number_DecimalDigit},
-  {0xa62a, 0xa62b, HB_Letter_Other},
-  {0xa62c, 0xa63f, HB_Other_NotAssigned},
-  {0xa640, 0xa640, HB_Letter_Uppercase},
-  {0xa641, 0xa641, HB_Letter_Lowercase},
-  {0xa642, 0xa642, HB_Letter_Uppercase},
-  {0xa643, 0xa643, HB_Letter_Lowercase},
-  {0xa644, 0xa644, HB_Letter_Uppercase},
-  {0xa645, 0xa645, HB_Letter_Lowercase},
-  {0xa646, 0xa646, HB_Letter_Uppercase},
-  {0xa647, 0xa647, HB_Letter_Lowercase},
-  {0xa648, 0xa648, HB_Letter_Uppercase},
-  {0xa649, 0xa649, HB_Letter_Lowercase},
-  {0xa64a, 0xa64a, HB_Letter_Uppercase},
-  {0xa64b, 0xa64b, HB_Letter_Lowercase},
-  {0xa64c, 0xa64c, HB_Letter_Uppercase},
-  {0xa64d, 0xa64d, HB_Letter_Lowercase},
-  {0xa64e, 0xa64e, HB_Letter_Uppercase},
-  {0xa64f, 0xa64f, HB_Letter_Lowercase},
-  {0xa650, 0xa650, HB_Letter_Uppercase},
-  {0xa651, 0xa651, HB_Letter_Lowercase},
-  {0xa652, 0xa652, HB_Letter_Uppercase},
-  {0xa653, 0xa653, HB_Letter_Lowercase},
-  {0xa654, 0xa654, HB_Letter_Uppercase},
-  {0xa655, 0xa655, HB_Letter_Lowercase},
-  {0xa656, 0xa656, HB_Letter_Uppercase},
-  {0xa657, 0xa657, HB_Letter_Lowercase},
-  {0xa658, 0xa658, HB_Letter_Uppercase},
-  {0xa659, 0xa659, HB_Letter_Lowercase},
-  {0xa65a, 0xa65a, HB_Letter_Uppercase},
-  {0xa65b, 0xa65b, HB_Letter_Lowercase},
-  {0xa65c, 0xa65c, HB_Letter_Uppercase},
-  {0xa65d, 0xa65d, HB_Letter_Lowercase},
-  {0xa65e, 0xa65e, HB_Letter_Uppercase},
-  {0xa65f, 0xa65f, HB_Letter_Lowercase},
-  {0xa660, 0xa661, HB_Other_NotAssigned},
-  {0xa662, 0xa662, HB_Letter_Uppercase},
-  {0xa663, 0xa663, HB_Letter_Lowercase},
-  {0xa664, 0xa664, HB_Letter_Uppercase},
-  {0xa665, 0xa665, HB_Letter_Lowercase},
-  {0xa666, 0xa666, HB_Letter_Uppercase},
-  {0xa667, 0xa667, HB_Letter_Lowercase},
-  {0xa668, 0xa668, HB_Letter_Uppercase},
-  {0xa669, 0xa669, HB_Letter_Lowercase},
-  {0xa66a, 0xa66a, HB_Letter_Uppercase},
-  {0xa66b, 0xa66b, HB_Letter_Lowercase},
-  {0xa66c, 0xa66c, HB_Letter_Uppercase},
-  {0xa66d, 0xa66d, HB_Letter_Lowercase},
-  {0xa66e, 0xa66e, HB_Letter_Other},
-  {0xa66f, 0xa66f, HB_Mark_NonSpacing},
-  {0xa670, 0xa672, HB_Mark_Enclosing},
-  {0xa673, 0xa673, HB_Punctuation_Other},
-  {0xa674, 0xa67b, HB_Other_NotAssigned},
-  {0xa67c, 0xa67d, HB_Mark_NonSpacing},
-  {0xa67e, 0xa67e, HB_Punctuation_Other},
-  {0xa67f, 0xa67f, HB_Letter_Modifier},
-  {0xa680, 0xa680, HB_Letter_Uppercase},
-  {0xa681, 0xa681, HB_Letter_Lowercase},
-  {0xa682, 0xa682, HB_Letter_Uppercase},
-  {0xa683, 0xa683, HB_Letter_Lowercase},
-  {0xa684, 0xa684, HB_Letter_Uppercase},
-  {0xa685, 0xa685, HB_Letter_Lowercase},
-  {0xa686, 0xa686, HB_Letter_Uppercase},
-  {0xa687, 0xa687, HB_Letter_Lowercase},
-  {0xa688, 0xa688, HB_Letter_Uppercase},
-  {0xa689, 0xa689, HB_Letter_Lowercase},
-  {0xa68a, 0xa68a, HB_Letter_Uppercase},
-  {0xa68b, 0xa68b, HB_Letter_Lowercase},
-  {0xa68c, 0xa68c, HB_Letter_Uppercase},
-  {0xa68d, 0xa68d, HB_Letter_Lowercase},
-  {0xa68e, 0xa68e, HB_Letter_Uppercase},
-  {0xa68f, 0xa68f, HB_Letter_Lowercase},
-  {0xa690, 0xa690, HB_Letter_Uppercase},
-  {0xa691, 0xa691, HB_Letter_Lowercase},
-  {0xa692, 0xa692, HB_Letter_Uppercase},
-  {0xa693, 0xa693, HB_Letter_Lowercase},
-  {0xa694, 0xa694, HB_Letter_Uppercase},
-  {0xa695, 0xa695, HB_Letter_Lowercase},
-  {0xa696, 0xa696, HB_Letter_Uppercase},
-  {0xa697, 0xa697, HB_Letter_Lowercase},
-  {0xa698, 0xa6ff, HB_Other_NotAssigned},
-  {0xa700, 0xa716, HB_Symbol_Modifier},
-  {0xa717, 0xa71f, HB_Letter_Modifier},
-  {0xa720, 0xa721, HB_Symbol_Modifier},
-  {0xa722, 0xa722, HB_Letter_Uppercase},
-  {0xa723, 0xa723, HB_Letter_Lowercase},
-  {0xa724, 0xa724, HB_Letter_Uppercase},
-  {0xa725, 0xa725, HB_Letter_Lowercase},
-  {0xa726, 0xa726, HB_Letter_Uppercase},
-  {0xa727, 0xa727, HB_Letter_Lowercase},
-  {0xa728, 0xa728, HB_Letter_Uppercase},
-  {0xa729, 0xa729, HB_Letter_Lowercase},
-  {0xa72a, 0xa72a, HB_Letter_Uppercase},
-  {0xa72b, 0xa72b, HB_Letter_Lowercase},
-  {0xa72c, 0xa72c, HB_Letter_Uppercase},
-  {0xa72d, 0xa72d, HB_Letter_Lowercase},
-  {0xa72e, 0xa72e, HB_Letter_Uppercase},
-  {0xa72f, 0xa731, HB_Letter_Lowercase},
-  {0xa732, 0xa732, HB_Letter_Uppercase},
-  {0xa733, 0xa733, HB_Letter_Lowercase},
-  {0xa734, 0xa734, HB_Letter_Uppercase},
-  {0xa735, 0xa735, HB_Letter_Lowercase},
-  {0xa736, 0xa736, HB_Letter_Uppercase},
-  {0xa737, 0xa737, HB_Letter_Lowercase},
-  {0xa738, 0xa738, HB_Letter_Uppercase},
-  {0xa739, 0xa739, HB_Letter_Lowercase},
-  {0xa73a, 0xa73a, HB_Letter_Uppercase},
-  {0xa73b, 0xa73b, HB_Letter_Lowercase},
-  {0xa73c, 0xa73c, HB_Letter_Uppercase},
-  {0xa73d, 0xa73d, HB_Letter_Lowercase},
-  {0xa73e, 0xa73e, HB_Letter_Uppercase},
-  {0xa73f, 0xa73f, HB_Letter_Lowercase},
-  {0xa740, 0xa740, HB_Letter_Uppercase},
-  {0xa741, 0xa741, HB_Letter_Lowercase},
-  {0xa742, 0xa742, HB_Letter_Uppercase},
-  {0xa743, 0xa743, HB_Letter_Lowercase},
-  {0xa744, 0xa744, HB_Letter_Uppercase},
-  {0xa745, 0xa745, HB_Letter_Lowercase},
-  {0xa746, 0xa746, HB_Letter_Uppercase},
-  {0xa747, 0xa747, HB_Letter_Lowercase},
-  {0xa748, 0xa748, HB_Letter_Uppercase},
-  {0xa749, 0xa749, HB_Letter_Lowercase},
-  {0xa74a, 0xa74a, HB_Letter_Uppercase},
-  {0xa74b, 0xa74b, HB_Letter_Lowercase},
-  {0xa74c, 0xa74c, HB_Letter_Uppercase},
-  {0xa74d, 0xa74d, HB_Letter_Lowercase},
-  {0xa74e, 0xa74e, HB_Letter_Uppercase},
-  {0xa74f, 0xa74f, HB_Letter_Lowercase},
-  {0xa750, 0xa750, HB_Letter_Uppercase},
-  {0xa751, 0xa751, HB_Letter_Lowercase},
-  {0xa752, 0xa752, HB_Letter_Uppercase},
-  {0xa753, 0xa753, HB_Letter_Lowercase},
-  {0xa754, 0xa754, HB_Letter_Uppercase},
-  {0xa755, 0xa755, HB_Letter_Lowercase},
-  {0xa756, 0xa756, HB_Letter_Uppercase},
-  {0xa757, 0xa757, HB_Letter_Lowercase},
-  {0xa758, 0xa758, HB_Letter_Uppercase},
-  {0xa759, 0xa759, HB_Letter_Lowercase},
-  {0xa75a, 0xa75a, HB_Letter_Uppercase},
-  {0xa75b, 0xa75b, HB_Letter_Lowercase},
-  {0xa75c, 0xa75c, HB_Letter_Uppercase},
-  {0xa75d, 0xa75d, HB_Letter_Lowercase},
-  {0xa75e, 0xa75e, HB_Letter_Uppercase},
-  {0xa75f, 0xa75f, HB_Letter_Lowercase},
-  {0xa760, 0xa760, HB_Letter_Uppercase},
-  {0xa761, 0xa761, HB_Letter_Lowercase},
-  {0xa762, 0xa762, HB_Letter_Uppercase},
-  {0xa763, 0xa763, HB_Letter_Lowercase},
-  {0xa764, 0xa764, HB_Letter_Uppercase},
-  {0xa765, 0xa765, HB_Letter_Lowercase},
-  {0xa766, 0xa766, HB_Letter_Uppercase},
-  {0xa767, 0xa767, HB_Letter_Lowercase},
-  {0xa768, 0xa768, HB_Letter_Uppercase},
-  {0xa769, 0xa769, HB_Letter_Lowercase},
-  {0xa76a, 0xa76a, HB_Letter_Uppercase},
-  {0xa76b, 0xa76b, HB_Letter_Lowercase},
-  {0xa76c, 0xa76c, HB_Letter_Uppercase},
-  {0xa76d, 0xa76d, HB_Letter_Lowercase},
-  {0xa76e, 0xa76e, HB_Letter_Uppercase},
-  {0xa76f, 0xa76f, HB_Letter_Lowercase},
-  {0xa770, 0xa770, HB_Letter_Modifier},
-  {0xa771, 0xa778, HB_Letter_Lowercase},
-  {0xa779, 0xa779, HB_Letter_Uppercase},
-  {0xa77a, 0xa77a, HB_Letter_Lowercase},
-  {0xa77b, 0xa77b, HB_Letter_Uppercase},
-  {0xa77c, 0xa77c, HB_Letter_Lowercase},
-  {0xa77d, 0xa77e, HB_Letter_Uppercase},
-  {0xa77f, 0xa77f, HB_Letter_Lowercase},
-  {0xa780, 0xa780, HB_Letter_Uppercase},
-  {0xa781, 0xa781, HB_Letter_Lowercase},
-  {0xa782, 0xa782, HB_Letter_Uppercase},
-  {0xa783, 0xa783, HB_Letter_Lowercase},
-  {0xa784, 0xa784, HB_Letter_Uppercase},
-  {0xa785, 0xa785, HB_Letter_Lowercase},
-  {0xa786, 0xa786, HB_Letter_Uppercase},
-  {0xa787, 0xa787, HB_Letter_Lowercase},
-  {0xa788, 0xa788, HB_Letter_Modifier},
-  {0xa789, 0xa78a, HB_Symbol_Modifier},
-  {0xa78b, 0xa78b, HB_Letter_Uppercase},
-  {0xa78c, 0xa78c, HB_Letter_Lowercase},
-  {0xa78d, 0xa7fa, HB_Other_NotAssigned},
-  {0xa7fb, 0xa801, HB_Letter_Other},
-  {0xa802, 0xa802, HB_Mark_NonSpacing},
-  {0xa803, 0xa805, HB_Letter_Other},
-  {0xa806, 0xa806, HB_Mark_NonSpacing},
-  {0xa807, 0xa80a, HB_Letter_Other},
-  {0xa80b, 0xa80b, HB_Mark_NonSpacing},
-  {0xa80c, 0xa822, HB_Letter_Other},
-  {0xa823, 0xa824, HB_Mark_SpacingCombining},
-  {0xa825, 0xa826, HB_Mark_NonSpacing},
-  {0xa827, 0xa827, HB_Mark_SpacingCombining},
-  {0xa828, 0xa82b, HB_Symbol_Other},
-  {0xa82c, 0xa83f, HB_Other_NotAssigned},
-  {0xa840, 0xa873, HB_Letter_Other},
-  {0xa874, 0xa877, HB_Punctuation_Other},
-  {0xa878, 0xa87f, HB_Other_NotAssigned},
-  {0xa880, 0xa881, HB_Mark_SpacingCombining},
-  {0xa882, 0xa8b3, HB_Letter_Other},
-  {0xa8b4, 0xa8c3, HB_Mark_SpacingCombining},
-  {0xa8c4, 0xa8c4, HB_Mark_NonSpacing},
-  {0xa8c5, 0xa8cd, HB_Other_NotAssigned},
-  {0xa8ce, 0xa8cf, HB_Punctuation_Other},
-  {0xa8d0, 0xa8d9, HB_Number_DecimalDigit},
-  {0xa8da, 0xa8ff, HB_Other_NotAssigned},
-  {0xa900, 0xa909, HB_Number_DecimalDigit},
-  {0xa90a, 0xa925, HB_Letter_Other},
-  {0xa926, 0xa92d, HB_Mark_NonSpacing},
-  {0xa92e, 0xa92f, HB_Punctuation_Other},
-  {0xa930, 0xa946, HB_Letter_Other},
-  {0xa947, 0xa951, HB_Mark_NonSpacing},
-  {0xa952, 0xa953, HB_Mark_SpacingCombining},
-  {0xa954, 0xa95e, HB_Other_NotAssigned},
-  {0xa95f, 0xa95f, HB_Punctuation_Other},
-  {0xa960, 0xa9ff, HB_Other_NotAssigned},
-  {0xaa00, 0xaa28, HB_Letter_Other},
-  {0xaa29, 0xaa2e, HB_Mark_NonSpacing},
-  {0xaa2f, 0xaa30, HB_Mark_SpacingCombining},
-  {0xaa31, 0xaa32, HB_Mark_NonSpacing},
-  {0xaa33, 0xaa34, HB_Mark_SpacingCombining},
-  {0xaa35, 0xaa36, HB_Mark_NonSpacing},
-  {0xaa37, 0xaa3f, HB_Other_NotAssigned},
-  {0xaa40, 0xaa42, HB_Letter_Other},
-  {0xaa43, 0xaa43, HB_Mark_NonSpacing},
-  {0xaa44, 0xaa4b, HB_Letter_Other},
-  {0xaa4c, 0xaa4c, HB_Mark_NonSpacing},
-  {0xaa4d, 0xaa4d, HB_Mark_SpacingCombining},
-  {0xaa4e, 0xaa4f, HB_Other_NotAssigned},
-  {0xaa50, 0xaa59, HB_Number_DecimalDigit},
-  {0xaa5a, 0xaa5b, HB_Other_NotAssigned},
-  {0xaa5c, 0xaa5f, HB_Punctuation_Other},
-  {0xaa60, 0xabff, HB_Other_NotAssigned},
-  {0xac00, 0xd7a3, HB_Letter_Other},
-  {0xd7a4, 0xd7ff, HB_Other_NotAssigned},
-  {0xd800, 0xdfff, HB_Other_Surrogate},
-  {0xe000, 0xf8ff, HB_Other_PrivateUse},
-  {0xf900, 0xfa2d, HB_Letter_Other},
-  {0xfa2e, 0xfa2f, HB_Other_NotAssigned},
-  {0xfa30, 0xfa6a, HB_Letter_Other},
-  {0xfa6b, 0xfa6f, HB_Other_NotAssigned},
-  {0xfa70, 0xfad9, HB_Letter_Other},
-  {0xfada, 0xfaff, HB_Other_NotAssigned},
-  {0xfb00, 0xfb06, HB_Letter_Lowercase},
-  {0xfb07, 0xfb12, HB_Other_NotAssigned},
-  {0xfb13, 0xfb17, HB_Letter_Lowercase},
-  {0xfb18, 0xfb1c, HB_Other_NotAssigned},
-  {0xfb1d, 0xfb1d, HB_Letter_Other},
-  {0xfb1e, 0xfb1e, HB_Mark_NonSpacing},
-  {0xfb1f, 0xfb28, HB_Letter_Other},
-  {0xfb29, 0xfb29, HB_Symbol_Math},
-  {0xfb2a, 0xfb36, HB_Letter_Other},
-  {0xfb37, 0xfb37, HB_Other_NotAssigned},
-  {0xfb38, 0xfb3c, HB_Letter_Other},
-  {0xfb3d, 0xfb3d, HB_Other_NotAssigned},
-  {0xfb3e, 0xfb3e, HB_Letter_Other},
-  {0xfb3f, 0xfb3f, HB_Other_NotAssigned},
-  {0xfb40, 0xfb41, HB_Letter_Other},
-  {0xfb42, 0xfb42, HB_Other_NotAssigned},
-  {0xfb43, 0xfb44, HB_Letter_Other},
-  {0xfb45, 0xfb45, HB_Other_NotAssigned},
-  {0xfb46, 0xfbb1, HB_Letter_Other},
-  {0xfbb2, 0xfbd2, HB_Other_NotAssigned},
-  {0xfbd3, 0xfd3d, HB_Letter_Other},
-  {0xfd3e, 0xfd3e, HB_Punctuation_Open},
-  {0xfd3f, 0xfd3f, HB_Punctuation_Close},
-  {0xfd40, 0xfd4f, HB_Other_NotAssigned},
-  {0xfd50, 0xfd8f, HB_Letter_Other},
-  {0xfd90, 0xfd91, HB_Other_NotAssigned},
-  {0xfd92, 0xfdc7, HB_Letter_Other},
-  {0xfdc8, 0xfdef, HB_Other_NotAssigned},
-  {0xfdf0, 0xfdfb, HB_Letter_Other},
-  {0xfdfc, 0xfdfc, HB_Symbol_Currency},
-  {0xfdfd, 0xfdfd, HB_Symbol_Other},
-  {0xfdfe, 0xfdff, HB_Other_NotAssigned},
-  {0xfe00, 0xfe0f, HB_Mark_NonSpacing},
-  {0xfe10, 0xfe16, HB_Punctuation_Other},
-  {0xfe17, 0xfe17, HB_Punctuation_Open},
-  {0xfe18, 0xfe18, HB_Punctuation_Close},
-  {0xfe19, 0xfe19, HB_Punctuation_Other},
-  {0xfe1a, 0xfe1f, HB_Other_NotAssigned},
-  {0xfe20, 0xfe26, HB_Mark_NonSpacing},
-  {0xfe27, 0xfe2f, HB_Other_NotAssigned},
-  {0xfe30, 0xfe30, HB_Punctuation_Other},
-  {0xfe31, 0xfe32, HB_Punctuation_Dash},
-  {0xfe33, 0xfe34, HB_Punctuation_Connector},
-  {0xfe35, 0xfe35, HB_Punctuation_Open},
-  {0xfe36, 0xfe36, HB_Punctuation_Close},
-  {0xfe37, 0xfe37, HB_Punctuation_Open},
-  {0xfe38, 0xfe38, HB_Punctuation_Close},
-  {0xfe39, 0xfe39, HB_Punctuation_Open},
-  {0xfe3a, 0xfe3a, HB_Punctuation_Close},
-  {0xfe3b, 0xfe3b, HB_Punctuation_Open},
-  {0xfe3c, 0xfe3c, HB_Punctuation_Close},
-  {0xfe3d, 0xfe3d, HB_Punctuation_Open},
-  {0xfe3e, 0xfe3e, HB_Punctuation_Close},
-  {0xfe3f, 0xfe3f, HB_Punctuation_Open},
-  {0xfe40, 0xfe40, HB_Punctuation_Close},
-  {0xfe41, 0xfe41, HB_Punctuation_Open},
-  {0xfe42, 0xfe42, HB_Punctuation_Close},
-  {0xfe43, 0xfe43, HB_Punctuation_Open},
-  {0xfe44, 0xfe44, HB_Punctuation_Close},
-  {0xfe45, 0xfe46, HB_Punctuation_Other},
-  {0xfe47, 0xfe47, HB_Punctuation_Open},
-  {0xfe48, 0xfe48, HB_Punctuation_Close},
-  {0xfe49, 0xfe4c, HB_Punctuation_Other},
-  {0xfe4d, 0xfe4f, HB_Punctuation_Connector},
-  {0xfe50, 0xfe52, HB_Punctuation_Other},
-  {0xfe53, 0xfe53, HB_Other_NotAssigned},
-  {0xfe54, 0xfe57, HB_Punctuation_Other},
-  {0xfe58, 0xfe58, HB_Punctuation_Dash},
-  {0xfe59, 0xfe59, HB_Punctuation_Open},
-  {0xfe5a, 0xfe5a, HB_Punctuation_Close},
-  {0xfe5b, 0xfe5b, HB_Punctuation_Open},
-  {0xfe5c, 0xfe5c, HB_Punctuation_Close},
-  {0xfe5d, 0xfe5d, HB_Punctuation_Open},
-  {0xfe5e, 0xfe5e, HB_Punctuation_Close},
-  {0xfe5f, 0xfe61, HB_Punctuation_Other},
-  {0xfe62, 0xfe62, HB_Symbol_Math},
-  {0xfe63, 0xfe63, HB_Punctuation_Dash},
-  {0xfe64, 0xfe66, HB_Symbol_Math},
-  {0xfe67, 0xfe67, HB_Other_NotAssigned},
-  {0xfe68, 0xfe68, HB_Punctuation_Other},
-  {0xfe69, 0xfe69, HB_Symbol_Currency},
-  {0xfe6a, 0xfe6b, HB_Punctuation_Other},
-  {0xfe6c, 0xfe6f, HB_Other_NotAssigned},
-  {0xfe70, 0xfe74, HB_Letter_Other},
-  {0xfe75, 0xfe75, HB_Other_NotAssigned},
-  {0xfe76, 0xfefc, HB_Letter_Other},
-  {0xfefd, 0xfefe, HB_Other_NotAssigned},
-  {0xfeff, 0xfeff, HB_Other_Format},
-  {0xff00, 0xff00, HB_Other_NotAssigned},
-  {0xff01, 0xff03, HB_Punctuation_Other},
-  {0xff04, 0xff04, HB_Symbol_Currency},
-  {0xff05, 0xff07, HB_Punctuation_Other},
-  {0xff08, 0xff08, HB_Punctuation_Open},
-  {0xff09, 0xff09, HB_Punctuation_Close},
-  {0xff0a, 0xff0a, HB_Punctuation_Other},
-  {0xff0b, 0xff0b, HB_Symbol_Math},
-  {0xff0c, 0xff0c, HB_Punctuation_Other},
-  {0xff0d, 0xff0d, HB_Punctuation_Dash},
-  {0xff0e, 0xff0f, HB_Punctuation_Other},
-  {0xff10, 0xff19, HB_Number_DecimalDigit},
-  {0xff1a, 0xff1b, HB_Punctuation_Other},
-  {0xff1c, 0xff1e, HB_Symbol_Math},
-  {0xff1f, 0xff20, HB_Punctuation_Other},
-  {0xff21, 0xff3a, HB_Letter_Uppercase},
-  {0xff3b, 0xff3b, HB_Punctuation_Open},
-  {0xff3c, 0xff3c, HB_Punctuation_Other},
-  {0xff3d, 0xff3d, HB_Punctuation_Close},
-  {0xff3e, 0xff3e, HB_Symbol_Modifier},
-  {0xff3f, 0xff3f, HB_Punctuation_Connector},
-  {0xff40, 0xff40, HB_Symbol_Modifier},
-  {0xff41, 0xff5a, HB_Letter_Lowercase},
-  {0xff5b, 0xff5b, HB_Punctuation_Open},
-  {0xff5c, 0xff5c, HB_Symbol_Math},
-  {0xff5d, 0xff5d, HB_Punctuation_Close},
-  {0xff5e, 0xff5e, HB_Symbol_Math},
-  {0xff5f, 0xff5f, HB_Punctuation_Open},
-  {0xff60, 0xff60, HB_Punctuation_Close},
-  {0xff61, 0xff61, HB_Punctuation_Other},
-  {0xff62, 0xff62, HB_Punctuation_Open},
-  {0xff63, 0xff63, HB_Punctuation_Close},
-  {0xff64, 0xff65, HB_Punctuation_Other},
-  {0xff66, 0xff6f, HB_Letter_Other},
-  {0xff70, 0xff70, HB_Letter_Modifier},
-  {0xff71, 0xff9d, HB_Letter_Other},
-  {0xff9e, 0xff9f, HB_Letter_Modifier},
-  {0xffa0, 0xffbe, HB_Letter_Other},
-  {0xffbf, 0xffc1, HB_Other_NotAssigned},
-  {0xffc2, 0xffc7, HB_Letter_Other},
-  {0xffc8, 0xffc9, HB_Other_NotAssigned},
-  {0xffca, 0xffcf, HB_Letter_Other},
-  {0xffd0, 0xffd1, HB_Other_NotAssigned},
-  {0xffd2, 0xffd7, HB_Letter_Other},
-  {0xffd8, 0xffd9, HB_Other_NotAssigned},
-  {0xffda, 0xffdc, HB_Letter_Other},
-  {0xffdd, 0xffdf, HB_Other_NotAssigned},
-  {0xffe0, 0xffe1, HB_Symbol_Currency},
-  {0xffe2, 0xffe2, HB_Symbol_Math},
-  {0xffe3, 0xffe3, HB_Symbol_Modifier},
-  {0xffe4, 0xffe4, HB_Symbol_Other},
-  {0xffe5, 0xffe6, HB_Symbol_Currency},
-  {0xffe7, 0xffe7, HB_Other_NotAssigned},
-  {0xffe8, 0xffe8, HB_Symbol_Other},
-  {0xffe9, 0xffec, HB_Symbol_Math},
-  {0xffed, 0xffee, HB_Symbol_Other},
-  {0xffef, 0xfff8, HB_Other_NotAssigned},
-  {0xfff9, 0xfffb, HB_Other_Format},
-  {0xfffc, 0xfffd, HB_Symbol_Other},
-  {0xfffe, 0xffff, HB_Other_NotAssigned},
-  {0x10000, 0x1000b, HB_Letter_Other},
-  {0x1000c, 0x1000c, HB_Other_NotAssigned},
-  {0x1000d, 0x10026, HB_Letter_Other},
-  {0x10027, 0x10027, HB_Other_NotAssigned},
-  {0x10028, 0x1003a, HB_Letter_Other},
-  {0x1003b, 0x1003b, HB_Other_NotAssigned},
-  {0x1003c, 0x1003d, HB_Letter_Other},
-  {0x1003e, 0x1003e, HB_Other_NotAssigned},
-  {0x1003f, 0x1004d, HB_Letter_Other},
-  {0x1004e, 0x1004f, HB_Other_NotAssigned},
-  {0x10050, 0x1005d, HB_Letter_Other},
-  {0x1005e, 0x1007f, HB_Other_NotAssigned},
-  {0x10080, 0x100fa, HB_Letter_Other},
-  {0x100fb, 0x100ff, HB_Other_NotAssigned},
-  {0x10100, 0x10101, HB_Punctuation_Other},
-  {0x10102, 0x10102, HB_Symbol_Other},
-  {0x10103, 0x10106, HB_Other_NotAssigned},
-  {0x10107, 0x10133, HB_Number_Other},
-  {0x10134, 0x10136, HB_Other_NotAssigned},
-  {0x10137, 0x1013f, HB_Symbol_Other},
-  {0x10140, 0x10174, HB_Number_Letter},
-  {0x10175, 0x10178, HB_Number_Other},
-  {0x10179, 0x10189, HB_Symbol_Other},
-  {0x1018a, 0x1018a, HB_Number_Other},
-  {0x1018b, 0x1018f, HB_Other_NotAssigned},
-  {0x10190, 0x1019b, HB_Symbol_Other},
-  {0x1019c, 0x101cf, HB_Other_NotAssigned},
-  {0x101d0, 0x101fc, HB_Symbol_Other},
-  {0x101fd, 0x101fd, HB_Mark_NonSpacing},
-  {0x101fe, 0x1027f, HB_Other_NotAssigned},
-  {0x10280, 0x1029c, HB_Letter_Other},
-  {0x1029d, 0x1029f, HB_Other_NotAssigned},
-  {0x102a0, 0x102d0, HB_Letter_Other},
-  {0x102d1, 0x102ff, HB_Other_NotAssigned},
-  {0x10300, 0x1031e, HB_Letter_Other},
-  {0x1031f, 0x1031f, HB_Other_NotAssigned},
-  {0x10320, 0x10323, HB_Number_Other},
-  {0x10324, 0x1032f, HB_Other_NotAssigned},
-  {0x10330, 0x10340, HB_Letter_Other},
-  {0x10341, 0x10341, HB_Number_Letter},
-  {0x10342, 0x10349, HB_Letter_Other},
-  {0x1034a, 0x1034a, HB_Number_Letter},
-  {0x1034b, 0x1037f, HB_Other_NotAssigned},
-  {0x10380, 0x1039d, HB_Letter_Other},
-  {0x1039e, 0x1039e, HB_Other_NotAssigned},
-  {0x1039f, 0x1039f, HB_Punctuation_Other},
-  {0x103a0, 0x103c3, HB_Letter_Other},
-  {0x103c4, 0x103c7, HB_Other_NotAssigned},
-  {0x103c8, 0x103cf, HB_Letter_Other},
-  {0x103d0, 0x103d0, HB_Punctuation_Other},
-  {0x103d1, 0x103d5, HB_Number_Letter},
-  {0x103d6, 0x103ff, HB_Other_NotAssigned},
-  {0x10400, 0x10427, HB_Letter_Uppercase},
-  {0x10428, 0x1044f, HB_Letter_Lowercase},
-  {0x10450, 0x1049d, HB_Letter_Other},
-  {0x1049e, 0x1049f, HB_Other_NotAssigned},
-  {0x104a0, 0x104a9, HB_Number_DecimalDigit},
-  {0x104aa, 0x107ff, HB_Other_NotAssigned},
-  {0x10800, 0x10805, HB_Letter_Other},
-  {0x10806, 0x10807, HB_Other_NotAssigned},
-  {0x10808, 0x10808, HB_Letter_Other},
-  {0x10809, 0x10809, HB_Other_NotAssigned},
-  {0x1080a, 0x10835, HB_Letter_Other},
-  {0x10836, 0x10836, HB_Other_NotAssigned},
-  {0x10837, 0x10838, HB_Letter_Other},
-  {0x10839, 0x1083b, HB_Other_NotAssigned},
-  {0x1083c, 0x1083c, HB_Letter_Other},
-  {0x1083d, 0x1083e, HB_Other_NotAssigned},
-  {0x1083f, 0x1083f, HB_Letter_Other},
-  {0x10840, 0x108ff, HB_Other_NotAssigned},
-  {0x10900, 0x10915, HB_Letter_Other},
-  {0x10916, 0x10919, HB_Number_Other},
-  {0x1091a, 0x1091e, HB_Other_NotAssigned},
-  {0x1091f, 0x1091f, HB_Punctuation_Other},
-  {0x10920, 0x10939, HB_Letter_Other},
-  {0x1093a, 0x1093e, HB_Other_NotAssigned},
-  {0x1093f, 0x1093f, HB_Punctuation_Other},
-  {0x10940, 0x109ff, HB_Other_NotAssigned},
-  {0x10a00, 0x10a00, HB_Letter_Other},
-  {0x10a01, 0x10a03, HB_Mark_NonSpacing},
-  {0x10a04, 0x10a04, HB_Other_NotAssigned},
-  {0x10a05, 0x10a06, HB_Mark_NonSpacing},
-  {0x10a07, 0x10a0b, HB_Other_NotAssigned},
-  {0x10a0c, 0x10a0f, HB_Mark_NonSpacing},
-  {0x10a10, 0x10a13, HB_Letter_Other},
-  {0x10a14, 0x10a14, HB_Other_NotAssigned},
-  {0x10a15, 0x10a17, HB_Letter_Other},
-  {0x10a18, 0x10a18, HB_Other_NotAssigned},
-  {0x10a19, 0x10a33, HB_Letter_Other},
-  {0x10a34, 0x10a37, HB_Other_NotAssigned},
-  {0x10a38, 0x10a3a, HB_Mark_NonSpacing},
-  {0x10a3b, 0x10a3e, HB_Other_NotAssigned},
-  {0x10a3f, 0x10a3f, HB_Mark_NonSpacing},
-  {0x10a40, 0x10a47, HB_Number_Other},
-  {0x10a48, 0x10a4f, HB_Other_NotAssigned},
-  {0x10a50, 0x10a58, HB_Punctuation_Other},
-  {0x10a59, 0x11fff, HB_Other_NotAssigned},
-  {0x12000, 0x1236e, HB_Letter_Other},
-  {0x1236f, 0x123ff, HB_Other_NotAssigned},
-  {0x12400, 0x12462, HB_Number_Letter},
-  {0x12463, 0x1246f, HB_Other_NotAssigned},
-  {0x12470, 0x12473, HB_Punctuation_Other},
-  {0x12474, 0x1cfff, HB_Other_NotAssigned},
-  {0x1d000, 0x1d0f5, HB_Symbol_Other},
-  {0x1d0f6, 0x1d0ff, HB_Other_NotAssigned},
-  {0x1d100, 0x1d126, HB_Symbol_Other},
-  {0x1d127, 0x1d128, HB_Other_NotAssigned},
-  {0x1d129, 0x1d164, HB_Symbol_Other},
-  {0x1d165, 0x1d166, HB_Mark_SpacingCombining},
-  {0x1d167, 0x1d169, HB_Mark_NonSpacing},
-  {0x1d16a, 0x1d16c, HB_Symbol_Other},
-  {0x1d16d, 0x1d172, HB_Mark_SpacingCombining},
-  {0x1d173, 0x1d17a, HB_Other_Format},
-  {0x1d17b, 0x1d182, HB_Mark_NonSpacing},
-  {0x1d183, 0x1d184, HB_Symbol_Other},
-  {0x1d185, 0x1d18b, HB_Mark_NonSpacing},
-  {0x1d18c, 0x1d1a9, HB_Symbol_Other},
-  {0x1d1aa, 0x1d1ad, HB_Mark_NonSpacing},
-  {0x1d1ae, 0x1d1dd, HB_Symbol_Other},
-  {0x1d1de, 0x1d1ff, HB_Other_NotAssigned},
-  {0x1d200, 0x1d241, HB_Symbol_Other},
-  {0x1d242, 0x1d244, HB_Mark_NonSpacing},
-  {0x1d245, 0x1d245, HB_Symbol_Other},
-  {0x1d246, 0x1d2ff, HB_Other_NotAssigned},
-  {0x1d300, 0x1d356, HB_Symbol_Other},
-  {0x1d357, 0x1d35f, HB_Other_NotAssigned},
-  {0x1d360, 0x1d371, HB_Number_Other},
-  {0x1d372, 0x1d3ff, HB_Other_NotAssigned},
-  {0x1d400, 0x1d419, HB_Letter_Uppercase},
-  {0x1d41a, 0x1d433, HB_Letter_Lowercase},
-  {0x1d434, 0x1d44d, HB_Letter_Uppercase},
-  {0x1d44e, 0x1d454, HB_Letter_Lowercase},
-  {0x1d455, 0x1d455, HB_Other_NotAssigned},
-  {0x1d456, 0x1d467, HB_Letter_Lowercase},
-  {0x1d468, 0x1d481, HB_Letter_Uppercase},
-  {0x1d482, 0x1d49b, HB_Letter_Lowercase},
-  {0x1d49c, 0x1d49c, HB_Letter_Uppercase},
-  {0x1d49d, 0x1d49d, HB_Other_NotAssigned},
-  {0x1d49e, 0x1d49f, HB_Letter_Uppercase},
-  {0x1d4a0, 0x1d4a1, HB_Other_NotAssigned},
-  {0x1d4a2, 0x1d4a2, HB_Letter_Uppercase},
-  {0x1d4a3, 0x1d4a4, HB_Other_NotAssigned},
-  {0x1d4a5, 0x1d4a6, HB_Letter_Uppercase},
-  {0x1d4a7, 0x1d4a8, HB_Other_NotAssigned},
-  {0x1d4a9, 0x1d4ac, HB_Letter_Uppercase},
-  {0x1d4ad, 0x1d4ad, HB_Other_NotAssigned},
-  {0x1d4ae, 0x1d4b5, HB_Letter_Uppercase},
-  {0x1d4b6, 0x1d4b9, HB_Letter_Lowercase},
-  {0x1d4ba, 0x1d4ba, HB_Other_NotAssigned},
-  {0x1d4bb, 0x1d4bb, HB_Letter_Lowercase},
-  {0x1d4bc, 0x1d4bc, HB_Other_NotAssigned},
-  {0x1d4bd, 0x1d4c3, HB_Letter_Lowercase},
-  {0x1d4c4, 0x1d4c4, HB_Other_NotAssigned},
-  {0x1d4c5, 0x1d4cf, HB_Letter_Lowercase},
-  {0x1d4d0, 0x1d4e9, HB_Letter_Uppercase},
-  {0x1d4ea, 0x1d503, HB_Letter_Lowercase},
-  {0x1d504, 0x1d505, HB_Letter_Uppercase},
-  {0x1d506, 0x1d506, HB_Other_NotAssigned},
-  {0x1d507, 0x1d50a, HB_Letter_Uppercase},
-  {0x1d50b, 0x1d50c, HB_Other_NotAssigned},
-  {0x1d50d, 0x1d514, HB_Letter_Uppercase},
-  {0x1d515, 0x1d515, HB_Other_NotAssigned},
-  {0x1d516, 0x1d51c, HB_Letter_Uppercase},
-  {0x1d51d, 0x1d51d, HB_Other_NotAssigned},
-  {0x1d51e, 0x1d537, HB_Letter_Lowercase},
-  {0x1d538, 0x1d539, HB_Letter_Uppercase},
-  {0x1d53a, 0x1d53a, HB_Other_NotAssigned},
-  {0x1d53b, 0x1d53e, HB_Letter_Uppercase},
-  {0x1d53f, 0x1d53f, HB_Other_NotAssigned},
-  {0x1d540, 0x1d544, HB_Letter_Uppercase},
-  {0x1d545, 0x1d545, HB_Other_NotAssigned},
-  {0x1d546, 0x1d546, HB_Letter_Uppercase},
-  {0x1d547, 0x1d549, HB_Other_NotAssigned},
-  {0x1d54a, 0x1d550, HB_Letter_Uppercase},
-  {0x1d551, 0x1d551, HB_Other_NotAssigned},
-  {0x1d552, 0x1d56b, HB_Letter_Lowercase},
-  {0x1d56c, 0x1d585, HB_Letter_Uppercase},
-  {0x1d586, 0x1d59f, HB_Letter_Lowercase},
-  {0x1d5a0, 0x1d5b9, HB_Letter_Uppercase},
-  {0x1d5ba, 0x1d5d3, HB_Letter_Lowercase},
-  {0x1d5d4, 0x1d5ed, HB_Letter_Uppercase},
-  {0x1d5ee, 0x1d607, HB_Letter_Lowercase},
-  {0x1d608, 0x1d621, HB_Letter_Uppercase},
-  {0x1d622, 0x1d63b, HB_Letter_Lowercase},
-  {0x1d63c, 0x1d655, HB_Letter_Uppercase},
-  {0x1d656, 0x1d66f, HB_Letter_Lowercase},
-  {0x1d670, 0x1d689, HB_Letter_Uppercase},
-  {0x1d68a, 0x1d6a5, HB_Letter_Lowercase},
-  {0x1d6a6, 0x1d6a7, HB_Other_NotAssigned},
-  {0x1d6a8, 0x1d6c0, HB_Letter_Uppercase},
-  {0x1d6c1, 0x1d6c1, HB_Symbol_Math},
-  {0x1d6c2, 0x1d6da, HB_Letter_Lowercase},
-  {0x1d6db, 0x1d6db, HB_Symbol_Math},
-  {0x1d6dc, 0x1d6e1, HB_Letter_Lowercase},
-  {0x1d6e2, 0x1d6fa, HB_Letter_Uppercase},
-  {0x1d6fb, 0x1d6fb, HB_Symbol_Math},
-  {0x1d6fc, 0x1d714, HB_Letter_Lowercase},
-  {0x1d715, 0x1d715, HB_Symbol_Math},
-  {0x1d716, 0x1d71b, HB_Letter_Lowercase},
-  {0x1d71c, 0x1d734, HB_Letter_Uppercase},
-  {0x1d735, 0x1d735, HB_Symbol_Math},
-  {0x1d736, 0x1d74e, HB_Letter_Lowercase},
-  {0x1d74f, 0x1d74f, HB_Symbol_Math},
-  {0x1d750, 0x1d755, HB_Letter_Lowercase},
-  {0x1d756, 0x1d76e, HB_Letter_Uppercase},
-  {0x1d76f, 0x1d76f, HB_Symbol_Math},
-  {0x1d770, 0x1d788, HB_Letter_Lowercase},
-  {0x1d789, 0x1d789, HB_Symbol_Math},
-  {0x1d78a, 0x1d78f, HB_Letter_Lowercase},
-  {0x1d790, 0x1d7a8, HB_Letter_Uppercase},
-  {0x1d7a9, 0x1d7a9, HB_Symbol_Math},
-  {0x1d7aa, 0x1d7c2, HB_Letter_Lowercase},
-  {0x1d7c3, 0x1d7c3, HB_Symbol_Math},
-  {0x1d7c4, 0x1d7c9, HB_Letter_Lowercase},
-  {0x1d7ca, 0x1d7ca, HB_Letter_Uppercase},
-  {0x1d7cb, 0x1d7cb, HB_Letter_Lowercase},
-  {0x1d7cc, 0x1d7cd, HB_Other_NotAssigned},
-  {0x1d7ce, 0x1d7ff, HB_Number_DecimalDigit},
-  {0x1d800, 0x1efff, HB_Other_NotAssigned},
-  {0x1f000, 0x1f02b, HB_Symbol_Other},
-  {0x1f02c, 0x1f02f, HB_Other_NotAssigned},
-  {0x1f030, 0x1f093, HB_Symbol_Other},
-  {0x1f094, 0x1ffff, HB_Other_NotAssigned},
-  {0x20000, 0x2a6d6, HB_Letter_Other},
-  {0x2a6d7, 0x2f7ff, HB_Other_NotAssigned},
-  {0x2f800, 0x2fa1d, HB_Letter_Other},
-  {0x2fa1e, 0xe0000, HB_Other_NotAssigned},
-  {0xe0001, 0xe0001, HB_Other_Format},
-  {0xe0002, 0xe001f, HB_Other_NotAssigned},
-  {0xe0020, 0xe007f, HB_Other_Format},
-  {0xe0080, 0xe00ff, HB_Other_NotAssigned},
-  {0xe0100, 0xe01ef, HB_Mark_NonSpacing},
-  {0xe01f0, 0xeffff, HB_Other_NotAssigned},
-  {0xf0000, 0xffffd, HB_Other_PrivateUse},
-  {0xffffe, 0xfffff, HB_Other_NotAssigned},
-  {0x100000, 0x10fffd, HB_Other_PrivateUse},
-  {0x10fffe, 0x10ffff, HB_Other_NotAssigned},
-};
-
-static const unsigned category_properties_count = 2849;
-
-#endif  // CATEGORY_PROPERTIES_H_
diff --git a/third_party/harfbuzz/contrib/tables/combining-class-parse.py b/third_party/harfbuzz/contrib/tables/combining-class-parse.py
deleted file mode 100644
index c591ddd..0000000
--- a/third_party/harfbuzz/contrib/tables/combining-class-parse.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import sys
-from unicode_parse_common import *
-
-# http://www.unicode.org/Public/5.1.0/ucd/extracted/DerivedCombiningClass.txt
-
-class IdentityMap(object):
-  def __getitem__(_, key):
-    return key
-
-def main(infile, outfile):
-  ranges = unicode_file_parse(infile, IdentityMap(), '0')
-  ranges = sort_and_merge(ranges)
-
-  print >>outfile, '// Generated from Unicode tables\n'
-  print >>outfile, '#ifndef COMBINING_PROPERTIES_H_'
-  print >>outfile, '#define COMBINING_PROPERTIES_H_\n'
-  print >>outfile, '#include <stdint.h>'
-  print >>outfile, 'struct combining_property {'
-  print >>outfile, '  uint32_t range_start;'
-  print >>outfile, '  uint32_t range_end;'
-  print >>outfile, '  uint8_t klass;'
-  print >>outfile, '};\n'
-  print >>outfile, 'static const struct combining_property combining_properties[] = {'
-  for (start, end, value) in ranges:
-    print >>outfile, '  {0x%x, 0x%x, %s},' % (start, end, value)
-  print >>outfile, '};\n'
-  print >>outfile, 'static const unsigned combining_properties_count = %d;\n' % len(ranges)
-  print >>outfile, '#endif  // COMBINING_PROPERTIES_H_'
-
-if __name__ == '__main__':
-  if len(sys.argv) != 3:
-    print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
-  else:
-    main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))
diff --git a/third_party/harfbuzz/contrib/tables/combining-properties.h b/third_party/harfbuzz/contrib/tables/combining-properties.h
deleted file mode 100644
index 552ed35..0000000
--- a/third_party/harfbuzz/contrib/tables/combining-properties.h
+++ /dev/null
@@ -1,247 +0,0 @@
-// Generated from Unicode tables
-
-#ifndef COMBINING_PROPERTIES_H_
-#define COMBINING_PROPERTIES_H_
-
-#include <stdint.h>
-struct combining_property {
-  uint32_t range_start;
-  uint32_t range_end;
-  uint8_t klass;
-};
-
-static const struct combining_property combining_properties[] = {
-  {0x300, 0x314, 230},
-  {0x315, 0x315, 232},
-  {0x316, 0x319, 220},
-  {0x31a, 0x31a, 232},
-  {0x31b, 0x31b, 216},
-  {0x31c, 0x320, 220},
-  {0x321, 0x322, 202},
-  {0x323, 0x326, 220},
-  {0x327, 0x328, 202},
-  {0x329, 0x333, 220},
-  {0x334, 0x338, 1},
-  {0x339, 0x33c, 220},
-  {0x33d, 0x344, 230},
-  {0x345, 0x345, 240},
-  {0x346, 0x346, 230},
-  {0x347, 0x349, 220},
-  {0x34a, 0x34c, 230},
-  {0x34d, 0x34e, 220},
-  {0x350, 0x352, 230},
-  {0x353, 0x356, 220},
-  {0x357, 0x357, 230},
-  {0x358, 0x358, 232},
-  {0x359, 0x35a, 220},
-  {0x35b, 0x35b, 230},
-  {0x35c, 0x35c, 233},
-  {0x35d, 0x35e, 234},
-  {0x35f, 0x35f, 233},
-  {0x360, 0x361, 234},
-  {0x362, 0x362, 233},
-  {0x363, 0x36f, 230},
-  {0x483, 0x487, 230},
-  {0x591, 0x591, 220},
-  {0x592, 0x595, 230},
-  {0x596, 0x596, 220},
-  {0x597, 0x599, 230},
-  {0x59a, 0x59a, 222},
-  {0x59b, 0x59b, 220},
-  {0x59c, 0x5a1, 230},
-  {0x5a2, 0x5a7, 220},
-  {0x5a8, 0x5a9, 230},
-  {0x5aa, 0x5aa, 220},
-  {0x5ab, 0x5ac, 230},
-  {0x5ad, 0x5ad, 222},
-  {0x5ae, 0x5ae, 228},
-  {0x5af, 0x5af, 230},
-  {0x5b0, 0x5b0, 10},
-  {0x5b1, 0x5b1, 11},
-  {0x5b2, 0x5b2, 12},
-  {0x5b3, 0x5b3, 13},
-  {0x5b4, 0x5b4, 14},
-  {0x5b5, 0x5b5, 15},
-  {0x5b6, 0x5b6, 16},
-  {0x5b7, 0x5b7, 17},
-  {0x5b8, 0x5b8, 18},
-  {0x5b9, 0x5ba, 19},
-  {0x5bb, 0x5bb, 20},
-  {0x5bc, 0x5bc, 21},
-  {0x5bd, 0x5bd, 22},
-  {0x5bf, 0x5bf, 23},
-  {0x5c1, 0x5c1, 24},
-  {0x5c2, 0x5c2, 25},
-  {0x5c4, 0x5c4, 230},
-  {0x5c5, 0x5c5, 220},
-  {0x5c7, 0x5c7, 18},
-  {0x610, 0x617, 230},
-  {0x618, 0x618, 30},
-  {0x619, 0x619, 31},
-  {0x61a, 0x61a, 32},
-  {0x64b, 0x64b, 27},
-  {0x64c, 0x64c, 28},
-  {0x64d, 0x64d, 29},
-  {0x64e, 0x64e, 30},
-  {0x64f, 0x64f, 31},
-  {0x650, 0x650, 32},
-  {0x651, 0x651, 33},
-  {0x652, 0x652, 34},
-  {0x653, 0x654, 230},
-  {0x655, 0x656, 220},
-  {0x657, 0x65b, 230},
-  {0x65c, 0x65c, 220},
-  {0x65d, 0x65e, 230},
-  {0x670, 0x670, 35},
-  {0x6d6, 0x6dc, 230},
-  {0x6df, 0x6e2, 230},
-  {0x6e3, 0x6e3, 220},
-  {0x6e4, 0x6e4, 230},
-  {0x6e7, 0x6e8, 230},
-  {0x6ea, 0x6ea, 220},
-  {0x6eb, 0x6ec, 230},
-  {0x6ed, 0x6ed, 220},
-  {0x711, 0x711, 36},
-  {0x730, 0x730, 230},
-  {0x731, 0x731, 220},
-  {0x732, 0x733, 230},
-  {0x734, 0x734, 220},
-  {0x735, 0x736, 230},
-  {0x737, 0x739, 220},
-  {0x73a, 0x73a, 230},
-  {0x73b, 0x73c, 220},
-  {0x73d, 0x73d, 230},
-  {0x73e, 0x73e, 220},
-  {0x73f, 0x741, 230},
-  {0x742, 0x742, 220},
-  {0x743, 0x743, 230},
-  {0x744, 0x744, 220},
-  {0x745, 0x745, 230},
-  {0x746, 0x746, 220},
-  {0x747, 0x747, 230},
-  {0x748, 0x748, 220},
-  {0x749, 0x74a, 230},
-  {0x7eb, 0x7f1, 230},
-  {0x7f2, 0x7f2, 220},
-  {0x7f3, 0x7f3, 230},
-  {0x93c, 0x93c, 7},
-  {0x94d, 0x94d, 9},
-  {0x951, 0x951, 230},
-  {0x952, 0x952, 220},
-  {0x953, 0x954, 230},
-  {0x9bc, 0x9bc, 7},
-  {0x9cd, 0x9cd, 9},
-  {0xa3c, 0xa3c, 7},
-  {0xa4d, 0xa4d, 9},
-  {0xabc, 0xabc, 7},
-  {0xacd, 0xacd, 9},
-  {0xb3c, 0xb3c, 7},
-  {0xb4d, 0xb4d, 9},
-  {0xbcd, 0xbcd, 9},
-  {0xc4d, 0xc4d, 9},
-  {0xc55, 0xc55, 84},
-  {0xc56, 0xc56, 91},
-  {0xcbc, 0xcbc, 7},
-  {0xccd, 0xccd, 9},
-  {0xd4d, 0xd4d, 9},
-  {0xdca, 0xdca, 9},
-  {0xe38, 0xe39, 103},
-  {0xe3a, 0xe3a, 9},
-  {0xe48, 0xe4b, 107},
-  {0xeb8, 0xeb9, 118},
-  {0xec8, 0xecb, 122},
-  {0xf18, 0xf19, 220},
-  {0xf35, 0xf35, 220},
-  {0xf37, 0xf37, 220},
-  {0xf39, 0xf39, 216},
-  {0xf71, 0xf71, 129},
-  {0xf72, 0xf72, 130},
-  {0xf74, 0xf74, 132},
-  {0xf7a, 0xf7d, 130},
-  {0xf80, 0xf80, 130},
-  {0xf82, 0xf83, 230},
-  {0xf84, 0xf84, 9},
-  {0xf86, 0xf87, 230},
-  {0xfc6, 0xfc6, 220},
-  {0x1037, 0x1037, 7},
-  {0x1039, 0x103a, 9},
-  {0x108d, 0x108d, 220},
-  {0x135f, 0x135f, 230},
-  {0x1714, 0x1714, 9},
-  {0x1734, 0x1734, 9},
-  {0x17d2, 0x17d2, 9},
-  {0x17dd, 0x17dd, 230},
-  {0x18a9, 0x18a9, 228},
-  {0x1939, 0x1939, 222},
-  {0x193a, 0x193a, 230},
-  {0x193b, 0x193b, 220},
-  {0x1a17, 0x1a17, 230},
-  {0x1a18, 0x1a18, 220},
-  {0x1b34, 0x1b34, 7},
-  {0x1b44, 0x1b44, 9},
-  {0x1b6b, 0x1b6b, 230},
-  {0x1b6c, 0x1b6c, 220},
-  {0x1b6d, 0x1b73, 230},
-  {0x1baa, 0x1baa, 9},
-  {0x1c37, 0x1c37, 7},
-  {0x1dc0, 0x1dc1, 230},
-  {0x1dc2, 0x1dc2, 220},
-  {0x1dc3, 0x1dc9, 230},
-  {0x1dca, 0x1dca, 220},
-  {0x1dcb, 0x1dcc, 230},
-  {0x1dcd, 0x1dcd, 234},
-  {0x1dce, 0x1dce, 214},
-  {0x1dcf, 0x1dcf, 220},
-  {0x1dd0, 0x1dd0, 202},
-  {0x1dd1, 0x1de6, 230},
-  {0x1dfe, 0x1dfe, 230},
-  {0x1dff, 0x1dff, 220},
-  {0x20d0, 0x20d1, 230},
-  {0x20d2, 0x20d3, 1},
-  {0x20d4, 0x20d7, 230},
-  {0x20d8, 0x20da, 1},
-  {0x20db, 0x20dc, 230},
-  {0x20e1, 0x20e1, 230},
-  {0x20e5, 0x20e6, 1},
-  {0x20e7, 0x20e7, 230},
-  {0x20e8, 0x20e8, 220},
-  {0x20e9, 0x20e9, 230},
-  {0x20ea, 0x20eb, 1},
-  {0x20ec, 0x20ef, 220},
-  {0x20f0, 0x20f0, 230},
-  {0x2de0, 0x2dff, 230},
-  {0x302a, 0x302a, 218},
-  {0x302b, 0x302b, 228},
-  {0x302c, 0x302c, 232},
-  {0x302d, 0x302d, 222},
-  {0x302e, 0x302f, 224},
-  {0x3099, 0x309a, 8},
-  {0xa66f, 0xa66f, 230},
-  {0xa67c, 0xa67d, 230},
-  {0xa806, 0xa806, 9},
-  {0xa8c4, 0xa8c4, 9},
-  {0xa92b, 0xa92d, 220},
-  {0xa953, 0xa953, 9},
-  {0xfb1e, 0xfb1e, 26},
-  {0xfe20, 0xfe26, 230},
-  {0x101fd, 0x101fd, 220},
-  {0x10a0d, 0x10a0d, 220},
-  {0x10a0f, 0x10a0f, 230},
-  {0x10a38, 0x10a38, 230},
-  {0x10a39, 0x10a39, 1},
-  {0x10a3a, 0x10a3a, 220},
-  {0x10a3f, 0x10a3f, 9},
-  {0x1d165, 0x1d166, 216},
-  {0x1d167, 0x1d169, 1},
-  {0x1d16d, 0x1d16d, 226},
-  {0x1d16e, 0x1d172, 216},
-  {0x1d17b, 0x1d182, 220},
-  {0x1d185, 0x1d189, 230},
-  {0x1d18a, 0x1d18b, 220},
-  {0x1d1aa, 0x1d1ad, 230},
-  {0x1d242, 0x1d244, 230},
-};
-
-static const unsigned combining_properties_count = 229;
-
-#endif  // COMBINING_PROPERTIES_H_
diff --git a/third_party/harfbuzz/contrib/tables/grapheme-break-parse.py b/third_party/harfbuzz/contrib/tables/grapheme-break-parse.py
deleted file mode 100644
index a4b3534..0000000
--- a/third_party/harfbuzz/contrib/tables/grapheme-break-parse.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import sys
-from unicode_parse_common import *
-
-# http://www.unicode.org/Public/UNIDATA/auxiliary/GraphemeBreakProperty.txt
-
-property_to_harfbuzz = {
-  'CR': 'HB_Grapheme_CR',
-  'LF': 'HB_Grapheme_LF',
-  'Control': 'HB_Grapheme_Control',
-  'Extend': 'HB_Grapheme_Extend',
-  'Prepend': 'HB_Grapheme_Other',
-  'SpacingMark': 'HB_Grapheme_Other',
-  'L': 'HB_Grapheme_L',
-  'V': 'HB_Grapheme_V',
-  'T': 'HB_Grapheme_T',
-  'LV': 'HB_Grapheme_LV',
-  'LVT': 'HB_Grapheme_LVT',
-}
-
-def main(infile, outfile):
-  ranges = unicode_file_parse(infile, property_to_harfbuzz)
-  ranges.sort()
-
-  print >>outfile, '// Generated from Unicode Grapheme break tables\n'
-  print >>outfile, '#ifndef GRAPHEME_BREAK_PROPERTY_H_'
-  print >>outfile, '#define GRAPHEME_BREAK_PROPERTY_H_\n'
-  print >>outfile, '#include <stdint.h>'
-  print >>outfile, '#include "harfbuzz-external.h"\n'
-  print >>outfile, 'struct grapheme_break_property {'
-  print >>outfile, '  uint32_t range_start;'
-  print >>outfile, '  uint32_t range_end;'
-  print >>outfile, '  HB_GraphemeClass klass;'
-  print >>outfile, '};\n'
-  print >>outfile, 'static const struct grapheme_break_property grapheme_break_properties[] = {'
-  for (start, end, value) in ranges:
-    print >>outfile, '  {0x%x, 0x%x, %s},' % (start, end, value)
-  print >>outfile, '};\n'
-  print >>outfile, 'static const unsigned grapheme_break_properties_count = %d;\n' % len(ranges)
-  print >>outfile, '#endif  // GRAPHEME_BREAK_PROPERTY_H_'
-
-if __name__ == '__main__':
-  if len(sys.argv) != 3:
-    print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
-  else:
-    main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))
diff --git a/third_party/harfbuzz/contrib/tables/grapheme-break-properties.h b/third_party/harfbuzz/contrib/tables/grapheme-break-properties.h
deleted file mode 100644
index 73f47d4..0000000
--- a/third_party/harfbuzz/contrib/tables/grapheme-break-properties.h
+++ /dev/null
@@ -1,1113 +0,0 @@
-// Generated from Unicode Grapheme break tables
-
-#ifndef GRAPHEME_BREAK_PROPERTY_H_
-#define GRAPHEME_BREAK_PROPERTY_H_
-
-#include <stdint.h>
-#include "harfbuzz-external.h"
-
-struct grapheme_break_property {
-  uint32_t range_start;
-  uint32_t range_end;
-  HB_GraphemeClass klass;
-};
-
-static const struct grapheme_break_property grapheme_break_properties[] = {
-  {0x0, 0x9, HB_Grapheme_Control},
-  {0xa, 0xa, HB_Grapheme_LF},
-  {0xb, 0xc, HB_Grapheme_Control},
-  {0xd, 0xd, HB_Grapheme_CR},
-  {0xe, 0x1f, HB_Grapheme_Control},
-  {0x7f, 0x9f, HB_Grapheme_Control},
-  {0xad, 0xad, HB_Grapheme_Control},
-  {0x300, 0x36f, HB_Grapheme_Extend},
-  {0x483, 0x487, HB_Grapheme_Extend},
-  {0x488, 0x489, HB_Grapheme_Extend},
-  {0x591, 0x5bd, HB_Grapheme_Extend},
-  {0x5bf, 0x5bf, HB_Grapheme_Extend},
-  {0x5c1, 0x5c2, HB_Grapheme_Extend},
-  {0x5c4, 0x5c5, HB_Grapheme_Extend},
-  {0x5c7, 0x5c7, HB_Grapheme_Extend},
-  {0x600, 0x603, HB_Grapheme_Control},
-  {0x610, 0x61a, HB_Grapheme_Extend},
-  {0x64b, 0x65e, HB_Grapheme_Extend},
-  {0x670, 0x670, HB_Grapheme_Extend},
-  {0x6d6, 0x6dc, HB_Grapheme_Extend},
-  {0x6dd, 0x6dd, HB_Grapheme_Control},
-  {0x6de, 0x6de, HB_Grapheme_Extend},
-  {0x6df, 0x6e4, HB_Grapheme_Extend},
-  {0x6e7, 0x6e8, HB_Grapheme_Extend},
-  {0x6ea, 0x6ed, HB_Grapheme_Extend},
-  {0x70f, 0x70f, HB_Grapheme_Control},
-  {0x711, 0x711, HB_Grapheme_Extend},
-  {0x730, 0x74a, HB_Grapheme_Extend},
-  {0x7a6, 0x7b0, HB_Grapheme_Extend},
-  {0x7eb, 0x7f3, HB_Grapheme_Extend},
-  {0x901, 0x902, HB_Grapheme_Extend},
-  {0x903, 0x903, HB_Grapheme_Other},
-  {0x93c, 0x93c, HB_Grapheme_Extend},
-  {0x93e, 0x940, HB_Grapheme_Other},
-  {0x941, 0x948, HB_Grapheme_Extend},
-  {0x949, 0x94c, HB_Grapheme_Other},
-  {0x94d, 0x94d, HB_Grapheme_Extend},
-  {0x951, 0x954, HB_Grapheme_Extend},
-  {0x962, 0x963, HB_Grapheme_Extend},
-  {0x981, 0x981, HB_Grapheme_Extend},
-  {0x982, 0x983, HB_Grapheme_Other},
-  {0x9bc, 0x9bc, HB_Grapheme_Extend},
-  {0x9be, 0x9be, HB_Grapheme_Extend},
-  {0x9bf, 0x9c0, HB_Grapheme_Other},
-  {0x9c1, 0x9c4, HB_Grapheme_Extend},
-  {0x9c7, 0x9c8, HB_Grapheme_Other},
-  {0x9cb, 0x9cc, HB_Grapheme_Other},
-  {0x9cd, 0x9cd, HB_Grapheme_Extend},
-  {0x9d7, 0x9d7, HB_Grapheme_Extend},
-  {0x9e2, 0x9e3, HB_Grapheme_Extend},
-  {0xa01, 0xa02, HB_Grapheme_Extend},
-  {0xa03, 0xa03, HB_Grapheme_Other},
-  {0xa3c, 0xa3c, HB_Grapheme_Extend},
-  {0xa3e, 0xa40, HB_Grapheme_Other},
-  {0xa41, 0xa42, HB_Grapheme_Extend},
-  {0xa47, 0xa48, HB_Grapheme_Extend},
-  {0xa4b, 0xa4d, HB_Grapheme_Extend},
-  {0xa51, 0xa51, HB_Grapheme_Extend},
-  {0xa70, 0xa71, HB_Grapheme_Extend},
-  {0xa75, 0xa75, HB_Grapheme_Extend},
-  {0xa81, 0xa82, HB_Grapheme_Extend},
-  {0xa83, 0xa83, HB_Grapheme_Other},
-  {0xabc, 0xabc, HB_Grapheme_Extend},
-  {0xabe, 0xac0, HB_Grapheme_Other},
-  {0xac1, 0xac5, HB_Grapheme_Extend},
-  {0xac7, 0xac8, HB_Grapheme_Extend},
-  {0xac9, 0xac9, HB_Grapheme_Other},
-  {0xacb, 0xacc, HB_Grapheme_Other},
-  {0xacd, 0xacd, HB_Grapheme_Extend},
-  {0xae2, 0xae3, HB_Grapheme_Extend},
-  {0xb01, 0xb01, HB_Grapheme_Extend},
-  {0xb02, 0xb03, HB_Grapheme_Other},
-  {0xb3c, 0xb3c, HB_Grapheme_Extend},
-  {0xb3e, 0xb3e, HB_Grapheme_Extend},
-  {0xb3f, 0xb3f, HB_Grapheme_Extend},
-  {0xb40, 0xb40, HB_Grapheme_Other},
-  {0xb41, 0xb44, HB_Grapheme_Extend},
-  {0xb47, 0xb48, HB_Grapheme_Other},
-  {0xb4b, 0xb4c, HB_Grapheme_Other},
-  {0xb4d, 0xb4d, HB_Grapheme_Extend},
-  {0xb56, 0xb56, HB_Grapheme_Extend},
-  {0xb57, 0xb57, HB_Grapheme_Extend},
-  {0xb62, 0xb63, HB_Grapheme_Extend},
-  {0xb82, 0xb82, HB_Grapheme_Extend},
-  {0xbbe, 0xbbe, HB_Grapheme_Extend},
-  {0xbbf, 0xbbf, HB_Grapheme_Other},
-  {0xbc0, 0xbc0, HB_Grapheme_Extend},
-  {0xbc1, 0xbc2, HB_Grapheme_Other},
-  {0xbc6, 0xbc8, HB_Grapheme_Other},
-  {0xbca, 0xbcc, HB_Grapheme_Other},
-  {0xbcd, 0xbcd, HB_Grapheme_Extend},
-  {0xbd7, 0xbd7, HB_Grapheme_Extend},
-  {0xc01, 0xc03, HB_Grapheme_Other},
-  {0xc3e, 0xc40, HB_Grapheme_Extend},
-  {0xc41, 0xc44, HB_Grapheme_Other},
-  {0xc46, 0xc48, HB_Grapheme_Extend},
-  {0xc4a, 0xc4d, HB_Grapheme_Extend},
-  {0xc55, 0xc56, HB_Grapheme_Extend},
-  {0xc62, 0xc63, HB_Grapheme_Extend},
-  {0xc82, 0xc83, HB_Grapheme_Other},
-  {0xcbc, 0xcbc, HB_Grapheme_Extend},
-  {0xcbe, 0xcbe, HB_Grapheme_Other},
-  {0xcbf, 0xcbf, HB_Grapheme_Extend},
-  {0xcc0, 0xcc1, HB_Grapheme_Other},
-  {0xcc2, 0xcc2, HB_Grapheme_Extend},
-  {0xcc3, 0xcc4, HB_Grapheme_Other},
-  {0xcc6, 0xcc6, HB_Grapheme_Extend},
-  {0xcc7, 0xcc8, HB_Grapheme_Other},
-  {0xcca, 0xccb, HB_Grapheme_Other},
-  {0xccc, 0xccd, HB_Grapheme_Extend},
-  {0xcd5, 0xcd6, HB_Grapheme_Extend},
-  {0xce2, 0xce3, HB_Grapheme_Extend},
-  {0xd02, 0xd03, HB_Grapheme_Other},
-  {0xd3e, 0xd3e, HB_Grapheme_Extend},
-  {0xd3f, 0xd40, HB_Grapheme_Other},
-  {0xd41, 0xd44, HB_Grapheme_Extend},
-  {0xd46, 0xd48, HB_Grapheme_Other},
-  {0xd4a, 0xd4c, HB_Grapheme_Other},
-  {0xd4d, 0xd4d, HB_Grapheme_Extend},
-  {0xd57, 0xd57, HB_Grapheme_Extend},
-  {0xd62, 0xd63, HB_Grapheme_Extend},
-  {0xd82, 0xd83, HB_Grapheme_Other},
-  {0xdca, 0xdca, HB_Grapheme_Extend},
-  {0xdcf, 0xdcf, HB_Grapheme_Extend},
-  {0xdd0, 0xdd1, HB_Grapheme_Other},
-  {0xdd2, 0xdd4, HB_Grapheme_Extend},
-  {0xdd6, 0xdd6, HB_Grapheme_Extend},
-  {0xdd8, 0xdde, HB_Grapheme_Other},
-  {0xddf, 0xddf, HB_Grapheme_Extend},
-  {0xdf2, 0xdf3, HB_Grapheme_Other},
-  {0xe30, 0xe30, HB_Grapheme_Extend},
-  {0xe31, 0xe31, HB_Grapheme_Extend},
-  {0xe32, 0xe33, HB_Grapheme_Extend},
-  {0xe34, 0xe3a, HB_Grapheme_Extend},
-  {0xe40, 0xe44, HB_Grapheme_Other},
-  {0xe45, 0xe45, HB_Grapheme_Extend},
-  {0xe47, 0xe4e, HB_Grapheme_Extend},
-  {0xeb0, 0xeb0, HB_Grapheme_Extend},
-  {0xeb1, 0xeb1, HB_Grapheme_Extend},
-  {0xeb2, 0xeb3, HB_Grapheme_Extend},
-  {0xeb4, 0xeb9, HB_Grapheme_Extend},
-  {0xebb, 0xebc, HB_Grapheme_Extend},
-  {0xec0, 0xec4, HB_Grapheme_Other},
-  {0xec8, 0xecd, HB_Grapheme_Extend},
-  {0xf18, 0xf19, HB_Grapheme_Extend},
-  {0xf35, 0xf35, HB_Grapheme_Extend},
-  {0xf37, 0xf37, HB_Grapheme_Extend},
-  {0xf39, 0xf39, HB_Grapheme_Extend},
-  {0xf3e, 0xf3f, HB_Grapheme_Other},
-  {0xf71, 0xf7e, HB_Grapheme_Extend},
-  {0xf7f, 0xf7f, HB_Grapheme_Other},
-  {0xf80, 0xf84, HB_Grapheme_Extend},
-  {0xf86, 0xf87, HB_Grapheme_Extend},
-  {0xf90, 0xf97, HB_Grapheme_Extend},
-  {0xf99, 0xfbc, HB_Grapheme_Extend},
-  {0xfc6, 0xfc6, HB_Grapheme_Extend},
-  {0x102b, 0x102c, HB_Grapheme_Other},
-  {0x102d, 0x1030, HB_Grapheme_Extend},
-  {0x1031, 0x1031, HB_Grapheme_Other},
-  {0x1032, 0x1037, HB_Grapheme_Extend},
-  {0x1038, 0x1038, HB_Grapheme_Other},
-  {0x1039, 0x103a, HB_Grapheme_Extend},
-  {0x103b, 0x103c, HB_Grapheme_Other},
-  {0x103d, 0x103e, HB_Grapheme_Extend},
-  {0x1056, 0x1057, HB_Grapheme_Other},
-  {0x1058, 0x1059, HB_Grapheme_Extend},
-  {0x105e, 0x1060, HB_Grapheme_Extend},
-  {0x1062, 0x1064, HB_Grapheme_Other},
-  {0x1067, 0x106d, HB_Grapheme_Other},
-  {0x1071, 0x1074, HB_Grapheme_Extend},
-  {0x1082, 0x1082, HB_Grapheme_Extend},
-  {0x1083, 0x1084, HB_Grapheme_Other},
-  {0x1085, 0x1086, HB_Grapheme_Extend},
-  {0x1087, 0x108c, HB_Grapheme_Other},
-  {0x108d, 0x108d, HB_Grapheme_Extend},
-  {0x108f, 0x108f, HB_Grapheme_Other},
-  {0x1100, 0x1159, HB_Grapheme_L},
-  {0x115f, 0x115f, HB_Grapheme_L},
-  {0x1160, 0x11a2, HB_Grapheme_V},
-  {0x11a8, 0x11f9, HB_Grapheme_T},
-  {0x135f, 0x135f, HB_Grapheme_Extend},
-  {0x1712, 0x1714, HB_Grapheme_Extend},
-  {0x1732, 0x1734, HB_Grapheme_Extend},
-  {0x1752, 0x1753, HB_Grapheme_Extend},
-  {0x1772, 0x1773, HB_Grapheme_Extend},
-  {0x17b4, 0x17b5, HB_Grapheme_Control},
-  {0x17b6, 0x17b6, HB_Grapheme_Other},
-  {0x17b7, 0x17bd, HB_Grapheme_Extend},
-  {0x17be, 0x17c5, HB_Grapheme_Other},
-  {0x17c6, 0x17c6, HB_Grapheme_Extend},
-  {0x17c7, 0x17c8, HB_Grapheme_Other},
-  {0x17c9, 0x17d3, HB_Grapheme_Extend},
-  {0x17dd, 0x17dd, HB_Grapheme_Extend},
-  {0x180b, 0x180d, HB_Grapheme_Extend},
-  {0x18a9, 0x18a9, HB_Grapheme_Extend},
-  {0x1920, 0x1922, HB_Grapheme_Extend},
-  {0x1923, 0x1926, HB_Grapheme_Other},
-  {0x1927, 0x1928, HB_Grapheme_Extend},
-  {0x1929, 0x192b, HB_Grapheme_Other},
-  {0x1930, 0x1931, HB_Grapheme_Other},
-  {0x1932, 0x1932, HB_Grapheme_Extend},
-  {0x1933, 0x1938, HB_Grapheme_Other},
-  {0x1939, 0x193b, HB_Grapheme_Extend},
-  {0x19b0, 0x19c0, HB_Grapheme_Other},
-  {0x19c8, 0x19c9, HB_Grapheme_Other},
-  {0x1a17, 0x1a18, HB_Grapheme_Extend},
-  {0x1a19, 0x1a1b, HB_Grapheme_Other},
-  {0x1b00, 0x1b03, HB_Grapheme_Extend},
-  {0x1b04, 0x1b04, HB_Grapheme_Other},
-  {0x1b34, 0x1b34, HB_Grapheme_Extend},
-  {0x1b35, 0x1b35, HB_Grapheme_Other},
-  {0x1b36, 0x1b3a, HB_Grapheme_Extend},
-  {0x1b3b, 0x1b3b, HB_Grapheme_Other},
-  {0x1b3c, 0x1b3c, HB_Grapheme_Extend},
-  {0x1b3d, 0x1b41, HB_Grapheme_Other},
-  {0x1b42, 0x1b42, HB_Grapheme_Extend},
-  {0x1b43, 0x1b44, HB_Grapheme_Other},
-  {0x1b6b, 0x1b73, HB_Grapheme_Extend},
-  {0x1b80, 0x1b81, HB_Grapheme_Extend},
-  {0x1b82, 0x1b82, HB_Grapheme_Other},
-  {0x1ba1, 0x1ba1, HB_Grapheme_Other},
-  {0x1ba2, 0x1ba5, HB_Grapheme_Extend},
-  {0x1ba6, 0x1ba7, HB_Grapheme_Other},
-  {0x1ba8, 0x1ba9, HB_Grapheme_Extend},
-  {0x1baa, 0x1baa, HB_Grapheme_Other},
-  {0x1c24, 0x1c2b, HB_Grapheme_Other},
-  {0x1c2c, 0x1c33, HB_Grapheme_Extend},
-  {0x1c34, 0x1c35, HB_Grapheme_Other},
-  {0x1c36, 0x1c37, HB_Grapheme_Extend},
-  {0x1dc0, 0x1de6, HB_Grapheme_Extend},
-  {0x1dfe, 0x1dff, HB_Grapheme_Extend},
-  {0x200b, 0x200b, HB_Grapheme_Control},
-  {0x200c, 0x200d, HB_Grapheme_Extend},
-  {0x200e, 0x200f, HB_Grapheme_Control},
-  {0x2028, 0x2028, HB_Grapheme_Control},
-  {0x2029, 0x2029, HB_Grapheme_Control},
-  {0x202a, 0x202e, HB_Grapheme_Control},
-  {0x2060, 0x2064, HB_Grapheme_Control},
-  {0x206a, 0x206f, HB_Grapheme_Control},
-  {0x20d0, 0x20dc, HB_Grapheme_Extend},
-  {0x20dd, 0x20e0, HB_Grapheme_Extend},
-  {0x20e1, 0x20e1, HB_Grapheme_Extend},
-  {0x20e2, 0x20e4, HB_Grapheme_Extend},
-  {0x20e5, 0x20f0, HB_Grapheme_Extend},
-  {0x2de0, 0x2dff, HB_Grapheme_Extend},
-  {0x302a, 0x302f, HB_Grapheme_Extend},
-  {0x3099, 0x309a, HB_Grapheme_Extend},
-  {0xa66f, 0xa66f, HB_Grapheme_Extend},
-  {0xa670, 0xa672, HB_Grapheme_Extend},
-  {0xa67c, 0xa67d, HB_Grapheme_Extend},
-  {0xa802, 0xa802, HB_Grapheme_Extend},
-  {0xa806, 0xa806, HB_Grapheme_Extend},
-  {0xa80b, 0xa80b, HB_Grapheme_Extend},
-  {0xa823, 0xa824, HB_Grapheme_Other},
-  {0xa825, 0xa826, HB_Grapheme_Extend},
-  {0xa827, 0xa827, HB_Grapheme_Other},
-  {0xa880, 0xa881, HB_Grapheme_Other},
-  {0xa8b4, 0xa8c3, HB_Grapheme_Other},
-  {0xa8c4, 0xa8c4, HB_Grapheme_Extend},
-  {0xa926, 0xa92d, HB_Grapheme_Extend},
-  {0xa947, 0xa951, HB_Grapheme_Extend},
-  {0xa952, 0xa953, HB_Grapheme_Other},
-  {0xaa29, 0xaa2e, HB_Grapheme_Extend},
-  {0xaa2f, 0xaa30, HB_Grapheme_Other},
-  {0xaa31, 0xaa32, HB_Grapheme_Extend},
-  {0xaa33, 0xaa34, HB_Grapheme_Other},
-  {0xaa35, 0xaa36, HB_Grapheme_Extend},
-  {0xaa43, 0xaa43, HB_Grapheme_Extend},
-  {0xaa4c, 0xaa4c, HB_Grapheme_Extend},
-  {0xaa4d, 0xaa4d, HB_Grapheme_Other},
-  {0xac00, 0xac00, HB_Grapheme_LV},
-  {0xac01, 0xac1b, HB_Grapheme_LVT},
-  {0xac1c, 0xac1c, HB_Grapheme_LV},
-  {0xac1d, 0xac37, HB_Grapheme_LVT},
-  {0xac38, 0xac38, HB_Grapheme_LV},
-  {0xac39, 0xac53, HB_Grapheme_LVT},
-  {0xac54, 0xac54, HB_Grapheme_LV},
-  {0xac55, 0xac6f, HB_Grapheme_LVT},
-  {0xac70, 0xac70, HB_Grapheme_LV},
-  {0xac71, 0xac8b, HB_Grapheme_LVT},
-  {0xac8c, 0xac8c, HB_Grapheme_LV},
-  {0xac8d, 0xaca7, HB_Grapheme_LVT},
-  {0xaca8, 0xaca8, HB_Grapheme_LV},
-  {0xaca9, 0xacc3, HB_Grapheme_LVT},
-  {0xacc4, 0xacc4, HB_Grapheme_LV},
-  {0xacc5, 0xacdf, HB_Grapheme_LVT},
-  {0xace0, 0xace0, HB_Grapheme_LV},
-  {0xace1, 0xacfb, HB_Grapheme_LVT},
-  {0xacfc, 0xacfc, HB_Grapheme_LV},
-  {0xacfd, 0xad17, HB_Grapheme_LVT},
-  {0xad18, 0xad18, HB_Grapheme_LV},
-  {0xad19, 0xad33, HB_Grapheme_LVT},
-  {0xad34, 0xad34, HB_Grapheme_LV},
-  {0xad35, 0xad4f, HB_Grapheme_LVT},
-  {0xad50, 0xad50, HB_Grapheme_LV},
-  {0xad51, 0xad6b, HB_Grapheme_LVT},
-  {0xad6c, 0xad6c, HB_Grapheme_LV},
-  {0xad6d, 0xad87, HB_Grapheme_LVT},
-  {0xad88, 0xad88, HB_Grapheme_LV},
-  {0xad89, 0xada3, HB_Grapheme_LVT},
-  {0xada4, 0xada4, HB_Grapheme_LV},
-  {0xada5, 0xadbf, HB_Grapheme_LVT},
-  {0xadc0, 0xadc0, HB_Grapheme_LV},
-  {0xadc1, 0xaddb, HB_Grapheme_LVT},
-  {0xaddc, 0xaddc, HB_Grapheme_LV},
-  {0xaddd, 0xadf7, HB_Grapheme_LVT},
-  {0xadf8, 0xadf8, HB_Grapheme_LV},
-  {0xadf9, 0xae13, HB_Grapheme_LVT},
-  {0xae14, 0xae14, HB_Grapheme_LV},
-  {0xae15, 0xae2f, HB_Grapheme_LVT},
-  {0xae30, 0xae30, HB_Grapheme_LV},
-  {0xae31, 0xae4b, HB_Grapheme_LVT},
-  {0xae4c, 0xae4c, HB_Grapheme_LV},
-  {0xae4d, 0xae67, HB_Grapheme_LVT},
-  {0xae68, 0xae68, HB_Grapheme_LV},
-  {0xae69, 0xae83, HB_Grapheme_LVT},
-  {0xae84, 0xae84, HB_Grapheme_LV},
-  {0xae85, 0xae9f, HB_Grapheme_LVT},
-  {0xaea0, 0xaea0, HB_Grapheme_LV},
-  {0xaea1, 0xaebb, HB_Grapheme_LVT},
-  {0xaebc, 0xaebc, HB_Grapheme_LV},
-  {0xaebd, 0xaed7, HB_Grapheme_LVT},
-  {0xaed8, 0xaed8, HB_Grapheme_LV},
-  {0xaed9, 0xaef3, HB_Grapheme_LVT},
-  {0xaef4, 0xaef4, HB_Grapheme_LV},
-  {0xaef5, 0xaf0f, HB_Grapheme_LVT},
-  {0xaf10, 0xaf10, HB_Grapheme_LV},
-  {0xaf11, 0xaf2b, HB_Grapheme_LVT},
-  {0xaf2c, 0xaf2c, HB_Grapheme_LV},
-  {0xaf2d, 0xaf47, HB_Grapheme_LVT},
-  {0xaf48, 0xaf48, HB_Grapheme_LV},
-  {0xaf49, 0xaf63, HB_Grapheme_LVT},
-  {0xaf64, 0xaf64, HB_Grapheme_LV},
-  {0xaf65, 0xaf7f, HB_Grapheme_LVT},
-  {0xaf80, 0xaf80, HB_Grapheme_LV},
-  {0xaf81, 0xaf9b, HB_Grapheme_LVT},
-  {0xaf9c, 0xaf9c, HB_Grapheme_LV},
-  {0xaf9d, 0xafb7, HB_Grapheme_LVT},
-  {0xafb8, 0xafb8, HB_Grapheme_LV},
-  {0xafb9, 0xafd3, HB_Grapheme_LVT},
-  {0xafd4, 0xafd4, HB_Grapheme_LV},
-  {0xafd5, 0xafef, HB_Grapheme_LVT},
-  {0xaff0, 0xaff0, HB_Grapheme_LV},
-  {0xaff1, 0xb00b, HB_Grapheme_LVT},
-  {0xb00c, 0xb00c, HB_Grapheme_LV},
-  {0xb00d, 0xb027, HB_Grapheme_LVT},
-  {0xb028, 0xb028, HB_Grapheme_LV},
-  {0xb029, 0xb043, HB_Grapheme_LVT},
-  {0xb044, 0xb044, HB_Grapheme_LV},
-  {0xb045, 0xb05f, HB_Grapheme_LVT},
-  {0xb060, 0xb060, HB_Grapheme_LV},
-  {0xb061, 0xb07b, HB_Grapheme_LVT},
-  {0xb07c, 0xb07c, HB_Grapheme_LV},
-  {0xb07d, 0xb097, HB_Grapheme_LVT},
-  {0xb098, 0xb098, HB_Grapheme_LV},
-  {0xb099, 0xb0b3, HB_Grapheme_LVT},
-  {0xb0b4, 0xb0b4, HB_Grapheme_LV},
-  {0xb0b5, 0xb0cf, HB_Grapheme_LVT},
-  {0xb0d0, 0xb0d0, HB_Grapheme_LV},
-  {0xb0d1, 0xb0eb, HB_Grapheme_LVT},
-  {0xb0ec, 0xb0ec, HB_Grapheme_LV},
-  {0xb0ed, 0xb107, HB_Grapheme_LVT},
-  {0xb108, 0xb108, HB_Grapheme_LV},
-  {0xb109, 0xb123, HB_Grapheme_LVT},
-  {0xb124, 0xb124, HB_Grapheme_LV},
-  {0xb125, 0xb13f, HB_Grapheme_LVT},
-  {0xb140, 0xb140, HB_Grapheme_LV},
-  {0xb141, 0xb15b, HB_Grapheme_LVT},
-  {0xb15c, 0xb15c, HB_Grapheme_LV},
-  {0xb15d, 0xb177, HB_Grapheme_LVT},
-  {0xb178, 0xb178, HB_Grapheme_LV},
-  {0xb179, 0xb193, HB_Grapheme_LVT},
-  {0xb194, 0xb194, HB_Grapheme_LV},
-  {0xb195, 0xb1af, HB_Grapheme_LVT},
-  {0xb1b0, 0xb1b0, HB_Grapheme_LV},
-  {0xb1b1, 0xb1cb, HB_Grapheme_LVT},
-  {0xb1cc, 0xb1cc, HB_Grapheme_LV},
-  {0xb1cd, 0xb1e7, HB_Grapheme_LVT},
-  {0xb1e8, 0xb1e8, HB_Grapheme_LV},
-  {0xb1e9, 0xb203, HB_Grapheme_LVT},
-  {0xb204, 0xb204, HB_Grapheme_LV},
-  {0xb205, 0xb21f, HB_Grapheme_LVT},
-  {0xb220, 0xb220, HB_Grapheme_LV},
-  {0xb221, 0xb23b, HB_Grapheme_LVT},
-  {0xb23c, 0xb23c, HB_Grapheme_LV},
-  {0xb23d, 0xb257, HB_Grapheme_LVT},
-  {0xb258, 0xb258, HB_Grapheme_LV},
-  {0xb259, 0xb273, HB_Grapheme_LVT},
-  {0xb274, 0xb274, HB_Grapheme_LV},
-  {0xb275, 0xb28f, HB_Grapheme_LVT},
-  {0xb290, 0xb290, HB_Grapheme_LV},
-  {0xb291, 0xb2ab, HB_Grapheme_LVT},
-  {0xb2ac, 0xb2ac, HB_Grapheme_LV},
-  {0xb2ad, 0xb2c7, HB_Grapheme_LVT},
-  {0xb2c8, 0xb2c8, HB_Grapheme_LV},
-  {0xb2c9, 0xb2e3, HB_Grapheme_LVT},
-  {0xb2e4, 0xb2e4, HB_Grapheme_LV},
-  {0xb2e5, 0xb2ff, HB_Grapheme_LVT},
-  {0xb300, 0xb300, HB_Grapheme_LV},
-  {0xb301, 0xb31b, HB_Grapheme_LVT},
-  {0xb31c, 0xb31c, HB_Grapheme_LV},
-  {0xb31d, 0xb337, HB_Grapheme_LVT},
-  {0xb338, 0xb338, HB_Grapheme_LV},
-  {0xb339, 0xb353, HB_Grapheme_LVT},
-  {0xb354, 0xb354, HB_Grapheme_LV},
-  {0xb355, 0xb36f, HB_Grapheme_LVT},
-  {0xb370, 0xb370, HB_Grapheme_LV},
-  {0xb371, 0xb38b, HB_Grapheme_LVT},
-  {0xb38c, 0xb38c, HB_Grapheme_LV},
-  {0xb38d, 0xb3a7, HB_Grapheme_LVT},
-  {0xb3a8, 0xb3a8, HB_Grapheme_LV},
-  {0xb3a9, 0xb3c3, HB_Grapheme_LVT},
-  {0xb3c4, 0xb3c4, HB_Grapheme_LV},
-  {0xb3c5, 0xb3df, HB_Grapheme_LVT},
-  {0xb3e0, 0xb3e0, HB_Grapheme_LV},
-  {0xb3e1, 0xb3fb, HB_Grapheme_LVT},
-  {0xb3fc, 0xb3fc, HB_Grapheme_LV},
-  {0xb3fd, 0xb417, HB_Grapheme_LVT},
-  {0xb418, 0xb418, HB_Grapheme_LV},
-  {0xb419, 0xb433, HB_Grapheme_LVT},
-  {0xb434, 0xb434, HB_Grapheme_LV},
-  {0xb435, 0xb44f, HB_Grapheme_LVT},
-  {0xb450, 0xb450, HB_Grapheme_LV},
-  {0xb451, 0xb46b, HB_Grapheme_LVT},
-  {0xb46c, 0xb46c, HB_Grapheme_LV},
-  {0xb46d, 0xb487, HB_Grapheme_LVT},
-  {0xb488, 0xb488, HB_Grapheme_LV},
-  {0xb489, 0xb4a3, HB_Grapheme_LVT},
-  {0xb4a4, 0xb4a4, HB_Grapheme_LV},
-  {0xb4a5, 0xb4bf, HB_Grapheme_LVT},
-  {0xb4c0, 0xb4c0, HB_Grapheme_LV},
-  {0xb4c1, 0xb4db, HB_Grapheme_LVT},
-  {0xb4dc, 0xb4dc, HB_Grapheme_LV},
-  {0xb4dd, 0xb4f7, HB_Grapheme_LVT},
-  {0xb4f8, 0xb4f8, HB_Grapheme_LV},
-  {0xb4f9, 0xb513, HB_Grapheme_LVT},
-  {0xb514, 0xb514, HB_Grapheme_LV},
-  {0xb515, 0xb52f, HB_Grapheme_LVT},
-  {0xb530, 0xb530, HB_Grapheme_LV},
-  {0xb531, 0xb54b, HB_Grapheme_LVT},
-  {0xb54c, 0xb54c, HB_Grapheme_LV},
-  {0xb54d, 0xb567, HB_Grapheme_LVT},
-  {0xb568, 0xb568, HB_Grapheme_LV},
-  {0xb569, 0xb583, HB_Grapheme_LVT},
-  {0xb584, 0xb584, HB_Grapheme_LV},
-  {0xb585, 0xb59f, HB_Grapheme_LVT},
-  {0xb5a0, 0xb5a0, HB_Grapheme_LV},
-  {0xb5a1, 0xb5bb, HB_Grapheme_LVT},
-  {0xb5bc, 0xb5bc, HB_Grapheme_LV},
-  {0xb5bd, 0xb5d7, HB_Grapheme_LVT},
-  {0xb5d8, 0xb5d8, HB_Grapheme_LV},
-  {0xb5d9, 0xb5f3, HB_Grapheme_LVT},
-  {0xb5f4, 0xb5f4, HB_Grapheme_LV},
-  {0xb5f5, 0xb60f, HB_Grapheme_LVT},
-  {0xb610, 0xb610, HB_Grapheme_LV},
-  {0xb611, 0xb62b, HB_Grapheme_LVT},
-  {0xb62c, 0xb62c, HB_Grapheme_LV},
-  {0xb62d, 0xb647, HB_Grapheme_LVT},
-  {0xb648, 0xb648, HB_Grapheme_LV},
-  {0xb649, 0xb663, HB_Grapheme_LVT},
-  {0xb664, 0xb664, HB_Grapheme_LV},
-  {0xb665, 0xb67f, HB_Grapheme_LVT},
-  {0xb680, 0xb680, HB_Grapheme_LV},
-  {0xb681, 0xb69b, HB_Grapheme_LVT},
-  {0xb69c, 0xb69c, HB_Grapheme_LV},
-  {0xb69d, 0xb6b7, HB_Grapheme_LVT},
-  {0xb6b8, 0xb6b8, HB_Grapheme_LV},
-  {0xb6b9, 0xb6d3, HB_Grapheme_LVT},
-  {0xb6d4, 0xb6d4, HB_Grapheme_LV},
-  {0xb6d5, 0xb6ef, HB_Grapheme_LVT},
-  {0xb6f0, 0xb6f0, HB_Grapheme_LV},
-  {0xb6f1, 0xb70b, HB_Grapheme_LVT},
-  {0xb70c, 0xb70c, HB_Grapheme_LV},
-  {0xb70d, 0xb727, HB_Grapheme_LVT},
-  {0xb728, 0xb728, HB_Grapheme_LV},
-  {0xb729, 0xb743, HB_Grapheme_LVT},
-  {0xb744, 0xb744, HB_Grapheme_LV},
-  {0xb745, 0xb75f, HB_Grapheme_LVT},
-  {0xb760, 0xb760, HB_Grapheme_LV},
-  {0xb761, 0xb77b, HB_Grapheme_LVT},
-  {0xb77c, 0xb77c, HB_Grapheme_LV},
-  {0xb77d, 0xb797, HB_Grapheme_LVT},
-  {0xb798, 0xb798, HB_Grapheme_LV},
-  {0xb799, 0xb7b3, HB_Grapheme_LVT},
-  {0xb7b4, 0xb7b4, HB_Grapheme_LV},
-  {0xb7b5, 0xb7cf, HB_Grapheme_LVT},
-  {0xb7d0, 0xb7d0, HB_Grapheme_LV},
-  {0xb7d1, 0xb7eb, HB_Grapheme_LVT},
-  {0xb7ec, 0xb7ec, HB_Grapheme_LV},
-  {0xb7ed, 0xb807, HB_Grapheme_LVT},
-  {0xb808, 0xb808, HB_Grapheme_LV},
-  {0xb809, 0xb823, HB_Grapheme_LVT},
-  {0xb824, 0xb824, HB_Grapheme_LV},
-  {0xb825, 0xb83f, HB_Grapheme_LVT},
-  {0xb840, 0xb840, HB_Grapheme_LV},
-  {0xb841, 0xb85b, HB_Grapheme_LVT},
-  {0xb85c, 0xb85c, HB_Grapheme_LV},
-  {0xb85d, 0xb877, HB_Grapheme_LVT},
-  {0xb878, 0xb878, HB_Grapheme_LV},
-  {0xb879, 0xb893, HB_Grapheme_LVT},
-  {0xb894, 0xb894, HB_Grapheme_LV},
-  {0xb895, 0xb8af, HB_Grapheme_LVT},
-  {0xb8b0, 0xb8b0, HB_Grapheme_LV},
-  {0xb8b1, 0xb8cb, HB_Grapheme_LVT},
-  {0xb8cc, 0xb8cc, HB_Grapheme_LV},
-  {0xb8cd, 0xb8e7, HB_Grapheme_LVT},
-  {0xb8e8, 0xb8e8, HB_Grapheme_LV},
-  {0xb8e9, 0xb903, HB_Grapheme_LVT},
-  {0xb904, 0xb904, HB_Grapheme_LV},
-  {0xb905, 0xb91f, HB_Grapheme_LVT},
-  {0xb920, 0xb920, HB_Grapheme_LV},
-  {0xb921, 0xb93b, HB_Grapheme_LVT},
-  {0xb93c, 0xb93c, HB_Grapheme_LV},
-  {0xb93d, 0xb957, HB_Grapheme_LVT},
-  {0xb958, 0xb958, HB_Grapheme_LV},
-  {0xb959, 0xb973, HB_Grapheme_LVT},
-  {0xb974, 0xb974, HB_Grapheme_LV},
-  {0xb975, 0xb98f, HB_Grapheme_LVT},
-  {0xb990, 0xb990, HB_Grapheme_LV},
-  {0xb991, 0xb9ab, HB_Grapheme_LVT},
-  {0xb9ac, 0xb9ac, HB_Grapheme_LV},
-  {0xb9ad, 0xb9c7, HB_Grapheme_LVT},
-  {0xb9c8, 0xb9c8, HB_Grapheme_LV},
-  {0xb9c9, 0xb9e3, HB_Grapheme_LVT},
-  {0xb9e4, 0xb9e4, HB_Grapheme_LV},
-  {0xb9e5, 0xb9ff, HB_Grapheme_LVT},
-  {0xba00, 0xba00, HB_Grapheme_LV},
-  {0xba01, 0xba1b, HB_Grapheme_LVT},
-  {0xba1c, 0xba1c, HB_Grapheme_LV},
-  {0xba1d, 0xba37, HB_Grapheme_LVT},
-  {0xba38, 0xba38, HB_Grapheme_LV},
-  {0xba39, 0xba53, HB_Grapheme_LVT},
-  {0xba54, 0xba54, HB_Grapheme_LV},
-  {0xba55, 0xba6f, HB_Grapheme_LVT},
-  {0xba70, 0xba70, HB_Grapheme_LV},
-  {0xba71, 0xba8b, HB_Grapheme_LVT},
-  {0xba8c, 0xba8c, HB_Grapheme_LV},
-  {0xba8d, 0xbaa7, HB_Grapheme_LVT},
-  {0xbaa8, 0xbaa8, HB_Grapheme_LV},
-  {0xbaa9, 0xbac3, HB_Grapheme_LVT},
-  {0xbac4, 0xbac4, HB_Grapheme_LV},
-  {0xbac5, 0xbadf, HB_Grapheme_LVT},
-  {0xbae0, 0xbae0, HB_Grapheme_LV},
-  {0xbae1, 0xbafb, HB_Grapheme_LVT},
-  {0xbafc, 0xbafc, HB_Grapheme_LV},
-  {0xbafd, 0xbb17, HB_Grapheme_LVT},
-  {0xbb18, 0xbb18, HB_Grapheme_LV},
-  {0xbb19, 0xbb33, HB_Grapheme_LVT},
-  {0xbb34, 0xbb34, HB_Grapheme_LV},
-  {0xbb35, 0xbb4f, HB_Grapheme_LVT},
-  {0xbb50, 0xbb50, HB_Grapheme_LV},
-  {0xbb51, 0xbb6b, HB_Grapheme_LVT},
-  {0xbb6c, 0xbb6c, HB_Grapheme_LV},
-  {0xbb6d, 0xbb87, HB_Grapheme_LVT},
-  {0xbb88, 0xbb88, HB_Grapheme_LV},
-  {0xbb89, 0xbba3, HB_Grapheme_LVT},
-  {0xbba4, 0xbba4, HB_Grapheme_LV},
-  {0xbba5, 0xbbbf, HB_Grapheme_LVT},
-  {0xbbc0, 0xbbc0, HB_Grapheme_LV},
-  {0xbbc1, 0xbbdb, HB_Grapheme_LVT},
-  {0xbbdc, 0xbbdc, HB_Grapheme_LV},
-  {0xbbdd, 0xbbf7, HB_Grapheme_LVT},
-  {0xbbf8, 0xbbf8, HB_Grapheme_LV},
-  {0xbbf9, 0xbc13, HB_Grapheme_LVT},
-  {0xbc14, 0xbc14, HB_Grapheme_LV},
-  {0xbc15, 0xbc2f, HB_Grapheme_LVT},
-  {0xbc30, 0xbc30, HB_Grapheme_LV},
-  {0xbc31, 0xbc4b, HB_Grapheme_LVT},
-  {0xbc4c, 0xbc4c, HB_Grapheme_LV},
-  {0xbc4d, 0xbc67, HB_Grapheme_LVT},
-  {0xbc68, 0xbc68, HB_Grapheme_LV},
-  {0xbc69, 0xbc83, HB_Grapheme_LVT},
-  {0xbc84, 0xbc84, HB_Grapheme_LV},
-  {0xbc85, 0xbc9f, HB_Grapheme_LVT},
-  {0xbca0, 0xbca0, HB_Grapheme_LV},
-  {0xbca1, 0xbcbb, HB_Grapheme_LVT},
-  {0xbcbc, 0xbcbc, HB_Grapheme_LV},
-  {0xbcbd, 0xbcd7, HB_Grapheme_LVT},
-  {0xbcd8, 0xbcd8, HB_Grapheme_LV},
-  {0xbcd9, 0xbcf3, HB_Grapheme_LVT},
-  {0xbcf4, 0xbcf4, HB_Grapheme_LV},
-  {0xbcf5, 0xbd0f, HB_Grapheme_LVT},
-  {0xbd10, 0xbd10, HB_Grapheme_LV},
-  {0xbd11, 0xbd2b, HB_Grapheme_LVT},
-  {0xbd2c, 0xbd2c, HB_Grapheme_LV},
-  {0xbd2d, 0xbd47, HB_Grapheme_LVT},
-  {0xbd48, 0xbd48, HB_Grapheme_LV},
-  {0xbd49, 0xbd63, HB_Grapheme_LVT},
-  {0xbd64, 0xbd64, HB_Grapheme_LV},
-  {0xbd65, 0xbd7f, HB_Grapheme_LVT},
-  {0xbd80, 0xbd80, HB_Grapheme_LV},
-  {0xbd81, 0xbd9b, HB_Grapheme_LVT},
-  {0xbd9c, 0xbd9c, HB_Grapheme_LV},
-  {0xbd9d, 0xbdb7, HB_Grapheme_LVT},
-  {0xbdb8, 0xbdb8, HB_Grapheme_LV},
-  {0xbdb9, 0xbdd3, HB_Grapheme_LVT},
-  {0xbdd4, 0xbdd4, HB_Grapheme_LV},
-  {0xbdd5, 0xbdef, HB_Grapheme_LVT},
-  {0xbdf0, 0xbdf0, HB_Grapheme_LV},
-  {0xbdf1, 0xbe0b, HB_Grapheme_LVT},
-  {0xbe0c, 0xbe0c, HB_Grapheme_LV},
-  {0xbe0d, 0xbe27, HB_Grapheme_LVT},
-  {0xbe28, 0xbe28, HB_Grapheme_LV},
-  {0xbe29, 0xbe43, HB_Grapheme_LVT},
-  {0xbe44, 0xbe44, HB_Grapheme_LV},
-  {0xbe45, 0xbe5f, HB_Grapheme_LVT},
-  {0xbe60, 0xbe60, HB_Grapheme_LV},
-  {0xbe61, 0xbe7b, HB_Grapheme_LVT},
-  {0xbe7c, 0xbe7c, HB_Grapheme_LV},
-  {0xbe7d, 0xbe97, HB_Grapheme_LVT},
-  {0xbe98, 0xbe98, HB_Grapheme_LV},
-  {0xbe99, 0xbeb3, HB_Grapheme_LVT},
-  {0xbeb4, 0xbeb4, HB_Grapheme_LV},
-  {0xbeb5, 0xbecf, HB_Grapheme_LVT},
-  {0xbed0, 0xbed0, HB_Grapheme_LV},
-  {0xbed1, 0xbeeb, HB_Grapheme_LVT},
-  {0xbeec, 0xbeec, HB_Grapheme_LV},
-  {0xbeed, 0xbf07, HB_Grapheme_LVT},
-  {0xbf08, 0xbf08, HB_Grapheme_LV},
-  {0xbf09, 0xbf23, HB_Grapheme_LVT},
-  {0xbf24, 0xbf24, HB_Grapheme_LV},
-  {0xbf25, 0xbf3f, HB_Grapheme_LVT},
-  {0xbf40, 0xbf40, HB_Grapheme_LV},
-  {0xbf41, 0xbf5b, HB_Grapheme_LVT},
-  {0xbf5c, 0xbf5c, HB_Grapheme_LV},
-  {0xbf5d, 0xbf77, HB_Grapheme_LVT},
-  {0xbf78, 0xbf78, HB_Grapheme_LV},
-  {0xbf79, 0xbf93, HB_Grapheme_LVT},
-  {0xbf94, 0xbf94, HB_Grapheme_LV},
-  {0xbf95, 0xbfaf, HB_Grapheme_LVT},
-  {0xbfb0, 0xbfb0, HB_Grapheme_LV},
-  {0xbfb1, 0xbfcb, HB_Grapheme_LVT},
-  {0xbfcc, 0xbfcc, HB_Grapheme_LV},
-  {0xbfcd, 0xbfe7, HB_Grapheme_LVT},
-  {0xbfe8, 0xbfe8, HB_Grapheme_LV},
-  {0xbfe9, 0xc003, HB_Grapheme_LVT},
-  {0xc004, 0xc004, HB_Grapheme_LV},
-  {0xc005, 0xc01f, HB_Grapheme_LVT},
-  {0xc020, 0xc020, HB_Grapheme_LV},
-  {0xc021, 0xc03b, HB_Grapheme_LVT},
-  {0xc03c, 0xc03c, HB_Grapheme_LV},
-  {0xc03d, 0xc057, HB_Grapheme_LVT},
-  {0xc058, 0xc058, HB_Grapheme_LV},
-  {0xc059, 0xc073, HB_Grapheme_LVT},
-  {0xc074, 0xc074, HB_Grapheme_LV},
-  {0xc075, 0xc08f, HB_Grapheme_LVT},
-  {0xc090, 0xc090, HB_Grapheme_LV},
-  {0xc091, 0xc0ab, HB_Grapheme_LVT},
-  {0xc0ac, 0xc0ac, HB_Grapheme_LV},
-  {0xc0ad, 0xc0c7, HB_Grapheme_LVT},
-  {0xc0c8, 0xc0c8, HB_Grapheme_LV},
-  {0xc0c9, 0xc0e3, HB_Grapheme_LVT},
-  {0xc0e4, 0xc0e4, HB_Grapheme_LV},
-  {0xc0e5, 0xc0ff, HB_Grapheme_LVT},
-  {0xc100, 0xc100, HB_Grapheme_LV},
-  {0xc101, 0xc11b, HB_Grapheme_LVT},
-  {0xc11c, 0xc11c, HB_Grapheme_LV},
-  {0xc11d, 0xc137, HB_Grapheme_LVT},
-  {0xc138, 0xc138, HB_Grapheme_LV},
-  {0xc139, 0xc153, HB_Grapheme_LVT},
-  {0xc154, 0xc154, HB_Grapheme_LV},
-  {0xc155, 0xc16f, HB_Grapheme_LVT},
-  {0xc170, 0xc170, HB_Grapheme_LV},
-  {0xc171, 0xc18b, HB_Grapheme_LVT},
-  {0xc18c, 0xc18c, HB_Grapheme_LV},
-  {0xc18d, 0xc1a7, HB_Grapheme_LVT},
-  {0xc1a8, 0xc1a8, HB_Grapheme_LV},
-  {0xc1a9, 0xc1c3, HB_Grapheme_LVT},
-  {0xc1c4, 0xc1c4, HB_Grapheme_LV},
-  {0xc1c5, 0xc1df, HB_Grapheme_LVT},
-  {0xc1e0, 0xc1e0, HB_Grapheme_LV},
-  {0xc1e1, 0xc1fb, HB_Grapheme_LVT},
-  {0xc1fc, 0xc1fc, HB_Grapheme_LV},
-  {0xc1fd, 0xc217, HB_Grapheme_LVT},
-  {0xc218, 0xc218, HB_Grapheme_LV},
-  {0xc219, 0xc233, HB_Grapheme_LVT},
-  {0xc234, 0xc234, HB_Grapheme_LV},
-  {0xc235, 0xc24f, HB_Grapheme_LVT},
-  {0xc250, 0xc250, HB_Grapheme_LV},
-  {0xc251, 0xc26b, HB_Grapheme_LVT},
-  {0xc26c, 0xc26c, HB_Grapheme_LV},
-  {0xc26d, 0xc287, HB_Grapheme_LVT},
-  {0xc288, 0xc288, HB_Grapheme_LV},
-  {0xc289, 0xc2a3, HB_Grapheme_LVT},
-  {0xc2a4, 0xc2a4, HB_Grapheme_LV},
-  {0xc2a5, 0xc2bf, HB_Grapheme_LVT},
-  {0xc2c0, 0xc2c0, HB_Grapheme_LV},
-  {0xc2c1, 0xc2db, HB_Grapheme_LVT},
-  {0xc2dc, 0xc2dc, HB_Grapheme_LV},
-  {0xc2dd, 0xc2f7, HB_Grapheme_LVT},
-  {0xc2f8, 0xc2f8, HB_Grapheme_LV},
-  {0xc2f9, 0xc313, HB_Grapheme_LVT},
-  {0xc314, 0xc314, HB_Grapheme_LV},
-  {0xc315, 0xc32f, HB_Grapheme_LVT},
-  {0xc330, 0xc330, HB_Grapheme_LV},
-  {0xc331, 0xc34b, HB_Grapheme_LVT},
-  {0xc34c, 0xc34c, HB_Grapheme_LV},
-  {0xc34d, 0xc367, HB_Grapheme_LVT},
-  {0xc368, 0xc368, HB_Grapheme_LV},
-  {0xc369, 0xc383, HB_Grapheme_LVT},
-  {0xc384, 0xc384, HB_Grapheme_LV},
-  {0xc385, 0xc39f, HB_Grapheme_LVT},
-  {0xc3a0, 0xc3a0, HB_Grapheme_LV},
-  {0xc3a1, 0xc3bb, HB_Grapheme_LVT},
-  {0xc3bc, 0xc3bc, HB_Grapheme_LV},
-  {0xc3bd, 0xc3d7, HB_Grapheme_LVT},
-  {0xc3d8, 0xc3d8, HB_Grapheme_LV},
-  {0xc3d9, 0xc3f3, HB_Grapheme_LVT},
-  {0xc3f4, 0xc3f4, HB_Grapheme_LV},
-  {0xc3f5, 0xc40f, HB_Grapheme_LVT},
-  {0xc410, 0xc410, HB_Grapheme_LV},
-  {0xc411, 0xc42b, HB_Grapheme_LVT},
-  {0xc42c, 0xc42c, HB_Grapheme_LV},
-  {0xc42d, 0xc447, HB_Grapheme_LVT},
-  {0xc448, 0xc448, HB_Grapheme_LV},
-  {0xc449, 0xc463, HB_Grapheme_LVT},
-  {0xc464, 0xc464, HB_Grapheme_LV},
-  {0xc465, 0xc47f, HB_Grapheme_LVT},
-  {0xc480, 0xc480, HB_Grapheme_LV},
-  {0xc481, 0xc49b, HB_Grapheme_LVT},
-  {0xc49c, 0xc49c, HB_Grapheme_LV},
-  {0xc49d, 0xc4b7, HB_Grapheme_LVT},
-  {0xc4b8, 0xc4b8, HB_Grapheme_LV},
-  {0xc4b9, 0xc4d3, HB_Grapheme_LVT},
-  {0xc4d4, 0xc4d4, HB_Grapheme_LV},
-  {0xc4d5, 0xc4ef, HB_Grapheme_LVT},
-  {0xc4f0, 0xc4f0, HB_Grapheme_LV},
-  {0xc4f1, 0xc50b, HB_Grapheme_LVT},
-  {0xc50c, 0xc50c, HB_Grapheme_LV},
-  {0xc50d, 0xc527, HB_Grapheme_LVT},
-  {0xc528, 0xc528, HB_Grapheme_LV},
-  {0xc529, 0xc543, HB_Grapheme_LVT},
-  {0xc544, 0xc544, HB_Grapheme_LV},
-  {0xc545, 0xc55f, HB_Grapheme_LVT},
-  {0xc560, 0xc560, HB_Grapheme_LV},
-  {0xc561, 0xc57b, HB_Grapheme_LVT},
-  {0xc57c, 0xc57c, HB_Grapheme_LV},
-  {0xc57d, 0xc597, HB_Grapheme_LVT},
-  {0xc598, 0xc598, HB_Grapheme_LV},
-  {0xc599, 0xc5b3, HB_Grapheme_LVT},
-  {0xc5b4, 0xc5b4, HB_Grapheme_LV},
-  {0xc5b5, 0xc5cf, HB_Grapheme_LVT},
-  {0xc5d0, 0xc5d0, HB_Grapheme_LV},
-  {0xc5d1, 0xc5eb, HB_Grapheme_LVT},
-  {0xc5ec, 0xc5ec, HB_Grapheme_LV},
-  {0xc5ed, 0xc607, HB_Grapheme_LVT},
-  {0xc608, 0xc608, HB_Grapheme_LV},
-  {0xc609, 0xc623, HB_Grapheme_LVT},
-  {0xc624, 0xc624, HB_Grapheme_LV},
-  {0xc625, 0xc63f, HB_Grapheme_LVT},
-  {0xc640, 0xc640, HB_Grapheme_LV},
-  {0xc641, 0xc65b, HB_Grapheme_LVT},
-  {0xc65c, 0xc65c, HB_Grapheme_LV},
-  {0xc65d, 0xc677, HB_Grapheme_LVT},
-  {0xc678, 0xc678, HB_Grapheme_LV},
-  {0xc679, 0xc693, HB_Grapheme_LVT},
-  {0xc694, 0xc694, HB_Grapheme_LV},
-  {0xc695, 0xc6af, HB_Grapheme_LVT},
-  {0xc6b0, 0xc6b0, HB_Grapheme_LV},
-  {0xc6b1, 0xc6cb, HB_Grapheme_LVT},
-  {0xc6cc, 0xc6cc, HB_Grapheme_LV},
-  {0xc6cd, 0xc6e7, HB_Grapheme_LVT},
-  {0xc6e8, 0xc6e8, HB_Grapheme_LV},
-  {0xc6e9, 0xc703, HB_Grapheme_LVT},
-  {0xc704, 0xc704, HB_Grapheme_LV},
-  {0xc705, 0xc71f, HB_Grapheme_LVT},
-  {0xc720, 0xc720, HB_Grapheme_LV},
-  {0xc721, 0xc73b, HB_Grapheme_LVT},
-  {0xc73c, 0xc73c, HB_Grapheme_LV},
-  {0xc73d, 0xc757, HB_Grapheme_LVT},
-  {0xc758, 0xc758, HB_Grapheme_LV},
-  {0xc759, 0xc773, HB_Grapheme_LVT},
-  {0xc774, 0xc774, HB_Grapheme_LV},
-  {0xc775, 0xc78f, HB_Grapheme_LVT},
-  {0xc790, 0xc790, HB_Grapheme_LV},
-  {0xc791, 0xc7ab, HB_Grapheme_LVT},
-  {0xc7ac, 0xc7ac, HB_Grapheme_LV},
-  {0xc7ad, 0xc7c7, HB_Grapheme_LVT},
-  {0xc7c8, 0xc7c8, HB_Grapheme_LV},
-  {0xc7c9, 0xc7e3, HB_Grapheme_LVT},
-  {0xc7e4, 0xc7e4, HB_Grapheme_LV},
-  {0xc7e5, 0xc7ff, HB_Grapheme_LVT},
-  {0xc800, 0xc800, HB_Grapheme_LV},
-  {0xc801, 0xc81b, HB_Grapheme_LVT},
-  {0xc81c, 0xc81c, HB_Grapheme_LV},
-  {0xc81d, 0xc837, HB_Grapheme_LVT},
-  {0xc838, 0xc838, HB_Grapheme_LV},
-  {0xc839, 0xc853, HB_Grapheme_LVT},
-  {0xc854, 0xc854, HB_Grapheme_LV},
-  {0xc855, 0xc86f, HB_Grapheme_LVT},
-  {0xc870, 0xc870, HB_Grapheme_LV},
-  {0xc871, 0xc88b, HB_Grapheme_LVT},
-  {0xc88c, 0xc88c, HB_Grapheme_LV},
-  {0xc88d, 0xc8a7, HB_Grapheme_LVT},
-  {0xc8a8, 0xc8a8, HB_Grapheme_LV},
-  {0xc8a9, 0xc8c3, HB_Grapheme_LVT},
-  {0xc8c4, 0xc8c4, HB_Grapheme_LV},
-  {0xc8c5, 0xc8df, HB_Grapheme_LVT},
-  {0xc8e0, 0xc8e0, HB_Grapheme_LV},
-  {0xc8e1, 0xc8fb, HB_Grapheme_LVT},
-  {0xc8fc, 0xc8fc, HB_Grapheme_LV},
-  {0xc8fd, 0xc917, HB_Grapheme_LVT},
-  {0xc918, 0xc918, HB_Grapheme_LV},
-  {0xc919, 0xc933, HB_Grapheme_LVT},
-  {0xc934, 0xc934, HB_Grapheme_LV},
-  {0xc935, 0xc94f, HB_Grapheme_LVT},
-  {0xc950, 0xc950, HB_Grapheme_LV},
-  {0xc951, 0xc96b, HB_Grapheme_LVT},
-  {0xc96c, 0xc96c, HB_Grapheme_LV},
-  {0xc96d, 0xc987, HB_Grapheme_LVT},
-  {0xc988, 0xc988, HB_Grapheme_LV},
-  {0xc989, 0xc9a3, HB_Grapheme_LVT},
-  {0xc9a4, 0xc9a4, HB_Grapheme_LV},
-  {0xc9a5, 0xc9bf, HB_Grapheme_LVT},
-  {0xc9c0, 0xc9c0, HB_Grapheme_LV},
-  {0xc9c1, 0xc9db, HB_Grapheme_LVT},
-  {0xc9dc, 0xc9dc, HB_Grapheme_LV},
-  {0xc9dd, 0xc9f7, HB_Grapheme_LVT},
-  {0xc9f8, 0xc9f8, HB_Grapheme_LV},
-  {0xc9f9, 0xca13, HB_Grapheme_LVT},
-  {0xca14, 0xca14, HB_Grapheme_LV},
-  {0xca15, 0xca2f, HB_Grapheme_LVT},
-  {0xca30, 0xca30, HB_Grapheme_LV},
-  {0xca31, 0xca4b, HB_Grapheme_LVT},
-  {0xca4c, 0xca4c, HB_Grapheme_LV},
-  {0xca4d, 0xca67, HB_Grapheme_LVT},
-  {0xca68, 0xca68, HB_Grapheme_LV},
-  {0xca69, 0xca83, HB_Grapheme_LVT},
-  {0xca84, 0xca84, HB_Grapheme_LV},
-  {0xca85, 0xca9f, HB_Grapheme_LVT},
-  {0xcaa0, 0xcaa0, HB_Grapheme_LV},
-  {0xcaa1, 0xcabb, HB_Grapheme_LVT},
-  {0xcabc, 0xcabc, HB_Grapheme_LV},
-  {0xcabd, 0xcad7, HB_Grapheme_LVT},
-  {0xcad8, 0xcad8, HB_Grapheme_LV},
-  {0xcad9, 0xcaf3, HB_Grapheme_LVT},
-  {0xcaf4, 0xcaf4, HB_Grapheme_LV},
-  {0xcaf5, 0xcb0f, HB_Grapheme_LVT},
-  {0xcb10, 0xcb10, HB_Grapheme_LV},
-  {0xcb11, 0xcb2b, HB_Grapheme_LVT},
-  {0xcb2c, 0xcb2c, HB_Grapheme_LV},
-  {0xcb2d, 0xcb47, HB_Grapheme_LVT},
-  {0xcb48, 0xcb48, HB_Grapheme_LV},
-  {0xcb49, 0xcb63, HB_Grapheme_LVT},
-  {0xcb64, 0xcb64, HB_Grapheme_LV},
-  {0xcb65, 0xcb7f, HB_Grapheme_LVT},
-  {0xcb80, 0xcb80, HB_Grapheme_LV},
-  {0xcb81, 0xcb9b, HB_Grapheme_LVT},
-  {0xcb9c, 0xcb9c, HB_Grapheme_LV},
-  {0xcb9d, 0xcbb7, HB_Grapheme_LVT},
-  {0xcbb8, 0xcbb8, HB_Grapheme_LV},
-  {0xcbb9, 0xcbd3, HB_Grapheme_LVT},
-  {0xcbd4, 0xcbd4, HB_Grapheme_LV},
-  {0xcbd5, 0xcbef, HB_Grapheme_LVT},
-  {0xcbf0, 0xcbf0, HB_Grapheme_LV},
-  {0xcbf1, 0xcc0b, HB_Grapheme_LVT},
-  {0xcc0c, 0xcc0c, HB_Grapheme_LV},
-  {0xcc0d, 0xcc27, HB_Grapheme_LVT},
-  {0xcc28, 0xcc28, HB_Grapheme_LV},
-  {0xcc29, 0xcc43, HB_Grapheme_LVT},
-  {0xcc44, 0xcc44, HB_Grapheme_LV},
-  {0xcc45, 0xcc5f, HB_Grapheme_LVT},
-  {0xcc60, 0xcc60, HB_Grapheme_LV},
-  {0xcc61, 0xcc7b, HB_Grapheme_LVT},
-  {0xcc7c, 0xcc7c, HB_Grapheme_LV},
-  {0xcc7d, 0xcc97, HB_Grapheme_LVT},
-  {0xcc98, 0xcc98, HB_Grapheme_LV},
-  {0xcc99, 0xccb3, HB_Grapheme_LVT},
-  {0xccb4, 0xccb4, HB_Grapheme_LV},
-  {0xccb5, 0xcccf, HB_Grapheme_LVT},
-  {0xccd0, 0xccd0, HB_Grapheme_LV},
-  {0xccd1, 0xcceb, HB_Grapheme_LVT},
-  {0xccec, 0xccec, HB_Grapheme_LV},
-  {0xcced, 0xcd07, HB_Grapheme_LVT},
-  {0xcd08, 0xcd08, HB_Grapheme_LV},
-  {0xcd09, 0xcd23, HB_Grapheme_LVT},
-  {0xcd24, 0xcd24, HB_Grapheme_LV},
-  {0xcd25, 0xcd3f, HB_Grapheme_LVT},
-  {0xcd40, 0xcd40, HB_Grapheme_LV},
-  {0xcd41, 0xcd5b, HB_Grapheme_LVT},
-  {0xcd5c, 0xcd5c, HB_Grapheme_LV},
-  {0xcd5d, 0xcd77, HB_Grapheme_LVT},
-  {0xcd78, 0xcd78, HB_Grapheme_LV},
-  {0xcd79, 0xcd93, HB_Grapheme_LVT},
-  {0xcd94, 0xcd94, HB_Grapheme_LV},
-  {0xcd95, 0xcdaf, HB_Grapheme_LVT},
-  {0xcdb0, 0xcdb0, HB_Grapheme_LV},
-  {0xcdb1, 0xcdcb, HB_Grapheme_LVT},
-  {0xcdcc, 0xcdcc, HB_Grapheme_LV},
-  {0xcdcd, 0xcde7, HB_Grapheme_LVT},
-  {0xcde8, 0xcde8, HB_Grapheme_LV},
-  {0xcde9, 0xce03, HB_Grapheme_LVT},
-  {0xce04, 0xce04, HB_Grapheme_LV},
-  {0xce05, 0xce1f, HB_Grapheme_LVT},
-  {0xce20, 0xce20, HB_Grapheme_LV},
-  {0xce21, 0xce3b, HB_Grapheme_LVT},
-  {0xce3c, 0xce3c, HB_Grapheme_LV},
-  {0xce3d, 0xce57, HB_Grapheme_LVT},
-  {0xce58, 0xce58, HB_Grapheme_LV},
-  {0xce59, 0xce73, HB_Grapheme_LVT},
-  {0xce74, 0xce74, HB_Grapheme_LV},
-  {0xce75, 0xce8f, HB_Grapheme_LVT},
-  {0xce90, 0xce90, HB_Grapheme_LV},
-  {0xce91, 0xceab, HB_Grapheme_LVT},
-  {0xceac, 0xceac, HB_Grapheme_LV},
-  {0xcead, 0xcec7, HB_Grapheme_LVT},
-  {0xcec8, 0xcec8, HB_Grapheme_LV},
-  {0xcec9, 0xcee3, HB_Grapheme_LVT},
-  {0xcee4, 0xcee4, HB_Grapheme_LV},
-  {0xcee5, 0xceff, HB_Grapheme_LVT},
-  {0xcf00, 0xcf00, HB_Grapheme_LV},
-  {0xcf01, 0xcf1b, HB_Grapheme_LVT},
-  {0xcf1c, 0xcf1c, HB_Grapheme_LV},
-  {0xcf1d, 0xcf37, HB_Grapheme_LVT},
-  {0xcf38, 0xcf38, HB_Grapheme_LV},
-  {0xcf39, 0xcf53, HB_Grapheme_LVT},
-  {0xcf54, 0xcf54, HB_Grapheme_LV},
-  {0xcf55, 0xcf6f, HB_Grapheme_LVT},
-  {0xcf70, 0xcf70, HB_Grapheme_LV},
-  {0xcf71, 0xcf8b, HB_Grapheme_LVT},
-  {0xcf8c, 0xcf8c, HB_Grapheme_LV},
-  {0xcf8d, 0xcfa7, HB_Grapheme_LVT},
-  {0xcfa8, 0xcfa8, HB_Grapheme_LV},
-  {0xcfa9, 0xcfc3, HB_Grapheme_LVT},
-  {0xcfc4, 0xcfc4, HB_Grapheme_LV},
-  {0xcfc5, 0xcfdf, HB_Grapheme_LVT},
-  {0xcfe0, 0xcfe0, HB_Grapheme_LV},
-  {0xcfe1, 0xcffb, HB_Grapheme_LVT},
-  {0xcffc, 0xcffc, HB_Grapheme_LV},
-  {0xcffd, 0xd017, HB_Grapheme_LVT},
-  {0xd018, 0xd018, HB_Grapheme_LV},
-  {0xd019, 0xd033, HB_Grapheme_LVT},
-  {0xd034, 0xd034, HB_Grapheme_LV},
-  {0xd035, 0xd04f, HB_Grapheme_LVT},
-  {0xd050, 0xd050, HB_Grapheme_LV},
-  {0xd051, 0xd06b, HB_Grapheme_LVT},
-  {0xd06c, 0xd06c, HB_Grapheme_LV},
-  {0xd06d, 0xd087, HB_Grapheme_LVT},
-  {0xd088, 0xd088, HB_Grapheme_LV},
-  {0xd089, 0xd0a3, HB_Grapheme_LVT},
-  {0xd0a4, 0xd0a4, HB_Grapheme_LV},
-  {0xd0a5, 0xd0bf, HB_Grapheme_LVT},
-  {0xd0c0, 0xd0c0, HB_Grapheme_LV},
-  {0xd0c1, 0xd0db, HB_Grapheme_LVT},
-  {0xd0dc, 0xd0dc, HB_Grapheme_LV},
-  {0xd0dd, 0xd0f7, HB_Grapheme_LVT},
-  {0xd0f8, 0xd0f8, HB_Grapheme_LV},
-  {0xd0f9, 0xd113, HB_Grapheme_LVT},
-  {0xd114, 0xd114, HB_Grapheme_LV},
-  {0xd115, 0xd12f, HB_Grapheme_LVT},
-  {0xd130, 0xd130, HB_Grapheme_LV},
-  {0xd131, 0xd14b, HB_Grapheme_LVT},
-  {0xd14c, 0xd14c, HB_Grapheme_LV},
-  {0xd14d, 0xd167, HB_Grapheme_LVT},
-  {0xd168, 0xd168, HB_Grapheme_LV},
-  {0xd169, 0xd183, HB_Grapheme_LVT},
-  {0xd184, 0xd184, HB_Grapheme_LV},
-  {0xd185, 0xd19f, HB_Grapheme_LVT},
-  {0xd1a0, 0xd1a0, HB_Grapheme_LV},
-  {0xd1a1, 0xd1bb, HB_Grapheme_LVT},
-  {0xd1bc, 0xd1bc, HB_Grapheme_LV},
-  {0xd1bd, 0xd1d7, HB_Grapheme_LVT},
-  {0xd1d8, 0xd1d8, HB_Grapheme_LV},
-  {0xd1d9, 0xd1f3, HB_Grapheme_LVT},
-  {0xd1f4, 0xd1f4, HB_Grapheme_LV},
-  {0xd1f5, 0xd20f, HB_Grapheme_LVT},
-  {0xd210, 0xd210, HB_Grapheme_LV},
-  {0xd211, 0xd22b, HB_Grapheme_LVT},
-  {0xd22c, 0xd22c, HB_Grapheme_LV},
-  {0xd22d, 0xd247, HB_Grapheme_LVT},
-  {0xd248, 0xd248, HB_Grapheme_LV},
-  {0xd249, 0xd263, HB_Grapheme_LVT},
-  {0xd264, 0xd264, HB_Grapheme_LV},
-  {0xd265, 0xd27f, HB_Grapheme_LVT},
-  {0xd280, 0xd280, HB_Grapheme_LV},
-  {0xd281, 0xd29b, HB_Grapheme_LVT},
-  {0xd29c, 0xd29c, HB_Grapheme_LV},
-  {0xd29d, 0xd2b7, HB_Grapheme_LVT},
-  {0xd2b8, 0xd2b8, HB_Grapheme_LV},
-  {0xd2b9, 0xd2d3, HB_Grapheme_LVT},
-  {0xd2d4, 0xd2d4, HB_Grapheme_LV},
-  {0xd2d5, 0xd2ef, HB_Grapheme_LVT},
-  {0xd2f0, 0xd2f0, HB_Grapheme_LV},
-  {0xd2f1, 0xd30b, HB_Grapheme_LVT},
-  {0xd30c, 0xd30c, HB_Grapheme_LV},
-  {0xd30d, 0xd327, HB_Grapheme_LVT},
-  {0xd328, 0xd328, HB_Grapheme_LV},
-  {0xd329, 0xd343, HB_Grapheme_LVT},
-  {0xd344, 0xd344, HB_Grapheme_LV},
-  {0xd345, 0xd35f, HB_Grapheme_LVT},
-  {0xd360, 0xd360, HB_Grapheme_LV},
-  {0xd361, 0xd37b, HB_Grapheme_LVT},
-  {0xd37c, 0xd37c, HB_Grapheme_LV},
-  {0xd37d, 0xd397, HB_Grapheme_LVT},
-  {0xd398, 0xd398, HB_Grapheme_LV},
-  {0xd399, 0xd3b3, HB_Grapheme_LVT},
-  {0xd3b4, 0xd3b4, HB_Grapheme_LV},
-  {0xd3b5, 0xd3cf, HB_Grapheme_LVT},
-  {0xd3d0, 0xd3d0, HB_Grapheme_LV},
-  {0xd3d1, 0xd3eb, HB_Grapheme_LVT},
-  {0xd3ec, 0xd3ec, HB_Grapheme_LV},
-  {0xd3ed, 0xd407, HB_Grapheme_LVT},
-  {0xd408, 0xd408, HB_Grapheme_LV},
-  {0xd409, 0xd423, HB_Grapheme_LVT},
-  {0xd424, 0xd424, HB_Grapheme_LV},
-  {0xd425, 0xd43f, HB_Grapheme_LVT},
-  {0xd440, 0xd440, HB_Grapheme_LV},
-  {0xd441, 0xd45b, HB_Grapheme_LVT},
-  {0xd45c, 0xd45c, HB_Grapheme_LV},
-  {0xd45d, 0xd477, HB_Grapheme_LVT},
-  {0xd478, 0xd478, HB_Grapheme_LV},
-  {0xd479, 0xd493, HB_Grapheme_LVT},
-  {0xd494, 0xd494, HB_Grapheme_LV},
-  {0xd495, 0xd4af, HB_Grapheme_LVT},
-  {0xd4b0, 0xd4b0, HB_Grapheme_LV},
-  {0xd4b1, 0xd4cb, HB_Grapheme_LVT},
-  {0xd4cc, 0xd4cc, HB_Grapheme_LV},
-  {0xd4cd, 0xd4e7, HB_Grapheme_LVT},
-  {0xd4e8, 0xd4e8, HB_Grapheme_LV},
-  {0xd4e9, 0xd503, HB_Grapheme_LVT},
-  {0xd504, 0xd504, HB_Grapheme_LV},
-  {0xd505, 0xd51f, HB_Grapheme_LVT},
-  {0xd520, 0xd520, HB_Grapheme_LV},
-  {0xd521, 0xd53b, HB_Grapheme_LVT},
-  {0xd53c, 0xd53c, HB_Grapheme_LV},
-  {0xd53d, 0xd557, HB_Grapheme_LVT},
-  {0xd558, 0xd558, HB_Grapheme_LV},
-  {0xd559, 0xd573, HB_Grapheme_LVT},
-  {0xd574, 0xd574, HB_Grapheme_LV},
-  {0xd575, 0xd58f, HB_Grapheme_LVT},
-  {0xd590, 0xd590, HB_Grapheme_LV},
-  {0xd591, 0xd5ab, HB_Grapheme_LVT},
-  {0xd5ac, 0xd5ac, HB_Grapheme_LV},
-  {0xd5ad, 0xd5c7, HB_Grapheme_LVT},
-  {0xd5c8, 0xd5c8, HB_Grapheme_LV},
-  {0xd5c9, 0xd5e3, HB_Grapheme_LVT},
-  {0xd5e4, 0xd5e4, HB_Grapheme_LV},
-  {0xd5e5, 0xd5ff, HB_Grapheme_LVT},
-  {0xd600, 0xd600, HB_Grapheme_LV},
-  {0xd601, 0xd61b, HB_Grapheme_LVT},
-  {0xd61c, 0xd61c, HB_Grapheme_LV},
-  {0xd61d, 0xd637, HB_Grapheme_LVT},
-  {0xd638, 0xd638, HB_Grapheme_LV},
-  {0xd639, 0xd653, HB_Grapheme_LVT},
-  {0xd654, 0xd654, HB_Grapheme_LV},
-  {0xd655, 0xd66f, HB_Grapheme_LVT},
-  {0xd670, 0xd670, HB_Grapheme_LV},
-  {0xd671, 0xd68b, HB_Grapheme_LVT},
-  {0xd68c, 0xd68c, HB_Grapheme_LV},
-  {0xd68d, 0xd6a7, HB_Grapheme_LVT},
-  {0xd6a8, 0xd6a8, HB_Grapheme_LV},
-  {0xd6a9, 0xd6c3, HB_Grapheme_LVT},
-  {0xd6c4, 0xd6c4, HB_Grapheme_LV},
-  {0xd6c5, 0xd6df, HB_Grapheme_LVT},
-  {0xd6e0, 0xd6e0, HB_Grapheme_LV},
-  {0xd6e1, 0xd6fb, HB_Grapheme_LVT},
-  {0xd6fc, 0xd6fc, HB_Grapheme_LV},
-  {0xd6fd, 0xd717, HB_Grapheme_LVT},
-  {0xd718, 0xd718, HB_Grapheme_LV},
-  {0xd719, 0xd733, HB_Grapheme_LVT},
-  {0xd734, 0xd734, HB_Grapheme_LV},
-  {0xd735, 0xd74f, HB_Grapheme_LVT},
-  {0xd750, 0xd750, HB_Grapheme_LV},
-  {0xd751, 0xd76b, HB_Grapheme_LVT},
-  {0xd76c, 0xd76c, HB_Grapheme_LV},
-  {0xd76d, 0xd787, HB_Grapheme_LVT},
-  {0xd788, 0xd788, HB_Grapheme_LV},
-  {0xd789, 0xd7a3, HB_Grapheme_LVT},
-  {0xfb1e, 0xfb1e, HB_Grapheme_Extend},
-  {0xfe00, 0xfe0f, HB_Grapheme_Extend},
-  {0xfe20, 0xfe26, HB_Grapheme_Extend},
-  {0xfeff, 0xfeff, HB_Grapheme_Control},
-  {0xff9e, 0xff9f, HB_Grapheme_Extend},
-  {0xfff9, 0xfffb, HB_Grapheme_Control},
-  {0x101fd, 0x101fd, HB_Grapheme_Extend},
-  {0x10a01, 0x10a03, HB_Grapheme_Extend},
-  {0x10a05, 0x10a06, HB_Grapheme_Extend},
-  {0x10a0c, 0x10a0f, HB_Grapheme_Extend},
-  {0x10a38, 0x10a3a, HB_Grapheme_Extend},
-  {0x10a3f, 0x10a3f, HB_Grapheme_Extend},
-  {0x1d165, 0x1d165, HB_Grapheme_Extend},
-  {0x1d166, 0x1d166, HB_Grapheme_Other},
-  {0x1d167, 0x1d169, HB_Grapheme_Extend},
-  {0x1d16d, 0x1d16d, HB_Grapheme_Other},
-  {0x1d16e, 0x1d172, HB_Grapheme_Extend},
-  {0x1d173, 0x1d17a, HB_Grapheme_Control},
-  {0x1d17b, 0x1d182, HB_Grapheme_Extend},
-  {0x1d185, 0x1d18b, HB_Grapheme_Extend},
-  {0x1d1aa, 0x1d1ad, HB_Grapheme_Extend},
-  {0x1d242, 0x1d244, HB_Grapheme_Extend},
-  {0xe0001, 0xe0001, HB_Grapheme_Control},
-  {0xe0020, 0xe007f, HB_Grapheme_Control},
-  {0xe0100, 0xe01ef, HB_Grapheme_Extend},
-};
-
-static const unsigned grapheme_break_properties_count = 1093;
-
-#endif  // GRAPHEME_BREAK_PROPERTY_H_
diff --git a/third_party/harfbuzz/contrib/tables/mirroring-parse.py b/third_party/harfbuzz/contrib/tables/mirroring-parse.py
deleted file mode 100644
index 5724e19..0000000
--- a/third_party/harfbuzz/contrib/tables/mirroring-parse.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import sys
-
-# http://www.unicode.org/Public/UNIDATA/auxiliary/BidiMirroring.txt
-
-# This parses a file in the format of the above file and outputs a table
-# suitable for bsearch(3). This table maps Unicode code points to their
-# 'mirror'. (Mirroring is used when rendering RTL characters, see the Unicode
-# standard). By convention, this mapping should be commutative, but this code
-# doesn't enforce or check this.
-
-def main(infile, outfile):
-  pairs = []
-  for line in infile:
-    line = line[:-1]
-    if len(line) == 0 or line[0] == '#':
-      continue
-    if '#' in line:
-      (data, _) = line.split('#', 1)
-    else:
-      data = line
-    if ';' not in data:
-      continue
-    (a, b) = data.split(';', 1)
-    a = int(a, 16)
-    b = int(b, 16)
-
-    pairs.append((a, b))
-
-  pairs.sort()
-
-  print >>outfile, '// Generated from Unicode Bidi Mirroring tables\n'
-  print >>outfile, '#ifndef MIRRORING_PROPERTY_H_'
-  print >>outfile, '#define MIRRORING_PROPERTY_H_\n'
-  print >>outfile, '#include <stdint.h>'
-  print >>outfile, 'struct mirroring_property {'
-  print >>outfile, '  uint32_t a;'
-  print >>outfile, '  uint32_t b;'
-  print >>outfile, '};\n'
-  print >>outfile, 'static const struct mirroring_property mirroring_properties[] = {'
-  for pair in pairs:
-    print >>outfile, '  {0x%x, 0x%x},' % pair
-  print >>outfile, '};\n'
-  print >>outfile, 'static const unsigned mirroring_properties_count = %d;\n' % len(pairs)
-  print >>outfile, '#endif  // MIRRORING_PROPERTY_H_'
-
-if __name__ == '__main__':
-  if len(sys.argv) != 3:
-    print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
-  else:
-    main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))
diff --git a/third_party/harfbuzz/contrib/tables/mirroring-properties.h b/third_party/harfbuzz/contrib/tables/mirroring-properties.h
deleted file mode 100644
index f9be2f6..0000000
--- a/third_party/harfbuzz/contrib/tables/mirroring-properties.h
+++ /dev/null
@@ -1,379 +0,0 @@
-// Generated from Unicode Bidi Mirroring tables
-
-#ifndef MIRRORING_PROPERTY_H_
-#define MIRRORING_PROPERTY_H_
-
-#include <stdint.h>
-struct mirroring_property {
-  uint32_t a;
-  uint32_t b;
-};
-
-static const struct mirroring_property mirroring_properties[] = {
-  {0x28, 0x29},
-  {0x29, 0x28},
-  {0x3c, 0x3e},
-  {0x3e, 0x3c},
-  {0x5b, 0x5d},
-  {0x5d, 0x5b},
-  {0x7b, 0x7d},
-  {0x7d, 0x7b},
-  {0xab, 0xbb},
-  {0xbb, 0xab},
-  {0xf3a, 0xf3b},
-  {0xf3b, 0xf3a},
-  {0xf3c, 0xf3d},
-  {0xf3d, 0xf3c},
-  {0x169b, 0x169c},
-  {0x169c, 0x169b},
-  {0x2039, 0x203a},
-  {0x203a, 0x2039},
-  {0x2045, 0x2046},
-  {0x2046, 0x2045},
-  {0x207d, 0x207e},
-  {0x207e, 0x207d},
-  {0x208d, 0x208e},
-  {0x208e, 0x208d},
-  {0x2208, 0x220b},
-  {0x2209, 0x220c},
-  {0x220a, 0x220d},
-  {0x220b, 0x2208},
-  {0x220c, 0x2209},
-  {0x220d, 0x220a},
-  {0x2215, 0x29f5},
-  {0x223c, 0x223d},
-  {0x223d, 0x223c},
-  {0x2243, 0x22cd},
-  {0x2252, 0x2253},
-  {0x2253, 0x2252},
-  {0x2254, 0x2255},
-  {0x2255, 0x2254},
-  {0x2264, 0x2265},
-  {0x2265, 0x2264},
-  {0x2266, 0x2267},
-  {0x2267, 0x2266},
-  {0x2268, 0x2269},
-  {0x2269, 0x2268},
-  {0x226a, 0x226b},
-  {0x226b, 0x226a},
-  {0x226e, 0x226f},
-  {0x226f, 0x226e},
-  {0x2270, 0x2271},
-  {0x2271, 0x2270},
-  {0x2272, 0x2273},
-  {0x2273, 0x2272},
-  {0x2274, 0x2275},
-  {0x2275, 0x2274},
-  {0x2276, 0x2277},
-  {0x2277, 0x2276},
-  {0x2278, 0x2279},
-  {0x2279, 0x2278},
-  {0x227a, 0x227b},
-  {0x227b, 0x227a},
-  {0x227c, 0x227d},
-  {0x227d, 0x227c},
-  {0x227e, 0x227f},
-  {0x227f, 0x227e},
-  {0x2280, 0x2281},
-  {0x2281, 0x2280},
-  {0x2282, 0x2283},
-  {0x2283, 0x2282},
-  {0x2284, 0x2285},
-  {0x2285, 0x2284},
-  {0x2286, 0x2287},
-  {0x2287, 0x2286},
-  {0x2288, 0x2289},
-  {0x2289, 0x2288},
-  {0x228a, 0x228b},
-  {0x228b, 0x228a},
-  {0x228f, 0x2290},
-  {0x2290, 0x228f},
-  {0x2291, 0x2292},
-  {0x2292, 0x2291},
-  {0x2298, 0x29b8},
-  {0x22a2, 0x22a3},
-  {0x22a3, 0x22a2},
-  {0x22a6, 0x2ade},
-  {0x22a8, 0x2ae4},
-  {0x22a9, 0x2ae3},
-  {0x22ab, 0x2ae5},
-  {0x22b0, 0x22b1},
-  {0x22b1, 0x22b0},
-  {0x22b2, 0x22b3},
-  {0x22b3, 0x22b2},
-  {0x22b4, 0x22b5},
-  {0x22b5, 0x22b4},
-  {0x22b6, 0x22b7},
-  {0x22b7, 0x22b6},
-  {0x22c9, 0x22ca},
-  {0x22ca, 0x22c9},
-  {0x22cb, 0x22cc},
-  {0x22cc, 0x22cb},
-  {0x22cd, 0x2243},
-  {0x22d0, 0x22d1},
-  {0x22d1, 0x22d0},
-  {0x22d6, 0x22d7},
-  {0x22d7, 0x22d6},
-  {0x22d8, 0x22d9},
-  {0x22d9, 0x22d8},
-  {0x22da, 0x22db},
-  {0x22db, 0x22da},
-  {0x22dc, 0x22dd},
-  {0x22dd, 0x22dc},
-  {0x22de, 0x22df},
-  {0x22df, 0x22de},
-  {0x22e0, 0x22e1},
-  {0x22e1, 0x22e0},
-  {0x22e2, 0x22e3},
-  {0x22e3, 0x22e2},
-  {0x22e4, 0x22e5},
-  {0x22e5, 0x22e4},
-  {0x22e6, 0x22e7},
-  {0x22e7, 0x22e6},
-  {0x22e8, 0x22e9},
-  {0x22e9, 0x22e8},
-  {0x22ea, 0x22eb},
-  {0x22eb, 0x22ea},
-  {0x22ec, 0x22ed},
-  {0x22ed, 0x22ec},
-  {0x22f0, 0x22f1},
-  {0x22f1, 0x22f0},
-  {0x22f2, 0x22fa},
-  {0x22f3, 0x22fb},
-  {0x22f4, 0x22fc},
-  {0x22f6, 0x22fd},
-  {0x22f7, 0x22fe},
-  {0x22fa, 0x22f2},
-  {0x22fb, 0x22f3},
-  {0x22fc, 0x22f4},
-  {0x22fd, 0x22f6},
-  {0x22fe, 0x22f7},
-  {0x2308, 0x2309},
-  {0x2309, 0x2308},
-  {0x230a, 0x230b},
-  {0x230b, 0x230a},
-  {0x2329, 0x232a},
-  {0x232a, 0x2329},
-  {0x2768, 0x2769},
-  {0x2769, 0x2768},
-  {0x276a, 0x276b},
-  {0x276b, 0x276a},
-  {0x276c, 0x276d},
-  {0x276d, 0x276c},
-  {0x276e, 0x276f},
-  {0x276f, 0x276e},
-  {0x2770, 0x2771},
-  {0x2771, 0x2770},
-  {0x2772, 0x2773},
-  {0x2773, 0x2772},
-  {0x2774, 0x2775},
-  {0x2775, 0x2774},
-  {0x27c3, 0x27c4},
-  {0x27c4, 0x27c3},
-  {0x27c5, 0x27c6},
-  {0x27c6, 0x27c5},
-  {0x27c8, 0x27c9},
-  {0x27c9, 0x27c8},
-  {0x27d5, 0x27d6},
-  {0x27d6, 0x27d5},
-  {0x27dd, 0x27de},
-  {0x27de, 0x27dd},
-  {0x27e2, 0x27e3},
-  {0x27e3, 0x27e2},
-  {0x27e4, 0x27e5},
-  {0x27e5, 0x27e4},
-  {0x27e6, 0x27e7},
-  {0x27e7, 0x27e6},
-  {0x27e8, 0x27e9},
-  {0x27e9, 0x27e8},
-  {0x27ea, 0x27eb},
-  {0x27eb, 0x27ea},
-  {0x27ec, 0x27ed},
-  {0x27ed, 0x27ec},
-  {0x27ee, 0x27ef},
-  {0x27ef, 0x27ee},
-  {0x2983, 0x2984},
-  {0x2984, 0x2983},
-  {0x2985, 0x2986},
-  {0x2986, 0x2985},
-  {0x2987, 0x2988},
-  {0x2988, 0x2987},
-  {0x2989, 0x298a},
-  {0x298a, 0x2989},
-  {0x298b, 0x298c},
-  {0x298c, 0x298b},
-  {0x298d, 0x2990},
-  {0x298e, 0x298f},
-  {0x298f, 0x298e},
-  {0x2990, 0x298d},
-  {0x2991, 0x2992},
-  {0x2992, 0x2991},
-  {0x2993, 0x2994},
-  {0x2994, 0x2993},
-  {0x2995, 0x2996},
-  {0x2996, 0x2995},
-  {0x2997, 0x2998},
-  {0x2998, 0x2997},
-  {0x29b8, 0x2298},
-  {0x29c0, 0x29c1},
-  {0x29c1, 0x29c0},
-  {0x29c4, 0x29c5},
-  {0x29c5, 0x29c4},
-  {0x29cf, 0x29d0},
-  {0x29d0, 0x29cf},
-  {0x29d1, 0x29d2},
-  {0x29d2, 0x29d1},
-  {0x29d4, 0x29d5},
-  {0x29d5, 0x29d4},
-  {0x29d8, 0x29d9},
-  {0x29d9, 0x29d8},
-  {0x29da, 0x29db},
-  {0x29db, 0x29da},
-  {0x29f5, 0x2215},
-  {0x29f8, 0x29f9},
-  {0x29f9, 0x29f8},
-  {0x29fc, 0x29fd},
-  {0x29fd, 0x29fc},
-  {0x2a2b, 0x2a2c},
-  {0x2a2c, 0x2a2b},
-  {0x2a2d, 0x2a2e},
-  {0x2a2e, 0x2a2d},
-  {0x2a34, 0x2a35},
-  {0x2a35, 0x2a34},
-  {0x2a3c, 0x2a3d},
-  {0x2a3d, 0x2a3c},
-  {0x2a64, 0x2a65},
-  {0x2a65, 0x2a64},
-  {0x2a79, 0x2a7a},
-  {0x2a7a, 0x2a79},
-  {0x2a7d, 0x2a7e},
-  {0x2a7e, 0x2a7d},
-  {0x2a7f, 0x2a80},
-  {0x2a80, 0x2a7f},
-  {0x2a81, 0x2a82},
-  {0x2a82, 0x2a81},
-  {0x2a83, 0x2a84},
-  {0x2a84, 0x2a83},
-  {0x2a8b, 0x2a8c},
-  {0x2a8c, 0x2a8b},
-  {0x2a91, 0x2a92},
-  {0x2a92, 0x2a91},
-  {0x2a93, 0x2a94},
-  {0x2a94, 0x2a93},
-  {0x2a95, 0x2a96},
-  {0x2a96, 0x2a95},
-  {0x2a97, 0x2a98},
-  {0x2a98, 0x2a97},
-  {0x2a99, 0x2a9a},
-  {0x2a9a, 0x2a99},
-  {0x2a9b, 0x2a9c},
-  {0x2a9c, 0x2a9b},
-  {0x2aa1, 0x2aa2},
-  {0x2aa2, 0x2aa1},
-  {0x2aa6, 0x2aa7},
-  {0x2aa7, 0x2aa6},
-  {0x2aa8, 0x2aa9},
-  {0x2aa9, 0x2aa8},
-  {0x2aaa, 0x2aab},
-  {0x2aab, 0x2aaa},
-  {0x2aac, 0x2aad},
-  {0x2aad, 0x2aac},
-  {0x2aaf, 0x2ab0},
-  {0x2ab0, 0x2aaf},
-  {0x2ab3, 0x2ab4},
-  {0x2ab4, 0x2ab3},
-  {0x2abb, 0x2abc},
-  {0x2abc, 0x2abb},
-  {0x2abd, 0x2abe},
-  {0x2abe, 0x2abd},
-  {0x2abf, 0x2ac0},
-  {0x2ac0, 0x2abf},
-  {0x2ac1, 0x2ac2},
-  {0x2ac2, 0x2ac1},
-  {0x2ac3, 0x2ac4},
-  {0x2ac4, 0x2ac3},
-  {0x2ac5, 0x2ac6},
-  {0x2ac6, 0x2ac5},
-  {0x2acd, 0x2ace},
-  {0x2ace, 0x2acd},
-  {0x2acf, 0x2ad0},
-  {0x2ad0, 0x2acf},
-  {0x2ad1, 0x2ad2},
-  {0x2ad2, 0x2ad1},
-  {0x2ad3, 0x2ad4},
-  {0x2ad4, 0x2ad3},
-  {0x2ad5, 0x2ad6},
-  {0x2ad6, 0x2ad5},
-  {0x2ade, 0x22a6},
-  {0x2ae3, 0x22a9},
-  {0x2ae4, 0x22a8},
-  {0x2ae5, 0x22ab},
-  {0x2aec, 0x2aed},
-  {0x2aed, 0x2aec},
-  {0x2af7, 0x2af8},
-  {0x2af8, 0x2af7},
-  {0x2af9, 0x2afa},
-  {0x2afa, 0x2af9},
-  {0x2e02, 0x2e03},
-  {0x2e03, 0x2e02},
-  {0x2e04, 0x2e05},
-  {0x2e05, 0x2e04},
-  {0x2e09, 0x2e0a},
-  {0x2e0a, 0x2e09},
-  {0x2e0c, 0x2e0d},
-  {0x2e0d, 0x2e0c},
-  {0x2e1c, 0x2e1d},
-  {0x2e1d, 0x2e1c},
-  {0x2e20, 0x2e21},
-  {0x2e21, 0x2e20},
-  {0x2e22, 0x2e23},
-  {0x2e23, 0x2e22},
-  {0x2e24, 0x2e25},
-  {0x2e25, 0x2e24},
-  {0x2e26, 0x2e27},
-  {0x2e27, 0x2e26},
-  {0x2e28, 0x2e29},
-  {0x2e29, 0x2e28},
-  {0x3008, 0x3009},
-  {0x3009, 0x3008},
-  {0x300a, 0x300b},
-  {0x300b, 0x300a},
-  {0x300c, 0x300d},
-  {0x300d, 0x300c},
-  {0x300e, 0x300f},
-  {0x300f, 0x300e},
-  {0x3010, 0x3011},
-  {0x3011, 0x3010},
-  {0x3014, 0x3015},
-  {0x3015, 0x3014},
-  {0x3016, 0x3017},
-  {0x3017, 0x3016},
-  {0x3018, 0x3019},
-  {0x3019, 0x3018},
-  {0x301a, 0x301b},
-  {0x301b, 0x301a},
-  {0xfe59, 0xfe5a},
-  {0xfe5a, 0xfe59},
-  {0xfe5b, 0xfe5c},
-  {0xfe5c, 0xfe5b},
-  {0xfe5d, 0xfe5e},
-  {0xfe5e, 0xfe5d},
-  {0xfe64, 0xfe65},
-  {0xfe65, 0xfe64},
-  {0xff08, 0xff09},
-  {0xff09, 0xff08},
-  {0xff1c, 0xff1e},
-  {0xff1e, 0xff1c},
-  {0xff3b, 0xff3d},
-  {0xff3d, 0xff3b},
-  {0xff5b, 0xff5d},
-  {0xff5d, 0xff5b},
-  {0xff5f, 0xff60},
-  {0xff60, 0xff5f},
-  {0xff62, 0xff63},
-  {0xff63, 0xff62},
-};
-
-static const unsigned mirroring_properties_count = 362;
-
-#endif  // MIRRORING_PROPERTY_H_
diff --git a/third_party/harfbuzz/contrib/tables/script-properties.h b/third_party/harfbuzz/contrib/tables/script-properties.h
deleted file mode 100644
index a6ff50b..0000000
--- a/third_party/harfbuzz/contrib/tables/script-properties.h
+++ /dev/null
@@ -1,297 +0,0 @@
-// Generated from Unicode script tables
-
-#ifndef SCRIPT_PROPERTIES_H_
-#define SCRIPT_PROPERTIES_H_
-
-#include <stdint.h>
-#include "harfbuzz-shaper.h"
-
-struct script_property {
-  uint32_t range_start;
-  uint32_t range_end;
-  HB_Script script;
-};
-
-static const struct script_property script_properties[] = {
-  {0x300, 0x36f, HB_Script_Inherited},
-  {0x370, 0x373, HB_Script_Greek},
-  {0x375, 0x377, HB_Script_Greek},
-  {0x37a, 0x37d, HB_Script_Greek},
-  {0x384, 0x384, HB_Script_Greek},
-  {0x386, 0x386, HB_Script_Greek},
-  {0x388, 0x38a, HB_Script_Greek},
-  {0x38c, 0x38c, HB_Script_Greek},
-  {0x38e, 0x3a1, HB_Script_Greek},
-  {0x3a3, 0x3e1, HB_Script_Greek},
-  {0x3f0, 0x3ff, HB_Script_Greek},
-  {0x400, 0x523, HB_Script_Cyrillic},
-  {0x531, 0x556, HB_Script_Armenian},
-  {0x559, 0x55f, HB_Script_Armenian},
-  {0x561, 0x587, HB_Script_Armenian},
-  {0x58a, 0x58a, HB_Script_Armenian},
-  {0x591, 0x5c7, HB_Script_Hebrew},
-  {0x5d0, 0x5ea, HB_Script_Hebrew},
-  {0x5f0, 0x5f4, HB_Script_Hebrew},
-  {0x606, 0x60b, HB_Script_Arabic},
-  {0x60d, 0x61a, HB_Script_Arabic},
-  {0x61e, 0x61e, HB_Script_Arabic},
-  {0x621, 0x63f, HB_Script_Arabic},
-  {0x641, 0x64a, HB_Script_Arabic},
-  {0x64b, 0x655, HB_Script_Inherited},
-  {0x656, 0x65e, HB_Script_Arabic},
-  {0x66a, 0x66f, HB_Script_Arabic},
-  {0x670, 0x670, HB_Script_Inherited},
-  {0x671, 0x6dc, HB_Script_Arabic},
-  {0x6de, 0x6ff, HB_Script_Arabic},
-  {0x700, 0x70d, HB_Script_Syriac},
-  {0x70f, 0x74a, HB_Script_Syriac},
-  {0x74d, 0x74f, HB_Script_Syriac},
-  {0x750, 0x77f, HB_Script_Arabic},
-  {0x780, 0x7b1, HB_Script_Thaana},
-  {0x901, 0x939, HB_Script_Devanagari},
-  {0x93c, 0x94d, HB_Script_Devanagari},
-  {0x950, 0x950, HB_Script_Devanagari},
-  {0x951, 0x952, HB_Script_Inherited},
-  {0x953, 0x954, HB_Script_Devanagari},
-  {0x958, 0x963, HB_Script_Devanagari},
-  {0x966, 0x96f, HB_Script_Devanagari},
-  {0x971, 0x972, HB_Script_Devanagari},
-  {0x97b, 0x97f, HB_Script_Devanagari},
-  {0x981, 0x983, HB_Script_Bengali},
-  {0x985, 0x98c, HB_Script_Bengali},
-  {0x98f, 0x990, HB_Script_Bengali},
-  {0x993, 0x9a8, HB_Script_Bengali},
-  {0x9aa, 0x9b0, HB_Script_Bengali},
-  {0x9b2, 0x9b2, HB_Script_Bengali},
-  {0x9b6, 0x9b9, HB_Script_Bengali},
-  {0x9bc, 0x9c4, HB_Script_Bengali},
-  {0x9c7, 0x9c8, HB_Script_Bengali},
-  {0x9cb, 0x9ce, HB_Script_Bengali},
-  {0x9d7, 0x9d7, HB_Script_Bengali},
-  {0x9dc, 0x9dd, HB_Script_Bengali},
-  {0x9df, 0x9e3, HB_Script_Bengali},
-  {0x9e6, 0x9fa, HB_Script_Bengali},
-  {0xa01, 0xa03, HB_Script_Gurmukhi},
-  {0xa05, 0xa0a, HB_Script_Gurmukhi},
-  {0xa0f, 0xa10, HB_Script_Gurmukhi},
-  {0xa13, 0xa28, HB_Script_Gurmukhi},
-  {0xa2a, 0xa30, HB_Script_Gurmukhi},
-  {0xa32, 0xa33, HB_Script_Gurmukhi},
-  {0xa35, 0xa36, HB_Script_Gurmukhi},
-  {0xa38, 0xa39, HB_Script_Gurmukhi},
-  {0xa3c, 0xa3c, HB_Script_Gurmukhi},
-  {0xa3e, 0xa42, HB_Script_Gurmukhi},
-  {0xa47, 0xa48, HB_Script_Gurmukhi},
-  {0xa4b, 0xa4d, HB_Script_Gurmukhi},
-  {0xa51, 0xa51, HB_Script_Gurmukhi},
-  {0xa59, 0xa5c, HB_Script_Gurmukhi},
-  {0xa5e, 0xa5e, HB_Script_Gurmukhi},
-  {0xa66, 0xa75, HB_Script_Gurmukhi},
-  {0xa81, 0xa83, HB_Script_Gujarati},
-  {0xa85, 0xa8d, HB_Script_Gujarati},
-  {0xa8f, 0xa91, HB_Script_Gujarati},
-  {0xa93, 0xaa8, HB_Script_Gujarati},
-  {0xaaa, 0xab0, HB_Script_Gujarati},
-  {0xab2, 0xab3, HB_Script_Gujarati},
-  {0xab5, 0xab9, HB_Script_Gujarati},
-  {0xabc, 0xac5, HB_Script_Gujarati},
-  {0xac7, 0xac9, HB_Script_Gujarati},
-  {0xacb, 0xacd, HB_Script_Gujarati},
-  {0xad0, 0xad0, HB_Script_Gujarati},
-  {0xae0, 0xae3, HB_Script_Gujarati},
-  {0xae6, 0xaef, HB_Script_Gujarati},
-  {0xaf1, 0xaf1, HB_Script_Gujarati},
-  {0xb01, 0xb03, HB_Script_Oriya},
-  {0xb05, 0xb0c, HB_Script_Oriya},
-  {0xb0f, 0xb10, HB_Script_Oriya},
-  {0xb13, 0xb28, HB_Script_Oriya},
-  {0xb2a, 0xb30, HB_Script_Oriya},
-  {0xb32, 0xb33, HB_Script_Oriya},
-  {0xb35, 0xb39, HB_Script_Oriya},
-  {0xb3c, 0xb44, HB_Script_Oriya},
-  {0xb47, 0xb48, HB_Script_Oriya},
-  {0xb4b, 0xb4d, HB_Script_Oriya},
-  {0xb56, 0xb57, HB_Script_Oriya},
-  {0xb5c, 0xb5d, HB_Script_Oriya},
-  {0xb5f, 0xb63, HB_Script_Oriya},
-  {0xb66, 0xb71, HB_Script_Oriya},
-  {0xb82, 0xb83, HB_Script_Tamil},
-  {0xb85, 0xb8a, HB_Script_Tamil},
-  {0xb8e, 0xb90, HB_Script_Tamil},
-  {0xb92, 0xb95, HB_Script_Tamil},
-  {0xb99, 0xb9a, HB_Script_Tamil},
-  {0xb9c, 0xb9c, HB_Script_Tamil},
-  {0xb9e, 0xb9f, HB_Script_Tamil},
-  {0xba3, 0xba4, HB_Script_Tamil},
-  {0xba8, 0xbaa, HB_Script_Tamil},
-  {0xbae, 0xbb9, HB_Script_Tamil},
-  {0xbbe, 0xbc2, HB_Script_Tamil},
-  {0xbc6, 0xbc8, HB_Script_Tamil},
-  {0xbca, 0xbcd, HB_Script_Tamil},
-  {0xbd0, 0xbd0, HB_Script_Tamil},
-  {0xbd7, 0xbd7, HB_Script_Tamil},
-  {0xbe6, 0xbfa, HB_Script_Tamil},
-  {0xc01, 0xc03, HB_Script_Telugu},
-  {0xc05, 0xc0c, HB_Script_Telugu},
-  {0xc0e, 0xc10, HB_Script_Telugu},
-  {0xc12, 0xc28, HB_Script_Telugu},
-  {0xc2a, 0xc33, HB_Script_Telugu},
-  {0xc35, 0xc39, HB_Script_Telugu},
-  {0xc3d, 0xc44, HB_Script_Telugu},
-  {0xc46, 0xc48, HB_Script_Telugu},
-  {0xc4a, 0xc4d, HB_Script_Telugu},
-  {0xc55, 0xc56, HB_Script_Telugu},
-  {0xc58, 0xc59, HB_Script_Telugu},
-  {0xc60, 0xc63, HB_Script_Telugu},
-  {0xc66, 0xc6f, HB_Script_Telugu},
-  {0xc78, 0xc7f, HB_Script_Telugu},
-  {0xc82, 0xc83, HB_Script_Kannada},
-  {0xc85, 0xc8c, HB_Script_Kannada},
-  {0xc8e, 0xc90, HB_Script_Kannada},
-  {0xc92, 0xca8, HB_Script_Kannada},
-  {0xcaa, 0xcb3, HB_Script_Kannada},
-  {0xcb5, 0xcb9, HB_Script_Kannada},
-  {0xcbc, 0xcc4, HB_Script_Kannada},
-  {0xcc6, 0xcc8, HB_Script_Kannada},
-  {0xcca, 0xccd, HB_Script_Kannada},
-  {0xcd5, 0xcd6, HB_Script_Kannada},
-  {0xcde, 0xcde, HB_Script_Kannada},
-  {0xce0, 0xce3, HB_Script_Kannada},
-  {0xce6, 0xcef, HB_Script_Kannada},
-  {0xd02, 0xd03, HB_Script_Malayalam},
-  {0xd05, 0xd0c, HB_Script_Malayalam},
-  {0xd0e, 0xd10, HB_Script_Malayalam},
-  {0xd12, 0xd28, HB_Script_Malayalam},
-  {0xd2a, 0xd39, HB_Script_Malayalam},
-  {0xd3d, 0xd44, HB_Script_Malayalam},
-  {0xd46, 0xd48, HB_Script_Malayalam},
-  {0xd4a, 0xd4d, HB_Script_Malayalam},
-  {0xd57, 0xd57, HB_Script_Malayalam},
-  {0xd60, 0xd63, HB_Script_Malayalam},
-  {0xd66, 0xd75, HB_Script_Malayalam},
-  {0xd79, 0xd7f, HB_Script_Malayalam},
-  {0xd82, 0xd83, HB_Script_Sinhala},
-  {0xd85, 0xd96, HB_Script_Sinhala},
-  {0xd9a, 0xdb1, HB_Script_Sinhala},
-  {0xdb3, 0xdbb, HB_Script_Sinhala},
-  {0xdbd, 0xdbd, HB_Script_Sinhala},
-  {0xdc0, 0xdc6, HB_Script_Sinhala},
-  {0xdca, 0xdca, HB_Script_Sinhala},
-  {0xdcf, 0xdd4, HB_Script_Sinhala},
-  {0xdd6, 0xdd6, HB_Script_Sinhala},
-  {0xdd8, 0xddf, HB_Script_Sinhala},
-  {0xdf2, 0xdf4, HB_Script_Sinhala},
-  {0xe01, 0xe3a, HB_Script_Thai},
-  {0xe40, 0xe5b, HB_Script_Thai},
-  {0xe81, 0xe82, HB_Script_Lao},
-  {0xe84, 0xe84, HB_Script_Lao},
-  {0xe87, 0xe88, HB_Script_Lao},
-  {0xe8a, 0xe8a, HB_Script_Lao},
-  {0xe8d, 0xe8d, HB_Script_Lao},
-  {0xe94, 0xe97, HB_Script_Lao},
-  {0xe99, 0xe9f, HB_Script_Lao},
-  {0xea1, 0xea3, HB_Script_Lao},
-  {0xea5, 0xea5, HB_Script_Lao},
-  {0xea7, 0xea7, HB_Script_Lao},
-  {0xeaa, 0xeab, HB_Script_Lao},
-  {0xead, 0xeb9, HB_Script_Lao},
-  {0xebb, 0xebd, HB_Script_Lao},
-  {0xec0, 0xec4, HB_Script_Lao},
-  {0xec6, 0xec6, HB_Script_Lao},
-  {0xec8, 0xecd, HB_Script_Lao},
-  {0xed0, 0xed9, HB_Script_Lao},
-  {0xedc, 0xedd, HB_Script_Lao},
-  {0xf00, 0xf47, HB_Script_Tibetan},
-  {0xf49, 0xf6c, HB_Script_Tibetan},
-  {0xf71, 0xf8b, HB_Script_Tibetan},
-  {0xf90, 0xf97, HB_Script_Tibetan},
-  {0xf99, 0xfbc, HB_Script_Tibetan},
-  {0xfbe, 0xfcc, HB_Script_Tibetan},
-  {0xfce, 0xfd4, HB_Script_Tibetan},
-  {0x1000, 0x1099, HB_Script_Myanmar},
-  {0x109e, 0x109f, HB_Script_Myanmar},
-  {0x10a0, 0x10c5, HB_Script_Georgian},
-  {0x10d0, 0x10fa, HB_Script_Georgian},
-  {0x10fc, 0x10fc, HB_Script_Georgian},
-  {0x1100, 0x1159, HB_Script_Hangul},
-  {0x115f, 0x11a2, HB_Script_Hangul},
-  {0x11a8, 0x11f9, HB_Script_Hangul},
-  {0x1680, 0x169c, HB_Script_Ogham},
-  {0x16a0, 0x16ea, HB_Script_Runic},
-  {0x16ee, 0x16f0, HB_Script_Runic},
-  {0x1780, 0x17dd, HB_Script_Khmer},
-  {0x17e0, 0x17e9, HB_Script_Khmer},
-  {0x17f0, 0x17f9, HB_Script_Khmer},
-  {0x19e0, 0x19ff, HB_Script_Khmer},
-  {0x1d26, 0x1d2a, HB_Script_Greek},
-  {0x1d2b, 0x1d2b, HB_Script_Cyrillic},
-  {0x1d5d, 0x1d61, HB_Script_Greek},
-  {0x1d66, 0x1d6a, HB_Script_Greek},
-  {0x1d78, 0x1d78, HB_Script_Cyrillic},
-  {0x1dbf, 0x1dbf, HB_Script_Greek},
-  {0x1dc0, 0x1de6, HB_Script_Inherited},
-  {0x1dfe, 0x1dff, HB_Script_Inherited},
-  {0x1f00, 0x1f15, HB_Script_Greek},
-  {0x1f18, 0x1f1d, HB_Script_Greek},
-  {0x1f20, 0x1f45, HB_Script_Greek},
-  {0x1f48, 0x1f4d, HB_Script_Greek},
-  {0x1f50, 0x1f57, HB_Script_Greek},
-  {0x1f59, 0x1f59, HB_Script_Greek},
-  {0x1f5b, 0x1f5b, HB_Script_Greek},
-  {0x1f5d, 0x1f5d, HB_Script_Greek},
-  {0x1f5f, 0x1f7d, HB_Script_Greek},
-  {0x1f80, 0x1fb4, HB_Script_Greek},
-  {0x1fb6, 0x1fc4, HB_Script_Greek},
-  {0x1fc6, 0x1fd3, HB_Script_Greek},
-  {0x1fd6, 0x1fdb, HB_Script_Greek},
-  {0x1fdd, 0x1fef, HB_Script_Greek},
-  {0x1ff2, 0x1ff4, HB_Script_Greek},
-  {0x1ff6, 0x1ffe, HB_Script_Greek},
-  {0x200c, 0x200d, HB_Script_Inherited},
-  {0x20d0, 0x20f0, HB_Script_Inherited},
-  {0x2126, 0x2126, HB_Script_Greek},
-  {0x2d00, 0x2d25, HB_Script_Georgian},
-  {0x2de0, 0x2dff, HB_Script_Cyrillic},
-  {0x302a, 0x302f, HB_Script_Inherited},
-  {0x3099, 0x309a, HB_Script_Inherited},
-  {0x3131, 0x318e, HB_Script_Hangul},
-  {0x3200, 0x321e, HB_Script_Hangul},
-  {0x3260, 0x327e, HB_Script_Hangul},
-  {0xa640, 0xa65f, HB_Script_Cyrillic},
-  {0xa662, 0xa673, HB_Script_Cyrillic},
-  {0xa67c, 0xa697, HB_Script_Cyrillic},
-  {0xac00, 0xd7a3, HB_Script_Hangul},
-  {0xfb13, 0xfb17, HB_Script_Armenian},
-  {0xfb1d, 0xfb36, HB_Script_Hebrew},
-  {0xfb38, 0xfb3c, HB_Script_Hebrew},
-  {0xfb3e, 0xfb3e, HB_Script_Hebrew},
-  {0xfb40, 0xfb41, HB_Script_Hebrew},
-  {0xfb43, 0xfb44, HB_Script_Hebrew},
-  {0xfb46, 0xfb4f, HB_Script_Hebrew},
-  {0xfb50, 0xfbb1, HB_Script_Arabic},
-  {0xfbd3, 0xfd3d, HB_Script_Arabic},
-  {0xfd50, 0xfd8f, HB_Script_Arabic},
-  {0xfd92, 0xfdc7, HB_Script_Arabic},
-  {0xfdf0, 0xfdfc, HB_Script_Arabic},
-  {0xfe00, 0xfe0f, HB_Script_Inherited},
-  {0xfe20, 0xfe26, HB_Script_Inherited},
-  {0xfe70, 0xfe74, HB_Script_Arabic},
-  {0xfe76, 0xfefc, HB_Script_Arabic},
-  {0xffa0, 0xffbe, HB_Script_Hangul},
-  {0xffc2, 0xffc7, HB_Script_Hangul},
-  {0xffca, 0xffcf, HB_Script_Hangul},
-  {0xffd2, 0xffd7, HB_Script_Hangul},
-  {0xffda, 0xffdc, HB_Script_Hangul},
-  {0x10140, 0x1018a, HB_Script_Greek},
-  {0x101fd, 0x101fd, HB_Script_Inherited},
-  {0x1d167, 0x1d169, HB_Script_Inherited},
-  {0x1d17b, 0x1d182, HB_Script_Inherited},
-  {0x1d185, 0x1d18b, HB_Script_Inherited},
-  {0x1d1aa, 0x1d1ad, HB_Script_Inherited},
-  {0x1d200, 0x1d245, HB_Script_Greek},
-  {0xe0100, 0xe01ef, HB_Script_Inherited},
-};
-
-static const unsigned script_properties_count = 277;
-
-#endif  // SCRIPT_PROPERTIES_H_
diff --git a/third_party/harfbuzz/contrib/tables/scripts-parse.py b/third_party/harfbuzz/contrib/tables/scripts-parse.py
deleted file mode 100644
index 23bac10..0000000
--- a/third_party/harfbuzz/contrib/tables/scripts-parse.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import sys
-from unicode_parse_common import *
-
-# http://www.unicode.org/Public/5.1.0/ucd/Scripts.txt
-
-script_to_harfbuzz = {
-  # This is the list of HB_Script_* at the time of writing
-  'Common': 'HB_Script_Common',
-  'Greek': 'HB_Script_Greek',
-  'Cyrillic': 'HB_Script_Cyrillic',
-  'Armenian': 'HB_Script_Armenian',
-  'Hebrew': 'HB_Script_Hebrew',
-  'Arabic': 'HB_Script_Arabic',
-  'Syriac': 'HB_Script_Syriac',
-  'Thaana': 'HB_Script_Thaana',
-  'Devanagari': 'HB_Script_Devanagari',
-  'Bengali': 'HB_Script_Bengali',
-  'Gurmukhi': 'HB_Script_Gurmukhi',
-  'Gujarati': 'HB_Script_Gujarati',
-  'Oriya': 'HB_Script_Oriya',
-  'Tamil': 'HB_Script_Tamil',
-  'Telugu': 'HB_Script_Telugu',
-  'Kannada': 'HB_Script_Kannada',
-  'Malayalam': 'HB_Script_Malayalam',
-  'Sinhala': 'HB_Script_Sinhala',
-  'Thai': 'HB_Script_Thai',
-  'Lao': 'HB_Script_Lao',
-  'Tibetan': 'HB_Script_Tibetan',
-  'Myanmar': 'HB_Script_Myanmar',
-  'Georgian': 'HB_Script_Georgian',
-  'Hangul': 'HB_Script_Hangul',
-  'Ogham': 'HB_Script_Ogham',
-  'Runic': 'HB_Script_Runic',
-  'Khmer': 'HB_Script_Khmer',
-  'Inherited': 'HB_Script_Inherited',
-}
-
-class ScriptDict(object):
-  def __init__(self, base):
-    self.base = base
-
-  def __getitem__(self, key):
-    r = self.base.get(key, None)
-    if r is None:
-      return 'HB_Script_Common'
-    return r
-
-def main(infile, outfile):
-  ranges = unicode_file_parse(infile,
-                              ScriptDict(script_to_harfbuzz),
-                              'HB_Script_Common')
-  ranges = sort_and_merge(ranges)
-
-  print >>outfile, '// Generated from Unicode script tables\n'
-  print >>outfile, '#ifndef SCRIPT_PROPERTIES_H_'
-  print >>outfile, '#define SCRIPT_PROPERTIES_H_\n'
-  print >>outfile, '#include <stdint.h>'
-  print >>outfile, '#include "harfbuzz-shaper.h"\n'
-  print >>outfile, 'struct script_property {'
-  print >>outfile, '  uint32_t range_start;'
-  print >>outfile, '  uint32_t range_end;'
-  print >>outfile, '  HB_Script script;'
-  print >>outfile, '};\n'
-  print >>outfile, 'static const struct script_property script_properties[] = {'
-  for (start, end, value) in ranges:
-    print >>outfile, '  {0x%x, 0x%x, %s},' % (start, end, value)
-  print >>outfile, '};\n'
-  print >>outfile, 'static const unsigned script_properties_count = %d;\n' % len(ranges)
-  print >>outfile, '#endif  // SCRIPT_PROPERTIES_H_'
-
-if __name__ == '__main__':
-  if len(sys.argv) != 3:
-    print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
-  else:
-    main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))
diff --git a/third_party/harfbuzz/contrib/tables/unicode_parse_common.py b/third_party/harfbuzz/contrib/tables/unicode_parse_common.py
deleted file mode 100644
index ac26eca..0000000
--- a/third_party/harfbuzz/contrib/tables/unicode_parse_common.py
+++ /dev/null
@@ -1,70 +0,0 @@
-def lines_get(f):
-  '''Parse a file like object, removing comments and returning a list of
-     lines.'''
-  def cut_comment(line):
-    first_hash = line.find('#')
-    if first_hash == -1:
-      return line
-    return line[:first_hash]
-
-  return [x for x in [cut_comment(x[:-1]) for x in f.readlines()] if len(x)]
-
-def line_split(line):
-  '''Split a line based on a semicolon separator.'''
-  def normalise(word):
-    return word.lstrip().rstrip()
-  return [normalise(x) for x in line.split(';')]
-
-def codepoints_parse(token):
-  '''Parse a Unicode style code-point range. Return either a single value or a
-     tuple of (start, end) for a range of code-points.'''
-  def fromHex(token):
-    return int(token, 16)
-  parts = token.split('..')
-  if len(parts) == 2:
-    return (fromHex(parts[0]), fromHex(parts[1]))
-  elif len(parts) == 1:
-    return fromHex(parts[0])
-  else:
-    raise ValueError(token)
-
-def unicode_file_parse(input, map, default_value = None):
-  '''Parse a file like object, @input where the first column is a code-point
-     range and the second column is mapped via the given dict, @map.'''
-  ranges = []
-  tokens = [line_split(x) for x in lines_get(input)]
-  for line in tokens:
-    if len(line) == 2:
-      codepoints = codepoints_parse(line[0])
-      value = map[line[1]]
-      if value == default_value:
-        continue
-
-      if type(codepoints) == int:
-        codepoints = (codepoints, codepoints)
-
-      ranges.append((codepoints[0], codepoints[1], value))
-    else:
-      raise ValueError(line)
-
-  return ranges
-
-def sort_and_merge(ranges):
-  '''Given a list of (start, end, value), merge elements where the ranges are
-     continuous and the values are the same.'''
-  output = []
-  ranges.sort()
-  current = None
-  for v in ranges:
-    if current is None:
-      current = v
-      continue
-    if current[1] + 1 == v[0] and current[2] == v[2]:
-      current = (current[0], v[1], v[2])
-    else:
-      output.append(current)
-      current = v
-  if current is not None:
-    output.append(current)
-
-  return output
diff --git a/third_party/harfbuzz/harfbuzz.gyp b/third_party/harfbuzz/harfbuzz.gyp
deleted file mode 100644
index 1e3296f..0000000
--- a/third_party/harfbuzz/harfbuzz.gyp
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (c) 2009 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'targets': [
-    {
-      'target_name': 'harfbuzz',
-      'type': '<(library)',
-      'sources': [
-        'src/harfbuzz-buffer.c',
-        'src/harfbuzz-stream.c',
-        'src/harfbuzz-dump.c',
-        'src/harfbuzz-gdef.c',
-        'src/harfbuzz-gpos.c',
-        'src/harfbuzz-gsub.c',
-        'src/harfbuzz-impl.c',
-        'src/harfbuzz-open.c',
-        'src/harfbuzz-shaper.cpp',
-        'src/harfbuzz-tibetan.c',
-        'src/harfbuzz-khmer.c',
-        'src/harfbuzz-indic.cpp',
-        'src/harfbuzz-hebrew.c',
-        'src/harfbuzz-arabic.c',
-        'src/harfbuzz-hangul.c',
-        'src/harfbuzz-myanmar.c',
-        'src/harfbuzz-thai.c',
-      ],
-      'include_dirs': [
-        'src',
-      ],
-      'direct_dependent_settings': {
-        'include_dirs': [
-          'src',
-        ],
-      },
-      'dependencies': [
-        '../../build/linux/system.gyp:freetype2',
-      ],
-    },
-    {
-      'target_name': 'harfbuzz_interface',
-      'type': '<(library)',
-      'sources': [
-        'contrib/harfbuzz-freetype.c',
-        'contrib/harfbuzz-unicode.c',
-        'contrib/harfbuzz-unicode-tables.c',
-      ],
-      'include_dirs': [
-        'src',
-        'contrib',
-      ],
-      'direct_dependent_settings': {
-        'include_dirs': [
-          'contrib',
-        ],
-      },
-      'dependencies': [
-        '../../build/linux/system.gyp:freetype2',
-      ],
-    },
-  ],
-}
diff --git a/third_party/harfbuzz/src/.gitignore b/third_party/harfbuzz/src/.gitignore
deleted file mode 100644
index 74de98b..0000000
--- a/third_party/harfbuzz/src/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-*.o
-*.lo
-Makefile
-*.la
-.deps
-.libs
-*~
diff --git a/third_party/harfbuzz/src/Makefile.am b/third_party/harfbuzz/src/Makefile.am
deleted file mode 100644
index 2b0fb1d..0000000
--- a/third_party/harfbuzz/src/Makefile.am
+++ /dev/null
@@ -1,68 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-noinst_LTLIBRARIES = libharfbuzz-1.la
-
-MAINSOURCES =  \
-	harfbuzz-buffer.c \
-	harfbuzz-stream.c \
-	harfbuzz-dump.c \
-	harfbuzz-gdef.c \
-	harfbuzz-gpos.c \
-	harfbuzz-gsub.c \
-	harfbuzz-impl.c \
-	harfbuzz-open.c \
-	harfbuzz-shaper.cpp \
-	harfbuzz-tibetan.c \
-	harfbuzz-khmer.c \
-	harfbuzz-indic.cpp \
-	harfbuzz-hebrew.c \
-	harfbuzz-arabic.c \
-	harfbuzz-hangul.c \
-	harfbuzz-myanmar.c \
-	harfbuzz-thai.c
-
-EXTRA_SOURCES = harfbuzz.c
-
-PUBLICHEADERS = \
-	harfbuzz.h \
-	harfbuzz-buffer.h \
-	harfbuzz-dump.h \
-	harfbuzz-gdef.h \
-	harfbuzz-gpos.h \
-	harfbuzz-gsub.h \
-	harfbuzz-open.h \
-	harfbuzz-global.h \
-	harfbuzz-external.h \
-	harfbuzz-shaper.h \
-	harfbuzz-stream.h
-
-PRIVATEHEADERS = \
-	harfbuzz-impl.h \
-	harfbuzz-buffer-private.h \
-	harfbuzz-stream-private.h \
-	harfbuzz-gdef-private.h \
-	harfbuzz-gpos-private.h \
-	harfbuzz-gsub-private.h \
-	harfbuzz-open-private.h \
-	harfbuzz-shaper-private.h
-
-libharfbuzz_1_la_SOURCES = \
-	$(MAINSOURCES) \
-	$(PUBLICHEADERS) \
-	$(PRIVATEHEADERS)
-
-#noinst_PROGRAMS = harfbuzz-dump
-#
-#harfbuzz_dump_SOURCES = 	\
-#	harfbuzz-dump-main.c
-#
-#harfbuzz_dump_LDADD = 		\
-#	libharfbuzz-1.la
-
-EXTRA_DIST = 		\
-	README		\
-	COPYING.FTL	\
-	COPYING.GPL	\
-	COPYING		\
-	$(EXTRA_SOURCES)
-
diff --git a/third_party/harfbuzz/src/harfbuzz-arabic.c b/third_party/harfbuzz/src/harfbuzz-arabic.c
deleted file mode 100644
index ce2ca6c..0000000
--- a/third_party/harfbuzz/src/harfbuzz-arabic.c
+++ /dev/null
@@ -1,1145 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-
-static const HB_UChar16 ReplacementCharacter = 0xfffd;
-
-typedef struct {
-    unsigned char shape;
-    unsigned char justification;
-} HB_ArabicProperties;
-
-typedef enum {
-    XIsolated,
-    XFinal,
-    XInitial,
-    XMedial,
-    /* intermediate state */
-    XCausing
-} ArabicShape;
-
-/*
-// these groups correspond to the groups defined in the Unicode standard.
-// Some of these groups are equal with regards to both joining and line breaking behaviour,
-// and thus have the same enum value
-//
-// I'm not sure the mapping of syriac to arabic enums is correct with regards to justification, but as
-// I couldn't find any better document I'll hope for the best.
-*/
-typedef enum {
-    /* NonJoining */
-    ArabicNone,
-    ArabicSpace,
-    /* Transparent */
-    Transparent,
-    /* Causing */
-    Center,
-    Kashida,
-
-    /* Arabic */
-    /* Dual */
-    Beh,
-    Noon,
-    Meem = Noon,
-    Heh = Noon,
-    KnottedHeh = Noon,
-    HehGoal = Noon,
-    SwashKaf = Noon,
-    Yeh,
-    Hah,
-    Seen,
-    Sad = Seen,
-    Tah,
-    Kaf = Tah,
-    Gaf = Tah,
-    Lam = Tah,
-    Ain,
-    Feh = Ain,
-    Qaf = Ain,
-    /* Right */
-    Alef,
-    Waw,
-    Dal,
-    TehMarbuta = Dal,
-    Reh,
-    HamzaOnHehGoal,
-    YehWithTail = HamzaOnHehGoal,
-    YehBarre = HamzaOnHehGoal,
-
-    /* Syriac */
-    /* Dual */
-    Beth = Beh,
-    Gamal = Ain,
-    Heth = Noon,
-    Teth = Hah,
-    Yudh = Noon,
-    Kaph = Noon,
-    Lamadh = Lam,
-    Mim = Noon,
-    Nun = Noon,
-    Semakh = Noon,
-    FinalSemakh = Noon,
-    SyriacE = Ain,
-    Pe = Ain,
-    ReversedPe = Hah,
-    Qaph = Noon,
-    Shin = Noon,
-    Fe = Ain,
-
-    /* Right */
-    Alaph = Alef,
-    Dalath = Dal,
-    He = Dal,
-    SyriacWaw = Waw,
-    Zain = Alef,
-    YudhHe = Waw,
-    Sadhe = HamzaOnHehGoal,
-    Taw = Dal,
-
-    /* Compiler bug? Otherwise ArabicGroupsEnd would be equal to Dal + 1. */
-    Dummy = HamzaOnHehGoal,
-    ArabicGroupsEnd
-} ArabicGroup;
-
-static const unsigned char arabic_group[0x150] = {
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, Transparent, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
-    ArabicNone, ArabicNone, Alef, Alef,
-    Waw, Alef, Yeh, Alef,
-    Beh, TehMarbuta, Beh, Beh,
-    Hah, Hah, Hah, Dal,
-
-    Dal, Reh, Reh, Seen,
-    Seen, Sad, Sad, Tah,
-    Tah, Ain, Ain, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
-    /* 0x640 */
-    Kashida, Feh, Qaf, Kaf,
-    Lam, Meem, Noon, Heh,
-    Waw, Yeh, Yeh, Transparent,
-    Transparent, Transparent, Transparent, Transparent,
-
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, Beh, Qaf,
-
-    Transparent, Alef, Alef, Alef,
-    ArabicNone, Alef, Waw, Waw,
-    Yeh, Beh, Beh, Beh,
-    Beh, Beh, Beh, Beh,
-
-    /* 0x680 */
-    Beh, Hah, Hah, Hah,
-    Hah, Hah, Hah, Hah,
-    Dal, Dal, Dal, Dal,
-    Dal, Dal, Dal, Dal,
-
-    Dal, Reh, Reh, Reh,
-    Reh, Reh, Reh, Reh,
-    Reh, Reh, Seen, Seen,
-    Seen, Sad, Sad, Tah,
-
-    Ain, Feh, Feh, Feh,
-    Feh, Feh, Feh, Qaf,
-    Qaf, Gaf, SwashKaf, Gaf,
-    Kaf, Kaf, Kaf, Gaf,
-
-    Gaf, Gaf, Gaf, Gaf,
-    Gaf, Lam, Lam, Lam,
-    Lam, Noon, Noon, Noon,
-    Noon, Noon, KnottedHeh, Hah,
-
-    /* 0x6c0 */
-    TehMarbuta, HehGoal, HamzaOnHehGoal, HamzaOnHehGoal,
-    Waw, Waw, Waw, Waw,
-    Waw, Waw, Waw, Waw,
-    Yeh, YehWithTail, Yeh, Waw,
-
-    Yeh, Yeh, YehBarre, YehBarre,
-    ArabicNone, TehMarbuta, Transparent, Transparent,
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, ArabicNone, ArabicNone, Transparent,
-
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, ArabicNone, ArabicNone, Transparent,
-    Transparent, ArabicNone, Transparent, Transparent,
-    Transparent, Transparent, Dal, Reh,
-
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, Seen, Sad,
-    Ain, ArabicNone, ArabicNone, KnottedHeh,
-
-    /* 0x700 */
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-    ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
-    Alaph, Transparent, Beth, Gamal,
-    Gamal, Dalath, Dalath, He,
-    SyriacWaw, Zain, Heth, Teth,
-    Teth, Yudh, YudhHe, Kaph,
-
-    Lamadh, Mim, Nun, Semakh,
-    FinalSemakh, SyriacE, Pe, ReversedPe,
-    Sadhe, Qaph, Dalath, Shin,
-    Taw, Beth, Gamal, Dalath,
-
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, Transparent, Transparent, Transparent,
-
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, Transparent, Transparent, Transparent,
-    Transparent, Transparent, Transparent, ArabicNone,
-    ArabicNone, Zain, Kaph, Fe,
-};
-
-static ArabicGroup arabicGroup(unsigned short uc)
-{
-    if (uc >= 0x0600 && uc < 0x750)
-        return (ArabicGroup) arabic_group[uc-0x600];
-    else if (uc == 0x200d)
-        return Center;
-    else if (HB_GetUnicodeCharCategory(uc) == HB_Separator_Space)
-        return ArabicSpace;
-    else
-        return ArabicNone;
-}
-
-
-/*
-   Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on
-   arabic).
-
-   Each unicode char has a joining class (right, dual (left&right), center (joincausing) or transparent).
-   transparent joining is not encoded in HB_UChar16::joining(), but applies to all combining marks and format marks.
-
-   Right join-causing: dual + center
-   Left join-causing: dual + right + center
-
-   Rules are as follows (for a string already in visual order, as we have it here):
-
-   R1 Transparent characters do not affect joining behaviour.
-   R2 A right joining character, that has a right join-causing char on the right will get form XRight
-   (R3 A left joining character, that has a left join-causing char on the left will get form XLeft)
-   Note: the above rule is meaningless, as there are no pure left joining characters defined in Unicode
-   R4 A dual joining character, that has a left join-causing char on the left and a right join-causing char on
-             the right will get form XMedial
-   R5  A dual joining character, that has a right join causing char on the right, and no left join causing char on the left
-         will get form XRight
-   R6 A dual joining character, that has a  left join causing char on the left, and no right join causing char on the right
-         will get form XLeft
-   R7 Otherwise the character will get form XIsolated
-
-   Additionally we have to do the minimal ligature support for lam-alef ligatures:
-
-   L1 Transparent characters do not affect ligature behaviour.
-   L2 Any sequence of Alef(XRight) + Lam(XMedial) will form the ligature Alef.Lam(XLeft)
-   L3 Any sequence of Alef(XRight) + Lam(XLeft) will form the ligature Alef.Lam(XIsolated)
-
-   The state table below handles rules R1-R7.
-*/
-
-typedef enum {
-    JNone,
-    JCausing,
-    JDual,
-    JRight,
-    JTransparent
-} Joining;
-
-static const Joining joining_for_group[ArabicGroupsEnd] = {
-    /* NonJoining */
-    JNone, /* ArabicNone */
-    JNone, /* ArabicSpace */
-    /* Transparent */
-    JTransparent, /* Transparent */
-    /* Causing */
-    JCausing, /* Center */
-    JCausing, /* Kashida */
-    /* Dual */
-    JDual, /* Beh */
-    JDual, /* Noon */
-    JDual, /* Yeh */
-    JDual, /* Hah */
-    JDual, /* Seen */
-    JDual, /* Tah */
-    JDual, /* Ain */
-    /* Right */
-    JRight, /* Alef */
-    JRight, /* Waw */
-    JRight, /* Dal */
-    JRight, /* Reh */
-    JRight  /* HamzaOnHehGoal */
-};
-
-
-typedef struct {
-    ArabicShape form1;
-    ArabicShape form2;
-} JoiningPair;
-
-static const JoiningPair joining_table[5][4] =
-/* None, Causing, Dual, Right */
-{
-    { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XInitial }, { XIsolated, XIsolated } }, /* XIsolated */
-    { { XFinal, XIsolated }, { XFinal, XCausing }, { XFinal, XInitial }, { XFinal, XIsolated } }, /* XFinal */
-    { { XIsolated, XIsolated }, { XInitial, XCausing }, { XInitial, XMedial }, { XInitial, XFinal } }, /* XInitial */
-    { { XFinal, XIsolated }, { XMedial, XCausing }, { XMedial, XMedial }, { XMedial, XFinal } }, /* XMedial */
-    { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XMedial }, { XIsolated, XFinal } }, /* XCausing */
-};
-
-
-/*
-According to http://www.microsoft.com/middleeast/Arabicdev/IE6/KBase.asp
-
-1. Find the priority of the connecting opportunities in each word
-2. Add expansion at the highest priority connection opportunity
-3. If more than one connection opportunity have the same highest value,
-   use the opportunity closest to the end of the word.
-
-Following is a chart that provides the priority for connection
-opportunities and where expansion occurs. The character group names
-are those in table 6.6 of the UNICODE 2.0 book.
-
-
-PrioritY        Glyph                   Condition                                       Kashida Location
-
-Arabic_Kashida        User inserted Kashida   The user entered a Kashida in a position.       After the user
-                (Shift+j or Shift+[E with hat])    Thus, it is the highest priority to insert an   inserted kashida
-                                        automatic kashida.
-
-Arabic_Seen        Seen, Sad               Connecting to the next character.               After the character.
-                                        (Initial or medial form).
-
-Arabic_HaaDal        Teh Marbutah, Haa, Dal  Connecting to previous character.               Before the final form
-                                                                                        of these characters.
-
-Arabic_Alef     Alef, Tah, Lam,         Connecting to previous character.               Before the final form
-                Kaf and Gaf                                                             of these characters.
-
-Arabic_BaRa     Reh, Yeh                Connected to medial Beh                         Before preceding medial Baa
-
-Arabic_Waw        Waw, Ain, Qaf, Feh      Connecting to previous character.               Before the final form of
-                                                                                        these characters.
-
-Arabic_Normal   Other connecting        Connecting to previous character.               Before the final form
-                characters                                                              of these characters.
-
-
-
-This seems to imply that we have at most one kashida point per arabic word.
-
-*/
-
-static void getArabicProperties(const unsigned short *chars, int len, HB_ArabicProperties *properties)
-{
-/*     qDebug("arabicSyriacOpenTypeShape: properties:"); */
-    int lastPos = 0;
-    int lastGroup = ArabicNone;
-    int i = 0;
-
-    ArabicGroup group = arabicGroup(chars[0]);
-    Joining j = joining_for_group[group];
-    ArabicShape shape = joining_table[XIsolated][j].form2;
-    properties[0].justification = HB_NoJustification;
-
-    for (i = 1; i < len; ++i) {
-        /* #### fix handling for spaces and punktuation */
-        properties[i].justification = HB_NoJustification;
-
-        group = arabicGroup(chars[i]);
-        j = joining_for_group[group];
-
-        if (j == JTransparent) {
-            properties[i].shape = XIsolated;
-            continue;
-        }
-
-        properties[lastPos].shape = joining_table[shape][j].form1;
-        shape = joining_table[shape][j].form2;
-
-        switch(lastGroup) {
-        case Seen:
-            if (properties[lastPos].shape == XInitial || properties[lastPos].shape == XMedial)
-                properties[i-1].justification = HB_Arabic_Seen;
-            break;
-        case Hah:
-            if (properties[lastPos].shape == XFinal)
-                properties[lastPos-1].justification = HB_Arabic_HaaDal;
-            break;
-        case Alef:
-            if (properties[lastPos].shape == XFinal)
-                properties[lastPos-1].justification = HB_Arabic_Alef;
-            break;
-        case Ain:
-            if (properties[lastPos].shape == XFinal)
-                properties[lastPos-1].justification = HB_Arabic_Waw;
-            break;
-        case Noon:
-            if (properties[lastPos].shape == XFinal)
-                properties[lastPos-1].justification = HB_Arabic_Normal;
-            break;
-        case ArabicNone:
-            break;
-
-        default:
-            assert(FALSE);
-        }
-
-        lastGroup = ArabicNone;
-
-        switch(group) {
-        case ArabicNone:
-        case Transparent:
-        /* ### Center should probably be treated as transparent when it comes to justification. */
-        case Center:
-            break;
-        case ArabicSpace:
-            properties[i].justification = HB_Arabic_Space;
-            break;
-        case Kashida:
-            properties[i].justification = HB_Arabic_Kashida;
-            break;
-        case Seen:
-            lastGroup = Seen;
-            break;
-
-        case Hah:
-        case Dal:
-            lastGroup = Hah;
-            break;
-
-        case Alef:
-        case Tah:
-            lastGroup = Alef;
-            break;
-
-        case Yeh:
-        case Reh:
-            if (properties[lastPos].shape == XMedial && arabicGroup(chars[lastPos]) == Beh)
-                properties[lastPos-1].justification = HB_Arabic_BaRa;
-            break;
-
-        case Ain:
-        case Waw:
-            lastGroup = Ain;
-            break;
-
-        case Noon:
-        case Beh:
-        case HamzaOnHehGoal:
-            lastGroup = Noon;
-            break;
-        case ArabicGroupsEnd:
-            assert(FALSE);
-        }
-
-        lastPos = i;
-    }
-    properties[lastPos].shape = joining_table[shape][JNone].form1;
-
-
-    /*
-     for (int i = 0; i < len; ++i)
-         qDebug("arabic properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification);
-    */
-}
-
-static Joining getNkoJoining(unsigned short uc)
-{
-    if (uc < 0x7ca)
-        return JNone;
-    if (uc <= 0x7ea)
-        return JDual;
-    if (uc <= 0x7f3)
-        return JTransparent;
-    if (uc <= 0x7f9)
-        return JNone;
-    if (uc == 0x7fa)
-        return JCausing;
-    return JNone;
-}
-
-static void getNkoProperties(const unsigned short *chars, int len, HB_ArabicProperties *properties)
-{
-    int lastPos = 0;
-    int i = 0;
-
-    Joining j = getNkoJoining(chars[0]);
-    ArabicShape shape = joining_table[XIsolated][j].form2;
-    properties[0].justification = HB_NoJustification;
-
-    for (i = 1; i < len; ++i) {
-        properties[i].justification = (HB_GetUnicodeCharCategory(chars[i]) == HB_Separator_Space) ?
-                                      ArabicSpace : ArabicNone;
-
-        j = getNkoJoining(chars[i]);
-
-        if (j == JTransparent) {
-            properties[i].shape = XIsolated;
-            continue;
-        }
-
-        properties[lastPos].shape = joining_table[shape][j].form1;
-        shape = joining_table[shape][j].form2;
-
-
-        lastPos = i;
-    }
-    properties[lastPos].shape = joining_table[shape][JNone].form1;
-
-
-    /*
-     for (int i = 0; i < len; ++i)
-         qDebug("nko properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification);
-    */
-}
-
-/*
-// The unicode to unicode shaping codec.
-// does only presentation forms B at the moment, but that should be enough for
-// simple display
-*/
-static const hb_uint16 arabicUnicodeMapping[256][2] = {
-    /* base of shaped forms, and number-1 of them (0 for non shaping,
-       1 for right binding and 3 for dual binding */
-
-    /* These are just the glyphs available in Unicode,
-       some characters are in R class, but have no glyphs in Unicode. */
-
-    { 0x0600, 0 }, /* 0x0600 */
-    { 0x0601, 0 }, /* 0x0601 */
-    { 0x0602, 0 }, /* 0x0602 */
-    { 0x0603, 0 }, /* 0x0603 */
-    { 0x0604, 0 }, /* 0x0604 */
-    { 0x0605, 0 }, /* 0x0605 */
-    { 0x0606, 0 }, /* 0x0606 */
-    { 0x0607, 0 }, /* 0x0607 */
-    { 0x0608, 0 }, /* 0x0608 */
-    { 0x0609, 0 }, /* 0x0609 */
-    { 0x060A, 0 }, /* 0x060A */
-    { 0x060B, 0 }, /* 0x060B */
-    { 0x060C, 0 }, /* 0x060C */
-    { 0x060D, 0 }, /* 0x060D */
-    { 0x060E, 0 }, /* 0x060E */
-    { 0x060F, 0 }, /* 0x060F */
-
-    { 0x0610, 0 }, /* 0x0610 */
-    { 0x0611, 0 }, /* 0x0611 */
-    { 0x0612, 0 }, /* 0x0612 */
-    { 0x0613, 0 }, /* 0x0613 */
-    { 0x0614, 0 }, /* 0x0614 */
-    { 0x0615, 0 }, /* 0x0615 */
-    { 0x0616, 0 }, /* 0x0616 */
-    { 0x0617, 0 }, /* 0x0617 */
-    { 0x0618, 0 }, /* 0x0618 */
-    { 0x0619, 0 }, /* 0x0619 */
-    { 0x061A, 0 }, /* 0x061A */
-    { 0x061B, 0 }, /* 0x061B */
-    { 0x061C, 0 }, /* 0x061C */
-    { 0x061D, 0 }, /* 0x061D */
-    { 0x061E, 0 }, /* 0x061E */
-    { 0x061F, 0 }, /* 0x061F */
-
-    { 0x0620, 0 }, /* 0x0620 */
-    { 0xFE80, 0 }, /* 0x0621            HAMZA */
-    { 0xFE81, 1 }, /* 0x0622    R       ALEF WITH MADDA ABOVE */
-    { 0xFE83, 1 }, /* 0x0623    R       ALEF WITH HAMZA ABOVE */
-    { 0xFE85, 1 }, /* 0x0624    R       WAW WITH HAMZA ABOVE */
-    { 0xFE87, 1 }, /* 0x0625    R       ALEF WITH HAMZA BELOW */
-    { 0xFE89, 3 }, /* 0x0626    D       YEH WITH HAMZA ABOVE */
-    { 0xFE8D, 1 }, /* 0x0627    R       ALEF */
-    { 0xFE8F, 3 }, /* 0x0628    D       BEH */
-    { 0xFE93, 1 }, /* 0x0629    R       TEH MARBUTA */
-    { 0xFE95, 3 }, /* 0x062A    D       TEH */
-    { 0xFE99, 3 }, /* 0x062B    D       THEH */
-    { 0xFE9D, 3 }, /* 0x062C    D       JEEM */
-    { 0xFEA1, 3 }, /* 0x062D    D       HAH */
-    { 0xFEA5, 3 }, /* 0x062E    D       KHAH */
-    { 0xFEA9, 1 }, /* 0x062F    R       DAL */
-
-    { 0xFEAB, 1 }, /* 0x0630    R       THAL */
-    { 0xFEAD, 1 }, /* 0x0631    R       REH */
-    { 0xFEAF, 1 }, /* 0x0632    R       ZAIN */
-    { 0xFEB1, 3 }, /* 0x0633    D       SEEN */
-    { 0xFEB5, 3 }, /* 0x0634    D       SHEEN */
-    { 0xFEB9, 3 }, /* 0x0635    D       SAD */
-    { 0xFEBD, 3 }, /* 0x0636    D       DAD */
-    { 0xFEC1, 3 }, /* 0x0637    D       TAH */
-    { 0xFEC5, 3 }, /* 0x0638    D       ZAH */
-    { 0xFEC9, 3 }, /* 0x0639    D       AIN */
-    { 0xFECD, 3 }, /* 0x063A    D       GHAIN */
-    { 0x063B, 0 }, /* 0x063B */
-    { 0x063C, 0 }, /* 0x063C */
-    { 0x063D, 0 }, /* 0x063D */
-    { 0x063E, 0 }, /* 0x063E */
-    { 0x063F, 0 }, /* 0x063F */
-
-    { 0x0640, 0 }, /* 0x0640    C       TATWEEL // ### Join Causing, only one glyph */
-    { 0xFED1, 3 }, /* 0x0641    D       FEH */
-    { 0xFED5, 3 }, /* 0x0642    D       QAF */
-    { 0xFED9, 3 }, /* 0x0643    D       KAF */
-    { 0xFEDD, 3 }, /* 0x0644    D       LAM */
-    { 0xFEE1, 3 }, /* 0x0645    D       MEEM */
-    { 0xFEE5, 3 }, /* 0x0646    D       NOON */
-    { 0xFEE9, 3 }, /* 0x0647    D       HEH */
-    { 0xFEED, 1 }, /* 0x0648    R       WAW */
-    { 0x0649, 3 }, /* 0x0649            ALEF MAKSURA // ### Dual, glyphs not consecutive, handle in code. */
-    { 0xFEF1, 3 }, /* 0x064A    D       YEH */
-    { 0x064B, 0 }, /* 0x064B */
-    { 0x064C, 0 }, /* 0x064C */
-    { 0x064D, 0 }, /* 0x064D */
-    { 0x064E, 0 }, /* 0x064E */
-    { 0x064F, 0 }, /* 0x064F */
-
-    { 0x0650, 0 }, /* 0x0650 */
-    { 0x0651, 0 }, /* 0x0651 */
-    { 0x0652, 0 }, /* 0x0652 */
-    { 0x0653, 0 }, /* 0x0653 */
-    { 0x0654, 0 }, /* 0x0654 */
-    { 0x0655, 0 }, /* 0x0655 */
-    { 0x0656, 0 }, /* 0x0656 */
-    { 0x0657, 0 }, /* 0x0657 */
-    { 0x0658, 0 }, /* 0x0658 */
-    { 0x0659, 0 }, /* 0x0659 */
-    { 0x065A, 0 }, /* 0x065A */
-    { 0x065B, 0 }, /* 0x065B */
-    { 0x065C, 0 }, /* 0x065C */
-    { 0x065D, 0 }, /* 0x065D */
-    { 0x065E, 0 }, /* 0x065E */
-    { 0x065F, 0 }, /* 0x065F */
-
-    { 0x0660, 0 }, /* 0x0660 */
-    { 0x0661, 0 }, /* 0x0661 */
-    { 0x0662, 0 }, /* 0x0662 */
-    { 0x0663, 0 }, /* 0x0663 */
-    { 0x0664, 0 }, /* 0x0664 */
-    { 0x0665, 0 }, /* 0x0665 */
-    { 0x0666, 0 }, /* 0x0666 */
-    { 0x0667, 0 }, /* 0x0667 */
-    { 0x0668, 0 }, /* 0x0668 */
-    { 0x0669, 0 }, /* 0x0669 */
-    { 0x066A, 0 }, /* 0x066A */
-    { 0x066B, 0 }, /* 0x066B */
-    { 0x066C, 0 }, /* 0x066C */
-    { 0x066D, 0 }, /* 0x066D */
-    { 0x066E, 0 }, /* 0x066E */
-    { 0x066F, 0 }, /* 0x066F */
-
-    { 0x0670, 0 }, /* 0x0670 */
-    { 0xFB50, 1 }, /* 0x0671    R       ALEF WASLA */
-    { 0x0672, 0 }, /* 0x0672 */
-    { 0x0673, 0 }, /* 0x0673 */
-    { 0x0674, 0 }, /* 0x0674 */
-    { 0x0675, 0 }, /* 0x0675 */
-    { 0x0676, 0 }, /* 0x0676 */
-    { 0x0677, 0 }, /* 0x0677 */
-    { 0x0678, 0 }, /* 0x0678 */
-    { 0xFB66, 3 }, /* 0x0679    D       TTEH */
-    { 0xFB5E, 3 }, /* 0x067A    D       TTEHEH */
-    { 0xFB52, 3 }, /* 0x067B    D       BEEH */
-    { 0x067C, 0 }, /* 0x067C */
-    { 0x067D, 0 }, /* 0x067D */
-    { 0xFB56, 3 }, /* 0x067E    D       PEH */
-    { 0xFB62, 3 }, /* 0x067F    D       TEHEH */
-
-    { 0xFB5A, 3 }, /* 0x0680    D       BEHEH */
-    { 0x0681, 0 }, /* 0x0681 */
-    { 0x0682, 0 }, /* 0x0682 */
-    { 0xFB76, 3 }, /* 0x0683    D       NYEH */
-    { 0xFB72, 3 }, /* 0x0684    D       DYEH */
-    { 0x0685, 0 }, /* 0x0685 */
-    { 0xFB7A, 3 }, /* 0x0686    D       TCHEH */
-    { 0xFB7E, 3 }, /* 0x0687    D       TCHEHEH */
-    { 0xFB88, 1 }, /* 0x0688    R       DDAL */
-    { 0x0689, 0 }, /* 0x0689 */
-    { 0x068A, 0 }, /* 0x068A */
-    { 0x068B, 0 }, /* 0x068B */
-    { 0xFB84, 1 }, /* 0x068C    R       DAHAL */
-    { 0xFB82, 1 }, /* 0x068D    R       DDAHAL */
-    { 0xFB86, 1 }, /* 0x068E    R       DUL */
-    { 0x068F, 0 }, /* 0x068F */
-
-    { 0x0690, 0 }, /* 0x0690 */
-    { 0xFB8C, 1 }, /* 0x0691    R       RREH */
-    { 0x0692, 0 }, /* 0x0692 */
-    { 0x0693, 0 }, /* 0x0693 */
-    { 0x0694, 0 }, /* 0x0694 */
-    { 0x0695, 0 }, /* 0x0695 */
-    { 0x0696, 0 }, /* 0x0696 */
-    { 0x0697, 0 }, /* 0x0697 */
-    { 0xFB8A, 1 }, /* 0x0698    R       JEH */
-    { 0x0699, 0 }, /* 0x0699 */
-    { 0x069A, 0 }, /* 0x069A */
-    { 0x069B, 0 }, /* 0x069B */
-    { 0x069C, 0 }, /* 0x069C */
-    { 0x069D, 0 }, /* 0x069D */
-    { 0x069E, 0 }, /* 0x069E */
-    { 0x069F, 0 }, /* 0x069F */
-
-    { 0x06A0, 0 }, /* 0x06A0 */
-    { 0x06A1, 0 }, /* 0x06A1 */
-    { 0x06A2, 0 }, /* 0x06A2 */
-    { 0x06A3, 0 }, /* 0x06A3 */
-    { 0xFB6A, 3 }, /* 0x06A4    D       VEH */
-    { 0x06A5, 0 }, /* 0x06A5 */
-    { 0xFB6E, 3 }, /* 0x06A6    D       PEHEH */
-    { 0x06A7, 0 }, /* 0x06A7 */
-    { 0x06A8, 0 }, /* 0x06A8 */
-    { 0xFB8E, 3 }, /* 0x06A9    D       KEHEH */
-    { 0x06AA, 0 }, /* 0x06AA */
-    { 0x06AB, 0 }, /* 0x06AB */
-    { 0x06AC, 0 }, /* 0x06AC */
-    { 0xFBD3, 3 }, /* 0x06AD    D       NG */
-    { 0x06AE, 0 }, /* 0x06AE */
-    { 0xFB92, 3 }, /* 0x06AF    D       GAF */
-
-    { 0x06B0, 0 }, /* 0x06B0 */
-    { 0xFB9A, 3 }, /* 0x06B1    D       NGOEH */
-    { 0x06B2, 0 }, /* 0x06B2 */
-    { 0xFB96, 3 }, /* 0x06B3    D       GUEH */
-    { 0x06B4, 0 }, /* 0x06B4 */
-    { 0x06B5, 0 }, /* 0x06B5 */
-    { 0x06B6, 0 }, /* 0x06B6 */
-    { 0x06B7, 0 }, /* 0x06B7 */
-    { 0x06B8, 0 }, /* 0x06B8 */
-    { 0x06B9, 0 }, /* 0x06B9 */
-    { 0xFB9E, 1 }, /* 0x06BA    R       NOON GHUNNA */
-    { 0xFBA0, 3 }, /* 0x06BB    D       RNOON */
-    { 0x06BC, 0 }, /* 0x06BC */
-    { 0x06BD, 0 }, /* 0x06BD */
-    { 0xFBAA, 3 }, /* 0x06BE    D       HEH DOACHASHMEE */
-    { 0x06BF, 0 }, /* 0x06BF */
-
-    { 0xFBA4, 1 }, /* 0x06C0    R       HEH WITH YEH ABOVE */
-    { 0xFBA6, 3 }, /* 0x06C1    D       HEH GOAL */
-    { 0x06C2, 0 }, /* 0x06C2 */
-    { 0x06C3, 0 }, /* 0x06C3 */
-    { 0x06C4, 0 }, /* 0x06C4 */
-    { 0xFBE0, 1 }, /* 0x06C5    R       KIRGHIZ OE */
-    { 0xFBD9, 1 }, /* 0x06C6    R       OE */
-    { 0xFBD7, 1 }, /* 0x06C7    R       U */
-    { 0xFBDB, 1 }, /* 0x06C8    R       YU */
-    { 0xFBE2, 1 }, /* 0x06C9    R       KIRGHIZ YU */
-    { 0x06CA, 0 }, /* 0x06CA */
-    { 0xFBDE, 1 }, /* 0x06CB    R       VE */
-    { 0xFBFC, 3 }, /* 0x06CC    D       FARSI YEH */
-    { 0x06CD, 0 }, /* 0x06CD */
-    { 0x06CE, 0 }, /* 0x06CE */
-    { 0x06CF, 0 }, /* 0x06CF */
-
-    { 0xFBE4, 3 }, /* 0x06D0    D       E */
-    { 0x06D1, 0 }, /* 0x06D1 */
-    { 0xFBAE, 1 }, /* 0x06D2    R       YEH BARREE */
-    { 0xFBB0, 1 }, /* 0x06D3    R       YEH BARREE WITH HAMZA ABOVE */
-    { 0x06D4, 0 }, /* 0x06D4 */
-    { 0x06D5, 0 }, /* 0x06D5 */
-    { 0x06D6, 0 }, /* 0x06D6 */
-    { 0x06D7, 0 }, /* 0x06D7 */
-    { 0x06D8, 0 }, /* 0x06D8 */
-    { 0x06D9, 0 }, /* 0x06D9 */
-    { 0x06DA, 0 }, /* 0x06DA */
-    { 0x06DB, 0 }, /* 0x06DB */
-    { 0x06DC, 0 }, /* 0x06DC */
-    { 0x06DD, 0 }, /* 0x06DD */
-    { 0x06DE, 0 }, /* 0x06DE */
-    { 0x06DF, 0 }, /* 0x06DF */
-
-    { 0x06E0, 0 }, /* 0x06E0 */
-    { 0x06E1, 0 }, /* 0x06E1 */
-    { 0x06E2, 0 }, /* 0x06E2 */
-    { 0x06E3, 0 }, /* 0x06E3 */
-    { 0x06E4, 0 }, /* 0x06E4 */
-    { 0x06E5, 0 }, /* 0x06E5 */
-    { 0x06E6, 0 }, /* 0x06E6 */
-    { 0x06E7, 0 }, /* 0x06E7 */
-    { 0x06E8, 0 }, /* 0x06E8 */
-    { 0x06E9, 0 }, /* 0x06E9 */
-    { 0x06EA, 0 }, /* 0x06EA */
-    { 0x06EB, 0 }, /* 0x06EB */
-    { 0x06EC, 0 }, /* 0x06EC */
-    { 0x06ED, 0 }, /* 0x06ED */
-    { 0x06EE, 0 }, /* 0x06EE */
-    { 0x06EF, 0 }, /* 0x06EF */
-
-    { 0x06F0, 0 }, /* 0x06F0 */
-    { 0x06F1, 0 }, /* 0x06F1 */
-    { 0x06F2, 0 }, /* 0x06F2 */
-    { 0x06F3, 0 }, /* 0x06F3 */
-    { 0x06F4, 0 }, /* 0x06F4 */
-    { 0x06F5, 0 }, /* 0x06F5 */
-    { 0x06F6, 0 }, /* 0x06F6 */
-    { 0x06F7, 0 }, /* 0x06F7 */
-    { 0x06F8, 0 }, /* 0x06F8 */
-    { 0x06F9, 0 }, /* 0x06F9 */
-    { 0x06FA, 0 }, /* 0x06FA */
-    { 0x06FB, 0 }, /* 0x06FB */
-    { 0x06FC, 0 }, /* 0x06FC */
-    { 0x06FD, 0 }, /* 0x06FD */
-    { 0x06FE, 0 }, /* 0x06FE */
-    { 0x06FF, 0 }  /* 0x06FF */
-};
-
-/* the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, this table does */
-static const hb_uint16 alefMaksura[4] = {0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9};
-
-/*
-// this is a bit tricky. Alef always binds to the right, so the second parameter descibing the shape
-// of the lam can be either initial of medial. So initial maps to the isolated form of the ligature,
-// medial to the final form
-*/
-static const hb_uint16 arabicUnicodeLamAlefMapping[6][4] = {
-    { 0xfffd, 0xfffd, 0xfef5, 0xfef6 }, /* 0x622        R       Alef with Madda above */
-    { 0xfffd, 0xfffd, 0xfef7, 0xfef8 }, /* 0x623        R       Alef with Hamza above */
-    { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, /* 0x624        // Just to fill the table ;-) */
-    { 0xfffd, 0xfffd, 0xfef9, 0xfefa }, /* 0x625        R       Alef with Hamza below */
-    { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, /* 0x626        // Just to fill the table ;-) */
-    { 0xfffd, 0xfffd, 0xfefb, 0xfefc }  /* 0x627        R       Alef */
-};
-
-static int getShape(hb_uint8 cell, int shape)
-{
-    /* the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, handle this here */
-    int ch = (cell != 0x49)
-              ? (shape ? arabicUnicodeMapping[cell][0] + shape : 0x600+cell)
-              : alefMaksura[shape] ;
-    return ch;
-}
-
-
-/*
-  Two small helper functions for arabic shaping.
-*/
-static HB_UChar16 prevChar(const HB_UChar16 *str, int pos)
-{
-    /*qDebug("leftChar: pos=%d", pos); */
-    const HB_UChar16 *ch = str + pos - 1;
-    pos--;
-    while(pos > -1) {
-        if(HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing)
-            return *ch;
-        pos--;
-        ch--;
-    }
-    return ReplacementCharacter;
-}
-
-static HB_UChar16 nextChar(const HB_UChar16 *str, hb_uint32 len, hb_uint32 pos)
-{
-    const HB_UChar16 *ch = str + pos + 1;
-    pos++;
-    while(pos < len) {
-        /*qDebug("rightChar: %d isLetter=%d, joining=%d", pos, ch.isLetter(), ch.joining()); */
-        if(HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing)
-            return *ch;
-        /* assume it's a transparent char, this might not be 100% correct */
-        pos++;
-        ch++;
-    }
-    return ReplacementCharacter;
-}
-
-static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 from, hb_uint32 len, HB_UChar16 *shapeBuffer, int *shapedLength,
-                         HB_Bool reverse, HB_GlyphAttributes *attributes, unsigned short *logClusters)
-{
-    HB_ArabicProperties *properties;
-    hb_int32 f = from;
-    hb_uint32 l = len;
-    const HB_UChar16 *ch;
-    HB_UChar16 *data;
-    int clusterStart;
-    hb_uint32 i;
-    HB_STACKARRAY(HB_ArabicProperties, props, len + 2);
-    properties = props;
-
-    assert(stringLength >= from + len);
-
-    if(len == 0) {
-        *shapedLength = 0;
-        return;
-    }
-
-    if (from > 0) {
-        --f;
-        ++l;
-        ++properties;
-    }
-    if (f + l < stringLength)
-        ++l;
-    getArabicProperties(uc+f, l, props);
-
-    ch = uc + from;
-    data = shapeBuffer;
-    clusterStart = 0;
-
-    for (i = 0; i < len; i++) {
-        hb_uint8 r = *ch >> 8;
-        int gpos = data - shapeBuffer;
-
-        if (r != 0x06) {
-            if (r == 0x20) {
-                if (*ch == 0x200c || *ch == 0x200d)
-                    /* remove ZWJ and ZWNJ */
-                    goto skip;
-            }
-            if (reverse)
-                *data = HB_GetMirroredChar(*ch);
-            else
-                *data = *ch;
-        } else {
-            hb_uint8 c = *ch & 0xff;
-            int pos = i + from;
-            int shape = properties[i].shape;
-/*            qDebug("mapping U+%x to shape %d glyph=0x%x", ch->unicode(), shape, getShape(c, shape)); */
-            /* take care of lam-alef ligatures (lam right of alef) */
-            hb_uint16 map;
-            switch (c) {
-                case 0x44: { /* lam */
-                    const HB_UChar16 pch = nextChar(uc, stringLength, pos);
-                    if ((pch >> 8) == 0x06) {
-                        switch (pch & 0xff) {
-                            case 0x22:
-                            case 0x23:
-                            case 0x25:
-                            case 0x27:
-/*                                 qDebug(" lam of lam-alef ligature"); */
-                                map = arabicUnicodeLamAlefMapping[(pch & 0xff) - 0x22][shape];
-                                goto next;
-                            default:
-                                break;
-                        }
-                    }
-                    break;
-                }
-                case 0x22: /* alef with madda */
-                case 0x23: /* alef with hamza above */
-                case 0x25: /* alef with hamza below */
-                case 0x27: /* alef */
-                    if (prevChar(uc, pos) == 0x0644) {
-                        /* have a lam alef ligature */
-                        /*qDebug(" alef of lam-alef ligature"); */
-                        goto skip;
-                    }
-                default:
-                    break;
-            }
-            map = getShape(c, shape);
-        next:
-            *data = map;
-        }
-        /* ##### Fixme */
-        /*glyphs[gpos].attributes.zeroWidth = zeroWidth; */
-        if (HB_GetUnicodeCharCategory(*ch) == HB_Mark_NonSpacing) {
-            attributes[gpos].mark = TRUE;
-/*             qDebug("glyph %d (char %d) is mark!", gpos, i); */
-        } else {
-            attributes[gpos].mark = FALSE;
-            clusterStart = data - shapeBuffer;
-        }
-        attributes[gpos].clusterStart = !attributes[gpos].mark;
-        attributes[gpos].combiningClass = HB_GetUnicodeCharCombiningClass(*ch);
-        attributes[gpos].justification = properties[i].justification;
-/*         qDebug("data[%d] = %x (from %x)", gpos, (uint)data->unicode(), ch->unicode());*/
-        data++;
-    skip:
-        ch++;
-        logClusters[i] = clusterStart;
-    }
-    *shapedLength = data - shapeBuffer;
-
-    HB_FREE_STACKARRAY(props);
-}
-
-#ifndef NO_OPENTYPE
-
-static const HB_OpenTypeFeature arabic_features[] = {
-    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
-    { HB_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty },
-    { HB_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty },
-    { HB_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty },
-    { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
-    { HB_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty },
-    { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty },
-    { HB_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty },
-    { HB_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty },
-    { HB_MAKE_TAG('c', 's', 'w', 'h'), CswhProperty },
-    /* mset is used in old Win95 fonts that don't have a 'mark' positioning table. */
-    { HB_MAKE_TAG('m', 's', 'e', 't'), MsetProperty },
-    {0, 0}
-};
-
-static const HB_OpenTypeFeature syriac_features[] = {
-    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
-    { HB_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty },
-    { HB_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty },
-    { HB_MAKE_TAG('f', 'i', 'n', '2'), FinaProperty },
-    { HB_MAKE_TAG('f', 'i', 'n', '3'), FinaProperty },
-    { HB_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty },
-    { HB_MAKE_TAG('m', 'e', 'd', '2'), MediProperty },
-    { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
-    { HB_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty },
-    { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty },
-    { HB_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty },
-    { HB_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty },
-    {0, 0}
-};
-
-static HB_Bool arabicSyriacOpenTypeShape(HB_ShaperItem *item, HB_Bool *ot_ok)
-{
-    const HB_UChar16 *uc;
-    const int nglyphs = item->num_glyphs;
-    hb_int32 f;
-    hb_uint32 l;
-    HB_ArabicProperties *properties;
-    HB_DECLARE_STACKARRAY(HB_ArabicProperties, props)
-    HB_DECLARE_STACKARRAY(hb_uint32, apply)
-    HB_Bool shaped;
-    int i = 0;
-
-    *ot_ok = TRUE;
-
-    if (!HB_ConvertStringToGlyphIndices(item))
-        return FALSE;
-    HB_HeuristicSetGlyphAttributes(item);
-
-    HB_INIT_STACKARRAY(HB_ArabicProperties, props, item->item.length + 2);
-    HB_INIT_STACKARRAY(hb_uint32, apply, item->num_glyphs);
-
-    uc = item->string + item->item.pos;
-
-    properties = props;
-    f = 0;
-    l = item->item.length;
-    if (item->item.pos > 0) {
-        --f;
-        ++l;
-        ++properties;
-    }
-    if (f + l + item->item.pos < item->stringLength) {
-        ++l;
-    }
-    if (item->item.script == HB_Script_Nko)
-        getNkoProperties(uc+f, l, props);
-    else
-        getArabicProperties(uc+f, l, props);
-
-    for (i = 0; i < (int)item->num_glyphs; i++) {
-        apply[i] = 0;
-
-        if (properties[i].shape == XIsolated)
-            apply[i] |= MediProperty|FinaProperty|InitProperty;
-        else if (properties[i].shape == XMedial)
-            apply[i] |= IsolProperty|FinaProperty|InitProperty;
-        else if (properties[i].shape == XFinal)
-            apply[i] |= IsolProperty|MediProperty|InitProperty;
-        else if (properties[i].shape == XInitial)
-            apply[i] |= IsolProperty|MediProperty|FinaProperty;
-
-        item->attributes[i].justification = properties[i].justification;
-    }
-
-    HB_FREE_STACKARRAY(props);
-
-    shaped = HB_OpenTypeShape(item, apply);
-
-    HB_FREE_STACKARRAY(apply);
-
-    if (!shaped) {
-        *ot_ok = FALSE;
-        return FALSE;
-    }
-    return HB_OpenTypePosition(item, nglyphs, /*doLogClusters*/TRUE);
-}
-
-#endif
-
-/* #### stil missing: identify invalid character combinations */
-HB_Bool HB_ArabicShape(HB_ShaperItem *item)
-{
-    int slen;
-    HB_Bool haveGlyphs;
-    HB_STACKARRAY(HB_UChar16, shapedChars, item->item.length);
-
-    assert(item->item.script == HB_Script_Arabic || item->item.script == HB_Script_Syriac
-           || item->item.script == HB_Script_Nko);
-
-    item->shaperFlags |= HB_ShaperFlag_ForceMarksToZeroWidth;
-#ifndef NO_OPENTYPE
-
-    if (HB_SelectScript(item, item->item.script == HB_Script_Arabic ? arabic_features : syriac_features)) {
-        HB_Bool ot_ok;
-        if (arabicSyriacOpenTypeShape(item, &ot_ok))
-            return TRUE;
-        if (ot_ok)
-            return FALSE;
-            /* fall through to the non OT code*/
-    }
-#endif
-
-    if (item->item.script != HB_Script_Arabic)
-        return HB_BasicShape(item);
-
-    shapedString(item->string, item->stringLength, item->item.pos, item->item.length, shapedChars, &slen,
-                  item->item.bidiLevel % 2,
-                  item->attributes, item->log_clusters);
-
-    haveGlyphs = item->font->klass
-        ->convertStringToGlyphIndices(item->font,
-                                      shapedChars, slen,
-                                      item->glyphs, &item->num_glyphs,
-                                      item->item.bidiLevel % 2);
-
-    HB_FREE_STACKARRAY(shapedChars);
-
-    if (!haveGlyphs)
-        return FALSE;
-
-    HB_HeuristicPosition(item);
-    return TRUE;
-}
-
-
diff --git a/third_party/harfbuzz/src/harfbuzz-buffer-private.h b/third_party/harfbuzz/src/harfbuzz-buffer-private.h
deleted file mode 100644
index 5065f2e..0000000
--- a/third_party/harfbuzz/src/harfbuzz-buffer-private.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2004,2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#ifndef HARFBUZZ_BUFFER_PRIVATE_H
-#define HARFBUZZ_BUFFER_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-buffer.h"
-
-HB_BEGIN_HEADER
-
-#define HB_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
-
-HB_INTERNAL void
-_hb_buffer_swap( HB_Buffer buffer );
-
-HB_INTERNAL void
-_hb_buffer_clear_output( HB_Buffer buffer );
-
-HB_INTERNAL HB_Error
-_hb_buffer_clear_positions( HB_Buffer buffer );
-
-HB_INTERNAL HB_Error
-_hb_buffer_add_output_glyphs( HB_Buffer  buffer,
-			      HB_UShort  num_in,
-			      HB_UShort  num_out,
-			      HB_UShort *glyph_data,
-			      HB_UShort  component,
-			      HB_UShort  ligID );
-
-HB_INTERNAL HB_Error
-_hb_buffer_add_output_glyph ( HB_Buffer buffer,
-			      HB_UInt   glyph_index,
-			      HB_UShort component,
-			      HB_UShort ligID );
-
-HB_INTERNAL HB_Error
-_hb_buffer_copy_output_glyph ( HB_Buffer buffer );
-
-HB_INTERNAL HB_Error
-_hb_buffer_replace_output_glyph ( HB_Buffer buffer,
-				  HB_UInt   glyph_index,
-				  HB_Bool   inplace );
-
-HB_INTERNAL HB_UShort
-_hb_buffer_allocate_ligid( HB_Buffer buffer );
-
-
-/* convenience macros */
-
-#define IN_GLYPH( pos )        (buffer->in_string[(pos)].gindex)
-#define IN_ITEM( pos )         (&buffer->in_string[(pos)])
-#define IN_CURGLYPH()          (buffer->in_string[buffer->in_pos].gindex)
-#define IN_CURITEM()           (&buffer->in_string[buffer->in_pos])
-#define IN_PROPERTIES( pos )   (buffer->in_string[(pos)].properties)
-#define IN_LIGID( pos )        (buffer->in_string[(pos)].ligID)
-#define IN_COMPONENT( pos )    (buffer->in_string[(pos)].component)
-#define POSITION( pos )        (&buffer->positions[(pos)])
-#define OUT_GLYPH( pos )       (buffer->out_string[(pos)].gindex)
-#define OUT_ITEM( pos )        (&buffer->out_string[(pos)])
-
-#define CHECK_Property( gdef, index, flags, property )					\
-          ( ( error = _HB_GDEF_Check_Property( (gdef), (index), (flags),		\
-                                      (property) ) ) != HB_Err_Ok )
-
-#define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID )             \
-          ( ( error = _hb_buffer_add_output_glyphs( (buffer),                            \
-						    (num_in), (num_out),                \
-                                                    (glyph_data), (component), (ligID)  \
-                                                  ) ) != HB_Err_Ok )
-#define ADD_Glyph( buffer, glyph_index, component, ligID )				\
-          ( ( error = _hb_buffer_add_output_glyph( (buffer),                             \
-                                                    (glyph_index), (component), (ligID) \
-                                                  ) ) != HB_Err_Ok )
-#define REPLACE_Glyph( buffer, glyph_index, nesting_level )				\
-          ( ( error = _hb_buffer_replace_output_glyph( (buffer), (glyph_index),		\
-						      (nesting_level) == 1 ) ) != HB_Err_Ok )
-#define COPY_Glyph( buffer )								\
-	  ( (error = _hb_buffer_copy_output_glyph ( buffer ) ) != HB_Err_Ok )
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_BUFFER_PRIVATE_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-buffer.c b/third_party/harfbuzz/src/harfbuzz-buffer.c
deleted file mode 100644
index 4d4c167..0000000
--- a/third_party/harfbuzz/src/harfbuzz-buffer.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2004,2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-buffer-private.h"
-#include "harfbuzz-gsub-private.h"
-#include "harfbuzz-gpos-private.h"
-
-/* Here is how the buffer works internally:
- *
- * There are two string pointers: in_string and out_string.  They
- * always have same allocated size, but different length and positions.
- *
- * As an optimization, both in_string and out_string may point to the
- * same piece of memory, which is owned by in_string.  This remains the
- * case as long as:
- *
- *   - copy_glyph() is called
- *   - replace_glyph() is called with inplace=TRUE
- *   - add_output_glyph() and add_output_glyphs() are not called
- *
- * In that case swap(), and copy_glyph(), and replace_glyph() are all
- * mostly no-op.
- *
- * As soon an add_output_glyph[s]() or replace_glyph() with inplace=FALSE is
- * called, out_string is moved over to an alternate buffer (alt_string), and
- * its current contents (out_length entries) are copied to the alt buffer.
- * This should all remain transparent to the user.  swap() then switches
- * in_string and alt_string.  alt_string is not allocated until its needed,
- * but after that it's grown with in_string unconditionally.
- *
- * The buffer->separate_out boolean keeps status of whether out_string points
- * to in_string (FALSE) or alt_string (TRUE).
- */
-
-/* Internal API */
-
-static HB_Error
-hb_buffer_ensure( HB_Buffer buffer,
-		   HB_UInt   size )
-{
-  HB_UInt new_allocated = buffer->allocated;
-
-  if (size > new_allocated)
-    {
-      HB_Error error;
-
-      while (size > new_allocated)
-	new_allocated += (new_allocated >> 1) + 8;
-      
-      if ( buffer->positions )
-        {
-	  if ( REALLOC_ARRAY( buffer->positions, new_allocated, HB_PositionRec ) )
-	    return error;
-	}
-
-      if ( REALLOC_ARRAY( buffer->in_string, new_allocated, HB_GlyphItemRec ) )
-	return error;
-
-      if ( buffer->separate_out )
-        {
-	  if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) )
-	    return error;
-
-	  buffer->out_string = buffer->alt_string;
-	}
-      else
-        {
-	  buffer->out_string = buffer->in_string;
-
-	  if ( buffer->alt_string )
-	    {
-	      if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) )
-		return error;
-	    }
-	}
-
-      buffer->allocated = new_allocated;
-    }
-
-  return HB_Err_Ok;
-}
-
-static HB_Error
-hb_buffer_duplicate_out_buffer( HB_Buffer buffer )
-{
-  if ( !buffer->alt_string )
-    {
-      HB_Error error;
-
-      if ( ALLOC_ARRAY( buffer->alt_string, buffer->allocated, HB_GlyphItemRec ) )
-	return error;
-    }
-
-  buffer->out_string = buffer->alt_string;
-  memcpy( buffer->out_string, buffer->in_string, buffer->out_length * sizeof (buffer->out_string[0]) );
-  buffer->separate_out = TRUE;
-
-  return HB_Err_Ok;
-}
-
-/* Public API */
-
-HB_Error
-hb_buffer_new( HB_Buffer *pbuffer )
-{
-  HB_Buffer buffer;
-  HB_Error error;
-
-  if ( ALLOC( buffer, sizeof( HB_BufferRec ) ) )
-    return error;
-
-  buffer->allocated = 0;
-  buffer->in_string = NULL;
-  buffer->alt_string = NULL;
-  buffer->positions = NULL;
-
-  hb_buffer_clear( buffer );
-
-  *pbuffer = buffer;
-
-  return HB_Err_Ok;
-}
-
-void
-hb_buffer_free( HB_Buffer buffer )
-{
-  FREE( buffer->in_string );
-  FREE( buffer->alt_string );
-  buffer->out_string = NULL;
-  FREE( buffer->positions );
-  FREE( buffer );
-}
-
-void
-hb_buffer_clear( HB_Buffer buffer )
-{
-  buffer->in_length = 0;
-  buffer->out_length = 0;
-  buffer->in_pos = 0;
-  buffer->out_pos = 0;
-  buffer->out_string = buffer->in_string;
-  buffer->separate_out = FALSE;
-  buffer->max_ligID = 0;
-}
-
-HB_Error
-hb_buffer_add_glyph( HB_Buffer buffer,
-		      HB_UInt   glyph_index,
-		      HB_UInt   properties,
-		      HB_UInt   cluster )
-{
-  HB_Error error;
-  HB_GlyphItem glyph;
-  
-  error = hb_buffer_ensure( buffer, buffer->in_length + 1 );
-  if ( error )
-    return error;
-
-  glyph = &buffer->in_string[buffer->in_length];
-  glyph->gindex = glyph_index;
-  glyph->properties = properties;
-  glyph->cluster = cluster;
-  glyph->component = 0;
-  glyph->ligID = 0;
-  glyph->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
-  
-  buffer->in_length++;
-
-  return HB_Err_Ok;
-}
-
-/* HarfBuzz-Internal API */
-
-HB_INTERNAL void
-_hb_buffer_clear_output( HB_Buffer buffer )
-{
-  buffer->out_length = 0;
-  buffer->out_pos = 0;
-  buffer->out_string = buffer->in_string;
-  buffer->separate_out = FALSE;
-}
-
-HB_INTERNAL HB_Error
-_hb_buffer_clear_positions( HB_Buffer buffer )
-{
-  if ( !buffer->positions )
-    {
-      HB_Error error;
-
-      if ( ALLOC_ARRAY( buffer->positions, buffer->allocated, HB_PositionRec ) )
-	return error;
-    }
-
-  memset (buffer->positions, 0, sizeof (buffer->positions[0]) * buffer->in_length);
-
-  return HB_Err_Ok;
-}
-
-HB_INTERNAL void
-_hb_buffer_swap( HB_Buffer buffer )
-{
-  HB_GlyphItem tmp_string;
-  int tmp_length;
-  int tmp_pos;
-
-  if ( buffer->separate_out )
-    {
-      tmp_string = buffer->in_string;
-      buffer->in_string = buffer->out_string;
-      buffer->out_string = tmp_string;
-      buffer->alt_string = buffer->out_string;
-    }
-
-  tmp_length = buffer->in_length;
-  buffer->in_length = buffer->out_length;
-  buffer->out_length = tmp_length;
-
-  tmp_pos = buffer->in_pos;
-  buffer->in_pos = buffer->out_pos;
-  buffer->out_pos = tmp_pos;
-}
-
-/* The following function copies `num_out' elements from `glyph_data'
-   to `buffer->out_string', advancing the in array pointer in the structure
-   by `num_in' elements, and the out array pointer by `num_out' elements.
-   Finally, it sets the `length' field of `out' equal to
-   `pos' of the `out' structure.
-
-   If `component' is 0xFFFF, the component value from buffer->in_pos
-   will copied `num_out' times, otherwise `component' itself will
-   be used to fill the `component' fields.
-
-   If `ligID' is 0xFFFF, the ligID value from buffer->in_pos
-   will copied `num_out' times, otherwise `ligID' itself will
-   be used to fill the `ligID' fields.
-
-   The properties for all replacement glyphs are taken
-   from the glyph at position `buffer->in_pos'.
-
-   The cluster value for the glyph at position buffer->in_pos is used
-   for all replacement glyphs */
-HB_INTERNAL HB_Error
-_hb_buffer_add_output_glyphs( HB_Buffer  buffer,
-			      HB_UShort  num_in,
-			      HB_UShort  num_out,
-			      HB_UShort *glyph_data,
-			      HB_UShort  component,
-			      HB_UShort  ligID )
-{
-  HB_Error  error;
-  HB_UShort i;
-  HB_UInt properties;
-  HB_UInt cluster;
-
-  error = hb_buffer_ensure( buffer, buffer->out_pos + num_out );
-  if ( error )
-    return error;
-
-  if ( !buffer->separate_out )
-    {
-      error = hb_buffer_duplicate_out_buffer( buffer );
-      if ( error )
-	return error;
-    }
-
-  properties = buffer->in_string[buffer->in_pos].properties;
-  cluster = buffer->in_string[buffer->in_pos].cluster;
-  if ( component == 0xFFFF )
-    component = buffer->in_string[buffer->in_pos].component;
-  if ( ligID == 0xFFFF )
-    ligID = buffer->in_string[buffer->in_pos].ligID;
-
-  for ( i = 0; i < num_out; i++ )
-  {
-    HB_GlyphItem item = &buffer->out_string[buffer->out_pos + i];
-
-    item->gindex = glyph_data[i];
-    item->properties = properties;
-    item->cluster = cluster;
-    item->component = component;
-    item->ligID = ligID;
-    item->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
-  }
-
-  buffer->in_pos  += num_in;
-  buffer->out_pos += num_out;
-
-  buffer->out_length = buffer->out_pos;
-
-  return HB_Err_Ok;
-}
-
-HB_INTERNAL HB_Error
-_hb_buffer_add_output_glyph( HB_Buffer buffer,
-			     HB_UInt   glyph_index,
-			     HB_UShort component,
-			     HB_UShort ligID )
-{
-  HB_UShort glyph_data =  glyph_index;
-
-  return _hb_buffer_add_output_glyphs ( buffer, 1, 1,
-					&glyph_data, component, ligID );
-}
-
-HB_INTERNAL HB_Error
-_hb_buffer_copy_output_glyph ( HB_Buffer buffer )
-{  
-  HB_Error  error;
-
-  error = hb_buffer_ensure( buffer, buffer->out_pos + 1 );
-  if ( error )
-    return error;
-  
-  if ( buffer->separate_out )
-    {
-      buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos];
-    }
-
-  buffer->in_pos++;
-  buffer->out_pos++;
-  buffer->out_length = buffer->out_pos;
-
-  return HB_Err_Ok;
-}
-
-HB_INTERNAL HB_Error
-_hb_buffer_replace_output_glyph( HB_Buffer buffer,
-				 HB_UInt   glyph_index,
-				 HB_Bool   inplace )
-{
-
-  HB_Error error;
-
-  if ( inplace )
-    {
-      error = _hb_buffer_copy_output_glyph ( buffer );
-      if ( error )
-	return error;
-
-      buffer->out_string[buffer->out_pos-1].gindex = glyph_index;
-    }
-  else
-    {
-      return _hb_buffer_add_output_glyph( buffer, glyph_index, 0xFFFF, 0xFFFF );
-    }
-
-  return HB_Err_Ok;
-}
-
-HB_INTERNAL HB_UShort
-_hb_buffer_allocate_ligid( HB_Buffer buffer )
-{
-  buffer->max_ligID++;
-  if (HB_UNLIKELY (buffer->max_ligID == 0))
-    buffer->max_ligID++;
-
-  return buffer->max_ligID;
-}
diff --git a/third_party/harfbuzz/src/harfbuzz-buffer.h b/third_party/harfbuzz/src/harfbuzz-buffer.h
deleted file mode 100644
index b134407..0000000
--- a/third_party/harfbuzz/src/harfbuzz-buffer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2004,2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#ifndef HARFBUZZ_BUFFER_H
-#define HARFBUZZ_BUFFER_H
-
-#include "harfbuzz-global.h"
-
-HB_BEGIN_HEADER
-
-typedef struct HB_GlyphItemRec_ {
-  HB_UInt     gindex;
-  HB_UInt     properties;
-  HB_UInt     cluster;
-  HB_UShort   component;
-  HB_UShort   ligID;
-  HB_UShort   gproperties;
-} HB_GlyphItemRec, *HB_GlyphItem;
-
-typedef struct HB_PositionRec_ {
-  HB_Fixed   x_pos;
-  HB_Fixed   y_pos;
-  HB_Fixed   x_advance;
-  HB_Fixed   y_advance;
-  HB_UShort  back;            /* number of glyphs to go back
-				 for drawing current glyph   */
-  HB_Bool    new_advance;     /* if set, the advance width values are
-				 absolute, i.e., they won't be
-				 added to the original glyph's value
-				 but rather replace them.            */
-  HB_Short  cursive_chain;   /* character to which this connects,
-				 may be positive or negative; used
-				 only internally                     */
-} HB_PositionRec, *HB_Position;
-
-
-typedef struct HB_BufferRec_{ 
-  HB_UInt    allocated;
-
-  HB_UInt    in_length;
-  HB_UInt    out_length;
-  HB_UInt    in_pos;
-  HB_UInt    out_pos;
-  
-  HB_Bool       separate_out;
-  HB_GlyphItem  in_string;
-  HB_GlyphItem  out_string;
-  HB_GlyphItem  alt_string;
-  HB_Position   positions;
-  HB_UShort      max_ligID;
-} HB_BufferRec, *HB_Buffer;
-
-HB_Error
-hb_buffer_new( HB_Buffer *buffer );
-
-void
-hb_buffer_free( HB_Buffer buffer );
-
-void
-hb_buffer_clear( HB_Buffer buffer );
-
-HB_Error
-hb_buffer_add_glyph( HB_Buffer buffer,
-		      HB_UInt    glyph_index,
-		      HB_UInt    properties,
-		      HB_UInt    cluster );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_BUFFER_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-dump-main.c b/third_party/harfbuzz/src/harfbuzz-dump-main.c
deleted file mode 100644
index dfb35fb..0000000
--- a/third_party/harfbuzz/src/harfbuzz-dump-main.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2000  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "harfbuzz.h"
-#include "harfbuzz-dump.h"
-
-#define N_ELEMENTS(arr) (sizeof(arr)/ sizeof((arr)[0]))
-
-static int
-croak (const char *situation, HB_Error error)
-{
-  fprintf (stderr, "%s: Error %d\n", situation, error);
-
-  exit (1);
-}
-
-int 
-main (int argc, char **argv)
-{
-  HB_Error error;
-  FT_Library library;
-  HB_Font font;
-  HB_GSUB gsub;
-  HB_GPOS gpos;
-
-  if (argc != 2)
-    {
-      fprintf (stderr, "Usage: harfbuzz-dump MYFONT.TTF\n");
-      exit(1);
-    }
-
-  if ((error = FT_Init_FreeType (&library)))
-    croak ("FT_Init_FreeType", error);
-
-  if ((error = FT_New_Face (library, argv[1], 0, &font)))
-    croak ("FT_New_Face", error);
-
-  printf ("<?xml version=\"1.0\"?>\n");
-  printf ("<OpenType>\n");
-
-  if (!(error = HB_Load_GSUB_Table (font, &gsub, NULL)))
-    {
-      HB_Dump_GSUB_Table (gsub, stdout);
-      
-      if ((error = HB_Done_GSUB_Table (gsub)))
-	croak ("HB_Done_GSUB_Table", error);
-    }
-  else if (error != HB_Err_Not_Covered)
-    fprintf (stderr, "HB_Load_GSUB_Table: error 0x%x\n", error);
-
-  if (!(error = HB_Load_GPOS_Table (font, &gpos, NULL)))
-    {
-      HB_Dump_GPOS_Table (gpos, stdout);
-      
-      if ((error = HB_Done_GPOS_Table (gpos)))
-	croak ("HB_Done_GPOS_Table", error);
-    }
-  else if (error != HB_Err_Not_Covered)
-    fprintf (stderr, "HB_Load_GPOS_Table: error 0x%x\n", error);
-
-  printf ("</OpenType>\n");
-
-  if ((error = FT_Done_Face (font)))
-    croak ("FT_Done_Face", error);
-
-  if ((error = FT_Done_FreeType (library)))
-    croak ("FT_Done_FreeType", error);
-  
-  return 0;
-}
-
diff --git a/third_party/harfbuzz/src/harfbuzz-dump.c b/third_party/harfbuzz/src/harfbuzz-dump.c
deleted file mode 100644
index 8c81da1..0000000
--- a/third_party/harfbuzz/src/harfbuzz-dump.c
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
- * Copyright (C) 2000, 2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-dump.h"
-#include "harfbuzz-gdef-private.h"
-#include "harfbuzz-gsub-private.h"
-#include "harfbuzz-gpos-private.h"
-#include "harfbuzz-open-private.h"
-#include <stdarg.h>
-
-#define DUMP(format) dump (stream, indent, format)
-#define DUMP1(format, arg1) dump (stream, indent, format, arg1)
-#define DUMP2(format, arg1, arg2) dump (stream, indent, format, arg1, arg2)
-#define DUMP3(format, arg1, arg2, arg3) dump (stream, indent, format, arg1, arg2, arg3)
-
-#define DUMP_FINT(strct,fld) dump (stream, indent, "<" #fld ">%d</" #fld ">\n", (strct)->fld)
-#define DUMP_FUINT(strct,fld) dump (stream, indent, "<" #fld ">%u</" #fld ">\n", (strct)->fld)
-#define DUMP_FGLYPH(strct,fld) dump (stream, indent, "<" #fld ">%#06x</" #fld ">\n", (strct)->fld)
-#define DUMP_FGLYPH(strct,fld) dump (stream, indent, "<" #fld ">%#06x</" #fld ">\n", (strct)->fld)
-#define DUMP_USHORT_ARRAY(strct,fld,cnt) Dump_UShort_Array ((strct)->fld, cnt, #fld, stream, indent);
-
-#define DEF_DUMP(type) static void Dump_ ## type (HB_ ## type *type, FILE *stream, int indent, HB_Type hb_type)
-#define RECURSE(name, type, val) do {  DUMP ("<" #name ">\n"); Dump_ ## type (val, stream, indent + 1, hb_type); DUMP ("</" #name ">\n"); } while (0)
-#define RECURSE_NUM(name, i, type, val) do {  DUMP1 ("<" #name "> <!-- %d -->\n", i); Dump_ ## type (val, stream, indent + 1, hb_type); DUMP ("</" #name ">\n"); } while (0)
-#define DUMP_VALUE_RECORD(val, frmt) do {  DUMP ("<ValueRecord>\n"); Dump_ValueRecord (val, stream, indent + 1, hb_type, frmt); DUMP ("</ValueRecord>\n"); } while (0)
-
-static void
-do_indent (FILE *stream, int indent)
-{
-  fprintf (stream, "%*s", indent * 3, "");
-}
-
-static void
-dump (FILE *stream, int indent, const char *format, ...)
-{
-  va_list list;
-
-  do_indent (stream, indent);
-
-  va_start (list, format);
-  vfprintf (stream, format, list);
-  va_end (list);
-}
-
-static void
-Dump_UShort_Array (HB_UShort *array, int count, const char *name, FILE *stream, int indent)
-{
-  int i;
-
-  do_indent (stream, indent);
-
-  fprintf (stream, "<%s>", name);
-  for (i = 0; i < count; i++)
-    fprintf (stream, "%d%s", array[i], i == 0 ? "" : " ");
-  fprintf (stream, "</%s>\n", name);
-}
-
-static void
-Print_Tag (HB_UInt tag, FILE *stream)
-{
-  fprintf (stream, "%c%c%c%c",
-	   (unsigned char)(tag >> 24),
-	   (unsigned char)((tag >> 16) & 0xff),
-	   (unsigned char)((tag >> 8) & 0xff),
-	   (unsigned char)(tag & 0xff));
-}
-
-DEF_DUMP (LangSys)
-{
-  int i;
-
-  HB_UNUSED(hb_type);
-
-  DUMP_FUINT (LangSys, LookupOrderOffset);
-  DUMP_FUINT (LangSys, ReqFeatureIndex);
-  DUMP_FUINT (LangSys, FeatureCount);
-
-  for (i=0; i < LangSys->FeatureCount; i++)
-    DUMP1("<FeatureIndex>%d</FeatureIndex>\n", LangSys->FeatureIndex[i]);
-}
-
-DEF_DUMP (ScriptTable)
-{
-  int i;
-
-  RECURSE (DefaultLangSys, LangSys, &ScriptTable->DefaultLangSys);
-
-  DUMP_FUINT (ScriptTable, LangSysCount);
-
-  for (i=0; i < ScriptTable->LangSysCount; i++)
-    {
-      do_indent (stream, indent);
-      fprintf (stream, "<LangSysTag>");
-      Print_Tag (ScriptTable->LangSysRecord[i].LangSysTag, stream);
-      fprintf (stream, "</LangSysTag>\n");
-      RECURSE_NUM (LangSys, i, LangSys, &ScriptTable->LangSysRecord[i].LangSys);
-    }
-}
-
-DEF_DUMP (ScriptList)
-{
-  int i;
-
-  DUMP_FUINT (ScriptList, ScriptCount);
-
-  for (i=0; i < ScriptList->ScriptCount; i++)
-    {
-      do_indent (stream, indent);
-      fprintf (stream, "<ScriptTag>");
-      Print_Tag (ScriptList->ScriptRecord[i].ScriptTag, stream);
-      fprintf (stream, "</ScriptTag>\n");
-      RECURSE_NUM (Script, i, ScriptTable, &ScriptList->ScriptRecord[i].Script);
-    }
-}
-
-DEF_DUMP (Feature)
-{
-  int i;
-
-  HB_UNUSED(hb_type);
-
-  DUMP_FUINT (Feature, FeatureParams);
-  DUMP_FUINT (Feature, LookupListCount);
-
-  for (i=0; i < Feature->LookupListCount; i++)
-    DUMP1("<LookupIndex>%d</LookupIndex>\n", Feature->LookupListIndex[i]);
-}
-
-DEF_DUMP (MarkRecord)
-{
-  HB_UNUSED(hb_type);
-
-  DUMP_FUINT (MarkRecord, Class);
-  DUMP1("<Anchor>%d</Anchor>\n", MarkRecord->MarkAnchor.PosFormat );
-}
-
-DEF_DUMP (MarkArray)
-{
-  int i;
-
-  DUMP_FUINT (MarkArray, MarkCount);
-
-  for (i=0; i < MarkArray->MarkCount; i++)
-    RECURSE_NUM (MarkRecord, i, MarkRecord, &MarkArray->MarkRecord[i]);
-}
-
-DEF_DUMP (FeatureList)
-{
-  int i;
-
-  DUMP_FUINT (FeatureList, FeatureCount);
-
-  for (i=0; i < FeatureList->FeatureCount; i++)
-    {
-      do_indent (stream, indent);
-      fprintf (stream, "<FeatureTag>");
-      Print_Tag (FeatureList->FeatureRecord[i].FeatureTag, stream);
-      fprintf (stream, "</FeatureTag> <!-- %d -->\n", i);
-      RECURSE_NUM (Feature, i, Feature, &FeatureList->FeatureRecord[i].Feature);
-    }
-}
-
-DEF_DUMP (Coverage)
-{
-  HB_UNUSED(hb_type);
-
-  DUMP_FUINT (Coverage, CoverageFormat);
-
-  if (Coverage->CoverageFormat == 1)
-    {
-      int i;
-      DUMP_FUINT (&Coverage->cf.cf1, GlyphCount);
-
-      for (i = 0; i < Coverage->cf.cf1.GlyphCount; i++)
-	DUMP2("<Glyph>%#06x</Glyph> <!-- %d -->\n",
-	      Coverage->cf.cf1.GlyphArray[i], i);
-    }
-  else
-    {
-      int i;
-      DUMP_FUINT (&Coverage->cf.cf2, RangeCount);
-
-      for ( i = 0; i < Coverage->cf.cf2.RangeCount; i++ )
-	  DUMP3("<Glyph>%#06x - %#06x</Glyph> <!-- %d -->\n",
-	        Coverage->cf.cf2.RangeRecord[i].Start,
-	        Coverage->cf.cf2.RangeRecord[i].End, i);
-    }
-}
-
-DEF_DUMP (ClassRangeRecord)
-{
-  HB_UNUSED(hb_type);
-
-  DUMP_FGLYPH (ClassRangeRecord, Start);
-  DUMP_FGLYPH (ClassRangeRecord, End);
-  DUMP_FUINT (ClassRangeRecord, Class);
-}
-
-DEF_DUMP (ClassDefinition)
-{
-  HB_UNUSED(hb_type);
-
-  DUMP_FUINT( ClassDefinition, ClassFormat);
-  DUMP_FUINT( ClassDefinition, loaded);
-
-  if (ClassDefinition->ClassFormat == 1)
-    {
-      int i;
-      HB_ClassDefFormat1 *ClassDefFormat1 = &ClassDefinition->cd.cd1;
-      DUMP("<ClassDefinition>\n");
-      DUMP_FUINT (ClassDefFormat1, StartGlyph );
-      DUMP_FUINT (ClassDefFormat1, GlyphCount );
-      for (i = 0; i < ClassDefFormat1->GlyphCount; i++)
-	DUMP2(" <Class>%d</Class> <!-- %#06x -->", ClassDefFormat1->ClassValueArray[i],
-	      ClassDefFormat1->StartGlyph+i );
-    }
-  else if (ClassDefinition->ClassFormat == 2)
-    {
-      int i;
-      HB_ClassDefFormat2 *ClassDefFormat2 = &ClassDefinition->cd.cd2;
-      DUMP_FUINT (ClassDefFormat2, ClassRangeCount);
-
-      for (i = 0; i < ClassDefFormat2->ClassRangeCount; i++)
-	RECURSE_NUM (ClassRangeRecord, i, ClassRangeRecord, &ClassDefFormat2->ClassRangeRecord[i]);
-    }
-  else
-    fprintf(stderr, "invalid class def table!!!\n");
-}
-
-DEF_DUMP (SubstLookupRecord)
-{
-  HB_UNUSED(hb_type);
-
-  DUMP_FUINT (SubstLookupRecord, SequenceIndex);
-  DUMP_FUINT (SubstLookupRecord, LookupListIndex);
-}
-
-DEF_DUMP (ChainSubClassRule)
-{
-  int i;
-
-  DUMP_USHORT_ARRAY (ChainSubClassRule, Backtrack, ChainSubClassRule->BacktrackGlyphCount);
-  DUMP_USHORT_ARRAY (ChainSubClassRule, Input, ChainSubClassRule->InputGlyphCount - 1);
-  DUMP_USHORT_ARRAY (ChainSubClassRule, Lookahead, ChainSubClassRule->LookaheadGlyphCount);
-
-  for (i = 0; i < ChainSubClassRule->SubstCount; i++)
-    RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainSubClassRule->SubstLookupRecord[i]);
-
-  indent--;
-}
-
-DEF_DUMP (ChainSubClassSet)
-{
-  int i;
-
-  DUMP_FUINT( ChainSubClassSet, ChainSubClassRuleCount );
-  for (i = 0; i < ChainSubClassSet->ChainSubClassRuleCount; i++)
-    RECURSE_NUM (ChainSubClassRule, i, ChainSubClassRule, &ChainSubClassSet->ChainSubClassRule[i]);
-}
-
-static void
-Dump_GSUB_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
-  HB_SingleSubst *SingleSubst = &subtable->st.gsub.single;
-
-  DUMP_FUINT (SingleSubst, SubstFormat);
-  RECURSE (Coverage, Coverage, &SingleSubst->Coverage);
-
-  if (SingleSubst->SubstFormat == 1)
-    {
-      DUMP_FINT (&SingleSubst->ssf.ssf1, DeltaGlyphID);
-    }
-  else
-    {
-      int i;
-
-      DUMP_FINT (&SingleSubst->ssf.ssf2, GlyphCount);
-      for (i=0; i < SingleSubst->ssf.ssf2.GlyphCount; i++)
-	DUMP2("<Substitute>%#06x</Substitute> <!-- %d -->\n", SingleSubst->ssf.ssf2.Substitute[i], i);
-    }
-}
-
-DEF_DUMP (Ligature)
-{
-  int i;
-
-  HB_UNUSED(hb_type);
-
-  DUMP_FGLYPH (Ligature, LigGlyph);
-  DUMP_FUINT (Ligature, ComponentCount);
-
-  for (i=0; i < Ligature->ComponentCount - 1; i++)
-    DUMP1("<Component>%#06x</Component>\n", Ligature->Component[i]);
-}
-
-DEF_DUMP (LigatureSet)
-{
-  int i;
-
-  DUMP_FUINT (LigatureSet, LigatureCount);
-
-  for (i=0; i < LigatureSet->LigatureCount; i++)
-    RECURSE_NUM (Ligature, i, Ligature, &LigatureSet->Ligature[i]);
-}
-
-static void
-Dump_GSUB_Lookup_Ligature (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
-  int i;
-  HB_LigatureSubst *LigatureSubst = &subtable->st.gsub.ligature;
-
-  DUMP_FUINT (LigatureSubst, SubstFormat);
-  RECURSE (Coverage, Coverage, &LigatureSubst->Coverage);
-
-  DUMP_FUINT (LigatureSubst, LigatureSetCount);
-
-  for (i=0; i < LigatureSubst->LigatureSetCount; i++)
-    RECURSE_NUM (LigatureSet, i, LigatureSet, &LigatureSubst->LigatureSet[i]);
-}
-
-DEF_DUMP (ContextSubstFormat1)
-{
-  HB_UNUSED(hb_type);
-  HB_UNUSED(ContextSubstFormat1);
-
-
-  DUMP("<!-- Not implemented!!! -->\n");
-}
-
-DEF_DUMP (ContextSubstFormat2)
-{
-  DUMP_FUINT (ContextSubstFormat2, MaxContextLength);
-  RECURSE (Coverage, Coverage, &ContextSubstFormat2->Coverage);
-  RECURSE (ClassDefinition, ClassDefinition, &ContextSubstFormat2->ClassDef);
-}
-
-DEF_DUMP (ContextSubstFormat3)
-{
-  HB_UNUSED(hb_type);
-  HB_UNUSED(ContextSubstFormat3);
-
-  DUMP("<!-- Not implemented!!! -->\n");
-}
-
-static void
-Dump_GSUB_Lookup_Context (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
-  HB_ContextSubst *ContextSubst = &subtable->st.gsub.context;
-
-  DUMP_FUINT (ContextSubst, SubstFormat);
-  switch( ContextSubst->SubstFormat )
-    {
-    case 1:
-      Dump_ContextSubstFormat1 (&ContextSubst->csf.csf1, stream, indent+2, hb_type);
-      break;
-    case 2:
-      Dump_ContextSubstFormat2 (&ContextSubst->csf.csf2, stream, indent+2, hb_type);
-      break;
-    case 3:
-      Dump_ContextSubstFormat3 (&ContextSubst->csf.csf3, stream, indent+2, hb_type);
-      break;
-    default:
-      fprintf(stderr, "invalid subformat!!!!!\n");
-    }
-}
-
-DEF_DUMP (ChainContextSubstFormat1)
-{
-  HB_UNUSED(hb_type);
-  HB_UNUSED(ChainContextSubstFormat1);
-
-  DUMP("<!-- Not implemented!!! -->\n");
-}
-
-DEF_DUMP (ChainContextSubstFormat2)
-{
-  int i;
-
-  RECURSE (Coverage, Coverage, &ChainContextSubstFormat2->Coverage);
-  DUMP_FUINT (ChainContextSubstFormat2, MaxBacktrackLength);
-  RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->BacktrackClassDef);
-  DUMP_FUINT (ChainContextSubstFormat2, MaxInputLength);
-  RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->InputClassDef);
-  DUMP_FUINT (ChainContextSubstFormat2, MaxLookaheadLength);
-  RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->LookaheadClassDef);
-
-  DUMP_FUINT (ChainContextSubstFormat2, ChainSubClassSetCount);
-  for (i = 0; i < ChainContextSubstFormat2->ChainSubClassSetCount; i++)
-    RECURSE (ChainSubClassSet, ChainSubClassSet, &ChainContextSubstFormat2->ChainSubClassSet[i]);
-}
-
-DEF_DUMP (ChainContextSubstFormat3)
-{
-  int i;
-
-  DUMP_FUINT (ChainContextSubstFormat3, BacktrackGlyphCount);
-  for (i = 0; i < ChainContextSubstFormat3->BacktrackGlyphCount; i++)
-    RECURSE (BacktrackCoverage, Coverage, &ChainContextSubstFormat3->BacktrackCoverage[i]);
-  DUMP_FUINT (ChainContextSubstFormat3, InputGlyphCount);
-  for (i = 0; i < ChainContextSubstFormat3->InputGlyphCount; i++)
-    RECURSE (InputCoverage, Coverage, &ChainContextSubstFormat3->InputCoverage[i]);
-  DUMP_FUINT (ChainContextSubstFormat3, LookaheadGlyphCount);
-  for (i = 0; i < ChainContextSubstFormat3->LookaheadGlyphCount; i++)
-    RECURSE (LookaheadCoverage, Coverage, &ChainContextSubstFormat3->LookaheadCoverage[i]);
-
-  for (i = 0; i < ChainContextSubstFormat3->SubstCount; i++)
-    RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainContextSubstFormat3->SubstLookupRecord[i]);
-
-}
-
-static void
-Dump_GSUB_Lookup_Chain (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
-  HB_ChainContextSubst *chain = &subtable->st.gsub.chain;
-
-  DUMP_FUINT (chain, SubstFormat);
-  switch (chain->SubstFormat)
-    {
-    case 1:
-      Dump_ChainContextSubstFormat1 (&chain->ccsf.ccsf1, stream, indent+2, hb_type);
-      break;
-    case 2:
-      Dump_ChainContextSubstFormat2 (&chain->ccsf.ccsf2, stream, indent+2, hb_type);
-      break;
-    case 3:
-      Dump_ChainContextSubstFormat3 (&chain->ccsf.ccsf3, stream, indent+2, hb_type);
-      break;
-    default:
-      fprintf(stderr, "invalid subformat!!!!!\n");
-    }
-}
-
-static void
-Dump_Device (HB_Device *Device, FILE *stream, int indent, HB_Type hb_type)
-{
-  int i;
-  int bits;
-  int n_per;
-  unsigned int mask;
-
-  HB_UNUSED(hb_type);
-
-  DUMP_FUINT (Device, StartSize);
-  DUMP_FUINT (Device, EndSize);
-  DUMP_FUINT (Device, DeltaFormat);
-  switch (Device->DeltaFormat)
-    {
-    case 1:
-      bits = 2;
-      break;
-    case 2:
-      bits = 4;
-      break;
-    case 3:
-      bits = 8;
-      break;
-    default:
-      bits = 0;
-      break;
-    }
-
-  DUMP ("<DeltaValue>");
-  if (!bits)
-    {
-
-      fprintf(stderr, "invalid DeltaFormat!!!!!\n");
-    }
-  else
-    {
-      n_per = 16 / bits;
-      mask = (1 << bits) - 1;
-      mask = mask << (16 - bits);
-
-      for (i = Device->StartSize; i <= Device->EndSize ; i++)
-	{
-	  HB_UShort val = Device->DeltaValue[i / n_per];
-	  HB_Short signed_val = ((val << ((i % n_per) * bits)) & mask);
-	  dump (stream, indent, "%d", signed_val >> (16 - bits));
-	  if (i != Device->EndSize)
-	    DUMP (", ");
-	}
-    }
-  DUMP ("</DeltaValue>\n");
-}
-
-static void
-Dump_ValueRecord (HB_ValueRecord *ValueRecord, FILE *stream, int indent, HB_Type hb_type, HB_UShort value_format)
-{
-  if (value_format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT)
-    DUMP_FINT (ValueRecord, XPlacement);
-  if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT)
-    DUMP_FINT (ValueRecord, YPlacement);
-  if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE)
-    DUMP_FINT (ValueRecord, XAdvance);
-  if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE)
-    DUMP_FINT (ValueRecord, XAdvance);
-  if (value_format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE)
-    RECURSE (Device, Device, &ValueRecord->XPlacementDevice);
-  if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE)
-    RECURSE (Device, Device, &ValueRecord->YPlacementDevice);
-  if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE)
-    RECURSE (Device, Device, &ValueRecord->XAdvanceDevice);
-  if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE)
-    RECURSE (Device, Device, &ValueRecord->YAdvanceDevice);
-  if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT)
-    DUMP_FUINT (ValueRecord, XIdPlacement);
-  if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT)
-    DUMP_FUINT (ValueRecord, YIdPlacement);
-  if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE)
-    DUMP_FUINT (ValueRecord, XIdAdvance);
-  if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE)
-    DUMP_FUINT (ValueRecord, XIdAdvance);
-}
-
-static void
-Dump_GPOS_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
-  HB_SinglePos *SinglePos = &subtable->st.gpos.single;
-
-  DUMP_FUINT (SinglePos, PosFormat);
-  RECURSE (Coverage, Coverage, &SinglePos->Coverage);
-
-  DUMP_FUINT (SinglePos, ValueFormat);
-
-  if (SinglePos->PosFormat == 1)
-    {
-      DUMP_VALUE_RECORD (&SinglePos->spf.spf1.Value, SinglePos->ValueFormat);
-    }
-  else
-    {
-      int i;
-
-      DUMP_FUINT (&SinglePos->spf.spf2, ValueCount);
-      for (i = 0; i < SinglePos->spf.spf2.ValueCount; i++)
-	DUMP_VALUE_RECORD (&SinglePos->spf.spf2.Value[i], SinglePos->ValueFormat);
-    }
-}
-
-static void
-Dump_PairValueRecord (HB_PairValueRecord *PairValueRecord, FILE *stream, int indent, HB_Type hb_type, HB_UShort ValueFormat1, HB_UShort ValueFormat2)
-{
-  DUMP_FUINT (PairValueRecord, SecondGlyph);
-  DUMP_VALUE_RECORD (&PairValueRecord->Value1, ValueFormat1);
-  DUMP_VALUE_RECORD (&PairValueRecord->Value2, ValueFormat2);
-}
-
-static void
-Dump_PairSet (HB_PairSet *PairSet, FILE *stream, int indent, HB_Type hb_type, HB_UShort ValueFormat1, HB_UShort ValueFormat2)
-{
-  int i;
-  DUMP_FUINT (PairSet, PairValueCount);
-
-  for (i = 0; i < PairSet->PairValueCount; i++)
-    {
-      DUMP ("<PairValueRecord>\n");
-      Dump_PairValueRecord (&PairSet->PairValueRecord[i], stream, indent + 1, hb_type, ValueFormat1, ValueFormat2);
-      DUMP ("</PairValueRecord>\n");
-    }
-}
-
-static void
-Dump_GPOS_Lookup_Pair (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
-  HB_PairPos *PairPos = &subtable->st.gpos.pair;
-
-  DUMP_FUINT (PairPos, PosFormat);
-  RECURSE (Coverage, Coverage, &PairPos->Coverage);
-
-  DUMP_FUINT (PairPos, ValueFormat1);
-  DUMP_FUINT (PairPos, ValueFormat2);
-
-  if (PairPos->PosFormat == 1)
-    {
-      int i;
-
-      DUMP_FUINT (&PairPos->ppf.ppf1, PairSetCount);
-      for (i = 0; i < PairPos->ppf.ppf1.PairSetCount; i++)
-	{
-	  DUMP ("<PairSet>\n");
-	  Dump_PairSet (&PairPos->ppf.ppf1.PairSet[i], stream, indent + 1, hb_type, PairPos->ValueFormat1, PairPos->ValueFormat2);
-	  DUMP ("</PairSet>\n");
-	}
-    }
-  else
-    {
-    }
-}
-
-static void
-Dump_GPOS_Lookup_Markbase (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
-  int i;
-  HB_MarkBasePos *markbase = &subtable->st.gpos.markbase;
-
-  DUMP_FUINT (markbase, PosFormat);
-  RECURSE (Coverage, Coverage, &markbase->MarkCoverage);
-  RECURSE (Coverage, Coverage, &markbase->BaseCoverage);
-  DUMP_FUINT (markbase, ClassCount);
-  RECURSE (MarkArray, MarkArray, &markbase->MarkArray);
-
-  DUMP ("<BaseArray>\n");
-  indent++;
-
-  DUMP_FUINT (&markbase->BaseArray, BaseCount);
-  for (i = 0; i < markbase->BaseArray.BaseCount; i++)
-    {
-      int j;
-      HB_BaseRecord *r = &markbase->BaseArray.BaseRecord[i];
-      DUMP1 ("<BaseRecord> <!-- %d -->\n",  i);
-      for (j = 0; j < markbase->ClassCount; j++)
-	DUMP1 ("  <Anchor>%d</Anchor>\n", r->BaseAnchor->PosFormat);
-      DUMP ("<BaseRecord>\n");
-    }
-
-  indent--;
-  DUMP ("</BaseArray>\n");
-}
-
-DEF_DUMP (Lookup)
-{
-  int i;
-  const char *lookup_name;
-  void (*lookup_func) (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type) = NULL;
-
-  if (hb_type == HB_Type_GSUB)
-    {
-      switch (Lookup->LookupType)
-	{
-	case  HB_GSUB_LOOKUP_SINGLE:
-	  lookup_name = "SINGLE";
-	  lookup_func = Dump_GSUB_Lookup_Single;
-	  break;
-	case  HB_GSUB_LOOKUP_MULTIPLE:
-	  lookup_name = "MULTIPLE";
-	  break;
-	case  HB_GSUB_LOOKUP_ALTERNATE:
-	  lookup_name = "ALTERNATE";
-	  break;
-	case  HB_GSUB_LOOKUP_LIGATURE:
-	  lookup_name = "LIGATURE";
-	  lookup_func = Dump_GSUB_Lookup_Ligature;
-	  break;
-	case  HB_GSUB_LOOKUP_CONTEXT:
-	  lookup_name = "CONTEXT";
-	  lookup_func = Dump_GSUB_Lookup_Context;
-	  break;
-	case  HB_GSUB_LOOKUP_CHAIN:
-	  lookup_name = "CHAIN";
-	  lookup_func = Dump_GSUB_Lookup_Chain;
-	  break;
-	default:
-	  lookup_name = "(unknown)";
-	  lookup_func = NULL;
-	  break;
-	}
-    }
-  else
-    {
-      switch (Lookup->LookupType)
-	{
-	case HB_GPOS_LOOKUP_SINGLE:
-	  lookup_name = "SINGLE";
-	  lookup_func = Dump_GPOS_Lookup_Single;
-	  break;
-	case HB_GPOS_LOOKUP_PAIR:
-	  lookup_name = "PAIR";
-	  lookup_func = Dump_GPOS_Lookup_Pair;
-	  break;
-	case HB_GPOS_LOOKUP_CURSIVE:
-	  lookup_name = "CURSIVE";
-	  break;
-	case HB_GPOS_LOOKUP_MARKBASE:
-	  lookup_name = "MARKBASE";
-	  lookup_func = Dump_GPOS_Lookup_Markbase;
-	  break;
-	case HB_GPOS_LOOKUP_MARKLIG:
-	  lookup_name = "MARKLIG";
-	  break;
-	case HB_GPOS_LOOKUP_MARKMARK:
-	  lookup_name = "MARKMARK";
-	  break;
-	case HB_GPOS_LOOKUP_CONTEXT:
-	  lookup_name = "CONTEXT";
-	  break;
-	case HB_GPOS_LOOKUP_CHAIN:
-	  lookup_name = "CHAIN";
-	  break;
-	default:
-	  lookup_name = "(unknown)";
-	  lookup_func = NULL;
-	  break;
-	}
-    }
-
-  DUMP2("<LookupType>%s</LookupType> <!-- %d -->\n", lookup_name, Lookup->LookupType);
-  DUMP1("<LookupFlag>%#06x</LookupFlag>\n", Lookup->LookupFlag);
-
-  for (i=0; i < Lookup->SubTableCount; i++)
-    {
-      DUMP ("<Subtable>\n");
-      if (lookup_func)
-	(*lookup_func) (&Lookup->SubTable[i], stream, indent + 1, hb_type);
-      DUMP ("</Subtable>\n");
-    }
-}
-
-DEF_DUMP (LookupList)
-{
-  int i;
-
-  DUMP_FUINT (LookupList, LookupCount);
-
-  for (i=0; i < LookupList->LookupCount; i++)
-    RECURSE_NUM (Lookup, i, Lookup, &LookupList->Lookup[i]);
-}
-
-void
-HB_Dump_GSUB_Table (HB_GSUB gsub, FILE *stream)
-{
-  int indent = 1;
-  HB_Type hb_type = HB_Type_GSUB;
-
-  do_indent (stream, indent);
-  fprintf(stream, "<!-- GSUB -->\n");
-  RECURSE (ScriptList, ScriptList, &gsub->ScriptList);
-  RECURSE (FeatureList, FeatureList, &gsub->FeatureList);
-  RECURSE (LookupList, LookupList, &gsub->LookupList);
-}
-
-void
-HB_Dump_GPOS_Table (HB_GPOS gpos, FILE *stream)
-{
-  int indent = 1;
-  HB_Type hb_type = HB_Type_GPOS;
-
-  do_indent (stream, indent);
-  fprintf(stream, "<!-- GPOS -->\n");
-  RECURSE (ScriptList, ScriptList, &gpos->ScriptList);
-  RECURSE (FeatureList, FeatureList, &gpos->FeatureList);
-  RECURSE (LookupList, LookupList, &gpos->LookupList);
-}
diff --git a/third_party/harfbuzz/src/harfbuzz-dump.h b/third_party/harfbuzz/src/harfbuzz-dump.h
deleted file mode 100644
index ea4a62b..0000000
--- a/third_party/harfbuzz/src/harfbuzz-dump.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2000, 2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#ifndef HARFBUZZ_DUMP_H
-#define HARFBUZZ_DUMP_H
-
-#include <stdio.h>
-#include "harfbuzz-gsub.h"
-#include "harfbuzz-gpos.h"
-
-HB_BEGIN_HEADER
-
-void HB_Dump_GSUB_Table (HB_GSUB gsub, FILE *stream);
-void HB_Dump_GPOS_Table (HB_GPOS gpos, FILE *stream);
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_DUMP_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-external.h b/third_party/harfbuzz/src/harfbuzz-external.h
deleted file mode 100644
index 760749b..0000000
--- a/third_party/harfbuzz/src/harfbuzz-external.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_EXTERNAL_H
-#define HARFBUZZ_EXTERNAL_H
-
-#include "harfbuzz-global.h"
-
-HB_BEGIN_HEADER
-
-/* This header contains some methods that are not part of
-   Harfbuzz itself, but referenced by it.
-   They need to be provided by the application/library
-*/
-
-
-/*
- see http://www.unicode.org/reports/tr14/tr14-19.html
- we don't use the XX, AI and CB properties and map them to AL instead.
- as we don't support any EBDIC based OS'es, NL is ignored and mapped to AL as well.
-*/
-typedef enum {
-    HB_LineBreak_OP, HB_LineBreak_CL, HB_LineBreak_QU, HB_LineBreak_GL, HB_LineBreak_NS,
-    HB_LineBreak_EX, HB_LineBreak_SY, HB_LineBreak_IS, HB_LineBreak_PR, HB_LineBreak_PO,
-    HB_LineBreak_NU, HB_LineBreak_AL, HB_LineBreak_ID, HB_LineBreak_IN, HB_LineBreak_HY,
-    HB_LineBreak_BA, HB_LineBreak_BB, HB_LineBreak_B2, HB_LineBreak_ZW, HB_LineBreak_CM,
-    HB_LineBreak_WJ, HB_LineBreak_H2, HB_LineBreak_H3, HB_LineBreak_JL, HB_LineBreak_JV,
-    HB_LineBreak_JT, HB_LineBreak_SA, HB_LineBreak_SG,
-    HB_LineBreak_SP, HB_LineBreak_CR, HB_LineBreak_LF, HB_LineBreak_BK
-} HB_LineBreakClass;
-
-typedef enum 
-{
-    HB_NoCategory,
-
-    HB_Mark_NonSpacing,          /*   Mn */
-    HB_Mark_SpacingCombining,    /*   Mc */
-    HB_Mark_Enclosing,           /*   Me */
-
-    HB_Number_DecimalDigit,      /*   Nd */
-    HB_Number_Letter,            /*   Nl */
-    HB_Number_Other,             /*   No */
-
-    HB_Separator_Space,          /*   Zs */
-    HB_Separator_Line,           /*   Zl */
-    HB_Separator_Paragraph,      /*   Zp */
-
-    HB_Other_Control,            /*   Cc */
-    HB_Other_Format,             /*   Cf */
-    HB_Other_Surrogate,          /*   Cs */
-    HB_Other_PrivateUse,         /*   Co */
-    HB_Other_NotAssigned,        /*   Cn */
-
-    HB_Letter_Uppercase,         /*   Lu */
-    HB_Letter_Lowercase,         /*   Ll */
-    HB_Letter_Titlecase,         /*   Lt */
-    HB_Letter_Modifier,          /*   Lm */
-    HB_Letter_Other,             /*   Lo */
-
-    HB_Punctuation_Connector,    /*   Pc */
-    HB_Punctuation_Dash,         /*   Pd */
-    HB_Punctuation_Open,         /*   Ps */
-    HB_Punctuation_Close,        /*   Pe */
-    HB_Punctuation_InitialQuote, /*   Pi */
-    HB_Punctuation_FinalQuote,   /*   Pf */
-    HB_Punctuation_Other,        /*   Po */
-
-    HB_Symbol_Math,              /*   Sm */
-    HB_Symbol_Currency,          /*   Sc */
-    HB_Symbol_Modifier,          /*   Sk */
-    HB_Symbol_Other              /*   So */
-} HB_CharCategory;
-
-typedef enum
-{
-    HB_Grapheme_Other, 
-    HB_Grapheme_CR,
-    HB_Grapheme_LF,
-    HB_Grapheme_Control,
-    HB_Grapheme_Extend,
-    HB_Grapheme_L, 
-    HB_Grapheme_V, 
-    HB_Grapheme_T, 
-    HB_Grapheme_LV, 
-    HB_Grapheme_LVT
-} HB_GraphemeClass;
-
-
-typedef enum
-{
-    HB_Word_Other,
-    HB_Word_Format,
-    HB_Word_Katakana,
-    HB_Word_ALetter,
-    HB_Word_MidLetter,
-    HB_Word_MidNum,
-    HB_Word_Numeric,
-    HB_Word_ExtendNumLet
-} HB_WordClass;
-
-
-typedef enum
-{
-    HB_Sentence_Other,
-    HB_Sentence_Sep,
-    HB_Sentence_Format,
-    HB_Sentence_Sp,
-    HB_Sentence_Lower,
-    HB_Sentence_Upper,
-    HB_Sentence_OLetter,
-    HB_Sentence_Numeric,
-    HB_Sentence_ATerm,
-    HB_Sentence_STerm,
-    HB_Sentence_Close
-} HB_SentenceClass;
-
-HB_GraphemeClass HB_GetGraphemeClass(HB_UChar32 ch);
-HB_WordClass HB_GetWordClass(HB_UChar32 ch);
-HB_SentenceClass HB_GetSentenceClass(HB_UChar32 ch);
-HB_LineBreakClass HB_GetLineBreakClass(HB_UChar32 ch);
-
-void HB_GetGraphemeAndLineBreakClass(HB_UChar32 ch, HB_GraphemeClass *grapheme, HB_LineBreakClass *lineBreak);
-void HB_GetUnicodeCharProperties(HB_UChar32 ch, HB_CharCategory *category, int *combiningClass);
-HB_CharCategory HB_GetUnicodeCharCategory(HB_UChar32 ch);
-int HB_GetUnicodeCharCombiningClass(HB_UChar32 ch);
-HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch);
-
-void *HB_Library_Resolve(const char *library, const char *symbol);
-
-void *HB_TextCodecForMib(int mib);
-char *HB_TextCodec_ConvertFromUnicode(void *codec, const HB_UChar16 *unicode, hb_uint32 length, hb_uint32 *outputLength);
-void HB_TextCodec_FreeResult(char *);
-
-HB_END_HEADER
-
-#endif
diff --git a/third_party/harfbuzz/src/harfbuzz-gdef-private.h b/third_party/harfbuzz/src/harfbuzz-gdef-private.h
deleted file mode 100644
index da06b6f..0000000
--- a/third_party/harfbuzz/src/harfbuzz-gdef-private.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_GDEF_PRIVATE_H
-#define HARFBUZZ_GDEF_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-stream-private.h"
-#include "harfbuzz-buffer-private.h"
-#include "harfbuzz-gdef.h"
-
-HB_BEGIN_HEADER
-
-
-/* Attachment related structures */
-
-struct  HB_AttachPoint_
-{
-  HB_UShort   PointCount;             /* size of the PointIndex array */
-  HB_UShort*  PointIndex;             /* array of contour points      */
-};
-
-/* Ligature Caret related structures */
-
-struct  HB_CaretValueFormat1_
-{
-  HB_Short  Coordinate;               /* x or y value (in design units) */
-};
-
-typedef struct HB_CaretValueFormat1_  HB_CaretValueFormat1;
-
-
-struct  HB_CaretValueFormat2_
-{
-  HB_UShort  CaretValuePoint;         /* contour point index on glyph */
-};
-
-typedef struct HB_CaretValueFormat2_  HB_CaretValueFormat2;
-
-
-struct  HB_CaretValueFormat3_
-{
-  HB_Short    Coordinate;             /* x or y value (in design units) */
-  HB_Device  Device;                 /* Device table for x or y value  */
-};
-
-typedef struct HB_CaretValueFormat3_  HB_CaretValueFormat3;
-
-
-struct  HB_CaretValueFormat4_
-{
-  HB_UShort  IdCaretValue;            /* metric ID */
-};
-
-typedef struct HB_CaretValueFormat4_  HB_CaretValueFormat4;
-
-
-struct  HB_CaretValue_
-{
-  HB_UShort  CaretValueFormat;        /* 1, 2, 3, or 4 */
-
-  union
-  {
-    HB_CaretValueFormat1  cvf1;
-    HB_CaretValueFormat2  cvf2;
-    HB_CaretValueFormat3  cvf3;
-    HB_CaretValueFormat4  cvf4;
-  } cvf;
-};
-
-typedef struct HB_CaretValue_  HB_CaretValue;
-
-
-struct  HB_LigGlyph_
-{
-  HB_Bool          loaded;
-
-  HB_UShort        CaretCount;        /* number of caret values */
-  HB_CaretValue*  CaretValue;        /* array of caret values  */
-};
-
-
-HB_INTERNAL HB_Error
-_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,
-				       HB_UShort        glyphID,
-				       HB_UShort        property );
-
-HB_INTERNAL HB_Error
-_HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
-				   HB_GlyphItem    item,
-				   HB_UShort        flags,
-				   HB_UShort*       property );
-
-HB_INTERNAL HB_Error
-_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,
-						  HB_Stream      input,
-						  HB_Lookup*     lo,
-						  HB_UShort      num_lookups );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GDEF_PRIVATE_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-gdef.c b/third_party/harfbuzz/src/harfbuzz-gdef.c
deleted file mode 100644
index ff3a1f4..0000000
--- a/third_party/harfbuzz/src/harfbuzz-gdef.c
+++ /dev/null
@@ -1,1159 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-gdef-private.h"
-#include "harfbuzz-open-private.h"
-
-static HB_Error  Load_AttachList( HB_AttachList*  al,
-				  HB_Stream        stream );
-static HB_Error  Load_LigCaretList( HB_LigCaretList*  lcl,
-				    HB_Stream          stream );
-
-static void  Free_AttachList( HB_AttachList*  al);
-static void  Free_LigCaretList( HB_LigCaretList*  lcl);
-
-static void  Free_NewGlyphClasses( HB_GDEFHeader*  gdef);
-
-
-
-/* GDEF glyph classes */
-
-#define UNCLASSIFIED_GLYPH  0
-#define SIMPLE_GLYPH        1
-#define LIGATURE_GLYPH      2
-#define MARK_GLYPH          3
-#define COMPONENT_GLYPH     4
-
-
-
-
-
-
-HB_Error  HB_New_GDEF_Table( HB_GDEFHeader** retptr )
-{
-  HB_Error         error;
-
-  HB_GDEFHeader*  gdef;
-
-  if ( !retptr )
-    return ERR(HB_Err_Invalid_Argument);
-
-  if ( ALLOC( gdef, sizeof( *gdef ) ) )
-    return error;
-
-  gdef->GlyphClassDef.loaded = FALSE;
-  gdef->AttachList.loaded = FALSE;
-  gdef->LigCaretList.loaded = FALSE;
-  gdef->MarkAttachClassDef_offset = 0;
-  gdef->MarkAttachClassDef.loaded = FALSE;
-
-  gdef->LastGlyph = 0;
-  gdef->NewGlyphClasses = NULL;
-
-  *retptr = gdef;
-
-  return HB_Err_Ok;
-}
-
-
-HB_Error  HB_Load_GDEF_Table( HB_Stream stream, 
-			      HB_GDEFHeader** retptr )
-{
-  HB_Error         error;
-  HB_UInt         cur_offset, new_offset, base_offset;
-
-  HB_GDEFHeader*  gdef;
-
-
-  if ( !retptr )
-    return ERR(HB_Err_Invalid_Argument);
-
-  if ( GOTO_Table( TTAG_GDEF ) )
-    return error;
-
-  if (( error = HB_New_GDEF_Table ( &gdef ) ))
-    return error;
-
-  base_offset = FILE_Pos();
-
-  /* skip version */
-
-  if ( FILE_Seek( base_offset + 4L ) ||
-       ACCESS_Frame( 2L ) )
-    goto Fail0;
-
-  new_offset = GET_UShort();
-
-  FORGET_Frame();
-
-  /* all GDEF subtables are optional */
-
-  if ( new_offset )
-  {
-    new_offset += base_offset;
-
-    /* only classes 1-4 are allowed here */
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_ClassDefinition( &gdef->GlyphClassDef, 5,
-					 stream ) ) != HB_Err_Ok )
-      goto Fail0;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail1;
-
-  new_offset = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( new_offset )
-  {
-    new_offset += base_offset;
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_AttachList( &gdef->AttachList,
-				    stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  new_offset = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( new_offset )
-  {
-    new_offset += base_offset;
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_LigCaretList( &gdef->LigCaretList,
-				      stream ) ) != HB_Err_Ok )
-      goto Fail2;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  /* OpenType 1.2 has introduced the `MarkAttachClassDef' field.  We
-     first have to scan the LookupFlag values to find out whether we
-     must load it or not.  Here we only store the offset of the table. */
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  new_offset = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( new_offset )
-    gdef->MarkAttachClassDef_offset = new_offset + base_offset;
-  else
-    gdef->MarkAttachClassDef_offset = 0;
-
-  *retptr = gdef;
-
-  return HB_Err_Ok;
-
-Fail3:
-  Free_LigCaretList( &gdef->LigCaretList );
-  
-Fail2:
-  Free_AttachList( &gdef->AttachList );
-
-Fail1:
-  _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );
-
-Fail0:
-  FREE( gdef );
-
-  return error;
-}
-
-
-HB_Error  HB_Done_GDEF_Table ( HB_GDEFHeader* gdef ) 
-{  
-  Free_LigCaretList( &gdef->LigCaretList );
-  Free_AttachList( &gdef->AttachList );
-  _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );
-  _HB_OPEN_Free_ClassDefinition( &gdef->MarkAttachClassDef );
-  
-  Free_NewGlyphClasses( gdef );
-
-  FREE( gdef );
-
-  return HB_Err_Ok;
-}
-
-
-
-
-/*******************************
- * AttachList related functions
- *******************************/
-
-
-/* AttachPoint */
-
-static HB_Error  Load_AttachPoint( HB_AttachPoint*  ap,
-				   HB_Stream         stream )
-{
-  HB_Error  error;
-
-  HB_UShort   n, count;
-  HB_UShort*  pi;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = ap->PointCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ap->PointIndex = NULL;
-
-  if ( count )
-  {
-    if ( ALLOC_ARRAY( ap->PointIndex, count, HB_UShort ) )
-      return error;
-
-    pi = ap->PointIndex;
-
-    if ( ACCESS_Frame( count * 2L ) )
-    {
-      FREE( pi );
-      return error;
-    }
-
-    for ( n = 0; n < count; n++ )
-      pi[n] = GET_UShort();
-
-    FORGET_Frame();
-  }
-
-  return HB_Err_Ok;
-}
-
-
-static void  Free_AttachPoint( HB_AttachPoint*  ap )
-{
-  FREE( ap->PointIndex );
-}
-
-
-/* AttachList */
-
-static HB_Error  Load_AttachList( HB_AttachList*  al,
-				  HB_Stream        stream )
-{
-  HB_Error  error;
-
-  HB_UShort         n, m, count;
-  HB_UInt          cur_offset, new_offset, base_offset;
-
-  HB_AttachPoint*  ap;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &al->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = al->GlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  al->AttachPoint = NULL;
-
-  if ( ALLOC_ARRAY( al->AttachPoint, count, HB_AttachPoint ) )
-    goto Fail2;
-
-  ap = al->AttachPoint;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_AttachPoint( &ap[n], stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  al->loaded = TRUE;
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_AttachPoint( &ap[m] );
-
-  FREE( ap );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &al->Coverage );
-  return error;
-}
-
-
-static void  Free_AttachList( HB_AttachList*  al)
-{
-  HB_UShort         n, count;
-
-  HB_AttachPoint*  ap;
-
-
-  if ( !al->loaded )
-    return;
-
-  if ( al->AttachPoint )
-  {
-    count = al->GlyphCount;
-    ap    = al->AttachPoint;
-
-    for ( n = 0; n < count; n++ )
-      Free_AttachPoint( &ap[n] );
-
-    FREE( ap );
-  }
-
-  _HB_OPEN_Free_Coverage( &al->Coverage );
-}
-
-
-
-/*********************************
- * LigCaretList related functions
- *********************************/
-
-
-/* CaretValueFormat1 */
-/* CaretValueFormat2 */
-/* CaretValueFormat3 */
-/* CaretValueFormat4 */
-
-static HB_Error  Load_CaretValue( HB_CaretValue*  cv,
-				  HB_Stream        stream )
-{
-  HB_Error  error;
-
-  HB_UInt cur_offset, new_offset, base_offset;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  cv->CaretValueFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  switch ( cv->CaretValueFormat )
-  {
-  case 1:
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    cv->cvf.cvf1.Coordinate = GET_Short();
-
-    FORGET_Frame();
-
-    break;
-
-  case 2:
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    cv->cvf.cvf2.CaretValuePoint = GET_UShort();
-
-    FORGET_Frame();
-
-    break;
-
-  case 3:
-    if ( ACCESS_Frame( 4L ) )
-      return error;
-
-    cv->cvf.cvf3.Coordinate = GET_Short();
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Device( &cv->cvf.cvf3.Device,
-				stream ) ) != HB_Err_Ok )
-      return error;
-    (void)FILE_Seek( cur_offset );
-
-    break;
-
-  case 4:
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    cv->cvf.cvf4.IdCaretValue = GET_UShort();
-
-    FORGET_Frame();
-    break;
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;
-}
-
-
-static void  Free_CaretValue( HB_CaretValue*  cv)
-{
-  if ( cv->CaretValueFormat == 3 )
-    _HB_OPEN_Free_Device( &cv->cvf.cvf3.Device );
-}
-
-
-/* LigGlyph */
-
-static HB_Error  Load_LigGlyph( HB_LigGlyph*  lg,
-				HB_Stream      stream )
-{
-  HB_Error  error;
-
-  HB_UShort        n, m, count;
-  HB_UInt         cur_offset, new_offset, base_offset;
-
-  HB_CaretValue*  cv;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = lg->CaretCount = GET_UShort();
-
-  FORGET_Frame();
-
-  lg->CaretValue = NULL;
-
-  if ( ALLOC_ARRAY( lg->CaretValue, count, HB_CaretValue ) )
-    return error;
-
-  cv = lg->CaretValue;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_CaretValue( &cv[n], stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_CaretValue( &cv[m] );
-
-  FREE( cv );
-  return error;
-}
-
-
-static void  Free_LigGlyph( HB_LigGlyph*  lg)
-{
-  HB_UShort        n, count;
-
-  HB_CaretValue*  cv;
-
-
-  if ( lg->CaretValue )
-  {
-    count = lg->CaretCount;
-    cv    = lg->CaretValue;
-
-    for ( n = 0; n < count; n++ )
-      Free_CaretValue( &cv[n] );
-
-    FREE( cv );
-  }
-}
-
-
-/* LigCaretList */
-
-static HB_Error  Load_LigCaretList( HB_LigCaretList*  lcl,
-				    HB_Stream          stream )
-{
-  HB_Error  error;
-
-  HB_UShort      m, n, count;
-  HB_UInt       cur_offset, new_offset, base_offset;
-
-  HB_LigGlyph*  lg;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &lcl->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = lcl->LigGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  lcl->LigGlyph = NULL;
-
-  if ( ALLOC_ARRAY( lcl->LigGlyph, count, HB_LigGlyph ) )
-    goto Fail2;
-
-  lg = lcl->LigGlyph;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_LigGlyph( &lg[n], stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  lcl->loaded = TRUE;
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_LigGlyph( &lg[m] );
-
-  FREE( lg );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &lcl->Coverage );
-  return error;
-}
-
-
-static void  Free_LigCaretList( HB_LigCaretList*  lcl )
-{
-  HB_UShort      n, count;
-
-  HB_LigGlyph*  lg;
-
-
-  if ( !lcl->loaded )
-    return;
-
-  if ( lcl->LigGlyph )
-  {
-    count = lcl->LigGlyphCount;
-    lg    = lcl->LigGlyph;
-
-    for ( n = 0; n < count; n++ )
-      Free_LigGlyph( &lg[n] );
-
-    FREE( lg );
-  }
-
-  _HB_OPEN_Free_Coverage( &lcl->Coverage );
-}
-
-
-
-/***********
- * GDEF API
- ***********/
-
-
-static HB_UShort  Get_New_Class( HB_GDEFHeader*  gdef,
-				 HB_UShort        glyphID,
-				 HB_UShort        index )
-{
-  HB_UShort              glyph_index, array_index, count;
-  HB_UShort              byte, bits;
-  
-  HB_ClassRangeRecord*  gcrr;
-  HB_UShort**            ngc;
-
-
-  if ( glyphID >= gdef->LastGlyph )
-    return 0;
-
-  count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
-  gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
-  ngc  = gdef->NewGlyphClasses;
-
-  if ( index < count && glyphID < gcrr[index].Start )
-  {
-    array_index = index;
-    if ( index == 0 )
-      glyph_index = glyphID;
-    else
-      glyph_index = glyphID - gcrr[index - 1].End - 1;
-  }
-  else
-  {
-    array_index = index + 1;
-    glyph_index = glyphID - gcrr[index].End - 1;
-  }
-
-  byte = ngc[array_index][glyph_index / 4];
-  bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
-
-  return bits & 0x000F;
-}
-
-
-
-HB_Error  HB_GDEF_Get_Glyph_Property( HB_GDEFHeader*  gdef,
-				      HB_UShort        glyphID,
-				      HB_UShort*       property )
-{
-  HB_UShort class = 0, index = 0; /* shut compiler up */
-
-  HB_Error  error;
-
-
-  if ( !gdef || !property )
-    return ERR(HB_Err_Invalid_Argument);
-
-  /* first, we check for mark attach classes */
-
-  if ( gdef->MarkAttachClassDef.loaded )
-  {
-    error = _HB_OPEN_Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index );
-    if ( error && error != HB_Err_Not_Covered )
-      return error;
-    if ( !error )
-    {
-      *property = class << 8;
-      return HB_Err_Ok;
-    }
-  }
-
-  error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
-  if ( error && error != HB_Err_Not_Covered )
-    return error;
-
-  /* if we have a constructed class table, check whether additional
-     values have been assigned                                      */
-
-  if ( error == HB_Err_Not_Covered && gdef->NewGlyphClasses )
-    class = Get_New_Class( gdef, glyphID, index );
-
-  switch ( class )
-  {
-  default:
-  case UNCLASSIFIED_GLYPH:
-    *property = 0;
-    break;
-
-  case SIMPLE_GLYPH:
-    *property = HB_GDEF_BASE_GLYPH;
-    break;
-
-  case LIGATURE_GLYPH:
-    *property = HB_GDEF_LIGATURE;
-    break;
-
-  case MARK_GLYPH:
-    *property = HB_GDEF_MARK;
-    break;
-
-  case COMPONENT_GLYPH:
-    *property = HB_GDEF_COMPONENT;
-    break;
-  }
-
-  return HB_Err_Ok;
-}
-
-
-static HB_Error  Make_ClassRange( HB_ClassDefinition*  cd,
-				  HB_UShort             start,
-				  HB_UShort             end,
-				  HB_UShort             class )
-{
-  HB_Error               error;
-  HB_UShort              index;
-
-  HB_ClassDefFormat2*   cdf2;
-  HB_ClassRangeRecord*  crr;
-
-
-  cdf2 = &cd->cd.cd2;
-
-  if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,
-		      cdf2->ClassRangeCount + 1 ,
-		      HB_ClassRangeRecord ) )
-    return error;
-
-  cdf2->ClassRangeCount++;
-
-  crr   = cdf2->ClassRangeRecord;
-  index = cdf2->ClassRangeCount - 1;
-
-  crr[index].Start = start;
-  crr[index].End   = end;
-  crr[index].Class = class;
-
-  return HB_Err_Ok;
-}
-
-
-
-HB_Error  HB_GDEF_Build_ClassDefinition( HB_GDEFHeader*  gdef,
-					 HB_UShort        num_glyphs,
-					 HB_UShort        glyph_count,
-					 HB_UShort*       glyph_array,
-					 HB_UShort*       class_array )
-{
-  HB_UShort              start, curr_glyph, curr_class;
-  HB_UShort              n, m, count;
-  HB_Error               error;
-
-  HB_ClassDefinition*   gcd;
-  HB_ClassRangeRecord*  gcrr;
-  HB_UShort**            ngc;
-
-
-  if ( !gdef || !glyph_array || !class_array )
-    return ERR(HB_Err_Invalid_Argument);
-
-  gcd = &gdef->GlyphClassDef;
-
-  /* We build a format 2 table */
-
-  gcd->ClassFormat = 2;
-
-  gcd->cd.cd2.ClassRangeCount  = 0;
-  gcd->cd.cd2.ClassRangeRecord = NULL;
-
-  start      = glyph_array[0];
-  curr_class = class_array[0];
-  curr_glyph = start;
-
-  if ( curr_class >= 5 )
-  {
-    error = ERR(HB_Err_Invalid_Argument);
-    goto Fail4;
-  }
-
-  glyph_count--;
-
-  for ( n = 0; n < glyph_count + 1; n++ )
-  {
-    if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] )
-    {
-      if ( n == glyph_count )
-      {
-	if ( ( error = Make_ClassRange( gcd, start,
-					curr_glyph,
-					curr_class) ) != HB_Err_Ok )
-	  goto Fail3;
-      }
-      else
-      {
-	if ( curr_glyph == 0xFFFF )
-	{
-	  error = ERR(HB_Err_Invalid_Argument);
-	  goto Fail3;
-	}
-	else
-	  curr_glyph++;
-      }
-    }
-    else
-    {
-      if ( ( error = Make_ClassRange( gcd, start,
-				      curr_glyph - 1,
-				      curr_class) ) != HB_Err_Ok )
-	goto Fail3;
-
-      if ( curr_glyph > glyph_array[n] )
-      {
-	error = ERR(HB_Err_Invalid_Argument);
-	goto Fail3;
-      }
-
-      start      = glyph_array[n];
-      curr_class = class_array[n];
-      curr_glyph = start;
-
-      if ( curr_class >= 5 )
-      {
-	error = ERR(HB_Err_Invalid_Argument);
-	goto Fail3;
-      }
-
-      if ( n == glyph_count )
-      {
-	if ( ( error = Make_ClassRange( gcd, start,
-					curr_glyph,
-					curr_class) ) != HB_Err_Ok )
-	  goto Fail3;
-      }
-      else
-      {
-	if ( curr_glyph == 0xFFFF )
-	{
-	  error = ERR(HB_Err_Invalid_Argument);
-	  goto Fail3;
-	}
-	else
-	  curr_glyph++;
-      }
-    }
-  }
-
-  /* now prepare the arrays for class values assigned during the lookup
-     process                                                            */
-
-  if ( ALLOC_ARRAY( gdef->NewGlyphClasses,
-		    gcd->cd.cd2.ClassRangeCount + 1, HB_UShort* ) )
-    goto Fail3;
-
-  count = gcd->cd.cd2.ClassRangeCount;
-  gcrr  = gcd->cd.cd2.ClassRangeRecord;
-  ngc   = gdef->NewGlyphClasses;
-
-  /* We allocate arrays for all glyphs not covered by the class range
-     records.  Each element holds four class values.                  */
-
-  if ( count > 0 )
-  {
-      if ( gcrr[0].Start )
-      {
-	if ( ALLOC_ARRAY( ngc[0], ( gcrr[0].Start + 3 ) / 4, HB_UShort ) )
-	  goto Fail2;
-      }
-
-      for ( n = 1; n < count; n++ )
-      {
-	if ( gcrr[n].Start - gcrr[n - 1].End > 1 )
-	  if ( ALLOC_ARRAY( ngc[n],
-			    ( gcrr[n].Start - gcrr[n - 1].End + 2 ) / 4,
-			    HB_UShort ) )
-	    goto Fail1;
-      }
-
-      if ( gcrr[count - 1].End != num_glyphs - 1 )
-      {
-	if ( ALLOC_ARRAY( ngc[count],
-			  ( num_glyphs - gcrr[count - 1].End + 2 ) / 4,
-			  HB_UShort ) )
-	    goto Fail1;
-      }
-  }
-  else if ( num_glyphs > 0 )
-  {
-      if ( ALLOC_ARRAY( ngc[count],
-			( num_glyphs + 3 ) / 4,
-			HB_UShort ) )
-	  goto Fail2;
-  }
-      
-  gdef->LastGlyph = num_glyphs - 1;
-
-  gdef->MarkAttachClassDef_offset = 0L;
-  gdef->MarkAttachClassDef.loaded = FALSE;
-
-  gcd->loaded = TRUE;
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    FREE( ngc[m] );
-
-Fail2:
-  FREE( gdef->NewGlyphClasses );
-
-Fail3:
-  FREE( gcd->cd.cd2.ClassRangeRecord );
-
-Fail4:
-  return error;
-}
-
-
-static void  Free_NewGlyphClasses( HB_GDEFHeader*  gdef )
-{
-  HB_UShort**  ngc;
-  HB_UShort    n, count;
-
-
-  if ( gdef->NewGlyphClasses )
-  {
-    count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1;
-    ngc   = gdef->NewGlyphClasses;
-
-    for ( n = 0; n < count; n++ )
-      FREE( ngc[n] );
-
-    FREE( ngc );
-  }
-}
-
-
-HB_INTERNAL HB_Error
-_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,
-			      HB_UShort        glyphID,
-			      HB_UShort        property )
-{
-  HB_Error               error;
-  HB_UShort              class, new_class, index = 0; /* shut compiler up */
-  HB_UShort              byte, bits, mask;
-  HB_UShort              array_index, glyph_index, count;
-
-  HB_ClassRangeRecord*  gcrr;
-  HB_UShort**            ngc;
-
-
-  error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
-  if ( error && error != HB_Err_Not_Covered )
-    return error;
-
-  /* we don't accept glyphs covered in `GlyphClassDef' */
-
-  if ( !error )
-    return HB_Err_Not_Covered;
-
-  switch ( property )
-  {
-  case 0:
-    new_class = UNCLASSIFIED_GLYPH;
-    break;
-
-  case HB_GDEF_BASE_GLYPH:
-    new_class = SIMPLE_GLYPH;
-    break;
-
-  case HB_GDEF_LIGATURE:
-    new_class = LIGATURE_GLYPH;
-    break;
-
-  case HB_GDEF_MARK:
-    new_class = MARK_GLYPH;
-    break;
-
-  case HB_GDEF_COMPONENT:
-    new_class = COMPONENT_GLYPH;
-    break;
-
-  default:
-    return ERR(HB_Err_Invalid_Argument);
-  }
-
-  count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
-  gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
-  ngc  = gdef->NewGlyphClasses;
-
-  if ( index < count && glyphID < gcrr[index].Start )
-  {
-    array_index = index;
-    if ( index == 0 )
-      glyph_index = glyphID;
-    else
-      glyph_index = glyphID - gcrr[index - 1].End - 1;
-  }
-  else
-  {
-    array_index = index + 1;
-    glyph_index = glyphID - gcrr[index].End - 1;
-  }
-
-  byte  = ngc[array_index][glyph_index / 4];
-  bits  = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
-  class = bits & 0x000F;
-
-  /* we don't overwrite existing entries */
-
-  if ( !class )
-  {
-    bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 );
-    mask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) );
-
-    ngc[array_index][glyph_index / 4] &= mask;
-    ngc[array_index][glyph_index / 4] |= bits;
-  }
-
-  return HB_Err_Ok;
-}
-
-
-HB_INTERNAL HB_Error
-_HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
-			  HB_GlyphItem    gitem,
-			  HB_UShort        flags,
-			  HB_UShort*       property )
-{
-  HB_Error  error;
-
-  if ( gdef )
-  {
-    HB_UShort basic_glyph_class;
-    HB_UShort desired_attachment_class;
-
-    if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN )
-    {
-      error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );
-      if ( error )
-	return error;
-    }
-
-    *property = gitem->gproperties;
-
-    /* If the glyph was found in the MarkAttachmentClass table,
-     * then that class value is the high byte of the result,
-     * otherwise the low byte contains the basic type of the glyph
-     * as defined by the GlyphClassDef table.
-     */
-    if ( *property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS  )
-      basic_glyph_class = HB_GDEF_MARK;
-    else
-      basic_glyph_class = *property;
-
-    /* Return Not_Covered, if, for example, basic_glyph_class
-     * is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES
-     */
-    if ( flags & basic_glyph_class )
-      return HB_Err_Not_Covered;
-    
-    /* The high byte of LookupFlags has the meaning
-     * "ignore marks of attachment type different than
-     * the attachment type specified."
-     */
-    desired_attachment_class = flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS;
-    if ( desired_attachment_class )
-    {
-      if ( basic_glyph_class == HB_GDEF_MARK &&
-	   *property != desired_attachment_class )
-	return HB_Err_Not_Covered;
-    }
-  } else {
-      *property = 0;
-  }
-
-  return HB_Err_Ok;
-}
-
-HB_INTERNAL HB_Error
-_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,
-						  HB_Stream      stream,
-						  HB_Lookup*     lo,
-						  HB_UShort      num_lookups)
-{
-  HB_Error   error = HB_Err_Ok;
-  HB_UShort  i;
-
-  /* We now check the LookupFlags for values larger than 0xFF to find
-     out whether we need to load the `MarkAttachClassDef' field of the
-     GDEF table -- this hack is necessary for OpenType 1.2 tables since
-     the version field of the GDEF table hasn't been incremented.
-
-     For constructed GDEF tables, we only load it if
-     `MarkAttachClassDef_offset' is not zero (nevertheless, a build of
-     a constructed mark attach table is not supported currently).       */
-
-  if ( gdef &&
-       gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )
-  {
-    for ( i = 0; i < num_lookups; i++ )
-    {
-
-      if ( lo[i].LookupFlag & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
-      {
-	if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||
-	     ( error = _HB_OPEN_Load_ClassDefinition( &gdef->MarkAttachClassDef,
-					     256, stream ) ) != HB_Err_Ok )
-	  goto Done;
-
-	break;
-      }
-    }
-  }
-
-Done:
-  return error;
-}
-
-/* END */
diff --git a/third_party/harfbuzz/src/harfbuzz-gdef.h b/third_party/harfbuzz/src/harfbuzz-gdef.h
deleted file mode 100644
index b6dcadc..0000000
--- a/third_party/harfbuzz/src/harfbuzz-gdef.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_GDEF_H
-#define HARFBUZZ_GDEF_H
-
-#include "harfbuzz-open.h"
-#include "harfbuzz-stream.h"
-
-HB_BEGIN_HEADER
-
-/* GDEF glyph properties.  Note that HB_GDEF_COMPONENT has no corresponding
- * flag in the LookupFlag field.     */
-#define HB_GDEF_BASE_GLYPH  0x0002
-#define HB_GDEF_LIGATURE    0x0004
-#define HB_GDEF_MARK        0x0008
-#define HB_GDEF_COMPONENT   0x0010
-
-
-typedef struct HB_AttachPoint_  HB_AttachPoint;
-
-
-struct  HB_AttachList_
-{
-  HB_Bool           loaded;
-
-  HB_Coverage       Coverage;         /* Coverage table              */
-  HB_UShort         GlyphCount;       /* number of glyphs with
-					 attachments                 */
-  HB_AttachPoint*   AttachPoint;      /* array of AttachPoint tables */
-};
-
-typedef struct HB_AttachList_  HB_AttachList;
-
-typedef struct HB_LigGlyph_  HB_LigGlyph;
-
-struct  HB_LigCaretList_
-{
-  HB_Bool        loaded;
-
-  HB_Coverage    Coverage;            /* Coverage table            */
-  HB_UShort      LigGlyphCount;       /* number of ligature glyphs */
-  HB_LigGlyph*   LigGlyph;            /* array of LigGlyph tables  */
-};
-
-typedef struct HB_LigCaretList_  HB_LigCaretList;
-
-
-
-/* The `NewGlyphClasses' field is not defined in the TTO specification.
-   We use it for fonts with a constructed `GlyphClassDef' structure
-   (i.e., which don't have a GDEF table) to collect glyph classes
-   assigned during the lookup process.  The number of arrays in this
-   pointer array is GlyphClassDef->cd.cd2.ClassRangeCount+1; the nth
-   array then contains the glyph class values of the glyphs not covered
-   by the ClassRangeRecords structures with index n-1 and n.  We store
-   glyph class values for four glyphs in a single array element.
-
-   `LastGlyph' is identical to the number of glyphs minus one in the
-   font; we need it only if `NewGlyphClasses' is not NULL (to have an
-   upper bound for the last array).
-
-   Note that we first store the file offset to the `MarkAttachClassDef'
-   field (which has been introduced in OpenType 1.2) -- since the
-   `Version' field value hasn't been increased to indicate that we have
-   one more field for some obscure reason, we must parse the GSUB table
-   to find out whether class values refer to this table.  Only then we
-   can finally load the MarkAttachClassDef structure if necessary.      */
-
-struct  HB_GDEFHeader_
-{
-  HB_UInt             offset;
-
-  HB_16Dot16             Version;
-
-  HB_ClassDefinition   GlyphClassDef;
-  HB_AttachList        AttachList;
-  HB_LigCaretList      LigCaretList;
-  HB_UInt             MarkAttachClassDef_offset;
-  HB_ClassDefinition   MarkAttachClassDef;        /* new in OT 1.2 */
-
-  HB_UShort            LastGlyph;
-  HB_UShort**          NewGlyphClasses;
-};
-
-typedef struct HB_GDEFHeader_   HB_GDEFHeader;
-typedef struct HB_GDEFHeader_*  HB_GDEF;
-
-
-HB_Error  HB_New_GDEF_Table( HB_GDEFHeader** retptr );
-      
-
-HB_Error  HB_Load_GDEF_Table( HB_Stream       stream,
-			      HB_GDEFHeader** gdef );
-
-
-HB_Error  HB_Done_GDEF_Table ( HB_GDEFHeader* gdef );
-
-
-HB_Error  HB_GDEF_Get_Glyph_Property( HB_GDEFHeader*  gdef,
-				      HB_UShort        glyphID,
-				      HB_UShort*       property );
-
-HB_Error  HB_GDEF_Build_ClassDefinition( HB_GDEFHeader*  gdef,
-					 HB_UShort        num_glyphs,
-					 HB_UShort        glyph_count,
-					 HB_UShort*       glyph_array,
-					 HB_UShort*       class_array );
-
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GDEF_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-global.h b/third_party/harfbuzz/src/harfbuzz-global.h
deleted file mode 100644
index d4e6b46..0000000
--- a/third_party/harfbuzz/src/harfbuzz-global.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#ifndef HARFBUZZ_GLOBAL_H
-#define HARFBUZZ_GLOBAL_H
-
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef __cplusplus
-#define HB_BEGIN_HEADER  extern "C" {
-#define HB_END_HEADER  }
-#else
-#define HB_BEGIN_HEADER  /* nothing */
-#define HB_END_HEADER  /* nothing */
-#endif
-
-HB_BEGIN_HEADER
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE (!FALSE)
-#endif
-
-#define HB_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
-          ( ( (HB_UInt)_x1 << 24 ) |     \
-            ( (HB_UInt)_x2 << 16 ) |     \
-            ( (HB_UInt)_x3 <<  8 ) |     \
-              (HB_UInt)_x4         )
-
-typedef char hb_int8;
-typedef unsigned char hb_uint8;
-typedef short hb_int16;
-typedef unsigned short hb_uint16;
-typedef int hb_int32;
-typedef unsigned int hb_uint32;
-
-typedef hb_uint8 HB_Bool;
-
-typedef hb_uint8 HB_Byte;
-typedef hb_uint16 HB_UShort;
-typedef hb_uint32 HB_UInt;
-typedef hb_int8 HB_Char;
-typedef hb_int16 HB_Short;
-typedef hb_int32 HB_Int;
-
-typedef hb_uint16 HB_UChar16;
-typedef hb_uint32 HB_UChar32;
-typedef hb_uint32 HB_Glyph;
-typedef hb_int32 HB_Fixed; /* 26.6 */
-
-#define HB_FIXED_CONSTANT(v) ((v) * 64)
-#define HB_FIXED_ROUND(v) (((v)+32) & -64)
-
-typedef hb_int32 HB_16Dot16; /* 16.16 */
-
-typedef void * HB_Pointer;
-typedef hb_uint32 HB_Tag;
-
-typedef enum {
-  /* no error */
-  HB_Err_Ok                           = 0x0000,
-  HB_Err_Not_Covered                  = 0xFFFF,
-
-  /* _hb_err() is called whenever returning the following errors,
-   * and in a couple places for HB_Err_Not_Covered too. */
-
-  /* programmer error */
-  HB_Err_Invalid_Argument             = 0x1A66,
-
-  /* font error */
-  HB_Err_Invalid_SubTable_Format      = 0x157F,
-  HB_Err_Invalid_SubTable             = 0x1570,
-  HB_Err_Read_Error                   = 0x6EAD,
-
-  /* system error */
-  HB_Err_Out_Of_Memory                = 0xDEAD
-} HB_Error;
-
-typedef struct {
-    HB_Fixed x;
-    HB_Fixed y;
-} HB_FixedPoint;
-
-typedef struct HB_Font_ *HB_Font;
-typedef struct HB_StreamRec_ *HB_Stream;
-typedef struct HB_FaceRec_ *HB_Face;
-
-HB_END_HEADER
-
-#endif
diff --git a/third_party/harfbuzz/src/harfbuzz-gpos-private.h b/third_party/harfbuzz/src/harfbuzz-gpos-private.h
deleted file mode 100644
index 4110700..0000000
--- a/third_party/harfbuzz/src/harfbuzz-gpos-private.h
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_GPOS_PRIVATE_H
-#define HARFBUZZ_GPOS_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-stream-private.h"
-#include "harfbuzz-gpos.h"
-
-HB_BEGIN_HEADER
-
-
-/* shared tables */
-
-struct  HB_ValueRecord_
-{
-  HB_Short    XPlacement;             /* horizontal adjustment for
-					 placement                      */
-  HB_Short    YPlacement;             /* vertical adjustment for
-					 placement                      */
-  HB_Short    XAdvance;               /* horizontal adjustment for
-					 advance                        */
-  HB_Short    YAdvance;               /* vertical adjustment for
-					 advance                        */
-  HB_Device  XPlacementDevice;       /* device table for horizontal
-					 placement                      */
-  HB_Device  YPlacementDevice;       /* device table for vertical
-					 placement                      */
-  HB_Device  XAdvanceDevice;         /* device table for horizontal
-					 advance                        */
-  HB_Device  YAdvanceDevice;         /* device table for vertical
-					 advance                        */
-  HB_UShort   XIdPlacement;           /* horizontal placement metric ID */
-  HB_UShort   YIdPlacement;           /* vertical placement metric ID   */
-  HB_UShort   XIdAdvance;             /* horizontal advance metric ID   */
-  HB_UShort   YIdAdvance;             /* vertical advance metric ID     */
-};
-
-typedef struct HB_ValueRecord_  HB_ValueRecord;
-
-
-/* Mask values to scan the value format of the ValueRecord structure.
- We always expand compressed ValueRecords of the font.              */
-
-#define HB_GPOS_FORMAT_HAVE_X_PLACEMENT         0x0001
-#define HB_GPOS_FORMAT_HAVE_Y_PLACEMENT         0x0002
-#define HB_GPOS_FORMAT_HAVE_X_ADVANCE           0x0004
-#define HB_GPOS_FORMAT_HAVE_Y_ADVANCE           0x0008
-#define HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE  0x0010
-#define HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE  0x0020
-#define HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE    0x0040
-#define HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE    0x0080
-#define HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT      0x0100
-#define HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT      0x0200
-#define HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE        0x0400
-#define HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE        0x0800
-
-
-struct  HB_AnchorFormat1_
-{
-  HB_Short   XCoordinate;             /* horizontal value */
-  HB_Short   YCoordinate;             /* vertical value   */
-};
-
-typedef struct HB_AnchorFormat1_  HB_AnchorFormat1;
-
-
-struct  HB_AnchorFormat2_
-{
-  HB_Short   XCoordinate;             /* horizontal value             */
-  HB_Short   YCoordinate;             /* vertical value               */
-  HB_UShort  AnchorPoint;             /* index to glyph contour point */
-};
-
-typedef struct HB_AnchorFormat2_  HB_AnchorFormat2;
-
-
-struct  HB_AnchorFormat3_
-{
-  HB_Short    XCoordinate;            /* horizontal value              */
-  HB_Short    YCoordinate;            /* vertical value                */
-  HB_Device  XDeviceTable;           /* device table for X coordinate */
-  HB_Device  YDeviceTable;           /* device table for Y coordinate */
-};
-
-typedef struct HB_AnchorFormat3_  HB_AnchorFormat3;
-
-
-struct  HB_AnchorFormat4_
-{
-  HB_UShort  XIdAnchor;               /* horizontal metric ID */
-  HB_UShort  YIdAnchor;               /* vertical metric ID   */
-};
-
-typedef struct HB_AnchorFormat4_  HB_AnchorFormat4;
-
-
-struct  HB_Anchor_
-{
-  HB_UShort  PosFormat;               /* 1, 2, 3, or 4 -- 0 indicates
-					 that there is no Anchor table */
-
-  union
-  {
-    HB_AnchorFormat1  af1;
-    HB_AnchorFormat2  af2;
-    HB_AnchorFormat3  af3;
-    HB_AnchorFormat4  af4;
-  } af;
-};
-
-typedef struct HB_Anchor_  HB_Anchor;
-
-
-struct  HB_MarkRecord_
-{
-  HB_UShort   Class;                  /* mark class   */
-  HB_Anchor  MarkAnchor;             /* anchor table */
-};
-
-typedef struct HB_MarkRecord_  HB_MarkRecord;
-
-
-struct  HB_MarkArray_
-{
-  HB_UShort        MarkCount;         /* number of MarkRecord tables */
-  HB_MarkRecord*  MarkRecord;        /* array of MarkRecord tables  */
-};
-
-typedef struct HB_MarkArray_  HB_MarkArray;
-
-
-/* LookupType 1 */
-
-struct  HB_SinglePosFormat1_
-{
-  HB_ValueRecord  Value;             /* ValueRecord for all covered
-					 glyphs                      */
-};
-
-typedef struct HB_SinglePosFormat1_  HB_SinglePosFormat1;
-
-
-struct  HB_SinglePosFormat2_
-{
-  HB_UShort         ValueCount;       /* number of ValueRecord tables */
-  HB_ValueRecord*  Value;            /* array of ValueRecord tables  */
-};
-
-typedef struct HB_SinglePosFormat2_  HB_SinglePosFormat2;
-
-
-struct  HB_SinglePos_
-{
-  HB_UShort     PosFormat;            /* 1 or 2         */
-  HB_Coverage  Coverage;             /* Coverage table */
-
-  HB_UShort     ValueFormat;          /* format of ValueRecord table */
-
-  union
-  {
-    HB_SinglePosFormat1  spf1;
-    HB_SinglePosFormat2  spf2;
-  } spf;
-};
-
-typedef struct HB_SinglePos_  HB_SinglePos;
-
-
-/* LookupType 2 */
-
-struct  HB_PairValueRecord_
-{
-  HB_UShort        SecondGlyph;       /* glyph ID for second glyph  */
-  HB_ValueRecord  Value1;            /* pos. data for first glyph  */
-  HB_ValueRecord  Value2;            /* pos. data for second glyph */
-};
-
-typedef struct HB_PairValueRecord_  HB_PairValueRecord;
-
-
-struct  HB_PairSet_
-{
-  HB_UShort             PairValueCount;
-				      /* number of PairValueRecord tables */
-  HB_PairValueRecord*  PairValueRecord;
-				      /* array of PairValueRecord tables  */
-};
-
-typedef struct HB_PairSet_  HB_PairSet;
-
-
-struct  HB_PairPosFormat1_
-{
-  HB_UShort     PairSetCount;         /* number of PairSet tables    */
-  HB_PairSet*  PairSet;              /* array of PairSet tables     */
-};
-
-typedef struct HB_PairPosFormat1_  HB_PairPosFormat1;
-
-
-struct  HB_Class2Record_
-{
-  HB_ValueRecord  Value1;            /* pos. data for first glyph  */
-  HB_ValueRecord  Value2;            /* pos. data for second glyph */
-};
-
-typedef struct HB_Class2Record_  HB_Class2Record;
-
-
-struct  HB_Class1Record_
-{
-  HB_Class2Record*  Class2Record;    /* array of Class2Record tables */
-};
-
-typedef struct HB_Class1Record_  HB_Class1Record;
-
-
-struct  HB_PairPosFormat2_
-{
-  HB_ClassDefinition  ClassDef1;     /* class def. for first glyph     */
-  HB_ClassDefinition  ClassDef2;     /* class def. for second glyph    */
-  HB_UShort            Class1Count;   /* number of classes in ClassDef1
-					 table                          */
-  HB_UShort            Class2Count;   /* number of classes in ClassDef2
-					 table                          */
-  HB_Class1Record*    Class1Record;  /* array of Class1Record tables   */
-};
-
-typedef struct HB_PairPosFormat2_  HB_PairPosFormat2;
-
-
-struct  HB_PairPos_
-{
-  HB_UShort     PosFormat;            /* 1 or 2         */
-  HB_Coverage  Coverage;             /* Coverage table */
-  HB_UShort     ValueFormat1;         /* format of ValueRecord table
-					 for first glyph             */
-  HB_UShort     ValueFormat2;         /* format of ValueRecord table
-					 for second glyph            */
-
-  union
-  {
-    HB_PairPosFormat1  ppf1;
-    HB_PairPosFormat2  ppf2;
-  } ppf;
-};
-
-typedef struct HB_PairPos_  HB_PairPos;
-
-
-/* LookupType 3 */
-
-struct  HB_EntryExitRecord_
-{
-  HB_Anchor  EntryAnchor;            /* entry Anchor table */
-  HB_Anchor  ExitAnchor;             /* exit Anchor table  */
-};
-
-
-typedef struct HB_EntryExitRecord_  HB_EntryExitRecord;
-
-struct  HB_CursivePos_
-{
-  HB_UShort             PosFormat;    /* always 1                         */
-  HB_Coverage          Coverage;     /* Coverage table                   */
-  HB_UShort             EntryExitCount;
-				      /* number of EntryExitRecord tables */
-  HB_EntryExitRecord*  EntryExitRecord;
-				      /* array of EntryExitRecord tables  */
-};
-
-typedef struct HB_CursivePos_  HB_CursivePos;
-
-
-/* LookupType 4 */
-
-struct  HB_BaseRecord_
-{
-  HB_Anchor*  BaseAnchor;            /* array of base glyph anchor
-					 tables                     */
-};
-
-typedef struct HB_BaseRecord_  HB_BaseRecord;
-
-
-struct  HB_BaseArray_
-{
-  HB_UShort        BaseCount;         /* number of BaseRecord tables */
-  HB_BaseRecord*  BaseRecord;        /* array of BaseRecord tables  */
-};
-
-typedef struct HB_BaseArray_  HB_BaseArray;
-
-
-struct  HB_MarkBasePos_
-{
-  HB_UShort      PosFormat;           /* always 1                  */
-  HB_Coverage   MarkCoverage;        /* mark glyph coverage table */
-  HB_Coverage   BaseCoverage;        /* base glyph coverage table */
-  HB_UShort      ClassCount;          /* number of mark classes    */
-  HB_MarkArray  MarkArray;           /* mark array table          */
-  HB_BaseArray  BaseArray;           /* base array table          */
-};
-
-typedef struct HB_MarkBasePos_  HB_MarkBasePos;
-
-
-/* LookupType 5 */
-
-struct  HB_ComponentRecord_
-{
-  HB_Anchor*  LigatureAnchor;        /* array of ligature glyph anchor
-					 tables                         */
-};
-
-typedef struct HB_ComponentRecord_  HB_ComponentRecord;
-
-
-struct  HB_LigatureAttach_
-{
-  HB_UShort             ComponentCount;
-				      /* number of ComponentRecord tables */
-  HB_ComponentRecord*  ComponentRecord;
-				      /* array of ComponentRecord tables  */
-};
-
-typedef struct HB_LigatureAttach_  HB_LigatureAttach;
-
-
-struct  HB_LigatureArray_
-{
-  HB_UShort            LigatureCount; /* number of LigatureAttach tables */
-  HB_LigatureAttach*  LigatureAttach;
-				      /* array of LigatureAttach tables  */
-};
-
-typedef struct HB_LigatureArray_  HB_LigatureArray;
-
-
-struct  HB_MarkLigPos_
-{
-  HB_UShort          PosFormat;       /* always 1                      */
-  HB_Coverage       MarkCoverage;    /* mark glyph coverage table     */
-  HB_Coverage       LigatureCoverage;
-				      /* ligature glyph coverage table */
-  HB_UShort          ClassCount;      /* number of mark classes        */
-  HB_MarkArray      MarkArray;       /* mark array table              */
-  HB_LigatureArray  LigatureArray;   /* ligature array table          */
-};
-
-typedef struct HB_MarkLigPos_  HB_MarkLigPos;
-
-
-/* LookupType 6 */
-
-struct  HB_Mark2Record_
-{
-  HB_Anchor*  Mark2Anchor;           /* array of mark glyph anchor
-					 tables                     */
-};
-
-typedef struct HB_Mark2Record_  HB_Mark2Record;
-
-
-struct  HB_Mark2Array_
-{
-  HB_UShort         Mark2Count;       /* number of Mark2Record tables */
-  HB_Mark2Record*  Mark2Record;      /* array of Mark2Record tables  */
-};
-
-typedef struct HB_Mark2Array_  HB_Mark2Array;
-
-
-struct  HB_MarkMarkPos_
-{
-  HB_UShort       PosFormat;          /* always 1                         */
-  HB_Coverage    Mark1Coverage;      /* first mark glyph coverage table  */
-  HB_Coverage    Mark2Coverage;      /* second mark glyph coverave table */
-  HB_UShort       ClassCount;         /* number of combining mark classes */
-  HB_MarkArray   Mark1Array;         /* MarkArray table for first mark   */
-  HB_Mark2Array  Mark2Array;         /* MarkArray table for second mark  */
-};
-
-typedef struct HB_MarkMarkPos_  HB_MarkMarkPos;
-
-
-/* needed by both lookup type 7 and 8 */
-
-struct  HB_PosLookupRecord_
-{
-  HB_UShort  SequenceIndex;           /* index into current
-					 glyph sequence               */
-  HB_UShort  LookupListIndex;         /* Lookup to apply to that pos. */
-};
-
-typedef struct HB_PosLookupRecord_  HB_PosLookupRecord;
-
-
-/* LookupType 7 */
-
-struct  HB_PosRule_
-{
-  HB_UShort             GlyphCount;   /* total number of input glyphs     */
-  HB_UShort             PosCount;     /* number of PosLookupRecord tables */
-  HB_UShort*            Input;        /* array of input glyph IDs         */
-  HB_PosLookupRecord*  PosLookupRecord;
-				      /* array of PosLookupRecord tables  */
-};
-
-typedef struct HB_PosRule_  HB_PosRule;
-
-
-struct  HB_PosRuleSet_
-{
-  HB_UShort     PosRuleCount;         /* number of PosRule tables */
-  HB_PosRule*  PosRule;              /* array of PosRule tables  */
-};
-
-typedef struct HB_PosRuleSet_  HB_PosRuleSet;
-
-
-struct  HB_ContextPosFormat1_
-{
-  HB_Coverage     Coverage;          /* Coverage table              */
-  HB_UShort        PosRuleSetCount;   /* number of PosRuleSet tables */
-  HB_PosRuleSet*  PosRuleSet;        /* array of PosRuleSet tables  */
-};
-
-typedef struct HB_ContextPosFormat1_  HB_ContextPosFormat1;
-
-
-struct  HB_PosClassRule_
-{
-  HB_UShort             GlyphCount;   /* total number of context classes  */
-  HB_UShort             PosCount;     /* number of PosLookupRecord tables */
-  HB_UShort*            Class;        /* array of classes                 */
-  HB_PosLookupRecord*  PosLookupRecord;
-				      /* array of PosLookupRecord tables  */
-};
-
-typedef struct HB_PosClassRule_  HB_PosClassRule;
-
-
-struct  HB_PosClassSet_
-{
-  HB_UShort          PosClassRuleCount;
-				      /* number of PosClassRule tables */
-  HB_PosClassRule*  PosClassRule;    /* array of PosClassRule tables  */
-};
-
-typedef struct HB_PosClassSet_  HB_PosClassSet;
-
-
-/* The `MaxContextLength' field is not defined in the TTO specification
-   but simplifies the implementation of this format.  It holds the
-   maximal context length used in the context rules.                    */
-
-struct  HB_ContextPosFormat2_
-{
-  HB_UShort            MaxContextLength;
-				      /* maximal context length       */
-  HB_Coverage         Coverage;      /* Coverage table               */
-  HB_ClassDefinition  ClassDef;      /* ClassDef table               */
-  HB_UShort            PosClassSetCount;
-				      /* number of PosClassSet tables */
-  HB_PosClassSet*     PosClassSet;   /* array of PosClassSet tables  */
-};
-
-typedef struct HB_ContextPosFormat2_  HB_ContextPosFormat2;
-
-
-struct  HB_ContextPosFormat3_
-{
-  HB_UShort             GlyphCount;   /* number of input glyphs           */
-  HB_UShort             PosCount;     /* number of PosLookupRecord tables */
-  HB_Coverage*         Coverage;     /* array of Coverage tables         */
-  HB_PosLookupRecord*  PosLookupRecord;
-				      /* array of PosLookupRecord tables  */
-};
-
-typedef struct HB_ContextPosFormat3_  HB_ContextPosFormat3;
-
-
-struct  HB_ContextPos_
-{
-  HB_UShort  PosFormat;               /* 1, 2, or 3     */
-
-  union
-  {
-    HB_ContextPosFormat1  cpf1;
-    HB_ContextPosFormat2  cpf2;
-    HB_ContextPosFormat3  cpf3;
-  } cpf;
-};
-
-typedef struct HB_ContextPos_  HB_ContextPos;
-
-
-/* LookupType 8 */
-
-struct  HB_ChainPosRule_
-{
-  HB_UShort             BacktrackGlyphCount;
-				      /* total number of backtrack glyphs */
-  HB_UShort*            Backtrack;    /* array of backtrack glyph IDs     */
-  HB_UShort             InputGlyphCount;
-				      /* total number of input glyphs     */
-  HB_UShort*            Input;        /* array of input glyph IDs         */
-  HB_UShort             LookaheadGlyphCount;
-				      /* total number of lookahead glyphs */
-  HB_UShort*            Lookahead;    /* array of lookahead glyph IDs     */
-  HB_UShort             PosCount;     /* number of PosLookupRecords       */
-  HB_PosLookupRecord*  PosLookupRecord;
-				      /* array of PosLookupRecords       */
-};
-
-typedef struct HB_ChainPosRule_  HB_ChainPosRule;
-
-
-struct  HB_ChainPosRuleSet_
-{
-  HB_UShort          ChainPosRuleCount;
-				      /* number of ChainPosRule tables */
-  HB_ChainPosRule*  ChainPosRule;    /* array of ChainPosRule tables  */
-};
-
-typedef struct HB_ChainPosRuleSet_  HB_ChainPosRuleSet;
-
-
-struct  HB_ChainContextPosFormat1_
-{
-  HB_Coverage          Coverage;     /* Coverage table                   */
-  HB_UShort             ChainPosRuleSetCount;
-				      /* number of ChainPosRuleSet tables */
-  HB_ChainPosRuleSet*  ChainPosRuleSet;
-				      /* array of ChainPosRuleSet tables  */
-};
-
-typedef struct HB_ChainContextPosFormat1_  HB_ChainContextPosFormat1;
-
-
-struct  HB_ChainPosClassRule_
-{
-  HB_UShort             BacktrackGlyphCount;
-				      /* total number of backtrack
-					 classes                         */
-  HB_UShort*            Backtrack;    /* array of backtrack classes      */
-  HB_UShort             InputGlyphCount;
-				      /* total number of context classes */
-  HB_UShort*            Input;        /* array of context classes        */
-  HB_UShort             LookaheadGlyphCount;
-				      /* total number of lookahead
-					 classes                         */
-  HB_UShort*            Lookahead;    /* array of lookahead classes      */
-  HB_UShort             PosCount;     /* number of PosLookupRecords      */
-  HB_PosLookupRecord*  PosLookupRecord;
-				      /* array of substitution lookups   */
-};
-
-typedef struct HB_ChainPosClassRule_  HB_ChainPosClassRule;
-
-
-struct  HB_ChainPosClassSet_
-{
-  HB_UShort               ChainPosClassRuleCount;
-				      /* number of ChainPosClassRule
-					 tables                      */
-  HB_ChainPosClassRule*  ChainPosClassRule;
-				      /* array of ChainPosClassRule
-					 tables                      */
-};
-
-typedef struct HB_ChainPosClassSet_  HB_ChainPosClassSet;
-
-
-/* The `MaxXXXLength' fields are not defined in the TTO specification
-   but simplifies the implementation of this format.  It holds the
-   maximal context length used in the specific context rules.         */
-
-struct  HB_ChainContextPosFormat2_
-{
-  HB_Coverage           Coverage;    /* Coverage table             */
-
-  HB_UShort              MaxBacktrackLength;
-				      /* maximal backtrack length   */
-  HB_ClassDefinition    BacktrackClassDef;
-				      /* BacktrackClassDef table    */
-  HB_UShort              MaxInputLength;
-				      /* maximal input length       */
-  HB_ClassDefinition    InputClassDef;
-				      /* InputClassDef table        */
-  HB_UShort              MaxLookaheadLength;
-				      /* maximal lookahead length   */
-  HB_ClassDefinition    LookaheadClassDef;
-				      /* LookaheadClassDef table    */
-
-  HB_UShort              ChainPosClassSetCount;
-				      /* number of ChainPosClassSet
-					 tables                     */
-  HB_ChainPosClassSet*  ChainPosClassSet;
-				      /* array of ChainPosClassSet
-					 tables                     */
-};
-
-typedef struct HB_ChainContextPosFormat2_  HB_ChainContextPosFormat2;
-
-
-struct  HB_ChainContextPosFormat3_
-{
-  HB_UShort             BacktrackGlyphCount;
-				      /* number of backtrack glyphs    */
-  HB_Coverage*         BacktrackCoverage;
-				      /* array of backtrack Coverage
-					 tables                        */
-  HB_UShort             InputGlyphCount;
-				      /* number of input glyphs        */
-  HB_Coverage*         InputCoverage;
-				      /* array of input coverage
-					 tables                        */
-  HB_UShort             LookaheadGlyphCount;
-				      /* number of lookahead glyphs    */
-  HB_Coverage*         LookaheadCoverage;
-				      /* array of lookahead coverage
-					 tables                        */
-  HB_UShort             PosCount;     /* number of PosLookupRecords    */
-  HB_PosLookupRecord*  PosLookupRecord;
-				      /* array of substitution lookups */
-};
-
-typedef struct HB_ChainContextPosFormat3_  HB_ChainContextPosFormat3;
-
-
-struct  HB_ChainContextPos_
-{
-  HB_UShort  PosFormat;             /* 1, 2, or 3 */
-
-  union
-  {
-    HB_ChainContextPosFormat1  ccpf1;
-    HB_ChainContextPosFormat2  ccpf2;
-    HB_ChainContextPosFormat3  ccpf3;
-  } ccpf;
-};
-
-typedef struct HB_ChainContextPos_  HB_ChainContextPos;
-
-
-#if 0
-/* LookupType 10 */
-struct HB_ExtensionPos_
-{
-  HB_UShort      PosFormat;           /* always 1 */
-  HB_UShort      LookuptType;         /* lookup-type of referenced subtable */
-  HB_GPOS_SubTable *subtable;         /* referenced subtable */
-};
-
-typedef struct HB_ExtensionPos_  HB_ExtensionPos;
-#endif
-
-
-union  HB_GPOS_SubTable_
-{
-  HB_SinglePos        single;
-  HB_PairPos          pair;
-  HB_CursivePos       cursive;
-  HB_MarkBasePos      markbase;
-  HB_MarkLigPos       marklig;
-  HB_MarkMarkPos      markmark;
-  HB_ContextPos       context;
-  HB_ChainContextPos  chain;
-};
-
-typedef union HB_GPOS_SubTable_  HB_GPOS_SubTable;
-
-
-
-HB_INTERNAL HB_Error
-_HB_GPOS_Load_SubTable( HB_GPOS_SubTable* st,
-				  HB_Stream     stream,
-				  HB_UShort     lookup_type );
-
-HB_INTERNAL void
-_HB_GPOS_Free_SubTable( HB_GPOS_SubTable* st,
-			      HB_UShort     lookup_type );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GPOS_PRIVATE_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-gpos.c b/third_party/harfbuzz/src/harfbuzz-gpos.c
deleted file mode 100644
index 356dc01..0000000
--- a/third_party/harfbuzz/src/harfbuzz-gpos.c
+++ /dev/null
@@ -1,6055 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- * Copyright (C) 2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-gpos-private.h"
-#include "harfbuzz-open-private.h"
-#include "harfbuzz-gdef-private.h"
-#include "harfbuzz-shaper.h"
-
-struct  GPOS_Instance_
-{
-  HB_GPOSHeader*  gpos;
-  HB_Font          font;
-  HB_Bool          dvi;
-  HB_UShort        load_flags;  /* how the glyph should be loaded */
-  HB_Bool          r2l;
-
-  HB_UShort        last;        /* the last valid glyph -- used
-				   with cursive positioning     */
-  HB_Fixed           anchor_x;    /* the coordinates of the anchor point */
-  HB_Fixed           anchor_y;    /* of the last valid glyph             */
-};
-
-typedef struct GPOS_Instance_  GPOS_Instance;
-
-
-static HB_Error  GPOS_Do_Glyph_Lookup( GPOS_Instance*    gpi,
-				       HB_UShort         lookup_index,
-				       HB_Buffer        buffer,
-				       HB_UShort         context_length,
-				       int               nesting_level );
-
-
-
-/* the client application must replace this with something more
-   meaningful if multiple master fonts are to be supported.     */
-
-static HB_Error  default_mmfunc( HB_Font      font,
-				 HB_UShort    metric_id,
-				 HB_Fixed*      metric_value,
-				 void*        data )
-{
-  HB_UNUSED(font);
-  HB_UNUSED(metric_id);
-  HB_UNUSED(metric_value);
-  HB_UNUSED(data);
-  return ERR(HB_Err_Not_Covered); /* ERR() call intended */
-}
-
-
-
-HB_Error  HB_Load_GPOS_Table( HB_Stream stream, 
-			      HB_GPOSHeader** retptr,
-			      HB_GDEFHeader*  gdef,
-			      HB_Stream       gdefStream )
-{
-  HB_UInt         cur_offset, new_offset, base_offset;
-
-  HB_GPOSHeader*  gpos;
-
-  HB_Error   error;
-
-
-  if ( !retptr )
-    return ERR(HB_Err_Invalid_Argument);
-
-  if ( GOTO_Table( TTAG_GPOS ) )
-    return error;
-
-  base_offset = FILE_Pos();
-
-  if ( ALLOC ( gpos, sizeof( *gpos ) ) )
-    return error;
-
-  gpos->mmfunc = default_mmfunc;
-
-  /* skip version */
-
-  if ( FILE_Seek( base_offset + 4L ) ||
-       ACCESS_Frame( 2L ) )
-    goto Fail4;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_ScriptList( &gpos->ScriptList,
-				  stream ) ) != HB_Err_Ok )
-    goto Fail4;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_FeatureList( &gpos->FeatureList,
-				   stream ) ) != HB_Err_Ok )
-    goto Fail3;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_LookupList( &gpos->LookupList,
-				  stream, HB_Type_GPOS ) ) != HB_Err_Ok )
-    goto Fail2;
-
-  gpos->gdef = gdef;      /* can be NULL */
-
-  if ( ( error =  _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, gdefStream,
-								     gpos->LookupList.Lookup,
-								     gpos->LookupList.LookupCount ) ) )
-    goto Fail1;
-
-  *retptr = gpos;
-
-  return HB_Err_Ok;
-
-Fail1:
-  _HB_OPEN_Free_LookupList( &gpos->LookupList, HB_Type_GPOS );
-
-Fail2:
-  _HB_OPEN_Free_FeatureList( &gpos->FeatureList );
-
-Fail3:
-  _HB_OPEN_Free_ScriptList( &gpos->ScriptList );
-
-Fail4:
-  FREE( gpos );
-
-  return error;
-}
-
-
-HB_Error  HB_Done_GPOS_Table( HB_GPOSHeader* gpos )
-{
-  _HB_OPEN_Free_LookupList( &gpos->LookupList, HB_Type_GPOS );
-  _HB_OPEN_Free_FeatureList( &gpos->FeatureList );
-  _HB_OPEN_Free_ScriptList( &gpos->ScriptList );
-
-  FREE( gpos );
-
-  return HB_Err_Ok;
-}
-
-
-/*****************************
- * SubTable related functions
- *****************************/
-
-/* shared tables */
-
-/* ValueRecord */
-
-/* There is a subtle difference in the specs between a `table' and a
-   `record' -- offsets for device tables in ValueRecords are taken from
-   the parent table and not the parent record.                          */
-
-static HB_Error  Load_ValueRecord( HB_ValueRecord*  vr,
-				   HB_UShort         format,
-				   HB_UInt          base_offset,
-				   HB_Stream         stream )
-{
-  HB_Error  error;
-
-  HB_UInt cur_offset, new_offset;
-
-
-  if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    vr->XPlacement = GET_Short();
-
-    FORGET_Frame();
-  }
-  else
-    vr->XPlacement = 0;
-
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    vr->YPlacement = GET_Short();
-
-    FORGET_Frame();
-  }
-  else
-    vr->YPlacement = 0;
-
-  if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    vr->XAdvance = GET_Short();
-
-    FORGET_Frame();
-  }
-  else
-    vr->XAdvance = 0;
-
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    vr->YAdvance = GET_Short();
-
-    FORGET_Frame();
-  }
-  else
-    vr->YAdvance = 0;
-
-  if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    new_offset = GET_UShort();
-
-    FORGET_Frame();
-
-    if ( new_offset )
-    {
-      new_offset += base_offset;
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = _HB_OPEN_Load_Device( &vr->XPlacementDevice,
-				  stream ) ) != HB_Err_Ok )
-	return error;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-      goto empty1;
-  }
-  else
-  {
-  empty1:
-    vr->XPlacementDevice.StartSize  = 0;
-    vr->XPlacementDevice.EndSize    = 0;
-    vr->XPlacementDevice.DeltaValue = NULL;
-  }
-
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail3;
-
-    new_offset = GET_UShort();
-
-    FORGET_Frame();
-
-    if ( new_offset )
-    {
-      new_offset += base_offset;
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = _HB_OPEN_Load_Device( &vr->YPlacementDevice,
-				  stream ) ) != HB_Err_Ok )
-	goto Fail3;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-      goto empty2;
-  }
-  else
-  {
-  empty2:
-    vr->YPlacementDevice.StartSize  = 0;
-    vr->YPlacementDevice.EndSize    = 0;
-    vr->YPlacementDevice.DeltaValue = NULL;
-  }
-
-  if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail2;
-
-    new_offset = GET_UShort();
-
-    FORGET_Frame();
-
-    if ( new_offset )
-    {
-      new_offset += base_offset;
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = _HB_OPEN_Load_Device( &vr->XAdvanceDevice,
-				  stream ) ) != HB_Err_Ok )
-	goto Fail2;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-      goto empty3;
-  }
-  else
-  {
-  empty3:
-    vr->XAdvanceDevice.StartSize  = 0;
-    vr->XAdvanceDevice.EndSize    = 0;
-    vr->XAdvanceDevice.DeltaValue = NULL;
-  }
-
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort();
-
-    FORGET_Frame();
-
-    if ( new_offset )
-    {
-      new_offset += base_offset;
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = _HB_OPEN_Load_Device( &vr->YAdvanceDevice,
-				  stream ) ) != HB_Err_Ok )
-	goto Fail1;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-      goto empty4;
-  }
-  else
-  {
-  empty4:
-    vr->YAdvanceDevice.StartSize  = 0;
-    vr->YAdvanceDevice.EndSize    = 0;
-    vr->YAdvanceDevice.DeltaValue = NULL;
-  }
-
-  if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    vr->XIdPlacement = GET_UShort();
-
-    FORGET_Frame();
-  }
-  else
-    vr->XIdPlacement = 0;
-
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    vr->YIdPlacement = GET_UShort();
-
-    FORGET_Frame();
-  }
-  else
-    vr->YIdPlacement = 0;
-
-  if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    vr->XIdAdvance = GET_UShort();
-
-    FORGET_Frame();
-  }
-  else
-    vr->XIdAdvance = 0;
-
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    vr->YIdAdvance = GET_UShort();
-
-    FORGET_Frame();
-  }
-  else
-    vr->YIdAdvance = 0;
-
-  return HB_Err_Ok;
-
-Fail1:
-  _HB_OPEN_Free_Device( &vr->YAdvanceDevice );
-
-Fail2:
-  _HB_OPEN_Free_Device( &vr->XAdvanceDevice );
-
-Fail3:
-  _HB_OPEN_Free_Device( &vr->YPlacementDevice );
-  return error;
-}
-
-
-static void  Free_ValueRecord( HB_ValueRecord*  vr,
-			       HB_UShort         format )
-{
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE )
-    _HB_OPEN_Free_Device( &vr->YAdvanceDevice );
-  if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE )
-    _HB_OPEN_Free_Device( &vr->XAdvanceDevice );
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE )
-    _HB_OPEN_Free_Device( &vr->YPlacementDevice );
-  if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE )
-    _HB_OPEN_Free_Device( &vr->XPlacementDevice );
-}
-
-
-static HB_Error  Get_ValueRecord( GPOS_Instance*    gpi,
-				  HB_ValueRecord*  vr,
-				  HB_UShort         format,
-				  HB_Position      gd )
-{
-  HB_Fixed           value;
-  HB_Short         pixel_value;
-  HB_Error         error = HB_Err_Ok;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-
-  HB_UShort  x_ppem, y_ppem;
-  HB_16Dot16   x_scale, y_scale;
-
-
-  if ( !format )
-    return HB_Err_Ok;
-
-  x_ppem  = gpi->font->x_ppem;
-  y_ppem  = gpi->font->y_ppem;
-  x_scale = gpi->font->x_scale;
-  y_scale = gpi->font->y_scale;
-
-  /* design units -> fractional pixel */
-
-  if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT )
-    gd->x_pos += x_scale * vr->XPlacement / 0x10000;
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT )
-    gd->y_pos += y_scale * vr->YPlacement / 0x10000;
-  if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE )
-    gd->x_advance += x_scale * vr->XAdvance / 0x10000;
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE )
-    gd->y_advance += y_scale * vr->YAdvance / 0x10000;
-
-  if ( !gpi->dvi )
-  {
-    /* pixel -> fractional pixel */
-
-    if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE )
-    {
-      _HB_OPEN_Get_Device( &vr->XPlacementDevice, x_ppem, &pixel_value );
-      gd->x_pos += pixel_value << 6;
-    }
-    if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE )
-    {
-      _HB_OPEN_Get_Device( &vr->YPlacementDevice, y_ppem, &pixel_value );
-      gd->y_pos += pixel_value << 6;
-    }
-    if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE )
-    {
-      _HB_OPEN_Get_Device( &vr->XAdvanceDevice, x_ppem, &pixel_value );
-      gd->x_advance += pixel_value << 6;
-    }
-    if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE )
-    {
-      _HB_OPEN_Get_Device( &vr->YAdvanceDevice, y_ppem, &pixel_value );
-      gd->y_advance += pixel_value << 6;
-    }
-  }
-
-  /* values returned from mmfunc() are already in fractional pixels */
-
-  if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT )
-  {
-    error = (gpos->mmfunc)( gpi->font, vr->XIdPlacement,
-			    &value, gpos->data );
-    if ( error )
-      return error;
-    gd->x_pos += value;
-  }
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT )
-  {
-    error = (gpos->mmfunc)( gpi->font, vr->YIdPlacement,
-			    &value, gpos->data );
-    if ( error )
-      return error;
-    gd->y_pos += value;
-  }
-  if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE )
-  {
-    error = (gpos->mmfunc)( gpi->font, vr->XIdAdvance,
-			    &value, gpos->data );
-    if ( error )
-      return error;
-    gd->x_advance += value;
-  }
-  if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE )
-  {
-    error = (gpos->mmfunc)( gpi->font, vr->YIdAdvance,
-			    &value, gpos->data );
-    if ( error )
-      return error;
-    gd->y_advance += value;
-  }
-
-  return error;
-}
-
-
-/* AnchorFormat1 */
-/* AnchorFormat2 */
-/* AnchorFormat3 */
-/* AnchorFormat4 */
-
-static HB_Error  Load_Anchor( HB_Anchor*  an,
-			      HB_Stream    stream )
-{
-  HB_Error  error;
-
-  HB_UInt cur_offset, new_offset, base_offset;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  an->PosFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  switch ( an->PosFormat )
-  {
-  case 1:
-    if ( ACCESS_Frame( 4L ) )
-      return error;
-
-    an->af.af1.XCoordinate = GET_Short();
-    an->af.af1.YCoordinate = GET_Short();
-
-    FORGET_Frame();
-    break;
-
-  case 2:
-    if ( ACCESS_Frame( 6L ) )
-      return error;
-
-    an->af.af2.XCoordinate = GET_Short();
-    an->af.af2.YCoordinate = GET_Short();
-    an->af.af2.AnchorPoint = GET_UShort();
-
-    FORGET_Frame();
-    break;
-
-  case 3:
-    if ( ACCESS_Frame( 6L ) )
-      return error;
-
-    an->af.af3.XCoordinate = GET_Short();
-    an->af.af3.YCoordinate = GET_Short();
-
-    new_offset = GET_UShort();
-
-    FORGET_Frame();
-
-    if ( new_offset )
-    {
-      new_offset += base_offset;
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = _HB_OPEN_Load_Device( &an->af.af3.XDeviceTable,
-				  stream ) ) != HB_Err_Ok )
-	return error;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-    {
-      an->af.af3.XDeviceTable.StartSize  = 0;
-      an->af.af3.XDeviceTable.EndSize    = 0;
-      an->af.af3.XDeviceTable.DeltaValue = NULL;
-    }
-
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort();
-
-    FORGET_Frame();
-
-    if ( new_offset )
-    {
-      new_offset += base_offset;
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = _HB_OPEN_Load_Device( &an->af.af3.YDeviceTable,
-				  stream ) ) != HB_Err_Ok )
-	goto Fail;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-    {
-      an->af.af3.YDeviceTable.StartSize  = 0;
-      an->af.af3.YDeviceTable.EndSize    = 0;
-      an->af.af3.YDeviceTable.DeltaValue = NULL;
-    }
-    break;
-
-  case 4:
-    if ( ACCESS_Frame( 4L ) )
-      return error;
-
-    an->af.af4.XIdAnchor = GET_UShort();
-    an->af.af4.YIdAnchor = GET_UShort();
-
-    FORGET_Frame();
-    break;
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable );
-  return error;
-}
-
-
-static void  Free_Anchor( HB_Anchor*  an)
-{
-  if ( an->PosFormat == 3 )
-  {
-    _HB_OPEN_Free_Device( &an->af.af3.YDeviceTable );
-    _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable );
-  }
-}
-
-
-static HB_Error  Get_Anchor( GPOS_Instance*   gpi,
-			     HB_Anchor*      an,
-			     HB_UShort        glyph_index,
-			     HB_Fixed*          x_value,
-			     HB_Fixed*          y_value )
-{
-  HB_Error  error = HB_Err_Ok;
-
-  HB_GPOSHeader*  gpos = gpi->gpos;
-  HB_UShort        ap;
-
-  HB_Short         pixel_value;
-
-  HB_UShort        x_ppem, y_ppem;
-  HB_16Dot16         x_scale, y_scale;
-
-
-  x_ppem  = gpi->font->x_ppem;
-  y_ppem  = gpi->font->y_ppem;
-  x_scale = gpi->font->x_scale;
-  y_scale = gpi->font->y_scale;
-
-  switch ( an->PosFormat )
-  {
-  case 0:
-    /* The special case of an empty AnchorTable */
-  default:
-
-    return HB_Err_Not_Covered;
-
-  case 1:
-    *x_value = x_scale * an->af.af1.XCoordinate / 0x10000;
-    *y_value = y_scale * an->af.af1.YCoordinate / 0x10000;
-    break;
-
-  case 2:
-    if ( !gpi->dvi )
-    {
-      hb_uint32 n_points = 0;
-      ap = an->af.af2.AnchorPoint;
-      if (!gpi->font->klass->getPointInOutline)
-          goto no_contour_point;
-      error = gpi->font->klass->getPointInOutline(gpi->font, glyph_index, gpi->load_flags, ap, x_value, y_value, &n_points);
-      if (error)
-          return error;
-      /* if n_points is set to zero, we use the design coordinate value pair.
-       * This can happen e.g. for sbit glyphs. */
-      if (!n_points)
-          goto no_contour_point;
-    }
-    else
-    {
-    no_contour_point:
-      *x_value = x_scale * an->af.af3.XCoordinate / 0x10000;
-      *y_value = y_scale * an->af.af3.YCoordinate / 0x10000;
-    }
-    break;
-
-  case 3:
-    if ( !gpi->dvi )
-    {
-      _HB_OPEN_Get_Device( &an->af.af3.XDeviceTable, x_ppem, &pixel_value );
-      *x_value = pixel_value << 6;
-      _HB_OPEN_Get_Device( &an->af.af3.YDeviceTable, y_ppem, &pixel_value );
-      *y_value = pixel_value << 6;
-    }
-    else
-      *x_value = *y_value = 0;
-
-    *x_value += x_scale * an->af.af3.XCoordinate / 0x10000;
-    *y_value += y_scale * an->af.af3.YCoordinate / 0x10000;
-    break;
-
-  case 4:
-    error = (gpos->mmfunc)( gpi->font, an->af.af4.XIdAnchor,
-			    x_value, gpos->data );
-    if ( error )
-      return error;
-
-    error = (gpos->mmfunc)( gpi->font, an->af.af4.YIdAnchor,
-			    y_value, gpos->data );
-    if ( error )
-      return error;
-    break;
-  }
-
-  return error;
-}
-
-
-/* MarkArray */
-
-static HB_Error  Load_MarkArray ( HB_MarkArray*  ma,
-				  HB_Stream       stream )
-{
-  HB_Error  error;
-
-  HB_UShort        n, m, count;
-  HB_UInt         cur_offset, new_offset, base_offset;
-
-  HB_MarkRecord*  mr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = ma->MarkCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ma->MarkRecord = NULL;
-
-  if ( ALLOC_ARRAY( ma->MarkRecord, count, HB_MarkRecord ) )
-    return error;
-
-  mr = ma->MarkRecord;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 4L ) )
-      goto Fail;
-
-    mr[n].Class = GET_UShort();
-    new_offset  = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_Anchor( &mr[n].MarkAnchor, stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_Anchor( &mr[m].MarkAnchor );
-
-  FREE( mr );
-  return error;
-}
-
-
-static void  Free_MarkArray( HB_MarkArray*  ma )
-{
-  HB_UShort        n, count;
-
-  HB_MarkRecord*  mr;
-
-
-  if ( ma->MarkRecord )
-  {
-    count = ma->MarkCount;
-    mr    = ma->MarkRecord;
-
-    for ( n = 0; n < count; n++ )
-      Free_Anchor( &mr[n].MarkAnchor );
-
-    FREE( mr );
-  }
-}
-
-
-/* LookupType 1 */
-
-/* SinglePosFormat1 */
-/* SinglePosFormat2 */
-
-static HB_Error  Load_SinglePos( HB_GPOS_SubTable* st,
-				 HB_Stream       stream )
-{
-  HB_Error  error;
-  HB_SinglePos*   sp = &st->single;
-
-  HB_UShort         n, m, count, format;
-  HB_UInt          cur_offset, new_offset, base_offset;
-
-  HB_ValueRecord*  vr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 6L ) )
-    return error;
-
-  sp->PosFormat = GET_UShort();
-  new_offset    = GET_UShort() + base_offset;
-
-  format = sp->ValueFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( !format )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &sp->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  switch ( sp->PosFormat )
-  {
-  case 1:
-    error = Load_ValueRecord( &sp->spf.spf1.Value, format,
-			      base_offset, stream );
-    if ( error )
-      goto Fail2;
-    break;
-
-  case 2:
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail2;
-
-    count = sp->spf.spf2.ValueCount = GET_UShort();
-
-    FORGET_Frame();
-
-    sp->spf.spf2.Value = NULL;
-
-    if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, HB_ValueRecord ) )
-      goto Fail2;
-
-    vr = sp->spf.spf2.Value;
-
-    for ( n = 0; n < count; n++ )
-    {
-      error = Load_ValueRecord( &vr[n], format, base_offset, stream );
-      if ( error )
-	goto Fail1;
-    }
-    break;
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_ValueRecord( &vr[m], format );
-
-  FREE( vr );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &sp->Coverage );
-  return error;
-}
-
-
-static void  Free_SinglePos( HB_GPOS_SubTable* st )
-{
-  HB_UShort         n, count, format;
-  HB_SinglePos*   sp = &st->single;
-
-  HB_ValueRecord*  v;
-
-
-  format = sp->ValueFormat;
-
-  switch ( sp->PosFormat )
-  {
-  case 1:
-    Free_ValueRecord( &sp->spf.spf1.Value, format );
-    break;
-
-  case 2:
-    if ( sp->spf.spf2.Value )
-    {
-      count = sp->spf.spf2.ValueCount;
-      v     = sp->spf.spf2.Value;
-
-      for ( n = 0; n < count; n++ )
-	Free_ValueRecord( &v[n], format );
-
-      FREE( v );
-    }
-    break;
-  default:
-    break;
-  }
-
-  _HB_OPEN_Free_Coverage( &sp->Coverage );
-}
-
-static HB_Error  Lookup_SinglePos( GPOS_Instance*    gpi,
-				   HB_GPOS_SubTable* st,
-				   HB_Buffer        buffer,
-				   HB_UShort         flags,
-				   HB_UShort         context_length,
-				   int               nesting_level )
-{
-  HB_UShort        index, property;
-  HB_Error         error;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-  HB_SinglePos*   sp = &st->single;
-
-  HB_UNUSED(nesting_level);
-
-  if ( context_length != 0xFFFF && context_length < 1 )
-    return HB_Err_Not_Covered;
-
-  if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &sp->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  switch ( sp->PosFormat )
-  {
-  case 1:
-    error = Get_ValueRecord( gpi, &sp->spf.spf1.Value,
-			     sp->ValueFormat, POSITION( buffer->in_pos ) );
-    if ( error )
-      return error;
-    break;
-
-  case 2:
-    if ( index >= sp->spf.spf2.ValueCount )
-      return ERR(HB_Err_Invalid_SubTable);
-    error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index],
-			     sp->ValueFormat, POSITION( buffer->in_pos ) );
-    if ( error )
-      return error;
-    break;
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable);
-  }
-
-  (buffer->in_pos)++;
-
-  return HB_Err_Ok;
-}
-
-
-/* LookupType 2 */
-
-/* PairSet */
-
-static HB_Error  Load_PairSet ( HB_PairSet*  ps,
-				HB_UShort     format1,
-				HB_UShort     format2,
-				HB_Stream     stream )
-{
-  HB_Error  error;
-
-  HB_UShort             n, m, count;
-  HB_UInt              base_offset;
-
-  HB_PairValueRecord*  pvr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = ps->PairValueCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ps->PairValueRecord = NULL;
-
-  if ( ALLOC_ARRAY( ps->PairValueRecord, count, HB_PairValueRecord ) )
-    return error;
-
-  pvr = ps->PairValueRecord;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    pvr[n].SecondGlyph = GET_UShort();
-
-    FORGET_Frame();
-
-    if ( format1 )
-    {
-      error = Load_ValueRecord( &pvr[n].Value1, format1,
-				base_offset, stream );
-      if ( error )
-	goto Fail;
-    }
-    if ( format2 )
-    {
-      error = Load_ValueRecord( &pvr[n].Value2, format2,
-				base_offset, stream );
-      if ( error )
-      {
-	if ( format1 )
-	  Free_ValueRecord( &pvr[n].Value1, format1 );
-	goto Fail;
-      }
-    }
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-  {
-    if ( format1 )
-      Free_ValueRecord( &pvr[m].Value1, format1 );
-    if ( format2 )
-      Free_ValueRecord( &pvr[m].Value2, format2 );
-  }
-
-  FREE( pvr );
-  return error;
-}
-
-
-static void  Free_PairSet( HB_PairSet*  ps,
-			   HB_UShort     format1,
-			   HB_UShort     format2 )
-{
-  HB_UShort             n, count;
-
-  HB_PairValueRecord*  pvr;
-
-
-  if ( ps->PairValueRecord )
-  {
-    count = ps->PairValueCount;
-    pvr   = ps->PairValueRecord;
-
-    for ( n = 0; n < count; n++ )
-    {
-      if ( format1 )
-	Free_ValueRecord( &pvr[n].Value1, format1 );
-      if ( format2 )
-	Free_ValueRecord( &pvr[n].Value2, format2 );
-    }
-
-    FREE( pvr );
-  }
-}
-
-
-/* PairPosFormat1 */
-
-static HB_Error  Load_PairPos1( HB_PairPosFormat1*  ppf1,
-				HB_UShort            format1,
-				HB_UShort            format2,
-				HB_Stream            stream )
-{
-  HB_Error  error;
-
-  HB_UShort     n, m, count;
-  HB_UInt      cur_offset, new_offset, base_offset;
-
-  HB_PairSet*  ps;
-
-
-  base_offset = FILE_Pos() - 8L;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = ppf1->PairSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ppf1->PairSet = NULL;
-
-  if ( ALLOC_ARRAY( ppf1->PairSet, count, HB_PairSet ) )
-    return error;
-
-  ps = ppf1->PairSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_PairSet( &ps[n], format1,
-				 format2, stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_PairSet( &ps[m], format1, format2 );
-
-  FREE( ps );
-  return error;
-}
-
-
-static void  Free_PairPos1( HB_PairPosFormat1*  ppf1,
-			    HB_UShort            format1,
-			    HB_UShort            format2 )
-{
-  HB_UShort     n, count;
-
-  HB_PairSet*  ps;
-
-
-  if ( ppf1->PairSet )
-  {
-    count = ppf1->PairSetCount;
-    ps    = ppf1->PairSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_PairSet( &ps[n], format1, format2 );
-
-    FREE( ps );
-  }
-}
-
-
-/* PairPosFormat2 */
-
-static HB_Error  Load_PairPos2( HB_PairPosFormat2*  ppf2,
-				HB_UShort            format1,
-				HB_UShort            format2,
-				HB_Stream            stream )
-{
-  HB_Error  error;
-
-  HB_UShort          m, n, k, count1, count2;
-  HB_UInt           cur_offset, new_offset1, new_offset2, base_offset;
-
-  HB_Class1Record*  c1r;
-  HB_Class2Record*  c2r;
-
-
-  base_offset = FILE_Pos() - 8L;
-
-  if ( ACCESS_Frame( 8L ) )
-    return error;
-
-  new_offset1 = GET_UShort() + base_offset;
-  new_offset2 = GET_UShort() + base_offset;
-
-  /* `Class1Count' and `Class2Count' are the upper limits for class
-     values, thus we read it now to make additional safety checks.  */
-
-  count1 = ppf2->Class1Count = GET_UShort();
-  count2 = ppf2->Class2Count = GET_UShort();
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset1 ) ||
-       ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef1, count1,
-				       stream ) ) != HB_Err_Ok )
-    return error;
-  if ( FILE_Seek( new_offset2 ) ||
-       ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef2, count2,
-				       stream ) ) != HB_Err_Ok )
-    goto Fail3;
-  (void)FILE_Seek( cur_offset );
-
-  ppf2->Class1Record = NULL;
-
-  if ( ALLOC_ARRAY( ppf2->Class1Record, count1, HB_Class1Record ) )
-    goto Fail2;
-
-  c1r = ppf2->Class1Record;
-
-  for ( m = 0; m < count1; m++ )
-  {
-    c1r[m].Class2Record = NULL;
-
-    if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, HB_Class2Record ) )
-      goto Fail1;
-
-    c2r = c1r[m].Class2Record;
-
-    for ( n = 0; n < count2; n++ )
-    {
-      if ( format1 )
-      {
-	error = Load_ValueRecord( &c2r[n].Value1, format1,
-				  base_offset, stream );
-	if ( error )
-	  goto Fail0;
-      }
-      if ( format2 )
-      {
-	error = Load_ValueRecord( &c2r[n].Value2, format2,
-				  base_offset, stream );
-	if ( error )
-	{
-	  if ( format1 )
-	    Free_ValueRecord( &c2r[n].Value1, format1 );
-	  goto Fail0;
-	}
-      }
-    }
-
-    continue;
-
-  Fail0:
-    for ( k = 0; k < n; k++ )
-    {
-      if ( format1 )
-	Free_ValueRecord( &c2r[k].Value1, format1 );
-      if ( format2 )
-	Free_ValueRecord( &c2r[k].Value2, format2 );
-    }
-    goto Fail1;
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( k = 0; k < m; k++ )
-  {
-    c2r = c1r[k].Class2Record;
-
-    for ( n = 0; n < count2; n++ )
-    {
-      if ( format1 )
-	Free_ValueRecord( &c2r[n].Value1, format1 );
-      if ( format2 )
-	Free_ValueRecord( &c2r[n].Value2, format2 );
-    }
-
-    FREE( c2r );
-  }
-
-  FREE( c1r );
-Fail2:
-
-  _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 );
-
-Fail3:
-  _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 );
-  return error;
-}
-
-
-static void  Free_PairPos2( HB_PairPosFormat2*  ppf2,
-			    HB_UShort            format1,
-			    HB_UShort            format2)
-{
-  HB_UShort          m, n, count1, count2;
-
-  HB_Class1Record*  c1r;
-  HB_Class2Record*  c2r;
-
-
-  if ( ppf2->Class1Record )
-  {
-    c1r    = ppf2->Class1Record;
-    count1 = ppf2->Class1Count;
-    count2 = ppf2->Class2Count;
-
-    for ( m = 0; m < count1; m++ )
-    {
-      c2r = c1r[m].Class2Record;
-
-      for ( n = 0; n < count2; n++ )
-      {
-	if ( format1 )
-	  Free_ValueRecord( &c2r[n].Value1, format1 );
-	if ( format2 )
-	  Free_ValueRecord( &c2r[n].Value2, format2 );
-      }
-
-      FREE( c2r );
-    }
-
-    FREE( c1r );
-
-    _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 );
-    _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 );
-  }
-}
-
-
-static HB_Error  Load_PairPos( HB_GPOS_SubTable* st,
-			       HB_Stream     stream )
-{
-  HB_Error  error;
-  HB_PairPos*     pp = &st->pair;
-
-  HB_UShort         format1, format2;
-  HB_UInt          cur_offset, new_offset, base_offset;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 8L ) )
-    return error;
-
-  pp->PosFormat = GET_UShort();
-  new_offset    = GET_UShort() + base_offset;
-
-  format1 = pp->ValueFormat1 = GET_UShort();
-  format2 = pp->ValueFormat2 = GET_UShort();
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &pp->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  switch ( pp->PosFormat )
-  {
-  case 1:
-    error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, stream );
-    if ( error )
-      goto Fail;
-    break;
-
-  case 2:
-    error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, stream );
-    if ( error )
-      goto Fail;
-    break;
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  _HB_OPEN_Free_Coverage( &pp->Coverage );
-  return error;
-}
-
-
-static void  Free_PairPos( HB_GPOS_SubTable* st )
-{
-  HB_UShort  format1, format2;
-  HB_PairPos*     pp = &st->pair;
-
-
-  format1 = pp->ValueFormat1;
-  format2 = pp->ValueFormat2;
-
-  switch ( pp->PosFormat )
-  {
-  case 1:
-    Free_PairPos1( &pp->ppf.ppf1, format1, format2 );
-    break;
-
-  case 2:
-    Free_PairPos2( &pp->ppf.ppf2, format1, format2 );
-    break;
-
-  default:
-    break;
-  }
-
-  _HB_OPEN_Free_Coverage( &pp->Coverage );
-}
-
-
-static HB_Error  Lookup_PairPos1( GPOS_Instance*       gpi,
-				  HB_PairPosFormat1*  ppf1,
-				  HB_Buffer           buffer,
-				  HB_UInt              first_pos,
-				  HB_UShort            index,
-				  HB_UShort            format1,
-				  HB_UShort            format2 )
-{
-  HB_Error              error;
-  HB_UShort             numpvr, glyph2;
-
-  HB_PairValueRecord*  pvr;
-
-
-  if ( index >= ppf1->PairSetCount )
-     return ERR(HB_Err_Invalid_SubTable);
-
-  pvr = ppf1->PairSet[index].PairValueRecord;
-  if ( !pvr )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  glyph2 = IN_CURGLYPH();
-
-  for ( numpvr = ppf1->PairSet[index].PairValueCount;
-	numpvr;
-	numpvr--, pvr++ )
-  {
-    if ( glyph2 == pvr->SecondGlyph )
-    {
-      error = Get_ValueRecord( gpi, &pvr->Value1, format1,
-			       POSITION( first_pos ) );
-      if ( error )
-	return error;
-      return Get_ValueRecord( gpi, &pvr->Value2, format2,
-			      POSITION( buffer->in_pos ) );
-    }
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-static HB_Error  Lookup_PairPos2( GPOS_Instance*       gpi,
-				  HB_PairPosFormat2*  ppf2,
-				  HB_Buffer           buffer,
-				  HB_UInt              first_pos,
-				  HB_UShort            format1,
-				  HB_UShort            format2 )
-{
-  HB_Error           error;
-  HB_UShort          cl1 = 0, cl2 = 0; /* shut compiler up */
-
-  HB_Class1Record*  c1r;
-  HB_Class2Record*  c2r;
-
-
-  error = _HB_OPEN_Get_Class( &ppf2->ClassDef1, IN_GLYPH( first_pos ),
-		     &cl1, NULL );
-  if ( error && error != HB_Err_Not_Covered )
-    return error;
-  error = _HB_OPEN_Get_Class( &ppf2->ClassDef2, IN_CURGLYPH(),
-		     &cl2, NULL );
-  if ( error && error != HB_Err_Not_Covered )
-    return error;
-
-  c1r = &ppf2->Class1Record[cl1];
-  if ( !c1r )
-    return ERR(HB_Err_Invalid_SubTable);
-  c2r = &c1r->Class2Record[cl2];
-
-  error = Get_ValueRecord( gpi, &c2r->Value1, format1, POSITION( first_pos ) );
-  if ( error )
-    return error;
-  return Get_ValueRecord( gpi, &c2r->Value2, format2, POSITION( buffer->in_pos ) );
-}
-
-
-static HB_Error  Lookup_PairPos( GPOS_Instance*    gpi,
-				 HB_GPOS_SubTable* st,
-				 HB_Buffer        buffer,
-				 HB_UShort         flags,
-				 HB_UShort         context_length,
-				 int               nesting_level )
-{
-  HB_Error         error;
-  HB_UShort        index, property;
-  HB_UInt          first_pos;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-  HB_PairPos*     pp = &st->pair;
-
-  HB_UNUSED(nesting_level);
-
-  if ( buffer->in_pos >= buffer->in_length - 1 )
-    return HB_Err_Not_Covered;           /* Not enough glyphs in stream */
-
-  if ( context_length != 0xFFFF && context_length < 2 )
-    return HB_Err_Not_Covered;
-
-  if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &pp->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  /* second glyph */
-
-  first_pos = buffer->in_pos;
-  (buffer->in_pos)++;
-
-  while ( CHECK_Property( gpos->gdef, IN_CURITEM(),
-			  flags, &property ) )
-  {
-    if ( error && error != HB_Err_Not_Covered )
-      return error;
-
-    if ( buffer->in_pos == buffer->in_length )
-      {
-	buffer->in_pos = first_pos;
-        return HB_Err_Not_Covered;
-      }
-    (buffer->in_pos)++;
-
-  }
-
-  switch ( pp->PosFormat )
-  {
-  case 1:
-    error = Lookup_PairPos1( gpi, &pp->ppf.ppf1, buffer,
-			     first_pos, index,
-			     pp->ValueFormat1, pp->ValueFormat2 );
-    break;
-
-  case 2:
-    error = Lookup_PairPos2( gpi, &pp->ppf.ppf2, buffer, first_pos,
-			     pp->ValueFormat1, pp->ValueFormat2 );
-    break;
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  /* if we don't have coverage for the second glyph don't skip it for
-     further lookups but reset in_pos back to the first_glyph and let
-     the caller in Do_String_Lookup increment in_pos */
-  if ( error == HB_Err_Not_Covered )
-      buffer->in_pos = first_pos;
-
-  /* adjusting the `next' glyph */
-
-  if ( pp->ValueFormat2 )
-    (buffer->in_pos)++;
-
-  return error;
-}
-
-
-/* LookupType 3 */
-
-/* CursivePosFormat1 */
-
-static HB_Error  Load_CursivePos( HB_GPOS_SubTable* st,
-				  HB_Stream        stream )
-{
-  HB_Error  error;
-  HB_CursivePos*  cp = &st->cursive;
-
-  HB_UShort             n, m, count;
-  HB_UInt              cur_offset, new_offset, base_offset;
-
-  HB_EntryExitRecord*  eer;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  cp->PosFormat = GET_UShort();
-  new_offset    = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &cp->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = cp->EntryExitCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cp->EntryExitRecord = NULL;
-
-  if ( ALLOC_ARRAY( cp->EntryExitRecord, count, HB_EntryExitRecord ) )
-    goto Fail2;
-
-  eer = cp->EntryExitRecord;
-
-  for ( n = 0; n < count; n++ )
-  {
-    HB_UInt entry_offset;
-
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    entry_offset = new_offset = GET_UShort();
-
-    FORGET_Frame();
-
-    if ( new_offset )
-    {
-      new_offset += base_offset;
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = Load_Anchor( &eer[n].EntryAnchor,
-				  stream ) ) != HB_Err_Ok )
-	goto Fail1;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-      eer[n].EntryAnchor.PosFormat   = 0;
-
-    if ( ACCESS_Frame( 2L ) )
-      return error;
-
-    new_offset = GET_UShort();
-
-    FORGET_Frame();
-
-    if ( new_offset )
-    {
-      new_offset += base_offset;
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = Load_Anchor( &eer[n].ExitAnchor,
-				  stream ) ) != HB_Err_Ok )
-      {
-	if ( entry_offset )
-	  Free_Anchor( &eer[n].EntryAnchor );
-	goto Fail1;
-      }
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-      eer[n].ExitAnchor.PosFormat   = 0;
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-  {
-    Free_Anchor( &eer[m].EntryAnchor );
-    Free_Anchor( &eer[m].ExitAnchor );
-  }
-
-  FREE( eer );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &cp->Coverage );
-  return error;
-}
-
-
-static void  Free_CursivePos( HB_GPOS_SubTable* st )
-{
-  HB_UShort             n, count;
-  HB_CursivePos*  cp = &st->cursive;
-
-  HB_EntryExitRecord*  eer;
-
-
-  if ( cp->EntryExitRecord )
-  {
-    count = cp->EntryExitCount;
-    eer   = cp->EntryExitRecord;
-
-    for ( n = 0; n < count; n++ )
-    {
-      Free_Anchor( &eer[n].EntryAnchor );
-      Free_Anchor( &eer[n].ExitAnchor );
-    }
-
-    FREE( eer );
-  }
-
-  _HB_OPEN_Free_Coverage( &cp->Coverage );
-}
-
-
-static HB_Error  Lookup_CursivePos( GPOS_Instance*    gpi,
-				    HB_GPOS_SubTable* st,
-				    HB_Buffer        buffer,
-				    HB_UShort         flags,
-				    HB_UShort         context_length,
-				    int               nesting_level )
-{
-  HB_UShort        index, property;
-  HB_Error         error;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-  HB_CursivePos*  cp = &st->cursive;
-
-  HB_EntryExitRecord*  eer;
-  HB_Fixed                entry_x, entry_y;
-  HB_Fixed                exit_x, exit_y;
-
-  HB_UNUSED(nesting_level);
-
-  if ( context_length != 0xFFFF && context_length < 1 )
-  {
-    gpi->last = 0xFFFF;
-    return HB_Err_Not_Covered;
-  }
-
-  /* Glyphs not having the right GDEF properties will be ignored, i.e.,
-     gpi->last won't be reset (contrary to user defined properties). */
-
-  if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  /* We don't handle mark glyphs here.  According to Andrei, this isn't
-     possible, but who knows...                                         */
-
-  if ( property == HB_GDEF_MARK )
-  {
-    gpi->last = 0xFFFF;
-    return HB_Err_Not_Covered;
-  }
-
-  error = _HB_OPEN_Coverage_Index( &cp->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-  {
-    gpi->last = 0xFFFF;
-    return error;
-  }
-
-  if ( index >= cp->EntryExitCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  eer = &cp->EntryExitRecord[index];
-
-  /* Now comes the messiest part of the whole OpenType
-     specification.  At first glance, cursive connections seem easy
-     to understand, but there are pitfalls!  The reason is that
-     the specs don't mention how to compute the advance values
-     resp. glyph offsets.  I was told it would be an omission, to
-     be fixed in the next OpenType version...  Again many thanks to
-     Andrei Burago <andreib@microsoft.com> for clarifications.
-
-     Consider the following example:
-
-		      |  xadv1    |
-		       +---------+
-		       |         |
-		 +-----+--+ 1    |
-		 |     | .|      |
-		 |    0+--+------+
-		 |   2    |
-		 |        |
-		0+--------+
-		|  xadv2   |
-
-       glyph1: advance width = 12
-	       anchor point = (3,1)
-
-       glyph2: advance width = 11
-	       anchor point = (9,4)
-
-       LSB is 1 for both glyphs (so the boxes drawn above are glyph
-       bboxes).  Writing direction is R2L; `0' denotes the glyph's
-       coordinate origin.
-
-     Now the surprising part: The advance width of the *left* glyph
-     (resp. of the *bottom* glyph) will be modified, no matter
-     whether the writing direction is L2R or R2L (resp. T2B or
-     B2T)!  This assymetry is caused by the fact that the glyph's
-     coordinate origin is always the lower left corner for all
-     writing directions.
-
-     Continuing the above example, we can compute the new
-     (horizontal) advance width of glyph2 as
-
-       9 - 3 = 6  ,
-
-     and the new vertical offset of glyph2 as
-
-       1 - 4 = -3  .
-
-
-     Vertical writing direction is far more complicated:
-
-     a) Assuming that we recompute the advance height of the lower glyph:
-
-				  --
-		       +---------+
-	      --       |         |
-		 +-----+--+ 1    | yadv1
-		 |     | .|      |
-	   yadv2 |    0+--+------+        -- BSB1  --
-		 |   2    |       --      --        y_offset
-		 |        |
-   BSB2 --      0+--------+                        --
-	--    --
-
-       glyph1: advance height = 6
-	       anchor point = (3,1)
-
-       glyph2: advance height = 7
-	       anchor point = (9,4)
-
-       TSB is 1 for both glyphs; writing direction is T2B.
-
-
-	 BSB1     = yadv1 - (TSB1 + ymax1)
-	 BSB2     = yadv2 - (TSB2 + ymax2)
-	 y_offset = y2 - y1
-
-       vertical advance width of glyph2
-	 = y_offset + BSB2 - BSB1
-	 = (y2 - y1) + (yadv2 - (TSB2 + ymax2)) - (yadv1 - (TSB1 + ymax1))
-	 = y2 - y1 + yadv2 - TSB2 - ymax2 - (yadv1 - TSB1 - ymax1)
-	 = y2 - y1 + yadv2 - TSB2 - ymax2 - yadv1 + TSB1 + ymax1
-
-
-     b) Assuming that we recompute the advance height of the upper glyph:
-
-				  --      --
-		       +---------+        -- TSB1
-	--    --       |         |
-   TSB2 --       +-----+--+ 1    | yadv1   ymax1
-		 |     | .|      |
-	   yadv2 |    0+--+------+        --       --
-    ymax2        |   2    |       --                y_offset
-		 |        |
-	--      0+--------+                        --
-	      --
-
-       glyph1: advance height = 6
-	       anchor point = (3,1)
-
-       glyph2: advance height = 7
-	       anchor point = (9,4)
-
-       TSB is 1 for both glyphs; writing direction is T2B.
-
-       y_offset = y2 - y1
-
-       vertical advance width of glyph2
-	 = TSB1 + ymax1 + y_offset - (TSB2 + ymax2)
-	 = TSB1 + ymax1 + y2 - y1 - TSB2 - ymax2
-
-
-     Comparing a) with b) shows that b) is easier to compute.  I'll wait
-     for a reply from Andrei to see what should really be implemented...
-
-     Since horizontal advance widths or vertical advance heights
-     can be used alone but not together, no ambiguity occurs.        */
-
-  if ( gpi->last == 0xFFFF )
-    goto end;
-
-  /* Get_Anchor() returns HB_Err_Not_Covered if there is no anchor
-     table.                                                         */
-
-  error = Get_Anchor( gpi, &eer->EntryAnchor, IN_CURGLYPH(),
-		      &entry_x, &entry_y );
-  if ( error == HB_Err_Not_Covered )
-    goto end;
-  if ( error )
-    return error;
-
-  if ( gpi->r2l )
-  {
-    POSITION( buffer->in_pos )->x_advance   = entry_x - gpi->anchor_x;
-    POSITION( buffer->in_pos )->new_advance = TRUE;
-  }
-  else
-  {
-    POSITION( gpi->last )->x_advance   = gpi->anchor_x - entry_x;
-    POSITION( gpi->last )->new_advance = TRUE;
-  }
-
-  if ( flags & HB_LOOKUP_FLAG_RIGHT_TO_LEFT )
-  {
-    POSITION( gpi->last )->cursive_chain = gpi->last - buffer->in_pos;
-    POSITION( gpi->last )->y_pos = entry_y - gpi->anchor_y;
-  }
-  else
-  {
-    POSITION( buffer->in_pos )->cursive_chain = buffer->in_pos - gpi->last;
-    POSITION( buffer->in_pos )->y_pos = gpi->anchor_y - entry_y;
-  }
-
-end:
-  error = Get_Anchor( gpi, &eer->ExitAnchor, IN_CURGLYPH(),
-		      &exit_x, &exit_y );
-  if ( error == HB_Err_Not_Covered )
-    gpi->last = 0xFFFF;
-  else
-  {
-    gpi->last     = buffer->in_pos;
-    gpi->anchor_x = exit_x;
-    gpi->anchor_y = exit_y;
-  }
-  if ( error )
-    return error;
-
-  (buffer->in_pos)++;
-
-  return HB_Err_Ok;
-}
-
-
-/* LookupType 4 */
-
-/* BaseArray */
-
-static HB_Error  Load_BaseArray( HB_BaseArray*  ba,
-				 HB_UShort       num_classes,
-				 HB_Stream       stream )
-{
-  HB_Error  error;
-
-  HB_UShort       m, n, count;
-  HB_UInt         cur_offset, new_offset, base_offset;
-
-  HB_BaseRecord  *br;
-  HB_Anchor      *ban, *bans;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = ba->BaseCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ba->BaseRecord = NULL;
-
-  if ( ALLOC_ARRAY( ba->BaseRecord, count, HB_BaseRecord ) )
-    return error;
-
-  br = ba->BaseRecord;
-
-  bans = NULL;
-
-  if ( ALLOC_ARRAY( bans, count * num_classes, HB_Anchor ) )
-    goto Fail;
-
-  for ( m = 0; m < count; m++ )
-  {
-    br[m].BaseAnchor = NULL;
-
-    ban = br[m].BaseAnchor = bans + m * num_classes;
-
-    for ( n = 0; n < num_classes; n++ )
-    {
-      if ( ACCESS_Frame( 2L ) )
-	goto Fail;
-
-      new_offset = GET_UShort() + base_offset;
-
-      FORGET_Frame();
-
-      if (new_offset == base_offset) {
-	/* XXX
-	 * Doulos SIL Regular is buggy and has zero offsets here.
-	 * Skip it
-	 */
-	ban[n].PosFormat = 0;
-	continue;
-      }
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = Load_Anchor( &ban[n], stream ) ) != HB_Err_Ok )
-	goto Fail;
-      (void)FILE_Seek( cur_offset );
-    }
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  FREE( bans );
-  FREE( br );
-  return error;
-}
-
-
-static void  Free_BaseArray( HB_BaseArray*  ba,
-			     HB_UShort       num_classes )
-{
-  HB_BaseRecord  *br;
-  HB_Anchor      *bans;
-
-  if ( ba->BaseRecord )
-  {
-    br    = ba->BaseRecord;
-
-    if ( ba->BaseCount )
-    {
-      HB_UShort i, count;
-      count = num_classes * ba->BaseCount;
-      bans = br[0].BaseAnchor;
-      for (i = 0; i < count; i++)
-        Free_Anchor (&bans[i]);
-      FREE( bans );
-    }
-
-    FREE( br );
-  }
-}
-
-
-/* MarkBasePosFormat1 */
-
-static HB_Error  Load_MarkBasePos( HB_GPOS_SubTable* st,
-				   HB_Stream         stream )
-{
-  HB_Error  error;
-  HB_MarkBasePos* mbp = &st->markbase;
-
-  HB_UInt  cur_offset, new_offset, base_offset;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  mbp->PosFormat = GET_UShort();
-  new_offset     = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  if (mbp->PosFormat != 1)
-    return ERR(HB_Err_Invalid_SubTable_Format);
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &mbp->MarkCoverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &mbp->BaseCoverage, stream ) ) != HB_Err_Ok )
-    goto Fail3;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 4L ) )
-    goto Fail2;
-
-  mbp->ClassCount = GET_UShort();
-  new_offset      = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = Load_MarkArray( &mbp->MarkArray, stream ) ) != HB_Err_Ok )
-    goto Fail2;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail1;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = Load_BaseArray( &mbp->BaseArray, mbp->ClassCount,
-				 stream ) ) != HB_Err_Ok )
-    goto Fail1;
-
-  return HB_Err_Ok;
-
-Fail1:
-  Free_MarkArray( &mbp->MarkArray );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &mbp->BaseCoverage );
-
-Fail3:
-  _HB_OPEN_Free_Coverage( &mbp->MarkCoverage );
-  return error;
-}
-
-
-static void  Free_MarkBasePos( HB_GPOS_SubTable* st )
-{
-  HB_MarkBasePos* mbp = &st->markbase;
-
-  Free_BaseArray( &mbp->BaseArray, mbp->ClassCount );
-  Free_MarkArray( &mbp->MarkArray );
-  _HB_OPEN_Free_Coverage( &mbp->BaseCoverage );
-  _HB_OPEN_Free_Coverage( &mbp->MarkCoverage );
-}
-
-
-static HB_Error  Lookup_MarkBasePos( GPOS_Instance*    gpi,
-				     HB_GPOS_SubTable* st,
-				     HB_Buffer        buffer,
-				     HB_UShort         flags,
-				     HB_UShort         context_length,
-				     int               nesting_level )
-{
-  HB_UShort        i, j, mark_index, base_index, property, class;
-  HB_Fixed           x_mark_value, y_mark_value, x_base_value, y_base_value;
-  HB_Error         error;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-  HB_MarkBasePos* mbp = &st->markbase;
-
-  HB_MarkArray*   ma;
-  HB_BaseArray*   ba;
-  HB_BaseRecord*  br;
-  HB_Anchor*      mark_anchor;
-  HB_Anchor*      base_anchor;
-
-  HB_Position     o;
-
-  HB_UNUSED(nesting_level);
-
-  if ( context_length != 0xFFFF && context_length < 1 )
-    return HB_Err_Not_Covered;
-
-  if ( flags & HB_LOOKUP_FLAG_IGNORE_BASE_GLYPHS )
-    return HB_Err_Not_Covered;
-
-  if ( CHECK_Property( gpos->gdef, IN_CURITEM(),
-		       flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &mbp->MarkCoverage, IN_CURGLYPH(),
-			  &mark_index );
-  if ( error )
-    return error;
-
-  /* now we search backwards for a non-mark glyph */
-
-  i = 1;
-  j = buffer->in_pos - 1;
-
-  while ( i <= buffer->in_pos )
-  {
-    error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),
-					&property );
-    if ( error )
-      return error;
-
-    if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )
-      break;
-
-    i++;
-    j--;
-  }
-
-  /* The following assertion is too strong -- at least for mangal.ttf. */
-#if 0
-  if ( property != HB_GDEF_BASE_GLYPH )
-    return HB_Err_Not_Covered;
-#endif
-
-  if ( i > buffer->in_pos )
-    return HB_Err_Not_Covered;
-
-  error = _HB_OPEN_Coverage_Index( &mbp->BaseCoverage, IN_GLYPH( j ),
-			  &base_index );
-  if ( error )
-    return error;
-
-  ma = &mbp->MarkArray;
-
-  if ( mark_index >= ma->MarkCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  class       = ma->MarkRecord[mark_index].Class;
-  mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;
-
-  if ( class >= mbp->ClassCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  ba = &mbp->BaseArray;
-
-  if ( base_index >= ba->BaseCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  br          = &ba->BaseRecord[base_index];
-  base_anchor = &br->BaseAnchor[class];
-
-  error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(),
-		      &x_mark_value, &y_mark_value );
-  if ( error )
-    return error;
-
-  error = Get_Anchor( gpi, base_anchor, IN_GLYPH( j ),
-		      &x_base_value, &y_base_value );
-  if ( error )
-    return error;
-
-  /* anchor points are not cumulative */
-
-  o = POSITION( buffer->in_pos );
-
-  o->x_pos     = x_base_value - x_mark_value;
-  o->y_pos     = y_base_value - y_mark_value;
-  o->x_advance = 0;
-  o->y_advance = 0;
-  o->back      = i;
-
-  (buffer->in_pos)++;
-
-  return HB_Err_Ok;
-}
-
-
-/* LookupType 5 */
-
-/* LigatureAttach */
-
-static HB_Error  Load_LigatureAttach( HB_LigatureAttach*  lat,
-				      HB_UShort            num_classes,
-				      HB_Stream            stream )
-{
-  HB_Error  error;
-
-  HB_UShort             m, n, k, count;
-  HB_UInt              cur_offset, new_offset, base_offset;
-
-  HB_ComponentRecord*  cr;
-  HB_Anchor*           lan;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = lat->ComponentCount = GET_UShort();
-
-  FORGET_Frame();
-
-  lat->ComponentRecord = NULL;
-
-  if ( ALLOC_ARRAY( lat->ComponentRecord, count, HB_ComponentRecord ) )
-    return error;
-
-  cr = lat->ComponentRecord;
-
-  for ( m = 0; m < count; m++ )
-  {
-    cr[m].LigatureAnchor = NULL;
-
-    if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, HB_Anchor ) )
-      goto Fail;
-
-    lan = cr[m].LigatureAnchor;
-
-    for ( n = 0; n < num_classes; n++ )
-    {
-      if ( ACCESS_Frame( 2L ) )
-	goto Fail0;
-
-      new_offset = GET_UShort();
-
-      FORGET_Frame();
-
-      if ( new_offset )
-      {
-	new_offset += base_offset;
-
-	cur_offset = FILE_Pos();
-	if ( FILE_Seek( new_offset ) ||
-	     ( error = Load_Anchor( &lan[n], stream ) ) != HB_Err_Ok )
-	  goto Fail0;
-	(void)FILE_Seek( cur_offset );
-      }
-      else
-	lan[n].PosFormat = 0;
-    }
-
-    continue;
-  Fail0:
-    for ( k = 0; k < n; k++ )
-      Free_Anchor( &lan[k] );
-    goto Fail;
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( k = 0; k < m; k++ )
-  {
-    lan = cr[k].LigatureAnchor;
-
-    for ( n = 0; n < num_classes; n++ )
-      Free_Anchor( &lan[n] );
-
-    FREE( lan );
-  }
-
-  FREE( cr );
-  return error;
-}
-
-
-static void  Free_LigatureAttach( HB_LigatureAttach*  lat,
-				  HB_UShort            num_classes )
-{
-  HB_UShort        m, n, count;
-
-  HB_ComponentRecord*  cr;
-  HB_Anchor*           lan;
-
-
-  if ( lat->ComponentRecord )
-  {
-    count = lat->ComponentCount;
-    cr    = lat->ComponentRecord;
-
-    for ( m = 0; m < count; m++ )
-    {
-      lan = cr[m].LigatureAnchor;
-
-      for ( n = 0; n < num_classes; n++ )
-	Free_Anchor( &lan[n] );
-
-      FREE( lan );
-    }
-
-    FREE( cr );
-  }
-}
-
-
-/* LigatureArray */
-
-static HB_Error  Load_LigatureArray( HB_LigatureArray*  la,
-				     HB_UShort           num_classes,
-				     HB_Stream           stream )
-{
-  HB_Error  error;
-
-  HB_UShort            n, m, count;
-  HB_UInt             cur_offset, new_offset, base_offset;
-
-  HB_LigatureAttach*  lat;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = la->LigatureCount = GET_UShort();
-
-  FORGET_Frame();
-
-  la->LigatureAttach = NULL;
-
-  if ( ALLOC_ARRAY( la->LigatureAttach, count, HB_LigatureAttach ) )
-    return error;
-
-  lat = la->LigatureAttach;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_LigatureAttach( &lat[n], num_classes,
-					stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_LigatureAttach( &lat[m], num_classes );
-
-  FREE( lat );
-  return error;
-}
-
-
-static void  Free_LigatureArray( HB_LigatureArray*  la,
-				 HB_UShort           num_classes )
-{
-  HB_UShort            n, count;
-
-  HB_LigatureAttach*  lat;
-
-
-  if ( la->LigatureAttach )
-  {
-    count = la->LigatureCount;
-    lat   = la->LigatureAttach;
-
-    for ( n = 0; n < count; n++ )
-      Free_LigatureAttach( &lat[n], num_classes );
-
-    FREE( lat );
-  }
-}
-
-
-/* MarkLigPosFormat1 */
-
-static HB_Error  Load_MarkLigPos( HB_GPOS_SubTable* st,
-				  HB_Stream        stream )
-{
-  HB_Error  error;
-  HB_MarkLigPos*  mlp = &st->marklig;
-
-  HB_UInt  cur_offset, new_offset, base_offset;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  mlp->PosFormat = GET_UShort();
-  new_offset     = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &mlp->MarkCoverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &mlp->LigatureCoverage,
-				stream ) ) != HB_Err_Ok )
-    goto Fail3;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 4L ) )
-    goto Fail2;
-
-  mlp->ClassCount = GET_UShort();
-  new_offset      = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = Load_MarkArray( &mlp->MarkArray, stream ) ) != HB_Err_Ok )
-    goto Fail2;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail1;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = Load_LigatureArray( &mlp->LigatureArray, mlp->ClassCount,
-				     stream ) ) != HB_Err_Ok )
-    goto Fail1;
-
-  return HB_Err_Ok;
-
-Fail1:
-  Free_MarkArray( &mlp->MarkArray );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage );
-
-Fail3:
-  _HB_OPEN_Free_Coverage( &mlp->MarkCoverage );
-  return error;
-}
-
-
-static void  Free_MarkLigPos( HB_GPOS_SubTable* st)
-{
-  HB_MarkLigPos*  mlp = &st->marklig;
-
-  Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount );
-  Free_MarkArray( &mlp->MarkArray );
-  _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage );
-  _HB_OPEN_Free_Coverage( &mlp->MarkCoverage );
-}
-
-
-static HB_Error  Lookup_MarkLigPos( GPOS_Instance*    gpi,
-				    HB_GPOS_SubTable* st,
-				    HB_Buffer        buffer,
-				    HB_UShort         flags,
-				    HB_UShort         context_length,
-				    int               nesting_level )
-{
-  HB_UShort        i, j, mark_index, lig_index, property, class;
-  HB_UShort        mark_glyph;
-  HB_Fixed           x_mark_value, y_mark_value, x_lig_value, y_lig_value;
-  HB_Error         error;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-  HB_MarkLigPos*  mlp = &st->marklig;
-
-  HB_MarkArray*        ma;
-  HB_LigatureArray*    la;
-  HB_LigatureAttach*   lat;
-  HB_ComponentRecord*  cr;
-  HB_UShort             comp_index;
-  HB_Anchor*           mark_anchor;
-  HB_Anchor*           lig_anchor;
-
-  HB_Position    o;
-
-  HB_UNUSED(nesting_level);
-
-  if ( context_length != 0xFFFF && context_length < 1 )
-    return HB_Err_Not_Covered;
-
-  if ( flags & HB_LOOKUP_FLAG_IGNORE_LIGATURES )
-    return HB_Err_Not_Covered;
-
-  mark_glyph = IN_CURGLYPH();
-
-  if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &mlp->MarkCoverage, mark_glyph, &mark_index );
-  if ( error )
-    return error;
-
-  /* now we search backwards for a non-mark glyph */
-
-  i = 1;
-  j = buffer->in_pos - 1;
-
-  while ( i <= buffer->in_pos )
-  {
-    error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),
-					&property );
-    if ( error )
-      return error;
-
-    if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )
-      break;
-
-    i++;
-    j--;
-  }
-
-  /* Similar to Lookup_MarkBasePos(), I suspect that this assertion is
-     too strong, thus it is commented out.                             */
-#if 0
-  if ( property != HB_GDEF_LIGATURE )
-    return HB_Err_Not_Covered;
-#endif
-
-  if ( i > buffer->in_pos )
-    return HB_Err_Not_Covered;
-
-  error = _HB_OPEN_Coverage_Index( &mlp->LigatureCoverage, IN_GLYPH( j ),
-			  &lig_index );
-  if ( error )
-    return error;
-
-  ma = &mlp->MarkArray;
-
-  if ( mark_index >= ma->MarkCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  class       = ma->MarkRecord[mark_index].Class;
-  mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;
-
-  if ( class >= mlp->ClassCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  la = &mlp->LigatureArray;
-
-  if ( lig_index >= la->LigatureCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  lat = &la->LigatureAttach[lig_index];
-
-  /* We must now check whether the ligature ID of the current mark glyph
-     is identical to the ligature ID of the found ligature.  If yes, we
-     can directly use the component index.  If not, we attach the mark
-     glyph to the last component of the ligature.                        */
-
-  if ( IN_LIGID( j ) == IN_LIGID( buffer->in_pos) )
-  {
-    comp_index = IN_COMPONENT( buffer->in_pos );
-    if ( comp_index >= lat->ComponentCount )
-      return HB_Err_Not_Covered;
-  }
-  else
-    comp_index = lat->ComponentCount - 1;
-
-  cr         = &lat->ComponentRecord[comp_index];
-  lig_anchor = &cr->LigatureAnchor[class];
-
-  error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(),
-		      &x_mark_value, &y_mark_value );
-  if ( error )
-    return error;
-  error = Get_Anchor( gpi, lig_anchor, IN_GLYPH( j ),
-		      &x_lig_value, &y_lig_value );
-  if ( error )
-    return error;
-
-  /* anchor points are not cumulative */
-
-  o = POSITION( buffer->in_pos );
-
-  o->x_pos     = x_lig_value - x_mark_value;
-  o->y_pos     = y_lig_value - y_mark_value;
-  o->x_advance = 0;
-  o->y_advance = 0;
-  o->back      = i;
-
-  (buffer->in_pos)++;
-
-  return HB_Err_Ok;
-}
-
-
-/* LookupType 6 */
-
-/* Mark2Array */
-
-static HB_Error  Load_Mark2Array( HB_Mark2Array*  m2a,
-				  HB_UShort        num_classes,
-				  HB_Stream        stream )
-{
-  HB_Error  error;
-
-  HB_UShort        m, n, count;
-  HB_UInt          cur_offset, new_offset, base_offset;
-
-  HB_Mark2Record  *m2r;
-  HB_Anchor       *m2an, *m2ans;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = m2a->Mark2Count = GET_UShort();
-
-  FORGET_Frame();
-
-  m2a->Mark2Record = NULL;
-
-  if ( ALLOC_ARRAY( m2a->Mark2Record, count, HB_Mark2Record ) )
-    return error;
-
-  m2r = m2a->Mark2Record;
-
-  m2ans = NULL;
-
-  if ( ALLOC_ARRAY( m2ans, count * num_classes, HB_Anchor ) )
-    goto Fail;
-
-  for ( m = 0; m < count; m++ )
-  {
-    m2an = m2r[m].Mark2Anchor = m2ans + m * num_classes;
-
-    for ( n = 0; n < num_classes; n++ )
-    {
-      if ( ACCESS_Frame( 2L ) )
-	goto Fail;
-
-      new_offset = GET_UShort() + base_offset;
-
-      FORGET_Frame();
-
-      if (new_offset == base_offset) {
-        /* Anchor table not provided.  Skip loading.
-	 * Some versions of FreeSans hit this. */
-        m2an[n].PosFormat = 0;
-	continue;
-      }
-
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = Load_Anchor( &m2an[n], stream ) ) != HB_Err_Ok )
-	goto Fail;
-      (void)FILE_Seek( cur_offset );
-    }
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  FREE( m2ans );
-  FREE( m2r );
-  return error;
-}
-
-
-static void  Free_Mark2Array( HB_Mark2Array*  m2a,
-			      HB_UShort        num_classes )
-{
-  HB_Mark2Record  *m2r;
-  HB_Anchor       *m2ans;
-
-  HB_UNUSED(num_classes);
-
-  if ( m2a->Mark2Record )
-  {
-    m2r   = m2a->Mark2Record;
-
-    if ( m2a->Mark2Count )
-    {
-      m2ans = m2r[0].Mark2Anchor;
-      FREE( m2ans );
-    }
-
-    FREE( m2r );
-  }
-}
-
-
-/* MarkMarkPosFormat1 */
-
-static HB_Error  Load_MarkMarkPos( HB_GPOS_SubTable* st,
-				   HB_Stream         stream )
-{
-  HB_Error  error;
-  HB_MarkMarkPos* mmp = &st->markmark;
-
-  HB_UInt  cur_offset, new_offset, base_offset;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  mmp->PosFormat = GET_UShort();
-  new_offset     = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &mmp->Mark1Coverage,
-				stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &mmp->Mark2Coverage,
-				stream ) ) != HB_Err_Ok )
-    goto Fail3;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 4L ) )
-    goto Fail2;
-
-  mmp->ClassCount = GET_UShort();
-  new_offset      = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = Load_MarkArray( &mmp->Mark1Array, stream ) ) != HB_Err_Ok )
-    goto Fail2;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail1;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = Load_Mark2Array( &mmp->Mark2Array, mmp->ClassCount,
-				  stream ) ) != HB_Err_Ok )
-    goto Fail1;
-
-  return HB_Err_Ok;
-
-Fail1:
-  Free_MarkArray( &mmp->Mark1Array );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage );
-
-Fail3:
-  _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage );
-  return error;
-}
-
-
-static void  Free_MarkMarkPos( HB_GPOS_SubTable* st)
-{
-  HB_MarkMarkPos* mmp = &st->markmark;
-
-  Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount );
-  Free_MarkArray( &mmp->Mark1Array );
-  _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage );
-  _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage );
-}
-
-
-static HB_Error  Lookup_MarkMarkPos( GPOS_Instance*    gpi,
-				     HB_GPOS_SubTable* st,
-				     HB_Buffer        buffer,
-				     HB_UShort         flags,
-				     HB_UShort         context_length,
-				     int               nesting_level )
-{
-  HB_UShort        i, j, mark1_index, mark2_index, property, class;
-  HB_Fixed           x_mark1_value, y_mark1_value,
-		   x_mark2_value, y_mark2_value;
-  HB_Error         error;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-  HB_MarkMarkPos* mmp = &st->markmark;
-
-  HB_MarkArray*    ma1;
-  HB_Mark2Array*   ma2;
-  HB_Mark2Record*  m2r;
-  HB_Anchor*       mark1_anchor;
-  HB_Anchor*       mark2_anchor;
-
-  HB_Position    o;
-
-  HB_UNUSED(nesting_level);
-
-  if ( context_length != 0xFFFF && context_length < 1 )
-    return HB_Err_Not_Covered;
-
-  if ( flags & HB_LOOKUP_FLAG_IGNORE_MARKS )
-    return HB_Err_Not_Covered;
-
-  if ( CHECK_Property( gpos->gdef, IN_CURITEM(),
-		       flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &mmp->Mark1Coverage, IN_CURGLYPH(),
-			  &mark1_index );
-  if ( error )
-    return error;
-
-  /* now we search backwards for a suitable mark glyph until a non-mark
-     glyph                                                */
-
-  if ( buffer->in_pos == 0 )
-    return HB_Err_Not_Covered;
-
-  i = 1;
-  j = buffer->in_pos - 1;
-  while ( i <= buffer->in_pos )
-  {
-    error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),
-					&property );
-    if ( error )
-      return error;
-
-    if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )
-      return HB_Err_Not_Covered;
-
-    if ( flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
-    {
-      if ( property == (flags & 0xFF00) )
-        break;
-    }
-    else
-      break;
-
-    i++;
-    j--;
-  }
-
-  error = _HB_OPEN_Coverage_Index( &mmp->Mark2Coverage, IN_GLYPH( j ),
-			  &mark2_index );
-  if ( error )
-    return error;
-
-  ma1 = &mmp->Mark1Array;
-
-  if ( mark1_index >= ma1->MarkCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  class        = ma1->MarkRecord[mark1_index].Class;
-  mark1_anchor = &ma1->MarkRecord[mark1_index].MarkAnchor;
-
-  if ( class >= mmp->ClassCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  ma2 = &mmp->Mark2Array;
-
-  if ( mark2_index >= ma2->Mark2Count )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  m2r          = &ma2->Mark2Record[mark2_index];
-  mark2_anchor = &m2r->Mark2Anchor[class];
-
-  error = Get_Anchor( gpi, mark1_anchor, IN_CURGLYPH(),
-		      &x_mark1_value, &y_mark1_value );
-  if ( error )
-    return error;
-  error = Get_Anchor( gpi, mark2_anchor, IN_GLYPH( j ),
-		      &x_mark2_value, &y_mark2_value );
-  if ( error )
-    return error;
-
-  /* anchor points are not cumulative */
-
-  o = POSITION( buffer->in_pos );
-
-  o->x_pos     = x_mark2_value - x_mark1_value;
-  o->y_pos     = y_mark2_value - y_mark1_value;
-  o->x_advance = 0;
-  o->y_advance = 0;
-  o->back      = 1;
-
-  (buffer->in_pos)++;
-
-  return HB_Err_Ok;
-}
-
-
-/* Do the actual positioning for a context positioning (either format
-   7 or 8).  This is only called after we've determined that the stream
-   matches the subrule.                                                 */
-
-static HB_Error  Do_ContextPos( GPOS_Instance*        gpi,
-				HB_UShort             GlyphCount,
-				HB_UShort             PosCount,
-				HB_PosLookupRecord*  pos,
-				HB_Buffer            buffer,
-				int                   nesting_level )
-{
-  HB_Error  error;
-  HB_UInt   i, old_pos;
-
-
-  i = 0;
-
-  while ( i < GlyphCount )
-  {
-    if ( PosCount && i == pos->SequenceIndex )
-    {
-      old_pos = buffer->in_pos;
-
-      /* Do a positioning */
-
-      error = GPOS_Do_Glyph_Lookup( gpi, pos->LookupListIndex, buffer,
-				    GlyphCount, nesting_level );
-
-      if ( error )
-	return error;
-
-      pos++;
-      PosCount--;
-      i += buffer->in_pos - old_pos;
-    }
-    else
-    {
-      i++;
-      (buffer->in_pos)++;
-    }
-  }
-
-  return HB_Err_Ok;
-}
-
-
-/* LookupType 7 */
-
-/* PosRule */
-
-static HB_Error  Load_PosRule( HB_PosRule*  pr,
-			       HB_Stream     stream )
-{
-  HB_Error  error;
-
-  HB_UShort             n, count;
-  HB_UShort*            i;
-
-  HB_PosLookupRecord*  plr;
-
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  pr->GlyphCount = GET_UShort();
-  pr->PosCount   = GET_UShort();
-
-  FORGET_Frame();
-
-  pr->Input = NULL;
-
-  count = pr->GlyphCount - 1;         /* only GlyphCount - 1 elements */
-
-  if ( ALLOC_ARRAY( pr->Input, count, HB_UShort ) )
-    return error;
-
-  i = pr->Input;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail2;
-
-  for ( n = 0; n < count; n++ )
-    i[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  pr->PosLookupRecord = NULL;
-
-  count = pr->PosCount;
-
-  if ( ALLOC_ARRAY( pr->PosLookupRecord, count, HB_PosLookupRecord ) )
-    goto Fail2;
-
-  plr = pr->PosLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    plr[n].SequenceIndex   = GET_UShort();
-    plr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( plr );
-
-Fail2:
-  FREE( i );
-  return error;
-}
-
-
-static void  Free_PosRule( HB_PosRule*  pr )
-{
-  FREE( pr->PosLookupRecord );
-  FREE( pr->Input );
-}
-
-
-/* PosRuleSet */
-
-static HB_Error  Load_PosRuleSet( HB_PosRuleSet*  prs,
-				  HB_Stream        stream )
-{
-  HB_Error  error;
-
-  HB_UShort     n, m, count;
-  HB_UInt      cur_offset, new_offset, base_offset;
-
-  HB_PosRule*  pr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = prs->PosRuleCount = GET_UShort();
-
-  FORGET_Frame();
-
-  prs->PosRule = NULL;
-
-  if ( ALLOC_ARRAY( prs->PosRule, count, HB_PosRule ) )
-    return error;
-
-  pr = prs->PosRule;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_PosRule( &pr[n], stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_PosRule( &pr[m] );
-
-  FREE( pr );
-  return error;
-}
-
-
-static void  Free_PosRuleSet( HB_PosRuleSet*  prs )
-{
-  HB_UShort     n, count;
-
-  HB_PosRule*  pr;
-
-
-  if ( prs->PosRule )
-  {
-    count = prs->PosRuleCount;
-    pr    = prs->PosRule;
-
-    for ( n = 0; n < count; n++ )
-      Free_PosRule( &pr[n] );
-
-    FREE( pr );
-  }
-}
-
-
-/* ContextPosFormat1 */
-
-static HB_Error  Load_ContextPos1( HB_ContextPosFormat1*  cpf1,
-				   HB_Stream               stream )
-{
-  HB_Error  error;
-
-  HB_UShort        n, m, count;
-  HB_UInt         cur_offset, new_offset, base_offset;
-
-  HB_PosRuleSet*  prs;
-
-
-  base_offset = FILE_Pos() - 2L;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &cpf1->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = cpf1->PosRuleSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cpf1->PosRuleSet = NULL;
-
-  if ( ALLOC_ARRAY( cpf1->PosRuleSet, count, HB_PosRuleSet ) )
-    goto Fail2;
-
-  prs = cpf1->PosRuleSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_PosRuleSet( &prs[n], stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_PosRuleSet( &prs[m] );
-
-  FREE( prs );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &cpf1->Coverage );
-  return error;
-}
-
-
-static void  Free_ContextPos1( HB_ContextPosFormat1*  cpf1 )
-{
-  HB_UShort        n, count;
-
-  HB_PosRuleSet*  prs;
-
-
-  if ( cpf1->PosRuleSet )
-  {
-    count = cpf1->PosRuleSetCount;
-    prs   = cpf1->PosRuleSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_PosRuleSet( &prs[n] );
-
-    FREE( prs );
-  }
-
-  _HB_OPEN_Free_Coverage( &cpf1->Coverage );
-}
-
-
-/* PosClassRule */
-
-static HB_Error  Load_PosClassRule( HB_ContextPosFormat2*  cpf2,
-				    HB_PosClassRule*       pcr,
-				    HB_Stream               stream )
-{
-  HB_Error  error;
-
-  HB_UShort             n, count;
-
-  HB_UShort*            c;
-  HB_PosLookupRecord*  plr;
-
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  pcr->GlyphCount = GET_UShort();
-  pcr->PosCount   = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( pcr->GlyphCount > cpf2->MaxContextLength )
-    cpf2->MaxContextLength = pcr->GlyphCount;
-
-  pcr->Class = NULL;
-
-  count = pcr->GlyphCount - 1;        /* only GlyphCount - 1 elements */
-
-  if ( ALLOC_ARRAY( pcr->Class, count, HB_UShort ) )
-    return error;
-
-  c = pcr->Class;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail2;
-
-  for ( n = 0; n < count; n++ )
-    c[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  pcr->PosLookupRecord = NULL;
-
-  count = pcr->PosCount;
-
-  if ( ALLOC_ARRAY( pcr->PosLookupRecord, count, HB_PosLookupRecord ) )
-    goto Fail2;
-
-  plr = pcr->PosLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    plr[n].SequenceIndex   = GET_UShort();
-    plr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( plr );
-
-Fail2:
-  FREE( c );
-  return error;
-}
-
-
-static void  Free_PosClassRule( HB_PosClassRule*  pcr )
-{
-  FREE( pcr->PosLookupRecord );
-  FREE( pcr->Class );
-}
-
-
-/* PosClassSet */
-
-static HB_Error  Load_PosClassSet( HB_ContextPosFormat2*  cpf2,
-				   HB_PosClassSet*        pcs,
-				   HB_Stream               stream )
-{
-  HB_Error  error;
-
-  HB_UShort          n, m, count;
-  HB_UInt           cur_offset, new_offset, base_offset;
-
-  HB_PosClassRule*  pcr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = pcs->PosClassRuleCount = GET_UShort();
-
-  FORGET_Frame();
-
-  pcs->PosClassRule = NULL;
-
-  if ( ALLOC_ARRAY( pcs->PosClassRule, count, HB_PosClassRule ) )
-    return error;
-
-  pcr = pcs->PosClassRule;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_PosClassRule( cpf2, &pcr[n],
-				      stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_PosClassRule( &pcr[m] );
-
-  FREE( pcr );
-  return error;
-}
-
-
-static void  Free_PosClassSet( HB_PosClassSet*  pcs )
-{
-  HB_UShort          n, count;
-
-  HB_PosClassRule*  pcr;
-
-
-  if ( pcs->PosClassRule )
-  {
-    count = pcs->PosClassRuleCount;
-    pcr   = pcs->PosClassRule;
-
-    for ( n = 0; n < count; n++ )
-      Free_PosClassRule( &pcr[n] );
-
-    FREE( pcr );
-  }
-}
-
-
-/* ContextPosFormat2 */
-
-static HB_Error  Load_ContextPos2( HB_ContextPosFormat2*  cpf2,
-				   HB_Stream               stream )
-{
-  HB_Error  error;
-
-  HB_UShort         n, m, count;
-  HB_UInt          cur_offset, new_offset, base_offset;
-
-  HB_PosClassSet*  pcs;
-
-
-  base_offset = FILE_Pos() - 2;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &cpf2->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 4L ) )
-    goto Fail3;
-
-  new_offset = GET_UShort() + base_offset;
-
-  /* `PosClassSetCount' is the upper limit for class values, thus we
-     read it now to make an additional safety check.                 */
-
-  count = cpf2->PosClassSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_ClassDefinition( &cpf2->ClassDef, count,
-				       stream ) ) != HB_Err_Ok )
-    goto Fail3;
-  (void)FILE_Seek( cur_offset );
-
-  cpf2->PosClassSet      = NULL;
-  cpf2->MaxContextLength = 0;
-
-  if ( ALLOC_ARRAY( cpf2->PosClassSet, count, HB_PosClassSet ) )
-    goto Fail2;
-
-  pcs = cpf2->PosClassSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    if ( new_offset != base_offset )      /* not a NULL offset */
-    {
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = Load_PosClassSet( cpf2, &pcs[n],
-				       stream ) ) != HB_Err_Ok )
-	goto Fail1;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-    {
-      /* we create a PosClassSet table with no entries */
-
-      cpf2->PosClassSet[n].PosClassRuleCount = 0;
-      cpf2->PosClassSet[n].PosClassRule      = NULL;
-    }
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; n++ )
-    Free_PosClassSet( &pcs[m] );
-
-  FREE( pcs );
-
-Fail2:
-  _HB_OPEN_Free_ClassDefinition( &cpf2->ClassDef );
-
-Fail3:
-  _HB_OPEN_Free_Coverage( &cpf2->Coverage );
-  return error;
-}
-
-
-static void  Free_ContextPos2( HB_ContextPosFormat2*  cpf2 )
-{
-  HB_UShort         n, count;
-
-  HB_PosClassSet*  pcs;
-
-
-  if ( cpf2->PosClassSet )
-  {
-    count = cpf2->PosClassSetCount;
-    pcs   = cpf2->PosClassSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_PosClassSet( &pcs[n] );
-
-    FREE( pcs );
-  }
-
-  _HB_OPEN_Free_ClassDefinition( &cpf2->ClassDef );
-  _HB_OPEN_Free_Coverage( &cpf2->Coverage );
-}
-
-
-/* ContextPosFormat3 */
-
-static HB_Error  Load_ContextPos3( HB_ContextPosFormat3*  cpf3,
-				   HB_Stream               stream )
-{
-  HB_Error  error;
-
-  HB_UShort             n, count;
-  HB_UInt              cur_offset, new_offset, base_offset;
-
-  HB_Coverage*         c;
-  HB_PosLookupRecord*  plr;
-
-
-  base_offset = FILE_Pos() - 2L;
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  cpf3->GlyphCount = GET_UShort();
-  cpf3->PosCount   = GET_UShort();
-
-  FORGET_Frame();
-
-  cpf3->Coverage = NULL;
-
-  count = cpf3->GlyphCount;
-
-  if ( ALLOC_ARRAY( cpf3->Coverage, count, HB_Coverage ) )
-    return error;
-
-  c = cpf3->Coverage;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail2;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != HB_Err_Ok )
-      goto Fail2;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  cpf3->PosLookupRecord = NULL;
-
-  count = cpf3->PosCount;
-
-  if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, HB_PosLookupRecord ) )
-    goto Fail2;
-
-  plr = cpf3->PosLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    plr[n].SequenceIndex   = GET_UShort();
-    plr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( plr );
-
-Fail2:
-  for ( n = 0; n < count; n++ )
-    _HB_OPEN_Free_Coverage( &c[n] );
-
-  FREE( c );
-  return error;
-}
-
-
-static void  Free_ContextPos3( HB_ContextPosFormat3*  cpf3 )
-{
-  HB_UShort      n, count;
-
-  HB_Coverage*  c;
-
-
-  FREE( cpf3->PosLookupRecord );
-
-  if ( cpf3->Coverage )
-  {
-    count = cpf3->GlyphCount;
-    c     = cpf3->Coverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-}
-
-
-/* ContextPos */
-
-static HB_Error  Load_ContextPos( HB_GPOS_SubTable* st,
-				  HB_Stream        stream )
-{
-  HB_Error  error;
-  HB_ContextPos*   cp = &st->context;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  cp->PosFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  switch ( cp->PosFormat )
-  {
-  case 1:
-    return Load_ContextPos1( &cp->cpf.cpf1, stream );
-
-  case 2:
-    return Load_ContextPos2( &cp->cpf.cpf2, stream );
-
-  case 3:
-    return Load_ContextPos3( &cp->cpf.cpf3, stream );
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-static void  Free_ContextPos( HB_GPOS_SubTable* st )
-{
-  HB_ContextPos*   cp = &st->context;
-
-  switch ( cp->PosFormat )
-  {
-  case 1:  Free_ContextPos1( &cp->cpf.cpf1 ); break;
-  case 2:  Free_ContextPos2( &cp->cpf.cpf2 ); break;
-  case 3:  Free_ContextPos3( &cp->cpf.cpf3 ); break;
-  default:					      break;
-  }
-}
-
-
-static HB_Error  Lookup_ContextPos1( GPOS_Instance*          gpi,
-				     HB_ContextPosFormat1*  cpf1,
-				     HB_Buffer              buffer,
-				     HB_UShort               flags,
-				     HB_UShort               context_length,
-				     int                     nesting_level )
-{
-  HB_UShort        index, property;
-  HB_UShort        i, j, k, numpr;
-  HB_Error         error;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-
-  HB_PosRule*     pr;
-  HB_GDEFHeader*  gdef;
-
-
-  gdef = gpos->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &cpf1->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  pr    = cpf1->PosRuleSet[index].PosRule;
-  numpr = cpf1->PosRuleSet[index].PosRuleCount;
-
-  for ( k = 0; k < numpr; k++ )
-  {
-    if ( context_length != 0xFFFF && context_length < pr[k].GlyphCount )
-      goto next_posrule;
-
-    if ( buffer->in_pos + pr[k].GlyphCount > buffer->in_length )
-      goto next_posrule;                       /* context is too long */
-
-    for ( i = 1, j = buffer->in_pos + 1; i < pr[k].GlyphCount; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + pr[k].GlyphCount - i == (HB_Int)buffer->in_length )
-	  goto next_posrule;
-	j++;
-      }
-
-      if ( IN_GLYPH( j ) != pr[k].Input[i - 1] )
-	goto next_posrule;
-    }
-
-    return Do_ContextPos( gpi, pr[k].GlyphCount,
-			  pr[k].PosCount, pr[k].PosLookupRecord,
-			  buffer,
-			  nesting_level );
-
-    next_posrule:
-      ;
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-static HB_Error  Lookup_ContextPos2( GPOS_Instance*          gpi,
-				     HB_ContextPosFormat2*  cpf2,
-				     HB_Buffer              buffer,
-				     HB_UShort               flags,
-				     HB_UShort               context_length,
-				     int                     nesting_level )
-{
-  HB_UShort          index, property;
-  HB_Error           error;
-  HB_UShort          i, j, k, known_classes;
-
-  HB_UShort*         classes;
-  HB_UShort*         cl;
-  HB_GPOSHeader*    gpos = gpi->gpos;
-
-  HB_PosClassSet*   pcs;
-  HB_PosClassRule*  pr;
-  HB_GDEFHeader*    gdef;
-
-
-  gdef = gpos->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  /* Note: The coverage table in format 2 doesn't give an index into
-	   anything.  It just lets us know whether or not we need to
-	   do any lookup at all.                                     */
-
-  error = _HB_OPEN_Coverage_Index( &cpf2->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  if (cpf2->MaxContextLength < 1)
-    return HB_Err_Not_Covered;
-
-  if ( ALLOC_ARRAY( classes, cpf2->MaxContextLength, HB_UShort ) )
-    return error;
-
-  error = _HB_OPEN_Get_Class( &cpf2->ClassDef, IN_CURGLYPH(),
-		     &classes[0], NULL );
-  if ( error && error != HB_Err_Not_Covered )
-    goto End;
-  known_classes = 0;
-
-  pcs = &cpf2->PosClassSet[classes[0]];
-  if ( !pcs )
-  {
-    error = ERR(HB_Err_Invalid_SubTable);
-    goto End;
-  }
-
-  for ( k = 0; k < pcs->PosClassRuleCount; k++ )
-  {
-    pr = &pcs->PosClassRule[k];
-
-    if ( context_length != 0xFFFF && context_length < pr->GlyphCount )
-      goto next_posclassrule;
-
-    if ( buffer->in_pos + pr->GlyphCount > buffer->in_length )
-      goto next_posclassrule;                /* context is too long */
-
-    cl   = pr->Class;
-
-    /* Start at 1 because [0] is implied */
-
-    for ( i = 1, j = buffer->in_pos + 1; i < pr->GlyphCount; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End;
-
-	if ( j + pr->GlyphCount - i == (HB_Int)buffer->in_length )
-	  goto next_posclassrule;
-	j++;
-      }
-
-      if ( i > known_classes )
-      {
-	/* Keeps us from having to do this for each rule */
-
-	error = _HB_OPEN_Get_Class( &cpf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL );
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End;
-	known_classes = i;
-      }
-
-      if ( cl[i - 1] != classes[i] )
-	goto next_posclassrule;
-    }
-
-    error = Do_ContextPos( gpi, pr->GlyphCount,
-			   pr->PosCount, pr->PosLookupRecord,
-			   buffer,
-			   nesting_level );
-    goto End;
-
-  next_posclassrule:
-    ;
-  }
-
-  error = HB_Err_Not_Covered;
-
-End:
-  FREE( classes );
-  return error;
-}
-
-
-static HB_Error  Lookup_ContextPos3( GPOS_Instance*          gpi,
-				     HB_ContextPosFormat3*  cpf3,
-				     HB_Buffer              buffer,
-				     HB_UShort               flags,
-				     HB_UShort               context_length,
-				     int                     nesting_level )
-{
-  HB_Error         error;
-  HB_UShort        index, i, j, property;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-
-  HB_Coverage*    c;
-  HB_GDEFHeader*  gdef;
-
-
-  gdef = gpos->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  if ( context_length != 0xFFFF && context_length < cpf3->GlyphCount )
-    return HB_Err_Not_Covered;
-
-  if ( buffer->in_pos + cpf3->GlyphCount > buffer->in_length )
-    return HB_Err_Not_Covered;         /* context is too long */
-
-  c    = cpf3->Coverage;
-
-  for ( i = 1, j = 1; i < cpf3->GlyphCount; i++, j++ )
-  {
-    while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-    {
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-
-      if ( j + cpf3->GlyphCount - i == (HB_Int)buffer->in_length )
-	return HB_Err_Not_Covered;
-      j++;
-    }
-
-    error = _HB_OPEN_Coverage_Index( &c[i], IN_GLYPH( j ), &index );
-    if ( error )
-      return error;
-  }
-
-  return Do_ContextPos( gpi, cpf3->GlyphCount,
-			cpf3->PosCount, cpf3->PosLookupRecord,
-			buffer,
-			nesting_level );
-}
-
-
-static HB_Error  Lookup_ContextPos( GPOS_Instance*    gpi,
-				    HB_GPOS_SubTable* st,
-				    HB_Buffer        buffer,
-				    HB_UShort         flags,
-				    HB_UShort         context_length,
-				    int               nesting_level )
-{
-  HB_ContextPos*   cp = &st->context;
-
-  switch ( cp->PosFormat )
-  {
-  case 1:
-    return Lookup_ContextPos1( gpi, &cp->cpf.cpf1, buffer,
-			       flags, context_length, nesting_level );
-
-  case 2:
-    return Lookup_ContextPos2( gpi, &cp->cpf.cpf2, buffer,
-			       flags, context_length, nesting_level );
-
-  case 3:
-    return Lookup_ContextPos3( gpi, &cp->cpf.cpf3, buffer,
-			       flags, context_length, nesting_level );
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-/* LookupType 8 */
-
-/* ChainPosRule */
-
-static HB_Error  Load_ChainPosRule( HB_ChainPosRule*  cpr,
-				    HB_Stream          stream )
-{
-  HB_Error  error;
-
-  HB_UShort             n, count;
-  HB_UShort*            b;
-  HB_UShort*            i;
-  HB_UShort*            l;
-
-  HB_PosLookupRecord*  plr;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  cpr->BacktrackGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cpr->Backtrack = NULL;
-
-  count = cpr->BacktrackGlyphCount;
-
-  if ( ALLOC_ARRAY( cpr->Backtrack, count, HB_UShort ) )
-    return error;
-
-  b = cpr->Backtrack;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail4;
-
-  for ( n = 0; n < count; n++ )
-    b[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail4;
-
-  cpr->InputGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cpr->Input = NULL;
-
-  count = cpr->InputGlyphCount - 1;  /* only InputGlyphCount - 1 elements */
-
-  if ( ALLOC_ARRAY( cpr->Input, count, HB_UShort ) )
-    goto Fail4;
-
-  i = cpr->Input;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail3;
-
-  for ( n = 0; n < count; n++ )
-    i[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  cpr->LookaheadGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cpr->Lookahead = NULL;
-
-  count = cpr->LookaheadGlyphCount;
-
-  if ( ALLOC_ARRAY( cpr->Lookahead, count, HB_UShort ) )
-    goto Fail3;
-
-  l = cpr->Lookahead;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail2;
-
-  for ( n = 0; n < count; n++ )
-    l[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  cpr->PosCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cpr->PosLookupRecord = NULL;
-
-  count = cpr->PosCount;
-
-  if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, HB_PosLookupRecord ) )
-    goto Fail2;
-
-  plr = cpr->PosLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    plr[n].SequenceIndex   = GET_UShort();
-    plr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( plr );
-
-Fail2:
-  FREE( l );
-
-Fail3:
-  FREE( i );
-
-Fail4:
-  FREE( b );
-  return error;
-}
-
-
-static void  Free_ChainPosRule( HB_ChainPosRule*  cpr )
-{
-  FREE( cpr->PosLookupRecord );
-  FREE( cpr->Lookahead );
-  FREE( cpr->Input );
-  FREE( cpr->Backtrack );
-}
-
-
-/* ChainPosRuleSet */
-
-static HB_Error  Load_ChainPosRuleSet( HB_ChainPosRuleSet*  cprs,
-				       HB_Stream             stream )
-{
-  HB_Error  error;
-
-  HB_UShort          n, m, count;
-  HB_UInt           cur_offset, new_offset, base_offset;
-
-  HB_ChainPosRule*  cpr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = cprs->ChainPosRuleCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cprs->ChainPosRule = NULL;
-
-  if ( ALLOC_ARRAY( cprs->ChainPosRule, count, HB_ChainPosRule ) )
-    return error;
-
-  cpr = cprs->ChainPosRule;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_ChainPosRule( &cpr[n], stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_ChainPosRule( &cpr[m] );
-
-  FREE( cpr );
-  return error;
-}
-
-
-static void  Free_ChainPosRuleSet( HB_ChainPosRuleSet*  cprs )
-{
-  HB_UShort          n, count;
-
-  HB_ChainPosRule*  cpr;
-
-
-  if ( cprs->ChainPosRule )
-  {
-    count = cprs->ChainPosRuleCount;
-    cpr   = cprs->ChainPosRule;
-
-    for ( n = 0; n < count; n++ )
-      Free_ChainPosRule( &cpr[n] );
-
-    FREE( cpr );
-  }
-}
-
-
-/* ChainContextPosFormat1 */
-
-static HB_Error  Load_ChainContextPos1( HB_ChainContextPosFormat1*  ccpf1,
-					HB_Stream                    stream )
-{
-  HB_Error  error;
-
-  HB_UShort             n, m, count;
-  HB_UInt              cur_offset, new_offset, base_offset;
-
-  HB_ChainPosRuleSet*  cprs;
-
-
-  base_offset = FILE_Pos() - 2L;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &ccpf1->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = ccpf1->ChainPosRuleSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccpf1->ChainPosRuleSet = NULL;
-
-  if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, HB_ChainPosRuleSet ) )
-    goto Fail2;
-
-  cprs = ccpf1->ChainPosRuleSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_ChainPosRuleSet( &cprs[n], stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_ChainPosRuleSet( &cprs[m] );
-
-  FREE( cprs );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &ccpf1->Coverage );
-  return error;
-}
-
-
-static void  Free_ChainContextPos1( HB_ChainContextPosFormat1*  ccpf1 )
-{
-  HB_UShort             n, count;
-
-  HB_ChainPosRuleSet*  cprs;
-
-
-  if ( ccpf1->ChainPosRuleSet )
-  {
-    count = ccpf1->ChainPosRuleSetCount;
-    cprs  = ccpf1->ChainPosRuleSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_ChainPosRuleSet( &cprs[n] );
-
-    FREE( cprs );
-  }
-
-  _HB_OPEN_Free_Coverage( &ccpf1->Coverage );
-}
-
-
-/* ChainPosClassRule */
-
-static HB_Error  Load_ChainPosClassRule(
-		   HB_ChainContextPosFormat2*  ccpf2,
-		   HB_ChainPosClassRule*       cpcr,
-		   HB_Stream                    stream )
-{
-  HB_Error  error;
-
-  HB_UShort             n, count;
-
-  HB_UShort*            b;
-  HB_UShort*            i;
-  HB_UShort*            l;
-  HB_PosLookupRecord*  plr;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  cpcr->BacktrackGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength )
-    ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount;
-
-  cpcr->Backtrack = NULL;
-
-  count = cpcr->BacktrackGlyphCount;
-
-  if ( ALLOC_ARRAY( cpcr->Backtrack, count, HB_UShort ) )
-    return error;
-
-  b = cpcr->Backtrack;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail4;
-
-  for ( n = 0; n < count; n++ )
-    b[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail4;
-
-  cpcr->InputGlyphCount = GET_UShort();
-
-  if ( cpcr->InputGlyphCount > ccpf2->MaxInputLength )
-    ccpf2->MaxInputLength = cpcr->InputGlyphCount;
-
-  FORGET_Frame();
-
-  cpcr->Input = NULL;
-
-  count = cpcr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
-
-  if ( ALLOC_ARRAY( cpcr->Input, count, HB_UShort ) )
-    goto Fail4;
-
-  i = cpcr->Input;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail3;
-
-  for ( n = 0; n < count; n++ )
-    i[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  cpcr->LookaheadGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( cpcr->LookaheadGlyphCount > ccpf2->MaxLookaheadLength )
-    ccpf2->MaxLookaheadLength = cpcr->LookaheadGlyphCount;
-
-  cpcr->Lookahead = NULL;
-
-  count = cpcr->LookaheadGlyphCount;
-
-  if ( ALLOC_ARRAY( cpcr->Lookahead, count, HB_UShort ) )
-    goto Fail3;
-
-  l = cpcr->Lookahead;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail2;
-
-  for ( n = 0; n < count; n++ )
-    l[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  cpcr->PosCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cpcr->PosLookupRecord = NULL;
-
-  count = cpcr->PosCount;
-
-  if ( ALLOC_ARRAY( cpcr->PosLookupRecord, count, HB_PosLookupRecord ) )
-    goto Fail2;
-
-  plr = cpcr->PosLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    plr[n].SequenceIndex   = GET_UShort();
-    plr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( plr );
-
-Fail2:
-  FREE( l );
-
-Fail3:
-  FREE( i );
-
-Fail4:
-  FREE( b );
-  return error;
-}
-
-
-static void  Free_ChainPosClassRule( HB_ChainPosClassRule*  cpcr )
-{
-  FREE( cpcr->PosLookupRecord );
-  FREE( cpcr->Lookahead );
-  FREE( cpcr->Input );
-  FREE( cpcr->Backtrack );
-}
-
-
-/* PosClassSet */
-
-static HB_Error  Load_ChainPosClassSet(
-		   HB_ChainContextPosFormat2*  ccpf2,
-		   HB_ChainPosClassSet*        cpcs,
-		   HB_Stream                    stream )
-{
-  HB_Error  error;
-
-  HB_UShort               n, m, count;
-  HB_UInt                cur_offset, new_offset, base_offset;
-
-  HB_ChainPosClassRule*  cpcr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = cpcs->ChainPosClassRuleCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cpcs->ChainPosClassRule = NULL;
-
-  if ( ALLOC_ARRAY( cpcs->ChainPosClassRule, count,
-		    HB_ChainPosClassRule ) )
-    return error;
-
-  cpcr = cpcs->ChainPosClassRule;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_ChainPosClassRule( ccpf2, &cpcr[n],
-					   stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_ChainPosClassRule( &cpcr[m] );
-
-  FREE( cpcr );
-  return error;
-}
-
-
-static void  Free_ChainPosClassSet( HB_ChainPosClassSet*  cpcs )
-{
-  HB_UShort               n, count;
-
-  HB_ChainPosClassRule*  cpcr;
-
-
-  if ( cpcs->ChainPosClassRule )
-  {
-    count = cpcs->ChainPosClassRuleCount;
-    cpcr  = cpcs->ChainPosClassRule;
-
-    for ( n = 0; n < count; n++ )
-      Free_ChainPosClassRule( &cpcr[n] );
-
-    FREE( cpcr );
-  }
-}
-
-
-/* ChainContextPosFormat2 */
-
-static HB_Error  Load_ChainContextPos2( HB_ChainContextPosFormat2*  ccpf2,
-					HB_Stream                    stream )
-{
-  HB_Error  error;
-
-  HB_UShort              n, m, count;
-  HB_UInt               cur_offset, new_offset, base_offset;
-  HB_UInt               backtrack_offset, input_offset, lookahead_offset;
-
-  HB_ChainPosClassSet*  cpcs;
-
-
-  base_offset = FILE_Pos() - 2;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &ccpf2->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 8L ) )
-    goto Fail5;
-
-  backtrack_offset = GET_UShort();
-  input_offset     = GET_UShort();
-  lookahead_offset = GET_UShort();
-
-  /* `ChainPosClassSetCount' is the upper limit for input class values,
-     thus we read it now to make an additional safety check. No limit
-     is known or needed for the other two class definitions          */
-
-  count = ccpf2->ChainPosClassSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->BacktrackClassDef, 65535,
-						       backtrack_offset, base_offset,
-						       stream ) ) != HB_Err_Ok )
-    goto Fail5;
-  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->InputClassDef, count,
-						       input_offset, base_offset,
-						       stream ) ) != HB_Err_Ok )
-    goto Fail4;
-  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->LookaheadClassDef, 65535,
-						       lookahead_offset, base_offset,
-						       stream ) ) != HB_Err_Ok )
-    goto Fail3;
-
-  ccpf2->ChainPosClassSet   = NULL;
-  ccpf2->MaxBacktrackLength = 0;
-  ccpf2->MaxInputLength     = 0;
-  ccpf2->MaxLookaheadLength = 0;
-
-  if ( ALLOC_ARRAY( ccpf2->ChainPosClassSet, count, HB_ChainPosClassSet ) )
-    goto Fail2;
-
-  cpcs = ccpf2->ChainPosClassSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    if ( new_offset != base_offset )      /* not a NULL offset */
-    {
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = Load_ChainPosClassSet( ccpf2, &cpcs[n],
-					    stream ) ) != HB_Err_Ok )
-	goto Fail1;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-    {
-      /* we create a ChainPosClassSet table with no entries */
-
-      ccpf2->ChainPosClassSet[n].ChainPosClassRuleCount = 0;
-      ccpf2->ChainPosClassSet[n].ChainPosClassRule      = NULL;
-    }
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_ChainPosClassSet( &cpcs[m] );
-
-  FREE( cpcs );
-
-Fail2:
-  _HB_OPEN_Free_ClassDefinition( &ccpf2->LookaheadClassDef );
-
-Fail3:
-  _HB_OPEN_Free_ClassDefinition( &ccpf2->InputClassDef );
-
-Fail4:
-  _HB_OPEN_Free_ClassDefinition( &ccpf2->BacktrackClassDef );
-
-Fail5:
-  _HB_OPEN_Free_Coverage( &ccpf2->Coverage );
-  return error;
-}
-
-
-static void  Free_ChainContextPos2( HB_ChainContextPosFormat2*  ccpf2 )
-{
-  HB_UShort              n, count;
-
-  HB_ChainPosClassSet*  cpcs;
-
-
-  if ( ccpf2->ChainPosClassSet )
-  {
-    count = ccpf2->ChainPosClassSetCount;
-    cpcs  = ccpf2->ChainPosClassSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_ChainPosClassSet( &cpcs[n] );
-
-    FREE( cpcs );
-  }
-
-  _HB_OPEN_Free_ClassDefinition( &ccpf2->LookaheadClassDef );
-  _HB_OPEN_Free_ClassDefinition( &ccpf2->InputClassDef );
-  _HB_OPEN_Free_ClassDefinition( &ccpf2->BacktrackClassDef );
-
-  _HB_OPEN_Free_Coverage( &ccpf2->Coverage );
-}
-
-
-/* ChainContextPosFormat3 */
-
-static HB_Error  Load_ChainContextPos3( HB_ChainContextPosFormat3*  ccpf3,
-					HB_Stream                    stream )
-{
-  HB_Error  error;
-
-  HB_UShort             n, nb, ni, nl, m, count;
-  HB_UShort             backtrack_count, input_count, lookahead_count;
-  HB_UInt              cur_offset, new_offset, base_offset;
-
-  HB_Coverage*         b;
-  HB_Coverage*         i;
-  HB_Coverage*         l;
-  HB_PosLookupRecord*  plr;
-
-
-  base_offset = FILE_Pos() - 2L;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  ccpf3->BacktrackGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccpf3->BacktrackCoverage = NULL;
-
-  backtrack_count = ccpf3->BacktrackGlyphCount;
-
-  if ( ALLOC_ARRAY( ccpf3->BacktrackCoverage, backtrack_count,
-		    HB_Coverage ) )
-    return error;
-
-  b = ccpf3->BacktrackCoverage;
-
-  for ( nb = 0; nb < backtrack_count; nb++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail4;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok )
-      goto Fail4;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail4;
-
-  ccpf3->InputGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccpf3->InputCoverage = NULL;
-
-  input_count = ccpf3->InputGlyphCount;
-
-  if ( ALLOC_ARRAY( ccpf3->InputCoverage, input_count, HB_Coverage ) )
-    goto Fail4;
-
-  i = ccpf3->InputCoverage;
-
-  for ( ni = 0; ni < input_count; ni++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail3;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_Err_Ok )
-      goto Fail3;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  ccpf3->LookaheadGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccpf3->LookaheadCoverage = NULL;
-
-  lookahead_count = ccpf3->LookaheadGlyphCount;
-
-  if ( ALLOC_ARRAY( ccpf3->LookaheadCoverage, lookahead_count,
-		    HB_Coverage ) )
-    goto Fail3;
-
-  l = ccpf3->LookaheadCoverage;
-
-  for ( nl = 0; nl < lookahead_count; nl++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail2;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok )
-      goto Fail2;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  ccpf3->PosCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccpf3->PosLookupRecord = NULL;
-
-  count = ccpf3->PosCount;
-
-  if ( ALLOC_ARRAY( ccpf3->PosLookupRecord, count, HB_PosLookupRecord ) )
-    goto Fail2;
-
-  plr = ccpf3->PosLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    plr[n].SequenceIndex   = GET_UShort();
-    plr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( plr );
-
-Fail2:
-  for ( m = 0; m < nl; m++ )
-    _HB_OPEN_Free_Coverage( &l[m] );
-
-  FREE( l );
-
-Fail3:
-  for ( m = 0; m < ni; m++ )
-    _HB_OPEN_Free_Coverage( &i[m] );
-
-  FREE( i );
-
-Fail4:
-  for ( m = 0; m < nb; m++ )
-    _HB_OPEN_Free_Coverage( &b[m] );
-
-  FREE( b );
-  return error;
-}
-
-
-static void  Free_ChainContextPos3( HB_ChainContextPosFormat3*  ccpf3 )
-{
-  HB_UShort      n, count;
-
-  HB_Coverage*  c;
-
-
-  FREE( ccpf3->PosLookupRecord );
-
-  if ( ccpf3->LookaheadCoverage )
-  {
-    count = ccpf3->LookaheadGlyphCount;
-    c     = ccpf3->LookaheadCoverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-
-  if ( ccpf3->InputCoverage )
-  {
-    count = ccpf3->InputGlyphCount;
-    c     = ccpf3->InputCoverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-
-  if ( ccpf3->BacktrackCoverage )
-  {
-    count = ccpf3->BacktrackGlyphCount;
-    c     = ccpf3->BacktrackCoverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-}
-
-
-/* ChainContextPos */
-
-static HB_Error  Load_ChainContextPos( HB_GPOS_SubTable* st,
-				       HB_Stream             stream )
-{
-  HB_Error  error;
-  HB_ChainContextPos*  ccp = &st->chain;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  ccp->PosFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  switch ( ccp->PosFormat )
-  {
-  case 1:
-    return Load_ChainContextPos1( &ccp->ccpf.ccpf1, stream );
-
-  case 2:
-    return Load_ChainContextPos2( &ccp->ccpf.ccpf2, stream );
-
-  case 3:
-    return Load_ChainContextPos3( &ccp->ccpf.ccpf3, stream );
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-static void  Free_ChainContextPos( HB_GPOS_SubTable* st )
-{
-  HB_ChainContextPos*  ccp = &st->chain;
-
-  switch ( ccp->PosFormat )
-  {
-  case 1:  Free_ChainContextPos1( &ccp->ccpf.ccpf1 ); break;
-  case 2:  Free_ChainContextPos2( &ccp->ccpf.ccpf2 ); break;
-  case 3:  Free_ChainContextPos3( &ccp->ccpf.ccpf3 ); break;
-  default:						      break;
-  }
-}
-
-
-static HB_Error  Lookup_ChainContextPos1(
-		   GPOS_Instance*               gpi,
-		   HB_ChainContextPosFormat1*  ccpf1,
-		   HB_Buffer                   buffer,
-		   HB_UShort                    flags,
-		   HB_UShort                    context_length,
-		   int                          nesting_level )
-{
-  HB_UShort          index, property;
-  HB_UShort          i, j, k, num_cpr;
-  HB_UShort          bgc, igc, lgc;
-  HB_Error           error;
-  HB_GPOSHeader*    gpos = gpi->gpos;
-
-  HB_ChainPosRule*  cpr;
-  HB_ChainPosRule   curr_cpr;
-  HB_GDEFHeader*    gdef;
-
-
-  gdef = gpos->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &ccpf1->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  cpr     = ccpf1->ChainPosRuleSet[index].ChainPosRule;
-  num_cpr = ccpf1->ChainPosRuleSet[index].ChainPosRuleCount;
-
-  for ( k = 0; k < num_cpr; k++ )
-  {
-    curr_cpr = cpr[k];
-    bgc      = curr_cpr.BacktrackGlyphCount;
-    igc      = curr_cpr.InputGlyphCount;
-    lgc      = curr_cpr.LookaheadGlyphCount;
-
-    if ( context_length != 0xFFFF && context_length < igc )
-      goto next_chainposrule;
-
-    /* check whether context is too long; it is a first guess only */
-
-    if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length )
-      goto next_chainposrule;
-
-    if ( bgc )
-    {
-      /* Since we don't know in advance the number of glyphs to inspect,
-	 we search backwards for matches in the backtrack glyph array    */
-
-      for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
-      {
-	while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-	{
-	  if ( error && error != HB_Err_Not_Covered )
-	    return error;
-
-	  if ( j + 1 == bgc - i )
-	    goto next_chainposrule;
-	  j--;
-	}
-
-	/* In OpenType 1.3, it is undefined whether the offsets of
-	   backtrack glyphs is in logical order or not.  Version 1.4
-	   will clarify this:
-
-	     Logical order -      a  b  c  d  e  f  g  h  i  j
-					      i
-	     Input offsets -                  0  1
-	     Backtrack offsets -  3  2  1  0
-	     Lookahead offsets -                    0  1  2  3           */
-
-	if ( IN_GLYPH( j ) != curr_cpr.Backtrack[i] )
-	  goto next_chainposrule;
-      }
-    }
-
-    /* Start at 1 because [0] is implied */
-
-    for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
-	  goto next_chainposrule;
-	j++;
-      }
-
-      if ( IN_GLYPH( j ) != curr_cpr.Input[i - 1] )
-	goto next_chainposrule;
-    }
-
-    /* we are starting to check for lookahead glyphs right after the
-       last context glyph                                            */
-
-    for ( i = 0; i < lgc; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + lgc - i == (HB_Int)buffer->in_length )
-	  goto next_chainposrule;
-	j++;
-      }
-
-      if ( IN_GLYPH( j ) != curr_cpr.Lookahead[i] )
-	goto next_chainposrule;
-    }
-
-    return Do_ContextPos( gpi, igc,
-			  curr_cpr.PosCount,
-			  curr_cpr.PosLookupRecord,
-			  buffer,
-			  nesting_level );
-
-  next_chainposrule:
-    ;
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-static HB_Error  Lookup_ChainContextPos2(
-		   GPOS_Instance*               gpi,
-		   HB_ChainContextPosFormat2*  ccpf2,
-		   HB_Buffer                   buffer,
-		   HB_UShort                    flags,
-		   HB_UShort                    context_length,
-		   int                          nesting_level )
-{
-  HB_UShort              index, property;
-  HB_Error               error;
-  HB_UShort              i, j, k;
-  HB_UShort              bgc, igc, lgc;
-  HB_UShort              known_backtrack_classes,
-			 known_input_classes,
-			 known_lookahead_classes;
-
-  HB_UShort*             backtrack_classes;
-  HB_UShort*             input_classes;
-  HB_UShort*             lookahead_classes;
-
-  HB_UShort*             bc;
-  HB_UShort*             ic;
-  HB_UShort*             lc;
-  HB_GPOSHeader*        gpos = gpi->gpos;
-
-  HB_ChainPosClassSet*  cpcs;
-  HB_ChainPosClassRule  cpcr;
-  HB_GDEFHeader*        gdef;
-
-
-  gdef = gpos->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  /* Note: The coverage table in format 2 doesn't give an index into
-	   anything.  It just lets us know whether or not we need to
-	   do any lookup at all.                                     */
-
-  error = _HB_OPEN_Coverage_Index( &ccpf2->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  if ( ALLOC_ARRAY( backtrack_classes, ccpf2->MaxBacktrackLength, HB_UShort ) )
-    return error;
-  known_backtrack_classes = 0;
-
-  if (ccpf2->MaxInputLength < 1)
-    return HB_Err_Not_Covered;
-
-  if ( ALLOC_ARRAY( input_classes, ccpf2->MaxInputLength, HB_UShort ) )
-    goto End3;
-  known_input_classes = 1;
-
-  if ( ALLOC_ARRAY( lookahead_classes, ccpf2->MaxLookaheadLength, HB_UShort ) )
-    goto End2;
-  known_lookahead_classes = 0;
-
-  error = _HB_OPEN_Get_Class( &ccpf2->InputClassDef, IN_CURGLYPH(),
-		     &input_classes[0], NULL );
-  if ( error && error != HB_Err_Not_Covered )
-    goto End1;
-
-  cpcs = &ccpf2->ChainPosClassSet[input_classes[0]];
-  if ( !cpcs )
-  {
-    error = ERR(HB_Err_Invalid_SubTable);
-    goto End1;
-  }
-
-  for ( k = 0; k < cpcs->ChainPosClassRuleCount; k++ )
-  {
-    cpcr = cpcs->ChainPosClassRule[k];
-    bgc  = cpcr.BacktrackGlyphCount;
-    igc  = cpcr.InputGlyphCount;
-    lgc  = cpcr.LookaheadGlyphCount;
-
-    if ( context_length != 0xFFFF && context_length < igc )
-      goto next_chainposclassrule;
-
-    /* check whether context is too long; it is a first guess only */
-
-    if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length )
-      goto next_chainposclassrule;
-
-    if ( bgc )
-    {
-      /* Since we don't know in advance the number of glyphs to inspect,
-	 we search backwards for matches in the backtrack glyph array.
-	 Note that `known_backtrack_classes' starts at index 0.         */
-
-      bc       = cpcr.Backtrack;
-
-      for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
-      {
-	while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-	{
-	  if ( error && error != HB_Err_Not_Covered )
-	    goto End1;
-
-	  if ( j + 1 == bgc - i )
-	    goto next_chainposclassrule;
-	  j++;
-	}
-
-	if ( i >= known_backtrack_classes )
-	{
-	  /* Keeps us from having to do this for each rule */
-
-	  error = _HB_OPEN_Get_Class( &ccpf2->BacktrackClassDef, IN_GLYPH( j ),
-			     &backtrack_classes[i], NULL );
-	  if ( error && error != HB_Err_Not_Covered )
-	    goto End1;
-	  known_backtrack_classes = i;
-	}
-
-	if ( bc[i] != backtrack_classes[i] )
-	  goto next_chainposclassrule;
-      }
-    }
-
-    ic       = cpcr.Input;
-
-    /* Start at 1 because [0] is implied */
-
-    for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End1;
-
-	if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
-	  goto next_chainposclassrule;
-	j++;
-      }
-
-      if ( i >= known_input_classes )
-      {
-	error = _HB_OPEN_Get_Class( &ccpf2->InputClassDef, IN_GLYPH( j ),
-			   &input_classes[i], NULL );
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End1;
-	known_input_classes = i;
-      }
-
-      if ( ic[i - 1] != input_classes[i] )
-	goto next_chainposclassrule;
-    }
-
-    /* we are starting to check for lookahead glyphs right after the
-       last context glyph                                            */
-
-    lc       = cpcr.Lookahead;
-
-    for ( i = 0; i < lgc; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End1;
-
-	if ( j + lgc - i == (HB_Int)buffer->in_length )
-	  goto next_chainposclassrule;
-	j++;
-      }
-
-      if ( i >= known_lookahead_classes )
-      {
-	error = _HB_OPEN_Get_Class( &ccpf2->LookaheadClassDef, IN_GLYPH( j ),
-			   &lookahead_classes[i], NULL );
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End1;
-	known_lookahead_classes = i;
-      }
-
-      if ( lc[i] != lookahead_classes[i] )
-	goto next_chainposclassrule;
-    }
-
-    error = Do_ContextPos( gpi, igc,
-			   cpcr.PosCount,
-			   cpcr.PosLookupRecord,
-			   buffer,
-			   nesting_level );
-    goto End1;
-
-  next_chainposclassrule:
-    ;
-  }
-
-  error = HB_Err_Not_Covered;
-
-End1:
-  FREE( lookahead_classes );
-
-End2:
-  FREE( input_classes );
-
-End3:
-  FREE( backtrack_classes );
-  return error;
-}
-
-
-static HB_Error  Lookup_ChainContextPos3(
-		   GPOS_Instance*               gpi,
-		   HB_ChainContextPosFormat3*  ccpf3,
-		   HB_Buffer                   buffer,
-		   HB_UShort                    flags,
-		   HB_UShort                    context_length,
-		   int                          nesting_level )
-{
-  HB_UShort        index, i, j, property;
-  HB_UShort        bgc, igc, lgc;
-  HB_Error         error;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-
-  HB_Coverage*    bc;
-  HB_Coverage*    ic;
-  HB_Coverage*    lc;
-  HB_GDEFHeader*  gdef;
-
-
-  gdef = gpos->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  bgc = ccpf3->BacktrackGlyphCount;
-  igc = ccpf3->InputGlyphCount;
-  lgc = ccpf3->LookaheadGlyphCount;
-
-  if ( context_length != 0xFFFF && context_length < igc )
-    return HB_Err_Not_Covered;
-
-  /* check whether context is too long; it is a first guess only */
-
-  if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length )
-    return HB_Err_Not_Covered;
-
-  if ( bgc )
-  {
-    /* Since we don't know in advance the number of glyphs to inspect,
-       we search backwards for matches in the backtrack glyph array    */
-
-    bc       = ccpf3->BacktrackCoverage;
-
-    for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + 1 == bgc - i )
-	  return HB_Err_Not_Covered;
-	j--;
-      }
-
-      error = _HB_OPEN_Coverage_Index( &bc[i], IN_GLYPH( j ), &index );
-      if ( error )
-	return error;
-    }
-  }
-
-  ic       = ccpf3->InputCoverage;
-
-  for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ )
-  {
-    /* We already called CHECK_Property for IN_GLYPH ( buffer->in_pos ) */
-    while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-    {
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-
-      if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
-	return HB_Err_Not_Covered;
-      j++;
-    }
-
-    error = _HB_OPEN_Coverage_Index( &ic[i], IN_GLYPH( j ), &index );
-    if ( error )
-      return error;
-  }
-
-  /* we are starting to check for lookahead glyphs right after the
-     last context glyph                                            */
-
-  lc       = ccpf3->LookaheadCoverage;
-
-  for ( i = 0; i < lgc; i++, j++ )
-  {
-    while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-    {
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-
-      if ( j + lgc - i == (HB_Int)buffer->in_length )
-	return HB_Err_Not_Covered;
-      j++;
-    }
-
-    error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index );
-    if ( error )
-      return error;
-  }
-
-  return Do_ContextPos( gpi, igc,
-			ccpf3->PosCount,
-			ccpf3->PosLookupRecord,
-			buffer,
-			nesting_level );
-}
-
-
-static HB_Error  Lookup_ChainContextPos(
-		   GPOS_Instance*        gpi,
-		   HB_GPOS_SubTable* st,
-		   HB_Buffer            buffer,
-		   HB_UShort             flags,
-		   HB_UShort             context_length,
-		   int                   nesting_level )
-{
-  HB_ChainContextPos*  ccp = &st->chain;
-
-  switch ( ccp->PosFormat )
-  {
-  case 1:
-    return Lookup_ChainContextPos1( gpi, &ccp->ccpf.ccpf1, buffer,
-				    flags, context_length,
-				    nesting_level );
-
-  case 2:
-    return Lookup_ChainContextPos2( gpi, &ccp->ccpf.ccpf2, buffer,
-				    flags, context_length,
-				    nesting_level );
-
-  case 3:
-    return Lookup_ChainContextPos3( gpi, &ccp->ccpf.ccpf3, buffer,
-				    flags, context_length,
-				    nesting_level );
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-
-/***********
- * GPOS API
- ***********/
-
-
-
-HB_Error  HB_GPOS_Select_Script( HB_GPOSHeader*  gpos,
-				 HB_UInt         script_tag,
-				 HB_UShort*       script_index )
-{
-  HB_UShort          n;
-
-  HB_ScriptList*    sl;
-  HB_ScriptRecord*  sr;
-
-
-  if ( !gpos || !script_index )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gpos->ScriptList;
-  sr = sl->ScriptRecord;
-
-  for ( n = 0; n < sl->ScriptCount; n++ )
-    if ( script_tag == sr[n].ScriptTag )
-    {
-      *script_index = n;
-
-      return HB_Err_Ok;
-    }
-
-  return HB_Err_Not_Covered;
-}
-
-
-
-HB_Error  HB_GPOS_Select_Language( HB_GPOSHeader*  gpos,
-				   HB_UInt         language_tag,
-				   HB_UShort        script_index,
-				   HB_UShort*       language_index,
-				   HB_UShort*       req_feature_index )
-{
-  HB_UShort           n;
-
-  HB_ScriptList*     sl;
-  HB_ScriptRecord*   sr;
-  HB_ScriptTable*         s;
-  HB_LangSysRecord*  lsr;
-
-
-  if ( !gpos || !language_index || !req_feature_index )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gpos->ScriptList;
-  sr = sl->ScriptRecord;
-
-  if ( script_index >= sl->ScriptCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  s   = &sr[script_index].Script;
-  lsr = s->LangSysRecord;
-
-  for ( n = 0; n < s->LangSysCount; n++ )
-    if ( language_tag == lsr[n].LangSysTag )
-    {
-      *language_index = n;
-      *req_feature_index = lsr[n].LangSys.ReqFeatureIndex;
-
-      return HB_Err_Ok;
-    }
-
-  return HB_Err_Not_Covered;
-}
-
-
-/* selecting 0xFFFF for language_index asks for the values of the
-   default language (DefaultLangSys)                              */
-
-
-HB_Error  HB_GPOS_Select_Feature( HB_GPOSHeader*  gpos,
-				  HB_UInt         feature_tag,
-				  HB_UShort        script_index,
-				  HB_UShort        language_index,
-				  HB_UShort*       feature_index )
-{
-  HB_UShort           n;
-
-  HB_ScriptList*     sl;
-  HB_ScriptRecord*   sr;
-  HB_ScriptTable*         s;
-  HB_LangSysRecord*  lsr;
-  HB_LangSys*        ls;
-  HB_UShort*          fi;
-
-  HB_FeatureList*    fl;
-  HB_FeatureRecord*  fr;
-
-
-  if ( !gpos || !feature_index )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gpos->ScriptList;
-  sr = sl->ScriptRecord;
-
-  fl = &gpos->FeatureList;
-  fr = fl->FeatureRecord;
-
-  if ( script_index >= sl->ScriptCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  s   = &sr[script_index].Script;
-  lsr = s->LangSysRecord;
-
-  if ( language_index == 0xFFFF )
-    ls = &s->DefaultLangSys;
-  else
-  {
-    if ( language_index >= s->LangSysCount )
-      return ERR(HB_Err_Invalid_Argument);
-
-    ls = &lsr[language_index].LangSys;
-  }
-
-  fi = ls->FeatureIndex;
-
-  for ( n = 0; n < ls->FeatureCount; n++ )
-  {
-    if ( fi[n] >= fl->FeatureCount )
-      return ERR(HB_Err_Invalid_SubTable_Format);
-
-    if ( feature_tag == fr[fi[n]].FeatureTag )
-    {
-      *feature_index = fi[n];
-
-      return HB_Err_Ok;
-    }
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-/* The next three functions return a null-terminated list */
-
-
-HB_Error  HB_GPOS_Query_Scripts( HB_GPOSHeader*  gpos,
-				 HB_UInt**       script_tag_list )
-{
-  HB_Error           error;
-  HB_UShort          n;
-  HB_UInt*          stl;
-
-  HB_ScriptList*    sl;
-  HB_ScriptRecord*  sr;
-
-
-  if ( !gpos || !script_tag_list )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gpos->ScriptList;
-  sr = sl->ScriptRecord;
-
-  if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, HB_UInt ) )
-    return error;
-
-  for ( n = 0; n < sl->ScriptCount; n++ )
-    stl[n] = sr[n].ScriptTag;
-  stl[n] = 0;
-
-  *script_tag_list = stl;
-
-  return HB_Err_Ok;
-}
-
-
-
-HB_Error  HB_GPOS_Query_Languages( HB_GPOSHeader*  gpos,
-				   HB_UShort        script_index,
-				   HB_UInt**       language_tag_list )
-{
-  HB_Error            error;
-  HB_UShort           n;
-  HB_UInt*           ltl;
-
-  HB_ScriptList*     sl;
-  HB_ScriptRecord*   sr;
-  HB_ScriptTable*    s;
-  HB_LangSysRecord*  lsr;
-
-
-  if ( !gpos || !language_tag_list )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gpos->ScriptList;
-  sr = sl->ScriptRecord;
-
-  if ( script_index >= sl->ScriptCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  s   = &sr[script_index].Script;
-  lsr = s->LangSysRecord;
-
-  if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, HB_UInt ) )
-    return error;
-
-  for ( n = 0; n < s->LangSysCount; n++ )
-    ltl[n] = lsr[n].LangSysTag;
-  ltl[n] = 0;
-
-  *language_tag_list = ltl;
-
-  return HB_Err_Ok;
-}
-
-
-/* selecting 0xFFFF for language_index asks for the values of the
-   default language (DefaultLangSys)                              */
-
-
-HB_Error  HB_GPOS_Query_Features( HB_GPOSHeader*  gpos,
-				  HB_UShort        script_index,
-				  HB_UShort        language_index,
-				  HB_UInt**       feature_tag_list )
-{
-  HB_UShort           n;
-  HB_Error            error;
-  HB_UInt*           ftl;
-
-  HB_ScriptList*     sl;
-  HB_ScriptRecord*   sr;
-  HB_ScriptTable*    s;
-  HB_LangSysRecord*  lsr;
-  HB_LangSys*        ls;
-  HB_UShort*          fi;
-
-  HB_FeatureList*    fl;
-  HB_FeatureRecord*  fr;
-
-
-  if ( !gpos || !feature_tag_list )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gpos->ScriptList;
-  sr = sl->ScriptRecord;
-
-  fl = &gpos->FeatureList;
-  fr = fl->FeatureRecord;
-
-  if ( script_index >= sl->ScriptCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  s   = &sr[script_index].Script;
-  lsr = s->LangSysRecord;
-
-  if ( language_index == 0xFFFF )
-    ls = &s->DefaultLangSys;
-  else
-  {
-    if ( language_index >= s->LangSysCount )
-      return ERR(HB_Err_Invalid_Argument);
-
-    ls = &lsr[language_index].LangSys;
-  }
-
-  fi = ls->FeatureIndex;
-
-  if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, HB_UInt ) )
-    return error;
-
-  for ( n = 0; n < ls->FeatureCount; n++ )
-  {
-    if ( fi[n] >= fl->FeatureCount )
-    {
-      FREE( ftl );
-      return ERR(HB_Err_Invalid_SubTable_Format);
-    }
-    ftl[n] = fr[fi[n]].FeatureTag;
-  }
-  ftl[n] = 0;
-
-  *feature_tag_list = ftl;
-
-  return HB_Err_Ok;
-}
-
-
-/* Do an individual subtable lookup.  Returns HB_Err_Ok if positioning
-   has been done, or HB_Err_Not_Covered if not.                        */
-static HB_Error  GPOS_Do_Glyph_Lookup( GPOS_Instance*    gpi,
-				       HB_UShort         lookup_index,
-				       HB_Buffer        buffer,
-				       HB_UShort         context_length,
-				       int               nesting_level )
-{
-  HB_Error             error = HB_Err_Not_Covered;
-  HB_UShort            i, flags, lookup_count;
-  HB_GPOSHeader*       gpos = gpi->gpos;
-  HB_Lookup*           lo;
-  int		       lookup_type;
-
-
-  nesting_level++;
-
-  if ( nesting_level > HB_MAX_NESTING_LEVEL )
-    return ERR(HB_Err_Not_Covered); /* ERR() call intended */
-
-  lookup_count = gpos->LookupList.LookupCount;
-  if (lookup_index >= lookup_count)
-    return error;
-
-  lo    = &gpos->LookupList.Lookup[lookup_index];
-  flags = lo->LookupFlag;
-  lookup_type = lo->LookupType;
-
-  for ( i = 0; i < lo->SubTableCount; i++ )
-  {
-    HB_GPOS_SubTable *st = &lo->SubTable[i].st.gpos;
-
-    switch (lookup_type) {
-      case HB_GPOS_LOOKUP_SINGLE:
-        error = Lookup_SinglePos	( gpi, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GPOS_LOOKUP_PAIR:
-	error = Lookup_PairPos		( gpi, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GPOS_LOOKUP_CURSIVE:
-	error = Lookup_CursivePos	( gpi, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GPOS_LOOKUP_MARKBASE:
-	error = Lookup_MarkBasePos	( gpi, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GPOS_LOOKUP_MARKLIG:
-	error = Lookup_MarkLigPos	( gpi, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GPOS_LOOKUP_MARKMARK:
-	error = Lookup_MarkMarkPos	( gpi, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GPOS_LOOKUP_CONTEXT:
-	error = Lookup_ContextPos	( gpi, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GPOS_LOOKUP_CHAIN:
-	error = Lookup_ChainContextPos	( gpi, st, buffer, flags, context_length, nesting_level ); break;
-    /*case HB_GPOS_LOOKUP_EXTENSION:
-	error = Lookup_ExtensionPos	( gpi, st, buffer, flags, context_length, nesting_level ); break;*/
-      default:
-	error = HB_Err_Not_Covered;
-    }
-
-    /* Check whether we have a successful positioning or an error other
-       than HB_Err_Not_Covered                                         */
-    if ( error != HB_Err_Not_Covered )
-      return error;
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-HB_INTERNAL HB_Error
-_HB_GPOS_Load_SubTable( HB_GPOS_SubTable* st,
-			HB_Stream         stream,
-			HB_UShort         lookup_type )
-{
-  switch ( lookup_type ) {
-    case HB_GPOS_LOOKUP_SINGLE:		return Load_SinglePos		( st, stream );
-    case HB_GPOS_LOOKUP_PAIR:		return Load_PairPos		( st, stream );
-    case HB_GPOS_LOOKUP_CURSIVE:	return Load_CursivePos		( st, stream );
-    case HB_GPOS_LOOKUP_MARKBASE:	return Load_MarkBasePos		( st, stream );
-    case HB_GPOS_LOOKUP_MARKLIG:	return Load_MarkLigPos		( st, stream );
-    case HB_GPOS_LOOKUP_MARKMARK:	return Load_MarkMarkPos		( st, stream );
-    case HB_GPOS_LOOKUP_CONTEXT:	return Load_ContextPos		( st, stream );
-    case HB_GPOS_LOOKUP_CHAIN:		return Load_ChainContextPos	( st, stream );
-  /*case HB_GPOS_LOOKUP_EXTENSION:	return Load_ExtensionPos	( st, stream );*/
-    default:				return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-}
-
-
-HB_INTERNAL void
-_HB_GPOS_Free_SubTable( HB_GPOS_SubTable* st,
-			HB_UShort         lookup_type )
-{
-  switch ( lookup_type ) {
-    case HB_GPOS_LOOKUP_SINGLE:		Free_SinglePos		( st ); return;
-    case HB_GPOS_LOOKUP_PAIR:		Free_PairPos		( st ); return;
-    case HB_GPOS_LOOKUP_CURSIVE:	Free_CursivePos		( st ); return;
-    case HB_GPOS_LOOKUP_MARKBASE:	Free_MarkBasePos	( st ); return;
-    case HB_GPOS_LOOKUP_MARKLIG:	Free_MarkLigPos		( st ); return;
-    case HB_GPOS_LOOKUP_MARKMARK:	Free_MarkMarkPos	( st ); return;
-    case HB_GPOS_LOOKUP_CONTEXT:	Free_ContextPos		( st ); return;
-    case HB_GPOS_LOOKUP_CHAIN:		Free_ChainContextPos	( st ); return;
-  /*case HB_GPOS_LOOKUP_EXTENSION:	Free_ExtensionPos	( st ); return;*/
-    default:									return;
-  }
-}
-
-
-/* apply one lookup to the input string object */
-
-static HB_Error  GPOS_Do_String_Lookup( GPOS_Instance*    gpi,
-				   HB_UShort         lookup_index,
-				   HB_Buffer        buffer )
-{
-  HB_Error         error, retError = HB_Err_Not_Covered;
-  HB_GPOSHeader*  gpos = gpi->gpos;
-
-  HB_UInt*  properties = gpos->LookupList.Properties;
-
-  const int       nesting_level = 0;
-  /* 0xFFFF indicates that we don't have a context length yet */
-  const HB_UShort context_length = 0xFFFF;
-
-
-  gpi->last  = 0xFFFF;     /* no last valid glyph for cursive pos. */
-
-  buffer->in_pos = 0;
-  while ( buffer->in_pos < buffer->in_length )
-  {
-    if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
-    {
-      /* Note that the connection between mark and base glyphs hold
-	 exactly one (string) lookup.  For example, it would be possible
-	 that in the first lookup, mark glyph X is attached to base
-	 glyph A, and in the next lookup it is attached to base glyph B.
-	 It is up to the font designer to provide meaningful lookups and
-	 lookup order.                                                   */
-
-      error = GPOS_Do_Glyph_Lookup( gpi, lookup_index, buffer, context_length, nesting_level );
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-    }
-    else
-    {
-      /* Contrary to properties defined in GDEF, user-defined properties
-	 will always stop a possible cursive positioning.                */
-      gpi->last = 0xFFFF;
-
-      error = HB_Err_Not_Covered;
-    }
-
-    if ( error == HB_Err_Not_Covered )
-      (buffer->in_pos)++;
-    else
-      retError = error;
-  }
-
-  return retError;
-}
-
-
-static HB_Error  Position_CursiveChain ( HB_Buffer     buffer )
-{
-  HB_UInt   i, j;
-  HB_Position positions = buffer->positions;
-
-  /* First handle all left-to-right connections */
-  for (j = 0; j < buffer->in_length; j++)
-  {
-    if (positions[j].cursive_chain > 0)
-      positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos;
-  }
-
-  /* Then handle all right-to-left connections */
-  for (i = buffer->in_length; i > 0; i--)
-  {
-    j = i - 1;
-
-    if (positions[j].cursive_chain < 0)
-      positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos;
-  }
-
-  return HB_Err_Ok;
-}
-
-
-HB_Error  HB_GPOS_Add_Feature( HB_GPOSHeader*  gpos,
-			       HB_UShort        feature_index,
-			       HB_UInt          property )
-{
-  HB_UShort    i;
-
-  HB_Feature  feature;
-  HB_UInt*     properties;
-  HB_UShort*   index;
-  HB_UShort    lookup_count;
-
-  /* Each feature can only be added once */
-
-  if ( !gpos ||
-       feature_index >= gpos->FeatureList.FeatureCount ||
-       gpos->FeatureList.ApplyCount == gpos->FeatureList.FeatureCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  gpos->FeatureList.ApplyOrder[gpos->FeatureList.ApplyCount++] = feature_index;
-
-  properties = gpos->LookupList.Properties;
-
-  feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
-  index   = feature.LookupListIndex;
-  lookup_count = gpos->LookupList.LookupCount;
-
-  for ( i = 0; i < feature.LookupListCount; i++ )
-  {
-    HB_UShort lookup_index = index[i];
-    if (lookup_index < lookup_count)
-      properties[lookup_index] |= property;
-  }
-
-  return HB_Err_Ok;
-}
-
-
-
-HB_Error  HB_GPOS_Clear_Features( HB_GPOSHeader*  gpos )
-{
-  HB_UShort i;
-
-  HB_UInt*  properties;
-
-
-  if ( !gpos )
-    return ERR(HB_Err_Invalid_Argument);
-
-  gpos->FeatureList.ApplyCount = 0;
-
-  properties = gpos->LookupList.Properties;
-
-  for ( i = 0; i < gpos->LookupList.LookupCount; i++ )
-    properties[i] = 0;
-
-  return HB_Err_Ok;
-}
-
-
-
-HB_Error  HB_GPOS_Register_MM_Function( HB_GPOSHeader*  gpos,
-					HB_MMFunction   mmfunc,
-					void*            data )
-{
-  if ( !gpos )
-    return ERR(HB_Err_Invalid_Argument);
-
-  gpos->mmfunc = mmfunc;
-  gpos->data   = data;
-
-  return HB_Err_Ok;
-}
-
-/* If `dvi' is TRUE, glyph contour points for anchor points and device
-   tables are ignored -- you will get device independent values.         */
-
-
-HB_Error  HB_GPOS_Apply_String( HB_Font            font,
-				HB_GPOSHeader*    gpos,
-				HB_UShort          load_flags,
-				HB_Buffer         buffer,
-				HB_Bool            dvi,
-				HB_Bool            r2l )
-{
-  HB_Error       error, retError = HB_Err_Not_Covered;
-  GPOS_Instance  gpi;
-  int            i, j, lookup_count, num_features;
-
-  if ( !font || !gpos || !buffer )
-    return ERR(HB_Err_Invalid_Argument);
-
-  if ( buffer->in_length == 0 )
-    return HB_Err_Not_Covered;
-
-  gpi.font       = font;
-  gpi.gpos       = gpos;
-  gpi.load_flags = load_flags;
-  gpi.r2l        = r2l;
-  gpi.dvi        = dvi;
-
-  lookup_count = gpos->LookupList.LookupCount;
-  num_features = gpos->FeatureList.ApplyCount;
-
-  if ( num_features )
-    {
-      error = _hb_buffer_clear_positions( buffer );
-      if ( error )
-	return error;
-    }
-
-  for ( i = 0; i < num_features; i++ )
-  {
-    HB_UShort  feature_index = gpos->FeatureList.ApplyOrder[i];
-    HB_Feature feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
-
-    for ( j = 0; j < feature.LookupListCount; j++ )
-    {
-      HB_UShort lookup_index = feature.LookupListIndex[j];
-
-      /* Skip nonexistant lookups */
-      if (lookup_index >= lookup_count)
-       continue;
-
-      error = GPOS_Do_String_Lookup( &gpi, lookup_index, buffer );
-      if ( error )
-      {
-	if ( error != HB_Err_Not_Covered )
-	  return error;
-      }
-      else
-	retError = error;
-    }
-  }
-
-  if ( num_features )
-    {
-  error = Position_CursiveChain ( buffer );
-  if ( error )
-    return error;
-    }
-
-  return retError;
-}
-
-/* END */
diff --git a/third_party/harfbuzz/src/harfbuzz-gpos.h b/third_party/harfbuzz/src/harfbuzz-gpos.h
deleted file mode 100644
index 2840dae..0000000
--- a/third_party/harfbuzz/src/harfbuzz-gpos.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_GPOS_H
-#define HARFBUZZ_GPOS_H
-
-#include "harfbuzz-gdef.h"
-#include "harfbuzz-buffer.h"
-
-HB_BEGIN_HEADER
-
-
-/* Lookup types for glyph positioning */
-
-#define HB_GPOS_LOOKUP_SINGLE     1
-#define HB_GPOS_LOOKUP_PAIR       2
-#define HB_GPOS_LOOKUP_CURSIVE    3
-#define HB_GPOS_LOOKUP_MARKBASE   4
-#define HB_GPOS_LOOKUP_MARKLIG    5
-#define HB_GPOS_LOOKUP_MARKMARK   6
-#define HB_GPOS_LOOKUP_CONTEXT    7
-#define HB_GPOS_LOOKUP_CHAIN      8
-#define HB_GPOS_LOOKUP_EXTENSION  9
-
-/* A pointer to a function which accesses the PostScript interpreter.
-   Multiple Master fonts need this interface to convert a metric ID
-   (as stored in an OpenType font version 1.2 or higher) `metric_id'
-   into a metric value (returned in `metric_value').
-
-   `data' points to the user-defined structure specified during a
-   call to HB_GPOS_Register_MM_Function().
-
-   `metric_value' must be returned as a scaled value (but shouldn't
-   be rounded).                                                       */
-
-typedef HB_Error  (*HB_MMFunction)(HB_Font       font,
-				    HB_UShort    metric_id,
-				    HB_Fixed*      metric_value,
-				    void*        data );
-
-
-struct  HB_GPOSHeader_
-{
-  HB_16Dot16           Version;
-
-  HB_ScriptList     ScriptList;
-  HB_FeatureList    FeatureList;
-  HB_LookupList     LookupList;
-
-  HB_GDEFHeader*    gdef;
-
-  /* this is OpenType 1.2 -- Multiple Master fonts need this
-     callback function to get various metric values from the
-     PostScript interpreter.                                 */
-
-  HB_MMFunction     mmfunc;
-  void*              data;
-};
-
-typedef struct HB_GPOSHeader_  HB_GPOSHeader;
-typedef HB_GPOSHeader* HB_GPOS;
-
-
-HB_Error  HB_Load_GPOS_Table( HB_Stream stream, 
-                              HB_GPOSHeader** gpos,
-			      HB_GDEFHeader*  gdef,
-                              HB_Stream       gdefStream );
-
-
-HB_Error  HB_Done_GPOS_Table( HB_GPOSHeader* gpos );
-
-
-HB_Error  HB_GPOS_Select_Script( HB_GPOSHeader*  gpos,
-				 HB_UInt         script_tag,
-				 HB_UShort*       script_index );
-
-HB_Error  HB_GPOS_Select_Language( HB_GPOSHeader*  gpos,
-				   HB_UInt         language_tag,
-				   HB_UShort        script_index,
-				   HB_UShort*       language_index,
-				   HB_UShort*       req_feature_index );
-
-HB_Error  HB_GPOS_Select_Feature( HB_GPOSHeader*  gpos,
-				  HB_UInt         feature_tag,
-				  HB_UShort        script_index,
-				  HB_UShort        language_index,
-				  HB_UShort*       feature_index );
-
-
-HB_Error  HB_GPOS_Query_Scripts( HB_GPOSHeader*  gpos,
-				 HB_UInt**       script_tag_list );
-
-HB_Error  HB_GPOS_Query_Languages( HB_GPOSHeader*  gpos,
-				   HB_UShort        script_index,
-				   HB_UInt**       language_tag_list );
-
-HB_Error  HB_GPOS_Query_Features( HB_GPOSHeader*  gpos,
-				  HB_UShort        script_index,
-				  HB_UShort        language_index,
-				  HB_UInt**       feature_tag_list );
-
-
-HB_Error  HB_GPOS_Add_Feature( HB_GPOSHeader*  gpos,
-			       HB_UShort        feature_index,
-			       HB_UInt          property );
-
-HB_Error  HB_GPOS_Clear_Features( HB_GPOSHeader*  gpos );
-
-
-HB_Error  HB_GPOS_Register_MM_Function( HB_GPOSHeader*  gpos,
-					HB_MMFunction   mmfunc,
-					void*            data );
-
-/* If `dvi' is TRUE, glyph contour points for anchor points and device
-   tables are ignored -- you will get device independent values.         */
-
-
-HB_Error  HB_GPOS_Apply_String( HB_Font           font,
-				HB_GPOSHeader*   gpos,
-				HB_UShort         load_flags,
-				HB_Buffer        buffer,
-				HB_Bool           dvi,
-				HB_Bool           r2l );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GPOS_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-gsub-private.h b/third_party/harfbuzz/src/harfbuzz-gsub-private.h
deleted file mode 100644
index dd5ffdf..0000000
--- a/third_party/harfbuzz/src/harfbuzz-gsub-private.h
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_GSUB_PRIVATE_H
-#define HARFBUZZ_GSUB_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-stream-private.h"
-#include "harfbuzz-gsub.h"
-
-HB_BEGIN_HEADER
-
-
-typedef union HB_GSUB_SubTable_  HB_GSUB_SubTable;
-
-/* LookupType 1 */
-
-struct  HB_SingleSubstFormat1_
-{
-  HB_Short  DeltaGlyphID;             /* constant added to get
-					 substitution glyph index */
-};
-
-typedef struct HB_SingleSubstFormat1_  HB_SingleSubstFormat1;
-
-
-struct  HB_SingleSubstFormat2_
-{
-  HB_UShort   GlyphCount;             /* number of glyph IDs in
-					 Substitute array              */
-  HB_UShort*  Substitute;             /* array of substitute glyph IDs */
-};
-
-typedef struct HB_SingleSubstFormat2_  HB_SingleSubstFormat2;
-
-
-struct  HB_SingleSubst_
-{
-  HB_UShort     SubstFormat;          /* 1 or 2         */
-  HB_Coverage  Coverage;             /* Coverage table */
-
-  union
-  {
-    HB_SingleSubstFormat1  ssf1;
-    HB_SingleSubstFormat2  ssf2;
-  } ssf;
-};
-
-typedef struct HB_SingleSubst_  HB_SingleSubst;
-
-
-/* LookupType 2 */
-
-struct  HB_Sequence_
-{
-  HB_UShort   GlyphCount;             /* number of glyph IDs in the
-					 Substitute array           */
-  HB_UShort*  Substitute;             /* string of glyph IDs to
-					 substitute                 */
-};
-
-typedef struct HB_Sequence_  HB_Sequence;
-
-
-struct  HB_MultipleSubst_
-{
-  HB_UShort      SubstFormat;         /* always 1                  */
-  HB_Coverage   Coverage;            /* Coverage table            */
-  HB_UShort      SequenceCount;       /* number of Sequence tables */
-  HB_Sequence*  Sequence;            /* array of Sequence tables  */
-};
-
-typedef struct HB_MultipleSubst_  HB_MultipleSubst;
-
-
-/* LookupType 3 */
-
-struct  HB_AlternateSet_
-{
-  HB_UShort   GlyphCount;             /* number of glyph IDs in the
-					 Alternate array              */
-  HB_UShort*  Alternate;              /* array of alternate glyph IDs */
-};
-
-typedef struct HB_AlternateSet_  HB_AlternateSet;
-
-
-struct  HB_AlternateSubst_
-{
-  HB_UShort          SubstFormat;     /* always 1                      */
-  HB_Coverage       Coverage;        /* Coverage table                */
-  HB_UShort          AlternateSetCount;
-				      /* number of AlternateSet tables */
-  HB_AlternateSet*  AlternateSet;    /* array of AlternateSet tables  */
-};
-
-typedef struct HB_AlternateSubst_  HB_AlternateSubst;
-
-
-/* LookupType 4 */
-
-struct  HB_Ligature_
-{
-  HB_UShort   LigGlyph;               /* glyphID of ligature
-					 to substitute                    */
-  HB_UShort   ComponentCount;         /* number of components in ligature */
-  HB_UShort*  Component;              /* array of component glyph IDs     */
-};
-
-typedef struct HB_Ligature_  HB_Ligature;
-
-
-struct  HB_LigatureSet_
-{
-  HB_UShort      LigatureCount;       /* number of Ligature tables */
-  HB_Ligature*  Ligature;            /* array of Ligature tables  */
-};
-
-typedef struct HB_LigatureSet_  HB_LigatureSet;
-
-
-struct  HB_LigatureSubst_
-{
-  HB_UShort         SubstFormat;      /* always 1                     */
-  HB_Coverage      Coverage;         /* Coverage table               */
-  HB_UShort         LigatureSetCount; /* number of LigatureSet tables */
-  HB_LigatureSet*  LigatureSet;      /* array of LigatureSet tables  */
-};
-
-typedef struct HB_LigatureSubst_  HB_LigatureSubst;
-
-
-/* needed by both lookup type 5 and 6 */
-
-struct  HB_SubstLookupRecord_
-{
-  HB_UShort  SequenceIndex;           /* index into current
-					 glyph sequence               */
-  HB_UShort  LookupListIndex;         /* Lookup to apply to that pos. */
-};
-
-typedef struct HB_SubstLookupRecord_  HB_SubstLookupRecord;
-
-
-/* LookupType 5 */
-
-struct  HB_SubRule_
-{
-  HB_UShort               GlyphCount; /* total number of input glyphs */
-  HB_UShort               SubstCount; /* number of SubstLookupRecord
-					 tables                       */
-  HB_UShort*              Input;      /* array of input glyph IDs     */
-  HB_SubstLookupRecord*  SubstLookupRecord;
-				      /* array of SubstLookupRecord
-					 tables                       */
-};
-
-typedef struct HB_SubRule_  HB_SubRule;
-
-
-struct  HB_SubRuleSet_
-{
-  HB_UShort     SubRuleCount;         /* number of SubRule tables */
-  HB_SubRule*  SubRule;              /* array of SubRule tables  */
-};
-
-typedef struct HB_SubRuleSet_  HB_SubRuleSet;
-
-
-struct  HB_ContextSubstFormat1_
-{
-  HB_Coverage     Coverage;          /* Coverage table              */
-  HB_UShort        SubRuleSetCount;   /* number of SubRuleSet tables */
-  HB_SubRuleSet*  SubRuleSet;        /* array of SubRuleSet tables  */
-};
-
-typedef struct HB_ContextSubstFormat1_  HB_ContextSubstFormat1;
-
-
-struct  HB_SubClassRule_
-{
-  HB_UShort               GlyphCount; /* total number of context classes */
-  HB_UShort               SubstCount; /* number of SubstLookupRecord
-					 tables                          */
-  HB_UShort*              Class;      /* array of classes                */
-  HB_SubstLookupRecord*  SubstLookupRecord;
-				      /* array of SubstLookupRecord
-					 tables                          */
-};
-
-typedef struct HB_SubClassRule_  HB_SubClassRule;
-
-
-struct  HB_SubClassSet_
-{
-  HB_UShort          SubClassRuleCount;
-				      /* number of SubClassRule tables */
-  HB_SubClassRule*  SubClassRule;    /* array of SubClassRule tables  */
-};
-
-typedef struct HB_SubClassSet_  HB_SubClassSet;
-
-
-/* The `MaxContextLength' field is not defined in the TTO specification
-   but simplifies the implementation of this format.  It holds the
-   maximal context length used in the context rules.                    */
-
-struct  HB_ContextSubstFormat2_
-{
-  HB_UShort            MaxContextLength;
-				      /* maximal context length       */
-  HB_Coverage         Coverage;      /* Coverage table               */
-  HB_ClassDefinition  ClassDef;      /* ClassDef table               */
-  HB_UShort            SubClassSetCount;
-				      /* number of SubClassSet tables */
-  HB_SubClassSet*     SubClassSet;   /* array of SubClassSet tables  */
-};
-
-typedef struct HB_ContextSubstFormat2_  HB_ContextSubstFormat2;
-
-
-struct  HB_ContextSubstFormat3_
-{
-  HB_UShort               GlyphCount; /* number of input glyphs        */
-  HB_UShort               SubstCount; /* number of SubstLookupRecords  */
-  HB_Coverage*           Coverage;   /* array of Coverage tables      */
-  HB_SubstLookupRecord*  SubstLookupRecord;
-				      /* array of substitution lookups */
-};
-
-typedef struct HB_ContextSubstFormat3_  HB_ContextSubstFormat3;
-
-
-struct  HB_ContextSubst_
-{
-  HB_UShort  SubstFormat;             /* 1, 2, or 3 */
-
-  union
-  {
-    HB_ContextSubstFormat1  csf1;
-    HB_ContextSubstFormat2  csf2;
-    HB_ContextSubstFormat3  csf3;
-  } csf;
-};
-
-typedef struct HB_ContextSubst_  HB_ContextSubst;
-
-
-/* LookupType 6 */
-
-struct  HB_ChainSubRule_
-{
-  HB_UShort               BacktrackGlyphCount;
-				      /* total number of backtrack glyphs */
-  HB_UShort*              Backtrack;  /* array of backtrack glyph IDs     */
-  HB_UShort               InputGlyphCount;
-				      /* total number of input glyphs     */
-  HB_UShort*              Input;      /* array of input glyph IDs         */
-  HB_UShort               LookaheadGlyphCount;
-				      /* total number of lookahead glyphs */
-  HB_UShort*              Lookahead;  /* array of lookahead glyph IDs     */
-  HB_UShort               SubstCount; /* number of SubstLookupRecords     */
-  HB_SubstLookupRecord*  SubstLookupRecord;
-				      /* array of SubstLookupRecords      */
-};
-
-typedef struct HB_ChainSubRule_  HB_ChainSubRule;
-
-
-struct  HB_ChainSubRuleSet_
-{
-  HB_UShort          ChainSubRuleCount;
-				      /* number of ChainSubRule tables */
-  HB_ChainSubRule*  ChainSubRule;    /* array of ChainSubRule tables  */
-};
-
-typedef struct HB_ChainSubRuleSet_  HB_ChainSubRuleSet;
-
-
-struct  HB_ChainContextSubstFormat1_
-{
-  HB_Coverage          Coverage;     /* Coverage table                   */
-  HB_UShort             ChainSubRuleSetCount;
-				      /* number of ChainSubRuleSet tables */
-  HB_ChainSubRuleSet*  ChainSubRuleSet;
-				      /* array of ChainSubRuleSet tables  */
-};
-
-typedef struct HB_ChainContextSubstFormat1_  HB_ChainContextSubstFormat1;
-
-
-struct  HB_ChainSubClassRule_
-{
-  HB_UShort               BacktrackGlyphCount;
-				      /* total number of backtrack
-					 classes                         */
-  HB_UShort*              Backtrack;  /* array of backtrack classes      */
-  HB_UShort               InputGlyphCount;
-				      /* total number of context classes */
-  HB_UShort*              Input;      /* array of context classes        */
-  HB_UShort               LookaheadGlyphCount;
-				      /* total number of lookahead
-					 classes                         */
-  HB_UShort*              Lookahead;  /* array of lookahead classes      */
-  HB_UShort               SubstCount; /* number of SubstLookupRecords    */
-  HB_SubstLookupRecord*  SubstLookupRecord;
-				      /* array of substitution lookups   */
-};
-
-typedef struct HB_ChainSubClassRule_  HB_ChainSubClassRule;
-
-
-struct  HB_ChainSubClassSet_
-{
-  HB_UShort               ChainSubClassRuleCount;
-				      /* number of ChainSubClassRule
-					 tables                      */
-  HB_ChainSubClassRule*  ChainSubClassRule;
-				      /* array of ChainSubClassRule
-					 tables                      */
-};
-
-typedef struct HB_ChainSubClassSet_  HB_ChainSubClassSet;
-
-
-/* The `MaxXXXLength' fields are not defined in the TTO specification
-   but simplifies the implementation of this format.  It holds the
-   maximal context length used in the specific context rules.         */
-
-struct  HB_ChainContextSubstFormat2_
-{
-  HB_Coverage           Coverage;    /* Coverage table             */
-
-  HB_UShort              MaxBacktrackLength;
-				      /* maximal backtrack length   */
-  HB_ClassDefinition    BacktrackClassDef;
-				      /* BacktrackClassDef table    */
-  HB_UShort              MaxInputLength;
-				      /* maximal input length       */
-  HB_ClassDefinition    InputClassDef;
-				      /* InputClassDef table        */
-  HB_UShort              MaxLookaheadLength;
-				      /* maximal lookahead length   */
-  HB_ClassDefinition    LookaheadClassDef;
-				      /* LookaheadClassDef table    */
-
-  HB_UShort              ChainSubClassSetCount;
-				      /* number of ChainSubClassSet
-					 tables                     */
-  HB_ChainSubClassSet*  ChainSubClassSet;
-				      /* array of ChainSubClassSet
-					 tables                     */
-};
-
-typedef struct HB_ChainContextSubstFormat2_  HB_ChainContextSubstFormat2;
-
-
-struct  HB_ChainContextSubstFormat3_
-{
-  HB_UShort               BacktrackGlyphCount;
-				      /* number of backtrack glyphs    */
-  HB_Coverage*           BacktrackCoverage;
-				      /* array of backtrack Coverage
-					 tables                        */
-  HB_UShort               InputGlyphCount;
-				      /* number of input glyphs        */
-  HB_Coverage*           InputCoverage;
-				      /* array of input coverage
-					 tables                        */
-  HB_UShort               LookaheadGlyphCount;
-				      /* number of lookahead glyphs    */
-  HB_Coverage*           LookaheadCoverage;
-				      /* array of lookahead coverage
-					 tables                        */
-  HB_UShort               SubstCount; /* number of SubstLookupRecords  */
-  HB_SubstLookupRecord*  SubstLookupRecord;
-				      /* array of substitution lookups */
-};
-
-typedef struct HB_ChainContextSubstFormat3_  HB_ChainContextSubstFormat3;
-
-
-struct  HB_ChainContextSubst_
-{
-  HB_UShort  SubstFormat;             /* 1, 2, or 3 */
-
-  union
-  {
-    HB_ChainContextSubstFormat1  ccsf1;
-    HB_ChainContextSubstFormat2  ccsf2;
-    HB_ChainContextSubstFormat3  ccsf3;
-  } ccsf;
-};
-
-typedef struct HB_ChainContextSubst_  HB_ChainContextSubst;
-
-
-#if 0
-/* LookupType 7 */
-struct HB_ExtensionSubst_
-{
-  HB_UShort      SubstFormat;         /* always 1 */
-  HB_UShort      LookuptType;         /* lookup-type of referenced subtable */
-  HB_GSUB_SubTable *subtable;         /* referenced subtable */
-};
-
-typedef struct HB_ExtensionSubst_  HB_ExtensionSubst;
-#endif
-
-
-/* LookupType 8 */
-struct HB_ReverseChainContextSubst_
-{
-  HB_UShort      SubstFormat;         /* always 1 */
-  HB_Coverage   Coverage;	        /* coverage table for input glyphs */
-  HB_UShort      BacktrackGlyphCount; /* number of backtrack glyphs      */
-  HB_Coverage*  BacktrackCoverage;   /* array of backtrack Coverage
-					 tables                          */
-  HB_UShort      LookaheadGlyphCount; /* number of lookahead glyphs      */
-  HB_Coverage*  LookaheadCoverage;   /* array of lookahead Coverage
-					 tables                          */
-  HB_UShort      GlyphCount;          /* number of Glyph IDs             */
-  HB_UShort*     Substitute;          /* array of substitute Glyph ID    */
-};
-
-typedef struct HB_ReverseChainContextSubst_  HB_ReverseChainContextSubst;
-
-
-union  HB_GSUB_SubTable_
-{
-  HB_SingleSubst              single;
-  HB_MultipleSubst            multiple;
-  HB_AlternateSubst           alternate;
-  HB_LigatureSubst            ligature;
-  HB_ContextSubst             context;
-  HB_ChainContextSubst        chain;
-  HB_ReverseChainContextSubst reverse;
-};
-
-
-
-
-HB_INTERNAL HB_Error
-_HB_GSUB_Load_SubTable( HB_GSUB_SubTable* st,
-				  HB_Stream     stream,
-				  HB_UShort     lookup_type );
-
-HB_INTERNAL void
-_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st,
-			      HB_UShort     lookup_type );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GSUB_PRIVATE_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-gsub.c b/third_party/harfbuzz/src/harfbuzz-gsub.c
deleted file mode 100644
index 21fec51..0000000
--- a/third_party/harfbuzz/src/harfbuzz-gsub.c
+++ /dev/null
@@ -1,4329 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- * Copyright (C) 2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-gsub-private.h"
-#include "harfbuzz-open-private.h"
-#include "harfbuzz-gdef-private.h"
-
-static HB_Error  GSUB_Do_Glyph_Lookup( HB_GSUBHeader*   gsub,
-				       HB_UShort         lookup_index,
-				       HB_Buffer        buffer,
-				       HB_UShort         context_length,
-				       int               nesting_level );
-
-
-
-/**********************
- * Auxiliary functions
- **********************/
-
-
-
-HB_Error  HB_Load_GSUB_Table( HB_Stream stream,
-			      HB_GSUBHeader** retptr,
-			      HB_GDEFHeader*  gdef,
-                              HB_Stream       gdefStream )
-{
-  HB_Error         error;
-  HB_UInt         cur_offset, new_offset, base_offset;
-
-  HB_GSUBHeader*  gsub;
-
-  if ( !retptr )
-    return ERR(HB_Err_Invalid_Argument);
-
-  if ( GOTO_Table( TTAG_GSUB ) )
-    return error;
-
-  base_offset = FILE_Pos();
-
-  if ( ALLOC ( gsub, sizeof( *gsub ) ) ) 
-      return error;
-  
-
-  /* skip version */
-
-  if ( FILE_Seek( base_offset + 4L ) ||
-       ACCESS_Frame( 2L ) )
-    goto Fail4;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_ScriptList( &gsub->ScriptList,
-				  stream ) ) != HB_Err_Ok )
-    goto Fail4;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_FeatureList( &gsub->FeatureList,
-				   stream ) ) != HB_Err_Ok )
-    goto Fail3;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_LookupList( &gsub->LookupList,
-				  stream, HB_Type_GSUB ) ) != HB_Err_Ok )
-    goto Fail2;
-
-  gsub->gdef = gdef;      /* can be NULL */
-
-  if ( ( error =  _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, gdefStream,
-								     gsub->LookupList.Lookup,
-								     gsub->LookupList.LookupCount ) ) )
-    goto Fail1;
-
-  *retptr = gsub;
-
-  return HB_Err_Ok;
-
-Fail1:
-  _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB );
-
-Fail2:
-  _HB_OPEN_Free_FeatureList( &gsub->FeatureList );
-
-Fail3:
-  _HB_OPEN_Free_ScriptList( &gsub->ScriptList );
-
-Fail4:
-  FREE ( gsub );
-
-
-  return error;
-}
-
-
-HB_Error   HB_Done_GSUB_Table( HB_GSUBHeader* gsub )
-{
-  _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB );
-  _HB_OPEN_Free_FeatureList( &gsub->FeatureList );
-  _HB_OPEN_Free_ScriptList( &gsub->ScriptList );
-
-  FREE( gsub );
-
-  return HB_Err_Ok;
-}
-
-/*****************************
- * SubTable related functions
- *****************************/
-
-
-/* LookupType 1 */
-
-/* SingleSubstFormat1 */
-/* SingleSubstFormat2 */
-
-static HB_Error  Load_SingleSubst( HB_GSUB_SubTable* st,
-				   HB_Stream         stream )
-{
-  HB_Error error;
-  HB_SingleSubst*  ss = &st->single;
-
-  HB_UShort n, count;
-  HB_UInt cur_offset, new_offset, base_offset;
-
-  HB_UShort*  s;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  ss->SubstFormat = GET_UShort();
-  new_offset      = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &ss->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  switch ( ss->SubstFormat )
-  {
-  case 1:
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail2;
-
-    ss->ssf.ssf1.DeltaGlyphID = GET_UShort();
-
-    FORGET_Frame();
-
-    break;
-
-  case 2:
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail2;
-
-    count = ss->ssf.ssf2.GlyphCount = GET_UShort();
-
-    FORGET_Frame();
-
-    ss->ssf.ssf2.Substitute = NULL;
-
-    if ( ALLOC_ARRAY( ss->ssf.ssf2.Substitute, count, HB_UShort ) )
-      goto Fail2;
-
-    s = ss->ssf.ssf2.Substitute;
-
-    if ( ACCESS_Frame( count * 2L ) )
-      goto Fail1;
-
-    for ( n = 0; n < count; n++ )
-      s[n] = GET_UShort();
-
-    FORGET_Frame();
-
-    break;
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( s );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &ss->Coverage );
-  return error;
-}
-
-
-static void  Free_SingleSubst( HB_GSUB_SubTable* st )
-{
-  HB_SingleSubst*  ss = &st->single;
-
-  switch ( ss->SubstFormat )
-  {
-  case 1:
-    break;
-
-  case 2:
-    FREE( ss->ssf.ssf2.Substitute );
-    break;
-
-  default:
-    break;
-  }
-
-  _HB_OPEN_Free_Coverage( &ss->Coverage );
-}
-
-
-static HB_Error  Lookup_SingleSubst( HB_GSUBHeader*   gsub,
-				     HB_GSUB_SubTable* st,
-				     HB_Buffer        buffer,
-				     HB_UShort         flags,
-				     HB_UShort         context_length,
-				     int               nesting_level )
-{
-  HB_UShort index, value, property;
-  HB_Error  error;
-  HB_SingleSubst*  ss = &st->single;
-  HB_GDEFHeader*   gdef = gsub->gdef;
-
-  HB_UNUSED(nesting_level);
-
-  if ( context_length != 0xFFFF && context_length < 1 )
-    return HB_Err_Not_Covered;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &ss->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  switch ( ss->SubstFormat )
-  {
-  case 1:
-    value = ( IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF;
-    if ( REPLACE_Glyph( buffer, value, nesting_level ) )
-      return error;
-    break;
-
-  case 2:
-    if ( index >= ss->ssf.ssf2.GlyphCount )
-      return ERR(HB_Err_Invalid_SubTable);
-    value = ss->ssf.ssf2.Substitute[index];
-    if ( REPLACE_Glyph( buffer, value, nesting_level ) )
-      return error;
-    break;
-
-  default:
-    return ERR(HB_Err_Invalid_SubTable);
-  }
-
-  if ( gdef && gdef->NewGlyphClasses )
-  {
-    /* we inherit the old glyph class to the substituted glyph */
-
-    error = _HB_GDEF_Add_Glyph_Property( gdef, value, property );
-    if ( error && error != HB_Err_Not_Covered )
-      return error;
-  }
-
-  return HB_Err_Ok;
-}
-
-
-/* LookupType 2 */
-
-/* Sequence */
-
-static HB_Error  Load_Sequence( HB_Sequence*  s,
-				HB_Stream      stream )
-{
-  HB_Error error;
-
-  HB_UShort n, count;
-  HB_UShort*  sub;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = s->GlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  s->Substitute = NULL;
-
-  if ( count )
-  {
-    if ( ALLOC_ARRAY( s->Substitute, count, HB_UShort ) )
-      return error;
-
-    sub = s->Substitute;
-
-    if ( ACCESS_Frame( count * 2L ) )
-    {
-      FREE( sub );
-      return error;
-    }
-
-    for ( n = 0; n < count; n++ )
-      sub[n] = GET_UShort();
-
-    FORGET_Frame();
-  }
-
-  return HB_Err_Ok;
-}
-
-
-static void  Free_Sequence( HB_Sequence*  s )
-{
-  FREE( s->Substitute );
-}
-
-
-/* MultipleSubstFormat1 */
-
-static HB_Error  Load_MultipleSubst( HB_GSUB_SubTable* st,
-				     HB_Stream         stream )
-{
-  HB_Error error;
-  HB_MultipleSubst*  ms = &st->multiple;
-
-  HB_UShort      n = 0, m, count;
-  HB_UInt       cur_offset, new_offset, base_offset;
-
-  HB_Sequence*  s;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  ms->SubstFormat = GET_UShort();             /* should be 1 */
-  new_offset      = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &ms->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = ms->SequenceCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ms->Sequence = NULL;
-
-  if ( ALLOC_ARRAY( ms->Sequence, count, HB_Sequence ) )
-    goto Fail2;
-
-  s = ms->Sequence;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_Sequence( &s[n], stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_Sequence( &s[m] );
-
-  FREE( s );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &ms->Coverage );
-  return error;
-}
-
-
-static void  Free_MultipleSubst( HB_GSUB_SubTable* st )
-{
-  HB_UShort      n, count;
-  HB_MultipleSubst*  ms = &st->multiple;
-
-  HB_Sequence*  s;
-
-
-  if ( ms->Sequence )
-  {
-    count = ms->SequenceCount;
-    s     = ms->Sequence;
-
-    for ( n = 0; n < count; n++ )
-      Free_Sequence( &s[n] );
-
-    FREE( s );
-  }
-
-  _HB_OPEN_Free_Coverage( &ms->Coverage );
-}
-
-
-static HB_Error  Lookup_MultipleSubst( HB_GSUBHeader*    gsub,
-				       HB_GSUB_SubTable* st,
-				       HB_Buffer         buffer,
-				       HB_UShort          flags,
-				       HB_UShort          context_length,
-				       int                nesting_level )
-{
-  HB_Error  error;
-  HB_UShort index, property, n, count;
-  HB_UShort*s;
-  HB_MultipleSubst*  ms = &st->multiple;
-  HB_GDEFHeader*     gdef = gsub->gdef;
-
-  HB_UNUSED(nesting_level);
-
-  if ( context_length != 0xFFFF && context_length < 1 )
-    return HB_Err_Not_Covered;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &ms->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  if ( index >= ms->SequenceCount )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  count = ms->Sequence[index].GlyphCount;
-  s     = ms->Sequence[index].Substitute;
-
-  if ( ADD_String( buffer, 1, count, s, 0xFFFF, 0xFFFF ) )
-    return error;
-
-  if ( gdef && gdef->NewGlyphClasses )
-  {
-    /* this is a guess only ... */
-
-    if ( property == HB_GDEF_LIGATURE )
-      property = HB_GDEF_BASE_GLYPH;
-
-    for ( n = 0; n < count; n++ )
-    {
-      error = _HB_GDEF_Add_Glyph_Property( gdef, s[n], property );
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-    }
-  }
-
-  return HB_Err_Ok;
-}
-
-
-/* LookupType 3 */
-
-/* AlternateSet */
-
-static HB_Error  Load_AlternateSet( HB_AlternateSet*  as,
-				    HB_Stream          stream )
-{
-  HB_Error error;
-
-  HB_UShort n, count;
-  HB_UShort*  a;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = as->GlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  as->Alternate = NULL;
-
-  if ( ALLOC_ARRAY( as->Alternate, count, HB_UShort ) )
-    return error;
-
-  a = as->Alternate;
-
-  if ( ACCESS_Frame( count * 2L ) )
-  {
-    FREE( a );
-    return error;
-  }
-
-  for ( n = 0; n < count; n++ )
-    a[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-}
-
-
-static void  Free_AlternateSet( HB_AlternateSet*  as )
-{
-  FREE( as->Alternate );
-}
-
-
-/* AlternateSubstFormat1 */
-
-static HB_Error  Load_AlternateSubst( HB_GSUB_SubTable* st,
-				      HB_Stream         stream )
-{
-  HB_Error error;
-  HB_AlternateSubst* as = &st->alternate;
-
-  HB_UShort          n = 0, m, count;
-  HB_UInt           cur_offset, new_offset, base_offset;
-
-  HB_AlternateSet*  aset;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  as->SubstFormat = GET_UShort();             /* should be 1 */
-  new_offset      = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &as->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = as->AlternateSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  as->AlternateSet = NULL;
-
-  if ( ALLOC_ARRAY( as->AlternateSet, count, HB_AlternateSet ) )
-    goto Fail2;
-
-  aset = as->AlternateSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_AlternateSet( &aset[n], stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_AlternateSet( &aset[m] );
-
-  FREE( aset );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &as->Coverage );
-  return error;
-}
-
-
-static void  Free_AlternateSubst( HB_GSUB_SubTable* st )
-{
-  HB_UShort          n, count;
-  HB_AlternateSubst* as = &st->alternate;
-
-  HB_AlternateSet*  aset;
-
-
-  if ( as->AlternateSet )
-  {
-    count = as->AlternateSetCount;
-    aset  = as->AlternateSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_AlternateSet( &aset[n] );
-
-    FREE( aset );
-  }
-
-  _HB_OPEN_Free_Coverage( &as->Coverage );
-}
-
-
-static HB_Error  Lookup_AlternateSubst( HB_GSUBHeader*    gsub,
-					HB_GSUB_SubTable* st,
-					HB_Buffer         buffer,
-					HB_UShort          flags,
-					HB_UShort          context_length,
-					int                nesting_level )
-{
-  HB_Error          error;
-  HB_UShort         index, value, alt_index, property;
-  HB_AlternateSubst* as = &st->alternate;
-  HB_GDEFHeader*     gdef = gsub->gdef;
-  HB_AlternateSet  aset;
-
-  HB_UNUSED(nesting_level);
-
-  if ( context_length != 0xFFFF && context_length < 1 )
-    return HB_Err_Not_Covered;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &as->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  aset = as->AlternateSet[index];
-
-  /* we use a user-defined callback function to get the alternate index */
-
-  if ( gsub->altfunc )
-    alt_index = (gsub->altfunc)( buffer->out_pos, IN_CURGLYPH(),
-				 aset.GlyphCount, aset.Alternate,
-				 gsub->data );
-  else
-    alt_index = 0;
-
-  value = aset.Alternate[alt_index];
-  if ( REPLACE_Glyph( buffer, value, nesting_level ) )
-    return error;
-
-  if ( gdef && gdef->NewGlyphClasses )
-  {
-    /* we inherit the old glyph class to the substituted glyph */
-
-    error = _HB_GDEF_Add_Glyph_Property( gdef, value, property );
-    if ( error && error != HB_Err_Not_Covered )
-      return error;
-  }
-
-  return HB_Err_Ok;
-}
-
-
-/* LookupType 4 */
-
-/* Ligature */
-
-static HB_Error  Load_Ligature( HB_Ligature*  l,
-				HB_Stream      stream )
-{
-  HB_Error error;
-
-  HB_UShort n, count;
-  HB_UShort*  c;
-
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  l->LigGlyph       = GET_UShort();
-  l->ComponentCount = GET_UShort();
-
-  FORGET_Frame();
-
-  l->Component = NULL;
-
-  count = l->ComponentCount - 1;      /* only ComponentCount - 1 elements */
-
-  if ( ALLOC_ARRAY( l->Component, count, HB_UShort ) )
-    return error;
-
-  c = l->Component;
-
-  if ( ACCESS_Frame( count * 2L ) )
-  {
-    FREE( c );
-    return error;
-  }
-
-  for ( n = 0; n < count; n++ )
-    c[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-}
-
-
-static void  Free_Ligature( HB_Ligature*  l )
-{
-  FREE( l->Component );
-}
-
-
-/* LigatureSet */
-
-static HB_Error  Load_LigatureSet( HB_LigatureSet*  ls,
-				   HB_Stream         stream )
-{
-  HB_Error error;
-
-  HB_UShort      n = 0, m, count;
-  HB_UInt       cur_offset, new_offset, base_offset;
-
-  HB_Ligature*  l;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = ls->LigatureCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ls->Ligature = NULL;
-
-  if ( ALLOC_ARRAY( ls->Ligature, count, HB_Ligature ) )
-    return error;
-
-  l = ls->Ligature;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_Ligature( &l[n], stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_Ligature( &l[m] );
-
-  FREE( l );
-  return error;
-}
-
-
-static void  Free_LigatureSet( HB_LigatureSet*  ls )
-{
-  HB_UShort      n, count;
-
-  HB_Ligature*  l;
-
-
-  if ( ls->Ligature )
-  {
-    count = ls->LigatureCount;
-    l     = ls->Ligature;
-
-    for ( n = 0; n < count; n++ )
-      Free_Ligature( &l[n] );
-
-    FREE( l );
-  }
-}
-
-
-/* LigatureSubstFormat1 */
-
-static HB_Error  Load_LigatureSubst( HB_GSUB_SubTable* st,
-				     HB_Stream         stream )
-{
-  HB_Error error;
-  HB_LigatureSubst*  ls = &st->ligature;
-
-  HB_UShort         n = 0, m, count;
-  HB_UInt          cur_offset, new_offset, base_offset;
-
-  HB_LigatureSet*  lset;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  ls->SubstFormat = GET_UShort();             /* should be 1 */
-  new_offset      = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &ls->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = ls->LigatureSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ls->LigatureSet = NULL;
-
-  if ( ALLOC_ARRAY( ls->LigatureSet, count, HB_LigatureSet ) )
-    goto Fail2;
-
-  lset = ls->LigatureSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_LigatureSet( &lset[n], stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_LigatureSet( &lset[m] );
-
-  FREE( lset );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &ls->Coverage );
-  return error;
-}
-
-
-static void  Free_LigatureSubst( HB_GSUB_SubTable* st )
-{
-  HB_UShort         n, count;
-  HB_LigatureSubst*  ls = &st->ligature;
-
-  HB_LigatureSet*  lset;
-
-
-  if ( ls->LigatureSet )
-  {
-    count = ls->LigatureSetCount;
-    lset  = ls->LigatureSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_LigatureSet( &lset[n] );
-
-    FREE( lset );
-  }
-
-  _HB_OPEN_Free_Coverage( &ls->Coverage );
-}
-
-
-static HB_Error  Lookup_LigatureSubst( HB_GSUBHeader*    gsub,
-				       HB_GSUB_SubTable* st,
-				       HB_Buffer         buffer,
-				       HB_UShort          flags,
-				       HB_UShort          context_length,
-				       int                nesting_level )
-{
-  HB_UShort      index, property;
-  HB_Error       error;
-  HB_UShort      numlig, i, j, is_mark, first_is_mark = FALSE;
-  HB_UShort*     c;
-  HB_LigatureSubst*  ls = &st->ligature;
-  HB_GDEFHeader*     gdef = gsub->gdef;
-
-  HB_Ligature*  lig;
-
-  HB_UNUSED(nesting_level);
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  if ( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
-    first_is_mark = TRUE;
-
-  error = _HB_OPEN_Coverage_Index( &ls->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  if ( index >= ls->LigatureSetCount )
-     return ERR(HB_Err_Invalid_SubTable);
-
-  lig = ls->LigatureSet[index].Ligature;
-
-  for ( numlig = ls->LigatureSet[index].LigatureCount;
-	numlig;
-	numlig--, lig++ )
-  {
-    if ( buffer->in_pos + lig->ComponentCount > buffer->in_length )
-      goto next_ligature;               /* Not enough glyphs in input */
-
-    c    = lig->Component;
-
-    is_mark = first_is_mark;
-
-    if ( context_length != 0xFFFF && context_length < lig->ComponentCount )
-      break;
-
-    for ( i = 1, j = buffer->in_pos + 1; i < lig->ComponentCount; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + lig->ComponentCount - i == (HB_Int)buffer->in_length )
-	  goto next_ligature;
-	j++;
-      }
-
-      if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )
-	is_mark = FALSE;
-
-      if ( IN_GLYPH( j ) != c[i - 1] )
-	goto next_ligature;
-    }
-
-    if ( gdef && gdef->NewGlyphClasses )
-    {
-      /* this is just a guess ... */
-
-      error = _HB_GDEF_Add_Glyph_Property( gdef, lig->LigGlyph,
-				  is_mark ? HB_GDEF_MARK : HB_GDEF_LIGATURE );
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-    }
-
-    if ( j == buffer->in_pos + i ) /* No input glyphs skipped */
-    {
-      /* We don't use a new ligature ID if there are no skipped
-	 glyphs and the ligature already has an ID.             */
-
-      if ( IN_LIGID( buffer->in_pos ) )
-      {
-	if ( ADD_String( buffer, i, 1, &lig->LigGlyph,
-			0xFFFF, 0xFFFF ) )
-	  return error;
-      }
-      else
-      {
-	HB_UShort ligID = _hb_buffer_allocate_ligid( buffer );
-	if ( ADD_String( buffer, i, 1, &lig->LigGlyph,
-			0xFFFF, ligID ) )
-	  return error;
-      }
-    }
-    else
-    {
-      HB_UShort ligID = _hb_buffer_allocate_ligid( buffer );
-      if ( ADD_Glyph( buffer, lig->LigGlyph, 0xFFFF, ligID ) )
-	return error;
-
-      /* Now we must do a second loop to copy the skipped glyphs to
-	 `out' and assign component values to it.  We start with the
-	 glyph after the first component.  Glyphs between component
-	 i and i+1 belong to component i.  Together with the ligID
-	 value it is later possible to check whether a specific
-	 component value really belongs to a given ligature.         */
-
-      for ( i = 0; i < lig->ComponentCount - 1; i++ )
-      {
-	while ( CHECK_Property( gdef, IN_CURITEM(),
-				flags, &property ) )
-	  if ( ADD_Glyph( buffer, IN_CURGLYPH(), i, ligID ) )
-	    return error;
-
-	(buffer->in_pos)++;
-      }
-    }
-
-    return HB_Err_Ok;
-
-  next_ligature:
-    ;
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-/* Do the actual substitution for a context substitution (either format
-   5 or 6).  This is only called after we've determined that the input
-   matches the subrule.                                                 */
-
-static HB_Error  Do_ContextSubst( HB_GSUBHeader*        gsub,
-				  HB_UShort              GlyphCount,
-				  HB_UShort              SubstCount,
-				  HB_SubstLookupRecord* subst,
-				  HB_Buffer             buffer,
-				  int                    nesting_level )
-{
-  HB_Error  error;
-  HB_UInt   i, old_pos;
-
-
-  i = 0;
-
-  while ( i < GlyphCount )
-  {
-    if ( SubstCount && i == subst->SequenceIndex )
-    {
-      old_pos = buffer->in_pos;
-
-      /* Do a substitution */
-
-      error = GSUB_Do_Glyph_Lookup( gsub, subst->LookupListIndex, buffer,
-				    GlyphCount, nesting_level );
-
-      subst++;
-      SubstCount--;
-      i += buffer->in_pos - old_pos;
-
-      if ( error == HB_Err_Not_Covered )
-      {
-	if ( COPY_Glyph( buffer ) )
-	  return error;
-	i++;
-      }
-      else if ( error )
-	return error;
-    }
-    else
-    {
-      /* No substitution for this index */
-
-      if ( COPY_Glyph( buffer ) )
-	return error;
-      i++;
-    }
-  }
-
-  return HB_Err_Ok;
-}
-
-
-/* LookupType 5 */
-
-/* SubRule */
-
-static HB_Error  Load_SubRule( HB_SubRule*  sr,
-			       HB_Stream     stream )
-{
-  HB_Error error;
-
-  HB_UShort               n, count;
-  HB_UShort*              i;
-
-  HB_SubstLookupRecord*  slr;
-
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  sr->GlyphCount = GET_UShort();
-  sr->SubstCount = GET_UShort();
-
-  FORGET_Frame();
-
-  sr->Input = NULL;
-
-  count = sr->GlyphCount - 1;         /* only GlyphCount - 1 elements */
-
-  if ( ALLOC_ARRAY( sr->Input, count, HB_UShort ) )
-    return error;
-
-  i = sr->Input;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail2;
-
-  for ( n = 0; n < count; n++ )
-    i[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  sr->SubstLookupRecord = NULL;
-
-  count = sr->SubstCount;
-
-  if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, HB_SubstLookupRecord ) )
-    goto Fail2;
-
-  slr = sr->SubstLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    slr[n].SequenceIndex   = GET_UShort();
-    slr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( slr );
-
-Fail2:
-  FREE( i );
-  return error;
-}
-
-
-static void  Free_SubRule( HB_SubRule*  sr )
-{
-  FREE( sr->SubstLookupRecord );
-  FREE( sr->Input );
-}
-
-
-/* SubRuleSet */
-
-static HB_Error  Load_SubRuleSet( HB_SubRuleSet*  srs,
-				  HB_Stream        stream )
-{
-  HB_Error error;
-
-  HB_UShort     n = 0, m, count;
-  HB_UInt      cur_offset, new_offset, base_offset;
-
-  HB_SubRule*  sr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = srs->SubRuleCount = GET_UShort();
-
-  FORGET_Frame();
-
-  srs->SubRule = NULL;
-
-  if ( ALLOC_ARRAY( srs->SubRule, count, HB_SubRule ) )
-    return error;
-
-  sr = srs->SubRule;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_SubRule( &sr[n], stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_SubRule( &sr[m] );
-
-  FREE( sr );
-  return error;
-}
-
-
-static void  Free_SubRuleSet( HB_SubRuleSet*  srs )
-{
-  HB_UShort     n, count;
-
-  HB_SubRule*  sr;
-
-
-  if ( srs->SubRule )
-  {
-    count = srs->SubRuleCount;
-    sr    = srs->SubRule;
-
-    for ( n = 0; n < count; n++ )
-      Free_SubRule( &sr[n] );
-
-    FREE( sr );
-  }
-}
-
-
-/* ContextSubstFormat1 */
-
-static HB_Error  Load_ContextSubst1( HB_ContextSubstFormat1*  csf1,
-				     HB_Stream                 stream )
-{
-  HB_Error error;
-
-  HB_UShort        n = 0, m, count;
-  HB_UInt         cur_offset, new_offset, base_offset;
-
-  HB_SubRuleSet*  srs;
-
-
-  base_offset = FILE_Pos() - 2L;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &csf1->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = csf1->SubRuleSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  csf1->SubRuleSet = NULL;
-
-  if ( ALLOC_ARRAY( csf1->SubRuleSet, count, HB_SubRuleSet ) )
-    goto Fail2;
-
-  srs = csf1->SubRuleSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_SubRuleSet( &srs[n], stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_SubRuleSet( &srs[m] );
-
-  FREE( srs );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &csf1->Coverage );
-  return error;
-}
-
-
-static void  Free_ContextSubst1( HB_ContextSubstFormat1* csf1 )
-{
-  HB_UShort        n, count;
-
-  HB_SubRuleSet*  srs;
-
-
-  if ( csf1->SubRuleSet )
-  {
-    count = csf1->SubRuleSetCount;
-    srs   = csf1->SubRuleSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_SubRuleSet( &srs[n] );
-
-    FREE( srs );
-  }
-
-  _HB_OPEN_Free_Coverage( &csf1->Coverage );
-}
-
-
-/* SubClassRule */
-
-static HB_Error  Load_SubClassRule( HB_ContextSubstFormat2*  csf2,
-				    HB_SubClassRule*         scr,
-				    HB_Stream                 stream )
-{
-  HB_Error error;
-
-  HB_UShort               n, count;
-
-  HB_UShort*              c;
-  HB_SubstLookupRecord*  slr;
-
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  scr->GlyphCount = GET_UShort();
-  scr->SubstCount = GET_UShort();
-
-  if ( scr->GlyphCount > csf2->MaxContextLength )
-    csf2->MaxContextLength = scr->GlyphCount;
-
-  FORGET_Frame();
-
-  scr->Class = NULL;
-
-  count = scr->GlyphCount - 1;        /* only GlyphCount - 1 elements */
-
-  if ( ALLOC_ARRAY( scr->Class, count, HB_UShort ) )
-    return error;
-
-  c = scr->Class;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail2;
-
-  for ( n = 0; n < count; n++ )
-    c[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  scr->SubstLookupRecord = NULL;
-
-  count = scr->SubstCount;
-
-  if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, HB_SubstLookupRecord ) )
-    goto Fail2;
-
-  slr = scr->SubstLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    slr[n].SequenceIndex   = GET_UShort();
-    slr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( slr );
-
-Fail2:
-  FREE( c );
-  return error;
-}
-
-
-static void  Free_SubClassRule( HB_SubClassRule*  scr )
-{
-  FREE( scr->SubstLookupRecord );
-  FREE( scr->Class );
-}
-
-
-/* SubClassSet */
-
-static HB_Error  Load_SubClassSet( HB_ContextSubstFormat2*  csf2,
-				   HB_SubClassSet*          scs,
-				   HB_Stream                 stream )
-{
-  HB_Error error;
-
-  HB_UShort          n = 0, m, count;
-  HB_UInt           cur_offset, new_offset, base_offset;
-
-  HB_SubClassRule*  scr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = scs->SubClassRuleCount = GET_UShort();
-
-  FORGET_Frame();
-
-  scs->SubClassRule = NULL;
-
-  if ( ALLOC_ARRAY( scs->SubClassRule, count, HB_SubClassRule ) )
-    return error;
-
-  scr = scs->SubClassRule;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_SubClassRule( csf2, &scr[n],
-				      stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_SubClassRule( &scr[m] );
-
-  FREE( scr );
-  return error;
-}
-
-
-static void  Free_SubClassSet( HB_SubClassSet*  scs )
-{
-  HB_UShort          n, count;
-
-  HB_SubClassRule*  scr;
-
-
-  if ( scs->SubClassRule )
-  {
-    count = scs->SubClassRuleCount;
-    scr   = scs->SubClassRule;
-
-    for ( n = 0; n < count; n++ )
-      Free_SubClassRule( &scr[n] );
-
-    FREE( scr );
-  }
-}
-
-
-/* ContextSubstFormat2 */
-
-static HB_Error  Load_ContextSubst2( HB_ContextSubstFormat2*  csf2,
-				     HB_Stream                 stream )
-{
-  HB_Error error;
-
-  HB_UShort         n = 0, m, count;
-  HB_UInt          cur_offset, new_offset, base_offset;
-
-  HB_SubClassSet*  scs;
-
-
-  base_offset = FILE_Pos() - 2;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &csf2->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 4L ) )
-    goto Fail3;
-
-  new_offset = GET_UShort() + base_offset;
-
-  /* `SubClassSetCount' is the upper limit for class values, thus we
-     read it now to make an additional safety check.                 */
-
-  count = csf2->SubClassSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_ClassDefinition( &csf2->ClassDef, count,
-				       stream ) ) != HB_Err_Ok )
-    goto Fail3;
-  (void)FILE_Seek( cur_offset );
-
-  csf2->SubClassSet      = NULL;
-  csf2->MaxContextLength = 0;
-
-  if ( ALLOC_ARRAY( csf2->SubClassSet, count, HB_SubClassSet ) )
-    goto Fail2;
-
-  scs = csf2->SubClassSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    if ( new_offset != base_offset )      /* not a NULL offset */
-    {
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = Load_SubClassSet( csf2, &scs[n],
-				       stream ) ) != HB_Err_Ok )
-	goto Fail1;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-    {
-      /* we create a SubClassSet table with no entries */
-
-      csf2->SubClassSet[n].SubClassRuleCount = 0;
-      csf2->SubClassSet[n].SubClassRule      = NULL;
-    }
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_SubClassSet( &scs[m] );
-
-  FREE( scs );
-
-Fail2:
-  _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef );
-
-Fail3:
-  _HB_OPEN_Free_Coverage( &csf2->Coverage );
-  return error;
-}
-
-
-static void  Free_ContextSubst2( HB_ContextSubstFormat2*  csf2 )
-{
-  HB_UShort         n, count;
-
-  HB_SubClassSet*  scs;
-
-
-  if ( csf2->SubClassSet )
-  {
-    count = csf2->SubClassSetCount;
-    scs   = csf2->SubClassSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_SubClassSet( &scs[n] );
-
-    FREE( scs );
-  }
-
-  _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef );
-  _HB_OPEN_Free_Coverage( &csf2->Coverage );
-}
-
-
-/* ContextSubstFormat3 */
-
-static HB_Error  Load_ContextSubst3( HB_ContextSubstFormat3*  csf3,
-				     HB_Stream                 stream )
-{
-  HB_Error error;
-
-  HB_UShort               n = 0, m, count;
-  HB_UInt                cur_offset, new_offset, base_offset;
-
-  HB_Coverage*           c;
-  HB_SubstLookupRecord*  slr;
-
-
-  base_offset = FILE_Pos() - 2L;
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  csf3->GlyphCount = GET_UShort();
-  csf3->SubstCount = GET_UShort();
-
-  FORGET_Frame();
-
-  csf3->Coverage = NULL;
-
-  count = csf3->GlyphCount;
-
-  if ( ALLOC_ARRAY( csf3->Coverage, count, HB_Coverage ) )
-    return error;
-
-  c = csf3->Coverage;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail2;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != HB_Err_Ok )
-      goto Fail2;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  csf3->SubstLookupRecord = NULL;
-
-  count = csf3->SubstCount;
-
-  if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count,
-		    HB_SubstLookupRecord ) )
-    goto Fail2;
-
-  slr = csf3->SubstLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    slr[n].SequenceIndex   = GET_UShort();
-    slr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( slr );
-
-Fail2:
-  for ( m = 0; m < n; m++ )
-    _HB_OPEN_Free_Coverage( &c[m] );
-
-  FREE( c );
-  return error;
-}
-
-
-static void  Free_ContextSubst3( HB_ContextSubstFormat3*  csf3 )
-{
-  HB_UShort      n, count;
-
-  HB_Coverage*  c;
-
-
-  FREE( csf3->SubstLookupRecord );
-
-  if ( csf3->Coverage )
-  {
-    count = csf3->GlyphCount;
-    c     = csf3->Coverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-}
-
-
-/* ContextSubst */
-
-static HB_Error  Load_ContextSubst( HB_GSUB_SubTable* st,
-				    HB_Stream         stream )
-{
-  HB_Error error;
-  HB_ContextSubst*  cs = &st->context;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  cs->SubstFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  switch ( cs->SubstFormat )
-  {
-  case 1:  return Load_ContextSubst1( &cs->csf.csf1, stream );
-  case 2:  return Load_ContextSubst2( &cs->csf.csf2, stream );
-  case 3:  return Load_ContextSubst3( &cs->csf.csf3, stream );
-  default: return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-static void  Free_ContextSubst( HB_GSUB_SubTable* st )
-{
-  HB_ContextSubst*  cs = &st->context;
-
-  switch ( cs->SubstFormat )
-  {
-  case 1:  Free_ContextSubst1( &cs->csf.csf1 ); break;
-  case 2:  Free_ContextSubst2( &cs->csf.csf2 ); break;
-  case 3:  Free_ContextSubst3( &cs->csf.csf3 ); break;
-  default:						break;
-  }
-}
-
-
-static HB_Error  Lookup_ContextSubst1( HB_GSUBHeader*          gsub,
-				       HB_ContextSubstFormat1* csf1,
-				       HB_Buffer               buffer,
-				       HB_UShort                flags,
-				       HB_UShort                context_length,
-				       int                      nesting_level )
-{
-  HB_UShort        index, property;
-  HB_UShort        i, j, k, numsr;
-  HB_Error         error;
-
-  HB_SubRule*     sr;
-  HB_GDEFHeader*  gdef;
-
-
-  gdef = gsub->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &csf1->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  sr    = csf1->SubRuleSet[index].SubRule;
-  numsr = csf1->SubRuleSet[index].SubRuleCount;
-
-  for ( k = 0; k < numsr; k++ )
-  {
-    if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount )
-      goto next_subrule;
-
-    if ( buffer->in_pos + sr[k].GlyphCount > buffer->in_length )
-      goto next_subrule;                        /* context is too long */
-
-    for ( i = 1, j = buffer->in_pos + 1; i < sr[k].GlyphCount; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + sr[k].GlyphCount - i == (HB_Int)buffer->in_length )
-	  goto next_subrule;
-	j++;
-      }
-
-      if ( IN_GLYPH( j ) != sr[k].Input[i - 1] )
-	goto next_subrule;
-    }
-
-    return Do_ContextSubst( gsub, sr[k].GlyphCount,
-			    sr[k].SubstCount, sr[k].SubstLookupRecord,
-			    buffer,
-			    nesting_level );
-  next_subrule:
-    ;
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-static HB_Error  Lookup_ContextSubst2( HB_GSUBHeader*          gsub,
-				       HB_ContextSubstFormat2* csf2,
-				       HB_Buffer               buffer,
-				       HB_UShort                flags,
-				       HB_UShort                context_length,
-				       int                      nesting_level )
-{
-  HB_UShort          index, property;
-  HB_Error           error;
-  HB_UShort          i, j, k, known_classes;
-
-  HB_UShort*         classes;
-  HB_UShort*         cl;
-
-  HB_SubClassSet*   scs;
-  HB_SubClassRule*  sr;
-  HB_GDEFHeader*    gdef;
-
-
-  gdef = gsub->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  /* Note: The coverage table in format 2 doesn't give an index into
-	   anything.  It just lets us know whether or not we need to
-	   do any lookup at all.                                     */
-
-  error = _HB_OPEN_Coverage_Index( &csf2->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  if (csf2->MaxContextLength < 1)
-    return HB_Err_Not_Covered;
-
-  if ( ALLOC_ARRAY( classes, csf2->MaxContextLength, HB_UShort ) )
-    return error;
-
-  error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_CURGLYPH(),
-		     &classes[0], NULL );
-  if ( error && error != HB_Err_Not_Covered )
-    goto End;
-  known_classes = 0;
-
-  scs = &csf2->SubClassSet[classes[0]];
-  if ( !scs )
-  {
-    error = ERR(HB_Err_Invalid_SubTable);
-    goto End;
-  }
-
-  for ( k = 0; k < scs->SubClassRuleCount; k++ )
-  {
-    sr  = &scs->SubClassRule[k];
-
-    if ( context_length != 0xFFFF && context_length < sr->GlyphCount )
-      goto next_subclassrule;
-
-    if ( buffer->in_pos + sr->GlyphCount > buffer->in_length )
-      goto next_subclassrule;                      /* context is too long */
-
-    cl   = sr->Class;
-
-    /* Start at 1 because [0] is implied */
-
-    for ( i = 1, j = buffer->in_pos + 1; i < sr->GlyphCount; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End;
-
-	if ( j + sr->GlyphCount - i < (HB_Int)buffer->in_length )
-	  goto next_subclassrule;
-	j++;
-      }
-
-      if ( i > known_classes )
-      {
-	/* Keeps us from having to do this for each rule */
-
-	error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL );
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End;
-	known_classes = i;
-      }
-
-      if ( cl[i - 1] != classes[i] )
-	goto next_subclassrule;
-    }
-
-    error = Do_ContextSubst( gsub, sr->GlyphCount,
-			     sr->SubstCount, sr->SubstLookupRecord,
-			     buffer,
-			     nesting_level );
-    goto End;
-
-  next_subclassrule:
-    ;
-  }
-
-  error = HB_Err_Not_Covered;
-
-End:
-  FREE( classes );
-  return error;
-}
-
-
-static HB_Error  Lookup_ContextSubst3( HB_GSUBHeader*          gsub,
-				       HB_ContextSubstFormat3* csf3,
-				       HB_Buffer               buffer,
-				       HB_UShort                flags,
-				       HB_UShort                context_length,
-				       int                      nesting_level )
-{
-  HB_Error         error;
-  HB_UShort        index, i, j, property;
-
-  HB_Coverage*    c;
-  HB_GDEFHeader*  gdef;
-
-
-  gdef = gsub->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  if ( context_length != 0xFFFF && context_length < csf3->GlyphCount )
-    return HB_Err_Not_Covered;
-
-  if ( buffer->in_pos + csf3->GlyphCount > buffer->in_length )
-    return HB_Err_Not_Covered;         /* context is too long */
-
-  c    = csf3->Coverage;
-
-  for ( i = 1, j = buffer->in_pos + 1; i < csf3->GlyphCount; i++, j++ )
-  {
-    while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-    {
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-
-      if ( j + csf3->GlyphCount - i == (HB_Int)buffer->in_length )
-	return HB_Err_Not_Covered;
-      j++;
-    }
-
-    error = _HB_OPEN_Coverage_Index( &c[i], IN_GLYPH( j ), &index );
-    if ( error )
-      return error;
-  }
-
-  return Do_ContextSubst( gsub, csf3->GlyphCount,
-			  csf3->SubstCount, csf3->SubstLookupRecord,
-			  buffer,
-			  nesting_level );
-}
-
-
-static HB_Error  Lookup_ContextSubst( HB_GSUBHeader*    gsub,
-				      HB_GSUB_SubTable* st,
-				      HB_Buffer         buffer,
-				      HB_UShort          flags,
-				      HB_UShort          context_length,
-				      int                nesting_level )
-{
-  HB_ContextSubst*  cs = &st->context;
-
-  switch ( cs->SubstFormat )
-  {
-  case 1:  return Lookup_ContextSubst1( gsub, &cs->csf.csf1, buffer, flags, context_length, nesting_level );
-  case 2:  return Lookup_ContextSubst2( gsub, &cs->csf.csf2, buffer, flags, context_length, nesting_level );
-  case 3:  return Lookup_ContextSubst3( gsub, &cs->csf.csf3, buffer, flags, context_length, nesting_level );
-  default: return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-/* LookupType 6 */
-
-/* ChainSubRule */
-
-static HB_Error  Load_ChainSubRule( HB_ChainSubRule*  csr,
-				    HB_Stream          stream )
-{
-  HB_Error error;
-
-  HB_UShort               n, count;
-  HB_UShort*              b;
-  HB_UShort*              i;
-  HB_UShort*              l;
-
-  HB_SubstLookupRecord*  slr;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  csr->BacktrackGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  csr->Backtrack = NULL;
-
-  count = csr->BacktrackGlyphCount;
-
-  if ( ALLOC_ARRAY( csr->Backtrack, count, HB_UShort ) )
-    return error;
-
-  b = csr->Backtrack;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail4;
-
-  for ( n = 0; n < count; n++ )
-    b[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail4;
-
-  csr->InputGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  csr->Input = NULL;
-
-  count = csr->InputGlyphCount - 1;  /* only InputGlyphCount - 1 elements */
-
-  if ( ALLOC_ARRAY( csr->Input, count, HB_UShort ) )
-    goto Fail4;
-
-  i = csr->Input;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail3;
-
-  for ( n = 0; n < count; n++ )
-    i[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  csr->LookaheadGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  csr->Lookahead = NULL;
-
-  count = csr->LookaheadGlyphCount;
-
-  if ( ALLOC_ARRAY( csr->Lookahead, count, HB_UShort ) )
-    goto Fail3;
-
-  l = csr->Lookahead;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail2;
-
-  for ( n = 0; n < count; n++ )
-    l[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  csr->SubstCount = GET_UShort();
-
-  FORGET_Frame();
-
-  csr->SubstLookupRecord = NULL;
-
-  count = csr->SubstCount;
-
-  if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, HB_SubstLookupRecord ) )
-    goto Fail2;
-
-  slr = csr->SubstLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    slr[n].SequenceIndex   = GET_UShort();
-    slr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( slr );
-
-Fail2:
-  FREE( l );
-
-Fail3:
-  FREE( i );
-
-Fail4:
-  FREE( b );
-  return error;
-}
-
-
-static void  Free_ChainSubRule( HB_ChainSubRule*  csr )
-{
-  FREE( csr->SubstLookupRecord );
-  FREE( csr->Lookahead );
-  FREE( csr->Input );
-  FREE( csr->Backtrack );
-}
-
-
-/* ChainSubRuleSet */
-
-static HB_Error  Load_ChainSubRuleSet( HB_ChainSubRuleSet*  csrs,
-				       HB_Stream             stream )
-{
-  HB_Error error;
-
-  HB_UShort          n = 0, m, count;
-  HB_UInt           cur_offset, new_offset, base_offset;
-
-  HB_ChainSubRule*  csr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = csrs->ChainSubRuleCount = GET_UShort();
-
-  FORGET_Frame();
-
-  csrs->ChainSubRule = NULL;
-
-  if ( ALLOC_ARRAY( csrs->ChainSubRule, count, HB_ChainSubRule ) )
-    return error;
-
-  csr = csrs->ChainSubRule;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_ChainSubRule( &csr[n], stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_ChainSubRule( &csr[m] );
-
-  FREE( csr );
-  return error;
-}
-
-
-static void  Free_ChainSubRuleSet( HB_ChainSubRuleSet*  csrs )
-{
-  HB_UShort          n, count;
-
-  HB_ChainSubRule*  csr;
-
-
-  if ( csrs->ChainSubRule )
-  {
-    count = csrs->ChainSubRuleCount;
-    csr   = csrs->ChainSubRule;
-
-    for ( n = 0; n < count; n++ )
-      Free_ChainSubRule( &csr[n] );
-
-    FREE( csr );
-  }
-}
-
-
-/* ChainContextSubstFormat1 */
-
-static HB_Error  Load_ChainContextSubst1(
-		   HB_ChainContextSubstFormat1*  ccsf1,
-		   HB_Stream                      stream )
-{
-  HB_Error error;
-
-  HB_UShort             n = 0, m, count;
-  HB_UInt              cur_offset, new_offset, base_offset;
-
-  HB_ChainSubRuleSet*  csrs;
-
-
-  base_offset = FILE_Pos() - 2L;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &ccsf1->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = ccsf1->ChainSubRuleSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccsf1->ChainSubRuleSet = NULL;
-
-  if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, HB_ChainSubRuleSet ) )
-    goto Fail2;
-
-  csrs = ccsf1->ChainSubRuleSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_ChainSubRuleSet( &csrs[n], stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_ChainSubRuleSet( &csrs[m] );
-
-  FREE( csrs );
-
-Fail2:
-  _HB_OPEN_Free_Coverage( &ccsf1->Coverage );
-  return error;
-}
-
-
-static void  Free_ChainContextSubst1( HB_ChainContextSubstFormat1*  ccsf1 )
-{
-  HB_UShort             n, count;
-
-  HB_ChainSubRuleSet*  csrs;
-
-
-  if ( ccsf1->ChainSubRuleSet )
-  {
-    count = ccsf1->ChainSubRuleSetCount;
-    csrs  = ccsf1->ChainSubRuleSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_ChainSubRuleSet( &csrs[n] );
-
-    FREE( csrs );
-  }
-
-  _HB_OPEN_Free_Coverage( &ccsf1->Coverage );
-}
-
-
-/* ChainSubClassRule */
-
-static HB_Error  Load_ChainSubClassRule(
-		   HB_ChainContextSubstFormat2*  ccsf2,
-		   HB_ChainSubClassRule*         cscr,
-		   HB_Stream                      stream )
-{
-  HB_Error error;
-
-  HB_UShort               n, count;
-
-  HB_UShort*              b;
-  HB_UShort*              i;
-  HB_UShort*              l;
-  HB_SubstLookupRecord*  slr;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  cscr->BacktrackGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength )
-    ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount;
-
-  cscr->Backtrack = NULL;
-
-  count = cscr->BacktrackGlyphCount;
-
-  if ( ALLOC_ARRAY( cscr->Backtrack, count, HB_UShort ) )
-    return error;
-
-  b = cscr->Backtrack;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail4;
-
-  for ( n = 0; n < count; n++ )
-    b[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail4;
-
-  cscr->InputGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( cscr->InputGlyphCount > ccsf2->MaxInputLength )
-    ccsf2->MaxInputLength = cscr->InputGlyphCount;
-
-  cscr->Input = NULL;
-
-  count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
-
-  if ( ALLOC_ARRAY( cscr->Input, count, HB_UShort ) )
-    goto Fail4;
-
-  i = cscr->Input;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail3;
-
-  for ( n = 0; n < count; n++ )
-    i[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  cscr->LookaheadGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength )
-    ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount;
-
-  cscr->Lookahead = NULL;
-
-  count = cscr->LookaheadGlyphCount;
-
-  if ( ALLOC_ARRAY( cscr->Lookahead, count, HB_UShort ) )
-    goto Fail3;
-
-  l = cscr->Lookahead;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail2;
-
-  for ( n = 0; n < count; n++ )
-    l[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  cscr->SubstCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cscr->SubstLookupRecord = NULL;
-
-  count = cscr->SubstCount;
-
-  if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count,
-		    HB_SubstLookupRecord ) )
-    goto Fail2;
-
-  slr = cscr->SubstLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    slr[n].SequenceIndex   = GET_UShort();
-    slr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( slr );
-
-Fail2:
-  FREE( l );
-
-Fail3:
-  FREE( i );
-
-Fail4:
-  FREE( b );
-  return error;
-}
-
-
-static void  Free_ChainSubClassRule( HB_ChainSubClassRule*  cscr )
-{
-  FREE( cscr->SubstLookupRecord );
-  FREE( cscr->Lookahead );
-  FREE( cscr->Input );
-  FREE( cscr->Backtrack );
-}
-
-
-/* SubClassSet */
-
-static HB_Error  Load_ChainSubClassSet(
-		   HB_ChainContextSubstFormat2*  ccsf2,
-		   HB_ChainSubClassSet*          cscs,
-		   HB_Stream                      stream )
-{
-  HB_Error error;
-
-  HB_UShort               n = 0, m, count;
-  HB_UInt                cur_offset, new_offset, base_offset;
-
-  HB_ChainSubClassRule*  cscr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = cscs->ChainSubClassRuleCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cscs->ChainSubClassRule = NULL;
-
-  if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count,
-		    HB_ChainSubClassRule ) )
-    return error;
-
-  cscr = cscs->ChainSubClassRule;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_ChainSubClassRule( ccsf2, &cscr[n],
-					   stream ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_ChainSubClassRule( &cscr[m] );
-
-  FREE( cscr );
-  return error;
-}
-
-
-static void  Free_ChainSubClassSet( HB_ChainSubClassSet*  cscs )
-{
-  HB_UShort               n, count;
-
-  HB_ChainSubClassRule*  cscr;
-
-
-  if ( cscs->ChainSubClassRule )
-  {
-    count = cscs->ChainSubClassRuleCount;
-    cscr  = cscs->ChainSubClassRule;
-
-    for ( n = 0; n < count; n++ )
-      Free_ChainSubClassRule( &cscr[n] );
-
-    FREE( cscr );
-  }
-}
-
-
-/* ChainContextSubstFormat2 */
-
-static HB_Error  Load_ChainContextSubst2(
-		   HB_ChainContextSubstFormat2*  ccsf2,
-		   HB_Stream                      stream )
-{
-  HB_Error error;
-
-  HB_UShort              n = 0, m, count;
-  HB_UInt               cur_offset, new_offset, base_offset;
-  HB_UInt               backtrack_offset, input_offset, lookahead_offset;
-
-  HB_ChainSubClassSet*  cscs;
-
-
-  base_offset = FILE_Pos() - 2;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &ccsf2->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-  if ( ACCESS_Frame( 8L ) )
-    goto Fail5;
-
-  backtrack_offset = GET_UShort();
-  input_offset     = GET_UShort();
-  lookahead_offset = GET_UShort();
-
-  /* `ChainSubClassSetCount' is the upper limit for input class values,
-     thus we read it now to make an additional safety check. No limit
-     is known or needed for the other two class definitions          */
-
-  count = ccsf2->ChainSubClassSetCount = GET_UShort();
-
-  FORGET_Frame();
-
-  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, 65535,
-						       backtrack_offset, base_offset,
-						       stream ) ) != HB_Err_Ok )
-      goto Fail5;
-
-  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count,
-						       input_offset, base_offset,
-						       stream ) ) != HB_Err_Ok )
-      goto Fail4;
-  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, 65535,
-						       lookahead_offset, base_offset,
-						       stream ) ) != HB_Err_Ok )
-    goto Fail3;
-
-  ccsf2->ChainSubClassSet   = NULL;
-  ccsf2->MaxBacktrackLength = 0;
-  ccsf2->MaxInputLength     = 0;
-  ccsf2->MaxLookaheadLength = 0;
-
-  if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, HB_ChainSubClassSet ) )
-    goto Fail2;
-
-  cscs = ccsf2->ChainSubClassSet;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    if ( new_offset != base_offset )      /* not a NULL offset */
-    {
-      cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-	   ( error = Load_ChainSubClassSet( ccsf2, &cscs[n],
-					    stream ) ) != HB_Err_Ok )
-	goto Fail1;
-      (void)FILE_Seek( cur_offset );
-    }
-    else
-    {
-      /* we create a ChainSubClassSet table with no entries */
-
-      ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0;
-      ccsf2->ChainSubClassSet[n].ChainSubClassRule      = NULL;
-    }
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_ChainSubClassSet( &cscs[m] );
-
-  FREE( cscs );
-
-Fail2:
-  _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef );
-
-Fail3:
-  _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef );
-
-Fail4:
-  _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef );
-
-Fail5:
-  _HB_OPEN_Free_Coverage( &ccsf2->Coverage );
-  return error;
-}
-
-
-static void  Free_ChainContextSubst2( HB_ChainContextSubstFormat2*  ccsf2 )
-{
-  HB_UShort              n, count;
-
-  HB_ChainSubClassSet*  cscs;
-
-
-  if ( ccsf2->ChainSubClassSet )
-  {
-    count = ccsf2->ChainSubClassSetCount;
-    cscs  = ccsf2->ChainSubClassSet;
-
-    for ( n = 0; n < count; n++ )
-      Free_ChainSubClassSet( &cscs[n] );
-
-    FREE( cscs );
-  }
-
-  _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef );
-  _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef );
-  _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef );
-
-  _HB_OPEN_Free_Coverage( &ccsf2->Coverage );
-}
-
-
-/* ChainContextSubstFormat3 */
-
-static HB_Error  Load_ChainContextSubst3(
-		   HB_ChainContextSubstFormat3*  ccsf3,
-		   HB_Stream                      stream )
-{
-  HB_Error error;
-
-  HB_UShort               n, nb = 0, ni =0, nl = 0, m, count;
-  HB_UShort               backtrack_count, input_count, lookahead_count;
-  HB_UInt                cur_offset, new_offset, base_offset;
-
-  HB_Coverage*           b;
-  HB_Coverage*           i;
-  HB_Coverage*           l;
-  HB_SubstLookupRecord*  slr;
-
-
-  base_offset = FILE_Pos() - 2L;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  ccsf3->BacktrackGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccsf3->BacktrackCoverage = NULL;
-
-  backtrack_count = ccsf3->BacktrackGlyphCount;
-
-  if ( ALLOC_ARRAY( ccsf3->BacktrackCoverage, backtrack_count,
-		    HB_Coverage ) )
-    return error;
-
-  b = ccsf3->BacktrackCoverage;
-
-  for ( nb = 0; nb < backtrack_count; nb++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail4;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok )
-      goto Fail4;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail4;
-
-  ccsf3->InputGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccsf3->InputCoverage = NULL;
-
-  input_count = ccsf3->InputGlyphCount;
-
-  if ( ALLOC_ARRAY( ccsf3->InputCoverage, input_count, HB_Coverage ) )
-    goto Fail4;
-
-  i = ccsf3->InputCoverage;
-
-  for ( ni = 0; ni < input_count; ni++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail3;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_Err_Ok )
-      goto Fail3;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  ccsf3->LookaheadGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccsf3->LookaheadCoverage = NULL;
-
-  lookahead_count = ccsf3->LookaheadGlyphCount;
-
-  if ( ALLOC_ARRAY( ccsf3->LookaheadCoverage, lookahead_count,
-		    HB_Coverage ) )
-    goto Fail3;
-
-  l = ccsf3->LookaheadCoverage;
-
-  for ( nl = 0; nl < lookahead_count; nl++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail2;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok )
-      goto Fail2;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  ccsf3->SubstCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ccsf3->SubstLookupRecord = NULL;
-
-  count = ccsf3->SubstCount;
-
-  if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count,
-		    HB_SubstLookupRecord ) )
-    goto Fail2;
-
-  slr = ccsf3->SubstLookupRecord;
-
-  if ( ACCESS_Frame( count * 4L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-  {
-    slr[n].SequenceIndex   = GET_UShort();
-    slr[n].LookupListIndex = GET_UShort();
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( slr );
-
-Fail2:
-  for ( m = 0; m < nl; m++ )
-    _HB_OPEN_Free_Coverage( &l[m] );
-
-  FREE( l );
-
-Fail3:
-  for ( m = 0; m < ni; m++ )
-    _HB_OPEN_Free_Coverage( &i[m] );
-
-  FREE( i );
-
-Fail4:
-  for ( m = 0; m < nb; m++ )
-    _HB_OPEN_Free_Coverage( &b[m] );
-
-  FREE( b );
-  return error;
-}
-
-
-static void  Free_ChainContextSubst3( HB_ChainContextSubstFormat3*  ccsf3 )
-{
-  HB_UShort      n, count;
-
-  HB_Coverage*  c;
-
-
-  FREE( ccsf3->SubstLookupRecord );
-
-  if ( ccsf3->LookaheadCoverage )
-  {
-    count = ccsf3->LookaheadGlyphCount;
-    c     = ccsf3->LookaheadCoverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-
-  if ( ccsf3->InputCoverage )
-  {
-    count = ccsf3->InputGlyphCount;
-    c     = ccsf3->InputCoverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-
-  if ( ccsf3->BacktrackCoverage )
-  {
-    count = ccsf3->BacktrackGlyphCount;
-    c     = ccsf3->BacktrackCoverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-}
-
-
-/* ChainContextSubst */
-
-static HB_Error  Load_ChainContextSubst( HB_GSUB_SubTable* st,
-					 HB_Stream         stream )
-{
-  HB_Error error;
-  HB_ChainContextSubst*  ccs = &st->chain;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  ccs->SubstFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  switch ( ccs->SubstFormat ) {
-    case 1:  return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, stream );
-    case 2:  return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, stream );
-    case 3:  return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, stream );
-    default: return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-static void  Free_ChainContextSubst( HB_GSUB_SubTable* st )
-{
-  HB_ChainContextSubst*  ccs = &st->chain;
-
-  switch ( ccs->SubstFormat ) {
-    case 1:  Free_ChainContextSubst1( &ccs->ccsf.ccsf1 ); break;
-    case 2:  Free_ChainContextSubst2( &ccs->ccsf.ccsf2 ); break;
-    case 3:  Free_ChainContextSubst3( &ccs->ccsf.ccsf3 ); break;
-    default:							  break;
-  }
-}
-
-
-static HB_Error  Lookup_ChainContextSubst1( HB_GSUBHeader*               gsub,
-					    HB_ChainContextSubstFormat1* ccsf1,
-					    HB_Buffer                    buffer,
-					    HB_UShort                     flags,
-					    HB_UShort                     context_length,
-					    int                           nesting_level )
-{
-  HB_UShort          index, property;
-  HB_UShort          i, j, k, num_csr;
-  HB_UShort          bgc, igc, lgc;
-  HB_Error           error;
-
-  HB_ChainSubRule*  csr;
-  HB_ChainSubRule   curr_csr;
-  HB_GDEFHeader*    gdef;
-
-
-  gdef = gsub->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  error = _HB_OPEN_Coverage_Index( &ccsf1->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  csr     = ccsf1->ChainSubRuleSet[index].ChainSubRule;
-  num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount;
-
-  for ( k = 0; k < num_csr; k++ )
-  {
-    curr_csr = csr[k];
-    bgc      = curr_csr.BacktrackGlyphCount;
-    igc      = curr_csr.InputGlyphCount;
-    lgc      = curr_csr.LookaheadGlyphCount;
-
-    if ( context_length != 0xFFFF && context_length < igc )
-      goto next_chainsubrule;
-
-    /* check whether context is too long; it is a first guess only */
-
-    if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
-      goto next_chainsubrule;
-
-    if ( bgc )
-    {
-      /* since we don't know in advance the number of glyphs to inspect,
-	 we search backwards for matches in the backtrack glyph array    */
-
-      for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
-      {
-	while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
-	{
-	  if ( error && error != HB_Err_Not_Covered )
-	    return error;
-
-	  if ( j + 1 == bgc - i )
-	    goto next_chainsubrule;
-	  j--;
-	}
-
-	/* In OpenType 1.3, it is undefined whether the offsets of
-	   backtrack glyphs is in logical order or not.  Version 1.4
-	   will clarify this:
-
-	     Logical order -      a  b  c  d  e  f  g  h  i  j
-					      i
-	     Input offsets -                  0  1
-	     Backtrack offsets -  3  2  1  0
-	     Lookahead offsets -                    0  1  2  3           */
-
-	if ( OUT_GLYPH( j ) != curr_csr.Backtrack[i] )
-	  goto next_chainsubrule;
-      }
-    }
-
-    /* Start at 1 because [0] is implied */
-
-    for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
-	  goto next_chainsubrule;
-	j++;
-      }
-
-      if ( IN_GLYPH( j ) != curr_csr.Input[i - 1] )
-	  goto next_chainsubrule;
-    }
-
-    /* we are starting to check for lookahead glyphs right after the
-       last context glyph                                            */
-
-    for ( i = 0; i < lgc; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + lgc - i == (HB_Int)buffer->in_length )
-	  goto next_chainsubrule;
-	j++;
-      }
-
-      if ( IN_GLYPH( j ) != curr_csr.Lookahead[i] )
-	goto next_chainsubrule;
-    }
-
-    return Do_ContextSubst( gsub, igc,
-			    curr_csr.SubstCount,
-			    curr_csr.SubstLookupRecord,
-			    buffer,
-			    nesting_level );
-
-  next_chainsubrule:
-    ;
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-static HB_Error  Lookup_ChainContextSubst2( HB_GSUBHeader*               gsub,
-					    HB_ChainContextSubstFormat2* ccsf2,
-					    HB_Buffer                    buffer,
-					    HB_UShort                     flags,
-					    HB_UShort                     context_length,
-					    int                           nesting_level )
-{
-  HB_UShort              index, property;
-  HB_Error               error;
-  HB_UShort              i, j, k;
-  HB_UShort              bgc, igc, lgc;
-  HB_UShort              known_backtrack_classes,
-			 known_input_classes,
-			 known_lookahead_classes;
-
-  HB_UShort*             backtrack_classes;
-  HB_UShort*             input_classes;
-  HB_UShort*             lookahead_classes;
-
-  HB_UShort*             bc;
-  HB_UShort*             ic;
-  HB_UShort*             lc;
-
-  HB_ChainSubClassSet*  cscs;
-  HB_ChainSubClassRule  ccsr;
-  HB_GDEFHeader*        gdef;
-
-
-  gdef = gsub->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  /* Note: The coverage table in format 2 doesn't give an index into
-	   anything.  It just lets us know whether or not we need to
-	   do any lookup at all.                                     */
-
-  error = _HB_OPEN_Coverage_Index( &ccsf2->Coverage, IN_CURGLYPH(), &index );
-  if ( error )
-    return error;
-
-  if ( ALLOC_ARRAY( backtrack_classes, ccsf2->MaxBacktrackLength, HB_UShort ) )
-    return error;
-  known_backtrack_classes = 0;
-
-  if (ccsf2->MaxInputLength < 1)
-    return HB_Err_Not_Covered;
-
-  if ( ALLOC_ARRAY( input_classes, ccsf2->MaxInputLength, HB_UShort ) )
-    goto End3;
-  known_input_classes = 1;
-
-  if ( ALLOC_ARRAY( lookahead_classes, ccsf2->MaxLookaheadLength, HB_UShort ) )
-    goto End2;
-  known_lookahead_classes = 0;
-
-  error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_CURGLYPH(),
-		     &input_classes[0], NULL );
-  if ( error && error != HB_Err_Not_Covered )
-    goto End1;
-
-  cscs = &ccsf2->ChainSubClassSet[input_classes[0]];
-  if ( !cscs )
-  {
-    error = ERR(HB_Err_Invalid_SubTable);
-    goto End1;
-  }
-
-  for ( k = 0; k < cscs->ChainSubClassRuleCount; k++ )
-  {
-    ccsr = cscs->ChainSubClassRule[k];
-    bgc  = ccsr.BacktrackGlyphCount;
-    igc  = ccsr.InputGlyphCount;
-    lgc  = ccsr.LookaheadGlyphCount;
-
-    if ( context_length != 0xFFFF && context_length < igc )
-      goto next_chainsubclassrule;
-
-    /* check whether context is too long; it is a first guess only */
-
-    if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
-      goto next_chainsubclassrule;
-
-    if ( bgc )
-    {
-      /* Since we don't know in advance the number of glyphs to inspect,
-	 we search backwards for matches in the backtrack glyph array.
-	 Note that `known_backtrack_classes' starts at index 0.         */
-
-      bc       = ccsr.Backtrack;
-
-      for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
-      {
-	while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
-	{
-	  if ( error && error != HB_Err_Not_Covered )
-	    goto End1;
-
-	  if ( j + 1 == bgc - i )
-	    goto next_chainsubclassrule;
-	  j--;
-	}
-
-	if ( i >= known_backtrack_classes )
-	{
-	  /* Keeps us from having to do this for each rule */
-
-	  error = _HB_OPEN_Get_Class( &ccsf2->BacktrackClassDef, OUT_GLYPH( j ),
-			     &backtrack_classes[i], NULL );
-	  if ( error && error != HB_Err_Not_Covered )
-	    goto End1;
-	  known_backtrack_classes = i;
-	}
-
-	if ( bc[i] != backtrack_classes[i] )
-	  goto next_chainsubclassrule;
-      }
-    }
-
-    ic       = ccsr.Input;
-
-    /* Start at 1 because [0] is implied */
-
-    for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End1;
-
-	if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
-	  goto next_chainsubclassrule;
-	j++;
-      }
-
-      if ( i >= known_input_classes )
-      {
-	error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_GLYPH( j ),
-			   &input_classes[i], NULL );
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End1;
-	known_input_classes = i;
-      }
-
-      if ( ic[i - 1] != input_classes[i] )
-	goto next_chainsubclassrule;
-    }
-
-    /* we are starting to check for lookahead glyphs right after the
-       last context glyph                                            */
-
-    lc       = ccsr.Lookahead;
-
-    for ( i = 0; i < lgc; i++, j++ )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End1;
-
-	if ( j + lgc - i == (HB_Int)buffer->in_length )
-	  goto next_chainsubclassrule;
-	j++;
-      }
-
-      if ( i >= known_lookahead_classes )
-      {
-	error = _HB_OPEN_Get_Class( &ccsf2->LookaheadClassDef, IN_GLYPH( j ),
-			   &lookahead_classes[i], NULL );
-	if ( error && error != HB_Err_Not_Covered )
-	  goto End1;
-	known_lookahead_classes = i;
-      }
-
-      if ( lc[i] != lookahead_classes[i] )
-	goto next_chainsubclassrule;
-    }
-
-    error = Do_ContextSubst( gsub, igc,
-			     ccsr.SubstCount,
-			     ccsr.SubstLookupRecord,
-			     buffer,
-			     nesting_level );
-    goto End1;
-
-  next_chainsubclassrule:
-    ;
-  }
-
-  error = HB_Err_Not_Covered;
-
-End1:
-  FREE( lookahead_classes );
-
-End2:
-  FREE( input_classes );
-
-End3:
-  FREE( backtrack_classes );
-  return error;
-}
-
-
-static HB_Error  Lookup_ChainContextSubst3( HB_GSUBHeader*               gsub,
-					    HB_ChainContextSubstFormat3* ccsf3,
-					    HB_Buffer                    buffer,
-					    HB_UShort                     flags,
-					    HB_UShort                     context_length,
-					    int                           nesting_level )
-{
-  HB_UShort        index, i, j, property;
-  HB_UShort        bgc, igc, lgc;
-  HB_Error         error;
-
-  HB_Coverage*    bc;
-  HB_Coverage*    ic;
-  HB_Coverage*    lc;
-  HB_GDEFHeader*  gdef;
-
-
-  gdef = gsub->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  bgc = ccsf3->BacktrackGlyphCount;
-  igc = ccsf3->InputGlyphCount;
-  lgc = ccsf3->LookaheadGlyphCount;
-
-  if ( context_length != 0xFFFF && context_length < igc )
-    return HB_Err_Not_Covered;
-
-  /* check whether context is too long; it is a first guess only */
-
-  if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
-    return HB_Err_Not_Covered;
-
-  if ( bgc )
-  {
-    /* Since we don't know in advance the number of glyphs to inspect,
-       we search backwards for matches in the backtrack glyph array    */
-
-    bc       = ccsf3->BacktrackCoverage;
-
-    for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
-    {
-      while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + 1 == bgc - i )
-	  return HB_Err_Not_Covered;
-	j--;
-      }
-
-      error = _HB_OPEN_Coverage_Index( &bc[i], OUT_GLYPH( j ), &index );
-      if ( error )
-	return error;
-    }
-  }
-
-  ic       = ccsf3->InputCoverage;
-
-  for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ )
-  {
-    /* We already called CHECK_Property for IN_GLYPH( buffer->in_pos ) */
-    while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-    {
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-
-      if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
-	return HB_Err_Not_Covered;
-      j++;
-    }
-
-    error = _HB_OPEN_Coverage_Index( &ic[i], IN_GLYPH( j ), &index );
-    if ( error )
-      return error;
-  }
-
-  /* we are starting for lookahead glyphs right after the last context
-     glyph                                                             */
-
-  lc       = ccsf3->LookaheadCoverage;
-
-  for ( i = 0; i < lgc; i++, j++ )
-  {
-    while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-    {
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-
-      if ( j + lgc - i == (HB_Int)buffer->in_length )
-	return HB_Err_Not_Covered;
-      j++;
-    }
-
-    error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index );
-    if ( error )
-      return error;
-  }
-
-  return Do_ContextSubst( gsub, igc,
-			  ccsf3->SubstCount,
-			  ccsf3->SubstLookupRecord,
-			  buffer,
-			  nesting_level );
-}
-
-
-static HB_Error  Lookup_ChainContextSubst( HB_GSUBHeader*    gsub,
-					   HB_GSUB_SubTable* st,
-					   HB_Buffer         buffer,
-					   HB_UShort          flags,
-					   HB_UShort          context_length,
-					   int                nesting_level )
-{
-  HB_ChainContextSubst*  ccs = &st->chain;
-
-  switch ( ccs->SubstFormat ) {
-    case 1:  return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, buffer, flags, context_length, nesting_level );
-    case 2:  return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, buffer, flags, context_length, nesting_level );
-    case 3:  return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, buffer, flags, context_length, nesting_level );
-    default: return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-}
-
-
-static HB_Error  Load_ReverseChainContextSubst( HB_GSUB_SubTable* st,
-					        HB_Stream         stream )
-{
-  HB_Error error;
-  HB_ReverseChainContextSubst*  rccs = &st->reverse;
-
-  HB_UShort               m, count;
-
-  HB_UShort               nb = 0, nl = 0, n;
-  HB_UShort               backtrack_count, lookahead_count;
-  HB_UInt                cur_offset, new_offset, base_offset;
-
-  HB_Coverage*           b;
-  HB_Coverage*           l;
-  HB_UShort*              sub;
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  rccs->SubstFormat = GET_UShort();
-
-  if ( rccs->SubstFormat != 1 )
-    return ERR(HB_Err_Invalid_SubTable_Format);
-
-  FORGET_Frame();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  cur_offset = FILE_Pos();
-  if ( FILE_Seek( new_offset ) ||
-       ( error = _HB_OPEN_Load_Coverage( &rccs->Coverage, stream ) ) != HB_Err_Ok )
-    return error;
-  (void)FILE_Seek( cur_offset );
-
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail4;
-
-  rccs->BacktrackGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  rccs->BacktrackCoverage = NULL;
-
-  backtrack_count = rccs->BacktrackGlyphCount;
-
-  if ( ALLOC_ARRAY( rccs->BacktrackCoverage, backtrack_count,
-		    HB_Coverage ) )
-    goto Fail4;
-
-  b = rccs->BacktrackCoverage;
-
-  for ( nb = 0; nb < backtrack_count; nb++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail3;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok )
-      goto Fail3;
-    (void)FILE_Seek( cur_offset );
-  }
-
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail3;
-
-  rccs->LookaheadGlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  rccs->LookaheadCoverage = NULL;
-
-  lookahead_count = rccs->LookaheadGlyphCount;
-
-  if ( ALLOC_ARRAY( rccs->LookaheadCoverage, lookahead_count,
-		    HB_Coverage ) )
-    goto Fail3;
-
-  l = rccs->LookaheadCoverage;
-
-  for ( nl = 0; nl < lookahead_count; nl++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail2;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok )
-      goto Fail2;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  rccs->GlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  rccs->Substitute = NULL;
-
-  count = rccs->GlyphCount;
-
-  if ( ALLOC_ARRAY( rccs->Substitute, count,
-		    HB_UShort ) )
-    goto Fail2;
-
-  sub = rccs->Substitute;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail1;
-
-  for ( n = 0; n < count; n++ )
-    sub[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( sub );
-
-Fail2:
-  for ( m = 0; m < nl; m++ )
-    _HB_OPEN_Free_Coverage( &l[m] );
-
-  FREE( l );
-
-Fail3:
-  for ( m = 0; m < nb; m++ )
-    _HB_OPEN_Free_Coverage( &b[m] );
-
-  FREE( b );
-
-Fail4:
-  _HB_OPEN_Free_Coverage( &rccs->Coverage );
-  return error;
-}
-
-
-static void  Free_ReverseChainContextSubst( HB_GSUB_SubTable* st )
-{
-  HB_UShort      n, count;
-  HB_ReverseChainContextSubst*  rccs = &st->reverse;
-
-  HB_Coverage*  c;
-
-  _HB_OPEN_Free_Coverage( &rccs->Coverage );
-
-  if ( rccs->LookaheadCoverage )
-  {
-    count = rccs->LookaheadGlyphCount;
-    c     = rccs->LookaheadCoverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-
-  if ( rccs->BacktrackCoverage )
-  {
-    count = rccs->BacktrackGlyphCount;
-    c     = rccs->BacktrackCoverage;
-
-    for ( n = 0; n < count; n++ )
-      _HB_OPEN_Free_Coverage( &c[n] );
-
-    FREE( c );
-  }
-
-  FREE ( rccs->Substitute );
-}
-
-
-static HB_Error  Lookup_ReverseChainContextSubst( HB_GSUBHeader*    gsub,
-						  HB_GSUB_SubTable* st,
-						  HB_Buffer         buffer,
-						  HB_UShort          flags,
-						  HB_UShort         context_length,
-						  int               nesting_level )
-{
-  HB_UShort        index, input_index, i, j, property;
-  HB_UShort        bgc, lgc;
-  HB_Error         error;
-
-  HB_ReverseChainContextSubst*  rccs = &st->reverse;
-  HB_Coverage*    bc;
-  HB_Coverage*    lc;
-  HB_GDEFHeader*  gdef;
-
-  if ( nesting_level != 1 || context_length != 0xFFFF )
-    return HB_Err_Not_Covered;
-
-  gdef = gsub->gdef;
-
-  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
-    return error;
-
-  bgc = rccs->BacktrackGlyphCount;
-  lgc = rccs->LookaheadGlyphCount;
-
-  /* check whether context is too long; it is a first guess only */
-
-  if ( bgc > buffer->in_pos || buffer->in_pos + 1 + lgc > buffer->in_length )
-    return HB_Err_Not_Covered;
-
-  if ( bgc )
-  {
-    /* Since we don't know in advance the number of glyphs to inspect,
-       we search backwards for matches in the backtrack glyph array    */
-
-    bc       = rccs->BacktrackCoverage;
-
-    for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
-    {
-      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-      {
-	if ( error && error != HB_Err_Not_Covered )
-	  return error;
-
-	if ( j + 1 == bgc - i )
-	  return HB_Err_Not_Covered;
-	j--;
-      }
-
-      error = _HB_OPEN_Coverage_Index( &bc[i], IN_GLYPH( j ), &index );
-      if ( error )
-	return error;
-    }
-  }
-
-  j = buffer->in_pos;
-
-  error = _HB_OPEN_Coverage_Index( &rccs->Coverage, IN_GLYPH( j ), &input_index );
-  if ( error )
-      return error;
-
-  lc       = rccs->LookaheadCoverage;
-
-  for ( i = 0, j = buffer->in_pos + 1; i < lgc; i++, j++ )
-  {
-    while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
-    {
-      if ( error && error != HB_Err_Not_Covered )
-	return error;
-
-      if ( j + lgc - i == (HB_Int)buffer->in_length )
-	return HB_Err_Not_Covered;
-      j++;
-    }
-
-    error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index );
-    if ( error )
-      return error;
-  }
-
-  IN_CURGLYPH() = rccs->Substitute[input_index];
-  buffer->in_pos--; /* Reverse! */
-
-  return error;
-}
-
-
-
-/***********
- * GSUB API
- ***********/
-
-
-
-HB_Error  HB_GSUB_Select_Script( HB_GSUBHeader*  gsub,
-				 HB_UInt         script_tag,
-				 HB_UShort*       script_index )
-{
-  HB_UShort          n;
-
-  HB_ScriptList*    sl;
-  HB_ScriptRecord*  sr;
-
-
-  if ( !gsub || !script_index )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gsub->ScriptList;
-  sr = sl->ScriptRecord;
-
-  for ( n = 0; n < sl->ScriptCount; n++ )
-    if ( script_tag == sr[n].ScriptTag )
-    {
-      *script_index = n;
-
-      return HB_Err_Ok;
-    }
-
-  return HB_Err_Not_Covered;
-}
-
-
-
-HB_Error  HB_GSUB_Select_Language( HB_GSUBHeader*  gsub,
-				   HB_UInt         language_tag,
-				   HB_UShort        script_index,
-				   HB_UShort*       language_index,
-				   HB_UShort*       req_feature_index )
-{
-  HB_UShort           n;
-
-  HB_ScriptList*     sl;
-  HB_ScriptRecord*   sr;
-  HB_ScriptTable*    s;
-  HB_LangSysRecord*  lsr;
-
-
-  if ( !gsub || !language_index || !req_feature_index )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gsub->ScriptList;
-  sr = sl->ScriptRecord;
-
-  if ( script_index >= sl->ScriptCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  s   = &sr[script_index].Script;
-  lsr = s->LangSysRecord;
-
-  for ( n = 0; n < s->LangSysCount; n++ )
-    if ( language_tag == lsr[n].LangSysTag )
-    {
-      *language_index = n;
-      *req_feature_index = lsr[n].LangSys.ReqFeatureIndex;
-
-      return HB_Err_Ok;
-    }
-
-  return HB_Err_Not_Covered;
-}
-
-
-/* selecting 0xFFFF for language_index asks for the values of the
-   default language (DefaultLangSys)                              */
-
-
-HB_Error  HB_GSUB_Select_Feature( HB_GSUBHeader*  gsub,
-				  HB_UInt         feature_tag,
-				  HB_UShort        script_index,
-				  HB_UShort        language_index,
-				  HB_UShort*       feature_index )
-{
-  HB_UShort           n;
-
-  HB_ScriptList*     sl;
-  HB_ScriptRecord*   sr;
-  HB_ScriptTable*    s;
-  HB_LangSysRecord*  lsr;
-  HB_LangSys*        ls;
-  HB_UShort*          fi;
-
-  HB_FeatureList*    fl;
-  HB_FeatureRecord*  fr;
-
-
-  if ( !gsub || !feature_index )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gsub->ScriptList;
-  sr = sl->ScriptRecord;
-
-  fl = &gsub->FeatureList;
-  fr = fl->FeatureRecord;
-
-  if ( script_index >= sl->ScriptCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  s   = &sr[script_index].Script;
-  lsr = s->LangSysRecord;
-
-  if ( language_index == 0xFFFF )
-    ls = &s->DefaultLangSys;
-  else
-  {
-    if ( language_index >= s->LangSysCount )
-      return ERR(HB_Err_Invalid_Argument);
-
-    ls = &lsr[language_index].LangSys;
-  }
-
-  fi = ls->FeatureIndex;
-
-  for ( n = 0; n < ls->FeatureCount; n++ )
-  {
-    if ( fi[n] >= fl->FeatureCount )
-      return ERR(HB_Err_Invalid_SubTable_Format);
-
-    if ( feature_tag == fr[fi[n]].FeatureTag )
-    {
-      *feature_index = fi[n];
-
-      return HB_Err_Ok;
-    }
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-/* The next three functions return a null-terminated list */
-
-
-HB_Error  HB_GSUB_Query_Scripts( HB_GSUBHeader*  gsub,
-				 HB_UInt**       script_tag_list )
-{
-  HB_UShort          n;
-  HB_Error           error;
-  HB_UInt*          stl;
-
-  HB_ScriptList*    sl;
-  HB_ScriptRecord*  sr;
-
-
-  if ( !gsub || !script_tag_list )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gsub->ScriptList;
-  sr = sl->ScriptRecord;
-
-  if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, HB_UInt ) )
-    return error;
-
-  for ( n = 0; n < sl->ScriptCount; n++ )
-    stl[n] = sr[n].ScriptTag;
-  stl[n] = 0;
-
-  *script_tag_list = stl;
-
-  return HB_Err_Ok;
-}
-
-
-
-HB_Error  HB_GSUB_Query_Languages( HB_GSUBHeader*  gsub,
-				   HB_UShort        script_index,
-				   HB_UInt**       language_tag_list )
-{
-  HB_UShort           n;
-  HB_Error            error;
-  HB_UInt*           ltl;
-
-  HB_ScriptList*     sl;
-  HB_ScriptRecord*   sr;
-  HB_ScriptTable*    s;
-  HB_LangSysRecord*  lsr;
-
-
-  if ( !gsub || !language_tag_list )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gsub->ScriptList;
-  sr = sl->ScriptRecord;
-
-  if ( script_index >= sl->ScriptCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  s   = &sr[script_index].Script;
-  lsr = s->LangSysRecord;
-
-  if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, HB_UInt ) )
-    return error;
-
-  for ( n = 0; n < s->LangSysCount; n++ )
-    ltl[n] = lsr[n].LangSysTag;
-  ltl[n] = 0;
-
-  *language_tag_list = ltl;
-
-  return HB_Err_Ok;
-}
-
-
-/* selecting 0xFFFF for language_index asks for the values of the
-   default language (DefaultLangSys)                              */
-
-
-HB_Error  HB_GSUB_Query_Features( HB_GSUBHeader*  gsub,
-				  HB_UShort        script_index,
-				  HB_UShort        language_index,
-				  HB_UInt**       feature_tag_list )
-{
-  HB_UShort           n;
-  HB_Error            error;
-  HB_UInt*           ftl;
-
-  HB_ScriptList*     sl;
-  HB_ScriptRecord*   sr;
-  HB_ScriptTable*    s;
-  HB_LangSysRecord*  lsr;
-  HB_LangSys*        ls;
-  HB_UShort*          fi;
-
-  HB_FeatureList*    fl;
-  HB_FeatureRecord*  fr;
-
-
-  if ( !gsub || !feature_tag_list )
-    return ERR(HB_Err_Invalid_Argument);
-
-  sl = &gsub->ScriptList;
-  sr = sl->ScriptRecord;
-
-  fl = &gsub->FeatureList;
-  fr = fl->FeatureRecord;
-
-  if ( script_index >= sl->ScriptCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  s   = &sr[script_index].Script;
-  lsr = s->LangSysRecord;
-
-  if ( language_index == 0xFFFF )
-    ls = &s->DefaultLangSys;
-  else
-  {
-    if ( language_index >= s->LangSysCount )
-      return ERR(HB_Err_Invalid_Argument);
-
-    ls = &lsr[language_index].LangSys;
-  }
-
-  fi = ls->FeatureIndex;
-
-  if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, HB_UInt ) )
-    return error;
-
-  for ( n = 0; n < ls->FeatureCount; n++ )
-  {
-    if ( fi[n] >= fl->FeatureCount )
-    {
-      FREE( ftl );
-      return ERR(HB_Err_Invalid_SubTable_Format);
-    }
-    ftl[n] = fr[fi[n]].FeatureTag;
-  }
-  ftl[n] = 0;
-
-  *feature_tag_list = ftl;
-
-  return HB_Err_Ok;
-}
-
-
-/* Do an individual subtable lookup.  Returns HB_Err_Ok if substitution
-   has been done, or HB_Err_Not_Covered if not.                        */
-static HB_Error  GSUB_Do_Glyph_Lookup( HB_GSUBHeader* gsub,
-				       HB_UShort       lookup_index,
-				       HB_Buffer      buffer,
-				       HB_UShort       context_length,
-				       int             nesting_level )
-{
-  HB_Error               error = HB_Err_Not_Covered;
-  HB_UShort              i, flags, lookup_count;
-  HB_Lookup*             lo;
-  int                    lookup_type;
-
-  nesting_level++;
-
-  if ( nesting_level > HB_MAX_NESTING_LEVEL )
-    return ERR(HB_Err_Not_Covered); /* ERR() call intended */
-
-  lookup_count = gsub->LookupList.LookupCount;
-  if (lookup_index >= lookup_count)
-    return error;
-
-  lo    = &gsub->LookupList.Lookup[lookup_index];
-  flags = lo->LookupFlag;
-  lookup_type = lo->LookupType;
-
-  for ( i = 0; i < lo->SubTableCount; i++ )
-  {
-    HB_GSUB_SubTable *st = &lo->SubTable[i].st.gsub;
-
-    switch (lookup_type) {
-      case HB_GSUB_LOOKUP_SINGLE:
-	error = Lookup_SingleSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GSUB_LOOKUP_MULTIPLE:
-	error = Lookup_MultipleSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GSUB_LOOKUP_ALTERNATE:
-	error = Lookup_AlternateSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GSUB_LOOKUP_LIGATURE:
-	error = Lookup_LigatureSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GSUB_LOOKUP_CONTEXT:
-	error = Lookup_ContextSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
-      case HB_GSUB_LOOKUP_CHAIN:
-	error = Lookup_ChainContextSubst	( gsub, st, buffer, flags, context_length, nesting_level ); break;
-    /*case HB_GSUB_LOOKUP_EXTENSION:
-	error = Lookup_ExtensionSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;*/
-      case HB_GSUB_LOOKUP_REVERSE_CHAIN:
-	error = Lookup_ReverseChainContextSubst	( gsub, st, buffer, flags, context_length, nesting_level ); break;
-      default:
-	error = HB_Err_Not_Covered;
-    };
-
-    /* Check whether we have a successful substitution or an error other
-       than HB_Err_Not_Covered                                          */
-    if ( error != HB_Err_Not_Covered )
-      return error;
-  }
-
-  return HB_Err_Not_Covered;
-}
-
-
-HB_INTERNAL HB_Error
-_HB_GSUB_Load_SubTable( HB_GSUB_SubTable* st,
-			HB_Stream         stream,
-			HB_UShort         lookup_type )
-{
-  switch (lookup_type) {
-    case HB_GSUB_LOOKUP_SINGLE:		return Load_SingleSubst			( st, stream );
-    case HB_GSUB_LOOKUP_MULTIPLE:	return Load_MultipleSubst		( st, stream );
-    case HB_GSUB_LOOKUP_ALTERNATE:	return Load_AlternateSubst		( st, stream );
-    case HB_GSUB_LOOKUP_LIGATURE:	return Load_LigatureSubst		( st, stream );
-    case HB_GSUB_LOOKUP_CONTEXT:	return Load_ContextSubst		( st, stream );
-    case HB_GSUB_LOOKUP_CHAIN:		return Load_ChainContextSubst		( st, stream );
-  /*case HB_GSUB_LOOKUP_EXTENSION:	return Load_ExtensionSubst		( st, stream );*/
-    case HB_GSUB_LOOKUP_REVERSE_CHAIN:	return Load_ReverseChainContextSubst	( st, stream );
-    default:				return ERR(HB_Err_Invalid_SubTable_Format);
-  };
-}
-
-
-HB_INTERNAL void
-_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st,
-			HB_UShort         lookup_type )
-{
-  switch ( lookup_type ) {
-    case HB_GSUB_LOOKUP_SINGLE:		Free_SingleSubst		( st ); return;
-    case HB_GSUB_LOOKUP_MULTIPLE:	Free_MultipleSubst		( st ); return;
-    case HB_GSUB_LOOKUP_ALTERNATE:	Free_AlternateSubst		( st ); return;
-    case HB_GSUB_LOOKUP_LIGATURE:	Free_LigatureSubst		( st ); return;
-    case HB_GSUB_LOOKUP_CONTEXT:	Free_ContextSubst		( st ); return;
-    case HB_GSUB_LOOKUP_CHAIN:		Free_ChainContextSubst		( st ); return;
-  /*case HB_GSUB_LOOKUP_EXTENSION:	Free_ExtensionSubst		( st ); return;*/
-    case HB_GSUB_LOOKUP_REVERSE_CHAIN:	Free_ReverseChainContextSubst	( st ); return;
-    default:									return;
-  };
-}
-
-
-
-/* apply one lookup to the input string object */
-
-static HB_Error  GSUB_Do_String_Lookup( HB_GSUBHeader*   gsub,
-				   HB_UShort         lookup_index,
-				   HB_Buffer        buffer )
-{
-  HB_Error  error, retError = HB_Err_Not_Covered;
-
-  HB_UInt*  properties = gsub->LookupList.Properties;
-  int       lookup_type = gsub->LookupList.Lookup[lookup_index].LookupType;
-
-  const int       nesting_level = 0;
-  /* 0xFFFF indicates that we don't have a context length yet */
-  const HB_UShort context_length = 0xFFFF;
-
-  switch (lookup_type) {
-
-    case HB_GSUB_LOOKUP_SINGLE:
-    case HB_GSUB_LOOKUP_MULTIPLE:
-    case HB_GSUB_LOOKUP_ALTERNATE:
-    case HB_GSUB_LOOKUP_LIGATURE:
-    case HB_GSUB_LOOKUP_CONTEXT:
-    case HB_GSUB_LOOKUP_CHAIN:
-      /* in/out forward substitution (implemented lazy) */
-
-      _hb_buffer_clear_output ( buffer );
-      buffer->in_pos = 0;
-  while ( buffer->in_pos < buffer->in_length )
-  {
-    if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
-    {
-	  error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level );
-      if ( error )
-      {
-	if ( error != HB_Err_Not_Covered )
-	  return error;
-      }
-      else
-	retError = error;
-    }
-    else
-      error = HB_Err_Not_Covered;
-
-    if ( error == HB_Err_Not_Covered )
-	  if ( COPY_Glyph ( buffer ) )
-	return error;
-  }
-      /* we shouldn't swap if error occurred.
-       *
-       * also don't swap if nothing changed (ie HB_Err_Not_Covered).
-       * shouldn't matter in that case though.
-       */
-      if ( retError == HB_Err_Ok )
-	_hb_buffer_swap( buffer );
-
-  return retError;
-
-    case HB_GSUB_LOOKUP_REVERSE_CHAIN:
-      /* in-place backward substitution */
-
-      buffer->in_pos = buffer->in_length - 1;
-    do
-    {
-      if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
-	{
-	  error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level );
-	  if ( error )
-	    {
-	      if ( error != HB_Err_Not_Covered )
-		return error;
-	    }
-	  else
-	    retError = error;
-	}
-	else
-	  error = HB_Err_Not_Covered;
-
-	if ( error == HB_Err_Not_Covered )
-	  buffer->in_pos--;
-      }
-      while ((HB_Int) buffer->in_pos >= 0);
-
-      return retError;
-
-  /*case HB_GSUB_LOOKUP_EXTENSION:*/
-    default:
-  return retError;
-  };
-}
-
-
-HB_Error  HB_GSUB_Add_Feature( HB_GSUBHeader*  gsub,
-			       HB_UShort        feature_index,
-			       HB_UInt          property )
-{
-  HB_UShort    i;
-
-  HB_Feature  feature;
-  HB_UInt*     properties;
-  HB_UShort*   index;
-  HB_UShort    lookup_count;
-
-  /* Each feature can only be added once */
-
-  if ( !gsub ||
-       feature_index >= gsub->FeatureList.FeatureCount ||
-       gsub->FeatureList.ApplyCount == gsub->FeatureList.FeatureCount )
-    return ERR(HB_Err_Invalid_Argument);
-
-  gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index;
-
-  properties = gsub->LookupList.Properties;
-
-  feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
-  index   = feature.LookupListIndex;
-  lookup_count = gsub->LookupList.LookupCount;
-
-  for ( i = 0; i < feature.LookupListCount; i++ )
-  {
-    HB_UShort lookup_index = index[i];
-    if (lookup_index < lookup_count)
-      properties[lookup_index] |= property;
-  }
-
-  return HB_Err_Ok;
-}
-
-
-
-HB_Error  HB_GSUB_Clear_Features( HB_GSUBHeader*  gsub )
-{
-  HB_UShort i;
-
-  HB_UInt*  properties;
-
-
-  if ( !gsub )
-    return ERR(HB_Err_Invalid_Argument);
-
-  gsub->FeatureList.ApplyCount = 0;
-
-  properties = gsub->LookupList.Properties;
-
-  for ( i = 0; i < gsub->LookupList.LookupCount; i++ )
-    properties[i] = 0;
-
-  return HB_Err_Ok;
-}
-
-
-
-HB_Error  HB_GSUB_Register_Alternate_Function( HB_GSUBHeader*  gsub,
-					       HB_AltFunction  altfunc,
-					       void*            data )
-{
-  if ( !gsub )
-    return ERR(HB_Err_Invalid_Argument);
-
-  gsub->altfunc = altfunc;
-  gsub->data    = data;
-
-  return HB_Err_Ok;
-}
-
-/* returns error if one happened, otherwise returns HB_Err_Not_Covered if no
- * feature were applied, or HB_Err_Ok otherwise.
- */
-HB_Error  HB_GSUB_Apply_String( HB_GSUBHeader*   gsub,
-				HB_Buffer        buffer )
-{
-  HB_Error          error, retError = HB_Err_Not_Covered;
-  int               i, j, lookup_count, num_features;
-
-  if ( !gsub ||
-       !buffer)
-    return ERR(HB_Err_Invalid_Argument);
-
-  if ( buffer->in_length == 0 )
-    return retError;
-
-  lookup_count = gsub->LookupList.LookupCount;
-  num_features = gsub->FeatureList.ApplyCount;
-
-  for ( i = 0; i < num_features; i++)
-  {
-    HB_UShort  feature_index = gsub->FeatureList.ApplyOrder[i];
-    HB_Feature feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
-
-    for ( j = 0; j < feature.LookupListCount; j++ )
-    {
-      HB_UShort         lookup_index = feature.LookupListIndex[j];
-
-      /* Skip nonexistant lookups */
-      if (lookup_index >= lookup_count)
-       continue;
-
-	error = GSUB_Do_String_Lookup( gsub, lookup_index, buffer );
-      if ( error )
-      {
-	if ( error != HB_Err_Not_Covered )
-	  return error;
-      }
-      else
-	retError = error;
-    }
-  }
-
-  error = retError;
-
-  return error;
-}
-
-
-/* END */
diff --git a/third_party/harfbuzz/src/harfbuzz-gsub.h b/third_party/harfbuzz/src/harfbuzz-gsub.h
deleted file mode 100644
index 1ca3f0c..0000000
--- a/third_party/harfbuzz/src/harfbuzz-gsub.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_GSUB_H
-#define HARFBUZZ_GSUB_H
-
-#include "harfbuzz-gdef.h"
-#include "harfbuzz-buffer.h"
-
-HB_BEGIN_HEADER
-
-
-/* Lookup types for glyph substitution */
-
-#define HB_GSUB_LOOKUP_SINGLE        1
-#define HB_GSUB_LOOKUP_MULTIPLE      2
-#define HB_GSUB_LOOKUP_ALTERNATE     3
-#define HB_GSUB_LOOKUP_LIGATURE      4
-#define HB_GSUB_LOOKUP_CONTEXT       5
-#define HB_GSUB_LOOKUP_CHAIN         6
-#define HB_GSUB_LOOKUP_EXTENSION     7
-#define HB_GSUB_LOOKUP_REVERSE_CHAIN 8
-
-
-/* A pointer to a function which selects the alternate glyph.  `pos' is
-   the position of the glyph with index `glyphID', `num_alternates'
-   gives the number of alternates in the `alternates' array.  `data'
-   points to the user-defined structure specified during a call to
-   HB_GSUB_Register_Alternate_Function().  The function must return an
-   index into the `alternates' array.                                   */
-
-typedef HB_UShort  (*HB_AltFunction)(HB_UInt    pos,
-				      HB_UShort   glyphID,
-				      HB_UShort   num_alternates,
-				      HB_UShort*  alternates,
-				      void*       data );
-
-
-struct  HB_GSUBHeader_
-{
-  HB_UInt         offset;
-
-  HB_16Dot16         Version;
-
-  HB_ScriptList   ScriptList;
-  HB_FeatureList  FeatureList;
-  HB_LookupList   LookupList;
-
-  HB_GDEFHeader*  gdef;
-
-  /* the next two fields are used for an alternate substitution callback
-     function to select the proper alternate glyph.                      */
-
-  HB_AltFunction  altfunc;
-  void*            data;
-};
-
-typedef struct HB_GSUBHeader_   HB_GSUBHeader;
-typedef HB_GSUBHeader*  HB_GSUB;
-
-
-HB_Error  HB_Load_GSUB_Table( HB_Stream       stream,
-			      HB_GSUBHeader** gsub,
-			      HB_GDEFHeader*  gdef,
-                              HB_Stream       gdefStream );
-
-
-HB_Error  HB_Done_GSUB_Table( HB_GSUBHeader*  gsub );
-
-
-HB_Error  HB_GSUB_Select_Script( HB_GSUBHeader*  gsub,
-				 HB_UInt         script_tag,
-				 HB_UShort*       script_index );
-
-HB_Error  HB_GSUB_Select_Language( HB_GSUBHeader*  gsub,
-				   HB_UInt         language_tag,
-				   HB_UShort        script_index,
-				   HB_UShort*       language_index,
-				   HB_UShort*       req_feature_index );
-
-HB_Error  HB_GSUB_Select_Feature( HB_GSUBHeader*  gsub,
-				  HB_UInt         feature_tag,
-				  HB_UShort        script_index,
-				  HB_UShort        language_index,
-				  HB_UShort*       feature_index );
-
-
-HB_Error  HB_GSUB_Query_Scripts( HB_GSUBHeader*  gsub,
-				 HB_UInt**       script_tag_list );
-
-HB_Error  HB_GSUB_Query_Languages( HB_GSUBHeader*  gsub,
-				   HB_UShort        script_index,
-				   HB_UInt**       language_tag_list );
-
-HB_Error  HB_GSUB_Query_Features( HB_GSUBHeader*  gsub,
-				  HB_UShort        script_index,
-				  HB_UShort        language_index,
-				  HB_UInt**       feature_tag_list );
-
-
-HB_Error  HB_GSUB_Add_Feature( HB_GSUBHeader*  gsub,
-			       HB_UShort        feature_index,
-			       HB_UInt          property );
-
-HB_Error  HB_GSUB_Clear_Features( HB_GSUBHeader*  gsub );
-
-
-HB_Error  HB_GSUB_Register_Alternate_Function( HB_GSUBHeader*  gsub,
-					       HB_AltFunction  altfunc,
-					       void*            data );
-
-
-HB_Error  HB_GSUB_Apply_String( HB_GSUBHeader*   gsub,
-				HB_Buffer        buffer );
-
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GSUB_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-hangul.c b/third_party/harfbuzz/src/harfbuzz-hangul.c
deleted file mode 100644
index a819dac..0000000
--- a/third_party/harfbuzz/src/harfbuzz-hangul.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-
-/*
-// Hangul is a syllable based script. Unicode reserves a large range
-// for precomposed hangul, where syllables are already precomposed to
-// their final glyph shape. In addition, a so called jamo range is
-// defined, that can be used to express old Hangul. Modern hangul
-// syllables can also be expressed as jamo, and should be composed
-// into syllables. The operation is rather simple and mathematical.
-
-// Every hangul jamo is classified as being either a Leading consonant
-// (L), and intermediat Vowel (V) or a trailing consonant (T). Modern
-// hangul syllables (the ones in the precomposed area can be of type
-// LV or LVT.
-//
-// Syllable breaks do _not_ occur between:
-//
-// L              L, V or precomposed
-// V, LV          V, T
-// LVT, T         T
-//
-// A standard syllable is of the form L+V+T*. The above rules allow
-// nonstandard syllables L*V*T*. To transform them into standard
-// syllables fill characters L_f and V_f can be inserted.
-*/
-
-enum {
-    Hangul_SBase = 0xac00,
-    Hangul_LBase = 0x1100,
-    Hangul_VBase = 0x1161,
-    Hangul_TBase = 0x11a7,
-    Hangul_SCount = 11172,
-    Hangul_LCount = 19,
-    Hangul_VCount = 21,
-    Hangul_TCount = 28,
-    Hangul_NCount = 21*28
-};
-
-#define hangul_isPrecomposed(uc) \
-    (uc >= Hangul_SBase && uc < Hangul_SBase + Hangul_SCount)
-
-#define hangul_isLV(uc) \
-    ((uc - Hangul_SBase) % Hangul_TCount == 0)
-
-typedef enum {
-    L,
-    V,
-    T,
-    LV,
-    LVT,
-    X
-} HangulType;
-
-static HangulType hangul_type(unsigned short uc) {
-    if (uc > Hangul_SBase && uc < Hangul_SBase + Hangul_SCount)
-        return hangul_isLV(uc) ? LV : LVT;
-    if (uc < Hangul_LBase || uc > 0x11ff)
-        return X;
-    if (uc < Hangul_VBase)
-        return L;
-    if (uc < Hangul_TBase)
-        return V;
-    return T;
-}
-
-static int hangul_nextSyllableBoundary(const HB_UChar16 *s, int start, int end)
-{
-    const HB_UChar16 *uc = s + start;
-
-    HangulType state = hangul_type(*uc);
-    int pos = 1;
-
-    while (pos < end - start) {
-        HangulType newState = hangul_type(uc[pos]);
-        switch(newState) {
-        case X:
-            goto finish;
-        case L:
-        case V:
-        case T:
-            if (state > newState)
-                goto finish;
-            state = newState;
-            break;
-        case LV:
-            if (state > L)
-                goto finish;
-            state = V;
-            break;
-        case LVT:
-            if (state > L)
-                goto finish;
-            state = T;
-        }
-        ++pos;
-    }
-
- finish:
-    return start+pos;
-}
-
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature hangul_features [] = {
-    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
-    { HB_MAKE_TAG('l', 'j', 'm', 'o'), CcmpProperty },
-    { HB_MAKE_TAG('j', 'j', 'm', 'o'), CcmpProperty },
-    { HB_MAKE_TAG('t', 'j', 'm', 'o'), CcmpProperty },
-    { 0, 0 }
-};
-#endif
-
-static HB_Bool hangul_shape_syllable(HB_ShaperItem *item, HB_Bool openType)
-{
-    const HB_UChar16 *ch = item->string + item->item.pos;
-    int len = item->item.length;
-#ifndef NO_OPENTYPE
-    const int availableGlyphs = item->num_glyphs;
-#endif
-
-    int i;
-    HB_UChar16 composed = 0;
-    /* see if we can compose the syllable into a modern hangul */
-    if (item->item.length == 2) {
-        int LIndex = ch[0] - Hangul_LBase;
-        int VIndex = ch[1] - Hangul_VBase;
-        if (LIndex >= 0 && LIndex < Hangul_LCount &&
-            VIndex >= 0 && VIndex < Hangul_VCount)
-            composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + Hangul_SBase;
-    } else if (item->item.length == 3) {
-        int LIndex = ch[0] - Hangul_LBase;
-        int VIndex = ch[1] - Hangul_VBase;
-        int TIndex = ch[2] - Hangul_TBase;
-        if (LIndex >= 0 && LIndex < Hangul_LCount &&
-            VIndex >= 0 && VIndex < Hangul_VCount &&
-            TIndex >= 0 && TIndex < Hangul_TCount)
-            composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + TIndex + Hangul_SBase;
-    }
-
-
-
-    /* if we have a modern hangul use the composed form */
-    if (composed) {
-        ch = &composed;
-        len = 1;
-    }
-
-    if (!item->font->klass->convertStringToGlyphIndices(item->font,
-                                                        ch, len,
-                                                        item->glyphs, &item->num_glyphs,
-                                                        item->item.bidiLevel % 2))
-        return FALSE;
-    for (i = 0; i < len; i++) {
-        item->attributes[i].mark = FALSE;
-        item->attributes[i].clusterStart = FALSE;
-        item->attributes[i].justification = 0;
-        item->attributes[i].zeroWidth = FALSE;
-        /*IDEBUG("    %d: %4x", i, ch[i].unicode()); */
-    }
-
-#ifndef NO_OPENTYPE
-    if (!composed && openType) {
-        HB_Bool positioned;
-
-        HB_STACKARRAY(unsigned short, logClusters, len);
-        for (i = 0; i < len; ++i)
-            logClusters[i] = i;
-        item->log_clusters = logClusters;
-
-        HB_OpenTypeShape(item, /*properties*/0);
-
-        positioned = HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE);
-
-        HB_FREE_STACKARRAY(logClusters);
-
-        if (!positioned)
-            return FALSE;
-    } else {
-        HB_HeuristicPosition(item);
-    }
-#endif
-
-    item->attributes[0].clusterStart = TRUE;
-    return TRUE;
-}
-
-HB_Bool HB_HangulShape(HB_ShaperItem *item)
-{
-    const HB_UChar16 *uc = item->string + item->item.pos;
-    HB_Bool allPrecomposed = TRUE;
-    int i;
-
-    assert(item->item.script == HB_Script_Hangul);
-
-    for (i = 0; i < (int)item->item.length; ++i) {
-        if (!hangul_isPrecomposed(uc[i])) {
-            allPrecomposed = FALSE;
-            break;
-        }
-    }
-
-    if (!allPrecomposed) {
-        HB_Bool openType = FALSE;
-        unsigned short *logClusters = item->log_clusters;
-        HB_ShaperItem syllable;
-        int first_glyph = 0;
-        int sstart = item->item.pos;
-        int end = sstart + item->item.length;
-
-#ifndef NO_OPENTYPE
-        openType = HB_SelectScript(item, hangul_features);
-#endif
-        syllable = *item;
-
-        while (sstart < end) {
-            int send = hangul_nextSyllableBoundary(item->string, sstart, end);
-
-            syllable.item.pos = sstart;
-            syllable.item.length = send-sstart;
-            syllable.glyphs = item->glyphs + first_glyph;
-            syllable.attributes = item->attributes + first_glyph;
-            syllable.offsets = item->offsets + first_glyph;
-            syllable.advances = item->advances + first_glyph;
-            syllable.num_glyphs = item->num_glyphs - first_glyph;
-            if (!hangul_shape_syllable(&syllable, openType)) {
-                item->num_glyphs += syllable.num_glyphs;
-                return FALSE;
-            }
-            /* fix logcluster array */
-            for (i = sstart; i < send; ++i)
-                logClusters[i-item->item.pos] = first_glyph;
-            sstart = send;
-            first_glyph += syllable.num_glyphs;
-        }
-        item->num_glyphs = first_glyph;
-        return TRUE;
-    }
-
-    return HB_BasicShape(item);
-}
-
-
diff --git a/third_party/harfbuzz/src/harfbuzz-hebrew.c b/third_party/harfbuzz/src/harfbuzz-hebrew.c
deleted file mode 100644
index d2664de..0000000
--- a/third_party/harfbuzz/src/harfbuzz-hebrew.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-#include <assert.h>
-
-/*
-// Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly
-// ligatures one does not want in modern Hebrew (as lam-alef ligatures).
-*/
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature hebrew_features[] = {
-    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
-    {0, 0}
-};
-#endif
-
-/* Hebrew shaping. In the non opentype case we try to use the
-   presentation forms specified for Hebrew. Especially for the
-   ligatures with Dagesh this gives much better results than we could
-   achieve manually.
-*/
-HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
-{
-    enum {
-        Dagesh = 0x5bc,
-        ShinDot = 0x5c1,
-        SinDot = 0x5c2,
-        Patah = 0x5b7,
-        Qamats = 0x5b8,
-        Holam = 0x5b9,
-        Rafe = 0x5bf
-    };
-
-    assert(shaper_item->item.script == HB_Script_Hebrew);
-
-    HB_HeuristicSetGlyphAttributes(shaper_item);
-
-#ifndef NO_OPENTYPE
-    if (HB_SelectScript(shaper_item, hebrew_features)) {
-
-        const int availableGlyphs = shaper_item->num_glyphs;
-        if (!HB_ConvertStringToGlyphIndices(shaper_item))
-            return FALSE;
-
-
-        HB_OpenTypeShape(shaper_item, /*properties*/0);
-        return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
-    }
-#endif
-
-    {
-        const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos;
-        unsigned short *logClusters = shaper_item->log_clusters;
-        HB_GlyphAttributes *attributes = shaper_item->attributes;
-
-        HB_Bool haveGlyphs;
-        int slen = 1;
-        int cluster_start = 0;
-        hb_uint32 i;
-
-        HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length);
-        *shapedChars = *uc;
-        logClusters[0] = 0;
-
-        for (i = 1; i < shaper_item->item.length; ++i) {
-            hb_uint16 base = shapedChars[cluster_start];
-            hb_uint16 shaped = 0;
-            HB_Bool invalid = FALSE;
-            if (uc[i] == Dagesh) {
-                if (base >= 0x5d0
-                    && base <= 0x5ea
-                    && base != 0x5d7
-                    && base != 0x5dd
-                    && base != 0x5df
-                    && base != 0x5e2
-                    && base != 0x5e5) {
-                    shaped = base - 0x5d0 + 0xfb30;
-                } else if (base == 0xfb2a || base == 0xfb2b /* Shin with Shin or Sin dot */) {
-                    shaped = base + 2;
-                } else {
-                    invalid = TRUE;
-                }
-            } else if (uc[i] == ShinDot) {
-                if (base == 0x05e9)
-                    shaped = 0xfb2a;
-                else if (base == 0xfb49)
-                    shaped = 0xfb2c;
-                else
-                    invalid = TRUE;
-            } else if (uc[i] == SinDot) {
-                if (base == 0x05e9)
-                    shaped = 0xfb2b;
-                else if (base == 0xfb49)
-                    shaped = 0xfb2d;
-                else
-                    invalid = TRUE;
-            } else if (uc[i] == Patah) {
-                if (base == 0x5d0)
-                    shaped = 0xfb2e;
-            } else if (uc[i] == Qamats) {
-                if (base == 0x5d0)
-                    shaped = 0xfb2f;
-            } else if (uc[i] == Holam) {
-                if (base == 0x5d5)
-                    shaped = 0xfb4b;
-            } else if (uc[i] == Rafe) {
-                if (base == 0x5d1)
-                    shaped = 0xfb4c;
-                else if (base == 0x5db)
-                    shaped = 0xfb4d;
-                else if (base == 0x5e4)
-                    shaped = 0xfb4e;
-            }
-
-            if (invalid) {
-                shapedChars[slen] = 0x25cc;
-                attributes[slen].clusterStart = TRUE;
-                attributes[slen].mark = FALSE;
-                attributes[slen].combiningClass = 0;
-                cluster_start = slen;
-                ++slen;
-            }
-            if (shaped) {
-                if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) {
-                    shapedChars[cluster_start] = shaped;
-                } else
-                    shaped = 0;
-            }
-            if (!shaped) {
-                HB_CharCategory category;
-                int cmb;
-                shapedChars[slen] = uc[i];
-                HB_GetUnicodeCharProperties(uc[i], &category, &cmb);
-                if (category != HB_Mark_NonSpacing) {
-                    attributes[slen].clusterStart = TRUE;
-                    attributes[slen].mark = FALSE;
-                    attributes[slen].combiningClass = 0;
-                    attributes[slen].dontPrint = HB_IsControlChar(uc[i]);
-                    cluster_start = slen;
-                } else {
-                    attributes[slen].clusterStart = FALSE;
-                    attributes[slen].mark = TRUE;
-                    attributes[slen].combiningClass = cmb;
-                }
-                ++slen;
-            }
-            logClusters[i] = cluster_start;
-        }
-
-        haveGlyphs = shaper_item->font->klass
-            ->convertStringToGlyphIndices(shaper_item->font,
-                                          shapedChars, slen,
-                                          shaper_item->glyphs, &shaper_item->num_glyphs,
-                                          shaper_item->item.bidiLevel % 2);
-
-        HB_FREE_STACKARRAY(shapedChars);
-
-        if (!haveGlyphs)
-            return FALSE;
-
-        HB_HeuristicPosition(shaper_item);
-    }
-
-    return TRUE;
-}
-
diff --git a/third_party/harfbuzz/src/harfbuzz-impl.c b/third_party/harfbuzz/src/harfbuzz-impl.c
deleted file mode 100644
index ddbf36b..0000000
--- a/third_party/harfbuzz/src/harfbuzz-impl.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-
-
-HB_INTERNAL HB_Pointer
-_hb_alloc(size_t     size,
-	  HB_Error  *perror )
-{
-  HB_Error    error = (HB_Error)0;
-  HB_Pointer  block = NULL;
-
-  if ( size > 0 )
-  {
-    block = calloc( 1, size );
-    if ( !block )
-      error = ERR(HB_Err_Out_Of_Memory);
-  }
-
-  *perror = error;
-  return block;
-}
-
-
-HB_INTERNAL HB_Pointer
-_hb_realloc(HB_Pointer  block,
-	    size_t      new_size,
-	    HB_Error   *perror )
-{
-    HB_Pointer  block2 = NULL;
-    HB_Error    error  = (HB_Error)0;
-
-    block2 = realloc( block, new_size );
-    if ( block2 == NULL && new_size != 0 )
-        error = ERR(HB_Err_Out_Of_Memory);
-
-    if ( !error )
-        block = block2;
-
-    *perror = error;
-    return block;
-}
-
-
-HB_INTERNAL void
-_hb_free( HB_Pointer  block )
-{
-  if ( block )
-    free( block );
-}
-
-
-/* helper func to set a breakpoint on */
-HB_INTERNAL HB_Error
-_hb_err (HB_Error code)
-{
-  return code;
-}
diff --git a/third_party/harfbuzz/src/harfbuzz-impl.h b/third_party/harfbuzz/src/harfbuzz-impl.h
deleted file mode 100644
index 5f43049..0000000
--- a/third_party/harfbuzz/src/harfbuzz-impl.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_IMPL_H
-#define HARFBUZZ_IMPL_H
-
-#include "harfbuzz-global.h"
-
-#include <stdlib.h>
-
-HB_BEGIN_HEADER
-
-#ifndef HB_INTERNAL
-# define HB_INTERNAL
-#endif
-
-#ifndef NULL
-# define NULL ((void *)0)
-#endif
-
-#ifndef FALSE
-# define FALSE 0
-#endif
-
-#ifndef TRUE
-# define TRUE 1
-#endif
-
-#ifndef TTAG_GDEF
-# define TTAG_GDEF  HB_MAKE_TAG( 'G', 'D', 'E', 'F' )
-#endif
-#ifndef TTAG_GPOS
-# define TTAG_GPOS  HB_MAKE_TAG( 'G', 'P', 'O', 'S' )
-#endif
-#ifndef TTAG_GSUB
-# define TTAG_GSUB  HB_MAKE_TAG( 'G', 'S', 'U', 'B' )
-#endif
-
-#ifndef HB_UNUSED
-# define HB_UNUSED(arg) ((arg) = (arg))
-#endif
-
-#define HB_LIKELY(cond) (cond)
-#define HB_UNLIKELY(cond) (cond)
-
-#define ARRAY_LEN(Array) ((int)(sizeof (Array) / sizeof (Array)[0]))
-
-
-
-#define HB_IsHighSurrogate(ucs) \
-    (((ucs) & 0xfc00) == 0xd800)
-
-#define HB_IsLowSurrogate(ucs) \
-    (((ucs) & 0xfc00) == 0xdc00)
-
-#define HB_SurrogateToUcs4(high, low) \
-    (((HB_UChar32)(high))<<10) + (low) - 0x35fdc00;
-
-
-
-
-
-#define  ALLOC(_ptr,_size)   \
-           ( (_ptr) = _hb_alloc( _size, &error ), error != 0 )
-
-#define  REALLOC(_ptr,_newsz)  \
-           ( (_ptr) = _hb_realloc( (_ptr), (_newsz), &error ), error != 0 )
-
-#define  FREE(_ptr)                    \
-  do {                                 \
-    if ( (_ptr) )                      \
-    {                                  \
-      _hb_free( _ptr );     \
-      _ptr = NULL;                     \
-    }                                  \
-  } while (0)
-
-#define  ALLOC_ARRAY(_ptr,_count,_type)   \
-           ALLOC(_ptr,(_count)*sizeof(_type))
-
-#define  REALLOC_ARRAY(_ptr,_newcnt,_type) \
-           REALLOC(_ptr,(_newcnt)*sizeof(_type))
-
-#define  MEM_Copy(dest,source,count)   memcpy( (char*)(dest), (const char*)(source), (size_t)(count) )
-
-#define ERR(err)   _hb_err (err)
-
-
-HB_INTERNAL HB_Pointer
-_hb_alloc( size_t    size,
-	   HB_Error *perror_ );
-
-HB_INTERNAL HB_Pointer
-_hb_realloc( HB_Pointer block,
-	     size_t     new_size,
-	     HB_Error  *perror_ );
-
-HB_INTERNAL void
-_hb_free( HB_Pointer block );
-
-
-/* helper func to set a breakpoint on */
-HB_INTERNAL HB_Error
-_hb_err (HB_Error code);
-
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_IMPL_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-indic.cpp b/third_party/harfbuzz/src/harfbuzz-indic.cpp
deleted file mode 100644
index 3c9df93..0000000
--- a/third_party/harfbuzz/src/harfbuzz-indic.cpp
+++ /dev/null
@@ -1,1873 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-#define FLAG(x) (1 << (x))
-
-static HB_Bool isLetter(HB_UChar16 ucs)
-{
-    const int test = FLAG(HB_Letter_Uppercase) |
-                     FLAG(HB_Letter_Lowercase) |
-                     FLAG(HB_Letter_Titlecase) |
-                     FLAG(HB_Letter_Modifier) |
-                     FLAG(HB_Letter_Other);
-    return FLAG(HB_GetUnicodeCharCategory(ucs)) & test;
-}
-
-static HB_Bool isMark(HB_UChar16 ucs)
-{
-    const int test = FLAG(HB_Mark_NonSpacing) |
-                     FLAG(HB_Mark_SpacingCombining) |
-                     FLAG(HB_Mark_Enclosing);
-    return FLAG(HB_GetUnicodeCharCategory(ucs)) & test;
-}
-
-enum Form {
-    Invalid = 0x0,
-    UnknownForm = Invalid,
-    Consonant,
-    Nukta,
-    Halant,
-    Matra,
-    VowelMark,
-    StressMark,
-    IndependentVowel,
-    LengthMark,
-    Control,
-    Other
-};
-
-static const unsigned char indicForms[0xe00-0x900] = {
-    // Devangari
-    Invalid, VowelMark, VowelMark, VowelMark,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, UnknownForm, UnknownForm,
-    Nukta, Other, Matra, Matra,
-
-    Matra, Matra, Matra, Matra,
-    Matra, Matra, Matra, Matra,
-    Matra, Matra, Matra, Matra,
-    Matra, Halant, UnknownForm, UnknownForm,
-
-    Other, StressMark, StressMark, StressMark,
-    StressMark, UnknownForm, UnknownForm, UnknownForm,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    IndependentVowel, IndependentVowel, VowelMark, VowelMark,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Consonant,
-    Consonant, Consonant /* ??? */, Consonant, Consonant,
-
-    // Bengali
-    Invalid, VowelMark, VowelMark, VowelMark,
-    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, Invalid, Invalid, IndependentVowel,
-
-    IndependentVowel, Invalid, Invalid, IndependentVowel,
-    IndependentVowel, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Invalid, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Invalid, Consonant, Invalid,
-    Invalid, Invalid, Consonant, Consonant,
-    Consonant, Consonant, UnknownForm, UnknownForm,
-    Nukta, Other, Matra, Matra,
-
-    Matra, Matra, Matra, Matra,
-    Matra, Invalid, Invalid, Matra,
-    Matra, Invalid, Invalid, Matra,
-    Matra, Halant, Consonant, UnknownForm,
-
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Invalid, VowelMark,
-    Invalid, Invalid, Invalid, Invalid,
-    Consonant, Consonant, Invalid, Consonant,
-
-    IndependentVowel, IndependentVowel, VowelMark, VowelMark,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    Consonant, Consonant, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    // Gurmukhi
-    Invalid, VowelMark, VowelMark, VowelMark,
-    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
-    Invalid, Invalid, Invalid, IndependentVowel,
-
-    IndependentVowel, Invalid, Invalid, IndependentVowel,
-    IndependentVowel, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Invalid, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Invalid, Consonant, Consonant,
-    Invalid, Consonant, Consonant, Invalid,
-    Consonant, Consonant, UnknownForm, UnknownForm,
-    Nukta, Other, Matra, Matra,
-
-    Matra, Matra, Matra, Invalid,
-    Invalid, Invalid, Invalid, Matra,
-    Matra, Invalid, Invalid, Matra,
-    Matra, Halant, UnknownForm, UnknownForm,
-
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, UnknownForm, UnknownForm, UnknownForm,
-    Invalid, Consonant, Consonant, Consonant,
-    Consonant, Invalid, Consonant, Invalid,
-
-    Other, Other, Invalid, Invalid,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    StressMark, StressMark, Consonant, Consonant,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    // Gujarati
-    Invalid, VowelMark, VowelMark, VowelMark,
-    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, Invalid, IndependentVowel,
-
-    IndependentVowel, IndependentVowel, Invalid, IndependentVowel,
-    IndependentVowel, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Invalid, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Invalid, Consonant, Consonant,
-    Invalid, Consonant, Consonant, Consonant,
-    Consonant, Consonant, UnknownForm, UnknownForm,
-    Nukta, Other, Matra, Matra,
-
-    Matra, Matra, Matra, Matra,
-    Matra, Matra, Invalid, Matra,
-    Matra, Matra, Invalid, Matra,
-    Matra, Halant, UnknownForm, UnknownForm,
-
-    Other, UnknownForm, UnknownForm, UnknownForm,
-    UnknownForm, UnknownForm, UnknownForm, UnknownForm,
-    UnknownForm, UnknownForm, UnknownForm, UnknownForm,
-    UnknownForm, UnknownForm, UnknownForm, UnknownForm,
-
-    IndependentVowel, IndependentVowel, VowelMark, VowelMark,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    // Oriya
-    Invalid, VowelMark, VowelMark, VowelMark,
-    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, Invalid, Invalid, IndependentVowel,
-
-    IndependentVowel, Invalid, Invalid, IndependentVowel,
-    IndependentVowel, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Invalid, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Invalid, Consonant, Consonant,
-    Invalid, Consonant, Consonant, Consonant,
-    Consonant, Consonant, UnknownForm, UnknownForm,
-    Nukta, Other, Matra, Matra,
-
-    Matra, Matra, Matra, Matra,
-    Invalid, Invalid, Invalid, Matra,
-    Matra, Invalid, Invalid, Matra,
-    Matra, Halant, UnknownForm, UnknownForm,
-
-    Other, Invalid, Invalid, Invalid,
-    Invalid, UnknownForm, LengthMark, LengthMark,
-    Invalid, Invalid, Invalid, Invalid,
-    Consonant, Consonant, Invalid, Consonant,
-
-    IndependentVowel, IndependentVowel, Invalid, Invalid,
-    Invalid, Invalid, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    Other, Consonant, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    //Tamil
-    Invalid, Invalid, VowelMark, Other,
-    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
-    Invalid, Invalid, IndependentVowel, IndependentVowel,
-
-    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-    IndependentVowel, Consonant, Invalid, Invalid,
-    Invalid, Consonant, Consonant, Invalid,
-    Consonant, Invalid, Consonant, Consonant,
-
-    Invalid, Invalid, Invalid, Consonant,
-    Consonant, Invalid, Invalid, Invalid,
-    Consonant, Consonant, Consonant, Invalid,
-    Invalid, Invalid, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, UnknownForm, UnknownForm,
-    Invalid, Invalid, Matra, Matra,
-
-    Matra, Matra, Matra, Invalid,
-    Invalid, Invalid, Matra, Matra,
-    Matra, Invalid, Matra, Matra,
-    Matra, Halant, Invalid, Invalid,
-
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Invalid, LengthMark,
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Invalid, Invalid,
-
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    // Telugu
-    Invalid, VowelMark, VowelMark, VowelMark,
-    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-
-    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-    IndependentVowel, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Invalid, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Invalid, Consonant, Consonant, Consonant,
-    Consonant, Consonant, UnknownForm, UnknownForm,
-    Invalid, Invalid, Matra, Matra,
-
-    Matra, Matra, Matra, Matra,
-    Matra, Invalid, Matra, Matra,
-    Matra, Invalid, Matra, Matra,
-    Matra, Halant, Invalid, Invalid,
-
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, LengthMark, Matra, Invalid,
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Invalid, Invalid,
-
-    IndependentVowel, IndependentVowel, Invalid, Invalid,
-    Invalid, Invalid, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    // Kannada
-    Invalid, Invalid, VowelMark, VowelMark,
-    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-
-    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-    IndependentVowel, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Invalid, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Invalid, Consonant, Consonant, Consonant,
-    Consonant, Consonant, UnknownForm, UnknownForm,
-    Nukta, Other, Matra, Matra,
-
-    Matra, Matra, Matra, Matra,
-    Matra, Invalid, Matra, Matra,
-    Matra, Invalid, Matra, Matra,
-    Matra, Halant, Invalid, Invalid,
-
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, LengthMark, LengthMark, Invalid,
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Consonant, Invalid,
-
-    IndependentVowel, IndependentVowel, VowelMark, VowelMark,
-    Invalid, Invalid, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    // Malayalam
-    Invalid, Invalid, VowelMark, VowelMark,
-    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-
-    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-    IndependentVowel, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Invalid, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, UnknownForm, UnknownForm,
-    Invalid, Invalid, Matra, Matra,
-
-    Matra, Matra, Matra, Matra,
-    Invalid, Invalid, Matra, Matra,
-    Matra, Invalid, Matra, Matra,
-    Matra, Halant, Invalid, Invalid,
-
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Invalid, Matra,
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Invalid, Invalid,
-
-    IndependentVowel, IndependentVowel, Invalid, Invalid,
-    Invalid, Invalid, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-
-    // Sinhala
-    Invalid, Invalid, VowelMark, VowelMark,
-    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-
-    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-    IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
-    Invalid, Invalid, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-
-    Consonant, Consonant, Invalid, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Consonant,
-    Invalid, Consonant, Invalid, Invalid,
-
-    Consonant, Consonant, Consonant, Consonant,
-    Consonant, Consonant, Consonant, Invalid,
-    Invalid, Invalid, Halant, Invalid,
-    Invalid, Invalid, Invalid, Matra,
-
-    Matra, Matra, Matra, Matra,
-    Matra, Invalid, Matra, Invalid,
-    Matra, Matra, Matra, Matra,
-    Matra, Matra, Matra, Matra,
-
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Invalid, Invalid,
-    Invalid, Invalid, Invalid, Invalid,
-
-    Invalid, Invalid, Matra, Matra,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-    Other, Other, Other, Other,
-};
-
-enum Position {
-    None,
-    Pre,
-    Above,
-    Below,
-    Post,
-    Split,
-    Base,
-    Reph,
-    Vattu,
-    Inherit
-};
-
-static const unsigned char indicPosition[0xe00-0x900] = {
-    // Devanagari
-    None, Above, Above, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    Below, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, Post, Pre,
-
-    Post, Below, Below, Below,
-    Below, Above, Above, Above,
-    Above, Post, Post, Post,
-    Post, None, None, None,
-
-    None, Above, Below, Above,
-    Above, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, Below, Below,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    // Bengali
-    None, Above, Post, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    Below, None, None, Post,
-
-    Below, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    Below, None, Post, Pre,
-
-    Post, Below, Below, Below,
-    Below, None, None, Pre,
-    Pre, None, None, Split,
-    Split, Below, None, None,
-
-    None, None, None, None,
-    None, None, None, Post,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, Below, Below,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    Below, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    // Gurmukhi
-    None, Above, Above, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, Post,
-
-    Below, None, None, None,
-    None, Below, None, None,
-    None, Below, None, None,
-    Below, None, Post, Pre,
-
-    Post, Below, Below, None,
-    None, None, None, Above,
-    Above, None, None, Above,
-    Above, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    Above, Above, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    // Gujarati
-    None, Above, Above, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    Below, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, Post, Pre,
-
-    Post, Below, Below, Below,
-    Below, Above, None, Above,
-    Above, Post, None, Post,
-    Post, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, Below, Below,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    // Oriya
-    None, Above, Post, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    Below, None, None, None,
-    Below, None, None, None,
-    Below, Below, Below, Post,
-
-    Below, None, Below, Below,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, Post, Above,
-
-    Post, Below, Below, Below,
-    None, None, None, Pre,
-    Split, None, None, Split,
-    Split, None, None, None,
-
-    None, None, None, None,
-    None, None, Above, Post,
-    None, None, None, None,
-    None, None, None, Post,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, Below, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    // Tamil
-    None, None, Above, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, Post, Post,
-
-    Above, Below, Below, None,
-    None, None, Pre, Pre,
-    Pre, None, Split, Split,
-    Split, Halant, None, None,
-
-    None, None, None, None,
-    None, None, None, Post,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    // Telugu
-    None, Post, Post, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, Below, Below, Below,
-    Below, Below, Below, Below,
-    Below, Below, Below, Below,
-
-    Below, Below, Below, Below,
-    Below, Below, Below, Below,
-    Below, None, Below, Below,
-    Below, Below, Below, Below,
-
-    Below, None, Below, Below,
-    None, Below, Below, Below,
-    Below, Below, None, None,
-    None, None, Post, Above,
-
-    Above, Post, Post, Post,
-    Post, None, Above, Above,
-    Split, None, Post, Above,
-    Above, Halant, None, None,
-
-    None, None, None, None,
-    None, Above, Below, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    // Kannada
-    None, None, Post, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, Below, Below, Below,
-    Below, Below, Below, Below,
-    Below, Below, Below, Below,
-
-    Below, Below, Below, Below,
-    Below, Below, Below, Below,
-    Below, Below, Below, Below,
-    Below, Below, Below, Below,
-
-    Below, None, Below, Below,
-    None, Below, Below, Below,
-    Below, Below, None, None,
-    None, None, Post, Above,
-
-    Split, Post, Post, Post,
-    Post, None, Above, Split,
-    Split, None, Split, Split,
-    Above, Halant, None, None,
-
-    None, None, None, None,
-    None, Post, Post, None,
-    None, None, None, None,
-    None, None, Below, None,
-
-    None, None, Below, Below,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    // Malayalam
-    None, None, Post, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, Post,
-
-    Post, None, Below, None,
-    None, Post, None, None,
-    None, None, None, None,
-    None, None, Post, Post,
-
-    Post, Post, Post, Post,
-    None, None, Pre, Pre,
-    Pre, None, Split, Split,
-    Split, Halant, None, None,
-
-    None, None, None, None,
-    None, None, None, Post,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    // Sinhala
-    None, None, Post, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, Post,
-
-    Post, Post, Above, Above,
-    Below, None, Below, None,
-    Post, Pre, Split, Pre,
-    Split, Split, Split, Post,
-
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None,
-
-    None, None, Post, Post,
-    None, None, None, None,
-    None, None, None, None,
-    None, None, None, None
-};
-
-static inline Form form(unsigned short uc) {
-    if (uc < 0x900 || uc > 0xdff) {
-        if (uc == 0x25cc)
-            return Consonant;
-        if (uc == 0x200c || uc == 0x200d)
-            return Control;
-        return Other;
-    }
-    return (Form)indicForms[uc-0x900];
-}
-
-static inline Position indic_position(unsigned short uc) {
-    if (uc < 0x900 || uc > 0xdff)
-        return None;
-    return (Position) indicPosition[uc-0x900];
-}
-
-
-enum IndicScriptProperties {
-    HasReph = 0x01,
-    HasSplit = 0x02
-};
-
-const hb_uint8 scriptProperties[10] = {
-    // Devanagari,
-    HasReph,
-    // Bengali,
-    HasReph|HasSplit,
-    // Gurmukhi,
-    0,
-    // Gujarati,
-    HasReph,
-    // Oriya,
-    HasReph|HasSplit,
-    // Tamil,
-    HasSplit,
-    // Telugu,
-    HasSplit,
-    // Kannada,
-    HasSplit|HasReph,
-    // Malayalam,
-    HasSplit,
-    // Sinhala,
-    HasSplit
-};
-
-struct IndicOrdering {
-    Form form;
-    Position position;
-};
-
-static const IndicOrdering devanagari_order [] = {
-    { Consonant, Below },
-    { Matra, Below },
-    { VowelMark, Below },
-    { StressMark, Below },
-    { Matra, Above },
-    { Matra, Post },
-    { Consonant, Reph },
-    { VowelMark, Above },
-    { StressMark, Above },
-    { VowelMark, Post },
-    { (Form)0, None }
-};
-
-static const IndicOrdering bengali_order [] = {
-    { Consonant, Below },
-    { Matra, Below },
-    { Matra, Above },
-    { Consonant, Reph },
-    { VowelMark, Above },
-    { Consonant, Post },
-    { Matra, Post },
-    { VowelMark, Post },
-    { (Form)0, None }
-};
-
-static const IndicOrdering gurmukhi_order [] = {
-    { Consonant, Below },
-    { Matra, Below },
-    { Matra, Above },
-    { Consonant, Post },
-    { Matra, Post },
-    { VowelMark, Above },
-    { (Form)0, None }
-};
-
-static const IndicOrdering tamil_order [] = {
-    { Matra, Above },
-    { Matra, Post },
-    { VowelMark, Post },
-    { (Form)0, None }
-};
-
-static const IndicOrdering telugu_order [] = {
-    { Matra, Above },
-    { Matra, Below },
-    { Matra, Post },
-    { Consonant, Below },
-    { Consonant, Post },
-    { VowelMark, Post },
-    { (Form)0, None }
-};
-
-static const IndicOrdering kannada_order [] = {
-    { Matra, Above },
-    { Matra, Post },
-    { Consonant, Below },
-    { Consonant, Post },
-    { LengthMark, Post },
-    { Consonant, Reph },
-    { VowelMark, Post },
-    { (Form)0, None }
-};
-
-static const IndicOrdering malayalam_order [] = {
-    { Consonant, Below },
-    { Matra, Below },
-    { Consonant, Reph },
-    { Consonant, Post },
-    { Matra, Post },
-    { VowelMark, Post },
-    { (Form)0, None }
-};
-
-static const IndicOrdering sinhala_order [] = {
-    { Matra, Below },
-    { Matra, Above },
-    { Matra, Post },
-    { VowelMark, Post },
-    { (Form)0, None }
-};
-
-static const IndicOrdering * const indic_order[] = {
-    devanagari_order, // Devanagari
-    bengali_order, // Bengali
-    gurmukhi_order, // Gurmukhi
-    devanagari_order, // Gujarati
-    bengali_order, // Oriya
-    tamil_order, // Tamil
-    telugu_order, // Telugu
-    kannada_order, // Kannada
-    malayalam_order, // Malayalam
-    sinhala_order // Sinhala
-};
-
-
-
-// vowel matras that have to be split into two parts.
-static const unsigned short split_matras[]  = {
-    //  matra, split1, split2, split3
-
-    // bengalis
-    0x9cb, 0x9c7, 0x9be, 0x0,
-    0x9cc, 0x9c7, 0x9d7, 0x0,
-    // oriya
-    0xb48, 0xb47, 0xb56, 0x0,
-    0xb4b, 0xb47, 0xb3e, 0x0,
-    0xb4c, 0xb47, 0xb57, 0x0,
-    // tamil
-    0xbca, 0xbc6, 0xbbe, 0x0,
-    0xbcb, 0xbc7, 0xbbe, 0x0,
-    0xbcc, 0xbc6, 0xbd7, 0x0,
-    // telugu
-    0xc48, 0xc46, 0xc56, 0x0,
-    // kannada
-    0xcc0, 0xcbf, 0xcd5, 0x0,
-    0xcc7, 0xcc6, 0xcd5, 0x0,
-    0xcc8, 0xcc6, 0xcd6, 0x0,
-    0xcca, 0xcc6, 0xcc2, 0x0,
-    0xccb, 0xcc6, 0xcc2, 0xcd5,
-    // malayalam
-    0xd4a, 0xd46, 0xd3e, 0x0,
-    0xd4b, 0xd47, 0xd3e, 0x0,
-    0xd4c, 0xd46, 0xd57, 0x0,
-    // sinhala
-    0xdda, 0xdd9, 0xdca, 0x0,
-    0xddc, 0xdd9, 0xdcf, 0x0,
-    0xddd, 0xdd9, 0xdcf, 0xdca,
-    0xdde, 0xdd9, 0xddf, 0x0,
-    0xffff
-};
-
-static inline void splitMatra(unsigned short *reordered, int matra, int &len)
-{
-    unsigned short matra_uc = reordered[matra];
-    //qDebug("matra=%d, reordered[matra]=%x", matra, reordered[matra]);
-
-    const unsigned short *split = split_matras;
-    while (split[0] < matra_uc)
-        split += 4;
-
-    assert(*split == matra_uc);
-    ++split;
-
-    int added_chars = split[2] == 0x0 ? 1 : 2;
-
-    memmove(reordered + matra + added_chars, reordered + matra, (len-matra)*sizeof(unsigned short));
-    reordered[matra] = split[0];
-    reordered[matra+1] = split[1];
-    if(added_chars == 2)
-        reordered[matra+2] = split[2];
-    len += added_chars;
-}
-
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature indic_features[] = {
-    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
-    { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
-    { HB_MAKE_TAG('n', 'u', 'k', 't'), NuktaProperty },
-    { HB_MAKE_TAG('a', 'k', 'h', 'n'), AkhantProperty },
-    { HB_MAKE_TAG('r', 'p', 'h', 'f'), RephProperty },
-    { HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty },
-    { HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty },
-    { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
-    { HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty },
-    { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty },
-    { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
-    { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
-    { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty },
-    { HB_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty },
-    { 0, 0 }
-};
-#endif
-
-// #define INDIC_DEBUG
-#ifdef INDIC_DEBUG
-#define IDEBUG hb_debug
-#include <stdarg.h>
-
-static void hb_debug(const char *msg, ...)
-{
-    va_list ap;
-    va_start(ap, msg); // use variable arg list
-    vfprintf(stderr, msg, ap);
-    va_end(ap);
-    fprintf(stderr, "\n");
-}
-
-#else
-#define IDEBUG if(0) printf
-#endif
-
-#if 0 //def INDIC_DEBUG
-static QString propertiesToString(int properties)
-{
-    QString res;
-    properties = ~properties;
-    if (properties & CcmpProperty)
-        res += "Ccmp ";
-    if (properties & InitProperty)
-        res += "Init ";
-    if (properties & NuktaProperty)
-        res += "Nukta ";
-    if (properties & AkhantProperty)
-        res += "Akhant ";
-    if (properties & RephProperty)
-        res += "Reph ";
-    if (properties & PreFormProperty)
-        res += "PreForm ";
-    if (properties & BelowFormProperty)
-        res += "BelowForm ";
-    if (properties & AboveFormProperty)
-        res += "AboveForm ";
-    if (properties & HalfFormProperty)
-        res += "HalfForm ";
-    if (properties & PostFormProperty)
-        res += "PostForm ";
-    if (properties & VattuProperty)
-        res += "Vattu ";
-    if (properties & PreSubstProperty)
-        res += "PreSubst ";
-    if (properties & BelowSubstProperty)
-        res += "BelowSubst ";
-    if (properties & AboveSubstProperty)
-        res += "AboveSubst ";
-    if (properties & PostSubstProperty)
-        res += "PostSubst ";
-    if (properties & HalantProperty)
-        res += "Halant ";
-    if (properties & CligProperty)
-        res += "Clig ";
-    return res;
-}
-#endif
-
-static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool invalid)
-{
-    HB_Script script = item->item.script;
-    assert(script >= HB_Script_Devanagari && script <= HB_Script_Sinhala);
-    const unsigned short script_base = 0x0900 + 0x80*(script-HB_Script_Devanagari);
-    const unsigned short ra = script_base + 0x30;
-    const unsigned short halant = script_base + 0x4d;
-    const unsigned short nukta = script_base + 0x3c;
-    bool control = false;
-
-    int len = (int)item->item.length;
-    IDEBUG(">>>>> indic shape: from=%d, len=%d invalid=%d", item->item.pos, item->item.length, invalid);
-
-    if ((int)item->num_glyphs < len+4) {
-        item->num_glyphs = len+4;
-        return false;
-    }
-
-    HB_STACKARRAY(HB_UChar16, reordered, len + 4);
-    HB_STACKARRAY(hb_uint8, position, len + 4);
-
-    unsigned char properties = scriptProperties[script-HB_Script_Devanagari];
-
-    if (invalid) {
-        *reordered = 0x25cc;
-        memcpy(reordered+1, item->string + item->item.pos, len*sizeof(HB_UChar16));
-        len++;
-    } else {
-        memcpy(reordered, item->string + item->item.pos, len*sizeof(HB_UChar16));
-    }
-    if (reordered[len-1] == 0x200c) // zero width non joiner
-        len--;
-
-    int i;
-    int base = 0;
-    int reph = -1;
-
-#ifdef INDIC_DEBUG
-    IDEBUG("original:");
-    for (i = 0; i < len; i++) {
-        IDEBUG("    %d: %4x", i, reordered[i]);
-    }
-#endif
-
-    if (len != 1) {
-        HB_UChar16 *uc = reordered;
-        bool beginsWithRa = false;
-
-        // Rule 1: find base consonant
-        //
-        // The shaping engine finds the base consonant of the
-        // syllable, using the following algorithm: starting from the
-        // end of the syllable, move backwards until a consonant is
-        // found that does not have a below-base or post-base form
-        // (post-base forms have to follow below-base forms), or
-        // arrive at the first consonant. The consonant stopped at
-        // will be the base.
-        //
-        //  * If the syllable starts with Ra + H (in a script that has
-        //    'Reph'), Ra is excluded from candidates for base
-        //    consonants.
-        //
-        // * In Kannada and Telugu, the base consonant cannot be
-        //   farther than 3 consonants from the end of the syllable.
-        // #### replace the HasReph property by testing if the feature exists in the font!
-        if (form(*uc) == Consonant || (script == HB_Script_Bengali && form(*uc) == IndependentVowel)) {
-            if ((properties & HasReph) && (len > 2) &&
-                (*uc == ra || *uc == 0x9f0) && *(uc+1) == halant)
-                beginsWithRa = true;
-
-            if (beginsWithRa && form(*(uc+2)) == Control)
-                beginsWithRa = false;
-
-            base = (beginsWithRa ? 2 : 0);
-            IDEBUG("    length = %d, beginsWithRa = %d, base=%d", len, beginsWithRa, base);
-
-            int lastConsonant = 0;
-            int matra = -1;
-            // we remember:
-            // * the last consonant since we need it for rule 2
-            // * the matras position for rule 3 and 4
-
-            // figure out possible base glyphs
-            memset(position, 0, len);
-            if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) {
-                bool vattu = false;
-                for (i = base; i < len; ++i) {
-                    position[i] = form(uc[i]);
-                    if (position[i] == Consonant) {
-                        lastConsonant = i;
-                        vattu = (!vattu && uc[i] == ra);
-                        if (vattu) {
-                            IDEBUG("excluding vattu glyph at %d from base candidates", i);
-                            position[i] = Vattu;
-                        }
-                    } else if (position[i] == Matra) {
-                        matra = i;
-                    }
-                }
-            } else {
-                for (i = base; i < len; ++i) {
-                    position[i] = form(uc[i]);
-                    if (position[i] == Consonant)
-                        lastConsonant = i;
-                    else if (matra < 0 && position[i] == Matra)
-                        matra = i;
-                }
-            }
-            int skipped = 0;
-            Position pos = Post;
-            for (i = len-1; i > base; i--) {
-                if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada))
-                    continue;
-
-                Position charPosition = indic_position(uc[i]);
-                if (pos == Post && charPosition == Post) {
-                    pos = Post;
-                } else if ((pos == Post || pos == Below) && charPosition == Below) {
-                    if (script == HB_Script_Devanagari || script == HB_Script_Gujarati)
-                        base = i;
-                    pos = Below;
-                } else {
-                    base = i;
-                    break;
-                }
-                if (skipped == 2 && (script == HB_Script_Kannada || script == HB_Script_Telugu)) {
-                    base = i;
-                    break;
-                }
-                ++skipped;
-            }
-
-            IDEBUG("    base consonant at %d skipped=%d, lastConsonant=%d", base, skipped, lastConsonant);
-
-            // Rule 2:
-            //
-            // If the base consonant is not the last one, Uniscribe
-            // moves the halant from the base consonant to the last
-            // one.
-            if (lastConsonant > base) {
-                int halantPos = 0;
-                if (uc[base+1] == halant)
-                    halantPos = base + 1;
-                else if (uc[base+1] == nukta && uc[base+2] == halant)
-                    halantPos = base + 2;
-                if (halantPos > 0) {
-                    IDEBUG("    moving halant from %d to %d!", base+1, lastConsonant);
-                    for (i = halantPos; i < lastConsonant; i++)
-                        uc[i] = uc[i+1];
-                    uc[lastConsonant] = halant;
-                }
-            }
-
-            // Rule 3:
-            //
-            // If the syllable starts with Ra + H, Uniscribe moves
-            // this combination so that it follows either:
-
-            // * the post-base 'matra' (if any) or the base consonant
-            //   (in scripts that show similarity to Devanagari, i.e.,
-            //   Devanagari, Gujarati, Bengali)
-            // * the base consonant (other scripts)
-            // * the end of the syllable (Kannada)
-
-            Position matra_position = None;
-            if (matra > 0)
-                matra_position = indic_position(uc[matra]);
-            IDEBUG("    matra at %d with form %d, base=%d", matra, matra_position, base);
-
-            if (beginsWithRa && base != 0) {
-                int toPos = base+1;
-                if (toPos < len && uc[toPos] == nukta)
-                    toPos++;
-                if (toPos < len && uc[toPos] == halant)
-                    toPos++;
-                if (toPos < len && uc[toPos] == 0x200d)
-                    toPos++;
-                if (toPos < len-1 && uc[toPos] == ra && uc[toPos+1] == halant)
-                    toPos += 2;
-                if (script == HB_Script_Devanagari || script == HB_Script_Gujarati || script == HB_Script_Bengali) {
-                    if (matra_position == Post || matra_position == Split) {
-                        toPos = matra+1;
-                        matra -= 2;
-                    }
-                } else if (script == HB_Script_Kannada) {
-                    toPos = len;
-                    matra -= 2;
-                }
-
-                IDEBUG("moving leading ra+halant to position %d", toPos);
-                for (i = 2; i < toPos; i++)
-                    uc[i-2] = uc[i];
-                uc[toPos-2] = ra;
-                uc[toPos-1] = halant;
-                base -= 2;
-                if (properties & HasReph)
-                    reph = toPos-2;
-            }
-
-            // Rule 4:
-
-            // Uniscribe splits two- or three-part matras into their
-            // parts. This splitting is a character-to-character
-            // operation).
-            //
-            //      Uniscribe describes some moving operations for these
-            //      matras here. For shaping however all pre matras need
-            //      to be at the beginning of the syllable, so we just move
-            //      them there now.
-            if (matra_position == Split) {
-                splitMatra(uc, matra, len);
-                // Handle three-part matras (0xccb in Kannada)
-                matra_position = indic_position(uc[matra]);
-            }
-
-            if (matra_position == Pre) {
-                unsigned short m = uc[matra];
-                while (matra--)
-                    uc[matra+1] = uc[matra];
-                uc[0] = m;
-                base++;
-            }
-        }
-
-        // Rule 5:
-        //
-        // Uniscribe classifies consonants and 'matra' parts as
-        // pre-base, above-base (Reph), below-base or post-base. This
-        // classification exists on the character code level and is
-        // language-dependent, not font-dependent.
-        for (i = 0; i < base; ++i)
-            position[i] = Pre;
-        position[base] = Base;
-        for (i = base+1; i < len; ++i) {
-            position[i] = indic_position(uc[i]);
-            // #### replace by adjusting table
-            if (uc[i] == nukta || uc[i] == halant)
-                position[i] = Inherit;
-        }
-        if (reph > 0) {
-            // recalculate reph, it might have changed.
-            for (i = base+1; i < len; ++i)
-                if (uc[i] == ra)
-                    reph = i;
-            position[reph] = Reph;
-            position[reph+1] = Inherit;
-        }
-
-        // all reordering happens now to the chars after the base
-        int fixed = base+1;
-        if (fixed < len && uc[fixed] == nukta)
-            fixed++;
-        if (fixed < len && uc[fixed] == halant)
-            fixed++;
-        if (fixed < len && uc[fixed] == 0x200d)
-            fixed++;
-
-#ifdef INDIC_DEBUG
-        for (i = fixed; i < len; ++i)
-            IDEBUG("position[%d] = %d, form=%d uc=%x", i, position[i], form(uc[i]), uc[i]);
-#endif
-        // we continuosly position the matras and vowel marks and increase the fixed
-        // until we reached the end.
-        const IndicOrdering *finalOrder = indic_order[script-HB_Script_Devanagari];
-
-        IDEBUG("    reordering pass:");
-        IDEBUG("        base=%d fixed=%d", base, fixed);
-        int toMove = 0;
-        while (finalOrder[toMove].form && fixed < len-1) {
-            IDEBUG("        fixed = %d, toMove=%d, moving form %d with pos %d", fixed, toMove, finalOrder[toMove].form, finalOrder[toMove].position);
-            for (i = fixed; i < len; i++) {
-//                IDEBUG() << "           i=" << i << "uc=" << hex << uc[i] << "form=" << form(uc[i])
-//                         << "position=" << position[i];
-                if (form(uc[i]) == finalOrder[toMove].form &&
-                     position[i] == finalOrder[toMove].position) {
-                    // need to move this glyph
-                    int to = fixed;
-                    if (i < len-1 && position[i+1] == Inherit) {
-                        IDEBUG("         moving two chars from %d to %d", i, to);
-                        unsigned short ch = uc[i];
-                        unsigned short ch2 = uc[i+1];
-                        unsigned char pos = position[i];
-                        for (int j = i+1; j > to+1; j--) {
-                            uc[j] = uc[j-2];
-                            position[j] = position[j-2];
-                        }
-                        uc[to] = ch;
-                        uc[to+1] = ch2;
-                        position[to] = pos;
-                        position[to+1] = pos;
-                        fixed += 2;
-                    } else {
-                        IDEBUG("         moving one char from %d to %d", i, to);
-                        unsigned short ch = uc[i];
-                        unsigned char pos = position[i];
-                        for (int j = i; j > to; j--) {
-                            uc[j] = uc[j-1];
-                            position[j] = position[j-1];
-                        }
-                        uc[to] = ch;
-                        position[to] = pos;
-                        fixed++;
-                    }
-                }
-            }
-            toMove++;
-        }
-
-    }
-
-    if (reph > 0) {
-        // recalculate reph, it might have changed.
-        for (i = base+1; i < len; ++i)
-            if (reordered[i] == ra)
-                reph = i;
-    }
-
-#ifndef NO_OPENTYPE
-    const int availableGlyphs = item->num_glyphs;
-#endif
-    if (!item->font->klass->convertStringToGlyphIndices(item->font,
-                                                        reordered, len,
-                                                        item->glyphs, &item->num_glyphs,
-                                                        item->item.bidiLevel % 2))
-        goto error;
-
-
-    IDEBUG("  base=%d, reph=%d", base, reph);
-    IDEBUG("reordered:");
-    for (i = 0; i < len; i++) {
-        item->attributes[i].mark = false;
-        item->attributes[i].clusterStart = false;
-        item->attributes[i].justification = 0;
-        item->attributes[i].zeroWidth = false;
-        IDEBUG("    %d: %4x", i, reordered[i]);
-    }
-
-    // now we have the syllable in the right order, and can start running it through open type.
-
-    for (i = 0; i < len; ++i)
-        control |= (form(reordered[i]) == Control);
-
-#ifndef NO_OPENTYPE
-    if (openType) {
-
-        // we need to keep track of where the base glyph is for some
-        // scripts and use the cluster feature for this.  This
-        // also means we have to correct the logCluster output from
-        // the open type engine manually afterwards.  for indic this
-        // is rather simple, as all chars just point to the first
-        // glyph in the syllable.
-        HB_STACKARRAY(unsigned short, clusters, len);
-        HB_STACKARRAY(unsigned int, properties, len);
-
-        for (i = 0; i < len; ++i)
-            clusters[i] = i;
-
-        // features we should always apply
-        for (i = 0; i < len; ++i)
-            properties[i] = ~(CcmpProperty
-                              | NuktaProperty
-                              | VattuProperty
-                              | PreSubstProperty
-                              | BelowSubstProperty
-                              | AboveSubstProperty
-                              | PostSubstProperty
-                              | HalantProperty
-                              | PositioningProperties);
-
-        // Ccmp always applies
-        // Init
-        if (item->item.pos == 0
-            || !(isLetter(item->string[item->item.pos-1]) || isMark(item->string[item->item.pos-1])))
-            properties[0] &= ~InitProperty;
-
-        // Nukta always applies
-        // Akhant
-        for (i = 0; i <= base; ++i)
-            properties[i] &= ~AkhantProperty;
-        // Reph
-        if (reph >= 0) {
-            properties[reph] &= ~RephProperty;
-            properties[reph+1] &= ~RephProperty;
-        }
-        // BelowForm
-        for (i = base+1; i < len; ++i)
-            properties[i] &= ~BelowFormProperty;
-
-        if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) {
-            // vattu glyphs need this aswell
-            bool vattu = false;
-            for (i = base-2; i > 1; --i) {
-                if (form(reordered[i]) == Consonant) {
-                    vattu = (!vattu && reordered[i] == ra);
-                    if (vattu) {
-                        IDEBUG("forming vattu ligature at %d", i);
-                        properties[i] &= ~BelowFormProperty;
-                        properties[i+1] &= ~BelowFormProperty;
-                    }
-                }
-            }
-        }
-        // HalfFormProperty
-        for (i = 0; i < base; ++i)
-            properties[i] &= ~HalfFormProperty;
-        if (control) {
-            for (i = 2; i < len; ++i) {
-                if (reordered[i] == 0x200d /* ZWJ */) {
-                    properties[i-1] &= ~HalfFormProperty;
-                    properties[i-2] &= ~HalfFormProperty;
-                } else if (reordered[i] == 0x200c /* ZWNJ */) {
-                    properties[i-1] &= ~HalfFormProperty;
-                    properties[i-2] &= ~HalfFormProperty;
-                }
-            }
-        }
-        // PostFormProperty
-        for (i = base+1; i < len; ++i)
-            properties[i] &= ~PostFormProperty;
-        // vattu always applies
-        // pres always applies
-        // blws always applies
-        // abvs always applies
-        // psts always applies
-        // halant always applies
-
-#ifdef INDIC_DEBUG
-//        {
-//            IDEBUG("OT properties:");
-//            for (int i = 0; i < len; ++i)
-//                qDebug("    i: %s", ::propertiesToString(properties[i]).toLatin1().data());
-//        }
-#endif
-
-        // initialize
-        item->log_clusters = clusters;
-        HB_OpenTypeShape(item, properties);
-
-        int newLen = item->face->buffer->in_length;
-        HB_GlyphItem otl_glyphs = item->face->buffer->in_string;
-
-        // move the left matra back to its correct position in malayalam and tamil
-        if ((script == HB_Script_Malayalam || script == HB_Script_Tamil) && (form(reordered[0]) == Matra)) {
-//             qDebug("reordering matra, len=%d", newLen);
-            // need to find the base in the shaped string and move the matra there
-            int basePos = 0;
-            while (basePos < newLen && (int)otl_glyphs[basePos].cluster <= base)
-                basePos++;
-            --basePos;
-            if (basePos < newLen && basePos > 1) {
-//                 qDebug("moving prebase matra to position %d in syllable newlen=%d", basePos, newLen);
-                HB_GlyphItemRec m = otl_glyphs[0];
-                --basePos;
-                for (i = 0; i < basePos; ++i)
-                    otl_glyphs[i] = otl_glyphs[i+1];
-                otl_glyphs[basePos] = m;
-            }
-        }
-
-        HB_Bool positioned = HB_OpenTypePosition(item, availableGlyphs, false);
-
-        HB_FREE_STACKARRAY(clusters);
-        HB_FREE_STACKARRAY(properties);
-
-        if (!positioned)
-            goto error;
-
-        if (control) {
-            IDEBUG("found a control char in the syllable");
-            hb_uint32 i = 0, j = 0;
-            while (i < item->num_glyphs) {
-                if (form(reordered[otl_glyphs[i].cluster]) == Control) {
-                    ++i;
-                    if (i >= item->num_glyphs)
-                        break;
-                }
-                item->glyphs[j] = item->glyphs[i];
-                item->attributes[j] = item->attributes[i];
-                ++i;
-                ++j;
-            }
-            item->num_glyphs = j;
-        }
-
-    } else {
-        HB_HeuristicPosition(item);
-    }
-#endif // NO_OPENTYPE
-    item->attributes[0].clusterStart = true;
-
-    HB_FREE_STACKARRAY(reordered);
-    HB_FREE_STACKARRAY(position);
-
-    IDEBUG("<<<<<<");
-    return true;
-
-error:
-    HB_FREE_STACKARRAY(reordered);
-    HB_FREE_STACKARRAY(position);
-    return false;
-}
-
-/* syllables are of the form:
-
-   (Consonant Nukta? Halant)* Consonant Matra? VowelMark? StressMark?
-   (Consonant Nukta? Halant)* Consonant Halant
-   IndependentVowel VowelMark? StressMark?
-
-   We return syllable boundaries on invalid combinations aswell
-*/
-static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int start, int end, bool *invalid)
-{
-    *invalid = false;
-    IDEBUG("indic_nextSyllableBoundary: start=%d, end=%d", start, end);
-    const HB_UChar16 *uc = s+start;
-
-    int pos = 0;
-    Form state = form(uc[pos]);
-    IDEBUG("state[%d]=%d (uc=%4x)", pos, state, uc[pos]);
-    pos++;
-
-    if (state != Consonant && state != IndependentVowel) {
-        if (state != Other)
-            *invalid = true;
-        goto finish;
-    }
-
-    while (pos < end - start) {
-        Form newState = form(uc[pos]);
-        IDEBUG("state[%d]=%d (uc=%4x)", pos, newState, uc[pos]);
-        switch(newState) {
-        case Control:
-            newState = state;
- 	    if (state == Halant && uc[pos] == 0x200d /* ZWJ */)
-  		break;
-            // the control character should be the last char in the item
-            ++pos;
-            goto finish;
-        case Consonant:
-	    if (state == Halant && (script != HB_Script_Sinhala || uc[pos-1] == 0x200d /* ZWJ */))
-                break;
-            goto finish;
-        case Halant:
-            if (state == Nukta || state == Consonant)
-                break;
-            // Bengali has a special exception allowing the combination Vowel_A/E + Halant + Ya
-            if (script == HB_Script_Bengali && pos == 1 &&
-                 (uc[0] == 0x0985 || uc[0] == 0x098f))
-                break;
-            // Sinhala uses the Halant as a component of certain matras. Allow these, but keep the state on Matra.
-            if (script == HB_Script_Sinhala && state == Matra) {
-                ++pos;
-                continue;
-            }
-            if (script == HB_Script_Malayalam && state == Matra && uc[pos-1] == 0x0d41) {
-                ++pos;
-                continue;
-            }
-            goto finish;
-        case Nukta:
-            if (state == Consonant)
-                break;
-            goto finish;
-        case StressMark:
-            if (state == VowelMark)
-                break;
-            // fall through
-        case VowelMark:
-            if (state == Matra || state == LengthMark || state == IndependentVowel)
-                break;
-            // fall through
-        case Matra:
-            if (state == Consonant || state == Nukta)
-                break;
-            if (state == Matra) {
-                // ### needs proper testing for correct two/three part matras
-                break;
-            }
-            // ### not sure if this is correct. If it is, does it apply only to Bengali or should
-            // it work for all Indic languages?
-            // the combination Independent_A + Vowel Sign AA is allowed.
-            if (script == HB_Script_Bengali && uc[pos] == 0x9be && uc[pos-1] == 0x985)
-                break;
-            if (script == HB_Script_Tamil && state == Matra) {
-                if (uc[pos-1] == 0x0bc6 &&
-                     (uc[pos] == 0xbbe || uc[pos] == 0xbd7))
-                    break;
-                if (uc[pos-1] == 0x0bc7 && uc[pos] == 0xbbe)
-                    break;
-            }
-            goto finish;
-
-        case LengthMark:
-            if (state == Matra) {
-                // ### needs proper testing for correct two/three part matras
-                break;
-            }
-        case IndependentVowel:
-        case Invalid:
-        case Other:
-            goto finish;
-        }
-        state = newState;
-        pos++;
-    }
- finish:
-    return pos+start;
-}
-
-HB_Bool HB_IndicShape(HB_ShaperItem *item)
-{
-    assert(item->item.script >= HB_Script_Devanagari && item->item.script <= HB_Script_Sinhala);
-
-    HB_Bool openType = false;
-#ifndef NO_OPENTYPE
-    openType = HB_SelectScript(item, indic_features);
-#endif
-    unsigned short *logClusters = item->log_clusters;
-
-    HB_ShaperItem syllable = *item;
-    int first_glyph = 0;
-
-    int sstart = item->item.pos;
-    int end = sstart + item->item.length;
-    IDEBUG("indic_shape: from %d length %d", item->item.pos, item->item.length);
-    while (sstart < end) {
-        bool invalid;
-        int send = indic_nextSyllableBoundary(item->item.script, item->string, sstart, end, &invalid);
-        IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
-               invalid ? "true" : "false");
-        syllable.item.pos = sstart;
-        syllable.item.length = send-sstart;
-        syllable.glyphs = item->glyphs + first_glyph;
-        syllable.attributes = item->attributes + first_glyph;
-        syllable.offsets = item->offsets + first_glyph;
-        syllable.advances = item->advances + first_glyph;
-        syllable.num_glyphs = item->num_glyphs - first_glyph;
-        if (!indic_shape_syllable(openType, &syllable, invalid)) {
-            IDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
-            item->num_glyphs += syllable.num_glyphs;
-            return false;
-        }
-        // fix logcluster array
-        IDEBUG("syllable:");
-        hb_uint32 g;
-        for (g = first_glyph; g < first_glyph + syllable.num_glyphs; ++g)
-            IDEBUG("        %d -> glyph %x", g, item->glyphs[g]);
-        IDEBUG("    logclusters:");
-        int i;
-        for (i = sstart; i < send; ++i) {
-            IDEBUG("        %d -> glyph %d", i, first_glyph);
-            logClusters[i-item->item.pos] = first_glyph;
-        }
-        sstart = send;
-        first_glyph += syllable.num_glyphs;
-    }
-    item->num_glyphs = first_glyph;
-    return true;
-}
-
-void HB_IndicAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
-{
-    int end = from + len;
-    const HB_UChar16 *uc = text + from;
-    attributes += from;
-    hb_uint32 i = 0;
-    while (i < len) {
-        bool invalid;
-        hb_uint32 boundary = indic_nextSyllableBoundary(script, text, from+i, end, &invalid) - from;
-         attributes[i].charStop = true;
-
-        if (boundary > len-1) boundary = len;
-        i++;
-        while (i < boundary) {
-            attributes[i].charStop = false;
-            ++uc;
-            ++i;
-        }
-        assert(i == boundary);
-    }
-
-
-}
-
-
diff --git a/third_party/harfbuzz/src/harfbuzz-khmer.c b/third_party/harfbuzz/src/harfbuzz-khmer.c
deleted file mode 100644
index 958069e..0000000
--- a/third_party/harfbuzz/src/harfbuzz-khmer.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-/*
-//  Vocabulary
-//      Base ->         A consonant or an independent vowel in its full (not subscript) form. It is the
-//                      center of the syllable, it can be surrounded by coeng (subscript) consonants, vowels,
-//                      split vowels, signs... but there is only one base in a syllable, it has to be coded as
-//                      the first character of the syllable.
-//      split vowel --> vowel that has two parts placed separately (e.g. Before and after the consonant).
-//                      Khmer language has five of them. Khmer split vowels either have one part before the
-//                      base and one after the base or they have a part before the base and a part above the base.
-//                      The first part of all Khmer split vowels is the same character, identical to
-//                      the glyph of Khmer dependent vowel SRA EI
-//      coeng -->  modifier used in Khmer to construct coeng (subscript) consonants
-//                 Differently than indian languages, the coeng modifies the consonant that follows it,
-//                 not the one preceding it  Each consonant has two forms, the base form and the subscript form
-//                 the base form is the normal one (using the consonants code-point), the subscript form is
-//                 displayed when the combination coeng + consonant is encountered.
-//      Consonant of type 1 -> A consonant which has subscript for that only occupies space under a base consonant
-//      Consonant of type 2.-> Its subscript form occupies space under and before the base (only one, RO)
-//      Consonant of Type 3 -> Its subscript form occupies space under and after the base (KHO, CHHO, THHO, BA, YO, SA)
-//      Consonant shifter -> Khmer has to series of consonants. The same dependent vowel has different sounds
-//                           if it is attached to a consonant of the first series or a consonant of the second series
-//                           Most consonants have an equivalent in the other series, but some of theme exist only in
-//                           one series (for example SA). If we want to use the consonant SA with a vowel sound that
-//                           can only be done with a vowel sound that corresponds to a vowel accompanying a consonant
-//                           of the other series, then we need to use a consonant shifter: TRIISAP or MUSIKATOAN
-//                           x17C9 y x17CA. TRIISAP changes a first series consonant to second series sound and
-//                           MUSIKATOAN a second series consonant to have a first series vowel sound.
-//                           Consonant shifter are both normally supercript marks, but, when they are followed by a
-//                           superscript, they change shape and take the form of subscript dependent vowel SRA U.
-//                           If they are in the same syllable as a coeng consonant, Unicode 3.0 says that they
-//                           should be typed before the coeng. Unicode 4.0 breaks the standard and says that it should
-//                           be placed after the coeng consonant.
-//      Dependent vowel ->   In khmer dependent vowels can be placed above, below, before or after the base
-//                           Each vowel has its own position. Only one vowel per syllable is allowed.
-//      Signs            ->  Khmer has above signs and post signs. Only one above sign and/or one post sign are
-//                           Allowed in a syllable.
-//
-//
-//   order is important here! This order must be the same that is found in each horizontal
-//   line in the statetable for Khmer (see khmerStateTable) .
-*/
-enum KhmerCharClassValues {
-    CC_RESERVED             =  0,
-    CC_CONSONANT            =  1, /* Consonant of type 1 or independent vowel */
-    CC_CONSONANT2           =  2, /* Consonant of type 2 */
-    CC_CONSONANT3           =  3, /* Consonant of type 3 */
-    CC_ZERO_WIDTH_NJ_MARK   =  4, /* Zero Width non joiner character (0x200C) */
-    CC_CONSONANT_SHIFTER    =  5,
-    CC_ROBAT                =  6, /* Khmer special diacritic accent -treated differently in state table */
-    CC_COENG                =  7, /* Subscript consonant combining character */
-    CC_DEPENDENT_VOWEL      =  8,
-    CC_SIGN_ABOVE           =  9,
-    CC_SIGN_AFTER           = 10,
-    CC_ZERO_WIDTH_J_MARK    = 11, /* Zero width joiner character */
-    CC_COUNT                = 12  /* This is the number of character classes */
-};
-
-
-enum KhmerCharClassFlags {
-    CF_CLASS_MASK    = 0x0000FFFF,
-
-    CF_CONSONANT     = 0x01000000,  /* flag to speed up comparing */
-    CF_SPLIT_VOWEL   = 0x02000000,  /* flag for a split vowel -> the first part is added in front of the syllable */
-    CF_DOTTED_CIRCLE = 0x04000000,  /* add a dotted circle if a character with this flag is the first in a syllable */
-    CF_COENG         = 0x08000000,  /* flag to speed up comparing */
-    CF_SHIFTER       = 0x10000000,  /* flag to speed up comparing */
-    CF_ABOVE_VOWEL   = 0x20000000,  /* flag to speed up comparing */
-
-    /* position flags */
-    CF_POS_BEFORE    = 0x00080000,
-    CF_POS_BELOW     = 0x00040000,
-    CF_POS_ABOVE     = 0x00020000,
-    CF_POS_AFTER     = 0x00010000,
-    CF_POS_MASK      = 0x000f0000
-};
-
-
-/* Characters that get referred to by name */
-enum KhmerChar {
-    C_SIGN_ZWNJ     = 0x200C,
-    C_SIGN_ZWJ      = 0x200D,
-    C_RO            = 0x179A,
-    C_VOWEL_AA      = 0x17B6,
-    C_SIGN_NIKAHIT  = 0x17C6,
-    C_VOWEL_E       = 0x17C1,
-    C_COENG         = 0x17D2
-};
-
-
-/*
-//  simple classes, they are used in the statetable (in this file) to control the length of a syllable
-//  they are also used to know where a character should be placed (location in reference to the base character)
-//  and also to know if a character, when independently displayed, should be displayed with a dotted-circle to
-//  indicate error in syllable construction
-*/
-enum {
-    _xx = CC_RESERVED,
-    _sa = CC_SIGN_ABOVE | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
-    _sp = CC_SIGN_AFTER | CF_DOTTED_CIRCLE| CF_POS_AFTER,
-    _c1 = CC_CONSONANT | CF_CONSONANT,
-    _c2 = CC_CONSONANT2 | CF_CONSONANT,
-    _c3 = CC_CONSONANT3 | CF_CONSONANT,
-    _rb = CC_ROBAT | CF_POS_ABOVE | CF_DOTTED_CIRCLE,
-    _cs = CC_CONSONANT_SHIFTER | CF_DOTTED_CIRCLE | CF_SHIFTER,
-    _dl = CC_DEPENDENT_VOWEL | CF_POS_BEFORE | CF_DOTTED_CIRCLE,
-    _db = CC_DEPENDENT_VOWEL | CF_POS_BELOW | CF_DOTTED_CIRCLE,
-    _da = CC_DEPENDENT_VOWEL | CF_POS_ABOVE | CF_DOTTED_CIRCLE | CF_ABOVE_VOWEL,
-    _dr = CC_DEPENDENT_VOWEL | CF_POS_AFTER | CF_DOTTED_CIRCLE,
-    _co = CC_COENG | CF_COENG | CF_DOTTED_CIRCLE,
-
-    /* split vowel */
-    _va = _da | CF_SPLIT_VOWEL,
-    _vr = _dr | CF_SPLIT_VOWEL
-};
-
-
-/*
-//   Character class: a character class value
-//   ORed with character class flags.
-*/
-typedef unsigned long KhmerCharClass;
-
-
-/*
-//  Character class tables
-//  _xx character does not combine into syllable, such as numbers, puntuation marks, non-Khmer signs...
-//  _sa Sign placed above the base
-//  _sp Sign placed after the base
-//  _c1 Consonant of type 1 or independent vowel (independent vowels behave as type 1 consonants)
-//  _c2 Consonant of type 2 (only RO)
-//  _c3 Consonant of type 3
-//  _rb Khmer sign robat u17CC. combining mark for subscript consonants
-//  _cd Consonant-shifter
-//  _dl Dependent vowel placed before the base (left of the base)
-//  _db Dependent vowel placed below the base
-//  _da Dependent vowel placed above the base
-//  _dr Dependent vowel placed behind the base (right of the base)
-//  _co Khmer combining mark COENG u17D2, combines with the consonant or independent vowel following
-//      it to create a subscript consonant or independent vowel
-//  _va Khmer split vowel in which the first part is before the base and the second one above the base
-//  _vr Khmer split vowel in which the first part is before the base and the second one behind (right of) the base
-*/
-static const KhmerCharClass khmerCharClasses[] = {
-    _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, /* 1780 - 178F */
-    _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c2, _c1, _c1, _c1, _c3, _c3, /* 1790 - 179F */
-    _c1, _c3, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, /* 17A0 - 17AF */
-    _c1, _c1, _c1, _c1, _dr, _dr, _dr, _da, _da, _da, _da, _db, _db, _db, _va, _vr, /* 17B0 - 17BF */
-    _vr, _dl, _dl, _dl, _vr, _vr, _sa, _sp, _sp, _cs, _cs, _sa, _rb, _sa, _sa, _sa, /* 17C0 - 17CF */
-    _sa, _sa, _co, _sa, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _sa, _xx, _xx  /* 17D0 - 17DF */
-};
-
-/* this enum must reflect the range of khmerCharClasses */
-enum KhmerCharClassesRange {
-    KhmerFirstChar = 0x1780,
-    KhmerLastChar  = 0x17df
-};
-
-/*
-//  Below we define how a character in the input string is either in the khmerCharClasses table
-//  (in which case we get its type back), a ZWJ or ZWNJ (two characters that may appear
-//  within the syllable, but are not in the table) we also get their type back, or an unknown object
-//  in which case we get _xx (CC_RESERVED) back
-*/
-static KhmerCharClass getKhmerCharClass(HB_UChar16 uc)
-{
-    if (uc == C_SIGN_ZWJ) {
-        return CC_ZERO_WIDTH_J_MARK;
-    }
-
-    if (uc == C_SIGN_ZWNJ) {
-        return CC_ZERO_WIDTH_NJ_MARK;
-    }
-
-    if (uc < KhmerFirstChar || uc > KhmerLastChar) {
-        return CC_RESERVED;
-    }
-
-    return khmerCharClasses[uc - KhmerFirstChar];
-}
-
-
-/*
-//  The stateTable is used to calculate the end (the length) of a well
-//  formed Khmer Syllable.
-//
-//  Each horizontal line is ordered exactly the same way as the values in KhmerClassTable
-//  CharClassValues. This coincidence of values allows the follow up of the table.
-//
-//  Each line corresponds to a state, which does not necessarily need to be a type
-//  of component... for example, state 2 is a base, with is always a first character
-//  in the syllable, but the state could be produced a consonant of any type when
-//  it is the first character that is analysed (in ground state).
-//
-//  Differentiating 3 types of consonants is necessary in order to
-//  forbid the use of certain combinations, such as having a second
-//  coeng after a coeng RO,
-//  The inexistent possibility of having a type 3 after another type 3 is permitted,
-//  eliminating it would very much complicate the table, and it does not create typing
-//  problems, as the case above.
-//
-//  The table is quite complex, in order to limit the number of coeng consonants
-//  to 2 (by means of the table).
-//
-//  There a peculiarity, as far as Unicode is concerned:
-//  - The consonant-shifter is considered in two possible different
-//    locations, the one considered in Unicode 3.0 and the one considered in
-//    Unicode 4.0. (there is a backwards compatibility problem in this standard).
-//
-//
-//  xx    independent character, such as a number, punctuation sign or non-khmer char
-//
-//  c1    Khmer consonant of type 1 or an independent vowel
-//        that is, a letter in which the subscript for is only under the
-//        base, not taking any space to the right or to the left
-//
-//  c2    Khmer consonant of type 2, the coeng form takes space under
-//        and to the left of the base (only RO is of this type)
-//
-//  c3    Khmer consonant of type 3. Its subscript form takes space under
-//        and to the right of the base.
-//
-//  cs    Khmer consonant shifter
-//
-//  rb    Khmer robat
-//
-//  co    coeng character (u17D2)
-//
-//  dv    dependent vowel (including split vowels, they are treated in the same way).
-//        even if dv is not defined above, the component that is really tested for is
-//        KhmerClassTable::CC_DEPENDENT_VOWEL, which is common to all dependent vowels
-//
-//  zwj   Zero Width joiner
-//
-//  zwnj  Zero width non joiner
-//
-//  sa    above sign
-//
-//  sp    post sign
-//
-//  there are lines with equal content but for an easier understanding
-//  (and maybe change in the future) we did not join them
-*/
-static const signed char khmerStateTable[][CC_COUNT] =
-{
-    /* xx  c1  c2  c3 zwnj cs  rb  co  dv  sa  sp zwj */
-    { 1,  2,  2,  2,  1,  1,  1,  6,  1,  1,  1,  2}, /*  0 - ground state */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /*  1 - exit state (or sign to the right of the syllable) */
-    {-1, -1, -1, -1,  3,  4,  5,  6, 16, 17,  1, -1}, /*  2 - Base consonant */
-    {-1, -1, -1, -1, -1,  4, -1, -1, 16, -1, -1, -1}, /*  3 - First ZWNJ before a register shifter It can only be followed by a shifter or a vowel */
-    {-1, -1, -1, -1, 15, -1, -1,  6, 16, 17,  1, 14}, /*  4 - First register shifter */
-    {-1, -1, -1, -1, -1, -1, -1, -1, 20, -1,  1, -1}, /*  5 - Robat */
-    {-1,  7,  8,  9, -1, -1, -1, -1, -1, -1, -1, -1}, /*  6 - First Coeng */
-    {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17,  1, 14}, /*  7 - First consonant of type 1 after coeng */
-    {-1, -1, -1, -1, 12, 13, -1, -1, 16, 17,  1, 14}, /*  8 - First consonant of type 2 after coeng */
-    {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17,  1, 14}, /*  9 - First consonant or type 3 after ceong */
-    {-1, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1}, /* 10 - Second Coeng (no register shifter before) */
-    {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17,  1, 14}, /* 11 - Second coeng consonant (or ind. vowel) no register shifter before */
-    {-1, -1, -1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, /* 12 - Second ZWNJ before a register shifter */
-    {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17,  1, 14}, /* 13 - Second register shifter */
-    {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 14 - ZWJ before vowel */
-    {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 15 - ZWNJ before vowel */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, 17,  1, 18}, /* 16 - dependent vowel */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1, 18}, /* 17 - sign above */
-    {-1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1}, /* 18 - ZWJ after vowel */
-    {-1,  1, -1,  1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19 - Third coeng */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1, -1}, /* 20 - dependent vowel after a Robat */
-};
-
-
-/*  #define KHMER_DEBUG */
-#ifdef KHMER_DEBUG
-#define KHDEBUG qDebug
-#else
-#define KHDEBUG if(0) printf
-#endif
-
-/*
-//  Given an input string of characters and a location in which to start looking
-//  calculate, using the state table, which one is the last character of the syllable
-//  that starts in the starting position.
-*/
-static int khmer_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid)
-{
-    const HB_UChar16 *uc = s + start;
-    int state = 0;
-    int pos = start;
-    *invalid = FALSE;
-
-    while (pos < end) {
-        KhmerCharClass charClass = getKhmerCharClass(*uc);
-        if (pos == start) {
-            *invalid = (charClass > 0) && ! (charClass & CF_CONSONANT);
-        }
-        state = khmerStateTable[state][charClass & CF_CLASS_MASK];
-
-        KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", pos - start, state,
-                charClass, *uc );
-
-        if (state < 0) {
-            break;
-        }
-        ++uc;
-        ++pos;
-    }
-    return pos;
-}
-
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature khmer_features[] = {
-    { HB_MAKE_TAG( 'p', 'r', 'e', 'f' ), PreFormProperty },
-    { HB_MAKE_TAG( 'b', 'l', 'w', 'f' ), BelowFormProperty },
-    { HB_MAKE_TAG( 'a', 'b', 'v', 'f' ), AboveFormProperty },
-    { HB_MAKE_TAG( 'p', 's', 't', 'f' ), PostFormProperty },
-    { HB_MAKE_TAG( 'p', 'r', 'e', 's' ), PreSubstProperty },
-    { HB_MAKE_TAG( 'b', 'l', 'w', 's' ), BelowSubstProperty },
-    { HB_MAKE_TAG( 'a', 'b', 'v', 's' ), AboveSubstProperty },
-    { HB_MAKE_TAG( 'p', 's', 't', 's' ), PostSubstProperty },
-    { HB_MAKE_TAG( 'c', 'l', 'i', 'g' ), CligProperty },
-    { 0, 0 }
-};
-#endif
-
-
-static HB_Bool khmer_shape_syllable(HB_Bool openType, HB_ShaperItem *item)
-{
-/*    KHDEBUG("syllable from %d len %d, str='%s'", item->from, item->length,
-  	    item->string->mid(item->from, item->length).toUtf8().data()); */
-
-    int len = 0;
-    int syllableEnd = item->item.pos + item->item.length;
-    unsigned short reordered[16];
-    unsigned char properties[16];
-    enum {
-	AboveForm = 0x01,
-	PreForm = 0x02,
-	PostForm = 0x04,
-	BelowForm = 0x08
-    };
-#ifndef NO_OPENTYPE
-    const int availableGlyphs = item->num_glyphs;
-#endif
-    int coengRo;
-    int i;
-
-    /* according to the specs this is the max length one can get
-       ### the real value should be smaller */
-    assert(item->item.length < 13);
-
-    memset(properties, 0, 16*sizeof(unsigned char));
-
-#ifdef KHMER_DEBUG
-    qDebug("original:");
-    for (int i = from; i < syllableEnd; i++) {
-        qDebug("    %d: %4x", i, string[i]);
-    }
-#endif
-
-    /*
-    // write a pre vowel or the pre part of a split vowel first
-    // and look out for coeng + ro. RO is the only vowel of type 2, and
-    // therefore the only one that requires saving space before the base.
-    */
-    coengRo = -1;  /* There is no Coeng Ro, if found this value will change */
-    for (i = item->item.pos; i < syllableEnd; i += 1) {
-        KhmerCharClass charClass = getKhmerCharClass(item->string[i]);
-
-        /* if a split vowel, write the pre part. In Khmer the pre part
-           is the same for all split vowels, same glyph as pre vowel C_VOWEL_E */
-        if (charClass & CF_SPLIT_VOWEL) {
-            reordered[len] = C_VOWEL_E;
-            properties[len] = PreForm;
-            ++len;
-            break; /* there can be only one vowel */
-        }
-        /* if a vowel with pos before write it out */
-        if (charClass & CF_POS_BEFORE) {
-            reordered[len] = item->string[i];
-            properties[len] = PreForm;
-            ++len;
-            break; /* there can be only one vowel */
-        }
-        /* look for coeng + ro and remember position
-           works because coeng + ro is always in front of a vowel (if there is a vowel)
-           and because CC_CONSONANT2 is enough to identify it, as it is the only consonant
-           with this flag */
-        if ( (charClass & CF_COENG) && (i + 1 < syllableEnd) &&
-              ( (getKhmerCharClass(item->string[i+1]) & CF_CLASS_MASK) == CC_CONSONANT2) ) {
-            coengRo = i;
-        }
-    }
-
-    /* write coeng + ro if found */
-    if (coengRo > -1) {
-        reordered[len] = C_COENG;
-        properties[len] = PreForm;
-        ++len;
-        reordered[len] = C_RO;
-        properties[len] = PreForm;
-        ++len;
-    }
-
-    /*
-       shall we add a dotted circle?
-       If in the position in which the base should be (first char in the string) there is
-       a character that has the Dotted circle flag (a character that cannot be a base)
-       then write a dotted circle */
-    if (getKhmerCharClass(item->string[item->item.pos]) & CF_DOTTED_CIRCLE) {
-        reordered[len] = C_DOTTED_CIRCLE;
-        ++len;
-    }
-
-    /* copy what is left to the output, skipping before vowels and
-       coeng Ro if they are present */
-    for (i = item->item.pos; i < syllableEnd; i += 1) {
-        HB_UChar16 uc = item->string[i];
-        KhmerCharClass charClass = getKhmerCharClass(uc);
-
-        /* skip a before vowel, it was already processed */
-        if (charClass & CF_POS_BEFORE) {
-            continue;
-        }
-
-        /* skip coeng + ro, it was already processed */
-        if (i == coengRo) {
-            i += 1;
-            continue;
-        }
-
-        switch (charClass & CF_POS_MASK)
-        {
-            case CF_POS_ABOVE :
-                reordered[len] = uc;
-                properties[len] = AboveForm;
-                ++len;
-                break;
-
-            case CF_POS_AFTER :
-                reordered[len] = uc;
-                properties[len] = PostForm;
-                ++len;
-                break;
-
-            case CF_POS_BELOW :
-                reordered[len] = uc;
-                properties[len] = BelowForm;
-                ++len;
-                break;
-
-            default:
-                /* assign the correct flags to a coeng consonant
-                   Consonants of type 3 are taged as Post forms and those type 1 as below forms */
-                if ( (charClass & CF_COENG) && i + 1 < syllableEnd ) {
-                    unsigned char property = (getKhmerCharClass(item->string[i+1]) & CF_CLASS_MASK) == CC_CONSONANT3 ?
-                                              PostForm : BelowForm;
-                    reordered[len] = uc;
-                    properties[len] = property;
-                    ++len;
-                    i += 1;
-                    reordered[len] = item->string[i];
-                    properties[len] = property;
-                    ++len;
-                    break;
-                }
-
-                /* if a shifter is followed by an above vowel change the shifter to below form,
-                   an above vowel can have two possible positions i + 1 or i + 3
-                   (position i+1 corresponds to unicode 3, position i+3 to Unicode 4)
-                   and there is an extra rule for C_VOWEL_AA + C_SIGN_NIKAHIT also for two
-                   different positions, right after the shifter or after a vowel (Unicode 4) */
-                if ( (charClass & CF_SHIFTER) && (i + 1 < syllableEnd) ) {
-                    if (getKhmerCharClass(item->string[i+1]) & CF_ABOVE_VOWEL ) {
-                        reordered[len] = uc;
-                        properties[len] = BelowForm;
-                        ++len;
-                        break;
-                    }
-                    if (i + 2 < syllableEnd &&
-                        (item->string[i+1] == C_VOWEL_AA) &&
-                        (item->string[i+2] == C_SIGN_NIKAHIT) )
-                    {
-                        reordered[len] = uc;
-                        properties[len] = BelowForm;
-                        ++len;
-                        break;
-                    }
-                    if (i + 3 < syllableEnd && (getKhmerCharClass(item->string[i+3]) & CF_ABOVE_VOWEL) ) {
-                        reordered[len] = uc;
-                        properties[len] = BelowForm;
-                        ++len;
-                        break;
-                    }
-                    if (i + 4 < syllableEnd &&
-                        (item->string[i+3] == C_VOWEL_AA) &&
-                        (item->string[i+4] == C_SIGN_NIKAHIT) )
-                    {
-                        reordered[len] = uc;
-                        properties[len] = BelowForm;
-                        ++len;
-                        break;
-                    }
-                }
-
-                /* default - any other characters */
-                reordered[len] = uc;
-                ++len;
-                break;
-        } /* switch */
-    } /* for */
-
-    if (!item->font->klass->convertStringToGlyphIndices(item->font,
-                                                        reordered, len,
-                                                        item->glyphs, &item->num_glyphs,
-                                                        item->item.bidiLevel % 2))
-        return FALSE;
-
-
-    KHDEBUG("after shaping: len=%d", len);
-    for (i = 0; i < len; i++) {
-	item->attributes[i].mark = FALSE;
-	item->attributes[i].clusterStart = FALSE;
-	item->attributes[i].justification = 0;
-	item->attributes[i].zeroWidth = FALSE;
-	KHDEBUG("    %d: %4x property=%x", i, reordered[i], properties[i]);
-    }
-
-    /* now we have the syllable in the right order, and can start running it through open type. */
-
-#ifndef NO_OPENTYPE
-    if (openType) {
- 	hb_uint32 where[16];
-        for (i = 0; i < len; ++i) {
-            where[i] = ~(PreSubstProperty
-                         | BelowSubstProperty
-                         | AboveSubstProperty
-                         | PostSubstProperty
-                         | CligProperty
-                         | PositioningProperties);
-            if (properties[i] == PreForm)
-                where[i] &= ~PreFormProperty;
-            else if (properties[i] == BelowForm)
-                where[i] &= ~BelowFormProperty;
-            else if (properties[i] == AboveForm)
-                where[i] &= ~AboveFormProperty;
-            else if (properties[i] == PostForm)
-                where[i] &= ~PostFormProperty;
-        }
-
-        HB_OpenTypeShape(item, where);
-        if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE))
-            return FALSE;
-    } else
-#endif
-    {
-	KHDEBUG("Not using openType");
-        HB_HeuristicPosition(item);
-    }
-
-    item->attributes[0].clusterStart = TRUE;
-    return TRUE;
-}
-
-HB_Bool HB_KhmerShape(HB_ShaperItem *item)
-{
-    HB_Bool openType = FALSE;
-    unsigned short *logClusters = item->log_clusters;
-    int i;
-
-    HB_ShaperItem syllable = *item;
-    int first_glyph = 0;
-
-    int sstart = item->item.pos;
-    int end = sstart + item->item.length;
-
-    assert(item->item.script == HB_Script_Khmer);
-
-#ifndef NO_OPENTYPE
-    openType = HB_SelectScript(item, khmer_features);
-#endif
-
-    KHDEBUG("khmer_shape: from %d length %d", item->item.pos, item->item.length);
-    while (sstart < end) {
-        HB_Bool invalid;
-        int send = khmer_nextSyllableBoundary(item->string, sstart, end, &invalid);
-        KHDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
-               invalid ? "TRUE" : "FALSE");
-        syllable.item.pos = sstart;
-        syllable.item.length = send-sstart;
-        syllable.glyphs = item->glyphs + first_glyph;
-        syllable.attributes = item->attributes + first_glyph;
-        syllable.offsets = item->offsets + first_glyph;
-        syllable.advances = item->advances + first_glyph;
-        syllable.num_glyphs = item->num_glyphs - first_glyph;
-        if (!khmer_shape_syllable(openType, &syllable)) {
-            KHDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
-            item->num_glyphs += syllable.num_glyphs;
-            return FALSE;
-        }
-        /* fix logcluster array */
-        KHDEBUG("syllable:");
-        for (i = first_glyph; i < first_glyph + (int)syllable.num_glyphs; ++i)
-            KHDEBUG("        %d -> glyph %x", i, item->glyphs[i]);
-        KHDEBUG("    logclusters:");
-        for (i = sstart; i < send; ++i) {
-            KHDEBUG("        %d -> glyph %d", i, first_glyph);
-            logClusters[i-item->item.pos] = first_glyph;
-        }
-        sstart = send;
-        first_glyph += syllable.num_glyphs;
-    }
-    item->num_glyphs = first_glyph;
-    return TRUE;
-}
-
-void HB_KhmerAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
-{
-    int end = from + len;
-    const HB_UChar16 *uc = text + from;
-    hb_uint32 i = 0;
-    HB_UNUSED(script);
-    attributes += from;
-    while ( i < len ) {
-	HB_Bool invalid;
-	hb_uint32 boundary = khmer_nextSyllableBoundary( text, from+i, end, &invalid ) - from;
-
-	attributes[i].charStop = TRUE;
-
-	if ( boundary > len-1 ) boundary = len;
-	i++;
-	while ( i < boundary ) {
-	    attributes[i].charStop = FALSE;
-	    ++uc;
-	    ++i;
-	}
-	assert( i == boundary );
-    }
-}
-
diff --git a/third_party/harfbuzz/src/harfbuzz-myanmar.c b/third_party/harfbuzz/src/harfbuzz-myanmar.c
deleted file mode 100644
index 7cd82bb..0000000
--- a/third_party/harfbuzz/src/harfbuzz-myanmar.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-enum MymrCharClassValues
-{
-    Mymr_CC_RESERVED             =  0,
-    Mymr_CC_CONSONANT            =  1, /* Consonant of type 1, that has subscript form */
-    Mymr_CC_CONSONANT2           =  2, /* Consonant of type 2, that has no subscript form */
-    Mymr_CC_NGA	          =  3, /* Consonant NGA */
-    Mymr_CC_YA		          =  4, /* Consonant YA */
-    Mymr_CC_RA		          =  5, /* Consonant RA */
-    Mymr_CC_WA		          =  6, /* Consonant WA */
-    Mymr_CC_HA		          =  7, /* Consonant HA */
-    Mymr_CC_IND_VOWEL		  =  8, /* Independent vowel */
-    Mymr_CC_ZERO_WIDTH_NJ_MARK   =  9, /* Zero Width non joiner character (0x200C) */
-    Mymr_CC_VIRAMA               = 10, /* Subscript consonant combining character */
-    Mymr_CC_PRE_VOWEL   	  = 11, /* Dependent vowel, prebase (Vowel e) */
-    Mymr_CC_BELOW_VOWEL   	  = 12, /* Dependent vowel, prebase (Vowel u, uu) */
-    Mymr_CC_ABOVE_VOWEL   	  = 13, /* Dependent vowel, prebase (Vowel i, ii, ai) */
-    Mymr_CC_POST_VOWEL   	  = 14, /* Dependent vowel, prebase (Vowel aa) */
-    Mymr_CC_SIGN_ABOVE           = 15,
-    Mymr_CC_SIGN_BELOW           = 16,
-    Mymr_CC_SIGN_AFTER           = 17,
-    Mymr_CC_ZERO_WIDTH_J_MARK    = 18, /* Zero width joiner character */
-    Mymr_CC_COUNT                = 19  /* This is the number of character classes */
-};
-
-enum MymrCharClassFlags
-{
-    Mymr_CF_CLASS_MASK    = 0x0000FFFF,
-
-    Mymr_CF_CONSONANT     = 0x01000000,  /* flag to speed up comparing */
-    Mymr_CF_MEDIAL	   = 0x02000000,  /* flag to speed up comparing */
-    Mymr_CF_IND_VOWEL 	   = 0x04000000,  /* flag to speed up comparing */
-    Mymr_CF_DEP_VOWEL 	   = 0x08000000,  /* flag to speed up comparing */
-    Mymr_CF_DOTTED_CIRCLE = 0x10000000,  /* add a dotted circle if a character with this flag is the first in a syllable */
-    Mymr_CF_VIRAMA        = 0x20000000,  /* flag to speed up comparing */
-
-    /* position flags */
-    Mymr_CF_POS_BEFORE    = 0x00080000,
-    Mymr_CF_POS_BELOW     = 0x00040000,
-    Mymr_CF_POS_ABOVE     = 0x00020000,
-    Mymr_CF_POS_AFTER     = 0x00010000,
-    Mymr_CF_POS_MASK      = 0x000f0000,
-
-    Mymr_CF_AFTER_KINZI   = 0x00100000
-};
-
-/* Characters that get refrered to by name */
-enum MymrChar
-{
-    Mymr_C_SIGN_ZWNJ     = 0x200C,
-    Mymr_C_SIGN_ZWJ      = 0x200D,
-    Mymr_C_DOTTED_CIRCLE = 0x25CC,
-    Mymr_C_RA            = 0x101B,
-    Mymr_C_YA            = 0x101A,
-    Mymr_C_NGA           = 0x1004,
-    Mymr_C_VOWEL_E       = 0x1031,
-    Mymr_C_VIRAMA        = 0x1039
-};
-
-enum
-{
-    Mymr_xx = Mymr_CC_RESERVED,
-    Mymr_c1 = Mymr_CC_CONSONANT | Mymr_CF_CONSONANT | Mymr_CF_POS_BELOW,
-    Mymr_c2 = Mymr_CC_CONSONANT2 | Mymr_CF_CONSONANT,
-    Mymr_ng = Mymr_CC_NGA | Mymr_CF_CONSONANT | Mymr_CF_POS_ABOVE,
-    Mymr_ya = Mymr_CC_YA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_AFTER | Mymr_CF_AFTER_KINZI,
-    Mymr_ra = Mymr_CC_RA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BEFORE,
-    Mymr_wa = Mymr_CC_WA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BELOW,
-    Mymr_ha = Mymr_CC_HA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BELOW,
-    Mymr_id = Mymr_CC_IND_VOWEL | Mymr_CF_IND_VOWEL,
-    Mymr_vi = Mymr_CC_VIRAMA | Mymr_CF_VIRAMA | Mymr_CF_POS_ABOVE | Mymr_CF_DOTTED_CIRCLE,
-    Mymr_dl = Mymr_CC_PRE_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_BEFORE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
-    Mymr_db = Mymr_CC_BELOW_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_BELOW | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
-    Mymr_da = Mymr_CC_ABOVE_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_ABOVE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
-    Mymr_dr = Mymr_CC_POST_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_AFTER | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
-    Mymr_sa = Mymr_CC_SIGN_ABOVE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_POS_ABOVE | Mymr_CF_AFTER_KINZI,
-    Mymr_sb = Mymr_CC_SIGN_BELOW | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_POS_BELOW | Mymr_CF_AFTER_KINZI,
-    Mymr_sp = Mymr_CC_SIGN_AFTER | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI
-};
-
-
-typedef int MymrCharClass;
-
-
-static const MymrCharClass mymrCharClasses[] =
-{
-    Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_ng, Mymr_c1, Mymr_c1, Mymr_c1,
-    Mymr_c1, Mymr_c1, Mymr_c2, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, /* 1000 - 100F */
-    Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1,
-    Mymr_c1, Mymr_c1, Mymr_ya, Mymr_ra, Mymr_c1, Mymr_wa, Mymr_c1, Mymr_ha, /* 1010 - 101F */
-    Mymr_c2, Mymr_c2, Mymr_xx, Mymr_id, Mymr_id, Mymr_id, Mymr_id, Mymr_id,
-    Mymr_xx, Mymr_id, Mymr_id, Mymr_xx, Mymr_dr, Mymr_da, Mymr_da, Mymr_db, /* 1020 - 102F */
-    Mymr_db, Mymr_dl, Mymr_da, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_sa, Mymr_sb,
-    Mymr_sp, Mymr_vi, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1030 - 103F */
-    Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx,
-    Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1040 - 104F */
-    Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx,
-    Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1050 - 105F */
-};
-
-static MymrCharClass
-getMyanmarCharClass (HB_UChar16 ch)
-{
-    if (ch == Mymr_C_SIGN_ZWJ)
-        return Mymr_CC_ZERO_WIDTH_J_MARK;
-
-    if (ch == Mymr_C_SIGN_ZWNJ)
-        return Mymr_CC_ZERO_WIDTH_NJ_MARK;
-
-    if (ch < 0x1000 || ch > 0x105f)
-        return Mymr_CC_RESERVED;
-
-    return mymrCharClasses[ch - 0x1000];
-}
-
-static const signed char mymrStateTable[][Mymr_CC_COUNT] =
-{
-/*   xx  c1, c2  ng  ya  ra  wa  ha  id zwnj vi  dl  db  da  dr  sa  sb  sp zwj */
-    { 1,  4,  4,  2,  4,  4,  4,  4, 24,  1, 27, 17, 18, 19, 20, 21,  1,  1,  4}, /*  0 - ground state */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /*  1 - exit state (or sp to the right of the syllable) */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  3, 17, 18, 19, 20, 21, -1, -1,  4}, /*  2 - NGA */
-    {-1,  4,  4,  4,  4,  4,  4,  4, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /*  3 - Virama after NGA */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  5, 17, 18, 19, 20, 21,  1,  1, -1}, /*  4 - Base consonant */
-    {-2,  6, -2, -2,  7,  8,  9, 10, -2, 23, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /*  5 - First virama */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 17, 18, 19, 20, 21, -1, -1, -1}, /*  6 - c1 after virama */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, /*  7 - ya after virama */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, /*  8 - ra after virama */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, /*  9 - wa after virama */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, /* 10 - ha after virama */
-    {-1, -1, -1, -1,  7,  8,  9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 11 - Virama after NGA+zwj */
-    {-2, -2, -2, -2, -2, -2, 13, 14, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 12 - Second virama */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 17, 18, 19, 20, 21, -1, -1, -1}, /* 13 - wa after virama */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, /* 14 - ha after virama */
-    {-2, -2, -2, -2, -2, -2, -2, 16, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 15 - Third virama */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, /* 16 - ha after virama */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 21,  1,  1, -1}, /* 17 - dl, Dependent vowel e */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, -1, 21,  1,  1, -1}, /* 18 - db, Dependent vowel u,uu */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1,  1,  1, -1}, /* 19 - da, Dependent vowel i,ii,ai */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,  1,  1, -1}, /* 20 - dr, Dependent vowel aa */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1,  1, -1}, /* 21 - sa, Sign anusvara */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 22 - atha */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1,  1, -1}, /* 23 - zwnj for atha */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1, -1}, /* 24 - Independent vowel */
-    {-2, -2, -2, -2, 26, 26, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 25 - Virama after subscript consonant */
-    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1,  1, -1}, /* 26 - ra/ya after subscript consonant + virama */
-    {-1,  6, -1, -1,  7,  8,  9, 10, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 - Virama after ground state */
-/* exit state -2 is for invalid order of medials and combination of invalids
-   with virama where virama should treat as start of next syllable
- */
-};
-
-
-
-/*#define MYANMAR_DEBUG */
-#ifdef MYANMAR_DEBUG
-#define MMDEBUG qDebug
-#else
-#define MMDEBUG if(0) printf
-#endif
-
-/*
-//  Given an input string of characters and a location in which to start looking
-//  calculate, using the state table, which one is the last character of the syllable
-//  that starts in the starting position.
-*/
-static int myanmar_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid)
-{
-    const HB_UChar16 *uc = s + start;
-    int state = 0;
-    int pos = start;
-    *invalid = FALSE;
-
-    while (pos < end) {
-        MymrCharClass charClass = getMyanmarCharClass(*uc);
-        state = mymrStateTable[state][charClass & Mymr_CF_CLASS_MASK];
-        if (pos == start)
-            *invalid = (HB_Bool)(charClass & Mymr_CF_DOTTED_CIRCLE);
-
-        MMDEBUG("state[%d]=%d class=%8x (uc=%4x)", pos - start, state, charClass, *uc);
-
-        if (state < 0) {
-            if (state < -1)
-                --pos;
-            break;
-        }
-        ++uc;
-        ++pos;
-    }
-    return pos;
-}
-
-#ifndef NO_OPENTYPE
-/* ###### might have to change order of above and below forms and substitutions,
-   but according to Unicode below comes before above */
-static const HB_OpenTypeFeature myanmar_features[] = {
-    { HB_MAKE_TAG('p', 'r', 'e', 'f'), PreFormProperty },
-    { HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty },
-    { HB_MAKE_TAG('a', 'b', 'v', 'f'), AboveFormProperty },
-    { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
-    { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty },
-    { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
-    { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
-    { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty },
-    { HB_MAKE_TAG('r', 'l', 'i', 'g'), CligProperty }, /* Myanmar1 uses this instead of the other features */
-    { 0, 0 }
-};
-#endif
-
-
-/*
-// Visual order before shaping should be:
-//
-//    [Vowel Mark E]
-//    [Virama + Medial Ra]
-//    [Base]
-//    [Virama + Consonant]
-//    [Nga + Virama] (Kinzi) ### should probably come before post forms (medial ya)
-//    [Vowels]
-//    [Marks]
-//
-// This means that we can keep the logical order apart from having to
-// move the pre vowel, medial ra and kinzi
-*/
-
-static HB_Bool myanmar_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid)
-{
-    /*
-//    MMDEBUG("\nsyllable from %d len %d, str='%s'", item->item.pos, item->item.length,
-//	    item->string->mid(item->from, item->length).toUtf8().data());
-    */
-
-#ifndef NO_OPENTYPE
-    const int availableGlyphs = item->num_glyphs;
-#endif
-    const HB_UChar16 *uc = item->string + item->item.pos;
-    int vowel_e = -1;
-    int kinzi = -1;
-    int medial_ra = -1;
-    int base = -1;
-    int i;
-    int len = 0;
-    unsigned short reordered[32];
-    unsigned char properties[32];
-    enum {
-	AboveForm = 0x01,
-	PreForm = 0x02,
-	PostForm = 0x04,
-	BelowForm = 0x08
-    };
-    HB_Bool lastWasVirama = FALSE;
-    int basePos = -1;
-
-    memset(properties, 0, 32*sizeof(unsigned char));
-
-    /* according to the table the max length of a syllable should be around 14 chars */
-    assert(item->item.length < 32);
-
-#ifdef MYANMAR_DEBUG
-    printf("original:");
-    for (i = 0; i < (int)item->item.length; i++) {
-        printf("    %d: %4x", i, uc[i]);
-    }
-#endif
-    for (i = 0; i < (int)item->item.length; ++i) {
-        HB_UChar16 chr = uc[i];
-
-        if (chr == Mymr_C_VOWEL_E) {
-            vowel_e = i;
-            continue;
-        }
-        if (i == 0
-            && chr == Mymr_C_NGA
-            && i + 2 < (int)item->item.length
-            && uc[i+1] == Mymr_C_VIRAMA) {
-            int mc = getMyanmarCharClass(uc[i+2]);
-            /*MMDEBUG("maybe kinzi: mc=%x", mc);*/
-            if ((mc & Mymr_CF_CONSONANT) == Mymr_CF_CONSONANT) {
-                kinzi = i;
-                continue;
-            }
-        }
-        if (base >= 0
-            && chr == Mymr_C_VIRAMA
-            && i + 1 < (int)item->item.length
-            && uc[i+1] == Mymr_C_RA) {
-            medial_ra = i;
-            continue;
-        }
-        if (base < 0)
-            base = i;
-    }
-
-    MMDEBUG("\n  base=%d, vowel_e=%d, kinzi=%d, medial_ra=%d", base, vowel_e, kinzi, medial_ra);
-    /* write vowel_e if found */
-    if (vowel_e >= 0) {
-        reordered[0] = Mymr_C_VOWEL_E;
-        len = 1;
-    }
-    /* write medial_ra */
-    if (medial_ra >= 0) {
-        reordered[len] = Mymr_C_VIRAMA;
-        reordered[len+1] = Mymr_C_RA;
-        properties[len] = PreForm;
-        properties[len+1] = PreForm;
-        len += 2;
-    }
-
-    /* shall we add a dotted circle?
-       If in the position in which the base should be (first char in the string) there is
-       a character that has the Dotted circle flag (a character that cannot be a base)
-       then write a dotted circle */
-    if (invalid) {
-        reordered[len] = C_DOTTED_CIRCLE;
-        ++len;
-    }
-
-    /* copy the rest of the syllable to the output, inserting the kinzi
-       at the correct place */
-    for (i = 0; i < (int)item->item.length; ++i) {
-        hb_uint16 chr = uc[i];
-        MymrCharClass cc;
-        if (i == vowel_e)
-            continue;
-        if (i == medial_ra || i == kinzi) {
-            ++i;
-            continue;
-        }
-
-        cc = getMyanmarCharClass(uc[i]);
-        if (kinzi >= 0 && i > base && (cc & Mymr_CF_AFTER_KINZI)) {
-            reordered[len] = Mymr_C_NGA;
-            reordered[len+1] = Mymr_C_VIRAMA;
-            properties[len-1] = AboveForm;
-            properties[len] = AboveForm;
-            len += 2;
-            kinzi = -1;
-        }
-
-        if (lastWasVirama) {
-            int prop = 0;
-            switch(cc & Mymr_CF_POS_MASK) {
-            case Mymr_CF_POS_BEFORE:
-                prop = PreForm;
-                break;
-            case Mymr_CF_POS_BELOW:
-                prop = BelowForm;
-                break;
-            case Mymr_CF_POS_ABOVE:
-                prop = AboveForm;
-                break;
-            case Mymr_CF_POS_AFTER:
-                prop = PostForm;
-                break;
-            default:
-                break;
-            }
-            properties[len-1] = prop;
-            properties[len] = prop;
-            if(basePos >= 0 && basePos == len-2)
-                properties[len-2] = prop;
-        }
-        lastWasVirama = (chr == Mymr_C_VIRAMA);
-        if(i == base)
-            basePos = len;
-
-        if ((chr != Mymr_C_SIGN_ZWNJ && chr != Mymr_C_SIGN_ZWJ) || !len) {
-            reordered[len] = chr;
-            ++len;
-        }
-    }
-    if (kinzi >= 0) {
-        reordered[len] = Mymr_C_NGA;
-        reordered[len+1] = Mymr_C_VIRAMA;
-        properties[len] = AboveForm;
-        properties[len+1] = AboveForm;
-        len += 2;
-    }
-
-    if (!item->font->klass->convertStringToGlyphIndices(item->font,
-                                                        reordered, len,
-                                                        item->glyphs, &item->num_glyphs,
-                                                        item->item.bidiLevel % 2))
-        return FALSE;
-
-    MMDEBUG("after shaping: len=%d", len);
-    for (i = 0; i < len; i++) {
-	item->attributes[i].mark = FALSE;
-	item->attributes[i].clusterStart = FALSE;
-	item->attributes[i].justification = 0;
-	item->attributes[i].zeroWidth = FALSE;
-	MMDEBUG("    %d: %4x property=%x", i, reordered[i], properties[i]);
-    }
-
-    /* now we have the syllable in the right order, and can start running it through open type. */
-
-#ifndef NO_OPENTYPE
-    if (openType) {
-	unsigned short logClusters[32];
- 	hb_uint32 where[32];
-
-	for (i = 0; i < len; ++i)
-	    logClusters[i] = i;
-
-        for (i = 0; i < len; ++i) {
-            where[i] = ~(PreSubstProperty
-                         | BelowSubstProperty
-                         | AboveSubstProperty
-                         | PostSubstProperty
-                         | CligProperty
-                         | PositioningProperties);
-            if (properties[i] & PreForm)
-                where[i] &= ~PreFormProperty;
-            if (properties[i] & BelowForm)
-                where[i] &= ~BelowFormProperty;
-            if (properties[i] & AboveForm)
-                where[i] &= ~AboveFormProperty;
-            if (properties[i] & PostForm)
-                where[i] &= ~PostFormProperty;
-        }
-
-        HB_OpenTypeShape(item, where);
-        if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE))
-            return FALSE;
-    } else
-#endif
-    {
-	MMDEBUG("Not using openType");
-        HB_HeuristicPosition(item);
-    }
-
-    item->attributes[0].clusterStart = TRUE;
-    return TRUE;
-}
-
-HB_Bool HB_MyanmarShape(HB_ShaperItem *item)
-{
-    HB_Bool openType = FALSE;
-    unsigned short *logClusters = item->log_clusters;
-
-    HB_ShaperItem syllable = *item;
-    int first_glyph = 0;
-
-    int sstart = item->item.pos;
-    int end = sstart + item->item.length;
-    int i = 0;
-
-    assert(item->item.script == HB_Script_Myanmar);
-#ifndef NO_OPENTYPE
-    openType = HB_SelectScript(item, myanmar_features);
-#endif
-
-    MMDEBUG("myanmar_shape: from %d length %d", item->item.pos, item->item.length);
-    while (sstart < end) {
-        HB_Bool invalid;
-        int send = myanmar_nextSyllableBoundary(item->string, sstart, end, &invalid);
-        MMDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
-               invalid ? "TRUE" : "FALSE");
-        syllable.item.pos = sstart;
-        syllable.item.length = send-sstart;
-        syllable.glyphs = item->glyphs + first_glyph;
-        syllable.attributes = item->attributes + first_glyph;
-        syllable.advances = item->advances + first_glyph;
-        syllable.offsets = item->offsets + first_glyph;
-        syllable.num_glyphs = item->num_glyphs - first_glyph;
-        if (!myanmar_shape_syllable(openType, &syllable, invalid)) {
-            MMDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
-            item->num_glyphs += syllable.num_glyphs;
-            return FALSE;
-        }
-
-        /* fix logcluster array */
-        MMDEBUG("syllable:");
-        for (i = first_glyph; i < first_glyph + (int)syllable.num_glyphs; ++i)
-            MMDEBUG("        %d -> glyph %x", i, item->glyphs[i]);
-        MMDEBUG("    logclusters:");
-        for (i = sstart; i < send; ++i) {
-            MMDEBUG("        %d -> glyph %d", i, first_glyph);
-            logClusters[i-item->item.pos] = first_glyph;
-        }
-        sstart = send;
-        first_glyph += syllable.num_glyphs;
-    }
-    item->num_glyphs = first_glyph;
-    return TRUE;
-}
-
-void HB_MyanmarAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
-{
-    int end = from + len;
-    const HB_UChar16 *uc = text + from;
-    hb_uint32 i = 0;
-    HB_UNUSED(script);
-    attributes += from;
-    while (i < len) {
-	HB_Bool invalid;
-	hb_uint32 boundary = myanmar_nextSyllableBoundary(text, from+i, end, &invalid) - from;
-
-	attributes[i].charStop = TRUE;
-        if (i)
-            attributes[i-1].lineBreakType = HB_Break;
-
-	if (boundary > len-1)
-            boundary = len;
-	i++;
-	while (i < boundary) {
-	    attributes[i].charStop = FALSE;
-	    ++uc;
-	    ++i;
-	}
-	assert(i == boundary);
-    }
-}
-
diff --git a/third_party/harfbuzz/src/harfbuzz-open-private.h b/third_party/harfbuzz/src/harfbuzz-open-private.h
deleted file mode 100644
index 73dd383..0000000
--- a/third_party/harfbuzz/src/harfbuzz-open-private.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_OPEN_PRIVATE_H
-#define HARFBUZZ_OPEN_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-open.h"
-#include "harfbuzz-gsub-private.h"
-#include "harfbuzz-gpos-private.h"
-
-HB_BEGIN_HEADER
-
-
-struct  HB_SubTable_
-{
-  union
-  {
-    HB_GSUB_SubTable  gsub;
-    HB_GPOS_SubTable  gpos;
-  } st;
-};
-
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_ScriptList( HB_ScriptList* sl,
-			   HB_Stream     input );
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_FeatureList( HB_FeatureList* fl,
-			    HB_Stream         input );
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_LookupList( HB_LookupList*  ll,
-			   HB_Stream        input,
-			   HB_Type         type );
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_Coverage( HB_Coverage* c,
-			 HB_Stream      input );
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_ClassDefinition( HB_ClassDefinition* cd,
-				HB_UShort             limit,
-				HB_Stream             input );
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd,
-					       HB_UShort             limit,
-					       HB_UInt              class_offset,
-					       HB_UInt              base_offset,
-					       HB_Stream             input );
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_Device( HB_Device* d,
-		       HB_Stream    input );
-
-HB_INTERNAL void  _HB_OPEN_Free_ScriptList( HB_ScriptList*  sl );
-HB_INTERNAL void  _HB_OPEN_Free_FeatureList( HB_FeatureList*  fl );
-HB_INTERNAL void  _HB_OPEN_Free_LookupList( HB_LookupList*  ll,
-		       HB_Type         type );
-
-HB_INTERNAL void  _HB_OPEN_Free_Coverage( HB_Coverage*  c );
-HB_INTERNAL void  _HB_OPEN_Free_ClassDefinition( HB_ClassDefinition*  cd );
-HB_INTERNAL void  _HB_OPEN_Free_Device( HB_Device*  d );
-
-
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Coverage_Index( HB_Coverage* c,
-			  HB_UShort      glyphID,
-			  HB_UShort*     index );
-HB_INTERNAL HB_Error
-_HB_OPEN_Get_Class( HB_ClassDefinition* cd,
-		     HB_UShort             glyphID,
-		    HB_UShort*          klass,
-		     HB_UShort*            index );
-HB_INTERNAL HB_Error
-_HB_OPEN_Get_Device( HB_Device* d,
-		      HB_UShort    size,
-		      HB_Short*    value );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_OPEN_PRIVATE_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-open.c b/third_party/harfbuzz/src/harfbuzz-open.c
deleted file mode 100644
index 0fe1e4d..0000000
--- a/third_party/harfbuzz/src/harfbuzz-open.c
+++ /dev/null
@@ -1,1416 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-open-private.h"
-
-
-/***************************
- * Script related functions
- ***************************/
-
-
-/* LangSys */
-
-static HB_Error  Load_LangSys( HB_LangSys*  ls,
-			       HB_Stream     stream )
-{
-  HB_Error   error;
-  HB_UShort  n, count;
-  HB_UShort* fi;
-
-
-  if ( ACCESS_Frame( 6L ) )
-    return error;
-
-  ls->LookupOrderOffset    = GET_UShort();    /* should be 0 */
-  ls->ReqFeatureIndex      = GET_UShort();
-  count = ls->FeatureCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ls->FeatureIndex = NULL;
-
-  if ( ALLOC_ARRAY( ls->FeatureIndex, count, HB_UShort ) )
-    return error;
-
-  if ( ACCESS_Frame( count * 2L ) )
-  {
-    FREE( ls->FeatureIndex );
-    return error;
-  }
-
-  fi = ls->FeatureIndex;
-
-  for ( n = 0; n < count; n++ )
-    fi[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-}
-
-
-static void  Free_LangSys( HB_LangSys*  ls )
-{
-  FREE( ls->FeatureIndex );
-}
-
-
-/* Script */
-
-static HB_Error  Load_Script( HB_ScriptTable*  s,
-			      HB_Stream    stream )
-{
-  HB_Error   error;
-  HB_UShort  n, m, count;
-  HB_UInt   cur_offset, new_offset, base_offset;
-
-  HB_LangSysRecord*  lsr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  new_offset = GET_UShort() + base_offset;
-
-  FORGET_Frame();
-
-  if ( new_offset != base_offset )        /* not a NULL offset */
-  {
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_LangSys( &s->DefaultLangSys,
-				 stream ) ) != HB_Err_Ok )
-      return error;
-    (void)FILE_Seek( cur_offset );
-  }
-  else
-  {
-    /* we create a DefaultLangSys table with no entries */
-
-    s->DefaultLangSys.LookupOrderOffset = 0;
-    s->DefaultLangSys.ReqFeatureIndex   = 0xFFFF;
-    s->DefaultLangSys.FeatureCount      = 0;
-    s->DefaultLangSys.FeatureIndex      = NULL;
-  }
-
-  if ( ACCESS_Frame( 2L ) )
-    goto Fail2;
-
-  count = s->LangSysCount = GET_UShort();
-
-  /* safety check; otherwise the official handling of TrueType Open
-     fonts won't work */
-
-  if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 )
-  {
-    error = HB_Err_Not_Covered;
-    goto Fail2;
-  }
-
-  FORGET_Frame();
-
-  s->LangSysRecord = NULL;
-
-  if ( ALLOC_ARRAY( s->LangSysRecord, count, HB_LangSysRecord ) )
-    goto Fail2;
-
-  lsr = s->LangSysRecord;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 6L ) )
-      goto Fail1;
-
-    lsr[n].LangSysTag = GET_ULong();
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_LangSys( &lsr[n].LangSys, stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_LangSys( &lsr[m].LangSys );
-
-  FREE( s->LangSysRecord );
-
-Fail2:
-  Free_LangSys( &s->DefaultLangSys );
-  return error;
-}
-
-
-static void  Free_Script( HB_ScriptTable*  s )
-{
-  HB_UShort           n, count;
-
-  HB_LangSysRecord*  lsr;
-
-
-  Free_LangSys( &s->DefaultLangSys );
-
-  if ( s->LangSysRecord )
-  {
-    count = s->LangSysCount;
-    lsr   = s->LangSysRecord;
-
-    for ( n = 0; n < count; n++ )
-      Free_LangSys( &lsr[n].LangSys );
-
-    FREE( lsr );
-  }
-}
-
-
-/* ScriptList */
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_ScriptList( HB_ScriptList* sl,
-			   HB_Stream        stream )
-{
-  HB_Error   error;
-
-  HB_UShort          n, script_count;
-  HB_UInt           cur_offset, new_offset, base_offset;
-
-  HB_ScriptRecord*  sr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  script_count = GET_UShort();
-
-  FORGET_Frame();
-
-  sl->ScriptRecord = NULL;
-
-  if ( ALLOC_ARRAY( sl->ScriptRecord, script_count, HB_ScriptRecord ) )
-    return error;
-
-  sr = sl->ScriptRecord;
-
-  sl->ScriptCount= 0;
-  for ( n = 0; n < script_count; n++ )
-  {
-    if ( ACCESS_Frame( 6L ) )
-      goto Fail;
-
-    sr[sl->ScriptCount].ScriptTag = GET_ULong();
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-
-    if ( FILE_Seek( new_offset ) )
-      goto Fail;
-
-    error = Load_Script( &sr[sl->ScriptCount].Script, stream );
-    if ( error == HB_Err_Ok )
-      sl->ScriptCount += 1;
-    else if ( error != HB_Err_Not_Covered )
-      goto Fail;
-
-    (void)FILE_Seek( cur_offset );
-  }
-
-  /* Empty tables are harmless and generated by fontforge.
-   * See http://bugzilla.gnome.org/show_bug.cgi?id=347073
-   */
-#if 0
-  if ( sl->ScriptCount == 0 )
-  {
-    error = ERR(HB_Err_Invalid_SubTable);
-    goto Fail;
-  }
-#endif
-  
-  return HB_Err_Ok;
-
-Fail:
-  for ( n = 0; n < sl->ScriptCount; n++ )
-    Free_Script( &sr[n].Script );
-
-  FREE( sl->ScriptRecord );
-  return error;
-}
-
-
-HB_INTERNAL void
-_HB_OPEN_Free_ScriptList( HB_ScriptList* sl )
-{
-  HB_UShort          n, count;
-
-  HB_ScriptRecord*  sr;
-
-
-  if ( sl->ScriptRecord )
-  {
-    count = sl->ScriptCount;
-    sr    = sl->ScriptRecord;
-
-    for ( n = 0; n < count; n++ )
-      Free_Script( &sr[n].Script );
-
-    FREE( sr );
-  }
-}
-
-
-
-/*********************************
- * Feature List related functions
- *********************************/
-
-
-/* Feature */
-
-static HB_Error  Load_Feature( HB_Feature*  f,
-			       HB_Stream     stream )
-{
-  HB_Error   error;
-
-  HB_UShort   n, count;
-
-  HB_UShort*  lli;
-
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  f->FeatureParams           = GET_UShort();    /* should be 0 */
-  count = f->LookupListCount = GET_UShort();
-
-  FORGET_Frame();
-
-  f->LookupListIndex = NULL;
-
-  if ( ALLOC_ARRAY( f->LookupListIndex, count, HB_UShort ) )
-    return error;
-
-  lli = f->LookupListIndex;
-
-  if ( ACCESS_Frame( count * 2L ) )
-  {
-    FREE( f->LookupListIndex );
-    return error;
-  }
-
-  for ( n = 0; n < count; n++ )
-    lli[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-}
-
-
-static void  Free_Feature( HB_Feature*  f )
-{
-  FREE( f->LookupListIndex );
-}
-
-
-/* FeatureList */
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_FeatureList( HB_FeatureList* fl,
-			    HB_Stream         stream )
-{
-  HB_Error   error;
-
-  HB_UShort           n, m, count;
-  HB_UInt            cur_offset, new_offset, base_offset;
-
-  HB_FeatureRecord*  fr;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = fl->FeatureCount = GET_UShort();
-
-  FORGET_Frame();
-
-  fl->FeatureRecord = NULL;
-
-  if ( ALLOC_ARRAY( fl->FeatureRecord, count, HB_FeatureRecord ) )
-    return error;
-  if ( ALLOC_ARRAY( fl->ApplyOrder, count, HB_UShort ) )
-    goto Fail2;
-  
-  fl->ApplyCount = 0;
-
-  fr = fl->FeatureRecord;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 6L ) )
-      goto Fail1;
-
-    fr[n].FeatureTag = GET_ULong();
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_Feature( &fr[n].Feature, stream ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  for ( m = 0; m < n; m++ )
-    Free_Feature( &fr[m].Feature );
-
-  FREE( fl->ApplyOrder );
-
-Fail2:
-  FREE( fl->FeatureRecord );
-
-  return error;
-}
-
-
-HB_INTERNAL void
-_HB_OPEN_Free_FeatureList( HB_FeatureList*  fl )
-{
-  HB_UShort           n, count;
-
-  HB_FeatureRecord*  fr;
-
-
-  if ( fl->FeatureRecord )
-  {
-    count = fl->FeatureCount;
-    fr    = fl->FeatureRecord;
-
-    for ( n = 0; n < count; n++ )
-      Free_Feature( &fr[n].Feature );
-
-    FREE( fr );
-  }
-  
-  FREE( fl->ApplyOrder );
-}
-
-
-
-/********************************
- * Lookup List related functions
- ********************************/
-
-/* the subroutines of the following two functions are defined in
-   ftxgsub.c and ftxgpos.c respectively                          */
-
-
-/* SubTable */
-
-static HB_Error  Load_SubTable( HB_SubTable*  st,
-				HB_Stream     stream,
-				HB_Type       table_type,
-				HB_UShort     lookup_type )
-{
-  if ( table_type == HB_Type_GSUB )
-    return _HB_GSUB_Load_SubTable ( &st->st.gsub, stream, lookup_type );
-  else
-    return _HB_GPOS_Load_SubTable ( &st->st.gpos, stream, lookup_type );
-}
-
-
-static void  Free_SubTable( HB_SubTable*  st,
-			    HB_Type       table_type,
-			    HB_UShort      lookup_type )
-{
-  if ( table_type == HB_Type_GSUB )
-    _HB_GSUB_Free_SubTable ( &st->st.gsub, lookup_type );
-  else
-    _HB_GPOS_Free_SubTable ( &st->st.gpos, lookup_type );
-}
-
-
-/* Lookup */
-
-static HB_Error  Load_Lookup( HB_Lookup*   l,
-			      HB_Stream     stream,
-			      HB_Type      type )
-{
-  HB_Error   error;
-
-  HB_UShort      n, m, count;
-  HB_UInt       cur_offset, new_offset, base_offset;
-
-  HB_SubTable*  st;
-
-  HB_Bool        is_extension = FALSE;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 6L ) )
-    return error;
-
-  l->LookupType            = GET_UShort();
-  l->LookupFlag            = GET_UShort();
-  count = l->SubTableCount = GET_UShort();
-
-  FORGET_Frame();
-
-  l->SubTable = NULL;
-
-  if ( ALLOC_ARRAY( l->SubTable, count, HB_SubTable ) )
-    return error;
-
-  st = l->SubTable;
-
-  if ( ( type == HB_Type_GSUB && l->LookupType == HB_GSUB_LOOKUP_EXTENSION ) ||
-       ( type == HB_Type_GPOS && l->LookupType == HB_GPOS_LOOKUP_EXTENSION ) )
-    is_extension = TRUE;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-
-    if ( is_extension )
-    {
-      if ( FILE_Seek( new_offset ) || ACCESS_Frame( 8L ) )
-	goto Fail;
-
-      if (GET_UShort() != 1) /* format should be 1 */
-	goto Fail;
-
-      l->LookupType = GET_UShort();
-      new_offset += GET_ULong();
-
-      FORGET_Frame();
-    }
-
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_SubTable( &st[n], stream,
-				  type, l->LookupType ) ) != HB_Err_Ok )
-      goto Fail;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail:
-  for ( m = 0; m < n; m++ )
-    Free_SubTable( &st[m], type, l->LookupType );
-
-  FREE( l->SubTable );
-  return error;
-}
-
-
-static void  Free_Lookup( HB_Lookup*   l,
-			  HB_Type      type)
-{
-  HB_UShort      n, count;
-
-  HB_SubTable*  st;
-
-
-  if ( l->SubTable )
-  {
-    count = l->SubTableCount;
-    st    = l->SubTable;
-
-    for ( n = 0; n < count; n++ )
-      Free_SubTable( &st[n], type, l->LookupType );
-
-    FREE( st );
-  }
-}
-
-
-/* LookupList */
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_LookupList( HB_LookupList* ll,
-			   HB_Stream        stream,
-			   HB_Type         type )
-{
-  HB_Error   error;
-
-  HB_UShort    n, m, count;
-  HB_UInt     cur_offset, new_offset, base_offset;
-
-  HB_Lookup*  l;
-
-
-  base_offset = FILE_Pos();
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = ll->LookupCount = GET_UShort();
-
-  FORGET_Frame();
-
-  ll->Lookup = NULL;
-
-  if ( ALLOC_ARRAY( ll->Lookup, count, HB_Lookup ) )
-    return error;
-  if ( ALLOC_ARRAY( ll->Properties, count, HB_UInt ) )
-    goto Fail2;
-
-  l = ll->Lookup;
-
-  for ( n = 0; n < count; n++ )
-  {
-    if ( ACCESS_Frame( 2L ) )
-      goto Fail1;
-
-    new_offset = GET_UShort() + base_offset;
-
-    FORGET_Frame();
-
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( new_offset ) ||
-	 ( error = Load_Lookup( &l[n], stream, type ) ) != HB_Err_Ok )
-      goto Fail1;
-    (void)FILE_Seek( cur_offset );
-  }
-
-  return HB_Err_Ok;
-
-Fail1:
-  FREE( ll->Properties );
-
-  for ( m = 0; m < n; m++ )
-    Free_Lookup( &l[m], type );
-
-Fail2:
-  FREE( ll->Lookup );
-  return error;
-}
-
-
-HB_INTERNAL void
-_HB_OPEN_Free_LookupList( HB_LookupList* ll,
-		       HB_Type         type )
-{
-  HB_UShort    n, count;
-
-  HB_Lookup*  l;
-
-
-  FREE( ll->Properties );
-
-  if ( ll->Lookup )
-  {
-    count = ll->LookupCount;
-    l     = ll->Lookup;
-
-    for ( n = 0; n < count; n++ )
-      Free_Lookup( &l[n], type );
-
-    FREE( l );
-  }
-}
-
-
-
-/*****************************
- * Coverage related functions
- *****************************/
-
-
-/* CoverageFormat1 */
-
-static HB_Error  Load_Coverage1( HB_CoverageFormat1*  cf1,
-				 HB_Stream             stream )
-{
-  HB_Error   error;
-
-  HB_UShort  n, count;
-
-  HB_UShort* ga;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = cf1->GlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cf1->GlyphArray = NULL;
-
-  if ( ALLOC_ARRAY( cf1->GlyphArray, count, HB_UShort ) )
-    return error;
-
-  ga = cf1->GlyphArray;
-
-  if ( ACCESS_Frame( count * 2L ) )
-  {
-    FREE( cf1->GlyphArray );
-    return error;
-  }
-
-  for ( n = 0; n < count; n++ )
-    ga[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-}
-
-
-static void  Free_Coverage1( HB_CoverageFormat1*  cf1)
-{
-  FREE( cf1->GlyphArray );
-}
-
-
-/* CoverageFormat2 */
-
-static HB_Error  Load_Coverage2( HB_CoverageFormat2*  cf2,
-				 HB_Stream             stream )
-{
-  HB_Error   error;
-
-  HB_UShort         n, count;
-
-  HB_RangeRecord*  rr;
-
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = cf2->RangeCount = GET_UShort();
-
-  FORGET_Frame();
-
-  cf2->RangeRecord = NULL;
-
-  if ( ALLOC_ARRAY( cf2->RangeRecord, count, HB_RangeRecord ) )
-    return error;
-
-  rr = cf2->RangeRecord;
-
-  if ( ACCESS_Frame( count * 6L ) )
-    goto Fail;
-
-  for ( n = 0; n < count; n++ )
-  {
-    rr[n].Start              = GET_UShort();
-    rr[n].End                = GET_UShort();
-    rr[n].StartCoverageIndex = GET_UShort();
-
-    /* sanity check; we are limited to 16bit integers */
-    if ( rr[n].Start > rr[n].End ||
-	 ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >=
-	   0x10000L )
-    {
-      error = ERR(HB_Err_Invalid_SubTable);
-      goto Fail;
-    }
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail:
-  FREE( cf2->RangeRecord );
-  return error;
-}
-
-
-static void  Free_Coverage2( HB_CoverageFormat2*  cf2 )
-{
-  FREE( cf2->RangeRecord );
-}
-
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_Coverage( HB_Coverage* c,
-			 HB_Stream      stream )
-{
-  HB_Error   error;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  c->CoverageFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  switch ( c->CoverageFormat )
-  {
-  case 1:  return Load_Coverage1( &c->cf.cf1, stream );
-  case 2:  return Load_Coverage2( &c->cf.cf2, stream );
-  default: return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-HB_INTERNAL void
-_HB_OPEN_Free_Coverage( HB_Coverage* c )
-{
-  switch ( c->CoverageFormat )
-  {
-  case 1:  Free_Coverage1( &c->cf.cf1 ); break;
-  case 2:  Free_Coverage2( &c->cf.cf2 ); break;
-  default:					 break;
-  }
-}
-
-
-static HB_Error  Coverage_Index1( HB_CoverageFormat1*  cf1,
-				  HB_UShort             glyphID,
-				  HB_UShort*            index )
-{
-  HB_UShort min, max, new_min, new_max, middle;
-
-  HB_UShort*  array = cf1->GlyphArray;
-
-
-  /* binary search */
-
-  if ( cf1->GlyphCount == 0 )
-    return HB_Err_Not_Covered;
-
-  new_min = 0;
-  new_max = cf1->GlyphCount - 1;
-
-  do
-  {
-    min = new_min;
-    max = new_max;
-
-    /* we use (min + max) / 2 = max - (max - min) / 2  to avoid
-       overflow and rounding errors                             */
-
-    middle = max - ( ( max - min ) >> 1 );
-
-    if ( glyphID == array[middle] )
-    {
-      *index = middle;
-      return HB_Err_Ok;
-    }
-    else if ( glyphID < array[middle] )
-    {
-      if ( middle == min )
-	break;
-      new_max = middle - 1;
-    }
-    else
-    {
-      if ( middle == max )
-	break;
-      new_min = middle + 1;
-    }
-  } while ( min < max );
-
-  return HB_Err_Not_Covered;
-}
-
-
-static HB_Error  Coverage_Index2( HB_CoverageFormat2*  cf2,
-				  HB_UShort             glyphID,
-				  HB_UShort*            index )
-{
-  HB_UShort         min, max, new_min, new_max, middle;
-
-  HB_RangeRecord*  rr = cf2->RangeRecord;
-
-
-  /* binary search */
-
-  if ( cf2->RangeCount == 0 )
-    return HB_Err_Not_Covered;
-
-  new_min = 0;
-  new_max = cf2->RangeCount - 1;
-
-  do
-  {
-    min = new_min;
-    max = new_max;
-
-    /* we use (min + max) / 2 = max - (max - min) / 2  to avoid
-       overflow and rounding errors                             */
-
-    middle = max - ( ( max - min ) >> 1 );
-
-    if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End )
-    {
-      *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start;
-      return HB_Err_Ok;
-    }
-    else if ( glyphID < rr[middle].Start )
-    {
-      if ( middle == min )
-	break;
-      new_max = middle - 1;
-    }
-    else
-    {
-      if ( middle == max )
-	break;
-      new_min = middle + 1;
-    }
-  } while ( min < max );
-
-  return HB_Err_Not_Covered;
-}
-
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Coverage_Index( HB_Coverage* c,
-			  HB_UShort      glyphID,
-			  HB_UShort*     index )
-{
-  switch ( c->CoverageFormat )
-  {
-  case 1:  return Coverage_Index1( &c->cf.cf1, glyphID, index );
-  case 2:  return Coverage_Index2( &c->cf.cf2, glyphID, index );
-  default: return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-
-/*************************************
- * Class Definition related functions
- *************************************/
-
-
-/* ClassDefFormat1 */
-
-static HB_Error  Load_ClassDef1( HB_ClassDefinition*  cd,
-				 HB_UShort             limit,
-				 HB_Stream             stream )
-{
-  HB_Error   error;
-
-  HB_UShort             n, count;
-
-  HB_UShort*            cva;
-
-  HB_ClassDefFormat1*  cdf1;
-
-
-  cdf1 = &cd->cd.cd1;
-
-  if ( ACCESS_Frame( 4L ) )
-    return error;
-
-  cdf1->StartGlyph         = GET_UShort();
-  count = cdf1->GlyphCount = GET_UShort();
-
-  FORGET_Frame();
-
-  /* sanity check; we are limited to 16bit integers */
-
-  if ( cdf1->StartGlyph + (long)count >= 0x10000L )
-    return ERR(HB_Err_Invalid_SubTable);
-
-  cdf1->ClassValueArray = NULL;
-
-  if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, HB_UShort ) )
-    return error;
-
-  cva = cdf1->ClassValueArray;
-
-  if ( ACCESS_Frame( count * 2L ) )
-    goto Fail;
-
-  for ( n = 0; n < count; n++ )
-  {
-    cva[n] = GET_UShort();
-    if ( cva[n] >= limit )
-    {
-      error = ERR(HB_Err_Invalid_SubTable);
-      goto Fail;
-    }
-  }
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-
-Fail:
-  FREE( cva );
-
-  return error;
-}
-
-
-static void  Free_ClassDef1( HB_ClassDefFormat1*  cdf1 )
-{
-  FREE( cdf1->ClassValueArray );
-}
-
-
-/* ClassDefFormat2 */
-
-static HB_Error  Load_ClassDef2( HB_ClassDefinition*  cd,
-				 HB_UShort             limit,
-				 HB_Stream             stream )
-{
-  HB_Error   error;
-
-  HB_UShort              n, count;
-
-  HB_ClassRangeRecord*  crr;
-
-  HB_ClassDefFormat2*   cdf2;
-
-
-  cdf2 = &cd->cd.cd2;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  count = GET_UShort();
-  cdf2->ClassRangeCount = 0; /* zero for now.  we fill with the number of good entries later */
-
-  FORGET_Frame();
-
-  cdf2->ClassRangeRecord = NULL;
-
-  if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, HB_ClassRangeRecord ) )
-    return error;
-
-  crr = cdf2->ClassRangeRecord;
-
-  if ( ACCESS_Frame( count * 6L ) )
-    goto Fail;
-
-  for ( n = 0; n < count; n++ )
-  {
-    crr[n].Start = GET_UShort();
-    crr[n].End   = GET_UShort();
-    crr[n].Class = GET_UShort();
-
-    /* sanity check */
-
-    if ( crr[n].Start > crr[n].End ||
-	 crr[n].Class >= limit )
-    {
-      /* XXX
-       * Corrupt entry.  Skip it.
-       * This is hit by Nafees Nastaliq font for example
-       */
-       n--;
-       count--;
-    }
-  }
-
-  FORGET_Frame();
-
-  cdf2->ClassRangeCount = count;
-
-  return HB_Err_Ok;
-
-Fail:
-  FREE( crr );
-
-  return error;
-}
-
-
-static void  Free_ClassDef2( HB_ClassDefFormat2*  cdf2 )
-{
-  FREE( cdf2->ClassRangeRecord );
-}
-
-
-/* ClassDefinition */
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_ClassDefinition( HB_ClassDefinition* cd,
-				HB_UShort             limit,
-				HB_Stream             stream )
-{
-  HB_Error   error;
-
-  if ( ACCESS_Frame( 2L ) )
-    return error;
-
-  cd->ClassFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  switch ( cd->ClassFormat )
-  {
-  case 1:  error = Load_ClassDef1( cd, limit, stream ); break;
-  case 2:  error = Load_ClassDef2( cd, limit, stream ); break;
-  default: error = ERR(HB_Err_Invalid_SubTable_Format);	break;
-  }
-
-  if ( error )
-    return error;
-
-  cd->loaded = TRUE;
-
-  return HB_Err_Ok;
-}
-
-
-static HB_Error
-_HB_OPEN_Load_EmptyClassDefinition( HB_ClassDefinition*  cd )
-{
-  HB_Error   error;
-
-  cd->ClassFormat = 1; /* Meaningless */
-
-  if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, HB_UShort ) )
-    return error;
-
-  cd->loaded = TRUE;
-
-  return HB_Err_Ok;
-}
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd,
-					       HB_UShort             limit,
-					       HB_UInt              class_offset,
-					       HB_UInt              base_offset,
-					       HB_Stream             stream )
-{
-  HB_Error error;
-  HB_UInt               cur_offset;
-
-  cur_offset = FILE_Pos();
-
-  if ( class_offset )
-    {
-      if ( !FILE_Seek( class_offset + base_offset ) )
-	error = _HB_OPEN_Load_ClassDefinition( cd, limit, stream );
-    }
-  else
-     error = _HB_OPEN_Load_EmptyClassDefinition ( cd );
-
-  if (error == HB_Err_Ok)
-    (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */
-
-  return error;
-}
-
-HB_INTERNAL void
-_HB_OPEN_Free_ClassDefinition( HB_ClassDefinition*  cd )
-{
-  if ( !cd->loaded )
-    return;
-
-  switch ( cd->ClassFormat )
-  {
-  case 1:  Free_ClassDef1( &cd->cd.cd1 ); break;
-  case 2:  Free_ClassDef2( &cd->cd.cd2 ); break;
-  default:				  break;
-  }
-}
-
-
-static HB_Error  Get_Class1( HB_ClassDefFormat1*  cdf1,
-			     HB_UShort             glyphID,
-			     HB_UShort*            klass,
-			     HB_UShort*            index )
-{
-  HB_UShort*  cva = cdf1->ClassValueArray;
-
-
-  if ( index )
-    *index = 0;
-
-  if ( glyphID >= cdf1->StartGlyph &&
-       glyphID < cdf1->StartGlyph + cdf1->GlyphCount )
-  {
-    *klass = cva[glyphID - cdf1->StartGlyph];
-    return HB_Err_Ok;
-  }
-  else
-  {
-    *klass = 0;
-    return HB_Err_Not_Covered;
-  }
-}
-
-
-/* we need the index value of the last searched class range record
-   in case of failure for constructed GDEF tables                  */
-
-static HB_Error  Get_Class2( HB_ClassDefFormat2*  cdf2,
-			     HB_UShort             glyphID,
-			     HB_UShort*            klass,
-			     HB_UShort*            index )
-{
-  HB_Error               error = HB_Err_Ok;
-  HB_UShort              min, max, new_min, new_max, middle;
-
-  HB_ClassRangeRecord*  crr = cdf2->ClassRangeRecord;
-
-
-  /* binary search */
-
-  if ( cdf2->ClassRangeCount == 0 )
-    {
-      *klass = 0;
-      if ( index )
-	*index = 0;
-      
-      return HB_Err_Not_Covered;
-    }
-
-  new_min = 0;
-  new_max = cdf2->ClassRangeCount - 1;
-
-  do
-  {
-    min = new_min;
-    max = new_max;
-
-    /* we use (min + max) / 2 = max - (max - min) / 2  to avoid
-       overflow and rounding errors                             */
-
-    middle = max - ( ( max - min ) >> 1 );
-
-    if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End )
-    {
-      *klass = crr[middle].Class;
-      error  = HB_Err_Ok;
-      break;
-    }
-    else if ( glyphID < crr[middle].Start )
-    {
-      if ( middle == min )
-      {
-	*klass = 0;
-	error  = HB_Err_Not_Covered;
-	break;
-      }
-      new_max = middle - 1;
-    }
-    else
-    {
-      if ( middle == max )
-      {
-	*klass = 0;
-	error  = HB_Err_Not_Covered;
-	break;
-      }
-      new_min = middle + 1;
-    }
-  } while ( min < max );
-
-  if ( index )
-    *index = middle;
-
-  return error;
-}
-
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Get_Class( HB_ClassDefinition* cd,
-		     HB_UShort             glyphID,
-		    HB_UShort*          klass,
-		     HB_UShort*            index )
-{
-  switch ( cd->ClassFormat )
-  {
-  case 1:  return Get_Class1( &cd->cd.cd1, glyphID, klass, index );
-  case 2:  return Get_Class2( &cd->cd.cd2, glyphID, klass, index );
-  default: return ERR(HB_Err_Invalid_SubTable_Format);
-  }
-
-  return HB_Err_Ok;               /* never reached */
-}
-
-
-
-/***************************
- * Device related functions
- ***************************/
-
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Load_Device( HB_Device* d,
-		       HB_Stream    stream )
-{
-  HB_Error   error;
-
-  HB_UShort   n, count;
-
-  HB_UShort*  dv;
-
-
-  if ( ACCESS_Frame( 6L ) )
-    return error;
-
-  d->StartSize   = GET_UShort();
-  d->EndSize     = GET_UShort();
-  d->DeltaFormat = GET_UShort();
-
-  FORGET_Frame();
-
-  d->DeltaValue = NULL;
-
-  if ( d->StartSize > d->EndSize ||
-       d->DeltaFormat == 0 || d->DeltaFormat > 3 )
-    {
-      /* XXX
-       * I've seen fontforge generate DeltaFormat == 0.
-       * Just return Ok and let the NULL DeltaValue disable
-       * this table.
-       */
-      return HB_Err_Ok;
-    }
-
-  count = ( ( d->EndSize - d->StartSize + 1 ) >>
-	      ( 4 - d->DeltaFormat ) ) + 1;
-
-  if ( ALLOC_ARRAY( d->DeltaValue, count, HB_UShort ) )
-    return error;
-
-  if ( ACCESS_Frame( count * 2L ) )
-  {
-    FREE( d->DeltaValue );
-    return error;
-  }
-
-  dv = d->DeltaValue;
-
-  for ( n = 0; n < count; n++ )
-    dv[n] = GET_UShort();
-
-  FORGET_Frame();
-
-  return HB_Err_Ok;
-}
-
-
-HB_INTERNAL void
-_HB_OPEN_Free_Device( HB_Device* d )
-{
-  FREE( d->DeltaValue );
-}
-
-
-/* Since we have the delta values stored in compressed form, we must
-   uncompress it now.  To simplify the interface, the function always
-   returns a meaningful value in `value'; the error is just for
-   information.
-			       |                |
-   format = 1: 0011223344556677|8899101112131415|...
-			       |                |
-		    byte 1           byte 2
-
-     00: (byte >> 14) & mask
-     11: (byte >> 12) & mask
-     ...
-
-     mask = 0x0003
-			       |                |
-   format = 2: 0000111122223333|4444555566667777|...
-			       |                |
-		    byte 1           byte 2
-
-     0000: (byte >> 12) & mask
-     1111: (byte >>  8) & mask
-     ...
-
-     mask = 0x000F
-			       |                |
-   format = 3: 0000000011111111|2222222233333333|...
-			       |                |
-		    byte 1           byte 2
-
-     00000000: (byte >> 8) & mask
-     11111111: (byte >> 0) & mask
-     ....
-
-     mask = 0x00FF                                    */
-
-HB_INTERNAL HB_Error
-_HB_OPEN_Get_Device( HB_Device* d,
-		      HB_UShort    size,
-		      HB_Short*    value )
-{
-  HB_UShort  byte, bits, mask, f, s;
-
-
-  f = d->DeltaFormat;
-
-  if ( d->DeltaValue && size >= d->StartSize && size <= d->EndSize )
-  {
-    s    = size - d->StartSize;
-    byte = d->DeltaValue[s >> ( 4 - f )];
-    bits = byte >> ( 16 - ( ( s % ( 1 << ( 4 - f ) ) + 1 ) << f ) );
-    mask = 0xFFFF >> ( 16 - ( 1 << f ) );
-
-    *value = (HB_Short)( bits & mask );
-
-    /* conversion to a signed value */
-
-    if ( *value >= ( ( mask + 1 ) >> 1 ) )
-      *value -= mask + 1;
-
-    return HB_Err_Ok;
-  }
-  else
-  {
-    *value = 0;
-    return HB_Err_Not_Covered;
-  }
-}
-
-
-/* END */
diff --git a/third_party/harfbuzz/src/harfbuzz-open.h b/third_party/harfbuzz/src/harfbuzz-open.h
deleted file mode 100644
index bdc6358..0000000
--- a/third_party/harfbuzz/src/harfbuzz-open.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_OPEN_H
-#define HARFBUZZ_OPEN_H
-
-#include "harfbuzz-global.h"
-
-HB_BEGIN_HEADER
-
-/* Use this if a feature applies to all glyphs */
-#define HB_ALL_GLYPHS                    0xFFFF
-
-#define HB_DEFAULT_LANGUAGE              0xFFFF
-
-#define HB_MAX_NESTING_LEVEL             100
-
-
-/* Script list related structures */
-
-struct  HB_LangSys_
-{
-  HB_UShort   LookupOrderOffset;      /* always 0 for TT Open 1.0  */
-  HB_UShort   ReqFeatureIndex;        /* required FeatureIndex     */
-  HB_UShort   FeatureCount;           /* number of Feature indices */
-  HB_UShort*  FeatureIndex;           /* array of Feature indices  */
-};
-
-typedef struct HB_LangSys_  HB_LangSys;
-
-
-struct  HB_LangSysRecord_
-{
-  HB_UInt     LangSysTag;            /* LangSysTag identifier */
-  HB_LangSys  LangSys;               /* LangSys table         */
-};
-
-typedef struct HB_LangSysRecord_  HB_LangSysRecord;
-
-
-struct  HB_ScriptTable_
-{
-  HB_LangSys         DefaultLangSys; /* DefaultLangSys table     */
-  HB_UShort           LangSysCount;   /* number of LangSysRecords */
-  HB_LangSysRecord*  LangSysRecord;  /* array of LangSysRecords  */
-};
-
-typedef struct HB_ScriptTable_  HB_ScriptTable;
-
-
-struct  HB_ScriptRecord_
-{
-  HB_UInt        ScriptTag;              /* ScriptTag identifier */
-  HB_ScriptTable  Script;                 /* Script table         */
-};
-
-typedef struct HB_ScriptRecord_  HB_ScriptRecord;
-
-
-struct  HB_ScriptList_
-{
-  HB_UShort          ScriptCount;     /* number of ScriptRecords */
-  HB_ScriptRecord*  ScriptRecord;    /* array of ScriptRecords  */
-};
-
-typedef struct HB_ScriptList_  HB_ScriptList;
-
-
-/* Feature list related structures */
-
-struct HB_Feature_
-{
-  HB_UShort   FeatureParams;          /* always 0 for TT Open 1.0     */
-  HB_UShort   LookupListCount;        /* number of LookupList indices */
-  HB_UShort*  LookupListIndex;        /* array of LookupList indices  */
-};
-
-typedef struct HB_Feature_  HB_Feature;
-
-
-struct  HB_FeatureRecord_
-{
-  HB_UInt     FeatureTag;            /* FeatureTag identifier */
-  HB_Feature  Feature;               /* Feature table         */
-};
-
-typedef struct HB_FeatureRecord_  HB_FeatureRecord;
-
-
-struct  HB_FeatureList_
-{
-  HB_UShort           FeatureCount;   /* number of FeatureRecords */
-  HB_FeatureRecord*  FeatureRecord;  /* array of FeatureRecords  */
-  HB_UShort*		ApplyOrder;	/* order to apply features */
-  HB_UShort		ApplyCount;	/* number of elements in ApplyOrder */
-};
-
-typedef struct HB_FeatureList_  HB_FeatureList;
-
-
-/* Lookup list related structures */
-
-typedef struct HB_SubTable_  HB_SubTable;
-
-
-struct  HB_Lookup_
-{
-  HB_UShort      LookupType;          /* Lookup type         */
-  HB_UShort      LookupFlag;          /* Lookup qualifiers   */
-  HB_UShort      SubTableCount;       /* number of SubTables */
-  HB_SubTable*  SubTable;            /* array of SubTables  */
-};
-
-typedef struct HB_Lookup_  HB_Lookup;
-
-
-/* The `Properties' field is not defined in the OpenType specification but
-   is needed for processing lookups.  If properties[n] is > 0, the
-   functions HB_GSUB_Apply_String() resp. HB_GPOS_Apply_String() will
-   process Lookup[n] for glyphs which have the specific bit not set in
-   the `properties' field of the input string object.                  */
-
-struct  HB_LookupList_
-{
-  HB_UShort    LookupCount;           /* number of Lookups       */
-  HB_Lookup*  Lookup;                /* array of Lookup records */
-  HB_UInt*     Properties;            /* array of flags          */
-};
-
-typedef struct HB_LookupList_  HB_LookupList;
-
-
-/* Possible LookupFlag bit masks.  `HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS' comes from the
-   OpenType 1.2 specification; HB_LOOKUP_FLAG_RIGHT_TO_LEFT has been (re)introduced in
-   OpenType 1.3 -- if set, the last glyph in a cursive attachment
-   sequence has to be positioned on the baseline -- regardless of the
-   writing direction.                                                    */
-
-#define HB_LOOKUP_FLAG_RIGHT_TO_LEFT         0x0001
-#define HB_LOOKUP_FLAG_IGNORE_BASE_GLYPHS    0x0002
-#define HB_LOOKUP_FLAG_IGNORE_LIGATURES      0x0004
-#define HB_LOOKUP_FLAG_IGNORE_MARKS          0x0008
-#define HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS  0xFF00
-
-
-struct  HB_CoverageFormat1_
-{
-  HB_UShort   GlyphCount;             /* number of glyphs in GlyphArray */
-  HB_UShort*  GlyphArray;             /* array of glyph IDs             */
-};
-
-typedef struct HB_CoverageFormat1_  HB_CoverageFormat1;
-
-
-struct HB_RangeRecord_
-{
-  HB_UShort  Start;                   /* first glyph ID in the range */
-  HB_UShort  End;                     /* last glyph ID in the range  */
-  HB_UShort  StartCoverageIndex;      /* coverage index of first
-					 glyph ID in the range       */
-};
-
-typedef struct HB_RangeRecord_  HB_RangeRecord;
-
-
-struct  HB_CoverageFormat2_
-{
-  HB_UShort         RangeCount;       /* number of RangeRecords */
-  HB_RangeRecord*  RangeRecord;      /* array of RangeRecords  */
-};
-
-typedef struct HB_CoverageFormat2_  HB_CoverageFormat2;
-
-
-struct  HB_Coverage_
-{
-  HB_UShort  CoverageFormat;          /* 1 or 2 */
-
-  union
-  {
-    HB_CoverageFormat1  cf1;
-    HB_CoverageFormat2  cf2;
-  } cf;
-};
-
-typedef struct HB_Coverage_  HB_Coverage;
-
-
-struct  HB_ClassDefFormat1_
-{
-  HB_UShort   StartGlyph;             /* first glyph ID of the
-					 ClassValueArray             */
-  HB_UShort   GlyphCount;             /* size of the ClassValueArray */
-  HB_UShort*  ClassValueArray;        /* array of class values       */
-};
-
-typedef struct HB_ClassDefFormat1_  HB_ClassDefFormat1;
-
-
-struct  HB_ClassRangeRecord_
-{
-  HB_UShort  Start;                   /* first glyph ID in the range    */
-  HB_UShort  End;                     /* last glyph ID in the range     */
-  HB_UShort  Class;                   /* applied to all glyphs in range */
-};
-
-typedef struct HB_ClassRangeRecord_  HB_ClassRangeRecord;
-
-
-struct  HB_ClassDefFormat2_
-{
-  HB_UShort              ClassRangeCount;
-				      /* number of ClassRangeRecords */
-  HB_ClassRangeRecord*  ClassRangeRecord;
-				      /* array of ClassRangeRecords  */
-};
-
-typedef struct HB_ClassDefFormat2_  HB_ClassDefFormat2;
-
-
-struct  HB_ClassDefinition_
-{
-  HB_Bool    loaded;
-
-  HB_UShort  ClassFormat;             /* 1 or 2                      */
-
-  union
-  {
-    HB_ClassDefFormat1  cd1;
-    HB_ClassDefFormat2  cd2;
-  } cd;
-};
-
-typedef struct HB_ClassDefinition_  HB_ClassDefinition;
-
-
-struct HB_Device_
-{
-  HB_UShort   StartSize;              /* smallest size to correct      */
-  HB_UShort   EndSize;                /* largest size to correct       */
-  HB_UShort   DeltaFormat;            /* DeltaValue array data format:
-					 1, 2, or 3                    */
-  HB_UShort*  DeltaValue;             /* array of compressed data      */
-};
-
-typedef struct HB_Device_  HB_Device;
-
-
-enum  HB_Type_
-{
-  HB_Type_GSUB,
-  HB_Type_GPOS
-};
-
-typedef enum HB_Type_  HB_Type;
-
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_OPEN_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-shape.h b/third_party/harfbuzz/src/harfbuzz-shape.h
deleted file mode 100644
index e4b5f9a..0000000
--- a/third_party/harfbuzz/src/harfbuzz-shape.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2006  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor
- */
-
-#include <stdint.h>
-
-/* Base Types */
-
-typedef hb_uint16 HB_CodePoint; /* UTF-16 codepoint (not character ) */
-typedef char HB_Boolean;
-typedef hb_uint32 HB_Fixed; /* 26.6 */
-typedef hb_uint32 HB_Glyph;
-typedef hb_uint32 HB_Unichar;
-
-/* Metrics reported by the font backend for use of the shaper */
-typedef struct _HB_GlyphMetrics HB_GlyphMetrics;
-struct _HB_GlyphMetrics
-{
-    HB_Fixed advance;
-    
-    /* Do we need ink/logical extents for the glyph here? */
-};
-
-/*
- * HB_Font: Abstract font interface.
- *  First pass of this might just have FT_Face *getFace();
- */
-typedef struct _HB_Font HB_Font;
-typedef struct _HB_FontClass HB_FontClass;
-
-struct HB_FontClass {
-    HB_Glyph   (*charToGlyph)(HB_Font *font, HB_Unichar chr);
-    void       (*getMetrics)(HB_Font *font, HB_Glyph glyph, HB_GlyphMetrics *metrics);
-    HB_Boolean (*getSFontTable)(HB_Font *font, void **cookie, char **start, int *len);
-    HB_Boolean (*freeSFontTable)(void **cookie);
-};
-
-struct _HB_Font {
-    HB_FontClass *clazz;
-};
-
-/*
- * Language tags, of the form en-us; represented as interned, canonicalized
- * strings. hb_language_from_string("en_US"), hb_language_from_string("en-us")
- * both return the same (pointer-comparable) HB_Language).
- */
-typedef struct HB_Language_ *HB_Language;
-
-HB_Language hb_language_from_string(const char *str);
-const char *hb_language_to_string(HB_Language language);
-
-/* Special treatment for the edges of runs.
- */
-typedef enum {
-    HB_RUN_EDGE_LINE_VISUAL_EDGE    = 1 << 0,
-    HB_RUN_EDGE_LINE_LOGICAL_EDGE   = 1 << 1,
-    HB_RUN_EDGE_LINE_ADD_HYPHEN     = 1 << 2  /* ???? */
-} HB_RunEdge;
-
-/* Defines optional informaiton in HB_ShapeInput; this allows extension
- * of HB_ShapeInput while keeping binary compatibility
- */
-typedef enum {
-    HB_SHAPE_START_TYPE = 1 << 0,
-    HB_SHAPE_END_TYPE   = 1 << 1
-} HB_ShapeFlags;
-
-/* Attributes types are described by "interned strings"; this is a little
- * annoying if you want to write a switch statement, but keeps things
- * simple.
- */
-typedef struct _HB_AttributeType *HB_AttributeType;
-
-HB_AttributeType hb_attribute_type_from_string(const char *str);
-const char *hb_attribute_type_to_string(HB_AttributeType attribute_type);
-
-struct HB_Attribute {
-    HB_AttributeType type;
-    int start; 
-    int end;
-};
-
-
-/**
- * You could handle this like HB_Language, but an enum seems a little nicer;
- * another approach would be to use OpenType script tags.
- */
-typedef enum {
-    HB_SCRIPT_LATIN
-    /* ... */
-} HB_ShapeScript;
-
-/* This is just the subset of direction information needed by the shaper */
-typedef enum {
-    HB_DIRECTION_LTR,
-    HB_DIRECTION_RTL,
-    HB_DIRECTION_TTB
-} HB_Direction;
-
-typedef struct _HB_ShapeInput HB_ShapeInput;
-struct _HB_ShapeInput {
-    /* Defines what fields the caller has initialized - fields not in
-     * the enum are mandatory.
-     */
-    HB_ShapeFlags flags;
-    
-    HB_CodePoint *text;
-    int length;       /* total length of text to shape */
-    int shape_offset; /* start of section to shape */
-    int shape_length; /* number of code points to shape */
-
-    HB_Direction direction;
-    HB_ShapeScript script;
-    HB_Language language;
-
-    HB_AttributeType *attributes;
-    int n_attributes;
-
-    HB_RunEdge start_type;
-    HB_RunEdge end_type;
-};
-
-struct HB_GlyphItem {
-    HB_Glyph glyph;
-    
-    HB_Fixed x_offset;
-    HB_Fixed y_offset;
-    HB_Fixed advance;
-
-    /* Add kashida information, etc, here */
-};
-
-typedef enum {
-    HB_RESULT_SUCCESS,
-    HB_RESULT_NO_MEMORY,
-    HB_SHAPE_RESULT_FAILED
-} HB_Result;
-
-/*
- * Buffer for output 
- */
-typedef struct _HB_GlyphBuffer HB_GlyphBuffer;
-struct _HB_GlyphBuffer {
-    int glyph_item_size;
-    int total_glyphs;
-    
-    int *log_clusters; /* Uniscribe style */
-    int cluster_space;
-  
-    int glyph_space;
-    void *glyph_buffer;
-};
-
-/* Making this self-allocating simplifies writing shapers and
- * also keeps things easier for caller. item_size passed in
- * must be at least sizeof(HB_GlyphItem) but can be bigger,
- * to accomodate application structures that extend HB_GlyphItem.
- * The allocated items will be zero-initialized.
- *
- * (Hack: Harfbuzz could choose to use even a *bigger* item size
- * and stick internal information before the public item structure.
- * This hack could possibly be used to unify this with HB_Buffer)
- */
-HB_GlyphBuffer *hb_glyph_buffer_new             (size_t item_size);
-void            hb_glyph_buffer_clear           (HB_GlyphBuffer *buf);
-HB_Result       hb_glyph_buffer_extend_glyphs   (HB_GlyphBuffer *buf, int n_items);
-HB_Result       hb_glyph_buffer_extend_clusters (HB_GlyphBuffer *buf, int n_clusters);
-void            hb_glyph_buffer_free            (HB_GlyphBuffer *buf);
-
-
-/* Accessor for a particular glyph */
-#define HB_GLYPH_BUFFER_ITEM(buffer, index)
-
-/*
- * Main shaping function
- */
-HB_Result hb_shape(HB_ShapeInput *input, HB_GlyphBuffer *output);
diff --git a/third_party/harfbuzz/src/harfbuzz-shaper-all.cpp b/third_party/harfbuzz/src/harfbuzz-shaper-all.cpp
deleted file mode 100644
index d2f902f..0000000
--- a/third_party/harfbuzz/src/harfbuzz-shaper-all.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.cpp"
-#include "harfbuzz-indic.cpp"
-extern "C" {
-#include "harfbuzz-tibetan.c"
-#include "harfbuzz-khmer.c"
-#include "harfbuzz-hebrew.c"
-#include "harfbuzz-arabic.c"
-#include "harfbuzz-hangul.c"
-#include "harfbuzz-myanmar.c"
-#include "harfbuzz-thai.c"
-}
-
diff --git a/third_party/harfbuzz/src/harfbuzz-shaper-private.h b/third_party/harfbuzz/src/harfbuzz-shaper-private.h
deleted file mode 100644
index 80bccf8..0000000
--- a/third_party/harfbuzz/src/harfbuzz-shaper-private.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_SHAPER_PRIVATE_H
-#define HARFBUZZ_SHAPER_PRIVATE_H
-
-HB_BEGIN_HEADER
-
-enum {
-    C_DOTTED_CIRCLE = 0x25CC
-};
-
-typedef enum 
-{
-    HB_Combining_BelowLeftAttached       = 200,
-    HB_Combining_BelowAttached           = 202,
-    HB_Combining_BelowRightAttached      = 204,
-    HB_Combining_LeftAttached            = 208,
-    HB_Combining_RightAttached           = 210,
-    HB_Combining_AboveLeftAttached       = 212,
-    HB_Combining_AboveAttached           = 214,
-    HB_Combining_AboveRightAttached      = 216,
-
-    HB_Combining_BelowLeft               = 218,
-    HB_Combining_Below                   = 220,
-    HB_Combining_BelowRight              = 222,
-    HB_Combining_Left                    = 224,
-    HB_Combining_Right                   = 226,
-    HB_Combining_AboveLeft               = 228,
-    HB_Combining_Above                   = 230,
-    HB_Combining_AboveRight              = 232,
-
-    HB_Combining_DoubleBelow             = 233,
-    HB_Combining_DoubleAbove             = 234,
-    HB_Combining_IotaSubscript           = 240
-} HB_CombiningClass;
-
-typedef enum {
-    CcmpProperty = 0x1,
-    InitProperty = 0x2,
-    IsolProperty = 0x4,
-    FinaProperty = 0x8,
-    MediProperty = 0x10,
-    RligProperty = 0x20,
-    CaltProperty = 0x40,
-    LigaProperty = 0x80,
-    DligProperty = 0x100,
-    CswhProperty = 0x200,
-    MsetProperty = 0x400,
-
-    /* used by indic and myanmar shaper */
-    NuktaProperty = 0x4,
-    AkhantProperty = 0x8,
-    RephProperty = 0x10,
-    PreFormProperty = 0x20,
-    BelowFormProperty = 0x40,
-    AboveFormProperty = 0x80,
-    HalfFormProperty = 0x100,
-    PostFormProperty = 0x200,
-    VattuProperty = 0x400,
-    PreSubstProperty = 0x800,
-    BelowSubstProperty = 0x1000,
-    AboveSubstProperty = 0x2000,
-    PostSubstProperty = 0x4000,
-    HalantProperty = 0x8000,
-    CligProperty = 0x10000
-
-} HB_OpenTypeProperty;
-
-/* return true if ok. */
-typedef HB_Bool (*HB_ShapeFunction)(HB_ShaperItem *shaper_item);
-typedef void (*HB_AttributeFunction)(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
-
-typedef struct {
-    HB_ShapeFunction shape;
-    HB_AttributeFunction charAttributes;
-} HB_ScriptEngine;
-
-extern const HB_ScriptEngine hb_scriptEngines[];
-
-extern HB_Bool HB_BasicShape(HB_ShaperItem *shaper_item);
-extern HB_Bool HB_TibetanShape(HB_ShaperItem *shaper_item);
-extern HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item);
-extern HB_Bool HB_ArabicShape(HB_ShaperItem *shaper_item);
-extern HB_Bool HB_HangulShape(HB_ShaperItem *shaper_item);
-extern HB_Bool HB_MyanmarShape(HB_ShaperItem *shaper_item);
-extern HB_Bool HB_KhmerShape(HB_ShaperItem *shaper_item);
-extern HB_Bool HB_IndicShape(HB_ShaperItem *shaper_item);
-
-extern void HB_TibetanAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
-
-extern void HB_MyanmarAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
-
-extern void HB_KhmerAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
-
-extern void HB_IndicAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
-
-extern void HB_ThaiAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
-
-typedef struct {
-    hb_uint32 tag;
-    hb_uint32 property;
-} HB_OpenTypeFeature;
-
-#define PositioningProperties 0x80000000
-
-HB_Bool HB_SelectScript(HB_ShaperItem *item, const HB_OpenTypeFeature *features);
-
-HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_uint32 *properties);
-HB_Bool HB_OpenTypePosition(HB_ShaperItem *item, int availableGlyphs, HB_Bool doLogClusters);
-
-void HB_HeuristicPosition(HB_ShaperItem *item);
-void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item);
-
-#define HB_IsControlChar(uc) \
-    ((uc >= 0x200b && uc <= 0x200f /* ZW Space, ZWNJ, ZWJ, LRM and RLM */) \
-     || (uc >= 0x2028 && uc <= 0x202f /* LS, PS, LRE, RLE, PDF, LRO, RLO, NNBSP */) \
-     || (uc >= 0x206a && uc <= 0x206f /* ISS, ASS, IAFS, AFS, NADS, NODS */))
-
-HB_Bool HB_ConvertStringToGlyphIndices(HB_ShaperItem *shaper_item);
-
-#define HB_GetGlyphAdvances(shaper_item) \
-    shaper_item->font->klass->getGlyphAdvances(shaper_item->font, \
-                                               shaper_item->glyphs, shaper_item->num_glyphs, \
-                                               shaper_item->advances, \
-                                               shaper_item->face->current_flags);
-
-#define HB_DECLARE_STACKARRAY(Type, Name) \
-    Type stack##Name[512]; \
-    Type *Name = stack##Name;
-
-#define HB_INIT_STACKARRAY(Type, Name, Length) \
-    if ((Length) >= 512) \
-        Name = (Type *)malloc((Length) * sizeof(Type));
-
-#define HB_STACKARRAY(Type, Name, Length) \
-    HB_DECLARE_STACKARRAY(Type, Name) \
-    HB_INIT_STACKARRAY(Type, Name, Length)
-
-#define HB_FREE_STACKARRAY(Name) \
-    if (stack##Name != Name) \
-        free(Name);
-
-HB_END_HEADER
-
-#endif
diff --git a/third_party/harfbuzz/src/harfbuzz-shaper.cpp b/third_party/harfbuzz/src/harfbuzz-shaper.cpp
deleted file mode 100644
index f1606e6..0000000
--- a/third_party/harfbuzz/src/harfbuzz-shaper.cpp
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include "harfbuzz-stream-private.h"
-#include <assert.h>
-#include <stdio.h>
-
-#define HB_MIN(a, b) ((a) < (b) ? (a) : (b))
-#define HB_MAX(a, b) ((a) > (b) ? (a) : (b))
-
-// -----------------------------------------------------------------------------------------------------
-//
-// The line break algorithm. See http://www.unicode.org/reports/tr14/tr14-13.html
-//
-// -----------------------------------------------------------------------------------------------------
-
-/* The Unicode algorithm does in our opinion allow line breaks at some
-   places they shouldn't be allowed. The following changes were thus
-   made in comparison to the Unicode reference:
-
-   EX->AL from DB to IB
-   SY->AL from DB to IB
-   SY->PO from DB to IB
-   SY->PR from DB to IB
-   SY->OP from DB to IB
-   AL->PR from DB to IB
-   AL->PO from DB to IB
-   PR->PR from DB to IB
-   PO->PO from DB to IB
-   PR->PO from DB to IB
-   PO->PR from DB to IB
-   HY->PO from DB to IB
-   HY->PR from DB to IB
-   HY->OP from DB to IB
-   NU->EX from PB to IB
-   EX->PO from DB to IB
-*/
-
-// The following line break classes are not treated by the table:
-//  AI, BK, CB, CR, LF, NL, SA, SG, SP, XX
-
-enum break_class {
-    // the first 4 values have to agree with the enum in QCharAttributes
-    ProhibitedBreak,            // PB in table
-    DirectBreak,                // DB in table
-    IndirectBreak,              // IB in table
-    CombiningIndirectBreak,     // CI in table
-    CombiningProhibitedBreak    // CP in table
-};
-#define DB DirectBreak
-#define IB IndirectBreak
-#define CI CombiningIndirectBreak
-#define CP CombiningProhibitedBreak
-#define PB ProhibitedBreak
-
-static const hb_uint8 breakTable[HB_LineBreak_JT+1][HB_LineBreak_JT+1] =
-{
-/*          OP  CL  QU  GL  NS  EX  SY  IS  PR  PO  NU  AL  ID  IN  HY  BA  BB  B2  ZW  CM  WJ  H2  H3  JL  JV  JT */
-/* OP */ { PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, CP, PB, PB, PB, PB, PB, PB },
-/* CL */ { DB, PB, IB, IB, PB, PB, PB, PB, IB, IB, IB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* QU */ { PB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, IB, IB, IB, IB, IB, PB, CI, PB, IB, IB, IB, IB, IB },
-/* GL */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, IB, IB, IB, IB, IB, PB, CI, PB, IB, IB, IB, IB, IB },
-/* NS */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, DB, DB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* EX */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* SY */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* IS */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, IB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* PR */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, DB, IB, IB, DB, DB, PB, CI, PB, IB, IB, IB, IB, IB },
-/* PO */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* NU */ { IB, PB, IB, IB, IB, IB, PB, PB, IB, IB, IB, IB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* AL */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* ID */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* IN */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* HY */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, DB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* BA */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, DB, DB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* BB */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, IB, IB, IB, IB, IB, PB, CI, PB, IB, IB, IB, IB, IB },
-/* B2 */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, DB, DB, DB, DB, IB, IB, DB, PB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* ZW */ { DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, PB, DB, DB, DB, DB, DB, DB, DB },
-/* CM */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, IB, IB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },
-/* WJ */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, IB, IB, IB, IB, IB, PB, CI, PB, IB, IB, IB, IB, IB },
-/* H2 */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, IB, IB },
-/* H3 */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, IB },
-/* JL */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, IB, IB, IB, IB, DB },
-/* JV */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, IB, IB },
-/* JT */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, IB }
-};
-#undef DB
-#undef IB
-#undef CI
-#undef CP
-#undef PB
-
-static const hb_uint8 graphemeTable[HB_Grapheme_LVT + 1][HB_Grapheme_LVT + 1] =
-{
-//      Other, CR,    LF,    Control,Extend,L,    V,     T,     LV,    LVT
-    { true , true , true , true , true , true , true , true , true , true  }, // Other, 
-    { true , true , true , true , true , true , true , true , true , true  }, // CR,
-    { true , false, true , true , true , true , true , true , true , true  }, // LF,
-    { true , true , true , true , true , true , true , true , true , true  }, // Control,
-    { false, true , true , true , false, false, false, false, false, false }, // Extend,
-    { true , true , true , true , true , false, true , true , true , true  }, // L, 
-    { true , true , true , true , true , false, false, true , false, true  }, // V, 
-    { true , true , true , true , true , true , false, false, false, false }, // T, 
-    { true , true , true , true , true , false, true , true , true , true  }, // LV, 
-    { true , true , true , true , true , false, true , true , true , true  }, // LVT
-};
-    
-static void calcLineBreaks(const HB_UChar16 *uc, hb_uint32 len, HB_CharAttributes *charAttributes)
-{
-    if (!len)
-        return;
-
-    // ##### can this fail if the first char is a surrogate?
-    HB_LineBreakClass cls;
-    HB_GraphemeClass grapheme;
-    HB_GetGraphemeAndLineBreakClass(*uc, &grapheme, &cls);
-    // handle case where input starts with an LF
-    if (cls == HB_LineBreak_LF)
-        cls = HB_LineBreak_BK;
-
-    charAttributes[0].whiteSpace = (cls == HB_LineBreak_SP || cls == HB_LineBreak_BK);
-    charAttributes[0].charStop = true;
-
-    int lcls = cls;
-    for (hb_uint32 i = 1; i < len; ++i) {
-        charAttributes[i].whiteSpace = false;
-        charAttributes[i].charStop = true;
-
-        HB_UChar32 code = uc[i];
-        HB_GraphemeClass ngrapheme;
-        HB_LineBreakClass ncls;
-        HB_GetGraphemeAndLineBreakClass(code, &ngrapheme, &ncls);
-        charAttributes[i].charStop = graphemeTable[ngrapheme][grapheme];
-        // handle surrogates
-        if (ncls == HB_LineBreak_SG) {
-            if (HB_IsHighSurrogate(uc[i]) && i < len - 1 && HB_IsLowSurrogate(uc[i+1])) {
-                continue;
-            } else if (HB_IsLowSurrogate(uc[i]) && HB_IsHighSurrogate(uc[i-1])) {
-                code = HB_SurrogateToUcs4(uc[i-1], uc[i]);
-                HB_GetGraphemeAndLineBreakClass(code, &ngrapheme, &ncls);
-                charAttributes[i].charStop = false;
-            } else {
-                ncls = HB_LineBreak_AL;
-            }
-        }
-
-        // set white space and char stop flag
-        if (ncls >= HB_LineBreak_SP)
-            charAttributes[i].whiteSpace = true;
-
-        HB_LineBreakType lineBreakType = HB_NoBreak;
-        if (cls >= HB_LineBreak_LF) {
-            lineBreakType = HB_ForcedBreak;
-        } else if(cls == HB_LineBreak_CR) {
-            lineBreakType = (ncls == HB_LineBreak_LF) ? HB_NoBreak : HB_ForcedBreak;
-        }
-
-        if (ncls == HB_LineBreak_SP)
-            goto next_no_cls_update;
-        if (ncls >= HB_LineBreak_CR)
-            goto next;
-
-        // two complex chars (thai or lao), thai_attributes might override, but here we do a best guess
-	if (cls == HB_LineBreak_SA && ncls == HB_LineBreak_SA) {
-            lineBreakType = HB_Break;
-            goto next;
-        }
-
-        {
-            int tcls = ncls;
-            if (tcls >= HB_LineBreak_SA)
-                tcls = HB_LineBreak_ID;
-            if (cls >= HB_LineBreak_SA)
-                cls = HB_LineBreak_ID;
-
-            int brk = breakTable[cls][tcls];
-            switch (brk) {
-            case DirectBreak:
-                lineBreakType = HB_Break;
-                if (uc[i-1] == 0xad) // soft hyphen
-                    lineBreakType = HB_SoftHyphen;
-                break;
-            case IndirectBreak:
-                lineBreakType = (lcls == HB_LineBreak_SP) ? HB_Break : HB_NoBreak;
-                break;
-            case CombiningIndirectBreak:
-                lineBreakType = HB_NoBreak;
-                if (lcls == HB_LineBreak_SP){
-                    if (i > 1)
-                        charAttributes[i-2].lineBreakType = HB_Break;
-                } else {
-                    goto next_no_cls_update;
-                }
-                break;
-            case CombiningProhibitedBreak:
-                lineBreakType = HB_NoBreak;
-                if (lcls != HB_LineBreak_SP)
-                    goto next_no_cls_update;
-            case ProhibitedBreak:
-            default:
-                break;
-            }
-        }
-    next:
-        cls = ncls;
-    next_no_cls_update:
-        lcls = ncls;
-        grapheme = ngrapheme;
-        charAttributes[i-1].lineBreakType = lineBreakType;
-    }
-    charAttributes[len-1].lineBreakType = HB_ForcedBreak;
-}
-
-// --------------------------------------------------------------------------------------------------------------------------------------------
-//
-// Basic processing
-//
-// --------------------------------------------------------------------------------------------------------------------------------------------
-
-static inline void positionCluster(HB_ShaperItem *item, int gfrom,  int glast)
-{
-    int nmarks = glast - gfrom;
-    assert(nmarks > 0);
-
-    HB_Glyph *glyphs = item->glyphs;
-    HB_GlyphAttributes *attributes = item->attributes;
-
-    HB_GlyphMetrics baseMetrics;
-    item->font->klass->getGlyphMetrics(item->font, glyphs[gfrom], &baseMetrics);
-
-    if (item->item.script == HB_Script_Hebrew
-        && (-baseMetrics.y) > baseMetrics.height)
-        // we need to attach below the baseline, because of the hebrew iud.
-        baseMetrics.height = -baseMetrics.y;
-
-//     qDebug("---> positionCluster: cluster from %d to %d", gfrom, glast);
-//     qDebug("baseInfo: %f/%f (%f/%f) off=%f/%f", baseInfo.x, baseInfo.y, baseInfo.width, baseInfo.height, baseInfo.xoff, baseInfo.yoff);
-
-    HB_Fixed size = item->font->klass->getFontMetric(item->font, HB_FontAscent) / 10;
-    HB_Fixed offsetBase = HB_FIXED_CONSTANT(1) + (size - HB_FIXED_CONSTANT(4)) / 4;
-    if (size > HB_FIXED_CONSTANT(4))
-        offsetBase += HB_FIXED_CONSTANT(4);
-    else
-        offsetBase += size;
-    //qreal offsetBase = (size - 4) / 4 + qMin<qreal>(size, 4) + 1;
-//     qDebug("offset = %f", offsetBase);
-
-    bool rightToLeft = item->item.bidiLevel % 2;
-
-    int i;
-    unsigned char lastCmb = 0;
-    HB_GlyphMetrics attachmentRect;
-    memset(&attachmentRect, 0, sizeof(attachmentRect));
-
-    for(i = 1; i <= nmarks; i++) {
-        HB_Glyph mark = glyphs[gfrom+i];
-        HB_GlyphMetrics markMetrics;
-        item->font->klass->getGlyphMetrics(item->font, mark, &markMetrics);
-        HB_FixedPoint p;
-        p.x = p.y = 0;
-//          qDebug("markInfo: %f/%f (%f/%f) off=%f/%f", markInfo.x, markInfo.y, markInfo.width, markInfo.height, markInfo.xoff, markInfo.yoff);
-
-        HB_Fixed offset = offsetBase;
-        unsigned char cmb = attributes[gfrom+i].combiningClass;
-
-        // ### maybe the whole position determination should move down to heuristicSetGlyphAttributes. Would save some
-        // bits  in the glyphAttributes structure.
-        if (cmb < 200) {
-            // fixed position classes. We approximate by mapping to one of the others.
-            // currently I added only the ones for arabic, hebrew, lao and thai.
-
-            // for Lao and Thai marks with class 0, see below (heuristicSetGlyphAttributes)
-
-            // add a bit more offset to arabic, a bit hacky
-            if (cmb >= 27 && cmb <= 36 && offset < 3)
-                offset +=1;
-            // below
-            if ((cmb >= 10 && cmb <= 18) ||
-                 cmb == 20 || cmb == 22 ||
-                 cmb == 29 || cmb == 32)
-                cmb = HB_Combining_Below;
-            // above
-            else if (cmb == 23 || cmb == 27 || cmb == 28 ||
-                      cmb == 30 || cmb == 31 || (cmb >= 33 && cmb <= 36))
-                cmb = HB_Combining_Above;
-            //below-right
-            else if (cmb == 9 || cmb == 103 || cmb == 118)
-                cmb = HB_Combining_BelowRight;
-            // above-right
-            else if (cmb == 24 || cmb == 107 || cmb == 122)
-                cmb = HB_Combining_AboveRight;
-            else if (cmb == 25)
-                cmb = HB_Combining_AboveLeft;
-            // fixed:
-            //  19 21
-
-        }
-
-        // combining marks of different class don't interact. Reset the rectangle.
-        if (cmb != lastCmb) {
-            //qDebug("resetting rect");
-            attachmentRect = baseMetrics;
-        }
-
-        switch(cmb) {
-        case HB_Combining_DoubleBelow:
-                // ### wrong in rtl context!
-        case HB_Combining_BelowLeft:
-            p.y += offset;
-        case HB_Combining_BelowLeftAttached:
-            p.x += attachmentRect.x - markMetrics.x;
-            p.y += (attachmentRect.y + attachmentRect.height) - markMetrics.y;
-            break;
-        case HB_Combining_Below:
-            p.y += offset;
-        case HB_Combining_BelowAttached:
-            p.x += attachmentRect.x - markMetrics.x;
-            p.y += (attachmentRect.y + attachmentRect.height) - markMetrics.y;
-
-            p.x += (attachmentRect.width - markMetrics.width) / 2;
-            break;
-        case HB_Combining_BelowRight:
-            p.y += offset;
-        case HB_Combining_BelowRightAttached:
-            p.x += attachmentRect.x + attachmentRect.width - markMetrics.width - markMetrics.x;
-            p.y += attachmentRect.y + attachmentRect.height - markMetrics.y;
-            break;
-        case HB_Combining_Left:
-            p.x -= offset;
-        case HB_Combining_LeftAttached:
-            break;
-        case HB_Combining_Right:
-            p.x += offset;
-        case HB_Combining_RightAttached:
-            break;
-        case HB_Combining_DoubleAbove:
-            // ### wrong in RTL context!
-        case HB_Combining_AboveLeft:
-            p.y -= offset;
-        case HB_Combining_AboveLeftAttached:
-            p.x += attachmentRect.x - markMetrics.x;
-            p.y += attachmentRect.y - markMetrics.y - markMetrics.height;
-            break;
-        case HB_Combining_Above:
-            p.y -= offset;
-        case HB_Combining_AboveAttached:
-            p.x += attachmentRect.x - markMetrics.x;
-            p.y += attachmentRect.y - markMetrics.y - markMetrics.height;
-
-            p.x += (attachmentRect.width - markMetrics.width) / 2;
-            break;
-        case HB_Combining_AboveRight:
-            p.y -= offset;
-        case HB_Combining_AboveRightAttached:
-            p.x += attachmentRect.x + attachmentRect.width - markMetrics.x - markMetrics.width;
-            p.y += attachmentRect.y - markMetrics.y - markMetrics.height;
-            break;
-
-        case HB_Combining_IotaSubscript:
-            default:
-                break;
-        }
-//          qDebug("char=%x combiningClass = %d offset=%f/%f", mark, cmb, p.x(), p.y());
-        markMetrics.x += p.x;
-        markMetrics.y += p.y;
-
-        HB_GlyphMetrics unitedAttachmentRect = attachmentRect;
-        unitedAttachmentRect.x = HB_MIN(attachmentRect.x, markMetrics.x);
-        unitedAttachmentRect.y = HB_MIN(attachmentRect.y, markMetrics.y);
-        unitedAttachmentRect.width = HB_MAX(attachmentRect.x + attachmentRect.width, markMetrics.x + markMetrics.width) - unitedAttachmentRect.x;
-        unitedAttachmentRect.height = HB_MAX(attachmentRect.y + attachmentRect.height, markMetrics.y + markMetrics.height) - unitedAttachmentRect.y;
-        attachmentRect = unitedAttachmentRect;
-
-        lastCmb = cmb;
-        if (rightToLeft) {
-            item->offsets[gfrom+i].x = p.x;
-            item->offsets[gfrom+i].y = p.y;
-        } else {
-            item->offsets[gfrom+i].x = p.x - baseMetrics.xOffset;
-            item->offsets[gfrom+i].y = p.y - baseMetrics.yOffset;
-        }
-        item->advances[gfrom+i] = 0;
-    }
-}
-
-void HB_HeuristicPosition(HB_ShaperItem *item)
-{
-    HB_GetGlyphAdvances(item);
-    HB_GlyphAttributes *attributes = item->attributes;
-
-    int cEnd = -1;
-    int i = item->num_glyphs;
-    while (i--) {
-        if (cEnd == -1 && attributes[i].mark) {
-            cEnd = i;
-        } else if (cEnd != -1 && !attributes[i].mark) {
-            positionCluster(item, i, cEnd);
-            cEnd = -1;
-        }
-    }
-}
-
-// set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs
-// and no reordering.
-// also computes logClusters heuristically
-void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item)
-{
-    const HB_UChar16 *uc = item->string + item->item.pos;
-    hb_uint32 length = item->item.length;
-
-    // ### zeroWidth and justification are missing here!!!!!
-
-    assert(length <= item->num_glyphs);
-
-//     qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs);
-    HB_GlyphAttributes *attributes = item->attributes;
-    unsigned short *logClusters = item->log_clusters;
-
-    hb_uint32 glyph_pos = 0;
-    hb_uint32 i;
-    for (i = 0; i < length; i++) {
-        if (HB_IsHighSurrogate(uc[i]) && i < length - 1
-            && HB_IsLowSurrogate(uc[i + 1])) {
-            logClusters[i] = glyph_pos;
-            logClusters[++i] = glyph_pos;
-        } else {
-            logClusters[i] = glyph_pos;
-        }
-        ++glyph_pos;
-    }
-
-    // first char in a run is never (treated as) a mark
-    int cStart = 0;
-    const bool symbolFont = item->face->isSymbolFont;
-    attributes[0].mark = false;
-    attributes[0].clusterStart = true;
-    attributes[0].dontPrint = (!symbolFont && uc[0] == 0x00ad) || HB_IsControlChar(uc[0]);
-
-    int pos = 0;
-    HB_CharCategory lastCat;
-    int dummy;
-    HB_GetUnicodeCharProperties(uc[0], &lastCat, &dummy);
-    for (i = 1; i < length; ++i) {
-        if (logClusters[i] == pos)
-            // same glyph
-            continue;
-        ++pos;
-        while (pos < logClusters[i]) {
-            attributes[pos] = attributes[pos-1];
-            ++pos;
-        }
-        // hide soft-hyphens by default
-        if ((!symbolFont && uc[i] == 0x00ad) || HB_IsControlChar(uc[i]))
-            attributes[pos].dontPrint = true;
-        HB_CharCategory cat;
-        int cmb;
-        HB_GetUnicodeCharProperties(uc[i], &cat, &cmb);
-        if (cat != HB_Mark_NonSpacing) {
-            attributes[pos].mark = false;
-            attributes[pos].clusterStart = true;
-            attributes[pos].combiningClass = 0;
-            cStart = logClusters[i];
-        } else {
-            if (cmb == 0) {
-                // Fix 0 combining classes
-                if ((uc[pos] & 0xff00) == 0x0e00) {
-                    // thai or lao
-                    if (uc[pos] == 0xe31 ||
-                         uc[pos] == 0xe34 ||
-                         uc[pos] == 0xe35 ||
-                         uc[pos] == 0xe36 ||
-                         uc[pos] == 0xe37 ||
-                         uc[pos] == 0xe47 ||
-                         uc[pos] == 0xe4c ||
-                         uc[pos] == 0xe4d ||
-                         uc[pos] == 0xe4e) {
-                        cmb = HB_Combining_AboveRight;
-                    } else if (uc[pos] == 0xeb1 ||
-                                uc[pos] == 0xeb4 ||
-                                uc[pos] == 0xeb5 ||
-                                uc[pos] == 0xeb6 ||
-                                uc[pos] == 0xeb7 ||
-                                uc[pos] == 0xebb ||
-                                uc[pos] == 0xecc ||
-                                uc[pos] == 0xecd) {
-                        cmb = HB_Combining_Above;
-                    } else if (uc[pos] == 0xebc) {
-                        cmb = HB_Combining_Below;
-                    }
-                }
-            }
-
-            attributes[pos].mark = true;
-            attributes[pos].clusterStart = false;
-            attributes[pos].combiningClass = cmb;
-            logClusters[i] = cStart;
-        }
-        // one gets an inter character justification point if the current char is not a non spacing mark.
-        // as then the current char belongs to the last one and one gets a space justification point
-        // after the space char.
-        if (lastCat == HB_Separator_Space)
-            attributes[pos-1].justification = HB_Space;
-        else if (cat != HB_Mark_NonSpacing)
-            attributes[pos-1].justification = HB_Character;
-        else
-            attributes[pos-1].justification = HB_NoJustification;
-
-        lastCat = cat;
-    }
-    pos = logClusters[length-1];
-    if (lastCat == HB_Separator_Space)
-        attributes[pos].justification = HB_Space;
-    else
-        attributes[pos].justification = HB_Character;
-}
-
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature basic_features[] = {
-    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
-    { HB_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty },
-    { HB_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty },
-    {0, 0}
-};
-#endif
-
-HB_Bool HB_ConvertStringToGlyphIndices(HB_ShaperItem *shaper_item)
-{
-    if (shaper_item->glyphIndicesPresent) {
-        shaper_item->num_glyphs = shaper_item->initialGlyphCount;
-        shaper_item->glyphIndicesPresent = false;
-        return true;
-    }
-    return shaper_item->font->klass
-           ->convertStringToGlyphIndices(shaper_item->font,
-                                         shaper_item->string + shaper_item->item.pos, shaper_item->item.length,
-                                         shaper_item->glyphs, &shaper_item->num_glyphs,
-                                         shaper_item->item.bidiLevel % 2);
-}
-
-HB_Bool HB_BasicShape(HB_ShaperItem *shaper_item)
-{
-#ifndef NO_OPENTYPE
-    const int availableGlyphs = shaper_item->num_glyphs;
-#endif
-
-    if (!HB_ConvertStringToGlyphIndices(shaper_item))
-        return false;
-
-    HB_HeuristicSetGlyphAttributes(shaper_item);
-
-#ifndef NO_OPENTYPE
-    if (HB_SelectScript(shaper_item, basic_features)) {
-        HB_OpenTypeShape(shaper_item, /*properties*/0);
-        return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/true);
-    }
-#endif
-
-    HB_HeuristicPosition(shaper_item);
-    return true;
-}
-
-const HB_ScriptEngine HB_ScriptEngines[] = {
-    // Common
-    { HB_BasicShape, 0},
-    // Greek
-    { HB_BasicShape, 0},
-    // Cyrillic
-    { HB_BasicShape, 0},
-    // Armenian
-    { HB_BasicShape, 0},
-    // Hebrew
-    { HB_HebrewShape, 0 },
-    // Arabic
-    { HB_ArabicShape, 0},
-    // Syriac
-    { HB_ArabicShape, 0},
-    // Thaana
-    { HB_BasicShape, 0 },
-    // Devanagari
-    { HB_IndicShape, HB_IndicAttributes },
-    // Bengali
-    { HB_IndicShape, HB_IndicAttributes },
-    // Gurmukhi
-    { HB_IndicShape, HB_IndicAttributes },
-    // Gujarati
-    { HB_IndicShape, HB_IndicAttributes },
-    // Oriya
-    { HB_IndicShape, HB_IndicAttributes },
-    // Tamil
-    { HB_IndicShape, HB_IndicAttributes },
-    // Telugu
-    { HB_IndicShape, HB_IndicAttributes },
-    // Kannada
-    { HB_IndicShape, HB_IndicAttributes },
-    // Malayalam
-    { HB_IndicShape, HB_IndicAttributes },
-    // Sinhala
-    { HB_IndicShape, HB_IndicAttributes },
-    // Thai
-    { HB_BasicShape, HB_ThaiAttributes },
-    // Lao
-    { HB_BasicShape, 0 },
-    // Tibetan
-    { HB_TibetanShape, HB_TibetanAttributes },
-    // Myanmar
-    { HB_MyanmarShape, HB_MyanmarAttributes },
-    // Georgian
-    { HB_BasicShape, 0 },
-    // Hangul
-    { HB_HangulShape, 0 },
-    // Ogham
-    { HB_BasicShape, 0 },
-    // Runic
-    { HB_BasicShape, 0 },
-    // Khmer
-    { HB_KhmerShape, HB_KhmerAttributes },
-    // N'Ko
-    { HB_ArabicShape, 0}
-};
-
-void HB_GetCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength,
-                          const HB_ScriptItem *items, hb_uint32 numItems,
-                          HB_CharAttributes *attributes)
-{
-    calcLineBreaks(string, stringLength, attributes);
-
-    for (hb_uint32 i = 0; i < numItems; ++i) {
-        HB_Script script = items[i].script;
-        if (script == HB_Script_Inherited)
-            script = HB_Script_Common;
-        HB_AttributeFunction attributeFunction = HB_ScriptEngines[script].charAttributes;
-        if (!attributeFunction)
-            continue;
-        attributeFunction(script, string, items[i].pos, items[i].length, attributes);
-    }
-}
-
-
-enum BreakRule { NoBreak = 0, Break = 1, Middle = 2 };
-
-static const hb_uint8 wordbreakTable[HB_Word_ExtendNumLet + 1][HB_Word_ExtendNumLet + 1] = {
-//        Other    Format   Katakana ALetter  MidLetter MidNum  Numeric  ExtendNumLet
-    {   Break,   Break,   Break,   Break,   Break,   Break,   Break,   Break }, // Other
-    {   Break,   Break,   Break,   Break,   Break,   Break,   Break,   Break }, // Format 
-    {   Break,   Break, NoBreak,   Break,   Break,   Break,   Break, NoBreak }, // Katakana
-    {   Break,   Break,   Break, NoBreak,  Middle,   Break, NoBreak, NoBreak }, // ALetter
-    {   Break,   Break,   Break,   Break,   Break,   Break,   Break,   Break }, // MidLetter
-    {   Break,   Break,   Break,   Break,   Break,   Break,   Break,   Break }, // MidNum
-    {   Break,   Break,   Break, NoBreak,   Break,  Middle, NoBreak, NoBreak }, // Numeric
-    {   Break,   Break, NoBreak, NoBreak,   Break,   Break, NoBreak, NoBreak }, // ExtendNumLet
-};
-
-void HB_GetWordBoundaries(const HB_UChar16 *string, hb_uint32 stringLength,
-                          const HB_ScriptItem * /*items*/, hb_uint32 /*numItems*/,
-                          HB_CharAttributes *attributes)
-{
-    if (stringLength == 0)
-        return;
-    unsigned int brk = HB_GetWordClass(string[0]);
-    attributes[0].wordBoundary = true;
-    for (hb_uint32 i = 1; i < stringLength; ++i) {
-        if (!attributes[i].charStop) {
-            attributes[i].wordBoundary = false;
-            continue;
-        }
-        hb_uint32 nbrk = HB_GetWordClass(string[i]);
-        if (nbrk == HB_Word_Format) {
-            attributes[i].wordBoundary = (HB_GetSentenceClass(string[i-1]) == HB_Sentence_Sep);
-            continue;
-        }
-        BreakRule rule = (BreakRule)wordbreakTable[brk][nbrk];
-        if (rule == Middle) {
-            rule = Break;
-            hb_uint32 lookahead = i + 1;
-            while (lookahead < stringLength) {
-                hb_uint32 testbrk = HB_GetWordClass(string[lookahead]);
-                if (testbrk == HB_Word_Format && HB_GetSentenceClass(string[lookahead]) != HB_Sentence_Sep) {
-                    ++lookahead;
-                    continue;
-                }
-                if (testbrk == brk) {
-                    rule = NoBreak;
-                    while (i < lookahead)
-                        attributes[i++].wordBoundary = false;
-                    nbrk = testbrk;
-                }
-                break;
-            }
-        }
-        attributes[i].wordBoundary = (rule == Break);
-        brk = nbrk;
-    }
-}
-
-
-enum SentenceBreakStates {
-    SB_Initial,
-    SB_Upper,
-    SB_UpATerm, 
-    SB_ATerm,
-    SB_ATermC, 
-    SB_ACS, 
-    SB_STerm, 
-    SB_STermC, 
-    SB_SCS,
-    SB_BAfter, 
-    SB_Break,
-    SB_Look
-};
-
-static const hb_uint8 sentenceBreakTable[HB_Sentence_Close + 1][HB_Sentence_Close + 1] = {
-//        Other       Sep         Format      Sp          Lower       Upper       OLetter     Numeric     ATerm       STerm       Close
-      { SB_Initial, SB_BAfter , SB_Initial, SB_Initial, SB_Initial, SB_Upper  , SB_Initial, SB_Initial, SB_ATerm  , SB_STerm  , SB_Initial }, // SB_Initial,
-      { SB_Initial, SB_BAfter , SB_Upper  , SB_Initial, SB_Initial, SB_Upper  , SB_Initial, SB_Initial, SB_UpATerm, SB_STerm  , SB_Initial }, // SB_Upper
-      
-      { SB_Look   , SB_BAfter , SB_UpATerm, SB_ACS    , SB_Initial, SB_Upper  , SB_Break  , SB_Initial, SB_ATerm  , SB_STerm  , SB_ATermC  }, // SB_UpATerm
-      { SB_Look   , SB_BAfter , SB_ATerm  , SB_ACS    , SB_Initial, SB_Break  , SB_Break  , SB_Initial, SB_ATerm  , SB_STerm  , SB_ATermC  }, // SB_ATerm
-      { SB_Look   , SB_BAfter , SB_ATermC , SB_ACS    , SB_Initial, SB_Break  , SB_Break  , SB_Look   , SB_ATerm  , SB_STerm  , SB_ATermC  }, // SB_ATermC,
-      { SB_Look   , SB_BAfter , SB_ACS    , SB_ACS    , SB_Initial, SB_Break  , SB_Break  , SB_Look   , SB_ATerm  , SB_STerm  , SB_Look    }, // SB_ACS,
-      
-      { SB_Break  , SB_BAfter , SB_STerm  , SB_SCS    , SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_ATerm  , SB_STerm  , SB_STermC  }, // SB_STerm,
-      { SB_Break  , SB_BAfter , SB_STermC , SB_SCS    , SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_ATerm  , SB_STerm  , SB_STermC  }, // SB_STermC,
-      { SB_Break  , SB_BAfter , SB_SCS    , SB_SCS    , SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_ATerm  , SB_STerm  , SB_Break   }, // SB_SCS,
-      { SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_Break  , SB_Break   }, // SB_BAfter,
-};
-
-void HB_GetSentenceBoundaries(const HB_UChar16 *string, hb_uint32 stringLength,
-                              const HB_ScriptItem * /*items*/, hb_uint32 /*numItems*/,
-                              HB_CharAttributes *attributes)
-{
-    if (stringLength == 0)
-        return;
-    hb_uint32 brk = sentenceBreakTable[SB_Initial][HB_GetSentenceClass(string[0])];
-    attributes[0].sentenceBoundary = true;
-    for (hb_uint32 i = 1; i < stringLength; ++i) {
-        if (!attributes[i].charStop) {
-            attributes[i].sentenceBoundary = false;
-            continue;
-        }
-        brk = sentenceBreakTable[brk][HB_GetSentenceClass(string[i])];
-        if (brk == SB_Look) {
-            brk = SB_Break;
-            hb_uint32 lookahead = i + 1;
-            while (lookahead < stringLength) {
-                hb_uint32 sbrk = HB_GetSentenceClass(string[lookahead]);
-                if (sbrk != HB_Sentence_Other && sbrk != HB_Sentence_Numeric && sbrk != HB_Sentence_Close) {
-                    break;
-                } else if (sbrk == HB_Sentence_Lower) {
-                    brk = SB_Initial;
-                    break;
-                }
-                ++lookahead;
-            }
-            if (brk == SB_Initial) {
-                while (i < lookahead)
-                    attributes[i++].sentenceBoundary = false;
-            }
-        }
-        if (brk == SB_Break) {
-            attributes[i].sentenceBoundary = true;
-            brk = sentenceBreakTable[SB_Initial][HB_GetSentenceClass(string[i])];
-        } else {
-            attributes[i].sentenceBoundary = false;
-        }
-    }
-}
-
-
-static inline char *tag_to_string(HB_UInt tag)
-{
-    static char string[5];
-    string[0] = (tag >> 24)&0xff;
-    string[1] = (tag >> 16)&0xff;
-    string[2] = (tag >> 8)&0xff;
-    string[3] = tag&0xff;
-    string[4] = 0;
-    return string;
-}
-
-#ifdef OT_DEBUG
-static void dump_string(HB_Buffer buffer)
-{
-    for (uint i = 0; i < buffer->in_length; ++i) {
-        qDebug("    %x: cluster=%d", buffer->in_string[i].gindex, buffer->in_string[i].cluster);
-    }
-}
-#define DEBUG printf
-#else
-#define DEBUG if (1) ; else printf
-#endif
-
-#define DefaultLangSys 0xffff
-#define DefaultScript HB_MAKE_TAG('D', 'F', 'L', 'T')
-
-enum {
-    RequiresGsub = 1,
-    RequiresGpos = 2
-};
-
-struct OTScripts {
-    unsigned int tag;
-    int flags;
-};
-static const OTScripts ot_scripts [] = {
-    // Common
-    { HB_MAKE_TAG('l', 'a', 't', 'n'), 0 },
-    // Greek
-    { HB_MAKE_TAG('g', 'r', 'e', 'k'), 0 },
-    // Cyrillic
-    { HB_MAKE_TAG('c', 'y', 'r', 'l'), 0 },
-    // Armenian
-    { HB_MAKE_TAG('a', 'r', 'm', 'n'), 0 },
-    // Hebrew
-    { HB_MAKE_TAG('h', 'e', 'b', 'r'), 1 },
-    // Arabic
-    { HB_MAKE_TAG('a', 'r', 'a', 'b'), 1 },
-    // Syriac
-    { HB_MAKE_TAG('s', 'y', 'r', 'c'), 1 },
-    // Thaana
-    { HB_MAKE_TAG('t', 'h', 'a', 'a'), 1 },
-    // Devanagari
-    { HB_MAKE_TAG('d', 'e', 'v', 'a'), 1 },
-    // Bengali
-    { HB_MAKE_TAG('b', 'e', 'n', 'g'), 1 },
-    // Gurmukhi
-    { HB_MAKE_TAG('g', 'u', 'r', 'u'), 1 },
-    // Gujarati
-    { HB_MAKE_TAG('g', 'u', 'j', 'r'), 1 },
-    // Oriya
-    { HB_MAKE_TAG('o', 'r', 'y', 'a'), 1 },
-    // Tamil
-    { HB_MAKE_TAG('t', 'a', 'm', 'l'), 1 },
-    // Telugu
-    { HB_MAKE_TAG('t', 'e', 'l', 'u'), 1 },
-    // Kannada
-    { HB_MAKE_TAG('k', 'n', 'd', 'a'), 1 },
-    // Malayalam
-    { HB_MAKE_TAG('m', 'l', 'y', 'm'), 1 },
-    // Sinhala
-    { HB_MAKE_TAG('s', 'i', 'n', 'h'), 1 },
-    // Thai
-    { HB_MAKE_TAG('t', 'h', 'a', 'i'), 1 },
-    // Lao
-    { HB_MAKE_TAG('l', 'a', 'o', ' '), 1 },
-    // Tibetan
-    { HB_MAKE_TAG('t', 'i', 'b', 't'), 1 },
-    // Myanmar
-    { HB_MAKE_TAG('m', 'y', 'm', 'r'), 1 },
-    // Georgian
-    { HB_MAKE_TAG('g', 'e', 'o', 'r'), 0 },
-    // Hangul
-    { HB_MAKE_TAG('h', 'a', 'n', 'g'), 1 },
-    // Ogham
-    { HB_MAKE_TAG('o', 'g', 'a', 'm'), 0 },
-    // Runic
-    { HB_MAKE_TAG('r', 'u', 'n', 'r'), 0 },
-    // Khmer
-    { HB_MAKE_TAG('k', 'h', 'm', 'r'), 1 },
-    // N'Ko
-    { HB_MAKE_TAG('n', 'k', 'o', ' '), 1 }
-};
-enum { NumOTScripts = sizeof(ot_scripts)/sizeof(OTScripts) };
-
-static HB_Bool checkScript(HB_Face face, int script)
-{
-    assert(script < HB_ScriptCount);
-
-    if (!face->gsub && !face->gpos)
-        return false;
-
-    unsigned int tag = ot_scripts[script].tag;
-    int requirements = ot_scripts[script].flags;
-
-    if (requirements & RequiresGsub) {
-        if (!face->gsub)
-            return false;
-
-        HB_UShort script_index;
-        HB_Error error = HB_GSUB_Select_Script(face->gsub, tag, &script_index);
-        if (error) {
-            DEBUG("could not select script %d in GSub table: %d", (int)script, error);
-            error = HB_GSUB_Select_Script(face->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &script_index);
-            if (error)
-                return false;
-        }
-    }
-
-    if (requirements & RequiresGpos) {
-        if (!face->gpos)
-            return false;
-
-        HB_UShort script_index;
-        HB_Error error = HB_GPOS_Select_Script(face->gpos, script, &script_index);
-        if (error) {
-            DEBUG("could not select script in gpos table: %d", error);
-            error = HB_GPOS_Select_Script(face->gpos, HB_MAKE_TAG('D', 'F', 'L', 'T'), &script_index);
-            if (error)
-                return false;
-        }
-
-    }
-    return true;
-}
-
-static HB_Stream getTableStream(void *font, HB_GetFontTableFunc tableFunc, HB_Tag tag)
-{
-    HB_Error error;
-    HB_UInt length = 0;
-    HB_Stream stream = 0;
-
-    if (!font)
-        return 0;
-
-    error = tableFunc(font, tag, 0, &length);
-    if (error)
-        return 0;
-    stream = (HB_Stream)malloc(sizeof(HB_StreamRec));
-    if (!stream)
-        return 0;
-    stream->base = (HB_Byte*)malloc(length);
-    if (!stream->base) {
-        free(stream);
-        return 0;
-    }
-    error = tableFunc(font, tag, stream->base, &length);
-    if (error) {
-        _hb_close_stream(stream);
-        return 0;
-    }
-    stream->size = length;
-    stream->pos = 0;
-    stream->cursor = NULL;
-    return stream;
-}
-
-HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
-{
-    HB_Face face = (HB_Face )malloc(sizeof(HB_FaceRec));
-    if (!face)
-        return 0;
-
-    face->isSymbolFont = false;
-    face->gdef = 0;
-    face->gpos = 0;
-    face->gsub = 0;
-    face->current_script = HB_ScriptCount;
-    face->current_flags = HB_ShaperFlag_Default;
-    face->has_opentype_kerning = false;
-    face->tmpAttributes = 0;
-    face->tmpLogClusters = 0;
-    face->glyphs_substituted = false;
-    face->buffer = 0;
-
-    HB_Error error;
-    HB_Stream stream;
-    HB_Stream gdefStream;
-
-    gdefStream = getTableStream(font, tableFunc, TTAG_GDEF);
-    if (!gdefStream || (error = HB_Load_GDEF_Table(gdefStream, &face->gdef))) {
-        //DEBUG("error loading gdef table: %d", error);
-        face->gdef = 0;
-    }
-
-    //DEBUG() << "trying to load gsub table";
-    stream = getTableStream(font, tableFunc, TTAG_GSUB);
-    if (!stream || (error = HB_Load_GSUB_Table(stream, &face->gsub, face->gdef, gdefStream))) {
-        face->gsub = 0;
-        if (error != HB_Err_Not_Covered) {
-            //DEBUG("error loading gsub table: %d", error);
-        } else {
-            //DEBUG("face doesn't have a gsub table");
-        }
-    }
-    _hb_close_stream(stream);
-
-    stream = getTableStream(font, tableFunc, TTAG_GPOS);
-    if (!stream || (error = HB_Load_GPOS_Table(stream, &face->gpos, face->gdef, gdefStream))) {
-        face->gpos = 0;
-        DEBUG("error loading gpos table: %d", error);
-    }
-    _hb_close_stream(stream);
-
-    _hb_close_stream(gdefStream);
-
-    for (unsigned int i = 0; i < HB_ScriptCount; ++i)
-        face->supported_scripts[i] = checkScript(face, i);
-
-    if (hb_buffer_new(&face->buffer) != HB_Err_Ok) {
-        HB_FreeFace(face);
-        return 0;
-    }
-
-    return face;
-}
-
-void HB_FreeFace(HB_Face face)
-{
-    if (!face)
-        return;
-    if (face->gpos)
-        HB_Done_GPOS_Table(face->gpos);
-    if (face->gsub)
-        HB_Done_GSUB_Table(face->gsub);
-    if (face->gdef)
-        HB_Done_GDEF_Table(face->gdef);
-    if (face->buffer)
-        hb_buffer_free(face->buffer);
-    if (face->tmpAttributes)
-        free(face->tmpAttributes);
-    if (face->tmpLogClusters)
-        free(face->tmpLogClusters);
-    free(face);
-}
-
-HB_Bool HB_SelectScript(HB_ShaperItem *shaper_item, const HB_OpenTypeFeature *features)
-{
-    HB_Script script = shaper_item->item.script;
-
-    if (!shaper_item->face->supported_scripts[script])
-        return false;
-
-    HB_Face face = shaper_item->face;
-    if (face->current_script == script && face->current_flags == shaper_item->shaperFlags)
-        return true;
-
-    face->current_script = script;
-    face->current_flags = shaper_item->shaperFlags;
-
-    assert(script < HB_ScriptCount);
-    // find script in our list of supported scripts.
-    unsigned int tag = ot_scripts[script].tag;
-
-    if (face->gsub && features) {
-#ifdef OT_DEBUG
-        {
-            HB_FeatureList featurelist = face->gsub->FeatureList;
-            int numfeatures = featurelist.FeatureCount;
-            DEBUG("gsub table has %d features", numfeatures);
-            for (int i = 0; i < numfeatures; i++) {
-                HB_FeatureRecord *r = featurelist.FeatureRecord + i;
-                DEBUG("   feature '%s'", tag_to_string(r->FeatureTag));
-            }
-        }
-#endif
-        HB_GSUB_Clear_Features(face->gsub);
-        HB_UShort script_index;
-        HB_Error error = HB_GSUB_Select_Script(face->gsub, tag, &script_index);
-        if (!error) {
-            DEBUG("script %s has script index %d", tag_to_string(script), script_index);
-            while (features->tag) {
-                HB_UShort feature_index;
-                error = HB_GSUB_Select_Feature(face->gsub, features->tag, script_index, 0xffff, &feature_index);
-                if (!error) {
-                    DEBUG("  adding feature %s", tag_to_string(features->tag));
-                    HB_GSUB_Add_Feature(face->gsub, feature_index, features->property);
-                }
-                ++features;
-            }
-        }
-    }
-
-    // reset
-    face->has_opentype_kerning = false;
-
-    if (face->gpos) {
-        HB_GPOS_Clear_Features(face->gpos);
-        HB_UShort script_index;
-        HB_Error error = HB_GPOS_Select_Script(face->gpos, tag, &script_index);
-        if (!error) {
-#ifdef OT_DEBUG
-            {
-                HB_FeatureList featurelist = face->gpos->FeatureList;
-                int numfeatures = featurelist.FeatureCount;
-                DEBUG("gpos table has %d features", numfeatures);
-                for(int i = 0; i < numfeatures; i++) {
-                    HB_FeatureRecord *r = featurelist.FeatureRecord + i;
-                    HB_UShort feature_index;
-                    HB_GPOS_Select_Feature(face->gpos, r->FeatureTag, script_index, 0xffff, &feature_index);
-                    DEBUG("   feature '%s'", tag_to_string(r->FeatureTag));
-                }
-            }
-#endif
-            HB_UInt *feature_tag_list_buffer;
-            error = HB_GPOS_Query_Features(face->gpos, script_index, 0xffff, &feature_tag_list_buffer);
-            if (!error) {
-                HB_UInt *feature_tag_list = feature_tag_list_buffer;
-                while (*feature_tag_list) {
-                    HB_UShort feature_index;
-                    if (*feature_tag_list == HB_MAKE_TAG('k', 'e', 'r', 'n')) {
-                        if (face->current_flags & HB_ShaperFlag_NoKerning) {
-                            ++feature_tag_list;
-                            continue;
-                        }
-                        face->has_opentype_kerning = true;
-                    }
-                    error = HB_GPOS_Select_Feature(face->gpos, *feature_tag_list, script_index, 0xffff, &feature_index);
-                    if (!error)
-                        HB_GPOS_Add_Feature(face->gpos, feature_index, PositioningProperties);
-                    ++feature_tag_list;
-                }
-                FREE(feature_tag_list_buffer);
-            }
-        }
-    }
-
-    return true;
-}
-
-HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_uint32 *properties)
-{
-    HB_GlyphAttributes *tmpAttributes;
-    unsigned int *tmpLogClusters;
-
-    HB_Face face = item->face;
-
-    face->length = item->num_glyphs;
-
-    hb_buffer_clear(face->buffer);
-
-    tmpAttributes = (HB_GlyphAttributes *) realloc(face->tmpAttributes, face->length*sizeof(HB_GlyphAttributes));
-    if (!tmpAttributes)
-        return false;
-    face->tmpAttributes = tmpAttributes;
-
-    tmpLogClusters = (unsigned int *) realloc(face->tmpLogClusters, face->length*sizeof(unsigned int));
-    if (!tmpLogClusters)
-        return false;
-    face->tmpLogClusters = tmpLogClusters;
-
-    for (int i = 0; i < face->length; ++i) {
-        hb_buffer_add_glyph(face->buffer, item->glyphs[i], properties ? properties[i] : 0, i);
-        face->tmpAttributes[i] = item->attributes[i];
-        face->tmpLogClusters[i] = item->log_clusters[i];
-    }
-
-#ifdef OT_DEBUG
-    DEBUG("-----------------------------------------");
-//     DEBUG("log clusters before shaping:");
-//     for (int j = 0; j < length; j++)
-//         DEBUG("    log[%d] = %d", j, item->log_clusters[j]);
-    DEBUG("original glyphs: %p", item->glyphs);
-    for (int i = 0; i < length; ++i)
-        DEBUG("   glyph=%4x", hb_buffer->in_string[i].gindex);
-//     dump_string(hb_buffer);
-#endif
-
-    face->glyphs_substituted = false;
-    if (face->gsub) {
-        unsigned int error = HB_GSUB_Apply_String(face->gsub, face->buffer);
-        if (error && error != HB_Err_Not_Covered)
-            return false;
-        face->glyphs_substituted = (error != HB_Err_Not_Covered);
-    }
-
-#ifdef OT_DEBUG
-//     DEBUG("log clusters before shaping:");
-//     for (int j = 0; j < length; j++)
-//         DEBUG("    log[%d] = %d", j, item->log_clusters[j]);
-    DEBUG("shaped glyphs:");
-    for (int i = 0; i < length; ++i)
-        DEBUG("   glyph=%4x", hb_buffer->in_string[i].gindex);
-    DEBUG("-----------------------------------------");
-//     dump_string(hb_buffer);
-#endif
-
-    return true;
-}
-
-/* See comments near the definition of HB_ShaperFlag_ForceMarksToZeroWidth for a description
-   of why this function exists. */
-void HB_FixupZeroWidth(HB_ShaperItem *item)
-{
-    HB_UShort property;
-
-    if (!item->face->gdef)
-        return;
-
-    for (unsigned int i = 0; i < item->num_glyphs; ++i) {
-        /* If the glyph is a mark, force its advance to zero. */
-        if (HB_GDEF_Get_Glyph_Property (item->face->gdef, item->glyphs[i], &property) == HB_Err_Ok &&
-            property == HB_GDEF_MARK) {
-            item->advances[i] = 0;
-        }
-    }
-}
-
-HB_Bool HB_OpenTypePosition(HB_ShaperItem *item, int availableGlyphs, HB_Bool doLogClusters)
-{
-    HB_Face face = item->face;
-
-    bool glyphs_positioned = false;
-    if (face->gpos) {
-        if (face->buffer->positions)
-            memset(face->buffer->positions, 0, face->buffer->in_length*sizeof(HB_PositionRec));
-        // #### check that passing "false,false" is correct
-        glyphs_positioned = HB_GPOS_Apply_String(item->font, face->gpos, face->current_flags, face->buffer, false, false) != HB_Err_Not_Covered;
-    }
-
-    if (!face->glyphs_substituted && !glyphs_positioned) {
-        HB_GetGlyphAdvances(item);
-        if (item->face->current_flags & HB_ShaperFlag_ForceMarksToZeroWidth)
-            HB_FixupZeroWidth(item);
-        return true; // nothing to do for us
-    }
-
-    // make sure we have enough space to write everything back
-    if (availableGlyphs < (int)face->buffer->in_length) {
-        item->num_glyphs = face->buffer->in_length;
-        return false;
-    }
-
-    HB_Glyph *glyphs = item->glyphs;
-    HB_GlyphAttributes *attributes = item->attributes;
-
-    for (unsigned int i = 0; i < face->buffer->in_length; ++i) {
-        glyphs[i] = face->buffer->in_string[i].gindex;
-        attributes[i] = face->tmpAttributes[face->buffer->in_string[i].cluster];
-        if (i && face->buffer->in_string[i].cluster == face->buffer->in_string[i-1].cluster)
-            attributes[i].clusterStart = false;
-    }
-    item->num_glyphs = face->buffer->in_length;
-
-    if (doLogClusters && face->glyphs_substituted) {
-        // we can't do this for indic, as we pass the stuf in syllables and it's easier to do it in the shaper.
-        unsigned short *logClusters = item->log_clusters;
-        int clusterStart = 0;
-        int oldCi = 0;
-        // #### the reconstruction of the logclusters currently does not work if the original string
-        // contains surrogate pairs
-        for (unsigned int i = 0; i < face->buffer->in_length; ++i) {
-            int ci = face->buffer->in_string[i].cluster;
-            //         DEBUG("   ci[%d] = %d mark=%d, cmb=%d, cs=%d",
-            //                i, ci, glyphAttributes[i].mark, glyphAttributes[i].combiningClass, glyphAttributes[i].clusterStart);
-            if (!attributes[i].mark && attributes[i].clusterStart && ci != oldCi) {
-                for (int j = oldCi; j < ci; j++)
-                    logClusters[j] = clusterStart;
-                clusterStart = i;
-                oldCi = ci;
-            }
-        }
-        for (int j = oldCi; j < face->length; j++)
-            logClusters[j] = clusterStart;
-    }
-
-    // calulate the advances for the shaped glyphs
-//     DEBUG("unpositioned: ");
-
-    // positioning code:
-    if (glyphs_positioned) {
-        HB_GetGlyphAdvances(item);
-        HB_Position positions = face->buffer->positions;
-        HB_Fixed *advances = item->advances;
-
-//         DEBUG("positioned glyphs:");
-        for (unsigned int i = 0; i < face->buffer->in_length; i++) {
-//             DEBUG("    %d:\t orig advance: (%d/%d)\tadv=(%d/%d)\tpos=(%d/%d)\tback=%d\tnew_advance=%d", i,
-//                    glyphs[i].advance.x.toInt(), glyphs[i].advance.y.toInt(),
-//                    (int)(positions[i].x_advance >> 6), (int)(positions[i].y_advance >> 6),
-//                    (int)(positions[i].x_pos >> 6), (int)(positions[i].y_pos >> 6),
-//                    positions[i].back, positions[i].new_advance);
-
-            HB_Fixed adjustment = (item->item.bidiLevel % 2) ? -positions[i].x_advance : positions[i].x_advance;
-
-            if (!(face->current_flags & HB_ShaperFlag_UseDesignMetrics))
-                adjustment = HB_FIXED_ROUND(adjustment);
-
-            if (positions[i].new_advance) {
-                advances[i] = adjustment;
-            } else {
-                advances[i] += adjustment;
-            }
-
-            int back = 0;
-            HB_FixedPoint *offsets = item->offsets;
-            offsets[i].x = positions[i].x_pos;
-            offsets[i].y = positions[i].y_pos;
-            while (positions[i - back].back) {
-                back += positions[i - back].back;
-                offsets[i].x += positions[i - back].x_pos;
-                offsets[i].y += positions[i - back].y_pos;
-            }
-            offsets[i].y = -offsets[i].y;
-
-            if (item->item.bidiLevel % 2) {
-                // ### may need to go back multiple glyphs like in ltr
-                back = positions[i].back;
-                while (back--)
-                    offsets[i].x -= advances[i-back];
-            } else {
-                back = 0;
-                while (positions[i - back].back) {
-                    back += positions[i - back].back;
-                    offsets[i].x -= advances[i-back];
-                }
-            }
-//             DEBUG("   ->\tadv=%d\tpos=(%d/%d)",
-//                    glyphs[i].advance.x.toInt(), glyphs[i].offset.x.toInt(), glyphs[i].offset.y.toInt());
-        }
-        item->kerning_applied = face->has_opentype_kerning;
-    } else {
-        HB_HeuristicPosition(item);
-    }
-
-#ifdef OT_DEBUG
-    if (doLogClusters) {
-        DEBUG("log clusters after shaping:");
-        for (int j = 0; j < length; j++)
-            DEBUG("    log[%d] = %d", j, item->log_clusters[j]);
-    }
-    DEBUG("final glyphs:");
-    for (int i = 0; i < (int)hb_buffer->in_length; ++i)
-        DEBUG("   glyph=%4x char_index=%d mark: %d cmp: %d, clusterStart: %d advance=%d/%d offset=%d/%d",
-               glyphs[i].glyph, hb_buffer->in_string[i].cluster, glyphs[i].attributes.mark,
-               glyphs[i].attributes.combiningClass, glyphs[i].attributes.clusterStart,
-               glyphs[i].advance.x.toInt(), glyphs[i].advance.y.toInt(),
-               glyphs[i].offset.x.toInt(), glyphs[i].offset.y.toInt());
-    DEBUG("-----------------------------------------");
-#endif
-    return true;
-}
-
-HB_Bool HB_ShapeItem(HB_ShaperItem *shaper_item)
-{
-    HB_Bool result = false;
-    if (shaper_item->num_glyphs < shaper_item->item.length) {
-        shaper_item->num_glyphs = shaper_item->item.length;
-        return false;
-    }
-    assert(shaper_item->item.script < HB_ScriptCount);
-    result = HB_ScriptEngines[shaper_item->item.script].shape(shaper_item);
-    shaper_item->glyphIndicesPresent = false;
-    return result;
-}
-
diff --git a/third_party/harfbuzz/src/harfbuzz-shaper.h b/third_party/harfbuzz/src/harfbuzz-shaper.h
deleted file mode 100644
index 33fc85a..0000000
--- a/third_party/harfbuzz/src/harfbuzz-shaper.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_SHAPER_H
-#define HARFBUZZ_SHAPER_H
-
-#include "harfbuzz-global.h"
-#include "harfbuzz-gdef.h"
-#include "harfbuzz-gpos.h"
-#include "harfbuzz-gsub.h"
-#include "harfbuzz-external.h"
-#include "harfbuzz-stream-private.h"
-
-HB_BEGIN_HEADER
-
-typedef enum {
-        HB_Script_Common,
-        HB_Script_Greek,
-        HB_Script_Cyrillic,
-        HB_Script_Armenian,
-        HB_Script_Hebrew,
-        HB_Script_Arabic,
-        HB_Script_Syriac,
-        HB_Script_Thaana,
-        HB_Script_Devanagari,
-        HB_Script_Bengali,
-        HB_Script_Gurmukhi,
-        HB_Script_Gujarati,
-        HB_Script_Oriya,
-        HB_Script_Tamil,
-        HB_Script_Telugu,
-        HB_Script_Kannada,
-        HB_Script_Malayalam,
-        HB_Script_Sinhala,
-        HB_Script_Thai,
-        HB_Script_Lao,
-        HB_Script_Tibetan,
-        HB_Script_Myanmar,
-        HB_Script_Georgian,
-        HB_Script_Hangul,
-        HB_Script_Ogham,
-        HB_Script_Runic,
-        HB_Script_Khmer,
-        HB_Script_Nko,
-        HB_Script_Inherited,
-        HB_ScriptCount = HB_Script_Inherited
-        /*
-        HB_Script_Latin = Common,
-        HB_Script_Ethiopic = Common,
-        HB_Script_Cherokee = Common,
-        HB_Script_CanadianAboriginal = Common,
-        HB_Script_Mongolian = Common,
-        HB_Script_Hiragana = Common,
-        HB_Script_Katakana = Common,
-        HB_Script_Bopomofo = Common,
-        HB_Script_Han = Common,
-        HB_Script_Yi = Common,
-        HB_Script_OldItalic = Common,
-        HB_Script_Gothic = Common,
-        HB_Script_Deseret = Common,
-        HB_Script_Tagalog = Common,
-        HB_Script_Hanunoo = Common,
-        HB_Script_Buhid = Common,
-        HB_Script_Tagbanwa = Common,
-        HB_Script_Limbu = Common,
-        HB_Script_TaiLe = Common,
-        HB_Script_LinearB = Common,
-        HB_Script_Ugaritic = Common,
-        HB_Script_Shavian = Common,
-        HB_Script_Osmanya = Common,
-        HB_Script_Cypriot = Common,
-        HB_Script_Braille = Common,
-        HB_Script_Buginese = Common,
-        HB_Script_Coptic = Common,
-        HB_Script_NewTaiLue = Common,
-        HB_Script_Glagolitic = Common,
-        HB_Script_Tifinagh = Common,
-        HB_Script_SylotiNagri = Common,
-        HB_Script_OldPersian = Common,
-        HB_Script_Kharoshthi = Common,
-        HB_Script_Balinese = Common,
-        HB_Script_Cuneiform = Common,
-        HB_Script_Phoenician = Common,
-        HB_Script_PhagsPa = Common,
-        */
-} HB_Script;
-
-typedef struct
-{
-    hb_uint32 pos;
-    hb_uint32 length;
-    HB_Script script;
-    hb_uint8 bidiLevel;
-} HB_ScriptItem;
-
-typedef enum {
-    HB_NoBreak,
-    HB_SoftHyphen,
-    HB_Break,
-    HB_ForcedBreak
-} HB_LineBreakType;
-
-
-typedef struct {
-    /*HB_LineBreakType*/ unsigned lineBreakType  :2;
-    /*HB_Bool*/ unsigned whiteSpace              :1;     /* A unicode whitespace character, except NBSP, ZWNBSP */
-    /*HB_Bool*/ unsigned charStop                :1;     /* Valid cursor position (for left/right arrow) */
-    /*HB_Bool*/ unsigned wordBoundary            :1;
-    /*HB_Bool*/ unsigned sentenceBoundary        :1;
-    unsigned unused                  :2;
-} HB_CharAttributes;
-
-void HB_GetCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength,
-                          const HB_ScriptItem *items, hb_uint32 numItems,
-                          HB_CharAttributes *attributes);
-
-/* requires HB_GetCharAttributes to be called before */
-void HB_GetWordBoundaries(const HB_UChar16 *string, hb_uint32 stringLength,
-                          const HB_ScriptItem *items, hb_uint32 numItems,
-                          HB_CharAttributes *attributes);
-
-/* requires HB_GetCharAttributes to be called before */
-void HB_GetSentenceBoundaries(const HB_UChar16 *string, hb_uint32 stringLength,
-                              const HB_ScriptItem *items, hb_uint32 numItems,
-                              HB_CharAttributes *attributes);
-
-
-typedef enum {
-    HB_LeftToRight = 0,
-    HB_RightToLeft = 1
-} HB_StringToGlyphsFlags;
-
-typedef enum {
-    HB_ShaperFlag_Default = 0,
-    HB_ShaperFlag_NoKerning = 1,
-    HB_ShaperFlag_UseDesignMetrics = 1 << 1,
-    /* Arabic vowels in some fonts (Times New Roman, at least) have
-       non-zero advances, when they should be zero.  Setting this shaper
-       flag causes us to zero out the advances for mark glyphs. */
-    HB_ShaperFlag_ForceMarksToZeroWidth = 1 << 2
-} HB_ShaperFlag;
-
-/* 
-   highest value means highest priority for justification. Justification is done by first inserting kashidas
-   starting with the highest priority positions, then stretching spaces, afterwards extending inter char
-   spacing, and last spacing between arabic words.
-   NoJustification is for example set for arabic where no Kashida can be inserted or for diacritics.
-*/
-typedef enum {
-    HB_NoJustification= 0,   /* Justification can't be applied after this glyph */
-    HB_Arabic_Space   = 1,   /* This glyph represents a space inside arabic text */
-    HB_Character      = 2,   /* Inter-character justification point follows this glyph */
-    HB_Space          = 4,   /* This glyph represents a blank outside an Arabic run */
-    HB_Arabic_Normal  = 7,   /* Normal Middle-Of-Word glyph that connects to the right (begin) */
-    HB_Arabic_Waw     = 8,   /* Next character is final form of Waw/Ain/Qaf/Fa */
-    HB_Arabic_BaRa    = 9,   /* Next two chars are Ba + Ra/Ya/AlefMaksura */
-    HB_Arabic_Alef    = 10,  /* Next character is final form of Alef/Tah/Lam/Kaf/Gaf */
-    HB_Arabic_HaaDal  = 11,  /* Next character is final form of Haa/Dal/Taa Marbutah */
-    HB_Arabic_Seen    = 12,  /* Initial or Medial form Of Seen/Sad */
-    HB_Arabic_Kashida = 13   /* Kashida(U+640) in middle of word */
-} HB_JustificationClass;
-
-/* This structure is binary compatible with Uniscribe's SCRIPT_VISATTR. Would be nice to keep
- * it like that. If this is a problem please tell Trolltech :)
- */
-typedef struct {
-    unsigned justification   :4;  /* Justification class */
-    unsigned clusterStart    :1;  /* First glyph of representation of cluster */
-    unsigned mark            :1;  /* needs to be positioned around base char */
-    unsigned zeroWidth       :1;  /* ZWJ, ZWNJ etc, with no width */
-    unsigned dontPrint       :1;
-    unsigned combiningClass  :8;
-} HB_GlyphAttributes;
-
-typedef struct HB_FaceRec_ {
-    HB_Bool isSymbolFont;
-
-    HB_GDEF gdef;
-    HB_GSUB gsub;
-    HB_GPOS gpos;
-    HB_Bool supported_scripts[HB_ScriptCount];
-    HB_Buffer buffer;
-    HB_Script current_script;
-    int current_flags; /* HB_ShaperFlags */
-    HB_Bool has_opentype_kerning;
-    HB_Bool glyphs_substituted;
-    HB_GlyphAttributes *tmpAttributes;
-    unsigned int *tmpLogClusters;
-    int length;
-    int orig_nglyphs;
-} HB_FaceRec;
-
-typedef HB_Error (*HB_GetFontTableFunc)(void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length);
-
-HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc);
-void HB_FreeFace(HB_Face face);
-
-typedef struct {
-    HB_Fixed x, y;
-    HB_Fixed width, height;
-    HB_Fixed xOffset, yOffset;
-} HB_GlyphMetrics;
-
-typedef enum {
-    HB_FontAscent
-} HB_FontMetric;
-
-typedef struct {
-    HB_Bool  (*convertStringToGlyphIndices)(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft);
-    void     (*getGlyphAdvances)(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGlyphs, HB_Fixed *advances, int flags /*HB_ShaperFlag*/);
-    HB_Bool  (*canRender)(HB_Font font, const HB_UChar16 *string, hb_uint32 length);
-    /* implementation needs to make sure to load a scaled glyph, so /no/ FT_LOAD_NO_SCALE */
-    HB_Error (*getPointInOutline)(HB_Font font, HB_Glyph glyph, int flags /*HB_ShaperFlag*/, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
-    void     (*getGlyphMetrics)(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics);
-    HB_Fixed (*getFontMetric)(HB_Font font, HB_FontMetric metric);
-} HB_FontClass;
-
-typedef struct HB_Font_ {
-    const HB_FontClass *klass;
-
-    /* Metrics */
-    HB_UShort x_ppem, y_ppem;
-    HB_16Dot16 x_scale, y_scale;
-
-    void *userData;
-} HB_FontRec;
-
-typedef struct HB_ShaperItem_ HB_ShaperItem;
-
-struct HB_ShaperItem_ {
-    const HB_UChar16 *string;               /* input: the Unicode UTF16 text to be shaped */
-    hb_uint32 stringLength;                 /* input: the length of the input in 16-bit words */
-    HB_ScriptItem item;                     /* input: the current run to be shaped: a run of text all in the same script that is a substring of <string> */
-    HB_Font font;                           /* input: the font: scale, units and function pointers supplying glyph indices and metrics */
-    HB_Face face;                           /* input: the shaper state; current script, access to the OpenType tables , etc. */
-    int shaperFlags;                        /* input (unused) should be set to 0; intended to support flags defined in HB_ShaperFlag */
-    HB_Bool glyphIndicesPresent;            /* input: true if the <glyphs> array contains glyph indices ready to be shaped */
-    hb_uint32 initialGlyphCount;            /* input: if glyphIndicesPresent is true, the number of glyph indices in the <glyphs> array */
-
-    hb_uint32 num_glyphs;                   /* input: capacity of output arrays <glyphs>, <attributes>, <advances>, <offsets>, and <log_clusters>; */
-                                            /* output: required capacity (may be larger than actual capacity) */
-
-    HB_Glyph *glyphs;                       /* output: <num_glyphs> indices of shaped glyphs */
-    HB_GlyphAttributes *attributes;         /* output: <num_glyphs> glyph attributes */
-    HB_Fixed *advances;                     /* output: <num_glyphs> advances */
-    HB_FixedPoint *offsets;                 /* output: <num_glyphs> offsets */
-    unsigned short *log_clusters;           /* output: for each output glyph, the index in the input of the start of its logical cluster */
-
-    /* internal */
-    HB_Bool kerning_applied;                /* output: true if kerning was applied by the shaper */
-};
-
-HB_Bool HB_ShapeItem(HB_ShaperItem *item);
-
-HB_END_HEADER
-
-#endif
diff --git a/third_party/harfbuzz/src/harfbuzz-stream-private.h b/third_party/harfbuzz/src/harfbuzz-stream-private.h
deleted file mode 100644
index fbd9f81..0000000
--- a/third_party/harfbuzz/src/harfbuzz-stream-private.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_STREAM_PRIVATE_H
-#define HARFBUZZ_STREAM_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-stream.h"
-
-HB_BEGIN_HEADER
-
-HB_INTERNAL void
-_hb_close_stream( HB_Stream stream );
-
-HB_INTERNAL HB_Int
-_hb_stream_pos( HB_Stream stream );
-
-HB_INTERNAL HB_Error
-_hb_stream_seek( HB_Stream stream,
-                 HB_UInt   pos );
-
-HB_INTERNAL HB_Error
-_hb_stream_frame_enter( HB_Stream stream,
-                        HB_UInt   size );
-
-HB_INTERNAL void
-_hb_stream_frame_exit( HB_Stream stream );
-
-/* convenience macros */
-
-#define  SET_ERR(c)   ( (error = (c)) != 0 )
-
-#define  GOTO_Table(tag) (0)
-#define  FILE_Pos()      _hb_stream_pos( stream )
-#define  FILE_Seek(pos)  SET_ERR( _hb_stream_seek( stream, pos ) )
-#define  ACCESS_Frame(size)  SET_ERR( _hb_stream_frame_enter( stream, size ) )
-#define  FORGET_Frame()      _hb_stream_frame_exit( stream )
-
-#define  GET_Byte()      (*stream->cursor++)
-#define  GET_Short()     (stream->cursor += 2, (HB_Short)( \
-				(*(((HB_Byte*)stream->cursor)-2) << 8) | \
-				 *(((HB_Byte*)stream->cursor)-1) \
-			 ))
-#define  GET_Long()      (stream->cursor += 4, (HB_Int)( \
-				(*(((HB_Byte*)stream->cursor)-4) << 24) | \
-				(*(((HB_Byte*)stream->cursor)-3) << 16) | \
-				(*(((HB_Byte*)stream->cursor)-2) << 8) | \
-				 *(((HB_Byte*)stream->cursor)-1) \
-			 ))
-
-
-#define  GET_Char()      ((HB_Char)GET_Byte())
-#define  GET_UShort()    ((HB_UShort)GET_Short())
-#define  GET_ULong()     ((HB_UInt)GET_Long())
-#define  GET_Tag4()      GET_ULong()
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_STREAM_PRIVATE_H */
diff --git a/third_party/harfbuzz/src/harfbuzz-stream.c b/third_party/harfbuzz/src/harfbuzz-stream.c
deleted file mode 100644
index 2d9638f..0000000
--- a/third_party/harfbuzz/src/harfbuzz-stream.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2005  David Turner
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2007  Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-stream-private.h"
-#include <stdlib.h>
-
-#if 0
-#include <stdio.h>
-#define  LOG(x)  _hb_log x
-
-static void
-_hb_log( const char*   format, ... )
-{
-  va_list  ap;
- 
-  va_start( ap, format );
-  vfprintf( stderr, format, ap );
-  va_end( ap );
-}
-
-#else
-#define  LOG(x)  do {} while (0)
-#endif
-
-HB_INTERNAL void
-_hb_close_stream( HB_Stream stream )
-{
-  if (!stream)
-      return;
-  free(stream->base);
-  free(stream);
-}
-
-
-HB_INTERNAL HB_Int
-_hb_stream_pos( HB_Stream stream )
-{
-  LOG(( "_hb_stream_pos() -> %ld\n", stream->pos ));
-  return stream->pos;
-}
-
-
-HB_INTERNAL HB_Error
-_hb_stream_seek( HB_Stream stream,
-		 HB_UInt pos )
-{
-  HB_Error  error = (HB_Error)0;
-
-  stream->pos = pos;
-  if (pos > stream->size)
-      error = ERR(HB_Err_Read_Error);
-
-  LOG(( "_hb_stream_seek(%ld) -> 0x%04X\n", pos, error ));
-  return error;
-}
-
-
-HB_INTERNAL HB_Error
-_hb_stream_frame_enter( HB_Stream stream,
-			HB_UInt count )
-{
-  HB_Error  error = HB_Err_Ok;
-
-  /* check new position, watch for overflow */
-  if (HB_UNLIKELY (stream->pos + count > stream->size ||
-		   stream->pos + count < stream->pos))
-  {
-    error = ERR(HB_Err_Read_Error);
-    goto Exit;
-  }
-
-  /* set cursor */
-  stream->cursor = stream->base + stream->pos;
-  stream->pos   += count;
-
-Exit:
-  LOG(( "_hb_stream_frame_enter(%ld) -> 0x%04X\n", count, error ));
-  return error;
-}
-
-
-HB_INTERNAL void
-_hb_stream_frame_exit( HB_Stream stream )
-{
-  stream->cursor = NULL;
-
-  LOG(( "_hb_stream_frame_exit()\n" ));
-}
diff --git a/third_party/harfbuzz/src/harfbuzz-stream.h b/third_party/harfbuzz/src/harfbuzz-stream.h
deleted file mode 100644
index 9991936..0000000
--- a/third_party/harfbuzz/src/harfbuzz-stream.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2005  David Turner
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_STREAM_H
-#define HARFBUZZ_STREAM_H
-
-#include "harfbuzz-global.h"
-
-HB_BEGIN_HEADER
-
-typedef struct HB_StreamRec_
-{
-    HB_Byte*       base;
-    HB_UInt        size;
-    HB_UInt        pos;
-    
-    HB_Byte*       cursor;
-} HB_StreamRec;
-
-
-HB_END_HEADER
-
-#endif
diff --git a/third_party/harfbuzz/src/harfbuzz-thai.c b/third_party/harfbuzz/src/harfbuzz-thai.c
deleted file mode 100644
index 1d1aa2f..0000000
--- a/third_party/harfbuzz/src/harfbuzz-thai.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-#include "harfbuzz-external.h"
-
-#include <assert.h>
-
-static void thaiWordBreaks(const HB_UChar16 *string, hb_uint32 len, HB_CharAttributes *attributes)
-{
-    typedef int (*th_brk_def)(const char*, int[], int);
-    static void *thaiCodec = 0;
-    static th_brk_def th_brk = 0;
-    char *cstr = 0;
-    int brp[128];
-    int *break_positions = brp;
-    hb_uint32 numbreaks;
-    hb_uint32 i;
-
-    if (!thaiCodec)
-        thaiCodec = HB_TextCodecForMib(2259);
-
-    /* load libthai dynamically */
-    if (!th_brk && thaiCodec) {
-        th_brk = (th_brk_def)HB_Library_Resolve("thai", "th_brk");
-        if (!th_brk)
-            thaiCodec = 0;
-    }
-
-    if (!th_brk)
-        return;
-
-    cstr = HB_TextCodec_ConvertFromUnicode(thaiCodec, string, len, 0);
-    if (!cstr)
-        return;
-
-    break_positions = brp;
-    numbreaks = th_brk(cstr, break_positions, 128);
-    if (numbreaks > 128) {
-        break_positions = (int *)malloc(numbreaks * sizeof(int));
-        numbreaks = th_brk(cstr, break_positions, numbreaks);
-    }
-
-    for (i = 0; i < len; ++i)
-        attributes[i].lineBreakType = HB_NoBreak;
-
-    for (i = 0; i < numbreaks; ++i) {
-        if (break_positions[i] > 0)
-            attributes[break_positions[i]-1].lineBreakType = HB_Break;
-    }
-
-    if (break_positions != brp)
-        free(break_positions);
-
-    HB_TextCodec_FreeResult(cstr);
-}
-
-
-void HB_ThaiAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
-{
-    assert(script == HB_Script_Thai);
-    attributes += from;
-    thaiWordBreaks(text + from, len, attributes);
-}
-
diff --git a/third_party/harfbuzz/src/harfbuzz-tibetan.c b/third_party/harfbuzz/src/harfbuzz-tibetan.c
deleted file mode 100644
index bfa31b1..0000000
--- a/third_party/harfbuzz/src/harfbuzz-tibetan.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-
-/*
- tibetan syllables are of the form:
-    head position consonant
-    first sub-joined consonant
-    ....intermediate sub-joined consonants (if any)
-    last sub-joined consonant
-    sub-joined vowel (a-chung U+0F71)
-    standard or compound vowel sign (or 'virama' for devanagari transliteration)
-*/
-
-typedef enum {
-    TibetanOther,
-    TibetanHeadConsonant,
-    TibetanSubjoinedConsonant,
-    TibetanSubjoinedVowel,
-    TibetanVowel
-} TibetanForm;
-
-/* this table starts at U+0f40 */
-static const unsigned char tibetanForm[0x80] = {
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-    TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
-    TibetanOther, TibetanOther, TibetanOther, TibetanOther,
-
-    TibetanOther, TibetanVowel, TibetanVowel, TibetanVowel,
-    TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
-    TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
-    TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
-
-    TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
-    TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
-    TibetanOther, TibetanOther, TibetanOther, TibetanOther,
-    TibetanOther, TibetanOther, TibetanOther, TibetanOther,
-
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
-    TibetanSubjoinedConsonant, TibetanOther, TibetanOther, TibetanOther
-};
-
-
-#define tibetan_form(c) \
-    (TibetanForm)tibetanForm[c - 0x0f40]
-
-static const HB_OpenTypeFeature tibetan_features[] = {
-    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
-    { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
-    { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
-    { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty },
-    {0, 0}
-};
-
-static HB_Bool tibetan_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid)
-{
-    hb_uint32 i;
-    const HB_UChar16 *str = item->string + item->item.pos;
-    int len = item->item.length;
-#ifndef NO_OPENTYPE
-    const int availableGlyphs = item->num_glyphs;
-#endif
-    HB_Bool haveGlyphs;
-    HB_STACKARRAY(HB_UChar16, reordered, len + 4);
-
-    if (item->num_glyphs < item->item.length + 4) {
-        item->num_glyphs = item->item.length + 4;
-        return FALSE;
-    }
-
-    if (invalid) {
-        *reordered = 0x25cc;
-        memcpy(reordered+1, str, len*sizeof(HB_UChar16));
-        len++;
-        str = reordered;
-    }
-
-    haveGlyphs = item->font->klass->convertStringToGlyphIndices(item->font,
-                                                                str, len,
-                                                                item->glyphs, &item->num_glyphs,
-                                                                item->item.bidiLevel % 2);
-
-    HB_FREE_STACKARRAY(reordered);
-
-    if (!haveGlyphs)
-        return FALSE;
-
-    for (i = 0; i < item->item.length; i++) {
-        item->attributes[i].mark = FALSE;
-        item->attributes[i].clusterStart = FALSE;
-        item->attributes[i].justification = 0;
-        item->attributes[i].zeroWidth = FALSE;
-/*        IDEBUG("    %d: %4x", i, str[i]); */
-    }
-
-    /* now we have the syllable in the right order, and can start running it through open type. */
-
-#ifndef NO_OPENTYPE
-    if (openType) {
-        HB_OpenTypeShape(item, /*properties*/0);
-        if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE))
-            return FALSE;
-    } else {
-        HB_HeuristicPosition(item);
-    }
-#endif
-
-    item->attributes[0].clusterStart = TRUE;
-    return TRUE;
-}
-
-
-static int tibetan_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid)
-{
-    const HB_UChar16 *uc = s + start;
-
-    int pos = 0;
-    TibetanForm state = tibetan_form(*uc);
-
-/*     qDebug("state[%d]=%d (uc=%4x)", pos, state, uc[pos]);*/
-    pos++;
-
-    if (state != TibetanHeadConsonant) {
-        if (state != TibetanOther)
-            *invalid = TRUE;
-        goto finish;
-    }
-
-    while (pos < end - start) {
-        TibetanForm newState = tibetan_form(uc[pos]);
-        switch(newState) {
-        case TibetanSubjoinedConsonant:
-        case TibetanSubjoinedVowel:
-            if (state != TibetanHeadConsonant &&
-                 state != TibetanSubjoinedConsonant)
-                goto finish;
-            state = newState;
-            break;
-        case TibetanVowel:
-            if (state != TibetanHeadConsonant &&
-                 state != TibetanSubjoinedConsonant &&
-                 state != TibetanSubjoinedVowel)
-                goto finish;
-            break;
-        case TibetanOther:
-        case TibetanHeadConsonant:
-            goto finish;
-        }
-        pos++;
-    }
-
-finish:
-    *invalid = FALSE;
-    return start+pos;
-}
-
-HB_Bool HB_TibetanShape(HB_ShaperItem *item)
-{
-
-    HB_Bool openType = FALSE;
-    unsigned short *logClusters = item->log_clusters;
-
-    HB_ShaperItem syllable = *item;
-    int first_glyph = 0;
-
-    int sstart = item->item.pos;
-    int end = sstart + item->item.length;
-
-    assert(item->item.script == HB_Script_Tibetan);
-
-#ifndef QT_NO_OPENTYPE
-    openType = HB_SelectScript(item, tibetan_features);
-#endif
-
-    while (sstart < end) {
-        HB_Bool invalid;
-        int i;
-        int send = tibetan_nextSyllableBoundary(item->string, sstart, end, &invalid);
-/*        IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
-                 invalid ? "TRUE" : "FALSE"); */
-        syllable.item.pos = sstart;
-        syllable.item.length = send-sstart;
-        syllable.glyphs = item->glyphs + first_glyph;
-        syllable.attributes = item->attributes + first_glyph;
-        syllable.offsets = item->offsets + first_glyph;
-        syllable.advances = item->advances + first_glyph;
-        syllable.num_glyphs = item->num_glyphs - first_glyph;
-        if (!tibetan_shape_syllable(openType, &syllable, invalid)) {
-            item->num_glyphs += syllable.num_glyphs;
-            return FALSE;
-        }
-        /* fix logcluster array */
-        for (i = sstart; i < send; ++i)
-            logClusters[i-item->item.pos] = first_glyph;
-        sstart = send;
-        first_glyph += syllable.num_glyphs;
-    }
-    item->num_glyphs = first_glyph;
-    return TRUE;
-}
-
-void HB_TibetanAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
-{
-    int end = from + len;
-    const HB_UChar16 *uc = text + from;
-    hb_uint32 i = 0;
-    HB_UNUSED(script);
-    attributes += from;
-    while (i < len) {
-        HB_Bool invalid;
-        hb_uint32 boundary = tibetan_nextSyllableBoundary(text, from+i, end, &invalid) - from;
-
-        attributes[i].charStop = TRUE;
-
-        if (boundary > len-1) boundary = len;
-        i++;
-        while (i < boundary) {
-            attributes[i].charStop = FALSE;
-            ++uc;
-            ++i;
-        }
-        assert(i == boundary);
-    }
-}
-
-
diff --git a/third_party/harfbuzz/src/harfbuzz.c b/third_party/harfbuzz/src/harfbuzz.c
deleted file mode 100644
index 3e4a30a..0000000
--- a/third_party/harfbuzz/src/harfbuzz.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#define HB_INTERNAL static
-#include "harfbuzz-buffer.c"
-#include "harfbuzz-gdef.c"
-#include "harfbuzz-gsub.c"
-#include "harfbuzz-gpos.c"
-#include "harfbuzz-impl.c"
-#include "harfbuzz-open.c"
-#include "harfbuzz-stream.c"
diff --git a/third_party/harfbuzz/src/harfbuzz.h b/third_party/harfbuzz/src/harfbuzz.h
deleted file mode 100644
index e91a33e..0000000
--- a/third_party/harfbuzz/src/harfbuzz.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 1998-2004  David Turner and Werner Lemberg
- * Copyright (C) 2006  Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HARFBUZZ_H
-#define HARFBUZZ_H
-
-#include "harfbuzz-external.h"
-#include "harfbuzz-global.h"
-#include "harfbuzz-buffer.h"
-#include "harfbuzz-gdef.h"
-#include "harfbuzz-gsub.h"
-#include "harfbuzz-gpos.h"
-#include "harfbuzz-open.h"
-#include "harfbuzz-shaper.h"
-
-#endif /* HARFBUZZ_OPEN_H */
diff --git a/third_party/harfbuzz/tests/Makefile.am b/third_party/harfbuzz/tests/Makefile.am
deleted file mode 100644
index febf890..0000000
--- a/third_party/harfbuzz/tests/Makefile.am
+++ /dev/null
@@ -1,7 +0,0 @@
-
-SUBDIRS =
-
-if QT
-SUBDIRS += linebreaking shaping
-endif
-
diff --git a/third_party/harfbuzz/tests/linebreaking/.gitignore b/third_party/harfbuzz/tests/linebreaking/.gitignore
deleted file mode 100644
index 81e019d..0000000
--- a/third_party/harfbuzz/tests/linebreaking/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.deps
-linebreaking
-*.moc
-*.o
diff --git a/third_party/harfbuzz/tests/linebreaking/Makefile.am b/third_party/harfbuzz/tests/linebreaking/Makefile.am
deleted file mode 100644
index b710896..0000000
--- a/third_party/harfbuzz/tests/linebreaking/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-
-check_PROGRAMS = linebreaking
-
-linebreaking_SOURCES = main.cpp harfbuzz-qt.cpp
-linebreaking_LDADD = $(QT_GUI_LIBS) $(QT_QTEST_LIBS) ../../src/libharfbuzz-1.la
-
-main.o: main.moc
-
-main.moc: $(srcdir)/main.cpp
-	$(QT_MOC) -o main.moc $(srcdir)/main.cpp
-
-INCLUDES = -I$(top_srcdir)/src $(FREETYPE_CFLAGS) $(QT_GUI_CFLAGS) $(QT_QTEST_CFLAGS)
diff --git a/third_party/harfbuzz/tests/linebreaking/harfbuzz-qt.cpp b/third_party/harfbuzz/tests/linebreaking/harfbuzz-qt.cpp
deleted file mode 100644
index ea03052..0000000
--- a/third_party/harfbuzz/tests/linebreaking/harfbuzz-qt.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include <harfbuzz-external.h>
-#include <Qt/private/qunicodetables_p.h>
-#include <QLibrary>
-#include <QTextCodec>
-
-extern "C" {
-
-HB_LineBreakClass HB_GetLineBreakClass(HB_UChar32 ch)
-{
-#if QT_VERSION >= 0x040300
-    return (HB_LineBreakClass)QUnicodeTables::lineBreakClass(ch);
-#else
-#error "This test currently requires Qt >= 4.3"
-#endif
-}
-
-void HB_GetUnicodeCharProperties(HB_UChar32 ch, HB_CharCategory *category, int *combiningClass)
-{
-    *category = (HB_CharCategory)QChar::category(ch);
-    *combiningClass = QChar::combiningClass(ch);
-}
-
-HB_CharCategory HB_GetUnicodeCharCategory(HB_UChar32 ch)
-{
-    return (HB_CharCategory)QChar::category(ch);
-}
-
-int HB_GetUnicodeCharCombiningClass(HB_UChar32 ch)
-{
-    return QChar::combiningClass(ch);
-}
-
-HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch)
-{
-    return QChar::mirroredChar(ch);
-}
-
-HB_WordClass HB_GetWordClass(HB_UChar32 ch)
-{
-    const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
-    return (HB_WordClass) prop->wordBreak;
-}
-
-
-HB_SentenceClass HB_GetSentenceClass(HB_UChar32 ch)
-{
-    const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
-    return (HB_SentenceClass) prop->sentenceBreak;
-}
-
-void HB_GetGraphemeAndLineBreakClass(HB_UChar32 ch, HB_GraphemeClass *grapheme, HB_LineBreakClass *lineBreak)
-{
-    const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
-    *grapheme = (HB_GraphemeClass) prop->graphemeBreak;
-    *lineBreak = (HB_LineBreakClass) prop->line_break_class;
-}
-
-void *HB_Library_Resolve(const char *library, const char *symbol)
-{
-    return QLibrary::resolve(library, symbol);
-}
-
-void *HB_TextCodecForMib(int mib)
-{
-    return QTextCodec::codecForMib(mib);
-}
-
-char *HB_TextCodec_ConvertFromUnicode(void *codec, const HB_UChar16 *unicode, hb_uint32 length, hb_uint32 *outputLength)
-{
-    QByteArray data = reinterpret_cast<QTextCodec *>(codec)->fromUnicode((const QChar *)unicode, length);
-    // ### suboptimal
-    char *output = (char *)malloc(data.length() + 1);
-    memcpy(output, data.constData(), data.length() + 1);
-    if (outputLength)
-        *outputLength = data.length();
-    return output;
-}
-
-void HB_TextCodec_FreeResult(char *string)
-{
-    free(string);
-}
-
-}
diff --git a/third_party/harfbuzz/tests/linebreaking/main.cpp b/third_party/harfbuzz/tests/linebreaking/main.cpp
deleted file mode 100644
index 3b2734a..0000000
--- a/third_party/harfbuzz/tests/linebreaking/main.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-/*
-    !!!!!! Warning !!!!!
-    Please don't save this file in emacs. It contains utf8 text sequences emacs will
-    silently convert to a series of question marks.
- */
-#include <QtTest/QtTest>
-#include <QtCore/qdebug.h>
-
-#include <harfbuzz-shaper.h>
-
-static QVector<HB_CharAttributes> getCharAttributes(const QString &str, HB_Script script = HB_Script_Common)
-{
-    QVector<HB_CharAttributes> attrs(str.length());
-    HB_ScriptItem item;
-    item.pos = 0;
-    item.length = str.length();
-    item.script = script;
-    HB_GetCharAttributes(str.utf16(), str.length(),
-                         &item, 1,
-                         attrs.data());
-    return attrs;
-}
-
-class tst_CharAttributes : public QObject
-{
-    Q_OBJECT
-
-public:
-    tst_CharAttributes();
-    virtual ~tst_CharAttributes();
-
-public slots:
-    void init();
-    void cleanup();
-private slots:
-    void lineBreaking();
-    void charWordStopOnLineSeparator();
-    void charStopForSurrogatePairs();
-    void thaiWordBreak();
-};
-
-
-tst_CharAttributes::tst_CharAttributes()
-{
-}
-
-tst_CharAttributes::~tst_CharAttributes()
-{
-}
-
-void tst_CharAttributes::init()
-{
-}
-
-void tst_CharAttributes::cleanup()
-{
-}
-
-
-void tst_CharAttributes::lineBreaking()
-{
-    struct Breaks {
-	const char *utf8;
-	uchar breaks[32];
-    };
-    Breaks brks[] = {
-	{ "11", { false, 0xff } },
-	{ "aa", { false, 0xff } },
-	{ "++", { false, 0xff } },
-	{ "--", { false, 0xff } },
-	{ "((", { false, 0xff } },
-	{ "))", { false, 0xff } },
-	{ "..", { false, 0xff } },
-	{ "\"\"", { false, 0xff } },
-	{ "$$", { false, 0xff } },
-	{ "!!", { false, 0xff } },
-	{ "??", { false, 0xff } },
-	{ ",,", { false, 0xff } },
-
-	{ ")()", { true, false, 0xff } },
-	{ "?!?", { false, false, 0xff } },
-	{ ".,.", { false, false, 0xff } },
-	{ "+-+", { false, false, 0xff } },
-	{ "+=+", { false, false, 0xff } },
-	{ "+(+", { false, false, 0xff } },
-	{ "+)+", { false, false, 0xff } },
-
-	{ "a b", { false, true, 0xff } },
-	{ "a(b", { false, false, 0xff } },
-	{ "a)b", { false, false, 0xff } },
-	{ "a-b", { false, true, 0xff } },
-	{ "a.b", { false, false, 0xff } },
-	{ "a+b", { false, false, 0xff } },
-	{ "a?b", { false, false, 0xff } },
-	{ "a!b", { false, false, 0xff } },
-	{ "a$b", { false, false, 0xff } },
-	{ "a,b", { false, false, 0xff } },
-	{ "a/b", { false, false, 0xff } },
-	{ "1/2", { false, false, 0xff } },
-	{ "./.", { false, false, 0xff } },
-	{ ",/,", { false, false, 0xff } },
-	{ "!/!", { false, false, 0xff } },
-	{ "\\/\\", { false, false, 0xff } },
-	{ "1 2", { false, true, 0xff } },
-	{ "1(2", { false, false, 0xff } },
-	{ "1)2", { false, false, 0xff } },
-	{ "1-2", { false, false, 0xff } },
-	{ "1.2", { false, false, 0xff } },
-	{ "1+2", { false, false, 0xff } },
-	{ "1?2", { false, true, 0xff } },
-	{ "1!2", { false, true, 0xff } },
-	{ "1$2", { false, false, 0xff } },
-	{ "1,2", { false, false, 0xff } },
-	{ "1/2", { false, false, 0xff } },
-	{ "\330\260\331\216\331\204\331\220\331\203\331\216", { false, false, false, false, false, 0xff } },
-	{ "\330\247\331\204\331\205 \330\247\331\204\331\205", { false, false, false, true, false, false, 0xff } },
-	{ "1#2", { false, false, 0xff } },
-	{ "!#!", { false, false, 0xff } },
-	{ 0, {} }
-    };
-    Breaks *b = brks;
-    while (b->utf8) {
-        QString str = QString::fromUtf8(b->utf8);
-
-        QVector<HB_CharAttributes> attrs = getCharAttributes(str);
-
-        int i;
-        for (i = 0; i < (int)str.length() - 1; ++i) {
-            QVERIFY(b->breaks[i] != 0xff);
-            if ( (attrs[i].lineBreakType != HB_NoBreak) != (bool)b->breaks[i] ) {
-                qDebug("test case \"%s\" failed at char %d; break type: %d", b->utf8, i, attrs[i].lineBreakType);
-                QCOMPARE( (attrs[i].lineBreakType != HB_NoBreak), (bool)b->breaks[i] );
-            }
-        }
-        QVERIFY(attrs[i].lineBreakType == HB_ForcedBreak);
-        QCOMPARE(b->breaks[i], (uchar)0xff);
-        ++b;
-    }
-}
-
-void tst_CharAttributes::charWordStopOnLineSeparator()
-{
-    const QChar lineSeparator(QChar::LineSeparator);
-    QString txt;
-    txt.append(lineSeparator);
-    txt.append(lineSeparator);
-    QVector<HB_CharAttributes> attrs = getCharAttributes(txt);
-    QVERIFY(attrs[1].charStop);
-}
-
-void tst_CharAttributes::charStopForSurrogatePairs()
-{
-    QString txt;
-    txt.append("a");
-    txt.append(0xd87e);
-    txt.append(0xdc25);
-    txt.append("b");
-    QVector<HB_CharAttributes> attrs = getCharAttributes(txt);
-    QVERIFY(attrs[0].charStop);
-    QVERIFY(attrs[1].charStop);
-    QVERIFY(!attrs[2].charStop);
-    QVERIFY(attrs[3].charStop);
-}
-
-void tst_CharAttributes::thaiWordBreak()
-{
-    // สวัสดีครับ นี่เป็นการงทดสอบตัวเอ
-    QTextCodec *codec = QTextCodec::codecForMib(2259);
-    QString txt = codec->toUnicode(QByteArray("\xca\xc7\xd1\xca\xb4\xd5\xa4\xc3\xd1\xba\x20\xb9\xd5\xe8\xe0\xbb\xe7\xb9\xa1\xd2\xc3\xb7\xb4\xca\xcd\xba\xb5\xd1\xc7\xe0\xcd\xa7"));
-
-
-    QCOMPARE(txt.length(), 32);
-    QVector<HB_CharAttributes> attrs = getCharAttributes(txt, HB_Script_Thai);
-    QVERIFY(attrs[0].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[1].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[2].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[3].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[4].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[5].lineBreakType == HB_Break);
-    QVERIFY(attrs[6].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[7].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[8].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[9].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[10].lineBreakType == HB_Break);
-    QVERIFY(attrs[11].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[12].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[13].lineBreakType == HB_Break);
-    QVERIFY(attrs[14].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[15].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[16].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[17].lineBreakType == HB_Break);
-    QVERIFY(attrs[18].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[19].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[20].lineBreakType == HB_Break);
-    QVERIFY(attrs[21].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[22].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[23].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[24].lineBreakType == HB_NoBreak);
-    QVERIFY(attrs[25].lineBreakType == HB_Break);
-    QVERIFY(attrs[26].lineBreakType == HB_NoBreak);
-    for (int i = 27; i < 32; ++i)
-        QVERIFY(attrs[i].lineBreakType == HB_NoBreak);
-}
-
-QTEST_MAIN(tst_CharAttributes)
-#include "main.moc"
diff --git a/third_party/harfbuzz/tests/shaping/.gitignore b/third_party/harfbuzz/tests/shaping/.gitignore
deleted file mode 100644
index 3f32cbe..0000000
--- a/third_party/harfbuzz/tests/shaping/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-harfbuzz-test-fonts-0.1.tar.bz2
-fonts
diff --git a/third_party/harfbuzz/tests/shaping/Makefile.am b/third_party/harfbuzz/tests/shaping/Makefile.am
deleted file mode 100644
index 31c6db7..0000000
--- a/third_party/harfbuzz/tests/shaping/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-
-check_PROGRAMS = shaping
-
-shaping_SOURCES = main.cpp ../linebreaking/harfbuzz-qt.cpp
-shaping_LDADD = $(QT_GUI_LIBS) $(QT_QTEST_LIBS) ../../src/libharfbuzz-1.la
-
-main.o: main.moc
-
-main.moc: $(srcdir)/main.cpp
-	$(QT_MOC) -o main.moc $(srcdir)/main.cpp
-
-INCLUDES = -I$(top_srcdir)/src $(FREETYPE_CFLAGS) $(QT_GUI_CFLAGS) $(QT_QTEST_CFLAGS)
-AM_CPPFLAGS = -DQT_GUI_LIB -DSRCDIR=\"$(srcdir)\"
-
diff --git a/third_party/harfbuzz/tests/shaping/README b/third_party/harfbuzz/tests/shaping/README
deleted file mode 100644
index 1db1c5a..0000000
--- a/third_party/harfbuzz/tests/shaping/README
+++ /dev/null
@@ -1,9 +0,0 @@
-These shaper tests need some specific TrueType fonts. You can get a package of
-them from
-
-        http://people.freedesktop.org/~hausmann/harfbuzz-test-fonts-0.1.tar.bz2
-
-In addition you may need two fonts (Mangal and Tunga) from Microsoft Windows
-for some of the test cases. These fonts are not freely redistributable.
-
-The test program looks for them in a fonts/ subdirectory.
diff --git a/third_party/harfbuzz/tests/shaping/main.cpp b/third_party/harfbuzz/tests/shaping/main.cpp
deleted file mode 100644
index 1a3ef4f..0000000
--- a/third_party/harfbuzz/tests/shaping/main.cpp
+++ /dev/null
@@ -1,1035 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include <QtTest/QtTest>
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TRUETYPE_TABLES_H
-
-#include <harfbuzz-shaper.h>
-#include <harfbuzz-global.h>
-#include <harfbuzz-gpos.h>
-
-static FT_Library freetype;
-
-static FT_Face loadFace(const char *name)
-{
-    FT_Face face;
-    char path[256];
-
-    strcpy(path, SRCDIR);
-    strcat(path, "/fonts/");
-    strcat(path, name);
-
-    if (FT_New_Face(freetype, path, /*index*/0, &face))
-        return 0;
-    return face;
-}
-
-static HB_UChar32 getChar(const HB_UChar16 *string, hb_uint32 length, hb_uint32 &i)
-{
-    HB_UChar32 ch;
-    if (HB_IsHighSurrogate(string[i])
-        && i < length - 1
-        && HB_IsLowSurrogate(string[i + 1])) {
-        ch = HB_SurrogateToUcs4(string[i], string[i + 1]);
-        ++i;
-    } else {
-        ch = string[i];
-    }
-    return ch;
-}
-
-static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool /*rightToLeft*/)
-{
-    FT_Face face = (FT_Face)font->userData;
-    if (length > *numGlyphs)
-        return false;
-
-    int glyph_pos = 0;
-    for (hb_uint32 i = 0; i < length; ++i) {
-        glyphs[glyph_pos] = FT_Get_Char_Index(face, getChar(string, length, i));
-        ++glyph_pos;
-    }
-
-    *numGlyphs = glyph_pos;
-
-    return true;
-}
-
-static void hb_getAdvances(HB_Font /*font*/, const HB_Glyph * /*glyphs*/, hb_uint32 numGlyphs, HB_Fixed *advances, int /*flags*/)
-{
-    for (hb_uint32 i = 0; i < numGlyphs; ++i)
-        advances[i] = 0; // ### not tested right now
-}
-
-static HB_Bool hb_canRender(HB_Font font, const HB_UChar16 *string, hb_uint32 length)
-{
-    FT_Face face = (FT_Face)font->userData;
-
-    for (hb_uint32 i = 0; i < length; ++i)
-        if (!FT_Get_Char_Index(face, getChar(string, length, i)))
-            return false;
-
-    return true;
-}
-
-static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length)
-{
-    FT_Face face = (FT_Face)font;
-    FT_ULong ftlen = *length;
-    FT_Error error = 0;
-
-    if (!FT_IS_SFNT(face))
-        return HB_Err_Invalid_Argument;
-
-    error = FT_Load_Sfnt_Table(face, tableTag, 0, buffer, &ftlen);
-    *length = ftlen;
-    return (HB_Error)error;
-}
-
-HB_Error hb_getPointInOutline(HB_Font font, HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
-{
-    HB_Error error = HB_Err_Ok;
-    FT_Face face = (FT_Face)font->userData;
-
-    int load_flags = (flags & HB_ShaperFlag_UseDesignMetrics) ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT;
-
-    if ((error = (HB_Error)FT_Load_Glyph(face, glyph, load_flags)))
-        return error;
-
-    if (face->glyph->format != ft_glyph_format_outline)
-        return (HB_Error)HB_Err_Invalid_SubTable;
-
-    *nPoints = face->glyph->outline.n_points;
-    if (!(*nPoints))
-        return HB_Err_Ok;
-
-    if (point > *nPoints)
-        return (HB_Error)HB_Err_Invalid_SubTable;
-
-    *xpos = face->glyph->outline.points[point].x;
-    *ypos = face->glyph->outline.points[point].y;
-
-    return HB_Err_Ok;
-}
-
-void hb_getGlyphMetrics(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics)
-{
-    // ###
-    metrics->x = metrics->y = metrics->width = metrics->height = metrics->xOffset = metrics->yOffset = 0;
-}
-
-HB_Fixed hb_getFontMetric(HB_Font font, HB_FontMetric metric)
-{
-    return 0; // ####
-}
-
-const HB_FontClass hb_fontClass = {
-    hb_stringToGlyphs, hb_getAdvances, hb_canRender,
-    hb_getPointInOutline, hb_getGlyphMetrics, hb_getFontMetric
-};
-
-
-//TESTED_CLASS=
-//TESTED_FILES= gui/text/qscriptengine.cpp
-
-class tst_QScriptEngine : public QObject
-{
-Q_OBJECT
-
-public:
-    tst_QScriptEngine();
-    virtual ~tst_QScriptEngine();
-
-
-public slots:
-    void initTestCase();
-    void cleanupTestCase();
-private slots:
-    void devanagari();
-    void bengali();
-    void gurmukhi();
-    // gujarati missing
-    void oriya();
-    void tamil();
-    void telugu();
-    void kannada();
-    void malayalam();
-    // sinhala missing
-
-    void khmer();
-    void linearB();
-};
-
-tst_QScriptEngine::tst_QScriptEngine()
-{
-}
-
-tst_QScriptEngine::~tst_QScriptEngine()
-{
-}
-
-void tst_QScriptEngine::initTestCase()
-{
-    FT_Init_FreeType(&freetype);
-}
-
-void tst_QScriptEngine::cleanupTestCase()
-{
-    FT_Done_FreeType(freetype);
-}
-
-struct ShapeTable {
-    unsigned short unicode[16];
-    unsigned short glyphs[16];
-};
-
-static bool shaping(FT_Face face, const ShapeTable *s, HB_Script script)
-{
-    QString str = QString::fromUtf16( s->unicode );
-
-    HB_Face hbFace = HB_NewFace(face, hb_getSFntTable);
-
-    HB_FontRec hbFont;
-    hbFont.klass = &hb_fontClass;
-    hbFont.userData = face;
-    hbFont.x_ppem  = face->size->metrics.x_ppem;
-    hbFont.y_ppem  = face->size->metrics.y_ppem;
-    hbFont.x_scale = face->size->metrics.x_scale;
-    hbFont.y_scale = face->size->metrics.y_scale;
-
-    HB_ShaperItem shaper_item;
-    shaper_item.kerning_applied = false;
-    shaper_item.string = reinterpret_cast<const HB_UChar16 *>(str.constData());
-    shaper_item.stringLength = str.length();
-    shaper_item.item.script = script;
-    shaper_item.item.pos = 0;
-    shaper_item.item.length = shaper_item.stringLength;
-    shaper_item.item.bidiLevel = 0; // ###
-    shaper_item.shaperFlags = 0;
-    shaper_item.font = &hbFont;
-    shaper_item.face = hbFace;
-    shaper_item.num_glyphs = shaper_item.item.length;
-    shaper_item.glyphIndicesPresent = false;
-    shaper_item.initialGlyphCount = 0;
-
-    QVarLengthArray<HB_Glyph> hb_glyphs(shaper_item.num_glyphs);
-    QVarLengthArray<HB_GlyphAttributes> hb_attributes(shaper_item.num_glyphs);
-    QVarLengthArray<HB_Fixed> hb_advances(shaper_item.num_glyphs);
-    QVarLengthArray<HB_FixedPoint> hb_offsets(shaper_item.num_glyphs);
-    QVarLengthArray<unsigned short> hb_logClusters(shaper_item.num_glyphs);
-
-    while (1) {
-        hb_glyphs.resize(shaper_item.num_glyphs);
-        hb_attributes.resize(shaper_item.num_glyphs);
-        hb_advances.resize(shaper_item.num_glyphs);
-        hb_offsets.resize(shaper_item.num_glyphs);
-        hb_logClusters.resize(shaper_item.num_glyphs);
-
-        memset(hb_glyphs.data(), 0, hb_glyphs.size() * sizeof(HB_Glyph));
-        memset(hb_attributes.data(), 0, hb_attributes.size() * sizeof(HB_GlyphAttributes));
-        memset(hb_advances.data(), 0, hb_advances.size() * sizeof(HB_Fixed));
-        memset(hb_offsets.data(), 0, hb_offsets.size() * sizeof(HB_FixedPoint));
-
-        shaper_item.glyphs = hb_glyphs.data();
-        shaper_item.attributes = hb_attributes.data();
-        shaper_item.advances = hb_advances.data();
-        shaper_item.offsets = hb_offsets.data();
-        shaper_item.log_clusters = hb_logClusters.data();
-
-        if (HB_ShapeItem(&shaper_item))
-            break;
-
-    }
-
-    HB_FreeFace(hbFace);
-
-    hb_uint32 nglyphs = 0;
-    const unsigned short *g = s->glyphs;
-    while ( *g ) {
-	nglyphs++;
-	g++;
-    }
-
-    if( nglyphs != shaper_item.num_glyphs )
-	goto error;
-
-    for (hb_uint32 i = 0; i < nglyphs; ++i) {
-	if ((shaper_item.glyphs[i]&0xffffff) != s->glyphs[i])
-	    goto error;
-    }
-    return true;
- error:
-    str = "";
-    const unsigned short *uc = s->unicode;
-    while (*uc) {
-	str += QString("%1 ").arg(*uc, 4, 16);
-	++uc;
-    }
-    qDebug("%s: shaping of string %s failed, nglyphs=%d, expected %d",
-           face->family_name,
-           str.toLatin1().constData(),
-           shaper_item.num_glyphs, nglyphs);
-
-    str = "";
-    hb_uint32 i = 0;
-    while (i < shaper_item.num_glyphs) {
-	str += QString("%1 ").arg(shaper_item.glyphs[i], 4, 16);
-	++i;
-    }
-    qDebug("    glyph result = %s", str.toLatin1().constData());
-    return false;
-}
-
-void tst_QScriptEngine::devanagari()
-{
-    {
-        FT_Face face = loadFace("raghu.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		// Ka
-		{ { 0x0915, 0x0 },
-		  { 0x0080, 0x0 } },
-		// Ka Halant
-		{ { 0x0915, 0x094d, 0x0 },
-		  { 0x0080, 0x0051, 0x0 } },
-		// Ka Halant Ka
-		{ { 0x0915, 0x094d, 0x0915, 0x0 },
-		  { 0x00c8, 0x0080, 0x0 } },
-		// Ka MatraI
-		{ { 0x0915, 0x093f, 0x0 },
-		  { 0x01d1, 0x0080, 0x0 } },
-		// Ra Halant Ka
-		{ { 0x0930, 0x094d, 0x0915, 0x0 },
-		  { 0x0080, 0x005b, 0x0 } },
-		// Ra Halant Ka MatraI
-		{ { 0x0930, 0x094d, 0x0915, 0x093f, 0x0 },
-		  { 0x01d1, 0x0080, 0x005b, 0x0 } },
-		// MatraI
-		{ { 0x093f, 0x0 },
-		  { 0x01d4, 0x029c, 0x0 } },
-		// Ka Nukta
-		{ { 0x0915, 0x093c, 0x0 },
-		  { 0x00a4, 0x0 } },
-		// Ka Halant Ra
-		{ { 0x0915, 0x094d, 0x0930, 0x0 },
-		  { 0x0110, 0x0 } },
-		// Ka Halant Ra Halant Ka
-		{ { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0x0 },
-		  { 0x0158, 0x0080, 0x0 } },
-		{ { 0x0930, 0x094d, 0x200d, 0x0 },
-		  { 0x00e2, 0x0 } },
-		{ { 0x0915, 0x094d, 0x0930, 0x094d, 0x200d, 0x0 },
-		  { 0x0158, 0x0 } },
-
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Devanagari) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find raghu.ttf", SkipAll);
-	}
-    }
-
-    {
-        FT_Face face = loadFace("mangal.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		// Ka
-		{ { 0x0915, 0x0 },
-		  { 0x0080, 0x0 } },
-		// Ka Halant
-		{ { 0x0915, 0x094d, 0x0 },
-		  { 0x0080, 0x0051, 0x0 } },
-		// Ka Halant Ka
-		{ { 0x0915, 0x094d, 0x0915, 0x0 },
-		  { 0x00c8, 0x0080, 0x0 } },
-		// Ka MatraI
-		{ { 0x0915, 0x093f, 0x0 },
-		  { 0x01d1, 0x0080, 0x0 } },
-		// Ra Halant Ka
-		{ { 0x0930, 0x094d, 0x0915, 0x0 },
-		  { 0x0080, 0x005b, 0x0 } },
-		// Ra Halant Ka MatraI
-		{ { 0x0930, 0x094d, 0x0915, 0x093f, 0x0 },
-		  { 0x01d1, 0x0080, 0x005b, 0x0 } },
-		// MatraI
-		{ { 0x093f, 0x0 },
-		  { 0x01d4, 0x029c, 0x0 } },
-		// Ka Nukta
-		{ { 0x0915, 0x093c, 0x0 },
-		  { 0x00a4, 0x0 } },
-		// Ka Halant Ra
-		{ { 0x0915, 0x094d, 0x0930, 0x0 },
-		  { 0x0110, 0x0 } },
-		// Ka Halant Ra Halant Ka
-		{ { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0x0 },
-		  { 0x0158, 0x0080, 0x0 } },
-
-                { { 0x92b, 0x94d, 0x930, 0x0 },
-                  { 0x125, 0x0 } },
-                { { 0x92b, 0x93c, 0x94d, 0x930, 0x0 },
-                  { 0x149, 0x0 } }, 
-		{ {0}, {0} }
-	    };
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Devanagari) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couldn't find mangal.ttf", SkipAll);
-	}
-    }
-}
-
-void tst_QScriptEngine::bengali()
-{
-    {
-        FT_Face face = loadFace("AkaashNormal.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		// Ka
-		{ { 0x0995, 0x0 },
-		  { 0x0151, 0x0 } },
-		// Ka Halant
-		{ { 0x0995, 0x09cd, 0x0 },
-		  { 0x0151, 0x017d, 0x0 } },
-		// Ka Halant Ka
-		{ { 0x0995, 0x09cd, 0x0995, 0x0 },
-		  { 0x019b, 0x0 } },
-		// Ka MatraI
-		{ { 0x0995, 0x09bf, 0x0 },
-		  { 0x0173, 0x0151, 0x0 } },
-		// Ra Halant Ka
-		{ { 0x09b0, 0x09cd, 0x0995, 0x0 },
-		  { 0x0151, 0x0276, 0x0 } },
-		// Ra Halant Ka MatraI
-		{ { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0x0 },
-		  { 0x0173, 0x0151, 0x0276, 0x0 } },
-		// Ka Nukta
-		{ { 0x0995, 0x09bc, 0x0 },
-		  { 0x0151, 0x0171, 0x0 } },
-		// Ka Halant Ra
-		{ { 0x0995, 0x09cd, 0x09b0, 0x0 },
-		  { 0x01f4, 0x0 } },
-		// Ka Halant Ra Halant Ka
-		{ { 0x0995, 0x09cd, 0x09b0, 0x09cd, 0x0995, 0x0 },
-		  { 0x025c, 0x0276, 0x0151, 0x0 } },
-		// Ya + Halant
-		{ { 0x09af, 0x09cd, 0x0 },
-		  { 0x016a, 0x017d, 0x0 } },
-		// Da Halant Ya -> Da Ya-Phala
-		{ { 0x09a6, 0x09cd, 0x09af, 0x0 },
-		  { 0x01e5, 0x0 } },
-		// A Halant Ya -> A Ya-phala
-		{ { 0x0985, 0x09cd, 0x09af, 0x0 },
-		  { 0x0145, 0x01cf, 0x0 } },
-		// Na Halant Ka
-		{ { 0x09a8, 0x09cd, 0x0995, 0x0 },
-		  { 0x026f, 0x0151, 0x0 } },
-		// Na Halant ZWNJ Ka
-		{ { 0x09a8, 0x09cd, 0x200c, 0x0995, 0x0 },
-		  { 0x0164, 0x017d, 0x0151, 0x0 } },
-		// Na Halant ZWJ Ka
-		{ { 0x09a8, 0x09cd, 0x200d, 0x0995, 0x0 },
-		  { 0x026f, 0x0151, 0x0 } },
-		// Ka Halant ZWNJ Ka
-		{ { 0x0995, 0x09cd, 0x200c, 0x0995, 0x0 },
-		  { 0x0151, 0x017d, 0x0151, 0x0 } },
-		// Ka Halant ZWJ Ka
-		{ { 0x0995, 0x09cd, 0x200d, 0x0995, 0x0 },
-		  { 0x025c, 0x0151, 0x0 } },
-		// Na Halant Ra
-		{ { 0x09a8, 0x09cd, 0x09b0, 0x0 },
-		  { 0x0207, 0x0 } },
-		// Na Halant ZWNJ Ra
-		{ { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0x0 },
-		  { 0x0164, 0x017d, 0x016b, 0x0 } },
-		// Na Halant ZWJ Ra
-		{ { 0x09a8, 0x09cd, 0x200d, 0x09b0, 0x0 },
-		  { 0x026f, 0x016b, 0x0 } },
-		// Na Halant Ba
-		{ { 0x09a8, 0x09cd, 0x09ac, 0x0 },
-		  { 0x022f, 0x0 } },
-		// Na Halant ZWNJ Ba
-		{ { 0x09a8, 0x09cd, 0x200c, 0x09ac, 0x0 },
-		  { 0x0164, 0x017d, 0x0167, 0x0 } },
-		// Na Halant ZWJ Ba
-		{ { 0x09a8, 0x09cd, 0x200d, 0x09ac, 0x0 },
-		  { 0x026f, 0x0167, 0x0 } },
-		// Na Halant Dha
-		{ { 0x09a8, 0x09cd, 0x09a7, 0x0 },
-		  { 0x01d3, 0x0 } },
-		// Na Halant ZWNJ Dha
-		{ { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0x0 },
-		  { 0x0164, 0x017d, 0x0163, 0x0 } },
-		// Na Halant ZWJ Dha
-		{ { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0x0 },
-		  { 0x026f, 0x0163, 0x0 } },
-		// Ra Halant Ka MatraAU
-		{ { 0x09b0, 0x09cd, 0x0995, 0x09cc, 0x0 },
-		  { 0x0179, 0x0151, 0x0276, 0x017e, 0x0 } },
-		// Ra Halant Ba Halant Ba
-		{ { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 },
-		  { 0x0232, 0x0276, 0x0 } },
-                { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x982, 0x0 },
-                  { 0x151, 0x276, 0x172, 0x143, 0x0 } },
-                { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x983, 0x0 },
-                  { 0x151, 0x276, 0x172, 0x144, 0x0 } }, 
-
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Bengali) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find AkaashNormal.ttf", SkipAll);
-	}
-    }
-    {
-        FT_Face face = loadFace("MuktiNarrow.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		// Ka
-		{ { 0x0995, 0x0 },
-		  { 0x0073, 0x0 } },
-		// Ka Halant
-		{ { 0x0995, 0x09cd, 0x0 },
-		  { 0x00b9, 0x0 } },
-		// Ka Halant Ka
-		{ { 0x0995, 0x09cd, 0x0995, 0x0 },
-		  { 0x0109, 0x0 } },
-		// Ka MatraI
-		{ { 0x0995, 0x09bf, 0x0 },
-		  { 0x0095, 0x0073, 0x0 } },
-		// Ra Halant Ka
-		{ { 0x09b0, 0x09cd, 0x0995, 0x0 },
-		  { 0x0073, 0x00e1, 0x0 } },
-		// Ra Halant Ka MatraI
-		{ { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0x0 },
-		  { 0x0095, 0x0073, 0x00e1, 0x0 } },
-		// MatraI
- 		{ { 0x09bf, 0x0 },
-		  { 0x0095, 0x01c8, 0x0 } },
-		// Ka Nukta
-		{ { 0x0995, 0x09bc, 0x0 },
-		  { 0x0073, 0x0093, 0x0 } },
-		// Ka Halant Ra
-		{ { 0x0995, 0x09cd, 0x09b0, 0x0 },
-		  { 0x00e5, 0x0 } },
-		// Ka Halant Ra Halant Ka
-                { { 0x995, 0x9cd, 0x9b0, 0x9cd, 0x995, 0x0 },
-                  { 0x234, 0x24e, 0x73, 0x0 } }, 
-		// Ya + Halant
-		{ { 0x09af, 0x09cd, 0x0 },
-		  { 0x00d2, 0x0 } },
-		// Da Halant Ya -> Da Ya-Phala
-		{ { 0x09a6, 0x09cd, 0x09af, 0x0 },
-		  { 0x0084, 0x00e2, 0x0 } },
-		// A Halant Ya -> A Ya-phala
-		{ { 0x0985, 0x09cd, 0x09af, 0x0 },
-		  { 0x0067, 0x00e2, 0x0 } },
-		// Na Halant Ka
-		{ { 0x09a8, 0x09cd, 0x0995, 0x0 },
-		  { 0x0188, 0x0 } },
-		// Na Halant ZWNJ Ka
-                { { 0x9a8, 0x9cd, 0x200c, 0x995, 0x0 },
-                  { 0xcc, 0x73, 0x0 } }, 
-		// Na Halant ZWJ Ka
-                { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 },
-                  { 0x247, 0x73, 0x0 } }, 
-		// Ka Halant ZWNJ Ka
-                { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 },
-                  { 0x247, 0x73, 0x0 } }, 
-		// Ka Halant ZWJ Ka
-                { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 },
-                  { 0x247, 0x73, 0x0 } }, 
-		// Na Halant Ra
-		{ { 0x09a8, 0x09cd, 0x09b0, 0x0 },
-		  { 0x00f8, 0x0 } },
-		// Na Halant ZWNJ Ra
-		{ { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0x0 },
-		  { 0xcc, 0x8d, 0x0 } },
-		// Na Halant ZWJ Ra
-                { { 0x9a8, 0x9cd, 0x200d, 0x9b0, 0x0 },
-                  { 0x247, 0x8d, 0x0 } }, 
-		// Na Halant Ba
-		{ { 0x09a8, 0x09cd, 0x09ac, 0x0 },
-		  { 0x0139, 0x0 } },
-		// Na Halant ZWNJ Ba
-                { { 0x9a8, 0x9cd, 0x200c, 0x9ac, 0x0 },
-                  { 0xcc, 0x89, 0x0 } }, 
-		// Na Halant ZWJ Ba
-                { { 0x9a8, 0x9cd, 0x200d, 0x9ac, 0x0 },
-                  { 0x247, 0x89, 0x0 } }, 
-		// Na Halant Dha
-		{ { 0x09a8, 0x09cd, 0x09a7, 0x0 },
-		  { 0x0145, 0x0 } },
-		// Na Halant ZWNJ Dha
-		{ { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0x0 },
-		  { 0xcc, 0x85, 0x0 } },
-		// Na Halant ZWJ Dha
-		{ { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0x0 },
-		  { 0x247, 0x85, 0x0 } },
-		// Ra Halant Ka MatraAU
-                { { 0x9b0, 0x9cd, 0x995, 0x9cc, 0x0 },
-                  { 0x232, 0x73, 0xe1, 0xa0, 0x0 } }, 
-		// Ra Halant Ba Halant Ba
-		{ { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 },
-		  { 0x013b, 0x00e1, 0x0 } },
-
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Bengali) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find MuktiNarrow.ttf", SkipAll);
-	}
-    }
-    {
-        FT_Face face = loadFace("LikhanNormal.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		{ { 0x09a8, 0x09cd, 0x09af, 0x0 },
-		  { 0x0192, 0x0 } },
-		{ { 0x09b8, 0x09cd, 0x09af, 0x0 },
-		  { 0x01d6, 0x0 } },
-		{ { 0x09b6, 0x09cd, 0x09af, 0x0 },
-		  { 0x01bc, 0x0 } },
-		{ { 0x09b7, 0x09cd, 0x09af, 0x0 },
-		  { 0x01c6, 0x0 } },
-		{ { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0x0 },
-		  { 0xd3, 0x12f, 0x0 } },
-
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Bengali) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find LikhanNormal.ttf", SkipAll);
-	}
-    }
-}
-
-void tst_QScriptEngine::gurmukhi()
-{
-    {
-        FT_Face face = loadFace("lohit.punjabi.1.1.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		{ { 0xA15, 0xA4D, 0xa39, 0x0 },
-		  { 0x3b, 0x8b, 0x0 } },
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Gurmukhi) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find lohit.punjabi.1.1.ttf", SkipAll);
-	}
-    }
-}
-
-void tst_QScriptEngine::oriya()
-{
-    {
-        FT_Face face = loadFace("utkalm.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-                { { 0xb15, 0xb4d, 0xb24, 0xb4d, 0xb30, 0x0 },
-                  { 0x150, 0x125, 0x0 } }, 
-                { { 0xb24, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0x0 },
-                  { 0x151, 0x120, 0x0 } }, 
-                { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0x0 },
-                  { 0x152, 0x120, 0x0 } }, 
-                { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0x0 },
-                  { 0x152, 0x120, 0x0 } }, 
-                { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb30, 0x0 },
-                  { 0x176, 0x0 } }, 
-                { { 0xb38, 0xb4d, 0xb24, 0xb4d, 0xb30, 0x0 },
-                  { 0x177, 0x0 } }, 
-                { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb30, 0xb4d, 0xb2f, 0x0 },
-                  { 0x176, 0x124, 0x0 } }, 
-                { {0}, {0} }
-
-            };
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Oriya) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find utkalm.ttf", SkipAll);
-	}
-    }
-}
-
-
-void tst_QScriptEngine::tamil()
-{
-    {
-        FT_Face face = loadFace("akruti1.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		{ { 0x0b95, 0x0bc2, 0x0 },
-		  { 0x004e, 0x0 } },
-		{ { 0x0bae, 0x0bc2, 0x0 },
-		  { 0x009e, 0x0 } },
-		{ { 0x0b9a, 0x0bc2, 0x0 },
-		  { 0x0058, 0x0 } },
-		{ { 0x0b99, 0x0bc2, 0x0 },
-		  { 0x0053, 0x0 } },
-		{ { 0x0bb0, 0x0bc2, 0x0 },
-		  { 0x00a8, 0x0 } },
-		{ { 0x0ba4, 0x0bc2, 0x0 },
-		  { 0x008e, 0x0 } },
-		{ { 0x0b9f, 0x0bc2, 0x0 },
-		  { 0x0062, 0x0 } },
-		{ { 0x0b95, 0x0bc6, 0x0 },
-		  { 0x000a, 0x0031, 0x0 } },
-		{ { 0x0b95, 0x0bca, 0x0 },
-		  { 0x000a, 0x0031, 0x0007, 0x0 } },
-		{ { 0x0b95, 0x0bc6, 0x0bbe, 0x0 },
-		  { 0x000a, 0x0031, 0x007, 0x0 } },
-		{ { 0x0b95, 0x0bcd, 0x0bb7, 0x0 },
-		  { 0x0049, 0x0 } },
-		{ { 0x0b95, 0x0bcd, 0x0bb7, 0x0bca, 0x0 },
-		  { 0x000a, 0x0049, 0x007, 0x0 } },
-		{ { 0x0b95, 0x0bcd, 0x0bb7, 0x0bc6, 0x0bbe, 0x0 },
-		  { 0x000a, 0x0049, 0x007, 0x0 } },
-		{ { 0x0b9f, 0x0bbf, 0x0 },
-		  { 0x005f, 0x0 } },
-		{ { 0x0b9f, 0x0bc0, 0x0 },
-		  { 0x0060, 0x0 } },
-		{ { 0x0bb2, 0x0bc0, 0x0 },
-		  { 0x00ab, 0x0 } },
-		{ { 0x0bb2, 0x0bbf, 0x0 },
-		  { 0x00aa, 0x0 } },
-		{ { 0x0bb0, 0x0bcd, 0x0 },
-		  { 0x00a4, 0x0 } },
-		{ { 0x0bb0, 0x0bbf, 0x0 },
-		  { 0x00a5, 0x0 } },
-		{ { 0x0bb0, 0x0bc0, 0x0 },
-		  { 0x00a6, 0x0 } },
-		{ { 0x0b83, 0x0 },
-		  { 0x0025, 0x0 } },
-		{ { 0x0b83, 0x0b95, 0x0 },
-		  { 0x0025, 0x0031, 0x0 } },
-
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Tamil) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find akruti1.ttf", SkipAll);
-	}
-    }
-}
-
-
-void tst_QScriptEngine::telugu()
-{
-    {
-        FT_Face face = loadFace("Pothana2000.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-                { { 0xc15, 0xc4d, 0x0 },
-                  { 0xbb, 0x0 } }, 
-                { { 0xc15, 0xc4d, 0xc37, 0x0 },
-                  { 0x4b, 0x0 } }, 
-                { { 0xc15, 0xc4d, 0xc37, 0xc4d, 0x0 },
-                  { 0xe0, 0x0 } }, 
-                { { 0xc15, 0xc4d, 0xc37, 0xc4d, 0xc23, 0x0 },
-                  { 0x4b, 0x91, 0x0 } }, 
-                { { 0xc15, 0xc4d, 0xc30, 0x0 },
-                  { 0x5a, 0xb2, 0x0 } }, 
-                { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0x0 },
-                  { 0xbb, 0xb2, 0x0 } }, 
-                { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0xc15, 0x0 },
-                  { 0x5a, 0xb2, 0x83, 0x0 } }, 
-                { { 0xc15, 0xc4d, 0xc30, 0xc3f, 0x0 },
-                  { 0xe2, 0xb2, 0x0 } }, 
-                { { 0xc15, 0xc4d, 0xc15, 0xc48, 0x0 },
-                  { 0xe6, 0xb3, 0x83, 0x0 } },
-                { { 0xc15, 0xc4d, 0xc30, 0xc48, 0x0 },
-                  { 0xe6, 0xb3, 0x9f, 0x0 } }, 
-		{ {0}, {0} }
-
-            };
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Telugu) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find Pothana2000.ttf", SkipAll);
-	}
-    }
-}
-
-
-void tst_QScriptEngine::kannada()
-{
-    {
-        FT_Face face = loadFace("Sampige.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		{ { 0x0ca8, 0x0ccd, 0x0ca8, 0x0 },
-		  { 0x0049, 0x00ba, 0x0 } },
-		{ { 0x0ca8, 0x0ccd, 0x0ca1, 0x0 },
-		  { 0x0049, 0x00b3, 0x0 } },
-		{ { 0x0caf, 0x0cc2, 0x0 },
-		  { 0x004f, 0x005d, 0x0 } },
-		{ { 0x0ce0, 0x0 },
-		  { 0x006a, 0x0 } },
-		{ { 0x0ce6, 0x0ce7, 0x0ce8, 0x0 },
-		  { 0x006b, 0x006c, 0x006d, 0x0 } },
-		{ { 0x0cb5, 0x0ccb, 0x0 },
-		  { 0x015f, 0x0067, 0x0 } },
-		{ { 0x0cb0, 0x0ccd, 0x0cae, 0x0 },
-		  { 0x004e, 0x0082, 0x0 } },
-		{ { 0x0cb0, 0x0ccd, 0x0c95, 0x0 },
-		  { 0x0036, 0x0082, 0x0 } },
-		{ { 0x0c95, 0x0ccd, 0x0cb0, 0x0 },
-		  { 0x0036, 0x00c1, 0x0 } },
-		{ { 0x0cb0, 0x0ccd, 0x200d, 0x0c95, 0x0 },
-		  { 0x0050, 0x00a7, 0x0 } },
-
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Kannada) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find Sampige.ttf", SkipAll);
-	}
-    }
-    {
-        FT_Face face = loadFace("tunga.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		{ { 0x0cb7, 0x0cc6, 0x0 },
-		  { 0x00b0, 0x006c, 0x0 } },
-		{ { 0x0cb7, 0x0ccd, 0x0 },
-		  { 0x0163, 0x0 } },
-
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Kannada) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find tunga.ttf", SkipAll);
-	}
-    }
-}
-
-
-
-void tst_QScriptEngine::malayalam()
-{
-    {
-        FT_Face face = loadFace("AkrutiMal2Normal.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		{ { 0x0d15, 0x0d46, 0x0 },
-		  { 0x005e, 0x0034, 0x0 } },
-		{ { 0x0d15, 0x0d47, 0x0 },
-		  { 0x005f, 0x0034, 0x0 } },
-		{ { 0x0d15, 0x0d4b, 0x0 },
-		  { 0x005f, 0x0034, 0x0058, 0x0 } },
-		{ { 0x0d15, 0x0d48, 0x0 },
-		  { 0x0060, 0x0034, 0x0 } },
-		{ { 0x0d15, 0x0d4a, 0x0 },
-		  { 0x005e, 0x0034, 0x0058, 0x0 } },
-		{ { 0x0d30, 0x0d4d, 0x0d15, 0x0 },
-		  { 0x009e, 0x0034, 0x0 } },
-		{ { 0x0d15, 0x0d4d, 0x0d35, 0x0 },
-		  { 0x0034, 0x007a, 0x0 } },
-		{ { 0x0d15, 0x0d4d, 0x0d2f, 0x0 },
-		  { 0x0034, 0x00a2, 0x0 } },
-		{ { 0x0d1f, 0x0d4d, 0x0d1f, 0x0 },
-		  { 0x0069, 0x0 } },
-		{ { 0x0d26, 0x0d4d, 0x0d26, 0x0 },
-		  { 0x0074, 0x0 } },
-		{ { 0x0d30, 0x0d4d, 0x0 },
-		  { 0x009e, 0x0 } },
-		{ { 0x0d30, 0x0d4d, 0x200c, 0x0 },
-		  { 0x009e, 0x0 } },
-		{ { 0x0d30, 0x0d4d, 0x200d, 0x0 },
-		  { 0x009e, 0x0 } },
-
-
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Malayalam) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find AkrutiMal2Normal.ttf", SkipAll);
-	}
-    }
-}
-
-
-
-void tst_QScriptEngine::khmer()
-{
-    {
-        FT_Face face = loadFace("KhmerOS.ttf");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		{ { 0x179a, 0x17cd, 0x0 },
-		  { 0x24c, 0x27f, 0x0 } },
-		{ { 0x179f, 0x17c5, 0x0 },
-		  { 0x273, 0x203, 0x0 } },
-		{ { 0x1790, 0x17d2, 0x1784, 0x17c3, 0x0 },
-		  { 0x275, 0x242, 0x182, 0x0 } },
-		{ { 0x179a, 0x0 },
-		  { 0x24c, 0x0 } },
-		{ { 0x1781, 0x17d2, 0x1798, 0x17c2, 0x0 },
-		  { 0x274, 0x233, 0x197, 0x0 } },
-		{ { 0x1798, 0x17b6, 0x0 },
-		  { 0x1cb, 0x0 } },
-		{ { 0x179a, 0x17b8, 0x0 },
-		  { 0x24c, 0x26a, 0x0 } },
-		{ { 0x1787, 0x17b6, 0x0 },
-		  { 0x1ba, 0x0 } },
-		{ { 0x1798, 0x17d2, 0x1796, 0x17bb, 0x0 },
-		  { 0x24a, 0x195, 0x26d, 0x0 } },
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Khmer) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find KhmerOS.ttf", SkipAll);
-	}
-    }
-}
-
-void tst_QScriptEngine::linearB()
-{
-    {
-        FT_Face face = loadFace("PENUTURE.TTF");
-        if (face) {
-	    const ShapeTable shape_table [] = {
-		{ { 0xd800, 0xdc01, 0xd800, 0xdc02, 0xd800, 0xdc03,  0 },
-                  { 0x5, 0x6, 0x7, 0 } },
-		{ {0}, {0} }
-	    };
-
-
-	    const ShapeTable *s = shape_table;
-	    while (s->unicode[0]) {
-		QVERIFY( shaping(face, s, HB_Script_Common) );
-		++s;
-	    }
-
-            FT_Done_Face(face);
-	} else {
-	    QSKIP("couln't find PENUTURE.TTF", SkipAll);
-	}
-    }
-}
-
-
-QTEST_MAIN(tst_QScriptEngine)
-#include "main.moc"
diff --git a/third_party/ktx/ktx.cpp b/third_party/ktx/ktx.cpp
index a05498b..7cc2f28 100644
--- a/third_party/ktx/ktx.cpp
+++ b/third_party/ktx/ktx.cpp
@@ -12,9 +12,53 @@
 #include "SkEndian.h"
 
 #include "gl/GrGLDefines.h"
+#include "GrConfig.h"
 
 #include "etc1.h"
 
+static inline uint32_t compressed_fmt_to_gl_define(SkTextureCompressor::Format fmt) {
+    static const uint32_t kGLDefineMap[SkTextureCompressor::kFormatCnt] = {
+        GR_GL_COMPRESSED_LUMINANCE_LATC1,  // kLATC_Format
+        GR_GL_COMPRESSED_R11,              // kR11_EAC_Format
+        GR_GL_COMPRESSED_RGB8_ETC1,        // kETC1_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_4x4,    // kASTC_4x4_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_5x4,    // kASTC_5x4_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_5x5,    // kASTC_5x5_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_6x5,    // kASTC_6x5_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_6x6,    // kASTC_6x6_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_8x5,    // kASTC_8x5_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_8x6,    // kASTC_8x6_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_8x8,    // kASTC_8x8_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_10x5,   // kASTC_10x5_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_10x6,   // kASTC_10x6_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_10x8,   // kASTC_10x8_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_10x10,  // kASTC_10x10_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_12x10,  // kASTC_12x10_Format
+        GR_GL_COMPRESSED_RGBA_ASTC_12x12,  // kASTC_12x12_Format
+    };
+
+    GR_STATIC_ASSERT(0 == SkTextureCompressor::kLATC_Format);
+    GR_STATIC_ASSERT(1 == SkTextureCompressor::kR11_EAC_Format);
+    GR_STATIC_ASSERT(2 == SkTextureCompressor::kETC1_Format);
+    GR_STATIC_ASSERT(3 == SkTextureCompressor::kASTC_4x4_Format);
+    GR_STATIC_ASSERT(4 == SkTextureCompressor::kASTC_5x4_Format);
+    GR_STATIC_ASSERT(5 == SkTextureCompressor::kASTC_5x5_Format);
+    GR_STATIC_ASSERT(6 == SkTextureCompressor::kASTC_6x5_Format);
+    GR_STATIC_ASSERT(7 == SkTextureCompressor::kASTC_6x6_Format);
+    GR_STATIC_ASSERT(8 == SkTextureCompressor::kASTC_8x5_Format);
+    GR_STATIC_ASSERT(9 == SkTextureCompressor::kASTC_8x6_Format);
+    GR_STATIC_ASSERT(10 == SkTextureCompressor::kASTC_8x8_Format);
+    GR_STATIC_ASSERT(11 == SkTextureCompressor::kASTC_10x5_Format);
+    GR_STATIC_ASSERT(12 == SkTextureCompressor::kASTC_10x6_Format);
+    GR_STATIC_ASSERT(13 == SkTextureCompressor::kASTC_10x8_Format);
+    GR_STATIC_ASSERT(14 == SkTextureCompressor::kASTC_10x10_Format);
+    GR_STATIC_ASSERT(15 == SkTextureCompressor::kASTC_12x10_Format);
+    GR_STATIC_ASSERT(16 == SkTextureCompressor::kASTC_12x12_Format);
+    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kGLDefineMap) == SkTextureCompressor::kFormatCnt);
+
+    return kGLDefineMap[fmt];
+}
+
 #define KTX_FILE_IDENTIFIER_SIZE 12
 static const uint8_t KTX_FILE_IDENTIFIER[KTX_FILE_IDENTIFIER_SIZE] = {
     0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
@@ -91,7 +135,7 @@
 }
 
 uint32_t SkKTXFile::readInt(const uint8_t** buf, size_t* bytesLeft) const {
-    SkASSERT(NULL != buf && NULL != bytesLeft);
+    SkASSERT(buf && bytesLeft);
 
     uint32_t result;
 
@@ -123,8 +167,19 @@
     return SkString();
 }
 
-bool SkKTXFile::isETC1() const {
-    return this->valid() && GR_GL_COMPRESSED_RGB8_ETC1 == fHeader.fGLInternalFormat;
+bool SkKTXFile::isCompressedFormat(SkTextureCompressor::Format fmt) const {
+    if (!this->valid()) {
+        return false;
+    }
+
+    // This has many aliases
+    bool isFmt = false;
+    if (fmt == SkTextureCompressor::kLATC_Format) {
+        isFmt = GR_GL_COMPRESSED_RED_RGTC1 == fHeader.fGLInternalFormat ||
+                GR_GL_COMPRESSED_3DC_X == fHeader.fGLInternalFormat;
+    }
+
+    return isFmt || compressed_fmt_to_gl_define(fmt) == fHeader.fGLInternalFormat;
 }
 
 bool SkKTXFile::isRGBA8() const {
@@ -201,6 +256,11 @@
         if (fHeader.fNumberOfFaces > 1) {
             return false;
         }
+
+        // We don't support width and/or height <= 0
+        if (fHeader.fPixelWidth <= 0 || fHeader.fPixelHeight <= 0) {
+            return false;
+        }
     }
 
     // Make sure that we have enough bytes left for the key/value
diff --git a/third_party/ktx/ktx.h b/third_party/ktx/ktx.h
index 2f445a8..1114b49 100644
--- a/third_party/ktx/ktx.h
+++ b/third_party/ktx/ktx.h
@@ -11,6 +11,7 @@
 #define SkKTXFile_DEFINED
 
 #include "SkData.h"
+#include "SkTextureCompressor.h"
 #include "SkTypes.h"
 #include "SkTDArray.h"
 #include "SkString.h"
@@ -58,7 +59,7 @@
 
     int numMipmaps() const { return static_cast<int>(fHeader.fNumberOfMipmapLevels); }
 
-    bool isETC1() const;
+    bool isCompressedFormat(SkTextureCompressor::Format fmt) const;
     bool isRGBA8() const;
     bool isRGB8() const;
 
diff --git a/tools/CopyTilesRenderer.cpp b/tools/CopyTilesRenderer.cpp
index ebd33d8..30a3256 100644
--- a/tools/CopyTilesRenderer.cpp
+++ b/tools/CopyTilesRenderer.cpp
@@ -16,11 +16,17 @@
 #include "SkString.h"
 
 namespace sk_tools {
+#if SK_SUPPORT_GPU
+    CopyTilesRenderer::CopyTilesRenderer(const GrContext::Options& opts, int x, int y)
+    : INHERITED(opts)
+    , fXTilesPerLargeTile(x)
+    , fYTilesPerLargeTile(y) { }
+#else
     CopyTilesRenderer::CopyTilesRenderer(int x, int y)
     : fXTilesPerLargeTile(x)
-    , fYTilesPerLargeTile(y) {
-    }
-    void CopyTilesRenderer::init(SkPicture* pict, const SkString* writePath,
+    , fYTilesPerLargeTile(y) { }
+#endif
+    void CopyTilesRenderer::init(const SkPicture* pict, const SkString* writePath,
                                  const SkString* mismatchPath, const SkString* inputFilename,
                                  bool useChecksumBasedFilenames) {
         // Do not call INHERITED::init(), which would create a (potentially large) canvas which is
@@ -57,7 +63,8 @@
                 // Draw the picture
                 fCanvas->drawPicture(fPicture);
                 // Now extract the picture into tiles
-                const SkBitmap& baseBitmap = fCanvas->getDevice()->accessBitmap(false);
+                SkBitmap baseBitmap;
+                fCanvas->readPixels(SkIRect::MakeSize(fCanvas->getBaseLayerSize()), &baseBitmap);
                 SkIRect subset;
                 for (int tileY = 0; tileY < fLargeTileHeight; tileY += this->getTileHeight()) {
                     for (int tileX = 0; tileX < fLargeTileWidth; tileX += this->getTileWidth()) {
@@ -71,8 +78,8 @@
                             // a bitmap directly.
                             // TODO: Share more common code with write() to do this, to properly
                             // write out the JSON summary, etc.
-                            SkString pathWithNumber = SkOSPath::SkPathJoin(fWritePath.c_str(),
-                                                                           fInputFilename.c_str());
+                            SkString pathWithNumber = SkOSPath::Join(fWritePath.c_str(),
+                                                                     fInputFilename.c_str());
                             pathWithNumber.remove(pathWithNumber.size() - 4, 4);
                             pathWithNumber.appendf("%i.png", i++);
                             SkBitmap copy;
diff --git a/tools/CopyTilesRenderer.h b/tools/CopyTilesRenderer.h
index 3bf969b..b244142 100644
--- a/tools/CopyTilesRenderer.h
+++ b/tools/CopyTilesRenderer.h
@@ -22,8 +22,14 @@
     class CopyTilesRenderer : public TiledPictureRenderer {
 
     public:
+#if SK_SUPPORT_GPU
+        CopyTilesRenderer(const GrContext::Options &opts, int x, int y);
+#else
         CopyTilesRenderer(int x, int y);
-        virtual void init(SkPicture* pict, const SkString* writePath, const SkString* mismatchPath,
+#endif
+        virtual void init(const SkPicture* pict, 
+                          const SkString* writePath, 
+                          const SkString* mismatchPath,
                           const SkString* inputFilename,
                           bool useChecksumBasedFilenames) SK_OVERRIDE;
 
diff --git a/tools/CrashHandler.cpp b/tools/CrashHandler.cpp
index ffd9f3b..7355f20 100644
--- a/tools/CrashHandler.cpp
+++ b/tools/CrashHandler.cpp
@@ -4,169 +4,178 @@
 
 #include <stdlib.h>
 
-#if defined(SK_BUILD_FOR_MAC)
-
-// We only use local unwinding, so we can define this to select a faster implementation.
-#define UNW_LOCAL_ONLY
-#include <libunwind.h>
-#include <cxxabi.h>
-
-static void handler(int sig) {
-    unw_context_t context;
-    unw_getcontext(&context);
-
-    unw_cursor_t cursor;
-    unw_init_local(&cursor, &context);
-
-    SkDebugf("\nSignal %d:\n", sig);
-    while (unw_step(&cursor) > 0) {
-        static const size_t kMax = 256;
-        char mangled[kMax], demangled[kMax];
-        unw_word_t offset;
-        unw_get_proc_name(&cursor, mangled, kMax, &offset);
-
-        int ok;
-        size_t len = kMax;
-        abi::__cxa_demangle(mangled, demangled, &len, &ok);
-
-        SkDebugf("%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset);
-    }
-    SkDebugf("\n");
-
-    // Exit NOW.  Don't notify other threads, don't call anything registered with atexit().
-    _Exit(sig);
-}
-
-#elif defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL)   // NACL doesn't have backtrace().
-
-// We'd use libunwind here too, but it's a pain to get installed for both 32 and 64 bit on bots.
-// Doesn't matter much: catchsegv is best anyway.
-#include <execinfo.h>
-
-static void handler(int sig) {
-    static const int kMax = 64;
-    void* stack[kMax];
-    const int count = backtrace(stack, kMax);
-
-    SkDebugf("\nSignal %d:\n", sig);
-    backtrace_symbols_fd(stack, count, 2/*stderr*/);
-
-    // Exit NOW.  Don't notify other threads, don't call anything registered with atexit().
-    _Exit(sig);
-}
-
-#endif
-
-#if defined(SK_BUILD_FOR_MAC) || (defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL))
-#include <signal.h>
-
-void SetupCrashHandler() {
-    static const int kSignals[] = {
-        SIGABRT,
-        SIGBUS,
-        SIGFPE,
-        SIGILL,
-        SIGSEGV,
-    };
-
-    for (size_t i = 0; i < sizeof(kSignals) / sizeof(kSignals[0]); i++) {
-        // Register our signal handler unless something's already done so (e.g. catchsegv).
-        void (*prev)(int) = signal(kSignals[i], handler);
-        if (prev != SIG_DFL) {
-            signal(kSignals[i], prev);
-        }
-    }
-}
-
-#elif defined(SK_BUILD_FOR_WIN)
-
-#include <DbgHelp.h>
-
-static const struct {
-    const char* name;
-    int code;
-} kExceptions[] = {
-#define _(E) {#E, E}
-    _(EXCEPTION_ACCESS_VIOLATION),
-    _(EXCEPTION_BREAKPOINT),
-    _(EXCEPTION_INT_DIVIDE_BY_ZERO),
-    _(EXCEPTION_STACK_OVERFLOW),
-    // TODO: more?
-#undef _
-};
-
-static LONG WINAPI handler(EXCEPTION_POINTERS* e) {
-    const DWORD code = e->ExceptionRecord->ExceptionCode;
-    SkDebugf("\nCaught exception %u", code);
-    for (size_t i = 0; i < SK_ARRAY_COUNT(kExceptions); i++) {
-        if (kExceptions[i].code == code) {
-            SkDebugf(" %s", kExceptions[i].name);
-        }
-    }
-    SkDebugf("\n");
-
-    // We need to run SymInitialize before doing any of the stack walking below.
-    HANDLE hProcess = GetCurrentProcess();
-    SymInitialize(hProcess, 0, true);
-
-    STACKFRAME64 frame;
-    sk_bzero(&frame, sizeof(frame));
-    // Start frame off from the frame that triggered the exception.
-    CONTEXT* c = e->ContextRecord;
-    frame.AddrPC.Mode      = AddrModeFlat;
-    frame.AddrStack.Mode   = AddrModeFlat;
-    frame.AddrFrame.Mode   = AddrModeFlat;
-#if defined(_X86_)
-    frame.AddrPC.Offset    = c->Eip;
-    frame.AddrStack.Offset = c->Esp;
-    frame.AddrFrame.Offset = c->Ebp;
-    const DWORD machineType = IMAGE_FILE_MACHINE_I386;
-#elif defined(_AMD64_)
-    frame.AddrPC.Offset    = c->Rip;
-    frame.AddrStack.Offset = c->Rsp;
-    frame.AddrFrame.Offset = c->Rbp;
-    const DWORD machineType = IMAGE_FILE_MACHINE_AMD64;
-#endif
-
-    while (StackWalk64(machineType,
-                       GetCurrentProcess(),
-                       GetCurrentThread(),
-                       &frame,
-                       c,
-                       NULL,
-                       SymFunctionTableAccess64,
-                       SymGetModuleBase64,
-                       NULL)) {
-        // Buffer to store symbol name in.
-        static const int kMaxNameLength = 1024;
-        uint8_t buffer[sizeof(IMAGEHLP_SYMBOL64) + kMaxNameLength];
-        sk_bzero(buffer, sizeof(buffer));
-
-        // We have to place IMAGEHLP_SYMBOL64 at the front, and fill in how much space it can use.
-        IMAGEHLP_SYMBOL64* symbol = reinterpret_cast<IMAGEHLP_SYMBOL64*>(&buffer);
-        symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
-        symbol->MaxNameLength = kMaxNameLength - 1;
-
-        // Translate the current PC into a symbol and byte offset from the symbol.
-        DWORD64 offset;
-        SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offset, symbol);
-
-        SkDebugf("%s +%x\n", symbol->Name, offset);
-    }
-
-    // Exit NOW.  Don't notify other threads, don't call anything registered with atexit().
-    _exit(1);
-
-    // The compiler wants us to return something.  This is what we'd do if we didn't _exit().
-    return EXCEPTION_EXECUTE_HANDLER;
-}
-
-void SetupCrashHandler() {
-    SetUnhandledExceptionFilter(handler);
-}
+// Disable SetupCrashHandler() unless SK_CRASH_HANDLER is defined.
+#ifndef SK_CRASH_HANDLER
+    void SetupCrashHandler() { }
 
 #else
 
-void SetupCrashHandler() { }
+    #if defined(SK_BUILD_FOR_MAC)
 
-#endif
+        // We only use local unwinding, so we can define this to select a faster implementation.
+        #define UNW_LOCAL_ONLY
+        #include <libunwind.h>
+        #include <cxxabi.h>
+
+        static void handler(int sig) {
+            unw_context_t context;
+            unw_getcontext(&context);
+
+            unw_cursor_t cursor;
+            unw_init_local(&cursor, &context);
+
+            SkDebugf("\nSignal %d:\n", sig);
+            while (unw_step(&cursor) > 0) {
+                static const size_t kMax = 256;
+                char mangled[kMax], demangled[kMax];
+                unw_word_t offset;
+                unw_get_proc_name(&cursor, mangled, kMax, &offset);
+
+                int ok;
+                size_t len = kMax;
+                abi::__cxa_demangle(mangled, demangled, &len, &ok);
+
+                SkDebugf("%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset);
+            }
+            SkDebugf("\n");
+
+            // Exit NOW.  Don't notify other threads, don't call anything registered with atexit().
+            _Exit(sig);
+        }
+
+    #elif defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL)  // NACL doesn't have backtrace.
+
+        // We'd use libunwind here too, but it's a pain to get installed for
+        // both 32 and 64 bit on bots.  Doesn't matter much: catchsegv is best anyway.
+        #include <execinfo.h>
+
+        static void handler(int sig) {
+            static const int kMax = 64;
+            void* stack[kMax];
+            const int count = backtrace(stack, kMax);
+
+            SkDebugf("\nSignal %d [%s]:\n", sig, strsignal(sig));
+            backtrace_symbols_fd(stack, count, 2/*stderr*/);
+
+            // Exit NOW.  Don't notify other threads, don't call anything registered with atexit().
+            _Exit(sig);
+        }
+
+    #endif
+
+    #if (defined(SK_BUILD_FOR_MAC) || (defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL)))
+        #include <signal.h>
+
+        void SetupCrashHandler() {
+            static const int kSignals[] = {
+                SIGABRT,
+                SIGBUS,
+                SIGFPE,
+                SIGILL,
+                SIGSEGV,
+            };
+
+            for (size_t i = 0; i < sizeof(kSignals) / sizeof(kSignals[0]); i++) {
+                // Register our signal handler unless something's already done so (e.g. catchsegv).
+                void (*prev)(int) = signal(kSignals[i], handler);
+                if (prev != SIG_DFL) {
+                    signal(kSignals[i], prev);
+                }
+            }
+        }
+
+    #elif defined(SK_CRASH_HANDLER) && defined(SK_BUILD_FOR_WIN)
+
+        #include <DbgHelp.h>
+
+        static const struct {
+            const char* name;
+            int code;
+        } kExceptions[] = {
+        #define _(E) {#E, E}
+            _(EXCEPTION_ACCESS_VIOLATION),
+            _(EXCEPTION_BREAKPOINT),
+            _(EXCEPTION_INT_DIVIDE_BY_ZERO),
+            _(EXCEPTION_STACK_OVERFLOW),
+            // TODO: more?
+        #undef _
+        };
+
+        static LONG WINAPI handler(EXCEPTION_POINTERS* e) {
+            const DWORD code = e->ExceptionRecord->ExceptionCode;
+            SkDebugf("\nCaught exception %u", code);
+            for (size_t i = 0; i < SK_ARRAY_COUNT(kExceptions); i++) {
+                if (kExceptions[i].code == code) {
+                    SkDebugf(" %s", kExceptions[i].name);
+                }
+            }
+            SkDebugf("\n");
+
+            // We need to run SymInitialize before doing any of the stack walking below.
+            HANDLE hProcess = GetCurrentProcess();
+            SymInitialize(hProcess, 0, true);
+
+            STACKFRAME64 frame;
+            sk_bzero(&frame, sizeof(frame));
+            // Start frame off from the frame that triggered the exception.
+            CONTEXT* c = e->ContextRecord;
+            frame.AddrPC.Mode      = AddrModeFlat;
+            frame.AddrStack.Mode   = AddrModeFlat;
+            frame.AddrFrame.Mode   = AddrModeFlat;
+        #if defined(_X86_)
+            frame.AddrPC.Offset    = c->Eip;
+            frame.AddrStack.Offset = c->Esp;
+            frame.AddrFrame.Offset = c->Ebp;
+            const DWORD machineType = IMAGE_FILE_MACHINE_I386;
+        #elif defined(_AMD64_)
+            frame.AddrPC.Offset    = c->Rip;
+            frame.AddrStack.Offset = c->Rsp;
+            frame.AddrFrame.Offset = c->Rbp;
+            const DWORD machineType = IMAGE_FILE_MACHINE_AMD64;
+        #endif
+
+            while (StackWalk64(machineType,
+                               GetCurrentProcess(),
+                               GetCurrentThread(),
+                               &frame,
+                               c,
+                               NULL,
+                               SymFunctionTableAccess64,
+                               SymGetModuleBase64,
+                               NULL)) {
+                // Buffer to store symbol name in.
+                static const int kMaxNameLength = 1024;
+                uint8_t buffer[sizeof(IMAGEHLP_SYMBOL64) + kMaxNameLength];
+                sk_bzero(buffer, sizeof(buffer));
+
+                // We have to place IMAGEHLP_SYMBOL64 at the front, and fill in
+                // how much space it can use.
+                IMAGEHLP_SYMBOL64* symbol = reinterpret_cast<IMAGEHLP_SYMBOL64*>(&buffer);
+                symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+                symbol->MaxNameLength = kMaxNameLength - 1;
+
+                // Translate the current PC into a symbol and byte offset from the symbol.
+                DWORD64 offset;
+                SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offset, symbol);
+
+                SkDebugf("%s +%x\n", symbol->Name, offset);
+            }
+
+            // Exit NOW.  Don't notify other threads, don't call anything registered with atexit().
+            _exit(1);
+
+            // The compiler wants us to return something.  This is what we'd do
+            // if we didn't _exit().
+            return EXCEPTION_EXECUTE_HANDLER;
+        }
+
+        void SetupCrashHandler() {
+            SetUnhandledExceptionFilter(handler);
+        }
+
+    #else  // We asked for SK_CRASH_HANDLER, but it's not Mac, Linux, or Windows.  Sorry!
+
+        void SetupCrashHandler() { }
+
+    #endif
+#endif // SK_CRASH_HANDLER
diff --git a/tools/CrashHandler.h b/tools/CrashHandler.h
index 6c22c8e..606e81e 100644
--- a/tools/CrashHandler.h
+++ b/tools/CrashHandler.h
@@ -1,9 +1,11 @@
 #ifndef CrashHandler_DEFINED
 #define CrashHandler_DEFINED
 
-// If possible (and not already done) register a handler for a stack trace when we crash.
-// Currently this works on Linux and Mac, hopefully Windows soon.
-// On Linux, you will get much better results than we can deliver by running "catchsegv <program>".
+// If possible (and not already done), and SK_CRASH_HANDLER is defined,
+// register a handler for a stack trace when we crash.
+//
+// Currently this works on Linux and Mac and Windows, but on Linux, you will
+// get much better results than we can deliver by running "catchsegv <program>".
 void SetupCrashHandler();
 
 #endif//CrashHandler_DEFINED
diff --git a/tools/DumpRecord.cpp b/tools/DumpRecord.cpp
index 2376fb9..c505123 100644
--- a/tools/DumpRecord.cpp
+++ b/tools/DumpRecord.cpp
@@ -10,8 +10,8 @@
 #include "SkRecord.h"
 #include "SkRecordDraw.h"
 
-#include "BenchTimer.h"
 #include "DumpRecord.h"
+#include "Timer.h"
 
 namespace {
 
@@ -20,6 +20,7 @@
     explicit Dumper(SkCanvas* canvas, int count, bool timeWithCommand)
         : fDigits(0)
         , fIndent(0)
+        , fIndex(0)
         , fDraw(canvas)
         , fTimeWithCommand(timeWithCommand) {
         while (count > 0) {
@@ -28,12 +29,9 @@
         }
     }
 
-    unsigned index() const { return fDraw.index(); }
-    void next() { fDraw.next(); }
-
     template <typename T>
     void operator()(const T& command) {
-        BenchTimer timer;
+        Timer timer;
         timer.start();
             fDraw(command);
         timer.end();
@@ -71,7 +69,7 @@
         if (!fTimeWithCommand) {
             printf("%6.1f ", time * 1000);
         }
-        printf("%*d ", fDigits, fDraw.index());
+        printf("%*d ", fDigits, fIndex++);
         for (int i = 0; i < fIndent; i++) {
             putchar('\t');
         }
@@ -96,6 +94,7 @@
 
     int fDigits;
     int fIndent;
+    int fIndex;
     SkRecords::Draw fDraw;
     const bool fTimeWithCommand;
 };
@@ -105,9 +104,8 @@
 void DumpRecord(const SkRecord& record,
                   SkCanvas* canvas,
                   bool timeWithCommand) {
-    for (Dumper dumper(canvas, record.count(), timeWithCommand);
-         dumper.index() < record.count();
-         dumper.next()) {
-        record.visit<void>(dumper.index(), dumper);
+    Dumper dumper(canvas, record.count(), timeWithCommand);
+    for (unsigned i = 0; i < record.count(); i++) {
+        record.visit<void>(i, dumper);
     }
 }
diff --git a/tools/LazyDecodeBitmap.cpp b/tools/LazyDecodeBitmap.cpp
index 6c4160c..ec275ea 100644
--- a/tools/LazyDecodeBitmap.cpp
+++ b/tools/LazyDecodeBitmap.cpp
@@ -22,7 +22,7 @@
             "implementation.");
 
 //  Fits SkPicture::InstallPixelRefProc call signature.
-//  Used in SkPicturePlayback::CreateFromStream
+//  Used in SkPictureData::CreateFromStream
 bool sk_tools::LazyDecodeBitmap(const void* src,
                                 size_t length,
                                 SkBitmap* dst) {
@@ -39,7 +39,7 @@
         return false;
     }
     SkDiscardableMemory::Factory* pool = NULL;
-    if ((!FLAGS_useVolatileCache) || (info.fWidth * info.fHeight < 32 * 1024)) {
+    if ((!FLAGS_useVolatileCache) || (info.width() * info.height() < 32 * 1024)) {
         // how to do switching with SkDiscardableMemory.
         pool = SkGetGlobalDiscardableMemoryPool();
         // Only meaningful if platform has a default discardable
diff --git a/tools/OverwriteLine.h b/tools/OverwriteLine.h
index b76c223..e8f0504 100644
--- a/tools/OverwriteLine.h
+++ b/tools/OverwriteLine.h
@@ -5,6 +5,8 @@
 static const char* kSkOverwriteLine =
 #ifdef SK_BUILD_FOR_WIN32
 "\r                                                                               \r"
+#elif defined(SK_BUILD_FOR_IOS)
+"\r"
 #else
 "\r\033[K"
 #endif
diff --git a/tools/PdfRenderer.cpp b/tools/PdfRenderer.cpp
deleted file mode 100644
index bcecf57..0000000
--- a/tools/PdfRenderer.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "PdfRenderer.h"
-#include "SkCanvas.h"
-#include "SkDevice.h"
-#include "SkPDFDevice.h"
-#include "SkPDFDocument.h"
-
-namespace sk_tools {
-
-void PdfRenderer::init(SkPicture* pict, SkWStream* stream) {
-    SkASSERT(NULL == fPicture);
-    SkASSERT(NULL == fCanvas.get());
-    if (fPicture != NULL || NULL != fCanvas.get()) {
-        return;
-    }
-
-    SkASSERT(pict != NULL);
-    if (NULL == pict) {
-        return;
-    }
-
-    fPicture = pict;
-    fCanvas.reset(this->setupCanvas(stream, pict->width(), pict->height()));
-}
-
-SkCanvas* PdfRenderer::setupCanvas(SkWStream* stream, int width, int height) {
-    fPdfDoc.reset(SkDocument::CreatePDF(stream, NULL, fEncoder));
-
-    SkCanvas* canvas = fPdfDoc->beginPage(SkIntToScalar(width), SkIntToScalar(height));
-    canvas->ref();
-
-    return canvas;
-}
-
-void PdfRenderer::end() {
-    fPicture = NULL;
-    fCanvas.reset(NULL);
-    fPdfDoc.reset(NULL);
-}
-
-bool SimplePdfRenderer::render() {
-    SkASSERT(fCanvas.get() != NULL);
-    SkASSERT(fPicture != NULL);
-    if (NULL == fCanvas.get() || NULL == fPicture) {
-        return false;
-    }
-
-    fCanvas->drawPicture(fPicture);
-    fCanvas->flush();
-
-    return fPdfDoc->close();
-}
-
-}
diff --git a/tools/PdfRenderer.h b/tools/PdfRenderer.h
deleted file mode 100644
index d70c458..0000000
--- a/tools/PdfRenderer.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef PdfRenderer_DEFINED
-#define PdfRenderer_DEFINED
-
-//
-// PdfRender takes a SkPicture and writes it to a PDF file.
-// An SkPicture can be built manually, or read from an SKP file.
-//
-
-#include "SkDocument.h"
-#include "SkMath.h"
-#include "SkPicture.h"
-#include "SkTypes.h"
-#include "SkTDArray.h"
-#include "SkRefCnt.h"
-#include "SkString.h"
-
-class SkBitmap;
-class SkCanvas;
-class SkWStream;
-
-namespace sk_tools {
-
-class PdfRenderer : public SkRefCnt {
-public:
-    virtual void init(SkPicture* pict, SkWStream* stream);
-    virtual void setup() {}
-    virtual bool render() = 0;
-    virtual void end();
-
-    PdfRenderer(SkPicture::EncodeBitmap encoder)
-        : fPicture(NULL)
-        , fEncoder(encoder)
-        , fPdfDoc(NULL)
-        {}
-
-protected:
-    SkCanvas* setupCanvas(SkWStream* stream, int width, int height);
-
-    SkAutoTUnref<SkCanvas> fCanvas;
-    SkPicture* fPicture;
-    SkPicture::EncodeBitmap fEncoder;
-    SkAutoTUnref<SkDocument> fPdfDoc;
-
-private:
-    typedef SkRefCnt INHERITED;
-};
-
-class SimplePdfRenderer : public PdfRenderer {
-public:
-    SimplePdfRenderer(SkPicture::EncodeBitmap encoder)
-        : PdfRenderer(encoder) {}
-    virtual bool render() SK_OVERRIDE;
-
-private:
-    typedef PdfRenderer INHERITED;
-};
-
-}
-
-#endif  // PdfRenderer_DEFINED
diff --git a/tools/PictureBenchmark.cpp b/tools/PictureBenchmark.cpp
index 30967c7..15b6173 100644
--- a/tools/PictureBenchmark.cpp
+++ b/tools/PictureBenchmark.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "BenchTimer.h"
+#include "Timer.h"
 #include "PictureBenchmark.h"
 #include "SkCanvas.h"
 #include "SkPicture.h"
@@ -42,13 +42,13 @@
     fTimerTypes |= gpu ? TimerData::kGpu_Flag : 0;
 }
 
-BenchTimer* PictureBenchmark::setupTimer(bool useGLTimer) {
+Timer* PictureBenchmark::setupTimer(bool useGLTimer) {
 #if SK_SUPPORT_GPU
     if (useGLTimer && fRenderer != NULL && fRenderer->isUsingGpuDevice()) {
-        return SkNEW_ARGS(BenchTimer, (fRenderer->getGLContext()));
+        return SkNEW_ARGS(Timer, (fRenderer->getGLContext()));
     }
 #endif
-    return SkNEW_ARGS(BenchTimer, (NULL));
+    return SkNEW_ARGS(Timer, (NULL));
 }
 
 PictureRenderer* PictureBenchmark::setRenderer(sk_tools::PictureRenderer* renderer) {
@@ -73,20 +73,14 @@
     fRenderer->setup();
 
     if (fPreprocess) {
-        if (NULL != fRenderer->getCanvas()) {
-            fRenderer->getCanvas()->EXPERIMENTAL_optimize(pict);
+        if (fRenderer->getCanvas()) {
+            fRenderer->getCanvas()->EXPERIMENTAL_optimize(fRenderer->getPicture());
         }
     }
 
     fRenderer->render(NULL);
     fRenderer->resetState(true);   // flush, swapBuffers and Finish
 
-    if (fPreprocess) {
-        if (NULL != fRenderer->getCanvas()) {
-            fRenderer->getCanvas()->EXPERIMENTAL_purge(pict);
-        }
-    }
-
     if (fPurgeDecodedTex) {
         fRenderer->purgeTextures();
     }
@@ -147,11 +141,11 @@
             // seems to cause problems (i.e., INVALID_OPERATIONs) on several
             // platforms. To work around this, we disable the gpu timer on the
             // long running timer.
-            SkAutoTDelete<BenchTimer> longRunningTimer(this->setupTimer());
+            SkAutoTDelete<Timer> longRunningTimer(this->setupTimer());
             TimerData longRunningTimerData(numOuterLoops);
 
             for (int outer = 0; outer < numOuterLoops; ++outer) {
-                SkAutoTDelete<BenchTimer> perTileTimer(this->setupTimer(false));
+                SkAutoTDelete<Timer> perTileTimer(this->setupTimer(false));
                 TimerData perTileTimerData(numInnerLoops);
 
                 longRunningTimer->start();
@@ -173,7 +167,7 @@
                 SkAssertResult(longRunningTimerData.appendTimes(longRunningTimer.get()));
             }
 
-            fWriter->tileConfig(tiledRenderer->getConfigName());
+            fWriter->logRenderer(tiledRenderer);
             fWriter->tileMeta(x, y, xTiles, yTiles);
 
             // TODO(borenet): Turn off per-iteration tile time reporting for now.
@@ -201,11 +195,11 @@
                 numInnerLoops);
         }
     } else {
-        SkAutoTDelete<BenchTimer> longRunningTimer(this->setupTimer());
+        SkAutoTDelete<Timer> longRunningTimer(this->setupTimer());
         TimerData longRunningTimerData(numOuterLoops);
 
         for (int outer = 0; outer < numOuterLoops; ++outer) {
-            SkAutoTDelete<BenchTimer> perRunTimer(this->setupTimer(false));
+            SkAutoTDelete<Timer> perRunTimer(this->setupTimer(false));
             TimerData perRunTimerData(numInnerLoops);
 
             longRunningTimer->start();
@@ -220,12 +214,6 @@
 
                 SkAssertResult(perRunTimerData.appendTimes(perRunTimer.get()));
 
-                if (fPreprocess) {
-                    if (NULL != fRenderer->getCanvas()) {
-                        fRenderer->getCanvas()->EXPERIMENTAL_purge(pict);
-                    }
-                }
-
                 if (fPurgeDecodedTex) {
                     fRenderer->purgeTextures();
                 }
@@ -236,7 +224,7 @@
             SkAssertResult(longRunningTimerData.appendTimes(longRunningTimer.get()));
         }
 
-        fWriter->tileConfig(fRenderer->getConfigName());
+        fWriter->logRenderer(fRenderer);
         if (fPurgeDecodedTex) {
             fWriter->addTileFlag(PictureResultsWriter::kPurging);
         }
diff --git a/tools/PictureBenchmark.h b/tools/PictureBenchmark.h
index 142d526..2b1ccb5 100644
--- a/tools/PictureBenchmark.h
+++ b/tools/PictureBenchmark.h
@@ -13,8 +13,8 @@
 #include "SkTypes.h"
 #include "TimerData.h"
 
-class BenchTimer;
 class SkPicture;
+class Timer;
 
 namespace sk_tools {
 
@@ -49,6 +49,7 @@
     bool preprocess() const { return fPreprocess; }
 
     PictureRenderer* setRenderer(PictureRenderer*);
+    PictureRenderer* renderer() { return fRenderer; }
 
     void setTimerResultType(TimerData::Result resultType) { fTimerResult = resultType; }
 
@@ -67,7 +68,7 @@
 
     PictureResultsWriter* fWriter;
 
-    BenchTimer* setupTimer(bool useGLTimer = true);
+    Timer* setupTimer(bool useGLTimer = true);
 };
 
 }
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index d337a5e..705849d 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -48,8 +48,11 @@
     kDefaultTileHeight = 256
 };
 
-void PictureRenderer::init(SkPicture* pict, const SkString* writePath, const SkString* mismatchPath,
-                           const SkString* inputFilename, bool useChecksumBasedFilenames) {
+void PictureRenderer::init(const SkPicture* pict,
+                           const SkString* writePath,
+                           const SkString* mismatchPath,
+                           const SkString* inputFilename,
+                           bool useChecksumBasedFilenames) {
     this->CopyString(&fWritePath, writePath);
     this->CopyString(&fMismatchPath, mismatchPath);
     this->CopyString(&fInputFilename, inputFilename);
@@ -57,7 +60,7 @@
 
     SkASSERT(NULL == fPicture);
     SkASSERT(NULL == fCanvas.get());
-    if (NULL != fPicture || NULL != fCanvas.get()) {
+    if (fPicture || fCanvas.get()) {
         return;
     }
 
@@ -71,7 +74,7 @@
 }
 
 void PictureRenderer::CopyString(SkString* dest, const SkString* src) {
-    if (NULL != src) {
+    if (src) {
         dest->set(*src);
     } else {
         dest->reset();
@@ -87,7 +90,7 @@
         paint->setFlags(paint->getFlags() & ~fFlags[t] & SkPaint::kAllFlags);
         if (PictureRenderer::kMaskFilter_DrawFilterFlag & fFlags[t]) {
             SkMaskFilter* maskFilter = paint->getMaskFilter();
-            if (NULL != maskFilter) {
+            if (maskFilter) {
                 paint->setMaskFilter(NULL);
             }
         }
@@ -154,7 +157,8 @@
                 return NULL;
             }
 
-            SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target));
+            SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target,
+                                         SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType)));
             canvas = SkNEW_ARGS(SkCanvas, (device.get()));
             break;
         }
@@ -188,7 +192,7 @@
 
 int PictureRenderer::getViewWidth() {
     SkASSERT(fPicture != NULL);
-    int width = SkScalarCeilToInt(fPicture->width() * fScaleFactor);
+    int width = SkScalarCeilToInt(fPicture->cullRect().width() * fScaleFactor);
     if (fViewport.width() > 0) {
         width = SkMin32(width, fViewport.width());
     }
@@ -197,7 +201,7 @@
 
 int PictureRenderer::getViewHeight() {
     SkASSERT(fPicture != NULL);
-    int height = SkScalarCeilToInt(fPicture->height() * fScaleFactor);
+    int height = SkScalarCeilToInt(fPicture->cullRect().height() * fScaleFactor);
     if (fViewport.height() > 0) {
         height = SkMin32(height, fViewport.height());
     }
@@ -209,14 +213,15 @@
  *  should call this method during init.
  */
 void PictureRenderer::buildBBoxHierarchy() {
-    SkASSERT(NULL != fPicture);
-    if (kNone_BBoxHierarchyType != fBBoxHierarchyType && NULL != fPicture) {
+    SkASSERT(fPicture);
+    if (kNone_BBoxHierarchyType != fBBoxHierarchyType && fPicture) {
         SkAutoTDelete<SkBBHFactory> factory(this->getFactory());
         SkPictureRecorder recorder;
-        SkCanvas* canvas = recorder.beginRecording(fPicture->width(), fPicture->height(),
+        SkCanvas* canvas = recorder.beginRecording(fPicture->cullRect().width(), 
+                                                   fPicture->cullRect().height(),
                                                    factory.get(),
                                                    this->recordFlags());
-        fPicture->draw(canvas);
+        fPicture->playback(canvas);
         fPicture.reset(recorder.endRecording());
     }
 }
@@ -294,22 +299,22 @@
     SkString outputFilename;
     const char *outputSubdirPtr = NULL;
     if (useChecksumBasedFilenames) {
-        const ImageDigest *imageDigestPtr = bitmapAndDigest.getImageDigestPtr();
+        ImageDigest *imageDigestPtr = bitmapAndDigest.getImageDigestPtr();
         outputSubdirPtr = escapedInputFilename.c_str();
         outputFilename.set(imageDigestPtr->getHashType());
         outputFilename.append("_");
         outputFilename.appendU64(imageDigestPtr->getHashValue());
     } else {
         outputFilename.set(escapedInputFilename);
-        if (NULL != tileNumberPtr) {
+        if (tileNumberPtr) {
             outputFilename.append("-tile");
             outputFilename.appendS32(*tileNumberPtr);
         }
     }
     outputFilename.append(".png");
 
-    if (NULL != jsonSummaryPtr) {
-        const ImageDigest *imageDigestPtr = bitmapAndDigest.getImageDigestPtr();
+    if (jsonSummaryPtr) {
+        ImageDigest *imageDigestPtr = bitmapAndDigest.getImageDigestPtr();
         SkString outputRelativePath;
         if (outputSubdirPtr) {
             outputRelativePath.set(outputSubdirPtr);
@@ -322,8 +327,8 @@
         jsonSummaryPtr->add(inputFilename.c_str(), outputRelativePath.c_str(),
                             *imageDigestPtr, tileNumberPtr);
         if (!mismatchPath.isEmpty() &&
-            !jsonSummaryPtr->matchesExpectation(inputFilename.c_str(), *imageDigestPtr,
-                                                tileNumberPtr)) {
+            !jsonSummaryPtr->getExpectation(inputFilename.c_str(),
+                                            tileNumberPtr).matches(*imageDigestPtr)) {
             if (!write_bitmap_to_disk(bitmap, mismatchPath, outputSubdirPtr, outputFilename)) {
                 return false;
             }
@@ -352,15 +357,16 @@
 bool RecordPictureRenderer::render(SkBitmap** out) {
     SkAutoTDelete<SkBBHFactory> factory(this->getFactory());
     SkPictureRecorder recorder;
-    SkCanvas* canvas = recorder.beginRecording(this->getViewWidth(), this->getViewHeight(),
+    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(this->getViewWidth()), 
+                                               SkIntToScalar(this->getViewHeight()),
                                                factory.get(),
                                                this->recordFlags());
     this->scaleToScaleFactor(canvas);
-    fPicture->draw(canvas);
+    fPicture->playback(canvas);
     SkAutoTUnref<SkPicture> picture(recorder.endRecording());
     if (!fWritePath.isEmpty()) {
         // Record the new picture as a new SKP with PNG encoded bitmaps.
-        SkString skpPath = SkOSPath::SkPathJoin(fWritePath.c_str(), fInputFilename.c_str());
+        SkString skpPath = SkOSPath::Join(fWritePath.c_str(), fInputFilename.c_str());
         SkFILEWStream stream(skpPath.c_str());
         picture->serialize(&stream, &encode_bitmap_to_data);
         return true;
@@ -387,9 +393,10 @@
     pipeCanvas->drawPicture(fPicture);
     writer.endRecording();
     fCanvas->flush();
-    if (NULL != out) {
+    if (out) {
         *out = SkNEW(SkBitmap);
-        setup_bitmap(*out, fPicture->width(), fPicture->height());
+        setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), 
+                           SkScalarCeilToInt(fPicture->cullRect().height()));
         fCanvas->readPixels(*out, 0, 0);
     }
     if (fEnableWrites) {
@@ -406,7 +413,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-void SimplePictureRenderer::init(SkPicture* picture, const SkString* writePath,
+void SimplePictureRenderer::init(const SkPicture* picture, const SkString* writePath,
                                  const SkString* mismatchPath, const SkString* inputFilename,
                                  bool useChecksumBasedFilenames) {
     INHERITED::init(picture, writePath, mismatchPath, inputFilename, useChecksumBasedFilenames);
@@ -415,16 +422,17 @@
 
 bool SimplePictureRenderer::render(SkBitmap** out) {
     SkASSERT(fCanvas.get() != NULL);
-    SkASSERT(NULL != fPicture);
+    SkASSERT(fPicture);
     if (NULL == fCanvas.get() || NULL == fPicture) {
         return false;
     }
 
     fCanvas->drawPicture(fPicture);
     fCanvas->flush();
-    if (NULL != out) {
+    if (out) {
         *out = SkNEW(SkBitmap);
-        setup_bitmap(*out, fPicture->width(), fPicture->height());
+        setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), 
+                           SkScalarCeilToInt(fPicture->cullRect().height()));
         fCanvas->readPixels(*out, 0, 0);
     }
     if (fEnableWrites) {
@@ -441,8 +449,14 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
+#if SK_SUPPORT_GPU
+TiledPictureRenderer::TiledPictureRenderer(const GrContext::Options& opts)
+    : INHERITED(opts)
+    , fTileWidth(kDefaultTileWidth)
+#else
 TiledPictureRenderer::TiledPictureRenderer()
     : fTileWidth(kDefaultTileWidth)
+#endif
     , fTileHeight(kDefaultTileHeight)
     , fTileWidthPercentage(0.0)
     , fTileHeightPercentage(0.0)
@@ -451,10 +465,10 @@
     , fTilesX(0)
     , fTilesY(0) { }
 
-void TiledPictureRenderer::init(SkPicture* pict, const SkString* writePath,
+void TiledPictureRenderer::init(const SkPicture* pict, const SkString* writePath,
                                 const SkString* mismatchPath, const SkString* inputFilename,
                                 bool useChecksumBasedFilenames) {
-    SkASSERT(NULL != pict);
+    SkASSERT(pict);
     SkASSERT(0 == fTileRects.count());
     if (NULL == pict || fTileRects.count() != 0) {
         return;
@@ -470,10 +484,10 @@
     this->buildBBoxHierarchy();
 
     if (fTileWidthPercentage > 0) {
-        fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100));
+        fTileWidth = SkScalarCeilToInt(float(fTileWidthPercentage * fPicture->cullRect().width() / 100));
     }
     if (fTileHeightPercentage > 0) {
-        fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture->height() / 100));
+        fTileHeight = SkScalarCeilToInt(float(fTileHeightPercentage * fPicture->cullRect().height() / 100));
     }
 
     if (fTileMinPowerOf2Width > 0) {
@@ -579,7 +593,9 @@
  * Saves and restores so that the initial clip and matrix return to their state before this function
  * is called.
  */
-static void draw_tile_to_canvas(SkCanvas* canvas, const SkRect& tileRect, SkPicture* picture) {
+static void draw_tile_to_canvas(SkCanvas* canvas,
+                                const SkRect& tileRect,
+                                const SkPicture* picture) {
     int saveCount = canvas->save();
     // Translate so that we draw the correct portion of the picture.
     // Perform a postTranslate so that the scaleFactor does not interfere with the positioning.
@@ -636,7 +652,8 @@
     SkBitmap bitmap;
     if (out){
         *out = SkNEW(SkBitmap);
-        setup_bitmap(*out, fPicture->width(), fPicture->height());
+        setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), 
+                           SkScalarCeilToInt(fPicture->cullRect().height()));
         setup_bitmap(&bitmap, fTileWidth, fTileHeight);
     }
     bool success = true;
@@ -646,7 +663,7 @@
             success &= write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr,
                              fUseChecksumBasedFilenames, &i);
         }
-        if (NULL != out) {
+        if (out) {
             if (fCanvas->readPixels(&bitmap, 0, 0)) {
                 // Add this tile to the entire bitmap.
                 bitmapCopyAtOffset(bitmap, *out, SkScalarFloorToInt(fTileRects[i].left()),
@@ -661,7 +678,7 @@
 
 SkCanvas* TiledPictureRenderer::setupCanvas(int width, int height) {
     SkCanvas* canvas = this->INHERITED::setupCanvas(width, height);
-    SkASSERT(NULL != fPicture);
+    SkASSERT(fPicture);
     // Clip the tile to an area that is completely inside both the SkPicture and the viewport. This
     // is mostly important for tiles on the right and bottom edges as they may go over this area and
     // the picture may have some commands that draw outside of this area and so should not actually
@@ -698,192 +715,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-// Holds all of the information needed to draw a set of tiles.
-class CloneData : public SkRunnable {
-
-public:
-    CloneData(SkPicture* clone, SkCanvas* canvas, SkTDArray<SkRect>& rects, int start, int end,
-              SkRunnable* done, ImageResultsAndExpectations* jsonSummaryPtr,
-              bool useChecksumBasedFilenames, bool enableWrites)
-        : fClone(clone)
-        , fCanvas(canvas)
-        , fEnableWrites(enableWrites)
-        , fRects(rects)
-        , fStart(start)
-        , fEnd(end)
-        , fSuccess(NULL)
-        , fDone(done)
-        , fJsonSummaryPtr(jsonSummaryPtr)
-        , fUseChecksumBasedFilenames(useChecksumBasedFilenames) {
-        SkASSERT(fDone != NULL);
-    }
-
-    virtual void run() SK_OVERRIDE {
-        SkGraphics::SetTLSFontCacheLimit(1024 * 1024);
-
-        SkBitmap bitmap;
-        if (fBitmap != NULL) {
-            // All tiles are the same size.
-            setup_bitmap(&bitmap, SkScalarFloorToInt(fRects[0].width()), SkScalarFloorToInt(fRects[0].height()));
-        }
-
-        for (int i = fStart; i < fEnd; i++) {
-            draw_tile_to_canvas(fCanvas, fRects[i], fClone);
-            if (fEnableWrites) {
-                if (!write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr,
-                           fUseChecksumBasedFilenames, &i)
-                    && fSuccess != NULL) {
-                    *fSuccess = false;
-                    // If one tile fails to write to a file, do not continue drawing the rest.
-                    break;
-                }
-                if (fBitmap != NULL) {
-                    if (fCanvas->readPixels(&bitmap, 0, 0)) {
-                        SkAutoLockPixels alp(*fBitmap);
-                        bitmapCopyAtOffset(bitmap, fBitmap, SkScalarFloorToInt(fRects[i].left()),
-                                           SkScalarFloorToInt(fRects[i].top()));
-                    } else {
-                        *fSuccess = false;
-                        // If one tile fails to read pixels, do not continue drawing the rest.
-                        break;
-                    }
-                }
-            }
-        }
-        fDone->run();
-    }
-
-    void setPathsAndSuccess(const SkString& writePath, const SkString& mismatchPath,
-                            const SkString& inputFilename, bool* success) {
-        fWritePath.set(writePath);
-        fMismatchPath.set(mismatchPath);
-        fInputFilename.set(inputFilename);
-        fSuccess = success;
-    }
-
-    void setBitmap(SkBitmap* bitmap) {
-        fBitmap = bitmap;
-    }
-
-private:
-    // All pointers unowned.
-    SkPicture*         fClone;      // Picture to draw from. Each CloneData has a unique one which
-                                    // is threadsafe.
-    SkCanvas*          fCanvas;     // Canvas to draw to. Reused for each tile.
-    bool               fEnableWrites; // TODO(epoger): Temporary hack; see declaration of
-                                      // fEnableWrites in PictureRenderer.h.
-    SkString           fWritePath;  // If not empty, write all results into this directory.
-    SkString           fMismatchPath;  // If not empty, write all unexpected results into this dir.
-    SkString           fInputFilename; // Filename of input SkPicture file.
-    SkTDArray<SkRect>& fRects;      // All tiles of the picture.
-    const int          fStart;      // Range of tiles drawn by this thread.
-    const int          fEnd;
-    bool*              fSuccess;    // Only meaningful if path is non-null. Shared by all threads,
-                                    // and only set to false upon failure to write to a PNG.
-    SkRunnable*        fDone;
-    SkBitmap*          fBitmap;
-    ImageResultsAndExpectations* fJsonSummaryPtr;
-    bool               fUseChecksumBasedFilenames;
-};
-
-MultiCorePictureRenderer::MultiCorePictureRenderer(int threadCount)
-: fNumThreads(threadCount)
-, fThreadPool(threadCount)
-, fCountdown(threadCount) {
-    // Only need to create fNumThreads - 1 clones, since one thread will use the base
-    // picture.
-    fPictureClones = SkNEW_ARRAY(SkPicture, fNumThreads - 1);
-    fCloneData = SkNEW_ARRAY(CloneData*, fNumThreads);
-}
-
-void MultiCorePictureRenderer::init(SkPicture *pict, const SkString* writePath,
-                                    const SkString* mismatchPath, const SkString* inputFilename,
-                                    bool useChecksumBasedFilenames) {
-    // Set fPicture and the tiles.
-    this->INHERITED::init(pict, writePath, mismatchPath, inputFilename, useChecksumBasedFilenames);
-    for (int i = 0; i < fNumThreads; ++i) {
-        *fCanvasPool.append() = this->setupCanvas(this->getTileWidth(), this->getTileHeight());
-    }
-    // Only need to create fNumThreads - 1 clones, since one thread will use the base picture.
-    fPicture->clone(fPictureClones, fNumThreads - 1);
-    // Populate each thread with the appropriate data.
-    // Group the tiles into nearly equal size chunks, rounding up so we're sure to cover them all.
-    const int chunkSize = (fTileRects.count() + fNumThreads - 1) / fNumThreads;
-
-    for (int i = 0; i < fNumThreads; i++) {
-        SkPicture* pic;
-        if (i == fNumThreads-1) {
-            // The last set will use the original SkPicture.
-            pic = fPicture;
-        } else {
-            pic = &fPictureClones[i];
-        }
-        const int start = i * chunkSize;
-        const int end = SkMin32(start + chunkSize, fTileRects.count());
-        fCloneData[i] = SkNEW_ARGS(CloneData,
-                                   (pic, fCanvasPool[i], fTileRects, start, end, &fCountdown,
-                                    fJsonSummaryPtr, useChecksumBasedFilenames, fEnableWrites));
-    }
-}
-
-bool MultiCorePictureRenderer::render(SkBitmap** out) {
-    bool success = true;
-    if (!fWritePath.isEmpty() || !fMismatchPath.isEmpty()) {
-        for (int i = 0; i < fNumThreads-1; i++) {
-            fCloneData[i]->setPathsAndSuccess(fWritePath, fMismatchPath, fInputFilename, &success);
-        }
-    }
-
-    if (NULL != out) {
-        *out = SkNEW(SkBitmap);
-        setup_bitmap(*out, fPicture->width(), fPicture->height());
-        for (int i = 0; i < fNumThreads; i++) {
-            fCloneData[i]->setBitmap(*out);
-        }
-    } else {
-        for (int i = 0; i < fNumThreads; i++) {
-            fCloneData[i]->setBitmap(NULL);
-        }
-    }
-
-    fCountdown.reset(fNumThreads);
-    for (int i = 0; i < fNumThreads; i++) {
-        fThreadPool.add(fCloneData[i]);
-    }
-    fCountdown.wait();
-
-    return success;
-}
-
-void MultiCorePictureRenderer::end() {
-    for (int i = 0; i < fNumThreads - 1; i++) {
-        SkDELETE(fCloneData[i]);
-        fCloneData[i] = NULL;
-    }
-
-    fCanvasPool.unrefAll();
-
-    this->INHERITED::end();
-}
-
-MultiCorePictureRenderer::~MultiCorePictureRenderer() {
-    // Each individual CloneData was deleted in end.
-    SkDELETE_ARRAY(fCloneData);
-    SkDELETE_ARRAY(fPictureClones);
-}
-
-SkString MultiCorePictureRenderer::getConfigNameInternal() {
-    SkString name = this->INHERITED::getConfigNameInternal();
-    name.appendf("_multi_%i_threads", fNumThreads);
-    return name;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
 void PlaybackCreationRenderer::setup() {
     SkAutoTDelete<SkBBHFactory> factory(this->getFactory());
     fRecorder.reset(SkNEW(SkPictureRecorder));
-    SkCanvas* canvas = fRecorder->beginRecording(this->getViewWidth(), this->getViewHeight(),
+    SkCanvas* canvas = fRecorder->beginRecording(SkIntToScalar(this->getViewWidth()), 
+                                                 SkIntToScalar(this->getViewHeight()),
                                                  factory.get(),
                                                  this->recordFlags());
     this->scaleToScaleFactor(canvas);
@@ -907,8 +743,6 @@
     switch (fBBoxHierarchyType) {
         case kNone_BBoxHierarchyType:
             return NULL;
-        case kQuadTree_BBoxHierarchyType:
-            return SkNEW(SkQuadTreeFactory);
         case kRTree_BBoxHierarchyType:
             return SkNEW(SkRTreeFactory);
         case kTileGrid_BBoxHierarchyType:
@@ -922,9 +756,13 @@
 
 class GatherRenderer : public PictureRenderer {
 public:
+#if SK_SUPPORT_GPU
+    GatherRenderer(const GrContext::Options& opts) : INHERITED(opts) { }
+#endif
+
     virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE {
-        SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
-                                       SkIntToScalar(fPicture->height()));
+        SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->cullRect().width()),
+                                       SkIntToScalar(fPicture->cullRect().height()));
         SkData* data = SkPictureUtils::GatherPixelRefs(fPicture, bounds);
         SkSafeUnref(data);
 
@@ -935,33 +773,18 @@
     virtual SkString getConfigNameInternal() SK_OVERRIDE {
         return SkString("gather_pixelrefs");
     }
+
+    typedef PictureRenderer INHERITED;
 };
 
+#if SK_SUPPORT_GPU
+PictureRenderer* CreateGatherPixelRefsRenderer(const GrContext::Options& opts) {
+    return SkNEW_ARGS(GatherRenderer, (opts));
+}
+#else
 PictureRenderer* CreateGatherPixelRefsRenderer() {
     return SkNEW(GatherRenderer);
 }
-
-///////////////////////////////////////////////////////////////////////////////
-
-class PictureCloneRenderer : public PictureRenderer {
-public:
-    virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE {
-        for (int i = 0; i < 100; ++i) {
-            SkPicture* clone = fPicture->clone();
-            SkSafeUnref(clone);
-        }
-
-        return (fWritePath.isEmpty());    // we don't have anything to write
-    }
-
-private:
-    virtual SkString getConfigNameInternal() SK_OVERRIDE {
-        return SkString("picture_clone");
-    }
-};
-
-PictureRenderer* CreatePictureCloneRenderer() {
-    return SkNEW(PictureCloneRenderer);
-}
+#endif
 
 } // namespace sk_tools
diff --git a/tools/PictureRenderer.h b/tools/PictureRenderer.h
index efe118f..04ac20f 100644
--- a/tools/PictureRenderer.h
+++ b/tools/PictureRenderer.h
@@ -9,18 +9,16 @@
 #define PictureRenderer_DEFINED
 
 #include "SkCanvas.h"
-#include "SkCountdown.h"
 #include "SkDrawFilter.h"
+#include "SkJSONCPP.h"
 #include "SkMath.h"
 #include "SkPaint.h"
 #include "SkPicture.h"
 #include "SkPictureRecorder.h"
 #include "SkRect.h"
 #include "SkRefCnt.h"
-#include "SkRunnable.h"
 #include "SkString.h"
 #include "SkTDArray.h"
-#include "SkThreadPool.h"
 #include "SkTypes.h"
 
 #if SK_SUPPORT_GPU
@@ -58,7 +56,6 @@
 
     enum BBoxHierarchyType {
         kNone_BBoxHierarchyType = 0,
-        kQuadTree_BBoxHierarchyType,
         kRTree_BBoxHierarchyType,
         kTileGrid_BBoxHierarchyType,
 
@@ -92,8 +89,11 @@
      * @param useChecksumBasedFilenames Whether to use checksum-based filenames when writing
      *     bitmap images to disk.
      */
-    virtual void init(SkPicture* pict, const SkString* writePath, const SkString* mismatchPath,
-                      const SkString* inputFilename, bool useChecksumBasedFilenames);
+    virtual void init(const SkPicture* pict,
+                      const SkString* writePath,
+                      const SkString* mismatchPath,
+                      const SkString* inputFilename,
+                      bool useChecksumBasedFilenames);
 
     /**
      * TODO(epoger): Temporary hack, while we work on http://skbug.com/2584 ('bench_pictures is
@@ -165,7 +165,11 @@
     /**
      * Set the backend type. Returns true on success and false on failure.
      */
+#if SK_SUPPORT_GPU
+    bool setDeviceType(SkDeviceTypes deviceType, GrGLStandard gpuAPI = kNone_GrGLStandard) {
+#else
     bool setDeviceType(SkDeviceTypes deviceType) {
+#endif
         fDeviceType = deviceType;
 #if SK_SUPPORT_GPU
         // In case this function is called more than once
@@ -200,7 +204,7 @@
                 return false;
         }
 #if SK_SUPPORT_GPU
-        fGrContext = fGrContextFactory.get(glContextType);
+        fGrContext = fGrContextFactory.get(glContextType, gpuAPI);
         if (NULL == fGrContext) {
             return false;
         } else {
@@ -256,8 +260,6 @@
         }
         if (kRTree_BBoxHierarchyType == fBBoxHierarchyType) {
             config.append("_rtree");
-        } else if (kQuadTree_BBoxHierarchyType == fBBoxHierarchyType) {
-            config.append("_quadtree");
         } else if (kTileGrid_BBoxHierarchyType == fBBoxHierarchyType) {
             config.append("_grid");
             config.append("_");
@@ -296,6 +298,58 @@
         return config;
     }
 
+    Json::Value getJSONConfig() {
+        Json::Value result;
+
+        result["mode"] = this->getConfigNameInternal().c_str();
+        result["scale"] = 1.0f;
+        if (SK_Scalar1 != fScaleFactor) {
+            result["scale"] = SkScalarToFloat(fScaleFactor);
+        }
+        if (kRTree_BBoxHierarchyType == fBBoxHierarchyType) {
+            result["bbh"] = "rtree";
+        } else if (kTileGrid_BBoxHierarchyType == fBBoxHierarchyType) {
+            SkString tmp("grid_");
+            tmp.appendS32(fGridInfo.fTileInterval.width());
+            tmp.append("x");
+            tmp.appendS32(fGridInfo.fTileInterval.height());
+            result["bbh"] = tmp.c_str();
+        }
+#if SK_SUPPORT_GPU
+        SkString tmp;
+        switch (fDeviceType) {
+            case kGPU_DeviceType:
+                if (0 != fSampleCount) {
+                    tmp = "msaa";
+                    tmp.appendS32(fSampleCount);
+                    result["config"] = tmp.c_str();
+                } else {
+                    result["config"] = "gpu";
+                }
+                break;
+            case kNVPR_DeviceType:
+                tmp = "nvprmsaa";
+                tmp.appendS32(fSampleCount);
+                result["config"] = tmp.c_str();
+                break;
+#if SK_ANGLE
+            case kAngle_DeviceType:
+                result["config"] = "angle";
+                break;
+#endif
+#if SK_MESA
+            case kMesa_DeviceType:
+                result["config"] = "mesa";
+                break;
+#endif
+            default:
+                // Assume that no extra info means bitmap.
+                break;
+        }
+#endif
+        return result;
+    }
+
 #if SK_SUPPORT_GPU
     bool isUsingGpuDevice() {
         switch (fDeviceType) {
@@ -344,23 +398,32 @@
     GrContext* getGrContext() {
         return fGrContext;
     }
+
+    const GrContext::Options& getGrContextOptions() {
+        return fGrContextFactory.getGlobalOptions();
+    }
 #endif
 
     SkCanvas* getCanvas() {
         return fCanvas;
     }
 
-    SkPicture* getPicture() {
+    const SkPicture* getPicture() {
         return fPicture;
     }
 
+#if SK_SUPPORT_GPU
+    explicit PictureRenderer(const GrContext::Options &opts)
+#else
     PictureRenderer()
+#endif
         : fJsonSummaryPtr(NULL)
         , fDeviceType(kBitmap_DeviceType)
         , fEnableWrites(false)
         , fBBoxHierarchyType(kNone_BBoxHierarchyType)
         , fScaleFactor(SK_Scalar1)
 #if SK_SUPPORT_GPU
+        , fGrContextFactory(opts)
         , fGrContext(NULL)
         , fSampleCount(0)
 #endif
@@ -380,7 +443,7 @@
 
 protected:
     SkAutoTUnref<SkCanvas> fCanvas;
-    SkAutoTUnref<SkPicture> fPicture;
+    SkAutoTUnref<const SkPicture> fPicture;
     bool                   fUseChecksumBasedFilenames;
     ImageResultsAndExpectations*   fJsonSummaryPtr;
     SkDeviceTypes          fDeviceType;
@@ -441,6 +504,11 @@
  * to time.
  */
 class RecordPictureRenderer : public PictureRenderer {
+public:
+#if SK_SUPPORT_GPU
+    RecordPictureRenderer(const GrContext::Options &opts) : INHERITED(opts) { }
+#endif
+
     virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE;
 
     virtual SkString getPerIterTimeFormat() SK_OVERRIDE { return SkString("%.4f"); }
@@ -452,10 +520,16 @@
 
 private:
     virtual SkString getConfigNameInternal() SK_OVERRIDE;
+
+    typedef PictureRenderer INHERITED;
 };
 
 class PipePictureRenderer : public PictureRenderer {
 public:
+#if SK_SUPPORT_GPU
+    PipePictureRenderer(const GrContext::Options &opts) : INHERITED(opts) { }
+#endif
+
     virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE;
 
 private:
@@ -466,8 +540,15 @@
 
 class SimplePictureRenderer : public PictureRenderer {
 public:
-    virtual void init(SkPicture* pict, const SkString* writePath, const SkString* mismatchPath,
-                      const SkString* inputFilename, bool useChecksumBasedFilenames) SK_OVERRIDE;
+#if SK_SUPPORT_GPU
+    SimplePictureRenderer(const GrContext::Options &opts) : INHERITED(opts) { }
+#endif
+
+    virtual void init(const SkPicture* pict,
+                      const SkString* writePath,
+                      const SkString* mismatchPath,
+                      const SkString* inputFilename,
+                      bool useChecksumBasedFilenames) SK_OVERRIDE;
 
     virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE;
 
@@ -479,16 +560,22 @@
 
 class TiledPictureRenderer : public PictureRenderer {
 public:
+#if SK_SUPPORT_GPU
+    TiledPictureRenderer(const GrContext::Options &opts);
+#else
     TiledPictureRenderer();
+#endif
 
-    virtual void init(SkPicture* pict, const SkString* writePath, const SkString* mismatchPath,
-                      const SkString* inputFilename, bool useChecksumBasedFilenames) SK_OVERRIDE;
+    virtual void init(const SkPicture* pict,
+                      const SkString* writePath,
+                      const SkString* mismatchPath,
+                      const SkString* inputFilename,
+                      bool useChecksumBasedFilenames) SK_OVERRIDE;
 
     /**
      * Renders to tiles, rather than a single canvas.
      * If fWritePath was provided, a separate file is
      * created for each tile, named "path0.png", "path1.png", etc.
-     * Multithreaded mode currently does not support writing to a file.
      */
     virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE;
 
@@ -598,45 +685,16 @@
     typedef PictureRenderer INHERITED;
 };
 
-class CloneData;
-
-class MultiCorePictureRenderer : public TiledPictureRenderer {
-public:
-    explicit MultiCorePictureRenderer(int threadCount);
-
-    ~MultiCorePictureRenderer();
-
-    virtual void init(SkPicture* pict, const SkString* writePath, const SkString* mismatchPath,
-                      const SkString* inputFilename, bool useChecksumBasedFilenames) SK_OVERRIDE;
-
-    /**
-     * Behaves like TiledPictureRenderer::render(), only using multiple threads.
-     */
-    virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE;
-
-    virtual void end() SK_OVERRIDE;
-
-    virtual bool supportsTimingIndividualTiles() SK_OVERRIDE { return false; }
-
-private:
-    virtual SkString getConfigNameInternal() SK_OVERRIDE;
-
-    const int            fNumThreads;
-    SkTDArray<SkCanvas*> fCanvasPool;
-    SkThreadPool         fThreadPool;
-    SkPicture*           fPictureClones;
-    CloneData**          fCloneData;
-    SkCountdown          fCountdown;
-
-    typedef TiledPictureRenderer INHERITED;
-};
-
 /**
  * This class does not do any rendering, but its render function executes turning an SkPictureRecord
  * into an SkPicturePlayback, which we want to time.
  */
 class PlaybackCreationRenderer : public PictureRenderer {
 public:
+#if SK_SUPPORT_GPU
+    PlaybackCreationRenderer(const GrContext::Options &opts) : INHERITED(opts) { }
+#endif
+
     virtual void setup() SK_OVERRIDE;
 
     virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE;
@@ -653,8 +711,11 @@
     typedef PictureRenderer INHERITED;
 };
 
+#if SK_SUPPORT_GPU
+extern PictureRenderer* CreateGatherPixelRefsRenderer(const GrContext::Options& opts);
+#else
 extern PictureRenderer* CreateGatherPixelRefsRenderer();
-extern PictureRenderer* CreatePictureCloneRenderer();
+#endif
 
 }
 
diff --git a/tools/PictureRenderingFlags.cpp b/tools/PictureRenderingFlags.cpp
index 5acec26..d78229a 100644
--- a/tools/PictureRenderingFlags.cpp
+++ b/tools/PictureRenderingFlags.cpp
@@ -18,7 +18,7 @@
 
 // Alphabetized list of flags used by this file or bench_ and render_pictures.
 DEFINE_string(bbh, "none", "bbhType [width height]: Set the bounding box hierarchy type to "
-              "be used. Accepted values are: none, rtree, quadtree, grid. "
+              "be used. Accepted values are: none, rtree, grid. "
               "Not compatible with --pipe. With value "
               "'grid', width and height must be specified. 'grid' can "
               "only be used with modes tile, record, and "
@@ -26,6 +26,8 @@
 
 
 #if SK_SUPPORT_GPU
+static const char kGpuAPINameGL[] = "gl";
+static const char kGpuAPINameGLES[] = "gles";
 #define GPU_CONFIG_STRING "|gpu|msaa4|msaa16|nvprmsaa4|nvprmsaa16"
 #else
 #define GPU_CONFIG_STRING ""
@@ -66,23 +68,24 @@
               "\tSkPicturePlayback.\n"
               "rerecord: (Only in render_pictures) Record the picture as a new skp,\n"
               "\twith the bitmaps PNG encoded.\n");
-DEFINE_int32(multi, 1, "Set the number of threads for multi threaded drawing. "
-             "If > 1, requires tiled rendering.");
 DEFINE_bool(pipe, false, "Use SkGPipe rendering. Currently incompatible with \"mode\".");
 DEFINE_string2(readPath, r, "", "skp files or directories of skp files to process.");
 DEFINE_double(scale, 1, "Set the scale factor.");
 DEFINE_string(tiles, "", "Used with --mode copyTile to specify number of tiles per larger tile "
               "in the x and y directions.");
 DEFINE_string(viewport, "", "width height: Set the viewport.");
+#if SK_SUPPORT_GPU
+DEFINE_string(gpuAPI, "", "Force use of specific gpu API.  Using \"gl\" "
+              "forces OpenGL API. Using \"gles\" forces OpenGL ES API. "
+              "Defaults to empty string, which selects the API native to the "
+              "system.");
+DEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to "
+                                          "software path rendering.");
+#endif
 
 sk_tools::PictureRenderer* parseRenderer(SkString& error, PictureTool tool) {
     error.reset();
 
-    if (FLAGS_multi <= 0) {
-        error.printf("--multi must be > 0, was %i", FLAGS_multi);
-        return NULL;
-    }
-
     bool useTiles = false;
     const char* widthString = NULL;
     const char* heightString = NULL;
@@ -91,15 +94,20 @@
     const char* mode = NULL;
     bool gridSupported = false;
 
+#if SK_SUPPORT_GPU
+    GrContext::Options grContextOpts;
+    grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks;
+  #define RENDERER_ARGS (grContextOpts)
+#else
+  #define RENDERER_ARGS ()
+#endif
+
     SkAutoTUnref<sk_tools::PictureRenderer> renderer;
     if (FLAGS_mode.count() >= 1) {
         mode = FLAGS_mode[0];
         if (0 == strcmp(mode, "record")) {
-            renderer.reset(SkNEW(sk_tools::RecordPictureRenderer));
+            renderer.reset(SkNEW_ARGS(sk_tools::RecordPictureRenderer, RENDERER_ARGS));
             gridSupported = true;
-        // undocumented
-        } else if (0 == strcmp(mode, "clone")) {
-            renderer.reset(sk_tools::CreatePictureCloneRenderer());
         } else if (0 == strcmp(mode, "tile") || 0 == strcmp(mode, "pow2tile")
                    || 0 == strcmp(mode, "copyTile")) {
             useTiles = true;
@@ -125,13 +133,17 @@
 
             heightString = FLAGS_mode[2];
         } else if (0 == strcmp(mode, "playbackCreation") && kBench_PictureTool == tool) {
-            renderer.reset(SkNEW(sk_tools::PlaybackCreationRenderer));
+            renderer.reset(SkNEW_ARGS(sk_tools::PlaybackCreationRenderer, RENDERER_ARGS));
             gridSupported = true;
         // undocumented
         } else if (0 == strcmp(mode, "gatherPixelRefs") && kBench_PictureTool == tool) {
+#if SK_SUPPORT_GPU
+            renderer.reset(sk_tools::CreateGatherPixelRefsRenderer(grContextOpts));
+#else
             renderer.reset(sk_tools::CreateGatherPixelRefsRenderer());
+#endif
         } else if (0 == strcmp(mode, "rerecord") && kRender_PictureTool == tool) {
-            renderer.reset(SkNEW(sk_tools::RecordPictureRenderer));
+            renderer.reset(SkNEW_ARGS(sk_tools::RecordPictureRenderer, RENDERER_ARGS));
         // Allow 'mode' to be set to 'simple', but do not create a renderer, so we can
         // ensure that pipe does not override a mode besides simple. The renderer will
         // be created below.
@@ -169,12 +181,13 @@
             } else {
                 x = y = 4;
             }
+#if SK_SUPPORT_GPU
+            tiledRenderer.reset(SkNEW_ARGS(sk_tools::CopyTilesRenderer, (grContextOpts, x, y)));
+#else
             tiledRenderer.reset(SkNEW_ARGS(sk_tools::CopyTilesRenderer, (x, y)));
-        } else if (FLAGS_multi > 1) {
-            tiledRenderer.reset(SkNEW_ARGS(sk_tools::MultiCorePictureRenderer,
-                                           (FLAGS_multi)));
+#endif
         } else {
-            tiledRenderer.reset(SkNEW(sk_tools::TiledPictureRenderer));
+            tiledRenderer.reset(SkNEW_ARGS(sk_tools::TiledPictureRenderer, RENDERER_ARGS));
         }
 
         if (isPowerOf2Mode) {
@@ -230,21 +243,17 @@
         }
 
     } else { // useTiles
-        if (FLAGS_multi > 1) {
-            error.printf("Multithreaded drawing requires tiled rendering.\n");
-            return NULL;
-        }
         if (FLAGS_pipe) {
             if (renderer != NULL) {
                 error.printf("Pipe is incompatible with other modes.\n");
                 return NULL;
             }
-            renderer.reset(SkNEW(sk_tools::PipePictureRenderer));
+            renderer.reset(SkNEW_ARGS(sk_tools::PipePictureRenderer, RENDERER_ARGS));
         }
     }
 
     if (NULL == renderer) {
-        renderer.reset(SkNEW(sk_tools::SimplePictureRenderer));
+        renderer.reset(SkNEW_ARGS(sk_tools::SimplePictureRenderer, RENDERER_ARGS));
     }
 
     if (FLAGS_viewport.count() > 0) {
@@ -261,6 +270,21 @@
     sk_tools::PictureRenderer::SkDeviceTypes deviceType =
         sk_tools::PictureRenderer::kBitmap_DeviceType;
 #if SK_SUPPORT_GPU
+    GrGLStandard gpuAPI = kNone_GrGLStandard;
+    if (1 == FLAGS_gpuAPI.count()) {
+        if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
+            gpuAPI = kGL_GrGLStandard;
+        } else if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
+            gpuAPI = kGLES_GrGLStandard;
+        } else {
+            error.printf("--gpuAPI invalid api value.\n");
+            return NULL;
+        }
+    } else if (FLAGS_gpuAPI.count() > 1) {
+        error.printf("--gpuAPI invalid api value.\n");
+        return NULL;
+    }
+
     int sampleCount = 0;
 #endif
     if (FLAGS_config.count() > 0) {
@@ -270,59 +294,31 @@
 #if SK_SUPPORT_GPU
         else if (0 == strcmp(FLAGS_config[0], "gpu")) {
             deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
-            if (FLAGS_multi > 1) {
-                error.printf("GPU not compatible with multithreaded tiling.\n");
-                return NULL;
-            }
         }
         else if (0 == strcmp(FLAGS_config[0], "msaa4")) {
             deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
-            if (FLAGS_multi > 1) {
-                error.printf("GPU not compatible with multithreaded tiling.\n");
-                return NULL;
-            }
             sampleCount = 4;
         }
         else if (0 == strcmp(FLAGS_config[0], "msaa16")) {
             deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
-            if (FLAGS_multi > 1) {
-                error.printf("GPU not compatible with multithreaded tiling.\n");
-                return NULL;
-            }
             sampleCount = 16;
         }
         else if (0 == strcmp(FLAGS_config[0], "nvprmsaa4")) {
             deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType;
-            if (FLAGS_multi > 1) {
-                error.printf("GPU not compatible with multithreaded tiling.\n");
-                return NULL;
-            }
             sampleCount = 4;
         }
         else if (0 == strcmp(FLAGS_config[0], "nvprmsaa16")) {
             deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType;
-            if (FLAGS_multi > 1) {
-                error.printf("GPU not compatible with multithreaded tiling.\n");
-                return NULL;
-            }
             sampleCount = 16;
         }
 #if SK_ANGLE
         else if (0 == strcmp(FLAGS_config[0], "angle")) {
             deviceType = sk_tools::PictureRenderer::kAngle_DeviceType;
-            if (FLAGS_multi > 1) {
-                error.printf("Angle not compatible with multithreaded tiling.\n");
-                return NULL;
-            }
         }
 #endif
 #if SK_MESA
         else if (0 == strcmp(FLAGS_config[0], "mesa")) {
             deviceType = sk_tools::PictureRenderer::kMesa_DeviceType;
-            if (FLAGS_multi > 1) {
-                error.printf("Mesa not compatible with multithreaded tiling.\n");
-                return NULL;
-            }
         }
 #endif
 #endif
@@ -330,7 +326,14 @@
             error.printf("%s is not a valid mode for --config\n", FLAGS_config[0]);
             return NULL;
         }
-        renderer->setDeviceType(deviceType);
+#if SK_SUPPORT_GPU
+        if (!renderer->setDeviceType(deviceType, gpuAPI)) {
+#else
+        if (!renderer->setDeviceType(deviceType)) {
+#endif
+            error.printf("Could not create backend for --config %s\n", FLAGS_config[0]);
+            return NULL;
+        }
 #if SK_SUPPORT_GPU
         renderer->setSampleCount(sampleCount);
 #endif
@@ -343,8 +346,6 @@
         const char* type = FLAGS_bbh[0];
         if (0 == strcmp(type, "none")) {
             bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
-        } else if (0 == strcmp(type, "quadtree")) {
-            bbhType = sk_tools::PictureRenderer::kQuadTree_BBoxHierarchyType;
         } else if (0 == strcmp(type, "rtree")) {
             bbhType = sk_tools::PictureRenderer::kRTree_BBoxHierarchyType;
         } else if (0 == strcmp(type, "grid")) {
diff --git a/tools/PictureResultsWriter.h b/tools/PictureResultsWriter.h
index d4a1576..9ef1666 100644
--- a/tools/PictureResultsWriter.h
+++ b/tools/PictureResultsWriter.h
@@ -10,6 +10,8 @@
 #ifndef SkPictureResultsWriter_DEFINED
 #define SkPictureResultsWriter_DEFINED
 
+
+#include "PictureRenderer.h"
 #include "BenchLogger.h"
 #include "ResultsWriter.h"
 #include "SkJSONCPP.h"
@@ -29,7 +31,7 @@
     virtual ~PictureResultsWriter() {}
 
     virtual void bench(const char name[], int32_t x, int32_t y) = 0;
-    virtual void tileConfig(SkString configName) = 0;
+    virtual void logRenderer(sk_tools::PictureRenderer *pr) = 0;
     virtual void tileMeta(int x, int y, int tx, int ty) = 0;
     virtual void addTileFlag(PictureResultsWriter::TileFlags flag) = 0;
     virtual void tileData(
@@ -54,22 +56,22 @@
         fWriters.push_back(newWriter);
     }
     virtual ~PictureResultsMultiWriter() {}
-    virtual void bench(const char name[], int32_t x, int32_t y) {
+    virtual void bench(const char name[], int32_t x, int32_t y) SK_OVERRIDE {
         for(int i=0; i<fWriters.count(); ++i) {
             fWriters[i]->bench(name, x, y);
         }
     }
-    virtual void tileConfig(SkString configName) {
+    virtual void logRenderer(sk_tools::PictureRenderer *pr) SK_OVERRIDE {
         for(int i=0; i<fWriters.count(); ++i) {
-            fWriters[i]->tileConfig(configName);
+            fWriters[i]->logRenderer(pr);
         }
     }
-    virtual void tileMeta(int x, int y, int tx, int ty) {
+    virtual void tileMeta(int x, int y, int tx, int ty) SK_OVERRIDE {
         for(int i=0; i<fWriters.count(); ++i) {
             fWriters[i]->tileMeta(x, y, tx, ty);
         }
     }
-    virtual void addTileFlag(PictureResultsWriter::TileFlags flag) {
+    virtual void addTileFlag(PictureResultsWriter::TileFlags flag) SK_OVERRIDE {
         for(int i=0; i<fWriters.count(); ++i) {
             fWriters[i]->addTileFlag(flag);
         }
@@ -79,13 +81,13 @@
             const char format[],
             const TimerData::Result result,
             uint32_t timerTypes,
-            int numInnerLoops = 1) {
+            int numInnerLoops = 1) SK_OVERRIDE {
         for(int i=0; i<fWriters.count(); ++i) {
             fWriters[i]->tileData(data, format, result, timerTypes,
                                  numInnerLoops);
         }
     }
-   virtual void end() {
+   virtual void end() SK_OVERRIDE {
         for(int i=0; i<fWriters.count(); ++i) {
             fWriters[i]->end();
         }
@@ -106,23 +108,23 @@
     }
 public:
     PictureResultsLoggerWriter(BenchLogger* log)
-          : fLogger(log), currentLine() {}
-    virtual void bench(const char name[], int32_t x, int32_t y) {
+          : fLogger(log), fCurrentLine() {}
+    virtual void bench(const char name[], int32_t x, int32_t y) SK_OVERRIDE {
         SkString result;
         result.printf("running bench [%i %i] %s ", x, y, name);
         this->logProgress(result.c_str());
     }
-    virtual void tileConfig(SkString configName) {
-        currentLine = configName;
+    virtual void logRenderer(sk_tools::PictureRenderer* renderer) SK_OVERRIDE {
+        fCurrentLine = renderer->getConfigName();
     }
-    virtual void tileMeta(int x, int y, int tx, int ty) {
-        currentLine.appendf(": tile [%i,%i] out of [%i,%i]", x, y, tx, ty);
+    virtual void tileMeta(int x, int y, int tx, int ty) SK_OVERRIDE {
+        fCurrentLine.appendf(": tile [%i,%i] out of [%i,%i]", x, y, tx, ty);
     }
-    virtual void addTileFlag(PictureResultsWriter::TileFlags flag) {
+    virtual void addTileFlag(PictureResultsWriter::TileFlags flag) SK_OVERRIDE {
         if(flag == PictureResultsWriter::kPurging) {
-            currentLine.append(" <withPurging>");
+            fCurrentLine.append(" <withPurging>");
         } else if(flag == PictureResultsWriter::kAvg) {
-            currentLine.append(" <averaged>");
+            fCurrentLine.append(" <averaged>");
         }
     }
     virtual void tileData(
@@ -130,16 +132,16 @@
             const char format[],
             const TimerData::Result result,
             uint32_t timerTypes,
-            int numInnerLoops = 1) {
+            int numInnerLoops = 1) SK_OVERRIDE {
         SkString results = data->getResult(format, result,
-                currentLine.c_str(), timerTypes, numInnerLoops);
+                fCurrentLine.c_str(), timerTypes, numInnerLoops);
         results.append("\n");
         this->logProgress(results.c_str());
     }
     virtual void end() {}
 private:
     BenchLogger* fLogger;
-    SkString currentLine;
+    SkString fCurrentLine;
 };
 
 /**
@@ -172,61 +174,137 @@
 
 class PictureJSONResultsWriter : public PictureResultsWriter {
 public:
-    PictureJSONResultsWriter(const char filename[])
-        : fFilename(filename),
-          fRoot(),
-          fCurrentBench(NULL),
-          fCurrentTileSet(NULL),
-          fCurrentTile(NULL) {}
+    PictureJSONResultsWriter(const char filename[],
+                             const char builderName[],
+                             int buildNumber,
+                             int timestamp,
+                             const char gitHash[],
+                             int gitNumber)
+        : fStream(filename) {
+        fBuilderName = SkString(builderName);
+        fBuildNumber = buildNumber;
+        fTimestamp = timestamp;
+        fGitHash = SkString(gitHash);
+        fGitNumber = gitNumber;
+        fBuilderData = this->makeBuilderJson();
+    }
 
-    virtual void bench(const char name[], int32_t x, int32_t y) {
-        SkString sk_name(name);
-        sk_name.append("_");
-        sk_name.appendS32(x);
-        sk_name.append("_");
-        sk_name.appendS32(y);
-        Json::Value* bench_node = SkFindNamedNode(&fRoot["benches"], sk_name.c_str());
-        fCurrentBench = &(*bench_node)["tileSets"];
+    virtual void bench(const char name[], int32_t x, int32_t y) SK_OVERRIDE {
+        fBenchName = SkString(name);
     }
-    virtual void tileConfig(SkString configName) {
-        SkASSERT(fCurrentBench != NULL);
-        fCurrentTileSet = SkFindNamedNode(fCurrentBench, configName.c_str());
-        fCurrentTile = &(*fCurrentTileSet)["tiles"][0];
+    virtual void logRenderer(sk_tools::PictureRenderer* pr) SK_OVERRIDE {
+        fParams = pr->getJSONConfig();
+        fConfigString = pr->getConfigName();
     }
-    virtual void tileMeta(int x, int y, int tx, int ty) {
-        SkASSERT(fCurrentTileSet != NULL);
-        (*fCurrentTileSet)["tx"] = tx;
-        (*fCurrentTileSet)["ty"] = ty;
-        fCurrentTile = &(*fCurrentTileSet)["tiles"][x+tx*y];
-    }
-    virtual void addTileFlag(PictureResultsWriter::TileFlags flag) {
-        SkASSERT(fCurrentTile != NULL);
-        if(flag == PictureResultsWriter::kPurging) {
-            (*fCurrentTile)["flags"]["purging"] = true;
-        } else if(flag == PictureResultsWriter::kAvg) {
-            (*fCurrentTile)["flags"]["averaged"] = true;
-        }
-    }
+    // Apparently tiles aren't used, so tileMeta is empty
+    virtual void tileMeta(int x, int y, int tx, int ty) SK_OVERRIDE {}
+    // Flags aren't used, so addTileFlag is empty
+    virtual void addTileFlag(PictureResultsWriter::TileFlags flag) SK_OVERRIDE {}
     virtual void tileData(
             TimerData* data,
             const char format[],
             const TimerData::Result result,
             uint32_t timerTypes,
-            int numInnerLoops = 1) {
-        SkASSERT(fCurrentTile != NULL);
-        (*fCurrentTile)["data"] = data->getJSON(timerTypes, result, numInnerLoops);
+            int numInnerLoops = 1) SK_OVERRIDE {
+        Json::Value newData = data->getJSON(timerTypes, result, numInnerLoops);
+        Json::Value combinedParams(fBuilderData);
+        for(Json::ValueIterator iter = fParams.begin(); iter != fParams.end();
+                iter++) {
+            combinedParams[iter.key().asString()]= *iter;
+        }
+        // For each set of timer data
+        for(Json::ValueIterator iter = newData.begin(); iter != newData.end();
+                iter++) {
+            Json::Value data;
+            data["buildNumber"] = fBuildNumber;
+            data["timestamp"] = fTimestamp;
+            data["gitHash"] = fGitHash.c_str();
+            data["gitNumber"] = fGitNumber;
+            data["isTrybot"] = fBuilderName.endsWith("Trybot");
+
+            data["params"] = combinedParams;
+            data["params"]["benchName"] = fBenchName.c_str();
+
+            // Not including skpSize because that's deprecated?
+            data["key"] = this->makeKey(iter.key().asString().c_str()).c_str();
+            // Get the data
+            SkTArray<double> times;
+            Json::Value val = *iter;
+            for(Json::ValueIterator vals = val.begin(); vals != val.end();
+                    vals++) {
+                times.push_back((*vals).asDouble());
+            }
+            qsort(static_cast<void*>(times.begin()), times.count(),
+                    sizeof(double), PictureJSONResultsWriter::CompareDoubles);
+            data["value"] = times[static_cast<int>(times.count() * 0.25f)];
+            data["params"]["measurementType"] = iter.key().asString();
+            fStream.writeText(Json::FastWriter().write(data).c_str());
+        }
     }
-    virtual void end() {
-       SkFILEWStream stream(fFilename.c_str());
-       stream.writeText(Json::FastWriter().write(fRoot).c_str());
-       stream.flush();
+    virtual void end() SK_OVERRIDE {
+       fStream.flush();
     }
 private:
-    SkString fFilename;
-    Json::Value fRoot;
-    Json::Value *fCurrentBench;
-    Json::Value *fCurrentTileSet;
-    Json::Value *fCurrentTile;
+    Json::Value makeBuilderJson() const {
+        static const int kNumKeys = 6;
+        static const char* kKeys[kNumKeys] = {
+            "role", "os", "model", "gpu", "arch", "configuration"};
+        Json::Value builderData;
+
+        if (!fBuilderName.isEmpty()) {
+            SkTArray<SkString> splitBuilder;
+            SkStrSplit(fBuilderName.c_str(), "-", &splitBuilder);
+            SkASSERT(splitBuilder.count() >= kNumKeys);
+            for (int i = 0; i < kNumKeys && i < splitBuilder.count(); ++i) {
+                builderData[kKeys[i]] = splitBuilder[i].c_str();
+            }
+            builderData["builderName"] = fBuilderName.c_str();
+            if (kNumKeys < splitBuilder.count()) {
+                SkString extras;
+                for (int i = kNumKeys; i < splitBuilder.count(); ++i) {
+                    extras.append(splitBuilder[i]);
+                    if (i != splitBuilder.count() - 1) {
+                        extras.append("-");
+                    }
+                }
+                builderData["badParams"] = extras.c_str();
+            }
+        }
+        return builderData;
+    }
+
+    static int CompareDoubles(const void* p1, const void* p2) {
+        if(*static_cast<const double*>(p1) < *static_cast<const double*>(p2)) {
+            return -1;
+        } else if(*static_cast<const double*>(p1) ==
+                *static_cast<const double*>(p2)) {
+            return 0;
+        } else {
+            return 1;
+        }
+    }
+    SkString makeKey(const char measurementType[]) const {
+        SkString tmp(fBuilderName);
+        tmp.append("_");
+        tmp.append(fBenchName);
+        tmp.append("_");
+        tmp.append(fConfigString);
+        tmp.append("_");
+        tmp.append(measurementType);
+        return tmp;
+    }
+
+    SkFILEWStream   fStream;
+    Json::Value     fBuilderData;
+    SkString        fBenchName;
+    Json::Value     fParams;
+
+    SkString        fConfigString;
+    SkString        fBuilderName;
+    int             fBuildNumber;
+    int             fTimestamp;
+    SkString        fGitHash;
+    int             fGitNumber;
 };
 
 #endif
diff --git a/tools/ProcStats.cpp b/tools/ProcStats.cpp
new file mode 100644
index 0000000..eaa1379
--- /dev/null
+++ b/tools/ProcStats.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 "ProcStats.h"
+
+#if defined(SK_BUILD_FOR_UNIX) || \
+    defined(SK_BUILD_FOR_MAC) || \
+    defined(SK_BUILD_FOR_ANDROID)
+
+    #include <sys/resource.h>
+    int sk_tools::getMaxResidentSetSizeMB() {
+        struct rusage ru;
+        getrusage(RUSAGE_SELF, &ru);
+    #if defined(SK_BUILD_FOR_MAC)
+        return static_cast<int>(ru.ru_maxrss / 1024 / 1024);  // Darwin reports bytes.
+    #else
+        return static_cast<int>(ru.ru_maxrss / 1024);  // Linux reports kilobytes.
+    #endif
+    }
+
+#else
+
+    int sk_tools::getMaxResidentSetSizeMB() {
+        return -1;
+    }
+
+#endif
diff --git a/tools/ProcStats.h b/tools/ProcStats.h
new file mode 100644
index 0000000..14b98b7
--- /dev/null
+++ b/tools/ProcStats.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef ProcStats_DEFINED
+#define ProcStats_DEFINED
+
+/**
+ * ProcStats - Process Statistics Functions
+ */
+
+namespace sk_tools {
+
+/**
+ *  If not implemented for this OS, returns -1.  Otherwise, return
+ *  the maximum resident set size, as reported by getrusage().
+ */
+int getMaxResidentSetSizeMB();
+
+}  // namespace sk_tools
+
+#endif  // ProcStats_DEFINED
diff --git a/tools/Resources.cpp b/tools/Resources.cpp
index 756d14a..606c5c4 100644
--- a/tools/Resources.cpp
+++ b/tools/Resources.cpp
@@ -13,5 +13,9 @@
 DEFINE_string2(resourcePath, i, "resources", "Directory with test resources: images, fonts, etc.");
 
 SkString GetResourcePath(const char* resource) {
-    return SkOSPath::SkPathJoin(FLAGS_resourcePath[0], resource);
+    return SkOSPath::Join(FLAGS_resourcePath[0], resource);
+}
+
+void SetResourcePath(const char* resource) {
+    FLAGS_resourcePath.set(0, resource);
 }
diff --git a/tools/Resources.h b/tools/Resources.h
index a10612b..485a112 100644
--- a/tools/Resources.h
+++ b/tools/Resources.h
@@ -11,5 +11,6 @@
 #include "SkString.h"
 
 SkString GetResourcePath(const char* resource = "");
+void SetResourcePath(const char* );
 
 #endif  // Resources_DEFINED
diff --git a/tools/Stats.h b/tools/Stats.h
index 2370084..8487a94 100644
--- a/tools/Stats.h
+++ b/tools/Stats.h
@@ -1,6 +1,15 @@
 #ifndef Stats_DEFINED
 #define Stats_DEFINED
 
+#include "SkString.h"
+#include "SkTSort.h"
+
+#ifdef SK_BUILD_FOR_WIN
+    static const char* kBars[] = { ".", "o", "O" };
+#else
+    static const char* kBars[] = { "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" };
+#endif
+
 struct Stats {
     Stats(const double samples[], int n) {
         min = samples[0];
@@ -21,12 +30,36 @@
             err += (samples[i] - mean) * (samples[i] - mean);
         }
         var = err / (n-1);
+
+        SkAutoTMalloc<double> sorted(n);
+        memcpy(sorted.get(), samples, n * sizeof(double));
+        SkTQSort(sorted.get(), sorted.get() + n - 1);
+        median = sorted[n/2];
+
+        // Normalize samples to [min, max] in as many quanta as we have distinct bars to print.
+        for (int i = 0; i < n; i++) {
+            if (min == max) {
+                // All samples are the same value.  Don't divide by zero.
+                plot.append(kBars[0]);
+                continue;
+            }
+
+            double s = samples[i];
+            s -= min;
+            s /= (max - min);
+            s *= (SK_ARRAY_COUNT(kBars) - 1);
+            const size_t bar = (size_t)(s + 0.5);
+            SK_ALWAYSBREAK(bar < SK_ARRAY_COUNT(kBars));
+            plot.append(kBars[bar]);
+        }
     }
 
     double min;
     double max;
-    double mean;  // Estimate of population mean.
-    double var;   // Estimate of population variance.
+    double mean;    // Estimate of population mean.
+    double var;     // Estimate of population variance.
+    double median;
+    SkString plot;  // A single-line bar chart (_not_ histogram) of the samples.
 };
 
 #endif//Stats_DEFINED
diff --git a/tools/add_codereview_message.py b/tools/add_codereview_message.py
index 6710390..296a894 100755
--- a/tools/add_codereview_message.py
+++ b/tools/add_codereview_message.py
@@ -7,14 +7,12 @@
 
 """Add message to codereview issue.
 
-This script takes a codereview URL or a codereview issue number as its
-argument and a (possibly multi-line) message on stdin.  It then calls
-`git cl upload` to append the message to the given codereview issue.
+This script takes a codereview issue number as its argument and a (possibly
+multi-line) message on stdin.  It appends the message to the given issue.
 
 Usage:
-  echo MESSAGE | %prog -c CHECKOUT_PATH CODEREVIEW_ISSUE
+  echo MESSAGE | %prog CODEREVIEW_ISSUE
 or:
-  cd /path/to/git/checkout
   %prog CODEREVIEW_ISSUE <<EOF
   MESSAGE
   EOF
@@ -23,126 +21,49 @@
 """
 
 import optparse
-import os
 import sys
 
-import git_utils
-import misc_utils
+import fix_pythonpath  # pylint: disable=W0611
+from common.py.utils import find_depot_tools  # pylint: disable=W0611
+import rietveld
 
 
-DEFAULT_REVIEWERS = ','.join([
-    'rmistry@google.com',
-    'reed@google.com',
-    'bsalomon@google.com',
-    'robertphillips@google.com',
-    ])
+RIETVELD_URL = 'https://codereview.chromium.org'
 
 
-DEFAULT_CC_LIST = ','.join([
-    'skia-team@google.com',
-    ])
+def add_codereview_message(issue, message):
+  """Add a message to a given codereview.
 
-
-def add_codereview_message(codereview_url, message, checkout_path,
-                           skip_cl_upload, verbose, reviewers, cclist):
-    """Add a message to a given codereview.
-
-    Args:
-        codereview_url: (string) we will extract the issue number from
-            this url, or this could simply be the issue number.
-        message: (string) will be passed to `git cl upload -m $MESSAGE`
-        checkout_path: (string) location of the git
-            repository checkout to be used.
-        skip_cl_upload: (boolean) if true, don't actually
-            add the message and keep the temporary branch around.
-        verbose: (boolean) print out details useful for debugging.
-        reviewers: (string) comma-separated list of reviewers
-        cclist: (string) comma-separated list of addresses to be
-            carbon-copied
-    """
-    # pylint: disable=I0011,R0913
-    git = git_utils.git_executable()
-    issue = codereview_url.strip('/').split('/')[-1]
-    vsp = misc_utils.VerboseSubprocess(verbose)
-    if skip_cl_upload:
-        branch_name = 'issue_%s' % issue
-    else:
-        branch_name = None
-    upstream = 'origin/master'
-
-    with misc_utils.ChangeDir(checkout_path, verbose):
-        vsp.check_call([git, 'fetch', '-q', 'origin'])
-
-        with git_utils.ChangeGitBranch(branch_name, upstream, verbose):
-            vsp.check_call([git, 'cl', 'patch', issue])
-
-            git_upload = [
-                git, 'cl', 'upload', '-t', 'bot report', '-m', message]
-            if cclist:
-                git_upload.append('--cc=' + cclist)
-            if reviewers:
-                git_upload.append('--reviewers=' + reviewers)
-
-            if skip_cl_upload:
-                branch_name = git_utils.git_branch_name(verbose)
-                space = '    '
-                print 'You should call:'
-                misc_utils.print_subprocess_args(space, ['cd', os.getcwd()])
-                misc_utils.print_subprocess_args(
-                    space, [git, 'checkout', branch_name])
-                misc_utils.print_subprocess_args(space, git_upload)
-            else:
-                vsp.check_call(git_upload)
-                print vsp.check_output([git, 'cl', 'issue'])
+  Args:
+      codereview_url: (string) we will extract the issue number from
+          this url, or this could simply be the issue number.
+      message: (string) message to add.
+  """
+  # Passing None for the email and password will result in a prompt or
+  # reuse of existing cached credentials.
+  my_rietveld = rietveld.Rietveld(RIETVELD_URL, email=None, password=None)
+  
+  my_rietveld.add_comment(issue, message)
 
 
 def main(argv):
-    """main function; see module-level docstring and GetOptionParser help.
+  """main function; see module-level docstring and GetOptionParser help.
 
-    Args:
-        argv: sys.argv[1:]-type argument list.
-    """
-    option_parser = optparse.OptionParser(usage=__doc__)
-    option_parser.add_option(
-        '-c', '--checkout_path',
-        default=os.curdir,
-        help='Path to the Git repository checkout,'
-        ' defaults to current working directory.')
-    option_parser.add_option(
-        '', '--skip_cl_upload', action='store_true', default=False,
-        help='Skip the cl upload step; useful for testing.')
-    option_parser.add_option(
-        '', '--verbose', action='store_true', dest='verbose', default=False,
-        help='Do not suppress the output from `git cl`.',)
-    option_parser.add_option(
-        '', '--git_path', default='git',
-        help='Git executable, defaults to "git".',)
-    option_parser.add_option(
-        '', '--reviewers', default=DEFAULT_REVIEWERS,
-        help=('Comma-separated list of reviewers.  Default is "%s".'
-              % DEFAULT_REVIEWERS))
-    option_parser.add_option(
-        '', '--cc', default=DEFAULT_CC_LIST,
-        help=('Comma-separated list of addresses to be carbon-copied.'
-              '  Default is "%s".' %  DEFAULT_CC_LIST))
+  Args:
+      argv: sys.argv[1:]-type argument list.
+  """
+  option_parser = optparse.OptionParser(usage=__doc__)
+  _, arguments = option_parser.parse_args(argv)
 
-    options, arguments = option_parser.parse_args(argv)
+  if len(arguments) > 1:
+    option_parser.error('Extra arguments.')
+  if len(arguments) != 1:
+    option_parser.error('Missing issue number.')
 
-    if not options.checkout_path:
-        option_parser.error('Must specify checkout_path.')
-    if not git_utils.git_executable():
-        option_parser.error('Invalid git executable.')
-    if len(arguments) > 1:
-        option_parser.error('Extra arguments.')
-    if len(arguments) != 1:
-        option_parser.error('Missing Codereview URL.')
-
-    message = sys.stdin.read()
-    add_codereview_message(arguments[0], message, options.checkout_path,
-                           options.skip_cl_upload, options.verbose,
-                           options.reviewers, options.cc)
+  message = sys.stdin.read()
+  add_codereview_message(int(arguments[0]), message)
 
 
 if __name__ == '__main__':
-    main(sys.argv[1:])
+  main(sys.argv[1:])
 
diff --git a/tools/bbh_shootout.cpp b/tools/bbh_shootout.cpp
index e657917..2a827fd 100644
--- a/tools/bbh_shootout.cpp
+++ b/tools/bbh_shootout.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "BenchTimer.h"
+#include "Timer.h"
 #include "Benchmark.h"
 #include "LazyDecodeBitmap.h"
 #include "PictureBenchmark.h"
@@ -23,7 +23,7 @@
 
 DEFINE_string2(skps, r, "", "The list of SKPs to benchmark.");
 DEFINE_string(bb_types, "", "The set of bbox types to test. If empty, all are tested. "
-                       "Should be one or more of none, quadtree, rtree, tilegrid.");
+                       "Should be one or more of none, rtree, tilegrid.");
 DEFINE_int32(record, 100, "Number of times to record each SKP.");
 DEFINE_int32(playback, 1, "Number of times to playback each SKP.");
 DEFINE_int32(tilesize, 256, "The size of a tile.");
@@ -36,7 +36,6 @@
 
 const char* kBBoxHierarchyTypeNames[kBBoxTypeCount] = {
     "none", // kNone_BBoxHierarchyType
-    "quadtree", // kQuadTree_BBoxHierarchyType
     "rtree", // kRTree_BBoxHierarchyType
     "tilegrid", // kTileGrid_BBoxHierarchyType
 };
@@ -64,7 +63,7 @@
         BBoxType bBoxType,
         SkPicture* pic,
         const int numRepeats,
-        BenchTimer* timer) {
+        Timer* timer) {
     renderer->setBBoxHierarchyType(bBoxType);
     renderer->setGridSize(FLAGS_tilesize, FLAGS_tilesize);
     renderer->init(pic, NULL, NULL, NULL, false);
@@ -105,15 +104,25 @@
         for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
             if (!includeBBoxType[bBoxType]) { continue; }
             if (FLAGS_playback > 0) {
+#if SK_SUPPORT_GPU
+                GrContext::Options grContextOpts;
+                sk_tools::TiledPictureRenderer playbackRenderer(grContextOpts);
+#else
                 sk_tools::TiledPictureRenderer playbackRenderer;
-                BenchTimer playbackTimer;
+#endif
+                Timer playbackTimer;
                 do_benchmark_work(&playbackRenderer, (BBoxType)bBoxType,
                                   picture, FLAGS_playback, &playbackTimer);
                 measurement.fPlaybackAverage[bBoxType] = playbackTimer.fCpu;
             }
             if (FLAGS_record > 0) {
+#if SK_SUPPORT_GPU
+                GrContext::Options grContextOpts;
+                sk_tools::RecordPictureRenderer recordRenderer(grContextOpts);
+#else
                 sk_tools::RecordPictureRenderer recordRenderer;
-                BenchTimer recordTimer;
+#endif
+                Timer recordTimer;
                 do_benchmark_work(&recordRenderer, (BBoxType)bBoxType,
                                   picture, FLAGS_record, &recordTimer);
                 measurement.fRecordAverage[bBoxType] = recordTimer.fCpu;
diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
index d9b767b..ade93fc 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "BenchLogger.h"
-#include "BenchTimer.h"
+#include "Timer.h"
 #include "CopyTilesRenderer.h"
 #include "CrashHandler.h"
 #include "LazyDecodeBitmap.h"
@@ -42,7 +42,6 @@
 DEFINE_bool(logPerIter, false, "Log each repeat timer instead of mean.");
 DEFINE_string(jsonLog, "", "Destination for writing JSON data.");
 DEFINE_bool(min, false, "Print the minimum times (instead of average).");
-DECLARE_int32(multi);
 DECLARE_string(readPath);
 DEFINE_int32(repeat, 1, "Set the number of times to repeat each test.");
 DEFINE_bool(timeIndividualTiles, false, "Report times for drawing individual tiles, rather than "
@@ -55,8 +54,21 @@
             "SK_LAZY_CACHE_STATS set to true. Report percentage of cache hits when using "
             "deferred image decoding.");
 
+#if GR_GPU_STATS
+DEFINE_bool(gpuStats, false, "Only meaningful with gpu configurations. "
+            "Report some GPU call statistics.");
+#endif
+
 DEFINE_bool(preprocess, false, "If true, perform device specific preprocessing before timing.");
 
+// Buildbot-specific parameters
+DEFINE_string(builderName, "", "Name of the builder this is running on.");
+DEFINE_int32(buildNumber, -1, "Build number of the build this test is running on");
+DEFINE_int32(timestamp, 0, "Timestamp of the revision of Skia being tested.");
+DEFINE_string(gitHash, "", "Commit hash of the revision of Skia being run.");
+DEFINE_int32(gitNumber, -1, "Git number of the revision of Skia being run.");
+
+
 static char const * const gFilterTypes[] = {
     "paint",
     "point",
@@ -190,9 +202,21 @@
         return false;
     }
 
-    SkString filename = SkOSPath::SkBasename(inputPath.c_str());
+    if (FLAGS_preprocess) {
+        // Because the GPU preprocessing step relies on the in-memory picture
+        // statistics we need to rerecord the picture here
+        SkPictureRecorder recorder;
+        picture->playback(recorder.beginRecording(picture->cullRect().width(), 
+                                                  picture->cullRect().height(), 
+                                                  NULL, 0));
+        picture.reset(recorder.endRecording());
+    }
 
-    gWriter.bench(filename.c_str(), picture->width(), picture->height());
+    SkString filename = SkOSPath::Basename(inputPath.c_str());
+
+    gWriter.bench(filename.c_str(), 
+                  SkScalarCeilToInt(picture->cullRect().width()), 
+                  SkScalarCeilToInt(picture->cullRect().height()));
 
     benchmark.run(picture);
 
@@ -328,10 +352,6 @@
     }
 
     if (FLAGS_timeIndividualTiles) {
-        if (FLAGS_multi > 1) {
-            gLogger.logError("Cannot time individual tiles with more than one thread.\n");
-            exit(-1);
-        }
         sk_tools::TiledPictureRenderer* tiledRenderer = renderer->getTiledRenderer();
         if (NULL == tiledRenderer) {
             gLogger.logError("--timeIndividualTiles requires tiled rendering.\n");
@@ -373,7 +393,7 @@
     int failures = 0;
     if (iter.next(&inputFilename)) {
         do {
-            SkString inputPath = SkOSPath::SkPathJoin(input, inputFilename.c_str());
+            SkString inputPath = SkOSPath::Join(input, inputFilename.c_str());
             if (!run_single_benchmark(inputPath, benchmark)) {
                 ++failures;
             }
@@ -421,7 +441,14 @@
 
     SkAutoTDelete<PictureJSONResultsWriter> jsonWriter;
     if (FLAGS_jsonLog.count() == 1) {
-        jsonWriter.reset(SkNEW(PictureJSONResultsWriter(FLAGS_jsonLog[0])));
+        SkASSERT(FLAGS_builderName.count() == 1 && FLAGS_gitHash.count() == 1);
+        jsonWriter.reset(SkNEW(PictureJSONResultsWriter(
+                        FLAGS_jsonLog[0],
+                        FLAGS_builderName[0],
+                        FLAGS_buildNumber,
+                        FLAGS_timestamp,
+                        FLAGS_gitHash[0],
+                        FLAGS_gitNumber)));
         gWriter.add(jsonWriter.get());
     }
 
@@ -454,6 +481,15 @@
                  (double) gTotalCacheHits / (gTotalCacheHits + gTotalCacheMisses));
     }
 #endif
+
+#if GR_GPU_STATS
+    if (FLAGS_gpuStats && benchmark.renderer()->isUsingGpuDevice()) {
+        GrContext* ctx = benchmark.renderer()->getGrContext();
+        SkDebugf("RenderTarget Binds: %d\n", ctx->gpuStats()->renderTargetBinds());
+        SkDebugf("Shader Compilations: %d\n", ctx->gpuStats()->shaderCompilations());
+    }
+#endif
+
     gWriter.end();
     return 0;
 }
diff --git a/tools/bench_playback.cpp b/tools/bench_playback.cpp
deleted file mode 100644
index 26fa1c7..0000000
--- a/tools/bench_playback.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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 "SkCommandLineFlags.h"
-#include "SkForceLinking.h"
-#include "SkGraphics.h"
-#include "SkOSFile.h"
-#include "SkPicture.h"
-#include "SkPictureRecorder.h"
-#include "SkStream.h"
-#include "SkString.h"
-
-#include "../include/record/SkRecording.h"
-
-#include "BenchTimer.h"
-#include "Stats.h"
-
-typedef WallTimer Timer;
-
-__SK_FORCE_IMAGE_DECODER_LINKING;
-
-DEFINE_string2(skps, r, "skps", "Directory containing SKPs to playback.");
-DEFINE_int32(samples, 10, "Gather this many samples of each picture playback.");
-DEFINE_bool(skr, false, "Play via SkRecord instead of SkPicture.");
-DEFINE_int32(tile, 1000000000, "Simulated tile size.");
-DEFINE_string(match, "", "The usual filters on file names of SKPs to bench.");
-DEFINE_string(timescale, "ms", "Print times in ms, us, or ns");
-DEFINE_int32(verbose, 0, "0: print min sample; "
-                         "1: print min, mean, max and noise indication "
-                         "2: print all samples");
-
-static double timescale() {
-    if (FLAGS_timescale.contains("us")) return 1000;
-    if (FLAGS_timescale.contains("ns")) return 1000000;
-    return 1;
-}
-
-static SkPicture* rerecord_with_tilegrid(SkPicture& src) {
-    SkTileGridFactory::TileGridInfo info;
-    info.fTileInterval.set(FLAGS_tile, FLAGS_tile);
-    info.fMargin.setEmpty();
-    info.fOffset.setZero();
-    SkTileGridFactory factory(info);
-
-    SkPictureRecorder recorder;
-    src.draw(recorder.beginRecording(src.width(), src.height(), &factory));
-    return recorder.endRecording();
-}
-
-static EXPERIMENTAL::SkPlayback* rerecord_with_skr(SkPicture& src) {
-    EXPERIMENTAL::SkRecording recording(src.width(), src.height());
-    src.draw(recording.canvas());
-    return recording.releasePlayback();
-}
-
-static void draw(const EXPERIMENTAL::SkPlayback& skr, const SkPicture& skp, SkCanvas* canvas) {
-    if (FLAGS_skr) {
-        skr.draw(canvas);
-    } else {
-        skp.draw(canvas);
-    }
-}
-
-static void bench(SkPMColor* scratch, SkPicture& src, const char* name) {
-    SkAutoTUnref<SkPicture> picture(rerecord_with_tilegrid(src));
-    SkAutoTDelete<EXPERIMENTAL::SkPlayback> record(rerecord_with_skr(src));
-
-    SkAutoTDelete<SkCanvas> canvas(SkCanvas::NewRasterDirectN32(src.width(),
-                                                                src.height(),
-                                                                scratch,
-                                                                src.width() * sizeof(SkPMColor)));
-    canvas->clipRect(SkRect::MakeWH(SkIntToScalar(FLAGS_tile), SkIntToScalar(FLAGS_tile)));
-
-    // Draw once to warm any caches.  The first sample otherwise can be very noisy.
-    draw(*record, *picture, canvas.get());
-
-    Timer timer;
-    SkAutoTMalloc<double> samples(FLAGS_samples);
-    for (int i = 0; i < FLAGS_samples; i++) {
-        // We assume timer overhead (typically, ~30ns) is insignificant
-        // compared to draw runtime (at least ~100us, usually several ms).
-        timer.start(timescale());
-        draw(*record, *picture, canvas.get());
-        timer.end();
-        samples[i] = timer.fWall;
-    }
-
-    Stats stats(samples.get(), FLAGS_samples);
-    if (FLAGS_verbose == 0) {
-        printf("%g\t%s\n", stats.min, name);
-    } else if (FLAGS_verbose == 1) {
-        // Get a rough idea of how noisy the measurements were.
-        const double noisePercent = 100 * sqrt(stats.var) / stats.mean;
-        printf("%g\t%g\t%g\t±%.0f%%\t%s\n", stats.min, stats.mean, stats.max, noisePercent, name);
-    } else if (FLAGS_verbose == 2) {
-        printf("%s", name);
-        for (int i = 0; i < FLAGS_samples; i++) {
-            printf("\t%g", samples[i]);
-        }
-        printf("\n");
-    }
-}
-
-int tool_main(int argc, char** argv);
-int tool_main(int argc, char** argv) {
-    SkCommandLineFlags::Parse(argc, argv);
-    SkAutoGraphics autoGraphics;
-
-    // We share a single scratch bitmap among benches to reduce the profile noise from allocation.
-    static const int kMaxArea = 209825221;  // tabl_mozilla is this big.
-    SkAutoTMalloc<SkPMColor> scratch(kMaxArea);
-
-    SkOSFile::Iter it(FLAGS_skps[0], ".skp");
-    SkString filename;
-    bool failed = false;
-    while (it.next(&filename)) {
-        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) {
-            continue;
-        }
-
-        const SkString path = SkOSPath::SkPathJoin(FLAGS_skps[0], filename.c_str());
-
-        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path.c_str()));
-        if (!stream) {
-            SkDebugf("Could not read %s.\n", path.c_str());
-            failed = true;
-            continue;
-        }
-        SkAutoTUnref<SkPicture> src(SkPicture::CreateFromStream(stream));
-        if (!src) {
-            SkDebugf("Could not read %s as an SkPicture.\n", path.c_str());
-            failed = true;
-            continue;
-        }
-
-        if (src->width() * src->height() > kMaxArea) {
-            SkDebugf("%s (%dx%d) is larger than hardcoded scratch bitmap (%dpx).\n",
-                     path.c_str(), src->width(), src->height(), kMaxArea);
-            failed = true;
-            continue;
-        }
-
-        bench(scratch.get(), *src, filename.c_str());
-    }
-    return failed ? 1 : 0;
-}
-
-#if !defined SK_BUILD_FOR_IOS
-int main(int argc, char * const argv[]) {
-    return tool_main(argc, (char**) argv);
-}
-#endif
diff --git a/tools/bench_record.cpp b/tools/bench_record.cpp
deleted file mode 100644
index 0024c2c..0000000
--- a/tools/bench_record.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * 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 "SkCommandLineFlags.h"
-#include "SkForceLinking.h"
-#include "SkGraphics.h"
-#include "SkOSFile.h"
-#include "SkPicture.h"
-#include "SkPictureRecorder.h"
-#include "SkStream.h"
-#include "SkString.h"
-
-#include "BenchTimer.h"
-#include "LazyDecodeBitmap.h"
-#include "Stats.h"
-
-typedef WallTimer Timer;
-
-__SK_FORCE_IMAGE_DECODER_LINKING;
-
-DEFINE_string2(skps, r, "skps", "Directory containing SKPs to read and re-record.");
-DEFINE_int32(samples, 10, "Number of times to re-record each SKP.");
-DEFINE_int32(tileGridSize, 512, "Set the tile grid size. Has no effect if bbh is not set to tilegrid.");
-DEFINE_string(bbh, "", "Turn on the bbh and select the type, one of rtree, tilegrid, quadtree");
-DEFINE_bool(skr, false, "Record SKR instead of SKP.");
-DEFINE_string(match, "", "The usual filters on file names of SKPs to bench.");
-DEFINE_string(timescale, "us", "Print times in ms, us, or ns");
-DEFINE_double(overheadGoal, 0.0001,
-              "Try to make timer overhead at most this fraction of our sample measurements.");
-DEFINE_int32(verbose, 0, "0: print min sample; "
-                         "1: print min, mean, max and noise indication "
-                         "2: print all samples");
-
-static double timescale() {
-    if (FLAGS_timescale.contains("us")) return 1000;
-    if (FLAGS_timescale.contains("ns")) return 1000000;
-    return 1;
-}
-
-static SkBBHFactory* parse_FLAGS_bbh() {
-    if (FLAGS_bbh.isEmpty()) {
-        return NULL;
-    }
-
-    if (FLAGS_bbh.contains("rtree")) {
-        return SkNEW(SkRTreeFactory);
-    }
-    if (FLAGS_bbh.contains("tilegrid")) {
-        SkTileGridFactory::TileGridInfo info;
-        info.fTileInterval.set(FLAGS_tileGridSize, FLAGS_tileGridSize);
-        info.fMargin.setEmpty();
-        info.fOffset.setZero();
-        return SkNEW_ARGS(SkTileGridFactory, (info));
-    }
-    if (FLAGS_bbh.contains("quadtree")) {
-        return SkNEW(SkQuadTreeFactory);
-    }
-    SkDebugf("Invalid bbh type %s, must be one of rtree, tilegrid, quadtree.\n", FLAGS_bbh[0]);
-    return NULL;
-}
-
-static void rerecord(const SkPicture& src, SkBBHFactory* bbhFactory) {
-    SkPictureRecorder recorder;
-    if (FLAGS_skr) {
-        src.draw(recorder.EXPERIMENTAL_beginRecording(src.width(), src.height(), bbhFactory));
-    } else {
-        src.draw(recorder.beginRecording(src.width(), src.height(), bbhFactory));
-    }
-    SkAutoTUnref<SkPicture> pic(recorder.endRecording());
-}
-
-static void bench_record(const SkPicture& src,
-                         const double timerOverhead,
-                         const char* name,
-                         SkBBHFactory* bbhFactory) {
-    // Rerecord once to warm up any caches.  Otherwise the first sample can be very noisy.
-    rerecord(src, bbhFactory);
-
-    // Rerecord once to see how many times we should loop to make timer overhead insignificant.
-    Timer timer;
-    do {
-        timer.start(timescale());
-        rerecord(src, bbhFactory);
-        timer.end();
-    } while (timer.fWall < timerOverhead);   // Loop just in case something bizarre happens.
-
-    // We want (timer overhead / measurement) to be less than FLAGS_overheadGoal.
-    // So in each sample, we'll loop enough times to have made that true for our first measurement.
-    const int loops = (int)ceil(timerOverhead / timer.fWall / FLAGS_overheadGoal);
-
-    SkAutoTMalloc<double> samples(FLAGS_samples);
-    for (int i = 0; i < FLAGS_samples; i++) {
-        timer.start(timescale());
-        for (int j = 0; j < loops; j++) {
-            rerecord(src, bbhFactory);
-        }
-        timer.end();
-        samples[i] = timer.fWall / loops;
-    }
-
-    Stats stats(samples.get(), FLAGS_samples);
-    if (FLAGS_verbose == 0) {
-        printf("%g\t%s\n", stats.min, name);
-    } else if (FLAGS_verbose == 1) {
-        // Get a rough idea of how noisy the measurements were.
-        const double noisePercent = 100 * sqrt(stats.var) / stats.mean;
-        printf("%g\t%g\t%g\t±%.0f%%\t%s\n", stats.min, stats.mean, stats.max, noisePercent, name);
-    } else if (FLAGS_verbose == 2) {
-        printf("%s", name);
-        for (int i = 0; i < FLAGS_samples; i++) {
-            printf("\t%g", samples[i]);
-        }
-        printf("\n");
-    }
-}
-
-int tool_main(int argc, char** argv);
-int tool_main(int argc, char** argv) {
-    SkCommandLineFlags::Parse(argc, argv);
-    SkAutoGraphics autoGraphics;
-
-    if (FLAGS_bbh.count() > 1) {
-        SkDebugf("Multiple bbh arguments supplied.\n");
-        return 1;
-    }
-
-    SkAutoTDelete<SkBBHFactory> bbhFactory(parse_FLAGS_bbh());
-
-    // Each run will use this timer overhead estimate to guess how many times it should run.
-    static const int kOverheadLoops = 10000000;
-    Timer timer;
-    double overheadEstimate = 0.0;
-    for (int i = 0; i < kOverheadLoops; i++) {
-        timer.start(timescale());
-        timer.end();
-        overheadEstimate += timer.fWall;
-    }
-    overheadEstimate /= kOverheadLoops;
-
-    SkOSFile::Iter it(FLAGS_skps[0], ".skp");
-    SkString filename;
-    bool failed = false;
-    while (it.next(&filename)) {
-        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) {
-            continue;
-        }
-
-        const SkString path = SkOSPath::SkPathJoin(FLAGS_skps[0], filename.c_str());
-
-        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path.c_str()));
-        if (!stream) {
-            SkDebugf("Could not read %s.\n", path.c_str());
-            failed = true;
-            continue;
-        }
-        SkAutoTUnref<SkPicture> src(
-            SkPicture::CreateFromStream(stream, sk_tools::LazyDecodeBitmap));
-        if (!src) {
-            SkDebugf("Could not read %s as an SkPicture.\n", path.c_str());
-            failed = true;
-            continue;
-        }
-        bench_record(*src, overheadEstimate, filename.c_str(), bbhFactory.get());
-    }
-    return failed ? 1 : 0;
-}
-
-#if !defined SK_BUILD_FOR_IOS
-int main(int argc, char * const argv[]) {
-    return tool_main(argc, (char**) argv);
-}
-#endif
diff --git a/tools/create_test_font.cpp b/tools/create_test_font.cpp
new file mode 100644
index 0000000..f6cac0a
--- /dev/null
+++ b/tools/create_test_font.cpp
@@ -0,0 +1,450 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// running create_test_font generates ./tools/test_font_data.cpp
+// which is read by ./tools/sk_tool_utils_font.cpp
+
+#include "Resources.h"
+#include "SkOSFile.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkStream.h"
+#include "SkTArray.h"
+#include "SkTSort.h"
+#include "SkTypeface.h"
+#include "SkUtils.h"
+#include <stdio.h>
+
+// the folllowing include is generated by running dm with
+//   --portableFonts --reportUsedChars
+#include "test_font_data_chars.cpp"
+
+#define DEFAULT_FONT_NAME "Liberation Sans"
+
+static struct FontDesc {
+    const char* fName;
+    SkTypeface::Style fStyle;
+    const char* fFont;
+    const char* fFile;
+    const char* fCharsUsed;
+    int fFontIndex;
+} gFonts[] = {
+    {"Courier New", SkTypeface::kNormal, "Courier New",     "Courier New.ttf",
+            gCourierNew},
+    {"Courier New", SkTypeface::kBold,   "Courier New",     "Courier New Bold.ttf",
+            gCourierNew_Bold},
+    {"Courier New", SkTypeface::kItalic, "Courier New",     "Courier New Italic.ttf",
+            gCourierNew_Italic},
+    {"Courier New", SkTypeface::kBoldItalic, "Courier New", "Courier New Bold Italic.ttf",
+            gCourierNew_BoldItalic},
+    {"Helvetica",   SkTypeface::kNormal, "Liberation Sans", "LiberationSans-Regular.ttf",
+            gLiberationSans},
+    {"Helvetica",  SkTypeface::kBold,    "Liberation Sans", "LiberationSans-Bold.ttf",
+            gLiberationSans_Bold},
+    {"Helvetica",  SkTypeface::kItalic,  "Liberation Sans", "LiberationSans-Italic.ttf",
+            gLiberationSans_Italic},
+    {"Helvetica",  SkTypeface::kBoldItalic, "Liberation Sans", "LiberationSans-BoldItalic.ttf",
+            gLiberationSans_BoldItalic},
+    {"Hiragino Maru Gothic Pro", SkTypeface::kNormal, "Hiragino Maru Gothic Pro", "Pro W4.otf",
+            gHiraginoMaruGothicPro},
+    {"Liberation Sans", SkTypeface::kNormal, "Liberation Sans", "LiberationSans-Regular.ttf",
+            gLiberationSans},
+    {"Liberation Sans", SkTypeface::kBold,   "Liberation Sans", "LiberationSans-Bold.ttf",
+            gLiberationSans_Bold},
+    {"Liberation Sans", SkTypeface::kItalic, "Liberation Sans", "LiberationSans-Italic.ttf",
+            gLiberationSans_Italic},
+    {"Liberation Sans", SkTypeface::kBoldItalic, "Liberation Sans", "LiberationSans-BoldItalic.ttf",
+            gLiberationSans_BoldItalic},
+    {"monospace",   SkTypeface::kNormal, "Courier New",     "Courier New.ttf",
+            gCourierNew},
+    {"monospace",   SkTypeface::kBold,   "Courier New",     "Courier New Bold.ttf",
+            gCourierNew_Bold},
+    {"monospace",   SkTypeface::kItalic, "Courier New",     "Courier New Italic.ttf",
+            gCourierNew_Italic},
+    {"monospace",   SkTypeface::kBoldItalic, "Courier New", "Courier New Bold Italic.ttf",
+            gCourierNew_BoldItalic},
+    {"Papyrus",     SkTypeface::kNormal, "Papyrus",         "Papyrus.ttc",
+            gPapyrus},
+    {"sans-serif",  SkTypeface::kNormal, "Liberation Sans", "LiberationSans-Regular.ttf",
+            gLiberationSans},
+    {"sans-serif",  SkTypeface::kBold,   "Liberation Sans", "LiberationSans-Bold.ttf",
+            gLiberationSans_Bold},
+    {"sans-serif",  SkTypeface::kItalic, "Liberation Sans", "LiberationSans-Italic.ttf",
+            gLiberationSans_Italic},
+    {"sans-serif", SkTypeface::kBoldItalic, "Liberation Sans", "LiberationSans-BoldItalic.ttf",
+            gLiberationSans_BoldItalic},
+    {"serif",       SkTypeface::kNormal, "Times New Roman", "Times New Roman.ttf",
+            gTimesNewRoman},
+    {"serif",       SkTypeface::kBold,   "Times New Roman", "Times New Roman Bold.ttf",
+            gTimesNewRoman_Bold},
+    {"serif",       SkTypeface::kItalic, "Times New Roman", "Times New Roman Italic.ttf",
+            gTimesNewRoman_Italic},
+    {"serif",   SkTypeface::kBoldItalic, "Times New Roman", "Times New Roman Bold Italic.ttf",
+            gTimesNewRoman_BoldItalic},
+    {"Times",       SkTypeface::kNormal, "Times New Roman", "Times New Roman.ttf",
+            gTimesNewRoman},
+    {"Times",       SkTypeface::kBold,   "Times New Roman", "Times New Roman Bold.ttf",
+            gTimesNewRoman_Bold},
+    {"Times",       SkTypeface::kItalic, "Times New Roman", "Times New Roman Italic.ttf",
+            gTimesNewRoman_Italic},
+    {"Times",   SkTypeface::kBoldItalic, "Times New Roman", "Times New Roman Bold Italic.ttf",
+            gTimesNewRoman_BoldItalic},
+    {"Times New Roman", SkTypeface::kNormal, "Times New Roman", "Times New Roman.ttf",
+            gTimesNewRoman},
+    {"Times New Roman", SkTypeface::kBold,   "Times New Roman", "Times New Roman Bold.ttf",
+            gTimesNewRoman_Bold},
+    {"Times New Roman", SkTypeface::kItalic, "Times New Roman", "Times New Roman Italic.ttf",
+            gTimesNewRoman_Italic},
+    {"Times New Roman", SkTypeface::kBoldItalic, "Times New Roman", "Times New Roman Bold Italic.ttf",
+            gTimesNewRoman_BoldItalic},
+    {"Times Roman", SkTypeface::kNormal, "Liberation Sans", "LiberationSans-Regular.ttf",
+            gLiberationSans},
+};
+
+const int gFontsCount = (int) SK_ARRAY_COUNT(gFonts);
+
+const char* gStyleName[] = {
+    "kNormal",
+    "kBold",
+    "kItalic",
+    "kBoldItalic",
+};
+
+const char gHeader[] =
+"/*\n"
+" * Copyright 2014 Google Inc.\n"
+" *\n"
+" * Use of this source code is governed by a BSD-style license that can be\n"
+" * found in the LICENSE file.\n"
+" */\n"
+"\n"
+"// Auto-generated by ";
+
+static FILE* font_header() {
+    SkString outPath(SkOSPath::SkPathJoin(".", "tools"));
+    outPath = SkOSPath::SkPathJoin(outPath.c_str(), "test_font_data.cpp");
+    FILE* out = fopen(outPath.c_str(), "w");
+    fprintf(out, "%s%s\n\n", gHeader, SkOSPath::SkBasename(__FILE__).c_str());
+    return out;
+}
+
+enum {
+    kMaxLineLength = 80,
+};
+
+static ptrdiff_t last_line_length(const SkString& str) {
+    const char* first = str.c_str();
+    const char* last = first + str.size();
+    const char* ptr = last;
+    while (ptr > first && *--ptr != '\n')
+        ;
+    return last - ptr - 1;
+}
+
+static void output_fixed(SkScalar num, int emSize, SkString* out) {
+    int hex = (int) (num * 65536 / emSize);
+    out->appendf("0x%08x,", hex);
+    *out += (int) last_line_length(*out) >= kMaxLineLength ? '\n' : ' ';
+}
+
+static void output_scalar(SkScalar num, int emSize, SkString* out) {
+    num /= emSize;
+    if (num == (int) num) {
+       out->appendS32((int) num);
+    } else {
+        SkString str;
+        str.printf("%1.6g", num);
+        int width = (int) str.size();
+        const char* cStr = str.c_str();
+        while (cStr[width - 1] == '0') {
+            --width;
+        }
+        str.remove(width, str.size() - width);
+        out->appendf("%sf", str.c_str());
+    }
+    *out += ',';
+    *out += (int) last_line_length(*out) >= kMaxLineLength ? '\n' : ' ';
+}
+
+static int output_points(const SkPoint* pts, int emSize, int count, SkString* ptsOut) {
+    for (int index = 0; index < count; ++index) {
+//        SkASSERT(floor(pts[index].fX) == pts[index].fX);
+        output_scalar(pts[index].fX, emSize, ptsOut);
+//        SkASSERT(floor(pts[index].fY) == pts[index].fY);
+        output_scalar(pts[index].fY, emSize, ptsOut);
+    }
+    return count;
+}
+
+static void output_path_data(const SkPaint& paint, const char* used,
+        int emSize, SkString* ptsOut, SkTDArray<SkPath::Verb>* verbs,
+        SkTDArray<unsigned>* charCodes, SkTDArray<SkScalar>* widths) {
+   while (*used) {
+        SkUnichar index = SkUTF8_NextUnichar(&used);
+        SkPath path;
+        paint.getTextPath((const void*) &index, 2, 0, 0, &path);
+        SkPath::RawIter iter(path);
+        SkPath::Verb verb;
+        SkPoint pts[4];
+        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+            *verbs->append() = verb;
+            switch (verb) {
+                case SkPath::kMove_Verb:
+                    output_points(&pts[0], emSize, 1, ptsOut);
+                    break;
+                case SkPath::kLine_Verb:
+                    output_points(&pts[1], emSize, 1, ptsOut);
+                    break;
+                case SkPath::kQuad_Verb:
+                    output_points(&pts[1], emSize, 2, ptsOut);
+                    break;
+                case SkPath::kCubic_Verb:
+                    output_points(&pts[1], emSize, 3, ptsOut);
+                    break;
+                case SkPath::kClose_Verb:
+                    break;
+                default:
+                    SkDEBUGFAIL("bad verb");
+                    SkASSERT(0);
+            }
+        }
+        *verbs->append() = SkPath::kDone_Verb;
+        *charCodes->append() = index;
+        SkScalar width;
+        SkDEBUGCODE(int charCount =) paint.getTextWidths((const void*) &index, 2, &width);
+        SkASSERT(charCount == 1);
+//        SkASSERT(floor(width) == width);  // not true for Hiragino Maru Gothic Pro
+        *widths->append() = width;
+    }
+}
+
+static int offset_str_len(unsigned num) {
+    if (num == (unsigned) -1) {
+        return 10;
+    }
+    unsigned result = 1;
+    unsigned ref = 10;
+    while (ref <= num) {
+        ++result;
+        ref *= 10;
+    }
+    return result;
+}
+
+static SkString strip_spaces(const SkString& str) {
+    SkString result;
+    int count = (int) str.size();
+    for (int index = 0; index < count; ++index) {
+        char c = str[index];
+        if (c != ' ' && c != '-') {
+            result += c;
+        }
+    }
+    return result;
+}
+
+static SkString strip_final(const SkString& str) {
+    SkString result(str);
+    if (result.endsWith("\n")) {
+        result.remove(result.size() - 1, 1);
+    }
+    if (result.endsWith(" ")) {
+        result.remove(result.size() - 1, 1);
+    }
+    if (result.endsWith(",")) {
+        result.remove(result.size() - 1, 1);
+    }
+    return result;
+}
+
+static void output_font(SkTypeface* face, const char* name, SkTypeface::Style style,
+        const char* used, FILE* out) {
+    int emSize = face->getUnitsPerEm() * 2;
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    paint.setTextAlign(SkPaint::kLeft_Align);
+    paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
+    paint.setTextSize(emSize);
+    SkSafeUnref(paint.setTypeface(face));
+    SkTDArray<SkPath::Verb> verbs;
+    SkTDArray<unsigned> charCodes;
+    SkTDArray<SkScalar> widths;
+    SkString ptsOut;
+    output_path_data(paint, used, emSize, &ptsOut, &verbs, &charCodes, &widths);
+    SkString fontnameStr(name);
+    SkString strippedStr = strip_spaces(fontnameStr);
+    strippedStr.appendf("%s", gStyleName[style]);
+    const char* fontname = strippedStr.c_str();
+    fprintf(out, "const SkScalar %sPoints[] = {\n", fontname);
+    ptsOut = strip_final(ptsOut);
+    fprintf(out, "%s", ptsOut.c_str());
+    fprintf(out, "\n};\n\n");
+    fprintf(out, "const unsigned char %sVerbs[] = {\n", fontname);
+    int verbCount = verbs.count();
+    int outChCount = 0;
+    for (int index = 0; index < verbCount;) {
+        SkPath::Verb verb = verbs[index];
+        SkASSERT(verb >= SkPath::kMove_Verb && verb <= SkPath::kDone_Verb);
+        SkASSERT((unsigned) verb == (unsigned char) verb);
+        fprintf(out, "%u", verb);
+        if (++index < verbCount) {
+            outChCount += 3;
+            fprintf(out, "%c", ',');
+            if (outChCount >= kMaxLineLength) {
+                outChCount = 0;
+                fprintf(out, "%c", '\n');
+            } else {
+                fprintf(out, "%c", ' ');
+            }
+        }
+    }
+    fprintf(out, "\n};\n\n");
+    
+    fprintf(out, "const unsigned %sCharCodes[] = {\n", fontname);
+    int offsetCount = charCodes.count();
+    for (int index = 0; index < offsetCount;) {
+        unsigned offset = charCodes[index];
+        fprintf(out, "%u", offset);
+        if (++index < offsetCount) {
+            outChCount += offset_str_len(offset) + 2;
+            fprintf(out, "%c", ',');
+            if (outChCount >= kMaxLineLength) {
+                outChCount = 0;
+                fprintf(out, "%c", '\n');
+            } else {
+                fprintf(out, "%c", ' ');
+            }
+        }
+    }
+    fprintf(out, "\n};\n\n");
+    
+    SkString widthsStr;
+    fprintf(out, "const SkFixed %sWidths[] = {\n", fontname);
+    for (int index = 0; index < offsetCount; ++index) {
+        output_fixed(widths[index], emSize, &widthsStr);
+    }
+    widthsStr = strip_final(widthsStr);
+    fprintf(out, "%s\n};\n\n", widthsStr.c_str());
+    
+    fprintf(out, "const int %sCharCodesCount = (int) SK_ARRAY_COUNT(%sCharCodes);\n\n",
+            fontname, fontname);
+
+    SkPaint::FontMetrics metrics;
+    paint.getFontMetrics(&metrics);
+    fprintf(out, "const SkPaint::FontMetrics %sMetrics = {\n", fontname);
+    SkString metricsStr;
+    metricsStr.printf("0x%08x, ", metrics.fFlags);
+    output_scalar(metrics.fTop, emSize, &metricsStr);
+    output_scalar(metrics.fAscent, emSize, &metricsStr);
+    output_scalar(metrics.fDescent, emSize, &metricsStr);
+    output_scalar(metrics.fBottom, emSize, &metricsStr);
+    output_scalar(metrics.fLeading, emSize, &metricsStr);
+    output_scalar(metrics.fAvgCharWidth, emSize, &metricsStr);
+    output_scalar(metrics.fMaxCharWidth, emSize, &metricsStr);
+    output_scalar(metrics.fXMin, emSize, &metricsStr);
+    output_scalar(metrics.fXMax, emSize, &metricsStr);
+    output_scalar(metrics.fXHeight, emSize, &metricsStr);
+    output_scalar(metrics.fCapHeight, emSize, &metricsStr);
+    output_scalar(metrics.fUnderlineThickness, emSize, &metricsStr);
+    output_scalar(metrics.fUnderlinePosition, emSize, &metricsStr);
+    metricsStr = strip_final(metricsStr);
+    fprintf(out, "%s\n};\n\n", metricsStr.c_str());
+}
+
+struct FontWritten {
+    const char* fName;
+    SkTypeface::Style fStyle;
+};
+
+static SkTDArray<FontWritten> gWritten;
+
+static int written_index(const FontDesc& fontDesc) {
+    for (int index = 0; index < gWritten.count(); ++index) {
+        const FontWritten& writ = gWritten[index];
+        if (!strcmp(fontDesc.fFont, writ.fName) && fontDesc.fStyle == writ.fStyle) {
+            return index;
+        }
+    }
+    return -1;
+}
+
+static void generate_fonts(FILE* out) {
+    for (int index = 0; index < gFontsCount; ++index) {
+        FontDesc& fontDesc = gFonts[index];
+        int fontIndex = written_index(fontDesc);
+        if (fontIndex >= 0) {
+            fontDesc.fFontIndex = fontIndex;
+            continue;
+        }
+        SkTypeface* systemTypeface = SkTypeface::CreateFromName(fontDesc.fFont, fontDesc.fStyle);
+        SkASSERT(systemTypeface);
+        SkString filepath(GetResourcePath(fontDesc.fFile));
+        SkASSERT(sk_exists(filepath.c_str()));
+        SkTypeface* resourceTypeface = SkTypeface::CreateFromFile(filepath.c_str());
+        SkASSERT(resourceTypeface);
+        output_font(resourceTypeface, fontDesc.fFont, fontDesc.fStyle, fontDesc.fCharsUsed, out);
+        fontDesc.fFontIndex = gWritten.count();
+        FontWritten* writ = gWritten.append();
+        writ->fName = fontDesc.fFont;
+        writ->fStyle = fontDesc.fStyle;
+    }
+}
+
+static void generate_index(const char* defaultName, FILE* out) {
+    int fontCount = gWritten.count();
+    fprintf(out,
+            "static SkTestFontData gTestFonts[] = {\n");
+    int fontIndex;
+    for (fontIndex = 0; fontIndex < fontCount; ++fontIndex) {
+        const FontWritten& writ = gWritten[fontIndex];
+        const char* name = writ.fName;
+        SkString strippedStr = strip_spaces(SkString(name));
+        strippedStr.appendf("%s", gStyleName[writ.fStyle]);
+        const char* strip = strippedStr.c_str();
+        fprintf(out,
+                "    {    %sPoints, %sVerbs, %sCharCodes,\n"
+                "         %sCharCodesCount, %sWidths,\n"
+                "         %sMetrics, \"%s\", SkTypeface::%s, NULL\n"
+                "    },\n",
+                strip, strip, strip, strip, strip, strip, name, gStyleName[writ.fStyle]);
+    }
+    fprintf(out, "};\n\n");
+    fprintf(out, "const int gTestFontsCount = (int) SK_ARRAY_COUNT(gTestFonts);\n\n");
+    fprintf(out,
+                "struct SubFont {\n"
+                "    const char* fName;\n"
+                "    SkTypeface::Style fStyle;\n"
+                "    SkTestFontData& fFont;\n"
+                "    const char* fFile;\n"
+                "};\n\n"
+                "const SubFont gSubFonts[] = {\n");
+    int defaultIndex = -1;
+    for (int subIndex = 0; subIndex < gFontsCount; subIndex++) {
+        const FontDesc& desc = gFonts[subIndex];
+        if (!strcmp(defaultName, desc.fName)) {
+            defaultIndex = subIndex;
+        }
+        fprintf(out,
+                "    { \"%s\", SkTypeface::%s, gTestFonts[%d], \"%s\"},\n", desc.fName,
+                gStyleName[desc.fStyle], desc.fFontIndex, desc.fFile);
+    }
+    fprintf(out, "};\n\n");
+    fprintf(out, "const int gSubFontsCount = (int) SK_ARRAY_COUNT(gSubFonts);\n\n");
+    SkASSERT(defaultIndex >= 0);
+    fprintf(out, "const int gDefaultFontIndex = %d;\n", defaultIndex);
+}
+
+int main(int , char * const []) {
+#ifndef SK_BUILD_FOR_MAC
+    #error "use fonts installed on Mac"
+#endif
+    FILE* out = font_header();
+    generate_fonts(out);
+    generate_index(DEFAULT_FONT_NAME, out);
+    fclose(out);
+    return 0;
+}
diff --git a/tools/dump_record.cpp b/tools/dump_record.cpp
index 4fb1cf5..fc2e102 100644
--- a/tools/dump_record.cpp
+++ b/tools/dump_record.cpp
@@ -57,11 +57,12 @@
             SkDebugf("Could not read %s as an SkPicture.\n", FLAGS_skps[i]);
             exit(1);
         }
-        const int w = src->width(), h = src->height();
+        const int w = SkScalarCeilToInt(src->cullRect().width());
+        const int h = SkScalarCeilToInt(src->cullRect().height());
 
         SkRecord record;
         SkRecorder canvas(&record, w, h);
-        src->draw(&canvas);
+        src->playback(&canvas);
 
         if (FLAGS_optimize) {
             SkRecordOptimize(&record);
diff --git a/tools/filtermain.cpp b/tools/filtermain.cpp
index 2a404f9..87d68ff 100644
--- a/tools/filtermain.cpp
+++ b/tools/filtermain.cpp
@@ -13,7 +13,6 @@
 #include "SkImageEncoder.h"
 #include "SkOSFile.h"
 #include "SkPicture.h"
-#include "SkPicturePlayback.h"
 #include "SkPictureRecord.h"
 #include "SkPictureRecorder.h"
 #include "SkStream.h"
@@ -85,7 +84,7 @@
     const SkPaint* saveLayerPaint = saveLayer->paint();
 
     // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed
-    if (NULL != saveLayerPaint) {
+    if (saveLayerPaint) {
         SkDrawBitmapRectCommand* dbmr =
             (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+1);
         SkPaint* dbmrPaint = dbmr->paint();
@@ -93,7 +92,7 @@
         if (NULL == dbmrPaint) {
             // if the DBMR doesn't have a paint just use the saveLayer's
             dbmr->setPaint(*saveLayerPaint);
-        } else if (NULL != saveLayerPaint) {
+        } else if (saveLayerPaint) {
             // Both paints are present so their alphas need to be combined
             SkColor color = saveLayerPaint->getColor();
             int a0 = SkColorGetA(color);
@@ -163,7 +162,7 @@
     const SkPaint* saveLayerPaint = saveLayer->paint();
 
     // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed
-    if (NULL != saveLayerPaint) {
+    if (saveLayerPaint) {
         SkDrawBitmapRectCommand* dbmr =
             (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+3);
         SkPaint* dbmrPaint = dbmr->paint();
@@ -424,8 +423,8 @@
     const SkPaint* saveLayerPaint0 = saveLayer0->paint();
     const SkPaint* saveLayerPaint1 = saveLayer1->paint();
 
-    if ((NULL != saveLayerPaint0 && !is_simple(*saveLayerPaint0)) ||
-        (NULL != saveLayerPaint1 && !is_simple(*saveLayerPaint1))) {
+    if ((saveLayerPaint0 && !is_simple(*saveLayerPaint0)) ||
+        (saveLayerPaint1 && !is_simple(*saveLayerPaint1))) {
         return false;
     }
 
@@ -435,14 +434,14 @@
         return true;
     }
 
-    if (NULL != saveLayerPaint0) {
+    if (saveLayerPaint0) {
         SkColor layerColor0 = saveLayerPaint0->getColor() | 0xFF000000; // force opaque
         if (dbmrPaint->getColor() != layerColor0) {
             return false;
         }
     }
 
-    if (NULL != saveLayerPaint1) {
+    if (saveLayerPaint1) {
         SkColor layerColor1 = saveLayerPaint1->getColor() | 0xFF000000; // force opaque
         if (dbmrPaint->getColor() != layerColor1) {
             return false;
@@ -478,7 +477,7 @@
     int a0, a1;
 
     const SkPaint* saveLayerPaint0 = saveLayer0->paint();
-    if (NULL != saveLayerPaint0) {
+    if (saveLayerPaint0) {
         color = saveLayerPaint0->getColor();
         a0 = SkColorGetA(color);
     } else {
@@ -486,7 +485,7 @@
     }
 
     const SkPaint* saveLayerPaint1 = saveLayer1->paint();
-    if (NULL != saveLayerPaint1) {
+    if (saveLayerPaint1) {
         color = saveLayerPaint1->getColor();
         a1 = SkColorGetA(color);
     } else {
@@ -498,7 +497,7 @@
 
     SkPaint* dbmrPaint = dbmr->paint();
 
-    if (NULL != dbmrPaint) {
+    if (dbmrPaint) {
         SkColor newColor = SkColorSetA(dbmrPaint->getColor(), newA);
         dbmrPaint->setColor(newColor);
     } else {
@@ -580,7 +579,7 @@
 
     SkScalar newSrcLeft, newSrcTop;
 
-    if (NULL != dbmr->srcRect()) {
+    if (dbmr->srcRect()) {
         newSrcLeft = dbmr->srcRect()->fLeft + clip->rect().fLeft - dbmr->dstRect().fLeft;
         newSrcTop  = dbmr->srcRect()->fTop + clip->rect().fTop - dbmr->dstRect().fTop;
     } else {
@@ -678,9 +677,9 @@
 
     memset(localCount, 0, sizeof(localCount));
 
-    SkDebugCanvas debugCanvas(inPicture->width(), inPicture->height());
-    debugCanvas.setBounds(inPicture->width(), inPicture->height());
-    inPicture->draw(&debugCanvas);
+    SkDebugCanvas debugCanvas(SkScalarCeilToInt(inPicture->cullRect().width()), 
+                              SkScalarCeilToInt(inPicture->cullRect().height()));
+    inPicture->playback(&debugCanvas);
 
     // delete the initial save and restore since replaying the commands will
     // re-add them
@@ -718,7 +717,9 @@
 
     if (!outFile.isEmpty()) {
         SkPictureRecorder recorder;
-        SkCanvas* canvas = recorder.beginRecording(inPicture->width(), inPicture->height(), NULL, 0);
+        SkCanvas* canvas = recorder.beginRecording(inPicture->cullRect().width(), 
+                                                   inPicture->cullRect().height(), 
+                                                   NULL, 0);
         debugCanvas.draw(canvas);
         SkAutoTUnref<SkPicture> outPicture(recorder.endRecording());
 
@@ -817,9 +818,9 @@
     if (iter.next(&inputFilename)) {
 
         do {
-            inFile = SkOSPath::SkPathJoin(inDir.c_str(), inputFilename.c_str());
+            inFile = SkOSPath::Join(inDir.c_str(), inputFilename.c_str());
             if (!outDir.isEmpty()) {
-                outFile = SkOSPath::SkPathJoin(outDir.c_str(), inputFilename.c_str());
+                outFile = SkOSPath::Join(outDir.c_str(), inputFilename.c_str());
             }
             SkDebugf("Executing %s\n", inputFilename.c_str());
             filter_picture(inFile, outFile);
diff --git a/tools/fix_pythonpath.py b/tools/fix_pythonpath.py
new file mode 100644
index 0000000..c84738a
--- /dev/null
+++ b/tools/fix_pythonpath.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+"""Add the checkout root to sys.path, provide mechanisms for adding others."""
+
+
+import os
+import sys
+
+
+CHECKOUT_ROOT = os.path.realpath(os.path.join(
+    os.path.dirname(os.path.abspath(__file__)), os.pardir))
+
+
+def add_to_pythonpath(path):
+  """Add the given directory to PYTHONPATH."""
+  sys.path.append(path)
+
+
+add_to_pythonpath(CHECKOUT_ROOT)
+
diff --git a/tools/flags/SkCommandLineFlags.cpp b/tools/flags/SkCommandLineFlags.cpp
index 9b31b65..c25fec5 100644
--- a/tools/flags/SkCommandLineFlags.cpp
+++ b/tools/flags/SkCommandLineFlags.cpp
@@ -8,7 +8,7 @@
 #include "SkCommandLineFlags.h"
 #include "SkTDArray.h"
 
-DEFINE_string(undefok, "", "Silently ignore unknown flags listed here instead of crashing.");
+DEFINE_bool(undefok, false, "Silently ignore unknown flags instead of crashing.");
 
 bool SkFlagInfo::CreateStringFlag(const char* name, const char* shortName,
                                   SkCommandLineFlags::StringArray* pStrings,
@@ -287,11 +287,7 @@
                 flag = flag->next();
             }
             if (!flagMatched) {
-                SkString stripped(argv[i]);
-                while (stripped.startsWith('-')) {
-                    stripped.remove(0, 1);
-                }
-                if (!FLAGS_undefok.contains(stripped.c_str())) {
+                if (!FLAGS_undefok) {
                     SkDebugf("Got unknown flag \"%s\". Exiting.\n", argv[i]);
                     exit(-1);
                 }
diff --git a/tools/flags/SkCommandLineFlags.h b/tools/flags/SkCommandLineFlags.h
index 370198b..0fb0233 100644
--- a/tools/flags/SkCommandLineFlags.h
+++ b/tools/flags/SkCommandLineFlags.h
@@ -137,6 +137,10 @@
             return false;
         }
 
+        void set(int i, const char* str) {
+            fStrings[i].set(str);
+        }
+
     private:
         void reset() { fStrings.reset(); }
 
@@ -412,7 +416,7 @@
         , fStrings(NULL) {
         fNext = SkCommandLineFlags::gHead;
         SkCommandLineFlags::gHead = this;
-        SkASSERT(NULL != name && strlen(name) > 1);
+        SkASSERT(name && strlen(name) > 1);
         SkASSERT(NULL == shortName || 1 == strlen(shortName));
     }
 
diff --git a/tools/flags/SkCommonFlags.cpp b/tools/flags/SkCommonFlags.cpp
new file mode 100644
index 0000000..c8cd330
--- /dev/null
+++ b/tools/flags/SkCommonFlags.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 "SkCommonFlags.h"
+
+DEFINE_string(config, "565 8888 pdf gpu nonrendering angle",
+              "Options: 565 8888 pdf gpu nonrendering msaa4 msaa16 nvprmsaa4 nvprmsaa16 "
+              "gpunull gpudebug angle mesa");
+
+DEFINE_bool(cpu, true, "master switch for running CPU-bound work.");
+
+DEFINE_bool(dryRun, false,
+            "just print the tests that would be run, without actually running them.");
+
+DEFINE_bool(gpu, true, "master switch for running GPU-bound work.");
+
+DEFINE_string(gpuAPI, "", "Force use of specific gpu API.  Using \"gl\" "
+              "forces OpenGL API. Using \"gles\" forces OpenGL ES API. "
+              "Defaults to empty string, which selects the API native to the "
+              "system.");
+
+DEFINE_bool2(leaks, l, false, "show leaked ref cnt'd objects.");
+
+DEFINE_string2(match, m, NULL,
+               "[~][^]substring[$] [...] of GM name to run.\n"
+               "Multiple matches may be separated by spaces.\n"
+               "~ causes a matching GM to always be skipped\n"
+               "^ requires the start of the GM to match\n"
+               "$ requires the end of the GM to match\n"
+               "^ and $ requires an exact match\n"
+               "If a GM does not match any list entry,\n"
+               "it is skipped unless some list entry starts with ~");
+
+DEFINE_bool2(quiet, q, false, "if true, don't print status updates.");
+
+DEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each test.");
+DEFINE_bool(abandonGpuContext, false, "Abandon the GrContext after running each test. "
+                                      "Implies --resetGpuContext.");
+
+DEFINE_string(skps, "skps", "Directory to read skps from.");
+
+DEFINE_int32(threads, 0, "Run threadsafe tests on a threadpool with this many threads, "
+                         "defaulting to one thread per core.");
+
+DEFINE_bool2(verbose, v, false, "enable verbose output from the test driver.");
+
+DEFINE_bool2(veryVerbose, V, false, "tell individual tests to be verbose.");
+
+DEFINE_string2(writePath, w, "", "If set, write bitmaps here as .pngs.");
+
+DEFINE_string(key, "",
+              "Space-separated key/value pairs to add to JSON identifying this builder.");
+DEFINE_string(properties, "",
+              "Space-separated key/value pairs to add to JSON identifying this run.");
+
diff --git a/tools/flags/SkCommonFlags.h b/tools/flags/SkCommonFlags.h
new file mode 100644
index 0000000..661501a
--- /dev/null
+++ b/tools/flags/SkCommonFlags.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SK_COMMON_FLAGS_H
+#define SK_COMMON_FLAGS_H
+
+#include "SkCommandLineFlags.h"
+
+DECLARE_string(config);
+DECLARE_bool(cpu);
+DECLARE_bool(dryRun);
+DECLARE_bool(gpu);
+DECLARE_string(gpuAPI);
+DECLARE_bool(leaks);
+DECLARE_string(match);
+DECLARE_bool(quiet);
+DECLARE_bool(resetGpuContext);
+DECLARE_bool(abandonGpuContext);
+DECLARE_string(skps);
+DECLARE_int32(threads);
+DECLARE_string(resourcePath);
+DECLARE_bool(verbose);
+DECLARE_bool(veryVerbose);
+DECLARE_string(writePath);
+
+DECLARE_string(key);
+DECLARE_string(properties);
+
+#endif
diff --git a/tools/gen_bench_expectations_from_codereview.py b/tools/gen_bench_expectations_from_codereview.py
index 3d40aa6..f0463fe 100644
--- a/tools/gen_bench_expectations_from_codereview.py
+++ b/tools/gen_bench_expectations_from_codereview.py
@@ -10,21 +10,25 @@
 
 import collections
 import compare_codereview
+import json
 import os
 import re
 import shutil
 import subprocess
 import sys
+import urllib2
 
 
-BENCH_DATA_URL = 'gs://chromium-skia-gm/perfdata/%s/%s/*'
+BENCH_DATA_URL = 'gs://chromium-skia-gm/perfdata/%s/%s/bench_*_data_*'
+BUILD_STATUS_SUCCESS = 0
+BUILD_STATUS_WARNINGS = 1
 CHECKOUT_PATH = os.path.realpath(os.path.join(
     os.path.dirname(os.path.abspath(__file__)), os.pardir))
 TMP_BENCH_DATA_DIR = os.path.join(CHECKOUT_PATH, '.bench_data')
 
 
 TryBuild = collections.namedtuple(
-    'TryBuild', ['builder_name', 'build_number', 'is_finished'])
+    'TryBuild', ['builder_name', 'build_number', 'is_finished', 'json_url'])
 
 
 def find_all_builds(codereview_url):
@@ -40,12 +44,19 @@
   try_builds = []
   for builder, data in results.iteritems():
     if builder.startswith('Perf'):
-      build_num = data.url.split('/')[-1] if data.url else None
+      build_num = None
+      json_url = None
+      if data.url:
+        split_url = data.url.split('/')
+        build_num = split_url[-1]
+        split_url.insert(split_url.index('builders'), 'json')
+        json_url = '/'.join(split_url)
       is_finished = (data.status not in ('pending', 'try-pending') and
                      build_num is not None)
       try_builds.append(TryBuild(builder_name=builder,
                                  build_number=build_num,
-                                 is_finished=is_finished))
+                                 is_finished=is_finished,
+                                 json_url=json_url))
   return try_builds
 
 
@@ -85,9 +96,7 @@
       dest_dir: string; destination directory for the bench data.
   """
   url = BENCH_DATA_URL % (builder, build_num)
-  subprocess.check_call(['gsutil', 'cp', '-R', url, dest_dir],
-                         stdout=subprocess.PIPE,
-                         stderr=subprocess.PIPE)
+  subprocess.check_call(['gsutil', 'cp', '-R', url, dest_dir])
 
 
 def find_revision_from_downloaded_data(dest_dir):
@@ -111,8 +120,32 @@
   pass
 
 
+def _step_succeeded(try_build, step_name):
+  """Return True if the given step succeeded and False otherwise.
+
+  This function talks to the build master's JSON interface, which is slow.
+
+  TODO(borenet): There are now a few places which talk to the master's JSON
+  interface. Maybe it'd be worthwhile to create a module which does this.
+
+  Args:
+      try_build: TryBuild instance; the build we're concerned about.
+      step_name: string; name of the step we're concerned about.
+  """
+  step_url = '/'.join((try_build.json_url, 'steps', step_name))
+  step_data = json.load(urllib2.urlopen(step_url))
+  # step_data['results'] may not be present if the step succeeded. If present,
+  # it is a list whose first element is a result code, per the documentation:
+  # http://docs.buildbot.net/latest/developer/results.html
+  result = step_data.get('results', [BUILD_STATUS_SUCCESS])[0]
+  if result in (BUILD_STATUS_SUCCESS, BUILD_STATUS_WARNINGS):
+    return True
+  return False
+
+
 def gen_bench_expectations_from_codereview(codereview_url,
-                                           error_on_unfinished=True):
+                                           error_on_unfinished=True,
+                                           error_on_try_failure=True):
   """Generate bench expectations from a code review.
 
   Scans the given code review for Perf trybot runs. Downloads the results of
@@ -122,6 +155,8 @@
   Args:
       url: string; URL of the code review.
       error_on_unfinished: bool; throw an error if any trybot has not finished.
+      error_on_try_failure: bool; throw an error if any trybot failed an
+          important step.
   """
   try_builds = find_all_builds(codereview_url)
 
@@ -129,14 +164,32 @@
   if error_on_unfinished and not _all_trybots_finished(try_builds):
     raise TrybotNotFinishedError('Not all trybots have finished.')
 
+  failed_run = []
   failed_data_pull = []
   failed_gen_expectations = []
 
+  # Don't even try to do anything if BenchPictures, PostBench, or
+  # UploadBenchResults failed.
+  for try_build in try_builds:
+    for step in ('BenchPictures', 'PostBench', 'UploadBenchResults'):
+      if not _step_succeeded(try_build, step):
+        msg = '%s failed on %s!' % (step, try_build.builder_name)
+        if error_on_try_failure:
+          raise Exception(msg)
+        print 'WARNING: %s Skipping.' % msg
+        failed_run.append(try_build.builder_name)
+
   if os.path.isdir(TMP_BENCH_DATA_DIR):
     shutil.rmtree(TMP_BENCH_DATA_DIR)
 
   for try_build in try_builds:
     try_builder = try_build.builder_name
+
+    # Even if we're not erroring out on try failures, we can't generate new
+    # expectations for failed bots.
+    if try_builder in failed_run:
+      continue
+
     builder = try_builder.replace('-Trybot', '')
 
     # Download the data.
diff --git a/tools/git-sync-deps b/tools/git-sync-deps
index ee37e63..1d626d0 100755
--- a/tools/git-sync-deps
+++ b/tools/git-sync-deps
@@ -35,7 +35,25 @@
 import sys
 import threading
 
-from git_utils import git_executable
+
+def git_executable():
+  """Find the git executable.
+
+  Returns:
+      A string suitable for passing to subprocess functions, or None.
+  """
+  envgit = os.environ.get('GIT_EXECUTABLE')
+  searchlist = ['git', 'git.exe', 'git.bat']
+  if envgit:
+    searchlist.insert(0, envgit)
+  with open(os.devnull, 'w') as devnull:
+    for git in searchlist:
+      try:
+        subprocess.call([git, '--version'], stdout=devnull)
+      except (OSError,):
+        continue
+      return git
+  return None
 
 
 DEFAULT_DEPS_PATH = os.path.normpath(
@@ -130,38 +148,29 @@
   return dictionary
 
 
-class DepsError(Exception):
-  """Raised if deps_os is a bad key.
-  """
-  pass
-
-
-def git_sync_deps(deps_file_path, deps_os_list, verbose):
+def git_sync_deps(deps_file_path, command_line_os_requests, verbose):
   """Grab dependencies, with optional platform support.
 
   Args:
     deps_file_path (string) Path to the DEPS file.
 
-    deps_os_list (list of strings) Can be empty list.  List of
-                 strings that should each be a key in the deps_os
-                 dictionary in the DEPS file.
+    command_line_os_requests (list of strings) Can be empty list.
+        List of strings that should each be a key in the deps_os
+        dictionary in the DEPS file.
 
-  Raises DepsError exception and git Exceptions.
+  Raises git Exceptions.
   """
   git = git_executable()
   assert git
 
   deps_file_directory = os.path.dirname(deps_file_path)
-  deps = parse_file_to_dict(deps_file_path)
-  dependencies = deps['deps'].copy()
-  for deps_os in deps_os_list:
+  deps_file = parse_file_to_dict(deps_file_path)
+  dependencies = deps_file['deps'].copy()
+  os_specific_dependencies = deps_file.get('deps_os', [])
+  for os_name in command_line_os_requests:
     # Add OS-specific dependencies
-    if deps_os not in deps['deps_os']:
-      raise DepsError(
-        'Argument "%s" not found within deps_os keys %r' %
-        (deps_os, deps['deps_os'].keys()))
-    for dep in deps['deps_os'][deps_os]:
-      dependencies[dep] = deps['deps_os'][deps_os][dep]
+    if os_name in os_specific_dependencies:
+      dependencies.update(os_specific_dependencies[os_name])
   list_of_arg_lists = []
   for directory in dependencies:
     if '@' in dependencies[directory]:
@@ -176,6 +185,10 @@
 
   multithread(git_checkout_to_directory, list_of_arg_lists)
 
+  for directory in deps_file.get('recursedeps', []):
+    recursive_path = os.path.join(deps_file_directory, directory, 'DEPS')
+    git_sync_deps(recursive_path, command_line_os_requests, verbose)
+
 
 def multithread(function, list_of_arg_lists):
   # for args in list_of_arg_lists:
@@ -193,13 +206,14 @@
 def main(argv):
   deps_file_path = os.environ.get('GIT_SYNC_DEPS_PATH', DEFAULT_DEPS_PATH)
   verbose = not bool(os.environ.get('GIT_SYNC_DEPS_QUIET', False))
-  try:
-    git_sync_deps(deps_file_path, argv, verbose)
-    return 0
-  except DepsError:
+
+  if '--help' in argv or '-h' in argv:
     usage(deps_file_path)
     return 1
 
+  git_sync_deps(deps_file_path, argv, verbose)
+  return 0
+
 
 if __name__ == '__main__':
   exit(main(sys.argv[1:]))
diff --git a/tools/git_utils.py b/tools/git_utils.py
deleted file mode 100644
index a35c85e..0000000
--- a/tools/git_utils.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright 2014 Google Inc.
-#
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Module to host the ChangeGitBranch class and test_git_executable function.
-"""
-
-import os
-import subprocess
-
-import misc_utils
-
-
-class ChangeGitBranch(object):
-    """Class to manage git branches.
-
-    This class allows one to create a new branch in a repository based
-    off of a given commit, and restore the original tree state.
-
-    Assumes current working directory is a git repository.
-
-    Example:
-        with ChangeGitBranch():
-            edit_files(files)
-            git_add(files)
-            git_commit()
-            git_format_patch('HEAD~')
-        # At this point, the repository is returned to its original
-        # state.
-
-    Constructor Args:
-        branch_name: (string) if not None, the name of the branch to
-            use.  If None, then use a temporary branch that will be
-            deleted.  If the branch already exists, then a different
-            branch name will be created.  Use git_branch_name() to
-            find the actual branch name used.
-        upstream_branch: (string) if not None, the name of the branch or
-            commit to branch from.  If None, then use origin/master
-        verbose: (boolean) if true, makes debugging easier.
-
-    Raises:
-        OSError: the git executable disappeared.
-        subprocess.CalledProcessError: git returned unexpected status.
-        Exception: if the given branch name exists, or if the repository
-            isn't clean on exit, or git can't be found.
-    """
-    # pylint: disable=I0011,R0903,R0902
-
-    def __init__(self,
-                 branch_name=None,
-                 upstream_branch=None,
-                 verbose=False):
-        # pylint: disable=I0011,R0913
-        if branch_name:
-            self._branch_name = branch_name
-            self._delete_branch = False
-        else:
-            self._branch_name = 'ChangeGitBranchTempBranch'
-            self._delete_branch = True
-
-        if upstream_branch:
-            self._upstream_branch = upstream_branch
-        else:
-            self._upstream_branch = 'origin/master'
-
-        self._git = git_executable()
-        if not self._git:
-            raise Exception('Git can\'t be found.')
-
-        self._stash = None
-        self._original_branch = None
-        self._vsp = misc_utils.VerboseSubprocess(verbose)
-
-    def _has_git_diff(self):
-        """Return true iff repository has uncommited changes."""
-        return bool(self._vsp.call([self._git, 'diff', '--quiet', 'HEAD']))
-
-    def _branch_exists(self, branch):
-        """Return true iff branch exists."""
-        return 0 == self._vsp.call([self._git, 'show-ref', '--quiet', branch])
-
-    def __enter__(self):
-        git, vsp = self._git, self._vsp
-
-        if self._branch_exists(self._branch_name):
-            i, branch_name = 0, self._branch_name
-            while self._branch_exists(branch_name):
-                i += 1
-                branch_name = '%s_%03d' % (self._branch_name, i)
-            self._branch_name = branch_name
-
-        self._stash = self._has_git_diff()
-        if self._stash:
-            vsp.check_call([git, 'stash', 'save'])
-        self._original_branch = git_branch_name(vsp.verbose)
-        vsp.check_call(
-            [git, 'checkout', '-q', '-b',
-             self._branch_name, self._upstream_branch])
-
-    def __exit__(self, etype, value, traceback):
-        git, vsp = self._git, self._vsp
-
-        if self._has_git_diff():
-            status = vsp.check_output([git, 'status', '-s'])
-            raise Exception('git checkout not clean:\n%s' % status)
-        vsp.check_call([git, 'checkout', '-q', self._original_branch])
-        if self._stash:
-            vsp.check_call([git, 'stash', 'pop'])
-        if self._delete_branch:
-            assert self._original_branch != self._branch_name
-            vsp.check_call([git, 'branch', '-D', self._branch_name])
-
-
-def git_branch_name(verbose=False):
-    """Return a description of the current branch.
-
-    Args:
-        verbose: (boolean) makes debugging easier
-
-    Returns:
-        A string suitable for passing to `git checkout` later.
-    """
-    git = git_executable()
-    vsp = misc_utils.VerboseSubprocess(verbose)
-    try:
-        full_branch = vsp.strip_output([git, 'symbolic-ref', 'HEAD'])
-        return full_branch.split('/')[-1]
-    except (subprocess.CalledProcessError,):
-        # "fatal: ref HEAD is not a symbolic ref"
-        return vsp.strip_output([git, 'rev-parse', 'HEAD'])
-
-
-def test_git_executable(git):
-    """Test the git executable.
-
-    Args:
-        git: git executable path.
-    Returns:
-        True if test is successful.
-    """
-    with open(os.devnull, 'w') as devnull:
-        try:
-            subprocess.call([git, '--version'], stdout=devnull)
-        except (OSError,):
-            return False
-    return True
-
-
-def git_executable():
-    """Find the git executable.
-
-    If the GIT_EXECUTABLE environment variable is set, that will
-    override whatever is found in the PATH.
-
-    If no suitable executable is found, return None
-
-    Returns:
-        A string suiable for passing to subprocess functions, or None.
-    """
-    env_git = os.environ.get('GIT_EXECUTABLE')
-    if env_git and test_git_executable(env_git):
-        return env_git
-    for git in ('git', 'git.exe', 'git.bat'):
-        if test_git_executable(git):
-            return git
-    return None
-
diff --git a/tools/gpuveto.cpp b/tools/gpuveto.cpp
index 68f343b..4e9fdeb 100644
--- a/tools/gpuveto.cpp
+++ b/tools/gpuveto.cpp
@@ -55,7 +55,9 @@
     // The SkPicture tracking information is only generated during recording
     // an isn't serialized. Replay the picture to regenerated the tracking data.
     SkPictureRecorder recorder;
-    picture->draw(recorder.beginRecording(picture->width(), picture->height(), NULL, 0));
+    picture->playback(recorder.beginRecording(picture->cullRect().width(), 
+                                              picture->cullRect().height(), 
+                                              NULL, 0));
     SkAutoTUnref<SkPicture> recorded(recorder.endRecording());
 
     if (recorded->suitableForGpuRasterization(NULL)) {
diff --git a/tools/iOSShell.cpp b/tools/iOSShell.cpp
new file mode 100644
index 0000000..8656e64
--- /dev/null
+++ b/tools/iOSShell.cpp
@@ -0,0 +1,101 @@
+/*
+ * 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 "iOSShell.h"
+
+#include "Resources.h"
+#include "SkApplication.h"
+#include "SkCanvas.h"
+#include "SkCommonFlags.h"
+#include "SkGraphics.h"
+#include "SkWindow.h"
+#include "sk_tool_utils.h"
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* curr_view(SkWindow* wind) {
+    SkView::F2BIter iter(wind);
+    return iter.next();
+}
+
+ShellWindow::ShellWindow(void* hwnd, int argc, char** argv)
+    : INHERITED(hwnd) {
+    SkCommandLineFlags::Parse(argc, argv);
+}
+
+ShellWindow::~ShellWindow() {
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool ShellWindow::onDispatchClick(int x, int y, Click::State state,
+        void* owner, unsigned modi) {
+    int w = SkScalarRoundToInt(this->width());
+    int h = SkScalarRoundToInt(this->height());
+
+    // check for the resize-box
+    if (w - x < 16 && h - y < 16) {
+        return false;   // let the OS handle the click
+    } else {
+        return this->INHERITED::onDispatchClick(x, y, state, owner, modi);
+    }
+}
+
+void ShellWindow::onSizeChange() {
+    this->INHERITED::onSizeChange();
+
+    SkView::F2BIter iter(this);
+    SkView* view = iter.next();
+    view->setSize(this->width(), this->height());
+}
+
+DEFINE_bool(dm, false, "run dm");
+DEFINE_bool(nanobench, false, "run nanobench");
+
+int nanobench_main();
+int dm_main();
+
+IOS_launch_type set_cmd_line_args(int argc, char *argv[], const char* resourceDir) {
+    SkCommandLineFlags::Parse(argc, argv);
+    SetResourcePath(resourceDir);
+    if (FLAGS_nanobench) {
+        return nanobench_main() ? kError_iOSLaunchType : kTool_iOSLaunchType;
+    }
+    if (FLAGS_dm) {
+        return dm_main() ? kError_iOSLaunchType : kTool_iOSLaunchType;
+    }
+    return kError_iOSLaunchType;
+}
+
+// FIXME: this should be in a header
+SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv);
+SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
+    return new ShellWindow(hwnd, argc, argv);
+}
+
+// FIXME: this should be in a header
+void get_preferred_size(int* x, int* y, int* width, int* height);
+void get_preferred_size(int* x, int* y, int* width, int* height) {
+    *x = 10;
+    *y = 50;
+    *width = 640;
+    *height = 480;
+}
+
+// FIXME: this should be in a header
+void application_init();
+void application_init() {
+    SkGraphics::Init();
+    SkEvent::Init();
+}
+
+// FIXME: this should be in a header
+void application_term();
+void application_term() {
+    SkEvent::Term();
+    SkGraphics::Term();
+}
diff --git a/tools/iOSShell.h b/tools/iOSShell.h
new file mode 100644
index 0000000..a0a0a5e
--- /dev/null
+++ b/tools/iOSShell.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014 Skia
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef iOSShell_DEFINED
+#define iOSShell_DEFINED
+
+#include "SkWindow.h"
+
+class SkCanvas;
+class SkEvent;
+class SkViewFactory;
+
+class ShellWindow : public SkOSWindow {
+public:
+    ShellWindow(void* hwnd, int argc, char** argv);
+    virtual ~ShellWindow();
+
+protected:
+    virtual void onSizeChange() SK_OVERRIDE;
+
+    virtual bool onDispatchClick(int x, int y, Click::State, void* owner,
+                                 unsigned modi) SK_OVERRIDE;
+
+private:
+    typedef SkOSWindow INHERITED;
+};
+
+#endif
diff --git a/tools/image_expectations.cpp b/tools/image_expectations.cpp
index ac232e9..05a905d 100644
--- a/tools/image_expectations.cpp
+++ b/tools/image_expectations.cpp
@@ -28,7 +28,9 @@
  * output module.
  */
 const static char kJsonKey_ActualResults[] = "actual-results";
+const static char kJsonKey_Descriptions[] = "descriptions";
 const static char kJsonKey_ExpectedResults[] = "expected-results";
+const static char kJsonKey_ImageBaseGSUrl[] = "image-base-gs-url";
 const static char kJsonKey_Header[] = "header";
 const static char kJsonKey_Header_Type[] = "type";
 const static char kJsonKey_Header_Revision[] = "revision";
@@ -52,44 +54,69 @@
 
     // ImageDigest class...
 
-    ImageDigest::ImageDigest(const SkBitmap &bitmap) {
-        if (!SkBitmapHasher::ComputeDigest(bitmap, &fHashValue)) {
-            SkFAIL("unable to compute image digest");
-        }
-    }
+    ImageDigest::ImageDigest(const SkBitmap &bitmap) :
+        fBitmap(bitmap), fHashValue(0), fComputedHashValue(false) {}
 
-    ImageDigest::ImageDigest(const SkString &hashType, uint64_t hashValue) {
+    ImageDigest::ImageDigest(const SkString &hashType, uint64_t hashValue) :
+        fBitmap(), fHashValue(hashValue), fComputedHashValue(true) {
         if (!hashType.equals(kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5)) {
-            SkFAIL((SkString("unsupported hashType ")+=hashType).c_str());
-        } else {
-            fHashValue = hashValue;
+            SkDebugf("unsupported hashType '%s'\n", hashType.c_str());
+            SkFAIL("unsupported hashType (see above)");
         }
     }
 
-    SkString ImageDigest::getHashType() const {
+    bool ImageDigest::equals(ImageDigest &other) {
+        // TODO(epoger): The current implementation assumes that this
+        // and other always have hashType kJsonKey_Hashtype_Bitmap_64bitMD5
+        return (this->getHashValue() == other.getHashValue());
+    }
+
+    SkString ImageDigest::getHashType() {
         // TODO(epoger): The current implementation assumes that the
         // result digest is always of type kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 .
         return SkString(kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5);
     }
 
-    uint64_t ImageDigest::getHashValue() const {
-        return fHashValue;
+    uint64_t ImageDigest::getHashValue() {
+        if (!this->fComputedHashValue) {
+            if (!SkBitmapHasher::ComputeDigest(this->fBitmap, &this->fHashValue)) {
+                SkFAIL("unable to compute image digest");
+            }
+            this->fComputedHashValue = true;
+        }
+        return this->fHashValue;
     }
 
     // BitmapAndDigest class...
 
-    BitmapAndDigest::BitmapAndDigest(const SkBitmap &bitmap) : fBitmap(bitmap) {
-    }
+    BitmapAndDigest::BitmapAndDigest(const SkBitmap &bitmap) :
+        fBitmap(bitmap), fImageDigest(bitmap) {}
 
-    const ImageDigest *BitmapAndDigest::getImageDigestPtr() {
-        if (NULL == fImageDigestRef.get()) {
-            fImageDigestRef.reset(SkNEW_ARGS(ImageDigest, (fBitmap)));
-        }
-        return fImageDigestRef.get();
-    }
+    const SkBitmap *BitmapAndDigest::getBitmapPtr() const {return &fBitmap;}
 
-    const SkBitmap *BitmapAndDigest::getBitmapPtr() const {
-        return &fBitmap;
+    ImageDigest *BitmapAndDigest::getImageDigestPtr() {return &fImageDigest;}
+
+    // Expectation class...
+
+    // For when we need a valid ImageDigest, but we don't care what it is.
+    static const ImageDigest kDummyImageDigest(
+        SkString(kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5), 0);
+
+    Expectation::Expectation(bool ignoreFailure) :
+        fIsEmpty(true), fIgnoreFailure(ignoreFailure), fImageDigest(kDummyImageDigest) {}
+
+    Expectation::Expectation(const SkString &hashType, uint64_t hashValue, bool ignoreFailure) :
+        fIsEmpty(false), fIgnoreFailure(ignoreFailure), fImageDigest(hashType, hashValue) {}
+
+    Expectation::Expectation(const SkBitmap& bitmap, bool ignoreFailure) :
+        fIsEmpty(false), fIgnoreFailure(ignoreFailure), fImageDigest(bitmap) {}
+
+    bool Expectation::ignoreFailure() const { return this->fIgnoreFailure; }
+
+    bool Expectation::empty() const { return this->fIsEmpty; }
+
+    bool Expectation::matches(ImageDigest &imageDigest) {
+        return !(this->fIsEmpty) && (this->fImageDigest.equals(imageDigest));
     }
 
     // ImageResultsAndExpectations class...
@@ -135,19 +162,11 @@
     }
 
     void ImageResultsAndExpectations::add(const char *sourceName, const char *fileName,
-                                          const ImageDigest &digest, const int *tileNumber) {
+                                          ImageDigest &digest, const int *tileNumber) {
         // Get expectation, if any.
-        Json::Value expectedImage;
-        if (!fExpectedResults.isNull()) {
-            if (NULL == tileNumber) {
-                expectedImage = fExpectedResults[sourceName][kJsonKey_Source_WholeImage];
-            } else {
-                expectedImage = fExpectedResults[sourceName][kJsonKey_Source_TiledImages]
-                                                [*tileNumber];
-            }
-        }
+        Expectation expectation = this->getExpectation(sourceName, tileNumber);
 
-        // Fill in info about the actual result itself.
+        // Fill in info about the actual result.
         Json::Value actualChecksumAlgorithm = digest.getHashType().c_str();
         Json::Value actualChecksumValue = Json::UInt64(digest.getHashValue());
         Json::Value actualImage;
@@ -156,16 +175,15 @@
         actualImage[kJsonKey_Image_Filepath] = fileName;
 
         // Compare against expectedImage to fill in comparisonResult.
-        Json::Value comparisonResult = kJsonValue_Image_ComparisonResult_NoComparison;
-        if (!expectedImage.isNull()) {
-            if ((actualChecksumAlgorithm == expectedImage[kJsonKey_Image_ChecksumAlgorithm]) &&
-                (actualChecksumValue == expectedImage[kJsonKey_Image_ChecksumValue])) {
-                comparisonResult = kJsonValue_Image_ComparisonResult_Succeeded;
-            } else if (expectedImage[kJsonKey_Image_IgnoreFailure] == true) {
-                comparisonResult = kJsonValue_Image_ComparisonResult_FailureIgnored;
-            } else {
-                comparisonResult = kJsonValue_Image_ComparisonResult_Failed;
-            }
+        Json::Value comparisonResult;
+        if (expectation.empty()) {
+            comparisonResult = kJsonValue_Image_ComparisonResult_NoComparison;
+        } else if (expectation.matches(digest)) {
+            comparisonResult = kJsonValue_Image_ComparisonResult_Succeeded;
+        } else if (expectation.ignoreFailure()) {
+            comparisonResult = kJsonValue_Image_ComparisonResult_FailureIgnored;
+        } else {
+            comparisonResult = kJsonValue_Image_ComparisonResult_Failed;
         }
         actualImage[kJsonKey_Image_ComparisonResult] = comparisonResult;
 
@@ -177,11 +195,18 @@
         }
     }
 
-    bool ImageResultsAndExpectations::matchesExpectation(const char *sourceName,
-                                                         const ImageDigest &digest,
-                                                         const int *tileNumber) {
+    void ImageResultsAndExpectations::addDescription(const char *key, const char *value) {
+        fDescriptions[key] = value;
+    }
+
+    void ImageResultsAndExpectations::setImageBaseGSUrl(const char *imageBaseGSUrl) {
+        fImageBaseGSUrl = imageBaseGSUrl;
+    }
+
+    Expectation ImageResultsAndExpectations::getExpectation(const char *sourceName,
+                                                            const int *tileNumber) {
         if (fExpectedResults.isNull()) {
-            return false;
+            return Expectation();
         }
 
         Json::Value expectedImage;
@@ -191,13 +216,13 @@
             expectedImage = fExpectedResults[sourceName][kJsonKey_Source_TiledImages][*tileNumber];
         }
         if (expectedImage.isNull()) {
-            return false;
+            return Expectation();
         }
 
-        Json::Value actualChecksumAlgorithm = digest.getHashType().c_str();
-        Json::Value actualChecksumValue = Json::UInt64(digest.getHashValue());
-        return ((actualChecksumAlgorithm == expectedImage[kJsonKey_Image_ChecksumAlgorithm]) &&
-                (actualChecksumValue == expectedImage[kJsonKey_Image_ChecksumValue]));
+        bool ignoreFailure = (expectedImage[kJsonKey_Image_IgnoreFailure] == true);
+        return Expectation(SkString(expectedImage[kJsonKey_Image_ChecksumAlgorithm].asCString()),
+                           expectedImage[kJsonKey_Image_ChecksumValue].asUInt64(),
+                           ignoreFailure);
     }
 
     void ImageResultsAndExpectations::writeToFile(const char *filename) const {
@@ -205,8 +230,10 @@
         header[kJsonKey_Header_Type] = kJsonValue_Header_Type;
         header[kJsonKey_Header_Revision] = kJsonValue_Header_Revision;
         Json::Value root;
-        root[kJsonKey_Header] = header;
         root[kJsonKey_ActualResults] = fActualResults;
+        root[kJsonKey_Descriptions] = fDescriptions;
+        root[kJsonKey_Header] = header;
+        root[kJsonKey_ImageBaseGSUrl] = fImageBaseGSUrl;
         std::string jsonStdString = root.toStyledString();
         SkFILEWStream stream(filename);
         stream.write(jsonStdString.c_str(), jsonStdString.length());
diff --git a/tools/image_expectations.h b/tools/image_expectations.h
index a24334e..422c64d 100644
--- a/tools/image_expectations.h
+++ b/tools/image_expectations.h
@@ -11,7 +11,6 @@
 #include "SkBitmap.h"
 #include "SkJSONCPP.h"
 #include "SkOSFile.h"
-#include "SkRefCnt.h"
 
 namespace sk_tools {
 
@@ -20,14 +19,12 @@
      *
      * Currently, this is always a uint64_t hash digest of an SkBitmap.
      */
-    class ImageDigest : public SkRefCnt {
+    class ImageDigest {
     public:
         /**
          * Create an ImageDigest of a bitmap.
          *
-         * Note that this is an expensive operation, because it has to examine all pixels in
-         * the bitmap.  You may wish to consider using the BitmapAndDigest class, which will
-         * compute the ImageDigest lazily.
+         * Computes the hash of the bitmap lazily, since that is an expensive operation.
          *
          * @param bitmap image to get the digest of
          */
@@ -43,36 +40,105 @@
         explicit ImageDigest(const SkString &hashType, uint64_t hashValue);
 
         /**
+         * Returns true iff this and other ImageDigest represent identical images.
+         */
+        bool equals(ImageDigest &other);
+
+        /**
          * Returns the hash digest type as an SkString.
          *
          * For now, this always returns kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 .
          */
-        SkString getHashType() const;
+        SkString getHashType();
 
         /**
          * Returns the hash digest value as a uint64_t.
+         *
+         * Since the hash is computed lazily, this may take some time, and it may modify
+         * some fields on this object.
          */
-        uint64_t getHashValue() const;
+        uint64_t getHashValue();
 
     private:
+        const SkBitmap fBitmap;
         uint64_t fHashValue;
+        bool fComputedHashValue;
     };
 
     /**
-     * Container that holds a reference to an SkBitmap and computes its ImageDigest lazily.
-     *
-     * Computing the ImageDigest can be expensive, so this can help you postpone (or maybe even
-     * avoid) that work.
+     * Container that holds a reference to an SkBitmap and its ImageDigest.
      */
     class BitmapAndDigest {
     public:
         explicit BitmapAndDigest(const SkBitmap &bitmap);
 
-        const ImageDigest *getImageDigestPtr();
         const SkBitmap *getBitmapPtr() const;
+
+        /**
+         * Returns a pointer to the ImageDigest.
+         *
+         * Since the hash is computed lazily within the ImageDigest object, we cannot mandate
+         * that it be held const.
+         */
+        ImageDigest *getImageDigestPtr();
     private:
         const SkBitmap fBitmap;
-        SkAutoTUnref<ImageDigest> fImageDigestRef;
+        ImageDigest fImageDigest;
+    };
+
+    /**
+     * Expected test result: expected image (if any), and whether we want to ignore failures on
+     * this test or not.
+     *
+     * This is just an ImageDigest (or lack thereof, if there is no expectation) and a boolean
+     * telling us whether to ignore failures.
+     */
+    class Expectation {
+    public:
+        /**
+         * No expectation at all.
+         */
+        explicit Expectation(bool ignoreFailure=kDefaultIgnoreFailure);
+
+        /**
+         * Expect an image, passed as hashType/hashValue.
+         */
+        explicit Expectation(const SkString &hashType, uint64_t hashValue,
+                             bool ignoreFailure=kDefaultIgnoreFailure);
+
+        /**
+         * Expect an image, passed as a bitmap.
+         */
+        explicit Expectation(const SkBitmap& bitmap,
+                             bool ignoreFailure=kDefaultIgnoreFailure);
+
+        /**
+         * Returns true iff we want to ignore failed expectations.
+         */
+        bool ignoreFailure() const;
+
+        /**
+         * Returns true iff there are no allowed results.
+         */
+        bool empty() const;
+
+        /**
+         * Returns true iff we are expecting a particular image, and imageDigest matches it.
+         *
+         * If empty() returns true, this will return false.
+         *
+         * If this expectation DOES contain an image, and imageDigest doesn't match it,
+         * this method will return false regardless of what ignoreFailure() would return.
+         * (The caller can check that separately.)
+         */
+        bool matches(ImageDigest &imageDigest);
+
+    private:
+        static const bool kDefaultIgnoreFailure = false;
+
+        const bool fIsEmpty;
+        const bool fIgnoreFailure;
+        ImageDigest fImageDigest;  // cannot be const, because it computes its hash lazily
     };
 
     /**
@@ -107,19 +173,34 @@
          * @param digest description of the image's contents
          * @param tileNumber if not NULL, pointer to tile number
          */
-        void add(const char *sourceName, const char *fileName, const ImageDigest &digest,
+        void add(const char *sourceName, const char *fileName, ImageDigest &digest,
                  const int *tileNumber=NULL);
 
         /**
-         * Returns true if this test result matches its expectations.
-         * If there are no expectations for this test result, this will return false.
+         * Adds a key/value pair to the descriptions dict within the summary of results.
+         *
+         * @param key key within the descriptions dict
+         * @param value value to associate with that key
+         */
+        void addDescription(const char *key, const char *value);
+
+        /**
+         * Adds the image base Google Storage URL to the summary of results.
+         *
+         * @param imageBaseGSUrl the image base Google Storage URL
+         */
+        void setImageBaseGSUrl(const char *imageBaseGSUrl);
+
+        /**
+         * Returns the Expectation for this test.
          *
          * @param sourceName name of the source file that generated this result
-         * @param digest description of the image's contents
          * @param tileNumber if not NULL, pointer to tile number
+         *
+         * TODO(stephana): To make this work for GMs, we will need to add parameters for
+         * config, and maybe renderMode/builder?
          */
-        bool matchesExpectation(const char *sourceName, const ImageDigest &digest,
-                                const int *tileNumber=NULL);
+        Expectation getExpectation(const char *sourceName, const int *tileNumber=NULL);
 
         /**
          * Writes the summary (as constructed so far) to a file.
@@ -140,8 +221,10 @@
         static bool Parse(SkFILE* filePtr, Json::Value *jsonRoot);
 
         Json::Value fActualResults;
+        Json::Value fDescriptions;
         Json::Value fExpectedJsonRoot;
         Json::Value fExpectedResults;
+        Json::Value fImageBaseGSUrl;
     };
 
 } // namespace sk_tools
diff --git a/tools/lsan.supp b/tools/lsan.supp
index 6a274c0..8d46f5b 100644
--- a/tools/lsan.supp
+++ b/tools/lsan.supp
@@ -2,15 +2,11 @@
 #   tools/xsan_build address -C out/Debug
 #   ASAN_OPTIONS=detect_leaks=1 LSAN_OPTIONS=suppressions=tools/lsan.supp out/Debug/$FOO
 
-# Ignore fontconfig leaks.
-leak:FcFontSet
-leak:FcPatternObject
+# Fontconfig
+leak:libfontconfig
 
-# It'd be really nice to supress these leaks in the Nvidia driver, but I can't figure it out.
-# Direct leak of 18072 byte(s) in 3 object(s) allocated from:
-#   #0 0x5ebb59 in calloc ~/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:90
-#   #1 0x7f66af293b1e (/usr/lib/nvidia-current/libGL.so.1+0xbcb1e)
+# Nvidia driver
+leak:libGL.so
 
-# Skia leaks
-leak:SkRTConf
-leak:SkFontMgr
+# Not clear what this is.  skia:2916
+leak:__strdup
diff --git a/tools/lua/glyph-counts.lua b/tools/lua/glyph-counts.lua
new file mode 100644
index 0000000..553e9e3
--- /dev/null
+++ b/tools/lua/glyph-counts.lua
@@ -0,0 +1,110 @@
+function tostr(t)
+    local str = ""
+    for k, v in next, t do
+        if #str > 0 then
+            str = str .. ", "
+        end
+        if type(k) == "number" then
+            str = str .. "[" .. k .. "] = "
+        else
+            str = str .. tostring(k) .. " = "
+        end
+        if type(v) == "table" then
+            str = str .. "{ " .. tostr(v) .. " }"
+        else
+            str = str .. tostring(v)
+        end
+    end
+    return str
+end
+
+local canvas        -- holds the current canvas (from startcanvas())
+
+--[[
+    startcanvas() is called at the start of each picture file, passing the
+    canvas that we will be drawing into, and the name of the file.
+    
+    Following this call, there will be some number of calls to accumulate(t)
+    where t is a table of parameters that were passed to that draw-op.
+    
+        t.verb is a string holding the name of the draw-op (e.g. "drawRect")
+    
+    when a given picture is done, we call endcanvas(canvas, fileName)
+]]
+function sk_scrape_startcanvas(c, fileName)
+    canvas = c
+end
+
+--[[
+    Called when the current canvas is done drawing.
+]]
+function sk_scrape_endcanvas(c, fileName)
+    canvas = nil
+end
+
+--[[
+    Called with the parameters to each canvas.draw call, where canvas is the
+    current canvas as set by startcanvas()
+]]
+
+local gCounts = {}  -- [fontID_pointsize] = [] unique glyphs
+local gFirstGlyphs = {}
+local gTotalCount = 0
+
+function array_count(array)
+    local n = 0
+    for k in next, array do
+        n = n + 1
+    end
+    return n
+end
+
+function sk_scrape_accumulate(t)
+    verb = t.verb;
+    if verb == "drawPosText" or verb == "drawPosTextH" then
+        if t.glyphs then
+            local key = array_count(t.glyphs)
+            local n = gCounts[key]
+            if n then
+                gCounts[key] = n + 1
+            else
+                gCounts[key] = 1
+            end
+            
+            if key == 1 then
+                local first = t.glyphs[1];
+                local n = gFirstGlyphs[first]
+                if n then
+                    n = n + 1
+                else
+                    n = 0
+                end
+                gFirstGlyphs[first] = n
+            end
+
+            gTotalCount = gTotalCount + 1
+        end
+    end
+end
+
+--[[
+    lua_pictures will call this function after all of the pictures have been
+    "accumulated".
+]]
+function sk_scrape_summarize()
+    for k, v in next, gCounts do
+        io.write("glyph_count ", k, ",frequency ", v * 100 / gTotalCount, "\n")
+    end
+
+--[[
+    io.write("\n\nFirst glyph spread\n\n")
+    for k, v in next, gFirstGlyphs do
+        io.write("glyph, ", k, ",count, ", v, "\n")
+    end
+]]
+end
+
+function test_summary()
+    io.write("just testing test_summary\n")
+end
+
diff --git a/tools/lua/lua_app.cpp b/tools/lua/lua_app.cpp
index 50b1352..023ddae 100644
--- a/tools/lua/lua_app.cpp
+++ b/tools/lua/lua_app.cpp
@@ -18,14 +18,11 @@
 }
 
 static SkData* read_into_data(const char file[]) {
-    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(file));
-    if (!stream.get()) {
-        return SkData::NewEmpty();
+    SkData* data = SkData::NewFromFileName(file);
+    if (!data) {
+        data = SkData::NewEmpty();
     }
-    size_t len = stream->getLength();
-    void* buffer = sk_malloc_throw(len);
-    stream->read(buffer, len);
-    return SkData::NewFromMalloc(buffer, len);
+    return data;
 }
 
 int tool_main(int argc, char** argv);
diff --git a/tools/lua/lua_pictures.cpp b/tools/lua/lua_pictures.cpp
index 2985bf6..6c7087f 100644
--- a/tools/lua/lua_pictures.cpp
+++ b/tools/lua/lua_pictures.cpp
@@ -47,17 +47,6 @@
     return pic;
 }
 
-static SkData* read_into_data(const char file[]) {
-    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(file));
-    if (!stream.get()) {
-        return SkData::NewEmpty();
-    }
-    size_t len = stream->getLength();
-    void* buffer = sk_malloc_throw(len);
-    stream->read(buffer, len);
-    return SkData::NewFromMalloc(buffer, len);
-}
-
 static void call_canvas(lua_State* L, SkLuaCanvas* canvas,
                         const char pictureFile[], const char funcName[]) {
     lua_getglobal(L, funcName);
@@ -97,7 +86,10 @@
     SkLua L(summary);
 
     for (int i = 0; i < FLAGS_luaFile.count(); ++i) {
-        SkAutoDataUnref data(read_into_data(FLAGS_luaFile[i]));
+        SkAutoDataUnref data(SkData::NewFromFileName(FLAGS_luaFile[i]));
+        if (NULL == data.get()) {
+            data.reset(SkData::NewEmpty());
+        }
         if (!FLAGS_quiet) {
             SkDebugf("loading %s...\n", FLAGS_luaFile[i]);
         }
@@ -132,7 +124,7 @@
             SkString filename;
             SkOSFile::Iter iter(FLAGS_skpPath[i], "skp");
             while(iter.next(&filename)) {
-                paths.push_back() = SkOSPath::SkPathJoin(directory.c_str(), filename.c_str());
+                paths.push_back() = SkOSPath::Join(directory.c_str(), filename.c_str());
             }
         } else {
             // Add this as an .skp itself.
@@ -154,7 +146,8 @@
             SkAutoTUnref<SkPicture> pic(load_picture(path));
             if (pic.get()) {
                 SkAutoTUnref<SkLuaCanvas> canvas(
-                                    new SkLuaCanvas(pic->width(), pic->height(),
+                                    new SkLuaCanvas(SkScalarCeilToInt(pic->cullRect().width()), 
+                                                    SkScalarCeilToInt(pic->cullRect().height()),
                                                     L.get(), gAccumulateFunc));
 
                 call_canvas(L.get(), canvas.get(), path, gStartCanvasFunc);
diff --git a/tools/lua/paths.lua b/tools/lua/paths.lua
new file mode 100644
index 0000000..0fa6528
--- /dev/null
+++ b/tools/lua/paths.lua
@@ -0,0 +1,124 @@
+--
+-- Copyright 2014 Google Inc.
+--
+-- Use of this source code is governed by a BSD-style license that can be
+-- found in the LICENSE file.
+--
+
+-- Path scraping script.
+-- This script is designed to count the number of times we fall back to software
+-- rendering for a path in a given SKP. However, this script does not count an exact
+-- number of uploads, since there is some overlap with clipping: e.g. two clipped paths
+-- may cause three uploads to the GPU (set clip 1, set clip 2, unset clip 2/reset clip 1),
+-- but these cases are rare.
+
+draws = 0
+drawPaths = 0
+drawPathsAnti = 0
+drawPathsConvexAnti = 0
+
+clips = 0
+clipPaths = 0
+clipPathsAnti = 0
+clipPathsConvexAnti = 0
+
+usedPath = false
+usedSWPath = false
+
+skpsTotal = 0
+skpsWithPath = 0
+skpsWithSWPath = 0
+
+function sk_scrape_startcanvas(c, fileName)
+   usedPath = false
+   usedSWPath = false
+end
+
+function sk_scrape_endcanvas(c, fileName)
+   skpsTotal = skpsTotal + 1
+   if usedPath then
+      skpsWithPath = skpsWithPath + 1
+      if usedSWPath then
+         skpsWithSWPath = skpsWithSWPath + 1
+      end
+   end
+end
+
+function string.starts(String,Start)
+   return string.sub(String,1,string.len(Start))==Start
+end
+
+function isPathValid(path)
+   if not path then
+      return false
+   end
+
+   if path:isEmpty() then
+      return false
+   end
+
+   if path:isRect() then
+      return false
+   end
+
+   return true
+end
+
+function sk_scrape_accumulate(t)
+   if (string.starts(t.verb, "draw")) then
+      draws = draws + 1
+   end
+
+   if (string.starts(t.verb, "clip")) then
+      clips = clips + 1
+   end
+
+   if t.verb == "clipPath" then
+      local path = t.path
+      if isPathValid(path) then
+         clipPaths = clipPaths + 1
+         usedPath = true
+         if t.aa then
+            clipPathsAnti = clipPathsAnti + 1
+            if path:isConvex() then
+               clipPathsConvexAnti = clipPathsConvexAnti + 1
+            else
+               usedSWPath = true
+            end
+         end
+      end
+   end
+
+   if t.verb == "drawPath" then
+      local path = t.path
+      local paint = t.paint
+      if paint and isPathValid(path) then
+         drawPaths = drawPaths + 1
+         usedPath = true
+         if paint:isAntiAlias() then
+            drawPathsAnti = drawPathsAnti + 1
+            if path:isConvex() then
+               drawPathsConvexAnti = drawPathsConvexAnti + 1
+            else
+               usedSWPath = true
+            end
+         end
+      end
+   end
+end
+
+function sk_scrape_summarize() 
+   local swDrawPaths = drawPathsAnti - drawPathsConvexAnti
+   local swClipPaths = clipPathsAnti - clipPathsConvexAnti
+
+   io.write("clips = clips + ", clips, "\n");
+   io.write("draws = draws + ", draws, "\n");
+   io.write("clipPaths = clipPaths + ", clipPaths, "\n");
+   io.write("drawPaths = drawPaths + ", drawPaths, "\n");
+   io.write("swClipPaths = swClipPaths + ", swClipPaths, "\n");
+   io.write("swDrawPaths = swDrawPaths + ", swDrawPaths, "\n");
+
+   io.write("skpsTotal = skpsTotal + ", skpsTotal, "\n");
+   io.write("skpsWithPath = skpsWithPath + ", skpsWithPath, "\n");
+   io.write("skpsWithSWPath = skpsWithSWPath + ", skpsWithSWPath, "\n");
+end
diff --git a/tools/lua/paths_agg.lua b/tools/lua/paths_agg.lua
new file mode 100644
index 0000000..deb212e
--- /dev/null
+++ b/tools/lua/paths_agg.lua
@@ -0,0 +1,41 @@
+
+clips = 0
+draws = 0
+clipPaths = 0
+drawPaths = 0
+swClipPaths = 0
+swDrawPaths = 0
+
+skpsTotal = 0
+skpsWithPath = 0
+skpsWithSWPath = 0
+
+dofile("/tmp/lua-output")
+
+io.write("Number of clips: ", clips, "\n");
+io.write("Number of draws: ", draws, "\n");
+io.write("Number of clipped paths: ", clipPaths, "\n");
+io.write("Number of drawn paths: ", drawPaths, "\n");
+io.write("Number of clipped software paths: ", swClipPaths, "\n");
+io.write("Number of drawn software paths: ", swDrawPaths, "\n");
+
+io.write("\n")
+
+io.write("Number of SKPs total: ", skpsTotal, "\n")
+io.write("Number of SKPs that draw paths: ", skpsWithPath, "\n")
+io.write("Number of SKPs that draw SW paths: ", skpsWithSWPath, "\n")
+
+io.write("\n")
+io.write("\n")
+
+totalSWPaths = swDrawPaths + swClipPaths
+totalPaths = drawPaths + clipPaths
+
+io.write("Percentage of paths needing software: ", (100*(totalSWPaths / totalPaths)), "\n")
+io.write("Percentage of draws/clips needing software: ",
+         (100*(totalSWPaths / (draws + clips))), "\n")
+
+io.write("\n")
+
+io.write("Percentage of SKPs that draw paths: ", (100*(skpsWithPath / skpsTotal)), "\n")
+io.write("Percentage of SKPs that draw SW paths: ", (100*(skpsWithSWPath / skpsTotal)), "\n")
diff --git a/tools/misc_utils.py b/tools/misc_utils.py
index 13978a4..89a2f92 100644
--- a/tools/misc_utils.py
+++ b/tools/misc_utils.py
@@ -4,221 +4,56 @@
 # found in the LICENSE file.
 
 
-"""Module to host the VerboseSubprocess, ChangeDir, and ReSearch classes.
-"""
+"""Miscellaneous utilities."""
 
-import os
+
 import re
-import subprocess
-
-
-def print_subprocess_args(prefix, *args, **kwargs):
-    """Print out args in a human-readable manner."""
-    def quote_and_escape(string):
-        """Quote and escape a string if necessary."""
-        if ' ' in string or '\n' in string:
-            string = '"%s"' % string.replace('"', '\\"')
-        return string
-    if 'cwd' in kwargs:
-        print '%scd %s' % (prefix, kwargs['cwd'])
-    print prefix + ' '.join(quote_and_escape(arg) for arg in args[0])
-    if 'cwd' in kwargs:
-        print '%scd -' % prefix
-
-
-class VerboseSubprocess(object):
-    """Call subprocess methods, but print out command before executing.
-
-    Attributes:
-        verbose: (boolean) should we print out the command or not.  If
-                 not, this is the same as calling the subprocess method
-        quiet: (boolean) suppress stdout on check_call and call.
-        prefix: (string) When verbose, what to print before each command.
-    """
-
-    def __init__(self, verbose):
-        self.verbose = verbose
-        self.quiet = not verbose
-        self.prefix = '~~$ '
-
-    def check_call(self, *args, **kwargs):
-        """Wrapper for subprocess.check_call().
-
-        Args:
-            *args: to be passed to subprocess.check_call()
-            **kwargs: to be passed to subprocess.check_call()
-        Returns:
-            Whatever subprocess.check_call() returns.
-        Raises:
-            OSError or subprocess.CalledProcessError: raised by check_call.
-        """
-        if self.verbose:
-            print_subprocess_args(self.prefix, *args, **kwargs)
-        if self.quiet:
-            with open(os.devnull, 'w') as devnull:
-                return subprocess.check_call(*args, stdout=devnull, **kwargs)
-        else:
-            return subprocess.check_call(*args, **kwargs)
-
-    def call(self, *args, **kwargs):
-        """Wrapper for subprocess.check().
-
-        Args:
-            *args: to be passed to subprocess.check_call()
-            **kwargs: to be passed to subprocess.check_call()
-        Returns:
-            Whatever subprocess.call() returns.
-        Raises:
-            OSError or subprocess.CalledProcessError: raised by call.
-        """
-        if self.verbose:
-            print_subprocess_args(self.prefix, *args, **kwargs)
-        if self.quiet:
-            with open(os.devnull, 'w') as devnull:
-                return subprocess.call(*args, stdout=devnull, **kwargs)
-        else:
-            return subprocess.call(*args, **kwargs)
-
-    def check_output(self, *args, **kwargs):
-        """Wrapper for subprocess.check_output().
-
-        Args:
-            *args: to be passed to subprocess.check_output()
-            **kwargs: to be passed to subprocess.check_output()
-        Returns:
-            Whatever subprocess.check_output() returns.
-        Raises:
-            OSError or subprocess.CalledProcessError: raised by check_output.
-        """
-        if self.verbose:
-            print_subprocess_args(self.prefix, *args, **kwargs)
-        return subprocess.check_output(*args, **kwargs)
-
-    def strip_output(self, *args, **kwargs):
-        """Wrap subprocess.check_output and str.strip().
-
-        Pass the given arguments into subprocess.check_output() and return
-        the results, after stripping any excess whitespace.
-
-        Args:
-            *args: to be passed to subprocess.check_output()
-            **kwargs: to be passed to subprocess.check_output()
-
-        Returns:
-            The output of the process as a string without leading or
-            trailing whitespace.
-        Raises:
-            OSError or subprocess.CalledProcessError: raised by check_output.
-        """
-        if self.verbose:
-            print_subprocess_args(self.prefix, *args, **kwargs)
-        return str(subprocess.check_output(*args, **kwargs)).strip()
-
-    def popen(self, *args, **kwargs):
-        """Wrapper for subprocess.Popen().
-
-        Args:
-            *args: to be passed to subprocess.Popen()
-            **kwargs: to be passed to subprocess.Popen()
-        Returns:
-            The output of subprocess.Popen()
-        Raises:
-            OSError or subprocess.CalledProcessError: raised by Popen.
-        """
-        if self.verbose:
-            print_subprocess_args(self.prefix, *args, **kwargs)
-        return subprocess.Popen(*args, **kwargs)
-
-
-class ChangeDir(object):
-    """Use with a with-statement to temporarily change directories."""
-    # pylint: disable=I0011,R0903
-
-    def __init__(self, directory, verbose=False):
-        self._directory = directory
-        self._verbose = verbose
-
-    def __enter__(self):
-        if self._directory != os.curdir:
-            if self._verbose:
-                print '~~$ cd %s' % self._directory
-            cwd = os.getcwd()
-            os.chdir(self._directory)
-            self._directory = cwd
-
-    def __exit__(self, etype, value, traceback):
-        if self._directory != os.curdir:
-            if self._verbose:
-                print '~~$ cd %s' % self._directory
-            os.chdir(self._directory)
 
 
 class ReSearch(object):
-    """A collection of static methods for regexing things."""
+  """A collection of static methods for regexing things."""
 
-    @staticmethod
-    def search_within_stream(input_stream, pattern, default=None):
-        """Search for regular expression in a file-like object.
+  @staticmethod
+  def search_within_stream(input_stream, pattern, default=None):
+    """Search for regular expression in a file-like object.
 
-        Opens a file for reading and searches line by line for a match to
-        the regex and returns the parenthesized group named return for the
-        first match.  Does not search across newlines.
+    Opens a file for reading and searches line by line for a match to
+    the regex and returns the parenthesized group named return for the
+    first match.  Does not search across newlines.
 
-        For example:
-            pattern = '^root(:[^:]*){4}:(?P<return>[^:]*)'
-            with open('/etc/passwd', 'r') as stream:
-                return search_within_file(stream, pattern)
-        should return root's home directory (/root on my system).
+    For example:
+        pattern = '^root(:[^:]*){4}:(?P<return>[^:]*)'
+        with open('/etc/passwd', 'r') as stream:
+            return search_within_file(stream, pattern)
+    should return root's home directory (/root on my system).
 
-        Args:
-            input_stream: file-like object to be read
-            pattern: (string) to be passed to re.compile
-            default: what to return if no match
+    Args:
+        input_stream: file-like object to be read
+        pattern: (string) to be passed to re.compile
+        default: what to return if no match
 
-        Returns:
-            A string or whatever default is
-        """
-        pattern_object = re.compile(pattern)
-        for line in input_stream:
-            match = pattern_object.search(line)
-            if match:
-                return match.group('return')
-        return default
+    Returns:
+        A string or whatever default is
+    """
+    pattern_object = re.compile(pattern)
+    for line in input_stream:
+      match = pattern_object.search(line)
+      if match:
+        return match.group('return')
+    return default
 
-    @staticmethod
-    def search_within_string(input_string, pattern, default=None):
-        """Search for regular expression in a string.
+  @staticmethod
+  def search_within_string(input_string, pattern, default=None):
+    """Search for regular expression in a string.
 
-        Args:
-            input_string: (string) to be searched
-            pattern: (string) to be passed to re.compile
-            default: what to return if no match
+    Args:
+        input_string: (string) to be searched
+        pattern: (string) to be passed to re.compile
+        default: what to return if no match
 
-        Returns:
-            A string or whatever default is
-        """
-        match = re.search(pattern, input_string)
-        return match.group('return') if match else default
-
-    @staticmethod
-    def search_within_output(verbose, pattern, default, *args, **kwargs):
-        """Search for regular expression in a process output.
-
-        Does not search across newlines.
-
-        Args:
-            verbose: (boolean) shoule we call print_subprocess_args?
-            pattern: (string) to be passed to re.compile
-            default: what to return if no match
-            *args: to be passed to subprocess.Popen()
-            **kwargs: to be passed to subprocess.Popen()
-
-        Returns:
-            A string or whatever default is
-        """
-        if verbose:
-            print_subprocess_args('~~$ ', *args, **kwargs)
-        proc = subprocess.Popen(*args, stdout=subprocess.PIPE, **kwargs)
-        return ReSearch.search_within_stream(proc.stdout, pattern, default)
-
+    Returns:
+        A string or whatever default is
+    """
+    match = re.search(pattern, input_string)
+    return match.group('return') if match else default
 
diff --git a/tools/pathops_sorter.htm b/tools/pathops_sorter.htm
index aac151a..8f00e91 100644
--- a/tools/pathops_sorter.htm
+++ b/tools/pathops_sorter.htm
@@ -953,11 +953,37 @@
 {{{1020, 672}, {1020, 640.93395999999996}, {998.03301999999996, 618.96698000000004}}}
 </div>
 
+<div id="skpwww_9to5mac_com_64">
+{{{{365.848175,5081.15186}, {368,5103}}},
+{{{367.967712,5102.61084}, {368.278717,5105.71045}}}},
+</div>
+
+<div id="issue2753">
+{{50.6,117.001}, {50.6,117.001}, {164.601,85.2}, {188.201,117.601}},
+{{188.201,117.601}, {188.201,117.601}, {174.801,93}, {39,124.001}},
+computed quadratics set
+{{50.6,117.001}, {52.4926111,116.112083}, {81.0298889,109.956333}},
+{{81.0298889,109.956333}, {109.567167,103.800583}, {142.037778,103.045}},
+{{142.037778,103.045}, {174.508389,102.289417}, {188.201,117.601}},
+computed quadratics set
+{{188.201,117.601}, {189.210269,116.85838}, {179.697259,112.371148}},
+{{179.697259,112.371148}, {170.18425,107.883917}, {138.037741,108.563519}},
+{{138.037741,108.563519}, {105.891231,109.24312}, {39,124.001}},
+</div>
+
+<div id="battle6001">
+{{{0.111722f, -59.999897f}, {0.0895366594f, -59.999939f}, {0.0673542097f, -59.9999695f}, {0.0451717526f, -59.9999847f}}}
+{{{0.0451734141f, -59.9999847f}, {0.0438041016f, -59.9999886f}, {0.0424379632f, -59.9999886f}, {0.0410718247f, -59.9999886f}}}
+</div>
+
 </div>
 
 <script type="text/javascript">
 
     var testDivs = [
+        battle6001,
+        issue2753,
+        skpwww_9to5mac_com_64,
         skpcarrot_is24x,
         skpwww_wartepop_blogspot_com_br_6,
         skpwww_wartepop_blogspot_com_br_6a,
@@ -1146,6 +1172,7 @@
 
     var draw_t = false;
     var draw_closest_t = false;
+    var draw_cubic_red = false;
     var draw_derivative = false;
     var draw_endpoints = true;
     var draw_midpoint = 0;
@@ -1707,7 +1734,7 @@
             }
             ctx.lineWidth = 1;
             if (draw_tangents != 0) {
-                if (firstInside == curves) {
+                if (draw_cubic_red ? curve.length == 8 : firstInside == curves) {
                     ctx.strokeStyle = "rgba(255,0,0, 0.3)";
                 } else {
                     ctx.strokeStyle = "rgba(0,0,255, 0.3)";
@@ -1736,7 +1763,7 @@
                     (curve[4] - srcLeft) * scale, (curve[5] - srcTop) * scale,
                     (curve[6] - srcLeft) * scale, (curve[7] - srcTop) * scale);
             }
-            if (firstInside == curves) {
+            if (draw_cubic_red ? curve.length == 8 : firstInside == curves) {
                 ctx.strokeStyle = "rgba(255,0,0, 1)";
             } else {
                 ctx.strokeStyle = "rgba(0,0,255, 1)";
@@ -1818,7 +1845,7 @@
                 ctx.closePath();
                 ctx.fillStyle = "white";
                 ctx.fill();
-                if (firstInside == curves) {
+                if (draw_cubic_red ? curve.length == 8 : firstInside == curves) {
                     ctx.strokeStyle = "rgba(255,0,0, 1)";
                     ctx.fillStyle = "rgba(255,0,0, 1)";
                 } else {
@@ -1934,6 +1961,10 @@
                 calcLeftTop();
                 redraw();
                 break;
+            case 'b':
+                draw_cubic_red ^= true;
+                redraw();
+                break;
             case 'c':
                 drawTop();
                 break;
diff --git a/tools/pathops_visualizer.htm b/tools/pathops_visualizer.htm
index 9872b38..eece69b 100644
--- a/tools/pathops_visualizer.htm
+++ b/tools/pathops_visualizer.htm
@@ -1,85 +1,171 @@
 <html>
 <head>
 <div height="0" hidden="true">
+<div id="fuzz487a">
+  RunTestSet [fuzz487a]
 
-<div id="skpwww_argus_presse_fr_41">
-  RunTestSet [skpwww_argus_presse_fr_41]
-
-{{1000,343}, {165,343}},
-{{165,343}, {165,364.869873}},
-{{165,364.869873}, {1000,364.869873}},
-{{1000,364.869873}, {1000,343}},
-op intersect
-{{165,343.000031}, {1000,343.000031}},
-{{1000,343.000031}, {1000,364.869904}},
-{{1000,364.869904}, {165,364.869904}},
-{{165,364.869904}, {165,343.000031}},
-debugShowLineIntersection wtTs[0]=0 {{165,343}, {165,364.869873}} {{165,343}} wnTs[0]=1 {{1000,343}, {165,343}}
-debugShowLineIntersection wtTs[0]=1 {{1000,364.869873}, {1000,343}} {{1000,343}} wnTs[0]=0 {{1000,343}, {165,343}}
-debugShowLineIntersection wtTs[0]=0 {{165,364.869873}, {1000,364.869873}} {{165,364.869873}} wnTs[0]=1 {{165,343}, {165,364.869873}}
-debugShowLineIntersection wtTs[0]=0 {{1000,364.869873}, {1000,343}} {{1000,364.869873}} wnTs[0]=1 {{165,364.869873}, {1000,364.869873}}
-debugShowLineIntersection wtTs[0]=0 {{165,343.000031}, {1000,343.000031}} {{165,343}} wtTs[1]=1 {{1000,343}} wnTs[0]=1 {{1000,343}, {165,343}} wnTs[1]=0
-debugShowLineIntersection wtTs[0]=0 {{1000,343.000031}, {1000,364.869904}} {{1000,343.000031}} wnTs[0]=0 {{1000,343}, {165,343}}
-debugShowLineIntersection wtTs[0]=1 {{165,364.869904}, {165,343.000031}} {{165,343.000031}} wnTs[0]=1 {{1000,343}, {165,343}}
-debugShowLineIntersection wtTs[0]=0 {{165,343.000031}, {1000,343.000031}} {{165,343}} wnTs[0]=0 {{165,343}, {165,364.869873}}
-debugShowLineIntersection wtTs[0]=1 {{1000,364.869904}, {165,364.869904}} {{165,364.869873}} wnTs[0]=1 {{165,343}, {165,364.869873}}
-debugShowLineIntersection wtTs[0]=0 {{165,364.869904}, {165,343.000031}} {{165,364.869904}} wtTs[1]=1 {{165,343.000031}} wnTs[0]=1 {{165,343}, {165,364.869873}} wnTs[1]=1.39541634e-006
-debugShowLineIntersection wtTs[0]=1 {{1000,343.000031}, {1000,364.869904}} {{1000,364.869904}} wnTs[0]=1 {{165,364.869873}, {1000,364.869873}}
-debugShowLineIntersection wtTs[0]=0 {{1000,364.869904}, {165,364.869904}} {{1000,364.869873}} wtTs[1]=1 {{165,364.869873}} wnTs[0]=1 {{165,364.869873}, {1000,364.869873}} wnTs[1]=0
-debugShowLineIntersection wtTs[0]=0 {{165,364.869904}, {165,343.000031}} {{165,364.869904}} wnTs[0]=0 {{165,364.869873}, {1000,364.869873}}
-debugShowLineIntersection wtTs[0]=1 {{165,343.000031}, {1000,343.000031}} {{1000,343}} wnTs[0]=1 {{1000,364.869873}, {1000,343}}
-debugShowLineIntersection wtTs[0]=0 {{1000,343.000031}, {1000,364.869904}} {{1000,343.000031}} wtTs[1]=1 {{1000,364.869904}} wnTs[0]=0.999999 {{1000,364.869873}, {1000,343}} wnTs[1]=0
-debugShowLineIntersection wtTs[0]=0 {{1000,364.869904}, {165,364.869904}} {{1000,364.869873}} wnTs[0]=0 {{1000,364.869873}, {1000,343}}
-debugShowLineIntersection wtTs[0]=0 {{1000,343.000031}, {1000,364.869904}} {{1000,343.000031}} wnTs[0]=1 {{165,343.000031}, {1000,343.000031}}
-debugShowLineIntersection wtTs[0]=1 {{165,364.869904}, {165,343.000031}} {{165,343.000031}} wnTs[0]=0 {{165,343.000031}, {1000,343.000031}}
-debugShowLineIntersection wtTs[0]=0 {{1000,364.869904}, {165,364.869904}} {{1000,364.869904}} wnTs[0]=1 {{1000,343.000031}, {1000,364.869904}}
-debugShowLineIntersection wtTs[0]=0 {{165,364.869904}, {165,343.000031}} {{165,364.869904}} wnTs[0]=1 {{1000,364.869904}, {165,364.869904}}
-SkOpSegment::debugShowTs - id=0 [o=3,5 t=0 1000,343.000031 w=1 o=0] [o=7,1 t=1 165,343 w=1 o=0]
-SkOpSegment::debugShowTs o id=4 [o=7,1 t=0 165,343 w=1 o=0] [o=3,5 t=1 1000,343.000031 w=1 o=0] operand
-SkOpSegment::debugShowTs + id=0 [o=3,5 t=0 1000,343.000031 w=1 o=0] [o=7,1 t=1 165,343 w=1 o=0]
-SkOpSegment::debugShowTs o id=4 [o=7,1 t=0 165,343 w=1 o=0] [o=3,5 t=1 1000,343.000031 w=1 o=0] operand
-SkOpSegment::debugShowTs - id=1 [o=4,0 t=0 165,343 w=1 o=0] [o=6,2 t=1 165,364.869873 w=1 o=0]
-SkOpSegment::debugShowTs o id=7 [o=6,2 t=0 165,364.869904 w=1 o=0] [o=4,0 t=1 165,343.000031 w=1 o=0] operand
-SkOpSegment::addTPair addTPair this=1 1.39541634e-006 other=7 1
-SkOpSegment::addTPair addTPair this=7 0 other=1 1
-SkOpSegment::debugShowTs + id=1 [o=4,0 t=0 165,343 w=1 o=0] [o=7 t=1.4e-006 165,343.000031 w=1 o=0] [o=7,6,2 t=1 165,364.869873 w=1 o=0]
-SkOpSegment::debugShowTs o id=7 [o=1,6,2 t=0 165,364.869904 w=1 o=0] [o=1,4,0 t=1 165,343.000031 w=1 o=0] operand
-SkOpSegment::debugShowTs - id=2 [o=1,7 t=0 165,364.869904 w=1 o=0] [o=5,3 t=1 1000,364.869873 w=1 o=0]
-SkOpSegment::debugShowTs o id=6 [o=5,3 t=0 1000,364.869873 w=1 o=0] [o=1,7 t=1 165,364.869904 w=1 o=0] operand
-SkOpSegment::debugShowTs + id=2 [o=1,7 t=0 165,364.869904 w=1 o=0] [o=5,3 t=1 1000,364.869873 w=1 o=0]
-SkOpSegment::debugShowTs o id=6 [o=5,3 t=0 1000,364.869873 w=1 o=0] [o=1,7 t=1 165,364.869904 w=1 o=0] operand
-SkOpSegment::debugShowTs - id=3 [o=6,2 t=0 1000,364.869873 w=1 o=0] [o=4,0 t=1 1000,343 w=1 o=0]
-SkOpSegment::debugShowTs o id=5 [o=4,0 t=0 1000,343.000031 w=1 o=0] [o=6,2 t=1 1000,364.869904 w=1 o=0] operand
-SkOpSegment::addTPair addTPair this=3 0 other=5 1
-SkOpSegment::addTPair addTPair this=5 0 other=3 0.999998605
-SkOpSegment::debugShowTs + id=3 [o=6,2,5 t=0 1000,364.869904 w=1 o=0] [o=5 t=1 1000,343.000031 w=1 o=0] [o=4,0 t=1 1000,343 w=1 o=0]
-SkOpSegment::debugShowTs o id=5 [o=3,4,0 t=0 1000,343.000031 w=1 o=0] [o=3,6,2 t=1 1000,364.869904 w=1 o=0] operand
+{{172.5,96}, {137.600006,96}},
+{{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}},
+{{107.500008,56.7999992}, {116.500008,23.0999985}},
+{{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}},
+{{97.0000076,20.4999981}, {97.0000076,55.4000015}},
+{{97.0000076,55.4000015}, {97.0000076,55.4000015}},
+{{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}},
+{{57.8000069,85.5}, {24.1000061,76.5}},
+{{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}},
+{{21.5000057,96}, {56.4000092,96}},
+{{56.4000092,96}, {56.4000092,96}},
+{{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}},
+{{228.900009,192}, {172.5,96}},
+op union
+{{172.5,96}, {137.600006,96}},
+{{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}},
+{{117.300003,60.9000015}, {134.800003,30.7000008}},
+{{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}},
+{{97.1000061,20.6000004}, {97.1000061,55.5}},
+{{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}},
+{{62.0000076,75.8000031}, {31.6000004,58.2999992}},
+{{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}},
+{{21.5,96}, {56.4000015,96}},
+{{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}},
+{{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}},
+{{43.3999977,156.700012}, {3.33333338e+029,119.400002}},
+{{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}},
+{{29.3999996,-10.8000002}, {33.2999992,-25.6000004}},
+{{33.2999992,-25.6000004}, {62,-17.9000015}},
+{{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}},
+{{161.199997,136}, {172.5,96}},
+debugShowCubicIntersection no self intersect {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}}
+debugShowCubicIntersection no self intersect {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}}
+debugShowCubicIntersection no self intersect {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}}
+debugShowCubicIntersection no self intersect {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}}
+debugShowCubicIntersection no self intersect {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}}
+debugShowCubicIntersection no self intersect {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}}
+debugShowCubicIntersection no self intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{172.5,96}, {137.600006,96}}
+debugShowLineIntersection wtTs[0]=1 {{161.199997,136}, {172.5,96}} {{172.5,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection wtTs[0]=1 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{117.300003,60.9000015}} wnTs[0]=0 {{117.300003,60.9000015}, {134.800003,30.7000008}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{137.600006,96}} wtTs[1]=1 {{117.300003,60.9000015}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicIntersection no intersect {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{134.800003,30.7000008}} wnTs[0]=1 {{117.300003,60.9000015}, {134.800003,30.7000008}}
+debugShowLineIntersection wtTs[0]=0 {{117.300003,60.9000015}, {134.800003,30.7000008}} {{117.300003,60.9000015}} wtTs[1]=1 {{134.800003,30.7000008}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{117.300003,60.9000015}, {134.800003,30.7000008}}
+debugShowCubicLineIntersection wtTs[0]=1 {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{97.1000061,20.6000004}} wnTs[0]=0 {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowCubicLineIntersection wtTs[0]=0 {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{134.800003,30.7000008}} wtTs[1]=1 {{97.1000061,20.6000004}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicIntersection no intersect {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{97.1000061,55.5}} wnTs[0]=1 {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{97.1000061,20.6000004}} wnTs[0]=0 {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowCubicLineIntersection wtTs[0]=0.13656589 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{97.1000061,40.6604424}} wnTs[0]=0.574798 {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowCubicLineIntersection wtTs[0]=1 {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{62.0000076,75.8000031}} wnTs[0]=0 {{62.0000076,75.8000031}, {31.6000004,58.2999992}}
+debugShowCubicLineIntersection wtTs[0]=0 {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{97.1000061,55.5}} wtTs[1]=1 {{62.0000076,75.8000031}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicIntersection no intersect {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{31.6000004,58.2999992}} wnTs[0]=1 {{62.0000076,75.8000031}, {31.6000004,58.2999992}}
+debugShowLineIntersection wtTs[0]=0 {{62.0000076,75.8000031}, {31.6000004,58.2999992}} {{62.0000076,75.8000031}} wtTs[1]=1 {{31.6000004,58.2999992}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{62.0000076,75.8000031}, {31.6000004,58.2999992}}
+debugShowCubicLineIntersection wtTs[0]=1 {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{21.5,96}} wnTs[0]=0 {{21.5,96}, {56.4000015,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{31.6000004,58.2999992}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{56.4000015,96}} wnTs[0]=1 {{21.5,96}, {56.4000015,96}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{56.4000015,96}} wnTs[0]=1 {{21.5,96}, {56.4000015,96}}
+debugShowCubicIntersection wtTs[0]=1 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{76.6999969,131.100006}} wnTs[0]=0 {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}}
+debugShowCubicLineIntersection wtTs[0]=1 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{76.6999969,131.100006}} wnTs[0]=0 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{56.4000015,96}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowCubicIntersection no intersect {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}} {{76.6999969,131.100006}} wtTs[1]=1 {{43.3999977,156.700012}} wnTs[0]=0 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}} wnTs[1]=0
+debugShowCubicIntersection no intersect {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowLineIntersection wtTs[0]=1 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}} {{3.33333338e+029,119.400002}} wnTs[0]=0 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowCubicLineIntersection wtTs[0]=1 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{161.199997,136}} wnTs[0]=0 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}}
+debugShowLineIntersection wtTs[0]=0 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}} {{161.199997,136}} wnTs[0]=0 {{161.199997,136}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{29.3999996,-10.8000002}} wnTs[0]=0 {{29.3999996,-10.8000002}, {33.2999992,-25.6000004}}
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{172.5,96}} wnTs[0]=1 {{161.199997,136}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=1 {{29.3999996,-10.8000002}, {33.2999992,-25.6000004}} {{33.2999992,-25.6000004}} wnTs[0]=0 {{33.2999992,-25.6000004}, {62,-17.9000015}}
+debugShowCubicLineIntersection wtTs[0]=0 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{62,-17.9000015}} wnTs[0]=1 {{33.2999992,-25.6000004}, {62,-17.9000015}}
+debugShowCubicLineIntersection wtTs[0]=1 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{161.199997,136}} wnTs[0]=0 {{161.199997,136}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=0 {{172.5,96}, {137.600006,96}} {{172.5,96}} wtTs[1]=1 {{137.600006,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}} wnTs[1]=1
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{172.5,96}, {137.600006,96}}
+debugShowLineIntersection wtTs[0]=1 {{228.900009,192}, {172.5,96}} {{172.5,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{137.600006,96}} wnTs[0]=0 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}}
+debugShowCubicIntersection no intersect {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicLineIntersection wtTs[0]=0.798977321 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{117.320122,60.8652802}} wnTs[0]=0.00114967 {{117.300003,60.9000015}, {134.800003,30.7000008}}
+debugShowCubicLineIntersection wtTs[0]=0.511418257 {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{116.491173,23.1330757}} wnTs[0]=0.999019 {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicIntersection no intersect {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}}
+debugShowCubicLineIntersection no intersect {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}} {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowCubicIntersection no intersect {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}}
+debugShowCubicLineIntersection wtTs[0]=0.799679553 {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}} {{61.8468246,75.7118225}} wnTs[0]=0.00503891 {{62.0000076,75.8000031}, {31.6000004,58.2999992}}
+debugShowCubicLineIntersection no intersect {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{57.8000069,85.5}, {24.1000061,76.5}}
+debugShowCubicIntersection wtTs[0]=1 {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{21.5,96}} wnTs[0]=1 {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}}
+debugShowCubicLineIntersection no intersect {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicLineIntersection wtTs[0]=1 {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}} {{21.5000057,96}} wnTs[0]=1.63955e-007 {{21.5,96}, {56.4000015,96}}
+debugShowLineIntersection wtTs[0]=0 {{21.5000057,96}, {56.4000092,96}} {{21.5000057,96}} wtTs[1]=0.999999781 {{56.4000015,96}} wnTs[0]=1.63955e-007 {{21.5,96}, {56.4000015,96}} wnTs[1]=1
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{21.5,96}, {56.4000015,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{56.4000015,96}} wnTs[0]=1 {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicIntersection wtTs[0]=0 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{56.4000015,96}} wnTs[0]=0 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicIntersection wtTs[0]=0.267722282 {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}} {{64.540802,133.291794}} wnTs[0]=0.131302 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{43.3999977,156.700012}, {3.33333338e+029,119.400002}}
+debugShowLineIntersection wtTs[0]=4.94283788e-028 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}} {{208.16127,156.700012}} wnTs[0]=0.367708 {{228.900009,192}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{137.600006,96}} wtTs[1]=1 {{107.500008,56.7999992}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{107.500008,56.7999992}} wnTs[0]=0 {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicLineIntersection wtTs[0]=0 {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}} {{116.500008,23.0999985}} wtTs[1]=1 {{97.0000076,20.4999981}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{97.0000076,20.4999981}} wnTs[0]=0 {{97.0000076,20.4999981}, {97.0000076,55.4000015}}
+debugShowCubicLineIntersection wtTs[0]=0 {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}} {{97.0000076,55.4000015}} wtTs[1]=1 {{57.8000069,85.5}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{57.8000069,85.5}} wnTs[0]=0 {{57.8000069,85.5}, {24.1000061,76.5}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{56.4000092,96}} wnTs[0]=1 {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{56.4000092,96}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{172.5,96}} wnTs[0]=1 {{228.900009,192}, {172.5,96}}
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{172.5,96}, {137.600006,96}}
+debugShowCubicIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}}
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}}
+debugShowCubicLineIntersection wtTs[0]=0.136112912 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{97.0000076,40.4949226}} wnTs[0]=0.57292 {{97.0000076,20.4999981}, {97.0000076,55.4000015}}
+debugShowCubicIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}}
+debugShowCubicIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowLineIntersection wtTs[0]=1 {{161.199997,136}, {172.5,96}} {{172.5,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{161.199997,136}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=1 {{161.199997,136}, {172.5,96}} {{172.5,96}} wnTs[0]=1 {{228.900009,192}, {172.5,96}}
+debugShowCubicIntersection no self intersect {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}}
+debugShowCubicIntersection no self intersect {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}}
+debugShowCubicIntersection no self intersect {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}}
+debugShowCubicIntersection no self intersect {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}}
+debugShowCubicIntersection no self intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{172.5,96}, {137.600006,96}}
+debugShowLineIntersection wtTs[0]=1 {{228.900009,192}, {172.5,96}} {{172.5,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection wtTs[0]=1 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{107.500008,56.7999992}} wnTs[0]=0 {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicIntersection no intersect {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicLineIntersection wtTs[0]=0 {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}} {{116.500008,23.0999985}} wnTs[0]=1 {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicLineIntersection wtTs[0]=1 {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}} {{97.0000076,20.4999981}} wnTs[0]=0 {{97.0000076,20.4999981}, {97.0000076,55.4000015}}
+debugShowCubicLineIntersection wtTs[0]=0 {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}} {{97.0000076,55.4000015}} wnTs[0]=1 {{97.0000076,20.4999981}, {97.0000076,55.4000015}}
+debugShowCubicLineIntersection wtTs[0]=1 {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}} {{57.8000069,85.5}} wnTs[0]=0 {{57.8000069,85.5}, {24.1000061,76.5}}
+debugShowCubicLineIntersection wtTs[0]=0 {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}} {{24.1000061,76.5}} wnTs[0]=1 {{57.8000069,85.5}, {24.1000061,76.5}}
+debugShowCubicLineIntersection wtTs[0]=1 {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}} {{21.5000057,96}} wnTs[0]=0 {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{56.4000092,96}} wnTs[0]=1 {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicLineIntersection wtTs[0]=1 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{228.900009,192}} wnTs[0]=0 {{228.900009,192}, {172.5,96}}
+SkOpSegment::debugShowTs - id=13 [o=12 t=0 117.300003,60.9000015 w=1 o=0] [o=1 t=0.00115 117.320122,60.8652802 w=1 o=0] [o=14 t=1 134.800003,30.7000008 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=23 [o=22 t=0 3.33333338e+029,119.400002 w=1 o=0] [o=1,0,12,11,12,14,15,14,16,16,18,20,19,10,27,2,1,3,4,3,5,6,5,9,8,24 t=1 29.3999996,-10.8000002 w=1 o=0] operand
+SkOpSegment::addTPair addTPair this=13 0 other=23 0.999999881
+SkOpSegment::debugShowTs + id=13 [o=23,12 t=0 117.300003,60.9000015 w=1 o=0] [o=1 t=0.00115 117.320122,60.8652802 w=1 o=0] [o=14 t=1 134.800003,30.7000008 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=23 [o=22 t=0 3.33333338e+029,119.400002 w=1 o=0] [o=13 t=1 117.300003,60.9000015 w=1 o=0] [o=1,0,12,11,12,14,15,14,16,16,18,20,19,10,27,2,1,3,4,3,5,6,5,9,8,24 t=1 29.3999996,-10.8000002 w=1 o=0] operand
+SkOpSegment::debugShowTs - id=17 [o=16 t=0 62.0000076,75.8000031 w=1 o=0] [o=5 t=0.00504 61.8468246,75.7118225 w=1 o=0] [o=18 t=1 31.6000004,58.2999992 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=23 [o=22 t=0 3.33333338e+029,119.400002 w=1 o=0] [o=13 t=1 117.300003,60.9000015 w=1 o=0] [o=1,0,12,11,12,14,15,14,16,16,18,20,19,10,27,2,1,3,4,3,5,6,5,9,8,24 t=1 29.3999996,-10.8000002 w=1 o=0] operand
+SkOpSegment::addTPair addTPair this=17 0 other=23 0.999999881
+SkOpSegment::debugShowTs + id=17 [o=23,16 t=0 62.0000076,75.8000031 w=1 o=0] [o=5 t=0.00504 61.8468246,75.7118225 w=1 o=0] [o=18 t=1 31.6000004,58.2999992 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=23 [o=22 t=0 3.33333338e+029,119.400002 w=1 o=0] [o=13,17 t=1 62.0000076,75.8000031 w=1 o=0] [o=1,0,12,11,12,14,15,14,16,16,18,20,19,10,27,2,1,3,4,3,5,6,5,9,8,24 t=1 29.3999996,-10.8000002 w=1 o=0] operand
+SkOpSegment::debugShowTs - id=11 [o=10,27 t=0 172.5,96 w=1 o=0] [o=1,23,12 t=1 137.600006,96 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=0 [o=10,27 t=0 172.5,96 w=1 o=0] [o=1,23,12 t=1 137.600006,96 w=1 o=0]
+SkOpSegment::debugShowTs + id=11 [o=10,27 t=0 172.5,96 w=1 o=0] [o=1,23,12 t=1 137.600006,96 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=0 [o=10,27 t=0 172.5,96 w=1 o=0] [o=1,23,12 t=1 137.600006,96 w=1 o=0]
+SkOpSegment::debugShowTs - id=19 [o=18 t=0 21.5,96 w=1 o=0] [o=7 t=1.64e-007 21.5000057,96 w=1 o=0] [o=23,20 t=1 56.4000015,96 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=8 [o=7 t=0 21.5000057,96 w=1 o=0] [o=20 t=1 56.4000015,96 w=1 o=0] [o=9,23 t=1 56.4000092,96 w=1 o=0]
+SkOpSegment::addTPair addTPair this=19 1.63955463e-007 other=8 0
+SkOpSegment::addTPair addTPair this=8 0.999999781 other=19 1
+SkOpSegment::debugShowTs + id=19 [o=18 t=0 21.5,96 w=1 o=0] [o=8,7 t=1.64e-007 21.5000057,96 w=1 o=0] [o=8,23,20 t=1 56.4000015,96 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=8 [o=19,7 t=0 21.5000057,96 w=1 o=0] [o=19,20 t=1 56.4000015,96 w=1 o=0] [o=9,23 t=1 56.4000092,96 w=1 o=0]
 SkOpContour::calcCoincidentWinding count=4
-SkOpSegment::debugShowTs p id=0 [o=3,5 t=0 1000,343.000031 w=1 o=-1] [o=7,1 t=1 165,343 w=1 o=0]
-SkOpSegment::debugShowTs o id=4 [o=7,1 t=0 165,343 w=0 o=0] [o=3,5 t=1 1000,343.000031 w=1 o=0] operand done
-SkOpSegment::debugShowTs p id=1 [o=4,0 t=0 165,343 w=1 o=0] [o=7 t=1.4e-006 165,343.000031 w=1 o=-1] [o=7,6,2 t=1 165,364.869873 w=1 o=0]
-SkOpSegment::debugShowTs o id=7 [o=1,6,2 t=0 165,364.869904 w=0 o=0] [o=1,4,0 t=1 165,343.000031 w=1 o=0] operand done
-SkOpSegment::debugShowTs p id=2 [o=1,7 t=0 165,364.869904 w=1 o=-1] [o=5,3 t=1 1000,364.869873 w=1 o=0]
-SkOpSegment::debugShowTs o id=6 [o=5,3 t=0 1000,364.869873 w=0 o=0] [o=1,7 t=1 165,364.869904 w=1 o=0] operand done
-SkOpSegment::debugShowTs p id=3 [o=6,2,5 t=0 1000,364.869904 w=1 o=-1] [o=5 t=1 1000,343.000031 w=1 o=0] [o=4,0 t=1 1000,343 w=1 o=0]
-SkOpSegment::debugShowTs o id=5 [o=3,4,0 t=0 1000,343.000031 w=0 o=0] [o=3,6,2 t=1 1000,364.869904 w=1 o=0] operand done
-SkOpSegment::addTPair addTPair this=0 0 other=4 1
-SkOpSegment::addTPair addTPair this=0 1 other=4 0
-SkOpSegment::addTPair addTPair this=6 1 other=2 0
-SkOpSegment::addTPair addTPair duplicate this=2 0 other=6 1
-SkOpSegment::addTPair addTPair this=2 1 other=6 0
-SkOpContour::joinCoincidence count=4
-SkOpSegment::sortAngles [0] tStart=0 [0]
-SkOpSegment::sortAngles [0] tStart=1 [5]
-SkOpSegment::sortAngles [1] tStart=1.39541634e-006 [2]
-SkOpSegment::sortAngles [1] tStart=1 [5]
-SkOpSegment::sortAngles [2] tStart=1 [5]
-SkOpSegment::sortAngles [3] tStart=0.999998605 [3]
-SkOpSegment::debugShowActiveSpans id=0 (1000,343 165,343) t=0 (1000,343) tEnd=1 other=3 otherT=1 otherIndex=5 windSum=? windValue=1 oppValue=-1
-SkOpSegment::debugShowActiveSpans id=1 (165,343 165,364.869873) t=1.39541634e-006 (165,343.000031) tEnd=1 other=7 otherT=1 otherIndex=3 windSum=? windValue=1 oppValue=-1
-SkOpSegment::debugShowActiveSpans id=2 (165,364.869873 1000,364.869873) t=0 (165,364.869873) tEnd=1 other=6 otherT=1 otherIndex=3 windSum=? windValue=1 oppValue=-1
-SkOpSegment::debugShowActiveSpans id=3 (1000,364.869873 1000,343) t=0 (1000,364.869873) tEnd=0.999998605 other=6 otherT=0 otherIndex=2 windSum=? windValue=1 oppValue=-1
-Assemble
 
 </div>
 
@@ -88,7 +174,7 @@
 <script type="text/javascript">
 
 var testDivs = [
-    skpwww_argus_presse_fr_41,
+    fuzz487a,
 ];
 
 var decimal_places = 3; // make this 3 to show more precision
diff --git a/tools/picture_utils.cpp b/tools/picture_utils.cpp
index 597fd48..5c120b0 100644
--- a/tools/picture_utils.cpp
+++ b/tools/picture_utils.cpp
@@ -18,7 +18,7 @@
     void force_all_opaque(const SkBitmap& bitmap) {
         SkASSERT(NULL == bitmap.getTexture());
         SkASSERT(kN32_SkColorType == bitmap.colorType());
-        if (NULL != bitmap.getTexture() || kN32_SkColorType == bitmap.colorType()) {
+        if (bitmap.getTexture() || kN32_SkColorType == bitmap.colorType()) {
             return;
         }
 
@@ -55,12 +55,12 @@
                               const char *subdirOrNull, const SkString& baseName) {
         SkString partialPath;
         if (subdirOrNull) {
-            partialPath = SkOSPath::SkPathJoin(dirPath.c_str(), subdirOrNull);
+            partialPath = SkOSPath::Join(dirPath.c_str(), subdirOrNull);
             sk_mkdir(partialPath.c_str());
         } else {
             partialPath.set(dirPath);
         }
-        SkString fullPath = SkOSPath::SkPathJoin(partialPath.c_str(), baseName.c_str());
+        SkString fullPath = SkOSPath::Join(partialPath.c_str(), baseName.c_str());
         if (SkImageEncoder::EncodeFile(fullPath.c_str(), bm, SkImageEncoder::kPNG_Type, 100)) {
             return true;
         } else {
diff --git a/tools/pinspect.cpp b/tools/pinspect.cpp
index 368d6fe..18c0d70 100644
--- a/tools/pinspect.cpp
+++ b/tools/pinspect.cpp
@@ -40,7 +40,9 @@
         SkDebugf("Could not create SkPicture: %s\n", path);
         return NULL;
     }
-    printf("picture size:[%d %d]\n", pic->width(), pic->height());
+    printf("picture cullRect: [%f %f %f %f]\n", 
+           pic->cullRect().fLeft, pic->cullRect().fTop,
+           pic->cullRect().fRight, pic->cullRect().fBottom);
     return pic;
 }
 
diff --git a/tools/pyutils/__init__.py b/tools/pyutils/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tools/pyutils/__init__.py
+++ /dev/null
diff --git a/tools/pyutils/gs_utils.py b/tools/pyutils/gs_utils.py
deleted file mode 100755
index 2659c03..0000000
--- a/tools/pyutils/gs_utils.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/python
-
-"""
-Copyright 2014 Google Inc.
-
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
-
-Utilities for accessing Google Cloud Storage.
-
-TODO(epoger): move this into tools/utils for broader use?
-"""
-
-# System-level imports
-import os
-import posixpath
-import sys
-try:
-  from apiclient.discovery import build as build_service
-except ImportError:
-  print ('Missing google-api-python-client.  Please install it; directions '
-         'can be found at https://developers.google.com/api-client-library/'
-         'python/start/installation')
-  raise
-
-# Local imports
-import url_utils
-
-
-def download_file(source_bucket, source_path, dest_path,
-                  create_subdirs_if_needed=False):
-  """ Downloads a single file from Google Cloud Storage to local disk.
-
-  Args:
-    source_bucket: GCS bucket to download the file from
-    source_path: full path (Posix-style) within that bucket
-    dest_path: full path (local-OS-style) on local disk to copy the file to
-    create_subdirs_if_needed: boolean; whether to create subdirectories as
-        needed to create dest_path
-  """
-  source_http_url = posixpath.join(
-      'http://storage.googleapis.com', source_bucket, source_path)
-  url_utils.copy_contents(source_url=source_http_url, dest_path=dest_path,
-                          create_subdirs_if_needed=create_subdirs_if_needed)
-
-
-def list_bucket_contents(bucket, subdir=None):
-  """ Returns files in the Google Cloud Storage bucket as a (dirs, files) tuple.
-
-  Uses the API documented at
-  https://developers.google.com/storage/docs/json_api/v1/objects/list
-
-  Args:
-    bucket: name of the Google Storage bucket
-    subdir: directory within the bucket to list, or None for root directory
-  """
-  # The GCS command relies on the subdir name (if any) ending with a slash.
-  if subdir and not subdir.endswith('/'):
-    subdir += '/'
-  subdir_length = len(subdir) if subdir else 0
-
-  storage = build_service('storage', 'v1')
-  command = storage.objects().list(
-      bucket=bucket, delimiter='/', fields='items(name),prefixes',
-      prefix=subdir)
-  results = command.execute()
-
-  # The GCS command returned two subdicts:
-  # prefixes: the full path of every directory within subdir, with trailing '/'
-  # items: property dict for each file object within subdir
-  #        (including 'name', which is full path of the object)
-  dirs = []
-  for dir_fullpath in results.get('prefixes', []):
-    dir_basename = dir_fullpath[subdir_length:]
-    dirs.append(dir_basename[:-1])  # strip trailing slash
-  files = []
-  for file_properties in results.get('items', []):
-    file_fullpath = file_properties['name']
-    file_basename = file_fullpath[subdir_length:]
-    files.append(file_basename)
-  return (dirs, files)
diff --git a/tools/pyutils/url_utils.py b/tools/pyutils/url_utils.py
deleted file mode 100755
index b107f56..0000000
--- a/tools/pyutils/url_utils.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/python
-
-"""
-Copyright 2014 Google Inc.
-
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
-
-Utilities for working with URLs.
-
-TODO(epoger): move this into tools/utils for broader use?
-"""
-
-# System-level imports
-import contextlib
-import os
-import shutil
-import urllib
-import urlparse
-
-
-def create_filepath_url(filepath):
-  """ Returns a file:/// URL pointing at the given filepath on local disk.
-
-  Args:
-    filepath: string; path to a file on local disk (may be absolute or relative,
-        and the file does not need to exist)
-
-  Returns:
-    A file:/// URL pointing at the file.  Regardless of whether filepath was
-        specified as a relative or absolute path, the URL will contain an
-        absolute path to the file.
-
-  Raises:
-    An Exception, if filepath is already a URL.
-  """
-  if urlparse.urlparse(filepath).scheme:
-    raise Exception('"%s" is already a URL' % filepath)
-  return urlparse.urljoin(
-      'file:', urllib.pathname2url(os.path.abspath(filepath)))
-
-
-def copy_contents(source_url, dest_path, create_subdirs_if_needed=False):
-  """ Copies the full contents of the URL 'source_url' into
-  filepath 'dest_path'.
-
-  Args:
-    source_url: string; complete URL to read from
-    dest_path: string; complete filepath to write to (may be absolute or
-        relative)
-    create_subdirs_if_needed: boolean; whether to create subdirectories as
-        needed to create dest_path
-
-  Raises:
-    Some subclass of Exception if unable to read source_url or write dest_path.
-  """
-  if create_subdirs_if_needed:
-    dest_dir = os.path.dirname(dest_path)
-    if not os.path.exists(dest_dir):
-      os.makedirs(dest_dir)
-  with contextlib.closing(urllib.urlopen(source_url)) as source_handle:
-    with open(dest_path, 'wb') as dest_handle:
-      shutil.copyfileobj(fsrc=source_handle, fdst=dest_handle)
diff --git a/tools/pyutils/url_utils_test.py b/tools/pyutils/url_utils_test.py
deleted file mode 100755
index ef3d8c8..0000000
--- a/tools/pyutils/url_utils_test.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/python
-
-"""
-Copyright 2014 Google Inc.
-
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
-
-Test url_utils.py
-"""
-
-# System-level imports
-import os
-import shutil
-import tempfile
-import unittest
-import urllib
-
-# Imports from within Skia
-import url_utils
-
-
-class UrlUtilsTest(unittest.TestCase):
-
-  def test_create_filepath_url(self):
-    """Tests create_filepath_url(). """
-    with self.assertRaises(Exception):
-      url_utils.create_filepath_url('http://1.2.3.4/path')
-    # Pass absolute filepath.
-    self.assertEquals(
-        url_utils.create_filepath_url(
-            '%sdir%sfile' % (os.path.sep, os.path.sep)),
-        'file:///dir/file')
-    # Pass relative filepath.
-    self.assertEquals(
-        url_utils.create_filepath_url(os.path.join('dir', 'file')),
-        'file://%s/dir/file' % urllib.pathname2url(os.getcwd()))
-
-  def test_copy_contents(self):
-    """Tests copy_contents(). """
-    contents = 'these are the contents'
-    tempdir_path = tempfile.mkdtemp()
-    try:
-      source_path = os.path.join(tempdir_path, 'source')
-      source_url = url_utils.create_filepath_url(source_path)
-      with open(source_path, 'w') as source_handle:
-        source_handle.write(contents)
-      dest_path = os.path.join(tempdir_path, 'new_subdir', 'dest')
-      # Destination subdir does not exist, so copy_contents() should fail
-      # if create_subdirs_if_needed is False.
-      with self.assertRaises(Exception):
-        url_utils.copy_contents(source_url=source_url,
-                                dest_path=dest_path,
-                                create_subdirs_if_needed=False)
-      # If create_subdirs_if_needed is True, it should work.
-      url_utils.copy_contents(source_url=source_url,
-                              dest_path=dest_path,
-                              create_subdirs_if_needed=True)
-      self.assertEquals(open(dest_path).read(), contents)
-    finally:
-      shutil.rmtree(tempdir_path)
diff --git a/tools/render_pdfs_main.cpp b/tools/render_pdfs_main.cpp
index 5e33700..dd5f642 100644
--- a/tools/render_pdfs_main.cpp
+++ b/tools/render_pdfs_main.cpp
@@ -6,17 +6,17 @@
  */
 
 #include "SkCanvas.h"
-#include "SkDevice.h"
+#include "SkCommandLineFlags.h"
+#include "SkDocument.h"
 #include "SkForceLinking.h"
 #include "SkGraphics.h"
 #include "SkImageEncoder.h"
 #include "SkOSFile.h"
 #include "SkPicture.h"
-#include "SkPixelRef.h"
 #include "SkStream.h"
 #include "SkTArray.h"
-#include "PdfRenderer.h"
-#include "picture_utils.h"
+#include "SkTSort.h"
+#include "ProcStats.h"
 
 __SK_FORCE_IMAGE_DECODER_LINKING;
 
@@ -38,26 +38,28 @@
 static const char PDF_FILE_EXTENSION[] = "pdf";
 static const char SKP_FILE_EXTENSION[] = "skp";
 
-static void usage(const char* argv0) {
-    SkDebugf("SKP to PDF rendering tool\n");
-    SkDebugf("\n"
-"Usage: \n"
-"     %s <input>... [-w <outputDir>] [--jpegQuality N] \n"
-, argv0);
-    SkDebugf("\n\n");
-    SkDebugf(
-"     input:     A list of directories and files to use as input. Files are\n"
-"                expected to have the .skp extension.\n\n");
-    SkDebugf(
-"     outputDir: directory to write the rendered pdfs.\n\n");
-    SkDebugf("\n");
-        SkDebugf(
-"     jpegQuality N: encodes images in JPEG at quality level N, which can\n"
-"                    be in range 0-100).\n"
-"                    N = -1 will disable JPEG compression.\n"
-"                    Default is N = 100, maximum quality.\n\n");
-    SkDebugf("\n");
-}
+
+DEFINE_string2(inputPaths, r, "",
+              "A list of directories and files to use as input. "
+              "Files are expected to have the .skp extension.");
+
+DEFINE_string2(outputDir, w, "",
+               "Directory to write the rendered pdfs.");
+
+DEFINE_string2(match, m, "",
+               "[~][^]substring[$] [...] of filenames to run.\n"
+               "Multiple matches may be separated by spaces.\n"
+               "~ causes a matching file to always be skipped\n"
+               "^ requires the start of the file to match\n"
+               "$ requires the end of the file to match\n"
+               "^ and $ requires an exact match\n"
+               "If a file does not match any list entry,\n"
+               "it is skipped unless some list entry starts with ~");
+
+DEFINE_int32(jpegQuality, 100,
+             "Encodes images in JPEG at quality level N, which can be in "
+             "range 0-100).   N = -1 will disable JPEG compression. "
+             "Default is N = 100, maximum quality.");
 
 /** Replaces the extension of a file.
  * @param path File name whose extension will be changed.
@@ -81,10 +83,9 @@
     return false;
 }
 
-int gJpegQuality = 100;
 // the size_t* parameter is deprecated, so we ignore it
 static SkData* encode_to_dct_data(size_t*, const SkBitmap& bitmap) {
-    if (gJpegQuality == -1) {
+    if (FLAGS_jpegQuality == -1) {
         return NULL;
     }
 
@@ -97,9 +98,8 @@
     bm = copy;
 #endif
 
-    return SkImageEncoder::EncodeData(bm,
-                                      SkImageEncoder::kJPEG_Type,
-                                      gJpegQuality);
+    return SkImageEncoder::EncodeData(
+            bm, SkImageEncoder::kJPEG_Type, FLAGS_jpegQuality);
 }
 
 /** Builds the output filename. path = dir/name, and it replaces expected
@@ -111,12 +111,26 @@
  */
 static bool make_output_filepath(SkString* path, const SkString& dir,
                                  const SkString& name) {
-    *path = SkOSPath::SkPathJoin(dir.c_str(), name.c_str());
+    *path = SkOSPath::Join(dir.c_str(), name.c_str());
     return replace_filename_extension(path,
                                       SKP_FILE_EXTENSION,
                                       PDF_FILE_EXTENSION);
 }
 
+namespace {
+// This is a write-only stream.
+class NullWStream : public SkWStream {
+public:
+    NullWStream() : fBytesWritten(0) { }
+    virtual bool write(const void*, size_t size) SK_OVERRIDE {
+        fBytesWritten += size;
+        return true;
+    }
+    virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; }
+    size_t fBytesWritten;
+};
+}  // namespace
+
 /** Write the output of pdf renderer to a file.
  * @param outputDir Output dir.
  * @param inputFilename The skp file that was read.
@@ -125,7 +139,7 @@
 static SkWStream* open_stream(const SkString& outputDir,
                               const SkString& inputFilename) {
     if (outputDir.isEmpty()) {
-        return SkNEW(SkDynamicMemoryWStream);
+        return SkNEW(NullWStream);
     }
 
     SkString outputPath;
@@ -133,145 +147,137 @@
         return NULL;
     }
 
-    SkFILEWStream* stream = SkNEW_ARGS(SkFILEWStream, (outputPath.c_str()));
-    if (!stream->isValid()) {
+    SkAutoTDelete<SkFILEWStream> stream(
+            SkNEW_ARGS(SkFILEWStream, (outputPath.c_str())));
+    if (!stream.get() ||  !stream->isValid()) {
         SkDebugf("Could not write to file %s\n", outputPath.c_str());
         return NULL;
     }
 
-    return stream;
+    return stream.detach();
 }
 
-/** Reads an skp file, renders it to pdf and writes the output to a pdf file
- * @param inputPath The skp file to be read.
- * @param outputDir Output dir.
- * @param renderer The object responsible to render the skp object into pdf.
+/**
+ *  Given a SkPicture, write a one-page PDF document to the given
+ *  output, using the provided encoder.
  */
-static bool render_pdf(const SkString& inputPath, const SkString& outputDir,
-                       sk_tools::PdfRenderer& renderer) {
-    SkString inputFilename = SkOSPath::SkBasename(inputPath.c_str());
-
-    SkFILEStream inputStream;
-    inputStream.setPath(inputPath.c_str());
-    if (!inputStream.isValid()) {
-        SkDebugf("Could not open file %s\n", inputPath.c_str());
-        return false;
-    }
-
-    SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream));
-
-    if (NULL == picture.get()) {
-        SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str());
-        return false;
-    }
-
-    SkDebugf("exporting... [%i %i] %s\n", picture->width(), picture->height(),
-             inputPath.c_str());
-
-    SkWStream* stream(open_stream(outputDir, inputFilename));
-
-    if (!stream) {
-        return false;
-    }
-
-    renderer.init(picture, stream);
-
-    bool success = renderer.render();
-    SkDELETE(stream);
-
-    renderer.end();
-
-    return success;
+static bool pdf_to_stream(SkPicture* picture,
+                          SkWStream* output,
+                          SkPicture::EncodeBitmap encoder) {
+    SkAutoTUnref<SkDocument> pdfDocument(
+            SkDocument::CreatePDF(output, NULL, encoder));
+    SkCanvas* canvas = pdfDocument->beginPage(picture->cullRect().width(), 
+                                              picture->cullRect().height());
+    canvas->drawPicture(picture);
+    canvas->flush();
+    return pdfDocument->close();
 }
 
-/** For each file in the directory or for the file passed in input, call
- * render_pdf.
- * @param input A directory or an skp file.
- * @param outputDir Output dir.
- * @param renderer The object responsible to render the skp object into pdf.
+static bool operator<(const SkString& a, const SkString& b) {
+    return strcmp(a.c_str(), b.c_str()) < 0;
+}
+
+/**
+ * @param A list of directories or a skp files.
+ * @returns an alphabetical list of skp files.
  */
-static int process_input(const SkString& input, const SkString& outputDir,
-                         sk_tools::PdfRenderer& renderer) {
-    int failures = 0;
-    if (sk_isdir(input.c_str())) {
-        SkOSFile::Iter iter(input.c_str(), SKP_FILE_EXTENSION);
-        SkString inputFilename;
-        while (iter.next(&inputFilename)) {
-            SkString inputPath = SkOSPath::SkPathJoin(input.c_str(), inputFilename.c_str());
-            if (!render_pdf(inputPath, outputDir, renderer)) {
-                ++failures;
-            }
-        }
-    } else {
-        SkString inputPath(input);
-        if (!render_pdf(inputPath, outputDir, renderer)) {
-            ++failures;
-        }
-    }
-    return failures;
-}
-
-static void parse_commandline(int argc, char* const argv[],
-                              SkTArray<SkString>* inputs,
-                              SkString* outputDir) {
-    const char* argv0 = argv[0];
-    char* const* stop = argv + argc;
-
-    for (++argv; argv < stop; ++argv) {
-        if ((0 == strcmp(*argv, "-h")) || (0 == strcmp(*argv, "--help"))) {
-            usage(argv0);
-            exit(-1);
-        } else if (0 == strcmp(*argv, "-w")) {
-            ++argv;
-            if (argv >= stop) {
-                SkDebugf("Missing outputDir for -w\n");
-                usage(argv0);
-                exit(-1);
-            }
-            *outputDir = SkString(*argv);
-        } else if (0 == strcmp(*argv, "--jpegQuality")) {
-            ++argv;
-            if (argv >= stop) {
-                SkDebugf("Missing argument for --jpegQuality\n");
-                usage(argv0);
-                exit(-1);
-            }
-            gJpegQuality = atoi(*argv);
-            if (gJpegQuality < -1 || gJpegQuality > 100) {
-                SkDebugf("Invalid argument for --jpegQuality\n");
-                usage(argv0);
-                exit(-1);
+static void process_input_files(
+        const SkCommandLineFlags::StringArray& inputs,
+        SkTArray<SkString>* files) {
+    for (int i = 0; i < inputs.count(); i ++) {
+        const char* input = inputs[i];
+        if (sk_isdir(input)) {
+            SkOSFile::Iter iter(input, SKP_FILE_EXTENSION);
+            SkString inputFilename;
+            while (iter.next(&inputFilename)) {
+                if (!SkCommandLineFlags::ShouldSkip(
+                            FLAGS_match, inputFilename.c_str())) {
+                    files->push_back(
+                            SkOSPath::Join(input, inputFilename.c_str()));
+                }
             }
         } else {
-            inputs->push_back(SkString(*argv));
+            if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, input)) {
+                files->push_back(SkString(input));
+            }
         }
     }
-
-    if (inputs->count() < 1) {
-        usage(argv0);
-        exit(-1);
+    if (files->count() > 0) {
+        SkTQSort<SkString>(files->begin(), files->end() - 1);
     }
 }
 
+/** For each input skp file, read it, render it to pdf and write. the
+ *  output to a pdf file
+ */
 int tool_main_core(int argc, char** argv);
 int tool_main_core(int argc, char** argv) {
-    SkAutoGraphics ag;
-    SkTArray<SkString> inputs;
+    SkCommandLineFlags::Parse(argc, argv);
 
-    SkAutoTUnref<sk_tools::PdfRenderer>
-        renderer(SkNEW_ARGS(sk_tools::SimplePdfRenderer, (encode_to_dct_data)));
-    SkASSERT(renderer.get());
+    SkAutoGraphics ag;
 
     SkString outputDir;
-    parse_commandline(argc, argv, &inputs, &outputDir);
-
-    int failures = 0;
-    for (int i = 0; i < inputs.count(); i ++) {
-        failures += process_input(inputs[i], outputDir, *renderer);
+    if (FLAGS_outputDir.count() > 0) {
+        outputDir = FLAGS_outputDir[0];
+        if (!sk_mkdir(outputDir.c_str())) {
+            SkDebugf("Unable to mkdir '%s'\n", outputDir.c_str());
+            return 1;
+        }
     }
 
+    SkTArray<SkString> files;
+    process_input_files(FLAGS_inputPaths, &files);
+
+    size_t maximumPathLength = 0;
+    for (int i = 0; i < files.count(); i ++) {
+        SkString basename = SkOSPath::Basename(files[i].c_str());
+        maximumPathLength = SkTMax(maximumPathLength, basename.size());
+    }
+
+    int failures = 0;
+    for (int i = 0; i < files.count(); i ++) {
+        SkString basename = SkOSPath::Basename(files[i].c_str());
+
+        SkFILEStream inputStream;
+        inputStream.setPath(files[i].c_str());
+        if (!inputStream.isValid()) {
+            SkDebugf("Could not open file %s\n", files[i].c_str());
+            ++failures;
+            continue;
+        }
+
+        SkAutoTUnref<SkPicture> picture(
+                SkPicture::CreateFromStream(&inputStream));
+        if (NULL == picture.get()) {
+            SkDebugf("Could not read an SkPicture from %s\n",
+                     files[i].c_str());
+            ++failures;
+            continue;
+        }
+        SkDebugf("[%f,%f,%f,%f] %-*s", 
+            picture->cullRect().fLeft, picture->cullRect().fTop,
+            picture->cullRect().fRight, picture->cullRect().fBottom,
+            maximumPathLength, basename.c_str());
+
+        SkAutoTDelete<SkWStream> stream(open_stream(outputDir, files[i]));
+        if (!stream.get()) {
+            ++failures;
+            continue;
+        }
+        if (!pdf_to_stream(picture, stream.get(), encode_to_dct_data)) {
+            SkDebugf("Error in PDF Serialization.");
+            ++failures;
+        }
+
+        int max_rss_mb = sk_tools::getMaxResidentSetSizeMB();
+        if (max_rss_mb >= 0) {
+            SkDebugf(" %4dM peak rss", max_rss_mb);
+        }
+
+        SkDebugf("\n");
+    }
     if (failures != 0) {
-        SkDebugf("Failed to render %i PDFs.\n", failures);
+        SkDebugf("Failed to render %i of %i PDFs.\n", failures, files.count());
         return 1;
     }
 
@@ -294,7 +300,6 @@
 #endif
     return 0;
 }
-
 #if !defined SK_BUILD_FOR_IOS
 int main(int argc, char * const argv[]) {
     return tool_main(argc, (char**) argv);
diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp
index 850053c..d7a213c 100644
--- a/tools/render_pictures_main.cpp
+++ b/tools/render_pictures_main.cpp
@@ -26,13 +26,21 @@
 #include "picture_utils.h"
 
 // Flags used by this file, alphabetically:
-DEFINE_int32(clone, 0, "Clone the picture n times before rendering.");
+DEFINE_bool(bench_record, false, "If true, drop into an infinite loop of recording the picture.");
 DECLARE_bool(deferImageDecoding);
+DEFINE_string(descriptions, "", "one or more key=value pairs to add to the descriptions section "
+              "of the JSON summary.");
+DEFINE_string(imageBaseGSUrl, "", "The Google Storage image base URL the images are stored in.");
 DEFINE_int32(maxComponentDiff, 256, "Maximum diff on a component, 0 - 256. Components that differ "
              "by more than this amount are considered errors, though all diffs are reported. "
              "Requires --validate.");
 DEFINE_string(mismatchPath, "", "Write images for tests that failed due to "
               "pixel mismatches into this directory.");
+#if GR_GPU_STATS
+DEFINE_bool(gpuStats, false, "Only meaningful with gpu configurations. "
+            "Report some GPU call statistics.");
+#endif
+DEFINE_bool(preprocess, false, "If true, perform device specific preprocessing before rendering.");
 DEFINE_string(readJsonSummaryPath, "", "JSON file to read image expectations from.");
 DECLARE_string(readPath);
 DEFINE_bool(writeChecksumBasedFilenames, false,
@@ -48,10 +56,6 @@
             "the picture rendered in simple mode. When used in conjunction with --bbh, results "
             "are validated against the picture rendered in the same mode, but without the bbh.");
 
-DEFINE_bool(bench_record, false, "If true, drop into an infinite loop of recording the picture.");
-
-DEFINE_bool(preprocess, false, "If true, perform device specific preprocessing before rendering.");
-
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 /**
@@ -124,7 +128,7 @@
     SkString name = SkStringPrintf("%s_%d%s", gInputFileName.c_str(), gImageNo++,
                                    get_suffix_from_format(format));
     SkString dir(FLAGS_writePath[0]);
-    outPath = SkOSPath::SkPathJoin(dir.c_str(), name.c_str());
+    outPath = SkOSPath::Join(dir.c_str(), name.c_str());
     SkFILEWStream fileStream(outPath.c_str());
     if (!(fileStream.isValid() && fileStream.write(buffer, size))) {
         SkDebugf("Failed to write encoded data to \"%s\"\n", outPath.c_str());
@@ -143,13 +147,13 @@
                                     const SkString* mismatchPath,
                                     sk_tools::PictureRenderer& renderer,
                                     SkBitmap** out) {
-    SkString inputFilename = SkOSPath::SkBasename(inputPath.c_str());
+    SkString inputFilename = SkOSPath::Basename(inputPath.c_str());
     SkString writePathString;
-    if (NULL != writePath && writePath->size() > 0 && !FLAGS_writeEncodedImages) {
+    if (writePath && writePath->size() > 0 && !FLAGS_writeEncodedImages) {
         writePathString.set(*writePath);
     }
     SkString mismatchPathString;
-    if (NULL != mismatchPath && mismatchPath->size() > 0) {
+    if (mismatchPath && mismatchPath->size() > 0) {
         mismatchPathString.set(*mismatchPath);
     }
 
@@ -173,33 +177,41 @@
 
     SkDebugf("deserializing... %s\n", inputPath.c_str());
 
-    SkPicture* picture = SkPicture::CreateFromStream(&inputStream, proc);
+    SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream, proc));
 
     if (NULL == picture) {
         SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str());
         return false;
     }
 
+    if (FLAGS_preprocess) {
+        // Because the GPU preprocessing step relies on the in-memory picture
+        // statistics we need to rerecord the picture here
+        SkPictureRecorder recorder;
+        picture->playback(recorder.beginRecording(picture->cullRect().width(), 
+                                                  picture->cullRect().height(), 
+                                                  NULL, 0));
+        picture.reset(recorder.endRecording());
+    }
+
     while (FLAGS_bench_record) {
         SkPictureRecorder recorder;
-        picture->draw(recorder.beginRecording(picture->width(), picture->height(), NULL, 0));
+        picture->playback(recorder.beginRecording(picture->cullRect().width(), 
+                                                  picture->cullRect().height(), 
+                                                  NULL, 0));
         SkAutoTUnref<SkPicture> other(recorder.endRecording());
     }
 
-    for (int i = 0; i < FLAGS_clone; ++i) {
-        SkPicture* clone = picture->clone();
-        SkDELETE(picture);
-        picture = clone;
-    }
-
-    SkDebugf("drawing... [%i %i] %s\n", picture->width(), picture->height(),
+    SkDebugf("drawing... [%f %f %f %f] %s\n", 
+             picture->cullRect().fLeft, picture->cullRect().fTop,
+             picture->cullRect().fRight, picture->cullRect().fBottom,
              inputPath.c_str());
 
     renderer.init(picture, &writePathString, &mismatchPathString, &inputFilename,
                   FLAGS_writeChecksumBasedFilenames);
 
     if (FLAGS_preprocess) {
-        if (NULL != renderer.getCanvas()) {
+        if (renderer.getCanvas()) {
             renderer.getCanvas()->EXPERIMENTAL_optimize(renderer.getPicture());
         }
     }
@@ -214,7 +226,6 @@
 
     renderer.end();
 
-    SkDELETE(picture);
     return success;
 }
 
@@ -243,7 +254,7 @@
     }
 
     ~AutoRestoreBbhType() {
-        if (NULL != fRenderer) {
+        if (fRenderer) {
             fRenderer->setBBoxHierarchyType(fSavedBbhType);
         }
     }
@@ -292,7 +303,12 @@
             referenceRenderer->ref();  // to match auto unref below
             arbbh.set(referenceRenderer, sk_tools::PictureRenderer::kNone_BBoxHierarchyType);
         } else {
+#if SK_SUPPORT_GPU
+            referenceRenderer = SkNEW_ARGS(sk_tools::SimplePictureRenderer,
+                                           (renderer.getGrContextOptions()));
+#else
             referenceRenderer = SkNEW(sk_tools::SimplePictureRenderer);
+#endif
         }
         SkAutoTUnref<sk_tools::PictureRenderer> aurReferenceRenderer(referenceRenderer);
 
@@ -352,22 +368,22 @@
     if (FLAGS_writeWholeImage) {
         sk_tools::force_all_opaque(*bitmap);
 
-        SkString inputFilename = SkOSPath::SkBasename(inputPath.c_str());
+        SkString inputFilename = SkOSPath::Basename(inputPath.c_str());
         SkString outputFilename(inputFilename);
         sk_tools::replace_char(&outputFilename, '.', '_');
         outputFilename.append(".png");
 
-        if (NULL != jsonSummaryPtr) {
+        if (jsonSummaryPtr) {
             sk_tools::ImageDigest imageDigest(*bitmap);
             jsonSummaryPtr->add(inputFilename.c_str(), outputFilename.c_str(), imageDigest);
-            if ((NULL != mismatchPath) && !mismatchPath->isEmpty() &&
-                !jsonSummaryPtr->matchesExpectation(inputFilename.c_str(), imageDigest)) {
+            if ((mismatchPath) && !mismatchPath->isEmpty() &&
+                !jsonSummaryPtr->getExpectation(inputFilename.c_str()).matches(imageDigest)) {
                 success &= sk_tools::write_bitmap_to_disk(*bitmap, *mismatchPath, NULL,
                                                           outputFilename);
             }
         }
 
-        if ((NULL != writePath) && !writePath->isEmpty()) {
+        if ((writePath) && !writePath->isEmpty()) {
             success &= sk_tools::write_bitmap_to_disk(*bitmap, *writePath, NULL, outputFilename);
         }
     }
@@ -386,7 +402,7 @@
     SkDebugf("process_input, %s\n", input);
     if (iter.next(&inputFilename)) {
         do {
-            SkString inputPath = SkOSPath::SkPathJoin(input, inputFilename.c_str());
+            SkString inputPath = SkOSPath::Join(input, inputFilename.c_str());
             if (!render_picture(inputPath, writePath, mismatchPath, renderer, jsonSummaryPtr)) {
                 ++failures;
             }
@@ -424,11 +440,6 @@
         exit(-1);
     }
 
-    if (FLAGS_clone < 0) {
-        SkDebugf("--clone must be >= 0. Was %i\n", FLAGS_clone);
-        exit(-1);
-    }
-
     if (FLAGS_writeEncodedImages) {
         if (FLAGS_writePath.isEmpty()) {
             SkDebugf("--writeEncodedImages requires --writePath\n");
@@ -489,8 +500,25 @@
 #endif
     }
 #endif
+#if GR_GPU_STATS
+    if (FLAGS_gpuStats && renderer->isUsingGpuDevice()) {
+        GrContext* ctx = renderer->getGrContext();
+        SkDebugf("RenderTarget Binds: %d\n", ctx->gpuStats()->renderTargetBinds());
+        SkDebugf("Shader Compilations: %d\n", ctx->gpuStats()->shaderCompilations());
+    }
+#endif
 #endif
     if (FLAGS_writeJsonSummaryPath.count() == 1) {
+        // If there were any descriptions on the command line, insert them now.
+        for (int i=0; i<FLAGS_descriptions.count(); i++) {
+            SkTArray<SkString> tokens;
+            SkStrSplit(FLAGS_descriptions[i], "=", &tokens);
+            SkASSERT(tokens.count() == 2);
+            jsonSummary.addDescription(tokens[0].c_str(), tokens[1].c_str());
+        }
+        if (FLAGS_imageBaseGSUrl.count() == 1) {
+          jsonSummary.setImageBaseGSUrl(FLAGS_imageBaseGSUrl[0]);
+        }
         jsonSummary.writeToFile(FLAGS_writeJsonSummaryPath[0]);
     }
     return 0;
diff --git a/tools/roll_deps.py b/tools/roll_deps.py
index d280bda..e255099 100755
--- a/tools/roll_deps.py
+++ b/tools/roll_deps.py
@@ -28,516 +28,271 @@
 import os
 import re
 import shutil
-import subprocess
 import sys
 import tempfile
 
-import git_utils
-import misc_utils
+import fix_pythonpath # pylint: disable=W0611
+from common.py.utils import git_utils
+from common.py.utils import misc
+from common.py.utils import shell_utils
 
 
 DEFAULT_BOTS_LIST = [
-    'android_clang_dbg',
-    'android_dbg',
-    'android_rel',
-    'cros_daisy',
-    'linux',
-    'linux_asan',
-    'linux_chromeos',
-    'linux_chromeos_asan',
-    'linux_chromium_gn_dbg',
-    'linux_gpu',
-    'linux_layout',
-    'linux_layout_rel',
-    'mac',
-    'mac_asan',
-    'mac_gpu',
-    'mac_layout',
-    'mac_layout_rel',
-    'win',
-    'win_gpu',
-    'win_layout',
-    'win_layout_rel',
+  'android_clang_dbg',
+  'android_dbg',
+  'android_rel',
+  'cros_daisy',
+  'linux',
+  'linux_asan',
+  'linux_chromeos',
+  'linux_chromeos_asan',
+  'linux_chromium_gn_dbg',
+  'linux_gpu',
+  'linux_layout',
+  'linux_layout_rel',
+  'mac',
+  'mac_asan',
+  'mac_gpu',
+  'mac_layout',
+  'mac_layout_rel',
+  'win',
+  'win_gpu',
+  'win_layout',
+  'win_layout_rel',
 ]
 
+REGEXP_SKIA_REVISION = (
+    r'^  "skia_revision": "(?P<revision>[0-9a-fA-F]{2,40})",$')
+
 
 class DepsRollConfig(object):
-    """Contains configuration options for this module.
+  """Contains configuration options for this module.
 
-    Attributes:
-        git: (string) The git executable.
-        chromium_path: (string) path to a local chromium git repository.
-        save_branches: (boolean) iff false, delete temporary branches.
-        verbose: (boolean)  iff false, suppress the output from git-cl.
-        search_depth: (int) how far back to look for the revision.
-        skia_url: (string) Skia's git repository.
-        self.skip_cl_upload: (boolean)
-        self.cl_bot_list: (list of strings)
+  Attributes:
+      chromium_path: (string) path to a local chromium git repository.
+      save_branches: (boolean) iff false, delete temporary branches.
+      verbose: (boolean)  iff false, suppress the output from git-cl.
+      skip_cl_upload: (boolean)
+      cl_bot_list: (list of strings)
+  """
+
+  # pylint: disable=I0011,R0903,R0902
+  def __init__(self, options=None):
+    if not options:
+      options = DepsRollConfig.GetOptionParser()
+    # pylint: disable=I0011,E1103
+    self.verbose = options.verbose
+    self.save_branches = not options.delete_branches
+    self.chromium_path = options.chromium_path
+    self.skip_cl_upload = options.skip_cl_upload
+    # Split and remove empty strigns from the bot list.
+    self.cl_bot_list = [bot for bot in options.bots.split(',') if bot]
+    self.default_branch_name = 'autogenerated_deps_roll_branch'
+    self.reviewers_list = ','.join([
+        # 'rmistry@google.com',
+        # 'reed@google.com',
+        # 'bsalomon@google.com',
+        # 'robertphillips@google.com',
+        ])
+    self.cc_list = ','.join([
+        # 'skia-team@google.com',
+        ])
+
+  @staticmethod
+  def GetOptionParser():
+    # pylint: disable=I0011,C0103
+    """Returns an optparse.OptionParser object.
+
+    Returns:
+        An optparse.OptionParser object.
+
+    Called by the main() function.
     """
+    option_parser = optparse.OptionParser(usage=__doc__)
+    # Anyone using this script on a regular basis should set the
+    # CHROMIUM_CHECKOUT_PATH environment variable.
+    option_parser.add_option(
+        '-c', '--chromium_path', help='Path to local Chromium Git'
+        ' repository checkout, defaults to CHROMIUM_CHECKOUT_PATH'
+        ' if that environment variable is set.',
+        default=os.environ.get('CHROMIUM_CHECKOUT_PATH'))
+    option_parser.add_option(
+        '-r', '--revision', default=None,
+        help='The Skia Git commit hash.')
 
-    # pylint: disable=I0011,R0903,R0902
-    def __init__(self, options=None):
-        self.skia_url = 'https://skia.googlesource.com/skia.git'
-        self.revision_format = (
-            'git-svn-id: http://skia.googlecode.com/svn/trunk@%d ')
+    option_parser.add_option(
+        '', '--delete_branches', help='Delete the temporary branches',
+        action='store_true', dest='delete_branches', default=False)
+    option_parser.add_option(
+        '', '--verbose', help='Do not suppress the output from `git cl`.',
+        action='store_true', dest='verbose', default=False)
+    option_parser.add_option(
+        '', '--skip_cl_upload', help='Skip the cl upload step; useful'
+        ' for testing.',
+        action='store_true', default=False)
 
-        self.git = git_utils.git_executable()
+    default_bots_help = (
+        'Comma-separated list of bots, defaults to a list of %d bots.'
+        '  To skip `git cl try`, set this to an empty string.'
+        % len(DEFAULT_BOTS_LIST))
+    default_bots = ','.join(DEFAULT_BOTS_LIST)
+    option_parser.add_option(
+        '', '--bots', help=default_bots_help, default=default_bots)
 
-        if not options:
-            options = DepsRollConfig.GetOptionParser()
-        # pylint: disable=I0011,E1103
-        self.verbose = options.verbose
-        self.vsp = misc_utils.VerboseSubprocess(self.verbose)
-        self.save_branches = not options.delete_branches
-        self.search_depth = options.search_depth
-        self.chromium_path = options.chromium_path
-        self.skip_cl_upload = options.skip_cl_upload
-        # Split and remove empty strigns from the bot list.
-        self.cl_bot_list = [bot for bot in options.bots.split(',') if bot]
-        self.skia_git_checkout_path = options.skia_git_path
-        self.default_branch_name = 'autogenerated_deps_roll_branch'
-        self.reviewers_list = ','.join([
-            # 'rmistry@google.com',
-            # 'reed@google.com',
-            # 'bsalomon@google.com',
-            # 'robertphillips@google.com',
-            ])
-        self.cc_list = ','.join([
-            # 'skia-team@google.com',
-            ])
-
-    @staticmethod
-    def GetOptionParser():
-        # pylint: disable=I0011,C0103
-        """Returns an optparse.OptionParser object.
-
-        Returns:
-            An optparse.OptionParser object.
-
-        Called by the main() function.
-        """
-        option_parser = optparse.OptionParser(usage=__doc__)
-        # Anyone using this script on a regular basis should set the
-        # CHROMIUM_CHECKOUT_PATH environment variable.
-        option_parser.add_option(
-            '-c', '--chromium_path', help='Path to local Chromium Git'
-            ' repository checkout, defaults to CHROMIUM_CHECKOUT_PATH'
-            ' if that environment variable is set.',
-            default=os.environ.get('CHROMIUM_CHECKOUT_PATH'))
-        option_parser.add_option(
-            '-r', '--revision', type='int', default=None,
-            help='The Skia SVN revision number, defaults to top of tree.')
-        option_parser.add_option(
-            '-g', '--git_hash', default=None,
-            help='A partial Skia Git hash.  Do not set this and revision.')
-
-        # Anyone using this script on a regular basis should set the
-        # SKIA_GIT_CHECKOUT_PATH environment variable.
-        option_parser.add_option(
-            '', '--skia_git_path',
-            help='Path of a pure-git Skia repository checkout.  If empty,'
-            ' a temporary will be cloned.  Defaults to SKIA_GIT_CHECKOUT'
-            '_PATH, if that environment variable is set.',
-            default=os.environ.get('SKIA_GIT_CHECKOUT_PATH'))
-        option_parser.add_option(
-            '', '--search_depth', type='int', default=100,
-            help='How far back to look for the revision.')
-        option_parser.add_option(
-            '', '--delete_branches', help='Delete the temporary branches',
-            action='store_true', dest='delete_branches', default=False)
-        option_parser.add_option(
-            '', '--verbose', help='Do not suppress the output from `git cl`.',
-            action='store_true', dest='verbose', default=False)
-        option_parser.add_option(
-            '', '--skip_cl_upload', help='Skip the cl upload step; useful'
-            ' for testing.',
-            action='store_true', default=False)
-
-        default_bots_help = (
-            'Comma-separated list of bots, defaults to a list of %d bots.'
-            '  To skip `git cl try`, set this to an empty string.'
-            % len(DEFAULT_BOTS_LIST))
-        default_bots = ','.join(DEFAULT_BOTS_LIST)
-        option_parser.add_option(
-            '', '--bots', help=default_bots_help, default=default_bots)
-
-        return option_parser
+    return option_parser
 
 
 class DepsRollError(Exception):
-    """Exceptions specific to this module."""
-    pass
+  """Exceptions specific to this module."""
+  pass
 
 
-def get_svn_revision(config, commit):
-    """Works in both git and git-svn. returns a string."""
-    svn_format = (
-        '(git-svn-id: [^@ ]+@|SVN changes up to revision |'
-        'LKGR w/ DEPS up to revision )(?P<return>[0-9]+)')
-    svn_revision = misc_utils.ReSearch.search_within_output(
-        config.verbose, svn_format, None,
-        [config.git, 'log', '-n', '1', '--format=format:%B', commit])
-    if not svn_revision:
-        raise DepsRollError(
-            'Revision number missing from Chromium origin/master.')
-    return int(svn_revision)
+def change_skia_deps(revision, depspath):
+  """Update the DEPS file.
 
+  Modify the skia_revision entry in the given DEPS file.
 
-class SkiaGitCheckout(object):
-    """Class to create a temporary skia git checkout, if necessary.
-    """
-    # pylint: disable=I0011,R0903
+  Args:
+      revision: (string) Skia commit hash.
+      depspath: (string) path to DEPS file.
+  """
+  temp_file = tempfile.NamedTemporaryFile(delete=False,
+                                          prefix='skia_DEPS_ROLL_tmp_')
+  try:
+    deps_regex_rev = re.compile(REGEXP_SKIA_REVISION)
+    deps_regex_rev_repl = '  "skia_revision": "%s",' % revision
 
-    def __init__(self, config, depth):
-        self._config = config
-        self._depth = depth
-        self._use_temp = None
-        self._original_cwd = None
+    with open(depspath, 'r') as input_stream:
+      for line in input_stream:
+        line = deps_regex_rev.sub(deps_regex_rev_repl, line)
+        temp_file.write(line)
+  finally:
+    temp_file.close()
+  shutil.move(temp_file.name, depspath)
 
-    def __enter__(self):
-        config = self._config
-        git = config.git
-        skia_dir = None
-        self._original_cwd = os.getcwd()
-        if config.skia_git_checkout_path:
-            if config.skia_git_checkout_path != os.curdir:
-                skia_dir = config.skia_git_checkout_path
-                ## Update origin/master if needed.
-                if self._config.verbose:
-                    print '~~$', 'cd', skia_dir
-                os.chdir(skia_dir)
-            config.vsp.check_call([git, 'fetch', '-q', 'origin'])
-            self._use_temp = None
-        else:
-            skia_dir = tempfile.mkdtemp(prefix='git_skia_tmp_')
-            self._use_temp = skia_dir
-            try:
-                os.chdir(skia_dir)
-                config.vsp.check_call(
-                    [git, 'clone', '-q', '--depth=%d' % self._depth,
-                     '--single-branch', config.skia_url, '.'])
-            except (OSError, subprocess.CalledProcessError) as error:
-                shutil.rmtree(skia_dir)
-                raise error
 
-    def __exit__(self, etype, value, traceback):
-        if self._config.skia_git_checkout_path != os.curdir:
-            if self._config.verbose:
-                print '~~$', 'cd', self._original_cwd
-            os.chdir(self._original_cwd)
-        if self._use_temp:
-            shutil.rmtree(self._use_temp)
+def submit_tries(bots_to_run, dry_run=False):
+  """Submit try requests for the current branch on the given bots.
 
+  Args:
+      bots_to_run: (list of strings) bots to request.
+      dry_run: (bool) whether to actually submit the try request.
+  """
+  git_try = [
+      git_utils.GIT, 'cl', 'try', '-m', 'tryserver.chromium']
+  git_try.extend([arg for bot in bots_to_run for arg in ('-b', bot)])
 
-def revision_and_hash(config):
-    """Finds revision number and git hash of origin/master in the Skia tree.
+  if dry_run:
+    space = '   '
+    print 'You should call:'
+    print space, git_try
+    print
+  else:
+    shell_utils.run(git_try)
 
-    Args:
-        config: (roll_deps.DepsRollConfig) object containing options.
 
-    Returns:
-        A tuple (revision, hash)
-            revision: (int) SVN revision number.
-            git_hash: (string) full Git commit hash.
+def roll_deps(config, revision):
+  """Upload changed DEPS and a whitespace change.
 
-    Raises:
-        roll_deps.DepsRollError: if the revision can't be found.
-        OSError: failed to execute git or git-cl.
-        subprocess.CalledProcessError: git returned unexpected status.
-    """
-    with SkiaGitCheckout(config, 1):
-        revision = get_svn_revision(config, 'origin/master')
-        git_hash = config.vsp.strip_output(
-            [config.git, 'show-ref', 'origin/master', '--hash'])
-        if not git_hash:
-            raise DepsRollError('Git hash can not be found.')
-    return revision, git_hash
+  Given the correct git_hash, create two Reitveld issues.
 
+  Args:
+      config: (roll_deps.DepsRollConfig) object containing options.
+      revision: (string) Skia Git hash.
 
-def revision_and_hash_from_revision(config, revision):
-    """Finds revision number and git hash of a commit in the Skia tree.
+  Returns:
+      a tuple containing textual description of the two issues.
 
-    Args:
-        config: (roll_deps.DepsRollConfig) object containing options.
-        revision: (int) SVN revision number.
+  Raises:
+      OSError: failed to execute git or git-cl.
+      subprocess.CalledProcessError: git returned unexpected status.
+  """
+  with misc.ChDir(config.chromium_path, verbose=config.verbose):
+    git_utils.Fetch()
+    output = shell_utils.run([git_utils.GIT, 'show', 'origin/master:DEPS'],
+                             log_in_real_time=False).rstrip()
+    match = re.search(REGEXP_SKIA_REVISION, output, flags=re.MULTILINE)
+    old_revision = None
+    if match:
+      old_revision = match.group('revision')
+    assert old_revision
 
-    Returns:
-        A tuple (revision, hash)
-            revision: (int) SVN revision number.
-            git_hash: (string) full Git commit hash.
+    master_hash = git_utils.FullHash('origin/master').rstrip()
 
-    Raises:
-        roll_deps.DepsRollError: if the revision can't be found.
-        OSError: failed to execute git or git-cl.
-        subprocess.CalledProcessError: git returned unexpected status.
-    """
-    with SkiaGitCheckout(config, config.search_depth):
-        revision_regex = config.revision_format % revision
-        git_hash = config.vsp.strip_output(
-            [config.git, 'log', '--grep', revision_regex,
-             '--format=format:%H', 'origin/master'])
-        if not git_hash:
-            raise DepsRollError('Git hash can not be found.')
-    return revision, git_hash
+    # master_hash[8] gives each whitespace CL a unique name.
+    branch = 'control_%s' % master_hash[:8]
+    message = ('whitespace change %s\n\n'
+               'Chromium base revision: %s\n\n'
+               'This CL was created by Skia\'s roll_deps.py script.\n'
+               ) % (master_hash[:8], master_hash[:8])
+    with git_utils.GitBranch(branch, message,
+                             delete_when_finished=not config.save_branches,
+                             upload=not config.skip_cl_upload
+                             ) as whitespace_branch:
+      branch = git_utils.GetCurrentBranch()
+      with open(os.path.join('build', 'whitespace_file.txt'), 'a') as f:
+        f.write('\nCONTROL\n')
 
+      control_url = whitespace_branch.commit_and_upload()
+      if config.cl_bot_list:
+        submit_tries(config.cl_bot_list, dry_run=config.skip_cl_upload)
+      whitespace_cl = control_url
+      if config.save_branches:
+        whitespace_cl += '\n    branch: %s' % branch
 
-def revision_and_hash_from_partial(config, partial_hash):
-    """Returns the SVN revision number and full git hash.
+    branch = 'roll_%s_%s' % (revision, master_hash[:8])
+    message = (
+        'roll skia DEPS to %s\n\n'
+        'Chromium base revision: %s\n'
+        'Old Skia revision: %s\n'
+        'New Skia revision: %s\n'
+        'Control CL: %s\n\n'
+        'This CL was created by Skia\'s roll_deps.py script.\n\n'
+        'Bypassing commit queue trybots:\n'
+        'NOTRY=true\n'
+        % (revision, master_hash[:8],
+           old_revision[:8], revision[:8], control_url))
+    with git_utils.GitBranch(branch, message,
+                             delete_when_finished=not config.save_branches,
+                             upload=not config.skip_cl_upload
+                             ) as roll_branch:
+      change_skia_deps(revision, 'DEPS')
+      deps_url = roll_branch.commit_and_upload()
+      if config.cl_bot_list:
+        submit_tries(config.cl_bot_list, dry_run=config.skip_cl_upload)
+      deps_cl = deps_url
+      if config.save_branches:
+        deps_cl += '\n    branch: %s' % branch
 
-    Args:
-        config: (roll_deps.DepsRollConfig) object containing options.
-        partial_hash: (string) Partial git commit hash.
-
-    Returns:
-        A tuple (revision, hash)
-            revision: (int) SVN revision number.
-            git_hash: (string) full Git commit hash.
-
-    Raises:
-        roll_deps.DepsRollError: if the revision can't be found.
-        OSError: failed to execute git or git-cl.
-        subprocess.CalledProcessError: git returned unexpected status.
-    """
-    with SkiaGitCheckout(config, config.search_depth):
-        git_hash = config.vsp.strip_output(
-            ['git', 'log', '-n', '1', '--format=format:%H', partial_hash])
-        if not git_hash:
-            raise DepsRollError('Partial Git hash can not be found.')
-        revision = get_svn_revision(config, git_hash)
-    return revision, git_hash
-
-
-def change_skia_deps(revision, git_hash, depspath):
-    """Update the DEPS file.
-
-    Modify the skia_revision and skia_hash entries in the given DEPS file.
-
-    Args:
-        revision: (int) Skia SVN revision.
-        git_hash: (string) Skia Git hash.
-        depspath: (string) path to DEPS file.
-    """
-    temp_file = tempfile.NamedTemporaryFile(delete=False,
-                                            prefix='skia_DEPS_ROLL_tmp_')
-    try:
-        deps_regex_rev = re.compile('"skia_revision": "[0-9]*",')
-        deps_regex_hash = re.compile('"skia_hash": "[0-9a-f]*",')
-
-        deps_regex_rev_repl = '"skia_revision": "%d",' % revision
-        deps_regex_hash_repl = '"skia_hash": "%s",' % git_hash
-
-        with open(depspath, 'r') as input_stream:
-            for line in input_stream:
-                line = deps_regex_rev.sub(deps_regex_rev_repl, line)
-                line = deps_regex_hash.sub(deps_regex_hash_repl, line)
-                temp_file.write(line)
-    finally:
-        temp_file.close()
-    shutil.move(temp_file.name, depspath)
-
-
-def git_cl_uploader(config, message, file_list):
-    """Create a commit in the current git branch; upload via git-cl.
-
-    Assumes that you are already on the branch you want to be on.
-
-    Args:
-        config: (roll_deps.DepsRollConfig) object containing options.
-        message: (string) the commit message, can be multiline.
-        file_list: (list of strings) list of filenames to pass to `git add`.
-
-    Returns:
-        The output of `git cl issue`, if not config.skip_cl_upload, else ''.
-    """
-
-    git, vsp = config.git, config.vsp
-    svn_info = str(get_svn_revision(config, 'HEAD'))
-
-    for filename in file_list:
-        assert os.path.exists(filename)
-        vsp.check_call([git, 'add', filename])
-
-    vsp.check_call([git, 'commit', '-q', '-m', message])
-
-    git_cl = [git, 'cl', 'upload', '-f',
-              '--bypass-hooks', '--bypass-watchlists']
-    if config.cc_list:
-        git_cl.append('--cc=%s' % config.cc_list)
-    if config.reviewers_list:
-        git_cl.append('--reviewers=%s' % config.reviewers_list)
-
-    git_try = [
-        git, 'cl', 'try', '-m', 'tryserver.chromium', '--revision', svn_info]
-    git_try.extend([arg for bot in config.cl_bot_list for arg in ('-b', bot)])
-
-    branch_name = git_utils.git_branch_name(vsp.verbose)
-
-    if config.skip_cl_upload:
-        space = '   '
-        print 'You should call:'
-        print '%scd %s' % (space, os.getcwd())
-        misc_utils.print_subprocess_args(space, [git, 'checkout', branch_name])
-        misc_utils.print_subprocess_args(space, git_cl)
-        if config.cl_bot_list:
-            misc_utils.print_subprocess_args(space, git_try)
-        print
-        return ''
-    else:
-        vsp.check_call(git_cl)
-        issue = vsp.strip_output([git, 'cl', 'issue'])
-        if config.cl_bot_list:
-            vsp.check_call(git_try)
-        return issue
-
-
-def roll_deps(config, revision, git_hash):
-    """Upload changed DEPS and a whitespace change.
-
-    Given the correct git_hash, create two Reitveld issues.
-
-    Args:
-        config: (roll_deps.DepsRollConfig) object containing options.
-        revision: (int) Skia SVN revision.
-        git_hash: (string) Skia Git hash.
-
-    Returns:
-        a tuple containing textual description of the two issues.
-
-    Raises:
-        OSError: failed to execute git or git-cl.
-        subprocess.CalledProcessError: git returned unexpected status.
-    """
-
-    git = config.git
-    with misc_utils.ChangeDir(config.chromium_path, config.verbose):
-        config.vsp.check_call([git, 'fetch', '-q', 'origin'])
-
-        old_revision = misc_utils.ReSearch.search_within_output(
-            config.verbose, '"skia_revision": "(?P<return>[0-9]+)",', None,
-            [git, 'show', 'origin/master:DEPS'])
-        assert old_revision
-        if revision == int(old_revision):
-            print 'DEPS is up to date!'
-            return (None, None)
-
-        master_hash = config.vsp.strip_output(
-            [git, 'show-ref', 'origin/master', '--hash'])
-        master_revision = get_svn_revision(config, 'origin/master')
-
-        # master_hash[8] gives each whitespace CL a unique name.
-        if config.save_branches:
-            branch = 'control_%s' % master_hash[:8]
-        else:
-            branch = None
-        message = ('whitespace change %s\n\n'
-                   'Chromium base revision: %d / %s\n\n'
-                   'This CL was created by Skia\'s roll_deps.py script.\n'
-                  ) % (master_hash[:8], master_revision, master_hash[:8])
-        with git_utils.ChangeGitBranch(branch, 'origin/master',
-                                       config.verbose):
-            branch = git_utils.git_branch_name(config.vsp.verbose)
-
-            with open('build/whitespace_file.txt', 'a') as output_stream:
-                output_stream.write('\nCONTROL\n')
-
-            whitespace_cl = git_cl_uploader(
-                config, message, ['build/whitespace_file.txt'])
-
-            control_url = misc_utils.ReSearch.search_within_string(
-                whitespace_cl, '(?P<return>https?://[^) ]+)', '?')
-            if config.save_branches:
-                whitespace_cl = '%s\n    branch: %s' % (whitespace_cl, branch)
-
-        if config.save_branches:
-            branch = 'roll_%d_%s' % (revision, master_hash[:8])
-        else:
-            branch = None
-        message = (
-            'roll skia DEPS to %d\n\n'
-            'Chromium base revision: %d / %s\n'
-            'Old Skia revision: %s\n'
-            'New Skia revision: %d\n'
-            'Control CL: %s\n\n'
-            'This CL was created by Skia\'s roll_deps.py script.\n\n'
-            'Bypassing commit queue trybots:\n'
-            'NOTRY=true\n'
-            % (revision, master_revision, master_hash[:8],
-               old_revision, revision, control_url))
-        with git_utils.ChangeGitBranch(branch, 'origin/master',
-                                       config.verbose):
-            branch = git_utils.git_branch_name(config.vsp.verbose)
-
-            change_skia_deps(revision, git_hash, 'DEPS')
-            deps_cl = git_cl_uploader(config, message, ['DEPS'])
-            if config.save_branches:
-                deps_cl = '%s\n    branch: %s' % (deps_cl, branch)
-
-        return deps_cl, whitespace_cl
-
-
-def find_hash_and_roll_deps(config, revision=None, partial_hash=None):
-    """Call find_hash_from_revision() and roll_deps().
-
-    The calls to git will be verbose on standard output.  After a
-    successful upload of both issues, print links to the new
-    codereview issues.
-
-    Args:
-        config: (roll_deps.DepsRollConfig) object containing options.
-        revision: (int or None) the Skia SVN revision number or None
-            to use the tip of the tree.
-        partial_hash: (string or None) a partial pure-git Skia commit
-            hash.  Don't pass both partial_hash and revision.
-
-    Raises:
-        roll_deps.DepsRollError: if the revision can't be found.
-        OSError: failed to execute git or git-cl.
-        subprocess.CalledProcessError: git returned unexpected status.
-    """
-
-    if revision and partial_hash:
-        raise DepsRollError('Pass revision or partial_hash, not both.')
-
-    if partial_hash:
-        revision, git_hash = revision_and_hash_from_partial(
-            config, partial_hash)
-    elif revision:
-        revision, git_hash = revision_and_hash_from_revision(config, revision)
-    else:
-        revision, git_hash = revision_and_hash(config)
-
-    print 'revision=%r\nhash=%r\n' % (revision, git_hash)
-
-    deps_issue, whitespace_issue = roll_deps(config, revision, git_hash)
-
-    if deps_issue and whitespace_issue:
-        print 'DEPS roll:\n    %s\n' % deps_issue
-        print 'Whitespace change:\n    %s\n' % whitespace_issue
-    else:
-        print >> sys.stderr, 'No issues created.'
+    return deps_cl, whitespace_cl
 
 
 def main(args):
-    """main function; see module-level docstring and GetOptionParser help.
+  """main function; see module-level docstring and GetOptionParser help.
 
-    Args:
-        args: sys.argv[1:]-type argument list.
-    """
-    option_parser = DepsRollConfig.GetOptionParser()
-    options = option_parser.parse_args(args)[0]
+  Args:
+      args: sys.argv[1:]-type argument list.
+  """
+  option_parser = DepsRollConfig.GetOptionParser()
+  options = option_parser.parse_args(args)[0]
 
-    if not options.chromium_path:
-        option_parser.error('Must specify chromium_path.')
-    if not os.path.isdir(options.chromium_path):
-        option_parser.error('chromium_path must be a directory.')
+  if not options.revision:
+    option_parser.error('Must specify a revision.')
+  if not options.chromium_path:
+    option_parser.error('Must specify chromium_path.')
+  if not os.path.isdir(options.chromium_path):
+    option_parser.error('chromium_path must be a directory.')
 
-    if not git_utils.git_executable():
-        option_parser.error('Invalid git executable.')
+  config = DepsRollConfig(options)
+  shell_utils.VERBOSE = options.verbose
+  deps_issue, whitespace_issue = roll_deps(config, options.revision)
 
-    config = DepsRollConfig(options)
-    find_hash_and_roll_deps(config, options.revision, options.git_hash)
+  if deps_issue and whitespace_issue:
+    print 'DEPS roll:\n    %s\n' % deps_issue
+    print 'Whitespace change:\n    %s\n' % whitespace_issue
+  else:
+    print >> sys.stderr, 'No issues created.'
 
 
 if __name__ == '__main__':
-    main(sys.argv[1:])
-
+  main(sys.argv[1:])
diff --git a/tools/sk_tool_utils.cpp b/tools/sk_tool_utils.cpp
index 3eb5555..0200123 100644
--- a/tools/sk_tool_utils.cpp
+++ b/tools/sk_tool_utils.cpp
@@ -1,4 +1,19 @@
+/*
+ * 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 "sk_tool_utils.h"
+#include "sk_tool_utils_flags.h"
+
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkTestScalerContext.h"
+
+DEFINE_bool(portableFonts, false, "Use portable fonts");
+DEFINE_bool(resourceFonts, false, "Use resource fonts");
 
 namespace sk_tool_utils {
 
@@ -17,16 +32,31 @@
     }
 }
 
+SkTypeface* create_portable_typeface(const char* name, SkTypeface::Style style) {
+    SkTypeface* face;
+    if (FLAGS_portableFonts) {
+        face = create_font(name, style);
+    } else if (FLAGS_resourceFonts) {
+        face = resource_font(name, style);
+    } else {
+        face = SkTypeface::CreateFromName(name, style);
+    }
+    return face;
+}
+
+void set_portable_typeface(SkPaint* paint, const char* name, SkTypeface::Style style) {
+    SkTypeface* face = create_portable_typeface(name, style);
+    SkSafeUnref(paint->setTypeface(face));
+}
+
 void write_pixels(SkCanvas* canvas, const SkBitmap& bitmap, int x, int y,
                   SkColorType colorType, SkAlphaType alphaType) {
     SkBitmap tmp(bitmap);
     tmp.lockPixels();
 
-    SkImageInfo info = tmp.info();
-    info.fColorType = colorType;
-    info.fAlphaType = alphaType;
+    const SkImageInfo info = SkImageInfo::Make(tmp.width(), tmp.height(), colorType, alphaType);
 
     canvas->writePixels(info, tmp.getPixels(), tmp.rowBytes(), x, y);
 }
 
-}
+}  // namespace sk_tool_utils
diff --git a/tools/sk_tool_utils.h b/tools/sk_tool_utils.h
index 48fd716..e9bda5f 100644
--- a/tools/sk_tool_utils.h
+++ b/tools/sk_tool_utils.h
@@ -8,18 +8,36 @@
 #ifndef sk_tool_utils_DEFINED
 #define sk_tool_utils_DEFINED
 
-#include "SkCanvas.h"
-#include "SkBitmap.h"
+#include "SkImageInfo.h"
+#include "SkTypeface.h"
+
+class SkBitmap;
+class SkCanvas;
+class SkPaint;
+class SkTestFont;
 
 namespace sk_tool_utils {
 
     const char* colortype_name(SkColorType);
 
     /**
+     * Sets the paint to use a platform-independent text renderer.
+     */
+    void set_portable_typeface(SkPaint* paint, const char* name = NULL,
+                               SkTypeface::Style style = SkTypeface::kNormal);
+    SkTypeface* create_portable_typeface(const char* name, SkTypeface::Style style);
+    void report_used_chars();
+
+    /**
      *  Call canvas->writePixels() by using the pixels from bitmap, but with an info that claims
      *  the pixels are colorType + alphaType
      */
     void write_pixels(SkCanvas*, const SkBitmap&, int x, int y, SkColorType, SkAlphaType);
-}
 
-#endif
+    // private to sk_tool_utils
+    SkTypeface* create_font(const char* name, SkTypeface::Style );
+    SkTypeface* resource_font(const char* name, SkTypeface::Style );
+
+}  // namespace sk_tool_utils
+
+#endif  // sk_tool_utils_DEFINED
diff --git a/tools/sk_tool_utils_flags.h b/tools/sk_tool_utils_flags.h
new file mode 100644
index 0000000..ee15fbd
--- /dev/null
+++ b/tools/sk_tool_utils_flags.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef sk_tool_utils_flags_DEFINED
+#define sk_tool_utils_flags_DEFINED
+
+#include "SkCommandLineFlags.h"
+
+DECLARE_bool(portableFonts);
+DECLARE_bool(resourceFonts);
+
+#endif  // sk_tool_utils_flags_DEFINED
diff --git a/tools/sk_tool_utils_font.cpp b/tools/sk_tool_utils_font.cpp
new file mode 100644
index 0000000..3236f07
--- /dev/null
+++ b/tools/sk_tool_utils_font.cpp
@@ -0,0 +1,178 @@
+/*
+ * 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 "Resources.h"
+#include "SkOSFile.h"
+#include "SkTestScalerContext.h"
+#include "SkThread.h"
+#include "SkUtils.h"
+#include "sk_tool_utils.h"
+
+namespace sk_tool_utils {
+
+#include "test_font_data.cpp"
+
+static void release_portable_typefaces() {
+    // We'll clean this up in our own tests, but disable for clients.
+    // Chrome seems to have funky multi-process things going on in unit tests that
+    // makes this unsafe to delete when the main process atexit()s.
+    // SkLazyPtr does the same sort of thing.
+#if SK_DEVELOPER
+    for (int index = 0; index < gTestFontsCount; ++index) {
+        SkTestFontData& fontData = gTestFonts[index];
+        SkSafeUnref(fontData.fFontCache);
+    }
+#endif
+}
+
+SK_DECLARE_STATIC_MUTEX(gTestFontMutex);
+
+SkTypeface* create_font(const char* name, SkTypeface::Style style) {
+    SkTestFontData* fontData = NULL;
+    const SubFont* sub;
+    if (name) {
+        for (int index = 0; index < gSubFontsCount; ++index) {
+            sub = &gSubFonts[index];
+            if (!strcmp(name, sub->fName) && sub->fStyle == style) {
+                fontData = &sub->fFont;
+                break;
+            }
+        }
+        if (!fontData) {
+            SkDebugf("missing %s %d\n", name, style);
+            return SkTypeface::CreateFromName(name, style);
+        }
+    } else {
+        sub = &gSubFonts[gDefaultFontIndex];
+        fontData = &sub->fFont;
+    }
+    SkTestFont* font;
+    {
+        SkAutoMutexAcquire ac(gTestFontMutex);
+        if (fontData->fFontCache) {
+            font = SkSafeRef(fontData->fFontCache);
+        } else {
+            font = SkNEW_ARGS(SkTestFont, (*fontData));
+            SkDEBUGCODE(font->fDebugName = sub->fName);
+            SkDEBUGCODE(font->fDebugStyle = sub->fStyle);
+            fontData->fFontCache = SkSafeRef(font);
+            atexit(release_portable_typefaces);
+        }
+    }
+    return SkNEW_ARGS(SkTestTypeface, (font, style));
+}
+
+
+SkTypeface* resource_font(const char* name, SkTypeface::Style style) {
+    const char* file = NULL;
+    if (name) {
+        for (int index = 0; index < gSubFontsCount; ++index) {
+            const SubFont& sub = gSubFonts[index];
+            if (!strcmp(name, sub.fName) && sub.fStyle == style) {
+                file = sub.fFile;
+                break;
+            }
+        }
+        if (!file) {
+            return SkTypeface::CreateFromName(name, style);
+        }
+    } else {
+        file = gSubFonts[gDefaultFontIndex].fFile;
+    }
+    SkString filepath(GetResourcePath(file));
+    if (sk_exists(filepath.c_str())) {
+        return SkTypeface::CreateFromFile(filepath.c_str());
+    }
+    return SkTypeface::CreateFromName(name, style);
+}
+
+#ifdef SK_DEBUG
+#include <stdio.h>
+
+char const * const gStyleName[] = {
+    "",
+    "_Bold",
+    "_Italic",
+    "_BoldItalic",
+};
+
+static SkString strip_spaces(const char* str) {
+    SkString result;
+    int count = (int) strlen(str);
+    for (int index = 0; index < count; ++index) {
+        char c = str[index];
+        if (c != ' ' && c != '-') {
+            result += c;
+        }
+    }
+    return result;
+}
+
+const char gHeader[] =
+"/*\n"
+" * Copyright 2014 Google Inc.\n"
+" *\n"
+" * Use of this source code is governed by a BSD-style license that can be\n"
+" * found in the LICENSE file.\n"
+" */\n"
+"\n"
+"// Auto-generated by ";
+
+static FILE* font_header() {
+    SkString pathStr(GetResourcePath());
+    pathStr = SkOSPath::Join(pathStr.c_str(), "..");
+    pathStr = SkOSPath::Join(pathStr.c_str(), "tools");
+    pathStr = SkOSPath::Join(pathStr.c_str(), "test_font_data_chars.cpp");
+    FILE* out = fopen(pathStr.c_str(), "w");
+    fprintf(out, "%s%s\n\n", gHeader, SkOSPath::Basename(__FILE__).c_str());
+    return out;
+}
+
+void report_used_chars() {
+    FILE* out = font_header();
+    for (int index = 0; index < gTestFontsCount; ++index) {
+        SkTestFontData& fontData = gTestFonts[index];
+        SkTestFont* font = fontData.fFontCache;
+        if (!font) {
+            continue;
+        }
+        SkString name(strip_spaces(font->debugFontName()));
+        fprintf(out, "const char g%s%s[] =\n", name.c_str(), gStyleName[font->fDebugStyle]);
+        SkString used("    \"");
+        for (int c = ' '; c <= '~'; ++c) {
+            int bitOffset = c - ' ';
+            if (font->fDebugBits[bitOffset >> 3] & (1 << (bitOffset & 7))) {
+                if (c == '"' || c == '\\') {
+                    used += '\\';
+                }
+                used += c;
+            }
+        }
+        if (used.size() > 1) {
+            fprintf(out, "%s\"", used.c_str());
+        }
+        int oIndex = 0;
+        while (font->fDebugOverage[oIndex]) {
+            uint16_t uni = font->fDebugOverage[oIndex];
+            size_t byteCount = SkUTF16_ToUTF8(&uni, 1, NULL);
+            SkAutoSTMalloc<10, char> utf8(byteCount);
+            SkUTF16_ToUTF8(&uni, 1, utf8);
+            for (unsigned byteIndex = 0; byteIndex < byteCount; ++byteIndex) {
+                char unibyte = utf8[byteIndex];
+                fprintf(out, " \"\\x%02X\"", (unsigned char) unibyte);
+            }
+            if (++oIndex >= (int) sizeof(font->fDebugOverage)) {
+                break;
+            }
+        }
+       fprintf(out, ";\n");
+    }
+    fclose(out);
+}
+#endif
+
+}
diff --git a/tools/skdiff_image.cpp b/tools/skdiff_image.cpp
index 172f62b..89f7381 100644
--- a/tools/skdiff_image.cpp
+++ b/tools/skdiff_image.cpp
@@ -37,11 +37,11 @@
     drp->fComparison.fStatus = DiffResource::kSpecified_Status;
 
     SkAutoDataUnref baseFileBits(read_file(drp->fBase.fFullPath.c_str()));
-    if (NULL != baseFileBits) {
+    if (baseFileBits) {
         drp->fBase.fStatus = DiffResource::kRead_Status;
     }
     SkAutoDataUnref comparisonFileBits(read_file(drp->fComparison.fFullPath.c_str()));
-    if (NULL != comparisonFileBits) {
+    if (comparisonFileBits) {
         drp->fComparison.fStatus = DiffResource::kRead_Status;
     }
     if (NULL == baseFileBits || NULL == comparisonFileBits) {
diff --git a/tools/skdiff_main.cpp b/tools/skdiff_main.cpp
index ba32216..df07844 100644
--- a/tools/skdiff_main.cpp
+++ b/tools/skdiff_main.cpp
@@ -422,11 +422,11 @@
             drp->fComparison.fStatus = DiffResource::kExists_Status;
 
             SkAutoDataUnref baseFileBits(read_file(drp->fBase.fFullPath.c_str()));
-            if (NULL != baseFileBits) {
+            if (baseFileBits) {
                 drp->fBase.fStatus = DiffResource::kRead_Status;
             }
             SkAutoDataUnref comparisonFileBits(read_file(drp->fComparison.fFullPath.c_str()));
-            if (NULL != comparisonFileBits) {
+            if (comparisonFileBits) {
                 drp->fComparison.fStatus = DiffResource::kRead_Status;
             }
             if (NULL == baseFileBits || NULL == comparisonFileBits) {
diff --git a/tools/skdiff_utils.cpp b/tools/skdiff_utils.cpp
index 9157ac6..a00ea7b 100644
--- a/tools/skdiff_utils.cpp
+++ b/tools/skdiff_utils.cpp
@@ -25,27 +25,11 @@
 }
 
 SkData* read_file(const char* file_path) {
-    SkFILEStream fileStream(file_path);
-    if (!fileStream.isValid()) {
+    SkData* data = SkData::NewFromFileName(file_path);
+    if (!data) {
         SkDebugf("WARNING: could not open file <%s> for reading\n", file_path);
-        return NULL;
     }
-    size_t bytesInFile = fileStream.getLength();
-    size_t bytesLeftToRead = bytesInFile;
-
-    void* bufferStart = sk_malloc_throw(bytesInFile);
-    char* bufferPointer = (char*)bufferStart;
-    while (bytesLeftToRead > 0) {
-        size_t bytesReadThisTime = fileStream.read(bufferPointer, bytesLeftToRead);
-        if (0 == bytesReadThisTime) {
-            SkDebugf("WARNING: error reading from <%s>\n", file_path);
-            sk_free(bufferStart);
-            return NULL;
-        }
-        bytesLeftToRead -= bytesReadThisTime;
-        bufferPointer += bytesReadThisTime;
-    }
-    return SkData::NewFromMalloc(bufferStart, bytesInFile);
+    return data;
 }
 
 bool get_bitmap(SkData* fileBits, DiffResource& resource, SkImageDecoder::Mode mode) {
@@ -103,7 +87,7 @@
     const char *first_char = input_cstr;
     const char *match_char;
     size_t oldSubstringLen = strlen(oldSubstring);
-    while (NULL != (match_char = strstr(first_char, oldSubstring))) {
+    while ((match_char = strstr(first_char, oldSubstring))) {
         output.append(first_char, (match_char - first_char));
         output.append(newSubstring);
         first_char = match_char + oldSubstringLen;
diff --git a/tools/skimage_main.cpp b/tools/skimage_main.cpp
index a488aa7..a2d353c 100644
--- a/tools/skimage_main.cpp
+++ b/tools/skimage_main.cpp
@@ -80,8 +80,8 @@
 
 static void make_outname(SkString* dst, const char outDir[], const char src[],
                          const char suffix[]) {
-    SkString basename = SkOSPath::SkBasename(src);
-    dst->set(SkOSPath::SkPathJoin(outDir, basename.c_str()));
+    SkString basename = SkOSPath::Basename(src);
+    dst->set(SkOSPath::Join(outDir, basename.c_str()));
     dst->append(suffix);
 }
 
@@ -138,14 +138,14 @@
     if (FLAGS_writeChecksumBasedFilenames) {
         // First create the directory for the hashtype.
         const SkString hashType = bitmapAndDigest.fDigest.getHashType();
-        const SkString hashDir = SkOSPath::SkPathJoin(outDir, hashType.c_str());
+        const SkString hashDir = SkOSPath::Join(outDir, hashType.c_str());
         if (!sk_mkdir(hashDir.c_str())) {
             return false;
         }
 
         // Now create the name of the folder specific to this image.
-        SkString basename = SkOSPath::SkBasename(src);
-        const SkString imageDir = SkOSPath::SkPathJoin(hashDir.c_str(), basename.c_str());
+        SkString basename = SkOSPath::Basename(src);
+        const SkString imageDir = SkOSPath::Join(hashDir.c_str(), basename.c_str());
         if (!sk_mkdir(imageDir.c_str())) {
             return false;
         }
@@ -154,7 +154,7 @@
         SkString checksumBasedName = bitmapAndDigest.fDigest.getDigestValue();
         checksumBasedName.append(".png");
 
-        filename = SkOSPath::SkPathJoin(imageDir.c_str(), checksumBasedName.c_str());
+        filename = SkOSPath::Join(imageDir.c_str(), checksumBasedName.c_str());
     } else {
         make_outname(&filename, outDir, src, ".png");
     }
@@ -358,7 +358,7 @@
         subsetPath.set(writePath);
     } else {
         // Create a subdirectory to hold the results of decodeSubset.
-        subsetPath = SkOSPath::SkPathJoin(writePath, "subsets");
+        subsetPath = SkOSPath::Join(writePath, "subsets");
         if (!sk_mkdir(subsetPath.c_str())) {
             gFailedSubsetDecodes.push_back().printf("Successfully decoded subset %s, but "
                                                     "failed to create a directory to write to.",
@@ -385,7 +385,7 @@
             return false;
         }
 
-        SkString dirExtracted = SkOSPath::SkPathJoin(writePath, "extracted");
+        SkString dirExtracted = SkOSPath::Join(writePath, "extracted");
         if (!sk_mkdir(dirExtracted.c_str())) {
             gFailedSubsetDecodes.push_back().printf("Successfully decoded subset%s, but failed "
                                                     "to create a directory for extractSubset "
@@ -502,7 +502,7 @@
     stream.rewind();
 
     // Create a string representing just the filename itself, for use in json expectations.
-    SkString basename = SkOSPath::SkBasename(srcPath);
+    SkString basename = SkOSPath::Basename(srcPath);
     // Replace '_' with '-', so that the names can fit gm_json.py's IMAGE_FILENAME_PATTERN
     replace_char(&basename, '_', '-');
     // Replace '.' with '-', so the output filename can still retain the original file extension,
@@ -511,7 +511,7 @@
     const char* filename = basename.c_str();
 
     if (!codec->decode(&stream, &bitmap, gPrefColorType, SkImageDecoder::kDecodePixels_Mode)) {
-        if (NULL != gJsonExpectations.get()) {
+        if (gJsonExpectations.get()) {
             const SkString name_config = create_json_key(filename);
             skiagm::Expectations jsExpectations = gJsonExpectations->get(name_config.c_str());
             if (jsExpectations.ignoreFailure()) {
@@ -587,7 +587,8 @@
         // Build the tile index for decoding subsets. If the image is 1x1, skip subset
         // decoding since there are no smaller subsets.
         if (codec->buildTileIndex(&stream, &width, &height) && width > 1 && height > 1) {
-            SkASSERT(bitmap.width() == width && bitmap.height() == height);
+            SkASSERT((bitmap.width() == width && bitmap.height() == height)
+                     || FLAGS_sampleSize != 1);
             // Call decodeSubset multiple times:
             SkRandom rand(0);
             for (int i = 0; i < 5; i++) {
@@ -636,7 +637,7 @@
             }
             if (SkImageDecoder::kUnknown_Format == format) {
                 const char* dot = strrchr(srcPath, '.');
-                if (NULL != dot) {
+                if (dot) {
                     format = guess_format_from_suffix(dot);
                 }
                 if (SkImageDecoder::kUnknown_Format == format) {
@@ -795,7 +796,7 @@
                 if (!is_image_file(filename.c_str())) {
                     continue;
                 }
-                SkString fullname = SkOSPath::SkPathJoin(dir, filename.c_str());
+                SkString fullname = SkOSPath::Join(dir, filename.c_str());
                 decodeFileAndWrite(fullname.c_str(), outDirPtr);
             }
         } else if (sk_exists(readPath) && is_image_file(readPath)) {
diff --git a/tools/skpdiff/SkDiffContext.cpp b/tools/skpdiff/SkDiffContext.cpp
index 6f0b09f..32688f5 100644
--- a/tools/skpdiff/SkDiffContext.cpp
+++ b/tools/skpdiff/SkDiffContext.cpp
@@ -9,34 +9,54 @@
 #include "SkImageDecoder.h"
 #include "SkOSFile.h"
 #include "SkRunnable.h"
+#include "SkSize.h"
 #include "SkStream.h"
 #include "SkTDict.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
+
+// from the tools directory for replace_char(...)
+#include "picture_utils.h"
 
 #include "SkDiffContext.h"
+#include "SkImageDiffer.h"
 #include "skpdiff_util.h"
 
 SkDiffContext::SkDiffContext() {
     fDiffers = NULL;
     fDifferCount = 0;
-    fThreadCount = SkThreadPool::kThreadPerCore;
 }
 
 SkDiffContext::~SkDiffContext() {
-    if (NULL != fDiffers) {
+    if (fDiffers) {
         SkDELETE_ARRAY(fDiffers);
     }
 }
 
-void SkDiffContext::setDifferenceDir(const SkString& path) {
+void SkDiffContext::setAlphaMaskDir(const SkString& path) {
     if (!path.isEmpty() && sk_mkdir(path.c_str())) {
-        fDifferenceDir = path;
+        fAlphaMaskDir = path;
     }
 }
 
+void SkDiffContext::setRgbDiffDir(const SkString& path) {
+    if (!path.isEmpty() && sk_mkdir(path.c_str())) {
+        fRgbDiffDir = path;
+    }
+}
+
+void SkDiffContext::setWhiteDiffDir(const SkString& path) {
+    if (!path.isEmpty() && sk_mkdir(path.c_str())) {
+        fWhiteDiffDir = path;
+    }
+}
+
+void SkDiffContext::setLongNames(const bool useLongNames) {
+    longNames = useLongNames;
+}
+
 void SkDiffContext::setDiffers(const SkTDArray<SkImageDiffer*>& differs) {
     // Delete whatever the last array of differs was
-    if (NULL != fDiffers) {
+    if (fDiffers) {
         SkDELETE_ARRAY(fDiffers);
         fDiffers = NULL;
         fDifferCount = 0;
@@ -65,6 +85,16 @@
     }
 }
 
+static SkString get_combined_name(const SkString& a, const SkString& b) {
+    // Note (stephana): We must keep this function in sync with
+    // getImageDiffRelativeUrl() in static/loader.js (under rebaseline_server).
+    SkString result = a;
+    result.append("-vs-");
+    result.append(b);
+    sk_tools::replace_char(&result, '.', '_');
+    return result;
+}
+
 void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) {
     // Load the images at the paths
     SkBitmap baselineBitmap;
@@ -84,19 +114,25 @@
     fRecordMutex.release();
 
     // compute the common name
-    SkString baseName = SkOSPath::SkBasename(baselinePath);
-    SkString testName = SkOSPath::SkBasename(testPath);
-    newRecord->fCommonName = get_common_prefix(baseName, testName);
+    SkString baseName = SkOSPath::Basename(baselinePath);
+    SkString testName = SkOSPath::Basename(testPath);
+
+    if (longNames) {
+        newRecord->fCommonName = get_combined_name(baseName, testName);
+    } else {
+        newRecord->fCommonName = get_common_prefix(baseName, testName);
+    }
+    newRecord->fCommonName.append(".png");
 
     newRecord->fBaselinePath = baselinePath;
     newRecord->fTestPath = testPath;
+    newRecord->fSize = SkISize::Make(baselineBitmap.width(), baselineBitmap.height());
 
-    bool alphaMaskPending = false;
-
-    // only enable alpha masks if a difference dir has been provided
-    if (!fDifferenceDir.isEmpty()) {
-        alphaMaskPending = true;
-    }
+    // only generate diff images if we have a place to store them
+    SkImageDiffer::BitmapsToCreate bitmapsToCreate;
+    bitmapsToCreate.alphaMask = !fAlphaMaskDir.isEmpty();
+    bitmapsToCreate.rgbDiff = !fRgbDiffDir.isEmpty();
+    bitmapsToCreate.whiteDiff = !fWhiteDiffDir.isEmpty();
 
     // Perform each diff
     for (int differIndex = 0; differIndex < fDifferCount; differIndex++) {
@@ -106,30 +142,69 @@
         DiffData& diffData = newRecord->fDiffs.push_back();
         diffData.fDiffName = differ->getName();
 
-        if (!differ->diff(&baselineBitmap, &testBitmap, alphaMaskPending, &diffData.fResult)) {
-            // if the diff failed record -1 as the result
+        if (!differ->diff(&baselineBitmap, &testBitmap, bitmapsToCreate, &diffData.fResult)) {
+            // if the diff failed, record -1 as the result
+            // TODO(djsollen): Record more detailed information about exactly what failed.
+            // (Image dimension mismatch? etc.)  See http://skbug.com/2710 ('make skpdiff
+            // report more detail when it fails to compare two images')
             diffData.fResult.result = -1;
             continue;
         }
 
-        if (alphaMaskPending
+        if (bitmapsToCreate.alphaMask
                 && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
                 && !diffData.fResult.poiAlphaMask.empty()
                 && !newRecord->fCommonName.isEmpty()) {
 
-            newRecord->fDifferencePath = SkOSPath::SkPathJoin(fDifferenceDir.c_str(),
-                                                              newRecord->fCommonName.c_str());
+            newRecord->fAlphaMaskPath = SkOSPath::Join(fAlphaMaskDir.c_str(),
+                                                       newRecord->fCommonName.c_str());
 
             // compute the image diff and output it
             SkBitmap copy;
             diffData.fResult.poiAlphaMask.copyTo(&copy, kN32_SkColorType);
-            SkImageEncoder::EncodeFile(newRecord->fDifferencePath.c_str(), copy,
+            SkImageEncoder::EncodeFile(newRecord->fAlphaMaskPath.c_str(), copy,
                                        SkImageEncoder::kPNG_Type, 100);
 
             // cleanup the existing bitmap to free up resources;
             diffData.fResult.poiAlphaMask.reset();
 
-            alphaMaskPending = false;
+            bitmapsToCreate.alphaMask = false;
+        }
+
+        if (bitmapsToCreate.rgbDiff
+                && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
+                && !diffData.fResult.rgbDiffBitmap.empty()
+                && !newRecord->fCommonName.isEmpty()) {
+            // TODO(djsollen): Rather than taking the max r/g/b diffs that come back from
+            // a particular differ and storing them as toplevel fields within
+            // newRecord, we should extend outputRecords() to report optional
+            // fields for each differ (not just "result" and "pointsOfInterest").
+            // See http://skbug.com/2712 ('allow skpdiff to report different sets
+            // of result fields for different comparison algorithms')
+            newRecord->fMaxRedDiff = diffData.fResult.maxRedDiff;
+            newRecord->fMaxGreenDiff = diffData.fResult.maxGreenDiff;
+            newRecord->fMaxBlueDiff = diffData.fResult.maxBlueDiff;
+
+            newRecord->fRgbDiffPath = SkOSPath::Join(fRgbDiffDir.c_str(),
+                                                     newRecord->fCommonName.c_str());
+            SkImageEncoder::EncodeFile(newRecord->fRgbDiffPath.c_str(),
+                                       diffData.fResult.rgbDiffBitmap,
+                                       SkImageEncoder::kPNG_Type, 100);
+            diffData.fResult.rgbDiffBitmap.reset();
+            bitmapsToCreate.rgbDiff = false;
+        }
+
+        if (bitmapsToCreate.whiteDiff
+                && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
+                && !diffData.fResult.whiteDiffBitmap.empty()
+                && !newRecord->fCommonName.isEmpty()) {
+            newRecord->fWhiteDiffPath = SkOSPath::Join(fWhiteDiffDir.c_str(),
+                                                       newRecord->fCommonName.c_str());
+            SkImageEncoder::EncodeFile(newRecord->fWhiteDiffPath.c_str(),
+                                       diffData.fResult.whiteDiffBitmap,
+                                       SkImageEncoder::kPNG_Type, 100);
+            diffData.fResult.whiteDiffBitmap.reset();
+            bitmapsToCreate.whiteDiff = false;
         }
     }
 }
@@ -162,7 +237,7 @@
         return;
     }
 
-    SkThreadPool threadPool(fThreadCount);
+    SkTaskGroup tg;
     SkTArray<SkThreadedDiff> runnableDiffs;
     runnableDiffs.reset(baselineEntries.count());
 
@@ -170,20 +245,18 @@
         const char* baseFilename = baselineEntries[x].c_str();
 
         // Find the real location of each file to compare
-        SkString baselineFile = SkOSPath::SkPathJoin(baselinePath, baseFilename);
-        SkString testFile = SkOSPath::SkPathJoin(testPath, baseFilename);
+        SkString baselineFile = SkOSPath::Join(baselinePath, baseFilename);
+        SkString testFile = SkOSPath::Join(testPath, baseFilename);
 
         // Check that the test file exists and is a file
         if (sk_exists(testFile.c_str()) && !sk_isdir(testFile.c_str())) {
             // Queue up the comparison with the differ
             runnableDiffs[x].setup(this, baselineFile, testFile);
-            threadPool.add(&runnableDiffs[x]);
+            tg.add(&runnableDiffs[x]);
         } else {
             SkDebugf("Baseline file \"%s\" has no corresponding test file\n", baselineFile.c_str());
         }
     }
-
-    threadPool.wait();
 }
 
 
@@ -208,16 +281,15 @@
         return;
     }
 
-    SkThreadPool threadPool(fThreadCount);
+    SkTaskGroup tg;
     SkTArray<SkThreadedDiff> runnableDiffs;
     runnableDiffs.reset(baselineEntries.count());
 
     for (int x = 0; x < baselineEntries.count(); x++) {
         runnableDiffs[x].setup(this, baselineEntries[x], testEntries[x]);
-        threadPool.add(&runnableDiffs[x]);
+        tg.add(&runnableDiffs[x]);
     }
-
-    threadPool.wait();
+    tg.wait();
 }
 
 void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
@@ -229,11 +301,15 @@
     } else {
         stream.writeText("{\n");
     }
+
+    // TODO(djsollen): Would it be better to use the jsoncpp library to write out the JSON?
+    // This manual approach is probably more efficient, but it sure is ugly.
+    // See http://skbug.com/2713 ('make skpdiff use jsoncpp library to write out
+    // JSON output, instead of manual writeText() calls?')
     stream.writeText("    \"records\": [\n");
-    while (NULL != currentRecord) {
+    while (currentRecord) {
         stream.writeText("        {\n");
 
-            SkString differenceAbsPath = get_absolute_path(currentRecord->fDifferencePath);
             SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselinePath);
             SkString testAbsPath = get_absolute_path(currentRecord->fTestPath);
 
@@ -242,7 +318,15 @@
             stream.writeText("\",\n");
 
             stream.writeText("            \"differencePath\": \"");
-            stream.writeText(differenceAbsPath.c_str());
+            stream.writeText(get_absolute_path(currentRecord->fAlphaMaskPath).c_str());
+            stream.writeText("\",\n");
+
+            stream.writeText("            \"rgbDiffPath\": \"");
+            stream.writeText(get_absolute_path(currentRecord->fRgbDiffPath).c_str());
+            stream.writeText("\",\n");
+
+            stream.writeText("            \"whiteDiffPath\": \"");
+            stream.writeText(get_absolute_path(currentRecord->fWhiteDiffPath).c_str());
             stream.writeText("\",\n");
 
             stream.writeText("            \"baselinePath\": \"");
@@ -253,6 +337,23 @@
             stream.writeText(testAbsPath.c_str());
             stream.writeText("\",\n");
 
+            stream.writeText("            \"width\": ");
+            stream.writeDecAsText(currentRecord->fSize.width());
+            stream.writeText(",\n");
+            stream.writeText("            \"height\": ");
+            stream.writeDecAsText(currentRecord->fSize.height());
+            stream.writeText(",\n");
+
+            stream.writeText("            \"maxRedDiff\": ");
+            stream.writeDecAsText(currentRecord->fMaxRedDiff);
+            stream.writeText(",\n");
+            stream.writeText("            \"maxGreenDiff\": ");
+            stream.writeDecAsText(currentRecord->fMaxGreenDiff);
+            stream.writeText(",\n");
+            stream.writeText("            \"maxBlueDiff\": ");
+            stream.writeDecAsText(currentRecord->fMaxBlueDiff);
+            stream.writeText(",\n");
+
             stream.writeText("            \"diffs\": [\n");
             for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); diffIndex++) {
                 DiffData& data = currentRecord->fDiffs[diffIndex];
@@ -285,7 +386,7 @@
         currentRecord = iter.next();
 
         // JSON does not allow trailing commas
-        if (NULL != currentRecord) {
+        if (currentRecord) {
             stream.writeText(",");
         }
         stream.writeText("\n");
@@ -308,7 +409,7 @@
     DiffRecord* currentRecord = iter.get();
 
     // Write CSV header and create a dictionary of all columns.
-    while (NULL != currentRecord) {
+    while (currentRecord) {
         for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); diffIndex++) {
             DiffData& data = currentRecord->fDiffs[diffIndex];
             if (!columns.find(data.fDiffName)) {
@@ -327,7 +428,7 @@
 
     SkTLList<DiffRecord>::Iter iter2(fRecords, SkTLList<DiffRecord>::Iter::kHead_IterStart);
     currentRecord = iter2.get();
-    while (NULL != currentRecord) {
+    while (currentRecord) {
         for (int i = 0; i < cntColumns; i++) {
             values[i] = -1;
         }
diff --git a/tools/skpdiff/SkDiffContext.h b/tools/skpdiff/SkDiffContext.h
index c036c2e..8f4789f 100644
--- a/tools/skpdiff/SkDiffContext.h
+++ b/tools/skpdiff/SkDiffContext.h
@@ -28,10 +28,47 @@
     void setThreadCount(int threadCount) { fThreadCount = threadCount; }
 
     /**
-     * Creates the directory if it does not exist and uses it to store differences
-     * between images.
+     * Sets the directory within which to store alphaMasks (images that
+     * are transparent for each pixel that differs between baseline and test).
+     *
+     * If the directory does not exist yet, it will be created.
      */
-    void setDifferenceDir(const SkString& directory);
+    void setAlphaMaskDir(const SkString& directory);
+
+    /**
+     * Sets the directory within which to store rgbDiffs (images showing the
+     * per-channel difference between baseline and test at each pixel).
+     *
+     * If the directory does not exist yet, it will be created.
+     */
+    void setRgbDiffDir(const SkString& directory);
+
+    /**
+     * Sets the directory within which to store whiteDiffs (images showing white
+     * for each pixel that differs between baseline and test).
+     *
+     * If the directory does not exist yet, it will be created.
+     */
+    void setWhiteDiffDir(const SkString& directory);
+
+    /**
+     * Modify the pattern used to generate commonName (= the 
+     * basename of rgb/white diff files).
+     *
+     * - true: basename is a combination of the input file names.
+     * - false: basename is the common prefix of the input file names.
+     *
+     * For example, for:
+     *   baselinePath=/tmp/dir/image-before.png
+     *   testPath=/tmp/dir/image-after.png
+     * 
+     * If setLongNames(true), commonName would be:
+     *    image-before-png-vs-image-after-png.png
+     * 
+     * If setLongNames(false), commonName would be:
+     *   image-.png
+     */
+    void setLongNames(const bool useLongNames);
 
     /**
      * Sets the differs to be used in each diff. Already started diffs will not retroactively use
@@ -67,13 +104,22 @@
      *
      * The format of the JSON document is one top level array named "records".
      * Each record in the array is an object with the following values:
-     *    "commonName"     : string containing the common prefix of the baselinePath
-     *                       and testPath filenames
+     *    "commonName"     : string containing the output filename (basename) 
+     *                       depending on the value of 'longNames'. 
+     *                       (see 'setLongNames' for an explanation and example).
      *    "baselinePath"   : string containing the path to the baseline image
      *    "testPath"       : string containing the path to the test image
      *    "differencePath" : (optional) string containing the path to an alpha
      *                       mask of the pixel difference between the baseline
      *                       and test images
+     *                       TODO(epoger): consider renaming this "alphaMaskPath"
+     *                       to distinguish from other difference types?
+     *    "rgbDiffPath"    : (optional) string containing the path to a bitmap
+     *                       showing per-channel differences between the
+     *                       baseline and test images at each pixel
+     *    "whiteDiffPath"  : (optional) string containing the path to a bitmap
+     *                       showing every pixel that differs between the
+     *                       baseline and test images as white
      *
      * They also have an array named "diffs" with each element being one diff record for the two
      * images indicated in the above field.
@@ -117,10 +163,21 @@
     };
 
     struct DiffRecord {
+        // TODO(djsollen): Some of these fields are required, while others are optional
+        // (e.g., fRgbDiffPath is only filled in if SkDifferentPixelsMetric
+        // was run).  Figure out a way to note that.  See http://skbug.com/2712
+        // ('allow skpdiff to report different sets of result fields for
+        // different comparison algorithms')
         SkString           fCommonName;
-        SkString           fDifferencePath;
+        SkString           fAlphaMaskPath;
+        SkString           fRgbDiffPath;
+        SkString           fWhiteDiffPath;
         SkString           fBaselinePath;
         SkString               fTestPath;
+        SkISize                    fSize;
+        int                  fMaxRedDiff;
+        int                fMaxGreenDiff;
+        int                 fMaxBlueDiff;
         SkTArray<DiffData>        fDiffs;
     };
 
@@ -137,7 +194,10 @@
     int fDifferCount;
     int fThreadCount;
 
-    SkString fDifferenceDir;
+    SkString fAlphaMaskDir;
+    SkString fRgbDiffDir;
+    SkString fWhiteDiffDir;
+    bool longNames;
 };
 
 #endif
diff --git a/tools/skpdiff/SkDifferentPixelsMetric.h b/tools/skpdiff/SkDifferentPixelsMetric.h
index 06c56b1..9302d9e 100644
--- a/tools/skpdiff/SkDifferentPixelsMetric.h
+++ b/tools/skpdiff/SkDifferentPixelsMetric.h
@@ -28,7 +28,8 @@
 #endif
 public:
     virtual const char* getName() const SK_OVERRIDE;
-    virtual bool diff(SkBitmap* baseline, SkBitmap* test, bool computeMask,
+    virtual bool diff(SkBitmap* baseline, SkBitmap* test,
+                      const BitmapsToCreate& bitmapsToCreate,
                       Result* result) const SK_OVERRIDE;
 
 protected:
diff --git a/tools/skpdiff/SkDifferentPixelsMetric_cpu.cpp b/tools/skpdiff/SkDifferentPixelsMetric_cpu.cpp
index e528b78..7194e80 100644
--- a/tools/skpdiff/SkDifferentPixelsMetric_cpu.cpp
+++ b/tools/skpdiff/SkDifferentPixelsMetric_cpu.cpp
@@ -14,7 +14,8 @@
     return "different_pixels";
 }
 
-bool SkDifferentPixelsMetric::diff(SkBitmap* baseline, SkBitmap* test, bool computeMask,
+bool SkDifferentPixelsMetric::diff(SkBitmap* baseline, SkBitmap* test,
+                                   const BitmapsToCreate& bitmapsToCreate,
                                    Result* result) const {
     double startTime = get_seconds();
 
@@ -22,17 +23,34 @@
     if (baseline->width() != test->width() || baseline->height() != test->height() ||
         baseline->width() <= 0 || baseline->height() <= 0 ||
         baseline->colorType() != test->colorType()) {
+        SkASSERT(baseline->width() == test->width());
+        SkASSERT(baseline->height() == test->height());
+        SkASSERT(baseline->width() > 0);
+        SkASSERT(baseline->height() > 0);
+        SkASSERT(baseline->colorType() == test->colorType());
         return false;
     }
 
     int width = baseline->width();
     int height = baseline->height();
+    int maxRedDiff = 0;
+    int maxGreenDiff = 0;
+    int maxBlueDiff = 0;
 
-    // Prepare the POI alpha mask if needed
-    if (computeMask) {
+    // Prepare any bitmaps we will be filling in
+    if (bitmapsToCreate.alphaMask) {
         result->poiAlphaMask.allocPixels(SkImageInfo::MakeA8(width, height));
         result->poiAlphaMask.eraseARGB(SK_AlphaOPAQUE, 0, 0, 0);
     }
+    if (bitmapsToCreate.rgbDiff) {
+        result->rgbDiffBitmap.allocPixels(SkImageInfo::Make(width, height, baseline->colorType(),
+                                                            kPremul_SkAlphaType));
+        result->rgbDiffBitmap.eraseARGB(SK_AlphaTRANSPARENT, 0, 0, 0);
+    }
+    if (bitmapsToCreate.whiteDiff) {
+        result->whiteDiffBitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height));
+        result->whiteDiffBitmap.eraseARGB(SK_AlphaOPAQUE, 0, 0, 0);
+    }
 
     // Prepare the pixels for comparison
     result->poiCount = 0;
@@ -40,24 +58,60 @@
     test->lockPixels();
     for (int y = 0; y < height; y++) {
         // Grab a row from each image for easy comparison
-        unsigned char* baselineRow = (unsigned char*)baseline->getAddr(0, y);
-        unsigned char* testRow = (unsigned char*)test->getAddr(0, y);
+        // TODO(epoger): The code below already assumes 4 bytes per pixel, so I think
+        // we could just call getAddr32() to save a little time.
+        // OR, if we want to play it safe, call ComputeBytesPerPixel instead
+        // of assuming 4 bytes per pixel.
+        uint32_t* baselineRow = static_cast<uint32_t *>(baseline->getAddr(0, y));
+        uint32_t* testRow = static_cast<uint32_t *>(test->getAddr(0, y));
         for (int x = 0; x < width; x++) {
             // Compare one pixel at a time so each differing pixel can be noted
-            if (memcmp(&baselineRow[x * 4], &testRow[x * 4], 4) != 0) {
+            // TODO(epoger): This loop looks like a good place to work on performance,
+            // but we should run the code through a profiler to be sure.
+            uint32_t baselinePixel = baselineRow[x];
+            uint32_t testPixel = testRow[x];
+            if (baselinePixel != testPixel) {
                 result->poiCount++;
-                if (computeMask) {
+
+                int redDiff = abs(static_cast<int>(SkColorGetR(baselinePixel) -
+                                                   SkColorGetR(testPixel)));
+                if (redDiff > maxRedDiff) {maxRedDiff = redDiff;}
+                int greenDiff = abs(static_cast<int>(SkColorGetG(baselinePixel) -
+                                                     SkColorGetG(testPixel)));
+                if (greenDiff > maxGreenDiff) {maxGreenDiff = greenDiff;}
+                int blueDiff = abs(static_cast<int>(SkColorGetB(baselinePixel) -
+                                                    SkColorGetB(testPixel)));
+                if (blueDiff > maxBlueDiff) {maxBlueDiff = blueDiff;}
+
+                if (bitmapsToCreate.alphaMask) {
                     *result->poiAlphaMask.getAddr8(x,y) = SK_AlphaTRANSPARENT;
                 }
+                if (bitmapsToCreate.rgbDiff) {
+                    *result->rgbDiffBitmap.getAddr32(x,y) =
+                        SkColorSetRGB(redDiff, greenDiff, blueDiff);
+                }
+                if (bitmapsToCreate.whiteDiff) {
+                    *result->whiteDiffBitmap.getAddr32(x,y) = SK_ColorWHITE;
+                }
             }
         }
     }
     test->unlockPixels();
     baseline->unlockPixels();
 
-    if (computeMask) {
+    result->maxRedDiff = maxRedDiff;
+    result->maxGreenDiff = maxGreenDiff;
+    result->maxBlueDiff = maxBlueDiff;
+
+    if (bitmapsToCreate.alphaMask) {
         result->poiAlphaMask.unlockPixels();
     }
+    if (bitmapsToCreate.rgbDiff) {
+        result->rgbDiffBitmap.unlockPixels();
+    }
+    if (bitmapsToCreate.whiteDiff) {
+        result->whiteDiffBitmap.unlockPixels();
+    }
 
     // Calculates the percentage of identical pixels
     result->result = 1.0 - ((double)result->poiCount / (width * height));
diff --git a/tools/skpdiff/SkDifferentPixelsMetric_opencl.cpp b/tools/skpdiff/SkDifferentPixelsMetric_opencl.cpp
index 1422505..2e5ab8f 100644
--- a/tools/skpdiff/SkDifferentPixelsMetric_opencl.cpp
+++ b/tools/skpdiff/SkDifferentPixelsMetric_opencl.cpp
@@ -36,7 +36,8 @@
     return "different_pixels";
 }
 
-bool SkDifferentPixelsMetric::diff(SkBitmap* baseline, SkBitmap* test, bool computeMask,
+bool SkDifferentPixelsMetric::diff(SkBitmap* baseline, SkBitmap* test, bool computeAlphaMask,
+                                   bool computeRgbDiff, bool computeWhiteDiff,
                                    Result* result) const {
     double startTime = get_seconds();
 
diff --git a/tools/skpdiff/SkImageDiffer.h b/tools/skpdiff/SkImageDiffer.h
index 641bbe8..1f9ffd1 100644
--- a/tools/skpdiff/SkImageDiffer.h
+++ b/tools/skpdiff/SkImageDiffer.h
@@ -24,10 +24,30 @@
     struct Result {
         double result;
         int poiCount;
+        // TODO(djsollen): Figure out a way that the differ can report which of the
+        // optional fields it has filled in.  See http://skbug.com/2712 ('allow
+        // skpdiff to report different sets of result fields for different comparison algorithms')
         SkBitmap poiAlphaMask; // optional
+        SkBitmap rgbDiffBitmap; // optional
+        SkBitmap whiteDiffBitmap; // optional
+        int maxRedDiff; // optional
+        int maxGreenDiff; // optional
+        int maxBlueDiff; // optional
         double timeElapsed; // optional
     };
 
+    // A bitfield indicating which bitmap types we want a differ to create.
+    //
+    // TODO(epoger): Remove whiteDiffBitmap, because alphaMask can provide
+    // the same functionality and more.
+    // It will be a little bit tricky, because the rebaseline_server client
+    // and server side code will both need to change to use the alphaMask.
+    struct BitmapsToCreate {
+        bool alphaMask;
+        bool rgbDiff;
+        bool whiteDiff;
+    };
+
     /**
      * Gets a unique and descriptive name of this differ
      * @return A statically allocated null terminated string that is the name of this differ
@@ -43,10 +63,10 @@
      * diff on a pair of bitmaps.
      * @param  baseline    The correct bitmap
      * @param  test        The bitmap whose difference is being tested
-     * @param  computeMask true if the differ is to attempt to create poiAlphaMask
+     * @param  bitmapsToCreate  Which bitmaps the differ should attempt to create
      * @return             true on success, and false in the case of failure
      */
-    virtual bool diff(SkBitmap* baseline, SkBitmap* test, bool computeMask,
+    virtual bool diff(SkBitmap* baseline, SkBitmap* test, const BitmapsToCreate& bitmapsToCreate,
                       Result* result) const = 0;
 };
 
diff --git a/tools/skpdiff/SkPMetric.cpp b/tools/skpdiff/SkPMetric.cpp
index a433d9f..392a342 100644
--- a/tools/skpdiff/SkPMetric.cpp
+++ b/tools/skpdiff/SkPMetric.cpp
@@ -442,7 +442,8 @@
     return 1.0 - (double)(*poiCount) / (width * height);
 }
 
-bool SkPMetric::diff(SkBitmap* baseline, SkBitmap* test, bool computeMask, Result* result) const {
+bool SkPMetric::diff(SkBitmap* baseline, SkBitmap* test, const BitmapsToCreate& bitmapsToCreate,
+                     Result* result) const {
     double startTime = get_seconds();
 
     // Ensure the images are comparable
diff --git a/tools/skpdiff/SkPMetric.h b/tools/skpdiff/SkPMetric.h
index b60858a..00a3d7a 100644
--- a/tools/skpdiff/SkPMetric.h
+++ b/tools/skpdiff/SkPMetric.h
@@ -19,7 +19,7 @@
 class SkPMetric : public SkImageDiffer {
 public:
     virtual const char* getName() const SK_OVERRIDE { return "perceptual"; }
-    virtual bool diff(SkBitmap* baseline, SkBitmap* test, bool computeMask,
+    virtual bool diff(SkBitmap* baseline, SkBitmap* test, const BitmapsToCreate& bitmapsToCreate,
                       Result* result) const SK_OVERRIDE;
 
 private:
diff --git a/tools/skpdiff/skpdiff_main.cpp b/tools/skpdiff/skpdiff_main.cpp
index b1bf917..c01767e 100644
--- a/tools/skpdiff/skpdiff_main.cpp
+++ b/tools/skpdiff/skpdiff_main.cpp
@@ -5,6 +5,11 @@
  * found in the LICENSE file.
  */
 
+// TODO(djsollen): Rename this whole package (perhaps to "SkMultiDiffer").
+// It's not just for "pdiff" (perceptual diffs)--it's a harness that allows
+// the execution of an arbitrary set of difference algorithms.
+// See http://skbug.com/2711 ('rename skpdiff')
+
 #if SK_SUPPORT_OPENCL
 
 #define __NO_STD_VECTOR // Uses cl::vectpr instead of std::vectpr
@@ -22,6 +27,7 @@
 #include "SkGraphics.h"
 #include "SkStream.h"
 #include "SkTDArray.h"
+#include "SkTaskGroup.h"
 
 #include "SkDifferentPixelsMetric.h"
 #include "SkDiffContext.h"
@@ -37,11 +43,14 @@
 DEFINE_string2(differs, d, "", "The names of the differs to use or all of them by default");
 DEFINE_string2(folders, f, "", "Compare two folders with identical subfile names: <baseline folder> <test folder>");
 DEFINE_string2(patterns, p, "", "Use two patterns to compare images: <baseline> <test>");
-DEFINE_string2(output, o, "", "Writes the output of these diffs to output: <output>");
-DEFINE_string(alphaDir, "", "Writes the alpha mask of these diffs to output: <output>");
+DEFINE_string2(output, o, "", "Writes a JSON summary of these diffs to file: <filepath>");
+DEFINE_string(alphaDir, "", "If the differ can generate an alpha mask, write it into directory: <dirpath>");
+DEFINE_string(rgbDiffDir, "", "If the differ can generate an image showing the RGB diff at each pixel, write it into directory: <dirpath>");
+DEFINE_string(whiteDiffDir, "", "If the differ can generate an image showing every changed pixel in white, write it into directory: <dirpath>");
 DEFINE_bool(jsonp, true, "Output JSON with padding");
-DEFINE_string(csv, "", "Writes the output of these diffs to a csv file");
+DEFINE_string(csv, "", "Writes the output of these diffs to a csv file: <filepath>");
 DEFINE_int32(threads, -1, "run N threads in parallel [default is derived from CPUs available]");
+DEFINE_bool(longnames, false, "Output image names are a combination of baseline and test names");
 
 #if SK_SUPPORT_OPENCL
 /// A callback for any OpenCL errors
@@ -117,6 +126,7 @@
 
     // Needed by various Skia components
     SkAutoGraphics ag;
+    SkTaskGroup::Enabler enabled;
 
     if (FLAGS_list) {
         SkDebugf("Available Metrics:\n");
@@ -124,7 +134,7 @@
 
     // Figure which differs the user chose, and optionally print them if the user requests it
     SkTDArray<SkImageDiffer*> chosenDiffers;
-    for (int differIndex = 0; NULL != gDiffers[differIndex]; differIndex++) {
+    for (int differIndex = 0; gDiffers[differIndex]; differIndex++) {
         SkImageDiffer* differ = gDiffers[differIndex];
         if (FLAGS_list) {
             SkDebugf("    %s", differ->getName());
@@ -193,12 +203,32 @@
             return 1;
         }
     }
+    if (!FLAGS_rgbDiffDir.isEmpty()) {
+        if (1 != FLAGS_rgbDiffDir.count()) {
+            SkDebugf("rgbDiffDir flag expects one argument: <directory>\n");
+            return 1;
+        }
+    }
+
+    if (!FLAGS_whiteDiffDir.isEmpty()) {
+        if (1 != FLAGS_whiteDiffDir.count()) {
+            SkDebugf("whiteDiffDir flag expects one argument: <directory>\n");
+            return 1;
+        }
+    }
 
     SkDiffContext ctx;
     ctx.setDiffers(chosenDiffers);
+    ctx.setLongNames(FLAGS_longnames);
 
     if (!FLAGS_alphaDir.isEmpty()) {
-        ctx.setDifferenceDir(SkString(FLAGS_alphaDir[0]));
+        ctx.setAlphaMaskDir(SkString(FLAGS_alphaDir[0]));
+    }
+    if (!FLAGS_rgbDiffDir.isEmpty()) {
+        ctx.setRgbDiffDir(SkString(FLAGS_rgbDiffDir[0]));
+    }
+    if (!FLAGS_whiteDiffDir.isEmpty()) {
+        ctx.setWhiteDiffDir(SkString(FLAGS_whiteDiffDir[0]));
     }
 
     if (FLAGS_threads >= 0) {
diff --git a/tools/skpdiff/skpdiff_util.cpp b/tools/skpdiff/skpdiff_util.cpp
index 171721c..498f657 100644
--- a/tools/skpdiff/skpdiff_util.cpp
+++ b/tools/skpdiff/skpdiff_util.cpp
@@ -83,7 +83,7 @@
 }
 #endif
 
-// TODO refactor BenchTimer to be used here
+// TODO refactor Timer to be used here
 double get_seconds() {
 #if SK_BUILD_FOR_WIN32
     LARGE_INTEGER currentTime;
@@ -117,7 +117,7 @@
     while ((entry = readdir(dir))) {
         // dirent only gives relative paths, we need to join them to the base path to check if they
         // are directories.
-        SkString joinedPath = SkOSPath::SkPathJoin(path, entry->d_name);
+        SkString joinedPath = SkOSPath::Join(path, entry->d_name);
 
         // We only care about files
         if (!sk_isdir(joinedPath.c_str())) {
@@ -174,7 +174,7 @@
     // Note these paths are in sorted order by default according to http://linux.die.net/man/3/glob
     // Check under the flag GLOB_NOSORT
     char** paths = globBuffer.gl_pathv;
-    while(NULL != *paths) {
+    while(*paths) {
         entries->push_back(SkString(*paths));
         paths++;
     }
diff --git a/tools/skpinfo.cpp b/tools/skpinfo.cpp
index 6b5eded..5522965 100644
--- a/tools/skpinfo.cpp
+++ b/tools/skpinfo.cpp
@@ -7,13 +7,12 @@
 
 #include "SkCommandLineFlags.h"
 #include "SkPicture.h"
-#include "SkPicturePlayback.h"
+#include "SkPictureData.h"
 #include "SkStream.h"
 
 DEFINE_string2(input, i, "", "skp on which to report");
 DEFINE_bool2(version, v, true, "version");
-DEFINE_bool2(width, w, true, "width");
-DEFINE_bool2(height, h, true, "height");
+DEFINE_bool2(cullRect, c, true, "cullRect");
 DEFINE_bool2(flags, f, true, "flags");
 DEFINE_bool2(tags, t, true, "tags");
 DEFINE_bool2(quiet, q, false, "quiet");
@@ -59,11 +58,10 @@
     if (FLAGS_version && !FLAGS_quiet) {
         SkDebugf("Version: %d\n", info.fVersion);
     }
-    if (FLAGS_width && !FLAGS_quiet) {
-        SkDebugf("Width: %d\n", info.fWidth);
-    }
-    if (FLAGS_height && !FLAGS_quiet) {
-        SkDebugf("Height: %d\n", info.fHeight);
+    if (FLAGS_cullRect && !FLAGS_quiet) {
+        SkDebugf("Cull Rect: %f,%f,%f,%f\n", 
+                 info.fCullRect.fLeft, info.fCullRect.fTop, 
+                 info.fCullRect.fRight, info.fCullRect.fBottom);
     }
     if (FLAGS_flags && !FLAGS_quiet) {
         SkDebugf("Flags: 0x%x\n", info.fFlags);
diff --git a/tools/skpmaker.cpp b/tools/skpmaker.cpp
index 390e5ca..03f720f 100644
--- a/tools/skpmaker.cpp
+++ b/tools/skpmaker.cpp
@@ -25,18 +25,20 @@
 DEFINE_int32(width, 300, "Width of canvas to create.");
 DEFINE_string(writePath, "", "Filepath to write the SKP into.");
 
-static void skpmaker(int width, int height, int border, SkColor color,
+// Create a 'width' by 'height' skp with a 'border'-wide black border around
+// a 'color' rectangle.
+static void make_skp(SkScalar width, SkScalar height, SkScalar border, SkColor color,
                      const char *writePath) {
     SkPictureRecorder recorder;
     SkCanvas* canvas = recorder.beginRecording(width, height, NULL, 0);
     SkPaint paint;
     paint.setStyle(SkPaint::kFill_Style);
     paint.setColor(SK_ColorBLACK);
-    canvas->drawRectCoords(0, 0, SkIntToScalar(width), SkIntToScalar(height), paint);
+    SkRect r = SkRect::MakeWH(width, height);
+    canvas->drawRect(r, paint);
     paint.setColor(color);
-    canvas->drawRectCoords(SkIntToScalar(border), SkIntToScalar(border),
-                           SkIntToScalar(width - border*2), SkIntToScalar(height - border*2),
-                           paint);
+    r.inset(border, border);
+    canvas->drawRect(r, paint);
     SkAutoTUnref<SkPicture> pict(recorder.endRecording());
     SkFILEWStream stream(writePath);
     pict->serialize(&stream);
@@ -74,7 +76,10 @@
     }
 
     SkColor color = SkColorSetRGB(FLAGS_red, FLAGS_green, FLAGS_blue);
-    skpmaker(FLAGS_width, FLAGS_height, FLAGS_border, color, FLAGS_writePath[0]);
+    make_skp(SkIntToScalar(FLAGS_width), 
+             SkIntToScalar(FLAGS_height), 
+             SkIntToScalar(FLAGS_border), 
+             color, FLAGS_writePath[0]);
     return 0;
 }
 
diff --git a/tools/test_font_data.cpp b/tools/test_font_data.cpp
new file mode 100644
index 0000000..2db09b7
--- /dev/null
+++ b/tools/test_font_data.cpp
@@ -0,0 +1,8622 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// Auto-generated by create_test_font.cpp
+
+const SkScalar CourierNewkNormalPoints[] = {
+0.339355f, -0.571289f, 0.320801f, -0.240234f, 0.319824f, -0.224609f, 0.314209f, -0.218262f,
+0.308594f, -0.211914f, 0.300293f, -0.211914f, 0.291504f, -0.211914f, 0.285889f, -0.218262f,
+0.280273f, -0.224609f, 0.279297f, -0.240234f, 0.26123f, -0.571289f, 0.260254f, -0.583008f,
+0.260254f, -0.588379f, 0.260254f, -0.60498f, 0.271729f, -0.616211f, 0.283203f, -0.627441f,
+0.300293f, -0.627441f, 0.317383f, -0.627441f, 0.328613f, -0.616211f, 0.339844f, -0.60498f,
+0.339844f, -0.587891f, 0.339844f, -0.583008f, 0.339355f, -0.571289f, 0.290527f, -0.0869141f,
+0.30957f, -0.0869141f, 0.330566f, -0.0869141f, 0.345459f, -0.0720215f, 0.360352f,
+-0.0571289f, 0.360352f, -0.0361328f, 0.360352f, -0.0146484f, 0.345215f, 0, 0.330078f,
+0.0146484f, 0.30957f, 0.0146484f, 0.290527f, 0.0146484f, 0.269531f, 0.0146484f, 0.254639f,
+-0.000244141f, 0.239746f, -0.0151367f, 0.239746f, -0.0356445f, 0.239746f, -0.0576172f,
+0.254883f, -0.0722656f, 0.27002f, -0.0869141f, 0.290527f, -0.0869141f, 0.484375f,
+-0.642578f, 0.154297f, 0.0644531f, 0.145996f, 0.0825195f, 0.132812f, 0.0825195f,
+0.124512f, 0.0825195f, 0.118408f, 0.076416f, 0.112305f, 0.0703125f, 0.112305f, 0.0629883f,
+0.112305f, 0.0571289f, 0.117188f, 0.046875f, 0.446777f, -0.660156f, 0.452148f, -0.671387f,
+0.457031f, -0.674805f, 0.461914f, -0.678223f, 0.46875f, -0.678223f, 0.477051f, -0.678223f,
+0.483154f, -0.672119f, 0.489258f, -0.666016f, 0.489258f, -0.658691f, 0.489258f, -0.65332f,
+0.484375f, -0.642578f, 0.0478516f, -0.284668f, 0.491211f, -0.531738f, 0.501953f,
+-0.537598f, 0.507324f, -0.537598f, 0.515625f, -0.537598f, 0.521729f, -0.531494f,
+0.527832f, -0.525391f, 0.527832f, -0.51709f, 0.527832f, -0.504883f, 0.51123f, -0.495605f,
+0.131348f, -0.284668f, 0.510742f, -0.0737305f, 0.527344f, -0.0644531f, 0.527344f,
+-0.0522461f, 0.527344f, -0.0439453f, 0.52124f, -0.0378418f, 0.515137f, -0.0317383f,
+0.506836f, -0.0317383f, 0.501465f, -0.0317383f, 0.490723f, -0.0375977f, 0.552246f,
+-0.284668f, 0.108887f, -0.0375977f, 0.0981445f, -0.0317383f, 0.0927734f, -0.0317383f,
+0.0844727f, -0.0317383f, 0.0783691f, -0.0378418f, 0.0722656f, -0.0439453f, 0.0722656f,
+-0.0522461f, 0.0722656f, -0.0644531f, 0.0888672f, -0.0737305f, 0.46875f, -0.284668f,
+0.0893555f, -0.495605f, 0.0727539f, -0.504883f, 0.0727539f, -0.51709f, 0.0727539f,
+-0.525391f, 0.0788574f, -0.531494f, 0.0849609f, -0.537598f, 0.0932617f, -0.537598f,
+0.0986328f, -0.537598f, 0.109375f, -0.531738f, 0.435059f, -0.190918f, 0.165527f,
+-0.190918f, 0.110352f, -0.0410156f, 0.188965f, -0.0410156f, 0.203613f, -0.0410156f,
+0.209961f, -0.0354004f, 0.216309f, -0.0297852f, 0.216309f, -0.0205078f, 0.216309f,
+-0.0117188f, 0.209961f, -0.00585938f, 0.203613f, 0, 0.188965f, 0, 0.0356445f, 0,
+0.0209961f, 0, 0.0146484f, -0.00585938f, 0.00830078f, -0.0117188f, 0.00830078f, -0.0205078f,
+0.00830078f, -0.0297852f, 0.0146484f, -0.0354004f, 0.0209961f, -0.0410156f, 0.0356445f,
+-0.0410156f, 0.0673828f, -0.0410156f, 0.248535f, -0.530273f, 0.127441f, -0.530273f,
+0.112793f, -0.530273f, 0.106445f, -0.535889f, 0.100098f, -0.541504f, 0.100098f, -0.550781f,
+0.100098f, -0.560059f, 0.106445f, -0.565674f, 0.112793f, -0.571289f, 0.127441f, -0.571289f,
+0.333984f, -0.571289f, 0.53418f, -0.0410156f, 0.565918f, -0.0410156f, 0.580566f,
+-0.0410156f, 0.586914f, -0.0354004f, 0.593262f, -0.0297852f, 0.593262f, -0.0205078f,
+0.593262f, -0.0117188f, 0.586914f, -0.00585938f, 0.580566f, 0, 0.565918f, 0, 0.413086f,
+0, 0.397949f, 0, 0.391602f, -0.00585938f, 0.385254f, -0.0117188f, 0.385254f, -0.0205078f,
+0.385254f, -0.0297852f, 0.391602f, -0.0354004f, 0.397949f, -0.0410156f, 0.413086f,
+-0.0410156f, 0.491211f, -0.0410156f, 0.419434f, -0.231934f, 0.306152f, -0.530273f,
+0.291016f, -0.530273f, 0.181152f, -0.231934f, 0.480469f, -0.515137f, 0.480469f, -0.543945f,
+0.480469f, -0.558594f, 0.486084f, -0.564941f, 0.491699f, -0.571289f, 0.500977f, -0.571289f,
+0.510254f, -0.571289f, 0.515869f, -0.564941f, 0.521484f, -0.558594f, 0.521484f, -0.543945f,
+0.521484f, -0.430176f, 0.521484f, -0.415039f, 0.515869f, -0.408691f, 0.510254f, -0.402344f,
+0.500977f, -0.402344f, 0.492676f, -0.402344f, 0.487061f, -0.408203f, 0.481445f, -0.414062f,
+0.480469f, -0.427246f, 0.478027f, -0.468262f, 0.436035f, -0.5f, 0.379395f, -0.543457f,
+0.307129f, -0.543457f, 0.259766f, -0.543457f, 0.217773f, -0.522461f, 0.186523f, -0.507324f,
+0.167969f, -0.485352f, 0.135742f, -0.447266f, 0.116699f, -0.400879f, 0.103027f, -0.366699f,
+0.103027f, -0.32373f, 0.103027f, -0.251953f, 0.103027f, -0.160156f, 0.169434f, -0.0925293f,
+0.23584f, -0.0249023f, 0.32373f, -0.0249023f, 0.376465f, -0.0249023f, 0.418213f,
+-0.0478516f, 0.459961f, -0.0708008f, 0.499023f, -0.117188f, 0.507324f, -0.127441f,
+0.517578f, -0.127441f, 0.526367f, -0.127441f, 0.531738f, -0.12207f, 0.537109f, -0.116699f,
+0.537109f, -0.108398f, 0.537109f, -0.097168f, 0.516113f, -0.0742188f, 0.476074f,
+-0.0292969f, 0.426025f, -0.0065918f, 0.375977f, 0.0161133f, 0.324707f, 0.0161133f,
+0.280273f, 0.0161133f, 0.234375f, -0.000976562f, 0.199219f, -0.0141602f, 0.17627f,
+-0.0317383f, 0.15332f, -0.0493164f, 0.119873f, -0.0910645f, 0.0864258f, -0.132812f,
+0.0742188f, -0.168213f, 0.0620117f, -0.203613f, 0.0620117f, -0.246094f, 0.0620117f,
+-0.32959f, 0.0620117f, -0.390137f, 0.0944824f, -0.453369f, 0.126953f, -0.516602f,
+0.18335f, -0.550537f, 0.239746f, -0.584473f, 0.305664f, -0.584473f, 0.407227f, -0.584473f,
+0.480469f, -0.515137f, 0.438965f, -0.276367f, 0.166992f, -0.276367f, 0.166992f, -0.0410156f,
+0.222168f, -0.0410156f, 0.236816f, -0.0410156f, 0.243164f, -0.0354004f, 0.249512f,
+-0.0297852f, 0.249512f, -0.0205078f, 0.249512f, -0.0117188f, 0.243164f, -0.00585938f,
+0.236816f, 0, 0.222168f, 0, 0.0795898f, 0, 0.0649414f, 0, 0.0585938f, -0.00585938f,
+0.0522461f, -0.0117188f, 0.0522461f, -0.0205078f, 0.0522461f, -0.0297852f, 0.0585938f,
+-0.0354004f, 0.0649414f, -0.0410156f, 0.0795898f, -0.0410156f, 0.125977f, -0.0410156f,
+0.125977f, -0.530273f, 0.100586f, -0.530273f, 0.0854492f, -0.530273f, 0.0791016f,
+-0.535889f, 0.0727539f, -0.541504f, 0.0727539f, -0.550781f, 0.0727539f, -0.560059f,
+0.0791016f, -0.565674f, 0.0854492f, -0.571289f, 0.100586f, -0.571289f, 0.222168f,
+-0.571289f, 0.236816f, -0.571289f, 0.243164f, -0.565674f, 0.249512f, -0.560059f,
+0.249512f, -0.550781f, 0.249512f, -0.541504f, 0.243164f, -0.535889f, 0.236816f, -0.530273f,
+0.222168f, -0.530273f, 0.166992f, -0.530273f, 0.166992f, -0.317383f, 0.438965f, -0.317383f,
+0.438965f, -0.530273f, 0.384277f, -0.530273f, 0.369629f, -0.530273f, 0.363281f, -0.535889f,
+0.356934f, -0.541504f, 0.356934f, -0.550781f, 0.356934f, -0.560059f, 0.363037f, -0.565674f,
+0.369141f, -0.571289f, 0.384277f, -0.571289f, 0.505859f, -0.571289f, 0.520996f, -0.571289f,
+0.527344f, -0.565674f, 0.533691f, -0.560059f, 0.533691f, -0.550781f, 0.533691f, -0.541504f,
+0.527344f, -0.535889f, 0.520996f, -0.530273f, 0.505859f, -0.530273f, 0.480469f, -0.530273f,
+0.480469f, -0.0410156f, 0.526855f, -0.0410156f, 0.541504f, -0.0410156f, 0.547852f,
+-0.0354004f, 0.554199f, -0.0297852f, 0.554199f, -0.0205078f, 0.554199f, -0.0117188f,
+0.547852f, -0.00585938f, 0.541504f, 0, 0.526855f, 0, 0.384277f, 0, 0.369629f, 0,
+0.363281f, -0.00585938f, 0.356934f, -0.0117188f, 0.356934f, -0.0205078f, 0.356934f,
+-0.0297852f, 0.363037f, -0.0354004f, 0.369141f, -0.0410156f, 0.384277f, -0.0410156f,
+0.438965f, -0.0410156f, 0.327148f, -0.171387f, 0.280273f, -0.171387f, 0.122559f,
+-0.530273f, 0.114746f, -0.530273f, 0.114746f, -0.0410156f, 0.19043f, -0.0410156f,
+0.205078f, -0.0410156f, 0.211426f, -0.0354004f, 0.217773f, -0.0297852f, 0.217773f,
+-0.0205078f, 0.217773f, -0.0117188f, 0.211426f, -0.00585938f, 0.205078f, 0, 0.19043f,
+0, 0.0390625f, 0, 0.0244141f, 0, 0.0180664f, -0.00585938f, 0.0117188f, -0.0117188f,
+0.0117188f, -0.0205078f, 0.0117188f, -0.0297852f, 0.0180664f, -0.0354004f, 0.0244141f,
+-0.0410156f, 0.0390625f, -0.0410156f, 0.0737305f, -0.0410156f, 0.0737305f, -0.530273f,
+0.0478516f, -0.530273f, 0.0332031f, -0.530273f, 0.0268555f, -0.535889f, 0.0205078f,
+-0.541504f, 0.0205078f, -0.550781f, 0.0205078f, -0.560059f, 0.0268555f, -0.565674f,
+0.0332031f, -0.571289f, 0.0478516f, -0.571289f, 0.148438f, -0.571289f, 0.303711f,
+-0.217773f, 0.456543f, -0.571289f, 0.557129f, -0.571289f, 0.572266f, -0.571289f,
+0.578613f, -0.565674f, 0.584961f, -0.560059f, 0.584961f, -0.550781f, 0.584961f, -0.541504f,
+0.578613f, -0.535889f, 0.572266f, -0.530273f, 0.557129f, -0.530273f, 0.531738f, -0.530273f,
+0.531738f, -0.0410156f, 0.565918f, -0.0410156f, 0.581055f, -0.0410156f, 0.587402f,
+-0.0354004f, 0.59375f, -0.0297852f, 0.59375f, -0.0205078f, 0.59375f, -0.0117188f,
+0.587402f, -0.00585938f, 0.581055f, 0, 0.565918f, 0, 0.415039f, 0, 0.400391f, 0,
+0.393799f, -0.00585938f, 0.387207f, -0.0117188f, 0.387207f, -0.0205078f, 0.387207f,
+-0.0297852f, 0.393555f, -0.0354004f, 0.399902f, -0.0410156f, 0.415039f, -0.0410156f,
+0.490723f, -0.0410156f, 0.490723f, -0.530273f, 0.481934f, -0.530273f, 0.320312f,
+-0.530273f, 0.320312f, -0.0410156f, 0.426758f, -0.0410156f, 0.441406f, -0.0410156f,
+0.447754f, -0.0354004f, 0.454102f, -0.0297852f, 0.454102f, -0.0205078f, 0.454102f,
+-0.0117188f, 0.447754f, -0.00585938f, 0.441406f, 0, 0.426758f, 0, 0.172363f, 0, 0.157715f,
+0, 0.151367f, -0.00585938f, 0.14502f, -0.0117188f, 0.14502f, -0.0205078f, 0.14502f,
+-0.0297852f, 0.151367f, -0.0354004f, 0.157715f, -0.0410156f, 0.172363f, -0.0410156f,
+0.278809f, -0.0410156f, 0.278809f, -0.530273f, 0.11084f, -0.530273f, 0.11084f, -0.388184f,
+0.11084f, -0.373047f, 0.105225f, -0.366699f, 0.0996094f, -0.360352f, 0.090332f, -0.360352f,
+0.081543f, -0.360352f, 0.0756836f, -0.366699f, 0.0698242f, -0.373047f, 0.0698242f,
+-0.388184f, 0.0698242f, -0.571289f, 0.529297f, -0.571289f, 0.529297f, -0.388184f,
+0.529297f, -0.373047f, 0.523682f, -0.366699f, 0.518066f, -0.360352f, 0.508789f, -0.360352f,
+0.499512f, -0.360352f, 0.493896f, -0.366699f, 0.488281f, -0.373047f, 0.488281f, -0.388184f,
+0.488281f, -0.530273f, 0.47998f, 0, 0.415527f, 0, 0.299316f, -0.405762f, 0.185547f,
+0, 0.121094f, 0, 0.0605469f, -0.530273f, 0.0454102f, -0.530273f, 0.0307617f, -0.530273f,
+0.0244141f, -0.535889f, 0.0180664f, -0.541504f, 0.0180664f, -0.550781f, 0.0180664f,
+-0.560059f, 0.0244141f, -0.565674f, 0.0307617f, -0.571289f, 0.0454102f, -0.571289f,
+0.197754f, -0.571289f, 0.212891f, -0.571289f, 0.219238f, -0.565674f, 0.225586f, -0.560059f,
+0.225586f, -0.550781f, 0.225586f, -0.541504f, 0.219238f, -0.535889f, 0.212891f, -0.530273f,
+0.197754f, -0.530273f, 0.102051f, -0.530273f, 0.15625f, -0.046875f, 0.26709f, -0.444824f,
+0.330078f, -0.444824f, 0.443848f, -0.046875f, 0.49707f, -0.530273f, 0.400879f, -0.530273f,
+0.38623f, -0.530273f, 0.379883f, -0.535889f, 0.373535f, -0.541504f, 0.373535f, -0.550781f,
+0.373535f, -0.560059f, 0.379883f, -0.565674f, 0.38623f, -0.571289f, 0.400879f, -0.571289f,
+0.552246f, -0.571289f, 0.567383f, -0.571289f, 0.57373f, -0.565674f, 0.580078f, -0.560059f,
+0.580078f, -0.550781f, 0.580078f, -0.541504f, 0.57373f, -0.535889f, 0.567383f, -0.530273f,
+0.552246f, -0.530273f, 0.537109f, -0.530273f, 0.321777f, -0.257812f, 0.321777f, -0.0410156f,
+0.428223f, -0.0410156f, 0.442871f, -0.0410156f, 0.449219f, -0.0354004f, 0.455566f,
+-0.0297852f, 0.455566f, -0.0205078f, 0.455566f, -0.0117188f, 0.449219f, -0.00585938f,
+0.442871f, 0, 0.428223f, 0, 0.173828f, 0, 0.15918f, 0, 0.152832f, -0.00585938f, 0.146484f,
+-0.0117188f, 0.146484f, -0.0205078f, 0.146484f, -0.0297852f, 0.152588f, -0.0354004f,
+0.158691f, -0.0410156f, 0.173828f, -0.0410156f, 0.280273f, -0.0410156f, 0.280273f,
+-0.257812f, 0.100098f, -0.530273f, 0.0756836f, -0.530273f, 0.0610352f, -0.530273f,
+0.0546875f, -0.535889f, 0.0483398f, -0.541504f, 0.0483398f, -0.550781f, 0.0483398f,
+-0.560059f, 0.0546875f, -0.565674f, 0.0610352f, -0.571289f, 0.0756836f, -0.571289f,
+0.188477f, -0.571289f, 0.203125f, -0.571289f, 0.209473f, -0.565674f, 0.21582f, -0.560059f,
+0.21582f, -0.550781f, 0.21582f, -0.541504f, 0.209473f, -0.535889f, 0.203125f, -0.530273f,
+0.188477f, -0.530273f, 0.147949f, -0.530273f, 0.30127f, -0.299316f, 0.451172f, -0.530273f,
+0.411133f, -0.530273f, 0.395996f, -0.530273f, 0.389648f, -0.535889f, 0.383301f, -0.541504f,
+0.383301f, -0.550781f, 0.383301f, -0.560059f, 0.389648f, -0.565674f, 0.395996f, -0.571289f,
+0.411133f, -0.571289f, 0.523438f, -0.571289f, 0.538086f, -0.571289f, 0.544434f, -0.565674f,
+0.550781f, -0.560059f, 0.550781f, -0.550781f, 0.550781f, -0.541504f, 0.544434f, -0.535889f,
+0.538086f, -0.530273f, 0.523438f, -0.530273f, 0.499023f, -0.530273f, 0.417969f, 0,
+0.417969f, -0.059082f, 0.328613f, 0.0161133f, 0.227051f, 0.0161133f, 0.15332f, 0.0161133f,
+0.111816f, -0.0212402f, 0.0703125f, -0.0585938f, 0.0703125f, -0.112793f, 0.0703125f,
+-0.172363f, 0.125f, -0.216797f, 0.179688f, -0.26123f, 0.284668f, -0.26123f, 0.312988f,
+-0.26123f, 0.346191f, -0.257568f, 0.379395f, -0.253906f, 0.417969f, -0.246094f, 0.417969f,
+-0.3125f, 0.417969f, -0.346191f, 0.386719f, -0.371094f, 0.355469f, -0.395996f, 0.292969f,
+-0.395996f, 0.245117f, -0.395996f, 0.158691f, -0.368164f, 0.143066f, -0.363281f,
+0.138672f, -0.363281f, 0.130859f, -0.363281f, 0.125244f, -0.369141f, 0.119629f, -0.375f,
+0.119629f, -0.383789f, 0.119629f, -0.39209f, 0.124512f, -0.396973f, 0.131348f, -0.404297f,
+0.179688f, -0.416992f, 0.255859f, -0.4375f, 0.294922f, -0.4375f, 0.372559f, -0.4375f,
+0.416016f, -0.39917f, 0.459473f, -0.36084f, 0.459473f, -0.3125f, 0.459473f, -0.0410156f,
+0.51416f, -0.0410156f, 0.529297f, -0.0410156f, 0.535645f, -0.0354004f, 0.541992f,
+-0.0297852f, 0.541992f, -0.0205078f, 0.541992f, -0.0117188f, 0.535645f, -0.00585938f,
+0.529297f, 0, 0.51416f, 0, 0.417969f, -0.204102f, 0.38916f, -0.212402f, 0.356934f,
+-0.216309f, 0.324707f, -0.220215f, 0.289062f, -0.220215f, 0.199707f, -0.220215f,
+0.149414f, -0.181641f, 0.111328f, -0.152832f, 0.111328f, -0.112793f, 0.111328f, -0.0756836f,
+0.140381f, -0.050293f, 0.169434f, -0.0249023f, 0.225098f, -0.0249023f, 0.27832f,
+-0.0249023f, 0.323975f, -0.0461426f, 0.369629f, -0.0673828f, 0.417969f, -0.11377f,
+0.145508f, -0.612793f, 0.145508f, -0.34082f, 0.219727f, -0.4375f, 0.324707f, -0.4375f,
+0.414551f, -0.4375f, 0.478516f, -0.372314f, 0.54248f, -0.307129f, 0.54248f, -0.212402f,
+0.54248f, -0.116699f, 0.477783f, -0.050293f, 0.413086f, 0.0161133f, 0.324707f, 0.0161133f,
+0.217285f, 0.0161133f, 0.145508f, -0.0805664f, 0.145508f, 0, 0.0493164f, 0, 0.034668f,
+0, 0.0283203f, -0.00585938f, 0.0219727f, -0.0117188f, 0.0219727f, -0.0205078f, 0.0219727f,
+-0.0297852f, 0.0283203f, -0.0354004f, 0.034668f, -0.0410156f, 0.0493164f, -0.0410156f,
+0.104492f, -0.0410156f, 0.104492f, -0.571289f, 0.0493164f, -0.571289f, 0.034668f,
+-0.571289f, 0.0283203f, -0.577148f, 0.0219727f, -0.583008f, 0.0219727f, -0.592285f,
+0.0219727f, -0.601074f, 0.0283203f, -0.606934f, 0.034668f, -0.612793f, 0.0493164f,
+-0.612793f, 0.501465f, -0.210449f, 0.501465f, -0.288086f, 0.448242f, -0.342041f,
+0.39502f, -0.395996f, 0.32373f, -0.395996f, 0.252441f, -0.395996f, 0.199219f, -0.342041f,
+0.145996f, -0.288086f, 0.145996f, -0.210449f, 0.145996f, -0.132812f, 0.199219f, -0.0788574f,
+0.252441f, -0.0249023f, 0.32373f, -0.0249023f, 0.39502f, -0.0249023f, 0.448242f,
+-0.0788574f, 0.501465f, -0.132812f, 0.501465f, -0.210449f, 0.471191f, -0.381348f,
+0.471191f, -0.39502f, 0.471191f, -0.410156f, 0.477051f, -0.416504f, 0.48291f, -0.422852f,
+0.491699f, -0.422852f, 0.500977f, -0.422852f, 0.506836f, -0.416504f, 0.512695f, -0.410156f,
+0.512695f, -0.39502f, 0.512695f, -0.302246f, 0.512207f, -0.287109f, 0.506592f, -0.280762f,
+0.500977f, -0.274414f, 0.491699f, -0.274414f, 0.483398f, -0.274414f, 0.477783f, -0.280029f,
+0.472168f, -0.285645f, 0.471191f, -0.298828f, 0.468262f, -0.333496f, 0.425537f, -0.364746f,
+0.382812f, -0.395996f, 0.310547f, -0.395996f, 0.219238f, -0.395996f, 0.171875f, -0.338867f,
+0.124512f, -0.281738f, 0.124512f, -0.208008f, 0.124512f, -0.128418f, 0.176758f, -0.0766602f,
+0.229004f, -0.0249023f, 0.312012f, -0.0249023f, 0.359863f, -0.0249023f, 0.409424f,
+-0.0424805f, 0.458984f, -0.0600586f, 0.499023f, -0.0991211f, 0.509277f, -0.108887f,
+0.51709f, -0.108887f, 0.525391f, -0.108887f, 0.531006f, -0.103271f, 0.536621f, -0.0976562f,
+0.536621f, -0.0893555f, 0.536621f, -0.0683594f, 0.487305f, -0.0361328f, 0.407715f,
+0.0161133f, 0.310059f, 0.0161133f, 0.210938f, 0.0161133f, 0.147217f, -0.0471191f,
+0.0834961f, -0.110352f, 0.0834961f, -0.20752f, 0.0834961f, -0.306641f, 0.148682f,
+-0.37207f, 0.213867f, -0.4375f, 0.312988f, -0.4375f, 0.407227f, -0.4375f, 0.471191f,
+-0.381348f, 0.500977f, -0.612793f, 0.500977f, -0.0410156f, 0.555664f, -0.0410156f,
+0.570801f, -0.0410156f, 0.577148f, -0.0354004f, 0.583496f, -0.0297852f, 0.583496f,
+-0.0205078f, 0.583496f, -0.0117188f, 0.577148f, -0.00585938f, 0.570801f, 0, 0.555664f,
+0, 0.459473f, 0, 0.459473f, -0.081543f, 0.388184f, 0.0161133f, 0.27832f, 0.0161133f,
+0.222656f, 0.0161133f, 0.171631f, -0.0134277f, 0.120605f, -0.0429688f, 0.0910645f,
+-0.0976562f, 0.0615234f, -0.152344f, 0.0615234f, -0.210449f, 0.0615234f, -0.269043f,
+0.0910645f, -0.323486f, 0.120605f, -0.37793f, 0.171631f, -0.407715f, 0.222656f, -0.4375f,
+0.278809f, -0.4375f, 0.38623f, -0.4375f, 0.459473f, -0.339844f, 0.459473f, -0.571289f,
+0.404785f, -0.571289f, 0.389648f, -0.571289f, 0.383301f, -0.577148f, 0.376953f, -0.583008f,
+0.376953f, -0.592285f, 0.376953f, -0.601074f, 0.383301f, -0.606934f, 0.389648f, -0.612793f,
+0.404785f, -0.612793f, 0.459473f, -0.210449f, 0.459473f, -0.288574f, 0.406738f, -0.342285f,
+0.354004f, -0.395996f, 0.28125f, -0.395996f, 0.208008f, -0.395996f, 0.155273f, -0.342285f,
+0.102539f, -0.288574f, 0.102539f, -0.210449f, 0.102539f, -0.132812f, 0.155273f, -0.0788574f,
+0.208008f, -0.0249023f, 0.28125f, -0.0249023f, 0.354004f, -0.0249023f, 0.406738f,
+-0.0788574f, 0.459473f, -0.132812f, 0.459473f, -0.210449f, 0.521973f, -0.20166f,
+0.104004f, -0.20166f, 0.114746f, -0.12207f, 0.170654f, -0.0734863f, 0.226562f, -0.0249023f,
+0.309082f, -0.0249023f, 0.35498f, -0.0249023f, 0.405273f, -0.0400391f, 0.455566f,
+-0.0551758f, 0.487305f, -0.0800781f, 0.496582f, -0.0874023f, 0.503418f, -0.0874023f,
+0.51123f, -0.0874023f, 0.51709f, -0.0812988f, 0.522949f, -0.0751953f, 0.522949f,
+-0.0668945f, 0.522949f, -0.0585938f, 0.515137f, -0.0507812f, 0.491699f, -0.0263672f,
+0.431885f, -0.00512695f, 0.37207f, 0.0161133f, 0.309082f, 0.0161133f, 0.203613f,
+0.0161133f, 0.133057f, -0.0529785f, 0.0625f, -0.12207f, 0.0625f, -0.220215f, 0.0625f,
+-0.30957f, 0.128662f, -0.373535f, 0.194824f, -0.4375f, 0.29248f, -0.4375f, 0.393066f,
+-0.4375f, 0.458008f, -0.371826f, 0.522949f, -0.306152f, 0.521973f, -0.20166f, 0.480469f,
+-0.243164f, 0.468262f, -0.311035f, 0.41626f, -0.353516f, 0.364258f, -0.395996f, 0.29248f,
+-0.395996f, 0.220703f, -0.395996f, 0.168945f, -0.354004f, 0.117188f, -0.312012f,
+0.104492f, -0.243164f, 0.272949f, -0.381348f, 0.272949f, -0.0410156f, 0.453125f,
+-0.0410156f, 0.467773f, -0.0410156f, 0.474121f, -0.0354004f, 0.480469f, -0.0297852f,
+0.480469f, -0.0205078f, 0.480469f, -0.0117188f, 0.474121f, -0.00585938f, 0.467773f,
+0, 0.453125f, 0, 0.132324f, 0, 0.117676f, 0, 0.111328f, -0.00585938f, 0.10498f, -0.0117188f,
+0.10498f, -0.0205078f, 0.10498f, -0.0297852f, 0.111328f, -0.0354004f, 0.117676f,
+-0.0410156f, 0.132324f, -0.0410156f, 0.231445f, -0.0410156f, 0.231445f, -0.381348f,
+0.142578f, -0.381348f, 0.12793f, -0.381348f, 0.121582f, -0.387207f, 0.115234f, -0.393066f,
+0.115234f, -0.402344f, 0.115234f, -0.411133f, 0.121582f, -0.416992f, 0.12793f, -0.422852f,
+0.142578f, -0.422852f, 0.231445f, -0.422852f, 0.231445f, -0.484863f, 0.231445f, -0.536621f,
+0.273438f, -0.574707f, 0.31543f, -0.612793f, 0.384766f, -0.612793f, 0.442871f, -0.612793f,
+0.508789f, -0.602051f, 0.533691f, -0.598145f, 0.538818f, -0.592773f, 0.543945f, -0.587402f,
+0.543945f, -0.578613f, 0.543945f, -0.569824f, 0.538086f, -0.564209f, 0.532227f, -0.558594f,
+0.522461f, -0.558594f, 0.518555f, -0.558594f, 0.509277f, -0.560059f, 0.435547f, -0.571289f,
+0.384766f, -0.571289f, 0.331055f, -0.571289f, 0.302002f, -0.544922f, 0.272949f, -0.518555f,
+0.272949f, -0.484863f, 0.272949f, -0.422852f, 0.464844f, -0.422852f, 0.479492f, -0.422852f,
+0.48584f, -0.416992f, 0.492188f, -0.411133f, 0.492188f, -0.401855f, 0.492188f, -0.393066f,
+0.48584f, -0.387207f, 0.479492f, -0.381348f, 0.464844f, -0.381348f, 0.437988f, -0.347656f,
+0.437988f, -0.422852f, 0.53418f, -0.422852f, 0.548828f, -0.422852f, 0.555176f, -0.416992f,
+0.561523f, -0.411133f, 0.561523f, -0.401855f, 0.561523f, -0.393066f, 0.555176f, -0.387207f,
+0.548828f, -0.381348f, 0.53418f, -0.381348f, 0.479004f, -0.381348f, 0.479004f, 0.0283203f,
+0.479004f, 0.0693359f, 0.461426f, 0.101562f, 0.449707f, 0.123047f, 0.422363f, 0.145996f,
+0.39502f, 0.168945f, 0.372559f, 0.178711f, 0.350098f, 0.188477f, 0.3125f, 0.188477f,
+0.196289f, 0.188477f, 0.181641f, 0.188477f, 0.175293f, 0.182861f, 0.168945f, 0.177246f,
+0.168945f, 0.167969f, 0.168945f, 0.158691f, 0.175293f, 0.152832f, 0.181641f, 0.146973f,
+0.196289f, 0.146973f, 0.313965f, 0.147461f, 0.350098f, 0.147461f, 0.37915f, 0.128906f,
+0.408203f, 0.110352f, 0.427246f, 0.074707f, 0.437988f, 0.0541992f, 0.437988f, 0.0224609f,
+0.437988f, -0.100586f, 0.37207f, -0.0102539f, 0.268066f, -0.0102539f, 0.183594f,
+-0.0102539f, 0.122314f, -0.072998f, 0.0610352f, -0.135742f, 0.0610352f, -0.224121f,
+0.0610352f, -0.3125f, 0.122314f, -0.375f, 0.183594f, -0.4375f, 0.268066f, -0.4375f,
+0.37207f, -0.4375f, 0.437988f, -0.347656f, 0.437988f, -0.224121f, 0.437988f, -0.296387f,
+0.388428f, -0.346191f, 0.338867f, -0.395996f, 0.27002f, -0.395996f, 0.201172f, -0.395996f,
+0.151855f, -0.345947f, 0.102539f, -0.295898f, 0.102539f, -0.224121f, 0.102539f, -0.151855f,
+0.151855f, -0.101807f, 0.201172f, -0.0517578f, 0.27002f, -0.0517578f, 0.338867f,
+-0.0517578f, 0.388428f, -0.101807f, 0.437988f, -0.151855f, 0.437988f, -0.224121f,
+0.320312f, -0.633301f, 0.320312f, -0.527344f, 0.259766f, -0.527344f, 0.259766f, -0.633301f,
+0.321777f, -0.422852f, 0.321777f, -0.0410156f, 0.48291f, -0.0410156f, 0.498047f,
+-0.0410156f, 0.504395f, -0.0354004f, 0.510742f, -0.0297852f, 0.510742f, -0.0205078f,
+0.510742f, -0.0117188f, 0.504395f, -0.00585938f, 0.498047f, 0, 0.48291f, 0, 0.119629f,
+0, 0.10498f, 0, 0.0986328f, -0.00585938f, 0.0922852f, -0.0117188f, 0.0922852f, -0.0205078f,
+0.0922852f, -0.0297852f, 0.0986328f, -0.0354004f, 0.10498f, -0.0410156f, 0.119629f,
+-0.0410156f, 0.280762f, -0.0410156f, 0.280762f, -0.381348f, 0.161133f, -0.381348f,
+0.146484f, -0.381348f, 0.139893f, -0.387207f, 0.133301f, -0.393066f, 0.133301f, -0.401855f,
+0.133301f, -0.411133f, 0.139648f, -0.416992f, 0.145996f, -0.422852f, 0.161133f, -0.422852f,
+0.320801f, -0.612793f, 0.320801f, -0.0410156f, 0.481934f, -0.0410156f, 0.49707f,
+-0.0410156f, 0.503418f, -0.0354004f, 0.509766f, -0.0297852f, 0.509766f, -0.0205078f,
+0.509766f, -0.0117188f, 0.503418f, -0.00585938f, 0.49707f, 0, 0.481934f, 0, 0.118652f,
+0, 0.104004f, 0, 0.0976562f, -0.00585938f, 0.0913086f, -0.0117188f, 0.0913086f, -0.0205078f,
+0.0913086f, -0.0297852f, 0.0976562f, -0.0354004f, 0.104004f, -0.0410156f, 0.118652f,
+-0.0410156f, 0.279785f, -0.0410156f, 0.279785f, -0.571289f, 0.161621f, -0.571289f,
+0.146973f, -0.571289f, 0.140381f, -0.577148f, 0.133789f, -0.583008f, 0.133789f, -0.592285f,
+0.133789f, -0.601074f, 0.140137f, -0.606934f, 0.146484f, -0.612793f, 0.161621f, -0.612793f,
+0.113281f, -0.422852f, 0.113281f, -0.381348f, 0.165527f, -0.4375f, 0.218262f, -0.4375f,
+0.25f, -0.4375f, 0.273926f, -0.420654f, 0.297852f, -0.403809f, 0.313965f, -0.369629f,
+0.341309f, -0.403809f, 0.369385f, -0.420654f, 0.397461f, -0.4375f, 0.425781f, -0.4375f,
+0.470215f, -0.4375f, 0.496582f, -0.408691f, 0.53125f, -0.371582f, 0.53125f, -0.327637f,
+0.53125f, -0.0410156f, 0.565918f, -0.0410156f, 0.580566f, -0.0410156f, 0.586914f,
+-0.0354004f, 0.593262f, -0.0297852f, 0.593262f, -0.0205078f, 0.593262f, -0.0117188f,
+0.586914f, -0.00585938f, 0.580566f, 0, 0.565918f, 0, 0.490234f, 0, 0.490234f, -0.32373f,
+0.490234f, -0.35498f, 0.471191f, -0.375488f, 0.452148f, -0.395996f, 0.427246f, -0.395996f,
+0.404785f, -0.395996f, 0.379883f, -0.37915f, 0.35498f, -0.362305f, 0.323242f, -0.312988f,
+0.323242f, -0.0410156f, 0.357422f, -0.0410156f, 0.37207f, -0.0410156f, 0.378418f,
+-0.0354004f, 0.384766f, -0.0297852f, 0.384766f, -0.0205078f, 0.384766f, -0.0117188f,
+0.378418f, -0.00585938f, 0.37207f, 0, 0.357422f, 0, 0.281738f, 0, 0.281738f, -0.320801f,
+0.281738f, -0.353516f, 0.262451f, -0.374756f, 0.243164f, -0.395996f, 0.219238f, -0.395996f,
+0.197266f, -0.395996f, 0.175781f, -0.381836f, 0.145996f, -0.361816f, 0.113281f, -0.312988f,
+0.113281f, -0.0410156f, 0.147949f, -0.0410156f, 0.162598f, -0.0410156f, 0.168945f,
+-0.0354004f, 0.175293f, -0.0297852f, 0.175293f, -0.0205078f, 0.175293f, -0.0117188f,
+0.168945f, -0.00585938f, 0.162598f, 0, 0.147949f, 0, 0.0375977f, 0, 0.0229492f, 0,
+0.0166016f, -0.00585938f, 0.0102539f, -0.0117188f, 0.0102539f, -0.0205078f, 0.0102539f,
+-0.0297852f, 0.0166016f, -0.0354004f, 0.0229492f, -0.0410156f, 0.0375977f, -0.0410156f,
+0.0722656f, -0.0410156f, 0.0722656f, -0.381348f, 0.0375977f, -0.381348f, 0.0229492f,
+-0.381348f, 0.0166016f, -0.387207f, 0.0102539f, -0.393066f, 0.0102539f, -0.402344f,
+0.0102539f, -0.411133f, 0.0166016f, -0.416992f, 0.0229492f, -0.422852f, 0.0375977f,
+-0.422852f, 0.16748f, -0.422852f, 0.16748f, -0.36084f, 0.210449f, -0.404297f, 0.245117f,
+-0.420898f, 0.279785f, -0.4375f, 0.323242f, -0.4375f, 0.370117f, -0.4375f, 0.408691f,
+-0.41748f, 0.436035f, -0.402832f, 0.458252f, -0.368896f, 0.480469f, -0.334961f, 0.480469f,
+-0.299316f, 0.480469f, -0.0410156f, 0.515137f, -0.0410156f, 0.529785f, -0.0410156f,
+0.536133f, -0.0354004f, 0.54248f, -0.0297852f, 0.54248f, -0.0205078f, 0.54248f, -0.0117188f,
+0.536133f, -0.00585938f, 0.529785f, 0, 0.515137f, 0, 0.405273f, 0, 0.390137f, 0,
+0.383789f, -0.00585938f, 0.377441f, -0.0117188f, 0.377441f, -0.0205078f, 0.377441f,
+-0.0297852f, 0.383789f, -0.0354004f, 0.390137f, -0.0410156f, 0.405273f, -0.0410156f,
+0.439453f, -0.0410156f, 0.439453f, -0.29248f, 0.439453f, -0.335938f, 0.407715f, -0.365967f,
+0.375977f, -0.395996f, 0.322754f, -0.395996f, 0.282227f, -0.395996f, 0.252441f, -0.379639f,
+0.222656f, -0.363281f, 0.16748f, -0.29834f, 0.16748f, -0.0410156f, 0.213867f, -0.0410156f,
+0.228516f, -0.0410156f, 0.234863f, -0.0354004f, 0.241211f, -0.0297852f, 0.241211f,
+-0.0205078f, 0.241211f, -0.0117188f, 0.234863f, -0.00585938f, 0.228516f, 0, 0.213867f,
+0, 0.0800781f, 0, 0.0654297f, 0, 0.059082f, -0.00585938f, 0.0527344f, -0.0117188f,
+0.0527344f, -0.0205078f, 0.0527344f, -0.0297852f, 0.059082f, -0.0354004f, 0.0654297f,
+-0.0410156f, 0.0800781f, -0.0410156f, 0.126465f, -0.0410156f, 0.126465f, -0.381348f,
+0.0917969f, -0.381348f, 0.0771484f, -0.381348f, 0.0708008f, -0.387207f, 0.0644531f,
+-0.393066f, 0.0644531f, -0.402344f, 0.0644531f, -0.411133f, 0.0708008f, -0.416992f,
+0.0771484f, -0.422852f, 0.0917969f, -0.422852f, 0.529297f, -0.210449f, 0.529297f,
+-0.116699f, 0.462158f, -0.050293f, 0.39502f, 0.0161133f, 0.300293f, 0.0161133f, 0.20459f,
+0.0161133f, 0.137695f, -0.0505371f, 0.0708008f, -0.117188f, 0.0708008f, -0.210449f,
+0.0708008f, -0.304199f, 0.137695f, -0.37085f, 0.20459f, -0.4375f, 0.300293f, -0.4375f,
+0.39502f, -0.4375f, 0.462158f, -0.371094f, 0.529297f, -0.304688f, 0.529297f, -0.210449f,
+0.487793f, -0.210449f, 0.487793f, -0.287598f, 0.432861f, -0.341797f, 0.37793f, -0.395996f,
+0.299805f, -0.395996f, 0.22168f, -0.395996f, 0.166748f, -0.341553f, 0.111816f, -0.287109f,
+0.111816f, -0.210449f, 0.111816f, -0.134277f, 0.166748f, -0.0795898f, 0.22168f, -0.0249023f,
+0.299805f, -0.0249023f, 0.37793f, -0.0249023f, 0.432861f, -0.0793457f, 0.487793f,
+-0.133789f, 0.487793f, -0.210449f, 0.145508f, -0.422852f, 0.145508f, -0.348145f,
+0.182129f, -0.392578f, 0.224121f, -0.415039f, 0.266113f, -0.4375f, 0.323242f, -0.4375f,
+0.383789f, -0.4375f, 0.435059f, -0.40918f, 0.486328f, -0.380859f, 0.514404f, -0.330322f,
+0.54248f, -0.279785f, 0.54248f, -0.224121f, 0.54248f, -0.135742f, 0.479248f, -0.072998f,
+0.416016f, -0.0102539f, 0.32373f, -0.0102539f, 0.213867f, -0.0102539f, 0.145508f,
+-0.0996094f, 0.145508f, 0.147461f, 0.245117f, 0.147461f, 0.259766f, 0.147461f, 0.266113f,
+0.153076f, 0.272461f, 0.158691f, 0.272461f, 0.167969f, 0.272461f, 0.176758f, 0.266113f,
+0.182617f, 0.259766f, 0.188477f, 0.245117f, 0.188477f, 0.0493164f, 0.188477f, 0.034668f,
+0.188477f, 0.0283203f, 0.182861f, 0.0219727f, 0.177246f, 0.0219727f, 0.167969f, 0.0219727f,
+0.158691f, 0.0283203f, 0.153076f, 0.034668f, 0.147461f, 0.0493164f, 0.147461f, 0.104492f,
+0.147461f, 0.104492f, -0.381348f, 0.0493164f, -0.381348f, 0.034668f, -0.381348f,
+0.0283203f, -0.387207f, 0.0219727f, -0.393066f, 0.0219727f, -0.402344f, 0.0219727f,
+-0.411133f, 0.0283203f, -0.416992f, 0.034668f, -0.422852f, 0.0493164f, -0.422852f,
+0.500977f, -0.224121f, 0.500977f, -0.294922f, 0.449463f, -0.345459f, 0.397949f, -0.395996f,
+0.32373f, -0.395996f, 0.249023f, -0.395996f, 0.197266f, -0.345215f, 0.145508f, -0.294434f,
+0.145508f, -0.224121f, 0.145508f, -0.15332f, 0.197266f, -0.102539f, 0.249023f, -0.0517578f,
+0.32373f, -0.0517578f, 0.397461f, -0.0517578f, 0.449219f, -0.102295f, 0.500977f,
+-0.152832f, 0.500977f, -0.224121f, 0.250977f, -0.422852f, 0.250977f, -0.319336f,
+0.331055f, -0.391602f, 0.37085f, -0.412354f, 0.410645f, -0.433105f, 0.444336f, -0.433105f,
+0.480957f, -0.433105f, 0.512451f, -0.408447f, 0.543945f, -0.383789f, 0.543945f, -0.371094f,
+0.543945f, -0.361816f, 0.537842f, -0.355713f, 0.531738f, -0.349609f, 0.522461f, -0.349609f,
+0.517578f, -0.349609f, 0.51416f, -0.351318f, 0.510742f, -0.353027f, 0.501465f, -0.362305f,
+0.484375f, -0.379395f, 0.47168f, -0.385742f, 0.458984f, -0.39209f, 0.446777f, -0.39209f,
+0.419922f, -0.39209f, 0.38208f, -0.370605f, 0.344238f, -0.349121f, 0.250977f, -0.265625f,
+0.250977f, -0.0410156f, 0.432617f, -0.0410156f, 0.447754f, -0.0410156f, 0.454102f,
+-0.0354004f, 0.460449f, -0.0297852f, 0.460449f, -0.0205078f, 0.460449f, -0.0117188f,
+0.454102f, -0.00585938f, 0.447754f, 0, 0.432617f, 0, 0.11084f, 0, 0.0961914f, 0,
+0.0898438f, -0.00561523f, 0.0834961f, -0.0112305f, 0.0834961f, -0.0200195f, 0.0834961f,
+-0.0283203f, 0.0895996f, -0.0339355f, 0.0957031f, -0.0395508f, 0.11084f, -0.0395508f,
+0.209961f, -0.0395508f, 0.209961f, -0.381348f, 0.134277f, -0.381348f, 0.119629f,
+-0.381348f, 0.113281f, -0.387207f, 0.106934f, -0.393066f, 0.106934f, -0.402344f,
+0.106934f, -0.411133f, 0.113037f, -0.416992f, 0.119141f, -0.422852f, 0.134277f, -0.422852f,
+0.435547f, -0.395996f, 0.435547f, -0.410156f, 0.441406f, -0.416504f, 0.447266f, -0.422852f,
+0.456055f, -0.422852f, 0.465332f, -0.422852f, 0.471191f, -0.416504f, 0.477051f, -0.410156f,
+0.477051f, -0.39502f, 0.477051f, -0.324707f, 0.477051f, -0.310059f, 0.471191f, -0.303711f,
+0.465332f, -0.297363f, 0.456055f, -0.297363f, 0.447754f, -0.297363f, 0.442139f, -0.302734f,
+0.436523f, -0.308105f, 0.435547f, -0.320312f, 0.432617f, -0.349609f, 0.405273f, -0.368652f,
+0.365234f, -0.395996f, 0.299316f, -0.395996f, 0.230469f, -0.395996f, 0.192383f, -0.368164f,
+0.163574f, -0.347168f, 0.163574f, -0.321289f, 0.163574f, -0.291992f, 0.197754f, -0.272461f,
+0.221191f, -0.258789f, 0.286621f, -0.251465f, 0.37207f, -0.242188f, 0.405273f, -0.230469f,
+0.452637f, -0.213379f, 0.47583f, -0.183105f, 0.499023f, -0.152832f, 0.499023f, -0.117676f,
+0.499023f, -0.0654297f, 0.44873f, -0.0246582f, 0.398438f, 0.0161133f, 0.30127f, 0.0161133f,
+0.204102f, 0.0161133f, 0.14209f, -0.0332031f, 0.14209f, -0.0166016f, 0.140137f, -0.0117188f,
+0.138184f, -0.00683594f, 0.133057f, -0.00341797f, 0.12793f, 0, 0.121582f, 0, 0.112793f,
+0, 0.106934f, -0.00634766f, 0.101074f, -0.0126953f, 0.101074f, -0.0273438f, 0.101074f,
+-0.111816f, 0.101074f, -0.126465f, 0.106689f, -0.132812f, 0.112305f, -0.13916f, 0.121582f,
+-0.13916f, 0.130371f, -0.13916f, 0.136475f, -0.133057f, 0.142578f, -0.126953f, 0.142578f,
+-0.116699f, 0.142578f, -0.0942383f, 0.153809f, -0.0791016f, 0.170898f, -0.0556641f,
+0.208252f, -0.0402832f, 0.245605f, -0.0249023f, 0.299805f, -0.0249023f, 0.379883f,
+-0.0249023f, 0.418945f, -0.0546875f, 0.458008f, -0.0844727f, 0.458008f, -0.117676f,
+0.458008f, -0.155762f, 0.418457f, -0.178711f, 0.378418f, -0.20166f, 0.302002f, -0.209473f,
+0.225586f, -0.217285f, 0.192383f, -0.22998f, 0.15918f, -0.242676f, 0.140625f, -0.268066f,
+0.12207f, -0.293457f, 0.12207f, -0.322754f, 0.12207f, -0.375488f, 0.173828f, -0.406494f,
+0.225586f, -0.4375f, 0.297363f, -0.4375f, 0.382324f, -0.4375f, 0.435547f, -0.395996f,
+0.21582f, -0.422852f, 0.438477f, -0.422852f, 0.453125f, -0.422852f, 0.459473f, -0.416992f,
+0.46582f, -0.411133f, 0.46582f, -0.401855f, 0.46582f, -0.393066f, 0.459473f, -0.387207f,
+0.453125f, -0.381348f, 0.438477f, -0.381348f, 0.21582f, -0.381348f, 0.21582f, -0.108398f,
+0.21582f, -0.0727539f, 0.244385f, -0.0488281f, 0.272949f, -0.0249023f, 0.328125f,
+-0.0249023f, 0.369629f, -0.0249023f, 0.417969f, -0.0373535f, 0.466309f, -0.0498047f,
+0.493164f, -0.0654297f, 0.50293f, -0.0717773f, 0.509277f, -0.0717773f, 0.51709f,
+-0.0717773f, 0.522949f, -0.0656738f, 0.528809f, -0.0595703f, 0.528809f, -0.0512695f,
+0.528809f, -0.0439453f, 0.522461f, -0.0375977f, 0.506836f, -0.0214844f, 0.446533f,
+-0.00268555f, 0.38623f, 0.0161133f, 0.331055f, 0.0161133f, 0.259277f, 0.0161133f,
+0.216797f, -0.0175781f, 0.174316f, -0.0512695f, 0.174316f, -0.108398f, 0.174316f,
+-0.381348f, 0.0986328f, -0.381348f, 0.0839844f, -0.381348f, 0.0776367f, -0.387207f,
+0.0712891f, -0.393066f, 0.0712891f, -0.402344f, 0.0712891f, -0.411133f, 0.0776367f,
+-0.416992f, 0.0839844f, -0.422852f, 0.0986328f, -0.422852f, 0.174316f, -0.422852f,
+0.174316f, -0.543945f, 0.174316f, -0.558594f, 0.180176f, -0.564941f, 0.186035f, -0.571289f,
+0.194824f, -0.571289f, 0.204102f, -0.571289f, 0.209961f, -0.564941f, 0.21582f, -0.558594f,
+0.21582f, -0.543945f, 0.44043f, 0, 0.44043f, -0.0600586f, 0.356445f, 0.0161133f,
+0.258789f, 0.0161133f, 0.19873f, 0.0161133f, 0.16748f, -0.0166016f, 0.126953f, -0.0595703f,
+0.126953f, -0.116699f, 0.126953f, -0.381348f, 0.0717773f, -0.381348f, 0.0571289f,
+-0.381348f, 0.0507812f, -0.387207f, 0.0444336f, -0.393066f, 0.0444336f, -0.402344f,
+0.0444336f, -0.411133f, 0.0507812f, -0.416992f, 0.0571289f, -0.422852f, 0.0717773f,
+-0.422852f, 0.167969f, -0.422852f, 0.167969f, -0.116699f, 0.167969f, -0.0766602f,
+0.193359f, -0.0507812f, 0.21875f, -0.0249023f, 0.256836f, -0.0249023f, 0.356934f,
+-0.0249023f, 0.44043f, -0.116699f, 0.44043f, -0.381348f, 0.364746f, -0.381348f, 0.350098f,
+-0.381348f, 0.34375f, -0.387207f, 0.337402f, -0.393066f, 0.337402f, -0.402344f, 0.337402f,
+-0.411133f, 0.34375f, -0.416992f, 0.350098f, -0.422852f, 0.364746f, -0.422852f, 0.481445f,
+-0.422852f, 0.481445f, -0.0410156f, 0.516113f, -0.0410156f, 0.530762f, -0.0410156f,
+0.537109f, -0.0354004f, 0.543457f, -0.0297852f, 0.543457f, -0.0205078f, 0.543457f,
+-0.0117188f, 0.537109f, -0.00585938f, 0.530762f, 0, 0.516113f, 0, 0.302734f, 0, 0.112305f,
+-0.381348f, 0.100098f, -0.381348f, 0.0854492f, -0.381348f, 0.0791016f, -0.387207f,
+0.0727539f, -0.393066f, 0.0727539f, -0.401855f, 0.0727539f, -0.408203f, 0.0759277f,
+-0.41333f, 0.0791016f, -0.418457f, 0.0842285f, -0.420654f, 0.0893555f, -0.422852f,
+0.100098f, -0.422852f, 0.212402f, -0.422852f, 0.227051f, -0.422852f, 0.233398f, -0.416992f,
+0.239746f, -0.411133f, 0.239746f, -0.401855f, 0.239746f, -0.393066f, 0.233398f, -0.387207f,
+0.227051f, -0.381348f, 0.212402f, -0.381348f, 0.157227f, -0.381348f, 0.324707f, -0.0449219f,
+0.489746f, -0.381348f, 0.43457f, -0.381348f, 0.419922f, -0.381348f, 0.413574f, -0.387207f,
+0.407227f, -0.393066f, 0.407227f, -0.402344f, 0.407227f, -0.411133f, 0.413574f, -0.416992f,
+0.419922f, -0.422852f, 0.43457f, -0.422852f, 0.546387f, -0.422852f, 0.561523f, -0.422852f,
+0.567871f, -0.416992f, 0.574219f, -0.411133f, 0.574219f, -0.401855f, 0.574219f, -0.395508f,
+0.570312f, -0.390137f, 0.566406f, -0.384766f, 0.561523f, -0.383057f, 0.556641f, -0.381348f,
+0.53418f, -0.381348f, 0.274414f, 0.147461f, 0.338379f, 0.147461f, 0.353027f, 0.147461f,
+0.359375f, 0.153076f, 0.365723f, 0.158691f, 0.365723f, 0.167969f, 0.365723f, 0.176758f,
+0.359375f, 0.182617f, 0.353027f, 0.188477f, 0.338379f, 0.188477f, 0.102051f, 0.188477f,
+0.0874023f, 0.188477f, 0.0810547f, 0.182861f, 0.074707f, 0.177246f, 0.074707f, 0.167969f,
+0.074707f, 0.158691f, 0.0810547f, 0.153076f, 0.0874023f, 0.147461f, 0.102051f, 0.147461f,
+0.230469f, 0.147461f
+};
+
+const unsigned char CourierNewkNormalVerbs[] = {
+6, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5,
+6, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2,
+5, 6, 0, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 0, 1, 1, 1,
+5, 6, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1,
+2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+1, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 1,
+1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+6, 0, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 5, 0, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 0, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2,
+1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2,
+2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 5, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1,
+1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5,
+6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2,
+2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6,
+0, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2,
+1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2,
+2, 2, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2,
+2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2,
+2, 2, 5, 6, 0, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1,
+1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6
+};
+
+const unsigned CourierNewkNormalCharCodes[] = {
+32, 33, 47, 60, 62,
+65, 67, 72, 77, 84, 87, 89, 97, 98, 99, 100, 101, 102, 103, 105, 108, 109, 110,
+111, 112, 114, 115, 116, 117, 121
+};
+
+const SkFixed CourierNewkNormalWidths[] = {
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0
+};
+
+const int CourierNewkNormalCharCodesCount = (int) SK_ARRAY_COUNT(CourierNewkNormalCharCodes);
+
+const SkPaint::FontMetrics CourierNewkNormalMetrics = {
+0x00000003, -1.021f, -0.83252f, 0.300293f, 0.679688f, 0, 0.744141f, 0, -0.121582f,
+0.622559f, 0.437988f, 0, 0.0410156f, 0.23291f
+};
+
+const SkScalar CourierNewkBoldPoints[] = {
+0.422363f, -0.161133f, 0.179199f, -0.161133f, 0.154785f, -0.100098f, 0.179199f, -0.100098f,
+0.215332f, -0.100098f, 0.230713f, -0.0861816f, 0.246094f, -0.0722656f, 0.246094f,
+-0.0498047f, 0.246094f, -0.027832f, 0.230713f, -0.013916f, 0.215332f, 0, 0.179199f,
+0, 0.0444336f, 0, 0.00830078f, 0, -0.00708008f, -0.013916f, -0.0224609f, -0.027832f,
+-0.0224609f, -0.050293f, -0.0224609f, -0.0727539f, -0.00634766f, -0.0869141f, 0.00976562f,
+-0.101074f, 0.046875f, -0.100098f, 0.204102f, -0.491699f, 0.138672f, -0.491699f,
+0.102539f, -0.491699f, 0.0871582f, -0.505615f, 0.0717773f, -0.519531f, 0.0717773f,
+-0.541992f, 0.0717773f, -0.564453f, 0.0871582f, -0.578369f, 0.102539f, -0.592285f,
+0.138672f, -0.592285f, 0.35498f, -0.591797f, 0.554199f, -0.100098f, 0.589355f, -0.100098f,
+0.600586f, -0.0922852f, 0.623047f, -0.0761719f, 0.623047f, -0.0498047f, 0.623047f,
+-0.027832f, 0.60791f, -0.013916f, 0.592773f, 0, 0.556641f, 0, 0.421875f, 0, 0.385742f,
+0, 0.370361f, -0.013916f, 0.35498f, -0.027832f, 0.35498f, -0.050293f, 0.35498f, -0.0722656f,
+0.370361f, -0.0861816f, 0.385742f, -0.100098f, 0.421875f, -0.100098f, 0.446289f,
+-0.100098f, 0.380859f, -0.26123f, 0.300293f, -0.459473f, 0.219238f, -0.26123f, 0.409668f,
+-0.245117f, 0.195801f, -0.245117f, 0.195801f, -0.100098f, 0.211426f, -0.100098f,
+0.247559f, -0.100098f, 0.262939f, -0.0861816f, 0.27832f, -0.0722656f, 0.27832f, -0.0498047f,
+0.27832f, -0.027832f, 0.262939f, -0.013916f, 0.247559f, 0, 0.211426f, 0, 0.0888672f,
+0, 0.0527344f, 0, 0.0373535f, -0.013916f, 0.0219727f, -0.027832f, 0.0219727f, -0.050293f,
+0.0219727f, -0.0776367f, 0.0458984f, -0.0927734f, 0.0576172f, -0.100586f, 0.0957031f,
+-0.100098f, 0.0957031f, -0.491699f, 0.0693359f, -0.494141f, 0.0559082f, -0.507812f,
+0.0424805f, -0.521484f, 0.0424805f, -0.541992f, 0.0424805f, -0.564453f, 0.0578613f,
+-0.578369f, 0.0732422f, -0.592285f, 0.109375f, -0.592285f, 0.211426f, -0.591797f,
+0.247559f, -0.591797f, 0.262939f, -0.578125f, 0.27832f, -0.564453f, 0.27832f, -0.541992f,
+0.27832f, -0.519531f, 0.262939f, -0.505615f, 0.247559f, -0.491699f, 0.211426f, -0.491699f,
+0.195801f, -0.491699f, 0.195801f, -0.345215f, 0.409668f, -0.345215f, 0.409668f, -0.491699f,
+0.394043f, -0.491699f, 0.35791f, -0.491699f, 0.342529f, -0.505615f, 0.327148f, -0.519531f,
+0.327148f, -0.541992f, 0.327148f, -0.564453f, 0.342529f, -0.578369f, 0.35791f, -0.592285f,
+0.394043f, -0.592285f, 0.496094f, -0.591797f, 0.532227f, -0.591797f, 0.547607f, -0.578125f,
+0.562988f, -0.564453f, 0.562988f, -0.541992f, 0.562988f, -0.521484f, 0.549561f, -0.507812f,
+0.536133f, -0.494141f, 0.509766f, -0.491699f, 0.509766f, -0.100098f, 0.54834f, -0.100098f,
+0.55957f, -0.0927734f, 0.583496f, -0.0776367f, 0.583496f, -0.0498047f, 0.583496f,
+-0.027832f, 0.568115f, -0.013916f, 0.552734f, 0, 0.516602f, 0, 0.394043f, 0, 0.35791f,
+0, 0.342529f, -0.013916f, 0.327148f, -0.027832f, 0.327148f, -0.050293f, 0.327148f,
+-0.0722656f, 0.342773f, -0.0861816f, 0.358398f, -0.100098f, 0.394043f, -0.100098f,
+0.409668f, -0.100098f, 0.348633f, -0.491699f, 0.348633f, -0.100098f, 0.416016f, -0.100098f,
+0.452148f, -0.100098f, 0.467529f, -0.0861816f, 0.48291f, -0.0722656f, 0.48291f, -0.0498047f,
+0.48291f, -0.027832f, 0.467529f, -0.013916f, 0.452148f, 0, 0.416016f, 0, 0.181641f,
+0, 0.145508f, 0, 0.130127f, -0.013916f, 0.114746f, -0.027832f, 0.114746f, -0.050293f,
+0.114746f, -0.0722656f, 0.130127f, -0.0861816f, 0.145508f, -0.100098f, 0.181641f,
+-0.100098f, 0.248535f, -0.100098f, 0.248535f, -0.491699f, 0.140137f, -0.491699f,
+0.140137f, -0.396973f, 0.140137f, -0.36084f, 0.126221f, -0.345459f, 0.112305f, -0.330078f,
+0.0898438f, -0.330078f, 0.0678711f, -0.330078f, 0.0539551f, -0.345459f, 0.0400391f,
+-0.36084f, 0.0400391f, -0.396973f, 0.0400391f, -0.592285f, 0.558594f, -0.591797f,
+0.558594f, -0.396973f, 0.558594f, -0.36084f, 0.544678f, -0.345459f, 0.530762f, -0.330078f,
+0.508301f, -0.330078f, 0.486328f, -0.330078f, 0.472412f, -0.345459f, 0.458496f, -0.36084f,
+0.458496f, -0.396973f, 0.458496f, -0.491699f, 0.300293f, -0.28418f, 0.20752f, 0,
+0.0952148f, 0, 0.0356445f, -0.491699f, 0.0126953f, -0.494629f, 0.000976562f, -0.507568f,
+-0.0107422f, -0.520508f, -0.0107422f, -0.540527f, -0.0107422f, -0.563965f, 0.00463867f,
+-0.578125f, 0.0200195f, -0.592285f, 0.0561523f, -0.592285f, 0.189453f, -0.591797f,
+0.225586f, -0.591797f, 0.240967f, -0.578125f, 0.256348f, -0.564453f, 0.256348f, -0.541992f,
+0.256348f, -0.519531f, 0.240967f, -0.505615f, 0.225586f, -0.491699f, 0.189453f, -0.491699f,
+0.137207f, -0.491699f, 0.17041f, -0.211914f, 0.249023f, -0.444824f, 0.353027f, -0.444824f,
+0.431152f, -0.211914f, 0.464355f, -0.491699f, 0.412109f, -0.491699f, 0.375977f, -0.491699f,
+0.360596f, -0.505615f, 0.345215f, -0.519531f, 0.345215f, -0.541992f, 0.345215f, -0.564453f,
+0.360596f, -0.578369f, 0.375977f, -0.592285f, 0.412109f, -0.592285f, 0.544922f, -0.591797f,
+0.581055f, -0.591797f, 0.596436f, -0.578125f, 0.611816f, -0.564453f, 0.611816f, -0.541992f,
+0.611816f, -0.522949f, 0.599609f, -0.509277f, 0.587402f, -0.495605f, 0.564453f, -0.491699f,
+0.506836f, 0, 0.396484f, 0, 0.350586f, -0.248535f, 0.350586f, -0.100098f, 0.417969f,
+-0.100098f, 0.454102f, -0.100098f, 0.469482f, -0.0861816f, 0.484863f, -0.0722656f,
+0.484863f, -0.0498047f, 0.484863f, -0.027832f, 0.469482f, -0.013916f, 0.454102f,
+0, 0.417969f, 0, 0.183105f, 0, 0.147461f, 0, 0.13208f, -0.013916f, 0.116699f, -0.027832f,
+0.116699f, -0.050293f, 0.116699f, -0.0722656f, 0.13208f, -0.0861816f, 0.147461f,
+-0.100098f, 0.183105f, -0.100098f, 0.250488f, -0.100098f, 0.250488f, -0.248535f,
+0.0849609f, -0.491699f, 0.0517578f, -0.491699f, 0.036377f, -0.505859f, 0.0209961f,
+-0.52002f, 0.0209961f, -0.541992f, 0.0209961f, -0.564453f, 0.036377f, -0.578369f,
+0.0517578f, -0.592285f, 0.0878906f, -0.592285f, 0.178711f, -0.591797f, 0.214844f,
+-0.591797f, 0.230225f, -0.578125f, 0.245605f, -0.564453f, 0.245605f, -0.541992f,
+0.245605f, -0.508301f, 0.206055f, -0.491699f, 0.300781f, -0.352051f, 0.393555f, -0.491699f,
+0.371582f, -0.5f, 0.362305f, -0.512695f, 0.353027f, -0.525391f, 0.353027f, -0.541992f,
+0.353027f, -0.564453f, 0.368408f, -0.578125f, 0.383789f, -0.591797f, 0.419922f, -0.592285f,
+0.51416f, -0.591797f, 0.550293f, -0.591797f, 0.565674f, -0.578125f, 0.581055f, -0.564453f,
+0.581055f, -0.541992f, 0.581055f, -0.519531f, 0.56543f, -0.505615f, 0.549805f, -0.491699f,
+0.514648f, -0.491699f, 0.390137f, 0, 0.390137f, -0.0234375f, 0.352539f, -0.00341797f,
+0.307129f, 0.0065918f, 0.261719f, 0.0166016f, 0.224609f, 0.0166016f, 0.144043f, 0.0166016f,
+0.09375f, -0.026123f, 0.043457f, -0.0688477f, 0.043457f, -0.120605f, 0.043457f, -0.183594f,
+0.107666f, -0.237549f, 0.171875f, -0.291504f, 0.285156f, -0.291504f, 0.330566f, -0.291504f,
+0.390137f, -0.281738f, 0.390137f, -0.305664f, 0.390137f, -0.328125f, 0.37085f, -0.342285f,
+0.351562f, -0.356445f, 0.297363f, -0.356445f, 0.25293f, -0.356445f, 0.182129f, -0.338867f,
+0.155762f, -0.33252f, 0.141113f, -0.33252f, 0.121094f, -0.33252f, 0.107178f, -0.346924f,
+0.0932617f, -0.361328f, 0.0932617f, -0.383789f, 0.0932617f, -0.396484f, 0.0981445f,
+-0.405762f, 0.103027f, -0.415039f, 0.111816f, -0.420654f, 0.120605f, -0.42627f, 0.148438f,
+-0.434082f, 0.185547f, -0.444336f, 0.224121f, -0.450439f, 0.262695f, -0.456543f,
+0.293945f, -0.456543f, 0.387207f, -0.456543f, 0.438721f, -0.41626f, 0.490234f, -0.375977f,
+0.490234f, -0.306152f, 0.490234f, -0.100098f, 0.507324f, -0.100098f, 0.543457f, -0.100098f,
+0.558838f, -0.0861816f, 0.574219f, -0.0722656f, 0.574219f, -0.0498047f, 0.574219f,
+-0.027832f, 0.558838f, -0.013916f, 0.543457f, 0, 0.507324f, 0, 0.390137f, -0.179199f,
+0.330078f, -0.190918f, 0.279297f, -0.190918f, 0.218262f, -0.190918f, 0.174316f, -0.161133f,
+0.146973f, -0.14209f, 0.146973f, -0.122559f, 0.146973f, -0.108398f, 0.160156f, -0.0996094f,
+0.18457f, -0.0834961f, 0.227051f, -0.0834961f, 0.263184f, -0.0834961f, 0.308838f,
+-0.0976562f, 0.354492f, -0.111816f, 0.390137f, -0.13623f, 0.173828f, -0.633301f,
+0.173828f, -0.408691f, 0.210449f, -0.432617f, 0.248291f, -0.44458f, 0.286133f, -0.456543f,
+0.324707f, -0.456543f, 0.428711f, -0.456543f, 0.500977f, -0.384766f, 0.573242f, -0.312988f,
+0.573242f, -0.211426f, 0.573242f, -0.114258f, 0.504395f, -0.0490723f, 0.435547f,
+0.0161133f, 0.322754f, 0.0161133f, 0.282715f, 0.0161133f, 0.245605f, 0.00585938f,
+0.208496f, -0.00439453f, 0.173828f, -0.0244141f, 0.173828f, 0, 0.0566406f, 0, 0.0205078f,
+0, 0.00512695f, -0.013916f, -0.0102539f, -0.027832f, -0.0102539f, -0.050293f, -0.0102539f,
+-0.0722656f, 0.00537109f, -0.0861816f, 0.0209961f, -0.100098f, 0.0566406f, -0.100098f,
+0.0737305f, -0.100098f, 0.0737305f, -0.533203f, 0.0566406f, -0.533203f, 0.0205078f,
+-0.533203f, 0.00512695f, -0.547119f, -0.0102539f, -0.561035f, -0.0102539f, -0.583496f,
+-0.0102539f, -0.605469f, 0.00512695f, -0.619385f, 0.0205078f, -0.633301f, 0.0566406f,
+-0.633301f, 0.473145f, -0.208496f, 0.473145f, -0.270508f, 0.429688f, -0.313477f,
+0.38623f, -0.356445f, 0.323242f, -0.356445f, 0.260742f, -0.356445f, 0.217285f, -0.313477f,
+0.173828f, -0.270508f, 0.173828f, -0.209961f, 0.173828f, -0.154785f, 0.212891f, -0.119385f,
+0.251953f, -0.0839844f, 0.323242f, -0.0839844f, 0.394531f, -0.0839844f, 0.433838f,
+-0.119385f, 0.473145f, -0.154785f, 0.473145f, -0.208496f, 0.55127f, -0.170898f, 0.140625f,
+-0.170898f, 0.15625f, -0.131836f, 0.196045f, -0.10791f, 0.23584f, -0.0839844f, 0.303711f,
+-0.0839844f, 0.359375f, -0.0839844f, 0.45166f, -0.10791f, 0.489746f, -0.117676f,
+0.504395f, -0.117676f, 0.524414f, -0.117676f, 0.538086f, -0.103516f, 0.551758f, -0.0893555f,
+0.551758f, -0.0678711f, 0.551758f, -0.0483398f, 0.537109f, -0.034668f, 0.517578f,
+-0.0166016f, 0.441895f, -0.000244141f, 0.366211f, 0.0161133f, 0.296387f, 0.0161133f,
+0.17627f, 0.0161133f, 0.104248f, -0.0517578f, 0.0322266f, -0.119629f, 0.0322266f,
+-0.21875f, 0.0322266f, -0.324219f, 0.110107f, -0.390381f, 0.187988f, -0.456543f,
+0.289551f, -0.456543f, 0.350586f, -0.456543f, 0.401611f, -0.435059f, 0.452637f, -0.413574f,
+0.477539f, -0.388672f, 0.512695f, -0.352539f, 0.535645f, -0.299316f, 0.55127f, -0.262207f,
+0.55127f, -0.213379f, 0.44043f, -0.270996f, 0.41748f, -0.313965f, 0.380371f, -0.335205f,
+0.343262f, -0.356445f, 0.291992f, -0.356445f, 0.241211f, -0.356445f, 0.204102f, -0.335205f,
+0.166992f, -0.313965f, 0.143555f, -0.270996f, 0.299316f, -0.343262f, 0.299316f, -0.100098f,
+0.441895f, -0.100098f, 0.478027f, -0.100098f, 0.493408f, -0.0861816f, 0.508789f,
+-0.0722656f, 0.508789f, -0.0498047f, 0.508789f, -0.027832f, 0.493408f, -0.013916f,
+0.478027f, 0, 0.441895f, 0, 0.139648f, 0, 0.103516f, 0, 0.0881348f, -0.013916f, 0.0727539f,
+-0.027832f, 0.0727539f, -0.050293f, 0.0727539f, -0.0722656f, 0.0881348f, -0.0861816f,
+0.103516f, -0.100098f, 0.139648f, -0.100098f, 0.199219f, -0.100098f, 0.199219f, -0.343262f,
+0.151367f, -0.343262f, 0.115234f, -0.343262f, 0.0998535f, -0.357178f, 0.0844727f,
+-0.371094f, 0.0844727f, -0.393555f, 0.0844727f, -0.415527f, 0.0998535f, -0.429443f,
+0.115234f, -0.443359f, 0.151367f, -0.443359f, 0.199219f, -0.443359f, 0.199219f, -0.481445f,
+0.199219f, -0.546875f, 0.248291f, -0.590088f, 0.297363f, -0.633301f, 0.390625f, -0.633301f,
+0.432129f, -0.633301f, 0.486572f, -0.625732f, 0.541016f, -0.618164f, 0.556396f, -0.604492f,
+0.571777f, -0.59082f, 0.571777f, -0.569336f, 0.571777f, -0.546387f, 0.558105f, -0.531982f,
+0.544434f, -0.517578f, 0.524414f, -0.517578f, 0.515137f, -0.517578f, 0.496582f, -0.520996f,
+0.43457f, -0.533203f, 0.386719f, -0.533203f, 0.336914f, -0.533203f, 0.318115f, -0.518311f,
+0.299316f, -0.503418f, 0.299316f, -0.481445f, 0.299316f, -0.443359f, 0.453613f, -0.443359f,
+0.489746f, -0.443359f, 0.505127f, -0.429443f, 0.520508f, -0.415527f, 0.520508f, -0.393066f,
+0.520508f, -0.371094f, 0.505127f, -0.357178f, 0.489746f, -0.343262f, 0.453613f, -0.343262f,
+0.410156f, -0.413574f, 0.410156f, -0.443359f, 0.527344f, -0.443359f, 0.563477f, -0.443359f,
+0.578857f, -0.429443f, 0.594238f, -0.415527f, 0.594238f, -0.393066f, 0.594238f, -0.371094f,
+0.578857f, -0.357178f, 0.563477f, -0.343262f, 0.527344f, -0.343262f, 0.510254f, -0.343262f,
+0.510254f, 0.0209961f, 0.510254f, 0.0737305f, 0.488037f, 0.113037f, 0.46582f, 0.152344f,
+0.419922f, 0.180664f, 0.374023f, 0.208984f, 0.316406f, 0.208984f, 0.203125f, 0.208984f,
+0.166992f, 0.208984f, 0.151611f, 0.195068f, 0.13623f, 0.181152f, 0.13623f, 0.15918f,
+0.13623f, 0.136719f, 0.151611f, 0.122803f, 0.166992f, 0.108887f, 0.203125f, 0.108887f,
+0.313477f, 0.108887f, 0.359375f, 0.108887f, 0.384766f, 0.0839844f, 0.410156f, 0.059082f,
+0.410156f, 0.0209961f, 0.410156f, -0.027832f, 0.376953f, -0.00634766f, 0.342529f,
+0.00439453f, 0.308105f, 0.0151367f, 0.271973f, 0.0151367f, 0.169922f, 0.0151367f,
+0.101074f, -0.0529785f, 0.0322266f, -0.121094f, 0.0322266f, -0.221191f, 0.0322266f,
+-0.321777f, 0.101074f, -0.389893f, 0.169922f, -0.458008f, 0.271973f, -0.458008f,
+0.310059f, -0.458008f, 0.344482f, -0.447021f, 0.378906f, -0.436035f, 0.410156f, -0.413574f,
+0.409668f, -0.22168f, 0.409668f, -0.276855f, 0.368896f, -0.317383f, 0.328125f, -0.35791f,
+0.270996f, -0.35791f, 0.213867f, -0.35791f, 0.173096f, -0.317383f, 0.132324f, -0.276855f,
+0.132324f, -0.22168f, 0.132324f, -0.166016f, 0.173096f, -0.125732f, 0.213867f, -0.0854492f,
+0.270996f, -0.0854492f, 0.328125f, -0.0854492f, 0.368896f, -0.125732f, 0.409668f,
+-0.166016f, 0.409668f, -0.22168f, 0.145508f, -0.443359f, 0.145508f, -0.415039f, 0.169922f,
+-0.438965f, 0.189697f, -0.447998f, 0.209473f, -0.457031f, 0.235352f, -0.457031f,
+0.257324f, -0.457031f, 0.278809f, -0.446289f, 0.300293f, -0.435547f, 0.320801f, -0.414062f,
+0.34668f, -0.435547f, 0.373291f, -0.446045f, 0.399902f, -0.456543f, 0.427734f, -0.456543f,
+0.483398f, -0.456543f, 0.518066f, -0.426758f, 0.563965f, -0.387695f, 0.563965f, -0.324219f,
+0.563965f, -0.100098f, 0.595215f, -0.100098f, 0.610352f, -0.0859375f, 0.625488f,
+-0.0717773f, 0.625488f, -0.0498047f, 0.625488f, -0.027832f, 0.610352f, -0.013916f,
+0.595215f, 0, 0.559082f, 0, 0.463867f, 0, 0.463867f, -0.315918f, 0.463867f, -0.338867f,
+0.455566f, -0.347656f, 0.447266f, -0.356445f, 0.430176f, -0.356445f, 0.413574f, -0.356445f,
+0.399414f, -0.347656f, 0.381348f, -0.335449f, 0.355469f, -0.301758f, 0.355469f, -0.100098f,
+0.386719f, -0.100098f, 0.401855f, -0.0859375f, 0.416992f, -0.0717773f, 0.416992f,
+-0.0498047f, 0.416992f, -0.027832f, 0.401855f, -0.013916f, 0.386719f, 0, 0.350586f,
+0, 0.255371f, 0, 0.255371f, -0.315918f, 0.255371f, -0.338379f, 0.246826f, -0.347412f,
+0.238281f, -0.356445f, 0.221191f, -0.356445f, 0.203613f, -0.356445f, 0.186523f, -0.345459f,
+0.169434f, -0.334473f, 0.145508f, -0.301758f, 0.145508f, -0.100098f, 0.176758f, -0.100098f,
+0.192139f, -0.0859375f, 0.20752f, -0.0717773f, 0.20752f, -0.0498047f, 0.20752f, -0.027832f,
+0.192139f, -0.013916f, 0.176758f, 0, 0.140625f, 0, 0.050293f, 0, 0.0141602f, 0, -0.0012207f,
+-0.013916f, -0.0166016f, -0.027832f, -0.0166016f, -0.050293f, -0.0166016f, -0.0722656f,
+-0.00146484f, -0.0861816f, 0.0136719f, -0.100098f, 0.0454102f, -0.100098f, 0.0454102f,
+-0.343262f, 0.0136719f, -0.343262f, -0.00146484f, -0.357422f, -0.0166016f, -0.371582f,
+-0.0166016f, -0.393555f, -0.0166016f, -0.415527f, -0.0012207f, -0.429443f, 0.0141602f,
+-0.443359f, 0.050293f, -0.443359f, 0.19873f, -0.443359f, 0.19873f, -0.409668f, 0.226074f,
+-0.433105f, 0.259033f, -0.444824f, 0.291992f, -0.456543f, 0.330566f, -0.456543f,
+0.419434f, -0.456543f, 0.471191f, -0.401367f, 0.512207f, -0.357422f, 0.512207f, -0.286133f,
+0.512207f, -0.100098f, 0.543945f, -0.100098f, 0.559082f, -0.0861816f, 0.574219f,
+-0.0722656f, 0.574219f, -0.0498047f, 0.574219f, -0.027832f, 0.558838f, -0.013916f,
+0.543457f, 0, 0.507324f, 0, 0.416992f, 0, 0.380859f, 0, 0.365479f, -0.013916f, 0.350098f,
+-0.027832f, 0.350098f, -0.050293f, 0.350098f, -0.0722656f, 0.365234f, -0.0861816f,
+0.380371f, -0.100098f, 0.412109f, -0.100098f, 0.412109f, -0.289062f, 0.412109f, -0.321777f,
+0.394531f, -0.336914f, 0.371582f, -0.356445f, 0.325684f, -0.356445f, 0.291016f, -0.356445f,
+0.264893f, -0.343018f, 0.23877f, -0.32959f, 0.19873f, -0.286133f, 0.19873f, -0.100098f,
+0.237305f, -0.100098f, 0.248535f, -0.0927734f, 0.272461f, -0.078125f, 0.272461f,
+-0.0498047f, 0.272461f, -0.027832f, 0.25708f, -0.013916f, 0.241699f, 0, 0.205566f,
+0, 0.0917969f, 0, 0.0556641f, 0, 0.0402832f, -0.013916f, 0.0249023f, -0.027832f,
+0.0249023f, -0.050293f, 0.0249023f, -0.0776367f, 0.0483398f, -0.0927734f, 0.0600586f,
+-0.100098f, 0.0986328f, -0.100098f, 0.0986328f, -0.343262f, 0.0668945f, -0.343262f,
+0.0517578f, -0.357422f, 0.0366211f, -0.371582f, 0.0366211f, -0.393555f, 0.0366211f,
+-0.415527f, 0.052002f, -0.429443f, 0.0673828f, -0.443359f, 0.103516f, -0.443359f,
+0.560059f, -0.213379f, 0.560059f, -0.155762f, 0.528076f, -0.101807f, 0.496094f, -0.0478516f,
+0.432861f, -0.0158691f, 0.369629f, 0.0161133f, 0.300781f, 0.0161133f, 0.232422f,
+0.0161133f, 0.169922f, -0.0153809f, 0.107422f, -0.046875f, 0.074707f, -0.101074f,
+0.0419922f, -0.155273f, 0.0419922f, -0.214355f, 0.0419922f, -0.274414f, 0.0751953f,
+-0.332275f, 0.108398f, -0.390137f, 0.170654f, -0.42334f, 0.23291f, -0.456543f, 0.300781f,
+-0.456543f, 0.369141f, -0.456543f, 0.432373f, -0.422607f, 0.495605f, -0.388672f,
+0.527832f, -0.331299f, 0.560059f, -0.273926f, 0.560059f, -0.213379f, 0.459961f, -0.212891f,
+0.459961f, -0.26123f, 0.425293f, -0.301758f, 0.37793f, -0.356445f, 0.300781f, -0.356445f,
+0.23291f, -0.356445f, 0.1875f, -0.312988f, 0.14209f, -0.269531f, 0.14209f, -0.212402f,
+0.14209f, -0.165527f, 0.187988f, -0.124756f, 0.233887f, -0.0839844f, 0.300781f, -0.0839844f,
+0.368164f, -0.0839844f, 0.414062f, -0.124756f, 0.459961f, -0.165527f, 0.459961f,
+-0.212891f, 0.175781f, -0.0551758f, 0.175781f, 0.108887f, 0.23584f, 0.108887f, 0.271973f,
+0.108887f, 0.287354f, 0.122803f, 0.302734f, 0.136719f, 0.302734f, 0.15918f, 0.302734f,
+0.181152f, 0.287354f, 0.195068f, 0.271973f, 0.208984f, 0.23584f, 0.208984f, 0.0585938f,
+0.208984f, 0.0224609f, 0.208984f, 0.00708008f, 0.195068f, -0.00830078f, 0.181152f,
+-0.00830078f, 0.15918f, -0.00830078f, 0.136719f, 0.00732422f, 0.122803f, 0.0229492f,
+0.108887f, 0.0585938f, 0.108887f, 0.0756836f, 0.108887f, 0.0756836f, -0.343262f,
+0.0585938f, -0.343262f, 0.0224609f, -0.343262f, 0.00708008f, -0.357178f, -0.00830078f,
+-0.371094f, -0.00830078f, -0.393555f, -0.00830078f, -0.415527f, 0.00708008f, -0.429443f,
+0.0224609f, -0.443359f, 0.0585938f, -0.443359f, 0.175781f, -0.443359f, 0.175781f,
+-0.40918f, 0.210938f, -0.433105f, 0.248535f, -0.444824f, 0.286133f, -0.456543f, 0.325684f,
+-0.456543f, 0.428223f, -0.456543f, 0.500488f, -0.386963f, 0.572754f, -0.317383f,
+0.572754f, -0.227539f, 0.572754f, -0.128418f, 0.487305f, -0.0639648f, 0.416016f,
+-0.0102539f, 0.32666f, -0.0102539f, 0.288086f, -0.0102539f, 0.250488f, -0.0214844f,
+0.212891f, -0.0327148f, 0.175781f, -0.0551758f, 0.472656f, -0.227051f, 0.472656f,
+-0.248047f, 0.456055f, -0.280518f, 0.439453f, -0.312988f, 0.405029f, -0.334717f,
+0.370605f, -0.356445f, 0.324219f, -0.356445f, 0.249512f, -0.356445f, 0.205566f, -0.300293f,
+0.175781f, -0.261719f, 0.175781f, -0.226074f, 0.175781f, -0.186035f, 0.218506f, -0.148193f,
+0.26123f, -0.110352f, 0.324219f, -0.110352f, 0.387695f, -0.110352f, 0.430176f, -0.147949f,
+0.472656f, -0.185547f, 0.472656f, -0.227051f, 0.279297f, -0.443359f, 0.279297f, -0.380859f,
+0.342285f, -0.42627f, 0.378662f, -0.441406f, 0.415039f, -0.456543f, 0.446777f, -0.456543f,
+0.495605f, -0.456543f, 0.541504f, -0.42041f, 0.572754f, -0.395996f, 0.572754f, -0.370605f,
+0.572754f, -0.349121f, 0.557861f, -0.334229f, 0.542969f, -0.319336f, 0.521973f, -0.319336f,
+0.503418f, -0.319336f, 0.48291f, -0.337891f, 0.462402f, -0.356445f, 0.446289f, -0.356445f,
+0.425293f, -0.356445f, 0.383545f, -0.330078f, 0.341797f, -0.303711f, 0.279297f, -0.250977f,
+0.279297f, -0.100098f, 0.421875f, -0.100098f, 0.458008f, -0.100098f, 0.473389f, -0.0861816f,
+0.48877f, -0.0722656f, 0.48877f, -0.0498047f, 0.48877f, -0.027832f, 0.473389f, -0.013916f,
+0.458008f, 0, 0.421875f, 0, 0.119629f, 0, 0.0834961f, 0, 0.0681152f, -0.013916f,
+0.0527344f, -0.027832f, 0.0527344f, -0.050293f, 0.0527344f, -0.0722656f, 0.0681152f,
+-0.0861816f, 0.0834961f, -0.100098f, 0.119629f, -0.100098f, 0.179199f, -0.100098f,
+0.179199f, -0.343262f, 0.143066f, -0.343262f, 0.106934f, -0.343262f, 0.0915527f,
+-0.357178f, 0.0761719f, -0.371094f, 0.0761719f, -0.393555f, 0.0761719f, -0.415527f,
+0.0915527f, -0.429443f, 0.106934f, -0.443359f, 0.143066f, -0.443359f, 0.408203f,
+-0.326172f, 0.383789f, -0.341309f, 0.356934f, -0.348877f, 0.330078f, -0.356445f,
+0.300781f, -0.356445f, 0.242676f, -0.356445f, 0.208496f, -0.337402f, 0.193359f, -0.329102f,
+0.193359f, -0.319336f, 0.193359f, -0.308105f, 0.213867f, -0.297363f, 0.229492f, -0.289551f,
+0.283691f, -0.282227f, 0.383301f, -0.268555f, 0.422363f, -0.254883f, 0.473633f, -0.236816f,
+0.501465f, -0.201172f, 0.529297f, -0.165527f, 0.529297f, -0.125977f, 0.529297f, -0.0722656f,
+0.481934f, -0.0361328f, 0.414062f, 0.0161133f, 0.305664f, 0.0161133f, 0.262207f,
+0.0161133f, 0.225342f, 0.00854492f, 0.188477f, 0.000976562f, 0.157715f, -0.0136719f,
+0.150391f, -0.00732422f, 0.14209f, -0.00390625f, 0.133789f, -0.000488281f, 0.125f,
+-0.000488281f, 0.101562f, -0.000488281f, 0.0876465f, -0.0158691f, 0.0737305f, -0.03125f,
+0.0737305f, -0.0673828f, 0.0737305f, -0.101074f, 0.0737305f, -0.137207f, 0.0876465f,
+-0.152588f, 0.101562f, -0.167969f, 0.124023f, -0.167969f, 0.14209f, -0.167969f, 0.154297f,
+-0.157959f, 0.166504f, -0.147949f, 0.17334f, -0.123535f, 0.196289f, -0.104004f, 0.228516f,
+-0.0939941f, 0.260742f, -0.0839844f, 0.302734f, -0.0839844f, 0.371582f, -0.0839844f,
+0.409668f, -0.105469f, 0.427734f, -0.116211f, 0.427734f, -0.12793f, 0.427734f, -0.147461f,
+0.401855f, -0.160156f, 0.375977f, -0.172852f, 0.294922f, -0.181641f, 0.174316f, -0.194336f,
+0.133789f, -0.230469f, 0.0932617f, -0.266113f, 0.0932617f, -0.318359f, 0.0932617f,
+-0.37207f, 0.138672f, -0.407715f, 0.200195f, -0.456543f, 0.299805f, -0.456543f, 0.334473f,
+-0.456543f, 0.366455f, -0.449951f, 0.398438f, -0.443359f, 0.427734f, -0.429688f,
+0.437012f, -0.436523f, 0.445068f, -0.439941f, 0.453125f, -0.443359f, 0.459961f, -0.443359f,
+0.480469f, -0.443359f, 0.494141f, -0.427979f, 0.507812f, -0.412598f, 0.507812f, -0.376465f,
+0.507812f, -0.352051f, 0.507812f, -0.319336f, 0.5f, -0.307617f, 0.484375f, -0.285156f,
+0.45752f, -0.285156f, 0.439453f, -0.285156f, 0.425781f, -0.296387f, 0.412109f, -0.307617f,
+0.408203f, -0.326172f, 0.512695f, -0.443359f, 0.512695f, -0.100098f, 0.544434f, -0.100098f,
+0.55957f, -0.0859375f, 0.574707f, -0.0717773f, 0.574707f, -0.0498047f, 0.574707f,
+-0.027832f, 0.559326f, -0.013916f, 0.543945f, 0, 0.507812f, 0, 0.412598f, 0, 0.412598f,
+-0.0229492f, 0.369629f, -0.00341797f, 0.330566f, 0.00634766f, 0.291504f, 0.0161133f,
+0.256348f, 0.0161133f, 0.207031f, 0.0161133f, 0.170898f, -0.00463867f, 0.134766f,
+-0.0253906f, 0.11377f, -0.0620117f, 0.0986328f, -0.0883789f, 0.0986328f, -0.12793f,
+0.0986328f, -0.343262f, 0.081543f, -0.343262f, 0.0454102f, -0.343262f, 0.0300293f,
+-0.357178f, 0.0146484f, -0.371094f, 0.0146484f, -0.393555f, 0.0146484f, -0.415527f,
+0.0300293f, -0.429443f, 0.0454102f, -0.443359f, 0.081543f, -0.443359f, 0.19873f,
+-0.443359f, 0.19873f, -0.145508f, 0.19873f, -0.11377f, 0.214111f, -0.098877f, 0.229492f,
+-0.0839844f, 0.26123f, -0.0839844f, 0.291504f, -0.0839844f, 0.326416f, -0.0959473f,
+0.361328f, -0.10791f, 0.412598f, -0.13916f, 0.412598f, -0.343262f, 0.376465f, -0.343262f,
+0.340332f, -0.343262f, 0.324951f, -0.357178f, 0.30957f, -0.371094f, 0.30957f, -0.393555f,
+0.30957f, -0.415527f, 0.324951f, -0.429443f, 0.340332f, -0.443359f, 0.376465f, -0.443359f,
+0.244141f, -0.00341797f, 0.0708008f, -0.343262f, 0.0463867f, -0.346191f, 0.0336914f,
+-0.359863f, 0.0209961f, -0.373535f, 0.0209961f, -0.393066f, 0.0209961f, -0.415527f,
+0.036377f, -0.429443f, 0.0517578f, -0.443359f, 0.0878906f, -0.443359f, 0.179199f,
+-0.443359f, 0.215332f, -0.443359f, 0.230713f, -0.429443f, 0.246094f, -0.415527f,
+0.246094f, -0.393066f, 0.246094f, -0.371094f, 0.230713f, -0.357178f, 0.215332f, -0.343262f,
+0.182129f, -0.343262f, 0.300293f, -0.113281f, 0.41748f, -0.343262f, 0.385254f, -0.343262f,
+0.369873f, -0.357178f, 0.354492f, -0.371094f, 0.354492f, -0.393555f, 0.354492f, -0.415527f,
+0.369873f, -0.429443f, 0.385254f, -0.443359f, 0.421387f, -0.443359f, 0.515625f, -0.443359f,
+0.55127f, -0.443359f, 0.56665f, -0.429443f, 0.582031f, -0.415527f, 0.582031f, -0.393066f,
+0.582031f, -0.373047f, 0.568848f, -0.359131f, 0.555664f, -0.345215f, 0.529785f, -0.343262f,
+0.300293f, 0.108887f, 0.337891f, 0.108887f, 0.349609f, 0.116211f, 0.373047f, 0.131348f,
+0.373047f, 0.15918f, 0.373047f, 0.181152f, 0.357666f, 0.195068f, 0.342285f, 0.208984f,
+0.306152f, 0.208984f, 0.0878906f, 0.208984f, 0.0517578f, 0.208984f, 0.036377f, 0.195068f,
+0.0209961f, 0.181152f, 0.0209961f, 0.15918f, 0.0209961f, 0.136719f, 0.036377f, 0.122803f,
+0.0517578f, 0.108887f, 0.0878906f, 0.108887f, 0.1875f, 0.108887f
+};
+
+const unsigned char CourierNewkBoldVerbs[] = {
+6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1,
+2, 2, 2, 2, 1, 5, 0, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1,
+2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2,
+1, 1, 1, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1,
+1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 1,
+2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2,
+5, 0, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2,
+1, 1, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1,
+2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2,
+2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2,
+1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6
+};
+
+const unsigned CourierNewkBoldCharCodes[] = {
+32, 65, 72, 84, 87,
+89, 97, 98, 101, 102, 103, 109, 110, 111, 112, 114, 115, 117, 121
+};
+
+const SkFixed CourierNewkBoldWidths[] = {
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0
+};
+
+const int CourierNewkBoldCharCodesCount = (int) SK_ARRAY_COUNT(CourierNewkBoldCharCodes);
+
+const SkPaint::FontMetrics CourierNewkBoldMetrics = {
+0x00000003, -1.22119f, -0.83252f, 0.300293f, 0.710449f, 0, 0.893555f, 0, -0.191895f,
+0.70166f, 0.458008f, 0, 0.100098f, 0.23291f
+};
+
+const SkScalar CourierNewkItalicPoints[] = {
+0.496582f, -0.190918f, 0.227051f, -0.190918f, 0.139648f, -0.0410156f, 0.218262f, -0.0410156f,
+0.232422f, -0.0410156f, 0.237305f, -0.0368652f, 0.242188f, -0.0327148f, 0.242188f,
+-0.0249023f, 0.242188f, -0.0146484f, 0.233887f, -0.00732422f, 0.225586f, 0, 0.209473f,
+0, 0.0566406f, 0, 0.0429688f, 0, 0.0380859f, -0.00439453f, 0.0332031f, -0.00878906f,
+0.0332031f, -0.0166016f, 0.0332031f, -0.0263672f, 0.0412598f, -0.0336914f, 0.0493164f,
+-0.0410156f, 0.0654297f, -0.0410156f, 0.0966797f, -0.0410156f, 0.382324f, -0.530273f,
+0.26123f, -0.530273f, 0.247559f, -0.530273f, 0.242676f, -0.534424f, 0.237793f, -0.538574f,
+0.237793f, -0.546875f, 0.237793f, -0.556641f, 0.24585f, -0.563965f, 0.253906f, -0.571289f,
+0.27002f, -0.571289f, 0.476074f, -0.571289f, 0.563965f, -0.0410156f, 0.595703f, -0.0410156f,
+0.609375f, -0.0410156f, 0.614258f, -0.0368652f, 0.619141f, -0.0327148f, 0.619141f,
+-0.0249023f, 0.619141f, -0.0146484f, 0.611084f, -0.00732422f, 0.603027f, 0, 0.586914f,
+0, 0.433594f, 0, 0.419922f, 0, 0.415039f, -0.00439453f, 0.410156f, -0.00878906f,
+0.410156f, -0.0166016f, 0.410156f, -0.0263672f, 0.418213f, -0.0336914f, 0.42627f,
+-0.0410156f, 0.442383f, -0.0410156f, 0.520996f, -0.0410156f, 0.489746f, -0.231934f,
+0.439941f, -0.530273f, 0.424805f, -0.530273f, 0.250977f, -0.231934f, 0.49707f, -0.276367f,
+0.224609f, -0.276367f, 0.174805f, -0.0410156f, 0.221191f, -0.0410156f, 0.243652f,
+-0.0410156f, 0.248535f, -0.0368652f, 0.253418f, -0.0327148f, 0.253418f, -0.0249023f,
+0.253418f, -0.0146484f, 0.245361f, -0.00732422f, 0.237305f, 0, 0.221191f, 0, 0.0786133f,
+0, 0.0649414f, 0, 0.0605469f, -0.00561523f, 0.0561523f, -0.0112305f, 0.0561523f,
+-0.019043f, 0.0561523f, -0.0288086f, 0.0637207f, -0.0349121f, 0.0712891f, -0.0410156f,
+0.0874023f, -0.0410156f, 0.133789f, -0.0410156f, 0.237793f, -0.530273f, 0.191895f,
+-0.530273f, 0.171387f, -0.530273f, 0.164307f, -0.53418f, 0.157227f, -0.538086f, 0.158203f,
+-0.54834f, 0.158203f, -0.557617f, 0.164795f, -0.563721f, 0.171387f, -0.569824f, 0.192383f,
+-0.571777f, 0.32959f, -0.571777f, 0.347168f, -0.569336f, 0.351807f, -0.567627f, 0.356445f,
+-0.565918f, 0.35791f, -0.556152f, 0.35791f, -0.545898f, 0.352051f, -0.539062f, 0.346191f,
+-0.532227f, 0.325195f, -0.530273f, 0.278809f, -0.530273f, 0.233398f, -0.317383f,
+0.505859f, -0.317383f, 0.550781f, -0.530273f, 0.504395f, -0.530273f, 0.481934f, -0.530273f,
+0.477051f, -0.534424f, 0.472168f, -0.538574f, 0.472168f, -0.546875f, 0.472168f, -0.556641f,
+0.480225f, -0.563965f, 0.488281f, -0.571289f, 0.504395f, -0.571289f, 0.626465f, -0.571289f,
+0.652832f, -0.570801f, 0.661133f, -0.567383f, 0.669434f, -0.563965f, 0.67041f, -0.555176f,
+0.671387f, -0.544922f, 0.664307f, -0.538574f, 0.657227f, -0.532227f, 0.638672f, -0.530273f,
+0.592285f, -0.530273f, 0.488281f, -0.0410156f, 0.53418f, -0.0410156f, 0.554199f,
+-0.0419922f, 0.560303f, -0.0354004f, 0.566406f, -0.0288086f, 0.566406f, -0.0209961f,
+0.566406f, -0.0107422f, 0.556396f, -0.00537109f, 0.546387f, 0, 0.525391f, 0, 0.393066f,
+0, 0.379395f, 0, 0.373779f, -0.00366211f, 0.368164f, -0.00732422f, 0.368164f, -0.0151367f,
+0.368164f, -0.0249023f, 0.372559f, -0.0317383f, 0.376953f, -0.0385742f, 0.400391f,
+-0.0410156f, 0.446777f, -0.0410156f, 0.433105f, -0.530273f, 0.329102f, -0.0410156f,
+0.435547f, -0.0410156f, 0.449219f, -0.0410156f, 0.454102f, -0.0368652f, 0.458984f,
+-0.0327148f, 0.458984f, -0.0249023f, 0.458984f, -0.0146484f, 0.450928f, -0.00732422f,
+0.442871f, 0, 0.426758f, 0, 0.172363f, 0, 0.158691f, 0, 0.153809f, -0.00439453f,
+0.148926f, -0.00878906f, 0.148926f, -0.0166016f, 0.148926f, -0.0263672f, 0.156982f,
+-0.0336914f, 0.165039f, -0.0410156f, 0.181152f, -0.0410156f, 0.287598f, -0.0410156f,
+0.391602f, -0.530273f, 0.223633f, -0.530273f, 0.193359f, -0.388184f, 0.19043f, -0.373047f,
+0.18335f, -0.366699f, 0.17627f, -0.360352f, 0.166992f, -0.360352f, 0.159668f, -0.360352f,
+0.155029f, -0.36499f, 0.150391f, -0.369629f, 0.150391f, -0.375488f, 0.150391f, -0.379883f,
+0.152344f, -0.388184f, 0.191406f, -0.571289f, 0.650879f, -0.571289f, 0.611816f, -0.388184f,
+0.608887f, -0.373047f, 0.601562f, -0.366699f, 0.594238f, -0.360352f, 0.584961f, -0.360352f,
+0.578125f, -0.360352f, 0.573486f, -0.36499f, 0.568848f, -0.369629f, 0.568848f, -0.375488f,
+0.568848f, -0.379883f, 0.570801f, -0.388184f, 0.601074f, -0.530273f, 0.47998f, 0,
+0.416016f, 0, 0.385742f, -0.405762f, 0.185547f, 0, 0.121094f, 0, 0.173828f, -0.530273f,
+0.158691f, -0.530273f, 0.14502f, -0.530273f, 0.139893f, -0.534424f, 0.134766f, -0.538574f,
+0.134766f, -0.546875f, 0.134766f, -0.556641f, 0.143066f, -0.563965f, 0.151367f, -0.571289f,
+0.16748f, -0.571289f, 0.319824f, -0.571289f, 0.333496f, -0.571289f, 0.338379f, -0.567139f,
+0.343262f, -0.562988f, 0.343262f, -0.555176f, 0.343262f, -0.544922f, 0.335205f, -0.537598f,
+0.327148f, -0.530273f, 0.311035f, -0.530273f, 0.214844f, -0.530273f, 0.166504f, -0.046875f,
+0.362305f, -0.444824f, 0.424805f, -0.444824f, 0.454102f, -0.046875f, 0.609863f, -0.530273f,
+0.513672f, -0.530273f, 0.5f, -0.530273f, 0.495117f, -0.534424f, 0.490234f, -0.538574f,
+0.490234f, -0.546875f, 0.490234f, -0.556641f, 0.498291f, -0.563965f, 0.506348f, -0.571289f,
+0.522461f, -0.571289f, 0.674316f, -0.571289f, 0.687988f, -0.571289f, 0.692871f, -0.567139f,
+0.697754f, -0.562988f, 0.697754f, -0.555176f, 0.697754f, -0.547852f, 0.692871f, -0.54126f,
+0.687988f, -0.534668f, 0.681152f, -0.532227f, 0.67627f, -0.530273f, 0.650391f, -0.530273f,
+0.375977f, -0.257812f, 0.330078f, -0.0410156f, 0.436523f, -0.0410156f, 0.450195f,
+-0.0410156f, 0.455078f, -0.0368652f, 0.459961f, -0.0327148f, 0.459961f, -0.0249023f,
+0.459961f, -0.0146484f, 0.451904f, -0.00732422f, 0.443848f, 0, 0.427734f, 0, 0.17334f,
+0, 0.159668f, 0, 0.154785f, -0.00439453f, 0.149902f, -0.00878906f, 0.149902f, -0.0166016f,
+0.149902f, -0.0263672f, 0.157959f, -0.0336914f, 0.166016f, -0.0410156f, 0.182129f,
+-0.0410156f, 0.288574f, -0.0410156f, 0.334961f, -0.257812f, 0.212402f, -0.530273f,
+0.187988f, -0.530273f, 0.174316f, -0.530273f, 0.169434f, -0.534424f, 0.164551f, -0.538574f,
+0.164551f, -0.546875f, 0.164551f, -0.556641f, 0.172607f, -0.563965f, 0.180664f, -0.571289f,
+0.196777f, -0.571289f, 0.30957f, -0.571289f, 0.323242f, -0.571289f, 0.328125f, -0.567139f,
+0.333008f, -0.562988f, 0.333008f, -0.555176f, 0.333008f, -0.544922f, 0.324951f, -0.537598f,
+0.316895f, -0.530273f, 0.300781f, -0.530273f, 0.260254f, -0.530273f, 0.364258f, -0.299316f,
+0.563477f, -0.530273f, 0.523438f, -0.530273f, 0.509277f, -0.530273f, 0.504395f, -0.534424f,
+0.499512f, -0.538574f, 0.499512f, -0.546875f, 0.499512f, -0.556641f, 0.507568f, -0.563965f,
+0.515625f, -0.571289f, 0.531738f, -0.571289f, 0.644531f, -0.571289f, 0.658203f, -0.571289f,
+0.663086f, -0.567139f, 0.667969f, -0.562988f, 0.667969f, -0.555176f, 0.667969f, -0.544922f,
+0.659912f, -0.537598f, 0.651855f, -0.530273f, 0.635742f, -0.530273f, 0.611328f, -0.530273f,
+0.418457f, 0, 0.430664f, -0.059082f, 0.325684f, 0.0161133f, 0.223633f, 0.0161133f,
+0.158203f, 0.0161133f, 0.125f, -0.0131836f, 0.0917969f, -0.0424805f, 0.0917969f,
+-0.0864258f, 0.0917969f, -0.15332f, 0.150391f, -0.201172f, 0.223145f, -0.26123f,
+0.340332f, -0.26123f, 0.396484f, -0.26123f, 0.470703f, -0.246094f, 0.484863f, -0.3125f,
+0.486328f, -0.319824f, 0.486328f, -0.327148f, 0.486328f, -0.355469f, 0.463867f, -0.372559f,
+0.433594f, -0.395996f, 0.377441f, -0.395996f, 0.330078f, -0.395996f, 0.231934f, -0.366699f,
+0.220703f, -0.363281f, 0.21582f, -0.363281f, 0.209473f, -0.363281f, 0.205078f, -0.367676f,
+0.200684f, -0.37207f, 0.200684f, -0.379395f, 0.200684f, -0.388672f, 0.207764f, -0.395996f,
+0.214844f, -0.40332f, 0.262695f, -0.415527f, 0.347168f, -0.4375f, 0.388184f, -0.4375f,
+0.458008f, -0.4375f, 0.493408f, -0.406738f, 0.528809f, -0.375977f, 0.528809f, -0.337402f,
+0.528809f, -0.324707f, 0.525879f, -0.3125f, 0.468262f, -0.0410156f, 0.523438f, -0.0410156f,
+0.537109f, -0.0410156f, 0.541992f, -0.0368652f, 0.546875f, -0.0327148f, 0.546875f,
+-0.0249023f, 0.546875f, -0.0146484f, 0.538818f, -0.00732422f, 0.530762f, 0, 0.514648f,
+0, 0.461914f, -0.204102f, 0.406738f, -0.220215f, 0.335938f, -0.220215f, 0.237793f,
+-0.220215f, 0.178711f, -0.174805f, 0.134277f, -0.140625f, 0.134277f, -0.0966797f,
+0.134277f, -0.0649414f, 0.157471f, -0.0449219f, 0.180664f, -0.0249023f, 0.229004f,
+-0.0249023f, 0.282227f, -0.0249023f, 0.33252f, -0.0456543f, 0.382812f, -0.0664062f,
+0.442383f, -0.11377f, 0.275879f, -0.612793f, 0.218262f, -0.34082f, 0.312012f, -0.4375f,
+0.41748f, -0.4375f, 0.494141f, -0.4375f, 0.543701f, -0.388184f, 0.593262f, -0.338867f,
+0.593262f, -0.263184f, 0.593262f, -0.196289f, 0.555664f, -0.129395f, 0.518066f, -0.0625f,
+0.451416f, -0.0231934f, 0.384766f, 0.0161133f, 0.321777f, 0.0161133f, 0.213379f,
+0.0161133f, 0.162598f, -0.0805664f, 0.145508f, 0, 0.0493164f, 0, 0.0356445f, 0, 0.0307617f,
+-0.00439453f, 0.0258789f, -0.00878906f, 0.0258789f, -0.0166016f, 0.0258789f, -0.0263672f,
+0.0339355f, -0.0336914f, 0.0419922f, -0.0410156f, 0.0581055f, -0.0410156f, 0.113281f,
+-0.0410156f, 0.225586f, -0.571289f, 0.170898f, -0.571289f, 0.157227f, -0.571289f,
+0.152344f, -0.575684f, 0.147461f, -0.580078f, 0.147461f, -0.587891f, 0.147461f, -0.597656f,
+0.155518f, -0.605225f, 0.163574f, -0.612793f, 0.179688f, -0.612793f, 0.32959f, -0.0249023f,
+0.368164f, -0.0249023f, 0.406982f, -0.0427246f, 0.445801f, -0.0605469f, 0.477539f,
+-0.0900879f, 0.509277f, -0.119629f, 0.530029f, -0.162842f, 0.550781f, -0.206055f,
+0.550781f, -0.254883f, 0.550781f, -0.313965f, 0.509521f, -0.35498f, 0.468262f, -0.395996f,
+0.407227f, -0.395996f, 0.35791f, -0.395996f, 0.301758f, -0.363525f, 0.245605f, -0.331055f,
+0.21582f, -0.2771f, 0.186035f, -0.223145f, 0.186035f, -0.167969f, 0.186035f, -0.107422f,
+0.227295f, -0.0661621f, 0.268555f, -0.0249023f, 0.32959f, -0.0249023f, 0.56543f,
+-0.20166f, 0.147461f, -0.20166f, 0.145996f, -0.186523f, 0.145996f, -0.178711f, 0.145996f,
+-0.111816f, 0.191406f, -0.0683594f, 0.236816f, -0.0249023f, 0.314453f, -0.0249023f,
+0.359863f, -0.0249023f, 0.413086f, -0.0397949f, 0.466309f, -0.0546875f, 0.504395f,
+-0.0800781f, 0.515625f, -0.0874023f, 0.522461f, -0.0874023f, 0.528809f, -0.0874023f,
+0.533203f, -0.0827637f, 0.537598f, -0.078125f, 0.537598f, -0.0708008f, 0.537598f,
+-0.0620117f, 0.529785f, -0.0541992f, 0.507324f, -0.0302734f, 0.439941f, -0.00708008f,
+0.372559f, 0.0161133f, 0.303223f, 0.0161133f, 0.213379f, 0.0161133f, 0.158936f, -0.0371094f,
+0.104492f, -0.090332f, 0.104492f, -0.172363f, 0.104492f, -0.226562f, 0.12793f, -0.274658f,
+0.151367f, -0.322754f, 0.189697f, -0.357666f, 0.228027f, -0.392578f, 0.278076f, -0.415039f,
+0.328125f, -0.4375f, 0.387207f, -0.4375f, 0.471191f, -0.4375f, 0.522217f, -0.388184f,
+0.573242f, -0.338867f, 0.573242f, -0.262207f, 0.573242f, -0.236816f, 0.56543f, -0.20166f,
+0.532227f, -0.243164f, 0.534668f, -0.310547f, 0.492188f, -0.353516f, 0.449219f, -0.395996f,
+0.376953f, -0.395996f, 0.306641f, -0.395996f, 0.245605f, -0.354492f, 0.18457f, -0.312988f,
+0.15625f, -0.243164f, 0.354004f, -0.381348f, 0.281738f, -0.0410156f, 0.461914f, -0.0410156f,
+0.475586f, -0.0410156f, 0.480469f, -0.0368652f, 0.485352f, -0.0327148f, 0.485352f,
+-0.0249023f, 0.485352f, -0.0146484f, 0.477295f, -0.00732422f, 0.469238f, 0, 0.453125f,
+0, 0.132324f, 0, 0.118652f, 0, 0.11377f, -0.00439453f, 0.108887f, -0.00878906f, 0.108887f,
+-0.0166016f, 0.108887f, -0.0263672f, 0.116943f, -0.0336914f, 0.125f, -0.0410156f,
+0.141113f, -0.0410156f, 0.240234f, -0.0410156f, 0.3125f, -0.381348f, 0.223633f, -0.381348f,
+0.209961f, -0.381348f, 0.205078f, -0.385742f, 0.200195f, -0.390137f, 0.200195f, -0.397949f,
+0.200195f, -0.407715f, 0.208252f, -0.415283f, 0.216309f, -0.422852f, 0.232422f, -0.422852f,
+0.321289f, -0.422852f, 0.334473f, -0.484863f, 0.345703f, -0.537109f, 0.395752f, -0.574951f,
+0.445801f, -0.612793f, 0.515625f, -0.612793f, 0.569824f, -0.612793f, 0.632324f, -0.603027f,
+0.65918f, -0.598633f, 0.66333f, -0.594238f, 0.66748f, -0.589844f, 0.66748f, -0.583496f,
+0.66748f, -0.573242f, 0.659912f, -0.565918f, 0.652344f, -0.558594f, 0.640625f, -0.558594f,
+0.637207f, -0.558594f, 0.628418f, -0.560059f, 0.557129f, -0.571289f, 0.507324f, -0.571289f,
+0.452148f, -0.571289f, 0.41748f, -0.544678f, 0.382812f, -0.518066f, 0.375977f, -0.484863f,
+0.362793f, -0.422852f, 0.554688f, -0.422852f, 0.568359f, -0.422852f, 0.572754f, -0.418945f,
+0.578125f, -0.414062f, 0.578125f, -0.40625f, 0.578125f, -0.396484f, 0.570068f, -0.388916f,
+0.562012f, -0.381348f, 0.545898f, -0.381348f, 0.511719f, -0.347656f, 0.527832f, -0.422852f,
+0.624023f, -0.422852f, 0.637695f, -0.422852f, 0.64209f, -0.418945f, 0.647949f, -0.414062f,
+0.647949f, -0.40625f, 0.647949f, -0.396484f, 0.639648f, -0.388916f, 0.631348f, -0.381348f,
+0.615234f, -0.381348f, 0.560547f, -0.381348f, 0.473145f, 0.0283203f, 0.464844f, 0.0678711f,
+0.441406f, 0.100098f, 0.424805f, 0.122559f, 0.391113f, 0.145996f, 0.357422f, 0.169434f,
+0.333984f, 0.178955f, 0.310547f, 0.188477f, 0.272461f, 0.188477f, 0.15625f, 0.188477f,
+0.142578f, 0.188477f, 0.137695f, 0.184082f, 0.132812f, 0.179688f, 0.132812f, 0.172363f,
+0.132812f, 0.162109f, 0.140869f, 0.154541f, 0.148926f, 0.146973f, 0.165039f, 0.146973f,
+0.282715f, 0.147461f, 0.317383f, 0.147461f, 0.350098f, 0.129883f, 0.382812f, 0.112305f,
+0.410645f, 0.0751953f, 0.42627f, 0.0546875f, 0.433105f, 0.0224609f, 0.459473f, -0.100586f,
+0.374023f, -0.0102539f, 0.268555f, -0.0102539f, 0.197754f, -0.0102539f, 0.150879f,
+-0.0578613f, 0.104004f, -0.105469f, 0.104004f, -0.180176f, 0.104004f, -0.232422f,
+0.128418f, -0.280518f, 0.152832f, -0.328613f, 0.1875f, -0.361572f, 0.222168f, -0.394531f,
+0.266357f, -0.416016f, 0.310547f, -0.4375f, 0.361328f, -0.4375f, 0.465332f, -0.4375f,
+0.511719f, -0.347656f, 0.279785f, -0.0517578f, 0.321289f, -0.0517578f, 0.35791f,
+-0.0688477f, 0.394531f, -0.0859375f, 0.423828f, -0.114014f, 0.453125f, -0.14209f,
+0.471436f, -0.181885f, 0.489746f, -0.22168f, 0.489746f, -0.263184f, 0.489746f, -0.320312f,
+0.45166f, -0.358154f, 0.413574f, -0.395996f, 0.355957f, -0.395996f, 0.274414f, -0.395996f,
+0.210205f, -0.332031f, 0.145996f, -0.268066f, 0.145996f, -0.1875f, 0.145996f, -0.12793f,
+0.184082f, -0.0898438f, 0.222168f, -0.0517578f, 0.279785f, -0.0517578f, 0.203125f,
+-0.422852f, 0.194336f, -0.381348f, 0.258301f, -0.4375f, 0.312012f, -0.4375f, 0.341309f,
+-0.4375f, 0.362305f, -0.42041f, 0.383301f, -0.40332f, 0.392578f, -0.369629f, 0.427246f,
+-0.403809f, 0.458984f, -0.420654f, 0.490723f, -0.4375f, 0.519531f, -0.4375f, 0.555664f,
+-0.4375f, 0.57959f, -0.412842f, 0.603516f, -0.388184f, 0.603516f, -0.349121f, 0.603516f,
+-0.339355f, 0.600586f, -0.327637f, 0.540039f, -0.0410156f, 0.574219f, -0.0410156f,
+0.588379f, -0.0410156f, 0.593262f, -0.0368652f, 0.598145f, -0.0327148f, 0.598145f,
+-0.0249023f, 0.598145f, -0.0146484f, 0.589844f, -0.00732422f, 0.581543f, 0, 0.56543f,
+0, 0.489746f, 0, 0.558594f, -0.32373f, 0.560547f, -0.332031f, 0.560547f, -0.340332f,
+0.560547f, -0.366211f, 0.546631f, -0.381104f, 0.532715f, -0.395996f, 0.512207f, -0.395996f,
+0.489746f, -0.395996f, 0.465332f, -0.382324f, 0.432617f, -0.363281f, 0.389648f, -0.312988f,
+0.331543f, -0.0410156f, 0.366211f, -0.0410156f, 0.379883f, -0.0410156f, 0.384766f,
+-0.0368652f, 0.389648f, -0.0327148f, 0.389648f, -0.0249023f, 0.389648f, -0.0146484f,
+0.381592f, -0.00732422f, 0.373535f, 0, 0.357422f, 0, 0.281738f, 0, 0.350098f, -0.320801f,
+0.352051f, -0.330566f, 0.352051f, -0.339844f, 0.352051f, -0.364746f, 0.337646f, -0.380371f,
+0.323242f, -0.395996f, 0.304199f, -0.395996f, 0.282227f, -0.395996f, 0.258301f, -0.382812f,
+0.223633f, -0.362793f, 0.179688f, -0.312988f, 0.12207f, -0.0410156f, 0.15625f, -0.0410156f,
+0.17041f, -0.0410156f, 0.175293f, -0.0368652f, 0.180176f, -0.0327148f, 0.180176f,
+-0.0249023f, 0.180176f, -0.0146484f, 0.171875f, -0.00732422f, 0.163574f, 0, 0.147461f,
+0, 0.0375977f, 0, 0.0239258f, 0, 0.019043f, -0.00439453f, 0.0141602f, -0.00878906f,
+0.0141602f, -0.0166016f, 0.0141602f, -0.0263672f, 0.0222168f, -0.0336914f, 0.0302734f,
+-0.0410156f, 0.0463867f, -0.0410156f, 0.0805664f, -0.0410156f, 0.15332f, -0.381348f,
+0.118652f, -0.381348f, 0.10498f, -0.381348f, 0.100098f, -0.385742f, 0.0952148f, -0.390137f,
+0.0952148f, -0.397949f, 0.0952148f, -0.407715f, 0.103271f, -0.415283f, 0.111328f,
+-0.422852f, 0.127441f, -0.422852f, 0.257324f, -0.422852f, 0.244141f, -0.36084f, 0.297852f,
+-0.405273f, 0.335693f, -0.421387f, 0.373535f, -0.4375f, 0.41748f, -0.4375f, 0.478027f,
+-0.4375f, 0.512451f, -0.405273f, 0.546875f, -0.373047f, 0.546875f, -0.321777f, 0.546875f,
+-0.312012f, 0.544434f, -0.299316f, 0.489258f, -0.0410156f, 0.523926f, -0.0410156f,
+0.537598f, -0.0410156f, 0.54248f, -0.0368652f, 0.547363f, -0.0327148f, 0.547363f,
+-0.0249023f, 0.547363f, -0.0146484f, 0.539307f, -0.00732422f, 0.53125f, 0, 0.515137f,
+0, 0.404785f, 0, 0.391113f, 0, 0.38623f, -0.00439453f, 0.381348f, -0.00878906f, 0.381348f,
+-0.0166016f, 0.381348f, -0.0263672f, 0.389404f, -0.0336914f, 0.397461f, -0.0410156f,
+0.413574f, -0.0410156f, 0.448242f, -0.0410156f, 0.501465f, -0.29248f, 0.503906f,
+-0.303711f, 0.503906f, -0.313965f, 0.503906f, -0.349609f, 0.479004f, -0.372803f,
+0.454102f, -0.395996f, 0.407715f, -0.395996f, 0.365234f, -0.395996f, 0.331787f, -0.378906f,
+0.29834f, -0.361816f, 0.230957f, -0.29834f, 0.17627f, -0.0410156f, 0.222656f, -0.0410156f,
+0.236328f, -0.0410156f, 0.241211f, -0.0368652f, 0.246094f, -0.0327148f, 0.246094f,
+-0.0249023f, 0.246094f, -0.0146484f, 0.238037f, -0.00732422f, 0.22998f, 0, 0.213867f,
+0, 0.0800781f, 0, 0.0664062f, 0, 0.0615234f, -0.00439453f, 0.0566406f, -0.00878906f,
+0.0566406f, -0.0166016f, 0.0566406f, -0.0263672f, 0.0646973f, -0.0336914f, 0.0727539f,
+-0.0410156f, 0.0888672f, -0.0410156f, 0.135254f, -0.0410156f, 0.20752f, -0.381348f,
+0.172852f, -0.381348f, 0.15918f, -0.381348f, 0.154297f, -0.385742f, 0.149414f, -0.390137f,
+0.149414f, -0.397949f, 0.149414f, -0.407715f, 0.157471f, -0.415283f, 0.165527f, -0.422852f,
+0.181641f, -0.422852f, 0.294922f, 0.0161133f, 0.214355f, 0.0161133f, 0.162598f, -0.0349121f,
+0.11084f, -0.0859375f, 0.11084f, -0.164551f, 0.11084f, -0.228516f, 0.149902f, -0.294678f,
+0.188965f, -0.36084f, 0.25708f, -0.39917f, 0.325195f, -0.4375f, 0.39502f, -0.4375f,
+0.475098f, -0.4375f, 0.526855f, -0.386719f, 0.578613f, -0.335938f, 0.578613f, -0.260254f,
+0.578613f, -0.193848f, 0.540771f, -0.128418f, 0.50293f, -0.0629883f, 0.434326f, -0.0234375f,
+0.365723f, 0.0161133f, 0.294922f, 0.0161133f, 0.304199f, -0.0249023f, 0.361816f,
+-0.0249023f, 0.418213f, -0.057373f, 0.474609f, -0.0898438f, 0.505615f, -0.143555f,
+0.536621f, -0.197266f, 0.536621f, -0.251465f, 0.536621f, -0.312988f, 0.494141f, -0.354492f,
+0.45166f, -0.395996f, 0.385742f, -0.395996f, 0.338379f, -0.395996f, 0.297607f, -0.377197f,
+0.256836f, -0.358398f, 0.225342f, -0.328857f, 0.193848f, -0.299316f, 0.17334f, -0.258057f,
+0.152832f, -0.216797f, 0.152832f, -0.172852f, 0.152832f, -0.108887f, 0.195312f, -0.0668945f,
+0.237793f, -0.0249023f, 0.304199f, -0.0249023f, 0.235352f, -0.422852f, 0.219727f,
+-0.348145f, 0.266602f, -0.393555f, 0.313232f, -0.415527f, 0.359863f, -0.4375f, 0.416504f,
+-0.4375f, 0.498047f, -0.4375f, 0.546387f, -0.390381f, 0.594727f, -0.343262f, 0.594727f,
+-0.268555f, 0.594727f, -0.169434f, 0.513428f, -0.0898438f, 0.432129f, -0.0102539f,
+0.325684f, -0.0102539f, 0.216309f, -0.0102539f, 0.166992f, -0.0996094f, 0.114258f,
+0.147461f, 0.213379f, 0.147461f, 0.224609f, 0.147461f, 0.228271f, 0.148926f, 0.231934f,
+0.150391f, 0.234619f, 0.154541f, 0.237305f, 0.158691f, 0.237305f, 0.163574f, 0.237305f,
+0.173828f, 0.229004f, 0.181152f, 0.220703f, 0.188477f, 0.20459f, 0.188477f, 0.00927734f,
+0.188477f, -0.00439453f, 0.188477f, -0.00927734f, 0.184082f, -0.0141602f, 0.179688f,
+-0.0141602f, 0.172363f, -0.0141602f, 0.162109f, -0.00610352f, 0.154785f, 0.00195312f,
+0.147461f, 0.0180664f, 0.147461f, 0.0732422f, 0.147461f, 0.185547f, -0.381348f, 0.130371f,
+-0.381348f, 0.116699f, -0.381348f, 0.111816f, -0.385742f, 0.106934f, -0.390137f,
+0.106934f, -0.397949f, 0.106934f, -0.407715f, 0.11499f, -0.415283f, 0.123047f, -0.422852f,
+0.13916f, -0.422852f, 0.333008f, -0.0517578f, 0.42041f, -0.0517578f, 0.486328f, -0.115723f,
+0.552246f, -0.179688f, 0.552246f, -0.26123f, 0.552246f, -0.318359f, 0.511963f, -0.357178f,
+0.47168f, -0.395996f, 0.40918f, -0.395996f, 0.321777f, -0.395996f, 0.255615f, -0.332031f,
+0.189453f, -0.268066f, 0.189453f, -0.189453f, 0.189453f, -0.130371f, 0.229736f, -0.0910645f,
+0.27002f, -0.0517578f, 0.333008f, -0.0517578f, 0.34082f, -0.422852f, 0.318848f, -0.319336f,
+0.416016f, -0.392578f, 0.459717f, -0.412842f, 0.503418f, -0.433105f, 0.536621f, -0.433105f,
+0.569824f, -0.433105f, 0.596436f, -0.410645f, 0.623047f, -0.388184f, 0.623047f, -0.375488f,
+0.623047f, -0.365234f, 0.615234f, -0.357422f, 0.607422f, -0.349609f, 0.59668f, -0.349609f,
+0.591797f, -0.349609f, 0.588867f, -0.351318f, 0.585938f, -0.353027f, 0.578613f, -0.362305f,
+0.56543f, -0.379395f, 0.553955f, -0.385742f, 0.54248f, -0.39209f, 0.530762f, -0.39209f,
+0.503418f, -0.39209f, 0.461182f, -0.370605f, 0.418945f, -0.349121f, 0.307617f, -0.265625f,
+0.259766f, -0.0410156f, 0.441406f, -0.0410156f, 0.455566f, -0.0410156f, 0.460449f,
+-0.0368652f, 0.465332f, -0.0327148f, 0.465332f, -0.0249023f, 0.465332f, -0.0146484f,
+0.457031f, -0.00732422f, 0.44873f, 0, 0.432617f, 0, 0.11084f, 0, 0.097168f, 0, 0.0922852f,
+-0.00415039f, 0.0874023f, -0.00830078f, 0.0874023f, -0.015625f, 0.0874023f, -0.0253906f,
+0.0952148f, -0.0324707f, 0.103027f, -0.0395508f, 0.119141f, -0.0395508f, 0.218262f,
+-0.0395508f, 0.291016f, -0.381348f, 0.215332f, -0.381348f, 0.20166f, -0.381348f,
+0.196777f, -0.385742f, 0.191895f, -0.390137f, 0.191895f, -0.397461f, 0.191895f, -0.407715f,
+0.199951f, -0.415283f, 0.208008f, -0.422852f, 0.224121f, -0.422852f, 0.52002f, -0.395996f,
+0.522949f, -0.410156f, 0.530273f, -0.416504f, 0.537598f, -0.422852f, 0.546387f, -0.422852f,
+0.553711f, -0.422852f, 0.55835f, -0.418213f, 0.562988f, -0.413574f, 0.562988f, -0.407715f,
+0.562988f, -0.40332f, 0.561035f, -0.39502f, 0.546387f, -0.324707f, 0.542969f, -0.310059f,
+0.535889f, -0.303711f, 0.528809f, -0.297363f, 0.519531f, -0.297363f, 0.512695f, -0.297363f,
+0.508057f, -0.301758f, 0.503418f, -0.306152f, 0.503418f, -0.312012f, 0.503906f, -0.320312f,
+0.504395f, -0.324219f, 0.504395f, -0.327637f, 0.504395f, -0.354004f, 0.480957f, -0.370605f,
+0.446289f, -0.395996f, 0.383789f, -0.395996f, 0.308594f, -0.395996f, 0.26416f, -0.36377f,
+0.230957f, -0.339844f, 0.230957f, -0.312988f, 0.230957f, -0.286621f, 0.259766f, -0.27002f,
+0.280762f, -0.258301f, 0.348633f, -0.250732f, 0.416504f, -0.243164f, 0.445801f, -0.233398f,
+0.486816f, -0.220215f, 0.506836f, -0.195312f, 0.526855f, -0.17041f, 0.526855f, -0.13916f,
+0.526855f, -0.103027f, 0.500488f, -0.0668945f, 0.474121f, -0.0307617f, 0.419922f,
+-0.00732422f, 0.365723f, 0.0161133f, 0.297852f, 0.0161133f, 0.249512f, 0.0161133f,
+0.212402f, 0.00366211f, 0.175293f, -0.00878906f, 0.149414f, -0.0332031f, 0.145508f,
+-0.0131836f, 0.139648f, -0.00732422f, 0.131348f, 0, 0.121582f, 0, 0.114746f, 0, 0.110107f,
+-0.00439453f, 0.105469f, -0.00878906f, 0.105469f, -0.0151367f, 0.105469f, -0.0195312f,
+0.106934f, -0.0273438f, 0.125f, -0.111816f, 0.12793f, -0.126465f, 0.135254f, -0.132812f,
+0.142578f, -0.13916f, 0.151855f, -0.13916f, 0.158691f, -0.13916f, 0.16333f, -0.134521f,
+0.167969f, -0.129883f, 0.167969f, -0.123535f, 0.167969f, -0.119629f, 0.166504f, -0.112305f,
+0.165039f, -0.10498f, 0.165039f, -0.101562f, 0.165039f, -0.0737305f, 0.193848f, -0.0527344f,
+0.231934f, -0.0249023f, 0.305176f, -0.0249023f, 0.392578f, -0.0249023f, 0.438477f,
+-0.0595703f, 0.484375f, -0.0942383f, 0.484375f, -0.128418f, 0.484375f, -0.146973f,
+0.470947f, -0.164795f, 0.45752f, -0.182617f, 0.430176f, -0.193115f, 0.402832f, -0.203613f,
+0.340576f, -0.210205f, 0.27832f, -0.216797f, 0.249756f, -0.226807f, 0.221191f, -0.236816f,
+0.205078f, -0.257324f, 0.188965f, -0.277832f, 0.188965f, -0.304199f, 0.188965f, -0.334961f,
+0.209961f, -0.364502f, 0.230957f, -0.394043f, 0.280029f, -0.415771f, 0.329102f, -0.4375f,
+0.390137f, -0.4375f, 0.432617f, -0.4375f, 0.465088f, -0.427246f, 0.497559f, -0.416992f,
+0.52002f, -0.395996f, 0.44043f, 0, 0.453125f, -0.0600586f, 0.353027f, 0.0161133f,
+0.253906f, 0.0161133f, 0.205078f, 0.0161133f, 0.176514f, -0.0119629f, 0.147949f,
+-0.0400391f, 0.147949f, -0.0834961f, 0.147949f, -0.0991211f, 0.151855f, -0.116699f,
+0.208008f, -0.381348f, 0.152832f, -0.381348f, 0.13916f, -0.381348f, 0.134277f, -0.385742f,
+0.129395f, -0.390137f, 0.129395f, -0.397949f, 0.129395f, -0.407715f, 0.137451f, -0.415283f,
+0.145508f, -0.422852f, 0.161621f, -0.422852f, 0.257812f, -0.422852f, 0.192871f, -0.116699f,
+0.190918f, -0.106445f, 0.190918f, -0.0957031f, 0.190918f, -0.0634766f, 0.209961f,
+-0.0441895f, 0.229004f, -0.0249023f, 0.261719f, -0.0249023f, 0.362793f, -0.0249023f,
+0.465332f, -0.116699f, 0.521484f, -0.381348f, 0.445801f, -0.381348f, 0.432129f, -0.381348f,
+0.427246f, -0.385742f, 0.422363f, -0.390137f, 0.422363f, -0.397949f, 0.422363f, -0.407715f,
+0.43042f, -0.415283f, 0.438477f, -0.422852f, 0.45459f, -0.422852f, 0.571289f, -0.422852f,
+0.490234f, -0.0410156f, 0.524902f, -0.0410156f, 0.538574f, -0.0410156f, 0.543457f,
+-0.0368652f, 0.54834f, -0.0327148f, 0.54834f, -0.0249023f, 0.54834f, -0.0146484f,
+0.540283f, -0.00732422f, 0.532227f, 0, 0.516113f, 0, 0.278809f, 0, 0.169922f, -0.381348f,
+0.157715f, -0.381348f, 0.144043f, -0.381348f, 0.138916f, -0.385742f, 0.133789f, -0.390137f,
+0.133789f, -0.397949f, 0.133789f, -0.404297f, 0.137939f, -0.410645f, 0.14209f, -0.416992f,
+0.148193f, -0.419922f, 0.154297f, -0.422852f, 0.166504f, -0.422852f, 0.27832f, -0.422852f,
+0.289062f, -0.422852f, 0.292969f, -0.421143f, 0.296875f, -0.419434f, 0.299316f, -0.415527f,
+0.301758f, -0.411621f, 0.301758f, -0.40625f, 0.301758f, -0.396484f, 0.293701f, -0.388916f,
+0.285645f, -0.381348f, 0.269531f, -0.381348f, 0.214844f, -0.381348f, 0.310059f, -0.0449219f,
+0.546875f, -0.381348f, 0.492188f, -0.381348f, 0.478516f, -0.381348f, 0.473389f, -0.385742f,
+0.468262f, -0.390137f, 0.468262f, -0.397949f, 0.468262f, -0.407715f, 0.476318f, -0.415283f,
+0.484375f, -0.422852f, 0.500977f, -0.422852f, 0.612793f, -0.422852f, 0.626465f, -0.422852f,
+0.630371f, -0.418945f, 0.63623f, -0.414062f, 0.63623f, -0.40625f, 0.63623f, -0.399414f,
+0.631592f, -0.392822f, 0.626953f, -0.38623f, 0.620117f, -0.383301f, 0.614746f, -0.381348f,
+0.591309f, -0.381348f, 0.219238f, 0.147461f, 0.283203f, 0.147461f, 0.293945f, 0.147461f,
+0.297852f, 0.148926f, 0.301758f, 0.150391f, 0.304199f, 0.154541f, 0.306641f, 0.158691f,
+0.306641f, 0.163574f, 0.306641f, 0.173828f, 0.298584f, 0.181152f, 0.290527f, 0.188477f,
+0.274414f, 0.188477f, 0.0380859f, 0.188477f, 0.0244141f, 0.188477f, 0.0195312f, 0.184082f,
+0.0146484f, 0.179688f, 0.0146484f, 0.172363f, 0.0146484f, 0.162109f, 0.0227051f,
+0.154785f, 0.0307617f, 0.147461f, 0.046875f, 0.147461f, 0.175781f, 0.147461f
+};
+
+const unsigned char CourierNewkItalicVerbs[] = {
+6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1,
+1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1,
+1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 5, 6,
+0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1,
+1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0,
+1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1,
+2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1,
+1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 1, 1,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5,
+6, 0, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2,
+1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6
+};
+
+const unsigned CourierNewkItalicCharCodes[] = {
+32, 65,
+72, 84, 87, 89, 97, 98, 101, 102, 103, 109, 110, 111, 112, 114, 115, 117, 121
+};
+
+const SkFixed CourierNewkItalicWidths[] = {
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0
+};
+
+const int CourierNewkItalicCharCodesCount = (int) SK_ARRAY_COUNT(CourierNewkItalicCharCodes);
+
+const SkPaint::FontMetrics CourierNewkItalicMetrics = {
+0x00000003, -1.00049f, -0.83252f, 0.300293f, 0.273926f, 0, 0.923828f, 0, -0.123535f,
+0.800293f, 0.437988f, 0, 0.0410156f, 0.23291f
+};
+
+const SkScalar CourierNewkBoldItalicPoints[] = {
+0.456543f, -0.161133f, 0.213379f, -0.161133f, 0.175781f, -0.100098f, 0.200195f, -0.100098f,
+0.233887f, -0.100098f, 0.245605f, -0.0898438f, 0.257324f, -0.0795898f, 0.257324f,
+-0.0605469f, 0.257324f, -0.0302734f, 0.228516f, -0.0102539f, 0.213379f, 0, 0.179199f,
+0, 0.0439453f, 0, 0.0107422f, 0, -0.0012207f, -0.010498f, -0.0131836f, -0.0209961f,
+-0.0131836f, -0.0395508f, -0.0131836f, -0.0649414f, 0.00708008f, -0.0830078f, 0.0273438f,
+-0.101074f, 0.0678711f, -0.100098f, 0.308594f, -0.491699f, 0.242676f, -0.491699f,
+0.209473f, -0.491699f, 0.19751f, -0.502197f, 0.185547f, -0.512695f, 0.185547f, -0.531738f,
+0.185547f, -0.561523f, 0.213867f, -0.581543f, 0.229492f, -0.592285f, 0.26416f, -0.592285f,
+0.480469f, -0.592285f, 0.575195f, -0.100098f, 0.609375f, -0.101074f, 0.62207f, -0.090332f,
+0.634766f, -0.0795898f, 0.634766f, -0.0605469f, 0.634766f, -0.0302734f, 0.605469f,
+-0.0102539f, 0.59082f, 0, 0.556152f, 0, 0.421387f, 0, 0.388184f, 0, 0.376221f, -0.010498f,
+0.364258f, -0.0209961f, 0.364258f, -0.0395508f, 0.364258f, -0.0693359f, 0.392578f,
+-0.0893555f, 0.408203f, -0.100098f, 0.442871f, -0.100098f, 0.467285f, -0.100098f,
+0.436035f, -0.26123f, 0.397461f, -0.459473f, 0.274414f, -0.26123f, 0.461426f, -0.245117f,
+0.247559f, -0.245117f, 0.216797f, -0.100098f, 0.232422f, -0.100098f, 0.266113f, -0.100098f,
+0.277832f, -0.0898438f, 0.289551f, -0.0795898f, 0.289551f, -0.0605469f, 0.289551f,
+-0.0302734f, 0.260742f, -0.0102539f, 0.245605f, 0, 0.211426f, 0, 0.0883789f, 0, 0.0551758f,
+0, 0.0432129f, -0.010498f, 0.03125f, -0.0209961f, 0.03125f, -0.0395508f, 0.03125f,
+-0.0708008f, 0.0615234f, -0.0908203f, 0.0761719f, -0.100586f, 0.116699f, -0.100098f,
+0.199707f, -0.491699f, 0.177246f, -0.493652f, 0.166748f, -0.50415f, 0.15625f, -0.514648f,
+0.15625f, -0.531738f, 0.15625f, -0.561523f, 0.185059f, -0.581543f, 0.200195f, -0.592285f,
+0.234863f, -0.592285f, 0.336914f, -0.591797f, 0.370605f, -0.591797f, 0.382568f, -0.581543f,
+0.394531f, -0.571289f, 0.394531f, -0.552246f, 0.394531f, -0.521973f, 0.365234f, -0.501953f,
+0.350098f, -0.491699f, 0.315918f, -0.491699f, 0.299805f, -0.491699f, 0.269043f, -0.345215f,
+0.48291f, -0.345215f, 0.51416f, -0.491699f, 0.498047f, -0.491699f, 0.464844f, -0.491699f,
+0.452881f, -0.502197f, 0.440918f, -0.512695f, 0.440918f, -0.531738f, 0.440918f, -0.561523f,
+0.469238f, -0.581543f, 0.484863f, -0.592285f, 0.519531f, -0.592285f, 0.621582f, -0.591797f,
+0.655273f, -0.591797f, 0.666992f, -0.581543f, 0.678711f, -0.571289f, 0.678711f, -0.552246f,
+0.678711f, -0.529785f, 0.661377f, -0.512207f, 0.644043f, -0.494629f, 0.614258f, -0.491699f,
+0.530762f, -0.100098f, 0.570801f, -0.100098f, 0.581055f, -0.0917969f, 0.594727f,
+-0.0800781f, 0.594727f, -0.0605469f, 0.594727f, -0.0302734f, 0.565918f, -0.0102539f,
+0.550781f, 0, 0.516602f, 0, 0.393555f, 0, 0.360352f, 0, 0.348389f, -0.010498f, 0.336426f,
+-0.0209961f, 0.336426f, -0.0395508f, 0.336426f, -0.0693359f, 0.364746f, -0.0893555f,
+0.380371f, -0.100098f, 0.415039f, -0.100098f, 0.430664f, -0.100098f, 0.453125f, -0.491699f,
+0.370117f, -0.100098f, 0.4375f, -0.100098f, 0.470703f, -0.100098f, 0.482666f, -0.0895996f,
+0.494629f, -0.0791016f, 0.494629f, -0.0605469f, 0.494629f, -0.0307617f, 0.466309f,
+-0.0107422f, 0.450684f, 0, 0.416016f, 0, 0.181152f, 0, 0.147949f, 0, 0.135986f, -0.010498f,
+0.124023f, -0.0209961f, 0.124023f, -0.0395508f, 0.124023f, -0.0698242f, 0.152344f,
+-0.0893555f, 0.167969f, -0.100098f, 0.202637f, -0.100098f, 0.27002f, -0.100098f,
+0.353027f, -0.491699f, 0.244629f, -0.491699f, 0.224609f, -0.396973f, 0.216797f, -0.36084f,
+0.199707f, -0.345459f, 0.182617f, -0.330078f, 0.159668f, -0.330078f, 0.142578f, -0.330078f,
+0.131348f, -0.341064f, 0.120117f, -0.352051f, 0.120117f, -0.366699f, 0.120117f, -0.376953f,
+0.124512f, -0.396973f, 0.166016f, -0.591797f, 0.684082f, -0.591797f, 0.642578f, -0.396973f,
+0.635254f, -0.36084f, 0.61792f, -0.345459f, 0.600586f, -0.330078f, 0.578125f, -0.330078f,
+0.561035f, -0.330078f, 0.549805f, -0.341064f, 0.538574f, -0.352051f, 0.538574f, -0.366699f,
+0.538574f, -0.376953f, 0.54248f, -0.396973f, 0.562988f, -0.491699f, 0.36084f, -0.28418f,
+0.20752f, 0, 0.0952148f, 0, 0.140137f, -0.491699f, 0.121094f, -0.494141f, 0.111816f,
+-0.503906f, 0.102539f, -0.513672f, 0.102539f, -0.52832f, 0.102539f, -0.560547f, 0.131348f,
+-0.581055f, 0.146484f, -0.592285f, 0.181641f, -0.592285f, 0.31543f, -0.591797f, 0.349121f,
+-0.591797f, 0.36084f, -0.581543f, 0.372559f, -0.571289f, 0.372559f, -0.552246f, 0.372559f,
+-0.522461f, 0.344238f, -0.502441f, 0.329102f, -0.491699f, 0.293945f, -0.491699f,
+0.241699f, -0.491699f, 0.215332f, -0.211914f, 0.343262f, -0.444824f, 0.447754f, -0.444824f,
+0.476074f, -0.211914f, 0.568848f, -0.491699f, 0.516602f, -0.491699f, 0.48291f, -0.491699f,
+0.470947f, -0.502197f, 0.458984f, -0.512695f, 0.458984f, -0.531738f, 0.458984f, -0.561523f,
+0.487793f, -0.581543f, 0.50293f, -0.592285f, 0.537598f, -0.592285f, 0.670898f, -0.591797f,
+0.704102f, -0.591797f, 0.716064f, -0.581543f, 0.728027f, -0.571289f, 0.728027f, -0.552246f,
+0.728027f, -0.53125f, 0.712158f, -0.513672f, 0.696289f, -0.496094f, 0.668945f, -0.491699f,
+0.506836f, 0, 0.395996f, 0, 0.40332f, -0.248535f, 0.37207f, -0.100098f, 0.438965f,
+-0.100098f, 0.472656f, -0.100098f, 0.484619f, -0.0898438f, 0.496582f, -0.0795898f,
+0.496582f, -0.0605469f, 0.496582f, -0.0302734f, 0.467285f, -0.0102539f, 0.452148f,
+0, 0.417969f, 0, 0.183105f, 0, 0.149902f, 0, 0.137939f, -0.010498f, 0.125977f, -0.0209961f,
+0.125977f, -0.0395508f, 0.125977f, -0.0698242f, 0.154297f, -0.0893555f, 0.169922f,
+-0.100098f, 0.20459f, -0.100098f, 0.271973f, -0.100098f, 0.303223f, -0.248535f, 0.189453f,
+-0.491699f, 0.158691f, -0.491699f, 0.146729f, -0.502441f, 0.134766f, -0.513184f,
+0.134766f, -0.531738f, 0.134766f, -0.561523f, 0.163574f, -0.581543f, 0.178711f, -0.592285f,
+0.213379f, -0.592285f, 0.304688f, -0.591797f, 0.338379f, -0.591797f, 0.350098f, -0.581543f,
+0.361816f, -0.571289f, 0.361816f, -0.552246f, 0.361816f, -0.53418f, 0.349854f, -0.518311f,
+0.337891f, -0.502441f, 0.310547f, -0.491699f, 0.375488f, -0.352051f, 0.498047f, -0.491699f,
+0.467285f, -0.504883f, 0.467285f, -0.531738f, 0.467285f, -0.561523f, 0.495605f, -0.581543f,
+0.510742f, -0.591797f, 0.545898f, -0.591797f, 0.639648f, -0.591797f, 0.67334f, -0.591797f,
+0.685059f, -0.581543f, 0.696777f, -0.571289f, 0.696777f, -0.552246f, 0.696777f, -0.522949f,
+0.669434f, -0.50293f, 0.65332f, -0.491699f, 0.619141f, -0.491699f, 0.389648f, 0,
+0.394531f, -0.0234375f, 0.311035f, 0.0161133f, 0.217773f, 0.0161133f, 0.148438f,
+0.0161133f, 0.107422f, -0.019043f, 0.0664062f, -0.0541992f, 0.0664062f, -0.0991211f,
+0.0664062f, -0.135742f, 0.0947266f, -0.17627f, 0.132812f, -0.230957f, 0.199463f,
+-0.26123f, 0.266113f, -0.291504f, 0.347168f, -0.291504f, 0.39209f, -0.291504f, 0.449707f,
+-0.281738f, 0.45459f, -0.305664f, 0.455566f, -0.310547f, 0.455566f, -0.31543f, 0.455566f,
+-0.333496f, 0.441406f, -0.343262f, 0.422852f, -0.356445f, 0.372559f, -0.356445f,
+0.32666f, -0.356445f, 0.253906f, -0.338867f, 0.226562f, -0.33252f, 0.210938f, -0.33252f,
+0.194824f, -0.33252f, 0.184082f, -0.343262f, 0.17334f, -0.354004f, 0.17334f, -0.371582f,
+0.17334f, -0.395996f, 0.188965f, -0.411865f, 0.20459f, -0.427734f, 0.274658f, -0.442139f,
+0.344727f, -0.456543f, 0.39502f, -0.456543f, 0.477051f, -0.456543f, 0.517822f, -0.422607f,
+0.558594f, -0.388672f, 0.558594f, -0.339844f, 0.558594f, -0.324219f, 0.555176f, -0.306152f,
+0.51123f, -0.100098f, 0.52832f, -0.100098f, 0.562012f, -0.100098f, 0.57373f, -0.0898438f,
+0.585449f, -0.0795898f, 0.585449f, -0.0605469f, 0.585449f, -0.0302734f, 0.556641f,
+-0.0102539f, 0.541504f, 0, 0.507324f, 0, 0.427734f, -0.179199f, 0.370605f, -0.190918f,
+0.319336f, -0.190918f, 0.25293f, -0.190918f, 0.199219f, -0.155273f, 0.168457f, -0.135254f,
+0.168457f, -0.117188f, 0.168457f, -0.102539f, 0.189697f, -0.0930176f, 0.210938f,
+-0.0834961f, 0.244141f, -0.0834961f, 0.278809f, -0.0834961f, 0.327881f, -0.0974121f,
+0.376953f, -0.111328f, 0.418457f, -0.13623f, 0.308594f, -0.633301f, 0.26123f, -0.408691f,
+0.344238f, -0.456543f, 0.422852f, -0.456543f, 0.511719f, -0.456543f, 0.567871f, -0.401611f,
+0.624023f, -0.34668f, 0.624023f, -0.265625f, 0.624023f, -0.195801f, 0.58667f, -0.12915f,
+0.549316f, -0.0625f, 0.475342f, -0.0231934f, 0.401367f, 0.0161133f, 0.319336f, 0.0161133f,
+0.239258f, 0.0161133f, 0.179199f, -0.0244141f, 0.173828f, 0, 0.0566406f, 0, 0.0234375f,
+0, 0.0114746f, -0.010498f, -0.000488281f, -0.0209961f, -0.000488281f, -0.0395508f,
+-0.000488281f, -0.0693359f, 0.027832f, -0.0893555f, 0.043457f, -0.100098f, 0.078125f,
+-0.100098f, 0.0952148f, -0.100098f, 0.187012f, -0.533203f, 0.169922f, -0.533203f,
+0.136719f, -0.533203f, 0.124756f, -0.543701f, 0.112793f, -0.554199f, 0.112793f, -0.572754f,
+0.112793f, -0.602539f, 0.141113f, -0.622559f, 0.156738f, -0.633301f, 0.191406f, -0.633301f,
+0.34082f, -0.0839844f, 0.422852f, -0.0839844f, 0.471924f, -0.129395f, 0.520996f,
+-0.174805f, 0.520996f, -0.242676f, 0.520996f, -0.291016f, 0.487305f, -0.32373f, 0.453613f,
+-0.356445f, 0.399414f, -0.356445f, 0.327148f, -0.356445f, 0.271484f, -0.302246f,
+0.21582f, -0.248047f, 0.21582f, -0.181641f, 0.21582f, -0.138672f, 0.24707f, -0.111328f,
+0.27832f, -0.0839844f, 0.34082f, -0.0839844f, 0.587891f, -0.170898f, 0.177246f, -0.170898f,
+0.184082f, -0.132324f, 0.218262f, -0.108154f, 0.252441f, -0.0839844f, 0.320801f,
+-0.0839844f, 0.377441f, -0.0839844f, 0.474609f, -0.10791f, 0.515137f, -0.117676f,
+0.530273f, -0.117676f, 0.546387f, -0.117676f, 0.557129f, -0.107178f, 0.567871f, -0.0966797f,
+0.567871f, -0.0795898f, 0.567871f, -0.0546875f, 0.545654f, -0.0354004f, 0.523438f,
+-0.0161133f, 0.440918f, 0, 0.358398f, 0.0161133f, 0.291992f, 0.0161133f, 0.1875f,
+0.0161133f, 0.130615f, -0.036377f, 0.0737305f, -0.0888672f, 0.0737305f, -0.17041f,
+0.0737305f, -0.238281f, 0.11499f, -0.306641f, 0.15625f, -0.375f, 0.232666f, -0.415771f,
+0.309082f, -0.456543f, 0.389648f, -0.456543f, 0.484375f, -0.456543f, 0.543213f, -0.404297f,
+0.602051f, -0.352051f, 0.602051f, -0.258301f, 0.602051f, -0.238281f, 0.597168f, -0.213379f,
+0.498047f, -0.270996f, 0.484863f, -0.312012f, 0.452148f, -0.334229f, 0.419434f, -0.356445f,
+0.368164f, -0.356445f, 0.316895f, -0.356445f, 0.275391f, -0.335205f, 0.233887f, -0.313965f,
+0.20166f, -0.270996f, 0.37207f, -0.343262f, 0.320801f, -0.100098f, 0.462891f, -0.100098f,
+0.496582f, -0.100098f, 0.508301f, -0.0898438f, 0.52002f, -0.0795898f, 0.52002f, -0.0605469f,
+0.52002f, -0.0302734f, 0.491211f, -0.0102539f, 0.476074f, 0, 0.441895f, 0, 0.13916f,
+0, 0.105957f, 0, 0.0939941f, -0.010498f, 0.0820312f, -0.0209961f, 0.0820312f, -0.0395508f,
+0.0820312f, -0.0698242f, 0.110352f, -0.0893555f, 0.125977f, -0.100098f, 0.160645f,
+-0.100098f, 0.220703f, -0.100098f, 0.271973f, -0.343262f, 0.224121f, -0.343262f,
+0.190918f, -0.343262f, 0.178711f, -0.35376f, 0.166504f, -0.364258f, 0.166504f, -0.382812f,
+0.166504f, -0.412109f, 0.194336f, -0.432129f, 0.209961f, -0.443359f, 0.245117f, -0.443359f,
+0.293457f, -0.443359f, 0.301758f, -0.481445f, 0.31543f, -0.547852f, 0.373779f, -0.590576f,
+0.432129f, -0.633301f, 0.524902f, -0.633301f, 0.561035f, -0.633301f, 0.61377f, -0.626465f,
+0.666504f, -0.619629f, 0.680176f, -0.608398f, 0.693848f, -0.597168f, 0.693848f, -0.57959f,
+0.693848f, -0.555176f, 0.675537f, -0.536377f, 0.657227f, -0.517578f, 0.634277f, -0.517578f,
+0.625488f, -0.517578f, 0.606934f, -0.520996f, 0.547363f, -0.533203f, 0.499512f, -0.533203f,
+0.450195f, -0.533203f, 0.428223f, -0.518311f, 0.40625f, -0.503418f, 0.401855f, -0.481445f,
+0.393555f, -0.443359f, 0.547852f, -0.443359f, 0.581055f, -0.443359f, 0.593018f, -0.432861f,
+0.60498f, -0.422363f, 0.60498f, -0.403809f, 0.60498f, -0.374023f, 0.57666f, -0.354004f,
+0.561523f, -0.343262f, 0.526367f, -0.343262f, 0.486328f, -0.423828f, 0.504395f, -0.443359f,
+0.621582f, -0.443359f, 0.655273f, -0.443359f, 0.667236f, -0.432861f, 0.679199f, -0.422363f,
+0.679199f, -0.40332f, 0.679199f, -0.374512f, 0.651367f, -0.354492f, 0.635742f, -0.343262f,
+0.600586f, -0.343262f, 0.583496f, -0.343262f, 0.505859f, 0.0209961f, 0.494629f, 0.0727539f,
+0.4646f, 0.112061f, 0.43457f, 0.151367f, 0.381836f, 0.180176f, 0.329102f, 0.208984f,
+0.271973f, 0.208984f, 0.158691f, 0.208984f, 0.125488f, 0.208984f, 0.113525f, 0.19873f,
+0.101562f, 0.188477f, 0.101562f, 0.169434f, 0.101562f, 0.13916f, 0.130371f, 0.119141f,
+0.145508f, 0.108887f, 0.179688f, 0.108887f, 0.290039f, 0.108887f, 0.335938f, 0.108887f,
+0.366699f, 0.0842285f, 0.397461f, 0.0595703f, 0.405762f, 0.0209961f, 0.416016f, -0.027832f,
+0.378418f, -0.00634766f, 0.341553f, 0.00439453f, 0.304688f, 0.0151367f, 0.268555f,
+0.0151367f, 0.180664f, 0.0151367f, 0.127197f, -0.0368652f, 0.0737305f, -0.0888672f,
+0.0737305f, -0.167969f, 0.0737305f, -0.23877f, 0.112549f, -0.307129f, 0.151367f,
+-0.375488f, 0.222412f, -0.416748f, 0.293457f, -0.458008f, 0.370117f, -0.458008f,
+0.401855f, -0.458008f, 0.42749f, -0.450439f, 0.453125f, -0.442871f, 0.486328f, -0.423828f,
+0.288086f, -0.0854492f, 0.355469f, -0.0854492f, 0.407715f, -0.135986f, 0.459961f,
+-0.186523f, 0.459961f, -0.25f, 0.459961f, -0.29541f, 0.428223f, -0.32666f, 0.396484f,
+-0.35791f, 0.348633f, -0.35791f, 0.28125f, -0.35791f, 0.229004f, -0.306885f, 0.176758f,
+-0.255859f, 0.176758f, -0.194336f, 0.176758f, -0.147461f, 0.208252f, -0.116455f,
+0.239746f, -0.0854492f, 0.288086f, -0.0854492f, 0.231934f, -0.443359f, 0.228516f,
+-0.413574f, 0.260254f, -0.437988f, 0.282471f, -0.447266f, 0.304688f, -0.456543f,
+0.328125f, -0.456543f, 0.375977f, -0.456543f, 0.408691f, -0.414062f, 0.438965f, -0.435547f,
+0.468018f, -0.446045f, 0.49707f, -0.456543f, 0.525391f, -0.456543f, 0.57666f, -0.456543f,
+0.606201f, -0.428223f, 0.635742f, -0.399902f, 0.635742f, -0.353516f, 0.635742f, -0.339844f,
+0.632324f, -0.324219f, 0.584961f, -0.100098f, 0.61377f, -0.100098f, 0.625488f, -0.0895996f,
+0.637207f, -0.0791016f, 0.637207f, -0.0605469f, 0.637207f, -0.0302734f, 0.608398f,
+-0.0102539f, 0.593262f, 0, 0.558594f, 0, 0.463379f, 0, 0.530762f, -0.315918f, 0.532715f,
+-0.32666f, 0.532715f, -0.334961f, 0.532715f, -0.344727f, 0.526123f, -0.350586f, 0.519531f,
+-0.356445f, 0.505859f, -0.356445f, 0.489258f, -0.356445f, 0.474121f, -0.347656f,
+0.452637f, -0.335938f, 0.419434f, -0.301758f, 0.376465f, -0.100098f, 0.405273f, -0.100098f,
+0.416992f, -0.0895996f, 0.428711f, -0.0791016f, 0.428711f, -0.0605469f, 0.428711f,
+-0.0302734f, 0.399902f, -0.0102539f, 0.384766f, 0, 0.350098f, 0, 0.254883f, 0, 0.322266f,
+-0.315918f, 0.324219f, -0.326172f, 0.324219f, -0.334473f, 0.324219f, -0.344238f,
+0.317383f, -0.350342f, 0.310547f, -0.356445f, 0.297363f, -0.356445f, 0.279297f, -0.356445f,
+0.262695f, -0.347168f, 0.240723f, -0.334961f, 0.209473f, -0.301758f, 0.166504f, -0.100098f,
+0.195312f, -0.100098f, 0.207031f, -0.0895996f, 0.21875f, -0.0791016f, 0.21875f, -0.0605469f,
+0.21875f, -0.0302734f, 0.189941f, -0.0102539f, 0.174805f, 0, 0.140137f, 0, 0.0498047f,
+0, 0.0166016f, 0, 0.00463867f, -0.010498f, -0.00732422f, -0.0209961f, -0.00732422f,
+-0.0395508f, -0.00732422f, -0.0639648f, 0.0124512f, -0.0822754f, 0.0322266f, -0.100586f,
+0.0664062f, -0.100098f, 0.118164f, -0.343262f, 0.0888672f, -0.343262f, 0.0771484f,
+-0.354004f, 0.0654297f, -0.364746f, 0.0654297f, -0.382812f, 0.0654297f, -0.412109f,
+0.0932617f, -0.432129f, 0.108887f, -0.443359f, 0.144043f, -0.443359f, 0.29248f, -0.443359f,
+0.288086f, -0.409668f, 0.321777f, -0.435059f, 0.352051f, -0.445801f, 0.382324f, -0.456543f,
+0.421875f, -0.456543f, 0.498535f, -0.456543f, 0.538086f, -0.421631f, 0.577637f, -0.386719f,
+0.577637f, -0.330566f, 0.577637f, -0.310059f, 0.572754f, -0.286133f, 0.533203f, -0.100098f,
+0.562012f, -0.100098f, 0.57373f, -0.0895996f, 0.585449f, -0.0791016f, 0.585449f,
+-0.0605469f, 0.585449f, -0.0302734f, 0.556641f, -0.0102539f, 0.541504f, 0, 0.506836f,
+0, 0.416504f, 0, 0.383301f, 0, 0.371338f, -0.010498f, 0.359375f, -0.0209961f, 0.359375f,
+-0.0395508f, 0.359375f, -0.0639648f, 0.37915f, -0.0822754f, 0.398926f, -0.100586f,
+0.433105f, -0.100098f, 0.473145f, -0.289062f, 0.475586f, -0.300781f, 0.475586f, -0.311035f,
+0.475586f, -0.330078f, 0.460938f, -0.341309f, 0.440918f, -0.356445f, 0.401367f, -0.356445f,
+0.367188f, -0.356445f, 0.338135f, -0.343262f, 0.309082f, -0.330078f, 0.259277f, -0.286133f,
+0.219727f, -0.100098f, 0.259277f, -0.100098f, 0.269531f, -0.0917969f, 0.283691f,
+-0.0800781f, 0.283691f, -0.0605469f, 0.283691f, -0.0302734f, 0.254883f, -0.0102539f,
+0.239746f, 0, 0.205078f, 0, 0.0913086f, 0, 0.0581055f, 0, 0.0461426f, -0.010498f,
+0.0341797f, -0.0209961f, 0.0341797f, -0.0395508f, 0.0341797f, -0.0708008f, 0.0644531f,
+-0.0908203f, 0.0791016f, -0.100098f, 0.119629f, -0.100098f, 0.171387f, -0.343262f,
+0.142578f, -0.343262f, 0.130615f, -0.354004f, 0.118652f, -0.364746f, 0.118652f, -0.382812f,
+0.118652f, -0.412109f, 0.146484f, -0.432129f, 0.162109f, -0.443359f, 0.197266f, -0.443359f,
+0.29834f, 0.0161133f, 0.236328f, 0.0161133f, 0.185303f, -0.0090332f, 0.134277f, -0.0341797f,
+0.108643f, -0.0771484f, 0.0830078f, -0.120117f, 0.0830078f, -0.170898f, 0.0830078f,
+-0.233887f, 0.125977f, -0.304199f, 0.168945f, -0.374512f, 0.245605f, -0.415527f,
+0.322266f, -0.456543f, 0.401855f, -0.456543f, 0.458984f, -0.456543f, 0.509277f, -0.430176f,
+0.55957f, -0.403809f, 0.584961f, -0.359619f, 0.610352f, -0.31543f, 0.610352f, -0.262695f,
+0.610352f, -0.194336f, 0.570068f, -0.12915f, 0.529785f, -0.0639648f, 0.452881f, -0.0239258f,
+0.375977f, 0.0161133f, 0.29834f, 0.0161133f, 0.318848f, -0.0839844f, 0.395508f, -0.0839844f,
+0.45166f, -0.133057f, 0.507812f, -0.182129f, 0.507812f, -0.23584f, 0.507812f, -0.288086f,
+0.472168f, -0.322266f, 0.436523f, -0.356445f, 0.377441f, -0.356445f, 0.293457f, -0.356445f,
+0.233398f, -0.293945f, 0.185547f, -0.243652f, 0.185547f, -0.193359f, 0.185547f, -0.150879f,
+0.222412f, -0.117432f, 0.259277f, -0.0839844f, 0.318848f, -0.0839844f, 0.187988f,
+-0.0551758f, 0.152832f, 0.108887f, 0.212891f, 0.108887f, 0.246094f, 0.108887f, 0.258057f,
+0.119385f, 0.27002f, 0.129883f, 0.27002f, 0.148438f, 0.27002f, 0.179199f, 0.241211f,
+0.19873f, 0.226074f, 0.208984f, 0.191406f, 0.208984f, 0.0141602f, 0.208984f, -0.019043f,
+0.208984f, -0.0310059f, 0.19873f, -0.0429688f, 0.188477f, -0.0429688f, 0.169434f,
+-0.0429688f, 0.139648f, -0.0146484f, 0.119629f, 0.000976562f, 0.108887f, 0.0356445f,
+0.108887f, 0.0527344f, 0.108887f, 0.148926f, -0.343262f, 0.131836f, -0.343262f, 0.0981445f,
+-0.343262f, 0.0861816f, -0.35376f, 0.0742188f, -0.364258f, 0.0742188f, -0.382812f,
+0.0742188f, -0.412109f, 0.102051f, -0.432129f, 0.117676f, -0.443359f, 0.152832f,
+-0.443359f, 0.27002f, -0.443359f, 0.263184f, -0.40918f, 0.343262f, -0.456543f, 0.42334f,
+-0.456543f, 0.512695f, -0.456543f, 0.569336f, -0.401855f, 0.625977f, -0.347168f,
+0.625977f, -0.269043f, 0.625977f, -0.208008f, 0.587158f, -0.146973f, 0.54834f, -0.0859375f,
+0.473877f, -0.0480957f, 0.399414f, -0.0102539f, 0.32959f, -0.0102539f, 0.251953f,
+-0.0102539f, 0.187988f, -0.0551758f, 0.347656f, -0.110352f, 0.418945f, -0.110352f,
+0.470947f, -0.154541f, 0.522949f, -0.19873f, 0.522949f, -0.241699f, 0.522949f, -0.291016f,
+0.489258f, -0.32373f, 0.455566f, -0.356445f, 0.400879f, -0.356445f, 0.330566f, -0.356445f,
+0.276611f, -0.306641f, 0.222656f, -0.256836f, 0.222656f, -0.211426f, 0.222656f, -0.172852f,
+0.25708f, -0.141602f, 0.291504f, -0.110352f, 0.347656f, -0.110352f, 0.374023f, -0.443359f,
+0.36084f, -0.380859f, 0.434082f, -0.426758f, 0.473389f, -0.44165f, 0.512695f, -0.456543f,
+0.544434f, -0.456543f, 0.587402f, -0.456543f, 0.620117f, -0.429932f, 0.652832f, -0.40332f,
+0.652832f, -0.381348f, 0.652832f, -0.357422f, 0.633545f, -0.338379f, 0.614258f, -0.319336f,
+0.590332f, -0.319336f, 0.571777f, -0.319336f, 0.555176f, -0.337891f, 0.538574f, -0.356445f,
+0.522461f, -0.356445f, 0.504395f, -0.356445f, 0.463867f, -0.335938f, 0.42334f, -0.31543f,
+0.333008f, -0.250977f, 0.30127f, -0.100098f, 0.443359f, -0.100098f, 0.477051f, -0.100098f,
+0.48877f, -0.0898438f, 0.500488f, -0.0795898f, 0.500488f, -0.0605469f, 0.500488f,
+-0.0302734f, 0.47168f, -0.0102539f, 0.456543f, 0, 0.422363f, 0, 0.119629f, 0, 0.0864258f,
+0, 0.0744629f, -0.010498f, 0.0625f, -0.0209961f, 0.0625f, -0.0395508f, 0.0625f, -0.0698242f,
+0.0908203f, -0.0893555f, 0.106445f, -0.100098f, 0.141113f, -0.100098f, 0.201172f,
+-0.100098f, 0.252441f, -0.343262f, 0.216309f, -0.343262f, 0.183105f, -0.343262f,
+0.170898f, -0.35376f, 0.158691f, -0.364258f, 0.158691f, -0.382812f, 0.158691f, -0.412109f,
+0.186523f, -0.432129f, 0.202148f, -0.443359f, 0.237793f, -0.443359f, 0.477051f, -0.326172f,
+0.456055f, -0.341309f, 0.430908f, -0.348877f, 0.405762f, -0.356445f, 0.375977f, -0.356445f,
+0.328125f, -0.356445f, 0.294434f, -0.343506f, 0.260742f, -0.330566f, 0.260742f, -0.317383f,
+0.260742f, -0.308594f, 0.271973f, -0.300781f, 0.287109f, -0.290039f, 0.343262f, -0.282227f,
+0.430176f, -0.27002f, 0.470459f, -0.256836f, 0.510742f, -0.243652f, 0.534668f, -0.214355f,
+0.558594f, -0.185059f, 0.558594f, -0.149414f, 0.558594f, -0.0776367f, 0.481445f,
+-0.0307617f, 0.404297f, 0.0161133f, 0.302246f, 0.0161133f, 0.258789f, 0.0161133f,
+0.223145f, 0.00854492f, 0.1875f, 0.000976562f, 0.160156f, -0.0136719f, 0.14209f,
+-0.000488281f, 0.125488f, -0.000488281f, 0.106445f, -0.000488281f, 0.0949707f, -0.0114746f,
+0.0834961f, -0.0224609f, 0.0834961f, -0.0375977f, 0.0834961f, -0.0473633f, 0.0878906f,
+-0.0673828f, 0.0952148f, -0.101074f, 0.102539f, -0.137695f, 0.119873f, -0.152832f,
+0.137207f, -0.167969f, 0.159668f, -0.167969f, 0.177734f, -0.167969f, 0.1875f, -0.157959f,
+0.197266f, -0.147949f, 0.199219f, -0.123535f, 0.217773f, -0.104004f, 0.248047f, -0.0939941f,
+0.27832f, -0.0839844f, 0.320312f, -0.0839844f, 0.394043f, -0.0839844f, 0.436523f,
+-0.10791f, 0.455566f, -0.118652f, 0.455566f, -0.132324f, 0.455566f, -0.151367f, 0.432129f,
+-0.162598f, 0.408691f, -0.17334f, 0.333496f, -0.181641f, 0.225586f, -0.193359f, 0.191895f,
+-0.22168f, 0.158203f, -0.25f, 0.158203f, -0.294434f, 0.158203f, -0.333008f, 0.183105f,
+-0.367676f, 0.208008f, -0.402344f, 0.257812f, -0.42627f, 0.322266f, -0.456543f, 0.396484f,
+-0.456543f, 0.431152f, -0.456543f, 0.461914f, -0.449951f, 0.492676f, -0.443359f,
+0.519043f, -0.429688f, 0.540039f, -0.443359f, 0.553711f, -0.443359f, 0.569336f, -0.443359f,
+0.580566f, -0.432373f, 0.591797f, -0.421387f, 0.591797f, -0.406738f, 0.591797f, -0.396484f,
+0.587891f, -0.376465f, 0.58252f, -0.352051f, 0.574707f, -0.315918f, 0.557373f, -0.300537f,
+0.540039f, -0.285156f, 0.517578f, -0.285156f, 0.499512f, -0.285156f, 0.488281f, -0.296387f,
+0.477051f, -0.307617f, 0.477051f, -0.326172f, 0.606445f, -0.443359f, 0.533691f, -0.100098f,
+0.5625f, -0.100098f, 0.574219f, -0.0895996f, 0.585938f, -0.0791016f, 0.585938f, -0.0605469f,
+0.585938f, -0.0307617f, 0.557617f, -0.0107422f, 0.54248f, 0, 0.507324f, 0, 0.412109f,
+0, 0.416992f, -0.0229492f, 0.322754f, 0.0161133f, 0.25f, 0.0161133f, 0.192383f, 0.0161133f,
+0.157227f, -0.0163574f, 0.12207f, -0.0488281f, 0.12207f, -0.0976562f, 0.12207f, -0.111328f,
+0.125488f, -0.12793f, 0.170898f, -0.343262f, 0.153809f, -0.343262f, 0.120605f, -0.343262f,
+0.108643f, -0.35376f, 0.0966797f, -0.364258f, 0.0966797f, -0.382812f, 0.0966797f,
+-0.412598f, 0.125f, -0.432617f, 0.140137f, -0.443359f, 0.175293f, -0.443359f, 0.29248f,
+-0.443359f, 0.229004f, -0.145508f, 0.226074f, -0.130371f, 0.226074f, -0.121094f,
+0.226074f, -0.105957f, 0.239014f, -0.0949707f, 0.251953f, -0.0839844f, 0.277832f,
+-0.0839844f, 0.308594f, -0.0839844f, 0.345703f, -0.0957031f, 0.382812f, -0.107422f,
+0.441895f, -0.13916f, 0.485352f, -0.343262f, 0.44873f, -0.343262f, 0.415527f, -0.343262f,
+0.403564f, -0.35376f, 0.391602f, -0.364258f, 0.391602f, -0.382812f, 0.391602f, -0.412598f,
+0.419922f, -0.432617f, 0.435059f, -0.443359f, 0.470215f, -0.443359f, 0.244629f, -0.00341797f,
+0.143555f, -0.343262f, 0.122559f, -0.345703f, 0.112793f, -0.355957f, 0.103027f, -0.366211f,
+0.103027f, -0.382812f, 0.103027f, -0.412598f, 0.131348f, -0.432617f, 0.146484f, -0.443359f,
+0.181641f, -0.443359f, 0.272949f, -0.443359f, 0.306641f, -0.443359f, 0.318604f, -0.432861f,
+0.330566f, -0.422363f, 0.330566f, -0.403809f, 0.330566f, -0.379395f, 0.311035f, -0.361328f,
+0.291504f, -0.343262f, 0.254883f, -0.343262f, 0.32373f, -0.113281f, 0.489746f, -0.343262f,
+0.460449f, -0.343262f, 0.44873f, -0.354004f, 0.437012f, -0.364746f, 0.437012f, -0.382812f,
+0.437012f, -0.412109f, 0.464355f, -0.432129f, 0.47998f, -0.443359f, 0.515625f, -0.443359f,
+0.609375f, -0.443359f, 0.642578f, -0.443359f, 0.654541f, -0.432861f, 0.666504f, -0.422363f,
+0.666504f, -0.403809f, 0.666504f, -0.381348f, 0.649414f, -0.363525f, 0.632324f, -0.345703f,
+0.602539f, -0.343262f, 0.276855f, 0.108887f, 0.315918f, 0.108887f, 0.326172f, 0.117676f,
+0.340332f, 0.129395f, 0.340332f, 0.148438f, 0.340332f, 0.179199f, 0.311035f, 0.19873f,
+0.295898f, 0.208984f, 0.261719f, 0.208984f, 0.0429688f, 0.208984f, 0.00976562f, 0.208984f,
+-0.00219727f, 0.19873f, -0.0141602f, 0.188477f, -0.0141602f, 0.169434f, -0.0141602f,
+0.139648f, 0.0141602f, 0.119629f, 0.0297852f, 0.108887f, 0.0644531f, 0.108887f, 0.164062f,
+0.108887f
+};
+
+const unsigned char CourierNewkBoldItalicVerbs[] = {
+6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1,
+2, 2, 2, 2, 1, 5, 0, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1,
+2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1,
+1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6,
+0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2,
+2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2,
+1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2,
+2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1,
+2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6
+};
+
+const unsigned CourierNewkBoldItalicCharCodes[] = {
+32,
+65, 72, 84, 87, 89, 97, 98, 101, 102, 103, 109, 110, 111, 112, 114, 115, 117, 121
+};
+
+const SkFixed CourierNewkBoldItalicWidths[] = {
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0,
+0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0, 0x000099a0
+};
+
+const int CourierNewkBoldItalicCharCodesCount = (int) SK_ARRAY_COUNT(CourierNewkBoldItalicCharCodes);
+
+const SkPaint::FontMetrics CourierNewkBoldItalicMetrics = {
+0x2e302d23, -1.00391f, -0.83252f, 0.300293f, 0.376953f, 0, 0.941895f, 4.24199e-08f,
+-0.102539f, 0.839355f, 0.458008f, 1.53766e-13f, 0.100098f, 0.23291f
+};
+
+const SkScalar LiberationSanskNormalPoints[] = {
+0.175293f, -0.193848f, 0.103027f, -0.193848f, 0.0913086f, -0.687988f, 0.187012f, -0.687988f,
+0.090332f, 0, 0.090332f, -0.0981445f, 0.185059f, -0.0981445f, 0.185059f, 0, 0.4375f,
+-0.432129f, 0.399414f, -0.251953f, 0.526367f, -0.251953f, 0.526367f, -0.199219f,
+0.388184f, -0.199219f, 0.345215f, 0, 0.291504f, 0, 0.333496f, -0.199219f, 0.15625f,
+-0.199219f, 0.115234f, 0, 0.0615234f, 0, 0.102539f, -0.199219f, 0.00439453f, -0.199219f,
+0.00439453f, -0.251953f, 0.114258f, -0.251953f, 0.152344f, -0.432129f, 0.0292969f,
+-0.432129f, 0.0292969f, -0.484863f, 0.163086f, -0.484863f, 0.206543f, -0.684082f,
+0.260254f, -0.684082f, 0.217285f, -0.484863f, 0.394531f, -0.484863f, 0.4375f, -0.684082f,
+0.491211f, -0.684082f, 0.448242f, -0.484863f, 0.55127f, -0.484863f, 0.55127f, -0.432129f,
+0.20752f, -0.432129f, 0.168457f, -0.251953f, 0.345215f, -0.251953f, 0.383301f, -0.432129f,
+0.853516f, -0.211914f, 0.853516f, -0.150879f, 0.841064f, -0.109131f, 0.828613f, -0.0673828f,
+0.807373f, -0.041748f, 0.786133f, -0.0161133f, 0.757812f, -0.00512695f, 0.729492f,
+0.00585938f, 0.697266f, 0.00585938f, 0.665039f, 0.00585938f, 0.636963f, -0.00512695f,
+0.608887f, -0.0161133f, 0.588135f, -0.0415039f, 0.567383f, -0.0668945f, 0.55542f,
+-0.108643f, 0.543457f, -0.150391f, 0.543457f, -0.211914f, 0.543457f, -0.276855f,
+0.555176f, -0.319336f, 0.566895f, -0.361816f, 0.587891f, -0.386963f, 0.608887f, -0.412109f,
+0.637451f, -0.422119f, 0.666016f, -0.432129f, 0.699219f, -0.432129f, 0.731445f, -0.432129f,
+0.759521f, -0.422119f, 0.787598f, -0.412109f, 0.80835f, -0.386963f, 0.829102f, -0.361816f,
+0.841309f, -0.319336f, 0.853516f, -0.276855f, 0.853516f, -0.211914f, 0.257324f, 0,
+0.181641f, 0, 0.631836f, -0.687988f, 0.708496f, -0.687988f, 0.192383f, -0.693848f,
+0.223633f, -0.693848f, 0.251465f, -0.683838f, 0.279297f, -0.673828f, 0.300293f, -0.648926f,
+0.321289f, -0.624023f, 0.333252f, -0.582031f, 0.345215f, -0.540039f, 0.345215f, -0.476074f,
+0.345215f, -0.414551f, 0.333008f, -0.372559f, 0.320801f, -0.330566f, 0.300049f, -0.304443f,
+0.279297f, -0.27832f, 0.250977f, -0.26709f, 0.222656f, -0.255859f, 0.19043f, -0.255859f,
+0.157715f, -0.255859f, 0.129395f, -0.26709f, 0.101074f, -0.27832f, 0.0803223f, -0.304199f,
+0.0595703f, -0.330078f, 0.0476074f, -0.37207f, 0.0356445f, -0.414062f, 0.0356445f,
+-0.476074f, 0.0356445f, -0.540039f, 0.0476074f, -0.582031f, 0.0595703f, -0.624023f,
+0.0805664f, -0.648926f, 0.101562f, -0.673828f, 0.130371f, -0.683838f, 0.15918f, -0.693848f,
+0.192383f, -0.693848f, 0.78125f, -0.211914f, 0.78125f, -0.260254f, 0.775879f, -0.292236f,
+0.770508f, -0.324219f, 0.76001f, -0.343262f, 0.749512f, -0.362305f, 0.734131f, -0.370117f,
+0.71875f, -0.37793f, 0.699219f, -0.37793f, 0.678711f, -0.37793f, 0.663086f, -0.369873f,
+0.647461f, -0.361816f, 0.636719f, -0.342773f, 0.625977f, -0.32373f, 0.620605f, -0.291748f,
+0.615234f, -0.259766f, 0.615234f, -0.211914f, 0.615234f, -0.165527f, 0.62085f, -0.134277f,
+0.626465f, -0.103027f, 0.636963f, -0.0837402f, 0.647461f, -0.0644531f, 0.662842f,
+-0.0561523f, 0.678223f, -0.0478516f, 0.698242f, -0.0478516f, 0.717285f, -0.0478516f,
+0.732666f, -0.0561523f, 0.748047f, -0.0644531f, 0.758789f, -0.0837402f, 0.769531f,
+-0.103027f, 0.775391f, -0.134277f, 0.78125f, -0.165527f, 0.78125f, -0.211914f, 0.273438f,
+-0.476074f, 0.273438f, -0.523926f, 0.268066f, -0.555664f, 0.262695f, -0.587402f,
+0.252441f, -0.606445f, 0.242188f, -0.625488f, 0.227051f, -0.633301f, 0.211914f, -0.641113f,
+0.192383f, -0.641113f, 0.171387f, -0.641113f, 0.155518f, -0.633057f, 0.139648f, -0.625f,
+0.128906f, -0.605957f, 0.118164f, -0.586914f, 0.112793f, -0.555176f, 0.107422f, -0.523438f,
+0.107422f, -0.476074f, 0.107422f, -0.429688f, 0.113037f, -0.397949f, 0.118652f, -0.366211f,
+0.12915f, -0.346924f, 0.139648f, -0.327637f, 0.155273f, -0.319336f, 0.170898f, -0.311035f,
+0.191406f, -0.311035f, 0.209961f, -0.311035f, 0.225098f, -0.319336f, 0.240234f, -0.327637f,
+0.250977f, -0.346924f, 0.261719f, -0.366211f, 0.267578f, -0.397949f, 0.273438f, -0.429688f,
+0.273438f, -0.476074f, 0.58252f, 0.00585938f, 0.535645f, 0.00585938f, 0.500488f,
+-0.0102539f, 0.465332f, -0.0263672f, 0.437012f, -0.0561523f, 0.422363f, -0.043457f,
+0.403809f, -0.0317383f, 0.385254f, -0.0200195f, 0.362549f, -0.0107422f, 0.339844f,
+-0.00146484f, 0.313232f, 0.00415039f, 0.286621f, 0.00976562f, 0.255371f, 0.00976562f,
+0.198242f, 0.00976562f, 0.156494f, -0.00488281f, 0.114746f, -0.0195312f, 0.0878906f,
+-0.045166f, 0.0610352f, -0.0708008f, 0.0480957f, -0.105713f, 0.0351562f, -0.140625f,
+0.0351562f, -0.181152f, 0.0351562f, -0.219727f, 0.0476074f, -0.251221f, 0.0600586f,
+-0.282715f, 0.0822754f, -0.30835f, 0.104492f, -0.333984f, 0.135254f, -0.354248f,
+0.166016f, -0.374512f, 0.202637f, -0.390625f, 0.193848f, -0.407227f, 0.186768f, -0.426025f,
+0.179688f, -0.444824f, 0.174316f, -0.463867f, 0.168945f, -0.48291f, 0.166016f, -0.501953f,
+0.163086f, -0.520996f, 0.163086f, -0.538086f, 0.163086f, -0.570312f, 0.172852f, -0.598389f,
+0.182617f, -0.626465f, 0.203369f, -0.647217f, 0.224121f, -0.667969f, 0.256592f, -0.679932f,
+0.289062f, -0.691895f, 0.334473f, -0.691895f, 0.370117f, -0.691895f, 0.400146f, -0.682617f,
+0.430176f, -0.67334f, 0.452148f, -0.655762f, 0.474121f, -0.638184f, 0.486328f, -0.612305f,
+0.498535f, -0.586426f, 0.498535f, -0.553223f, 0.498535f, -0.516602f, 0.482422f, -0.488037f,
+0.466309f, -0.459473f, 0.438965f, -0.437012f, 0.411621f, -0.414551f, 0.375488f, -0.39624f,
+0.339355f, -0.37793f, 0.298828f, -0.361816f, 0.329102f, -0.306152f, 0.364746f, -0.25708f,
+0.400391f, -0.208008f, 0.441895f, -0.160645f, 0.47168f, -0.20459f, 0.491455f, -0.253174f,
+0.51123f, -0.301758f, 0.525391f, -0.36084f, 0.596191f, -0.339844f, 0.579102f, -0.271973f,
+0.552979f, -0.216553f, 0.526855f, -0.161133f, 0.492676f, -0.11084f, 0.518555f, -0.0844727f,
+0.544434f, -0.0737305f, 0.570312f, -0.0629883f, 0.594238f, -0.0629883f, 0.609863f,
+-0.0629883f, 0.624268f, -0.0646973f, 0.638672f, -0.0664062f, 0.651367f, -0.0708008f,
+0.651367f, -0.00488281f, 0.637695f, 0.000488281f, 0.619385f, 0.00317383f, 0.601074f,
+0.00585938f, 0.58252f, 0.00585938f, 0.424316f, -0.553223f, 0.424316f, -0.571289f,
+0.417725f, -0.585938f, 0.411133f, -0.600586f, 0.399414f, -0.611084f, 0.387695f, -0.621582f,
+0.37085f, -0.627197f, 0.354004f, -0.632812f, 0.333496f, -0.632812f, 0.286621f, -0.632812f,
+0.262207f, -0.607666f, 0.237793f, -0.58252f, 0.237793f, -0.538086f, 0.237793f, -0.509277f,
+0.246826f, -0.477783f, 0.255859f, -0.446289f, 0.269531f, -0.418945f, 0.30127f, -0.431641f,
+0.32959f, -0.445068f, 0.35791f, -0.458496f, 0.378906f, -0.474365f, 0.399902f, -0.490234f,
+0.412109f, -0.509521f, 0.424316f, -0.528809f, 0.424316f, -0.553223f, 0.388184f, -0.105957f,
+0.344727f, -0.157227f, 0.304688f, -0.213379f, 0.264648f, -0.269531f, 0.232422f, -0.329102f,
+0.177246f, -0.305664f, 0.147217f, -0.269531f, 0.117188f, -0.233398f, 0.117188f, -0.182129f,
+0.117188f, -0.155273f, 0.125732f, -0.13208f, 0.134277f, -0.108887f, 0.151855f, -0.0915527f,
+0.169434f, -0.0742188f, 0.196045f, -0.064209f, 0.222656f, -0.0541992f, 0.258301f,
+-0.0541992f, 0.279785f, -0.0541992f, 0.299072f, -0.0588379f, 0.318359f, -0.0634766f,
+0.334961f, -0.0708008f, 0.351562f, -0.078125f, 0.36499f, -0.0874023f, 0.378418f,
+-0.0966797f, 0.388184f, -0.105957f, 0.129883f, -0.47168f, 0.0610352f, -0.47168f,
+0.0507812f, -0.687988f, 0.140625f, -0.687988f, 0.270996f, -0.257812f, 0.270996f,
+-0.189453f, 0.260742f, -0.127686f, 0.250488f, -0.065918f, 0.228516f, -0.00878906f,
+0.206543f, 0.0483398f, 0.172363f, 0.102051f, 0.138184f, 0.155762f, 0.0908203f, 0.207031f,
+0.00585938f, 0.207031f, 0.0517578f, 0.155762f, 0.0852051f, 0.102051f, 0.118652f,
+0.0483398f, 0.140137f, -0.00927734f, 0.161621f, -0.0668945f, 0.172119f, -0.128906f,
+0.182617f, -0.190918f, 0.182617f, -0.258789f, 0.182617f, -0.32666f, 0.172119f, -0.388672f,
+0.161621f, -0.450684f, 0.140137f, -0.508057f, 0.118652f, -0.56543f, 0.0852051f, -0.619385f,
+0.0517578f, -0.67334f, 0.00585938f, -0.724609f, 0.0908203f, -0.724609f, 0.138184f,
+-0.67334f, 0.172363f, -0.619629f, 0.206543f, -0.565918f, 0.228516f, -0.508789f, 0.250488f,
+-0.45166f, 0.260742f, -0.389648f, 0.270996f, -0.327637f, 0.270996f, -0.259766f, 0.222656f,
+-0.543945f, 0.351562f, -0.594238f, 0.373535f, -0.529785f, 0.23584f, -0.494141f, 0.326172f,
+-0.37207f, 0.268066f, -0.336914f, 0.194824f, -0.462891f, 0.118652f, -0.337891f, 0.0605469f,
+-0.373047f, 0.152832f, -0.494141f, 0.0161133f, -0.529785f, 0.0380859f, -0.595215f,
+0.168457f, -0.542969f, 0.162598f, -0.687988f, 0.229004f, -0.687988f, 0.327637f, -0.296875f,
+0.327637f, -0.0878906f, 0.255859f, -0.0878906f, 0.255859f, -0.296875f, 0.0488281f,
+-0.296875f, 0.0488281f, -0.368164f, 0.255859f, -0.368164f, 0.255859f, -0.577148f,
+0.327637f, -0.577148f, 0.327637f, -0.368164f, 0.534668f, -0.368164f, 0.534668f, -0.296875f,
+0.0444336f, -0.226562f, 0.0444336f, -0.304688f, 0.288574f, -0.304688f, 0.288574f,
+-0.226562f, 0.0913086f, 0, 0.0913086f, -0.106934f, 0.186523f, -0.106934f, 0.186523f,
+0, 0, 0.00976562f, 0.200684f, -0.724609f, 0.277832f, -0.724609f, 0.0791016f, 0.00976562f,
+0.0761719f, 0, 0.0761719f, -0.074707f, 0.251465f, -0.074707f, 0.251465f, -0.604004f,
+0.0961914f, -0.493164f, 0.0961914f, -0.576172f, 0.258789f, -0.687988f, 0.339844f,
+-0.687988f, 0.339844f, -0.074707f, 0.507324f, -0.074707f, 0.507324f, 0, 0.050293f,
+0, 0.050293f, -0.0620117f, 0.0751953f, -0.119141f, 0.111084f, -0.162842f, 0.146973f,
+-0.206543f, 0.186523f, -0.241943f, 0.226074f, -0.277344f, 0.264893f, -0.307617f,
+0.303711f, -0.337891f, 0.334961f, -0.368164f, 0.366211f, -0.398438f, 0.385498f, -0.431641f,
+0.404785f, -0.464844f, 0.404785f, -0.506836f, 0.404785f, -0.536133f, 0.395996f, -0.55835f,
+0.387207f, -0.580566f, 0.370605f, -0.595703f, 0.354004f, -0.61084f, 0.330811f, -0.618408f,
+0.307617f, -0.625977f, 0.279297f, -0.625977f, 0.25293f, -0.625977f, 0.229736f, -0.618652f,
+0.206543f, -0.611328f, 0.188477f, -0.59668f, 0.17041f, -0.582031f, 0.158936f, -0.560303f,
+0.147461f, -0.538574f, 0.144043f, -0.509766f, 0.0541992f, -0.518066f, 0.0585938f,
+-0.555176f, 0.074707f, -0.587891f, 0.0908203f, -0.620605f, 0.119141f, -0.645264f,
+0.147461f, -0.669922f, 0.187256f, -0.684082f, 0.227051f, -0.698242f, 0.279297f, -0.698242f,
+0.330566f, -0.698242f, 0.370605f, -0.686035f, 0.410645f, -0.673828f, 0.438232f, -0.649902f,
+0.46582f, -0.625977f, 0.480469f, -0.59082f, 0.495117f, -0.555664f, 0.495117f, -0.509766f,
+0.495117f, -0.475098f, 0.482666f, -0.443848f, 0.470215f, -0.412598f, 0.449463f, -0.384277f,
+0.428711f, -0.355957f, 0.401367f, -0.32959f, 0.374023f, -0.303223f, 0.344238f, -0.278076f,
+0.314453f, -0.25293f, 0.28418f, -0.228271f, 0.253906f, -0.203613f, 0.227295f, -0.178711f,
+0.200684f, -0.153809f, 0.179688f, -0.128174f, 0.158691f, -0.102539f, 0.146973f, -0.074707f,
+0.505859f, -0.074707f, 0.505859f, 0, 0.430176f, -0.155762f, 0.430176f, 0, 0.347168f,
+0, 0.347168f, -0.155762f, 0.0229492f, -0.155762f, 0.0229492f, -0.224121f, 0.337891f,
+-0.687988f, 0.430176f, -0.687988f, 0.430176f, -0.225098f, 0.526855f, -0.225098f,
+0.526855f, -0.155762f, 0.347168f, -0.588867f, 0.346191f, -0.586426f, 0.342285f, -0.579346f,
+0.338379f, -0.572266f, 0.333496f, -0.563477f, 0.328613f, -0.554688f, 0.323486f, -0.545654f,
+0.318359f, -0.536621f, 0.314453f, -0.530762f, 0.138184f, -0.270996f, 0.135742f, -0.26709f,
+0.131104f, -0.260742f, 0.126465f, -0.254395f, 0.121582f, -0.247803f, 0.116699f, -0.241211f,
+0.111816f, -0.234863f, 0.106934f, -0.228516f, 0.104004f, -0.225098f, 0.347168f, -0.225098f,
+0.51416f, -0.224121f, 0.51416f, -0.172363f, 0.498535f, -0.129395f, 0.48291f, -0.0864258f,
+0.452148f, -0.0554199f, 0.421387f, -0.0244141f, 0.375732f, -0.00732422f, 0.330078f,
+0.00976562f, 0.27002f, 0.00976562f, 0.21582f, 0.00976562f, 0.175537f, -0.00292969f,
+0.135254f, -0.015625f, 0.107422f, -0.0378418f, 0.0795898f, -0.0600586f, 0.0632324f,
+-0.0898438f, 0.046875f, -0.119629f, 0.0400391f, -0.153809f, 0.128906f, -0.164062f,
+0.134277f, -0.144531f, 0.144043f, -0.126221f, 0.153809f, -0.10791f, 0.170654f, -0.0935059f,
+0.1875f, -0.0791016f, 0.212158f, -0.0705566f, 0.236816f, -0.0620117f, 0.271973f,
+-0.0620117f, 0.306152f, -0.0620117f, 0.333984f, -0.0725098f, 0.361816f, -0.0830078f,
+0.381592f, -0.103516f, 0.401367f, -0.124023f, 0.412109f, -0.153809f, 0.422852f, -0.183594f,
+0.422852f, -0.222168f, 0.422852f, -0.253906f, 0.412598f, -0.280518f, 0.402344f, -0.307129f,
+0.383301f, -0.326416f, 0.364258f, -0.345703f, 0.33667f, -0.356445f, 0.309082f, -0.367188f,
+0.273926f, -0.367188f, 0.251953f, -0.367188f, 0.233398f, -0.363281f, 0.214844f, -0.359375f,
+0.198975f, -0.352539f, 0.183105f, -0.345703f, 0.170166f, -0.33667f, 0.157227f, -0.327637f,
+0.145996f, -0.317871f, 0.0600586f, -0.317871f, 0.0830078f, -0.687988f, 0.474121f,
+-0.687988f, 0.474121f, -0.613281f, 0.163086f, -0.613281f, 0.149902f, -0.39502f, 0.17334f,
+-0.413086f, 0.208496f, -0.426025f, 0.243652f, -0.438965f, 0.291992f, -0.438965f,
+0.343262f, -0.438965f, 0.384277f, -0.42334f, 0.425293f, -0.407715f, 0.454102f, -0.37915f,
+0.48291f, -0.350586f, 0.498535f, -0.311035f, 0.51416f, -0.271484f, 0.51416f, -0.224121f,
+0.512207f, -0.225098f, 0.512207f, -0.17334f, 0.497803f, -0.130127f, 0.483398f, -0.0869141f,
+0.455322f, -0.0559082f, 0.427246f, -0.0249023f, 0.385742f, -0.00756836f, 0.344238f,
+0.00976562f, 0.290039f, 0.00976562f, 0.22998f, 0.00976562f, 0.185059f, -0.0131836f,
+0.140137f, -0.0361328f, 0.110352f, -0.0793457f, 0.0805664f, -0.122559f, 0.0656738f,
+-0.185303f, 0.0507812f, -0.248047f, 0.0507812f, -0.328125f, 0.0507812f, -0.419922f,
+0.067627f, -0.489258f, 0.0844727f, -0.558594f, 0.116211f, -0.60498f, 0.147949f, -0.651367f,
+0.193604f, -0.674805f, 0.239258f, -0.698242f, 0.296875f, -0.698242f, 0.332031f, -0.698242f,
+0.362793f, -0.690918f, 0.393555f, -0.683594f, 0.418701f, -0.667236f, 0.443848f, -0.650879f,
+0.462891f, -0.624023f, 0.481934f, -0.597168f, 0.493164f, -0.558105f, 0.40918f, -0.542969f,
+0.395508f, -0.587402f, 0.365479f, -0.607178f, 0.335449f, -0.626953f, 0.295898f, -0.626953f,
+0.259766f, -0.626953f, 0.230469f, -0.609863f, 0.201172f, -0.592773f, 0.180664f, -0.558838f,
+0.160156f, -0.524902f, 0.14917f, -0.473633f, 0.138184f, -0.422363f, 0.138184f, -0.354004f,
+0.162109f, -0.398438f, 0.205566f, -0.421631f, 0.249023f, -0.444824f, 0.305176f, -0.444824f,
+0.352051f, -0.444824f, 0.390137f, -0.429688f, 0.428223f, -0.414551f, 0.455322f, -0.385986f,
+0.482422f, -0.357422f, 0.497314f, -0.31665f, 0.512207f, -0.275879f, 0.512207f, -0.225098f,
+0.422852f, -0.221191f, 0.422852f, -0.256836f, 0.414062f, -0.285645f, 0.405273f, -0.314453f,
+0.387695f, -0.334717f, 0.370117f, -0.35498f, 0.344238f, -0.365967f, 0.318359f, -0.376953f,
+0.28418f, -0.376953f, 0.260254f, -0.376953f, 0.23584f, -0.369873f, 0.211426f, -0.362793f,
+0.19165f, -0.346924f, 0.171875f, -0.331055f, 0.159424f, -0.305176f, 0.146973f, -0.279297f,
+0.146973f, -0.242188f, 0.146973f, -0.204102f, 0.156738f, -0.171143f, 0.166504f, -0.138184f,
+0.184814f, -0.11377f, 0.203125f, -0.0893555f, 0.229004f, -0.0751953f, 0.254883f,
+-0.0610352f, 0.287109f, -0.0610352f, 0.318848f, -0.0610352f, 0.343994f, -0.0720215f,
+0.369141f, -0.0830078f, 0.386719f, -0.10376f, 0.404297f, -0.124512f, 0.413574f, -0.154297f,
+0.422852f, -0.184082f, 0.422852f, -0.221191f, 0.505859f, -0.616699f, 0.454102f, -0.537598f,
+0.410645f, -0.4646f, 0.367188f, -0.391602f, 0.335938f, -0.317627f, 0.304688f, -0.243652f,
+0.287354f, -0.165771f, 0.27002f, -0.0878906f, 0.27002f, 0, 0.178223f, 0, 0.178223f,
+-0.0825195f, 0.197754f, -0.161865f, 0.217285f, -0.241211f, 0.250488f, -0.317627f,
+0.283691f, -0.394043f, 0.327637f, -0.467773f, 0.371582f, -0.541504f, 0.420898f, -0.613281f,
+0.0512695f, -0.613281f, 0.0512695f, -0.687988f, 0.505859f, -0.687988f, 0.508789f,
+-0.35791f, 0.508789f, -0.266113f, 0.491455f, -0.197021f, 0.474121f, -0.12793f, 0.441895f,
+-0.0820312f, 0.409668f, -0.0361328f, 0.363525f, -0.0131836f, 0.317383f, 0.00976562f,
+0.259766f, 0.00976562f, 0.220215f, 0.00976562f, 0.188477f, 0.00170898f, 0.156738f,
+-0.00634766f, 0.131836f, -0.0234375f, 0.106934f, -0.0405273f, 0.0893555f, -0.0678711f,
+0.0717773f, -0.0952148f, 0.0610352f, -0.133789f, 0.14502f, -0.146973f, 0.158691f,
+-0.102539f, 0.187744f, -0.0817871f, 0.216797f, -0.0610352f, 0.26123f, -0.0610352f,
+0.296875f, -0.0610352f, 0.326416f, -0.0778809f, 0.355957f, -0.0947266f, 0.376709f,
+-0.128418f, 0.397461f, -0.162109f, 0.40918f, -0.212891f, 0.420898f, -0.263672f, 0.421875f,
+-0.332031f, 0.411621f, -0.309082f, 0.393799f, -0.291016f, 0.375977f, -0.272949f,
+0.353271f, -0.260498f, 0.330566f, -0.248047f, 0.304199f, -0.241455f, 0.277832f, -0.234863f,
+0.250977f, -0.234863f, 0.204102f, -0.234863f, 0.16626f, -0.251709f, 0.128418f, -0.268555f,
+0.102051f, -0.298828f, 0.0756836f, -0.329102f, 0.0612793f, -0.371826f, 0.046875f,
+-0.414551f, 0.046875f, -0.466797f, 0.046875f, -0.52002f, 0.0622559f, -0.562988f,
+0.0776367f, -0.605957f, 0.106934f, -0.635986f, 0.13623f, -0.666016f, 0.178955f, -0.682129f,
+0.22168f, -0.698242f, 0.275879f, -0.698242f, 0.390625f, -0.698242f, 0.449707f, -0.613281f,
+0.508789f, -0.52832f, 0.508789f, -0.35791f, 0.413086f, -0.442871f, 0.413086f, -0.480957f,
+0.404053f, -0.514648f, 0.39502f, -0.54834f, 0.377197f, -0.573242f, 0.359375f, -0.598145f,
+0.333252f, -0.612549f, 0.307129f, -0.626953f, 0.272949f, -0.626953f, 0.241211f, -0.626953f,
+0.21582f, -0.615723f, 0.19043f, -0.604492f, 0.172852f, -0.58374f, 0.155273f, -0.562988f,
+0.145752f, -0.533203f, 0.13623f, -0.503418f, 0.13623f, -0.466797f, 0.13623f, -0.432129f,
+0.144775f, -0.402344f, 0.15332f, -0.372559f, 0.17041f, -0.35083f, 0.1875f, -0.329102f,
+0.212891f, -0.31665f, 0.238281f, -0.304199f, 0.271973f, -0.304199f, 0.296387f, -0.304199f,
+0.321533f, -0.3125f, 0.34668f, -0.320801f, 0.366943f, -0.337891f, 0.387207f, -0.35498f,
+0.400146f, -0.381104f, 0.413086f, -0.407227f, 0.413086f, -0.442871f, 0.0913086f,
+-0.427246f, 0.0913086f, -0.52832f, 0.186523f, -0.52832f, 0.186523f, -0.427246f, 0.0913086f,
+0, 0.0913086f, -0.101074f, 0.186523f, -0.101074f, 0.186523f, 0, 0.187988f, -0.101074f,
+0.187988f, -0.0249023f, 0.187988f, 0.000976562f, 0.185791f, 0.0222168f, 0.183594f,
+0.043457f, 0.178711f, 0.0617676f, 0.173828f, 0.0800781f, 0.166748f, 0.0961914f, 0.159668f,
+0.112305f, 0.149902f, 0.12793f, 0.0898438f, 0.12793f, 0.111816f, 0.0961914f, 0.123779f,
+0.0639648f, 0.135742f, 0.0317383f, 0.135742f, 0, 0.0927734f, 0, 0.0927734f, -0.101074f,
+0.0927734f, -0.427246f, 0.0927734f, -0.52832f, 0.187988f, -0.52832f, 0.187988f, -0.427246f,
+0.0493164f, -0.278809f, 0.0493164f, -0.378906f, 0.535156f, -0.583008f, 0.535156f,
+-0.507812f, 0.116211f, -0.329102f, 0.535156f, -0.149902f, 0.535156f, -0.0751953f,
+0.0488281f, -0.417969f, 0.0488281f, -0.490234f, 0.534668f, -0.490234f, 0.534668f,
+-0.417969f, 0.0488281f, -0.167969f, 0.0488281f, -0.240234f, 0.534668f, -0.240234f,
+0.534668f, -0.167969f, 0.0493164f, -0.0751953f, 0.0493164f, -0.149902f, 0.468262f,
+-0.329102f, 0.0493164f, -0.507812f, 0.0493164f, -0.583008f, 0.535156f, -0.378906f,
+0.535156f, -0.278809f, 0.519043f, -0.503906f, 0.519043f, -0.469238f, 0.51001f, -0.442871f,
+0.500977f, -0.416504f, 0.48584f, -0.395752f, 0.470703f, -0.375f, 0.451416f, -0.358643f,
+0.432129f, -0.342285f, 0.412109f, -0.327637f, 0.39209f, -0.312988f, 0.372803f, -0.298828f,
+0.353516f, -0.284668f, 0.338135f, -0.268066f, 0.322754f, -0.251465f, 0.313232f, -0.231201f,
+0.303711f, -0.210938f, 0.303223f, -0.184082f, 0.217773f, -0.184082f, 0.21875f, -0.217773f,
+0.228271f, -0.243164f, 0.237793f, -0.268555f, 0.25293f, -0.288086f, 0.268066f, -0.307617f,
+0.287109f, -0.322998f, 0.306152f, -0.338379f, 0.325684f, -0.352295f, 0.345215f, -0.366211f,
+0.364014f, -0.380127f, 0.382812f, -0.394043f, 0.397461f, -0.411133f, 0.412109f, -0.428223f,
+0.421143f, -0.449707f, 0.430176f, -0.471191f, 0.430176f, -0.5f, 0.430176f, -0.528809f,
+0.419922f, -0.55127f, 0.409668f, -0.57373f, 0.390869f, -0.589111f, 0.37207f, -0.604492f,
+0.345459f, -0.612305f, 0.318848f, -0.620117f, 0.286133f, -0.620117f, 0.217773f, -0.620117f,
+0.177734f, -0.585938f, 0.137695f, -0.551758f, 0.130859f, -0.492188f, 0.0410156f,
+-0.498047f, 0.0463867f, -0.539062f, 0.0627441f, -0.575439f, 0.0791016f, -0.611816f,
+0.108643f, -0.63916f, 0.138184f, -0.666504f, 0.181885f, -0.682373f, 0.225586f, -0.698242f,
+0.285156f, -0.698242f, 0.34082f, -0.698242f, 0.384277f, -0.68457f, 0.427734f, -0.670898f,
+0.457764f, -0.645752f, 0.487793f, -0.620605f, 0.503418f, -0.584473f, 0.519043f, -0.54834f,
+0.519043f, -0.503906f, 0.213867f, 0, 0.213867f, -0.0981445f, 0.309082f, -0.0981445f,
+0.309082f, 0, 0.928711f, -0.368652f, 0.928711f, -0.29834f, 0.912354f, -0.23999f,
+0.895996f, -0.181641f, 0.867188f, -0.139648f, 0.838379f, -0.0976562f, 0.798096f,
+-0.0742188f, 0.757812f, -0.0507812f, 0.710449f, -0.0507812f, 0.683105f, -0.0507812f,
+0.663818f, -0.057373f, 0.644531f, -0.0639648f, 0.632324f, -0.0754395f, 0.620117f,
+-0.0869141f, 0.614746f, -0.102539f, 0.609375f, -0.118164f, 0.609375f, -0.136719f,
+0.609375f, -0.144043f, 0.609863f, -0.154541f, 0.610352f, -0.165039f, 0.61084f, -0.170898f,
+0.60791f, -0.170898f, 0.596191f, -0.148926f, 0.579346f, -0.127197f, 0.5625f, -0.105469f,
+0.539795f, -0.088623f, 0.51709f, -0.0717773f, 0.488525f, -0.0612793f, 0.459961f,
+-0.0507812f, 0.425293f, -0.0507812f, 0.384277f, -0.0507812f, 0.35376f, -0.0649414f,
+0.323242f, -0.0791016f, 0.303467f, -0.104248f, 0.283691f, -0.129395f, 0.273926f,
+-0.163818f, 0.26416f, -0.198242f, 0.26416f, -0.23877f, 0.26416f, -0.297363f, 0.281494f,
+-0.351318f, 0.298828f, -0.405273f, 0.331055f, -0.446533f, 0.363281f, -0.487793f,
+0.408447f, -0.512695f, 0.453613f, -0.537598f, 0.509277f, -0.537598f, 0.538574f, -0.537598f,
+0.562012f, -0.531006f, 0.585449f, -0.524414f, 0.603271f, -0.512695f, 0.621094f, -0.500977f,
+0.634277f, -0.484619f, 0.647461f, -0.468262f, 0.65625f, -0.44873f, 0.65918f, -0.44873f,
+0.678223f, -0.526855f, 0.754395f, -0.526855f, 0.697754f, -0.279785f, 0.688477f, -0.23877f,
+0.684082f, -0.209473f, 0.679688f, -0.180176f, 0.679688f, -0.15625f, 0.679688f, -0.132812f,
+0.690186f, -0.121582f, 0.700684f, -0.110352f, 0.719238f, -0.110352f, 0.749512f, -0.110352f,
+0.775635f, -0.130127f, 0.801758f, -0.149902f, 0.821045f, -0.18457f, 0.840332f, -0.219238f,
+0.851318f, -0.266113f, 0.862305f, -0.312988f, 0.862305f, -0.367676f, 0.862305f, -0.430664f,
+0.842041f, -0.484863f, 0.821777f, -0.539062f, 0.782471f, -0.578613f, 0.743164f, -0.618164f,
+0.685059f, -0.640625f, 0.626953f, -0.663086f, 0.550781f, -0.663086f, 0.485352f, -0.663086f,
+0.429932f, -0.647461f, 0.374512f, -0.631836f, 0.32959f, -0.603516f, 0.284668f, -0.575195f,
+0.250732f, -0.535889f, 0.216797f, -0.496582f, 0.193848f, -0.449707f, 0.170898f, -0.402832f,
+0.15918f, -0.349365f, 0.147461f, -0.295898f, 0.147461f, -0.239746f, 0.147461f, -0.170898f,
+0.168457f, -0.112793f, 0.189453f, -0.0546875f, 0.229736f, -0.0129395f, 0.27002f,
+0.0288086f, 0.329346f, 0.0522461f, 0.388672f, 0.0756836f, 0.46582f, 0.0756836f, 0.51709f,
+0.0756836f, 0.561523f, 0.067627f, 0.605957f, 0.0595703f, 0.643066f, 0.0478516f, 0.680176f,
+0.0361328f, 0.709473f, 0.0222168f, 0.73877f, 0.00830078f, 0.760254f, -0.00341797f,
+0.787109f, 0.0512695f, 0.762695f, 0.065918f, 0.729736f, 0.0812988f, 0.696777f, 0.0966797f,
+0.65625f, 0.109375f, 0.615723f, 0.12207f, 0.567871f, 0.130127f, 0.52002f, 0.138184f,
+0.46582f, 0.138184f, 0.373047f, 0.138184f, 0.301025f, 0.110107f, 0.229004f, 0.0820312f,
+0.179443f, 0.0317383f, 0.129883f, -0.0185547f, 0.104248f, -0.0878906f, 0.0786133f,
+-0.157227f, 0.0786133f, -0.239746f, 0.0786133f, -0.307617f, 0.0939941f, -0.370117f,
+0.109375f, -0.432617f, 0.138184f, -0.486328f, 0.166992f, -0.540039f, 0.208496f, -0.583984f,
+0.25f, -0.62793f, 0.30249f, -0.65918f, 0.35498f, -0.69043f, 0.417236f, -0.70752f,
+0.479492f, -0.724609f, 0.549805f, -0.724609f, 0.647949f, -0.724609f, 0.719238f, -0.695801f,
+0.790527f, -0.666992f, 0.837158f, -0.618164f, 0.883789f, -0.569336f, 0.90625f, -0.504883f,
+0.928711f, -0.44043f, 0.928711f, -0.368652f, 0.632812f, -0.364746f, 0.632812f, -0.38916f,
+0.624512f, -0.409668f, 0.616211f, -0.430176f, 0.60083f, -0.444824f, 0.585449f, -0.459473f,
+0.563721f, -0.467529f, 0.541992f, -0.475586f, 0.514648f, -0.475586f, 0.472656f, -0.475586f,
+0.440918f, -0.454834f, 0.40918f, -0.434082f, 0.387939f, -0.400391f, 0.366699f, -0.366699f,
+0.355713f, -0.324463f, 0.344727f, -0.282227f, 0.344727f, -0.239746f, 0.344727f, -0.181152f,
+0.36792f, -0.147949f, 0.391113f, -0.114746f, 0.439453f, -0.114746f, 0.473145f, -0.114746f,
+0.502441f, -0.129883f, 0.531738f, -0.14502f, 0.555176f, -0.169922f, 0.578613f, -0.194824f,
+0.595703f, -0.227051f, 0.612793f, -0.259277f, 0.621582f, -0.293945f, 0.625977f, -0.311523f,
+0.629395f, -0.331055f, 0.632812f, -0.350586f, 0.632812f, -0.364746f, 0.569824f, 0,
+0.491211f, -0.201172f, 0.177734f, -0.201172f, 0.0986328f, 0, 0.00195312f, 0, 0.282715f,
+-0.687988f, 0.388672f, -0.687988f, 0.665039f, 0, 0.375f, -0.500977f, 0.367188f, -0.520508f,
+0.360107f, -0.540527f, 0.353027f, -0.560547f, 0.347656f, -0.576904f, 0.342285f, -0.593262f,
+0.338623f, -0.604248f, 0.334961f, -0.615234f, 0.334473f, -0.617676f, 0.333496f, -0.615234f,
+0.330078f, -0.604004f, 0.32666f, -0.592773f, 0.321045f, -0.576172f, 0.31543f, -0.55957f,
+0.30835f, -0.539551f, 0.30127f, -0.519531f, 0.293945f, -0.5f, 0.206055f, -0.273926f,
+0.463379f, -0.273926f, 0.614258f, -0.193848f, 0.614258f, -0.141602f, 0.59375f, -0.104736f,
+0.573242f, -0.0678711f, 0.538574f, -0.0446777f, 0.503906f, -0.0214844f, 0.458008f,
+-0.0107422f, 0.412109f, 0, 0.361328f, 0, 0.0820312f, 0, 0.0820312f, -0.687988f, 0.332031f,
+-0.687988f, 0.38916f, -0.687988f, 0.434082f, -0.678467f, 0.479004f, -0.668945f, 0.510254f,
+-0.648438f, 0.541504f, -0.62793f, 0.557861f, -0.596436f, 0.574219f, -0.564941f, 0.574219f,
+-0.520996f, 0.574219f, -0.492188f, 0.566162f, -0.466797f, 0.558105f, -0.441406f,
+0.541748f, -0.420654f, 0.525391f, -0.399902f, 0.500732f, -0.38501f, 0.476074f, -0.370117f,
+0.443359f, -0.362793f, 0.484863f, -0.35791f, 0.516846f, -0.34375f, 0.548828f, -0.32959f,
+0.570312f, -0.307617f, 0.591797f, -0.285645f, 0.603027f, -0.256592f, 0.614258f, -0.227539f,
+0.614258f, -0.193848f, 0.480469f, -0.509766f, 0.480469f, -0.56543f, 0.442383f, -0.589355f,
+0.404297f, -0.613281f, 0.332031f, -0.613281f, 0.175293f, -0.613281f, 0.175293f, -0.395508f,
+0.332031f, -0.395508f, 0.373047f, -0.395508f, 0.401367f, -0.403564f, 0.429688f, -0.411621f,
+0.447266f, -0.426514f, 0.464844f, -0.441406f, 0.472656f, -0.462402f, 0.480469f, -0.483398f,
+0.480469f, -0.509766f, 0.52002f, -0.201172f, 0.52002f, -0.233887f, 0.508057f, -0.256836f,
+0.496094f, -0.279785f, 0.473633f, -0.294434f, 0.451172f, -0.309082f, 0.419678f, -0.315918f,
+0.388184f, -0.322754f, 0.349121f, -0.322754f, 0.175293f, -0.322754f, 0.175293f, -0.074707f,
+0.356445f, -0.074707f, 0.39209f, -0.074707f, 0.422119f, -0.0805664f, 0.452148f, -0.0864258f,
+0.473877f, -0.101074f, 0.495605f, -0.115723f, 0.507812f, -0.140137f, 0.52002f, -0.164551f,
+0.52002f, -0.201172f, 0.386719f, -0.62207f, 0.328125f, -0.62207f, 0.282959f, -0.602539f,
+0.237793f, -0.583008f, 0.207275f, -0.546875f, 0.176758f, -0.510742f, 0.161133f, -0.459961f,
+0.145508f, -0.40918f, 0.145508f, -0.347168f, 0.145508f, -0.285156f, 0.162354f, -0.233643f,
+0.179199f, -0.182129f, 0.210693f, -0.14502f, 0.242188f, -0.10791f, 0.287842f, -0.0874023f,
+0.333496f, -0.0668945f, 0.390625f, -0.0668945f, 0.430664f, -0.0668945f, 0.463623f,
+-0.0773926f, 0.496582f, -0.0878906f, 0.523193f, -0.106934f, 0.549805f, -0.125977f,
+0.570801f, -0.1521f, 0.591797f, -0.178223f, 0.60791f, -0.209961f, 0.684082f, -0.171875f,
+0.665527f, -0.133301f, 0.638184f, -0.100098f, 0.61084f, -0.0668945f, 0.573975f, -0.0424805f,
+0.537109f, -0.0180664f, 0.490479f, -0.00415039f, 0.443848f, 0.00976562f, 0.38623f,
+0.00976562f, 0.302734f, 0.00976562f, 0.23999f, -0.0168457f, 0.177246f, -0.043457f,
+0.13501f, -0.0910645f, 0.0927734f, -0.138672f, 0.0717773f, -0.204102f, 0.0507812f,
+-0.269531f, 0.0507812f, -0.347168f, 0.0507812f, -0.427734f, 0.072998f, -0.492676f,
+0.0952148f, -0.557617f, 0.137939f, -0.603271f, 0.180664f, -0.648926f, 0.243164f,
+-0.673584f, 0.305664f, -0.698242f, 0.385742f, -0.698242f, 0.495605f, -0.698242f,
+0.569336f, -0.655273f, 0.643066f, -0.612305f, 0.677734f, -0.527832f, 0.589355f, -0.498535f,
+0.57959f, -0.522949f, 0.562988f, -0.545166f, 0.546387f, -0.567383f, 0.521484f, -0.584473f,
+0.496582f, -0.601562f, 0.463135f, -0.611816f, 0.429688f, -0.62207f, 0.386719f, -0.62207f,
+0.674316f, -0.351074f, 0.674316f, -0.265137f, 0.648438f, -0.199463f, 0.622559f, -0.133789f,
+0.577637f, -0.0895996f, 0.532715f, -0.0454102f, 0.471436f, -0.0227051f, 0.410156f,
+0, 0.339355f, 0, 0.0820312f, 0, 0.0820312f, -0.687988f, 0.30957f, -0.687988f, 0.38916f,
+-0.687988f, 0.456299f, -0.668213f, 0.523438f, -0.648438f, 0.571777f, -0.607178f,
+0.620117f, -0.565918f, 0.647217f, -0.502441f, 0.674316f, -0.438965f, 0.674316f, -0.351074f,
+0.580566f, -0.351074f, 0.580566f, -0.420898f, 0.560547f, -0.470459f, 0.540527f, -0.52002f,
+0.504395f, -0.551758f, 0.468262f, -0.583496f, 0.417969f, -0.598389f, 0.367676f, -0.613281f,
+0.307617f, -0.613281f, 0.175293f, -0.613281f, 0.175293f, -0.074707f, 0.328613f, -0.074707f,
+0.382812f, -0.074707f, 0.428955f, -0.0922852f, 0.475098f, -0.109863f, 0.508789f,
+-0.144531f, 0.54248f, -0.179199f, 0.561523f, -0.230957f, 0.580566f, -0.282715f, 0.580566f,
+-0.351074f, 0.0820312f, 0, 0.0820312f, -0.687988f, 0.604004f, -0.687988f, 0.604004f,
+-0.611816f, 0.175293f, -0.611816f, 0.175293f, -0.391113f, 0.574707f, -0.391113f,
+0.574707f, -0.315918f, 0.175293f, -0.315918f, 0.175293f, -0.0761719f, 0.624023f,
+-0.0761719f, 0.624023f, 0, 0.175293f, -0.611816f, 0.175293f, -0.355957f, 0.559082f,
+-0.355957f, 0.559082f, -0.278809f, 0.175293f, -0.278809f, 0.175293f, 0, 0.0820312f,
+0, 0.0820312f, -0.687988f, 0.570801f, -0.687988f, 0.570801f, -0.611816f, 0.547363f,
+0, 0.547363f, -0.318848f, 0.175293f, -0.318848f, 0.175293f, 0, 0.0820312f, 0, 0.0820312f,
+-0.687988f, 0.175293f, -0.687988f, 0.175293f, -0.396973f, 0.547363f, -0.396973f,
+0.547363f, -0.687988f, 0.640625f, -0.687988f, 0.640625f, 0, 0.0922852f, 0, 0.0922852f,
+-0.687988f, 0.185547f, -0.687988f, 0.185547f, 0, 0.223145f, 0.00976562f, 0.139648f,
+0.00976562f, 0.0861816f, -0.0336914f, 0.0327148f, -0.0771484f, 0.015625f, -0.170898f,
+0.106934f, -0.186035f, 0.111816f, -0.154297f, 0.123047f, -0.131592f, 0.134277f, -0.108887f,
+0.149902f, -0.0942383f, 0.165527f, -0.0795898f, 0.18457f, -0.0727539f, 0.203613f,
+-0.065918f, 0.223633f, -0.065918f, 0.274414f, -0.065918f, 0.303711f, -0.10083f, 0.333008f,
+-0.135742f, 0.333008f, -0.203125f, 0.333008f, -0.611816f, 0.200684f, -0.611816f,
+0.200684f, -0.687988f, 0.425781f, -0.687988f, 0.425781f, -0.205078f, 0.425781f, -0.155762f,
+0.412109f, -0.116211f, 0.398438f, -0.0766602f, 0.372314f, -0.048584f, 0.346191f,
+-0.0205078f, 0.308594f, -0.00537109f, 0.270996f, 0.00976562f, 0.223145f, 0.00976562f,
+0.540039f, 0, 0.265137f, -0.332031f, 0.175293f, -0.263672f, 0.175293f, 0, 0.0820312f,
+0, 0.0820312f, -0.687988f, 0.175293f, -0.687988f, 0.175293f, -0.343262f, 0.506836f,
+-0.687988f, 0.616699f, -0.687988f, 0.32373f, -0.38916f, 0.655762f, 0, 0.0820312f,
+0, 0.0820312f, -0.687988f, 0.175293f, -0.687988f, 0.175293f, -0.0761719f, 0.522949f,
+-0.0761719f, 0.522949f, 0, 0.666992f, 0, 0.666992f, -0.458984f, 0.666992f, -0.483887f,
+0.66748f, -0.509766f, 0.667969f, -0.535645f, 0.668945f, -0.557129f, 0.669922f, -0.582031f,
+0.671387f, -0.605469f, 0.664551f, -0.580566f, 0.657227f, -0.556152f, 0.650879f, -0.535156f,
+0.643311f, -0.511475f, 0.635742f, -0.487793f, 0.628418f, -0.46875f, 0.450684f, 0,
+0.385254f, 0, 0.205078f, -0.46875f, 0.202148f, -0.476074f, 0.198975f, -0.48584f,
+0.195801f, -0.495605f, 0.192139f, -0.506592f, 0.188477f, -0.517578f, 0.184814f, -0.529053f,
+0.181152f, -0.540527f, 0.177734f, -0.551758f, 0.169434f, -0.577637f, 0.161621f, -0.605469f,
+0.162109f, -0.578125f, 0.163086f, -0.55127f, 0.164062f, -0.52832f, 0.164551f, -0.503174f,
+0.165039f, -0.478027f, 0.165039f, -0.458984f, 0.165039f, 0, 0.0820312f, 0, 0.0820312f,
+-0.687988f, 0.20459f, -0.687988f, 0.387695f, -0.210938f, 0.391113f, -0.201172f, 0.395996f,
+-0.185791f, 0.400879f, -0.17041f, 0.405273f, -0.154297f, 0.409668f, -0.138184f, 0.41333f,
+-0.123779f, 0.416992f, -0.109375f, 0.418457f, -0.101562f, 0.419922f, -0.109375f,
+0.423828f, -0.124023f, 0.427734f, -0.138672f, 0.432861f, -0.154785f, 0.437988f, -0.170898f,
+0.442871f, -0.186035f, 0.447754f, -0.201172f, 0.45166f, -0.210938f, 0.631348f, -0.687988f,
+0.750977f, -0.687988f, 0.750977f, 0, 0.52832f, 0, 0.160156f, -0.585938f, 0.161133f,
+-0.562012f, 0.162598f, -0.538574f, 0.163574f, -0.518555f, 0.164307f, -0.496338f,
+0.165039f, -0.474121f, 0.165039f, -0.457031f, 0.165039f, 0, 0.0820312f, 0, 0.0820312f,
+-0.687988f, 0.19043f, -0.687988f, 0.5625f, -0.0981445f, 0.561035f, -0.12207f, 0.55957f,
+-0.145996f, 0.558594f, -0.166504f, 0.557617f, -0.190674f, 0.556641f, -0.214844f,
+0.556641f, -0.236816f, 0.556641f, -0.687988f, 0.640625f, -0.687988f, 0.640625f, 0,
+0.72998f, -0.347168f, 0.72998f, -0.266602f, 0.706787f, -0.200684f, 0.683594f, -0.134766f,
+0.639648f, -0.0878906f, 0.595703f, -0.0410156f, 0.532227f, -0.015625f, 0.46875f,
+0.00976562f, 0.388184f, 0.00976562f, 0.303223f, 0.00976562f, 0.239258f, -0.0168457f,
+0.175293f, -0.043457f, 0.132812f, -0.0910645f, 0.090332f, -0.138672f, 0.0688477f,
+-0.204102f, 0.0473633f, -0.269531f, 0.0473633f, -0.347168f, 0.0473633f, -0.427734f,
+0.0698242f, -0.492676f, 0.0922852f, -0.557617f, 0.135742f, -0.603271f, 0.179199f,
+-0.648926f, 0.24292f, -0.673584f, 0.306641f, -0.698242f, 0.38916f, -0.698242f, 0.471191f,
+-0.698242f, 0.534912f, -0.67334f, 0.598633f, -0.648438f, 0.641846f, -0.602539f, 0.685059f,
+-0.556641f, 0.70752f, -0.491699f, 0.72998f, -0.426758f, 0.72998f, -0.347168f, 0.634766f,
+-0.347168f, 0.634766f, -0.40918f, 0.618896f, -0.459961f, 0.603027f, -0.510742f, 0.572021f,
+-0.546875f, 0.541016f, -0.583008f, 0.495117f, -0.602539f, 0.449219f, -0.62207f, 0.38916f,
+-0.62207f, 0.327637f, -0.62207f, 0.28125f, -0.602539f, 0.234863f, -0.583008f, 0.203857f,
+-0.546875f, 0.172852f, -0.510742f, 0.157471f, -0.459961f, 0.14209f, -0.40918f, 0.14209f,
+-0.347168f, 0.14209f, -0.285156f, 0.157959f, -0.233643f, 0.173828f, -0.182129f, 0.204834f,
+-0.144775f, 0.23584f, -0.107422f, 0.281982f, -0.0866699f, 0.328125f, -0.065918f,
+0.388184f, -0.065918f, 0.452637f, -0.065918f, 0.499268f, -0.0869141f, 0.545898f,
+-0.10791f, 0.575928f, -0.145264f, 0.605957f, -0.182617f, 0.620361f, -0.234375f, 0.634766f,
+-0.286133f, 0.634766f, -0.347168f, 0.614258f, -0.480957f, 0.614258f, -0.436035f,
+0.599365f, -0.397217f, 0.584473f, -0.358398f, 0.554932f, -0.329834f, 0.525391f, -0.30127f,
+0.480957f, -0.284668f, 0.436523f, -0.268066f, 0.377441f, -0.268066f, 0.175293f, -0.268066f,
+0.175293f, 0, 0.0820312f, 0, 0.0820312f, -0.687988f, 0.371582f, -0.687988f, 0.432617f,
+-0.687988f, 0.478027f, -0.673096f, 0.523438f, -0.658203f, 0.553711f, -0.631104f,
+0.583984f, -0.604004f, 0.599121f, -0.565674f, 0.614258f, -0.527344f, 0.614258f, -0.480957f,
+0.520508f, -0.47998f, 0.520508f, -0.54541f, 0.480469f, -0.579346f, 0.44043f, -0.613281f,
+0.360352f, -0.613281f, 0.175293f, -0.613281f, 0.175293f, -0.341797f, 0.364258f, -0.341797f,
+0.444824f, -0.341797f, 0.482666f, -0.377441f, 0.520508f, -0.413086f, 0.520508f, -0.47998f,
+0.72998f, -0.347168f, 0.72998f, -0.274414f, 0.711182f, -0.214111f, 0.692383f, -0.153809f,
+0.656982f, -0.108398f, 0.621582f, -0.0629883f, 0.570068f, -0.0344238f, 0.518555f,
+-0.00585938f, 0.453125f, 0.00292969f, 0.463379f, 0.0341797f, 0.476318f, 0.0561523f,
+0.489258f, 0.078125f, 0.505859f, 0.092041f, 0.522461f, 0.105957f, 0.542725f, 0.112549f,
+0.562988f, 0.119141f, 0.587891f, 0.119141f, 0.601562f, 0.119141f, 0.617188f, 0.117188f,
+0.632812f, 0.115234f, 0.644043f, 0.112793f, 0.644043f, 0.178223f, 0.625488f, 0.182617f,
+0.603271f, 0.185791f, 0.581055f, 0.188965f, 0.557129f, 0.188965f, 0.515137f, 0.188965f,
+0.483887f, 0.176514f, 0.452637f, 0.164062f, 0.428955f, 0.140869f, 0.405273f, 0.117676f,
+0.388184f, 0.0839844f, 0.371094f, 0.050293f, 0.35791f, 0.0078125f, 0.280762f, 0.00390625f,
+0.222412f, -0.0241699f, 0.164062f, -0.0522461f, 0.125244f, -0.0993652f, 0.0864258f,
+-0.146484f, 0.0668945f, -0.209717f, 0.0473633f, -0.272949f, 0.0473633f, -0.347168f,
+0.0473633f, -0.427734f, 0.0698242f, -0.492676f, 0.0922852f, -0.557617f, 0.135742f,
+-0.603271f, 0.179199f, -0.648926f, 0.24292f, -0.673584f, 0.306641f, -0.698242f, 0.38916f,
+-0.698242f, 0.471191f, -0.698242f, 0.534912f, -0.67334f, 0.598633f, -0.648438f, 0.641846f,
+-0.602539f, 0.685059f, -0.556641f, 0.70752f, -0.491699f, 0.72998f, -0.426758f, 0.72998f,
+-0.347168f, 0.634766f, -0.347168f, 0.634766f, -0.40918f, 0.618896f, -0.459961f, 0.603027f,
+-0.510742f, 0.572021f, -0.546875f, 0.541016f, -0.583008f, 0.495117f, -0.602539f,
+0.449219f, -0.62207f, 0.38916f, -0.62207f, 0.327637f, -0.62207f, 0.28125f, -0.602539f,
+0.234863f, -0.583008f, 0.203857f, -0.546875f, 0.172852f, -0.510742f, 0.157471f, -0.459961f,
+0.14209f, -0.40918f, 0.14209f, -0.347168f, 0.14209f, -0.285156f, 0.157959f, -0.233643f,
+0.173828f, -0.182129f, 0.204834f, -0.144775f, 0.23584f, -0.107422f, 0.281982f, -0.0866699f,
+0.328125f, -0.065918f, 0.388184f, -0.065918f, 0.452637f, -0.065918f, 0.499268f, -0.0869141f,
+0.545898f, -0.10791f, 0.575928f, -0.145264f, 0.605957f, -0.182617f, 0.620361f, -0.234375f,
+0.634766f, -0.286133f, 0.634766f, -0.347168f, 0.568359f, 0, 0.389648f, -0.285645f,
+0.175293f, -0.285645f, 0.175293f, 0, 0.0820312f, 0, 0.0820312f, -0.687988f, 0.405762f,
+-0.687988f, 0.464355f, -0.687988f, 0.509521f, -0.674561f, 0.554688f, -0.661133f,
+0.585449f, -0.635742f, 0.616211f, -0.610352f, 0.632324f, -0.57373f, 0.648438f, -0.537109f,
+0.648438f, -0.491211f, 0.648438f, -0.458496f, 0.638916f, -0.426758f, 0.629395f, -0.39502f,
+0.608887f, -0.368652f, 0.588379f, -0.342285f, 0.556641f, -0.323242f, 0.524902f, -0.304199f,
+0.480469f, -0.296387f, 0.675781f, 0, 0.554688f, -0.490234f, 0.554688f, -0.521484f,
+0.543945f, -0.544434f, 0.533203f, -0.567383f, 0.512695f, -0.582764f, 0.492188f, -0.598145f,
+0.462891f, -0.605713f, 0.433594f, -0.613281f, 0.396484f, -0.613281f, 0.175293f, -0.613281f,
+0.175293f, -0.359375f, 0.400391f, -0.359375f, 0.44043f, -0.359375f, 0.469727f, -0.369385f,
+0.499023f, -0.379395f, 0.517822f, -0.396973f, 0.536621f, -0.414551f, 0.545654f, -0.438477f,
+0.554688f, -0.462402f, 0.554688f, -0.490234f, 0.621094f, -0.189941f, 0.621094f, -0.146484f,
+0.604248f, -0.109863f, 0.587402f, -0.0732422f, 0.552246f, -0.0466309f, 0.51709f,
+-0.0200195f, 0.463623f, -0.00512695f, 0.410156f, 0.00976562f, 0.336914f, 0.00976562f,
+0.208496f, 0.00976562f, 0.136719f, -0.0351562f, 0.0649414f, -0.0800781f, 0.0454102f,
+-0.165039f, 0.135742f, -0.183105f, 0.142578f, -0.15625f, 0.156738f, -0.134277f, 0.170898f,
+-0.112305f, 0.195068f, -0.0964355f, 0.219238f, -0.0805664f, 0.254883f, -0.0717773f,
+0.290527f, -0.0629883f, 0.340332f, -0.0629883f, 0.381836f, -0.0629883f, 0.416504f,
+-0.0700684f, 0.451172f, -0.0771484f, 0.476074f, -0.0917969f, 0.500977f, -0.106445f,
+0.514893f, -0.129639f, 0.528809f, -0.152832f, 0.528809f, -0.185059f, 0.528809f, -0.21875f,
+0.513428f, -0.239746f, 0.498047f, -0.260742f, 0.470215f, -0.274414f, 0.442383f, -0.288086f,
+0.403809f, -0.297363f, 0.365234f, -0.306641f, 0.318359f, -0.317383f, 0.289551f, -0.32373f,
+0.260498f, -0.331299f, 0.231445f, -0.338867f, 0.204834f, -0.349365f, 0.178223f, -0.359863f,
+0.154785f, -0.374023f, 0.131348f, -0.388184f, 0.114258f, -0.407959f, 0.097168f, -0.427734f,
+0.0874023f, -0.453857f, 0.0776367f, -0.47998f, 0.0776367f, -0.51416f, 0.0776367f,
+-0.562988f, 0.0974121f, -0.5979f, 0.117188f, -0.632812f, 0.152344f, -0.655273f, 0.1875f,
+-0.677734f, 0.235352f, -0.687988f, 0.283203f, -0.698242f, 0.338867f, -0.698242f,
+0.402832f, -0.698242f, 0.448242f, -0.688232f, 0.493652f, -0.678223f, 0.524902f, -0.658203f,
+0.556152f, -0.638184f, 0.574951f, -0.608643f, 0.59375f, -0.579102f, 0.60498f, -0.540039f,
+0.513184f, -0.523926f, 0.506348f, -0.548828f, 0.493408f, -0.568359f, 0.480469f, -0.587891f,
+0.459473f, -0.601074f, 0.438477f, -0.614258f, 0.408447f, -0.621094f, 0.378418f, -0.62793f,
+0.337891f, -0.62793f, 0.290039f, -0.62793f, 0.257568f, -0.619385f, 0.225098f, -0.61084f,
+0.205322f, -0.596191f, 0.185547f, -0.581543f, 0.177002f, -0.561768f, 0.168457f, -0.541992f,
+0.168457f, -0.519043f, 0.168457f, -0.488281f, 0.183838f, -0.468506f, 0.199219f, -0.44873f,
+0.225586f, -0.435547f, 0.251953f, -0.422363f, 0.286621f, -0.413574f, 0.321289f, -0.404785f,
+0.360352f, -0.395996f, 0.39209f, -0.388672f, 0.423584f, -0.381104f, 0.455078f, -0.373535f,
+0.483887f, -0.363037f, 0.512695f, -0.352539f, 0.537842f, -0.338379f, 0.562988f, -0.324219f,
+0.581543f, -0.303711f, 0.600098f, -0.283203f, 0.610596f, -0.255371f, 0.621094f, -0.227539f,
+0.621094f, -0.189941f, 0.351562f, -0.611816f, 0.351562f, 0, 0.258789f, 0, 0.258789f,
+-0.611816f, 0.0224609f, -0.611816f, 0.0224609f, -0.687988f, 0.587891f, -0.687988f,
+0.587891f, -0.611816f, 0.381836f, 0, 0.285156f, 0, 0.00439453f, -0.687988f, 0.102539f,
+-0.687988f, 0.292969f, -0.203613f, 0.300293f, -0.181641f, 0.307617f, -0.159912f,
+0.314941f, -0.138184f, 0.320801f, -0.121094f, 0.327637f, -0.101074f, 0.333984f, -0.0820312f,
+0.339844f, -0.100098f, 0.34668f, -0.120117f, 0.352539f, -0.137207f, 0.359619f, -0.158691f,
+0.366699f, -0.180176f, 0.375f, -0.203613f, 0.564453f, -0.687988f, 0.662598f, -0.687988f,
+0.737793f, 0, 0.626465f, 0, 0.507324f, -0.437012f, 0.501953f, -0.455566f, 0.49585f,
+-0.480957f, 0.489746f, -0.506348f, 0.484863f, -0.529297f, 0.479004f, -0.556152f,
+0.473145f, -0.583984f, 0.466797f, -0.555664f, 0.460938f, -0.528809f, 0.455566f, -0.505371f,
+0.449707f, -0.480469f, 0.443848f, -0.455566f, 0.438477f, -0.437012f, 0.318359f, 0,
+0.207031f, 0, 0.00439453f, -0.687988f, 0.101562f, -0.687988f, 0.225098f, -0.250977f,
+0.233398f, -0.220215f, 0.240967f, -0.189941f, 0.248535f, -0.159668f, 0.253906f, -0.135742f,
+0.260254f, -0.107422f, 0.265625f, -0.0820312f, 0.272949f, -0.115723f, 0.280762f,
+-0.148438f, 0.28418f, -0.162109f, 0.287598f, -0.177246f, 0.291016f, -0.192383f, 0.294678f,
+-0.207031f, 0.29834f, -0.22168f, 0.302002f, -0.235107f, 0.305664f, -0.248535f, 0.308594f,
+-0.259766f, 0.428223f, -0.687988f, 0.517578f, -0.687988f, 0.637207f, -0.259766f,
+0.640137f, -0.248535f, 0.643799f, -0.235107f, 0.647461f, -0.22168f, 0.651123f, -0.207275f,
+0.654785f, -0.192871f, 0.658203f, -0.177734f, 0.661621f, -0.162598f, 0.665039f, -0.148926f,
+0.672852f, -0.116211f, 0.680176f, -0.0820312f, 0.680664f, -0.0820312f, 0.68457f,
+-0.098877f, 0.688477f, -0.115723f, 0.694336f, -0.141113f, 0.700195f, -0.166504f,
+0.707275f, -0.196045f, 0.714355f, -0.225586f, 0.72168f, -0.250977f, 0.843262f, -0.687988f,
+0.94043f, -0.687988f, 0.542969f, 0, 0.336426f, -0.300781f, 0.125488f, 0, 0.0224609f,
+0, 0.28418f, -0.357422f, 0.0424805f, -0.687988f, 0.145508f, -0.687988f, 0.336914f,
+-0.417969f, 0.522949f, -0.687988f, 0.625977f, -0.687988f, 0.390625f, -0.36084f, 0.645996f,
+0, 0.379395f, -0.285156f, 0.379395f, 0, 0.286621f, 0, 0.286621f, -0.285156f, 0.0219727f,
+-0.687988f, 0.124512f, -0.687988f, 0.333984f, -0.360352f, 0.54248f, -0.687988f, 0.64502f,
+-0.687988f, 0.57959f, 0, 0.0317383f, 0, 0.0317383f, -0.0698242f, 0.450684f, -0.611816f,
+0.0673828f, -0.611816f, 0.0673828f, -0.687988f, 0.556641f, -0.687988f, 0.556641f,
+-0.620117f, 0.137695f, -0.0761719f, 0.57959f, -0.0761719f, 0.0712891f, 0.20752f,
+0.0712891f, -0.724609f, 0.27002f, -0.724609f, 0.27002f, -0.661621f, 0.15625f, -0.661621f,
+0.15625f, 0.144531f, 0.27002f, 0.144531f, 0.27002f, 0.20752f, 0.19873f, 0.00976562f,
+0, -0.724609f, 0.0771484f, -0.724609f, 0.277832f, 0.00976562f, 0.0078125f, 0.20752f,
+0.0078125f, 0.144531f, 0.121582f, 0.144531f, 0.121582f, -0.661621f, 0.0078125f, -0.661621f,
+0.0078125f, -0.724609f, 0.206543f, -0.724609f, 0.206543f, 0.20752f, 0.384277f, -0.328613f,
+0.233398f, -0.637695f, 0.0839844f, -0.328613f, 0.00488281f, -0.328613f, 0.18457f,
+-0.687988f, 0.283691f, -0.687988f, 0.464355f, -0.328613f, 0.212891f, -0.586426f,
+0.0517578f, -0.722168f, 0.0517578f, -0.736328f, 0.152832f, -0.736328f, 0.258789f,
+-0.596191f, 0.258789f, -0.586426f, 0.202148f, 0.00976562f, 0.122559f, 0.00976562f,
+0.0825195f, -0.0322266f, 0.0424805f, -0.0742188f, 0.0424805f, -0.147461f, 0.0424805f,
+-0.199707f, 0.0622559f, -0.233154f, 0.0820312f, -0.266602f, 0.114014f, -0.285645f,
+0.145996f, -0.304688f, 0.187012f, -0.312012f, 0.228027f, -0.319336f, 0.270508f, -0.320312f,
+0.38916f, -0.322266f, 0.38916f, -0.351074f, 0.38916f, -0.383789f, 0.382324f, -0.406738f,
+0.375488f, -0.429688f, 0.361328f, -0.443848f, 0.347168f, -0.458008f, 0.325928f, -0.4646f,
+0.304688f, -0.471191f, 0.275879f, -0.471191f, 0.250488f, -0.471191f, 0.22998f, -0.467529f,
+0.209473f, -0.463867f, 0.194336f, -0.454346f, 0.179199f, -0.444824f, 0.169922f, -0.428467f,
+0.160645f, -0.412109f, 0.157715f, -0.387207f, 0.065918f, -0.395508f, 0.0708008f,
+-0.426758f, 0.0844727f, -0.452881f, 0.0981445f, -0.479004f, 0.123291f, -0.498047f,
+0.148438f, -0.51709f, 0.186279f, -0.527588f, 0.224121f, -0.538086f, 0.277832f, -0.538086f,
+0.377441f, -0.538086f, 0.427734f, -0.492432f, 0.478027f, -0.446777f, 0.478027f, -0.360352f,
+0.478027f, -0.132812f, 0.478027f, -0.09375f, 0.488281f, -0.0739746f, 0.498535f, -0.0541992f,
+0.527344f, -0.0541992f, 0.534668f, -0.0541992f, 0.541992f, -0.0551758f, 0.549316f,
+-0.0561523f, 0.556152f, -0.0576172f, 0.556152f, -0.00292969f, 0.539551f, 0.000976562f,
+0.523193f, 0.00292969f, 0.506836f, 0.00488281f, 0.488281f, 0.00488281f, 0.463379f,
+0.00488281f, 0.445557f, -0.00170898f, 0.427734f, -0.00830078f, 0.416504f, -0.0217285f,
+0.405273f, -0.0351562f, 0.399414f, -0.0549316f, 0.393555f, -0.074707f, 0.39209f,
+-0.101074f, 0.38916f, -0.101074f, 0.375f, -0.0756836f, 0.358154f, -0.0551758f, 0.341309f,
+-0.034668f, 0.318848f, -0.0202637f, 0.296387f, -0.00585938f, 0.267822f, 0.00195312f,
+0.239258f, 0.00976562f, 0.202148f, 0.00976562f, 0.222168f, -0.0561523f, 0.26416f,
+-0.0561523f, 0.295654f, -0.0715332f, 0.327148f, -0.0869141f, 0.3479f, -0.11084f,
+0.368652f, -0.134766f, 0.378906f, -0.163086f, 0.38916f, -0.191406f, 0.38916f, -0.217285f,
+0.38916f, -0.260742f, 0.292969f, -0.258789f, 0.260742f, -0.258301f, 0.231689f, -0.25415f,
+0.202637f, -0.25f, 0.180664f, -0.237793f, 0.158691f, -0.225586f, 0.145752f, -0.203613f,
+0.132812f, -0.181641f, 0.132812f, -0.145996f, 0.132812f, -0.103027f, 0.156006f, -0.0795898f,
+0.179199f, -0.0561523f, 0.222168f, -0.0561523f, 0.51416f, -0.266602f, 0.51416f, 0.00976562f,
+0.319824f, 0.00976562f, 0.259766f, 0.00976562f, 0.219971f, -0.0119629f, 0.180176f,
+-0.0336914f, 0.155273f, -0.0820312f, 0.154297f, -0.0820312f, 0.154297f, -0.0693359f,
+0.153564f, -0.0556641f, 0.152832f, -0.0419922f, 0.1521f, -0.0302734f, 0.151367f,
+-0.0185547f, 0.150635f, -0.0102539f, 0.149902f, -0.00195312f, 0.149414f, 0, 0.0644531f,
+0, 0.0649414f, -0.00439453f, 0.0654297f, -0.0148926f, 0.065918f, -0.0253906f, 0.0664062f,
+-0.0400391f, 0.0668945f, -0.0546875f, 0.0671387f, -0.0722656f, 0.0673828f, -0.0898438f,
+0.0673828f, -0.108887f, 0.0673828f, -0.724609f, 0.155273f, -0.724609f, 0.155273f,
+-0.518066f, 0.155273f, -0.503418f, 0.155029f, -0.48999f, 0.154785f, -0.476562f, 0.154297f,
+-0.466309f, 0.153809f, -0.454102f, 0.15332f, -0.443359f, 0.155273f, -0.443359f, 0.179688f,
+-0.494141f, 0.219971f, -0.516113f, 0.260254f, -0.538086f, 0.319824f, -0.538086f,
+0.419922f, -0.538086f, 0.467041f, -0.470703f, 0.51416f, -0.40332f, 0.51416f, -0.266602f,
+0.421875f, -0.263672f, 0.421875f, -0.318359f, 0.415039f, -0.357422f, 0.408203f, -0.396484f,
+0.393066f, -0.421631f, 0.37793f, -0.446777f, 0.354492f, -0.458496f, 0.331055f, -0.470215f,
+0.297363f, -0.470215f, 0.262695f, -0.470215f, 0.236084f, -0.458984f, 0.209473f, -0.447754f,
+0.19165f, -0.422852f, 0.173828f, -0.397949f, 0.164551f, -0.357422f, 0.155273f, -0.316895f,
+0.155273f, -0.258301f, 0.155273f, -0.20166f, 0.164551f, -0.163086f, 0.173828f, -0.124512f,
+0.19165f, -0.100342f, 0.209473f, -0.0761719f, 0.23584f, -0.0656738f, 0.262207f, -0.0551758f,
+0.296387f, -0.0551758f, 0.328613f, -0.0551758f, 0.352051f, -0.0664062f, 0.375488f,
+-0.0776367f, 0.391113f, -0.102539f, 0.406738f, -0.127441f, 0.414307f, -0.167236f,
+0.421875f, -0.207031f, 0.421875f, -0.263672f, 0.134277f, -0.266602f, 0.134277f, -0.221191f,
+0.140869f, -0.183105f, 0.147461f, -0.14502f, 0.163086f, -0.117432f, 0.178711f, -0.0898438f,
+0.204346f, -0.074707f, 0.22998f, -0.0595703f, 0.267578f, -0.0595703f, 0.314453f,
+-0.0595703f, 0.345947f, -0.0849609f, 0.377441f, -0.110352f, 0.384766f, -0.163086f,
+0.473633f, -0.157227f, 0.469238f, -0.124512f, 0.45459f, -0.0942383f, 0.439941f, -0.0639648f,
+0.414795f, -0.0410156f, 0.389648f, -0.0180664f, 0.353516f, -0.00415039f, 0.317383f,
+0.00976562f, 0.27002f, 0.00976562f, 0.208008f, 0.00976562f, 0.164551f, -0.0112305f,
+0.121094f, -0.0322266f, 0.0939941f, -0.0690918f, 0.0668945f, -0.105957f, 0.0546875f,
+-0.156006f, 0.0424805f, -0.206055f, 0.0424805f, -0.264648f, 0.0424805f, -0.317871f,
+0.0512695f, -0.358643f, 0.0600586f, -0.399414f, 0.0759277f, -0.429932f, 0.0917969f,
+-0.460449f, 0.113281f, -0.481201f, 0.134766f, -0.501953f, 0.159912f, -0.514404f,
+0.185059f, -0.526855f, 0.212891f, -0.532471f, 0.240723f, -0.538086f, 0.269043f, -0.538086f,
+0.313477f, -0.538086f, 0.348145f, -0.525879f, 0.382812f, -0.513672f, 0.407959f, -0.492432f,
+0.433105f, -0.471191f, 0.44873f, -0.442383f, 0.464355f, -0.413574f, 0.470703f, -0.380371f,
+0.380371f, -0.373535f, 0.373535f, -0.41748f, 0.345703f, -0.443359f, 0.317871f, -0.469238f,
+0.266602f, -0.469238f, 0.229004f, -0.469238f, 0.203857f, -0.456787f, 0.178711f, -0.444336f,
+0.163086f, -0.419189f, 0.147461f, -0.394043f, 0.140869f, -0.355957f, 0.134277f, -0.317871f,
+0.134277f, -0.266602f, 0.400879f, -0.0849609f, 0.376465f, -0.0341797f, 0.336182f,
+-0.012207f, 0.295898f, 0.00976562f, 0.236328f, 0.00976562f, 0.13623f, 0.00976562f,
+0.0891113f, -0.0576172f, 0.0419922f, -0.125f, 0.0419922f, -0.261719f, 0.0419922f,
+-0.538086f, 0.236328f, -0.538086f, 0.296387f, -0.538086f, 0.336426f, -0.516113f,
+0.376465f, -0.494141f, 0.400879f, -0.446289f, 0.401855f, -0.446289f, 0.401855f, -0.451172f,
+0.401611f, -0.46167f, 0.401367f, -0.472168f, 0.401123f, -0.483643f, 0.400879f, -0.495117f,
+0.400879f, -0.505371f, 0.400879f, -0.515625f, 0.400879f, -0.52002f, 0.400879f, -0.724609f,
+0.48877f, -0.724609f, 0.48877f, -0.108887f, 0.48877f, -0.0898438f, 0.489014f, -0.0722656f,
+0.489258f, -0.0546875f, 0.489746f, -0.0400391f, 0.490234f, -0.0253906f, 0.490723f,
+-0.0148926f, 0.491211f, -0.00439453f, 0.491699f, 0, 0.407715f, 0, 0.406738f, -0.00488281f,
+0.406006f, -0.013916f, 0.405273f, -0.0229492f, 0.404541f, -0.034668f, 0.403809f,
+-0.0463867f, 0.40332f, -0.0593262f, 0.402832f, -0.0722656f, 0.402832f, -0.0849609f,
+0.134277f, -0.264648f, 0.134277f, -0.209961f, 0.141113f, -0.170898f, 0.147949f, -0.131836f,
+0.163086f, -0.106689f, 0.178223f, -0.081543f, 0.20166f, -0.0698242f, 0.225098f, -0.0581055f,
+0.258789f, -0.0581055f, 0.293457f, -0.0581055f, 0.320068f, -0.0693359f, 0.34668f,
+-0.0805664f, 0.364502f, -0.105713f, 0.382324f, -0.130859f, 0.391602f, -0.171387f,
+0.400879f, -0.211914f, 0.400879f, -0.270508f, 0.400879f, -0.32666f, 0.391602f, -0.365479f,
+0.382324f, -0.404297f, 0.364258f, -0.428223f, 0.346191f, -0.452148f, 0.320068f, -0.462646f,
+0.293945f, -0.473145f, 0.259766f, -0.473145f, 0.227539f, -0.473145f, 0.204102f, -0.461914f,
+0.180664f, -0.450684f, 0.165039f, -0.425781f, 0.149414f, -0.400879f, 0.141846f, -0.361084f,
+0.134277f, -0.321289f, 0.134277f, -0.264648f, 0.134766f, -0.245605f, 0.134766f, -0.204102f,
+0.143311f, -0.169189f, 0.151855f, -0.134277f, 0.169678f, -0.109131f, 0.1875f, -0.0839844f,
+0.215332f, -0.0700684f, 0.243164f, -0.0561523f, 0.282227f, -0.0561523f, 0.339355f,
+-0.0561523f, 0.373779f, -0.0791016f, 0.408203f, -0.102051f, 0.42041f, -0.137207f,
+0.497559f, -0.115234f, 0.489258f, -0.0932617f, 0.474365f, -0.0710449f, 0.459473f,
+-0.0488281f, 0.43457f, -0.0310059f, 0.409668f, -0.0131836f, 0.372314f, -0.00170898f,
+0.334961f, 0.00976562f, 0.282227f, 0.00976562f, 0.165039f, 0.00976562f, 0.10376f,
+-0.0600586f, 0.0424805f, -0.129883f, 0.0424805f, -0.267578f, 0.0424805f, -0.341797f,
+0.0610352f, -0.393311f, 0.0795898f, -0.444824f, 0.111816f, -0.477051f, 0.144043f,
+-0.509277f, 0.187012f, -0.523682f, 0.22998f, -0.538086f, 0.278809f, -0.538086f, 0.345215f,
+-0.538086f, 0.389893f, -0.516602f, 0.43457f, -0.495117f, 0.46167f, -0.457275f, 0.48877f,
+-0.419434f, 0.500244f, -0.368164f, 0.511719f, -0.316895f, 0.511719f, -0.257324f,
+0.511719f, -0.245605f, 0.420898f, -0.312988f, 0.413574f, -0.396484f, 0.378418f, -0.434814f,
+0.343262f, -0.473145f, 0.277344f, -0.473145f, 0.255371f, -0.473145f, 0.231201f, -0.466064f,
+0.207031f, -0.458984f, 0.186523f, -0.440918f, 0.166016f, -0.422852f, 0.151855f, -0.391846f,
+0.137695f, -0.36084f, 0.135742f, -0.312988f, 0.17627f, -0.464355f, 0.17627f, 0, 0.0883789f,
+0, 0.0883789f, -0.464355f, 0.0141602f, -0.464355f, 0.0141602f, -0.52832f, 0.0883789f,
+-0.52832f, 0.0883789f, -0.587891f, 0.0883789f, -0.616699f, 0.09375f, -0.641357f,
+0.0991211f, -0.666016f, 0.113525f, -0.684326f, 0.12793f, -0.702637f, 0.152832f, -0.713135f,
+0.177734f, -0.723633f, 0.217285f, -0.723633f, 0.23291f, -0.723633f, 0.249756f, -0.722168f,
+0.266602f, -0.720703f, 0.279297f, -0.717773f, 0.279297f, -0.650879f, 0.270996f, -0.652344f,
+0.26001f, -0.653564f, 0.249023f, -0.654785f, 0.240234f, -0.654785f, 0.220703f, -0.654785f,
+0.208252f, -0.649414f, 0.195801f, -0.644043f, 0.188721f, -0.634033f, 0.181641f, -0.624023f,
+0.178955f, -0.609375f, 0.17627f, -0.594727f, 0.17627f, -0.575684f, 0.17627f, -0.52832f,
+0.279297f, -0.52832f, 0.279297f, -0.464355f, 0.267578f, 0.20752f, 0.222168f, 0.20752f,
+0.187012f, 0.198242f, 0.151855f, 0.188965f, 0.126953f, 0.171631f, 0.102051f, 0.154297f,
+0.0864258f, 0.130371f, 0.0708008f, 0.106445f, 0.0639648f, 0.0771484f, 0.152344f,
+0.0644531f, 0.161133f, 0.101074f, 0.191162f, 0.12085f, 0.221191f, 0.140625f, 0.27002f,
+0.140625f, 0.299805f, 0.140625f, 0.324219f, 0.132324f, 0.348633f, 0.124023f, 0.365723f,
+0.105713f, 0.382812f, 0.0874023f, 0.39209f, 0.0581055f, 0.401367f, 0.0288086f, 0.401367f,
+-0.0131836f, 0.401367f, -0.0981445f, 0.400391f, -0.0981445f, 0.390625f, -0.078125f,
+0.376221f, -0.0598145f, 0.361816f, -0.0415039f, 0.341064f, -0.0273438f, 0.320312f,
+-0.0131836f, 0.292969f, -0.00463867f, 0.265625f, 0.00390625f, 0.230469f, 0.00390625f,
+0.180176f, 0.00390625f, 0.144287f, -0.0129395f, 0.108398f, -0.0297852f, 0.0856934f,
+-0.0634766f, 0.0629883f, -0.097168f, 0.0524902f, -0.147217f, 0.0419922f, -0.197266f,
+0.0419922f, -0.263184f, 0.0419922f, -0.32666f, 0.0524902f, -0.377441f, 0.0629883f,
+-0.428223f, 0.0866699f, -0.463623f, 0.110352f, -0.499023f, 0.148193f, -0.517822f,
+0.186035f, -0.536621f, 0.240234f, -0.536621f, 0.296387f, -0.536621f, 0.337646f, -0.510986f,
+0.378906f, -0.485352f, 0.401367f, -0.437988f, 0.402344f, -0.437988f, 0.402344f, -0.450195f,
+0.403076f, -0.465332f, 0.403809f, -0.480469f, 0.404541f, -0.493896f, 0.405273f, -0.507324f,
+0.40625f, -0.51709f, 0.407227f, -0.526855f, 0.408203f, -0.52832f, 0.491699f, -0.52832f,
+0.491211f, -0.523926f, 0.490723f, -0.513428f, 0.490234f, -0.50293f, 0.489746f, -0.488281f,
+0.489258f, -0.473633f, 0.489014f, -0.455811f, 0.48877f, -0.437988f, 0.48877f, -0.418945f,
+0.48877f, -0.0151367f, 0.48877f, 0.0957031f, 0.434326f, 0.151611f, 0.379883f, 0.20752f,
+0.267578f, 0.20752f, 0.401367f, -0.26416f, 0.401367f, -0.319336f, 0.389404f, -0.358643f,
+0.377441f, -0.397949f, 0.35791f, -0.422852f, 0.338379f, -0.447754f, 0.313232f, -0.459473f,
+0.288086f, -0.471191f, 0.261719f, -0.471191f, 0.228027f, -0.471191f, 0.203857f, -0.459473f,
+0.179688f, -0.447754f, 0.163818f, -0.422607f, 0.147949f, -0.397461f, 0.140381f, -0.358154f,
+0.132812f, -0.318848f, 0.132812f, -0.26416f, 0.132812f, -0.207031f, 0.140381f, -0.168213f,
+0.147949f, -0.129395f, 0.163574f, -0.105469f, 0.179199f, -0.081543f, 0.203125f, -0.0712891f,
+0.227051f, -0.0610352f, 0.260254f, -0.0610352f, 0.286621f, -0.0610352f, 0.311768f,
+-0.0722656f, 0.336914f, -0.0834961f, 0.356934f, -0.10791f, 0.376953f, -0.132324f,
+0.38916f, -0.170898f, 0.401367f, -0.209473f, 0.401367f, -0.26416f, 0.0668945f, -0.640625f,
+0.0668945f, -0.724609f, 0.154785f, -0.724609f, 0.154785f, -0.640625f, 0.0668945f,
+0, 0.0668945f, -0.52832f, 0.154785f, -0.52832f, 0.154785f, 0, 0.0673828f, 0, 0.0673828f,
+-0.724609f, 0.155273f, -0.724609f, 0.155273f, 0, 0.375f, 0, 0.375f, -0.334961f, 0.375f,
+-0.373535f, 0.370117f, -0.399414f, 0.365234f, -0.425293f, 0.35376f, -0.441162f, 0.342285f,
+-0.457031f, 0.32373f, -0.463623f, 0.305176f, -0.470215f, 0.27832f, -0.470215f, 0.250488f,
+-0.470215f, 0.228027f, -0.459229f, 0.205566f, -0.448242f, 0.189697f, -0.42749f, 0.173828f,
+-0.406738f, 0.165283f, -0.376221f, 0.156738f, -0.345703f, 0.156738f, -0.306152f,
+0.156738f, 0, 0.0693359f, 0, 0.0693359f, -0.415527f, 0.0693359f, -0.432129f, 0.0690918f,
+-0.450439f, 0.0688477f, -0.46875f, 0.0683594f, -0.485107f, 0.0678711f, -0.501465f,
+0.0673828f, -0.513184f, 0.0668945f, -0.524902f, 0.0664062f, -0.52832f, 0.149414f,
+-0.52832f, 0.149902f, -0.525879f, 0.150391f, -0.515137f, 0.150879f, -0.504395f, 0.151611f,
+-0.490479f, 0.152344f, -0.476562f, 0.152832f, -0.462158f, 0.15332f, -0.447754f, 0.15332f,
+-0.437988f, 0.154785f, -0.437988f, 0.166504f, -0.460938f, 0.180176f, -0.479492f,
+0.193848f, -0.498047f, 0.212158f, -0.510986f, 0.230469f, -0.523926f, 0.25415f, -0.531006f,
+0.277832f, -0.538086f, 0.309082f, -0.538086f, 0.369141f, -0.538086f, 0.404053f, -0.51416f,
+0.438965f, -0.490234f, 0.452637f, -0.437988f, 0.454102f, -0.437988f, 0.46582f, -0.460938f,
+0.480469f, -0.479492f, 0.495117f, -0.498047f, 0.514648f, -0.510986f, 0.53418f, -0.523926f,
+0.558594f, -0.531006f, 0.583008f, -0.538086f, 0.614258f, -0.538086f, 0.654297f, -0.538086f,
+0.68335f, -0.527344f, 0.712402f, -0.516602f, 0.730957f, -0.494141f, 0.749512f, -0.47168f,
+0.758301f, -0.436279f, 0.76709f, -0.400879f, 0.76709f, -0.352051f, 0.76709f, 0, 0.680176f,
+0, 0.680176f, -0.334961f, 0.680176f, -0.373535f, 0.675293f, -0.399414f, 0.67041f,
+-0.425293f, 0.658936f, -0.441162f, 0.647461f, -0.457031f, 0.628906f, -0.463623f,
+0.610352f, -0.470215f, 0.583496f, -0.470215f, 0.555664f, -0.470215f, 0.533203f, -0.459717f,
+0.510742f, -0.449219f, 0.494873f, -0.428711f, 0.479004f, -0.408203f, 0.470459f, -0.377441f,
+0.461914f, -0.34668f, 0.461914f, -0.306152f, 0.461914f, 0, 0.402832f, 0, 0.402832f,
+-0.334961f, 0.402832f, -0.373535f, 0.397217f, -0.399414f, 0.391602f, -0.425293f,
+0.378906f, -0.441162f, 0.366211f, -0.457031f, 0.345459f, -0.463623f, 0.324707f, -0.470215f,
+0.293945f, -0.470215f, 0.262695f, -0.470215f, 0.237549f, -0.459229f, 0.212402f, -0.448242f,
+0.19458f, -0.42749f, 0.176758f, -0.406738f, 0.166992f, -0.376221f, 0.157227f, -0.345703f,
+0.157227f, -0.306152f, 0.157227f, 0, 0.0693359f, 0, 0.0693359f, -0.415527f, 0.0693359f,
+-0.432129f, 0.0690918f, -0.450439f, 0.0688477f, -0.46875f, 0.0683594f, -0.485107f,
+0.0678711f, -0.501465f, 0.0673828f, -0.513184f, 0.0668945f, -0.524902f, 0.0664062f,
+-0.52832f, 0.149414f, -0.52832f, 0.149902f, -0.525879f, 0.150391f, -0.515137f, 0.150879f,
+-0.504395f, 0.151611f, -0.490479f, 0.152344f, -0.476562f, 0.152832f, -0.462158f,
+0.15332f, -0.447754f, 0.15332f, -0.437988f, 0.154785f, -0.437988f, 0.16748f, -0.460938f,
+0.182617f, -0.479492f, 0.197754f, -0.498047f, 0.217773f, -0.510986f, 0.237793f, -0.523926f,
+0.263672f, -0.531006f, 0.289551f, -0.538086f, 0.32373f, -0.538086f, 0.367676f, -0.538086f,
+0.399414f, -0.527344f, 0.431152f, -0.516602f, 0.45166f, -0.494141f, 0.472168f, -0.47168f,
+0.481689f, -0.436279f, 0.491211f, -0.400879f, 0.491211f, -0.352051f, 0.491211f, 0,
+0.51416f, -0.264648f, 0.51416f, -0.125977f, 0.453125f, -0.0581055f, 0.39209f, 0.00976562f,
+0.275879f, 0.00976562f, 0.220703f, 0.00976562f, 0.177246f, -0.00683594f, 0.133789f,
+-0.0234375f, 0.10376f, -0.0576172f, 0.0737305f, -0.0917969f, 0.0578613f, -0.143311f,
+0.0419922f, -0.194824f, 0.0419922f, -0.264648f, 0.0419922f, -0.538086f, 0.278809f,
+-0.538086f, 0.340332f, -0.538086f, 0.38501f, -0.520996f, 0.429688f, -0.503906f, 0.458252f,
+-0.469727f, 0.486816f, -0.435547f, 0.500488f, -0.384277f, 0.51416f, -0.333008f, 0.51416f,
+-0.264648f, 0.421875f, -0.264648f, 0.421875f, -0.326172f, 0.412354f, -0.366211f,
+0.402832f, -0.40625f, 0.384521f, -0.430176f, 0.366211f, -0.454102f, 0.339844f, -0.463623f,
+0.313477f, -0.473145f, 0.280273f, -0.473145f, 0.246582f, -0.473145f, 0.219482f, -0.463135f,
+0.192383f, -0.453125f, 0.17334f, -0.428955f, 0.154297f, -0.404785f, 0.144287f, -0.364746f,
+0.134277f, -0.324707f, 0.134277f, -0.264648f, 0.134277f, -0.203125f, 0.14502f, -0.162842f,
+0.155762f, -0.122559f, 0.174561f, -0.0986328f, 0.193359f, -0.074707f, 0.218994f,
+-0.0649414f, 0.244629f, -0.0551758f, 0.274902f, -0.0551758f, 0.308594f, -0.0551758f,
+0.335938f, -0.0646973f, 0.363281f, -0.0742188f, 0.382324f, -0.0981445f, 0.401367f,
+-0.12207f, 0.411621f, -0.162598f, 0.421875f, -0.203125f, 0.421875f, -0.264648f, 0.51416f,
+-0.266602f, 0.51416f, -0.206543f, 0.504395f, -0.155762f, 0.494629f, -0.10498f, 0.471924f,
+-0.0683594f, 0.449219f, -0.0317383f, 0.411865f, -0.0109863f, 0.374512f, 0.00976562f,
+0.319824f, 0.00976562f, 0.263184f, 0.00976562f, 0.220703f, -0.0117188f, 0.178223f,
+-0.0332031f, 0.155762f, -0.0820312f, 0.15332f, -0.0820312f, 0.153809f, -0.0810547f,
+0.154053f, -0.0732422f, 0.154297f, -0.0654297f, 0.154541f, -0.0537109f, 0.154785f,
+-0.0419922f, 0.155029f, -0.0275879f, 0.155273f, -0.0131836f, 0.155273f, 0.000976562f,
+0.155273f, 0.20752f, 0.0673828f, 0.20752f, 0.0673828f, -0.42041f, 0.0673828f, -0.439453f,
+0.0671387f, -0.457031f, 0.0668945f, -0.474609f, 0.0664062f, -0.489014f, 0.065918f,
+-0.503418f, 0.0654297f, -0.513672f, 0.0649414f, -0.523926f, 0.0644531f, -0.52832f,
+0.149414f, -0.52832f, 0.149902f, -0.526855f, 0.150635f, -0.518066f, 0.151367f, -0.509277f,
+0.1521f, -0.496826f, 0.152832f, -0.484375f, 0.153564f, -0.470215f, 0.154297f, -0.456055f,
+0.154297f, -0.443359f, 0.15625f, -0.443359f, 0.168457f, -0.46875f, 0.184082f, -0.486572f,
+0.199707f, -0.504395f, 0.219727f, -0.515869f, 0.239746f, -0.527344f, 0.264404f, -0.532471f,
+0.289062f, -0.537598f, 0.319824f, -0.537598f, 0.374512f, -0.537598f, 0.411865f, -0.518066f,
+0.449219f, -0.498535f, 0.471924f, -0.463135f, 0.494629f, -0.427734f, 0.504395f, -0.377686f,
+0.51416f, -0.327637f, 0.51416f, -0.266602f, 0.421875f, -0.264648f, 0.421875f, -0.313477f,
+0.416016f, -0.351562f, 0.410156f, -0.389648f, 0.395752f, -0.416016f, 0.381348f, -0.442383f,
+0.357422f, -0.456055f, 0.333496f, -0.469727f, 0.297363f, -0.469727f, 0.268066f, -0.469727f,
+0.242188f, -0.461426f, 0.216309f, -0.453125f, 0.197021f, -0.429688f, 0.177734f, -0.40625f,
+0.166504f, -0.36499f, 0.155273f, -0.32373f, 0.155273f, -0.257812f, 0.155273f, -0.20166f,
+0.164551f, -0.162842f, 0.173828f, -0.124023f, 0.19165f, -0.100098f, 0.209473f, -0.0761719f,
+0.23584f, -0.0656738f, 0.262207f, -0.0551758f, 0.296387f, -0.0551758f, 0.333008f,
+-0.0551758f, 0.357178f, -0.0693359f, 0.381348f, -0.0834961f, 0.395752f, -0.110352f,
+0.410156f, -0.137207f, 0.416016f, -0.176025f, 0.421875f, -0.214844f, 0.421875f, -0.264648f,
+0.236328f, 0.00976562f, 0.135742f, 0.00976562f, 0.0888672f, -0.0581055f, 0.0419922f,
+-0.125977f, 0.0419922f, -0.261719f, 0.0419922f, -0.399414f, 0.0900879f, -0.46875f,
+0.138184f, -0.538086f, 0.236328f, -0.538086f, 0.269043f, -0.538086f, 0.294189f, -0.532227f,
+0.319336f, -0.526367f, 0.339111f, -0.514893f, 0.358887f, -0.503418f, 0.373779f, -0.486328f,
+0.388672f, -0.469238f, 0.400879f, -0.446289f, 0.401855f, -0.446289f, 0.401855f, -0.458496f,
+0.402588f, -0.473389f, 0.40332f, -0.488281f, 0.404053f, -0.501465f, 0.404785f, -0.514648f,
+0.405762f, -0.52417f, 0.406738f, -0.533691f, 0.407715f, -0.535156f, 0.492188f, -0.535156f,
+0.491211f, -0.526855f, 0.48999f, -0.491699f, 0.48877f, -0.456543f, 0.48877f, -0.391113f,
+0.48877f, 0.20752f, 0.400879f, 0.20752f, 0.400879f, -0.00683594f, 0.400879f, -0.0195312f,
+0.401123f, -0.0332031f, 0.401367f, -0.046875f, 0.401855f, -0.059082f, 0.402344f,
+-0.0727539f, 0.402832f, -0.0869141f, 0.401855f, -0.0869141f, 0.38916f, -0.0620117f,
+0.373779f, -0.0437012f, 0.358398f, -0.0253906f, 0.338379f, -0.0134277f, 0.318359f,
+-0.00146484f, 0.293213f, 0.00415039f, 0.268066f, 0.00976562f, 0.236328f, 0.00976562f,
+0.400879f, -0.270508f, 0.400879f, -0.328125f, 0.390869f, -0.367188f, 0.380859f, -0.40625f,
+0.362549f, -0.429688f, 0.344238f, -0.453125f, 0.318115f, -0.463135f, 0.291992f, -0.473145f,
+0.259766f, -0.473145f, 0.226074f, -0.473145f, 0.202148f, -0.460693f, 0.178223f, -0.448242f,
+0.16333f, -0.422607f, 0.148438f, -0.396973f, 0.141357f, -0.357666f, 0.134277f, -0.318359f,
+0.134277f, -0.264648f, 0.134277f, -0.211914f, 0.140869f, -0.172852f, 0.147461f, -0.133789f,
+0.162354f, -0.108398f, 0.177246f, -0.0830078f, 0.200928f, -0.0705566f, 0.224609f,
+-0.0581055f, 0.258789f, -0.0581055f, 0.288086f, -0.0581055f, 0.313965f, -0.0671387f,
+0.339844f, -0.0761719f, 0.359131f, -0.0998535f, 0.378418f, -0.123535f, 0.389648f,
+-0.164795f, 0.400879f, -0.206055f, 0.400879f, -0.270508f, 0.0693359f, 0, 0.0693359f,
+-0.405273f, 0.0693359f, -0.421875f, 0.0690918f, -0.439209f, 0.0688477f, -0.456543f,
+0.0683594f, -0.472656f, 0.0678711f, -0.48877f, 0.0673828f, -0.50293f, 0.0668945f,
+-0.51709f, 0.0664062f, -0.52832f, 0.149414f, -0.52832f, 0.149902f, -0.51709f, 0.150635f,
+-0.502686f, 0.151367f, -0.488281f, 0.1521f, -0.473145f, 0.152832f, -0.458008f, 0.153076f,
+-0.444092f, 0.15332f, -0.430176f, 0.15332f, -0.42041f, 0.155273f, -0.42041f, 0.164551f,
+-0.450684f, 0.175049f, -0.4729f, 0.185547f, -0.495117f, 0.199707f, -0.509521f, 0.213867f,
+-0.523926f, 0.233398f, -0.531006f, 0.25293f, -0.538086f, 0.280762f, -0.538086f, 0.291504f,
+-0.538086f, 0.30127f, -0.536377f, 0.311035f, -0.534668f, 0.316406f, -0.533203f, 0.316406f,
+-0.452637f, 0.307617f, -0.455078f, 0.295898f, -0.456299f, 0.28418f, -0.45752f, 0.269531f,
+-0.45752f, 0.239258f, -0.45752f, 0.218018f, -0.443848f, 0.196777f, -0.430176f, 0.18335f,
+-0.406006f, 0.169922f, -0.381836f, 0.163574f, -0.348389f, 0.157227f, -0.314941f,
+0.157227f, -0.275391f, 0.157227f, 0, 0.463867f, -0.145996f, 0.463867f, -0.108887f,
+0.449463f, -0.079834f, 0.435059f, -0.0507812f, 0.407715f, -0.0310059f, 0.380371f,
+-0.0112305f, 0.340576f, -0.000732422f, 0.300781f, 0.00976562f, 0.249512f, 0.00976562f,
+0.203613f, 0.00976562f, 0.166748f, 0.00268555f, 0.129883f, -0.00439453f, 0.102051f,
+-0.0200195f, 0.0742188f, -0.0356445f, 0.0554199f, -0.0612793f, 0.0366211f, -0.0869141f,
+0.027832f, -0.124023f, 0.105469f, -0.13916f, 0.116699f, -0.0966797f, 0.151855f, -0.0769043f,
+0.187012f, -0.0571289f, 0.249512f, -0.0571289f, 0.277832f, -0.0571289f, 0.301514f,
+-0.0610352f, 0.325195f, -0.0649414f, 0.342285f, -0.0744629f, 0.359375f, -0.0839844f,
+0.368896f, -0.0998535f, 0.378418f, -0.115723f, 0.378418f, -0.13916f, 0.378418f, -0.163086f,
+0.367188f, -0.178467f, 0.355957f, -0.193848f, 0.335938f, -0.204102f, 0.315918f, -0.214355f,
+0.287354f, -0.221924f, 0.258789f, -0.229492f, 0.224609f, -0.23877f, 0.192871f, -0.24707f,
+0.161621f, -0.257324f, 0.130371f, -0.267578f, 0.105225f, -0.284424f, 0.0800781f,
+-0.30127f, 0.0644531f, -0.326172f, 0.0488281f, -0.351074f, 0.0488281f, -0.388672f,
+0.0488281f, -0.460938f, 0.100342f, -0.498779f, 0.151855f, -0.536621f, 0.250488f,
+-0.536621f, 0.337891f, -0.536621f, 0.389404f, -0.505859f, 0.440918f, -0.475098f,
+0.45459f, -0.407227f, 0.375488f, -0.397461f, 0.371094f, -0.417969f, 0.359375f, -0.431885f,
+0.347656f, -0.445801f, 0.331055f, -0.454346f, 0.314453f, -0.462891f, 0.293701f, -0.466553f,
+0.272949f, -0.470215f, 0.250488f, -0.470215f, 0.190918f, -0.470215f, 0.162598f, -0.452148f,
+0.134277f, -0.434082f, 0.134277f, -0.397461f, 0.134277f, -0.375977f, 0.144775f, -0.362061f,
+0.155273f, -0.348145f, 0.174072f, -0.338623f, 0.192871f, -0.329102f, 0.219238f, -0.322021f,
+0.245605f, -0.314941f, 0.277344f, -0.307129f, 0.29834f, -0.301758f, 0.320312f, -0.295654f,
+0.342285f, -0.289551f, 0.363037f, -0.281006f, 0.383789f, -0.272461f, 0.4021f, -0.260986f,
+0.42041f, -0.249512f, 0.434082f, -0.233398f, 0.447754f, -0.217285f, 0.455811f, -0.195801f,
+0.463867f, -0.174316f, 0.463867f, -0.145996f, 0.270508f, -0.00390625f, 0.250488f,
+0.00146484f, 0.229736f, 0.00463867f, 0.208984f, 0.0078125f, 0.181641f, 0.0078125f,
+0.0761719f, 0.0078125f, 0.0761719f, -0.111816f, 0.0761719f, -0.464355f, 0.0151367f,
+-0.464355f, 0.0151367f, -0.52832f, 0.0795898f, -0.52832f, 0.105469f, -0.646484f,
+0.164062f, -0.646484f, 0.164062f, -0.52832f, 0.261719f, -0.52832f, 0.261719f, -0.464355f,
+0.164062f, -0.464355f, 0.164062f, -0.130859f, 0.164062f, -0.0927734f, 0.176514f,
+-0.0773926f, 0.188965f, -0.0620117f, 0.219727f, -0.0620117f, 0.232422f, -0.0620117f,
+0.244385f, -0.0639648f, 0.256348f, -0.065918f, 0.270508f, -0.0688477f, 0.15332f,
+-0.52832f, 0.15332f, -0.193359f, 0.15332f, -0.154785f, 0.158936f, -0.128906f, 0.164551f,
+-0.103027f, 0.177246f, -0.0871582f, 0.189941f, -0.0712891f, 0.210693f, -0.0646973f,
+0.231445f, -0.0581055f, 0.262207f, -0.0581055f, 0.293457f, -0.0581055f, 0.318604f,
+-0.0690918f, 0.34375f, -0.0800781f, 0.361572f, -0.10083f, 0.379395f, -0.121582f,
+0.38916f, -0.1521f, 0.398926f, -0.182617f, 0.398926f, -0.222168f, 0.398926f, -0.52832f,
+0.486816f, -0.52832f, 0.486816f, -0.112793f, 0.486816f, -0.0961914f, 0.487061f, -0.0778809f,
+0.487305f, -0.0595703f, 0.487793f, -0.0432129f, 0.488281f, -0.0268555f, 0.48877f,
+-0.0151367f, 0.489258f, -0.00341797f, 0.489746f, 0, 0.406738f, 0, 0.40625f, -0.00244141f,
+0.405762f, -0.0131836f, 0.405273f, -0.0239258f, 0.404541f, -0.0378418f, 0.403809f,
+-0.0517578f, 0.40332f, -0.0661621f, 0.402832f, -0.0805664f, 0.402832f, -0.090332f,
+0.401367f, -0.090332f, 0.388672f, -0.0673828f, 0.373535f, -0.0488281f, 0.358398f,
+-0.0302734f, 0.338379f, -0.017334f, 0.318359f, -0.00439453f, 0.29248f, 0.00268555f,
+0.266602f, 0.00976562f, 0.232422f, 0.00976562f, 0.188477f, 0.00976562f, 0.156738f,
+-0.000976562f, 0.125f, -0.0117188f, 0.104492f, -0.0341797f, 0.0839844f, -0.0566406f,
+0.0744629f, -0.0917969f, 0.0649414f, -0.126953f, 0.0649414f, -0.17627f, 0.0649414f,
+-0.52832f, 0.299316f, 0, 0.195312f, 0, 0.00341797f, -0.52832f, 0.097168f, -0.52832f,
+0.213379f, -0.18457f, 0.216797f, -0.173828f, 0.221436f, -0.158447f, 0.226074f, -0.143066f,
+0.230957f, -0.126465f, 0.23584f, -0.109863f, 0.23999f, -0.0944824f, 0.244141f, -0.0791016f,
+0.24707f, -0.0688477f, 0.25f, -0.0791016f, 0.254639f, -0.0944824f, 0.259277f, -0.109863f,
+0.26416f, -0.125977f, 0.269043f, -0.14209f, 0.27417f, -0.157471f, 0.279297f, -0.172852f,
+0.283203f, -0.183594f, 0.40332f, -0.52832f, 0.496582f, -0.52832f, 0.573242f, 0, 0.471191f,
+0, 0.386719f, -0.34082f, 0.382812f, -0.354004f, 0.378662f, -0.373535f, 0.374512f,
+-0.393066f, 0.370605f, -0.411621f, 0.365723f, -0.433105f, 0.361328f, -0.456055f,
+0.356934f, -0.434082f, 0.352051f, -0.412598f, 0.348145f, -0.394043f, 0.343506f, -0.374023f,
+0.338867f, -0.354004f, 0.334961f, -0.338867f, 0.248047f, 0, 0.146484f, 0, -0.00146484f,
+-0.52832f, 0.0854492f, -0.52832f, 0.174805f, -0.169434f, 0.178223f, -0.158203f, 0.181641f,
+-0.141846f, 0.185059f, -0.125488f, 0.188477f, -0.109863f, 0.191895f, -0.0917969f,
+0.195801f, -0.0727539f, 0.199707f, -0.0913086f, 0.204102f, -0.108887f, 0.208008f,
+-0.124023f, 0.211914f, -0.139648f, 0.21582f, -0.155273f, 0.21875f, -0.165527f, 0.314453f,
+-0.52832f, 0.408691f, -0.52832f, 0.500977f, -0.165527f, 0.504395f, -0.152832f, 0.508301f,
+-0.136719f, 0.512207f, -0.120605f, 0.515625f, -0.106445f, 0.519531f, -0.0898438f,
+0.523438f, -0.0727539f, 0.527344f, -0.0913086f, 0.53125f, -0.108887f, 0.534668f,
+-0.124023f, 0.53833f, -0.140381f, 0.541992f, -0.156738f, 0.54541f, -0.169434f, 0.638672f,
+-0.52832f, 0.724609f, -0.52832f, 0.391113f, 0, 0.249023f, -0.216797f, 0.105957f,
+0, 0.0112305f, 0, 0.199219f, -0.271484f, 0.0200195f, -0.52832f, 0.117188f, -0.52832f,
+0.249023f, -0.322754f, 0.379883f, -0.52832f, 0.478027f, -0.52832f, 0.298828f, -0.272461f,
+0.489258f, 0, 0.294922f, 0, 0.276367f, 0.0478516f, 0.25708f, 0.0861816f, 0.237793f,
+0.124512f, 0.213867f, 0.151611f, 0.189941f, 0.178711f, 0.160645f, 0.193115f, 0.131348f,
+0.20752f, 0.0932617f, 0.20752f, 0.0766602f, 0.20752f, 0.0625f, 0.206543f, 0.0483398f,
+0.205566f, 0.0327148f, 0.202148f, 0.0327148f, 0.13623f, 0.0419922f, 0.137695f, 0.0537109f,
+0.138428f, 0.0654297f, 0.13916f, 0.0737305f, 0.13916f, 0.112305f, 0.13916f, 0.145508f,
+0.110352f, 0.178711f, 0.081543f, 0.203613f, 0.0185547f, 0.211914f, -0.00244141f,
+0.00244141f, -0.52832f, 0.0961914f, -0.52832f, 0.20752f, -0.236328f, 0.212402f, -0.223145f,
+0.219971f, -0.201172f, 0.227539f, -0.179199f, 0.235107f, -0.157227f, 0.242676f, -0.135254f,
+0.248535f, -0.117676f, 0.254395f, -0.100098f, 0.255371f, -0.0957031f, 0.256836f,
+-0.101074f, 0.262451f, -0.116943f, 0.268066f, -0.132812f, 0.275146f, -0.152344f,
+0.282227f, -0.171875f, 0.289551f, -0.191895f, 0.296875f, -0.211914f, 0.301758f, -0.226562f,
+0.405273f, -0.52832f, 0.498047f, -0.52832f, 0.0239258f, 0, 0.0239258f, -0.0668945f,
+0.34668f, -0.460449f, 0.043457f, -0.460449f, 0.043457f, -0.52832f, 0.445801f, -0.52832f,
+0.445801f, -0.461426f, 0.122559f, -0.0678711f, 0.463867f, -0.0678711f, 0.463867f,
+0
+};
+
+const unsigned char LiberationSanskNormalVerbs[] = {
+6, 0, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 1, 1, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 2, 2, 1, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5,
+6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6,
+0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6,
+0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 5, 0, 1,
+1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1,
+1, 1, 5, 6, 0, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 5, 6, 0, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0,
+1, 1, 1, 1, 1, 1, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1,
+1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 0,
+2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 1,
+1, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1,
+5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1,
+1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+5, 0, 2, 2, 1, 1, 1, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 0, 2, 2,
+2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1,
+2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1,
+1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2,
+1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2,
+1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 0, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1,
+1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2,
+2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 5, 0,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2,
+2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 2, 2, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 5, 6
+};
+
+const unsigned LiberationSanskNormalCharCodes[] = {
+32, 33, 35, 37, 38, 39, 41, 42, 43, 45, 46, 47, 49, 50,
+52, 53, 54, 55, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73,
+74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+96, 97, 98, 99, 100, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115,
+116, 117, 118, 119, 120, 121, 122
+};
+
+const SkFixed LiberationSanskNormalWidths[] = {
+0x00004720, 0x00004720, 0x00008e60, 0x0000e3a0, 0x0000aac0, 0x000030e0, 0x00005540,
+0x000063a0, 0x00009580, 0x00005540, 0x00004720, 0x00004720, 0x00008e60, 0x00008e60,
+0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60, 0x00004720, 0x00004720,
+0x00009580, 0x00009580, 0x00009580, 0x00008e60, 0x000103e0, 0x0000aac0, 0x0000aac0,
+0x0000b8e0, 0x0000b8e0, 0x0000aac0, 0x00009c60, 0x0000b8e0, 0x00004720, 0x00008000,
+0x0000aac0, 0x00008e60, 0x0000d540, 0x0000b8e0, 0x0000c720, 0x0000aac0, 0x0000c720,
+0x0000b8e0, 0x0000aac0, 0x00009c60, 0x0000aac0, 0x0000f1a0, 0x0000aac0, 0x0000aac0,
+0x00009c60, 0x00004720, 0x00004720, 0x00004720, 0x00007820, 0x00005540, 0x00008e60,
+0x00008e60, 0x00008000, 0x00008e60, 0x00008e60, 0x00004720, 0x00008e60, 0x000038e0,
+0x000038e0, 0x0000d540, 0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60, 0x00005540,
+0x00008000, 0x00004720, 0x00008e60, 0x00008000, 0x0000b8e0, 0x00008000, 0x00008000,
+0x00008000
+};
+
+const int LiberationSanskNormalCharCodesCount = (int) SK_ARRAY_COUNT(LiberationSanskNormalCharCodes);
+
+const SkPaint::FontMetrics LiberationSanskNormalMetrics = {
+0x00000003, -0.910156f, -0.905273f, 0.211914f, 0.303223f, 0.0327148f, 1.25342f, 0,
+-0.203125f, 1.05029f, 0.538086f, 0, 0.0732422f, 0.105957f
+};
+
+const SkScalar LiberationSanskBoldPoints[] = {
+0.222168f, -0.208008f, 0.109863f, -0.208008f, 0.0942383f, -0.687988f, 0.237793f, -0.687988f,
+0.0942383f, 0, 0.0942383f, -0.131836f, 0.234863f, -0.131836f, 0.234863f, 0, 0.394043f,
+-0.438477f, 0.287109f, -0.438477f, 0.273926f, -0.687988f, 0.408203f, -0.687988f,
+0.186035f, -0.438477f, 0.0791016f, -0.438477f, 0.065918f, -0.687988f, 0.199219f,
+-0.687988f, 0.443848f, -0.420898f, 0.410156f, -0.258789f, 0.515137f, -0.258789f,
+0.515137f, -0.186035f, 0.39502f, -0.186035f, 0.35498f, 0, 0.278809f, 0, 0.317871f,
+-0.186035f, 0.167969f, -0.186035f, 0.128906f, 0, 0.0541992f, 0, 0.0927734f, -0.186035f,
+0.0170898f, -0.186035f, 0.0170898f, -0.258789f, 0.108887f, -0.258789f, 0.143066f,
+-0.420898f, 0.0419922f, -0.420898f, 0.0419922f, -0.493164f, 0.158203f, -0.493164f,
+0.199219f, -0.681152f, 0.273926f, -0.681152f, 0.233887f, -0.493164f, 0.383789f, -0.493164f,
+0.424805f, -0.681152f, 0.500977f, -0.681152f, 0.459961f, -0.493164f, 0.540039f, -0.493164f,
+0.540039f, -0.420898f, 0.219238f, -0.420898f, 0.184082f, -0.258789f, 0.334961f, -0.258789f,
+0.369141f, -0.420898f, 0.541992f, -0.201172f, 0.541992f, -0.159668f, 0.52832f, -0.125732f,
+0.514648f, -0.0917969f, 0.486084f, -0.0671387f, 0.45752f, -0.0424805f, 0.413086f,
+-0.0280762f, 0.368652f, -0.0136719f, 0.307129f, -0.0112305f, 0.307129f, 0.0742188f,
+0.253906f, 0.0742188f, 0.253906f, -0.00976562f, 0.198242f, -0.0117188f, 0.156982f,
+-0.0249023f, 0.115723f, -0.0380859f, 0.0866699f, -0.0620117f, 0.0576172f, -0.0859375f,
+0.0397949f, -0.120361f, 0.0219727f, -0.154785f, 0.0131836f, -0.199219f, 0.138184f,
+-0.222168f, 0.14209f, -0.19873f, 0.149658f, -0.179443f, 0.157227f, -0.160156f, 0.17041f,
+-0.145996f, 0.183594f, -0.131836f, 0.203857f, -0.122803f, 0.224121f, -0.11377f, 0.253906f,
+-0.11084f, 0.253906f, -0.301758f, 0.252441f, -0.302734f, 0.246582f, -0.303955f, 0.240723f,
+-0.305176f, 0.23877f, -0.305176f, 0.200684f, -0.313965f, 0.164062f, -0.326904f, 0.127441f,
+-0.339844f, 0.098877f, -0.362061f, 0.0703125f, -0.384277f, 0.0527344f, -0.418213f,
+0.0351562f, -0.452148f, 0.0351562f, -0.50293f, 0.0351562f, -0.547363f, 0.0512695f,
+-0.579346f, 0.0673828f, -0.611328f, 0.0964355f, -0.632324f, 0.125488f, -0.65332f,
+0.165771f, -0.664062f, 0.206055f, -0.674805f, 0.253906f, -0.676758f, 0.253906f, -0.742188f,
+0.307129f, -0.742188f, 0.307129f, -0.676758f, 0.359375f, -0.674805f, 0.395996f, -0.663086f,
+0.432617f, -0.651367f, 0.458008f, -0.630127f, 0.483398f, -0.608887f, 0.499023f, -0.577881f,
+0.514648f, -0.546875f, 0.524902f, -0.505859f, 0.395996f, -0.486816f, 0.388672f, -0.529297f,
+0.367432f, -0.55249f, 0.346191f, -0.575684f, 0.307129f, -0.581055f, 0.307129f, -0.40918f,
+0.30957f, -0.408203f, 0.312256f, -0.408203f, 0.314941f, -0.408203f, 0.317871f, -0.407227f,
+0.359863f, -0.397461f, 0.400146f, -0.384277f, 0.44043f, -0.371094f, 0.471924f, -0.348633f,
+0.503418f, -0.326172f, 0.522705f, -0.290771f, 0.541992f, -0.255371f, 0.541992f, -0.201172f,
+0.253906f, -0.583008f, 0.228027f, -0.581055f, 0.210693f, -0.574219f, 0.193359f, -0.567383f,
+0.182617f, -0.556885f, 0.171875f, -0.546387f, 0.16748f, -0.532959f, 0.163086f, -0.519531f,
+0.163086f, -0.504883f, 0.163086f, -0.483887f, 0.169922f, -0.470459f, 0.176758f, -0.457031f,
+0.188965f, -0.448242f, 0.201172f, -0.439453f, 0.217773f, -0.43335f, 0.234375f, -0.427246f,
+0.253906f, -0.420898f, 0.415039f, -0.199219f, 0.415039f, -0.223145f, 0.406738f, -0.238037f,
+0.398438f, -0.25293f, 0.383789f, -0.262207f, 0.369141f, -0.271484f, 0.349365f, -0.277588f,
+0.32959f, -0.283691f, 0.307129f, -0.290039f, 0.307129f, -0.11084f, 0.358887f, -0.114258f,
+0.386963f, -0.135254f, 0.415039f, -0.15625f, 0.415039f, -0.199219f, 0.862793f, -0.210938f,
+0.862793f, -0.149902f, 0.849121f, -0.10791f, 0.835449f, -0.065918f, 0.812012f, -0.0402832f,
+0.788574f, -0.0146484f, 0.75708f, -0.00341797f, 0.725586f, 0.0078125f, 0.689941f,
+0.0078125f, 0.65332f, 0.0078125f, 0.621826f, -0.00341797f, 0.590332f, -0.0146484f,
+0.567139f, -0.0402832f, 0.543945f, -0.065918f, 0.530518f, -0.10791f, 0.51709f, -0.149902f,
+0.51709f, -0.210938f, 0.51709f, -0.275391f, 0.530518f, -0.317627f, 0.543945f, -0.359863f,
+0.567383f, -0.38501f, 0.59082f, -0.410156f, 0.622803f, -0.420166f, 0.654785f, -0.430176f,
+0.691895f, -0.430176f, 0.727051f, -0.430176f, 0.758301f, -0.420166f, 0.789551f, -0.410156f,
+0.812744f, -0.38501f, 0.835938f, -0.359863f, 0.849365f, -0.317627f, 0.862793f, -0.275391f,
+0.862793f, -0.210938f, 0.269531f, 0, 0.168945f, 0, 0.618164f, -0.687988f, 0.720215f,
+-0.687988f, 0.199219f, -0.695801f, 0.234375f, -0.695801f, 0.265625f, -0.685791f,
+0.296875f, -0.675781f, 0.320312f, -0.650879f, 0.34375f, -0.625977f, 0.357422f, -0.58374f,
+0.371094f, -0.541504f, 0.371094f, -0.477051f, 0.371094f, -0.416016f, 0.357422f, -0.374023f,
+0.34375f, -0.332031f, 0.320068f, -0.306152f, 0.296387f, -0.280273f, 0.264648f, -0.269043f,
+0.23291f, -0.257812f, 0.196777f, -0.257812f, 0.161133f, -0.257812f, 0.129639f, -0.269043f,
+0.0981445f, -0.280273f, 0.0749512f, -0.305908f, 0.0517578f, -0.331543f, 0.0383301f,
+-0.373535f, 0.0249023f, -0.415527f, 0.0249023f, -0.477051f, 0.0249023f, -0.541504f,
+0.0380859f, -0.58374f, 0.0512695f, -0.625977f, 0.074707f, -0.650879f, 0.0981445f,
+-0.675781f, 0.130127f, -0.685791f, 0.162109f, -0.695801f, 0.199219f, -0.695801f,
+0.757812f, -0.210938f, 0.757812f, -0.253418f, 0.753662f, -0.28125f, 0.749512f, -0.309082f,
+0.741211f, -0.325439f, 0.73291f, -0.341797f, 0.720703f, -0.348389f, 0.708496f, -0.35498f,
+0.691895f, -0.35498f, 0.673828f, -0.35498f, 0.660889f, -0.348389f, 0.647949f, -0.341797f,
+0.639648f, -0.325195f, 0.631348f, -0.308594f, 0.627197f, -0.280762f, 0.623047f, -0.25293f,
+0.623047f, -0.210938f, 0.623047f, -0.169922f, 0.626953f, -0.142822f, 0.630859f, -0.115723f,
+0.639404f, -0.0991211f, 0.647949f, -0.0825195f, 0.660645f, -0.0756836f, 0.67334f,
+-0.0688477f, 0.690918f, -0.0688477f, 0.707031f, -0.0688477f, 0.719482f, -0.0756836f,
+0.731934f, -0.0825195f, 0.740479f, -0.098877f, 0.749023f, -0.115234f, 0.753418f,
+-0.142578f, 0.757812f, -0.169922f, 0.757812f, -0.210938f, 0.265137f, -0.477051f,
+0.265137f, -0.519043f, 0.260986f, -0.546631f, 0.256836f, -0.574219f, 0.248535f, -0.590576f,
+0.240234f, -0.606934f, 0.228027f, -0.613525f, 0.21582f, -0.620117f, 0.199219f, -0.620117f,
+0.181152f, -0.620117f, 0.167969f, -0.613281f, 0.154785f, -0.606445f, 0.146484f, -0.590088f,
+0.138184f, -0.57373f, 0.134033f, -0.546143f, 0.129883f, -0.518555f, 0.129883f, -0.477051f,
+0.129883f, -0.436035f, 0.134033f, -0.408691f, 0.138184f, -0.381348f, 0.146729f, -0.364746f,
+0.155273f, -0.348145f, 0.167969f, -0.341064f, 0.180664f, -0.333984f, 0.198242f, -0.333984f,
+0.214844f, -0.333984f, 0.227295f, -0.34082f, 0.239746f, -0.347656f, 0.248291f, -0.364258f,
+0.256836f, -0.380859f, 0.260986f, -0.408447f, 0.265137f, -0.436035f, 0.265137f, -0.477051f,
+0.0439453f, -0.187988f, 0.0439453f, -0.226562f, 0.0563965f, -0.257812f, 0.0688477f,
+-0.289062f, 0.0908203f, -0.314453f, 0.112793f, -0.339844f, 0.143066f, -0.360107f,
+0.17334f, -0.380371f, 0.208984f, -0.396973f, 0.193359f, -0.428711f, 0.183105f, -0.464844f,
+0.172852f, -0.500977f, 0.172852f, -0.533203f, 0.172852f, -0.56543f, 0.182617f, -0.594238f,
+0.192383f, -0.623047f, 0.214355f, -0.644775f, 0.236328f, -0.666504f, 0.271484f, -0.679199f,
+0.306641f, -0.691895f, 0.356934f, -0.691895f, 0.396484f, -0.691895f, 0.428955f, -0.682373f,
+0.461426f, -0.672852f, 0.484863f, -0.654297f, 0.508301f, -0.635742f, 0.52124f, -0.608887f,
+0.53418f, -0.582031f, 0.53418f, -0.546875f, 0.53418f, -0.51123f, 0.518066f, -0.483643f,
+0.501953f, -0.456055f, 0.475342f, -0.433838f, 0.44873f, -0.411621f, 0.414062f, -0.393311f,
+0.379395f, -0.375f, 0.342773f, -0.35791f, 0.367676f, -0.313965f, 0.397461f, -0.273193f,
+0.427246f, -0.232422f, 0.461914f, -0.193848f, 0.489258f, -0.235352f, 0.507812f, -0.279053f,
+0.526367f, -0.322754f, 0.539062f, -0.371094f, 0.641113f, -0.336914f, 0.624512f, -0.279785f,
+0.601562f, -0.229492f, 0.578613f, -0.179199f, 0.546875f, -0.131836f, 0.568848f, -0.113281f,
+0.59082f, -0.104736f, 0.612793f, -0.0961914f, 0.633789f, -0.0961914f, 0.649414f,
+-0.0961914f, 0.663818f, -0.0981445f, 0.678223f, -0.100098f, 0.690918f, -0.104004f,
+0.690918f, -0.00488281f, 0.664062f, 0.00585938f, 0.626953f, 0.00585938f, 0.602051f,
+0.00585938f, 0.579102f, 0.000976562f, 0.556152f, -0.00390625f, 0.535645f, -0.0119629f,
+0.515137f, -0.0200195f, 0.497559f, -0.0307617f, 0.47998f, -0.0415039f, 0.46582f,
+-0.0532227f, 0.449707f, -0.0410156f, 0.429932f, -0.029541f, 0.410156f, -0.0180664f,
+0.386963f, -0.00927734f, 0.36377f, -0.000488281f, 0.337158f, 0.00463867f, 0.310547f,
+0.00976562f, 0.280762f, 0.00976562f, 0.219238f, 0.00976562f, 0.174316f, -0.00537109f,
+0.129395f, -0.0205078f, 0.100586f, -0.046875f, 0.0717773f, -0.0732422f, 0.0578613f,
+-0.109375f, 0.0439453f, -0.145508f, 0.0439453f, -0.187988f, 0.424805f, -0.545898f,
+0.424805f, -0.57373f, 0.40625f, -0.591309f, 0.387695f, -0.608887f, 0.355957f, -0.608887f,
+0.318359f, -0.608887f, 0.298584f, -0.587891f, 0.278809f, -0.566895f, 0.278809f, -0.532227f,
+0.278809f, -0.508789f, 0.286377f, -0.484375f, 0.293945f, -0.459961f, 0.305176f, -0.437988f,
+0.330078f, -0.44873f, 0.352051f, -0.459717f, 0.374023f, -0.470703f, 0.390137f, -0.483643f,
+0.40625f, -0.496582f, 0.415527f, -0.511719f, 0.424805f, -0.526855f, 0.424805f, -0.545898f,
+0.384766f, -0.120117f, 0.347168f, -0.162109f, 0.313477f, -0.208008f, 0.279785f, -0.253906f,
+0.251953f, -0.304199f, 0.211426f, -0.285156f, 0.189697f, -0.257324f, 0.167969f, -0.229492f,
+0.167969f, -0.189941f, 0.167969f, -0.16748f, 0.175537f, -0.147949f, 0.183105f, -0.128418f,
+0.197754f, -0.114014f, 0.212402f, -0.0996094f, 0.234619f, -0.0913086f, 0.256836f,
+-0.0830078f, 0.286133f, -0.0830078f, 0.317871f, -0.0830078f, 0.343506f, -0.0947266f,
+0.369141f, -0.106445f, 0.384766f, -0.120117f, 0.172852f, -0.438477f, 0.065918f, -0.438477f,
+0.0532227f, -0.687988f, 0.186035f, -0.687988f, 0.194824f, 0.20752f, 0.157227f, 0.15332f,
+0.129883f, 0.0996094f, 0.102539f, 0.0458984f, 0.0847168f, -0.0107422f, 0.0668945f,
+-0.0673828f, 0.0583496f, -0.128662f, 0.0498047f, -0.189941f, 0.0498047f, -0.259277f,
+0.0498047f, -0.329102f, 0.0583496f, -0.389893f, 0.0668945f, -0.450684f, 0.0847168f,
+-0.50708f, 0.102539f, -0.563477f, 0.129883f, -0.616943f, 0.157227f, -0.67041f, 0.194824f,
+-0.724609f, 0.332031f, -0.724609f, 0.292969f, -0.667969f, 0.265137f, -0.612793f,
+0.237305f, -0.557617f, 0.219482f, -0.500977f, 0.20166f, -0.444336f, 0.193359f, -0.384521f,
+0.185059f, -0.324707f, 0.185059f, -0.258789f, 0.185059f, -0.192383f, 0.193359f, -0.132568f,
+0.20166f, -0.0727539f, 0.219482f, -0.0161133f, 0.237305f, 0.0405273f, 0.265137f,
+0.095459f, 0.292969f, 0.150391f, 0.332031f, 0.20752f, 0.000976562f, 0.20752f, 0.0400391f,
+0.150391f, 0.0678711f, 0.095459f, 0.0957031f, 0.0405273f, 0.113525f, -0.0161133f,
+0.131348f, -0.0727539f, 0.139648f, -0.132568f, 0.147949f, -0.192383f, 0.147949f,
+-0.258789f, 0.147949f, -0.324707f, 0.139648f, -0.384521f, 0.131348f, -0.444336f,
+0.113525f, -0.500977f, 0.0957031f, -0.557617f, 0.0678711f, -0.612793f, 0.0400391f,
+-0.667969f, 0.000976562f, -0.724609f, 0.138184f, -0.724609f, 0.175781f, -0.67041f,
+0.203125f, -0.616943f, 0.230469f, -0.563477f, 0.248291f, -0.50708f, 0.266113f, -0.450684f,
+0.274658f, -0.389893f, 0.283203f, -0.329102f, 0.283203f, -0.259277f, 0.283203f, -0.189941f,
+0.274658f, -0.128662f, 0.266113f, -0.0673828f, 0.248291f, -0.0107422f, 0.230469f,
+0.0458984f, 0.203125f, 0.0996094f, 0.175781f, 0.15332f, 0.138184f, 0.20752f, 0.240234f,
+-0.554199f, 0.35498f, -0.60498f, 0.388184f, -0.508789f, 0.266113f, -0.479004f, 0.356934f,
+-0.375f, 0.26709f, -0.315918f, 0.195801f, -0.438965f, 0.123047f, -0.315918f, 0.0322266f,
+-0.375977f, 0.125f, -0.479004f, 0.00292969f, -0.508789f, 0.0361328f, -0.60498f, 0.152832f,
+-0.554199f, 0.144043f, -0.687988f, 0.249023f, -0.687988f, 0.347168f, -0.277832f,
+0.347168f, -0.0786133f, 0.236816f, -0.0786133f, 0.236816f, -0.277832f, 0.0419922f,
+-0.277832f, 0.0419922f, -0.387207f, 0.236816f, -0.387207f, 0.236816f, -0.586426f,
+0.347168f, -0.586426f, 0.347168f, -0.387207f, 0.543457f, -0.387207f, 0.543457f, -0.277832f,
+0.0390625f, -0.199707f, 0.0390625f, -0.318848f, 0.292969f, -0.318848f, 0.292969f,
+-0.199707f, 0.0678711f, 0, 0.0678711f, -0.148926f, 0.208984f, -0.148926f, 0.208984f,
+0, 0.00976562f, 0.0200195f, 0.151855f, -0.724609f, 0.268066f, -0.724609f, 0.128418f,
+0.0200195f, 0.515137f, -0.344238f, 0.515137f, -0.245605f, 0.49707f, -0.177979f, 0.479004f,
+-0.110352f, 0.447021f, -0.0686035f, 0.415039f, -0.0268555f, 0.371338f, -0.00854492f,
+0.327637f, 0.00976562f, 0.275879f, 0.00976562f, 0.224121f, 0.00976562f, 0.180664f,
+-0.00830078f, 0.137207f, -0.0263672f, 0.105957f, -0.0681152f, 0.074707f, -0.109863f,
+0.0571289f, -0.17749f, 0.0395508f, -0.245117f, 0.0395508f, -0.344238f, 0.0395508f,
+-0.448242f, 0.0568848f, -0.516357f, 0.0742188f, -0.584473f, 0.105957f, -0.625f, 0.137695f,
+-0.665527f, 0.181885f, -0.681885f, 0.226074f, -0.698242f, 0.279785f, -0.698242f,
+0.330078f, -0.698242f, 0.373291f, -0.681885f, 0.416504f, -0.665527f, 0.447998f, -0.625f,
+0.479492f, -0.584473f, 0.497314f, -0.516357f, 0.515137f, -0.448242f, 0.515137f, -0.344238f,
+0.377441f, -0.344238f, 0.377441f, -0.416992f, 0.37207f, -0.4646f, 0.366699f, -0.512207f,
+0.35498f, -0.540283f, 0.343262f, -0.568359f, 0.324463f, -0.57959f, 0.305664f, -0.59082f,
+0.278809f, -0.59082f, 0.25f, -0.59082f, 0.230469f, -0.579346f, 0.210938f, -0.567871f,
+0.198975f, -0.539551f, 0.187012f, -0.51123f, 0.181885f, -0.463623f, 0.176758f, -0.416016f,
+0.176758f, -0.344238f, 0.176758f, -0.273438f, 0.182129f, -0.226074f, 0.1875f, -0.178711f,
+0.199219f, -0.150146f, 0.210938f, -0.121582f, 0.22998f, -0.109863f, 0.249023f, -0.0981445f,
+0.276855f, -0.0981445f, 0.303711f, -0.0981445f, 0.322754f, -0.109863f, 0.341797f,
+-0.121582f, 0.354004f, -0.150146f, 0.366211f, -0.178711f, 0.371826f, -0.226074f,
+0.377441f, -0.273438f, 0.377441f, -0.344238f, 0.0629883f, 0, 0.0629883f, -0.102051f,
+0.233398f, -0.102051f, 0.233398f, -0.571289f, 0.0683594f, -0.468262f, 0.0683594f,
+-0.576172f, 0.240723f, -0.687988f, 0.370605f, -0.687988f, 0.370605f, -0.102051f,
+0.52832f, -0.102051f, 0.52832f, 0, 0.034668f, 0, 0.034668f, -0.0952148f, 0.0581055f,
+-0.146484f, 0.0917969f, -0.187744f, 0.125488f, -0.229004f, 0.162354f, -0.263428f,
+0.199219f, -0.297852f, 0.235596f, -0.327393f, 0.271973f, -0.356934f, 0.301025f, -0.384521f,
+0.330078f, -0.412109f, 0.348145f, -0.439941f, 0.366211f, -0.467773f, 0.366211f, -0.499023f,
+0.366211f, -0.544922f, 0.343262f, -0.566895f, 0.320312f, -0.588867f, 0.275879f, -0.588867f,
+0.231934f, -0.588867f, 0.20874f, -0.565186f, 0.185547f, -0.541504f, 0.178711f, -0.494141f,
+0.0405273f, -0.501953f, 0.0454102f, -0.54248f, 0.0605469f, -0.578125f, 0.0756836f,
+-0.61377f, 0.10376f, -0.640625f, 0.131836f, -0.66748f, 0.174072f, -0.682861f, 0.216309f,
+-0.698242f, 0.274902f, -0.698242f, 0.330566f, -0.698242f, 0.373535f, -0.685303f,
+0.416504f, -0.672363f, 0.445801f, -0.647461f, 0.475098f, -0.622559f, 0.490234f, -0.58667f,
+0.505371f, -0.550781f, 0.505371f, -0.504883f, 0.505371f, -0.456543f, 0.486328f, -0.41748f,
+0.467285f, -0.378418f, 0.4375f, -0.345459f, 0.407715f, -0.3125f, 0.371338f, -0.283691f,
+0.334961f, -0.254883f, 0.300781f, -0.227539f, 0.266602f, -0.200195f, 0.238525f, -0.172363f,
+0.210449f, -0.144531f, 0.196777f, -0.112793f, 0.516113f, -0.112793f, 0.516113f, 0,
+0.52002f, -0.190918f, 0.52002f, -0.144043f, 0.504639f, -0.106689f, 0.489258f, -0.0693359f,
+0.458496f, -0.0429688f, 0.427734f, -0.0166016f, 0.38208f, -0.00268555f, 0.336426f,
+0.0112305f, 0.275879f, 0.0112305f, 0.208496f, 0.0112305f, 0.162354f, -0.00585938f,
+0.116211f, -0.0229492f, 0.0866699f, -0.0510254f, 0.0571289f, -0.0791016f, 0.0422363f,
+-0.114746f, 0.0273438f, -0.150391f, 0.0229492f, -0.187012f, 0.162598f, -0.199219f,
+0.165527f, -0.177246f, 0.173584f, -0.158936f, 0.181641f, -0.140625f, 0.195312f, -0.127441f,
+0.208984f, -0.114258f, 0.22876f, -0.107178f, 0.248535f, -0.100098f, 0.275391f, -0.100098f,
+0.324707f, -0.100098f, 0.352051f, -0.124512f, 0.379395f, -0.148926f, 0.379395f, -0.199219f,
+0.379395f, -0.22998f, 0.366455f, -0.248535f, 0.353516f, -0.26709f, 0.33374f, -0.2771f,
+0.313965f, -0.287109f, 0.291016f, -0.290527f, 0.268066f, -0.293945f, 0.247559f, -0.293945f,
+0.199707f, -0.293945f, 0.199707f, -0.404785f, 0.244629f, -0.404785f, 0.265137f, -0.404785f,
+0.286377f, -0.408691f, 0.307617f, -0.412598f, 0.324707f, -0.422852f, 0.341797f, -0.433105f,
+0.352539f, -0.451416f, 0.363281f, -0.469727f, 0.363281f, -0.498047f, 0.363281f, -0.540527f,
+0.3396f, -0.564697f, 0.315918f, -0.588867f, 0.270508f, -0.588867f, 0.228027f, -0.588867f,
+0.201904f, -0.56543f, 0.175781f, -0.541992f, 0.171875f, -0.499023f, 0.034668f, -0.508789f,
+0.0405273f, -0.557129f, 0.0612793f, -0.592773f, 0.0820312f, -0.628418f, 0.113525f,
+-0.651855f, 0.14502f, -0.675293f, 0.186035f, -0.686768f, 0.227051f, -0.698242f, 0.272949f,
+-0.698242f, 0.333496f, -0.698242f, 0.376953f, -0.683594f, 0.42041f, -0.668945f, 0.448242f,
+-0.644043f, 0.476074f, -0.619141f, 0.489258f, -0.585938f, 0.502441f, -0.552734f,
+0.502441f, -0.515137f, 0.502441f, -0.484863f, 0.493652f, -0.45874f, 0.484863f, -0.432617f,
+0.467041f, -0.411865f, 0.449219f, -0.391113f, 0.421387f, -0.376221f, 0.393555f, -0.361328f,
+0.355469f, -0.354004f, 0.355469f, -0.352051f, 0.397949f, -0.347168f, 0.429199f, -0.332764f,
+0.460449f, -0.318359f, 0.480469f, -0.296875f, 0.500488f, -0.275391f, 0.510254f, -0.248291f,
+0.52002f, -0.221191f, 0.52002f, -0.190918f, 0.52832f, -0.229004f, 0.52832f, -0.177246f,
+0.511963f, -0.133545f, 0.495605f, -0.0898438f, 0.463379f, -0.0578613f, 0.431152f,
+-0.0258789f, 0.383545f, -0.00805664f, 0.335938f, 0.00976562f, 0.273438f, 0.00976562f,
+0.21582f, 0.00976562f, 0.172852f, -0.00415039f, 0.129883f, -0.0180664f, 0.100342f,
+-0.0427246f, 0.0708008f, -0.0673828f, 0.0539551f, -0.100586f, 0.0371094f, -0.133789f,
+0.0307617f, -0.171875f, 0.167969f, -0.183105f, 0.171875f, -0.166992f, 0.178955f,
+-0.151855f, 0.186035f, -0.136719f, 0.19873f, -0.125f, 0.211426f, -0.113281f, 0.22998f,
+-0.106201f, 0.248535f, -0.0991211f, 0.274902f, -0.0991211f, 0.326172f, -0.0991211f,
+0.356689f, -0.131836f, 0.387207f, -0.164551f, 0.387207f, -0.226074f, 0.387207f, -0.253418f,
+0.379639f, -0.275391f, 0.37207f, -0.297363f, 0.358154f, -0.312988f, 0.344238f, -0.328613f,
+0.323975f, -0.336914f, 0.303711f, -0.345215f, 0.277832f, -0.345215f, 0.243652f, -0.345215f,
+0.22168f, -0.332275f, 0.199707f, -0.319336f, 0.18457f, -0.300781f, 0.0507812f, -0.300781f,
+0.074707f, -0.687988f, 0.488281f, -0.687988f, 0.488281f, -0.585938f, 0.199219f, -0.585938f,
+0.187988f, -0.412109f, 0.208496f, -0.430176f, 0.239746f, -0.443115f, 0.270996f, -0.456055f,
+0.3125f, -0.456055f, 0.363281f, -0.456055f, 0.40332f, -0.439453f, 0.443359f, -0.422852f,
+0.471191f, -0.393066f, 0.499023f, -0.363281f, 0.513672f, -0.321533f, 0.52832f, -0.279785f,
+0.52832f, -0.229004f, 0.52002f, -0.225098f, 0.52002f, -0.17334f, 0.505371f, -0.130127f,
+0.490723f, -0.0869141f, 0.46167f, -0.0559082f, 0.432617f, -0.0249023f, 0.38916f,
+-0.00756836f, 0.345703f, 0.00976562f, 0.288574f, 0.00976562f, 0.166992f, 0.00976562f,
+0.101807f, -0.0754395f, 0.0366211f, -0.160645f, 0.0366211f, -0.328125f, 0.0366211f,
+-0.512207f, 0.102783f, -0.605225f, 0.168945f, -0.698242f, 0.291992f, -0.698242f,
+0.333008f, -0.698242f, 0.366699f, -0.689697f, 0.400391f, -0.681152f, 0.426758f, -0.662109f,
+0.453125f, -0.643066f, 0.47168f, -0.613037f, 0.490234f, -0.583008f, 0.501465f, -0.540039f,
+0.37207f, -0.521973f, 0.362305f, -0.558105f, 0.340332f, -0.573975f, 0.318359f, -0.589844f,
+0.289062f, -0.589844f, 0.233887f, -0.589844f, 0.202393f, -0.534668f, 0.170898f, -0.479492f,
+0.170898f, -0.367188f, 0.192871f, -0.403809f, 0.231934f, -0.42334f, 0.270996f, -0.442871f,
+0.320312f, -0.442871f, 0.365723f, -0.442871f, 0.402588f, -0.427979f, 0.439453f, -0.413086f,
+0.465576f, -0.38501f, 0.491699f, -0.356934f, 0.505859f, -0.316406f, 0.52002f, -0.275879f,
+0.52002f, -0.225098f, 0.382324f, -0.221191f, 0.382324f, -0.249023f, 0.375977f, -0.27124f,
+0.369629f, -0.293457f, 0.356689f, -0.309082f, 0.34375f, -0.324707f, 0.324707f, -0.333252f,
+0.305664f, -0.341797f, 0.280762f, -0.341797f, 0.262695f, -0.341797f, 0.244629f, -0.335938f,
+0.226562f, -0.330078f, 0.212402f, -0.317139f, 0.198242f, -0.304199f, 0.189453f, -0.28418f,
+0.180664f, -0.26416f, 0.180664f, -0.23584f, 0.180664f, -0.206543f, 0.187988f, -0.181152f,
+0.195312f, -0.155762f, 0.20874f, -0.136963f, 0.222168f, -0.118164f, 0.241211f, -0.107666f,
+0.260254f, -0.097168f, 0.28418f, -0.097168f, 0.330566f, -0.097168f, 0.356445f, -0.130127f,
+0.382324f, -0.163086f, 0.382324f, -0.221191f, 0.512207f, -0.579102f, 0.46582f, -0.505859f,
+0.424561f, -0.437012f, 0.383301f, -0.368164f, 0.352539f, -0.298584f, 0.321777f, -0.229004f,
+0.303955f, -0.155518f, 0.286133f, -0.0820312f, 0.286133f, 0, 0.143066f, 0, 0.143066f,
+-0.081543f, 0.162354f, -0.155029f, 0.181641f, -0.228516f, 0.214844f, -0.29834f, 0.248047f,
+-0.368164f, 0.291992f, -0.436279f, 0.335938f, -0.504395f, 0.384766f, -0.575195f,
+0.0429688f, -0.575195f, 0.0429688f, -0.687988f, 0.512207f, -0.687988f, 0.525391f,
+-0.193848f, 0.525391f, -0.149414f, 0.510742f, -0.112061f, 0.496094f, -0.074707f,
+0.46582f, -0.0476074f, 0.435547f, -0.0205078f, 0.38916f, -0.00537109f, 0.342773f,
+0.00976562f, 0.278809f, 0.00976562f, 0.215332f, 0.00976562f, 0.168701f, -0.00537109f,
+0.12207f, -0.0205078f, 0.0915527f, -0.0476074f, 0.0610352f, -0.074707f, 0.0463867f,
+-0.111816f, 0.0317383f, -0.148926f, 0.0317383f, -0.192871f, 0.0317383f, -0.230469f,
+0.043457f, -0.259521f, 0.0551758f, -0.288574f, 0.074707f, -0.30957f, 0.0942383f,
+-0.330566f, 0.119629f, -0.343018f, 0.14502f, -0.355469f, 0.171875f, -0.359863f, 0.171875f,
+-0.361816f, 0.143066f, -0.368164f, 0.120117f, -0.382812f, 0.097168f, -0.397461f,
+0.0810547f, -0.417969f, 0.0649414f, -0.438477f, 0.0563965f, -0.463623f, 0.0478516f,
+-0.48877f, 0.0478516f, -0.516113f, 0.0478516f, -0.557129f, 0.0627441f, -0.59082f,
+0.0776367f, -0.624512f, 0.106445f, -0.648438f, 0.135254f, -0.672363f, 0.177979f,
+-0.685303f, 0.220703f, -0.698242f, 0.276855f, -0.698242f, 0.336914f, -0.698242f,
+0.380615f, -0.684814f, 0.424316f, -0.671387f, 0.452637f, -0.647217f, 0.480957f, -0.623047f,
+0.494629f, -0.589355f, 0.508301f, -0.555664f, 0.508301f, -0.515137f, 0.508301f, -0.488281f,
+0.499756f, -0.463135f, 0.491211f, -0.437988f, 0.475098f, -0.41748f, 0.458984f, -0.396973f,
+0.435791f, -0.382812f, 0.412598f, -0.368652f, 0.383301f, -0.362793f, 0.383301f, -0.36084f,
+0.413574f, -0.355957f, 0.439697f, -0.343018f, 0.46582f, -0.330078f, 0.484863f, -0.309326f,
+0.503906f, -0.288574f, 0.514648f, -0.259521f, 0.525391f, -0.230469f, 0.525391f, -0.193848f,
+0.367188f, -0.507812f, 0.367188f, -0.52832f, 0.362793f, -0.545654f, 0.358398f, -0.562988f,
+0.348145f, -0.575439f, 0.337891f, -0.587891f, 0.320557f, -0.594971f, 0.303223f, -0.602051f,
+0.276855f, -0.602051f, 0.251465f, -0.602051f, 0.234375f, -0.594971f, 0.217285f, -0.587891f,
+0.207031f, -0.575439f, 0.196777f, -0.562988f, 0.192383f, -0.545654f, 0.187988f, -0.52832f,
+0.187988f, -0.507812f, 0.187988f, -0.489746f, 0.19165f, -0.472168f, 0.195312f, -0.45459f,
+0.205078f, -0.440674f, 0.214844f, -0.426758f, 0.232422f, -0.417969f, 0.25f, -0.40918f,
+0.277832f, -0.40918f, 0.307129f, -0.40918f, 0.324951f, -0.417969f, 0.342773f, -0.426758f,
+0.352051f, -0.440918f, 0.361328f, -0.455078f, 0.364258f, -0.472656f, 0.367188f, -0.490234f,
+0.367188f, -0.507812f, 0.383301f, -0.205078f, 0.383301f, -0.226074f, 0.378662f, -0.245605f,
+0.374023f, -0.265137f, 0.362061f, -0.280029f, 0.350098f, -0.294922f, 0.329102f, -0.303955f,
+0.308105f, -0.312988f, 0.275879f, -0.312988f, 0.246582f, -0.312988f, 0.226807f, -0.303955f,
+0.207031f, -0.294922f, 0.195068f, -0.279785f, 0.183105f, -0.264648f, 0.177979f, -0.244873f,
+0.172852f, -0.225098f, 0.172852f, -0.203125f, 0.172852f, -0.177246f, 0.177979f, -0.155762f,
+0.183105f, -0.134277f, 0.195557f, -0.118896f, 0.208008f, -0.103516f, 0.228516f, -0.0952148f,
+0.249023f, -0.0869141f, 0.279785f, -0.0869141f, 0.310547f, -0.0869141f, 0.330566f,
+-0.095459f, 0.350586f, -0.104004f, 0.362305f, -0.119629f, 0.374023f, -0.135254f,
+0.378662f, -0.156982f, 0.383301f, -0.178711f, 0.383301f, -0.205078f, 0.519043f, -0.35498f,
+0.519043f, -0.171875f, 0.452148f, -0.0810547f, 0.385254f, 0.00976562f, 0.262207f,
+0.00976562f, 0.217773f, 0.00976562f, 0.182373f, 0.000488281f, 0.146973f, -0.00878906f,
+0.120605f, -0.0283203f, 0.0942383f, -0.0478516f, 0.0759277f, -0.0786133f, 0.0576172f,
+-0.109375f, 0.046875f, -0.151855f, 0.175781f, -0.169922f, 0.185547f, -0.133301f,
+0.207764f, -0.115723f, 0.22998f, -0.0981445f, 0.263672f, -0.0981445f, 0.291504f,
+-0.0981445f, 0.313477f, -0.111328f, 0.335449f, -0.124512f, 0.351074f, -0.151367f,
+0.366699f, -0.178223f, 0.375244f, -0.219482f, 0.383789f, -0.260742f, 0.384277f, -0.316895f,
+0.374512f, -0.297852f, 0.358398f, -0.283203f, 0.342285f, -0.268555f, 0.322021f, -0.258789f,
+0.301758f, -0.249023f, 0.278809f, -0.243896f, 0.255859f, -0.23877f, 0.232422f, -0.23877f,
+0.1875f, -0.23877f, 0.150879f, -0.254639f, 0.114258f, -0.270508f, 0.0883789f, -0.300293f,
+0.0625f, -0.330078f, 0.048584f, -0.372314f, 0.034668f, -0.414551f, 0.034668f, -0.467773f,
+0.034668f, -0.522461f, 0.0510254f, -0.56543f, 0.0673828f, -0.608398f, 0.0981445f,
+-0.637939f, 0.128906f, -0.66748f, 0.173584f, -0.682861f, 0.218262f, -0.698242f, 0.274902f,
+-0.698242f, 0.334473f, -0.698242f, 0.380127f, -0.677979f, 0.425781f, -0.657715f,
+0.456543f, -0.615479f, 0.487305f, -0.573242f, 0.503174f, -0.508545f, 0.519043f, -0.443848f,
+0.519043f, -0.35498f, 0.374023f, -0.451172f, 0.374023f, -0.480469f, 0.367432f, -0.506104f,
+0.36084f, -0.531738f, 0.347656f, -0.550537f, 0.334473f, -0.569336f, 0.31543f, -0.580078f,
+0.296387f, -0.59082f, 0.271484f, -0.59082f, 0.248535f, -0.59082f, 0.230469f, -0.582275f,
+0.212402f, -0.57373f, 0.199707f, -0.557617f, 0.187012f, -0.541504f, 0.18042f, -0.518555f,
+0.173828f, -0.495605f, 0.173828f, -0.466797f, 0.173828f, -0.439941f, 0.180176f, -0.416748f,
+0.186523f, -0.393555f, 0.19873f, -0.376709f, 0.210938f, -0.359863f, 0.229492f, -0.350342f,
+0.248047f, -0.34082f, 0.271973f, -0.34082f, 0.291016f, -0.34082f, 0.309326f, -0.347656f,
+0.327637f, -0.354492f, 0.342041f, -0.368164f, 0.356445f, -0.381836f, 0.365234f, -0.402588f,
+0.374023f, -0.42334f, 0.374023f, -0.451172f, 0.0961914f, -0.367188f, 0.0961914f,
+-0.504883f, 0.236816f, -0.504883f, 0.236816f, -0.367188f, 0.0961914f, 0, 0.0961914f,
+-0.137207f, 0.236816f, -0.137207f, 0.236816f, 0, 0.097168f, -0.367188f, 0.097168f,
+-0.504883f, 0.237793f, -0.504883f, 0.237793f, -0.367188f, 0.237793f, -0.0322266f,
+0.237793f, 0.000488281f, 0.234131f, 0.0273438f, 0.230469f, 0.0541992f, 0.223633f,
+0.0769043f, 0.216797f, 0.0996094f, 0.207031f, 0.118652f, 0.197266f, 0.137695f, 0.185059f,
+0.154785f, 0.0952148f, 0.154785f, 0.108887f, 0.137695f, 0.12085f, 0.118652f, 0.132812f,
+0.0996094f, 0.141602f, 0.0795898f, 0.150391f, 0.0595703f, 0.155273f, 0.0395508f,
+0.160156f, 0.0195312f, 0.160156f, 0, 0.097168f, 0, 0.097168f, -0.137207f, 0.237793f,
+-0.137207f, 0.0415039f, -0.411133f, 0.0415039f, -0.52002f, 0.542969f, -0.52002f,
+0.542969f, -0.411133f, 0.0415039f, -0.14209f, 0.0415039f, -0.25f, 0.542969f, -0.25f,
+0.542969f, -0.14209f, 0.0419922f, -0.0610352f, 0.0419922f, -0.171875f, 0.448242f,
+-0.330078f, 0.0419922f, -0.48877f, 0.0419922f, -0.600098f, 0.543457f, -0.40918f,
+0.543457f, -0.251953f, 0.553223f, -0.500977f, 0.553223f, -0.46875f, 0.544678f, -0.444336f,
+0.536133f, -0.419922f, 0.521973f, -0.400635f, 0.507812f, -0.381348f, 0.489746f, -0.365967f,
+0.47168f, -0.350586f, 0.452637f, -0.336914f, 0.433594f, -0.323242f, 0.415283f, -0.310059f,
+0.396973f, -0.296875f, 0.382324f, -0.281982f, 0.367676f, -0.26709f, 0.358398f, -0.249268f,
+0.349121f, -0.231445f, 0.348145f, -0.208008f, 0.217773f, -0.208008f, 0.220215f, -0.249512f,
+0.235596f, -0.279053f, 0.250977f, -0.308594f, 0.272949f, -0.330566f, 0.294922f, -0.352539f,
+0.319824f, -0.369873f, 0.344727f, -0.387207f, 0.365967f, -0.405273f, 0.387207f, -0.42334f,
+0.401123f, -0.44458f, 0.415039f, -0.46582f, 0.415039f, -0.495117f, 0.415039f, -0.538086f,
+0.386963f, -0.562988f, 0.358887f, -0.587891f, 0.307129f, -0.587891f, 0.282227f, -0.587891f,
+0.26123f, -0.580322f, 0.240234f, -0.572754f, 0.224365f, -0.559082f, 0.208496f, -0.54541f,
+0.198242f, -0.525879f, 0.187988f, -0.506348f, 0.185059f, -0.48291f, 0.0458984f, -0.48877f,
+0.0517578f, -0.532227f, 0.0700684f, -0.570312f, 0.0883789f, -0.608398f, 0.120117f,
+-0.636719f, 0.151855f, -0.665039f, 0.197998f, -0.681641f, 0.244141f, -0.698242f,
+0.305176f, -0.698242f, 0.36377f, -0.698242f, 0.409668f, -0.68457f, 0.455566f, -0.670898f,
+0.487549f, -0.645264f, 0.519531f, -0.619629f, 0.536377f, -0.583008f, 0.553223f, -0.546387f,
+0.553223f, -0.500977f, 0.213867f, 0, 0.213867f, -0.131836f, 0.35498f, -0.131836f,
+0.35498f, 0, 0.553223f, 0, 0.492188f, -0.175781f, 0.22998f, -0.175781f, 0.168945f,
+0, 0.0249023f, 0, 0.275879f, -0.687988f, 0.445801f, -0.687988f, 0.695801f, 0, 0.39209f,
+-0.481934f, 0.38623f, -0.499023f, 0.380615f, -0.516357f, 0.375f, -0.533691f, 0.37085f,
+-0.548096f, 0.366699f, -0.5625f, 0.364014f, -0.571777f, 0.361328f, -0.581055f, 0.36084f,
+-0.582031f, 0.360352f, -0.580566f, 0.35791f, -0.571289f, 0.355469f, -0.562012f, 0.351318f,
+-0.547852f, 0.347168f, -0.533691f, 0.341553f, -0.516357f, 0.335938f, -0.499023f,
+0.330078f, -0.481934f, 0.262207f, -0.28418f, 0.459961f, -0.28418f, 0.676758f, -0.196289f,
+0.676758f, -0.144043f, 0.655762f, -0.106689f, 0.634766f, -0.0693359f, 0.598389f,
+-0.0456543f, 0.562012f, -0.0219727f, 0.513672f, -0.0109863f, 0.465332f, 0, 0.411133f,
+0, 0.0668945f, 0, 0.0668945f, -0.687988f, 0.381836f, -0.687988f, 0.442871f, -0.687988f,
+0.490479f, -0.67749f, 0.538086f, -0.666992f, 0.570801f, -0.645508f, 0.603516f, -0.624023f,
+0.620361f, -0.591553f, 0.637207f, -0.559082f, 0.637207f, -0.515137f, 0.637207f, -0.456543f,
+0.604736f, -0.41626f, 0.572266f, -0.375977f, 0.505859f, -0.361816f, 0.589355f, -0.352051f,
+0.633057f, -0.309326f, 0.676758f, -0.266602f, 0.676758f, -0.196289f, 0.492188f, -0.495605f,
+0.492188f, -0.541992f, 0.462646f, -0.561523f, 0.433105f, -0.581055f, 0.375f, -0.581055f,
+0.210938f, -0.581055f, 0.210938f, -0.410645f, 0.375977f, -0.410645f, 0.437012f, -0.410645f,
+0.4646f, -0.431885f, 0.492188f, -0.453125f, 0.492188f, -0.495605f, 0.532227f, -0.20752f,
+0.532227f, -0.234863f, 0.521484f, -0.253418f, 0.510742f, -0.271973f, 0.491943f, -0.283203f,
+0.473145f, -0.294434f, 0.447998f, -0.299316f, 0.422852f, -0.304199f, 0.393555f, -0.304199f,
+0.210938f, -0.304199f, 0.210938f, -0.106934f, 0.398926f, -0.106934f, 0.427246f, -0.106934f,
+0.45166f, -0.111572f, 0.476074f, -0.116211f, 0.493896f, -0.127686f, 0.511719f, -0.13916f,
+0.521973f, -0.158691f, 0.532227f, -0.178223f, 0.532227f, -0.20752f, 0.388184f, -0.103516f,
+0.428711f, -0.103516f, 0.458252f, -0.11499f, 0.487793f, -0.126465f, 0.509521f, -0.14502f,
+0.53125f, -0.163574f, 0.545654f, -0.187012f, 0.560059f, -0.210449f, 0.569336f, -0.234375f,
+0.694824f, -0.187012f, 0.679688f, -0.149902f, 0.655273f, -0.114258f, 0.630859f, -0.0786133f,
+0.594238f, -0.0512695f, 0.557617f, -0.0239258f, 0.50708f, -0.00708008f, 0.456543f,
+0.00976562f, 0.388184f, 0.00976562f, 0.298828f, 0.00976562f, 0.233398f, -0.0168457f,
+0.167969f, -0.043457f, 0.125244f, -0.0910645f, 0.0825195f, -0.138672f, 0.0617676f,
+-0.204102f, 0.0410156f, -0.269531f, 0.0410156f, -0.347168f, 0.0410156f, -0.427734f,
+0.0617676f, -0.492676f, 0.0825195f, -0.557617f, 0.124512f, -0.603271f, 0.166504f,
+-0.648926f, 0.230713f, -0.673584f, 0.294922f, -0.698242f, 0.381836f, -0.698242f,
+0.449219f, -0.698242f, 0.499756f, -0.684082f, 0.550293f, -0.669922f, 0.587158f, -0.644287f,
+0.624023f, -0.618652f, 0.648193f, -0.58374f, 0.672363f, -0.548828f, 0.686035f, -0.506836f,
+0.559082f, -0.472168f, 0.552246f, -0.494141f, 0.538086f, -0.514404f, 0.523926f, -0.534668f,
+0.502197f, -0.550293f, 0.480469f, -0.565918f, 0.451172f, -0.575439f, 0.421875f, -0.584961f,
+0.384766f, -0.584961f, 0.33252f, -0.584961f, 0.294922f, -0.568115f, 0.257324f, -0.55127f,
+0.233154f, -0.52002f, 0.208984f, -0.48877f, 0.19751f, -0.445068f, 0.186035f, -0.401367f,
+0.186035f, -0.347168f, 0.186035f, -0.293457f, 0.19751f, -0.248779f, 0.208984f, -0.204102f,
+0.233398f, -0.171875f, 0.257812f, -0.139648f, 0.296143f, -0.121582f, 0.334473f, -0.103516f,
+0.388184f, -0.103516f, 0.680176f, -0.349121f, 0.680176f, -0.263184f, 0.654297f, -0.197998f,
+0.628418f, -0.132812f, 0.583496f, -0.0888672f, 0.538574f, -0.0449219f, 0.477295f,
+-0.0224609f, 0.416016f, 0, 0.345215f, 0, 0.0668945f, 0, 0.0668945f, -0.687988f, 0.315918f,
+-0.687988f, 0.395996f, -0.687988f, 0.462891f, -0.667969f, 0.529785f, -0.647949f,
+0.578125f, -0.606445f, 0.626465f, -0.564941f, 0.65332f, -0.500977f, 0.680176f, -0.437012f,
+0.680176f, -0.349121f, 0.535156f, -0.349121f, 0.535156f, -0.40918f, 0.518799f, -0.452148f,
+0.502441f, -0.495117f, 0.473145f, -0.522705f, 0.443848f, -0.550293f, 0.403076f, -0.563477f,
+0.362305f, -0.57666f, 0.312988f, -0.57666f, 0.210938f, -0.57666f, 0.210938f, -0.111328f,
+0.333008f, -0.111328f, 0.376465f, -0.111328f, 0.41333f, -0.126465f, 0.450195f, -0.141602f,
+0.477295f, -0.171631f, 0.504395f, -0.20166f, 0.519775f, -0.246094f, 0.535156f, -0.290527f,
+0.535156f, -0.349121f, 0.0668945f, 0, 0.0668945f, -0.687988f, 0.60791f, -0.687988f,
+0.60791f, -0.57666f, 0.210938f, -0.57666f, 0.210938f, -0.403809f, 0.578125f, -0.403809f,
+0.578125f, -0.29248f, 0.210938f, -0.29248f, 0.210938f, -0.111328f, 0.62793f, -0.111328f,
+0.62793f, 0, 0.210938f, -0.57666f, 0.210938f, -0.36377f, 0.562988f, -0.36377f, 0.562988f,
+-0.252441f, 0.210938f, -0.252441f, 0.210938f, 0, 0.0668945f, 0, 0.0668945f, -0.687988f,
+0.574219f, -0.687988f, 0.574219f, -0.57666f, 0.393555f, -0.103027f, 0.424805f, -0.103027f,
+0.453613f, -0.10791f, 0.482422f, -0.112793f, 0.50708f, -0.12085f, 0.531738f, -0.128906f,
+0.551514f, -0.139404f, 0.571289f, -0.149902f, 0.583984f, -0.161133f, 0.583984f, -0.256348f,
+0.416016f, -0.256348f, 0.416016f, -0.362793f, 0.71582f, -0.362793f, 0.71582f, -0.109863f,
+0.692383f, -0.0859375f, 0.65918f, -0.064209f, 0.625977f, -0.0424805f, 0.584473f,
+-0.026123f, 0.542969f, -0.00976562f, 0.493896f, 0, 0.444824f, 0.00976562f, 0.389648f,
+0.00976562f, 0.29834f, 0.00976562f, 0.232422f, -0.0168457f, 0.166504f, -0.043457f,
+0.124023f, -0.0910645f, 0.081543f, -0.138672f, 0.0612793f, -0.204102f, 0.0410156f,
+-0.269531f, 0.0410156f, -0.347168f, 0.0410156f, -0.427734f, 0.0625f, -0.492676f,
+0.0839844f, -0.557617f, 0.127686f, -0.603271f, 0.171387f, -0.648926f, 0.237549f,
+-0.673584f, 0.303711f, -0.698242f, 0.393066f, -0.698242f, 0.458008f, -0.698242f,
+0.508545f, -0.685547f, 0.559082f, -0.672852f, 0.596924f, -0.649414f, 0.634766f, -0.625977f,
+0.6604f, -0.593018f, 0.686035f, -0.560059f, 0.701172f, -0.519043f, 0.568359f, -0.479004f,
+0.55957f, -0.500488f, 0.544922f, -0.519775f, 0.530273f, -0.539062f, 0.508545f, -0.553467f,
+0.486816f, -0.567871f, 0.458252f, -0.576416f, 0.429688f, -0.584961f, 0.393066f, -0.584961f,
+0.339355f, -0.584961f, 0.300293f, -0.568115f, 0.26123f, -0.55127f, 0.23584f, -0.52002f,
+0.210449f, -0.48877f, 0.198242f, -0.445068f, 0.186035f, -0.401367f, 0.186035f, -0.347168f,
+0.186035f, -0.293457f, 0.198486f, -0.248535f, 0.210938f, -0.203613f, 0.236572f, -0.171387f,
+0.262207f, -0.13916f, 0.30127f, -0.121094f, 0.340332f, -0.103027f, 0.393555f, -0.103027f,
+0.510742f, 0, 0.510742f, -0.294922f, 0.210938f, -0.294922f, 0.210938f, 0, 0.0668945f,
+0, 0.0668945f, -0.687988f, 0.210938f, -0.687988f, 0.210938f, -0.414062f, 0.510742f,
+-0.414062f, 0.510742f, -0.687988f, 0.654785f, -0.687988f, 0.654785f, 0, 0.0668945f,
+0, 0.0668945f, -0.687988f, 0.210938f, -0.687988f, 0.210938f, 0, 0.255859f, 0.00976562f,
+0.204102f, 0.00976562f, 0.163574f, -0.000976562f, 0.123047f, -0.0117188f, 0.0932617f,
+-0.0351562f, 0.0634766f, -0.0585938f, 0.0441895f, -0.0959473f, 0.0249023f, -0.133301f,
+0.0151367f, -0.186523f, 0.158203f, -0.20752f, 0.163086f, -0.178711f, 0.171875f, -0.158936f,
+0.180664f, -0.13916f, 0.193115f, -0.126709f, 0.205566f, -0.114258f, 0.22168f, -0.108643f,
+0.237793f, -0.103027f, 0.256836f, -0.103027f, 0.299805f, -0.103027f, 0.322021f, -0.131836f,
+0.344238f, -0.160645f, 0.344238f, -0.214355f, 0.344238f, -0.575195f, 0.207031f, -0.575195f,
+0.207031f, -0.687988f, 0.487793f, -0.687988f, 0.487793f, -0.217773f, 0.487793f, -0.165527f,
+0.472656f, -0.123291f, 0.45752f, -0.0810547f, 0.427979f, -0.0515137f, 0.398438f,
+-0.0219727f, 0.355225f, -0.00610352f, 0.312012f, 0.00976562f, 0.255859f, 0.00976562f,
+0.0668945f, 0, 0.0668945f, -0.687988f, 0.210938f, -0.687988f, 0.210938f, -0.111328f,
+0.580078f, -0.111328f, 0.580078f, 0, 0.638184f, 0, 0.638184f, -0.416992f, 0.638184f,
+-0.441895f, 0.638916f, -0.468262f, 0.639648f, -0.494629f, 0.640625f, -0.516602f,
+0.64209f, -0.54248f, 0.643066f, -0.566895f, 0.632812f, -0.52832f, 0.623535f, -0.493652f,
+0.619629f, -0.479004f, 0.615234f, -0.463379f, 0.61084f, -0.447754f, 0.606689f, -0.433105f,
+0.602539f, -0.418457f, 0.598633f, -0.405762f, 0.594727f, -0.393066f, 0.591797f, -0.383789f,
+0.467773f, 0, 0.365234f, 0, 0.241211f, -0.383789f, 0.238281f, -0.393066f, 0.234619f,
+-0.405762f, 0.230957f, -0.418457f, 0.226807f, -0.433105f, 0.222656f, -0.447754f,
+0.218262f, -0.463379f, 0.213867f, -0.479004f, 0.209473f, -0.493652f, 0.199707f, -0.52832f,
+0.188965f, -0.566895f, 0.19043f, -0.538574f, 0.191895f, -0.51123f, 0.192871f, -0.487793f,
+0.193848f, -0.461914f, 0.194824f, -0.436035f, 0.194824f, -0.416992f, 0.194824f, 0,
+0.0668945f, 0, 0.0668945f, -0.687988f, 0.259766f, -0.687988f, 0.382812f, -0.303223f,
+0.387695f, -0.288086f, 0.393311f, -0.266113f, 0.398926f, -0.244141f, 0.404297f, -0.223633f,
+0.410156f, -0.199707f, 0.416992f, -0.173828f, 0.423828f, -0.199219f, 0.430176f, -0.222656f,
+0.433105f, -0.23291f, 0.436035f, -0.243652f, 0.438965f, -0.254395f, 0.441895f, -0.264648f,
+0.444824f, -0.274902f, 0.447754f, -0.28418f, 0.450684f, -0.293457f, 0.453125f, -0.300781f,
+0.574219f, -0.687988f, 0.766113f, -0.687988f, 0.766113f, 0, 0.73584f, -0.347168f,
+0.73584f, -0.266602f, 0.711914f, -0.200684f, 0.687988f, -0.134766f, 0.643066f, -0.0878906f,
+0.598145f, -0.0410156f, 0.533447f, -0.015625f, 0.46875f, 0.00976562f, 0.387207f,
+0.00976562f, 0.300781f, 0.00976562f, 0.236084f, -0.0168457f, 0.171387f, -0.043457f,
+0.12793f, -0.0910645f, 0.0844727f, -0.138672f, 0.0627441f, -0.204102f, 0.0410156f,
+-0.269531f, 0.0410156f, -0.347168f, 0.0410156f, -0.427734f, 0.0637207f, -0.492676f,
+0.0864258f, -0.557617f, 0.130615f, -0.603271f, 0.174805f, -0.648926f, 0.239502f,
+-0.673584f, 0.304199f, -0.698242f, 0.388184f, -0.698242f, 0.472168f, -0.698242f,
+0.536865f, -0.67334f, 0.601562f, -0.648438f, 0.645752f, -0.602539f, 0.689941f, -0.556641f,
+0.712891f, -0.491943f, 0.73584f, -0.427246f, 0.73584f, -0.347168f, 0.588867f, -0.347168f,
+0.588867f, -0.401367f, 0.575928f, -0.445068f, 0.562988f, -0.48877f, 0.537598f, -0.52002f,
+0.512207f, -0.55127f, 0.474854f, -0.568115f, 0.4375f, -0.584961f, 0.388184f, -0.584961f,
+0.337891f, -0.584961f, 0.300049f, -0.568115f, 0.262207f, -0.55127f, 0.236816f, -0.52002f,
+0.211426f, -0.48877f, 0.19873f, -0.445068f, 0.186035f, -0.401367f, 0.186035f, -0.347168f,
+0.186035f, -0.293457f, 0.198975f, -0.248779f, 0.211914f, -0.204102f, 0.237305f, -0.171875f,
+0.262695f, -0.139648f, 0.300293f, -0.121582f, 0.337891f, -0.103516f, 0.387207f, -0.103516f,
+0.439941f, -0.103516f, 0.478027f, -0.121826f, 0.516113f, -0.140137f, 0.540771f, -0.172607f,
+0.56543f, -0.205078f, 0.577148f, -0.249756f, 0.588867f, -0.294434f, 0.588867f, -0.347168f,
+0.539551f, 0, 0.379883f, -0.26123f, 0.210938f, -0.26123f, 0.210938f, 0, 0.0668945f,
+0, 0.0668945f, -0.687988f, 0.410645f, -0.687988f, 0.475098f, -0.687988f, 0.523193f,
+-0.673584f, 0.571289f, -0.65918f, 0.603516f, -0.632568f, 0.635742f, -0.605957f, 0.651611f,
+-0.568115f, 0.66748f, -0.530273f, 0.66748f, -0.48291f, 0.66748f, -0.444336f, 0.656006f,
+-0.412354f, 0.644531f, -0.380371f, 0.624268f, -0.355469f, 0.604004f, -0.330566f,
+0.576172f, -0.313721f, 0.54834f, -0.296875f, 0.515625f, -0.289062f, 0.70166f, 0,
+0.522461f, -0.477051f, 0.522461f, -0.527344f, 0.489502f, -0.551758f, 0.456543f, -0.576172f,
+0.395508f, -0.576172f, 0.210938f, -0.576172f, 0.210938f, -0.373047f, 0.399414f, -0.373047f,
+0.431641f, -0.373047f, 0.454834f, -0.380615f, 0.478027f, -0.388184f, 0.49292f, -0.4021f,
+0.507812f, -0.416016f, 0.515137f, -0.435059f, 0.522461f, -0.454102f, 0.522461f, -0.477051f,
+0.62793f, -0.198242f, 0.62793f, -0.151367f, 0.61084f, -0.113037f, 0.59375f, -0.074707f,
+0.557861f, -0.0473633f, 0.521973f, -0.0200195f, 0.466064f, -0.00512695f, 0.410156f,
+0.00976562f, 0.333008f, 0.00976562f, 0.264648f, 0.00976562f, 0.212402f, -0.00244141f,
+0.160156f, -0.0146484f, 0.122803f, -0.0385742f, 0.0854492f, -0.0625f, 0.0622559f,
+-0.0979004f, 0.0390625f, -0.133301f, 0.0288086f, -0.179199f, 0.167969f, -0.202148f,
+0.173828f, -0.179199f, 0.185059f, -0.160156f, 0.196289f, -0.141113f, 0.216064f, -0.127197f,
+0.23584f, -0.113281f, 0.265381f, -0.105713f, 0.294922f, -0.0981445f, 0.336914f, -0.0981445f,
+0.410156f, -0.0981445f, 0.448975f, -0.120361f, 0.487793f, -0.142578f, 0.487793f,
+-0.189941f, 0.487793f, -0.218262f, 0.472168f, -0.236328f, 0.456543f, -0.254395f,
+0.430664f, -0.266113f, 0.404785f, -0.277832f, 0.371094f, -0.285645f, 0.337402f, -0.293457f,
+0.300781f, -0.300781f, 0.271484f, -0.307617f, 0.242188f, -0.314941f, 0.212891f, -0.322266f,
+0.186279f, -0.33252f, 0.159668f, -0.342773f, 0.136719f, -0.356934f, 0.11377f, -0.371094f,
+0.0969238f, -0.391846f, 0.0800781f, -0.412598f, 0.0705566f, -0.44043f, 0.0610352f,
+-0.468262f, 0.0610352f, -0.505859f, 0.0610352f, -0.557129f, 0.081543f, -0.59375f,
+0.102051f, -0.630371f, 0.138428f, -0.653564f, 0.174805f, -0.676758f, 0.225098f, -0.6875f,
+0.275391f, -0.698242f, 0.334961f, -0.698242f, 0.402344f, -0.698242f, 0.450439f, -0.687744f,
+0.498535f, -0.677246f, 0.531006f, -0.655762f, 0.563477f, -0.634277f, 0.582275f, -0.601807f,
+0.601074f, -0.569336f, 0.609863f, -0.525879f, 0.470215f, -0.506836f, 0.459473f, -0.55127f,
+0.426514f, -0.57373f, 0.393555f, -0.596191f, 0.332031f, -0.596191f, 0.293945f, -0.596191f,
+0.268799f, -0.5896f, 0.243652f, -0.583008f, 0.22876f, -0.571777f, 0.213867f, -0.560547f,
+0.20752f, -0.545654f, 0.201172f, -0.530762f, 0.201172f, -0.51416f, 0.201172f, -0.48877f,
+0.213379f, -0.472412f, 0.225586f, -0.456055f, 0.247559f, -0.445068f, 0.269531f, -0.434082f,
+0.300049f, -0.426514f, 0.330566f, -0.418945f, 0.367188f, -0.411133f, 0.399414f, -0.404297f,
+0.431152f, -0.396729f, 0.462891f, -0.38916f, 0.491699f, -0.378906f, 0.520508f, -0.368652f,
+0.54541f, -0.354004f, 0.570312f, -0.339355f, 0.588623f, -0.318115f, 0.606934f, -0.296875f,
+0.617432f, -0.267578f, 0.62793f, -0.238281f, 0.62793f, -0.198242f, 0.377441f, -0.57666f,
+0.377441f, 0, 0.233398f, 0, 0.233398f, -0.57666f, 0.0112305f, -0.57666f, 0.0112305f,
+-0.687988f, 0.600098f, -0.687988f, 0.600098f, -0.57666f, 0.353027f, 0.00976562f,
+0.288574f, 0.00976562f, 0.234863f, -0.00561523f, 0.181152f, -0.0209961f, 0.142334f,
+-0.0534668f, 0.103516f, -0.0859375f, 0.0817871f, -0.136719f, 0.0600586f, -0.1875f,
+0.0600586f, -0.257812f, 0.0600586f, -0.687988f, 0.204102f, -0.687988f, 0.204102f,
+-0.269043f, 0.204102f, -0.225586f, 0.214844f, -0.194092f, 0.225586f, -0.162598f,
+0.245605f, -0.142334f, 0.265625f, -0.12207f, 0.293945f, -0.112549f, 0.322266f, -0.103027f,
+0.356934f, -0.103027f, 0.39209f, -0.103027f, 0.421631f, -0.113037f, 0.451172f, -0.123047f,
+0.472412f, -0.144043f, 0.493652f, -0.165039f, 0.505371f, -0.197266f, 0.51709f, -0.229492f,
+0.51709f, -0.273926f, 0.51709f, -0.687988f, 0.661133f, -0.687988f, 0.661133f, -0.265137f,
+0.661133f, -0.194336f, 0.638184f, -0.142578f, 0.615234f, -0.0908203f, 0.574219f,
+-0.0568848f, 0.533203f, -0.0229492f, 0.476807f, -0.0065918f, 0.42041f, 0.00976562f,
+0.353027f, 0.00976562f, 0.407227f, 0, 0.26123f, 0, 0.00683594f, -0.687988f, 0.157227f,
+-0.687988f, 0.298828f, -0.246094f, 0.305664f, -0.224121f, 0.312012f, -0.201172f,
+0.318359f, -0.178223f, 0.32373f, -0.15918f, 0.32959f, -0.136719f, 0.334961f, -0.116211f,
+0.339844f, -0.13623f, 0.345215f, -0.158203f, 0.350098f, -0.176758f, 0.356689f, -0.199951f,
+0.363281f, -0.223145f, 0.370117f, -0.246094f, 0.51123f, -0.687988f, 0.660156f, -0.687988f,
+0.765137f, 0, 0.594238f, 0, 0.500977f, -0.397949f, 0.496582f, -0.416016f, 0.491455f,
+-0.440918f, 0.486328f, -0.46582f, 0.481934f, -0.489258f, 0.476562f, -0.516113f, 0.472168f,
+-0.544922f, 0.466797f, -0.516113f, 0.461426f, -0.48877f, 0.458984f, -0.477051f, 0.456543f,
+-0.4646f, 0.454102f, -0.452148f, 0.451416f, -0.440186f, 0.44873f, -0.428223f, 0.446533f,
+-0.41748f, 0.444336f, -0.406738f, 0.441895f, -0.397949f, 0.349121f, 0, 0.178223f,
+0, 0.000976562f, -0.687988f, 0.146973f, -0.687988f, 0.23291f, -0.305176f, 0.240234f,
+-0.273926f, 0.246582f, -0.243652f, 0.25293f, -0.213379f, 0.258301f, -0.189453f, 0.26416f,
+-0.161621f, 0.269043f, -0.13623f, 0.276367f, -0.172363f, 0.283203f, -0.206543f, 0.286133f,
+-0.221191f, 0.289551f, -0.236816f, 0.292969f, -0.252441f, 0.296143f, -0.267578f,
+0.299316f, -0.282715f, 0.30249f, -0.296631f, 0.305664f, -0.310547f, 0.308105f, -0.321777f,
+0.393066f, -0.687988f, 0.554199f, -0.687988f, 0.641113f, -0.321777f, 0.644043f, -0.310059f,
+0.646973f, -0.295654f, 0.649902f, -0.28125f, 0.652832f, -0.265869f, 0.655762f, -0.250488f,
+0.658691f, -0.235107f, 0.661621f, -0.219727f, 0.664062f, -0.205078f, 0.669922f, -0.170898f,
+0.675781f, -0.13623f, 0.681641f, -0.163574f, 0.687988f, -0.192871f, 0.693359f, -0.217773f,
+0.700195f, -0.247559f, 0.707031f, -0.277344f, 0.713867f, -0.305176f, 0.796875f, -0.687988f,
+0.942871f, -0.687988f, 0.506836f, 0, 0.333984f, -0.273926f, 0.161133f, 0, 0.00878906f,
+0, 0.24707f, -0.361816f, 0.0288086f, -0.687988f, 0.181152f, -0.687988f, 0.333984f,
+-0.444824f, 0.486816f, -0.687988f, 0.638184f, -0.687988f, 0.429199f, -0.361816f,
+0.658203f, 0, 0.405762f, -0.282227f, 0.405762f, 0, 0.262207f, 0, 0.262207f, -0.282227f,
+0.0170898f, -0.687988f, 0.167969f, -0.687988f, 0.333008f, -0.396973f, 0.5f, -0.687988f,
+0.650879f, -0.687988f, 0.582031f, 0, 0.0297852f, 0, 0.0297852f, -0.102051f, 0.401855f,
+-0.575195f, 0.0668945f, -0.575195f, 0.0668945f, -0.687988f, 0.562012f, -0.687988f,
+0.562012f, -0.587891f, 0.189941f, -0.112793f, 0.582031f, -0.112793f, 0.0561523f,
+0.20752f, 0.0561523f, -0.724609f, 0.320801f, -0.724609f, 0.320801f, -0.631836f, 0.186035f,
+-0.631836f, 0.186035f, 0.114258f, 0.320801f, 0.114258f, 0.320801f, 0.20752f, 0.012207f,
+0.20752f, 0.012207f, 0.114258f, 0.147949f, 0.114258f, 0.147949f, -0.631836f, 0.012207f,
+-0.631836f, 0.012207f, -0.724609f, 0.276855f, -0.724609f, 0.276855f, 0.20752f, 0.450195f,
+-0.250977f, 0.291016f, -0.618164f, 0.132812f, -0.250977f, 0.0219727f, -0.250977f,
+0.212891f, -0.687988f, 0.370117f, -0.687988f, 0.562012f, -0.250977f, -0.00976562f,
+0.12207f, -0.00976562f, 0.0839844f, 0.564941f, 0.0839844f, 0.564941f, 0.12207f, 0.191895f,
+0.00976562f, 0.153809f, 0.00976562f, 0.123779f, -0.000732422f, 0.09375f, -0.0112305f,
+0.0727539f, -0.0314941f, 0.0517578f, -0.0517578f, 0.0405273f, -0.081543f, 0.0292969f,
+-0.111328f, 0.0292969f, -0.149414f, 0.0292969f, -0.196289f, 0.0456543f, -0.228271f,
+0.0620117f, -0.260254f, 0.090332f, -0.280029f, 0.118652f, -0.299805f, 0.156738f,
+-0.308838f, 0.194824f, -0.317871f, 0.237793f, -0.318359f, 0.351562f, -0.320312f,
+0.351562f, -0.347168f, 0.351562f, -0.375977f, 0.346436f, -0.395264f, 0.341309f, -0.414551f,
+0.331543f, -0.426758f, 0.321777f, -0.438965f, 0.307373f, -0.444092f, 0.292969f, -0.449219f,
+0.274414f, -0.449219f, 0.257324f, -0.449219f, 0.243896f, -0.445801f, 0.230469f, -0.442383f,
+0.220703f, -0.433838f, 0.210938f, -0.425293f, 0.204834f, -0.410889f, 0.19873f, -0.396484f,
+0.196289f, -0.374512f, 0.0532227f, -0.381348f, 0.059082f, -0.416016f, 0.074707f,
+-0.44458f, 0.090332f, -0.473145f, 0.11792f, -0.494141f, 0.145508f, -0.515137f, 0.185791f,
+-0.526611f, 0.226074f, -0.538086f, 0.280273f, -0.538086f, 0.32959f, -0.538086f, 0.368164f,
+-0.525879f, 0.406738f, -0.513672f, 0.433594f, -0.489502f, 0.460449f, -0.465332f,
+0.474609f, -0.430176f, 0.48877f, -0.39502f, 0.48877f, -0.348633f, 0.48877f, -0.15625f,
+0.48877f, -0.137695f, 0.490479f, -0.123047f, 0.492188f, -0.108398f, 0.496826f, -0.0983887f,
+0.501465f, -0.0883789f, 0.51001f, -0.083252f, 0.518555f, -0.078125f, 0.532227f, -0.078125f,
+0.547852f, -0.078125f, 0.5625f, -0.0810547f, 0.5625f, -0.00683594f, 0.550293f, -0.00390625f,
+0.540527f, -0.00146484f, 0.530762f, 0.000976562f, 0.520996f, 0.00244141f, 0.51123f,
+0.00390625f, 0.500244f, 0.00488281f, 0.489258f, 0.00585938f, 0.474609f, 0.00585938f,
+0.422852f, 0.00585938f, 0.398193f, -0.0195312f, 0.373535f, -0.0449219f, 0.368652f,
+-0.0942383f, 0.365723f, -0.0942383f, 0.338379f, -0.0449219f, 0.295654f, -0.0175781f,
+0.25293f, 0.00976562f, 0.191895f, 0.00976562f, 0.351562f, -0.244629f, 0.28125f, -0.243652f,
+0.259277f, -0.242676f, 0.239502f, -0.23999f, 0.219727f, -0.237305f, 0.204834f, -0.22876f,
+0.189941f, -0.220215f, 0.181152f, -0.204102f, 0.172363f, -0.187988f, 0.172363f, -0.160156f,
+0.172363f, -0.122559f, 0.189697f, -0.104248f, 0.207031f, -0.0859375f, 0.23584f, -0.0859375f,
+0.262207f, -0.0859375f, 0.283691f, -0.097168f, 0.305176f, -0.108398f, 0.320068f,
+-0.126709f, 0.334961f, -0.14502f, 0.343262f, -0.168945f, 0.351562f, -0.192871f, 0.351562f,
+-0.217773f, 0.569824f, -0.266113f, 0.569824f, -0.206055f, 0.557861f, -0.155518f,
+0.545898f, -0.10498f, 0.520996f, -0.0681152f, 0.496094f, -0.03125f, 0.457764f, -0.0107422f,
+0.419434f, 0.00976562f, 0.367188f, 0.00976562f, 0.34375f, 0.00976562f, 0.320312f,
+0.00488281f, 0.296875f, 0, 0.275879f, -0.0112305f, 0.254883f, -0.0224609f, 0.237305f,
+-0.0405273f, 0.219727f, -0.0585938f, 0.207031f, -0.0849609f, 0.206055f, -0.0849609f,
+0.206055f, -0.074707f, 0.205322f, -0.0615234f, 0.20459f, -0.0483398f, 0.203613f,
+-0.0358887f, 0.202637f, -0.0234375f, 0.201416f, -0.0136719f, 0.200195f, -0.00390625f,
+0.199219f, 0, 0.065918f, 0, 0.0673828f, -0.0170898f, 0.0686035f, -0.048584f, 0.0698242f,
+-0.0800781f, 0.0698242f, -0.120605f, 0.0698242f, -0.724609f, 0.207031f, -0.724609f,
+0.207031f, -0.522461f, 0.207031f, -0.506836f, 0.206787f, -0.491943f, 0.206543f, -0.477051f,
+0.206055f, -0.464355f, 0.205566f, -0.449707f, 0.205078f, -0.436523f, 0.207031f, -0.436523f,
+0.231934f, -0.491211f, 0.275391f, -0.514648f, 0.318848f, -0.538086f, 0.375977f, -0.538086f,
+0.426758f, -0.538086f, 0.463379f, -0.517822f, 0.5f, -0.497559f, 0.523682f, -0.461182f,
+0.547363f, -0.424805f, 0.558594f, -0.375f, 0.569824f, -0.325195f, 0.569824f, -0.266113f,
+0.426758f, -0.266113f, 0.426758f, -0.355957f, 0.400391f, -0.399414f, 0.374023f, -0.442871f,
+0.318848f, -0.442871f, 0.297852f, -0.442871f, 0.277344f, -0.43457f, 0.256836f, -0.42627f,
+0.240723f, -0.405518f, 0.224609f, -0.384766f, 0.214844f, -0.349854f, 0.205078f, -0.314941f,
+0.205078f, -0.261719f, 0.205078f, -0.209961f, 0.214844f, -0.175781f, 0.224609f, -0.141602f,
+0.240234f, -0.121094f, 0.255859f, -0.100586f, 0.276367f, -0.0922852f, 0.296875f,
+-0.0839844f, 0.317871f, -0.0839844f, 0.370117f, -0.0839844f, 0.398438f, -0.127197f,
+0.426758f, -0.17041f, 0.426758f, -0.266113f, 0.412109f, 0, 0.411133f, -0.00390625f,
+0.409912f, -0.013916f, 0.408691f, -0.0239258f, 0.407471f, -0.0366211f, 0.40625f,
+-0.0493164f, 0.405518f, -0.0625f, 0.404785f, -0.0756836f, 0.404785f, -0.0859375f,
+0.402832f, -0.0859375f, 0.378906f, -0.034668f, 0.336182f, -0.0124512f, 0.293457f,
+0.00976562f, 0.233887f, 0.00976562f, 0.184082f, 0.00976562f, 0.147705f, -0.0107422f,
+0.111328f, -0.03125f, 0.0876465f, -0.0678711f, 0.0639648f, -0.104492f, 0.0524902f,
+-0.154541f, 0.0410156f, -0.20459f, 0.0410156f, -0.263672f, 0.0410156f, -0.32373f,
+0.0529785f, -0.374023f, 0.0649414f, -0.424316f, 0.0898438f, -0.460693f, 0.114746f,
+-0.49707f, 0.153076f, -0.517578f, 0.191406f, -0.538086f, 0.244141f, -0.538086f, 0.27002f,
+-0.538086f, 0.293945f, -0.532715f, 0.317871f, -0.527344f, 0.338379f, -0.516113f,
+0.358887f, -0.504883f, 0.375488f, -0.487305f, 0.39209f, -0.469727f, 0.403809f, -0.444824f,
+0.404785f, -0.444824f, 0.404785f, -0.449707f, 0.404541f, -0.459229f, 0.404297f, -0.46875f,
+0.404297f, -0.480957f, 0.404297f, -0.493164f, 0.404053f, -0.506348f, 0.403809f, -0.519531f,
+0.403809f, -0.531738f, 0.403809f, -0.724609f, 0.541016f, -0.724609f, 0.541016f, -0.115234f,
+0.541016f, -0.0766602f, 0.54248f, -0.0466309f, 0.543945f, -0.0166016f, 0.544922f,
+0, 0.405762f, -0.26709f, 0.405762f, -0.319336f, 0.395996f, -0.35376f, 0.38623f, -0.388184f,
+0.370361f, -0.408447f, 0.354492f, -0.428711f, 0.334229f, -0.436768f, 0.313965f, -0.444824f,
+0.292969f, -0.444824f, 0.266602f, -0.444824f, 0.246338f, -0.43457f, 0.226074f, -0.424316f,
+0.212158f, -0.402344f, 0.198242f, -0.380371f, 0.191162f, -0.346191f, 0.184082f, -0.312012f,
+0.184082f, -0.263672f, 0.184082f, -0.0839844f, 0.291992f, -0.0839844f, 0.3125f, -0.0839844f,
+0.333008f, -0.0927734f, 0.353516f, -0.101562f, 0.369629f, -0.122559f, 0.385742f,
+-0.143555f, 0.395752f, -0.178955f, 0.405762f, -0.214355f, 0.405762f, -0.26709f, 0.286133f,
+0.00976562f, 0.229004f, 0.00976562f, 0.18335f, -0.00708008f, 0.137695f, -0.0239258f,
+0.105469f, -0.0583496f, 0.0732422f, -0.0927734f, 0.0561523f, -0.144775f, 0.0390625f,
+-0.196777f, 0.0390625f, -0.266602f, 0.0390625f, -0.342285f, 0.0593262f, -0.394043f,
+0.0795898f, -0.445801f, 0.114014f, -0.477783f, 0.148438f, -0.509766f, 0.193359f,
+-0.523926f, 0.238281f, -0.538086f, 0.288086f, -0.538086f, 0.350586f, -0.538086f,
+0.394775f, -0.516357f, 0.438965f, -0.494629f, 0.467285f, -0.455566f, 0.495605f, -0.416504f,
+0.508789f, -0.362061f, 0.521973f, -0.307617f, 0.521973f, -0.241699f, 0.521973f, -0.237793f,
+0.183105f, -0.237793f, 0.183105f, -0.20459f, 0.188965f, -0.176025f, 0.194824f, -0.147461f,
+0.208008f, -0.126709f, 0.221191f, -0.105957f, 0.242188f, -0.0939941f, 0.263184f,
+-0.0820312f, 0.292969f, -0.0820312f, 0.329102f, -0.0820312f, 0.352051f, -0.0974121f,
+0.375f, -0.112793f, 0.384766f, -0.14502f, 0.51416f, -0.133789f, 0.505371f, -0.111328f,
+0.489502f, -0.0859375f, 0.473633f, -0.0605469f, 0.447266f, -0.0393066f, 0.420898f,
+-0.0180664f, 0.381592f, -0.00415039f, 0.342285f, 0.00976562f, 0.286133f, 0.00976562f,
+0.286133f, -0.45166f, 0.265137f, -0.45166f, 0.246826f, -0.44458f, 0.228516f, -0.4375f,
+0.215088f, -0.422119f, 0.20166f, -0.406738f, 0.193359f, -0.382324f, 0.185059f, -0.35791f,
+0.184082f, -0.32373f, 0.38916f, -0.32373f, 0.385254f, -0.387695f, 0.358398f, -0.419678f,
+0.331543f, -0.45166f, 0.286133f, -0.45166f, 0.230957f, -0.435547f, 0.230957f, 0,
+0.0942383f, 0, 0.0942383f, -0.435547f, 0.0170898f, -0.435547f, 0.0170898f, -0.52832f,
+0.0942383f, -0.52832f, 0.0942383f, -0.583496f, 0.0942383f, -0.61377f, 0.101562f,
+-0.639404f, 0.108887f, -0.665039f, 0.126465f, -0.684082f, 0.144043f, -0.703125f,
+0.173828f, -0.713867f, 0.203613f, -0.724609f, 0.248047f, -0.724609f, 0.271484f, -0.724609f,
+0.294189f, -0.722168f, 0.316895f, -0.719727f, 0.334961f, -0.716797f, 0.334961f, -0.628418f,
+0.326172f, -0.630371f, 0.315186f, -0.631592f, 0.304199f, -0.632812f, 0.294922f, -0.632812f,
+0.275879f, -0.632812f, 0.263428f, -0.628906f, 0.250977f, -0.625f, 0.243896f, -0.617188f,
+0.236816f, -0.609375f, 0.233887f, -0.597412f, 0.230957f, -0.585449f, 0.230957f, -0.569824f,
+0.230957f, -0.52832f, 0.334961f, -0.52832f, 0.334961f, -0.435547f, 0.291016f, 0.211914f,
+0.23877f, 0.211914f, 0.198975f, 0.201416f, 0.15918f, 0.190918f, 0.131104f, 0.172119f,
+0.103027f, 0.15332f, 0.0861816f, 0.127197f, 0.0693359f, 0.101074f, 0.0629883f, 0.0698242f,
+0.200195f, 0.0537109f, 0.20752f, 0.0854492f, 0.231689f, 0.103516f, 0.255859f, 0.121582f,
+0.294922f, 0.121582f, 0.319336f, 0.121582f, 0.3396f, 0.114746f, 0.359863f, 0.10791f,
+0.374268f, 0.0915527f, 0.388672f, 0.0751953f, 0.396729f, 0.0483398f, 0.404785f, 0.0214844f,
+0.404785f, -0.0180664f, 0.404785f, -0.0317383f, 0.404785f, -0.0458984f, 0.404785f,
+-0.0600586f, 0.405273f, -0.0717773f, 0.405762f, -0.0854492f, 0.405762f, -0.0981445f,
+0.404785f, -0.0981445f, 0.380859f, -0.046875f, 0.337646f, -0.0239258f, 0.294434f,
+-0.000976562f, 0.234863f, -0.000976562f, 0.18457f, -0.000976562f, 0.148193f, -0.020752f,
+0.111816f, -0.0405273f, 0.0878906f, -0.0759277f, 0.0639648f, -0.111328f, 0.0524902f,
+-0.1604f, 0.0410156f, -0.209473f, 0.0410156f, -0.268555f, 0.0410156f, -0.32959f,
+0.0532227f, -0.37915f, 0.0654297f, -0.428711f, 0.0905762f, -0.464355f, 0.115723f,
+-0.5f, 0.154053f, -0.519287f, 0.192383f, -0.538574f, 0.245117f, -0.538574f, 0.297852f,
+-0.538574f, 0.3396f, -0.516113f, 0.381348f, -0.493652f, 0.404785f, -0.443359f, 0.407227f,
+-0.443359f, 0.407227f, -0.453613f, 0.407959f, -0.467041f, 0.408691f, -0.480469f,
+0.409668f, -0.49292f, 0.410645f, -0.505371f, 0.411865f, -0.515137f, 0.413086f, -0.524902f,
+0.414062f, -0.52832f, 0.543945f, -0.52832f, 0.542969f, -0.510742f, 0.541992f, -0.479004f,
+0.541016f, -0.447266f, 0.541016f, -0.40625f, 0.541016f, -0.0161133f, 0.541016f, 0.0415039f,
+0.524414f, 0.0842285f, 0.507812f, 0.126953f, 0.47583f, 0.155273f, 0.443848f, 0.183594f,
+0.397217f, 0.197754f, 0.350586f, 0.211914f, 0.291016f, 0.211914f, 0.405762f, -0.271484f,
+0.405762f, -0.321289f, 0.395996f, -0.354492f, 0.38623f, -0.387695f, 0.370605f, -0.407715f,
+0.35498f, -0.427734f, 0.334717f, -0.436035f, 0.314453f, -0.444336f, 0.293945f, -0.444336f,
+0.267578f, -0.444336f, 0.247314f, -0.434082f, 0.227051f, -0.423828f, 0.212891f, -0.402344f,
+0.19873f, -0.380859f, 0.191406f, -0.347656f, 0.184082f, -0.314453f, 0.184082f, -0.268555f,
+0.184082f, -0.183105f, 0.211426f, -0.139648f, 0.23877f, -0.0961914f, 0.292969f, -0.0961914f,
+0.313477f, -0.0961914f, 0.33374f, -0.104248f, 0.354004f, -0.112305f, 0.370117f, -0.132568f,
+0.38623f, -0.152832f, 0.395996f, -0.186523f, 0.405762f, -0.220215f, 0.405762f, -0.271484f,
+0.205078f, -0.422852f, 0.23291f, -0.483398f, 0.274902f, -0.510742f, 0.316895f, -0.538086f,
+0.375f, -0.538086f, 0.422852f, -0.538086f, 0.455811f, -0.522461f, 0.48877f, -0.506836f,
+0.509521f, -0.479492f, 0.530273f, -0.452148f, 0.539551f, -0.415039f, 0.548828f, -0.37793f,
+0.548828f, -0.334961f, 0.548828f, 0, 0.412109f, 0, 0.412109f, -0.295898f, 0.412109f,
+-0.32666f, 0.407227f, -0.352295f, 0.402344f, -0.37793f, 0.391113f, -0.39624f, 0.379883f,
+-0.414551f, 0.361816f, -0.424805f, 0.34375f, -0.435059f, 0.317871f, -0.435059f, 0.292969f,
+-0.435059f, 0.272705f, -0.424072f, 0.252441f, -0.413086f, 0.237793f, -0.392822f,
+0.223145f, -0.372559f, 0.215088f, -0.344482f, 0.207031f, -0.316406f, 0.207031f, -0.282715f,
+0.207031f, 0, 0.0698242f, 0, 0.0698242f, -0.724609f, 0.207031f, -0.724609f, 0.207031f,
+-0.526855f, 0.207031f, -0.51123f, 0.206543f, -0.495361f, 0.206055f, -0.479492f, 0.205322f,
+-0.465576f, 0.20459f, -0.45166f, 0.204102f, -0.44043f, 0.203613f, -0.429199f, 0.203125f,
+-0.422852f, 0.0698242f, -0.623535f, 0.0698242f, -0.724609f, 0.207031f, -0.724609f,
+0.207031f, -0.623535f, 0.0698242f, 0, 0.0698242f, -0.52832f, 0.207031f, -0.52832f,
+0.207031f, 0, 0.0703125f, -0.623535f, 0.0703125f, -0.724609f, 0.20752f, -0.724609f,
+0.20752f, -0.623535f, 0.0673828f, 0.20752f, 0.0400391f, 0.20752f, 0.0197754f, 0.206299f,
+-0.000488281f, 0.205078f, -0.015625f, 0.203125f, -0.015625f, 0.106445f, -0.00927734f,
+0.107422f, -0.00292969f, 0.10791f, 0.00341797f, 0.108398f, 0.00927734f, 0.108398f,
+0.0283203f, 0.108398f, 0.0400391f, 0.104492f, 0.0517578f, 0.100586f, 0.0585938f,
+0.0913086f, 0.0654297f, 0.0820312f, 0.0678711f, 0.0668945f, 0.0703125f, 0.0517578f,
+0.0703125f, 0.0292969f, 0.0703125f, -0.52832f, 0.20752f, -0.52832f, 0.20752f, 0.0625f,
+0.20752f, 0.0942383f, 0.199707f, 0.120605f, 0.191895f, 0.146973f, 0.175049f, 0.166504f,
+0.158203f, 0.186035f, 0.131592f, 0.196777f, 0.10498f, 0.20752f, 0.0673828f, 0.20752f,
+0.407227f, 0, 0.266113f, -0.239258f, 0.207031f, -0.198242f, 0.207031f, 0, 0.0698242f,
+0, 0.0698242f, -0.724609f, 0.207031f, -0.724609f, 0.207031f, -0.30957f, 0.395508f,
+-0.52832f, 0.542969f, -0.52832f, 0.357422f, -0.322266f, 0.557129f, 0, 0.0698242f,
+0, 0.0698242f, -0.724609f, 0.207031f, -0.724609f, 0.207031f, 0, 0.380859f, 0, 0.380859f,
+-0.296387f, 0.380859f, -0.327148f, 0.376709f, -0.352783f, 0.372559f, -0.378418f,
+0.363037f, -0.396729f, 0.353516f, -0.415039f, 0.338135f, -0.425293f, 0.322754f, -0.435547f,
+0.300781f, -0.435547f, 0.279785f, -0.435547f, 0.262695f, -0.424561f, 0.245605f, -0.413574f,
+0.233154f, -0.393311f, 0.220703f, -0.373047f, 0.213867f, -0.344971f, 0.207031f, -0.316895f,
+0.207031f, -0.283203f, 0.207031f, 0, 0.0698242f, 0, 0.0698242f, -0.410156f, 0.0698242f,
+-0.427246f, 0.0695801f, -0.445312f, 0.0693359f, -0.463379f, 0.0686035f, -0.479736f,
+0.0678711f, -0.496094f, 0.0673828f, -0.509033f, 0.0668945f, -0.521973f, 0.065918f,
+-0.52832f, 0.196777f, -0.52832f, 0.197754f, -0.522461f, 0.19873f, -0.509521f, 0.199707f,
+-0.496582f, 0.200684f, -0.480957f, 0.20166f, -0.465332f, 0.202393f, -0.449707f, 0.203125f,
+-0.434082f, 0.203125f, -0.42334f, 0.205078f, -0.42334f, 0.230469f, -0.483887f, 0.268311f,
+-0.51123f, 0.306152f, -0.538574f, 0.358887f, -0.538574f, 0.419434f, -0.538574f, 0.456299f,
+-0.509033f, 0.493164f, -0.479492f, 0.505859f, -0.42334f, 0.508789f, -0.42334f, 0.522949f,
+-0.456055f, 0.539307f, -0.478027f, 0.555664f, -0.5f, 0.575439f, -0.513428f, 0.595215f,
+-0.526855f, 0.618408f, -0.532715f, 0.641602f, -0.538574f, 0.668945f, -0.538574f,
+0.712402f, -0.538574f, 0.742432f, -0.522949f, 0.772461f, -0.507324f, 0.79126f, -0.47998f,
+0.810059f, -0.452637f, 0.818604f, -0.415527f, 0.827148f, -0.378418f, 0.827148f, -0.335449f,
+0.827148f, 0, 0.690918f, 0, 0.690918f, -0.296387f, 0.690918f, -0.327148f, 0.686768f,
+-0.352783f, 0.682617f, -0.378418f, 0.673096f, -0.396729f, 0.663574f, -0.415039f,
+0.648193f, -0.425293f, 0.632812f, -0.435547f, 0.61084f, -0.435547f, 0.590332f, -0.435547f,
+0.573486f, -0.425049f, 0.556641f, -0.414551f, 0.544189f, -0.395264f, 0.531738f, -0.375977f,
+0.524902f, -0.349121f, 0.518066f, -0.322266f, 0.51709f, -0.289551f, 0.51709f, 0,
+0.412109f, 0, 0.412109f, -0.296387f, 0.412109f, -0.327148f, 0.407227f, -0.352783f,
+0.402344f, -0.378418f, 0.391113f, -0.396729f, 0.379883f, -0.415039f, 0.361816f, -0.425293f,
+0.34375f, -0.435547f, 0.317871f, -0.435547f, 0.292969f, -0.435547f, 0.272705f, -0.424561f,
+0.252441f, -0.413574f, 0.237793f, -0.393311f, 0.223145f, -0.373047f, 0.215088f, -0.344971f,
+0.207031f, -0.316895f, 0.207031f, -0.283203f, 0.207031f, 0, 0.0698242f, 0, 0.0698242f,
+-0.410156f, 0.0698242f, -0.427246f, 0.0695801f, -0.445312f, 0.0693359f, -0.463379f,
+0.0686035f, -0.479736f, 0.0678711f, -0.496094f, 0.0673828f, -0.509033f, 0.0668945f,
+-0.521973f, 0.065918f, -0.52832f, 0.196777f, -0.52832f, 0.197754f, -0.522461f, 0.19873f,
+-0.509521f, 0.199707f, -0.496582f, 0.200684f, -0.480957f, 0.20166f, -0.465332f, 0.202393f,
+-0.449707f, 0.203125f, -0.434082f, 0.203125f, -0.42334f, 0.205078f, -0.42334f, 0.23291f,
+-0.483887f, 0.274902f, -0.51123f, 0.316895f, -0.538574f, 0.375f, -0.538574f, 0.422852f,
+-0.538574f, 0.455811f, -0.522949f, 0.48877f, -0.507324f, 0.509521f, -0.47998f, 0.530273f,
+-0.452637f, 0.539551f, -0.415527f, 0.548828f, -0.378418f, 0.548828f, -0.335449f,
+0.548828f, 0, 0.571777f, -0.264648f, 0.571777f, -0.204102f, 0.554932f, -0.153809f,
+0.538086f, -0.103516f, 0.504395f, -0.0671387f, 0.470703f, -0.0307617f, 0.42041f,
+-0.010498f, 0.370117f, 0.00976562f, 0.303223f, 0.00976562f, 0.23877f, 0.00976562f,
+0.189453f, -0.0102539f, 0.140137f, -0.0302734f, 0.106689f, -0.0664062f, 0.0732422f,
+-0.102539f, 0.0561523f, -0.153076f, 0.0390625f, -0.203613f, 0.0390625f, -0.264648f,
+0.0390625f, -0.32373f, 0.0554199f, -0.373779f, 0.0717773f, -0.423828f, 0.10498f,
+-0.460449f, 0.138184f, -0.49707f, 0.188477f, -0.517578f, 0.23877f, -0.538086f, 0.306152f,
+-0.538086f, 0.377441f, -0.538086f, 0.427734f, -0.517578f, 0.478027f, -0.49707f, 0.51001f,
+-0.460693f, 0.541992f, -0.424316f, 0.556885f, -0.374268f, 0.571777f, -0.324219f,
+0.571777f, -0.264648f, 0.428223f, -0.264648f, 0.428223f, -0.358887f, 0.397461f, -0.401367f,
+0.366699f, -0.443848f, 0.308105f, -0.443848f, 0.247559f, -0.443848f, 0.215332f, -0.400879f,
+0.183105f, -0.35791f, 0.183105f, -0.264648f, 0.183105f, -0.217285f, 0.19165f, -0.183105f,
+0.200195f, -0.148926f, 0.21582f, -0.126953f, 0.231445f, -0.10498f, 0.253418f, -0.0944824f,
+0.275391f, -0.0839844f, 0.301758f, -0.0839844f, 0.332031f, -0.0839844f, 0.355713f,
+-0.0944824f, 0.379395f, -0.10498f, 0.395508f, -0.126953f, 0.411621f, -0.148926f,
+0.419922f, -0.183105f, 0.428223f, -0.217285f, 0.428223f, -0.264648f, 0.569824f, -0.266602f,
+0.569824f, -0.206543f, 0.557861f, -0.155762f, 0.545898f, -0.10498f, 0.520996f, -0.0683594f,
+0.496094f, -0.0317383f, 0.457764f, -0.0109863f, 0.419434f, 0.00976562f, 0.367188f,
+0.00976562f, 0.34375f, 0.00976562f, 0.320557f, 0.00488281f, 0.297363f, 0, 0.276367f,
+-0.0109863f, 0.255371f, -0.0219727f, 0.237549f, -0.0397949f, 0.219727f, -0.0576172f,
+0.207031f, -0.0839844f, 0.204102f, -0.0839844f, 0.20459f, -0.081543f, 0.205078f,
+-0.0717773f, 0.205566f, -0.0620117f, 0.206055f, -0.0490723f, 0.206543f, -0.0361328f,
+0.206787f, -0.0217285f, 0.207031f, -0.00732422f, 0.207031f, 0.00488281f, 0.207031f,
+0.20752f, 0.0698242f, 0.20752f, 0.0698242f, -0.406738f, 0.0698242f, -0.447266f, 0.0686035f,
+-0.479004f, 0.0673828f, -0.510742f, 0.065918f, -0.52832f, 0.199219f, -0.52832f, 0.200195f,
+-0.524902f, 0.201416f, -0.515137f, 0.202637f, -0.505371f, 0.203369f, -0.492676f,
+0.204102f, -0.47998f, 0.20459f, -0.466309f, 0.205078f, -0.452637f, 0.205078f, -0.442383f,
+0.207031f, -0.442383f, 0.231934f, -0.494629f, 0.275391f, -0.51709f, 0.318848f, -0.539551f,
+0.375977f, -0.539551f, 0.42627f, -0.539551f, 0.462891f, -0.519043f, 0.499512f, -0.498535f,
+0.523193f, -0.462402f, 0.546875f, -0.42627f, 0.55835f, -0.376221f, 0.569824f, -0.326172f,
+0.569824f, -0.266602f, 0.426758f, -0.266602f, 0.426758f, -0.356934f, 0.399414f, -0.400635f,
+0.37207f, -0.444336f, 0.317871f, -0.444336f, 0.297363f, -0.444336f, 0.2771f, -0.435791f,
+0.256836f, -0.427246f, 0.240967f, -0.406494f, 0.225098f, -0.385742f, 0.215088f, -0.35083f,
+0.205078f, -0.315918f, 0.205078f, -0.262695f, 0.205078f, -0.210938f, 0.214844f, -0.176514f,
+0.224609f, -0.14209f, 0.240479f, -0.121582f, 0.256348f, -0.101074f, 0.276367f, -0.0925293f,
+0.296387f, -0.0839844f, 0.316895f, -0.0839844f, 0.343262f, -0.0839844f, 0.36377f,
+-0.0944824f, 0.384277f, -0.10498f, 0.398193f, -0.127197f, 0.412109f, -0.149414f,
+0.419434f, -0.184082f, 0.426758f, -0.21875f, 0.426758f, -0.266602f, 0.0410156f, -0.263672f,
+0.0410156f, -0.32373f, 0.0532227f, -0.374268f, 0.0654297f, -0.424805f, 0.0905762f,
+-0.461182f, 0.115723f, -0.497559f, 0.154053f, -0.518066f, 0.192383f, -0.538574f,
+0.245117f, -0.538574f, 0.297852f, -0.538574f, 0.3396f, -0.516113f, 0.381348f, -0.493652f,
+0.404785f, -0.443359f, 0.404785f, -0.453613f, 0.405518f, -0.467041f, 0.40625f, -0.480469f,
+0.407471f, -0.49292f, 0.408691f, -0.505371f, 0.409912f, -0.515137f, 0.411133f, -0.524902f,
+0.412109f, -0.52832f, 0.543945f, -0.52832f, 0.542969f, -0.510742f, 0.541992f, -0.479004f,
+0.541016f, -0.447266f, 0.541016f, -0.406738f, 0.541016f, 0.20752f, 0.404785f, 0.20752f,
+0.404785f, -0.012207f, 0.404785f, -0.0258789f, 0.405273f, -0.0390625f, 0.405762f,
+-0.0522461f, 0.40625f, -0.0634766f, 0.406738f, -0.0761719f, 0.407227f, -0.0878906f,
+0.40625f, -0.0878906f, 0.382324f, -0.0366211f, 0.337891f, -0.0134277f, 0.293457f,
+0.00976562f, 0.233887f, 0.00976562f, 0.184082f, 0.00976562f, 0.147705f, -0.0107422f,
+0.111328f, -0.03125f, 0.0876465f, -0.0678711f, 0.0639648f, -0.104492f, 0.0524902f,
+-0.154541f, 0.0410156f, -0.20459f, 0.0410156f, -0.263672f, 0.405762f, -0.266602f,
+0.405762f, -0.319336f, 0.395996f, -0.353516f, 0.38623f, -0.387695f, 0.370605f, -0.407959f,
+0.35498f, -0.428223f, 0.334717f, -0.436279f, 0.314453f, -0.444336f, 0.293945f, -0.444336f,
+0.267578f, -0.444336f, 0.247314f, -0.434082f, 0.227051f, -0.423828f, 0.212891f, -0.401855f,
+0.19873f, -0.379883f, 0.191406f, -0.345703f, 0.184082f, -0.311523f, 0.184082f, -0.263672f,
+0.184082f, -0.0839844f, 0.292969f, -0.0839844f, 0.313477f, -0.0839844f, 0.33374f,
+-0.0927734f, 0.354004f, -0.101562f, 0.370117f, -0.122559f, 0.38623f, -0.143555f,
+0.395996f, -0.178711f, 0.405762f, -0.213867f, 0.405762f, -0.266602f, 0.0698242f,
+0, 0.0698242f, -0.404297f, 0.0698242f, -0.421387f, 0.0695801f, -0.44043f, 0.0693359f,
+-0.459473f, 0.0686035f, -0.476807f, 0.0678711f, -0.494141f, 0.0673828f, -0.508057f,
+0.0668945f, -0.521973f, 0.065918f, -0.52832f, 0.196777f, -0.52832f, 0.197754f, -0.522461f,
+0.19873f, -0.508057f, 0.199707f, -0.493652f, 0.200684f, -0.476562f, 0.20166f, -0.459473f,
+0.202393f, -0.442627f, 0.203125f, -0.425781f, 0.203125f, -0.415527f, 0.205078f, -0.415527f,
+0.215332f, -0.444336f, 0.225586f, -0.467041f, 0.23584f, -0.489746f, 0.249756f, -0.505615f,
+0.263672f, -0.521484f, 0.283203f, -0.530029f, 0.302734f, -0.538574f, 0.331543f, -0.538574f,
+0.34375f, -0.538574f, 0.355713f, -0.536377f, 0.367676f, -0.53418f, 0.374023f, -0.53125f,
+0.374023f, -0.416504f, 0.36084f, -0.419434f, 0.347412f, -0.421631f, 0.333984f, -0.423828f,
+0.31543f, -0.423828f, 0.26416f, -0.423828f, 0.235596f, -0.382324f, 0.207031f, -0.34082f,
+0.207031f, -0.259277f, 0.207031f, 0, 0.515137f, -0.154297f, 0.515137f, -0.116211f,
+0.499268f, -0.0859375f, 0.483398f, -0.0556641f, 0.453125f, -0.0344238f, 0.422852f,
+-0.0131836f, 0.378906f, -0.00170898f, 0.334961f, 0.00976562f, 0.278809f, 0.00976562f,
+0.228516f, 0.00976562f, 0.187988f, 0.00244141f, 0.147461f, -0.00488281f, 0.116943f,
+-0.0217285f, 0.0864258f, -0.0385742f, 0.065918f, -0.0654297f, 0.0454102f, -0.0922852f,
+0.0351562f, -0.131836f, 0.155762f, -0.149902f, 0.161621f, -0.12793f, 0.171875f, -0.114258f,
+0.182129f, -0.100586f, 0.197266f, -0.0932617f, 0.212402f, -0.0859375f, 0.232666f,
+-0.0834961f, 0.25293f, -0.0810547f, 0.278809f, -0.0810547f, 0.302246f, -0.0810547f,
+0.32251f, -0.0837402f, 0.342773f, -0.0864258f, 0.357666f, -0.0930176f, 0.372559f,
+-0.0996094f, 0.380859f, -0.111572f, 0.38916f, -0.123535f, 0.38916f, -0.141602f, 0.38916f,
+-0.162109f, 0.377197f, -0.174072f, 0.365234f, -0.186035f, 0.344482f, -0.193604f,
+0.32373f, -0.201172f, 0.295654f, -0.206787f, 0.267578f, -0.212402f, 0.23584f, -0.219727f,
+0.202637f, -0.227051f, 0.17041f, -0.237305f, 0.138184f, -0.247559f, 0.112793f, -0.265137f,
+0.0874023f, -0.282715f, 0.0717773f, -0.309814f, 0.0561523f, -0.336914f, 0.0561523f,
+-0.378418f, 0.0561523f, -0.416016f, 0.0708008f, -0.445557f, 0.0854492f, -0.475098f,
+0.11377f, -0.49585f, 0.14209f, -0.516602f, 0.183838f, -0.527588f, 0.225586f, -0.538574f,
+0.279785f, -0.538574f, 0.322754f, -0.538574f, 0.359863f, -0.530518f, 0.396973f, -0.522461f,
+0.42627f, -0.505127f, 0.455566f, -0.487793f, 0.475342f, -0.460938f, 0.495117f, -0.434082f,
+0.50293f, -0.395996f, 0.381348f, -0.383301f, 0.37793f, -0.402344f, 0.369141f, -0.414795f,
+0.360352f, -0.427246f, 0.347412f, -0.43457f, 0.334473f, -0.441895f, 0.317383f, -0.44458f,
+0.300293f, -0.447266f, 0.279785f, -0.447266f, 0.230957f, -0.447266f, 0.206543f, -0.434814f,
+0.182129f, -0.422363f, 0.182129f, -0.393066f, 0.182129f, -0.375f, 0.192139f, -0.364258f,
+0.202148f, -0.353516f, 0.220459f, -0.346436f, 0.23877f, -0.339355f, 0.263916f, -0.334229f,
+0.289062f, -0.329102f, 0.318848f, -0.321777f, 0.355469f, -0.313965f, 0.390869f, -0.303467f,
+0.42627f, -0.292969f, 0.453857f, -0.274658f, 0.481445f, -0.256348f, 0.498291f, -0.227539f,
+0.515137f, -0.19873f, 0.515137f, -0.154297f, 0.199219f, -0.52832f, 0.199219f, -0.231934f,
+0.199219f, -0.201172f, 0.204102f, -0.175537f, 0.208984f, -0.149902f, 0.220215f, -0.131592f,
+0.231445f, -0.113281f, 0.249268f, -0.103027f, 0.26709f, -0.0927734f, 0.292969f, -0.0927734f,
+0.317871f, -0.0927734f, 0.338135f, -0.10376f, 0.358398f, -0.114746f, 0.373047f, -0.13501f,
+0.387695f, -0.155273f, 0.395752f, -0.18335f, 0.403809f, -0.211426f, 0.403809f, -0.245117f,
+0.403809f, -0.52832f, 0.541016f, -0.52832f, 0.541016f, -0.118164f, 0.541016f, -0.101562f,
+0.54126f, -0.083252f, 0.541504f, -0.0649414f, 0.542236f, -0.048584f, 0.542969f, -0.0322266f,
+0.543701f, -0.0192871f, 0.544434f, -0.00634766f, 0.544922f, 0, 0.414062f, 0, 0.413574f,
+-0.00585938f, 0.412354f, -0.0187988f, 0.411133f, -0.0317383f, 0.4104f, -0.0473633f,
+0.409668f, -0.0629883f, 0.408936f, -0.0786133f, 0.408203f, -0.0942383f, 0.408203f,
+-0.10498f, 0.405762f, -0.10498f, 0.378418f, -0.0449219f, 0.336182f, -0.0175781f,
+0.293945f, 0.00976562f, 0.23584f, 0.00976562f, 0.188477f, 0.00976562f, 0.155273f,
+-0.00585938f, 0.12207f, -0.0214844f, 0.101318f, -0.048584f, 0.0805664f, -0.0756836f,
+0.0712891f, -0.112793f, 0.0620117f, -0.149902f, 0.0620117f, -0.192871f, 0.0620117f,
+-0.52832f, 0.275879f, -0.11084f, 0.408203f, -0.52832f, 0.551758f, -0.52832f, 0.356934f,
+0, 0.192871f, 0, 0.00390625f, -0.52832f, 0.148926f, -0.52832f, 0.212891f, -0.124512f,
+0.314941f, -0.52832f, 0.461914f, -0.52832f, 0.562988f, -0.124512f, 0.652832f, -0.52832f,
+0.779785f, -0.52832f, 0.641113f, 0, 0.496094f, 0, 0.38916f, -0.430664f, 0.278809f,
+0, 0.133789f, 0, -0.00292969f, -0.52832f, 0.125977f, -0.52832f, 0.399902f, 0, 0.276855f,
+-0.191406f, 0.152832f, 0, 0.00683594f, 0, 0.200195f, -0.272949f, 0.0161133f, -0.52832f,
+0.164062f, -0.52832f, 0.276855f, -0.355469f, 0.38916f, -0.52832f, 0.538086f, -0.52832f,
+0.354004f, -0.274414f, 0.548828f, 0, 0.285156f, -0.117676f, 0.407227f, -0.52832f,
+0.550781f, -0.52832f, 0.341797f, 0.027832f, 0.302246f, 0.124023f, 0.259766f, 0.164062f,
+0.213379f, 0.20752f, 0.138184f, 0.20752f, 0.0888672f, 0.20752f, 0.0517578f, 0.201172f,
+0.0517578f, 0.103516f, 0.0776367f, 0.107422f, 0.0983887f, 0.107422f, 0.119141f, 0.107422f,
+0.134766f, 0.103027f, 0.150391f, 0.0986328f, 0.163086f, 0.0883789f, 0.187988f, 0.0678711f,
+0.208008f, 0.0180664f, 0.216797f, -0.00537109f, 0.0078125f, -0.52832f, 0.152832f,
+-0.52832f, 0.0332031f, 0, 0.0332031f, -0.097168f, 0.296875f, -0.429199f, 0.0532227f,
+-0.429199f, 0.0532227f, -0.52832f, 0.448242f, -0.52832f, 0.448242f, -0.430176f, 0.186035f,
+-0.100098f, 0.472168f, -0.100098f, 0.472168f, 0
+};
+
+const unsigned char LiberationSanskBoldVerbs[] = {
+6, 0, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 1,
+1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 1, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 0, 1, 1, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1,
+1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1,
+1, 5, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 0, 1, 1, 1, 5,
+6, 0, 1, 1, 1, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1,
+1, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 0, 2, 2, 1, 1, 1, 2, 2, 5, 0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2,
+5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 0, 2,
+2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 1, 5, 0, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 5,
+6, 0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0,
+1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1,
+5, 6, 0, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 1, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 5, 0,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 1, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2,
+2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1,
+5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2,
+2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 5,
+0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 5, 6, 0,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5,
+6, 0, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 5, 6
+};
+
+const unsigned LiberationSanskBoldCharCodes[] = {
+32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 47, 48, 49, 50, 51,
+53, 54, 55, 56, 57, 58, 59, 61, 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+76, 77, 79, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 93, 94, 95, 97, 98, 100, 101,
+102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 117, 118,
+119, 120, 121, 122
+};
+
+const SkFixed LiberationSanskBoldWidths[] = {
+0x00004720, 0x00005540, 0x00007960, 0x00008e60, 0x00008e60, 0x0000e3a0, 0x0000b8e0,
+0x00003ce0, 0x00005540, 0x00005540, 0x000063a0, 0x00009580, 0x00005540, 0x00004720,
+0x00004720, 0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60,
+0x00008e60, 0x00008e60, 0x00008e60, 0x00005540, 0x00005540, 0x00009580, 0x00009580,
+0x00009c60, 0x0000b8e0, 0x0000b8e0, 0x0000b8e0, 0x0000b8e0, 0x0000aac0, 0x00009c60,
+0x0000c720, 0x0000b8e0, 0x00004720, 0x00008e60, 0x00009c60, 0x0000d540, 0x0000c720,
+0x0000b8e0, 0x0000aac0, 0x00009c60, 0x0000b8e0, 0x0000aac0, 0x0000f1a0, 0x0000aac0,
+0x0000aac0, 0x00009c60, 0x00005540, 0x00005540, 0x00009580, 0x00008e60, 0x00008e60,
+0x00009c60, 0x00009c60, 0x00008e60, 0x00005540, 0x00009c60, 0x00009c60, 0x00004720,
+0x00004720, 0x00008e60, 0x00004720, 0x0000e3a0, 0x00009c60, 0x00009c60, 0x00009c60,
+0x00009c60, 0x000063a0, 0x00008e60, 0x00009c60, 0x00008e60, 0x0000c720, 0x00008e60,
+0x00008e60, 0x00008000
+};
+
+const int LiberationSanskBoldCharCodesCount = (int) SK_ARRAY_COUNT(LiberationSanskBoldCharCodes);
+
+const SkPaint::FontMetrics LiberationSanskBoldMetrics = {
+0x2c663933, -1.0332f, -0.905273f, 0.211914f, 0.303223f, 0.0327148f, 1.24609f, 4.07409e-11f,
+-0.184082f, 1.06201f, 0.538086f, 6.66449e-1f, 0.10498f, 0.105957f
+};
+
+const SkScalar LiberationSanskItalicPoints[] = {
+0.518066f, 0, 0.481445f, -0.201172f, 0.169434f, -0.201172f, 0.0522461f, 0, -0.0493164f,
+0, 0.364746f, -0.687988f, 0.470703f, -0.687988f, 0.613281f, 0, 0.425293f, -0.504883f,
+0.421387f, -0.524902f, 0.417725f, -0.543945f, 0.414062f, -0.562988f, 0.411621f, -0.578857f,
+0.40918f, -0.594727f, 0.407471f, -0.605225f, 0.405762f, -0.615723f, 0.405273f, -0.617676f,
+0.404297f, -0.615723f, 0.398682f, -0.60498f, 0.393066f, -0.594238f, 0.384277f, -0.578369f,
+0.375488f, -0.5625f, 0.364746f, -0.543213f, 0.354004f, -0.523926f, 0.342285f, -0.504395f,
+0.210449f, -0.273926f, 0.467773f, -0.273926f, 0.498535f, 0, 0.560547f, -0.318848f,
+0.186035f, -0.318848f, 0.124023f, 0, 0.0307617f, 0, 0.164551f, -0.687988f, 0.257812f,
+-0.687988f, 0.201172f, -0.396973f, 0.575684f, -0.396973f, 0.632324f, -0.687988f,
+0.723145f, -0.687988f, 0.589355f, 0, 0.418945f, -0.611816f, 0.299805f, 0, 0.207031f,
+0, 0.326172f, -0.611816f, 0.0898438f, -0.611816f, 0.104492f, -0.687988f, 0.669922f,
+-0.687988f, 0.655273f, -0.611816f, 0.686523f, 0, 0.577637f, 0, 0.542969f, -0.437012f,
+0.54248f, -0.446289f, 0.541748f, -0.458008f, 0.541016f, -0.469727f, 0.540283f, -0.482666f,
+0.539551f, -0.495605f, 0.538818f, -0.509033f, 0.538086f, -0.522461f, 0.537598f, -0.534668f,
+0.536133f, -0.563965f, 0.535156f, -0.595215f, 0.523438f, -0.564453f, 0.51123f, -0.534668f,
+0.500977f, -0.509277f, 0.489502f, -0.482422f, 0.478027f, -0.455566f, 0.469238f, -0.437012f,
+0.264648f, 0, 0.155762f, 0, 0.0864258f, -0.687988f, 0.182617f, -0.687988f, 0.221191f,
+-0.250977f, 0.223633f, -0.220215f, 0.225098f, -0.190186f, 0.226562f, -0.160156f,
+0.227539f, -0.135742f, 0.228516f, -0.107422f, 0.229004f, -0.0820312f, 0.243164f,
+-0.115723f, 0.257324f, -0.148438f, 0.263184f, -0.162598f, 0.269775f, -0.17749f, 0.276367f,
+-0.192383f, 0.282715f, -0.207031f, 0.289062f, -0.22168f, 0.295166f, -0.235107f, 0.30127f,
+-0.248535f, 0.306641f, -0.259766f, 0.509277f, -0.687988f, 0.598633f, -0.687988f,
+0.635254f, -0.259766f, 0.63623f, -0.249023f, 0.637207f, -0.235352f, 0.638184f, -0.22168f,
+0.638916f, -0.207275f, 0.639648f, -0.192871f, 0.640381f, -0.177979f, 0.641113f, -0.163086f,
+0.641602f, -0.148926f, 0.643066f, -0.116211f, 0.643555f, -0.0820312f, 0.644043f,
+-0.0820312f, 0.651123f, -0.098877f, 0.658203f, -0.115723f, 0.668945f, -0.141113f,
+0.679688f, -0.166504f, 0.692627f, -0.196045f, 0.705566f, -0.225586f, 0.717773f, -0.250977f,
+0.924316f, -0.687988f, 1.02246f, -0.687988f, 0.383301f, -0.285156f, 0.328125f, 0,
+0.235352f, 0, 0.291504f, -0.285156f, 0.104004f, -0.687988f, 0.199707f, -0.687988f,
+0.349121f, -0.358887f, 0.622559f, -0.687988f, 0.727051f, -0.687988f, 0.515137f, -0.00292969f,
+0.500977f, 0.000488281f, 0.484619f, 0.00268555f, 0.468262f, 0.00488281f, 0.452637f,
+0.00488281f, 0.407227f, 0.00488281f, 0.386475f, -0.013916f, 0.365723f, -0.0327148f,
+0.365723f, -0.0698242f, 0.365723f, -0.0771484f, 0.366699f, -0.0856934f, 0.367676f,
+-0.0942383f, 0.368164f, -0.101074f, 0.365234f, -0.101074f, 0.348145f, -0.0751953f,
+0.329834f, -0.0546875f, 0.311523f, -0.0341797f, 0.289307f, -0.0197754f, 0.26709f,
+-0.00537109f, 0.239746f, 0.00219727f, 0.212402f, 0.00976562f, 0.17627f, 0.00976562f,
+0.138184f, 0.00976562f, 0.109619f, -0.00244141f, 0.0810547f, -0.0146484f, 0.0615234f,
+-0.0349121f, 0.0419922f, -0.0551758f, 0.0322266f, -0.081543f, 0.0224609f, -0.10791f,
+0.0224609f, -0.135742f, 0.0224609f, -0.175293f, 0.0339355f, -0.204102f, 0.0454102f,
+-0.23291f, 0.0651855f, -0.253418f, 0.0849609f, -0.273926f, 0.111572f, -0.286865f,
+0.138184f, -0.299805f, 0.168213f, -0.307129f, 0.198242f, -0.314453f, 0.230469f, -0.317383f,
+0.262695f, -0.320312f, 0.293457f, -0.320801f, 0.406738f, -0.322266f, 0.410156f, -0.339844f,
+0.412598f, -0.352051f, 0.414307f, -0.363281f, 0.416016f, -0.374512f, 0.416016f, -0.384277f,
+0.416016f, -0.428711f, 0.390137f, -0.449951f, 0.364258f, -0.471191f, 0.318359f, -0.471191f,
+0.294434f, -0.471191f, 0.273682f, -0.467529f, 0.25293f, -0.463867f, 0.236572f, -0.454346f,
+0.220215f, -0.444824f, 0.207764f, -0.428467f, 0.195312f, -0.412109f, 0.1875f, -0.387207f,
+0.100586f, -0.401367f, 0.109863f, -0.431641f, 0.125977f, -0.456787f, 0.14209f, -0.481934f,
+0.168457f, -0.5f, 0.194824f, -0.518066f, 0.232666f, -0.528076f, 0.270508f, -0.538086f,
+0.323242f, -0.538086f, 0.366699f, -0.538086f, 0.400391f, -0.527344f, 0.434082f, -0.516602f,
+0.457031f, -0.497559f, 0.47998f, -0.478516f, 0.491943f, -0.452148f, 0.503906f, -0.425781f,
+0.503906f, -0.394043f, 0.503906f, -0.378906f, 0.501221f, -0.357666f, 0.498535f, -0.336426f,
+0.494629f, -0.317383f, 0.458496f, -0.132812f, 0.456055f, -0.12207f, 0.45459f, -0.11084f,
+0.453125f, -0.0996094f, 0.453125f, -0.0898438f, 0.453125f, -0.0717773f, 0.462646f,
+-0.0629883f, 0.472168f, -0.0541992f, 0.492676f, -0.0541992f, 0.5f, -0.0541992f, 0.507568f,
+-0.0551758f, 0.515137f, -0.0561523f, 0.521973f, -0.0576172f, 0.39502f, -0.261719f,
+0.297852f, -0.259766f, 0.27832f, -0.259277f, 0.257324f, -0.257812f, 0.236328f, -0.256348f,
+0.216064f, -0.251709f, 0.195801f, -0.24707f, 0.17749f, -0.239258f, 0.15918f, -0.231445f,
+0.145508f, -0.218018f, 0.131836f, -0.20459f, 0.123779f, -0.185547f, 0.115723f, -0.166504f,
+0.115723f, -0.139648f, 0.115723f, -0.124023f, 0.12085f, -0.109131f, 0.125977f, -0.0942383f,
+0.136719f, -0.0827637f, 0.147461f, -0.0712891f, 0.16333f, -0.064209f, 0.179199f,
+-0.0571289f, 0.200684f, -0.0571289f, 0.243164f, -0.0571289f, 0.274902f, -0.0717773f,
+0.306641f, -0.0864258f, 0.329102f, -0.10791f, 0.351562f, -0.129395f, 0.364502f, -0.154541f,
+0.377441f, -0.179688f, 0.381836f, -0.200684f, 0.363281f, -0.538086f, 0.402344f, -0.538086f,
+0.432617f, -0.525879f, 0.462891f, -0.513672f, 0.483398f, -0.491211f, 0.503906f, -0.46875f,
+0.514648f, -0.436768f, 0.525391f, -0.404785f, 0.525391f, -0.365234f, 0.525391f, -0.34082f,
+0.523193f, -0.311768f, 0.520996f, -0.282715f, 0.515137f, -0.251953f, 0.501953f, -0.182617f,
+0.480469f, -0.133057f, 0.458984f, -0.0834961f, 0.428711f, -0.0517578f, 0.398438f,
+-0.0200195f, 0.359375f, -0.00512695f, 0.320312f, 0.00976562f, 0.271973f, 0.00976562f,
+0.211914f, 0.00976562f, 0.174316f, -0.015625f, 0.136719f, -0.0410156f, 0.121094f,
+-0.0869141f, 0.119629f, -0.0869141f, 0.117188f, -0.0742188f, 0.11377f, -0.0598145f,
+0.110352f, -0.0454102f, 0.107178f, -0.0327148f, 0.104004f, -0.0200195f, 0.101807f,
+-0.0109863f, 0.0996094f, -0.00195312f, 0.0986328f, 0, 0.0141602f, 0, 0.015625f, -0.00439453f,
+0.0180664f, -0.0148926f, 0.0205078f, -0.0253906f, 0.0236816f, -0.0400391f, 0.0268555f,
+-0.0546875f, 0.0307617f, -0.0722656f, 0.034668f, -0.0898438f, 0.0380859f, -0.108887f,
+0.157715f, -0.724609f, 0.245605f, -0.724609f, 0.205078f, -0.518066f, 0.202637f, -0.503906f,
+0.199463f, -0.491211f, 0.196289f, -0.478516f, 0.193848f, -0.469238f, 0.190918f, -0.458496f,
+0.188477f, -0.449707f, 0.19043f, -0.449707f, 0.208008f, -0.472656f, 0.226318f, -0.489258f,
+0.244629f, -0.505859f, 0.265381f, -0.516846f, 0.286133f, -0.527832f, 0.310059f, -0.532959f,
+0.333984f, -0.538086f, 0.363281f, -0.538086f, 0.337891f, -0.470215f, 0.306641f, -0.470215f,
+0.278564f, -0.460938f, 0.250488f, -0.45166f, 0.226562f, -0.428955f, 0.202637f, -0.40625f,
+0.184326f, -0.367676f, 0.166016f, -0.329102f, 0.154785f, -0.270508f, 0.145508f, -0.222656f,
+0.145508f, -0.184082f, 0.145508f, -0.152832f, 0.153809f, -0.128662f, 0.162109f, -0.104492f,
+0.17749f, -0.0881348f, 0.192871f, -0.0717773f, 0.2146f, -0.0634766f, 0.236328f, -0.0551758f,
+0.262695f, -0.0551758f, 0.292969f, -0.0551758f, 0.317383f, -0.064209f, 0.341797f,
+-0.0732422f, 0.361572f, -0.095459f, 0.381348f, -0.117676f, 0.396484f, -0.155029f,
+0.411621f, -0.192383f, 0.422363f, -0.249023f, 0.433594f, -0.308105f, 0.433594f, -0.349609f,
+0.433594f, -0.409668f, 0.410645f, -0.439941f, 0.387695f, -0.470215f, 0.337891f, -0.470215f,
+0.125f, -0.245605f, 0.122559f, -0.231934f, 0.121826f, -0.218018f, 0.121094f, -0.204102f,
+0.120605f, -0.19043f, 0.120605f, -0.125488f, 0.153076f, -0.0908203f, 0.185547f, -0.0561523f,
+0.250977f, -0.0561523f, 0.27832f, -0.0561523f, 0.300781f, -0.0632324f, 0.323242f,
+-0.0703125f, 0.341553f, -0.0822754f, 0.359863f, -0.0942383f, 0.373779f, -0.110107f,
+0.387695f, -0.125977f, 0.396973f, -0.143555f, 0.464355f, -0.112793f, 0.452148f, -0.0908203f,
+0.43457f, -0.0690918f, 0.416992f, -0.0473633f, 0.390869f, -0.0297852f, 0.364746f,
+-0.012207f, 0.328125f, -0.0012207f, 0.291504f, 0.00976562f, 0.240723f, 0.00976562f,
+0.191895f, 0.00976562f, 0.15332f, -0.00415039f, 0.114746f, -0.0180664f, 0.0881348f,
+-0.0446777f, 0.0615234f, -0.0712891f, 0.0476074f, -0.109863f, 0.0336914f, -0.148438f,
+0.0336914f, -0.197754f, 0.0336914f, -0.274902f, 0.0544434f, -0.337891f, 0.0751953f,
+-0.400879f, 0.112061f, -0.445312f, 0.148926f, -0.489746f, 0.198975f, -0.513916f,
+0.249023f, -0.538086f, 0.307617f, -0.538086f, 0.361328f, -0.538086f, 0.400879f, -0.523926f,
+0.44043f, -0.509766f, 0.466797f, -0.484375f, 0.493164f, -0.458984f, 0.506104f, -0.423584f,
+0.519043f, -0.388184f, 0.519043f, -0.345703f, 0.519043f, -0.335449f, 0.518311f, -0.323242f,
+0.517578f, -0.311035f, 0.516113f, -0.297852f, 0.514648f, -0.284668f, 0.512451f, -0.27124f,
+0.510254f, -0.257812f, 0.507324f, -0.245605f, 0.429688f, -0.312988f, 0.430664f, -0.322754f,
+0.431152f, -0.331299f, 0.431641f, -0.339844f, 0.431641f, -0.348145f, 0.431641f, -0.380371f,
+0.422852f, -0.404053f, 0.414062f, -0.427734f, 0.397949f, -0.443115f, 0.381836f, -0.458496f,
+0.359375f, -0.46582f, 0.336914f, -0.473145f, 0.30957f, -0.473145f, 0.286133f, -0.473145f,
+0.260254f, -0.466064f, 0.234375f, -0.458984f, 0.210693f, -0.440918f, 0.187012f, -0.422852f,
+0.16748f, -0.391846f, 0.147949f, -0.36084f, 0.136719f, -0.312988f, 0.211914f, -0.464355f,
+0.121582f, 0, 0.0336914f, 0, 0.124023f, -0.464355f, 0.0498047f, -0.464355f, 0.0625f,
+-0.52832f, 0.136719f, -0.52832f, 0.147949f, -0.587891f, 0.153809f, -0.616699f, 0.163086f,
+-0.641602f, 0.172363f, -0.666504f, 0.189697f, -0.685059f, 0.207031f, -0.703613f,
+0.234375f, -0.714111f, 0.261719f, -0.724609f, 0.303711f, -0.724609f, 0.319336f, -0.724609f,
+0.335693f, -0.723145f, 0.352051f, -0.72168f, 0.364258f, -0.71875f, 0.351562f, -0.651855f,
+0.347168f, -0.652832f, 0.341553f, -0.65332f, 0.335938f, -0.653809f, 0.32959f, -0.654541f,
+0.323242f, -0.655273f, 0.317383f, -0.655518f, 0.311523f, -0.655762f, 0.307129f, -0.655762f,
+0.288574f, -0.655762f, 0.276123f, -0.650391f, 0.263672f, -0.64502f, 0.255615f, -0.634766f,
+0.247559f, -0.624512f, 0.242676f, -0.609619f, 0.237793f, -0.594727f, 0.233887f, -0.575684f,
+0.224609f, -0.52832f, 0.327637f, -0.52832f, 0.314941f, -0.464355f, 0.193848f, 0.20752f,
+0.148438f, 0.20752f, 0.114746f, 0.198486f, 0.0810547f, 0.189453f, 0.0578613f, 0.17334f,
+0.034668f, 0.157227f, 0.0212402f, 0.134521f, 0.0078125f, 0.111816f, 0.00195312f,
+0.0844727f, 0.081543f, 0.0639648f, 0.0898438f, 0.101074f, 0.118408f, 0.12085f, 0.146973f,
+0.140625f, 0.195801f, 0.140625f, 0.230957f, 0.140625f, 0.257812f, 0.131592f, 0.284668f,
+0.122559f, 0.303955f, 0.104004f, 0.323242f, 0.0854492f, 0.336182f, 0.0563965f, 0.349121f,
+0.0273438f, 0.356934f, -0.0131836f, 0.359375f, -0.0258789f, 0.362305f, -0.0405273f,
+0.365234f, -0.0551758f, 0.367676f, -0.0678711f, 0.370605f, -0.0830078f, 0.373535f,
+-0.0981445f, 0.372559f, -0.0981445f, 0.358887f, -0.0786133f, 0.343506f, -0.0600586f,
+0.328125f, -0.0415039f, 0.308105f, -0.0273438f, 0.288086f, -0.0131836f, 0.261719f,
+-0.00463867f, 0.235352f, 0.00390625f, 0.200195f, 0.00390625f, 0.161621f, 0.00390625f,
+0.130859f, -0.00952148f, 0.100098f, -0.0229492f, 0.0786133f, -0.0466309f, 0.0571289f,
+-0.0703125f, 0.0456543f, -0.103271f, 0.0341797f, -0.13623f, 0.0341797f, -0.175293f,
+0.0341797f, -0.199219f, 0.0368652f, -0.22583f, 0.0395508f, -0.252441f, 0.0454102f,
+-0.283203f, 0.0698242f, -0.410645f, 0.128174f, -0.474121f, 0.186523f, -0.537598f,
+0.287109f, -0.537598f, 0.314941f, -0.537598f, 0.339844f, -0.531006f, 0.364746f, -0.524414f,
+0.384521f, -0.511475f, 0.404297f, -0.498535f, 0.418701f, -0.47998f, 0.433105f, -0.461426f,
+0.439453f, -0.437988f, 0.44043f, -0.437988f, 0.442871f, -0.450195f, 0.446533f, -0.465332f,
+0.450195f, -0.480469f, 0.453613f, -0.493896f, 0.457031f, -0.507324f, 0.459961f, -0.51709f,
+0.462891f, -0.526855f, 0.463867f, -0.52832f, 0.547363f, -0.52832f, 0.546387f, -0.523926f,
+0.543945f, -0.513428f, 0.541504f, -0.50293f, 0.538086f, -0.488281f, 0.534668f, -0.473633f,
+0.531006f, -0.455811f, 0.527344f, -0.437988f, 0.523438f, -0.418945f, 0.444824f, -0.0151367f,
+0.43457f, 0.0371094f, 0.416504f, 0.0783691f, 0.398438f, 0.119629f, 0.368652f, 0.148438f,
+0.338867f, 0.177246f, 0.296143f, 0.192383f, 0.253418f, 0.20752f, 0.193848f, 0.20752f,
+0.126465f, -0.182129f, 0.126465f, -0.123047f, 0.1521f, -0.092041f, 0.177734f, -0.0610352f,
+0.227539f, -0.0610352f, 0.253906f, -0.0610352f, 0.281006f, -0.0722656f, 0.308105f,
+-0.0834961f, 0.332275f, -0.10791f, 0.356445f, -0.132324f, 0.375732f, -0.170898f,
+0.39502f, -0.209473f, 0.405762f, -0.26416f, 0.409668f, -0.284668f, 0.411621f, -0.306396f,
+0.413574f, -0.328125f, 0.413574f, -0.34375f, 0.413574f, -0.376465f, 0.404785f, -0.400635f,
+0.395996f, -0.424805f, 0.380127f, -0.440918f, 0.364258f, -0.457031f, 0.342773f, -0.464844f,
+0.321289f, -0.472656f, 0.296387f, -0.472656f, 0.266113f, -0.472656f, 0.241455f, -0.463623f,
+0.216797f, -0.45459f, 0.197266f, -0.432861f, 0.177734f, -0.411133f, 0.163086f, -0.374756f,
+0.148438f, -0.338379f, 0.137695f, -0.283203f, 0.132324f, -0.254395f, 0.129395f, -0.228027f,
+0.126465f, -0.20166f, 0.126465f, -0.182129f, 0.322266f, 0, 0.382812f, -0.30957f,
+0.384766f, -0.319336f, 0.386963f, -0.331055f, 0.38916f, -0.342773f, 0.390869f, -0.354492f,
+0.392578f, -0.366211f, 0.393799f, -0.376709f, 0.39502f, -0.387207f, 0.39502f, -0.394531f,
+0.39502f, -0.431152f, 0.376465f, -0.450439f, 0.35791f, -0.469727f, 0.315918f, -0.469727f,
+0.288086f, -0.469727f, 0.262939f, -0.457275f, 0.237793f, -0.444824f, 0.217773f, -0.422119f,
+0.197754f, -0.399414f, 0.183105f, -0.366943f, 0.168457f, -0.334473f, 0.161621f, -0.294922f,
+0.104004f, 0, 0.0166016f, 0, 0.0976562f, -0.415527f, 0.101074f, -0.432129f, 0.104248f,
+-0.450439f, 0.107422f, -0.46875f, 0.110107f, -0.485107f, 0.112793f, -0.501465f, 0.114502f,
+-0.513184f, 0.116211f, -0.524902f, 0.116699f, -0.52832f, 0.199707f, -0.52832f, 0.199707f,
+-0.525879f, 0.198242f, -0.515137f, 0.196777f, -0.504395f, 0.19458f, -0.490479f, 0.192383f,
+-0.476562f, 0.190186f, -0.462158f, 0.187988f, -0.447754f, 0.186035f, -0.437988f,
+0.1875f, -0.437988f, 0.202148f, -0.460938f, 0.217773f, -0.479492f, 0.233398f, -0.498047f,
+0.251953f, -0.510986f, 0.270508f, -0.523926f, 0.293213f, -0.530762f, 0.315918f, -0.537598f,
+0.344727f, -0.537598f, 0.403809f, -0.537598f, 0.438477f, -0.508545f, 0.473145f, -0.479492f,
+0.47998f, -0.424316f, 0.495605f, -0.44873f, 0.512207f, -0.469238f, 0.528809f, -0.489746f,
+0.549072f, -0.505127f, 0.569336f, -0.520508f, 0.593994f, -0.529053f, 0.618652f, -0.537598f,
+0.649902f, -0.537598f, 0.71582f, -0.537598f, 0.751221f, -0.501953f, 0.786621f, -0.466309f,
+0.786621f, -0.398926f, 0.786621f, -0.381348f, 0.783447f, -0.359375f, 0.780273f, -0.337402f,
+0.776367f, -0.318848f, 0.714355f, 0, 0.627441f, 0, 0.687988f, -0.30957f, 0.689941f,
+-0.319336f, 0.692139f, -0.331055f, 0.694336f, -0.342773f, 0.696045f, -0.354492f,
+0.697754f, -0.366211f, 0.698975f, -0.376709f, 0.700195f, -0.387207f, 0.700195f, -0.394531f,
+0.700195f, -0.431152f, 0.681641f, -0.450439f, 0.663086f, -0.469727f, 0.621094f, -0.469727f,
+0.593262f, -0.469727f, 0.568115f, -0.45752f, 0.542969f, -0.445312f, 0.522949f, -0.422852f,
+0.50293f, -0.400391f, 0.488281f, -0.368164f, 0.473633f, -0.335938f, 0.466797f, -0.296387f,
+0.40918f, 0, 0.350098f, 0, 0.411621f, -0.314941f, 0.415527f, -0.333984f, 0.417969f,
+-0.35376f, 0.42041f, -0.373535f, 0.42041f, -0.388184f, 0.42041f, -0.426758f, 0.399902f,
+-0.448242f, 0.379395f, -0.469727f, 0.333008f, -0.469727f, 0.301758f, -0.469727f,
+0.27417f, -0.457275f, 0.246582f, -0.444824f, 0.224121f, -0.422119f, 0.20166f, -0.399414f,
+0.185791f, -0.367432f, 0.169922f, -0.335449f, 0.162109f, -0.295898f, 0.104492f, 0,
+0.0166016f, 0, 0.0976562f, -0.415527f, 0.101074f, -0.432129f, 0.104248f, -0.450439f,
+0.107422f, -0.46875f, 0.110107f, -0.485107f, 0.112793f, -0.501465f, 0.114502f, -0.513184f,
+0.116211f, -0.524902f, 0.116699f, -0.52832f, 0.199707f, -0.52832f, 0.199707f, -0.525879f,
+0.198242f, -0.515137f, 0.196777f, -0.504395f, 0.19458f, -0.490479f, 0.192383f, -0.476562f,
+0.190186f, -0.462158f, 0.187988f, -0.447754f, 0.186035f, -0.437988f, 0.1875f, -0.437988f,
+0.204102f, -0.460938f, 0.22168f, -0.479492f, 0.239258f, -0.498047f, 0.260498f, -0.510986f,
+0.281738f, -0.523926f, 0.307373f, -0.530762f, 0.333008f, -0.537598f, 0.365723f, -0.537598f,
+0.437988f, -0.537598f, 0.474365f, -0.501953f, 0.510742f, -0.466309f, 0.510742f, -0.398926f,
+0.510742f, -0.381348f, 0.507568f, -0.359375f, 0.504395f, -0.337402f, 0.500488f, -0.318848f,
+0.438477f, 0, 0.524414f, -0.333496f, 0.524414f, -0.308105f, 0.521484f, -0.282471f,
+0.518555f, -0.256836f, 0.511719f, -0.228027f, 0.49707f, -0.163574f, 0.470947f, -0.118164f,
+0.444824f, -0.0727539f, 0.409668f, -0.0444336f, 0.374512f, -0.0161133f, 0.331543f,
+-0.00317383f, 0.288574f, 0.00976562f, 0.239746f, 0.00976562f, 0.192871f, 0.00976562f,
+0.154785f, -0.00463867f, 0.116699f, -0.019043f, 0.0895996f, -0.0466309f, 0.0625f,
+-0.0742188f, 0.0476074f, -0.114014f, 0.0327148f, -0.153809f, 0.0327148f, -0.20459f,
+0.0332031f, -0.227539f, 0.0354004f, -0.251953f, 0.0375977f, -0.276367f, 0.043457f,
+-0.302734f, 0.0576172f, -0.364258f, 0.0825195f, -0.408447f, 0.107422f, -0.452637f,
+0.141602f, -0.481445f, 0.175781f, -0.510254f, 0.218994f, -0.523926f, 0.262207f, -0.537598f,
+0.313477f, -0.537598f, 0.365234f, -0.537598f, 0.404541f, -0.523926f, 0.443848f, -0.510254f,
+0.470459f, -0.483887f, 0.49707f, -0.45752f, 0.510742f, -0.419678f, 0.524414f, -0.381836f,
+0.524414f, -0.333496f, 0.433594f, -0.333496f, 0.433594f, -0.371094f, 0.425293f, -0.397461f,
+0.416992f, -0.423828f, 0.401123f, -0.440674f, 0.385254f, -0.45752f, 0.362793f, -0.465332f,
+0.340332f, -0.473145f, 0.3125f, -0.473145f, 0.286621f, -0.473145f, 0.260498f, -0.467041f,
+0.234375f, -0.460938f, 0.210693f, -0.442383f, 0.187012f, -0.423828f, 0.16748f, -0.389648f,
+0.147949f, -0.355469f, 0.134766f, -0.298828f, 0.128418f, -0.271973f, 0.125732f, -0.247803f,
+0.123047f, -0.223633f, 0.123047f, -0.203125f, 0.123047f, -0.163086f, 0.132324f, -0.134766f,
+0.141602f, -0.106445f, 0.157959f, -0.0888672f, 0.174316f, -0.0712891f, 0.196533f,
+-0.0632324f, 0.21875f, -0.0551758f, 0.245117f, -0.0551758f, 0.271484f, -0.0551758f,
+0.297119f, -0.0610352f, 0.322754f, -0.0668945f, 0.345703f, -0.0856934f, 0.368652f,
+-0.104492f, 0.387939f, -0.13916f, 0.407227f, -0.173828f, 0.42041f, -0.230957f, 0.427246f,
+-0.260254f, 0.429932f, -0.284668f, 0.432617f, -0.309082f, 0.433594f, -0.333496f,
+0.270508f, 0.00976562f, 0.210449f, 0.00976562f, 0.172607f, -0.015625f, 0.134766f,
+-0.0410156f, 0.119141f, -0.0869141f, 0.116699f, -0.0869141f, 0.116699f, -0.0859375f,
+0.115723f, -0.0773926f, 0.114746f, -0.0688477f, 0.112793f, -0.0561523f, 0.11084f,
+-0.043457f, 0.108154f, -0.0283203f, 0.105469f, -0.0131836f, 0.102539f, 0.000976562f,
+0.0625f, 0.20752f, -0.0249023f, 0.20752f, 0.0966797f, -0.42041f, 0.100586f, -0.439453f,
+0.103516f, -0.457031f, 0.106445f, -0.474609f, 0.108643f, -0.489014f, 0.11084f, -0.503418f,
+0.112061f, -0.513672f, 0.113281f, -0.523926f, 0.11377f, -0.52832f, 0.195312f, -0.52832f,
+0.195312f, -0.524414f, 0.194824f, -0.515625f, 0.194336f, -0.506836f, 0.193115f, -0.49585f,
+0.191895f, -0.484863f, 0.19043f, -0.472656f, 0.188965f, -0.460449f, 0.187012f, -0.449707f,
+0.188965f, -0.449707f, 0.206543f, -0.472656f, 0.224854f, -0.489258f, 0.243164f, -0.505859f,
+0.263916f, -0.516846f, 0.284668f, -0.527832f, 0.308594f, -0.532959f, 0.33252f, -0.538086f,
+0.361816f, -0.538086f, 0.400879f, -0.538086f, 0.431152f, -0.525879f, 0.461426f, -0.513672f,
+0.481934f, -0.491211f, 0.502441f, -0.46875f, 0.513184f, -0.436768f, 0.523926f, -0.404785f,
+0.523926f, -0.365234f, 0.523926f, -0.34082f, 0.521729f, -0.311768f, 0.519531f, -0.282715f,
+0.513672f, -0.251953f, 0.500488f, -0.182617f, 0.479004f, -0.133057f, 0.45752f, -0.0834961f,
+0.427246f, -0.0517578f, 0.396973f, -0.0200195f, 0.35791f, -0.00512695f, 0.318848f,
+0.00976562f, 0.270508f, 0.00976562f, 0.336426f, -0.470215f, 0.305176f, -0.470215f,
+0.2771f, -0.460938f, 0.249023f, -0.45166f, 0.225098f, -0.428955f, 0.201172f, -0.40625f,
+0.182861f, -0.367676f, 0.164551f, -0.329102f, 0.15332f, -0.270508f, 0.144043f, -0.222656f,
+0.144043f, -0.184082f, 0.144043f, -0.152832f, 0.152344f, -0.128662f, 0.160645f, -0.104492f,
+0.176025f, -0.0881348f, 0.191406f, -0.0717773f, 0.213135f, -0.0634766f, 0.234863f,
+-0.0551758f, 0.26123f, -0.0551758f, 0.291504f, -0.0551758f, 0.315918f, -0.064209f,
+0.340332f, -0.0732422f, 0.360107f, -0.095459f, 0.379883f, -0.117676f, 0.39502f, -0.155029f,
+0.410156f, -0.192383f, 0.420898f, -0.249023f, 0.432129f, -0.308105f, 0.432129f, -0.349609f,
+0.432129f, -0.409668f, 0.40918f, -0.439941f, 0.38623f, -0.470215f, 0.336426f, -0.470215f,
+0.350586f, -0.458008f, 0.342285f, -0.460449f, 0.330811f, -0.462402f, 0.319336f, -0.464355f,
+0.306641f, -0.464355f, 0.275391f, -0.464355f, 0.250488f, -0.446289f, 0.225586f, -0.428223f,
+0.206787f, -0.400391f, 0.187988f, -0.372559f, 0.175781f, -0.339111f, 0.163574f, -0.305664f,
+0.158203f, -0.275391f, 0.104492f, 0, 0.0166016f, 0, 0.0957031f, -0.405273f, 0.0991211f,
+-0.422363f, 0.102051f, -0.439453f, 0.10498f, -0.456543f, 0.107666f, -0.472656f, 0.110352f,
+-0.48877f, 0.112793f, -0.503174f, 0.115234f, -0.517578f, 0.116699f, -0.52832f, 0.199707f,
+-0.52832f, 0.198242f, -0.517578f, 0.196045f, -0.50293f, 0.193848f, -0.488281f, 0.191406f,
+-0.473145f, 0.188965f, -0.458008f, 0.186768f, -0.444092f, 0.18457f, -0.430176f, 0.182617f,
+-0.42041f, 0.18457f, -0.42041f, 0.199707f, -0.450684f, 0.2146f, -0.4729f, 0.229492f,
+-0.495117f, 0.245605f, -0.509521f, 0.261719f, -0.523926f, 0.280029f, -0.531006f,
+0.29834f, -0.538086f, 0.320312f, -0.538086f, 0.325684f, -0.538086f, 0.332031f, -0.537354f,
+0.338379f, -0.536621f, 0.344971f, -0.535645f, 0.351562f, -0.534668f, 0.357422f, -0.533447f,
+0.363281f, -0.532227f, 0.366699f, -0.53125f, 0.442871f, -0.154785f, 0.442871f, -0.113281f,
+0.42627f, -0.0822754f, 0.409668f, -0.0512695f, 0.37915f, -0.0307617f, 0.348633f,
+-0.0102539f, 0.305176f, -0.000244141f, 0.261719f, 0.00976562f, 0.20752f, 0.00976562f,
+0.162109f, 0.00976562f, 0.12793f, 0.00195312f, 0.09375f, -0.00585938f, 0.0690918f,
+-0.020752f, 0.0444336f, -0.0356445f, 0.0280762f, -0.0578613f, 0.0117188f, -0.0800781f,
+0.00244141f, -0.108887f, 0.0742188f, -0.13623f, 0.081543f, -0.116699f, 0.0930176f,
+-0.101318f, 0.104492f, -0.0859375f, 0.121338f, -0.0754395f, 0.138184f, -0.0649414f,
+0.161377f, -0.0595703f, 0.18457f, -0.0541992f, 0.215332f, -0.0541992f, 0.246582f,
+-0.0541992f, 0.272705f, -0.0593262f, 0.298828f, -0.0644531f, 0.317627f, -0.0756836f,
+0.336426f, -0.0869141f, 0.346924f, -0.104492f, 0.357422f, -0.12207f, 0.357422f, -0.146973f,
+0.357422f, -0.166504f, 0.348145f, -0.18042f, 0.338867f, -0.194336f, 0.322021f, -0.204834f,
+0.305176f, -0.215332f, 0.281006f, -0.224365f, 0.256836f, -0.233398f, 0.227051f, -0.242676f,
+0.195312f, -0.25293f, 0.166748f, -0.265137f, 0.138184f, -0.277344f, 0.116455f, -0.294434f,
+0.0947266f, -0.311523f, 0.0817871f, -0.334717f, 0.0688477f, -0.35791f, 0.0688477f,
+-0.38916f, 0.0688477f, -0.429199f, 0.0861816f, -0.457275f, 0.103516f, -0.485352f,
+0.133057f, -0.50293f, 0.162598f, -0.520508f, 0.201904f, -0.528564f, 0.241211f, -0.536621f,
+0.285156f, -0.536621f, 0.325195f, -0.536621f, 0.358398f, -0.529785f, 0.391602f, -0.522949f,
+0.416504f, -0.508057f, 0.441406f, -0.493164f, 0.45752f, -0.469482f, 0.473633f, -0.445801f,
+0.479492f, -0.412109f, 0.399902f, -0.399902f, 0.38916f, -0.438477f, 0.359375f, -0.455566f,
+0.32959f, -0.472656f, 0.279297f, -0.472656f, 0.253418f, -0.472656f, 0.230713f, -0.46875f,
+0.208008f, -0.464844f, 0.190918f, -0.456055f, 0.173828f, -0.447266f, 0.163818f, -0.433105f,
+0.153809f, -0.418945f, 0.153809f, -0.398926f, 0.153809f, -0.378906f, 0.163086f, -0.365479f,
+0.172363f, -0.352051f, 0.189209f, -0.341797f, 0.206055f, -0.331543f, 0.229736f, -0.323486f,
+0.253418f, -0.31543f, 0.282715f, -0.306152f, 0.310547f, -0.297363f, 0.339111f, -0.285645f,
+0.367676f, -0.273926f, 0.390625f, -0.256592f, 0.413574f, -0.239258f, 0.428223f, -0.2146f,
+0.442871f, -0.189941f, 0.442871f, -0.154785f, 0.202637f, -0.52832f, 0.141113f, -0.213379f,
+0.137207f, -0.194336f, 0.134766f, -0.174561f, 0.132324f, -0.154785f, 0.132324f, -0.140137f,
+0.132324f, -0.101562f, 0.152832f, -0.0800781f, 0.17334f, -0.0585938f, 0.219727f,
+-0.0585938f, 0.250977f, -0.0585938f, 0.278564f, -0.0710449f, 0.306152f, -0.0834961f,
+0.328613f, -0.106201f, 0.351074f, -0.128906f, 0.366943f, -0.160889f, 0.382812f, -0.192871f,
+0.390625f, -0.232422f, 0.448242f, -0.52832f, 0.536133f, -0.52832f, 0.455078f, -0.112793f,
+0.45166f, -0.0961914f, 0.448486f, -0.0778809f, 0.445312f, -0.0595703f, 0.442627f,
+-0.0432129f, 0.439941f, -0.0268555f, 0.438232f, -0.0151367f, 0.436523f, -0.00341797f,
+0.436035f, 0, 0.353027f, 0, 0.353027f, -0.00244141f, 0.354492f, -0.0131836f, 0.355957f,
+-0.0239258f, 0.358154f, -0.0378418f, 0.360352f, -0.0517578f, 0.362549f, -0.0661621f,
+0.364746f, -0.0805664f, 0.366699f, -0.090332f, 0.365234f, -0.090332f, 0.348633f,
+-0.0673828f, 0.331055f, -0.0488281f, 0.313477f, -0.0302734f, 0.292236f, -0.017334f,
+0.270996f, -0.00439453f, 0.245361f, 0.00244141f, 0.219727f, 0.00927734f, 0.187012f,
+0.00927734f, 0.114746f, 0.00927734f, 0.0783691f, -0.0263672f, 0.0419922f, -0.0620117f,
+0.0419922f, -0.129395f, 0.0419922f, -0.146973f, 0.045166f, -0.168945f, 0.0483398f,
+-0.190918f, 0.0522461f, -0.209473f, 0.114258f, -0.52832f, 0.244629f, 0, 0.217773f,
+0.0463867f, 0.192871f, 0.0844727f, 0.167969f, 0.122559f, 0.140625f, 0.149902f, 0.113281f,
+0.177246f, 0.0812988f, 0.192383f, 0.0493164f, 0.20752f, 0.0078125f, 0.20752f, -0.00830078f,
+0.20752f, -0.0251465f, 0.205811f, -0.0419922f, 0.204102f, -0.0566406f, 0.200684f,
+-0.0415039f, 0.135254f, -0.0332031f, 0.136719f, -0.0227051f, 0.137939f, -0.012207f,
+0.13916f, -0.00390625f, 0.13916f, 0.0424805f, 0.13916f, 0.0778809f, 0.10791f, 0.113281f,
+0.0766602f, 0.147461f, 0.0170898f, 0.160645f, -0.00585938f, 0.0546875f, -0.52832f,
+0.144043f, -0.52832f, 0.19873f, -0.236328f, 0.20166f, -0.220703f, 0.205078f, -0.200195f,
+0.208496f, -0.179688f, 0.211426f, -0.159424f, 0.214355f, -0.13916f, 0.216553f, -0.121826f,
+0.21875f, -0.104492f, 0.219238f, -0.0957031f, 0.224121f, -0.106445f, 0.231934f, -0.121826f,
+0.239746f, -0.137207f, 0.249268f, -0.154541f, 0.258789f, -0.171875f, 0.268799f, -0.190186f,
+0.278809f, -0.208496f, 0.288086f, -0.225586f, 0.453125f, -0.52832f, 0.550293f, -0.52832f
+};
+
+const unsigned char LiberationSanskItalicVerbs[] = {
+6, 0, 1, 1, 1, 1, 1, 1, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1,
+1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6
+};
+
+const unsigned LiberationSanskItalicCharCodes[] = {
+32, 65, 72, 84, 87, 89, 97,
+98, 101, 102, 103, 109, 110, 111, 112, 114, 115, 117, 121
+};
+
+const SkFixed LiberationSanskItalicWidths[] = {
+0x00004720, 0x0000aac0, 0x0000b8e0, 0x00009c60, 0x0000f1a0, 0x0000aac0, 0x00008e60,
+0x00008e60, 0x00008e60, 0x00004720, 0x00008e60, 0x0000d540, 0x00008e60, 0x00008e60,
+0x00008e60, 0x00005540, 0x00008000, 0x00008e60, 0x00008000
+};
+
+const int LiberationSanskItalicCharCodesCount = (int) SK_ARRAY_COUNT(LiberationSanskItalicCharCodes);
+
+const SkPaint::FontMetrics LiberationSanskItalicMetrics = {
+0x00000003, -1.01416f, -0.905273f, 0.211914f, 0.303223f, 0.0327148f, 1.33447f, 0,
+-0.271973f, 1.0625f, 0.537598f, 0, 0.0732422f, 0.105957f
+};
+
+const SkScalar LiberationSanskBoldItalicPoints[] = {
+0.206543f, -0.208008f, 0.0942383f, -0.208008f, 0.172363f, -0.687988f, 0.315918f, -0.687988f,
+0.0385742f, 0, 0.0639648f, -0.131836f, 0.20459f, -0.131836f, 0.179199f, 0, 0.169434f,
+-0.0322266f, 0.163086f, 0.000488281f, 0.154297f, 0.0273438f, 0.145508f, 0.0541992f,
+0.134277f, 0.0769043f, 0.123047f, 0.0996094f, 0.109619f, 0.118652f, 0.0961914f, 0.137695f,
+0.0805664f, 0.154785f, -0.00976562f, 0.154785f, 0.00732422f, 0.137695f, 0.0229492f,
+0.118652f, 0.0385742f, 0.0996094f, 0.0512695f, 0.0795898f, 0.0639648f, 0.0595703f,
+0.0727539f, 0.0395508f, 0.081543f, 0.0195312f, 0.0854492f, 0, 0.0224609f, 0, 0.0512695f,
+-0.148926f, 0.192383f, -0.148926f, 0.0273438f, -0.199707f, 0.050293f, -0.318848f,
+0.304199f, -0.318848f, 0.28125f, -0.199707f, 0.0224609f, 0, 0.0512695f, -0.148926f,
+0.192383f, -0.148926f, 0.163574f, 0, -0.0371094f, 0.0200195f, 0.249512f, -0.724609f,
+0.365723f, -0.724609f, 0.0810547f, 0.0200195f, 0.353516f, -0.698242f, 0.394043f,
+-0.698242f, 0.429199f, -0.687256f, 0.464355f, -0.67627f, 0.490234f, -0.649902f, 0.516113f,
+-0.623535f, 0.53125f, -0.579834f, 0.546387f, -0.536133f, 0.546387f, -0.470703f, 0.546387f,
+-0.439941f, 0.541748f, -0.404785f, 0.537109f, -0.369629f, 0.527832f, -0.324707f,
+0.51416f, -0.259766f, 0.495605f, -0.209473f, 0.477051f, -0.15918f, 0.454346f, -0.12207f,
+0.431641f, -0.0849609f, 0.405762f, -0.0598145f, 0.379883f, -0.034668f, 0.351562f,
+-0.019043f, 0.323242f, -0.00341797f, 0.293457f, 0.00317383f, 0.263672f, 0.00976562f,
+0.233398f, 0.00976562f, 0.1875f, 0.00976562f, 0.151855f, -0.00317383f, 0.116211f,
+-0.0161133f, 0.0915527f, -0.0441895f, 0.0668945f, -0.0722656f, 0.0541992f, -0.116211f,
+0.0415039f, -0.160156f, 0.0415039f, -0.22168f, 0.0415039f, -0.251465f, 0.0456543f,
+-0.285645f, 0.0498047f, -0.319824f, 0.0581055f, -0.364258f, 0.0712891f, -0.433105f,
+0.090332f, -0.484863f, 0.109375f, -0.536621f, 0.132568f, -0.57373f, 0.155762f, -0.61084f,
+0.182373f, -0.63501f, 0.208984f, -0.65918f, 0.237305f, -0.673096f, 0.265625f, -0.687012f,
+0.295166f, -0.692627f, 0.324707f, -0.698242f, 0.353516f, -0.698242f, 0.242676f, -0.0981445f,
+0.269531f, -0.0981445f, 0.291748f, -0.109619f, 0.313965f, -0.121094f, 0.33252f, -0.148438f,
+0.351074f, -0.175781f, 0.366211f, -0.221191f, 0.381348f, -0.266602f, 0.393555f, -0.334473f,
+0.401855f, -0.380371f, 0.407471f, -0.414307f, 0.413086f, -0.448242f, 0.413086f, -0.477051f,
+0.413086f, -0.530762f, 0.395264f, -0.560791f, 0.377441f, -0.59082f, 0.338867f, -0.59082f,
+0.30957f, -0.59082f, 0.287598f, -0.579346f, 0.265625f, -0.567871f, 0.248535f, -0.540771f,
+0.231445f, -0.513672f, 0.218262f, -0.468262f, 0.205078f, -0.422852f, 0.193359f, -0.354492f,
+0.186035f, -0.312012f, 0.18042f, -0.271729f, 0.174805f, -0.231445f, 0.174805f, -0.202637f,
+0.174805f, -0.180664f, 0.177979f, -0.161377f, 0.181152f, -0.14209f, 0.188965f, -0.128174f,
+0.196777f, -0.114258f, 0.209961f, -0.106201f, 0.223145f, -0.0981445f, 0.242676f,
+-0.0981445f, 0.0161133f, 0, 0.0371094f, -0.112793f, 0.20752f, -0.112793f, 0.294922f,
+-0.5625f, 0.108887f, -0.458008f, 0.131836f, -0.576172f, 0.325195f, -0.687988f, 0.457031f,
+-0.687988f, 0.344727f, -0.112793f, 0.502441f, -0.112793f, 0.480957f, 0, -0.015625f,
+0, 0.00244141f, -0.0952148f, 0.0258789f, -0.135742f, 0.0556641f, -0.169189f, 0.0854492f,
+-0.202637f, 0.118164f, -0.230957f, 0.150879f, -0.259277f, 0.184814f, -0.283691f,
+0.21875f, -0.308105f, 0.250732f, -0.330566f, 0.282715f, -0.353027f, 0.310791f, -0.374268f,
+0.338867f, -0.395508f, 0.359619f, -0.418213f, 0.380371f, -0.440918f, 0.392578f, -0.465576f,
+0.404785f, -0.490234f, 0.404785f, -0.519043f, 0.404785f, -0.538574f, 0.398926f, -0.552002f,
+0.393066f, -0.56543f, 0.382568f, -0.573486f, 0.37207f, -0.581543f, 0.357422f, -0.585205f,
+0.342773f, -0.588867f, 0.325684f, -0.588867f, 0.306641f, -0.588867f, 0.290039f, -0.584473f,
+0.273438f, -0.580078f, 0.259521f, -0.569824f, 0.245605f, -0.55957f, 0.234863f, -0.542236f,
+0.224121f, -0.524902f, 0.216797f, -0.499023f, 0.0869141f, -0.527832f, 0.0986328f,
+-0.567383f, 0.118652f, -0.598877f, 0.138672f, -0.630371f, 0.168945f, -0.652344f,
+0.199219f, -0.674316f, 0.240479f, -0.686279f, 0.281738f, -0.698242f, 0.335449f, -0.698242f,
+0.390625f, -0.698242f, 0.430176f, -0.686279f, 0.469727f, -0.674316f, 0.495605f, -0.652344f,
+0.521484f, -0.630371f, 0.533691f, -0.599121f, 0.545898f, -0.567871f, 0.545898f, -0.528809f,
+0.545898f, -0.490723f, 0.533691f, -0.458496f, 0.521484f, -0.42627f, 0.500488f, -0.398438f,
+0.479492f, -0.370605f, 0.451904f, -0.346191f, 0.424316f, -0.321777f, 0.393311f, -0.299316f,
+0.362305f, -0.276855f, 0.330078f, -0.255127f, 0.297852f, -0.233398f, 0.267822f, -0.210938f,
+0.237793f, -0.188477f, 0.211914f, -0.164307f, 0.186035f, -0.140137f, 0.16748f, -0.112793f,
+0.486816f, -0.112793f, 0.465332f, 0, 0.26123f, -0.404785f, 0.28418f, -0.404785f,
+0.309814f, -0.408691f, 0.335449f, -0.412598f, 0.356689f, -0.424316f, 0.37793f, -0.436035f,
+0.391846f, -0.457275f, 0.405762f, -0.478516f, 0.405762f, -0.513184f, 0.405762f, -0.54834f,
+0.386963f, -0.568604f, 0.368164f, -0.588867f, 0.329102f, -0.588867f, 0.284668f, -0.588867f,
+0.255371f, -0.566895f, 0.226074f, -0.544922f, 0.213379f, -0.499023f, 0.0830078f,
+-0.524414f, 0.0961914f, -0.570312f, 0.119141f, -0.603271f, 0.14209f, -0.63623f, 0.173828f,
+-0.657227f, 0.205566f, -0.678223f, 0.24585f, -0.688232f, 0.286133f, -0.698242f, 0.334473f,
+-0.698242f, 0.384277f, -0.698242f, 0.42334f, -0.686768f, 0.462402f, -0.675293f, 0.489502f,
+-0.653564f, 0.516602f, -0.631836f, 0.530762f, -0.60083f, 0.544922f, -0.569824f, 0.544922f,
+-0.530273f, 0.544922f, -0.493164f, 0.533203f, -0.462402f, 0.521484f, -0.431641f,
+0.498779f, -0.408936f, 0.476074f, -0.38623f, 0.443359f, -0.37207f, 0.410645f, -0.35791f,
+0.368652f, -0.354004f, 0.368164f, -0.352051f, 0.398926f, -0.347168f, 0.423828f, -0.335693f,
+0.44873f, -0.324219f, 0.466309f, -0.305664f, 0.483887f, -0.287109f, 0.493408f, -0.261719f,
+0.50293f, -0.236328f, 0.50293f, -0.204102f, 0.50293f, -0.161621f, 0.486328f, -0.122803f,
+0.469727f, -0.0839844f, 0.437744f, -0.0544434f, 0.405762f, -0.0249023f, 0.358398f,
+-0.00756836f, 0.311035f, 0.00976562f, 0.249512f, 0.00976562f, 0.188965f, 0.00976562f,
+0.144775f, -0.00341797f, 0.100586f, -0.0166016f, 0.0712891f, -0.0402832f, 0.0419922f,
+-0.0639648f, 0.0266113f, -0.0964355f, 0.0112305f, -0.128906f, 0.0078125f, -0.16748f,
+0.145508f, -0.186035f, 0.148438f, -0.161621f, 0.156982f, -0.145264f, 0.165527f, -0.128906f,
+0.179443f, -0.118896f, 0.193359f, -0.108887f, 0.212646f, -0.104736f, 0.231934f, -0.100586f,
+0.255859f, -0.100586f, 0.283203f, -0.100586f, 0.303467f, -0.108398f, 0.32373f, -0.116211f,
+0.337158f, -0.129883f, 0.350586f, -0.143555f, 0.357178f, -0.162354f, 0.36377f, -0.181152f,
+0.36377f, -0.203125f, 0.36377f, -0.248535f, 0.337402f, -0.27124f, 0.311035f, -0.293945f,
+0.256348f, -0.293945f, 0.204102f, -0.293945f, 0.225586f, -0.404785f, 0.426758f, -0.139648f,
+0.400391f, 0, 0.269531f, 0, 0.295898f, -0.139648f, -0.0166016f, -0.139648f, 0.00341797f,
+-0.240723f, 0.353516f, -0.687988f, 0.53418f, -0.687988f, 0.447266f, -0.242188f, 0.539062f,
+-0.242188f, 0.518555f, -0.139648f, 0.366211f, -0.498047f, 0.367676f, -0.505371f,
+0.370605f, -0.517578f, 0.373535f, -0.529785f, 0.377197f, -0.543213f, 0.380859f, -0.556641f,
+0.384521f, -0.569092f, 0.388184f, -0.581543f, 0.390625f, -0.588867f, 0.387207f, -0.583008f,
+0.380371f, -0.57251f, 0.373535f, -0.562012f, 0.365479f, -0.550049f, 0.357422f, -0.538086f,
+0.348877f, -0.526367f, 0.340332f, -0.514648f, 0.333496f, -0.505859f, 0.126465f, -0.242188f,
+0.316406f, -0.242188f, 0.154297f, -0.687988f, 0.567871f, -0.687988f, 0.546875f, -0.575195f,
+0.256836f, -0.575195f, 0.214355f, -0.412109f, 0.223145f, -0.419922f, 0.235107f, -0.427734f,
+0.24707f, -0.435547f, 0.262207f, -0.441895f, 0.277344f, -0.448242f, 0.296387f, -0.452148f,
+0.31543f, -0.456055f, 0.338867f, -0.456055f, 0.376953f, -0.456055f, 0.409912f, -0.442871f,
+0.442871f, -0.429688f, 0.467285f, -0.403809f, 0.491699f, -0.37793f, 0.505615f, -0.340088f,
+0.519531f, -0.302246f, 0.519531f, -0.25293f, 0.519531f, -0.194824f, 0.500488f, -0.146484f,
+0.481445f, -0.0981445f, 0.445312f, -0.0634766f, 0.40918f, -0.0288086f, 0.356689f,
+-0.00952148f, 0.304199f, 0.00976562f, 0.237305f, 0.00976562f, 0.182617f, 0.00976562f,
+0.142578f, -0.00317383f, 0.102539f, -0.0161133f, 0.0749512f, -0.0388184f, 0.0473633f,
+-0.0615234f, 0.0314941f, -0.0927734f, 0.015625f, -0.124023f, 0.00976562f, -0.160645f,
+0.147949f, -0.182617f, 0.151855f, -0.162109f, 0.158691f, -0.146729f, 0.165527f, -0.131348f,
+0.177246f, -0.121094f, 0.188965f, -0.11084f, 0.206543f, -0.105713f, 0.224121f, -0.100586f,
+0.249023f, -0.100586f, 0.281738f, -0.100586f, 0.306396f, -0.111328f, 0.331055f, -0.12207f,
+0.347412f, -0.140869f, 0.36377f, -0.159668f, 0.371826f, -0.18457f, 0.379883f, -0.209473f,
+0.379883f, -0.237305f, 0.379883f, -0.265625f, 0.372803f, -0.286133f, 0.365723f, -0.306641f,
+0.353271f, -0.319824f, 0.34082f, -0.333008f, 0.323975f, -0.339111f, 0.307129f, -0.345215f,
+0.287598f, -0.345215f, 0.255859f, -0.345215f, 0.231934f, -0.333984f, 0.208008f, -0.322754f,
+0.188965f, -0.300781f, 0.0551758f, -0.300781f, 0.260254f, 0.00976562f, 0.208008f,
+0.00976562f, 0.168213f, -0.00708008f, 0.128418f, -0.0239258f, 0.101318f, -0.0559082f,
+0.0742188f, -0.0878906f, 0.0603027f, -0.133789f, 0.0463867f, -0.179688f, 0.0463867f,
+-0.237793f, 0.0463867f, -0.337402f, 0.0695801f, -0.421631f, 0.0927734f, -0.505859f,
+0.134521f, -0.567383f, 0.17627f, -0.628906f, 0.234863f, -0.663574f, 0.293457f, -0.698242f,
+0.36377f, -0.698242f, 0.397461f, -0.698242f, 0.430664f, -0.690918f, 0.463867f, -0.683594f,
+0.491211f, -0.665527f, 0.518555f, -0.647461f, 0.537354f, -0.616943f, 0.556152f, -0.586426f,
+0.561523f, -0.540039f, 0.431641f, -0.52002f, 0.424805f, -0.555664f, 0.406738f, -0.572754f,
+0.388672f, -0.589844f, 0.356445f, -0.589844f, 0.300293f, -0.589844f, 0.258789f, -0.533691f,
+0.217285f, -0.477539f, 0.198242f, -0.364258f, 0.224121f, -0.399414f, 0.263916f, -0.421143f,
+0.303711f, -0.442871f, 0.354004f, -0.442871f, 0.392578f, -0.442871f, 0.424316f, -0.430908f,
+0.456055f, -0.418945f, 0.47876f, -0.395752f, 0.501465f, -0.372559f, 0.513916f, -0.338623f,
+0.526367f, -0.304688f, 0.526367f, -0.260254f, 0.526367f, -0.206055f, 0.507568f, -0.157227f,
+0.48877f, -0.108398f, 0.454102f, -0.0712891f, 0.419434f, -0.0341797f, 0.370361f,
+-0.012207f, 0.321289f, 0.00976562f, 0.260254f, 0.00976562f, 0.180176f, -0.209473f,
+0.180176f, -0.158203f, 0.204102f, -0.12793f, 0.228027f, -0.0976562f, 0.272461f, -0.0976562f,
+0.297363f, -0.0976562f, 0.318359f, -0.107422f, 0.339355f, -0.117188f, 0.354492f,
+-0.135986f, 0.369629f, -0.154785f, 0.378174f, -0.181885f, 0.386719f, -0.208984f,
+0.386719f, -0.243652f, 0.386719f, -0.269043f, 0.380127f, -0.287598f, 0.373535f, -0.306152f,
+0.361816f, -0.318115f, 0.350098f, -0.330078f, 0.334229f, -0.335938f, 0.318359f, -0.341797f,
+0.299805f, -0.341797f, 0.277832f, -0.341797f, 0.256348f, -0.333496f, 0.234863f, -0.325195f,
+0.218018f, -0.308838f, 0.201172f, -0.29248f, 0.190674f, -0.267578f, 0.180176f, -0.242676f,
+0.180176f, -0.209473f, 0.345215f, -0.697754f, 0.394531f, -0.697754f, 0.43335f, -0.686035f,
+0.472168f, -0.674316f, 0.499023f, -0.652832f, 0.525879f, -0.631348f, 0.540283f, -0.60083f,
+0.554688f, -0.570312f, 0.554688f, -0.532715f, 0.554688f, -0.5f, 0.544189f, -0.470947f,
+0.533691f, -0.441895f, 0.513916f, -0.419678f, 0.494141f, -0.397461f, 0.465332f, -0.382568f,
+0.436523f, -0.367676f, 0.400391f, -0.362793f, 0.399902f, -0.36084f, 0.424805f, -0.353516f,
+0.445557f, -0.340332f, 0.466309f, -0.327148f, 0.480957f, -0.30835f, 0.495605f, -0.289551f,
+0.503906f, -0.265137f, 0.512207f, -0.240723f, 0.512207f, -0.210938f, 0.512207f, -0.163574f,
+0.495117f, -0.123291f, 0.478027f, -0.0830078f, 0.444092f, -0.0534668f, 0.410156f,
+-0.0239258f, 0.359375f, -0.00708008f, 0.308594f, 0.00976562f, 0.240723f, 0.00976562f,
+0.182617f, 0.00976562f, 0.139648f, -0.00415039f, 0.0966797f, -0.0180664f, 0.0686035f,
+-0.0429688f, 0.0405273f, -0.0678711f, 0.0268555f, -0.101807f, 0.0131836f, -0.135742f,
+0.0131836f, -0.175781f, 0.0131836f, -0.221191f, 0.029541f, -0.253174f, 0.0458984f,
+-0.285156f, 0.0715332f, -0.306885f, 0.097168f, -0.328613f, 0.128174f, -0.341309f,
+0.15918f, -0.354004f, 0.188477f, -0.359863f, 0.188477f, -0.361816f, 0.143555f, -0.381836f,
+0.120361f, -0.421143f, 0.097168f, -0.460449f, 0.097168f, -0.513672f, 0.097168f, -0.556152f,
+0.114014f, -0.590332f, 0.130859f, -0.624512f, 0.162842f, -0.648193f, 0.194824f, -0.671875f,
+0.240967f, -0.684814f, 0.287109f, -0.697754f, 0.345215f, -0.697754f, 0.316406f, -0.410156f,
+0.345703f, -0.410156f, 0.364746f, -0.420654f, 0.383789f, -0.431152f, 0.395264f, -0.447266f,
+0.406738f, -0.463379f, 0.411133f, -0.482666f, 0.415527f, -0.501953f, 0.415527f, -0.519531f,
+0.415527f, -0.558594f, 0.39502f, -0.580078f, 0.374512f, -0.601562f, 0.331543f, -0.601562f,
+0.310547f, -0.601562f, 0.29248f, -0.595459f, 0.274414f, -0.589355f, 0.260986f, -0.57666f,
+0.247559f, -0.563965f, 0.23999f, -0.544434f, 0.232422f, -0.524902f, 0.232422f, -0.498047f,
+0.232422f, -0.482422f, 0.236328f, -0.466553f, 0.240234f, -0.450684f, 0.249756f, -0.438232f,
+0.259277f, -0.425781f, 0.275391f, -0.417969f, 0.291504f, -0.410156f, 0.316406f, -0.410156f,
+0.273926f, -0.3125f, 0.244629f, -0.3125f, 0.222412f, -0.303223f, 0.200195f, -0.293945f,
+0.185303f, -0.2771f, 0.17041f, -0.260254f, 0.162598f, -0.236572f, 0.154785f, -0.212891f,
+0.154785f, -0.184082f, 0.154785f, -0.163086f, 0.160645f, -0.145264f, 0.166504f, -0.127441f,
+0.178711f, -0.114502f, 0.190918f, -0.101562f, 0.209717f, -0.0942383f, 0.228516f,
+-0.0869141f, 0.253906f, -0.0869141f, 0.27832f, -0.0869141f, 0.299561f, -0.0952148f,
+0.320801f, -0.103516f, 0.33667f, -0.119873f, 0.352539f, -0.13623f, 0.361816f, -0.1604f,
+0.371094f, -0.18457f, 0.371094f, -0.216797f, 0.371094f, -0.234863f, 0.366455f, -0.251953f,
+0.361816f, -0.269043f, 0.350342f, -0.282471f, 0.338867f, -0.295898f, 0.320312f, -0.304199f,
+0.301758f, -0.3125f, 0.273926f, -0.3125f, 0.398926f, -0.318848f, 0.383789f, -0.300781f,
+0.367432f, -0.287109f, 0.351074f, -0.273438f, 0.33252f, -0.26416f, 0.313965f, -0.254883f,
+0.292236f, -0.250244f, 0.270508f, -0.245605f, 0.244141f, -0.245605f, 0.204102f, -0.245605f,
+0.172119f, -0.259521f, 0.140137f, -0.273438f, 0.11792f, -0.298584f, 0.0957031f, -0.32373f,
+0.0837402f, -0.358887f, 0.0717773f, -0.394043f, 0.0717773f, -0.436035f, 0.0717773f,
+-0.491211f, 0.0915527f, -0.539062f, 0.111328f, -0.586914f, 0.146484f, -0.622314f,
+0.181641f, -0.657715f, 0.230469f, -0.677979f, 0.279297f, -0.698242f, 0.337891f, -0.698242f,
+0.384277f, -0.698242f, 0.42334f, -0.683105f, 0.462402f, -0.667969f, 0.490967f, -0.638428f,
+0.519531f, -0.608887f, 0.535645f, -0.565918f, 0.551758f, -0.522949f, 0.551758f, -0.467285f,
+0.551758f, -0.454102f, 0.550781f, -0.4375f, 0.549805f, -0.420898f, 0.548096f, -0.403076f,
+0.546387f, -0.385254f, 0.543701f, -0.366699f, 0.541016f, -0.348145f, 0.537598f, -0.331543f,
+0.519043f, -0.239746f, 0.487793f, -0.174805f, 0.456543f, -0.109863f, 0.416748f, -0.0688477f,
+0.376953f, -0.027832f, 0.330322f, -0.0090332f, 0.283691f, 0.00976562f, 0.233887f,
+0.00976562f, 0.192383f, 0.00976562f, 0.156738f, 0, 0.121094f, -0.00976562f, 0.09375f,
+-0.0300293f, 0.0664062f, -0.050293f, 0.0483398f, -0.0805664f, 0.0302734f, -0.11084f,
+0.0234375f, -0.151855f, 0.157227f, -0.175293f, 0.164062f, -0.138672f, 0.18457f, -0.118652f,
+0.205078f, -0.0986328f, 0.243164f, -0.0986328f, 0.264648f, -0.0986328f, 0.286865f,
+-0.108154f, 0.309082f, -0.117676f, 0.329834f, -0.142334f, 0.350586f, -0.166992f,
+0.368408f, -0.209717f, 0.38623f, -0.252441f, 0.398926f, -0.318848f, 0.41748f, -0.492676f,
+0.41748f, -0.513184f, 0.411377f, -0.531006f, 0.405273f, -0.548828f, 0.393799f, -0.562256f,
+0.382324f, -0.575684f, 0.366455f, -0.583252f, 0.350586f, -0.59082f, 0.331055f, -0.59082f,
+0.304688f, -0.59082f, 0.282715f, -0.581055f, 0.260742f, -0.571289f, 0.244873f, -0.552002f,
+0.229004f, -0.532715f, 0.219971f, -0.504395f, 0.210938f, -0.476074f, 0.210938f, -0.439453f,
+0.210938f, -0.41748f, 0.217529f, -0.400146f, 0.224121f, -0.382812f, 0.235596f, -0.37085f,
+0.24707f, -0.358887f, 0.263184f, -0.352783f, 0.279297f, -0.34668f, 0.29834f, -0.34668f,
+0.316895f, -0.34668f, 0.335205f, -0.351807f, 0.353516f, -0.356934f, 0.369141f, -0.369141f,
+0.384766f, -0.381348f, 0.396484f, -0.400879f, 0.408203f, -0.42041f, 0.413574f, -0.449219f,
+0.415527f, -0.460938f, 0.416504f, -0.47168f, 0.41748f, -0.482422f, 0.41748f, -0.492676f,
+0.114746f, -0.367188f, 0.141602f, -0.504883f, 0.282227f, -0.504883f, 0.255371f, -0.367188f,
+0.043457f, 0, 0.0703125f, -0.137207f, 0.210938f, -0.137207f, 0.184082f, 0, 0.507324f,
+0, 0.480469f, -0.175781f, 0.218262f, -0.175781f, 0.123047f, 0, -0.0205078f, 0, 0.36377f,
+-0.687988f, 0.533691f, -0.687988f, 0.649902f, 0, 0.436523f, -0.504883f, 0.435547f,
+-0.512207f, 0.434082f, -0.523193f, 0.432617f, -0.53418f, 0.431152f, -0.545654f, 0.429688f,
+-0.557129f, 0.428711f, -0.567139f, 0.427734f, -0.577148f, 0.427734f, -0.582031f,
+0.425781f, -0.576172f, 0.420654f, -0.564209f, 0.415527f, -0.552246f, 0.408936f, -0.537598f,
+0.402344f, -0.522949f, 0.394531f, -0.507324f, 0.386719f, -0.491699f, 0.379883f, -0.478516f,
+0.276367f, -0.28418f, 0.469238f, -0.28418f, 0.151367f, -0.687988f, 0.436523f, -0.687988f,
+0.500488f, -0.687988f, 0.547119f, -0.677246f, 0.59375f, -0.666504f, 0.624512f, -0.645996f,
+0.655273f, -0.625488f, 0.670166f, -0.595947f, 0.685059f, -0.566406f, 0.685059f, -0.528809f,
+0.685059f, -0.493164f, 0.673828f, -0.465088f, 0.662598f, -0.437012f, 0.641846f, -0.41626f,
+0.621094f, -0.395508f, 0.591797f, -0.381592f, 0.5625f, -0.367676f, 0.526855f, -0.360352f,
+0.561523f, -0.354492f, 0.587891f, -0.34082f, 0.614258f, -0.327148f, 0.63208f, -0.307373f,
+0.649902f, -0.287598f, 0.658936f, -0.262939f, 0.667969f, -0.238281f, 0.667969f, -0.210449f,
+0.667969f, -0.149414f, 0.643311f, -0.108887f, 0.618652f, -0.0683594f, 0.576904f,
+-0.0441895f, 0.535156f, -0.0200195f, 0.479492f, -0.0100098f, 0.423828f, 0, 0.361816f,
+0, 0.0175781f, 0, 0.241211f, -0.410645f, 0.384766f, -0.410645f, 0.427246f, -0.410645f,
+0.457275f, -0.416016f, 0.487305f, -0.421387f, 0.506104f, -0.433105f, 0.524902f, -0.444824f,
+0.533447f, -0.463135f, 0.541992f, -0.481445f, 0.541992f, -0.506836f, 0.541992f, -0.52832f,
+0.533936f, -0.542725f, 0.525879f, -0.557129f, 0.510498f, -0.565674f, 0.495117f, -0.574219f,
+0.472412f, -0.577637f, 0.449707f, -0.581055f, 0.420898f, -0.581055f, 0.273926f, -0.581055f,
+0.182129f, -0.106934f, 0.342285f, -0.106934f, 0.388672f, -0.106934f, 0.422852f, -0.111816f,
+0.457031f, -0.116699f, 0.479248f, -0.128906f, 0.501465f, -0.141113f, 0.512451f, -0.161621f,
+0.523438f, -0.182129f, 0.523438f, -0.213379f, 0.523438f, -0.257324f, 0.490234f, -0.280762f,
+0.457031f, -0.304199f, 0.381836f, -0.304199f, 0.220703f, -0.304199f, 0.195801f, -0.279785f,
+0.195801f, -0.23877f, 0.206055f, -0.206055f, 0.216309f, -0.17334f, 0.236572f, -0.150391f,
+0.256836f, -0.127441f, 0.286865f, -0.115234f, 0.316895f, -0.103027f, 0.356934f, -0.103027f,
+0.39502f, -0.103027f, 0.42627f, -0.113281f, 0.45752f, -0.123535f, 0.482666f, -0.141113f,
+0.507812f, -0.158691f, 0.5271f, -0.181396f, 0.546387f, -0.204102f, 0.561035f, -0.229004f,
+0.671875f, -0.171875f, 0.650879f, -0.134766f, 0.621582f, -0.101562f, 0.592285f, -0.0683594f,
+0.552734f, -0.0437012f, 0.513184f, -0.019043f, 0.462402f, -0.00463867f, 0.411621f,
+0.00976562f, 0.347168f, 0.00976562f, 0.270508f, 0.00976562f, 0.214111f, -0.0126953f,
+0.157715f, -0.0351562f, 0.121094f, -0.0739746f, 0.0844727f, -0.112793f, 0.0666504f,
+-0.165283f, 0.0488281f, -0.217773f, 0.0488281f, -0.277832f, 0.0488281f, -0.338379f,
+0.0615234f, -0.393066f, 0.0742188f, -0.447754f, 0.0983887f, -0.494385f, 0.122559f,
+-0.541016f, 0.157715f, -0.578857f, 0.192871f, -0.616699f, 0.237793f, -0.643066f,
+0.282715f, -0.669434f, 0.33667f, -0.683838f, 0.390625f, -0.698242f, 0.452637f, -0.698242f,
+0.519531f, -0.698242f, 0.568115f, -0.682617f, 0.616699f, -0.666992f, 0.650391f, -0.640625f,
+0.684082f, -0.614258f, 0.704102f, -0.57959f, 0.724121f, -0.544922f, 0.733887f, -0.506836f,
+0.600098f, -0.472168f, 0.594238f, -0.493652f, 0.582275f, -0.513916f, 0.570312f, -0.53418f,
+0.551758f, -0.550049f, 0.533203f, -0.565918f, 0.507324f, -0.575439f, 0.481445f, -0.584961f,
+0.448242f, -0.584961f, 0.386719f, -0.584961f, 0.3396f, -0.562744f, 0.29248f, -0.540527f,
+0.260498f, -0.500244f, 0.228516f, -0.459961f, 0.212158f, -0.403809f, 0.195801f, -0.347656f,
+0.195801f, -0.279785f, 0.358398f, -0.687988f, 0.437988f, -0.687988f, 0.500244f, -0.669434f,
+0.5625f, -0.650879f, 0.605469f, -0.614014f, 0.648438f, -0.577148f, 0.671143f, -0.522217f,
+0.693848f, -0.467285f, 0.693848f, -0.394043f, 0.693848f, -0.329102f, 0.678955f, -0.274658f,
+0.664062f, -0.220215f, 0.637451f, -0.176514f, 0.61084f, -0.132812f, 0.573975f, -0.0998535f,
+0.537109f, -0.0668945f, 0.493408f, -0.0446777f, 0.449707f, -0.0224609f, 0.400391f,
+-0.0112305f, 0.351074f, 0, 0.299805f, 0, 0.0175781f, 0, 0.151367f, -0.687988f, 0.183105f,
+-0.111328f, 0.29541f, -0.111328f, 0.352051f, -0.111328f, 0.400391f, -0.129395f, 0.44873f,
+-0.147461f, 0.483887f, -0.182373f, 0.519043f, -0.217285f, 0.539062f, -0.268799f,
+0.559082f, -0.320312f, 0.559082f, -0.387695f, 0.559082f, -0.435547f, 0.54541f, -0.470947f,
+0.531738f, -0.506348f, 0.506104f, -0.529785f, 0.480469f, -0.553223f, 0.443359f, -0.564941f,
+0.40625f, -0.57666f, 0.359375f, -0.57666f, 0.273438f, -0.57666f, 0.0175781f, 0, 0.150879f,
+-0.687988f, 0.691895f, -0.687988f, 0.67041f, -0.57666f, 0.273438f, -0.57666f, 0.239746f,
+-0.403809f, 0.606934f, -0.403809f, 0.585449f, -0.29248f, 0.218262f, -0.29248f, 0.183105f,
+-0.111328f, 0.600098f, -0.111328f, 0.578125f, 0, 0.273438f, -0.57666f, 0.231934f,
+-0.36377f, 0.558105f, -0.36377f, 0.536621f, -0.252441f, 0.210449f, -0.252441f, 0.161133f,
+0, 0.0175781f, 0, 0.150879f, -0.687988f, 0.632324f, -0.687988f, 0.61084f, -0.57666f,
+0.683594f, -0.0854492f, 0.650879f, -0.0629883f, 0.616455f, -0.045166f, 0.582031f,
+-0.0273438f, 0.542969f, -0.0153809f, 0.503906f, -0.00341797f, 0.459229f, 0.00292969f,
+0.414551f, 0.00927734f, 0.361328f, 0.00927734f, 0.282227f, 0.00927734f, 0.223389f,
+-0.0129395f, 0.164551f, -0.0351562f, 0.125732f, -0.0742188f, 0.0869141f, -0.113281f,
+0.0678711f, -0.167236f, 0.0488281f, -0.221191f, 0.0488281f, -0.284668f, 0.0488281f,
+-0.376465f, 0.0776367f, -0.452637f, 0.106445f, -0.528809f, 0.159912f, -0.583496f,
+0.213379f, -0.638184f, 0.289551f, -0.668213f, 0.365723f, -0.698242f, 0.459961f, -0.698242f,
+0.523926f, -0.698242f, 0.572754f, -0.682617f, 0.621582f, -0.666992f, 0.656738f, -0.640625f,
+0.691895f, -0.614258f, 0.714111f, -0.579834f, 0.736328f, -0.54541f, 0.74707f, -0.507324f,
+0.609375f, -0.469238f, 0.603516f, -0.491699f, 0.591553f, -0.512695f, 0.57959f, -0.533691f,
+0.560547f, -0.549805f, 0.541504f, -0.565918f, 0.514648f, -0.575439f, 0.487793f, -0.584961f,
+0.452148f, -0.584961f, 0.390137f, -0.584961f, 0.342041f, -0.5625f, 0.293945f, -0.540039f,
+0.26123f, -0.500488f, 0.228516f, -0.460938f, 0.21167f, -0.406738f, 0.194824f, -0.352539f,
+0.194824f, -0.289062f, 0.194824f, -0.251465f, 0.204834f, -0.217773f, 0.214844f, -0.184082f,
+0.236328f, -0.158447f, 0.257812f, -0.132812f, 0.291748f, -0.11792f, 0.325684f, -0.103027f,
+0.373047f, -0.103027f, 0.40332f, -0.103027f, 0.430664f, -0.106934f, 0.458008f, -0.11084f,
+0.481934f, -0.117432f, 0.505859f, -0.124023f, 0.525635f, -0.132324f, 0.54541f, -0.140625f,
+0.560547f, -0.149902f, 0.583008f, -0.26123f, 0.416016f, -0.26123f, 0.435059f, -0.362793f,
+0.734863f, -0.362793f, 0.466797f, 0, 0.524414f, -0.294922f, 0.21875f, -0.294922f,
+0.161133f, 0, 0.0175781f, 0, 0.150879f, -0.687988f, 0.294922f, -0.687988f, 0.241699f,
+-0.414062f, 0.547363f, -0.414062f, 0.600586f, -0.687988f, 0.739258f, -0.687988f,
+0.605469f, 0, 0.0175781f, 0, 0.150879f, -0.687988f, 0.294922f, -0.687988f, 0.161133f,
+0, 0.48584f, 0, 0.3125f, -0.3125f, 0.209473f, -0.252441f, 0.160156f, 0, 0.0175781f,
+0, 0.150879f, -0.687988f, 0.294922f, -0.687988f, 0.231445f, -0.375977f, 0.602539f,
+-0.687988f, 0.782715f, -0.687988f, 0.417969f, -0.387207f, 0.64502f, 0, 0.0175781f,
+0, 0.150879f, -0.687988f, 0.294922f, -0.687988f, 0.183105f, -0.111328f, 0.552246f,
+-0.111328f, 0.530273f, 0, 0.588867f, 0, 0.672852f, -0.431641f, 0.678223f, -0.458496f,
+0.68457f, -0.486084f, 0.690918f, -0.513672f, 0.696289f, -0.536621f, 0.702637f, -0.563477f,
+0.708984f, -0.588867f, 0.691406f, -0.550781f, 0.675293f, -0.515137f, 0.668457f, -0.5f,
+0.660889f, -0.483887f, 0.65332f, -0.467773f, 0.645996f, -0.452393f, 0.638672f, -0.437012f,
+0.63208f, -0.423096f, 0.625488f, -0.40918f, 0.619629f, -0.398438f, 0.418457f, 0,
+0.315918f, 0, 0.27002f, -0.399902f, 0.269043f, -0.40918f, 0.267578f, -0.422119f,
+0.266113f, -0.435059f, 0.264404f, -0.450195f, 0.262695f, -0.465332f, 0.260986f, -0.481445f,
+0.259277f, -0.497559f, 0.257812f, -0.512695f, 0.254395f, -0.548828f, 0.250488f, -0.588867f,
+0.24707f, -0.559082f, 0.243652f, -0.530273f, 0.242188f, -0.518066f, 0.240479f, -0.504883f,
+0.23877f, -0.491699f, 0.237061f, -0.479004f, 0.235352f, -0.466309f, 0.233398f, -0.45459f,
+0.231445f, -0.442871f, 0.229492f, -0.433105f, 0.145508f, 0, 0.0175781f, 0, 0.151367f,
+-0.687988f, 0.344238f, -0.687988f, 0.387207f, -0.303223f, 0.38916f, -0.288086f, 0.391113f,
+-0.265381f, 0.393066f, -0.242676f, 0.39502f, -0.220703f, 0.396973f, -0.195312f, 0.399414f,
+-0.168457f, 0.411621f, -0.195312f, 0.42334f, -0.220215f, 0.433105f, -0.241699f, 0.444092f,
+-0.263916f, 0.455078f, -0.286133f, 0.462402f, -0.300781f, 0.658691f, -0.687988f,
+0.850586f, -0.687988f, 0.716797f, 0, 0.431641f, 0, 0.249023f, -0.552246f, 0.246094f,
+-0.53125f, 0.243164f, -0.510742f, 0.240723f, -0.493164f, 0.237305f, -0.4729f, 0.233887f,
+-0.452637f, 0.230469f, -0.435547f, 0.145508f, 0, 0.0175781f, 0, 0.151367f, -0.687988f,
+0.322266f, -0.687988f, 0.506348f, -0.130859f, 0.509277f, -0.149902f, 0.512207f, -0.170898f,
+0.514648f, -0.188965f, 0.518311f, -0.211182f, 0.521973f, -0.233398f, 0.526367f, -0.255859f,
+0.611328f, -0.687988f, 0.739258f, -0.687988f, 0.605469f, 0, 0.453125f, -0.698242f,
+0.525391f, -0.698242f, 0.58252f, -0.678467f, 0.639648f, -0.658691f, 0.679443f, -0.621826f,
+0.719238f, -0.584961f, 0.740234f, -0.532715f, 0.76123f, -0.480469f, 0.76123f, -0.415527f,
+0.76123f, -0.391602f, 0.758789f, -0.365967f, 0.756348f, -0.340332f, 0.751465f, -0.316895f,
+0.736328f, -0.241699f, 0.701904f, -0.181396f, 0.66748f, -0.121094f, 0.616699f, -0.0786133f,
+0.565918f, -0.0361328f, 0.499756f, -0.0131836f, 0.433594f, 0.00976562f, 0.35498f,
+0.00976562f, 0.280273f, 0.00976562f, 0.223145f, -0.0114746f, 0.166016f, -0.0327148f,
+0.127197f, -0.0710449f, 0.0883789f, -0.109375f, 0.0686035f, -0.162598f, 0.0488281f,
+-0.21582f, 0.0488281f, -0.279785f, 0.0488281f, -0.302246f, 0.0510254f, -0.325684f,
+0.0532227f, -0.349121f, 0.0581055f, -0.373047f, 0.0732422f, -0.446289f, 0.106934f,
+-0.506348f, 0.140625f, -0.566406f, 0.190918f, -0.609131f, 0.241211f, -0.651855f,
+0.307373f, -0.675049f, 0.373535f, -0.698242f, 0.453125f, -0.698242f, 0.446289f, -0.584473f,
+0.394043f, -0.584473f, 0.353027f, -0.568848f, 0.312012f, -0.553223f, 0.281982f, -0.523926f,
+0.251953f, -0.494629f, 0.231934f, -0.451904f, 0.211914f, -0.40918f, 0.20166f, -0.35498f,
+0.198242f, -0.336914f, 0.196777f, -0.318604f, 0.195312f, -0.300293f, 0.195312f, -0.283691f,
+0.195312f, -0.193848f, 0.239258f, -0.148682f, 0.283203f, -0.103516f, 0.361816f, -0.103516f,
+0.414551f, -0.103516f, 0.455566f, -0.119385f, 0.496582f, -0.135254f, 0.526855f, -0.165039f,
+0.557129f, -0.194824f, 0.576904f, -0.237061f, 0.59668f, -0.279297f, 0.606934f, -0.332031f,
+0.610352f, -0.349609f, 0.611572f, -0.369629f, 0.612793f, -0.389648f, 0.612793f, -0.403809f,
+0.612793f, -0.449219f, 0.601074f, -0.48291f, 0.589355f, -0.516602f, 0.567871f, -0.539307f,
+0.546387f, -0.562012f, 0.515381f, -0.573242f, 0.484375f, -0.584473f, 0.446289f, -0.584473f,
+0.415039f, -0.687988f, 0.475586f, -0.687988f, 0.522705f, -0.673828f, 0.569824f, -0.659668f,
+0.602295f, -0.632812f, 0.634766f, -0.605957f, 0.651611f, -0.567871f, 0.668457f, -0.529785f,
+0.668457f, -0.481934f, 0.668457f, -0.42627f, 0.648682f, -0.381836f, 0.628906f, -0.337402f,
+0.592773f, -0.306396f, 0.556641f, -0.275391f, 0.505859f, -0.258789f, 0.455078f, -0.242188f,
+0.393066f, -0.242188f, 0.208984f, -0.242188f, 0.161133f, 0, 0.0175781f, 0, 0.150879f,
+-0.687988f, 0.22998f, -0.353027f, 0.371094f, -0.353027f, 0.446777f, -0.353027f, 0.484619f,
+-0.381348f, 0.522461f, -0.409668f, 0.522461f, -0.474121f, 0.522461f, -0.500977f,
+0.513672f, -0.520264f, 0.504883f, -0.539551f, 0.48877f, -0.552002f, 0.472656f, -0.564453f,
+0.450439f, -0.570312f, 0.428223f, -0.576172f, 0.401367f, -0.576172f, 0.273438f, -0.576172f,
+0.453125f, -0.698242f, 0.525391f, -0.698242f, 0.58252f, -0.678467f, 0.639648f, -0.658691f,
+0.679443f, -0.621826f, 0.719238f, -0.584961f, 0.740234f, -0.532715f, 0.76123f, -0.480469f,
+0.76123f, -0.415527f, 0.76123f, -0.391602f, 0.758789f, -0.365967f, 0.756348f, -0.340332f,
+0.751465f, -0.316895f, 0.738281f, -0.250977f, 0.710205f, -0.196533f, 0.682129f, -0.14209f,
+0.641113f, -0.10083f, 0.600098f, -0.0595703f, 0.547119f, -0.032959f, 0.494141f, -0.00634766f,
+0.430664f, 0.00390625f, 0.439941f, 0.0517578f, 0.462158f, 0.0732422f, 0.484375f,
+0.0947266f, 0.527832f, 0.0947266f, 0.536133f, 0.0947266f, 0.545898f, 0.0942383f,
+0.555664f, 0.09375f, 0.56543f, 0.0927734f, 0.575195f, 0.0917969f, 0.584473f, 0.0905762f,
+0.59375f, 0.0893555f, 0.601074f, 0.0878906f, 0.579102f, 0.183105f, 0.564941f, 0.187988f,
+0.542725f, 0.19165f, 0.520508f, 0.195312f, 0.496582f, 0.195312f, 0.442383f, 0.195312f,
+0.404297f, 0.181641f, 0.366211f, 0.167969f, 0.341309f, 0.142822f, 0.316406f, 0.117676f,
+0.303223f, 0.0825195f, 0.290039f, 0.0473633f, 0.285156f, 0.00439453f, 0.227539f,
+-0.00488281f, 0.18335f, -0.029541f, 0.13916f, -0.0541992f, 0.109131f, -0.0910645f,
+0.0791016f, -0.12793f, 0.0639648f, -0.175781f, 0.0488281f, -0.223633f, 0.0488281f,
+-0.279785f, 0.0488281f, -0.302246f, 0.0510254f, -0.325684f, 0.0532227f, -0.349121f,
+0.0581055f, -0.373047f, 0.0732422f, -0.446289f, 0.106934f, -0.506348f, 0.140625f,
+-0.566406f, 0.190918f, -0.609131f, 0.241211f, -0.651855f, 0.307373f, -0.675049f,
+0.373535f, -0.698242f, 0.453125f, -0.698242f, 0.446289f, -0.584473f, 0.394043f, -0.584473f,
+0.353027f, -0.568848f, 0.312012f, -0.553223f, 0.281982f, -0.523926f, 0.251953f, -0.494629f,
+0.231934f, -0.451904f, 0.211914f, -0.40918f, 0.20166f, -0.35498f, 0.198242f, -0.336914f,
+0.196777f, -0.318604f, 0.195312f, -0.300293f, 0.195312f, -0.283691f, 0.195312f, -0.193848f,
+0.239258f, -0.148682f, 0.283203f, -0.103516f, 0.361816f, -0.103516f, 0.414551f, -0.103516f,
+0.455566f, -0.119385f, 0.496582f, -0.135254f, 0.526855f, -0.165039f, 0.557129f, -0.194824f,
+0.576904f, -0.237061f, 0.59668f, -0.279297f, 0.606934f, -0.332031f, 0.610352f, -0.349609f,
+0.611572f, -0.369629f, 0.612793f, -0.389648f, 0.612793f, -0.403809f, 0.612793f, -0.449219f,
+0.601074f, -0.48291f, 0.589355f, -0.516602f, 0.567871f, -0.539307f, 0.546387f, -0.562012f,
+0.515381f, -0.573242f, 0.484375f, -0.584473f, 0.446289f, -0.584473f, 0.493164f, 0,
+0.380859f, -0.260742f, 0.211914f, -0.260742f, 0.161621f, 0, 0.0175781f, 0, 0.151367f,
+-0.687988f, 0.469238f, -0.687988f, 0.535156f, -0.687988f, 0.582031f, -0.671875f,
+0.628906f, -0.655762f, 0.658447f, -0.628662f, 0.687988f, -0.601562f, 0.70166f, -0.565918f,
+0.715332f, -0.530273f, 0.715332f, -0.491211f, 0.715332f, -0.445312f, 0.698975f, -0.409424f,
+0.682617f, -0.373535f, 0.655518f, -0.347656f, 0.628418f, -0.321777f, 0.592773f, -0.306152f,
+0.557129f, -0.290527f, 0.518555f, -0.284668f, 0.652344f, 0, 0.425781f, -0.373047f,
+0.458496f, -0.373047f, 0.484863f, -0.379395f, 0.51123f, -0.385742f, 0.530029f, -0.399414f,
+0.548828f, -0.413086f, 0.559082f, -0.433838f, 0.569336f, -0.45459f, 0.569336f, -0.48291f,
+0.569336f, -0.508301f, 0.560059f, -0.526123f, 0.550781f, -0.543945f, 0.534668f, -0.554932f,
+0.518555f, -0.565918f, 0.49707f, -0.571045f, 0.475586f, -0.576172f, 0.451172f, -0.576172f,
+0.273438f, -0.576172f, 0.233887f, -0.373047f, 0.292969f, 0.00976562f, 0.227051f,
+0.00976562f, 0.177246f, -0.00195312f, 0.127441f, -0.0136719f, 0.0930176f, -0.0373535f,
+0.0585938f, -0.0610352f, 0.0388184f, -0.0961914f, 0.019043f, -0.131348f, 0.012207f,
+-0.178223f, 0.15332f, -0.202148f, 0.158203f, -0.175781f, 0.168945f, -0.15625f, 0.179688f,
+-0.136719f, 0.197754f, -0.123779f, 0.21582f, -0.11084f, 0.241699f, -0.104492f, 0.267578f,
+-0.0981445f, 0.302734f, -0.0981445f, 0.339844f, -0.0981445f, 0.37085f, -0.103027f,
+0.401855f, -0.10791f, 0.424072f, -0.119385f, 0.446289f, -0.130859f, 0.45874f, -0.149414f,
+0.471191f, -0.167969f, 0.471191f, -0.195312f, 0.471191f, -0.218262f, 0.461914f, -0.234375f,
+0.452637f, -0.250488f, 0.434326f, -0.262207f, 0.416016f, -0.273926f, 0.388916f, -0.283203f,
+0.361816f, -0.29248f, 0.325684f, -0.301758f, 0.279785f, -0.313965f, 0.239502f, -0.329102f,
+0.199219f, -0.344238f, 0.169189f, -0.367432f, 0.13916f, -0.390625f, 0.121582f, -0.424072f,
+0.104004f, -0.45752f, 0.104004f, -0.506348f, 0.104004f, -0.552734f, 0.125977f, -0.588623f,
+0.147949f, -0.624512f, 0.185791f, -0.648926f, 0.223633f, -0.67334f, 0.274658f, -0.685791f,
+0.325684f, -0.698242f, 0.383789f, -0.698242f, 0.446777f, -0.698242f, 0.494385f, -0.686279f,
+0.541992f, -0.674316f, 0.575684f, -0.652588f, 0.609375f, -0.630859f, 0.629395f, -0.600342f,
+0.649414f, -0.569824f, 0.656738f, -0.532715f, 0.516113f, -0.5f, 0.505371f, -0.543945f,
+0.469482f, -0.570068f, 0.433594f, -0.596191f, 0.375977f, -0.596191f, 0.34375f, -0.596191f,
+0.31958f, -0.589844f, 0.29541f, -0.583496f, 0.279053f, -0.572266f, 0.262695f, -0.561035f,
+0.254395f, -0.54541f, 0.246094f, -0.529785f, 0.246094f, -0.51123f, 0.246094f, -0.489258f,
+0.25708f, -0.474365f, 0.268066f, -0.459473f, 0.287354f, -0.44873f, 0.306641f, -0.437988f,
+0.333496f, -0.429688f, 0.360352f, -0.421387f, 0.392578f, -0.412598f, 0.41748f, -0.405762f,
+0.443604f, -0.397705f, 0.469727f, -0.389648f, 0.494141f, -0.378662f, 0.518555f, -0.367676f,
+0.540039f, -0.352783f, 0.561523f, -0.337891f, 0.577637f, -0.317139f, 0.59375f, -0.296387f,
+0.603027f, -0.269287f, 0.612305f, -0.242188f, 0.612305f, -0.206543f, 0.612305f, -0.155273f,
+0.592773f, -0.115234f, 0.573242f, -0.0751953f, 0.533691f, -0.0473633f, 0.494141f,
+-0.0195312f, 0.434082f, -0.00488281f, 0.374023f, 0.00976562f, 0.292969f, 0.00976562f,
+0.437012f, -0.57666f, 0.324707f, 0, 0.180664f, 0, 0.292969f, -0.57666f, 0.0708008f,
+-0.57666f, 0.0922852f, -0.687988f, 0.681152f, -0.687988f, 0.659668f, -0.57666f, 0.335938f,
+-0.103027f, 0.374512f, -0.103027f, 0.404297f, -0.111328f, 0.434082f, -0.119629f,
+0.456299f, -0.138672f, 0.478516f, -0.157715f, 0.493164f, -0.188477f, 0.507812f, -0.219238f,
+0.516602f, -0.26416f, 0.598633f, -0.687988f, 0.742676f, -0.687988f, 0.65918f, -0.258789f,
+0.645508f, -0.189453f, 0.618652f, -0.138916f, 0.591797f, -0.0883789f, 0.551025f,
+-0.0554199f, 0.510254f, -0.0224609f, 0.454834f, -0.00634766f, 0.399414f, 0.00976562f,
+0.328125f, 0.00976562f, 0.265137f, 0.00976562f, 0.214844f, -0.00463867f, 0.164551f,
+-0.019043f, 0.129883f, -0.046875f, 0.0952148f, -0.074707f, 0.0766602f, -0.115967f,
+0.0581055f, -0.157227f, 0.0581055f, -0.210449f, 0.0581055f, -0.220703f, 0.059082f,
+-0.234131f, 0.0600586f, -0.247559f, 0.0617676f, -0.26123f, 0.0634766f, -0.274902f,
+0.0654297f, -0.287842f, 0.0673828f, -0.300781f, 0.0693359f, -0.310059f, 0.141602f,
+-0.687988f, 0.285645f, -0.687988f, 0.210938f, -0.29248f, 0.20752f, -0.275879f, 0.204834f,
+-0.252686f, 0.202148f, -0.229492f, 0.202148f, -0.208496f, 0.202148f, -0.182129f,
+0.211914f, -0.162354f, 0.22168f, -0.142578f, 0.239502f, -0.129395f, 0.257324f, -0.116211f,
+0.281982f, -0.109619f, 0.306641f, -0.103027f, 0.335938f, -0.103027f, 0.703613f, 0,
+0.532715f, 0, 0.519531f, -0.396484f, 0.519531f, -0.401855f, 0.519043f, -0.419189f,
+0.518555f, -0.436523f, 0.518066f, -0.458496f, 0.517578f, -0.480469f, 0.517334f, -0.503906f,
+0.51709f, -0.527344f, 0.51709f, -0.544922f, 0.506348f, -0.516113f, 0.496094f, -0.48877f,
+0.491699f, -0.477051f, 0.486816f, -0.4646f, 0.481934f, -0.452148f, 0.477295f, -0.440186f,
+0.472656f, -0.428223f, 0.468262f, -0.41748f, 0.463867f, -0.406738f, 0.459961f, -0.397949f,
+0.290039f, 0, 0.116699f, 0, 0.0732422f, -0.687988f, 0.209961f, -0.687988f, 0.227539f,
+-0.290039f, 0.228516f, -0.266602f, 0.229248f, -0.237549f, 0.22998f, -0.208496f, 0.230469f,
+-0.182129f, 0.230957f, -0.151855f, 0.230957f, -0.121094f, 0.245117f, -0.157227f,
+0.258789f, -0.191406f, 0.264648f, -0.206055f, 0.270996f, -0.22168f, 0.277344f, -0.237305f,
+0.283691f, -0.252441f, 0.290039f, -0.267578f, 0.295654f, -0.281494f, 0.30127f, -0.29541f,
+0.306152f, -0.306641f, 0.469238f, -0.687988f, 0.623535f, -0.687988f, 0.63916f, -0.250977f,
+0.640137f, -0.230469f, 0.640869f, -0.208008f, 0.641602f, -0.185547f, 0.642578f, -0.166016f,
+0.643555f, -0.143066f, 0.644043f, -0.121094f, 0.654297f, -0.148926f, 0.665527f, -0.178223f,
+0.675293f, -0.203125f, 0.687012f, -0.23291f, 0.69873f, -0.262695f, 0.709961f, -0.290527f,
+0.873047f, -0.687988f, 1.01514f, -0.687988f, 0.107422f, -0.687988f, 0.258301f, -0.687988f,
+0.367676f, -0.458008f, 0.563965f, -0.687988f, 0.716797f, -0.687988f, 0.423828f, -0.357422f,
+0.603027f, 0, 0.453125f, 0, 0.32959f, -0.259766f, 0.107422f, 0, -0.0458984f, 0, 0.272461f,
+-0.359375f, 0.408203f, -0.282227f, 0.353516f, 0, 0.209961f, 0, 0.264648f, -0.282227f,
+0.0839844f, -0.687988f, 0.226562f, -0.687988f, 0.353027f, -0.392578f, 0.584473f,
+-0.687988f, 0.742188f, -0.687988f, 0.52832f, 0, -0.0234375f, 0, -0.00390625f, -0.102051f,
+0.44873f, -0.575195f, 0.125f, -0.575195f, 0.146973f, -0.687988f, 0.64209f, -0.687988f,
+0.622559f, -0.587891f, 0.168457f, -0.112793f, 0.550293f, -0.112793f, -0.0263672f,
+0.20752f, 0.154297f, -0.724609f, 0.418945f, -0.724609f, 0.400879f, -0.631836f, 0.266113f,
+-0.631836f, 0.121094f, 0.114258f, 0.255859f, 0.114258f, 0.237793f, 0.20752f, 0.141113f,
+0.0200195f, 0.0541992f, -0.725098f, 0.17041f, -0.725098f, 0.259766f, 0.0200195f,
+-0.0849609f, 0.20752f, -0.0668945f, 0.114258f, 0.0683594f, 0.114258f, 0.213379f,
+-0.631836f, 0.0776367f, -0.631836f, 0.0957031f, -0.724609f, 0.360352f, -0.724609f,
+0.179199f, 0.20752f, -0.0585938f, 0.12207f, -0.0585938f, 0.0839844f, 0.516113f, 0.0839844f,
+0.516113f, 0.12207f, 0.52002f, -0.00585938f, 0.499512f, 0.00195312f, 0.478516f, 0.00341797f,
+0.45752f, 0.00488281f, 0.435547f, 0.00488281f, 0.386719f, 0.00488281f, 0.360352f,
+-0.015625f, 0.333984f, -0.0361328f, 0.333984f, -0.0698242f, 0.333984f, -0.0771484f,
+0.334473f, -0.0852051f, 0.334961f, -0.0932617f, 0.336426f, -0.101074f, 0.333496f,
+-0.101074f, 0.316895f, -0.0751953f, 0.299805f, -0.0546875f, 0.282715f, -0.0341797f,
+0.261963f, -0.0197754f, 0.241211f, -0.00537109f, 0.215332f, 0.00219727f, 0.189453f,
+0.00976562f, 0.154785f, 0.00976562f, 0.116699f, 0.00976562f, 0.088623f, -0.00244141f,
+0.0605469f, -0.0146484f, 0.0419922f, -0.0349121f, 0.0234375f, -0.0551758f, 0.0141602f,
+-0.081543f, 0.00488281f, -0.10791f, 0.00488281f, -0.135742f, 0.00488281f, -0.175293f,
+0.0158691f, -0.204102f, 0.0268555f, -0.23291f, 0.0458984f, -0.253418f, 0.0649414f,
+-0.273926f, 0.0905762f, -0.286865f, 0.116211f, -0.299805f, 0.145508f, -0.307129f,
+0.174805f, -0.314453f, 0.206543f, -0.317383f, 0.238281f, -0.320312f, 0.269043f, -0.320801f,
+0.362305f, -0.322266f, 0.366211f, -0.339844f, 0.369629f, -0.354492f, 0.371094f, -0.365479f,
+0.372559f, -0.376465f, 0.372559f, -0.38623f, 0.372559f, -0.418457f, 0.355957f, -0.433594f,
+0.339355f, -0.44873f, 0.310547f, -0.44873f, 0.296387f, -0.44873f, 0.28125f, -0.446777f,
+0.266113f, -0.444824f, 0.252686f, -0.437744f, 0.239258f, -0.430664f, 0.228271f, -0.416748f,
+0.217285f, -0.402832f, 0.211426f, -0.379395f, 0.0830078f, -0.394531f, 0.0908203f,
+-0.427246f, 0.108398f, -0.453613f, 0.125977f, -0.47998f, 0.154297f, -0.498779f, 0.182617f,
+-0.517578f, 0.221924f, -0.527832f, 0.26123f, -0.538086f, 0.312988f, -0.538086f, 0.414062f,
+-0.538086f, 0.461182f, -0.502441f, 0.508301f, -0.466797f, 0.508301f, -0.394043f,
+0.508301f, -0.378906f, 0.504395f, -0.35791f, 0.500488f, -0.336914f, 0.496582f, -0.317383f,
+0.461914f, -0.14502f, 0.460449f, -0.136719f, 0.459229f, -0.127197f, 0.458008f, -0.117676f,
+0.458008f, -0.109863f, 0.458008f, -0.0981445f, 0.462891f, -0.0917969f, 0.467773f,
+-0.0854492f, 0.474121f, -0.0825195f, 0.480469f, -0.0795898f, 0.486816f, -0.0788574f,
+0.493164f, -0.078125f, 0.496582f, -0.078125f, 0.503418f, -0.078125f, 0.509521f, -0.0786133f,
+0.515625f, -0.0791016f, 0.526855f, -0.081543f, 0.347168f, -0.245605f, 0.268066f,
+-0.245605f, 0.210938f, -0.244629f, 0.177979f, -0.222168f, 0.14502f, -0.199707f, 0.14502f,
+-0.158691f, 0.14502f, -0.139648f, 0.150879f, -0.125732f, 0.156738f, -0.111816f, 0.166504f,
+-0.103027f, 0.17627f, -0.0942383f, 0.189209f, -0.0900879f, 0.202148f, -0.0859375f,
+0.216309f, -0.0859375f, 0.230469f, -0.0859375f, 0.247803f, -0.0915527f, 0.265137f,
+-0.097168f, 0.281982f, -0.110352f, 0.298828f, -0.123535f, 0.313477f, -0.145752f,
+0.328125f, -0.167969f, 0.336426f, -0.200684f, 0.41748f, -0.538086f, 0.457031f, -0.538086f,
+0.487793f, -0.525879f, 0.518555f, -0.513672f, 0.539307f, -0.491211f, 0.560059f, -0.46875f,
+0.571045f, -0.436768f, 0.582031f, -0.404785f, 0.582031f, -0.365234f, 0.582031f, -0.358398f,
+0.582031f, -0.334961f, 0.57959f, -0.307617f, 0.577148f, -0.280273f, 0.571777f, -0.251953f,
+0.558105f, -0.182617f, 0.536621f, -0.133057f, 0.515137f, -0.0834961f, 0.484619f,
+-0.0517578f, 0.454102f, -0.0200195f, 0.414795f, -0.00512695f, 0.375488f, 0.00976562f,
+0.32666f, 0.00976562f, 0.265625f, 0.00976562f, 0.227539f, -0.015625f, 0.189453f,
+-0.0410156f, 0.173828f, -0.0869141f, 0.172852f, -0.0869141f, 0.169922f, -0.0742188f,
+0.16626f, -0.0598145f, 0.162598f, -0.0454102f, 0.158936f, -0.0327148f, 0.155273f,
+-0.0200195f, 0.152832f, -0.0109863f, 0.150391f, -0.00195312f, 0.149414f, 0, 0.0170898f,
+0, 0.0185547f, -0.00439453f, 0.0209961f, -0.0148926f, 0.0234375f, -0.0253906f, 0.0266113f,
+-0.0400391f, 0.0297852f, -0.0546875f, 0.0336914f, -0.0722656f, 0.0375977f, -0.0898438f,
+0.0410156f, -0.108887f, 0.161133f, -0.724609f, 0.29834f, -0.724609f, 0.257324f, -0.516113f,
+0.250977f, -0.483887f, 0.246582f, -0.464844f, 0.242188f, -0.445801f, 0.241699f, -0.445801f,
+0.243652f, -0.445801f, 0.270996f, -0.486816f, 0.314697f, -0.512451f, 0.358398f, -0.538086f,
+0.41748f, -0.538086f, 0.358887f, -0.442871f, 0.333496f, -0.442871f, 0.310059f, -0.434814f,
+0.286621f, -0.426758f, 0.26709f, -0.407227f, 0.247559f, -0.387695f, 0.232178f, -0.354492f,
+0.216797f, -0.321289f, 0.207031f, -0.270508f, 0.203125f, -0.249023f, 0.200928f, -0.230469f,
+0.19873f, -0.211914f, 0.19873f, -0.195801f, 0.19873f, -0.168457f, 0.205811f, -0.147705f,
+0.212891f, -0.126953f, 0.22583f, -0.112793f, 0.23877f, -0.0986328f, 0.256836f, -0.0915527f,
+0.274902f, -0.0844727f, 0.296875f, -0.0844727f, 0.321777f, -0.0844727f, 0.341553f,
+-0.092041f, 0.361328f, -0.0996094f, 0.377197f, -0.118408f, 0.393066f, -0.137207f,
+0.405518f, -0.169678f, 0.417969f, -0.202148f, 0.428223f, -0.251953f, 0.433594f, -0.276855f,
+0.436279f, -0.298584f, 0.438965f, -0.320312f, 0.438965f, -0.338867f, 0.438965f, -0.390137f,
+0.421631f, -0.416504f, 0.404297f, -0.442871f, 0.358887f, -0.442871f, 0.261719f, -0.0844727f,
+0.302246f, -0.0844727f, 0.328613f, -0.110107f, 0.35498f, -0.135742f, 0.370605f, -0.186035f,
+0.50293f, -0.161621f, 0.491211f, -0.123047f, 0.470947f, -0.0913086f, 0.450684f, -0.0595703f,
+0.420654f, -0.0371094f, 0.390625f, -0.0146484f, 0.349365f, -0.00244141f, 0.308105f,
+0.00976562f, 0.253906f, 0.00976562f, 0.197266f, 0.00976562f, 0.155273f, -0.00537109f,
+0.113281f, -0.0205078f, 0.0856934f, -0.0480957f, 0.0581055f, -0.0756836f, 0.0444336f,
+-0.11377f, 0.0307617f, -0.151855f, 0.0307617f, -0.197754f, 0.0307617f, -0.217285f,
+0.0324707f, -0.240234f, 0.0341797f, -0.263184f, 0.0395508f, -0.285156f, 0.0517578f,
+-0.339355f, 0.0705566f, -0.37915f, 0.0893555f, -0.418945f, 0.112549f, -0.447021f,
+0.135742f, -0.475098f, 0.162598f, -0.49292f, 0.189453f, -0.510742f, 0.217773f, -0.520752f,
+0.246094f, -0.530762f, 0.275146f, -0.534424f, 0.304199f, -0.538086f, 0.332031f, -0.538086f,
+0.384277f, -0.538086f, 0.422363f, -0.523926f, 0.460449f, -0.509766f, 0.486084f, -0.485596f,
+0.511719f, -0.461426f, 0.525146f, -0.429443f, 0.538574f, -0.397461f, 0.541504f, -0.361816f,
+0.402832f, -0.350586f, 0.400391f, -0.394531f, 0.380615f, -0.419189f, 0.36084f, -0.443848f,
+0.321289f, -0.443848f, 0.293945f, -0.443848f, 0.273682f, -0.434814f, 0.253418f, -0.425781f,
+0.237793f, -0.406006f, 0.222168f, -0.38623f, 0.209717f, -0.355225f, 0.197266f, -0.324219f,
+0.186035f, -0.280762f, 0.184082f, -0.270996f, 0.182129f, -0.26001f, 0.180176f, -0.249023f,
+0.178467f, -0.238037f, 0.176758f, -0.227051f, 0.175781f, -0.217041f, 0.174805f, -0.207031f,
+0.174805f, -0.19873f, 0.174805f, -0.139648f, 0.196777f, -0.112061f, 0.21875f, -0.0844727f,
+0.261719f, -0.0844727f, 0.365723f, -0.078125f, 0.348145f, -0.0551758f, 0.32959f,
+-0.0385742f, 0.311035f, -0.0219727f, 0.290283f, -0.0109863f, 0.269531f, 0, 0.245117f,
+0.00512695f, 0.220703f, 0.0102539f, 0.191406f, 0.0102539f, 0.152344f, 0.0102539f,
+0.121826f, -0.00341797f, 0.0913086f, -0.0170898f, 0.0705566f, -0.0415039f, 0.0498047f,
+-0.065918f, 0.0390625f, -0.0996094f, 0.0283203f, -0.133301f, 0.0283203f, -0.172852f,
+0.0283203f, -0.194824f, 0.0305176f, -0.220215f, 0.0327148f, -0.245605f, 0.0385742f,
+-0.276367f, 0.0522461f, -0.345703f, 0.0759277f, -0.395264f, 0.0996094f, -0.444824f,
+0.131104f, -0.476562f, 0.162598f, -0.508301f, 0.201172f, -0.523193f, 0.239746f, -0.538086f,
+0.283203f, -0.538086f, 0.318848f, -0.538086f, 0.344971f, -0.530518f, 0.371094f, -0.522949f,
+0.389404f, -0.509766f, 0.407715f, -0.496582f, 0.419189f, -0.479004f, 0.430664f, -0.461426f,
+0.436523f, -0.441406f, 0.438965f, -0.441406f, 0.439941f, -0.451172f, 0.442871f, -0.470703f,
+0.445801f, -0.490234f, 0.45166f, -0.520508f, 0.492676f, -0.724609f, 0.62793f, -0.724609f,
+0.511719f, -0.112793f, 0.506348f, -0.0830078f, 0.50293f, -0.0546875f, 0.499512f,
+-0.0263672f, 0.497559f, 0, 0.360352f, 0, 0.360352f, -0.00390625f, 0.360596f, -0.0117188f,
+0.36084f, -0.0195312f, 0.361816f, -0.0302734f, 0.362793f, -0.0410156f, 0.364258f,
+-0.0532227f, 0.365723f, -0.0654297f, 0.367676f, -0.078125f, 0.251465f, -0.0839844f,
+0.277344f, -0.0839844f, 0.300537f, -0.092041f, 0.32373f, -0.100098f, 0.343262f, -0.119873f,
+0.362793f, -0.139648f, 0.37793f, -0.173096f, 0.393066f, -0.206543f, 0.402832f, -0.257324f,
+0.406738f, -0.278809f, 0.408936f, -0.297607f, 0.411133f, -0.316406f, 0.411133f, -0.33252f,
+0.411133f, -0.391113f, 0.388184f, -0.417725f, 0.365234f, -0.444336f, 0.319336f, -0.444336f,
+0.296387f, -0.444336f, 0.275391f, -0.436523f, 0.254395f, -0.428711f, 0.236816f, -0.409424f,
+0.219238f, -0.390137f, 0.205078f, -0.357666f, 0.190918f, -0.325195f, 0.182129f, -0.275879f,
+0.177734f, -0.250977f, 0.175537f, -0.230713f, 0.17334f, -0.210449f, 0.17334f, -0.191895f,
+0.17334f, -0.140137f, 0.191895f, -0.112061f, 0.210449f, -0.0839844f, 0.251465f, -0.0839844f,
+0.174805f, -0.232422f, 0.172852f, -0.22168f, 0.172119f, -0.210938f, 0.171387f, -0.200195f,
+0.171387f, -0.188965f, 0.171387f, -0.137207f, 0.194092f, -0.109619f, 0.216797f, -0.0820312f,
+0.26123f, -0.0820312f, 0.281738f, -0.0820312f, 0.297852f, -0.0883789f, 0.313965f,
+-0.0947266f, 0.32666f, -0.105713f, 0.339355f, -0.116699f, 0.348877f, -0.131836f,
+0.358398f, -0.146973f, 0.365234f, -0.164551f, 0.484863f, -0.128418f, 0.470215f, -0.097168f,
+0.45166f, -0.0715332f, 0.433105f, -0.0458984f, 0.40625f, -0.027832f, 0.379395f, -0.00976562f,
+0.341797f, 0, 0.304199f, 0.00976562f, 0.251953f, 0.00976562f, 0.198242f, 0.00976562f,
+0.156982f, -0.00537109f, 0.115723f, -0.0205078f, 0.0876465f, -0.0483398f, 0.0595703f,
+-0.0761719f, 0.045166f, -0.115723f, 0.0307617f, -0.155273f, 0.0307617f, -0.204102f,
+0.0307617f, -0.28418f, 0.052002f, -0.346191f, 0.0732422f, -0.408203f, 0.111084f,
+-0.450928f, 0.148926f, -0.493652f, 0.201172f, -0.515869f, 0.253418f, -0.538086f,
+0.31543f, -0.538086f, 0.370117f, -0.538086f, 0.410156f, -0.523438f, 0.450195f, -0.508789f,
+0.476562f, -0.482178f, 0.50293f, -0.455566f, 0.515625f, -0.418701f, 0.52832f, -0.381836f,
+0.52832f, -0.337402f, 0.52832f, -0.31543f, 0.525146f, -0.286865f, 0.521973f, -0.258301f,
+0.516602f, -0.232422f, 0.401367f, -0.32373f, 0.402344f, -0.331543f, 0.402588f, -0.337891f,
+0.402832f, -0.344238f, 0.402832f, -0.351074f, 0.402832f, -0.40332f, 0.378662f, -0.427246f,
+0.354492f, -0.451172f, 0.31543f, -0.451172f, 0.298828f, -0.451172f, 0.280273f, -0.445801f,
+0.261719f, -0.44043f, 0.244385f, -0.426025f, 0.227051f, -0.411621f, 0.213135f, -0.386963f,
+0.199219f, -0.362305f, 0.190918f, -0.32373f, 0.257812f, -0.435547f, 0.172852f, 0,
+0.0361328f, 0, 0.121094f, -0.435547f, 0.0439453f, -0.435547f, 0.0620117f, -0.52832f,
+0.13916f, -0.52832f, 0.149902f, -0.583496f, 0.15625f, -0.616699f, 0.169189f, -0.643066f,
+0.182129f, -0.669434f, 0.204834f, -0.6875f, 0.227539f, -0.705566f, 0.260742f, -0.715088f,
+0.293945f, -0.724609f, 0.34082f, -0.724609f, 0.362793f, -0.724609f, 0.382568f, -0.721924f,
+0.402344f, -0.719238f, 0.416504f, -0.716309f, 0.398926f, -0.62793f, 0.394531f, -0.628906f,
+0.388428f, -0.629639f, 0.382324f, -0.630371f, 0.375732f, -0.631104f, 0.369141f, -0.631836f,
+0.362793f, -0.632324f, 0.356445f, -0.632812f, 0.352051f, -0.632812f, 0.319336f, -0.632812f,
+0.304688f, -0.617188f, 0.290039f, -0.601562f, 0.283691f, -0.569824f, 0.275879f, -0.52832f,
+0.379883f, -0.52832f, 0.361816f, -0.435547f, 0.210449f, 0.20752f, 0.15918f, 0.20752f,
+0.121582f, 0.198486f, 0.0839844f, 0.189453f, 0.0581055f, 0.171875f, 0.0322266f, 0.154297f,
+0.017334f, 0.128662f, 0.00244141f, 0.103027f, -0.00341797f, 0.0693359f, 0.134766f,
+0.0546875f, 0.141602f, 0.0869141f, 0.164551f, 0.101807f, 0.1875f, 0.116699f, 0.226562f,
+0.116699f, 0.254883f, 0.116699f, 0.275879f, 0.109131f, 0.296875f, 0.101562f, 0.312256f,
+0.0856934f, 0.327637f, 0.0698242f, 0.338135f, 0.045166f, 0.348633f, 0.0205078f, 0.356445f,
+-0.0131836f, 0.359375f, -0.0273438f, 0.362061f, -0.0422363f, 0.364746f, -0.0571289f,
+0.367188f, -0.0698242f, 0.369629f, -0.0844727f, 0.371582f, -0.0981445f, 0.370605f,
+-0.0981445f, 0.356934f, -0.0786133f, 0.341553f, -0.0600586f, 0.326172f, -0.0415039f,
+0.305908f, -0.0273438f, 0.285645f, -0.0131836f, 0.259277f, -0.00463867f, 0.23291f,
+0.00390625f, 0.197754f, 0.00390625f, 0.15918f, 0.00390625f, 0.128174f, -0.00927734f,
+0.097168f, -0.0224609f, 0.0759277f, -0.0458984f, 0.0546875f, -0.0693359f, 0.0432129f,
+-0.102051f, 0.0317383f, -0.134766f, 0.0317383f, -0.173828f, 0.0317383f, -0.197754f,
+0.0339355f, -0.225098f, 0.0361328f, -0.252441f, 0.0419922f, -0.283203f, 0.0668945f,
+-0.410645f, 0.125732f, -0.474121f, 0.18457f, -0.537598f, 0.286133f, -0.537598f, 0.313965f,
+-0.537598f, 0.339111f, -0.530762f, 0.364258f, -0.523926f, 0.384277f, -0.510986f,
+0.404297f, -0.498047f, 0.418701f, -0.479248f, 0.433105f, -0.460449f, 0.439941f, -0.436035f,
+0.440918f, -0.436035f, 0.443359f, -0.44873f, 0.447021f, -0.463867f, 0.450684f, -0.479004f,
+0.454102f, -0.49292f, 0.45752f, -0.506836f, 0.460449f, -0.516846f, 0.463379f, -0.526855f,
+0.464355f, -0.52832f, 0.59375f, -0.52832f, 0.592773f, -0.523926f, 0.590332f, -0.513184f,
+0.587891f, -0.502441f, 0.584473f, -0.487549f, 0.581055f, -0.472656f, 0.577393f, -0.454346f,
+0.57373f, -0.436035f, 0.569824f, -0.416504f, 0.489258f, -0.00488281f, 0.478516f,
+0.0478516f, 0.458496f, 0.0876465f, 0.438477f, 0.127441f, 0.405518f, 0.154053f, 0.372559f,
+0.180664f, 0.324707f, 0.194092f, 0.276855f, 0.20752f, 0.210449f, 0.20752f, 0.406738f,
+-0.267578f, 0.410156f, -0.284668f, 0.411621f, -0.303223f, 0.413086f, -0.321777f,
+0.413086f, -0.334961f, 0.413086f, -0.362793f, 0.405762f, -0.383057f, 0.398438f, -0.40332f,
+0.385498f, -0.416992f, 0.372559f, -0.430664f, 0.354736f, -0.437256f, 0.336914f, -0.443848f,
+0.316406f, -0.443848f, 0.291504f, -0.443848f, 0.27124f, -0.436279f, 0.250977f, -0.428711f,
+0.235107f, -0.4104f, 0.219238f, -0.39209f, 0.207031f, -0.361084f, 0.194824f, -0.330078f,
+0.186035f, -0.283691f, 0.181641f, -0.259277f, 0.178467f, -0.235352f, 0.175293f, -0.211426f,
+0.175293f, -0.193359f, 0.175293f, -0.143066f, 0.197021f, -0.119629f, 0.21875f, -0.0961914f,
+0.259766f, -0.0961914f, 0.28125f, -0.0961914f, 0.303711f, -0.105713f, 0.326172f,
+-0.115234f, 0.346191f, -0.135986f, 0.366211f, -0.156738f, 0.38208f, -0.189209f, 0.397949f,
+-0.22168f, 0.406738f, -0.267578f, 0.293457f, -0.724609f, 0.254883f, -0.526855f, 0.25293f,
+-0.516602f, 0.250488f, -0.504639f, 0.248047f, -0.492676f, 0.245361f, -0.480957f,
+0.242676f, -0.469238f, 0.240234f, -0.458008f, 0.237793f, -0.446777f, 0.23584f, -0.437988f,
+0.237305f, -0.437988f, 0.251953f, -0.458496f, 0.269775f, -0.476562f, 0.287598f, -0.494629f,
+0.30957f, -0.508301f, 0.331543f, -0.521973f, 0.358643f, -0.529785f, 0.385742f, -0.537598f,
+0.419434f, -0.537598f, 0.493652f, -0.537598f, 0.53125f, -0.501953f, 0.568848f, -0.466309f,
+0.568848f, -0.398926f, 0.568848f, -0.390137f, 0.567627f, -0.378906f, 0.566406f, -0.367676f,
+0.564941f, -0.356689f, 0.563477f, -0.345703f, 0.561768f, -0.335693f, 0.560059f, -0.325684f,
+0.558594f, -0.318848f, 0.496582f, 0, 0.360352f, 0, 0.417969f, -0.290527f, 0.419922f,
+-0.299805f, 0.422119f, -0.311035f, 0.424316f, -0.322266f, 0.42627f, -0.333496f, 0.428223f,
+-0.344727f, 0.429443f, -0.354736f, 0.430664f, -0.364746f, 0.430664f, -0.371094f,
+0.430664f, -0.401855f, 0.411865f, -0.417969f, 0.393066f, -0.434082f, 0.356445f, -0.434082f,
+0.333496f, -0.434082f, 0.310547f, -0.424316f, 0.287598f, -0.414551f, 0.267822f, -0.396484f,
+0.248047f, -0.378418f, 0.233154f, -0.352783f, 0.218262f, -0.327148f, 0.212402f, -0.295898f,
+0.154785f, 0, 0.0170898f, 0, 0.156738f, -0.724609f, 0.137695f, -0.623535f, 0.157715f,
+-0.724609f, 0.294922f, -0.724609f, 0.274902f, -0.623535f, 0.0170898f, 0, 0.119629f,
+-0.52832f, 0.256836f, -0.52832f, 0.153809f, 0, 0.138184f, -0.623535f, 0.157715f,
+-0.724609f, 0.294922f, -0.724609f, 0.275391f, -0.623535f, -0.0263672f, 0.20752f,
+-0.0507812f, 0.20752f, -0.0717773f, 0.204834f, -0.0927734f, 0.202148f, -0.107422f,
+0.198242f, -0.0898438f, 0.106445f, -0.0834961f, 0.107422f, -0.0754395f, 0.10791f,
+-0.0673828f, 0.108398f, -0.0615234f, 0.108398f, -0.0449219f, 0.108398f, -0.0332031f,
+0.104492f, -0.0214844f, 0.100586f, -0.0131836f, 0.0913086f, -0.00488281f, 0.0820312f,
+0.000732422f, 0.0668945f, 0.00634766f, 0.0517578f, 0.0107422f, 0.0292969f, 0.119629f,
+-0.52832f, 0.256836f, -0.52832f, 0.141602f, 0.0625f, 0.135254f, 0.0942383f, 0.122314f,
+0.120605f, 0.109375f, 0.146973f, 0.0888672f, 0.166504f, 0.0683594f, 0.186035f, 0.0397949f,
+0.196777f, 0.0112305f, 0.20752f, -0.0263672f, 0.20752f, 0.355469f, 0, 0.263672f,
+-0.242676f, 0.195312f, -0.206055f, 0.153809f, 0, 0.0170898f, 0, 0.157715f, -0.724609f,
+0.294922f, -0.724609f, 0.213379f, -0.30957f, 0.44043f, -0.52832f, 0.597656f, -0.52832f,
+0.366699f, -0.322266f, 0.500977f, 0, 0.0170898f, 0, 0.157715f, -0.724609f, 0.294922f,
+-0.724609f, 0.153809f, 0, 0.645508f, -0.435547f, 0.623535f, -0.435547f, 0.60376f,
+-0.425781f, 0.583984f, -0.416016f, 0.568115f, -0.397705f, 0.552246f, -0.379395f,
+0.540771f, -0.35376f, 0.529297f, -0.328125f, 0.522949f, -0.296387f, 0.464844f, 0,
+0.328613f, 0, 0.388672f, -0.310059f, 0.390137f, -0.317871f, 0.391602f, -0.326904f,
+0.393066f, -0.335938f, 0.394287f, -0.345215f, 0.395508f, -0.354492f, 0.39624f, -0.362549f,
+0.396973f, -0.370605f, 0.396973f, -0.376465f, 0.396973f, -0.435547f, 0.335449f, -0.435547f,
+0.312988f, -0.435547f, 0.293457f, -0.425537f, 0.273926f, -0.415527f, 0.257812f, -0.397217f,
+0.241699f, -0.378906f, 0.230225f, -0.352783f, 0.21875f, -0.32666f, 0.212402f, -0.294922f,
+0.154785f, 0, 0.0170898f, 0, 0.0981445f, -0.415527f, 0.101562f, -0.432129f, 0.104736f,
+-0.450439f, 0.10791f, -0.46875f, 0.110596f, -0.485107f, 0.113281f, -0.501465f, 0.11499f,
+-0.513184f, 0.116699f, -0.524902f, 0.117188f, -0.52832f, 0.25f, -0.52832f, 0.25f,
+-0.525879f, 0.248535f, -0.515137f, 0.24707f, -0.504395f, 0.244873f, -0.490479f, 0.242676f,
+-0.476562f, 0.240479f, -0.462158f, 0.238281f, -0.447754f, 0.236328f, -0.437988f,
+0.237793f, -0.437988f, 0.25293f, -0.460938f, 0.268799f, -0.479492f, 0.284668f, -0.498047f,
+0.303467f, -0.510986f, 0.322266f, -0.523926f, 0.345459f, -0.530762f, 0.368652f, -0.537598f,
+0.397949f, -0.537598f, 0.458496f, -0.537598f, 0.493652f, -0.508545f, 0.528809f, -0.479492f,
+0.535645f, -0.424316f, 0.55127f, -0.44873f, 0.568359f, -0.469238f, 0.585449f, -0.489746f,
+0.605957f, -0.505127f, 0.626465f, -0.520508f, 0.651611f, -0.529053f, 0.676758f, -0.537598f,
+0.708496f, -0.537598f, 0.775879f, -0.537598f, 0.811768f, -0.501953f, 0.847656f, -0.466309f,
+0.847656f, -0.398926f, 0.847656f, -0.381348f, 0.844482f, -0.359375f, 0.841309f, -0.337402f,
+0.837402f, -0.318848f, 0.774902f, 0, 0.638672f, 0, 0.698242f, -0.306152f, 0.699707f,
+-0.313477f, 0.701172f, -0.32251f, 0.702637f, -0.331543f, 0.704102f, -0.340576f, 0.705566f,
+-0.349609f, 0.706299f, -0.358398f, 0.707031f, -0.367188f, 0.707031f, -0.374023f,
+0.707031f, -0.376465f, 0.705566f, -0.435547f, 0.645508f, -0.435547f, 0.360352f, 0,
+0.417969f, -0.290527f, 0.419922f, -0.299805f, 0.422119f, -0.311035f, 0.424316f, -0.322266f,
+0.42627f, -0.333496f, 0.428223f, -0.344727f, 0.429443f, -0.354736f, 0.430664f, -0.364746f,
+0.430664f, -0.371094f, 0.430664f, -0.401855f, 0.412109f, -0.417969f, 0.393555f, -0.434082f,
+0.356445f, -0.434082f, 0.333496f, -0.434082f, 0.310547f, -0.424316f, 0.287598f, -0.414551f,
+0.267822f, -0.396484f, 0.248047f, -0.378418f, 0.233154f, -0.352783f, 0.218262f, -0.327148f,
+0.212402f, -0.295898f, 0.154785f, 0, 0.0170898f, 0, 0.0981445f, -0.415527f, 0.101562f,
+-0.432129f, 0.104736f, -0.450439f, 0.10791f, -0.46875f, 0.110352f, -0.485107f, 0.112793f,
+-0.501465f, 0.114502f, -0.513184f, 0.116211f, -0.524902f, 0.116699f, -0.52832f, 0.247559f,
+-0.52832f, 0.247559f, -0.525879f, 0.246338f, -0.515137f, 0.245117f, -0.504395f, 0.243408f,
+-0.490479f, 0.241699f, -0.476562f, 0.239746f, -0.462158f, 0.237793f, -0.447754f,
+0.23584f, -0.437988f, 0.237305f, -0.437988f, 0.251953f, -0.458496f, 0.269775f, -0.476562f,
+0.287598f, -0.494629f, 0.30957f, -0.508301f, 0.331543f, -0.521973f, 0.358643f, -0.529785f,
+0.385742f, -0.537598f, 0.419434f, -0.537598f, 0.493652f, -0.537598f, 0.53125f, -0.501953f,
+0.568848f, -0.466309f, 0.568848f, -0.398926f, 0.568848f, -0.390137f, 0.567627f, -0.378906f,
+0.566406f, -0.367676f, 0.564941f, -0.356689f, 0.563477f, -0.345703f, 0.561768f, -0.335693f,
+0.560059f, -0.325684f, 0.558594f, -0.318848f, 0.496582f, 0, 0.578613f, -0.333496f,
+0.578613f, -0.253906f, 0.554688f, -0.190186f, 0.530762f, -0.126465f, 0.488281f, -0.0820312f,
+0.445801f, -0.0375977f, 0.387695f, -0.013916f, 0.32959f, 0.00976562f, 0.26123f, 0.00976562f,
+0.208984f, 0.00976562f, 0.166504f, -0.00463867f, 0.124023f, -0.019043f, 0.09375f,
+-0.0466309f, 0.0634766f, -0.0742188f, 0.0471191f, -0.114014f, 0.0307617f, -0.153809f,
+0.0307617f, -0.20459f, 0.0307617f, -0.280273f, 0.0534668f, -0.341797f, 0.0761719f,
+-0.40332f, 0.117676f, -0.446777f, 0.15918f, -0.490234f, 0.216797f, -0.513916f, 0.274414f,
+-0.537598f, 0.34375f, -0.537598f, 0.401367f, -0.537598f, 0.445312f, -0.523926f, 0.489258f,
+-0.510254f, 0.518799f, -0.483887f, 0.54834f, -0.45752f, 0.563477f, -0.419678f, 0.578613f,
+-0.381836f, 0.578613f, -0.333496f, 0.435059f, -0.323242f, 0.435059f, -0.355469f,
+0.427979f, -0.378418f, 0.420898f, -0.401367f, 0.407715f, -0.415771f, 0.394531f, -0.430176f,
+0.375732f, -0.437012f, 0.356934f, -0.443848f, 0.333496f, -0.443848f, 0.312012f, -0.443848f,
+0.290039f, -0.438721f, 0.268066f, -0.433594f, 0.248291f, -0.41748f, 0.228516f, -0.401367f,
+0.212158f, -0.371582f, 0.195801f, -0.341797f, 0.18457f, -0.292969f, 0.179199f, -0.269531f,
+0.177002f, -0.248779f, 0.174805f, -0.228027f, 0.174805f, -0.210449f, 0.174805f, -0.175293f,
+0.182373f, -0.151367f, 0.189941f, -0.127441f, 0.203613f, -0.112305f, 0.217285f, -0.097168f,
+0.23584f, -0.0905762f, 0.254395f, -0.0839844f, 0.276367f, -0.0839844f, 0.29834f,
+-0.0839844f, 0.319824f, -0.0888672f, 0.341309f, -0.09375f, 0.36084f, -0.109619f,
+0.380371f, -0.125488f, 0.396484f, -0.155029f, 0.412598f, -0.18457f, 0.423828f, -0.234375f,
+0.429199f, -0.259766f, 0.431641f, -0.281006f, 0.434082f, -0.302246f, 0.435059f, -0.323242f,
+0.355469f, -0.442871f, 0.330078f, -0.442871f, 0.306641f, -0.434814f, 0.283203f, -0.426758f,
+0.263672f, -0.407227f, 0.244141f, -0.387695f, 0.22876f, -0.354492f, 0.213379f, -0.321289f,
+0.203613f, -0.270508f, 0.199707f, -0.249023f, 0.19751f, -0.230469f, 0.195312f, -0.211914f,
+0.195312f, -0.195801f, 0.195312f, -0.168457f, 0.202393f, -0.147705f, 0.209473f, -0.126953f,
+0.222412f, -0.112793f, 0.235352f, -0.0986328f, 0.253418f, -0.0915527f, 0.271484f,
+-0.0844727f, 0.293457f, -0.0844727f, 0.318359f, -0.0844727f, 0.338623f, -0.0922852f,
+0.358887f, -0.100098f, 0.375f, -0.119141f, 0.391113f, -0.138184f, 0.403564f, -0.170654f,
+0.416016f, -0.203125f, 0.424805f, -0.251953f, 0.429199f, -0.276855f, 0.431641f, -0.298584f,
+0.434082f, -0.320312f, 0.434082f, -0.338867f, 0.434082f, -0.390625f, 0.415283f, -0.416748f,
+0.396484f, -0.442871f, 0.355469f, -0.442871f, 0.240723f, -0.445801f, 0.257812f, -0.469727f,
+0.275879f, -0.487061f, 0.293945f, -0.504395f, 0.314941f, -0.515869f, 0.335938f, -0.527344f,
+0.360352f, -0.532715f, 0.384766f, -0.538086f, 0.414062f, -0.538086f, 0.453613f, -0.538086f,
+0.484375f, -0.525879f, 0.515137f, -0.513672f, 0.535889f, -0.491211f, 0.556641f, -0.46875f,
+0.567627f, -0.436768f, 0.578613f, -0.404785f, 0.578613f, -0.365234f, 0.578613f, -0.336426f,
+0.576172f, -0.30835f, 0.57373f, -0.280273f, 0.568359f, -0.251953f, 0.554688f, -0.182617f,
+0.533203f, -0.133057f, 0.511719f, -0.0834961f, 0.481201f, -0.0517578f, 0.450684f,
+-0.0200195f, 0.411377f, -0.00512695f, 0.37207f, 0.00976562f, 0.323242f, 0.00976562f,
+0.262207f, 0.00976562f, 0.224121f, -0.015625f, 0.186035f, -0.0410156f, 0.17041f,
+-0.0869141f, 0.169434f, -0.0869141f, 0.166992f, -0.0664062f, 0.162598f, -0.0419922f,
+0.158203f, -0.0175781f, 0.153809f, 0.00488281f, 0.114746f, 0.20752f, -0.0219727f,
+0.20752f, 0.0966797f, -0.406738f, 0.100098f, -0.423828f, 0.102295f, -0.435791f, 0.104492f,
+-0.447754f, 0.106201f, -0.460205f, 0.10791f, -0.472656f, 0.110107f, -0.488281f, 0.112305f,
+-0.503906f, 0.115723f, -0.52832f, 0.25f, -0.52832f, 0.25f, -0.525391f, 0.249023f,
+-0.515625f, 0.248047f, -0.505859f, 0.246582f, -0.493408f, 0.245117f, -0.480957f,
+0.243164f, -0.468018f, 0.241211f, -0.455078f, 0.23877f, -0.445801f, 0.438477f, -0.440918f,
+0.440918f, -0.453125f, 0.444092f, -0.466553f, 0.447266f, -0.47998f, 0.450439f, -0.491943f,
+0.453613f, -0.503906f, 0.456543f, -0.513672f, 0.459473f, -0.523438f, 0.461426f, -0.52832f,
+0.593262f, -0.52832f, 0.59082f, -0.52002f, 0.583252f, -0.485352f, 0.575684f, -0.450684f,
+0.563477f, -0.388184f, 0.448242f, 0.20752f, 0.311035f, 0.20752f, 0.352539f, -0.00341797f,
+0.355957f, -0.0195312f, 0.360352f, -0.0385742f, 0.364746f, -0.0576172f, 0.370117f,
+-0.0795898f, 0.368164f, -0.0795898f, 0.350586f, -0.0566406f, 0.332031f, -0.0397949f,
+0.313477f, -0.0229492f, 0.292236f, -0.0117188f, 0.270996f, -0.000488281f, 0.246338f,
+0.00488281f, 0.22168f, 0.0102539f, 0.192383f, 0.0102539f, 0.152832f, 0.0102539f,
+0.122559f, -0.00317383f, 0.0922852f, -0.0166016f, 0.0712891f, -0.0402832f, 0.050293f,
+-0.0639648f, 0.0395508f, -0.097168f, 0.0288086f, -0.130371f, 0.0288086f, -0.169922f,
+0.0288086f, -0.191895f, 0.0310059f, -0.218506f, 0.0332031f, -0.245117f, 0.0390625f,
+-0.275879f, 0.0527344f, -0.345703f, 0.0766602f, -0.395508f, 0.100586f, -0.445312f,
+0.132324f, -0.477051f, 0.164062f, -0.508789f, 0.202393f, -0.523438f, 0.240723f, -0.538086f,
+0.283203f, -0.538086f, 0.31543f, -0.538086f, 0.3396f, -0.532715f, 0.36377f, -0.527344f,
+0.381836f, -0.515625f, 0.399902f, -0.503906f, 0.413086f, -0.485352f, 0.42627f, -0.466797f,
+0.436035f, -0.440918f, 0.25293f, -0.0839844f, 0.278809f, -0.0839844f, 0.302002f,
+-0.092041f, 0.325195f, -0.100098f, 0.344727f, -0.119873f, 0.364258f, -0.139648f,
+0.379395f, -0.173096f, 0.394531f, -0.206543f, 0.403809f, -0.257324f, 0.407715f, -0.278809f,
+0.409668f, -0.297363f, 0.411621f, -0.315918f, 0.411621f, -0.332031f, 0.411621f, -0.386719f,
+0.391357f, -0.415527f, 0.371094f, -0.444336f, 0.32666f, -0.444336f, 0.300781f, -0.444336f,
+0.278564f, -0.436768f, 0.256348f, -0.429199f, 0.238037f, -0.410156f, 0.219727f, -0.391113f,
+0.205811f, -0.358643f, 0.191895f, -0.326172f, 0.182617f, -0.275879f, 0.177734f, -0.250488f,
+0.175781f, -0.22876f, 0.173828f, -0.207031f, 0.173828f, -0.188477f, 0.173828f, -0.164551f,
+0.178467f, -0.145264f, 0.183105f, -0.125977f, 0.192627f, -0.112305f, 0.202148f, -0.0986328f,
+0.217041f, -0.0913086f, 0.231934f, -0.0839844f, 0.25293f, -0.0839844f, 0.412109f,
+-0.416504f, 0.400879f, -0.418945f, 0.388184f, -0.421387f, 0.375488f, -0.423828f,
+0.356445f, -0.423828f, 0.296387f, -0.423828f, 0.258545f, -0.381348f, 0.220703f, -0.338867f,
+0.203613f, -0.250977f, 0.154297f, 0, 0.0170898f, 0, 0.0957031f, -0.405273f, 0.0991211f,
+-0.422363f, 0.102051f, -0.439453f, 0.10498f, -0.456543f, 0.107666f, -0.472656f, 0.110352f,
+-0.48877f, 0.112549f, -0.503174f, 0.114746f, -0.517578f, 0.116211f, -0.52832f, 0.24707f,
+-0.52832f, 0.245605f, -0.517578f, 0.243896f, -0.50293f, 0.242188f, -0.488281f, 0.240234f,
+-0.473145f, 0.238281f, -0.458008f, 0.236084f, -0.444092f, 0.233887f, -0.430176f,
+0.232422f, -0.42041f, 0.234375f, -0.42041f, 0.250977f, -0.450684f, 0.267334f, -0.4729f,
+0.283691f, -0.495117f, 0.301514f, -0.509521f, 0.319336f, -0.523926f, 0.3396f, -0.531006f,
+0.359863f, -0.538086f, 0.384277f, -0.538086f, 0.390137f, -0.538086f, 0.397217f, -0.537354f,
+0.404297f, -0.536621f, 0.411377f, -0.535645f, 0.418457f, -0.534668f, 0.424561f, -0.533447f,
+0.430664f, -0.532227f, 0.43457f, -0.53125f, 0.488281f, -0.163086f, 0.488281f, -0.119629f,
+0.471924f, -0.0871582f, 0.455566f, -0.0546875f, 0.424072f, -0.0332031f, 0.392578f,
+-0.0117188f, 0.346924f, -0.000976562f, 0.30127f, 0.00976562f, 0.242676f, 0.00976562f,
+0.144531f, 0.00976562f, 0.0878906f, -0.0249023f, 0.03125f, -0.0595703f, 0.0112305f,
+-0.132324f, 0.133789f, -0.149902f, 0.138672f, -0.132324f, 0.147461f, -0.119385f,
+0.15625f, -0.106445f, 0.17041f, -0.0979004f, 0.18457f, -0.0893555f, 0.204834f, -0.0852051f,
+0.225098f, -0.0810547f, 0.252441f, -0.0810547f, 0.276367f, -0.0810547f, 0.296143f,
+-0.0847168f, 0.315918f, -0.0883789f, 0.330322f, -0.0964355f, 0.344727f, -0.104492f,
+0.352783f, -0.117188f, 0.36084f, -0.129883f, 0.36084f, -0.147461f, 0.36084f, -0.163086f,
+0.354248f, -0.173096f, 0.347656f, -0.183105f, 0.334229f, -0.190186f, 0.320801f, -0.197266f,
+0.300049f, -0.202881f, 0.279297f, -0.208496f, 0.251465f, -0.214355f, 0.212891f, -0.223145f,
+0.18042f, -0.235352f, 0.147949f, -0.247559f, 0.124512f, -0.266357f, 0.101074f, -0.285156f,
+0.0878906f, -0.311768f, 0.074707f, -0.338379f, 0.074707f, -0.375488f, 0.074707f,
+-0.419434f, 0.0930176f, -0.449951f, 0.111328f, -0.480469f, 0.143311f, -0.499756f,
+0.175293f, -0.519043f, 0.218262f, -0.527832f, 0.26123f, -0.536621f, 0.311035f, -0.536621f,
+0.356445f, -0.536621f, 0.392822f, -0.529541f, 0.429199f, -0.522461f, 0.455566f, -0.505859f,
+0.481934f, -0.489258f, 0.498779f, -0.462402f, 0.515625f, -0.435547f, 0.521973f, -0.395996f,
+0.399414f, -0.381836f, 0.391113f, -0.415527f, 0.367188f, -0.430664f, 0.343262f, -0.445801f,
+0.301758f, -0.445801f, 0.280762f, -0.445801f, 0.262451f, -0.443115f, 0.244141f, -0.44043f,
+0.230713f, -0.433594f, 0.217285f, -0.426758f, 0.209473f, -0.415527f, 0.20166f, -0.404297f,
+0.20166f, -0.387207f, 0.20166f, -0.371582f, 0.210938f, -0.361084f, 0.220215f, -0.350586f,
+0.236816f, -0.343018f, 0.253418f, -0.335449f, 0.276367f, -0.329834f, 0.299316f, -0.324219f,
+0.326172f, -0.317871f, 0.360352f, -0.310059f, 0.389893f, -0.298828f, 0.419434f, -0.287598f,
+0.441406f, -0.269775f, 0.463379f, -0.251953f, 0.47583f, -0.226074f, 0.488281f, -0.200195f,
+0.488281f, -0.163086f, 0.273438f, -0.00390625f, 0.255371f, 0.00146484f, 0.232422f,
+0.00463867f, 0.209473f, 0.0078125f, 0.183594f, 0.0078125f, 0.154785f, 0.0078125f,
+0.131348f, 0.000976562f, 0.10791f, -0.00585938f, 0.0913086f, -0.0195312f, 0.074707f,
+-0.0332031f, 0.0656738f, -0.0539551f, 0.0566406f, -0.074707f, 0.0566406f, -0.102051f,
+0.0566406f, -0.124023f, 0.0593262f, -0.144775f, 0.0620117f, -0.165527f, 0.0644531f,
+-0.178711f, 0.114258f, -0.435547f, 0.0419922f, -0.435547f, 0.0600586f, -0.52832f,
+0.13916f, -0.52832f, 0.206055f, -0.652344f, 0.291992f, -0.652344f, 0.268555f, -0.52832f,
+0.367188f, -0.52832f, 0.350098f, -0.435547f, 0.25f, -0.435547f, 0.199219f, -0.174316f,
+0.197266f, -0.164551f, 0.195312f, -0.150635f, 0.193359f, -0.136719f, 0.193848f, -0.126953f,
+0.194824f, -0.106445f, 0.206299f, -0.0964355f, 0.217773f, -0.0864258f, 0.236328f,
+-0.0864258f, 0.248047f, -0.0864258f, 0.26001f, -0.0881348f, 0.271973f, -0.0898438f,
+0.289062f, -0.0927734f, 0.25f, -0.52832f, 0.192383f, -0.237793f, 0.19043f, -0.228516f,
+0.188232f, -0.217285f, 0.186035f, -0.206055f, 0.184082f, -0.194824f, 0.182129f, -0.183594f,
+0.180908f, -0.173828f, 0.179688f, -0.164062f, 0.179688f, -0.157227f, 0.179688f, -0.126465f,
+0.198242f, -0.110352f, 0.216797f, -0.0942383f, 0.253906f, -0.0942383f, 0.276855f,
+-0.0942383f, 0.300049f, -0.104004f, 0.323242f, -0.11377f, 0.343018f, -0.131836f,
+0.362793f, -0.149902f, 0.377441f, -0.175537f, 0.39209f, -0.201172f, 0.397949f, -0.232422f,
+0.455566f, -0.52832f, 0.593262f, -0.52832f, 0.512207f, -0.112793f, 0.508789f, -0.0961914f,
+0.505615f, -0.0778809f, 0.502441f, -0.0595703f, 0.5f, -0.0432129f, 0.497559f, -0.0268555f,
+0.49585f, -0.0151367f, 0.494141f, -0.00341797f, 0.493652f, 0, 0.362793f, 0, 0.362793f,
+-0.00244141f, 0.364014f, -0.0131836f, 0.365234f, -0.0239258f, 0.366943f, -0.0378418f,
+0.368652f, -0.0517578f, 0.370605f, -0.0661621f, 0.372559f, -0.0805664f, 0.374512f,
+-0.090332f, 0.373047f, -0.090332f, 0.358398f, -0.0698242f, 0.34082f, -0.0517578f,
+0.323242f, -0.0336914f, 0.30127f, -0.0200195f, 0.279297f, -0.00634766f, 0.251953f,
+0.00146484f, 0.224609f, 0.00927734f, 0.190918f, 0.00927734f, 0.116699f, 0.00927734f,
+0.0791016f, -0.0263672f, 0.0415039f, -0.0620117f, 0.0415039f, -0.129395f, 0.0415039f,
+-0.138184f, 0.0427246f, -0.149414f, 0.0439453f, -0.160645f, 0.0454102f, -0.171631f,
+0.046875f, -0.182617f, 0.048584f, -0.192871f, 0.050293f, -0.203125f, 0.0517578f,
+-0.209473f, 0.11377f, -0.52832f, 0.303711f, 0, 0.139648f, 0, 0.0537109f, -0.52832f,
+0.194824f, -0.52832f, 0.229492f, -0.23291f, 0.231445f, -0.218262f, 0.23291f, -0.200684f,
+0.234375f, -0.183105f, 0.23584f, -0.165527f, 0.237305f, -0.147949f, 0.238525f, -0.131348f,
+0.239746f, -0.114746f, 0.240234f, -0.101562f, 0.245605f, -0.114258f, 0.252686f, -0.130859f,
+0.259766f, -0.147461f, 0.267822f, -0.165039f, 0.275879f, -0.182617f, 0.28418f, -0.199707f,
+0.29248f, -0.216797f, 0.299805f, -0.231445f, 0.454102f, -0.52832f, 0.601562f, -0.52832f,
+0.589355f, 0, 0.444336f, 0, 0.42334f, -0.322266f, 0.422363f, -0.337402f, 0.422119f,
+-0.356934f, 0.421875f, -0.376465f, 0.421387f, -0.393555f, 0.420898f, -0.413574f,
+0.420898f, -0.43457f, 0.413086f, -0.413574f, 0.404785f, -0.393555f, 0.397949f, -0.376465f,
+0.389893f, -0.356689f, 0.381836f, -0.336914f, 0.374512f, -0.321289f, 0.227051f, 0,
+0.0820312f, 0, 0.0483398f, -0.52832f, 0.174316f, -0.52832f, 0.180664f, -0.217773f,
+0.181152f, -0.20459f, 0.181152f, -0.188232f, 0.181152f, -0.171875f, 0.181152f, -0.157715f,
+0.181152f, -0.124512f, 0.1875f, -0.141113f, 0.194336f, -0.157715f, 0.200195f, -0.171875f,
+0.206787f, -0.188232f, 0.213379f, -0.20459f, 0.219727f, -0.217773f, 0.363281f, -0.52832f,
+0.510254f, -0.52832f, 0.530762f, -0.217773f, 0.531738f, -0.205078f, 0.531982f, -0.188965f,
+0.532227f, -0.172852f, 0.532715f, -0.158691f, 0.533203f, -0.14209f, 0.533203f, -0.124512f,
+0.540039f, -0.14209f, 0.546875f, -0.158691f, 0.552734f, -0.172852f, 0.559082f, -0.188965f,
+0.56543f, -0.205078f, 0.570801f, -0.217773f, 0.701172f, -0.52832f, 0.831055f, -0.52832f,
+0.353516f, 0, 0.262695f, -0.187012f, 0.103027f, 0, -0.0439453f, 0, 0.204102f, -0.274414f,
+0.0678711f, -0.52832f, 0.210449f, -0.52832f, 0.294922f, -0.358887f, 0.439453f, -0.52832f,
+0.589844f, -0.52832f, 0.354004f, -0.271973f, 0.497559f, 0, 0.27832f, 0.027832f, 0.250977f,
+0.0703125f, 0.226318f, 0.103516f, 0.20166f, 0.136719f, 0.174561f, 0.159912f, 0.147461f,
+0.183105f, 0.115723f, 0.195312f, 0.0839844f, 0.20752f, 0.0429688f, 0.20752f, 0.0175781f,
+0.20752f, -0.00268555f, 0.205322f, -0.0229492f, 0.203125f, -0.0415039f, 0.19873f,
+-0.0229492f, 0.103027f, -0.0141602f, 0.10498f, -0.00219727f, 0.106201f, 0.00976562f,
+0.107422f, 0.0195312f, 0.107422f, 0.0380859f, 0.107422f, 0.0539551f, 0.102539f, 0.0698242f,
+0.0976562f, 0.0849609f, 0.0864258f, 0.100098f, 0.0751953f, 0.114746f, 0.0568848f,
+0.129395f, 0.0385742f, 0.144531f, 0.0117188f, 0.158203f, -0.0117188f, 0.0546875f,
+-0.52832f, 0.196777f, -0.52832f, 0.231445f, -0.285645f, 0.232422f, -0.280273f, 0.234131f,
+-0.267578f, 0.23584f, -0.254883f, 0.237549f, -0.238525f, 0.239258f, -0.222168f, 0.241211f,
+-0.204102f, 0.243164f, -0.186035f, 0.244629f, -0.169678f, 0.246094f, -0.15332f, 0.247314f,
+-0.140625f, 0.248535f, -0.12793f, 0.248535f, -0.122559f, 0.250977f, -0.12793f, 0.256592f,
+-0.140381f, 0.262207f, -0.152832f, 0.269775f, -0.168701f, 0.277344f, -0.18457f, 0.285645f,
+-0.202148f, 0.293945f, -0.219727f, 0.301514f, -0.23584f, 0.309082f, -0.251953f, 0.31543f,
+-0.264893f, 0.321777f, -0.277832f, 0.324707f, -0.283691f, 0.451172f, -0.52832f, 0.597656f,
+-0.52832f, -0.0170898f, 0, 0.00146484f, -0.097168f, 0.320312f, -0.429199f, 0.0859375f,
+-0.429199f, 0.105469f, -0.52832f, 0.500488f, -0.52832f, 0.481445f, -0.430176f, 0.164062f,
+-0.100098f, 0.440918f, -0.100098f, 0.421387f, 0
+};
+
+const unsigned char LiberationSanskBoldItalicVerbs[] = {
+6, 0, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 5, 6,
+0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+1, 5, 6, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0,
+1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 0, 1,
+2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 0, 1, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 0, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1,
+1, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 1,
+1, 2, 2, 2, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2,
+2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 0, 1, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1,
+1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5,
+6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6,
+0, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 1, 1,
+1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+1, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1,
+2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2,
+1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1,
+1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0,
+1, 1, 1, 5, 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5,
+6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2,
+2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2,
+1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1,
+1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+2, 2, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6
+};
+
+const unsigned LiberationSanskBoldItalicCharCodes[] = {
+32, 33,
+44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 65, 66, 67, 68, 69, 70,
+71, 72, 73, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 91, 92,
+93, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122
+};
+
+const SkFixed LiberationSanskBoldItalicWidths[] = {
+0x00004720, 0x00005540, 0x00004720, 0x00005540, 0x00004720, 0x00004720, 0x00008e60,
+0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60, 0x00008e60,
+0x00008e60, 0x00005540, 0x0000b8e0, 0x0000b8e0, 0x0000b8e0, 0x0000b8e0, 0x0000aac0,
+0x00009c60, 0x0000c720, 0x0000b8e0, 0x00004720, 0x0000b8e0, 0x00009c60, 0x0000d540,
+0x0000b8e0, 0x0000c720, 0x0000aac0, 0x0000c720, 0x0000b8e0, 0x0000aac0, 0x00009c60,
+0x0000b8e0, 0x0000f1a0, 0x0000aac0, 0x0000aac0, 0x00009c60, 0x00005540, 0x00004720,
+0x00005540, 0x00008e60, 0x00008e60, 0x00009c60, 0x00008e60, 0x00009c60, 0x00008e60,
+0x00005540, 0x00009c60, 0x00009c60, 0x00004720, 0x00004720, 0x00008e60, 0x00004720,
+0x0000e3a0, 0x00009c60, 0x00009c60, 0x00009c60, 0x00009c60, 0x000063a0, 0x00008e60,
+0x00005540, 0x00009c60, 0x00008e60, 0x0000c720, 0x00008e60, 0x00008e60, 0x00008000
+};
+
+const int LiberationSanskBoldItalicCharCodesCount = (int) SK_ARRAY_COUNT(LiberationSanskBoldItalicCharCodes);
+
+const SkPaint::FontMetrics LiberationSanskBoldItalicMetrics = {
+0x00000003, -1.02979f, -0.905273f, 0.211914f, 0.303223f, 0.0327148f, 1.3374f, 0, -0.208984f,
+1.12842f, 0.537598f, 0, 0.10498f, 0.105957f
+};
+
+const SkScalar HiraginoMaruGothicProkNormalPoints[] = {
+0.109f, -0.22f, 0.109f, -0.197f, 0.128f, -0.186f, 0.149f, -0.186f, 0.169f, -0.186f,
+0.188f, -0.197f, 0.189f, -0.22f, 0.203f, -0.732f, 0.204f, -0.76f, 0.182f, -0.778f,
+0.15f, -0.778f, 0.117f, -0.778f, 0.095f, -0.76f, 0.095f, -0.732f, 0.149f, -0.125f,
+0.11f, -0.125f, 0.08f, -0.098f, 0.08f, -0.056f, 0.08f, -0.014f, 0.11f, 0.013f, 0.149f,
+0.013f, 0.186f, 0.013f, 0.218f, -0.014f, 0.218f, -0.056f, 0.218f, -0.098f, 0.186f,
+-0.125f, 0.149f, -0.125f, 0.291f, -0.684f, 0.291f, -0.028f, 0.291f, -0.001f, 0.312f,
+0.013f, 0.339f, 0.013f, 0.366f, 0.013f, 0.387f, -0.001f, 0.387f, -0.028f, 0.387f,
+-0.684f, 0.614f, -0.684f, 0.637f, -0.684f, 0.652f, -0.704f, 0.652f, -0.727f, 0.652f,
+-0.751f, 0.638f, -0.772f, 0.614f, -0.772f, 0.063f, -0.772f, 0.039f, -0.772f, 0.025f,
+-0.751f, 0.025f, -0.727f, 0.025f, -0.704f, 0.039f, -0.684f, 0.064f, -0.684f, 0.409f,
+-0.347f, 0.302f, -0.345f, 0.25f, -0.339f, 0.195f, -0.324f, 0.1f, -0.298f, 0.044f,
+-0.238f, 0.044f, -0.144f, 0.044f, -0.041f, 0.111f, 0.021f, 0.221f, 0.021f, 0.32f,
+0.021f, 0.373f, -0.018f, 0.411f, -0.061f, 0.412f, -0.041f, 0.414f, -0.023f, 0.417f,
+-0.011f, 0.421f, 0.007f, 0.439f, 0.013f, 0.459f, 0.013f, 0.462f, 0.013f, 0.465f,
+0.013f, 0.468f, 0.013f, 0.493f, 0.011f, 0.508f, -0.003f, 0.508f, -0.019f, 0.508f,
+-0.022f, 0.507f, -0.026f, 0.506f, -0.029f, 0.5f, -0.048f, 0.495f, -0.082f, 0.495f,
+-0.117f, 0.495f, -0.39f, 0.495f, -0.508f, 0.429f, -0.561f, 0.295f, -0.561f, 0.214f,
+-0.561f, 0.169f, -0.544f, 0.134f, -0.517f, 0.111f, -0.499f, 0.085f, -0.47f, 0.075f,
+-0.439f, 0.074f, -0.435f, 0.073f, -0.431f, 0.073f, -0.427f, 0.073f, -0.409f, 0.087f,
+-0.395f, 0.106f, -0.389f, 0.113f, -0.386f, 0.121f, -0.385f, 0.129f, -0.385f, 0.146f,
+-0.385f, 0.161f, -0.392f, 0.168f, -0.411f, 0.185f, -0.457f, 0.221f, -0.485f, 0.294f,
+-0.485f, 0.373f, -0.485f, 0.409f, -0.456f, 0.409f, -0.39f, 0.409f, -0.208f, 0.409f,
+-0.17f, 0.402f, -0.151f, 0.383f, -0.127f, 0.351f, -0.087f, 0.299f, -0.056f, 0.236f,
+-0.056f, 0.176f, -0.056f, 0.136f, -0.091f, 0.136f, -0.143f, 0.136f, -0.191f, 0.157f,
+-0.222f, 0.197f, -0.242f, 0.237f, -0.262f, 0.292f, -0.272f, 0.409f, -0.275f, 0.045f,
+-0.268f, 0.045f, -0.096f, 0.136f, 0.023f, 0.298f, 0.023f, 0.434f, 0.023f, 0.487f,
+-0.049f, 0.514f, -0.118f, 0.517f, -0.125f, 0.518f, -0.13f, 0.518f, -0.136f, 0.518f,
+-0.154f, 0.504f, -0.166f, 0.486f, -0.17f, 0.479f, -0.173f, 0.472f, -0.174f, 0.465f,
+-0.174f, 0.449f, -0.174f, 0.435f, -0.166f, 0.428f, -0.147f, 0.409f, -0.093f, 0.378f,
+-0.055f, 0.3f, -0.055f, 0.194f, -0.055f, 0.138f, -0.138f, 0.138f, -0.269f, 0.138f,
+-0.396f, 0.195f, -0.484f, 0.299f, -0.484f, 0.375f, -0.484f, 0.405f, -0.445f, 0.424f,
+-0.394f, 0.431f, -0.377f, 0.444f, -0.371f, 0.459f, -0.371f, 0.466f, -0.371f, 0.474f,
+-0.372f, 0.481f, -0.374f, 0.496f, -0.38f, 0.511f, -0.392f, 0.511f, -0.411f, 0.511f,
+-0.415f, 0.51f, -0.421f, 0.508f, -0.426f, 0.483f, -0.489f, 0.429f, -0.562f, 0.297f,
+-0.562f, 0.133f, -0.562f, 0.045f, -0.439f, 0.045f, -0.268f, 0.486f, -0.253f, 0.517f,
+-0.253f, 0.536f, -0.272f, 0.536f, -0.308f, 0.536f, -0.311f, 0.536f, -0.313f, 0.536f,
+-0.316f, 0.526f, -0.447f, 0.444f, -0.561f, 0.298f, -0.561f, 0.135f, -0.561f, 0.045f,
+-0.44f, 0.045f, -0.267f, 0.045f, -0.094f, 0.14f, 0.022f, 0.304f, 0.022f, 0.434f,
+0.022f, 0.492f, -0.044f, 0.524f, -0.11f, 0.528f, -0.116f, 0.529f, -0.122f, 0.529f,
+-0.128f, 0.529f, -0.146f, 0.515f, -0.158f, 0.498f, -0.163f, 0.491f, -0.165f, 0.484f,
+-0.167f, 0.477f, -0.167f, 0.463f, -0.167f, 0.45f, -0.16f, 0.441f, -0.142f, 0.417f,
+-0.089f, 0.377f, -0.053f, 0.305f, -0.053f, 0.197f, -0.053f, 0.136f, -0.13f, 0.134f,
+-0.253f, 0.137f, -0.326f, 0.15f, -0.424f, 0.202f, -0.488f, 0.298f, -0.488f, 0.39f,
+-0.488f, 0.433f, -0.415f, 0.445f, -0.344f, 0.445f, -0.342f, 0.445f, -0.34f, 0.445f,
+-0.339f, 0.445f, -0.33f, 0.441f, -0.326f, 0.43f, -0.326f, 0.138f, -0.547f, 0.053f,
+-0.547f, 0.028f, -0.547f, 0.017f, -0.529f, 0.017f, -0.506f, 0.017f, -0.483f, 0.029f,
+-0.468f, 0.053f, -0.468f, 0.138f, -0.468f, 0.138f, -0.027f, 0.138f, 0, 0.156f, 0.013f,
+0.183f, 0.013f, 0.209f, 0.013f, 0.228f, 0, 0.228f, -0.027f, 0.228f, -0.468f, 0.348f,
+-0.468f, 0.372f, -0.468f, 0.385f, -0.483f, 0.385f, -0.506f, 0.385f, -0.53f, 0.373f,
+-0.547f, 0.348f, -0.547f, 0.228f, -0.547f, 0.228f, -0.608f, 0.228f, -0.68f, 0.256f,
+-0.7f, 0.293f, -0.7f, 0.314f, -0.7f, 0.331f, -0.697f, 0.348f, -0.69f, 0.354f, -0.688f,
+0.359f, -0.687f, 0.364f, -0.687f, 0.382f, -0.687f, 0.396f, -0.7f, 0.402f, -0.717f,
+0.405f, -0.723f, 0.406f, -0.729f, 0.406f, -0.736f, 0.406f, -0.751f, 0.398f, -0.766f,
+0.379f, -0.772f, 0.351f, -0.781f, 0.326f, -0.783f, 0.293f, -0.783f, 0.217f, -0.783f,
+0.138f, -0.748f, 0.138f, -0.619f, 0.531f, -0.366f, 0.531f, -0.489f, 0.467f, -0.561f,
+0.348f, -0.561f, 0.253f, -0.561f, 0.193f, -0.516f, 0.158f, -0.445f, 0.159f, -0.464f,
+0.162f, -0.474f, 0.162f, -0.487f, 0.162f, -0.514f, 0.162f, -0.54f, 0.144f, -0.553f,
+0.118f, -0.553f, 0.09f, -0.553f, 0.071f, -0.54f, 0.071f, -0.514f, 0.071f, -0.027f,
+0.071f, 0, 0.089f, 0.013f, 0.117f, 0.013f, 0.143f, 0.013f, 0.162f, 0, 0.162f, -0.027f,
+0.162f, -0.307f, 0.162f, -0.346f, 0.172f, -0.375f, 0.197f, -0.409f, 0.231f, -0.456f,
+0.276f, -0.48f, 0.33f, -0.48f, 0.405f, -0.48f, 0.439f, -0.432f, 0.439f, -0.347f,
+0.439f, -0.027f, 0.439f, 0, 0.458f, 0.013f, 0.485f, 0.013f, 0.511f, 0.013f, 0.531f,
+0, 0.531f, -0.027f, 0.16f, -0.036f, 0.16f, -0.054f, 0.159f, -0.075f, 0.155f, -0.094f,
+0.189f, -0.024f, 0.246f, 0.022f, 0.339f, 0.022f, 0.488f, 0.022f, 0.578f, -0.096f,
+0.578f, -0.274f, 0.578f, -0.452f, 0.493f, -0.561f, 0.343f, -0.561f, 0.246f, -0.561f,
+0.191f, -0.514f, 0.156f, -0.443f, 0.159f, -0.46f, 0.16f, -0.484f, 0.16f, -0.498f,
+0.16f, -0.516f, 0.16f, -0.541f, 0.141f, -0.553f, 0.116f, -0.553f, 0.088f, -0.553f,
+0.071f, -0.54f, 0.071f, -0.514f, 0.071f, 0.184f, 0.071f, 0.209f, 0.088f, 0.223f,
+0.116f, 0.223f, 0.143f, 0.223f, 0.16f, 0.209f, 0.16f, 0.184f, 0.33f, -0.483f, 0.431f,
+-0.483f, 0.486f, -0.402f, 0.486f, -0.272f, 0.486f, -0.143f, 0.429f, -0.057f, 0.328f,
+-0.057f, 0.223f, -0.057f, 0.158f, -0.147f, 0.158f, -0.271f, 0.158f, -0.394f, 0.22f,
+-0.483f, 0.33f, -0.483f, 0.085f, -0.027f, 0.085f, 0, 0.104f, 0.013f, 0.132f, 0.013f,
+0.157f, 0.013f, 0.177f, 0, 0.177f, -0.027f, 0.177f, -0.303f, 0.178f, -0.345f, 0.193f,
+-0.382f, 0.219f, -0.414f, 0.244f, -0.446f, 0.277f, -0.468f, 0.32f, -0.469f, 0.341f,
+-0.469f, 0.354f, -0.466f, 0.368f, -0.463f, 0.371f, -0.462f, 0.374f, -0.462f, 0.377f,
+-0.462f, 0.398f, -0.462f, 0.412f, -0.48f, 0.416f, -0.501f, 0.417f, -0.507f, 0.418f,
+-0.513f, 0.418f, -0.518f, 0.418f, -0.537f, 0.409f, -0.551f, 0.386f, -0.554f, 0.372f,
+-0.557f, 0.361f, -0.559f, 0.346f, -0.559f, 0.339f, -0.559f, 0.332f, -0.559f, 0.324f,
+-0.558f, 0.238f, -0.555f, 0.187f, -0.493f, 0.171f, -0.445f, 0.173f, -0.461f, 0.177f,
+-0.478f, 0.177f, -0.492f, 0.177f, -0.514f, 0.177f, -0.54f, 0.157f, -0.553f, 0.132f,
+-0.553f, 0.104f, -0.553f, 0.085f, -0.54f, 0.085f, -0.514f, 0.286f, -0.236f, 0.377f,
+-0.218f, 0.403f, -0.191f, 0.403f, -0.142f, 0.403f, -0.091f, 0.351f, -0.056f, 0.271f,
+-0.056f, 0.192f, -0.056f, 0.151f, -0.085f, 0.133f, -0.143f, 0.127f, -0.162f, 0.109f,
+-0.17f, 0.09f, -0.17f, 0.086f, -0.17f, 0.081f, -0.169f, 0.076f, -0.168f, 0.057f,
+-0.164f, 0.04f, -0.15f, 0.04f, -0.13f, 0.04f, -0.126f, 0.041f, -0.122f, 0.042f, -0.117f,
+0.068f, -0.028f, 0.143f, 0.023f, 0.271f, 0.023f, 0.411f, 0.023f, 0.493f, -0.048f,
+0.493f, -0.144f, 0.493f, -0.249f, 0.441f, -0.287f, 0.311f, -0.314f, 0.249f, -0.327f,
+0.165f, -0.345f, 0.146f, -0.365f, 0.146f, -0.411f, 0.146f, -0.453f, 0.184f, -0.486f,
+0.265f, -0.486f, 0.322f, -0.486f, 0.366f, -0.463f, 0.379f, -0.418f, 0.384f, -0.399f,
+0.402f, -0.391f, 0.42f, -0.391f, 0.425f, -0.391f, 0.431f, -0.392f, 0.436f, -0.393f,
+0.454f, -0.398f, 0.471f, -0.411f, 0.471f, -0.43f, 0.471f, -0.434f, 0.47f, -0.438f,
+0.469f, -0.442f, 0.444f, -0.515f, 0.373f, -0.562f, 0.262f, -0.562f, 0.133f, -0.562f,
+0.055f, -0.5f, 0.055f, -0.409f, 0.055f, -0.314f, 0.106f, -0.271f, 0.229f, -0.247f,
+0.068f, -0.174f, 0.068f, -0.052f, 0.133f, 0.022f, 0.251f, 0.022f, 0.351f, 0.022f,
+0.409f, -0.029f, 0.44f, -0.099f, 0.437f, -0.083f, 0.434f, -0.063f, 0.434f, -0.052f,
+0.434f, -0.024f, 0.434f, 0.001f, 0.453f, 0.013f, 0.48f, 0.013f, 0.506f, 0.013f, 0.524f,
+0, 0.524f, -0.027f, 0.524f, -0.513f, 0.524f, -0.54f, 0.505f, -0.553f, 0.479f, -0.553f,
+0.452f, -0.553f, 0.433f, -0.54f, 0.433f, -0.513f, 0.433f, -0.235f, 0.433f, -0.196f,
+0.423f, -0.165f, 0.399f, -0.131f, 0.365f, -0.084f, 0.322f, -0.059f, 0.269f, -0.059f,
+0.195f, -0.059f, 0.16f, -0.107f, 0.16f, -0.193f, 0.16f, -0.513f, 0.16f, -0.54f, 0.141f,
+-0.553f, 0.114f, -0.553f, 0.087f, -0.553f, 0.068f, -0.54f, 0.068f, -0.513f, 0.307f,
+-0.194f, 0.296f, -0.165f, 0.282f, -0.127f, 0.274f, -0.096f, 0.265f, -0.127f, 0.256f,
+-0.164f, 0.244f, -0.196f, 0.118f, -0.528f, 0.111f, -0.546f, 0.096f, -0.553f, 0.08f,
+-0.553f, 0.073f, -0.553f, 0.066f, -0.552f, 0.059f, -0.55f, 0.041f, -0.544f, 0.026f,
+-0.529f, 0.026f, -0.511f, 0.026f, -0.506f, 0.027f, -0.5f, 0.029f, -0.495f, 0.231f,
+-0.005f, 0.203f, 0.065f, 0.185f, 0.111f, 0.164f, 0.149f, 0.121f, 0.149f, 0.103f,
+0.149f, 0.085f, 0.142f, 0.071f, 0.136f, 0.064f, 0.133f, 0.058f, 0.132f, 0.052f, 0.132f,
+0.035f, 0.132f, 0.022f, 0.143f, 0.015f, 0.16f, 0.012f, 0.168f, 0.01f, 0.175f, 0.01f,
+0.183f, 0.01f, 0.198f, 0.018f, 0.212f, 0.038f, 0.219f, 0.061f, 0.228f, 0.085f, 0.232f,
+0.11f, 0.232f, 0.208f, 0.232f, 0.249f, 0.175f, 0.284f, 0.089f, 0.52f, -0.496f, 0.522f,
+-0.502f, 0.523f, -0.508f, 0.523f, -0.513f, 0.523f, -0.531f, 0.509f, -0.545f, 0.49f,
+-0.55f, 0.484f, -0.551f, 0.478f, -0.552f, 0.472f, -0.552f, 0.455f, -0.552f, 0.44f,
+-0.545f, 0.433f, -0.526f, 0.88f, -0.329f, 0.905f, -0.329f, 0.919f, -0.345f, 0.919f,
+-0.372f, 0.919f, -0.398f, 0.905f, -0.417f, 0.879f, -0.417f, 0.12f, -0.417f, 0.094f,
+-0.417f, 0.08f, -0.398f, 0.08f, -0.372f, 0.08f, -0.345f, 0.094f, -0.329f, 0.119f,
+-0.329f
+};
+
+const unsigned char HiraginoMaruGothicProkNormalVerbs[] = {
+6, 0, 4, 4, 1, 4, 4, 5, 0, 4, 4, 4, 4, 5, 6, 0, 1, 4, 4, 1, 1, 4, 4, 1, 4, 4, 5,
+6, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 0, 4, 4, 4,
+4, 4, 5, 6, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 0, 4, 4, 4,
+4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 0, 4, 4, 4, 4, 5, 6, 0, 1, 4, 4, 1, 1, 4, 4, 1, 1,
+4, 4, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 0, 4, 4, 4, 1, 4, 4, 1, 4, 4, 1, 4, 4,
+4, 1, 4, 4, 5, 6, 0, 4, 4, 4, 4, 4, 4, 1, 4, 4, 1, 4, 4, 5, 0, 4, 4, 4, 4, 5, 6,
+0, 4, 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 5, 6, 0, 4, 4, 4, 4, 4, 4,
+4, 4, 4, 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 0, 4, 4, 4, 1, 4, 4, 1, 4, 4,
+1, 4, 4, 4, 1, 4, 4, 5, 6, 0, 4, 4, 1, 4, 4, 4, 4, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4,
+1, 4, 4, 4, 4, 5, 6, 0, 4, 4, 1, 4, 4, 5, 6
+};
+
+const unsigned HiraginoMaruGothicProkNormalCharCodes[] = {
+32, 33, 84, 97, 99, 101, 102, 110, 112,
+114, 115, 117, 121, 12540
+};
+
+const SkFixed HiraginoMaruGothicProkNormalWidths[] = {
+0x0000553f, 0x00004d4f, 0x0000ad0e, 0x000092b0, 0x00008dd2, 0x000092f1, 0x00006666,
+0x00009999, 0x00009fbe, 0x00006e97, 0x000088f5, 0x000098d4, 0x00008d0e, 0x00010000
+};
+
+const int HiraginoMaruGothicProkNormalCharCodesCount = (int) SK_ARRAY_COUNT(HiraginoMaruGothicProkNormalCharCodes);
+
+const SkPaint::FontMetrics HiraginoMaruGothicProkNormalMetrics = {
+0x00004f0f, -1.273f, -0.880002f, 0.12f, 0.4f, 0.500001f, 1.673f, 7.89174e-34f, -0.393f,
+1.28f, 0.576f, 5.17319e-29f, 0.077f, 0.06f
+};
+
+const SkScalar PapyruskNormalPoints[] = {
+0.172852f, -0.257812f, 0.166016f, -0.250977f, 0.155762f, -0.228027f, 0.152344f, -0.221191f,
+0.13623f, -0.210938f, 0.126953f, -0.21582f, 0.103027f, -0.213867f, 0.0952148f, -0.219238f,
+0.0859375f, -0.223145f, 0.0859375f, -0.230957f, 0.0869141f, -0.234863f, 0.105957f,
+-0.26416f, 0.11084f, -0.312988f, 0.11377f, -0.332031f, 0.125f, -0.332031f, 0.128906f,
+-0.338379f, 0.128906f, -0.344238f, 0.128906f, -0.349609f, 0.124023f, -0.356934f,
+0.11084f, -0.354004f, 0.10791f, -0.395996f, 0.119141f, -0.428223f, 0.115234f, -0.440918f,
+0.11084f, -0.449219f, 0.108887f, -0.506836f, 0.10791f, -0.52002f, 0.103027f, -0.520996f,
+0.103027f, -0.530762f, 0.118164f, -0.529785f, 0.12207f, -0.535156f, 0.116211f, -0.544434f,
+0.103027f, -0.546875f, 0.103027f, -0.551758f, 0.104004f, -0.583008f, 0.0991211f,
+-0.61084f, 0.101074f, -0.623047f, 0.0888672f, -0.631836f, 0.0834961f, -0.639648f,
+0.078125f, -0.647461f, 0.078125f, -0.657227f, 0.078125f, -0.675781f, 0.100586f, -0.691895f,
+0.123047f, -0.708008f, 0.146973f, -0.708008f, 0.155762f, -0.707031f, 0.161133f, -0.713867f,
+0.171387f, -0.708008f, 0.172852f, -0.703125f, 0.169922f, -0.688965f, 0.167969f, -0.666016f,
+0.163086f, -0.654785f, 0.167969f, -0.626953f, 0.160156f, -0.625f, 0.163086f, -0.601074f,
+0.166992f, -0.596191f, 0.166992f, -0.584961f, 0.168945f, -0.570801f, 0.166016f, -0.546875f,
+0.167969f, -0.535156f, 0.160156f, -0.509766f, 0.161133f, -0.503906f, 0.164062f, -0.500977f,
+0.163086f, -0.490234f, 0.15918f, -0.421875f, 0.154785f, -0.404785f, 0.155762f, -0.391113f,
+0.165039f, -0.374023f, 0.164062f, -0.355957f, 0.163086f, -0.333008f, 0.161621f, -0.330566f,
+0.154785f, -0.324219f, 0.167969f, -0.294922f, 0.170898f, -0.268066f, 0.194824f, -0.0390625f,
+0.190918f, -0.0322266f, 0.183105f, -0.0170898f, 0.152832f, 0.00390625f, 0.14502f,
+0.0141602f, 0.129883f, 0.00683594f, 0.117188f, -0.00976562f, 0.0981445f, -0.0268555f,
+0.0878906f, -0.0439453f, 0.0854492f, -0.0454102f, 0.0771484f, -0.046875f, 0.0668945f,
+-0.0498047f, 0.0683594f, -0.059082f, 0.0742188f, -0.0620117f, 0.10498f, -0.0810547f,
+0.12207f, -0.097168f, 0.12793f, -0.100098f, 0.132812f, -0.101074f, 0.145996f, -0.0888672f,
+0.181152f, -0.0639648f, 0.192383f, -0.0566406f, 0.194824f, -0.0390625f, 0.698242f,
+-0.0458984f, 0.672852f, -0.0239258f, 0.665039f, -0.0078125f, 0.658203f, -0.012207f,
+0.651855f, -0.00878906f, 0.645996f, 0.00195312f, 0.619141f, 0.0141602f, 0.617188f,
+0.012207f, 0.605957f, 0.00878906f, 0.60498f, -0.00390625f, 0.606934f, -0.0161133f,
+0.616211f, -0.0332031f, 0.612793f, -0.0478516f, 0.615234f, -0.0600586f, 0.620117f,
+-0.0888672f, 0.626953f, -0.11377f, 0.623047f, -0.145996f, 0.62207f, -0.155762f, 0.634766f,
+-0.165039f, 0.635254f, -0.169922f, 0.635254f, -0.177246f, 0.635254f, -0.191406f,
+0.62793f, -0.208008f, 0.63623f, -0.233887f, 0.625977f, -0.243164f, 0.631836f, -0.269043f,
+0.626953f, -0.271973f, 0.629883f, -0.354004f, 0.624023f, -0.358887f, 0.619141f, -0.378906f,
+0.615234f, -0.375f, 0.606445f, -0.375f, 0.603271f, -0.373535f, 0.600098f, -0.37207f,
+0.594238f, -0.365234f, 0.582031f, -0.352051f, 0.562988f, -0.359863f, 0.543457f, -0.354004f,
+0.540039f, -0.354004f, 0.540527f, -0.354004f, 0.527832f, -0.355957f, 0.514648f, -0.366211f,
+0.504883f, -0.366211f, 0.503418f, -0.366211f, 0.502686f, -0.365967f, 0.501953f, -0.365723f,
+0.500977f, -0.365234f, 0.450195f, -0.36084f, 0.398926f, -0.367188f, 0.356934f, -0.36377f,
+0.335938f, -0.369141f, 0.304199f, -0.359863f, 0.254883f, -0.365234f, 0.242188f, -0.36377f,
+0.227051f, -0.375f, 0.222168f, -0.362793f, 0.162109f, -0.36377f, 0.149902f, -0.352051f,
+0.149902f, -0.341797f, 0.155762f, -0.303223f, 0.157227f, -0.297852f, 0.157227f, -0.287109f,
+0.157227f, -0.277344f, 0.151855f, -0.268066f, 0.154785f, -0.237793f, 0.147949f, -0.233398f,
+0.146484f, -0.229248f, 0.14502f, -0.225098f, 0.14502f, -0.216797f, 0.148926f, -0.210449f,
+0.15918f, -0.208008f, 0.160156f, -0.187012f, 0.160156f, -0.123047f, 0.160156f, -0.120117f,
+0.161133f, -0.10791f, 0.161133f, -0.103516f, 0.154785f, -0.0991211f, 0.155762f, -0.0888672f,
+0.163086f, -0.059082f, 0.164062f, -0.0488281f, 0.164062f, -0.0273438f, 0.144043f,
+-0.0170898f, 0.119141f, -0.00488281f, 0.097168f, 0.0078125f, 0.0839844f, 0.0141602f,
+0.0810547f, 0.00976562f, 0.0761719f, 0.00976562f, 0.0708008f, -0.000976562f, 0.0708008f,
+-0.00976562f, 0.0708008f, -0.0200195f, 0.0732422f, -0.0239258f, 0.0839844f, -0.0488281f,
+0.0888672f, -0.065918f, 0.0961914f, -0.0688477f, 0.097168f, -0.0849609f, 0.0888672f,
+-0.0927734f, 0.0961914f, -0.106445f, 0.0961914f, -0.108887f, 0.0961914f, -0.111328f,
+0.0888672f, -0.124023f, 0.0878906f, -0.132812f, 0.0917969f, -0.213867f, 0.0869141f,
+-0.23584f, 0.0869141f, -0.24707f, 0.0952148f, -0.25293f, 0.102051f, -0.258789f, 0.104492f,
+-0.26123f, 0.105957f, -0.27002f, 0.0908203f, -0.275391f, 0.0908203f, -0.288086f,
+0.0908203f, -0.290039f, 0.0942383f, -0.327148f, 0.0878906f, -0.342773f, 0.0878906f,
+-0.398926f, 0.0859375f, -0.426758f, 0.0869141f, -0.441895f, 0.0791016f, -0.440918f,
+0.0771484f, -0.438965f, 0.0732422f, -0.452148f, 0.0771484f, -0.448242f, 0.0791016f,
+-0.466797f, 0.097168f, -0.477051f, 0.097168f, -0.487793f, 0.097168f, -0.50293f, 0.0771484f,
+-0.505859f, 0.0698242f, -0.540039f, 0.0698242f, -0.547852f, 0.0668945f, -0.586914f,
+0.0668945f, -0.618164f, 0.0791016f, -0.623047f, 0.0952148f, -0.634766f, 0.121094f,
+-0.646973f, 0.140137f, -0.654785f, 0.154785f, -0.648926f, 0.154785f, -0.639648f,
+0.161133f, -0.628906f, 0.153809f, -0.621094f, 0.152588f, -0.616211f, 0.151367f, -0.611328f,
+0.149902f, -0.591797f, 0.148926f, -0.580078f, 0.158203f, -0.545898f, 0.160156f, -0.525879f,
+0.155762f, -0.525879f, 0.146973f, -0.50293f, 0.153809f, -0.495117f, 0.151855f, -0.484863f,
+0.146973f, -0.476074f, 0.14209f, -0.46582f, 0.144043f, -0.455078f, 0.147949f, -0.446777f,
+0.151855f, -0.438965f, 0.151855f, -0.415039f, 0.163086f, -0.412109f, 0.25f, -0.407227f,
+0.263184f, -0.397949f, 0.295898f, -0.394043f, 0.306152f, -0.39502f, 0.309082f, -0.399902f,
+0.342773f, -0.397949f, 0.347168f, -0.396973f, 0.354004f, -0.402832f, 0.36084f, -0.402832f,
+0.371094f, -0.401855f, 0.371094f, -0.397949f, 0.376953f, -0.394043f, 0.388184f, -0.39502f,
+0.441895f, -0.395996f, 0.461914f, -0.397949f, 0.47998f, -0.39209f, 0.48877f, -0.404785f,
+0.500977f, -0.404785f, 0.50293f, -0.404785f, 0.527832f, -0.402832f, 0.575195f, -0.407227f,
+0.603027f, -0.405762f, 0.612793f, -0.408203f, 0.616211f, -0.418945f, 0.625f, -0.440918f,
+0.623047f, -0.49707f, 0.625f, -0.508789f, 0.618164f, -0.52002f, 0.605957f, -0.532227f,
+0.605957f, -0.553223f, 0.603027f, -0.575195f, 0.608887f, -0.585938f, 0.603027f, -0.605957f,
+0.603027f, -0.617188f, 0.603027f, -0.626465f, 0.608887f, -0.62793f, 0.62207f, -0.629883f,
+0.637207f, -0.641113f, 0.648926f, -0.641113f, 0.65625f, -0.643066f, 0.667969f, -0.654785f,
+0.682129f, -0.647949f, 0.687012f, -0.625f, 0.690918f, -0.611816f, 0.676758f, -0.560059f,
+0.680176f, -0.533203f, 0.678223f, -0.521973f, 0.672852f, -0.521973f, 0.666016f, -0.521973f,
+0.666016f, -0.512207f, 0.668457f, -0.506348f, 0.675781f, -0.50293f, 0.685059f, -0.498047f,
+0.687988f, -0.484863f, 0.690918f, -0.464844f, 0.689941f, -0.458984f, 0.682129f, -0.443848f,
+0.684082f, -0.35498f, 0.682129f, -0.278809f, 0.689941f, -0.26709f, 0.686035f, -0.249512f,
+0.686035f, -0.240234f, 0.686035f, -0.23877f, 0.686035f, -0.236816f, 0.686035f, -0.230957f,
+0.686035f, -0.219238f, 0.675781f, -0.208496f, 0.675781f, -0.204102f, 0.675781f, -0.202148f,
+0.676758f, -0.202148f, 0.689941f, -0.179199f, 0.687012f, -0.112793f, 0.688965f, -0.632812f,
+0.680176f, -0.625977f, 0.667969f, -0.60498f, 0.628906f, -0.589844f, 0.61084f, -0.578125f,
+0.60498f, -0.575195f, 0.599121f, -0.575195f, 0.598145f, -0.575195f, 0.569824f, -0.580078f,
+0.503906f, -0.582031f, 0.458008f, -0.586914f, 0.414062f, -0.583984f, 0.396973f, -0.586914f,
+0.390137f, -0.585938f, 0.384766f, -0.562988f, 0.387207f, -0.550781f, 0.388184f, -0.535156f,
+0.388184f, -0.530762f, 0.382812f, -0.507812f, 0.383789f, -0.490234f, 0.381836f, -0.475098f,
+0.384766f, -0.463867f, 0.373047f, -0.462891f, 0.369873f, -0.459961f, 0.366699f, -0.457031f,
+0.366211f, -0.445801f, 0.382324f, -0.443359f, 0.383789f, -0.437012f, 0.381836f, -0.401855f,
+0.381836f, -0.378906f, 0.381836f, -0.364258f, 0.362793f, -0.347168f, 0.365234f, -0.342773f,
+0.367188f, -0.340088f, 0.369141f, -0.337402f, 0.373291f, -0.335938f, 0.377441f, -0.334473f,
+0.381836f, -0.333984f, 0.384766f, -0.328125f, 0.378418f, -0.324219f, 0.376221f, -0.320312f,
+0.374023f, -0.316406f, 0.373047f, -0.307129f, 0.384766f, -0.293945f, 0.384766f, -0.27002f,
+0.384766f, -0.249023f, 0.384766f, -0.241211f, 0.37793f, -0.233887f, 0.382812f, -0.222168f,
+0.380859f, -0.208984f, 0.384766f, -0.190918f, 0.382812f, -0.176758f, 0.383789f, -0.165039f,
+0.384766f, -0.14502f, 0.366211f, -0.137207f, 0.366211f, -0.123047f, 0.366211f, -0.111328f,
+0.383789f, -0.102051f, 0.391113f, -0.0200195f, 0.383789f, -0.0141602f, 0.375f, -0.00976562f,
+0.349121f, 0.012207f, 0.339844f, 0.0131836f, 0.333008f, 0.0131836f, 0.327148f, 0.0200195f,
+0.321289f, 0.0161133f, 0.317871f, 0.0161133f, 0.317871f, 0.0161133f, 0.312012f, 0.0180664f,
+0.306152f, 0.00488281f, 0.307129f, 0.00195312f, 0.307373f, 0.000244141f, 0.307617f,
+-0.00146484f, 0.308105f, -0.00292969f, 0.312012f, -0.0249023f, 0.308105f, -0.0507812f,
+0.312012f, -0.0888672f, 0.314941f, -0.14502f, 0.319824f, -0.187012f, 0.319824f, -0.198242f,
+0.329102f, -0.209961f, 0.316895f, -0.254883f, 0.321777f, -0.286133f, 0.318848f, -0.327148f,
+0.316895f, -0.35498f, 0.315918f, -0.355957f, 0.315918f, -0.36377f, 0.325195f, -0.390137f,
+0.321777f, -0.400879f, 0.311035f, -0.427734f, 0.311035f, -0.437988f, 0.311035f, -0.438965f,
+0.312012f, -0.453125f, 0.306152f, -0.478027f, 0.307129f, -0.492188f, 0.300781f, -0.527832f,
+0.298828f, -0.540039f, 0.313965f, -0.569824f, 0.324219f, -0.575684f, 0.324219f, -0.581055f,
+0.324219f, -0.585938f, 0.323242f, -0.588867f, 0.295898f, -0.594238f, 0.287109f, -0.594238f,
+0.276855f, -0.595215f, 0.254883f, -0.604004f, 0.210938f, -0.600098f, 0.144043f, -0.606934f,
+0.0717773f, -0.603027f, 0.0600586f, -0.60498f, 0.0478516f, -0.59082f, 0.0380859f,
+-0.59082f, 0.0351562f, -0.59082f, 0.0209961f, -0.592773f, 0.00683594f, -0.595215f,
+0.00732422f, -0.609863f, 0.010498f, -0.615967f, 0.0136719f, -0.62207f, 0.0219727f,
+-0.628906f, 0.0581055f, -0.657227f, 0.0732422f, -0.664062f, 0.100586f, -0.664062f,
+0.11377f, -0.664062f, 0.119629f, -0.649902f, 0.129883f, -0.649902f, 0.139648f, -0.649902f,
+0.152832f, -0.661133f, 0.174805f, -0.65918f, 0.217773f, -0.64502f, 0.253906f, -0.646973f,
+0.282227f, -0.640137f, 0.338867f, -0.637207f, 0.362793f, -0.624023f, 0.374023f, -0.623047f,
+0.375f, -0.626953f, 0.387207f, -0.625977f, 0.417969f, -0.623535f, 0.425537f, -0.62207f,
+0.433105f, -0.620605f, 0.440918f, -0.61377f, 0.458008f, -0.609863f, 0.466797f, -0.616211f,
+0.48291f, -0.617188f, 0.503906f, -0.625977f, 0.540039f, -0.625f, 0.563965f, -0.629883f,
+0.579102f, -0.625f, 0.588867f, -0.625f, 0.63623f, -0.625f, 0.680176f, -0.646973f,
+0.686035f, -0.644043f, 0.48877f, -0.0332031f, 0.483887f, -0.0239258f, 0.476074f,
+-0.012207f, 0.461914f, -0.00683594f, 0.441895f, 0.00390625f, 0.422852f, 0.00976562f,
+0.404785f, 0.0170898f, 0.401855f, 0.0170898f, 0.398438f, 0.0170898f, 0.395264f, 0.0134277f,
+0.39209f, 0.00976562f, 0.39209f, 0.00683594f, 0.39209f, 0.00195312f, 0.396973f, -0.0151367f,
+0.399414f, -0.0200195f, 0.400879f, -0.0322266f, 0.391113f, -0.0258789f, 0.347168f,
+-0.0112305f, 0.333984f, -0.00488281f, 0.320801f, -0.00488281f, 0.319824f, -0.00488281f,
+0.300781f, -0.00488281f, 0.277832f, 0.00585938f, 0.262207f, 0.0078125f, 0.216797f,
+0.0170898f, 0.198242f, 0.0141602f, 0.185059f, 0.019043f, 0.175781f, 0.0209961f, 0.161133f,
+0.0200195f, 0.128906f, 0.0131836f, 0.106934f, 0.0112305f, 0.0844727f, 0.00830078f,
+0.0681152f, -0.00415039f, 0.0517578f, -0.0166016f, 0.0439453f, -0.0361328f, 0.0307617f,
+-0.0410156f, 0.027832f, -0.0532227f, 0.0268555f, -0.0620117f, 0.0200195f, -0.0849609f,
+0.0380859f, -0.121094f, 0.0439453f, -0.137207f, 0.046875f, -0.143555f, 0.0620117f,
+-0.155762f, 0.100098f, -0.187012f, 0.116211f, -0.192871f, 0.143066f, -0.204102f,
+0.143555f, -0.204102f, 0.14502f, -0.203857f, 0.146484f, -0.203613f, 0.147949f, -0.203125f,
+0.157715f, -0.224121f, 0.185059f, -0.224121f, 0.187988f, -0.227051f, 0.198242f, -0.227051f,
+0.20459f, -0.234863f, 0.210938f, -0.237793f, 0.217285f, -0.240723f, 0.234863f, -0.244141f,
+0.295898f, -0.254883f, 0.313965f, -0.25293f, 0.336914f, -0.257812f, 0.37793f, -0.262207f,
+0.398926f, -0.26709f, 0.398926f, -0.282227f, 0.398926f, -0.28418f, 0.397949f, -0.285156f,
+0.393066f, -0.307129f, 0.396973f, -0.338867f, 0.395508f, -0.349121f, 0.389648f, -0.35376f,
+0.383789f, -0.358398f, 0.37207f, -0.359863f, 0.365234f, -0.371094f, 0.354492f, -0.388672f,
+0.347656f, -0.393799f, 0.34082f, -0.398926f, 0.321777f, -0.402832f, 0.293945f, -0.40918f,
+0.26709f, -0.410156f, 0.253906f, -0.408203f, 0.249512f, -0.410156f, 0.24707f, -0.413086f,
+0.244629f, -0.416016f, 0.243164f, -0.421875f, 0.22998f, -0.416016f, 0.214844f, -0.401855f,
+0.166992f, -0.37793f, 0.151855f, -0.369629f, 0.146973f, -0.361816f, 0.140137f, -0.352051f,
+0.135254f, -0.344238f, 0.126953f, -0.344238f, 0.117188f, -0.346191f, 0.103027f, -0.353027f,
+0.0878906f, -0.355957f, 0.0805664f, -0.358398f, 0.0732422f, -0.364258f, 0.065918f,
+-0.370117f, 0.065918f, -0.375f, 0.065918f, -0.37793f, 0.0668945f, -0.37793f, 0.0751953f,
+-0.383789f, 0.0908203f, -0.395996f, 0.10791f, -0.398926f, 0.133789f, -0.412109f,
+0.166016f, -0.422852f, 0.174805f, -0.424805f, 0.195801f, -0.436035f, 0.212891f, -0.433105f,
+0.271973f, -0.445801f, 0.296875f, -0.444824f, 0.315918f, -0.444824f, 0.335938f, -0.437988f,
+0.394043f, -0.426758f, 0.402832f, -0.421875f, 0.402832f, -0.415039f, 0.395996f, -0.411133f,
+0.398926f, -0.394043f, 0.408203f, -0.394043f, 0.40918f, -0.394531f, 0.409668f, -0.394775f,
+0.410156f, -0.39502f, 0.411133f, -0.39502f, 0.424805f, -0.400879f, 0.426758f, -0.400879f,
+0.431641f, -0.400879f, 0.433105f, -0.395996f, 0.442871f, -0.37793f, 0.453125f, -0.370117f,
+0.453125f, -0.358887f, 0.451172f, -0.333984f, 0.451172f, -0.317871f, 0.466797f, -0.306152f,
+0.473145f, -0.233887f, 0.459961f, -0.21582f, 0.475098f, -0.198242f, 0.476074f, -0.191895f,
+0.473145f, -0.145996f, 0.477051f, -0.11084f, 0.477051f, -0.103027f, 0.477051f, -0.0917969f,
+0.470215f, -0.0898438f, 0.471191f, -0.0776367f, 0.47168f, -0.0742188f, 0.472168f,
+-0.0708008f, 0.475098f, -0.064209f, 0.478027f, -0.0576172f, 0.481934f, -0.0488281f,
+0.411133f, -0.118164f, 0.403809f, -0.124512f, 0.401855f, -0.128906f, 0.403809f, -0.148926f,
+0.399902f, -0.193848f, 0.405762f, -0.207031f, 0.390137f, -0.21582f, 0.381836f, -0.213867f,
+0.336914f, -0.216797f, 0.315918f, -0.21582f, 0.299805f, -0.227051f, 0.290039f, -0.221191f,
+0.263184f, -0.220215f, 0.244141f, -0.212891f, 0.23291f, -0.219238f, 0.219238f, -0.210938f,
+0.145996f, -0.175781f, 0.129883f, -0.164062f, 0.117188f, -0.14502f, 0.100098f, -0.134766f,
+0.0961914f, -0.130859f, 0.0961914f, -0.125977f, 0.0961914f, -0.125977f, 0.0964355f,
+-0.125488f, 0.0966797f, -0.125f, 0.097168f, -0.124023f, 0.101074f, -0.118164f, 0.100098f,
+-0.11377f, 0.11084f, -0.0698242f, 0.100098f, -0.0419922f, 0.10791f, -0.0322266f,
+0.121094f, -0.0478516f, 0.12793f, -0.0419922f, 0.133789f, -0.0380859f, 0.139648f,
+-0.0341797f, 0.147949f, -0.0314941f, 0.15625f, -0.0288086f, 0.168945f, -0.0258789f,
+0.179199f, -0.012207f, 0.212891f, -0.00878906f, 0.222168f, -0.0180664f, 0.231934f,
+-0.0131836f, 0.23877f, -0.0170898f, 0.244141f, -0.0200195f, 0.255859f, -0.0161133f,
+0.257812f, -0.0161133f, 0.272461f, -0.0161133f, 0.295898f, -0.0297852f, 0.297363f,
+-0.0307617f, 0.299805f, -0.0319824f, 0.302246f, -0.0332031f, 0.307129f, -0.0361328f,
+0.351074f, -0.0361328f, 0.365234f, -0.0541992f, 0.375f, -0.0668945f, 0.398926f, -0.0869141f,
+0.399902f, -0.0927734f, 0.398926f, -0.0991211f, 0.40625f, -0.101562f, 0.408203f,
+-0.10498f, 0.410156f, -0.108398f, 0.411133f, -0.118164f, 0.484863f, -0.0927734f,
+0.484863f, -0.0898438f, 0.483887f, -0.0878906f, 0.478027f, -0.0629883f, 0.478027f,
+-0.0625f, 0.478271f, -0.0615234f, 0.478516f, -0.0605469f, 0.479004f, -0.059082f,
+0.458008f, -0.0332031f, 0.445801f, -0.0297852f, 0.426758f, -0.0170898f, 0.418945f,
+-0.0151367f, 0.396973f, -0.00390625f, 0.39502f, -0.00390625f, 0.36377f, -0.00488281f,
+0.355469f, -0.00488281f, 0.34082f, 0.00195312f, 0.315918f, 0.0161133f, 0.276855f,
+0.019043f, 0.237793f, 0.0161133f, 0.229004f, 0.00878906f, 0.200195f, 0.00488281f,
+0.167969f, -0.00390625f, 0.123047f, -0.0141602f, 0.102051f, -0.0322266f, 0.0830078f,
+-0.0517578f, 0.0888672f, -0.0688477f, 0.0795898f, -0.0649414f, 0.0717773f, -0.0649414f,
+0.0678711f, -0.0649414f, 0.059082f, -0.0751953f, 0.046875f, -0.0961914f, 0.0400391f,
+-0.10498f, 0.0371094f, -0.132812f, 0.0410156f, -0.146973f, 0.0371094f, -0.154785f,
+0.0268555f, -0.166016f, 0.0332031f, -0.190918f, 0.0307617f, -0.23584f, 0.0478516f,
+-0.265137f, 0.0688477f, -0.308105f, 0.0961914f, -0.331055f, 0.14502f, -0.37793f,
+0.15918f, -0.388184f, 0.178223f, -0.401855f, 0.187012f, -0.404785f, 0.207031f, -0.419922f,
+0.27002f, -0.439941f, 0.285156f, -0.443848f, 0.286133f, -0.443848f, 0.286865f, -0.443604f,
+0.287598f, -0.443359f, 0.288086f, -0.442871f, 0.312988f, -0.432129f, 0.337891f, -0.438965f,
+0.384766f, -0.431152f, 0.424805f, -0.437012f, 0.432129f, -0.435059f, 0.440918f, -0.431152f,
+0.437012f, -0.415527f, 0.432373f, -0.4104f, 0.427734f, -0.405273f, 0.413086f, -0.398926f,
+0.412109f, -0.388184f, 0.39209f, -0.375977f, 0.37793f, -0.369141f, 0.375977f, -0.369141f,
+0.362793f, -0.371094f, 0.346191f, -0.369141f, 0.270996f, -0.380859f, 0.26709f, -0.381836f,
+0.259766f, -0.381836f, 0.25293f, -0.381836f, 0.25f, -0.380859f, 0.208984f, -0.373047f,
+0.195801f, -0.373047f, 0.179199f, -0.370117f, 0.163086f, -0.347168f, 0.14209f, -0.339844f,
+0.132812f, -0.319824f, 0.116211f, -0.316895f, 0.118164f, -0.312988f, 0.118164f, -0.310059f,
+0.0981445f, -0.270996f, 0.0961914f, -0.253906f, 0.097168f, -0.224121f, 0.0976562f,
+-0.202637f, 0.100586f, -0.188477f, 0.103516f, -0.174316f, 0.11084f, -0.160156f, 0.106934f,
+-0.148926f, 0.102051f, -0.140625f, 0.102051f, -0.138184f, 0.102051f, -0.135254f,
+0.10498f, -0.130859f, 0.119629f, -0.126953f, 0.119141f, -0.126953f, 0.123535f, -0.123535f,
+0.133789f, -0.108887f, 0.146973f, -0.0908203f, 0.147949f, -0.0888672f, 0.148926f,
+-0.0864258f, 0.149902f, -0.0839844f, 0.151855f, -0.0800781f, 0.163086f, -0.0800781f,
+0.168945f, -0.0717773f, 0.201172f, -0.0488281f, 0.214844f, -0.0371094f, 0.230957f,
+-0.0322266f, 0.245117f, -0.0268555f, 0.26709f, -0.0258789f, 0.323242f, -0.0200195f,
+0.324219f, -0.0195312f, 0.324707f, -0.0192871f, 0.325195f, -0.019043f, 0.325195f,
+-0.019043f, 0.333496f, -0.019043f, 0.359863f, -0.0332031f, 0.369141f, -0.0297852f,
+0.402832f, -0.0532227f, 0.416016f, -0.0551758f, 0.428711f, -0.0639648f, 0.441406f,
+-0.0727539f, 0.462891f, -0.0952148f, 0.469238f, -0.103027f, 0.475098f, -0.103027f,
+0.479004f, -0.103027f, 0.481934f, -0.100098f, 0.484863f, -0.097168f, 0.484863f, -0.0927734f,
+0.51123f, -0.100098f, 0.51123f, -0.09375f, 0.508789f, -0.0888672f, 0.499023f, -0.0717773f,
+0.476074f, -0.0322266f, 0.455078f, -0.0307617f, 0.441895f, -0.0200195f, 0.4375f,
+-0.015625f, 0.426758f, -0.0141602f, 0.338867f, 0.00292969f, 0.325195f, 0.0078125f,
+0.293945f, 0.00488281f, 0.249023f, 0.00878906f, 0.198242f, 0.00585938f, 0.184082f,
+0.00585938f, 0.17334f, -0.00244141f, 0.170898f, -0.00390625f, 0.123047f, -0.0209961f,
+0.106934f, -0.0361328f, 0.0751953f, -0.0581055f, 0.0498047f, -0.0917969f, 0.0400391f,
+-0.100098f, 0.0458984f, -0.111816f, 0.0458984f, -0.121094f, 0.0458984f, -0.125f,
+0.0439453f, -0.126953f, 0.0307617f, -0.147949f, 0.027832f, -0.175781f, 0.0268555f,
+-0.198242f, 0.0268555f, -0.209473f, 0.0322266f, -0.228027f, 0.0405273f, -0.257324f,
+0.0458984f, -0.263184f, 0.0639648f, -0.286133f, 0.0732422f, -0.307129f, 0.0961914f,
+-0.329102f, 0.121094f, -0.361816f, 0.143066f, -0.374023f, 0.174805f, -0.395996f,
+0.195801f, -0.410156f, 0.203125f, -0.415039f, 0.217773f, -0.417969f, 0.262207f, -0.432129f,
+0.296875f, -0.436035f, 0.317871f, -0.444824f, 0.328125f, -0.445801f, 0.353027f, -0.445801f,
+0.370117f, -0.418945f, 0.379395f, -0.419922f, 0.383789f, -0.429199f, 0.396973f, -0.417969f,
+0.415039f, -0.408203f, 0.456055f, -0.368164f, 0.463867f, -0.358398f, 0.468018f, -0.351318f,
+0.472168f, -0.344238f, 0.476318f, -0.336426f, 0.480469f, -0.328613f, 0.483643f, -0.319336f,
+0.486816f, -0.310059f, 0.493164f, -0.291016f, 0.49707f, -0.278809f, 0.492188f, -0.276855f,
+0.473145f, -0.280762f, 0.452148f, -0.273926f, 0.436035f, -0.276855f, 0.417969f, -0.271973f,
+0.383789f, -0.275879f, 0.351074f, -0.273926f, 0.316895f, -0.279785f, 0.26123f, -0.278809f,
+0.233887f, -0.279785f, 0.167969f, -0.270996f, 0.144043f, -0.271973f, 0.11084f, -0.262207f,
+0.0991211f, -0.259766f, 0.097168f, -0.248047f, 0.0961914f, -0.23584f, 0.09375f, -0.231445f,
+0.0913086f, -0.227051f, 0.0830078f, -0.221191f, 0.0839844f, -0.211914f, 0.100098f,
+-0.199707f, 0.101074f, -0.196777f, 0.11377f, -0.146973f, 0.120117f, -0.134766f, 0.115234f,
+-0.129883f, 0.115234f, -0.125977f, 0.115234f, -0.125977f, 0.115479f, -0.125488f,
+0.115723f, -0.125f, 0.116211f, -0.124023f, 0.134766f, -0.118164f, 0.13916f, -0.105957f,
+0.144043f, -0.0888672f, 0.151855f, -0.0849609f, 0.178223f, -0.0742188f, 0.187012f,
+-0.0551758f, 0.193848f, -0.0517578f, 0.208984f, -0.0498047f, 0.21582f, -0.0371094f,
+0.230957f, -0.0351562f, 0.272949f, -0.0200195f, 0.308105f, -0.0268555f, 0.400879f,
+-0.0419922f, 0.420898f, -0.0541992f, 0.452148f, -0.0732422f, 0.478027f, -0.106934f,
+0.484863f, -0.115234f, 0.494141f, -0.115234f, 0.51123f, -0.115234f, 0.51123f, -0.100098f,
+0.395996f, -0.330078f, 0.395996f, -0.337891f, 0.37793f, -0.362793f, 0.344238f, -0.387207f,
+0.333008f, -0.398926f, 0.316895f, -0.399902f, 0.279785f, -0.402832f, 0.270996f, -0.400879f,
+0.25f, -0.38916f, 0.223145f, -0.382812f, 0.188965f, -0.370117f, 0.175781f, -0.365234f,
+0.160156f, -0.341797f, 0.145508f, -0.331543f, 0.144043f, -0.329102f, 0.14209f, -0.323242f,
+0.202148f, -0.318848f, 0.208984f, -0.319824f, 0.220215f, -0.323242f, 0.230957f, -0.320801f,
+0.259766f, -0.314941f, 0.26123f, -0.314941f, 0.293945f, -0.320801f, 0.304199f, -0.323242f,
+0.312012f, -0.312012f, 0.323242f, -0.312012f, 0.366211f, -0.320801f, 0.383789f, -0.318848f,
+0.395996f, -0.320312f, 0.395996f, -0.330078f, 0.433105f, -0.911133f, 0.428223f, -0.899902f,
+0.413086f, -0.883789f, 0.401855f, -0.870117f, 0.38916f, -0.861816f, 0.375977f, -0.85498f,
+0.333984f, -0.875977f, 0.310547f, -0.888184f, 0.296875f, -0.888184f, 0.28418f, -0.888184f,
+0.254883f, -0.875977f, 0.224121f, -0.864746f, 0.210938f, -0.829102f, 0.196777f, -0.790039f,
+0.186035f, -0.76709f, 0.179199f, -0.734863f, 0.170898f, -0.724121f, 0.173828f, -0.709961f,
+0.179199f, -0.707031f, 0.176758f, -0.604004f, 0.166992f, -0.591797f, 0.166992f, -0.578125f,
+0.166016f, -0.566895f, 0.178223f, -0.538086f, 0.173828f, -0.518066f, 0.178223f, -0.470215f,
+0.178223f, -0.467773f, 0.178223f, -0.456543f, 0.162109f, -0.443848f, 0.164062f, -0.434082f,
+0.180664f, -0.42627f, 0.182129f, -0.421875f, 0.185059f, -0.402832f, 0.185059f, -0.395996f,
+0.196777f, -0.395996f, 0.211914f, -0.39502f, 0.265137f, -0.39209f, 0.304199f, -0.397949f,
+0.346191f, -0.401855f, 0.368164f, -0.408203f, 0.379883f, -0.40918f, 0.398926f, -0.40918f,
+0.411133f, -0.38916f, 0.399902f, -0.381836f, 0.36377f, -0.358887f, 0.345215f, -0.342773f,
+0.295898f, -0.350098f, 0.245117f, -0.345215f, 0.234863f, -0.345215f, 0.226074f, -0.348145f,
+0.201172f, -0.35498f, 0.195801f, -0.35498f, 0.188965f, -0.35498f, 0.183594f, -0.347168f,
+0.178223f, -0.339355f, 0.178223f, -0.331055f, 0.178223f, -0.328125f, 0.186035f, -0.254883f,
+0.186035f, -0.253906f, 0.186035f, -0.249023f, 0.173828f, -0.243164f, 0.171875f, -0.232422f,
+0.171875f, -0.233887f, 0.171875f, -0.226562f, 0.182129f, -0.214844f, 0.185059f, -0.201172f,
+0.187988f, -0.144043f, 0.191895f, -0.124023f, 0.186035f, -0.118164f, 0.181152f, -0.118164f,
+0.179199f, -0.119141f, 0.171387f, -0.114746f, 0.169922f, -0.105957f, 0.174805f, -0.105957f,
+0.173828f, -0.102051f, 0.187988f, -0.0839844f, 0.187988f, -0.0717773f, 0.186035f,
+-0.0581055f, 0.187988f, -0.0458984f, 0.190918f, -0.0341797f, 0.182129f, -0.0297852f,
+0.182129f, -0.0161133f, 0.138184f, 0.00292969f, 0.0991211f, 0.0078125f, 0.0927734f,
+0.00292969f, 0.0927734f, -0.00195312f, 0.0981445f, -0.0131836f, 0.102051f, -0.046875f,
+0.109863f, -0.0678711f, 0.112793f, -0.0898438f, 0.109863f, -0.115234f, 0.123047f,
+-0.128906f, 0.123047f, -0.141113f, 0.12207f, -0.147949f, 0.111816f, -0.182129f, 0.111816f,
+-0.185059f, 0.112793f, -0.22998f, 0.115234f, -0.315918f, 0.117188f, -0.328125f, 0.140137f,
+-0.331055f, 0.140137f, -0.341797f, 0.140137f, -0.348145f, 0.134766f, -0.348145f,
+0.116211f, -0.350098f, 0.100098f, -0.356934f, 0.0771484f, -0.356934f, 0.0610352f,
+-0.358887f, 0.0507812f, -0.359863f, 0.0419922f, -0.359863f, 0.0361328f, -0.356934f,
+0.0205078f, -0.352051f, 0.0180664f, -0.352051f, 0.00976562f, -0.352051f, 0.00976562f,
+-0.36084f, 0.00976562f, -0.364746f, 0.012207f, -0.367188f, 0.0219727f, -0.380859f,
+0.0400391f, -0.403809f, 0.046875f, -0.410156f, 0.059082f, -0.410156f, 0.0673828f,
+-0.410156f, 0.0820312f, -0.405762f, 0.10791f, -0.419922f, 0.106934f, -0.425781f,
+0.111816f, -0.458008f, 0.109863f, -0.509766f, 0.111328f, -0.524414f, 0.121094f, -0.53418f,
+0.10498f, -0.557129f, 0.105957f, -0.567871f, 0.103027f, -0.675781f, 0.103027f, -0.690918f,
+0.11084f, -0.704102f, 0.12793f, -0.73291f, 0.12793f, -0.737305f, 0.117188f, -0.745117f,
+0.12207f, -0.779785f, 0.14917f, -0.81958f, 0.17627f, -0.859375f, 0.208008f, -0.87793f,
+0.269043f, -0.915039f, 0.282227f, -0.923828f, 0.298828f, -0.925781f, 0.331055f, -0.934082f,
+0.347168f, -0.929199f, 0.383789f, -0.930176f, 0.393066f, -0.929688f, 0.400635f, -0.925293f,
+0.408203f, -0.920898f, 0.418945f, -0.910156f, 0.422852f, -0.914062f, 0.425781f, -0.914062f,
+0.428711f, -0.914062f, 0.433105f, -0.911133f, 0.160156f, -0.0869141f, 0.158203f,
+-0.0610352f, 0.15918f, -0.0410156f, 0.15918f, -0.0336914f, 0.151855f, -0.0288086f,
+0.154785f, -0.0170898f, 0.144043f, -0.0151367f, 0.111816f, 0.00488281f, 0.0991211f,
+0.00683594f, 0.0839844f, 0.0161133f, 0.0820312f, 0.0161133f, 0.0805664f, 0.0163574f,
+0.0791016f, 0.0166016f, 0.0771484f, 0.0170898f, 0.0678711f, 0.0170898f, 0.0678711f,
+0.0112305f, 0.0678711f, -0.000976562f, 0.0649414f, -0.0229492f, 0.0717773f, -0.0761719f,
+0.0742188f, -0.144043f, 0.0756836f, -0.168945f, 0.0849609f, -0.185059f, 0.0791016f,
+-0.200195f, 0.0708008f, -0.215332f, 0.0708008f, -0.217773f, 0.0708008f, -0.225586f,
+0.0830078f, -0.246094f, 0.0878906f, -0.253418f, 0.0878906f, -0.262207f, 0.0878906f,
+-0.269043f, 0.0732422f, -0.274902f, 0.0751953f, -0.283203f, 0.0708008f, -0.285156f,
+0.0708008f, -0.291992f, 0.0708008f, -0.299805f, 0.0791016f, -0.333984f, 0.0791016f,
+-0.417969f, 0.0888672f, -0.457031f, 0.0888672f, -0.464844f, 0.0771484f, -0.474121f,
+0.0771484f, -0.49707f, 0.0751953f, -0.584961f, 0.0751953f, -0.594727f, 0.0878906f,
+-0.618164f, 0.0952148f, -0.630859f, 0.0771484f, -0.63916f, 0.0771484f, -0.645996f,
+0.0771484f, -0.644043f, 0.0800781f, -0.665039f, 0.0698242f, -0.673828f, 0.0698242f,
+-0.692871f, 0.0678711f, -0.71582f, 0.0678711f, -0.720215f, 0.0761719f, -0.745117f,
+0.0678711f, -0.779785f, 0.0698242f, -0.796875f, 0.0600586f, -0.854004f, 0.0600586f,
+-0.858887f, 0.0600586f, -0.861816f, 0.0639648f, -0.87793f, 0.0668945f, -0.897949f,
+0.11084f, -0.921875f, 0.130859f, -0.937012f, 0.13916f, -0.938965f, 0.145996f, -0.928223f,
+0.146973f, -0.907227f, 0.150879f, -0.893066f, 0.151855f, -0.884766f, 0.151855f, -0.873047f,
+0.148926f, -0.836914f, 0.148926f, -0.833984f, 0.149902f, -0.816895f, 0.149902f, -0.808105f,
+0.147949f, -0.804199f, 0.13623f, -0.778809f, 0.134766f, -0.769043f, 0.144531f, -0.768555f,
+0.147217f, -0.765869f, 0.149902f, -0.763184f, 0.149902f, -0.751953f, 0.149902f, -0.741211f,
+0.149902f, -0.731445f, 0.138184f, -0.725098f, 0.138184f, -0.712891f, 0.137207f, -0.703125f,
+0.137207f, -0.699219f, 0.145996f, -0.685059f, 0.14209f, -0.591797f, 0.14209f, -0.524902f,
+0.128906f, -0.499023f, 0.13623f, -0.461914f, 0.125977f, -0.437988f, 0.127441f, -0.433594f,
+0.134766f, -0.426758f, 0.143066f, -0.417969f, 0.146973f, -0.259766f, 0.134766f, -0.246094f,
+0.13623f, -0.236816f, 0.13623f, -0.226074f, 0.13623f, -0.208984f, 0.131836f, -0.193848f,
+0.13623f, -0.183105f, 0.149902f, -0.183105f, 0.149902f, -0.165039f, 0.496094f, -0.0332031f,
+0.491211f, -0.019043f, 0.423828f, 0.0131836f, 0.410156f, -0.00439453f, 0.410156f,
+-0.00878906f, 0.410156f, -0.0112305f, 0.421875f, -0.0581055f, 0.422852f, -0.0791016f,
+0.426758f, -0.078125f, 0.435059f, -0.0878906f, 0.431641f, -0.0957031f, 0.428467f,
+-0.0981445f, 0.425293f, -0.100586f, 0.416992f, -0.104004f, 0.415039f, -0.111816f,
+0.422852f, -0.203125f, 0.417969f, -0.21582f, 0.418945f, -0.231934f, 0.418945f, -0.269043f,
+0.424805f, -0.287109f, 0.416016f, -0.295898f, 0.416992f, -0.325195f, 0.411621f, -0.341309f,
+0.398926f, -0.355957f, 0.398926f, -0.36084f, 0.398926f, -0.367188f, 0.39502f, -0.370117f,
+0.382812f, -0.371094f, 0.35791f, -0.38623f, 0.317871f, -0.383789f, 0.271973f, -0.387207f,
+0.266113f, -0.384277f, 0.258789f, -0.375f, 0.25f, -0.376953f, 0.211914f, -0.370117f,
+0.198242f, -0.367188f, 0.181152f, -0.354004f, 0.15918f, -0.344238f, 0.143066f, -0.336426f,
+0.141113f, -0.320801f, 0.140137f, -0.272949f, 0.133789f, -0.243164f, 0.144043f, -0.213867f,
+0.144043f, -0.198242f, 0.143066f, -0.140137f, 0.133789f, -0.120117f, 0.132812f, -0.112793f,
+0.132812f, -0.109863f, 0.14209f, -0.0942383f, 0.14502f, -0.0410156f, 0.148926f, -0.0239258f,
+0.148926f, -0.0209961f, 0.145996f, -0.0163574f, 0.143066f, -0.0117188f, 0.138184f,
+-0.00976562f, 0.105957f, -0.00195312f, 0.097168f, 0, 0.0893555f, 0.0131836f, 0.0820312f,
+0.0131836f, 0.0771484f, 0.0131836f, 0.0717773f, 0.0078125f, 0.0712891f, 0.00683594f,
+0.0705566f, 0.00585938f, 0.0698242f, 0.00488281f, 0.0688477f, 0.00390625f, 0.0668945f,
+0, 0.0668945f, 0.000976562f, 0.0742188f, -0.0351562f, 0.0732422f, -0.0761719f, 0.078125f,
+-0.0927734f, 0.0742188f, -0.120117f, 0.0761719f, -0.149902f, 0.0771484f, -0.212891f,
+0.0771484f, -0.225586f, 0.0942383f, -0.227051f, 0.0927734f, -0.237793f, 0.0891113f,
+-0.240479f, 0.0854492f, -0.243164f, 0.0732422f, -0.243164f, 0.0742188f, -0.331055f,
+0.0849609f, -0.337891f, 0.0791016f, -0.348145f, 0.065918f, -0.383789f, 0.0571289f,
+-0.39502f, 0.0629883f, -0.405762f, 0.0732422f, -0.417969f, 0.0908203f, -0.425781f,
+0.10791f, -0.438965f, 0.115234f, -0.444824f, 0.125977f, -0.444824f, 0.132324f, -0.444824f,
+0.138184f, -0.441162f, 0.144043f, -0.4375f, 0.14502f, -0.433105f, 0.145996f, -0.387207f,
+0.147949f, -0.37207f, 0.157227f, -0.375f, 0.174805f, -0.396484f, 0.198486f, -0.415283f,
+0.222168f, -0.434082f, 0.233887f, -0.434082f, 0.240234f, -0.434082f, 0.244141f, -0.423828f,
+0.253906f, -0.426758f, 0.26709f, -0.435059f, 0.28125f, -0.442871f, 0.291016f, -0.442871f,
+0.293945f, -0.442871f, 0.333984f, -0.438965f, 0.349121f, -0.443848f, 0.394043f, -0.437988f,
+0.416992f, -0.435059f, 0.430176f, -0.421875f, 0.437012f, -0.422852f, 0.452637f, -0.422852f,
+0.462891f, -0.40918f, 0.470215f, -0.396973f, 0.47998f, -0.380859f, 0.486816f, -0.372559f,
+0.486816f, -0.345215f, 0.486816f, -0.317871f, 0.48877f, -0.306152f, 0.477051f, -0.291016f,
+0.480957f, -0.278809f, 0.486816f, -0.268066f, 0.486816f, -0.256836f, 0.486816f, -0.248047f,
+0.486816f, -0.244141f, 0.48584f, -0.242188f, 0.479004f, -0.228027f, 0.477051f, -0.224121f,
+0.477051f, -0.213867f, 0.486816f, -0.201172f, 0.48584f, -0.187012f, 0.484863f, -0.152832f,
+0.484863f, -0.148926f, 0.492188f, -0.129883f, 0.493164f, -0.0859375f, 0.571777f,
+-0.248047f, 0.561035f, -0.25f, 0.562988f, -0.23877f, 0.551758f, -0.230957f, 0.554199f,
+-0.222168f, 0.555908f, -0.220215f, 0.557617f, -0.218262f, 0.564941f, -0.213867f,
+0.565918f, -0.204102f, 0.565918f, -0.150879f, 0.524902f, -0.0888672f, 0.515625f,
+-0.0751953f, 0.501953f, -0.0600586f, 0.488281f, -0.0449219f, 0.484863f, -0.0400391f,
+0.470215f, -0.0361328f, 0.37793f, 0.00683594f, 0.327148f, 0.00878906f, 0.290039f,
+0.0180664f, 0.246094f, 0.0170898f, 0.230957f, 0.0209961f, 0.187012f, 0.0131836f,
+0.168945f, 0.012207f, 0.15918f, 0.000976562f, 0.131836f, -0.00292969f, 0.119141f,
+-0.00976562f, 0.102539f, -0.0224609f, 0.0913086f, -0.0310059f, 0.0800781f, -0.0395508f,
+0.0769043f, -0.0422363f, 0.0737305f, -0.0449219f, 0.0717773f, -0.0478516f, 0.0610352f,
+-0.0688477f, 0.0458984f, -0.0810547f, 0.0341797f, -0.111816f, 0.0297852f, -0.124023f,
+0.0351562f, -0.12793f, 0.0351562f, -0.134766f, 0.0371094f, -0.137207f, 0.0390625f,
+-0.139648f, 0.0458984f, -0.14209f, 0.0429688f, -0.149902f, 0.0268555f, -0.160156f,
+0.0268555f, -0.180176f, 0.0268555f, -0.201172f, 0.0317383f, -0.22168f, 0.0366211f,
+-0.242188f, 0.0488281f, -0.269043f, 0.0678711f, -0.312012f, 0.0771484f, -0.317871f,
+0.097168f, -0.331055f, 0.10791f, -0.350098f, 0.11377f, -0.360352f, 0.12207f, -0.36377f,
+0.167969f, -0.388184f, 0.193848f, -0.40918f, 0.225098f, -0.420898f, 0.279785f, -0.439941f,
+0.325195f, -0.443848f, 0.36084f, -0.444824f, 0.391113f, -0.444824f, 0.391113f, -0.428223f,
+0.399414f, -0.420898f, 0.401855f, -0.420898f, 0.40918f, -0.420898f, 0.417969f, -0.435059f,
+0.430176f, -0.432129f, 0.461914f, -0.420898f, 0.475098f, -0.410156f, 0.493164f, -0.398926f,
+0.51123f, -0.371094f, 0.518555f, -0.361816f, 0.540039f, -0.361816f, 0.554199f, -0.344238f,
+0.559082f, -0.327148f, 0.563965f, -0.310059f, 0.569824f, -0.26416f, 0.500977f, -0.23584f,
+0.48291f, -0.291992f, 0.47998f, -0.316895f, 0.475098f, -0.326172f, 0.472168f, -0.326172f,
+0.468262f, -0.326172f, 0.46582f, -0.327637f, 0.463379f, -0.329102f, 0.459961f, -0.333008f,
+0.436035f, -0.362793f, 0.428223f, -0.375f, 0.387207f, -0.394043f, 0.381348f, -0.403809f,
+0.377197f, -0.408447f, 0.373047f, -0.413086f, 0.367188f, -0.413086f, 0.36084f, -0.413086f,
+0.347168f, -0.408203f, 0.333496f, -0.414062f, 0.327148f, -0.414062f, 0.312988f, -0.412109f,
+0.289062f, -0.411133f, 0.255859f, -0.398926f, 0.248047f, -0.405762f, 0.242188f, -0.397949f,
+0.208984f, -0.37793f, 0.147949f, -0.325195f, 0.13623f, -0.314941f, 0.132324f, -0.290039f,
+0.11377f, -0.257812f, 0.106934f, -0.246094f, 0.106934f, -0.242188f, 0.106934f, -0.231445f,
+0.103516f, -0.228027f, 0.100098f, -0.224609f, 0.0898438f, -0.223145f, 0.0878906f,
+-0.215332f, 0.0878906f, -0.21582f, 0.0883789f, -0.214844f, 0.088623f, -0.214111f,
+0.0888672f, -0.213379f, 0.0888672f, -0.212891f, 0.104004f, -0.195801f, 0.105957f,
+-0.185059f, 0.0908203f, -0.172363f, 0.0908203f, -0.167969f, 0.0908203f, -0.167969f,
+0.0927734f, -0.162109f, 0.097168f, -0.166992f, 0.101074f, -0.166992f, 0.105469f,
+-0.166992f, 0.106934f, -0.164062f, 0.118164f, -0.12793f, 0.143066f, -0.0869141f,
+0.140137f, -0.0620117f, 0.144043f, -0.0581055f, 0.148926f, -0.0581055f, 0.154785f,
+-0.0581055f, 0.161133f, -0.0639648f, 0.170898f, -0.0610352f, 0.22998f, -0.0249023f,
+0.290039f, -0.019043f, 0.324219f, -0.0141602f, 0.362793f, -0.0209961f, 0.388184f,
+-0.0268555f, 0.419922f, -0.059082f, 0.442871f, -0.065918f, 0.454102f, -0.078125f,
+0.47998f, -0.131836f, 0.493164f, -0.143066f, 0.5f, -0.149902f, 0.5f, -0.154785f,
+0.5f, -0.157227f, 0.492188f, -0.180176f, 0.587891f, -0.201172f, 0.578125f, -0.174805f,
+0.573242f, -0.163086f, 0.559082f, -0.14502f, 0.548828f, -0.125977f, 0.536133f, -0.112793f,
+0.526855f, -0.101074f, 0.52002f, -0.0991211f, 0.506836f, -0.102051f, 0.501953f, -0.0927734f,
+0.489258f, -0.0698242f, 0.482666f, -0.0639648f, 0.476074f, -0.0581055f, 0.458984f,
+-0.0581055f, 0.458008f, -0.0581055f, 0.450195f, -0.059082f, 0.448242f, -0.0424805f,
+0.436279f, -0.0310059f, 0.424316f, -0.0195312f, 0.396973f, -0.00976562f, 0.370117f,
+-0.000976562f, 0.348145f, 0.00683594f, 0.304199f, 0.0078125f, 0.291992f, 0.00976562f,
+0.279785f, 0.0180664f, 0.269043f, 0.012207f, 0.26416f, 0.0117188f, 0.259277f, 0.0112305f,
+0.23291f, 0.00878906f, 0.221191f, 0.0078125f, 0.223145f, -0.00390625f, 0.211914f,
+-0.00585938f, 0.202148f, 0, 0.193848f, 0.00390625f, 0.180176f, 0.00390625f, 0.158203f,
+0.00390625f, 0.148926f, 0.000976562f, 0.145996f, 0.0131836f, 0.147949f, 0.0859375f,
+0.141113f, 0.119141f, 0.140137f, 0.132812f, 0.147949f, 0.132812f, 0.150879f, 0.223145f,
+0.13916f, 0.225098f, 0.13623f, 0.23291f, 0.138184f, 0.245117f, 0.144043f, 0.270996f,
+0.141113f, 0.282227f, 0.147949f, 0.276855f, 0.152832f, 0.279785f, 0.153809f, 0.312988f,
+0.157227f, 0.345215f, 0.15918f, 0.367188f, 0.15918f, 0.376465f, 0.144043f, 0.37793f,
+0.141113f, 0.384766f, 0.158203f, 0.38916f, 0.157227f, 0.398926f, 0.162109f, 0.422852f,
+0.164062f, 0.438965f, 0.158203f, 0.448242f, 0.145996f, 0.458008f, 0.13623f, 0.474121f,
+0.124023f, 0.478027f, 0.0981445f, 0.490234f, 0.0898438f, 0.491211f, 0.0717773f, 0.490234f,
+0.0708008f, 0.472168f, 0.0717773f, 0.456055f, 0.0751953f, 0.415039f, 0.0742188f,
+0.374023f, 0.074707f, 0.367676f, 0.0766602f, 0.36377f, 0.0786133f, 0.359863f, 0.0849609f,
+0.35498f, 0.0800781f, 0.323242f, 0.0893555f, 0.313965f, 0.0915527f, 0.310059f, 0.09375f,
+0.306152f, 0.0942383f, 0.296875f, 0.0859375f, 0.293945f, 0.083252f, 0.291016f, 0.0805664f,
+0.288086f, 0.0791016f, 0.282227f, 0.0830078f, 0.26416f, 0.0810547f, 0.250977f, 0.0800781f,
+0.199219f, 0.078125f, 0.160156f, 0.0830078f, 0.11377f, 0.0839844f, 0.101074f, 0.0952148f,
+0.090332f, 0.0952148f, 0.0800781f, 0.0952148f, 0.0717773f, 0.0908203f, 0.0541992f,
+0.0800781f, 0.0507812f, 0.0751953f, 0.0341797f, 0.0751953f, 0.0268555f, 0.0810547f,
+-0.13623f, 0.0869141f, -0.153809f, 0.0849609f, -0.171875f, 0.0830078f, -0.185059f,
+0.0742188f, -0.187988f, 0.0742188f, -0.201172f, 0.0717773f, -0.272949f, 0.0717773f,
+-0.280762f, 0.0751953f, -0.300781f, 0.0698242f, -0.341797f, 0.0698242f, -0.358887f,
+0.067627f, -0.363037f, 0.0654297f, -0.367188f, 0.0532227f, -0.374023f, 0.0546875f,
+-0.389648f, 0.059082f, -0.394043f, 0.0688477f, -0.399902f, 0.0917969f, -0.425781f,
+0.112793f, -0.437988f, 0.125f, -0.443848f, 0.134277f, -0.442871f, 0.147949f, -0.431152f,
+0.145996f, -0.421875f, 0.144043f, -0.407227f, 0.14502f, -0.398926f, 0.153809f, -0.397949f,
+0.170898f, -0.407227f, 0.200684f, -0.422363f, 0.2146f, -0.427246f, 0.228516f, -0.432129f,
+0.244141f, -0.432129f, 0.252441f, -0.432129f, 0.25708f, -0.429932f, 0.261719f, -0.427734f,
+0.266113f, -0.422852f, 0.274902f, -0.429199f, 0.279785f, -0.435059f, 0.291992f, -0.437988f,
+0.312012f, -0.441895f, 0.367188f, -0.440918f, 0.414062f, -0.441895f, 0.42334f, -0.441895f,
+0.436035f, -0.426758f, 0.437988f, -0.427246f, 0.439941f, -0.427734f, 0.441895f, -0.428223f,
+0.442871f, -0.428223f, 0.446777f, -0.428223f, 0.459961f, -0.420898f, 0.496094f, -0.402832f,
+0.505859f, -0.398926f, 0.508789f, -0.394043f, 0.51709f, -0.375f, 0.519531f, -0.371094f,
+0.525879f, -0.371094f, 0.531738f, -0.371094f, 0.539062f, -0.374023f, 0.553711f, -0.362793f,
+0.563965f, -0.345215f, 0.570801f, -0.333008f, 0.578857f, -0.301514f, 0.586914f, -0.27002f,
+0.586914f, -0.253906f, 0.586914f, -0.251953f, 0.583984f, -0.23584f, 0.583008f, -0.222168f,
+0.524902f, -0.245117f, 0.506836f, -0.254395f, 0.50293f, -0.26709f, 0.495117f, -0.290039f,
+0.470215f, -0.327148f, 0.467773f, -0.347168f, 0.460938f, -0.354004f, 0.435059f, -0.353027f,
+0.395996f, -0.378906f, 0.368164f, -0.381836f, 0.341797f, -0.391113f, 0.270996f, -0.390137f,
+0.259766f, -0.390137f, 0.246094f, -0.388184f, 0.206055f, -0.376953f, 0.186035f, -0.373047f,
+0.169922f, -0.366211f, 0.158203f, -0.362793f, 0.146973f, -0.358887f, 0.146973f, -0.333984f,
+0.146973f, -0.328125f, 0.132812f, -0.297852f, 0.132812f, -0.294922f, 0.132812f, -0.291992f,
+0.133789f, -0.291016f, 0.13623f, -0.287109f, 0.145996f, -0.283203f, 0.144043f, -0.258789f,
+0.145996f, -0.203125f, 0.145996f, -0.196777f, 0.137207f, -0.181152f, 0.147949f, -0.157227f,
+0.147949f, -0.140137f, 0.145996f, -0.0952148f, 0.14502f, -0.078125f, 0.15918f, -0.0708008f,
+0.184082f, -0.0600586f, 0.204102f, -0.0449219f, 0.209961f, -0.0532227f, 0.223145f,
+-0.0478516f, 0.265137f, -0.0449219f, 0.300781f, -0.0307617f, 0.34082f, -0.0371094f,
+0.366211f, -0.0361328f, 0.384766f, -0.0439453f, 0.404785f, -0.0532227f, 0.429199f,
+-0.0708008f, 0.448242f, -0.0830078f, 0.46582f, -0.10498f, 0.486816f, -0.120117f,
+0.504883f, -0.131836f, 0.506836f, -0.144043f, 0.508789f, -0.163086f, 0.520996f, -0.187012f,
+0.521484f, -0.187988f, 0.521729f, -0.188721f, 0.521973f, -0.189453f, 0.521973f, -0.189941f,
+0.52002f, -0.229004f, 0.519043f, -0.240234f, 0.405762f, -0.40918f, 0.405762f, -0.406738f,
+0.403809f, -0.404785f, 0.375977f, -0.382812f, 0.36084f, -0.367188f, 0.352051f, -0.36377f,
+0.338867f, -0.37207f, 0.330078f, -0.380859f, 0.300781f, -0.381836f, 0.272949f, -0.393066f,
+0.262207f, -0.395996f, 0.255859f, -0.385254f, 0.249023f, -0.382568f, 0.242188f, -0.379883f,
+0.221191f, -0.379883f, 0.205078f, -0.373047f, 0.192871f, -0.376953f, 0.183105f, -0.369141f,
+0.144043f, -0.338867f, 0.134277f, -0.326172f, 0.132812f, -0.291992f, 0.131836f, -0.254883f,
+0.121094f, -0.248047f, 0.130859f, -0.231445f, 0.130859f, -0.21582f, 0.138184f, -0.21582f,
+0.13916f, -0.202148f, 0.141113f, -0.13916f, 0.14209f, -0.105957f, 0.140137f, -0.0761719f,
+0.125f, -0.0673828f, 0.125f, -0.0620117f, 0.125f, -0.0610352f, 0.128906f, -0.0532227f,
+0.14209f, -0.0561523f, 0.141113f, -0.0517578f, 0.14502f, -0.0322266f, 0.14502f, -0.0297852f,
+0.14502f, -0.0224609f, 0.137207f, -0.0146484f, 0.129395f, -0.00683594f, 0.121094f,
+-0.00585938f, 0.102051f, -0.00390625f, 0.0732422f, 0.0112305f, 0.0610352f, 0.00390625f,
+0.0629883f, -0.00585938f, 0.0698242f, -0.0341797f, 0.0668945f, -0.0717773f, 0.0698242f,
+-0.0771484f, 0.0800781f, -0.0771484f, 0.0800781f, -0.0830078f, 0.0791016f, -0.0917969f,
+0.0732422f, -0.105957f, 0.0717773f, -0.125977f, 0.0678711f, -0.143066f, 0.0678711f,
+-0.144043f, 0.0678711f, -0.157227f, 0.0688477f, -0.172852f, 0.0708008f, -0.175293f,
+0.072998f, -0.177979f, 0.0751953f, -0.180664f, 0.0788574f, -0.186035f, 0.0825195f,
+-0.191406f, 0.0869141f, -0.199219f, 0.0917969f, -0.210938f, 0.0908203f, -0.21582f,
+0.0678711f, -0.21582f, 0.0678711f, -0.226074f, 0.0698242f, -0.263184f, 0.0668945f,
+-0.299805f, 0.0683594f, -0.304688f, 0.0732422f, -0.309082f, 0.0732422f, -0.323242f,
+0.0668945f, -0.329102f, 0.0649414f, -0.34082f, 0.0639648f, -0.367188f, 0.0532227f,
+-0.388184f, 0.0566406f, -0.405762f, 0.0688477f, -0.417969f, 0.0991211f, -0.434082f,
+0.117188f, -0.445801f, 0.130859f, -0.441895f, 0.135986f, -0.436523f, 0.141113f, -0.431152f,
+0.141113f, -0.418945f, 0.141113f, -0.416016f, 0.141113f, -0.402832f, 0.141113f, -0.384766f,
+0.148926f, -0.384766f, 0.150879f, -0.384766f, 0.175781f, -0.397949f, 0.200195f, -0.407227f,
+0.242188f, -0.430176f, 0.255859f, -0.436035f, 0.26709f, -0.433105f, 0.289062f, -0.439941f,
+0.308105f, -0.445801f, 0.317871f, -0.445801f, 0.338867f, -0.443848f, 0.348633f, -0.430176f,
+0.35498f, -0.430176f, 0.355957f, -0.430664f, 0.356445f, -0.430908f, 0.356934f, -0.431152f,
+0.35791f, -0.431152f, 0.369141f, -0.437012f, 0.373047f, -0.438965f, 0.375f, -0.438965f,
+0.387207f, -0.438965f, 0.397949f, -0.425781f, 0.405762f, -0.416504f, 0.405762f, -0.40918f,
+0.440918f, -0.143066f, 0.440918f, -0.123535f, 0.433838f, -0.110352f, 0.426758f, -0.097168f,
+0.416992f, -0.097168f, 0.415039f, -0.097168f, 0.407227f, -0.0991211f, 0.400879f,
+-0.0878906f, 0.39209f, -0.0639648f, 0.370117f, -0.0400391f, 0.359863f, -0.0258789f,
+0.346191f, -0.0249023f, 0.300781f, -0.00195312f, 0.279785f, 0.000976562f, 0.244141f,
+0.0131836f, 0.21582f, 0.0078125f, 0.172852f, 0.0180664f, 0.168457f, 0.0180664f, 0.125f,
+0.00878906f, 0.104492f, 0.00439453f, 0.0991211f, 0, 0.0800781f, -0.012207f, 0.0561523f,
+-0.0258789f, 0.0410156f, -0.0356445f, 0.0314941f, -0.0510254f, 0.0219727f, -0.0664062f,
+0.0219727f, -0.0791016f, 0.0219727f, -0.0869141f, 0.0385742f, -0.100342f, 0.0551758f,
+-0.11377f, 0.0751953f, -0.123047f, 0.0859375f, -0.108887f, 0.0952148f, -0.065918f,
+0.112793f, -0.0551758f, 0.141113f, -0.0332031f, 0.154785f, -0.0288086f, 0.181152f,
+-0.0161133f, 0.199219f, -0.0161133f, 0.210938f, -0.0141602f, 0.234863f, -0.0209961f,
+0.274902f, -0.0249023f, 0.294922f, -0.0351562f, 0.313965f, -0.0419922f, 0.332031f,
+-0.0527344f, 0.349121f, -0.0861816f, 0.366211f, -0.119629f, 0.366211f, -0.146973f,
+0.366211f, -0.157227f, 0.359863f, -0.165039f, 0.34082f, -0.191895f, 0.335938f, -0.204102f,
+0.324219f, -0.209961f, 0.317871f, -0.202148f, 0.307129f, -0.203125f, 0.280762f, -0.207031f,
+0.25f, -0.207031f, 0.242188f, -0.207031f, 0.229004f, -0.226074f, 0.21875f, -0.214355f,
+0.212402f, -0.211182f, 0.206055f, -0.208008f, 0.187988f, -0.205078f, 0.170898f, -0.202148f,
+0.161133f, -0.207031f, 0.148926f, -0.207031f, 0.13623f, -0.216797f, 0.120117f, -0.213867f,
+0.10498f, -0.221191f, 0.0839844f, -0.228027f, 0.0717773f, -0.231934f, 0.0629883f,
+-0.24707f, 0.0541992f, -0.262207f, 0.0541992f, -0.277832f, 0.0541992f, -0.301758f,
+0.0708008f, -0.328613f, 0.0874023f, -0.355469f, 0.117188f, -0.37793f, 0.140137f,
+-0.395508f, 0.171875f, -0.412598f, 0.203613f, -0.429688f, 0.231689f, -0.438965f,
+0.259766f, -0.448242f, 0.277832f, -0.448242f, 0.283203f, -0.448242f, 0.314941f, -0.437988f,
+0.329102f, -0.433105f, 0.362305f, -0.438965f, 0.37207f, -0.438965f, 0.385742f, -0.438965f,
+0.393799f, -0.43457f, 0.401855f, -0.430176f, 0.401855f, -0.423828f, 0.401855f, -0.41748f,
+0.387939f, -0.406006f, 0.374023f, -0.394531f, 0.353027f, -0.384766f, 0.337891f, -0.37793f,
+0.325195f, -0.378906f, 0.300781f, -0.379883f, 0.282227f, -0.384766f, 0.273926f, -0.401855f,
+0.26709f, -0.401855f, 0.258789f, -0.393066f, 0.244141f, -0.393066f, 0.22998f, -0.393066f,
+0.209961f, -0.390137f, 0.194824f, -0.394043f, 0.187012f, -0.388184f, 0.155762f, -0.370117f,
+0.123047f, -0.341797f, 0.123047f, -0.318848f, 0.123047f, -0.302734f, 0.132812f, -0.297852f,
+0.165039f, -0.283203f, 0.174805f, -0.277832f, 0.174805f, -0.266113f, 0.189941f, -0.257812f,
+0.206055f, -0.272949f, 0.213867f, -0.271973f, 0.295898f, -0.277832f, 0.334961f, -0.269043f,
+0.353027f, -0.271973f, 0.375977f, -0.256836f, 0.410156f, -0.237793f, 0.42041f, -0.230957f,
+0.428223f, -0.207031f, 0.432129f, -0.193848f, 0.440918f, -0.163086f, 0.440918f, -0.143066f,
+0.504883f, -0.0297852f, 0.501465f, -0.0170898f, 0.490234f, -0.012207f, 0.434082f,
+0.012207f, 0.418945f, 0.00341797f, 0.418945f, -0.0161133f, 0.419922f, -0.0439453f,
+0.411133f, -0.0458984f, 0.378906f, -0.0307617f, 0.333984f, -0.00878906f, 0.315918f,
+0, 0.256836f, 0.0112305f, 0.237793f, 0.0170898f, 0.23291f, 0.0170898f, 0.228027f,
+0.0170898f, 0.226074f, 0.0161133f, 0.208008f, 0.00878906f, 0.186035f, 0.0151367f,
+0.166016f, -0.00195312f, 0.126953f, 0.00390625f, 0.121094f, 0.00146484f, 0.109863f,
+-0.00488281f, 0.0986328f, -0.0112305f, 0.0908203f, -0.019043f, 0.0688477f, -0.043457f,
+0.0688477f, -0.0688477f, 0.0688477f, -0.0766602f, 0.0791016f, -0.0849609f, 0.0629883f,
+-0.0908203f, 0.0620117f, -0.109863f, 0.0610352f, -0.13623f, 0.0610352f, -0.147949f,
+0.0649414f, -0.155762f, 0.0742188f, -0.172852f, 0.0649414f, -0.200195f, 0.065918f,
+-0.229004f, 0.0649414f, -0.262207f, 0.0654297f, -0.265137f, 0.0751953f, -0.295898f,
+0.0751953f, -0.303223f, 0.065918f, -0.298828f, 0.0600586f, -0.305176f, 0.0600586f,
+-0.314941f, 0.0610352f, -0.374023f, 0.0610352f, -0.387695f, 0.0581055f, -0.39502f,
+0.0541992f, -0.400879f, 0.0541992f, -0.401855f, 0.0539551f, -0.402588f, 0.0537109f,
+-0.40332f, 0.0532227f, -0.403809f, 0.0532227f, -0.412109f, 0.0649414f, -0.418945f,
+0.0708008f, -0.421875f, 0.106934f, -0.437012f, 0.124512f, -0.443848f, 0.130859f,
+-0.443848f, 0.138184f, -0.443848f, 0.144043f, -0.430176f, 0.148926f, -0.418945f,
+0.13916f, -0.391602f, 0.13916f, -0.368164f, 0.14209f, -0.339844f, 0.141113f, -0.328125f,
+0.132812f, -0.304199f, 0.132324f, -0.291016f, 0.131836f, -0.285889f, 0.131348f, -0.280762f,
+0.130859f, -0.276855f, 0.130859f, -0.269531f, 0.133789f, -0.262207f, 0.14209f, -0.248047f,
+0.130859f, -0.210938f, 0.134766f, -0.199219f, 0.130859f, -0.178223f, 0.126953f, -0.149902f,
+0.126953f, -0.145996f, 0.12793f, -0.144043f, 0.134766f, -0.131836f, 0.138184f, -0.0800781f,
+0.141113f, -0.065918f, 0.150635f, -0.0600586f, 0.160156f, -0.0541992f, 0.189941f,
+-0.0449219f, 0.226074f, -0.0351562f, 0.23584f, -0.0332031f, 0.258789f, -0.0332031f,
+0.275391f, -0.0332031f, 0.283203f, -0.0361328f, 0.311035f, -0.046875f, 0.34082f,
+-0.0390625f, 0.348633f, -0.0415039f, 0.351074f, -0.0551758f, 0.367188f, -0.0639648f,
+0.38916f, -0.0942383f, 0.407227f, -0.108887f, 0.414551f, -0.118652f, 0.416016f, -0.13623f,
+0.419922f, -0.186035f, 0.423828f, -0.196777f, 0.413086f, -0.208008f, 0.414062f, -0.226074f,
+0.416016f, -0.303223f, 0.413086f, -0.329102f, 0.408203f, -0.358887f, 0.408203f, -0.366211f,
+0.416992f, -0.375f, 0.415039f, -0.383789f, 0.407227f, -0.384766f, 0.404785f, -0.399902f,
+0.404785f, -0.403809f, 0.40918f, -0.418945f, 0.40918f, -0.429199f, 0.416992f, -0.426758f,
+0.471191f, -0.445801f, 0.47168f, -0.445801f, 0.472168f, -0.446289f, 0.472656f, -0.446777f,
+0.473145f, -0.446777f, 0.478516f, -0.446777f, 0.482178f, -0.437744f, 0.48584f, -0.428711f,
+0.48584f, -0.414062f, 0.481934f, -0.314941f, 0.475098f, -0.23877f, 0.461914f, -0.244141f,
+0.456055f, -0.230469f, 0.456055f, -0.225098f, 0.458984f, -0.214844f, 0.464844f, -0.216797f,
+0.467773f, -0.216797f, 0.472168f, -0.216797f, 0.475098f, -0.214355f, 0.478027f, -0.211914f,
+0.478027f, -0.208008f, 0.473145f, -0.116211f, 0.48291f, -0.0991211f, 0.487793f, -0.0517578f,
+0.490234f, -0.0488281f, 0.494385f, -0.0441895f, 0.498535f, -0.0395508f, 0.504883f,
+-0.0297852f, 0.48584f, -0.103027f, 0.469238f, -0.0571289f, 0.469238f, -0.0551758f,
+0.471191f, -0.0478516f, 0.480957f, -0.0361328f, 0.477051f, -0.00976562f, 0.479004f,
+0.027832f, 0.474121f, 0.0400391f, 0.475098f, 0.0917969f, 0.467773f, 0.108887f, 0.462891f,
+0.132812f, 0.455078f, 0.148926f, 0.456055f, 0.173828f, 0.438965f, 0.21582f, 0.435059f,
+0.227051f, 0.420898f, 0.23584f, 0.383789f, 0.283203f, 0.361816f, 0.315918f, 0.349609f,
+0.334961f, 0.336914f, 0.34082f, 0.324219f, 0.348145f, 0.312012f, 0.36084f, 0.296875f,
+0.370117f, 0.288086f, 0.37793f, 0.26709f, 0.383789f, 0.266602f, 0.383789f, 0.23584f,
+0.397949f, 0.205078f, 0.40918f, 0.161133f, 0.421875f, 0.115234f, 0.416992f, 0.0908203f,
+0.414062f, 0.0732422f, 0.412598f, 0.0610352f, 0.405762f, 0.027832f, 0.384766f, 0.0112305f,
+0.380859f, -0.00195312f, 0.362793f, -0.027832f, 0.347168f, -0.0371094f, 0.339355f,
+-0.0371094f, 0.319824f, -0.0371094f, 0.299316f, -0.0229492f, 0.280762f, -0.0185547f,
+0.275391f, -0.00390625f, 0.273926f, 0.00195312f, 0.288086f, 0.00683594f, 0.301758f,
+0.0258789f, 0.328125f, 0.0449219f, 0.35791f, 0.0551758f, 0.368164f, 0.0600586f, 0.368164f,
+0.0610352f, 0.368164f, 0.0678711f, 0.367188f, 0.108887f, 0.383789f, 0.143066f, 0.38623f,
+0.149414f, 0.391113f, 0.155762f, 0.391113f, 0.160645f, 0.391113f, 0.168945f, 0.384766f,
+0.180176f, 0.38623f, 0.200684f, 0.38623f, 0.23877f, 0.369141f, 0.272461f, 0.352539f,
+0.279785f, 0.344238f, 0.316895f, 0.306152f, 0.339844f, 0.291992f, 0.352539f, 0.282227f,
+0.36084f, 0.255859f, 0.373047f, 0.21582f, 0.391113f, 0.187988f, 0.388184f, 0.166992f,
+0.396973f, 0.12793f, 0.397949f, 0.0878906f, 0.397949f, 0.0673828f, 0.407227f, 0.046875f,
+0.415039f, 0.0200195f, 0.40918f, -0.00292969f, 0.403809f, -0.0708008f, 0.402832f,
+-0.0820312f, 0.402832f, -0.0869141f, 0.411133f, -0.112793f, 0.405762f, -0.120117f,
+0.391113f, -0.112793f, 0.374023f, -0.103027f, 0.359863f, -0.0878906f, 0.312988f,
+-0.0581055f, 0.289062f, -0.0351562f, 0.251953f, -0.0078125f, 0.236328f, 0.00292969f,
+0.228027f, 0.00585938f, 0.195801f, 0.0112305f, 0.178223f, 0.0180664f, 0.16748f, 0.0209961f,
+0.162109f, 0.0209961f, 0.143066f, 0.0209961f, 0.111328f, 0.00878906f, 0.0795898f,
+-0.00341797f, 0.0678711f, -0.0161133f, 0.0488281f, -0.0351562f, 0.0488281f, -0.0649414f,
+0.0498047f, -0.0751953f, 0.0600586f, -0.0820312f, 0.0600586f, -0.0878906f, 0.0600586f,
+-0.0888672f, 0.0598145f, -0.0895996f, 0.0595703f, -0.090332f, 0.059082f, -0.0908203f,
+0.0488281f, -0.10498f, 0.0478516f, -0.119141f, 0.0507812f, -0.131836f, 0.0698242f,
+-0.175781f, 0.065918f, -0.192871f, 0.065918f, -0.199219f, 0.065918f, -0.20459f, 0.0698242f,
+-0.223145f, 0.0791016f, -0.258789f, 0.0820312f, -0.271484f, 0.0839844f, -0.283203f,
+0.0849609f, -0.320801f, 0.0942383f, -0.358887f, 0.0942383f, -0.365723f, 0.0869141f,
+-0.375977f, 0.0732422f, -0.37793f, 0.0717773f, -0.38623f, 0.0898438f, -0.407227f,
+0.101074f, -0.411133f, 0.118164f, -0.416016f, 0.166992f, -0.443848f, 0.169922f, -0.443848f,
+0.177246f, -0.443848f, 0.181641f, -0.437988f, 0.186035f, -0.432129f, 0.186035f, -0.422852f,
+0.186035f, -0.419922f, 0.170898f, -0.382812f, 0.164062f, -0.346191f, 0.151855f, -0.290039f,
+0.148926f, -0.256836f, 0.146484f, -0.249512f, 0.141113f, -0.248047f, 0.125977f, -0.244141f,
+0.118164f, -0.241211f, 0.118164f, -0.23291f, 0.118164f, -0.221191f, 0.138184f, -0.221191f,
+0.124023f, -0.120117f, 0.120117f, -0.0908203f, 0.123047f, -0.0830078f, 0.129883f,
+-0.0742188f, 0.144043f, -0.0507812f, 0.171875f, -0.0400391f, 0.185059f, -0.0249023f,
+0.191895f, -0.0219727f, 0.195801f, -0.0219727f, 0.211914f, -0.0332031f, 0.258789f,
+-0.0488281f, 0.278809f, -0.0629883f, 0.312988f, -0.0869141f, 0.345215f, -0.118164f,
+0.366211f, -0.130859f, 0.375f, -0.13623f, 0.393066f, -0.183105f, 0.395996f, -0.185059f,
+0.397949f, -0.193848f, 0.408203f, -0.206055f, 0.403809f, -0.23291f, 0.408203f, -0.240234f,
+0.405762f, -0.26123f, 0.40918f, -0.271973f, 0.400879f, -0.314941f, 0.396973f, -0.374023f,
+0.382812f, -0.402832f, 0.381836f, -0.404785f, 0.381836f, -0.40918f, 0.381836f, -0.416992f,
+0.402832f, -0.423828f, 0.417969f, -0.437988f, 0.446777f, -0.441895f, 0.458008f, -0.444824f,
+0.472168f, -0.435059f, 0.472168f, -0.428223f, 0.472168f, -0.425781f, 0.469238f, -0.408203f,
+0.471191f, -0.373047f, 0.466797f, -0.358887f, 0.466797f, -0.346191f, 0.460938f, -0.324219f,
+0.461914f, -0.316895f, 0.469238f, -0.299316f, 0.473145f, -0.290527f, 0.477051f, -0.281738f,
+0.477051f, -0.276855f, 0.477051f, -0.26416f, 0.479004f, -0.23291f, 0.472168f, -0.21582f,
+0.470215f, -0.209961f, 0.470215f, -0.207031f, 0.470215f, -0.193359f, 0.48584f, -0.179199f,
+0.484863f, -0.166992f
+};
+
+const unsigned char PapyruskNormalVerbs[] = {
+6, 0, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 2, 1, 1, 5, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1,
+2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1,
+1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2,
+2, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2,
+2, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1,
+2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1,
+5, 6, 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1,
+1, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2,
+2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1,
+2, 1, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 5, 0, 2, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1,
+1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 5, 6, 0, 2, 1, 2, 2, 1, 1, 1, 1,
+1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1,
+1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 5, 6, 0, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,
+1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1,
+1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1,
+1, 2, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 5, 0, 2, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 6, 0, 1, 1, 1,
+1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2,
+1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 2, 2, 1,
+1, 1, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1,
+2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 5, 6, 0, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2,
+1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2,
+1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 1, 2, 2,
+2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2,
+2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 5, 0, 1, 1, 1, 1,
+2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1,
+2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 5, 6, 0, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1,
+1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 5, 0, 2, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 5, 6, 0, 2, 1, 1, 1, 1, 1,
+1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1,
+1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 5,
+6, 0, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1,
+1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 5, 6, 0, 2, 1, 2, 1, 1, 1,
+1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1,
+1, 2, 1, 2, 2, 2, 1, 1, 2, 2, 1, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2,
+2, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+2, 2, 2, 2, 1, 1, 1, 2, 1, 2, 2, 2, 1, 1, 1, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2,
+2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1,
+1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 5, 6
+};
+
+const unsigned PapyruskNormalCharCodes[] = {
+32, 33, 72, 84, 97,
+99, 101, 102, 108, 110, 111, 112, 114, 115, 117, 121
+};
+
+const SkFixed PapyruskNormalWidths[] = {
+0x00003a20, 0x000042e0, 0x0000c3e0, 0x0000b1e0, 0x00008940, 0x00007f80, 0x000087e0,
+0x000064a0, 0x00003860, 0x00008c80, 0x00009920, 0x00009d20, 0x000062e0, 0x000078e0,
+0x00008f20, 0x00008a40
+};
+
+const int PapyruskNormalCharCodesCount = (int) SK_ARRAY_COUNT(PapyruskNormalCharCodes);
+
+const SkPaint::FontMetrics PapyruskNormalMetrics = {
+0x00000003, -0.944824f, -0.939941f, 0.603027f, 0.603027f, 0, 2.51855f, 0, -0.5625f,
+1.95605f, 0.464355f, 0, 0.0673828f, 0.166504f
+};
+
+const SkScalar TimesNewRomankNormalPoints[] = {
+0.175781f, -0.175293f, 0.157227f, -0.175293f, 0.114258f, -0.570801f, 0.111328f, -0.59668f,
+0.111328f, -0.609375f, 0.111328f, -0.640137f, 0.127686f, -0.658691f, 0.144043f, -0.677246f,
+0.166992f, -0.677246f, 0.189941f, -0.677246f, 0.205811f, -0.658691f, 0.22168f, -0.640137f,
+0.22168f, -0.603516f, 0.22168f, -0.591797f, 0.219727f, -0.570801f, 0.166016f, -0.0942383f,
+0.188477f, -0.0942383f, 0.204346f, -0.0783691f, 0.220215f, -0.0625f, 0.220215f, -0.0405273f,
+0.220215f, -0.0180664f, 0.204346f, -0.00219727f, 0.188477f, 0.0136719f, 0.166016f,
+0.0136719f, 0.143555f, 0.0136719f, 0.127686f, -0.00219727f, 0.111816f, -0.0180664f,
+0.111816f, -0.0405273f, 0.111816f, -0.0625f, 0.127686f, -0.0783691f, 0.143555f, -0.0942383f,
+0.166016f, -0.0942383f, 0.28125f, -0.39209f, 0.254883f, -0.534668f, 0.244141f, -0.59375f,
+0.243164f, -0.605957f, 0.243164f, -0.618164f, 0.243164f, -0.648926f, 0.256836f, -0.663086f,
+0.270508f, -0.677246f, 0.292969f, -0.677246f, 0.313965f, -0.677246f, 0.327881f, -0.663086f,
+0.341797f, -0.648926f, 0.341797f, -0.625f, 0.341797f, -0.583496f, 0.33252f, -0.535156f,
+0.304688f, -0.39209f, 0.102539f, -0.39209f, 0.0756836f, -0.536621f, 0.0649414f, -0.596191f,
+0.0649414f, -0.617676f, 0.0649414f, -0.648926f, 0.0778809f, -0.663086f, 0.0908203f,
+-0.677246f, 0.112793f, -0.677246f, 0.134277f, -0.677246f, 0.148438f, -0.662842f,
+0.162598f, -0.648438f, 0.162598f, -0.624512f, 0.162598f, -0.605469f, 0.149902f, -0.536133f,
+0.123535f, -0.39209f, 0.0561523f, 0.0136719f, 0.101562f, -0.208496f, 0.0180664f,
+-0.208496f, 0.0180664f, -0.248535f, 0.109375f, -0.248535f, 0.143066f, -0.416016f,
+0.0180664f, -0.416016f, 0.0180664f, -0.455078f, 0.152344f, -0.455078f, 0.196777f,
+-0.677246f, 0.237305f, -0.677246f, 0.192871f, -0.455078f, 0.357422f, -0.455078f,
+0.404785f, -0.677246f, 0.445312f, -0.677246f, 0.398926f, -0.455078f, 0.481934f, -0.455078f,
+0.481934f, -0.416016f, 0.391602f, -0.416016f, 0.357422f, -0.248535f, 0.481934f, -0.248535f,
+0.481934f, -0.208496f, 0.349121f, -0.208496f, 0.303711f, 0.0136719f, 0.26416f, 0.0136719f,
+0.308594f, -0.208496f, 0.143066f, -0.208496f, 0.0966797f, 0.0136719f, 0.150391f,
+-0.248535f, 0.315918f, -0.248535f, 0.351074f, -0.416016f, 0.18457f, -0.416016f, 0.0527344f,
+-0.163086f, 0.0742188f, -0.163086f, 0.0795898f, -0.0961914f, 0.116211f, -0.0605469f,
+0.152832f, -0.0249023f, 0.225586f, -0.0180664f, 0.225586f, -0.303223f, 0.115723f,
+-0.371094f, 0.0791016f, -0.42334f, 0.0532227f, -0.460449f, 0.0532227f, -0.513672f,
+0.0532227f, -0.57373f, 0.0979004f, -0.618652f, 0.142578f, -0.663574f, 0.225586f,
+-0.672852f, 0.225586f, -0.717773f, 0.256836f, -0.717773f, 0.256836f, -0.672852f,
+0.296875f, -0.67041f, 0.324219f, -0.663574f, 0.338379f, -0.660156f, 0.417969f, -0.629883f,
+0.417969f, -0.483887f, 0.398926f, -0.483887f, 0.392578f, -0.561523f, 0.358643f, -0.597412f,
+0.324707f, -0.633301f, 0.256836f, -0.640137f, 0.256836f, -0.39209f, 0.379883f, -0.306152f,
+0.414795f, -0.265381f, 0.449707f, -0.224609f, 0.449707f, -0.164062f, 0.449707f, -0.0966797f,
+0.398682f, -0.0454102f, 0.347656f, 0.00585938f, 0.256836f, 0.0136719f, 0.256836f,
+0.0761719f, 0.225586f, 0.0761719f, 0.225586f, 0.0136719f, 0.179688f, 0.0117188f,
+0.140137f, 0.00317383f, 0.100586f, -0.00537109f, 0.0527344f, -0.0249023f, 0.225586f,
+-0.412598f, 0.225586f, -0.639648f, 0.176758f, -0.633789f, 0.153076f, -0.608643f,
+0.129395f, -0.583496f, 0.129395f, -0.54541f, 0.129395f, -0.509766f, 0.150879f, -0.47876f,
+0.172363f, -0.447754f, 0.225586f, -0.412598f, 0.256836f, -0.0180664f, 0.293457f,
+-0.0244141f, 0.312988f, -0.0361328f, 0.340332f, -0.0532227f, 0.356201f, -0.0808105f,
+0.37207f, -0.108398f, 0.37207f, -0.139648f, 0.37207f, -0.171875f, 0.352783f, -0.200684f,
+0.333496f, -0.229492f, 0.256836f, -0.282227f, 0.679688f, -0.677246f, 0.197266f, 0.0273438f,
+0.153809f, 0.0273438f, 0.63623f, -0.677246f, 0.177734f, -0.677246f, 0.243652f, -0.677246f,
+0.280029f, -0.622559f, 0.316406f, -0.567871f, 0.316406f, -0.49707f, 0.316406f, -0.412109f,
+0.275391f, -0.365723f, 0.234375f, -0.319336f, 0.176758f, -0.319336f, 0.138184f, -0.319336f,
+0.105957f, -0.340576f, 0.0737305f, -0.361816f, 0.0544434f, -0.403809f, 0.0351562f,
+-0.445801f, 0.0351562f, -0.49707f, 0.0351562f, -0.54834f, 0.0546875f, -0.591553f,
+0.0742188f, -0.634766f, 0.108154f, -0.656006f, 0.14209f, -0.677246f, 0.177734f, -0.677246f,
+0.17627f, -0.649902f, 0.151367f, -0.649902f, 0.13208f, -0.620605f, 0.112793f, -0.591309f,
+0.112793f, -0.497559f, 0.112793f, -0.429688f, 0.123535f, -0.394043f, 0.131836f, -0.367188f,
+0.149414f, -0.352539f, 0.159668f, -0.34375f, 0.174805f, -0.34375f, 0.198242f, -0.34375f,
+0.214844f, -0.369141f, 0.239258f, -0.406738f, 0.239258f, -0.494629f, 0.239258f, -0.587402f,
+0.215332f, -0.625f, 0.199707f, -0.649902f, 0.17627f, -0.649902f, 0.657227f, -0.328613f,
+0.691895f, -0.328613f, 0.726318f, -0.306641f, 0.760742f, -0.284668f, 0.779541f, -0.242676f,
+0.79834f, -0.200684f, 0.79834f, -0.150391f, 0.79834f, -0.0639648f, 0.756836f, -0.0183105f,
+0.715332f, 0.0273438f, 0.658691f, 0.0273438f, 0.623047f, 0.0273438f, 0.5896f, 0.00537109f,
+0.556152f, -0.0166016f, 0.536865f, -0.057373f, 0.517578f, -0.0981445f, 0.517578f,
+-0.150391f, 0.517578f, -0.20166f, 0.536865f, -0.244141f, 0.556152f, -0.286621f, 0.5896f,
+-0.307617f, 0.623047f, -0.328613f, 0.657227f, -0.328613f, 0.657715f, -0.302734f,
+0.634277f, -0.302734f, 0.617188f, -0.276367f, 0.595215f, -0.242188f, 0.595215f, -0.146973f,
+0.595215f, -0.0595703f, 0.617676f, -0.0249023f, 0.634277f, 0, 0.657715f, 0, 0.680176f,
+0, 0.697754f, -0.0268555f, 0.721191f, -0.0625f, 0.721191f, -0.149414f, 0.721191f,
+-0.241211f, 0.697754f, -0.277832f, 0.681641f, -0.302734f, 0.657715f, -0.302734f,
+0.510254f, -0.42627f, 0.715332f, -0.42627f, 0.715332f, -0.408203f, 0.672852f, -0.404785f,
+0.652588f, -0.389404f, 0.632324f, -0.374023f, 0.589355f, -0.296387f, 0.546387f, -0.21875f,
+0.492676f, -0.151367f, 0.536133f, -0.100586f, 0.570312f, -0.0803223f, 0.604492f,
+-0.0600586f, 0.63916f, -0.0600586f, 0.672852f, -0.0600586f, 0.696289f, -0.0783691f,
+0.719727f, -0.0966797f, 0.729492f, -0.132324f, 0.747559f, -0.119141f, 0.729492f,
+-0.050293f, 0.689453f, -0.0175781f, 0.649414f, 0.0151367f, 0.596191f, 0.0151367f,
+0.556152f, 0.0151367f, 0.514893f, -0.0065918f, 0.473633f, -0.0283203f, 0.424805f,
+-0.0800781f, 0.364258f, -0.0263672f, 0.315674f, -0.00561523f, 0.26709f, 0.0151367f,
+0.211914f, 0.0151367f, 0.131348f, 0.0151367f, 0.0839844f, -0.027832f, 0.0366211f,
+-0.0708008f, 0.0366211f, -0.130371f, 0.0366211f, -0.189453f, 0.0791016f, -0.248291f,
+0.121582f, -0.307129f, 0.23877f, -0.370117f, 0.21582f, -0.420898f, 0.20752f, -0.453369f,
+0.199219f, -0.48584f, 0.199219f, -0.515625f, 0.199219f, -0.599121f, 0.260742f, -0.643066f,
+0.308594f, -0.677246f, 0.369629f, -0.677246f, 0.427734f, -0.677246f, 0.464355f, -0.642822f,
+0.500977f, -0.608398f, 0.500977f, -0.558105f, 0.500977f, -0.506348f, 0.465576f, -0.467285f,
+0.430176f, -0.428223f, 0.340332f, -0.381836f, 0.402344f, -0.271484f, 0.469727f, -0.179688f,
+0.555664f, -0.282227f, 0.555664f, -0.352539f, 0.555664f, -0.375f, 0.541016f, -0.392578f,
+0.530273f, -0.405762f, 0.510254f, -0.408203f, 0.32373f, -0.413574f, 0.384277f, -0.442383f,
+0.414307f, -0.479004f, 0.444336f, -0.515625f, 0.444336f, -0.560547f, 0.444336f, -0.595703f,
+0.422607f, -0.618652f, 0.400879f, -0.641602f, 0.368652f, -0.641602f, 0.326172f, -0.641602f,
+0.304443f, -0.612061f, 0.282715f, -0.58252f, 0.282715f, -0.554199f, 0.282715f, -0.530273f,
+0.291016f, -0.500732f, 0.299316f, -0.471191f, 0.32373f, -0.413574f, 0.399414f, -0.108398f,
+0.334961f, -0.196289f, 0.310059f, -0.236816f, 0.285156f, -0.277344f, 0.255371f, -0.337402f,
+0.196777f, -0.303711f, 0.167236f, -0.263184f, 0.137695f, -0.222656f, 0.137695f, -0.175293f,
+0.137695f, -0.123047f, 0.171387f, -0.0834961f, 0.205078f, -0.0439453f, 0.262207f,
+-0.0439453f, 0.292969f, -0.0439453f, 0.321533f, -0.0561523f, 0.350098f, -0.0683594f,
+0.399414f, -0.108398f, 0.0771484f, -0.39209f, 0.0507812f, -0.536621f, 0.0395508f,
+-0.59668f, 0.0395508f, -0.617676f, 0.0395508f, -0.648926f, 0.0522461f, -0.663086f,
+0.0649414f, -0.677246f, 0.0869141f, -0.677246f, 0.108887f, -0.677246f, 0.123291f,
+-0.662842f, 0.137695f, -0.648438f, 0.137695f, -0.625f, 0.137695f, -0.606934f, 0.125f,
+-0.536133f, 0.0986328f, -0.39209f, 0.310547f, 0.195801f, 0.310547f, 0.213867f, 0.236816f,
+0.176758f, 0.1875f, 0.126953f, 0.117188f, 0.0561523f, 0.0791016f, -0.0400391f, 0.0410156f,
+-0.13623f, 0.0410156f, -0.239746f, 0.0410156f, -0.391113f, 0.115723f, -0.515869f,
+0.19043f, -0.640625f, 0.310547f, -0.694336f, 0.310547f, -0.673828f, 0.250488f, -0.640625f,
+0.211914f, -0.583008f, 0.17334f, -0.525391f, 0.154297f, -0.437012f, 0.135254f, -0.348633f,
+0.135254f, -0.252441f, 0.135254f, -0.147949f, 0.151367f, -0.0625f, 0.164062f, 0.00488281f,
+0.182129f, 0.0456543f, 0.200195f, 0.0864258f, 0.230713f, 0.124023f, 0.26123f, 0.161621f,
+0.310547f, 0.195801f, 0.0224609f, -0.673828f, 0.0224609f, -0.694336f, 0.0966797f,
+-0.657715f, 0.145996f, -0.60791f, 0.21582f, -0.536621f, 0.253906f, -0.440674f, 0.291992f,
+-0.344727f, 0.291992f, -0.240723f, 0.291992f, -0.0893555f, 0.217529f, 0.0354004f,
+0.143066f, 0.160156f, 0.0224609f, 0.213867f, 0.0224609f, 0.195801f, 0.0825195f, 0.162109f,
+0.121338f, 0.104736f, 0.160156f, 0.0473633f, 0.178955f, -0.0412598f, 0.197754f, -0.129883f,
+0.197754f, -0.226074f, 0.197754f, -0.330078f, 0.181641f, -0.416016f, 0.169434f, -0.483398f,
+0.151123f, -0.523926f, 0.132812f, -0.564453f, 0.102539f, -0.602051f, 0.0722656f,
+-0.639648f, 0.0224609f, -0.673828f, 0.241211f, -0.509766f, 0.239258f, -0.543457f,
+0.227539f, -0.57666f, 0.210938f, -0.624512f, 0.210938f, -0.642578f, 0.210938f, -0.667969f,
+0.2229f, -0.681152f, 0.234863f, -0.694336f, 0.252441f, -0.694336f, 0.267578f, -0.694336f,
+0.278809f, -0.681152f, 0.290039f, -0.667969f, 0.290039f, -0.643555f, 0.290039f, -0.621582f,
+0.2771f, -0.582275f, 0.26416f, -0.542969f, 0.26123f, -0.509766f, 0.288086f, -0.526855f,
+0.30957f, -0.55127f, 0.342773f, -0.589844f, 0.358887f, -0.599121f, 0.375f, -0.608398f,
+0.391602f, -0.608398f, 0.407715f, -0.608398f, 0.418701f, -0.597412f, 0.429688f, -0.586426f,
+0.429688f, -0.571289f, 0.429688f, -0.553223f, 0.413574f, -0.539062f, 0.397461f, -0.524902f,
+0.333008f, -0.510742f, 0.29541f, -0.502441f, 0.270508f, -0.491699f, 0.295898f, -0.478516f,
+0.33252f, -0.47168f, 0.391602f, -0.460938f, 0.409912f, -0.444824f, 0.428223f, -0.428711f,
+0.428223f, -0.409668f, 0.428223f, -0.39502f, 0.417236f, -0.384277f, 0.40625f, -0.373535f,
+0.391602f, -0.373535f, 0.376953f, -0.373535f, 0.359131f, -0.383789f, 0.341309f, -0.394043f,
+0.311035f, -0.429688f, 0.291016f, -0.453613f, 0.26123f, -0.474609f, 0.262207f, -0.446777f,
+0.272461f, -0.414062f, 0.290039f, -0.356445f, 0.290039f, -0.335449f, 0.290039f, -0.315918f,
+0.27832f, -0.30249f, 0.266602f, -0.289062f, 0.253418f, -0.289062f, 0.235352f, -0.289062f,
+0.220703f, -0.303223f, 0.210449f, -0.313477f, 0.210449f, -0.335938f, 0.210449f, -0.359375f,
+0.22168f, -0.392334f, 0.23291f, -0.425293f, 0.23584f, -0.437744f, 0.23877f, -0.450195f,
+0.241211f, -0.474609f, 0.212402f, -0.455566f, 0.190918f, -0.432129f, 0.155273f, -0.39209f,
+0.137207f, -0.381348f, 0.124512f, -0.373535f, 0.11084f, -0.373535f, 0.0942383f, -0.373535f,
+0.0825195f, -0.384766f, 0.0708008f, -0.395996f, 0.0708008f, -0.409668f, 0.0708008f,
+-0.421875f, 0.0808105f, -0.435303f, 0.0908203f, -0.44873f, 0.11084f, -0.45752f, 0.124023f,
+-0.463379f, 0.170898f, -0.473145f, 0.201172f, -0.479492f, 0.22998f, -0.491699f, 0.203613f,
+-0.504883f, 0.166992f, -0.512207f, 0.106934f, -0.524902f, 0.0927734f, -0.535156f,
+0.0708008f, -0.55127f, 0.0708008f, -0.574219f, 0.0708008f, -0.587402f, 0.0817871f,
+-0.598389f, 0.0927734f, -0.609375f, 0.107422f, -0.609375f, 0.123535f, -0.609375f,
+0.141602f, -0.599121f, 0.159668f, -0.588867f, 0.186523f, -0.557861f, 0.213379f, -0.526855f,
+0.241211f, -0.509766f, 0.26123f, -0.0688477f, 0.26123f, -0.3125f, 0.0180664f, -0.3125f,
+0.0180664f, -0.352539f, 0.26123f, -0.352539f, 0.26123f, -0.595215f, 0.300293f, -0.595215f,
+0.300293f, -0.352539f, 0.544434f, -0.352539f, 0.544434f, -0.3125f, 0.300293f, -0.3125f,
+0.300293f, -0.0688477f, 0.0537109f, 0.166504f, 0.0537109f, 0.14502f, 0.104004f, 0.128418f,
+0.131592f, 0.0935059f, 0.15918f, 0.0585938f, 0.15918f, 0.0195312f, 0.15918f, 0.0102539f,
+0.154785f, 0.00390625f, 0.151367f, -0.000488281f, 0.147949f, -0.000488281f, 0.142578f,
+-0.000488281f, 0.124512f, 0.00927734f, 0.115723f, 0.0136719f, 0.105957f, 0.0136719f,
+0.0820312f, 0.0136719f, 0.0678711f, -0.000488281f, 0.0537109f, -0.0146484f, 0.0537109f,
+-0.0395508f, 0.0537109f, -0.0634766f, 0.0720215f, -0.0805664f, 0.090332f, -0.0976562f,
+0.116699f, -0.0976562f, 0.148926f, -0.0976562f, 0.174072f, -0.0695801f, 0.199219f,
+-0.0415039f, 0.199219f, 0.00488281f, 0.199219f, 0.0551758f, 0.164307f, 0.0983887f,
+0.129395f, 0.141602f, 0.0537109f, 0.166504f, 0.0405273f, -0.26123f, 0.292969f, -0.26123f,
+0.292969f, -0.1875f, 0.0405273f, -0.1875f, 0.125f, -0.0947266f, 0.147949f, -0.0947266f,
+0.163574f, -0.0788574f, 0.179199f, -0.0629883f, 0.179199f, -0.0405273f, 0.179199f,
+-0.0180664f, 0.16333f, -0.00219727f, 0.147461f, 0.0136719f, 0.125f, 0.0136719f, 0.102539f,
+0.0136719f, 0.0866699f, -0.00219727f, 0.0708008f, -0.0180664f, 0.0708008f, -0.0405273f,
+0.0708008f, -0.0634766f, 0.0866699f, -0.0791016f, 0.102539f, -0.0947266f, 0.125f,
+-0.0947266f, 0.280273f, -0.694336f, 0.0405273f, 0.0136719f, 0.00146484f, 0.0136719f,
+0.241211f, -0.694336f, 0.117188f, -0.597168f, 0.27832f, -0.675781f, 0.294434f, -0.675781f,
+0.294434f, -0.116699f, 0.294434f, -0.0610352f, 0.299072f, -0.0473633f, 0.303711f,
+-0.0336914f, 0.318359f, -0.0263672f, 0.333008f, -0.019043f, 0.37793f, -0.0180664f,
+0.37793f, 0, 0.128906f, 0, 0.128906f, -0.0180664f, 0.175781f, -0.019043f, 0.189453f,
+-0.026123f, 0.203125f, -0.0332031f, 0.208496f, -0.045166f, 0.213867f, -0.0571289f,
+0.213867f, -0.116699f, 0.213867f, -0.474121f, 0.213867f, -0.546387f, 0.208984f, -0.566895f,
+0.205566f, -0.58252f, 0.196533f, -0.589844f, 0.1875f, -0.597168f, 0.174805f, -0.597168f,
+0.156738f, -0.597168f, 0.124512f, -0.582031f, 0.458496f, -0.127441f, 0.412109f, 0,
+0.0214844f, 0, 0.0214844f, -0.0180664f, 0.193848f, -0.175293f, 0.26416f, -0.274902f,
+0.334473f, -0.374512f, 0.334473f, -0.457031f, 0.334473f, -0.52002f, 0.295898f, -0.560547f,
+0.257324f, -0.601074f, 0.203613f, -0.601074f, 0.154785f, -0.601074f, 0.115967f, -0.57251f,
+0.0771484f, -0.543945f, 0.0585938f, -0.48877f, 0.0405273f, -0.48877f, 0.0527344f,
+-0.579102f, 0.103271f, -0.627441f, 0.153809f, -0.675781f, 0.229492f, -0.675781f,
+0.310059f, -0.675781f, 0.364014f, -0.624023f, 0.417969f, -0.572266f, 0.417969f, -0.501953f,
+0.417969f, -0.45166f, 0.394531f, -0.401367f, 0.358398f, -0.322266f, 0.277344f, -0.233887f,
+0.155762f, -0.101074f, 0.125488f, -0.0737305f, 0.29834f, -0.0737305f, 0.351074f,
+-0.0737305f, 0.372314f, -0.0776367f, 0.393555f, -0.081543f, 0.410645f, -0.0935059f,
+0.427734f, -0.105469f, 0.44043f, -0.127441f, 0.0507812f, -0.536133f, 0.0791016f,
+-0.603027f, 0.122314f, -0.639404f, 0.165527f, -0.675781f, 0.22998f, -0.675781f, 0.30957f,
+-0.675781f, 0.352051f, -0.624023f, 0.384277f, -0.585449f, 0.384277f, -0.541504f,
+0.384277f, -0.469238f, 0.293457f, -0.39209f, 0.354492f, -0.368164f, 0.385742f, -0.32373f,
+0.416992f, -0.279297f, 0.416992f, -0.219238f, 0.416992f, -0.133301f, 0.362305f, -0.0703125f,
+0.291016f, 0.0117188f, 0.155762f, 0.0117188f, 0.0888672f, 0.0117188f, 0.0646973f,
+-0.00488281f, 0.0405273f, -0.0214844f, 0.0405273f, -0.0405273f, 0.0405273f, -0.0546875f,
+0.052002f, -0.0654297f, 0.0634766f, -0.0761719f, 0.0795898f, -0.0761719f, 0.0917969f,
+-0.0761719f, 0.104492f, -0.0722656f, 0.112793f, -0.0698242f, 0.14209f, -0.0544434f,
+0.171387f, -0.0390625f, 0.182617f, -0.0361328f, 0.200684f, -0.0307617f, 0.221191f,
+-0.0307617f, 0.270996f, -0.0307617f, 0.307861f, -0.0693359f, 0.344727f, -0.10791f,
+0.344727f, -0.160645f, 0.344727f, -0.199219f, 0.327637f, -0.23584f, 0.314941f, -0.263184f,
+0.299805f, -0.277344f, 0.278809f, -0.296875f, 0.242188f, -0.312744f, 0.205566f, -0.328613f,
+0.16748f, -0.328613f, 0.151855f, -0.328613f, 0.151855f, -0.343262f, 0.19043f, -0.348145f,
+0.229248f, -0.371094f, 0.268066f, -0.394043f, 0.285645f, -0.42627f, 0.303223f, -0.458496f,
+0.303223f, -0.49707f, 0.303223f, -0.547363f, 0.271729f, -0.578369f, 0.240234f, -0.609375f,
+0.193359f, -0.609375f, 0.117676f, -0.609375f, 0.0668945f, -0.52832f, 0.465332f, -0.244141f,
+0.465332f, -0.174805f, 0.376465f, -0.174805f, 0.376465f, 0, 0.295898f, 0, 0.295898f,
+-0.174805f, 0.015625f, -0.174805f, 0.015625f, -0.237305f, 0.322754f, -0.675781f,
+0.376465f, -0.675781f, 0.376465f, -0.244141f, 0.295898f, -0.244141f, 0.295898f, -0.572754f,
+0.0634766f, -0.244141f, 0.434082f, -0.662109f, 0.395996f, -0.579102f, 0.196777f,
+-0.579102f, 0.15332f, -0.490234f, 0.282715f, -0.471191f, 0.358398f, -0.394043f, 0.42334f,
+-0.327637f, 0.42334f, -0.237793f, 0.42334f, -0.185547f, 0.4021f, -0.141113f, 0.380859f,
+-0.0966797f, 0.348633f, -0.0654297f, 0.316406f, -0.0341797f, 0.276855f, -0.0151367f,
+0.220703f, 0.0117188f, 0.161621f, 0.0117188f, 0.102051f, 0.0117188f, 0.0749512f,
+-0.00854492f, 0.0478516f, -0.0288086f, 0.0478516f, -0.0532227f, 0.0478516f, -0.0668945f,
+0.059082f, -0.0773926f, 0.0703125f, -0.0878906f, 0.0874023f, -0.0878906f, 0.100098f,
+-0.0878906f, 0.109619f, -0.0839844f, 0.119141f, -0.0800781f, 0.14209f, -0.0639648f,
+0.178711f, -0.0385742f, 0.216309f, -0.0385742f, 0.273438f, -0.0385742f, 0.31665f,
+-0.0817871f, 0.359863f, -0.125f, 0.359863f, -0.187012f, 0.359863f, -0.24707f, 0.321289f,
+-0.299072f, 0.282715f, -0.351074f, 0.214844f, -0.379395f, 0.161621f, -0.401367f,
+0.0698242f, -0.404785f, 0.196777f, -0.662109f, 0.448242f, -0.675781f, 0.448242f,
+-0.657715f, 0.383789f, -0.651367f, 0.343018f, -0.63208f, 0.302246f, -0.612793f, 0.262451f,
+-0.573242f, 0.222656f, -0.533691f, 0.196533f, -0.485107f, 0.17041f, -0.436523f, 0.152832f,
+-0.369629f, 0.223145f, -0.417969f, 0.293945f, -0.417969f, 0.361816f, -0.417969f,
+0.411621f, -0.363281f, 0.461426f, -0.308594f, 0.461426f, -0.222656f, 0.461426f, -0.139648f,
+0.411133f, -0.0712891f, 0.350586f, 0.0117188f, 0.250977f, 0.0117188f, 0.183105f,
+0.0117188f, 0.135742f, -0.0332031f, 0.0429688f, -0.120605f, 0.0429688f, -0.259766f,
+0.0429688f, -0.348633f, 0.0786133f, -0.428711f, 0.114258f, -0.508789f, 0.18042f,
+-0.570801f, 0.246582f, -0.632812f, 0.307129f, -0.654297f, 0.367676f, -0.675781f,
+0.419922f, -0.675781f, 0.144531f, -0.333984f, 0.135742f, -0.268066f, 0.135742f, -0.227539f,
+0.135742f, -0.180664f, 0.153076f, -0.125732f, 0.17041f, -0.0708008f, 0.20459f, -0.0385742f,
+0.229492f, -0.015625f, 0.265137f, -0.015625f, 0.307617f, -0.015625f, 0.341064f, -0.0556641f,
+0.374512f, -0.0957031f, 0.374512f, -0.169922f, 0.374512f, -0.253418f, 0.341309f,
+-0.314453f, 0.308105f, -0.375488f, 0.24707f, -0.375488f, 0.228516f, -0.375488f, 0.207275f,
+-0.367676f, 0.186035f, -0.359863f, 0.144531f, -0.333984f, 0.100586f, -0.662109f,
+0.455566f, -0.662109f, 0.455566f, -0.643555f, 0.234863f, 0.0136719f, 0.180176f, 0.0136719f,
+0.37793f, -0.58252f, 0.195801f, -0.58252f, 0.140625f, -0.58252f, 0.117188f, -0.569336f,
+0.0761719f, -0.546875f, 0.0512695f, -0.5f, 0.0371094f, -0.505371f, 0.191895f, -0.333496f,
+0.113281f, -0.397949f, 0.0905762f, -0.437012f, 0.0678711f, -0.476074f, 0.0678711f,
+-0.518066f, 0.0678711f, -0.58252f, 0.117676f, -0.62915f, 0.16748f, -0.675781f, 0.25f,
+-0.675781f, 0.330078f, -0.675781f, 0.378906f, -0.632324f, 0.427734f, -0.588867f,
+0.427734f, -0.533203f, 0.427734f, -0.496094f, 0.401367f, -0.45752f, 0.375f, -0.418945f,
+0.291504f, -0.366699f, 0.377441f, -0.300293f, 0.405273f, -0.262207f, 0.442383f, -0.212402f,
+0.442383f, -0.157227f, 0.442383f, -0.0874023f, 0.38916f, -0.0378418f, 0.335938f,
+0.0117188f, 0.249512f, 0.0117188f, 0.155273f, 0.0117188f, 0.102539f, -0.0473633f,
+0.0605469f, -0.0947266f, 0.0605469f, -0.150879f, 0.0605469f, -0.194824f, 0.0900879f,
+-0.238037f, 0.119629f, -0.28125f, 0.191895f, -0.333496f, 0.268555f, -0.385742f, 0.327148f,
+-0.438477f, 0.342773f, -0.468994f, 0.358398f, -0.499512f, 0.358398f, -0.538086f,
+0.358398f, -0.589355f, 0.32959f, -0.618408f, 0.300781f, -0.647461f, 0.250977f, -0.647461f,
+0.201172f, -0.647461f, 0.169922f, -0.618652f, 0.138672f, -0.589844f, 0.138672f, -0.55127f,
+0.138672f, -0.525879f, 0.151611f, -0.500488f, 0.164551f, -0.475098f, 0.188477f, -0.452148f,
+0.214844f, -0.314941f, 0.174316f, -0.280762f, 0.154785f, -0.240479f, 0.135254f, -0.200195f,
+0.135254f, -0.15332f, 0.135254f, -0.090332f, 0.169678f, -0.0524902f, 0.204102f, -0.0146484f,
+0.257324f, -0.0146484f, 0.310059f, -0.0146484f, 0.341797f, -0.0444336f, 0.373535f,
+-0.0742188f, 0.373535f, -0.116699f, 0.373535f, -0.151855f, 0.35498f, -0.179688f,
+0.320312f, -0.231445f, 0.214844f, -0.314941f, 0.0527344f, 0.0136719f, 0.0527344f,
+-0.00439453f, 0.116211f, -0.00537109f, 0.170898f, -0.0339355f, 0.225586f, -0.0625f,
+0.276611f, -0.133789f, 0.327637f, -0.205078f, 0.347656f, -0.290527f, 0.270996f, -0.241211f,
+0.208984f, -0.241211f, 0.13916f, -0.241211f, 0.0893555f, -0.295166f, 0.0395508f,
+-0.349121f, 0.0395508f, -0.438477f, 0.0395508f, -0.525391f, 0.0893555f, -0.593262f,
+0.149414f, -0.675781f, 0.246094f, -0.675781f, 0.327637f, -0.675781f, 0.385742f, -0.608398f,
+0.457031f, -0.524902f, 0.457031f, -0.402344f, 0.457031f, -0.291992f, 0.402832f, -0.196533f,
+0.348633f, -0.101074f, 0.251953f, -0.0380859f, 0.17334f, 0.0136719f, 0.0805664f,
+0.0136719f, 0.355469f, -0.32666f, 0.364258f, -0.390137f, 0.364258f, -0.428223f, 0.364258f,
+-0.475586f, 0.348145f, -0.530518f, 0.332031f, -0.585449f, 0.30249f, -0.614746f, 0.272949f,
+-0.644043f, 0.235352f, -0.644043f, 0.191895f, -0.644043f, 0.15918f, -0.60498f, 0.126465f,
+-0.565918f, 0.126465f, -0.48877f, 0.126465f, -0.385742f, 0.169922f, -0.327637f, 0.20166f,
+-0.285645f, 0.248047f, -0.285645f, 0.270508f, -0.285645f, 0.30127f, -0.296387f, 0.332031f,
+-0.307129f, 0.355469f, -0.32666f, 0.137695f, -0.461426f, 0.160156f, -0.461426f, 0.176025f,
+-0.445801f, 0.191895f, -0.430176f, 0.191895f, -0.407715f, 0.191895f, -0.385254f,
+0.176025f, -0.369385f, 0.160156f, -0.353516f, 0.137695f, -0.353516f, 0.115234f, -0.353516f,
+0.0993652f, -0.369385f, 0.0834961f, -0.385254f, 0.0834961f, -0.407715f, 0.0834961f,
+-0.430176f, 0.0993652f, -0.445801f, 0.115234f, -0.461426f, 0.137695f, -0.461426f,
+0.0693359f, 0.166504f, 0.0693359f, 0.14502f, 0.119629f, 0.128418f, 0.147217f, 0.0935059f,
+0.174805f, 0.0585938f, 0.174805f, 0.0195312f, 0.174805f, 0.0102539f, 0.17041f, 0.00390625f,
+0.166992f, -0.000488281f, 0.163574f, -0.000488281f, 0.158203f, -0.000488281f, 0.140137f,
+0.00927734f, 0.131348f, 0.0136719f, 0.121582f, 0.0136719f, 0.0976562f, 0.0136719f,
+0.0834961f, -0.000488281f, 0.0693359f, -0.0146484f, 0.0693359f, -0.0395508f, 0.0693359f,
+-0.0634766f, 0.0876465f, -0.0805664f, 0.105957f, -0.0976562f, 0.132324f, -0.0976562f,
+0.164551f, -0.0976562f, 0.189697f, -0.0695801f, 0.214844f, -0.0415039f, 0.214844f,
+0.00488281f, 0.214844f, 0.0551758f, 0.179932f, 0.0983887f, 0.14502f, 0.141602f, 0.0693359f,
+0.166504f, 0.0180664f, -0.344727f, 0.543457f, -0.572266f, 0.543457f, -0.529785f,
+0.0913086f, -0.333496f, 0.543457f, -0.135254f, 0.543457f, -0.0913086f, 0.0180664f,
+-0.320801f, 0.0180664f, -0.431152f, 0.544922f, -0.431152f, 0.544922f, -0.391113f,
+0.0180664f, -0.391113f, 0.0180664f, -0.271973f, 0.544922f, -0.271973f, 0.544922f,
+-0.231934f, 0.0180664f, -0.231934f, 0.543457f, -0.318848f, 0.0180664f, -0.0913086f,
+0.0180664f, -0.133301f, 0.470703f, -0.32959f, 0.0180664f, -0.527832f, 0.0180664f,
+-0.572266f, 0.543457f, -0.342773f, 0.22168f, -0.15625f, 0.20166f, -0.15625f, 0.205078f,
+-0.217773f, 0.217041f, -0.258057f, 0.229004f, -0.29834f, 0.266602f, -0.370117f, 0.295898f,
+-0.425293f, 0.304688f, -0.454834f, 0.313477f, -0.484375f, 0.313477f, -0.514648f,
+0.313477f, -0.57666f, 0.280518f, -0.613281f, 0.247559f, -0.649902f, 0.199707f, -0.649902f,
+0.157227f, -0.649902f, 0.132812f, -0.629883f, 0.108398f, -0.609863f, 0.108398f, -0.586426f,
+0.108398f, -0.568359f, 0.123047f, -0.541992f, 0.137695f, -0.515625f, 0.137695f, -0.501953f,
+0.137695f, -0.484375f, 0.126465f, -0.472412f, 0.115234f, -0.460449f, 0.0991211f,
+-0.460449f, 0.0786133f, -0.460449f, 0.0617676f, -0.480713f, 0.0449219f, -0.500977f,
+0.0449219f, -0.537109f, 0.0449219f, -0.592285f, 0.0922852f, -0.634766f, 0.139648f,
+-0.677246f, 0.220703f, -0.677246f, 0.321289f, -0.677246f, 0.368652f, -0.618652f,
+0.403809f, -0.575684f, 0.403809f, -0.523438f, 0.403809f, -0.487793f, 0.387939f, -0.450195f,
+0.37207f, -0.412598f, 0.327637f, -0.361816f, 0.256836f, -0.281738f, 0.240967f, -0.248291f,
+0.225098f, -0.214844f, 0.22168f, -0.15625f, 0.214844f, -0.0957031f, 0.237793f, -0.0957031f,
+0.253662f, -0.079834f, 0.269531f, -0.0639648f, 0.269531f, -0.0410156f, 0.269531f,
+-0.0185547f, 0.253418f, -0.00268555f, 0.237305f, 0.0131836f, 0.214844f, 0.0131836f,
+0.192383f, 0.0131836f, 0.176514f, -0.00268555f, 0.160645f, -0.0185547f, 0.160645f,
+-0.0410156f, 0.160645f, -0.0639648f, 0.176514f, -0.079834f, 0.192383f, -0.0957031f,
+0.214844f, -0.0957031f, 0.6875f, -0.467773f, 0.630371f, -0.272949f, 0.598633f, -0.163574f,
+0.591797f, -0.134277f, 0.584961f, -0.10498f, 0.584961f, -0.0874023f, 0.584961f, -0.0717773f,
+0.595459f, -0.0610352f, 0.605957f, -0.050293f, 0.621582f, -0.050293f, 0.657227f,
+-0.050293f, 0.707275f, -0.0859375f, 0.757324f, -0.121582f, 0.792969f, -0.20166f,
+0.828613f, -0.281738f, 0.828613f, -0.368652f, 0.828613f, -0.452148f, 0.78833f, -0.522949f,
+0.748047f, -0.59375f, 0.674561f, -0.631592f, 0.601074f, -0.669434f, 0.512207f, -0.669434f,
+0.399414f, -0.669434f, 0.302734f, -0.609619f, 0.206055f, -0.549805f, 0.149658f, -0.4375f,
+0.0932617f, -0.325195f, 0.0932617f, -0.204102f, 0.0932617f, -0.0917969f, 0.142822f,
+0, 0.192383f, 0.0917969f, 0.282227f, 0.138916f, 0.37207f, 0.186035f, 0.475586f, 0.186035f,
+0.604004f, 0.186035f, 0.707764f, 0.117188f, 0.811523f, 0.0483398f, 0.868164f, -0.0839844f,
+0.896484f, -0.0839844f, 0.852539f, 0.0498047f, 0.736816f, 0.132812f, 0.621094f, 0.21582f,
+0.473145f, 0.21582f, 0.356934f, 0.21582f, 0.257324f, 0.160889f, 0.157715f, 0.105957f,
+0.102539f, 0.00512695f, 0.0473633f, -0.0957031f, 0.0473633f, -0.216797f, 0.0473633f,
+-0.345703f, 0.10791f, -0.457275f, 0.168457f, -0.568848f, 0.277588f, -0.631592f, 0.386719f,
+-0.694336f, 0.509277f, -0.694336f, 0.610352f, -0.694336f, 0.69165f, -0.652588f, 0.772949f,
+-0.61084f, 0.81543f, -0.530518f, 0.85791f, -0.450195f, 0.85791f, -0.359863f, 0.85791f,
+-0.270508f, 0.818115f, -0.182861f, 0.77832f, -0.0952148f, 0.716797f, -0.0551758f,
+0.655273f, -0.0151367f, 0.588379f, -0.0151367f, 0.55127f, -0.0151367f, 0.532471f,
+-0.0327148f, 0.513672f, -0.050293f, 0.513672f, -0.0820312f, 0.513672f, -0.109375f,
+0.522461f, -0.153809f, 0.450195f, -0.0664062f, 0.406738f, -0.0405273f, 0.363281f,
+-0.0146484f, 0.330078f, -0.0146484f, 0.29541f, -0.0146484f, 0.268555f, -0.0456543f,
+0.241699f, -0.0766602f, 0.241699f, -0.128418f, 0.241699f, -0.199219f, 0.287842f,
+-0.287109f, 0.333984f, -0.375f, 0.410156f, -0.430176f, 0.466309f, -0.470703f, 0.510742f,
+-0.470703f, 0.543457f, -0.470703f, 0.565186f, -0.453857f, 0.586914f, -0.437012f,
+0.594727f, -0.40332f, 0.61084f, -0.457031f, 0.516113f, -0.447754f, 0.479492f, -0.447754f,
+0.441895f, -0.40918f, 0.386719f, -0.352539f, 0.347656f, -0.256348f, 0.318848f, -0.186035f,
+0.318848f, -0.143066f, 0.318848f, -0.112305f, 0.336182f, -0.0930176f, 0.353516f,
+-0.0737305f, 0.375f, -0.0737305f, 0.40332f, -0.0737305f, 0.43457f, -0.0952148f, 0.46582f,
+-0.116699f, 0.5f, -0.161377f, 0.53418f, -0.206055f, 0.549805f, -0.250977f, 0.577148f,
+-0.328613f, 0.577148f, -0.377441f, 0.577148f, -0.409668f, 0.559326f, -0.428711f,
+0.541504f, -0.447754f, 0.516113f, -0.447754f, 0.45752f, -0.22168f, 0.201172f, -0.22168f,
+0.15625f, -0.117188f, 0.139648f, -0.0786133f, 0.139648f, -0.0595703f, 0.139648f,
+-0.0444336f, 0.154053f, -0.032959f, 0.168457f, -0.0214844f, 0.216309f, -0.0180664f,
+0.216309f, 0, 0.0078125f, 0, 0.0078125f, -0.0180664f, 0.0493164f, -0.0253906f, 0.0615234f,
+-0.0371094f, 0.0864258f, -0.0605469f, 0.116699f, -0.132324f, 0.349609f, -0.677246f,
+0.366699f, -0.677246f, 0.597168f, -0.126465f, 0.625f, -0.0600586f, 0.647705f, -0.0402832f,
+0.67041f, -0.0205078f, 0.710938f, -0.0180664f, 0.710938f, 0, 0.449707f, 0, 0.449707f,
+-0.0180664f, 0.489258f, -0.0200195f, 0.503174f, -0.03125f, 0.51709f, -0.0424805f,
+0.51709f, -0.0585938f, 0.51709f, -0.0800781f, 0.497559f, -0.126465f, 0.443848f, -0.257812f,
+0.331543f, -0.525391f, 0.216309f, -0.257812f, 0.461914f, -0.337891f, 0.530762f, -0.323242f,
+0.564941f, -0.291016f, 0.612305f, -0.246094f, 0.612305f, -0.181152f, 0.612305f, -0.131836f,
+0.581055f, -0.0866699f, 0.549805f, -0.0415039f, 0.495361f, -0.020752f, 0.440918f,
+0, 0.329102f, 0, 0.0166016f, 0, 0.0166016f, -0.0180664f, 0.0415039f, -0.0180664f,
+0.0830078f, -0.0180664f, 0.101074f, -0.0444336f, 0.112305f, -0.0615234f, 0.112305f,
+-0.117188f, 0.112305f, -0.544922f, 0.112305f, -0.606445f, 0.0981445f, -0.622559f,
+0.0791016f, -0.644043f, 0.0415039f, -0.644043f, 0.0166016f, -0.644043f, 0.0166016f,
+-0.662109f, 0.302734f, -0.662109f, 0.382812f, -0.662109f, 0.431152f, -0.650391f,
+0.504395f, -0.632812f, 0.542969f, -0.588135f, 0.581543f, -0.543457f, 0.581543f, -0.485352f,
+0.581543f, -0.435547f, 0.55127f, -0.39624f, 0.520996f, -0.356934f, 0.461914f, -0.337891f,
+0.206055f, -0.364258f, 0.224121f, -0.36084f, 0.247314f, -0.359131f, 0.270508f, -0.357422f,
+0.29834f, -0.357422f, 0.369629f, -0.357422f, 0.405518f, -0.372803f, 0.441406f, -0.388184f,
+0.460449f, -0.419922f, 0.479492f, -0.45166f, 0.479492f, -0.489258f, 0.479492f, -0.547363f,
+0.432129f, -0.588379f, 0.384766f, -0.629395f, 0.293945f, -0.629395f, 0.245117f, -0.629395f,
+0.206055f, -0.618652f, 0.206055f, -0.0478516f, 0.262695f, -0.034668f, 0.317871f,
+-0.034668f, 0.40625f, -0.034668f, 0.452637f, -0.0744629f, 0.499023f, -0.114258f,
+0.499023f, -0.172852f, 0.499023f, -0.211426f, 0.478027f, -0.24707f, 0.457031f, -0.282715f,
+0.409668f, -0.303223f, 0.362305f, -0.32373f, 0.29248f, -0.32373f, 0.262207f, -0.32373f,
+0.240723f, -0.322754f, 0.219238f, -0.321777f, 0.206055f, -0.319336f, 0.602051f, -0.677246f,
+0.617188f, -0.452148f, 0.602051f, -0.452148f, 0.571777f, -0.553223f, 0.515625f, -0.597656f,
+0.459473f, -0.64209f, 0.380859f, -0.64209f, 0.314941f, -0.64209f, 0.261719f, -0.608643f,
+0.208496f, -0.575195f, 0.177979f, -0.501953f, 0.147461f, -0.428711f, 0.147461f, -0.319824f,
+0.147461f, -0.22998f, 0.17627f, -0.164062f, 0.205078f, -0.0981445f, 0.262939f, -0.0629883f,
+0.320801f, -0.027832f, 0.39502f, -0.027832f, 0.459473f, -0.027832f, 0.508789f, -0.0554199f,
+0.558105f, -0.0830078f, 0.617188f, -0.165039f, 0.632324f, -0.155273f, 0.58252f, -0.0668945f,
+0.516113f, -0.0258789f, 0.449707f, 0.0151367f, 0.358398f, 0.0151367f, 0.193848f,
+0.0151367f, 0.103516f, -0.106934f, 0.0361328f, -0.197754f, 0.0361328f, -0.320801f,
+0.0361328f, -0.419922f, 0.0805664f, -0.50293f, 0.125f, -0.585938f, 0.202881f, -0.631592f,
+0.280762f, -0.677246f, 0.373047f, -0.677246f, 0.444824f, -0.677246f, 0.514648f, -0.64209f,
+0.535156f, -0.631348f, 0.543945f, -0.631348f, 0.557129f, -0.631348f, 0.566895f, -0.640625f,
+0.57959f, -0.653809f, 0.584961f, -0.677246f, 0.0170898f, 0, 0.0170898f, -0.0180664f,
+0.0419922f, -0.0180664f, 0.0839844f, -0.0180664f, 0.101562f, -0.0449219f, 0.112305f,
+-0.0610352f, 0.112305f, -0.117188f, 0.112305f, -0.544922f, 0.112305f, -0.606934f,
+0.0986328f, -0.622559f, 0.0795898f, -0.644043f, 0.0419922f, -0.644043f, 0.0170898f,
+-0.644043f, 0.0170898f, -0.662109f, 0.286621f, -0.662109f, 0.435059f, -0.662109f,
+0.512451f, -0.628418f, 0.589844f, -0.594727f, 0.636963f, -0.516113f, 0.684082f, -0.4375f,
+0.684082f, -0.334473f, 0.684082f, -0.196289f, 0.600098f, -0.103516f, 0.505859f, 0,
+0.312988f, 0, 0.206055f, -0.0478516f, 0.268066f, -0.0341797f, 0.310059f, -0.0341797f,
+0.42334f, -0.0341797f, 0.498047f, -0.11377f, 0.572754f, -0.193359f, 0.572754f, -0.32959f,
+0.572754f, -0.466797f, 0.498047f, -0.545898f, 0.42334f, -0.625f, 0.306152f, -0.625f,
+0.262207f, -0.625f, 0.206055f, -0.61084f, 0.208984f, -0.625977f, 0.208984f, -0.364258f,
+0.354492f, -0.364258f, 0.411133f, -0.364258f, 0.430176f, -0.381348f, 0.455566f, -0.403809f,
+0.458496f, -0.460449f, 0.476562f, -0.460449f, 0.476562f, -0.22998f, 0.458496f, -0.22998f,
+0.45166f, -0.27832f, 0.444824f, -0.291992f, 0.436035f, -0.309082f, 0.416016f, -0.318848f,
+0.395996f, -0.328613f, 0.354492f, -0.328613f, 0.208984f, -0.328613f, 0.208984f, -0.110352f,
+0.208984f, -0.0664062f, 0.212891f, -0.0568848f, 0.216797f, -0.0473633f, 0.226562f,
+-0.041748f, 0.236328f, -0.0361328f, 0.263672f, -0.0361328f, 0.375977f, -0.0361328f,
+0.432129f, -0.0361328f, 0.45752f, -0.0439453f, 0.48291f, -0.0517578f, 0.506348f,
+-0.074707f, 0.536621f, -0.10498f, 0.568359f, -0.166016f, 0.587891f, -0.166016f, 0.530762f,
+0, 0.0205078f, 0, 0.0205078f, -0.0180664f, 0.0439453f, -0.0180664f, 0.0673828f, -0.0180664f,
+0.0883789f, -0.0292969f, 0.104004f, -0.0371094f, 0.109619f, -0.0527344f, 0.115234f,
+-0.0683594f, 0.115234f, -0.116699f, 0.115234f, -0.546875f, 0.115234f, -0.609863f,
+0.102539f, -0.624512f, 0.0849609f, -0.644043f, 0.0439453f, -0.644043f, 0.0205078f,
+-0.644043f, 0.0205078f, -0.662109f, 0.530762f, -0.662109f, 0.538086f, -0.51709f,
+0.519043f, -0.51709f, 0.508789f, -0.569336f, 0.496338f, -0.588867f, 0.483887f, -0.608398f,
+0.459473f, -0.618652f, 0.439941f, -0.625977f, 0.390625f, -0.625977f, 0.20459f, -0.625977f,
+0.20459f, -0.365723f, 0.325195f, -0.365723f, 0.366699f, -0.365723f, 0.385986f, -0.384033f,
+0.405273f, -0.402344f, 0.411621f, -0.456543f, 0.429688f, -0.456543f, 0.429688f, -0.232422f,
+0.411621f, -0.232422f, 0.411133f, -0.270996f, 0.401611f, -0.289062f, 0.39209f, -0.307129f,
+0.375244f, -0.316162f, 0.358398f, -0.325195f, 0.325195f, -0.325195f, 0.20459f, -0.325195f,
+0.20459f, -0.117188f, 0.20459f, -0.0668945f, 0.210938f, -0.0507812f, 0.21582f, -0.0385742f,
+0.231445f, -0.0297852f, 0.25293f, -0.0180664f, 0.276367f, -0.0180664f, 0.300293f,
+-0.0180664f, 0.300293f, 0, 0.0161133f, 0, 0.0161133f, -0.0180664f, 0.0395508f, -0.0180664f,
+0.0805664f, -0.0180664f, 0.0991211f, -0.0419922f, 0.11084f, -0.0576172f, 0.11084f,
+-0.117188f, 0.11084f, -0.544922f, 0.11084f, -0.595215f, 0.104492f, -0.611328f, 0.0996094f,
+-0.623535f, 0.0844727f, -0.632324f, 0.0634766f, -0.644043f, 0.0395508f, -0.644043f,
+0.0161133f, -0.644043f, 0.0161133f, -0.662109f, 0.508789f, -0.662109f, 0.515137f,
+-0.516602f, 0.498047f, -0.516602f, 0.485352f, -0.562988f, 0.468506f, -0.584717f,
+0.45166f, -0.606445f, 0.427002f, -0.616211f, 0.402344f, -0.625977f, 0.350586f, -0.625977f,
+0.61377f, -0.677246f, 0.630859f, -0.468262f, 0.61377f, -0.468262f, 0.587891f, -0.546387f,
+0.546875f, -0.585938f, 0.487793f, -0.643066f, 0.39502f, -0.643066f, 0.268555f, -0.643066f,
+0.202637f, -0.542969f, 0.147461f, -0.458496f, 0.147461f, -0.341797f, 0.147461f, -0.24707f,
+0.184082f, -0.168945f, 0.220703f, -0.0908203f, 0.280029f, -0.0544434f, 0.339355f,
+-0.0180664f, 0.401855f, -0.0180664f, 0.438477f, -0.0180664f, 0.472656f, -0.0273438f,
+0.506836f, -0.0366211f, 0.538574f, -0.0546875f, 0.538574f, -0.246094f, 0.538574f,
+-0.295898f, 0.531006f, -0.311279f, 0.523438f, -0.32666f, 0.507568f, -0.334717f, 0.491699f,
+-0.342773f, 0.45166f, -0.342773f, 0.45166f, -0.361328f, 0.708008f, -0.361328f, 0.708008f,
+-0.342773f, 0.695801f, -0.342773f, 0.657715f, -0.342773f, 0.643555f, -0.317383f,
+0.633789f, -0.299316f, 0.633789f, -0.246094f, 0.633789f, -0.043457f, 0.577637f, -0.0131836f,
+0.522949f, 0.000976562f, 0.468262f, 0.0151367f, 0.401367f, 0.0151367f, 0.209473f,
+0.0151367f, 0.109863f, -0.10791f, 0.0351562f, -0.200195f, 0.0351562f, -0.320801f,
+0.0351562f, -0.408203f, 0.0771484f, -0.488281f, 0.126953f, -0.583496f, 0.213867f,
+-0.634766f, 0.286621f, -0.677246f, 0.385742f, -0.677246f, 0.421875f, -0.677246f,
+0.451416f, -0.671387f, 0.480957f, -0.665527f, 0.535156f, -0.645508f, 0.5625f, -0.635254f,
+0.571777f, -0.635254f, 0.581055f, -0.635254f, 0.587646f, -0.643799f, 0.594238f, -0.652344f,
+0.595703f, -0.677246f, 0.205566f, -0.35498f, 0.513184f, -0.35498f, 0.513184f, -0.544434f,
+0.513184f, -0.595215f, 0.506836f, -0.611328f, 0.501953f, -0.623535f, 0.486328f, -0.632324f,
+0.465332f, -0.644043f, 0.441895f, -0.644043f, 0.418457f, -0.644043f, 0.418457f, -0.662109f,
+0.70166f, -0.662109f, 0.70166f, -0.644043f, 0.678223f, -0.644043f, 0.654785f, -0.644043f,
+0.633789f, -0.632812f, 0.618164f, -0.625f, 0.612549f, -0.609131f, 0.606934f, -0.593262f,
+0.606934f, -0.544434f, 0.606934f, -0.117188f, 0.606934f, -0.0668945f, 0.613281f,
+-0.0507812f, 0.618164f, -0.0385742f, 0.633301f, -0.0297852f, 0.654785f, -0.0180664f,
+0.678223f, -0.0180664f, 0.70166f, -0.0180664f, 0.70166f, 0, 0.418457f, 0, 0.418457f,
+-0.0180664f, 0.441895f, -0.0180664f, 0.482422f, -0.0180664f, 0.500977f, -0.0419922f,
+0.513184f, -0.0576172f, 0.513184f, -0.117188f, 0.513184f, -0.318848f, 0.205566f,
+-0.318848f, 0.205566f, -0.117188f, 0.205566f, -0.0668945f, 0.211914f, -0.0507812f,
+0.216797f, -0.0385742f, 0.232422f, -0.0297852f, 0.253418f, -0.0180664f, 0.276855f,
+-0.0180664f, 0.300781f, -0.0180664f, 0.300781f, 0, 0.0170898f, 0, 0.0170898f, -0.0180664f,
+0.0405273f, -0.0180664f, 0.081543f, -0.0180664f, 0.100098f, -0.0419922f, 0.111816f,
+-0.0576172f, 0.111816f, -0.117188f, 0.111816f, -0.544434f, 0.111816f, -0.595215f,
+0.105469f, -0.611328f, 0.100586f, -0.623535f, 0.0854492f, -0.632324f, 0.0639648f,
+-0.644043f, 0.0405273f, -0.644043f, 0.0170898f, -0.644043f, 0.0170898f, -0.662109f,
+0.300781f, -0.662109f, 0.300781f, -0.644043f, 0.276855f, -0.644043f, 0.253418f, -0.644043f,
+0.232422f, -0.632812f, 0.217285f, -0.625f, 0.211426f, -0.609131f, 0.205566f, -0.593262f,
+0.205566f, -0.544434f, 0.308594f, -0.0180664f, 0.308594f, 0, 0.0249023f, 0, 0.0249023f,
+-0.0180664f, 0.0483398f, -0.0180664f, 0.0893555f, -0.0180664f, 0.10791f, -0.0419922f,
+0.119629f, -0.0576172f, 0.119629f, -0.117188f, 0.119629f, -0.544922f, 0.119629f,
+-0.595215f, 0.113281f, -0.611328f, 0.108398f, -0.623535f, 0.0932617f, -0.632324f,
+0.0717773f, -0.644043f, 0.0483398f, -0.644043f, 0.0249023f, -0.644043f, 0.0249023f,
+-0.662109f, 0.308594f, -0.662109f, 0.308594f, -0.644043f, 0.284668f, -0.644043f,
+0.244141f, -0.644043f, 0.225586f, -0.620117f, 0.213379f, -0.604492f, 0.213379f, -0.544922f,
+0.213379f, -0.117188f, 0.213379f, -0.0668945f, 0.219727f, -0.0507812f, 0.224609f,
+-0.0385742f, 0.240234f, -0.0297852f, 0.26123f, -0.0180664f, 0.284668f, -0.0180664f,
+0.0996094f, -0.644043f, 0.0996094f, -0.662109f, 0.383301f, -0.662109f, 0.383301f,
+-0.644043f, 0.359375f, -0.644043f, 0.318848f, -0.644043f, 0.300293f, -0.620117f,
+0.288574f, -0.604492f, 0.288574f, -0.544922f, 0.288574f, -0.221191f, 0.288574f, -0.146484f,
+0.272217f, -0.100098f, 0.255859f, -0.0537109f, 0.21582f, -0.0192871f, 0.175781f,
+0.0151367f, 0.119141f, 0.0151367f, 0.0732422f, 0.0151367f, 0.046875f, -0.00756836f,
+0.0205078f, -0.0302734f, 0.0205078f, -0.0595703f, 0.0205078f, -0.0834961f, 0.0327148f,
+-0.0957031f, 0.0488281f, -0.11084f, 0.0703125f, -0.11084f, 0.0859375f, -0.11084f,
+0.0983887f, -0.100586f, 0.11084f, -0.090332f, 0.129883f, -0.0458984f, 0.141113f,
+-0.0195312f, 0.158691f, -0.0195312f, 0.171875f, -0.0195312f, 0.18335f, -0.0356445f,
+0.194824f, -0.0517578f, 0.194824f, -0.0927734f, 0.194824f, -0.544922f, 0.194824f,
+-0.595215f, 0.188477f, -0.611328f, 0.183594f, -0.623535f, 0.167969f, -0.632324f,
+0.146973f, -0.644043f, 0.123535f, -0.644043f, 0.298828f, -0.367188f, 0.542969f, -0.124512f,
+0.603027f, -0.0644531f, 0.645508f, -0.0427246f, 0.687988f, -0.0209961f, 0.730469f,
+-0.0180664f, 0.730469f, 0, 0.415527f, 0, 0.415527f, -0.0180664f, 0.443848f, -0.0180664f,
+0.456299f, -0.0275879f, 0.46875f, -0.0371094f, 0.46875f, -0.0488281f, 0.46875f, -0.0605469f,
+0.464111f, -0.0698242f, 0.459473f, -0.0791016f, 0.433594f, -0.104492f, 0.205078f,
+-0.330566f, 0.205078f, -0.117188f, 0.205078f, -0.0668945f, 0.211426f, -0.0507812f,
+0.216309f, -0.0385742f, 0.231934f, -0.0297852f, 0.25293f, -0.0180664f, 0.276367f,
+-0.0180664f, 0.298828f, -0.0180664f, 0.298828f, 0, 0.0166016f, 0, 0.0166016f, -0.0180664f,
+0.0400391f, -0.0180664f, 0.0810547f, -0.0180664f, 0.0996094f, -0.0419922f, 0.111328f,
+-0.0576172f, 0.111328f, -0.117188f, 0.111328f, -0.544922f, 0.111328f, -0.595215f,
+0.10498f, -0.611816f, 0.100098f, -0.623535f, 0.0849609f, -0.632324f, 0.0634766f,
+-0.644043f, 0.0400391f, -0.644043f, 0.0166016f, -0.644043f, 0.0166016f, -0.662109f,
+0.298828f, -0.662109f, 0.298828f, -0.644043f, 0.276367f, -0.644043f, 0.253418f, -0.644043f,
+0.231934f, -0.632812f, 0.216797f, -0.625f, 0.210938f, -0.609375f, 0.205078f, -0.59375f,
+0.205078f, -0.544922f, 0.205078f, -0.342285f, 0.214844f, -0.351562f, 0.271973f, -0.404297f,
+0.416992f, -0.537109f, 0.447266f, -0.581543f, 0.460449f, -0.601074f, 0.460449f, -0.615723f,
+0.460449f, -0.626953f, 0.450195f, -0.635498f, 0.439941f, -0.644043f, 0.415527f, -0.644043f,
+0.400391f, -0.644043f, 0.400391f, -0.662109f, 0.643555f, -0.662109f, 0.643555f, -0.644043f,
+0.62207f, -0.643555f, 0.604492f, -0.638184f, 0.586914f, -0.632812f, 0.561523f, -0.617432f,
+0.536133f, -0.602051f, 0.499023f, -0.567871f, 0.488281f, -0.558105f, 0.399902f, -0.467773f,
+0.573242f, -0.183105f, 0.589355f, -0.179688f, 0.532715f, 0, 0.0200195f, 0, 0.0200195f,
+-0.0180664f, 0.0449219f, -0.0180664f, 0.0869141f, -0.0180664f, 0.10498f, -0.0454102f,
+0.115234f, -0.0610352f, 0.115234f, -0.117676f, 0.115234f, -0.544922f, 0.115234f,
+-0.606934f, 0.101562f, -0.622559f, 0.0825195f, -0.644043f, 0.0449219f, -0.644043f,
+0.0200195f, -0.644043f, 0.0200195f, -0.662109f, 0.319824f, -0.662109f, 0.319824f,
+-0.644043f, 0.26709f, -0.644531f, 0.24585f, -0.634277f, 0.224609f, -0.624023f, 0.216797f,
+-0.608398f, 0.208984f, -0.592773f, 0.208984f, -0.533691f, 0.208984f, -0.117676f,
+0.208984f, -0.0771484f, 0.216797f, -0.0620117f, 0.222656f, -0.0517578f, 0.234863f,
+-0.046875f, 0.24707f, -0.0419922f, 0.311035f, -0.0419922f, 0.359375f, -0.0419922f,
+0.435547f, -0.0419922f, 0.466309f, -0.0532227f, 0.49707f, -0.0644531f, 0.522461f,
+-0.0930176f, 0.547852f, -0.121582f, 0.573242f, -0.183105f, 0.40918f, 0, 0.15332f,
+-0.557129f, 0.15332f, -0.114746f, 0.15332f, -0.0537109f, 0.166504f, -0.0385742f,
+0.18457f, -0.0180664f, 0.223633f, -0.0180664f, 0.24707f, -0.0180664f, 0.24707f, 0,
+0.0166016f, 0, 0.0166016f, -0.0180664f, 0.0400391f, -0.0180664f, 0.0820312f, -0.0180664f,
+0.0996094f, -0.043457f, 0.110352f, -0.059082f, 0.110352f, -0.114746f, 0.110352f,
+-0.547363f, 0.110352f, -0.591309f, 0.100586f, -0.61084f, 0.09375f, -0.625f, 0.0754395f,
+-0.634521f, 0.0571289f, -0.644043f, 0.0166016f, -0.644043f, 0.0166016f, -0.662109f,
+0.204102f, -0.662109f, 0.444336f, -0.144043f, 0.680664f, -0.662109f, 0.868164f, -0.662109f,
+0.868164f, -0.644043f, 0.845215f, -0.644043f, 0.802734f, -0.644043f, 0.785156f, -0.618652f,
+0.774414f, -0.603027f, 0.774414f, -0.547363f, 0.774414f, -0.114746f, 0.774414f, -0.0537109f,
+0.788086f, -0.0385742f, 0.806152f, -0.0180664f, 0.845215f, -0.0180664f, 0.868164f,
+-0.0180664f, 0.868164f, 0, 0.586914f, 0, 0.586914f, -0.0180664f, 0.610352f, -0.0180664f,
+0.652832f, -0.0180664f, 0.669922f, -0.043457f, 0.680664f, -0.059082f, 0.680664f,
+-0.114746f, 0.680664f, -0.557129f, 0.425293f, 0, -0.0131836f, -0.662109f, 0.166504f,
+-0.662109f, 0.571289f, -0.165527f, 0.571289f, -0.547363f, 0.571289f, -0.608398f,
+0.557617f, -0.623535f, 0.539551f, -0.644043f, 0.500488f, -0.644043f, 0.477539f, -0.644043f,
+0.477539f, -0.662109f, 0.708008f, -0.662109f, 0.708008f, -0.644043f, 0.68457f, -0.644043f,
+0.642578f, -0.644043f, 0.625f, -0.618652f, 0.614258f, -0.603027f, 0.614258f, -0.547363f,
+0.614258f, 0.0107422f, 0.59668f, 0.0107422f, 0.160156f, -0.522461f, 0.160156f, -0.114746f,
+0.160156f, -0.0537109f, 0.17334f, -0.0385742f, 0.191895f, -0.0180664f, 0.230469f,
+-0.0180664f, 0.253906f, -0.0180664f, 0.253906f, 0, 0.0234375f, 0, 0.0234375f, -0.0180664f,
+0.0463867f, -0.0180664f, 0.0888672f, -0.0180664f, 0.106445f, -0.043457f, 0.117188f,
+-0.059082f, 0.117188f, -0.114746f, 0.117188f, -0.575195f, 0.0883789f, -0.608887f,
+0.0734863f, -0.619629f, 0.0585938f, -0.630371f, 0.0297852f, -0.639648f, 0.015625f,
+-0.644043f, -0.0131836f, -0.644043f, 0.205078f, -0.310059f, 0.205078f, -0.117188f,
+0.205078f, -0.0546875f, 0.21875f, -0.0395508f, 0.237305f, -0.0180664f, 0.274902f,
+-0.0180664f, 0.300293f, -0.0180664f, 0.300293f, 0, 0.0166016f, 0, 0.0166016f, -0.0180664f,
+0.0415039f, -0.0180664f, 0.0834961f, -0.0180664f, 0.101562f, -0.0454102f, 0.111328f,
+-0.0605469f, 0.111328f, -0.117188f, 0.111328f, -0.544922f, 0.111328f, -0.607422f,
+0.0981445f, -0.622559f, 0.0791016f, -0.644043f, 0.0415039f, -0.644043f, 0.0166016f,
+-0.644043f, 0.0166016f, -0.662109f, 0.259277f, -0.662109f, 0.348145f, -0.662109f,
+0.399414f, -0.643799f, 0.450684f, -0.625488f, 0.48584f, -0.582031f, 0.520996f, -0.538574f,
+0.520996f, -0.479004f, 0.520996f, -0.397949f, 0.467529f, -0.347168f, 0.414062f, -0.296387f,
+0.316406f, -0.296387f, 0.29248f, -0.296387f, 0.264648f, -0.299805f, 0.236816f, -0.303223f,
+0.205078f, -0.310059f, 0.205078f, -0.337891f, 0.230957f, -0.333008f, 0.250977f, -0.330566f,
+0.270996f, -0.328125f, 0.285156f, -0.328125f, 0.335938f, -0.328125f, 0.372803f, -0.367432f,
+0.409668f, -0.406738f, 0.409668f, -0.469238f, 0.409668f, -0.512207f, 0.39209f, -0.549072f,
+0.374512f, -0.585938f, 0.342285f, -0.604248f, 0.310059f, -0.622559f, 0.269043f, -0.622559f,
+0.244141f, -0.622559f, 0.205078f, -0.613281f, 0.44043f, 0.00732422f, 0.490234f, 0.0932617f,
+0.548096f, 0.133789f, 0.605957f, 0.174316f, 0.679688f, 0.180176f, 0.679688f, 0.195801f,
+0.612305f, 0.193359f, 0.535645f, 0.168701f, 0.458984f, 0.144043f, 0.390381f, 0.100342f,
+0.321777f, 0.0566406f, 0.271973f, 0.00732422f, 0.20166f, -0.0209961f, 0.160645f,
+-0.0527344f, 0.101074f, -0.100098f, 0.0681152f, -0.169189f, 0.0351562f, -0.238281f,
+0.0351562f, -0.33252f, 0.0351562f, -0.480957f, 0.131348f, -0.579102f, 0.227539f,
+-0.677246f, 0.364258f, -0.677246f, 0.494141f, -0.677246f, 0.589111f, -0.578857f,
+0.684082f, -0.480469f, 0.684082f, -0.330566f, 0.684082f, -0.208984f, 0.616455f, -0.117188f,
+0.548828f, -0.0253906f, 0.44043f, 0.00732422f, 0.358398f, -0.639648f, 0.269531f,
+-0.639648f, 0.215332f, -0.576172f, 0.146973f, -0.496582f, 0.146973f, -0.33252f, 0.146973f,
+-0.171875f, 0.216309f, -0.0849609f, 0.27002f, -0.0180664f, 0.358398f, -0.0180664f,
+0.450195f, -0.0180664f, 0.506348f, -0.0849609f, 0.572266f, -0.164062f, 0.572266f,
+-0.318359f, 0.572266f, -0.437012f, 0.536133f, -0.518066f, 0.508301f, -0.580566f,
+0.462158f, -0.610107f, 0.416016f, -0.639648f, 0.358398f, -0.639648f, 0.675781f, 0,
+0.499023f, 0, 0.274902f, -0.30957f, 0.25f, -0.308594f, 0.234375f, -0.308594f, 0.228027f,
+-0.308594f, 0.220703f, -0.308838f, 0.213379f, -0.309082f, 0.205566f, -0.30957f, 0.205566f,
+-0.117188f, 0.205566f, -0.0546875f, 0.219238f, -0.0395508f, 0.237793f, -0.0180664f,
+0.274902f, -0.0180664f, 0.300781f, -0.0180664f, 0.300781f, 0, 0.0170898f, 0, 0.0170898f,
+-0.0180664f, 0.0419922f, -0.0180664f, 0.0839844f, -0.0180664f, 0.102051f, -0.0454102f,
+0.112305f, -0.0605469f, 0.112305f, -0.117188f, 0.112305f, -0.544922f, 0.112305f,
+-0.607422f, 0.0986328f, -0.622559f, 0.0795898f, -0.644043f, 0.0419922f, -0.644043f,
+0.0170898f, -0.644043f, 0.0170898f, -0.662109f, 0.258301f, -0.662109f, 0.36377f,
+-0.662109f, 0.413818f, -0.646729f, 0.463867f, -0.631348f, 0.498779f, -0.590088f,
+0.533691f, -0.548828f, 0.533691f, -0.491699f, 0.533691f, -0.430664f, 0.493896f, -0.385742f,
+0.454102f, -0.34082f, 0.370605f, -0.322266f, 0.507324f, -0.132324f, 0.554199f, -0.0668945f,
+0.587891f, -0.0454102f, 0.621582f, -0.0239258f, 0.675781f, -0.0180664f, 0.205566f,
+-0.340332f, 0.214844f, -0.340332f, 0.22168f, -0.340088f, 0.228516f, -0.339844f, 0.23291f,
+-0.339844f, 0.327637f, -0.339844f, 0.375732f, -0.380859f, 0.423828f, -0.421875f,
+0.423828f, -0.485352f, 0.423828f, -0.547363f, 0.38501f, -0.586182f, 0.346191f, -0.625f,
+0.282227f, -0.625f, 0.253906f, -0.625f, 0.205566f, -0.615723f, 0.458496f, -0.677246f,
+0.458496f, -0.448242f, 0.44043f, -0.448242f, 0.431641f, -0.51416f, 0.408936f, -0.553223f,
+0.38623f, -0.592285f, 0.344238f, -0.615234f, 0.302246f, -0.638184f, 0.257324f, -0.638184f,
+0.206543f, -0.638184f, 0.17334f, -0.607178f, 0.140137f, -0.576172f, 0.140137f, -0.536621f,
+0.140137f, -0.506348f, 0.161133f, -0.481445f, 0.191406f, -0.444824f, 0.305176f, -0.383789f,
+0.397949f, -0.333984f, 0.431885f, -0.307373f, 0.46582f, -0.280762f, 0.484131f, -0.244629f,
+0.502441f, -0.208496f, 0.502441f, -0.168945f, 0.502441f, -0.09375f, 0.444092f, -0.0393066f,
+0.385742f, 0.0151367f, 0.293945f, 0.0151367f, 0.265137f, 0.0151367f, 0.239746f, 0.0107422f,
+0.224609f, 0.00830078f, 0.177002f, -0.00708008f, 0.129395f, -0.0224609f, 0.116699f,
+-0.0224609f, 0.104492f, -0.0224609f, 0.0974121f, -0.0151367f, 0.090332f, -0.0078125f,
+0.0869141f, 0.0151367f, 0.0688477f, 0.0151367f, 0.0688477f, -0.211914f, 0.0869141f,
+-0.211914f, 0.0996094f, -0.140625f, 0.121094f, -0.105225f, 0.142578f, -0.0698242f,
+0.186768f, -0.0463867f, 0.230957f, -0.0229492f, 0.283691f, -0.0229492f, 0.344727f,
+-0.0229492f, 0.380127f, -0.0551758f, 0.415527f, -0.0874023f, 0.415527f, -0.131348f,
+0.415527f, -0.155762f, 0.4021f, -0.180664f, 0.388672f, -0.205566f, 0.360352f, -0.227051f,
+0.341309f, -0.241699f, 0.256348f, -0.289307f, 0.171387f, -0.336914f, 0.135498f, -0.365234f,
+0.0996094f, -0.393555f, 0.0810547f, -0.427734f, 0.0625f, -0.461914f, 0.0625f, -0.50293f,
+0.0625f, -0.574219f, 0.117188f, -0.625732f, 0.171875f, -0.677246f, 0.256348f, -0.677246f,
+0.309082f, -0.677246f, 0.368164f, -0.651367f, 0.395508f, -0.63916f, 0.406738f, -0.63916f,
+0.419434f, -0.63916f, 0.42749f, -0.646729f, 0.435547f, -0.654297f, 0.44043f, -0.677246f,
+0.578613f, -0.662109f, 0.585938f, -0.506836f, 0.567383f, -0.506836f, 0.562012f, -0.547852f,
+0.552734f, -0.56543f, 0.537598f, -0.59375f, 0.512451f, -0.607178f, 0.487305f, -0.620605f,
+0.446289f, -0.620605f, 0.353027f, -0.620605f, 0.353027f, -0.114746f, 0.353027f, -0.0537109f,
+0.366211f, -0.0385742f, 0.384766f, -0.0180664f, 0.42334f, -0.0180664f, 0.446289f,
+-0.0180664f, 0.446289f, 0, 0.165527f, 0, 0.165527f, -0.0180664f, 0.188965f, -0.0180664f,
+0.230957f, -0.0180664f, 0.248535f, -0.043457f, 0.259277f, -0.059082f, 0.259277f,
+-0.114746f, 0.259277f, -0.620605f, 0.179688f, -0.620605f, 0.133301f, -0.620605f,
+0.11377f, -0.61377f, 0.0883789f, -0.604492f, 0.0703125f, -0.578125f, 0.0522461f,
+-0.551758f, 0.0488281f, -0.506836f, 0.0302734f, -0.506836f, 0.0380859f, -0.662109f,
+0.709961f, -0.662109f, 0.709961f, -0.644043f, 0.674805f, -0.637695f, 0.656738f, -0.621582f,
+0.630859f, -0.597656f, 0.61084f, -0.54834f, 0.379883f, 0.0151367f, 0.361816f, 0.0151367f,
+0.11377f, -0.555664f, 0.0947266f, -0.599609f, 0.0869141f, -0.609375f, 0.074707f,
+-0.624512f, 0.0568848f, -0.633057f, 0.0390625f, -0.641602f, 0.00878906f, -0.644043f,
+0.00878906f, -0.662109f, 0.279297f, -0.662109f, 0.279297f, -0.644043f, 0.233398f,
+-0.639648f, 0.219727f, -0.628418f, 0.206055f, -0.617188f, 0.206055f, -0.599609f,
+0.206055f, -0.575195f, 0.228516f, -0.523438f, 0.396973f, -0.135254f, 0.553223f, -0.518555f,
+0.576172f, -0.575195f, 0.576172f, -0.597168f, 0.576172f, -0.611328f, 0.562012f, -0.624268f,
+0.547852f, -0.637207f, 0.51416f, -0.642578f, 0.511719f, -0.643066f, 0.505859f, -0.644043f,
+0.505859f, -0.662109f, 0.936035f, -0.662109f, 0.936035f, -0.644043f, 0.910156f, -0.644043f,
+0.894043f, -0.634766f, 0.87793f, -0.625488f, 0.863281f, -0.600098f, 0.853516f, -0.583008f,
+0.83252f, -0.518555f, 0.647949f, 0.0151367f, 0.628418f, 0.0151367f, 0.477539f, -0.408203f,
+0.327637f, 0.0151367f, 0.310059f, 0.0151367f, 0.113281f, -0.534668f, 0.0913086f,
+-0.596191f, 0.0854492f, -0.607422f, 0.0756836f, -0.625977f, 0.0588379f, -0.63501f,
+0.0419922f, -0.644043f, 0.0131836f, -0.644043f, 0.0131836f, -0.662109f, 0.258301f,
+-0.662109f, 0.258301f, -0.644043f, 0.246582f, -0.644043f, 0.220703f, -0.644043f,
+0.207031f, -0.632324f, 0.193359f, -0.620605f, 0.193359f, -0.604004f, 0.193359f, -0.586914f,
+0.214844f, -0.525391f, 0.345215f, -0.153809f, 0.455078f, -0.469727f, 0.435547f, -0.525391f,
+0.419922f, -0.569824f, 0.409668f, -0.594238f, 0.396973f, -0.612793f, 0.390625f, -0.62207f,
+0.381348f, -0.628418f, 0.369141f, -0.637207f, 0.356934f, -0.641113f, 0.347656f, -0.644043f,
+0.327637f, -0.644043f, 0.327637f, -0.662109f, 0.585449f, -0.662109f, 0.585449f, -0.644043f,
+0.567871f, -0.644043f, 0.540527f, -0.644043f, 0.527832f, -0.632324f, 0.515137f, -0.620605f,
+0.515137f, -0.600586f, 0.515137f, -0.575684f, 0.537109f, -0.513672f, 0.664062f, -0.153809f,
+0.790039f, -0.518555f, 0.811523f, -0.579102f, 0.811523f, -0.602539f, 0.811523f, -0.61377f,
+0.804443f, -0.623535f, 0.797363f, -0.633301f, 0.786621f, -0.637207f, 0.768066f, -0.644043f,
+0.738281f, -0.644043f, 0.738281f, -0.662109f, 0.408203f, -0.366699f, 0.550293f, -0.154785f,
+0.609375f, -0.0668945f, 0.637939f, -0.0437012f, 0.666504f, -0.0205078f, 0.710449f,
+-0.0180664f, 0.710449f, 0, 0.42627f, 0, 0.42627f, -0.0180664f, 0.45459f, -0.0185547f,
+0.468262f, -0.0239258f, 0.478516f, -0.0283203f, 0.485107f, -0.0373535f, 0.491699f,
+-0.0463867f, 0.491699f, -0.0556641f, 0.491699f, -0.0668945f, 0.487305f, -0.078125f,
+0.483887f, -0.0864258f, 0.460449f, -0.121094f, 0.348145f, -0.291016f, 0.209473f,
+-0.113281f, 0.1875f, -0.0849609f, 0.183105f, -0.0754395f, 0.178711f, -0.065918f,
+0.178711f, -0.0556641f, 0.178711f, -0.0400391f, 0.191895f, -0.0297852f, 0.205078f,
+-0.0195312f, 0.242188f, -0.0180664f, 0.242188f, 0, 0.00732422f, 0, 0.00732422f, -0.0180664f,
+0.0322266f, -0.0205078f, 0.050293f, -0.0283203f, 0.0805664f, -0.0410156f, 0.10791f,
+-0.0625f, 0.135254f, -0.0839844f, 0.17041f, -0.128418f, 0.32666f, -0.325684f, 0.196289f,
+-0.516602f, 0.143066f, -0.594238f, 0.105957f, -0.618408f, 0.0688477f, -0.642578f,
+0.0205078f, -0.644043f, 0.0205078f, -0.662109f, 0.32666f, -0.662109f, 0.32666f, -0.644043f,
+0.287598f, -0.642578f, 0.273193f, -0.631348f, 0.258789f, -0.620117f, 0.258789f, -0.606445f,
+0.258789f, -0.588379f, 0.282227f, -0.553711f, 0.383789f, -0.401855f, 0.501465f, -0.550781f,
+0.521973f, -0.577148f, 0.526611f, -0.586914f, 0.53125f, -0.59668f, 0.53125f, -0.606934f,
+0.53125f, -0.617188f, 0.525391f, -0.625f, 0.518066f, -0.635254f, 0.506836f, -0.639404f,
+0.495605f, -0.643555f, 0.460449f, -0.644043f, 0.460449f, -0.662109f, 0.695312f, -0.662109f,
+0.695312f, -0.644043f, 0.66748f, -0.642578f, 0.649902f, -0.635254f, 0.623535f, -0.624023f,
+0.601562f, -0.60498f, 0.57959f, -0.585938f, 0.539551f, -0.534668f, 0.476562f, -0.662109f,
+0.70752f, -0.662109f, 0.70752f, -0.644043f, 0.694824f, -0.644043f, 0.682129f, -0.644043f,
+0.657715f, -0.632812f, 0.633301f, -0.621582f, 0.613281f, -0.600586f, 0.593262f, -0.57959f,
+0.563965f, -0.532227f, 0.404297f, -0.280762f, 0.404297f, -0.114746f, 0.404297f, -0.0537109f,
+0.417969f, -0.0385742f, 0.436523f, -0.0180664f, 0.476562f, -0.0180664f, 0.498047f,
+-0.0180664f, 0.498047f, 0, 0.216797f, 0, 0.216797f, -0.0180664f, 0.240234f, -0.0180664f,
+0.282227f, -0.0180664f, 0.299805f, -0.043457f, 0.310547f, -0.059082f, 0.310547f,
+-0.114746f, 0.310547f, -0.271484f, 0.128906f, -0.548828f, 0.0966797f, -0.597656f,
+0.0852051f, -0.609863f, 0.0737305f, -0.62207f, 0.0375977f, -0.63916f, 0.027832f,
+-0.644043f, 0.00927734f, -0.644043f, 0.00927734f, -0.662109f, 0.29248f, -0.662109f,
+0.29248f, -0.644043f, 0.277832f, -0.644043f, 0.254883f, -0.644043f, 0.235596f, -0.633301f,
+0.216309f, -0.622559f, 0.216309f, -0.601074f, 0.216309f, -0.583496f, 0.246094f, -0.537598f,
+0.384277f, -0.324219f, 0.51416f, -0.52832f, 0.543457f, -0.574219f, 0.543457f, -0.59668f,
+0.543457f, -0.610352f, 0.536377f, -0.621094f, 0.529297f, -0.631836f, 0.516113f, -0.637939f,
+0.50293f, -0.644043f, 0.476562f, -0.644043f, 0.575195f, -0.662109f, 0.140137f, -0.0400391f,
+0.411621f, -0.0400391f, 0.474121f, -0.0400391f, 0.507568f, -0.0673828f, 0.541016f,
+-0.0947266f, 0.566895f, -0.178223f, 0.583008f, -0.175293f, 0.551758f, 0, 0.0126953f,
+0, 0.0126953f, -0.0180664f, 0.4375f, -0.622559f, 0.225586f, -0.622559f, 0.172852f,
+-0.622559f, 0.14917f, -0.611084f, 0.125488f, -0.599609f, 0.113037f, -0.577881f, 0.100586f,
+-0.556152f, 0.090332f, -0.496582f, 0.0717773f, -0.496582f, 0.0854492f, -0.662109f,
+0.296875f, 0.198242f, 0.0820312f, 0.198242f, 0.0820312f, -0.677246f, 0.296875f, -0.677246f,
+0.296875f, -0.638672f, 0.155273f, -0.638672f, 0.155273f, 0.160156f, 0.296875f, 0.160156f,
+0.0405273f, -0.694336f, 0.279785f, 0.0136719f, 0.240723f, 0.0136719f, 0.00146484f,
+-0.694336f, 0.0366211f, -0.677246f, 0.251465f, -0.677246f, 0.251465f, 0.19873f, 0.0366211f,
+0.19873f, 0.0366211f, 0.160156f, 0.178223f, 0.160156f, 0.178223f, -0.638672f, 0.0366211f,
+-0.638672f, 0.243164f, -0.675781f, 0.450684f, -0.325684f, 0.405762f, -0.325684f,
+0.234863f, -0.611816f, 0.0639648f, -0.325684f, 0.0180664f, -0.325684f, 0.228516f,
+-0.675781f, 0.508789f, 0.21582f, -0.00830078f, 0.21582f, -0.00830078f, 0.174805f,
+0.508789f, 0.174805f, 0.0576172f, -0.678711f, 0.166504f, -0.678711f, 0.218262f, -0.510254f,
+0.201172f, -0.510254f, 0.284668f, -0.0644531f, 0.21582f, -0.0112305f, 0.198242f,
+-0.00292969f, 0.171875f, 0.00927734f, 0.14209f, 0.00927734f, 0.0957031f, 0.00927734f,
+0.0656738f, -0.0224609f, 0.0356445f, -0.0541992f, 0.0356445f, -0.105957f, 0.0356445f,
+-0.138672f, 0.050293f, -0.162598f, 0.0703125f, -0.195801f, 0.119873f, -0.225098f,
+0.169434f, -0.254395f, 0.284668f, -0.296387f, 0.284668f, -0.313965f, 0.284668f, -0.380859f,
+0.263428f, -0.405762f, 0.242188f, -0.430664f, 0.20166f, -0.430664f, 0.170898f, -0.430664f,
+0.152832f, -0.414062f, 0.134277f, -0.397461f, 0.134277f, -0.375977f, 0.135254f, -0.347656f,
+0.135254f, -0.325195f, 0.123779f, -0.312988f, 0.112305f, -0.300781f, 0.09375f, -0.300781f,
+0.0756836f, -0.300781f, 0.064209f, -0.313477f, 0.0527344f, -0.326172f, 0.0527344f,
+-0.348145f, 0.0527344f, -0.390137f, 0.0957031f, -0.425293f, 0.138672f, -0.460449f,
+0.216309f, -0.460449f, 0.275879f, -0.460449f, 0.313965f, -0.44043f, 0.342773f, -0.425293f,
+0.356445f, -0.393066f, 0.365234f, -0.37207f, 0.365234f, -0.307129f, 0.365234f, -0.155273f,
+0.365234f, -0.0913086f, 0.367676f, -0.0769043f, 0.370117f, -0.0625f, 0.375732f, -0.0576172f,
+0.381348f, -0.0527344f, 0.388672f, -0.0527344f, 0.396484f, -0.0527344f, 0.402344f,
+-0.0561523f, 0.412598f, -0.0625f, 0.441895f, -0.0917969f, 0.441895f, -0.0644531f,
+0.387207f, 0.00878906f, 0.337402f, 0.00878906f, 0.313477f, 0.00878906f, 0.299316f,
+-0.0078125f, 0.285156f, -0.0244141f, 0.284668f, -0.0644531f, 0.284668f, -0.0961914f,
+0.284668f, -0.266602f, 0.210938f, -0.237305f, 0.189453f, -0.225098f, 0.150879f, -0.203613f,
+0.134277f, -0.180176f, 0.117676f, -0.156738f, 0.117676f, -0.128906f, 0.117676f, -0.09375f,
+0.138672f, -0.0705566f, 0.159668f, -0.0473633f, 0.187012f, -0.0473633f, 0.224121f,
+-0.0473633f, 0.284668f, -0.0961914f, 0.153809f, -0.370117f, 0.21875f, -0.460449f,
+0.293945f, -0.460449f, 0.362793f, -0.460449f, 0.414062f, -0.401611f, 0.465332f, -0.342773f,
+0.465332f, -0.240723f, 0.465332f, -0.121582f, 0.38623f, -0.0488281f, 0.318359f, 0.0136719f,
+0.234863f, 0.0136719f, 0.195801f, 0.0136719f, 0.155518f, -0.000488281f, 0.115234f,
+-0.0146484f, 0.0732422f, -0.0429688f, 0.0732422f, -0.506348f, 0.0732422f, -0.58252f,
+0.0695801f, -0.600098f, 0.065918f, -0.617676f, 0.0581055f, -0.624023f, 0.050293f,
+-0.630371f, 0.0385742f, -0.630371f, 0.0249023f, -0.630371f, 0.00439453f, -0.622559f,
+-0.00244141f, -0.639648f, 0.131836f, -0.694336f, 0.153809f, -0.694336f, 0.153809f,
+-0.338867f, 0.153809f, -0.0712891f, 0.178711f, -0.046875f, 0.205322f, -0.0344238f,
+0.231934f, -0.0219727f, 0.259766f, -0.0219727f, 0.304199f, -0.0219727f, 0.342529f,
+-0.0708008f, 0.380859f, -0.119629f, 0.380859f, -0.212891f, 0.380859f, -0.298828f,
+0.342529f, -0.344971f, 0.304199f, -0.391113f, 0.255371f, -0.391113f, 0.229492f, -0.391113f,
+0.203613f, -0.37793f, 0.184082f, -0.368164f, 0.153809f, -0.338867f, 0.411133f, -0.169922f,
+0.393066f, -0.081543f, 0.340332f, -0.0339355f, 0.287598f, 0.0136719f, 0.223633f,
+0.0136719f, 0.147461f, 0.0136719f, 0.0908203f, -0.050293f, 0.0341797f, -0.114258f,
+0.0341797f, -0.223145f, 0.0341797f, -0.328613f, 0.0969238f, -0.394531f, 0.159668f,
+-0.460449f, 0.247559f, -0.460449f, 0.313477f, -0.460449f, 0.355957f, -0.425537f,
+0.398438f, -0.390625f, 0.398438f, -0.353027f, 0.398438f, -0.334473f, 0.386475f, -0.322998f,
+0.374512f, -0.311523f, 0.353027f, -0.311523f, 0.324219f, -0.311523f, 0.30957f, -0.330078f,
+0.30127f, -0.340332f, 0.298584f, -0.369141f, 0.295898f, -0.397949f, 0.278809f, -0.413086f,
+0.261719f, -0.427734f, 0.231445f, -0.427734f, 0.182617f, -0.427734f, 0.152832f, -0.391602f,
+0.113281f, -0.34375f, 0.113281f, -0.265137f, 0.113281f, -0.185059f, 0.152588f, -0.123779f,
+0.191895f, -0.0625f, 0.258789f, -0.0625f, 0.306641f, -0.0625f, 0.344727f, -0.0952148f,
+0.371582f, -0.117676f, 0.396973f, -0.176758f, 0.347168f, -0.050293f, 0.314453f, -0.0161133f,
+0.283203f, -0.0012207f, 0.251953f, 0.0136719f, 0.21582f, 0.0136719f, 0.142578f, 0.0136719f,
+0.0878906f, -0.0476074f, 0.0332031f, -0.108887f, 0.0332031f, -0.205078f, 0.0332031f,
+-0.30127f, 0.09375f, -0.381104f, 0.154297f, -0.460938f, 0.249512f, -0.460938f, 0.308594f,
+-0.460938f, 0.347168f, -0.42334f, 0.347168f, -0.505859f, 0.347168f, -0.58252f, 0.343506f,
+-0.600098f, 0.339844f, -0.617676f, 0.332031f, -0.624023f, 0.324219f, -0.630371f,
+0.3125f, -0.630371f, 0.299805f, -0.630371f, 0.278809f, -0.622559f, 0.272461f, -0.639648f,
+0.405762f, -0.694336f, 0.427734f, -0.694336f, 0.427734f, -0.177246f, 0.427734f, -0.0986328f,
+0.431396f, -0.0812988f, 0.435059f, -0.0639648f, 0.443115f, -0.0571289f, 0.451172f,
+-0.050293f, 0.461914f, -0.050293f, 0.475098f, -0.050293f, 0.49707f, -0.0585938f,
+0.502441f, -0.0415039f, 0.369629f, 0.0136719f, 0.347168f, 0.0136719f, 0.347168f,
+-0.0844727f, 0.347168f, -0.314941f, 0.344238f, -0.348145f, 0.32959f, -0.375488f,
+0.314941f, -0.402832f, 0.290771f, -0.416748f, 0.266602f, -0.430664f, 0.243652f, -0.430664f,
+0.200684f, -0.430664f, 0.166992f, -0.39209f, 0.122559f, -0.341309f, 0.122559f, -0.243652f,
+0.122559f, -0.14502f, 0.165527f, -0.0925293f, 0.208496f, -0.0400391f, 0.26123f, -0.0400391f,
+0.305664f, -0.0400391f, 0.347168f, -0.0844727f, 0.106445f, -0.278809f, 0.105957f,
+-0.179199f, 0.154785f, -0.122559f, 0.203613f, -0.065918f, 0.269531f, -0.065918f,
+0.313477f, -0.065918f, 0.345947f, -0.0900879f, 0.378418f, -0.114258f, 0.400391f,
+-0.172852f, 0.415527f, -0.163086f, 0.405273f, -0.0961914f, 0.355957f, -0.0412598f,
+0.306641f, 0.0136719f, 0.232422f, 0.0136719f, 0.151855f, 0.0136719f, 0.0944824f,
+-0.0490723f, 0.0371094f, -0.111816f, 0.0371094f, -0.217773f, 0.0371094f, -0.33252f,
+0.0959473f, -0.396729f, 0.154785f, -0.460938f, 0.243652f, -0.460938f, 0.318848f,
+-0.460938f, 0.367188f, -0.411377f, 0.415527f, -0.361816f, 0.415527f, -0.278809f,
+0.106445f, -0.307129f, 0.313477f, -0.307129f, 0.311035f, -0.350098f, 0.303223f, -0.367676f,
+0.291016f, -0.39502f, 0.266846f, -0.410645f, 0.242676f, -0.42627f, 0.216309f, -0.42627f,
+0.175781f, -0.42627f, 0.143799f, -0.394775f, 0.111816f, -0.363281f, 0.106445f, -0.307129f,
+0.206055f, -0.412109f, 0.206055f, -0.118164f, 0.206055f, -0.0556641f, 0.219727f,
+-0.0390625f, 0.237793f, -0.0175781f, 0.268066f, -0.0175781f, 0.308594f, -0.0175781f,
+0.308594f, 0, 0.0415039f, 0, 0.0415039f, -0.0175781f, 0.0615234f, -0.0175781f, 0.0810547f,
+-0.0175781f, 0.097168f, -0.0273438f, 0.113281f, -0.0371094f, 0.119385f, -0.0537109f,
+0.125488f, -0.0703125f, 0.125488f, -0.118164f, 0.125488f, -0.412109f, 0.0385742f,
+-0.412109f, 0.0385742f, -0.447266f, 0.125488f, -0.447266f, 0.125488f, -0.476562f,
+0.125488f, -0.543457f, 0.146973f, -0.589844f, 0.168457f, -0.63623f, 0.212646f, -0.664795f,
+0.256836f, -0.693359f, 0.312012f, -0.693359f, 0.363281f, -0.693359f, 0.40625f, -0.660156f,
+0.43457f, -0.638184f, 0.43457f, -0.61084f, 0.43457f, -0.596191f, 0.421875f, -0.583252f,
+0.40918f, -0.570312f, 0.394531f, -0.570312f, 0.383301f, -0.570312f, 0.37085f, -0.578369f,
+0.358398f, -0.586426f, 0.340332f, -0.613037f, 0.322266f, -0.639648f, 0.307129f, -0.648926f,
+0.291992f, -0.658203f, 0.273438f, -0.658203f, 0.250977f, -0.658203f, 0.235352f, -0.64624f,
+0.219727f, -0.634277f, 0.212891f, -0.609131f, 0.206055f, -0.583984f, 0.206055f, -0.479492f,
+0.206055f, -0.447266f, 0.321289f, -0.447266f, 0.321289f, -0.412109f, 0.150879f, -0.163086f,
+0.109863f, -0.183105f, 0.0878906f, -0.218994f, 0.065918f, -0.254883f, 0.065918f,
+-0.29834f, 0.065918f, -0.364746f, 0.115967f, -0.412598f, 0.166016f, -0.460449f, 0.244141f,
+-0.460449f, 0.308105f, -0.460449f, 0.35498f, -0.429199f, 0.449707f, -0.429199f, 0.470703f,
+-0.429199f, 0.474121f, -0.427979f, 0.477539f, -0.426758f, 0.479004f, -0.423828f,
+0.481934f, -0.419434f, 0.481934f, -0.408203f, 0.481934f, -0.395508f, 0.479492f, -0.390625f,
+0.478027f, -0.388184f, 0.474365f, -0.386719f, 0.470703f, -0.385254f, 0.449707f, -0.385254f,
+0.391602f, -0.385254f, 0.418945f, -0.350098f, 0.418945f, -0.29541f, 0.418945f, -0.23291f,
+0.371094f, -0.188477f, 0.323242f, -0.144043f, 0.242676f, -0.144043f, 0.209473f, -0.144043f,
+0.174805f, -0.153809f, 0.15332f, -0.135254f, 0.145752f, -0.121338f, 0.138184f, -0.107422f,
+0.138184f, -0.0976562f, 0.138184f, -0.0893555f, 0.14624f, -0.081543f, 0.154297f,
+-0.0737305f, 0.177734f, -0.0703125f, 0.191406f, -0.0683594f, 0.246094f, -0.0668945f,
+0.34668f, -0.0644531f, 0.376465f, -0.0600586f, 0.421875f, -0.0537109f, 0.448975f,
+-0.0263672f, 0.476074f, 0.000976562f, 0.476074f, 0.0410156f, 0.476074f, 0.0961914f,
+0.424316f, 0.144531f, 0.348145f, 0.21582f, 0.225586f, 0.21582f, 0.131348f, 0.21582f,
+0.0664062f, 0.17334f, 0.0297852f, 0.148926f, 0.0297852f, 0.122559f, 0.0297852f, 0.11084f,
+0.0351562f, 0.0991211f, 0.043457f, 0.0810547f, 0.0693359f, 0.0488281f, 0.0727539f,
+0.0444336f, 0.119141f, -0.00390625f, 0.09375f, -0.019043f, 0.083252f, -0.0310059f,
+0.0727539f, -0.0429688f, 0.0727539f, -0.0581055f, 0.0727539f, -0.0751953f, 0.0866699f,
+-0.0981445f, 0.100586f, -0.121094f, 0.150879f, -0.163086f, 0.23584f, -0.437012f,
+0.199707f, -0.437012f, 0.175293f, -0.408203f, 0.150879f, -0.379395f, 0.150879f, -0.319824f,
+0.150879f, -0.242676f, 0.184082f, -0.200195f, 0.209473f, -0.167969f, 0.248535f, -0.167969f,
+0.285645f, -0.167969f, 0.30957f, -0.195801f, 0.333496f, -0.223633f, 0.333496f, -0.283203f,
+0.333496f, -0.36084f, 0.299805f, -0.404785f, 0.274902f, -0.437012f, 0.23584f, -0.437012f,
+0.145996f, 0, 0.123047f, 0.0249023f, 0.111328f, 0.0463867f, 0.0996094f, 0.0678711f,
+0.0996094f, 0.0859375f, 0.0996094f, 0.109375f, 0.12793f, 0.126953f, 0.176758f, 0.157227f,
+0.269043f, 0.157227f, 0.356934f, 0.157227f, 0.398682f, 0.126221f, 0.44043f, 0.0952148f,
+0.44043f, 0.0600586f, 0.44043f, 0.034668f, 0.415527f, 0.0239258f, 0.390137f, 0.0131836f,
+0.314941f, 0.0112305f, 0.205078f, 0.00830078f, 0.145996f, 0, 0.14502f, -0.694336f,
+0.165527f, -0.694336f, 0.179932f, -0.679932f, 0.194336f, -0.665527f, 0.194336f, -0.64502f,
+0.194336f, -0.624512f, 0.179932f, -0.609863f, 0.165527f, -0.595215f, 0.14502f, -0.595215f,
+0.124512f, -0.595215f, 0.109863f, -0.609863f, 0.0952148f, -0.624512f, 0.0952148f,
+-0.64502f, 0.0952148f, -0.665527f, 0.109619f, -0.679932f, 0.124023f, -0.694336f,
+0.14502f, -0.694336f, 0.185547f, -0.460449f, 0.185547f, -0.101074f, 0.185547f, -0.059082f,
+0.19165f, -0.045166f, 0.197754f, -0.03125f, 0.209717f, -0.0244141f, 0.22168f, -0.0175781f,
+0.253418f, -0.0175781f, 0.253418f, 0, 0.0361328f, 0, 0.0361328f, -0.0175781f, 0.0688477f,
+-0.0175781f, 0.0800781f, -0.0239258f, 0.0913086f, -0.0302734f, 0.0979004f, -0.0449219f,
+0.104492f, -0.0595703f, 0.104492f, -0.101074f, 0.104492f, -0.273438f, 0.104492f,
+-0.346191f, 0.100098f, -0.367676f, 0.0966797f, -0.383301f, 0.0893555f, -0.389404f,
+0.0820312f, -0.395508f, 0.0693359f, -0.395508f, 0.0556641f, -0.395508f, 0.0361328f,
+-0.388184f, 0.0292969f, -0.405762f, 0.164062f, -0.460449f, 0.144531f, -0.694824f,
+0.165527f, -0.694824f, 0.180176f, -0.680176f, 0.194824f, -0.665527f, 0.194824f, -0.644531f,
+0.194824f, -0.624023f, 0.180176f, -0.609375f, 0.165527f, -0.594727f, 0.144531f, -0.594727f,
+0.124023f, -0.594727f, 0.109375f, -0.609375f, 0.0947266f, -0.624023f, 0.0947266f,
+-0.644531f, 0.0947266f, -0.665527f, 0.109375f, -0.680176f, 0.124023f, -0.694824f,
+0.144531f, -0.694824f, 0.186523f, -0.460449f, 0.186523f, -0.0102539f, 0.186523f,
+0.104492f, 0.137695f, 0.160156f, 0.0888672f, 0.21582f, 0.0107422f, 0.21582f, -0.0336914f,
+0.21582f, -0.0551758f, 0.199707f, -0.0766602f, 0.183594f, -0.0766602f, 0.166504f,
+-0.0766602f, 0.149414f, -0.0646973f, 0.137207f, -0.0527344f, 0.125f, -0.0366211f,
+0.125f, -0.0239258f, 0.125f, -0.0107422f, 0.131348f, -0.00244141f, 0.134766f, 0.0212402f,
+0.156006f, 0.0449219f, 0.177246f, 0.0610352f, 0.177246f, 0.0727539f, 0.177246f, 0.0839844f,
+0.168213f, 0.0952148f, 0.15918f, 0.100586f, 0.137939f, 0.105957f, 0.116699f, 0.105957f,
+0.0458984f, 0.105957f, -0.272461f, 0.105957f, -0.346191f, 0.101562f, -0.367188f,
+0.0981445f, -0.383301f, 0.0908203f, -0.389404f, 0.0834961f, -0.395508f, 0.0708008f,
+-0.395508f, 0.0571289f, -0.395508f, 0.0375977f, -0.388184f, 0.0307617f, -0.405762f,
+0.165527f, -0.460449f, 0.163574f, -0.694336f, 0.163574f, -0.249023f, 0.277344f, -0.353027f,
+0.313477f, -0.38623f, 0.319336f, -0.39502f, 0.323242f, -0.400879f, 0.323242f, -0.406738f,
+0.323242f, -0.416504f, 0.315186f, -0.423584f, 0.307129f, -0.430664f, 0.288574f, -0.431641f,
+0.288574f, -0.447266f, 0.48291f, -0.447266f, 0.48291f, -0.431641f, 0.442871f, -0.430664f,
+0.41626f, -0.419434f, 0.389648f, -0.408203f, 0.35791f, -0.379395f, 0.243164f, -0.273438f,
+0.35791f, -0.128418f, 0.405762f, -0.0683594f, 0.422363f, -0.0522461f, 0.445801f,
+-0.0292969f, 0.463379f, -0.0224609f, 0.475586f, -0.0175781f, 0.505859f, -0.0175781f,
+0.505859f, 0, 0.288574f, 0, 0.288574f, -0.0175781f, 0.307129f, -0.0180664f, 0.313721f,
+-0.0231934f, 0.320312f, -0.0283203f, 0.320312f, -0.0375977f, 0.320312f, -0.0488281f,
+0.300781f, -0.0737305f, 0.163574f, -0.249023f, 0.163574f, -0.100586f, 0.163574f,
+-0.0571289f, 0.169678f, -0.043457f, 0.175781f, -0.0297852f, 0.187012f, -0.0239258f,
+0.198242f, -0.0180664f, 0.23584f, -0.0175781f, 0.23584f, 0, 0.00830078f, 0, 0.00830078f,
+-0.0175781f, 0.0424805f, -0.0175781f, 0.0595703f, -0.0258789f, 0.0698242f, -0.03125f,
+0.0751953f, -0.0424805f, 0.0825195f, -0.0585938f, 0.0825195f, -0.0981445f, 0.0825195f,
+-0.505371f, 0.0825195f, -0.583008f, 0.0791016f, -0.600342f, 0.0756836f, -0.617676f,
+0.0678711f, -0.624268f, 0.0600586f, -0.630859f, 0.0473633f, -0.630859f, 0.0371094f,
+-0.630859f, 0.0166016f, -0.622559f, 0.00830078f, -0.639648f, 0.141113f, -0.694336f,
+0.185059f, -0.694336f, 0.185059f, -0.101074f, 0.185059f, -0.059082f, 0.191162f, -0.0454102f,
+0.197266f, -0.0317383f, 0.209961f, -0.0246582f, 0.222656f, -0.0175781f, 0.257324f,
+-0.0175781f, 0.257324f, 0, 0.0380859f, 0, 0.0380859f, -0.0175781f, 0.0688477f, -0.0175781f,
+0.0800781f, -0.0239258f, 0.0913086f, -0.0302734f, 0.0976562f, -0.0449219f, 0.104004f,
+-0.0595703f, 0.104004f, -0.101074f, 0.104004f, -0.507324f, 0.104004f, -0.583008f,
+0.100586f, -0.600342f, 0.097168f, -0.617676f, 0.0895996f, -0.624023f, 0.0820312f,
+-0.630371f, 0.0703125f, -0.630371f, 0.0576172f, -0.630371f, 0.0380859f, -0.622559f,
+0.0297852f, -0.639648f, 0.163086f, -0.694336f, 0.164062f, -0.365234f, 0.212891f,
+-0.414062f, 0.22168f, -0.421387f, 0.243652f, -0.439941f, 0.269043f, -0.450195f, 0.294434f,
+-0.460449f, 0.319336f, -0.460449f, 0.361328f, -0.460449f, 0.391602f, -0.436035f,
+0.421875f, -0.411621f, 0.432129f, -0.365234f, 0.482422f, -0.423828f, 0.51709f, -0.442139f,
+0.551758f, -0.460449f, 0.588379f, -0.460449f, 0.624023f, -0.460449f, 0.651611f, -0.442139f,
+0.679199f, -0.423828f, 0.695312f, -0.382324f, 0.706055f, -0.354004f, 0.706055f, -0.293457f,
+0.706055f, -0.101074f, 0.706055f, -0.059082f, 0.712402f, -0.043457f, 0.717285f, -0.0327148f,
+0.730469f, -0.0251465f, 0.743652f, -0.0175781f, 0.773438f, -0.0175781f, 0.773438f,
+0, 0.552734f, 0, 0.552734f, -0.0175781f, 0.562012f, -0.0175781f, 0.59082f, -0.0175781f,
+0.606934f, -0.0288086f, 0.618164f, -0.0366211f, 0.623047f, -0.0537109f, 0.625f, -0.0620117f,
+0.625f, -0.101074f, 0.625f, -0.293457f, 0.625f, -0.348145f, 0.611816f, -0.370605f,
+0.592773f, -0.401855f, 0.550781f, -0.401855f, 0.524902f, -0.401855f, 0.498779f, -0.388916f,
+0.472656f, -0.375977f, 0.435547f, -0.34082f, 0.43457f, -0.335449f, 0.435547f, -0.314453f,
+0.435547f, -0.101074f, 0.435547f, -0.0551758f, 0.440674f, -0.0439453f, 0.445801f,
+-0.0327148f, 0.459961f, -0.0251465f, 0.474121f, -0.0175781f, 0.508301f, -0.0175781f,
+0.508301f, 0, 0.282227f, 0, 0.282227f, -0.0175781f, 0.319336f, -0.0175781f, 0.333252f,
+-0.0263672f, 0.347168f, -0.0351562f, 0.352539f, -0.0527344f, 0.35498f, -0.0610352f,
+0.35498f, -0.101074f, 0.35498f, -0.293457f, 0.35498f, -0.348145f, 0.338867f, -0.37207f,
+0.317383f, -0.40332f, 0.278809f, -0.40332f, 0.252441f, -0.40332f, 0.226562f, -0.38916f,
+0.186035f, -0.367676f, 0.164062f, -0.34082f, 0.164062f, -0.101074f, 0.164062f, -0.0571289f,
+0.170166f, -0.0439453f, 0.17627f, -0.0307617f, 0.188232f, -0.0241699f, 0.200195f,
+-0.0175781f, 0.236816f, -0.0175781f, 0.236816f, 0, 0.015625f, 0, 0.015625f, -0.0175781f,
+0.0463867f, -0.0175781f, 0.0585938f, -0.0241699f, 0.0708008f, -0.0307617f, 0.0771484f,
+-0.045166f, 0.0834961f, -0.0595703f, 0.0834961f, -0.101074f, 0.0834961f, -0.271973f,
+0.0834961f, -0.345703f, 0.0791016f, -0.367188f, 0.0756836f, -0.383301f, 0.0683594f,
+-0.389404f, 0.0610352f, -0.395508f, 0.0483398f, -0.395508f, 0.034668f, -0.395508f,
+0.015625f, -0.388184f, 0.00830078f, -0.405762f, 0.143066f, -0.460449f, 0.164062f,
+-0.460449f, 0.161621f, -0.365723f, 0.240234f, -0.460449f, 0.311523f, -0.460449f,
+0.348145f, -0.460449f, 0.374512f, -0.442139f, 0.400879f, -0.423828f, 0.416504f, -0.381836f,
+0.427246f, -0.352539f, 0.427246f, -0.291992f, 0.427246f, -0.101074f, 0.427246f, -0.0585938f,
+0.434082f, -0.043457f, 0.439453f, -0.03125f, 0.451416f, -0.0244141f, 0.463379f, -0.0175781f,
+0.495605f, -0.0175781f, 0.495605f, 0, 0.274414f, 0, 0.274414f, -0.0175781f, 0.283691f,
+-0.0175781f, 0.314941f, -0.0175781f, 0.327393f, -0.0270996f, 0.339844f, -0.0366211f,
+0.344727f, -0.0551758f, 0.34668f, -0.0625f, 0.34668f, -0.101074f, 0.34668f, -0.28418f,
+0.34668f, -0.345215f, 0.330811f, -0.372803f, 0.314941f, -0.400391f, 0.277344f, -0.400391f,
+0.219238f, -0.400391f, 0.161621f, -0.336914f, 0.161621f, -0.101074f, 0.161621f, -0.0556641f,
+0.166992f, -0.0449219f, 0.173828f, -0.0307617f, 0.185791f, -0.0241699f, 0.197754f,
+-0.0175781f, 0.234375f, -0.0175781f, 0.234375f, 0, 0.0131836f, 0, 0.0131836f, -0.0175781f,
+0.0229492f, -0.0175781f, 0.0571289f, -0.0175781f, 0.0690918f, -0.0349121f, 0.0810547f,
+-0.0522461f, 0.0810547f, -0.101074f, 0.0810547f, -0.26709f, 0.0810547f, -0.347656f,
+0.0773926f, -0.365234f, 0.0737305f, -0.382812f, 0.0661621f, -0.38916f, 0.0585938f,
+-0.395508f, 0.0458984f, -0.395508f, 0.0322266f, -0.395508f, 0.0131836f, -0.388184f,
+0.00585938f, -0.405762f, 0.140625f, -0.460449f, 0.161621f, -0.460449f, 0.25f, -0.460449f,
+0.351562f, -0.460449f, 0.413086f, -0.383301f, 0.465332f, -0.317383f, 0.465332f, -0.231934f,
+0.465332f, -0.171875f, 0.436523f, -0.110352f, 0.407715f, -0.0488281f, 0.357178f,
+-0.0175781f, 0.306641f, 0.0136719f, 0.244629f, 0.0136719f, 0.143555f, 0.0136719f,
+0.0839844f, -0.0668945f, 0.0336914f, -0.134766f, 0.0336914f, -0.219238f, 0.0336914f,
+-0.280762f, 0.064209f, -0.341553f, 0.0947266f, -0.402344f, 0.144531f, -0.431396f,
+0.194336f, -0.460449f, 0.25f, -0.460449f, 0.234863f, -0.428711f, 0.208984f, -0.428711f,
+0.182861f, -0.41333f, 0.156738f, -0.397949f, 0.140625f, -0.359375f, 0.124512f, -0.320801f,
+0.124512f, -0.260254f, 0.124512f, -0.162598f, 0.16333f, -0.0917969f, 0.202148f, -0.0209961f,
+0.265625f, -0.0209961f, 0.312988f, -0.0209961f, 0.34375f, -0.0600586f, 0.374512f,
+-0.0991211f, 0.374512f, -0.194336f, 0.374512f, -0.313477f, 0.323242f, -0.381836f,
+0.288574f, -0.428711f, 0.234863f, -0.428711f, -0.000976562f, -0.402832f, 0.136719f,
+-0.458496f, 0.155273f, -0.458496f, 0.155273f, -0.354004f, 0.189941f, -0.413086f,
+0.224854f, -0.436768f, 0.259766f, -0.460449f, 0.29834f, -0.460449f, 0.365723f, -0.460449f,
+0.410645f, -0.407715f, 0.46582f, -0.343262f, 0.46582f, -0.239746f, 0.46582f, -0.124023f,
+0.399414f, -0.0483398f, 0.344727f, 0.0136719f, 0.261719f, 0.0136719f, 0.225586f,
+0.0136719f, 0.199219f, 0.00341797f, 0.179688f, -0.00390625f, 0.155273f, -0.0258789f,
+0.155273f, 0.110352f, 0.155273f, 0.15625f, 0.160889f, 0.168701f, 0.166504f, 0.181152f,
+0.18042f, 0.188477f, 0.194336f, 0.195801f, 0.230957f, 0.195801f, 0.230957f, 0.213867f,
+-0.00341797f, 0.213867f, -0.00341797f, 0.195801f, 0.00878906f, 0.195801f, 0.0356445f,
+0.196289f, 0.0546875f, 0.185547f, 0.0639648f, 0.180176f, 0.0690918f, 0.168213f, 0.0742188f,
+0.15625f, 0.0742188f, 0.107422f, 0.0742188f, -0.31543f, 0.0742188f, -0.358887f, 0.0703125f,
+-0.370605f, 0.0664062f, -0.382324f, 0.0578613f, -0.388184f, 0.0493164f, -0.394043f,
+0.034668f, -0.394043f, 0.0229492f, -0.394043f, 0.00488281f, -0.387207f, 0.155273f,
+-0.325195f, 0.155273f, -0.158203f, 0.155273f, -0.104004f, 0.159668f, -0.0869141f,
+0.166504f, -0.0585938f, 0.193115f, -0.0371094f, 0.219727f, -0.015625f, 0.260254f,
+-0.015625f, 0.309082f, -0.015625f, 0.339355f, -0.0537109f, 0.378906f, -0.103516f,
+0.378906f, -0.193848f, 0.378906f, -0.296387f, 0.333984f, -0.351562f, 0.302734f, -0.389648f,
+0.259766f, -0.389648f, 0.236328f, -0.389648f, 0.213379f, -0.37793f, 0.195801f, -0.369141f,
+0.155273f, -0.325195f, 0.427246f, -0.460449f, 0.427246f, 0.114746f, 0.427246f, 0.157715f,
+0.433105f, 0.169922f, 0.438965f, 0.182129f, 0.451416f, 0.188965f, 0.463867f, 0.195801f,
+0.5f, 0.195801f, 0.5f, 0.213867f, 0.274414f, 0.213867f, 0.274414f, 0.195801f, 0.283691f,
+0.195801f, 0.311035f, 0.195801f, 0.325195f, 0.187988f, 0.334961f, 0.182617f, 0.34082f,
+0.168701f, 0.34668f, 0.154785f, 0.34668f, 0.114746f, 0.34668f, -0.0776367f, 0.302246f,
+-0.0249023f, 0.269043f, -0.00561523f, 0.23584f, 0.0136719f, 0.200195f, 0.0136719f,
+0.135254f, 0.0136719f, 0.0842285f, -0.0454102f, 0.0332031f, -0.104492f, 0.0332031f,
+-0.203613f, 0.0332031f, -0.317383f, 0.100586f, -0.388916f, 0.167969f, -0.460449f,
+0.263184f, -0.460449f, 0.291016f, -0.460449f, 0.314453f, -0.452637f, 0.337891f, -0.444824f,
+0.356445f, -0.429199f, 0.384766f, -0.442871f, 0.410645f, -0.460449f, 0.34668f, -0.108398f,
+0.34668f, -0.318359f, 0.34668f, -0.35498f, 0.337158f, -0.375977f, 0.327637f, -0.396973f,
+0.303223f, -0.411621f, 0.278809f, -0.42627f, 0.248047f, -0.42627f, 0.193359f, -0.42627f,
+0.154297f, -0.379883f, 0.115234f, -0.333496f, 0.115234f, -0.239258f, 0.115234f, -0.148926f,
+0.155029f, -0.102051f, 0.194824f, -0.0551758f, 0.250977f, -0.0551758f, 0.279785f,
+-0.0551758f, 0.302246f, -0.067627f, 0.324707f, -0.0800781f, 0.34668f, -0.108398f,
+0.162109f, -0.460449f, 0.162109f, -0.359863f, 0.218262f, -0.460449f, 0.277344f, -0.460449f,
+0.304199f, -0.460449f, 0.321777f, -0.444092f, 0.339355f, -0.427734f, 0.339355f, -0.40625f,
+0.339355f, -0.387207f, 0.32666f, -0.374023f, 0.313965f, -0.36084f, 0.296387f, -0.36084f,
+0.279297f, -0.36084f, 0.258057f, -0.377686f, 0.236816f, -0.394531f, 0.226562f, -0.394531f,
+0.217773f, -0.394531f, 0.20752f, -0.384766f, 0.185547f, -0.364746f, 0.162109f, -0.318848f,
+0.162109f, -0.104492f, 0.162109f, -0.0673828f, 0.171387f, -0.0483398f, 0.177734f,
+-0.0351562f, 0.193848f, -0.0263672f, 0.209961f, -0.0175781f, 0.240234f, -0.0175781f,
+0.240234f, 0, 0.0112305f, 0, 0.0112305f, -0.0175781f, 0.0454102f, -0.0175781f, 0.0620117f,
+-0.0283203f, 0.0742188f, -0.0361328f, 0.0791016f, -0.0532227f, 0.081543f, -0.0615234f,
+0.081543f, -0.100586f, 0.081543f, -0.273926f, 0.081543f, -0.352051f, 0.0783691f,
+-0.366943f, 0.0751953f, -0.381836f, 0.0666504f, -0.388672f, 0.0581055f, -0.395508f,
+0.0454102f, -0.395508f, 0.0302734f, -0.395508f, 0.0112305f, -0.388184f, 0.00634766f,
+-0.405762f, 0.141602f, -0.460449f, 0.320312f, -0.460449f, 0.320312f, -0.308105f,
+0.304199f, -0.308105f, 0.285645f, -0.379883f, 0.256592f, -0.405762f, 0.227539f, -0.431641f,
+0.182617f, -0.431641f, 0.148438f, -0.431641f, 0.127441f, -0.413574f, 0.106445f, -0.395508f,
+0.106445f, -0.373535f, 0.106445f, -0.346191f, 0.12207f, -0.32666f, 0.137207f, -0.306641f,
+0.183594f, -0.28418f, 0.254883f, -0.249512f, 0.354004f, -0.201172f, 0.354004f, -0.12207f,
+0.354004f, -0.0610352f, 0.307861f, -0.0236816f, 0.261719f, 0.0136719f, 0.20459f,
+0.0136719f, 0.163574f, 0.0136719f, 0.11084f, -0.000976562f, 0.0947266f, -0.00585938f,
+0.0844727f, -0.00585938f, 0.0732422f, -0.00585938f, 0.0668945f, 0.00683594f, 0.0507812f,
+0.00683594f, 0.0507812f, -0.152832f, 0.0668945f, -0.152832f, 0.0805664f, -0.0844727f,
+0.119141f, -0.0498047f, 0.157715f, -0.0151367f, 0.205566f, -0.0151367f, 0.239258f,
+-0.0151367f, 0.260498f, -0.0349121f, 0.281738f, -0.0546875f, 0.281738f, -0.0825195f,
+0.281738f, -0.116211f, 0.258057f, -0.13916f, 0.234375f, -0.162109f, 0.163574f, -0.197266f,
+0.0927734f, -0.232422f, 0.0708008f, -0.260742f, 0.0488281f, -0.288574f, 0.0488281f,
+-0.331055f, 0.0488281f, -0.38623f, 0.0866699f, -0.42334f, 0.124512f, -0.460449f,
+0.18457f, -0.460449f, 0.210938f, -0.460449f, 0.248535f, -0.449219f, 0.273438f, -0.441895f,
+0.281738f, -0.441895f, 0.289551f, -0.441895f, 0.293945f, -0.445312f, 0.29834f, -0.44873f,
+0.304199f, -0.460449f, 0.161133f, -0.594238f, 0.161133f, -0.447266f, 0.265625f, -0.447266f,
+0.265625f, -0.413086f, 0.161133f, -0.413086f, 0.161133f, -0.123047f, 0.161133f, -0.0795898f,
+0.173584f, -0.0644531f, 0.186035f, -0.0493164f, 0.205566f, -0.0493164f, 0.22168f,
+-0.0493164f, 0.236816f, -0.0593262f, 0.251953f, -0.0693359f, 0.260254f, -0.0888672f,
+0.279297f, -0.0888672f, 0.262207f, -0.0410156f, 0.230957f, -0.0168457f, 0.199707f,
+0.00732422f, 0.166504f, 0.00732422f, 0.144043f, 0.00732422f, 0.122559f, -0.00512695f,
+0.101074f, -0.0175781f, 0.0908203f, -0.0407715f, 0.0805664f, -0.0639648f, 0.0805664f,
+-0.112305f, 0.0805664f, -0.413086f, 0.00976562f, -0.413086f, 0.00976562f, -0.429199f,
+0.0366211f, -0.439941f, 0.0646973f, -0.465576f, 0.0927734f, -0.491211f, 0.114746f,
+-0.526367f, 0.125977f, -0.544922f, 0.145996f, -0.594238f, 0.42334f, -0.447266f, 0.42334f,
+-0.17627f, 0.42334f, -0.0986328f, 0.427002f, -0.0812988f, 0.430664f, -0.0639648f,
+0.438721f, -0.0571289f, 0.446777f, -0.050293f, 0.45752f, -0.050293f, 0.472656f, -0.050293f,
+0.491699f, -0.0585938f, 0.498535f, -0.0415039f, 0.364746f, 0.0136719f, 0.342773f,
+0.0136719f, 0.342773f, -0.0810547f, 0.285156f, -0.0185547f, 0.254883f, -0.00244141f,
+0.224609f, 0.0136719f, 0.190918f, 0.0136719f, 0.15332f, 0.0136719f, 0.125732f, -0.00805664f,
+0.0981445f, -0.0297852f, 0.0874023f, -0.0639648f, 0.0766602f, -0.0981445f, 0.0766602f,
+-0.160645f, 0.0766602f, -0.360352f, 0.0766602f, -0.39209f, 0.0698242f, -0.404297f,
+0.0629883f, -0.416504f, 0.0495605f, -0.423096f, 0.0361328f, -0.429688f, 0.000976562f,
+-0.429199f, 0.000976562f, -0.447266f, 0.157715f, -0.447266f, 0.157715f, -0.147949f,
+0.157715f, -0.0854492f, 0.179443f, -0.065918f, 0.201172f, -0.0463867f, 0.231934f,
+-0.0463867f, 0.25293f, -0.0463867f, 0.279541f, -0.0595703f, 0.306152f, -0.0727539f,
+0.342773f, -0.109863f, 0.342773f, -0.363281f, 0.342773f, -0.401367f, 0.328857f, -0.414795f,
+0.314941f, -0.428223f, 0.270996f, -0.429199f, 0.270996f, -0.447266f, 0.00830078f,
+-0.447266f, 0.21875f, -0.447266f, 0.21875f, -0.429199f, 0.205078f, -0.429199f, 0.186035f,
+-0.429199f, 0.176025f, -0.419922f, 0.166016f, -0.410645f, 0.166016f, -0.39502f, 0.166016f,
+-0.37793f, 0.17627f, -0.354492f, 0.280273f, -0.107422f, 0.384766f, -0.36377f, 0.395996f,
+-0.391113f, 0.395996f, -0.405273f, 0.395996f, -0.412109f, 0.39209f, -0.416504f, 0.386719f,
+-0.423828f, 0.378418f, -0.426514f, 0.370117f, -0.429199f, 0.344727f, -0.429199f,
+0.344727f, -0.447266f, 0.490723f, -0.447266f, 0.490723f, -0.429199f, 0.465332f, -0.427246f,
+0.455566f, -0.418945f, 0.438477f, -0.404297f, 0.424805f, -0.370117f, 0.266113f, 0.0136719f,
+0.246094f, 0.0136719f, 0.0864258f, -0.36377f, 0.0756836f, -0.390137f, 0.065918f,
+-0.401611f, 0.0561523f, -0.413086f, 0.0410156f, -0.420898f, 0.0327148f, -0.425293f,
+0.00830078f, -0.429199f, 0.00634766f, -0.447266f, 0.193848f, -0.447266f, 0.193848f,
+-0.429199f, 0.167969f, -0.427246f, 0.159912f, -0.419922f, 0.151855f, -0.412598f,
+0.151855f, -0.398926f, 0.151855f, -0.383789f, 0.160156f, -0.362305f, 0.255859f, -0.10498f,
+0.352051f, -0.314453f, 0.32666f, -0.380371f, 0.314941f, -0.409668f, 0.295898f, -0.420898f,
+0.285156f, -0.427734f, 0.255859f, -0.429199f, 0.255859f, -0.447266f, 0.46875f, -0.447266f,
+0.46875f, -0.429199f, 0.433594f, -0.427734f, 0.418945f, -0.416504f, 0.40918f, -0.408691f,
+0.40918f, -0.391602f, 0.40918f, -0.381836f, 0.413086f, -0.371582f, 0.514648f, -0.114746f,
+0.608887f, -0.362305f, 0.618652f, -0.388672f, 0.618652f, -0.404297f, 0.618652f, -0.413574f,
+0.609131f, -0.420898f, 0.599609f, -0.428223f, 0.571777f, -0.429199f, 0.571777f, -0.447266f,
+0.712891f, -0.447266f, 0.712891f, -0.429199f, 0.67041f, -0.422852f, 0.650391f, -0.371582f,
+0.500977f, 0.0136719f, 0.480957f, 0.0136719f, 0.369141f, -0.271973f, 0.23877f, 0.0136719f,
+0.220703f, 0.0136719f, 0.0771484f, -0.362305f, 0.0629883f, -0.397949f, 0.0493164f,
+-0.4104f, 0.0356445f, -0.422852f, 0.00634766f, -0.429199f, 0.0131836f, -0.447266f,
+0.223633f, -0.447266f, 0.223633f, -0.429199f, 0.203613f, -0.429199f, 0.195557f, -0.422363f,
+0.1875f, -0.415527f, 0.1875f, -0.404297f, 0.1875f, -0.392578f, 0.20459f, -0.368164f,
+0.209961f, -0.360352f, 0.220703f, -0.34375f, 0.252441f, -0.292969f, 0.289062f, -0.34375f,
+0.324219f, -0.39209f, 0.324219f, -0.404785f, 0.324219f, -0.415039f, 0.315918f, -0.422119f,
+0.307617f, -0.429199f, 0.289062f, -0.429199f, 0.289062f, -0.447266f, 0.44043f, -0.447266f,
+0.44043f, -0.429199f, 0.416504f, -0.427734f, 0.398926f, -0.416016f, 0.375f, -0.399414f,
+0.333496f, -0.34375f, 0.272461f, -0.262207f, 0.383789f, -0.102051f, 0.424805f, -0.0429688f,
+0.442383f, -0.0310059f, 0.459961f, -0.019043f, 0.487793f, -0.0175781f, 0.487793f,
+0, 0.276855f, 0, 0.276855f, -0.0175781f, 0.298828f, -0.0175781f, 0.311035f, -0.0273438f,
+0.320312f, -0.0341797f, 0.320312f, -0.0454102f, 0.320312f, -0.0566406f, 0.289062f,
+-0.102051f, 0.223633f, -0.197754f, 0.151855f, -0.102051f, 0.118652f, -0.0576172f,
+0.118652f, -0.0493164f, 0.118652f, -0.0375977f, 0.129639f, -0.0280762f, 0.140625f,
+-0.0185547f, 0.162598f, -0.0175781f, 0.162598f, 0, 0.0166016f, 0, 0.0166016f, -0.0175781f,
+0.0341797f, -0.0200195f, 0.0473633f, -0.0297852f, 0.065918f, -0.0439453f, 0.109863f,
+-0.102051f, 0.203613f, -0.226562f, 0.118652f, -0.349609f, 0.0825195f, -0.402344f,
+0.0627441f, -0.415771f, 0.0429688f, -0.429199f, 0.0131836f, -0.429199f, 0.00585938f,
+-0.447266f, 0.214355f, -0.447266f, 0.214355f, -0.429199f, 0.204102f, -0.429199f,
+0.182129f, -0.429199f, 0.171143f, -0.419678f, 0.160156f, -0.410156f, 0.160156f, -0.395996f,
+0.160156f, -0.376953f, 0.17627f, -0.343262f, 0.285156f, -0.117676f, 0.385254f, -0.364746f,
+0.393555f, -0.384766f, 0.393555f, -0.404297f, 0.393555f, -0.413086f, 0.390137f, -0.41748f,
+0.38623f, -0.422852f, 0.37793f, -0.426025f, 0.369629f, -0.429199f, 0.348633f, -0.429199f,
+0.348633f, -0.447266f, 0.494141f, -0.447266f, 0.494141f, -0.429199f, 0.476074f, -0.427246f,
+0.466309f, -0.421387f, 0.456543f, -0.415527f, 0.444824f, -0.399414f, 0.44043f, -0.392578f,
+0.428223f, -0.361816f, 0.246094f, 0.0844727f, 0.219727f, 0.149414f, 0.177002f, 0.182617f,
+0.134277f, 0.21582f, 0.0947266f, 0.21582f, 0.065918f, 0.21582f, 0.0473633f, 0.199219f,
+0.0288086f, 0.182617f, 0.0288086f, 0.161133f, 0.0288086f, 0.140625f, 0.0422363f,
+0.128174f, 0.0556641f, 0.115723f, 0.0791016f, 0.115723f, 0.0952148f, 0.115723f, 0.123047f,
+0.126465f, 0.142578f, 0.133789f, 0.147461f, 0.133789f, 0.162109f, 0.133789f, 0.179443f,
+0.118652f, 0.196777f, 0.103516f, 0.214355f, 0.0600586f, 0.246094f, -0.0175781f, 0.0854492f,
+-0.35498f, 0.078125f, -0.370117f, 0.0620117f, -0.392578f, 0.0498047f, -0.409668f,
+0.0419922f, -0.415527f, 0.0307617f, -0.42334f, 0.00585938f, -0.429199f, 0.419922f,
+-0.137207f, 0.414551f, 0, 0.0200195f, 0, 0.0200195f, -0.0175781f, 0.316895f, -0.413086f,
+0.17041f, -0.413086f, 0.123047f, -0.413086f, 0.108398f, -0.406982f, 0.09375f, -0.400879f,
+0.0844727f, -0.383789f, 0.0712891f, -0.359375f, 0.0693359f, -0.323242f, 0.0498047f,
+-0.323242f, 0.0527344f, -0.447266f, 0.427734f, -0.447266f, 0.427734f, -0.429199f,
+0.12793f, -0.0327148f, 0.291016f, -0.0327148f, 0.342285f, -0.0327148f, 0.360596f,
+-0.0412598f, 0.378906f, -0.0498047f, 0.390137f, -0.0712891f, 0.397949f, -0.0869141f,
+0.40332f, -0.137207f
+};
+
+const unsigned char TimesNewRomankNormalVerbs[] = {
+6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2,
+2, 2, 2, 2, 1, 5, 0, 1, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1,
+2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 5,
+0, 1, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 5, 0, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1,
+2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0,
+1, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 1,
+1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2,
+5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1,
+1, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1,
+1, 5, 6, 0, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5,
+0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1,
+1, 2, 2, 1, 1, 1, 2, 2, 2, 5, 0, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1,
+2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2,
+2, 2, 5, 6, 0, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1,
+1, 1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 1, 1, 1, 2,
+2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 5,
+6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2,
+2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 2, 1,
+1, 1, 1, 1, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2,
+1, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+2, 2, 2, 5, 6, 0, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2,
+2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2,
+5, 6, 0, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2,
+2, 5, 6, 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2,
+2, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2,
+2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 2, 5, 6, 0, 1, 2, 2, 1, 1, 1,
+1, 1, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 6, 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1, 1, 2,
+2, 2, 2, 2, 1, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2,
+2, 1, 1, 5, 6, 0, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2,
+1, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1,
+1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 5, 6, 0, 1, 2, 2, 1, 1,
+1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2,
+2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 5, 6, 0, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2,
+1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 5, 6,
+0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 5,
+6, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 5, 6, 0,
+1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2, 5,
+6, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 5, 0, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0,
+2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 5, 0, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 1, 2,
+2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0,
+2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 0, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 5, 6, 0, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1,
+1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1,
+1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1,
+2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
+1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2,
+1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 2,
+2, 2, 2, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2,
+2, 1, 2, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 1, 1,
+1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2,
+2, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 2, 1, 1, 1, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2,
+2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1,
+1, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 5, 6, 0, 1, 1, 2,
+2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2,
+2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 5, 6, 0, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1,
+1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1,
+1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 5, 6
+};
+
+const unsigned TimesNewRomankNormalCharCodes[] = {
+32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+42, 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63,
+64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84,
+86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 105,
+106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+122
+};
+
+const SkFixed TimesNewRomankNormalWidths[] = {
+0x00004000, 0x00005540, 0x00006880, 0x00008000, 0x00008000, 0x0000d540, 0x0000c720,
+0x00002e20, 0x00005540, 0x00005540, 0x00008000, 0x00009060, 0x00004000, 0x00005540,
+0x00004000, 0x00004720, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000,
+0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00004720, 0x00009060, 0x00009060,
+0x00009060, 0x000071a0, 0x0000ebc0, 0x0000b8e0, 0x0000aac0, 0x0000aac0, 0x0000b8e0,
+0x00009c60, 0x00008e60, 0x0000b8e0, 0x0000b8e0, 0x00005540, 0x000063a0, 0x0000b8e0,
+0x00009c60, 0x0000e3a0, 0x0000b8e0, 0x00008e60, 0x0000b8e0, 0x0000aac0, 0x00008e60,
+0x00009c60, 0x0000b8e0, 0x0000f1a0, 0x0000b8e0, 0x0000b8e0, 0x00009c60, 0x00005540,
+0x00004720, 0x00005540, 0x00007820, 0x00008000, 0x00005540, 0x000071a0, 0x00008000,
+0x000071a0, 0x00008000, 0x000071a0, 0x00005540, 0x00008000, 0x00004720, 0x00004720,
+0x00008000, 0x00004720, 0x0000c720, 0x00008000, 0x00008000, 0x00008000, 0x00008000,
+0x00005540, 0x000063a0, 0x00004720, 0x00008000, 0x00008000, 0x0000b8e0, 0x00008000,
+0x00008000, 0x000071a0
+};
+
+const int TimesNewRomankNormalCharCodesCount = (int) SK_ARRAY_COUNT(TimesNewRomankNormalCharCodes);
+
+const SkPaint::FontMetrics TimesNewRomankNormalMetrics = {
+0x2d202c67, -1.00684f, -0.891113f, 0.216309f, 0.306641f, 0.0424805f, 2.56836f, 4.1423e-11f,
+-0.568359f, 2, 0.460449f, 1.01859e-11f, 0.0488281f, 0.108887f
+};
+
+const SkScalar TimesNewRomankBoldPoints[] = {
+0.177734f, -0.215332f, 0.15625f, -0.215332f, 0.152832f, -0.270996f, 0.133789f, -0.350098f,
+0.108398f, -0.456543f, 0.0854492f, -0.552246f, 0.0854492f, -0.59375f, 0.0854492f,
+-0.631348f, 0.10791f, -0.654297f, 0.130371f, -0.677246f, 0.166504f, -0.677246f, 0.20166f,
+-0.677246f, 0.224854f, -0.654053f, 0.248047f, -0.630859f, 0.248047f, -0.595215f,
+0.248047f, -0.558105f, 0.223633f, -0.456543f, 0.197754f, -0.350098f, 0.184082f, -0.293457f,
+0.177734f, -0.215332f, 0.16748f, -0.145508f, 0.200195f, -0.145508f, 0.223389f, -0.122314f,
+0.246582f, -0.0991211f, 0.246582f, -0.065918f, 0.246582f, -0.0332031f, 0.223389f,
+-0.0100098f, 0.200195f, 0.0131836f, 0.16748f, 0.0131836f, 0.134766f, 0.0131836f,
+0.111572f, -0.0100098f, 0.0883789f, -0.0332031f, 0.0883789f, -0.065918f, 0.0883789f,
+-0.0986328f, 0.111328f, -0.12207f, 0.134277f, -0.145508f, 0.16748f, -0.145508f, 0.17041f,
+-0.352051f, 0.146484f, -0.352051f, 0.0957031f, -0.540039f, 0.0859375f, -0.57666f,
+0.0859375f, -0.604492f, 0.0859375f, -0.634766f, 0.107178f, -0.656006f, 0.128418f,
+-0.677246f, 0.158203f, -0.677246f, 0.192383f, -0.677246f, 0.211426f, -0.655029f,
+0.230469f, -0.632812f, 0.230469f, -0.606934f, 0.230469f, -0.584961f, 0.21875f, -0.539062f,
+0.40625f, -0.352051f, 0.381836f, -0.352051f, 0.33252f, -0.539551f, 0.320801f, -0.58252f,
+0.320801f, -0.605957f, 0.320801f, -0.634277f, 0.342529f, -0.655762f, 0.364258f, -0.677246f,
+0.394531f, -0.677246f, 0.429199f, -0.677246f, 0.44751f, -0.654297f, 0.46582f, -0.631348f,
+0.46582f, -0.607422f, 0.46582f, -0.590332f, 0.453125f, -0.539551f, 0.0439453f, 0.0136719f,
+0.0859375f, -0.193359f, 0.0195312f, -0.193359f, 0.0195312f, -0.258301f, 0.0986328f,
+-0.258301f, 0.127441f, -0.400879f, 0.0195312f, -0.400879f, 0.0195312f, -0.464355f,
+0.140137f, -0.464355f, 0.182617f, -0.675781f, 0.24707f, -0.675781f, 0.204102f, -0.464355f,
+0.348145f, -0.464355f, 0.390137f, -0.675781f, 0.45459f, -0.675781f, 0.411621f, -0.464355f,
+0.47998f, -0.464355f, 0.47998f, -0.400879f, 0.399414f, -0.400879f, 0.370117f, -0.258301f,
+0.47998f, -0.258301f, 0.47998f, -0.193359f, 0.35791f, -0.193359f, 0.315918f, 0.0136719f,
+0.250977f, 0.0136719f, 0.292969f, -0.193359f, 0.150879f, -0.193359f, 0.106934f, 0.0136719f,
+0.163574f, -0.258301f, 0.307129f, -0.258301f, 0.335449f, -0.400879f, 0.191895f, -0.400879f,
+0.276367f, -0.407715f, 0.393066f, -0.333984f, 0.425293f, -0.296387f, 0.468262f, -0.245605f,
+0.468262f, -0.176758f, 0.468262f, -0.101562f, 0.41748f, -0.0495605f, 0.366699f, 0.00244141f,
+0.276367f, 0.0102539f, 0.276367f, 0.0673828f, 0.233887f, 0.0673828f, 0.233887f, 0.0136719f,
+0.182129f, 0.0126953f, 0.14209f, 0.00512695f, 0.102051f, -0.00244141f, 0.050293f,
+-0.0224609f, 0.050293f, -0.180176f, 0.0708008f, -0.180176f, 0.0805664f, -0.126465f,
+0.101562f, -0.0932617f, 0.122559f, -0.0600586f, 0.154541f, -0.0432129f, 0.186523f,
+-0.0263672f, 0.233887f, -0.0224609f, 0.233887f, -0.263672f, 0.116211f, -0.337402f,
+0.0773926f, -0.381592f, 0.0385742f, -0.425781f, 0.0385742f, -0.484375f, 0.0385742f,
+-0.547852f, 0.0874023f, -0.596436f, 0.13623f, -0.64502f, 0.233887f, -0.657227f, 0.233887f,
+-0.680176f, 0.276367f, -0.680176f, 0.276367f, -0.657227f, 0.359375f, -0.651367f,
+0.443359f, -0.605957f, 0.443359f, -0.464844f, 0.424316f, -0.464844f, 0.410156f, -0.512695f,
+0.390381f, -0.543457f, 0.370605f, -0.574219f, 0.339355f, -0.596191f, 0.31543f, -0.612305f,
+0.276367f, -0.623047f, 0.233887f, -0.624512f, 0.198242f, -0.621582f, 0.176758f, -0.60498f,
+0.142578f, -0.579102f, 0.142578f, -0.54248f, 0.142578f, -0.52002f, 0.158447f, -0.49707f,
+0.174316f, -0.474121f, 0.233887f, -0.43457f, 0.276367f, -0.0224609f, 0.318359f, -0.0322266f,
+0.337891f, -0.0559082f, 0.357422f, -0.0795898f, 0.357422f, -0.115234f, 0.357422f,
+-0.145996f, 0.340088f, -0.172852f, 0.322754f, -0.199707f, 0.276367f, -0.233887f,
+0.768066f, -0.677246f, 0.297852f, 0.027832f, 0.232422f, 0.027832f, 0.702148f, -0.677246f,
+0.233398f, -0.677246f, 0.302734f, -0.677246f, 0.350342f, -0.628174f, 0.397949f, -0.579102f,
+0.397949f, -0.501465f, 0.397949f, -0.421875f, 0.350098f, -0.372314f, 0.302246f, -0.322754f,
+0.231445f, -0.322754f, 0.161621f, -0.322754f, 0.115479f, -0.370605f, 0.0693359f,
+-0.418457f, 0.0693359f, -0.496582f, 0.0693359f, -0.577148f, 0.116699f, -0.627197f,
+0.164062f, -0.677246f, 0.233398f, -0.677246f, 0.233398f, -0.651367f, 0.222656f, -0.651367f,
+0.21582f, -0.64502f, 0.203613f, -0.633789f, 0.19751f, -0.606201f, 0.191406f, -0.578613f,
+0.191406f, -0.492188f, 0.191406f, -0.42334f, 0.199707f, -0.385742f, 0.20459f, -0.364258f,
+0.216309f, -0.353516f, 0.223633f, -0.347168f, 0.233398f, -0.347168f, 0.244141f, -0.347168f,
+0.250488f, -0.353027f, 0.261719f, -0.363281f, 0.26709f, -0.38623f, 0.275391f, -0.42334f,
+0.275391f, -0.490234f, 0.275391f, -0.572266f, 0.267578f, -0.608887f, 0.262207f, -0.634277f,
+0.25f, -0.645996f, 0.244141f, -0.651367f, 0.233398f, -0.651367f, 0.764648f, -0.327637f,
+0.835449f, -0.327637f, 0.883057f, -0.279053f, 0.930664f, -0.230469f, 0.930664f, -0.151855f,
+0.930664f, -0.0722656f, 0.882324f, -0.0224609f, 0.833984f, 0.0273438f, 0.765625f,
+0.0273438f, 0.697754f, 0.0273438f, 0.650146f, -0.0224609f, 0.602539f, -0.0722656f,
+0.602539f, -0.150391f, 0.602539f, -0.229004f, 0.648926f, -0.27832f, 0.695312f, -0.327637f,
+0.764648f, -0.327637f, 0.766113f, -0.302246f, 0.756348f, -0.302246f, 0.749512f, -0.296387f,
+0.737793f, -0.285645f, 0.731445f, -0.259033f, 0.725098f, -0.232422f, 0.725098f, -0.157227f,
+0.725098f, -0.0771484f, 0.732422f, -0.0419922f, 0.737793f, -0.0170898f, 0.750488f,
+-0.00585938f, 0.756836f, 0, 0.76709f, 0, 0.776367f, 0, 0.782227f, -0.00537109f, 0.794434f,
+-0.0166016f, 0.800293f, -0.0419922f, 0.808594f, -0.0776367f, 0.808594f, -0.149902f,
+0.808594f, -0.226074f, 0.800781f, -0.26123f, 0.794922f, -0.286621f, 0.783203f, -0.296875f,
+0.777344f, -0.302246f, 0.766113f, -0.302246f, 0.569336f, -0.395996f, 0.772461f, -0.395996f,
+0.772461f, -0.376953f, 0.738281f, -0.37207f, 0.71875f, -0.356689f, 0.699219f, -0.341309f,
+0.667969f, -0.285156f, 0.636719f, -0.229004f, 0.580078f, -0.159668f, 0.629883f, -0.114746f,
+0.661133f, -0.097168f, 0.683105f, -0.0849609f, 0.704102f, -0.0849609f, 0.740234f,
+-0.0849609f, 0.769531f, -0.132324f, 0.789551f, -0.121582f, 0.749512f, -0.0429688f,
+0.704102f, -0.00976562f, 0.669434f, 0.0151367f, 0.625f, 0.0151367f, 0.586914f, 0.0151367f,
+0.55249f, -0.0012207f, 0.518066f, -0.0175781f, 0.46875f, -0.0625f, 0.407715f, -0.0214844f,
+0.354004f, -0.00317383f, 0.300293f, 0.0151367f, 0.242188f, 0.0151367f, 0.149414f,
+0.0151367f, 0.0947266f, -0.0351562f, 0.0400391f, -0.0854492f, 0.0400391f, -0.15332f,
+0.0400391f, -0.226562f, 0.0922852f, -0.280762f, 0.144531f, -0.334961f, 0.244141f,
+-0.374512f, 0.231445f, -0.40625f, 0.225098f, -0.436523f, 0.21875f, -0.466797f, 0.21875f,
+-0.495117f, 0.21875f, -0.573242f, 0.273682f, -0.625244f, 0.328613f, -0.677246f, 0.414062f,
+-0.677246f, 0.48291f, -0.677246f, 0.523193f, -0.642822f, 0.563477f, -0.608398f, 0.563477f,
+-0.5625f, 0.563477f, -0.507324f, 0.522217f, -0.468018f, 0.480957f, -0.428711f, 0.391602f,
+-0.395996f, 0.446777f, -0.298828f, 0.553223f, -0.186523f, 0.625f, -0.26709f, 0.625f,
+-0.324707f, 0.625f, -0.345215f, 0.61084f, -0.359619f, 0.59668f, -0.374023f, 0.569336f,
+-0.376953f, 0.375f, -0.425293f, 0.42627f, -0.444336f, 0.443848f, -0.466064f, 0.461426f,
+-0.487793f, 0.461426f, -0.518555f, 0.461426f, -0.573242f, 0.432617f, -0.61084f, 0.413574f,
+-0.635742f, 0.385742f, -0.635742f, 0.362793f, -0.635742f, 0.346436f, -0.617676f,
+0.330078f, -0.599609f, 0.330078f, -0.568848f, 0.330078f, -0.544922f, 0.337891f, -0.517578f,
+0.345703f, -0.490234f, 0.375f, -0.425293f, 0.257812f, -0.343262f, 0.21875f, -0.32666f,
+0.202637f, -0.308105f, 0.179688f, -0.280762f, 0.179688f, -0.24707f, 0.179688f, -0.201172f,
+0.206299f, -0.155762f, 0.23291f, -0.110352f, 0.270508f, -0.0854492f, 0.308105f, -0.0605469f,
+0.345703f, -0.0605469f, 0.364258f, -0.0605469f, 0.387451f, -0.0686035f, 0.410645f,
+-0.0766602f, 0.437988f, -0.0927734f, 0.320312f, -0.213379f, 0.257812f, -0.343262f,
+0.152832f, -0.352539f, 0.129395f, -0.352539f, 0.078125f, -0.539062f, 0.0683594f,
+-0.57373f, 0.0683594f, -0.603027f, 0.0683594f, -0.634766f, 0.0891113f, -0.656006f,
+0.109863f, -0.677246f, 0.140137f, -0.677246f, 0.174805f, -0.677246f, 0.193604f, -0.654785f,
+0.212402f, -0.632324f, 0.212402f, -0.605957f, 0.212402f, -0.583984f, 0.201172f, -0.539551f,
+0.321289f, -0.677246f, 0.321289f, -0.654785f, 0.270508f, -0.621582f, 0.246582f, -0.589844f,
+0.213379f, -0.545898f, 0.194824f, -0.477051f, 0.171387f, -0.391602f, 0.171387f, -0.238281f,
+0.171387f, -0.09375f, 0.192627f, -0.0136719f, 0.213867f, 0.0664062f, 0.250488f, 0.115723f,
+0.275879f, 0.149902f, 0.321289f, 0.175781f, 0.321289f, 0.200195f, 0.203613f, 0.160645f,
+0.121826f, 0.0388184f, 0.0400391f, -0.0830078f, 0.0400391f, -0.241211f, 0.0400391f,
+-0.397461f, 0.121582f, -0.517822f, 0.203125f, -0.638184f, 0.321289f, -0.677246f,
+0.012207f, 0.200195f, 0.012207f, 0.177734f, 0.0629883f, 0.144043f, 0.0869141f, 0.112305f,
+0.119629f, 0.0683594f, 0.138672f, 0, 0.162109f, -0.0859375f, 0.162109f, -0.239258f,
+0.162109f, -0.383789f, 0.140869f, -0.463623f, 0.119629f, -0.543457f, 0.0830078f,
+-0.592773f, 0.0576172f, -0.626953f, 0.012207f, -0.652832f, 0.012207f, -0.677246f,
+0.129883f, -0.637695f, 0.21167f, -0.515869f, 0.293457f, -0.394043f, 0.293457f, -0.23584f,
+0.293457f, -0.0800781f, 0.21167f, 0.0402832f, 0.129883f, 0.160645f, 0.012207f, 0.200195f,
+0.240723f, -0.484375f, 0.239258f, -0.512695f, 0.235107f, -0.527344f, 0.230957f, -0.541992f,
+0.215088f, -0.572754f, 0.199219f, -0.603516f, 0.199219f, -0.620605f, 0.199219f, -0.643066f,
+0.215088f, -0.660156f, 0.230957f, -0.677246f, 0.25f, -0.677246f, 0.270996f, -0.677246f,
+0.286377f, -0.661377f, 0.301758f, -0.645508f, 0.301758f, -0.620117f, 0.301758f, -0.600098f,
+0.286621f, -0.571777f, 0.271484f, -0.543457f, 0.267334f, -0.528564f, 0.263184f, -0.513672f,
+0.260742f, -0.484375f, 0.288086f, -0.495605f, 0.299805f, -0.503906f, 0.311523f, -0.512207f,
+0.334473f, -0.536621f, 0.365234f, -0.569336f, 0.393555f, -0.569336f, 0.415039f, -0.569336f,
+0.429688f, -0.555176f, 0.444336f, -0.541016f, 0.444336f, -0.521484f, 0.444336f, -0.500488f,
+0.42627f, -0.484375f, 0.408203f, -0.468262f, 0.379395f, -0.468262f, 0.369629f, -0.468262f,
+0.344727f, -0.469727f, 0.333008f, -0.470215f, 0.319336f, -0.470215f, 0.30127f, -0.470215f,
+0.264648f, -0.468262f, 0.285645f, -0.444336f, 0.297363f, -0.435303f, 0.309082f, -0.42627f,
+0.337891f, -0.411621f, 0.366699f, -0.396973f, 0.379395f, -0.380371f, 0.388672f, -0.368164f,
+0.388672f, -0.349121f, 0.388672f, -0.328125f, 0.374512f, -0.313721f, 0.360352f, -0.299316f,
+0.340332f, -0.299316f, 0.319336f, -0.299316f, 0.30249f, -0.31665f, 0.285645f, -0.333984f,
+0.279297f, -0.378418f, 0.275391f, -0.407227f, 0.270752f, -0.42041f, 0.266113f, -0.433594f,
+0.250977f, -0.458984f, 0.234863f, -0.433105f, 0.229492f, -0.418945f, 0.224121f, -0.404785f,
+0.220215f, -0.378418f, 0.213867f, -0.333984f, 0.197754f, -0.317383f, 0.181641f, -0.300781f,
+0.160156f, -0.300781f, 0.140137f, -0.300781f, 0.125732f, -0.314453f, 0.111328f, -0.328125f,
+0.111328f, -0.347168f, 0.111328f, -0.366699f, 0.122314f, -0.38208f, 0.133301f, -0.397461f,
+0.162842f, -0.413818f, 0.192383f, -0.430176f, 0.203613f, -0.438477f, 0.214844f, -0.446777f,
+0.236328f, -0.468262f, 0.184082f, -0.470215f, 0.17041f, -0.470215f, 0.158203f, -0.469727f,
+0.129395f, -0.467773f, 0.118652f, -0.467773f, 0.0908203f, -0.467773f, 0.0732422f,
+-0.483398f, 0.0556641f, -0.499023f, 0.0556641f, -0.520508f, 0.0556641f, -0.540527f,
+0.0700684f, -0.554932f, 0.0844727f, -0.569336f, 0.106445f, -0.569336f, 0.137207f,
+-0.569336f, 0.165527f, -0.540039f, 0.193848f, -0.510742f, 0.202148f, -0.504395f,
+0.213867f, -0.496094f, 0.240723f, -0.484375f, 0.0195312f, -0.363281f, 0.254395f,
+-0.363281f, 0.254395f, -0.597656f, 0.318359f, -0.597656f, 0.318359f, -0.363281f,
+0.553223f, -0.363281f, 0.553223f, -0.298828f, 0.318359f, -0.298828f, 0.318359f, -0.0664062f,
+0.254395f, -0.0664062f, 0.254395f, -0.298828f, 0.0195312f, -0.298828f, 0.0498047f,
+0.175293f, 0.0498047f, 0.153809f, 0.106445f, 0.129395f, 0.13208f, 0.0905762f, 0.157715f,
+0.0517578f, 0.157715f, 0.0112305f, 0.157715f, 0.00292969f, 0.154297f, -0.00146484f,
+0.150879f, -0.00537109f, 0.147461f, -0.00537109f, 0.144531f, -0.00537109f, 0.138672f,
+-0.00195312f, 0.124512f, 0.00634766f, 0.103516f, 0.00634766f, 0.074707f, 0.00634766f,
+0.0534668f, -0.0161133f, 0.0322266f, -0.0385742f, 0.0322266f, -0.0688477f, 0.0322266f,
+-0.101074f, 0.0566406f, -0.125488f, 0.0810547f, -0.149902f, 0.115723f, -0.149902f,
+0.157715f, -0.149902f, 0.1875f, -0.117432f, 0.217285f, -0.0849609f, 0.217285f, -0.0283203f,
+0.217285f, 0.0415039f, 0.175049f, 0.0957031f, 0.132812f, 0.149902f, 0.0498047f, 0.175293f,
+0.309082f, -0.179199f, 0.0244141f, -0.179199f, 0.0244141f, -0.280273f, 0.309082f,
+-0.280273f, 0.125f, -0.150391f, 0.15918f, -0.150391f, 0.182861f, -0.126465f, 0.206543f,
+-0.102539f, 0.206543f, -0.0688477f, 0.206543f, -0.0351562f, 0.182617f, -0.0114746f,
+0.158691f, 0.012207f, 0.125f, 0.012207f, 0.0913086f, 0.012207f, 0.067627f, -0.0114746f,
+0.0439453f, -0.0351562f, 0.0439453f, -0.0688477f, 0.0439453f, -0.102539f, 0.067627f,
+-0.126465f, 0.0913086f, -0.150391f, 0.125f, -0.150391f, 0.280762f, -0.677246f, 0.0634766f,
+0.0151367f, 0.000976562f, 0.0151367f, 0.219238f, -0.677246f, 0.463379f, -0.331055f,
+0.463379f, -0.231934f, 0.435547f, -0.145996f, 0.418945f, -0.0932617f, 0.390869f,
+-0.0595703f, 0.362793f, -0.0258789f, 0.327148f, -0.00610352f, 0.291504f, 0.0136719f,
+0.249512f, 0.0136719f, 0.20166f, 0.0136719f, 0.163086f, -0.0107422f, 0.124512f, -0.0351562f,
+0.0947266f, -0.0805664f, 0.0732422f, -0.11377f, 0.0571289f, -0.168945f, 0.0361328f,
+-0.243652f, 0.0361328f, -0.323242f, 0.0361328f, -0.431152f, 0.0664062f, -0.521484f,
+0.0913086f, -0.596191f, 0.14209f, -0.635986f, 0.192871f, -0.675781f, 0.249512f, -0.675781f,
+0.307129f, -0.675781f, 0.357178f, -0.636475f, 0.407227f, -0.597168f, 0.430664f, -0.530762f,
+0.463379f, -0.439453f, 0.463379f, -0.331055f, 0.312988f, -0.332031f, 0.312988f, -0.505859f,
+0.311035f, -0.534668f, 0.306152f, -0.602539f, 0.287598f, -0.626465f, 0.275391f, -0.64209f,
+0.248047f, -0.64209f, 0.227051f, -0.64209f, 0.214844f, -0.630371f, 0.196777f, -0.613281f,
+0.19043f, -0.570068f, 0.184082f, -0.526855f, 0.184082f, -0.268555f, 0.184082f, -0.12793f,
+0.193848f, -0.0800781f, 0.201172f, -0.0454102f, 0.214844f, -0.0336914f, 0.228516f,
+-0.0219727f, 0.250977f, -0.0219727f, 0.275391f, -0.0219727f, 0.287598f, -0.0375977f,
+0.308105f, -0.0649414f, 0.311035f, -0.12207f, 0.325684f, -0.675781f, 0.325684f, -0.134277f,
+0.325684f, -0.0732422f, 0.331055f, -0.0563965f, 0.336426f, -0.0395508f, 0.353516f,
+-0.0288086f, 0.370605f, -0.0180664f, 0.408203f, -0.0180664f, 0.42334f, -0.0180664f,
+0.42334f, 0, 0.074707f, 0, 0.074707f, -0.0180664f, 0.0922852f, -0.0180664f, 0.134766f,
+-0.0180664f, 0.152832f, -0.027832f, 0.170898f, -0.0375977f, 0.177246f, -0.0546875f,
+0.183594f, -0.0717773f, 0.183594f, -0.134277f, 0.183594f, -0.477539f, 0.183594f,
+-0.523438f, 0.179199f, -0.534912f, 0.174805f, -0.546387f, 0.162842f, -0.554443f,
+0.150879f, -0.5625f, 0.135254f, -0.5625f, 0.110352f, -0.5625f, 0.074707f, -0.546875f,
+0.065918f, -0.564453f, 0.30957f, -0.675781f, 0.414062f, 0, 0.0244141f, 0, 0.0244141f,
+-0.0107422f, 0.203613f, -0.224121f, 0.241943f, -0.297852f, 0.280273f, -0.371582f,
+0.280273f, -0.441895f, 0.280273f, -0.493164f, 0.248535f, -0.5271f, 0.216797f, -0.561035f,
+0.170898f, -0.561035f, 0.0957031f, -0.561035f, 0.0541992f, -0.48584f, 0.0361328f,
+-0.492188f, 0.0625f, -0.585938f, 0.116211f, -0.630859f, 0.169922f, -0.675781f, 0.240234f,
+-0.675781f, 0.290527f, -0.675781f, 0.332031f, -0.652344f, 0.373535f, -0.628906f,
+0.396973f, -0.588135f, 0.42041f, -0.547363f, 0.42041f, -0.511719f, 0.42041f, -0.446777f,
+0.384277f, -0.379883f, 0.334961f, -0.289551f, 0.168945f, -0.12793f, 0.312012f, -0.12793f,
+0.364746f, -0.12793f, 0.380615f, -0.132324f, 0.396484f, -0.136719f, 0.406738f, -0.147217f,
+0.416992f, -0.157715f, 0.433594f, -0.191406f, 0.451172f, -0.191406f, 0.147949f, -0.332031f,
+0.147949f, -0.349121f, 0.203613f, -0.365234f, 0.225098f, -0.37915f, 0.246582f, -0.393066f,
+0.262207f, -0.421631f, 0.277832f, -0.450195f, 0.277832f, -0.479492f, 0.277832f, -0.52002f,
+0.248291f, -0.549072f, 0.21875f, -0.578125f, 0.174805f, -0.578125f, 0.106445f, -0.578125f,
+0.0585938f, -0.505859f, 0.0405273f, -0.512207f, 0.0756836f, -0.59375f, 0.130615f,
+-0.634766f, 0.185547f, -0.675781f, 0.25293f, -0.675781f, 0.321777f, -0.675781f, 0.366455f,
+-0.633789f, 0.411133f, -0.591797f, 0.411133f, -0.535645f, 0.411133f, -0.499023f,
+0.390381f, -0.465088f, 0.369629f, -0.431152f, 0.325195f, -0.405273f, 0.382324f, -0.377441f,
+0.412354f, -0.33667f, 0.442383f, -0.295898f, 0.442383f, -0.234375f, 0.442383f, -0.130859f,
+0.367432f, -0.0583496f, 0.29248f, 0.0141602f, 0.166504f, 0.0141602f, 0.0825195f,
+0.0141602f, 0.0439453f, -0.0136719f, 0.0161133f, -0.0332031f, 0.0161133f, -0.0639648f,
+0.0161133f, -0.0864258f, 0.0322266f, -0.102295f, 0.0483398f, -0.118164f, 0.0693359f,
+-0.118164f, 0.0854492f, -0.118164f, 0.0996094f, -0.111328f, 0.107422f, -0.107422f,
+0.155029f, -0.0686035f, 0.202637f, -0.0297852f, 0.244141f, -0.0297852f, 0.280273f,
+-0.0297852f, 0.306152f, -0.0583496f, 0.332031f, -0.0869141f, 0.332031f, -0.130859f,
+0.332031f, -0.197754f, 0.285156f, -0.25415f, 0.238281f, -0.310547f, 0.147949f, -0.332031f,
+0.0249023f, -0.249512f, 0.339355f, -0.675781f, 0.398926f, -0.675781f, 0.398926f,
+-0.249512f, 0.459473f, -0.249512f, 0.459473f, -0.148438f, 0.398926f, -0.148438f,
+0.398926f, 0, 0.264648f, 0, 0.264648f, -0.148438f, 0.0249023f, -0.148438f, 0.0722656f,
+-0.249512f, 0.264648f, -0.249512f, 0.264648f, -0.510742f, 0.152344f, -0.662109f,
+0.462402f, -0.662109f, 0.413086f, -0.536133f, 0.152344f, -0.536133f, 0.127441f, -0.470215f,
+0.295898f, -0.463867f, 0.386719f, -0.38623f, 0.461426f, -0.322266f, 0.461426f, -0.227051f,
+0.461426f, -0.166016f, 0.426758f, -0.107666f, 0.39209f, -0.0493164f, 0.329102f, -0.0178223f,
+0.266113f, 0.0136719f, 0.190918f, 0.0136719f, 0.109863f, 0.0136719f, 0.0664062f,
+-0.0166016f, 0.0361328f, -0.0380859f, 0.0361328f, -0.0654297f, 0.0361328f, -0.0864258f,
+0.052002f, -0.102539f, 0.0678711f, -0.118652f, 0.0888672f, -0.118652f, 0.10791f,
+-0.118652f, 0.127441f, -0.11084f, 0.146973f, -0.103027f, 0.194336f, -0.0698242f,
+0.224121f, -0.0493164f, 0.245605f, -0.0415039f, 0.260742f, -0.0356445f, 0.279785f,
+-0.0356445f, 0.319824f, -0.0356445f, 0.3479f, -0.0649414f, 0.375977f, -0.0942383f,
+0.375977f, -0.135254f, 0.375977f, -0.221191f, 0.290039f, -0.274902f, 0.204102f, -0.328613f,
+0.0732422f, -0.328613f, 0.0600586f, -0.328613f, 0.0336914f, -0.328125f, 0.469727f,
+-0.675781f, 0.469727f, -0.662109f, 0.381348f, -0.639648f, 0.327881f, -0.604248f,
+0.274414f, -0.568848f, 0.243408f, -0.518311f, 0.212402f, -0.467773f, 0.195312f, -0.393066f,
+0.216797f, -0.407715f, 0.230957f, -0.412109f, 0.262695f, -0.421875f, 0.294922f, -0.421875f,
+0.369141f, -0.421875f, 0.418701f, -0.36792f, 0.468262f, -0.313965f, 0.468262f, -0.220703f,
+0.468262f, -0.155273f, 0.441406f, -0.100586f, 0.414551f, -0.0458984f, 0.365234f,
+-0.0161133f, 0.315918f, 0.0136719f, 0.259766f, 0.0136719f, 0.19873f, 0.0136719f,
+0.146973f, -0.0197754f, 0.0952148f, -0.0532227f, 0.0661621f, -0.117676f, 0.0371094f,
+-0.182129f, 0.0371094f, -0.257812f, 0.0371094f, -0.369141f, 0.0905762f, -0.465088f,
+0.144043f, -0.561035f, 0.242432f, -0.61792f, 0.34082f, -0.674805f, 0.469727f, -0.675781f,
+0.188965f, -0.353516f, 0.185059f, -0.286133f, 0.185059f, -0.254883f, 0.185059f, -0.1875f,
+0.197998f, -0.124512f, 0.210938f, -0.0615234f, 0.233398f, -0.0361328f, 0.249512f,
+-0.0180664f, 0.271484f, -0.0180664f, 0.293945f, -0.0180664f, 0.311523f, -0.0441895f,
+0.329102f, -0.0703125f, 0.329102f, -0.150391f, 0.329102f, -0.285156f, 0.296387f,
+-0.336426f, 0.275391f, -0.369629f, 0.239746f, -0.369629f, 0.220215f, -0.369629f,
+0.188965f, -0.353516f, 0.177246f, 0.0136719f, 0.357422f, -0.532715f, 0.220215f, -0.532715f,
+0.139648f, -0.532715f, 0.0991211f, -0.511719f, 0.0708008f, -0.49707f, 0.0522461f,
+-0.456543f, 0.0336914f, -0.456543f, 0.081543f, -0.662109f, 0.476074f, -0.662109f,
+0.253906f, 0.0136719f, 0.34082f, -0.374023f, 0.410645f, -0.322754f, 0.437744f, -0.278564f,
+0.464844f, -0.234375f, 0.464844f, -0.177246f, 0.464844f, -0.097168f, 0.404541f, -0.041748f,
+0.344238f, 0.0136719f, 0.240723f, 0.0136719f, 0.142578f, 0.0136719f, 0.0888672f,
+-0.034668f, 0.0351562f, -0.0830078f, 0.0351562f, -0.152832f, 0.0351562f, -0.206055f,
+0.0661621f, -0.246094f, 0.097168f, -0.286133f, 0.169434f, -0.319336f, 0.0908203f,
+-0.379395f, 0.0686035f, -0.41748f, 0.0463867f, -0.455566f, 0.0463867f, -0.505859f,
+0.0463867f, -0.572266f, 0.102783f, -0.622803f, 0.15918f, -0.67334f, 0.257324f, -0.67334f,
+0.352051f, -0.67334f, 0.403076f, -0.628662f, 0.454102f, -0.583984f, 0.454102f, -0.521484f,
+0.454102f, -0.474609f, 0.426514f, -0.438721f, 0.398926f, -0.402832f, 0.34082f, -0.374023f,
+0.303711f, -0.398926f, 0.321777f, -0.42334f, 0.330566f, -0.453613f, 0.339355f, -0.483887f,
+0.339355f, -0.52002f, 0.339355f, -0.583496f, 0.312012f, -0.617188f, 0.291504f, -0.643066f,
+0.255371f, -0.643066f, 0.222656f, -0.643066f, 0.199707f, -0.619385f, 0.176758f, -0.595703f,
+0.176758f, -0.560547f, 0.176758f, -0.524902f, 0.202393f, -0.486572f, 0.228027f, -0.448242f,
+0.303711f, -0.398926f, 0.206055f, -0.295898f, 0.190918f, -0.282227f, 0.18457f, -0.270996f,
+0.174805f, -0.253906f, 0.166992f, -0.221191f, 0.15918f, -0.188477f, 0.15918f, -0.152832f,
+0.15918f, -0.106934f, 0.170898f, -0.0759277f, 0.182617f, -0.0449219f, 0.204346f,
+-0.03125f, 0.226074f, -0.0175781f, 0.249023f, -0.0175781f, 0.284668f, -0.0175781f,
+0.309082f, -0.0437012f, 0.333496f, -0.0698242f, 0.333496f, -0.115234f, 0.333496f,
+-0.209961f, 0.206055f, -0.295898f, 0.0307617f, 0.0136719f, 0.0307617f, 0, 0.111816f,
+-0.0185547f, 0.168213f, -0.0546875f, 0.224609f, -0.0908203f, 0.257568f, -0.144043f,
+0.290527f, -0.197266f, 0.303711f, -0.266602f, 0.273438f, -0.250977f, 0.252197f, -0.244873f,
+0.230957f, -0.23877f, 0.20752f, -0.23877f, 0.132324f, -0.23877f, 0.0822754f, -0.292969f,
+0.0322266f, -0.347168f, 0.0322266f, -0.441406f, 0.0322266f, -0.506836f, 0.0593262f,
+-0.561279f, 0.0864258f, -0.615723f, 0.136719f, -0.645752f, 0.187012f, -0.675781f,
+0.241211f, -0.675781f, 0.299316f, -0.675781f, 0.351074f, -0.642578f, 0.402832f, -0.609375f,
+0.433594f, -0.546387f, 0.464355f, -0.483398f, 0.464355f, -0.402832f, 0.464355f, -0.29834f,
+0.414307f, -0.202637f, 0.364258f, -0.106934f, 0.265137f, -0.0490723f, 0.166016f,
+0.00878906f, 0.0307617f, 0.0136719f, 0.311035f, -0.307617f, 0.315918f, -0.362305f,
+0.315918f, -0.403809f, 0.315918f, -0.492676f, 0.29541f, -0.569336f, 0.283691f, -0.611816f,
+0.260742f, -0.631836f, 0.248535f, -0.642578f, 0.229004f, -0.642578f, 0.20459f, -0.642578f,
+0.190918f, -0.621582f, 0.171875f, -0.592773f, 0.171875f, -0.511719f, 0.171875f, -0.376465f,
+0.204102f, -0.325195f, 0.225098f, -0.291992f, 0.260742f, -0.291992f, 0.279785f, -0.291992f,
+0.311035f, -0.307617f, 0.166992f, -0.469727f, 0.200684f, -0.469727f, 0.224365f, -0.446045f,
+0.248047f, -0.422363f, 0.248047f, -0.388672f, 0.248047f, -0.35498f, 0.224365f, -0.331299f,
+0.200684f, -0.307617f, 0.166992f, -0.307617f, 0.133301f, -0.307617f, 0.109619f, -0.331299f,
+0.0859375f, -0.35498f, 0.0859375f, -0.388672f, 0.0859375f, -0.422363f, 0.109619f,
+-0.446045f, 0.133301f, -0.469727f, 0.166992f, -0.469727f, 0.166504f, -0.150391f,
+0.200684f, -0.150391f, 0.224365f, -0.126465f, 0.248047f, -0.102539f, 0.248047f, -0.0688477f,
+0.248047f, -0.0351562f, 0.224121f, -0.0114746f, 0.200195f, 0.012207f, 0.166504f,
+0.012207f, 0.132812f, 0.012207f, 0.109131f, -0.0114746f, 0.0854492f, -0.0351562f,
+0.0854492f, -0.0688477f, 0.0854492f, -0.102539f, 0.109131f, -0.126465f, 0.132812f,
+-0.150391f, 0.166504f, -0.150391f, 0.166504f, -0.469727f, 0.200195f, -0.469727f,
+0.223633f, -0.446289f, 0.24707f, -0.422852f, 0.24707f, -0.38916f, 0.24707f, -0.355469f,
+0.223389f, -0.331787f, 0.199707f, -0.308105f, 0.166504f, -0.308105f, 0.132812f, -0.308105f,
+0.109131f, -0.331787f, 0.0854492f, -0.355469f, 0.0854492f, -0.38916f, 0.0854492f,
+-0.422852f, 0.108887f, -0.446289f, 0.132324f, -0.469727f, 0.166504f, -0.469727f,
+0.0917969f, 0.175293f, 0.0917969f, 0.153809f, 0.148438f, 0.129395f, 0.174072f, 0.0905762f,
+0.199707f, 0.0517578f, 0.199707f, 0.0112305f, 0.199707f, 0.00292969f, 0.196289f,
+-0.00146484f, 0.192871f, -0.00537109f, 0.189453f, -0.00537109f, 0.186523f, -0.00537109f,
+0.180664f, -0.00195312f, 0.166504f, 0.00634766f, 0.145508f, 0.00634766f, 0.116699f,
+0.00634766f, 0.095459f, -0.0161133f, 0.0742188f, -0.0385742f, 0.0742188f, -0.0688477f,
+0.0742188f, -0.101074f, 0.0986328f, -0.125488f, 0.123047f, -0.149902f, 0.157715f,
+-0.149902f, 0.199707f, -0.149902f, 0.229492f, -0.117432f, 0.259277f, -0.0849609f,
+0.259277f, -0.0283203f, 0.259277f, 0.0415039f, 0.217041f, 0.0957031f, 0.174805f,
+0.149902f, 0.0917969f, 0.175293f, 0.553223f, -0.090332f, 0.0200195f, -0.308105f,
+0.0200195f, -0.347656f, 0.553223f, -0.567871f, 0.553223f, -0.500488f, 0.140625f,
+-0.328125f, 0.553223f, -0.158691f, 0.0195312f, -0.441406f, 0.553711f, -0.441406f,
+0.553711f, -0.37793f, 0.0195312f, -0.37793f, 0.0195312f, -0.281738f, 0.553711f, -0.281738f,
+0.553711f, -0.218262f, 0.0195312f, -0.218262f, 0.0200195f, -0.567871f, 0.553223f,
+-0.350586f, 0.553223f, -0.310547f, 0.0200195f, -0.090332f, 0.0200195f, -0.158203f,
+0.432617f, -0.330078f, 0.0200195f, -0.499512f, 0.237305f, -0.21582f, 0.217285f, -0.21582f,
+0.216309f, -0.27002f, 0.222412f, -0.296875f, 0.228516f, -0.32373f, 0.25415f, -0.37085f,
+0.279785f, -0.417969f, 0.287842f, -0.446533f, 0.295898f, -0.475098f, 0.295898f, -0.51709f,
+0.295898f, -0.582031f, 0.270508f, -0.612793f, 0.245117f, -0.643555f, 0.210449f, -0.643555f,
+0.184082f, -0.643555f, 0.166016f, -0.629395f, 0.152344f, -0.618652f, 0.152344f, -0.606934f,
+0.152344f, -0.599121f, 0.161621f, -0.58252f, 0.182617f, -0.544922f, 0.182617f, -0.518555f,
+0.182617f, -0.494629f, 0.16626f, -0.478516f, 0.149902f, -0.462402f, 0.125488f, -0.462402f,
+0.0981445f, -0.462402f, 0.0795898f, -0.481689f, 0.0610352f, -0.500977f, 0.0610352f,
+-0.532715f, 0.0610352f, -0.590332f, 0.11084f, -0.633789f, 0.160645f, -0.677246f,
+0.25f, -0.677246f, 0.344727f, -0.677246f, 0.394287f, -0.63208f, 0.443848f, -0.586914f,
+0.443848f, -0.522949f, 0.443848f, -0.476562f, 0.418457f, -0.437256f, 0.393066f, -0.397949f,
+0.320312f, -0.350098f, 0.271484f, -0.317871f, 0.256104f, -0.292725f, 0.240723f, -0.267578f,
+0.237305f, -0.21582f, 0.231934f, -0.144531f, 0.264648f, -0.144531f, 0.287598f, -0.121582f,
+0.310547f, -0.0986328f, 0.310547f, -0.065918f, 0.310547f, -0.0332031f, 0.287598f,
+-0.0100098f, 0.264648f, 0.0131836f, 0.231934f, 0.0131836f, 0.199219f, 0.0131836f,
+0.17627f, -0.0100098f, 0.15332f, -0.0332031f, 0.15332f, -0.065918f, 0.15332f, -0.0986328f,
+0.17627f, -0.121582f, 0.199219f, -0.144531f, 0.231934f, -0.144531f, 0.575684f, -0.45166f,
+0.694824f, -0.456543f, 0.605469f, -0.149902f, 0.590332f, -0.0991211f, 0.590332f,
+-0.0737305f, 0.590332f, -0.0581055f, 0.601807f, -0.0466309f, 0.613281f, -0.0351562f,
+0.629883f, -0.0351562f, 0.663574f, -0.0351562f, 0.717041f, -0.0739746f, 0.770508f,
+-0.112793f, 0.80542f, -0.184814f, 0.840332f, -0.256836f, 0.840332f, -0.338379f, 0.840332f,
+-0.473145f, 0.753662f, -0.559814f, 0.666992f, -0.646484f, 0.527832f, -0.646484f,
+0.407715f, -0.646484f, 0.30957f, -0.590088f, 0.211426f, -0.533691f, 0.153809f, -0.42627f,
+0.0961914f, -0.318848f, 0.0961914f, -0.195801f, 0.0961914f, -0.0268555f, 0.203857f,
+0.0808105f, 0.311523f, 0.188477f, 0.478027f, 0.188477f, 0.615234f, 0.188477f, 0.724121f,
+0.114746f, 0.833008f, 0.0410156f, 0.878418f, -0.0805664f, 0.908203f, -0.0805664f,
+0.849609f, 0.0629883f, 0.737549f, 0.139404f, 0.625488f, 0.21582f, 0.477051f, 0.21582f,
+0.289062f, 0.21582f, 0.166992f, 0.0944824f, 0.0449219f, -0.0268555f, 0.0449219f,
+-0.212891f, 0.0449219f, -0.34082f, 0.105469f, -0.449951f, 0.166016f, -0.559082f,
+0.275391f, -0.618164f, 0.384766f, -0.677246f, 0.517578f, -0.677246f, 0.625488f, -0.677246f,
+0.706299f, -0.634033f, 0.787109f, -0.59082f, 0.827637f, -0.512695f, 0.868164f, -0.43457f,
+0.868164f, -0.347656f, 0.868164f, -0.246582f, 0.824463f, -0.163086f, 0.780762f, -0.0795898f,
+0.715576f, -0.0397949f, 0.650391f, 0, 0.575195f, 0, 0.526855f, 0, 0.501465f, -0.0239258f,
+0.476074f, -0.0478516f, 0.476074f, -0.0854492f, 0.476074f, -0.111816f, 0.487793f,
+-0.154297f, 0.447266f, -0.0869141f, 0.424805f, -0.0610352f, 0.394043f, -0.0263672f,
+0.36377f, -0.0102539f, 0.344238f, 0, 0.319336f, 0, 0.284668f, 0, 0.260986f, -0.0275879f,
+0.237305f, -0.0551758f, 0.237305f, -0.108398f, 0.237305f, -0.163086f, 0.253174f,
+-0.215576f, 0.269043f, -0.268066f, 0.296387f, -0.314209f, 0.32373f, -0.360352f, 0.359619f,
+-0.396973f, 0.395508f, -0.433594f, 0.44043f, -0.45752f, 0.463379f, -0.470215f, 0.489746f,
+-0.470215f, 0.51709f, -0.470215f, 0.534912f, -0.453125f, 0.552734f, -0.436035f, 0.559082f,
+-0.393555f, 0.501953f, -0.435059f, 0.483398f, -0.435059f, 0.465332f, -0.414551f,
+0.440918f, -0.386719f, 0.413086f, -0.321777f, 0.363281f, -0.205078f, 0.363281f, -0.134277f,
+0.363281f, -0.112793f, 0.372314f, -0.101074f, 0.381348f, -0.0893555f, 0.39209f, -0.0893555f,
+0.401367f, -0.0893555f, 0.418945f, -0.103027f, 0.443848f, -0.12207f, 0.472168f, -0.16748f,
+0.500488f, -0.212891f, 0.518555f, -0.268311f, 0.536621f, -0.32373f, 0.536621f, -0.370605f,
+0.536621f, -0.404297f, 0.523926f, -0.421875f, 0.514648f, -0.435059f, 0.501953f, -0.435059f,
+0.416016f, -0.188477f, 0.182129f, -0.188477f, 0.154297f, -0.124023f, 0.140625f, -0.0917969f,
+0.140625f, -0.0708008f, 0.140625f, -0.0429688f, 0.163086f, -0.0297852f, 0.17627f,
+-0.0219727f, 0.228027f, -0.0180664f, 0.228027f, 0, 0.0078125f, 0, 0.0078125f, -0.0180664f,
+0.043457f, -0.0234375f, 0.0664062f, -0.0476074f, 0.0893555f, -0.0717773f, 0.123047f,
+-0.147461f, 0.359863f, -0.675781f, 0.369141f, -0.675781f, 0.60791f, -0.132812f, 0.64209f,
+-0.0556641f, 0.664062f, -0.0356445f, 0.680664f, -0.0205078f, 0.710938f, -0.0180664f,
+0.710938f, 0, 0.390625f, 0, 0.390625f, -0.0180664f, 0.403809f, -0.0180664f, 0.442383f,
+-0.0180664f, 0.458008f, -0.0288086f, 0.46875f, -0.0366211f, 0.46875f, -0.0512695f,
+0.46875f, -0.0600586f, 0.46582f, -0.0693359f, 0.464844f, -0.0737305f, 0.451172f,
+-0.105957f, 0.399414f, -0.224609f, 0.300781f, -0.452637f, 0.199219f, -0.224609f,
+0.444824f, -0.351074f, 0.539062f, -0.329102f, 0.577148f, -0.297852f, 0.631836f, -0.253418f,
+0.631836f, -0.182617f, 0.631836f, -0.10791f, 0.571777f, -0.059082f, 0.498047f, 0,
+0.357422f, 0, 0.0209961f, 0, 0.0209961f, -0.0180664f, 0.0668945f, -0.0180664f, 0.083252f,
+-0.0266113f, 0.0996094f, -0.0351562f, 0.106201f, -0.0488281f, 0.112793f, -0.0625f,
+0.112793f, -0.116211f, 0.112793f, -0.545898f, 0.112793f, -0.599609f, 0.106201f, -0.613525f,
+0.0996094f, -0.627441f, 0.0830078f, -0.635742f, 0.0664062f, -0.644043f, 0.0209961f,
+-0.644043f, 0.0209961f, -0.662109f, 0.338379f, -0.662109f, 0.452148f, -0.662109f,
+0.499512f, -0.641846f, 0.546875f, -0.621582f, 0.574219f, -0.581299f, 0.601562f, -0.541016f,
+0.601562f, -0.495605f, 0.601562f, -0.447754f, 0.566895f, -0.4104f, 0.532227f, -0.373047f,
+0.444824f, -0.351074f, 0.26709f, -0.364258f, 0.336426f, -0.364258f, 0.369385f, -0.379883f,
+0.402344f, -0.395508f, 0.419922f, -0.423828f, 0.4375f, -0.452148f, 0.4375f, -0.496094f,
+0.4375f, -0.540039f, 0.420166f, -0.568115f, 0.402832f, -0.596191f, 0.370605f, -0.61084f,
+0.338379f, -0.625488f, 0.26709f, -0.625f, 0.26709f, -0.326172f, 0.26709f, -0.11377f,
+0.266602f, -0.0893555f, 0.266602f, -0.0629883f, 0.280029f, -0.0495605f, 0.293457f,
+-0.0361328f, 0.319824f, -0.0361328f, 0.358887f, -0.0361328f, 0.391846f, -0.0534668f,
+0.424805f, -0.0708008f, 0.442383f, -0.10376f, 0.459961f, -0.136719f, 0.459961f, -0.177246f,
+0.459961f, -0.223633f, 0.438477f, -0.260498f, 0.416992f, -0.297363f, 0.379395f, -0.312012f,
+0.341797f, -0.32666f, 0.26709f, -0.326172f, 0.66748f, -0.677246f, 0.66748f, -0.447754f,
+0.648438f, -0.447754f, 0.626953f, -0.537598f, 0.568359f, -0.585449f, 0.509766f, -0.633301f,
+0.435547f, -0.633301f, 0.373535f, -0.633301f, 0.321777f, -0.597656f, 0.27002f, -0.562012f,
+0.246094f, -0.504395f, 0.215332f, -0.430664f, 0.215332f, -0.340332f, 0.215332f, -0.251465f,
+0.237793f, -0.178467f, 0.260254f, -0.105469f, 0.308105f, -0.0681152f, 0.355957f,
+-0.0307617f, 0.432129f, -0.0307617f, 0.494629f, -0.0307617f, 0.546631f, -0.0581055f,
+0.598633f, -0.0854492f, 0.65625f, -0.152344f, 0.65625f, -0.0952148f, 0.600586f, -0.0371094f,
+0.540283f, -0.0109863f, 0.47998f, 0.0151367f, 0.399414f, 0.0151367f, 0.293457f, 0.0151367f,
+0.211182f, -0.0273438f, 0.128906f, -0.0698242f, 0.0842285f, -0.149414f, 0.0395508f,
+-0.229004f, 0.0395508f, -0.318848f, 0.0395508f, -0.413574f, 0.0891113f, -0.498535f,
+0.138672f, -0.583496f, 0.2229f, -0.630371f, 0.307129f, -0.677246f, 0.401855f, -0.677246f,
+0.47168f, -0.677246f, 0.549316f, -0.646973f, 0.594238f, -0.629395f, 0.606445f, -0.629395f,
+0.62207f, -0.629395f, 0.633545f, -0.640869f, 0.64502f, -0.652344f, 0.648438f, -0.677246f,
+0.0131836f, 0, 0.0131836f, -0.0180664f, 0.0351562f, -0.0180664f, 0.0639648f, -0.0180664f,
+0.0793457f, -0.0270996f, 0.0947266f, -0.0361328f, 0.102051f, -0.0517578f, 0.106445f,
+-0.0620117f, 0.106445f, -0.113281f, 0.106445f, -0.548828f, 0.106445f, -0.599609f,
+0.101074f, -0.612305f, 0.0957031f, -0.625f, 0.0793457f, -0.634521f, 0.0629883f, -0.644043f,
+0.0351562f, -0.644043f, 0.0131836f, -0.644043f, 0.0131836f, -0.662109f, 0.30957f,
+-0.662109f, 0.428223f, -0.662109f, 0.500488f, -0.629883f, 0.588867f, -0.590332f,
+0.634521f, -0.510254f, 0.680176f, -0.430176f, 0.680176f, -0.329102f, 0.680176f, -0.259277f,
+0.657715f, -0.200439f, 0.635254f, -0.141602f, 0.599609f, -0.103271f, 0.563965f, -0.0649414f,
+0.517334f, -0.041748f, 0.470703f, -0.0185547f, 0.40332f, -0.00585938f, 0.373535f,
+0, 0.30957f, 0, 0.265625f, -0.624512f, 0.265625f, -0.10791f, 0.265625f, -0.0668945f,
+0.269531f, -0.0576172f, 0.273438f, -0.0483398f, 0.282715f, -0.043457f, 0.295898f,
+-0.0361328f, 0.320801f, -0.0361328f, 0.402344f, -0.0361328f, 0.445312f, -0.0917969f,
+0.503906f, -0.166992f, 0.503906f, -0.325195f, 0.503906f, -0.452637f, 0.463867f, -0.528809f,
+0.432129f, -0.588379f, 0.382324f, -0.609863f, 0.347168f, -0.625f, 0.265625f, -0.624512f,
+0.272461f, -0.624023f, 0.272461f, -0.354492f, 0.285645f, -0.354492f, 0.348633f, -0.354492f,
+0.376953f, -0.394043f, 0.405273f, -0.433594f, 0.413086f, -0.510742f, 0.431641f, -0.510742f,
+0.431641f, -0.164062f, 0.413086f, -0.164062f, 0.407227f, -0.220703f, 0.388428f, -0.256836f,
+0.369629f, -0.292969f, 0.344727f, -0.30542f, 0.319824f, -0.317871f, 0.272461f, -0.317871f,
+0.272461f, -0.131348f, 0.272461f, -0.0766602f, 0.2771f, -0.0644531f, 0.281738f, -0.0522461f,
+0.294434f, -0.0444336f, 0.307129f, -0.0366211f, 0.335449f, -0.0366211f, 0.375f, -0.0366211f,
+0.467773f, -0.0366211f, 0.523682f, -0.0795898f, 0.57959f, -0.122559f, 0.604004f,
+-0.210449f, 0.62207f, -0.210449f, 0.592285f, 0, 0.0200195f, 0, 0.0200195f, -0.0180664f,
+0.0419922f, -0.0180664f, 0.0708008f, -0.0180664f, 0.0883789f, -0.0283203f, 0.101074f,
+-0.0351562f, 0.10791f, -0.0517578f, 0.113281f, -0.0634766f, 0.113281f, -0.113281f,
+0.113281f, -0.548828f, 0.113281f, -0.59375f, 0.11084f, -0.604004f, 0.105957f, -0.621094f,
+0.0927734f, -0.630371f, 0.0742188f, -0.644043f, 0.0419922f, -0.644043f, 0.0200195f,
+-0.644043f, 0.0200195f, -0.662109f, 0.574219f, -0.662109f, 0.574219f, -0.466309f,
+0.555664f, -0.466309f, 0.541504f, -0.538086f, 0.515869f, -0.569336f, 0.490234f, -0.600586f,
+0.443359f, -0.615234f, 0.416016f, -0.624023f, 0.34082f, -0.624023f, 0.274902f, -0.624023f,
+0.274902f, -0.352051f, 0.293945f, -0.352051f, 0.337891f, -0.352051f, 0.365723f, -0.365234f,
+0.393555f, -0.378418f, 0.412842f, -0.409668f, 0.432129f, -0.440918f, 0.437988f, -0.494141f,
+0.455078f, -0.494141f, 0.455078f, -0.161621f, 0.437988f, -0.161621f, 0.428711f, -0.255859f,
+0.387451f, -0.285889f, 0.346191f, -0.315918f, 0.293945f, -0.315918f, 0.274902f, -0.315918f,
+0.274902f, -0.113281f, 0.274902f, -0.0625f, 0.280518f, -0.0498047f, 0.286133f, -0.0371094f,
+0.30249f, -0.0275879f, 0.318848f, -0.0180664f, 0.34668f, -0.0180664f, 0.368652f,
+-0.0180664f, 0.368652f, 0, 0.0224609f, 0, 0.0224609f, -0.0180664f, 0.0444336f, -0.0180664f,
+0.0732422f, -0.0180664f, 0.0908203f, -0.0283203f, 0.103516f, -0.0351562f, 0.110352f,
+-0.0517578f, 0.115723f, -0.0634766f, 0.115723f, -0.113281f, 0.115723f, -0.548828f,
+0.115723f, -0.599609f, 0.110352f, -0.612305f, 0.10498f, -0.625f, 0.088623f, -0.634521f,
+0.0722656f, -0.644043f, 0.0444336f, -0.644043f, 0.0224609f, -0.644043f, 0.0224609f,
+-0.662109f, 0.581055f, -0.662109f, 0.581055f, -0.472168f, 0.561035f, -0.472168f,
+0.554199f, -0.539062f, 0.526123f, -0.571289f, 0.498047f, -0.603516f, 0.444824f, -0.616699f,
+0.415527f, -0.624023f, 0.336426f, -0.624023f, 0.689941f, -0.677246f, 0.689941f, -0.443848f,
+0.671875f, -0.443848f, 0.63916f, -0.539551f, 0.57373f, -0.589355f, 0.508301f, -0.63916f,
+0.430664f, -0.63916f, 0.356445f, -0.63916f, 0.307129f, -0.597412f, 0.257812f, -0.555664f,
+0.237305f, -0.480957f, 0.216797f, -0.40625f, 0.216797f, -0.327637f, 0.216797f, -0.232422f,
+0.239258f, -0.160645f, 0.261719f, -0.0888672f, 0.311768f, -0.0551758f, 0.361816f,
+-0.0214844f, 0.430664f, -0.0214844f, 0.45459f, -0.0214844f, 0.479736f, -0.0266113f,
+0.504883f, -0.0317383f, 0.53125f, -0.0415039f, 0.53125f, -0.179199f, 0.53125f, -0.218262f,
+0.525879f, -0.229736f, 0.520508f, -0.241211f, 0.503662f, -0.250488f, 0.486816f, -0.259766f,
+0.462891f, -0.259766f, 0.445801f, -0.259766f, 0.445801f, -0.277832f, 0.767578f, -0.277832f,
+0.767578f, -0.259766f, 0.730957f, -0.257324f, 0.716553f, -0.249756f, 0.702148f, -0.242188f,
+0.694336f, -0.224609f, 0.689941f, -0.215332f, 0.689941f, -0.179199f, 0.689941f, -0.0415039f,
+0.626465f, -0.0131836f, 0.557861f, 0.0012207f, 0.489258f, 0.015625f, 0.415527f, 0.015625f,
+0.321289f, 0.015625f, 0.259033f, -0.0100098f, 0.196777f, -0.0356445f, 0.14917f, -0.0773926f,
+0.101562f, -0.119141f, 0.074707f, -0.171387f, 0.0405273f, -0.23877f, 0.0405273f,
+-0.322266f, 0.0405273f, -0.47168f, 0.145508f, -0.574707f, 0.250488f, -0.677734f,
+0.409668f, -0.677734f, 0.458984f, -0.677734f, 0.498535f, -0.669922f, 0.52002f, -0.666016f,
+0.568115f, -0.647705f, 0.616211f, -0.629395f, 0.625f, -0.629395f, 0.638672f, -0.629395f,
+0.650391f, -0.639404f, 0.662109f, -0.649414f, 0.671875f, -0.677246f, 0.273438f, -0.318359f,
+0.273438f, -0.113281f, 0.273438f, -0.0625f, 0.279053f, -0.0498047f, 0.284668f, -0.0371094f,
+0.301025f, -0.0275879f, 0.317383f, -0.0180664f, 0.345215f, -0.0180664f, 0.367188f,
+-0.0180664f, 0.367188f, 0, 0.0209961f, 0, 0.0209961f, -0.0180664f, 0.0429688f, -0.0180664f,
+0.0717773f, -0.0180664f, 0.0893555f, -0.0283203f, 0.102051f, -0.0351562f, 0.108887f,
+-0.0517578f, 0.114258f, -0.0634766f, 0.114258f, -0.113281f, 0.114258f, -0.548828f,
+0.114258f, -0.599609f, 0.108887f, -0.612305f, 0.103516f, -0.625f, 0.0871582f, -0.634521f,
+0.0708008f, -0.644043f, 0.0429688f, -0.644043f, 0.0209961f, -0.644043f, 0.0209961f,
+-0.662109f, 0.367188f, -0.662109f, 0.367188f, -0.644043f, 0.345215f, -0.644043f,
+0.316406f, -0.644043f, 0.298828f, -0.633789f, 0.286133f, -0.626953f, 0.278809f, -0.610352f,
+0.273438f, -0.598633f, 0.273438f, -0.548828f, 0.273438f, -0.361328f, 0.507324f, -0.361328f,
+0.507324f, -0.548828f, 0.507324f, -0.599609f, 0.501953f, -0.612305f, 0.496582f, -0.625f,
+0.47998f, -0.634521f, 0.463379f, -0.644043f, 0.435547f, -0.644043f, 0.414062f, -0.644043f,
+0.414062f, -0.662109f, 0.759766f, -0.662109f, 0.759766f, -0.644043f, 0.738281f, -0.644043f,
+0.708984f, -0.644043f, 0.691895f, -0.633789f, 0.679199f, -0.626953f, 0.671875f, -0.610352f,
+0.666504f, -0.598633f, 0.666504f, -0.548828f, 0.666504f, -0.113281f, 0.666504f, -0.0625f,
+0.671875f, -0.0498047f, 0.677246f, -0.0371094f, 0.693848f, -0.0275879f, 0.710449f,
+-0.0180664f, 0.738281f, -0.0180664f, 0.759766f, -0.0180664f, 0.759766f, 0, 0.414062f,
+0, 0.414062f, -0.0180664f, 0.435547f, -0.0180664f, 0.464844f, -0.0180664f, 0.481934f,
+-0.0283203f, 0.494629f, -0.0351562f, 0.501953f, -0.0517578f, 0.507324f, -0.0634766f,
+0.507324f, -0.113281f, 0.507324f, -0.318359f, 0.366211f, -0.0180664f, 0.366211f,
+0, 0.0200195f, 0, 0.0200195f, -0.0180664f, 0.0419922f, -0.0180664f, 0.0708008f, -0.0180664f,
+0.0883789f, -0.0283203f, 0.101074f, -0.0351562f, 0.10791f, -0.0517578f, 0.113281f,
+-0.0634766f, 0.113281f, -0.113281f, 0.113281f, -0.548828f, 0.113281f, -0.599609f,
+0.10791f, -0.612305f, 0.102539f, -0.625f, 0.0861816f, -0.634521f, 0.0698242f, -0.644043f,
+0.0419922f, -0.644043f, 0.0200195f, -0.644043f, 0.0200195f, -0.662109f, 0.366211f,
+-0.662109f, 0.366211f, -0.644043f, 0.344238f, -0.644043f, 0.31543f, -0.644043f, 0.297852f,
+-0.633789f, 0.285156f, -0.626953f, 0.277832f, -0.610352f, 0.272461f, -0.598633f,
+0.272461f, -0.548828f, 0.272461f, -0.113281f, 0.272461f, -0.0625f, 0.278076f, -0.0498047f,
+0.283691f, -0.0371094f, 0.300049f, -0.0275879f, 0.316406f, -0.0180664f, 0.344238f,
+-0.0180664f, 0.14209f, -0.644043f, 0.14209f, -0.662109f, 0.494141f, -0.662109f, 0.494141f,
+-0.644043f, 0.472656f, -0.644043f, 0.443359f, -0.644043f, 0.425781f, -0.633789f,
+0.413574f, -0.626953f, 0.40625f, -0.610352f, 0.400879f, -0.598633f, 0.400879f, -0.548828f,
+0.400879f, -0.224609f, 0.400879f, -0.129395f, 0.381836f, -0.0861816f, 0.362793f,
+-0.0429688f, 0.314209f, -0.013916f, 0.265625f, 0.0151367f, 0.197266f, 0.0151367f,
+0.11377f, 0.0151367f, 0.0622559f, -0.0288086f, 0.0107422f, -0.0727539f, 0.0107422f,
+-0.125977f, 0.0107422f, -0.160156f, 0.0317383f, -0.181396f, 0.0527344f, -0.202637f,
+0.0830078f, -0.202637f, 0.112793f, -0.202637f, 0.133057f, -0.183594f, 0.15332f, -0.164551f,
+0.15332f, -0.136719f, 0.15332f, -0.123047f, 0.149902f, -0.112793f, 0.147949f, -0.10791f,
+0.134521f, -0.0881348f, 0.121094f, -0.0683594f, 0.121094f, -0.0600586f, 0.121094f,
+-0.0473633f, 0.133789f, -0.0380859f, 0.152344f, -0.0244141f, 0.182129f, -0.0244141f,
+0.203125f, -0.0244141f, 0.216797f, -0.0351562f, 0.230469f, -0.0458984f, 0.236084f,
+-0.0686035f, 0.241699f, -0.0913086f, 0.241699f, -0.194824f, 0.241699f, -0.548828f,
+0.241699f, -0.599609f, 0.236084f, -0.612305f, 0.230469f, -0.625f, 0.214111f, -0.634521f,
+0.197754f, -0.644043f, 0.169922f, -0.644043f, 0.416504f, -0.408691f, 0.649414f, -0.117188f,
+0.69873f, -0.0556641f, 0.734375f, -0.0336914f, 0.760254f, -0.0180664f, 0.789062f,
+-0.0180664f, 0.789062f, 0, 0.444336f, 0, 0.444336f, -0.0180664f, 0.477051f, -0.0209961f,
+0.486572f, -0.0283203f, 0.496094f, -0.0356445f, 0.496094f, -0.0463867f, 0.496094f,
+-0.0668945f, 0.451172f, -0.123535f, 0.299316f, -0.314453f, 0.274902f, -0.293945f,
+0.274902f, -0.113281f, 0.274902f, -0.0615234f, 0.280762f, -0.0488281f, 0.286621f,
+-0.0361328f, 0.303223f, -0.0270996f, 0.319824f, -0.0180664f, 0.356445f, -0.0180664f,
+0.356445f, 0, 0.0224609f, 0, 0.0224609f, -0.0180664f, 0.0444336f, -0.0180664f, 0.0732422f,
+-0.0180664f, 0.0908203f, -0.0283203f, 0.103516f, -0.0351562f, 0.110352f, -0.0517578f,
+0.115723f, -0.0634766f, 0.115723f, -0.113281f, 0.115723f, -0.548828f, 0.115723f,
+-0.599609f, 0.110352f, -0.612305f, 0.10498f, -0.625f, 0.088623f, -0.634521f, 0.0722656f,
+-0.644043f, 0.0444336f, -0.644043f, 0.0224609f, -0.644043f, 0.0224609f, -0.662109f,
+0.352051f, -0.662109f, 0.352051f, -0.644043f, 0.318359f, -0.644043f, 0.300781f, -0.634277f,
+0.288086f, -0.627441f, 0.280762f, -0.611328f, 0.274902f, -0.599121f, 0.274902f, -0.548828f,
+0.274902f, -0.342773f, 0.520508f, -0.541504f, 0.571777f, -0.583008f, 0.571777f, -0.60791f,
+0.571777f, -0.626465f, 0.550781f, -0.637207f, 0.540039f, -0.642578f, 0.497559f, -0.644043f,
+0.497559f, -0.662109f, 0.755859f, -0.662109f, 0.755859f, -0.644043f, 0.721191f, -0.641602f,
+0.701416f, -0.631592f, 0.681641f, -0.621582f, 0.610352f, -0.563965f, 0.631348f, -0.232422f,
+0.606445f, 0, 0.0185547f, 0, 0.0185547f, -0.0180664f, 0.0405273f, -0.0180664f, 0.0693359f,
+-0.0180664f, 0.0869141f, -0.0283203f, 0.0996094f, -0.0351562f, 0.106445f, -0.0517578f,
+0.111816f, -0.0634766f, 0.111816f, -0.113281f, 0.111816f, -0.548828f, 0.111816f,
+-0.599609f, 0.106445f, -0.612305f, 0.101074f, -0.625f, 0.0847168f, -0.634521f, 0.0683594f,
+-0.644043f, 0.0405273f, -0.644043f, 0.0185547f, -0.644043f, 0.0185547f, -0.662109f,
+0.371582f, -0.662109f, 0.371582f, -0.644043f, 0.342773f, -0.644043f, 0.313965f, -0.644043f,
+0.296387f, -0.633789f, 0.283691f, -0.626953f, 0.276367f, -0.610352f, 0.270996f, -0.598633f,
+0.270996f, -0.548828f, 0.270996f, -0.126953f, 0.270996f, -0.0761719f, 0.276855f,
+-0.0622559f, 0.282715f, -0.0483398f, 0.299805f, -0.0415039f, 0.312012f, -0.0371094f,
+0.358887f, -0.0371094f, 0.414062f, -0.0371094f, 0.466797f, -0.0371094f, 0.501953f,
+-0.0556641f, 0.537109f, -0.0742188f, 0.562744f, -0.114258f, 0.588379f, -0.154297f,
+0.611328f, -0.232422f, 0.476562f, -0.225586f, 0.65625f, -0.662109f, 0.925781f, -0.662109f,
+0.925781f, -0.644043f, 0.904297f, -0.644043f, 0.875f, -0.644043f, 0.857422f, -0.633789f,
+0.845215f, -0.626953f, 0.837891f, -0.61084f, 0.83252f, -0.599121f, 0.83252f, -0.549805f,
+0.83252f, -0.113281f, 0.83252f, -0.0625f, 0.837891f, -0.0498047f, 0.843262f, -0.0371094f,
+0.859863f, -0.0275879f, 0.876465f, -0.0180664f, 0.904297f, -0.0180664f, 0.925781f,
+-0.0180664f, 0.925781f, 0, 0.580078f, 0, 0.580078f, -0.0180664f, 0.601562f, -0.0180664f,
+0.630859f, -0.0180664f, 0.648438f, -0.0283203f, 0.660645f, -0.0351562f, 0.667969f,
+-0.0517578f, 0.67334f, -0.0634766f, 0.67334f, -0.113281f, 0.67334f, -0.604004f, 0.419434f,
+0, 0.407715f, 0, 0.149902f, -0.599609f, 0.149902f, -0.133301f, 0.149902f, -0.0844727f,
+0.152344f, -0.0732422f, 0.158691f, -0.0488281f, 0.179932f, -0.0334473f, 0.201172f,
+-0.0180664f, 0.246582f, -0.0180664f, 0.246582f, 0, 0.0200195f, 0, 0.0200195f, -0.0180664f,
+0.0268555f, -0.0180664f, 0.0488281f, -0.0175781f, 0.0678711f, -0.0251465f, 0.0869141f,
+-0.0327148f, 0.0966797f, -0.0454102f, 0.106445f, -0.0581055f, 0.111816f, -0.0810547f,
+0.112793f, -0.0864258f, 0.112793f, -0.130859f, 0.112793f, -0.549805f, 0.112793f,
+-0.600098f, 0.107422f, -0.612549f, 0.102051f, -0.625f, 0.0854492f, -0.634521f, 0.0688477f,
+-0.644043f, 0.0410156f, -0.644043f, 0.0200195f, -0.644043f, 0.0200195f, -0.662109f,
+0.290527f, -0.662109f, 0.249023f, -0.662109f, 0.575684f, -0.251465f, 0.575684f, -0.536133f,
+0.575684f, -0.595703f, 0.558594f, -0.616699f, 0.535156f, -0.64502f, 0.47998f, -0.644043f,
+0.47998f, -0.662109f, 0.69873f, -0.662109f, 0.69873f, -0.644043f, 0.656738f, -0.638672f,
+0.642334f, -0.630127f, 0.62793f, -0.621582f, 0.619873f, -0.602295f, 0.611816f, -0.583008f,
+0.611816f, -0.536133f, 0.611816f, 0.0151367f, 0.595215f, 0.0151367f, 0.147461f, -0.536133f,
+0.147461f, -0.115234f, 0.147461f, -0.0581055f, 0.173584f, -0.0380859f, 0.199707f,
+-0.0180664f, 0.233398f, -0.0180664f, 0.249023f, -0.0180664f, 0.249023f, 0, 0.0141602f,
+0, 0.0141602f, -0.0180664f, 0.0688477f, -0.0185547f, 0.090332f, -0.0405273f, 0.111816f,
+-0.0625f, 0.111816f, -0.115234f, 0.111816f, -0.58252f, 0.0976562f, -0.600098f, 0.0766602f,
+-0.626465f, 0.0605469f, -0.634766f, 0.0444336f, -0.643066f, 0.0141602f, -0.644043f,
+0.0141602f, -0.662109f, 0.38623f, -0.671387f, 0.544434f, -0.677246f, 0.643311f, -0.579102f,
+0.742188f, -0.480957f, 0.742188f, -0.333496f, 0.742188f, -0.20752f, 0.668457f, -0.111816f,
+0.570801f, 0.0151367f, 0.392578f, 0.0151367f, 0.213867f, 0.0151367f, 0.116211f, -0.105957f,
+0.0390625f, -0.20166f, 0.0390625f, -0.333008f, 0.0390625f, -0.480469f, 0.139404f,
+-0.578857f, 0.239746f, -0.677246f, 0.38623f, -0.671387f, 0.39209f, -0.640137f, 0.30127f,
+-0.640137f, 0.253906f, -0.547363f, 0.215332f, -0.471191f, 0.215332f, -0.328613f,
+0.215332f, -0.15918f, 0.274902f, -0.078125f, 0.316406f, -0.0214844f, 0.391113f, -0.0214844f,
+0.441406f, -0.0214844f, 0.475098f, -0.0458984f, 0.518066f, -0.0771484f, 0.541992f,
+-0.145752f, 0.565918f, -0.214355f, 0.565918f, -0.324707f, 0.565918f, -0.456055f,
+0.541504f, -0.52124f, 0.51709f, -0.586426f, 0.479248f, -0.613281f, 0.441406f, -0.640137f,
+0.39209f, -0.640137f, 0.27002f, -0.299805f, 0.27002f, -0.116211f, 0.27002f, -0.0625f,
+0.276611f, -0.048584f, 0.283203f, -0.034668f, 0.300049f, -0.0263672f, 0.316895f,
+-0.0180664f, 0.361816f, -0.0180664f, 0.361816f, 0, 0.0253906f, 0, 0.0253906f, -0.0180664f,
+0.0712891f, -0.0180664f, 0.0876465f, -0.0266113f, 0.104004f, -0.0351562f, 0.110596f,
+-0.0488281f, 0.117188f, -0.0625f, 0.117188f, -0.116211f, 0.117188f, -0.545898f, 0.117188f,
+-0.599609f, 0.110596f, -0.613525f, 0.104004f, -0.627441f, 0.0874023f, -0.635742f,
+0.0708008f, -0.644043f, 0.0253906f, -0.644043f, 0.0253906f, -0.662109f, 0.313965f,
+-0.662109f, 0.456543f, -0.662109f, 0.518555f, -0.611328f, 0.580566f, -0.560547f,
+0.580566f, -0.484375f, 0.580566f, -0.419922f, 0.540527f, -0.374023f, 0.500488f, -0.328125f,
+0.430176f, -0.311523f, 0.382812f, -0.299805f, 0.27002f, -0.299805f, 0.27002f, -0.624023f,
+0.27002f, -0.337891f, 0.286133f, -0.336914f, 0.294434f, -0.336914f, 0.354004f, -0.336914f,
+0.38623f, -0.372314f, 0.418457f, -0.407715f, 0.418457f, -0.481934f, 0.418457f, -0.555664f,
+0.38623f, -0.589844f, 0.354004f, -0.624023f, 0.290039f, -0.624023f, 0.478027f, 0.00585938f,
+0.500488f, 0.0708008f, 0.547852f, 0.103516f, 0.595215f, 0.13623f, 0.666504f, 0.13623f,
+0.686035f, 0.13623f, 0.708008f, 0.132324f, 0.708008f, 0.162109f, 0.634277f, 0.180664f,
+0.576172f, 0.180664f, 0.485352f, 0.180664f, 0.413818f, 0.13623f, 0.342285f, 0.0917969f,
+0.306152f, 0.00585938f, 0.186035f, -0.0195312f, 0.112549f, -0.111816f, 0.0390625f,
+-0.204102f, 0.0390625f, -0.332031f, 0.0390625f, -0.480469f, 0.138672f, -0.578857f,
+0.238281f, -0.677246f, 0.391602f, -0.677246f, 0.544434f, -0.677246f, 0.643555f, -0.578613f,
+0.742676f, -0.47998f, 0.742676f, -0.332031f, 0.742676f, -0.203125f, 0.665039f, -0.10791f,
+0.587402f, -0.0126953f, 0.478027f, 0.00585938f, 0.391113f, -0.640137f, 0.303223f,
+-0.640137f, 0.255371f, -0.548828f, 0.215332f, -0.472168f, 0.215332f, -0.330566f,
+0.215332f, -0.160645f, 0.275391f, -0.0786133f, 0.317383f, -0.0214844f, 0.391113f,
+-0.0214844f, 0.465332f, -0.0214844f, 0.506836f, -0.0776367f, 0.566895f, -0.158203f,
+0.566895f, -0.319824f, 0.566895f, -0.479004f, 0.529297f, -0.550293f, 0.482422f, -0.640137f,
+0.391113f, -0.640137f, 0.265625f, -0.301758f, 0.265625f, -0.116211f, 0.265625f, -0.0625f,
+0.272217f, -0.048584f, 0.278809f, -0.034668f, 0.29541f, -0.0263672f, 0.312012f, -0.0180664f,
+0.357422f, -0.0180664f, 0.357422f, 0, 0.0185547f, 0, 0.0185547f, -0.0180664f, 0.0644531f,
+-0.0180664f, 0.0808105f, -0.0266113f, 0.097168f, -0.0351562f, 0.10376f, -0.0488281f,
+0.110352f, -0.0625f, 0.110352f, -0.116211f, 0.110352f, -0.545898f, 0.110352f, -0.599609f,
+0.10376f, -0.613525f, 0.097168f, -0.627441f, 0.0805664f, -0.635742f, 0.0639648f,
+-0.644043f, 0.0185547f, -0.644043f, 0.0185547f, -0.662109f, 0.326172f, -0.662109f,
+0.446289f, -0.662109f, 0.501953f, -0.645508f, 0.557617f, -0.628906f, 0.592773f, -0.584229f,
+0.62793f, -0.539551f, 0.62793f, -0.479492f, 0.62793f, -0.40625f, 0.575195f, -0.358398f,
+0.541504f, -0.328125f, 0.480957f, -0.312988f, 0.640137f, -0.0888672f, 0.671387f,
+-0.0454102f, 0.68457f, -0.034668f, 0.70459f, -0.0195312f, 0.730957f, -0.0180664f,
+0.730957f, 0, 0.522461f, 0, 0.309082f, -0.301758f, 0.265625f, -0.626465f, 0.265625f,
+-0.336426f, 0.293457f, -0.336426f, 0.361328f, -0.336426f, 0.39502f, -0.348877f, 0.428711f,
+-0.361328f, 0.447998f, -0.393799f, 0.467285f, -0.42627f, 0.467285f, -0.478516f, 0.467285f,
+-0.554199f, 0.431885f, -0.590332f, 0.396484f, -0.626465f, 0.317871f, -0.626465f,
+0.469727f, -0.677246f, 0.475098f, -0.456543f, 0.455078f, -0.456543f, 0.440918f, -0.539551f,
+0.385498f, -0.590088f, 0.330078f, -0.640625f, 0.265625f, -0.640625f, 0.21582f, -0.640625f,
+0.186768f, -0.614014f, 0.157715f, -0.587402f, 0.157715f, -0.552734f, 0.157715f, -0.530762f,
+0.167969f, -0.513672f, 0.182129f, -0.490723f, 0.213379f, -0.468262f, 0.236328f, -0.452148f,
+0.319336f, -0.411133f, 0.435547f, -0.354004f, 0.476074f, -0.303223f, 0.516113f, -0.252441f,
+0.516113f, -0.187012f, 0.516113f, -0.104004f, 0.451416f, -0.0441895f, 0.386719f,
+0.015625f, 0.287109f, 0.015625f, 0.255859f, 0.015625f, 0.228027f, 0.00927734f, 0.200195f,
+0.00292969f, 0.158203f, -0.0146484f, 0.134766f, -0.0244141f, 0.119629f, -0.0244141f,
+0.106934f, -0.0244141f, 0.0927734f, -0.0146484f, 0.0786133f, -0.00488281f, 0.0698242f,
+0.0151367f, 0.0517578f, 0.0151367f, 0.0517578f, -0.234863f, 0.0698242f, -0.234863f,
+0.0913086f, -0.129395f, 0.152588f, -0.0739746f, 0.213867f, -0.0185547f, 0.284668f,
+-0.0185547f, 0.339355f, -0.0185547f, 0.371826f, -0.0483398f, 0.404297f, -0.078125f,
+0.404297f, -0.117676f, 0.404297f, -0.141113f, 0.391846f, -0.163086f, 0.379395f, -0.185059f,
+0.354004f, -0.204834f, 0.328613f, -0.224609f, 0.26416f, -0.256348f, 0.173828f, -0.300781f,
+0.134277f, -0.332031f, 0.0947266f, -0.363281f, 0.0734863f, -0.401855f, 0.0522461f,
+-0.44043f, 0.0522461f, -0.486816f, 0.0522461f, -0.565918f, 0.110352f, -0.621582f,
+0.168457f, -0.677246f, 0.256836f, -0.677246f, 0.289062f, -0.677246f, 0.319336f, -0.669434f,
+0.342285f, -0.663574f, 0.375244f, -0.647705f, 0.408203f, -0.631836f, 0.421387f, -0.631836f,
+0.434082f, -0.631836f, 0.441406f, -0.639648f, 0.44873f, -0.647461f, 0.455078f, -0.677246f,
+0.630859f, -0.662109f, 0.630859f, -0.48291f, 0.613281f, -0.48291f, 0.597656f, -0.544922f,
+0.578613f, -0.572021f, 0.55957f, -0.599121f, 0.526367f, -0.615234f, 0.507812f, -0.624023f,
+0.461426f, -0.624023f, 0.412109f, -0.624023f, 0.412109f, -0.113281f, 0.412109f, -0.0625f,
+0.417725f, -0.0498047f, 0.42334f, -0.0371094f, 0.439697f, -0.0275879f, 0.456055f,
+-0.0180664f, 0.484375f, -0.0180664f, 0.506348f, -0.0180664f, 0.506348f, 0, 0.159668f,
+0, 0.159668f, -0.0180664f, 0.181641f, -0.0180664f, 0.210449f, -0.0180664f, 0.228027f,
+-0.0283203f, 0.240723f, -0.0351562f, 0.248047f, -0.0517578f, 0.253418f, -0.0634766f,
+0.253418f, -0.113281f, 0.253418f, -0.624023f, 0.205566f, -0.624023f, 0.138672f, -0.624023f,
+0.108398f, -0.595703f, 0.065918f, -0.556152f, 0.0546875f, -0.48291f, 0.0361328f,
+-0.48291f, 0.0361328f, -0.662109f, 0.0234375f, -0.662109f, 0.365234f, -0.662109f,
+0.365234f, -0.644043f, 0.348145f, -0.644043f, 0.30957f, -0.644043f, 0.295166f, -0.635986f,
+0.280762f, -0.62793f, 0.274658f, -0.61377f, 0.268555f, -0.599609f, 0.268555f, -0.542969f,
+0.268555f, -0.21875f, 0.268555f, -0.129883f, 0.281982f, -0.101074f, 0.29541f, -0.0722656f,
+0.326172f, -0.0532227f, 0.356934f, -0.0341797f, 0.403809f, -0.0341797f, 0.45752f,
+-0.0341797f, 0.495361f, -0.0583496f, 0.533203f, -0.0825195f, 0.552002f, -0.125f,
+0.570801f, -0.16748f, 0.570801f, -0.272949f, 0.570801f, -0.542969f, 0.570801f, -0.587402f,
+0.561523f, -0.606445f, 0.552246f, -0.625488f, 0.538086f, -0.632812f, 0.516113f, -0.644043f,
+0.476074f, -0.644043f, 0.476074f, -0.662109f, 0.705078f, -0.662109f, 0.705078f, -0.644043f,
+0.691406f, -0.644043f, 0.663574f, -0.644043f, 0.64502f, -0.632812f, 0.626465f, -0.621582f,
+0.618164f, -0.599121f, 0.611816f, -0.583496f, 0.611816f, -0.542969f, 0.611816f, -0.291504f,
+0.611816f, -0.174805f, 0.596436f, -0.123047f, 0.581055f, -0.0712891f, 0.521484f,
+-0.027832f, 0.461914f, 0.015625f, 0.358887f, 0.015625f, 0.272949f, 0.015625f, 0.226074f,
+-0.00732422f, 0.162109f, -0.0385742f, 0.135742f, -0.0874023f, 0.109375f, -0.13623f,
+0.109375f, -0.21875f, 0.109375f, -0.542969f, 0.109375f, -0.600098f, 0.103027f, -0.614014f,
+0.0966797f, -0.62793f, 0.0810547f, -0.63623f, 0.0654297f, -0.644531f, 0.0234375f,
+-0.644043f, 0.711914f, -0.662109f, 0.711914f, -0.644043f, 0.675781f, -0.638184f,
+0.647461f, -0.605469f, 0.626953f, -0.581055f, 0.586426f, -0.490723f, 0.358398f, 0.0151367f,
+0.342285f, 0.0151367f, 0.115234f, -0.51123f, 0.0742188f, -0.606445f, 0.0603027f,
+-0.623047f, 0.0463867f, -0.639648f, 0.0078125f, -0.644043f, 0.0078125f, -0.662109f,
+0.325195f, -0.662109f, 0.325195f, -0.644043f, 0.314453f, -0.644043f, 0.271484f, -0.644043f,
+0.255859f, -0.633301f, 0.244629f, -0.625977f, 0.244629f, -0.611816f, 0.244629f, -0.603027f,
+0.248535f, -0.591064f, 0.252441f, -0.579102f, 0.274902f, -0.526855f, 0.416016f, -0.197266f,
+0.546875f, -0.490723f, 0.570312f, -0.543945f, 0.575684f, -0.562012f, 0.581055f, -0.580078f,
+0.581055f, -0.592773f, 0.581055f, -0.607422f, 0.573242f, -0.618652f, 0.56543f, -0.629883f,
+0.550293f, -0.635742f, 0.529297f, -0.644043f, 0.494629f, -0.644043f, 0.494629f, -0.662109f,
+0.991211f, -0.662109f, 0.991211f, -0.644043f, 0.972656f, -0.642578f, 0.959961f, -0.633789f,
+0.947266f, -0.625f, 0.9375f, -0.606934f, 0.93457f, -0.601074f, 0.906738f, -0.53125f,
+0.699219f, 0.0151367f, 0.680176f, 0.0151367f, 0.516113f, -0.411621f, 0.335449f, 0.0151367f,
+0.317383f, 0.0151367f, 0.0996094f, -0.525391f, 0.0664062f, -0.606934f, 0.0532227f,
+-0.624023f, 0.0400391f, -0.641113f, 0.00878906f, -0.644043f, 0.00878906f, -0.662109f,
+0.295898f, -0.662109f, 0.295898f, -0.644043f, 0.26123f, -0.643066f, 0.249756f, -0.633545f,
+0.238281f, -0.624023f, 0.238281f, -0.609863f, 0.238281f, -0.591309f, 0.262207f, -0.53125f,
+0.39209f, -0.209961f, 0.496094f, -0.460938f, 0.46875f, -0.53125f, 0.446289f, -0.588867f,
+0.434082f, -0.608154f, 0.421875f, -0.627441f, 0.406006f, -0.635742f, 0.390137f, -0.644043f,
+0.359375f, -0.644043f, 0.359375f, -0.662109f, 0.680176f, -0.662109f, 0.680176f, -0.644043f,
+0.646484f, -0.643555f, 0.631836f, -0.638672f, 0.621582f, -0.635254f, 0.615723f, -0.627197f,
+0.609863f, -0.619141f, 0.609863f, -0.608887f, 0.609863f, -0.597656f, 0.631836f, -0.540039f,
+0.752441f, -0.226562f, 0.860352f, -0.510254f, 0.877441f, -0.554199f, 0.881348f, -0.570312f,
+0.885254f, -0.586426f, 0.885254f, -0.600098f, 0.885254f, -0.620117f, 0.871582f, -0.631592f,
+0.85791f, -0.643066f, 0.819336f, -0.644043f, 0.819336f, -0.662109f, 0.422363f, -0.388184f,
+0.60498f, -0.117188f, 0.650391f, -0.0498047f, 0.669678f, -0.0354004f, 0.688965f,
+-0.0209961f, 0.715332f, -0.0180664f, 0.715332f, 0, 0.392578f, 0, 0.392578f, -0.0180664f,
+0.431152f, -0.0209961f, 0.442383f, -0.0297852f, 0.453613f, -0.0385742f, 0.453613f,
+-0.0512695f, 0.453613f, -0.0600586f, 0.450195f, -0.0668945f, 0.443359f, -0.081543f,
+0.416016f, -0.121582f, 0.319336f, -0.264648f, 0.218262f, -0.141113f, 0.172852f, -0.0849609f,
+0.172852f, -0.0649414f, 0.172852f, -0.0507812f, 0.18457f, -0.0385742f, 0.196289f,
+-0.0263672f, 0.219238f, -0.0209961f, 0.229492f, -0.0180664f, 0.26123f, -0.0180664f,
+0.26123f, 0, 0.00683594f, 0, 0.00683594f, -0.0180664f, 0.050293f, -0.0244141f, 0.0751953f,
+-0.0415039f, 0.10791f, -0.0639648f, 0.166504f, -0.135254f, 0.297852f, -0.29541f,
+0.129395f, -0.542969f, 0.0878906f, -0.604004f, 0.0820312f, -0.61084f, 0.0688477f,
+-0.626953f, 0.0561523f, -0.633789f, 0.043457f, -0.640625f, 0.0209961f, -0.644043f,
+0.0209961f, -0.662109f, 0.349609f, -0.662109f, 0.349609f, -0.644043f, 0.333008f,
+-0.644043f, 0.304688f, -0.644043f, 0.293457f, -0.63501f, 0.282227f, -0.625977f, 0.282227f,
+-0.612305f, 0.282227f, -0.601562f, 0.285645f, -0.59375f, 0.319336f, -0.542969f, 0.401367f,
+-0.417969f, 0.471191f, -0.503418f, 0.524902f, -0.569336f, 0.524902f, -0.595703f,
+0.524902f, -0.608887f, 0.517334f, -0.620117f, 0.509766f, -0.631348f, 0.495605f, -0.637695f,
+0.481445f, -0.644043f, 0.45166f, -0.644043f, 0.45166f, -0.662109f, 0.695312f, -0.662109f,
+0.695312f, -0.644043f, 0.666504f, -0.643555f, 0.648926f, -0.636963f, 0.631348f, -0.630371f,
+0.611328f, -0.612305f, 0.598633f, -0.600586f, 0.547852f, -0.539551f, 0.710938f, -0.662109f,
+0.710938f, -0.644043f, 0.678223f, -0.639648f, 0.660645f, -0.625f, 0.63623f, -0.604492f,
+0.583496f, -0.513184f, 0.439941f, -0.273438f, 0.439941f, -0.113281f, 0.439941f, -0.0620117f,
+0.445312f, -0.0495605f, 0.450684f, -0.0371094f, 0.466553f, -0.0275879f, 0.482422f,
+-0.0180664f, 0.508789f, -0.0180664f, 0.545898f, -0.0180664f, 0.545898f, 0, 0.174316f,
+0, 0.174316f, -0.0180664f, 0.208984f, -0.0180664f, 0.238281f, -0.0180664f, 0.255371f,
+-0.0283203f, 0.268066f, -0.0351562f, 0.275391f, -0.0517578f, 0.280762f, -0.0634766f,
+0.280762f, -0.113281f, 0.280762f, -0.246094f, 0.125f, -0.529785f, 0.0786133f, -0.61377f,
+0.0595703f, -0.628662f, 0.0405273f, -0.643555f, 0.00878906f, -0.644043f, 0.00878906f,
+-0.662109f, 0.326172f, -0.662109f, 0.326172f, -0.644043f, 0.312012f, -0.644043f,
+0.283203f, -0.644043f, 0.271729f, -0.635742f, 0.260254f, -0.627441f, 0.260254f, -0.618164f,
+0.260254f, -0.600586f, 0.299316f, -0.529785f, 0.418945f, -0.310547f, 0.538086f, -0.510254f,
+0.58252f, -0.583496f, 0.58252f, -0.607422f, 0.58252f, -0.620605f, 0.569824f, -0.629395f,
+0.553223f, -0.641602f, 0.508789f, -0.644043f, 0.508789f, -0.662109f, 0.610352f, -0.662109f,
+0.221191f, -0.0371094f, 0.347168f, -0.0371094f, 0.436523f, -0.0371094f, 0.472168f,
+-0.0483398f, 0.530273f, -0.065918f, 0.572266f, -0.113037f, 0.614258f, -0.160156f,
+0.630371f, -0.239258f, 0.649414f, -0.239258f, 0.622559f, 0, 0.0161133f, 0, 0.405762f,
+-0.625977f, 0.307617f, -0.625977f, 0.250488f, -0.625977f, 0.232422f, -0.622559f,
+0.198242f, -0.616211f, 0.168213f, -0.597412f, 0.138184f, -0.578613f, 0.118408f, -0.547363f,
+0.0986328f, -0.516113f, 0.0874023f, -0.468262f, 0.0693359f, -0.468262f, 0.0874023f,
+-0.662109f, 0.104492f, 0.182617f, 0.104492f, -0.662109f, 0.300781f, -0.662109f, 0.300781f,
+-0.641602f, 0.278809f, -0.641602f, 0.246582f, -0.641602f, 0.235596f, -0.63501f, 0.224609f,
+-0.628418f, 0.218994f, -0.615479f, 0.213379f, -0.602539f, 0.213379f, -0.553223f,
+0.213379f, 0.0771484f, 0.213379f, 0.124023f, 0.215332f, 0.130859f, 0.219727f, 0.148438f,
+0.231689f, 0.156738f, 0.243652f, 0.165039f, 0.278809f, 0.165039f, 0.300781f, 0.165039f,
+0.300781f, 0.182617f, 0.000976562f, -0.677246f, 0.0625f, -0.677246f, 0.280762f, 0.0151367f,
+0.217773f, 0.0151367f, 0.229004f, -0.662109f, 0.229004f, 0.182617f, 0.0327148f, 0.182617f,
+0.0327148f, 0.164062f, 0.0546875f, 0.164062f, 0.0869141f, 0.164062f, 0.0979004f,
+0.157715f, 0.108887f, 0.151367f, 0.114502f, 0.138184f, 0.120117f, 0.125f, 0.120117f,
+0.0761719f, 0.120117f, -0.554688f, 0.120117f, -0.601562f, 0.118164f, -0.608398f,
+0.11377f, -0.625488f, 0.101807f, -0.634033f, 0.0898438f, -0.642578f, 0.0546875f,
+-0.642578f, 0.0327148f, -0.642578f, 0.0327148f, -0.662109f, 0.0717773f, -0.325195f,
+0.272461f, -0.675781f, 0.3125f, -0.675781f, 0.509766f, -0.325195f, 0.432129f, -0.325195f,
+0.288086f, -0.575195f, 0.146484f, -0.325195f, -0.00927734f, 0.151855f, 0.509277f,
+0.151855f, 0.509277f, 0.21582f, -0.00927734f, 0.21582f, 0.0185547f, -0.68457f, 0.165527f,
+-0.68457f, 0.222168f, -0.515137f, 0.180664f, -0.515137f, 0.285645f, -0.0673828f,
+0.202148f, 0.00634766f, 0.135742f, 0.00634766f, 0.0966797f, 0.00634766f, 0.0708008f,
+-0.0192871f, 0.0449219f, -0.0449219f, 0.0449219f, -0.0834961f, 0.0449219f, -0.135742f,
+0.0898438f, -0.17749f, 0.134766f, -0.219238f, 0.285645f, -0.288574f, 0.285645f, -0.334473f,
+0.285645f, -0.38623f, 0.280029f, -0.399658f, 0.274414f, -0.413086f, 0.258789f, -0.423096f,
+0.243164f, -0.433105f, 0.223633f, -0.433105f, 0.191895f, -0.433105f, 0.171387f, -0.418945f,
+0.158691f, -0.410156f, 0.158691f, -0.398438f, 0.158691f, -0.388184f, 0.172363f, -0.373047f,
+0.190918f, -0.352051f, 0.190918f, -0.33252f, 0.190918f, -0.308594f, 0.173096f, -0.291748f,
+0.155273f, -0.274902f, 0.126465f, -0.274902f, 0.0957031f, -0.274902f, 0.0749512f,
+-0.293457f, 0.0541992f, -0.312012f, 0.0541992f, -0.336914f, 0.0541992f, -0.37207f,
+0.0820312f, -0.404053f, 0.109863f, -0.436035f, 0.159668f, -0.453125f, 0.209473f,
+-0.470215f, 0.263184f, -0.470215f, 0.328125f, -0.470215f, 0.365967f, -0.442627f,
+0.403809f, -0.415039f, 0.415039f, -0.382812f, 0.421875f, -0.362305f, 0.421875f, -0.288574f,
+0.421875f, -0.111328f, 0.421875f, -0.0800781f, 0.424316f, -0.0720215f, 0.426758f,
+-0.0639648f, 0.431641f, -0.0600586f, 0.436523f, -0.0561523f, 0.442871f, -0.0561523f,
+0.455566f, -0.0561523f, 0.46875f, -0.0742188f, 0.483398f, -0.0625f, 0.458984f, -0.0263672f,
+0.432861f, -0.0100098f, 0.406738f, 0.00634766f, 0.373535f, 0.00634766f, 0.334473f,
+0.00634766f, 0.3125f, -0.0119629f, 0.290527f, -0.0302734f, 0.285645f, -0.0673828f,
+0.285645f, -0.103027f, 0.285645f, -0.255859f, 0.226562f, -0.221191f, 0.197754f, -0.181641f,
+0.178711f, -0.155273f, 0.178711f, -0.128418f, 0.178711f, -0.105957f, 0.194824f, -0.0888672f,
+0.207031f, -0.0756836f, 0.229004f, -0.0756836f, 0.253418f, -0.0756836f, 0.285645f,
+-0.103027f, 0.210449f, -0.662109f, 0.210449f, -0.410645f, 0.268066f, -0.470215f,
+0.336426f, -0.470215f, 0.383301f, -0.470215f, 0.424805f, -0.442627f, 0.466309f, -0.415039f,
+0.489746f, -0.364258f, 0.513184f, -0.313477f, 0.513184f, -0.24707f, 0.513184f, -0.172363f,
+0.483398f, -0.111328f, 0.453613f, -0.050293f, 0.403809f, -0.0183105f, 0.354004f,
+0.0136719f, 0.290039f, 0.0136719f, 0.25293f, 0.0136719f, 0.224121f, 0.00195312f,
+0.195312f, -0.00976562f, 0.16748f, -0.0361328f, 0.0917969f, 0.0131836f, 0.0751953f,
+0.0131836f, 0.0751953f, -0.567383f, 0.0751953f, -0.606934f, 0.0717773f, -0.616211f,
+0.0668945f, -0.629883f, 0.0563965f, -0.636475f, 0.0458984f, -0.643066f, 0.0209961f,
+-0.644043f, 0.0209961f, -0.662109f, 0.210449f, -0.367188f, 0.210449f, -0.164062f,
+0.210449f, -0.102051f, 0.213379f, -0.0849609f, 0.218262f, -0.0561523f, 0.236816f,
+-0.0383301f, 0.255371f, -0.0205078f, 0.28418f, -0.0205078f, 0.309082f, -0.0205078f,
+0.326904f, -0.034668f, 0.344727f, -0.0488281f, 0.356689f, -0.0908203f, 0.368652f,
+-0.132812f, 0.368652f, -0.242188f, 0.368652f, -0.347168f, 0.342285f, -0.38623f, 0.323242f,
+-0.414551f, 0.291016f, -0.414551f, 0.249023f, -0.414551f, 0.210449f, -0.367188f,
+0.40625f, -0.117676f, 0.421387f, -0.105957f, 0.38916f, -0.0454102f, 0.341064f, -0.0158691f,
+0.292969f, 0.0136719f, 0.23877f, 0.0136719f, 0.147461f, 0.0136719f, 0.0927734f, -0.0551758f,
+0.0380859f, -0.124023f, 0.0380859f, -0.220703f, 0.0380859f, -0.313965f, 0.0878906f,
+-0.384766f, 0.147949f, -0.470215f, 0.253418f, -0.470215f, 0.324219f, -0.470215f,
+0.365967f, -0.43457f, 0.407715f, -0.398926f, 0.407715f, -0.35498f, 0.407715f, -0.327148f,
+0.390869f, -0.310547f, 0.374023f, -0.293945f, 0.34668f, -0.293945f, 0.317871f, -0.293945f,
+0.299072f, -0.312988f, 0.280273f, -0.332031f, 0.275879f, -0.380859f, 0.272949f, -0.411621f,
+0.261719f, -0.423828f, 0.250488f, -0.436035f, 0.235352f, -0.436035f, 0.211914f, -0.436035f,
+0.195312f, -0.411133f, 0.169922f, -0.373535f, 0.169922f, -0.295898f, 0.169922f, -0.231445f,
+0.19043f, -0.172607f, 0.210938f, -0.11377f, 0.246582f, -0.0849609f, 0.273438f, -0.0639648f,
+0.310059f, -0.0639648f, 0.333984f, -0.0639648f, 0.355469f, -0.0751953f, 0.376953f,
+-0.0864258f, 0.40625f, -0.117676f, 0.477539f, -0.662109f, 0.477539f, -0.136719f,
+0.477539f, -0.0834961f, 0.480469f, -0.0737305f, 0.484375f, -0.0576172f, 0.495361f,
+-0.0498047f, 0.506348f, -0.0419922f, 0.533691f, -0.0400391f, 0.533691f, -0.0239258f,
+0.34082f, 0.0136719f, 0.34082f, -0.0585938f, 0.306152f, -0.0166016f, 0.279053f, -0.00146484f,
+0.251953f, 0.0136719f, 0.217773f, 0.0136719f, 0.130371f, 0.0136719f, 0.0795898f,
+-0.0644531f, 0.0385742f, -0.12793f, 0.0385742f, -0.220215f, 0.0385742f, -0.293945f,
+0.0639648f, -0.352295f, 0.0893555f, -0.410645f, 0.133545f, -0.44043f, 0.177734f,
+-0.470215f, 0.228516f, -0.470215f, 0.26123f, -0.470215f, 0.286621f, -0.45752f, 0.312012f,
+-0.444824f, 0.34082f, -0.413086f, 0.34082f, -0.550781f, 0.34082f, -0.603027f, 0.336426f,
+-0.61377f, 0.330566f, -0.62793f, 0.318848f, -0.634766f, 0.307129f, -0.641602f, 0.274902f,
+-0.641602f, 0.274902f, -0.662109f, 0.34082f, -0.352539f, 0.304688f, -0.421875f, 0.252441f,
+-0.421875f, 0.234375f, -0.421875f, 0.222656f, -0.412109f, 0.20459f, -0.396973f, 0.193115f,
+-0.358887f, 0.181641f, -0.320801f, 0.181641f, -0.242188f, 0.181641f, -0.155762f,
+0.194336f, -0.114258f, 0.207031f, -0.0727539f, 0.229004f, -0.0541992f, 0.240234f,
+-0.0449219f, 0.259766f, -0.0449219f, 0.302734f, -0.0449219f, 0.34082f, -0.112305f,
+0.42041f, -0.244629f, 0.169922f, -0.244629f, 0.174316f, -0.153809f, 0.218262f, -0.101074f,
+0.251953f, -0.0605469f, 0.299316f, -0.0605469f, 0.328613f, -0.0605469f, 0.352539f,
+-0.0769043f, 0.376465f, -0.0932617f, 0.403809f, -0.135742f, 0.42041f, -0.125f, 0.383301f,
+-0.0493164f, 0.338379f, -0.0178223f, 0.293457f, 0.0136719f, 0.234375f, 0.0136719f,
+0.132812f, 0.0136719f, 0.0805664f, -0.0644531f, 0.0385742f, -0.127441f, 0.0385742f,
+-0.220703f, 0.0385742f, -0.334961f, 0.100342f, -0.402588f, 0.162109f, -0.470215f,
+0.245117f, -0.470215f, 0.314453f, -0.470215f, 0.365479f, -0.41333f, 0.416504f, -0.356445f,
+0.42041f, -0.244629f, 0.300293f, -0.277344f, 0.300293f, -0.355957f, 0.291748f, -0.385254f,
+0.283203f, -0.414551f, 0.265137f, -0.429688f, 0.254883f, -0.438477f, 0.237793f, -0.438477f,
+0.212402f, -0.438477f, 0.196289f, -0.413574f, 0.16748f, -0.370117f, 0.16748f, -0.294434f,
+0.16748f, -0.277344f, 0.233887f, -0.408691f, 0.233887f, -0.0917969f, 0.233887f, -0.0458984f,
+0.243652f, -0.0341797f, 0.259277f, -0.0161133f, 0.30127f, -0.0175781f, 0.30127f,
+0, 0.0322266f, 0, 0.0322266f, -0.0175781f, 0.0629883f, -0.0180664f, 0.0759277f, -0.0246582f,
+0.0888672f, -0.03125f, 0.09375f, -0.0429688f, 0.0986328f, -0.0546875f, 0.0986328f,
+-0.0917969f, 0.0986328f, -0.408691f, 0.0322266f, -0.408691f, 0.0322266f, -0.456543f,
+0.0986328f, -0.456543f, 0.0986328f, -0.490234f, 0.0981445f, -0.513184f, 0.0981445f,
+-0.583496f, 0.149658f, -0.630371f, 0.201172f, -0.677246f, 0.289062f, -0.677246f,
+0.349121f, -0.677246f, 0.378174f, -0.654785f, 0.407227f, -0.632324f, 0.407227f, -0.60498f,
+0.407227f, -0.583008f, 0.38916f, -0.566895f, 0.371094f, -0.550781f, 0.341309f, -0.550781f,
+0.315918f, -0.550781f, 0.301025f, -0.563965f, 0.286133f, -0.577148f, 0.286133f, -0.593262f,
+0.286133f, -0.597656f, 0.289062f, -0.611328f, 0.291016f, -0.619629f, 0.291016f, -0.626953f,
+0.291016f, -0.637207f, 0.285156f, -0.64209f, 0.277344f, -0.649414f, 0.266113f, -0.649414f,
+0.251953f, -0.649414f, 0.242432f, -0.637695f, 0.23291f, -0.625977f, 0.23291f, -0.600098f,
+0.233887f, -0.514648f, 0.233887f, -0.456543f, 0.30127f, -0.456543f, 0.30127f, -0.408691f,
+0.32666f, -0.451172f, 0.480469f, -0.451172f, 0.480469f, -0.397461f, 0.393066f, -0.397461f,
+0.416992f, -0.373535f, 0.42627f, -0.354004f, 0.437988f, -0.327637f, 0.437988f, -0.298828f,
+0.437988f, -0.25f, 0.410889f, -0.214111f, 0.383789f, -0.178223f, 0.337158f, -0.157959f,
+0.290527f, -0.137695f, 0.254395f, -0.137695f, 0.251465f, -0.137695f, 0.195801f, -0.140137f,
+0.173828f, -0.140137f, 0.158936f, -0.125732f, 0.144043f, -0.111328f, 0.144043f, -0.0913086f,
+0.144043f, -0.0737305f, 0.157471f, -0.0625f, 0.170898f, -0.0512695f, 0.201172f, -0.0512695f,
+0.285645f, -0.0522461f, 0.388184f, -0.0522461f, 0.426758f, -0.0297852f, 0.481934f,
+0.00146484f, 0.481934f, 0.0664062f, 0.481934f, 0.10791f, 0.456543f, 0.141846f, 0.431152f,
+0.175781f, 0.389648f, 0.191895f, 0.32666f, 0.21582f, 0.244629f, 0.21582f, 0.183105f,
+0.21582f, 0.132324f, 0.203857f, 0.081543f, 0.191895f, 0.0595703f, 0.170654f, 0.0375977f,
+0.149414f, 0.0375977f, 0.125977f, 0.0375977f, 0.103516f, 0.0544434f, 0.0856934f,
+0.0712891f, 0.0678711f, 0.117188f, 0.0556641f, 0.0537109f, 0.0244141f, 0.0537109f,
+-0.03125f, 0.0537109f, -0.0649414f, 0.0795898f, -0.0966797f, 0.105469f, -0.128418f,
+0.161621f, -0.151855f, 0.0961914f, -0.175781f, 0.0668945f, -0.214844f, 0.0375977f,
+-0.253906f, 0.0375977f, -0.305176f, 0.0375977f, -0.37207f, 0.0922852f, -0.421143f,
+0.146973f, -0.470215f, 0.23291f, -0.470215f, 0.27832f, -0.470215f, 0.32666f, -0.451172f,
+0.242188f, -0.439941f, 0.213867f, -0.439941f, 0.194336f, -0.411377f, 0.174805f, -0.382812f,
+0.174805f, -0.292969f, 0.174805f, -0.220215f, 0.194092f, -0.193115f, 0.213379f, -0.166016f,
+0.239746f, -0.166016f, 0.269043f, -0.166016f, 0.288574f, -0.192871f, 0.308105f, -0.219727f,
+0.308105f, -0.297363f, 0.308105f, -0.384766f, 0.286133f, -0.416504f, 0.270508f, -0.439941f,
+0.242188f, -0.439941f, 0.213379f, 0.0673828f, 0.163574f, 0.0673828f, 0.147461f, 0.0756836f,
+0.119629f, 0.0908203f, 0.119629f, 0.116699f, 0.119629f, 0.141602f, 0.148438f, 0.161865f,
+0.177246f, 0.182129f, 0.256836f, 0.182129f, 0.324707f, 0.182129f, 0.363525f, 0.164062f,
+0.402344f, 0.145996f, 0.402344f, 0.113281f, 0.402344f, 0.101074f, 0.39502f, 0.0927734f,
+0.381836f, 0.078125f, 0.355225f, 0.0727539f, 0.328613f, 0.0673828f, 0.213379f, 0.0673828f,
+0.220215f, -0.662109f, 0.220215f, -0.397949f, 0.257812f, -0.4375f, 0.289062f, -0.453857f,
+0.320312f, -0.470215f, 0.354004f, -0.470215f, 0.396973f, -0.470215f, 0.42749f, -0.445801f,
+0.458008f, -0.421387f, 0.468018f, -0.388428f, 0.478027f, -0.355469f, 0.478027f, -0.277344f,
+0.478027f, -0.0991211f, 0.478027f, -0.046875f, 0.487793f, -0.0339355f, 0.497559f,
+-0.0209961f, 0.527344f, -0.0175781f, 0.527344f, 0, 0.295898f, 0, 0.295898f, -0.0175781f,
+0.320312f, -0.0209961f, 0.33252f, -0.0371094f, 0.341309f, -0.0498047f, 0.341309f,
+-0.0991211f, 0.341309f, -0.302734f, 0.341309f, -0.359375f, 0.336914f, -0.373779f,
+0.33252f, -0.388184f, 0.322021f, -0.39624f, 0.311523f, -0.404297f, 0.29834f, -0.404297f,
+0.278809f, -0.404297f, 0.260254f, -0.390869f, 0.241699f, -0.377441f, 0.220215f, -0.34375f,
+0.220215f, -0.0991211f, 0.220215f, -0.050293f, 0.227539f, -0.0380859f, 0.236816f,
+-0.0214844f, 0.265625f, -0.0175781f, 0.265625f, 0, 0.0341797f, 0, 0.0341797f, -0.0175781f,
+0.0629883f, -0.0205078f, 0.0751953f, -0.0361328f, 0.0834961f, -0.046875f, 0.0834961f,
+-0.0991211f, 0.0834961f, -0.562988f, 0.0834961f, -0.614746f, 0.0739746f, -0.627441f,
+0.0644531f, -0.640137f, 0.0341797f, -0.644043f, 0.0341797f, -0.662109f, 0.143555f,
+-0.677734f, 0.175293f, -0.677734f, 0.197266f, -0.655518f, 0.219238f, -0.633301f,
+0.219238f, -0.602051f, 0.219238f, -0.570801f, 0.197021f, -0.548828f, 0.174805f, -0.526855f,
+0.143555f, -0.526855f, 0.112305f, -0.526855f, 0.090332f, -0.548828f, 0.0683594f,
+-0.570801f, 0.0683594f, -0.602051f, 0.0683594f, -0.633301f, 0.090332f, -0.655518f,
+0.112305f, -0.677734f, 0.143555f, -0.677734f, 0.211914f, -0.456543f, 0.211914f, -0.0947266f,
+0.211914f, -0.0463867f, 0.223145f, -0.032959f, 0.234375f, -0.0195312f, 0.26709f,
+-0.0175781f, 0.26709f, 0, 0.0205078f, 0, 0.0205078f, -0.0175781f, 0.0507812f, -0.0185547f,
+0.0654297f, -0.0351562f, 0.0751953f, -0.0463867f, 0.0751953f, -0.0947266f, 0.0751953f,
+-0.361328f, 0.0751953f, -0.409668f, 0.0639648f, -0.423096f, 0.0527344f, -0.436523f,
+0.0205078f, -0.438477f, 0.0205078f, -0.456543f, 0.173828f, -0.677246f, 0.205078f,
+-0.677246f, 0.226807f, -0.655518f, 0.248535f, -0.633789f, 0.248535f, -0.603027f,
+0.248535f, -0.571777f, 0.226562f, -0.549805f, 0.20459f, -0.527832f, 0.173828f, -0.527832f,
+0.143066f, -0.527832f, 0.121094f, -0.549805f, 0.0991211f, -0.571777f, 0.0991211f,
+-0.603027f, 0.0991211f, -0.633789f, 0.12085f, -0.655518f, 0.142578f, -0.677246f,
+0.173828f, -0.677246f, 0.242188f, -0.456543f, 0.242188f, 0.0161133f, 0.242188f, 0.0825195f,
+0.233887f, 0.114258f, 0.22168f, 0.160156f, 0.185303f, 0.187988f, 0.148926f, 0.21582f,
+0.0893555f, 0.21582f, 0.0292969f, 0.21582f, 0.000732422f, 0.191406f, -0.027832f,
+0.166992f, -0.027832f, 0.132324f, -0.027832f, 0.11084f, -0.0129395f, 0.0949707f,
+0.00195312f, 0.0791016f, 0.0219727f, 0.0791016f, 0.0405273f, 0.0791016f, 0.0512695f,
+0.0900879f, 0.0620117f, 0.101074f, 0.0620117f, 0.123047f, 0.0620117f, 0.128906f,
+0.0615234f, 0.136719f, 0.0605469f, 0.146973f, 0.0605469f, 0.150879f, 0.0605469f,
+0.167969f, 0.0683594f, 0.17627f, 0.0761719f, 0.18457f, 0.0883789f, 0.18457f, 0.0996094f,
+0.18457f, 0.107666f, 0.174805f, 0.115723f, 0.165039f, 0.115723f, 0.146973f, 0.115723f,
+0.137207f, 0.112793f, 0.107422f, 0.10791f, 0.0532227f, 0.107422f, 0.0419922f, 0.105957f,
+-0.0737305f, 0.105957f, -0.355957f, 0.106445f, -0.381348f, 0.106445f, -0.412109f,
+0.0959473f, -0.423584f, 0.0854492f, -0.435059f, 0.0517578f, -0.438477f, 0.0517578f,
+-0.456543f, 0.219238f, -0.662109f, 0.219238f, -0.226562f, 0.325195f, -0.330566f,
+0.35791f, -0.362305f, 0.365967f, -0.376465f, 0.374023f, -0.390625f, 0.374023f, -0.403809f,
+0.374023f, -0.416992f, 0.363281f, -0.425781f, 0.352539f, -0.43457f, 0.321289f, -0.438477f,
+0.321289f, -0.456543f, 0.525879f, -0.456543f, 0.525879f, -0.438477f, 0.496582f, -0.437012f,
+0.474609f, -0.424561f, 0.452637f, -0.412109f, 0.388672f, -0.349609f, 0.338867f, -0.300781f,
+0.446289f, -0.143555f, 0.51123f, -0.0478516f, 0.523438f, -0.0361328f, 0.540039f,
+-0.0195312f, 0.56543f, -0.0175781f, 0.56543f, 0, 0.32959f, 0, 0.32959f, -0.0175781f,
+0.345215f, -0.0175781f, 0.352295f, -0.0234375f, 0.359375f, -0.0292969f, 0.359375f,
+-0.0361328f, 0.359375f, -0.0473633f, 0.338867f, -0.0776367f, 0.248535f, -0.209961f,
+0.219238f, -0.181152f, 0.219238f, -0.0991211f, 0.219238f, -0.046875f, 0.229004f,
+-0.0339355f, 0.23877f, -0.0209961f, 0.269043f, -0.0175781f, 0.269043f, 0, 0.0332031f,
+0, 0.0332031f, -0.0175781f, 0.0620117f, -0.0205078f, 0.0742188f, -0.0361328f, 0.0825195f,
+-0.046875f, 0.0825195f, -0.0991211f, 0.0825195f, -0.562988f, 0.0825195f, -0.614746f,
+0.072998f, -0.627441f, 0.0634766f, -0.640137f, 0.0332031f, -0.644043f, 0.0332031f,
+-0.662109f, 0.212402f, -0.662109f, 0.212402f, -0.0947266f, 0.212402f, -0.0463867f,
+0.223633f, -0.032959f, 0.234863f, -0.0195312f, 0.267578f, -0.0175781f, 0.267578f,
+0, 0.0209961f, 0, 0.0209961f, -0.0175781f, 0.0512695f, -0.0185547f, 0.065918f, -0.0351562f,
+0.0756836f, -0.0463867f, 0.0756836f, -0.0947266f, 0.0756836f, -0.567383f, 0.0756836f,
+-0.615234f, 0.0644531f, -0.628662f, 0.0532227f, -0.64209f, 0.0209961f, -0.644043f,
+0.0209961f, -0.662109f, 0.223145f, -0.456543f, 0.223145f, -0.396484f, 0.260742f,
+-0.4375f, 0.292725f, -0.453857f, 0.324707f, -0.470215f, 0.362793f, -0.470215f, 0.406738f,
+-0.470215f, 0.436523f, -0.449707f, 0.466309f, -0.429199f, 0.482422f, -0.387207f,
+0.521484f, -0.431152f, 0.557373f, -0.450684f, 0.593262f, -0.470215f, 0.632324f, -0.470215f,
+0.679688f, -0.470215f, 0.707764f, -0.448486f, 0.73584f, -0.426758f, 0.746826f, -0.393311f,
+0.757812f, -0.359863f, 0.757812f, -0.286621f, 0.757812f, -0.0996094f, 0.757812f,
+-0.046875f, 0.767334f, -0.0341797f, 0.776855f, -0.0214844f, 0.807129f, -0.0175781f,
+0.807129f, 0, 0.571289f, 0, 0.571289f, -0.0175781f, 0.599121f, -0.0200195f, 0.612305f,
+-0.0390625f, 0.621094f, -0.0522461f, 0.621094f, -0.0996094f, 0.621094f, -0.295898f,
+0.621094f, -0.356934f, 0.616211f, -0.373535f, 0.611328f, -0.390137f, 0.60083f, -0.398193f,
+0.590332f, -0.40625f, 0.576172f, -0.40625f, 0.555176f, -0.40625f, 0.533691f, -0.390869f,
+0.512207f, -0.375488f, 0.490234f, -0.344727f, 0.490234f, -0.0996094f, 0.490234f,
+-0.050293f, 0.498535f, -0.0375977f, 0.509766f, -0.0195312f, 0.541504f, -0.0175781f,
+0.541504f, 0, 0.305176f, 0, 0.305176f, -0.0175781f, 0.324219f, -0.0185547f, 0.335205f,
+-0.0270996f, 0.346191f, -0.0356445f, 0.349854f, -0.0476074f, 0.353516f, -0.0595703f,
+0.353516f, -0.0996094f, 0.353516f, -0.295898f, 0.353516f, -0.35791f, 0.348633f, -0.373535f,
+0.34375f, -0.38916f, 0.332275f, -0.397949f, 0.320801f, -0.406738f, 0.307617f, -0.406738f,
+0.288086f, -0.406738f, 0.271973f, -0.396484f, 0.249023f, -0.381348f, 0.223145f, -0.344727f,
+0.223145f, -0.0996094f, 0.223145f, -0.0512695f, 0.232666f, -0.0358887f, 0.242188f,
+-0.0205078f, 0.272461f, -0.0175781f, 0.272461f, 0, 0.0371094f, 0, 0.0371094f, -0.0175781f,
+0.065918f, -0.0205078f, 0.078125f, -0.0361328f, 0.0864258f, -0.046875f, 0.0864258f,
+-0.0996094f, 0.0864258f, -0.357422f, 0.0864258f, -0.40918f, 0.0769043f, -0.421875f,
+0.0673828f, -0.43457f, 0.0371094f, -0.438477f, 0.0371094f, -0.456543f, 0.220215f,
+-0.456543f, 0.220215f, -0.397461f, 0.255371f, -0.435547f, 0.287598f, -0.452881f,
+0.319824f, -0.470215f, 0.356934f, -0.470215f, 0.401367f, -0.470215f, 0.430664f, -0.445557f,
+0.459961f, -0.420898f, 0.469727f, -0.384277f, 0.477539f, -0.356445f, 0.477539f, -0.277344f,
+0.477539f, -0.0996094f, 0.477539f, -0.046875f, 0.487061f, -0.0339355f, 0.496582f,
+-0.0209961f, 0.526855f, -0.0175781f, 0.526855f, 0, 0.295898f, 0, 0.295898f, -0.0175781f,
+0.321777f, -0.0209961f, 0.333008f, -0.0390625f, 0.34082f, -0.0512695f, 0.34082f,
+-0.0996094f, 0.34082f, -0.302734f, 0.34082f, -0.358887f, 0.336426f, -0.373535f, 0.332031f,
+-0.388184f, 0.321533f, -0.39624f, 0.311035f, -0.404297f, 0.29834f, -0.404297f, 0.256348f,
+-0.404297f, 0.220215f, -0.344238f, 0.220215f, -0.0996094f, 0.220215f, -0.0483398f,
+0.229736f, -0.034668f, 0.239258f, -0.0209961f, 0.265137f, -0.0175781f, 0.265137f,
+0, 0.0341797f, 0, 0.0341797f, -0.0175781f, 0.0629883f, -0.0205078f, 0.0751953f, -0.0361328f,
+0.0834961f, -0.046875f, 0.0834961f, -0.0996094f, 0.0834961f, -0.357422f, 0.0834961f,
+-0.40918f, 0.0739746f, -0.421875f, 0.0644531f, -0.43457f, 0.0341797f, -0.438477f,
+0.0341797f, -0.456543f, 0.249023f, -0.470215f, 0.308594f, -0.470215f, 0.359863f,
+-0.439453f, 0.411133f, -0.408691f, 0.437744f, -0.352051f, 0.464355f, -0.29541f, 0.464355f,
+-0.228027f, 0.464355f, -0.130859f, 0.415039f, -0.0654297f, 0.355469f, 0.0136719f,
+0.250488f, 0.0136719f, 0.147461f, 0.0136719f, 0.0917969f, -0.0585938f, 0.0361328f,
+-0.130859f, 0.0361328f, -0.226074f, 0.0361328f, -0.324219f, 0.0930176f, -0.397217f,
+0.149902f, -0.470215f, 0.249023f, -0.470215f, 0.250977f, -0.435547f, 0.226074f, -0.435547f,
+0.208252f, -0.416748f, 0.19043f, -0.397949f, 0.184814f, -0.342529f, 0.179199f, -0.287109f,
+0.179199f, -0.188477f, 0.179199f, -0.13623f, 0.186035f, -0.0908203f, 0.191406f, -0.0561523f,
+0.208984f, -0.0380859f, 0.226562f, -0.0200195f, 0.249023f, -0.0200195f, 0.270996f,
+-0.0200195f, 0.285645f, -0.0322266f, 0.304688f, -0.0488281f, 0.311035f, -0.0786133f,
+0.320801f, -0.125f, 0.320801f, -0.266113f, 0.320801f, -0.349121f, 0.311523f, -0.380127f,
+0.302246f, -0.411133f, 0.28418f, -0.425293f, 0.271484f, -0.435547f, 0.250977f, -0.435547f,
+0.210449f, -0.0463867f, 0.210449f, 0.123535f, 0.210449f, 0.158691f, 0.216064f, 0.171387f,
+0.22168f, 0.184082f, 0.233398f, 0.189941f, 0.245117f, 0.195801f, 0.279297f, 0.195801f,
+0.279297f, 0.213867f, 0.019043f, 0.213867f, 0.019043f, 0.195801f, 0.0493164f, 0.194824f,
+0.0639648f, 0.178711f, 0.0737305f, 0.16748f, 0.0737305f, 0.120605f, 0.0737305f, -0.361328f,
+0.0737305f, -0.409668f, 0.0625f, -0.423096f, 0.0512695f, -0.436523f, 0.019043f, -0.438477f,
+0.019043f, -0.456543f, 0.210449f, -0.456543f, 0.210449f, -0.396484f, 0.234375f, -0.431641f,
+0.259277f, -0.447266f, 0.294922f, -0.470215f, 0.336914f, -0.470215f, 0.387207f, -0.470215f,
+0.428467f, -0.438477f, 0.469727f, -0.406738f, 0.491211f, -0.35083f, 0.512695f, -0.294922f,
+0.512695f, -0.230469f, 0.512695f, -0.161133f, 0.490479f, -0.10376f, 0.468262f, -0.0463867f,
+0.426025f, -0.0163574f, 0.383789f, 0.0136719f, 0.332031f, 0.0136719f, 0.294434f,
+0.0136719f, 0.261719f, -0.00292969f, 0.237305f, -0.015625f, 0.210449f, -0.0463867f,
+0.210449f, -0.0957031f, 0.252441f, -0.0361328f, 0.300293f, -0.0361328f, 0.32666f,
+-0.0361328f, 0.34375f, -0.0639648f, 0.369141f, -0.10498f, 0.369141f, -0.220215f,
+0.369141f, -0.338379f, 0.341309f, -0.381836f, 0.322754f, -0.410645f, 0.291504f, -0.410645f,
+0.242188f, -0.410645f, 0.210449f, -0.339355f, 0.340332f, -0.0478516f, 0.310547f,
+-0.0166016f, 0.284668f, -0.00390625f, 0.250488f, 0.0136719f, 0.213379f, 0.0136719f,
+0.127441f, 0.0136719f, 0.0776367f, -0.0629883f, 0.0380859f, -0.124023f, 0.0380859f,
+-0.208984f, 0.0380859f, -0.279785f, 0.0681152f, -0.342041f, 0.0981445f, -0.404297f,
+0.150635f, -0.437256f, 0.203125f, -0.470215f, 0.261719f, -0.470215f, 0.300781f, -0.470215f,
+0.331299f, -0.457031f, 0.361816f, -0.443848f, 0.383789f, -0.416992f, 0.460449f, -0.470215f,
+0.477051f, -0.470215f, 0.477051f, 0.121094f, 0.477051f, 0.166016f, 0.484863f, 0.177246f,
+0.497559f, 0.195312f, 0.536133f, 0.195801f, 0.536133f, 0.213867f, 0.272461f, 0.213867f,
+0.272461f, 0.195801f, 0.302734f, 0.195801f, 0.316406f, 0.188965f, 0.330078f, 0.182129f,
+0.335205f, 0.170898f, 0.340332f, 0.159668f, 0.340332f, 0.125f, 0.340332f, -0.0922852f,
+0.340332f, -0.280273f, 0.340332f, -0.358887f, 0.331787f, -0.384277f, 0.323242f, -0.409668f,
+0.300293f, -0.428223f, 0.288574f, -0.4375f, 0.270508f, -0.4375f, 0.233398f, -0.4375f,
+0.212891f, -0.404785f, 0.180664f, -0.354492f, 0.180664f, -0.217773f, 0.180664f, -0.112793f,
+0.208496f, -0.0703125f, 0.227539f, -0.0415039f, 0.257812f, -0.0415039f, 0.275391f,
+-0.0415039f, 0.297607f, -0.0537109f, 0.319824f, -0.065918f, 0.340332f, -0.0922852f,
+0.223145f, -0.456543f, 0.223145f, -0.353027f, 0.268555f, -0.423828f, 0.302734f, -0.447021f,
+0.336914f, -0.470215f, 0.368652f, -0.470215f, 0.395996f, -0.470215f, 0.412354f, -0.453369f,
+0.428711f, -0.436523f, 0.428711f, -0.405762f, 0.428711f, -0.373047f, 0.412842f, -0.35498f,
+0.396973f, -0.336914f, 0.374512f, -0.336914f, 0.348633f, -0.336914f, 0.32959f, -0.353516f,
+0.310547f, -0.370117f, 0.307129f, -0.37207f, 0.302246f, -0.375f, 0.295898f, -0.375f,
+0.281738f, -0.375f, 0.269043f, -0.364258f, 0.249023f, -0.347656f, 0.23877f, -0.316895f,
+0.223145f, -0.269531f, 0.223145f, -0.212402f, 0.223145f, -0.107422f, 0.223633f, -0.0800781f,
+0.223633f, -0.0522461f, 0.227051f, -0.0444336f, 0.23291f, -0.03125f, 0.244385f, -0.0251465f,
+0.255859f, -0.019043f, 0.283203f, -0.0175781f, 0.283203f, 0, 0.0366211f, 0, 0.0366211f,
+-0.0175781f, 0.0664062f, -0.0200195f, 0.0769043f, -0.0339355f, 0.0874023f, -0.0478516f,
+0.0874023f, -0.107422f, 0.0874023f, -0.359863f, 0.0874023f, -0.398926f, 0.0834961f,
+-0.409668f, 0.0786133f, -0.42334f, 0.0693359f, -0.429688f, 0.0600586f, -0.436035f,
+0.0366211f, -0.438477f, 0.0366211f, -0.456543f, 0.322266f, -0.469238f, 0.32959f,
+-0.313477f, 0.312988f, -0.313477f, 0.283203f, -0.382812f, 0.251221f, -0.408203f,
+0.219238f, -0.433594f, 0.1875f, -0.433594f, 0.16748f, -0.433594f, 0.15332f, -0.420166f,
+0.13916f, -0.406738f, 0.13916f, -0.38916f, 0.13916f, -0.375977f, 0.148926f, -0.36377f,
+0.164551f, -0.34375f, 0.236328f, -0.295166f, 0.308105f, -0.246582f, 0.330811f, -0.212646f,
+0.353516f, -0.178711f, 0.353516f, -0.136719f, 0.353516f, -0.0986328f, 0.334473f,
+-0.0620117f, 0.31543f, -0.0253906f, 0.280762f, -0.00585938f, 0.246094f, 0.0136719f,
+0.204102f, 0.0136719f, 0.171387f, 0.0136719f, 0.116699f, -0.00683594f, 0.102051f,
+-0.012207f, 0.0966797f, -0.012207f, 0.0805664f, -0.012207f, 0.0698242f, 0.012207f,
+0.0537109f, 0.012207f, 0.0458984f, -0.151855f, 0.0625f, -0.151855f, 0.0844727f, -0.0874023f,
+0.122803f, -0.0551758f, 0.161133f, -0.0229492f, 0.195312f, -0.0229492f, 0.21875f,
+-0.0229492f, 0.233643f, -0.0373535f, 0.248535f, -0.0517578f, 0.248535f, -0.0722656f,
+0.248535f, -0.0957031f, 0.233887f, -0.112793f, 0.219238f, -0.129883f, 0.168457f,
+-0.164551f, 0.09375f, -0.216309f, 0.0717773f, -0.243652f, 0.0395508f, -0.283691f,
+0.0395508f, -0.332031f, 0.0395508f, -0.384766f, 0.0759277f, -0.42749f, 0.112305f,
+-0.470215f, 0.181152f, -0.470215f, 0.218262f, -0.470215f, 0.25293f, -0.452148f, 0.266113f,
+-0.444824f, 0.274414f, -0.444824f, 0.283203f, -0.444824f, 0.288574f, -0.448486f,
+0.293945f, -0.452148f, 0.305664f, -0.469238f, 0.214844f, -0.623535f, 0.214844f, -0.456543f,
+0.323242f, -0.456543f, 0.323242f, -0.408203f, 0.214844f, -0.408203f, 0.214844f, -0.126465f,
+0.214844f, -0.0869141f, 0.218506f, -0.0754395f, 0.222168f, -0.0639648f, 0.231445f,
+-0.0568848f, 0.240723f, -0.0498047f, 0.248535f, -0.0498047f, 0.280273f, -0.0498047f,
+0.308594f, -0.0981445f, 0.323242f, -0.0874023f, 0.283691f, 0.00634766f, 0.194824f,
+0.00634766f, 0.151367f, 0.00634766f, 0.121338f, -0.0178223f, 0.0913086f, -0.0419922f,
+0.0830078f, -0.0717773f, 0.078125f, -0.0883789f, 0.078125f, -0.161621f, 0.078125f,
+-0.408203f, 0.0185547f, -0.408203f, 0.0185547f, -0.425293f, 0.0800781f, -0.46875f,
+0.123291f, -0.516602f, 0.166504f, -0.564453f, 0.19873f, -0.623535f, 0.474609f, -0.456543f,
+0.474609f, -0.0991211f, 0.474609f, -0.046875f, 0.484375f, -0.0339355f, 0.494141f,
+-0.0209961f, 0.523926f, -0.0175781f, 0.523926f, 0, 0.337891f, 0, 0.337891f, -0.0610352f,
+0.305176f, -0.0219727f, 0.272461f, -0.00415039f, 0.239746f, 0.0136719f, 0.199219f,
+0.0136719f, 0.160645f, 0.0136719f, 0.130615f, -0.0100098f, 0.100586f, -0.0336914f,
+0.090332f, -0.0654297f, 0.0800781f, -0.097168f, 0.0800781f, -0.17627f, 0.0800781f,
+-0.357422f, 0.0800781f, -0.40918f, 0.0705566f, -0.421875f, 0.0610352f, -0.43457f,
+0.0307617f, -0.438477f, 0.0307617f, -0.456543f, 0.216797f, -0.456543f, 0.216797f,
+-0.144531f, 0.216797f, -0.0957031f, 0.221436f, -0.081543f, 0.226074f, -0.0673828f,
+0.236084f, -0.0600586f, 0.246094f, -0.0527344f, 0.259277f, -0.0527344f, 0.276855f,
+-0.0527344f, 0.291016f, -0.0620117f, 0.310547f, -0.074707f, 0.337891f, -0.113281f,
+0.337891f, -0.357422f, 0.337891f, -0.40918f, 0.328369f, -0.421875f, 0.318848f, -0.43457f,
+0.288574f, -0.438477f, 0.288574f, -0.456543f, 0.239746f, 0.0136719f, 0.0859375f,
+-0.340332f, 0.0581055f, -0.404297f, 0.0424805f, -0.421387f, 0.03125f, -0.434082f,
+0.00927734f, -0.438477f, 0.00927734f, -0.456543f, 0.251953f, -0.456543f, 0.251953f,
+-0.438477f, 0.229004f, -0.438477f, 0.220703f, -0.430176f, 0.208984f, -0.419434f,
+0.208984f, -0.404785f, 0.208984f, -0.386719f, 0.230469f, -0.336914f, 0.305664f, -0.165527f,
+0.365723f, -0.313477f, 0.391602f, -0.376953f, 0.391602f, -0.40332f, 0.391602f, -0.418457f,
+0.380615f, -0.427979f, 0.369629f, -0.4375f, 0.341797f, -0.438477f, 0.341797f, -0.456543f,
+0.491211f, -0.456543f, 0.491211f, -0.438477f, 0.469727f, -0.435547f, 0.456055f, -0.422363f,
+0.442383f, -0.40918f, 0.415039f, -0.344727f, 0.262695f, 0.0136719f, 0.486328f, 0.0136719f,
+0.361328f, -0.321289f, 0.23877f, 0.0136719f, 0.213379f, 0.0136719f, 0.0917969f, -0.317383f,
+0.0644531f, -0.393066f, 0.0454102f, -0.416016f, 0.0332031f, -0.431641f, 0.00830078f,
+-0.438477f, 0.00830078f, -0.456543f, 0.23877f, -0.456543f, 0.23877f, -0.438477f,
+0.215332f, -0.438477f, 0.206543f, -0.431641f, 0.197754f, -0.424805f, 0.197754f, -0.416016f,
+0.197754f, -0.407715f, 0.213379f, -0.366211f, 0.280273f, -0.187988f, 0.344727f, -0.366211f,
+0.339844f, -0.37793f, 0.325195f, -0.414551f, 0.314209f, -0.424561f, 0.303223f, -0.43457f,
+0.280273f, -0.438477f, 0.280273f, -0.456543f, 0.51416f, -0.456543f, 0.51416f, -0.438477f,
+0.486816f, -0.437012f, 0.479492f, -0.430908f, 0.472168f, -0.424805f, 0.472168f, -0.413574f,
+0.472168f, -0.402832f, 0.486328f, -0.366211f, 0.550781f, -0.187988f, 0.609375f, -0.352051f,
+0.62207f, -0.387207f, 0.62207f, -0.399902f, 0.62207f, -0.418945f, 0.612793f, -0.427734f,
+0.603516f, -0.436523f, 0.57666f, -0.438477f, 0.57666f, -0.456543f, 0.711914f, -0.456543f,
+0.711914f, -0.438477f, 0.689453f, -0.435547f, 0.67627f, -0.422607f, 0.663086f, -0.409668f,
+0.64209f, -0.349121f, 0.51416f, 0.0136719f, 0.303711f, -0.279785f, 0.382812f, -0.129395f,
+0.423828f, -0.0507812f, 0.447754f, -0.0297852f, 0.460938f, -0.0185547f, 0.483887f,
+-0.0175781f, 0.483887f, 0, 0.229492f, 0, 0.229492f, -0.0175781f, 0.259277f, -0.0200195f,
+0.266357f, -0.0253906f, 0.273438f, -0.0307617f, 0.273438f, -0.0400391f, 0.273438f,
+-0.0537109f, 0.257812f, -0.0830078f, 0.218262f, -0.157227f, 0.18457f, -0.10791f,
+0.161621f, -0.0742188f, 0.158691f, -0.0678711f, 0.154785f, -0.0585938f, 0.154785f,
+-0.0512695f, 0.154785f, -0.0400391f, 0.159424f, -0.0324707f, 0.164062f, -0.0249023f,
+0.172119f, -0.0212402f, 0.180176f, -0.0175781f, 0.20166f, -0.0175781f, 0.20166f,
+0, 0.0229492f, 0, 0.0229492f, -0.0175781f, 0.0561523f, -0.0175781f, 0.0837402f, -0.0358887f,
+0.111328f, -0.0541992f, 0.164062f, -0.131836f, 0.20166f, -0.1875f, 0.123047f, -0.333008f,
+0.0844727f, -0.404297f, 0.0654297f, -0.42041f, 0.0463867f, -0.436523f, 0.0229492f,
+-0.438477f, 0.0229492f, -0.456543f, 0.275879f, -0.456543f, 0.275879f, -0.438477f,
+0.262695f, -0.437988f, 0.237305f, -0.429199f, 0.233398f, -0.425781f, 0.233398f, -0.417969f,
+0.233398f, -0.410645f, 0.23584f, -0.402832f, 0.237305f, -0.399414f, 0.249512f, -0.376465f,
+0.285156f, -0.310059f, 0.303711f, -0.336426f, 0.342773f, -0.390137f, 0.342773f, -0.411621f,
+0.342773f, -0.421875f, 0.334229f, -0.428955f, 0.325684f, -0.436035f, 0.303711f, -0.438477f,
+0.303711f, -0.456543f, 0.465332f, -0.456543f, 0.465332f, -0.438477f, 0.435547f, -0.4375f,
+0.409668f, -0.420166f, 0.383789f, -0.402832f, 0.351562f, -0.353027f, 0.243164f, 0.0185547f,
+0.0957031f, -0.319824f, 0.0625f, -0.396484f, 0.0466309f, -0.414062f, 0.0307617f,
+-0.431641f, 0.00830078f, -0.438477f, 0.00830078f, -0.456543f, 0.250977f, -0.456543f,
+0.250977f, -0.438477f, 0.227051f, -0.4375f, 0.217285f, -0.429199f, 0.20752f, -0.420898f,
+0.20752f, -0.40918f, 0.20752f, -0.390625f, 0.231934f, -0.335938f, 0.310059f, -0.157227f,
+0.363281f, -0.29541f, 0.39209f, -0.369141f, 0.39209f, -0.397949f, 0.39209f, -0.416016f,
+0.380127f, -0.426758f, 0.368164f, -0.4375f, 0.337891f, -0.438477f, 0.337891f, -0.456543f,
+0.490723f, -0.456543f, 0.490723f, -0.438477f, 0.468262f, -0.436035f, 0.454102f, -0.421143f,
+0.439941f, -0.40625f, 0.406738f, -0.319824f, 0.276367f, 0.0185547f, 0.227051f, 0.145508f,
+0.203125f, 0.174805f, 0.169434f, 0.21582f, 0.118652f, 0.21582f, 0.078125f, 0.21582f,
+0.0529785f, 0.192627f, 0.027832f, 0.169434f, 0.027832f, 0.136719f, 0.027832f, 0.108398f,
+0.045166f, 0.0898438f, 0.0625f, 0.0712891f, 0.0878906f, 0.0712891f, 0.112305f, 0.0712891f,
+0.127197f, 0.0869141f, 0.14209f, 0.102539f, 0.142578f, 0.135254f, 0.143066f, 0.153809f,
+0.146973f, 0.15918f, 0.150879f, 0.164551f, 0.158203f, 0.164551f, 0.169922f, 0.164551f,
+0.183105f, 0.150391f, 0.202637f, 0.129883f, 0.229004f, 0.0566406f, 0.407715f, 0,
+0.0102539f, 0, 0.0102539f, -0.0107422f, 0.26123f, -0.426758f, 0.187988f, -0.426758f,
+0.140625f, -0.426758f, 0.120117f, -0.418213f, 0.0996094f, -0.409668f, 0.0869141f,
+-0.390869f, 0.0742188f, -0.37207f, 0.0605469f, -0.32373f, 0.043457f, -0.32373f, 0.043457f,
+-0.456543f, 0.427734f, -0.456543f, 0.427734f, -0.443359f, 0.178711f, -0.03125f, 0.209961f,
+-0.03125f, 0.303711f, -0.03125f, 0.345215f, -0.0581055f, 0.386719f, -0.0849609f,
+0.407715f, -0.15625f, 0.421387f, -0.15625f
+};
+
+const unsigned char TimesNewRomankBoldVerbs[] = {
+6, 0, 1, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1,
+1, 2, 2, 2, 2, 2, 2, 5, 0, 1, 1, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 1, 1, 1, 5, 6,
+0, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 2,
+2, 2, 5, 0, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 5, 6,
+0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1,
+1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 5,
+6, 0, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 5, 6, 0, 1, 2,
+2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 6, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 1, 1, 5, 6, 0, 1, 1, 1, 1, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 1,
+1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0,
+1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 1, 5, 6, 0,
+1, 1, 1, 5, 0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1,
+1, 1, 2, 2, 2, 2, 5, 0, 1, 1, 5, 6, 0, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1,
+1, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 5, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 6, 0, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2,
+1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2,
+2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1,
+1, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1,
+2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1,
+1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1,
+1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 2, 2, 2,
+1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 2, 2, 2, 1,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 5, 6, 0, 1, 2, 2,
+1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1,
+2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 5, 6, 0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2,
+1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 2, 2, 2, 1,
+2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2,
+1, 2, 2, 2, 1, 1, 1, 5, 6, 0, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1,
+1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2,
+2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2,
+2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 5, 0, 1, 1, 2, 2, 2, 2, 2, 5, 6, 0,
+1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1,
+1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,
+1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 5, 6, 0, 1, 2,
+2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 2,
+2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2,
+2, 2, 1, 1, 2, 2, 2, 2, 1, 5, 6, 0, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1,
+1, 2, 2, 2, 5, 6, 0, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2,
+1, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 1, 5, 6, 0, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2,
+2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1,
+5, 6, 0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 1, 1, 1, 5, 6,
+0, 1, 1, 1, 5, 6, 0, 1, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2,
+5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 5, 0, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1,
+5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+5, 0, 2, 2, 2, 2, 2, 1, 5, 6, 0, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0,
+2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2,
+2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 1,
+5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 1, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 1, 5, 6,
+0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 1, 1, 1, 2, 2, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1,
+1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 1, 5, 6, 0, 1, 2, 2, 1, 1,
+1, 2, 2, 1, 2, 2, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2,
+2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1,
+1, 2, 2, 1, 2, 2, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2,
+2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 5, 0, 1, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1,
+2, 2, 1, 2, 2, 2, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 1, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 5, 6, 0, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 5, 6, 0, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1,
+2, 2, 2, 1, 1, 1, 2, 2, 1, 5, 6, 0, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1,
+2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 5, 6, 0, 1, 2, 2, 1, 1,
+1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2,
+2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 5, 6, 0, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2,
+2, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 1, 2,
+2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 5, 6
+};
+
+const unsigned TimesNewRomankBoldCharCodes[] = {
+32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
+119, 120, 121, 122
+};
+
+const SkFixed TimesNewRomankBoldWidths[] = {
+0x00004000, 0x00005540, 0x00008e20, 0x00008000, 0x00008000, 0x00010000, 0x0000d540,
+0x00004720, 0x00005540, 0x00005540, 0x00008000, 0x000091e0, 0x00004000, 0x00005540,
+0x00004000, 0x00004720, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000,
+0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00005540, 0x00005540,
+0x000091e0, 0x000091e0, 0x000091e0, 0x00008000, 0x0000ee20, 0x0000b8e0, 0x0000aac0,
+0x0000b8e0, 0x0000b8e0, 0x0000aac0, 0x00009c60, 0x0000c720, 0x0000c720, 0x000063a0,
+0x00008000, 0x0000c720, 0x0000aac0, 0x0000f1a0, 0x0000b8e0, 0x0000c720, 0x00009c60,
+0x0000c720, 0x0000b8e0, 0x00008e60, 0x0000aac0, 0x0000b8e0, 0x0000b8e0, 0x00010000,
+0x0000b8e0, 0x0000b8e0, 0x0000aac0, 0x00005540, 0x00004720, 0x00005540, 0x000094c0,
+0x00008000, 0x00005540, 0x00008000, 0x00008e60, 0x000071a0, 0x00008e60, 0x000071a0,
+0x00005540, 0x00008000, 0x00008e60, 0x00004720, 0x00005540, 0x00008e60, 0x00004720,
+0x0000d540, 0x00008e60, 0x00008000, 0x00008e60, 0x00008e60, 0x000071a0, 0x000063a0,
+0x00005540, 0x00008e60, 0x00008000, 0x0000b8e0, 0x00008000, 0x00008000, 0x000071a0
+};
+
+const int TimesNewRomankBoldCharCodesCount = (int) SK_ARRAY_COUNT(TimesNewRomankBoldCharCodes);
+
+const SkPaint::FontMetrics TimesNewRomankBoldMetrics = {
+0x08636967, -1.02588f, -0.891113f, 0.216309f, 0.306641f, 0.0424805f, 2.55811f, 2.57616e+24f,
+-0.558105f, 2, 0.470215f, 4.25072e-38f, 0.0952148f, 0.108887f
+};
+
+const SkScalar TimesNewRomankItalicPoints[] = {
+0.515137f, -0.677246f, 0.464844f, -0.126465f, 0.460938f, -0.0878906f, 0.460938f, -0.0756836f,
+0.460938f, -0.0561523f, 0.468262f, -0.0458984f, 0.477539f, -0.0317383f, 0.493408f,
+-0.0249023f, 0.509277f, -0.0180664f, 0.546875f, -0.0180664f, 0.541504f, 0, 0.280762f,
+0, 0.286133f, -0.0180664f, 0.297363f, -0.0180664f, 0.329102f, -0.0180664f, 0.349121f,
+-0.0317383f, 0.363281f, -0.0410156f, 0.371094f, -0.0625f, 0.376465f, -0.0776367f,
+0.381348f, -0.133789f, 0.38916f, -0.217773f, 0.199707f, -0.217773f, 0.132324f, -0.126465f,
+0.109375f, -0.0957031f, 0.103516f, -0.0822754f, 0.0976562f, -0.0688477f, 0.0976562f,
+-0.0571289f, 0.0976562f, -0.0415039f, 0.110352f, -0.0302734f, 0.123047f, -0.019043f,
+0.152344f, -0.0180664f, 0.146973f, 0, -0.0488281f, 0, -0.043457f, -0.0180664f, -0.00732422f,
+-0.0195312f, 0.0202637f, -0.0422363f, 0.0478516f, -0.0649414f, 0.102539f, -0.13916f,
+0.498047f, -0.677246f, 0.418457f, -0.514648f, 0.226562f, -0.253418f, 0.393066f, -0.253418f,
+0.246582f, -0.366699f, 0.552246f, -0.366699f, 0.600586f, -0.530273f, 0.614258f, -0.578125f,
+0.614258f, -0.604492f, 0.614258f, -0.617188f, 0.608154f, -0.626221f, 0.602051f, -0.635254f,
+0.589355f, -0.639648f, 0.57666f, -0.644043f, 0.539551f, -0.644043f, 0.544434f, -0.662109f,
+0.811035f, -0.662109f, 0.805176f, -0.644043f, 0.771484f, -0.644531f, 0.754883f, -0.637207f,
+0.731445f, -0.626953f, 0.720215f, -0.61084f, 0.704102f, -0.587891f, 0.6875f, -0.530273f,
+0.570801f, -0.130371f, 0.556152f, -0.0805664f, 0.556152f, -0.059082f, 0.556152f,
+-0.0405273f, 0.569092f, -0.0310059f, 0.582031f, -0.0214844f, 0.630859f, -0.0180664f,
+0.625488f, 0, 0.367676f, 0, 0.374512f, -0.0180664f, 0.412598f, -0.019043f, 0.425293f,
+-0.0249023f, 0.444824f, -0.0336914f, 0.453613f, -0.0473633f, 0.466309f, -0.0664062f,
+0.484863f, -0.130371f, 0.544434f, -0.333008f, 0.237305f, -0.333008f, 0.177246f, -0.130371f,
+0.163086f, -0.081543f, 0.163086f, -0.059082f, 0.163086f, -0.0405273f, 0.175781f,
+-0.0310059f, 0.188477f, -0.0214844f, 0.237305f, -0.0180664f, 0.233398f, 0, -0.0263672f,
+0, -0.0200195f, -0.0180664f, 0.0185547f, -0.019043f, 0.03125f, -0.0249023f, 0.0507812f,
+-0.0336914f, 0.0600586f, -0.0473633f, 0.0727539f, -0.0673828f, 0.0913086f, -0.130371f,
+0.208496f, -0.530273f, 0.222656f, -0.579102f, 0.222656f, -0.604492f, 0.222656f, -0.617188f,
+0.216553f, -0.626221f, 0.210449f, -0.635254f, 0.19751f, -0.639648f, 0.18457f, -0.644043f,
+0.146973f, -0.644043f, 0.152832f, -0.662109f, 0.414062f, -0.662109f, 0.408691f, -0.644043f,
+0.375977f, -0.644531f, 0.360352f, -0.637207f, 0.337402f, -0.627441f, 0.32666f, -0.611328f,
+0.312012f, -0.589844f, 0.294434f, -0.530273f, 0.146484f, -0.662109f, 0.649414f, -0.662109f,
+0.595215f, -0.486328f, 0.57666f, -0.486328f, 0.585938f, -0.524902f, 0.585938f, -0.555176f,
+0.585938f, -0.59082f, 0.563965f, -0.608887f, 0.547363f, -0.622559f, 0.478516f, -0.622559f,
+0.42627f, -0.622559f, 0.29541f, -0.166504f, 0.270508f, -0.0805664f, 0.270508f, -0.0605469f,
+0.270508f, -0.0419922f, 0.286133f, -0.0300293f, 0.301758f, -0.0180664f, 0.341309f,
+-0.0180664f, 0.36377f, -0.0180664f, 0.35791f, 0, 0.0698242f, 0, 0.0751953f, -0.0180664f,
+0.0878906f, -0.0180664f, 0.125977f, -0.0180664f, 0.146484f, -0.0302734f, 0.160645f,
+-0.0385742f, 0.172119f, -0.0603027f, 0.183594f, -0.0820312f, 0.204102f, -0.152344f,
+0.341309f, -0.622559f, 0.301758f, -0.622559f, 0.244629f, -0.622559f, 0.209717f, -0.60791f,
+0.174805f, -0.593262f, 0.15332f, -0.56543f, 0.131836f, -0.537598f, 0.118164f, -0.486328f,
+0.100098f, -0.486328f, 0.135254f, 0.0151367f, 0.192383f, -0.536621f, 0.195801f, -0.568359f,
+0.195801f, -0.585449f, 0.195801f, -0.61377f, 0.179688f, -0.628418f, 0.163574f, -0.643066f,
+0.121582f, -0.644043f, 0.126953f, -0.662109f, 0.375f, -0.662109f, 0.369629f, -0.644043f,
+0.319824f, -0.644531f, 0.301514f, -0.626221f, 0.283203f, -0.60791f, 0.276367f, -0.536621f,
+0.239746f, -0.179199f, 0.491211f, -0.567383f, 0.491699f, -0.577148f, 0.491699f, -0.583984f,
+0.491699f, -0.611328f, 0.475586f, -0.625977f, 0.459473f, -0.640625f, 0.40625f, -0.644043f,
+0.410156f, -0.662109f, 0.678223f, -0.662109f, 0.672852f, -0.644043f, 0.626465f, -0.643555f,
+0.610352f, -0.63623f, 0.598633f, -0.630859f, 0.590576f, -0.618896f, 0.58252f, -0.606934f,
+0.577637f, -0.578125f, 0.576172f, -0.569824f, 0.565674f, -0.464844f, 0.555176f, -0.359863f,
+0.53418f, -0.179199f, 0.743652f, -0.497559f, 0.777832f, -0.549805f, 0.786621f, -0.570801f,
+0.79541f, -0.591797f, 0.79541f, -0.606445f, 0.79541f, -0.620117f, 0.783691f, -0.630615f,
+0.771973f, -0.641113f, 0.743652f, -0.644043f, 0.747559f, -0.662109f, 0.943848f, -0.662109f,
+0.938965f, -0.644043f, 0.913086f, -0.64209f, 0.893066f, -0.631348f, 0.873047f, -0.620605f,
+0.845703f, -0.590332f, 0.830078f, -0.572754f, 0.78125f, -0.497559f, 0.44873f, 0.0151367f,
+0.430664f, 0.0151367f, 0.484375f, -0.497559f, 0.151855f, 0.0151367f, 0.349609f, -0.352051f,
+0.475586f, -0.52832f, 0.524414f, -0.597168f, 0.524414f, -0.616211f, 0.524414f, -0.626953f,
+0.513916f, -0.634033f, 0.503418f, -0.641113f, 0.454102f, -0.644043f, 0.458984f, -0.662109f,
+0.666992f, -0.662109f, 0.663086f, -0.644043f, 0.632812f, -0.640137f, 0.621582f, -0.635742f,
+0.604004f, -0.628418f, 0.586914f, -0.612793f, 0.563965f, -0.592285f, 0.520508f, -0.532227f,
+0.358398f, -0.308594f, 0.30957f, -0.14502f, 0.291504f, -0.0834961f, 0.291504f, -0.0600586f,
+0.291504f, -0.0449219f, 0.297119f, -0.0371094f, 0.302734f, -0.0292969f, 0.316895f,
+-0.0244141f, 0.335449f, -0.0185547f, 0.373535f, -0.0180664f, 0.368652f, 0, 0.0898438f,
+0, 0.0957031f, -0.0180664f, 0.137207f, -0.019043f, 0.150879f, -0.0249023f, 0.172852f,
+-0.0336914f, 0.183594f, -0.0483398f, 0.200195f, -0.0708008f, 0.217773f, -0.128906f,
+0.275879f, -0.322266f, 0.205078f, -0.550781f, 0.186035f, -0.611328f, 0.170166f, -0.625977f,
+0.154297f, -0.640625f, 0.114746f, -0.644043f, 0.119629f, -0.662109f, 0.364258f, -0.662109f,
+0.358398f, -0.644043f, 0.3125f, -0.640625f, 0.306152f, -0.638184f, 0.29541f, -0.634766f,
+0.288574f, -0.624512f, 0.281738f, -0.614258f, 0.281738f, -0.600586f, 0.281738f, -0.580566f,
+0.295898f, -0.532227f, 0.469238f, -0.441895f, 0.374023f, -0.11084f, 0.363281f, -0.0664062f,
+0.361816f, -0.0600586f, 0.361816f, -0.0556641f, 0.361816f, -0.0478516f, 0.366699f,
+-0.0419922f, 0.370605f, -0.0375977f, 0.376465f, -0.0375977f, 0.382812f, -0.0375977f,
+0.393066f, -0.0454102f, 0.412109f, -0.0595703f, 0.443848f, -0.104004f, 0.460449f,
+-0.0922852f, 0.426758f, -0.0415039f, 0.391113f, -0.0148926f, 0.355469f, 0.0117188f,
+0.325195f, 0.0117188f, 0.304199f, 0.0117188f, 0.293701f, 0.0012207f, 0.283203f, -0.00927734f,
+0.283203f, -0.0292969f, 0.283203f, -0.0532227f, 0.293945f, -0.0922852f, 0.304199f,
+-0.128906f, 0.240234f, -0.0454102f, 0.186523f, -0.012207f, 0.147949f, 0.0117188f,
+0.11084f, 0.0117188f, 0.0751953f, 0.0117188f, 0.0493164f, -0.0178223f, 0.0234375f,
+-0.0473633f, 0.0234375f, -0.0991211f, 0.0234375f, -0.176758f, 0.0700684f, -0.262939f,
+0.116699f, -0.349121f, 0.188477f, -0.400879f, 0.244629f, -0.441895f, 0.294434f, -0.441895f,
+0.324219f, -0.441895f, 0.343994f, -0.42627f, 0.36377f, -0.410645f, 0.374023f, -0.374512f,
+0.391602f, -0.430176f, 0.29541f, -0.416504f, 0.26416f, -0.416504f, 0.229004f, -0.387207f,
+0.179199f, -0.345703f, 0.140381f, -0.26416f, 0.101562f, -0.182617f, 0.101562f, -0.116699f,
+0.101562f, -0.0834961f, 0.118164f, -0.064209f, 0.134766f, -0.0449219f, 0.15625f,
+-0.0449219f, 0.209473f, -0.0449219f, 0.271973f, -0.123535f, 0.355469f, -0.228027f,
+0.355469f, -0.337891f, 0.355469f, -0.379395f, 0.339355f, -0.397949f, 0.323242f, -0.416504f,
+0.29541f, -0.416504f, 0.288574f, -0.694336f, 0.192383f, -0.356934f, 0.239258f, -0.405762f,
+0.27417f, -0.423828f, 0.309082f, -0.441895f, 0.347168f, -0.441895f, 0.400879f, -0.441895f,
+0.435059f, -0.40625f, 0.469238f, -0.370605f, 0.469238f, -0.30957f, 0.469238f, -0.230957f,
+0.424316f, -0.153076f, 0.379395f, -0.0751953f, 0.311523f, -0.0317383f, 0.243652f,
+0.0117188f, 0.177734f, 0.0117188f, 0.104004f, 0.0117188f, 0.0263672f, -0.043457f,
+0.174805f, -0.554688f, 0.191895f, -0.61377f, 0.191895f, -0.624023f, 0.191895f, -0.636719f,
+0.184082f, -0.643066f, 0.172852f, -0.651855f, 0.150879f, -0.651855f, 0.140625f, -0.651855f,
+0.119629f, -0.648438f, 0.119629f, -0.666992f, 0.0996094f, -0.0380859f, 0.148438f,
+-0.0112305f, 0.185547f, -0.0112305f, 0.228516f, -0.0112305f, 0.274658f, -0.0427246f,
+0.320801f, -0.0742188f, 0.354736f, -0.148926f, 0.388672f, -0.223633f, 0.388672f,
+-0.299805f, 0.388672f, -0.344727f, 0.366455f, -0.370117f, 0.344238f, -0.395508f,
+0.313965f, -0.395508f, 0.268555f, -0.395508f, 0.225098f, -0.359131f, 0.181641f, -0.322754f,
+0.163086f, -0.257812f, 0.119141f, -0.184082f, 0.115723f, -0.159668f, 0.115723f, -0.143555f,
+0.115723f, -0.100098f, 0.146484f, -0.0695801f, 0.177246f, -0.0390625f, 0.221191f,
+-0.0390625f, 0.256348f, -0.0390625f, 0.288818f, -0.0534668f, 0.321289f, -0.0678711f,
+0.385254f, -0.117188f, 0.395508f, -0.103027f, 0.279785f, 0.0117188f, 0.174805f, 0.0117188f,
+0.103516f, 0.0117188f, 0.0673828f, -0.0332031f, 0.03125f, -0.078125f, 0.03125f, -0.132324f,
+0.03125f, -0.205078f, 0.0761719f, -0.28125f, 0.121094f, -0.357422f, 0.188965f, -0.399658f,
+0.256836f, -0.441895f, 0.328613f, -0.441895f, 0.380371f, -0.441895f, 0.405273f, -0.420898f,
+0.430176f, -0.399902f, 0.430176f, -0.371094f, 0.430176f, -0.330566f, 0.397949f, -0.293457f,
+0.355469f, -0.245117f, 0.272949f, -0.215332f, 0.218262f, -0.195312f, 0.119141f, -0.184082f,
+0.122559f, -0.208008f, 0.194824f, -0.216309f, 0.240234f, -0.236328f, 0.300293f, -0.263184f,
+0.330322f, -0.300537f, 0.360352f, -0.337891f, 0.360352f, -0.371582f, 0.360352f, -0.39209f,
+0.347412f, -0.404785f, 0.334473f, -0.41748f, 0.310547f, -0.41748f, 0.260742f, -0.41748f,
+0.204834f, -0.364502f, 0.148926f, -0.311523f, 0.122559f, -0.208008f, 0.296387f, -0.430176f,
+0.287598f, -0.397949f, 0.216309f, -0.397949f, 0.162598f, -0.18457f, 0.126953f, -0.043457f,
+0.0908203f, 0.0336914f, 0.0395508f, 0.142578f, -0.0195312f, 0.184082f, -0.0644531f,
+0.21582f, -0.109375f, 0.21582f, -0.138672f, 0.21582f, -0.15918f, 0.198242f, -0.174316f,
+0.186035f, -0.174316f, 0.166504f, -0.174316f, 0.150879f, -0.161865f, 0.139404f, -0.149414f,
+0.12793f, -0.131348f, 0.12793f, -0.118164f, 0.12793f, -0.109131f, 0.13623f, -0.100098f,
+0.144531f, -0.100098f, 0.155273f, -0.100098f, 0.166016f, -0.110352f, 0.175293f, -0.118164f,
+0.182129f, -0.118164f, 0.185547f, -0.118164f, 0.189941f, -0.114746f, 0.192383f, -0.110352f,
+0.195801f, -0.101074f, 0.195801f, -0.0800781f, 0.195801f, -0.0568848f, 0.182617f,
+-0.0336914f, 0.169434f, -0.015625f, 0.143311f, 0.00244141f, 0.117188f, 0.0185547f,
+0.0678711f, 0.0253906f, 0.0473633f, 0.0551758f, -0.0673828f, 0.140137f, -0.397949f,
+0.0551758f, -0.397949f, 0.0620117f, -0.430176f, 0.102539f, -0.430176f, 0.118652f,
+-0.435791f, 0.134766f, -0.441406f, 0.148193f, -0.457275f, 0.161621f, -0.473145f,
+0.183105f, -0.516602f, 0.211914f, -0.575195f, 0.238281f, -0.607422f, 0.274414f, -0.650879f,
+0.314209f, -0.672607f, 0.354004f, -0.694336f, 0.38916f, -0.694336f, 0.42627f, -0.694336f,
+0.44873f, -0.675537f, 0.471191f, -0.656738f, 0.471191f, -0.634766f, 0.471191f, -0.617676f,
+0.459961f, -0.605957f, 0.44873f, -0.594238f, 0.431152f, -0.594238f, 0.416016f, -0.594238f,
+0.406494f, -0.603027f, 0.396973f, -0.611816f, 0.396973f, -0.624023f, 0.396973f, -0.631836f,
+0.40332f, -0.643311f, 0.409668f, -0.654785f, 0.409668f, -0.658691f, 0.409668f, -0.665527f,
+0.405273f, -0.668945f, 0.398926f, -0.673828f, 0.386719f, -0.673828f, 0.355957f, -0.673828f,
+0.331543f, -0.654297f, 0.298828f, -0.628418f, 0.272949f, -0.573242f, 0.259766f, -0.544434f,
+0.224609f, -0.430176f, 0.520996f, -0.411621f, 0.506836f, -0.36084f, 0.425293f, -0.36084f,
+0.43457f, -0.334473f, 0.43457f, -0.311523f, 0.43457f, -0.24707f, 0.379883f, -0.196777f,
+0.324707f, -0.146484f, 0.228516f, -0.141113f, 0.176758f, -0.125488f, 0.150879f, -0.104004f,
+0.141113f, -0.0961914f, 0.141113f, -0.0878906f, 0.141113f, -0.078125f, 0.149902f,
+-0.0700684f, 0.158691f, -0.0620117f, 0.194336f, -0.0537109f, 0.289062f, -0.0317383f,
+0.367676f, -0.0131836f, 0.393066f, 0.012207f, 0.417969f, 0.0380859f, 0.417969f, 0.0717773f,
+0.417969f, 0.111816f, 0.388428f, 0.14502f, 0.358887f, 0.178223f, 0.302002f, 0.197021f,
+0.245117f, 0.21582f, 0.17627f, 0.21582f, 0.115723f, 0.21582f, 0.065918f, 0.201416f,
+0.0161133f, 0.187012f, -0.00537109f, 0.162598f, -0.0268555f, 0.138184f, -0.0268555f,
+0.112305f, -0.0268555f, 0.0913086f, -0.0129395f, 0.0686035f, 0.000976562f, 0.0458984f,
+0.0219727f, 0.03125f, 0.0351562f, 0.0219727f, 0.0966797f, -0.0126953f, 0.0742188f,
+-0.0302734f, 0.0742188f, -0.0512695f, 0.0742188f, -0.0708008f, 0.0939941f, -0.0927734f,
+0.11377f, -0.114746f, 0.177734f, -0.141113f, 0.124023f, -0.151367f, 0.0925293f, -0.186035f,
+0.0610352f, -0.220703f, 0.0610352f, -0.263184f, 0.0610352f, -0.33252f, 0.121826f,
+-0.387207f, 0.182617f, -0.441895f, 0.283691f, -0.441895f, 0.320312f, -0.441895f,
+0.34375f, -0.43457f, 0.367188f, -0.427246f, 0.38916f, -0.411621f, 0.351562f, -0.334961f,
+0.351562f, -0.374023f, 0.329834f, -0.396484f, 0.308105f, -0.418945f, 0.272949f, -0.418945f,
+0.217773f, -0.418945f, 0.181885f, -0.363525f, 0.145996f, -0.308105f, 0.145996f, -0.248047f,
+0.145996f, -0.210449f, 0.168945f, -0.186523f, 0.191895f, -0.162598f, 0.224609f, -0.162598f,
+0.250488f, -0.162598f, 0.274658f, -0.176758f, 0.298828f, -0.190918f, 0.31543f, -0.21582f,
+0.332031f, -0.240723f, 0.341797f, -0.279297f, 0.351562f, -0.317871f, 0.351562f, -0.334961f,
+0.117676f, 0, 0.078125f, 0.0180664f, 0.0578613f, 0.0463867f, 0.0375977f, 0.074707f,
+0.0375977f, 0.102051f, 0.0375977f, 0.134277f, 0.0668945f, 0.155273f, 0.108887f, 0.185547f,
+0.189941f, 0.185547f, 0.259766f, 0.185547f, 0.309326f, 0.161865f, 0.358887f, 0.138184f,
+0.358887f, 0.100586f, 0.358887f, 0.081543f, 0.340576f, 0.0644531f, 0.322266f, 0.0473633f,
+0.269531f, 0.0366211f, 0.240723f, 0.0307617f, 0.117676f, 0, 0.216797f, -0.441895f,
+0.15332f, -0.22168f, 0.195801f, -0.299316f, 0.225586f, -0.338379f, 0.271973f, -0.398926f,
+0.315918f, -0.42627f, 0.341797f, -0.441895f, 0.370117f, -0.441895f, 0.394531f, -0.441895f,
+0.410645f, -0.42627f, 0.426758f, -0.410645f, 0.426758f, -0.38623f, 0.426758f, -0.362305f,
+0.415527f, -0.32373f, 0.380859f, -0.199707f, 0.460449f, -0.348633f, 0.531738f, -0.408691f,
+0.571289f, -0.441895f, 0.609863f, -0.441895f, 0.632324f, -0.441895f, 0.646729f, -0.426514f,
+0.661133f, -0.411133f, 0.661133f, -0.378906f, 0.661133f, -0.350586f, 0.652344f, -0.318848f,
+0.598633f, -0.128906f, 0.581055f, -0.0668945f, 0.581055f, -0.0600586f, 0.581055f,
+-0.0532227f, 0.585449f, -0.0483398f, 0.588379f, -0.0449219f, 0.593262f, -0.0449219f,
+0.598145f, -0.0449219f, 0.610352f, -0.0541992f, 0.638184f, -0.0756836f, 0.662598f,
+-0.11084f, 0.678711f, -0.100586f, 0.666504f, -0.0810547f, 0.635498f, -0.046875f,
+0.604492f, -0.0126953f, 0.58252f, -0.000488281f, 0.560547f, 0.0117188f, 0.541992f,
+0.0117188f, 0.524902f, 0.0117188f, 0.513428f, 0, 0.501953f, -0.0117188f, 0.501953f,
+-0.0288086f, 0.501953f, -0.0522461f, 0.521973f, -0.123047f, 0.566406f, -0.279785f,
+0.581543f, -0.333984f, 0.58252f, -0.339844f, 0.583984f, -0.349121f, 0.583984f, -0.35791f,
+0.583984f, -0.370117f, 0.578613f, -0.376953f, 0.572754f, -0.383789f, 0.56543f, -0.383789f,
+0.544922f, -0.383789f, 0.521973f, -0.362793f, 0.45459f, -0.300781f, 0.395996f, -0.188965f,
+0.357422f, -0.115234f, 0.32373f, 0, 0.25f, 0, 0.333496f, -0.29541f, 0.347168f, -0.343262f,
+0.347168f, -0.359375f, 0.347168f, -0.372559f, 0.341797f, -0.378906f, 0.336426f, -0.385254f,
+0.328613f, -0.385254f, 0.3125f, -0.385254f, 0.294434f, -0.373535f, 0.265137f, -0.354492f,
+0.218994f, -0.291992f, 0.172852f, -0.229492f, 0.147461f, -0.172363f, 0.135254f, -0.145508f,
+0.0893555f, 0, 0.0170898f, 0, 0.107422f, -0.316406f, 0.119141f, -0.357422f, 0.122559f,
+-0.366699f, 0.122559f, -0.371094f, 0.122559f, -0.381836f, 0.112793f, -0.390381f,
+0.103027f, -0.398926f, 0.0878906f, -0.398926f, 0.081543f, -0.398926f, 0.0527344f,
+-0.393066f, 0.0483398f, -0.411133f, 0.220703f, -0.441895f, 0.155762f, -0.219727f,
+0.24707f, -0.355957f, 0.295654f, -0.398926f, 0.344238f, -0.441895f, 0.38916f, -0.441895f,
+0.413574f, -0.441895f, 0.429443f, -0.425781f, 0.445312f, -0.409668f, 0.445312f, -0.383789f,
+0.445312f, -0.354492f, 0.431152f, -0.305664f, 0.371582f, -0.100098f, 0.361328f, -0.0644531f,
+0.361328f, -0.0566406f, 0.361328f, -0.0498047f, 0.365234f, -0.045166f, 0.369141f,
+-0.0405273f, 0.373535f, -0.0405273f, 0.379395f, -0.0405273f, 0.387695f, -0.046875f,
+0.413574f, -0.0673828f, 0.444336f, -0.109375f, 0.459473f, -0.100098f, 0.414062f,
+-0.0351562f, 0.373535f, -0.00732422f, 0.345215f, 0.0117188f, 0.322754f, 0.0117188f,
+0.304688f, 0.0117188f, 0.293945f, 0.000732422f, 0.283203f, -0.0102539f, 0.283203f,
+-0.0288086f, 0.283203f, -0.0522461f, 0.299805f, -0.109375f, 0.356445f, -0.305664f,
+0.367188f, -0.342285f, 0.367188f, -0.362793f, 0.367188f, -0.372559f, 0.36084f, -0.378662f,
+0.354492f, -0.384766f, 0.345215f, -0.384766f, 0.331543f, -0.384766f, 0.3125f, -0.373047f,
+0.276367f, -0.351074f, 0.237305f, -0.300537f, 0.198242f, -0.25f, 0.154785f, -0.171387f,
+0.131836f, -0.129883f, 0.116699f, -0.0805664f, 0.0922852f, 0, 0.019043f, 0, 0.10791f,
+-0.305664f, 0.123535f, -0.36084f, 0.123535f, -0.37207f, 0.123535f, -0.382812f, 0.11499f,
+-0.390869f, 0.106445f, -0.398926f, 0.09375f, -0.398926f, 0.0878906f, -0.398926f,
+0.0732422f, -0.396973f, 0.0546875f, -0.394043f, 0.0517578f, -0.411621f, 0.462402f,
+-0.289062f, 0.462402f, -0.21582f, 0.423584f, -0.144043f, 0.384766f, -0.0722656f,
+0.31543f, -0.0302734f, 0.246094f, 0.0117188f, 0.180664f, 0.0117188f, 0.11377f, 0.0117188f,
+0.0715332f, -0.0310059f, 0.0292969f, -0.0737305f, 0.0292969f, -0.141602f, 0.0292969f,
+-0.213379f, 0.0705566f, -0.285645f, 0.111816f, -0.35791f, 0.180908f, -0.399902f,
+0.25f, -0.441895f, 0.314453f, -0.441895f, 0.378906f, -0.441895f, 0.420654f, -0.399414f,
+0.462402f, -0.356934f, 0.462402f, -0.289062f, 0.381348f, -0.322754f, 0.381348f, -0.368164f,
+0.359131f, -0.392334f, 0.336914f, -0.416504f, 0.301758f, -0.416504f, 0.22998f, -0.416504f,
+0.169678f, -0.313721f, 0.109375f, -0.210938f, 0.109375f, -0.109375f, 0.109375f, -0.0629883f,
+0.132812f, -0.0378418f, 0.15625f, -0.0126953f, 0.191895f, -0.0126953f, 0.260742f,
+-0.0126953f, 0.321045f, -0.11499f, 0.381348f, -0.217285f, 0.381348f, -0.322754f,
+0.221191f, -0.441895f, 0.1875f, -0.32959f, 0.240723f, -0.39209f, 0.282471f, -0.416992f,
+0.324219f, -0.441895f, 0.367676f, -0.441895f, 0.411133f, -0.441895f, 0.441895f, -0.407471f,
+0.472656f, -0.373047f, 0.472656f, -0.317871f, 0.472656f, -0.210449f, 0.385254f, -0.0993652f,
+0.297852f, 0.0117188f, 0.181641f, 0.0117188f, 0.157227f, 0.0117188f, 0.138428f, 0.00634766f,
+0.119629f, 0.000976562f, 0.0961914f, -0.0126953f, 0.0605469f, 0.113281f, 0.0498047f,
+0.150391f, 0.0498047f, 0.161621f, 0.0498047f, 0.172363f, 0.0554199f, 0.179932f, 0.0610352f,
+0.1875f, 0.0737305f, 0.19165f, 0.0864258f, 0.195801f, 0.124023f, 0.195801f, 0.119629f,
+0.213867f, -0.110352f, 0.213867f, -0.105469f, 0.195801f, -0.0600586f, 0.193848f,
+-0.0441895f, 0.180176f, -0.0283203f, 0.166504f, -0.0107422f, 0.104492f, 0.112793f,
+-0.323242f, 0.124023f, -0.36377f, 0.124023f, -0.373535f, 0.124023f, -0.386719f, 0.116455f,
+-0.394043f, 0.108887f, -0.401367f, 0.0932617f, -0.401367f, 0.0791016f, -0.401367f,
+0.0537109f, -0.397949f, 0.0537109f, -0.416992f, 0.107422f, -0.0512695f, 0.137695f,
+-0.0151367f, 0.188965f, -0.0151367f, 0.214355f, -0.0151367f, 0.240723f, -0.0292969f,
+0.26709f, -0.043457f, 0.292236f, -0.0712891f, 0.317383f, -0.0991211f, 0.337402f,
+-0.135498f, 0.357422f, -0.171875f, 0.373291f, -0.221191f, 0.38916f, -0.270508f, 0.38916f,
+-0.318848f, 0.38916f, -0.35791f, 0.371338f, -0.378662f, 0.353516f, -0.399414f, 0.32959f,
+-0.399414f, 0.276855f, -0.399414f, 0.225342f, -0.338867f, 0.173828f, -0.27832f, 0.149902f,
+-0.197266f, 0.0522461f, -0.414551f, 0.220703f, -0.441895f, 0.150391f, -0.20459f,
+0.23584f, -0.350586f, 0.305664f, -0.408691f, 0.345215f, -0.441895f, 0.370117f, -0.441895f,
+0.38623f, -0.441895f, 0.395508f, -0.432373f, 0.404785f, -0.422852f, 0.404785f, -0.404785f,
+0.404785f, -0.372559f, 0.388184f, -0.343262f, 0.376465f, -0.321289f, 0.354492f, -0.321289f,
+0.343262f, -0.321289f, 0.335205f, -0.328613f, 0.327148f, -0.335938f, 0.325195f, -0.351074f,
+0.324219f, -0.360352f, 0.320801f, -0.363281f, 0.316895f, -0.367188f, 0.311523f, -0.367188f,
+0.303223f, -0.367188f, 0.295898f, -0.363281f, 0.283203f, -0.356445f, 0.257324f, -0.325195f,
+0.216797f, -0.277344f, 0.169434f, -0.201172f, 0.148926f, -0.168945f, 0.134277f, -0.128418f,
+0.11377f, -0.0727539f, 0.11084f, -0.0615234f, 0.0952148f, 0, 0.0205078f, 0, 0.11084f,
+-0.303223f, 0.126465f, -0.355957f, 0.126465f, -0.378418f, 0.126465f, -0.387207f,
+0.119141f, -0.393066f, 0.109375f, -0.400879f, 0.0932617f, -0.400879f, 0.0830078f,
+-0.400879f, 0.0556641f, -0.396484f, 0.362793f, -0.441895f, 0.333008f, -0.291992f,
+0.314941f, -0.291992f, 0.3125f, -0.357422f, 0.287109f, -0.387207f, 0.261719f, -0.416992f,
+0.224121f, -0.416992f, 0.193848f, -0.416992f, 0.176025f, -0.400391f, 0.158203f, -0.383789f,
+0.158203f, -0.360352f, 0.158203f, -0.344238f, 0.165283f, -0.32959f, 0.172363f, -0.314941f,
+0.196289f, -0.288574f, 0.259766f, -0.219238f, 0.27832f, -0.184082f, 0.296875f, -0.148926f,
+0.296875f, -0.117676f, 0.296875f, -0.0668945f, 0.254639f, -0.0275879f, 0.212402f,
+0.0117188f, 0.147949f, 0.0117188f, 0.112793f, 0.0117188f, 0.0668945f, -0.00488281f,
+0.0507812f, -0.0107422f, 0.0419922f, -0.0107422f, 0.0200195f, -0.0107422f, 0.00878906f,
+0.0117188f, -0.00927734f, 0.0117188f, 0.0205078f, -0.146484f, 0.0385742f, -0.146484f,
+0.0415039f, -0.0722656f, 0.0693359f, -0.0415039f, 0.097168f, -0.0107422f, 0.145508f,
+-0.0107422f, 0.182617f, -0.0107422f, 0.204346f, -0.0314941f, 0.226074f, -0.0522461f,
+0.226074f, -0.0825195f, 0.226074f, -0.102051f, 0.218262f, -0.118652f, 0.20459f, -0.147949f,
+0.160889f, -0.199707f, 0.117188f, -0.251465f, 0.104736f, -0.277344f, 0.0922852f,
+-0.303223f, 0.0922852f, -0.329102f, 0.0922852f, -0.376465f, 0.126709f, -0.40918f,
+0.161133f, -0.441895f, 0.215332f, -0.441895f, 0.230957f, -0.441895f, 0.243652f, -0.439453f,
+0.250488f, -0.437988f, 0.275635f, -0.428467f, 0.300781f, -0.418945f, 0.309082f, -0.418945f,
+0.330078f, -0.418945f, 0.344238f, -0.441895f, 0.470703f, -0.430176f, 0.385742f, -0.13916f,
+0.366699f, -0.0742188f, 0.366699f, -0.0571289f, 0.366699f, -0.0483398f, 0.369873f,
+-0.0441895f, 0.373047f, -0.0400391f, 0.378418f, -0.0400391f, 0.386719f, -0.0400391f,
+0.396729f, -0.0476074f, 0.406738f, -0.0551758f, 0.447266f, -0.10791f, 0.461914f,
+-0.0966797f, 0.42334f, -0.0356445f, 0.382812f, -0.00683594f, 0.355957f, 0.0117188f,
+0.331055f, 0.0117188f, 0.312012f, 0.0117188f, 0.30127f, 0.000976562f, 0.290527f,
+-0.00976562f, 0.290527f, -0.0268555f, 0.290527f, -0.043457f, 0.296875f, -0.0708008f,
+0.304688f, -0.106934f, 0.341309f, -0.228027f, 0.258301f, -0.0917969f, 0.202393f,
+-0.0400391f, 0.146484f, 0.0117188f, 0.0986328f, 0.0117188f, 0.0761719f, 0.0117188f,
+0.0605469f, -0.00390625f, 0.0449219f, -0.0195312f, 0.0449219f, -0.043457f, 0.0449219f,
+-0.0800781f, 0.0664062f, -0.155762f, 0.108887f, -0.306641f, 0.124512f, -0.36084f,
+0.124512f, -0.374023f, 0.124512f, -0.379883f, 0.120361f, -0.384033f, 0.116211f, -0.388184f,
+0.111328f, -0.388184f, 0.101074f, -0.388184f, 0.0908203f, -0.380859f, 0.0805664f,
+-0.373535f, 0.0444336f, -0.32666f, 0.0292969f, -0.337402f, 0.065918f, -0.394043f,
+0.106934f, -0.420898f, 0.138184f, -0.441895f, 0.164551f, -0.441895f, 0.182617f, -0.441895f,
+0.194092f, -0.43042f, 0.205566f, -0.418945f, 0.205566f, -0.400879f, 0.205566f, -0.374512f,
+0.186035f, -0.306641f, 0.140137f, -0.148926f, 0.121094f, -0.0844727f, 0.121094f,
+-0.0673828f, 0.121094f, -0.0581055f, 0.127197f, -0.0524902f, 0.133301f, -0.046875f,
+0.143555f, -0.046875f, 0.159668f, -0.046875f, 0.185547f, -0.0629883f, 0.211426f,
+-0.0791016f, 0.254639f, -0.134521f, 0.297852f, -0.189941f, 0.325928f, -0.238525f,
+0.354004f, -0.287109f, 0.385742f, -0.393066f, 0.396484f, -0.430176f, 0.159668f, -0.441895f,
+0.17627f, -0.413574f, 0.182617f, -0.388916f, 0.188965f, -0.364258f, 0.195312f, -0.291992f,
+0.216797f, -0.0517578f, 0.246094f, -0.0869141f, 0.301758f, -0.163086f, 0.328613f,
+-0.200195f, 0.368164f, -0.26416f, 0.39209f, -0.303223f, 0.397461f, -0.318848f, 0.400391f,
+-0.32666f, 0.400391f, -0.334961f, 0.400391f, -0.340332f, 0.396973f, -0.34375f, 0.393555f,
+-0.347168f, 0.37915f, -0.351807f, 0.364746f, -0.356445f, 0.355225f, -0.368896f, 0.345703f,
+-0.381348f, 0.345703f, -0.397461f, 0.345703f, -0.41748f, 0.357422f, -0.429688f, 0.369141f,
+-0.441895f, 0.386719f, -0.441895f, 0.408203f, -0.441895f, 0.42334f, -0.424072f, 0.438477f,
+-0.40625f, 0.438477f, -0.375f, 0.438477f, -0.336426f, 0.412109f, -0.286865f, 0.385742f,
+-0.237305f, 0.310547f, -0.134766f, 0.235352f, -0.0322266f, 0.128418f, 0.0888672f,
+0.0546875f, 0.172363f, 0.019043f, 0.194092f, -0.0166016f, 0.21582f, -0.0419922f,
+0.21582f, -0.0571289f, 0.21582f, -0.0686035f, 0.204346f, -0.0800781f, 0.192871f,
+-0.0800781f, 0.177734f, -0.0800781f, 0.158691f, -0.064209f, 0.143066f, -0.0483398f,
+0.127441f, -0.0297852f, 0.127441f, -0.0200195f, 0.127441f, -0.0136719f, 0.131836f,
+-0.00976562f, 0.134277f, -0.00512695f, 0.145752f, -0.000488281f, 0.157227f, 0.00341797f,
+0.161133f, 0.00585938f, 0.163574f, 0.00927734f, 0.163574f, 0.012207f, 0.163574f,
+0.0195312f, 0.158691f, 0.0463867f, 0.14209f, 0.0820312f, 0.105957f, 0.128906f, 0.0581055f,
+0.151367f, 0.027832f, 0.124023f, -0.281738f, 0.117188f, -0.358398f, 0.103516f, -0.375f,
+0.0898438f, -0.391602f, 0.0576172f, -0.391602f, 0.0473633f, -0.391602f, 0.0209961f,
+-0.388672f, 0.0166016f, -0.406738f
+};
+
+const unsigned char TimesNewRomankItalicVerbs[] = {
+6, 0, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1,
+5, 0, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 2,
+2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 5, 6,
+0, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 1, 5,
+6, 0, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1,
+2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2,
+2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 5, 0, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 5, 0, 2, 2,
+2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+0, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2,
+1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0,
+2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1,
+1, 2, 2, 1, 2, 2, 2, 2, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 5, 6, 0, 1, 1, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
+2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 5, 6, 0, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+2, 1, 5, 6
+};
+
+const unsigned TimesNewRomankItalicCharCodes[] = {
+32, 65, 72, 84, 87, 89, 97, 98, 101, 102, 103, 109, 110, 111, 112, 114,
+115, 117, 121
+};
+
+const SkFixed TimesNewRomankItalicWidths[] = {
+0x00004000, 0x00009c60, 0x0000b8e0, 0x00008e60, 0x0000d540, 0x00008e60, 0x00008000,
+0x00008000, 0x000071a0, 0x00004720, 0x00008000, 0x0000b8e0, 0x00008000, 0x00008000,
+0x00008000, 0x000063a0, 0x000063a0, 0x00008000, 0x000071a0
+};
+
+const int TimesNewRomankItalicCharCodesCount = (int) SK_ARRAY_COUNT(TimesNewRomankItalicCharCodes);
+
+const SkPaint::FontMetrics TimesNewRomankItalicMetrics = {
+0x00000003, -1.02344f, -0.891113f, 0.216309f, 0.306641f, 0.0424805f, 1.8501f, 0, -0.497559f,
+1.35254f, 0.453613f, 0, 0.0488281f, 0.108887f
+};
+
+const SkScalar TimesNewRomankBoldItalicPoints[] = {
+0.405273f, -0.213379f, 0.200195f, -0.213379f, 0.15918f, -0.162598f, 0.112305f, -0.106445f,
+0.0986328f, -0.0883789f, 0.0922852f, -0.0737305f, 0.0874023f, -0.0625f, 0.0874023f,
+-0.0512695f, 0.0874023f, -0.0395508f, 0.0998535f, -0.029541f, 0.112305f, -0.0195312f,
+0.141113f, -0.0180664f, 0.141113f, 0, -0.0566406f, 0, -0.0517578f, -0.0180664f, -0.0253906f,
+-0.0224609f, -0.00488281f, -0.0366211f, 0.0224609f, -0.0561523f, 0.0737305f, -0.117188f,
+0.542969f, -0.677246f, 0.564941f, -0.677246f, 0.542969f, -0.135254f, 0.541504f, -0.0927734f,
+0.541504f, -0.0839844f, 0.541504f, -0.0507812f, 0.554932f, -0.0356445f, 0.568359f,
+-0.0205078f, 0.599609f, -0.0180664f, 0.594727f, 0, 0.308105f, 0, 0.313477f, -0.0180664f,
+0.355957f, -0.0219727f, 0.362305f, -0.0249023f, 0.375977f, -0.0317383f, 0.387207f,
+-0.0534668f, 0.398438f, -0.0751953f, 0.400879f, -0.128906f, 0.405273f, -0.253418f,
+0.417969f, -0.469238f, 0.233887f, -0.253418f, 0.297363f, -0.357422f, 0.539551f, -0.357422f,
+0.593262f, -0.54248f, 0.604004f, -0.580566f, 0.604004f, -0.600586f, 0.604004f, -0.620117f,
+0.59082f, -0.630371f, 0.577637f, -0.640625f, 0.527344f, -0.644043f, 0.532715f, -0.662109f,
+0.861816f, -0.662109f, 0.856445f, -0.644043f, 0.808105f, -0.644043f, 0.783203f, -0.623535f,
+0.758301f, -0.603027f, 0.740723f, -0.54248f, 0.617676f, -0.118652f, 0.605469f, -0.0771484f,
+0.605469f, -0.059082f, 0.605469f, -0.0410156f, 0.618652f, -0.0317383f, 0.635742f,
+-0.019043f, 0.680664f, -0.0180664f, 0.675781f, 0, 0.353027f, 0, 0.360352f, -0.0180664f,
+0.407227f, -0.0180664f, 0.429443f, -0.036377f, 0.45166f, -0.0546875f, 0.470215f,
+-0.118652f, 0.527344f, -0.315918f, 0.286133f, -0.315918f, 0.229492f, -0.118652f,
+0.217285f, -0.078125f, 0.217285f, -0.0585938f, 0.217285f, -0.0410156f, 0.232178f,
+-0.0300293f, 0.24707f, -0.019043f, 0.291016f, -0.0180664f, 0.286133f, 0, -0.0322266f,
+0, -0.0268555f, -0.0180664f, 0.0200195f, -0.0180664f, 0.041748f, -0.036377f, 0.0634766f,
+-0.0546875f, 0.0820312f, -0.118652f, 0.205078f, -0.54248f, 0.21582f, -0.579102f,
+0.21582f, -0.600098f, 0.21582f, -0.620117f, 0.202881f, -0.630371f, 0.189941f, -0.640625f,
+0.141113f, -0.644043f, 0.146484f, -0.662109f, 0.470215f, -0.662109f, 0.462891f, -0.644043f,
+0.417969f, -0.644043f, 0.39502f, -0.624756f, 0.37207f, -0.605469f, 0.353027f, -0.54248f,
+0.160156f, -0.662109f, 0.692871f, -0.662109f, 0.642578f, -0.483887f, 0.625f, -0.483887f,
+0.625977f, -0.498047f, 0.625977f, -0.508789f, 0.625977f, -0.55957f, 0.596191f, -0.587646f,
+0.566406f, -0.615723f, 0.495605f, -0.619629f, 0.348145f, -0.121094f, 0.335938f, -0.0795898f,
+0.335938f, -0.0595703f, 0.335938f, -0.0410156f, 0.351074f, -0.0300293f, 0.366211f,
+-0.019043f, 0.412598f, -0.0180664f, 0.408203f, 0, 0.0795898f, 0, 0.0854492f, -0.0180664f,
+0.135742f, -0.0180664f, 0.158691f, -0.0368652f, 0.181641f, -0.0556641f, 0.200684f,
+-0.121094f, 0.348145f, -0.619629f, 0.271973f, -0.617188f, 0.220703f, -0.586426f,
+0.169434f, -0.555664f, 0.126953f, -0.483887f, 0.10791f, -0.483887f, 0.130371f, 0.0151367f,
+0.175293f, -0.55127f, 0.177246f, -0.576172f, 0.177246f, -0.592285f, 0.177246f, -0.618164f,
+0.165283f, -0.630371f, 0.15332f, -0.642578f, 0.123047f, -0.644043f, 0.130371f, -0.662109f,
+0.397949f, -0.662109f, 0.392578f, -0.644043f, 0.379395f, -0.644043f, 0.353027f, -0.644043f,
+0.33667f, -0.626709f, 0.320312f, -0.609375f, 0.316895f, -0.562012f, 0.291016f, -0.226074f,
+0.490723f, -0.499023f, 0.495605f, -0.562012f, 0.497559f, -0.581543f, 0.497559f, -0.593262f,
+0.497559f, -0.617188f, 0.484619f, -0.629883f, 0.47168f, -0.642578f, 0.441895f, -0.644043f,
+0.446777f, -0.662109f, 0.716309f, -0.662109f, 0.710938f, -0.644043f, 0.675293f, -0.644043f,
+0.658203f, -0.626709f, 0.641113f, -0.609375f, 0.637207f, -0.562012f, 0.611816f, -0.226074f,
+0.804199f, -0.490723f, 0.853516f, -0.558594f, 0.865234f, -0.583008f, 0.873535f, -0.599609f,
+0.873535f, -0.611328f, 0.873535f, -0.622559f, 0.862549f, -0.631592f, 0.851562f, -0.640625f,
+0.820312f, -0.644043f, 0.825195f, -0.662109f, 1.00195f, -0.662109f, 0.997559f, -0.644043f,
+0.973633f, -0.639648f, 0.958008f, -0.627441f, 0.936035f, -0.610352f, 0.900879f, -0.562012f,
+0.480469f, 0.0151367f, 0.45166f, 0.0151367f, 0.485352f, -0.431641f, 0.159668f, 0.0151367f,
+0.264648f, -0.29248f, 0.208984f, -0.533691f, 0.194824f, -0.596191f, 0.174805f, -0.619141f,
+0.159668f, -0.636719f, 0.119629f, -0.644043f, 0.125f, -0.662109f, 0.442871f, -0.662109f,
+0.437012f, -0.644043f, 0.390625f, -0.644043f, 0.369385f, -0.625244f, 0.348145f, -0.606445f,
+0.348145f, -0.580566f, 0.348145f, -0.564453f, 0.356934f, -0.524414f, 0.399902f, -0.328613f,
+0.506836f, -0.476074f, 0.547852f, -0.532715f, 0.558105f, -0.555908f, 0.568359f, -0.579102f,
+0.568359f, -0.59668f, 0.568359f, -0.614258f, 0.555176f, -0.627441f, 0.541992f, -0.640625f,
+0.512695f, -0.644043f, 0.518066f, -0.662109f, 0.716797f, -0.662109f, 0.716797f, -0.644043f,
+0.689941f, -0.641113f, 0.67041f, -0.626465f, 0.650879f, -0.611816f, 0.594238f, -0.533691f,
+0.40625f, -0.274902f, 0.362305f, -0.121582f, 0.348145f, -0.0742188f, 0.348145f, -0.0664062f,
+0.348145f, -0.0454102f, 0.364258f, -0.0317383f, 0.380371f, -0.0180664f, 0.418457f,
+-0.0180664f, 0.437012f, -0.0180664f, 0.431641f, 0, 0.0927734f, 0, 0.0976562f, -0.0180664f,
+0.134766f, -0.0175781f, 0.157227f, -0.0280762f, 0.179688f, -0.0385742f, 0.190918f,
+-0.0551758f, 0.19873f, -0.0668945f, 0.213867f, -0.117676f, 0.479004f, -0.445801f,
+0.384277f, -0.121094f, 0.374512f, -0.081543f, 0.373047f, -0.0742188f, 0.373047f,
+-0.0708008f, 0.373047f, -0.0649414f, 0.377197f, -0.0605469f, 0.381348f, -0.0561523f,
+0.385742f, -0.0561523f, 0.395996f, -0.0561523f, 0.414062f, -0.0717773f, 0.421387f,
+-0.078125f, 0.449219f, -0.116699f, 0.466309f, -0.10791f, 0.431641f, -0.0444336f,
+0.392334f, -0.0153809f, 0.353027f, 0.0136719f, 0.307617f, 0.0136719f, 0.279785f,
+0.0136719f, 0.265137f, -0.000732422f, 0.250488f, -0.0151367f, 0.250488f, -0.0371094f,
+0.250488f, -0.0561523f, 0.266113f, -0.10791f, 0.277832f, -0.147461f, 0.221191f, -0.050293f,
+0.168945f, -0.00976562f, 0.138672f, 0.0136719f, 0.104492f, 0.0136719f, 0.0595703f,
+0.0136719f, 0.0395508f, -0.0231934f, 0.0195312f, -0.0600586f, 0.0195312f, -0.106445f,
+0.0195312f, -0.175293f, 0.0615234f, -0.264404f, 0.103516f, -0.353516f, 0.171875f,
+-0.407715f, 0.228027f, -0.452637f, 0.277344f, -0.452637f, 0.304688f, -0.452637f,
+0.321289f, -0.436768f, 0.337891f, -0.420898f, 0.345703f, -0.378906f, 0.363281f, -0.438965f,
+0.322754f, -0.353027f, 0.322754f, -0.392578f, 0.310547f, -0.410156f, 0.301758f, -0.422363f,
+0.286621f, -0.422363f, 0.271484f, -0.422363f, 0.255371f, -0.407715f, 0.222656f, -0.377441f,
+0.184814f, -0.284912f, 0.146973f, -0.192383f, 0.146973f, -0.125f, 0.146973f, -0.0991211f,
+0.155518f, -0.0876465f, 0.164062f, -0.0761719f, 0.174316f, -0.0761719f, 0.196289f,
+-0.0761719f, 0.21875f, -0.101562f, 0.250977f, -0.137695f, 0.276855f, -0.189941f,
+0.322754f, -0.281738f, 0.322754f, -0.353027f, 0.315918f, -0.677246f, 0.231445f, -0.382812f,
+0.27002f, -0.424805f, 0.295898f, -0.438721f, 0.321777f, -0.452637f, 0.352051f, -0.452637f,
+0.410645f, -0.452637f, 0.439697f, -0.4104f, 0.46875f, -0.368164f, 0.46875f, -0.312988f,
+0.46875f, -0.181152f, 0.373047f, -0.0776367f, 0.288086f, 0.0136719f, 0.179688f, 0.0136719f,
+0.0991211f, 0.0136719f, 0.00927734f, -0.0336914f, 0.158691f, -0.551758f, 0.169434f,
+-0.588379f, 0.169434f, -0.602051f, 0.169434f, -0.61377f, 0.159668f, -0.620605f, 0.145996f,
+-0.630371f, 0.118164f, -0.628906f, 0.123535f, -0.648438f, 0.286621f, -0.677246f,
+0.128418f, -0.0288086f, 0.151367f, -0.0141602f, 0.169922f, -0.0141602f, 0.195801f,
+-0.0141602f, 0.213379f, -0.0244141f, 0.241211f, -0.0410156f, 0.271729f, -0.0844727f,
+0.302246f, -0.12793f, 0.322754f, -0.189453f, 0.343262f, -0.250977f, 0.343262f, -0.312012f,
+0.343262f, -0.34668f, 0.327637f, -0.364746f, 0.312012f, -0.382812f, 0.291504f, -0.382812f,
+0.257324f, -0.382812f, 0.231934f, -0.349609f, 0.214844f, -0.328125f, 0.194824f, -0.258301f,
+0.15625f, -0.183105f, 0.151855f, -0.151367f, 0.151855f, -0.130859f, 0.151855f, -0.0942383f,
+0.173096f, -0.0722656f, 0.194336f, -0.050293f, 0.22998f, -0.050293f, 0.26416f, -0.050293f,
+0.298584f, -0.0668945f, 0.333008f, -0.0834961f, 0.378418f, -0.125f, 0.393066f, -0.111816f,
+0.336914f, -0.0439453f, 0.283691f, -0.0151367f, 0.230469f, 0.0136719f, 0.166016f,
+0.0136719f, 0.0844727f, 0.0136719f, 0.0532227f, -0.0253906f, 0.0219727f, -0.0644531f,
+0.0219727f, -0.115723f, 0.0219727f, -0.195801f, 0.0686035f, -0.275879f, 0.115234f,
+-0.355957f, 0.195557f, -0.404297f, 0.275879f, -0.452637f, 0.356934f, -0.452637f,
+0.397949f, -0.452637f, 0.418945f, -0.433105f, 0.439941f, -0.413574f, 0.439941f, -0.383789f,
+0.439941f, -0.348145f, 0.419434f, -0.314453f, 0.391113f, -0.268555f, 0.348145f, -0.240479f,
+0.305176f, -0.212402f, 0.251953f, -0.197754f, 0.216309f, -0.187988f, 0.15625f, -0.183105f,
+0.160645f, -0.208496f, 0.203613f, -0.214844f, 0.227295f, -0.22583f, 0.250977f, -0.236816f,
+0.273682f, -0.260986f, 0.296387f, -0.285156f, 0.312988f, -0.322021f, 0.32959f, -0.358887f,
+0.32959f, -0.391113f, 0.32959f, -0.404785f, 0.322021f, -0.412598f, 0.314453f, -0.42041f,
+0.302734f, -0.42041f, 0.279297f, -0.42041f, 0.25f, -0.387695f, 0.196289f, -0.328125f,
+0.160645f, -0.208496f, 0.261719f, -0.381836f, 0.20459f, -0.15625f, 0.164551f, 0.00341797f,
+0.126465f, 0.0751953f, 0.0883789f, 0.146973f, 0.0373535f, 0.181396f, -0.0136719f,
+0.21582f, -0.0795898f, 0.21582f, -0.121094f, 0.21582f, -0.140625f, 0.199951f, -0.160156f,
+0.184082f, -0.160156f, 0.162598f, -0.160156f, 0.142578f, -0.144043f, 0.12793f, -0.12793f,
+0.113281f, -0.101562f, 0.113281f, -0.0795898f, 0.113281f, -0.0678711f, 0.124512f,
+-0.0561523f, 0.135742f, -0.0561523f, 0.152832f, -0.0561523f, 0.168457f, -0.0634766f,
+0.176025f, -0.0708008f, 0.183594f, -0.0708008f, 0.186035f, -0.0683594f, 0.189453f,
+-0.0654297f, 0.191895f, -0.0615234f, 0.191895f, -0.046875f, 0.191895f, -0.0366211f,
+0.182617f, -0.0107422f, 0.159668f, 0.00195312f, 0.126953f, 0.0107422f, 0.104492f,
+0.0356445f, 0.00830078f, 0.135254f, -0.381836f, 0.0673828f, -0.381836f, 0.0834961f,
+-0.438965f, 0.120117f, -0.438477f, 0.136719f, -0.448242f, 0.15332f, -0.458008f, 0.171875f,
+-0.492188f, 0.225586f, -0.591309f, 0.285156f, -0.634277f, 0.344727f, -0.677246f,
+0.417969f, -0.677246f, 0.464844f, -0.677246f, 0.486084f, -0.65918f, 0.507324f, -0.641113f,
+0.507324f, -0.612305f, 0.507324f, -0.586914f, 0.493164f, -0.572021f, 0.479004f, -0.557129f,
+0.458008f, -0.557129f, 0.438477f, -0.557129f, 0.425781f, -0.569336f, 0.413086f, -0.581543f,
+0.413086f, -0.598633f, 0.413086f, -0.61084f, 0.421143f, -0.624512f, 0.429199f, -0.638184f,
+0.429199f, -0.643066f, 0.429199f, -0.648438f, 0.425537f, -0.651855f, 0.421875f, -0.655273f,
+0.416016f, -0.655273f, 0.387207f, -0.655273f, 0.356934f, -0.619629f, 0.307129f, -0.5625f,
+0.276855f, -0.438965f, 0.347656f, -0.438965f, 0.330566f, -0.381836f, 0.386719f, -0.422852f,
+0.516602f, -0.422852f, 0.500977f, -0.369141f, 0.433594f, -0.369141f, 0.449219f, -0.340332f,
+0.449219f, -0.314453f, 0.449219f, -0.27002f, 0.425049f, -0.232422f, 0.400879f, -0.194824f,
+0.35376f, -0.172363f, 0.306641f, -0.149902f, 0.249023f, -0.149902f, 0.233887f, -0.149902f,
+0.215576f, -0.1521f, 0.197266f, -0.154297f, 0.175781f, -0.158203f, 0.143555f, -0.141602f,
+0.135254f, -0.131836f, 0.129395f, -0.125f, 0.129395f, -0.117676f, 0.129395f, -0.108887f,
+0.136719f, -0.102539f, 0.149414f, -0.0913086f, 0.174316f, -0.0859375f, 0.273926f,
+-0.0644531f, 0.305664f, -0.0512695f, 0.349121f, -0.0332031f, 0.371338f, -0.00488281f,
+0.393555f, 0.0234375f, 0.393555f, 0.0634766f, 0.393555f, 0.124512f, 0.337402f, 0.170166f,
+0.28125f, 0.21582f, 0.163574f, 0.21582f, 0.0449219f, 0.21582f, -0.0112305f, 0.176758f,
+-0.0517578f, 0.148438f, -0.0517578f, 0.109375f, -0.0517578f, 0.0795898f, -0.0251465f,
+0.0541992f, 0.00146484f, 0.0288086f, 0.0888672f, 0.00927734f, 0.059082f, -0.00732422f,
+0.0488281f, -0.0209961f, 0.034668f, -0.0395508f, 0.034668f, -0.0595703f, 0.034668f,
+-0.0922852f, 0.060791f, -0.117188f, 0.0869141f, -0.14209f, 0.148438f, -0.166504f,
+0.100586f, -0.185547f, 0.0793457f, -0.215576f, 0.0581055f, -0.245605f, 0.0581055f,
+-0.285645f, 0.0581055f, -0.328125f, 0.0837402f, -0.366455f, 0.109375f, -0.404785f,
+0.159424f, -0.428711f, 0.209473f, -0.452637f, 0.274414f, -0.452637f, 0.315918f, -0.452637f,
+0.348145f, -0.443359f, 0.364746f, -0.438477f, 0.386719f, -0.422852f, 0.284668f, -0.428711f,
+0.260742f, -0.428711f, 0.244141f, -0.413086f, 0.217773f, -0.38916f, 0.197998f, -0.333008f,
+0.178223f, -0.276855f, 0.178223f, -0.226562f, 0.178223f, -0.202637f, 0.192139f, -0.188721f,
+0.206055f, -0.174805f, 0.226562f, -0.174805f, 0.246582f, -0.174805f, 0.26123f, -0.188477f,
+0.289062f, -0.215332f, 0.30957f, -0.27417f, 0.330078f, -0.333008f, 0.330078f, -0.380859f,
+0.330078f, -0.402344f, 0.316895f, -0.415527f, 0.303711f, -0.428711f, 0.284668f, -0.428711f,
+0.116211f, 0.0205078f, 0.0698242f, 0.0385742f, 0.0529785f, 0.0595703f, 0.0361328f,
+0.0805664f, 0.0361328f, 0.10498f, 0.0361328f, 0.136719f, 0.0695801f, 0.162354f, 0.103027f,
+0.187988f, 0.17627f, 0.187988f, 0.237305f, 0.187988f, 0.264648f, 0.165771f, 0.291992f,
+0.143555f, 0.291992f, 0.11377f, 0.291992f, 0.0874023f, 0.266846f, 0.0708008f, 0.241699f,
+0.0541992f, 0.17041f, 0.0361328f, 0.137207f, 0.0273438f, 0.116211f, 0.0205078f, 0.265625f,
+-0.452637f, 0.203125f, -0.242676f, 0.266113f, -0.339355f, 0.294922f, -0.373047f,
+0.337402f, -0.422363f, 0.36499f, -0.4375f, 0.392578f, -0.452637f, 0.42041f, -0.452637f,
+0.452148f, -0.452637f, 0.466309f, -0.433594f, 0.480469f, -0.414551f, 0.480469f, -0.391602f,
+0.480469f, -0.367676f, 0.467285f, -0.321289f, 0.445312f, -0.242676f, 0.508789f, -0.340332f,
+0.536621f, -0.372559f, 0.57959f, -0.422363f, 0.611328f, -0.439941f, 0.633301f, -0.452637f,
+0.658203f, -0.452637f, 0.684082f, -0.452637f, 0.701416f, -0.435303f, 0.71875f, -0.417969f,
+0.71875f, -0.390137f, 0.71875f, -0.358887f, 0.704102f, -0.309082f, 0.649902f, -0.126953f,
+0.637695f, -0.0864258f, 0.637695f, -0.074707f, 0.637695f, -0.0708008f, 0.640869f,
+-0.0673828f, 0.644043f, -0.0639648f, 0.647949f, -0.0639648f, 0.65332f, -0.0639648f,
+0.657227f, -0.0673828f, 0.674805f, -0.081543f, 0.694336f, -0.108887f, 0.69873f, -0.114746f,
+0.70752f, -0.126953f, 0.724121f, -0.116211f, 0.69043f, -0.0532227f, 0.650146f, -0.0239258f,
+0.609863f, 0.00537109f, 0.575684f, 0.00537109f, 0.545898f, 0.00537109f, 0.527832f,
+-0.0109863f, 0.509766f, -0.0273438f, 0.509766f, -0.0493164f, 0.509766f, -0.0703125f,
+0.521973f, -0.112793f, 0.577148f, -0.303223f, 0.588379f, -0.342773f, 0.588379f, -0.352539f,
+0.588379f, -0.355957f, 0.584961f, -0.359131f, 0.581543f, -0.362305f, 0.578125f, -0.362305f,
+0.571777f, -0.362305f, 0.56543f, -0.359375f, 0.556152f, -0.354492f, 0.536865f, -0.333984f,
+0.517578f, -0.313477f, 0.481445f, -0.260498f, 0.445312f, -0.20752f, 0.431396f, -0.177734f,
+0.41748f, -0.147949f, 0.403809f, -0.100586f, 0.374023f, 0, 0.250488f, 0, 0.341797f,
+-0.318848f, 0.349121f, -0.344727f, 0.349121f, -0.354492f, 0.349121f, -0.35791f, 0.345947f,
+-0.36084f, 0.342773f, -0.36377f, 0.339355f, -0.36377f, 0.321289f, -0.36377f, 0.282227f,
+-0.316406f, 0.222656f, -0.243164f, 0.173828f, -0.140137f, 0.134277f, 0, 0.00976562f,
+0, 0.101562f, -0.313965f, 0.115234f, -0.360352f, 0.115234f, -0.379883f, 0.115234f,
+-0.387695f, 0.111328f, -0.393311f, 0.107422f, -0.398926f, 0.0986328f, -0.4021f, 0.0898438f,
+-0.405273f, 0.0649414f, -0.405273f, 0.0698242f, -0.423828f, 0.236328f, -0.452637f,
+0.26709f, -0.452637f, 0.206543f, -0.243164f, 0.267578f, -0.334961f, 0.297852f, -0.368652f,
+0.342285f, -0.41748f, 0.374512f, -0.435059f, 0.406738f, -0.452637f, 0.435059f, -0.452637f,
+0.460449f, -0.452637f, 0.478516f, -0.433838f, 0.496582f, -0.415039f, 0.496582f, -0.384766f,
+0.496582f, -0.357422f, 0.484863f, -0.318359f, 0.422363f, -0.109863f, 0.414551f, -0.0825195f,
+0.414551f, -0.0742188f, 0.414551f, -0.0693359f, 0.418213f, -0.0654297f, 0.421875f,
+-0.0615234f, 0.425781f, -0.0615234f, 0.430664f, -0.0615234f, 0.436035f, -0.0654297f,
+0.453125f, -0.0795898f, 0.470703f, -0.105469f, 0.475098f, -0.112305f, 0.484863f,
+-0.125977f, 0.503418f, -0.114746f, 0.431641f, 0.00585938f, 0.352539f, 0.00585938f,
+0.322266f, 0.00585938f, 0.305176f, -0.00976562f, 0.288086f, -0.0253906f, 0.288086f,
+-0.0488281f, 0.288086f, -0.0693359f, 0.299805f, -0.109863f, 0.36084f, -0.318359f,
+0.367188f, -0.338867f, 0.367188f, -0.348633f, 0.367188f, -0.354004f, 0.362793f, -0.358154f,
+0.358398f, -0.362305f, 0.352539f, -0.362305f, 0.333984f, -0.362305f, 0.307617f, -0.336914f,
+0.240234f, -0.272461f, 0.177246f, -0.14502f, 0.137207f, 0, 0.0126953f, 0, 0.104004f,
+-0.313477f, 0.117188f, -0.359863f, 0.117188f, -0.379395f, 0.117188f, -0.387695f,
+0.113281f, -0.393311f, 0.109375f, -0.398926f, 0.100586f, -0.4021f, 0.0917969f, -0.405273f,
+0.0673828f, -0.405273f, 0.0727539f, -0.423828f, 0.237305f, -0.452637f, 0.328613f,
+-0.452637f, 0.367188f, -0.452637f, 0.401123f, -0.434814f, 0.435059f, -0.416992f,
+0.452393f, -0.385254f, 0.469727f, -0.353516f, 0.469727f, -0.314941f, 0.469727f, -0.23584f,
+0.425537f, -0.156738f, 0.381348f, -0.0776367f, 0.309082f, -0.0319824f, 0.236816f,
+0.0136719f, 0.163574f, 0.0136719f, 0.097168f, 0.0136719f, 0.060791f, -0.0258789f,
+0.0244141f, -0.0654297f, 0.0244141f, -0.122559f, 0.0244141f, -0.19043f, 0.0515137f,
+-0.249756f, 0.0786133f, -0.309082f, 0.120361f, -0.353271f, 0.162109f, -0.397461f,
+0.216309f, -0.425049f, 0.270508f, -0.452637f, 0.328613f, -0.452637f, 0.308594f, -0.426758f,
+0.282715f, -0.426758f, 0.265625f, -0.411621f, 0.231445f, -0.380859f, 0.188477f, -0.267822f,
+0.145508f, -0.154785f, 0.145508f, -0.0639648f, 0.145508f, -0.0415039f, 0.15918f,
+-0.0268555f, 0.172852f, -0.012207f, 0.191406f, -0.012207f, 0.210449f, -0.012207f,
+0.225098f, -0.0239258f, 0.246582f, -0.0415039f, 0.277832f, -0.102783f, 0.309082f,
+-0.164062f, 0.329102f, -0.238037f, 0.349121f, -0.312012f, 0.349121f, -0.373535f,
+0.349121f, -0.398926f, 0.336914f, -0.412842f, 0.324707f, -0.426758f, 0.308594f, -0.426758f,
+0.0605469f, -0.425293f, 0.222168f, -0.452637f, 0.251465f, -0.452637f, 0.229492f,
+-0.373047f, 0.280762f, -0.419922f, 0.313477f, -0.436279f, 0.346191f, -0.452637f,
+0.378418f, -0.452637f, 0.424316f, -0.452637f, 0.449219f, -0.417236f, 0.474121f, -0.381836f,
+0.474121f, -0.330566f, 0.474121f, -0.19043f, 0.376953f, -0.0820312f, 0.291016f, 0.0136719f,
+0.189453f, 0.0136719f, 0.171387f, 0.0136719f, 0.158691f, 0.0102539f, 0.145996f, 0.00683594f,
+0.123047f, -0.00488281f, 0.0976562f, 0.0830078f, 0.0839844f, 0.130859f, 0.0839844f,
+0.155762f, 0.0839844f, 0.171387f, 0.0947266f, 0.18042f, 0.105469f, 0.189453f, 0.14502f,
+0.195801f, 0.140625f, 0.213867f, -0.12207f, 0.213867f, -0.117188f, 0.195801f, -0.0859375f,
+0.194824f, -0.0651855f, 0.175781f, -0.0444336f, 0.156738f, -0.0263672f, 0.09375f,
+0.0927734f, -0.316895f, 0.105957f, -0.362793f, 0.105957f, -0.381836f, 0.105957f,
+-0.390137f, 0.102051f, -0.395752f, 0.0981445f, -0.401367f, 0.090332f, -0.403809f,
+0.0825195f, -0.40625f, 0.0551758f, -0.40625f, 0.136719f, -0.050293f, 0.151367f, -0.0263672f,
+0.163086f, -0.0183105f, 0.174805f, -0.0102539f, 0.19043f, -0.0102539f, 0.206055f,
+-0.0102539f, 0.220947f, -0.0187988f, 0.23584f, -0.0273438f, 0.257812f, -0.0532227f,
+0.279785f, -0.0791016f, 0.300049f, -0.119629f, 0.320312f, -0.160156f, 0.33252f, -0.21167f,
+0.344727f, -0.263184f, 0.344727f, -0.310059f, 0.344727f, -0.347656f, 0.331299f, -0.364746f,
+0.317871f, -0.381836f, 0.298828f, -0.381836f, 0.281738f, -0.381836f, 0.266602f, -0.373047f,
+0.244629f, -0.360352f, 0.214844f, -0.325684f, 0.236816f, -0.452637f, 0.163086f, -0.178223f,
+0.253906f, -0.378906f, 0.299805f, -0.425293f, 0.32666f, -0.452637f, 0.356445f, -0.452637f,
+0.376953f, -0.452637f, 0.389648f, -0.437744f, 0.402344f, -0.422852f, 0.402344f, -0.395508f,
+0.402344f, -0.348145f, 0.379395f, -0.315918f, 0.364746f, -0.29541f, 0.34668f, -0.29541f,
+0.327148f, -0.29541f, 0.317383f, -0.313477f, 0.307617f, -0.331543f, 0.303711f, -0.334717f,
+0.299805f, -0.337891f, 0.29541f, -0.337891f, 0.290527f, -0.337891f, 0.285156f, -0.334961f,
+0.274414f, -0.329102f, 0.25708f, -0.306396f, 0.239746f, -0.283691f, 0.214355f, -0.230469f,
+0.188965f, -0.177246f, 0.174805f, -0.140381f, 0.160645f, -0.103516f, 0.135254f, 0,
+0.0170898f, 0, 0.0976562f, -0.32373f, 0.106445f, -0.359863f, 0.106445f, -0.371582f,
+0.106445f, -0.384766f, 0.101807f, -0.39209f, 0.097168f, -0.399414f, 0.0891113f, -0.402832f,
+0.0810547f, -0.40625f, 0.0556641f, -0.40625f, 0.0600586f, -0.42041f, 0.20752f, -0.452637f,
+0.37207f, -0.452637f, 0.350586f, -0.301758f, 0.33252f, -0.301758f, 0.328613f, -0.360352f,
+0.296631f, -0.394043f, 0.264648f, -0.427734f, 0.228027f, -0.427734f, 0.205566f, -0.427734f,
+0.190918f, -0.414551f, 0.17627f, -0.401367f, 0.17627f, -0.382812f, 0.17627f, -0.367188f,
+0.182617f, -0.353516f, 0.188965f, -0.339844f, 0.210938f, -0.316406f, 0.288086f, -0.233398f,
+0.304688f, -0.202148f, 0.321289f, -0.170898f, 0.321289f, -0.135254f, 0.321289f, -0.0966797f,
+0.301758f, -0.0622559f, 0.282227f, -0.027832f, 0.243408f, -0.00708008f, 0.20459f,
+0.0136719f, 0.162598f, 0.0136719f, 0.134277f, 0.0136719f, 0.0927734f, 0.00244141f,
+0.0654297f, -0.00537109f, 0.0517578f, -0.00537109f, 0.0395508f, -0.00537109f, 0.0327148f,
+-0.00170898f, 0.0258789f, 0.00195312f, 0.0175781f, 0.0136719f, -0.000488281f, 0.0136719f,
+0.0234375f, -0.148926f, 0.0390625f, -0.148926f, 0.0561523f, -0.0898438f, 0.0710449f,
+-0.0646973f, 0.0859375f, -0.0395508f, 0.11084f, -0.0246582f, 0.135742f, -0.00976562f,
+0.158691f, -0.00976562f, 0.185547f, -0.00976562f, 0.203125f, -0.0266113f, 0.220703f,
+-0.043457f, 0.220703f, -0.0668945f, 0.220703f, -0.0898438f, 0.209229f, -0.111328f,
+0.197754f, -0.132812f, 0.15625f, -0.178223f, 0.0991211f, -0.240234f, 0.0810547f,
+-0.273926f, 0.0683594f, -0.29834f, 0.0683594f, -0.32959f, 0.0683594f, -0.382324f,
+0.106689f, -0.41748f, 0.14502f, -0.452637f, 0.214355f, -0.452637f, 0.244629f, -0.452637f,
+0.288574f, -0.441895f, 0.310547f, -0.436523f, 0.32373f, -0.436523f, 0.342773f, -0.436523f,
+0.354492f, -0.452637f, 0.265625f, -0.452637f, 0.170898f, -0.120605f, 0.164062f, -0.0976562f,
+0.164062f, -0.0888672f, 0.164062f, -0.0844727f, 0.16748f, -0.0820312f, 0.171387f,
+-0.078125f, 0.176758f, -0.078125f, 0.199219f, -0.078125f, 0.236816f, -0.118164f,
+0.290527f, -0.17627f, 0.349609f, -0.285156f, 0.394043f, -0.43457f, 0.517578f, -0.438965f,
+0.423828f, -0.116699f, 0.412109f, -0.0756836f, 0.412109f, -0.0698242f, 0.412109f,
+-0.065918f, 0.415771f, -0.0617676f, 0.419434f, -0.0576172f, 0.42334f, -0.0576172f,
+0.430176f, -0.0576172f, 0.436523f, -0.0634766f, 0.454102f, -0.0776367f, 0.48291f,
+-0.120605f, 0.499512f, -0.108887f, 0.431641f, 0.0136719f, 0.350098f, 0.0136719f,
+0.319824f, 0.0136719f, 0.30249f, -0.00170898f, 0.285156f, -0.0170898f, 0.285156f,
+-0.0419922f, 0.285156f, -0.0683594f, 0.297363f, -0.108887f, 0.321289f, -0.191406f,
+0.257812f, -0.0991211f, 0.229004f, -0.0668945f, 0.185059f, -0.0185547f, 0.155029f,
+-0.00244141f, 0.125f, 0.0136719f, 0.0976562f, 0.0136719f, 0.0717773f, 0.0136719f,
+0.0529785f, -0.00537109f, 0.0341797f, -0.0244141f, 0.0341797f, -0.0537109f, 0.0341797f,
+-0.0786133f, 0.0463867f, -0.120605f, 0.101562f, -0.315918f, 0.115234f, -0.36377f,
+0.115234f, -0.380371f, 0.115234f, -0.387695f, 0.111328f, -0.393311f, 0.107422f, -0.398926f,
+0.0983887f, -0.4021f, 0.0893555f, -0.405273f, 0.0649414f, -0.405273f, 0.0698242f,
+-0.423828f, 0.236328f, -0.452637f, 0.0253906f, -0.408691f, 0.175781f, -0.452637f,
+0.193848f, -0.430176f, 0.201172f, -0.410156f, 0.214355f, -0.375488f, 0.219727f, -0.314453f,
+0.22998f, -0.194336f, 0.233887f, -0.0581055f, 0.286133f, -0.126953f, 0.353516f, -0.240234f,
+0.374023f, -0.274414f, 0.374023f, -0.304688f, 0.374023f, -0.32373f, 0.350342f, -0.34082f,
+0.32666f, -0.35791f, 0.320801f, -0.367432f, 0.314941f, -0.376953f, 0.314941f, -0.39209f,
+0.314941f, -0.416504f, 0.332764f, -0.43457f, 0.350586f, -0.452637f, 0.375977f, -0.452637f,
+0.402832f, -0.452637f, 0.422607f, -0.432129f, 0.442383f, -0.411621f, 0.442383f, -0.383789f,
+0.442383f, -0.351074f, 0.424072f, -0.307861f, 0.405762f, -0.264648f, 0.338379f, -0.159668f,
+0.251953f, -0.0253906f, 0.168945f, 0.0727539f, 0.115723f, 0.135254f, 0.0830078f,
+0.162842f, 0.050293f, 0.19043f, 0.0151367f, 0.206543f, -0.00585938f, 0.21582f, -0.0263672f,
+0.21582f, -0.0541992f, 0.21582f, -0.0739746f, 0.196289f, -0.09375f, 0.176758f, -0.09375f,
+0.149902f, -0.09375f, 0.123047f, -0.0759277f, 0.104492f, -0.0581055f, 0.0859375f,
+-0.0341797f, 0.0859375f, -0.00439453f, 0.0859375f, 0.0205078f, 0.117188f, 0.0371094f,
+0.138184f, 0.0478516f, 0.138184f, 0.059082f, 0.138184f, 0.0698242f, 0.131836f, 0.0844727f,
+0.124023f, 0.11084f, 0.0957031f, 0.11377f, 0.034668f, 0.11377f, 0.00341797f, 0.11377f,
+-0.0385742f, 0.109863f, -0.114746f, 0.101562f, -0.300781f, 0.097168f, -0.352051f,
+0.0795898f, -0.374512f, 0.065918f, -0.391113f, 0.0439453f, -0.391113f, 0.0356445f,
+-0.391113f, 0.0253906f, -0.389648f
+};
+
+const unsigned char TimesNewRomankBoldItalicVerbs[] = {
+6, 0, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 5,
+0, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1,
+1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 2, 1, 1, 1, 2, 2, 5, 6, 0, 1, 1, 1, 2, 2, 2,
+1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 1, 5, 6, 0, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1,
+1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 5, 6,
+0, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1,
+1, 1, 1, 2, 2, 2, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2,
+2, 2, 1, 2, 2, 2, 1, 1, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 2, 2, 2, 2, 2,
+1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0,
+1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 1,
+2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2,
+2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1,
+1, 5, 6, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 5, 6, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 2,
+2, 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6,
+0, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,
+1, 2, 2, 2, 2, 1, 1, 5, 6, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 5, 6
+};
+
+const unsigned TimesNewRomankBoldItalicCharCodes[] = {
+32, 65, 72, 84, 87, 89, 97, 98,
+101, 102, 103, 109, 110, 111, 112, 114, 115, 117, 121
+};
+
+const SkFixed TimesNewRomankBoldItalicWidths[] = {
+0x00004000, 0x0000aac0, 0x0000c720, 0x00009c60, 0x0000e3a0, 0x00009c60, 0x00008000,
+0x00008000, 0x000071a0, 0x00005540, 0x00008000, 0x0000c720, 0x00008e60, 0x00008000,
+0x00008000, 0x000063a0, 0x000063a0, 0x00008e60, 0x000071a0
+};
+
+const int TimesNewRomankBoldItalicCharCodesCount = (int) SK_ARRAY_COUNT(TimesNewRomankBoldItalicCharCodes);
+
+const SkPaint::FontMetrics TimesNewRomankBoldItalicMetrics = {
+0x3436342f, -1.03223f, -0.891113f, 0.216309f, 0.306641f, 0.0424805f, 1.94824f, 7.98734e-16f,
+-0.547363f, 1.40088f, 0.466309f, 9.77694e-15f, 0.0952148f, 0.108887f
+};
+
+static SkTestFontData gTestFonts[] = {
+    {    CourierNewkNormalPoints, CourierNewkNormalVerbs, CourierNewkNormalCharCodes,
+         CourierNewkNormalCharCodesCount, CourierNewkNormalWidths,
+         CourierNewkNormalMetrics, "Courier New", SkTypeface::kNormal, NULL
+    },
+    {    CourierNewkBoldPoints, CourierNewkBoldVerbs, CourierNewkBoldCharCodes,
+         CourierNewkBoldCharCodesCount, CourierNewkBoldWidths,
+         CourierNewkBoldMetrics, "Courier New", SkTypeface::kBold, NULL
+    },
+    {    CourierNewkItalicPoints, CourierNewkItalicVerbs, CourierNewkItalicCharCodes,
+         CourierNewkItalicCharCodesCount, CourierNewkItalicWidths,
+         CourierNewkItalicMetrics, "Courier New", SkTypeface::kItalic, NULL
+    },
+    {    CourierNewkBoldItalicPoints, CourierNewkBoldItalicVerbs, CourierNewkBoldItalicCharCodes,
+         CourierNewkBoldItalicCharCodesCount, CourierNewkBoldItalicWidths,
+         CourierNewkBoldItalicMetrics, "Courier New", SkTypeface::kBoldItalic, NULL
+    },
+    {    LiberationSanskNormalPoints, LiberationSanskNormalVerbs, LiberationSanskNormalCharCodes,
+         LiberationSanskNormalCharCodesCount, LiberationSanskNormalWidths,
+         LiberationSanskNormalMetrics, "Liberation Sans", SkTypeface::kNormal, NULL
+    },
+    {    LiberationSanskBoldPoints, LiberationSanskBoldVerbs, LiberationSanskBoldCharCodes,
+         LiberationSanskBoldCharCodesCount, LiberationSanskBoldWidths,
+         LiberationSanskBoldMetrics, "Liberation Sans", SkTypeface::kBold, NULL
+    },
+    {    LiberationSanskItalicPoints, LiberationSanskItalicVerbs, LiberationSanskItalicCharCodes,
+         LiberationSanskItalicCharCodesCount, LiberationSanskItalicWidths,
+         LiberationSanskItalicMetrics, "Liberation Sans", SkTypeface::kItalic, NULL
+    },
+    {    LiberationSanskBoldItalicPoints, LiberationSanskBoldItalicVerbs, LiberationSanskBoldItalicCharCodes,
+         LiberationSanskBoldItalicCharCodesCount, LiberationSanskBoldItalicWidths,
+         LiberationSanskBoldItalicMetrics, "Liberation Sans", SkTypeface::kBoldItalic, NULL
+    },
+    {    HiraginoMaruGothicProkNormalPoints, HiraginoMaruGothicProkNormalVerbs, HiraginoMaruGothicProkNormalCharCodes,
+         HiraginoMaruGothicProkNormalCharCodesCount, HiraginoMaruGothicProkNormalWidths,
+         HiraginoMaruGothicProkNormalMetrics, "Hiragino Maru Gothic Pro", SkTypeface::kNormal, NULL
+    },
+    {    PapyruskNormalPoints, PapyruskNormalVerbs, PapyruskNormalCharCodes,
+         PapyruskNormalCharCodesCount, PapyruskNormalWidths,
+         PapyruskNormalMetrics, "Papyrus", SkTypeface::kNormal, NULL
+    },
+    {    TimesNewRomankNormalPoints, TimesNewRomankNormalVerbs, TimesNewRomankNormalCharCodes,
+         TimesNewRomankNormalCharCodesCount, TimesNewRomankNormalWidths,
+         TimesNewRomankNormalMetrics, "Times New Roman", SkTypeface::kNormal, NULL
+    },
+    {    TimesNewRomankBoldPoints, TimesNewRomankBoldVerbs, TimesNewRomankBoldCharCodes,
+         TimesNewRomankBoldCharCodesCount, TimesNewRomankBoldWidths,
+         TimesNewRomankBoldMetrics, "Times New Roman", SkTypeface::kBold, NULL
+    },
+    {    TimesNewRomankItalicPoints, TimesNewRomankItalicVerbs, TimesNewRomankItalicCharCodes,
+         TimesNewRomankItalicCharCodesCount, TimesNewRomankItalicWidths,
+         TimesNewRomankItalicMetrics, "Times New Roman", SkTypeface::kItalic, NULL
+    },
+    {    TimesNewRomankBoldItalicPoints, TimesNewRomankBoldItalicVerbs, TimesNewRomankBoldItalicCharCodes,
+         TimesNewRomankBoldItalicCharCodesCount, TimesNewRomankBoldItalicWidths,
+         TimesNewRomankBoldItalicMetrics, "Times New Roman", SkTypeface::kBoldItalic, NULL
+    },
+};
+
+const int gTestFontsCount = (int) SK_ARRAY_COUNT(gTestFonts);
+
+struct SubFont {
+    const char* fName;
+    SkTypeface::Style fStyle;
+    SkTestFontData& fFont;
+    const char* fFile;
+};
+
+const SubFont gSubFonts[] = {
+    { "Courier New", SkTypeface::kNormal, gTestFonts[0], "Courier New.ttf"},
+    { "Courier New", SkTypeface::kBold, gTestFonts[1], "Courier New Bold.ttf"},
+    { "Courier New", SkTypeface::kItalic, gTestFonts[2], "Courier New Italic.ttf"},
+    { "Courier New", SkTypeface::kBoldItalic, gTestFonts[3], "Courier New Bold Italic.ttf"},
+    { "Helvetica", SkTypeface::kNormal, gTestFonts[4], "LiberationSans-Regular.ttf"},
+    { "Helvetica", SkTypeface::kBold, gTestFonts[5], "LiberationSans-Bold.ttf"},
+    { "Helvetica", SkTypeface::kItalic, gTestFonts[6], "LiberationSans-Italic.ttf"},
+    { "Helvetica", SkTypeface::kBoldItalic, gTestFonts[7], "LiberationSans-BoldItalic.ttf"},
+    { "Hiragino Maru Gothic Pro", SkTypeface::kNormal, gTestFonts[8], "Pro W4.otf"},
+    { "Liberation Sans", SkTypeface::kNormal, gTestFonts[4], "LiberationSans-Regular.ttf"},
+    { "Liberation Sans", SkTypeface::kBold, gTestFonts[5], "LiberationSans-Bold.ttf"},
+    { "Liberation Sans", SkTypeface::kItalic, gTestFonts[6], "LiberationSans-Italic.ttf"},
+    { "Liberation Sans", SkTypeface::kBoldItalic, gTestFonts[7], "LiberationSans-BoldItalic.ttf"},
+    { "monospace", SkTypeface::kNormal, gTestFonts[0], "Courier New.ttf"},
+    { "monospace", SkTypeface::kBold, gTestFonts[1], "Courier New Bold.ttf"},
+    { "monospace", SkTypeface::kItalic, gTestFonts[2], "Courier New Italic.ttf"},
+    { "monospace", SkTypeface::kBoldItalic, gTestFonts[3], "Courier New Bold Italic.ttf"},
+    { "Papyrus", SkTypeface::kNormal, gTestFonts[9], "Papyrus.ttc"},
+    { "sans-serif", SkTypeface::kNormal, gTestFonts[4], "LiberationSans-Regular.ttf"},
+    { "sans-serif", SkTypeface::kBold, gTestFonts[5], "LiberationSans-Bold.ttf"},
+    { "sans-serif", SkTypeface::kItalic, gTestFonts[6], "LiberationSans-Italic.ttf"},
+    { "sans-serif", SkTypeface::kBoldItalic, gTestFonts[7], "LiberationSans-BoldItalic.ttf"},
+    { "serif", SkTypeface::kNormal, gTestFonts[10], "Times New Roman.ttf"},
+    { "serif", SkTypeface::kBold, gTestFonts[11], "Times New Roman Bold.ttf"},
+    { "serif", SkTypeface::kItalic, gTestFonts[12], "Times New Roman Italic.ttf"},
+    { "serif", SkTypeface::kBoldItalic, gTestFonts[13], "Times New Roman Bold Italic.ttf"},
+    { "Times", SkTypeface::kNormal, gTestFonts[10], "Times New Roman.ttf"},
+    { "Times", SkTypeface::kBold, gTestFonts[11], "Times New Roman Bold.ttf"},
+    { "Times", SkTypeface::kItalic, gTestFonts[12], "Times New Roman Italic.ttf"},
+    { "Times", SkTypeface::kBoldItalic, gTestFonts[13], "Times New Roman Bold Italic.ttf"},
+    { "Times New Roman", SkTypeface::kNormal, gTestFonts[10], "Times New Roman.ttf"},
+    { "Times New Roman", SkTypeface::kBold, gTestFonts[11], "Times New Roman Bold.ttf"},
+    { "Times New Roman", SkTypeface::kItalic, gTestFonts[12], "Times New Roman Italic.ttf"},
+    { "Times New Roman", SkTypeface::kBoldItalic, gTestFonts[13], "Times New Roman Bold Italic.ttf"},
+    { "Times Roman", SkTypeface::kNormal, gTestFonts[4], "LiberationSans-Regular.ttf"},
+};
+
+const int gSubFontsCount = (int) SK_ARRAY_COUNT(gSubFonts);
+
+const int gDefaultFontIndex = 12;
diff --git a/tools/test_font_data_chars.cpp b/tools/test_font_data_chars.cpp
new file mode 100644
index 0000000..ffbfa88
--- /dev/null
+++ b/tools/test_font_data_chars.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// Auto-generated by sk_tool_utils_font.cpp
+
+const char gCourierNew[] =
+    " !/<>ACHMTWYabcdefgilmnoprstuy";
+const char gCourierNew_Bold[] =
+    " AHTWYabefgmnoprsuy";
+const char gCourierNew_Italic[] =
+    " AHTWYabefgmnoprsuy";
+const char gCourierNew_BoldItalic[] =
+    " AHTWYabefgmnoprsuy";
+const char gLiberationSans[] =
+    " !#%&')*+-./1245679:;<=>?@ABCDEFHIJKLMNOPQRSTVWXYZ[\\]^`abcdefgilmnopqrstuvwxyz";
+const char gLiberationSans_Bold[] =
+    " !\"#$%&'()*+-./012356789:;=>?ABCDEFGHIJLMORSTUVWXYZ[]^_abdefghijklmnopqrsuvwxyz";
+const char gLiberationSans_Italic[] =
+    " AHTWYabefgmnoprsuy";
+const char gLiberationSans_BoldItalic[] =
+    " !,-./012345689:ABCDEFGHIKLMNOPQRSTUWXYZ[\\]_abcdefghijklmnopqrstuvwxyz";
+const char gHiraginoMaruGothicPro[] =
+    " !Tacefnprsuy" "\xE3" "\x83" "\xBC";
+const char gPapyrus[] =
+    " !HTaceflnoprsuy";
+const char gTimesNewRoman[] =
+    " !\"#$%&'()*+,-./123456789;<=>?@ABCDEFGHIJKLMNPQRSTVWXYZ[\\]^_`abcdefgijklmnopqrstuvwxyz";
+const char gTimesNewRoman_Bold[] =
+    " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz";
+const char gTimesNewRoman_Italic[] =
+    " AHTWYabefgmnoprsuy";
+const char gTimesNewRoman_BoldItalic[] =
+    " AHTWYabefgmnoprsuy";
diff --git a/tools/tests/base_unittest.py b/tools/tests/base_unittest.py
index f7ee570..9ff710f 100755
--- a/tools/tests/base_unittest.py
+++ b/tools/tests/base_unittest.py
@@ -8,22 +8,77 @@
 
 A wrapper around the standard Python unittest library, adding features we need
 for various unittests within this directory.
+
+TODO(epoger): Move this into the common repo for broader use?  Or at least in
+a more common place within the Skia repo?
 """
 
 import errno
+import filecmp
 import os
 import shutil
-import sys
+import tempfile
 import unittest
 
-# Set the PYTHONPATH to include the tools directory.
-sys.path.append(
-    os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
-import find_run_binary
+TRUNK_DIR = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), os.pardir, os.pardir))
 
 
 class TestCase(unittest.TestCase):
 
+  def __init__(self, *args, **kwargs):
+    super(TestCase, self).__init__(*args, **kwargs)
+    # Subclasses should override this default value if they want their output
+    # to be automatically compared against expectations (see setUp and tearDown)
+    self._testdata_dir = None
+
+  def setUp(self):
+    """Called before each test."""
+    # Get the name of this test, in such a way that it will be consistent
+    # regardless of the directory it is run from (throw away package names,
+    # if any).
+    self._test_name = '.'.join(self.id().split('.')[-3:])
+
+    self._temp_dir = tempfile.mkdtemp()
+    if self._testdata_dir:
+      self.create_empty_dir(self.output_dir_actual)
+
+  def tearDown(self):
+    """Called after each test."""
+    shutil.rmtree(self._temp_dir)
+    if self._testdata_dir and os.path.exists(self.output_dir_expected):
+      different_files = _find_different_files(self.output_dir_actual,
+                                              self.output_dir_expected)
+      # Don't add any cleanup code below this assert!
+      # Then if tests fail, the artifacts will not be cleaned up.
+      assert (not different_files), \
+        ('found differing files:\n' +
+         '\n'.join(['tkdiff %s %s &' % (
+             os.path.join(self.output_dir_actual, basename),
+             os.path.join(self.output_dir_expected, basename))
+                    for basename in different_files]))
+
+  @property
+  def temp_dir(self):
+    return self._temp_dir
+
+  @property
+  def input_dir(self):
+    assert self._testdata_dir, 'self._testdata_dir must be set'
+    return os.path.join(self._testdata_dir, 'inputs')
+
+  @property
+  def output_dir_actual(self):
+    assert self._testdata_dir, 'self._testdata_dir must be set'
+    return os.path.join(
+        self._testdata_dir, 'outputs', 'actual', self._test_name)
+
+  @property
+  def output_dir_expected(self):
+    assert self._testdata_dir, 'self._testdata_dir must be set'
+    return os.path.join(
+        self._testdata_dir, 'outputs', 'expected', self._test_name)
+
   def shortDescription(self):
     """Tell unittest framework to not print docstrings for test cases."""
     return None
@@ -34,42 +89,48 @@
     Args:
       path: path on local disk
     """
-    shutil.rmtree(path=path, ignore_errors=True)
+    # Delete the old one, if any.
+    if os.path.isdir(path):
+      shutil.rmtree(path=path, ignore_errors=True)
+    elif os.path.lexists(path):
+      os.remove(path)
+
+    # Create the new one.
     try:
       os.makedirs(path)
     except OSError as exc:
+      # Guard against race condition (somebody else is creating the same dir)
       if exc.errno != errno.EEXIST:
         raise
     return path
 
-  def run_command(self, args):
-    """Runs a program from the command line and returns stdout.
 
-    Args:
-      args: Command line to run, as a list of string parameters. args[0] is the
-            binary to run.
+def _find_different_files(dir1, dir2, ignore_subtree_names=None):
+  """Returns a list of any files that differ between the directory trees rooted
+  at dir1 and dir2.
 
-    Returns:
-      stdout from the program, as a single string.
+  Args:
+    dir1: root of a directory tree; if nonexistent, will raise OSError
+    dir2: root of another directory tree; if nonexistent, will raise OSError
+    ignore_subtree_names: list of subtree directory names to ignore;
+          defaults to ['.svn'], so all SVN files are ignores
 
-    Raises:
-      Exception: the program exited with a nonzero return code.
-    """
-    return find_run_binary.run_command(args)
-
-  def find_path_to_program(self, program):
-    """Returns path to an existing program binary.
-
-    Args:
-      program: Basename of the program to find (e.g., 'render_pictures').
-
-    Returns:
-      Absolute path to the program binary, as a string.
-
-    Raises:
-      Exception: unable to find the program binary.
-    """
-    return find_run_binary.find_path_to_program(program)
+  TODO(epoger): include the dirname within each filename (not just the
+  basename), to make it easier to locate any differences
+  """
+  differing_files = []
+  if ignore_subtree_names is None:
+    ignore_subtree_names = ['.svn']
+  dircmp = filecmp.dircmp(dir1, dir2, ignore=ignore_subtree_names)
+  differing_files.extend(dircmp.left_only)
+  differing_files.extend(dircmp.right_only)
+  differing_files.extend(dircmp.common_funny)
+  differing_files.extend(dircmp.diff_files)
+  differing_files.extend(dircmp.funny_files)
+  for common_dir in dircmp.common_dirs:
+    differing_files.extend(_find_different_files(
+        os.path.join(dir1, common_dir), os.path.join(dir2, common_dir)))
+  return differing_files
 
 
 def main(test_case_class):
@@ -77,10 +138,6 @@
 
   Raises an Exception if any of those tests fail (in case we are running in the
   context of run_all.py, which depends on that Exception to signal failures).
-
-  TODO(epoger): Make all of our unit tests use the Python unittest framework,
-  so we can leverage its ability to run *all* the tests and report failures at
-  the end.
   """
   suite = unittest.TestLoader().loadTestsFromTestCase(test_case_class)
   results = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tools/tests/fix_pythonpath.py b/tools/tests/fix_pythonpath.py
new file mode 100755
index 0000000..a746a18
--- /dev/null
+++ b/tools/tests/fix_pythonpath.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+
+"""
+Copyright 2014 Google Inc.
+
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+
+Adds possibly-needed directories to PYTHONPATH, if they aren't already there.
+"""
+
+import os
+import sys
+
+TRUNK_DIRECTORY = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), os.pardir, os.pardir))
+for subdir in ['tools']:
+  fullpath = os.path.join(TRUNK_DIRECTORY, subdir)
+  if fullpath not in sys.path:
+    sys.path.append(fullpath)
diff --git a/tools/tests/render_pictures_test.py b/tools/tests/render_pictures_test.py
index 59722e8..9a2dd72 100755
--- a/tools/tests/render_pictures_test.py
+++ b/tools/tests/render_pictures_test.py
@@ -16,8 +16,12 @@
 import shutil
 import tempfile
 
+# Must fix up PYTHONPATH before importing from within Skia
+import fix_pythonpath  # pylint: disable=W0611
+
 # Imports from within Skia
 import base_unittest
+import find_run_binary
 
 # Maximum length of text diffs to show when tests fail
 MAX_DIFF_LENGTH = 30000
@@ -32,7 +36,7 @@
 # the comparison.
 RED_WHOLEIMAGE = {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 11092453015575919668,
+    "checksumValue" : 2853310525600416231,
     "comparisonResult" : "failed",
     "filepath" : "red_skp.png",
 }
@@ -42,7 +46,7 @@
 # the comparison.
 GREEN_WHOLEIMAGE = {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 8891695120562235492,
+    "checksumValue" : 11143979097452425335,
     "comparisonResult" : "succeeded",
     "filepath" : "green_skp.png",
 }
@@ -64,22 +68,22 @@
     "filepath" : "red_skp-tile1.png",
 }, {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 16670399404877552232,
+    "checksumValue" : 15939355025996362179,
     "comparisonResult" : "failed",
     "filepath" : "red_skp-tile2.png",
 }, {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 2507897274083364964,
+    "checksumValue" : 649771916797529222,
     "comparisonResult" : "failed",
     "filepath" : "red_skp-tile3.png",
 }, {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 7325267995523877959,
+    "checksumValue" : 8132820002266077288,
     "comparisonResult" : "failed",
     "filepath" : "red_skp-tile4.png",
 }, {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 2181381724594493116,
+    "checksumValue" : 2406160701181324581,
     "comparisonResult" : "failed",
     "filepath" : "red_skp-tile5.png",
 }]
@@ -101,22 +105,22 @@
     "filepath" : "green_skp-tile1.png",
 }, {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 5686489729535631913,
+    "checksumValue" : 11866144860997809880,
     "comparisonResult" : "succeeded",
     "filepath" : "green_skp-tile2.png",
 }, {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 7980646035555096146,
+    "checksumValue" : 3893392565127823822,
     "comparisonResult" : "succeeded",
     "filepath" : "green_skp-tile3.png",
 }, {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 17817086664365875131,
+    "checksumValue" : 2083084978343901738,
     "comparisonResult" : "succeeded",
     "filepath" : "green_skp-tile4.png",
 }, {
     "checksumAlgorithm" : "bitmap-64bitMD5",
-    "checksumValue" : 10673669813016809363,
+    "checksumValue" : 89620927366502076,
     "comparisonResult" : "succeeded",
     "filepath" : "green_skp-tile5.png",
 }]
@@ -193,6 +197,8 @@
         '--writeWholeImage'])
     expected_summary_dict = {
         "header" : EXPECTED_HEADER_CONTENTS,
+        "image-base-gs-url" : None,
+        "descriptions" : None,
         "actual-results" : {
             "red.skp": {
                 "tiled-images": RED_TILES,
@@ -208,6 +214,44 @@
     self._assert_directory_contents(
         write_path_dir, ['red_skp.png', 'green_skp.png'])
 
+  def test_ignore_some_failures(self):
+    """test_tiled_whole_image, but ignoring some failed tests.
+    """
+    output_json_path = os.path.join(self._output_dir, 'actuals.json')
+    write_path_dir = self.create_empty_dir(
+        path=os.path.join(self._output_dir, 'writePath'))
+    self._generate_skps()
+    expectations_path = self._create_expectations(ignore_some_failures=True)
+    self._run_render_pictures([
+        '-r', self._input_skp_dir,
+        '--bbh', 'grid', '256', '256',
+        '--mode', 'tile', '256', '256',
+        '--readJsonSummaryPath', expectations_path,
+        '--writeJsonSummaryPath', output_json_path,
+        '--writePath', write_path_dir,
+        '--writeWholeImage'])
+    modified_red_tiles = copy.deepcopy(RED_TILES)
+    modified_red_tiles[5]['comparisonResult'] = 'failure-ignored'
+    expected_summary_dict = {
+        "header" : EXPECTED_HEADER_CONTENTS,
+        "image-base-gs-url" : None,
+        "descriptions" : None,
+        "actual-results" : {
+            "red.skp": {
+                "tiled-images": modified_red_tiles,
+                "whole-image": modified_dict(
+                    RED_WHOLEIMAGE, {"comparisonResult" : "failure-ignored"}),
+            },
+            "green.skp": {
+                "tiled-images": GREEN_TILES,
+                "whole-image": GREEN_WHOLEIMAGE,
+            }
+        }
+    }
+    self._assert_json_contents(output_json_path, expected_summary_dict)
+    self._assert_directory_contents(
+        write_path_dir, ['red_skp.png', 'green_skp.png'])
+
   def test_missing_tile_and_whole_image(self):
     """test_tiled_whole_image, but missing expectations for some images.
     """
@@ -228,6 +272,8 @@
     modified_red_tiles[5]['comparisonResult'] = 'no-comparison'
     expected_summary_dict = {
         "header" : EXPECTED_HEADER_CONTENTS,
+        "image-base-gs-url" : None,
+        "descriptions" : None,
         "actual-results" : {
             "red.skp": {
                 "tiled-images": modified_red_tiles,
@@ -272,6 +318,8 @@
     if expected_summary_dict == None:
       expected_summary_dict = {
           "header" : EXPECTED_HEADER_CONTENTS,
+          "image-base-gs-url" : None,
+          "descriptions" : None,
           "actual-results" : {
               "red.skp": {
                   "whole-image": RED_WHOLEIMAGE,
@@ -292,10 +340,12 @@
   def test_untiled_empty_expectations_file(self):
     """Same as test_untiled, but with an empty expectations file."""
     expectations_path = os.path.join(self._expectations_dir, 'empty')
-    with open(expectations_path, 'w') as fh:
+    with open(expectations_path, 'w'):
       pass
     expected_summary_dict = {
         "header" : EXPECTED_HEADER_CONTENTS,
+        "image-base-gs-url" : None,
+        "descriptions" : None,
         "actual-results" : {
             "red.skp": {
                 "whole-image": modified_dict(
@@ -316,29 +366,39 @@
     write_path_dir = self.create_empty_dir(
         path=os.path.join(self._output_dir, 'writePath'))
     self._generate_skps()
-    self._run_render_pictures(['-r', self._input_skp_dir,
-                               '--writeChecksumBasedFilenames',
-                               '--writePath', write_path_dir,
-                               '--writeJsonSummaryPath', output_json_path])
+    self._run_render_pictures([
+        '-r', self._input_skp_dir,
+        '--descriptions', 'builder=builderName', 'renderMode=renderModeName',
+        '--writeChecksumBasedFilenames',
+        '--writePath', write_path_dir,
+        '--writeJsonSummaryPath', output_json_path,
+    ])
     expected_summary_dict = {
         "header" : EXPECTED_HEADER_CONTENTS,
+        "image-base-gs-url" : None,
+        "descriptions" : {
+            "builder": "builderName",
+            "renderMode": "renderModeName",
+        },
         "actual-results" : {
             "red.skp": {
                 # Manually verified: 640x400 red rectangle with black border
                 "whole-image": {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 11092453015575919668,
+                    "checksumValue" : 2853310525600416231,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "red_skp/bitmap-64bitMD5_11092453015575919668.png",
+                    "filepath" :
+                        "red_skp/bitmap-64bitMD5_2853310525600416231.png",
                 },
             },
             "green.skp": {
                 # Manually verified: 640x400 green rectangle with black border
                 "whole-image": {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 8891695120562235492,
+                    "checksumValue" : 11143979097452425335,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "green_skp/bitmap-64bitMD5_8891695120562235492.png",
+                    "filepath" :
+                        "green_skp/bitmap-64bitMD5_11143979097452425335.png",
                 },
             }
         }
@@ -347,10 +407,10 @@
     self._assert_directory_contents(write_path_dir, ['red_skp', 'green_skp'])
     self._assert_directory_contents(
         os.path.join(write_path_dir, 'red_skp'),
-        ['bitmap-64bitMD5_11092453015575919668.png'])
+        ['bitmap-64bitMD5_2853310525600416231.png'])
     self._assert_directory_contents(
         os.path.join(write_path_dir, 'green_skp'),
-        ['bitmap-64bitMD5_8891695120562235492.png'])
+        ['bitmap-64bitMD5_11143979097452425335.png'])
 
   def test_untiled_validate(self):
     """Same as test_untiled, but with --validate."""
@@ -367,6 +427,8 @@
         '--writeJsonSummaryPath', output_json_path])
     expected_summary_dict = {
         "header" : EXPECTED_HEADER_CONTENTS,
+        "image-base-gs-url" : None,
+        "descriptions" : None,
         "actual-results" : {
             "red.skp": {
                 "whole-image": RED_WHOLEIMAGE,
@@ -394,6 +456,8 @@
         '--writeJsonSummaryPath', output_json_path])
     expected_summary_dict = {
         "header" : EXPECTED_HEADER_CONTENTS,
+        "image-base-gs-url" : None,
+        "descriptions" : None,
         "actual-results" : {
             "red.skp": {
                 "tiled-images": RED_TILES,
@@ -428,6 +492,8 @@
         '--writeJsonSummaryPath', output_json_path])
     expected_summary_dict = {
         "header" : EXPECTED_HEADER_CONTENTS,
+        "image-base-gs-url" : None,
+        "descriptions" : None,
         "actual-results" : {
             "red.skp": {
                 "tiled-images": RED_TILES,
@@ -458,6 +524,8 @@
                                '--writeJsonSummaryPath', output_json_path])
     expected_summary_dict = {
         "header" : EXPECTED_HEADER_CONTENTS,
+        "image-base-gs-url" : None,
+        "descriptions" : None,
         "actual-results" : {
             "red.skp": {
                 # Manually verified these 6 images, all 256x256 tiles,
@@ -467,32 +535,38 @@
                     "checksumAlgorithm" : "bitmap-64bitMD5",
                     "checksumValue" : 5815827069051002745,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "red_skp/bitmap-64bitMD5_5815827069051002745.png",
+                    "filepath" :
+                        "red_skp/bitmap-64bitMD5_5815827069051002745.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
                     "checksumValue" : 9323613075234140270,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "red_skp/bitmap-64bitMD5_9323613075234140270.png",
+                    "filepath" :
+                        "red_skp/bitmap-64bitMD5_9323613075234140270.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 16670399404877552232,
+                    "checksumValue" : 15939355025996362179,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "red_skp/bitmap-64bitMD5_16670399404877552232.png",
+                    "filepath" :
+                        "red_skp/bitmap-64bitMD5_15939355025996362179.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 2507897274083364964,
+                    "checksumValue" : 649771916797529222,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "red_skp/bitmap-64bitMD5_2507897274083364964.png",
+                    "filepath" :
+                        "red_skp/bitmap-64bitMD5_649771916797529222.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 7325267995523877959,
+                    "checksumValue" : 8132820002266077288,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "red_skp/bitmap-64bitMD5_7325267995523877959.png",
+                    "filepath" :
+                        "red_skp/bitmap-64bitMD5_8132820002266077288.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 2181381724594493116,
+                    "checksumValue" : 2406160701181324581,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "red_skp/bitmap-64bitMD5_2181381724594493116.png",
+                    "filepath" :
+                        "red_skp/bitmap-64bitMD5_2406160701181324581.png",
                 }],
             },
             "green.skp": {
@@ -503,32 +577,38 @@
                     "checksumAlgorithm" : "bitmap-64bitMD5",
                     "checksumValue" : 12587324416545178013,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "green_skp/bitmap-64bitMD5_12587324416545178013.png",
+                    "filepath" :
+                        "green_skp/bitmap-64bitMD5_12587324416545178013.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
                     "checksumValue" : 7624374914829746293,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "green_skp/bitmap-64bitMD5_7624374914829746293.png",
+                    "filepath" :
+                        "green_skp/bitmap-64bitMD5_7624374914829746293.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 5686489729535631913,
+                    "checksumValue" : 11866144860997809880,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "green_skp/bitmap-64bitMD5_5686489729535631913.png",
+                    "filepath" :
+                        "green_skp/bitmap-64bitMD5_11866144860997809880.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 7980646035555096146,
+                    "checksumValue" : 3893392565127823822,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "green_skp/bitmap-64bitMD5_7980646035555096146.png",
+                    "filepath" :
+                        "green_skp/bitmap-64bitMD5_3893392565127823822.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 17817086664365875131,
+                    "checksumValue" : 2083084978343901738,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "green_skp/bitmap-64bitMD5_17817086664365875131.png",
+                    "filepath" :
+                        "green_skp/bitmap-64bitMD5_2083084978343901738.png",
                 }, {
                     "checksumAlgorithm" : "bitmap-64bitMD5",
-                    "checksumValue" : 10673669813016809363,
+                    "checksumValue" : 89620927366502076,
                     "comparisonResult" : "no-comparison",
-                    "filepath" : "green_skp/bitmap-64bitMD5_10673669813016809363.png",
+                    "filepath" :
+                        "green_skp/bitmap-64bitMD5_89620927366502076.png",
                 }],
             }
         }
@@ -539,33 +619,33 @@
         os.path.join(write_path_dir, 'red_skp'),
         ['bitmap-64bitMD5_5815827069051002745.png',
          'bitmap-64bitMD5_9323613075234140270.png',
-         'bitmap-64bitMD5_16670399404877552232.png',
-         'bitmap-64bitMD5_2507897274083364964.png',
-         'bitmap-64bitMD5_7325267995523877959.png',
-         'bitmap-64bitMD5_2181381724594493116.png'])
+         'bitmap-64bitMD5_15939355025996362179.png',
+         'bitmap-64bitMD5_649771916797529222.png',
+         'bitmap-64bitMD5_8132820002266077288.png',
+         'bitmap-64bitMD5_2406160701181324581.png'])
     self._assert_directory_contents(
         os.path.join(write_path_dir, 'green_skp'),
         ['bitmap-64bitMD5_12587324416545178013.png',
          'bitmap-64bitMD5_7624374914829746293.png',
-         'bitmap-64bitMD5_5686489729535631913.png',
-         'bitmap-64bitMD5_7980646035555096146.png',
-         'bitmap-64bitMD5_17817086664365875131.png',
-         'bitmap-64bitMD5_10673669813016809363.png'])
+         'bitmap-64bitMD5_11866144860997809880.png',
+         'bitmap-64bitMD5_3893392565127823822.png',
+         'bitmap-64bitMD5_2083084978343901738.png',
+         'bitmap-64bitMD5_89620927366502076.png'])
 
   def _run_render_pictures(self, args):
-    binary = self.find_path_to_program('render_pictures')
-    return self.run_command([binary,
-                             '--clone', '1',
-                             '--config', '8888',
-                             ] + args)
+    binary = find_run_binary.find_path_to_program('render_pictures')
+    return find_run_binary.run_command(
+        [binary, '--config', '8888'] + args)
 
   def _create_expectations(self, missing_some_images=False,
+                           ignore_some_failures=False,
                            rel_path='expectations.json'):
     """Creates expectations JSON file within self._expectations_dir .
 
     Args:
       missing_some_images: (bool) whether to remove expectations for a subset
           of the images
+      ignore_some_failures: (bool) whether to ignore some failing tests
       rel_path: (string) relative path within self._expectations_dir to write
           the expectations into
 
@@ -573,6 +653,7 @@
     """
     expectations_dict = {
         "header" : EXPECTED_HEADER_CONTENTS,
+        "descriptions" : None,
         "expected-results" : {
             # red.skp: these should fail the comparison
             "red.skp": {
@@ -589,8 +670,13 @@
         }
     }
     if missing_some_images:
-      del expectations_dict['expected-results']['red.skp']['whole-image']
-      del expectations_dict['expected-results']['red.skp']['tiled-images'][-1]
+      red_subdict = expectations_dict['expected-results']['red.skp']
+      del red_subdict['whole-image']
+      del red_subdict['tiled-images'][-1]
+    elif ignore_some_failures:
+      red_subdict = expectations_dict['expected-results']['red.skp']
+      red_subdict['whole-image']['ignoreFailure'] = True
+      red_subdict['tiled-images'][-1]['ignoreFailure'] = True
     path = os.path.join(self._expectations_dir, rel_path)
     with open(path, 'w') as fh:
       json.dump(expectations_dict, fh)
@@ -615,15 +701,16 @@
       width: Width of canvas to create.
       height: Height of canvas to create.
     """
-    binary = self.find_path_to_program('skpmaker')
-    return self.run_command([binary,
-                             '--red', str(red),
-                             '--green', str(green),
-                             '--blue', str(blue),
-                             '--width', str(width),
-                             '--height', str(height),
-                             '--writePath', str(output_path),
-                             ])
+    binary = find_run_binary.find_path_to_program('skpmaker')
+    return find_run_binary.run_command([
+        binary,
+        '--red', str(red),
+        '--green', str(green),
+        '--blue', str(blue),
+        '--width', str(width),
+        '--height', str(height),
+        '--writePath', str(output_path),
+    ])
 
   def _assert_directory_contents(self, dir_path, expected_filenames):
     """Asserts that files found in a dir are identical to expected_filenames.
diff --git a/tools/timer/GpuTimer.cpp b/tools/timer/GpuTimer.cpp
new file mode 100644
index 0000000..aac10a3
--- /dev/null
+++ b/tools/timer/GpuTimer.cpp
@@ -0,0 +1,77 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "GpuTimer.h"
+#include "gl/SkGLContextHelper.h"
+#include "gl/GrGLUtil.h"
+
+GpuTimer::GpuTimer(const SkGLContextHelper* glctx) : fContext(glctx) {
+    if (fContext) {
+        fContext->ref();
+        fContext->makeCurrent();
+        fStarted = false;
+        fSupported = GrGLGetVersion(fContext->gl()) > GR_GL_VER(3,3) ||
+                     fContext->hasExtension("GL_ARB_timer_query") ||
+                     fContext->hasExtension("GL_EXT_timer_query");
+
+        if (fSupported) {
+            SK_GL(*fContext, GenQueries(1, &fQuery));
+        }
+    }
+}
+
+GpuTimer::~GpuTimer() {
+    if (fContext) {
+        if (fSupported) {
+            fContext->makeCurrent();
+            SK_GL(*fContext, DeleteQueries(1, &fQuery));
+        }
+        fContext->unref();
+    }
+}
+
+void GpuTimer::start() {
+    if (fContext && fSupported) {
+        fContext->makeCurrent();
+        fStarted = true;
+        SK_GL(*fContext, BeginQuery(GR_GL_TIME_ELAPSED, fQuery));
+    }
+}
+
+/**
+ * It is important to stop the cpu clocks first,
+ * as this will cpu wait for the gpu to finish.
+ */
+double GpuTimer::end() {
+    if (fContext && fSupported) {
+        fStarted = false;
+        fContext->makeCurrent();
+        SK_GL(*fContext, EndQuery(GR_GL_TIME_ELAPSED));
+
+        GrGLint available = 0;
+        while (!available) {
+            SK_GL_NOERRCHECK(*fContext, GetQueryObjectiv(fQuery,
+                                                         GR_GL_QUERY_RESULT_AVAILABLE,
+                                                         &available));
+            // If GetQueryObjectiv is erroring out we need some alternative
+            // means of breaking out of this loop
+            GrGLenum error;
+            SK_GL_RET_NOERRCHECK(*fContext, error, GetError());
+            if (GR_GL_NO_ERROR != error) {
+                break;
+            }
+        }
+        GrGLuint64 totalGPUTimeElapsed = 0;
+        SK_GL(*fContext, GetQueryObjectui64v(fQuery,
+                                             GR_GL_QUERY_RESULT,
+                                             &totalGPUTimeElapsed));
+
+        return totalGPUTimeElapsed / 1000000.0;
+    } else {
+        return 0;
+    }
+}
diff --git a/tools/timer/GpuTimer.h b/tools/timer/GpuTimer.h
new file mode 100644
index 0000000..2100312
--- /dev/null
+++ b/tools/timer/GpuTimer.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef GpuTimer_DEFINED
+#define GpuTimer_DEFINED
+
+class SkGLContextHelper;
+
+class GpuTimer {
+public:
+    GpuTimer(const SkGLContextHelper*);
+    ~GpuTimer();
+    void start();
+    double end();
+private:
+    unsigned fQuery;
+    int fStarted;
+    const SkGLContextHelper* fContext;
+    bool fSupported;
+};
+
+#endif
diff --git a/tools/timer/SysTimer_mach.cpp b/tools/timer/SysTimer_mach.cpp
new file mode 100644
index 0000000..aca12de
--- /dev/null
+++ b/tools/timer/SysTimer_mach.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SysTimer_mach.h"
+
+static time_value_t mac_cpu_time() {
+    mach_port_t task = mach_task_self();
+    if (task == MACH_PORT_NULL) {
+        time_value_t none = {0, 0};
+        return none;
+    }
+
+    task_thread_times_info thread_info_data;
+    mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT;
+    if (KERN_SUCCESS != task_info(task,
+                                  TASK_THREAD_TIMES_INFO,
+                                  reinterpret_cast<task_info_t>(&thread_info_data),
+                                  &thread_info_count)) {
+        time_value_t none = {0, 0};
+        return none;
+    }
+
+    time_value_add(&thread_info_data.user_time, &thread_info_data.system_time)
+    return thread_info_data.user_time;
+}
+
+static double interval_in_ms(time_value_t start_clock, time_value_t end_clock) {
+    double duration_clock;
+    if ((end_clock.microseconds - start_clock.microseconds) < 0) {
+        duration_clock = (end_clock.seconds - start_clock.seconds-1) * 1000;
+        duration_clock += (1000000 + end_clock.microseconds - start_clock.microseconds) / 1000.0;
+    } else {
+        duration_clock = (end_clock.seconds - start_clock.seconds) * 1000;
+        duration_clock += (end_clock.microseconds - start_clock.microseconds) / 1000.0;
+    }
+    return duration_clock;
+}
+
+void SysTimer::startWall() {
+    fStartWall = mach_absolute_time();
+}
+
+void SysTimer::startCpu() {
+    fStartCpu = mac_cpu_time();
+}
+
+double SysTimer::endCpu() {
+    time_value_t end_cpu = mac_cpu_time();
+    return interval_in_ms(fStartCpu, end_cpu);
+}
+
+double SysTimer::endWall() {
+    uint64_t end_wall = mach_absolute_time();
+
+    uint64_t elapsed = end_wall - fStartWall;
+    mach_timebase_info_data_t sTimebaseInfo;
+    if (KERN_SUCCESS != mach_timebase_info(&sTimebaseInfo)) {
+        return 0;
+    } else {
+        uint64_t elapsedNano = elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom;
+        return elapsedNano / 1000000.0;
+    }
+}
diff --git a/bench/BenchSysTimer_mach.h b/tools/timer/SysTimer_mach.h
similarity index 79%
rename from bench/BenchSysTimer_mach.h
rename to tools/timer/SysTimer_mach.h
index 44d0e5e..8c21d57 100644
--- a/bench/BenchSysTimer_mach.h
+++ b/tools/timer/SysTimer_mach.h
@@ -1,18 +1,16 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#ifndef SkBenchSysTimer_DEFINED
-#define SkBenchSysTimer_DEFINED
+#ifndef SysTimer_DEFINED
+#define SysTimer_DEFINED
 
-//Time
 #include <mach/mach.h>
 #include <mach/mach_time.h>
 
-class BenchSysTimer {
+class SysTimer {
 public:
     void startWall();
     void startCpu();
diff --git a/tools/timer/SysTimer_posix.cpp b/tools/timer/SysTimer_posix.cpp
new file mode 100644
index 0000000..4b7d708
--- /dev/null
+++ b/tools/timer/SysTimer_posix.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SysTimer_posix.h"
+
+static double interval_in_ms(timespec start_clock, timespec end_clock)
+{
+    double duration_clock;
+    if ((end_clock.tv_nsec - start_clock.tv_nsec) < 0) {
+        duration_clock = (end_clock.tv_sec - start_clock.tv_sec - 1) * 1000;
+        duration_clock += (1000000000 + end_clock.tv_nsec - start_clock.tv_nsec) / 1000000.0;
+    } else {
+        duration_clock = (end_clock.tv_sec - start_clock.tv_sec) * 1000;
+        duration_clock += (end_clock.tv_nsec - start_clock.tv_nsec) / 1000000.0;
+    }
+    return duration_clock;
+}
+
+void SysTimer::startWall() {
+    if (-1 == clock_gettime(CLOCK_MONOTONIC, &fWall)) {
+        timespec none = {0, 0};
+        fWall = none;
+    }
+}
+void SysTimer::startCpu() {
+    if (-1 == clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &fCpu)) {
+        timespec none = {0, 0};
+        fCpu = none;
+    }
+}
+
+double SysTimer::endCpu() {
+    timespec end_cpu;
+    if (-1 == clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_cpu)) {
+        timespec none = {0, 0};
+        end_cpu = none;
+    }
+    return interval_in_ms(fCpu, end_cpu);
+}
+
+double SysTimer::endWall() {
+    timespec end_wall;
+    if (-1 == clock_gettime(CLOCK_MONOTONIC, &end_wall)) {
+        timespec none = {0, 0};
+        end_wall = none;
+    }
+    return interval_in_ms(fWall, end_wall);
+}
diff --git a/bench/BenchSysTimer_posix.h b/tools/timer/SysTimer_posix.h
similarity index 76%
rename from bench/BenchSysTimer_posix.h
rename to tools/timer/SysTimer_posix.h
index 8fd9706..1eca909 100644
--- a/bench/BenchSysTimer_posix.h
+++ b/tools/timer/SysTimer_posix.h
@@ -1,17 +1,15 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#ifndef SkBenchSysTimer_DEFINED
-#define SkBenchSysTimer_DEFINED
+#ifndef SysTimer_DEFINED
+#define SysTimer_DEFINED
 
-//Time
 #include <time.h>
 
-class BenchSysTimer {
+class SysTimer {
 public:
     void startWall();
     void startCpu();
diff --git a/tools/timer/SysTimer_windows.cpp b/tools/timer/SysTimer_windows.cpp
new file mode 100644
index 0000000..8e45b4a
--- /dev/null
+++ b/tools/timer/SysTimer_windows.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SysTimer_windows.h"
+
+#include <intrin.h>
+
+static ULONGLONG win_cpu_time() {
+    FILETIME createTime;
+    FILETIME exitTime;
+    FILETIME usrTime;
+    FILETIME sysTime;
+    if (0 == GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &sysTime, &usrTime)) {
+        return 0;
+    }
+    ULARGE_INTEGER start_cpu_sys;
+    ULARGE_INTEGER start_cpu_usr;
+    start_cpu_sys.LowPart  = sysTime.dwLowDateTime;
+    start_cpu_sys.HighPart = sysTime.dwHighDateTime;
+    start_cpu_usr.LowPart  = usrTime.dwLowDateTime;
+    start_cpu_usr.HighPart = usrTime.dwHighDateTime;
+    return start_cpu_sys.QuadPart + start_cpu_usr.QuadPart;
+}
+
+void SysTimer::startCpu() {
+    fStartCpu = win_cpu_time();
+}
+
+double SysTimer::endCpu() {
+    ULONGLONG end_cpu = win_cpu_time();
+    return static_cast<double>(end_cpu - fStartCpu) / 10000.0L;
+}
+
+// On recent Intel chips (roughly, "has Core or Atom in its name") __rdtsc will always tick
+// at the CPU's maximum rate, even while power management clocks the CPU up and down.
+// That's great, because it makes measuring wall time super simple.
+
+void SysTimer::startWall() {
+    fStartWall = __rdtsc();
+}
+
+double SysTimer::endWall() {
+    unsigned __int64 end = __rdtsc();
+
+    // This seems to, weirdly, give the CPU frequency in kHz.  That's exactly what we want!
+    LARGE_INTEGER freq_khz;
+    QueryPerformanceFrequency(&freq_khz);
+
+    return static_cast<double>(end - fStartWall) / static_cast<double>(freq_khz.QuadPart);
+}
diff --git a/bench/BenchSysTimer_windows.h b/tools/timer/SysTimer_windows.h
similarity index 74%
rename from bench/BenchSysTimer_windows.h
rename to tools/timer/SysTimer_windows.h
index 469332e..380debd 100644
--- a/bench/BenchSysTimer_windows.h
+++ b/tools/timer/SysTimer_windows.h
@@ -1,18 +1,17 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#ifndef SkBenchSysTimer_DEFINED
-#define SkBenchSysTimer_DEFINED
+#ifndef SysTimer_DEFINED
+#define SysTimer_DEFINED
 
 //Time
 #define WIN32_LEAN_AND_MEAN 1
 #include <windows.h>
 
-class BenchSysTimer {
+class SysTimer {
 public:
     void startWall();
     void startCpu();
@@ -20,7 +19,7 @@
     double endWall();
 private:
     ULONGLONG fStartCpu;
-    LARGE_INTEGER fStartWall;
+    unsigned __int64 fStartWall;
 };
 
 #endif
diff --git a/tools/timer/Timer.cpp b/tools/timer/Timer.cpp
new file mode 100644
index 0000000..4f3fc85
--- /dev/null
+++ b/tools/timer/Timer.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "Timer.h"
+
+Timer::Timer(SkGLContextHelper* gl)
+        : fCpu(-1.0)
+        , fWall(-1.0)
+        , fTruncatedCpu(-1.0)
+        , fTruncatedWall(-1.0)
+        , fGpu(-1.0)
+#if SK_SUPPORT_GPU
+        , fGpuTimer(gl)
+#endif
+        {}
+
+void Timer::start() {
+    fSysTimer.startWall();
+    fTruncatedSysTimer.startWall();
+#if SK_SUPPORT_GPU
+    fGpuTimer.start();
+#endif
+    fSysTimer.startCpu();
+    fTruncatedSysTimer.startCpu();
+}
+
+void Timer::end() {
+    fCpu = fSysTimer.endCpu();
+#if SK_SUPPORT_GPU
+    //It is important to stop the cpu clocks first,
+    //as the following will cpu wait for the gpu to finish.
+    fGpu = fGpuTimer.end();
+#endif
+    fWall = fSysTimer.endWall();
+}
+
+void Timer::truncatedEnd() {
+    fTruncatedCpu = fTruncatedSysTimer.endCpu();
+    fTruncatedWall = fTruncatedSysTimer.endWall();
+}
+
+WallTimer::WallTimer() : fWall(-1.0) {}
+
+void WallTimer::start() {
+    fSysTimer.startWall();
+}
+
+void WallTimer::end() {
+    fWall = fSysTimer.endWall();
+}
diff --git a/tools/timer/Timer.h b/tools/timer/Timer.h
new file mode 100644
index 0000000..15c93f5
--- /dev/null
+++ b/tools/timer/Timer.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef Timer_DEFINED
+#define Timer_DEFINED
+
+#include "SkTypes.h"
+
+#if defined(SK_BUILD_FOR_WIN32)
+    #include "SysTimer_windows.h"
+#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
+    #include "SysTimer_mach.h"
+#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
+    #include "SysTimer_posix.h"
+#endif
+
+#if SK_SUPPORT_GPU
+    #include "GpuTimer.h"
+#endif
+
+class SkGLContextHelper;
+
+/**
+ * SysTimers and GpuTimers are implemented orthogonally.
+ * This class combines 2 SysTimers and a GpuTimer into one single,
+ * platform specific Timer with a simple interface. The truncated
+ * timer doesn't include the time required for the GPU to finish
+ * its rendering. It should always be <= the un-truncated system
+ * times and (for GPU configurations) can be used to roughly (very
+ * roughly) gauge the GPU load/backlog.
+ */
+class Timer {
+public:
+    explicit Timer(SkGLContextHelper* gl = NULL);
+
+    void start();
+    void truncatedEnd();
+    void end();
+
+    // All times in milliseconds.
+    double fCpu;
+    double fWall;
+    double fTruncatedCpu;
+    double fTruncatedWall;
+    double fGpu;
+
+private:
+    SysTimer fSysTimer;
+    SysTimer fTruncatedSysTimer;
+#if SK_SUPPORT_GPU
+    GpuTimer fGpuTimer;
+#endif
+};
+
+// Same as Timer above, supporting only fWall but with much lower overhead.
+// (Typically, ~30ns instead of Timer's ~1us.)
+class WallTimer {
+public:
+    WallTimer();
+
+    void start();
+    void end();
+
+    double fWall;  // Milliseconds.
+
+private:
+    SysTimer fSysTimer;
+};
+
+#endif
diff --git a/bench/TimerData.cpp b/tools/timer/TimerData.cpp
similarity index 95%
rename from bench/TimerData.cpp
rename to tools/timer/TimerData.cpp
index 0cb0002..21529bc 100644
--- a/bench/TimerData.cpp
+++ b/tools/timer/TimerData.cpp
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2012 Google Inc.
  *
@@ -7,22 +6,19 @@
  */
 #include "TimerData.h"
 
-#include "BenchTimer.h"
+#include "Timer.h"
 #include <limits>
 
-using namespace std;
-
 TimerData::TimerData(int maxNumTimings)
-: fMaxNumTimings(maxNumTimings)
-, fCurrTiming(0)
-, fWallTimes(maxNumTimings)
-, fTruncatedWallTimes(maxNumTimings)
-, fCpuTimes(maxNumTimings)
-, fTruncatedCpuTimes(maxNumTimings)
-, fGpuTimes(maxNumTimings){
-}
+    : fMaxNumTimings(maxNumTimings)
+    , fCurrTiming(0)
+    , fWallTimes(maxNumTimings)
+    , fTruncatedWallTimes(maxNumTimings)
+    , fCpuTimes(maxNumTimings)
+    , fTruncatedCpuTimes(maxNumTimings)
+    , fGpuTimes(maxNumTimings) {}
 
-bool TimerData::appendTimes(BenchTimer* timer) {
+bool TimerData::appendTimes(Timer* timer) {
     SkASSERT(timer != NULL);
     if (fCurrTiming >= fMaxNumTimings) {
         return false;
diff --git a/bench/TimerData.h b/tools/timer/TimerData.h
similarity index 91%
rename from bench/TimerData.h
rename to tools/timer/TimerData.h
index fb84df1..35e94dc 100644
--- a/bench/TimerData.h
+++ b/tools/timer/TimerData.h
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2012 Google Inc.
  *
@@ -23,7 +22,7 @@
     #pragma warning(pop)
 #endif
 
-class BenchTimer;
+class Timer;
 
 class TimerData {
 public:
@@ -33,12 +32,12 @@
     explicit TimerData(int maxNumTimings);
 
     /**
-     * Collect times from the BenchTimer for an iteration. It will fail if called more often than
+     * Collect times from the Timer for an iteration. It will fail if called more often than
      * indicated in the constructor.
      *
-     * @param BenchTimer Must not be null.
+     * @param Timer Must not be null.
      */
-    bool appendTimes(BenchTimer*);
+    bool appendTimes(Timer*);
 
     enum Result {
         kMin_Result,
diff --git a/tools/valgrind.supp b/tools/valgrind.supp
index 2af598d..d96ada0 100644
--- a/tools/valgrind.supp
+++ b/tools/valgrind.supp
@@ -72,6 +72,7 @@
 {
     nv_driver_bug_2
     Memcheck:Cond
+    ...
     obj:/usr/lib/libnvidia-glcore.so*
 }
 {
@@ -81,28 +82,32 @@
     obj:/usr/lib*/libGL.so*
 }
 {
+    #Fixed by FontConfig 2.9.0
+    #http://cgit.freedesktop.org/fontconfig/commit/?id=1c475d5c8cb265ac939d6b9e097666e300162511
     font_config_bug_1
     Memcheck:Addr4
     fun:FcConfigFileExists
 }
 {
+    #https://bugs.freedesktop.org/show_bug.cgi?id=8215
+    #https://bugs.freedesktop.org/show_bug.cgi?id=8428
+    #FcPattern uses 'intptr_t elts_offset' instead of 'FcPatternEltPtr elts',
+    #which confuses valgrind.
     font_config_bug_2
     Memcheck:Leak
-    fun:malloc
-    fun:FcFontSetCreate
+    fun:*alloc
+    ...
+    fun:Fc*Add*
 }
 {
+    #Same root cause as font_config_bug_2.
+    #The 'leak' here is a copy of rule values, as opposed to new values.
     font_config_bug_3
     Memcheck:Leak
-    fun:realloc
-    fun:FcFontSetAdd
-}
-{
-    font_config_bug_4
-    Memcheck:Leak
-    fun:malloc
-    fun:FcPatternObjectInsertElt
-    fun:FcPatternObjectAddWithBinding
+    fun:*alloc
+    fun:FcConfigValues
+    fun:FcConfigSubstituteWithPat
+    fun:FcFontRenderPrepare
 }
 {
     zlib_bug_1
@@ -112,6 +117,14 @@
     fun:png_create_read_struct_2
     fun:png_create_read_struct
 }
+{
+    zlib_bug_2
+    Memcheck:Cond
+    fun:inflateReset2
+    fun:inflateInit2_
+    fun:_ZN12_GLOBAL__N_17doFlateEbP8SkStreamP9SkWStream
+    fun:_ZN7SkFlate7InflateEP8SkStreamP9SkWStream
+}
 
 # Why is it OK to suppress this?
 {
diff --git a/whitespace.txt b/whitespace.txt
index 6321da0..d70f3f1 100644
--- a/whitespace.txt
+++ b/whitespace.txt
@@ -1,13 +1,18 @@
 You can modify this file to create no-op changelists (like this one).
 
+I LOVE WHITESPACE!
 
 
 
 
 
+Lithp.
+Use the Forth.
 
 
-Life is a mistry.  WAKA WAKA WAKA
+
+
+Life is a mistry.  Everyone must WAKA WAKA WAKA
 
 
 
@@ -232,3 +237,6 @@
 
 
 
+
+
+